From 53f6bf29c7562d675593501441d2cc5165263795 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 15 Jun 2016 15:00:41 -0400 Subject: [PATCH] Fix bug: DRC report to File crashes Pcbnew, if the file cannot be created (for instance if the CWD is not writable, or if the path does not exist) Fix also an other issue: if the file path is not entered, the file is now created in the current project directory. --- pcbnew/dialogs/dialog_drc.cpp | 129 +++++++++++++++++++---------- pcbnew/dialogs/dialog_drc.h | 21 ++++- pcbnew/dialogs/dialog_drc_base.cpp | 2 +- pcbnew/dialogs/dialog_drc_base.fbp | 6 +- pcbnew/dialogs/dialog_drc_base.h | 8 +- pcbnew/drc.cpp | 6 +- 6 files changed, 113 insertions(+), 59 deletions(-) diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index ae30c05e26..6e915b6fd7 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -5,7 +5,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr + * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. * @@ -28,6 +28,9 @@ */ #include +#include +#include +#include #include #include #include @@ -47,6 +50,7 @@ DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* parent ) : m_BrdSettings = m_Parent->GetBoard()->GetDesignSettings(); InitValues(); + if( GetSizer() ) { GetSizer()->SetSizeHints( this ); @@ -109,13 +113,13 @@ void DIALOG_DRC_CONTROL::InitValues() DisplayDRCValues(); - Layout(); // adding the units above expanded Clearance text, now resize. - // Set the initial "enabled" status of the browse button and the text // field for report name wxCommandEvent junk; OnReportCheckBoxClicked( junk ); + Layout(); // adding the units above expanded Clearance text, now resize. + SetFocus(); } @@ -131,6 +135,20 @@ void DIALOG_DRC_CONTROL::SetDrcParmeters( ) } +void DIALOG_DRC_CONTROL::SetRptSettings( bool aEnable, const wxString& aFileName ) +{ + m_RptFilenameCtrl->Enable( aEnable ); + m_BrowseButton->Enable( aEnable ); + m_CreateRptCtrl->SetValue( aEnable ); + m_RptFilenameCtrl->SetValue( aFileName ); +} + +void DIALOG_DRC_CONTROL::GetRptSettings( bool* aEnable, wxString& aFileName ) +{ + *aEnable = m_CreateRptCtrl->GetValue(); + aFileName = m_RptFilenameCtrl->GetValue(); +} + void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event ) { wxString reportName; @@ -141,13 +159,13 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event ) if( reportName.IsEmpty() ) { - wxCommandEvent junk; - OnButtonBrowseRptFileClick( junk ); + wxCommandEvent dummy; + OnButtonBrowseRptFileClick( dummy ); } - - reportName = m_RptFilenameCtrl->GetValue(); } + reportName = makeValidFileNameReport(); + SetDrcParmeters(); m_tester->SetSettings( true, // Pad to pad DRC test enabled true, // unconnected pdas DRC test enabled @@ -170,17 +188,18 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event ) // Generate the report if( !reportName.IsEmpty() ) { - FILE* fp = wxFopen( reportName, wxT( "w" ) ); - writeReport( fp ); - fclose( fp ); + if( writeReport( reportName ) ) + { + wxString msg; + msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) ); - wxString msg; - msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) ); - - wxString caption( _( "Disk File Report Completed" ) ); - wxMessageDialog popupWindow( this, msg, caption ); - - popupWindow.ShowModal(); + wxString caption( _( "Disk File Report Completed" ) ); + wxMessageDialog popupWindow( this, msg, caption ); + popupWindow.ShowModal(); + } + else + DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "), + GetChars( reportName ) ) ); } wxEndBusyCursor(); @@ -209,10 +228,10 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event ) wxCommandEvent junk; OnButtonBrowseRptFileClick( junk ); } - - reportName = m_RptFilenameCtrl->GetValue(); } + reportName = makeValidFileNameReport(); + SetDrcParmeters(); m_tester->SetSettings( true, // Pad to pad DRC test enabled @@ -233,15 +252,17 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event ) // Generate the report if( !reportName.IsEmpty() ) { - FILE* fp = wxFopen( reportName, wxT( "w" ) ); - writeReport( fp ); - fclose( fp ); - - wxString msg; - msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) ); - wxString caption( _( "Disk File Report Completed" ) ); - wxMessageDialog popupWindow( this, msg, caption ); - popupWindow.ShowModal(); + if( writeReport( reportName ) ) + { + wxString msg; + msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) ); + wxString caption( _( "Disk File Report Completed" ) ); + wxMessageDialog popupWindow( this, msg, caption ); + popupWindow.ShowModal(); + } + else + DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "), + GetChars( reportName ) ) ); } wxEndBusyCursor(); @@ -299,16 +320,8 @@ void DIALOG_DRC_CONTROL::OnCancelClick( wxCommandEvent& event ) void DIALOG_DRC_CONTROL::OnReportCheckBoxClicked( wxCommandEvent& event ) { - if( m_CreateRptCtrl->IsChecked() ) - { - m_RptFilenameCtrl->Enable( true ); - m_BrowseButton->Enable( true ); - } - else - { - m_RptFilenameCtrl->Enable( false ); - m_BrowseButton->Enable( false ); - } + m_RptFilenameCtrl->Enable( m_CreateRptCtrl->IsChecked() ); + m_BrowseButton->Enable( m_CreateRptCtrl->IsChecked() ); } @@ -325,14 +338,9 @@ void DIALOG_DRC_CONTROL::OnLeftDClickClearance( wxMouseEvent& event ) // Find the selected MARKER in the PCB, position cursor there. // Then close the dialog. const DRC_ITEM* item = m_ClearanceListBox->GetItem( selection ); + if( item ) { - /* - * // after the goto, process a button OK command later. - * wxCommandEvent cmd( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ); - * ::wxPostEvent( GetEventHandler(), cmd ); - */ - m_Parent->CursorGoto( item->GetPointA() ); m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) ); @@ -549,8 +557,35 @@ void DIALOG_DRC_CONTROL::DelDRCMarkers() } -void DIALOG_DRC_CONTROL::writeReport( FILE* fp ) +const wxString DIALOG_DRC_CONTROL::makeValidFileNameReport() { + wxFileName fn = m_RptFilenameCtrl->GetValue(); + + if( !fn.HasExt() ) + { + fn.SetExt( ReportFileExtension ); + m_RptFilenameCtrl->SetValue( fn.GetFullPath() ); + } + + // Ensure it is an absolute filename. if it is given relative + // it will be made relative to the project + if( !fn.IsAbsolute() ) + { + wxString prj_path = Prj().GetProjectPath(); + fn.MakeAbsolute( prj_path ); + } + + return fn.GetFullPath(); +} + + +bool DIALOG_DRC_CONTROL::writeReport( const wxString& aFullFileName ) +{ + FILE* fp = wxFopen( aFullFileName, wxT( "w" ) ); + + if( fp == NULL ) + return false; + int count; fprintf( fp, "** Drc report for %s **\n", @@ -575,6 +610,10 @@ void DIALOG_DRC_CONTROL::writeReport( FILE* fp ) fprintf( fp, "%s", TO_UTF8( m_UnconnectedListBox->GetItem( i )->ShowReport() ) ); fprintf( fp, "\n** End of Report **\n" ); + + fclose( fp ); + + return true; } diff --git a/pcbnew/dialogs/dialog_drc.h b/pcbnew/dialogs/dialog_drc.h index 3efd0a96d9..d370792282 100644 --- a/pcbnew/dialogs/dialog_drc.h +++ b/pcbnew/dialogs/dialog_drc.h @@ -60,14 +60,31 @@ public: DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* parent ); ~DIALOG_DRC_CONTROL(){}; + /** + * Enable/disable the report file creation + * @param aEnbale = true to ask for creation + * @param aFileName = the filename or the report file + */ + void SetRptSettings( bool aEnable, const wxString& aFileName ); + + void GetRptSettings( bool* aEnable, wxString& aFileName ); + private: /** * Function writeReport * outputs the MARKER items and unconnecte DRC_ITEMs with commentary to an * open text file. - * @param fpOut The text file to write the report to. + * @param aFullFileName The text filename to write the report to. + * @return true if OK, false on error */ - void writeReport( FILE* fpOut ); + bool writeReport( const wxString& aFullFileName ); + + /** + * filenames can be entered by name. + * @return a good report filename (with .rpt extension) (a full filename) + * from m_CreateRptCtrl + */ + const wxString makeValidFileNameReport(); void InitValues( ); diff --git a/pcbnew/dialogs/dialog_drc_base.cpp b/pcbnew/dialogs/dialog_drc_base.cpp index b9c21b978d..03d63cf710 100644 --- a/pcbnew/dialogs/dialog_drc_base.cpp +++ b/pcbnew/dialogs/dialog_drc_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Mar 28 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! diff --git a/pcbnew/dialogs/dialog_drc_base.fbp b/pcbnew/dialogs/dialog_drc_base.fbp index 6f7dc9f16f..bf7590bd57 100644 --- a/pcbnew/dialogs/dialog_drc_base.fbp +++ b/pcbnew/dialogs/dialog_drc_base.fbp @@ -1155,7 +1155,7 @@ 1 - public + protected 1 Resizable @@ -1242,7 +1242,7 @@ 1 - public + protected 1 Resizable @@ -2315,7 +2315,7 @@ 1 - protected + private 1 Resizable diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h index 9507c4644a..8b24392bcc 100644 --- a/pcbnew/dialogs/dialog_drc_base.h +++ b/pcbnew/dialogs/dialog_drc_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Mar 28 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -51,6 +51,7 @@ class DRCLISTBOX; class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM { private: + wxPanel* m_panelUnconnectedBox; protected: wxStaticText* m_ClearanceTitle; @@ -60,6 +61,8 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxStaticText* m_ViaMinUnit; wxStaticText* m_MicroViaMinTitle; wxStaticText* m_MicroViaMinUnit; + wxCheckBox* m_CreateRptCtrl; + wxTextCtrl* m_RptFilenameCtrl; wxButton* m_BrowseButton; wxStaticText* m_staticText6; wxTextCtrl* m_Messages; @@ -70,7 +73,6 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxStaticText* m_staticTextErrMsg; wxNotebook* m_Notebook; wxPanel* m_panelClearanceListBox; - wxPanel* m_panelUnconnectedBox; wxStdDialogButtonSizer* m_sdbSizer1; wxButton* m_sdbSizer1OK; wxButton* m_sdbSizer1Cancel; @@ -99,8 +101,6 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxTextCtrl* m_SetTrackMinWidthCtrl; wxTextCtrl* m_SetViaMinSizeCtrl; wxTextCtrl* m_SetMicroViakMinSizeCtrl; - wxCheckBox* m_CreateRptCtrl; - wxTextCtrl* m_RptFilenameCtrl; DRCLISTBOX* m_ClearanceListBox; DRCLISTBOX* m_UnconnectedListBox; diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 06a4950460..31ebc50457 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -61,8 +61,7 @@ void DRC::ShowDialog() m_drcDialog = new DIALOG_DRC_CONTROL( this, m_mainWindow ); updatePointers(); - m_drcDialog->m_CreateRptCtrl->SetValue( m_doCreateRptFile ); - m_drcDialog->m_RptFilenameCtrl->SetValue( m_rptFilename ); + m_drcDialog->SetRptSettings( m_doCreateRptFile, m_rptFilename); } else updatePointers(); @@ -78,8 +77,7 @@ void DRC::DestroyDialog( int aReason ) if( aReason == wxID_OK ) { // if user clicked OK, save his choices in this DRC object. - m_doCreateRptFile = m_drcDialog->m_CreateRptCtrl->GetValue(); - m_rptFilename = m_drcDialog->m_RptFilenameCtrl->GetValue(); + m_drcDialog->GetRptSettings( &m_doCreateRptFile, m_rptFilename); } m_drcDialog->Destroy();