mardi 6 mai 2014

Personnaliser le groupware utilisateur


Bonjours, Ms et Mrs les windeveurs.
Aujourd'hui je vais vous parler d'un outils incontournable dans windev, le Groupware  Utilisateur alors nous allons commencer par savoir ce qu'est ce Groupware et ce qu'il fait

Groupware Utilisateur??

C'est le module de windev qui s'occupe de la gestion des utilisateurs et de leurs droits dans le logiciel.
Son fonctionnement est simple. Il énumère tous les champs et fenêtres et vous donne une interface bien aboutis pour gérer les droit d’accès des utilisateur ou des groupes.
Les informations sont par la suite enregistrée dans des tables de base de données crypté. Le reste, il le fait tout seul.

au premier lancement, le système crée automatiquement un utilisateur avec les droit de super administrateur (Superviseur) avec login et mot de passe par défaut (superviseur/superviseur)
C'est à partir de lui que vous commencer à créer des utilisateurs, des groupes et de gérer leurs droits.

Par exemple

Vous creez un utilisateur "X", et vous indiquez que "X" ne doit pas voire le bouton "BTN_b" dans la fenêtre "Fen_F". lorsque Mr "X" ouvre le logiciel avec son login et mot de passe, il ne trouve pas le bouton "BTN_b" dans la fentre "FEN_F"

Comment intégrer le groupware utilisateur??

C'est trés simple. Même plus simple que tous ce que vous imaginez. Allez dans le menu "Atelier->Paramétrer le Groupware utilisateur", Une interface apprêt avec 3 onglets(générale, fichier,LDAP).
Dans l'onglet "générale" vous cochez "Activez la gestion du groupware utilisateur" pour l'activer et puis vous choisissez intégration par défaut ou personnalisable.

Je vous conseille l'intégration personnalisable, celle ci vous ajoute les interfaces du groupware afin de les modifier et c'est d’ailleurs la partie la plus intéressante.
Et après y'a démarrage automatique ou manuel.
le démarrage automatique lance le groupware sans aucun appel au lancement de l'application mais avec le démarrage manuelle, vous choisissez le moment du lancement avec l'appel de la fonction "gpwlogin".

Je vous laisse avec les 2 autres onglets faire ce qui vous semble le mieux et maintenat nous allons passer à la personnalisation du groupware.

les interfaces du groupware

Comment je vous l'ai déjà dis, l'integration personnalisé vous ajoute les interfaces du groupeware et nous allons les voir rapidement:

GPWLogin

c'est la première interface, et celle qui est ouverte lors du lancement du groupware

Vous pouvez dés à présent modifier son apparence et même son comportement si vous le souhaitez. Il suffit de parcourir les élément de l'interface et son code afin de comprendre son fonctionnement. Nous verrons plus de détails par la suite mais pour la personnalisation de l'affichage c'est simple. Vous pouvez obtenir un résultat semblable à celui si sans effort.



GPWMenuSuperviseur

Cette interface appert lorsque l'utilisateur ce connecte avec un compte Superviseur.
Rien de compliqué, y a pas grand chose à modifier dans cette interface, juste les textes et l'apparence.
Inutile de vous expliquez à quoi sert chaque bouton mais je doit notifier que le bouton "Configurer le groupware" ouvre la partie de la gestion des utilisateurs et donc l'interface suivante est "GPWAssociationConfiguration"

GPWAssociationConfiguration

Cette interface est très importante. c'est celle à partir de laquelle on peut choisir le groupe de chaque utilisateur et définir ses paramètres.
on peut y appliquer quelques modification au niveau du comportement. afin d’empêcher un utilisateur de se supprimer lui même ou alors de s'enlever les mode superviseur.
nous y reviendrons plus tard pour ça.

GPWDetailsConfiguration



Alors la c'est la cerise sur le gâteaux. Cette interface est la plus importante dans le groupware. c'est d'ailleurs celle qui définie les droit de chaque utilisateur ou groupe (Configuration).
Son utilisation est un peut difficile pour les client (utilisateurs finaux de l'application) à cause de l’énumération des champs et des fenêtres qui sont affichés selon leurs noms physiques. Alors si vous utilisez une nomination qui n'est pas très claires, vos clients ferons appel à vous à chaque fois qu'ils ont besoin de changer les droit d'un utilisateur. Nous allons nous occupez plus tard de la rendre plus simple et plus compréhensible à utiliser.

GPWChoixConfiguration


Y a pas grand choses à dire sur cette interface. Modifiez simplement son apparence.

GPWFicheConfiguration


Encore la y a pas grand chose à dire. cette interface s'occupe de l'ajout et la modification d'un groupe.

GPWFicheUtilisateur


Cette interface à de l'importance. c'est celle ou on ajoute et on modifie les paramètres généraux d'un utilisateur.


La structure de la base de données du groupware

la base de donnée est constitué de 5 tables.

GPWConfiguration


Caractéristiques des rubriques :
Nom ExplicationTypeTailleClé
ConfigurationNom du groupe d'utilisateurs ou de l'utilisateurChaîne de caractères255 caractèresUnique
ApplicationNom de l'applicationChaîne de caractères255 caractèresAvec doublons
GroupeDéfinit si la configuration correspond à un groupe d'utilisateurs ou à un utilisateurBooléen
Groupe_ConfigurationClé composée des rubriques Groupe et ConfigurationClé composéeUnique
Application_ConfigurationClé composée des rubriques Application et ConfigurationClé composéeAvec doublons

GPWConfigurationElément


Caractéristiques des rubriques :
NomExplicationTypeTailleClé
ConfigurationNom du groupe d'utilisateurs ou de l'utilisateurChaîne de caractères255 caractèresAvec doublons
EtatEtat de l'élément (grisé, inactif, ...)SélecteurEntier non signé sur 1 octetAvec doublons
ElementNom de l'élémentChaîne de caractères255 caractèresAvec doublons
Configuration_ElementClé composée des rubriques Configuration et ElementClé composéeUnique

GPWElément


Caractéristiques des rubriques :

Nom

Explication

Type

Taille

Clé
ElementNom de l'élémentChaîne de caractères255 caractèresUnique
TypeType de l'élément (champ de saisie, table, ...)NumériqueEntier sur 4 octetsAvec doublons

GPWHistoriqueConnexion


Caractéristiques des rubriques
NomExplicationTypeTailleClé
IDLogConnexionIdentifiantIdentifiantUnique
ApplicationNom de l'applicationChaîne de caractères255 caractèresAvec doublons
LoginLogin de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'applicationChaîne de caractères255 caractèresAvec doublons
DateConnexionDate de la connexion à l'applicationDate8 caractèresAvec doublons
HeureConnexionHeure de la connexion à l'applicationHeure4 caractèresAvec doublons
AdresseIPAdresse IP du posteChaîne de caractères39 caractèresAvec doublons

GPWUtilisateur


Caractéristiques des rubriques :

Nom

Explication

Type

Taille

Clé
LoginLogin de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'applicationChaîne de caractères255 caractèresUnique
NomNom de l'utilisateurChaîne de caractères255 caractères
PrenomPrénom de l'utilisateurChaîne de caractères255 caractères
MotPasseMot de passe de l'utilisateurChaîne de caractères255 caractères
SuperviseurDéfinit si l'utilisateur est un superviseurBooléen
MotPasseASaisirDéfinit si l'utilisateur peut modifier son mot de passe lors de sa première connexionBooléen

GPWUtilisateurConfiguration


Caractéristiques des rubriques :
NomExplicationTypeTailleClé
ConfigurationNom du groupe d'utilisateurs ou de l'utilisateurChaîne de caractères255 caractèresAvec doublons
LoginLogin de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'applicationChaîne de caractères255 caractèresAvec doublons
Login_ConfigurationClé composée des rubriques Login et ConfigurationClé composéeAvec doublons
ApplicationNom de l'applicationChaîne de caractères255 caractèresAvec doublons
Login_ApplicationClé composée des rubriques Login et ApplicationClé composéeUnique
Application_ConfigurationClé composée des rubriques Application et ConfigurationClé composéeAvec doublons

Corriger une faille dans le groupware utilisateur

Une faille?
Oui une faille. Il y en a pas mal de failles mais celle ci est particulière.
lors de la première utilisation du groupeware les fichier des données sont vides. donc le système ajoute automatiquement les données de bases comme l'utilisateur "Superviseur" avec le mot de passe "Superviseur".
Et comme les fichiers existe en dur sur le disque dur du serveur, il suffit de les supprimer pour que tout soit réinitialisé.

Pour y remédié rien de plus simple.
Allez Maintenant sur l'interface "GPWLogin"=>code d'initialisation.
Après la dernière ligne nous allons ajouter une petite partie de code:
HLitRecherche(GPWUtilisateur,Login,"Superviseur")
SI HTrouve(GPWUtilisateur) Alors
   SI GPWUtilisateur.MotPasse="Superviseur"
      GPWUtilisateur.MotPasse=" Votre Mot de passe ici"
   FIN
FIN
Voila c'est pas compliqué. Et maintenant nous allons mettre quelques mesure de sécurités supplémentaires.

Se supprimer

Un utilisateur superviseur (Admin) peut supprimer son propre compte, ce qui peut poser problème dans certains cas ou alors révoquer les droits admin pour tout les utilisateurs ce qui peut poser plus de problèmes.
La solution est très simple.
Allez dans l'interface "GPWAssociationConfiguration"=>bouton supprimer=>code=>clic et vous trouverez ce code la:

SI OuiNon("Voulez-vous vraiment supprimer l'utilisateur '"+Login+"' ?") ALORS
 // recherche du login dans le fichier de relation entre les login et les applications
 HLitRecherchePremier(GPWUtilisateurConfiguration,"Login",Login)
 TANTQUE HTrouve(GPWUtilisateurConfiguration)
  SI PAS HSupprime(GPWUtilisateurConfiguration) ALORS
   Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo())
  FIN
  HLitSuivant(GPWUtilisateurConfiguration,"Login")
 FIN

 // recherche de l'utilisateur
 HLitRecherchePremier(GPWUtilisateur,"Login",Login)
 SI HTrouve(GPWUtilisateur) ALORS
  SI PAS HSupprime("GPWUtilisateur") ALORS
   Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo())
  FIN
 FIN

 // rafraichissement de la table
 AfficheTable()
FIN
Nous allons faire une petite modification au début pour empêcher un utilisateur de se supprimer
SI Login=gpwRecupInfoUtilisateur(gpwInfoLogin)
 Erreur("Impossible de supprimer l'utilisateur")
SINON SI OuiNon("Voulez-vous vraiment supprimer l'utilisateur '"+Login+"' ?") ALORS
 // recherche du login dans le fichier de relation entre les login et les applications
 HLitRecherchePremier(GPWUtilisateurConfiguration,"Login",Login)
 TANTQUE HTrouve(GPWUtilisateurConfiguration)
  SI PAS HSupprime(GPWUtilisateurConfiguration) ALORS
   Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo())
  FIN
  HLitSuivant(GPWUtilisateurConfiguration,"Login")
 FIN

 // recherche de l'utilisateur
 HLitRecherchePremier(GPWUtilisateur,"Login",Login)
 SI HTrouve(GPWUtilisateur) ALORS
  SI PAS HSupprime("GPWUtilisateur") ALORS
   Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo())
  FIN
 FIN

 // rafraichissement de la table
 AfficheTable()
FIN
Et maintenant nous allons nous assurer qu'il y a au moins un superviseur dans l'application et pour cela nous allons créer une requête de sélection appelé "REQ_liste_superviseur" et dont le code est:

SELECT 
 *
FROM 
 GPWUtilisateur
 WHERE Superviseur=1
Et puis nous allons à l'interface "GPWFicheUtilisateur" puis le bouton "ok"=>code de clic.
en bas nous allons modifier la partie:

// modification de l'utilisateur
SINON
 // modifie l'enregistrement dans le fichier
 SI PAS hmodifie("GPWUtilisateur") ALORS
  Erreur("Impossible de modifier l'utilisateur."+RC+HErreurInfo())
 FIN
FIN
Pour obtenir:
// modification de l'utilisateur
SINON
    bModif_ok est boolean=vrai
    // modifie l'enregistrement dans le fichier
    SI GPWUtilisateur.superviseur=faux ALORS
        HExécuteRequête(REQ_liste_superviseur,hRequêteDéfaut)
        SI HNbEnr(REQ_liste_superviseur)=1 ALORS
            Erreur("Impossible de révoquer le mode superviseur à cet utilisateur.+RC+"Cet utilisateur est le seul superviseur")
            bModif_ok=faux
        FIN
    FIN
    SI bModif_ok=vrai ALORS
        SI PAS hmodifie("GPWUtilisateur") ALORS
            Erreur("Impossible de modifier l'utilisateur."+RC+HErreurInfo())
 FIN
    FIN
FIN
J’espère que ça vous aide.

Faciliter la gestion des droits

J'ai déjà dis que l'utilisation de la gestion des droits dans la groupware n'est pas facile pour les clients à cause des noms physiques des champs et des fenêtres. Et pour facilité son utilisation, nous allons devoir modifier certaines choses et inscrire manuellement les champs que nous voulons. mais pour il faut comprendre le fonctionnement de l'interface "GPWDetailconfiguration"

Comprendre le fonctionnement de base

Cette interface est constitué de 5 parties:
  • Combo utilisateur/groupe: c'est la combo qui défini sur quelle configuration nous allons modifier les droits. Nous n'allons pas y toucher
  • Boutons (ajouter/modifier/supprimer): il agisse sur la configuration sélectionnée. Nous n'allons pas y toucher non plus
  • Combo Nom de la fenêtre: cette combo est remplie par l’énumération des fenêtres de l'application et du coup elle comprend la liste de toutes les fenêtres avec leurs noms physiques. Nous allons la remplir de façon manuelle et changer son comportement.
  • La liste Type: c'est une liste qui nous permet de choisir quel type de champs nous voulons afficher dans la liste des champs. Nous pouvons nous en débarrasser, ce serai plus simple pour l'utilisateur final qui ne fait pas la différence entre une liste et une combo ou alors sélecteur et interrupteur.
  • Le tableau des objets: c'est la liste des champs dans une fenêtre. et c'est l'endroit ou nous choisissons l’état du champs (droit). Bien évidement nous allons changer ça façon de se remplir et ça façon d'interagir.
Après avoir pris connaissance de ce que nous allons faire il va falloir voire tous ça de plus près.
Alors nous allons ouvrir le code de l'interface=>déclaration globale.
Nous y trouverons, la déclaration des tables de base de données, puis la déclaration des constantes du type de champs. Dans notre cas ils ne nous aiderons pas beaucoup mais pour ceux qui désire utiliser les types des champs ce serais intéressant.

Apres la déclaration globale, nous trouvons l'initialisation de la fenêtre. On y trouve un petit code:

// remplit la combo
InitComboConfiguration()

// sélection de la bonne configuration
SelectConfiguration()

// rafraichissement de la fenêtre
Rafraichissement()
Je pense que tout est claire, inutile de détailler la dessus mais il faut savoir que la fonction Rafraichissement() est la fonction qui remplit le tableau des objets en prenant en compte le type du champs et la fenêtre et voici son code avant modification:


// Rafraichissement de la fenêtre en fonction de la sélection de la fenêtre et de la configuration
PROCEDURE Rafraichissement()

// propose d'activer les options du menu "?"
SI Fenetre[Fenetre]="FI_MenuHWinDevHelp" ALORS
 SI ListeOccurrence(ColEtat)<>5
  ListeAjoute(ColEtat,"Actif")
 FIN
SINON SI ListeOccurrence(ColEtat)=5 ALORS
 ListeSupprime(ColEtat,5)
FIN

// vide la table
TableSupprimeTout(EtatObjet)

// filtre le fichier de configiguration des éléments
HFiltre("GPWConfigurationElement","Configuration",ComboConfiguration)

// selon la sélection dans la liste
// il faut remplir correctement
selon type
 cas eTOUS : RemplirTous(Fenetre[Fenetre])
 cas eGROUPE : Remplirparent(Fenetre[Fenetre],typGrp)
 cas eMENU : RemplirMenu(Fenetre[Fenetre])
 cas eMENUCONTEXTUEL : RemplirMenuContextuel(Fenetre[Fenetre])
 cas eBOUTON : RemplirElement(Fenetre[Fenetre],typBouton)
 cas eSAISIE : RemplirSaisie(Fenetre[Fenetre])
 cas eLIBELLE : RemplirElement(Fenetre[Fenetre],typLibellé)
 cas eLISTE : RemplirElement(Fenetre[Fenetre],typListe)
 cas eCOMBO : RemplirCombo(Fenetre[Fenetre])
 cas eSELECTEUR : RemplirElement(Fenetre[Fenetre],typSélect)
 cas eINTERRUPTEUR : RemplirElement(Fenetre[Fenetre],typInterr)
 cas eTABLE : RemplirElement(Fenetre[Fenetre],typTable)
 cas eBARREOUTILS : RemplirElement(Fenetre[Fenetre],typBarreOutils)
 cas eIMAGE : RemplirImage(Fenetre[Fenetre])
 cas eONGLET : Remplirparent(Fenetre[Fenetre],typOnglet)
 cas eVOLET : RemplirVolet(Fenetre[Fenetre])
 CAS eSUPERCHAMP : RemplirParent(Fenetre[Fenetre],typSuperChamp)
 cas eAUTRE : RemplirAutre(Fenetre[Fenetre])
 cas eBOITEOUTILS : Remplirparent(Fenetre[Fenetre],typBoîteAOutils)
FIN
Vous commencer à cerner comment fonctionne le système n'est ce pas? C'est pas bien compliquer.

Mise en place des éléments

Comme nous l'avons déjà dis, nous allons remplacer le système d’énumération automatique par un système manuel. et pour ça nous devons préparer la liste de nos éléments dans la déclaration de la fenêtre.

Ma méthode consiste à utiliser des structure de données et des tableaux comme cela:
STChamp est une structure
 xChamp_type est un numérique=0
 sNom_champ est une chaîne=""
 sLib_champ est une chaîne=""
 sNom_physique_champ est une chaîne=""
 sGroupe_champ est une chaîne=""
FIN
STFenetre est une structure
 sNom_fenetre est une chaîne=""
 sNom_physique_fenetre est une chaîne=""
 ptabListe_champ est un tableau dynamique de STChamp
FIN

gtabListe_fenetre est un tableau de 2 STFenetre
gAux_fenetre est STFenetre
gtabAux_liste_champs est un tableau dynamique de STChamp

Dimension(gtabAux_liste_champs,1)
gAux_fenetre:sNom_fenetre="Agenda"
gAux_fenetre:sNom_physique_fenetre="FEN_agenda"
gtabAux_liste_champs[1]:sLib_champ="Votre Agenda"
gtabAux_liste_champs[1]:sNom_physique_champ="AGD_Agenda"
gtabAux_liste_champs[1]:sNom_champ="Agenda"
gtabAux_liste_champs[1]:xChamp_type={"FEN_agenda.AGD_Agenda",indGPW}..Type
gtabAux_liste_champs[1]:sGroupe_champ={"FEN_agenda.AGD_Agenda",indGPW}..Groupe
gAux_fenetre:ptabListe_champ=gtabAux_liste_champs
gtabListe_fenetre[1]=gAux_fenetre

Dimension(gtabAux_liste_champs,3)
gAux_fenetre:sNom_fenetre="Saisie"
gAux_fenetre:sNom_physique_fenetre="FEN_Saisie"
gtabAux_liste_champs[1]:sLib_champ="premier champs de saisie"
gtabAux_liste_champs[1]:sNom_physique_champ="SAI_champ_saisie_1"
gtabAux_liste_champs[1]:sNom_champ="champs saisie 1"
gtabAux_liste_champs[1]:xChamp_type={"FEN_Saisie.SAI_champ_saisie_1",indGPW}..Type
gtabAux_liste_champs[1]:sGroupe_champ={"FEN_Saisie.SAI_champ_saisie_1",indGPW}..Groupe
gtabAux_liste_champs[2]:sLib_champ="deuxieme champs de saisie"
gtabAux_liste_champs[2]:sNom_physique_champ="SAI_champ_saisie_2"
gtabAux_liste_champs[2]:sNom_champ="champs saisie 2"
gtabAux_liste_champs[2]:xChamp_type={"FEN_Saisie.SAI_champ_saisie_2",indGPW}..Type
gtabAux_liste_champs[2]:sGroupe_champ={"FEN_Saisie.SAI_champ_saisie_2",indGPW}..Groupe
gtabAux_liste_champs[3]:sLib_champ="Bouton ok"
gtabAux_liste_champs[3]:sNom_physique_champ="BTN_OK"
gtabAux_liste_champs[3]:sNom_champ="OK"
gtabAux_liste_champs[3]:xChamp_type={"FEN_Saisie.BTN_OK",indGPW}..Type
gtabAux_liste_champs[3]:sGroupe_champ={"FEN_Saisie.BTN_OK",indGPW}..Groupe
gAux_fenetre:ptabListe_champ=gtabAux_liste_champs
gtabListe_fenetre[2]=gAux_fenetre

Je sais que c'est pas évident de passer en revue toutes les fenêtres et entrer tout les champs mais je vous assure que le gain généré plus tard dans la configuration et la formation chez les clients et le suivie en vaux la peine.
Mais comment allons nous utiliser cette liste??

Liste des fenêtres

Nous avons maintenons la liste des fenêtres et leurs champs. Mais nous n'allons pas les remplir une par une. Il suffit d'aller dans le code d’initialisation de la combo fenêtre, commenter le code existant (afin de pouvoir revenir en arrière en cas de besoin) et mettre ce bout de code:


ListeSupprimeTout(Fenetre)
POUR i=1 A 2
 ListeAjoute(Fenetre,gtabListe_fenetre[i]:sNom_fenetre)
FIN
Fenetre=1

Liste des champs

Dans cette partie nous allons nous intéresser à la fonction rafraichissement() puisque c'est elle qui remplit la liste des champs. Nous allons la modifier de la sorte:
// Rafraichissement de la fenêtre en fonction de la sélection de la fenêtre et de la configuration
PROCEDURE Rafraichissement()

// propose d'activer les options du menu "?"
//si Fenetre[Fenetre]="FI_MenuHWinDevHelp" alors
SI gtabListe_fenetre[Fenetre]:sNom_physique_fenetre="FI_MenuHWinDevHelp" ALORS
 SI ListeOccurrence(ColEtat)<>5
  ListeAjoute(ColEtat,"Actif")
 FIN
SINON SI ListeOccurrence(ColEtat)=5 ALORS
 ListeSupprime(ColEtat,5)
FIN

// vide la table
TableSupprimeTout(EtatObjet)

// filtre le fichier de configiguration des éléments
HFiltre("GPWConfigurationElement","Configuration",ComboConfiguration)

// selon la sélection dans la liste
// il faut remplir correctement
//selon type
// cas eTOUS : RemplirTous(Fenetre[Fenetre])
// cas eGROUPE : Remplirparent(Fenetre[Fenetre],typGrp)
// cas eMENU : RemplirMenu(Fenetre[Fenetre])
// cas eMENUCONTEXTUEL : RemplirMenuContextuel(Fenetre[Fenetre])
// cas eBOUTON : RemplirElement(Fenetre[Fenetre],typBouton)
// cas eSAISIE : RemplirSaisie(Fenetre[Fenetre])
// cas eLIBELLE : RemplirElement(Fenetre[Fenetre],typLibellé)
// cas eLISTE : RemplirElement(Fenetre[Fenetre],typListe)
// cas eCOMBO : RemplirCombo(Fenetre[Fenetre])
// cas eSELECTEUR : RemplirElement(Fenetre[Fenetre],typSélect)
// cas eINTERRUPTEUR : RemplirElement(Fenetre[Fenetre],typInterr)
// cas eTABLE : RemplirElement(Fenetre[Fenetre],typTable)
// cas eBARREOUTILS : RemplirElement(Fenetre[Fenetre],typBarreOutils)
// cas eIMAGE : RemplirImage(Fenetre[Fenetre])
// cas eONGLET : Remplirparent(Fenetre[Fenetre],typOnglet)
// cas eVOLET : RemplirVolet(Fenetre[Fenetre])
// CAS eSUPERCHAMP : RemplirParent(Fenetre[Fenetre],typSuperChamp)
// cas eAUTRE : RemplirAutre(Fenetre[Fenetre])
// cas eBOITEOUTILS : Remplirparent(Fenetre[Fenetre],typBoîteAOutils)
//FIN

POUR i=1 _A_ TableauOccurrence(gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ)
 TableAjoute(EtatObjet)
 EtatObjet[i].ColElement=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sLib_champ
 EtatObjet[i].ColGroupe=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sGroupe_champ
 EtatObjet[i].ColNom=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sNom_champ
 EtatObjet[i].ColType=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:xChamp_type
 EtatObjet[i].NomLogique=gtabListe_fenetre[ListeSelect(Fenetre)]:sNom_physique_fenetre+"."+gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sNom_physique_champ
 HLitRecherche(GPWConfigurationElement,Configuration_Element,ComboConfiguration..ValeurAffichée+","+EtatObjet[i].NomLogique,hIdentique)
 SI HTrouve(GPWConfigurationElement) ALORS
  EtatObjet[i].ColEtat=GPWConfigurationElement.etat
 SINON
  EtatObjet[i].ColEtat=1
 FIN
FIN

Et voila nous avons presque terminé tout ce qui nous reste c'est une petite modification sur l’état afin de prendre en charge le nom de la fenêtre.
C'est juste une petite ligne à modifier.
Dans la procédure mofietat():

// vérification de la dissociation d'un groupe
//c'est la ligne d'origine
//VerifDissociation(ComboConfiguration, Fenetre[Fenetre], sElement, nEtat, sListeGroupe, nType)
//c'est la nouvelle ligne
VerifDissociation(ComboConfiguration, gtabListe_fenetre[ListeSelect(Fenetre)]:sNom_physique_fenetre, sElement, nEtat, sListeGroupe, nType)
Et voila le tour est joué.
j’espère que ça vous sera utile.

N'hésitez pas à mettre des commentaire ou à me contacter en cas de besoin.
A la prochaine.

4 commentaires:

  1. wow, vraiment merci !
    Franchement c'est extrêmement utile !
    Encore merci.

    RépondreSupprimer
  2. wow, vraiment merci !
    Franchement c'est extrêmement utile !
    Encore merci.

    RépondreSupprimer
  3. Rebonjour,
    Je voulais apporter ma petite contribution à ce si bon post.
    Sur le code suivant (s'assurer qu'il y'a au moins un superviseur),
    Mettre :
    SI GPWUtilisateur.superviseur=Vrai ALORS
    HExécuteRequête(REQ_liste_superviseur,hRequêteDéfaut)

    au lieu de :
    GPWUtilisateur.superviseur=Faux

    "Vrai" au lieu de "Faux"

    RépondreSupprimer
  4. merci pour cet interet mais le but est d'empecher le superviseur de revoquer ces propres droit.
    Et de toute façon le post n'est plus valable pour les nouvelle versions de windev. :)

    RépondreSupprimer