Fix button order and genralize Exit dialog so it can be shared more.

This also fixes a bunch of bugs where an error during save would
still close the window (rather than cancelling the close action).

Fixes: lp:1785034
* https://bugs.launchpad.net/kicad/+bug/1785034
This commit is contained in:
Jeff Young 2018-08-02 00:06:12 +01:00
parent c655bffac1
commit d8d4f75fa1
18 changed files with 385 additions and 390 deletions

View File

@ -156,18 +156,20 @@ long KIDIALOG::getStyle( KD_TYPE aType )
class DIALOG_EXIT: public DIALOG_EXIT_BASE
{
public:
DIALOG_EXIT( wxWindow *aParent, const wxString& aMessage ) :
DIALOG_EXIT( wxWindow *aParent, const wxString& aWarning, const wxString& aMessage,
const wxString& aOKLabel, const wxString& aCancelLabel ) :
DIALOG_EXIT_BASE( aParent )
{
m_bitmap->SetBitmap( KiBitmap( dialog_warning_xpm ) );
m_TextInfo->SetLabel( aWarning );
m_staticText2->SetLabel( aMessage );
if( !aMessage.IsEmpty() )
m_TextInfo->SetLabel( aMessage );
// Caller must eanble these if desired
m_ApplyToAllOpt->Show( false );
m_DiscardButton->Show( false );
m_ApplyToAllOpt->Show( false ); // Caller must enable this
m_sdbSizer1OK->SetLabel( _( "Save and Exit" ) );
m_sdbSizer1Apply->SetLabel( _( "Discard Changes" ) );
m_sdbSizer1OK->SetLabel( aOKLabel );
m_sdbSizer1Cancel->SetLabel( aCancelLabel );
m_sdbSizer1OK->SetDefault();
m_sdbSizer1->Layout();
@ -177,14 +179,36 @@ public:
};
private:
void OnSaveAndExit( wxCommandEvent& event ) override { EndModal( wxID_YES ); }
void OnExitNoSave( wxCommandEvent& event ) override { EndModal( wxID_NO ); }
void OnSave( wxCommandEvent& event ) override { EndModal( wxID_YES ); }
void OnDiscard( wxCommandEvent& event ) override { EndModal( wxID_NO ); }
};
int DisplayExitDialog( wxWindow* parent, const wxString& aMessage, bool* aApplyToAll )
int UnsavedChangesDialog( wxWindow* parent, const wxString& aMessage, bool* aApplyToAll )
{
DIALOG_EXIT dlg( parent, aMessage );
DIALOG_EXIT dlg( parent, aMessage,
_( "If you don't save, all your changes will be permanently lost." ),
_( "Save" ), _( "Cancel" ) );
if( aApplyToAll )
dlg.m_ApplyToAllOpt->Show( true );
dlg.m_DiscardButton->Show( true );
int ret = dlg.ShowModal();
if( aApplyToAll )
*aApplyToAll = dlg.m_ApplyToAllOpt->GetValue();
// Returns wxID_YES, wxID_NO, or wxID_CANCEL
return ret;
}
int YesOrCancelDialog( wxWindow* aParent, const wxString& aWarning, const wxString& aMessage,
const wxString& aOKLabel, const wxString& aCancelLabel, bool* aApplyToAll )
{
DIALOG_EXIT dlg( aParent, aWarning, aMessage, aOKLabel, aCancelLabel );
if( aApplyToAll )
dlg.m_ApplyToAllOpt->Show( true );
@ -257,48 +281,6 @@ bool IsOK( wxWindow* aParent, const wxString& aMessage )
}
class DIALOG_YES_NO_CANCEL : public DIALOG_EXIT
{
public:
DIALOG_YES_NO_CANCEL( wxWindow *aParent,
const wxString& aPrimaryMessage,
const wxString& aSecondaryMessage = wxEmptyString,
const wxString& aYesButtonText = wxEmptyString,
const wxString& aNoButtonText = wxEmptyString,
const wxString& aCancelButtonText = wxEmptyString ) :
DIALOG_EXIT( aParent, aPrimaryMessage )
{
if( aSecondaryMessage.IsEmpty() )
m_staticText2->Hide();
else
m_staticText2->SetLabel( aSecondaryMessage );
m_sdbSizer1OK->SetLabel( aYesButtonText.IsEmpty() ? wxGetStockLabel( wxID_YES ) :
aYesButtonText );
m_sdbSizer1Apply->SetLabel( aNoButtonText.IsEmpty() ? wxGetStockLabel( wxID_NO ) :
aNoButtonText );
m_sdbSizer1Cancel->SetLabel( aCancelButtonText.IsEmpty() ? wxGetStockLabel( wxID_CANCEL ) :
aCancelButtonText );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
};
};
int YesNoCancelDialog( wxWindow* aParent,
const wxString& aPrimaryMessage,
const wxString& aSecondaryMessage,
const wxString& aYesButtonText,
const wxString& aNoButtonText,
const wxString& aCancelButtonText )
{
DIALOG_YES_NO_CANCEL dlg( aParent, aPrimaryMessage, aSecondaryMessage,
aYesButtonText, aNoButtonText, aCancelButtonText );
return dlg.ShowModal();
}
int SelectSingleOption( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage, const wxArrayString& aOptions )
{
wxSingleChoiceDialog dlg( aParent, aMessage, aTitle, aOptions );

View File

@ -19,19 +19,13 @@ DIALOG_EXIT_BASE::DIALOG_EXIT_BASE( wxWindow* parent, wxWindowID id, const wxStr
wxBoxSizer* bSizerUpper;
bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerBitmap;
bSizerBitmap = new wxBoxSizer( wxVERTICAL );
m_bitmap = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerBitmap->Add( m_bitmap, 0, wxALL, 5 );
bSizerUpper->Add( bSizerBitmap, 0, 0, 5 );
bSizerUpper->Add( m_bitmap, 0, wxALL, 5 );
wxBoxSizer* bSizerMessages;
bSizerMessages = new wxBoxSizer( wxVERTICAL );
m_TextInfo = new wxStaticText( this, wxID_ANY, _("Save the changes before closing?"), wxDefaultPosition, wxDefaultSize, 0 );
m_TextInfo = new wxStaticText( this, wxID_ANY, _("Save changes?"), wxDefaultPosition, wxDefaultSize, 0 );
m_TextInfo->Wrap( -1 );
m_TextInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
@ -54,18 +48,25 @@ DIALOG_EXIT_BASE::DIALOG_EXIT_BASE( wxWindow* parent, wxWindowID id, const wxStr
m_buttonSizer->SetMinSize( wxSize( 475,-1 ) );
m_ApplyToAllOpt = new wxCheckBox( this, wxID_ANY, _("Apply to all"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonSizer->Add( m_ApplyToAllOpt, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 20 );
m_buttonSizer->Add( m_ApplyToAllOpt, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 );
m_buttonSizer->Add( 0, 0, 1, wxRIGHT|wxLEFT, 10 );
m_DiscardButton = new wxButton( this, wxID_ANY, _("Discard Changes"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonSizer->Add( m_DiscardButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_buttonSizer->Add( 0, 0, 0, wxRIGHT|wxLEFT, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1OK = new wxButton( this, wxID_OK );
m_sdbSizer1->AddButton( m_sdbSizer1OK );
m_sdbSizer1Apply = new wxButton( this, wxID_APPLY );
m_sdbSizer1->AddButton( m_sdbSizer1Apply );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
m_buttonSizer->Add( m_sdbSizer1, 1, wxEXPAND|wxALL, 5 );
m_buttonSizer->Add( m_sdbSizer1, 0, wxALL, 5 );
bSizerMain->Add( m_buttonSizer, 0, wxEXPAND|wxLEFT, 10 );
@ -78,14 +79,14 @@ DIALOG_EXIT_BASE::DIALOG_EXIT_BASE( wxWindow* parent, wxWindowID id, const wxStr
this->Centre( wxBOTH );
// Connect Events
m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnExitNoSave ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnSaveAndExit ), NULL, this );
m_DiscardButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnDiscard ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnSave ), NULL, this );
}
DIALOG_EXIT_BASE::~DIALOG_EXIT_BASE()
{
// Disconnect Events
m_sdbSizer1Apply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnExitNoSave ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnSaveAndExit ), NULL, this );
m_DiscardButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnDiscard ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXIT_BASE::OnSave ), NULL, this );
}

View File

@ -102,15 +102,6 @@
<property name="name">bSizerUpper</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerBitmap</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
@ -192,8 +183,6 @@
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
@ -235,7 +224,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Save the changes before closing?</property>
<property name="label">Save changes?</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -464,8 +453,8 @@
<property name="orient">wxHORIZONTAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<property name="border">20</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
@ -552,11 +541,119 @@
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="border">10</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" 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="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</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">Discard Changes</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_DiscardButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</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"></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>
<event name="OnButtonClick">OnDiscard</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">1</property>
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
@ -567,12 +664,12 @@
<property name="minimum_size"></property>
<property name="name">m_sdbSizer1</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick">OnExitNoSave</event>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick">OnSaveAndExit</event>
<event name="OnOKButtonClick">OnSave</event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>

View File

@ -21,8 +21,8 @@
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/checkbox.h>
#include <wx/button.h>
@ -46,16 +46,16 @@ class DIALOG_EXIT_BASE : public DIALOG_SHIM
wxBoxSizer* m_buttonSizer;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Apply;
wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class
virtual void OnExitNoSave( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveAndExit( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDiscard( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSave( wxCommandEvent& event ) { event.Skip(); }
public:
wxCheckBox* m_ApplyToAllOpt;
wxButton* m_DiscardButton;
DIALOG_EXIT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_EXIT_BASE();

View File

@ -271,10 +271,9 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
{
if( m_modified )
{
wxString msg = _( "Component to Footprint links modified.\nSave before exit?" );
int ii = DisplayExitDialog( this, msg );
wxString msg = _( "Symbol to Footprint links have been modified.\nSave before exit?" );
switch( ii )
switch( UnsavedChangesDialog( this, msg ) )
{
case wxID_CANCEL:
Event.Veto();

View File

@ -138,8 +138,7 @@ std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aPart )
case SCH_FIELD_T:
case LIB_FIELD_T:
if( aPart )
return StrPrintf( "$PART: %s",
TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
break;
case SCH_COMPONENT_T:
@ -233,10 +232,8 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
break;
case MAIL_SCH_PCB_UPDATE_REQUEST:
{
doUpdatePcb( payload );
break;
}
case MAIL_BACKANNOTATE_FOOTPRINTS:
try
@ -279,13 +276,8 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
break;
case MAIL_SCH_SAVE:
{
wxCommandEvent dummyEvent;
OnSaveProject( dummyEvent );
if( !isAutoSaveRequired() ) // proxy for save completed
if( SaveProject() )
Kiway().ExpressMail( FRAME_CVPCB, MAIL_STATUS, _( "Schematic saved" ).ToStdString() );
}
break;
default:

View File

@ -962,10 +962,7 @@ void DIALOG_FIELDS_EDITOR_GLOBAL::OnSizeFieldList( wxSizeEvent& event )
void DIALOG_FIELDS_EDITOR_GLOBAL::OnSaveAndContinue( wxCommandEvent& aEvent )
{
if( TransferDataFromWindow() )
{
wxCommandEvent dummyEvent;
m_parent->OnSaveProject( dummyEvent );
}
m_parent->SaveProject();
}
@ -982,7 +979,7 @@ void DIALOG_FIELDS_EDITOR_GLOBAL::OnClose( wxCloseEvent& event )
if( m_dataModel->IsEdited() )
{
switch( DisplayExitDialog( this, wxEmptyString ) )
switch( UnsavedChangesDialog( this, wxEmptyString ) )
{
case wxID_CANCEL:
event.Veto();

View File

@ -337,7 +337,10 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
m_lastBrowseDir = dlg.GetDirectory();
const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
bool skipRemainingDuplicates = false;
bool addDuplicates = false;
bool applyToAll = false;
wxString warning = _( "Warning: Duplicate Nickname" );
wxString msg = _( "A library nicknamed \"%s\" already exists." );
wxArrayString files;
dlg.GetFilenames( files );
@ -346,29 +349,21 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
wxString filePath = dlg.GetDirectory() + wxFileName::GetPathSeparator() + file;
wxFileName fn( filePath );
wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), LIB_ID::ID_SCH );
bool doAdd = true;
if( cur_model()->ContainsNickname( nickname ) )
{
if( skipRemainingDuplicates )
continue;
int ret = YesNoCancelDialog( this,
_( "Warning: Duplicate Nickname" ),
wxString::Format( _( "A library nicknamed \"%s\" already exists." ), nickname ),
_( "Skip" ),
_( "Skip All Remaining Duplicates" ),
_( "Add Anyway" ) );
if( ret == wxID_YES )
continue;
else if ( ret == wxID_NO )
if( !applyToAll )
{
skipRemainingDuplicates = true;
continue;
}
int ret = YesOrCancelDialog( this, warning, wxString::Format( msg, nickname ),
_( "Skip" ), _( "Add Anyway" ), &applyToAll );
addDuplicates = (ret == wxID_CANCEL );
}
if( m_cur_grid->AppendRows( 1 ) )
doAdd = addDuplicates;
}
if( doAdd && m_cur_grid->AppendRows( 1 ) )
{
int last_row = m_cur_grid->GetNumberRows() - 1;

View File

@ -73,8 +73,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
if( aSaveUnderNewName )
{
wxFileDialog dlg( this, _( "Schematic Files" ),
wxPathOnly( Prj().GetProjectFullName() ),
wxFileDialog dlg( this, _( "Schematic Files" ), wxPathOnly( Prj().GetProjectFullName() ),
schematicFileName.GetFullName(), SchematicFileWildcard(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
@ -203,15 +202,12 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
wxString fullFileName( aFileSet[0] );
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
wxT( "bug in single_top.cpp or project manager." ) );
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
if( !LockFile( fullFileName ) )
{
wxString msg = wxString::Format( _(
"Schematic file \"%s\" is already open." ),
GetChars( fullFileName )
);
wxString msg = wxString::Format( _( "Schematic file \"%s\" is already open." ),
fullFileName );
DisplayError( this, msg );
return false;
}
@ -228,10 +224,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( is_new && !( aCtl & KICTL_CREATE ) )
{
// notify user that fullFileName does not exist, ask if user wants to create it.
wxString ask = wxString::Format( _(
"Schematic \"%s\" does not exist. Do you wish to create it?" ),
GetChars( fullFileName )
);
wxString ask = wxString::Format( _( "Schematic \"%s\" does not exist. Do you wish to create it?" ),
fullFileName );
if( !IsOK( this, ask ) )
return false;
}
@ -384,7 +378,6 @@ bool SCH_EDIT_FRAME::AppendSchematic()
{
wxString msg;
wxString fullFileName;
SCH_SCREEN* screen = GetScreen();
if( !screen )
@ -396,9 +389,8 @@ bool SCH_EDIT_FRAME::AppendSchematic()
// open file chooser dialog
wxString path = wxPathOnly( Prj().GetProjectFullName() );
wxFileDialog dlg( this, _( "Append Schematic" ), path,
wxEmptyString, SchematicFileWildcard(),
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
wxFileDialog dlg( this, _( "Append Schematic" ), path, wxEmptyString,
SchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return false;
@ -536,7 +528,6 @@ bool SCH_EDIT_FRAME::AppendSchematic()
// Don't expand environment variable because KIPRJMOD will not be correct
// for a different project.
wxString uri = table.GetFullURI( libName, false );
wxFileName newLib;
if( uri.Contains( "${KIPRJMOD}" ) )
@ -569,15 +560,10 @@ bool SCH_EDIT_FRAME::AppendSchematic()
// Rename the imported symbol library if it already exists.
while( Prj().SchSymbolLibTable()->HasLibrary( newLibName ) )
{
newLibName = wxString::Format( "%s%d", libName, libNameCnt );
}
SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( newLibName,
uri,
row->GetType(),
row->GetOptions(),
row->GetDescr() );
auto newRow = new SYMBOL_LIB_TABLE_ROW( newLibName, uri, row->GetType(),
row->GetOptions(), row->GetDescr() );
Prj().SchSymbolLibTable()->InsertRow( newRow );
if( libName != newLibName )
@ -653,7 +639,7 @@ void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event )
"Do you want to save the current document before proceeding?" );
if( IsOK( this, msg ) )
OnSaveProject( event );
SaveProject();
}
AppendSchematic();
@ -669,9 +655,8 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
bool setProject = Prj().GetProjectFullName().IsEmpty();
wxString path = wxPathOnly( Prj().GetProjectFullName() );
wxFileDialog dlg( this, _( "Import Schematic" ), path,
wxEmptyString, EagleSchematicFileWildcard(),
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString,
EagleSchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return;
@ -689,29 +674,35 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent )
{
SaveProject();
}
bool SCH_EDIT_FRAME::SaveProject()
{
SCH_SCREEN* screen;
SCH_SCREENS screenList;
bool success = true;
// I want to see it in the debugger, show me the string! Can't do that with wxFileName.
wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() );
wxFileName fn = fileName;
if( !fn.IsDirWritable() )
{
wxString msg = wxString::Format( _( "Directory \"%s\" is not writable." ), fn.GetPath() );
DisplayError( this, msg );
return;
return false;
}
for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
SaveEEFile( screen );
success &= SaveEEFile( screen );
CreateArchiveLibraryCacheFile();
UpdateTitle();
return success;
}
@ -762,7 +753,6 @@ bool SCH_EDIT_FRAME::doAutoSave()
bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
{
wxString fullFileName( aFileName );
wxString projectpath;
wxFileName newfilename;
SCH_SHEET_LIST sheetList( g_RootSheet );
@ -771,13 +761,13 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
{
case SCH_IO_MGR::SCH_EAGLE:
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
wxASSERT_MSG( wxFileName( aFileName ).IsAbsolute(),
wxT( "Import eagle schematic caller didn't send full filename" ) );
if( !LockFile( fullFileName ) )
if( !LockFile( aFileName ) )
{
wxString msg = wxString::Format( _( "Schematic file \"%s\" is already open." ),
GetChars( fullFileName ) );
aFileName );
DisplayError( this, msg );
return false;
}
@ -787,7 +777,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
delete g_RootSheet;
g_RootSheet = nullptr;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) );
g_RootSheet = pi->Load( fullFileName, &Kiway() );
g_RootSheet = pi->Load( aFileName, &Kiway() );
// Eagle sheets do not use a worksheet frame by default, so set it to an empty one
@ -819,7 +809,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
GetScreen()->SetModify();
SaveProjectSettings( false );
UpdateFileHistory( fullFileName );
UpdateFileHistory( aFileName );
SCH_SCREENS schematic;
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
@ -861,7 +851,6 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
}
}
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
// Only perform the dangling end test on root sheet.
GetScreen()->TestDanglingEnds();
@ -880,11 +869,10 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
Zoom_Automatique( false );
wxString msg;
msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
fullFileName, ioe.What() );
msg.Printf( _( "Error loading schematic \"%s\".\n%s" ), aFileName, ioe.What() );
DisplayError( this, msg );
msg.Printf( _( "Failed to load \"%s\"" ), fullFileName );
msg.Printf( _( "Failed to load \"%s\"" ), aFileName );
AppendMsgPanel( wxEmptyString, msg, CYAN );
return false;
@ -895,8 +883,6 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
default:
return false;
}
return false;
}
@ -909,25 +895,15 @@ bool SCH_EDIT_FRAME::AskToSaveChanges()
{
if( screen->IsModify() )
{
int response = YesNoCancelDialog( m_parent, _(
"The current schematic has been modified. Do you wish to save the changes?" ),
wxEmptyString,
_( "Save and Load" ),
_( "Load Without Saving" )
);
wxString msg = _( "The current schematic has been modified. Save changes?" );
if( response == wxID_CANCEL )
switch( UnsavedChangesDialog( this, msg ) )
{
return false;
default:
case wxID_CANCEL: return false;
case wxID_NO: return true;
case wxID_YES: return SaveProject();
}
else if( response == wxID_YES )
{
wxCommandEvent dummy;
OnSaveProject( dummy );
}
// else wxID_NO, so do not save
break;
}
}

View File

@ -695,7 +695,7 @@ bool LIB_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
wxString msg = wxString::Format( _( "Save changes to \"%s\" before closing?" ),
libNickname );
switch( DisplayExitDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
{
case wxID_YES: doSave = true; break;
case wxID_NO: doSave = false; break;
@ -706,9 +706,10 @@ bool LIB_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
if( doSave )
{
// If saving under existing name fails then do a Save As...
if( !saveLibrary( libNickname, false ) )
saveLibrary( libNickname, true );
// If saving under existing name fails then do a Save As..., and if that
// fails then cancel close action.
if( !saveLibrary( libNickname, false ) && !saveLibrary( libNickname, true ) )
return false;
}
}
}

View File

@ -655,26 +655,24 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
if( sheetList.IsModified() )
{
wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
wxString msg = wxString::Format( _(
"Save the changes in\n\"%s\"\nbefore closing?"),
GetChars( fileName )
);
wxString msg = _( "Save changes to\n\"%s\"\nbefore closing?" );
int ii = DisplayExitDialog( this, msg );
switch( ii )
switch( UnsavedChangesDialog( this, wxString::Format( msg, fileName ) ) )
{
case wxID_YES:
if( !SaveProject() )
{
case wxID_CANCEL:
aEvent.Veto();
return;
}
break;
case wxID_NO:
break;
case wxID_YES:
wxCommandEvent tmp( ID_SAVE_PROJECT );
OnSaveProject( tmp );
break;
case wxID_CANCEL:
aEvent.Veto();
return;
}
}

View File

@ -730,6 +730,7 @@ public:
* The component library archive name is &ltroot_name&gt-cache.lib
*/
void OnSaveProject( wxCommandEvent& aEvent );
bool SaveProject();
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override;

View File

@ -76,21 +76,16 @@ protected:
/**
* Function DisplayExitDialog
* displays a dialog with 3 buttons:
* Save and Exit
* Cancel
* Exit without save
* Function UnsavedChangesDialog
* displays a dialog with Save, Cancel and Discard Changes buttons.
*
* @param aParent = the parent window
* @param aMessage = the main message to put in dialog
* If empty, the standard message will be shown:
* Save the changes before closing?
* @param aApplyToAll = if non-null an "Apply to all" checkbox will be shown and the value
* written to the bool.
* @param aApplyToAll = if non-null an "Apply to all" checkbox will be shown and it's value
* written back to the bool.
* @return wxID_YES, wxID_CANCEL, wxID_NO.
*/
int DisplayExitDialog( wxWindow* aParent, const wxString& aMessage, bool* aApplyToAll = nullptr );
int UnsavedChangesDialog( wxWindow* aParent, const wxString& aMessage, bool* aApplyToAll = nullptr );
/**
@ -134,26 +129,21 @@ void DisplayInfoMessage( wxWindow* parent, const wxString& aMessage, const wxStr
bool IsOK( wxWindow* aParent, const wxString& aMessage );
/**
* Function YesNoCancelDialog
* displays a yes/no/cancel dialog with \a aMessage and returns the user response.
* Function YesOrCancelDialog
* displays a warning dialog with \a aMessage and returns the user response.
*
* @param aParent is the parent window. NULL can be used if the parent is the top level window.
* @param aPrimaryMessage is the message to display in the top part of the dialog box using
* a bold font.
* @param aSecondaryMessage is the message to display in the lower part of the dialog box
* using the default system UI font.
* @param aYesButtonText is the text to display in the yes button when defined.
* @param aNoButtonText is the text to display in the no button when defiend.
* @param aCancelButtonText is the text to display in the cancel button when defined.
* @param aWarning is the warning to display in the top part of the dialog box using a bold font.
* @param aMessage is the message to display in the lower part of the dialog box using the
* default system UI font.
* @param aOKLabel is the text to display in the OK button.
* @param aCancelLabel is the text to display in the cancel button.
*
* @return wxID_YES, wxID_NO, or wxID_CANCEL depending on the button the user selected.
* @return wxID_YES or wxID_CANCEL depending on the button the user selected.
*/
int YesNoCancelDialog( wxWindow* aParent,
const wxString& aPrimaryMessage,
const wxString& aSecondaryMessage,
const wxString& aYesButtonText = wxEmptyString,
const wxString& aNoButtonText = wxEmptyString,
const wxString& aCancelButtonText = wxEmptyString );
int YesOrCancelDialog( wxWindow* aParent, const wxString& aWarning, const wxString& aMessage,
const wxString& aOKLabel, const wxString& aCancelLabel,
bool* aApplyToAll = nullptr );

View File

@ -223,14 +223,11 @@ void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& Event )
wxString filename = GetCurrFileName();
if( filename.IsEmpty() )
msg = _( "Save changes in a new file before closing?" );
msg = _( "Save changes before closing?" );
else
msg.Printf( _( "Save the changes in\n\"%s\"\nbefore closing?" ),
GetChars( filename ) );
msg.Printf( _( "Save changes to\n\"%s\"\nbefore closing?" ), filename );
int ii = DisplayExitDialog( this, msg );
switch( ii )
switch( UnsavedChangesDialog( this, msg ) )
{
case wxID_CANCEL:
Event.Veto();
@ -239,16 +236,17 @@ void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& Event )
case wxID_NO:
break;
case wxID_OK:
case wxID_YES:
{
if( filename.IsEmpty() )
{
wxFileDialog openFileDialog( this, _( "Save As" ), wxEmptyString, wxEmptyString,
PageLayoutDescrFileWildcard(), wxFD_SAVE );
if(openFileDialog.ShowModal() == wxID_CANCEL )
if( openFileDialog.ShowModal() == wxID_CANCEL )
{
Event.Veto();
return;
}
filename = openFileDialog.GetPath();
}
@ -257,8 +255,10 @@ void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
msg.Printf( _( "Unable to create \"%s\"" ), GetChars( filename ) );
wxMessageBox( msg );
Event.Veto();
return;
}
}
break;
}
}

View File

@ -587,7 +587,10 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
m_lastBrowseDir = m_lastBrowseDir.BeforeLast( wxFileName::GetPathSeparator() );
const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
bool skipRemainingDuplicates = false;
bool addDuplicates = false;
bool applyToAll = false;
wxString warning = _( "Warning: Duplicate Nickname" );
wxString msg = _( "A library nicknamed \"%s\" already exists." );
wxArrayString files;
dlg.GetFilenames( files );
@ -595,29 +598,21 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{
wxFileName fn( filePath );
wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), LIB_ID::ID_PCB );
bool doAdd = true;
if( cur_model()->ContainsNickname( nickname ) )
{
if( skipRemainingDuplicates )
continue;
int ret = YesNoCancelDialog( this,
_( "Warning: Duplicate Nickname" ),
wxString::Format( _( "A library nicknamed \"%s\" already exists." ), nickname ),
_( "Skip" ),
_( "Skip All Remaining Duplicates" ),
_( "Add Anyway" ) );
if( ret == wxID_YES )
continue;
else if ( ret == wxID_NO )
if( !applyToAll )
{
skipRemainingDuplicates = true;
continue;
}
int ret = YesOrCancelDialog( this, warning, wxString::Format( msg, nickname ),
_( "Skip" ), _( "Add Anyway" ), &applyToAll );
addDuplicates = (ret == wxID_CANCEL );
}
if( m_cur_grid->AppendRows( 1 ) )
doAdd = addDuplicates;
}
if( doAdd && m_cur_grid->AppendRows( 1 ) )
{
int last_row = m_cur_grid->GetNumberRows() - 1;

View File

@ -416,35 +416,32 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
wxString fullFileName( aFileSet[0] );
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
wxT( "bug in single_top.cpp or project manager." ) );
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
if( !LockFile( fullFileName ) )
{
wxString msg = wxString::Format( _(
"PCB file \"%s\" is already open." ),
GetChars( fullFileName )
);
wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName );
DisplayError( this, msg );
return false;
}
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
{
int response = YesNoCancelDialog( this, _(
"The current board has been modified. Do you wish to save the changes?" ),
wxEmptyString,
_( "Save and Load" ),
_( "Load Without Saving" )
);
wxString msg = _( "The current PCB has been modified. Save changes?" );
if( response == wxID_CANCEL )
return false;
else if( response == wxID_YES )
SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE );
else
switch( UnsavedChangesDialog( this, msg ) )
{
// response == wxID_NO, fall thru
default:
case wxID_CANCEL:
return false;
case wxID_YES:
if( !SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ) )
return false;
break;
case wxID_NO:
break;
}
}
@ -457,10 +454,8 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( is_new && !( aCtl & KICTL_CREATE ) )
{
// notify user that fullFileName does not exist, ask if user wants to create it.
wxString ask = wxString::Format( _(
"Board \"%s\" does not exist. Do you wish to create it?" ),
GetChars( fullFileName )
);
wxString ask = wxString::Format( _( "PCB \"%s\" does not exist. Do you wish to create it?" ),
fullFileName );
if( !IsOK( this, ask ) )
return false;
}

View File

@ -517,9 +517,7 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
if( GetScreen()->IsModify() && GetBoard()->m_Modules )
{
int ii = DisplayExitDialog( this, _( "Save changes to footprint before closing?" ) );
switch( ii )
switch( UnsavedChangesDialog( this, _( "Save changes to footprint before closing?" ) ) )
{
default:
case wxID_NO:

View File

@ -630,16 +630,11 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
{
wxString msg = wxString::Format( _(
"Save the changes in\n"
"\"%s\"\n"
"before closing?" ),
GetChars( GetBoard()->GetFileName() )
);
wxString msg = _( "Save changes to\n\"%s\"\nbefore closing?" );
int ii = DisplayExitDialog( this, msg );
switch( ii )
switch( UnsavedChangesDialog( this, wxString::Format( msg, GetBoard()->GetFileName() ) ) )
{
default:
case wxID_CANCEL:
Event.Veto();
return;
@ -648,8 +643,6 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
break;
case wxID_YES:
// save the board. if the board has no name,
// the ID_SAVE_BOARD_AS will actually made
Files_io_from_id( ID_SAVE_BOARD );
break;
}
@ -684,11 +677,8 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
// Remove the auto save file on a normal close of Pcbnew.
if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )
{
wxString msg = wxString::Format( _(
"The auto save file \"%s\" could not be removed!" ),
GetChars( fn.GetFullPath() )
);
wxString msg = wxString::Format( _( "The auto save file \"%s\" could not be removed!" ),
fn.GetFullPath() );
wxMessageBox( msg, Pgm().App().GetAppName(), wxOK | wxICON_ERROR, this );
}
@ -816,12 +806,7 @@ void PCB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
double dtmp;
aCfg->Read( PlotLineWidthEntry, &dtmp, 0.1 ); // stored in mm
if( dtmp < 0.01 )
dtmp = 0.01;
if( dtmp > 5.0 )
dtmp = 5.0;
dtmp = std::max( 0.01, std::min( dtmp, 5.0 ) );
g_DrawDefaultLineThickness = Millimeter2iu( dtmp );
@ -1082,20 +1067,13 @@ void PCB_EDIT_FRAME::UpdateTitle()
wxString fileinfo;
if( fileName.IsOk() && fileName.FileExists() )
{
fileinfo = fileName.IsFileWritable() ? wxString( wxEmptyString ) : _( " [Read Only]" );
}
else
{
fileinfo = _( " [new file]" );
}
fileinfo = _( " [Unsaved]" );
wxString title;
title.Printf( _( "Pcbnew" ) + wxT( " \u2014 %s%s" ),
SetTitle( wxString::Format( _( "Pcbnew" ) + wxT( " \u2014 %s%s" ),
fileName.GetFullPath(),
fileinfo );
SetTitle( title );
fileinfo ) );
}