Statistiques fichiers projet PHP

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Statistiques fichiers projet PHP

Message par Cls »

En lien avec le topic de flaith (ici : http://www.purebasic.fr/french/viewtopic.php?f=6&t=8933).

Ce programme permet de détecter les fonctions inutilisées d'un répertoire contenant un projet PHP. Les fichiers à prendre en compte sont configurables (PHP, TPL, JS, etc.). Initialement je l'ai programmé pour savoir quelles fonctions je pouvais supprimer dans un projet PHP qui était légèrement parti en live.

Version PB : 4.31
Version source : Décembre 2008
Librairies optionnelles : PureLVSort (par défaut, vous n'en avez pas besoin. Dé commenter les lignes si besoin).

Fichier FonctionsInutilisees.pb

Code : Tout sélectionner

; Module de recherche des fonctions non utilisées d'un fichier PHP
; Version : Décembre 2008
; Auteur : Cls


; Fonctionnement
; 2 passes sur l'arboresence
;  - on recherche toutes les fonctions du projet
;  - on regarde le nombre d'utilisation dans le projet

; On sort ensuite les fonction non utilisées :)

; /!\ REMARQUE : en PHP, les noms des fonctions ne sont pas sensibles à la casse !
; [contrairement aux noms des variables]



; -------------------------------------------------------------------------------------------
;- Includes
; -------------------------------------------------------------------------------------------

XIncludeFile "FonctionsInutiliseesInterface.pb"


; -------------------------------------------------------------------------------------------
;- Variables globales
; -------------------------------------------------------------------------------------------


Global RootDirectory.s = "D:\"



; Fonctions du projet
Structure FCT
  nom.s              ; Nom de la fonction
  nb.l               ; Nombre d'occurence trouvée
  source_file.s      ; Fichier source
  line.l             ; Ligne dans le fichier source
  index.l              ; index dans le fichier source
EndStructure 

Global NewList Fonction.FCT()



; Fichier du projet
Structure FICHIER
  nom.s
  nb.l
EndStructure

Global NewList Fichier.FICHIER()




; Stocke les statistiques du projet
Structure STATS
  id.l
  valeur.l
  nom.s
  unite.s
  type.b
EndStructure

Global Dim Statistiques.STATS(50)
x = 0 : Statistiques(x)\id = 1 : Statistiques(x)\nom = "Lignes de code"               : Statistiques(x)\unite = "lignes"
x + 1 : Statistiques(x)\id = 2 : Statistiques(x)\nom = "Lignes de commentaire"        : Statistiques(x)\unite = "commentaires"
x + 1 : Statistiques(x)\id = 3 : Statistiques(x)\nom = "Taille du projet"             : Statistiques(x)\unite = ""              : Statistiques(x)\type = 1
x + 1 : Statistiques(x)\id = 4 : Statistiques(x)\nom = "Taille moyenne des fichiers"  : Statistiques(x)\unite = ""              : Statistiques(x)\type = 1
x + 1 : Statistiques(x)\id = 5 : Statistiques(x)\nom = ""                             : Statistiques(x)\unite = ""



; Tous les répertoires listé ici ne seront pas parcourus par les fonctions de recherche
Global NewList ExcludeDirectory.s()


; Liste des extensions de fichiers à prendre en compte
Global NewList UsedExtension.s()
  AddElement(UsedExtension()) : UsedExtension() = "php"
  AddElement(UsedExtension()) : UsedExtension() = "tpl"



; Statistiques

Global FileToScanned.l
Global FileScanned.l
Global TailleTotale.l


; Valeur des barres de progression
Global ProgressMaxValues.l
Global ProgressCurrentValues.l



; -------------------------------------------------------------------------------------------
;- Procédures & Fonctions
; -------------------------------------------------------------------------------------------

Declare MajProgressBar()


; Renvoi la taille formatée correctement (format Windows)
Procedure.s getComputedSize(octets.l)
  
  If octets < 1024
    ProcedureReturn Str(octets) + " o"
  ElseIf octets < 1024 * 1024
    ProcedureReturn StrF(octets/1024, 1) + " Ko"
  ElseIf octets < 1024 * 1024 * 1024
    ProcedureReturn StrF(octets/(1024*1024), 1) + " Mo"
  Else
    ProcedureReturn StrF(octets/(1024*1024*1024), 1) + " Go"
  EndIf
    
EndProcedure


; Recherche de toutes les fonctions de l'application
; elle commence par le mot clef "function" [espace] NOM_DE_LA_FONCTION (paramètres éventuels)
Procedure Scan_File_For_Function(filename.s)

  Global FileToScanned

  f = ReadFile(#PB_Any, filename)
  
  If f
    
    nb_line.l = 0
    FileToScanned + 1
    
    ; STATISTIQUES sur la taille du projet
    Statistiques(2)\valeur + Lof(f)
    Statistiques(3)\valeur = Statistiques(2)\valeur / CountList(Fichier())
    
    
    
    ; Lit le fichier entier
    While Eof(f) = 0
      
      line_correct.s = ReadString(f)
      
      line.s = LCase(line_correct)
      nb_line + 1
      
      
      ; STATISTIQUES sur les lignes de code
      If Trim(line_correct) <> ""
        Statistiques(0)\valeur + 1
        
        ; Ligne de commentaire
        If FindString(Trim(line_correct), "//", 1) Or FindString(Trim(line_correct), "/*", 1) Or FindString(Trim(line_correct), "*/", 1) Or Left(Trim(line_correct), 1) = "*"
          Statistiques(1)\valeur + 1
        EndIf
          
      EndIf
      
      
      idx = FindString(line, "function", 1)
      If idx = 1 Or (idx > 1 And (Mid(line, idx-1, 1) = " " Or Mid(line, idx-1, 1) = Chr(9))) 
      
        ; FUNCTION a été trouvé
        ; Cherche le nom de la fonction
        ; On cherche une parenthèse pour délimiter la fonction
        idx_parenthese = FindString(line, "(", idx)
        If idx_parenthese > 0
          function_name.s = Mid(line_correct, idx + 9, idx_parenthese - (idx + 9))
          function_name = Trim(function_name)
          
          If function_name ; Ne prend pas en compte le nom des fonctions vides
          
            ; Ajoute la fonction dans la liste des fonctions
            AddElement(Fonction())
              Fonction()\nom = function_name
              Fonction()\source_file = filename
              Fonction()\line = nb_line
              Fonction()\index = idx + 9   
          EndIf       
          
        EndIf
      Else
        ;Debug Mid(line, idx-1, 1)
        
      EndIf
      
      
    
    Wend 
    
    
    CloseFile(f)
  EndIf
  
  
EndProcedure

; Scan les fichiers pour compter l'utilisation des fonctions
Procedure Scan_File_For_Count(filename.s)

  Global FileScanned
  Global TailleTotale
  Global ProgressCurrentValues
  
  f = ReadFile(#PB_Any, filename)
  
  If f
    
    ; STATS
    
    TailleTotale + Lof(f)
    FileScanned + 1
    
    ProgressCurrentValues = FileScanned
    MajProgressBar()
    WindowEvent()
    
    ; Lit le fichier par bloc de 50k (pour éviter les buffer overflow qui ferait planter le programme) 
    ; (En PB les strings de base sont limitées à 65535 octets)
    bloc.s = ""
    While Eof(f) = 0
      
      bloc + LCase(ReadString(f))
      
      ; Si le bloc est > à 50k on le traite
      If Len(bloc) > 50000
        
        ;Debug "[+ 50k] " + bloc
        ForEach Fonction()

          idx = FindString(bloc, LCase(Fonction()\nom), 1)
          While idx > 0
            
            Fonction()\nb + 1
            
            idx = FindString(bloc, LCase(Fonction()\nom), idx + Len(Fonction()\nom))
            
          Wend
          
        Next
        
        bloc = ""
        
      EndIf
    
    Wend 

    
    ; Si le bloc est <= à 50k il n'a pas encore été traité ! On le fait bloc
    If Len(bloc) <= 50000
      
      ;Debug "[- 50k] " + bloc
      ForEach Fonction()
        
        idx = FindString(bloc, LCase(Fonction()\nom), 1)
        While idx > 0
          
          Fonction()\nb + 1
          
          idx = FindString(bloc, LCase(Fonction()\nom), idx + Len(Fonction()\nom))
          
        Wend
        
      Next
      
      bloc = ""
      
    EndIf
    
    
    CloseFile(f)
  EndIf

EndProcedure

; Scan un fichier à la recherche des includes
; Permet de compter le nombre d'utilisation d'un fichier (via les INCLUDEs uniquement)
Procedure Scan_File_For_Include(filename.s)
  
  f = ReadFile(#PB_Any, filename)
  
  If f    
    ; Lit le fichier par bloc de 50k (pour éviter les buffer overflow qui ferait planter le programme) 
    ; (En PB les strings de base sont limitées à 65535 octets)
    bloc.s = ""
    While Eof(f) = 0
      
      bloc + ReadString(f)
      
      ; Si le bloc est > à 50k on le traite
      If Len(bloc) > 50000
        
        ;Debug "[+ 50k] " + bloc
        ForEach Fichier()
          
          idx = FindString(LCase(bloc), LCase(GetFilePart(Fichier()\nom)), 1)
          While idx > 0
            
            Fichier()\nb + 1
            idx = FindString(LCase(bloc), LCase(GetFilePart(Fichier()\nom)), idx + Len(GetFilePart(Fichier()\nom)))
            
          Wend
          
        Next
        
        bloc = ""
        
      EndIf
    
    Wend 
    
    ; Si le bloc est <= à 50k il n'a pas encore été traité ! On le fait.
    If Len(bloc) <= 50000
      
      ;Debug "[- 50k] " + bloc
      
      ForEach Fichier()
          
          idx = FindString(LCase(bloc), LCase(GetFilePart(Fichier()\nom)), 1)
          While idx > 0
            
            Fichier()\nb + 1
            idx = FindString(LCase(bloc), LCase(GetFilePart(Fichier()\nom)), idx + Len(GetFilePart(Fichier()\nom)))
            
          Wend
          
        Next
      
      bloc = ""
      
    EndIf
    
    
    CloseFile(f)
  EndIf
EndProcedure

Procedure IsFileToScan(filename.s)
  
  ForEach UsedExtension()
    If UsedExtension() = GetExtensionPart(filename)
      ProcedureReturn #True
    EndIf
  Next
  
  ProcedureReturn #False
EndProcedure


Procedure IsDirectoryAuthorized(dir.s)
  ; Test s'il ne s'agit pas d'un repetoire interdit
  ForEach ExcludeDirectory()
    If LCase(dir) = LCase(ExcludeDirectory())
      ProcedureReturn #False
    EndIf
  Next
  
  ProcedureReturn #True
EndProcedure

; Parcours de tous les répertoires (récursif)
Procedure Scan_Directory(source.s, typeScan.l = 1, rek = 0) ; Source, indice 
  
  ; Ajoute les "\" 
  If Right(source, 1) <> "\" : source + "\" : EndIf
  
  If IsDirectoryAuthorized(source) = #False
    ProcedureReturn
  EndIf
  
  If ExamineDirectory(rek, source, "*")
    While NextDirectoryEntry(rek) 
      ; Nom & Type répertoire source
      s_name.s = DirectoryEntryName(rek) : s_type = DirectoryEntryType(rek) 
      
      Select s_type          
        
        Case #PB_DirectoryEntry_File 
          s_fullname.s = source + s_name
          
          If IsFileToScan(s_fullname)
            If typeScan = 1 ; Première passe
              
              ; On ajoute ce fichier à la liste des fichiers de l'application
              AddElement(Fichier()) : Fichier()\nom = s_fullname
              
              Scan_File_For_Function(s_fullname)

            
            ElseIf typeScan = 2 ; Seconde passe
              
              Scan_File_For_Count(s_fullname) ; Utilisation des fonctions
              Delay(1)
              Scan_File_For_Include(s_fullname) ; Utilisation des fichiers

              
            EndIf
          
          EndIf

          
        Case #PB_DirectoryEntry_Directory 
          If s_name <> "." And s_name <> ".." 
              
            If typeScan = 1 : SetGadgetText(#Text_5, "1. Scan " + source + s_name) : EndIf
            
            Scan_Directory(source + s_name, typeScan, rek + 1)

            
          EndIf      
      EndSelect 
    Wend 
    
    ;Libère la mémoire
    FinishDirectory(rek) 
    
  EndIf 
;
EndProcedure


; Parameters par défault sur l'interface
Procedure Init_Window0Default()
  
  ; Répertoire
  SetGadgetText(#String_0, RootDirectory)
  
  ; Extensions
  ext_list.s = ""
  ForEach UsedExtension()
    ext_list + UCase(UsedExtension()) + ","
  Next
  ext_list = Left(ext_list, Len(ext_list) - 1)
  
  SetGadgetText(#String_1, ext_list)
  
  ; Zone d'affichage des actions
  SetGadgetText(#Text_5, "")
  
  ; Barre de progression
  SetGadgetState(#ProgressBar_0, 0)
  
  ; Pourcentage
  SetGadgetText(#Text_6, "0 %")
  
  
  
  ; Mis à jour du navigateur dans l'onglet "paramètres"
  SetGadgetText(#ExplorerTree_0, RootDirectory)
  
  SetGadgetText(#ExplorerList_1, GetGadgetText(#ExplorerTree_0))
  
EndProcedure

; Met à jour la barre de progression & le pourcentage d'avancement
Procedure MajProgressBar()
  
  ; Pourcentage
  Global ProgressMaxValues.l
  Global ProgressCurrentValues.l
  
  If ProgressMaxValues = 0
    Avancement.f = 0 
  
  Else
    Avancement.f = ProgressCurrentValues / ProgressMaxValues * 100
  
  EndIf
  
  SetGadgetText(#Text_6, StrF(Avancement, 0) + " %")
  SetGadgetState(#ProgressBar_0, Avancement)
  
  
EndProcedure


Procedure MajNavigation(dir.s)
  If FileSize(dir) = -2
          
    ; S'il s'agit d'un répertoire qui existe, on met à jour la navigation
    SetGadgetText(#ExplorerTree_0, dir)
    
    SetGadgetText(#ExplorerList_1, GetGadgetText(#ExplorerTree_0))
  
  Else
    ;Debug "NON REPERTOIRE : " + dir 
    
  EndIf 
EndProcedure


Procedure ShowList(tri.l = 1, sens.l = 0, voirFonctionNonUtilisee.b = #True)
  
  ; Efface les liste précédentes
  ClearGadgetItemList(#ListIcon_0)
  ClearGadgetItemList(#ListIcon_1)
  
  
  ; Tri éventuel
  Select tri
    Case 1
      SortStructuredList(Fonction(), sens, OffsetOf(FCT\nom), #PB_Sort_String)
    
    Case 2
      SortStructuredList(Fonction(), sens, OffsetOf(FCT\source_file), #PB_Sort_String)
      
      
  EndSelect
  
  
  ; Affichage
  If voirFonctionNonUtilisee
  
    nb_fonctions_non_utilisees = 0
              
    ForEach Fonction()
      If Fonction()\nb <= 1
        
        txt.s = Fonction()\nom + Chr(10) + Str(Fonction()\nb - 1) + Chr(10) + Fonction()\source_file + " (Ligne : " + Str(Fonction()\line) + ", car : " + Str(Fonction()\index) + ")"
        
        AddGadgetItem(#ListIcon_0, -1, txt) 
        ;Debug Fonction()\nom + " [ " + Fonction()\source_file + " ] "
        ;Debug Fonction()\source_file + " (Ligne : " + Str(Fonction()\line) + ", car : " + Str(Fonction()\index) + ")"
        ;Debug " "
        
        nb_fonctions_non_utilisees + 1
      EndIf
    Next
  
  
    fichier_non_utilises = 0
    
    ForEach Fichier()
      If Fichier()\nb = 0
        
        txt.s = GetFilePart(Fichier()\nom) + Chr(10) + GetPathPart(Fichier()\nom)
        
        AddGadgetItem(#ListIcon_1, -1, txt) 
        ;Debug Fonction()\nom + " [ " + Fonction()\source_file + " ] "
        ;Debug Fonction()\source_file + " (Ligne : " + Str(Fonction()\line) + ", car : " + Str(Fonction()\index) + ")"
        ;Debug " "
        
        fichier_non_utilises + 1
      EndIf
    Next
    
    
    SetGadgetText(#Text_5, Str(nb_fonctions_non_utilisees) + " fonctions non utilisées." + Str(fichier_non_utilises) + " fichiers non utilisés.")
  
  
  Else ; Voir toutes les fonctions
  
    nb_fonctions_total = 0
              
    ForEach Fonction()
        
      txt.s = Fonction()\nom + Chr(10) + Str(Fonction()\nb - 1) + Chr(10) + Fonction()\source_file + " (Ligne : " + Str(Fonction()\line) + ", car : " + Str(Fonction()\index) + ")"
      
      AddGadgetItem(#ListIcon_0, -1, txt) 
      ;Debug Fonction()\nom + " [ " + Fonction()\source_file + " ] "
      ;Debug Fonction()\source_file + " (Ligne : " + Str(Fonction()\line) + ", car : " + Str(Fonction()\index) + ")"
      ;Debug " "
      
      nb_fonctions_total + 1

    Next
  
  
    fichier_total = 0
    
    ForEach Fichier()
        
      txt.s = GetFilePart(Fichier()\nom) + Chr(10) + GetPathPart(Fichier()\nom)
      
      AddGadgetItem(#ListIcon_1, -1, txt) 
      
      fichier_total + 1

    Next
    
    
    SetGadgetText(#Text_5, Str(nb_fonctions_total) + " fonctions." + Str(fichier_total) + " fichiers.")
  
  
  EndIf
  
EndProcedure


Procedure ShowStatistiques()
  
  ClearGadgetItemList(#ListIcon_3)
  
  ; Nombre de fonction
  AddGadgetItem(#ListIcon_3, -1, "Nombre de fichiers" + Chr(10) + Str(CountList(Fichier())))
  AddGadgetItem(#ListIcon_3, -1, "Nombre de fonctions" + Chr(10) + Str(CountList(Fonction())))
  
  For y = 0 To 100
    
    If Statistiques(y)\nom = "" : Break : EndIf

    ; Affiche les stats
    If Statistiques(y)\type = 1 ; Type taille
      txt.s = Statistiques(y)\nom + Chr(10) + getComputedSize(Statistiques(y)\valeur)
      
    Else
      txt.s = Statistiques(y)\nom + Chr(10) + Str(Statistiques(y)\valeur) + " " + Statistiques(y)\unite
      
    EndIf
    
    ; Ajout au gadget
    AddGadgetItem(#ListIcon_3, -1, txt)
    
  Next
  
EndProcedure


; -------------------------------------------------------------------------------------------
;- Début du programme
; -------------------------------------------------------------------------------------------


; Ouverture de l'interface
Open_Window_0()

Init_Window0Default()

; Initialise le tri
;
; _____________________________________________
; /!\ Nécéssite PureLVSORT pour fonctionner /!\
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
;
;PureLVSORT_SelectGadgetToSort(#ListIcon_0, #PureLVSORT_ShowClickedHeader_IconRight)
;PureLVSORT_SelectGadgetToSort(#ListIcon_1, #PureLVSORT_ShowClickedHeader_IconRight)


; Boucle des évènements
Quit = #False

Repeat
  EventId.l = WaitWindowEvent()
  
  Select EventId
    
    Case #PB_Event_SizeWindow
      
      ResizeGadget(#Panel_0, #PB_Ignore, #PB_Ignore, WindowWidth(#Window_0) - 10, WindowHeight(#Window_0) - 180) 
      ResizeGadget(#ListIcon_0, #PB_Ignore, #PB_Ignore, WindowWidth(#Window_0) - 22, WindowHeight(#Window_0) - 218)
      ResizeGadget(#ListIcon_1, #PB_Ignore, #PB_Ignore, WindowWidth(#Window_0) - 22, WindowHeight(#Window_0) - 218)
      ResizeGadget(#ListIcon_3, #PB_Ignore, #PB_Ignore, WindowWidth(#Window_0) - 22, WindowHeight(#Window_0) - 218)
      ResizeGadget(#Button_14, WindowWidth(#Window_0) - WindowWidth(#Window_0) * 0.85, WindowHeight(#Window_0) - 28, #PB_Ignore, #PB_Ignore)
      ResizeGadget(#Button_12, WindowWidth(#Window_0) - WindowWidth(#Window_0) * 0.45, WindowHeight(#Window_0) - 28, #PB_Ignore, #PB_Ignore)
      ResizeGadget(#CheckBox_0, #PB_Ignore, WindowHeight(#Window_0) - 48, #PB_Ignore, #PB_Ignore)
    
    Case #PB_Event_CloseWindow
      Quit = #True
    
      
    Case #PB_Event_Gadget
    
      Select EventGadget()
        
        
        ;- Checkbox
        Case #Checkbox_0
          
          If GetGadgetState(#Checkbox_0) = 1
            ShowList(1, 0, #False)
          
          Else
            ShowList()
          
          EndIf
        
        ;- - Navigation
        ; Modification du navigateur en fonction de la saisie "repertoire projet"
        Case #String_0
          
          temp_dir.s = GetGadgetText(#String_0)
          
          MajNavigation(temp_dir)
        
        
        Case #ExplorerTree_0
        
          SetGadgetText(#ExplorerList_1, GetGadgetText(#ExplorerTree_0))
        
        
        
        ; Sélection d'un répertoire projet
        Case #Button_0
          
          dir.s = PathRequester("Répertoire projet", GetGadgetText(#String_0))
          
          If dir 
            
            ; Met à jour l'interface et la varibale système
            RootDirectory = dir
            SetGadgetText(#String_0, RootDirectory)
            
            MajNavigation(dir)
            
          EndIf
        
        ;- - Scan du projet
        ; Scan du projet
        Case #Button_1
          
          repertoire.s = Trim(GetGadgetText(#String_0))
          extensions.s = Trim(GetGadgetText(#String_1))
          
          If repertoire And extensions
            
            ; Charge les extensions
            ClearList(UsedExtension())
            
            For x = 1 To CountString(extensions, ",") + 1
              AddElement(UsedExtension()) : UsedExtension() = LCase(StringField(extensions, x, ","))
            Next
            
            ; Charge les répertoires à exclure
            ClearList(ExcludeDirectory())
            
            For x = 0 To CountGadgetItems(#Listview_0) - 1
              AddElement(ExcludeDirectory()) : ExcludeDirectory() = GetGadgetItemText(#Listview_0, x)
            Next
            
            
            ; Scan en cours
            SetGadgetText(#Text_5, "1. Scan des répertoires à la recherche des fonctions")
            
            ClearList(Fichier())
            Scan_Directory(repertoire)
            
            SetGadgetText(#Text_5, "2. Scan des répertoires terminés !")
            
            
            Delay(500)
            
            ; Scan des repertoires pour compter les fonctions
            
            
            SetGadgetText(#Text_5, "3. Recherche en cours... [" + Str(CountList(Fonction())) + " fonctions]")
            
            ProgressMaxValues = FileToScanned
            
            Scan_Directory(repertoire, 2)
            
            SetGadgetText(#Text_5, "4. Recherche terminé !")
            
            
            Delay(500)
            
            
            SetGadgetText(#Text_5, "5. Exploitation des résultats...")
            
            ; AFFICHAGE
            ShowList()
            
            ShowStatistiques()
            
          Else
            MessageRequester("Paramètes manquants", "Il manque des paramètres pour lançer le scan du projet.", #MB_ICONINFORMATION)
          
          EndIf
          
        ;- - RAZ
        ; Remise à zéro du scanner
        Case #Button_3
          
        
        ;- - Exports 
        Case #Button_5 ; Export des fonctions inutilisés
          
          
          file.s = SaveFileRequester("Choisir un fichier cible pour l'export", "export.txt", "Fichier Texte (*.txt)|*.txt|Tous les fichiers (*)|*", 1)
          If file
            
            If CreateFile(0, file)
              
              
              If GetGadgetState(#Panel_0) = 0 ; Export des fonctions
              
                For x = 0 To CountGadgetItems(#ListIcon_0) - 1
                  
                  txt.s = LSet(GetGadgetItemText(#ListIcon_0, x, 0), 80, " ") + GetGadgetItemText(#ListIcon_0, x, 2)
                  WriteStringN(0, txt)
                  
                Next
                
              ElseIf GetGadgetState(#Panel_0) = 1 ; Export des fichiers
                
                For x = 0 To CountGadgetItems(#ListIcon_1) - 1
                  
                  txt.s = GetGadgetItemText(#ListIcon_1, x, 0)
                  WriteStringN(0, txt)
                  
                Next
              
                
              EndIf
              
              
              CloseFile(0)
            Else
              MessageRequester("Erreur", "Impossible de créer le fichier.", #MB_ICONERROR)
            
            EndIf
          EndIf
      
      
        ;- - Add répertoire exclu
        Case #Button_9 ; Ajouter un repertoire à exclure
        
          dir.s = GetGadgetText(#ExplorerList_1)
          
          ; Vérifie que le répertoire n'est pas déjà inséré
          bool.b = #True
          For x = 0 To CountGadgetItems(#Listview_0) - 1
            If FindString(dir, GetGadgetItemText(#Listview_0, x), 1) > 0
              bool = #False
            EndIf
          Next
          
          If bool
            AddGadgetItem(#Listview_0, -1, dir)
          
          Else
            MessageRequester("Répertoire non ajouté", "Ce répertoire a déjà été ajouté ou est un sous dossier d'un dossier exclu.", #MB_ICONINFORMATION)
            
          EndIf
          
        ;- - Remove répertoire exclu
        Case #Button_10 ; Retirer repertoire à exclure
          
          Sel.l = GetGadgetState(#Listview_0)
          
          If Sel > -1
            RemoveGadgetItem(#Listview_0, Sel)
            
          EndIf
          
        ;- - Enregistrer config
        Case #Button_12 ; Enregister config
        
          save_file.s = SaveFileRequester("Sélectionner un fichier pour la sauvegarde", "config.cfg", "Fichiers config(*.cfg)|*.cfg|Tous les fichiers(*.*)|*.*", 1)
          
          If save_file
            
            
            If CreateFile(0, save_file)
              
              ; Entête du fichier
              WriteStringN(0, "# Fichier de configuration")
              WriteStringN(0, "# Vous pouvez modifier ce fichier manuellement")
              WriteStringN(0, "")
              
              ; Sauvegarde du répertoire projet
              WriteStringN(0, "[RootPath]")
              WriteStringN(0, GetGadgetText(#String_0))
              WriteStringN(0, "")
              
              
              ; Sauvegarde des extensions à cibler
              WriteStringN(0, "[Extensions]")
              
              extensions.s = Trim(GetGadgetText(#String_1))
              
              For x = 1 To CountString(extensions, ",") + 1
                WriteStringN(0, StringField(extensions, x, ","))
              Next

              WriteStringN(0, "")
              
              
              ; Sauvegarde des fichiers à exclure
              WriteStringN(0, "[ExcludedDirectory]")
            
              For x = 0 To CountGadgetItems(#Listview_0) - 1
                
                WriteStringN(0, GetGadgetItemText(#Listview_0, x))

              Next

              WriteStringN(0, "")
              
              ; Footer
              WriteStringN(0, "[End]")
              WriteStringN(0, "# Fin du fichier de config")
              
              CloseFile(0)
            Else
            
              MessageRequester("Erreur", "Impossible de créer le fichier : " + save_file, #MB_ICONERROR)
            EndIf
            
            
          EndIf
        
        
        ;- - Charger config
        Case #Button_14 ; Charger config
          
          read_file.s = OpenFileRequester("Sélectionner un fichier pour le chargement", "config.cfg", "Fichiers config(*.cfg)|*.cfg|Tous les fichiers(*.*)|*.*", 1)
          
          If read_file
          
            
            If ReadFile(0, read_file)
              
              STATE.s = "NONE"   
              
              ClearList(UsedExtension())
              ClearList(ExcludeDirectory())
              
              
              While ~Eof(0)
              
                line.s = Trim(ReadString(0))
                
                ; Ignore les lignes vides et les commentaires
                If line = "" Or Left(line, 1) = "#"
                  Continue
                  
                EndIf
                
                ; Change l'état du chargeur
                Select line
                  Case "[RootPath]"
                    STATE = "PATH" : StateChanged = #True
                    
                  Case "[Extensions]"
                    STATE = "EXTS" : StateChanged = #True
                    
                  Case "[ExcludedDirectory]" : StateChanged = #True
                    STATE = "EDIR" : StateChanged = #True
                    
                  Case "[End]"
                    Break ; Sort de la lecture 
                  
                  Default
                     StateChanged = #False               
                  
                EndSelect
                
                
                ; L'état à été modifié, on passe à la ligne suivante
                If StateChanged = #True : Continue : EndIf
                
               
                ; Met à jour les données
                Select STATE
                  Case "PATH" ; Modification du répertoire principal
                    RootDirectory = line
                    
                  
                  Case "EXTS"
                    AddElement(UsedExtension()) : UsedExtension() = line
                  
                  
                  Case "EDIR"
                    AddElement(ExcludeDirectory()) : ExcludeDirectory() = line
                  
                EndSelect
                
              Wend
              
              
              ; Met à jour l'affichage
              SetGadgetText(#String_0, RootDirectory)
              
              MajNavigation(RootDirectory)
              
              ; Extensions
              ext_list.s = ""
              ForEach UsedExtension()
                ext_list + UCase(UsedExtension()) + ","
              Next
              ext_list = Left(ext_list, Len(ext_list) - 1)
              
              SetGadgetText(#String_1, ext_list)
              
              ; Exclude Directory
              ForEach ExcludeDirectory()
                AddGadgetItem(#Listview_0, -1, ExcludeDirectory())
              Next 
              
              ; Zone d'affichage des actions
              SetGadgetText(#Text_5, "")
              
              ; Barre de progression
              SetGadgetState(#ProgressBar_0, 0)
              
              ; Pourcentage
              SetGadgetText(#Text_6, "0 %")
              
              CloseFile(0)
              
            Else
              MessageRequester("Erreur", "Impossible de lire le fichier : " + read_file, #MB_ICONERROR)
              
            EndIf   
                      
          
          EndIf
        
       
       
      EndSelect
      
  EndSelect
  
Until Quit = #True

; -------------------------------------------------------------------------------------------
;- Fin du programme
; -------------------------------------------------------------------------------------------
Fichier FonctionsInutiliseesInterface.pb

Code : Tout sélectionner

; PureBasic Visual Designer v3.95 build 1485 (PB4Code)


;- Window Constants
;
Enumeration
  #Window_0
EndEnumeration

;- Gadget Constants
;
Enumeration
  #String_0
  #Button_0
  #Text_1
  #String_1
  #ProgressBar_0
  #Button_1
  #Button_3
  #Text_5
  #ListIcon_0
  #Text_6
  #Panel_0
  #ListIcon_1
  #Button_5
  #ExplorerTree_0
  #ExplorerList_1
  #Text_7
  #Text_9
  #Button_9
  #Frame3D_1
  #Listview_0
  #Button_10
  #Button_12
  #Button_14
  #CheckBox_0
  #ListIcon_3
EndEnumeration


Procedure Open_Window_0()
  If OpenWindow(#Window_0, 336, 168, 600, 676, "Recherche des fichiers/fonctions non utilisés d'un projet",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#Window_0))
      StringGadget(#String_0, 105, 15, 410, 20, "")
      ButtonGadget(#Button_0, 525, 15, 65, 20, "...")
      TextGadget(#Text_1, 15, 15, 85, 20, "Répertoire projet")
      ProgressBarGadget(#ProgressBar_0, 10, 75, 575, 15, 0, 100)
      ButtonGadget(#Button_1, 50, 45, 85, 20, "Scan !")
      ButtonGadget(#Button_3, 160, 45, 85, 20, "R.A.Z")
      TextGadget(#Text_5, 10, 95, 530, 20, "Affichage des actions")
      TextGadget(#Text_6, 545, 95, 40, 20, "", #PB_Text_Right)
      ButtonGadget(#Button_5, 500, 45, 85, 20, "Export...")
      ButtonGadget(#Button_12, 315, 650, 155, 20, "Enregistrer une config...")
      ButtonGadget(#Button_14, 130, 650, 155, 20, "Charger une config...")
      CheckBoxGadget(#CheckBox_0, 5, 625, 585, 15, "Voir tous les fichiers && toutes les fonctions")
      
      ;- Panel1
      PanelGadget(#Panel_0, 5, 125, 590, 495)
      AddGadgetItem(#Panel_0, -1, "Fonctions")
      
      ;-
      ListIconGadget(#ListIcon_0, 3, 8, 575, 455, "Fonctions", 200, #PB_ListIcon_FullRowSelect)
      AddGadgetColumn(#ListIcon_0, 1, "Nb utilisation", 80)
      AddGadgetColumn(#ListIcon_0, 2, "Fichier source (ligne, colonne)", 280)
      AddGadgetItem(#Panel_0, -1, "Fichiers")
      
      ;-
      ListIconGadget(#ListIcon_1, 3, 8, 575, 455, "Nom", 160, #PB_ListIcon_FullRowSelect)
      AddGadgetColumn(#ListIcon_1, 1, "Répertoire", 380)
      AddGadgetItem(#Panel_0, -1, "Paramètres")
      StringGadget(#String_1, 248, 18, 325, 20, "")
      ExplorerTreeGadget(#ExplorerTree_0, 13, 68, 275, 195, "", #PB_Explorer_AlwaysShowSelection | #PB_Explorer_AutoSort | #PB_Explorer_NoFiles)
      ExplorerListGadget(#ExplorerList_1, 298, 68, 275, 195, "", #PB_Explorer_AlwaysShowSelection | #PB_Explorer_AutoSort | #PB_Explorer_MultiSelect | #PB_Explorer_NoDirectoryChange | #PB_Explorer_NoDriveRequester | #PB_Explorer_NoMyDocuments | #PB_Explorer_NoParentFolder)
      TextGadget(#Text_7, 13, 18, 215, 20, "Extensions ciblées (séparer par des virugles)")
      TextGadget(#Text_9, 13, 43, 215, 20, "Répertoires à exclure du scan")
      ButtonGadget(#Button_9, 483, 268, 90, 20, "Ajouter")
      Frame3DGadget(#Frame3D_1, 13, 293, 560, 170, "Répertoires exclus")
      ListViewGadget(#Listview_0, 23, 313, 540, 115)
      ButtonGadget(#Button_10, 473, 433, 90, 20, "Retirer")
      AddGadgetItem(#Panel_0, -1, "Statistiques")
      
      ;-
      ListIconGadget(#ListIcon_3, 3, 8, 575, 455, "Nom de la données", 280, #PB_ListIcon_FullRowSelect)
      AddGadgetColumn(#ListIcon_3, 1, "Valeur", 180)
      CloseGadgetList()
      
    EndIf
  EndIf
EndProcedure