diff --git a/main2.pb b/main2.pb index 6f4fd62..8098476 100644 --- a/main2.pb +++ b/main2.pb @@ -356,7 +356,6 @@ Procedure.i RunExe(*call.runProgramCallStruct) EndProcedure - ; ============================================================================= ;-GUI ; ============================================================================= @@ -461,33 +460,33 @@ 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 + ; === 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 @@ -655,39 +654,39 @@ Procedure ResizeGUI() ; 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) + 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 @@ -764,17 +763,17 @@ Procedure ApplyToolTips() ; --- 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é")) + 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) --- @@ -787,42 +786,42 @@ Procedure UpdateGadgetsState() 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) @@ -831,26 +830,26 @@ Procedure UpdateGadgetsState() _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 @@ -1051,104 +1050,104 @@ Procedure OpenGUI() ; =========================================================================== -; 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() + ; 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() @@ -1159,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 @@ -1197,7 +1197,7 @@ Procedure GitInit() EndIf MessageRequester("Git init", "Échec: " + #LF$ + SupTrim(main\gitCall\errors), #PB_MessageRequester_Error) ProcedureReturn 0 - + EndProcedure Procedure.i DoCommit() @@ -1906,6 +1906,270 @@ Procedure readDirectory() EndProcedure +; ============================================================================= +;- 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 ~"" + HtmlEscape(text$) + "" +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$ + ~"
" + html$ + ~"" + + ; --- En-tête + html$ + "" + 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).")) + "
" + html$ + "" + HtmlEscape(T("help.nocommit.pushhint", + "Après votre premier commit, vous pourrez « Push » vers le dépôt distant.")) + "
" + EndIf + html$ + "" + HtmlEscape(T("help.status.conflicts.msg", + "Des conflits existent. Résolvez-les puis committez la résolution.")) + "
" + EndIf + + If cStaged + cUnstaged + cUntracked = 0 + html$ + "" + HtmlEscape(T("help.status.clean","Aucun changement local détecté.")) + "
" + Else + html$ + "" + 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))) + "
" + + Select Bool(ahead>0) * 2 + Bool(behind>0) ; 0=à jour, 1=behind, 2=ahead, 3=divergent + Case 0 + html$ + "" + HtmlEscape(T("help.remote.uptodate","Votre branche est à jour avec le distant.")) + "
" + Case 2 + html$ + "" + HtmlEscape(T("help.remote.push", + "Vous avez des commits en avance. Cliquez « Push » pour les publier.")) + "
" + Case 1 + html$ + "" + HtmlEscape(T("help.remote.pull", + "Le distant a des commits que vous n’avez pas. Cliquez « Pull » pour mettre à jour.")) + "
" + Case 3 + html$ + "" + HtmlEscape(T("help.remote.diverge", + "Branches divergentes. Effectuez un merge ou un rebase, puis poussez le résultat.")) + "
" + EndSelect + Else + html$ + "" + HtmlEscape(T("help.remote.select", + "Sélectionnez une branche locale et une branche distante pour évaluer l’état (Pull/Push).")) + "
" + EndIf + + html$ + "" + 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.")) + "
" + html$ + "init
— " + HtmlEscape(T("help.c.init","crée un dépôt vide dans le dossier courant.")) + "clone
— " + HtmlEscape(T("help.c.clone","copie un dépôt distant en local.")) + "stage
— " + HtmlEscape(T("help.c.stage","prépare des fichiers pour le prochain commit (cochez dans la liste).")) + "commit
— " + HtmlEscape(T("help.c.commit","enregistre un instantané avec message.")) + "push
— " + HtmlEscape(T("help.c.push","envoie vos commits vers le dépôt distant.")) + "pull
— " + HtmlEscape(T("help.c.pull","récupère et fusionne les commits distants.")) + "rebase
— " + HtmlEscape(T("help.c.rebase","rejoue vos commits au-dessus de la branche distante pour un historique linéaire.")) + "