Tool framework for Kicad Manager frame.

This commit is contained in:
Jeff Young 2019-06-09 14:12:44 +01:00
parent 16cb1e731d
commit c13ef839c1
20 changed files with 662 additions and 606 deletions

View File

@ -23,16 +23,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file eda_base_frame.cpp
* @brief EDA_BASE_FRAME class implementation.
*/
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <wx/display.h>
#include <dialog_shim.h>
#include <eda_doc.h>
#include <id.h>
@ -77,6 +70,11 @@ BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
EVT_MENU( wxID_INDEX, EDA_BASE_FRAME::GetKicadHelp )
EVT_MENU( ID_HELP_GET_INVOLVED, EDA_BASE_FRAME::GetKicadContribute )
EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
EVT_CHAR_HOOK( EDA_BASE_FRAME::OnCharHook )
EVT_MENU_OPEN( EDA_BASE_FRAME::OnMenuOpen )
EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuOpen )
EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuOpen )
END_EVENT_TABLE()
EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
@ -238,6 +236,53 @@ bool EDA_BASE_FRAME::doAutoSave()
}
void EDA_BASE_FRAME::OnCharHook( wxKeyEvent& event )
{
wxLogTrace( kicadTraceKeyEvent, "EDA_DRAW_FRAME::OnCharHook %s", dump( event ) );
// Key events can be filtered here.
// Currently no filtering is made.
event.Skip();
}
void EDA_BASE_FRAME::OnMenuOpen( wxMenuEvent& event )
{
// On wxWidgets 3.0.x Windows, EVT_MENU_OPEN and EVT_MENU_HIGHLIGHT events are not
// captured by the ACTON_MENU menus. While it is fixed in wxWidgets 3.1.x, we still
// need a solution for the earlier verions.
//
// This could be made conditional, but for now I'm going to use the same strategy
// everywhere so it gets wider testing.
// Note that if the conditional compilation is reactivated, the Connect() lines in
// ACTION_MENU::setupEvents() will need to be re-enabled.
//#if defined( __WINDOWS__ ) && wxCHECK_VERSION( 3, 0, 0 ) && !wxCHECK_VERSION( 3, 1, 0 )
// As if things weren't bad enough, wxWidgets doesn't pass the menu pointer when the
// event is a wxEVT_MENU_HIGHLIGHT, so we store the menu from the EVT_MENU_OPEN call.
static ACTION_MENU* currentMenu;
if( event.GetEventType() == wxEVT_MENU_OPEN )
{
currentMenu = dynamic_cast<ACTION_MENU*>( event.GetMenu() );
if( currentMenu )
currentMenu->OnMenuEvent( event );
}
else if( event.GetEventType() == wxEVT_MENU_HIGHLIGHT )
{
if( currentMenu )
currentMenu->OnMenuEvent( event );
}
else // if( event.GetEventType() == wxEVT_MENU_CLOSE )
{
currentMenu = nullptr;
}
//#endif
event.Skip();
}
void EDA_BASE_FRAME::ReCreateMenuBar()
{
}
@ -257,6 +302,7 @@ void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
_( "Open \"Getting Started in KiCad\" guide for beginners" ),
KiBitmap( help_xpm ) );
// JEY TODO: move to actions...
AddMenuItem( helpMenu, ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST, _( "&List Hotkeys..." ),
_( "Displays current hotkeys table and corresponding commands" ),
KiBitmap( hotkeys_xpm ) );

View File

@ -40,7 +40,6 @@
#include <view/view.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tool/action_menu.h>
#include <tool/actions.h>
#include <wx/clipbrd.h>
#include <ws_draw_item.h>
@ -75,14 +74,6 @@ static const wxString FirstRunShownKeyword( wxT( "FirstRunShown" ) );
*/
static const wxString MaxUndoItemsEntry(wxT( "DevelMaxUndoItems" ) );
BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, KIWAY_PLAYER )
EVT_CHAR_HOOK( EDA_DRAW_FRAME::OnCharHook )
EVT_MENU_OPEN( EDA_DRAW_FRAME::OnMenuOpen )
EVT_MENU_CLOSE( EDA_DRAW_FRAME::OnMenuOpen )
EVT_MENU_HIGHLIGHT_ALL( EDA_DRAW_FRAME::OnMenuOpen )
END_EVENT_TABLE()
EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString & aFrameName ) :
@ -193,15 +184,6 @@ EDA_DRAW_FRAME::~EDA_DRAW_FRAME()
}
void EDA_DRAW_FRAME::OnCharHook( wxKeyEvent& event )
{
wxLogTrace( kicadTraceKeyEvent, "EDA_DRAW_FRAME::OnCharHook %s", dump( event ) );
// Key events can be filtered here.
// Currently no filtering is made.
event.Skip();
}
void EDA_DRAW_FRAME::ReleaseFile()
{
m_file_checker = nullptr;
@ -259,44 +241,6 @@ void EDA_DRAW_FRAME::EraseMsgBox()
}
void EDA_DRAW_FRAME::OnMenuOpen( wxMenuEvent& event )
{
// On wxWidgets 3.0.x Windows, EVT_MENU_OPEN and EVT_MENU_HIGHLIGHT events are not
// captured by the ACTON_MENU menus. While it is fixed in wxWidgets 3.1.x, we still
// need a solution for the earlier verions.
//
// This could be made conditional, but for now I'm going to use the same strategy
// everywhere so it gets wider testing.
// Note that if the conditional compilation is reactivated, the Connect() lines in
// ACTION_MENU::setupEvents() will need to be re-enabled.
//#if defined( __WINDOWS__ ) && wxCHECK_VERSION( 3, 0, 0 ) && !wxCHECK_VERSION( 3, 1, 0 )
// As if things weren't bad enough, wxWidgets doesn't pass the menu pointer when the
// event is a wxEVT_MENU_HIGHLIGHT, so we store the menu from the EVT_MENU_OPEN call.
static ACTION_MENU* currentMenu;
if( event.GetEventType() == wxEVT_MENU_OPEN )
{
currentMenu = dynamic_cast<ACTION_MENU*>( event.GetMenu() );
if( currentMenu )
currentMenu->OnMenuEvent( event );
}
else if( event.GetEventType() == wxEVT_MENU_HIGHLIGHT )
{
if( currentMenu )
currentMenu->OnMenuEvent( event );
}
else // if( event.GetEventType() == wxEVT_MENU_CLOSE )
{
currentMenu = nullptr;
}
//#endif
event.Skip();
}
bool EDA_DRAW_FRAME::GetToolToggled( int aToolId )
{
// Checks all the toolbars and returns true if the given tool id is toggled.

View File

@ -231,9 +231,9 @@ int ACTION_MANAGER::processHotKey( TOOL_ACTION* aAction )
{
hotkey = hotkey & ~TOOL_ACTION::LEGACY_HK; // it leaves only HK_xxx identifier
auto frame = dynamic_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
auto frame = static_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
EDA_HOTKEY* hk_desc = nullptr;
if( frame )
hk_desc = frame->GetHotKeyDescription( hotkey );

View File

@ -30,7 +30,7 @@
#include <tool/action_toolbar.h>
ACTION_TOOLBAR::ACTION_TOOLBAR( EDA_DRAW_FRAME* parent, wxWindowID id, const wxPoint& pos,
ACTION_TOOLBAR::ACTION_TOOLBAR( EDA_BASE_FRAME* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style ) :
wxAuiToolBar( parent, id, pos, size, style ),
m_toolManager( parent->GetToolManager() )

View File

@ -449,8 +449,8 @@ void TOOL_MANAGER::InitTools()
if( !tool->Init() )
{
wxMessageBox(
wxString::Format( "Initialization of tool \"%s\" failed", tool->GetName() ) );
wxMessageBox( wxString::Format( "Initialization of tool \"%s\" failed",
tool->GetName() ) );
// Unregister the tool
setActiveState( nullptr );
@ -779,7 +779,7 @@ bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent )
if( TOOL_STATE* active = GetCurrentToolState() )
setActiveState( active );
if( m_view->IsDirty() )
if( m_view && m_view->IsDirty() )
{
GetEditFrame()->RefreshCanvas();
@ -947,12 +947,12 @@ bool TOOL_MANAGER::processEvent( const TOOL_EVENT& aEvent )
void TOOL_MANAGER::setActiveState( TOOL_STATE* aState )
{
if( m_activeState )
if( m_activeState && m_viewControls )
saveViewControls( m_activeState );
m_activeState = aState;
if( m_activeState )
if( m_activeState && m_viewControls )
applyViewControls( aState );
}

View File

@ -82,6 +82,7 @@ using S_C = SELECTION_CONDITIONS;
void TOOL_MENU::AddStandardSubMenus( EDA_DRAW_FRAME* aFrame )
{
#if defined( PCBNEW ) || defined( CVPCB ) || defined( EESCHEMA ) || defined( GERBVIEW ) || defined( PL_EDITOR )
m_menu.AddItem( ACTIONS::zoomCenter, S_C::ShowAlways, 1000 );
m_menu.AddItem( ACTIONS::zoomIn, S_C::ShowAlways, 1000 );
m_menu.AddItem( ACTIONS::zoomOut, S_C::ShowAlways, 1000 );
@ -94,4 +95,5 @@ void TOOL_MENU::AddStandardSubMenus( EDA_DRAW_FRAME* aFrame )
m_menu.AddMenu( createOwnSubMenu<ZOOM_MENU>( aFrame ).get(), S_C::ShowAlways, 1000 );
m_menu.AddMenu( createOwnSubMenu<GRID_MENU>( aFrame ).get(), S_C::ShowAlways, 1000 );
}
#endif
}

View File

@ -224,6 +224,22 @@ public:
*/
bool ProcessEvent( wxEvent& aEvent ) override;
/**
* Capture the key event before it is sent to the GUI.
*
* the basic frame does not capture this event.
* editor frames should override this event function to capture and filter
* these keys when they are used as hotkeys, and skip it if the key is not
* used as hotkey (otherwise the key events will be not sent to menus)
*/
virtual void OnCharHook( wxKeyEvent& event );
/**
* Workaround some issues in wxWidgets where the menu events aren't captured by the
* menus themselves.
*/
void OnMenuOpen( wxMenuEvent& event );
void SetAutoSaveInterval( int aInterval );
int GetAutoSaveInterval() const { return m_autoSaveInterval; }

View File

@ -211,16 +211,6 @@ public:
~EDA_DRAW_FRAME();
/**
* Capture the key event before it is sent to the GUI.
*
* the basic frame does not capture this event.
* editor frames should override this event function to capture and filter
* these keys when they are used as hotkeys, and skip it if the key is not
* used as hotkey (otherwise the key events will be not sent to menus)
*/
virtual void OnCharHook( wxKeyEvent& event );
/**
* Mark a schematic file as being in use. Use ReleaseFile() to undo this.
*
@ -361,8 +351,6 @@ public:
*/
virtual void ExecuteRemoteCommand( const char* cmdline ){}
void OnMenuOpen( wxMenuEvent& event );
///> @copydoc EDA_BASE_FRAME::WriteHotkeyConfig
int WriteHotkeyConfig( struct EDA_HOTKEY_CONFIG* aDescList, wxString* aFullFileName = NULL ) override;
@ -683,9 +671,12 @@ public:
*/
KIGFX::GAL_DISPLAY_OPTIONS& GetGalDisplayOptions() { return m_galDisplayOptions; }
void RefreshCanvas() override
{
GetGalCanvas()->Refresh();
}
virtual const BOX2I GetDocumentExtents() const;
DECLARE_EVENT_TABLE()
};
#endif // DRAW_FRAME_H_

View File

@ -75,8 +75,6 @@ enum main_id
ID_LOAD_PROJECT,
ID_APPEND_PROJECT,
ID_NEW_PROJECT,
ID_NEW_PROJECT_FROM_TEMPLATE,
ID_SAVE_PROJECT,
ID_SAVE_PROJECT_AS,
ID_LOAD_FILE,

View File

@ -40,7 +40,7 @@ class TOOL_ACTION;
class ACTION_TOOLBAR : public wxAuiToolBar
{
public:
ACTION_TOOLBAR( EDA_DRAW_FRAME* parent, wxWindowID id = wxID_ANY,
ACTION_TOOLBAR( EDA_BASE_FRAME* parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxAUI_TB_DEFAULT_STYLE );

View File

@ -27,6 +27,7 @@ set( KICAD_SRCS
tree_project_frame.cpp
treeprojectfiles.cpp
treeproject_item.cpp
tools/kicad_manager_control.cpp
)
if( MINGW )

View File

@ -126,10 +126,7 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event )
PrintMsg( wxT( "** end **\n" ) );
if( unzipDir == Prj().GetProjectPath() )
{
wxCommandEvent dummy;
OnRefresh( dummy );
}
RefreshProjectTree();
}

View File

@ -57,7 +57,6 @@ enum id_kicad_frm {
ID_LEFT_FRAME = ID_KICAD_MANAGER_START,
ID_PROJECT_TREE,
ID_PROJECT_TXTEDIT,
ID_PROJECT_TREE_REFRESH,
ID_PROJECT_SWITCH_TO_OTHER,
ID_PROJECT_NEWDIR,
ID_PROJECT_DELETE,

View File

@ -37,6 +37,8 @@
#include "pgm_kicad.h"
#include "tree_project_frame.h"
#include "kicad_id.h"
#include <tool/tool_manager.h>
#include <tools/kicad_manager_control.h>
#ifdef __WXMAC__
#include <MacTypes.h>
@ -85,6 +87,14 @@ KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& titl
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE );
// Create the manager
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, this );
// Register tools
m_toolManager->RegisterTool( new KICAD_MANAGER_CONTROL );
m_toolManager->InitTools();
RecreateBaseHToolbar();
ReCreateMenuBar();
@ -513,7 +523,7 @@ void KICAD_MANAGER_FRAME::OnBrowseInFileExplorer( wxCommandEvent& event )
}
void KICAD_MANAGER_FRAME::OnRefresh( wxCommandEvent& event )
void KICAD_MANAGER_FRAME::RefreshProjectTree()
{
m_LeftWin->ReCreateTreePrj();
}

View File

@ -87,24 +87,6 @@ public:
void OnCloseWindow( wxCloseEvent& Event );
void OnSize( wxSizeEvent& event );
/**
* Load an exiting project (.pro) file.
*/
void OnLoadProject( wxCommandEvent& event );
/**
* Creates a new project folder, copy a template into this new folder.
* and open this new projrct as working project
*/
void OnCreateProjectFromTemplate( wxCommandEvent& event );
void OnNewProject( wxCommandEvent& aEvent );
/**
* Save the project (.pro) file containing the top level configuration parameters.
*/
void OnSaveProject( wxCommandEvent& event );
void OnArchiveFiles( wxCommandEvent& event );
void OnUnarchiveFiles( wxCommandEvent& event );
@ -154,10 +136,9 @@ public:
*/
void ClearMsg();
void OnRefresh( wxCommandEvent& event );
void OnUpdateRequiresProject( wxUpdateUIEvent& event );
void RefreshProjectTree();
/**
/**
* Creates a new project by setting up and initial project, schematic, and board files.
*
* The project file is copied from the kicad.pro template file if possible. Otherwise,
@ -208,6 +189,7 @@ public:
*/
void OnChangeWatchedPaths( wxCommandEvent& aEvent );
void SyncMenusAndToolbars() override;
void SetProjectFileName( const wxString& aFullProjectProFileName );
const wxString GetProjectFileName();
@ -239,7 +221,7 @@ private:
TREE_PROJECT_FRAME* m_LeftWin;
LAUNCHER_PANEL* m_Launcher;
wxTextCtrl* m_MessagesBox;
wxAuiToolBar* m_mainToolBar;
ACTION_TOOLBAR* m_mainToolBar;
int m_leftWinWidth;
EDA_HOTKEY_CONFIG* m_manager_Hotkeys_Descr;

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 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
@ -23,16 +23,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file kicad/menubar.cpp
* @brief (Re)Create the project manager menubar for KiCad
*/
#include <bitmaps.h>
#include <hotkeys_basic.h>
#include <menus_helpers.h>
#include <tool/tool_manager.h>
#include <tools/kicad_manager_control.h>
#include <tools/kicad_manager_actions.h>
#include "kicad_manager_frame.h"
#include "pgm_kicad.h"
#include "kicad_id.h"
@ -44,13 +40,7 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_SIZE( KICAD_MANAGER_FRAME::OnSize )
EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow )
// Toolbar events
EVT_TOOL( ID_NEW_PROJECT, KICAD_MANAGER_FRAME::OnNewProject )
EVT_TOOL( ID_NEW_PROJECT_FROM_TEMPLATE, KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate )
EVT_TOOL( ID_LOAD_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject )
// Menu events
EVT_MENU( ID_SAVE_PROJECT, KICAD_MANAGER_FRAME::OnSaveProject )
EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
EVT_MENU( ID_TO_TEXT_EDITOR, KICAD_MANAGER_FRAME::OnOpenTextEditor )
EVT_MENU( ID_BROWSE_AN_SELECT_FILE, KICAD_MANAGER_FRAME::OnOpenFileInTextEditor )
@ -61,7 +51,6 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_MENU( wxID_PREFERENCES, KICAD_MANAGER_FRAME::OnPreferences )
EVT_MENU( ID_SAVE_AND_ZIP_FILES, KICAD_MANAGER_FRAME::OnArchiveFiles )
EVT_MENU( ID_READ_ZIP_ARCHIVE, KICAD_MANAGER_FRAME::OnUnarchiveFiles )
EVT_MENU( ID_PROJECT_TREE_REFRESH, KICAD_MANAGER_FRAME::OnRefresh )
EVT_MENU( ID_IMPORT_EAGLE_PROJECT, KICAD_MANAGER_FRAME::OnImportEagleFiles )
// Range menu events
@ -102,9 +91,6 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_BUTTON( ID_TO_PL_EDITOR, KICAD_MANAGER_FRAME::OnRunPageLayoutEditor )
EVT_MENU( ID_TO_PL_EDITOR, KICAD_MANAGER_FRAME::OnRunPageLayoutEditor )
EVT_UPDATE_UI_RANGE( ID_TO_SCH, ID_TO_PCB_FP_EDITOR,
KICAD_MANAGER_FRAME::OnUpdateRequiresProject )
END_EVENT_TABLE()
enum hotkey_id_command
@ -184,184 +170,88 @@ struct EDA_HOTKEY_CONFIG kicad_Manager_Hotkeys_Descr[] = {
*/
void KICAD_MANAGER_FRAME::ReCreateMenuBar()
{
wxString msg;
static wxMenu* openRecentMenu; // Open Recent submenu,
// static to remember this menu
m_manager_Hotkeys_Descr = kicad_Manager_Hotkeys_Descr;
KICAD_MANAGER_CONTROL* controlTool = m_toolManager->GetTool<KICAD_MANAGER_CONTROL>();
// wxWidgets handles the Mac Application menu behind the scenes, but that means
// we always have to start from scratch with a new wxMenuBar.
wxMenuBar* oldMenuBar = GetMenuBar();
wxMenuBar* menuBar = new wxMenuBar();
m_manager_Hotkeys_Descr = kicad_Manager_Hotkeys_Descr;
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, controlTool );
static ACTION_MENU* openRecentMenu;
// Before deleting, remove the menus managed by m_fileHistory
// (the file history will be updated when adding/removing files in history)
if( openRecentMenu )
PgmTop().GetFileHistory().RemoveMenu( openRecentMenu );
// Recreate all menus:
openRecentMenu = new ACTION_MENU();
openRecentMenu->SetTool( controlTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
// Menu File:
wxMenu* fileMenu = new wxMenu;
// New project creation
wxMenu* newprjSubMenu = new wxMenu();
msg = AddHotkeyName( _( "&Project..." ), kicad_Manager_Hotkeys_Descr, HK_NEW );
AddMenuItem( newprjSubMenu, ID_NEW_PROJECT, msg,
_( "Create new blank project" ),
KiBitmap( new_project_xpm ) );
msg = AddHotkeyName( _( "Project from &Template..." ),
kicad_Manager_Hotkeys_Descr, HK_NEW_PRJ_TEMPLATE );
AddMenuItem( newprjSubMenu, ID_NEW_PROJECT_FROM_TEMPLATE, msg,
_( "Create new project from template" ),
KiBitmap( new_project_with_template_xpm ) );
AddMenuItem( fileMenu, newprjSubMenu,
wxID_ANY,
_( "&New" ),
_( "Create new project" ),
KiBitmap( new_project_xpm ) );
// Open
msg = AddHotkeyName( _( "&Open Project..." ), kicad_Manager_Hotkeys_Descr, HK_OPEN );
AddMenuItem( fileMenu, ID_LOAD_PROJECT, msg,
_( "Open an existing project" ),
KiBitmap( open_project_xpm ) );
// File history
openRecentMenu = new wxMenu();
PgmTop().GetFileHistory().UseMenu( openRecentMenu );
PgmTop().GetFileHistory().AddFilesToMenu( );
AddMenuItem( fileMenu, openRecentMenu,
wxID_ANY,
_( "Open &Recent" ),
_( "Open a recent project" ),
KiBitmap( recent_xpm ) );
PgmTop().GetFileHistory().AddFilesToMenu( openRecentMenu );
// Currently there is nothing to save
// (Kicad manager does not save any info in .pro file)
#if 0
// Save
msg = AddHotkeyName( _( "&Save" ), kicad_Manager_Hotkeys_Descr, HK_SAVE );
AddMenuItem( fileMenu, ID_SAVE_PROJECT, msg,
_( "Save current project" ),
KiBitmap( save_project_xpm ) );
#endif
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newFromTemplate, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::openProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddSeparator();
fileMenu->AddItem( ID_IMPORT_EAGLE_PROJECT,
_( "Import EAGLE Project..." ),
_( "Import EAGLE CAD XML schematic and board" ),
import_project_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AppendSeparator();
wxMenu* importprjSubMenu = new wxMenu();
fileMenu->AddSeparator();
fileMenu->AddItem( ID_SAVE_AND_ZIP_FILES,
_( "&Archive Project..." ),
_( "Archive all needed project files into zip archive" ),
zip_xpm, SELECTION_CONDITIONS::ShowAlways );
AddMenuItem( importprjSubMenu, ID_IMPORT_EAGLE_PROJECT, _( "EAGLE CAD..." ),
_( "Import EAGLE CAD XML schematic and board" ),
KiBitmap( import_project_xpm ) );
fileMenu->AddItem( ID_READ_ZIP_ARCHIVE,
_( "&Unarchive Project..." ),
_( "Unarchive project files from zip archive" ),
unzip_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddSeparator();
// Don't use ACTIONS::quit; wxWidgets moves this on OSX and expects to find it via wxID_EXIT
fileMenu->AddItem( wxID_EXIT, _( "Quit" ), "", exit_xpm, SELECTION_CONDITIONS::ShowAlways );
AddMenuItem( fileMenu, importprjSubMenu,
wxID_ANY,
_( "Import Project" ),
_( "Import project files from other software" ),
KiBitmap( import_project_xpm ) );
fileMenu->Resolve();
//-- View menu -----------------------------------------------------------
//
CONDITIONAL_MENU* viewMenu = new CONDITIONAL_MENU( false, controlTool );
viewMenu->AddItem( ACTIONS::zoomRedraw, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AppendSeparator();
viewMenu->AddSeparator();
viewMenu->AddItem( ID_TO_TEXT_EDITOR,
_( "Open Text Editor" ), _( "Launch preferred text editor" ),
editor_xpm, SELECTION_CONDITIONS::ShowAlways );
// Archive
AddMenuItem( fileMenu,
ID_SAVE_AND_ZIP_FILES,
_( "&Archive Project..." ),
_( "Archive all needed project files into zip archive" ),
KiBitmap( zip_xpm ) );
viewMenu->AddItem( ID_BROWSE_AN_SELECT_FILE,
_( "Open Local File..." ), _( "Edit local file" ),
browse_files_xpm, SELECTION_CONDITIONS::ShowAlways );
// Unarchive
AddMenuItem( fileMenu,
ID_READ_ZIP_ARCHIVE,
_( "&Unarchive Project..." ),
_( "Unarchive project files from zip archive" ),
KiBitmap( unzip_xpm ) );
// Separator
fileMenu->AppendSeparator();
// Quit
AddMenuItem( fileMenu,
wxID_EXIT,
_( "&Exit" ),
_( "Close KiCad" ),
KiBitmap( exit_xpm ) );
// View Menu:
wxMenu* viewMenu = new wxMenu();
// Refresh project tree
msg = AddHotkeyName( _( "&Refresh" ), kicad_Manager_Hotkeys_Descr, HK_REFRESH );
AddMenuItem( viewMenu, ID_PROJECT_TREE_REFRESH, msg,
_( "Refresh project tree" ),
KiBitmap( reload_xpm ) );
viewMenu->AddItem( ID_BROWSE_IN_FILE_EXPLORER,
_( "Browse Project Files" ), _( "Open project directory in file browser" ),
directory_browser_xpm, SELECTION_CONDITIONS::ShowAlways );
#ifdef __APPLE__
viewMenu->AppendSeparator();
viewMenu->AddSeparator();
#endif
// Menu Browse:
wxMenu* browseMenu = new wxMenu();
viewMenu->Resolve();
// Text editor
AddMenuItem( browseMenu,
ID_TO_TEXT_EDITOR,
_( "Open Text E&ditor" ),
_( "Launch preferred text editor" ),
KiBitmap( editor_xpm ) );
// View file
AddMenuItem( browseMenu,
ID_BROWSE_AN_SELECT_FILE,
_( "&Open Local File..." ),
_( "Edit local file" ),
KiBitmap( browse_files_xpm ) );
// Browse in file explorer
browseMenu->AppendSeparator();
AddMenuItem( browseMenu,
ID_BROWSE_IN_FILE_EXPLORER,
_( "&Browse Project Files" ),
_( "Open project directory in file explorer" ),
KiBitmap( directory_browser_xpm ) );
// Menu Preferences:
wxMenu* preferencesMenu = new wxMenu;
// Path configuration edit dialog.
AddMenuItem( preferencesMenu,
ID_PREFERENCES_CONFIGURE_PATHS,
_( "&Configure Paths..." ),
_( "Edit path configuration environment variables" ),
KiBitmap( path_xpm ) );
AddMenuItem( preferencesMenu,
ID_EDIT_SYMBOL_LIBRARY_TABLE,
_( "Manage &Symbol Libraries..." ),
_( "Edit the global and project symbol library tables" ),
KiBitmap( library_table_xpm ) );
AddMenuItem( preferencesMenu,
ID_EDIT_FOOTPRINT_LIBRARY_TABLE,
_( "Manage &Footprint Libraries..." ),
_( "Configure footprint library table" ),
KiBitmap( library_table_xpm ) );
msg = AddHotkeyName( _( "Preferences..." ), kicad_Manager_Hotkeys_Descr, HK_PREFERENCES );
AddMenuItem( preferencesMenu, wxID_PREFERENCES, msg,
_( "Show preferences for all open tools" ),
KiBitmap( preference_xpm ) );
preferencesMenu->AppendSeparator();
// Language submenu
Pgm().AddMenuLanguageList( preferencesMenu );
// Menu Tools:
//-- Tools menu -----------------------------------------------
//
wxMenu* toolsMenu = new wxMenu;
wxString msg;
msg = AddHotkeyName( _( "Edit Schematic" ), kicad_Manager_Hotkeys_Descr, HK_RUN_EESCHEMA );
AddMenuItem( toolsMenu, ID_TO_SCH, msg, KiBitmap( eeschema_xpm ) );
@ -397,12 +287,27 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
_( "Edit worksheet graphics and text" ),
KiBitmap( pagelayout_load_xpm ) );
// Create the menubar and append all submenus
//-- Preferences menu -----------------------------------------------
//
CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, controlTool );
prefsMenu->AddItem( ACTIONS::configurePaths, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( ACTIONS::showSymbolLibTable, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( ACTIONS::showFootprintLibTable, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( wxID_PREFERENCES,
AddHotkeyName( _( "Preferences..." ), kicad_Manager_Hotkeys_Descr, HK_PREFERENCES ),
_( "Show preferences for all open tools" ),
preference_xpm, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddSeparator();
Pgm().AddMenuLanguageList( prefsMenu );
//-- Menubar -------------------------------------------------------------
//
menuBar->Append( fileMenu, _( "&File" ) );
menuBar->Append( viewMenu, _( "&View" ) );
menuBar->Append( toolsMenu, _( "&Tools" ) );
menuBar->Append( browseMenu, _( "&Browse" ) );
menuBar->Append( preferencesMenu, _( "&Preferences" ) );
menuBar->Append( prefsMenu, _( "&Preferences" ) );
AddStandardHelpMenu( menuBar );
SetMenuBar( menuBar );
@ -427,52 +332,26 @@ void KICAD_MANAGER_FRAME::RecreateBaseHToolbar()
if( m_mainToolBar )
m_mainToolBar->Clear();
else
m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
m_mainToolBar = new ACTION_TOOLBAR( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
// New
m_mainToolBar->AddTool( ID_NEW_PROJECT, wxEmptyString,
KiScaledBitmap( new_project_xpm, this ),
_( "Create new project" ) );
m_mainToolBar->AddTool( ID_NEW_PROJECT_FROM_TEMPLATE, wxEmptyString,
KiScaledBitmap( new_project_with_template_xpm, this ),
_( "Create new project from template" ) );
// Load
m_mainToolBar->AddTool( ID_LOAD_PROJECT, wxEmptyString,
KiScaledBitmap( open_project_xpm, this ),
_( "Open existing project" ) );
// Currently there is nothing to save
// (Kicad manager does not save any info in .pro file)
#if 0
// Save
m_mainToolBar->AddTool( ID_SAVE_PROJECT, wxEmptyString,
KiScaledBitmap( save_project_xpm, this ),
_( "Save current project" ) );
#endif
m_mainToolBar->Add( KICAD_MANAGER_ACTIONS::newProject );
m_mainToolBar->Add( KICAD_MANAGER_ACTIONS::newFromTemplate );
m_mainToolBar->Add( KICAD_MANAGER_ACTIONS::openProject );
KiScaledSeparator( m_mainToolBar, this );
// Archive
m_mainToolBar->AddTool( ID_SAVE_AND_ZIP_FILES, wxEmptyString,
KiScaledBitmap( zip_xpm, this ),
_( "Archive all project files" ) );
// Unarchive
m_mainToolBar->AddTool( ID_READ_ZIP_ARCHIVE, wxEmptyString,
KiScaledBitmap( unzip_xpm, this ),
_( "Unarchive project files from zip archive" ) );
KiScaledSeparator( m_mainToolBar, this );
m_mainToolBar->Add( ACTIONS::zoomRedraw );
// Refresh project tree
m_mainToolBar->AddTool( ID_PROJECT_TREE_REFRESH, wxEmptyString,
KiScaledBitmap( reload_xpm, this ),
_( "Refresh project tree" ) );
// Acces to the system file manager
KiScaledSeparator( m_mainToolBar, this );
m_mainToolBar->AddTool( ID_BROWSE_IN_FILE_EXPLORER, wxEmptyString,
KiScaledBitmap( directory_browser_xpm, this ),
@ -481,3 +360,15 @@ void KICAD_MANAGER_FRAME::RecreateBaseHToolbar()
// Create m_mainToolBar
m_mainToolBar->Realize();
}
void KICAD_MANAGER_FRAME::SyncMenusAndToolbars()
{
m_mainToolBar->ToggleTool( ID_TO_SCH, m_active_project );
m_mainToolBar->ToggleTool( ID_TO_SCH_LIB_EDITOR, m_active_project );
m_mainToolBar->ToggleTool( ID_TO_PCB, m_active_project );
m_mainToolBar->ToggleTool( ID_TO_PCB_FP_EDITOR, m_active_project );
m_mainToolBar->Refresh();
}

View File

@ -22,12 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file prjconfig.cpp
* Load and save project configuration files (*.pro)
*/
#include <wx/dir.h>
#include <wx/filename.h>
#include <wx/stdpaths.h>
@ -153,283 +147,3 @@ void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName )
// wxFile dtor will close the file
}
}
void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event )
{
wxString default_dir = GetMruPath();
wxFileDialog dlg( this, _( "Open Existing Project" ), default_dir, wxEmptyString,
ProjectFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return;
wxFileName pro( dlg.GetPath() );
pro.SetExt( ProjectFileExtension ); // enforce extension
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
if( !pro.FileExists() )
return;
LoadProject( pro );
}
///> 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;
};
void KICAD_MANAGER_FRAME::OnNewProject( wxCommandEvent& aEvent )
{
wxString default_dir = GetMruPath();
wxFileDialog dlg( this, _( "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;
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( this, msg );
return;
}
}
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( this, msg ) )
return;
}
CreateNewProject( pro );
LoadProject( pro );
}
void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event )
{
DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this );
wxFileName templatePath;
wxString envStr;
// KiCad system template path.
ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD_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;
if( ps->GetSelectedTemplate() == NULL )
{
wxMessageBox( _( "No project template was selected. Cannot generate new project." ),
_( "Error" ),
wxOK | wxICON_ERROR,
this );
return;
}
// Get project destination folder and project file name.
wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
wxString title = _( "New Project Folder" );
wxFileDialog dlg( this, title, 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;
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 ); // enforce extension
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( this, msg );
return;
}
}
if( !fn.IsDirWritable() )
{
wxString msg;
msg.Printf( _( "Cannot write to folder \"%s\"." ), fn.GetPath() );
wxMessageDialog msgDlg( this, msg, _( "Error!" ), wxICON_ERROR | wxOK | wxCENTER );
msgDlg.SetExtendedMessage( _( "Please check your access permissions to this folder "
"and try again." ) );
msgDlg.ShowModal();
return;
}
ClearMsg();
// 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( this, _( "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;
}
}
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( this,
_( "A problem occurred creating new project from template!" ),
_( "Template Error" ),
wxOK | wxICON_ERROR );
if( !errorMsg.empty() )
createDlg.SetExtendedMessage( errorMsg );
createDlg.ShowModal();
return;
}
CreateNewProject( fn.GetFullPath() );
LoadProject( fn );
}
void KICAD_MANAGER_FRAME::OnSaveProject( wxCommandEvent& event )
{
if( !wxIsWritable( GetProjectFileName() ) )
return;
Prj().ConfigSave( PgmTop().SysSearch(), GeneralGroupName, s_KicadManagerParams );
}
void KICAD_MANAGER_FRAME::OnUpdateRequiresProject( wxUpdateUIEvent& event )
{
event.Enable( m_active_project );
}

View File

@ -0,0 +1,57 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef KICAD_MANAGER_ACTIONS_H
#define KICAD_MANAGER_ACTIONS_H
#include <tool/tool_action.h>
#include <tool/actions.h>
#include <core/optional.h>
class TOOL_EVENT;
class TOOL_MANAGER;
/**
* Class KICAD_MANAGER_ACTIONS
* */
class KICAD_MANAGER_ACTIONS : public ACTIONS
{
public:
static TOOL_ACTION newProject;
static TOOL_ACTION newFromTemplate;
static TOOL_ACTION openProject;
static TOOL_ACTION importEagle;
static TOOL_ACTION archiveProject;
static TOOL_ACTION unarchiveProject;
///> @copydoc COMMON_ACTIONS::TranslateLegacyId()
virtual OPT<TOOL_EVENT> TranslateLegacyId( int aId ) override
{
return OPT<TOOL_EVENT>();
}
};
#endif

View File

@ -0,0 +1,346 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 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 <kicad_manager_frame.h>
#include <bitmaps.h>
#include <wildcards_and_files_ext.h>
#include <tool/selection.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
#include <tools/kicad_manager_actions.h>
#include <tools/kicad_manager_control.h>
#include <confirm.h>
#include <dialogs/dialog_template_selector.h>
#include <pgm_base.h>
TOOL_ACTION KICAD_MANAGER_ACTIONS::newProject( "kicad.Control.newProject",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_NEW ),
_( "New Project..." ), _( "Create new blank project" ),
new_project_xpm );
TOOL_ACTION KICAD_MANAGER_ACTIONS::newFromTemplate( "kicad.Control.newFromTemplate",
AS_GLOBAL, 0, // TOOL_ACTION::LegacyHotKey( HK_NEW_PRJ_TEMPLATE ),
_( "New Project from Template..." ), _( "Create new project from template" ),
new_project_with_template_xpm );
TOOL_ACTION KICAD_MANAGER_ACTIONS::openProject( "kicad.Control.openProject",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_OPEN ),
_( "Open Project..." ), _( "Open an existing project" ),
open_project_xpm );
///> 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( "KICAD_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() == NULL )
{
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(), 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 ); // enforce extension
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;
}
m_frame->ClearMsg();
// 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 )
{
wxString default_dir = m_frame->GetMruPath();
wxFileDialog dlg( m_frame, _( "Open Existing Project" ), default_dir, wxEmptyString,
ProjectFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;
wxFileName pro( dlg.GetPath() );
pro.SetExt( ProjectFileExtension ); // enforce extension
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
if( !pro.FileExists() )
return -1;
m_frame->LoadProject( pro );
return 0;
}
int KICAD_MANAGER_CONTROL::Refresh( const TOOL_EVENT& aEvent )
{
m_frame->RefreshProjectTree();
return 0;
}
void KICAD_MANAGER_CONTROL::setTransitions()
{
Go( &KICAD_MANAGER_CONTROL::NewProject, KICAD_MANAGER_ACTIONS::newProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::NewProject, KICAD_MANAGER_ACTIONS::newFromTemplate.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::OpenProject, KICAD_MANAGER_ACTIONS::openProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Refresh, ACTIONS::zoomRedraw.MakeEvent() );
}

View File

@ -0,0 +1,62 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef KICAD_MANAGER_CONTROL_H
#define KICAD_MANAGER_CONTROL_H
#include <tool/tool_interactive.h>
class KICAD_MANAGER_FRAME;
/**
* Class KICAD_MANAGER_CONTROL
*
* Handles actions in the kicad manager frame.
*/
class KICAD_MANAGER_CONTROL : public TOOL_INTERACTIVE
{
public:
KICAD_MANAGER_CONTROL();
~KICAD_MANAGER_CONTROL() override { }
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
int NewProject( const TOOL_EVENT& aEvent );
int NewFromTemplate( const TOOL_EVENT& aEvent );
int OpenProject( const TOOL_EVENT& aEvent );
int Refresh( const TOOL_EVENT& aEvent );
///> Sets up handlers for various events.
void setTransitions() override;
private:
///> Pointer to the currently used edit/draw frame.
KICAD_MANAGER_FRAME* m_frame;
};
#endif