KiCad PCB EDA Suite
PROJECT_TREE_PANE Class Reference

PROJECT_TREE_PANE Window to display the tree files. More...

#include <project_tree_pane.h>

Inheritance diagram for PROJECT_TREE_PANE:

Public Member Functions

 PROJECT_TREE_PANE (KICAD_MANAGER_FRAME *parent)
 The frame that shows the tree list of files and subdirectories inside the working directory. More...
 
 ~PROJECT_TREE_PANE ()
 
void ReCreateTreePrj ()
 Create or modify the tree showing project file names. More...
 
void FileWatcherReset ()
 Reinit the watched paths Should be called after opening a new project to rebuild the list of watched paths. More...
 
void EmptyTreePrj ()
 Delete all m_TreeProject entries. More...
 

Public Attributes

KICAD_MANAGER_FRAMEm_Parent
 
PROJECT_TREEm_TreeProject
 

Protected Member Functions

std::vector< PROJECT_TREE_ITEM * > GetSelectedData ()
 Function GetSelectedData return the item data from item currently selected (highlighted) Note this is not necessary the "clicked" item, because when expanding, collapsing an item this item is not selected. More...
 
PROJECT_TREE_ITEMGetItemIdData (wxTreeItemId aId)
 Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier. More...
 

Static Protected Member Functions

static wxString GetFileExt (TREE_FILE_TYPE type)
 

Private Member Functions

void onSelect (wxTreeEvent &Event)
 Called on a double click on an item. More...
 
void onExpand (wxTreeEvent &Event)
 Called on a click on the + or - button of an item with children. More...
 
void onRight (wxTreeEvent &Event)
 Called on a right click on an item. More...
 
void onOpenSelectedFileWithTextEditor (wxCommandEvent &event)
 Function onOpenSelectedFileWithTextEditor Call the text editor to open the selected file in the tree project. More...
 
void onDeleteFile (wxCommandEvent &event)
 Function onDeleteFile Delete the selected file or directory in the tree project. More...
 
void onRenameFile (wxCommandEvent &event)
 Function onRenameFile Rename the selected file or directory in the tree project. More...
 
void onOpenDirectory (wxCommandEvent &event)
 Function onOpenDirectory Handles the right-click menu for opening a directory in the current system file browser. More...
 
void onCreateNewDirectory (wxCommandEvent &event)
 Function onCreateNewDirectory Creates a new subdirectory inside the current kicad project directory the user is prompted to enter a directory name. More...
 
void onSwitchToSelectedProject (wxCommandEvent &event)
 Switch to a other project selected from the tree project (by selecting an other .pro file inside the current project folder) More...
 
void onIdle (wxIdleEvent &aEvent)
 Idle event handler, used process the selected items at a point in time when all other events have been consumed. More...
 
void onPaint (wxPaintEvent &aEvent)
 We don't have uniform borders so we have to draw them ourselves. More...
 
void shutdownFileWatcher ()
 Shutdown the file watcher. More...
 
wxTreeItemId addItemToProjectTree (const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
 Function addItemToProjectTree. More...
 
wxTreeItemId findSubdirTreeItem (const wxString &aSubDir)
 Function findSubdirTreeItem searches for the item in tree project which is the node of the subdirectory aSubDir. More...
 
void onFileSystemEvent (wxFileSystemWatcherEvent &event)
 called when a file or directory is modified/created/deleted The tree project is modified when a file or directory is created/deleted/renamed to reflect the file change More...
 
void onThemeChanged (wxSysColourChangedEvent &aEvent)
 

Private Attributes

bool m_isRenaming
 
wxTreeItemId m_root
 
std::vector< wxString > m_filters
 
wxFileSystemWatcher * m_watcher
 
PROJECT_TREE_ITEMm_selectedItem
 
bool m_watcherNeedReset
 

Friends

class PROJECT_TREE_ITEM
 

Detailed Description

PROJECT_TREE_PANE Window to display the tree files.

Definition at line 48 of file project_tree_pane.h.

Constructor & Destructor Documentation

◆ PROJECT_TREE_PANE()

PROJECT_TREE_PANE::PROJECT_TREE_PANE ( KICAD_MANAGER_FRAME parent)

The frame that shows the tree list of files and subdirectories inside the working directory.

Files are filtered (see s_allowedExtensionsToList) so only useful files are shown.

Definition at line 139 of file project_tree_pane.cpp.

139  :
140  wxSashLayoutWindow( parent, ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize,
141  wxNO_BORDER | wxTAB_TRAVERSAL )
142 {
143  m_Parent = parent;
144  m_TreeProject = nullptr;
145  m_isRenaming = false;
146  m_selectedItem = nullptr;
147  m_watcherNeedReset = false;
148 
149  m_watcher = nullptr;
150  Connect( wxEVT_FSWATCHER,
151  wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
152 
153  Bind( wxEVT_SYS_COLOUR_CHANGED,
154  wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
155 
156  /*
157  * Filtering is now inverted: the filters are actually used to _enable_ support
158  * for a given file type.
159  */
160  for( int ii = 0; s_allowedExtensionsToList[ii] != nullptr; ii++ )
161  m_filters.emplace_back( s_allowedExtensionsToList[ii] );
162 
163  m_filters.emplace_back( wxT( "^no KiCad files found" ) );
164 
165  ReCreateTreePrj();
166 }
std::vector< wxString > m_filters
void ReCreateTreePrj()
Create or modify the tree showing project file names.
PROJECT_TREE_ITEM * m_selectedItem
PROJECT_TREE * m_TreeProject
static const wxChar * s_allowedExtensionsToList[]
void onThemeChanged(wxSysColourChangedEvent &aEvent)
wxFileSystemWatcher * m_watcher
void onFileSystemEvent(wxFileSystemWatcherEvent &event)
called when a file or directory is modified/created/deleted The tree project is modified when a file ...
KICAD_MANAGER_FRAME * m_Parent

References onFileSystemEvent(), onThemeChanged(), and s_allowedExtensionsToList.

◆ ~PROJECT_TREE_PANE()

PROJECT_TREE_PANE::~PROJECT_TREE_PANE ( )

Definition at line 169 of file project_tree_pane.cpp.

170 {
172 }
void shutdownFileWatcher()
Shutdown the file watcher.

References shutdownFileWatcher().

Member Function Documentation

◆ addItemToProjectTree()

wxTreeItemId PROJECT_TREE_PANE::addItemToProjectTree ( const wxString &  aName,
const wxTreeItemId &  aParent,
std::vector< wxString > *  aProjectNames,
bool  aRecurse 
)
private

Function addItemToProjectTree.

Add the file or directory aName to the project tree

Parameters
aName= the filename or the directory name to add in tree
aParent= the wxTreeItemId item where to add sub tree items
aRecurse= true to add file or subdir names to the current tree item false to stop file add.
Returns
the Id for the new tree item

Definition at line 309 of file project_tree_pane.cpp.

313 {
315  wxFileName fn( aName );
316 
317  // Files/dirs names starting by "." are not visible files under unices.
318  // Skip them also under Windows
319  if( fn.GetName().StartsWith( wxT( "." ) ) )
320  return wxTreeItemId();
321 
322  if( wxDirExists( aName ) )
323  {
325  }
326  else
327  {
328  // Filter
329  wxRegEx reg;
330  bool addFile = false;
331 
332  for( const wxString& m_filter : m_filters )
333  {
334  wxCHECK2_MSG( reg.Compile( m_filter, wxRE_ICASE ), continue,
335  wxString::Format( wxT( "Regex %s failed to compile." ), m_filter ) );
336 
337  if( reg.Matches( aName ) )
338  {
339  addFile = true;
340  break;
341  }
342  }
343 
344  if( !addFile )
345  return wxTreeItemId();
346 
347  for( int i = static_cast<int>( TREE_FILE_TYPE::LEGACY_PROJECT );
348  i < static_cast<int>( TREE_FILE_TYPE::MAX ); i++ )
349  {
350  wxString ext = GetFileExt( (TREE_FILE_TYPE) i );
351 
352  if( ext == wxEmptyString )
353  continue;
354 
355  // For gerber files, the official ext is gbr
356  if( i == static_cast<int>( TREE_FILE_TYPE::GERBER ) )
357  ext = wxT( "gbr" );
358 
359  reg.Compile( wxString::FromAscii( "^.*\\." ) + ext + wxString::FromAscii( "$" ),
360  wxRE_ICASE );
361 
362  if( reg.Matches( aName ) )
363  {
364  type = (TREE_FILE_TYPE) i;
365  break;
366  }
367  }
368  }
369 
370  wxString file = wxFileNameFromPath( aName );
371  wxFileName currfile( file );
372  wxFileName project( m_Parent->GetProjectFileName() );
373 
374  // Ignore legacy projects with the same name as the current project
375  if( ( type == TREE_FILE_TYPE::LEGACY_PROJECT )
376  && ( currfile.GetName().CmpNoCase( project.GetName() ) == 0 ) )
377  {
378  return wxTreeItemId();
379  }
380 
381  if( currfile.GetExt() == GetFileExt( TREE_FILE_TYPE::LEGACY_SCHEMATIC )
382  || currfile.GetExt() == GetFileExt( TREE_FILE_TYPE::SEXPR_SCHEMATIC ) )
383  {
384  if( aProjectNames )
385  {
386  if( !alg::contains( *aProjectNames, currfile.GetName() ) )
387  return wxTreeItemId();
388  }
389  else
390  {
391  PROJECT_TREE_ITEM* parentTreeItem = GetItemIdData( aParent );
392  wxDir parentDir( parentTreeItem->GetDir() );
393  std::vector<wxString> projects = getProjects( parentDir );
394 
395  if( !alg::contains( projects, currfile.GetName() ) )
396  return wxTreeItemId();
397  }
398  }
399 
400  // also check to see if it is already there.
401  wxTreeItemIdValue cookie;
402  wxTreeItemId kid = m_TreeProject->GetFirstChild( aParent, cookie );
403 
404  while( kid.IsOk() )
405  {
406  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
407 
408  if( itemData && itemData->GetFileName() == aName )
409  return itemData->GetId(); // well, we would have added it, but it is already here!
410 
411  kid = m_TreeProject->GetNextChild( aParent, cookie );
412  }
413 
414  // Only show current files if both legacy and current files are present
417  {
418  kid = m_TreeProject->GetFirstChild( aParent, cookie );
419 
420  while( kid.IsOk() )
421  {
422  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
423 
424  if( itemData )
425  {
426  wxFileName fname( itemData->GetFileName() );
427 
428  if( fname.GetName().CmpNoCase( currfile.GetName() ) == 0 )
429  {
430  switch( type )
431  {
433  if( itemData->GetType() == TREE_FILE_TYPE::JSON_PROJECT )
434  return wxTreeItemId();
435 
436  break;
437 
439  if( itemData->GetType() == TREE_FILE_TYPE::SEXPR_SCHEMATIC )
440  return wxTreeItemId();
441 
442  break;
443 
445  if( itemData->GetType() == TREE_FILE_TYPE::LEGACY_PROJECT )
446  m_TreeProject->Delete( kid );
447 
448  break;
449 
451  if( itemData->GetType() == TREE_FILE_TYPE::LEGACY_SCHEMATIC )
452  m_TreeProject->Delete( kid );
453 
454  break;
455 
456  default:
457  break;
458  }
459  }
460  }
461 
462  kid = m_TreeProject->GetNextChild( aParent, cookie );
463  }
464  }
465 
466  // Append the item (only appending the filename not the full path):
467  wxTreeItemId newItemId = m_TreeProject->AppendItem( aParent, file );
468  PROJECT_TREE_ITEM* data = new PROJECT_TREE_ITEM( type, aName, m_TreeProject );
469 
470  m_TreeProject->SetItemData( newItemId, data );
471  data->SetState( 0 );
472 
473  // Mark root files (files which have the same aName as the project)
474  wxString fileName = currfile.GetName().Lower();
475  wxString projName = project.GetName().Lower();
476  data->SetRootFile( fileName == projName || fileName.StartsWith( projName + wxT( "-" ) ) );
477 
478 #ifndef __WINDOWS__
479  bool subdir_populated = false;
480 #endif
481 
482  // This section adds dirs and files found in the subdirs
483  // in this case AddFile is recursive, but for the first level only.
484  if( TREE_FILE_TYPE::DIRECTORY == type && aRecurse )
485  {
486  wxDir dir( aName );
487 
488  if( dir.IsOpened() ) // protected dirs will not open properly.
489  {
490  std::vector<wxString> projects = getProjects( dir );
491  wxString dir_filename;
492  bool haveFile = dir.GetFirst( &dir_filename );
493 
494  data->SetPopulated( true );
495 
496 #ifndef __WINDOWS__
497  subdir_populated = aRecurse;
498 #endif
499 
500  while( haveFile )
501  {
502  // Add name in tree, but do not recurse
503  wxString path = aName + wxFileName::GetPathSeparator() + dir_filename;
504  addItemToProjectTree( path, newItemId, &projects, false );
505 
506  haveFile = dir.GetNext( &dir_filename );
507  }
508  }
509 
510  // Sort filenames by alphabetic order
511  m_TreeProject->SortChildren( newItemId );
512  }
513 
514 #ifndef __WINDOWS__
515  if( subdir_populated )
516  m_watcherNeedReset = true;
517 #endif
518 
519  return newItemId;
520 }
const wxString & GetFileName() const
const wxString GetProjectFileName() const
TREE_FILE_TYPE GetType() const
std::vector< wxString > m_filters
TREE_FILE_TYPE
void SetPopulated(bool aValue)
void SetState(int state)
PROJECT_TREE * m_TreeProject
friend class PROJECT_TREE_ITEM
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
const wxString GetDir() const
static wxString GetFileExt(TREE_FILE_TYPE type)
Handle one item (a file or a directory name) for the tree file.
void SetRootFile(bool aValue)
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
KICAD_MANAGER_FRAME * m_Parent
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.
std::vector< wxString > getProjects(const wxDir &dir)

References alg::contains(), DIRECTORY, Format(), GERBER, PROJECT_TREE_ITEM::GetDir(), GetFileExt(), PROJECT_TREE_ITEM::GetFileName(), GetItemIdData(), KICAD_MANAGER_FRAME::GetProjectFileName(), getProjects(), PROJECT_TREE_ITEM::GetType(), JSON_PROJECT, LEGACY_PROJECT, LEGACY_SCHEMATIC, m_filters, m_Parent, m_TreeProject, m_watcherNeedReset, MAX, path, project, PROJECT_TREE_ITEM, PROJECT_TREE_ITEM::SetPopulated(), PROJECT_TREE_ITEM::SetRootFile(), PROJECT_TREE_ITEM::SetState(), SEXPR_SCHEMATIC, and UNKNOWN.

Referenced by onCreateNewDirectory(), onExpand(), onFileSystemEvent(), and ReCreateTreePrj().

◆ EmptyTreePrj()

void PROJECT_TREE_PANE::EmptyTreePrj ( )

Delete all m_TreeProject entries.

Definition at line 1253 of file project_tree_pane.cpp.

1254 {
1255  // Make sure we don't try to inspect the tree after we've deleted its items.
1257 
1258  m_TreeProject->DeleteAllItems();
1259 }
PROJECT_TREE * m_TreeProject
void shutdownFileWatcher()
Shutdown the file watcher.

References m_TreeProject, and shutdownFileWatcher().

Referenced by KICAD_MANAGER_FRAME::CloseProject().

◆ FileWatcherReset()

void PROJECT_TREE_PANE::FileWatcherReset ( )

Reinit the watched paths Should be called after opening a new project to rebuild the list of watched paths.

Should be called after the main loop event handler is started

Definition at line 1139 of file project_tree_pane.cpp.

1140 {
1141  m_watcherNeedReset = false;
1142 
1143  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
1144 
1145 #if defined( _WIN32 )
1146  if( KIPLATFORM::ENV::IsNetworkPath( prj_dir ) )
1147  {
1148  // Due to a combination of a bug in SAMBA sending bad change event IDs and wxWidgets
1149  // choosing to fault on an invalid event ID instead of sanely ignoring them we need to
1150  // avoid spawning a filewatcher. Unfortunately this punishes corporate environments with
1151  // Windows Server shares :/
1152  m_Parent->SetStatusText( _( "Network path: not monitoring folder changes" ), 1 );
1153  return;
1154  }
1155  else
1156  {
1157  m_Parent->SetStatusText( _( "Local path: monitoring folder changes" ), 1 );
1158  }
1159 #endif
1160 
1161  // Prepare file watcher:
1162  if( m_watcher )
1163  {
1164  m_watcher->RemoveAll();
1165  }
1166  else
1167  {
1168  m_watcher = new wxFileSystemWatcher();
1169  m_watcher->SetOwner( this );
1170  }
1171 
1172  // We can see wxString under a debugger, not a wxFileName
1173  wxFileName fn;
1174  fn.AssignDir( prj_dir );
1175  fn.DontFollowLink();
1176 
1177  // Add directories which should be monitored.
1178  // under windows, we add the curr dir and all subdirs
1179  // under unix, we add only the curr dir and the populated subdirs
1180  // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm
1181  // under unix, the file watcher needs more work to be efficient
1182  // moreover, under wxWidgets 2.9.4, AddTree does not work properly.
1183 #ifdef __WINDOWS__
1184  m_watcher->AddTree( fn );
1185 #else
1186  m_watcher->Add( fn );
1187 
1188  if( m_TreeProject->IsEmpty() )
1189  return;
1190 
1191  // Add subdirs
1192  wxTreeItemIdValue cookie;
1193  wxTreeItemId root_id = m_root;
1194 
1195  std::stack < wxTreeItemId > subdirs_id;
1196 
1197  wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1198 
1199  while( true )
1200  {
1201  if( !kid.IsOk() )
1202  {
1203  if( subdirs_id.empty() ) // all items were explored
1204  {
1205  break;
1206  }
1207  else
1208  {
1209  root_id = subdirs_id.top();
1210  subdirs_id.pop();
1211  kid = m_TreeProject->GetFirstChild( root_id, cookie );
1212 
1213  if( !kid.IsOk() )
1214  continue;
1215  }
1216  }
1217 
1218  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1219 
1220  if( itemData && itemData->GetType() == TREE_FILE_TYPE::DIRECTORY )
1221  {
1222  // we can see wxString under a debugger, not a wxFileName
1223  const wxString& path = itemData->GetFileName();
1224 
1225  wxLogTrace( tracePathsAndFiles, wxT( "%s: add '%s'\n" ), __func__, TO_UTF8( path ) );
1226 
1227  if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir
1228  {
1229  fn.AssignDir( path );
1230  m_watcher->Add( fn );
1231 
1232  // if kid is a subdir, push in list to explore it later
1233  if( itemData->IsPopulated() && m_TreeProject->GetChildrenCount( kid ) )
1234  subdirs_id.push( kid );
1235  }
1236  }
1237 
1238  kid = m_TreeProject->GetNextChild( root_id, cookie );
1239  }
1240 #endif
1241 
1242 #if defined(DEBUG) && 1
1243  wxArrayString paths;
1244  m_watcher->GetWatchedPaths( &paths );
1245  wxLogTrace( tracePathsAndFiles, wxT( "%s: watched paths:" ), __func__ );
1246 
1247  for( unsigned ii = 0; ii < paths.GetCount(); ii++ )
1248  wxLogTrace( tracePathsAndFiles, wxT( " %s\n" ), TO_UTF8( paths[ii] ) );
1249 #endif
1250 }
const wxString & GetFileName() const
const wxString GetProjectFileName() const
bool IsPopulated() const
TREE_FILE_TYPE GetType() const
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
PROJECT_TREE * m_TreeProject
#define _(s)
bool IsNetworkPath(const wxString &aPath)
Determines if a given path is a network shared file apth On Windows for example, any form of path is ...
wxFileSystemWatcher * m_watcher
Handle one item (a file or a directory name) for the tree file.
KICAD_MANAGER_FRAME * m_Parent
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.

References _, DIRECTORY, PROJECT_TREE_ITEM::GetFileName(), GetItemIdData(), KICAD_MANAGER_FRAME::GetProjectFileName(), PROJECT_TREE_ITEM::GetType(), KIPLATFORM::ENV::IsNetworkPath(), PROJECT_TREE_ITEM::IsPopulated(), m_Parent, m_root, m_TreeProject, m_watcher, m_watcherNeedReset, path, TO_UTF8, and tracePathsAndFiles.

Referenced by KICAD_MANAGER_FRAME::OnChangeWatchedPaths(), and onIdle().

◆ findSubdirTreeItem()

wxTreeItemId PROJECT_TREE_PANE::findSubdirTreeItem ( const wxString &  aSubDir)
private

Function findSubdirTreeItem searches for the item in tree project which is the node of the subdirectory aSubDir.

Parameters
aSubDir= the directory to find in tree
Returns
the opaque reference to the tree item; if not found, return an invalid tree item so that wxTreeItemId::IsOk() can be used to test the returned value

Definition at line 970 of file project_tree_pane.cpp.

971 {
972  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
973 
974  // If the subdir is the current working directory, return m_root
975  // in main list:
976  if( prj_dir == aSubDir )
977  return m_root;
978 
979  // The subdir is in the main tree or in a subdir: Locate it
980  wxTreeItemIdValue cookie;
981  wxTreeItemId root_id = m_root;
982  std::stack<wxTreeItemId> subdirs_id;
983 
984  wxTreeItemId child = m_TreeProject->GetFirstChild( root_id, cookie );
985 
986  while( true )
987  {
988  if( ! child.IsOk() )
989  {
990  if( subdirs_id.empty() ) // all items were explored
991  {
992  root_id = child; // Not found: return an invalid wxTreeItemId
993  break;
994  }
995  else
996  {
997  root_id = subdirs_id.top();
998  subdirs_id.pop();
999  child = m_TreeProject->GetFirstChild( root_id, cookie );
1000 
1001  if( !child.IsOk() )
1002  continue;
1003  }
1004  }
1005 
1006  PROJECT_TREE_ITEM* itemData = GetItemIdData( child );
1007 
1008  if( itemData && ( itemData->GetType() == TREE_FILE_TYPE::DIRECTORY ) )
1009  {
1010  if( itemData->GetFileName() == aSubDir ) // Found!
1011  {
1012  root_id = child;
1013  break;
1014  }
1015 
1016  // child is a subdir, push in list to explore it later
1017  if( itemData->IsPopulated() )
1018  subdirs_id.push( child );
1019  }
1020 
1021  child = m_TreeProject->GetNextChild( root_id, cookie );
1022  }
1023 
1024  return root_id;
1025 }
const wxString & GetFileName() const
const wxString GetProjectFileName() const
bool IsPopulated() const
TREE_FILE_TYPE GetType() const
PROJECT_TREE * m_TreeProject
Handle one item (a file or a directory name) for the tree file.
KICAD_MANAGER_FRAME * m_Parent
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.

References DIRECTORY, PROJECT_TREE_ITEM::GetFileName(), GetItemIdData(), KICAD_MANAGER_FRAME::GetProjectFileName(), PROJECT_TREE_ITEM::GetType(), PROJECT_TREE_ITEM::IsPopulated(), m_Parent, m_root, and m_TreeProject.

Referenced by onFileSystemEvent().

◆ GetFileExt()

wxString PROJECT_TREE_PANE::GetFileExt ( TREE_FILE_TYPE  type)
staticprotected

Definition at line 256 of file project_tree_pane.cpp.

257 {
258  switch( type )
259  {
276  case TREE_FILE_TYPE::DRILL_NC: return wxT( "nc" );
277  case TREE_FILE_TYPE::DRILL_XNC: return wxT( "xnc" );
284  default: return wxEmptyString;
285  }
286 }
const std::string NetlistFileExtension
const std::string KiCadFootprintFileExtension
const std::string ProjectFileExtension
const std::string LegacyPcbFileExtension
const std::string LegacySymbolLibFileExtension
const wxString GerberFileExtensionWildCard(wxT(".((gbr|gbrjob|(gb|gt)[alops])|pho)"))
const std::string DesignRulesFileExtension
const std::string KiCadPcbFileExtension
const std::string HtmlFileExtension
const std::string FootprintAssignmentFileExtension
const std::string GerberJobFileExtension
const std::string LegacyProjectFileExtension
const std::string PdfFileExtension
const std::string TextFileExtension
const std::string LegacySchematicFileExtension
const std::string DrawingSheetFileExtension
const std::string ReportFileExtension
const std::string KiCadSchematicFileExtension
const std::string SVGFileExtension
const std::string FootprintPlaceFileExtension
const std::string DrillFileExtension
const std::string KiCadSymbolLibFileExtension

References CMP_LINK, DESIGN_RULES, DesignRulesFileExtension, DRAWING_SHEET, DrawingSheetFileExtension, DRILL, DRILL_NC, DRILL_XNC, DrillFileExtension, FOOTPRINT_FILE, FootprintAssignmentFileExtension, FootprintPlaceFileExtension, FP_PLACE, GERBER, GERBER_JOB_FILE, GerberFileExtensionWildCard(), GerberJobFileExtension, HTML, HtmlFileExtension, JSON_PROJECT, KiCadFootprintFileExtension, KiCadPcbFileExtension, KiCadSchematicFileExtension, KiCadSymbolLibFileExtension, LEGACY_PCB, LEGACY_PROJECT, LEGACY_SCHEMATIC, LegacyPcbFileExtension, LegacyProjectFileExtension, LegacySchematicFileExtension, LegacySymbolLibFileExtension, NET, NetlistFileExtension, PDF, PdfFileExtension, ProjectFileExtension, REPORT, ReportFileExtension, SCHEMATIC_LIBFILE, SEXPR_PCB, SEXPR_SCHEMATIC, SEXPR_SYMBOL_LIB_FILE, SVG, SVGFileExtension, TextFileExtension, and TXT.

Referenced by addItemToProjectTree(), and PROJECT_TREE_ITEM::Rename().

◆ GetItemIdData()

PROJECT_TREE_ITEM * PROJECT_TREE_PANE::GetItemIdData ( wxTreeItemId  aId)
protected

Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.

Parameters
aId= the wxTreeItemId identifier.
Returns
a PROJECT_TREE_ITEM pointer corresponding to item id aId

Definition at line 964 of file project_tree_pane.cpp.

965 {
966  return dynamic_cast<PROJECT_TREE_ITEM*>( m_TreeProject->GetItemData( aId ) );
967 }
PROJECT_TREE * m_TreeProject

References m_TreeProject.

Referenced by addItemToProjectTree(), FileWatcherReset(), findSubdirTreeItem(), GetSelectedData(), onExpand(), and onFileSystemEvent().

◆ GetSelectedData()

std::vector< PROJECT_TREE_ITEM * > PROJECT_TREE_PANE::GetSelectedData ( )
protected

Function GetSelectedData return the item data from item currently selected (highlighted) Note this is not necessary the "clicked" item, because when expanding, collapsing an item this item is not selected.

Definition at line 950 of file project_tree_pane.cpp.

951 {
952  wxArrayTreeItemIds selection;
953  std::vector<PROJECT_TREE_ITEM*> data;
954 
955  m_TreeProject->GetSelections( selection );
956 
957  for( auto it = selection.begin(); it != selection.end(); it++ )
958  data.push_back( GetItemIdData( *it ) );
959 
960  return data;
961 }
PROJECT_TREE * m_TreeProject
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.

References GetItemIdData(), and m_TreeProject.

Referenced by onCreateNewDirectory(), onDeleteFile(), onOpenDirectory(), onOpenSelectedFileWithTextEditor(), onRenameFile(), onRight(), onSelect(), and onSwitchToSelectedProject().

◆ onCreateNewDirectory()

void PROJECT_TREE_PANE::onCreateNewDirectory ( wxCommandEvent &  event)
private

Function onCreateNewDirectory Creates a new subdirectory inside the current kicad project directory the user is prompted to enter a directory name.

Definition at line 228 of file project_tree_pane.cpp.

229 {
230  // Get the root directory name:
231  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
232 
233  for( PROJECT_TREE_ITEM* item_data : tree_data )
234  {
235  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
236 
237  // Ask for the new sub directory name
238  wxString curr_dir = item_data->GetDir();
239 
240  if( curr_dir.IsEmpty() )
241  curr_dir = prj_dir;
242 
243  wxString new_dir = wxGetTextFromUser( _( "Directory name:" ), _( "Create New Directory" ) );
244 
245  if( new_dir.IsEmpty() )
246  return;
247 
248  wxString full_dirname = curr_dir + wxFileName::GetPathSeparator() + new_dir;
249 
250  wxMkdir( full_dirname );
251  addItemToProjectTree( full_dirname, item_data->GetId(), nullptr, false );
252  }
253 }
const wxString GetProjectFileName() const
#define _(s)
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
Handle one item (a file or a directory name) for the tree file.
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
KICAD_MANAGER_FRAME * m_Parent

References _, addItemToProjectTree(), KICAD_MANAGER_FRAME::GetProjectFileName(), GetSelectedData(), and m_Parent.

◆ onDeleteFile()

void PROJECT_TREE_PANE::onDeleteFile ( wxCommandEvent &  event)
private

Function onDeleteFile Delete the selected file or directory in the tree project.

Definition at line 811 of file project_tree_pane.cpp.

812 {
813  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
814 
815  for( PROJECT_TREE_ITEM* item_data : tree_data )
816  item_data->Delete();
817 }
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
Handle one item (a file or a directory name) for the tree file.

References GetSelectedData().

◆ onExpand()

void PROJECT_TREE_PANE::onExpand ( wxTreeEvent &  Event)
private

Called on a click on the + or - button of an item with children.

Definition at line 885 of file project_tree_pane.cpp.

886 {
887  wxTreeItemId itemId = Event.GetItem();
888  PROJECT_TREE_ITEM* tree_data = GetItemIdData( itemId );
889 
890  if( !tree_data )
891  return;
892 
893  if( tree_data->GetType() != TREE_FILE_TYPE::DIRECTORY )
894  return;
895 
896  // explore list of non populated subdirs, and populate them
897  wxTreeItemIdValue cookie;
898  wxTreeItemId kid = m_TreeProject->GetFirstChild( itemId, cookie );
899 
900 #ifndef __WINDOWS__
901  bool subdir_populated = false;
902 #endif
903 
904  for( ; kid.IsOk(); kid = m_TreeProject->GetNextChild( itemId, cookie ) )
905  {
906  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
907 
908  if( !itemData || itemData->GetType() != TREE_FILE_TYPE::DIRECTORY )
909  continue;
910 
911  if( itemData->IsPopulated() )
912  continue;
913 
914  wxString fileName = itemData->GetFileName();
915  wxDir dir( fileName );
916 
917  if( dir.IsOpened() )
918  {
919  std::vector<wxString> projects = getProjects( dir );
920  wxString dir_filename;
921  bool haveFile = dir.GetFirst( &dir_filename );
922 
923  while( haveFile )
924  {
925  // Add name to tree item, but do not recurse in subdirs:
926  wxString name = fileName + wxFileName::GetPathSeparator() + dir_filename;
927  addItemToProjectTree( name, kid, &projects, false );
928 
929  haveFile = dir.GetNext( &dir_filename );
930  }
931 
932  itemData->SetPopulated( true ); // set state to populated
933 
934 #ifndef __WINDOWS__
935  subdir_populated = true;
936 #endif
937  }
938 
939  // Sort filenames by alphabetic order
940  m_TreeProject->SortChildren( kid );
941  }
942 
943 #ifndef __WINDOWS__
944  if( subdir_populated )
945  m_watcherNeedReset = true;
946 #endif
947 }
const wxString & GetFileName() const
bool IsPopulated() const
TREE_FILE_TYPE GetType() const
void SetPopulated(bool aValue)
PROJECT_TREE * m_TreeProject
const char * name
Definition: DXF_plotter.cpp:56
Handle one item (a file or a directory name) for the tree file.
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.
std::vector< wxString > getProjects(const wxDir &dir)

References addItemToProjectTree(), DIRECTORY, PROJECT_TREE_ITEM::GetFileName(), GetItemIdData(), getProjects(), PROJECT_TREE_ITEM::GetType(), PROJECT_TREE_ITEM::IsPopulated(), m_TreeProject, m_watcherNeedReset, name, and PROJECT_TREE_ITEM::SetPopulated().

◆ onFileSystemEvent()

void PROJECT_TREE_PANE::onFileSystemEvent ( wxFileSystemWatcherEvent &  event)
private

called when a file or directory is modified/created/deleted The tree project is modified when a file or directory is created/deleted/renamed to reflect the file change

Definition at line 1028 of file project_tree_pane.cpp.

1029 {
1030  // No need to process events when we're shutting down
1031  if( !m_watcher )
1032  return;
1033 
1034  const wxFileName& pathModified = event.GetPath();
1035  wxString subdir = pathModified.GetPath();
1036  wxString fn = pathModified.GetFullPath();
1037 
1038  switch( event.GetChangeType() )
1039  {
1040  case wxFSW_EVENT_DELETE:
1041  case wxFSW_EVENT_CREATE:
1042  case wxFSW_EVENT_RENAME:
1043  break;
1044 
1045  case wxFSW_EVENT_MODIFY:
1046  case wxFSW_EVENT_ACCESS:
1047  default:
1048  return;
1049  }
1050 
1051  wxTreeItemId root_id = findSubdirTreeItem( subdir );
1052 
1053  if( !root_id.IsOk() )
1054  return;
1055 
1056  wxTreeItemIdValue cookie; // dummy variable needed by GetFirstChild()
1057  wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1058 
1059  switch( event.GetChangeType() )
1060  {
1061  case wxFSW_EVENT_CREATE:
1062  {
1063  wxTreeItemId newitem =
1064  addItemToProjectTree( pathModified.GetFullPath(), root_id, nullptr, true );
1065 
1066  // If we are in the process of renaming a file, select the new one
1067  // This is needed for MSW and OSX, since we don't get RENAME events from them, just a
1068  // pair of DELETE and CREATE events.
1069  if( m_isRenaming && newitem.IsOk() )
1070  {
1071  m_TreeProject->SelectItem( newitem );
1072  m_isRenaming = false;
1073  }
1074  }
1075  break;
1076 
1077  case wxFSW_EVENT_DELETE:
1078  while( kid.IsOk() )
1079  {
1080  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1081 
1082  if( itemData && itemData->GetFileName() == fn )
1083  {
1084  m_TreeProject->Delete( kid );
1085  return;
1086  }
1087  kid = m_TreeProject->GetNextChild( root_id, cookie );
1088  }
1089  break;
1090 
1091  case wxFSW_EVENT_RENAME :
1092  {
1093  const wxFileName& newpath = event.GetNewPath();
1094  wxString newdir = newpath.GetPath();
1095  wxString newfn = newpath.GetFullPath();
1096 
1097  while( kid.IsOk() )
1098  {
1099  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1100 
1101  if( itemData && itemData->GetFileName() == fn )
1102  {
1103  m_TreeProject->Delete( kid );
1104  break;
1105  }
1106 
1107  kid = m_TreeProject->GetNextChild( root_id, cookie );
1108  }
1109 
1110  // Add the new item only if it is not the current project file (root item).
1111  // Remember: this code is called by a wxFileSystemWatcherEvent event, and not always
1112  // called after an actual file rename, and the cleanup code does not explore the
1113  // root item, because it cannot be renamed by the user. Also, ensure the new file
1114  // actually exists on the file system before it is readded. On Linux, moving a file
1115  // to the trash can cause the same path to be returned in both the old and new paths
1116  // of the event, even though the file isn't there anymore.
1117  PROJECT_TREE_ITEM* rootData = GetItemIdData( root_id );
1118 
1119  if( newpath.Exists() && ( newfn != rootData->GetFileName() ) )
1120  {
1121  wxTreeItemId newroot_id = findSubdirTreeItem( newdir );
1122  wxTreeItemId newitem = addItemToProjectTree( newfn, newroot_id, nullptr, true );
1123 
1124  // If the item exists, select it
1125  if( newitem.IsOk() )
1126  m_TreeProject->SelectItem( newitem );
1127  }
1128 
1129  m_isRenaming = false;
1130  }
1131  break;
1132  }
1133 
1134  // Sort filenames by alphabetic order
1135  m_TreeProject->SortChildren( root_id );
1136 }
const wxString & GetFileName() const
wxTreeItemId findSubdirTreeItem(const wxString &aSubDir)
Function findSubdirTreeItem searches for the item in tree project which is the node of the subdirecto...
PROJECT_TREE * m_TreeProject
wxFileSystemWatcher * m_watcher
Handle one item (a file or a directory name) for the tree file.
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
PROJECT_TREE_ITEM * GetItemIdData(wxTreeItemId aId)
Function GetItemIdData return the item data corresponding to a wxTreeItemId identifier.

References addItemToProjectTree(), findSubdirTreeItem(), PROJECT_TREE_ITEM::GetFileName(), GetItemIdData(), m_isRenaming, m_TreeProject, and m_watcher.

Referenced by PROJECT_TREE_PANE().

◆ onIdle()

void PROJECT_TREE_PANE::onIdle ( wxIdleEvent &  aEvent)
private

Idle event handler, used process the selected items at a point in time when all other events have been consumed.

Definition at line 863 of file project_tree_pane.cpp.

864 {
865  // Idle executes once all other events finished processing. This makes it ideal to launch
866  // a new window without starting Focus wars.
867  if( m_watcherNeedReset )
868  {
869  m_selectedItem = nullptr;
871  }
872 
873  if( m_selectedItem != nullptr )
874  {
875  // Activate launches a window which may run the event loop on top of us and cause OnIdle
876  // to get called again, so be sure to block off the activation condition first.
878  m_selectedItem = nullptr;
879 
880  item->Activate( this );
881  }
882 }
void Activate(PROJECT_TREE_PANE *aTreePrjFrame)
PROJECT_TREE_ITEM * m_selectedItem
void FileWatcherReset()
Reinit the watched paths Should be called after opening a new project to rebuild the list of watched ...
Handle one item (a file or a directory name) for the tree file.

References PROJECT_TREE_ITEM::Activate(), FileWatcherReset(), m_selectedItem, and m_watcherNeedReset.

◆ onOpenDirectory()

void PROJECT_TREE_PANE::onOpenDirectory ( wxCommandEvent &  event)
private

Function onOpenDirectory Handles the right-click menu for opening a directory in the current system file browser.

Definition at line 200 of file project_tree_pane.cpp.

201 {
202  // Get the root directory name:
203  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
204 
205  for( PROJECT_TREE_ITEM* item_data : tree_data )
206  {
207  // Ask for the new sub directory name
208  wxString curr_dir = item_data->GetDir();
209 
210  if( curr_dir.IsEmpty() )
211  {
212  // Use project path if the tree view path was empty.
213  curr_dir = wxPathOnly( m_Parent->GetProjectFileName() );
214 
215  // As a last resort use the user's documents folder.
216  if( curr_dir.IsEmpty() || !wxFileName::DirExists( curr_dir ) )
218 
219  if( !curr_dir.IsEmpty() )
220  curr_dir += wxFileName::GetPathSeparator();
221  }
222 
223  LaunchExternal( curr_dir );
224  }
225 }
const wxString GetProjectFileName() const
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:139
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
Definition: launch_ext.cpp:25
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
Handle one item (a file or a directory name) for the tree file.
KICAD_MANAGER_FRAME * m_Parent

References PATHS::GetDefaultUserProjectsPath(), KICAD_MANAGER_FRAME::GetProjectFileName(), GetSelectedData(), LaunchExternal(), and m_Parent.

◆ onOpenSelectedFileWithTextEditor()

void PROJECT_TREE_PANE::onOpenSelectedFileWithTextEditor ( wxCommandEvent &  event)
private

Function onOpenSelectedFileWithTextEditor Call the text editor to open the selected file in the tree project.

Definition at line 784 of file project_tree_pane.cpp.

785 {
786  wxString editorname = Pgm().GetTextEditor();
787 
788  if( editorname.IsEmpty() )
789  {
790  wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
791  return;
792  }
793 
794  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
795  wxString files;
796 
797  for( PROJECT_TREE_ITEM* item_data : tree_data )
798  {
799  wxString fullFileName = item_data->GetFileName();
800 
801  if( !files.IsEmpty() )
802  files += wxT( " " );
803 
804  files += fullFileName;
805  }
806 
807  ExecuteFile( editorname, files );
808 }
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback)
Call the executable file aEditorName with the parameter aFileName.
Definition: gestfich.cpp:115
#define _(s)
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
Handle one item (a file or a directory name) for the tree file.

References _, ExecuteFile(), GetSelectedData(), and Pgm().

◆ onPaint()

void PROJECT_TREE_PANE::onPaint ( wxPaintEvent &  aEvent)
private

We don't have uniform borders so we have to draw them ourselves.

Definition at line 1272 of file project_tree_pane.cpp.

1273 {
1274  wxRect rect( wxPoint( 0, 0 ), GetClientSize() );
1275  wxPaintDC dc( this );
1276 
1277  dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
1278  dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
1279 
1280  dc.DrawLine( rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom() );
1281  dc.DrawLine( rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom() );
1282 }

◆ onRenameFile()

void PROJECT_TREE_PANE::onRenameFile ( wxCommandEvent &  event)
private

Function onRenameFile Rename the selected file or directory in the tree project.

Definition at line 820 of file project_tree_pane.cpp.

821 {
822  wxTreeItemId curr_item = m_TreeProject->GetFocusedItem();
823  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
824 
825  // XXX: Unnecessary?
826  if( tree_data.size() != 1 )
827  return;
828 
829  wxString buffer = m_TreeProject->GetItemText( curr_item );
830  wxString msg = wxString::Format( _( "Change filename: '%s'" ),
831  tree_data[0]->GetFileName() );
832  wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer );
833 
834  if( dlg.ShowModal() != wxID_OK )
835  return; // canceled by user
836 
837  buffer = dlg.GetValue();
838  buffer.Trim( true );
839  buffer.Trim( false );
840 
841  if( buffer.IsEmpty() )
842  return; // empty file name not allowed
843 
844  tree_data[0]->Rename( buffer, true );
845  m_isRenaming = true;
846 }
PROJECT_TREE * m_TreeProject
#define _(s)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...

References _, Format(), GetSelectedData(), m_isRenaming, and m_TreeProject.

◆ onRight()

void PROJECT_TREE_PANE::onRight ( wxTreeEvent &  Event)
private

Called on a right click on an item.

Definition at line 607 of file project_tree_pane.cpp.

608 {
609  wxTreeItemId curr_item = Event.GetItem();
610 
611  // Ensure item is selected (Under Windows right click does not select the item)
612  m_TreeProject->SelectItem( curr_item );
613 
614  std::vector<PROJECT_TREE_ITEM*> selection = GetSelectedData();
615 
616  bool can_switch_to_project = true;
617  bool can_create_new_directory = true;
618  bool can_open_this_directory = true;
619  bool can_edit = true;
620  bool can_rename = true;
621  bool can_delete = true;
622 
623  if( selection.size() == 0 )
624  return;
625 
626  // Remove things that don't make sense for multiple selections
627  if( selection.size() != 1 )
628  {
629  can_switch_to_project = false;
630  can_create_new_directory = false;
631  can_rename = false;
632  }
633 
634  for( PROJECT_TREE_ITEM* item : selection )
635  {
636  // Check for empty project
637  if( !item )
638  {
639  can_switch_to_project = false;
640  can_edit = false;
641  can_rename = false;
642  continue;
643  }
644 
645  can_delete = item->CanDelete();
646  can_rename = item->CanRename();
647 
648  wxString full_file_name = item->GetFileName();
649 
650  switch( item->GetType() )
651  {
654  can_rename = false;
655 
656  if( item->GetId() == m_TreeProject->GetRootItem() )
657  {
658  can_switch_to_project = false;
659  }
660  else
661  {
662  can_create_new_directory = false;
663  can_open_this_directory = false;
664  }
665  break;
666 
668  can_switch_to_project = false;
669  can_edit = false;
670  break;
671 
672  default:
673  can_switch_to_project = false;
674  can_create_new_directory = false;
675  can_open_this_directory = false;
676 
677  break;
678  }
679  }
680 
681  wxMenu popup_menu;
682  wxString text;
683  wxString help_text;
684 
685  if( can_switch_to_project )
686  {
688  _( "Switch to this Project" ),
689  _( "Close all editors, and switch to the selected project" ),
691  popup_menu.AppendSeparator();
692  }
693 
694  if( can_create_new_directory )
695  {
696  AddMenuItem( &popup_menu, ID_PROJECT_NEWDIR, _( "New Directory..." ),
697  _( "Create a New Directory" ), KiBitmap( BITMAPS::directory ) );
698  }
699 
700  if( can_open_this_directory )
701  {
702  if( selection.size() == 1 )
703  {
704 #ifdef __APPLE__
705  text = _( "Reveal in Finder" );
706  help_text = _( "Reveals the directory in a Finder window" );
707 #else
708  text = _( "Open Directory in File Explorer" );
709  help_text = _( "Opens the directory in the default system file manager" );
710 #endif
711  }
712  else
713  {
714 #ifdef __APPLE__
715  text = _( "Reveal in Finder" );
716  help_text = _( "Reveals the directories in a Finder window" );
717 #else
718  text = _( "Open Directories in File Explorer" );
719  help_text = _( "Opens the directories in the default system file manager" );
720 #endif
721  }
722 
723  AddMenuItem( &popup_menu, ID_PROJECT_OPEN_DIR, text, help_text,
725  }
726 
727  if( can_edit )
728  {
729  if( selection.size() == 1 )
730  help_text = _( "Open the file in a Text Editor" );
731  else
732  help_text = _( "Open files in a Text Editor" );
733 
734  AddMenuItem( &popup_menu, ID_PROJECT_TXTEDIT, _( "Edit in a Text Editor" ),
735  help_text, KiBitmap( BITMAPS::editor ) );
736  }
737 
738  if( can_rename )
739  {
740  if( selection.size() == 1 )
741  {
742  text = _( "Rename File..." );
743  help_text = _( "Rename file" );
744  }
745  else
746  {
747  text = _( "Rename Files..." );
748  help_text = _( "Rename files" );
749  }
750 
751  AddMenuItem( &popup_menu, ID_PROJECT_RENAME, text, help_text, KiBitmap( BITMAPS::right ) );
752  }
753 
754  if( can_delete )
755  {
756  if( selection.size() == 1 )
757  help_text = _( "Delete the file and its content" );
758  else
759  help_text = _( "Delete the files and their contents" );
760 
761  if( can_switch_to_project
762  || can_create_new_directory
763  || can_open_this_directory
764  || can_edit
765  || can_rename )
766  {
767  popup_menu.AppendSeparator();
768  }
769 
770 #ifdef __WINDOWS__
771  AddMenuItem( &popup_menu, ID_PROJECT_DELETE, _( "Delete" ), help_text,
773 #else
774  AddMenuItem( &popup_menu, ID_PROJECT_DELETE, _( "Move to Trash" ), help_text,
776 #endif
777  }
778 
779  if( popup_menu.GetMenuItemCount() > 0 )
780  PopupMenu( &popup_menu );
781 }
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.
Definition: bitmap.cpp:257
PROJECT_TREE * m_TreeProject
#define _(s)
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
Handle one item (a file or a directory name) for the tree file.

References _, AddMenuItem(), DIRECTORY, directory, directory_browser, editor, GetSelectedData(), ID_PROJECT_DELETE, ID_PROJECT_NEWDIR, ID_PROJECT_OPEN_DIR, ID_PROJECT_RENAME, ID_PROJECT_SWITCH_TO_OTHER, ID_PROJECT_TXTEDIT, JSON_PROJECT, KiBitmap(), LEGACY_PROJECT, m_TreeProject, open_project, right, text, and trash.

◆ onSelect()

void PROJECT_TREE_PANE::onSelect ( wxTreeEvent &  Event)
private

Called on a double click on an item.

Definition at line 849 of file project_tree_pane.cpp.

850 {
851  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
852 
853  if( tree_data.size() != 1 )
854  return;
855 
856  // Bookmark the selected item but don't try and activate it until later. If we do it now,
857  // there will be more events at least on Windows in this frame that will steal focus from
858  // any newly launched windows
859  m_selectedItem = tree_data[0];
860 }
PROJECT_TREE_ITEM * m_selectedItem
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...

References GetSelectedData(), and m_selectedItem.

◆ onSwitchToSelectedProject()

void PROJECT_TREE_PANE::onSwitchToSelectedProject ( wxCommandEvent &  event)
private

Switch to a other project selected from the tree project (by selecting an other .pro file inside the current project folder)

Definition at line 187 of file project_tree_pane.cpp.

188 {
189  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
190 
191  if( tree_data.size() != 1 )
192  return;
193 
194  wxString prj_filename = tree_data[0]->GetFileName();
195 
196  m_Parent->LoadProject( prj_filename );
197 }
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
void LoadProject(const wxFileName &aProjectFileName)
KICAD_MANAGER_FRAME * m_Parent

References GetSelectedData(), KICAD_MANAGER_FRAME::LoadProject(), and m_Parent.

◆ onThemeChanged()

void PROJECT_TREE_PANE::onThemeChanged ( wxSysColourChangedEvent &  aEvent)
private

Definition at line 1262 of file project_tree_pane.cpp.

1263 {
1266  m_TreeProject->Refresh();
1267 
1268  aEvent.Skip();
1269 }
PROJECT_TREE * m_TreeProject
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
void LoadIcons()
BITMAP_STORE * GetBitmapStore()
Definition: bitmap.cpp:93

References GetBitmapStore(), PROJECT_TREE::LoadIcons(), m_TreeProject, and BITMAP_STORE::ThemeChanged().

Referenced by PROJECT_TREE_PANE().

◆ ReCreateTreePrj()

void PROJECT_TREE_PANE::ReCreateTreePrj ( )

Create or modify the tree showing project file names.

Definition at line 523 of file project_tree_pane.cpp.

524 {
525  wxString pro_dir = m_Parent->GetProjectFileName();
526 
527  if( !m_TreeProject )
528  m_TreeProject = new PROJECT_TREE( this );
529  else
530  m_TreeProject->DeleteAllItems();
531 
532  if( !pro_dir ) // This is empty from PROJECT_TREE_PANE constructor
533  return;
534 
535  wxFileName fn = pro_dir;
536  bool prjReset = false;
537 
538  if( !fn.IsOk() )
539  {
540  fn.Clear();
541  fn.SetPath( PATHS::GetDefaultUserProjectsPath() );
542  fn.SetName( NAMELESS_PROJECT );
543  fn.SetExt( ProjectFileExtension );
544  prjReset = true;
545  }
546 
547  bool prjOpened = fn.FileExists();
548 
549  // We may have opened a legacy project, in which case GetProjectFileName will return the
550  // name of the migrated (new format) file, which may not have been saved to disk yet.
551  if( !prjOpened && !prjReset )
552  {
553  fn.SetExt( LegacyProjectFileExtension );
554  prjOpened = fn.FileExists();
555 
556  // Set the ext back so that in the tree view we see the (not-yet-saved) new file
557  fn.SetExt( ProjectFileExtension );
558  }
559 
560  // root tree:
561  m_root = m_TreeProject->AddRoot( fn.GetFullName(), static_cast<int>( TREE_FILE_TYPE::ROOT ),
562  static_cast<int>( TREE_FILE_TYPE::ROOT ) );
563  m_TreeProject->SetItemBold( m_root, true );
564 
565  // The main project file is now a JSON file
567  fn.GetFullPath(), m_TreeProject ) );
568 
569  // Now adding all current files if available
570  if( prjOpened )
571  {
572  pro_dir = wxPathOnly( m_Parent->GetProjectFileName() );
573  wxDir dir( pro_dir );
574 
575  if( dir.IsOpened() ) // protected dirs will not open, see "man opendir()"
576  {
577  std::vector<wxString> projects = getProjects( dir );
578  wxString filename;
579  bool haveFile = dir.GetFirst( &filename );
580 
581  while( haveFile )
582  {
583  if( filename != fn.GetFullName() )
584  {
585  wxString name = dir.GetName() + wxFileName::GetPathSeparator() + filename;
586  // Add items living in the project directory, and populate the item
587  // if it is a directory (sub directories will be not populated)
588  addItemToProjectTree( name, m_root, &projects, true );
589  }
590 
591  haveFile = dir.GetNext( &filename );
592  }
593  }
594  }
595  else
596  {
597  m_TreeProject->AppendItem( m_root, wxT( "Empty project" ) );
598  }
599 
600  m_TreeProject->Expand( m_root );
601 
602  // Sort filenames by alphabetic order
603  m_TreeProject->SortChildren( m_root );
604 }
const wxString GetProjectFileName() const
const std::string ProjectFileExtension
PROJECT_TREE * m_TreeProject
friend class PROJECT_TREE_ITEM
const std::string LegacyProjectFileExtension
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:139
const char * name
Definition: DXF_plotter.cpp:56
#define NAMELESS_PROJECT
default name for nameless projects
Definition: project.h:41
wxTreeItemId addItemToProjectTree(const wxString &aName, const wxTreeItemId &aParent, std::vector< wxString > *aProjectNames, bool aRecurse)
Function addItemToProjectTree.
KICAD_MANAGER_FRAME * m_Parent
std::vector< wxString > getProjects(const wxDir &dir)
PROJECT_TREE This is the class to show (as a tree) the files in the project directory.
Definition: project_tree.h:38

References addItemToProjectTree(), PATHS::GetDefaultUserProjectsPath(), KICAD_MANAGER_FRAME::GetProjectFileName(), getProjects(), JSON_PROJECT, LegacyProjectFileExtension, m_Parent, m_root, m_TreeProject, name, NAMELESS_PROJECT, PROJECT_TREE_ITEM, ProjectFileExtension, and ROOT.

Referenced by KICAD_MANAGER_FRAME::LoadProject(), KICAD_MANAGER_FRAME::ReCreateTreePrj(), and KICAD_MANAGER_FRAME::RefreshProjectTree().

◆ shutdownFileWatcher()

void PROJECT_TREE_PANE::shutdownFileWatcher ( )
private

Shutdown the file watcher.

Used when closing to prevent post-free access into the project tree. (Using the destructor doesn't work as wxWidgets defers destruction in some cases.)

Definition at line 175 of file project_tree_pane.cpp.

176 {
177  if( m_watcher )
178  {
179  m_watcher->RemoveAll();
180  m_watcher->SetOwner( nullptr );
181  delete m_watcher;
182  m_watcher = nullptr;
183  }
184 }
wxFileSystemWatcher * m_watcher

References m_watcher.

Referenced by EmptyTreePrj(), and ~PROJECT_TREE_PANE().

Friends And Related Function Documentation

◆ PROJECT_TREE_ITEM

friend class PROJECT_TREE_ITEM
friend

Definition at line 50 of file project_tree_pane.h.

Referenced by addItemToProjectTree(), and ReCreateTreePrj().

Member Data Documentation

◆ m_filters

std::vector<wxString> PROJECT_TREE_PANE::m_filters
private

Definition at line 200 of file project_tree_pane.h.

Referenced by addItemToProjectTree().

◆ m_isRenaming

bool PROJECT_TREE_PANE::m_isRenaming
private

Definition at line 198 of file project_tree_pane.h.

Referenced by onFileSystemEvent(), and onRenameFile().

◆ m_Parent

◆ m_root

wxTreeItemId PROJECT_TREE_PANE::m_root
private

Definition at line 199 of file project_tree_pane.h.

Referenced by FileWatcherReset(), findSubdirTreeItem(), and ReCreateTreePrj().

◆ m_selectedItem

PROJECT_TREE_ITEM* PROJECT_TREE_PANE::m_selectedItem
private

Definition at line 202 of file project_tree_pane.h.

Referenced by onIdle(), and onSelect().

◆ m_TreeProject

◆ m_watcher

wxFileSystemWatcher* PROJECT_TREE_PANE::m_watcher
private

Definition at line 201 of file project_tree_pane.h.

Referenced by FileWatcherReset(), onFileSystemEvent(), and shutdownFileWatcher().

◆ m_watcherNeedReset

bool PROJECT_TREE_PANE::m_watcherNeedReset
private

Definition at line 203 of file project_tree_pane.h.

Referenced by addItemToProjectTree(), FileWatcherReset(), onExpand(), and onIdle().


The documentation for this class was generated from the following files: