From 243a8b6843c7e672ad844395890212222dc085e0 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 17 Jul 2019 11:57:12 +0100 Subject: [PATCH] Fix open in browser on Mac, and use correct terminology. (Mac uses "Reveal in Finder"). Fixes: lp:1836837 * https://bugs.launchpad.net/kicad/+bug/1836837 --- kicad/kicad_manager_frame.h | 3 +- kicad/menubar.cpp | 4 + kicad/tree_project_frame.cpp | 343 ++++++++--------------------------- kicad/tree_project_frame.h | 76 +++----- 4 files changed, 106 insertions(+), 320 deletions(-) diff --git a/kicad/kicad_manager_frame.h b/kicad/kicad_manager_frame.h index 345bb07b0d..2ae6726feb 100644 --- a/kicad/kicad_manager_frame.h +++ b/kicad/kicad_manager_frame.h @@ -41,7 +41,8 @@ class ACTION_TOOLBAR; // s_AllowedExtensionsToList[] enum TreeFileType { - TREE_PROJECT = 1, + TREE_ROOT = 0, + TREE_PROJECT, TREE_SCHEMA, // Schematic file (.sch) TREE_LEGACY_PCB, // board file (.brd) legacy format TREE_SEXP_PCB, // board file (.kicad_brd) new s expression format diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index 673499693d..a6c271fb14 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -190,7 +190,11 @@ void KICAD_MANAGER_FRAME::RecreateBaseHToolbar() KiScaledSeparator( m_mainToolBar, this ); m_mainToolBar->AddTool( ID_BROWSE_IN_FILE_EXPLORER, wxEmptyString, KiScaledBitmap( directory_browser_xpm, this ), +#ifdef __APPLE__ + _( "Reveal project directory in Finder" ) ); +#else _( "Open project directory in file explorer" ) ); +#endif // Create m_mainToolBar m_mainToolBar->Realize(); diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp index 62a565d269..6da7133be7 100644 --- a/kicad/tree_project_frame.cpp +++ b/kicad/tree_project_frame.cpp @@ -109,9 +109,8 @@ const wxString GerberFileExtensionWildCard( ".((gbr|gbrjob|(gb|gt)[alops])|pho)" /** - * @brief class TREE_PROJECT_FRAME is the frame that shows the tree list - * of files and subdirs inside the working directory - * Files are filtered (see s_allowedExtensionsToList) so + * @brief class TREE_PROJECT_FRAME 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. */ @@ -130,8 +129,7 @@ END_EVENT_TABLE() TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) : - wxSashLayoutWindow( parent, ID_LEFT_FRAME, - wxDefaultPosition, wxDefaultSize, + wxSashLayoutWindow( parent, ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL ) { m_Parent = parent; @@ -147,12 +145,12 @@ TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) : */ // NOTE: sch filter must be first because of a test in AddFile() below - m_filters.push_back( wxT( "^.*\\.sch$" ) ); + m_filters.emplace_back( wxT( "^.*\\.sch$" ) ); for( int ii = 0; s_allowedExtensionsToList[ii] != NULL; ii++ ) - m_filters.push_back( s_allowedExtensionsToList[ii] ); + m_filters.emplace_back( s_allowedExtensionsToList[ii] ); - m_filters.push_back( wxT( "^no KiCad files found" ) ); + m_filters.emplace_back( wxT( "^no KiCad files found" ) ); ReCreateTreePrj(); } @@ -169,19 +167,6 @@ TREE_PROJECT_FRAME::~TREE_PROJECT_FRAME() } -void TREE_PROJECT_FRAME::RemoveFilter( const wxString& filter ) -{ - for( unsigned int i = 0; i < m_filters.size(); i++ ) - { - if( filter == m_filters[i] ) - { - m_filters.erase( m_filters.begin() + i ); - return; - } - } -} - - void TREE_PROJECT_FRAME::OnSwitchToSelectedProject( wxCommandEvent& event ) { TREEPROJECT_ITEM* tree_data = GetSelectedData(); @@ -203,21 +188,6 @@ void TREE_PROJECT_FRAME::OnOpenDirectory( wxCommandEvent& event ) if( !treeData ) return; - TreeFileType rootType = treeData->GetType(); - wxTreeItemId root; - - if( TREE_DIRECTORY == rootType ) - { - root = m_TreeProject->GetSelection(); - } - else - { - root = m_TreeProject->GetItemParent( m_TreeProject->GetSelection() ); - - if( !root.IsOk() ) - root = m_TreeProject->GetSelection(); - } - // Ask for the new sub directory name wxString curr_dir = treeData->GetDir(); @@ -234,10 +204,19 @@ void TREE_PROJECT_FRAME::OnOpenDirectory( wxCommandEvent& event ) curr_dir += wxFileName::GetPathSeparator(); } +#ifdef __WXMAC__ + wxString msg; + + // Quote in case there are spaces in the path. + msg.Printf( "open \"%s\"", curr_dir ); + + system( msg.c_str() ); +#else // Quote in case there are spaces in the path. AddDelimiterString( curr_dir ); wxLaunchDefaultApplication( curr_dir ); +#endif } @@ -249,21 +228,6 @@ void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event ) if( !treeData ) return; - TreeFileType rootType = treeData->GetType(); - wxTreeItemId root; - - if( TREE_DIRECTORY == rootType ) - { - root = m_TreeProject->GetSelection(); - } - else - { - root = m_TreeProject->GetItemParent( m_TreeProject->GetSelection() ); - - if( !root.IsOk() ) - root = m_TreeProject->GetSelection(); - } - wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() ); // Ask for the new sub directory name @@ -282,8 +246,8 @@ void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event ) curr_dir += wxFileName::GetPathSeparator(); } - wxString msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) ); - wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir ); + wxString msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) ); + wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir ); if( subdir.IsEmpty() ) return; @@ -300,184 +264,37 @@ void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event ) wxString TREE_PROJECT_FRAME::GetFileExt( TreeFileType type ) { - wxString ext; - switch( type ) { - case TREE_PROJECT: - ext = ProjectFileExtension; - break; - - case TREE_SCHEMA: - ext = SchematicFileExtension; - break; - - case TREE_LEGACY_PCB: - ext = LegacyPcbFileExtension; - break; - - case TREE_SEXP_PCB: - ext = KiCadPcbFileExtension; - break; - - case TREE_GERBER: - ext = GerberFileExtensionWildCard; - break; - - case TREE_HTML: - ext = HtmlFileExtension; - break; - - case TREE_PDF: - ext = PdfFileExtension; - break; - - case TREE_TXT: - ext = TextFileExtension; - break; - - case TREE_NET: - ext = NetlistFileExtension; - break; - - case TREE_CMP_LINK: - ext = ComponentFileExtension; - break; - - case TREE_REPORT: - ext = ReportFileExtension; - break; - - case TREE_FP_PLACE: - ext = FootprintPlaceFileExtension; - break; - - case TREE_DRILL: - ext = DrillFileExtension; - break; - - case TREE_DRILL_NC: - ext = "nc"; - break; - - case TREE_DRILL_XNC: - ext = "xnc"; - break; - - case TREE_SVG: - ext = SVGFileExtension; - break; - - case TREE_PAGE_LAYOUT_DESCR: - ext = PageLayoutDescrFileExtension; - break; - - case TREE_FOOTPRINT_FILE: - ext = KiCadFootprintFileExtension; - break; - - case TREE_SCHEMATIC_LIBFILE: - ext = SchematicLibraryFileExtension; - break; - - default: // Eliminates unnecessary GCC warning. - break; + case TREE_PROJECT: return ProjectFileExtension; + case TREE_SCHEMA: return SchematicFileExtension; + case TREE_LEGACY_PCB: return LegacyPcbFileExtension; + case TREE_SEXP_PCB: return KiCadPcbFileExtension; + case TREE_GERBER: return GerberFileExtensionWildCard; + case TREE_HTML: return HtmlFileExtension; + case TREE_PDF: return PdfFileExtension; + case TREE_TXT: return TextFileExtension; + case TREE_NET: return NetlistFileExtension; + case TREE_CMP_LINK: return ComponentFileExtension; + case TREE_REPORT: return ReportFileExtension; + case TREE_FP_PLACE: return FootprintPlaceFileExtension; + case TREE_DRILL: return DrillFileExtension; + case TREE_DRILL_NC: return "nc"; + case TREE_DRILL_XNC: return "xnc"; + case TREE_SVG: return SVGFileExtension; + case TREE_PAGE_LAYOUT_DESCR: return PageLayoutDescrFileExtension; + case TREE_FOOTPRINT_FILE: return KiCadFootprintFileExtension; + case TREE_SCHEMATIC_LIBFILE: return SchematicLibraryFileExtension; + default: return wxEmptyString; } - - return ext; -} - - -wxString TREE_PROJECT_FRAME::GetFileWildcard( TreeFileType type ) -{ - wxString ext; - - switch( type ) - { - case TREE_PROJECT: - ext = ProjectFileWildcard(); - break; - - case TREE_SCHEMA: - ext = SchematicFileWildcard(); - break; - - case TREE_LEGACY_PCB: - case TREE_SEXP_PCB: - ext = PcbFileWildcard(); - break; - - case TREE_GERBER: - ext = GerberFileWildcard(); - break; - - case TREE_HTML: - ext = HtmlFileWildcard(); - break; - - case TREE_PDF: - ext = PdfFileWildcard(); - break; - - case TREE_TXT: - ext = TextFileWildcard(); - break; - - case TREE_NET: - ext = NetlistFileWildcard(); - break; - - case TREE_CMP_LINK: - ext = ComponentFileWildcard(); - break; - - case TREE_REPORT: - ext = ReportFileWildcard(); - break; - - case TREE_FP_PLACE: - ext = FootprintPlaceFileWildcard(); - break; - - case TREE_DRILL: - case TREE_DRILL_NC: - case TREE_DRILL_XNC: - ext = DrillFileWildcard(); - break; - - case TREE_SVG: - ext = SVGFileWildcard(); - break; - - case TREE_PAGE_LAYOUT_DESCR: - ext = PageLayoutDescrFileWildcard(); - break; - - case TREE_FOOTPRINT_FILE: - ext = KiCadFootprintLibFileWildcard(); - break; - - case TREE_SCHEMATIC_LIBFILE: - ext = SchematicLibraryFileWildcard(); - break; - - default: // Eliminates unnecessary GCC warning. - break; - } - - return ext; } bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, - wxTreeItemId& aRoot, bool aRecurse ) + wxTreeItemId& aRoot, bool aRecurse ) { wxTreeItemId cellule; - - // Check the file type TreeFileType type = TREE_UNKNOWN; - - // Skip not visible files and dirs wxFileName fn( aName ); // Files/dirs names starting by "." are not visible files under unices. @@ -531,8 +348,8 @@ bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, // This is an ugly fix. if( isSchematic ) { - wxString fullFileName = aName.BeforeLast( '.' ); - wxString rootName; + wxString fullFileName = aName.BeforeLast( '.' ); + wxString rootName; TREEPROJECT_ITEM* itemData = GetItemIdData( m_root ); if( itemData ) @@ -600,9 +417,7 @@ bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, if( itemData ) { if( itemData->GetFileName() == aName ) - { return true; // well, we would have added it, but it is already here! - } } kid = m_TreeProject->GetNextChild( aRoot, cookie ); @@ -657,9 +472,7 @@ bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, void TREE_PROJECT_FRAME::ReCreateTreePrj() { - wxTreeItemId rootcellule; - bool prjOpened = false; - wxString pro_dir = m_Parent->GetProjectFileName(); + wxString pro_dir = m_Parent->GetProjectFileName(); if( !m_TreeProject ) m_TreeProject = new TREEPROJECTFILES( this ); @@ -679,19 +492,13 @@ void TREE_PROJECT_FRAME::ReCreateTreePrj() fn.SetExt( ProjectFileExtension ); } - prjOpened = fn.FileExists(); + bool prjOpened = fn.FileExists(); // root tree: - m_root = rootcellule = m_TreeProject->AddRoot( fn.GetFullName(), - TREE_PROJECT - 1, - TREE_PROJECT - 1 ); - - m_TreeProject->SetItemBold( rootcellule, true ); - - m_TreeProject->SetItemData( rootcellule, - new TREEPROJECT_ITEM( TREE_PROJECT, - fn.GetFullPath(), - m_TreeProject ) ); + m_root = m_TreeProject->AddRoot( fn.GetFullName(), TREE_ROOT, TREE_ROOT ); + m_TreeProject->SetItemBold( m_root, true ); + m_TreeProject->SetItemData( m_root, new TREEPROJECT_ITEM( TREE_PROJECT, fn.GetFullPath(), + m_TreeProject ) ); // Now adding all current files if available if( prjOpened ) @@ -721,7 +528,7 @@ void TREE_PROJECT_FRAME::ReCreateTreePrj() m_TreeProject->AppendItem( m_root, wxT( "Empty project" ) ); } - m_TreeProject->Expand( rootcellule ); + m_TreeProject->Expand( m_root ); // Sort filenames by alphabetic order m_TreeProject->SortChildren( m_root ); @@ -768,8 +575,13 @@ void TREE_PROJECT_FRAME::OnRight( wxTreeEvent& Event ) KiBitmap( directory_xpm ) ); AddMenuItem( &popupMenu, ID_PROJECT_OPEN_DIR, - _( "&Open Directory in System" ), +#ifdef __APPLE__ + _( "Reveal in Finder" ), + _( "Reveals the directory in a Finder window" ), +#else + _( "&Open Directory in File Explorer" ), _( "Opens the directory in the default system file manager" ), +#endif KiBitmap( directory_browser_xpm ) ); break; @@ -779,8 +591,13 @@ void TREE_PROJECT_FRAME::OnRight( wxTreeEvent& Event ) _( "Create a New Directory" ), KiBitmap( directory_xpm ) ); AddMenuItem( &popupMenu, ID_PROJECT_OPEN_DIR, - _( "&Open Directory in System" ), +#ifdef __APPLE__ + _( "Reveal in Finder" ), + _( "Reveals the directory in a Finder window" ), +#else + _( "&Open Directory in File Explorer" ), _( "Opens the directory in the default system file manager" ), +#endif KiBitmap( directory_browser_xpm ) ); AddMenuItem( &popupMenu, ID_PROJECT_DELETE, _( "&Delete Directory" ), @@ -812,10 +629,7 @@ void TREE_PROJECT_FRAME::OnOpenSelectedFileWithTextEditor( wxCommandEvent& event { TREEPROJECT_ITEM* tree_data = GetSelectedData(); - if( !tree_data ) - return; - - if( tree_data->GetType() == TREE_DIRECTORY ) + if( !tree_data || tree_data->GetType() == TREE_DIRECTORY ) return; wxString fullFileName = tree_data->GetFileName(); @@ -847,11 +661,8 @@ void TREE_PROJECT_FRAME::OnRenameFile( wxCommandEvent& ) return; wxString buffer = m_TreeProject->GetItemText( curr_item ); - wxString msg = wxString::Format( - _( "Change filename: \"%s\"" ), - GetChars( tree_data->GetFileName() ) ); - - wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer ); + wxString msg = wxString::Format( _( "Change filename: \"%s\"" ), tree_data->GetFileName() ); + wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer ); if( dlg.ShowModal() != wxID_OK ) return; // canceled by user @@ -930,19 +741,16 @@ void TREE_PROJECT_FRAME::OnExpand( wxTreeEvent& Event ) m_TreeProject->SortChildren( kid ); } +#ifndef __WINDOWS__ if( subdir_populated ) - { - #ifndef __WINDOWS__ FileWatcherReset(); - #endif - } +#endif } TREEPROJECT_ITEM* TREE_PROJECT_FRAME::GetSelectedData() { - return dynamic_cast( m_TreeProject->GetItemData - ( m_TreeProject->GetSelection() ) ); + return GetItemIdData( m_TreeProject->GetSelection() ); } @@ -968,7 +776,7 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir ) wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie ); - while( 1 ) + while( true ) { if( ! kid.IsOk() ) { @@ -1019,11 +827,7 @@ void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event ) switch( event.GetChangeType() ) { case wxFSW_EVENT_DELETE: - break; - case wxFSW_EVENT_CREATE: - break; - case wxFSW_EVENT_RENAME: break; @@ -1102,19 +906,18 @@ void TREE_PROJECT_FRAME::FileWatcherReset() m_watcher->SetOwner( this ); } - // Add directories which should be monitored. - // under windows, we add the curr dir and all subdirs - // under unix, we add only the curr dir and the populated subdirs - // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm - // under unix, the file watcher needs more work to be efficient - // moreover, under wxWidgets 2.9.4, AddTree does not work properly. - // We can see wxString under a debugger, not a wxFileName wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() ); wxFileName fn; fn.AssignDir( prj_dir ); fn.DontFollowLink(); + // Add directories which should be monitored. + // under windows, we add the curr dir and all subdirs + // under unix, we add only the curr dir and the populated subdirs + // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm + // under unix, the file watcher needs more work to be efficient + // moreover, under wxWidgets 2.9.4, AddTree does not work properly. #ifdef __WINDOWS__ m_watcher->AddTree( fn ); #else @@ -1128,7 +931,7 @@ void TREE_PROJECT_FRAME::FileWatcherReset() wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie ); - while( 1 ) + while( true ) { if( !kid.IsOk() ) { diff --git a/kicad/tree_project_frame.h b/kicad/tree_project_frame.h index 9fffcad2e1..19ef5d4313 100644 --- a/kicad/tree_project_frame.h +++ b/kicad/tree_project_frame.h @@ -74,8 +74,7 @@ public: void FileWatcherReset(); protected: - static wxString GetFileExt( TreeFileType type ); - static wxString GetFileWildcard( TreeFileType type ); + static wxString GetFileExt( TreeFileType type ); /** * Function GetSelectedData @@ -83,7 +82,7 @@ protected: * Note this is not necessary the "clicked" item, * because when expanding, collapsing an item this item is not selected */ - TREEPROJECT_ITEM* GetSelectedData(); + TREEPROJECT_ITEM* GetSelectedData(); /** * Function GetItemIdData @@ -91,80 +90,64 @@ protected: * @param aId = the wxTreeItemId identifier. * @return a TREEPROJECT_ITEM pointer correspondinfg to item id aId */ - TREEPROJECT_ITEM* GetItemIdData( wxTreeItemId aId ); + TREEPROJECT_ITEM* GetItemIdData( wxTreeItemId aId ); private: /** * Called on a double click on an item */ - void OnSelect( wxTreeEvent& Event ); + void OnSelect( wxTreeEvent& Event ); /** * Called on a click on the + or - button of an item with children */ - void OnExpand( wxTreeEvent& Event ); + void OnExpand( wxTreeEvent& Event ); /** * Called on a right click on an item */ - void OnRight( wxTreeEvent& Event ); + void OnRight( wxTreeEvent& Event ); /** * Function OnOpenSelectedFileWithTextEditor * Called via the popup menu, when right clicking on a file name - * Call the text editor to open the selected file - * in the tree project + * Call the text editor to open the selected file in the tree project */ - void OnOpenSelectedFileWithTextEditor( wxCommandEvent& event ); + void OnOpenSelectedFileWithTextEditor( wxCommandEvent& event ); /** * Function OnDeleteFile - * Called via the popup menu, when right clicking on a file name - * or a directory name to delete the selected file or directory - * in the tree project + * Called via the popup menu, when right clicking on a file name or a directory name to + * delete the selected file or directory in the tree project */ - void OnDeleteFile( wxCommandEvent& event ); + void OnDeleteFile( wxCommandEvent& event ); /** * Function OnRenameFile - * Called via the popup menu, when right clicking on a file name - * or a directory name to rename the selected file or directory - * in the tree project + * Called via the popup menu, when right clicking on a file name or a directory name to + * rename the selected file or directory in the tree project */ - void OnRenameFile( wxCommandEvent& event ); + void OnRenameFile( wxCommandEvent& event ); /** * Function OnOpenDirectory - * Handles the right-click menu for opening a directory in the current system - * file browser + * Handles the right-click menu for opening a directory in the current system file browser */ - void OnOpenDirectory( wxCommandEvent& event ); + void OnOpenDirectory( wxCommandEvent& event ); /** * Function OnCreateNewDirectory - * Creates a new subdirectory inside the current kicad project directory - * the user is prompted to enter a directory name + * Creates a new subdirectory inside the current kicad project directory the user is + * prompted to enter a directory name */ - void OnCreateNewDirectory( wxCommandEvent& event ); + void OnCreateNewDirectory( wxCommandEvent& event ); /** - * Switch to a other project selected from the tree project - * (by selecting an other .pro file inside the current project folder) + * Switch to a other project selected from the tree project (by selecting an other .pro + * file inside the current project folder) */ void OnSwitchToSelectedProject( wxCommandEvent& event ); - void ClearFilters() - { - m_filters.clear(); - } - - const std::vector& GetFilters() - { - return m_filters; - } - - void RemoveFilter( const wxString& filter ); - /** * Function AddItemToTreeProject * @brief Add the file or directory aName to the project tree @@ -174,26 +157,21 @@ private: * false to stop file add. * @return true if the file (or directory) is added. */ - bool AddItemToTreeProject( const wxString& aName, - wxTreeItemId& aRoot, - bool aRecurse = true ); + bool AddItemToTreeProject( const wxString& aName, wxTreeItemId& aRoot, bool aRecurse = true ); /** * Function findSubdirTreeItem - * searches for the item in tree project which is the - * node of the subdirectory aSubDir + * searches for the item in tree project which is the node of the subdirectory aSubDir * @param aSubDir = the directory to find in tree - * @return the opaque reference to the tree item. - * if not found, return an invalid tree item. - * therefore wxTreeItemId::IsOk should be used to test - * the returned value + * @return 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 */ wxTreeItemId findSubdirTreeItem( const wxString& aSubDir ); /** * 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 + * The tree project is modified when a file or directory is created/deleted/renamed to + * reflect the file change */ void OnFileSystemEvent( wxFileSystemWatcherEvent& event );