29 #include <wx/stdpaths.h> 30 #include <wx/string.h> 67 wxT(
"^.*\\.kicad_pro$" ),
70 wxT(
"^.*\\.kicad_sch$" ),
71 wxT(
"^[^$].*\\.brd$" ),
72 wxT(
"^[^$].*\\.kicad_pcb$" ),
73 wxT(
"^[^$].*\\.kicad_dru$" ),
74 wxT(
"^[^$].*\\.kicad_wks$" ),
75 wxT(
"^[^$].*\\.kicad_mod$" ),
79 wxT(
"^.*\\.kicad_sym$" ),
83 wxT(
"^.*\\.gbrjob$" ),
84 wxT(
"^.*\\.gb[alops]$" ),
85 wxT(
"^.*\\.gt[alops]$" ),
86 wxT(
"^.*\\.g[0-9]{1,2}$" ),
138 wxSashLayoutWindow( parent,
ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize,
139 wxNO_BORDER | wxTAB_TRAVERSAL )
142 m_TreeProject =
NULL;
143 m_isRenaming =
false;
144 m_selectedItem =
nullptr;
145 m_watcherNeedReset =
false;
148 Connect( wxEVT_FSWATCHER,
158 m_filters.emplace_back( wxT(
"^no KiCad files found" ) );
179 if( tree_data.size() != 1 )
182 wxString prj_filename = tree_data[0]->GetFileName();
196 wxString curr_dir = item_data->GetDir();
198 if( curr_dir.IsEmpty() )
204 if( curr_dir.IsEmpty() || !wxFileName::DirExists( curr_dir ) )
207 if( !curr_dir.IsEmpty() )
208 curr_dir += wxFileName::GetPathSeparator();
215 msg.Printf(
"open \"%s\"", curr_dir );
217 system( msg.c_str() );
219 #if !wxCHECK_VERSION( 3, 1, 0 ) 227 wxLaunchDefaultApplication( curr_dir );
243 wxString curr_dir = item_data->GetDir();
245 if( curr_dir.IsEmpty() )
248 wxString new_dir = wxGetTextFromUser(
_(
"Directory name:" ),
_(
"Create New Directory" ) );
250 if( new_dir.IsEmpty() )
253 wxString full_dirname = curr_dir + wxFileName::GetPathSeparator() + new_dir;
255 wxMkdir( full_dirname );
289 default:
return wxEmptyString;
296 std::vector<wxString> projects;
297 wxString dir_filename;
298 bool haveFile = dir.GetFirst( &dir_filename );
302 wxFileName file( dir_filename );
305 projects.push_back( file.GetName() );
307 haveFile = dir.GetNext( &dir_filename );
315 const wxTreeItemId& aParent,
316 std::vector<wxString>* aProjectNames,
320 wxFileName fn( aName );
324 if( fn.GetName().StartsWith( wxT(
"." ) ) )
325 return wxTreeItemId();
327 if( wxDirExists( aName ) )
335 bool addFile =
false;
337 for(
const wxString& m_filter :
m_filters )
339 wxCHECK2_MSG( reg.Compile( m_filter, wxRE_ICASE ),
continue,
342 if( reg.Matches( aName ) )
350 return wxTreeItemId();
357 if( ext == wxT(
"" ) )
364 reg.Compile( wxString::FromAscii(
"^.*\\." ) + ext + wxString::FromAscii(
"$" ),
367 if( reg.Matches( aName ) )
375 wxString file = wxFileNameFromPath( aName );
376 wxFileName currfile( file );
381 && ( currfile.GetName().CmpNoCase( project.GetName() ) == 0 ) )
383 return wxTreeItemId();
392 return wxTreeItemId();
397 wxDir parentDir( parentTreeItem->
GetDir() );
398 std::vector<wxString> projects =
getProjects( parentDir );
401 return wxTreeItemId();
406 wxTreeItemIdValue cookie;
407 wxTreeItemId kid =
m_TreeProject->GetFirstChild( aParent, cookie );
414 return itemData->GetId();
433 if( fname.GetName().CmpNoCase( currfile.GetName() ) == 0 )
439 return wxTreeItemId();
445 return wxTreeItemId();
472 wxTreeItemId newItemId =
m_TreeProject->AppendItem( aParent, file );
479 wxString fileName = currfile.GetName().Lower();
480 wxString projName = project.GetName().Lower();
481 data->
SetRootFile( fileName == projName || fileName.StartsWith( projName +
"-" ) );
484 bool subdir_populated =
false;
495 std::vector<wxString> projects =
getProjects( dir );
496 wxString dir_filename;
497 bool haveFile = dir.GetFirst( &dir_filename );
501 subdir_populated = aRecurse;
507 wxString path = aName + wxFileName::GetPathSeparator() + dir_filename;
510 haveFile = dir.GetNext( &dir_filename );
519 if( subdir_populated )
539 wxFileName fn = pro_dir;
540 bool prjReset =
false;
551 bool prjOpened = fn.FileExists();
555 if( !prjOpened && !prjReset )
558 prjOpened = fn.FileExists();
577 wxDir dir( pro_dir );
581 std::vector<wxString> projects =
getProjects( dir );
583 bool haveFile = dir.GetFirst( &filename );
587 if( filename != fn.GetFullName() )
589 wxString
name = dir.GetName() + wxFileName::GetPathSeparator() + filename;
595 haveFile = dir.GetNext( &filename );
613 wxTreeItemId curr_item = Event.GetItem();
620 bool can_switch_to_project =
true;
621 bool can_create_new_directory =
true;
622 bool can_open_this_directory =
true;
623 bool can_edit =
true;
624 bool can_rename =
true;
625 bool can_delete =
true;
626 bool can_print =
true;
628 if( selection.size() == 0 )
632 if( selection.size() != 1 )
634 can_switch_to_project =
false;
635 can_create_new_directory =
false;
645 can_switch_to_project =
false;
652 wxString full_file_name = item->GetFileName();
654 switch( item->GetType() )
663 can_switch_to_project =
false;
668 can_create_new_directory =
false;
669 can_open_this_directory =
false;
674 can_switch_to_project =
false;
681 can_switch_to_project =
false;
682 can_create_new_directory =
false;
683 can_open_this_directory =
false;
696 if( can_switch_to_project )
699 _(
"Switch to this Project" ),
700 _(
"Close all editors, and switch to the selected project" ),
702 popup_menu.AppendSeparator();
705 if( can_create_new_directory )
711 if( can_open_this_directory )
713 if( selection.size() == 1 )
716 text =
_(
"Reveal in Finder" );
717 help_text =
_(
"Reveals the directory in a Finder window" );
719 text =
_(
"Open Directory in File Explorer" );
720 help_text =
_(
"Opens the directory in the default system file manager" );
726 text =
_(
"Reveal in Finder" );
727 help_text =
_(
"Reveals the directories in a Finder window" );
729 text =
_(
"Open Directories in File Explorer" );
730 help_text =
_(
"Opens the directories in the default system file manager" );
740 if( selection.size() == 1 )
741 help_text =
_(
"Open the file in a Text Editor" );
743 help_text =
_(
"Open files in a Text Editor" );
751 if( selection.size() == 1 )
753 text =
_(
"Rename File..." );
754 help_text =
_(
"Rename file" );
758 text =
_(
"Rename Files..." );
759 help_text =
_(
"Rename files" );
767 if( selection.size() == 1 )
768 help_text =
_(
"Delete the file and its content" );
770 help_text =
_(
"Delete the files and their contents" );
772 if( can_switch_to_project
773 || can_create_new_directory
774 || can_open_this_directory
778 popup_menu.AppendSeparator();
787 popup_menu.AppendSeparator();
797 if( popup_menu.GetMenuItemCount() > 0 )
798 PopupMenu( &popup_menu );
804 wxString editorname =
Pgm().GetEditorName();
806 if( editorname.IsEmpty() )
815 wxString fullFileName = item_data->GetFileName();
818 if( !files.IsEmpty() )
821 files += fullFileName;
831 wxString msg, caption;
833 if( tree_data.size() == 1 )
835 bool is_directory = wxDirExists( tree_data[0]->GetFileName() );
836 caption = is_directory ?
_(
"Delete Directory" ) :
_(
"Delete File" );
838 tree_data[0]->GetFileName() );
844 caption =
_(
"Delete Multiple Items" );
847 wxMessageDialog dialog( m_parent, msg, caption, wxYES_NO | wxICON_QUESTION );
849 if( dialog.ShowModal() == wxID_YES )
872 if( tree_data.size() != 1 )
877 tree_data[0]->GetFileName() );
878 wxTextEntryDialog dlg(
this, msg,
_(
"Change filename" ), buffer );
880 if( dlg.ShowModal() != wxID_OK )
883 buffer = dlg.GetValue();
885 buffer.Trim(
false );
887 if( buffer.IsEmpty() )
890 tree_data[0]->Rename( buffer,
true );
899 if( tree_data.size() != 1 )
933 wxTreeItemId itemId = Event.GetItem();
943 wxTreeItemIdValue cookie;
944 wxTreeItemId kid =
m_TreeProject->GetFirstChild( itemId, cookie );
947 bool subdir_populated =
false;
950 for( ; kid.IsOk(); kid =
m_TreeProject->GetNextChild( itemId, cookie ) )
961 wxDir dir( fileName );
965 std::vector<wxString> projects =
getProjects( dir );
966 wxString dir_filename;
967 bool haveFile = dir.GetFirst( &dir_filename );
972 wxString
name = fileName + wxFileName::GetPathSeparator() + dir_filename;
975 haveFile = dir.GetNext( &dir_filename );
980 subdir_populated =
true;
989 if( subdir_populated )
997 wxArrayTreeItemIds selection;
998 std::vector<PROJECT_TREE_ITEM*> data;
1002 for(
auto it = selection.begin(); it != selection.end(); it++ )
1011 return dynamic_cast<PROJECT_TREE_ITEM*>(
m_TreeProject->GetItemData( aId ) );
1021 if( prj_dir == aSubDir )
1025 wxTreeItemIdValue cookie;
1026 wxTreeItemId root_id =
m_root;
1027 std::stack < wxTreeItemId > subdirs_id;
1029 wxTreeItemId kid =
m_TreeProject->GetFirstChild( root_id, cookie );
1035 if( subdirs_id.empty() )
1042 root_id = subdirs_id.top();
1063 subdirs_id.push( kid );
1075 const wxFileName& pathModified =
event.GetPath();
1076 wxString subdir = pathModified.GetPath();
1077 wxString fn = pathModified.GetFullPath();
1079 switch( event.GetChangeType() )
1081 case wxFSW_EVENT_DELETE:
1082 case wxFSW_EVENT_CREATE:
1083 case wxFSW_EVENT_RENAME:
1086 case wxFSW_EVENT_MODIFY:
1087 case wxFSW_EVENT_ACCESS:
1094 if( !root_id.IsOk() )
1097 wxTreeItemIdValue cookie;
1098 wxTreeItemId kid =
m_TreeProject->GetFirstChild( root_id, cookie );
1100 switch( event.GetChangeType() )
1102 case wxFSW_EVENT_CREATE:
1118 case wxFSW_EVENT_DELETE:
1132 case wxFSW_EVENT_RENAME :
1134 const wxFileName& newpath =
event.GetNewPath();
1135 wxString newdir = newpath.GetPath();
1136 wxString newfn = newpath.GetFullPath();
1160 if( newpath.Exists() && ( newfn != rootData->
GetFileName() ) )
1166 if( newitem.IsOk() )
1186 #if defined( _WIN32 ) 1193 m_Parent->SetStatusText(
_(
"Network path: not monitoring folder changes" ), 1 );
1198 m_Parent->SetStatusText(
_(
"Local path: monitoring folder changes" ), 1 );
1215 fn.AssignDir( prj_dir );
1216 fn.DontFollowLink();
1233 wxTreeItemIdValue cookie;
1234 wxTreeItemId root_id =
m_root;
1236 std::stack < wxTreeItemId > subdirs_id;
1238 wxTreeItemId kid =
m_TreeProject->GetFirstChild( root_id, cookie );
1244 if( subdirs_id.empty() )
1250 root_id = subdirs_id.top();
1268 if( wxFileName::IsDirReadable( path ) )
1270 fn.AssignDir( path );
1275 subdirs_id.push( kid );
1283 #if defined(DEBUG) && 1 1284 wxArrayString paths;
1288 for(
unsigned ii = 0; ii < paths.GetCount(); ii++ )
const std::string NetlistFileExtension
const BITMAP_OPAQUE trash_xpm[1]
const wxString & GetFileName() const
void onRight(wxTreeEvent &Event)
Called on a right click on an item.
void onCreateNewDirectory(wxCommandEvent &event)
Function onCreateNewDirectory Creates a new subdirectory inside the current kicad project directory t...
IDs used in KiCad main frame foe menuitems and tools.
const BITMAP_OPAQUE right_xpm[1]
const wxString GetProjectFileName() const
This file is part of the common library TODO brief description.
const std::string KiCadFootprintFileExtension
void Activate(PROJECT_TREE_PANE *aTreePrjFrame)
const std::string ProjectFileExtension
TREE_FILE_TYPE GetType() const
const std::string LegacyPcbFileExtension
const std::string LegacySymbolLibFileExtension
const BITMAP_OPAQUE editor_xpm[1]
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
void onRenameFile(wxCommandEvent &event)
Function onRenameFile Rename the selected file or directory in the tree project.
wxTreeItemId findSubdirTreeItem(const wxString &aSubDir)
Function findSubdirTreeItem searches for the item in tree project which is the node of the subdirecto...
std::vector< wxString > m_filters
const std::string DesignRulesFileExtension
void SetPopulated(bool aValue)
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
const BITMAP_OPAQUE directory_browser_xpm[1]
const std::string ComponentFileExtension
void onDeleteFile(wxCommandEvent &event)
Function onDeleteFile Delete the selected file or directory in the tree project.
void ReCreateTreePrj()
Create or modify the tree showing project file names.
const std::string KiCadPcbFileExtension
void onOpenSelectedFileWithTextEditor(wxCommandEvent &event)
Function onOpenSelectedFileWithTextEditor Call the text editor to open the selected file in the tree ...
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
PROJECT_TREE_ITEM * m_selectedItem
PROJECT_TREE_PANE * m_leftWin
void onSwitchToSelectedProject(wxCommandEvent &event)
Switch to a other project selected from the tree project (by selecting an other .pro file inside the ...
void onExpand(wxTreeEvent &Event)
Called on a click on the + or - button of an item with children.
This file contains miscellaneous commonly used macros and functions.
PROJECT_TREE_PANE Window to display the tree files.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
const std::string HtmlFileExtension
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
PROJECT_TREE * m_TreeProject
const wxString GerberFileExtensionWildCard(".((gbr|gbrjob|(gb|gt)[alops])|pho)")
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
friend class PROJECT_TREE_ITEM
void OnChangeWatchedPaths(wxCommandEvent &aEvent)
Called by sending a event with id = ID_INIT_WATCHED_PATHS rebuild the list of watched paths.
wxLogTrace helper definitions.
void AddDelimiterString(wxString &string)
Add un " to the start and the end of string (if not already done).
const wxChar TextFileExtension[]
const BITMAP_OPAQUE open_project_xpm[1]
const std::string LegacyProjectFileExtension
const std::string PdfFileExtension
const std::string LegacySchematicFileExtension
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
const std::string PageLayoutDescrFileExtension
const BITMAP_OPAQUE directory_xpm[1]
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
void onIdle(wxIdleEvent &aEvent)
Idle event handler, used process the selected items at a point in time when all other events have bee...
static const wxChar * s_allowedExtensionsToList[]
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
const wxString GetDir() const
const std::string ReportFileExtension
void FileWatcherReset()
Reinit the watched paths Should be called after opening a new project to rebuild the list of watched ...
void onOpenDirectory(wxCommandEvent &event)
Function onOpenDirectory Handles the right-click menu for opening a directory in the current system f...
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
void EmptyTreePrj()
Delete all m_TreeProject entries.
#define NAMELESS_PROJECT
default name for nameless projects
const std::string KiCadSchematicFileExtension
static wxString GetFileExt(TREE_FILE_TYPE type)
const std::string SVGFileExtension
wxFileSystemWatcher * m_watcher
PROJECT_TREE_ITEM handles one item (a file or a directory name) for the tree file.
const std::string FootprintPlaceFileExtension
void onFileSystemEvent(wxFileSystemWatcherEvent &event)
called when a file or directory is modified/created/deleted The tree project is modified when a file ...
void SetRootFile(bool aValue)
void LoadProject(const wxFileName &aProjectFileName)
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
KICAD_MANAGER_FRAME * m_Parent
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString ¶m, wxProcess *callback)
Call the executable file ExecFile with the command line parameters param.
void onSelect(wxTreeEvent &Event)
Called on a double click on an item.
The main KiCad project manager frame.
bool CanPrintFile(const wxString &file)
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.
std::vector< wxString > getProjects(const wxDir &dir)
const std::string DrillFileExtension
const std::string KiCadSymbolLibFileExtension
PROJECT_TREE This is the class to show (as a tree) the files in the project directory.
void onPrintFile(wxCommandEvent &event)
Function onDeleteFile Print the selected file or directory in the tree project.