FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  MembresMembres  Connexion  
Derniers sujets
» Logiciel de planétarium.
TreeView en Panoramic Emptypar Pedro Aujourd'hui à 10:37

» Un autre pense-bête...
TreeView en Panoramic Emptypar Froggy One Jeu 21 Nov 2024 - 15:54

» Récupération du contenu d'une page html.
TreeView en Panoramic Emptypar Pedro Sam 16 Nov 2024 - 14:04

» Décompilation
TreeView en Panoramic Emptypar JL35 Mar 12 Nov 2024 - 19:57

» Un album photos comme du temps des grands-mères
TreeView en Panoramic Emptypar jjn4 Mar 12 Nov 2024 - 17:23

» traitement d'une feuille excel
TreeView en Panoramic Emptypar jjn4 Jeu 7 Nov 2024 - 3:52

» Aide-mémoire mensuel
TreeView en Panoramic Emptypar jjn4 Lun 4 Nov 2024 - 18:56

» Des incomprèhension avec Timer
TreeView en Panoramic Emptypar Klaus Mer 30 Oct 2024 - 18:26

» KGF_dll - nouvelles versions
TreeView en Panoramic Emptypar Klaus Mar 29 Oct 2024 - 17:58

» instructions panoramic
TreeView en Panoramic Emptypar maelilou Lun 28 Oct 2024 - 19:51

» Figures fractales
TreeView en Panoramic Emptypar Marc Ven 25 Oct 2024 - 12:18

» Panoramic et Scanette
TreeView en Panoramic Emptypar Yannick Mer 25 Sep 2024 - 22:16

» Editeur d étiquette avec QR évolutif
TreeView en Panoramic Emptypar JL35 Lun 23 Sep 2024 - 22:40

» BUG QR Code DelphiZXingQRCode
TreeView en Panoramic Emptypar Yannick Dim 22 Sep 2024 - 11:40

» fichier.exe
TreeView en Panoramic Emptypar leclode Ven 20 Sep 2024 - 19:02

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Novembre 2024
LunMarMerJeuVenSamDim
    123
45678910
11121314151617
18192021222324
252627282930 
CalendrierCalendrier
Le Deal du moment :
Boutique Nike : -25% dès 50€ sur TOUT le ...
Voir le deal

 

 TreeView en Panoramic

Aller en bas 
3 participants
AuteurMessage
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: TreeView en Panoramic   TreeView en Panoramic EmptyMer 7 Mai 2014 - 18:56

Depuis longtemps, je cherchais un moyen de faire une représentation en arborescence, de façon commode. En Delphi, je fais ça aisément avec le composant TTreeView, qui est très souple et marche très bien.

Or, malgré des recherches intensives, je n'ai pas pu le faire marcher avec Panoramic, sur le modèle du RichEdit, par exemple.

Donc, j'ai écrit un PanoramicTreeView (PTV), entièrement en Panoramic. Je montre ici la toute première version. Elle est encore incomplète, car il manquent les fonctions de recherche par chaîne de caractères et de suppression des noeuds. N"anmoins, on peut déjà se faire une bonne idée du fonctionnement.

Un bref rappel: Une représentation arborescente est une liste verticale de noms. Ceux qui sont collés tout à fait à gauche sont nommés "racines", ceux qui sont décalés vers la droite sont nommés "enfants", et ceci à plusieurs niveaux.
On peut créer le PTV.
On peut sauvegarder le PTV dans un fichier.
On peut charger un fichier sauvegardé dans un PTV.
On peut créer des noeuds racine, enfants pour racines ou enfants, et soeurs pour racines ou enfants.
On peut chercher le noeud parent ou le noeud racine de n'importe quel noeud.
Chaque noeud peut contenir des données (chaînes de caractères) qui sont mémorisées en interne et qui peuvent être lues pour le noeud actuel (celui qui vient d'être sélectionné ou qui est le résultat d'une recherche).

Voici le module #INCLUDE qui contient tout le code:
PTV_SUB.bas
Code:
' PTV_SUB.bas

' ############# ici, le #INCLUDE PTV_SUB.bas contenant tout ce qui suit #########
' ===============================================================================
' procédures de gestion du pseudo-objet PTV (PanoramicTreeView)
' Auteur: Klaus
'
' Procédures accessibles:
'    InitializePTV CreatePTV
'    SavePTV LoadPTV AddRootToPTV AddChildToPTV AddSisterToPTV
'    FindParentOfPTV FindRootOfPTV FoldNodeOfPTV UnfoldNodeOfPTV GetDataOfPTV
'    SelectNodeByAddressInPTV, SelectNodeByNameInPTV
'
' Procédures internes:
'    GetIndentOfPTV FindParentItemOfPTV EncodeNumberForPTV DecodeNumberForPTV
'    FormatAuxiliaryRecordForPTV EncodeDataForPTV DecodeDataForPTV

' =============== dipatching des fonctions ====================================
message "PTV: on ne peut pas executer ce module directement !"
terminate

' ********************** procédures publiques *************************************

sub InitializePTV()
' procedure optionnelle.
' Initialise les variables, mais c'est fait également dans CreatePTV.
' N"anmoins, cela évite un plantage lors d'un appel à une procédure avant la création.
  if variable("No%")=0 then dim No%
  if variable("PTV_actual_node%")=0 then dim PTV_actual_node%  : ' numéro du noeud actuel
  if variable("PTV_resultat%")=0 then dim PTV_resultat%        : ' résultat numérique
  if variable("PTV_resultat$")=0 then dim PTV_resultat$        : ' résultat chaîne de caractères
  if variable("PTV_table$")=0
    dim PTV_table$                                            : ' table d'encodage
    PTV_table$ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
  end_if
  PTV_actual_node% = 0
  if label("SelectPTV")=0 then label SelectPTV
end_sub

sub CreatePTV(P%,V%,T%,L%,H%,W%)
' création de l'objet PanoramicTreeView.
' Au retour, No% contient le numéro de l'objet LIST contenant le PTV visuel.
' L'objet No%-1 est une DLIST utilisée de façon interne.
  if variable("No%")=0 then dim No%
' la ligne suivante est la définition de la DLIST interne en utilisation normale
  No% = No% + 1 : dlist No%
' la ligne suivante est la définition de la DLIST interne en utilisation DEBUG
'  No% = No% + 1 : list No% : top No%,T% : left no%,L%+W%+10 : height No%,H% : width no%,900
  No% = No% + 1 : list No%
  if P% > 0 then Parent No%,P%
  If V% = 0 Then hide No%
  If H% > 0 Then Height No%,H%
  If W% > 0 Then Width No%,W%
  If T% > 0 Then Top No%,T%
  If L% > 0 Then Left No%,L%
  font_name No%,"Courier"
  if variable("PTV_actual_node%")=0 then dim PTV_actual_node%
  if variable("PTV_resultat%")=0 then dim PTV_resultat%
  if variable("PTV_resultat$")=0 then dim PTV_resultat$
  if variable("PTV_table$")=0
    dim PTV_table$
    PTV_table$ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
  end_if
  PTV_actual_node% = 0
  if label("SelectPTV")=0 then label SelectPTV
  on_click No%,SelectPTV
end_sub
SelectPTV:            : ' routine évènement pour la sélection d'un noeud de la PTV
  PTV_actual_node% = item_index(PTV%)
'  text e_nact%,str$(PTV_actual_node%)  : ' ligne à supprimer en utilisation normale
  return

sub SavePTV(PTV%,f$)
' sauvegarde du contenu du PTV dans deus fichiers:
'  *.ptv pour la partie visible LIST
'  *.ptx pour la partie interne DLIST
  dim_local s$
  if PTV%=0 then exit_sub
  s$ = f$
  if lower$(right$(s$,4))<>".ptv" then s$ = s$ + ".ptv"
  file_save PTV%,s$
  file_save PTV%-1,left$(s$,len(s$)-4)+".ptx"
end_sub

sub LoadPTV(PTV%,f$)
' restauration du contenu du PTV dans deus fichiers:
'  *.ptv pour la partie visible LIST
'  *.ptx pour la partie interne DLIST
  dim_local s$
  if PTV%=0 then exit_sub
  s$ = f$
  if lower$(right$(s$,4))<>".ptv" then s$ = s$ + ".ptv"
  if file_exists(s$)=0 then exit_sub
  file_load PTV%,s$
  file_load PTV%-1,left$(s$,len(s$)-4)+".ptx"
  if count(PTV%)>0
    PTV_actual_node% = 1
  else
    PTV_actual_node% = 0
  end_if
end_sub

sub AddRootToPTV(PTV%,lib$,dat$)
' ajouter un noeud racine, en fin de liste.
' un noeud racine est placé directement à gauche, sans indentation.
  if PTV%=0 then exit_sub
  FormatAuxiliaryRecordForPTV("",lib$,dat$)
  item_add PTV%-1,PTV_resultat$
  item_add PTV%,"- "+lib$
  PTV_actual_node% = count(PTV%)
end_sub

sub AddChildToPTV(PTV%,p%,lib$,dat$)
' ajouter un noeud enfant à un noeud parent.
' le noeud parent doit être le noeud actuellement sélectionné (dans PTV_actual_node%).
' le noeud enfant est ajouté à ce noeud parent, indenté d'un cran vers la droite.
' le paramètre p% donne la position:
'  1 = en fin de liste
'  0 = en début de liste
  dim_local s$, ind%, c$, pre$, i%, ptr%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  s$ = item_read$(PTV%,ptr%)
  GetIndentOfPTV(s$)
  ind% = PTV_resultat%
  for i%=1 to ind%+1 : pre$ = pre$ + "| " : next i%
  if p%>0
    c$ = left$(s$,ind%*2+2)
    if ptr%<count(PTV%)
      while ptr%<count(PTV%)
        ptr% = ptr% + 1
        s$ = item_read$(PTV%,ptr%)
        if left$(s$,ind%*2+2)=c$ then exit_while
      end_while
      ptr% = ptr% - 1
    end_if
  end_if
  FormatAuxiliaryRecordForPTV(pre$,lib$,dat$)
  item_insert PTV%-1,ptr%+1,PTV_resultat$
  item_insert PTV%,ptr%+1,pre$+"- "+lib$
  PTV_actual_node% = ptr%+1
end_sub

sub AddSisterToPTV(PTV%,p%,lib$,dat$) : ' p% conditionne le positionnement de la ligne
' ajouter un soeur enfant à un noeud parent.
' le noeud parent doit être le noeud actuellement sélectionné (dans PTV_actual_node%).
' le noeud enfant est ajouté à ce noeud parent,avec la même indentation.
' le paramètre p% donne la position:
'  1 = en fin de liste
'  0 = en début de liste
  dim_local s$, ind%, c$, pre$, i%, ptr%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  if ptr%=0 then ptr% = PTV_actual_node%
  FindParentItemOfPTV(PTV%,ptr%)
  if PTV_resultat%=0
    AddRootToPTV(PTV%,lib$,dat$)
  else
    PTV_actual_node% = PTV_resultat%
    AddChildToPTV(PTV%,p%,lib$,dat$)
  end_if
end_sub

sub FindParentOfPTV(PTV%)
' retourner le numéro du noeud parent du noeud actuellement sélectionné.
' Le résultat est retourné dans la variable PTV_resultat%.
' Si le noeud actuel est un noeud racine, la valeur 0 est retournée,
' car en effet, un noeud racide n'a pas de parent.
  dim_local ptr%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  FindParentItemOfPTV(PTV%,ptr%)
  if PTV_resultat%>0 then PTV_actual_node% = PTV_resultat%
end_sub

sub FindRootOfPTV(PTV%)
' retourner le numéro du noeud racine du noeud actuellement sélectionné.
' Le résultat est retourné dans la variable PTV_resultat%
' Si le noeud actuel est un noeud racine, la valeur 0 est retournée,
' car en effet, un noeud racide n'a pas de parent.
  dim_local ptr%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  repeat
    FindParentItemOfPTV(PTV%,ptr%)
    if PTV_resultat%>0 then PTV_actual_node% = PTV_resultat%
    ptr% = PTV_actual_node%
  until PTV_resultat% = 0
end_sub

sub FoldNodeOfPTV(PTV%)
' replier un noeud sur lui-même. Tous les noeuds enfant sont repliés et
' deviennent invisibles, et le noeud visé est marqué d'un signe "+".
  dim_local ptr%, s$, d$, d1$, d2$, ind%, pre$, i%, n%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  s$ = item_read$(PTV%,ptr%)
  GetIndentOfPTV(s$)
  ind% = PTV_resultat%
'  message str$(ptr%)+": "+str$(ind%)+"  ["+mid$(s$,ind%*2+1,1)+"]"
  if mid$(s$,ind%*2+1,1)="+" then exit_sub
  d$ = item_read$(PTV%-1,ptr%)          : ' lire la copie dans la DLIST
  i% = instr(d$,"-")
  d$ = left$(d$,i%-1) + "+" + mid$(d$,i%+1,len(d$)) : ' marquage "replié"
  pre$ = left$(s$,ind%*2)
  s$ = pre$ + "+ " + mid$(s$,ind%*2+3,len(s$))  : ' préparer le nouveau contenu du record
  item_delete PTV%,ptr%      : ' supprimer l'ancien
  item_insert PTV%,ptr%,s$  : ' et remplacer
  if ptr%<count(PTV%)
    n% = count(PTV%)
    i% = ptr%
    ptr% = ptr% + 1
    pre$ = pre$ + "| "
    d2$ = "00"  : ' préparer le cumul des lignes repliées
    while i%<n%
      i% = i% + 1
      s$ = item_read$(PTV%,ptr%)
      if left$(s$,ind%*2+2)<>pre$ then exit_while
      item_delete PTV%,ptr%          : ' supprimer dans l'arbre
      d1$ = item_read$(PTV%-1,ptr%)  : ' lire la copie dans la DLIST
      d2$ = left$(d2$,len(d2$)-2) + d1$    : ' et ajouter à celle du noeud. d1$ se termine déjà par "00" !
      item_delete PTV%-1,ptr%        : ' supprimer la copie dans DLIST
    end_while
  end_if
  EncodeNumberForPTV(len(d2$))      : ' longueur totale des lignes repliées
  d$ = left$(d$,len(d$)-2) + "zz" + PTV_resultat$ + d2$ : ' marquer et ajouter les lignes repliées au noeud
  item_delete PTV%-1,PTV_actual_node%        : ' supprimer l'ancienne copie
  item_insert PTV%-1,PTV_actual_node%,d$    : ' recréer la nouvelle copie dans la DLIST
end_sub

sub UnfoldNodeOfPTV(PTV%)
' délier un noeud sur lui-même. Tous les noeuds enfant sont dépliés et
' deviennent visibles, et le noeud visé est marqué d'un signe "-".
  dim_local ptr%, s$, ind%, d$, d1$, pre$, i%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  s$ = item_read$(PTV%,ptr%)
  GetIndentOfPTV(s$)
  ind% = PTV_resultat%
  if mid$(s$,ind%*2+1,1)="-" then exit_sub
  d$ = item_read$(PTV%-1,ptr%)    : ' lire la copie dans la DLIST
  i% = instr(d$,"+")
  d$ = left$(d$,i%-1) + "-" + mid$(d$,i%+1,len(d$)) : ' marquage "déplié"
  pre$ = left$(s$,2*ind%)
  s$ = pre$ + "- " + mid$(s$,ind%*2+3,len(s$))  : ' préparer le nouveau contenu du record
  item_delete PTV%,PTV_actual_node%      : ' supprimer l'ancien
  item_insert PTV%,PTV_actual_node%,s$  : ' et remplacer
  if left$(d$,2)="zz" then d$ = mid$(d$,5,len(d$)) : ' enlever l'éventuelle marque "éléments repliés"
'  d$ = mid$(d$,5,len(d$))                : ' enlever l'éventuelle marque "éléments repliés"
  DecodeNumberForPTV(left$(d$,2))        : ' décoder la longueur du noeud dans la copie
  d1$ = left$(d$,PTV_resultat%+2) + "00" : ' isoler le noeud
  item_delete PTV%-1,ptr%        : ' supprimer l'ancienne copie
  item_insert PTV%-1,ptr%,d1$    : ' recréer la nouvelle copie dans la DLIST
  d$ = mid$(d$,5+PTV_resultat%+2,len(d$))
  if len(d$)<2 then exit_sub
  repeat                          : ' boucle pour restituer les enregistrements repliés
    ptr% = ptr% + 1                      : ' passer au point d'insertion suivant
    if left$(d$,2)="zz"
      d$ = mid$(d$,3,len(d$))
      DecodeNumberForPTV(left$(d$,2))
      d1$ = left$(d1$,len(d1$)-2) + "zz" + left$(d$,PTV_resultat%)+"00"
      ptr% = ptr% - 1
      item_delete PTV%-1,ptr%
      item_insert PTV%-1,ptr%,d1$
      d$ = mid$(d$,PTV_resultat%+1,len(d$))
    else
      DecodeNumberForPTV(left$(d$,2))      : ' décoder la longueur du record replié dans la copie
      if PTV_resultat%>0                  : ' il y a une suite ?
        d1$ = left$(d$,PTV_resultat%+2) + "00"  : ' isoler le record replié suivant
        item_insert PTV%-1,ptr%,d1$            : ' recréer la nouvelle copie dans la DLIST
        d$ = mid$(d$,PTV_resultat%+3,len(d$))  : ' et les autres enregistrements repliés
        DecodeNumberForPTV(mid$(d1$,3,2))      : ' décoder la longueur du préfixe
        s$ = mid$(d1$,5,PTV_resultat%)          : ' début du record de l'arbre: préfixe
        i% = 4 + PTV_resultat% + 1
        DecodeNumberForPTV(mid$(d1$,i%,2))      : ' décoder la longueur du nom
        s$ = s$ + mid$(d1$,i%+2,PTV_resultat%)  : ' prendre le nom du record
        item_insert PTV%,ptr%,s$                : ' et insérer dans l'arbre
        PTV_resultat% = 1                      : ' juste par précaution...
      end_if
    end_if
  until PTV_resultat%=0
end_sub

sub GetDataOfPTV(PTV%)
' rechercher les données du noeud actuel.
  dim_local i%, s$
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  s$ = item_read$(PTV%-1,PTV_actual_node%)
  DecodeNumberForPTV(mid$(s$,3,2))
  i% = 3 + PTV_resultat% + 2
  DecodeNumberForPTV(mid$(s$,i%,2))
  i% = i% + 2 + PTV_resultat%
  DecodeNumberForPTV(mid$(s$,i%,2))
  DecodeDataForPTV(mid$(s$,i%+2,PTV_resultat%))
end_sub

sub SelectNodeByAddressInPTV(PTV%,n%)
' cibler un noeud par son numéro
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  if (n%>0) and (n%<=count(PTV%)) then PTV_actual_node% = n%
  PTV_resultat% = PTV_actual_node%
end_sub

sub SeletNodeByNameInPTV(PTV%,mode%,partiel%,name$)
' ++++++++++ pas encore implémentée.
' rechercher un noeud par son nom.
' mode:    0 = dans l'arbre visible, à partir du début
'          1 = dans l'arbre visible, à partir de la position actuelle
'          2 = dans l'arbre déplié,  à partir du début
'          3 = dans l'arbre déplié,  à partir de la position actuelle
' partiel: 0 = nom exact
'          1 = nom partiel

  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub

  PTV_resultat% = PTV_actual_node%
end_sub

' ********************** procédures internes **************************************

sub GetIndentOfPTV(s$)
  dim_local c$
  c$ = left$(s$,1)
  PTV_resultat% = 0
  while c$="|"
    PTV_resultat% = PTV_resultat% + 1
    c$ = mid$(s$,PTV_resultat%*2+1,1)
  end_while
end_sub

sub FindParentItemOfPTV(PTV%,p%)
  dim_local s$, ind%, c$, i%, ptr%
  if PTV%=0 then exit_sub
  if PTV_actual_node%=0 then exit_sub
  ptr% = PTV_actual_node%
  s$ = item_read$(PTV%,ptr%)
  GetIndentOfPTV(s$)
  ind% = PTV_resultat%
  if ind%=0
    PTV_resultat%  = 0
    exit_sub
  end_if
  while ptr%>1
    ptr%  = ptr% - 1
    s$ = item_read$(PTV%,ptr%)
    if (mid$(s$,ind%*2-1,1)="-") or (mid$(s$,ind%*2-1,1)="+") then exit_while
  end_while
  PTV_resultat% = ptr%
end_sub

sub EncodeNumberForPTV(n%)
  dim_local v%, v1%
  if n%<0
    PTV_resultat$ = "00"
  else
    if n%>=1024
      PTV_resultat$ = "VV"
    else
      v% = int(n%/32)
      v1% = n% - v%*32
      PTV_resultat$ = mid$(PTV_table$,v%+1,1)+mid$(PTV_table$,v1%+1,1)
    end_if
  end_if
end_sub

sub DecodeNumberForPTV(a$)
  dim_local v%, v1%
  v% = instr(PTV_table$,mid$(a$,1,1))
  v1% = instr(PTV_table$,mid$(a$,2,1))
  PTV_resultat% = (v%-1)*32 + (v1%-1)
end_sub

' <longueur totale><Longueur préfixe><préfixe><longueur libellé><libellé><longueur data><data><00>
sub FormatAuxiliaryRecordForPTV(pre$,lib$,dat$)
  dim_local s$, cnt%
  ' longueur du préfixe
  EncodeNumberForPTV(len(pre$+"- "))
  ' <Longueur préfixe><préfixe>
  s$ = PTV_resultat$ + pre$ + "- "
  ' longueur du libellé
  EncodeNumberForPTV(len(lib$))
  ' <Longueur préfixe><préfixe><longueur libellé><libellé>
  s$ = s$ + PTV_resultat$+lib$
  ' encoder les données
  EncodeDataForPTV(dat$)
  ' <Longueur préfixe><préfixe><longueur libellé><libellé><longueur data><data>
  s$ = s$ + PTV_resultat$
  ' longueur totale
  EncodeNumberForPTV(len(s$))
  ' <longueur totale><Longueur préfixe><préfixe><longueur libellé><libellé><longueur data><data><00>
  PTV_resultat$ = PTV_resultat$ + s$ + "00"
end_sub

Sub EncodeDataForPTV(s$)
 dim_local cnt%, i%, t$
 cnt% = len(s$)
 if cnt%>0
  i% = 0
  t$ = ""
  while i%<len(s$)
    i% = i% + 1
    if mid$(s$,i%,1)="#"
      t$ = t$ + "##"
      cnt% = cnt% + 1
    else
      if asc(mid$(s$,i%,1))<32
        t$ = t$ + "#" + chr$(asc(mid$(s$,i%,1))+32)
        cnt% = cnt% + 1
      else
        t$ = t$ + mid$(s$,i%,1)
      end_if
    end_if
  end_while
 end_if
 EncodeNumberForPTV(len(t$))
 PTV_resultat$ = PTV_resultat$ + t$
end_sub

sub DecodeDataForPTV(s$)
  dim_local i%, skip%
  skip% = 0
  PTV_resultat$ = ""
  if len(s$)>0
    for i%=1 to len(s$)
      if skip%=1
        skip% = 0
      else
        if mid$(s$,i%,1)="#"
          skip% = 1
          if mid$(s$,i%+1,1)="#"
            PTV_resultat$ = PTV_resultat$ + "#"
          else
            PTV_resultat$ = PTV_resultat$ + chr$(asc(mid$(s$,i%+1,1))-32)
          end_if
        else
          PTV_resultat$ = PTV_resultat$ + mid$(s$,i%,1)
        end_if
      end_if
    next i%
  end_if
end_sub

Programme de démo:
PanoramicTreeView.bas
Code:
' PanoramicTreeView.bas
'
' Ce programme crée et teste un pseudo_objet PTV.
' Cet objet donne certaines possibilités de TTreeView,
' mais il est entièrement réalisé en Panoramic.
'
' L'objet DLIST associe contient une copie des enregistrements, avec un encodage spécifique.
' Les données sont encodées de sorte à transformer tous les caractères invisibles (<32)
' en #<c+32>, ainsi que le # lui-même qui deviendra ##.
' Si le préfixe est "+", cela signifie que la ligne DLIST contient un ensemble de lignes
' repliées, toutes codées de la même manière.
' Exemple d'un TreeView complètement déplié, avec les données introduites par un "/" :
' - Animaux/domestiques et sauvages
' | - Mammifères/sang chaud
' | | - Bovins/domestiques
' | | - Chevaux/domestiques
' | | - Souris/sauvages
' | - Oiseaux/sang chaud
' | | - Cigognes/sauvage, mange grenouilles
' | | - Poules/domestiques, pond de oeufs
' - Plantes/cultivées et sauvages
' | - Céréales/essentiellement cultivées
' | | - Blé/nourriture de base
' | | - Riz/nourriture de base
' | - Légumes/cultivés
' | | - Haricots/cultivés
'
' Replier la ligne "| - Oiseaux/sang chaud" conduit au résultat suivant:
' - Animaux/domestiques et sauvages
' | - Mammifères/sang chaud
' | | - Bovins/domestiques
' | | - Chevaux/domestiques
' | | - Souris/sauvages
' | + Oiseaux/sang chaud  | | - Cigognes/sauvage, mange grenouilles  | | - Poules/domestiques, pond de oeufs
' - Plantes/cultivées et sauvages
' | - Céréales/essentiellement cultivées
' | | - Blé/nourriture de base
' | | - Riz/nourriture de base
' | - Légumes/cultivés
' | | - Haricots/cultivés

' replier maintenant "- Animaux/domestiques et sauvages" conduit à ceci;
' + Animaux/domestiques et sauvages | - Mammifères/sang chaud | | - Bovins/domestiques | | - Chevaux/domestiques | | - Souris/sauvages | + Oiseaux/sang chaud  | | - Cigognes/sauvage, mange grenouilles  | | - Poules/domestiques, pond de oeufs
' - Plantes/cultivées et sauvages
' | - Céréales/essentiellement cultivées
' | | - Blé/nourriture de base
' | | - Riz/nourriture de base
' | - Légumes/cultivés
' | | - Haricots/cultivés
'
' un PanoramicTreeView peut être sauvegardé ou restauré dans un fichier *.ptv, et *.ptx pour la partie DLIST.
' Les deux fichiers sont créés simultanément, et doivent coexister pour recharger le tableau.
'
' Tous les enregistrements de la DLIST ont le format suivant:
' <longueur totale><Longueur préfixe><préfixe><longueur libellé><libellé><longueur data><data>...répétition...<00>
' Si une branche de l'arbre est repliée, toutes les lignes repliées sont stockées dans la ligne du noeud replié,
' selon exactement le même format, juste à la suite. Et logiquement, la suite se termine par un <00> qui signifie
' que la longueur de la ligne suivante est zéro, donc que c'est la fin des lignes repliées. Ceci permet de
' déplier cette ligne en réinsérant dans la LIST et la DLIST toutes les lignes individuelles, tout en supprimant
' tout ça de la ligne du noeud d'origine, sauf bien sûr la toute première partie contenant le libellé et les
' données du noeud.

label creer, sauver, charger, ajracine, ajenfant, ajsoeur
label chparent, chracine, chdonnees
label plier, deplier

dim PTV%, e_nact%, e_lib%, e_dat%, e_dact%, d_open%, d_save%, f$

' width 0,700
full_space 0

xButton(10,10,0,0,"Créer") : on_click no%,creer
xButton(40,10,0,0,"Sauver") : on_click no%,sauver
xButton(70,10,0,0,"Charger") : on_click no%,charger
xAlpha(10,110,0,0,"Libellé:")
xEdit(10,160,260,0,0) : e_lib% = no%
xAlpha(40,110,0,0,"Données:")
xEdit(40,160,260,0,0) : e_dat% = no%
xButton(70,160,0,0,"Aj. Racine") : on_click no%,ajracine
xButton(70,250,0,0,"Aj. Enfant") : on_click no%,ajenfant
xButton(70,340,0,0,"Aj. Soeur") : on_click no%,ajsoeur
xButton(10,430,0,0,"Ch. Parent") : on_click no%,chparent
xButton(40,430,0,0,"Ch. Racine") : on_click no%,chracine
xButton(70,430,0,0,"Ch. Données") : on_click no%,chdonnees
xButton(10,520,0,0,"Plier") : on_click no%,plier
xButton(40,520,0,0,"Deplier") : on_click no%,deplier

xAlpha(410,10,0,0,"Noeud actuel:")
xEdit(410,120,68,0,1) : e_nact% = no% : font_bold e_nact%
xAlpha(440,10,0,0,"Données actuelles:")
xEdit(440,120,280,0,1) : e_dact% = no% : font_bold e_dact%

xSaveDialog("PanoramicTreeView|*.ptv") : d_save% = no%
xOpenDialog("PanoramicTreeView|*.ptv") : d_open% = no%

InitializePTV()

end

creer:
  CreatePTV(0,1,100,10,300,400) : PTV% = no%
  text e_nact%,str$(PTV_actual_node%)
  return
 
sauver:
  f$ = file_name$(d_save%)
  if f$<>"_" then SavePTV(PTV%,f$)
  return

charger:
  f$ = file_name$(d_open%)
  if f$<>"_"
    LoadPTV(PTV%,f$)
    text e_nact%,str$(PTV_actual_node%)
  end_if
  return

ajracine:
  AddRootToPTV(PTV%,text$(e_lib%),text$(e_dat%))
  text e_nact%,str$(PTV_actual_node%)
  return
 
ajenfant:
  AddChildToPTV(PTV%,1,text$(e_lib%),text$(e_dat%))
  text e_nact%,str$(PTV_actual_node%)
  return

ajsoeur:
  AddSisterToPTV(PTV%,1,text$(e_lib%),text$(e_dat%))
  text e_nact%,str$(PTV_actual_node%)
  return
 
chparent:
  FindParentOfPTV(PTV%)
  text e_nact%,str$(PTV_actual_node%)
  return

chracine:
  FindRootOfPTV(PTV%)
  text e_nact%,str$(PTV_actual_node%)
  return
 
chdonnees:
  text e_nact%,str$(PTV_actual_node%)
  GetDataOfPTV(PTV%)
  text e_dact%,PTV_resultat$
  return
 
plier:
  FoldNodeOfPTV(PTV%)
  return

deplier:
  UnfoldNodeOfPTV(PTV%)
  return

' contient tout ce qu'il faut pour PTV
#INCLUDE "PTV_SUB.bas"
' contient les procédures pour créer les objets Panoramic
#INCLUDE "KGF_OBJ.bas"

Et les fichiers pour une démo, en version repilée et en version dépliée:
demo_dépliée.ptv
Citation :
- Animaux
| - Mammifères
| | - Chevreuil
| | - Sanglier
| | - Cochon
| - Poissons
| | - Lieu noir
| | - Truite
| - Insectes
| | - Guêpe
| | - Fourni
- Plantes
| - Yf
| - Choux de Bruxelles
| - Rose trémiaire
| - Chêne

demo_dépliée.ptx
Citation :
1G02- 07Animaux10Poissons, mammifères et insectes00
1B04| - 0AMammifères0NSauvages et domestiques00
1706| | - 09Chevreuil0ISauvage, herbivore00
1506| | - 08Sanglier0HSauvage, omnivore00
1606| | - 06Cochon0KDomestique, omnivore00
1904| - 08Poissons0NEau douce et eau de mer00
0V06| | - 09Lieu noir0AEau de mer00
0R06| | - 06Truite09Eau douce00
1804| - 08Insectes0MVolants et non volants00
1206| | - 05Guêpe0HVolant, dangereux00
1806| | - 06Fourni0MNon volant, inoffensif00
1802- 07Plantes0PArbres, fleurs et légumes00
1904| - 02Yf0TArbre à feuilles persistantes00
1A04| - 0IChoux de Bruxelles0ELégume d'hiver00
0T04| - 0ERose trémiaire05Fleur00
1804| - 05Chêne0PArbre à feuilles caduques00

demo_repliée.ptv
Code:
+ Animaux
+ Plantes

demo_repliée.ptx 1ère ligne
Citation :
1F02+ 07Animaux10Poissons, mammifères et insecteszzCK1B04| + 0AMammifères0NSauvages et domestiqueszz3Q1706| | - 09Chevreuil0ISauvage, herbivore1506| | - 08Sanglier0HSauvage, omnivore1606| | - 06Cochon0KDomestique, omnivore1904| + 08Poissons0NEau douce et eau de merzz200V06| | - 09Lieu noir0AEau de mer0R06| | - 06Truite09Eau douce1804| + 08Insectes0MVolants et non volantszz2G1206| | - 05Guêpe0HVolant, dangereux1806| | - 06Fourni0MNon volant, inoffensif00
demo_repliée.ptx 2eme ligne
Citation :
1802+ 07Plantes0PArbres, fleurs et légumeszz521904| - 02Yf0TArbre à feuilles persistantes1A04| - 0IChoux de Bruxelles0ELégume d'hiver0T04| - 0ERose trémiaire05Fleur1804| - 05Chêne0PArbre à feuilles caduques00
Il faut éventuellement enlever les retours à la ligne dans ces deux dernières cases, puis combiner ces deux lignes en un seul fichier demo_repliée.ptx.

Attention: KGF_OBJ.bas dernière version est obligatoire !
Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
papydall

papydall


Nombre de messages : 7017
Age : 74
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyMer 7 Mai 2014 - 21:07

Bravo  klaus.
Personnellement j’utilise la commande TREE de l’invite de commande.
Mais le résultat est médiocre.
Ta solution est meilleure.

Code:

height 0,700 : width 0,400
memo 10 : width 10,300 : height 10,2000 : left 10,50 : font_bold 10
execute_wait "cmd.exe /c tree | clip"
item_add 10,clipboard_string_paste$

Revenir en haut Aller en bas
http://papydall-panoramic.forumarabia.com/
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyMer 7 Mai 2014 - 23:59

Je voulais faire un outil utilisable pour n'importe qu'elle type d'information à présenter sous forme d'abre. cela peut être une liste de fichiers et dossiers, une nomenclature de pièces détachées pour un éclaté dans un contexte de maintenance de moteurs, voitures, etc, une liste d'ingrédients pour un processus de fabrication, une hiérarchie administrative, ... Les applications potentielles sont légion. Et le but est d'avoir un outil permettant non seulement la représentation graphique, mais également la modification interactive, et la mémorisation de données variables avec chaque élément. Ces données ne sont pas affichées, mais restent attachées à un élément et peuvent être interrogées et modifiées à tout moment. Ce n'est pas une base de données, mais c'est plus qu'un simple fichier géré par liste.

D'ailleurs, dans Windows, on a des TreeView partout. Pour les dossiers et fichiers, bien sûr, mais également pour l'outil de maintenance des clés de registre, beaucoup d'outils utilisent ce moyen pour la gestion de leurs options de configuration, etc.

C'est pourquoi je voulais tellement injecter le TTreeVew de Delphi dans Panoramic. J'ai pu le créer et injecter, le dimensionner et le supprimer, même en exemplaires multiples. J'ai réussi à construire des structures arborescentes dans cet élément, et à les interroger. Mais je n'ai jamais réussi à lui faire afficher ces informations, même si elles étaient bien présentes et mémorisées dans l'objet. Très frustrant. Donc, je me suis lâché sur Panoramic et je l'ai cuisiné moi-même. J'y ajouterai une série de fonctionnalités supplémentaires prochainement, avant de l'inclure officiellement sur mon site dans la liste des pseudo-objets.

Certes, j'aurais aimé qu'un tel objet apparaisse nativement dans Panoramic.Mais sachant à quel point Jack est surchargé, je n'ai même pas fait la demande pour un tel ajout. La seule chose que je ne pourrai pas faire en Panoramic et qui est possible avec un objet TTreeView, c'est la possibilité d'affecter une icône de 16x16 pixels à chaque élément. Mais bon. On ne peut pas tout avoir. L'important, c'est la fonctionnalité, et elle est là.

J'aimerais apporter un complément d'information. Ce module est fait en Panoramic pur, sans utilisation de DLL. Donc, tout le monde peut s'en servir. Mais il y a un hic: si par l'appel à une procédure, le numéro de la ligne sélectionnée a changé, ce ne sera pas visuellement perceptible dans l'affichage, par en Panoramic, il n'y a aucun moyen de forcer la sélection (ligne sur fond bleu) d'une ligne d'un objet LIST. Je peux le faire par un simple appel de la fonction SelectListBoxItem de KGF.dll, mais je devrais alors imposer l'utilisation de KGF.dll. Je pense que je vais introduire cela par la détection automatique de la présence de KGF.dll, de sorte à résoudre ce problème automatiquement dans les programmes qui ont de toutes façon cette DLL.
Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
jjn4

jjn4


Nombre de messages : 2747
Date d'inscription : 13/09/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyJeu 8 Mai 2014 - 13:05

J'avais déjà réalisé cela entièrement en panoramic
dans la partie Treeviewramic de l'utilitaire Récapituloramic
que j'avais présenté récemment, mais c'était seulement
pour l'arborescence des mémoires informatiques
(clés USB ou disques durs).
Le tien a l'avantage de le faire pour toutes les arborescences.
Bravo !
 cheers  alien  cheers
Revenir en haut Aller en bas
http://jjn4.e-monsite.com
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyJeu 8 Mai 2014 - 18:11

Nouvelle version:
J'ai ajouté 2 possibilités:
- suppression du pseudo-objet PTV
- recherche d'un nom dans les noeuds visibles, avec 3 options:

à partir du début ou à partir de la position actuelle
recherche du nom complet ou partiel
respect de la casse ou casse indifférente

J'ai tout mis sur lme WebDav, dossier "PTV - PanoramicTreeView". C'est plus pratique comme ça.

Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyJeu 8 Mai 2014 - 19:00

Nouvelle version:
PTV_SUB.bas détecte maintenant automqtiquement si KGF.dll est chargée. Si oui, la ligne sélectionnée en résultat à un appel de procédure est automatiquement sélectionnée. Sinon, le programme fonctionne exactement de la même manière, mais il n'y a pas le repère visuel de la ligne sélectionnée, car c'est impossible à faire en Panoramic pur.

Le progralle de démo propose un bouton "Charger KGF.dll" au démarrage. Si l'on clique dessus, KGF.dll est chargée et le bouton disparait. Il fait bien sûr adapter le chemin vers la dll.

Maintenant, avec KGF.dll, l'effet de PTV est assez spectaculaire. Vous pouvez vérifier que pour chaque ligne, il y a des données spécifiques. Elles peuvent être visualisées dans le programme de démo, en sélectionnant une ligne puis en cliquant sur le bouton "Ch. données".
Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
Invité
Invité




TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyVen 9 Mai 2014 - 0:20

Klaus a écrit:
la ligne sélectionnée en résultat à un appel de procédure est automatiquement sélectionnée. Sinon, le programme fonctionne exactement de la même manière, mais il n'y a pas le repère visuel de la ligne sélectionnée, car c'est impossible à faire en Panoramic pur.
J'ai pas fait l'essai de ton programme. J'ai peux de temps en ce moment, et j'ai eu un problème très curieux que j'ai eu du mal à résoudre dans le temps consacré à l'ordi.
Chaque fois que j'essayai de taper sur un lien ou un moteur de recherche, et avec tous les navigateurs que je possède, j'ouvrais une boite de dialogue pour enregistrer la commande.

Mais pour me changer les idées, j'ai voulu faire l'essai avec trois alphas pour simuler un TreeView avec un repère visuel.

Code:
dim a$,l%
dim t$,m$ , s$
t$ = chr$(13)
m$ = chr$(149)
s$ = "   "
form 5:width 5,500:left 5,200:top 5,100 : color 5,255,255,255 :command_target_is 5
alpha 7:font_size 7,10 : left 7,10:top 7,10 : font_name 7,"Consolas"
alpha 8:font_size 8,10 : left 8,10 : font_name 8,"Consolas" : color 8 ,184,195,208
alpha 9:font_size 9,10 : left 9,10 : font_name 9,"Consolas"

alfa()

end
' =========================================

sub alfa()
    dim_local a$ , b$ , c$ , h%  , m%

    a$ = m$+"C:"+t$+s$+m$+"Pano"+t$+s$+s$+m$+"Basic Panoramic"+t$+s$+s$+s$+"logo.ico"
    caption 7,a$
    h% = height(7)+top(7)
    b$ = s$+s$+s$+"Panoramic_Editor.exe            "
    top 8,h% : caption 8,b$
    h%=h%+height(8)
    c$ = s$+s$+s$+"Nouveau_1.bas" +t$+s$+s$+m$+"Mémoire"+t$+s$+s$+s$+"teste1.txt"+t$+s$+s$+s$+"teste2.txt"
    top 9,h%
    caption 9,c$
    m% = max(width(7),width(8))
    m% = max(m%,width(9))
    height 5,h%+height(9)+50 :width 5,m%+30
end_sub
C'est du vite fait, juste pour voir le visuel.

Edit: Deux alphas pourraient suffire en écrivant tout, et en retenant la position de la ligne, et rajouter le 2ème pour la ligne en sur-écriture.
Revenir en haut Aller en bas
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyVen 9 Mai 2014 - 0:55

Jolie présentation, Cosmos70. Graphiquement plus agréable que la mienne. Mais tu ne peux pas cliquer que une ligne pour déterminer le numéro de ligne et la sélectionner graphiquement. Ca, c'est l'intérêt des listes.
Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
Invité
Invité




TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyVen 9 Mai 2014 - 1:41

J'ai juste voulu voir le visuel. Je n'ai pas regardé ton code, donc je ne peux pas décider si ça vaut le coup ou non, mais là je ne suis pas d'accord.

Surtout avec 2 alphas, c'est encore plus simple. Je n'ai pas fait l'essai ici, mais je crois qu'il y avait quelque chose de semblable dans pagiciel.
Dans a$, au fur et à mesure que tu incrémentes d'une ligne( je sais c'est une chaîne,  mais je pense que tu comprend) je retiens la hauteur de la ligne pour la mettre dans un tableau. Avec on click sur l'alpha principal, je regarde la position et je compare avec celui du tableau.

On peux même procédé autrement. considérant que l'écriture d'une ligne fasse 10 pixels, selon la position relevée sur le clic, on connait la ligne.

Maintenant je ne connait pas ton programme, et je fais des hypotèses. Peut-être ça ne vaut rien, et je viens de vérifier: mouse_y_position ne créé pas d'erreur sur alpha. C'est juste une idée, sans vouloir t'imposer ce concept. mais je ne peux seulement pas accepter ce que je considère comme une erreur de réflexion. Mais ne t'en fais pas, je me trompe souvent.

Là dessus bonne nuit. Je vais comme mes chats, je vais faire ronron.  Sleep
Revenir en haut Aller en bas
Klaus

Klaus


Nombre de messages : 12331
Age : 75
Localisation : Ile de France
Date d'inscription : 29/12/2009

TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyVen 9 Mai 2014 - 2:12

Oh, ce n'est pas une erreur de réflexion, Cosmos70. Certes, comme tu le décris très bien, on peut connaître la position du clic sur un ALPHA, ainsi que la hauteur d'une ligne, et en déduire le numéro de ligne affichée.

Mais ce numéro n'est pas le numéro de la ligne de données, en tout cas pas dans le cas d'un LIST, qui peut défiler à l'écran avec la barre de défilement vertical, ce qui est toujours le cas si le nombre de lignes à afficher dépasse le nombre de lignes affichables simultanément dans un ALPHA. Car je veux pouvoir faire des arbres de n'importe quel nombre de lignes et des lignes de n'importe quelle largeur, quelque soit l'espace d'affichage disponible.

Certes, je pourrais tout garder dans une DLIST, gérer le défilement mo-même en réaffichant uniquement la partie utile. C'est ce que je fais dans mon pseudo-objet GLIST. Mais je sais aussi quelle galère c'est, et j'ai voulu économiser ce travail qui est très bien fait par l'objet LIST, pour me concentrer sur le codage de la partie arborescence. Et tant pis pour l'aspect graphique. Mais essaie le programme, tu verras que ce n'est pas si catastrophique que ça...
Revenir en haut Aller en bas
http://klauspanoramic.comxa.com/index.html
Invité
Invité




TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic EmptyVen 9 Mai 2014 - 2:21

je me suis relevé, j'avais une autre idée:
Code:
list 1:item_add 1,"je regarde":item_add 1,"passer le train":item_add 1,"le soir":item_add 1,"au fond des bois"
width 1,300:height 1,200 : font_size 1,10

list 2:top 2,43:color 2,184,195,220 : font_size 2,10 :height 2,22 : width 2,300
 item_add 2, "ligne alpha"

On se croise. Bon moi je ne fais pas le programme. Je réagissais par rapport à l'impossibilité de faire qui était dite, et simplement je voulais montrer que cela se discutait, et j'ai fait un petit programme pour voir le résultat. Il est hors de question de reprendre ton travail. J'ai mes propres problèmes que je résous petit à petit. Car moi aussi de mon côté je dois surmonter des obstacles auxquels je ne m'attend pas.

Cette fois-ci bonne nuit.
Revenir en haut Aller en bas
Contenu sponsorisé





TreeView en Panoramic Empty
MessageSujet: Re: TreeView en Panoramic   TreeView en Panoramic Empty

Revenir en haut Aller en bas
 
TreeView en Panoramic
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Simulation d'un objet TreeView
» Logithèque : une base de données en Panoramic pour Panoramic
» IDE Panoramic écrit en Panoramic
» PANORAMIC V 0.9.6 available / PANORAMIC V 0.9.6 disponible
» Logo Panoramic en Panoramic

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: Vos sources, vos utilitaires à partager-
Sauter vers: