diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index bd6ecdee6b..5ddb965d20 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -31,12 +31,6 @@ #include #include -#ifdef USE_SPLASH_IMAGE - #define SPLASH_IMAGE logo_kicad.png - #include "wx/splash.h" - #include "wx/mediactrl.h" -#endif - #include #include #include @@ -45,12 +39,6 @@ const wxString g_KicadPrjFilenameExtension( wxT( ".pro" ) ); -/* Import functions */ -char* GetFileName( char* FullPathName ); -void ShowLogo( char* FonteFileName ); - -/* Local functions */ - /************************************/ /* Called to initialize the program */ /************************************/ @@ -113,7 +101,8 @@ bool EDA_APP::OnInit() wxFileName namelessProject( wxGetCwd(), NAMELESS_PROJECT, ProjectFileExtension ); frame = new KICAD_MANAGER_FRAME( NULL, wxT( "KiCad" ), - wxPoint( 30, 20 ), wxSize( 600, 400 ) ); + wxDefaultPosition, wxDefaultSize ); + SetTopWindow( frame ); if( argc > 1 ) { @@ -141,38 +130,6 @@ bool EDA_APP::OnInit() frame->OnLoadProject( cmd ); } - wxString title = GetTitle() + wxT( " " ) + GetBuildVersion() + - wxT( " " ) + frame->m_ProjectFileName.GetFullPath(); - - if( !namelessProject.IsDirWritable() ) - title += _( " [Read Only]" ); - - frame->SetTitle( title ); - frame->ReCreateMenuBar(); - frame->RecreateBaseHToolbar(); - - frame->m_LeftWin->ReCreateTreePrj(); - SetTopWindow( frame ); - - /* Splash screen logo */ -#ifdef USE_SPLASH_IMAGE - wxBitmap bmp; - wxString binDir = GetTraits()->GetStandardPaths().GetExecutablePath() + - wxFileName::GetPathSeparator(); - - if( bmp.LoadFile( binDir + _T( "logokicad.png" ), wxBITMAP_TYPE_PNG ) ) - { - wxSplashScreen* splash = new wxSplashScreen( splash_screen, - wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, - 3000, - frame, - wxID_ANY, - wxDefaultPosition, - wxDefaultSize, - wxSIMPLE_BORDER | wxSTAY_ON_TOP ); - } -#endif /* USE_SPLASH_IMAGE */ - frame->Show( true ); frame->Raise(); diff --git a/kicad/kicad.h b/kicad/kicad.h index de75b29e32..5e3074469a 100644 --- a/kicad/kicad.h +++ b/kicad/kicad.h @@ -15,6 +15,12 @@ #include #include +// With a recent wxWidget, we can use the wxFileSystemWatcherEvent +// to monitor files add/remove/rename in tree project +#if wxCHECK_VERSION( 2, 9, 4 ) +#define KICAD_USE_FILES_WATCHER +#endif + extern const wxString g_KicadPrjFilenameExtension; class RIGHT_KM_FRAME; @@ -77,7 +83,8 @@ enum id_kicad_frm { ID_SELECT_PREFERED_PDF_BROWSER, ID_SELECT_DEFAULT_PDF_BROWSER, ID_SAVE_AND_ZIP_FILES, - ID_READ_ZIP_ARCHIVE + ID_READ_ZIP_ARCHIVE, + ID_INIT_WATCHED_PATHS }; @@ -175,6 +182,15 @@ public: KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title, */ void SaveSettings(); +#ifdef KICAD_USE_FILES_WATCHER + void FileWatcherReset(); + /** + * Called by sending a event with id = ID_INIT_WATCHED_PATHS + * rebuild the list of wahtched paths + */ + void OnChangeWatchedPaths(wxCommandEvent& aEvent ); +#endif + DECLARE_EVENT_TABLE() }; diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index dd06cdb2b5..bbf53744d2 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -89,6 +89,7 @@ KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, PrintMsg( line ); RecreateBaseHToolbar(); + ReCreateMenuBar(); m_auimgr.SetManagedWindow( this ); diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index 3202d365e2..9afb07cf6f 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -31,6 +31,7 @@ #include #include #include +#include /* Menubar and toolbar event table */ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) @@ -67,9 +68,13 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) /* Range menu events */ EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::SetLanguage ) - EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, KICAD_MANAGER_FRAME::OnFileHistory ) + // Special functions + #ifdef KICAD_USE_FILES_WATCHER + EVT_MENU( ID_INIT_WATCHED_PATHS, KICAD_MANAGER_FRAME::OnChangeWatchedPaths ) + #endif + /* Button events */ EVT_BUTTON( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew ) EVT_BUTTON( ID_TO_CVPCB, KICAD_MANAGER_FRAME::OnRunCvpcb ) diff --git a/kicad/prjconfig.cpp b/kicad/prjconfig.cpp index c8d2fa104f..13a41a5029 100644 --- a/kicad/prjconfig.cpp +++ b/kicad/prjconfig.cpp @@ -222,10 +222,14 @@ void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event ) SetTitle( title ); UpdateFileHistory( m_ProjectFileName.GetFullPath() ); -#if wxCHECK_VERSION( 2, 9, 2 ) - m_LeftWin->FileWatcherReset(); -#endif m_LeftWin->ReCreateTreePrj(); +#ifdef KICAD_USE_FILES_WATCHER + // Rebuild the list of watched paths. + // however this is possible only when the main loop event handler is running, + // so we use it to rub the rebuild function. + wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS ); + wxPostEvent( this, cmd); +#endif PrintMsg( _( "Working dir: " ) + m_ProjectFileName.GetPath() + _( "\nProject: " ) + m_ProjectFileName.GetFullName() + diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp index 244611ef04..f12ed3de45 100644 --- a/kicad/tree_project_frame.cpp +++ b/kicad/tree_project_frame.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -137,9 +136,8 @@ TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) : m_TreeProject = NULL; wxMenuItem* item; m_PopupMenu = NULL; -#if wxCHECK_VERSION( 2, 9, 2 ) - m_watcher = new wxFileSystemWatcher(); - m_watcher->SetOwner( this ); +#ifdef KICAD_USE_FILES_WATCHER + m_watcher = NULL; Connect( wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler( TREE_PROJECT_FRAME::OnFileSystemEvent ) ); #endif @@ -235,7 +233,7 @@ TREE_PROJECT_FRAME::~TREE_PROJECT_FRAME() if( m_PopupMenu ) delete m_PopupMenu; -#if wxCHECK_VERSION( 2, 9, 2 ) +#ifdef KICAD_USE_FILES_WATCHER delete m_watcher; #endif } @@ -935,6 +933,7 @@ void TREE_PROJECT_FRAME::OnExpand( wxTreeEvent& Event ) wxTreeItemIdValue cookie; wxTreeItemId kid = m_TreeProject->GetFirstChild( itemId, cookie ); + bool subdir_populated = false; for( ; kid.IsOk(); kid = m_TreeProject->GetNextChild( itemId, cookie ) ) { TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); @@ -959,10 +958,20 @@ void TREE_PROJECT_FRAME::OnExpand( wxTreeEvent& Event ) } itemData->m_WasPopulated = true; // set state to populated + subdir_populated = true; /* Sort filenames by alphabetic order */ m_TreeProject->SortChildren( kid ); } + + if( subdir_populated ) + { +#ifdef KICAD_USE_FILES_WATCHER + #ifndef __WINDOWS__ + m_TreeProject->FileWatcherReset(); + #endif +#endif + } } @@ -1032,20 +1041,16 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir ) TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); - if( itemData ) + if( itemData && ( itemData->GetType() == TREE_DIRECTORY ) ) { - if( itemData->GetType() != TREE_DIRECTORY ) - continue; - if( itemData->m_FileName == aSubDir ) // Found! { root_id = kid; break; } - // if kid is a subdir, push in list to explore it later - if( itemData->GetType() == TREE_DIRECTORY && - itemData->m_WasPopulated ) + // kid is a subdir, push in list to explore it later + if( itemData->m_WasPopulated ) subdirs_id.push( kid ); } kid = m_TreeProject->GetNextChild( root_id, cookie ); @@ -1054,10 +1059,10 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir ) return root_id; } -#if wxCHECK_VERSION( 2, 9, 2 ) +#ifdef KICAD_USE_FILES_WATCHER /* called when a file or directory is modified/created/deleted - * The tree project should be rebuilt when a file or directory - * is created or deleted + * The tree project is modified when a file or directory + * is created/deleted/renamed to reflect the file change */ void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event ) { @@ -1102,28 +1107,23 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir ) { TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); - if( itemData ) + if( itemData && ( itemData->m_FileName == fn ) ) { - if( itemData->m_FileName == fn ) + if( event.GetChangeType() == wxFSW_EVENT_DELETE ) + m_TreeProject->Delete( kid ); + else { - if( event.GetChangeType() == wxFSW_EVENT_DELETE ) - { - m_TreeProject->Delete( kid ); - } - else - { - wxFileName newpath = event.GetNewPath(); - wxString newfn = newpath.GetFullPath(); - // Change item label and item data - // Extension could be modified and be not an usually selected file type - // However, here we do not filter files. - // This is simple, and I am not sure filtering renamed files here is better, - // becuse they could disappear, like deleted files - itemData->SetFileName( newpath.GetFullPath() ); - m_TreeProject->SetItemText( kid, newpath.GetFullName() ); - } - return; + wxFileName newpath = event.GetNewPath(); + wxString newfn = newpath.GetFullPath(); + // Change item label and item data + // Extension could be modified and be not an usually selected file type + // However, here we do not filter files. + // This is simple, and I am not sure filtering renamed files here is better, + // because they could disappear, like deleted files + itemData->SetFileName( newpath.GetFullPath() ); + m_TreeProject->SetItemText( kid, newpath.GetFullName() ); } + return; } kid = m_TreeProject->GetNextChild( root_id, cookie ); @@ -1134,6 +1134,11 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir ) m_TreeProject->SortChildren( root_id ); } +/* 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 + */ void TREE_PROJECT_FRAME::FileWatcherReset() { // Prepare file watcher: @@ -1142,15 +1147,73 @@ void TREE_PROJECT_FRAME::FileWatcherReset() m_watcher->SetOwner( this ); // Add directories which should be monitored. - // under windows, we add the curr dir and subdirs - // under unix, we add only the curr dir + // 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. + wxFileName watched_path = wxFileName::DirName( wxGetCwd() ); #ifdef __WINDOWS__ - m_watcher->AddTree( wxFileName::DirName( wxT( "./" ) ) ); + m_watcher->AddTree( watched_path ); #else - m_watcher->Add( wxFileName::DirName( wxT( "./" ) ) ); + m_watcher->Add( watched_path ); + + // Add subdirs + wxTreeItemIdValue cookie; + wxTreeItemId root_id = m_root; + std::stack < wxTreeItemId > subdirs_id; + + wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie ); + while( 1 ) + { + if( ! kid.IsOk() ) + { + if( subdirs_id.empty() ) // all items were explored + break; + else + { + root_id = subdirs_id.top(); + subdirs_id.pop(); + kid = m_TreeProject->GetFirstChild( root_id, cookie ); + if( ! kid.IsOk() ) + continue; + } + } + + TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); + + if( itemData && ( itemData->GetType() == TREE_DIRECTORY ) ) + { + watched_path = wxFileName::DirName( itemData->m_FileName ); + m_watcher->Add( watched_path ); + + // if kid is a subdir, push in list to explore it later + if( itemData->m_WasPopulated && m_TreeProject->GetChildrenCount( kid ) ) + subdirs_id.push( kid ); + } + kid = m_TreeProject->GetNextChild( root_id, cookie ); + } +#endif + +#if 0 // For test only! + wxArrayString paths; + m_watcher->GetWatchedPaths( &paths ); + for( unsigned ii = 0; ii < paths.GetCount(); ii++ ) + wxLogMessage( paths[ii] ); #endif } +/* Called by sending a event with id = ID_INIT_WATCHED_PATHS + * rebuild the list of whatched paths + * We are using an event called function to install or reinit a file system watcher + * because a file watcher *needs* a running loop event handler. + * this is noticeable under Linux. + * therefore the safe way to do that is to use the main event loop + * to call m_LeftWin->FileWatcherReset() + */ +void KICAD_MANAGER_FRAME::OnChangeWatchedPaths(wxCommandEvent& aEvent ) +{ + m_LeftWin->FileWatcherReset(); +} + #endif diff --git a/kicad/tree_project_frame.h b/kicad/tree_project_frame.h index 91e719de35..c57d33badc 100644 --- a/kicad/tree_project_frame.h +++ b/kicad/tree_project_frame.h @@ -29,7 +29,9 @@ #ifndef TREEPRJ_FRAME_H #define TREEPRJ_FRAME_H -#if wxCHECK_VERSION( 2, 9, 2 ) +#include + +#ifdef KICAD_USE_FILES_WATCHER #include #endif @@ -52,16 +54,22 @@ private: wxCursor m_DragCursor; wxCursor m_Default; -#if wxCHECK_VERSION( 2, 9, 2 ) - wxFileSystemWatcher* m_watcher; // file system watcher +#ifdef KICAD_USE_FILES_WATCHER + wxFileSystemWatcher* m_watcher; // file system watcher (since wxWidgets 2.9.2) #endif public: TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ); ~TREE_PROJECT_FRAME(); - void ReCreateTreePrj(); -#if wxCHECK_VERSION( 2, 9, 2 ) - void FileWatcherReset(); + void ReCreateTreePrj(); +#ifdef KICAD_USE_FILES_WATCHER + /** + * Reinit the watched paths + * Should be called after opening a new project to + * rebuild the list of watched paths. + * Should be called *atfer* the main loop event handler is started + */ + void FileWatcherReset(); #endif protected: @@ -160,8 +168,13 @@ private: */ wxTreeItemId findSubdirTreeItem( const wxString& aSubDir ); -#if wxCHECK_VERSION( 2, 9, 2 ) - void OnFileSystemEvent( wxFileSystemWatcherEvent& event ); +#ifdef KICAD_USE_FILES_WATCHER + /** + * 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 + */ + void OnFileSystemEvent( wxFileSystemWatcherEvent& event ); #endif DECLARE_EVENT_TABLE()