Fix mode-less dialog issues.

Don't assume the dialog is mode-less and call Destroy() from within a
dialog method.  This will most assuredly crash if the dialog is shown
modally or quasi-modally.

Don't leak memory for mode-less dialogs created on the stack.  Make sure
when the parent frame window is closed that all mode-less dialog memory
is cleaned up.  Dialogs are not child windows like controls and toolbars
so their memory does not automatically get cleaned up when the parent
window is destroyed.

Do not directly access frame parent window's pointer in dialog destructors.
Apparently the tear down order when destroying mode-less dialogs is not
guaranteed so the parent window may get deleted before the dialog causing
a crash when accessing the parent window pointer from the dialog dtor.

Do not close mode-less dialogs in the parent frame's destructor.  This
doesn't guarantee that the dialog(s) will be destroyed before the parent
but it may reduce some careless mode-less dialog event handling in the
future.
This commit is contained in:
Wayne Stambaugh 2023-03-13 12:03:48 -04:00
parent dc78797274
commit 66f6168163
35 changed files with 747 additions and 384 deletions

View File

@ -4,7 +4,7 @@
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2023 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
@ -144,7 +144,8 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
this );
}
aFrame->Connect( UNITS_CHANGED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL::onUnitsChanged ),
aFrame->Connect( EDA_EVT_UNITS_CHANGED,
wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL::onUnitsChanged ),
nullptr, this );
#ifdef __WXOSX__
@ -451,7 +452,8 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign
double step_mm = OFFSET_INCREMENT_MM;
double curr_value_mm =
EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits, textCtrl->GetValue() )
EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
textCtrl->GetValue() )
/ pcbIUScale.IU_PER_MM;
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCHES )

View File

@ -26,22 +26,17 @@
#include <wx/wxhtml.h>
DIALOG_BOOK_REPORTER::DIALOG_BOOK_REPORTER( KIWAY_PLAYER* aParent, const wxString& aDialogName,
const wxString& aDialogTitle ) :
DIALOG_BOOK_REPORTER_BASE( aParent ),
wxDEFINE_EVENT( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, wxCommandEvent );
DIALOG_BOOK_REPORTER::DIALOG_BOOK_REPORTER( KIWAY_PLAYER* aParent, const wxString& aName,
const wxString& aTitle ) :
DIALOG_BOOK_REPORTER_BASE( aParent, wxID_ANY, aTitle ),
m_frame( aParent )
{
SetName( aDialogName );
SetTitle( aDialogTitle );
aParent->Bind( wxEVT_CLOSE_WINDOW,
[this]( wxCloseEvent& aEvent )
{
Close();
aEvent.Skip();
} );
SetName( aName );
SetupStandardButtons();
finishDialogSettings();
}
@ -96,3 +91,21 @@ int DIALOG_BOOK_REPORTER::GetPageCount() const
return m_notebook->GetPageCount();
}
void DIALOG_BOOK_REPORTER::OnClose( wxCloseEvent& aEvent )
{
// Dialog is mode-less so let the parent know that it needs to be destroyed.
if( !IsModal() && !IsQuasiModal() )
{
wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, wxID_ANY );
evt->SetEventObject( this );
evt->SetString( GetName() );
wxWindow* parent = GetParent();
if( parent )
wxQueueEvent( parent, evt );
}
aEvent.Skip();
}

View File

@ -37,12 +37,12 @@ DIALOG_BOOK_REPORTER_BASE::DIALOG_BOOK_REPORTER_BASE( wxWindow* parent, wxWindow
this->Centre( wxBOTH );
// Connect Events
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BOOK_REPORTER_BASE::OnOK ), NULL, this );
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_BOOK_REPORTER_BASE::OnClose ) );
}
DIALOG_BOOK_REPORTER_BASE::~DIALOG_BOOK_REPORTER_BASE()
{
// Disconnect Events
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BOOK_REPORTER_BASE::OnOK ), NULL, this );
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_BOOK_REPORTER_BASE::OnClose ) );
}

View File

@ -56,6 +56,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnClose">OnClose</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bMainSizer</property>
@ -136,7 +137,6 @@
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnOKButtonClick">OnOK</event>
</object>
</object>
</object>

View File

@ -37,7 +37,7 @@ class DIALOG_BOOK_REPORTER_BASE : public DIALOG_SHIM
wxButton* m_sdbSizerOK;
// Virtual event handlers, override them in your derived class
virtual void OnOK( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
public:

View File

@ -218,7 +218,7 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_
&PANEL_SETUP_NETCLASSES::OnNetclassGridMouseEvent,
this );
m_frame->Bind( UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
m_netclassGrid->EndBatch();
m_assignmentGrid->EndBatch();
@ -243,7 +243,7 @@ PANEL_SETUP_NETCLASSES::~PANEL_SETUP_NETCLASSES()
wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging ),
nullptr, this );
m_frame->Unbind( UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
}
@ -287,8 +287,8 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
if( lineStyleIdx >= (int) g_lineStyleNames.size() )
lineStyleIdx = 0;
m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE, g_lineStyleNames[ lineStyleIdx ] );
m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE,
g_lineStyleNames[ lineStyleIdx ] );
m_netclassGrid->SetUnitValue( aRow, GRID_CLEARANCE, nc->GetClearance() );
m_netclassGrid->SetUnitValue( aRow, GRID_TRACKSIZE, nc->GetTrackWidth() );
m_netclassGrid->SetUnitValue( aRow, GRID_VIASIZE, nc->GetViaDiameter() );
@ -331,9 +331,6 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
}
/*
* Populates drop-downs with the list of net classes
*/
void PANEL_SETUP_NETCLASSES::rebuildNetclassDropdowns()
{
m_assignmentGrid->CommitPendingChanges( true );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -67,7 +67,7 @@
#include <functional>
#include <kiface_ids.h>
wxDEFINE_EVENT( UNITS_CHANGED, wxCommandEvent );
wxDEFINE_EVENT( EDA_EVT_UNITS_CHANGED, wxCommandEvent );
// Minimum window size
@ -664,7 +664,8 @@ void EDA_BASE_FRAME::ensureWindowIsOnScreen()
wxSize size = GetWindowSize();
wxLogTrace( traceDisplayLocation,
wxS( "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d" ), clientSize.x, clientSize.y,
wxS( "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d" ),
clientSize.x, clientSize.y,
clientSize.width, clientSize.height );
if( pos.y < clientSize.y )
@ -678,8 +679,8 @@ void EDA_BASE_FRAME::ensureWindowIsOnScreen()
if( pos.x < clientSize.x )
{
wxLogTrace( traceDisplayLocation,
wxS( "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d" ), pos.x,
clientSize.x );
wxS( "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d" ),
pos.x, clientSize.x );
pos.x = clientSize.x;
}
@ -687,8 +688,8 @@ void EDA_BASE_FRAME::ensureWindowIsOnScreen()
{
int newWidth = clientSize.width - ( pos.x - clientSize.x );
wxLogTrace( traceDisplayLocation,
wxS( "ensureWindowIsOnScreen: effective width %d above available %d, setting to %d" ),
pos.x + size.x, clientSize.width, newWidth );
wxS( "ensureWindowIsOnScreen: effective width %d above available %d, setting "
"to %d" ), pos.x + size.x, clientSize.width, newWidth );
size.x = newWidth;
}
@ -696,8 +697,8 @@ void EDA_BASE_FRAME::ensureWindowIsOnScreen()
{
int newHeight = clientSize.height - ( pos.y - clientSize.y );
wxLogTrace( traceDisplayLocation,
wxS( "ensureWindowIsOnScreen: effective height %d above available %d, setting to %d" ),
pos.y + size.y, clientSize.height, newHeight );
wxS( "ensureWindowIsOnScreen: effective height %d above available %d, setting "
"to %d" ), pos.y + size.y, clientSize.height, newHeight );
size.y = newHeight;
}
@ -1354,7 +1355,8 @@ void EDA_BASE_FRAME::ChangeUserUnits( EDA_UNITS aUnits )
SetUserUnits( aUnits );
unitsChangeRefresh();
wxCommandEvent e( UNITS_CHANGED );
wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
e.SetInt( static_cast<int>( aUnits ) );
e.SetClientData( this );
ProcessEventLocally( e );
}

View File

@ -284,7 +284,7 @@ void EDA_DRAW_FRAME::ToggleUserUnits()
: EDA_UNITS::INCHES );
unitsChangeRefresh();
wxCommandEvent e( UNITS_CHANGED );
wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
ProcessEventLocally( e );
}
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014-2015 CERN
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -101,7 +101,8 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
if( m_eventSource )
{
m_eventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
m_eventSource->Connect( EDA_EVT_UNITS_CHANGED,
wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
nullptr, this );
}
}
@ -117,7 +118,8 @@ UNIT_BINDER::~UNIT_BINDER()
if( m_eventSource )
{
m_eventSource->Disconnect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
m_eventSource->Disconnect( EDA_EVT_UNITS_CHANGED,
wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
nullptr, this );
}
@ -318,7 +320,8 @@ bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
m_errorMessage = wxString::Format( _( "%s must be at least %s." ),
valueDescriptionFromLabel( m_label ),
EDA_UNIT_UTILS::UI::StringFromValue( *m_iuScale, m_units,
val_min_iu, true ) );
val_min_iu,
true ) );
textEntry->SelectAll();
@ -334,7 +337,8 @@ bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
m_errorMessage = wxString::Format( _( "%s must be less than %s." ),
valueDescriptionFromLabel( m_label ),
EDA_UNIT_UTILS::UI::StringFromValue( *m_iuScale, m_units,
val_max_iu, true ) );
val_max_iu,
true ) );
textEntry->SelectAll();

View File

@ -49,6 +49,10 @@
#include <string_utils.h>
#include <kiplatform/ui.h>
wxDEFINE_EVENT( EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent );
// wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
// not, in repeatedly creating/destroying a wxDC to do the measurement in).
// Use default column widths instead.
@ -177,8 +181,6 @@ void DIALOG_ERC::UpdateAnnotationWarning()
}
// PROGRESS_REPORTER calls
bool DIALOG_ERC::updateUI()
{
// If ERC checks ever get slow enough we'll want a progress indicator...
@ -285,8 +287,6 @@ void DIALOG_ERC::OnDeleteOneClick( wxCommandEvent& aEvent )
}
/* Delete the old ERC markers, over the whole hierarchy
*/
void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
{
bool includeExclusions = false;
@ -318,7 +318,6 @@ void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
}
// This is a modeless dialog so we have to handle these ourselves.
void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
{
if( m_running )
@ -329,15 +328,26 @@ void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
m_parent->FocusOnItem( nullptr );
Close();
aEvent.Skip();
}
void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& event )
void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& aEvent )
{
m_parent->FocusOnItem( nullptr );
m_parent->GetToolManager()->GetTool<EE_INSPECTION_TOOL>()->DestroyERCDialog();
// Dialog is mode-less so let the parent know that it needs to be destroyed.
if( !IsModal() && !IsQuasiModal() )
{
wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY );
wxWindow* parent = GetParent();
if( parent )
wxQueueEvent( parent, evt );
}
aEvent.Skip();
}

View File

@ -34,6 +34,12 @@
#include <erc_settings.h>
/**
* Event sent to parent when dialog is mode-less.
*/
wxDECLARE_EVENT( EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent );
#define DIALOG_ERC_WINDOW_NAME "DialogErcWindowName"

View File

@ -91,12 +91,12 @@ public:
{
m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
m_frame->Bind( UNITS_CHANGED, &PIN_TABLE_DATA_MODEL::onUnitsChanged, this );
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &PIN_TABLE_DATA_MODEL::onUnitsChanged, this );
}
~PIN_TABLE_DATA_MODEL()
{
m_frame->Unbind( UNITS_CHANGED, &PIN_TABLE_DATA_MODEL::onUnitsChanged, this );
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &PIN_TABLE_DATA_MODEL::onUnitsChanged, this );
}
void onUnitsChanged( wxCommandEvent& aEvent )

View File

@ -293,7 +293,7 @@ void FIELDS_GRID_TABLE<T>::initGrid( WX_GRID* aGrid )
m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
m_frame->Bind( UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
}
@ -316,7 +316,7 @@ FIELDS_GRID_TABLE<T>::~FIELDS_GRID_TABLE()
m_fontAttr->DecRef();
m_colorAttr->DecRef();
m_frame->Unbind( UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
}

View File

@ -27,7 +27,9 @@
#include <symbol_library.h>
#include <confirm.h>
#include <connection_graph.h>
#include <dialogs/dialog_erc.h>
#include <dialogs/dialog_schematic_find.h>
#include <dialogs/dialog_book_reporter.h>
#include <eeschema_id.h>
#include <executable_names.h>
#include <gestfich.h>
@ -90,6 +92,9 @@
#include <drawing_sheet/ds_proxy_view_item.h>
#define DIFF_SYMBOLS_DIALOG_NAME wxT( "DiffSymbolsDialog" )
BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, SCH_BASE_FRAME )
EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, EDA_DRAW_FRAME::OnSockRequestServer )
EVT_SOCKET( ID_EDA_SOCKET_EVENT, EDA_DRAW_FRAME::OnSockRequest )
@ -115,7 +120,9 @@ END_EVENT_TABLE()
SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), wxDefaultPosition,
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
m_highlightedConn( nullptr )
m_highlightedConn( nullptr ),
m_ercDialog( nullptr ),
m_diffSymbolDialog( nullptr )
{
m_maximizeByDefault = true;
m_schematic = new SCHEMATIC( nullptr );
@ -286,6 +293,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
// top-left corner of the canvas
wxPoint canvas_pos = GetCanvas()->GetScreenPosition();
hierarchy_pane.FloatingPosition( canvas_pos.x + 10, canvas_pos.y + 10 );
Bind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &SCH_EDIT_FRAME::onCloseSymbolDiffDialog, this );
Bind( EDA_EVT_CLOSE_ERC_DIALOG, &SCH_EDIT_FRAME::onCloseErcDialog, this );
}
@ -294,23 +304,10 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
m_hierarchy->Disconnect( wxEVT_SIZE,
wxSizeEventHandler( SCH_EDIT_FRAME::OnResizeHierarchyNavigator ),
NULL, this );
// Ensure m_canvasType is up to date, to save it in config
m_canvasType = GetCanvas()->GetBackend();
// Close modeless dialogs
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_ERC_WINDOW_NAME );
if( open_dlg )
open_dlg->Close( true );
// Shutdown all running tools
if( m_toolManager )
{
m_toolManager->ShutdownAllTools();
delete m_toolManager;
m_toolManager = nullptr;
}
SetScreen( nullptr );
delete m_schematic;
@ -439,9 +436,12 @@ void SCH_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( ACTIONS::inchesUnits, CHECK( cond.Units( EDA_UNITS::INCHES ) ) );
mgr->SetConditions( ACTIONS::milsUnits, CHECK( cond.Units( EDA_UNITS::MILS ) ) );
mgr->SetConditions( EE_ACTIONS::lineModeFree, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_FREE ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode90, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_90 ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode45, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_45 ) ) );
mgr->SetConditions( EE_ACTIONS::lineModeFree,
CHECK( cond.LineMode( LINE_MODE::LINE_MODE_FREE ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode90,
CHECK( cond.LineMode( LINE_MODE::LINE_MODE_90 ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode45,
CHECK( cond.LineMode( LINE_MODE::LINE_MODE_45 ) ) );
mgr->SetConditions( ACTIONS::cut, ENABLE( hasElements ) );
mgr->SetConditions( ACTIONS::copy, ENABLE( hasElements ) );
@ -822,13 +822,6 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
}
}
// Close modeless dialogs. They're trouble when they get destroyed after the frame and/or
// board.
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_ERC_WINDOW_NAME );
if( open_dlg )
open_dlg->Close( true );
return true;
}
@ -841,6 +834,15 @@ void SCH_EDIT_FRAME::doCloseWindow()
if( m_toolManager )
m_toolManager->ShutdownAllTools();
// Close modeless dialogs. They're trouble when they get destroyed after the frame.
Unbind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &SCH_EDIT_FRAME::onCloseSymbolDiffDialog, this );
Unbind( EDA_EVT_CLOSE_ERC_DIALOG, &SCH_EDIT_FRAME::onCloseErcDialog, this );
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_ERC_WINDOW_NAME );
if( open_dlg )
open_dlg->Destroy();
// Close the find dialog and preserve its setting if it is displayed.
if( m_findReplaceDialog )
{
@ -851,6 +853,26 @@ void SCH_EDIT_FRAME::doCloseWindow()
m_findReplaceDialog = nullptr;
}
if( m_diffSymbolDialog )
{
m_diffSymbolDialog->Destroy();
m_diffSymbolDialog = nullptr;
}
if( m_ercDialog )
{
m_ercDialog->Destroy();
m_ercDialog = nullptr;
}
// Shutdown all running tools
if( m_toolManager )
{
m_toolManager->ShutdownAllTools();
delete m_toolManager;
m_toolManager = nullptr;
}
wxAuiPaneInfo& hierarchy_pane = m_auimgr.GetPane( SchematicHierarchyPaneName() );
if( hierarchy_pane.IsShown() && hierarchy_pane.IsFloating() )
@ -2075,3 +2097,42 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
m_hierarchy->UpdateHierarchySelection();
}
DIALOG_BOOK_REPORTER* SCH_EDIT_FRAME::GetSymbolDiffDialog()
{
if( !m_diffSymbolDialog )
m_diffSymbolDialog = new DIALOG_BOOK_REPORTER( this, DIFF_SYMBOLS_DIALOG_NAME,
_( "Diff Symbol with Library" ) );
return m_diffSymbolDialog;
}
void SCH_EDIT_FRAME::onCloseSymbolDiffDialog( wxCommandEvent& aEvent )
{
if( m_diffSymbolDialog && aEvent.GetString() == DIFF_SYMBOLS_DIALOG_NAME )
{
m_diffSymbolDialog->Destroy();
m_diffSymbolDialog = nullptr;
}
}
DIALOG_ERC* SCH_EDIT_FRAME::GetErcDialog()
{
if( !m_ercDialog )
m_ercDialog = new DIALOG_ERC( this );
return m_ercDialog;
}
void SCH_EDIT_FRAME::onCloseErcDialog( wxCommandEvent& aEvent )
{
if( m_ercDialog )
{
m_ercDialog->Destroy();
m_ercDialog = nullptr;
}
}

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2023 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
@ -54,6 +54,8 @@ class SCH_SYMBOL;
class SCH_FIELD;
class SCH_JUNCTION;
class SCHEMATIC;
class DIALOG_BOOK_REPORTER;
class DIALOG_ERC;
class DIALOG_SCH_FIND;
class wxFindReplaceData;
class RESCUER;
@ -271,16 +273,18 @@ public:
void TestDanglingEnds();
/**
* Sends items to Pcbnew for selection
* Send items to board editor for selection.
*
* This is used for when the eeschema user is using the cross-probe tool.
*
* @param aItems are the items to select
* @param aForce select the element in pcbnew whether or not the user has the select option chosen
* This is used for when the eeschema user is using the cross-probe tool
* @param aForce select the element in pcbnew whether or not the user has the select option
* chosen
*/
void SendSelectItemsToPcb( const std::vector<EDA_ITEM*>& aItems, bool aForce );
/**
* Sends a net name to Pcbnew for highlighting
* Send a net name to Pcbnew for highlighting.
*
* @param aNetName is the name of a net, or empty string to clear highlight
*/
@ -814,6 +818,10 @@ public:
*/
void ToggleSchematicHierarchy();
DIALOG_BOOK_REPORTER* GetSymbolDiffDialog();
DIALOG_ERC* GetErcDialog();
/**
* @return the name of the wxAuiPaneInfo managing the Hierarchy Navigator panel
*/
@ -843,6 +851,10 @@ protected:
void saveProjectSettings() override;
void onCloseSymbolDiffDialog( wxCommandEvent& aEvent );
void onCloseErcDialog( wxCommandEvent& aEvent );
private:
// Called when resizing the Hierarchy Navigator panel
void OnResizeHierarchyNavigator( wxSizeEvent& aEvent );
@ -932,7 +944,8 @@ private:
///< to call a custom net list generator.
DIALOG_SCH_FIND* m_findReplaceDialog;
DIALOG_ERC* m_ercDialog;
DIALOG_BOOK_REPORTER* m_diffSymbolDialog;
HIERARCHY_PANE* m_hierarchy;
bool m_syncingPcbToSchSelection; // Recursion guard when synchronizing selection from PCB

View File

@ -48,12 +48,8 @@
#include <math/util.h> // for KiROUND
#define DIFF_SYMBOLS_DIALOG_NAME wxT( "DiffSymbolsDialog" )
EE_INSPECTION_TOOL::EE_INSPECTION_TOOL() :
EE_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.InspectionTool" ),
m_ercDialog( nullptr )
EE_TOOL_BASE<SCH_BASE_FRAME>( "eeschema.InspectionTool" )
{
}
@ -79,9 +75,11 @@ void EE_INSPECTION_TOOL::Reset( RESET_REASON aReason )
{
EE_TOOL_BASE::Reset( aReason );
if( aReason == MODEL_RELOAD )
if( aReason == MODEL_RELOAD && m_frame )
{
DestroyERCDialog();
wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY );
wxQueueEvent( m_frame, evt );
}
}
@ -95,46 +93,35 @@ int EE_INSPECTION_TOOL::RunERC( const TOOL_EVENT& aEvent )
void EE_INSPECTION_TOOL::ShowERCDialog()
{
if( m_frame->IsType( FRAME_SCH ) )
{
if( m_ercDialog )
{
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( frame, /* void */ );
DIALOG_ERC* dlg = frame->GetErcDialog();
wxCHECK( dlg, /* void */ );
// Needed at least on Windows. Raise() is not enough
m_ercDialog->Show( true );
dlg->Show( true );
// Bring it to the top if already open. Dual monitor users need this.
m_ercDialog->Raise();
}
else
{
// This is a modeless dialog, so new it rather than instantiating on stack.
m_ercDialog = new DIALOG_ERC( static_cast<SCH_EDIT_FRAME*>( m_frame ) );
m_ercDialog->Show( true );
}
}
}
void EE_INSPECTION_TOOL::DestroyERCDialog()
{
if( m_ercDialog )
m_ercDialog->Destroy();
m_ercDialog = nullptr;
dlg->Raise();
}
int EE_INSPECTION_TOOL::PrevMarker( const TOOL_EVENT& aEvent )
{
if( m_ercDialog )
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( frame, 0 );
DIALOG_ERC* dlg = frame->GetErcDialog();
if( dlg )
{
m_ercDialog->Show( true );
m_ercDialog->Raise();
m_ercDialog->PrevMarker();
}
else
{
ShowERCDialog();
dlg->Show( true );
dlg->Raise();
dlg->PrevMarker();
}
return 0;
@ -143,16 +130,17 @@ int EE_INSPECTION_TOOL::PrevMarker( const TOOL_EVENT& aEvent )
int EE_INSPECTION_TOOL::NextMarker( const TOOL_EVENT& aEvent )
{
if( m_ercDialog )
{
m_ercDialog->Show( true );
m_ercDialog->Raise();
m_ercDialog->NextMarker();
}
else
{
ShowERCDialog();
}
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( frame, 0 );
DIALOG_ERC* dlg = frame->GetErcDialog();
wxCHECK( dlg, 0 );
dlg->Show( true );
dlg->Raise();
dlg->NextMarker();
return 0;
}
@ -160,18 +148,26 @@ int EE_INSPECTION_TOOL::NextMarker( const TOOL_EVENT& aEvent )
int EE_INSPECTION_TOOL::CrossProbe( const TOOL_EVENT& aEvent )
{
if( m_ercDialog )
{
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( frame, 0 );
DIALOG_ERC* dlg = frame->GetErcDialog();
wxCHECK( dlg, 0 );
EE_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
wxCHECK( selectionTool, 0 );
EE_SELECTION& selection = selectionTool->GetSelection();
if( selection.GetSize() == 1 && selection.Front()->Type() == SCH_MARKER_T )
{
if( !m_ercDialog->IsShown() )
m_ercDialog->Show( true );
if( !dlg->IsShown() )
dlg->Show( true );
m_ercDialog->SelectMarker( static_cast<SCH_MARKER*>( selection.Front() ) );
}
dlg->SelectMarker( static_cast<SCH_MARKER*>( selection.Front() ) );
}
// Show the item info on a left click on this item
@ -190,14 +186,20 @@ int EE_INSPECTION_TOOL::ExcludeMarker( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 1 && selection.Front()->Type() == SCH_MARKER_T )
marker = static_cast<SCH_MARKER*>( selection.Front() );
if( m_ercDialog )
{
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( frame, 0 );
DIALOG_ERC* dlg = frame->GetErcDialog();
wxCHECK( dlg, 0 );
// Let the ERC dialog handle it since it has more update hassles to worry about
// Note that if marker is nullptr the dialog will exclude whichever marker is selected
// in the dialog itself
m_ercDialog->ExcludeMarker( marker );
}
else if( marker != nullptr )
dlg->ExcludeMarker( marker );
if( marker != nullptr )
{
marker->SetExcluded( true );
m_frame->GetCanvas()->GetView()->Update( marker );
@ -244,8 +246,9 @@ int EE_INSPECTION_TOOL::CheckSymbol( const TOOL_EVENT& aEvent )
int EE_INSPECTION_TOOL::DiffSymbol( const TOOL_EVENT& aEvent )
{
if( !m_frame->IsType( FRAME_SCH ) )
return 0;
SCH_EDIT_FRAME* schEditorFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
wxCHECK( schEditorFrame, 0 );
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_SYMBOL_T } );
@ -255,14 +258,9 @@ int EE_INSPECTION_TOOL::DiffSymbol( const TOOL_EVENT& aEvent )
return 0;
}
wxWindow* window = wxWindow::FindWindowByName( DIFF_SYMBOLS_DIALOG_NAME );
DIALOG_BOOK_REPORTER* dialog = dynamic_cast<DIALOG_BOOK_REPORTER*>( window );
DIALOG_BOOK_REPORTER* dialog = schEditorFrame->GetSymbolDiffDialog();
if( !dialog )
{
dialog = new DIALOG_BOOK_REPORTER( m_frame, DIFF_SYMBOLS_DIALOG_NAME,
_( "Diff Symbol with Library" ) );
}
wxCHECK( dialog, 0 );
dialog->DeleteAllPages();
@ -278,7 +276,8 @@ int EE_INSPECTION_TOOL::DiffSymbol( const TOOL_EVENT& aEvent )
r->Report( wxS( "<h7>" ) + _( "Schematic vs library diff for:" ) + wxS( "</h7>" ) );
r->Report( wxS( "<ul><li>" ) + EscapeHTML( symbolDesc ) + wxS( "</li>" )
+ wxS( "<li>" ) + _( "Library: " ) + EscapeHTML( libName ) + wxS( "</li>" )
+ wxS( "<li>" ) + _( "Library item: " ) + EscapeHTML( symbolName ) + wxS( "</li></ul>" ) );
+ wxS( "<li>" ) + _( "Library item: " ) + EscapeHTML( symbolName )
+ wxS( "</li></ul>" ) );
r->Report( "" );

View File

@ -49,7 +49,6 @@ public:
int RunERC( const TOOL_EVENT& aEvent );
void ShowERCDialog();
void DestroyERCDialog();
int PrevMarker( const TOOL_EVENT& aEvent );
int NextMarker( const TOOL_EVENT& aEvent );
@ -76,7 +75,6 @@ private:
void setTransitions() override;
private:
DIALOG_ERC* m_ercDialog;
};
#endif /* EE_INSPECTION_TOOL_H */

View File

@ -30,16 +30,18 @@ class KIWAY_PLAYER;
class WX_HTML_REPORT_BOX;
class wxHtmlLinkEvent;
/**
* Event sent to parent when dialog is mode-less.
*/
wxDECLARE_EVENT( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, wxCommandEvent );
class DIALOG_BOOK_REPORTER : public DIALOG_BOOK_REPORTER_BASE
{
public:
DIALOG_BOOK_REPORTER( KIWAY_PLAYER* aParent, const wxString& aDialogName,
DIALOG_BOOK_REPORTER( KIWAY_PLAYER* aParent, const wxString& aName,
const wxString& aDialogTitle );
void OnOK( wxCommandEvent& aEvent ) override
{
Destroy();
}
void OnClose( wxCloseEvent& aEvent ) override;
void OnErrorLinkClicked( wxHtmlLinkEvent& aEvent );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2009-2015 Jean-Pierre Charras, jp.charras wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -89,7 +89,7 @@ struct WINDOW_STATE;
/// This is the handler functor for the update UI events
typedef std::function< void( wxUpdateUIEvent& ) > UIUpdateHandler;
wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent );
wxDECLARE_EVENT( EDA_EVT_UNITS_CHANGED, wxCommandEvent );
/**

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -61,7 +61,7 @@ struct MAGNETIC_SETTINGS;
class NL_PCBNEW_PLUGIN;
class PROGRESS_REPORTER;
wxDECLARE_EVENT( BOARD_CHANGED, wxCommandEvent );
wxDECLARE_EVENT( EDA_EVT_BOARD_CHANGED, wxCommandEvent );
/**
* Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
@ -382,6 +382,10 @@ public:
virtual void ActivateGalCanvas() override;
void AddBoardChangeListener( wxEvtHandler* aListener );
void RemoveBoardChangeListener( wxEvtHandler* aListener );
protected:
bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
@ -413,6 +417,8 @@ protected:
private:
NL_PCBNEW_PLUGIN* m_spaceMouse;
std::vector<wxEvtHandler*> m_boardChangeListeners;
};
#endif // PCB_BASE_FRAME_H

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2016 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -143,7 +143,8 @@ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS( PCB_EDIT
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnNetFilterSelect ),
nullptr, this );
m_parent->Bind( UNITS_CHANGED, &DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::onUnitsChanged, this );
m_parent->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::onUnitsChanged,
this );
finishDialogSettings();
}
@ -165,7 +166,8 @@ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS()
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnNetFilterSelect ),
nullptr, this );
m_parent->Unbind( UNITS_CHANGED, &DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::onUnitsChanged, this );
m_parent->Unbind( EDA_EVT_UNITS_CHANGED,
&DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::onUnitsChanged, this );
delete[] m_originalColWidths;
}

View File

@ -50,6 +50,9 @@
#include <vector>
wxDEFINE_EVENT( EDA_EVT_CLOSE_NET_INSPECTOR_DIALOG, wxCommandEvent );
static DIALOG_NET_INSPECTOR::SETTINGS g_settings;
@ -62,7 +65,8 @@ enum class CSV_COLUMN_DESC : int
struct DIALOG_NET_INSPECTOR::COLUMN_DESC
{
COLUMN_DESC( unsigned aNum, PCB_LAYER_ID aLayer, const wxString& aDisp, const wxString& aCsv, CSV_COLUMN_DESC aFlags ) :
COLUMN_DESC( unsigned aNum, PCB_LAYER_ID aLayer, const wxString& aDisp, const wxString& aCsv,
CSV_COLUMN_DESC aFlags ) :
num( aNum ), layer( aLayer ), display_name( aDisp ), csv_name( aCsv ), csv_flags( aFlags )
{}
@ -94,30 +98,6 @@ enum
class DIALOG_NET_INSPECTOR::LIST_ITEM
{
private:
// an item can be the child of only one parent at a time.
// FIXME: could use a more lightweight container like intrusive forward list.
LIST_ITEM* m_parent = nullptr;
std::vector<LIST_ITEM*> m_children;
bool m_is_group = false;
unsigned int m_group_number = 0;
NETINFO_ITEM* m_net = nullptr;
unsigned int m_pad_count = 0;
unsigned int m_via_count = 0;
uint64_t m_via_length = 0;
uint64_t m_chip_wire_length = 0;
std::array<uint64_t, MAX_CU_LAYERS> m_layer_wire_length{};
// dirty bits to record when some attribute has changed. this is to
// avoid unnecessary resort operations.
std::vector<char> m_column_changed;
// cached formatted net name for faster display sorting.
wxString m_net_name;
public:
LIST_ITEM( unsigned int aGroupNumber, const wxString& aGroupName ) :
m_is_group( true ),
@ -162,7 +142,7 @@ public:
std::fill( m_column_changed.begin(), m_column_changed.end(), 0 );
}
decltype( m_pad_count ) GetPadCount() const
unsigned int GetPadCount() const
{
return m_pad_count;
}
@ -172,7 +152,7 @@ public:
return m_column_changed[COLUMN_PAD_COUNT];
}
void SetPadCount( const decltype( m_pad_count ) &aValue )
void SetPadCount( unsigned int aValue )
{
if( m_parent )
m_parent->SetPadCount( m_parent->GetPadCount() - m_pad_count + aValue );
@ -181,7 +161,7 @@ public:
m_pad_count = aValue;
}
void AddPadCount( const decltype( m_pad_count ) &aValue )
void AddPadCount( unsigned int aValue )
{
if( m_parent )
m_parent->AddPadCount( aValue );
@ -190,7 +170,7 @@ public:
m_pad_count += aValue;
}
void SubPadCount( const decltype( m_pad_count ) &aValue )
void SubPadCount( unsigned int aValue )
{
if( m_parent )
m_parent->SubPadCount( aValue );
@ -209,7 +189,7 @@ public:
return m_column_changed[COLUMN_VIA_COUNT];
}
void SetViaCount( const decltype( m_via_count ) &aValue )
void SetViaCount( unsigned int aValue )
{
if( m_parent )
m_parent->SetViaCount( m_parent->GetViaCount() - m_via_count + aValue );
@ -218,7 +198,7 @@ public:
m_via_count = aValue;
}
void AddViaCount( const decltype( m_via_count ) &aValue )
void AddViaCount( unsigned int aValue )
{
if( m_parent )
m_parent->AddViaCount( aValue );
@ -227,7 +207,7 @@ public:
m_via_count += aValue;
}
void SubViaCount( const decltype( m_via_count ) &aValue )
void SubViaCount( unsigned int aValue )
{
if( m_parent )
m_parent->SubViaCount( aValue );
@ -246,7 +226,7 @@ public:
return m_column_changed[COLUMN_VIA_LENGTH];
}
void SetViaLength( const decltype( m_via_length ) &aValue )
void SetViaLength( unsigned int aValue )
{
if( m_parent )
m_parent->SetViaLength( m_parent->GetViaLength() - m_via_length + aValue );
@ -255,7 +235,7 @@ public:
m_via_length = aValue;
}
void AddViaLength( const decltype( m_via_length ) &aValue )
void AddViaLength( unsigned int aValue )
{
if( m_parent )
m_parent->AddViaLength( aValue );
@ -264,7 +244,7 @@ public:
m_via_length += aValue;
}
void SubViaLength( const decltype( m_via_length ) &aValue )
void SubViaLength( uint64_t aValue )
{
if( m_parent )
m_parent->SubViaLength( aValue );
@ -335,7 +315,7 @@ public:
return m_column_changed[COLUMN_CHIP_LENGTH];
}
void SetChipWireLength( const decltype( m_chip_wire_length ) &aValue )
void SetChipWireLength( uint64_t aValue )
{
if( m_parent )
m_parent->SetChipWireLength(
@ -345,7 +325,7 @@ public:
m_chip_wire_length = aValue;
}
void AddChipWireLength( const decltype( m_chip_wire_length ) &aValue )
void AddChipWireLength( uint64_t aValue )
{
if( m_parent )
m_parent->AddChipWireLength( aValue );
@ -354,7 +334,7 @@ public:
m_chip_wire_length += aValue;
}
void SubChipWireLength( const decltype( m_chip_wire_length ) &aValue )
void SubChipWireLength( uint64_t aValue )
{
if( m_parent )
m_parent->SubChipWireLength( aValue );
@ -362,7 +342,6 @@ public:
m_column_changed[COLUMN_CHIP_LENGTH] |= ( aValue != 0 );
m_chip_wire_length -= aValue;
}
;
// the total length column is always computed, never stored.
unsigned long long int GetTotalLength() const
@ -416,6 +395,29 @@ public:
m_parent->m_children.push_back( this );
}
}
private:
// an item can be the child of only one parent at a time.
// FIXME: could use a more lightweight container like intrusive forward list.
LIST_ITEM* m_parent = nullptr;
std::vector<LIST_ITEM*> m_children;
bool m_is_group = false;
unsigned int m_group_number = 0;
NETINFO_ITEM* m_net = nullptr;
unsigned int m_pad_count = 0;
unsigned int m_via_count = 0;
uint64_t m_via_length = 0;
uint64_t m_chip_wire_length = 0;
std::array<uint64_t, MAX_CU_LAYERS> m_layer_wire_length{};
// dirty bits to record when some attribute has changed. this is to
// avoid unnecessary resort operations.
std::vector<char> m_column_changed;
// cached formatted net name for faster display sorting.
wxString m_net_name;
};
@ -443,15 +445,6 @@ struct DIALOG_NET_INSPECTOR::LIST_ITEM_NETCODE_CMP_LESS
class DIALOG_NET_INSPECTOR::DATA_MODEL : public wxDataViewModel
{
private:
DIALOG_NET_INSPECTOR& m_parent;
// primary container, sorted by netcode number.
// groups have netcode < 0, so they always come first, in the order
// of the filter strings as input by the user (group mode 0, 1) or
// in order of occurrence (group mode 2, 3).
std::vector<std::unique_ptr<LIST_ITEM>> m_items;
public:
DATA_MODEL( DIALOG_NET_INSPECTOR& parent ) : m_parent( parent )
@ -618,7 +611,8 @@ public:
if( match )
{
wxString match_str = i->GetNetName().substr( match.start, match.length );
wxString match_str = i->GetNetName().substr( match.start,
match.length );
auto group = std::find_if( groups.begin(), groups.end(),
[&]( const std::unique_ptr<LIST_ITEM>& x )
@ -956,24 +950,39 @@ protected:
{
return wxS( "string" );
}
private:
DIALOG_NET_INSPECTOR& m_parent;
// primary container, sorted by netcode number.
// groups have netcode < 0, so they always come first, in the order
// of the filter strings as input by the user (group mode 0, 1) or
// in order of occurrence (group mode 2, 3).
std::vector<std::unique_ptr<LIST_ITEM>> m_items;
};
DIALOG_NET_INSPECTOR::DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent, const wxString& aDialogName ) :
DIALOG_NET_INSPECTOR::DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent ) :
DIALOG_NET_INSPECTOR_BASE( aParent ),
m_zero_netitem( nullptr ),
m_frame( aParent )
{
SetName( aDialogName );
m_columns.emplace_back( 0u, UNDEFINED_LAYER, _( "Net" ), _( "Net Code" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 1u, UNDEFINED_LAYER, _( "Name" ), _( "Net Name" ), CSV_COLUMN_DESC::CSV_QUOTE );
m_columns.emplace_back( 2u, UNDEFINED_LAYER, _( "Pad Count" ), _( "Pad Count" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 3u, UNDEFINED_LAYER, _( "Via Count" ), _( "Via Count" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 4u, UNDEFINED_LAYER, _( "Via Length" ), _( "Via Length" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 5u, UNDEFINED_LAYER, _( "Track Length" ), _( "Track Length" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 6u, UNDEFINED_LAYER, _( "Die Length" ), _( "Die Length" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 7u, UNDEFINED_LAYER, _( "Total Length" ), _( "Net Length" ), CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 0u, UNDEFINED_LAYER, _( "Net" ), _( "Net Code" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 1u, UNDEFINED_LAYER, _( "Name" ), _( "Net Name" ),
CSV_COLUMN_DESC::CSV_QUOTE );
m_columns.emplace_back( 2u, UNDEFINED_LAYER, _( "Pad Count" ), _( "Pad Count" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 3u, UNDEFINED_LAYER, _( "Via Count" ), _( "Via Count" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 4u, UNDEFINED_LAYER, _( "Via Length" ), _( "Via Length" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 5u, UNDEFINED_LAYER, _( "Track Length" ), _( "Track Length" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 6u, UNDEFINED_LAYER, _( "Die Length" ), _( "Die Length" ),
CSV_COLUMN_DESC::CSV_NONE );
m_columns.emplace_back( 7u, UNDEFINED_LAYER, _( "Total Length" ), _( "Net Length" ),
CSV_COLUMN_DESC::CSV_NONE );
m_brd = aParent->GetBoard();
@ -989,44 +998,51 @@ DIALOG_NET_INSPECTOR::DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent, const wxStr
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_NAME].display_name, m_columns[COLUMN_NAME],
m_netsList->AppendTextColumn( m_columns[COLUMN_NAME].display_name,
m_columns[COLUMN_NAME],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_REORDERABLE |
wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_PAD_COUNT].display_name, m_columns[COLUMN_PAD_COUNT],
m_netsList->AppendTextColumn( m_columns[COLUMN_PAD_COUNT].display_name,
m_columns[COLUMN_PAD_COUNT],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_VIA_COUNT].display_name, m_columns[COLUMN_VIA_COUNT],
m_netsList->AppendTextColumn( m_columns[COLUMN_VIA_COUNT].display_name,
m_columns[COLUMN_VIA_COUNT],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_VIA_LENGTH].display_name, m_columns[COLUMN_VIA_LENGTH],
m_netsList->AppendTextColumn( m_columns[COLUMN_VIA_LENGTH].display_name,
m_columns[COLUMN_VIA_LENGTH],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_BOARD_LENGTH].display_name, m_columns[COLUMN_BOARD_LENGTH],
m_netsList->AppendTextColumn( m_columns[COLUMN_BOARD_LENGTH].display_name,
m_columns[COLUMN_BOARD_LENGTH],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_CHIP_LENGTH].display_name, m_columns[COLUMN_CHIP_LENGTH],
m_netsList->AppendTextColumn( m_columns[COLUMN_CHIP_LENGTH].display_name,
m_columns[COLUMN_CHIP_LENGTH],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
},
[&]()
{
m_netsList->AppendTextColumn( m_columns[COLUMN_TOTAL_LENGTH].display_name, m_columns[COLUMN_TOTAL_LENGTH],
m_netsList->AppendTextColumn( m_columns[COLUMN_TOTAL_LENGTH].display_name,
m_columns[COLUMN_TOTAL_LENGTH],
wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_SORTABLE );
}
@ -1095,19 +1111,8 @@ DIALOG_NET_INSPECTOR::DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent, const wxStr
finishDialogSettings();
m_frame->Bind( wxEVT_CLOSE_WINDOW,
[this]( wxCloseEvent& aEvent )
{
Close();
aEvent.Skip();
} );
m_frame->Connect( UNITS_CHANGED,
wxCommandEventHandler( DIALOG_NET_INSPECTOR::onUnitsChanged ),
nullptr, this );
m_frame->Connect( BOARD_CHANGED,
wxCommandEventHandler( DIALOG_NET_INSPECTOR::onBoardChanged ),
nullptr, this );
Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_NET_INSPECTOR::onUnitsChanged, this );
Bind( EDA_EVT_BOARD_CHANGED, &DIALOG_NET_INSPECTOR::onBoardChanged, this );
if( m_brd != nullptr )
{
@ -1133,7 +1138,8 @@ DIALOG_NET_INSPECTOR::~DIALOG_NET_INSPECTOR()
g_settings.group_by = m_groupBy->IsChecked();
g_settings.group_by_kind = m_groupByKind->GetSelection();
g_settings.group_by_text = m_groupByText->GetValue();
g_settings.sorting_column = sorting_column ? static_cast<int>( sorting_column->GetModelColumn() ) : -1;
g_settings.sorting_column = sorting_column ?
static_cast<int>( sorting_column->GetModelColumn() ) : -1;
g_settings.sort_order_asc = sorting_column ? sorting_column->IsSortOrderAscending() : true;
g_settings.column_order = column_order;
@ -1142,23 +1148,17 @@ DIALOG_NET_INSPECTOR::~DIALOG_NET_INSPECTOR()
// from now on. so just disassociate it.
m_netsList->AssociateModel( nullptr );
m_frame->Disconnect( UNITS_CHANGED,
wxCommandEventHandler( DIALOG_NET_INSPECTOR::onUnitsChanged ),
nullptr, this );
m_frame->Disconnect( BOARD_CHANGED,
wxCommandEventHandler( DIALOG_NET_INSPECTOR::onBoardChanged ),
nullptr, this );
Unbind( EDA_EVT_UNITS_CHANGED, &DIALOG_NET_INSPECTOR::onUnitsChanged, this );
Unbind( EDA_EVT_BOARD_CHANGED, &DIALOG_NET_INSPECTOR::onBoardChanged, this );
if( m_brd != nullptr )
m_brd->RemoveListener( this );
m_frame->GetCanvas()->SetFocus();
}
void DIALOG_NET_INSPECTOR::onUnitsChanged( wxCommandEvent& event )
{
this->m_units = m_frame->GetUserUnits();
m_units = m_frame->GetUserUnits();
m_data_model->updateAllItems();
@ -1636,7 +1636,8 @@ DIALOG_NET_INSPECTOR::buildNewItem( NETINFO_ITEM* aNet, unsigned int aPadCount,
else if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
{
new_item->AddLayerWireLength( track->GetLength(), static_cast<int>( track->GetLayer() ) );
new_item->AddLayerWireLength( track->GetLength(),
static_cast<int>( track->GetLayer() ) );
if( item->Type() == PCB_VIA_T )
{
@ -2241,3 +2242,21 @@ void DIALOG_NET_INSPECTOR::onReport( wxCommandEvent& aEvent )
f.Write();
f.Close();
}
void DIALOG_NET_INSPECTOR::onClose( wxCloseEvent& aEvent )
{
// Dialog is mode-less so let the parent know that it needs to be destroyed.
if( !IsModal() && !IsQuasiModal() )
{
wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_NET_INSPECTOR_DIALOG, wxID_ANY );
evt->SetEventObject( this );
wxWindow* parent = GetParent();
if( parent )
wxQueueEvent( parent, evt );
}
aEvent.Skip();
}

View File

@ -37,6 +37,11 @@ class CN_ITEM;
class EDA_PATTERN_MATCH;
class PCB_TRACK;
/**
* Event sent to parent when dialog is mode-less.
*/
wxDECLARE_EVENT( EDA_EVT_CLOSE_NET_INSPECTOR_DIALOG, wxCommandEvent );
class DIALOG_NET_INSPECTOR : public DIALOG_NET_INSPECTOR_BASE, public BOARD_LISTENER
{
public:
@ -53,18 +58,23 @@ public:
std::vector<int> column_order;
};
DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent, const wxString& aDialogName );
DIALOG_NET_INSPECTOR( PCB_EDIT_FRAME* aParent );
~DIALOG_NET_INSPECTOR();
virtual void OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override;
virtual void OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override;
virtual void OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardItemsRemoved( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardNetSettingsChanged( BOARD& aBoard ) override;
virtual void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override;
virtual void OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardItemsChanged( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) override;
protected:
virtual void onClose( wxCloseEvent& aEvent ) override;
private:
struct COLUMN_DESC;
class LIST_ITEM;

View File

@ -73,16 +73,16 @@ DIALOG_NET_INSPECTOR_BASE::DIALOG_NET_INSPECTOR_BASE( wxWindow* parent, wxWindow
bSizerListButtons = new wxBoxSizer( wxHORIZONTAL );
m_addNet = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_addNet, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
bSizerListButtons->Add( m_addNet, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_renameNet = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_renameNet, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
bSizerListButtons->Add( m_renameNet, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
bSizerListButtons->Add( 20, 0, 0, wxEXPAND, 5 );
m_deleteNet = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_deleteNet, 0, wxALL, 5 );
bSizerListButtons->Add( m_deleteNet, 0, wxALIGN_CENTER_VERTICAL, 5 );
bSizerListButtons->Add( 0, 0, 1, wxEXPAND, 5 );
@ -101,6 +101,7 @@ DIALOG_NET_INSPECTOR_BASE::DIALOG_NET_INSPECTOR_BASE( wxWindow* parent, wxWindow
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_NET_INSPECTOR_BASE::onClose ) );
m_textCtrlFilter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );
m_cbShowZeroPad->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );
m_groupBy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );
@ -118,6 +119,7 @@ DIALOG_NET_INSPECTOR_BASE::DIALOG_NET_INSPECTOR_BASE( wxWindow* parent, wxWindow
DIALOG_NET_INSPECTOR_BASE::~DIALOG_NET_INSPECTOR_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_NET_INSPECTOR_BASE::onClose ) );
m_textCtrlFilter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );
m_cbShowZeroPad->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );
m_groupBy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NET_INSPECTOR_BASE::onFilterChange ), NULL, this );

View File

@ -56,6 +56,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnClose">onClose</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
@ -522,14 +523,14 @@
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="0">
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerListButtons</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property>
@ -603,7 +604,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property>
@ -687,7 +688,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property>

View File

@ -55,6 +55,7 @@ class DIALOG_NET_INSPECTOR_BASE : public DIALOG_SHIM
wxButton* m_ReportButt;
// Virtual event handlers, override them in your derived class
virtual void onClose( wxCloseEvent& event ) { event.Skip(); }
virtual void onFilterChange( wxCommandEvent& event ) { event.Skip(); }
virtual void onSortingChanged( wxDataViewEvent& event ) { event.Skip(); }
virtual void onSelChanged( wxDataViewEvent& event ) { event.Skip(); }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 CERN
* Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -388,7 +388,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
SetupStandardButtons();
m_frame->Bind( UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
m_netSelector->Bind( NET_SELECTED, &DIALOG_TRACK_VIA_PROPERTIES::onNetSelector, this );
// Now all widgets have the size fixed, call FinishDialogSettings
@ -398,7 +398,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
DIALOG_TRACK_VIA_PROPERTIES::~DIALOG_TRACK_VIA_PROPERTIES()
{
m_frame->Unbind( UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
}

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2018-2023 KiCad Developers, see change_log.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
@ -95,7 +95,7 @@ PANEL_SETUP_TEXT_AND_GRAPHICS::PANEL_SETUP_TEXT_AND_GRAPHICS( PAGED_DIALOG* aPar
m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
m_Frame->Bind( UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
m_Frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
}
@ -104,7 +104,7 @@ PANEL_SETUP_TEXT_AND_GRAPHICS::~PANEL_SETUP_TEXT_AND_GRAPHICS()
// destroy GRID_TRICKS before m_grid.
m_grid->PopEventHandler( true );
m_Frame->Unbind( UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
m_Frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
}
@ -151,8 +151,10 @@ bool PANEL_SETUP_TEXT_AND_GRAPHICS::TransferDataToWindow()
SET_MILS_CELL( i, COL_TEXT_WIDTH, m_BrdSettings->m_TextSize[ i ].x );
SET_MILS_CELL( i, COL_TEXT_HEIGHT, m_BrdSettings->m_TextSize[ i ].y );
SET_MILS_CELL( i, COL_TEXT_THICKNESS, m_BrdSettings->m_TextThickness[ i ] );
m_grid->SetCellValue( i, COL_TEXT_ITALIC, m_BrdSettings->m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
m_grid->SetCellValue( i, COL_TEXT_UPRIGHT, m_BrdSettings->m_TextUpright[ i ] ? wxT( "1" ) : wxT( "" ) );
m_grid->SetCellValue( i, COL_TEXT_ITALIC,
m_BrdSettings->m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
m_grid->SetCellValue( i, COL_TEXT_UPRIGHT,
m_BrdSettings->m_TextUpright[ i ] ? wxT( "1" ) : wxT( "" ) );
auto attr = new wxGridCellAttr;
attr->SetRenderer( new wxGridCellBoolRenderer() );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2018-2023 KiCad Developers, see change_log.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
@ -122,7 +122,7 @@ PANEL_SETUP_TRACKS_AND_VIAS::PANEL_SETUP_TRACKS_AND_VIAS( PAGED_DIALOG* aParent,
}
}
m_Frame->Bind( UNITS_CHANGED, &PANEL_SETUP_TRACKS_AND_VIAS::onUnitsChanged, this );
m_Frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TRACKS_AND_VIAS::onUnitsChanged, this );
}
@ -133,7 +133,7 @@ PANEL_SETUP_TRACKS_AND_VIAS::~PANEL_SETUP_TRACKS_AND_VIAS()
m_viaSizesGrid->PopEventHandler( true );
m_diffPairsGrid->PopEventHandler( true );
m_Frame->Unbind( UNITS_CHANGED, &PANEL_SETUP_TRACKS_AND_VIAS::onUnitsChanged, this );
m_Frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TRACKS_AND_VIAS::onUnitsChanged, this );
}

View File

@ -69,7 +69,7 @@ FP_TEXT_GRID_TABLE::FP_TEXT_GRID_TABLE( PCB_BASE_FRAME* aFrame ) :
m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
m_frame->Bind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
}
@ -80,7 +80,7 @@ FP_TEXT_GRID_TABLE::~FP_TEXT_GRID_TABLE()
m_orientationColAttr->DecRef();
m_layerColAttr->DecRef();
m_frame->Unbind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2018 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 CERN
*
* This program is free software; you can redistribute it and/or
@ -70,12 +70,13 @@
using KIGFX::RENDER_SETTINGS;
using KIGFX::PCB_RENDER_SETTINGS;
wxDEFINE_EVENT( BOARD_CHANGED, wxCommandEvent );
wxDEFINE_EVENT( EDA_EVT_BOARD_CHANGED, wxCommandEvent );
PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName ) :
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, pcbIUScale ),
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName,
pcbIUScale ),
m_pcb( nullptr ),
m_originTransforms( *this ),
m_spaceMouse( nullptr )
@ -226,9 +227,41 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
}
}
wxCommandEvent e( BOARD_CHANGED );
wxCommandEvent e( EDA_EVT_BOARD_CHANGED );
ProcessEventLocally( e );
for( wxEvtHandler* listener : m_boardChangeListeners )
{
wxCHECK2( listener, continue );
wxWindow* win = dynamic_cast<wxWindow*>( listener );
if( win )
win->HandleWindowEvent( e );
else
listener->SafelyProcessEvent( e );
}
}
}
void PCB_BASE_FRAME::AddBoardChangeListener( wxEvtHandler* aListener )
{
auto it = std::find( m_boardChangeListeners.begin(), m_boardChangeListeners.end(), aListener );
// Don't add duplicate listeners.
if( it == m_boardChangeListeners.end() )
m_boardChangeListeners.push_back( aListener );
}
void PCB_BASE_FRAME::RemoveBoardChangeListener( wxEvtHandler* aListener )
{
auto it = std::find( m_boardChangeListeners.begin(), m_boardChangeListeners.end(), aListener );
// Don't add duplicate listeners.
if( it != m_boardChangeListeners.end() )
m_boardChangeListeners.erase( it );
}

View File

@ -38,6 +38,7 @@
#include <dialog_find.h>
#include <dialog_footprint_properties.h>
#include <dialogs/dialog_exchange_footprints.h>
#include <dialogs/dialog_net_inspector.h>
#include <dialog_board_setup.h>
#include <invoke_pcb_dialog.h>
#include <board.h>
@ -114,6 +115,12 @@
using namespace std::placeholders;
#define INSPECT_DRC_ERROR_DIALOG_NAME wxT( "InspectDrcErrorDialog" )
#define INSPECT_CLEARANCE_DIALOG_NAME wxT( "InspectClearanceDialog" )
#define INSPECT_CONSTRAINTS_DIALOG_NAME wxT( "InspectConstraintsDialog" )
#define FOOTPRINT_DIFF_DIALOG_NAME wxT( "FootprintDiffDialog" )
BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, PCB_EDIT_FRAME::OnSockRequestServer )
EVT_SOCKET( ID_EDA_SOCKET_EVENT, PCB_EDIT_FRAME::OnSockRequest )
@ -183,7 +190,13 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
PCB_EDIT_FRAME_NAME ),
m_exportNetlistAction( nullptr ), m_findDialog( nullptr )
m_exportNetlistAction( nullptr ),
m_findDialog( nullptr ),
m_inspectDrcErrorDlg( nullptr ),
m_inspectClearanceDlg( nullptr ),
m_inspectConstraintsDlg( nullptr ),
m_footprintDiffDlg( nullptr ),
m_netInspectorDlg( nullptr )
{
m_maximizeByDefault = true;
m_showBorderAndTitleBlock = true; // true to display sheet references
@ -407,9 +420,9 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
wxFileName appK2S( strK2S, wxT( "kicad2step" ) );
#ifdef _WIN32
#ifdef _WIN32
appK2S.SetExt( wxT( "exe" ) );
#endif
#endif
// Ensure the window is on top
Raise();
@ -457,6 +470,11 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_eventCounterTimer->Start( 1000 );
}
Bind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs,
this );
Bind( EDA_EVT_CLOSE_NET_INSPECTOR_DIALOG, &PCB_EDIT_FRAME::onCloseNetInspectorDialog, this );
Bind( EDA_EVT_UNITS_CHANGED, &PCB_EDIT_FRAME::onUnitsChanged, this );
m_acceptedExts.emplace( KiCadPcbFileExtension, &PCB_ACTIONS::ddAppendBoard );
m_acceptedExts.emplace( LegacyPcbFileExtension, &PCB_ACTIONS::ddAppendBoard );
DragAcceptFiles( true );
@ -467,17 +485,12 @@ PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
{
if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
{
// Stop the timer during destruction early to avoid potential event race conditions (that do happen on windows)
// Stop the timer during destruction early to avoid potential event race conditions (that
// do happen on windows)
m_eventCounterTimer->Stop();
delete m_eventCounterTimer;
}
// Close modeless dialogs
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
if( open_dlg )
open_dlg->Close( true );
// Shutdown all running tools
if( m_toolManager )
m_toolManager->ShutdownAllTools();
@ -1059,13 +1072,6 @@ bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
}
}
// Close modeless dialogs. They're trouble when they get destroyed after the frame and/or
// board.
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
if( open_dlg )
open_dlg->Close( true );
return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
}
@ -1082,6 +1088,54 @@ void PCB_EDIT_FRAME::doCloseWindow()
GetCanvas()->StopDrawing();
// Clean up mode-less dialogs.
Unbind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER,
&PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs, this );
Unbind( EDA_EVT_CLOSE_NET_INSPECTOR_DIALOG, &PCB_EDIT_FRAME::onCloseNetInspectorDialog, this );
Unbind( EDA_EVT_UNITS_CHANGED, &PCB_EDIT_FRAME::onUnitsChanged, this );
wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
if( open_dlg )
open_dlg->Close( true );
if( m_findDialog )
{
m_findDialog->Destroy();
m_findDialog = nullptr;
}
if( m_inspectDrcErrorDlg )
{
m_inspectDrcErrorDlg->Destroy();
m_inspectDrcErrorDlg = nullptr;
}
if( m_inspectClearanceDlg )
{
m_inspectClearanceDlg->Destroy();
m_inspectClearanceDlg = nullptr;
}
if( m_inspectConstraintsDlg )
{
m_inspectConstraintsDlg->Destroy();
m_inspectConstraintsDlg = nullptr;
}
if( m_footprintDiffDlg )
{
m_footprintDiffDlg->Destroy();
m_footprintDiffDlg = nullptr;
}
if( m_netInspectorDlg )
{
RemoveBoardChangeListener( m_netInspectorDlg );
m_netInspectorDlg->Destroy();
m_netInspectorDlg = nullptr;
}
// Delete the auto save file if it exists.
wxFileName fn = GetBoard()->GetFileName();
@ -2338,3 +2392,100 @@ void PCB_EDIT_FRAME::onSize( wxSizeEvent& aEvent )
// Skip() is called in the base class.
EDA_DRAW_FRAME::OnSize( aEvent );
}
DIALOG_BOOK_REPORTER* PCB_EDIT_FRAME::GetInspectDrcErrorDialog()
{
if( !m_inspectDrcErrorDlg )
m_inspectDrcErrorDlg = new DIALOG_BOOK_REPORTER( this, INSPECT_DRC_ERROR_DIALOG_NAME,
_( "Violation Report" ) );
return m_inspectDrcErrorDlg;
}
DIALOG_BOOK_REPORTER* PCB_EDIT_FRAME::GetInspectClearanceDialog()
{
if( !m_inspectClearanceDlg )
m_inspectClearanceDlg = new DIALOG_BOOK_REPORTER( this, INSPECT_CLEARANCE_DIALOG_NAME,
_( "Clearance Report" ) );
return m_inspectClearanceDlg;
}
DIALOG_BOOK_REPORTER* PCB_EDIT_FRAME::GetInspectConstraintsDialog()
{
if( !m_inspectConstraintsDlg )
m_inspectConstraintsDlg = new DIALOG_BOOK_REPORTER( this, INSPECT_CONSTRAINTS_DIALOG_NAME,
_( "Constraints Report" ) );
return m_inspectConstraintsDlg;
}
DIALOG_BOOK_REPORTER* PCB_EDIT_FRAME::GetFootprintDiffDialog()
{
if( !m_footprintDiffDlg )
m_footprintDiffDlg = new DIALOG_BOOK_REPORTER( this, FOOTPRINT_DIFF_DIALOG_NAME,
_( "Diff Footprint with Library" ) );
return m_footprintDiffDlg;
}
void PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs( wxCommandEvent& aEvent )
{
if( m_inspectDrcErrorDlg && aEvent.GetString() == INSPECT_DRC_ERROR_DIALOG_NAME )
{
m_inspectDrcErrorDlg->Destroy();
m_inspectDrcErrorDlg = nullptr;
}
else if( m_inspectClearanceDlg && aEvent.GetString() == INSPECT_CLEARANCE_DIALOG_NAME )
{
m_inspectClearanceDlg->Destroy();
m_inspectClearanceDlg = nullptr;
}
else if( m_inspectConstraintsDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
{
m_inspectConstraintsDlg->Destroy();
m_inspectConstraintsDlg = nullptr;
}
else if( m_footprintDiffDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
{
m_footprintDiffDlg->Destroy();
m_footprintDiffDlg = nullptr;
}
}
DIALOG_NET_INSPECTOR* PCB_EDIT_FRAME::GetNetInspectorDialog()
{
if( !m_netInspectorDlg )
{
m_netInspectorDlg = new DIALOG_NET_INSPECTOR( this );
AddBoardChangeListener( m_netInspectorDlg );
}
return m_netInspectorDlg;
}
void PCB_EDIT_FRAME::onCloseNetInspectorDialog( wxCommandEvent& aEvent )
{
if( m_netInspectorDlg )
{
RemoveBoardChangeListener( m_netInspectorDlg );
m_netInspectorDlg->Destroy();
m_netInspectorDlg = nullptr;
}
}
void PCB_EDIT_FRAME::onUnitsChanged( wxCommandEvent& aEvent )
{
wxCommandEvent evt( EDA_EVT_UNITS_CHANGED );
if( m_netInspectorDlg )
m_netInspectorDlg->HandleWindowEvent( evt );
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2010-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2010-2023 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
@ -30,6 +30,8 @@ class PCB_SCREEN;
class BOARD;
class BOARD_COMMIT;
class BOARD_ITEM_CONTAINER;
class DIALOG_BOOK_REPORTER;
class DIALOG_NET_INSPECTOR;
class FOOTPRINT;
class PCB_TRACK;
class PCB_VIA;
@ -702,6 +704,16 @@ public:
TOOL_ACTION* GetExportNetlistAction() { return m_exportNetlistAction; }
DIALOG_BOOK_REPORTER* GetInspectDrcErrorDialog();
DIALOG_BOOK_REPORTER* GetInspectConstraintsDialog();
DIALOG_BOOK_REPORTER* GetInspectClearanceDialog();
DIALOG_BOOK_REPORTER* GetFootprintDiffDialog();
DIALOG_NET_INSPECTOR* GetNetInspectorDialog();
DECLARE_EVENT_TABLE()
protected:
@ -805,6 +817,12 @@ protected:
void saveProjectSettings() override;
void onCloseModelessBookReporterDialogs( wxCommandEvent& aEvent );
void onCloseNetInspectorDialog( wxCommandEvent& aEvent );
void onUnitsChanged( wxCommandEvent& aEvent );
public:
PCB_LAYER_BOX_SELECTOR* m_SelLayerBox; // a combo box to display and select active layer
@ -832,6 +850,11 @@ private:
TOOL_ACTION* m_exportNetlistAction;
DIALOG_FIND* m_findDialog;
DIALOG_BOOK_REPORTER* m_inspectDrcErrorDlg;
DIALOG_BOOK_REPORTER* m_inspectClearanceDlg;
DIALOG_BOOK_REPORTER* m_inspectConstraintsDlg;
DIALOG_BOOK_REPORTER* m_footprintDiffDlg;
DIALOG_NET_INSPECTOR* m_netInspectorDlg;
/**
* Keep track of viewport so that track net labels can be adjusted when it changes.

View File

@ -32,6 +32,7 @@
#include <drc/drc_engine.h>
#include <dialogs/dialog_board_statistics.h>
#include <dialogs/dialog_book_reporter.h>
#include <dialogs/dialog_net_inspector.h>
#include <dialogs/panel_setup_rules_base.h>
#include <string_utils.h>
#include <tools/board_inspection_tool.h>
@ -44,12 +45,6 @@
#include <pad.h>
#define LIST_NETS_DIALOG_NAME wxT( "ListNetsDialog" )
#define INSPECT_CLEARANCE_DIALOG_NAME wxT( "InspectClearanceDialog" )
#define INSPECT_CONSTRAINTS_DIALOG_NAME wxT( "InspectConstraintsDialog" )
#define DIFF_FOOTPRINTS_DIALOG_NAME wxT( "DiffFootprintsDialog" )
BOARD_INSPECTION_TOOL::BOARD_INSPECTION_TOOL() :
PCB_TOOL_BASE( "pcbnew.InspectionTool" ),
m_frame( nullptr )
@ -248,14 +243,12 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
BOARD_CONNECTED_ITEM* ac = dynamic_cast<BOARD_CONNECTED_ITEM*>( a );
BOARD_CONNECTED_ITEM* bc = dynamic_cast<BOARD_CONNECTED_ITEM*>( b );
PCB_LAYER_ID layer = m_frame->GetActiveLayer();
wxWindow* window = wxWindow::FindWindowByName( INSPECT_CLEARANCE_DIALOG_NAME );
DIALOG_BOOK_REPORTER* dialog = dynamic_cast<DIALOG_BOOK_REPORTER*>( window );
if( !dialog )
{
dialog = new DIALOG_BOOK_REPORTER( m_frame, INSPECT_CLEARANCE_DIALOG_NAME,
_( "Violation Report" ) );
}
wxCHECK( m_frame, /* void */ );
DIALOG_BOOK_REPORTER* dialog = m_frame->GetInspectDrcErrorDialog();
wxCHECK( dialog, /* void */ );
WX_HTML_REPORT_BOX* r = nullptr;
bool compileError = false;
@ -478,7 +471,8 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
{
layer = b->GetLayer();
}
else if( a->Type() == PCB_PAD_T && static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB::SMD )
else if( a->Type() == PCB_PAD_T
&& static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB::SMD )
{
PAD* pad = static_cast<PAD*>( a );
@ -487,7 +481,8 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
else
layer = B_Cu;
}
else if( b->Type() == PCB_PAD_T && static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB::SMD )
else if( b->Type() == PCB_PAD_T
&& static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB::SMD )
{
PAD* pad = static_cast<PAD*>( b );
@ -553,7 +548,12 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
{
wxCHECK( m_frame, 0 );
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
wxCHECK( selTool, 0 );
const PCB_SELECTION& selection = selTool->GetSelection();
if( selection.Size() != 2 )
@ -596,14 +596,9 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
// a and b could be null after group tests above.
wxCHECK( a && b, 0 );
wxWindow* window = wxWindow::FindWindowByName( INSPECT_CLEARANCE_DIALOG_NAME );
DIALOG_BOOK_REPORTER* dialog = dynamic_cast<DIALOG_BOOK_REPORTER*>( window );
DIALOG_BOOK_REPORTER* dialog = m_frame->GetInspectClearanceDialog();
if( !dialog )
{
dialog = new DIALOG_BOOK_REPORTER( m_frame, INSPECT_CLEARANCE_DIALOG_NAME,
_( "Clearance Report" ) );
}
wxCHECK( dialog, 0 );
dialog->DeleteAllPages();
@ -722,8 +717,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
clearance = constraint.m_Value.Min();
r->Report( "" );
r->Report( wxString::Format( _( "Overridden by larger physical hole clearance from %s;"
"clearance: %s." ),
r->Report( wxString::Format( _( "Overridden by larger physical hole clearance "
"from %s; clearance: %s." ),
EscapeHTML( constraint.GetName() ),
m_frame->StringFromValue( clearance, true ) ) );
}
@ -781,7 +776,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
if( clearance < 0 )
{
r->Report( wxString::Format( _( "Resolved clearance: %s; clearance will not be tested." ),
r->Report( wxString::Format( _( "Resolved clearance: %s; clearance will not be "
"tested." ),
m_frame->StringFromValue( clearance, true ) ) );
}
else
@ -817,7 +813,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( "" );
r->Report( "" );
r->Report( "" );
reportHeader( _( "Diff pair max uncoupled length resolution for:" ), ac, bc, active, r );
reportHeader( _( "Diff pair max uncoupled length resolution for:" ), ac, bc,
active, r );
if( !drcEngine.HasRulesForConstraintType( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT ) )
{
@ -1132,7 +1129,12 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
{
#define EVAL_RULES( constraint, a, b, layer, r ) drcEngine.EvalRules( constraint, a, b, layer, r )
wxCHECK( m_frame, 0 );
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
wxCHECK( selTool, 0 );
const PCB_SELECTION& selection = selTool->GetSelection();
if( selection.Size() != 1 )
@ -1141,14 +1143,9 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
return 0;
}
wxWindow* window = wxWindow::FindWindowByName( INSPECT_CONSTRAINTS_DIALOG_NAME );
DIALOG_BOOK_REPORTER* dialog = dynamic_cast<DIALOG_BOOK_REPORTER*>( window );
DIALOG_BOOK_REPORTER* dialog = m_frame->GetInspectConstraintsDialog();
if( !dialog )
{
dialog = new DIALOG_BOOK_REPORTER( m_frame, INSPECT_CONSTRAINTS_DIALOG_NAME,
_( "Constraints Report" ) );
}
wxCHECK( dialog, 0 );
dialog->DeleteAllPages();
@ -1287,7 +1284,8 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
r->Report( "" );
r->Report( _( "Report may be incomplete: some footprint courtyards are malformed." )
+ wxS( "&nbsp;&nbsp;" )
+ wxS( "<a href='$DRC'>" ) + _( "Run DRC for a full analysis." ) + wxS( "</a>" ) );
+ wxS( "<a href='$DRC'>" ) + _( "Run DRC for a full analysis." )
+ wxS( "</a>" ) );
}
r->Report( "" );
@ -1310,7 +1308,8 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
r->Report( "" );
r->Report( _( "Report may be incomplete: some footprint courtyards are malformed." )
+ wxS( "&nbsp;&nbsp;" )
+ wxS( "<a href='$DRC'>" ) + _( "Run DRC for a full analysis." ) + wxS( "</a>" ) );
+ wxS( "<a href='$DRC'>" ) + _( "Run DRC for a full analysis." )
+ wxS( "</a>" ) );
}
drcEngine.ProcessAssertions( item, []( const DRC_CONSTRAINT* c ){}, r );
@ -1324,7 +1323,12 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
int BOARD_INSPECTION_TOOL::DiffFootprint( const TOOL_EVENT& aEvent )
{
wxCHECK( m_frame, 0 );
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
wxCHECK( selTool, 0 );
const PCB_SELECTION& selection = selTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
@ -1341,18 +1345,14 @@ int BOARD_INSPECTION_TOOL::DiffFootprint( const TOOL_EVENT& aEvent )
if( selection.Size() != 1 )
{
m_frame->ShowInfoBarError( _( "Select a footprint to diff against its library equivalent." ) );
m_frame->ShowInfoBarError( _( "Select a footprint to diff against its library "
"equivalent." ) );
return 0;
}
wxWindow* window = wxWindow::FindWindowByName( DIFF_FOOTPRINTS_DIALOG_NAME );
DIALOG_BOOK_REPORTER* dialog = dynamic_cast<DIALOG_BOOK_REPORTER*>( window );
DIALOG_BOOK_REPORTER* dialog = m_frame->GetFootprintDiffDialog();
if( !dialog )
{
dialog = new DIALOG_BOOK_REPORTER( m_frame, DIFF_FOOTPRINTS_DIALOG_NAME,
_( "Diff Footprint with Library" ) );
}
wxCHECK( dialog, 0 );
dialog->DeleteAllPages();
@ -1387,14 +1387,16 @@ int BOARD_INSPECTION_TOOL::DiffFootprint( const TOOL_EVENT& aEvent )
{
r->Report( _( "The library is not included in the current configuration." )
+ wxS( "&nbsp;&nbsp;&nbsp" )
+ wxS( "<a href='$CONFIG'>" ) + _( "Manage Footprint Libraries" ) + wxS( "</a>" ) );
+ wxS( "<a href='$CONFIG'>" ) + _( "Manage Footprint Libraries" )
+ wxS( "</a>" ) );
}
else if( !libTable->HasLibrary( libName, true ) )
{
r->Report( _( "The library is not enabled in the current configuration." )
+ wxS( "&nbsp;&nbsp;&nbsp" )
+ wxS( "<a href='$CONFIG'>" ) + _( "Manage Footprint Libraries" ) + wxS( "</a>" ) );
+ wxS( "<a href='$CONFIG'>" ) + _( "Manage Footprint Libraries" )
+ wxS( "</a>" ) );
}
else
@ -1870,11 +1872,11 @@ void BOARD_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta )
int BOARD_INSPECTION_TOOL::ListNets( const TOOL_EVENT& aEvent )
{
wxWindow* window = wxWindow::FindWindowByName( LIST_NETS_DIALOG_NAME );
DIALOG_NET_INSPECTOR* dialog = dynamic_cast<DIALOG_NET_INSPECTOR*>( window );
wxCHECK( m_frame, 0 );
if( !dialog )
dialog = new DIALOG_NET_INSPECTOR( m_frame, LIST_NETS_DIALOG_NAME );
DIALOG_NET_INSPECTOR* dialog = m_frame->GetNetInspectorDialog();
wxCHECK( dialog, 0 );
dialog->Raise();
dialog->Show( true );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022-2023 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
@ -30,10 +30,12 @@ PCB_SEARCH_PANE::PCB_SEARCH_PANE( PCB_EDIT_FRAME* aFrame ) :
if( m_brd != nullptr )
m_brd->AddListener( this );
m_pcbFrame->Connect( UNITS_CHANGED, wxCommandEventHandler( PCB_SEARCH_PANE::onUnitsChanged ),
m_pcbFrame->Connect( EDA_EVT_UNITS_CHANGED,
wxCommandEventHandler( PCB_SEARCH_PANE::onUnitsChanged ),
nullptr, this );
m_pcbFrame->Connect( BOARD_CHANGED, wxCommandEventHandler( PCB_SEARCH_PANE::onBoardChanged ),
m_pcbFrame->Connect( EDA_EVT_BOARD_CHANGED,
wxCommandEventHandler( PCB_SEARCH_PANE::onBoardChanged ),
nullptr, this );
wxFont infoFont = KIUI::GetDockedPaneFont( this );
@ -49,9 +51,11 @@ PCB_SEARCH_PANE::PCB_SEARCH_PANE( PCB_EDIT_FRAME* aFrame ) :
PCB_SEARCH_PANE::~PCB_SEARCH_PANE()
{
m_pcbFrame->Disconnect( UNITS_CHANGED, wxCommandEventHandler( PCB_SEARCH_PANE::onUnitsChanged ),
m_pcbFrame->Disconnect( EDA_EVT_UNITS_CHANGED,
wxCommandEventHandler( PCB_SEARCH_PANE::onUnitsChanged ),
nullptr, this );
m_pcbFrame->Disconnect( BOARD_CHANGED, wxCommandEventHandler( PCB_SEARCH_PANE::onBoardChanged ),
m_pcbFrame->Disconnect( EDA_EVT_BOARD_CHANGED,
wxCommandEventHandler( PCB_SEARCH_PANE::onBoardChanged ),
nullptr, this );
}