mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 18:23:15 +02:00
Recommendation is to avoid using the year nomenclature as this information is already encoded in the git repo. Avoids needing to repeatly update. Also updates AUTHORS.txt from current repo with contributor names
289 lines
8.6 KiB
C++
289 lines
8.6 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 3
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you may find one here:
|
|
* http://www.gnu.org/licenses/gpl-3.0.html
|
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
|
|
#include "dialog_git_switch.h"
|
|
|
|
#include <wx/button.h>
|
|
#include <wx/checkbox.h>
|
|
#include <wx/listctrl.h>
|
|
#include <wx/event.h>
|
|
#include <wx/sizer.h>
|
|
#include <wx/timer.h>
|
|
#include <wx/stattext.h>
|
|
#include <wx/textctrl.h>
|
|
|
|
#include <git2.h>
|
|
|
|
|
|
DIALOG_GIT_SWITCH::DIALOG_GIT_SWITCH( wxWindow* aParent, git_repository* aRepository ) :
|
|
DIALOG_SHIM( aParent, wxID_ANY, _( "Git Branch Switch" ), wxDefaultPosition, wxDefaultSize,
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
|
|
m_timer( this ), m_repository( aRepository )
|
|
{
|
|
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
|
|
|
|
// Add explanation text
|
|
wxStaticText* explanationText =
|
|
new wxStaticText( this, wxID_ANY, _( "Select or enter a branch name:" ) );
|
|
sizer->Add( explanationText, 0, wxALL, 10 );
|
|
|
|
// Add branch list with three columns
|
|
m_branchList = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
|
wxLC_REPORT | wxLC_SINGLE_SEL );
|
|
m_branchList->InsertColumn( 0, _( "Branch" ) );
|
|
m_branchList->InsertColumn( 1, _( "Last Commit" ) );
|
|
m_branchList->InsertColumn( 2, _( "Last Updated" ) );
|
|
sizer->Add( m_branchList, 1, wxALL | wxEXPAND, 10 );
|
|
|
|
// Add branch name text box
|
|
m_branchNameText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
|
wxDefaultSize, wxTE_PROCESS_ENTER );
|
|
sizer->Add( m_branchNameText, 0, wxALL | wxEXPAND, 10 );
|
|
|
|
// Add buttons
|
|
wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer();
|
|
m_switchButton = new wxButton( this, wxID_OK, _( "Switch" ) );
|
|
buttonSizer->AddButton( m_switchButton );
|
|
m_switchButton->Disable();
|
|
wxButton* cancelButton = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
|
|
buttonSizer->AddButton( cancelButton );
|
|
buttonSizer->Realize();
|
|
sizer->Add( buttonSizer, 0, wxALIGN_RIGHT | wxALL, 10 );
|
|
|
|
// Bind events
|
|
Bind( wxEVT_LIST_ITEM_SELECTED, &DIALOG_GIT_SWITCH::OnBranchListSelection, this, m_branchList->GetId() );
|
|
Bind( wxEVT_LIST_ITEM_ACTIVATED, &DIALOG_GIT_SWITCH::OnBranchListDClick, this, m_branchList->GetId() );
|
|
Bind( wxEVT_BUTTON, &DIALOG_GIT_SWITCH::OnSwitchButton, this, m_switchButton->GetId() );
|
|
Bind( wxEVT_BUTTON, &DIALOG_GIT_SWITCH::OnCancelButton, this, cancelButton->GetId() );
|
|
Bind( wxEVT_TEXT, &DIALOG_GIT_SWITCH::OnTextChanged, this, m_branchNameText->GetId() );
|
|
Bind( wxEVT_TIMER, &DIALOG_GIT_SWITCH::OnTimer, this, m_timer.GetId() );
|
|
|
|
// Populate branch list
|
|
PopulateBranchList();
|
|
|
|
// Set sizer for the dialog
|
|
SetSizerAndFit( sizer );
|
|
|
|
finishDialogSettings();
|
|
|
|
m_existingBranch = false;
|
|
}
|
|
|
|
DIALOG_GIT_SWITCH::~DIALOG_GIT_SWITCH()
|
|
{
|
|
StopTimer();
|
|
Unbind( wxEVT_TIMER, &DIALOG_GIT_SWITCH::OnTimer, this, m_timer.GetId() );
|
|
}
|
|
|
|
void DIALOG_GIT_SWITCH::PopulateBranchList()
|
|
{
|
|
m_branchList->DeleteAllItems();
|
|
|
|
// Get the branches
|
|
GetBranches();
|
|
|
|
// Populate the list
|
|
for( auto& [ name, data ] : m_branches )
|
|
{
|
|
wxDateTime lastUpdated( data.lastUpdated );
|
|
wxString lastUpdatedString = lastUpdated.Format();
|
|
|
|
long itemIndex = m_branchList->InsertItem( m_branchList->GetItemCount(), name );
|
|
m_branchList->SetItem( itemIndex, 1, data.commitString );
|
|
m_branchList->SetItem( itemIndex, 2, lastUpdatedString );
|
|
}
|
|
|
|
m_branchList->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
|
m_branchList->SetColumnWidth( 1, wxLIST_AUTOSIZE );
|
|
m_branchList->SetColumnWidth( 2, wxLIST_AUTOSIZE );
|
|
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::OnBranchListDClick( wxListEvent& aEvent )
|
|
{
|
|
int selection = aEvent.GetIndex();
|
|
|
|
if( selection != wxNOT_FOUND )
|
|
{
|
|
wxString branchName = m_branchList->GetItemText( selection );
|
|
m_branchNameText->SetValue( branchName );
|
|
|
|
if( branchName != m_currentBranch )
|
|
EndModal( wxID_OK );
|
|
}
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::OnBranchListSelection( wxListEvent& aEvent )
|
|
{
|
|
int selection = aEvent.GetIndex();
|
|
|
|
if( selection != wxNOT_FOUND )
|
|
{
|
|
wxString branchName = m_branchList->GetItemText( selection );
|
|
m_branchNameText->SetValue( branchName );
|
|
m_switchButton->SetLabel( _( "Switch" ) );
|
|
m_switchButton->Enable( branchName != m_currentBranch );
|
|
}
|
|
else
|
|
{
|
|
// Deselect all elements in the list
|
|
for( int ii = 0; ii < m_branchList->GetItemCount(); ++ii )
|
|
m_branchList->SetItemState( ii, 0, 0 );
|
|
}
|
|
}
|
|
|
|
void DIALOG_GIT_SWITCH::OnSwitchButton(wxCommandEvent& aEvent)
|
|
{
|
|
wxString branchName = m_branchNameText->GetValue();
|
|
|
|
// Check if the branch name exists
|
|
bool branchExists = m_branches.count(branchName);
|
|
|
|
if (branchExists)
|
|
{
|
|
EndModal(wxID_OK); // Return Switch code
|
|
}
|
|
else
|
|
{
|
|
EndModal(wxID_ADD); // Return Add code
|
|
}
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::OnCancelButton(wxCommandEvent& aEvent)
|
|
{
|
|
EndModal(wxID_CANCEL); // Return Cancel code
|
|
}
|
|
|
|
|
|
wxString DIALOG_GIT_SWITCH::GetBranchName() const
|
|
{
|
|
return m_branchNameText->GetValue();
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::StartTimer()
|
|
{
|
|
m_timer.Start( 500, true );
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::StopTimer()
|
|
{
|
|
m_timer.Stop();
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::OnTimer( wxTimerEvent& aEvt )
|
|
{
|
|
wxString branchName = m_branchNameText->GetValue();
|
|
|
|
if( branchName == m_lastEnteredText )
|
|
return;
|
|
|
|
m_lastEnteredText = branchName;
|
|
|
|
// Check if the branch name exists
|
|
bool branchExists = m_branches.count( branchName );
|
|
|
|
if( branchExists )
|
|
{
|
|
m_switchButton->SetLabel( _( "Switch" ) );
|
|
m_switchButton->Enable( branchName != m_currentBranch );
|
|
}
|
|
else
|
|
{
|
|
m_switchButton->SetLabel( _( "Add" ) );
|
|
m_switchButton->Enable();
|
|
}
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::OnTextChanged( wxCommandEvent& aEvt )
|
|
{
|
|
StartTimer();
|
|
}
|
|
|
|
|
|
void DIALOG_GIT_SWITCH::GetBranches()
|
|
{
|
|
// Clear the branch list
|
|
m_branches.clear();
|
|
|
|
git_branch_iterator* branchIterator = nullptr;
|
|
git_branch_t branchType;
|
|
|
|
// Get Current Branch
|
|
git_reference* currentBranchReference = nullptr;
|
|
git_repository_head( ¤tBranchReference, m_repository );
|
|
|
|
// Get the current branch name
|
|
if( currentBranchReference )
|
|
{
|
|
m_currentBranch = git_reference_shorthand( currentBranchReference );
|
|
git_reference_free( currentBranchReference );
|
|
}
|
|
|
|
// Initialize branch iterator
|
|
git_branch_iterator_new( &branchIterator, m_repository, GIT_BRANCH_ALL );
|
|
|
|
// Iterate over local branches
|
|
git_reference* branchReference = nullptr;
|
|
while( git_branch_next( &branchReference, &branchType, branchIterator ) == 0 )
|
|
{
|
|
// Get the branch OID
|
|
const git_oid* branchOid = git_reference_target( branchReference );
|
|
|
|
// Skip this branch if it doesn't have an OID
|
|
if( !branchOid )
|
|
{
|
|
git_reference_free( branchReference );
|
|
continue;
|
|
}
|
|
|
|
git_commit* commit = nullptr;
|
|
|
|
if( git_commit_lookup( &commit, m_repository, branchOid ) )
|
|
{
|
|
// Skip this branch if it doesn't have a commit
|
|
git_reference_free( branchReference );
|
|
continue;
|
|
}
|
|
|
|
// Retrieve commit details
|
|
BranchData branchData;
|
|
branchData.commitString = git_commit_message( commit );
|
|
branchData.lastUpdated = static_cast<time_t>( git_commit_time( commit ) );
|
|
branchData.isRemote = branchType == GIT_BRANCH_REMOTE;
|
|
|
|
m_branches[git_reference_shorthand( branchReference )] = branchData;
|
|
|
|
git_commit_free( commit );
|
|
git_reference_free( branchReference );
|
|
}
|
|
|
|
git_branch_iterator_free( branchIterator );
|
|
} |