All pastes #170305 Raw Edit

Sans nom

public text v1 · immutable
·published 2006-09-14 14:36 UTC
rendered paste body
//
// Classe cArbre : Gestion de la multisélection sur un champ de type arbre
//

cArbre est une classe
	
	PROTÉGÉ
		m_sNomArbre 					est une chaîne				// Nom de l'arbre que l'on va gérer	
		m_bMultiSélectionAutorisée 		est un booléen				// MultiSélection ou non ?
		m_TabElementsSélectionnés 		est un tableau de 0 entiers	// Tableau des indices des éléments sélectionnés                   
		m_nNombreElémentsSélectionnés 	est un entier				// Nombre d'éléments sélectionnés (Correspond au dimension(m_TabElementsSélectionnés)
		m_TabElementsTreeview 			est un tableau de 0 chaîne	// Tableau contenant les éléments de l'arbre
		
	PRIVÉ
		m_bErreurDétectée 				est un booléen	// Une erreur est survenue
		m_sErreurInfo 					est une chaîne	// Dernière erreur rencontrée
		m_nCouleurSélection 			est un entier	// Couleur du bandeau de sélection
		m_nCouleurPolice 				est un entier	// Couleur de la police d'un élément sélectionné
		m_nCouleurFondDéfaut 			est un entier	// Couleur de fond de l'arbre
		m_nCouleurPoliceDéfaut			est un entier	// Couleur de la police par défaut
		m_nDernierIndiceSélectionné 	est un entier	// Indice du dernier élément sélectionné
		m_bForceSélection 				est un booléen	// Doit-on forcer la sélection ?
		
FIN

PROCEDURE Constructeur(sNomCompletArbre,bMultiSélection = Faux)

sNomRéduitArbre est une chaîne	// nom réduit du champ arbre

// RAZ des erreurs
:_VideErreur()

// Vérification de l'existence du champ
SI ChampExiste(snomcompletarbre) = Faux ALORS
	:_SetErreur(ChaîneConstruit("Le champ <%1> n'existe pas." , sNomCompletArbre))
	RENVOYER Faux
FIN
// Vérification du type du champ
SI {snomcompletarbre,indChamp}..Type <> typTreeView ALORS
	:_SetErreur(ChaîneConstruit("Le champ <%1> n'est pas un champ de type arbre." , sNomCompletArbre))
	RENVOYER Faux
FIN

// Active ou non la multi sélection
:SetSélectionMultiple(bMultiSélection)

// Sauvegarde des options de l'arbre
:m_sNomArbre 				= sNomCompletArbre
:m_nCouleurFondDéfaut 		= {:m_sNomArbre,indChamp}..CouleurFond
:m_nCouleurPoliceDéfaut 	= {:m_sNomArbre,indChamp}..Couleur

// On met les couleurs par défaut
:SetCouleurs()

// Récupération du nom réduit de l'arbre pour pouvoir poser les évenements dessus
sNomRéduitArbre = ExtraitChaîne(sNomCompletArbre , 1 , "." , DepuisFin)
// On pose un évènement sur le bouton gauche enfoncé pour effectuer les sélections
Evénement(":__SélectionneEvt" , sNomRéduitArbre , WM_LBUTTONDOWN)

RENVOYER Vrai
PROCEDURE Destructeur()
// Syntaxe :
//_SetErreur (<sMessageErreur>)
//
// Paramètres :
//	sMessageErreur : message d'erreur
// Valeur de retour :
// 	Aucune

PROCEDURE PRIVÉE  _SetErreur(sMessageErreur)

:m_sErreurInfo 		= sMessageErreur
:m_bErreurDétectée 	= Vrai
// Syntaxe :
//_VideErreur ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	Aucune

PROCEDURE PRIVÉE  _VideErreur()

:m_sErreurInfo 		= ""
:m_bErreurDétectée 	= Faux
// Syntaxe :
//[ <Résultat> = ] ArbreSelectPlus (<sNoeud>)
//
// Paramètres :
//	sNoeud : 	noeud à sélectionner dans l'arbre
// Valeur de retour :
// 	booléen : 	VRAI si la sélection est effective, FAUX autrement

PROCEDURE ArbreSelectPlus(sNoeud)

nIndiceTableau est un entier
nIndiceTableauSélection est un entier

// RAZ des erreurs
:_VideErreur()

// Recherche du noeud dans le tableau des éléments
nIndiceTableau = TableauCherche(:m_TabElementsTreeview , tcLinéaire , snoeud)

// Si le noeud n'est pas trouvé, on sort
SI nIndiceTableau <= 0 ALORS
	:_SetErreur("Impossible de trouver le noeud à sélectionner")
	RENVOYER Faux
FIN

// Si la multisélection n'est pas autorisée et que l'on ne doit pas forcer la sélection
SI :m_bMultiSélectionAutorisée = Faux _ET_ :m_bForceSélection = Faux ALORS
	// On enlève la sélection précédente
	:_EnlèveSélection()
FIN

// Si la sélection ne doit pas être forcée et que la touche control n'est pas enfoncée
SI :m_bForceSélection = Faux _ET_ ToucheEnfoncée(teControl , Vrai) = Faux ALORS
	// Pas de multisélection
	// On enlève la sélection courante
	:_EnlèveSélection()
FIN

// Gestion de la multisélection avec la touche SHIFT
SI ToucheEnfoncée(teShift,Vrai) = Vrai ET :m_bMultiSélectionAutorisée ALORS
	// On sélectionne entre deux
	:__SélectionneEntreDeux(nIndiceTableau)
	// La sélection est faite, on renvoie VRAI
	RENVOYER Vrai
	
SINON
	
	// Recherche de l'élément en cours dans le tableau des éléments sélectionnés
	// S'il est déjà sélectionné, on le désélectionne, sinon, on le sélectionne
	nIndiceTableauSélection = TableauCherche(:m_TabElementsSélectionnés , tcLinéaire , nIndiceTableau)
	SI nIndiceTableauSélection > 0 ALORS
		
		// On l'a trouvé
		// On le désélectionne
		:_EnlèveSélection(nindicetableausélection)
		
	SINON
		
		nIndiceArbre est un entier
		
		// Récupération de l'indice de l'arbre correspondant au noeud que l'on doit sélectionner
		nIndiceArbre = :__GetIndiceAffiché(nIndiceTableau)
		
		// Mise à jour de la couleur de fond et de la couleur de la police
		{:m_sNomArbre,indChamp}[nIndiceArbre]..CouleurFond 	= :m_nCouleurSélection
		{:m_sNomArbre,indChamp}[nIndiceArbre]..Couleur 		= :m_nCouleurPolice
		
		// Sauvegarde de l'élément sélectionné
		TableauAjoute(:m_TabElementsSélectionnés , nIndiceTableau)
		:m_nNombreElémentsSélectionnés++
	
		// Sauvegarde du dernier élément sélectionné
		:m_nDernierIndiceSélectionné = nindicetableau
		
		// On force la sélection de cet élément
		WL.ArbreSelectPlus(:m_sNomArbre , {:m_sNomArbre,indChamp}[nIndiceArbre])
		
		// On exécute le traitement de sélection utilisateur
		ExécuteTraitement(:m_sNomArbre , trtSélection)
		
	FIN	
	
FIN

// La sélection est faite, on renvoie VRAI
RENVOYER Vrai
// Syntaxe :
//_EnlèveSélection ( [<nIndiceSélectionné>])
//
// Paramètres :
//	nIndiceSélectionné (valeur par défaut=-1) : indice de l'élément sélectionné dans le tableau des éléments sélectionnés
// Valeur de retour :
// 	Aucune

PROCEDURE PRIVÉE  _EnlèveSélection(nIndiceSélectionné = -1)
i est un entier

// Un indice à déselectionné est passé en paramètre
SI nIndiceSélectionné <> -1 ALORS

	// Supprime l'élément demandé
	{:m_sNomArbre,indChamp}[:__GetIndiceAffiché(:m_TabElementsSélectionnés[nIndiceSélectionné])]..CouleurFond = :m_nCouleurFondDéfaut
	{:m_sNomArbre,indChamp}[:__GetIndiceAffiché(:m_TabElementsSélectionnés[nIndiceSélectionné])]..Couleur = :m_nCouleurPoliceDéfaut
	TableauSupprime(:m_TabElementsSélectionnés,nIndiceSélectionné)	
	:m_nNombreElémentsSélectionnés--	

SINON	// Aucun indice passé en paramètre
	
	// Déselectionne tous les éléments sélectionnés
	POUR i = 1 A :m_nNombreElémentsSélectionnés
		// Commence par enlever les couleurs de fond et changer la couleur de la police
		{:m_sNomArbre,indChamp}[:__GetIndiceAffiché(:m_TabElementsSélectionnés[i])]..CouleurFond = :m_nCouleurFondDéfaut
		{:m_sNomArbre,indChamp}[:__GetIndiceAffiché(:m_TabElementsSélectionnés[i])]..Couleur = :m_nCouleurPoliceDéfaut
	FIN
	// Supprime tout le tableau des élements sélectionnés
	TableauSupprimeTout(:m_TabElementsSélectionnés)
	// Remet le nombre d'éléments sélectionnés à 0
	:m_nNombreElémentsSélectionnés = 0
	
FIN
// Résumé : Positionne les couleurs de l'arbre de fond, de police, de sélection et de police lors d'une sélection
// Syntaxe :
//SetCouleurs ( [<nCouleurFond> [, <nCouleurPolice> [, <nCouleurSélection> [, <nCouleurPoliceSélection>]]]])
//
// Paramètres :
//	nCouleurFond (valeur par défaut=16777215) : 			couleur de fond de l'arbre
//	nCouleurPolice (valeur par défaut=0) : 					couleur de la police par défaut
//	nCouleurSélection (valeur par défaut=8388608) : 		couleur de sélection d'un élément dans l'arbre
//	nCouleurPoliceSélection (valeur par défaut=16777215) : 	couleur de la police d'un élément sélectionné
// Valeur de retour :
// 	Aucune

PROCEDURE SetCouleurs(nCouleurFond = iBlanc, nCouleurPolice = iNoir,nCouleurSélection = iBleuFoncé,nCouleurPoliceSélection = iBlanc )

:m_nCouleurFondDéfaut 	= ncouleurfond
:m_nCouleurPoliceDéfaut = nCouleurPolice
:m_nCouleurSélection 	= nCouleurSélection
:m_nCouleurPolice 		= nCouleurPoliceSélection
// Résumé : Appelée suite à l'évenement Clic Gauche sur l'arbre : sélectionne les noeuds/feuilles cliqués, enroule ou déroule les noeuds
// Syntaxe :
//[ <Résultat> = ] __SélectionneEvt (<nMessage>, <wParam>, <lParam>)
//
// Méthode appelée par l'évenement de sélection sur l'arbre
//
//
// Paramètres :
//	nMessage : 		numéro du message
//	wParam : 		premier paramètre
//	lParam : 		second paramètre
// Valeur de retour :
// 	booléen :    	VRAI
//
PROCEDURE PRIVÉE __SélectionneEvt(nMessage, wParam, lParam)

sNomBranche est une chaîne
nPosX 		est un entier = SourisPosX()
nPosY 		est un entier = SourisPosY()
nZone		est un entier = WL.ArbreInfoXY(:m_sNomArbre , aiZone , nposx , nposy) 

// Selon la zone de cliquage
SELON nzone

	// La sélection n'est effectuée que si le clic est sur le libellé, le bouton ou sur l'image
	CAS aizLibellé,aizBouton,aizImage
		
		// Vérification de l'état de l'arbre
		SI {:m_sNomArbre , indChamp}..Etat <> Actif ALORS
			RENVOYER Vrai
		FIN
		
		// Récupération de la branche sélectionnée
		snomBranche = WL.ArbreInfoXY(:m_sNomArbre, aiNomBranche , nposx , nposy)
		
		// Si c'est un clic sur le bouton, 
		SI nzone = aizBouton ALORS
			// Selon l'état précédent, on enroule ou on déroule la branche
			SI WL.ArbreEtat(:m_sNomArbre , snomBranche) = aEnroule ALORS
				WL.ArbreDéroule(:m_sNomArbre , snomBranche)
			SINON
				WL.ArbreEnroule(:m_sNomArbre , snomBranche)
			FIN
		FIN
		
		// Sélectionne le noeud
		:ArbreSelectPlus(snombranche)
		
	AUTRE CAS
		// Ne rien faire
FIN

RENVOYER Vrai
// Résumé : Sélectionne tous les noeuds/feuilles compris entre les deux derniers clics
// Syntaxe :
//__SélectionneEntreDeux (<nIndiceTableau>)
//
// Paramètres :
//	nIndiceTableau : indice du tableau de la dernière sélection
// Valeur de retour :
// 	Aucune

PROCEDURE PRIVÉE __SélectionneEntreDeux(nIndiceTableau)

i 						est un entier
nIndiceTableauSélection est un entier

// Sélectionne entre le dernier indice sélectionné et l'indice passé en paramètre
// On fait bien attention à ne pas dépasser les bornes de l'arbre (min : 1, et max : dimension(:m_TabElementsTreeview))
POUR i = Max(Min(nIndiceTableau , :m_nDernierIndiceSélectionné) , 1) A Min(Max(nIndiceTableau , :m_nDernierIndiceSélectionné) , Dimension(:m_TabElementsTreeview))
	
	// Recherche de l'élément en cours dans le tableau des éléments sélectionnés
	// S'il est déjà sélectionné, on le désélectionne, sinon, on le sélectionne
	nIndiceTableauSélection = TableauCherche(:m_TabElementsSélectionnés , tcLinéaire , i)
	SI nIndiceTableauSélection > 0 _ET_ i <> :m_nDernierIndiceSélectionné ALORS
		
		// On l'a trouvé
		// On le désélectionne
		:_EnlèveSélection(nindicetableausélection)
		
	SINON
		
		{:m_sNomArbre,indChamp}[i]..CouleurFond = :m_nCouleurSélection
		{:m_sNomArbre,indChamp}[i]..Couleur 	= :m_nCouleurPolice
		
		// Sauvegarde de l'élément sélectionné
		TableauAjoute(:m_TabElementsSélectionnés , i)
		:m_nNombreElémentsSélectionnés++
		
	FIN	
	
FIN
// Résumé : Renvoie le nombre de noeuds/feuilles sélectionnés
// Syntaxe :
//[ <Résultat> = ] ArbreSelectOccurrence ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	entier :      nombre d'éléments sélectionnés

PROCEDURE ArbreSelectOccurrence()

RENVOYER :m_nNombreElémentsSélectionnés
// Résumé : Renvoie le ième noeud sélectionné
// Syntaxe :
//[ <Résultat> = ] ArbreSelect ( [<nIndiceSélection>])
//
// Paramètres :
//	nIndiceSélection (valeur par défaut=-1) : 	indice de l'élément dans le tableau des éléments sélectionnés (dans le cas d'une multisélection
// Valeur de retour :
// 	Type indéterminé :        					noeud correspondant à cet indice de sélection, FAUX si l'indice de sélection est incorrecte

PROCEDURE ArbreSelect(nIndiceSélection=-1)

// RAZ de l'erreur
:_VideErreur()

// Si en mode Multisélection
SI :m_bMultiSélectionAutorisée ALORS
	
	// Vérification de l'indice de sélection
	SI PAS (1 <= nIndiceSélection <= :m_nNombreElémentsSélectionnés) ALORS
		:_SetErreur(ChaîneConstruit("L'indice de sélection doit être compris entre 1 et %1" , :m_nNombreElémentsSélectionnés))
		RENVOYER Faux
	FIN
	
	// Renvoie le noeud sélectionné de l'indice spécifié
	RENVOYER :m_TabElementsTreeview[:m_TabElementsSélectionnés[nIndiceSélection]]
	
SINON // Si en mode Monosélection

	// Renvoie LE noeud sélectionné
	RENVOYER :m_TabElementsTreeview[:m_TabElementsSélectionnés[1]]
	
FIN
// Résumé : Récupère l'indice d'un élément du champ arbre d'après son indice dans le tableau
// Syntaxe :
//[ <Résultat> = ] __GetIndiceAffiché (<nIndiceTableau>)
//
// Paramètres :
//	nIndiceTableau : 	indice de l'élément dans le tableau des éléments
// Valeur de retour :
// 	entier :     		position de ce noeu/de cette feuille dans le champ arbre

PROCEDURE PRIVÉE __GetIndiceAffiché(nIndiceTableau)

i est un entier
// On parcours les éléments de l'arbre pour trouver celui qui correspond au noeud passé en paramètre
POUR i = 1 A {:m_sNomArbre,indChamp}..Occurrence
	
	SI {:m_sNomArbre,indChamp}[i] = :m_TabElementsTreeview[nIndiceTableau] ALORS
		RENVOYER i
	FIN
FIN

RENVOYER i
// Résumé : Force ou non la sélection multiple
// Syntaxe :
//SetForceSélectionMultiple ( [<bForceSélection>])
//
// Paramètres :
//	bForceSélection (valeur par défaut=1) : VRAI si la sélection multiple doit être forcée, FAUX autrement
// Valeur de retour :
// 	Aucune

PROCEDURE SetForceSélectionMultiple(bForceSélection = Vrai)

:m_bForceSélection = bForceSélection
// Résumé : Active ou non la sélection multiple
// Syntaxe :
//SetSélectionMultiple ( [<bActiveSélection>])
//
// Paramètres :
//	bActiveSélection (valeur par défaut=1) : VRAI si la sélection multiple doit être activée, FAUX autrement
// Valeur de retour :
// 	Aucune

PROCEDURE SetSélectionMultiple(bActiveSélection = Vrai)

sNoeud 	est une chaîne	// Noeud sur lequel le dernier clic a eu lieu

// Si la multisélection était activé, et qu'elle ne doit plus l'être
SI :m_bMultiSélectionAutorisée = Vrai ET bActiveSélection = Faux ALORS
	
	// Conserve le noeud (son chemin) sur lequel le dernier clic a eu lieu
	SI 1 <= :m_nDernierIndiceSélectionné <= Dimension(:m_TabElementsTreeview) ALORS	sNoeud = :m_TabElementsTreeview[:m_nDernierIndiceSélectionné]
	
	// Désélectionne tous les noeuds de l'arbre
	:_EnlèveSélection()
	
	// Resélectionne le dernier noeud sur lequel un clic a eu lieu
	SI snoeud <> "" ALORS :ArbreSelectPlus(snoeud)	
	
FIN

// Positionne la multisélection ou non
:m_bMultiSélectionAutorisée = bActiveSélection
// Résumé : renvoie le positionnement de la sélection multiple
// Syntaxe :
//[ <Résultat> = ] GetSelectionMultiple ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	booléen :    VRAI si la sélection multiple est activé, FAUX autrement

PROCEDURE GetSelectionMultiple()

RENVOYER :m_bMultiSélectionAutorisée
// Résumé : Ajoute un noeud à l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreAjoute (<sNoeud> [, <bTrie> [, <sImageEnroulée> [, <sImageDéroulée> [, <nIdentifiant> [, <nModeAjoute> [, <sTexteBulle>]]]]]])
//
// Paramètres :
//	sNoeud : 								Noeud à ajouter à l'arbre ("Noeud"+tab+"SousNoeud"+tab+"Feuille")
//	bTrie (valeur par défaut=1) : 			VRAI si l'arbre doit être trié à la suite de l'ajout, FAUX autrement
//	sImageEnroulée (valeur par défaut=7) : 	Chemin de l'image enroulée ou aDéfaut ou Null
//	sImageDéroulée (valeur par défaut=7) : 	Chemin de l'image déroulée ou aDéfaut ou Null
//	nIdentifiant (valeur par défaut=0) : 	Identifiant du noeud / de la feuille
//	nModeAjoute (valeur par défaut=0) : 	Mode d'ajout aAccepteDoublon, aPremier, aDernier, aTriAlpha
//	sTexteBulle :							Texte de la bulle
// Valeur de retour :
// 	booléen :   							VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreAjoute(sNoeud , bTrie = Vrai , sImageEnroulée = aDéfaut , sImageDéroulée = aDéfaut , nIdentifiant = 0 , nModeAjoute = aTriAlpha , sTexteBulle = "")

// Si le noeud n'existe pas
SI ArbreTypeElément(:m_sNomArbre , snoeud) = aErreur ALORS
	
	// Ajoute l'élément dans l'arbre
	SI WL.ArbreAjoute(:m_sNomArbre , snoeud , sImageEnroulée , sImageDéroulée , nIdentifiant , nModeAjoute , sTexteBulle) = Faux ALORS RENVOYER Faux
		
SINON // Si le noeud existe déjà (crée par l'ajout d'un noeud fils/d'une feuille fille)
	
	// Modifie le noeud pour prendre en compte les images, l'identifiant et la bulle
	SI ArbreModifie(:m_sNomArbre , snoeud , Null , sImageEnroulée , sImageDéroulée , nIdentifiant , sTexteBulle) = Faux ALORS RENVOYER Faux
	
FIN

// Ajout de l'élément dans le tableau
TableauAjoute(:m_TabElementsTreeview , snoeud)

// Doit-on le trier ?
SI btrie ALORS
	// Trie l'arbre
	:ArbreTrie()
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Sélectionne toutes les lignes
// Syntaxe :
//ArbreSelectTout ( [<bSelection>])
//
// Paramètres :
//	bSelection (valeur par défaut=1) : VRAI si on doit tout sélectionner, FAUX si on doit tout désélectionner
// Valeur de retour :
// 	Aucune

PROCEDURE ArbreSelectTout(bSelection = Vrai)

i 						est un entier
nIndiceTableauSélection est un entier

// Si tous les éléments doivent être sélectionnés
SI bSelection ALORS
	
	// Contrôle que la multisélection est bien autorisée
	SI :m_bMultiSélectionAutorisée = Faux ALORS RETOUR
	
	// Vide la tableau
	TableauSupprimeTout(:m_TabElementsSélectionnés)
	// Positionne à 0 le nombre d'éléments sélectionnés
	:m_nNombreElémentsSélectionnés = 0	
	
	// Pour tous les éléments du tableau 
	POUR i = 1 A Dimension(:m_TabElementsTreeview)
		
		// Recherche de l'élément en cours dans le tableau des éléments sélectionnés
		// S'il est déjà sélectionné, on ne fait rien,  sinon, on le sélectionne
		nIndiceTableauSélection = TableauCherche(:m_TabElementsSélectionnés , tcLinéaire , i)
		SI nIndiceTableauSélection > 0 _ET_ i <> :m_nDernierIndiceSélectionné ALORS
			// On l'a trouvé ,on ne fait rien
		SINON
			
			// Positionne la couleur de fond et de police du noeud comme étant sélectionné
			{:m_sNomArbre,indChamp}[i]..CouleurFond = :m_nCouleurSélection
			{:m_sNomArbre,indChamp}[i]..Couleur 	= :m_nCouleurPolice
			
			// Sauvegarde de l'élément sélectionné
			TableauAjoute(:m_TabElementsSélectionnés , i)
			:m_nNombreElémentsSélectionnés++
			
		FIN	
		
	FIN	
	
SINON // Si tous les éléments doivent être désélectionnés
	:_EnlèveSélection()	
FIN
// Résumé : Supprime tout noeud/toute feuille de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreSupprimeTout ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	booléen :    VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreSupprimeTout()

// Vide le champ arbre
SI WL.ArbreSupprimeTout(:m_sNomArbre) = Faux ALORS RENVOYER Faux

// Vide les tableaux
TableauSupprimeTout(:m_TabElementsTreeview)		// Tableau des éléments de l'arbre
TableauSupprimeTout(:m_TabElementsSélectionnés)	// Tableau des indices des éléments sélectionnés

// Réinitialisation
:m_nNombreElémentsSélectionnés = 0

// traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Trie l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreTrie ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	booléen :   		VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreTrie()

tabElementSelectionne 	est un tableau de 0 chaîne // chaine contenant les chemins des noeuds sélectionnées
nIndice 				est un entier
sNoeud 					est une chaîne

// Pour chaque indice présent dans le tableau des éléments sélectionnés
POUR TOUT ELEMENT nindice DE :m_TabElementsSélectionnés
	// Ajoute le chemin du noeud sélectionné dans le tableau
	TableauAjoute(tabElementSelectionne , :m_TabElementsTreeview[nIndice])		
FIN

// Trie l'arbre
SI WL.ArbreTrie(:m_sNomArbre) = Faux ALORS RENVOYER Faux

// Trie le tableau des éléments
//	le tableau des éléments sélectionnées ne sera plus valide, puisque les indices ont changés
TableauTrie(:m_TabElementsTreeview,ttCroissant)

// Vide le tableau des indices des noeuds sélectionnés
TableauSupprimeTout(:m_TabElementsSélectionnés)

// Re parcours le tableau nouvellement trié pour récupérer les indices des éléments sélectionnés
POUR TOUT ELEMENT snoeud DE tabElementSelectionne
	// Récupère l'indice de ce noeud dans le tableau des éléments de l'arbre
	nindice = TableauCherche(:m_TabElementsTreeview , tcDichotomique , snoeud)
	SI nindice <> -1 ALORS
		// Ajoute l'indice de ce noeud dans le tableau des indices d'éléments sélectionnés
		TableauAjoute(:m_TabElementsSélectionnés , nIndice)		
	FIN
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Supprime un noeud et ses fils
// Syntaxe :
//[ <Résultat> = ] ArbreSupprime (<sNoeud>)
//
// Paramètres :
//	sNoeud : 			chemin du noeud à supprimer
// Valeur de retour :
// 	booléen :   		VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreSupprime(sNoeud)

// Supprime le noeud du champ arbre
SI WL.ArbreSupprime(:m_sNomArbre , snoeud) = Faux ALORS RENVOYER Faux

// Il faut supprimer tous les noeuds correspondants dans le tableau
j,i est un entier = 1
// Parcours le tableau des éléments de l'arbre
TANTQUE i <= Dimension(:m_TabElementsTreeview)
	
	//Si l'arborescence du noeud est présente dans l'élément, il s'agit :
	// du noeud lui même	("Noeud1"+tab+"Noeud2")
	// d'un des fils du noeud ("Noeud1"+tab+"Noeud2"+tab+"Feuille1")
	SI Position(:m_TabElementsTreeview[i] , snoeud) <> 0 ALORS
		
		// Si l'élément était sélectionné (son indice est présent dans le tableau des éléments sélectionnés)
		nIndiceSelect est un entier =  TableauCherche(:m_TabElementsSélectionnés,tcLinéaire,i) 
		SI nindiceselect <> -1 ALORS
			// Supprime l'indice du tableau
			TableauSupprime(:m_TabElementsSélectionnés,nindiceselect)
			// Décrémente le nombre de noeuds sélectionnés
			:m_nNombreElémentsSélectionnés--
			
		FIN
						
		// Supprime cet élément
		TableauSupprime(:m_TabElementsTreeview , i)
		
		// Dans le tableau des éléments sélectionnés, les indices supérieurs à l'indice i en cours ne sont plus corrects (du fait de la suppression),il faut les décrémenter
		// Pour chaque indice d'un élément sélectionné
		POUR j=1 A Dimension(:m_TabElementsSélectionnés)
			// Si cet indice est supérieur à l'indice de l'élément en cours
			SI :m_TabElementsSélectionnés[j] > i ALORS
				// Décrémente l'indice
				:m_TabElementsSélectionnés[j]--
			FIN
			
		FIN
					
	SINON // Si ce noeud n'est pas trouvé
		// Avance dans le tableau
		i++		
	FIN
			
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Insère un noeud dans l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreInsère (<sNoeudFrere>, <sFeuille> [, <sImageEnroulée> [, <sImageDéroulée> [, <nIdentifiant> [, <nModeAjoute> [, <sTexteBulle>]]]]])
//
// Paramètres :
//	sNoeudFrere : 							Noeud frère de l'arbre ("Noeud"+tab+"SousNoeud"+tab+"Feuille")
//	sFeuille : 								Feuille à insérée ("Feuille2")
//	sImageEnroulée (valeur par défaut=7) : 	Chemin de l'image enroulée ou aDéfaut ou Null
//	sImageDéroulée (valeur par défaut=7) : 	Chemin de l'image déroulée ou aDéfaut ou Null
//	nIdentifiant (valeur par défaut=0) : 	Identifiant du noeud / de la feuille
//	nModeAjoute (valeur par défaut=6) : 	Mode d'ajout aApres ou aAvant
//	sTexteBulle :							Texte de la bulle
// Valeur de retour :
// 	booléen :   							VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreInsère(sNoeudFrere , sFeuille , sImageEnroulée = aDéfaut , sImageDéroulée = aDéfaut , nIdentifiant = 0 , nModeAjoute = aAprès , sTexteBulle = "")

sCheminFeuille 	est une chaîne	// Chemin complet de la nouvelle feuille
nIndice 		est un entier 

// Ajoute l'élément dans l'arbre
SI WL.ArbreInsère(:m_sNomArbre , snoeudfrere , sFeuille , sImageEnroulée , sImageDéroulée , nIdentifiant , nModeAjoute , sTexteBulle) = Faux ALORS RENVOYER Faux

// Insère le noeud dans le tableau
// Il faut retrouver la position du noeud frère référence
nIndiceFrere est un entier = TableauCherche(:m_TabElementsTreeview , tcLinéaire , sNoeudFrere)
SI nIndiceFrere <> -1 ALORS
	
	// Il faut construire l'arborescence de la feuille à ajouter pour le tableau
	nIndice			= Position(snoeudfrere,TAB,0,DepuisFin)
	sCheminFeuille 	= snoeudfrere[[ 1 A nindice]] +sfeuille
		
	// Selon le mode d'ajout
	SELON nModeAjoute
		// Après le noeud frère
		CAS aAprès
			TableauInsère(:m_TabElementsTreeview , nIndiceFrere+1 , sCheminFeuille)		
		
		// Avant le noeud frère
		CAS aAvant
			TableauInsère(:m_TabElementsTreeview , nIndiceFrere , sCheminFeuille)
			
	FIN	

FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Modifie un noeud de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreModifie (<sBranche> [, <sNouveauLibelle> [, <sImageEnroulée> [, <sImageDéroulée> [, <nIdentifiant> [, <sTexteBulle>]]]]])
//
// Paramètres :
//	sBranche : 			Noeud à modifier à l'arbre ("Noeud"+tab+"SousNoeud"+tab+"Feuille")
//	sNouveauLibelle : 	Nouveau libellé de ce noeud
//	sImageEnroulée : 	Chemin de l'image enroulée ou aDéfaut ou Null
//	sImageDéroulée : 	Chemin de l'image déroulée ou aDéfaut ou Null
//	nIdentifiant : 		Identifiant du noeud / de la feuille
//	sTexteBulle :		Texte de la bulle
// Valeur de retour :
// 	booléen :   		VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreModifie(sBranche, sNouveauLibelle = Null , sImageEnroulée = Null , sImageDéroulée = Null , nIdentifiant = Null , sTexteBulle = "")

sNouveauChemin est une chaîne

// Modifie l'élément dans l'arbre
SI WL.ArbreModifie(:m_sNomArbre , sBranche , sNouveauLibelle , sImageEnroulée , sImageDéroulée , nIdentifiant , sTexteBulle) = Faux ALORS RENVOYER Faux

// Modifie le noeud dans le tableau
// Il faut retrouver la position
nIndiceElement est un entier = TableauCherche(:m_TabElementsTreeview , tcLinéaire , sBranche)
SI nIndiceElement <> -1 ALORS
	// Si un nouveau libellé est spécifié
	SI sNouveauLibelle <> Null ALORS
		// Il faut construire l'arborescence de la feuille à ajouter pour le tableau
		nIndice est un entier 	= Position(sBranche,TAB,0,DepuisFin)
		sNouveauChemin 			= sBranche[[ 1 A nindice]] +sNouveauLibelle	
		// Change le chemin du noeud de l'élément		
		:m_TabElementsTreeview[nindiceelement] = sNouveauChemin
	FIN	

FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : supprime les fils de l'élément (sans supprimer l'élément lui-même)
// Syntaxe :
//[ <Résultat> = ] ArbreSupprimeFils (<sNoeud>)
//
// Paramètres :
//	sNoeud : 			chemin du noeud pour lequel on souhaite supprimer les fils
// Valeur de retour :
// 	booléen :    		VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreSupprimeFils(sNoeud)

sCheminElement 	est une chaîne
j,i 			sont des entiers

// Supprime les fils de l'élément dans l'arbre
SI WL.ArbreSupprimeFils(:m_sNomArbre , snoeud) = Faux ALORS RENVOYER Faux

i=1
// Parcours le tableau des éléments de l'arbre
TANTQUE i <= Dimension(:m_TabElementsTreeview)
	
	//Si l'arborescence du noeud est présente dans l'élément, il s'agit :
	// du noeud lui même		("Noeud1"+tab+"Noeud2") => teste apres le _et_ pour éviter de le supprimer (ne supprime que les fils)
	// d'un des fils du noeud 	("Noeud1"+tab+"Noeud2"+tab+"Feuille1")
	SI Position(:m_TabElementsTreeview[i] , snoeud) <> 0 _ET_ :m_TabElementsTreeview[i] <> snoeud ALORS
		
		// Si l'élément était sélectionné (son indice est présent dans le tableau des éléments sélectionnés)
		nIndiceSelect est un entier =  TableauCherche(:m_TabElementsSélectionnés,tcLinéaire,i) 
		SI nindiceselect <> -1 ALORS
			// Supprime l'indice du tableau des indices
			TableauSupprime(:m_TabElementsSélectionnés,nindiceselect)
			// Décrémente le nombre de noeuds sélectionnés
			:m_nNombreElémentsSélectionnés--
			
		FIN
		
		// Supprime cet élément
		TableauSupprime(:m_TabElementsTreeview , i)
		
		// Dans le tableau des éléments sélectionnés, les indices supérieurs à l'indice i en cours ne sont plus corrects (du fait de la suppression),il faut les décrémenter
		// Pour chaque indice d'un élément sélectionné
		POUR j=1 A Dimension(:m_TabElementsSélectionnés)
			// Si cet indice est supérieur à l'indice de l'élément en cours
			SI :m_TabElementsSélectionnés[j] > i ALORS
				// Décrémente l'indice
				:m_TabElementsSélectionnés[j]--
			FIN
			
		FIN
		
	SINON // Si ce noeud n'est pas trouvé
		// Avance dans le tableau
		i++		
	FIN
	
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Déplace un élément (feuille ou noeud) dans un champ Arbre (toutes les branches issues de cet élément sont également déplacées)
// Syntaxe :
//[ <Résultat> = ] ArbreDeplaceElément (<sElementSource>, <sElementDestination>)
//
// Paramètres :
//	sElementSource : 		élément à déplacer
//	sElementDestination : 	noeud où déplacer cet élément
// Valeur de retour :
// 	booléen :   			VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreDeplaceElément(sElementSource , sElementDestination)

bRetour			est un booléen
nPosition 		est un entier	
sElement 		est une chaîne	// élément parcouru
sNouveauChemin 	est une chaîne	// nouveau chemin pour l'élément source et ses fils

// Déplace le noeud dans l'arbre
SI WL.ArbreDéplaceElément( :m_sNomArbre , sElementSource , sElementDestination) = Faux ALORS RENVOYER Faux

// Positionne le nouveau chemin de l'élément que l'on déplace
nPosition 		= Position(sElementSource,TAB,0,DepuisFin)
sNouveauChemin 	= sElementDestination+TAB+selementsource[[nposition+1 A Taille(selementsource)]]

// Pour chaque élément 
POUR TOUT ELEMENT sElement DE :m_TabElementsTreeview
	// Si le chemin du noeud à déplacer est trouvé dans le chemin de cet élément, il s'agit d'un fils ou de l'élément lui-même
	SI Position(sElement , selementsource) <> 0 ALORS
		// Remplace l'ancien chemin de l'élément par le nouveau chemin
		selement = Remplace(selement , selementsource , snouveauchemin)	
	FIN	
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Copie un élément (feuille ou noeud) dans un champ Arbre (toutes les branches issues de cet élément sont également copiées)
// Syntaxe :
//[ <Résultat> = ] ArbreCopieElément (<sElementSource>, <sElementDestination>)
//
// Paramètres :
//	sElementSource : 		élément à copier
//	sElementDestination : 	noeud où copier cet élément
// Valeur de retour :
// 	booléen :     			VRAI si le traitement a réussi, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreCopieElément(sElementSource , sElementDestination)

nPosition 		est un entier	
sElement 		est une chaîne	// élément parcouru
sNouveauChemin 	est une chaîne	// nouveau chemin pour l'élément source et ses fils
sNouvelElement	est une chaîne	// nouvel élément (copie d'un ancien élément)
tabElement		est un tableau de 0 chaînes

// on ne copie pas un noeud dans un noeud fils
SI Position(sElementDestination , sElementSource) <> 0 ALORS 
	
FIN

// Déplace le noeud dans l'arbre
SI WL.ArbreCopieElément( :m_sNomArbre , sElementSource , sElementDestination) = Faux ALORS RENVOYER Faux

// Positionne le nouveau chemin de l'élément que l'on copie
nPosition 		= Position(sElementSource,TAB,0,DepuisFin)
// le nouveau chemin correspond au chemin de destination + le dernier noeud spécifié dans le chemin de l'élément source
sNouveauChemin 	= sElementDestination + TAB + selementsource[[nposition+1 A Taille(selementsource)]]

// Pour chaque élément noeud de l'arbre
POUR TOUT ELEMENT sElement DE :m_TabElementsTreeview
	
	// Si le chemin du noeud à copier est trouvé dans le chemin de cet élément, il s'agit d'un fils ou de l'élément lui-même
	SI Position(sElement , selementsource) <> 0 ALORS
		// Création du nouvel élément
		sNouvelElement = Remplace(selement , selementsource , snouveauchemin)	
		// Ajoute le nouvel élément dans le tableau
		TableauAjoute(tabElement , snouvelelement)
		
	FIN	
	
FIN

// Pour chaque nouvel élément
POUR TOUT ELEMENT selement DE tabelement
	
	// Ajout de l'élément dans l'arbre
	:ArbreAjoute(selement , Vrai)
	
FIN

// Traitement effectué, renvoie VRAI
RENVOYER Vrai
// Résumé : Déroule un noeud de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreDéroule (<sNoeud>)
//
// Paramètres :
//	sNoeud :		noeud à dérouler
// Valeur de retour :
// 	booléen :    	VRAI si traitement effectué, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreDéroule(sNoeud)

RENVOYER WL.ArbreDéroule(:m_sNomArbre , snoeud)
// Résumé : Déroule tout l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreDérouleTout ( [<sNoeud>])
//
// Paramètres :
//	sNoeud : noeud à partir duquel tout dérouler
// Valeur de retour :
// 	booléen :  // 	Aucune
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreDérouleTout(sNoeud="")

// Si un noeud est précisé
SI snoeud <> "" ALORS
	RENVOYER WL.ArbreDérouleTout(:m_sNomArbre, snoeud)
SINON
	RENVOYER WL.ArbreDérouleTout(:m_sNomArbre)	
FIN

// Résumé : Enroule un noeud de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreEnroule (<sNoeud>)
//
// Paramètres :
//	sNoeud : noeud à enrouler
// Valeur de retour :
// 	booléen :   VRAI si traitement effectué, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX

PROCEDURE ArbreEnroule(sNoeud)

RENVOYER WL.ArbreEnroule(:m_sNomArbre , snoeud)
// Résumé : Enroule l'ensemble des noeuds de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreEnrouleTout ( [<sNoeud>])
//
// Paramètres :
//	sNoeud : 		noeud à partir duquel tout enroulé
// Valeur de retour :
// 	booléen :    	VRAI si traitement effectué, FAUX autrement
// Traitement automatique des erreurs : RENVOYER FAUX
//

PROCEDURE ArbreEnrouleTout(sNoeud="")

SI snoeud <> "" ALORS
	RENVOYER WL.ArbreEnrouleTout(:m_sNomArbre , snoeud)
SINON
	RENVOYER WL.ArbreEnrouleTout(:m_sNomArbre)	
FIN

// Résumé : renvoie l'état d'un noeud de l'arbre
// Syntaxe :
//[ <Résultat> = ] ArbreEtat (<sNoeud>)
//
// Paramètres :
//	sNoeud : 	noeud dont on souhaite connaitre l'état
// Valeur de retour :
// 	entier :  	etat du noeud : aEnroule, aDeroule, aErreur

PROCEDURE ArbreEtat(sNoeud)

RENVOYER WL.ArbreEtat(:m_sNomArbre , snoeud)
// Résumé : renvoie le type d'un élément passé en paramètre
// Syntaxe :
//[ <Résultat> = ] ArbreTypeElément (<sNoeud>)
//
// Paramètres :
//	sNoeud : 	noeud dont on souhaite connaitre le type
// Valeur de retour :
// 	entier : 	type de l'élément : aErreur, aFeuille, aNoeud

PROCEDURE ArbreTypeElément(sNoeud)

RENVOYER WL.ArbreTypeElément(:m_sNomArbre , snoeud)
// Résumé : récupère l'identifiant du noeud d'un arbre
// Syntaxe :
//[ <Résultat> = ] ArbreRécupèreIdentifiant (<sNoeud>)
//
// Paramètres :
//	sNoeud : 	noeud dont on souhaite récupérer l'identifiant
// Valeur de retour :
// 	chaîne :	identifiant du noeud
// Traitement automatique des erreurs : RENVOYER ""


PROCEDURE ArbreRécupèreIdentifiant(sNoeud)

RENVOYER WL.ArbreRécupèreIdentifiant(:m_sNomArbre , sNoeud)
// Résumé : récupère les fils d'un noeud
// Syntaxe :
//[ <Résultat> = ] ArbreRécupèreFils (<sNoeud>, <nFils>)
//
// Paramètres :
//	sNoeud : 			noeud dont on souhaite récupérer les fils
//	nFils : 			indique le fils voulu : aPremier ou aSuivant
// Valeur de retour :
// 	Type indéterminé :  nom du fils trouvé ou chaine vide ""
// Traitement automatique des erreurs : RENVOYER ""

PROCEDURE ArbreRécupèreFils(sNoeud , nFils)

RENVOYER WL.ArbreRécupèreFils(:m_sNomArbre , snoeud , nfils)
// Résumé : Affiche un champ Arbre àpartir d'un élément (noeud ou feuille) spécifié 
// Syntaxe :
//[ <Résultat> = ] ArbrePosition ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	chaîne :  Chemin complet du premier élément affiché dans le champ

PROCEDURE ArbrePosition()

RENVOYER WL.ArbrePosition(:m_sNomArbre)
// Résumé  :Renvoie le nombre d'éléments présents dans l'arbre ou dans une branche.
// Syntaxe :
//[ <Résultat> = ] ArbreOccurence ( [<sNoeud> [, <nNiveau>]])
//
// Paramètres :
//	sNoeud : 						Chemin complet du noeud à partir duquel le calcul doit être réalisé
//	nNiveau (valeur par défaut=0) : Niveau des éléments à prendre en compte dans le calcul : aTout ou aUnNiveau
// Valeur de retour :
// 	Type indéterminé :     			Nombre d'occurence 
// Traitement automatique des erreurs : RENVOYER -1
//

PROCEDURE ArbreOccurence(sNoeud =Null, nNiveau=aTout)

RENVOYER WL.ArbreOccurrence(:m_sNomArbre , sNoeud , nNiveau)
// Résumé : Liste les "fils" d'un noeud et les éléments "fils" de ces "fils
// Syntaxe :
//[ <Résultat> = ] ArbreListeFils (<sNoeud>, <sNomProcedure> [, <nParametre>])
//
// Paramètres :
//	sNoeud : 							noeud sur lequel on souhaite lister les fils
//	sNomProcedure : 					nom de la procédure appelée pour chaque fils
//	nParametre (valeur par défaut=0) : 	paramètre optionnel
// Valeur de retour :
// 	Type indéterminé : 					Nombre d'éléments listés

PROCEDURE ArbreListeFils(sNoeud , sNomProcedure, nParametre=0 )

RENVOYER WL.ArbreListeFils(:m_sNomArbre , snoeud , snomprocedure , nParametre)
// Résumé : Renvoie l'élément d'un arbre se trouvant à une position donnée. 
// Syntaxe :
//[ <Résultat> = ] ArbreInfoXY (<TypeInformation>, <nPosX>, <nPosY>)
//
// Paramètres :
//	TypeInformation : 	type d'information souhaité (cf l'aide en ligne de ArbreInfoXY du W-langage)
//	nPosX : 			coordonnée X à analyser
//	nPosY : 			coordonnée Y à analyser
// Valeur de retour :
// 	variant :  			information demandée		(cf l'aide en ligne de ArbreInfoXY du W-langage)

PROCEDURE ArbreInfoXY(TypeInformation , nPosX, nPosY)

RENVOYER WL.ArbreInfoXY(:m_sNomArbre , TypeInformation , nPosX , nPosY)
// Résumé : Renvoie la dernière erreur s'il en existe une
// Syntaxe :
//[ <Résultat> = ] GetErreur ()
//
// Paramètres :
//	Aucun
// Valeur de retour :
// 	chaîne : 	texte de l'erreur

PROCEDURE GetErreur()

RENVOYER :m_sErreurInfo
// Résumé : permet de construire le chemin des éléments en différenciant les doublons
// Syntaxe :
//[ <Résultat> = ] ArbreId (<sIdentifiant>)
//
// Paramètres :
//	sIdentifiant : 	identifiant de l'élément
// Valeur de retour :
// 	chaîne : 		chaîne de controle

PROCEDURE ArbreId(sIdentifiant)

RENVOYER WL.ArbreID(sidentifiant)