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 onPrintFile (wxCommandEvent &event)
 Function onDeleteFile Print 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 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 137 of file project_tree_pane.cpp.

137  :
138  wxSashLayoutWindow( parent, ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize,
139  wxNO_BORDER | wxTAB_TRAVERSAL )
140 {
141  m_Parent = parent;
142  m_TreeProject = nullptr;
143  m_isRenaming = false;
144  m_selectedItem = nullptr;
145  m_watcherNeedReset = false;
146 
147  m_watcher = nullptr;
148  Connect( wxEVT_FSWATCHER,
149  wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
150 
151  Bind( wxEVT_SYS_COLOUR_CHANGED,
152  wxSysColourChangedEventHandler( PROJECT_TREE_PANE::onThemeChanged ), this );
153 
154  /*
155  * Filtering is now inverted: the filters are actually used to _enable_ support
156  * for a given file type.
157  */
158  for( int ii = 0; s_allowedExtensionsToList[ii] != nullptr; ii++ )
159  m_filters.emplace_back( s_allowedExtensionsToList[ii] );
160 
161  m_filters.emplace_back( wxT( "^no KiCad files found" ) );
162 
163  ReCreateTreePrj();
164 }
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 167 of file project_tree_pane.cpp.

168 {
170 }
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 307 of file project_tree_pane.cpp.

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

1281 {
1282  // Make sure we don't try to inspect the tree after we've deleted its items.
1284 
1285  m_TreeProject->DeleteAllItems();
1286 }
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 1166 of file project_tree_pane.cpp.

1167 {
1168  m_watcherNeedReset = false;
1169 
1170  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
1171 
1172 #if defined( _WIN32 )
1173  if( KIPLATFORM::ENV::IsNetworkPath( prj_dir ) )
1174  {
1175  // Due to a combination of a bug in SAMBA sending bad change event IDs and wxWidgets
1176  // choosing to fault on an invalid event ID instead of sanely ignoring them we need to
1177  // avoid spawning a filewatcher. Unfortunately this punishes corporate environments with
1178  // Windows Server shares :/
1179  m_Parent->SetStatusText( _( "Network path: not monitoring folder changes" ), 1 );
1180  return;
1181  }
1182  else
1183  {
1184  m_Parent->SetStatusText( _( "Local path: monitoring folder changes" ), 1 );
1185  }
1186 #endif
1187 
1188  // Prepare file watcher:
1189  if( m_watcher )
1190  {
1191  m_watcher->RemoveAll();
1192  }
1193  else
1194  {
1195  m_watcher = new wxFileSystemWatcher();
1196  m_watcher->SetOwner( this );
1197  }
1198 
1199  // We can see wxString under a debugger, not a wxFileName
1200  wxFileName fn;
1201  fn.AssignDir( prj_dir );
1202  fn.DontFollowLink();
1203 
1204  // Add directories which should be monitored.
1205  // under windows, we add the curr dir and all subdirs
1206  // under unix, we add only the curr dir and the populated subdirs
1207  // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm
1208  // under unix, the file watcher needs more work to be efficient
1209  // moreover, under wxWidgets 2.9.4, AddTree does not work properly.
1210 #ifdef __WINDOWS__
1211  m_watcher->AddTree( fn );
1212 #else
1213  m_watcher->Add( fn );
1214 
1215  if( m_TreeProject->IsEmpty() )
1216  return;
1217 
1218  // Add subdirs
1219  wxTreeItemIdValue cookie;
1220  wxTreeItemId root_id = m_root;
1221 
1222  std::stack < wxTreeItemId > subdirs_id;
1223 
1224  wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1225 
1226  while( true )
1227  {
1228  if( !kid.IsOk() )
1229  {
1230  if( subdirs_id.empty() ) // all items were explored
1231  {
1232  break;
1233  }
1234  else
1235  {
1236  root_id = subdirs_id.top();
1237  subdirs_id.pop();
1238  kid = m_TreeProject->GetFirstChild( root_id, cookie );
1239 
1240  if( !kid.IsOk() )
1241  continue;
1242  }
1243  }
1244 
1245  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1246 
1247  if( itemData && itemData->GetType() == TREE_FILE_TYPE::DIRECTORY )
1248  {
1249  // we can see wxString under a debugger, not a wxFileName
1250  const wxString& path = itemData->GetFileName();
1251 
1252  wxLogTrace( tracePathsAndFiles, "%s: add '%s'\n", __func__, TO_UTF8( path ) );
1253 
1254  if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir
1255  {
1256  fn.AssignDir( path );
1257  m_watcher->Add( fn );
1258 
1259  // if kid is a subdir, push in list to explore it later
1260  if( itemData->IsPopulated() && m_TreeProject->GetChildrenCount( kid ) )
1261  subdirs_id.push( kid );
1262  }
1263  }
1264 
1265  kid = m_TreeProject->GetNextChild( root_id, cookie );
1266  }
1267 #endif
1268 
1269 #if defined(DEBUG) && 1
1270  wxArrayString paths;
1271  m_watcher->GetWatchedPaths( &paths );
1272  wxLogTrace( tracePathsAndFiles, "%s: watched paths:", __func__ );
1273 
1274  for( unsigned ii = 0; ii < paths.GetCount(); ii++ )
1275  wxLogTrace( tracePathsAndFiles, " %s\n", TO_UTF8( paths[ii] ) );
1276 #endif
1277 }
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 997 of file project_tree_pane.cpp.

998 {
999  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
1000 
1001  // If the subdir is the current working directory, return m_root
1002  // in main list:
1003  if( prj_dir == aSubDir )
1004  return m_root;
1005 
1006  // The subdir is in the main tree or in a subdir: Locate it
1007  wxTreeItemIdValue cookie;
1008  wxTreeItemId root_id = m_root;
1009  std::stack<wxTreeItemId> subdirs_id;
1010 
1011  wxTreeItemId child = m_TreeProject->GetFirstChild( root_id, cookie );
1012 
1013  while( true )
1014  {
1015  if( ! child.IsOk() )
1016  {
1017  if( subdirs_id.empty() ) // all items were explored
1018  {
1019  root_id = child; // Not found: return an invalid wxTreeItemId
1020  break;
1021  }
1022  else
1023  {
1024  root_id = subdirs_id.top();
1025  subdirs_id.pop();
1026  child = m_TreeProject->GetFirstChild( root_id, cookie );
1027 
1028  if( !child.IsOk() )
1029  continue;
1030  }
1031  }
1032 
1033  PROJECT_TREE_ITEM* itemData = GetItemIdData( child );
1034 
1035  if( itemData && ( itemData->GetType() == TREE_FILE_TYPE::DIRECTORY ) )
1036  {
1037  if( itemData->GetFileName() == aSubDir ) // Found!
1038  {
1039  root_id = child;
1040  break;
1041  }
1042 
1043  // child is a subdir, push in list to explore it later
1044  if( itemData->IsPopulated() )
1045  subdirs_id.push( child );
1046  }
1047 
1048  child = m_TreeProject->GetNextChild( root_id, cookie );
1049  }
1050 
1051  return root_id;
1052 }
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 254 of file project_tree_pane.cpp.

255 {
256  switch( type )
257  {
274  case TREE_FILE_TYPE::DRILL_NC: return "nc";
275  case TREE_FILE_TYPE::DRILL_XNC: return "xnc";
282  default: return wxEmptyString;
283  }
284 }
const std::string NetlistFileExtension
const std::string KiCadFootprintFileExtension
const std::string ProjectFileExtension
const std::string LegacyPcbFileExtension
const std::string LegacySymbolLibFileExtension
const std::string DesignRulesFileExtension
const std::string KiCadPcbFileExtension
const std::string HtmlFileExtension
const std::string FootprintAssignmentFileExtension
const wxString GerberFileExtensionWildCard(".((gbr|gbrjob|(gb|gt)[alops])|pho)")
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 991 of file project_tree_pane.cpp.

992 {
993  return dynamic_cast<PROJECT_TREE_ITEM*>( m_TreeProject->GetItemData( aId ) );
994 }
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 977 of file project_tree_pane.cpp.

978 {
979  wxArrayTreeItemIds selection;
980  std::vector<PROJECT_TREE_ITEM*> data;
981 
982  m_TreeProject->GetSelections( selection );
983 
984  for( auto it = selection.begin(); it != selection.end(); it++ )
985  data.push_back( GetItemIdData( *it ) );
986 
987  return data;
988 }
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(), onPrintFile(), 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 226 of file project_tree_pane.cpp.

227 {
228  // Get the root directory name:
229  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
230 
231  for( PROJECT_TREE_ITEM* item_data : tree_data )
232  {
233  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
234 
235  // Ask for the new sub directory name
236  wxString curr_dir = item_data->GetDir();
237 
238  if( curr_dir.IsEmpty() )
239  curr_dir = prj_dir;
240 
241  wxString new_dir = wxGetTextFromUser( _( "Directory name:" ), _( "Create New Directory" ) );
242 
243  if( new_dir.IsEmpty() )
244  return;
245 
246  wxString full_dirname = curr_dir + wxFileName::GetPathSeparator() + new_dir;
247 
248  wxMkdir( full_dirname );
249  addItemToProjectTree( full_dirname, item_data->GetId(), nullptr, false );
250  }
251 }
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 829 of file project_tree_pane.cpp.

830 {
831  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
832 
833  for( PROJECT_TREE_ITEM* item_data : tree_data )
834  item_data->Delete();
835 }
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 912 of file project_tree_pane.cpp.

913 {
914  wxTreeItemId itemId = Event.GetItem();
915  PROJECT_TREE_ITEM* tree_data = GetItemIdData( itemId );
916 
917  if( !tree_data )
918  return;
919 
920  if( tree_data->GetType() != TREE_FILE_TYPE::DIRECTORY )
921  return;
922 
923  // explore list of non populated subdirs, and populate them
924  wxTreeItemIdValue cookie;
925  wxTreeItemId kid = m_TreeProject->GetFirstChild( itemId, cookie );
926 
927 #ifndef __WINDOWS__
928  bool subdir_populated = false;
929 #endif
930 
931  for( ; kid.IsOk(); kid = m_TreeProject->GetNextChild( itemId, cookie ) )
932  {
933  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
934 
935  if( !itemData || itemData->GetType() != TREE_FILE_TYPE::DIRECTORY )
936  continue;
937 
938  if( itemData->IsPopulated() )
939  continue;
940 
941  wxString fileName = itemData->GetFileName();
942  wxDir dir( fileName );
943 
944  if( dir.IsOpened() )
945  {
946  std::vector<wxString> projects = getProjects( dir );
947  wxString dir_filename;
948  bool haveFile = dir.GetFirst( &dir_filename );
949 
950  while( haveFile )
951  {
952  // Add name to tree item, but do not recurse in subdirs:
953  wxString name = fileName + wxFileName::GetPathSeparator() + dir_filename;
954  addItemToProjectTree( name, kid, &projects, false );
955 
956  haveFile = dir.GetNext( &dir_filename );
957  }
958 
959  itemData->SetPopulated( true ); // set state to populated
960 
961 #ifndef __WINDOWS__
962  subdir_populated = true;
963 #endif
964  }
965 
966  // Sort filenames by alphabetic order
967  m_TreeProject->SortChildren( kid );
968  }
969 
970 #ifndef __WINDOWS__
971  if( subdir_populated )
972  m_watcherNeedReset = true;
973 #endif
974 }
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 1055 of file project_tree_pane.cpp.

1056 {
1057  // No need to process events when we're shutting down
1058  if( !m_watcher )
1059  return;
1060 
1061  const wxFileName& pathModified = event.GetPath();
1062  wxString subdir = pathModified.GetPath();
1063  wxString fn = pathModified.GetFullPath();
1064 
1065  switch( event.GetChangeType() )
1066  {
1067  case wxFSW_EVENT_DELETE:
1068  case wxFSW_EVENT_CREATE:
1069  case wxFSW_EVENT_RENAME:
1070  break;
1071 
1072  case wxFSW_EVENT_MODIFY:
1073  case wxFSW_EVENT_ACCESS:
1074  default:
1075  return;
1076  }
1077 
1078  wxTreeItemId root_id = findSubdirTreeItem( subdir );
1079 
1080  if( !root_id.IsOk() )
1081  return;
1082 
1083  wxTreeItemIdValue cookie; // dummy variable needed by GetFirstChild()
1084  wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1085 
1086  switch( event.GetChangeType() )
1087  {
1088  case wxFSW_EVENT_CREATE:
1089  {
1090  wxTreeItemId newitem =
1091  addItemToProjectTree( pathModified.GetFullPath(), root_id, nullptr, true );
1092 
1093  // If we are in the process of renaming a file, select the new one
1094  // This is needed for MSW and OSX, since we don't get RENAME events from them, just a
1095  // pair of DELETE and CREATE events.
1096  if( m_isRenaming && newitem.IsOk() )
1097  {
1098  m_TreeProject->SelectItem( newitem );
1099  m_isRenaming = false;
1100  }
1101  }
1102  break;
1103 
1104  case wxFSW_EVENT_DELETE:
1105  while( kid.IsOk() )
1106  {
1107  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1108 
1109  if( itemData && itemData->GetFileName() == fn )
1110  {
1111  m_TreeProject->Delete( kid );
1112  return;
1113  }
1114  kid = m_TreeProject->GetNextChild( root_id, cookie );
1115  }
1116  break;
1117 
1118  case wxFSW_EVENT_RENAME :
1119  {
1120  const wxFileName& newpath = event.GetNewPath();
1121  wxString newdir = newpath.GetPath();
1122  wxString newfn = newpath.GetFullPath();
1123 
1124  while( kid.IsOk() )
1125  {
1126  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1127 
1128  if( itemData && itemData->GetFileName() == fn )
1129  {
1130  m_TreeProject->Delete( kid );
1131  break;
1132  }
1133 
1134  kid = m_TreeProject->GetNextChild( root_id, cookie );
1135  }
1136 
1137  // Add the new item only if it is not the current project file (root item).
1138  // Remember: this code is called by a wxFileSystemWatcherEvent event, and not always
1139  // called after an actual file rename, and the cleanup code does not explore the
1140  // root item, because it cannot be renamed by the user. Also, ensure the new file
1141  // actually exists on the file system before it is readded. On Linux, moving a file
1142  // to the trash can cause the same path to be returned in both the old and new paths
1143  // of the event, even though the file isn't there anymore.
1144  PROJECT_TREE_ITEM* rootData = GetItemIdData( root_id );
1145 
1146  if( newpath.Exists() && ( newfn != rootData->GetFileName() ) )
1147  {
1148  wxTreeItemId newroot_id = findSubdirTreeItem( newdir );
1149  wxTreeItemId newitem = addItemToProjectTree( newfn, newroot_id, nullptr, true );
1150 
1151  // If the item exists, select it
1152  if( newitem.IsOk() )
1153  m_TreeProject->SelectItem( newitem );
1154  }
1155 
1156  m_isRenaming = false;
1157  }
1158  break;
1159  }
1160 
1161  // Sort filenames by alphabetic order
1162  m_TreeProject->SortChildren( root_id );
1163 }
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 890 of file project_tree_pane.cpp.

891 {
892  // Idle executes once all other events finished processing. This makes it ideal to launch
893  // a new window without starting Focus wars.
894  if( m_watcherNeedReset )
895  {
896  m_selectedItem = nullptr;
898  }
899 
900  if( m_selectedItem != nullptr )
901  {
902  // Activate launches a window which may run the event loop on top of us and cause OnIdle
903  // to get called again, so be sure to block off the activation condition first.
905  m_selectedItem = nullptr;
906 
907  item->Activate( this );
908  }
909 }
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 198 of file project_tree_pane.cpp.

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

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 802 of file project_tree_pane.cpp.

803 {
804  wxString editorname = Pgm().GetTextEditor();
805 
806  if( editorname.IsEmpty() )
807  {
808  wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
809  return;
810  }
811 
812  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
813  wxString files;
814 
815  for( PROJECT_TREE_ITEM* item_data : tree_data )
816  {
817  wxString fullFileName = item_data->GetFileName();
818 
819  if( !files.IsEmpty() )
820  files += " ";
821 
822  files += fullFileName;
823  }
824 
825  ExecuteFile( editorname, files );
826 }
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:114
#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().

◆ onPrintFile()

void PROJECT_TREE_PANE::onPrintFile ( wxCommandEvent &  event)
private

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

Definition at line 838 of file project_tree_pane.cpp.

839 {
840  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
841 
842  for( PROJECT_TREE_ITEM* item_data : tree_data )
843  item_data->Print();
844 }
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().

◆ onRenameFile()

void PROJECT_TREE_PANE::onRenameFile ( wxCommandEvent &  event)
private

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

Definition at line 847 of file project_tree_pane.cpp.

848 {
849  wxTreeItemId curr_item = m_TreeProject->GetFocusedItem();
850  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
851 
852  // XXX: Unnecessary?
853  if( tree_data.size() != 1 )
854  return;
855 
856  wxString buffer = m_TreeProject->GetItemText( curr_item );
857  wxString msg = wxString::Format( _( "Change filename: \"%s\"" ),
858  tree_data[0]->GetFileName() );
859  wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer );
860 
861  if( dlg.ShowModal() != wxID_OK )
862  return; // canceled by user
863 
864  buffer = dlg.GetValue();
865  buffer.Trim( true );
866  buffer.Trim( false );
867 
868  if( buffer.IsEmpty() )
869  return; // empty file name not allowed
870 
871  tree_data[0]->Rename( buffer, true );
872  m_isRenaming = true;
873 }
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 605 of file project_tree_pane.cpp.

606 {
607  wxTreeItemId curr_item = Event.GetItem();
608 
609  // Ensure item is selected (Under Windows right click does not select the item)
610  m_TreeProject->SelectItem( curr_item );
611 
612  std::vector<PROJECT_TREE_ITEM*> selection = GetSelectedData();
613 
614  bool can_switch_to_project = true;
615  bool can_create_new_directory = true;
616  bool can_open_this_directory = true;
617  bool can_edit = true;
618  bool can_rename = true;
619  bool can_delete = true;
620  bool can_print = true;
621 
622  if( selection.size() == 0 )
623  return;
624 
625  // Remove things that don't make sense for multiple selections
626  if( selection.size() != 1 )
627  {
628  can_switch_to_project = false;
629  can_create_new_directory = false;
630  can_rename = false;
631  can_print = 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  can_print = false;
643  continue;
644  }
645 
646  wxString full_file_name = item->GetFileName();
647 
648  switch( item->GetType() )
649  {
652  can_rename = false;
653  can_print = false;
654 
655  if( item->GetId() == m_TreeProject->GetRootItem() )
656  {
657  can_switch_to_project = false;
658  can_delete = 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  can_rename = false;
671  can_print = false;
672  break;
673 
674  default:
675  can_switch_to_project = false;
676  can_create_new_directory = false;
677  can_open_this_directory = false;
678 
679  if( !CanPrintFile( full_file_name ) )
680  can_print = false;
681 
682  break;
683  }
684  }
685 
686  wxMenu popup_menu;
687  wxString text;
688  wxString help_text;
689 
690  if( can_switch_to_project )
691  {
693  _( "Switch to this Project" ),
694  _( "Close all editors, and switch to the selected project" ),
696  popup_menu.AppendSeparator();
697  }
698 
699  if( can_create_new_directory )
700  {
701  AddMenuItem( &popup_menu, ID_PROJECT_NEWDIR, _( "New Directory..." ),
702  _( "Create a New Directory" ), KiBitmap( BITMAPS::directory ) );
703  }
704 
705  if( can_open_this_directory )
706  {
707  if( selection.size() == 1 )
708  {
709 #ifdef __APPLE__
710  text = _( "Reveal in Finder" );
711  help_text = _( "Reveals the directory in a Finder window" );
712 #else
713  text = _( "Open Directory in File Explorer" );
714  help_text = _( "Opens the directory in the default system file manager" );
715 #endif
716  }
717  else
718  {
719 #ifdef __APPLE__
720  text = _( "Reveal in Finder" );
721  help_text = _( "Reveals the directories in a Finder window" );
722 #else
723  text = _( "Open Directories in File Explorer" );
724  help_text = _( "Opens the directories in the default system file manager" );
725 #endif
726  }
727 
728  AddMenuItem( &popup_menu, ID_PROJECT_OPEN_DIR, text, help_text,
730  }
731 
732  if( can_edit )
733  {
734  if( selection.size() == 1 )
735  help_text = _( "Open the file in a Text Editor" );
736  else
737  help_text = _( "Open files in a Text Editor" );
738 
739  AddMenuItem( &popup_menu, ID_PROJECT_TXTEDIT, _( "Edit in a Text Editor" ),
740  help_text, KiBitmap( BITMAPS::editor ) );
741  }
742 
743  if( can_rename )
744  {
745  if( selection.size() == 1 )
746  {
747  text = _( "Rename File..." );
748  help_text = _( "Rename file" );
749  }
750  else
751  {
752  text = _( "Rename Files..." );
753  help_text = _( "Rename files" );
754  }
755 
756  AddMenuItem( &popup_menu, ID_PROJECT_RENAME, text, help_text, KiBitmap( BITMAPS::right ) );
757  }
758 
759  if( can_delete )
760  {
761  if( selection.size() == 1 )
762  help_text = _( "Delete the file and its content" );
763  else
764  help_text = _( "Delete the files and their contents" );
765 
766  if( can_switch_to_project
767  || can_create_new_directory
768  || can_open_this_directory
769  || can_edit
770  || can_rename )
771  {
772  popup_menu.AppendSeparator();
773  }
774 
775 #ifdef __WINDOWS__
776  AddMenuItem( &popup_menu, ID_PROJECT_DELETE, _( "Delete" ), help_text,
778 #else
779  AddMenuItem( &popup_menu, ID_PROJECT_DELETE, _( "Move to Trash" ), help_text,
781 #endif
782  }
783 
784  if( can_print )
785  {
786  popup_menu.AppendSeparator();
787  AddMenuItem( &popup_menu, ID_PROJECT_PRINT,
788 
789 #ifdef __APPLE__
790  _( "Print..." ),
791 #else
792  _( "Print" ),
793 #endif
794  _( "Print the contents of the file" ), KiBitmap( BITMAPS::print_button ) );
795  }
796 
797  if( popup_menu.GetMenuItemCount() > 0 )
798  PopupMenu( &popup_menu );
799 }
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.
bool CanPrintFile(const wxString &file)
Definition: gestfich.cpp:320

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

◆ onSelect()

void PROJECT_TREE_PANE::onSelect ( wxTreeEvent &  Event)
private

Called on a double click on an item.

Definition at line 876 of file project_tree_pane.cpp.

877 {
878  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
879 
880  if( tree_data.size() != 1 )
881  return;
882 
883  // Bookmark the selected item but don't try and activate it until later. If we do it now,
884  // there will be more events at least on Windows in this frame that will steal focus from
885  // any newly launched windows
886  m_selectedItem = tree_data[0];
887 }
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 185 of file project_tree_pane.cpp.

186 {
187  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
188 
189  if( tree_data.size() != 1 )
190  return;
191 
192  wxString prj_filename = tree_data[0]->GetFileName();
193 
194  m_Parent->LoadProject( prj_filename );
195 }
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 1289 of file project_tree_pane.cpp.

1290 {
1293  m_TreeProject->Refresh();
1294 
1295  aEvent.Skip();
1296 }
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 521 of file project_tree_pane.cpp.

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

174 {
175  if( m_watcher )
176  {
177  m_watcher->RemoveAll();
178  m_watcher->SetOwner( nullptr );
179  delete m_watcher;
180  m_watcher = nullptr;
181  }
182 }
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 201 of file project_tree_pane.h.

Referenced by addItemToProjectTree().

◆ m_isRenaming

bool PROJECT_TREE_PANE::m_isRenaming
private

Definition at line 199 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 200 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 203 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 202 of file project_tree_pane.h.

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

◆ m_watcherNeedReset

bool PROJECT_TREE_PANE::m_watcherNeedReset
private

Definition at line 204 of file project_tree_pane.h.

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


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