Compare commits
6 Commits
e78cad78f0
...
main
Author | SHA1 | Date | |
---|---|---|---|
f7b816bd48 | |||
fc18c30eaa | |||
d71b435d31 | |||
a948550932 | |||
7cc314e34c | |||
f4c8e58d55 |
BIN
GitCompanion.ico
Normal file
BIN
GitCompanion.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
BIN
GitCompanion.png
Normal file
BIN
GitCompanion.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
801
main2.pb
801
main2.pb
@@ -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()
|
||||
|
||||
@@ -351,7 +356,6 @@ Procedure.i RunExe(*call.runProgramCallStruct)
|
||||
EndProcedure
|
||||
|
||||
|
||||
|
||||
; =============================================================================
|
||||
;-GUI
|
||||
; =============================================================================
|
||||
@@ -456,6 +460,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
|
||||
@@ -491,6 +523,38 @@ EndEnumeration
|
||||
; -----------------------------------------------------------------------------
|
||||
; SMALL HELPERS / AIDES UTILITAIRES
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
; Compte le nombre d’items 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 d’items 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 +652,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
|
||||
|
||||
|
||||
@@ -662,16 +762,108 @@ Procedure ApplyToolTips()
|
||||
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 d’aide (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 L’INTERFACE
|
||||
; -----------------------------------------------------------------------------
|
||||
Enumeration
|
||||
#Panel_Repo
|
||||
#Panel_History
|
||||
#Panel_GitIgnore
|
||||
#Panel_Config
|
||||
#Panel_Tags
|
||||
EndEnumeration
|
||||
Procedure OpenGUI()
|
||||
UseModule Translate
|
||||
Define repoDir$ = GetCurrentDirectory()
|
||||
@@ -685,9 +877,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 :"))
|
||||
@@ -738,45 +930,44 @@ Procedure OpenGUI()
|
||||
|
||||
|
||||
; ---- 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
|
||||
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)
|
||||
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
|
||||
; 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)
|
||||
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"))
|
||||
; 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()
|
||||
; 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 +976,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 l’application (LANGUE, etc.) ---
|
||||
FrameGadget(#GID_FrmApp, #UI_Inset, #UI_Inset, GadgetWidth(#GID_Panel) - #UI_Inset*2, 90, T("App.FrameTitle","Paramètres de l’application"), #PB_Frame_Container)
|
||||
@@ -857,6 +1048,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()
|
||||
|
||||
@@ -864,11 +1158,12 @@ CloseGadgetList()
|
||||
; HELP AREA (RIGHT SIDE) / ZONE AIDE (À DROITE)
|
||||
; ===========================================================================
|
||||
FrameGadget(#GID_HelpFrame, #UI_Margin*2 + #UI_PanelStartW, #UI_Margin, 400, panelH, T("Help.FrameTitle","Aide"), #PB_Frame_Container)
|
||||
WebViewGadget(#GID_HelpWeb, GadgetX(#GID_HelpFrame) + #UI_Inset, GadgetY(#GID_HelpFrame) + #UI_FrameHeaderH, GadgetWidth(#GID_HelpFrame) - #UI_Inset*2, GadgetHeight(#GID_HelpFrame) - #UI_FrameHeaderH - #UI_Inset)
|
||||
WebViewGadget(#GID_HelpWeb, #UI_Inset, #UI_FrameHeaderH, GadgetWidth(#GID_HelpFrame) - #UI_Inset*2, GadgetHeight(#GID_HelpFrame) - #UI_FrameHeaderH - #UI_Inset,#PB_WebView_Debug)
|
||||
CloseGadgetList()
|
||||
|
||||
; Initial placement / placement initial
|
||||
ResizeGUI()
|
||||
;TODO Enable REsizeGui
|
||||
;ResizeGUI()
|
||||
; Tooltips
|
||||
ApplyToolTips()
|
||||
ProcedureReturn #True
|
||||
@@ -895,11 +1190,14 @@ Procedure.i GetGitVersion()
|
||||
ProcedureReturn #False
|
||||
EndProcedure
|
||||
|
||||
Procedure.i DoGitFetch(remote.s="origin",branch.s="main")
|
||||
If Git("fetch "+remote+" "+branch) = 0
|
||||
Procedure GitInit()
|
||||
If Git("init") = 0
|
||||
MessageRequester("Git init", "Répertoire initialisé." + #LF$ + SupTrim(main\gitCall\output), #PB_MessageRequester_Info)
|
||||
ProcedureReturn #True
|
||||
EndIf
|
||||
ProcedureReturn #False
|
||||
MessageRequester("Git init", "Échec: " + #LF$ + SupTrim(main\gitCall\errors), #PB_MessageRequester_Error)
|
||||
ProcedureReturn 0
|
||||
|
||||
EndProcedure
|
||||
|
||||
Procedure.i DoCommit()
|
||||
@@ -945,6 +1243,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)
|
||||
@@ -1475,6 +1825,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
|
||||
@@ -1521,7 +1906,272 @@ Procedure readDirectory()
|
||||
|
||||
EndProcedure
|
||||
|
||||
Procedure RefreshFiles()
|
||||
; =============================================================================
|
||||
;- HELP / ASSISTANT CONTEXTUEL
|
||||
; =============================================================================
|
||||
|
||||
; -- Petit formateur pour T() avec %1 %2 %3
|
||||
Procedure.s TF(key.s, Def.s, p1.s = "", p2.s = "", p3.s = "")
|
||||
Protected s.s = T(key, Def)
|
||||
If p1 <> "" : s = ReplaceString(s, "%1", p1) : EndIf
|
||||
If p2 <> "" : s = ReplaceString(s, "%2", p2) : EndIf
|
||||
If p3 <> "" : s = ReplaceString(s, "%3", p3) : EndIf
|
||||
ProcedureReturn s
|
||||
EndProcedure
|
||||
|
||||
; -- Échappe le HTML basique
|
||||
Procedure.s HtmlEscape(s.s)
|
||||
s = ReplaceString(s, "&", "&")
|
||||
s = ReplaceString(s, "<", "<")
|
||||
s = ReplaceString(s, ">", ">")
|
||||
s = ReplaceString(s, ~"\"", """)
|
||||
ProcedureReturn s
|
||||
EndProcedure
|
||||
|
||||
; -- file:// URL cross-plateforme
|
||||
Procedure.s _ToFileURL(path$)
|
||||
Protected p$ = ReplaceString(path$, "\", "/")
|
||||
CompilerSelect #PB_Compiler_OS
|
||||
CompilerCase #PB_OS_Windows
|
||||
ProcedureReturn "file:///" + p$
|
||||
CompilerDefault
|
||||
ProcedureReturn "file://" + p$
|
||||
CompilerEndSelect
|
||||
EndProcedure
|
||||
|
||||
; -- Y a-t-il au moins un commit ?
|
||||
Procedure.b _HasInitialCommit()
|
||||
ProcedureReturn Bool(Git("rev-parse --verify HEAD") = 0)
|
||||
EndProcedure
|
||||
|
||||
; -- Construis des petits "pills" d'état jolies
|
||||
Procedure.s _Pill(text$)
|
||||
ProcedureReturn ~"<span class='pill'>" + HtmlEscape(text$) + "</span>"
|
||||
EndProcedure
|
||||
|
||||
; -- Procédure principale
|
||||
Procedure RefreshHelp()
|
||||
Protected repo.b = main\IsRepository
|
||||
Protected workdir$ = GetCurrentDirectory()
|
||||
Protected remoteText$ = SupTrim(GetGadgetText(#GID_EdRemote))
|
||||
Protected hasRemoteCfg.b = main\hasRemoteUrl
|
||||
Protected locBr$ = SupTrim(GetGadgetText(#GID_CbLocalBranch))
|
||||
Protected remBr$ = SupTrim(GetGadgetText(#GID_CbRemoteBranch))
|
||||
|
||||
Protected hasCommit.b = #False
|
||||
Protected cStaged.l = 0, cUnstaged.l = 0, cUntracked.l = 0, cConflicts.l = 0
|
||||
Protected ahead.l, behind.l
|
||||
|
||||
; ========== Collecte d’infos ==========
|
||||
If repo
|
||||
hasCommit = _HasInitialCommit()
|
||||
|
||||
; -- Compte les états de travail à partir de main\Files()
|
||||
Protected x$, y$
|
||||
ForEach main\Files()
|
||||
x$ = Left(main\Files()\status, 1)
|
||||
y$ = Right(main\Files()\status, 1)
|
||||
|
||||
; Conflits
|
||||
Select main\Files()\status
|
||||
Case "DD","AU","UD","UA","DU","AA","UU"
|
||||
cConflicts + 1 : Continue
|
||||
EndSelect
|
||||
If x$ = "U" Or y$ = "U" : cConflicts + 1 : Continue : EndIf
|
||||
|
||||
; Non suivis / ignorés
|
||||
If main\Files()\status = "??" : cUntracked + 1 : Continue : EndIf
|
||||
If main\Files()\status = "!!" : Continue : EndIf
|
||||
|
||||
; Staged (index) si X != espace
|
||||
If x$ <> " " : cStaged + 1 : EndIf
|
||||
|
||||
; Non-staged (worktree) si Y != espace,? ,!
|
||||
If y$ <> " " And y$ <> "?" And y$ <> "!" : cUnstaged + 1 : EndIf
|
||||
Next
|
||||
|
||||
|
||||
If hasRemoteCfg And locBr$ <> "" And remBr$ <> ""
|
||||
; -- Récupère ahead/behind entre 2 branches
|
||||
If Trim(locBr$) <> "" And Trim(remBr$) <> ""
|
||||
If Git("rev-list --left-right --count " + locBr$ + "..." + remBr$) = 0
|
||||
Protected counts$ = Trim(ReplaceString(ReplaceString(main\GitCall\output, #TAB$, " "), " ", " "))
|
||||
ahead = Val(StringField(counts$, 1, " "))
|
||||
behind = Val(StringField(counts$, 2, " "))
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
; ========== Construction HTML ==========
|
||||
Protected html$
|
||||
html$ + ~"<!doctype html><html><head><meta charset='utf-8'>"
|
||||
html$ + ~"<style>"+
|
||||
"body{font:14px -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;padding:16px 16px 40px;color:#1b1f23;}"+
|
||||
"h1{font-size:18px;margin:0 0 10px;}"+
|
||||
"h2{font-size:16px;margin:22px 0 8px;}"+
|
||||
".section{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:14px 16px;margin-bottom:12px;box-shadow:0 1px 2px rgba(0,0,0,.04);}"+
|
||||
"ul{margin:8px 0 0 18px;}"+
|
||||
"li{margin:4px 0;}"+
|
||||
".muted{color:#6b7280;}"+
|
||||
".row{display:flex;gap:8px;flex-wrap:wrap;margin:6px 0;}"+
|
||||
".pill{display:inline-block;padding:3px 8px;border-radius:999px;border:1px solid #e5e7eb;background:#f9fafb;font-size:12px}"+
|
||||
"code{background:#f3f4f6;border:1px solid #e5e7eb;border-radius:6px;padding:1px 5px}"+
|
||||
".callout{border-left:4px solid #3b82f6;padding-left:10px;margin:8px 0}"+
|
||||
".ok{color:#16a34a}.warn{color:#d97706}.err{color:#dc2626}.info{color:#2563eb}"+
|
||||
"</style></head><body>"
|
||||
|
||||
; --- En-tête
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h1>" + HtmlEscape(T("help.title", "Assistant contextuel")) + "</h1>"
|
||||
html$ + "<div class='row'>"
|
||||
If repo
|
||||
html$ + _Pill(T("help.pill.repo", "Dépôt détecté"))
|
||||
Else
|
||||
html$ + _Pill(T("help.pill.norepo", "Pas de dépôt"))
|
||||
EndIf
|
||||
If hasRemoteCfg
|
||||
html$ + _Pill(TF("help.pill.remote", "Remote: %1", remoteText$))
|
||||
EndIf
|
||||
If locBr$ <> "" : html$ + _Pill(TF("help.pill.localbr", "Branche locale: %1", locBr$)) : EndIf
|
||||
If remBr$ <> "" : html$ + _Pill(TF("help.pill.remotebr", "Branche distante: %1", remBr$)) : EndIf
|
||||
html$ + "</div>"
|
||||
html$ + "<div class='muted'>" + HtmlEscape(TF("help.workdir", "Dossier : %1", workdir$)) + "</div>"
|
||||
html$ + "</div>"
|
||||
|
||||
; --- Corps selon contexte
|
||||
If Not repo
|
||||
; Pas de dépôt → proposer init ou clone
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.norepo.title","Aucun dépôt Git ici")) + "</h2>"
|
||||
html$ + "<div class='callout info'>" + HtmlEscape(T("help.norepo.why",
|
||||
"Initialiser un dépôt permet de suivre l’historique de vos fichiers, de créer des versions et de collaborer.")) + "</div>"
|
||||
html$ + "<ul>"
|
||||
html$ + "<li>" + HtmlEscape(T("help.norepo.action.init",
|
||||
"Cliquez sur « Init Dépôt » pour créer un dépôt vide (.git).")) + "</li>"
|
||||
html$ + "<li>" + HtmlEscape(T("help.norepo.action.clone",
|
||||
"Si vous avez une URL distante dans « Remote », cliquez sur « Clone » pour récupérer un dépôt existant.")) + "</li>"
|
||||
html$ + "</ul>"
|
||||
html$ + "</div>"
|
||||
|
||||
ElseIf repo And Not hasCommit
|
||||
; Dépôt sans commit
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.nocommit.title","Aucun commit pour l’instant")) + "</h2>"
|
||||
html$ + "<p>" + HtmlEscape(T("help.nocommit.how",
|
||||
"Cochez des fichiers à préparer (stage), écrivez un message puis cliquez « Commit ». Vous pouvez ignorer des fichiers via « Ignorer » (.gitignore).")) + "</p>"
|
||||
html$ + "<ul>"
|
||||
html$ + "<li>" + HtmlEscape(T("help.nocommit.step1","Cochez les fichiers à inclure.")) + "</li>"
|
||||
html$ + "<li>" + HtmlEscape(T("help.nocommit.step2","Saisissez un message clair et concis.")) + "</li>"
|
||||
html$ + "<li>" + HtmlEscape(T("help.nocommit.step3","Cliquez « Commit ». Un commit = un point de contrôle.")) + "</li>"
|
||||
html$ + "</ul>"
|
||||
If hasRemoteCfg
|
||||
html$ + "<p class='muted'>" + HtmlEscape(T("help.nocommit.pushhint",
|
||||
"Après votre premier commit, vous pourrez « Push » vers le dépôt distant.")) + "</p>"
|
||||
EndIf
|
||||
html$ + "</div>"
|
||||
|
||||
Else
|
||||
; Dépôt avec (potentiellement) des changements
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.status.title","État des changements")) + "</h2>"
|
||||
html$ + "<div class='row'>"
|
||||
html$ + _Pill(TF("help.status.staged", "Préparés : %1", Str(cStaged)))
|
||||
html$ + _Pill(TF("help.status.unstaged", "Non préparés : %1", Str(cUnstaged)))
|
||||
html$ + _Pill(TF("help.status.untracked", "Non suivis : %1", Str(cUntracked)))
|
||||
html$ + _Pill(TF("help.status.conflicts", "Conflits : %1", Str(cConflicts)))
|
||||
html$ + "</div>"
|
||||
|
||||
If cConflicts > 0
|
||||
html$ + "<p class='err'>" + HtmlEscape(T("help.status.conflicts.msg",
|
||||
"Des conflits existent. Résolvez-les puis committez la résolution.")) + "</p>"
|
||||
EndIf
|
||||
|
||||
If cStaged + cUnstaged + cUntracked = 0
|
||||
html$ + "<p class='ok'>" + HtmlEscape(T("help.status.clean","Aucun changement local détecté.")) + "</p>"
|
||||
Else
|
||||
html$ + "<ul>"
|
||||
If cUnstaged > 0 Or cStaged > 0
|
||||
html$ + "<li>" + HtmlEscape(T("help.status.suggest.commit",
|
||||
"Cochez les fichiers à inclure puis cliquez « Commit » pour enregistrer vos modifications.")) + "</li>"
|
||||
EndIf
|
||||
If cUntracked > 0
|
||||
html$ + "<li>" + HtmlEscape(T("help.status.suggest.ignore",
|
||||
"Des fichiers non suivis existent. Ajoutez-les au suivi (cochez/commit) ou ignorez-les via « Ignorer » pour les exclure du VCS.")) + "</li>"
|
||||
EndIf
|
||||
html$ + "</ul>"
|
||||
EndIf
|
||||
html$ + "</div>"
|
||||
|
||||
; --- Remote / Synchronisation
|
||||
If hasRemoteCfg
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.remote.title","Synchronisation avec le dépôt distant")) + "</h2>"
|
||||
|
||||
If locBr$ <> "" And remBr$ <> ""
|
||||
html$ + "<p>" + HtmlEscape(TF("help.remote.brpair",
|
||||
"Comparaison %1 ↔ %2 :", locBr$, remBr$)) + " "
|
||||
html$ + _Pill(TF("help.remote.ahead", "En avance : %1", Str(ahead)))
|
||||
html$ + _Pill(TF("help.remote.behind", "En retard : %1", Str(behind))) + "</p>"
|
||||
|
||||
Select Bool(ahead>0) * 2 + Bool(behind>0) ; 0=à jour, 1=behind, 2=ahead, 3=divergent
|
||||
Case 0
|
||||
html$ + "<p class='ok'>" + HtmlEscape(T("help.remote.uptodate","Votre branche est à jour avec le distant.")) + "</p>"
|
||||
Case 2
|
||||
html$ + "<p class='info'>" + HtmlEscape(T("help.remote.push",
|
||||
"Vous avez des commits en avance. Cliquez « Push » pour les publier.")) + "</p>"
|
||||
Case 1
|
||||
html$ + "<p class='warn'>" + HtmlEscape(T("help.remote.pull",
|
||||
"Le distant a des commits que vous n’avez pas. Cliquez « Pull » pour mettre à jour.")) + "</p>"
|
||||
Case 3
|
||||
html$ + "<p class='err'>" + HtmlEscape(T("help.remote.diverge",
|
||||
"Branches divergentes. Effectuez un merge ou un rebase, puis poussez le résultat.")) + "</p>"
|
||||
EndSelect
|
||||
Else
|
||||
html$ + "<p class='muted'>" + HtmlEscape(T("help.remote.select",
|
||||
"Sélectionnez une branche locale et une branche distante pour évaluer l’état (Pull/Push).")) + "</p>"
|
||||
EndIf
|
||||
|
||||
html$ + "</div>"
|
||||
|
||||
Else
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.remote.none.title","Aucun remote configuré")) + "</h2>"
|
||||
html$ + "<p>" + HtmlEscape(T("help.remote.none.hint",
|
||||
"Renseignez l’URL dans « Remote » (ex. https://… ou git@host:org/repo.git) puis utilisez « Push » pour publier ou « Pull »/« Fetch » pour synchroniser.")) + "</p>"
|
||||
html$ + "</div>"
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
; --- Concepts clés (toujours utile)
|
||||
html$ + "<div class='section'>"
|
||||
html$ + "<h2>" + HtmlEscape(T("help.concepts.title","Concepts clés")) + "</h2>"
|
||||
html$ + "<ul>"
|
||||
html$ + "<li><code>init</code> — " + HtmlEscape(T("help.c.init","crée un dépôt vide dans le dossier courant.")) + "</li>"
|
||||
html$ + "<li><code>clone</code> — " + HtmlEscape(T("help.c.clone","copie un dépôt distant en local.")) + "</li>"
|
||||
html$ + "<li><code>stage</code> — " + HtmlEscape(T("help.c.stage","prépare des fichiers pour le prochain commit (cochez dans la liste).")) + "</li>"
|
||||
html$ + "<li><code>commit</code> — " + HtmlEscape(T("help.c.commit","enregistre un instantané avec message.")) + "</li>"
|
||||
html$ + "<li><code>push</code> — " + HtmlEscape(T("help.c.push","envoie vos commits vers le dépôt distant.")) + "</li>"
|
||||
html$ + "<li><code>pull</code> — " + HtmlEscape(T("help.c.pull","récupère et fusionne les commits distants.")) + "</li>"
|
||||
html$ + "<li><code>rebase</code> — " + HtmlEscape(T("help.c.rebase","rejoue vos commits au-dessus de la branche distante pour un historique linéaire.")) + "</li>"
|
||||
html$ + "</ul>"
|
||||
html$ + "</div>"
|
||||
|
||||
html$ + "</body></html>"
|
||||
; -- Écrit le HTML et charge dans le WebView
|
||||
If CreateFile(0,GetTemporaryDirectory()+"test.htm")
|
||||
WriteString(0,html$)
|
||||
CloseFile(0)
|
||||
EndIf
|
||||
SetGadgetItemText(#GID_HelpWeb, #PB_WebView_HtmlCode,html$)
|
||||
|
||||
|
||||
EndProcedure
|
||||
|
||||
|
||||
Procedure RefreshGUI(null.i)
|
||||
DoGitFetch() ;TODO add Branch
|
||||
ClearGadgetItems(#GID_ListStatus)
|
||||
ClearList(main\Files())
|
||||
@@ -1562,6 +2212,12 @@ Procedure RefreshFiles()
|
||||
SetGadgetItemState(#GID_ListStatus,n,#PB_ListIcon_Checked)
|
||||
EndIf
|
||||
Next
|
||||
|
||||
RefreshHelp()
|
||||
EndProcedure
|
||||
|
||||
Procedure Refresh()
|
||||
CreateThread(@RefreshGUI(),0)
|
||||
EndProcedure
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
@@ -1577,7 +2233,11 @@ Procedure Main()
|
||||
For n = 0 To CountProgramParameters() - 1
|
||||
param$ = ProgramParameter(n)
|
||||
Select LCase(param$)
|
||||
Case "--project" : If n + 1 < CountProgramParameters() : main\GitCall\workdir = ProgramParameter(n + 1) : EndIf
|
||||
Case "--path"
|
||||
If n + 1 < CountProgramParameters()
|
||||
main\GitCall\workdir = GetPathPart(ProgramParameter(n + 1))
|
||||
|
||||
EndIf
|
||||
EndSelect
|
||||
Next n
|
||||
EndIf
|
||||
@@ -1619,7 +2279,7 @@ Procedure Main()
|
||||
SetWindowTitle(#WinMain,#AppTitle$+" (with "+main\gitVersion$+")")
|
||||
SetGadgetText(#GID_EdRepo, GetCurrentDirectory())
|
||||
|
||||
RefreshFiles()
|
||||
Refresh()
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
;-EVENT LOOP / BOUCLE D'ÉVÉNEMENTS
|
||||
@@ -1627,6 +2287,8 @@ Procedure Main()
|
||||
Protected.i ev, gid
|
||||
|
||||
Repeat
|
||||
UpdateGadgetsState()
|
||||
|
||||
ev = WaitWindowEvent()
|
||||
Select ev
|
||||
|
||||
@@ -1636,6 +2298,21 @@ 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
|
||||
RefreshHelp()
|
||||
Case #GID_BtnInit
|
||||
GitInit()
|
||||
RefreshHelp()
|
||||
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,18 +2322,26 @@ Procedure Main()
|
||||
SetCurrentDirectory(path$)
|
||||
main\IsRepository=IsGitRepository()
|
||||
If main\IsRepository=#True
|
||||
RefreshFiles()
|
||||
Refresh()
|
||||
EndIf
|
||||
;CreateThread(@RefreshFileList(),0) ;TODO refresh list
|
||||
EndIf
|
||||
|
||||
RefreshHelp()
|
||||
Case #GID_BtnInit
|
||||
SetGadgetText(#GID_TxtAction, T("Action.InitRepo","Init dépôt demandé"))
|
||||
; TODO: call your Git init logic
|
||||
GitInit()
|
||||
RefreshHelp()
|
||||
Refresh()
|
||||
|
||||
Case #GID_BtnRefresh
|
||||
RefreshFiles()
|
||||
Refresh()
|
||||
RefreshHelp()
|
||||
|
||||
Case #GID_EdRemote
|
||||
If EventType()=#PB_EventType_LostFocus
|
||||
AddRemoteRepo(SupTrim(GetGadgetText(#GID_EdRemote)))
|
||||
Refresh()
|
||||
RefreshHelp()
|
||||
EndIf
|
||||
Case #GID_BtnClone
|
||||
SetGadgetText(#GID_TxtAction, T("Action.Clone","Clone demandé"))
|
||||
; TODO: git clone
|
||||
@@ -1668,6 +2353,7 @@ Procedure Main()
|
||||
Case #GID_BtnPush
|
||||
DoPush()
|
||||
GetRemoteStatusInfo()
|
||||
RefreshHelp()
|
||||
; TODO: git push
|
||||
|
||||
Case #GID_BtnVerify
|
||||
@@ -1678,18 +2364,22 @@ 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
|
||||
|
||||
RefreshHelp()
|
||||
Case #GID_BtnSaveGitIgnore
|
||||
; TODO: save .gitignore
|
||||
|
||||
@@ -1706,8 +2396,11 @@ EndProcedure
|
||||
Main()
|
||||
|
||||
; IDE Options = PureBasic 6.21 (Windows - x64)
|
||||
; CursorPosition = 986
|
||||
; FirstLine = 974
|
||||
; Folding = ----f--
|
||||
; CursorPosition = 2340
|
||||
; FirstLine = 2308
|
||||
; Folding = ----------
|
||||
; EnableThread
|
||||
; EnableXP
|
||||
; DPIAware
|
||||
; UseIcon = GitCompanion.ico
|
||||
; Executable = GitCompanion.exe
|
Reference in New Issue
Block a user