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)
 class PROJECT_TREE_PANE is the frame that shows the tree list of files and subdirs 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...
 
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...
 

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)

class PROJECT_TREE_PANE is the frame that shows the tree list of files and subdirs 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;
143  m_isRenaming = false;
144  m_selectedItem = nullptr;
145  m_watcherNeedReset = false;
146 
147  m_watcher = NULL;
148  Connect( wxEVT_FSWATCHER,
149  wxFileSystemWatcherEventHandler( PROJECT_TREE_PANE::onFileSystemEvent ) );
150 
151  /*
152  * Filtering is now inverted: the filters are actually used to _enable_ support
153  * for a given file type.
154  */
155  for( int ii = 0; s_allowedExtensionsToList[ii] != NULL; ii++ )
156  m_filters.emplace_back( s_allowedExtensionsToList[ii] );
157 
158  m_filters.emplace_back( wxT( "^no KiCad files found" ) );
159 
160  ReCreateTreePrj();
161 }
std::vector< wxString > m_filters
void ReCreateTreePrj()
Create or modify the tree showing project file names.
PROJECT_TREE_ITEM * m_selectedItem
#define NULL
PROJECT_TREE * m_TreeProject
static const wxChar * s_allowedExtensionsToList[]
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 NULL, onFileSystemEvent(), and s_allowedExtensionsToList.

◆ ~PROJECT_TREE_PANE()

PROJECT_TREE_PANE::~PROJECT_TREE_PANE ( )

Definition at line 164 of file project_tree_pane.cpp.

165 {
166  if( m_watcher )
167  {
168  m_watcher->RemoveAll();
169  m_watcher->SetOwner( NULL );
170  delete m_watcher;
171  }
172 }
#define NULL
wxFileSystemWatcher * m_watcher

References m_watcher, and NULL.

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

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

1295 {
1296  m_TreeProject->DeleteAllItems();
1297 }
PROJECT_TREE * m_TreeProject

References m_TreeProject.

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

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

1016 {
1017  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
1018 
1019  // If the subdir is the current working directory, return m_root
1020  // in main list:
1021  if( prj_dir == aSubDir )
1022  return m_root;
1023 
1024  // The subdir is in the main tree or in a subdir: Locate it
1025  wxTreeItemIdValue cookie;
1026  wxTreeItemId root_id = m_root;
1027  std::stack < wxTreeItemId > subdirs_id;
1028 
1029  wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
1030 
1031  while( true )
1032  {
1033  if( ! kid.IsOk() )
1034  {
1035  if( subdirs_id.empty() ) // all items were explored
1036  {
1037  root_id = kid; // Not found: return an invalid wxTreeItemId
1038  break;
1039  }
1040  else
1041  {
1042  root_id = subdirs_id.top();
1043  subdirs_id.pop();
1044  kid = m_TreeProject->GetFirstChild( root_id, cookie );
1045 
1046  if( ! kid.IsOk() )
1047  continue;
1048  }
1049  }
1050 
1051  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
1052 
1053  if( itemData && ( itemData->GetType() == TREE_FILE_TYPE::DIRECTORY ) )
1054  {
1055  if( itemData->GetFileName() == aSubDir ) // Found!
1056  {
1057  root_id = kid;
1058  break;
1059  }
1060 
1061  // kid is a subdir, push in list to explore it later
1062  if( itemData->IsPopulated() )
1063  subdirs_id.push( kid );
1064  }
1065 
1066  kid = m_TreeProject->GetNextChild( root_id, cookie );
1067  }
1068 
1069  return root_id;
1070 }
const wxString & GetFileName() const
const wxString GetProjectFileName() const
bool IsPopulated() const
TREE_FILE_TYPE GetType() const
PROJECT_TREE * m_TreeProject
PROJECT_TREE_ITEM handles 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 261 of file project_tree_pane.cpp.

262 {
263  switch( type )
264  {
281  case TREE_FILE_TYPE::DRILL_NC: return "nc";
282  case TREE_FILE_TYPE::DRILL_XNC: return "xnc";
289  default: return wxEmptyString;
290  }
291 }
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 ComponentFileExtension
const std::string KiCadPcbFileExtension
const std::string HtmlFileExtension
const wxString GerberFileExtensionWildCard(".((gbr|gbrjob|(gb|gt)[alops])|pho)")
const std::string GerberJobFileExtension
const wxChar TextFileExtension[]
const std::string LegacyProjectFileExtension
const std::string PdfFileExtension
const std::string LegacySchematicFileExtension
const std::string PageLayoutDescrFileExtension
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, ComponentFileExtension, DESIGN_RULES, DesignRulesFileExtension, DRILL, DRILL_NC, DRILL_XNC, DrillFileExtension, FOOTPRINT_FILE, 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, PAGE_LAYOUT_DESCR, PageLayoutDescrFileExtension, 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 1009 of file project_tree_pane.cpp.

1010 {
1011  return dynamic_cast<PROJECT_TREE_ITEM*>( m_TreeProject->GetItemData( aId ) );
1012 }
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 995 of file project_tree_pane.cpp.

996 {
997  wxArrayTreeItemIds selection;
998  std::vector<PROJECT_TREE_ITEM*> data;
999 
1000  m_TreeProject->GetSelections( selection );
1001 
1002  for( auto it = selection.begin(); it != selection.end(); it++ )
1003  data.push_back( GetItemIdData( *it ) );
1004 
1005  return data;
1006 }
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 233 of file project_tree_pane.cpp.

234 {
235  // Get the root directory name:
236  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
237 
238  for( PROJECT_TREE_ITEM* item_data : tree_data )
239  {
240  wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
241 
242  // Ask for the new sub directory name
243  wxString curr_dir = item_data->GetDir();
244 
245  if( curr_dir.IsEmpty() )
246  curr_dir = prj_dir;
247 
248  wxString new_dir = wxGetTextFromUser( _( "Directory name:" ), _( "Create New Directory" ) );
249 
250  if( new_dir.IsEmpty() )
251  return;
252 
253  wxString full_dirname = curr_dir + wxFileName::GetPathSeparator() + new_dir;
254 
255  wxMkdir( full_dirname );
256  addItemToProjectTree( full_dirname, item_data->GetId(), nullptr, false );
257  }
258 }
const wxString GetProjectFileName() const
#define _(s)
Definition: 3d_actions.cpp:33
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
PROJECT_TREE_ITEM handles 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 828 of file project_tree_pane.cpp.

829 {
830  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
831  wxString msg, caption;
832 
833  if( tree_data.size() == 1 )
834  {
835  bool is_directory = wxDirExists( tree_data[0]->GetFileName() );
836  caption = is_directory ? _( "Delete Directory" ) : _( "Delete File" );
837  msg = wxString::Format( _( "Are you sure you want to delete '%s'?" ),
838  tree_data[0]->GetFileName() );
839  }
840  else
841  {
842  msg = wxString::Format( _( "Are you sure you want to delete %lu items?" ),
843  tree_data.size() );
844  caption = _( "Delete Multiple Items" );
845  }
846 
847  wxMessageDialog dialog( m_parent, msg, caption, wxYES_NO | wxICON_QUESTION );
848 
849  if( dialog.ShowModal() == wxID_YES )
850  {
851  for( PROJECT_TREE_ITEM* item_data : tree_data )
852  item_data->Delete();
853  }
854 }
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
#define _(s)
Definition: 3d_actions.cpp:33
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
PROJECT_TREE_ITEM handles one item (a file or a directory name) for the tree file.

References _, Format(), and 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 931 of file project_tree_pane.cpp.

932 {
933  wxTreeItemId itemId = Event.GetItem();
934  PROJECT_TREE_ITEM* tree_data = GetItemIdData( itemId );
935 
936  if( !tree_data )
937  return;
938 
939  if( tree_data->GetType() != TREE_FILE_TYPE::DIRECTORY )
940  return;
941 
942  // explore list of non populated subdirs, and populate them
943  wxTreeItemIdValue cookie;
944  wxTreeItemId kid = m_TreeProject->GetFirstChild( itemId, cookie );
945 
946 #ifndef __WINDOWS__
947  bool subdir_populated = false;
948 #endif
949 
950  for( ; kid.IsOk(); kid = m_TreeProject->GetNextChild( itemId, cookie ) )
951  {
952  PROJECT_TREE_ITEM* itemData = GetItemIdData( kid );
953 
954  if( !itemData || itemData->GetType() != TREE_FILE_TYPE::DIRECTORY )
955  continue;
956 
957  if( itemData->IsPopulated() )
958  continue;
959 
960  wxString fileName = itemData->GetFileName();
961  wxDir dir( fileName );
962 
963  if( dir.IsOpened() )
964  {
965  std::vector<wxString> projects = getProjects( dir );
966  wxString dir_filename;
967  bool haveFile = dir.GetFirst( &dir_filename );
968 
969  while( haveFile )
970  {
971  // Add name to tree item, but do not recurse in subdirs:
972  wxString name = fileName + wxFileName::GetPathSeparator() + dir_filename;
973  addItemToProjectTree( name, kid, &projects, false );
974 
975  haveFile = dir.GetNext( &dir_filename );
976  }
977 
978  itemData->SetPopulated( true ); // set state to populated
979 #ifndef __WINDOWS__
980  subdir_populated = true;
981 #endif
982  }
983 
984  // Sort filenames by alphabetic order
985  m_TreeProject->SortChildren( kid );
986  }
987 
988 #ifndef __WINDOWS__
989  if( subdir_populated )
990  m_watcherNeedReset = true;
991 #endif
992 }
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:59
PROJECT_TREE_ITEM handles 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 1073 of file project_tree_pane.cpp.

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

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

910 {
911  // Idle executes once all other events finished processing. This makes it ideal to launch
912  // a new window without starting Focus wars.
913  if( m_watcherNeedReset )
914  {
915  m_selectedItem = nullptr;
917  }
918 
919  if( m_selectedItem != nullptr )
920  {
921  // Activate launches a window which may run the event loop on top of us and cause OnIdle
922  // to get called again, so be sure to block off the activation condition first.
924  m_selectedItem = nullptr;
925 
926  item->Activate( this );
927  }
928 }
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 ...
PROJECT_TREE_ITEM handles 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 188 of file project_tree_pane.cpp.

189 {
190  // Get the root directory name:
191  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
192 
193  for( PROJECT_TREE_ITEM* item_data : tree_data )
194  {
195  // Ask for the new sub directory name
196  wxString curr_dir = item_data->GetDir();
197 
198  if( curr_dir.IsEmpty() )
199  {
200  // Use project path if the tree view path was empty.
201  curr_dir = wxPathOnly( m_Parent->GetProjectFileName() );
202 
203  // As a last resort use the user's documents folder.
204  if( curr_dir.IsEmpty() || !wxFileName::DirExists( curr_dir ) )
206 
207  if( !curr_dir.IsEmpty() )
208  curr_dir += wxFileName::GetPathSeparator();
209  }
210 
211 #ifdef __WXMAC__
212  wxString msg;
213 
214  // Quote in case there are spaces in the path.
215  msg.Printf( "open \"%s\"", curr_dir );
216 
217  system( msg.c_str() );
218 #else
219  #if !wxCHECK_VERSION( 3, 1, 0 )
220  // Quote in case there are spaces in the path.
221  // Not needed on 3.1.4, but needed in 3.0 versions
222  // Moreover, on Linux, on 3.1.4 wx version, adding quotes breaks
223  // wxLaunchDefaultApplication
224  AddDelimiterString( curr_dir );
225  #endif
226 
227  wxLaunchDefaultApplication( curr_dir );
228 #endif
229  }
230 }
const wxString GetProjectFileName() const
void AddDelimiterString(wxString &string)
Add un " to the start and the end of string (if not already done).
Definition: gestfich.cpp:42
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:130
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
PROJECT_TREE_ITEM handles one item (a file or a directory name) for the tree file.
KICAD_MANAGER_FRAME * m_Parent

References AddDelimiterString(), PATHS::GetDefaultUserProjectsPath(), KICAD_MANAGER_FRAME::GetProjectFileName(), GetSelectedData(), 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().GetEditorName();
805 
806  if( editorname.IsEmpty() )
807  return;
808 
809  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
810 
811  wxString files;
812 
813  for( PROJECT_TREE_ITEM* item_data : tree_data )
814  {
815  wxString fullFileName = item_data->GetFileName();
816  AddDelimiterString( fullFileName );
817 
818  if( !files.IsEmpty() )
819  files += " ";
820 
821  files += fullFileName;
822  }
823 
824  ExecuteFile( this, editorname, files );
825 }
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void AddDelimiterString(wxString &string)
Add un " to the start and the end of string (if not already done).
Definition: gestfich.cpp:42
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
PROJECT_TREE_ITEM handles one item (a file or a directory name) for the tree file.
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString &param, wxProcess *callback)
Call the executable file ExecFile with the command line parameters param.
Definition: gestfich.cpp:165

References AddDelimiterString(), 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 857 of file project_tree_pane.cpp.

858 {
859  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
860 
861  for( PROJECT_TREE_ITEM* item_data : tree_data )
862  item_data->Print();
863 }
std::vector< PROJECT_TREE_ITEM * > GetSelectedData()
Function GetSelectedData return the item data from item currently selected (highlighted) Note this is...
PROJECT_TREE_ITEM handles 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 866 of file project_tree_pane.cpp.

867 {
868  wxTreeItemId curr_item = m_TreeProject->GetFocusedItem();
869  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
870 
871  // XXX: Unnecessary?
872  if( tree_data.size() != 1 )
873  return;
874 
875  wxString buffer = m_TreeProject->GetItemText( curr_item );
876  wxString msg = wxString::Format( _( "Change filename: \"%s\"" ),
877  tree_data[0]->GetFileName() );
878  wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer );
879 
880  if( dlg.ShowModal() != wxID_OK )
881  return; // canceled by user
882 
883  buffer = dlg.GetValue();
884  buffer.Trim( true );
885  buffer.Trim( false );
886 
887  if( buffer.IsEmpty() )
888  return; // empty file name not allowed
889 
890  tree_data[0]->Rename( buffer, true );
891  m_isRenaming = true;
892 }
PROJECT_TREE * m_TreeProject
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
#define _(s)
Definition: 3d_actions.cpp:33
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 611 of file project_tree_pane.cpp.

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

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

896 {
897  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
898 
899  if( tree_data.size() != 1 )
900  return;
901 
902  // Bookmark the selected item but don't try and activate it until later. If we do it now,
903  // there will be more events at least on Windows in this frame that will steal focus from
904  // any newly launched windows
905  m_selectedItem = tree_data[0];
906 }
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 175 of file project_tree_pane.cpp.

176 {
177  std::vector<PROJECT_TREE_ITEM*> tree_data = GetSelectedData();
178 
179  if( tree_data.size() != 1 )
180  return;
181 
182  wxString prj_filename = tree_data[0]->GetFileName();
183 
184  m_Parent->LoadProject( prj_filename );
185 }
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.

◆ ReCreateTreePrj()

void PROJECT_TREE_PANE::ReCreateTreePrj ( )

Create or modify the tree showing project file names.

Definition at line 527 of file project_tree_pane.cpp.

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

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 193 of file project_tree_pane.h.

Referenced by addItemToProjectTree().

◆ m_isRenaming

bool PROJECT_TREE_PANE::m_isRenaming
private

Definition at line 191 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 192 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 195 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 194 of file project_tree_pane.h.

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

◆ m_watcherNeedReset

bool PROJECT_TREE_PANE::m_watcherNeedReset
private

Definition at line 196 of file project_tree_pane.h.

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


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