diff --git a/common/confirm.cpp b/common/confirm.cpp index e8ca3e25de..eb6670d9eb 100644 --- a/common/confirm.cpp +++ b/common/confirm.cpp @@ -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 ); diff --git a/common/dialogs/dialog_exit_base.cpp b/common/dialogs/dialog_exit_base.cpp index 6db15f4d31..92d0e15427 100644 --- a/common/dialogs/dialog_exit_base.cpp +++ b/common/dialogs/dialog_exit_base.cpp @@ -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 ); } diff --git a/common/dialogs/dialog_exit_base.fbp b/common/dialogs/dialog_exit_base.fbp index 65dfb776bd..72a2e4d808 100644 --- a/common/dialogs/dialog_exit_base.fbp +++ b/common/dialogs/dialog_exit_base.fbp @@ -104,94 +104,83 @@ none 5 - + wxALL 0 - + + 1 + 1 + 1 + 1 + + + + + + + Load From File; + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 - bSizerBitmap - wxVERTICAL - none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From File; - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_bitmap - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + m_bitmap + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -235,7 +224,7 @@ 0 0 wxID_ANY - Save the changes before closing? + Save changes? 0 @@ -464,8 +453,8 @@ wxHORIZONTAL protected - 20 - wxALIGN_CENTER_VERTICAL|wxRIGHT + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM 0 1 @@ -552,11 +541,119 @@ - 5 - wxEXPAND|wxALL + 10 + wxRIGHT|wxLEFT 1 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Discard Changes + + 0 + + + 0 + + 1 + m_DiscardButton + 1 + + + public + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnDiscard + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 - 1 + 0 1 0 0 @@ -567,12 +664,12 @@ m_sdbSizer1 protected - OnExitNoSave + - OnSaveAndExit + OnSave diff --git a/common/dialogs/dialog_exit_base.h b/common/dialogs/dialog_exit_base.h index 3808928aab..6c5618dd4b 100644 --- a/common/dialogs/dialog_exit_base.h +++ b/common/dialogs/dialog_exit_base.h @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -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(); diff --git a/cvpcb/cvpcb_mainframe.cpp b/cvpcb/cvpcb_mainframe.cpp index 3c1bb94b3f..e56b973c99 100644 --- a/cvpcb/cvpcb_mainframe.cpp +++ b/cvpcb/cvpcb_mainframe.cpp @@ -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(); diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index a257069f24..ce8148b1f5 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -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: diff --git a/eeschema/dialogs/dialog_fields_editor_global.cpp b/eeschema/dialogs/dialog_fields_editor_global.cpp index 25eee75820..1bf2866a5d 100644 --- a/eeschema/dialogs/dialog_fields_editor_global.cpp +++ b/eeschema/dialogs/dialog_fields_editor_global.cpp @@ -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(); diff --git a/eeschema/dialogs/panel_sym_lib_table.cpp b/eeschema/dialogs/panel_sym_lib_table.cpp index 99ae901122..b7d402c175 100644 --- a/eeschema/dialogs/panel_sym_lib_table.cpp +++ b/eeschema/dialogs/panel_sym_lib_table.cpp @@ -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 ); } + + doAdd = addDuplicates; } - if( m_cur_grid->AppendRows( 1 ) ) + if( doAdd && m_cur_grid->AppendRows( 1 ) ) { int last_row = m_cur_grid->GetNumberRows() - 1; diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index cd08aa3d89..18e4421ed7 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -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& 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& 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; } } diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp index d17d3e57d9..9489499225 100644 --- a/eeschema/libedit.cpp +++ b/eeschema/libedit.cpp @@ -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; } } } diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 434750e9e2..d0ca0e972c 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -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_CANCEL: - aEvent.Veto(); - return; + case wxID_YES: + if( !SaveProject() ) + { + 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; } } diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 538fe19a13..235bb68fc7 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -730,6 +730,7 @@ public: * The component library archive name is <root_name>-cache.lib */ void OnSaveProject( wxCommandEvent& aEvent ); + bool SaveProject(); bool OpenProjectFiles( const std::vector& aFileSet, int aCtl = 0 ) override; diff --git a/include/confirm.h b/include/confirm.h index 34e9aae1b8..f29853a9b8 100644 --- a/include/confirm.h +++ b/include/confirm.h @@ -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 ); diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 5c27f3b6d4..553a90d9f7 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -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; } } diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index bfc84cedd5..01a17684e6 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -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 ); } + + doAdd = addDuplicates; } - if( m_cur_grid->AppendRows( 1 ) ) + if( doAdd && m_cur_grid->AppendRows( 1 ) ) { int last_row = m_cur_grid->GetNumberRows() - 1; diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 8603f6a76a..9318394ecb 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -416,35 +416,32 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& 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& 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; } diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 8cb8fa0ffd..3288697f41 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -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: diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 902f9a3fde..4839aa62d1 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -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" ), - fileName.GetFullPath(), - fileinfo ); - - SetTitle( title ); + SetTitle( wxString::Format( _( "Pcbnew" ) + wxT( " \u2014 %s%s" ), + fileName.GetFullPath(), + fileinfo ) ); }