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/>.
*/
2007-01-30 22:32:21 +00:00
# include "elementspanel.h"
2007-09-21 13:22:18 +00:00
# include "qetapp.h"
2009-04-03 19:30:25 +00:00
# include "qetproject.h"
# include "diagram.h"
2007-04-05 01:13:14 +00:00
# include "elementscategory.h"
2011-09-13 21:46:10 +00:00
# include "elementscollectioncache.h"
2013-11-14 10:11:22 +00:00
# include "qetgraphicsitem/customelement.h"
2009-04-03 19:30:25 +00:00
# include "fileelementscollection.h"
# include "fileelementdefinition.h"
2009-05-01 14:41:33 +00:00
# include "qeticons.h"
2012-01-08 17:04:34 +00:00
# include "templatescollection.h"
2012-04-28 16:45:16 +00:00
# include "treecoloranimation.h"
2009-04-03 19:30:25 +00:00
/*
Lorsque le flag ENABLE_PANEL_DND_CHECKS est defini , le panel d ' elements
effectue des verifications lors des drag ' n drop d ' elements et categories .
Par exemple , il verifie qu ' une categorie cible est accessible en ecriture
avant d ' y autoriser le drop d ' un element .
Supprimer ce flag permet de tester le comportement des fonctions de gestion
des items ( copy , move , etc . ) .
*/
# define ENABLE_PANEL_DND_CHECKS
2006-10-27 15:47:22 +00:00
2010-02-28 16:13:45 +00:00
/*
Largeur maximale , en pixels , de la pixmap accrochee au pointeur de la
souris
*/
# define QET_MAX_DND_PIXMAP_WIDTH 500
/*
Hauteur maximale , en pixels , de la pixmap accrochee au pointeur de la
souris
*/
# define QET_MAX_DND_PIXMAP_HEIGHT 375
2006-10-27 15:47:22 +00:00
/**
Constructeur
@ param parent Le QWidget parent du panel d ' appareils
*/
2009-04-03 19:30:25 +00:00
ElementsPanel : : ElementsPanel ( QWidget * parent ) :
2012-02-06 21:21:43 +00:00
GenericPanel ( parent ) ,
2009-04-03 19:30:25 +00:00
common_collection_item_ ( 0 ) ,
2011-03-15 20:06:40 +00:00
custom_collection_item_ ( 0 ) ,
2011-03-20 03:13:32 +00:00
first_reload_ ( true )
2009-04-03 19:30:25 +00:00
{
2006-10-27 15:47:22 +00:00
// selection unique
setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
2006-10-28 19:39:43 +00:00
setColumnCount ( 1 ) ;
2010-11-15 00:35:02 +00:00
setExpandsOnDoubleClick ( true ) ;
2012-04-28 16:45:13 +00:00
setMouseTracking ( true ) ;
2006-10-27 15:47:22 +00:00
// drag'n drop autorise
setDragEnabled ( true ) ;
2009-04-03 19:30:25 +00:00
setAcceptDrops ( true ) ;
setDropIndicatorShown ( true ) ;
2010-11-14 20:11:57 +00:00
setAutoExpandDelay ( 1000 ) ;
2006-10-27 15:47:22 +00:00
2006-11-11 18:25:42 +00:00
// force du noir sur une alternance de blanc (comme le schema) et de gris
// clair, avec du blanc sur bleu pas trop fonce pour la selection
2006-10-27 15:47:22 +00:00
QPalette qp = palette ( ) ;
2007-02-01 01:07:26 +00:00
qp . setColor ( QPalette : : Text , Qt : : black ) ;
qp . setColor ( QPalette : : Base , Qt : : white ) ;
qp . setColor ( QPalette : : AlternateBase , QColor ( " #e8e8e8 " ) ) ;
qp . setColor ( QPalette : : Highlight , QColor ( " #678db2 " ) ) ;
2006-11-11 18:25:42 +00:00
qp . setColor ( QPalette : : HighlightedText , Qt : : white ) ;
2006-10-27 15:47:22 +00:00
setPalette ( qp ) ;
2007-06-30 17:41:07 +00:00
2012-02-06 21:21:43 +00:00
// we handle double click on items ourselves
connect (
this ,
SIGNAL ( itemDoubleClicked ( QTreeWidgetItem * , int ) ) ,
this ,
SLOT ( slot_doubleClick ( QTreeWidgetItem * , int ) )
) ;
connect ( this , SIGNAL ( firstActivated ( ) ) , this , SLOT ( firstActivation ( ) ) ) ;
2012-02-12 15:33:04 +00:00
connect ( this , SIGNAL ( panelContentChanged ( ) ) , this , SLOT ( panelContentChange ( ) ) ) ;
2007-10-28 16:03:18 +00:00
// emet un signal au lieu de gerer son menu contextuel
setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
2011-09-13 21:46:10 +00:00
2012-02-06 21:21:43 +00:00
setElementsCache ( QETApp : : collectionCache ( ) ) ;
2006-10-27 15:47:22 +00:00
}
2007-04-12 03:13:13 +00:00
/**
Destructeur
*/
ElementsPanel : : ~ ElementsPanel ( ) {
}
2009-04-03 19:30:25 +00:00
/**
@ param qtwi Un QTreeWidgetItem
@ return true si qtwi represente un element , false sinon
*/
bool ElementsPanel : : itemIsWritable ( QTreeWidgetItem * qtwi ) const {
if ( ElementsCollectionItem * qtwi_item = collectionItemForItem ( qtwi ) ) {
return ( qtwi_item - > isWritable ( ) ) ;
}
return ( false ) ;
2007-08-28 21:17:11 +00:00
}
2009-04-03 19:30:25 +00:00
/**
@ return true si l ' item selectionne est accessible en ecriture , false sinon
*/
bool ElementsPanel : : selectedItemIsWritable ( ) const {
if ( ElementsCollectionItem * selected_item = selectedItem ( ) ) {
return ( selected_item - > isWritable ( ) ) ;
}
return ( false ) ;
}
/**
@ return la collection , la categorie ou l ' element selectionne ( e )
*/
ElementsCollectionItem * ElementsPanel : : selectedItem ( ) const {
2012-02-06 21:21:43 +00:00
ElementsLocation selected_location ( selectedElementLocation ( ) ) ;
2009-04-03 19:30:25 +00:00
if ( ! selected_location . isNull ( ) ) {
return ( QETApp : : collectionItem ( selected_location ) ) ;
}
return ( 0 ) ;
}
/**
Gere l ' entree d ' un drag ' n drop . L ' evenement est accepte si les donnees
fournies contiennent un type MIME representant une categorie ou un element
QET .
@ param e QDragEnterEvent decrivant l ' entree du drag ' n drop
*/
void ElementsPanel : : dragEnterEvent ( QDragEnterEvent * e ) {
if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-category-uri " ) ) {
e - > acceptProposedAction ( ) ;
} else if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-element-uri " ) ) {
e - > acceptProposedAction ( ) ;
}
2007-08-28 21:17:11 +00:00
}
2006-10-27 15:47:22 +00:00
/**
Gere le mouvement lors d ' un drag ' n drop
*/
2009-04-03 19:30:25 +00:00
void ElementsPanel : : dragMoveEvent ( QDragMoveEvent * e ) {
// scrolle lorsque le curseur est pres des bords
int limit = 40 ;
QScrollBar * scroll_bar = verticalScrollBar ( ) ;
if ( e - > pos ( ) . y ( ) < limit ) {
scroll_bar - > setValue ( scroll_bar - > value ( ) - 1 ) ;
} else if ( e - > pos ( ) . y ( ) > height ( ) - limit ) {
scroll_bar - > setValue ( scroll_bar - > value ( ) + 1 ) ;
}
2010-11-14 20:11:57 +00:00
QTreeWidget : : dragMoveEvent ( e ) ;
2009-04-03 19:30:25 +00:00
// recupere la categorie cible pour le deplacement / la copie
ElementsCategory * target_category = categoryForPos ( e - > pos ( ) ) ;
if ( ! target_category ) {
e - > ignore ( ) ;
return ;
}
// recupere la source (categorie ou element) pour le deplacement / la copie
ElementsLocation dropped_location = ElementsLocation : : locationFromString ( e - > mimeData ( ) - > text ( ) ) ;
ElementsCollectionItem * source_item = QETApp : : collectionItem ( dropped_location , false ) ;
if ( ! source_item ) {
e - > ignore ( ) ;
return ;
}
# ifdef ENABLE_PANEL_DND_CHECKS
// ne prend pas en consideration le drop d'un item sur lui-meme ou une categorie imbriquee
if (
source_item - > location ( ) = = target_category - > location ( ) | | \
target_category - > isChildOf ( source_item )
) {
e - > ignore ( ) ;
return ;
}
// s'assure que la categorie cible est accessible en ecriture
if ( ! target_category - > isWritable ( ) ) {
e - > ignore ( ) ;
return ;
}
# endif
e - > accept ( ) ;
/// @todo mettre en valeur le lieu de depot
2006-10-27 15:47:22 +00:00
}
/**
Gere le depot lors d ' un drag ' n drop
2009-04-03 19:30:25 +00:00
@ param e QDropEvent decrivant le depot
2006-10-27 15:47:22 +00:00
*/
2009-04-03 19:30:25 +00:00
void ElementsPanel : : dropEvent ( QDropEvent * e ) {
// recupere la categorie cible pour le deplacement / la copie
ElementsCategory * target_category = categoryForPos ( e - > pos ( ) ) ;
if ( ! target_category ) {
e - > ignore ( ) ;
return ;
}
// recupere la source (categorie ou element) pour le deplacement / la copie
ElementsLocation dropped_location = ElementsLocation : : locationFromString ( e - > mimeData ( ) - > text ( ) ) ;
ElementsCollectionItem * source_item = QETApp : : collectionItem ( dropped_location , false ) ;
if ( ! source_item ) {
e - > ignore ( ) ;
return ;
}
# ifdef ENABLE_PANEL_DND_CHECKS
// ne prend pas en consideration le drop d'un item sur lui-meme ou une categorie imbriquee
if (
source_item - > location ( ) = = target_category - > location ( ) | | \
target_category - > isChildOf ( source_item )
) {
e - > ignore ( ) ;
return ;
}
// s'assure que la categorie cible est accessible en ecriture
if ( ! target_category - > isWritable ( ) ) {
e - > ignore ( ) ;
return ;
}
# endif
e - > accept ( ) ;
emit ( requestForMoveElements ( source_item , target_category , e - > pos ( ) ) ) ;
2006-10-27 15:47:22 +00:00
}
/**
Gere le debut des drag ' n drop
@ param supportedActions Les actions supportees
2009-04-03 19:30:25 +00:00
*/
2009-11-22 16:12:22 +00:00
void ElementsPanel : : startDrag ( Qt : : DropActions supportedActions ) {
Q_UNUSED ( supportedActions ) ;
2009-04-03 19:30:25 +00:00
// recupere l'emplacement selectionne
2012-02-06 21:21:43 +00:00
ElementsLocation element_location = selectedElementLocation ( ) ;
2012-01-22 10:40:37 +00:00
if ( ! element_location . isNull ( ) ) {
startElementDrag ( element_location ) ;
return ;
}
2009-04-03 19:30:25 +00:00
2012-02-06 21:21:43 +00:00
TitleBlockTemplateLocation tbt_location = selectedTemplateLocation ( ) ;
2012-01-22 10:40:37 +00:00
if ( tbt_location . isValid ( ) ) {
startTitleBlockTemplateDrag ( tbt_location ) ;
return ;
}
}
/**
Handle the dragging of an element .
@ param location Location of the dragged element
*/
void ElementsPanel : : startElementDrag ( const ElementsLocation & location ) {
2009-04-03 19:30:25 +00:00
// recupere la selection
ElementsCollectionItem * selected_item = QETApp : : collectionItem ( location ) ;
if ( ! selected_item ) return ;
2006-10-28 19:39:43 +00:00
2006-10-27 15:47:22 +00:00
// objet QDrag pour realiser le drag'n drop
QDrag * drag = new QDrag ( this ) ;
// donnees qui seront transmises par le drag'n drop
2009-04-03 19:30:25 +00:00
QString location_string ( location . toString ( ) ) ;
2006-10-27 15:47:22 +00:00
QMimeData * mimeData = new QMimeData ( ) ;
2009-04-03 19:30:25 +00:00
mimeData - > setText ( location_string ) ;
if ( selected_item - > isCategory ( ) | | selected_item - > isCollection ( ) ) {
mimeData - > setData ( " application/x-qet-category-uri " , location_string . toAscii ( ) ) ;
2009-05-01 14:41:33 +00:00
drag - > setPixmap ( QET : : Icons : : Folder . pixmap ( 22 , 22 ) ) ;
2009-04-03 19:30:25 +00:00
} else if ( selected_item - > isElement ( ) ) {
mimeData - > setData ( " application/x-qet-element-uri " , location_string . toAscii ( ) ) ;
// element temporaire pour fournir un apercu
int elmt_creation_state ;
Element * temp_elmt = new CustomElement ( location , 0 , 0 , & elmt_creation_state ) ;
if ( elmt_creation_state ) {
delete temp_elmt ;
return ;
}
// accrochage d'une pixmap representant l'appareil au pointeur
2010-02-28 16:13:45 +00:00
QPixmap elmt_pixmap ( temp_elmt - > pixmap ( ) ) ;
QPoint elmt_hotspot ( temp_elmt - > hotspot ( ) ) ;
// ajuste la pixmap si celle-ci est trop grande
QPoint elmt_pixmap_size ( elmt_pixmap . width ( ) , elmt_pixmap . height ( ) ) ;
if ( elmt_pixmap . width ( ) > QET_MAX_DND_PIXMAP_WIDTH | | elmt_pixmap . height ( ) > QET_MAX_DND_PIXMAP_HEIGHT ) {
elmt_pixmap = elmt_pixmap . scaled ( QET_MAX_DND_PIXMAP_WIDTH , QET_MAX_DND_PIXMAP_HEIGHT , Qt : : KeepAspectRatio ) ;
elmt_hotspot = QPoint (
elmt_hotspot . x ( ) * elmt_pixmap . width ( ) / elmt_pixmap_size . x ( ) ,
elmt_hotspot . y ( ) * elmt_pixmap . height ( ) / elmt_pixmap_size . y ( )
) ;
}
drag - > setPixmap ( elmt_pixmap ) ;
drag - > setHotSpot ( elmt_hotspot ) ;
2009-04-03 19:30:25 +00:00
// suppression de l'appareil temporaire
delete temp_elmt ;
2006-10-27 15:47:22 +00:00
}
2009-04-03 19:30:25 +00:00
// realisation du drag'n drop
2006-10-27 15:47:22 +00:00
drag - > setMimeData ( mimeData ) ;
2009-04-03 19:30:25 +00:00
drag - > start ( Qt : : MoveAction | Qt : : CopyAction ) ;
}
2012-01-22 10:40:37 +00:00
/**
Handle the dragging of a title block template
@ param location Location of the dragged template .
*/
void ElementsPanel : : startTitleBlockTemplateDrag ( const TitleBlockTemplateLocation & location ) {
QString location_string = location . toString ( ) ;
QMimeData * mime_data = new QMimeData ( ) ;
mime_data - > setText ( location_string ) ;
mime_data - > setData ( " application/x-qet-titleblock-uri " , location_string . toAscii ( ) ) ;
QDrag * drag = new QDrag ( this ) ;
drag - > setMimeData ( mime_data ) ;
drag - > setPixmap ( QET : : Icons : : TitleBlock . pixmap ( 22 , 16 ) ) ;
drag - > start ( Qt : : CopyAction ) ;
}
2012-02-06 21:21:43 +00:00
void ElementsPanel : : firstActivation ( ) {
QTimer : : singleShot ( 250 , this , SLOT ( reload ( ) ) ) ;
2011-03-15 20:06:40 +00:00
}
2012-02-12 15:33:04 +00:00
/**
Ensure the filter is applied again after the panel content has changed .
*/
void ElementsPanel : : panelContentChange ( ) {
if ( ! filter_ . isEmpty ( ) ) {
filter ( filter_ ) ;
}
}
2012-04-28 16:45:16 +00:00
/**
Inform this panel the project \ a project has integrated the element at \ a location
*/
QList < ElementsLocation > ElementsPanel : : elementIntegrated ( QETProject * project , const ElementsLocation & location ) {
// the base implementation simply refreshes the adequate category and returns the list of added locations
QList < ElementsLocation > added_locations = GenericPanel : : elementIntegrated ( project , location ) ;
2012-04-29 20:29:40 +00:00
if ( ! added_locations . count ( ) | | ! mustHighlightIntegratedElements ( ) ) {
return ( added_locations ) ;
}
2012-04-28 16:45:16 +00:00
// the additional job of this method consists in displaying the integrated elements...
if ( QTreeWidgetItem * integrated_element_qtwi = itemForElementsLocation ( location ) ) {
ensureHierarchyIsVisible ( QList < QTreeWidgetItem * > ( ) < < integrated_element_qtwi ) ;
scrollToItem ( integrated_element_qtwi , QAbstractItemView : : PositionAtCenter ) ;
}
// and make them "flash" (not too obviously though) so the user notices they have been integrated.
QList < QTreeWidgetItem * > items ;
foreach ( ElementsLocation loc , added_locations ) {
if ( QTreeWidgetItem * added_item = itemForElementsLocation ( loc ) ) {
items < < added_item ;
}
}
highlightItems ( items , this , SLOT ( scrollToSelectedItem ( ) ) ) ;
return ( added_locations ) ;
}
2009-04-03 19:30:25 +00:00
/**
Methode permettant d ' ajouter un projet au panel d ' elements .
@ param qtwi_parent QTreeWidgetItem parent sous lequel sera insere le projet
@ param project Projet a inserer dans le panel d ' elements
@ return Le QTreeWidgetItem insere le plus haut
*/
2012-02-06 21:21:43 +00:00
QTreeWidgetItem * ElementsPanel : : addProject ( QETProject * project ) {
2012-02-12 17:17:44 +00:00
bool first_add = ( first_reload_ | | ! projects_to_display_ . contains ( project ) ) ;
2012-02-06 21:21:43 +00:00
// create the QTreeWidgetItem representing the project
QTreeWidgetItem * qtwi_project = GenericPanel : : addProject ( project , 0 , GenericPanel : : All ) ;
2012-01-08 17:04:34 +00:00
// the project will be inserted right before the common tb templates collection
2012-02-06 21:21:43 +00:00
invisibleRootItem ( ) - > insertChild (
indexOfTopLevelItem ( common_tbt_collection_item_ ) ,
qtwi_project
2009-04-03 19:30:25 +00:00
) ;
2012-02-12 17:17:44 +00:00
if ( first_add ) qtwi_project - > setExpanded ( true ) ;
2012-02-12 16:47:37 +00:00
if ( TitleBlockTemplatesCollection * tbt_collection = project - > embeddedTitleBlockTemplatesCollection ( ) ) {
if ( QTreeWidgetItem * tbt_collection_qtwi = itemForTemplatesCollection ( tbt_collection ) ) {
2012-02-12 17:17:44 +00:00
if ( first_add ) tbt_collection_qtwi - > setExpanded ( true ) ;
2012-02-12 16:47:37 +00:00
}
}
if ( ElementsCollection * elmt_collection = project - > embeddedCollection ( ) ) {
if ( QTreeWidgetItem * elmt_collection_qtwi = itemForElementsCollection ( elmt_collection ) ) {
2012-05-03 05:28:28 +00:00
2012-02-12 17:17:44 +00:00
if ( first_add ) elmt_collection_qtwi - > setExpanded ( true ) ;
2012-02-12 16:47:37 +00:00
}
}
2006-10-27 15:47:22 +00:00
2012-04-28 16:45:13 +00:00
qtwi_project - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper ce projet " , " Status tip " ) ) ;
2009-04-03 19:30:25 +00:00
return ( qtwi_project ) ;
2006-10-27 15:47:22 +00:00
}
2006-10-28 19:39:43 +00:00
2009-04-03 19:30:25 +00:00
/**
Methode privee permettant d ' ajouter une collection d ' elements au panel d ' elements
@ param qtwi_parent QTreeWidgetItem parent sous lequel sera insere la collection d ' elements
@ param collection Collection a inserer dans le panel d ' elements - si
collection vaut 0 , cette methode retourne 0.
@ param coll_name Nom a utiliser pour la collection
@ param icon Icone a utiliser pour l ' affichage de la collection
@ return Le QTreeWidgetItem insere le plus haut
*/
2012-02-06 22:34:52 +00:00
QTreeWidgetItem * ElementsPanel : : addCollection ( ElementsCollection * collection ) {
2012-02-06 21:21:43 +00:00
PanelOptions options = GenericPanel : : AddAllChild ;
options | = GenericPanel : : DisplayElementsPreview ;
2012-02-06 22:34:52 +00:00
return ( addElementsCollection ( collection , invisibleRootItem ( ) , options ) ) ;
2009-04-03 19:30:25 +00:00
}
2012-05-03 05:28:28 +00:00
QTreeWidgetItem * ElementsPanel : : updateTemplatesCollectionItem ( QTreeWidgetItem * tbt_collection_qtwi , TitleBlockTemplatesCollection * tbt_collection , PanelOptions options , bool freshly_created ) {
QTreeWidgetItem * tbtc_qtwi = GenericPanel : : updateTemplatesCollectionItem ( tbt_collection_qtwi , tbt_collection , options , freshly_created ) ;
if ( tbt_collection & & tbt_collection - > parentProject ( ) ) {
2012-05-10 06:13:23 +00:00
tbtc_qtwi - > setText ( 0 , tr ( " Cartouches embarqu \351 s " ) ) ;
2012-05-03 05:28:28 +00:00
tbtc_qtwi - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper cette collection de cartouches embarqu \351 e " , " Status tip " ) ) ;
}
return ( tbtc_qtwi ) ;
}
2012-02-06 21:21:43 +00:00
QTreeWidgetItem * ElementsPanel : : updateTemplateItem ( QTreeWidgetItem * tb_template_qtwi , const TitleBlockTemplateLocation & tb_template , PanelOptions options , bool freshly_created ) {
QTreeWidgetItem * item = GenericPanel : : updateTemplateItem ( tb_template_qtwi , tb_template , options , freshly_created ) ;
item - > setStatusTip (
0 ,
tr (
" Cliquer-d \351 posez ce mod \350 le de cartouche sur un sch \351 ma pour l'y appliquer. " ,
2012-04-28 16:45:13 +00:00
" Status tip displayed when selecting a title block template "
2012-02-06 21:21:43 +00:00
)
) ;
return ( item ) ;
}
QTreeWidgetItem * ElementsPanel : : updateElementsCategoryItem ( QTreeWidgetItem * category_qtwi , ElementsCategory * category , PanelOptions options , bool freshly_created ) {
QTreeWidgetItem * item = GenericPanel : : updateElementsCategoryItem ( category_qtwi , category , options , freshly_created ) ;
2012-04-28 16:45:13 +00:00
item - > setStatusTip (
0 ,
tr (
" Double-cliquez pour r \351 duire ou d \351 velopper cette cat \351 gorie d' \351 l \351 ments " ,
" Status tip displayed by elements category "
)
) ;
2011-03-15 20:06:40 +00:00
emit ( loadingProgressed ( + + loading_progress_ , - 1 ) ) ;
2012-02-06 21:21:43 +00:00
return ( item ) ;
2006-11-11 18:25:42 +00:00
}
2012-05-03 05:28:28 +00:00
QTreeWidgetItem * ElementsPanel : : updateElementsCollectionItem ( QTreeWidgetItem * collection_qtwi , ElementsCollection * collection , PanelOptions options , bool freshly_created ) {
QTreeWidgetItem * c_qtwi = GenericPanel : : updateElementsCollectionItem ( collection_qtwi , collection , options , freshly_created ) ;
if ( collection & & collection - > project ( ) ) {
2012-05-10 06:13:23 +00:00
c_qtwi - > setText ( 0 , tr ( " Collection embarqu \351 e " ) ) ;
2012-05-03 05:28:28 +00:00
c_qtwi - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper cette collection d' \351 l \351 ments embarqu \351 e " , " Status tip " ) ) ;
}
return ( c_qtwi ) ;
}
2012-02-06 21:21:43 +00:00
QTreeWidgetItem * ElementsPanel : : updateElementItem ( QTreeWidgetItem * element_qtwi , ElementDefinition * element , PanelOptions options , bool freshly_created ) {
QTreeWidgetItem * item = GenericPanel : : updateElementItem ( element_qtwi , element , options , freshly_created ) ;
2011-09-13 21:46:10 +00:00
2012-01-22 10:40:37 +00:00
QString status_tip = tr (
2012-04-28 16:45:13 +00:00
" Cliquer-d \351 posez cet \351 l \351 ment sur un sch \351 ma pour y ins \351 rer un \351 l \351 ment \253 %1 \273 , double-cliquez dessus pour l' \351 diter " ,
" Status tip displayed in the status bar when selecting an element "
2012-01-22 10:40:37 +00:00
) ;
2012-02-06 21:21:43 +00:00
item - > setStatusTip ( 0 , status_tip . arg ( item - > text ( 0 ) ) ) ;
2009-04-03 19:30:25 +00:00
2012-02-06 21:21:43 +00:00
item - > setFlags ( Qt : : ItemIsSelectable | Qt : : ItemIsDragEnabled | Qt : : ItemIsEnabled ) ;
2012-01-08 17:04:34 +00:00
2012-02-06 21:21:43 +00:00
emit ( loadingProgressed ( + + loading_progress_ , - 1 ) ) ;
return ( item ) ;
2012-01-08 17:04:34 +00:00
}
2012-02-12 15:33:04 +00:00
/**
@ return true if \ a item matches the current filter , false otherwise
*/
bool ElementsPanel : : matchesCurrentFilter ( const QTreeWidgetItem * item ) const {
if ( ! item ) return ( false ) ;
// no filter => we consider the item matches
if ( filter_ . isEmpty ( ) ) return ( true ) ;
bool item_matches = item - > text ( 0 ) . contains ( filter_ , Qt : : CaseInsensitive ) ;
return ( item_matches ) ;
}
2011-03-15 20:06:40 +00:00
/**
Reloads the following collections :
* common collection
* custom collection
* collection of every project displayed in this panel
*/
void ElementsPanel : : reloadCollections ( ) {
2013-01-27 15:48:14 +00:00
QETApp : : commonElementsCollection ( ) - > reload ( ) ;
QETApp : : customElementsCollection ( ) - > reload ( ) ;
// reloads collection of every project displayed in this panel
foreach ( QETProject * project , projects_to_display_ ) {
if ( ElementsCollection * project_collection = project - > embeddedCollection ( ) ) {
project_collection - > reload ( ) ;
}
2011-03-15 20:06:40 +00:00
}
}
/**
@ return the count of categories and elements within the following collections :
* common collection
* custom collection
* collection of every project displayed in this panel
*/
int ElementsPanel : : elementsCollectionItemsCount ( ) {
int items_count = 0 ;
items_count + = QETApp : : commonElementsCollection ( ) - > count ( ) ;
items_count + = QETApp : : customElementsCollection ( ) - > count ( ) ;
foreach ( QETProject * project , projects_to_display_ . values ( ) ) {
if ( ElementsCollection * project_collection = project - > embeddedCollection ( ) ) {
items_count + = project_collection - > count ( ) ;
}
}
return ( items_count ) ;
}
2012-04-29 20:29:40 +00:00
/**
@ return true if freshly integrated elements should be highlighted , false otherwise .
*/
bool ElementsPanel : : mustHighlightIntegratedElements ( ) const {
return ( QETApp : : settings ( ) . value ( " diagrameditor/highlight-integrated-elements " , true ) . toBool ( ) ) ;
}
2007-02-26 22:42:46 +00:00
/**
Recharge l ' arbre des elements
2009-04-03 19:30:25 +00:00
@ param reload_collections true pour relire les collections depuis leurs sources ( fichiers , projets . . . )
2007-02-26 22:42:46 +00:00
*/
2009-04-03 19:30:25 +00:00
void ElementsPanel : : reload ( bool reload_collections ) {
if ( reload_collections ) {
2011-03-15 20:06:40 +00:00
emit ( readingAboutToBegin ( ) ) ;
reloadCollections ( ) ;
emit ( readingFinished ( ) ) ;
2009-04-03 19:30:25 +00:00
}
2012-01-08 17:04:34 +00:00
QIcon system_icon ( " :/ico/16x16/qet.png " ) ;
QIcon user_icon ( " :/ico/16x16/go-home.png " ) ;
2011-03-15 20:06:40 +00:00
// estimates the number of categories and elements to load
int items_count = elementsCollectionItemsCount ( ) ;
emit ( loadingProgressed ( loading_progress_ = 0 , items_count ) ) ;
2012-01-08 17:04:34 +00:00
// load the common title block templates collection
TitleBlockTemplatesCollection * common_tbt_collection = QETApp : : commonTitleBlockTemplatesCollection ( ) ;
2012-02-06 21:21:43 +00:00
common_tbt_collection_item_ = addTemplatesCollection ( common_tbt_collection , invisibleRootItem ( ) ) ;
common_tbt_collection_item_ - > setIcon ( 0 , system_icon ) ;
2012-04-28 16:45:13 +00:00
common_tbt_collection_item_ - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper la collection de cartouches QElectroTech " , " Status tip " ) ) ;
common_tbt_collection_item_ - > setWhatsThis ( 0 , tr ( " Ceci est la collection de cartouches fournie avec QElectroTech. Install \351 e en tant que composant syst \350 me, vous ne pouvez normalement pas la personnaliser. " , " \" What's this \" tip " ) ) ;
2012-01-08 17:04:34 +00:00
if ( first_reload_ ) common_tbt_collection_item_ - > setExpanded ( true ) ;
2012-02-06 21:21:43 +00:00
// load the common elements collection
2012-04-28 16:45:13 +00:00
if ( QETApp : : commonElementsCollection ( ) - > rootCategory ( ) ) {
2012-02-06 22:34:52 +00:00
common_collection_item_ = addCollection ( QETApp : : commonElementsCollection ( ) ) ;
2012-04-28 16:45:13 +00:00
common_collection_item_ - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper la collection d' \351 l \351 ments QElectroTech " , " Status tip " ) ) ;
common_collection_item_ - > setWhatsThis ( 0 , tr ( " Ceci est la collection d' \351 l \351 ments fournie avec QElectroTech. Install \351 e en tant que composant syst \350 me, vous ne pouvez normalement pas la personnaliser. " , " \" What's this \" tip " ) ) ;
2011-05-10 11:39:28 +00:00
if ( first_reload_ ) common_collection_item_ - > setExpanded ( true ) ;
}
2007-02-26 22:42:46 +00:00
2012-01-08 17:04:34 +00:00
// load the custom title block templates collection
TitleBlockTemplatesCollection * custom_tbt_collection = QETApp : : customTitleBlockTemplatesCollection ( ) ;
2012-02-06 21:21:43 +00:00
custom_tbt_collection_item_ = addTemplatesCollection ( custom_tbt_collection , invisibleRootItem ( ) ) ;
custom_tbt_collection_item_ - > setIcon ( 0 , user_icon ) ;
2012-04-28 16:45:13 +00:00
custom_tbt_collection_item_ - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper votre collection personnelle de cartouches " , " Status tip " ) ) ;
custom_tbt_collection_item_ - > setWhatsThis ( 0 , tr ( " Ceci est votre collection personnelle de cartouches -- utilisez-la pour cr \351 er, stocker et \351 diter vos propres cartouches. " , " \" What's this \" tip " ) ) ;
2012-01-08 17:04:34 +00:00
if ( first_reload_ ) custom_tbt_collection_item_ - > setExpanded ( true ) ;
2012-02-06 21:21:43 +00:00
// load the custom elements collection
2012-04-28 16:45:13 +00:00
if ( QETApp : : customElementsCollection ( ) - > rootCategory ( ) ) {
2012-02-06 22:34:52 +00:00
custom_collection_item_ = addCollection ( QETApp : : customElementsCollection ( ) ) ;
2012-04-28 16:45:13 +00:00
custom_collection_item_ - > setStatusTip ( 0 , tr ( " Double-cliquez pour r \351 duire ou d \351 velopper votre collection personnelle d' \351 l \351 ments " , " Status tip " ) ) ;
custom_collection_item_ - > setWhatsThis ( 0 , tr ( " Ceci est votre collection personnelle d' \351 l \351 ments -- utilisez-la pour cr \351 er, stocker et \351 diter vos propres \351 l \351 ments. " , " \" What's this \" tip " ) ) ;
2011-05-10 11:39:28 +00:00
if ( first_reload_ ) custom_collection_item_ - > setExpanded ( true ) ;
}
2007-10-16 12:49:04 +00:00
2012-02-06 21:21:43 +00:00
// add projects
2009-04-03 19:30:25 +00:00
foreach ( QETProject * project , projects_to_display_ . values ( ) ) {
2012-02-06 21:21:43 +00:00
addProject ( project ) ;
2007-12-20 19:18:31 +00:00
}
2012-01-08 17:04:34 +00:00
// the first time, expand the first level of collections
if ( first_reload_ ) first_reload_ = false ;
2013-01-29 23:03:09 +00:00
emit ( loadingFinished ( ) ) ;
2007-02-26 22:42:46 +00:00
}
2007-06-30 17:41:07 +00:00
2007-10-10 17:50:26 +00:00
/**
2009-04-03 19:30:25 +00:00
Gere le double - clic sur un element .
Si un double - clic sur un projet est effectue , le signal requestForProject
est emis .
Si un double - clic sur un schema est effectue , le signal requestForDiagram
est emis .
Si un double - clic sur une collection , une categorie ou un element est
effectue , le signal requestForCollectionItem est emis .
@ param qtwi
2007-10-10 17:50:26 +00:00
*/
2009-04-03 19:30:25 +00:00
void ElementsPanel : : slot_doubleClick ( QTreeWidgetItem * qtwi , int ) {
2012-02-06 21:21:43 +00:00
int qtwi_type = qtwi - > type ( ) ;
if ( qtwi_type = = QET : : Project ) {
QETProject * project = valueForItem < QETProject * > ( qtwi ) ;
2009-04-03 19:30:25 +00:00
emit ( requestForProject ( project ) ) ;
2012-02-06 21:21:43 +00:00
} else if ( qtwi_type = = QET : : Diagram ) {
Diagram * diagram = valueForItem < Diagram * > ( qtwi ) ;
2009-04-03 19:30:25 +00:00
emit ( requestForDiagram ( diagram ) ) ;
2012-02-06 21:21:43 +00:00
} else if ( qtwi_type & QET : : ElementsCollectionItem ) {
ElementsLocation element = valueForItem < ElementsLocation > ( qtwi ) ;
emit ( requestForCollectionItem ( element ) ) ;
} else if ( qtwi_type = = QET : : TitleBlockTemplate ) {
TitleBlockTemplateLocation tbt = valueForItem < TitleBlockTemplateLocation > ( qtwi ) ;
emit ( requestForTitleBlockTemplate ( tbt ) ) ;
2009-04-03 19:30:25 +00:00
}
}
/**
2012-02-06 21:21:43 +00:00
@ param qtwi Un QTreeWidgetItem
@ return L ' ElementsCollectionItem represente par qtwi , ou 0 si qtwi ne
represente pas un ElementsCollectionItem
2009-04-03 19:30:25 +00:00
*/
2012-02-06 21:21:43 +00:00
ElementsCollectionItem * ElementsPanel : : collectionItemForItem ( QTreeWidgetItem * qtwi ) const {
if ( qtwi & & qtwi - > type ( ) & QET : : ElementsCollectionItem ) {
ElementsLocation item_location = elementLocationForItem ( qtwi ) ;
return ( QETApp : : collectionItem ( item_location ) ) ;
2009-04-03 19:30:25 +00:00
}
2012-02-06 21:21:43 +00:00
return ( 0 ) ;
2007-08-28 21:17:11 +00:00
}
2007-10-10 17:50:26 +00:00
/**
2012-02-06 21:21:43 +00:00
Cette methode permet d ' acceder a la categorie correspondant a un item donne .
Si cet item represente une collection , c ' est sa categorie racine qui est renvoyee .
Si cet item represente une categorie , c ' est cette categorie qui est renvoyee .
Si cet item represente un element , c ' est sa categorie parente qui est renvoyee .
@ param qtwi un QTreeWidgetItem
@ return la categorie correspondant au QTreeWidgetItem qtwi , ou 0 s ' il n ' y a
aucune categorie correspondante .
2007-10-10 17:50:26 +00:00
*/
2012-02-06 21:21:43 +00:00
ElementsCategory * ElementsPanel : : categoryForItem ( QTreeWidgetItem * qtwi ) {
if ( ! qtwi ) return ( 0 ) ;
2011-10-01 19:22:30 +00:00
2012-02-06 21:21:43 +00:00
// Recupere le CollectionItem associe a cet item
ElementsCollectionItem * collection_item = collectionItemForItem ( qtwi ) ;
if ( ! collection_item ) return ( 0 ) ;
2011-10-01 19:22:30 +00:00
2012-02-06 21:21:43 +00:00
// recupere la categorie cible pour le deplacement
return ( collection_item - > toCategory ( ) ) ;
2007-08-28 21:17:11 +00:00
}
/**
2009-04-03 19:30:25 +00:00
@ param pos Position dans l ' arborescence
@ return La categorie situee sous la position pos , ou 0 s ' il n ' y a aucune
categorie correspondante .
@ see categoryForItem
2007-08-28 21:17:11 +00:00
*/
2009-04-03 19:30:25 +00:00
ElementsCategory * ElementsPanel : : categoryForPos ( const QPoint & pos ) {
// Accede a l'item sous la position
QTreeWidgetItem * pos_qtwi = itemAt ( pos ) ;
if ( ! pos_qtwi ) {
return ( 0 ) ;
}
2007-08-28 21:17:11 +00:00
2009-04-03 19:30:25 +00:00
return ( categoryForItem ( pos_qtwi ) ) ;
2007-08-28 21:17:11 +00:00
}
2013-02-03 19:22:58 +00:00
/**
@ param qtwi a QTreeWidgetItem
@ return the directory path of the object represented by \ a qtwi
*/
QString ElementsPanel : : dirPathForItem ( QTreeWidgetItem * item ) {
QString file_path = filePathForItem ( item ) ;
if ( ! file_path . isEmpty ( ) ) {
QFileInfo path_info ( file_path ) ;
if ( path_info . isDir ( ) ) {
return ( file_path ) ;
}
else {
return ( path_info . canonicalPath ( ) ) ;
}
}
return ( QString ( ) ) ;
}
/**
@ param qtwi a QTreeWidgetItem
@ return the filepath of the object represented by \ a qtwi
*/
QString ElementsPanel : : filePathForItem ( QTreeWidgetItem * item ) {
if ( ! item ) return ( QString ( ) ) ;
ElementsCollectionItem * collection_item = collectionItemForItem ( item ) ;
if ( collection_item ) {
if ( collection_item - > hasFilePath ( ) ) {
return ( collection_item - > filePath ( ) ) ;
}
}
else {
TitleBlockTemplateLocation tbt_location = templateLocationForItem ( item ) ;
TitleBlockTemplatesCollection * tbt_collection = tbt_location . parentCollection ( ) ;
if ( tbt_collection & & tbt_collection - > hasFilePath ( ) ) {
return ( tbt_collection - > filePath ( ) ) ;
}
else {
QETProject * project = projectForItem ( item ) ;
if ( project ) {
return ( project - > filePath ( ) ) ;
}
}
}
return ( QString ( ) ) ;
}
2010-12-24 21:00:11 +00:00
/**
2012-02-06 21:21:43 +00:00
Hide items that do not match the provided string , ensure others are visible
along with their parent hierarchy . When ending the filtering , restore the tree
as it was before the filtering ( except the current item ) and scroll to the
currently selected item .
@ param m String to be matched
@ param filtering whether to begin / apply / end the filtering
@ see QET : : Filtering
2007-10-10 17:50:26 +00:00
*/
2012-02-06 21:21:43 +00:00
void ElementsPanel : : filter ( const QString & m , QET : : Filtering filtering ) {
QList < QTreeWidgetItem * > items = findItems ( " * " , Qt : : MatchRecursive | Qt : : MatchWildcard ) ;
const int expanded_role = 42 ; // magic number? So you consider Douglas Adams wrote about magic?
2007-06-30 17:41:07 +00:00
2012-02-06 21:21:43 +00:00
if ( filtering = = QET : : BeginFilter ) {
foreach ( QTreeWidgetItem * item , items ) {
item - > setData ( 0 , expanded_role , item - > isExpanded ( ) ) ;
}
}
2009-04-03 19:30:25 +00:00
2012-02-06 21:21:43 +00:00
if ( filtering ! = QET : : EndFilter ) {
2012-02-12 15:33:04 +00:00
filter_ = m ;
applyCurrentFilter ( items ) ;
2012-02-06 21:21:43 +00:00
} else { // filtering == QET::EndFilter
2012-02-12 15:33:04 +00:00
filter_ = QString ( ) ;
2012-02-06 21:21:43 +00:00
QTreeWidgetItem * current_item = currentItem ( ) ;
// restore the tree as it was before the filtering
foreach ( QTreeWidgetItem * qtwi , items ) {
qtwi - > setHidden ( false ) ;
qtwi - > setExpanded ( qtwi - > data ( 0 , expanded_role ) . toBool ( ) ) ;
}
// avoid hiding the currently selected item
if ( current_item ) {
ensureHierarchyIsVisible ( QList < QTreeWidgetItem * > ( ) < < current_item ) ;
scrollToItem ( current_item ) ;
}
2007-06-30 17:41:07 +00:00
}
}
2007-08-28 21:17:11 +00:00
2009-04-03 19:30:25 +00:00
/**
Rajoute un projet au panel d ' elements
@ param project Projet ouvert a rajouter au panel
*/
void ElementsPanel : : projectWasOpened ( QETProject * project ) {
2012-02-06 21:21:43 +00:00
addProject ( project ) ;
2012-02-12 17:17:44 +00:00
projects_to_display_ < < project ;
2012-02-12 16:47:37 +00:00
emit ( panelContentChanged ( ) ) ;
2007-08-28 21:17:11 +00:00
}
2007-10-10 17:50:26 +00:00
/**
2009-04-03 19:30:25 +00:00
Enleve un projet du panel d ' elements
@ param project Projet a enlever du panel
2007-10-10 17:50:26 +00:00
*/
2009-04-03 19:30:25 +00:00
void ElementsPanel : : projectWasClosed ( QETProject * project ) {
2012-02-06 21:21:43 +00:00
if ( QTreeWidgetItem * item_to_remove = itemForProject ( project ) ) {
GenericPanel : : deleteItem ( item_to_remove ) ;
2009-04-03 19:30:25 +00:00
projects_to_display_ . remove ( project ) ;
}
2012-02-12 16:47:37 +00:00
emit ( panelContentChanged ( ) ) ;
2007-08-28 21:17:11 +00:00
}
2009-05-19 19:00:37 +00:00
/**
Affiche un element etant donne son emplacement
@ param location Emplacement de l ' element a afficher
*/
bool ElementsPanel : : scrollToElement ( const ElementsLocation & location ) {
// recherche l'element dans le panel
2012-02-06 21:21:43 +00:00
QTreeWidgetItem * item = itemForElementsLocation ( location ) ;
2009-05-19 19:00:37 +00:00
if ( ! item ) return ( false ) ;
// s'assure que l'item ne soit pas filtre
item - > setHidden ( false ) ;
setCurrentItem ( item ) ;
ensureHierarchyIsVisible ( QList < QTreeWidgetItem * > ( ) < < item ) ;
scrollToItem ( item ) ;
return ( true ) ;
}
2012-02-12 15:33:04 +00:00
/**
Apply the current filter to a given item .
*/
void ElementsPanel : : applyCurrentFilter ( const QList < QTreeWidgetItem * > & items ) {
if ( filter_ . isEmpty ( ) ) return ;
QList < QTreeWidgetItem * > matching_items ;
foreach ( QTreeWidgetItem * item , items ) {
bool item_matches = matchesCurrentFilter ( item ) ;
if ( item_matches ) matching_items < < item ;
item - > setHidden ( ! item_matches ) ;
}
ensureHierarchyIsVisible ( matching_items ) ;
}
2009-05-19 19:00:37 +00:00
/**
2009-11-22 16:12:22 +00:00
@ param items une liste de QTreeWidgetItem pour lesquels il faut s ' assurer
que eux et leurs parents sont visibles
2009-05-19 19:00:37 +00:00
*/
2012-02-12 15:33:04 +00:00
void ElementsPanel : : ensureHierarchyIsVisible ( const QList < QTreeWidgetItem * > & items ) {
2009-05-19 19:00:37 +00:00
// remonte l'arborescence pour lister les categories contenant les elements filtres
QSet < QTreeWidgetItem * > parent_items ;
foreach ( QTreeWidgetItem * item , items ) {
for ( QTreeWidgetItem * parent_qtwi = item - > parent ( ) ; parent_qtwi ; parent_qtwi = parent_qtwi - > parent ( ) ) {
parent_items < < parent_qtwi ;
}
}
// etend les parents
foreach ( QTreeWidgetItem * parent_qtwi , parent_items ) {
if ( ! parent_qtwi - > isExpanded ( ) ) parent_qtwi - > setExpanded ( true ) ;
}
// affiche les parents
foreach ( QTreeWidgetItem * parent_qtwi , parent_items ) {
if ( parent_qtwi - > isHidden ( ) ) parent_qtwi - > setHidden ( false ) ;
}
}
2012-04-28 16:45:16 +00:00
/**
Scroll to the currently selected item .
*/
void ElementsPanel : : scrollToSelectedItem ( ) {
QList < QTreeWidgetItem * > selected_items = selectedItems ( ) ;
if ( selected_items . count ( ) ) {
scrollToItem ( selected_items . first ( ) , QAbstractItemView : : PositionAtCenter ) ;
}
}
/**
Scroll to and highlight \ a items . Once the animation is finished , the slot
\ a method is called on the object \ a receiver .
*/
void ElementsPanel : : highlightItems ( const QList < QTreeWidgetItem * > & items , const QObject * receiver , const char * method ) {
TreeColorAnimation * animation1 = new TreeColorAnimation ( items ) ;
animation1 - > setStartValue ( QColor ( Qt : : white ) ) ;
animation1 - > setEndValue ( QColor ( Qt : : yellow ) ) ;
animation1 - > setDuration ( 400 ) ;
animation1 - > setEasingCurve ( QEasingCurve : : InQuad ) ;
TreeColorAnimation * animation2 = new TreeColorAnimation ( items ) ;
animation2 - > setStartValue ( QColor ( Qt : : yellow ) ) ;
animation2 - > setEndValue ( QColor ( Qt : : white ) ) ;
animation2 - > setDuration ( 500 ) ;
animation2 - > setEasingCurve ( QEasingCurve : : OutInQuint ) ;
QSequentialAnimationGroup * animation = new QSequentialAnimationGroup ( this ) ;
animation - > addAnimation ( animation1 ) ;
animation - > addAnimation ( new QPauseAnimation ( 700 ) ) ;
animation - > addAnimation ( animation2 ) ;
if ( receiver ) {
connect ( animation , SIGNAL ( finished ( ) ) , receiver , method ) ;
}
animation - > start ( QAbstractAnimation : : DeleteWhenStopped ) ;
}