Save file / window states for kicad project locally

This commit is contained in:
Mark Roszko 2020-08-24 02:01:14 +00:00 committed by Jon Evans
parent 2f7094b352
commit 89e74140eb
46 changed files with 668 additions and 216 deletions

View File

@ -127,6 +127,8 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
commonSettings->m_Backup.min_interval = m_backupMinInterval->GetValue() * 60;
commonSettings->m_Backup.limit_total_size = m_backupLimitTotalSize->GetValue() * 1024 * 1024;
commonSettings->m_Session.remember_open_files = m_cbRememberOpenFiles->GetValue();
Pgm().SetEditorName( m_textEditorPath->GetValue() );
Pgm().SetPdfBrowserName( m_PDFViewerPath->GetValue() );
@ -195,6 +197,8 @@ void PANEL_COMMON_SETTINGS::applySettingsToPanel( COMMON_SETTINGS& aSettings )
m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );
m_NonImmediateActions->SetValue( !aSettings.m_Input.immediate_actions );
m_cbRememberOpenFiles->SetValue( aSettings.m_Session.remember_open_files );
m_cbBackupEnabled->SetValue( aSettings.m_Backup.enabled );
m_cbBackupAutosave->SetValue( aSettings.m_Backup.backup_on_autosave );
m_backupLimitTotalFiles->SetValue( aSettings.m_Backup.limit_total_files );

View File

@ -278,6 +278,18 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
rightSizer->Add( sbSizer41, 1, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer5;
sbSizer5 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Session") ), wxVERTICAL );
m_cbRememberOpenFiles = new wxCheckBox( sbSizer5->GetStaticBox(), wxID_ANY, _("Remember open files for next project launch"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbRememberOpenFiles->SetValue(true);
m_cbRememberOpenFiles->SetToolTip( _("If checked, launching a project will also launch tools such as eeschema and pcbnew with previously open files") );
sbSizer5->Add( m_cbRememberOpenFiles, 0, wxALL, 5 );
rightSizer->Add( sbSizer5, 0, wxALL|wxEXPAND, 5 );
bPanelSizer->Add( rightSizer, 0, wxEXPAND|wxALL, 5 );

View File

@ -67,7 +67,7 @@
<property name="border">10</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxGridBagSizer" expanded="1">
<object class="wxGridBagSizer" expanded="0">
<property name="empty_cell_size">-1,2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@ -78,7 +78,7 @@
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="vgap">4</property>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
@ -142,14 +142,14 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxEXPAND</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer6</property>
<property name="orient">wxHORIZONTAL</property>
@ -279,14 +279,14 @@
</object>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">1</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -343,14 +343,14 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">1</property>
<property name="rowspan">1</property>
<object class="wxSpinCtrl" expanded="1">
<object class="wxSpinCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -408,23 +408,23 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxEXPAND</property>
<property name="row">2</property>
<property name="rowspan">1</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer5</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxSpinCtrl" expanded="1">
<object class="wxSpinCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -482,11 +482,11 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -545,14 +545,14 @@
</object>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -609,14 +609,14 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">2</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxChoice" expanded="1">
<object class="wxChoice" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -676,14 +676,14 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">6</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -740,14 +740,14 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">2</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="row">6</property>
<property name="rowspan">1</property>
<object class="wxChoice" expanded="1">
<object class="wxChoice" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -807,14 +807,14 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP</property>
<property name="row">2</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -877,7 +877,7 @@
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Helper Applications</property>
<property name="minimum_size"></property>
@ -885,11 +885,11 @@
<property name="orient">wxHORIZONTAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxGridBagSizer" expanded="1">
<object class="wxGridBagSizer" expanded="0">
<property name="empty_cell_size">-1,5</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@ -900,14 +900,14 @@
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="vgap">3</property>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">4</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="1">
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -964,14 +964,14 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">8</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxEXPAND</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxTextCtrl" expanded="1">
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1031,14 +1031,14 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxBitmapButton" expanded="1">
<object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1107,14 +1107,14 @@
<event name="OnButtonClick">OnTextEditorClick</event>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">4</property>
<property name="colspan">3</property>
<property name="column">0</property>
<property name="flag"></property>
<property name="row">3</property>
<property name="rowspan">1</property>
<object class="wxRadioButton" expanded="1">
<object class="wxRadioButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1174,14 +1174,14 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">4</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxRadioButton" expanded="1">
<object class="wxRadioButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1241,14 +1241,14 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">8</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxEXPAND</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxTextCtrl" expanded="1">
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1309,14 +1309,14 @@
<event name="OnUpdateUI">onUpdateUIPdfPath</event>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<object class="gbsizeritem" expanded="0">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="row">4</property>
<property name="rowspan">1</property>
<object class="wxBitmapButton" expanded="1">
<object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -2914,6 +2914,84 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label">Session</property>
<property name="minimum_size"></property>
<property name="name">sbSizer5</property>
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Remember open files for next project launch</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbRememberOpenFiles</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">If checked, launching a project will also launch tools such as eeschema and pcbnew with previously open files</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>

View File

@ -81,6 +81,7 @@ class PANEL_COMMON_SETTINGS_BASE : public RESETTABLE_PANEL
wxStaticText* m_staticText16;
wxSpinCtrl* m_backupLimitTotalSize;
wxStaticText* m_staticText17;
wxCheckBox* m_cbRememberOpenFiles;
// Virtual event handlers, overide them in your derived class
virtual void OnTextEditorClick( wxCommandEvent& event ) { event.Skip(); }

View File

@ -36,6 +36,7 @@
#include <settings/app_settings.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <project/project_local_settings.h>
#include <tool/action_manager.h>
#include <tool/action_menu.h>
#include <tool/actions.h>
@ -85,7 +86,8 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
m_autoSaveInterval(-1 ),
m_UndoRedoCountMax( DEFAULT_MAX_UNDO_ITEMS ),
m_userUnits( EDA_UNITS::MILLIMETRES ),
m_shuttingDown( false )
m_isClosing( false ),
m_isNonUserClose( false )
{
m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
m_mruPath = wxStandardPaths::Get().GetDocumentsDir();
@ -146,12 +148,30 @@ void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
return;
}
APP_SETTINGS_BASE* cfg = config();
if( cfg )
SaveSettings( cfg ); // virtual, wxFrame specific
if( event.GetId() == wxEVT_QUERY_END_SESSION
|| event.GetId() == wxEVT_END_SESSION )
{
// End session means the OS is going to terminate us
m_isNonUserClose = true;
}
event.Skip(); // we did not "handle" the event, only eavesdropped on it.
if( canCloseWindow( event ) )
{
m_isClosing = true;
APP_SETTINGS_BASE* cfg = config();
if( cfg )
SaveSettings( cfg ); // virtual, wxFrame specific
doCloseWindow();
Destroy();
}
else
{
event.Veto();
}
}
@ -430,15 +450,25 @@ void EDA_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
}
void EDA_BASE_FRAME::LoadWindowSettings( WINDOW_SETTINGS* aCfg )
void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName )
{
m_FramePos.x = aCfg->pos_x;
m_FramePos.y = aCfg->pos_y;
m_FrameSize.x = aCfg->size_x;
m_FrameSize.y = aCfg->size_y;
const PROJECT_FILE_STATE* state = Prj().GetLocalSettings().GetFileState( aFileName );
if( state != nullptr )
{
LoadWindowState( state->window );
}
}
void EDA_BASE_FRAME::LoadWindowState( const WINDOW_STATE& aState )
{
m_FramePos.x = aState.pos_x;
m_FramePos.y = aState.pos_y;
m_FrameSize.x = aState.size_x;
m_FrameSize.y = aState.size_y;
wxLogTrace( traceDisplayLocation, "Config position (%d, %d) with size (%d, %d)",
m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
// Ensure minimum size is set if the stored config was zero-initialized
if( m_FrameSize.x < s_minsize_x || m_FrameSize.y < s_minsize_y )
@ -451,7 +481,7 @@ void EDA_BASE_FRAME::LoadWindowSettings( WINDOW_SETTINGS* aCfg )
wxLogTrace( traceDisplayLocation, "Number of displays: %d", wxDisplay::GetCount() );
if( aCfg->display >= wxDisplay::GetCount() )
if( aState.display >= wxDisplay::GetCount() )
{
wxLogTrace( traceDisplayLocation, "Previous display not found" );
@ -459,7 +489,7 @@ void EDA_BASE_FRAME::LoadWindowSettings( WINDOW_SETTINGS* aCfg )
// Warning wxDisplay has 2 ctor variants. the parameter needs a type:
const unsigned int index = 0;
wxDisplay display( index );
wxRect clientSize = display.GetClientArea();
wxRect clientSize = display.GetGeometry();
m_FramePos = wxDefaultPosition;
@ -475,11 +505,11 @@ void EDA_BASE_FRAME::LoadWindowSettings( WINDOW_SETTINGS* aCfg )
wxPoint upperRight( m_FramePos.x + m_FrameSize.x, m_FramePos.y );
wxPoint upperLeft( m_FramePos.x, m_FramePos.y );
wxDisplay display( aCfg->display );
wxRect clientSize = display.GetClientArea();
wxDisplay display( aState.display );
wxRect clientSize = display.GetClientArea();
// The percentage size (represented in decimal) of the region around the screen's border where
// an upper corner is not allowed
// The percentage size (represented in decimal) of the region around the screen's border where
// an upper corner is not allowed
#define SCREEN_BORDER_REGION 0.10
int yLim = clientSize.y + ( clientSize.height * ( 1.0 - SCREEN_BORDER_REGION ) );
@ -523,11 +553,17 @@ void EDA_BASE_FRAME::LoadWindowSettings( WINDOW_SETTINGS* aCfg )
m_NormalFramePos = m_FramePos;
// Maximize if we were maximized before
if( aCfg->maximized )
if( aState.maximized )
{
wxLogTrace( traceDisplayLocation, "Maximizing window" );
Maximize();
}
}
void EDA_BASE_FRAME::LoadWindowSettings( const WINDOW_SETTINGS* aCfg )
{
LoadWindowState( aCfg->state );
if( m_hasAutoSave )
m_autoSaveInterval = Pgm().GetCommonSettings()->m_System.autosave_interval;
@ -560,12 +596,12 @@ void EDA_BASE_FRAME::SaveWindowSettings( WINDOW_SETTINGS* aCfg )
m_FramePos = GetPosition();
}
aCfg->pos_x = m_FramePos.x;
aCfg->pos_y = m_FramePos.y;
aCfg->size_x = m_FrameSize.x;
aCfg->size_y = m_FrameSize.y;
aCfg->maximized = IsMaximized();
aCfg->display = wxDisplay::GetFromWindow( this );
aCfg->state.pos_x = m_FramePos.x;
aCfg->state.pos_y = m_FramePos.y;
aCfg->state.size_x = m_FrameSize.x;
aCfg->state.size_y = m_FrameSize.y;
aCfg->state.maximized = IsMaximized();
aCfg->state.display = wxDisplay::GetFromWindow( this );
wxLogTrace( traceDisplayLocation, "Saving window maximized: %s", IsMaximized() ? "true" : "false" );
wxLogTrace( traceDisplayLocation, "Saving config position (%d, %d) with size (%d, %d)",
@ -602,6 +638,12 @@ void EDA_BASE_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
{
SaveWindowSettings( GetWindowSettings( aCfg ) );
bool fileOpen = m_isClosing && m_isNonUserClose;
wxFileName rfn( GetCurrentFileName() );
rfn.MakeRelativeTo( Prj().GetProjectPath() );
Prj().GetLocalSettings().SaveFileState( rfn.GetFullPath(), &aCfg->m_Window, fileOpen );
// Save the recently used files list
if( m_fileHistory )
{
@ -657,7 +699,7 @@ void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTO
aFileHistory->AddFileToHistory( FullFileName );
// Update the menubar to update the file history menu
if( !m_shuttingDown && GetMenuBar() )
if( !m_isClosing && GetMenuBar() )
{
ReCreateMenuBar();
GetMenuBar()->Refresh();

View File

@ -409,7 +409,7 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
if( frame == NULL ) // Already closed
return true;
if( frame->Close( doForce ) )
if( frame->NonUserClose( doForce ) )
return true;
return false;

View File

@ -45,7 +45,8 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType
long aStyle, const wxString& aWdoName ) :
EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName, aKiway ),
m_modal( false ),
m_modal_loop( 0 ), m_modal_resultant_parent( 0 )
m_modal_loop( 0 ),
m_modal_resultant_parent( 0 )
{
m_modal_ret_val = 0;
}

View File

@ -103,24 +103,17 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
if( aVal.empty() || !aVal.is_object() )
return;
auto setIfPresent =
[&aVal]( const std::string& aKey, bool& aTarget )
{
if( aVal.contains( aKey ) && aVal.at( aKey ).is_boolean() )
aTarget = aVal.at( aKey ).get<bool>();
};
setIfPresent( "lockedItems", m_SelectionFilter.lockedItems );
setIfPresent( "footprints", m_SelectionFilter.footprints );
setIfPresent( "text", m_SelectionFilter.text );
setIfPresent( "tracks", m_SelectionFilter.tracks );
setIfPresent( "vias", m_SelectionFilter.vias );
setIfPresent( "pads", m_SelectionFilter.pads );
setIfPresent( "graphics", m_SelectionFilter.graphics );
setIfPresent( "zones", m_SelectionFilter.zones );
setIfPresent( "keepouts", m_SelectionFilter.keepouts );
setIfPresent( "dimensions", m_SelectionFilter.dimensions );
setIfPresent( "otherItems", m_SelectionFilter.otherItems );
SetIfPresent( aVal, "lockedItems", m_SelectionFilter.lockedItems );
SetIfPresent( aVal, "footprints", m_SelectionFilter.footprints );
SetIfPresent( aVal, "text", m_SelectionFilter.text );
SetIfPresent( aVal, "tracks", m_SelectionFilter.tracks );
SetIfPresent( aVal, "vias", m_SelectionFilter.vias );
SetIfPresent( aVal, "pads", m_SelectionFilter.pads );
SetIfPresent( aVal, "graphics", m_SelectionFilter.graphics );
SetIfPresent( aVal, "zones", m_SelectionFilter.zones );
SetIfPresent( aVal, "keepouts", m_SelectionFilter.keepouts );
SetIfPresent( aVal, "dimensions", m_SelectionFilter.dimensions );
SetIfPresent( aVal, "otherItems", m_SelectionFilter.otherItems );
},
{
{ "lockedItems", true },
@ -163,6 +156,65 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
&m_ZoneDisplayMode, ZONE_DISPLAY_MODE::SHOW_FILLED, ZONE_DISPLAY_MODE::SHOW_OUTLINED,
ZONE_DISPLAY_MODE::SHOW_FILLED ) );
#endif
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "project.files",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
for( PROJECT_FILE_STATE& fileState : m_files )
{
nlohmann::json file;
file["name"] = fileState.fileName;
file["open"] = fileState.open;
nlohmann::json window;
window["maximized"] = fileState.window.maximized;
window["size_x"] = fileState.window.size_x;
window["size_y"] = fileState.window.size_y;
window["pos_x"] = fileState.window.pos_x;
window["pos_y"] = fileState.window.pos_y;
window["display"] = fileState.window.display;
file["window"] = window;
ret.push_back( file );
}
return ret;
},
[&]( const nlohmann::json& aVal )
{
if( !aVal.is_array() || aVal.empty() )
{
return;
}
for( const nlohmann::json& file : aVal )
{
PROJECT_FILE_STATE fileState;
try
{
SetIfPresent( file, "name", fileState.fileName );
SetIfPresent( file, "open", fileState.open );
SetIfPresent( file, "window.size_x", fileState.window.size_x );
SetIfPresent( file, "window.size_y", fileState.window.size_y );
SetIfPresent( file, "window.pos_x", fileState.window.pos_x );
SetIfPresent( file, "window.pos_y", fileState.window.pos_y );
SetIfPresent( file, "window.maximized", fileState.window.maximized );
SetIfPresent( file, "window.display", fileState.window.display );
m_files.push_back( fileState );
}
catch( ... )
{
// Non-integer or out of range entry in the array; ignore
}
}
},
{
} ) );
}
@ -229,3 +281,50 @@ bool PROJECT_LOCAL_SETTINGS::migrateSchema1to2()
return true;
}
const PROJECT_FILE_STATE* PROJECT_LOCAL_SETTINGS::GetFileState( const wxString& aFileName )
{
auto it = std::find_if( m_files.begin(), m_files.end(),
[&aFileName]( const PROJECT_FILE_STATE &a )
{
return a.fileName == aFileName;
} );
if( it != m_files.end() )
{
return &( *it );
}
return nullptr;
}
void PROJECT_LOCAL_SETTINGS::SaveFileState( const wxString& aFileName, const WINDOW_SETTINGS* aWindowCfg,
bool aOpen )
{
auto it = std::find_if( m_files.begin(), m_files.end(),
[&aFileName]( const PROJECT_FILE_STATE& a )
{
return a.fileName == aFileName;
} );
if( it == m_files.end() )
{
PROJECT_FILE_STATE fileState;
fileState.fileName = aFileName;
m_files.push_back( fileState );
it = m_files.end() - 1;
}
( *it ).window = aWindowCfg->state;
( *it ).open = aOpen;
}
void PROJECT_LOCAL_SETTINGS::ClearFileState()
{
m_files.clear();
}

View File

@ -262,23 +262,23 @@ bool APP_SETTINGS_BASE::migrateWindowConfig( wxConfigBase* aCfg, const std::stri
void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath )
{
m_params.emplace_back( new PARAM<bool>( aJsonPath + ".maximized",
&aWindow->maximized, false ) );
&aWindow->state.maximized, false ) );
m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".mru_path",
&aWindow->mru_path, "" ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->size_x, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->state.size_x, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->size_y, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->state.size_y, 0 ) );
m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".perspective",
&aWindow->perspective, "" ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->pos_x, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->state.pos_x, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->pos_y, 0 ) );
m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->state.pos_y, 0 ) );
m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->display, 0 ) );
m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->state.display, 0 ) );
m_params.emplace_back( new PARAM_LIST<double>( aJsonPath + ".zoom_factors",
&aWindow->zoom_factors, {} ) );

View File

@ -176,6 +176,8 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
m_params.emplace_back( new PARAM<int>( "system.clear_3d_cache_interval",
&m_System.clear_3d_cache_interval, 30 ) );
m_params.emplace_back( new PARAM<bool>( "session.remember_open_files",
&m_Session.remember_open_files, false ) );
}

View File

@ -448,6 +448,66 @@ nlohmann::json::json_pointer JSON_SETTINGS::PointerFromString( std::string aPath
}
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
wxString& aTarget )
{
nlohmann::json::json_pointer ptr = PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_string() )
{
aTarget = aObj.at( ptr ).get<wxString>();
return true;
}
return false;
}
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
bool& aTarget )
{
nlohmann::json::json_pointer ptr = PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_boolean() )
{
aTarget = aObj.at( ptr ).get<bool>();
return true;
}
return false;
}
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
int& aTarget )
{
nlohmann::json::json_pointer ptr = PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_number_integer() )
{
aTarget = aObj.at( ptr ).get<int>();
return true;
}
return false;
}
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
unsigned int& aTarget )
{
nlohmann::json::json_pointer ptr = PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_number_unsigned() )
{
aTarget = aObj.at( ptr ).get<unsigned int>();
return true;
}
return false;
}
template<typename ValueType>
bool JSON_SETTINGS::fromLegacy( wxConfigBase* aConfig, const std::string& aKey,
const std::string& aDest )

View File

@ -307,7 +307,6 @@ void CVPCB_MAINFRAME::setupEventHandlers()
}, wxID_CANCEL );
// Connect the handlers for the close events
Bind( wxEVT_CLOSE_WINDOW, &CVPCB_MAINFRAME::OnCloseWindow, this );
Bind( wxEVT_MENU,
[this]( wxCommandEvent& )
{
@ -336,26 +335,30 @@ void CVPCB_MAINFRAME::setupEventHandlers()
}
void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool CVPCB_MAINFRAME::canCloseWindow( wxCloseEvent& aEvent )
{
if( m_modified )
{
// Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )
{
aEvent.Veto();
return;
return false;
}
if( !HandleUnsavedChanges( this, _( "Symbol to Footprint links have been modified. "
"Save changes?" ),
[&]()->bool { return SaveFootprintAssociation( false ); } ) )
{
aEvent.Veto();
return;
return false;
}
}
return true;
}
void CVPCB_MAINFRAME::doCloseWindow()
{
// Close module display frame
if( GetFootprintViewerFrame() )
GetFootprintViewerFrame()->Close( true );
@ -364,10 +367,6 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& aEvent )
// clear highlight symbol in schematic:
SendMessageToEESCHEMA( true );
// Skip the close event. Looks like needed to have the close event sent to the
// root class EDA_BASE_FRAME, and save config
aEvent.Skip();
}

View File

@ -181,12 +181,8 @@ public:
*/
void OnSelectComponent( wxListEvent& event );
/**
* OnCloseWindow
*
* Called by a close event to close the window
*/
void OnCloseWindow( wxCloseEvent& Event );
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
void doCloseWindow() override;
/*
* Functions to rebuild the toolbars and menubars

View File

@ -219,7 +219,7 @@ void DISPLAY_FOOTPRINTS_FRAME::setupUIConditions()
}
void DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow( wxCloseEvent& event )
void DISPLAY_FOOTPRINTS_FRAME::doCloseWindow()
{
Destroy();
}

View File

@ -47,7 +47,7 @@ public:
DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, wxWindow* aParent );
~DISPLAY_FOOTPRINTS_FRAME() override;
void OnCloseWindow( wxCloseEvent& Event ) override;
void doCloseWindow() override;
void ReCreateHToolbar() override;
void ReCreateVToolbar() override;

View File

@ -250,22 +250,22 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
&m_PlotPanel.hpgl_origin, false ) );
m_params.emplace_back( new PARAM<int>( "simulator.window.pos_x",
&m_Simulator.window.pos_x, 0 ) );
&m_Simulator.window.state.pos_x, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.window.pos_y",
&m_Simulator.window.pos_y, 0 ) );
&m_Simulator.window.state.pos_y, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.window.size_x",
&m_Simulator.window.size_x, 500 ) );
&m_Simulator.window.state.size_x, 500 ) );
m_params.emplace_back( new PARAM<int>( "simulator.window.size_y",
&m_Simulator.window.size_y, 400 ) );
&m_Simulator.window.state.size_y, 400 ) );
m_params.emplace_back( new PARAM<unsigned int>( "simulator.window.display",
&m_Simulator.window.display, 0 ) );
&m_Simulator.window.state.display, 0 ) );
m_params.emplace_back( new PARAM<bool>( "simulator.window.maximized",
&m_Simulator.window.maximized, false ) );
&m_Simulator.window.state.maximized, false ) );
m_params.emplace_back( new PARAM<wxString>( "simulator.window.perspective",
&m_Simulator.window.perspective, "" ) );
@ -307,22 +307,22 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
&m_RescueNeverShow, false ) );
m_params.emplace_back( new PARAM<int>( "lib_view.window.pos_x",
&m_LibViewPanel.window.pos_x, 0 ) );
&m_LibViewPanel.window.state.pos_x, 0 ) );
m_params.emplace_back( new PARAM<int>( "lib_view.window.pos_y",
&m_LibViewPanel.window.pos_y, 0 ) );
&m_LibViewPanel.window.state.pos_y, 0 ) );
m_params.emplace_back( new PARAM<int>( "lib_view.window.size_x",
&m_LibViewPanel.window.size_x, 500 ) );
&m_LibViewPanel.window.state.size_x, 500 ) );
m_params.emplace_back( new PARAM<int>( "lib_view.window.size_y",
&m_LibViewPanel.window.size_y, 400 ) );
&m_LibViewPanel.window.state.size_y, 400 ) );
m_params.emplace_back( new PARAM<unsigned int>( "lib_view.window.display",
&m_LibViewPanel.window.display, 0 ) );
&m_LibViewPanel.window.state.display, 0 ) );
m_params.emplace_back( new PARAM<bool>( "lib_view.window.maximized",
&m_LibViewPanel.window.maximized, false ) );
&m_LibViewPanel.window.state.maximized, false ) );
m_params.emplace_back( new PARAM<wxString>( "lib_view.window.perspective",
&m_LibViewPanel.window.perspective, "" ) );

View File

@ -320,6 +320,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// update some of the needed schematic settings such as drawing defaults
LoadProjectSettings();
wxFileName rfn( GetCurrentFileName() );
rfn.MakeRelativeTo( Prj().GetProjectPath() );
LoadWindowState( rfn.GetFullPath() );
SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) );
if( Kiface().IsSingle() )
{

View File

@ -71,7 +71,6 @@
bool LIB_EDIT_FRAME:: m_showDeMorgan = false;
BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_CLOSE( LIB_EDIT_FRAME::OnCloseWindow )
EVT_SIZE( LIB_EDIT_FRAME::OnSize )
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectUnit )
@ -431,20 +430,27 @@ void LIB_EDIT_FRAME::setupUIConditions()
}
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool LIB_EDIT_FRAME::canCloseWindow(wxCloseEvent& aEvent)
{
// Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& IsContentModified() )
&& IsContentModified() )
{
aEvent.Veto();
return;
return false;
}
if( saveAllLibraries( true ) )
Destroy();
else
aEvent.Veto();
if( !saveAllLibraries( true ) )
{
return false;
}
return true;
}
void LIB_EDIT_FRAME::doCloseWindow()
{
Destroy();
}

View File

@ -213,7 +213,8 @@ public:
void UpdateAfterSymbolProperties( wxString* aOldName = nullptr );
void RebuildSymbolUnitsList();
void OnCloseWindow( wxCloseEvent& Event );
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
void doCloseWindow() override;
void OnExitKiCad( wxCommandEvent& event );
void ReCreateHToolbar() override;
void ReCreateVToolbar() override;

View File

@ -191,7 +191,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, EDA_DRAW_FRAME::OnSockRequestServer )
EVT_SOCKET( ID_EDA_SOCKET_EVENT, EDA_DRAW_FRAME::OnSockRequest )
EVT_CLOSE( SCH_EDIT_FRAME::OnCloseWindow )
EVT_SIZE( SCH_EDIT_FRAME::OnSize )
EVT_MENU_RANGE( ID_FILE1, ID_FILEMAX, SCH_EDIT_FRAME::OnLoadFile )
@ -576,40 +575,39 @@ void SCH_EDIT_FRAME::HardRedraw()
}
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
{
// Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& Schematic().GetSheets().IsModified() )
&& Schematic().GetSheets().IsModified() )
{
aEvent.Veto();
return;
return false;
}
if( Kiface().IsSingle() )
{
LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
if( libeditFrame && !libeditFrame->Close() ) // Can close component editor?
return;
return false;
LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
if( viewlibFrame && !viewlibFrame->Close() ) // Can close component viewer?
return;
return false;
viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, false );
if( viewlibFrame && !viewlibFrame->Close() ) // Can close modal component viewer?
return;
return false;
}
SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false );
if( simFrame && !simFrame->Close() ) // Can close the simulator?
return;
return false;
// We may have gotten multiple events; don't clean up twice
if( !Schematic().IsValid() )
return;
return false;
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
@ -621,15 +619,17 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
[&]()->bool { return SaveProject(); } ) )
{
aEvent.Veto();
return;
return false;
}
}
//
// OK, we're really closing now. No more returns after this.
//
m_shuttingDown = true;
return true;
}
void SCH_EDIT_FRAME::doCloseWindow()
{
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
// Shutdown all running tools ( and commit any pending change )
if( m_toolManager )

View File

@ -166,8 +166,6 @@ public:
SCHEMATIC& Schematic() const;
void OnCloseWindow( wxCloseEvent& Event );
/**
* Allow edit frame to show/hide hidden pins.
*/
@ -628,6 +626,9 @@ private:
void OnClearFileHistory( wxCommandEvent& aEvent );
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
void doCloseWindow() override;
/**
* Set the main window title bar text.
*

View File

@ -166,7 +166,6 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
updateNetlistExporter();
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SIM_PLOT_FRAME::onClose ), NULL, this );
Connect( EVT_SIM_UPDATE, wxCommandEventHandler( SIM_PLOT_FRAME::onSimUpdate ), NULL, this );
Connect( EVT_SIM_REPORT, wxCommandEventHandler( SIM_PLOT_FRAME::onSimReport ), NULL, this );
Connect( EVT_SIM_STARTED, wxCommandEventHandler( SIM_PLOT_FRAME::onSimStarted ), NULL, this );
@ -1409,7 +1408,7 @@ void SIM_PLOT_FRAME::onShowNetlist( wxCommandEvent& event )
}
void SIM_PLOT_FRAME::onClose( wxCloseEvent& aEvent )
void SIM_PLOT_FRAME::doCloseWindow()
{
SaveSettings( config() );

View File

@ -328,7 +328,7 @@ private:
void onTune( wxCommandEvent& event );
void onShowNetlist( wxCommandEvent& event );
void onClose( wxCloseEvent& aEvent );
void doCloseWindow() override;
void onCursorUpdate( wxCommandEvent& aEvent );
void onSimUpdate( wxCommandEvent& aEvent );

View File

@ -222,8 +222,10 @@ GERBVIEW_FRAME::~GERBVIEW_FRAME()
}
void GERBVIEW_FRAME::OnCloseWindow( wxCloseEvent& Event )
void GERBVIEW_FRAME::doCloseWindow()
{
// No more vetos
m_isClosing = true;
GetCanvas()->StopDrawing();
GetCanvas()->GetView()->Clear();

View File

@ -212,7 +212,7 @@ public:
GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent );
~GERBVIEW_FRAME();
void OnCloseWindow( wxCloseEvent& Event );
void doCloseWindow() override;
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) override;

View File

@ -79,6 +79,7 @@ class SETTINGS_MANAGER;
class APP_SETTINGS_BASE;
class WX_INFOBAR;
struct WINDOW_SETTINGS;
struct WINDOW_STATE;
enum id_librarytype {
LIBRARY_TYPE_EESCHEMA,
@ -163,10 +164,11 @@ protected:
EDA_UNITS m_userUnits;
bool m_shuttingDown;
// Map containing the UI update handlers registered with wx for each action
std::map<int, UIUpdateHandler> m_uiUpdateMap;
bool m_isClosing; // Set by the close window event handler after frames are asked if they can close
// Allows other functions when called to know our state is cleanup
bool m_isNonUserClose; // Set by NonUserClose() to indicate that the user did not request the current close
///> Default style flags used for wxAUI toolbars
static constexpr int KICAD_AUI_TB_STYLE = wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_PLAIN_BACKGROUND;
@ -206,6 +208,9 @@ protected:
*/
virtual bool doAutoSave();
virtual bool canCloseWindow( wxCloseEvent& aCloseEvent ) { return true; }
virtual void doCloseWindow() { }
/**
* Called when when the units setting has changed to allow for any derived classes
* to handle refreshing and controls that have units based measurements in them. The
@ -351,12 +356,14 @@ public:
*/
virtual void InstallPreferences( PAGED_DIALOG* , PANEL_HOTKEYS_EDITOR* ) { }
void LoadWindowState( const wxString& aFileName );
/**
* Loads window settings from the given settings object
* Normally called by LoadSettings unless the window in question is a child window that
* stores its settings somewhere other than APP_SETTINGS_BASE::m_Window
*/
void LoadWindowSettings( WINDOW_SETTINGS* aCfg );
void LoadWindowSettings( const WINDOW_SETTINGS* aCfg );
/**
* Saves window settings to the given settings object
@ -389,6 +396,11 @@ public:
*/
virtual WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg );
/**
* Load frame state info from a configuration file
*/
virtual void LoadWindowState( const WINDOW_STATE& aState );
/**
* @return a base name prefix used in Load/Save settings to build the full name of keys
* used in config.
@ -644,6 +656,8 @@ public:
virtual int GetRedoCommandCount() const { return m_redoList.m_CommandsList.size(); }
int GetMaxUndoItems() const { return m_UndoRedoCountMax; }
bool NonUserClose( bool aForce ) { m_isNonUserClose = true; return Close( aForce ); };
};

View File

@ -211,7 +211,6 @@ public:
void FocusOnItem( BOARD_ITEM* aItem );
// General
virtual void OnCloseWindow( wxCloseEvent& Event ) = 0;
virtual void ReCreateOptToolbar() override { }
virtual void ShowChangedLanguage() override;
virtual void ReCreateMenuBar() override;

View File

@ -25,9 +25,18 @@
#include <project/board_project_settings.h>
#include <settings/json_settings.h>
#include <wildcards_and_files_ext.h>
#include <settings/app_settings.h>
class PROJECT;
struct PROJECT_FILE_STATE
{
wxString fileName;
bool open;
struct WINDOW_STATE window;
};
/**
* The project local settings are things that are attached to a particular project, but also might
* be particular to a certain user editing that project, or change quickly, and therefore may not
@ -80,6 +89,13 @@ private:
public:
/**
* Project scope
*/
/// File based state
std::vector<PROJECT_FILE_STATE> m_files;
/**
* Board settings
*/
@ -118,6 +134,12 @@ public:
/// State of the selection filter widget
SELECTION_FILTER_OPTIONS m_SelectionFilter;
void SaveFileState( const wxString& aFileName, const WINDOW_SETTINGS* aWindowCfg, bool aOpen );
const PROJECT_FILE_STATE* GetFileState( const wxString& aFileName );
void ClearFileState();
};
#endif

View File

@ -61,21 +61,27 @@ struct GRID_SETTINGS
int style;
};
/**
* Stores the window positioning/state
*/
struct WINDOW_STATE
{
bool maximized;
int size_x;
int size_y;
int pos_x;
int pos_y;
unsigned int display;
};
/**
* Stores the common settings that are saved and loaded for each window / frame
*/
struct WINDOW_SETTINGS
{
bool maximized;
WINDOW_STATE state;
wxString mru_path;
int size_x;
int size_y;
wxString perspective;
int pos_x;
int pos_y;
unsigned int display;
std::vector<double> zoom_factors;
CURSOR_SETTINGS cursor;

View File

@ -80,6 +80,11 @@ public:
int opengl_aa_mode;
};
struct SESSION
{
bool remember_open_files;
};
struct SYSTEM
{
int autosave_interval;
@ -114,6 +119,8 @@ public:
GRAPHICS m_Graphics;
SESSION m_Session;
SYSTEM m_System;
// TODO: These may not want to be in common

View File

@ -184,6 +184,37 @@ c * @return true if the file was saved
*/
static nlohmann::json::json_pointer PointerFromString( std::string aPath );
/**
* Sets the given string if the given key/path is present
* @param aObj is the source object
* @param aTarget is the storage destination
* @return True if set, false if not
*/
static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, wxString& aTarget );
/**
* Sets the given bool if the given key/path is present
* @param aObj is the source object
* @param aTarget is the storage destination
* @return True if set, false if not
*/
static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, bool& aTarget );
/**
* Sets the given int if the given key/path is present
* @param aObj is the source object
* @param aTarget is the storage destination
* @return True if set, false if not
*/
static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, int& aTarget );
/**
* Sets the given unsigned int if the given key/path is present
* @param aObj is the source object
* @param aTarget is the storage destination
* @return True if set, false if not
*/
static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, unsigned int& aTarget );
protected:
/**

View File

@ -38,6 +38,7 @@
#include <launch_ext.h>
#include <panel_hotkeys_editor.h>
#include <reporter.h>
#include <project/project_local_settings.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <tool/action_manager.h>
@ -48,6 +49,7 @@
#include <tools/kicad_manager_actions.h>
#include <tools/kicad_manager_control.h>
#include <wildcards_and_files_ext.h>
#include <widgets/app_progress_dialog.h>
#ifdef __WXMAC__
#include <MacTypes.h>
@ -65,7 +67,7 @@
BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
// Window events
EVT_SIZE( KICAD_MANAGER_FRAME::OnSize )
EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow )
EVT_IDLE( KICAD_MANAGER_FRAME::OnIdle )
// Menu events
EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
@ -322,7 +324,7 @@ void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
}
void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
void KICAD_MANAGER_FRAME::doCloseWindow()
{
#ifdef _WINDOWS_
// For some obscure reason, on Windows, when killing Kicad from the Windows task manager
@ -344,8 +346,6 @@ void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
KICAD_SETTINGS* settings = kicadSettings();
settings->m_OpenProjects = GetSettingsManager()->GetOpenProjects();
aEvent.SetCanVeto( true );
if( CloseProject( true ) )
{
m_leftWin->Show( false );
@ -367,7 +367,6 @@ void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
bool KICAD_MANAGER_FRAME::CloseProject( bool aSave )
{
if( !Kiway().PlayersClose( false ) )
return false;
@ -414,6 +413,8 @@ void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() );
LoadWindowState( aProjectFileName.GetFullName() );
if( aProjectFileName.IsDirWritable() )
SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why?
@ -431,6 +432,7 @@ void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName )
PrintPrjInfo();
KIPLATFORM::APP::RegisterApplicationRestart( aProjectFileName.GetFullPath() );
m_openSavedWindows = true;
}
@ -513,6 +515,8 @@ void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName,
}
UpdateFileHistory( aProjectFileName.GetFullPath() );
m_openSavedWindows = true;
}
@ -648,3 +652,55 @@ bool KICAD_MANAGER_FRAME::IsProjectActive()
{
return m_active_project;
}
void KICAD_MANAGER_FRAME::OnIdle( wxIdleEvent& aEvent )
{
/**
* We start loading the saved previously open windows on idle to avoid locking up the GUI earlier in project loading
* This gives us the visual effect of a opened KiCad project but with a "busy" progress reporter
*/
if( m_openSavedWindows )
{
m_openSavedWindows = false;
if ( Pgm().GetCommonSettings()->m_Session.remember_open_files )
{
int previousOpenCount = std::count_if( Prj().GetLocalSettings().m_files.begin(),
Prj().GetLocalSettings().m_files.end(),
[&]( const PROJECT_FILE_STATE& f )
{
return !f.fileName.EndsWith( ProjectFileExtension ) && f.open;
} );
if ( previousOpenCount > 0 )
{
APP_PROGRESS_DIALOG progressReporter( _( "Restoring session" ), wxEmptyString, previousOpenCount, this );
int i = 0;
for( const PROJECT_FILE_STATE& file : Prj().GetLocalSettings().m_files )
{
if( file.open )
{
progressReporter.Update(
i++, wxString::Format( _( "Restoring \"%s\"" ), file.fileName ) );
wxFileName fn( file.fileName );
if( fn.GetExt() == LegacySchematicFileExtension
|| fn.GetExt() == KiCadSchematicFileExtension )
{
GetToolManager()->RunAction( KICAD_MANAGER_ACTIONS::editSchematic, true );
}
else if( fn.GetExt() == LegacyPcbFileExtension
|| fn.GetExt() == KiCadPcbFileExtension )
{
GetToolManager()->RunAction( KICAD_MANAGER_ACTIONS::editPCB, true );
}
}
wxYield();
}
}
}
// clear file states regardless if we opened windows or not due to setting
Prj().GetLocalSettings().ClearFileState();
}
}

View File

@ -83,7 +83,9 @@ public:
~KICAD_MANAGER_FRAME();
void OnCloseWindow( wxCloseEvent& Event );
void OnIdle( wxIdleEvent& event );
void doCloseWindow() override;
void OnSize( wxSizeEvent& event );
void OnArchiveFiles( wxCommandEvent& event );
@ -197,6 +199,8 @@ private:
void language_change( wxCommandEvent& event );
bool m_openSavedWindows;
private:
TREE_PROJECT_FRAME* m_leftWin;
ACTION_TOOLBAR* m_launcher;

View File

@ -62,7 +62,6 @@
#include <settings/settings_manager.h>
BEGIN_EVENT_TABLE( PL_EDITOR_FRAME, EDA_DRAW_FRAME )
EVT_CLOSE( PL_EDITOR_FRAME::OnCloseWindow )
EVT_MENU( wxID_CLOSE, PL_EDITOR_FRAME::OnExit )
EVT_MENU( wxID_EXIT, PL_EDITOR_FRAME::OnExit )
@ -329,29 +328,33 @@ void PL_EDITOR_FRAME::OnExit( wxCommandEvent& aEvent )
}
void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool PL_EDITOR_FRAME::canCloseWindow( wxCloseEvent& aEvent )
{
// Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& IsContentModified() )
{
aEvent.Veto();
return;
return false;
}
if( IsContentModified() )
{
wxFileName filename = GetCurrentFileName();
wxString msg = _( "Save changes to \"%s\" before closing?" );
wxString msg = _( "Save changes to \"%s\" before closing?" );
if( !HandleUnsavedChanges( this, wxString::Format( msg, filename.GetFullName() ),
[&]()->bool { return saveCurrentPageLayout(); } ) )
[&]() -> bool { return saveCurrentPageLayout(); } ) )
{
aEvent.Veto();
return;
return false;
}
}
return true;
}
void PL_EDITOR_FRAME::doCloseWindow()
{
// do not show the window because we do not want any paint event
Show( false );

View File

@ -108,11 +108,8 @@ public:
*/
void OnExit( wxCommandEvent& aEvent );
/*
* Function OnCloseWindow
* Event handler for the close event
*/
void OnCloseWindow( wxCloseEvent& aEvent );
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
void doCloseWindow() override;
// The Tool Framework initalization
void setupTools();

View File

@ -77,7 +77,6 @@
BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_CLOSE( FOOTPRINT_EDIT_FRAME::OnCloseWindow )
EVT_MENU( wxID_CLOSE, FOOTPRINT_EDIT_FRAME::CloseModuleEditor )
EVT_MENU( wxID_EXIT, FOOTPRINT_EDIT_FRAME::OnExitKiCad )
@ -536,7 +535,7 @@ const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents() const
}
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool FOOTPRINT_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
{
if( IsContentModified() )
{
@ -544,7 +543,7 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )
{
aEvent.Veto();
return;
return false;
}
wxString footprintName = GetBoard()->GetFirstModule()->GetFPID().GetLibItemName();
@ -557,10 +556,17 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
} ) )
{
aEvent.Veto();
return;
return false;
}
}
return true;
}
void FOOTPRINT_EDIT_FRAME::doCloseWindow()
{
// No more vetos
GetCanvas()->SetEventDispatcher( NULL );
GetCanvas()->StopDrawing();
@ -573,9 +579,6 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
Pgm().GetSettingsManager().FlushAndRelease( GetSettings() );
Clear_Pcb( false );
// Close the editor
aEvent.Skip();
}

View File

@ -89,7 +89,8 @@ public:
const BOX2I GetDocumentExtents() const override;
void OnCloseWindow( wxCloseEvent& Event ) override;
bool canCloseWindow( wxCloseEvent& Event ) override;
void doCloseWindow() override;
void CloseModuleEditor( wxCommandEvent& Event );
void OnExitKiCad( wxCommandEvent& aEvent );

View File

@ -69,7 +69,6 @@ using namespace std::placeholders;
BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
// Window events
EVT_CLOSE( FOOTPRINT_VIEWER_FRAME::OnCloseWindow )
EVT_SIZE( FOOTPRINT_VIEWER_FRAME::OnSize )
EVT_ACTIVATE( FOOTPRINT_VIEWER_FRAME::OnActivate )
@ -334,7 +333,7 @@ void FOOTPRINT_VIEWER_FRAME::setupUIConditions()
}
void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event )
void FOOTPRINT_VIEWER_FRAME::doCloseWindow()
{
// A workaround to avoid flicker, in modal mode when modview frame is destroyed,
// when the aui toolbar is not docked (i.e. shown in a miniframe)

View File

@ -121,7 +121,7 @@ private:
*/
void UpdateTitle();
void OnCloseWindow( wxCloseEvent& Event ) override;
void doCloseWindow() override;
void CloseFootprintViewer( wxCommandEvent& event );
void OnExitKiCad( wxCommandEvent& event );

View File

@ -58,7 +58,6 @@
BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
// Window events
EVT_CLOSE( FOOTPRINT_WIZARD_FRAME::OnCloseWindow )
EVT_SIZE( FOOTPRINT_WIZARD_FRAME::OnSize )
EVT_ACTIVATE( FOOTPRINT_WIZARD_FRAME::OnActivate )
@ -248,7 +247,7 @@ FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME()
}
void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event )
void FOOTPRINT_WIZARD_FRAME::doCloseWindow()
{
SaveSettings( config() );

View File

@ -180,7 +180,7 @@ private:
void DisplayWizardInfos();
void OnCloseWindow( wxCloseEvent& Event ) override;
void doCloseWindow() override;
void ReCreateHToolbar() override;
void ReCreateVToolbar() override;
void ClickOnPageList( wxCommandEvent& event );

View File

@ -63,7 +63,7 @@ PCB_BASE_EDIT_FRAME::~PCB_BASE_EDIT_FRAME()
}
void PCB_BASE_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
void PCB_BASE_EDIT_FRAME::doCloseWindow()
{
SETTINGS_MANAGER* mgr = GetSettingsManager();

View File

@ -47,7 +47,7 @@ public:
bool TryBefore( wxEvent& aEvent ) override;
void OnCloseWindow( wxCloseEvent& aEvent ) override;
void doCloseWindow() override;
/**
* If a library name is given, creates a new footprint library in the project folder

View File

@ -109,7 +109,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_CHOICE( ID_ON_ZOOM_SELECT, PCB_EDIT_FRAME::OnSelectZoom )
EVT_CHOICE( ID_ON_GRID_SELECT, PCB_EDIT_FRAME::OnSelectGrid )
EVT_CLOSE( PCB_EDIT_FRAME::OnCloseWindow )
EVT_SIZE( PCB_EDIT_FRAME::OnSize )
EVT_TOOL( ID_MENU_RECOVER_BOARD_AUTOSAVE, PCB_EDIT_FRAME::Files_io )
@ -789,20 +789,19 @@ void PCB_EDIT_FRAME::ResolveDRCExclusions()
}
void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
{
// Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& IsContentModified() )
&& IsContentModified() )
{
aEvent.Veto();
return;
return false;
}
// First close the DRC dialog. For some reason, if the board editor frame is destroyed
// when the DRC dialog currently open, Pcbnew crashes, at least on Windows.
DIALOG_DRC* open_dlg = static_cast<DIALOG_DRC*>(
wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME ) );
wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME ) );
if( open_dlg )
open_dlg->Close( true );
@ -813,15 +812,17 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
wxString msg = _( "Save changes to \"%s\" before closing?" );
if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
[&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
[&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
{
aEvent.Veto();
return;
return false;
}
}
m_shuttingDown = true;
return true;
}
void PCB_EDIT_FRAME::doCloseWindow()
{
// On Windows 7 / 32 bits, on OpenGL mode only, Pcbnew crashes
// when closing this frame if a footprint was selected, and the footprint editor called
// to edit this footprint, and when closing pcbnew if this footprint is still selected
@ -873,10 +874,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
// want any paint event
Show( false );
PCB_BASE_EDIT_FRAME::OnCloseWindow( aEvent );
// Close frame:
aEvent.Skip();
PCB_BASE_EDIT_FRAME::doCloseWindow();
}

View File

@ -240,6 +240,9 @@ protected:
*/
bool fixEagleNets( const std::unordered_map<wxString, wxString>& aRemap );
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
void doCloseWindow() override;
// protected so that PCB::IFACE::CreateWindow() is the only factory.
PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
@ -422,7 +425,6 @@ public:
*/
void ResolveDRCExclusions();
void OnCloseWindow( wxCloseEvent& Event ) override;
void Process_Special_Functions( wxCommandEvent& event );
void Tracks_and_Vias_Size_Event( wxCommandEvent& event );

View File

@ -144,6 +144,10 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
if( GetBoard()->GetDesignSettings().IsLayerEnabled( localSettings.m_ActiveLayer ) )
SetActiveLayer( localSettings.m_ActiveLayer );
wxFileName fn( GetCurrentFileName() );
fn.MakeRelativeTo( Prj().GetProjectPath() );
LoadWindowState( fn.GetFullPath() );
return true;
}