Compare commits

...

3 Commits

Author SHA1 Message Date
a948550932 Add Tags Gadgets 2025-09-01 06:31:17 +02:00
7cc314e34c UpdateGadgetState() to Enable or Desable gadget from context 2025-08-30 20:33:25 +02:00
f4c8e58d55 !!!Renommage de %1 en %2 2025-08-30 17:01:17 +02:00
2 changed files with 490 additions and 92 deletions

582
main2.pb
View File

@@ -1,5 +1,10 @@
EnableExplicit
CompilerIf #PB_Compiler_Thread=0
MessageRequester("Compiler","You must to enable Create Threadsafe executable in Compiler Options",#PB_MessageRequester_Error|#PB_MessageRequester_Ok)
End
CompilerEndIf
; =============================================================================
;-MODULE TRANSLATE
; =============================================================================
@@ -11,7 +16,7 @@ EndDeclareModule
Module Translate
; ===============================================
; Système Multilingue Minimaliste pour PureBasic
; Système Multilingue
; ===============================================
Global NewMap Translations.s()
@@ -456,6 +461,34 @@ Enumeration GadgetsIDs
#GID_CbScope
#GID_BtnSaveCfg
; === TAB 5: TAGS ===
#GID_Tab_Tags
#GID_FrmTagsList
#GID_ListTags
#GID_BtnCreateTag
#GID_BtnDeleteTag
#GID_BtnPushTag
#GID_BtnFetchTags
#GID_BtnCheckoutTag
; Frame création de tag
#GID_FrmCreateTag
#GID_LblTagName
#GID_EdTagName
#GID_LblTagType
#GID_OptTagLight
#GID_OptTagAnnotated
#GID_LblTagMessage
#GID_EdTagMessage
#GID_LblTagTarget
#GID_CbTagTarget
#GID_BtnApplyTag
#GID_BtnCancelTag
; Détails du tag
#GID_FrmTagDetails
#GID_TxtTagDetails
; --- App settings (langue) ---
#GID_FrmApp
#GID_LblAppLang
@@ -463,7 +496,7 @@ Enumeration GadgetsIDs
#GID_FrmProxy
#GID_ChkProxy
; HTTP
#GID_LblHttpSrv
#GID_EdHttpSrv
@@ -483,7 +516,7 @@ Enumeration GadgetsIDs
#GID_EdHttpsUser
#GID_LblHttpsPass
#GID_EdHttpsPass
#GID_BtnApplyProxy
EndEnumeration
@@ -491,6 +524,38 @@ EndEnumeration
; -----------------------------------------------------------------------------
; SMALL HELPERS / AIDES UTILITAIRES
; -----------------------------------------------------------------------------
; Compte le nombre ditems cochés (#PB_ListIcon_Checked) dans un ListIcon
Procedure.i _ListCountChecked(gadget.i)
Protected i, c
For i = 0 To CountGadgetItems(gadget) - 1
If GetGadgetItemState(gadget, i) & #PB_ListIcon_Checked
c + 1
EndIf
Next
ProcedureReturn c
EndProcedure
; Compte le nombre ditems sélectionnés (#PB_ListIcon_Selected) dans un ListIcon
Procedure.i _ListCountSelected(gadget.i)
Protected i, c
For i = 0 To CountGadgetItems(gadget) - 1
If GetGadgetItemState(gadget, i) & #PB_ListIcon_Selected
c + 1
EndIf
Next
ProcedureReturn c
EndProcedure
; Petit helper pour activer/désactiver sans se tromper
Procedure _SetEnabled(gadget.i, enabled.i)
If enabled
DisableGadget(gadget, 0)
Else
DisableGadget(gadget, 1)
EndIf
EndProcedure
Macro RightOf(g) : GadgetX(g) + GadgetWidth(g) : EndMacro
Macro BottomOf(g) : GadgetY(g) + GadgetHeight(g) : EndMacro
@@ -588,6 +653,42 @@ Procedure ResizeGUI()
ResizeGadget(#GID_BtnSaveGitIgnore, #UI_Inset, #UI_Inset + gitEdH + #UI_Inset, 100, #UI_RowH)
; Onglet 4 : statique (inchangé)
; === Onglet 5 : Tags ===
Protected tagsListH = (panelH - #UI_Inset*4) / 2
Protected tagsListInnerH = tagsListH - #UI_FrameHeaderH - #UI_RowH - #UI_Inset*2
If tagsListInnerH < 100 : tagsListInnerH = 100 : EndIf
ResizeGadget(#GID_FrmTagsList, #UI_Inset, #UI_Inset, panelW - #UI_Inset*2, tagsListH)
ResizeGadget(#GID_ListTags, #UI_Inset, #UI_FrameHeaderH,
GadgetWidth(#GID_FrmTagsList) - #UI_Inset*2, tagsListInnerH)
Protected yTagsButtons = GadgetHeight(#GID_FrmTagsList) - #UI_RowH - #UI_Inset
ResizeGadget(#GID_BtnCheckoutTag, #UI_Inset, yTagsButtons, 110, #UI_RowH)
ResizeGadget(#GID_BtnDeleteTag, RightOf(#GID_BtnCheckoutTag) + #UI_Inset, yTagsButtons, 110, #UI_RowH)
ResizeGadget(#GID_BtnPushTag, RightOf(#GID_BtnDeleteTag) + #UI_Inset, yTagsButtons, 110, #UI_RowH)
ResizeGadget(#GID_BtnFetchTags, RightOf(#GID_BtnPushTag) + #UI_Inset, yTagsButtons, 110, #UI_RowH)
Protected yCreateTag = BottomOf(#GID_FrmTagsList) + #UI_Inset
Protected createTagW = (panelW - #UI_Inset*3) / 2
Protected createTagH = panelH - yCreateTag - #UI_Inset
ResizeGadget(#GID_FrmCreateTag, #UI_Inset, yCreateTag, createTagW, createTagH)
ResizeGadget(#GID_EdTagName, RightOf(#GID_LblTagName) + #UI_Inset,
GadgetY(#GID_EdTagName), createTagW - 120 - #UI_Inset*3, #UI_RowH)
ResizeGadget(#GID_CbTagTarget, RightOf(#GID_LblTagTarget) + #UI_Inset,
GadgetY(#GID_CbTagTarget), createTagW - 120 - #UI_Inset*3, #UI_RowH)
ResizeGadget(#GID_EdTagMessage, #UI_Inset, GadgetY(#GID_EdTagMessage),
createTagW - #UI_Inset*2, 80)
Protected xDetails = RightOf(#GID_FrmCreateTag) + #UI_Inset
ResizeGadget(#GID_FrmTagDetails, xDetails, yCreateTag,
panelW - xDetails - #UI_Inset, createTagH)
ResizeGadget(#GID_TxtTagDetails, xDetails + #UI_Inset,
yCreateTag + #UI_FrameHeaderH,
GadgetWidth(#GID_FrmTagDetails) - #UI_Inset*2,
GadgetHeight(#GID_FrmTagDetails) - #UI_FrameHeaderH - #UI_Inset)
EndProcedure
@@ -605,15 +706,15 @@ Procedure ApplyToolTips()
; --- Remote / Branch ---
GadgetToolTip(#GID_EdRemote, T("tip.remote", "URL du remote (ex.: https://... ou git@host:org/repo.git)"))
; Local branches
GadgetToolTip(#GID_CbLocalBranch, T("tip.branch.local.select", "Choisir la branche locale active"))
GadgetToolTip(#GID_BtnNewLocalBranch,T("tip.branch.local.new", "Créer une nouvelle branche locale"))
; Remote branches
GadgetToolTip(#GID_CbRemoteBranch, T("tip.branch.remote.select", "Choisir une branche distante (remote-tracking)"))
GadgetToolTip(#GID_BtnNewRemoteBranch,T("tip.branch.remote.new", "Créer une branche sur le dépôt distant / publier"))
; --- Remote / Branch ---
GadgetToolTip(#GID_EdRemote, T("tip.remote", "URL du remote (ex.: https://... ou git@host:org/repo.git)"))
@@ -646,9 +747,9 @@ Procedure ApplyToolTips()
GadgetToolTip(#GID_CbScope, T("tip.cfg.scope", "Portée de la configuration (Local/Global/System)"))
GadgetToolTip(#GID_BtnSaveCfg, T("tip.cfg.save", "Enregistrer la configuration Git"))
; --- Langue ---
; --- Langue ---
GadgetToolTip(#GID_CbAppLang, T("tip.app.lang", "Langue de lapplication"))
; --- Proxy ---
GadgetToolTip(#GID_ChkProxy, T("tip.proxy.enable", "Activer/désactiver la configuration proxy"))
GadgetToolTip(#GID_EdHttpSrv, T("tip.proxy.http.server", "Serveur HTTP proxy"))
@@ -660,18 +761,110 @@ Procedure ApplyToolTips()
GadgetToolTip(#GID_EdHttpsUser, T("tip.proxy.https.user", "Login HTTPS proxy"))
GadgetToolTip(#GID_EdHttpsPass, T("tip.proxy.https.pass", "Mot de passe HTTPS proxy"))
GadgetToolTip(#GID_BtnApplyProxy,T("tip.proxy.apply", "Appliquer la configuration proxy dans Git"))
; --- Tags ---
GadgetToolTip(#GID_ListTags, T("tip.tags.list", "Liste des tags du dépôt"))
GadgetToolTip(#GID_BtnCreateTag, T("tip.tags.create", "Créer un nouveau tag"))
GadgetToolTip(#GID_BtnDeleteTag, T("tip.tags.delete", "Supprimer le tag sélectionné"))
GadgetToolTip(#GID_BtnPushTag, T("tip.tags.push", "Envoyer le tag vers le dépôt distant"))
GadgetToolTip(#GID_BtnFetchTags, T("tip.tags.fetch", "Récupérer les tags du dépôt distant"))
GadgetToolTip(#GID_BtnCheckoutTag, T("tip.tags.checkout", "Basculer vers le tag sélectionné"))
GadgetToolTip(#GID_EdTagName, T("tip.tags.name", "Nom du tag (ex: v1.0.0)"))
GadgetToolTip(#GID_OptTagLight, T("tip.tags.light", "Tag léger (référence simple)"))
GadgetToolTip(#GID_OptTagAnnotated,T("tip.tags.annotated", "Tag annoté (avec message et signature)"))
GadgetToolTip(#GID_CbTagTarget, T("tip.tags.target", "Commit ou branche à taguer"))
GadgetToolTip(#GID_EdTagMessage, T("tip.tags.message", "Message descriptif du tag annoté"))
; --- Help (optionnel) ---
GadgetToolTip(#GID_HelpWeb, T("tip.help.web", "Zone daide (documentation / rendu HTML)"))
EndProcedure
Procedure UpdateGadgetsState()
; --- État courant ---
Protected repo.b = main\IsRepository
Protected remoteURL$ = SupTrim(GetGadgetText(#GID_EdRemote))
Protected hasRemoteText.b = Bool(remoteURL$ <> "")
Protected hasRemoteCfg.b = Bool(repo And main\hasRemoteUrl) ; remote *réellement* configuré dans le dépôt
Protected locBr$ = SupTrim(GetGadgetText(#GID_CbLocalBranch))
Protected remBr$ = SupTrim(GetGadgetText(#GID_CbRemoteBranch))
Protected hasLocBr.b = Bool(locBr$ <> "")
Protected hasRemBr.b = Bool(remBr$ <> "")
Protected msg$ = SupTrim(GetGadgetText(#GID_EdMessage))
Protected hasMsg.b = Bool(msg$ <> "")
Protected checked.l = _ListCountChecked(#GID_ListStatus) ; pour Commit
Protected selected.l = _ListCountSelected(#GID_ListStatus) ; pour Restore/Rename/Delete/Ignore
Protected histSel.b = Bool(GetGadgetState(#GID_ListHistory) >= 0)
; --- Règles métier ---
Protected canInit.b = Bool(Not repo)
Protected canClone.b = Bool(Not repo And hasRemoteText) ; clone quand pas de repo et URL saisie
Protected canRefresh.b = repo
Protected canCommit.b = Bool(repo And hasMsg And (checked > 0))
Protected canFiles.b = Bool(repo And (selected > 0))
Protected canPull.b = Bool(repo And hasRemoteCfg And hasLocBr And hasRemBr)
Protected canPush.b = canPull ; même prérequis de base
Protected canVerifyRemote.b = Bool(repo And hasRemoteCfg)
; --- Toujours utiles ---
_SetEnabled(#GID_BtnBrowseRepo, #True)
_SetEnabled(#GID_EdRepo, #True)
; --- Local ---
_SetEnabled(#GID_BtnInit, canInit)
_SetEnabled(#GID_BtnRefresh, canRefresh)
_SetEnabled(#GID_CbLocalBranch, repo)
_SetEnabled(#GID_BtnNewLocalBranch, repo)
; --- Remote ---
_SetEnabled(#GID_EdRemote, #True) ; éditable tout le temps
_SetEnabled(#GID_CbRemoteBranch, hasRemoteCfg)
_SetEnabled(#GID_BtnNewRemoteBranch, hasRemoteCfg)
_SetEnabled(#GID_BtnClone, canClone)
_SetEnabled(#GID_BtnPull, canPull)
_SetEnabled(#GID_BtnPush, canPush)
_SetEnabled(#GID_BtnVerify, canVerifyRemote)
; --- Fichiers & commit ---
_SetEnabled(#GID_ListStatus, repo)
_SetEnabled(#GID_BtnRestore, canFiles)
_SetEnabled(#GID_BtnRename, canFiles)
_SetEnabled(#GID_BtnDelete, canFiles)
_SetEnabled(#GID_BtnIgnore, canFiles)
_SetEnabled(#GID_EdMessage, repo)
_SetEnabled(#GID_BtnCommit, canCommit)
; --- History ---
_SetEnabled(#GID_ListHistory, repo)
_SetEnabled(#GID_BtnRestoreCommit, Bool(repo And histSel))
_SetEnabled(#GID_TxtCommitInfo, repo)
; --- .gitignore ---
_SetEnabled(#GID_TxtGitIgnore, repo)
_SetEnabled(#GID_BtnSaveGitIgnore, repo)
; --- Config & Proxy : laissons-les actifs en permanence ---
EndProcedure
; -----------------------------------------------------------------------------
; BUILD GUI / CONSTRUCTION DE LINTERFACE
; -----------------------------------------------------------------------------
Enumeration
#Panel_Repo
#Panel_History
#Panel_GitIgnore
#Panel_Config
#Panel_Tags
EndEnumeration
Procedure OpenGUI()
UseModule Translate
Define repoDir$ = GetCurrentDirectory()
@@ -685,9 +878,9 @@ Procedure OpenGUI()
; ===========================================================================
; TAB 1: REPO / DÉPÔT
; ===========================================================================
AddGadgetItem(#GID_Panel, -1, T("Tab.Repo", "Dépôt"))
AddGadgetItem(#GID_Panel, #Panel_Repo, T("Tab.Repo", "Dépôt"))
; ---- Frame: Local repository ------------------------------------------------
; ---- Frame: Local repository ------------------------------------------------
FrameGadget(#GID_FrmLocal, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, #UI_FrameHeaderH + #UI_RowH*3 + #UI_Inset*3, T("Local.FrameTitle", "Dépôt local"), #PB_Frame_Container)
TextGadget(#GID_LblRepo, #UI_Inset, #UI_FrameHeaderH, 70, #UI_RowH, T("Local.Label.Repo","Dépôt :"))
@@ -696,7 +889,7 @@ Procedure OpenGUI()
ButtonGadget(#GID_BtnInit, #UI_Inset, BottomOf(#GID_BtnBrowseRepo) + #UI_Inset, #UI_BtnW, #UI_RowH, T("Local.Button.Init","Init Dépôt"))
ButtonGadget(#GID_BtnRefresh, RightOf(#GID_BtnInit) + #UI_Inset, GadgetY(#GID_BtnInit), #UI_BtnW, #UI_RowH, T("Local.Button.Refresh","Rafraîchir"))
; --- NEW: branche locale (sélecteur + bouton) ---
Define yLocalBranch = BottomOf(#GID_BtnRefresh) + #UI_Inset
TextGadget(#GID_LblLocalBranch, #UI_Inset, yLocalBranch, 120, #UI_RowH, T("Local.Label.Branch","Branche locale :"))
@@ -704,25 +897,25 @@ Procedure OpenGUI()
ButtonGadget(#GID_BtnNewLocalBranch, RightOf(#GID_CbLocalBranch) + #UI_Inset, yLocalBranch, 150, #UI_RowH, T("Local.Button.NewBranch","+ Nouvelle branche"))
CloseGadgetList()
; ---- Frame: Remote / Branche ------------------------------------------------
; ---- Frame: Remote / Branche ------------------------------------------------
Define yRemote = BottomOf(#GID_FrmLocal) + #UI_Inset
FrameGadget(#GID_FrmRemote, #UI_Inset, yRemote, GadgetWidth(#GID_Panel) - #UI_Inset*2, #UI_FrameHeaderH + #UI_RowH*5 + #UI_Inset*5, T("Remote.FrameTitle","Distant (remote / branche)"), #PB_Frame_Container)
; Ligne 1: URL du remote
TextGadget(#GID_LblRemote, #UI_Inset, #UI_FrameHeaderH, 70, #UI_RowH, T("Remote.Label.Remote","Remote :"))
StringGadget(#GID_EdRemote, RightOf(#GID_LblRemote) + #UI_Inset, #UI_FrameHeaderH, 420, #UI_RowH, "")
; Ligne 2: Branche distante (sélecteur + bouton)
Define yRemoteBranch = BottomOf(#GID_EdRemote) + #UI_Inset
TextGadget(#GID_LblRemoteBranch, #UI_Inset, yRemoteBranch, 130, #UI_RowH, T("Remote.Label.BranchRemote","Branche distante :"))
ComboBoxGadget(#GID_CbRemoteBranch, RightOf(#GID_LblRemoteBranch), yRemoteBranch, 220, #UI_RowH)
ButtonGadget(#GID_BtnNewRemoteBranch, RightOf(#GID_CbRemoteBranch) + #UI_Inset, yRemoteBranch, 160, #UI_RowH, T("Remote.Button.NewRemoteBranch","+ Nouvelle branche distante"))
; Ligne 3: Actions réseau
ButtonGadget(#GID_BtnClone, #UI_Inset, BottomOf(#GID_LblRemoteBranch) + #UI_Inset, #UI_BtnW, #UI_RowH, T("Remote.Button.Clone","Clone"))
ButtonGadget(#GID_BtnPull, RightOf(#GID_BtnClone) + #UI_Inset, GadgetY(#GID_BtnClone), #UI_BtnW, #UI_RowH, T("Remote.Button.Pull","Pull"))
ButtonGadget(#GID_BtnPush, RightOf(#GID_BtnPull) + #UI_Inset, GadgetY(#GID_BtnClone), #UI_BtnW, #UI_RowH, T("Remote.Button.Push","Push"))
; Ligne 4: Statut & dernière synchro
Define yStatus = BottomOf(#GID_BtnClone) + #UI_Inset
TextGadget(#GID_LblRemoteStatus, #UI_Inset, yStatus, 70, #UI_RowH, T("Remote.Status.Label","Status :"))
@@ -730,53 +923,52 @@ Procedure OpenGUI()
TextGadget(#GID_LblLastFetch, RightOf(#GID_TxtRemoteStatus) + 15, yStatus, 110, #UI_RowH, T("Remote.LastSync.Label","Dernière sync :"))
TextGadget(#GID_TxtLastFetch, RightOf(#GID_LblLastFetch), yStatus, 120, #UI_RowH, "-", #PB_Text_Border)
ButtonGadget(#GID_BtnVerify, RightOf(#GID_TxtLastFetch) + 10, yStatus - 2, 90, #UI_RowH, T("Remote.Button.Verify","Vérifier"))
; Ligne 5: Action en cours
TextGadget(#GID_LblAction, #UI_Inset, BottomOf(#GID_LblRemoteStatus) + #UI_Inset, 60, 20, T("Remote.Action.Label","Action :"))
TextGadget(#GID_TxtAction, RightOf(#GID_LblAction), GadgetY(#GID_LblAction), 300, 20, "-", #PB_Text_Border)
CloseGadgetList()
; ---- Frame: Files & changes -------------------------------------------------
Define yFiles = BottomOf(#GID_FrmRemote) + #UI_Inset
Define hFiles = panelH - yFiles - #UI_Inset
If hFiles < 260 : hFiles = 260 : EndIf ; hauteur mini du frame pour éviter valeurs négatives
FrameGadget(#GID_FrmFiles, #UI_Inset, yFiles, GadgetWidth(#GID_Panel) - #UI_Inset*2, hFiles, T("Files.FrameTitle","Fichiers & modifications"), #PB_Frame_Container)
; Hauteur de la liste avec garde-fou (même logique que dans ResizeGUI)
Define listH = hFiles - #UI_RowH*2 - #UI_Inset*4 - #UI_FrameHeaderH
If listH < 100 : listH = 100 : EndIf
ListIconGadget(#GID_ListStatus, #UI_Inset, #UI_FrameHeaderH, GadgetWidth(#GID_FrmFiles) - #UI_Inset*2, listH, T("Files.List.Path","Path"), 300, #PB_ListIcon_CheckBoxes | #PB_ListIcon_MultiSelect | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#GID_ListStatus, 1, T("Files.List.Status","Status"), 80)
AddGadgetColumn(#GID_ListStatus, 2, T("Files.List.Description","Description"), 300)
; Ligne boutons sous la liste
Define yLocalActions = #UI_FrameHeaderH + listH + #UI_Inset
ButtonGadget(#GID_BtnRestore, #UI_Inset + 10, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Restore","Restaurer"))
ButtonGadget(#GID_BtnRename, #UI_Inset + 130, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Rename","Renommer"))
ButtonGadget(#GID_BtnDelete, #UI_Inset + 250, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Delete","Supprimer"))
ButtonGadget(#GID_BtnIgnore, #UI_Inset + 370, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Ignore","Ignorer"))
; Message de commit
Define yMsg = yLocalActions + #UI_RowH + #UI_Inset
TextGadget(#GID_LblMessage, #UI_Inset + 10, yMsg + 4, 80, 22, T("Commit.Label.Message","Message :"))
StringGadget(#GID_EdMessage, #UI_Inset + 95, yMsg, GadgetWidth(#GID_FrmFiles) - #UI_Inset*2 - 95 - 110, #UI_RowH, "")
ButtonGadget(#GID_BtnCommit, GadgetWidth(#GID_FrmFiles) - #UI_Inset - 100, yMsg - 2, 100, #UI_RowH, T("Commit.Button.Commit","Commit"))
CloseGadgetList()
Define yFiles = BottomOf(#GID_FrmRemote) + #UI_Inset
Define hFiles = panelH - yFiles - #UI_Inset
If hFiles < 260 : hFiles = 260 : EndIf ; hauteur mini du frame pour éviter valeurs négatives
FrameGadget(#GID_FrmFiles, #UI_Inset, yFiles, GadgetWidth(#GID_Panel) - #UI_Inset*2, hFiles, T("Files.FrameTitle","Fichiers & modifications"), #PB_Frame_Container)
; Hauteur de la liste avec garde-fou (même logique que dans ResizeGUI)
Define listH = hFiles - #UI_RowH*2 - #UI_Inset*4 - #UI_FrameHeaderH
If listH < 100 : listH = 100 : EndIf
ListIconGadget(#GID_ListStatus, #UI_Inset, #UI_FrameHeaderH, GadgetWidth(#GID_FrmFiles) - #UI_Inset*2, listH, T("Files.List.Path","Path"), 300, #PB_ListIcon_CheckBoxes | #PB_ListIcon_MultiSelect | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#GID_ListStatus, 1, T("Files.List.Status","Status"), 80)
AddGadgetColumn(#GID_ListStatus, 2, T("Files.List.Description","Description"), 300)
; Ligne boutons sous la liste
Define yLocalActions = #UI_FrameHeaderH + listH + #UI_Inset
ButtonGadget(#GID_BtnRestore, #UI_Inset + 10, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Restore","Restaurer"))
ButtonGadget(#GID_BtnRename, #UI_Inset + 130, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Rename","Renommer"))
ButtonGadget(#GID_BtnDelete, #UI_Inset + 250, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Delete","Supprimer"))
ButtonGadget(#GID_BtnIgnore, #UI_Inset + 370, yLocalActions, 110, #UI_RowH, T("LocalActions.Button.Ignore","Ignorer"))
; Message de commit
Define yMsg = yLocalActions + #UI_RowH + #UI_Inset
TextGadget(#GID_LblMessage, #UI_Inset + 10, yMsg + 4, 80, 22, T("Commit.Label.Message","Message :"))
StringGadget(#GID_EdMessage, #UI_Inset + 95, yMsg, GadgetWidth(#GID_FrmFiles) - #UI_Inset*2 - 95 - 110, #UI_RowH, "")
ButtonGadget(#GID_BtnCommit, GadgetWidth(#GID_FrmFiles) - #UI_Inset - 100, yMsg - 2, 100, #UI_RowH, T("Commit.Button.Commit","Commit"))
CloseGadgetList()
; ===========================================================================
; TAB 2: HISTORY
; ===========================================================================
AddGadgetItem(#GID_Panel, -1, T("Tabs.History","History"))
AddGadgetItem(#GID_Panel, #Panel_History, T("Tabs.History","History"))
ListIconGadget(#GID_ListHistory, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, panelH - #UI_Inset*2 - #UI_RowH - 10 - 150 - 10, T("History.Headers.Header","Header"), 220, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#GID_ListHistory, 1, T("History.Headers.Date","Date"), 150)
AddGadgetColumn(#GID_ListHistory, 2, T("History.Headers.Author","Auteur"), 180)
AddGadgetColumn(#GID_ListHistory, 3, T("History.Headers.Files","Fichiers"), 120)
AddGadgetColumn(#GID_ListHistory, 4, T("History.Headers.Message","Message"), (GadgetWidth(#GID_Panel) - 2*#UI_Inset) - (220 + 150 + 180 + 120) - 20)
ListIconGadget(#GID_ListHistory, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, panelH - #UI_Inset*2 - #UI_RowH - 10 - 150 - 10, T("History.Headers.Header","Header"), 70, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#GID_ListHistory, 1, T("History.Headers.Date","Date"), 200)
AddGadgetColumn(#GID_ListHistory, 2, T("History.Headers.Author","Auteur"), 100)
AddGadgetColumn(#GID_ListHistory, 4, T("History.Headers.Message","Message"), 300)
ButtonGadget(#GID_BtnRestoreCommit, #UI_Inset, panelH - #UI_Inset - #UI_RowH - 150 - 10, 180, #UI_RowH, T("History.Button.RestoreCommit","Restore This Commit"))
@@ -785,14 +977,14 @@ CloseGadgetList()
; ===========================================================================
; TAB 3: .gitignore
; ===========================================================================
AddGadgetItem(#GID_Panel, -1, T("Tabs.Gitignore",".gitignore file"))
AddGadgetItem(#GID_Panel, #Panel_GitIgnore, T("Tabs.Gitignore",".gitignore file"))
EditorGadget(#GID_TxtGitIgnore, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, panelH - #UI_Inset*4 - #UI_RowH)
ButtonGadget(#GID_BtnSaveGitIgnore, #UI_Inset, GadgetY(#GID_TxtGitIgnore) + GadgetHeight(#GID_TxtGitIgnore) + #UI_Inset, 100, #UI_RowH, T("Gitignore.Button.SaveFile","Save File"))
; ===========================================================================
; TAB 4: CONFIG
; ===========================================================================
AddGadgetItem(#GID_Panel, -1, T("Tabs.Config","Config"))
AddGadgetItem(#GID_Panel, #Panel_Config, T("Tabs.Config","Config"))
; --- Frame: Paramètres de lapplication (LANGUE, etc.) ---
FrameGadget(#GID_FrmApp, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, 90, T("App.FrameTitle","Paramètres de lapplication"), #PB_Frame_Container)
@@ -857,6 +1049,109 @@ CloseGadgetList()
ButtonGadget(#GID_BtnApplyProxy, GadgetWidth(#GID_FrmProxy) - #UI_Inset - 140, #UI_Inset + 215, 140, #UI_RowH, T("Proxy.Apply","Appliquer proxy"))
CloseGadgetList()
; ===========================================================================
; TAB 5: TAGS
; ===========================================================================
AddGadgetItem(#GID_Panel, #Panel_Tags, T("Tabs.Tags", "Tags"))
; ---- Frame: Liste des tags ----
FrameGadget(#GID_FrmTagsList, #UI_Inset, #UI_Inset,
GadgetWidth(#GID_Panel) - #UI_Inset*2,
(panelH - #UI_Inset*4) / 2,
T("Tags.FrameList", "Tags existants"), #PB_Frame_Container)
; Liste des tags avec colonnes
ListIconGadget(#GID_ListTags, #UI_Inset, #UI_FrameHeaderH,
GadgetWidth(#GID_FrmTagsList) - #UI_Inset*2,
GadgetHeight(#GID_FrmTagsList) - #UI_FrameHeaderH - #UI_RowH - #UI_Inset*2,
T("Tags.List.Name", "Nom"), 200,
#PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#GID_ListTags, 1, T("Tags.List.Type", "Type"), 100)
AddGadgetColumn(#GID_ListTags, 2, T("Tags.List.Commit", "Commit"), 100)
AddGadgetColumn(#GID_ListTags, 3, T("Tags.List.Date", "Date"), 150)
AddGadgetColumn(#GID_ListTags, 4, T("Tags.List.Author", "Auteur"), 150)
AddGadgetColumn(#GID_ListTags, 5, T("Tags.List.Message", "Message"), 300)
; Boutons d'action pour les tags
Define yTagButtons = GadgetHeight(#GID_FrmTagsList) - #UI_RowH - #UI_Inset
ButtonGadget(#GID_BtnCheckoutTag, #UI_Inset, yTagButtons, 110, #UI_RowH,
T("Tags.Button.Checkout", "Checkout"))
ButtonGadget(#GID_BtnDeleteTag, RightOf(#GID_BtnCheckoutTag) + #UI_Inset, yTagButtons, 110, #UI_RowH,
T("Tags.Button.Delete", "Supprimer"))
ButtonGadget(#GID_BtnPushTag, RightOf(#GID_BtnDeleteTag) + #UI_Inset, yTagButtons, 110, #UI_RowH,
T("Tags.Button.Push", "Push Tag"))
ButtonGadget(#GID_BtnFetchTags, RightOf(#GID_BtnPushTag) + #UI_Inset, yTagButtons, 110, #UI_RowH,
T("Tags.Button.Fetch", "Fetch Tags"))
CloseGadgetList()
; ---- Frame: Création de tag ----
Define yCreateTag = BottomOf(#GID_FrmTagsList) + #UI_Inset
FrameGadget(#GID_FrmCreateTag, #UI_Inset, yCreateTag,
(GadgetWidth(#GID_Panel) - #UI_Inset*3) / 2,
panelH - yCreateTag - #UI_Inset,
T("Tags.FrameCreate", "Créer un tag"), #PB_Frame_Container)
; Nom du tag
TextGadget(#GID_LblTagName, #UI_Inset, #UI_FrameHeaderH + #UI_Inset, 100, #UI_RowH,
T("Tags.Label.Name", "Nom :"))
StringGadget(#GID_EdTagName, RightOf(#GID_LblTagName) + #UI_Inset,
#UI_FrameHeaderH + #UI_Inset,
GadgetWidth(#GID_FrmCreateTag) - 120 - #UI_Inset*3, #UI_RowH, "")
; Type de tag
Define yTagType = BottomOf(#GID_EdTagName) + #UI_Inset
TextGadget(#GID_LblTagType, #UI_Inset, yTagType, 100, #UI_RowH,
T("Tags.Label.Type", "Type :"))
OptionGadget(#GID_OptTagLight, RightOf(#GID_LblTagType) + #UI_Inset, yTagType, 100, #UI_RowH,
T("Tags.Type.Light", "Léger"))
OptionGadget(#GID_OptTagAnnotated, RightOf(#GID_OptTagLight) + #UI_Inset, yTagType, 100, #UI_RowH,
T("Tags.Type.Annotated", "Annoté"))
SetGadgetState(#GID_OptTagAnnotated, 1) ; Par défaut : tag annoté
; Cible du tag (commit/branche)
Define yTagTarget = BottomOf(#GID_OptTagLight) + #UI_Inset
TextGadget(#GID_LblTagTarget, #UI_Inset, yTagTarget, 100, #UI_RowH,
T("Tags.Label.Target", "Cible :"))
ComboBoxGadget(#GID_CbTagTarget, RightOf(#GID_LblTagTarget) + #UI_Inset, yTagTarget,
GadgetWidth(#GID_FrmCreateTag) - 120 - #UI_Inset*3, #UI_RowH)
AddGadgetItem(#GID_CbTagTarget, -1, "HEAD")
AddGadgetItem(#GID_CbTagTarget, -1, T("Tags.Target.SelectCommit", "Sélectionner un commit..."))
SetGadgetState(#GID_CbTagTarget, 0)
; Message du tag (pour les tags annotés)
Define yTagMessage = BottomOf(#GID_CbTagTarget) + #UI_Inset
TextGadget(#GID_LblTagMessage, #UI_Inset, yTagMessage, 100, #UI_RowH,
T("Tags.Label.Message", "Message :"))
EditorGadget(#GID_EdTagMessage, #UI_Inset, BottomOf(#GID_LblTagMessage) + 5,
GadgetWidth(#GID_FrmCreateTag) - #UI_Inset*2, 80)
; Boutons Créer/Annuler
Define yCreateButtons = BottomOf(#GID_EdTagMessage) + #UI_Inset
ButtonGadget(#GID_BtnApplyTag, #UI_Inset, yCreateButtons, 100, #UI_RowH,
T("Tags.Button.Create", "Créer"))
ButtonGadget(#GID_BtnCancelTag, RightOf(#GID_BtnApplyTag) + #UI_Inset, yCreateButtons, 100, #UI_RowH,
T("Tags.Button.Cancel", "Annuler"))
ButtonGadget(#GID_BtnCreateTag, RightOf(#GID_BtnCancelTag) + #UI_Inset, yCreateButtons, 140, #UI_RowH,
T("Tags.Button.NewTag", "+ Nouveau Tag"))
CloseGadgetList()
; ---- Frame: Détails du tag sélectionné ----
Define xDetails = RightOf(#GID_FrmCreateTag) + #UI_Inset
FrameGadget(#GID_FrmTagDetails, xDetails, yCreateTag,
GadgetWidth(#GID_Panel) - xDetails - #UI_Inset,
panelH - yCreateTag - #UI_Inset,
T("Tags.FrameDetails", "Détails du tag"), #PB_Frame_Container)
EditorGadget(#GID_TxtTagDetails, xDetails + #UI_Inset,
yCreateTag + #UI_FrameHeaderH,
GadgetWidth(#GID_FrmTagDetails) - #UI_Inset*2,
GadgetHeight(#GID_FrmTagDetails) - #UI_FrameHeaderH - #UI_Inset,
#PB_Editor_ReadOnly | #PB_Editor_WordWrap)
CloseGadgetList()
; --- End tabs ---
CloseGadgetList()
@@ -895,13 +1190,6 @@ Procedure.i GetGitVersion()
ProcedureReturn #False
EndProcedure
Procedure.i DoGitFetch(remote.s="origin",branch.s="main")
If Git("fetch "+remote+" "+branch) = 0
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.i DoCommit()
Protected code.i,nb.l=0,i.l
Protected args.s = "add"
@@ -925,8 +1213,8 @@ Procedure.i DoCommit()
If GetGadgetText(#GID_CbLocalBranch)<>"" And Git("switch "+GetGadgetText(#GID_CbLocalBranch))<>0
MessageRequester("Git switch", "Échec: " + #LF$ + main\GitCall\errors, #PB_MessageRequester_Error)
EndIf
If Git(args)<>0
MessageRequester("Git add", "Échec: " + #LF$ + main\GitCall\errors, #PB_MessageRequester_Error)
ProcedureReturn #False
@@ -945,6 +1233,58 @@ Procedure.i DoCommit()
ProcedureReturn #True
EndProcedure
Procedure DoRename()
Protected i.l,count.l=0
For i = 0 To CountGadgetItems(#GID_ListStatus) - 1
If GetGadgetItemState(#GID_ListStatus, i) & #PB_ListIcon_Selected
Protected filepath.s=StringField(GetGadgetItemText(#GID_ListStatus, i),1,Chr(10))
Protected newfilepath.s=InputRequester("Git mv","Rename This File",filepath,0,WindowID(#WinMain))
If newfilepath<>"" And filepath<>newfilepath
Protected sucess.b=#False
If LCase(filepath)=LCase(newfilepath) And (#PB_Compiler_OS=#PB_OS_Windows Or #PB_Compiler_OS=#PB_OS_MacOS)
; 2 time to renome on Windows and MacOs
If git("mv "+Chr(34)+filepath+Chr(34)+" "+Chr(34)+filepath+".tmp"+Chr(34))=0
git("mv "+Chr(34)+filepath+".tmp"+Chr(34)+" "+Chr(34)+newfilepath+Chr(34))
count=count+1
sucess=#True
EndIf
Else
If git("mv "+Chr(34)+filepath+Chr(34)+" "+Chr(34)+newfilepath+Chr(34))=0
count=count+1
sucess=#True
EndIf
EndIf
If sucess=#True
EndIf
EndIf
EndIf
Next i
Protected message.s
If count>0
If count=1
message=T("","Renommage de %1 en %2")
message=ReplaceString(message,"%1",filepath)
message=ReplaceString(message,"%2",newfilepath)
ElseIf count>1
message=T("","Renommage de %1 fichiers")
message=ReplaceString(message,"%1",Str(count))
EndIf
If Git("commit -m " + Chr(34)+message+Chr(34))<>0
MessageRequester("Git commit", "Échec ou rien à valider: " + #LF$ + main\GitCall\errors + #LF$ + main\GitCall\output, #PB_MessageRequester_Warning)
EndIf
EndIf
EndProcedure
Procedure.i DoGitFetch(remote.s="origin",branch.s="main")
If Git("fetch "+remote+" "+branch) = 0
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure AddRemoteRepo(Url.s,name.s="origin")
Url=SupTrim(Url)
name=SupTrim(name)
@@ -990,7 +1330,7 @@ Procedure DoPush()
MessageRequester("Git Push", "Échec: " + #LF$ + main\Gitcall\errors, #PB_MessageRequester_Error)
ProcedureReturn #False
EndIf
EndProcedure
Procedure.i GetRemoteStatusInfo()
@@ -1021,7 +1361,7 @@ Procedure.i GetRemoteStatusInfo()
If Len(counts) > 0
; Parser les résultats (séparés par des espaces ou tabs)
Protected parts.s = ReplaceString(counts, #TAB$, " ") ; Normaliser les séparateurs
parts = ReplaceString(parts, " ", " ") ; Supprimer les espaces multiples
parts = ReplaceString(parts, " ", " ") ; Supprimer les espaces multiples
ahead = Val(StringField(parts, 1, " "))
behind = Val(StringField(parts, 2, " "))
@@ -1137,23 +1477,23 @@ Procedure.i GetStatusImportance(status.s)
Protected x.s = Left(status, 1)
Protected y.s = Mid(status, 2, 1)
Protected score.i = 0
; Conflits d'abord
Select status
Case "DD","AU","UD","UA","DU","AA","UU"
ProcedureReturn 1000
EndSelect
If x = "U" Or y = "U" : ProcedureReturn 1000 : EndIf
; Cas simples
If status = "??" : ProcedureReturn 300 : EndIf ; Non suivis
If status = "!!" : ProcedureReturn 50 : EndIf ; Ignorés
If status = " " : ProcedureReturn 0 : EndIf ; Propres
; Index > Worktree
If x <> " " : score + 700 : EndIf
If y <> " " And y <> "?" And y <> "!" : score + 600 : EndIf
; Raffinement (X puis Y)
Select x
Case "D" : score + 80
@@ -1171,7 +1511,7 @@ Procedure.i GetStatusImportance(status.s)
Case "C" : score + 20
Case "T" : score + 15
EndSelect
ProcedureReturn score
EndProcedure
@@ -1189,7 +1529,7 @@ Procedure ParseStatusPorcelaine(output$)
Protected i.l = 1, tok$, sp.l
Protected xy$, path1$, path2$, name$, found.b
; Ne PAS vider main\Files(): on met à jour si existe déjà
For i=1 To total
tok$ = StringField(output$, i, delim$)
@@ -1199,7 +1539,7 @@ Procedure ParseStatusPorcelaine(output$)
Continue
EndIf
xy$ = Left(tok$, 2) ; ex: " M", "R ", " C", "??", "UU", etc.
path1$ = Mid(tok$, 4,Len(tok$)-(3)) ; 1er chemin
path1$ = Mid(tok$, 4,Len(tok$)-(3)) ; 1er chemin
;TODO check this
; Renomme/copie ? (si X ou Y est R/C, le prochain champ NUL = nouveau chemin)
@@ -1212,10 +1552,10 @@ Procedure ParseStatusPorcelaine(output$)
Else
name$ = path1$
EndIf
; Normalisation des séparateurs
name$ = ReplaceString(name$, "\", "/")
; MAJ si déjà présent, sinon ajout
found = #False
ForEach main\Files()
@@ -1226,7 +1566,7 @@ Procedure ParseStatusPorcelaine(output$)
Break
EndIf
Next
If Not found
AddElement(main\Files())
main\Files()\name = name$
@@ -1234,7 +1574,7 @@ Procedure ParseStatusPorcelaine(output$)
main\Files()\statusDescription = GetStatusDescription(xy$)
EndIf
Next
Debug "Récupération des status Git (-z) réussie. " + Str(ListSize(main\Files())) + " fichiers (maj/ajout)."
ProcedureReturn #True
EndProcedure
@@ -1389,7 +1729,7 @@ EndProcedure
Procedure.s RefreshLocalBranchesList(Gdt.i)
ClearGadgetItems(Gdt)
; Parser ligne par ligne
Protected n.l = CountString(main\Gitcall\output, #LF$) + 1
Protected i.l, line.s
@@ -1424,7 +1764,7 @@ EndProcedure
Procedure.s RefreshRemoteBranchesList(Gdt.i)
ClearGadgetItems(Gdt)
; Parser ligne par ligne
Protected n.l = CountString(main\Gitcall\output, #LF$) + 1
Protected i.l, line.s, cleanBranchName.s, defaultBranch.s
@@ -1475,6 +1815,41 @@ Procedure.s RefreshRemoteBranchesList(Gdt.i)
Next
EndProcedure
Procedure GetCommitHistory()
Protected i.l,n.l,line.s
; %H: Commit hash (full)
; %h: Commit hash (abbreviated)
; %an: Author name
; %ae: Author email
; %ad: Author date
; %cn: Committer name
; %ce: Committer email
; %cd: Committer date
; %s: Subject line
; %b: Body of the commit message
; %n: Newline character
If git(~"log --pretty=format:\"%H|%cd|%an|%s\" --date=iso")=0
ClearGadgetItems(#GID_ListHistory)
n.l = CountString(main\Gitcall\output, #LF$) + 1
Debug "Nombre de ligne :"+Str(n)
For i = 1 To n
line = SupTrim(StringField(main\Gitcall\output, i, #LF$))
line=ReplaceString(line,"|",Chr(10))
AddGadgetItem(#GID_ListHistory,-1,line)
Next
EndIf
EndProcedure
Procedure GetCommitInfo()
If GetGadgetState(#GID_ListHistory)>-1
Protected hash.s=GetGadgetItemText(#GID_ListHistory, GetGadgetState(#GID_ListHistory), 0)
If git("show --pretty=fuller --stat --name-status --no-patch --show-signature "+hash)=0
SetGadgetText(#GID_TxtCommitInfo,SupTrim(main\gitCall\output)+SupTrim(main\gitCall\errors))
EndIf
EndIf
EndProcedure
; --- Helper interne : scanne un dossier et alimente la liste
Procedure _ScanFiles(path$, root$="")
If root$="":root$=path$:EndIf
@@ -1494,10 +1869,10 @@ Procedure _ScanFiles(path$, root$="")
_ScanFiles(full$, root$)
EndIf
Else
Protected rel$ = Mid(full$, Len(root$) + 1)
rel$ = ReplaceString(rel$, "\", "/") ; chemins normalisés
AddElement(main\Files())
main\Files()\name = rel$
main\Files()\status = " " ; 2 espaces = clean
@@ -1521,7 +1896,8 @@ Procedure readDirectory()
EndProcedure
Procedure RefreshFiles()
Procedure RefreshGUI(null.i)
DoGitFetch() ;TODO add Branch
ClearGadgetItems(#GID_ListStatus)
ClearList(main\Files())
@@ -1550,7 +1926,7 @@ Procedure RefreshFiles()
main\Files()\importance = GetStatusImportance(main\Files()\status)
Next
;Sort by Importance
;Sort by Importance
SortStructuredList(main\Files(), #PB_Sort_Descending, OffsetOf(FilesStruct\importance), #PB_Integer)
;Display list
@@ -1564,6 +1940,10 @@ Procedure RefreshFiles()
Next
EndProcedure
Procedure Refresh()
CreateThread(@RefreshGUI(),0)
EndProcedure
; -----------------------------------------------------------------------------
;-MAIN
; -----------------------------------------------------------------------------
@@ -1618,15 +1998,16 @@ Procedure Main()
main\IsRepository=IsGitRepository()
SetWindowTitle(#WinMain,#AppTitle$+" (with "+main\gitVersion$+")")
SetGadgetText(#GID_EdRepo, GetCurrentDirectory())
RefreshFiles()
Refresh()
; -----------------------------------------------------------------------------
;-EVENT LOOP / BOUCLE D'ÉVÉNEMENTS
; -----------------------------------------------------------------------------
Protected.i ev, gid
Repeat
UpdateGadgetsState()
ev = WaitWindowEvent()
Select ev
@@ -1636,6 +2017,18 @@ Procedure Main()
Case #PB_Event_Gadget
gid = EventGadget()
Select gid
Case #GID_Panel
If EventType()=#PB_EventType_Change
Select GetGadgetState(#GID_Panel)
Case #Panel_Repo
Case #Panel_History
GetCommitHistory()
Case #Panel_GitIgnore
Case #Panel_Config
EndSelect
EndIf
Case #GID_BtnBrowseRepo
; FR: Sélection dossier / EN: select folder
Protected path$ = PathRequester(T("Dlg.SelectRepo","Sélectionnez le dépôt local..."), GetCurrentDirectory(),WindowID(#WinMain))
@@ -1645,7 +2038,7 @@ Procedure Main()
SetCurrentDirectory(path$)
main\IsRepository=IsGitRepository()
If main\IsRepository=#True
RefreshFiles()
Refresh()
EndIf
;CreateThread(@RefreshFileList(),0) ;TODO refresh list
EndIf
@@ -1655,7 +2048,7 @@ Procedure Main()
; TODO: call your Git init logic
Case #GID_BtnRefresh
RefreshFiles()
Refresh()
Case #GID_BtnClone
SetGadgetText(#GID_TxtAction, T("Action.Clone","Clone demandé"))
@@ -1678,16 +2071,20 @@ Procedure Main()
Case #GID_BtnRestore
; TODO: restore
Case #GID_BtnRename
; TODO: rename
DoRename()
Refresh()
Case #GID_BtnDelete
; TODO: delete
Case #GID_ListHistory
GetCommitInfo()
Case #GID_BtnIgnore
; TODO: ignore
Case #GID_BtnCommit
If DoCommit()=#True
SetGadgetText(#GID_EdMessage,"")
RefreshFiles()
Refresh()
EndIf
Case #GID_BtnSaveGitIgnore
@@ -1706,8 +2103,9 @@ EndProcedure
Main()
; IDE Options = PureBasic 6.21 (Windows - x64)
; CursorPosition = 986
; FirstLine = 974
; Folding = ----f--
; CursorPosition = 776
; FirstLine = 721
; Folding = ---------
; EnableThread
; EnableXP
; DPIAware