KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_git_tags.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
22#include <memory>
23
24#include <confirm.h>
28#include <eda_base_frame.h>
30#include <project.h>
31
32
33PANEL_GIT_TAGS::PANEL_GIT_TAGS( wxWindow* aParent, GIT_ADVANCED_DIALOG* aDialog, EDA_BASE_FRAME* aFrame ) :
34 PANEL_GIT_TAGS_BASE( aParent ),
35 m_dialog( aDialog ),
36 m_frame( aFrame )
37{
38 m_tagsList->AppendColumn( _( "Tag" ), wxLIST_FORMAT_LEFT, FromDIP( 220 ) );
39 m_tagsList->AppendColumn( _( "Commit" ), wxLIST_FORMAT_LEFT, FromDIP( 100 ) );
40 m_tagsList->AppendColumn( _( "Date" ), wxLIST_FORMAT_LEFT, FromDIP( 110 ) );
41
43
44 // The detail pane appears once a tag is selected.
45 m_tagSashPos = FromDIP( 460 );
46 m_tagsSplitter->Unsplit( m_tagDetail );
47
48 m_tagsList->Bind( wxEVT_LIST_ITEM_SELECTED,
49 [this]( wxListEvent& aEvent )
50 {
51 if( !m_fillingTags )
52 showTagDetail( m_tagsList->GetItemText( aEvent.GetIndex(), 0 ) );
53 } );
54
55 m_tagsList->Bind( wxEVT_LIST_ITEM_DESELECTED,
56 [this]( wxListEvent& )
57 {
58 if( !m_fillingTags
59 && m_tagsList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ) == -1 )
60 {
62 }
63 } );
64
65 m_checkoutTagButton->Bind( wxEVT_BUTTON,
66 [this]( wxCommandEvent& )
67 {
69 } );
70 m_deleteTagButton->Bind( wxEVT_BUTTON,
71 [this]( wxCommandEvent& )
72 {
74 } );
75 m_createTagButton->Bind( wxEVT_BUTTON,
76 [this]( wxCommandEvent& )
77 {
78 onNewTag();
79 } );
80}
81
82
84{
85 if( !m_dialog->SessionStillCurrent() )
86 return;
87
88 m_detailQuery.Cancel();
89
90 auto tags = std::make_shared<std::vector<KIGIT_TAG_INFO>>();
91
92 m_listQuery.Run(
93 m_frame->Prj().GetGitCommon(),
94 [tags]( KIGIT_COMMON& aCommon )
95 {
96 *tags = aCommon.GetTags();
97 },
98 [this, tags]()
99 {
100 if( !m_dialog->SessionStillCurrent() )
101 return;
102
103 wxString selected = KIGIT::SelectedText( m_tagsList, 0 );
104 long selectRow = wxNOT_FOUND;
105
106 m_detailQuery.Cancel();
107 m_fillingTags = true;
108 m_tagsList->DeleteAllItems();
109
110 for( const KIGIT_TAG_INFO& t : *tags )
111 {
112 long idx = m_tagsList->InsertItem( m_tagsList->GetItemCount(), t.name );
113 m_tagsList->SetItem( idx, 1, t.hash );
114 m_tagsList->SetItem( idx, 2, KIGIT::RelativeDate( t.when ) );
115
116 if( t.name == selected || ( selected.IsEmpty() && idx == 0 ) )
117 selectRow = idx;
118 }
119
120 int shown = m_tagsList->GetItemCount();
121 m_tagCount->SetLabel( shown == 1 ? _( "1 tag" ) : wxString::Format( _( "%d tags" ), shown ) );
122
123 if( selectRow != wxNOT_FOUND )
124 {
125 m_tagsList->SetItemState( selectRow, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
126 showTagDetail( m_tagsList->GetItemText( selectRow, 0 ) );
127 }
128 else
129 {
131 }
132
133 m_fillingTags = false;
134 } );
135}
136
137
138void PANEL_GIT_TAGS::showTagDetail( const wxString& aTag )
139{
141
142 if( aTag.IsEmpty() || !m_dialog->SessionStillCurrent() )
143 return;
144
145 auto detail = std::make_shared<KIGIT_TAG_DETAIL>();
146
147 m_detailQuery.Run(
148 m_frame->Prj().GetGitCommon(),
149 [detail, aTag]( KIGIT_COMMON& aCommon )
150 {
151 *detail = aCommon.GetTagDetail( aTag );
152 },
153 [this, detail, aTag]()
154 {
155 if( m_dialog->SessionStillCurrent() && KIGIT::SelectedText( m_tagsList, 0 ) == aTag )
156 {
157 fillTagDetail( *detail );
158 }
159 } );
160}
161
162
164{
165 if( !aDetail.found )
166 {
168 return;
169 }
170
171 m_tagTitle->SetLabel( wxString::Format( _( "Tag: %s" ), aDetail.name ) );
172 m_tagCommit->SetLabel( wxString::Format( _( "Commit: %s" ), aDetail.hash ) );
173 m_tagAuthor->SetLabel( wxString::Format( _( "Author: %s <%s>" ), aDetail.author, aDetail.email ) );
174 m_tagWhen->SetLabel( wxString::Format( _( "Date: %s" ), KIGIT::RelativeDate( aDetail.when ) ) );
175 m_tagMessage->ChangeValue( aDetail.message );
176
177 if( !m_tagsSplitter->IsSplit() )
179
180 m_tagDetail->Layout();
181}
182
183
189
190
192{
193 if( !m_dialog->SessionStillCurrent() )
194 return;
195
196 DIALOG_GIT_NEW_TAG dlg( this );
197
198 if( dlg.ShowModal() != wxID_OK )
199 return;
200
201 wxString name = dlg.GetName();
202 wxString message = dlg.GetMessage();
203
204 m_dialog->RunGitAction(
205 [name, message]( KIGIT_COMMON& aCommon )
206 {
207 return aCommon.CreateTag( name, message );
208 },
209 wxString::Format( _( "Could not create tag '%s'." ), name ) );
210}
211
212
214{
215 if( !m_dialog->SessionStillCurrent() )
216 return;
217
218 wxString name = KIGIT::SelectedText( m_tagsList, 0 );
219
220 if( name.IsEmpty() )
221 return;
222
223 m_dialog->RefuseOverUncommittedWork(
224 [this, name]( const GIT_WORKTREE_STATUS& aStatus )
225 {
226 if( !IsOK( this, wxString::Format( _( "Check out tag '%s'? This shows an old snapshot of the "
227 "project. To keep any commits you make here, create a new "
228 "branch before committing. Switching away without one "
229 "leaves those commits outside every branch." ),
230 name ) ) )
231 {
232 return;
233 }
234
235 if( !m_dialog->ConfirmWorkingTreeChange( aStatus ) )
236 return;
237
238 m_dialog->RunGitAction(
239 [name]( KIGIT_COMMON& aCommon )
240 {
241 return aCommon.CheckoutTag( name );
242 },
243 wxString::Format( _( "Could not check out tag '%s'." ), name ),
244 /* rewrites working tree */ true );
245 } );
246}
247
248
250{
251 if( !m_dialog->SessionStillCurrent() )
252 return;
253
254 wxString name = KIGIT::SelectedText( m_tagsList, 0 );
255
256 if( name.IsEmpty() )
257 return;
258
259 if( !IsOK( this, wxString::Format( _( "Delete tag '%s'?" ), name ) ) )
260 return;
261
262 m_dialog->RunGitAction(
263 [name]( KIGIT_COMMON& aCommon )
264 {
265 return aCommon.DeleteTag( name );
266 },
267 wxString::Format( _( "Could not delete tag '%s'." ), name ) );
268}
const char * name
Ask for a tag's name and its optional message. A message makes the tag annotated.
wxString GetName() const
wxString GetMessage() const
int ShowModal() override
The base frame for deriving all KiCad main window classes.
The advanced Git window: a non-modal dialog with a top bar naming the repository and branch and a sid...
The project's git session.
bool CheckoutTag(const wxString &aName)
bool DeleteTag(const wxString &aName)
bool CreateTag(const wxString &aName, const wxString &aMessage=wxEmptyString)
wxSplitterWindow * m_tagsSplitter
PANEL_GIT_TAGS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
KIGIT_QUERY m_listQuery
List and detail reads share the session lock without waiting on the UI thread.
int m_tagSashPos
Where the user left the sash between the list and its detail pane.
PANEL_GIT_TAGS(wxWindow *aParent, GIT_ADVANCED_DIALOG *aDialog, EDA_BASE_FRAME *aFrame)
KIGIT_QUERY m_detailQuery
void showTagDetail(const wxString &aTag)
Fill the detail pane with aTag, or hide it when the name is empty or gone.
GIT_ADVANCED_DIALOG * m_dialog
bool m_fillingTags
True while the list is being refilled, when its selection events are its own.
void fillTagDetail(const KIGIT_TAG_DETAIL &aDetail)
EDA_BASE_FRAME * m_frame
void Populate()
Fill the list from the repository's tags. The repository is read on a worker.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition confirm.cpp:274
This file is part of the common library.
#define _(s)
Base window classes and related definitions.
std::string message
void UnsplitKeepingSash(wxSplitterWindow *aSplitter, wxWindow *aPane, int &aSashPos)
Close a splitter's second pane, keeping the sash where the user left it for next time.
wxString SelectedText(wxListCtrl *aList, int aColumn)
The text of the selected row in a report list, or empty when nothing is selected.
wxString RelativeDate(const wxDateTime &aWhen)
"just now", "3 hours ago", or the ISO date once it is more than a month old.
void MarkDestructive(wxButton *aButton)
Paint a button's text the diff's red, for one that throws something away.
Repository state used before an operation that requires a clean working tree.
wxString message
The tag's own message, or the commit's for a lightweight tag.
wxString email
Their email.
wxString name
The tag name.
wxString hash
Short hash of the tagged commit.
wxDateTime when
When the tag was made, or the commit for a lightweight tag.
wxString author
Who made the tag, or the commit for a lightweight tag.
bool found
False when no tag of that name points at a commit.