31#include <wx/stdpaths.h>
34#include <wx/textdlg.h>
55#include <wx/dcclient.h>
56#include <wx/progdlg.h>
57#include <wx/settings.h>
104 wxT(
"^.*\\.kicad_pro$" ),
107 wxT(
"^.*\\.kicad_sch$" ),
108 wxT(
"^[^$].*\\.brd$" ),
109 wxT(
"^[^$].*\\.kicad_pcb$" ),
110 wxT(
"^[^$].*\\.kicad_dru$" ),
111 wxT(
"^[^$].*\\.kicad_wks$" ),
112 wxT(
"^[^$].*\\.kicad_mod$" ),
116 wxT(
"^.*\\.kicad_sym$" ),
121 wxT(
"^.*\\.gbrjob$" ),
122 wxT(
"^.*\\.gb[alops]$" ),
123 wxT(
"^.*\\.gt[alops]$" ),
124 wxT(
"^.*\\.g[0-9]{1,2}$" ),
125 wxT(
"^.*\\.gm[0-9]{1,2}$" ),
129 wxT(
"^.*\\.html$" ),
140 wxT(
"^.*\\.kicad_jobset" ),
222 wxSashLayoutWindow( parent,
ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize,
223 wxNO_BORDER | wxTAB_TRAVERSAL )
226 m_TreeProject =
nullptr;
227 m_isRenaming =
false;
228 m_selectedItem =
nullptr;
229 m_watcherNeedReset =
false;
230 m_gitLastError = GIT_ERROR_NONE;
232 m_gitIconsInitialized =
false;
234 Bind( wxEVT_FSWATCHER,
237 Bind( wxEVT_SYS_COLOUR_CHANGED,
240 m_gitSyncTimer.SetOwner(
this );
241 m_gitStatusTimer.SetOwner(
this );
251 m_filters.emplace_back( wxT(
"^no KiCad files found" ) );
259 Unbind( wxEVT_FSWATCHER,
261 Unbind( wxEVT_SYS_COLOUR_CHANGED,
290 if( tree_data.size() != 1 )
293 wxString prj_filename = tree_data[0]->GetFileName();
307 wxString curr_dir = item_data->GetDir();
309 if( curr_dir.IsEmpty() )
315 if( curr_dir.IsEmpty() || !wxFileName::DirExists( curr_dir ) )
318 if( !curr_dir.IsEmpty() )
319 curr_dir += wxFileName::GetPathSeparator();
337 wxString curr_dir = item_data->GetDir();
339 if( curr_dir.IsEmpty() )
342 wxString new_dir = wxGetTextFromUser(
_(
"Directory name:" ),
_(
"Create New Directory" ) );
344 if( new_dir.IsEmpty() )
347 wxString full_dirname = curr_dir + wxFileName::GetPathSeparator() + new_dir;
349 if( !wxMkdir( full_dirname ) )
379 case TREE_FILE_TYPE::DRILL_NC:
return "nc";
380 case TREE_FILE_TYPE::DRILL_XNC:
return "xnc";
390 case TREE_FILE_TYPE::ROOT:
391 case TREE_FILE_TYPE::UNKNOWN:
392 case TREE_FILE_TYPE::MAX:
393 case TREE_FILE_TYPE::DIRECTORY:
break;
396 return wxEmptyString;
402 std::vector<wxString> projects;
403 wxString dir_filename;
404 bool haveFile = dir.GetFirst( &dir_filename );
408 wxFileName file( dir_filename );
412 projects.push_back( file.GetName() );
414 haveFile = dir.GetNext( &dir_filename );
423 git_repository* repo =
nullptr;
427 if( git_repository_discover( &repo_path, filename, 0, NULL ) != GIT_OK )
435 if( git_repository_open( &repo, repo_path.ptr ) != GIT_OK )
446 const wxTreeItemId& aParent,
447 std::vector<wxString>* aProjectNames,
451 wxFileName fn( aName );
454 return wxTreeItemId();
456 if( wxDirExists( aName ) )
458 type = TREE_FILE_TYPE::DIRECTORY;
464 bool addFile =
false;
466 for(
const wxString& m_filter :
m_filters )
468 wxCHECK2_MSG( reg.Compile( m_filter, wxRE_ICASE ),
continue,
469 wxString::Format(
"Regex %s failed to compile.", m_filter ) );
471 if( reg.Matches( aName ) )
479 return wxTreeItemId();
481 for(
int i =
static_cast<int>( TREE_FILE_TYPE::LEGACY_PROJECT );
482 i < static_cast<int>( TREE_FILE_TYPE::MAX ); i++ )
486 if( ext == wxT(
"" ) )
489 if( reg.Compile( wxString::FromAscii(
"^.*\\." ) + ext + wxString::FromAscii(
"$" ),
490 wxRE_ICASE ) && reg.Matches( aName ) )
498 wxString file = wxFileNameFromPath( aName );
499 wxFileName currfile( file );
503 if( ( type == TREE_FILE_TYPE::LEGACY_PROJECT )
504 && ( currfile.GetName().CmpNoCase(
project.GetName() ) == 0 ) )
506 return wxTreeItemId();
509 if( currfile.GetExt() ==
GetFileExt( TREE_FILE_TYPE::LEGACY_SCHEMATIC )
510 || currfile.GetExt() ==
GetFileExt( TREE_FILE_TYPE::SEXPR_SCHEMATIC ) )
515 return wxTreeItemId();
520 wxDir parentDir( parentTreeItem->
GetDir() );
521 std::vector<wxString> projects =
getProjects( parentDir );
524 return wxTreeItemId();
529 wxTreeItemIdValue cookie;
530 wxTreeItemId kid =
m_TreeProject->GetFirstChild( aParent, cookie );
537 return itemData->GetId();
543 if( type == TREE_FILE_TYPE::LEGACY_PROJECT || type == TREE_FILE_TYPE::JSON_PROJECT
544 || type == TREE_FILE_TYPE::LEGACY_SCHEMATIC || type == TREE_FILE_TYPE::SEXPR_SCHEMATIC )
556 if( fname.GetName().CmpNoCase( currfile.GetName() ) == 0 )
560 case TREE_FILE_TYPE::LEGACY_PROJECT:
561 if( itemData->
GetType() == TREE_FILE_TYPE::JSON_PROJECT )
562 return wxTreeItemId();
566 case TREE_FILE_TYPE::LEGACY_SCHEMATIC:
567 if( itemData->
GetType() == TREE_FILE_TYPE::SEXPR_SCHEMATIC )
568 return wxTreeItemId();
572 case TREE_FILE_TYPE::JSON_PROJECT:
573 if( itemData->
GetType() == TREE_FILE_TYPE::LEGACY_PROJECT )
578 case TREE_FILE_TYPE::SEXPR_SCHEMATIC:
579 if( itemData->
GetType() == TREE_FILE_TYPE::LEGACY_SCHEMATIC )
595 wxTreeItemId newItemId =
m_TreeProject->AppendItem( aParent, file );
602 wxString fileName = currfile.GetName().Lower();
603 wxString projName =
project.GetName().Lower();
605 if( fileName == projName || fileName.StartsWith( projName +
"-" ) )
609 bool subdir_populated =
false;
614 if( TREE_FILE_TYPE::DIRECTORY == type && aRecurse )
620 std::vector<wxString> projects =
getProjects( dir );
621 wxString dir_filename;
622 bool haveFile = dir.GetFirst( &dir_filename );
627 subdir_populated = aRecurse;
633 wxString
path = aName + wxFileName::GetPathSeparator() + dir_filename;
636 haveFile = dir.GetNext( &dir_filename );
645 if( subdir_populated )
682 wxFileName fn = pro_dir;
683 bool prjReset =
false;
694 bool prjOpened = fn.FileExists();
697 if(
Pgm().GetCommonSettings()->m_Git.enableGit )
711 if( !prjOpened && !prjReset )
714 prjOpened = fn.FileExists();
721 m_root =
m_TreeProject->AddRoot( fn.GetFullName(),
static_cast<int>( TREE_FILE_TYPE::ROOT ),
722 static_cast<int>( TREE_FILE_TYPE::ROOT ) );
735 wxDir dir( pro_dir );
739 std::vector<wxString> projects =
getProjects( dir );
741 bool haveFile = dir.GetFirst( &filename );
745 if( filename != fn.GetFullName() )
747 wxString
name = dir.GetName() + wxFileName::GetPathSeparator() + filename;
754 haveFile = dir.GetNext( &filename );
770 wxLogTrace(
traceGit,
"PROJECT_TREE_PANE::ReCreateTreePrj: starting timers" );
784 git_status_options opts;
785 git_status_init_options( &opts, GIT_STATUS_OPTIONS_VERSION );
787 opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
788 opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
789 | GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
791 git_status_list* status_list =
nullptr;
793 if( git_status_list_new( &status_list, repo, &opts ) != GIT_OK )
800 return ( git_status_list_entrycount( status_list ) > 0 );
806 wxTreeItemId curr_item = Event.GetItem();
813 wxFileName prj_dir(
Prj().GetProjectPath(), wxEmptyString );
815 prj_dir.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_CASE | wxPATH_NORM_DOTS
816 | wxPATH_NORM_ENV_VARS | wxPATH_NORM_TILDE );
817 git_dir.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_CASE | wxPATH_NORM_DOTS
818 | wxPATH_NORM_ENV_VARS | wxPATH_NORM_TILDE );
819 wxString prj_name = prj_dir.GetFullPath();
820 wxString git_name = git_dir.GetFullPath();
822 bool can_switch_to_project =
true;
823 bool can_create_new_directory =
true;
824 bool can_open_this_directory =
true;
825 bool can_edit =
true;
826 bool can_rename =
true;
827 bool can_delete =
true;
828 bool run_jobs =
false;
832 bool vcs_can_init = !vcs_has_repo;
833 bool vcs_can_remove = vcs_has_repo && git_name.StartsWith( prj_name );
836 bool vcs_can_pull = vcs_can_fetch;
837 bool vcs_can_switch = vcs_has_repo;
841#if ( LIBGIT2_VER_MAJOR >= 1 ) || ( LIBGIT2_VER_MINOR >= 99 )
842 int major, minor, rev;
843 bool libgit_init = ( git_libgit2_version( &major, &minor, &rev ) == GIT_OK );
846 bool libgit_init =
true;
849 vcs_menu &= libgit_init;
851 if( selection.size() == 0 )
855 if( selection.size() != 1 )
857 can_switch_to_project =
false;
858 can_create_new_directory =
false;
867 can_switch_to_project =
false;
873 can_delete = item->CanDelete();
874 can_rename = item->CanRename();
876 switch( item->GetType() )
878 case TREE_FILE_TYPE::JSON_PROJECT:
879 case TREE_FILE_TYPE::LEGACY_PROJECT:
884 can_switch_to_project =
false;
888 can_create_new_directory =
false;
889 can_open_this_directory =
false;
893 case TREE_FILE_TYPE::DIRECTORY:
894 can_switch_to_project =
false;
898 case TREE_FILE_TYPE::ZIP_ARCHIVE:
899 case TREE_FILE_TYPE::PDF:
901 can_switch_to_project =
false;
902 can_create_new_directory =
false;
903 can_open_this_directory =
false;
906 case TREE_FILE_TYPE::JOBSET_FILE:
911 case TREE_FILE_TYPE::SEXPR_SCHEMATIC:
912 case TREE_FILE_TYPE::SEXPR_PCB:
916 can_switch_to_project =
false;
917 can_create_new_directory =
false;
918 can_open_this_directory =
false;
928 if( can_switch_to_project )
931 _(
"Close all editors, and switch to the selected project" ),
932 KiBitmap( BITMAPS::open_project ) );
933 popup_menu.AppendSeparator();
936 if( can_create_new_directory )
939 _(
"Create a New Directory" ),
KiBitmap( BITMAPS::directory ) );
942 if( can_open_this_directory )
944 if( selection.size() == 1 )
947 text =
_(
"Reveal in Finder" );
948 help_text =
_(
"Reveals the directory in a Finder window" );
950 text =
_(
"Open Directory in File Explorer" );
951 help_text =
_(
"Opens the directory in the default system file manager" );
957 text =
_(
"Reveal in Finder" );
958 help_text =
_(
"Reveals the directories in a Finder window" );
960 text =
_(
"Open Directories in File Explorer" );
961 help_text =
_(
"Opens the directories in the default system file manager" );
966 KiBitmap( BITMAPS::directory_browser ) );
971 if( selection.size() == 1 )
972 help_text =
_(
"Open the file in a Text Editor" );
974 help_text =
_(
"Open files in a Text Editor" );
980 if( run_jobs && selection.size() == 1 )
988 if( selection.size() == 1 )
990 text =
_(
"Rename File..." );
991 help_text =
_(
"Rename file" );
995 text =
_(
"Rename Files..." );
996 help_text =
_(
"Rename files" );
1005 if( selection.size() == 1 )
1006 help_text =
_(
"Delete the file and its content" );
1008 help_text =
_(
"Delete the files and their contents" );
1010 if( can_switch_to_project
1011 || can_create_new_directory
1012 || can_open_this_directory
1016 popup_menu.AppendSeparator();
1030 wxMenu* vcs_submenu =
new wxMenu();
1031 wxMenu* branch_submenu =
new wxMenu();
1032 wxMenuItem* vcs_menuitem =
nullptr;
1035 _(
"Add Project to Version Control..." ),
1036 _(
"Initialize a new repository" ) );
1037 vcs_menuitem->Enable( vcs_can_init );
1041 _(
"Commit changes to the local repository" ) );
1042 vcs_menuitem->Enable( vcs_can_commit );
1044 vcs_menuitem = vcs_submenu->Append(
ID_GIT_PUSH,
_(
"Push" ),
1045 _(
"Push committed local changes to remote repository" ) );
1046 vcs_menuitem->Enable( vcs_can_push );
1048 vcs_menuitem = vcs_submenu->Append(
ID_GIT_PULL,
_(
"Pull" ),
1049 _(
"Pull changes from remote repository into local" ) );
1050 vcs_menuitem->Enable( vcs_can_pull );
1052 vcs_submenu->AppendSeparator();
1055 _(
"Commit changes to the local repository" ) );
1056 vcs_menuitem->Enable( vcs_can_commit );
1058 vcs_submenu->AppendSeparator();
1067 for(
size_t ii = 1; ii < branchNames.size() && ii < 6; ++ii )
1069 wxString msg =
_(
"Switch to branch " ) + branchNames[ii];
1071 vcs_menuitem->Enable( vcs_can_switch );
1075 _(
"Switch to a different branch" ) );
1076 vcs_menuitem->Enable( vcs_can_switch );
1080 vcs_submenu->AppendSeparator();
1082 vcs_menuitem = vcs_submenu->Append(
ID_GIT_REMOVE_VCS,
_(
"Remove Version Control" ),
1083 _(
"Delete all version control files from the project directory." ) );
1084 vcs_menuitem->Enable( vcs_can_remove );
1086 popup_menu.AppendSeparator();
1087 popup_menu.AppendSubMenu( vcs_submenu,
_(
"Version Control" ) );
1090 if( popup_menu.GetMenuItemCount() > 0 )
1091 PopupMenu( &popup_menu );
1099 if( editorname.IsEmpty() )
1101 wxMessageBox(
_(
"No text editor selected in KiCad. Please choose one." ) );
1109 wxString fullFileName = item_data->GetFileName();
1111 if( !fullFileName.IsEmpty() )
1113 ExecuteFile( editorname, fullFileName.wc_str(),
nullptr,
false );
1124 item_data->Delete();
1134 if( tree_data.size() != 1 )
1138 wxString msg = wxString::Format(
_(
"Change filename: '%s'" ),
1139 tree_data[0]->GetFileName() );
1140 wxTextEntryDialog dlg( wxGetTopLevelParent(
this ), msg,
_(
"Change filename" ), buffer );
1142 if( dlg.ShowModal() != wxID_OK )
1145 buffer = dlg.GetValue();
1146 buffer.Trim(
true );
1147 buffer.Trim(
false );
1149 if( buffer.IsEmpty() )
1152 tree_data[0]->Rename( buffer,
true );
1161 if( tree_data.size() != 1 )
1195 wxTreeItemId itemId = Event.GetItem();
1201 if( tree_data->
GetType() != TREE_FILE_TYPE::DIRECTORY )
1205 wxTreeItemIdValue cookie;
1206 wxTreeItemId kid =
m_TreeProject->GetFirstChild( itemId, cookie );
1209 bool subdir_populated =
false;
1212 for( ; kid.IsOk(); kid =
m_TreeProject->GetNextChild( itemId, cookie ) )
1216 if( !itemData || itemData->
GetType() != TREE_FILE_TYPE::DIRECTORY )
1223 wxDir dir( fileName );
1225 if( dir.IsOpened() )
1227 std::vector<wxString> projects =
getProjects( dir );
1228 wxString dir_filename;
1229 bool haveFile = dir.GetFirst( &dir_filename );
1234 wxString
name = fileName + wxFileName::GetPathSeparator() + dir_filename;
1237 haveFile = dir.GetNext( &dir_filename );
1243 subdir_populated =
true;
1252 if( subdir_populated )
1260 wxArrayTreeItemIds selection;
1261 std::vector<PROJECT_TREE_ITEM*> data;
1265 for(
auto it = selection.begin(); it != selection.end(); it++ )
1271 wxLogTrace(
traceGit, wxS(
"Null tree item returned for selection, dynamic_cast "
1276 data.push_back( item );
1295 if( prj_dir == aSubDir )
1299 wxTreeItemIdValue cookie;
1300 wxTreeItemId root_id =
m_root;
1301 std::stack<wxTreeItemId> subdirs_id;
1303 wxTreeItemId child =
m_TreeProject->GetFirstChild( root_id, cookie );
1307 if( ! child.IsOk() )
1309 if( subdirs_id.empty() )
1316 root_id = subdirs_id.top();
1327 if( itemData && ( itemData->
GetType() == TREE_FILE_TYPE::DIRECTORY ) )
1337 subdirs_id.push( child );
1355 if( !( event.GetChangeType() & ( wxFSW_EVENT_CREATE |
1356 wxFSW_EVENT_DELETE |
1357 wxFSW_EVENT_RENAME |
1358 wxFSW_EVENT_MODIFY ) ) )
1363 const wxFileName& pathModified =
event.GetPath();
1364 wxString subdir = pathModified.GetPath();
1365 wxString fn = pathModified.GetFullPath();
1368 if( pathModified.GetFullName().IsEmpty() )
1370 subdir = subdir.BeforeLast(
'/' );
1371 fn = fn.BeforeLast(
'/' );
1376 if( !root_id.IsOk() )
1379 CallAfter( [
this] ()
1381 wxLogTrace(
traceGit, wxS(
"File system event detected, updating tree cache" ) );
1385 wxTreeItemIdValue cookie;
1386 wxTreeItemId kid =
m_TreeProject->GetFirstChild( root_id, cookie );
1388 switch( event.GetChangeType() )
1390 case wxFSW_EVENT_CREATE:
1405 case wxFSW_EVENT_DELETE:
1419 case wxFSW_EVENT_RENAME :
1421 const wxFileName& newpath =
event.GetNewPath();
1422 wxString newdir = newpath.GetPath();
1423 wxString newfn = newpath.GetFullPath();
1447 if( rootData && newpath.Exists() && ( newfn != rootData->
GetFileName() ) )
1453 if( newitem.IsOk() )
1476#if defined( _WIN32 )
1509 fn.AssignDir( prj_dir );
1510 fn.DontFollowLink();
1524 TO_UTF8( fn.GetFullPath() ) );
1532 TO_UTF8( fn.GetFullPath() ) );
1537 if( m_TreeProject->IsEmpty() )
1541 wxTreeItemIdValue cookie;
1542 wxTreeItemId root_id = m_root;
1544 std::stack < wxTreeItemId > subdirs_id;
1546 wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1547 int total_watch_count = 0;
1553 if( subdirs_id.empty() )
1559 root_id = subdirs_id.top();
1561 kid = m_TreeProject->GetFirstChild( root_id, cookie );
1577 if( wxFileName::IsDirReadable(
path ) )
1582 fn.AssignDir(
path );
1583 m_watcher->Add( fn );
1584 total_watch_count++;
1588 if( itemData->
IsPopulated() && m_TreeProject->GetChildrenCount( kid ) )
1589 subdirs_id.push( kid );
1593 kid = m_TreeProject->GetNextChild( root_id, cookie );
1600#if defined(DEBUG) && 1
1601 wxArrayString paths;
1602 m_watcher->GetWatchedPaths( &paths );
1605 for(
unsigned ii = 0; ii < paths.GetCount(); ii++ )
1624 if( !lock.owns_lock() )
1628 wxProgressDialog progress(
1630 _(
"Waiting for Git operations to finish..."),
1633 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH
1637 while ( !lock.try_lock() )
1640 std::this_thread::sleep_for( std::chrono::milliseconds(100) );
1665 wxRect rect( wxPoint( 0, 0 ), GetClientSize() );
1666 wxPaintDC dc(
this );
1668 dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
1669 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
1671 dc.DrawLine( rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom() );
1672 dc.DrawLine( rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom() );
1686 wxString dir = tree_data->
GetDir();
1690 wxLogError(
"Failed to initialize git project: project directory is empty." );
1695 git_repository* repo =
nullptr;
1696 int error = git_repository_open( &repo, dir.mb_str() );
1701 wxWindow* topLevelParent = wxGetTopLevelParent(
this );
1704 _(
"The selected directory is already a Git project." ) );
1705 git_repository_free( repo );
1712 dlg.SetTitle(
_(
"Set default remote" ) );
1718 if( git_repository_init( &repo, dir.mb_str(), 0 ) != GIT_OK )
1740 git_remote* remote =
nullptr;
1749 fullURL = dlg.
GetRepoURL().StartsWith(
"https" ) ?
"https://" :
"http://";
1757 fullURL.append( wxS(
":" ) );
1761 fullURL.append( wxS(
"@" ) );
1772 error = git_remote_create_with_fetchspec( &remote, repo,
"origin",
1773 fullURL.ToStdString().c_str(),
1774 "+refs/heads/*:refs/remotes/origin/*" );
1776 if( error != GIT_OK )
1824 handler.
SetProgressReporter( std::make_unique<WX_PROGRESS_REPORTER>(
this,
_(
"Fetch Remote" ), 1,
1847 handler.
SetProgressReporter( std::make_unique<WX_PROGRESS_REPORTER>(
this,
_(
"Fetch Remote" ), 1,
1850 if( handler.
PerformPush() != PushResult::Success )
1865 if(
int error = git_reference_name_to_id( &head_oid, aRepo,
"HEAD" ) != GIT_OK )
1872 git_commit* commit =
nullptr;
1874 if(
int error = git_commit_lookup( &commit, aRepo, &head_oid ) != GIT_OK )
1881 git_reference* branchRef =
nullptr;
1883 if(
int error = git_branch_create( &branchRef, aRepo, aBranchName.mb_str(), commit, 0 ) != GIT_OK )
1889 git_reference_free( branchRef );
1902 wxString branchName;
1911 if( retval == wxID_ADD )
1913 else if( retval != wxID_OK )
1921 if( branchIndex < 0 ||
static_cast<size_t>( branchIndex ) >= branches.size() )
1924 branchName = branches[branchIndex];
1928 git_reference* branchRef =
nullptr;
1930 if( git_reference_lookup( &branchRef, repo, branchName.mb_str() ) != GIT_OK &&
1931 git_reference_dwim( &branchRef, repo, branchName.mb_str() ) != GIT_OK )
1933 wxString errorMessage = wxString::Format(
_(
"Failed to lookup branch '%s': %s" ),
1940 const char* branchRefName = git_reference_name( branchRef );
1941 git_object* branchObj =
nullptr;
1943 if( git_revparse_single( &branchObj, repo, branchName.mb_str() ) != 0 )
1945 wxString errorMessage =
1946 wxString::Format(
_(
"Failed to find branch head for '%s'" ), branchName );
1954 if( git_checkout_tree( repo, branchObj,
nullptr ) != 0 )
1956 wxString errorMessage =
1957 wxString::Format(
_(
"Failed to switch to branch '%s'" ), branchName );
1963 if( git_repository_set_head( repo, branchRefName ) != 0 )
1965 wxString errorMessage = wxString::Format(
1966 _(
"Failed to update HEAD reference for branch '%s'" ), branchName );
1978 || !
IsOK( wxGetTopLevelParent(
this ),
1979 _(
"Are you sure you want to remove Git tracking from this project?" ) ) )
1985 git_repository_free( repo );
1990 fn.AppendDir(
".git" );
2000 std::stack<wxTreeItemId> items;
2003 while( !items.empty() )
2005 wxTreeItemId current = items.top();
2009 m_TreeProject->SetItemState( current, wxTREE_ITEMSTATE_NONE );
2011 wxTreeItemIdValue cookie;
2012 wxTreeItemId child =
m_TreeProject->GetFirstChild( current, cookie );
2014 while( child.IsOk() )
2016 items.push( child );
2025 wxLogTrace(
traceGit, wxS(
"updateGitStatusIcons: Updating git status icons" ) );
2028 if( !lock.owns_lock() )
2030 wxLogTrace(
traceGit, wxS(
"updateGitStatusIcons: Failed to acquire lock for git status icon update" ) );
2037 wxLogTrace(
traceGit, wxS(
"updateGitStatusIcons: Git is disabled or tree control is null" ) );
2041 std::stack<wxTreeItemId> items;
2044 while( !items.empty() )
2046 wxTreeItemId current = items.top();
2051 wxTreeItemIdValue cookie;
2052 wxTreeItemId child =
m_TreeProject->GetFirstChild( current, cookie );
2054 while( child.IsOk() )
2056 items.push( child );
2060 m_TreeProject->SetItemState( child,
static_cast<int>( it->second ) );
2072 wxString filename = wxFileNameFromPath( rootItem->
GetFileName() );
2077 wxLogTrace(
traceGit, wxS(
"updateGitStatusIcons: Git status icons updated" ) );
2083 wxLogTrace(
traceGit, wxS(
"updateTreeCache: Updating tree cache" ) );
2087 if( !lock.owns_lock() )
2089 wxLogTrace(
traceGit, wxS(
"updateTreeCache: Failed to acquire lock for tree cache update" ) );
2095 wxLogTrace(
traceGit, wxS(
"updateTreeCache: Tree control is null" ) );
2106 std::stack<wxTreeItemId> items;
2109 while( !items.empty() )
2118 gitAbsPath.Replace( wxS(
"\\" ), wxS(
"/" ) );
2122 wxTreeItemIdValue cookie;
2123 wxTreeItemId child =
m_TreeProject->GetFirstChild( kid, cookie );
2125 while( child.IsOk() )
2127 items.push( child );
2136 wxLogTrace(
traceGit, wxS(
"updateGitStatusIconMap: Updating git status icons" ) );
2137#if defined( _WIN32 )
2160 if( !lock1.owns_lock() || !lock2.owns_lock() )
2162 wxLogTrace(
traceGit, wxS(
"updateGitStatusIconMap: Failed to acquire locks for git status icon update" ) );
2170 wxLogTrace(
traceGit, wxS(
"updateGitStatusIconMap: No git repository found" ) );
2175 wxFileName rootFilename(
Prj().GetProjectFullName() );
2176 wxString repoWorkDir( git_repository_workdir( repo ) );
2178 wxFileName relative = rootFilename;
2179 relative.MakeRelativeTo( repoWorkDir );
2180 wxString pathspecStr = relative.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
2183 pathspecStr.Replace( wxS(
"\\" ), wxS(
"/" ) );
2186 const char* pathspec[] = { pathspecStr.c_str().AsChar() };
2188 git_status_options status_options;
2189 git_status_init_options( &status_options, GIT_STATUS_OPTIONS_VERSION );
2190 status_options.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
2191 status_options.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
2192 status_options.pathspec = { (
char**) pathspec, 1 };
2194 git_index* index =
nullptr;
2196 if( git_repository_index( &index, repo ) != GIT_OK )
2204 git_status_list* status_list =
nullptr;
2206 if( git_status_list_new( &status_list, repo, &status_options ) != GIT_OK )
2215 size_t count = git_status_list_entrycount( status_list );
2216 bool updated =
false;
2218 for(
size_t ii = 0; ii < count; ++ii )
2220 const git_status_entry* entry = git_status_byindex( status_list, ii );
2221 std::string
path( entry->head_to_index? entry->head_to_index->old_file.path
2222 : entry->index_to_workdir->old_file.path );
2224 wxString absPath = repoWorkDir;
2231 wxLogTrace(
traceGit, wxS(
"File '%s' not found in tree cache" ), absPath );
2238 if( entry->status & GIT_STATUS_IGNORED )
2240 wxLogTrace(
traceGit, wxS(
"File '%s' is ignored" ), absPath );
2249 else if( entry->status & ( GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED ) )
2251 wxLogTrace(
traceGit, wxS(
"File '%s' is modified in %s" ),
2252 absPath, ( entry->status & GIT_STATUS_INDEX_MODIFIED )?
"index" :
"working tree" );
2261 else if( entry->status & ( GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW ) )
2263 wxLogTrace(
traceGit, wxS(
"File '%s' is new in %s" ),
2264 absPath, ( entry->status & GIT_STATUS_INDEX_NEW )?
"index" :
"working tree" );
2273 else if( entry->status & ( GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED ) )
2275 wxLogTrace(
traceGit, wxS(
"File '%s' is deleted in %s" ),
2276 absPath, ( entry->status & GIT_STATUS_INDEX_DELETED )?
"index" :
"working tree" );
2285 else if( localChanges.count(
path ) )
2287 wxLogTrace(
traceGit, wxS(
"File '%s' is ahead of remote" ), absPath );
2296 else if( remoteChanges.count(
path ) )
2298 wxLogTrace(
traceGit, wxS(
"File '%s' is behind remote" ), absPath );
2320 git_reference* currentBranchReference =
nullptr;
2321 int rc = git_repository_head( ¤tBranchReference, repo );
2325 if( currentBranchReference )
2329 else if( rc == GIT_EUNBORNBRANCH )
2342 wxLogTrace(
traceGit, wxS(
"updateGitStatusIconMap: Updated git status icons" ) );
2361 if( repo ==
nullptr )
2363 wxMessageBox(
_(
"The selected directory is not a Git project." ) );
2367 git_config*
config =
nullptr;
2368 git_repository_config( &
config, repo );
2372 wxString authorName;
2373 wxString authorEmail;
2376 git_config_entry* name_c =
nullptr;
2377 git_config_entry* email_c =
nullptr;
2378 int authorNameError = git_config_get_entry( &name_c,
config,
"user.name" );
2381 if( authorNameError != 0 || name_c ==
nullptr )
2387 authorName = name_c->value;
2391 int authorEmailError = git_config_get_entry( &email_c,
config,
"user.email" );
2393 if( authorEmailError != 0 || email_c ==
nullptr )
2399 authorEmail = email_c->value;
2403 git_status_options status_options;
2404 git_status_init_options( &status_options, GIT_STATUS_OPTIONS_VERSION );
2405 status_options.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
2406 status_options.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
2408 git_status_list* status_list =
nullptr;
2409 git_status_list_new( &status_list, repo, &status_options );
2412 std::map<wxString, int> modifiedFiles;
2414 size_t count = git_status_list_entrycount( status_list );
2416 std::set<wxString> selected_files;
2420 if( item->GetType() != TREE_FILE_TYPE::DIRECTORY )
2421 selected_files.emplace( item->GetFileName() );
2424 for(
size_t i = 0; i < count; ++i )
2426 const git_status_entry* entry = git_status_byindex( status_list, i );
2429 if( entry->status == GIT_STATUS_CURRENT
2430 || ( entry->status & ( GIT_STATUS_CONFLICTED | GIT_STATUS_IGNORED ) ) )
2441 if( entry->index_to_workdir )
2443 fn.Assign( entry->index_to_workdir->old_file.path );
2444 fn.MakeAbsolute( git_repository_workdir( repo ) );
2445 filePath = wxString( entry->index_to_workdir->old_file.path, wxConvUTF8 );
2447 else if( entry->head_to_index )
2449 fn.Assign( entry->head_to_index->old_file.path );
2450 fn.MakeAbsolute( git_repository_workdir( repo ) );
2451 filePath = wxString( entry->head_to_index->old_file.path, wxConvUTF8 );
2455 wxCHECK2_MSG(
false,
continue,
"File status with neither git_status_entry set!" );
2460 wxString fileName = fn.GetFullPath();
2462 if( !fileName.StartsWith( projectPath ) )
2478 if( fn.GetPath().Contains(
Prj().GetProjectName() + wxT(
"-backups" ) ) )
2483 modifiedFiles.emplace( filePath, entry->status );
2485 else if( selected_files.count( fn.GetFullPath() ) )
2487 modifiedFiles.emplace( filePath, entry->status );
2492 DIALOG_GIT_COMMIT dlg( wxGetTopLevelParent(
this ), repo, authorName, authorEmail,
2496 if( ret != wxID_OK )
2501 git_tree* tree =
nullptr;
2502 git_commit* parent =
nullptr;
2503 git_index* index =
nullptr;
2509 wxMessageBox(
_(
"Discarding commit due to empty commit message." ) );
2515 wxMessageBox(
_(
"Discarding commit due to empty file selection." ) );
2519 if( git_repository_index( &index, repo ) != 0 )
2521 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to get repository index: %s" ),
2528 for( wxString& file : files )
2530 if( git_index_add_bypath( index, file.mb_str() ) != 0 )
2532 wxMessageBox( wxString::Format(
_(
"Failed to add file to index: %s" ),
2538 if( git_index_write( index ) != 0 )
2540 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to write index: %s" ),
2545 if( git_index_write_tree( &tree_id, index ) != 0)
2547 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to write tree: %s" ),
2552 if( git_tree_lookup( &tree, repo, &tree_id ) != 0 )
2554 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to lookup tree: %s" ),
2560 git_reference* headRef =
nullptr;
2562 if( git_repository_head_unborn( repo ) == 0 )
2564 if( git_repository_head( &headRef, repo ) != 0 )
2566 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to get HEAD reference: %s" ),
2573 if( git_reference_peel( (git_object**) &parent, headRef, GIT_OBJECT_COMMIT ) != 0 )
2575 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to get commit: %s" ),
2586 git_signature* author =
nullptr;
2588 if( git_signature_now( &author, author_name.mb_str(), author_email.mb_str() ) != 0 )
2590 wxLogTrace(
traceGit, wxString::Format(
_(
"Failed to create author signature: %s" ),
2598#if( LIBGIT2_VER_MAJOR == 1 && LIBGIT2_VER_MINOR == 8 \
2599 && ( LIBGIT2_VER_REVISION < 2 || LIBGIT2_VER_REVISION == 3 ) )
2618 git_commit*
const parents[1] = { parent };
2621 const git_commit* parents[1] = { parent };
2624 if( git_commit_create( &oid, repo,
"HEAD", author, author,
nullptr, commit_msg.mb_str(), tree,
2627 wxMessageBox( wxString::Format(
_(
"Failed to create commit: %s" ),
2632 wxLogTrace(
traceGit, wxString::Format(
_(
"Created commit with id: %s" ),
2633 git_oid_tostr_s( &oid ) ) );
2655 if( git_repository_index( &index, repo ) != 0 )
2664 if( git_index_find( &entry_pos, index, aFile.mb_str() ) == 0 )
2666 wxLogTrace(
traceGit,
"File already in index: %s", aFile );
2676 wxLogTrace(
traceGit,
"Syncing project" );
2681 wxLogTrace(
traceGit,
"sync: No git repository found" );
2748 wxLogTrace(
traceGit,
"onGitSyncTimer" );
2756 tp.push_task( [
this]()
2762 wxLogTrace(
traceGit,
"onGitSyncTimer: No git repository found" );
2777 wxLogTrace(
traceGit,
"onGitSyncTimer: Restarting git sync timer" );
2798 wxLogTrace(
traceGit,
"onGitStatusTimer" );
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
BITMAP_STORE * GetBitmapStore()
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
wxString GetCommitMessage() const
wxString GetAuthorEmail() const
std::vector< wxString > GetSelectedFiles() const
wxString GetAuthorName() const
KIGIT_COMMON::GIT_CONN_TYPE GetRepoType() const
wxString GetBareRepoURL() const
Get the Bare Repo U R L object.
wxString GetRepoSSHPath() const
wxString GetRepoURL() const
wxString GetUsername() const
wxString GetPassword() const
wxString GetBranchName() const
void SetProgressReporter(std::unique_ptr< WX_PROGRESS_REPORTER > aProgressReporter)
bool PerformFetch(bool aSkipLock=false)
void PerformRemoveFromIndex()
bool PerformResolveConflict()
The main KiCad project manager frame.
wxString m_FileWatcherInfo
PROJECT_TREE_PANE * m_leftWin
const wxString GetProjectFileName() const
void OnChangeWatchedPaths(wxCommandEvent &aEvent)
Called by sending a event with id = ID_INIT_WATCHED_PATHS rebuild the list of watched paths.
void LoadProject(const wxFileName &aProjectFileName)
std::mutex m_gitActionMutex
std::vector< wxString > GetBranchNames() const
static wxString GetLastGitError()
wxString GetGitRootDirectory() const
void SetSSHKey(const wxString &aSSHKey)
void SetUsername(const wxString &aUsername)
std::pair< std::set< wxString >, std::set< wxString > > GetDifferentFiles() const
Return a pair of sets of files that differ locally from the remote repository The first set is files ...
bool HasPushAndPullRemote() const
void UpdateCurrentBranchInfo()
bool HasLocalCommits() const
void SetPassword(const wxString &aPassword)
wxString GetErrorString()
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
void SetEllipsedTextField(const wxString &aText, int aFieldId)
Set the text in a field using wxELLIPSIZE_MIDDLE option to adjust the text size to the field size.
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
wxString m_GitRepoUsername
Handle one item (a file or a directory name) for the tree file.
void SetRootFile(bool aValue)
const wxString & GetFileName() const
void SetPopulated(bool aValue)
TREE_FILE_TYPE GetType() const
const wxString GetDir() const
void Activate(PROJECT_TREE_PANE *aTreePrjFrame)
PROJECT_TREE_PANE Window to display the tree files.
PROJECT_TREE_ITEM * m_selectedItem
std::unordered_map< wxString, wxTreeItemId > m_gitTreeCache
void onGitFetch(wxCommandEvent &event)
Fetch the latest changes from the git repository.
std::map< wxTreeItemId, KIGIT_COMMON::GIT_STATUS > m_gitStatusIcons
void onGitInitializeProject(wxCommandEvent &event)
Initialize a new git repository in the current project directory.
void onGitSyncProject(wxCommandEvent &event)
Sync the current project with the git repository.
void onDeleteFile(wxCommandEvent &event)
Function onDeleteFile Delete the selected file or directory in the tree project.
void onGitRemoveVCS(wxCommandEvent &event)
Remove the git repository from the current project directory.
void EmptyTreePrj()
Delete all m_TreeProject entries.
void FileWatcherReset()
Reinit the watched paths Should be called after opening a new project to rebuild the list of watched ...
wxString m_gitCurrentBranchName
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
void onOpenDirectory(wxCommandEvent &event)
Function onOpenDirectory Handles the right-click menu for opening a directory in the current system f...
void onGitResolveConflict(wxCommandEvent &event)
Resolve conflicts in the git repository.
void onFileSystemEvent(wxFileSystemWatcherEvent &event)
called when a file or directory is modified/created/deleted The tree project is modified when a file ...
wxFileSystemWatcher * m_watcher
void onRight(wxTreeEvent &Event)
Called on a right click on an item.
void onGitCommit(wxCommandEvent &event)
Commit the current project saved changes to the git repository.
void onSelect(wxTreeEvent &Event)
Called on a double click on an item.
PROJECT_TREE * m_TreeProject
KICAD_MANAGER_FRAME * m_Parent
void onExpand(wxTreeEvent &Event)
Called on a click on the + or - button of an item with children.
void onGitSyncTimer(wxTimerEvent &event)
void onIdle(wxIdleEvent &aEvent)
Idle event handler, used process the selected items at a point in time when all other events have bee...
void updateTreeCache()
Updates the map of the wxtreeitemid to the name of each file for use in the thread.
void gitStatusTimerHandler()
std::mutex m_gitStatusMutex
void onGitRevertLocal(wxCommandEvent &event)
Revert the local repository to the last commit.
void onGitPullProject(wxCommandEvent &event)
Pull the latest changes from the git repository.
static wxString GetFileExt(TREE_FILE_TYPE type)
friend class PROJECT_TREE_ITEM
void onGitRemoveFromIndex(wxCommandEvent &event)
Remove a file from the git index.
wxTreeItemId findSubdirTreeItem(const wxString &aSubDir)
Function findSubdirTreeItem searches for the item in tree project which is the node of the subdirecto...
void ReCreateTreePrj()
Create or modify the tree showing project file names.
void onThemeChanged(wxSysColourChangedEvent &aEvent)
void onRunSelectedJobsFile(wxCommandEvent &event)
Run a selected jobs file.
void onGitCompare(wxCommandEvent &event)
Compare the current project to a different branch in the git repository.
void onGitStatusTimer(wxTimerEvent &event)
void shutdownFileWatcher()
Shutdown the file watcher.
std::mutex m_gitTreeCacheMutex
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
bool hasChangedFiles()
Returns true if the current project has any uncommitted changes.
void onOpenSelectedFileWithTextEditor(wxCommandEvent &event)
Function onOpenSelectedFileWithTextEditor Call the text editor to open the selected file in the tree ...
void onGitAddToIndex(wxCommandEvent &event)
Add a file to the git index.
void updateGitStatusIcons()
Updates the icons shown in the tree project to reflect the current git status.
bool m_gitIconsInitialized
void updateGitStatusIconMap()
This is a threaded call that will change the map of git status icons for use in the main thread.
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.
void onGitSwitchBranch(wxCommandEvent &event)
Switch to a different branch in the git repository.
void onCreateNewDirectory(wxCommandEvent &event)
Function onCreateNewDirectory Creates a new subdirectory inside the current kicad project directory t...
void onSwitchToSelectedProject(wxCommandEvent &event)
Switch to a other project selected from the tree project (by selecting an other .pro file inside the ...
void onPaint(wxPaintEvent &aEvent)
We don't have uniform borders so we have to draw them ourselves.
void onRenameFile(wxCommandEvent &event)
Function onRenameFile Rename the selected file or directory in the tree project.
void onGitPushProject(wxCommandEvent &event)
Push the current project changes to the git repository.
bool canFileBeAddedToVCS(const wxString &aFilePath)
Returns true if the file has already been added to the repository or false if it has not been added y...
std::vector< wxString > m_filters
PROJECT_TREE This is the class to show (as a tree) the files in the project directory.
git_repository * GetGitRepo() const
KIGIT_COMMON * GitCommon() const
void SetGitRepo(git_repository *aRepo)
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
bool RmDirRecursive(const wxString &aFileName, wxString *aErrors)
Remove the directory aDirName and all its contents including subdirectories and their files.
int m_GitIconRefreshInterval
The interval in milliseconds to refresh the git icons in the project tree.
static const std::string LegacySchematicFileExtension
static const std::string HtmlFileExtension
static const wxString GerberFileExtensionsRegex
static const std::string NetlistFileExtension
static const std::string GerberJobFileExtension
static const std::string ReportFileExtension
static const std::string LockFileExtension
static const std::string ProjectFileExtension
static const std::string FootprintPlaceFileExtension
static const std::string LegacyPcbFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LegacySymbolLibFileExtension
static const std::string LockFilePrefix
static const std::string KiCadSymbolLibFileExtension
static const std::string SpiceFileExtension
static const std::string PdfFileExtension
static const std::string TextFileExtension
static const std::string DrawingSheetFileExtension
static const std::string BackupFileSuffix
static const std::string AutoSaveFilePrefix
static const std::string KiCadJobSetFileExtension
static const std::string FootprintAssignmentFileExtension
static const std::string SVGFileExtension
static const std::string DrillFileExtension
static const std::string DesignRulesFileExtension
static const std::string MarkdownFileExtension
static const std::string KiCadFootprintFileExtension
static const std::string ArchiveFileExtension
static const std::string KiCadPcbFileExtension
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
const wxChar *const traceGit
Flag to enable Git debugging output.
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
std::unique_ptr< git_object, decltype([](git_object *aObject) { git_object_free(aObject) GitObjectPtr
A unique pointer for git_object objects with automatic cleanup.
std::unique_ptr< git_status_list, decltype([](git_status_list *aList) { git_status_list_free(aList) GitStatusListPtr
A unique pointer for git_status_list objects with automatic cleanup.
std::unique_ptr< git_commit, decltype([](git_commit *aCommit) { git_commit_free(aCommit) GitCommitPtr
A unique pointer for git_commit objects with automatic cleanup.
std::unique_ptr< git_buf, decltype([](git_buf *aBuf) { git_buf_free(aBuf) GitBufPtr
A unique pointer for git_buf objects with automatic cleanup.
std::unique_ptr< git_tree, decltype([](git_tree *aTree) { git_tree_free(aTree) GitTreePtr
A unique pointer for git_tree objects with automatic cleanup.
std::unique_ptr< git_config_entry, decltype([](git_config_entry *aEntry) { git_config_entry_free(aEntry) GitConfigEntryPtr
A unique pointer for git_config_entry objects with automatic cleanup.
std::unique_ptr< git_index, decltype([](git_index *aIndex) { git_index_free(aIndex) GitIndexPtr
A unique pointer for git_index objects with automatic cleanup.
std::unique_ptr< git_signature, decltype([](git_signature *aSignature) { git_signature_free(aSignature) GitSignaturePtr
A unique pointer for git_signature objects with automatic cleanup.
std::unique_ptr< git_repository, decltype([](git_repository *aRepo) { git_repository_free(aRepo) GitRepositoryPtr
A unique pointer for git_repository objects with automatic cleanup.
std::unique_ptr< git_config, decltype([](git_config *aConfig) { git_config_free(aConfig) GitConfigPtr
A unique pointer for git_config objects with automatic cleanup.
std::unique_ptr< git_reference, decltype([](git_reference *aRef) { git_reference_free(aRef) GitReferencePtr
A unique pointer for git_reference objects with automatic cleanup.
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
PGM_BASE & Pgm()
The global program "get" accessor.
#define NAMELESS_PROJECT
default name for nameless projects
project_tree_ids
The frame that shows the tree list of files and subdirectories inside the working directory.
@ ID_PROJECT_SWITCH_TO_OTHER
@ ID_GIT_REMOVE_FROM_INDEX
@ ID_GIT_RESOLVE_CONFLICT
@ ID_GIT_INITIALIZE_PROJECT
std::vector< wxString > getProjects(const wxDir &dir)
static git_repository * get_git_repository_for_file(const char *filename)
static const wxChar * s_allowedExtensionsToList[]
static int git_create_branch(git_repository *aRepo, wxString &aBranchName)
wxDECLARE_EVENT(UPDATE_ICONS, wxCommandEvent)
#define wxFileSystemWatcher
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.