kicad-source/kicad/tools/kicad_manager_control.cpp

804 lines
26 KiB
C++
Raw Normal View History

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
2019-08-14 09:28:07 +01:00
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wildcards_and_files_ext.h>
#include <executable_names.h>
#include <pgm_base.h>
#include <kiway.h>
#include <kicad_manager_frame.h>
#include <confirm.h>
#include <bitmaps.h>
#include <tool/selection.h>
#include <tool/tool_event.h>
#include <tools/kicad_manager_actions.h>
#include <tools/kicad_manager_control.h>
#include <dialogs/dialog_template_selector.h>
#include <gestfich.h>
2020-10-24 10:45:37 -04:00
#include <wx/dir.h>
///< Helper widget to select whether a new directory should be created for a project.
class DIR_CHECKBOX : public wxPanel
{
public:
DIR_CHECKBOX( wxWindow* aParent )
: wxPanel( aParent )
{
m_cbCreateDir = new wxCheckBox( this, wxID_ANY,
_( "Create a new directory for the project" ) );
m_cbCreateDir->SetValue( true );
wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
sizer->Add( m_cbCreateDir, 0, wxALL, 8 );
SetSizerAndFit( sizer );
}
bool CreateNewDir() const
{
return m_cbCreateDir->GetValue();
}
static wxWindow* Create( wxWindow* aParent )
{
return new DIR_CHECKBOX( aParent );
}
protected:
wxCheckBox* m_cbCreateDir;
};
KICAD_MANAGER_CONTROL::KICAD_MANAGER_CONTROL() :
TOOL_INTERACTIVE( "kicad.Control" ),
m_frame( nullptr )
{
}
void KICAD_MANAGER_CONTROL::Reset( RESET_REASON aReason )
{
m_frame = getEditFrame<KICAD_MANAGER_FRAME>();
}
int KICAD_MANAGER_CONTROL::NewProject( const TOOL_EVENT& aEvent )
{
wxString default_dir = m_frame->GetMruPath();
wxFileDialog dlg( m_frame, _( "Create New Project" ), default_dir, wxEmptyString,
ProjectFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
// Add a "Create a new directory" checkbox
dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;
wxFileName pro( dlg.GetPath() );
// wxFileName automatically extracts an extension. But if it isn't
// a .pro extension, we should keep it as part of the filename
if( !pro.GetExt().IsEmpty() && pro.GetExt().ToStdString() != ProjectFileExtension )
pro.SetName( pro.GetName() + wxT( "." ) + pro.GetExt() );
pro.SetExt( ProjectFileExtension ); // enforce extension
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
// Append a new directory with the same name of the project file.
if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
pro.AppendDir( pro.GetName() );
// Check if the project directory is empty if it already exists.
wxDir directory( pro.GetPath() );
if( !pro.DirExists() )
{
if( !pro.Mkdir() )
{
wxString msg;
msg.Printf( _( "Directory \"%s\" could not be created.\n\n"
"Please make sure you have write permissions and try again." ),
pro.GetPath() );
DisplayErrorMessage( m_frame, msg );
return -1;
}
}
else if( directory.HasFiles() )
{
wxString msg = _( "The selected directory is not empty. It is recommended that you "
"create projects in their own empty directory.\n\nDo you "
"want to continue?" );
if( !IsOK( m_frame, msg ) )
return -1;
}
m_frame->CreateNewProject( pro );
m_frame->LoadProject( pro );
return 0;
}
int KICAD_MANAGER_CONTROL::NewFromTemplate( const TOOL_EVENT& aEvent )
{
DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( m_frame );
wxFileName templatePath;
wxString envStr;
// KiCad system template path.
ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD6_TEMPLATE_DIR" );
if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
{
templatePath.AssignDir( it->second.GetValue() );
ps->AddTemplatesPage( _( "System Templates" ), templatePath );
}
// User template path.
it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" );
if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString )
{
templatePath.AssignDir( it->second.GetValue() );
ps->AddTemplatesPage( _( "User Templates" ), templatePath );
}
// Show the project template selector dialog
if( ps->ShowModal() != wxID_OK )
return -1;
if( !ps->GetSelectedTemplate() )
{
wxMessageBox( _( "No project template was selected. Cannot generate new project." ),
_( "Error" ), wxOK | wxICON_ERROR, m_frame );
return -1;
}
// Get project destination folder and project file name.
wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
wxString title = _( "New Project Folder" );
wxFileDialog dlg( m_frame, title, default_dir, wxEmptyString, ProjectFileWildcard(),
2019-06-09 22:57:23 +01:00
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
// Add a "Create a new directory" checkbox
dlg.SetExtraControlCreator( &DIR_CHECKBOX::Create );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;
wxFileName fn( dlg.GetPath() );
// wxFileName automatically extracts an extension. But if it isn't
// a .pro extension, we should keep it as part of the filename
if( !fn.GetExt().IsEmpty() && fn.GetExt().ToStdString() != ProjectFileExtension )
fn.SetName( fn.GetName() + wxT( "." ) + fn.GetExt() );
fn.SetExt( ProjectFileExtension );
if( !fn.IsAbsolute() )
fn.MakeAbsolute();
// Append a new directory with the same name of the project file.
if( static_cast<DIR_CHECKBOX*>( dlg.GetExtraControl() )->CreateNewDir() )
fn.AppendDir( fn.GetName() );
// Check if the project directory is empty if it already exists.
wxDir directory( fn.GetPath() );
if( !fn.DirExists() )
{
if( !fn.Mkdir() )
{
wxString msg;
msg.Printf( _( "Directory \"%s\" could not be created.\n\n"
"Please make sure you have write permissions and try again." ),
fn.GetPath() );
DisplayErrorMessage( m_frame, msg );
return -1;
}
}
if( !fn.IsDirWritable() )
{
wxString msg;
msg.Printf( _( "Cannot write to folder \"%s\"." ), fn.GetPath() );
wxMessageDialog msgDlg( m_frame, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
msgDlg.SetExtendedMessage( _( "Please check your access permissions to this folder "
"and try again." ) );
msgDlg.ShowModal();
return -1;
}
// Make sure we are not overwriting anything in the destination folder.
std::vector< wxFileName > destFiles;
if( ps->GetSelectedTemplate()->GetDestinationFiles( fn, destFiles ) )
{
std::vector< wxFileName > overwrittenFiles;
for( const auto& file : destFiles )
{
if( file.FileExists() )
overwrittenFiles.push_back( file );
}
if( !overwrittenFiles.empty() )
{
wxString extendedMsg = _( "Overwriting files:" ) + "\n";
for( const auto& file : overwrittenFiles )
extendedMsg += "\n" + file.GetFullName();
KIDIALOG msgDlg( m_frame, _( "Similar files already exist in the destination folder." ),
_( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
msgDlg.SetExtendedMessage( extendedMsg );
msgDlg.SetOKLabel( _( "Overwrite" ) );
msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( msgDlg.ShowModal() == wxID_CANCEL )
return -1;
}
}
wxString errorMsg;
// The selected template widget contains the template we're attempting to use to
// create a project
if( !ps->GetSelectedTemplate()->CreateProject( fn, &errorMsg ) )
{
wxMessageDialog createDlg( m_frame,
_( "A problem occurred creating new project from template!" ),
_( "Template Error" ),
wxOK | wxICON_ERROR );
if( !errorMsg.empty() )
createDlg.SetExtendedMessage( errorMsg );
createDlg.ShowModal();
return -1;
}
m_frame->CreateNewProject( fn.GetFullPath() );
m_frame->LoadProject( fn );
return 0;
}
int KICAD_MANAGER_CONTROL::OpenProject( const TOOL_EVENT& aEvent )
{
2020-05-25 22:27:27 -04:00
wxString wildcard = AllProjectFilesWildcard() + "|" + ProjectFileWildcard() + "|"
+ LegacyProjectFileWildcard();
wxString default_dir = m_frame->GetMruPath();
wxFileDialog dlg( m_frame, _( "Open Existing Project" ), default_dir, wxEmptyString,
wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;
wxFileName pro( dlg.GetPath() );
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
if( !pro.FileExists() )
return -1;
m_frame->LoadProject( pro );
return 0;
}
int KICAD_MANAGER_CONTROL::CloseProject( const TOOL_EVENT& aEvent )
{
m_frame->CloseProject( true );
return 0;
}
class SAVE_AS_TRAVERSER : public wxDirTraverser
{
public:
SAVE_AS_TRAVERSER( KICAD_MANAGER_FRAME* aFrame,
const wxString& aSrcProjectDirPath,
const wxString& aSrcProjectName,
const wxString& aNewProjectDirPath,
const wxString& aNewProjectName ) :
m_frame( aFrame ),
m_projectDirPath( aSrcProjectDirPath ),
m_projectName( aSrcProjectName ),
m_newProjectDirPath( aNewProjectDirPath ),
m_newProjectName( aNewProjectName )
{
}
virtual wxDirTraverseResult OnFile( const wxString& aSrcFilePath ) override
{
// Recursion guard for a Save As to a location inside the source project.
if( aSrcFilePath.StartsWith( m_newProjectDirPath ) )
return wxDIR_CONTINUE;
wxFileName destFile( aSrcFilePath );
wxString ext = destFile.GetExt();
bool atRoot = destFile.GetPath() == m_projectDirPath;
if( ext == "pro" )
{
wxString destPath = destFile.GetPath();
if( destPath.StartsWith( m_projectDirPath ) )
{
destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
destFile.SetPath( destPath );
}
if( destFile.GetName() == m_projectName )
{
destFile.SetName( m_newProjectName );
if( atRoot )
m_newProjectFile = destFile;
}
// Currently all paths in the settings file are relative, so we can just do a
// straight copy
KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
}
else if( ext == "kicad_sch"
|| ext == "kicad_sch-bak"
|| ext == "sch"
|| ext == "sch-bak"
|| ext == "sym"
|| ext == "lib"
|| ext == "dcm"
|| ext == "kicad_sym"
|| ext == "net"
|| destFile.GetName() == "sym-lib-table" )
{
KIFACE* eeschema = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH );
eeschema->SaveFileAs( m_projectDirPath, m_projectName, m_newProjectDirPath,
m_newProjectName, aSrcFilePath, m_errors );
}
else if( ext == "kicad_pcb"
|| ext == "kicad_pcb-bak"
|| ext == "brd"
|| ext == "kicad_mod"
|| ext == "mod"
|| ext == "cmp"
|| destFile.GetName() == "fp-lib-table" )
{
KIFACE* pcbnew = m_frame->Kiway().KiFACE( KIWAY::FACE_PCB );
pcbnew->SaveFileAs( m_projectDirPath, m_projectName, m_newProjectDirPath,
m_newProjectName, aSrcFilePath, m_errors );
}
else if( ext == "kicad_wks" )
{
KIFACE* pleditor = m_frame->Kiway().KiFACE( KIWAY::FACE_PL_EDITOR );
pleditor->SaveFileAs( m_projectDirPath, m_projectName, m_newProjectDirPath,
m_newProjectName, aSrcFilePath, m_errors );
}
else if( ext == "gbr"
|| ext == "gbrjob"
|| ext == "drl"
|| IsProtelExtension( ext ) )
{
KIFACE* gerbview = m_frame->Kiway().KiFACE( KIWAY::FACE_GERBVIEW );
gerbview->SaveFileAs( m_projectDirPath, m_projectName, m_newProjectDirPath,
m_newProjectName, aSrcFilePath, m_errors );
}
else
{
// Everything we don't recognize just gets a straight copy.
wxString destPath = destFile.GetPath();
wxString destName = destFile.GetName();
if( destPath.StartsWith( m_projectDirPath ) )
{
destPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
destFile.SetPath( destPath );
}
if( destName == m_projectName )
destFile.SetName( m_newProjectName );
KiCopyFile( aSrcFilePath, destFile.GetFullPath(), m_errors );
}
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir( const wxString& aSrcDirPath ) override
{
// Recursion guard for a Save As to a location inside the source project.
if( aSrcDirPath.StartsWith( m_newProjectDirPath ) )
return wxDIR_CONTINUE;
wxFileName destDir( aSrcDirPath );
wxString destDirPath = destDir.GetPathWithSep();
wxUniChar pathSep = wxFileName::GetPathSeparator();
if( destDirPath.StartsWith( m_projectDirPath + pathSep ) )
{
destDirPath.Replace( m_projectDirPath, m_newProjectDirPath, false );
destDir.SetPath( destDirPath );
}
if( destDir.GetName() == m_projectName )
{
if( destDir.GetExt() == "pretty" )
destDir.SetName( m_newProjectName );
#if 0
// WAYNE STAMBAUGH TODO:
// If we end up with a symbol equivalent to ".pretty" we'll want to handle it here....
else if( destDir.GetExt() == "sym_lib_dir_extension" )
destDir.SetName( m_newProjectName );
#endif
}
if( !wxMkdir( destDir.GetFullPath() ) )
{
wxString msg;
if( !m_errors.empty() )
m_errors += "\n";
msg.Printf( _( "Cannot copy folder \"%s\"." ), destDir.GetFullPath() );
m_errors += msg;
}
return wxDIR_CONTINUE;
}
wxString GetErrors() { return m_errors; }
wxFileName GetNewProjectFile() { return m_newProjectFile; }
private:
KICAD_MANAGER_FRAME* m_frame;
wxString m_projectDirPath;
wxString m_projectName;
wxString m_newProjectDirPath;
wxString m_newProjectName;
wxFileName m_newProjectFile;
wxString m_errors;
};
int KICAD_MANAGER_CONTROL::SaveProjectAs( const TOOL_EVENT& aEvent )
{
wxString msg;
wxFileName currentProjectFile( Prj().GetProjectFullName() );
wxString currentProjectDirPath = currentProjectFile.GetPath();
wxString currentProjectName = Prj().GetProjectName();
wxString default_dir = m_frame->GetMruPath();
if( default_dir == currentProjectDirPath
|| default_dir == currentProjectDirPath + wxFileName::GetPathSeparator() )
{
// Don't start within the current project
wxFileName default_dir_fn( default_dir );
default_dir_fn.RemoveLastDir();
default_dir = default_dir_fn.GetPath();
}
wxFileDialog dlg( m_frame, _( "Save Project To" ), default_dir, wxEmptyString, wxEmptyString,
wxFD_SAVE );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;
wxFileName newProjectDir( dlg.GetPath() );
if( !newProjectDir.IsAbsolute() )
newProjectDir.MakeAbsolute();
if( wxDirExists( newProjectDir.GetFullPath() ) )
{
msg.Printf( _( "\"%s\" already exists." ), newProjectDir.GetFullPath() );
DisplayErrorMessage( m_frame, msg );
return -1;
}
if( !wxMkdir( newProjectDir.GetFullPath() ) )
{
msg.Printf( _( "Directory \"%s\" could not be created.\n\n"
"Please make sure you have write permissions and try again." ),
newProjectDir.GetPath() );
DisplayErrorMessage( m_frame, msg );
return -1;
}
if( !newProjectDir.IsDirWritable() )
{
msg.Printf( _( "Cannot write to folder \"%s\"." ), newProjectDir.GetFullPath() );
wxMessageDialog msgDlg( m_frame, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
msgDlg.SetExtendedMessage( _( "Please check your access permissions to this folder "
"and try again." ) );
msgDlg.ShowModal();
return -1;
}
const wxString& newProjectDirPath = newProjectDir.GetFullPath();
const wxString& newProjectName = newProjectDir.GetName();
wxDir currentProjectDir( currentProjectDirPath );
SAVE_AS_TRAVERSER traverser( m_frame, currentProjectDirPath, currentProjectName,
newProjectDirPath, newProjectName );
currentProjectDir.Traverse( traverser );
if( !traverser.GetErrors().empty() )
DisplayErrorMessage( m_frame, traverser.GetErrors() );
if( traverser.GetNewProjectFile().FileExists() )
{
m_frame->CreateNewProject( traverser.GetNewProjectFile() );
m_frame->LoadProject( traverser.GetNewProjectFile() );
}
return 0;
}
int KICAD_MANAGER_CONTROL::Refresh( const TOOL_EVENT& aEvent )
{
m_frame->RefreshProjectTree();
return 0;
}
int KICAD_MANAGER_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
{
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
SELECTION dummySel;
if( conditionalMenu )
conditionalMenu->Evaluate( dummySel );
if( actionMenu )
actionMenu->UpdateAll();
return 0;
}
int KICAD_MANAGER_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
{
FRAME_T playerType = aEvent.Parameter<FRAME_T>();
KIWAY_PLAYER* player;
if( playerType == FRAME_SCH && !m_frame->IsProjectActive() )
{
DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a schematic." ),
wxEmptyString );
return -1;
}
else if( playerType == FRAME_PCB_EDITOR && !m_frame->IsProjectActive() )
{
DisplayInfoMessage( m_frame, _( "Create (or open) a project to edit a pcb." ),
wxEmptyString );
return -1;
}
// Prevent multiple KIWAY_PLAYER loading at one time
if( !m_loading.try_lock() )
return -1;
const std::lock_guard<std::mutex> lock( m_loading, std::adopt_lock );
try
{
player = m_frame->Kiway().Player( playerType, true );
}
catch( const IO_ERROR& err )
{
wxMessageBox( _( "Application failed to load:\n" ) + err.What(), _( "KiCad Error" ),
wxOK | wxICON_ERROR, m_frame );
return -1;
}
if ( !player )
{
wxMessageBox( _( "Application failed to load." ), _( "KiCad Error" ),
wxOK | wxICON_ERROR, m_frame );
return -1;
}
if( !player->IsVisible() ) // A hidden frame might not have the document loaded.
{
wxString filepath;
if( playerType == FRAME_SCH )
{
Make the new schematic and symbol library file formats the default. This is a very large and potentially disruptive change so this will be an unusually long and detailed commit message. The new file formats are now the default in both the schematic and symbol library editors. Existing symbol libraries will be saved in their current format until new features are added to library symbols. Once this happens, both the legacy schematic and symbol file formats will be no longer be savable and existing libraries will have to be converted. Saving to the legacy file formats is still available for round robin testing and should not be used for normal editing. When loading the legacy schematic file, it is imperative that the schematic library symbols are rescued and/or remapped to valid library identifiers. Otherwise, there will be no way to link to the original library symbol and the user will be required manually set the library identifier. The cached symbol will be saved in the schematic file so the last library symbol in the cache will still be used but there will be no way to update it from the original library. The next save after loading a legacy schematic file will be converted to the s-expression file format. Schematics with hierarchical sheets will automatically have all sheet file name extensions changed to .kicad_sym and saved to the new format as well. Appending schematics requires that the schematic to append has already been converted to the new file format. This is required to ensure that library symbols are guaranteed to be valid for the appended schematic. The schematic symbol library symbol link resolution has been moved out of the SCH_COMPONENT object and move into the SCH_SCREEN object that owns the symbol. This was done to ensure that there is a single place where the library symbol links get resolved rather than the dozen or so different code paths that previously existed. It also removes the necessity of the SCH_COMPONENT object of requiring any knowledge of the symbol library table and/or the cache library. When opening an s-expression schematic, the legacy cache library is not loaded so any library symbols not rescued cannot be loaded. Broken library symbol links will have to be manually resolved by adding the cache library to the symbol library table and changing the links in the schematic symbol. Now that the library symbols are embedded in the schematic file, the SCH_SCREEN object maintains the list of library symbols for the schematic automatically. No external manipulation of this library cache should ever occur. ADDED: S-expression schematic and symbol library file formats.
2020-04-16 12:43:50 -04:00
wxFileName kicad_schematic( m_frame->SchFileName() );
wxFileName legacy_schematic( m_frame->SchLegacyFileName() );
if( !legacy_schematic.FileExists() || kicad_schematic.FileExists() )
filepath = kicad_schematic.GetFullPath();
else
filepath = legacy_schematic.GetFullPath();
}
else if( playerType == FRAME_PCB_EDITOR )
{
wxFileName kicad_board( m_frame->PcbFileName() );
wxFileName legacy_board( m_frame->PcbLegacyFileName() );
if( !legacy_board.FileExists() || kicad_board.FileExists() )
filepath = kicad_board.GetFullPath();
else
filepath = legacy_board.GetFullPath();
}
// Show the frame (and update widgets to set valid sizes),
// after creating player and before calling OpenProjectFiles().
// Useful because loading a complex board and building its internal data can be
// time consuming
player->Show( true );
wxSafeYield();
if( !filepath.IsEmpty() )
{
if( !player->OpenProjectFiles( std::vector<wxString>( 1, filepath ) ) )
return -1;
}
}
// Needed on Windows, other platforms do not use it, but it creates no issue
if( player->IsIconized() )
player->Iconize( false );
player->Raise();
// Raising the window does not set the focus on Linux. This should work on
// any platform.
if( wxWindow::FindFocus() != player )
player->SetFocus();
return 0;
}
class TERMINATE_HANDLER : public wxProcess
{
public:
TERMINATE_HANDLER( const wxString& appName ) :
m_appName( appName )
2019-06-10 15:30:42 +01:00
{ }
void OnTerminate( int pid, int status ) override
{
wxString msg = wxString::Format( _( "%s closed [pid=%d]\n" ), m_appName, pid );
wxWindow* window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
if( window ) // Should always happen.
{
// Be sure the kicad frame manager is found
// This dynamic cast is not really mandatory, but ...
KICAD_MANAGER_FRAME* frame = dynamic_cast<KICAD_MANAGER_FRAME*>( window );
if( frame )
frame->PrintMsg( msg );
}
delete this;
}
private:
wxString m_appName;
};
int KICAD_MANAGER_CONTROL::Execute( const TOOL_EVENT& aEvent )
{
wxString execFile;
wxString params;
if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) )
execFile = GERBVIEW_EXE;
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::convertImage ) )
execFile = BITMAPCONVERTER_EXE;
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::showCalculator ) )
execFile = PCB_CALCULATOR_EXE;
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editWorksheet ) )
execFile = PL_EDITOR_EXE;
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::openTextEditor ) )
execFile = Pgm().GetEditorName();
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherSch ) )
execFile = EESCHEMA_EXE;
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::editOtherPCB ) )
execFile = PCBNEW_EXE;
else
wxFAIL_MSG( "Execute(): unexpected request" );
if( execFile.IsEmpty() )
return 0;
if( aEvent.Parameter<wxString*>() )
params = *aEvent.Parameter<wxString*>();
else if( ( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) )
&& m_frame->IsProjectActive() )
params = m_frame->Prj().GetProjectPath();
if( !params.empty() )
AddDelimiterString( params );
TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( execFile );
long pid = ExecuteFile( m_frame, execFile, params, callback );
if( pid > 0 )
{
wxString msg = wxString::Format( _( "%s %s opened [pid=%ld]\n" ), execFile, params, pid );
m_frame->PrintMsg( msg );
#ifdef __WXMAC__
msg.Printf( "osascript -e 'activate application \"%s\"' ", execFile );
system( msg.c_str() );
#endif
}
else
{
delete callback;
}
return 0;
}
void KICAD_MANAGER_CONTROL::setTransitions()
{
Go( &KICAD_MANAGER_CONTROL::NewProject, KICAD_MANAGER_ACTIONS::newProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::NewFromTemplate,
KICAD_MANAGER_ACTIONS::newFromTemplate.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::OpenProject, KICAD_MANAGER_ACTIONS::openProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::CloseProject, KICAD_MANAGER_ACTIONS::closeProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::SaveProjectAs, ACTIONS::saveAs.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Refresh, ACTIONS::zoomRedraw.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::ShowPlayer, KICAD_MANAGER_ACTIONS::editSchematic.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::ShowPlayer, KICAD_MANAGER_ACTIONS::editSymbols.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::ShowPlayer, KICAD_MANAGER_ACTIONS::editPCB.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::ShowPlayer,
KICAD_MANAGER_ACTIONS::editFootprints.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::viewGerbers.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::convertImage.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute,
KICAD_MANAGER_ACTIONS::showCalculator.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::editWorksheet.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute,
KICAD_MANAGER_ACTIONS::openTextEditor.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::editOtherSch.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Execute, KICAD_MANAGER_ACTIONS::editOtherPCB.MakeEvent() );
}