diff --git a/common/lib_tree_model_adapter.cpp b/common/lib_tree_model_adapter.cpp index 9b6c357992..50e1aef473 100644 --- a/common/lib_tree_model_adapter.cpp +++ b/common/lib_tree_model_adapter.cpp @@ -216,7 +216,8 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch ) m_widget->UnselectAll(); Cleared(); -#if defined( __LINUX__ ) + +#ifdef __WXGTK__ // The fastest method to update wxDataViewCtrl is to rebuild from // scratch by calling Cleared(). Linux requires to reassociate model to // display data, but Windows will create multiple associations. diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 8103bf075e..aab4374b82 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -230,6 +230,7 @@ set( PCBNEW_DRC_SRCS drc/drc_clearance_test_functions.cpp drc/drc_marker_factory.cpp drc/drc_provider.cpp + drc/drc_tree_model.cpp ) set( PCBNEW_NETLIST_SRCS diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 37b31d983e..dfa973de73 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -39,6 +39,7 @@ #include #include + DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) : DIALOG_DRC_CONTROL_BASE( aParent ), @@ -53,8 +54,6 @@ DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFra m_currentBoard = m_brdEditor->GetBoard(); m_BrdSettings = m_brdEditor->GetBoard()->GetDesignSettings(); - m_BrowseButton->SetBitmap( KiBitmap( folder_xpm ) ); - m_markerTreeModel = new DRC_TREE_MODEL( m_markerDataView ); m_markerDataView->AssociateModel( m_markerTreeModel ); @@ -73,7 +72,7 @@ DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFra m_sdbSizer1OK->SetDefault(); - InitValues(); + initValues(); FinishDialogSettings(); } @@ -92,6 +91,18 @@ DIALOG_DRC_CONTROL::~DIALOG_DRC_CONTROL() } +void DIALOG_DRC_CONTROL::SetSettings( int aSeverities ) +{ + m_severities = aSeverities; +} + + +void DIALOG_DRC_CONTROL::GetSettings( int* aSeverities ) +{ + *aSeverities = m_severities; +} + + void DIALOG_DRC_CONTROL::OnActivateDlg( wxActivateEvent& event ) { if( m_currentBoard != m_brdEditor->GetBoard() ) @@ -109,11 +120,11 @@ void DIALOG_DRC_CONTROL::OnActivateDlg( wxActivateEvent& event ) // updating data which can be modified outside the dialog (DRC parameters, units ...) // because the dialog is not modal m_BrdSettings = m_brdEditor->GetBoard()->GetDesignSettings(); - DisplayDRCValues(); + displayDRCValues(); } -void DIALOG_DRC_CONTROL::DisplayDRCValues() +void DIALOG_DRC_CONTROL::displayDRCValues() { m_trackMinWidth.SetValue( m_BrdSettings.m_TrackMinWidth ); m_viaMinSize.SetValue( m_BrdSettings.m_ViasMinSize ); @@ -121,13 +132,13 @@ void DIALOG_DRC_CONTROL::DisplayDRCValues() } -void DIALOG_DRC_CONTROL::InitValues() +void DIALOG_DRC_CONTROL::initValues() { m_markersTitleTemplate = m_Notebook->GetPageText( 0 ); m_unconnectedTitleTemplate = m_Notebook->GetPageText( 1 ); m_footprintsTitleTemplate = m_Notebook->GetPageText( 2 ); - DisplayDRCValues(); + displayDRCValues(); auto cfg = m_brdEditor->GetSettings(); @@ -141,7 +152,7 @@ void DIALOG_DRC_CONTROL::InitValues() } -void DIALOG_DRC_CONTROL::SetDRCParameters() +void DIALOG_DRC_CONTROL::setDRCParameters() { m_BrdSettings.m_TrackMinWidth = (int) m_trackMinWidth.GetValue(); m_BrdSettings.m_ViasMinSize = (int) m_viaMinSize.GetValue(); @@ -151,44 +162,19 @@ void DIALOG_DRC_CONTROL::SetDRCParameters() } -void DIALOG_DRC_CONTROL::SetRptSettings( bool aEnable, const wxString& aFileName ) +void DIALOG_DRC_CONTROL::syncCheckboxes() { - m_RptFilenameCtrl->SetValue( aFileName ); - m_CreateRptCtrl->SetValue( aEnable ); -} - - -void DIALOG_DRC_CONTROL::GetRptSettings( bool* aEnable, wxString& aFileName ) -{ - *aEnable = m_CreateRptCtrl->GetValue(); - aFileName = m_RptFilenameCtrl->GetValue(); + m_showAll->SetValue( m_severities == DRC_SHOW_ERRORS | DRC_SHOW_WARNINGS | DRC_SHOW_INFOS ); + m_showErrors->SetValue( m_severities & DRC_SHOW_ERRORS ); + m_showWarnings->SetValue( m_severities & DRC_SHOW_WARNINGS ); + m_showInfos->SetValue( m_severities & DRC_SHOW_INFOS ); } void DIALOG_DRC_CONTROL::OnRunDRCClick( wxCommandEvent& event ) { - wxString reportName, msg; - - bool make_report = m_CreateRptCtrl->IsChecked(); - - if( make_report ) // Create a rpt file - { - reportName = m_RptFilenameCtrl->GetValue(); - - if( reportName.IsEmpty() ) - { - wxCommandEvent dummy; - OnButtonBrowseRptFileClick( dummy ); - } - - if( !reportName.IsEmpty() ) - reportName = makeValidFileNameReport(); - } - - SetDRCParameters(); + setDRCParameters(); m_tester->m_doZonesTest = m_cbReportTracksToZonesErrors->GetValue(); - m_tester->m_rptFilename = reportName; - m_tester->m_doCreateRptFile = make_report; m_tester->m_refillZones = m_cbRefillZones->GetValue(); m_tester->m_reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue(); m_tester->m_testFootprints = m_cbTestFootprints->GetValue(); @@ -204,22 +190,6 @@ void DIALOG_DRC_CONTROL::OnRunDRCClick( wxCommandEvent& event ) m_tester->RunTests( m_Messages ); m_Notebook->ChangeSelection( 0 ); // display the "Problems/Markers" tab - // Generate the report - if( !reportName.IsEmpty() ) - { - if( writeReport( reportName ) ) - { - msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) ); - wxMessageDialog popupWindow( this, msg, _( "Disk File Report Completed" ) ); - popupWindow.ShowModal(); - } - else - { - msg.Printf( _( "Unable to create report file \"%s\"" ), GetChars( reportName ) ); - DisplayError( this, msg ); - } - } - wxEndBusyCursor(); RefreshBoardEditor(); @@ -271,20 +241,69 @@ void DIALOG_DRC_CONTROL::OnDRCItemDClick( wxDataViewEvent& event ) } -void DIALOG_DRC_CONTROL::OnButtonBrowseRptFileClick( wxCommandEvent& ) +void DIALOG_DRC_CONTROL::OnSeverity( wxCommandEvent& event ) { - wxFileName fn = m_brdEditor->GetBoard()->GetFileName(); - fn.SetExt( ReportFileExtension ); - wxString prj_path = Prj().GetProjectPath(); + int flag = 0; - wxFileDialog dlg( this, _( "Save DRC Report File" ), prj_path, fn.GetFullName(), + if( event.GetEventObject() == m_showAll ) + flag = DRC_SHOW_ERRORS | DRC_SHOW_WARNINGS | DRC_SHOW_INFOS; + else if( event.GetEventObject() == m_showErrors ) + flag = DRC_SHOW_ERRORS; + else if( event.GetEventObject() == m_showWarnings ) + flag = DRC_SHOW_WARNINGS; + else if( event.GetEventObject() == m_showInfos ) + flag = DRC_SHOW_INFOS; + + if( event.IsChecked() ) + m_severities |= flag; + else + m_severities &= ~flag; + + syncCheckboxes(); + + // JEY TODO: + /* + * pass the severity level to the providers... + * or create new providers with the level... + * and then + m_markerTreeModel->SetProvider( ... ); + m_unconnectedTreeModel->SetProvider( ... ); + m_footprintsTreeModel->SetProvider( ... ); + */ +} + + +void DIALOG_DRC_CONTROL::OnSaveReport( wxCommandEvent& event ) +{ + wxFileName fn( "./DRC." + ReportFileExtension ); + + wxFileDialog dlg( this, _( "Save Report to File" ), fn.GetPath(), fn.GetFullName(), ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - if( dlg.ShowModal() == wxID_CANCEL ) + if( dlg.ShowModal() != wxID_OK ) return; - m_CreateRptCtrl->SetValue( true ); - m_RptFilenameCtrl->SetValue( dlg.GetPath() ); + fn = dlg.GetPath(); + + if( fn.GetExt().IsEmpty() ) + fn.SetExt( ReportFileExtension ); + + if( !fn.IsAbsolute() ) + { + wxString prj_path = Prj().GetProjectPath(); + fn.MakeAbsolute( prj_path ); + } + + if( writeReport( fn.GetFullPath() ) ) + { + m_Messages->AppendText( wxString::Format( _( "Report file '%s' created\n" ), + fn.GetFullPath() ) ); + } + else + { + DisplayError( this, wxString::Format( _( "Unable to create report file '%s'" ), + fn.GetFullPath() ) ); + } } @@ -293,7 +312,7 @@ void DIALOG_DRC_CONTROL::OnCancelClick( wxCommandEvent& event ) m_brdEditor->FocusOnItem( nullptr ); SetReturnCode( wxID_CANCEL ); - SetDRCParameters(); + setDRCParameters(); // The dialog can be modal or not modal. // Leave the DRC caller destroy (or not) the dialog @@ -301,19 +320,6 @@ void DIALOG_DRC_CONTROL::OnCancelClick( wxCommandEvent& event ) } -void DIALOG_DRC_CONTROL::OnReportCheckBoxClicked( wxCommandEvent& event ) -{ - if( m_CreateRptCtrl->IsChecked() ) - m_RptFilenameCtrl->SetFocus(); -} - - -void DIALOG_DRC_CONTROL::OnReportFilenameEdited( wxCommandEvent& event ) -{ - m_CreateRptCtrl->SetValue( event.GetString().Length() ); -} - - void DIALOG_DRC_CONTROL::OnChangingNotebookPage( wxNotebookEvent& event ) { // Shouldn't be necessary, but is on at least OSX @@ -344,28 +350,6 @@ void DIALOG_DRC_CONTROL::DelDRCMarkers() } -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" ) ); diff --git a/pcbnew/dialogs/dialog_drc.h b/pcbnew/dialogs/dialog_drc.h index a9a2fc451a..b71199f297 100644 --- a/pcbnew/dialogs/dialog_drc.h +++ b/pcbnew/dialogs/dialog_drc.h @@ -36,19 +36,20 @@ #include #include -// forward declarations + class DRC_ITEMS_PROVIDER; class BOARD_DESIGN_SETTINGS; class DRC_TREE_MODEL; -//end forward declarations -/*! - * DrcDialog class declaration - */ +#define DRC_SHOW_ERRORS 0x0001 +#define DRC_SHOW_WARNINGS 0x0002 +#define DRC_SHOW_INFOS 0x0004 + #define DIALOG_DRC_WINDOW_NAME "DialogDrcWindowName" -class DIALOG_DRC_CONTROL: public DIALOG_DRC_CONTROL_BASE +class +DIALOG_DRC_CONTROL: public DIALOG_DRC_CONTROL_BASE { public: BOARD_DESIGN_SETTINGS m_BrdSettings; @@ -57,14 +58,8 @@ public: DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ); ~DIALOG_DRC_CONTROL(); - /** - * Enable/disable the report file creation - * @param aEnable = 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 ); + void SetSettings( int aSeverities ); + void GetSettings( int* aSeverities ); void SetMarkersProvider( DRC_ITEMS_PROVIDER* aProvider ); void SetUnconnectedProvider( DRC_ITEMS_PROVIDER* aProvider ); @@ -82,31 +77,20 @@ private: */ 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( ); - - void DisplayDRCValues( ); - - void SetDRCParameters( ); - - void OnReportCheckBoxClicked( wxCommandEvent& event ) override; - void OnReportFilenameEdited( wxCommandEvent &event ) override; - void OnButtonBrowseRptFileClick( wxCommandEvent& event ) override; - - void OnRunDRCClick( wxCommandEvent& event ) override; - - void OnDeleteAllClick( wxCommandEvent& event ) override; - void OnDeleteOneClick( wxCommandEvent& event ) override; + void initValues(); + void displayDRCValues(); + void setDRCParameters(); + void syncCheckboxes(); void OnDRCItemSelected( wxDataViewEvent& event ) override; void OnDRCItemDClick( wxDataViewEvent& event ) override; + void OnSeverity( wxCommandEvent& event ) override; + void OnSaveReport( wxCommandEvent& event ) override; + + void OnDeleteOneClick( wxCommandEvent& event ) override; + void OnDeleteAllClick( wxCommandEvent& event ) override; + void OnRunDRCClick( wxCommandEvent& event ) override; void OnCancelClick( wxCommandEvent& event ) override; /// handler for activate event, updating data which can be modified outside the dialog @@ -133,6 +117,8 @@ private: DRC_TREE_MODEL* m_markerTreeModel; DRC_TREE_MODEL* m_unconnectedTreeModel; DRC_TREE_MODEL* m_footprintsTreeModel; + + int m_severities; }; #endif // _DIALOG_DRC_H_ diff --git a/pcbnew/dialogs/dialog_drc_base.cpp b/pcbnew/dialogs/dialog_drc_base.cpp index 96b2bad282..59f92a50d5 100644 --- a/pcbnew/dialogs/dialog_drc_base.cpp +++ b/pcbnew/dialogs/dialog_drc_base.cpp @@ -108,31 +108,6 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i gbSizer1->Add( m_Messages, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxTOP|wxLEFT, 5 ); - wxFlexGridSizer* fgSizerRpt; - fgSizerRpt = new wxFlexGridSizer( 0, 3, 0, 0 ); - fgSizerRpt->AddGrowableCol( 1 ); - fgSizerRpt->SetFlexibleDirection( wxBOTH ); - fgSizerRpt->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_CreateRptCtrl = new wxCheckBox( this, ID_CHECKBOX_RPT_FILE, _("Create report file:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_CreateRptCtrl->SetToolTip( _("Enable writing report to this file") ); - - fgSizerRpt->Add( m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 10 ); - - m_RptFilenameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_RptFilenameCtrl->SetToolTip( _("Enter the report filename") ); - m_RptFilenameCtrl->SetMinSize( wxSize( 180,-1 ) ); - - fgSizerRpt->Add( m_RptFilenameCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM, 3 ); - - m_BrowseButton = new wxBitmapButton( this, ID_BUTTON_BROWSE_RPT_FILE, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); - m_BrowseButton->SetMinSize( wxSize( 30,28 ) ); - - fgSizerRpt->Add( m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL, 2 ); - - - gbSizer1->Add( fgSizerRpt, wxGBPosition( 1, 0 ), wxGBSpan( 1, 3 ), wxEXPAND|wxTOP|wxRIGHT, 7 ); - gbSizer1->AddGrowableCol( 0 ); gbSizer1->AddGrowableCol( 1 ); @@ -181,7 +156,38 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i bSizerFootprintsBox->Fit( m_panelFootprintWarnings ); m_Notebook->AddPage( m_panelFootprintWarnings, _("Footprint Warnings (%d)"), false ); - m_MainSizer->Add( m_Notebook, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 ); + m_MainSizer->Add( m_Notebook, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSeveritySizer; + bSeveritySizer = new wxBoxSizer( wxHORIZONTAL ); + + m_showLabel = new wxStaticText( this, wxID_ANY, _("Show:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_showLabel->Wrap( -1 ); + bSeveritySizer->Add( m_showLabel, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + m_showAll = new wxCheckBox( this, wxID_ANY, _("All"), wxDefaultPosition, wxDefaultSize, 0 ); + bSeveritySizer->Add( m_showAll, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_showErrors = new wxCheckBox( this, wxID_ANY, _("Errors"), wxDefaultPosition, wxDefaultSize, 0 ); + bSeveritySizer->Add( m_showErrors, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_showWarnings = new wxCheckBox( this, wxID_ANY, _("Warnings"), wxDefaultPosition, wxDefaultSize, 0 ); + bSeveritySizer->Add( m_showWarnings, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_showInfos = new wxCheckBox( this, wxID_ANY, _("Infos"), wxDefaultPosition, wxDefaultSize, 0 ); + bSeveritySizer->Add( m_showInfos, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSeveritySizer->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_saveReport = new wxButton( this, wxID_ANY, _("Save..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSeveritySizer->Add( m_saveReport, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + m_MainSizer->Add( bSeveritySizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 ); + + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + m_MainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); m_sizerButtons = new wxBoxSizer( wxHORIZONTAL ); @@ -210,9 +216,6 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i // Connect Events this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_CONTROL_BASE::OnActivateDlg ) ); - m_CreateRptCtrl->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportCheckBoxClicked ), NULL, this ); - m_RptFilenameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportFilenameEdited ), NULL, this ); - m_BrowseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnButtonBrowseRptFileClick ), NULL, this ); m_Notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_CONTROL_BASE::OnChangingNotebookPage ), NULL, this ); m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemDClick ), NULL, this ); m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); @@ -220,6 +223,11 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i m_unconnectedDataView->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); m_footprintsDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemDClick ), NULL, this ); m_footprintsDataView->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); + m_showAll->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showErrors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showWarnings->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showInfos->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_saveReport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSaveReport ), NULL, this ); m_DeleteCurrentMarkerButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteOneClick ), NULL, this ); m_DeleteAllMarkersButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteAllClick ), NULL, this ); m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnCancelClick ), NULL, this ); @@ -230,9 +238,6 @@ DIALOG_DRC_CONTROL_BASE::~DIALOG_DRC_CONTROL_BASE() { // Disconnect Events this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_CONTROL_BASE::OnActivateDlg ) ); - m_CreateRptCtrl->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportCheckBoxClicked ), NULL, this ); - m_RptFilenameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportFilenameEdited ), NULL, this ); - m_BrowseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnButtonBrowseRptFileClick ), NULL, this ); m_Notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_CONTROL_BASE::OnChangingNotebookPage ), NULL, this ); m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemDClick ), NULL, this ); m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); @@ -240,6 +245,11 @@ DIALOG_DRC_CONTROL_BASE::~DIALOG_DRC_CONTROL_BASE() m_unconnectedDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); m_footprintsDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemDClick ), NULL, this ); m_footprintsDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_DRC_CONTROL_BASE::OnDRCItemSelected ), NULL, this ); + m_showAll->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showErrors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showWarnings->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_showInfos->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSeverity ), NULL, this ); + m_saveReport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnSaveReport ), NULL, this ); m_DeleteCurrentMarkerButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteOneClick ), NULL, this ); m_DeleteAllMarkersButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteAllClick ), NULL, this ); m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnCancelClick ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_drc_base.fbp b/pcbnew/dialogs/dialog_drc_base.fbp index a819eaedce..1ccd96ddd5 100644 --- a/pcbnew/dialogs/dialog_drc_base.fbp +++ b/pcbnew/dialogs/dialog_drc_base.fbp @@ -998,235 +998,11 @@ - - 7 - 3 - 0 - wxEXPAND|wxTOP|wxRIGHT - 1 - 1 - - 3 - wxBOTH - 1 - - 0 - - fgSizerRpt - wxFLEX_GROWMODE_SPECIFIED - none - 0 - 0 - - 10 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_CHECKBOX_RPT_FILE - Create report file: - - 0 - - - 0 - - 1 - m_CreateRptCtrl - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Enable writing report to this file - - wxFILTER_NONE - wxDefaultValidator - - - - - OnReportCheckBoxClicked - - - - 3 - wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - 180,-1 - 1 - m_RptFilenameCtrl - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Enter the report filename - - wxFILTER_NONE - wxDefaultValidator - - - - - - OnReportFilenameEdited - - - - 2 - wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - ID_BUTTON_BROWSE_RPT_FILE - Browse - - 0 - - 0 - - - 0 - 30,28 - 1 - m_BrowseButton - 1 - - - protected - 1 - - - - Resizable - 1 - - - ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnButtonBrowseRptFileClick - - - - 5 - wxEXPAND|wxLEFT|wxRIGHT + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT 1 1 @@ -1560,6 +1336,479 @@ + + 10 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSeveritySizer + wxHORIZONTAL + none + + 5 + wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Show: + 0 + + 0 + + + 0 + + 1 + m_showLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + All + + 0 + + + 0 + + 1 + m_showAll + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSeverity + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Errors + + 0 + + + 0 + + 1 + m_showErrors + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSeverity + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Warnings + + 0 + + + 0 + + 1 + m_showWarnings + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSeverity + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Infos + + 0 + + + 0 + + 1 + m_showInfos + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSeverity + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Save... + + 0 + + 0 + + + 0 + + 1 + m_saveReport + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSaveReport + + + + + + 10 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline1 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + 5 wxEXPAND|wxLEFT diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h index b22e815940..f61908f6c0 100644 --- a/pcbnew/dialogs/dialog_drc_base.h +++ b/pcbnew/dialogs/dialog_drc_base.h @@ -20,22 +20,20 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include #include +#include +#include #include /////////////////////////////////////////////////////////////////////////// -#define ID_CHECKBOX_RPT_FILE 1000 -#define ID_BUTTON_BROWSE_RPT_FILE 1001 -#define ID_NOTEBOOK1 1002 +#define ID_NOTEBOOK1 1000 /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_DRC_CONTROL_BASE @@ -57,15 +55,19 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxCheckBox* m_cbReportTracksToZonesErrors; wxCheckBox* m_cbTestFootprints; wxTextCtrl* m_Messages; - wxCheckBox* m_CreateRptCtrl; - wxTextCtrl* m_RptFilenameCtrl; - wxBitmapButton* m_BrowseButton; wxNotebook* m_Notebook; wxPanel* m_panelViolations; wxDataViewCtrl* m_markerDataView; wxDataViewCtrl* m_unconnectedDataView; wxPanel* m_panelFootprintWarnings; wxDataViewCtrl* m_footprintsDataView; + wxStaticText* m_showLabel; + wxCheckBox* m_showAll; + wxCheckBox* m_showErrors; + wxCheckBox* m_showWarnings; + wxCheckBox* m_showInfos; + wxButton* m_saveReport; + wxStaticLine* m_staticline1; wxBoxSizer* m_sizerButtons; wxButton* m_DeleteCurrentMarkerButton; wxButton* m_DeleteAllMarkersButton; @@ -75,12 +77,11 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM // Virtual event handlers, overide them in your derived class virtual void OnActivateDlg( wxActivateEvent& event ) { event.Skip(); } - virtual void OnReportCheckBoxClicked( wxCommandEvent& event ) { event.Skip(); } - virtual void OnReportFilenameEdited( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonBrowseRptFileClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnChangingNotebookPage( wxNotebookEvent& event ) { event.Skip(); } virtual void OnDRCItemDClick( wxDataViewEvent& event ) { event.Skip(); } virtual void OnDRCItemSelected( wxDataViewEvent& event ) { event.Skip(); } + virtual void OnSeverity( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSaveReport( wxCommandEvent& event ) { event.Skip(); } virtual void OnDeleteOneClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnDeleteAllClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 39cfe877f7..3ab411c835 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -75,8 +75,7 @@ DRC::DRC() : m_drcRun = false; m_footprintsTested = false; - m_doCreateRptFile = false; - // m_rptFilename set to empty by its constructor + m_severities = DRC_SHOW_ERRORS | DRC_SHOW_WARNINGS | DRC_SHOW_INFOS; m_segmAngle = 0; m_segmLength = 0; @@ -136,7 +135,7 @@ void DRC::ShowDRCDialog( wxWindow* aParent ) m_drcDialog = new DIALOG_DRC_CONTROL( this, m_pcbEditorFrame, aParent ); updatePointers(); - m_drcDialog->SetRptSettings( m_doCreateRptFile, m_rptFilename ); + m_drcDialog->SetSettings( m_severities ); if( show_dlg_modal ) m_drcDialog->ShowModal(); @@ -170,7 +169,7 @@ void DRC::DestroyDRCDialog( int aReason ) { if( m_drcDialog ) { - m_drcDialog->GetRptSettings( &m_doCreateRptFile, m_rptFilename); + m_drcDialog->GetSettings( &m_severities ); m_drcDialog->Destroy(); m_drcDialog = nullptr; diff --git a/pcbnew/drc/drc.h b/pcbnew/drc/drc.h index 6c954ff77a..7660c700b7 100644 --- a/pcbnew/drc/drc.h +++ b/pcbnew/drc/drc.h @@ -158,12 +158,10 @@ private: bool m_doUnconnectedTest; // enable unconnected tests bool m_doZonesTest; // enable zone to items clearance tests bool m_doKeepoutTest; // enable keepout areas to items clearance tests - bool m_doCreateRptFile; // enable creating a report file bool m_refillZones; // refill zones if requested (by user). bool m_reportAllTrackErrors; // Report all tracks errors (or only 4 first errors) bool m_testFootprints; // Test footprints against schematic - - wxString m_rptFilename; + int m_severities; // Severities of DRC violations to display MARKER_PCB* m_currentMarker; diff --git a/pcbnew/drc/drc_tree_model.cpp b/pcbnew/drc/drc_tree_model.cpp new file mode 100644 index 0000000000..b7b710945e --- /dev/null +++ b/pcbnew/drc/drc_tree_model.cpp @@ -0,0 +1,242 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include +#include + + +#define WX_DATAVIEW_WINDOW_PADDING 6 + + +BOARD_ITEM* DRC_TREE_MODEL::ToBoardItem( BOARD* aBoard, wxDataViewItem aItem ) +{ + BOARD_ITEM* board_item = nullptr; + const DRC_TREE_NODE* node = DRC_TREE_MODEL::ToNode( aItem ); + + if( node ) + { + const DRC_ITEM* drc_item = node->m_DrcItem; + + switch( node->m_Type ) + { + case DRC_TREE_NODE::MARKER: + board_item = static_cast( drc_item->GetParent() ); + break; + case DRC_TREE_NODE::MAIN_ITEM: + board_item = drc_item->GetMainItem( aBoard ); + break; + case DRC_TREE_NODE::AUX_ITEM: + board_item = drc_item->GetAuxiliaryItem( aBoard ); + break; + } + } + + return board_item; +} + + +DRC_TREE_MODEL::DRC_TREE_MODEL( wxDataViewCtrl* aView ) : + m_view( aView ), + m_drcItemsProvider( nullptr ) +{ + m_view->GetMainWindow()->Connect( wxEVT_SIZE, + wxSizeEventHandler( DRC_TREE_MODEL::onSizeView ), + NULL, this ); +} + + +DRC_TREE_MODEL::~DRC_TREE_MODEL() +{ + delete m_drcItemsProvider; +} + + +void DRC_TREE_MODEL::SetProvider( DRC_ITEMS_PROVIDER* aProvider ) +{ + wxWindowUpdateLocker updateLock( m_view ); + + // Even with the updateLock, wxWidgets sometimes ties its knickers in + // a knot when trying to run a wxdataview_selection_changed_callback() + // on a row that has been deleted. + m_view->UnselectAll(); + + Cleared(); + + delete m_drcItemsProvider; + m_drcItemsProvider = aProvider; + m_tree.clear(); + +#define PUSH_NODE( p, item, type ) push_back( std::make_unique( p, item, type ) ) + + for( int i = 0; m_drcItemsProvider && i < m_drcItemsProvider->GetCount(); ++i ) + { + const DRC_ITEM* drcItem = m_drcItemsProvider->GetItem( i ); + + m_tree.PUSH_NODE( nullptr, drcItem, DRC_TREE_NODE::MARKER ); + DRC_TREE_NODE* node = m_tree.back().get(); + + node->m_Children.PUSH_NODE( node, drcItem, DRC_TREE_NODE::MAIN_ITEM ); + + if( drcItem->HasSecondItem() ) + node->m_Children.PUSH_NODE( node, drcItem, DRC_TREE_NODE::AUX_ITEM ); + } + +#ifdef __WXGTK__ + // The fastest method to update wxDataViewCtrl is to rebuild from + // scratch by calling Cleared(). Linux requires to reassociate model to + // display data, but Windows will create multiple associations. + // On MacOS, this crashes kicad. See https://gitlab.com/kicad/code/kicad/issues/3666 + // and https://gitlab.com/kicad/code/kicad/issues/3653 + m_view->AssociateModel( this ); +#endif + + m_view->ClearColumns(); + int width = m_view->GetMainWindow()->GetRect().GetWidth() - WX_DATAVIEW_WINDOW_PADDING; + m_view->AppendTextColumn( wxEmptyString, 0, wxDATAVIEW_CELL_INERT, width ); + + ExpandAll(); +} + + +void DRC_TREE_MODEL::ExpandAll() +{ + for( std::unique_ptr& markerNode : m_tree ) + m_view->Expand( ToItem( markerNode.get() ) ); +} + + +bool DRC_TREE_MODEL::IsContainer( wxDataViewItem const& aItem ) const +{ + if( ToNode( aItem ) == nullptr ) // must be tree root... + return true; + else + return ToNode( aItem )->m_Type == DRC_TREE_NODE::MARKER; +} + + +wxDataViewItem DRC_TREE_MODEL::GetParent( wxDataViewItem const& aItem ) const +{ + return ToItem( ToNode( aItem)->m_Parent ); +} + + +unsigned int DRC_TREE_MODEL::GetChildren( wxDataViewItem const& aItem, + wxDataViewItemArray& aChildren ) const +{ + const DRC_TREE_NODE* p = ToNode( aItem ); + const std::vector>& children = p ? p->m_Children : m_tree; + + for( const std::unique_ptr& child: children ) + aChildren.Add( ToItem( child.get() ) ); + + return children.size(); +} + + +/** + * Called by the wxDataView to fetch an item's value. + */ +void DRC_TREE_MODEL::GetValue( wxVariant& aVariant, + wxDataViewItem const& aItem, + unsigned int aCol ) const +{ + const DRC_TREE_NODE* node = ToNode( aItem ); + wxASSERT( node ); + + switch( node->m_Type ) + { + case DRC_TREE_NODE::MARKER: aVariant = node->m_DrcItem->GetErrorText(); break; + case DRC_TREE_NODE::MAIN_ITEM: aVariant = node->m_DrcItem->GetMainText(); break; + case DRC_TREE_NODE::AUX_ITEM: aVariant = node->m_DrcItem->GetAuxiliaryText(); break; + } +} + + +/** + * Called by the wxDataView to fetch an item's formatting. Return true iff the + * item has non-default attributes. + */ +bool DRC_TREE_MODEL::GetAttr( wxDataViewItem const& aItem, + unsigned int aCol, + wxDataViewItemAttr& aAttr ) const +{ + const DRC_TREE_NODE* node = ToNode( aItem ); + wxASSERT( node ); + + switch( node->m_Type ) + { + case DRC_TREE_NODE::MARKER: aAttr.SetBold( true ); return true; + case DRC_TREE_NODE::MAIN_ITEM: return false; + case DRC_TREE_NODE::AUX_ITEM: return false; + } + + return false; +} + + +void DRC_TREE_MODEL::DeleteCurrentItem() +{ + wxDataViewItem dataViewItem = m_view->GetCurrentItem(); + DRC_TREE_NODE* tree_node = ToNode( dataViewItem ); + const DRC_ITEM* drc_item = tree_node ? tree_node->m_DrcItem : nullptr; + + if( !drc_item ) + { + wxBell(); + return; + } + + for( int i = 0; i < m_drcItemsProvider->GetCount(); ++i ) + { + if( m_drcItemsProvider->GetItem( i ) == drc_item ) + { + m_drcItemsProvider->DeleteItem( i ); + m_tree.erase( m_tree.begin() + i ); + + ItemDeleted( ToItem( nullptr ), dataViewItem ); + break; + } + } +} + + +void DRC_TREE_MODEL::DeleteAllItems() +{ + if( m_drcItemsProvider ) + { + m_drcItemsProvider->DeleteAllItems(); + + m_tree.clear(); + Cleared(); + } +} + + +void DRC_TREE_MODEL::onSizeView( wxSizeEvent& aEvent ) +{ + int width = m_view->GetMainWindow()->GetRect().GetWidth() - WX_DATAVIEW_WINDOW_PADDING; + + if( m_view->GetColumnCount() > 0 ) + m_view->GetColumn( 0 )->SetWidth( width ); +} diff --git a/pcbnew/drc/drc_tree_model.h b/pcbnew/drc/drc_tree_model.h index c84cf91145..0b4a968626 100644 --- a/pcbnew/drc/drc_tree_model.h +++ b/pcbnew/drc/drc_tree_model.h @@ -29,6 +29,9 @@ #include +#define WX_DATAVIEW_WINDOW_PADDING 6 + + /** * Provide an abstract interface of a DRC_ITEM* list manager. The details * of the actual list architecture are hidden from the caller. Any class @@ -165,15 +168,16 @@ public: m_DrcItem( aDrcItem ) {} - NODE_TYPE m_Type; - DRC_TREE_NODE* m_Parent; + NODE_TYPE m_Type; + DRC_TREE_NODE* m_Parent; - const DRC_ITEM* m_DrcItem; - std::vector m_Children; + const DRC_ITEM* m_DrcItem; + + std::vector> m_Children; }; -class DRC_TREE_MODEL : public wxDataViewModel +class DRC_TREE_MODEL : public wxDataViewModel, wxEvtHandler { public: static wxDataViewItem ToItem( DRC_TREE_NODE const* aNode ) @@ -186,119 +190,27 @@ public: return static_cast( aItem.GetID() ); } - static BOARD_ITEM* ToBoardItem( BOARD* aBoard, wxDataViewItem aItem ) - { - BOARD_ITEM* board_item = nullptr; - const DRC_TREE_NODE* node = DRC_TREE_MODEL::ToNode( aItem ); - - if( node ) - { - const DRC_ITEM* drc_item = node->m_DrcItem; - - switch( node->m_Type ) - { - case DRC_TREE_NODE::MARKER: - board_item = static_cast( drc_item->GetParent() ); - break; - case DRC_TREE_NODE::MAIN_ITEM: - board_item = drc_item->GetMainItem( aBoard ); - break; - case DRC_TREE_NODE::AUX_ITEM: - board_item = drc_item->GetAuxiliaryItem( aBoard ); - break; - } - } - - return board_item; - }; + static BOARD_ITEM* ToBoardItem( BOARD* aBoard, wxDataViewItem aItem ); public: - DRC_TREE_MODEL( wxDataViewCtrl* aView ) : - m_view( aView ), - m_drcItemsProvider( nullptr ) - { } + DRC_TREE_MODEL( wxDataViewCtrl* aView ); - ~DRC_TREE_MODEL() - { - delete m_drcItemsProvider; - } + ~DRC_TREE_MODEL(); - void SetProvider( DRC_ITEMS_PROVIDER* aProvider ) - { - wxWindowUpdateLocker updateLock( m_view ); - - // Even with the updateLock, wxWidgets sometimes ties its knickers in - // a knot when trying to run a wxdataview_selection_changed_callback() - // on a row that has been deleted. - m_view->UnselectAll(); - - Cleared(); - - delete m_drcItemsProvider; - m_drcItemsProvider = aProvider; - m_tree.clear(); - - for( int i = 0; m_drcItemsProvider && i < m_drcItemsProvider->GetCount(); ++i ) - { - const DRC_ITEM* drcItem = m_drcItemsProvider->GetItem( i ); - - m_tree.emplace_back( nullptr, drcItem, DRC_TREE_NODE::MARKER ); - DRC_TREE_NODE& node = m_tree.back(); - - node.m_Children.emplace_back( &node, drcItem, DRC_TREE_NODE::MAIN_ITEM ); - - if( drcItem->HasSecondItem() ) - node.m_Children.emplace_back( &node, drcItem, DRC_TREE_NODE::AUX_ITEM ); - } - -#if defined( __LINUX__ ) - // The fastest method to update wxDataViewCtrl is to rebuild from - // scratch by calling Cleared(). Linux requires to reassociate model to - // display data, but Windows will create multiple associations. - // On MacOS, this crashes kicad. See https://gitlab.com/kicad/code/kicad/issues/3666 - // and https://gitlab.com/kicad/code/kicad/issues/3653 - m_view->AssociateModel( this ); -#endif - m_view->ClearColumns(); - m_view->AppendTextColumn( wxEmptyString, 0, wxDATAVIEW_CELL_INERT, 4000 ); - - ExpandAll(); - } + void SetProvider( DRC_ITEMS_PROVIDER* aProvider ); int GetDRCItemCount() const { return m_tree.size(); } - const DRC_ITEM* GetDRCItem( int i ) const { return m_tree.at( i ).m_DrcItem; } + const DRC_ITEM* GetDRCItem( int i ) const { return m_tree.at( i )->m_DrcItem; } - void ExpandAll() - { - for( DRC_TREE_NODE& markerNode : m_tree ) - m_view->Expand( ToItem( &markerNode ) ); - } + void ExpandAll(); - bool IsContainer( wxDataViewItem const& aItem ) const override - { - if( ToNode( aItem ) == nullptr ) // must be tree root... - return true; - else - return ToNode( aItem )->m_Type == DRC_TREE_NODE::MARKER; - } + bool IsContainer( wxDataViewItem const& aItem ) const override; - wxDataViewItem GetParent( wxDataViewItem const& aItem ) const override - { - return ToItem( ToNode( aItem)->m_Parent ); - } + wxDataViewItem GetParent( wxDataViewItem const& aItem ) const override; unsigned int GetChildren( wxDataViewItem const& aItem, - wxDataViewItemArray& aChildren ) const override - { - const DRC_TREE_NODE* parent = ToNode( aItem ); - const std::vector& children = parent ? parent->m_Children : m_tree; - - for( const DRC_TREE_NODE& child: children ) - aChildren.Add( ToItem( &child ) ); - - return children.size(); - } + wxDataViewItemArray& aChildren ) const override; // Simple, single-text-column model unsigned int GetColumnCount() const override { return 1; } @@ -310,18 +222,7 @@ public: */ void GetValue( wxVariant& aVariant, wxDataViewItem const& aItem, - unsigned int aCol ) const override - { - const DRC_TREE_NODE* node = ToNode( aItem ); - wxASSERT( node ); - - switch( node->m_Type ) - { - case DRC_TREE_NODE::MARKER: aVariant = node->m_DrcItem->GetErrorText(); break; - case DRC_TREE_NODE::MAIN_ITEM: aVariant = node->m_DrcItem->GetMainText(); break; - case DRC_TREE_NODE::AUX_ITEM: aVariant = node->m_DrcItem->GetAuxiliaryText(); break; - } - } + unsigned int aCol ) const override; /** * Called by the wxDataView to edit an item's content. @@ -340,61 +241,18 @@ public: */ bool GetAttr( wxDataViewItem const& aItem, unsigned int aCol, - wxDataViewItemAttr& aAttr ) const override - { - const DRC_TREE_NODE* node = ToNode( aItem ); - wxASSERT( node ); + wxDataViewItemAttr& aAttr ) const override; - switch( node->m_Type ) - { - case DRC_TREE_NODE::MARKER: aAttr.SetBold( true ); return true; - case DRC_TREE_NODE::MAIN_ITEM: return false; - case DRC_TREE_NODE::AUX_ITEM: return false; - } + void DeleteCurrentItem(); + void DeleteAllItems(); - return false; - } - - void DeleteCurrentItem() - { - wxDataViewItem dataViewItem = m_view->GetCurrentItem(); - DRC_TREE_NODE* tree_node = ToNode( dataViewItem ); - const DRC_ITEM* drc_item = tree_node ? tree_node->m_DrcItem : nullptr; - - if( !drc_item ) - { - wxBell(); - return; - } - - for( int i = 0; i < m_drcItemsProvider->GetCount(); ++i ) - { - if( m_drcItemsProvider->GetItem( i ) == drc_item ) - { - m_drcItemsProvider->DeleteItem( i ); - m_tree.erase( m_tree.begin() + i ); - - ItemDeleted( ToItem( nullptr ), dataViewItem ); - break; - } - } - } - - void DeleteAllItems() - { - if( m_drcItemsProvider ) - { - m_drcItemsProvider->DeleteAllItems(); - - m_tree.clear(); - Cleared(); - } - } + void onSizeView( wxSizeEvent& aEvent ); private: - wxDataViewCtrl* m_view; - DRC_ITEMS_PROVIDER* m_drcItemsProvider; // I own this, but not its contents - std::vector m_tree; // I own this + wxDataViewCtrl* m_view; + DRC_ITEMS_PROVIDER* m_drcItemsProvider; // I own this, but not its contents + + std::vector> m_tree; // I own this }; #endif //KICAD_DRC_TREE_MODEL_H