langues et traduction

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

langues et traduction

Message par blendman »

salut

Sur la plupart de mes logiciels, j'utilise ce système pour changer facilement de langue.
ça fonctionne pas mal (mais je pense modifier la map pour utiliser 2 list()).
mise à jour 4.12.2021 (optimisation et amélioration)

Le code :

Code : Tout sélectionner

; by blendman 2021

; Create the list() for the langage file // on créé la list() pour le fichier de lang
Structure sLang
  Key$
  Value$
  type.a ; le type de ligne à ajouter dans le fichier préférence : 0 = clef, 1 = commentaire
EndStructure
Global NewList LangOk.sLang()

; je crée une map pour stocker le fichier pref d'origine
Global NewMap CopyLangOk$()

; ça c'est pour savoir quelle langue on a choisi (vous pouvez bien sûr utiliser une structure ou autre pour stocker vos options, c'est mieux)
Global OptionsLang$="fr", LangExt$=".ini"

Procedure LoadLang()
  ; je charge la langue, pour conserver tous les mots-clefs et commentaire de mon programme.
  If OpenFile(0,OptionsLang$+LangExt$)
    s_$ = " = " ; attention, j'utilise les + avec espace lorsque je crée le fichier pref, donc je dois aussi les utiliser icic
    
    While Eof(0)=0
      line$ = ReadString(0)
      If line$ <> ""
        If FindString(line$,s_$)=0
          ; comment
          AddMapElement(CopyLangOk$(), line$)
          CopyLangOk$() = line$
        Else
          ; clef et valeur
          key$ = StringField(line$,1,s_$)
          value$ = StringField(line$,2,s_$)
          AddMapElement(CopyLangOk$(), key$)
          CopyLangOk$() = value$
        EndIf
      EndIf
    Wend
    CloseFile(0)
  EndIf 
EndProcedure

Procedure SaveLang()
  
  ; pour enregistrer le mot ou la phrase dans le dossier de langue
  file$ = OptionsLang$+LangExt$
  If CreatePreferences(file$)
    ForEach LangOk()
      If LangOk()\type = 0
        WritePreferenceString(LangOk()\Key$, LangOk()\Value$)
      Else
        PreferenceComment(LangOk()\Value$)
      EndIf
    Next
    ClosePreferences()
  EndIf
  
  ; puis, j'enregistre le reste de la map CopyLangOk$()
  If OpenFile(0,file$,#PB_File_Append)
    ForEach CopyLangOk$()
      key$ = MapKey(CopyLangOk$())
      value$ = CopyLangOk$()
      If key$ <> ""
        If key$ <> value$
          ; c'est une clef
          txt$ = key$+ " = "+value$
        Else
          ; commentaire
          txt$ = value$
        EndIf
        WriteStringN(0, txt$)
      EndIf
    Next
    CloseFile(0)
  EndIf
  
EndProcedure

Procedure AddLangComment(comment$)
  If comment$<>""
    AddElement(LangOk())
    LangOk()\type = 1
    LangOk()\Value$ = comment$
    LangOk()\Key$ = comment$
    
    ; je vérifie dans la map si on a le commentaire, et je le supprime si je le trouve (pour ne pas le réécrire 2 fois si je fais savelang())
    If FindMapElement(CopyLangOk$(), "; "+comment$)
      ; Debug "on a trouvé le comment on va le supprimer : "+comment$
      DeleteMapElement(CopyLangOk$(), "; "+comment$)
    EndIf
  EndIf
EndProcedure

Procedure.s Lang(keyword$, comment$="")
  
  Protected word$
  ; TO define the word by default, if the ini file does'nt have it 
  ; pour définir le mot par défaut, si le fichier ini de langue ne le contient pas.
  
  AddLangComment(comment$)
  
  ; d'abord, on va vérifier s'il n'y a pas des charactère interdits :
  While Mid(keyword$, Len(keyword$)) = Chr(32) Or Mid(keyword$, Len(keyword$)) = "="
    keyword$ = Left(keyword$, Len(keyword$)-1)
  Wend
  
  ; on vérifie si on le mot dans notre fichier
  file$ = OptionsLang$+LangExt$
  ; puis, on vérifie si on a déjà le mot dans notre fichier
  If OpenPreferences(file$)
    word$ = ReadPreferenceString(keyword$,"")
    ClosePreferences()
    ; To change char # by chr(13)
    If word$ <> #Empty$
      ; then read the word$ with the keyword$ ok
      word$ = ReplaceString(word$,"#",Chr(13))
    EndIf
  EndIf
  
  ; puis, on ajoute le mot à notre liste
  ForEach LangOk()
    If LangOk()\Key$ = keyword$
      LangOk()\Value$ = word$
      find = 1
      Break
    EndIf
  Next
  
  ; on ne l'a pas trouvé, on l'ajoute
  If find=0
    AddElement(LangOk())
    LangOk()\key$ = keyword$
    LangOk()\Value$ = word$
  EndIf
  
  ; je vérifie dans la map si on a le commentaire, et je le supprime si je le trouve (pour ne pas le réécrire 2 fois si je fais savelang())
  If FindMapElement(CopyLangOk$(), keyword$)
    DeleteMapElement(CopyLangOk$(), keyword$)
  EndIf
  
  
  If word$ <> ""
    ProcedureReturn word$
  EndIf
  
  ProcedureReturn keyword$
EndProcedure


;{ programme exemple : 

LoadLang()
AddLangComment("Language File for the application")

If OpenWindow(0,0,0, 600, 400, lang("Application"),#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  
  AddLangComment("Main menu")
  CreateMenu(0,WindowID(0))
  MenuTitle(lang("File"))
  MenuItem(0,lang("New"))
  MenuItem(1,lang("Open"))
  MenuItem(2,lang("Save"))
  MenuTitle(lang("Edit"))
   MenuItem(6,lang("Copy"))
   MenuItem(7,lang("Paste"))
  MenuTitle(lang("View"))
  MenuItem(3,lang("Menu view1"))
  MenuItem(4,lang("Menu view2"))
  MenuTitle(lang("Help"))
  MenuItem(5,lang("About"))
  
  AddLangComment("Main Gadgets")
  ButtonGadget(0,10,10,100,20,lang("Add object  "))
  ButtonGadget(1,10,30,100,20,lang("Del object"))
  
  
  Repeat
    event =  WaitWindowEvent(1)
    
    Select event
      Case #PB_Event_CloseWindow
        quit =1
      Case #PB_Event_Gadget
      Case #PB_Event_Menu
        Select EventMenu()
          Case 5
            AddLangComment("Menu help - about")
            MessageRequester(lang("info"),lang("This is an example of message about"))
        EndSelect
        
    EndSelect
    
  Until quit =1
  
  SaveLang()
  
EndIf
;}
Explication : le code doit faire les choses suivantes
- ajouter dans un fichier les mots-clef dans l'ordre dans lequel ils sont ajoutés dans notre programme. Cela permet de conserver les groupes de mots-clef (menu principal, toolbar, panel1, panel2, sous-menu1, etc...) et donc d'avoir un fichier de langue facile à modifier
- si on ajoute un menuitem ou un gadget plus tard, le mot est ajouté dans le fichier dans le groupe dans lequel on l'a mis dans notre code, et PAS à la fin du fichier texte
- possibilité d'ajouter des commentaires pour bien différencier chaque "groupe" de mot-clef (menu principale, toolbar, gadgets, menu fenêtre 2).
- on lit le fichier et on sauvegarde les lignes, pour pouvoir les enregistrer quand on ferme le programme, si on le souhaite.

et voilà :)
Dernière modification par blendman le sam. 04/déc./2021 11:35, modifié 5 fois.
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: langues et traduction

Message par Shadow »

Merci beaucoup pour le code, très utile.
Par contre, cela pourrais je pense être bien amélioré et optimisé, ce que j'essayerais de faire. (Perfectible comme tu le dis ^^)
Mais c'est pas mal déjà pour comprendre le fonctionnement :)
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: langues et traduction

Message par Shadow »

J'ai fais ça, ça fonctionne, c'est pas ouf je sais mais ça fonctionne ^^

Code : Tout sélectionner

; Créer les Langages pour un logiciel de type GUI.
; Créer par Mr Dieppedalle David le: 01/12/2021.

Global NewMap MyLanguage.s()
Global Language$ = "Fr"

Procedure.s AddLanguage(Texte$)
  
  ; Le String a t-il été trouvé ?
  If Not FindMapElement(MyLanguage.s(), Texte$) ; Non
    
    ; Ajoute le String à la Map.
    AddMapElement(MyLanguage.s(), Texte$)
    MyLanguage.s() = ""
    
  Else ; Oui
    
    ; Y a t-il une valeur ?
    If MyLanguage.s(Texte$) <> "" ; Si oui, récupère la valeur, sinon ne fait rien.
      Texte$ = MyLanguage.s(Texte$)
    EndIf
    
  EndIf
  
  ProcedureReturn Texte$
  
EndProcedure

; Charge le fichier de langue.
Procedure.b LoadLanguage(Language$)
  
  If OpenPreferences(Language$ + ".Lang")
    
    ExaminePreferenceKeys()
    
    While NextPreferenceKey() 
      
      AddMapElement(MyLanguage.s(), PreferenceKeyName())
      MyLanguage.s() = PreferenceKeyValue()
      
    Wend
    
    ClosePreferences()
    ProcedureReturn  1
    
  Else
    MessageRequester("Avertissement..., ", "   Le fichier de Langue " + Chr(34) + Language$ + ".Lang" + Chr(34) + Chr(13) + Chr(10) +
                                           "   n'as pas été trouvé !", 48)
    
    ProcedureReturn 0
    
  EndIf
  
EndProcedure

Procedure.b SaveLanguage(Language$)
  
  If CreatePreferences(Language$ + ".Lang")
    
    ForEach MyLanguage.s()
      WritePreferenceString(MapKey(MyLanguage.s()), MyLanguage.s())
    Next
    
    ClosePreferences()
    
    MessageRequester("Information..., ", "   Le fichier de Langue " + Chr(34) + Language$ + ".Lang" + Chr(34) + Chr(13) + Chr(10) +
                                    "   a bien été créé !", 64)
    
    ProcedureReturn  1
    
  Else
    MessageRequester("Erreur..., ", "   Le fichier de Langue " + Chr(34) + Language$ + ".Lang" + Chr(34) + Chr(13) + Chr(10) +
                                    "   n'as pas peu être créé !", 16)
    
    ProcedureReturn 0
    
  EndIf
  
EndProcedure


; Exemple d'utilisation:

LoadLanguage("Fr")

Enumeration 1
  #Fenetre
EndEnumeration

Procedure Ma_Fenetre()
  If OpenWindow(#Fenetre, 327, 177, 500, 300, AddLanguage("Example of PureLanguage usage"),  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_TitleBar)
    
    CreateMenu(0,WindowID(#Fenetre))
    
    MenuTitle(AddLanguage("File"))
    MenuItem(0,AddLanguage("New"))
    MenuItem(1,AddLanguage("Open"))
    MenuItem(2,AddLanguage("Save"))
    MenuTitle(AddLanguage("View"))
    MenuItem(3,AddLanguage("Menu view1"))
    MenuItem(4,AddLanguage("Menu view2"))
    
    ButtonGadget(0, 10, 10, 175, 30, AddLanguage("My ButtonGadget n°1"))
    CheckBoxGadget(1, 10, 40, 175, 25, AddLanguage("My CheckBoxGadget n°1"))
    OptionGadget(2, 10, 60, 175, 25, AddLanguage("My OptionGadget n°1"))
    
    Repeat ; Départ des évènements de boucle
      
      Event = WaitWindowEvent(1) ; Cette ligne attend pendent (Minuteur) qu'un évènements soit recus par la fenêtre
      EventWindow = EventWindow() ; La fenêtre oû l'évènements c'est produit
      EventGadget = EventGadget() ; Pour savoir sur quel gadget c'est produis l'évènements
      EventMenu = EventMenu() ; Pour savoir sur quel menue c'est produis l'évènements
      EventType = EventType() ; Le type d'évènements qui c'est produis sur le gadget
      
      Select Event 

        Case #PB_Event_Gadget
          
          Select EventGadget
              
            Case 0
              
          EndSelect
          
        Case #PB_Event_Menu
          
          Select EventMenu
              
            Case 0
              
          EndSelect
          
        Case #PB_Event_CloseWindow  
          
      EndSelect
      
    Until Event = #PB_Event_CloseWindow ; Fin des évènements de boucle
    
  EndIf
EndProcedure

Ma_Fenetre()
SaveLanguage("Fr")

Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: langues et traduction

Message par Micoute »

C'est même très bien pour commencer.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre