Compare commits

...

28 Commits

Author SHA1 Message Date
modbw
ff7a520096 Merge branch 'fix-invalid-filename' into 'master'
Fix invalid filename on windows

See merge request kicad/code/kicad!2290
2025-09-11 06:40:59 +00:00
Seth Hillbrand
fcf40deae2 Scale down icons that are too big
In template view, if the icon is too big, try to fit to our size
2025-09-10 21:58:02 -07:00
Seth Hillbrand
ef602be91f Allow drawing subsheet with click+drag
Interestingly, the majority of people in a KiCad training course wanted
to draw subsheets this way.  There is no real reason to keep the
existing select behavior, so this greases some skids
2025-09-10 21:55:31 -07:00
Seth Hillbrand
bd5cb76fcd Sync pin shape between sheet/hier labels 2025-09-10 21:47:09 -07:00
Seth Hillbrand
de26550b5a Add stubs for compiling 2025-09-10 21:23:37 -07:00
Seth Hillbrand
7deff606be Update Pybind11 to 3.0.1 2025-09-10 13:02:24 -07:00
Seth Hillbrand
6e2b20ed0e Update BS Threadpool to 5.0 2025-09-10 13:02:24 -07:00
Jeff Young
2f1a91279f Make sure DRC inspection dialogs come up in front
of DRC dialog.
2025-09-10 17:52:09 +01:00
Jeff Young
6e316d9faa ADDED: menu items to control cross-probing from ERC
dialog.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17916
2025-09-10 17:52:09 +01:00
Jeff Young
3c5fb9d90d CHANGED: progressive disclosure in DRC dialog.
CHANGED: moved Report All Track Errors to config menu.

ADDED: menu items to control cross-probing from DRC
dialog.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17916
2025-09-10 17:52:09 +01:00
jean-pierre charras
11cc86e586 Hotkey handling: disable usage of keyboard modifier flag wxMOD_ALTGR.
The flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
So AltGr key cannot used as modifier key because it is the same as
Alt key + Ctrl key that is already handled.
So the previous code did not work with modifiers Alt key, Ctrl key and Altgr key

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21696
2025-09-10 18:10:43 +02:00
Roberto Fernandez Bautista
5e2fd084b9 Disable vcpkg compiler tracking 2025-09-10 09:48:50 +00:00
Seth Hillbrand
a1f816e8be Add additional modifies to hotkeys
Allows (depending on system) AltGr, Meta, Win, Super in combination with
other keys

Fixes https://gitlab.com/kicad/code/kicad/issues/1908
2025-09-09 13:30:01 -07:00
Seth Hillbrand
abf3438ed6 Remove noise from orthographic projection raytracing
We generally add some jitter to the raytracing lines in order to smooth
out over multiple iterations some of the imperfections.  However, when
we do this to an orthographic projection (where all lines are parallel
to start, we don't average and just introduce noticeable noise in the
render

Fixes https://gitlab.com/kicad/code/kicad/issues/8863
2025-09-09 13:16:57 -07:00
Seth Hillbrand
cb4c8e6647 Make global delete tracks remove tuning patterns
If we are removing the generated item, we should remove the generator as
well

Fixes https://gitlab.com/kicad/code/kicad/issues/21572
2025-09-09 13:06:52 -07:00
Seth Hillbrand
d356073798 ADDED: synthetic parameters for graphics
Allows editing start/end/radius instead of underlying properties

Fixes https://gitlab.com/kicad/code/kicad/issues/16279
2025-09-09 12:58:43 -07:00
Mark Roszko
b38d9d7f81 Edit Windows-CI.yml, remove after_script 2025-09-09 15:47:03 +00:00
Mark Roszko
297ca1bb7b Fix windows builds with a temporary hackfix for now 2025-09-09 11:12:39 -04:00
Seth Hillbrand
f9e25c2e06 ADDED: Cross-probing from 3d-viewer
Send cross-probe messages to pcb and schematic editors to highlight
objects when clicked in the 3d viewer
2025-09-09 07:50:51 -07:00
Seth Hillbrand
b0a6dc4acf Use actual value for symbol chooser options
When we moved to the single element, the pointer always resolved to
true, which was sometimes not what we wanted
2025-09-09 07:16:28 -07:00
Seth Hillbrand
59dcdb4a4f ADDED: proper icons for datasheet and fp in props
The properties panel needs to look like the data fields for user
experience.  In wx3.3 we get a helpful action button but until then, we
need to make our own
2025-09-09 07:12:27 -07:00
jean-pierre charras
39889f8446 fix a compil issue. 2025-09-09 15:41:28 +02:00
Seth Hillbrand
3f8abe3744 Update properties to show units
The function duplicated our built-in funcitonality and did not properly
handly outputs

Fixes https://gitlab.com/kicad/code/kicad/issues/21685
2025-09-09 06:39:39 -07:00
Seth Hillbrand
0acc659676 Try to fix MSW build error 2025-09-09 06:15:30 -07:00
Jeff Young
78c93ee0fb Clear stale local ratsnest flags when performing undo/redo.
Also removes some dangerous C-style casts.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17894
2025-09-09 14:09:19 +01:00
jean-pierre charras
9622cf8ff1 SCH_BITMAP, SCH_TABLE: add missing HitTest(SHAPE_LINE_CHAIN& aPoly, ...)
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21669
2025-09-09 09:45:46 +02:00
jean-pierre charras
3cca1e87d8 French translation update 2025-09-09 09:45:46 +02:00
modbw
ae88fe5d48 Fix invalid filename on windows
Replace ':' with '_' as this is an invalid character in windows filenames
2025-08-21 12:40:26 -04:00
406 changed files with 36951 additions and 10961 deletions

View File

@ -9,6 +9,7 @@ win64_build:
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/ltsc2022-msvc:latest
variables:
VCPKG_BINARY_SOURCES: 'nuget,gitlab,readwrite'
VCPKG_DISABLE_COMPILER_TRACKING: '1'
# Switch the compressor to fastzip and reduce the compression level
FF_USE_FASTZIP: "true"
CACHE_COMPRESSION_LEVEL: "fast"
@ -39,8 +40,6 @@ win64_build:
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../
after_script:
- Get-Content -Path C:\builder\vcpkg\buildtrees\wxpython-33\python3-tool-post-install-err.log
artifacts:
# Only save the artifacts that are needed for running the tests in the next stage
# and the compilation log. The entire build directory is too large to save as an

View File

@ -35,14 +35,22 @@
#include <advanced_config.h>
#include <build_version.h>
#include <board.h>
#include <pad.h>
#include <pcb_field.h>
#include <reporter.h>
#include <gal/opengl/gl_context_mgr.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <bitmaps.h>
#include <kiway_holder.h>
#include <kiway.h>
#include <macros.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <tool/tool_dispatcher.h>
#include <string_utils.h>
#include <mail_type.h>
#include <kiway_express.h>
#include <fmt/format.h>
#include <widgets/wx_busy_indicator.h>
@ -95,25 +103,9 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, aGLAttribs,
EDA_3D_CANVAS_ID, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_eventDispatcher( nullptr ),
m_parentStatusBar( nullptr ),
m_parentInfoBar( nullptr ),
m_glRC( nullptr ),
m_is_opengl_initialized( false ),
m_is_opengl_version_supported( true ),
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
m_render_pivot( false ),
m_camera_moving_speed( 1.0f ),
m_strtime_camera_movement( 0 ),
m_animation_enabled( true ),
m_moving_speed_multiplier( 3 ),
m_boardAdapter( aBoardAdapter ),
m_3d_render( nullptr ),
m_opengl_supports_raytracing( true ),
m_render_raytracing_was_requested( false ),
m_accelerator3DShapes( nullptr ),
m_currentRollOverItem( nullptr )
m_boardAdapter( aBoardAdapter )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
@ -482,7 +474,9 @@ void EDA_3D_CANVAS::DoRePaint()
if( m_camera_is_moving )
{
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
curtime_delta_s = ( curtime_delta / 1e6 ) * m_camera_moving_speed;
// Convert microseconds to seconds as float and apply speed multiplier
curtime_delta_s = static_cast<float>( static_cast<double>( curtime_delta ) / 1e6 )
* m_camera_moving_speed;
m_camera.Interpolate( curtime_delta_s );
if( curtime_delta_s > 1.0f )
@ -751,7 +745,8 @@ void EDA_3D_CANVAS::RenderToFrameBuffer( unsigned char* buffer, int width, int h
if( m_camera_is_moving )
{
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
curtime_delta_s = ( curtime_delta / 1e6 ) * m_camera_moving_speed;
curtime_delta_s = static_cast<float>( static_cast<double>( curtime_delta ) / 1e6 )
* m_camera_moving_speed;
m_camera.Interpolate( curtime_delta_s );
if( curtime_delta_s > 1.0f )
@ -887,7 +882,7 @@ void EDA_3D_CANVAS::OnZoomGesture( wxZoomGestureEvent& aEvent )
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
m_camera.Zoom( aEvent.GetZoomFactor() / m_gestureLastZoomFactor );
m_camera.Zoom( static_cast<float>( aEvent.GetZoomFactor() / m_gestureLastZoomFactor ) );
m_gestureLastZoomFactor = aEvent.GetZoomFactor();
@ -930,7 +925,7 @@ void EDA_3D_CANVAS::OnRotateGesture( wxRotateGestureEvent& aEvent )
if( m_camera_is_moving )
return;
m_camera.RotateScreen( m_gestureLastAngle - aEvent.GetRotationAngle() );
m_camera.RotateScreen( static_cast<float>( m_gestureLastAngle - aEvent.GetRotationAngle() ) );
m_gestureLastAngle = aEvent.GetRotationAngle();
DisplayStatus();
@ -1068,7 +1063,43 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
BOARD_ITEM* intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
// !TODO: send a selection item to pcbnew, eg: via kiway?
if( intersectedBoardItem )
{
FOOTPRINT* footprint = nullptr;
switch( intersectedBoardItem->Type() )
{
case PCB_FOOTPRINT_T:
footprint = static_cast<FOOTPRINT*>( intersectedBoardItem );
break;
case PCB_PAD_T:
footprint = static_cast<PAD*>( intersectedBoardItem )->GetParentFootprint();
break;
case PCB_FIELD_T:
footprint = static_cast<PCB_FIELD*>( intersectedBoardItem )->GetParentFootprint();
break;
default:
break;
}
if( footprint )
{
std::string command =
fmt::format( "$SELECT: 0,F{}",
EscapeString( footprint->GetReference(), CTX_IPC ).ToStdString() );
EDA_3D_VIEWER_FRAME* frame = static_cast<EDA_3D_VIEWER_FRAME*>( GetParent() );
if( frame )
{
frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_SELECTION, command, frame );
frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SELECTION, command, frame );
}
}
}
}
}
@ -1088,14 +1119,14 @@ void EDA_3D_CANVAS::OnLeftUp( wxMouseEvent& event )
int logicalW = logicalSize.GetWidth();
int logicalH = logicalSize.GetHeight();
int gizmo_x, gizmo_y, gizmo_width, gizmo_height;
int gizmo_x = 0, gizmo_y = 0, gizmo_width = 0, gizmo_height = 0;
std::tie( gizmo_x, gizmo_y, gizmo_width, gizmo_height ) = m_3d_render_opengl->getGizmoViewport();
float scaleX = static_cast<float>( gizmo_width ) / logicalW;
float scaleY = static_cast<float>( gizmo_height ) / logicalH;
float scaleX = static_cast<float>( static_cast<double>( gizmo_width ) / static_cast<double>( logicalW ) );
float scaleY = static_cast<float>( static_cast<double>( gizmo_height ) / static_cast<double>( logicalH ) );
int scaledMouseX = static_cast<int>( event.GetX() * scaleX );
int scaledMouseY = static_cast<int>( ( logicalH - event.GetY() ) * scaleY );
int scaledMouseX = static_cast<int>( static_cast<float>( event.GetX() ) * scaleX );
int scaledMouseY = static_cast<int>( static_cast<float>( logicalH - event.GetY() ) * scaleY );
m_3d_render_opengl->handleGizmoMouseInput( scaledMouseX, scaledMouseY );
Refresh();
@ -1229,7 +1260,7 @@ void EDA_3D_CANVAS::request_start_moving_camera( float aMovingSpeed, bool aRende
// Map speed multiplier option to actual multiplier value
// [1,2,3,4,5] -> [0.25, 0.5, 1, 2, 4]
aMovingSpeed *= ( 1 << m_moving_speed_multiplier ) / 8.0f;
aMovingSpeed *= static_cast<float>( ( 1 << m_moving_speed_multiplier ) ) / 8.0f;
m_render_pivot = aRenderPivot;
m_camera_moving_speed = aMovingSpeed;
@ -1249,7 +1280,7 @@ void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
{
RAY mouseRay = getRayAtCurrentMousePosition();
float hit_t;
float hit_t = 0.0f;
// Test it with the board bounding box
if( m_boardAdapter.GetBBox().Intersect( mouseRay, &hit_t ) )

View File

@ -42,7 +42,7 @@ class RENDER_3D_RAYTRACE_GL;
class RENDER_3D_OPENGL;
#define EDA_3D_CANVAS_ID wxID_HIGHEST + 1321
#define EDA_3D_CANVAS_ID (wxID_HIGHEST + 1321)
/**
* Implement a canvas based on a wxGLCanvas
@ -61,7 +61,7 @@ public:
EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs, BOARD_ADAPTER& aSettings,
CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
~EDA_3D_CANVAS();
~EDA_3D_CANVAS() override;
/**
* Set a dispatcher that processes events and forwards them to tools.
@ -302,36 +302,36 @@ private:
RAY getRayAtCurrentMousePosition();
private:
TOOL_DISPATCHER* m_eventDispatcher;
wxStatusBar* m_parentStatusBar; // Parent statusbar to report progress
WX_INFOBAR* m_parentInfoBar;
TOOL_DISPATCHER* m_eventDispatcher = nullptr;
wxStatusBar* m_parentStatusBar = nullptr; // Parent statusbar to report progress
WX_INFOBAR* m_parentInfoBar = nullptr;
wxGLContext* m_glRC; // Current OpenGL context
bool m_is_opengl_initialized;
bool m_is_opengl_version_supported;
wxGLContext* m_glRC = nullptr; // Current OpenGL context
bool m_is_opengl_initialized = false;
bool m_is_opengl_version_supported = true;
wxTimer m_editing_timeout_timer; // Expires after some time signaling that
// the mouse / keyboard movements are over
wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
std::atomic_flag m_is_currently_painting = ATOMIC_FLAG_INIT; // Avoid drawing twice at the same time
bool m_render_pivot; // Render the pivot while camera moving
float m_camera_moving_speed; // 1.0f will be 1:1
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
bool m_animation_enabled; // Camera animation enabled
int m_moving_speed_multiplier; // Camera animation speed multiplier option
bool m_render_pivot = false; // Render the pivot while camera moving
float m_camera_moving_speed = 1.0f; // 1.0f will be 1:1
int64_t m_strtime_camera_movement = 0; // Ticktime of camera movement start
bool m_animation_enabled = true; // Camera animation enabled
int m_moving_speed_multiplier = 3; // Camera animation speed multiplier option
BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
RENDER_3D_BASE* m_3d_render;
RENDER_3D_BASE* m_3d_render = nullptr;
RENDER_3D_RAYTRACE_GL* m_3d_render_raytracing;
RENDER_3D_OPENGL* m_3d_render_opengl;
bool m_opengl_supports_raytracing;
bool m_render_raytracing_was_requested;
bool m_opengl_supports_raytracing = true;
bool m_render_raytracing_was_requested = false;
ACCELERATOR_3D* m_accelerator3DShapes; // used for mouse over searching
ACCELERATOR_3D* m_accelerator3DShapes = nullptr; // used for mouse over searching
BOARD_ITEM* m_currentRollOverItem;
BOARD_ITEM* m_currentRollOverItem = nullptr;
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot

View File

@ -277,7 +277,7 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR
BS::multi_future<void> futures;
for( size_t i = 0; i < tp.get_thread_count(); ++i )
futures.push_back( tp.submit( processBlocks ) );
futures.push_back( tp.submit_task( processBlocks ) );
futures.wait();
@ -486,9 +486,12 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
// Initialize ray packets
const SFVEC2UI& blockPos = m_blockPositions[iBlock];
const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset );
const SFVEC2F randDisp = ( m_camera.GetProjection() == PROJECTION_TYPE::ORTHO ) ?
SFVEC2F( 0.0f, 0.0f ) :
SFVEC2F( DISP_FACTOR, DISP_FACTOR );
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) /* Displacement random factor */ );
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + randDisp,
randDisp /* Displacement random factor */ );
HITINFO_PACKET hitPacket_X0Y0[RAYPACKET_RAYS_PER_PACKET];
@ -566,7 +569,7 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f, 0.5f ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) );
randDisp );
if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
{
@ -603,16 +606,16 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - randDisp.x, randDisp.y ),
randDisp, blockRayPck_AA_X1Y0 );
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( randDisp.x, 0.5f - randDisp.y ),
randDisp, blockRayPck_AA_X0Y1 );
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - randDisp.x, 0.25f - randDisp.y ),
randDisp, blockRayPck_AA_X1Y1_half );
renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X1Y0,
hitColor_AA_X1Y0 );

View File

@ -190,7 +190,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks()
};
for( size_t ii = 0; ii < num_elements; ++ii )
returns[ii] = tp.submit( db_thread );
returns[ii] = tp.submit_task( db_thread );
for( const std::future<size_t>& ret : returns )
{

View File

@ -1059,9 +1059,13 @@ std::vector<wxWindow*> EDA_DRAW_FRAME::findDialogs()
}
void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos )
void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos, bool aAllowScroll )
{
bool centerView = false;
std::vector<BOX2D> dialogScreenRects;
if( aAllowScroll )
{
BOX2D r = GetCanvas()->GetView()->GetViewport();
// Center if we're off the current view, or within 10% of its edge
@ -1070,8 +1074,6 @@ void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos )
if( !r.Contains( aPos ) )
centerView = true;
std::vector<BOX2D> dialogScreenRects;
for( wxWindow* dialog : findDialogs() )
{
dialogScreenRects.emplace_back( ToVECTOR2D( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ) ),
@ -1086,6 +1088,7 @@ void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos )
if( rect.Contains( GetCanvas()->GetView()->ToScreen( aPos ) ) )
centerView = true;
}
}
if( centerView )
{

View File

@ -27,6 +27,8 @@
#include <git2.h>
#include <vector>
#include <wx/string.h>
// TEMPORARY HACKFIX INCLUDE FOR STD::VECTOR EXPORT OUT OF KICOMMON ON WINDOWS
#include <settings/parameters.h>
class LIBGIT_BACKEND;

View File

@ -40,6 +40,7 @@
#include <wx/txtstrm.h>
#include <wx/wfstream.h>
#include <tool/tool_action.h>
#include <tool/tool_event.h>
/*
@ -159,6 +160,10 @@ static struct hotkey_name_descr hotkeyNameList[] =
#define MODIFIER_CMD_MAC wxT( "Cmd+" )
#define MODIFIER_CTRL_BASE wxT( "Ctrl+" )
#define MODIFIER_SHIFT wxT( "Shift+" )
#define MODIFIER_META wxT( "Meta+" )
#define MODIFIER_WIN wxT( "Win+" )
#define MODIFIER_SUPER wxT( "Super+" )
#define MODIFIER_ALTGR wxT( "AltGr+" )
wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
@ -175,6 +180,14 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' );
else if( aKeycode == WXK_ALT )
return wxString( MODIFIER_ALT ).BeforeFirst( '+' );
#ifdef WXK_WINDOWS_LEFT
else if( aKeycode == WXK_WINDOWS_LEFT || aKeycode == WXK_WINDOWS_RIGHT )
return wxString( MODIFIER_WIN ).BeforeFirst( '+' );
#endif
#ifdef WXK_META
else if( aKeycode == WXK_META )
return wxString( MODIFIER_META ).BeforeFirst( '+' );
#endif
// Assume keycode of 0 is "unassigned"
if( (aKeycode & MD_CTRL) != 0 )
@ -186,7 +199,16 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
if( (aKeycode & MD_SHIFT) != 0 )
modifier << MODIFIER_SHIFT;
aKeycode &= ~( MD_CTRL | MD_ALT | MD_SHIFT );
if( (aKeycode & MD_META) != 0 )
modifier << MODIFIER_META;
if( (aKeycode & MD_SUPER) != 0 )
modifier << MODIFIER_WIN;
if( (aKeycode & MD_ALTGR) != 0 )
modifier << MODIFIER_ALTGR;
aKeycode &= ~MD_MODIFIER_MASK;
if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
{
@ -262,7 +284,7 @@ int KeyCodeFromKeyName( const wxString& keyname )
{
int ii, keycode = KEY_NON_FOUND;
// Search for modifiers: Ctrl+ Alt+ and Shift+
// Search for modifiers: Ctrl+ Alt+ Shift+ and others
// Note: on Mac OSX, the Cmd key is equiv here to Ctrl
wxString key = keyname;
wxString prefix;
@ -292,6 +314,26 @@ int KeyCodeFromKeyName( const wxString& keyname )
modifier |= MD_SHIFT;
prefix = MODIFIER_SHIFT;
}
else if( key.StartsWith( MODIFIER_META ) )
{
modifier |= MD_META;
prefix = MODIFIER_META;
}
else if( key.StartsWith( MODIFIER_WIN ) )
{
modifier |= MD_SUPER;
prefix = MODIFIER_WIN;
}
else if( key.StartsWith( MODIFIER_SUPER ) )
{
modifier |= MD_SUPER;
prefix = MODIFIER_SUPER;
}
else if( key.StartsWith( MODIFIER_ALTGR ) )
{
modifier |= MD_ALTGR;
prefix = MODIFIER_ALTGR;
}
else
{
break;

View File

@ -24,6 +24,16 @@
#include <properties/pg_properties.h>
#include <widgets/color_swatch.h>
#include <widgets/unit_binder.h>
#include <bitmaps.h>
#include <frame_type.h>
#include <kiway_player.h>
#include <kiway.h>
#include <wx/filedlg.h>
#include <wx/intl.h>
#include <eda_doc.h>
#include <wx/button.h>
#include <wx/bmpbuttn.h>
#include <wx/log.h>
@ -31,6 +41,8 @@ const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" );
const wxString PG_FPID_EDITOR::EDITOR_NAME = wxS( "KiCadFpidEditor" );
const wxString PG_URL_EDITOR::EDITOR_NAME = wxS( "KiCadUrlEditor" );
PG_UNIT_EDITOR::PG_UNIT_EDITOR( EDA_DRAW_FRAME* aFrame ) :
@ -51,6 +63,9 @@ PG_UNIT_EDITOR::~PG_UNIT_EDITOR()
wxString PG_UNIT_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
@ -458,3 +473,164 @@ void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl )
"properties!" ) );
}
}
PG_FPID_EDITOR::PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame )
{
m_editorName = BuildEditorName( aFrame );
}
void PG_FPID_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame )
{
m_frame = aFrame;
m_editorName = BuildEditorName( aFrame );
}
wxString PG_FPID_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
wxPGWindowList PG_FPID_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const
{
wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
buttons->Add( KiBitmap( BITMAPS::small_library ) );
buttons->Finalize( aGrid, aPos );
wxSize textSize = buttons->GetPrimarySize();
wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
aProperty->GetValueAsString(), nullptr, 0,
aProperty->GetMaxLength() );
wxPGWindowList ret( textCtrl, buttons );
return ret;
}
bool PG_FPID_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const
{
if( aEvent.GetEventType() == wxEVT_BUTTON )
{
wxString fpid = aProperty->GetValue().GetString();
if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_frame ) )
{
if( frame->ShowModal( &fpid, m_frame ) )
aGrid->ChangePropertyValue( aProperty, fpid );
frame->Destroy();
}
return true;
}
return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
}
PG_URL_EDITOR::PG_URL_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame )
{
m_editorName = BuildEditorName( aFrame );
}
void PG_URL_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame )
{
m_frame = aFrame;
m_editorName = BuildEditorName( aFrame );
}
wxString PG_URL_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
wxPGWindowList PG_URL_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const
{
wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
// Use a folder icon when no datasheet is set; otherwise use a globe icon.
wxString urlValue = aProperty->GetValueAsString();
bool hasUrl = !( urlValue.IsEmpty() || urlValue == wxS( "~" ) );
buttons->Add( KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ) );
buttons->Finalize( aGrid, aPos );
wxSize textSize = buttons->GetPrimarySize();
wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
aProperty->GetValueAsString(), nullptr, 0,
aProperty->GetMaxLength() );
wxPGWindowList ret( textCtrl, buttons );
return ret;
}
bool PG_URL_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const
{
if( aEvent.GetEventType() == wxEVT_BUTTON )
{
wxString filename = aProperty->GetValue().GetString();
if( filename.IsEmpty() || filename == wxS( "~" ) )
{
wxFileDialog openFileDialog( m_frame, _( "Open file" ), wxS( "" ), wxS( "" ),
_( "All Files" ) + wxS( " (*.*)|*.*" ),
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( openFileDialog.ShowModal() == wxID_OK )
{
filename = openFileDialog.GetPath();
aGrid->ChangePropertyValue( aProperty, wxString::Format( wxS( "file://%s" ),
filename ) );
}
}
else
{
GetAssociatedDocument( m_frame, filename, &m_frame->Prj() );
}
// Update the button icon to reflect presence/absence of URL
if( wxObject* src = aEvent.GetEventObject() )
{
wxString newUrl = aProperty->GetValueAsString();
bool hasUrl = !( newUrl.IsEmpty() || newUrl == wxS( "~" ) );
auto bmp = KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder );
if( wxWindow* win = wxDynamicCast( src, wxWindow ) )
{
if( wxBitmapButton* bb = wxDynamicCast( win, wxBitmapButton ) )
{
bb->SetBitmap( bmp );
}
else if( wxButton* b = wxDynamicCast( win, wxButton ) )
{
b->SetBitmap( bmp );
}
else if( wxWindow* parent = win->GetParent() )
{
if( wxPGMultiButton* buttons = wxDynamicCast( parent, wxPGMultiButton ) )
{
wxWindow* btn0 = buttons->GetButton( 0 );
if( wxBitmapButton* bb0 = wxDynamicCast( btn0, wxBitmapButton ) )
bb0->SetBitmap( bmp );
else if( wxButton* b0 = wxDynamicCast( btn0, wxButton ) )
b0->SetBitmap( bmp );
}
}
}
}
return true;
}
return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
}

View File

@ -158,6 +158,43 @@ TOOL_DISPATCHER::~TOOL_DISPATCHER()
delete st;
}
int TOOL_DISPATCHER::decodeModifiers( const wxKeyboardState* aState )
{
int mods = 0;
int wxmods = aState->GetModifiers();
// Returns the state of key modifiers (Alt, Ctrl and so on). Be carefull:
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( wxmods & wxMOD_CONTROL )
mods |= MD_CTRL;
if( wxmods & wxMOD_ALT )
mods |= MD_ALT;
}
if( wxmods & wxMOD_SHIFT )
mods |= MD_SHIFT;
#ifdef wxMOD_META
if( wxmods & wxMOD_META )
mods |= MD_META;
#endif
#ifdef wxMOD_WIN
if( wxmods & wxMOD_WIN )
mods |= MD_SUPER;
#endif
return mods;
}
void TOOL_DISPATCHER::ResetState()
{
@ -297,7 +334,19 @@ static bool isKeyModifierOnly( int aKeyCode )
{
static std::vector<enum wxKeyCode> special_keys =
{
WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT
WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT,
#ifdef WXK_WINDOWS_LEFT
WXK_WINDOWS_LEFT, WXK_WINDOWS_RIGHT,
#endif
#ifdef WXK_MENU
WXK_MENU,
#endif
#ifdef WXK_COMMAND
WXK_COMMAND,
#endif
#ifdef WXK_META
WXK_META,
#endif
};
return alg::contains( special_keys, aKeyCode );
@ -515,7 +564,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
if( !evt && me->GetWheelRotation() != 0 )
{
const unsigned modBits =
static_cast<unsigned>( mods ) & ( MD_CTRL | MD_ALT | MD_SHIFT );
static_cast<unsigned>( mods ) & MD_MODIFIER_MASK;
const bool shouldHandle = std::popcount( modBits ) > 1;
if( shouldHandle )

View File

@ -149,6 +149,9 @@ const std::string TOOL_EVENT::Format() const
{ MD_SHIFT, "shift" },
{ MD_CTRL, "ctrl" },
{ MD_ALT, "alt" },
{ MD_SUPER, "super" },
{ MD_META, "meta" },
{ MD_ALTGR, "altgr" },
{ 0, "" }
};

View File

@ -640,15 +640,36 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL )
int mods = aKeyStroke.GetModifiers();
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL;
if( aKeyStroke.GetModifiers() & wxMOD_ALT )
if( mods & wxMOD_ALT )
hotkey += MD_ALT;
}
if( aKeyStroke.GetModifiers() & wxMOD_SHIFT )
if( mods & wxMOD_SHIFT )
hotkey += MD_SHIFT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey += MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
hotkey += MD_SUPER;
#endif
if( hotkey == ACTIONS::expandAll.GetHotKey()
|| hotkey == ACTIONS::expandAll.GetHotKeyAlt() )
{
@ -860,14 +881,31 @@ void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.ShiftDown() )
hotkey |= MD_SHIFT;
int mods = aKeyStroke.GetModifiers();
if( aKeyStroke.AltDown() )
if( mods & wxMOD_ALTGR )
hotkey |= MD_ALTGR;
else
{
if( mods & wxMOD_ALT )
hotkey |= MD_ALT;
if( aKeyStroke.ControlDown() )
if( mods & wxMOD_CONTROL )
hotkey |= MD_CTRL;
}
if( mods & wxMOD_SHIFT )
hotkey |= MD_SHIFT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey |= MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
hotkey |= MD_SUPER;
#endif
if( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) )
aKeyStroke.Skip( false );

View File

@ -670,7 +670,7 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
{
long key = aEvent.GetKeyCode();
bool is_tab = aEvent.IsKeyInCategory( WXK_CATEGORY_TAB );
printf("key %lX mod %X\n", key, aEvent.GetModifiers());
if( key == WXK_ESCAPE )
{
return 0;
@ -693,14 +693,35 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
*/
bool keyIsLetter = key >= 'A' && key <= 'Z';
if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
int mods = aEvent.GetModifiers();
if( ( mods & wxMOD_SHIFT ) && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
key |= MD_SHIFT;
if( aEvent.ControlDown() )
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
key |= MD_CTRL;
if( aEvent.AltDown() )
if( mods & wxMOD_ALT )
key |= MD_ALT;
}
#ifdef wxMOD_META
if( mods & wxMOD_META )
key |= MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
key |= MD_SUPER;
#endif
return key;
}

View File

@ -1614,10 +1614,9 @@ void CONNECTION_GRAPH::resolveAllDrivers()
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.parallelize_loop( dirty_graphs.size(),
[&]( const int a, const int b)
auto results = tp.submit_loop( 0, dirty_graphs.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
update_lambda( dirty_graphs[ii] );
});
results.wait();
@ -2257,10 +2256,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.parallelize_loop( m_driver_subgraphs.size(),
[&]( const int a, const int b)
auto results = tp.submit_loop( 0, m_driver_subgraphs.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
m_driver_subgraphs[ii]->UpdateItemConnections();
});
@ -2464,10 +2462,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
return 1;
};
auto results2 = tp.parallelize_loop( m_driver_subgraphs.size(),
[&]( const int a, const int b)
auto results2 = tp.submit_loop( 0, m_driver_subgraphs.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
updateItemConnectionsTask( m_driver_subgraphs[ii] );
} );
results2.wait();

View File

@ -42,6 +42,7 @@
#include <id.h>
#include <confirm.h>
#include <widgets/wx_html_report_box.h>
#include <widgets/std_bitmap_button.h>
#include <dialogs/dialog_text_entry.h>
#include <string_utils.h>
#include <kiplatform/ui.h>
@ -76,15 +77,15 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_running( false ),
m_ercRun( false ),
m_centerMarkerOnIdle( nullptr ),
m_severities( 0 )
m_crossprobe( true ),
m_scroll_on_crossprobe( true )
{
m_currentSchematic = &parent->Schematic();
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
KIPLATFORM::UI::SetFloatLevel( this );
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
m_severities = cfg->m_Appearance.erc_severities;
m_bMenu->SetBitmap( KiBitmapBundle( BITMAPS::config ) );
m_messages->SetImmediateMode();
@ -92,7 +93,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_markerTreeModel = new ERC_TREE_MODEL( parent, m_markerDataView );
m_markerDataView->AssociateModel( m_markerTreeModel );
m_markerTreeModel->Update( m_markerProvider, m_severities );
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
@ -129,8 +130,11 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
SetFocus();
syncCheckboxes();
updateDisplayedCounts();
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
{
m_crossprobe = cfg->m_ERCDialog.crossprobe;
m_scroll_on_crossprobe = cfg->m_ERCDialog.scroll_on_crossprobe;
}
// Now all widgets have the size fixed, call FinishDialogSettings
finishDialogSettings();
@ -148,7 +152,10 @@ DIALOG_ERC::~DIALOG_ERC()
g_lastERCIgnored.push_back( { m_ignoredList->GetItemText( ii ), m_ignoredList->GetItemData( ii ) } );
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
cfg->m_Appearance.erc_severities = m_severities;
{
cfg->m_ERCDialog.crossprobe = m_crossprobe;
cfg->m_ERCDialog.scroll_on_crossprobe = m_scroll_on_crossprobe;
}
m_markerTreeModel->DecRef();
}
@ -189,6 +196,59 @@ void DIALOG_ERC::UpdateAnnotationWarning()
}
int DIALOG_ERC::getSeverities()
{
int severities = 0;
if( m_showErrors->GetValue() )
severities |= RPT_SEVERITY_ERROR;
if( m_showWarnings->GetValue() )
severities |= RPT_SEVERITY_WARNING;
if( m_showExclusions->GetValue() )
severities |= RPT_SEVERITY_EXCLUSION;
return severities;
}
void DIALOG_ERC::OnMenu( wxCommandEvent& event )
{
// Build a pop menu:
wxMenu menu;
menu.Append( 4206, _( "Cross-probe Selected Items" ),
_( "Highlight corresponding items on canvas when selected in the ERC list" ),
wxITEM_CHECK );
menu.Check( 4206, m_crossprobe );
menu.Append( 4207, _( "Center on Cross-probe" ),
_( "When cross-probing, scroll the canvas so that the item is visible" ),
wxITEM_CHECK );
menu.Check( 4207, m_scroll_on_crossprobe );
// menu_id is the selected submenu id from the popup menu or wxID_NONE
int menu_id = m_bMenu->GetPopupMenuSelectionFromUser( menu );
if( menu_id == 0 || menu_id == 4206 )
{
m_crossprobe = !m_crossprobe;
}
else if( menu_id == 1 || menu_id == 4207 )
{
m_scroll_on_crossprobe = !m_scroll_on_crossprobe;
}
}
bool DIALOG_ERC::TransferDataToWindow()
{
UpdateData();
return true;
}
bool DIALOG_ERC::updateUI()
{
// If ERC checks ever get slow enough we'll want a progress indicator...
@ -217,6 +277,13 @@ void DIALOG_ERC::Report( const wxString& aMessage )
}
void DIALOG_ERC::UpdateData()
{
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
updateDisplayedCounts();
}
void DIALOG_ERC::updateDisplayedCounts()
{
int numErrors = 0;
@ -348,30 +415,14 @@ void DIALOG_ERC::OnCloseErcDialog( 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_ERC_DIALOG, wxID_ANY );
wxWindow* parent = GetParent();
if( parent )
wxQueueEvent( parent, evt );
if( wxWindow* parent = GetParent() )
wxQueueEvent( parent, new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY ) );
}
aEvent.Skip();
}
static int RPT_SEVERITY_ALL = RPT_SEVERITY_WARNING | RPT_SEVERITY_ERROR | RPT_SEVERITY_EXCLUSION;
void DIALOG_ERC::syncCheckboxes()
{
m_showAll->SetValue( m_severities == RPT_SEVERITY_ALL );
m_showErrors->SetValue( m_severities & RPT_SEVERITY_ERROR );
m_showWarnings->SetValue( m_severities & RPT_SEVERITY_WARNING );
m_showExclusions->SetValue( m_severities & RPT_SEVERITY_EXCLUSION );
}
void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
{
m_parent->OnAnnotate();
@ -446,8 +497,7 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
}
if( m_cancelled )
// @spellingerror
m_messages->Report( _( "-------- ERC canceled by user.<br><br>" ), RPT_SEVERITY_INFO );
m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
else
m_messages->Report( _( "Done.<br><br>" ), RPT_SEVERITY_INFO );
@ -508,7 +558,7 @@ void DIALOG_ERC::testErc()
}
// Update marker list:
m_markerTreeModel->Update( m_markerProvider, m_severities );
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
// Display new markers from the current screen:
for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
@ -523,6 +573,12 @@ void DIALOG_ERC::testErc()
void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
{
if( !m_crossprobe )
{
aEvent.Skip();
return;
}
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
SCH_SHEET_PATH sheet;
SCH_ITEM* item = m_parent->Schematic().ResolveItem( itemID, &sheet, true );
@ -568,7 +624,7 @@ void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
m_parent->RedrawScreen( m_parent->GetScreen()->m_ScrollCenter, false );
}
m_parent->FocusOnItem( item );
m_parent->FocusOnItem( item, m_scroll_on_crossprobe );
redrawDrawPanel();
}
@ -762,7 +818,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
m_parent->GetCanvas()->GetView()->Update( marker );
// Update view
if( m_severities & RPT_SEVERITY_EXCLUSION )
if( getSeverities() & RPT_SEVERITY_EXCLUSION )
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
else
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
@ -788,7 +844,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
}
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
modified = true;
break;
@ -804,7 +860,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
}
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
modified = true;
break;
@ -830,7 +886,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
modified = true;
}
break;
@ -956,7 +1012,7 @@ void DIALOG_ERC::ExcludeMarker( SCH_MARKER* aMarker )
m_parent->GetCanvas()->GetView()->Update( marker );
// Update view
if( m_severities & RPT_SEVERITY_EXCLUSION )
if( getSeverities() & RPT_SEVERITY_EXCLUSION )
m_markerTreeModel->ValueChanged( node );
else
m_markerTreeModel->DeleteCurrentItem( false );
@ -976,28 +1032,14 @@ void DIALOG_ERC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
{
int flag = 0;
if( aEvent.GetEventObject() == m_showAll )
flag = RPT_SEVERITY_ALL;
else if( aEvent.GetEventObject() == m_showErrors )
flag = RPT_SEVERITY_ERROR;
else if( aEvent.GetEventObject() == m_showWarnings )
flag = RPT_SEVERITY_WARNING;
else if( aEvent.GetEventObject() == m_showExclusions )
flag = RPT_SEVERITY_EXCLUSION;
{
m_showErrors->SetValue( true );
m_showWarnings->SetValue( aEvent.IsChecked() );
m_showExclusions->SetValue( aEvent.IsChecked() );
}
if( aEvent.IsChecked() )
m_severities |= flag;
else if( aEvent.GetEventObject() == m_showAll )
m_severities = RPT_SEVERITY_ERROR;
else
m_severities &= ~flag;
syncCheckboxes();
m_markerTreeModel->Update( m_markerProvider, m_severities );
updateDisplayedCounts();
UpdateData();
}

View File

@ -49,6 +49,8 @@ public:
DIALOG_ERC( SCH_EDIT_FRAME* parent );
~DIALOG_ERC();
bool TransferDataToWindow() override;
// PROGRESS_REPORTER_BASE calls
bool updateUI() override;
void AdvancePhase( const wxString& aMessage ) override;
@ -66,10 +68,14 @@ public:
*/
void ExcludeMarker( SCH_MARKER* aMarker = nullptr );
void UpdateData();
void UpdateAnnotationWarning();
private:
int getSeverities();
// from DIALOG_ERC_BASE:
void OnMenu( wxCommandEvent& aEvent ) override;
void OnCloseErcDialog( wxCloseEvent& event ) override;
void OnRunERCClick( wxCommandEvent& event ) override;
void OnDeleteOneClick( wxCommandEvent& event ) override;
@ -92,8 +98,6 @@ private:
void testErc();
bool writeReport( const wxString& aFullFileName );
void deleteAllMarkers( bool aIncludeExclusions );
void syncCheckboxes();
@ -114,7 +118,8 @@ private:
const SCH_MARKER* m_centerMarkerOnIdle;
int m_severities;
bool m_crossprobe;
bool m_scroll_on_crossprobe;
};

View File

@ -5,6 +5,7 @@
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_html_report_box.h"
#include "widgets/wx_infobar.h"
@ -29,6 +30,24 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxGridBagSizer* gbSizerOptions;
gbSizerOptions = new wxGridBagSizer( 0, 0 );
gbSizerOptions->SetFlexibleDirection( wxBOTH );
gbSizerOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_bMenu = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bMenu->SetMinSize( wxSize( 30,30 ) );
gbSizerOptions->Add( m_bMenu, wxGBPosition( 0, 2 ), wxGBSpan( 2, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
gbSizerOptions->AddGrowableCol( 0 );
gbSizerOptions->AddGrowableCol( 1 );
gbSizerOptions->AddGrowableRow( 0 );
gbSizerOptions->AddGrowableRow( 1 );
bMainSizer->Add( gbSizerOptions, 0, wxEXPAND|wxLEFT, 5 );
m_runningResultsBook = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
running = new wxPanel( m_runningResultsBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer14;
@ -195,6 +214,7 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
m_bMenu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnMenu ), NULL, this );
m_messages->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLinkClicked ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemDClick ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemRClick ), NULL, this );
@ -216,6 +236,7 @@ DIALOG_ERC_BASE::~DIALOG_ERC_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
m_bMenu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnMenu ), NULL, this );
m_messages->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLinkClicked ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemDClick ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemRClick ), NULL, this );

View File

@ -14,7 +14,7 @@
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">dialog_erc_base</property>
<property name="first_id">1000</property>
<property name="first_id">7100</property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
@ -135,6 +135,101 @@
<property name="name">bMainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxGridBagSizer" expanded="true">
<property name="empty_cell_size"></property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">0,1</property>
<property name="growablerows">0,1</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gbSizerOptions</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="vgap">0</property>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">0</property>
<property name="rowspan">2</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Refresh Grouping</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">30,30</property>
<property name="moveable">1</property>
<property name="name">m_bMenu</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnMenu</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT</property>

View File

@ -10,6 +10,7 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_HTML_REPORT_BOX;
class WX_INFOBAR;
@ -20,13 +21,16 @@ class WX_INFOBAR;
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/gbsizer.h>
#include <wx/html/htmlwin.h>
#include <wx/gauge.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/notebook.h>
#include <wx/dataview.h>
#include <wx/listctrl.h>
@ -35,12 +39,11 @@ class WX_INFOBAR;
#include <wx/stattext.h>
#include <wx/checkbox.h>
#include <widgets/number_badge.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#define ID_ERASE_DRC_MARKERS 1000
#define ID_ERASE_DRC_MARKERS 7100
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_ERC_BASE
@ -51,6 +54,7 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
protected:
WX_INFOBAR* m_infoBar;
STD_BITMAP_BUTTON* m_bMenu;
wxSimplebook* m_runningResultsBook;
wxPanel* running;
wxNotebook* m_runningNotebook;
@ -82,6 +86,7 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
// Virtual event handlers, override them in your derived class
virtual void OnCloseErcDialog( wxCloseEvent& event ) { event.Skip(); }
virtual void OnMenu( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLinkClicked( wxHtmlLinkEvent& event ) { event.Skip(); }
virtual void OnERCItemDClick( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnERCItemRClick( wxDataViewEvent& event ) { event.Skip(); }

View File

@ -77,8 +77,8 @@ public:
*/
std::vector<std::pair<FIELD_T, wxString>> GetFields() const;
bool GetKeepSymbol() { return m_keepSymbol; }
bool GetPlaceAllUnits() { return m_useUnits; }
bool GetKeepSymbol() { return m_keepSymbol->GetValue(); }
bool GetPlaceAllUnits() { return m_useUnits->GetValue(); }
public:
static std::mutex g_Mutex;

View File

@ -921,16 +921,28 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnMenu( wxCommandEvent& event )
// Build a pop menu:
wxMenu menu;
menu.Append( 4204, _( "Include 'DNP' Symbols" ), wxEmptyString, wxITEM_CHECK );
menu.Append( 4205, _( "Include 'Exclude from BOM' Symbols" ), wxEmptyString, wxITEM_CHECK );
menu.AppendSeparator();
menu.Append( 4206, _( "Highlight on Cross Probe" ), wxEmptyString, wxITEM_CHECK );
menu.Append( 4207, _( "Select on Cross Probe" ), wxEmptyString, wxITEM_CHECK );
menu.Append( 4204, _( "Include 'DNP' Symbols" ),
_( "Show symbols marked 'DNP' in the table. This setting also controls whether or not 'DNP' "
"symbols are included on export." ),
wxITEM_CHECK );
menu.Check( 4204, !m_dataModel->GetExcludeDNP() );
menu.Append( 4205, _( "Include 'Exclude from BOM' Symbols" ),
_( "Show symbols marked 'Exclude from BOM' in the table. Symbols marked 'Exclude from BOM' "
"are never included on export." ),
wxITEM_CHECK );
menu.Check( 4205, m_dataModel->GetIncludeExcludedFromBOM() );
menu.AppendSeparator();
menu.Append( 4206, _( "Highlight on Cross-probe" ),
_( "Highlight corresponding item on canvas when it is selected in the table" ),
wxITEM_CHECK );
menu.Check( 4206, cfg.selection_mode == 0 );
menu.Append( 4207, _( "Select on Cross-probe" ),
_( "Select corresponding item on canvas when it is selected in the table" ),
wxITEM_CHECK );
menu.Check( 4207, cfg.selection_mode == 1 );
// menu_id is the selected submenu id from the popup menu or wxID_NONE

View File

@ -189,9 +189,6 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_params.emplace_back( new PARAM<int>( "appearance.edit_label_height",
&m_Appearance.edit_label_height, -1 ) );
m_params.emplace_back( new PARAM<int>( "appearance.erc_severities",
&m_Appearance.erc_severities, RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ) );
m_params.emplace_back( new PARAM<bool>( "appearance.footprint_preview",
&m_Appearance.footprint_preview, true ) );
@ -591,6 +588,12 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_params.emplace_back( new PARAM<int>( "symbol_chooser.sort_mode",
&m_SymChooserPanel.sort_mode, 0 ) );
m_params.emplace_back( new PARAM<bool>( "ERC.crossprobe",
&m_ERCDialog.crossprobe, true ) );
m_params.emplace_back( new PARAM<bool>( "ERC.scroll_on_crossprobe",
&m_ERCDialog.scroll_on_crossprobe, true ) );
m_params.emplace_back( new PARAM<bool>( "import_graphics.interactive_placement",
&m_ImportGraphics.interactive_placement, true ) );

View File

@ -68,7 +68,6 @@ public:
int edit_label_width;
int edit_label_height;
bool edit_label_multiple;
int erc_severities;
bool footprint_preview;
bool print_sheet_reference;
wxString default_font;
@ -265,6 +264,12 @@ public:
int sort_mode;
};
struct DIALOG_ERC
{
bool crossprobe;
bool scroll_on_crossprobe;
};
struct DIALOG_IMPORT_GRAPHICS
{
bool interactive_placement;
@ -329,35 +334,26 @@ private:
public:
APPEARANCE m_Appearance;
AUTOPLACE_FIELDS m_AutoplaceFields;
AUI_PANELS m_AuiPanels;
DRAWING m_Drawing;
FIND_REPLACE_EXTRA m_FindReplaceExtra;
INPUT m_Input;
AUTOPLACE_FIELDS m_AutoplaceFields;
SELECTION m_Selection;
PAGE_SETTINGS m_PageSettings;
PANEL_ANNOTATE m_AnnotatePanel;
PANEL_BOM m_BomPanel;
PANEL_SYMBOL_FIELDS_TABLE m_FieldEditorPanel;
PANEL_LIB_VIEW m_LibViewPanel;
PANEL_NETLIST m_NetlistPanel;
PANEL_SYM_CHOOSER m_SymChooserPanel;
FIND_REPLACE_EXTRA m_FindReplaceExtra;
DIALOG_ERC m_ERCDialog;
DIALOG_IMPORT_GRAPHICS m_ImportGraphics;
SELECTION m_Selection;
SIMULATOR m_Simulator;
bool m_RescueNeverShow;

View File

@ -159,6 +159,13 @@ bool SCH_BITMAP::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) c
}
bool SCH_BITMAP::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
{
return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
}
void SCH_BITMAP::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
{

View File

@ -100,6 +100,7 @@ public:
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
bool HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const override;
void Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed ) override;

View File

@ -2032,7 +2032,7 @@ bool SCH_EDIT_FRAME::GetShowAllPins() const
}
void SCH_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem )
void SCH_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
{
// nullptr will clear the current focus
if( aItem != nullptr && !aItem->IsSCH_ITEM() )
@ -2060,7 +2060,7 @@ void SCH_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem )
lastBrightenedItemID = aItem->m_Uuid;
}
FocusOnLocation( aItem->GetFocusPosition() );
FocusOnLocation( aItem->GetFocusPosition(), aAllowScroll );
}
}

View File

@ -755,7 +755,7 @@ public:
int GetSchematicJunctionSize();
double GetSchematicHopOverScale();
void FocusOnItem( EDA_ITEM* aItem ) override;
void FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll = true ) override;
bool IsSyncingSelection() { return m_syncingPcbToSchSelection; }

View File

@ -165,28 +165,6 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool addToParentGroup, SCH_COMMIT* aCommit, bool
}
void SCH_ITEM::SetUnitProp( const wxString& aUnit )
{
if( aUnit == _HKI( "All units" ) )
{
m_unit = 0;
return;
}
if( SYMBOL* symbol = GetParentSymbol() )
{
for( int unit = 1; unit <= symbol->GetUnitCount(); unit++ )
{
if( symbol->GetUnitDisplayName( unit, false ) == aUnit )
{
m_unit = unit;
return;
}
}
}
}
wxString SCH_ITEM::GetUnitDisplayName( int aUnit, bool aLabel ) const
{
if( aUnit == 0 )
@ -208,13 +186,6 @@ wxString SCH_ITEM::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
return wxEmptyString;
}
wxString SCH_ITEM::GetUnitProp() const
{
return GetUnitDisplayName( m_unit, false );
}
void SCH_ITEM::SetBodyStyleProp( const wxString& aBodyStyle )
{
if( aBodyStyle == _HKI( "All body styles" ) )
@ -734,21 +705,21 @@ static struct SCH_ITEM_DESC
return false;
};
propMgr.AddProperty( new PROPERTY<SCH_ITEM, wxString>( _HKI( "Unit" ),
&SCH_ITEM::SetUnitProp, &SCH_ITEM::GetUnitProp ) )
propMgr.AddProperty( new PROPERTY<SCH_ITEM, int>( _HKI( "Unit" ),
&SCH_ITEM::SetUnit, &SCH_ITEM::GetUnit ) )
.SetAvailableFunc( multiUnit )
.SetIsHiddenFromDesignEditors()
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
choices.Add( _HKI( "All units" ) );
choices.Add( _HKI( "All units" ), 0 );
if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
{
if( SYMBOL* symbol = item->GetParentSymbol() )
{
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
choices.Add( symbol->GetUnitDisplayName( ii, false ) );
choices.Add( symbol->GetUnitDisplayName( ii, false ), ii );
}
}

View File

@ -240,9 +240,6 @@ public:
virtual wxString GetUnitDisplayName( int aUnit, bool aLabel ) const;
virtual wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const;
virtual void SetUnitProp( const wxString& aUnit );
virtual wxString GetUnitProp() const;
virtual void SetBodyStyle( int aBodyStyle ) { m_bodyStyle = aBodyStyle; }
int GetBodyStyle() const { return m_bodyStyle; }

View File

@ -34,6 +34,9 @@
#include <string_utils.h>
#include <geometry/geometry_utils.h>
#include <schematic.h>
#include <sch_screen.h>
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <settings/color_settings.h>
#include <sch_painter.h>
#include <default_values.h>
@ -314,6 +317,82 @@ COLOR4D SCH_LABEL_BASE::GetLabelColor() const
}
void SCH_LABEL_BASE::SetLabelShape( LABEL_SHAPE aShape )
{
m_shape = (LABEL_FLAG_SHAPE) aShape;
static bool s_inUpdate = false;
if( s_inUpdate )
return;
s_inUpdate = true;
if( Type() == SCH_HIER_LABEL_T )
{
SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( this );
SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( label->GetParent() );
if( screen )
{
const wxString& text = label->GetText();
for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) )
{
SCH_HIERLABEL* other = static_cast<SCH_HIERLABEL*>( item );
if( other != label && other->GetText() == text )
other->SetLabelShape( aShape );
}
for( const SCH_SHEET_PATH& sheetPath : screen->GetClientSheetPaths() )
{
SCH_SHEET* sheet = sheetPath.Last();
if( sheet )
{
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
if( pin->GetText() == text )
pin->SetLabelShape( aShape );
}
}
}
}
}
else if( Type() == SCH_SHEET_PIN_T )
{
SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( this );
SCH_SHEET* parent = pin->GetParent();
if( parent )
{
const wxString& text = pin->GetText();
SCH_SCREEN* screen = parent->GetScreen();
if( screen )
{
for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) )
{
SCH_HIERLABEL* hlabel = static_cast<SCH_HIERLABEL*>( item );
if( hlabel->GetText() == text )
hlabel->SetLabelShape( aShape );
}
}
for( SCH_SHEET_PIN* other : parent->GetPins() )
{
if( other != pin && other->GetText() == text )
other->SetLabelShape( aShape );
}
}
}
s_inUpdate = false;
}
void SCH_LABEL_BASE::SetSpinStyle( SPIN_STYLE aSpinStyle )
{
// Assume "Right" and Left" mean which side of the anchor the text will be on

View File

@ -173,12 +173,19 @@ public:
bool HasConnectivityChanges( const SCH_ITEM* aItem,
const SCH_SHEET_PATH* aInstance = nullptr ) const override;
LABEL_FLAG_SHAPE GetShape() const { return m_shape; }
void SetShape( LABEL_FLAG_SHAPE aShape ) { m_shape = aShape; }
// Type-specific versions for property manager
LABEL_SHAPE GetLabelShape() const { return (LABEL_SHAPE) m_shape; }
void SetLabelShape( LABEL_SHAPE aShape ) { m_shape = (LABEL_FLAG_SHAPE) aShape; }
void SetLabelShape( LABEL_SHAPE aShape );
LABEL_FLAG_SHAPE GetShape() const { return m_shape; }
void SetShape( LABEL_FLAG_SHAPE aShape )
{
// Set flags directly if a flag shape
if( aShape >= F_FIRST )
m_shape = aShape;
else
SetLabelShape( (LABEL_SHAPE) aShape );
}
COLOR4D GetLabelColor() const;

View File

@ -531,6 +531,7 @@ void SCH_PLOTTER::createSVGFiles( const SCH_PLOT_OPTS& aPlotOpts,
// so replace separators to create a unique filename:
fname.Replace( "/", "_" );
fname.Replace( "\\", "_" );
fname.Replace( ":", "_" );
wxString ext = SVG_PLOTTER::GetDefaultFileExtension();
wxFileName plotFileName = createPlotFileName( aPlotOpts, fname, ext, aReporter );

View File

@ -2986,7 +2986,7 @@ static struct SCH_SYMBOL_DESC
return false;
};
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ),
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Unit" ),
&SCH_SYMBOL::SetUnitProp, &SCH_SYMBOL::GetUnitProp ) )
.SetAvailableFunc( multiUnit )
.SetChoicesFunc( []( INSPECTABLE* aItem )
@ -2996,7 +2996,7 @@ static struct SCH_SYMBOL_DESC
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
{
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
choices.Add( symbol->GetUnitDisplayName( ii, false ) );
choices.Add( symbol->GetUnitDisplayName( ii, false ), ii );
}
return choices;

View File

@ -497,24 +497,15 @@ public:
SetValueFieldText( aRef );
}
wxString GetUnitProp() const override
int GetUnitProp() const
{
int unit = GetUnitSelection( &Schematic()->CurrentSheet() );
return GetUnitDisplayName( unit, false );
return GetUnitSelection( &Schematic()->CurrentSheet() );
}
void SetUnitProp( const wxString& aUnit ) override
void SetUnitProp( int aUnit )
{
for( int unit = 1; unit <= GetUnitCount(); unit++ )
{
if( GetUnitDisplayName( unit, false ) == aUnit )
{
SetUnitSelection( &Schematic()->CurrentSheet(), unit );
SetUnit( unit );
return;
}
}
SetUnitSelection( &Schematic()->CurrentSheet(), aUnit );
SetUnit( aUnit );
}
wxString GetBodyStyleProp() const override

View File

@ -33,6 +33,7 @@
#include <sch_painter.h>
#include <wx/log.h>
#include <sch_table.h>
#include <geometry/geometry_utils.h>
SCH_TABLE::SCH_TABLE( int aLineWidth ) :
@ -327,6 +328,12 @@ bool SCH_TABLE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
}
bool SCH_TABLE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
{
return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
}
void SCH_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const
{

View File

@ -214,8 +214,8 @@ public:
std::vector<int> ViewGetLayers() const override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
bool HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const override;
void DrawBorders( const std::function<void( const VECTOR2I& aPt1, const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const;

View File

@ -140,10 +140,9 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor
// Read all self-contained models in parallel
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.parallelize_loop( modelQueue.size(),
[&]( const int a, const int b )
auto results = tp.submit_loop( 0, modelQueue.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
createModel( ii, true );
} );
results.wait();

View File

@ -1541,7 +1541,7 @@ const BOX2I SYMBOL_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) con
}
void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem )
void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
{
static KIID lastBrightenedItemID( niluuid );
@ -1587,7 +1587,7 @@ void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem )
lastBrightenedItemID = aItem->m_Uuid;
}
FocusOnLocation( VECTOR2I( aItem->GetFocusPosition().x, -aItem->GetFocusPosition().y ) );
FocusOnLocation( VECTOR2I( aItem->GetFocusPosition().x, -aItem->GetFocusPosition().y ), aAllowScroll );
}
}

View File

@ -377,7 +377,7 @@ public:
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
void FocusOnItem( EDA_ITEM* aItem ) override;
void FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll = true ) override;
/**
* Load a symbol from the schematic to edit in place.

View File

@ -3097,6 +3097,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr );
VECTOR2I cursorPos;
bool startedWithDrag = false; // Track if initial sheet placement started with a drag
m_toolMgr->RunAction( ACTIONS::selectionClear );
@ -3188,7 +3189,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
}
}
else if( !sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick ) ) )
|| evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick )
|| evt->IsDrag( BUT_LEFT ) ) )
{
SCH_SELECTION& selection = m_selectionTool->GetSelection();
@ -3211,7 +3213,15 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( ACTIONS::selectionClear );
sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(), cursorPos );
VECTOR2I sheetPos = evt->IsDrag( BUT_LEFT ) ?
grid.Align( evt->DragOrigin(), GRID_HELPER_GRIDS::GRID_GRAPHICS ) :
cursorPos;
// Remember whether this sheet was initiated with a drag so we can treat mouse-up as
// the terminating (second) click.
startedWithDrag = evt->IsDrag( BUT_LEFT );
sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(), sheetPos );
sheet->SetScreen( nullptr );
wxString ext = wxString( "." ) + FILEEXT::KiCadSchematicFileExtension;
@ -3268,7 +3278,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
else if( sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick )
|| evt->IsAction( &ACTIONS::finishInteractive ) ) )
|| evt->IsAction( &ACTIONS::finishInteractive )
|| ( startedWithDrag && evt->IsMouseUp( BUT_LEFT ) ) ) )
{
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
@ -3338,7 +3349,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
evt->SetPassEvent();
break;
}
else if( sheet && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
else if( sheet && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion()
|| evt->IsDrag( BUT_LEFT ) ) )
{
sizeSheet( sheet, cursorPos );
m_view->ClearPreview();

View File

@ -546,15 +546,36 @@ void HIERARCHY_PANE::onCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL )
int mods = aKeyStroke.GetModifiers();
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL;
if( aKeyStroke.GetModifiers() & wxMOD_ALT )
if( mods & wxMOD_ALT )
hotkey += MD_ALT;
}
if( aKeyStroke.GetModifiers() & wxMOD_SHIFT )
if( mods & wxMOD_SHIFT )
hotkey += MD_SHIFT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey += MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
hotkey += MD_SUPER;
#endif
if( hotkey == ACTIONS::expandAll.GetHotKey()
|| hotkey == ACTIONS::expandAll.GetHotKeyAlt() )
{

View File

@ -34,6 +34,7 @@
#include <schematic.h>
#include <sch_symbol.h>
#include <sch_field.h>
#include <template_fieldnames.h>
#include <settings/color_settings.h>
#include <string_utils.h>
#include <tool/tool_manager.h>
@ -149,6 +150,32 @@ SCH_PROPERTIES_PANEL::SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* a
{
m_colorEditorInstance = static_cast<PG_COLOR_EDITOR*>( it->second );
}
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
{
m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( it->second );
m_fpEditorInstance->UpdateFrame( m_frame );
}
else
{
PG_FPID_EDITOR* fpEditor = new PG_FPID_EDITOR( m_frame );
m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( wxPropertyGrid::RegisterEditorClass( fpEditor ) );
}
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_URL_EDITOR::BuildEditorName( m_frame ) );
if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
{
m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( it->second );
m_urlEditorInstance->UpdateFrame( m_frame );
}
else
{
PG_URL_EDITOR* urlEditor = new PG_URL_EDITOR( m_frame );
m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( wxPropertyGrid::RegisterEditorClass( urlEditor ) );
}
}
@ -156,6 +183,8 @@ SCH_PROPERTIES_PANEL::SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* a
SCH_PROPERTIES_PANEL::~SCH_PROPERTIES_PANEL()
{
m_unitEditorInstance->UpdateFrame( nullptr );
m_fpEditorInstance->UpdateFrame( nullptr );
m_urlEditorInstance->UpdateFrame( nullptr );
}
@ -226,6 +255,11 @@ wxPGProperty* SCH_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProp
colorProp->SetBackgroundColor( bg );
}
if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::FOOTPRINT ) )
prop->SetEditor( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
else if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::DATASHEET ) )
prop->SetEditor( PG_URL_EDITOR::BuildEditorName( m_frame ) );
return prop;
}

View File

@ -32,6 +32,8 @@ class PROPERTY_MANAGER;
class PG_UNIT_EDITOR;
class PG_CHECKBOX_EDITOR;
class PG_COLOR_EDITOR;
class PG_FPID_EDITOR;
class PG_URL_EDITOR;
class SCH_PROPERTIES_PANEL : public PROPERTIES_PANEL
{
@ -60,6 +62,8 @@ protected:
PG_UNIT_EDITOR* m_unitEditorInstance;
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
PG_COLOR_EDITOR* m_colorEditorInstance;
PG_FPID_EDITOR* m_fpEditorInstance;
PG_URL_EDITOR* m_urlEditorInstance;
static std::set<wxString> m_currentFieldNames;
wxPGChoices m_nets;

View File

@ -306,14 +306,14 @@ public:
*
* @param aPos is the point to go to.
*/
void FocusOnLocation( const VECTOR2I& aPos );
void FocusOnLocation( const VECTOR2I& aPos, bool aAllowScroll = true );
/**
* Focus on a particular canvas item.
*
* @param aItem is the item to focus on. nullptr clears the focus.
*/
virtual void FocusOnItem( EDA_ITEM* aItem ) {}
virtual void FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll = true ) {}
virtual void ClearFocus() { FocusOnItem( nullptr ); }

View File

@ -220,9 +220,10 @@ public:
EDA_ITEM* ResolveItem( const KIID& aId, bool aAllowNullptrReturn = false ) const override;
void FocusOnItem( EDA_ITEM* aItem ) override;
void FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
void FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
void FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll = true ) override;
void FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer = UNDEFINED_LAYER, bool aAllowScroll = true );
void FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
bool aAllowScroll = true );
void HideSolderMask();
void ShowSolderMask();

View File

@ -110,7 +110,7 @@ public:
*/
void BuildArgvUtf8();
BS::thread_pool& GetThreadPool() { return *m_singleton.m_ThreadPool; }
BS::thread_pool<0>& GetThreadPool() { return *m_singleton.m_ThreadPool; }
GL_CONTEXT_MANAGER* GetGLContextManager() { return m_singleton.m_GLContextManager; }

View File

@ -125,4 +125,58 @@ public:
};
class PG_FPID_EDITOR : public wxPGTextCtrlEditor
{
public:
static const wxString EDITOR_NAME;
PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame );
virtual ~PG_FPID_EDITOR() {}
wxString GetName() const override { return m_editorName; }
void UpdateFrame( EDA_DRAW_FRAME* aFrame );
static wxString BuildEditorName( EDA_DRAW_FRAME* aFrame );
wxPGWindowList CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const override;
bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const override;
private:
EDA_DRAW_FRAME* m_frame;
wxString m_editorName;
};
class PG_URL_EDITOR : public wxPGTextCtrlEditor
{
public:
static const wxString EDITOR_NAME;
PG_URL_EDITOR( EDA_DRAW_FRAME* aFrame );
virtual ~PG_URL_EDITOR() {}
wxString GetName() const override { return m_editorName; }
void UpdateFrame( EDA_DRAW_FRAME* aFrame );
static wxString BuildEditorName( EDA_DRAW_FRAME* aFrame );
wxPGWindowList CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const override;
bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const override;
private:
EDA_DRAW_FRAME* m_frame;
wxString m_editorName;
};
#endif //KICAD_PG_EDITORS_H

View File

@ -25,6 +25,7 @@
class GL_CONTEXT_MANAGER;
namespace BS
{
template <std::uint8_t>
class thread_pool;
}
@ -42,7 +43,7 @@ public:
void Init();
public:
BS::thread_pool* m_ThreadPool;
BS::thread_pool<0>* m_ThreadPool;
GL_CONTEXT_MANAGER* m_GLContextManager;
};

View File

@ -28,7 +28,7 @@
#include <bs_thread_pool.hpp>
#include <import_export.h>
using thread_pool = BS::thread_pool;
using thread_pool = BS::thread_pool<0>;
/**
* Get a reference to the current thread pool. N.B., you cannot copy the thread pool

View File

@ -84,22 +84,9 @@ private:
/// Returns the instance of VIEW, used by the application.
KIGFX::VIEW* getView();
/// Saves the state of key modifiers (Alt, Ctrl and so on).
static int decodeModifiers( const wxKeyboardState* aState )
{
int mods = 0;
if( aState->ControlDown() )
mods |= MD_CTRL;
if( aState->AltDown() )
mods |= MD_ALT;
if( aState->ShiftDown() )
mods |= MD_SHIFT;
return mods;
}
/// Returns the state of key modifiers (Alt, Ctrl and so on) as OR'ed list
/// of bits (MD_CTRL, MD_ALT ...)
static int decodeModifiers( const wxKeyboardState* aState );
private:
/// The time threshold for a mouse button press that distinguishes between a single mouse

View File

@ -143,7 +143,10 @@ enum TOOL_MODIFIERS
MD_SHIFT = 0x1000,
MD_CTRL = 0x2000,
MD_ALT = 0x4000,
MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT,
MD_SUPER = 0x8000,
MD_META = 0x10000,
MD_ALTGR = 0x20000,
MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT | MD_SUPER | MD_META | MD_ALTGR,
};
/// Defines when a context menu is opened.

View File

@ -26,11 +26,14 @@
#include <bitmaps.h>
#include <widgets/std_bitmap_button.h>
#include <widgets/ui_common.h>
#include <algorithm>
#include <wx_filename.h>
#include <wx/dir.h>
#include <wx/dirdlg.h>
#include <wx/settings.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/math.h>
#include "template_default_html.h"
// Welcome / fallback HTML now provided by template_default_html.h
@ -99,7 +102,24 @@ void TEMPLATE_WIDGET::SetTemplate( PROJECT_TEMPLATE* aTemplate )
wxBitmap* icon = aTemplate->GetIcon();
if( icon && icon->IsOk() )
{
wxSize maxSize = m_bitmapIcon->GetSize();
if( icon->GetWidth() > maxSize.x || icon->GetHeight() > maxSize.y )
{
double scale = std::min( (double) maxSize.x / icon->GetWidth(),
(double) maxSize.y / icon->GetHeight() );
wxImage image = icon->ConvertToImage();
int w = wxRound( icon->GetWidth() * scale );
int h = wxRound( icon->GetHeight() * scale );
image.Rescale( w, h, wxIMAGE_QUALITY_HIGH );
m_bitmapIcon->SetBitmap( wxBitmap( image ) );
}
else
{
m_bitmapIcon->SetBitmap( *icon );
}
}
else
m_bitmapIcon->SetBitmap( KiBitmap( BITMAPS::icon_kicad ) );
}

View File

@ -636,7 +636,11 @@ void PROJECT_TREE_PANE::ReCreateTreePrj()
std::lock_guard<std::mutex> lock2( m_gitTreeCacheMutex );
thread_pool& tp = GetKiCadThreadPool();
tp.wait_for_tasks();
while( tp.get_tasks_running() )
{
tp.wait_for( std::chrono::milliseconds( 250 ) );
}
m_gitStatusTimer.Stop();
m_gitSyncTimer.Stop();
m_gitTreeCache.clear();
@ -2293,8 +2297,7 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
thread_pool& tp = GetKiCadThreadPool();
tp.push_task(
[this]()
tp.submit_task( [this]()
{
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
@ -2307,10 +2310,7 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
GIT_PULL_HANDLER handler( gitCommon );
handler.PerformFetch();
CallAfter( [this]()
{
gitStatusTimerHandler();
} );
CallAfter( [this]() { gitStatusTimerHandler(); } );
} );
if( gitSettings.updatInterval > 0 )
@ -2327,11 +2327,7 @@ void PROJECT_TREE_PANE::gitStatusTimerHandler()
updateTreeCache();
thread_pool& tp = GetKiCadThreadPool();
tp.push_task(
[this]()
{
updateGitStatusIconMap();
} );
tp.submit_task( [this]() { updateGitStatusIconMap(); } );
}
void PROJECT_TREE_PANE::onGitStatusTimer( wxTimerEvent& aEvent )

View File

@ -274,5 +274,5 @@ void UPDATE_MANAGER::CheckForUpdate( wxWindow* aNoticeParent )
};
thread_pool& tp = GetKiCadThreadPool();
m_updateTask = tp.submit( update_check );
m_updateTask = tp.submit_task( update_check );
}

View File

@ -25,6 +25,7 @@
class wxChoice;
class wxNonOwnedWindow;
class wxTopLevelWindow;
class wxWindow;
namespace KIPLATFORM
@ -71,6 +72,8 @@ namespace KIPLATFORM
*/
void ReparentModal( wxNonOwnedWindow* aWindow );
void ReparentWindow( wxNonOwnedWindow* aWindow, wxTopLevelWindow* aParent );
/*
* An ugly hack to fix an issue on OSX: cmd+c closes the dialog instead of copying the
* text if a button with wxID_CANCEL is used in a wxStdDialogButtonSizer created by

View File

@ -154,6 +154,12 @@ void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow )
}
void KIPLATFORM::UI::ReparentWindow( wxNonOwnedWindow* aWindow, wxTopLevelWindow* aParent )
{
// Not needed on this platform (only relevant for macOS child window ordering)
}
void KIPLATFORM::UI::FixupCancelButtonCmdKeyCollision( wxWindow *aWindow )
{
// Not needed on this platform

View File

@ -88,6 +88,12 @@ void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow )
}
void KIPLATFORM::UI::ReparentWindow( wxNonOwnedWindow* aWindow, wxTopLevelWindow* aParent )
{
// Not needed on this platform (used only on macOS for child window ordering)
}
void KIPLATFORM::UI::FixupCancelButtonCmdKeyCollision( wxWindow *aWindow )
{
// Not needed on this platform

View File

@ -103,24 +103,21 @@ void KIPLATFORM::UI::EnsureVisible( wxWindow* aWindow )
}
void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow )
void KIPLATFORM::UI::ReparentWindow( wxNonOwnedWindow* aWindow, wxTopLevelWindow* aParent )
{
wxTopLevelWindow* parent =
static_cast<wxTopLevelWindow*>( wxGetTopLevelParent( aWindow->GetParent() ) );
// Quietly return if no parent is found
if( !parent )
{
return;
}
NSWindow* parentWindow = parent->GetWXWindow();
NSWindow* parentWindow = aParent->GetWXWindow();
NSWindow* theWindow = aWindow->GetWXWindow();
if( parentWindow && theWindow )
{
[parentWindow addChildWindow:theWindow ordered:NSWindowAbove];
}
void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow )
{
// Quietly return if no parent is found
if( wxTopLevelWindow* parent = static_cast<wxTopLevelWindow*>( wxGetTopLevelParent( aWindow->GetParent() ) ) )
ReparentWindow( aWindow, parent );
}

View File

@ -1114,7 +1114,7 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<
};
for( ZONE* zone : zones )
returns.emplace_back( tp.submit( cache_zones, zone ) );
returns.emplace_back( tp.submit_task( [cache_zones, zone] { return cache_zones( zone ); } ) );
// Finalize the triangulation threads
for( const std::future<size_t>& ret : returns )

View File

@ -270,24 +270,21 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
{
std::vector<std::future<size_t>> returns( dirtyItems.size() );
auto conn_lambda =
[&dirtyItems]( size_t aItem, CN_LIST* aItemList,
PROGRESS_REPORTER* aReporter) -> size_t
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
{
if( aReporter && aReporter->IsCancelled() )
returns[ii] = tp.submit_task(
[&dirtyItems, ii, this] () ->size_t {
if( m_progressReporter && m_progressReporter->IsCancelled() )
return 0;
CN_VISITOR visitor( dirtyItems[aItem] );
aItemList->FindNearby( dirtyItems[aItem], visitor );
CN_VISITOR visitor( dirtyItems[ii] );
m_itemList.FindNearby( dirtyItems[ii], visitor );
if( aReporter )
aReporter->AdvanceProgress();
if( m_progressReporter )
m_progressReporter->AdvanceProgress();
return 1;
};
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
returns[ii] = tp.submit( conn_lambda, ii, &m_itemList, m_progressReporter );
return 1; } );
}
for( const std::future<size_t>& ret : returns )
{
@ -490,7 +487,11 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
};
for( size_t ii = 0; ii < zitems.size(); ++ii )
returns[ii] = tp.submit( cache_zones, zitems[ii] );
{
CN_ZONE_LAYER* ptr = zitems[ii];
returns[ii] = tp.submit_task(
[cache_zones, ptr] { return cache_zones( ptr ); } );
}
for( const std::future<size_t>& ret : returns )
{

View File

@ -191,18 +191,16 @@ void CONNECTIVITY_DATA::updateRatsnest()
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.parallelize_loop( dirty_nets.size(),
[&]( const int a, const int b )
auto results = tp.submit_loop( 0, dirty_nets.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
dirty_nets[ii]->UpdateNet();
} );
results.wait();
auto results2 = tp.parallelize_loop( dirty_nets.size(),
[&]( const int a, const int b )
auto results2 = tp.submit_loop( 0, dirty_nets.size(),
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
dirty_nets[ii]->OptimizeRNEdges();
} );
results2.wait();
@ -370,10 +368,9 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector<BOARD_ITEM*>& aI
thread_pool& tp = GetKiCadThreadPool();
size_t num_nets = std::min( m_nets.size(), aDynamicData->m_nets.size() );
auto results = tp.parallelize_loop( 1, num_nets,
[&]( const int a, const int b)
auto results = tp.submit_loop( 1, num_nets,
[&]( const int ii )
{
for( int ii = a; ii < b; ++ii )
update_lambda( ii );
});
results.wait();

View File

@ -46,8 +46,10 @@
#include <wx/wupdlock.h>
#include <widgets/appearance_controls.h>
#include <widgets/ui_common.h>
#include <widgets/std_bitmap_button.h>
#include <widgets/progress_reporter_base.h>
#include <widgets/wx_html_report_box.h>
#include <view/view_controls.h>
#include <dialogs/panel_setup_rules_base.h>
#include <dialogs/dialog_text_entry.h>
#include <tools/drc_tool.h>
@ -74,6 +76,9 @@ DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
m_running( false ),
m_drcRun( false ),
m_footprintTestsRun( false ),
m_report_all_track_errors( false ),
m_crossprobe( true ),
m_scroll_on_crossprobe( true ),
m_markersTreeModel( nullptr ),
m_unconnectedTreeModel( nullptr ),
m_fpWarningsTreeModel( nullptr ),
@ -85,6 +90,15 @@ DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
m_frame = aEditorFrame;
m_currentBoard = m_frame->GetBoard();
m_bMenu->SetBitmap( KiBitmapBundle( BITMAPS::config ) );
if( PCBNEW_SETTINGS* cfg = m_frame->GetPcbNewSettings() )
{
m_report_all_track_errors = cfg->m_DRCDialog.report_all_track_errors;
m_crossprobe = cfg->m_DRCDialog.crossprobe;
m_scroll_on_crossprobe = cfg->m_DRCDialog.scroll_on_crossprobe;
}
m_messages->SetImmediateMode();
m_markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
@ -147,6 +161,13 @@ DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
DIALOG_DRC::~DIALOG_DRC()
{
if( PCBNEW_SETTINGS* cfg = m_frame->GetPcbNewSettings() )
{
cfg->m_DRCDialog.report_all_track_errors = m_report_all_track_errors;
cfg->m_DRCDialog.crossprobe = m_crossprobe;
cfg->m_DRCDialog.scroll_on_crossprobe = m_scroll_on_crossprobe;
}
m_frame->ClearFocus();
g_lastDRCBoard = m_currentBoard;
@ -240,6 +261,46 @@ int DIALOG_DRC::getSeverities()
}
void DIALOG_DRC::OnMenu( wxCommandEvent& event )
{
// Build a pop menu:
wxMenu menu;
menu.Append( 4205, _( "Report All Errors for Each Track" ),
_( "If unchecked, only the first error will be reported for each track" ),
wxITEM_CHECK );
menu.Check( 4205, m_report_all_track_errors );
menu.AppendSeparator();
menu.Append( 4206, _( "Cross-probe Selected Items" ),
_( "Highlight corresponding items on canvas when selected in the DRC list" ),
wxITEM_CHECK );
menu.Check( 4206, m_crossprobe );
menu.Append( 4207, _( "Center on Cross-probe" ),
_( "When cross-probing, scroll the canvas so that the item is visible" ),
wxITEM_CHECK );
menu.Check( 4207, m_scroll_on_crossprobe );
// menu_id is the selected submenu id from the popup menu or wxID_NONE
int menu_id = m_bMenu->GetPopupMenuSelectionFromUser( menu );
if( menu_id == 0 || menu_id == 4205 )
{
m_report_all_track_errors = !m_report_all_track_errors;
}
else if( menu_id == 2 || menu_id == 4206 )
{
m_crossprobe = !m_crossprobe;
}
else if( menu_id == 3 || menu_id == 4207 )
{
m_scroll_on_crossprobe = !m_scroll_on_crossprobe;
}
}
void DIALOG_DRC::OnErrorLinkClicked( wxHtmlLinkEvent& event )
{
m_frame->ShowBoardSetupDialog( _( "Custom Rules" ) );
@ -252,7 +313,6 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
DRC_TOOL* drcTool = toolMgr->GetTool<DRC_TOOL>();
ZONE_FILLER_TOOL* zoneFillerTool = toolMgr->GetTool<ZONE_FILLER_TOOL>();
bool refillZones = m_cbRefillZones->GetValue();
bool reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue();
bool testFootprints = m_cbTestFootprints->GetValue();
if( zoneFillerTool->IsBusy() )
@ -326,7 +386,7 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
{
wxBusyCursor dummy;
drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
drcTool->RunTests( this, refillZones, m_report_all_track_errors, testFootprints );
}
if( m_cancelled )
@ -378,6 +438,12 @@ void DIALOG_DRC::UpdateData()
void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
{
if( !m_crossprobe )
{
aEvent.Skip();
return;
}
BOARD* board = m_frame->GetBoard();
RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
@ -408,11 +474,8 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
{
VECTOR2D selectedItemPos = aSelectedMarkerItem->GetPosition() / PCB_IU_PER_MM;
VECTOR2D unSelectedItemPos = aUnSelectedMarkerItem->GetPosition() / PCB_IU_PER_MM;
double dist = selectedItemPos.Distance( unSelectedItemPos );
double minimumMarkerSeparationDistance =
ADVANCED_CFG::GetCfg().m_MinimumMarkerSeparationDistance;
double minimumMarkerSeparationDistance = ADVANCED_CFG::GetCfg().m_MinimumMarkerSeparationDistance;
return dist <= minimumMarkerSeparationDistance;
};
@ -430,7 +493,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
&& rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
{
m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos(), m_scroll_on_crossprobe );
aEvent.Skip();
return;
@ -512,7 +575,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
if( item->Type() == PCB_ZONE_T )
{
m_frame->FocusOnItem( item, principalLayer );
m_frame->FocusOnItem( item, principalLayer, m_scroll_on_crossprobe );
m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges(
[&]( CN_EDGE& edge )
@ -541,7 +604,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
: edge.GetTargetPos();
}
m_frame->FocusOnLocation( focusPos );
m_frame->FocusOnLocation( focusPos, m_scroll_on_crossprobe );
m_frame->RefreshCanvas();
return false;
@ -552,7 +615,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
}
else
{
m_frame->FocusOnItem( item, principalLayer );
m_frame->FocusOnItem( item, principalLayer, m_scroll_on_crossprobe );
}
}
else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
@ -579,7 +642,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
items.push_back( item );
}
m_frame->FocusOnItems( items, principalLayer );
m_frame->FocusOnItems( items, principalLayer, m_scroll_on_crossprobe );
}
else
{
@ -594,11 +657,11 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
}
items.push_back( item );
m_frame->FocusOnItems( items, principalLayer );
m_frame->FocusOnItems( items, principalLayer, m_scroll_on_crossprobe );
}
else
{
m_frame->FocusOnItem( item, principalLayer );
m_frame->FocusOnItem( item, principalLayer, m_scroll_on_crossprobe );
}
}

View File

@ -77,6 +77,7 @@ private:
bool TransferDataToWindow() override;
void OnMenu( wxCommandEvent& aEvent ) override;
void OnDRCItemSelected( wxDataViewEvent& aEvent ) override;
void OnDRCItemDClick( wxDataViewEvent& aEvent ) override;
void OnDRCItemRClick( wxDataViewEvent& aEvent ) override;
@ -117,6 +118,10 @@ private:
bool m_drcRun;
bool m_footprintTestsRun;
bool m_report_all_track_errors;
bool m_crossprobe;
bool m_scroll_on_crossprobe;
wxString m_markersTitleTemplate;
wxString m_unconnectedTitleTemplate;
wxString m_footprintsTitleTemplate;

View File

@ -5,6 +5,7 @@
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_html_report_box.h"
#include "dialog_drc_base.h"
@ -24,30 +25,43 @@ DIALOG_DRC_BASE::DIALOG_DRC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
wxBoxSizer* bSizer12;
bSizer12 = new wxBoxSizer( wxVERTICAL );
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbRefillZones->SetValue(true);
bSizer12->Add( m_cbRefillZones, 0, wxALL, 5 );
m_cbReportAllTrackErrors = new wxCheckBox( this, wxID_ANY, _("Report all errors for each track"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbReportAllTrackErrors->SetToolTip( _("If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.\n\nIf unselected, only the first DRC violation will be reported for each track connection.") );
bSizer12->Add( m_cbReportAllTrackErrors, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerOptions->Add( bSizer12, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerOptSettings;
bSizerOptSettings = new wxBoxSizer( wxVERTICAL );
m_cbTestFootprints = new wxCheckBox( this, wxID_ANY, _("Test for parity between PCB and schematic"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerOptSettings->Add( m_cbTestFootprints, 0, wxALL, 5 );
bSizerOptions->Add( bSizerOptSettings, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
m_MainSizer->Add( bSizerOptions, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 3 );
wxGridBagSizer* gbSizerOptions;
gbSizerOptions = new wxGridBagSizer( 0, 0 );
gbSizerOptions->SetFlexibleDirection( wxBOTH );
gbSizerOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbRefillZones->SetValue(true);
gbSizerOptions->Add( m_cbRefillZones, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_cbTestFootprints = new wxCheckBox( this, wxID_ANY, _("Test for parity between PCB and schematic"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizerOptions->Add( m_cbTestFootprints, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_bMenu = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bMenu->SetMinSize( wxSize( 30,30 ) );
gbSizerOptions->Add( m_bMenu, wxGBPosition( 0, 2 ), wxGBSpan( 2, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
gbSizerOptions->AddGrowableCol( 0 );
gbSizerOptions->AddGrowableCol( 1 );
gbSizerOptions->AddGrowableRow( 0 );
gbSizerOptions->AddGrowableRow( 1 );
m_MainSizer->Add( gbSizerOptions, 0, wxEXPAND|wxTOP|wxLEFT, 10 );
m_runningResultsBook = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
running = new wxPanel( m_runningResultsBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer14;
@ -242,6 +256,7 @@ DIALOG_DRC_BASE::DIALOG_DRC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
// Connect Events
this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_BASE::OnActivateDlg ) );
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_DRC_BASE::OnClose ) );
m_bMenu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_BASE::OnMenu ), NULL, this );
m_messages->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_DRC_BASE::OnErrorLinkClicked ), NULL, this );
m_Notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_BASE::OnChangingNotebookPage ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemDClick ), NULL, this );
@ -271,6 +286,7 @@ DIALOG_DRC_BASE::~DIALOG_DRC_BASE()
// Disconnect Events
this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_BASE::OnActivateDlg ) );
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_DRC_BASE::OnClose ) );
m_bMenu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_BASE::OnMenu ), NULL, this );
m_messages->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_DRC_BASE::OnErrorLinkClicked ), NULL, this );
m_Notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_BASE::OnChangingNotebookPage ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemDClick ), NULL, this );

View File

@ -84,10 +84,43 @@
<property name="name">bSizer12</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizerOptSettings</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxGridBagSizer" expanded="true">
<property name="empty_cell_size"></property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">0,1</property>
<property name="growablerows">0,1</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gbSizerOptions</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="vgap">0</property>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -149,86 +182,13 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Report all errors for each track</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbReportAllTrackErrors</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.&#x0A;&#x0A;If unselected, only the first DRC violation will be reported for each track connection.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizerOptSettings</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -290,6 +250,82 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="row">0</property>
<property name="rowspan">2</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Refresh Grouping</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">30,30</property>
<property name="moveable">1</property>
<property name="name">m_bMenu</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnMenu</event>
</object>
</object>
</object>

View File

@ -10,22 +10,26 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_HTML_REPORT_BOX;
#include "dialog_shim.h"
#include <wx/sizer.h>
#include <wx/gdicmn.h>
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/html/htmlwin.h>
#include <wx/gauge.h>
#include <wx/panel.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/gbsizer.h>
#include <wx/html/htmlwin.h>
#include <wx/gauge.h>
#include <wx/panel.h>
#include <wx/notebook.h>
#include <wx/dataview.h>
#include <wx/listctrl.h>
@ -33,7 +37,6 @@ class WX_HTML_REPORT_BOX;
#include <wx/simplebook.h>
#include <wx/stattext.h>
#include <widgets/number_badge.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -48,8 +51,8 @@ class DIALOG_DRC_BASE : public DIALOG_SHIM
protected:
wxCheckBox* m_cbRefillZones;
wxCheckBox* m_cbReportAllTrackErrors;
wxCheckBox* m_cbTestFootprints;
STD_BITMAP_BUTTON* m_bMenu;
wxSimplebook* m_runningResultsBook;
wxPanel* running;
wxNotebook* m_runningNotebook;
@ -85,6 +88,7 @@ class DIALOG_DRC_BASE : public DIALOG_SHIM
// Virtual event handlers, override them in your derived class
virtual void OnActivateDlg( wxActivateEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnMenu( wxCommandEvent& event ) { event.Skip(); }
virtual void OnErrorLinkClicked( wxHtmlLinkEvent& event ) { event.Skip(); }
virtual void OnChangingNotebookPage( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnDRCItemDClick( wxDataViewEvent& event ) { event.Skip(); }

View File

@ -425,7 +425,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO
};
thread_pool& tp = GetKiCadThreadPool();
auto ret = tp.submit( saveFile );
auto ret = tp.submit_task( saveFile );
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -31,7 +31,9 @@ using namespace std::placeholders;
#include <board_commit.h>
#include <board.h>
#include <footprint.h>
#include <pcb_generator.h>
#include <pcb_track.h>
#include <generators/pcb_tuning_pattern.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/global_edit_tool.h>
@ -272,6 +274,15 @@ void DIALOG_GLOBAL_DELETION::DoGlobalDeletions()
}
}
}
for( PCB_GENERATOR* generator : board->Generators() )
{
if( PCB_TUNING_PATTERN* pattern = dynamic_cast<PCB_TUNING_PATTERN*>( generator ) )
{
if( pattern->GetBoardItems().empty() )
commit.Remove( pattern );
}
}
}
commit.Push( _( "Global Delete" ) );

View File

@ -158,7 +158,7 @@ bool DRC_CACHE_GENERATOR::Run()
forEachGeometryItem( itemTypes, boardCopperLayers, countItems );
std::future<void> retn = tp.submit(
std::future<void> retn = tp.submit_task(
[&]()
{
std::unique_lock<std::shared_mutex> writeLock( m_board->m_CachesMutex );
@ -225,7 +225,7 @@ bool DRC_CACHE_GENERATOR::Run()
};
for( ZONE* zone : allZones )
returns.emplace_back( tp.submit( cache_zones, zone ) );
returns.emplace_back( tp.submit_task( [cache_zones, zone] { return cache_zones( zone ); } ) );
done.store( 1 );

View File

@ -2317,9 +2317,7 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
}
}
auto processWorkItems = [&]( size_t start_idx, size_t end_idx ) -> bool
{
for( size_t idx = start_idx; idx < end_idx; ++idx )
auto processWorkItems = [&]( size_t idx ) -> bool
{
auto [gn1, gn2] = work_items[idx];
@ -2366,7 +2364,7 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
AddConnection( connect1, connect2, pc );
}
}
return true;
};
@ -2374,15 +2372,16 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
// has already parallelized the work, so we can process all items in one go.
if( tp.get_tasks_total() >= tp.get_thread_count() - 4 )
{
processWorkItems( 0, work_items.size() );
for( size_t ii = 0; ii < work_items.size(); ii++ )
processWorkItems( ii );
}
else
{
auto ret = tp.parallelize_loop( work_items.size(), processWorkItems );
auto ret = tp.submit_loop( 0, work_items.size(), processWorkItems );
for( size_t ii = 0; ii < ret.size(); ii++ )
{
std::future<bool>& r = ret[ii];
auto& r = ret[ii];
if( !r.valid() )
continue;

View File

@ -505,7 +505,6 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
}
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<size_t>> returns;
size_t total_effort = 0;
for( const auto& [ netLayer, itemsPoly ] : dataset )
@ -513,14 +512,16 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
total_effort += std::max( (size_t) 1, total_effort ) * distinctMinWidths.size();
std::vector<std::future<size_t>> returns;
returns.reserve( dataset.size() );
for( const auto& [ netLayer, itemsPoly ] : dataset )
{
returns.emplace_back( tp.submit( build_netlayer_polys, netLayer.Netcode, netLayer.Layer ) );
int netcode = netLayer.Netcode;
PCB_LAYER_ID layer = netLayer.Layer;
returns.emplace_back( tp.submit_task( [&, netcode, layer]() { return build_netlayer_polys( netcode, layer ); } ) );
}
for( std::future<size_t>& ret : returns )
for( auto& ret : returns )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
@ -541,11 +542,13 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
if( minWidth - epsilon <= 0 )
continue;
returns.emplace_back( tp.submit( min_checker, itemsPoly, netLayer.Layer, minWidth ) );
returns.emplace_back( tp.submit_task( [min_checker, &itemsPoly, &netLayer, minWidth]() {
return min_checker( itemsPoly, netLayer.Layer, minWidth );
} ) );
}
}
for( std::future<size_t>& ret : returns )
for( auto& ret : returns )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -594,9 +594,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
auto testTrack = [&]( const int start_idx, const int end_idx )
{
for( int trackIdx = start_idx; trackIdx < end_idx; ++trackIdx )
auto testTrack = [&]( const int trackIdx )
{
PCB_TRACK* track = m_board->Tracks()[trackIdx];
@ -697,12 +695,11 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
}
done.fetch_add( 1 );
}
};
thread_pool& tp = GetKiCadThreadPool();
tp.push_loop( m_board->Tracks().size(), testTrack );
auto track_futures = tp.submit_loop( 0, m_board->Tracks().size(), testTrack );
while( done < count )
{
@ -710,7 +707,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
if( m_drcEngine->IsCancelled() )
{
tp.wait_for_tasks();
// Wait for the submitted loop tasks to finish
track_futures.wait();
break;
}
@ -967,9 +965,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
const auto fp_check = [&]( size_t aFromIdx, size_t aToIdx )
{
for( size_t ii = aFromIdx; ii < aToIdx; ++ii )
const auto fp_check = [&]( size_t ii )
{
FOOTPRINT* footprint = m_board->Footprints()[ ii ];
@ -1038,11 +1034,10 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
}
done.fetch_add( 1 );
}
};
size_t numFootprints = m_board->Footprints().size();
auto returns = tp.parallelize_loop( numFootprints, fp_check );
auto returns = tp.submit_loop( 0, numFootprints, fp_check );
// Wait for all threads to finish
for( size_t ii = 0; ii < returns.size(); ++ii )
@ -1152,7 +1147,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testGraphicClearances()
m_board->m_DRCMaxClearance );
};
std::future<void> retn = tp.submit(
std::future<void> retn = tp.submit_task(
[&]()
{
for( BOARD_ITEM* item : m_board->Drawings() )
@ -1370,7 +1365,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
continue;
count++;
tp.push_task( checkZones, ia, ia2, sameNet, layer );
tp.submit_task( [checkZones, ia, ia2, sameNet, layer]() { checkZones(ia, ia2, sameNet, layer); } );
}
}
}
@ -1382,7 +1377,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
if( m_drcEngine->IsCancelled() )
break;
if( tp.wait_for_tasks_duration( std::chrono::milliseconds( 250 ) ) )
if( tp.wait_for( std::chrono::milliseconds( 250 ) ) )
break;
}

View File

@ -110,11 +110,11 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
}
auto query_areas =
[&]( std::pair<ZONE* /* rule area */, ZONE* /* copper zone */> areaZonePair ) -> size_t
[&]( const int idx ) -> size_t
{
if( m_drcEngine->IsCancelled() )
return 0;
const auto& areaZonePair = toCache[idx];
ZONE* ruleArea = areaZonePair.first;
ZONE* copperZone = areaZonePair.second;
BOX2I areaBBox = ruleArea->GetBoundingBox();
@ -169,14 +169,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
};
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<size_t>> returns;
auto futures = tp.submit_loop( 0, toCache.size(), query_areas );
returns.reserve( toCache.size() );
for( const std::pair<ZONE*, ZONE*>& areaZonePair : toCache )
returns.emplace_back( tp.submit( query_areas, areaZonePair ) );
for( const std::future<size_t>& ret : returns )
for( auto& ret : futures )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -149,14 +149,10 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
};
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<size_t>> returns;
returns.reserve( copperLayers.size() );
auto returns = tp.submit_loop( 0, copperLayers.size(), build_layer_polys );
for( size_t ii = 0; ii < copperLayers.size(); ++ii )
returns.emplace_back( tp.submit( build_layer_polys, ii ) );
for( const std::future<size_t>& ret : returns )
for( auto& ret : returns )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -737,9 +737,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskBridges()
thread_pool& tp = GetKiCadThreadPool();
auto returns = tp.parallelize_loop( test_items.size(), [&]( size_t a, size_t b ) -> bool
{
for( size_t i = a; i < b; ++i )
auto returns = tp.submit_loop( 0, test_items.size(), [&]( size_t i ) -> bool
{
BOARD_ITEM* item = test_items[ i ];
@ -777,7 +775,6 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskBridges()
}
++count;
}
return true;
} );

View File

@ -70,13 +70,15 @@ bool DRC_TEST_PROVIDER_TRACK_ANGLE::Run()
return false; // DRC cancelled
auto checkTrackAngle =
[&]( PCB_TRACK* item ) -> bool
[&]( const int ind ) -> bool
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_ANGLE ) )
{
return false;
}
PCB_TRACK* item = m_drcEngine->GetBoard()->Tracks()[ind];
if( item->Type() != PCB_TRACE_T )
{
return true;
@ -196,16 +198,9 @@ bool DRC_TEST_PROVIDER_TRACK_ANGLE::Run()
int ii = 0;
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<bool>> returns;
auto futures = tp.submit_loop( 0, m_drcEngine->GetBoard()->Tracks().size(), checkTrackAngle );
returns.reserve( m_drcEngine->GetBoard()->Tracks().size() );
for( PCB_TRACK* item : m_drcEngine->GetBoard()->Tracks() )
{
returns.emplace_back( tp.submit( checkTrackAngle, item ) );
}
for( std::future<bool>& ret : returns )
for( auto& ret : futures )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -67,8 +67,9 @@ bool DRC_TEST_PROVIDER_TRACK_SEGMENT_LENGTH::Run()
return false; // DRC cancelled
auto checkTrackSegmentLength =
[&]( BOARD_ITEM* item ) -> bool
[&]( const int idx ) -> bool
{
BOARD_ITEM* item = m_drcEngine->GetBoard()->Tracks()[idx];
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_SEGMENT_LENGTH ) )
return false;
@ -153,16 +154,9 @@ bool DRC_TEST_PROVIDER_TRACK_SEGMENT_LENGTH::Run()
int ii = 0;
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<bool>> returns;
auto futures = tp.submit_loop( 0, m_drcEngine->GetBoard()->Tracks().size(), checkTrackSegmentLength );
returns.reserve( m_drcEngine->GetBoard()->Tracks().size() );
for( PCB_TRACK* item : m_drcEngine->GetBoard()->Tracks() )
{
returns.emplace_back( tp.submit( checkTrackSegmentLength, item ) );
}
for( std::future<bool>& ret : returns )
for( auto& ret : futures )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -319,27 +319,17 @@ bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run()
total_effort = std::max( (size_t) 1, total_effort );
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<int>> returns;
returns.reserve( zoneLayers.size() );
for( const std::pair<ZONE*, PCB_LAYER_ID>& zonelayer : zoneLayers )
{
returns.emplace_back( tp.submit(
[&]( ZONE* aZone, PCB_LAYER_ID aLayer ) -> int
auto returns = tp.submit_loop( 0, zoneLayers.size(),
[&]( const int ii )
{
if( !m_drcEngine->IsCancelled() )
{
testZoneLayer( aZone, aLayer );
done.fetch_add( aZone->GetFilledPolysList( aLayer )->FullPointCount() );
testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
}
} );
return 0;
},
zonelayer.first, zonelayer.second ) );
}
for( const std::future<int>& ret : returns )
for( auto& ret : returns )
{
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );

View File

@ -2026,9 +2026,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
{
std::mutex mutex;
auto subtractLoopFn = [&]( const int a, const int b )
{
for( int shapeId = a; shapeId < b; shapeId++ )
auto subtractLoopFn = [&]( const int shapeId )
{
TopoDS_Shape& shape = vec[shapeId];
@ -2047,7 +2045,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
}
if( holelist.IsEmpty() )
continue;
return; // nothing to cut for this shape
TopTools_ListOfShape cutArgs;
cutArgs.Append( shape );
@ -2092,10 +2090,9 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
}
shape = cut.Shape();
}
};
tp.parallelize_loop( vec.size(), subtractLoopFn ).wait();
tp.submit_loop( 0, vec.size(), subtractLoopFn ).wait();
}
};
@ -2172,7 +2169,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
BS::multi_future<void> mf;
for( const auto& [netname, _] : shapesToFuseMap )
mf.push_back( tp.submit( fuseLoopFn, netname ) );
mf.push_back( tp.submit_task( [&, netname]() { fuseLoopFn( netname ); } ) );
mf.wait();
}

View File

@ -207,7 +207,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints()
};
for( size_t ii = 0; ii < num_elements; ++ii )
returns[ii] = tp.submit( fp_thread );
returns[ii] = tp.submit_task( fp_thread );
for( const std::future<size_t>& ret : returns )
{

View File

@ -23,6 +23,7 @@
*/
#include <eda_item.h>
#include <geometry/geometry_utils.h>
#include <pcb_base_edit_frame.h>
#include <router/pns_meander.h>
#include <router/pns_meander_placer_base.h>

View File

@ -253,27 +253,27 @@ EDA_ITEM* PCB_BASE_FRAME::ResolveItem( const KIID& aId, bool aAllowNullptrReturn
return GetBoard()->ResolveItem( aId, aAllowNullptrReturn );
}
void PCB_BASE_FRAME::FocusOnItem( EDA_ITEM* aItem )
void PCB_BASE_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
{
// nullptr will clear the current focus
if( aItem != nullptr && !aItem->IsBOARD_ITEM() )
return;
FocusOnItem( static_cast<BOARD_ITEM*>( aItem ), UNDEFINED_LAYER );
FocusOnItem( static_cast<BOARD_ITEM*>( aItem ), UNDEFINED_LAYER, aAllowScroll );
}
void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer )
void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, bool aAllowScroll )
{
std::vector<BOARD_ITEM*> items;
if( aItem )
items.push_back( aItem );
FocusOnItems( items, aLayer );
FocusOnItems( items, aLayer, aAllowScroll );
}
void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID aLayer )
void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID aLayer, bool aAllowScroll )
{
static std::vector<KIID> lastBrightenedItemIDs;
@ -361,7 +361,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
case PCB_PAD_T:
case PCB_MARKER_T:
case PCB_VIA_T:
FocusOnLocation( item->GetFocusPosition() );
FocusOnLocation( item->GetFocusPosition(), aAllowScroll );
GetCanvas()->Refresh();
return;
@ -449,7 +449,7 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
}
}
FocusOnLocation( focusPt );
FocusOnLocation( focusPt, aAllowScroll );
GetCanvas()->Refresh();
}

View File

@ -991,6 +991,39 @@ static struct PCB_SHAPE_DESC
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Fill" ), isNotBezier );
auto isCircle =
[]( INSPECTABLE* aItem ) -> bool
{
if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
return shape->GetShape() == SHAPE_T::CIRCLE;
return false;
};
auto isNotCircle =
[]( INSPECTABLE* aItem ) -> bool
{
if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
return shape->GetShape() != SHAPE_T::CIRCLE;
return true;
};
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Start X" ), isNotCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Start Y" ), isNotCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "End X" ), isNotCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "End Y" ), isNotCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Center X" ), isCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Center Y" ), isCircle );
propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ),
_HKI( "Radius" ), isCircle );
auto isCopper =
[]( INSPECTABLE* aItem ) -> bool
{

View File

@ -349,6 +349,15 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
m_params.emplace_back( new PARAM<wxString>( "system.last_footprint3d_dir",
&m_LastFootprint3dDir, "" ) );
m_params.emplace_back( new PARAM<bool>( "DRC.report_all_track_errors",
&m_DRCDialog.report_all_track_errors, false ) );
m_params.emplace_back( new PARAM<bool>( "DRC.crossprobe",
&m_DRCDialog.crossprobe, true ) );
m_params.emplace_back( new PARAM<bool>( "DRC.scroll_on_crossprobe",
&m_DRCDialog.scroll_on_crossprobe, true ) );
registerMigration( 0, 1,
[&]()
{

View File

@ -168,6 +168,13 @@ public:
bool doNotExportUnconnectedPads;
};
struct DIALOG_DRC
{
bool report_all_track_errors;
bool crossprobe;
bool scroll_on_crossprobe;
};
struct FOOTPRINT_CHOOSER
{
// Footprint chooser is a FRAME, so there's no DIALOG_SHIM to save/restore control state
@ -227,6 +234,7 @@ public:
AUI_PANELS m_AuiPanels;
DIALOG_EXPORT_D356 m_ExportD356;
DIALOG_DRC m_DRCDialog;
FOOTPRINT_CHOOSER m_FootprintChooser;
ZONES m_Zones;

View File

@ -27,6 +27,7 @@
#include <tools/pcb_selection_tool.h>
#include <tools/pcb_picker_tool.h>
#include <tools/edit_tool.h>
#include <tools/drc_tool.h>
#include <pcb_painter.h>
#include <connectivity/connectivity_data.h>
#include <drc/drc_engine.h>
@ -34,11 +35,12 @@
#include <dialogs/dialog_book_reporter.h>
#include <dialogs/panel_setup_rules_base.h>
#include <dialogs/dialog_footprint_associations.h>
#include <dialogs/dialog_drc.h>
#include <kiplatform/ui.h>
#include <string_utils.h>
#include <tools/board_inspection_tool.h>
#include <fp_lib_table.h>
#include <pcb_shape.h>
#include <pcbnew_settings.h>
#include <widgets/appearance_controls.h>
#include <widgets/wx_html_report_box.h>
#include <widgets/footprint_diff_widget.h>
@ -338,7 +340,9 @@ wxString BOARD_INSPECTION_TOOL::InspectDRCErrorMenuText( const std::shared_ptr<R
void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDRCItem )
{
wxCHECK( m_frame, /* void */ );
DRC_TOOL* drcTool = m_toolMgr->GetTool<DRC_TOOL>();
wxCHECK( drcTool && m_frame, /* void */ );
BOARD_ITEM* a = m_frame->GetBoard()->ResolveItem( aDRCItem->GetMainItemID() );
BOARD_ITEM* b = m_frame->GetBoard()->ResolveItem( aDRCItem->GetAuxItemID() );
@ -349,7 +353,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( aDRCItem->GetErrorCode() == DRCE_LIB_FOOTPRINT_MISMATCH )
{
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( a ) )
DiffFootprint( footprint );
DiffFootprint( footprint, drcTool->GetDRCDialog() );
return;
}
@ -698,7 +702,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
r->Flush();
dialog->Raise();
KIPLATFORM::UI::ReparentWindow( dialog, drcTool->GetDRCDialog() );
dialog->Show( true );
}
@ -1613,7 +1617,7 @@ int BOARD_INSPECTION_TOOL::ShowFootprintLinks( const TOOL_EVENT& aEvent )
}
void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint )
void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint, wxTopLevelWindow* aReparentTo )
{
DIALOG_BOOK_REPORTER* dialog = m_frame->GetFootprintDiffDialog();
@ -1694,7 +1698,11 @@ void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint )
r->Flush();
if( aReparentTo )
KIPLATFORM::UI::ReparentWindow( dialog, aReparentTo );
else
dialog->Raise();
dialog->Show( true );
}

View File

@ -90,7 +90,7 @@ public:
int ShowFootprintLinks( const TOOL_EVENT& aEvent );
int DiffFootprint( const TOOL_EVENT& aEvent );
void DiffFootprint( FOOTPRINT* aFootprint );
void DiffFootprint( FOOTPRINT* aFootprint, wxTopLevelWindow* aReparentTo = nullptr );
/**
* @return true if a net or nets to highlight have been set

View File

@ -60,6 +60,8 @@ public:
int ShowDRCDialog( const TOOL_EVENT& aEvent );
DIALOG_DRC* GetDRCDialog() { return m_drcDialog; }
/**
* Check to see if the DRC_TOOL dialog is currently shown
*/

View File

@ -581,7 +581,7 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
// and extract all of the pairs of segments that might be merged. Then, perform
// the actual merge in the main loop.
thread_pool& tp = GetKiCadThreadPool();
auto merge_returns = tp.parallelize_loop( 0, m_brd->Tracks().size(), track_loop );
auto merge_returns = tp.submit_blocks( 0, m_brd->Tracks().size(), track_loop );
bool retval = false;
for( size_t ii = 0; ii < merge_returns.size(); ++ii )

View File

@ -265,6 +265,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
bool reBuild_ratsnest = false;
bool deep_reBuild_ratsnest = false; // true later if pointers must be rebuilt
bool solder_mask_dirty = false;
bool current_show_ratsnest = GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest;
std::vector<BOX2I> dirty_rule_areas;
KIGFX::PCB_VIEW* view = GetCanvas()->GetView();
@ -283,6 +284,32 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
std::unordered_map<EDA_ITEM*, ITEM_CHANGE_TYPE> item_changes;
auto clear_local_ratsnest_flags =
[&]( EDA_ITEM* item )
{
switch( item->Type() )
{
case PCB_TRACE_T:
case PCB_ARC_T:
case PCB_VIA_T:
static_cast<PCB_TRACK*>( item )->SetLocalRatsnestVisible( current_show_ratsnest );
break;
case PCB_ZONE_T:
static_cast<ZONE*>( item )->SetLocalRatsnestVisible( current_show_ratsnest );
break;
case PCB_FOOTPRINT_T:
for( PAD* pad : static_cast<FOOTPRINT*>( item )->Pads() )
pad->SetLocalRatsnestVisible( current_show_ratsnest );
break;
default:
break;
}
};
auto update_item_change_state =
[&]( EDA_ITEM* item, ITEM_CHANGE_TYPE change_type )
{
@ -431,8 +458,10 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
switch( aList->GetPickedItemStatus( ii ) )
{
case UNDO_REDO::CHANGED: /* Exchange old and new data for each item */
if( eda_item->IsBOARD_ITEM() )
{
BOARD_ITEM* item = (BOARD_ITEM*) eda_item;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
BOARD_ITEM* image = static_cast<BOARD_ITEM*>( aList->GetPickedItemLink( ii ) );
BOARD_ITEM_CONTAINER* parent = GetBoard();
if( item->GetParentFootprint() )
@ -443,14 +472,12 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
parent = item->GetParentFootprint();
}
BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
view->Remove( item );
parent->Remove( item );
item->SwapItemData( image );
clear_local_ratsnest_flags( item );
item->ClearFlags( UR_TRANSIENT );
image->SetFlags( UR_TRANSIENT );
@ -465,12 +492,15 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
update_item_change_state( item, ITEM_CHANGE_TYPE::CHANGED );
break;
}
break;
case UNDO_REDO::NEWITEM: /* new items are deleted */
if( eda_item->IsBOARD_ITEM() )
{
aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii );
GetModel()->Remove( (BOARD_ITEM*) eda_item, REMOVE_MODE::BULK );
GetModel()->Remove( static_cast<BOARD_ITEM*>( eda_item ), REMOVE_MODE::BULK );
update_item_change_state( eda_item, ITEM_CHANGE_TYPE::DELETED );
if( eda_item->Type() != PCB_NETINFO_T )
@ -480,15 +510,19 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( eda_item->Type() == PCB_ZONE_T && static_cast<ZONE*>( eda_item )->GetIsRuleArea() )
dirty_rule_areas.push_back( eda_item->GetBoundingBox() );
}
break;
case UNDO_REDO::DELETED: /* deleted items are put in List, as new items */
if( eda_item->IsBOARD_ITEM() )
{
aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii );
clear_local_ratsnest_flags( eda_item );
eda_item->ClearFlags( UR_TRANSIENT );
GetModel()->Add( (BOARD_ITEM*) eda_item, ADD_MODE::BULK_APPEND );
GetModel()->Add( static_cast<BOARD_ITEM*>( eda_item ), ADD_MODE::BULK_APPEND );
update_item_change_state( eda_item, ITEM_CHANGE_TYPE::ADDED );
if( eda_item->Type() != PCB_NETINFO_T )
@ -496,6 +530,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( eda_item->Type() == PCB_ZONE_T && static_cast<ZONE*>( eda_item )->GetIsRuleArea() )
dirty_rule_areas.push_back( eda_item->GetBoundingBox() );
}
break;
@ -517,15 +552,17 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
case UNDO_REDO::PAGESETTINGS:
if( eda_item->Type() == WS_PROXY_UNDO_ITEM_T || eda_item->Type() == WS_PROXY_UNDO_ITEM_PLUS_T )
{
// swap current settings with stored settings
DS_PROXY_UNDO_ITEM alt_item( this );
DS_PROXY_UNDO_ITEM* item = static_cast<DS_PROXY_UNDO_ITEM*>( eda_item );
item->Restore( this );
*item = std::move( alt_item );
break;
}
break;
default:
wxFAIL_MSG( wxString::Format( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
aList->GetPickedItemStatus( ii ) ) );

View File

@ -654,11 +654,9 @@ PCB_NET_INSPECTOR_PANEL::calculateNets( const std::vector<NETINFO_ITEM*>& aNetCo
std::mutex resultsMutex;
thread_pool& tp = GetKiCadThreadPool();
auto resultsFuture = tp.parallelize_loop(
auto resultsFuture = tp.submit_loop(
0, foundNets.size(),
[&, this, calc]( const int start, const int end )
{
for( int i = start; i < end; ++i )
[&, this, calc]( const int i )
{
int netCode = foundNets[i]->GetNetCode();
@ -695,7 +693,6 @@ PCB_NET_INSPECTOR_PANEL::calculateNets( const std::vector<NETINFO_ITEM*>& aNetCo
std::scoped_lock lock( resultsMutex );
results.emplace_back( std::move( new_item ) );
}
}
} );
resultsFuture.get();

View File

@ -42,6 +42,7 @@
#include <pad.h>
#include <footprint.h>
#include <pcb_field.h>
#include <template_fieldnames.h>
#include <settings/color_settings.h>
#include <string_utils.h>
#include <widgets/net_selector.h>
@ -244,12 +245,40 @@ PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_BASE_EDIT_FRA
{
m_netSelectorEditorInstance = static_cast<PG_NET_SELECTOR_EDITOR*>( it->second );
}
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
{
m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( it->second );
m_fpEditorInstance->UpdateFrame( m_frame );
}
else
{
PG_FPID_EDITOR* fpEditor = new PG_FPID_EDITOR( m_frame );
m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( wxPropertyGrid::RegisterEditorClass( fpEditor ) );
}
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_URL_EDITOR::BuildEditorName( m_frame ) );
if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
{
m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( it->second );
m_urlEditorInstance->UpdateFrame( m_frame );
}
else
{
PG_URL_EDITOR* urlEditor = new PG_URL_EDITOR( m_frame );
m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( wxPropertyGrid::RegisterEditorClass( urlEditor ) );
}
}
PCB_PROPERTIES_PANEL::~PCB_PROPERTIES_PANEL()
{
m_unitEditorInstance->UpdateFrame( nullptr );
m_fpEditorInstance->UpdateFrame( nullptr );
m_urlEditorInstance->UpdateFrame( nullptr );
}
@ -342,7 +371,14 @@ wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProp
return ret;
}
return PGPropertyFactory( aProperty, m_frame );
wxPGProperty* prop = PGPropertyFactory( aProperty, m_frame );
if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::FOOTPRINT ) )
prop->SetEditor( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
else if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::DATASHEET ) )
prop->SetEditor( PG_URL_EDITOR::BuildEditorName( m_frame ) );
return prop;
}

View File

@ -34,6 +34,8 @@ class PG_UNIT_EDITOR;
class PG_CHECKBOX_EDITOR;
class PG_RATIO_EDITOR;
class PG_NET_SELECTOR_EDITOR;
class PG_FPID_EDITOR;
class PG_URL_EDITOR;
class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL
{
@ -65,6 +67,8 @@ protected:
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
PG_RATIO_EDITOR* m_ratioEditorInstance;
PG_NET_SELECTOR_EDITOR* m_netSelectorEditorInstance;
PG_FPID_EDITOR* m_fpEditorInstance;
PG_URL_EDITOR* m_urlEditorInstance;
static std::set<wxString> m_currentFieldNames;
wxPGChoices m_nets;

View File

@ -611,7 +611,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
thread_pool& tp = GetKiCadThreadPool();
for( const std::pair<ZONE*, PCB_LAYER_ID>& fillItem : toFill )
returns.emplace_back( std::make_pair( tp.submit( fill_lambda, fillItem ), 0 ) );
returns.emplace_back( std::make_pair( tp.submit_task( [&, fillItem]() { return fill_lambda( fillItem ); } ), 0 ) );
while( !cancelled && finished != 2 * toFill.size() )
{
@ -636,9 +636,9 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
{
// Queue the next step (will re-queue the existing step if it didn't complete)
if( ret.second == 0 )
returns[ii].first = tp.submit( fill_lambda, toFill[ii] );
returns[ii].first = tp.submit_task( [&, idx = ii]() { return fill_lambda( toFill[idx] ); } );
else if( ret.second == 1 )
returns[ii].first = tp.submit( tesselate_lambda, toFill[ii] );
returns[ii].first = tp.submit_task( [&, idx = ii]() { return tesselate_lambda( toFill[idx] ); } );
}
}
}
@ -827,7 +827,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
return retval;
};
auto island_returns = tp.parallelize_loop( 0, polys_to_check.size(), island_lambda );
auto island_returns = tp.submit_blocks( 0, polys_to_check.size(), island_lambda );
cancelled = false;
// Allow island removal threads to finish

View File

@ -147,7 +147,7 @@ long PYTHON_MANAGER::Execute( const std::vector<wxString>& aArgs,
if( !aSaveOutput )
{
thread_pool& tp = GetKiCadThreadPool();
auto ret = tp.submit( monitor, process );
auto ret = tp.submit_task( [monitor, process] { monitor( process ); } );
}
}

View File

@ -5,21 +5,20 @@
# All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#cmake_minimum_required(VERSION 3.4)
# Propagate this policy (FindPythonInterp removal) so it can be detected later
if(NOT CMAKE_VERSION VERSION_LESS "3.27")
cmake_policy(GET CMP0148 _pybind11_cmp0148)
endif()
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
# the behavior using the following workaround:
if(${CMAKE_VERSION} VERSION_LESS 3.22)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.22)
cmake_minimum_required(VERSION 3.15...4.0)
if(_pybind11_cmp0148)
cmake_policy(SET CMP0148 ${_pybind11_cmp0148})
unset(_pybind11_cmp0148)
endif()
# Avoid infinite recursion if tests include this as a subdirectory
if(DEFINED PYBIND11_MASTER_PROJECT)
return()
endif()
include_guard(GLOBAL)
# Extract project version from source
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
@ -64,16 +63,15 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(PYBIND11_MASTER_PROJECT ON)
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
# Bug in macOS CMake < 3.7 is unable to download catch
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
# Only tested with 3.8+ in CI.
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
endif()
message(STATUS "CMake ${CMAKE_VERSION}")
if(DEFINED SKBUILD AND DEFINED ENV{PYBIND11_GLOBAL_SDIST})
message(
FATAL_ERROR
"PYBIND11_GLOBAL_SDIST is not supported, use nox -s build_global or a pybind11-global SDist instead."
)
endif()
if(CMAKE_CXX_STANDARD)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -82,59 +80,160 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(pybind11_system "")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(CMAKE_VERSION VERSION_LESS "3.18")
set(_pybind11_findpython_default OFF)
else()
set(_pybind11_findpython_default ON)
endif()
else()
set(PYBIND11_MASTER_PROJECT OFF)
set(pybind11_system SYSTEM)
set(_pybind11_findpython_default COMPAT)
endif()
# Options
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
option(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
"To enforce that a handle_type_name<> specialization exists" OFF)
option(PYBIND11_SIMPLE_GIL_MANAGEMENT
"Use simpler GIL management logic that does not support disassociation" OFF)
set(PYBIND11_INTERNALS_VERSION
""
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
option(PYBIND11_USE_CROSSCOMPILING "Respect CMAKE_CROSSCOMPILING" OFF)
if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
add_compile_definitions(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
endif()
if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)
endif()
cmake_dependent_option(
USE_PYTHON_INCLUDE_DIR
"Install pybind11 headers in Python include directory instead of default installation prefix"
OFF "PYBIND11_INSTALL" OFF)
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
set(PYBIND11_FINDPYTHON
${_pybind11_findpython_default}
CACHE STRING "Force new FindPython - NEW, OLD, COMPAT")
if(PYBIND11_MASTER_PROJECT)
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
# (makes transition easier while we support both modes).
if(PYBIND11_FINDPYTHON
AND DEFINED PYTHON_EXECUTABLE
AND NOT DEFINED Python_EXECUTABLE)
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()
# This is a shortcut that is primarily for the venv cmake preset,
# but can be used to quickly setup tests manually, too
set(PYBIND11_CREATE_WITH_UV
""
CACHE STRING "Create a virtualenv if it doesn't exist")
if(NOT PYBIND11_CREATE_WITH_UV STREQUAL "")
set(Python_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/.venv")
if(EXISTS "${Python_ROOT_DIR}")
if(EXISTS "${CMAKE_BINARY_DIR}/CMakeCache.txt")
message(STATUS "Using existing venv at ${Python_ROOT_DIR}, remove or --fresh to recreate")
else()
# --fresh used to remove the cache
file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/.venv")
endif()
endif()
if(NOT EXISTS "${Python_ROOT_DIR}")
find_program(UV uv REQUIRED)
# CMake 3.19+ would be able to use COMMAND_ERROR_IS_FATAL
message(
STATUS "Creating venv with ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} '${Python_ROOT_DIR}'")
execute_process(COMMAND ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} "${Python_ROOT_DIR}"
RESULT_VARIABLE _venv_result)
if(_venv_result AND NOT _venv_result EQUAL 0)
message(FATAL_ERROR "uv venv failed with '${_venv_result}'")
endif()
message(
STATUS
"Installing deps with ${UV} pip install -p '${Python_ROOT_DIR}' -r tests/requirements.txt"
)
execute_process(
COMMAND ${UV} pip install -p "${Python_ROOT_DIR}" -r
"${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt" RESULT_VARIABLE _pip_result)
if(_pip_result AND NOT _pip_result EQUAL 0)
message(FATAL_ERROR "uv pip install failed with '${_pip_result}'")
endif()
endif()
else()
if(NOT DEFINED Python3_EXECUTABLE
AND NOT DEFINED Python_EXECUTABLE
AND NOT DEFINED Python_ROOT_DIR
AND NOT DEFINED ENV{VIRTUALENV}
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
message(STATUS "Autodetecting Python in virtual environment")
set(Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
endif()
endif()
endif()
# NB: when adding a header don't forget to also add it to setup.py
set(PYBIND11_HEADERS
include/pybind11/detail/class.h
include/pybind11/detail/common.h
include/pybind11/detail/cpp_conduit.h
include/pybind11/detail/descr.h
include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h
include/pybind11/detail/exception_translation.h
include/pybind11/detail/function_record_pyobject.h
include/pybind11/detail/init.h
include/pybind11/detail/internals.h
include/pybind11/detail/native_enum_data.h
include/pybind11/detail/pybind11_namespace_macros.h
include/pybind11/detail/struct_smart_holder.h
include/pybind11/detail/type_caster_base.h
include/pybind11/detail/typeid.h
include/pybind11/detail/using_smart_holder.h
include/pybind11/detail/value_and_holder.h
include/pybind11/attr.h
include/pybind11/buffer_info.h
include/pybind11/cast.h
include/pybind11/chrono.h
include/pybind11/common.h
include/pybind11/complex.h
include/pybind11/conduit/pybind11_conduit_v1.h
include/pybind11/conduit/pybind11_platform_abi_id.h
include/pybind11/conduit/wrap_include_python_h.h
include/pybind11/critical_section.h
include/pybind11/options.h
include/pybind11/eigen.h
include/pybind11/eigen/common.h
include/pybind11/eigen/matrix.h
include/pybind11/eigen/tensor.h
include/pybind11/embed.h
include/pybind11/eval.h
include/pybind11/gil.h
include/pybind11/gil_safe_call_once.h
include/pybind11/gil_simple.h
include/pybind11/iostream.h
include/pybind11/functional.h
include/pybind11/native_enum.h
include/pybind11/numpy.h
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/subinterpreter.h
include/pybind11/stl.h
include/pybind11/stl_bind.h
include/pybind11/stl/filesystem.h)
include/pybind11/stl/filesystem.h
include/pybind11/trampoline_self_life_support.h
include/pybind11/type_caster_pyobject_ptr.h
include/pybind11/typing.h
include/pybind11/warnings.h)
# Compare with grep and warn if mismatched
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
if(PYBIND11_MASTER_PROJECT)
file(
GLOB_RECURSE _pybind11_header_check
LIST_DIRECTORIES false
@ -152,10 +251,7 @@ if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
endif()
endif()
# CMake 3.12 added list(TRANSFORM <list> PREPEND
# But we can't use it yet
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
"${PYBIND11_HEADERS}")
list(TRANSFORM PYBIND11_HEADERS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
# Cache variable so this can be used in parent projects
set(pybind11_INCLUDE_DIR
@ -198,6 +294,9 @@ else()
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
# https://github.com/jtojnar/cmake-snips/#concatenating-paths-when-building-pkg-config-files
# TODO: cmake 3.20 adds the cmake_path() function, which obsoletes this snippet
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake")
# Relative directory setting
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
@ -207,6 +306,9 @@ elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
endif()
if(PYBIND11_INSTALL)
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11_global")
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION "${SKBUILD_HEADERS_DIR}")
endif()
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
@ -222,25 +324,11 @@ if(PYBIND11_INSTALL)
tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
if(CMAKE_VERSION VERSION_LESS 3.14)
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
# not depend on architecture specific settings or libraries.
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
unset(CMAKE_SIZEOF_VOID_P)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
else()
# CMake 3.14+ natively supports header-only libraries
# CMake natively supports header-only libraries
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
endif()
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
@ -249,6 +337,7 @@ if(PYBIND11_INSTALL)
tools/pybind11Common.cmake
tools/pybind11Tools.cmake
tools/pybind11NewTools.cmake
tools/pybind11GuessPythonExtSuffix.cmake
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
if(NOT PYBIND11_EXPORT_NAME)
@ -262,6 +351,41 @@ if(PYBIND11_INSTALL)
NAMESPACE "pybind11::"
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
# pkg-config support
if(NOT prefix_for_pc_file)
if(IS_ABSOLUTE "${CMAKE_INSTALL_DATAROOTDIR}")
set(prefix_for_pc_file "${CMAKE_INSTALL_PREFIX}")
else()
set(pc_datarootdir "${CMAKE_INSTALL_DATAROOTDIR}")
if(CMAKE_VERSION VERSION_LESS 3.20)
set(prefix_for_pc_file "\${pcfiledir}/..")
while(pc_datarootdir)
get_filename_component(pc_datarootdir "${pc_datarootdir}" DIRECTORY)
string(APPEND prefix_for_pc_file "/..")
endwhile()
else()
cmake_path(RELATIVE_PATH CMAKE_INSTALL_PREFIX BASE_DIRECTORY CMAKE_INSTALL_DATAROOTDIR
OUTPUT_VARIABLE prefix_for_pc_file)
endif()
endif()
endif()
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
# When building a wheel, include __init__.py's for modules
# (see https://github.com/pybind/pybind11/pull/5552)
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/empty")
file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
endif()
# Uninstall target
if(PYBIND11_MASTER_PROJECT)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"

View File

@ -1,6 +0,0 @@
recursive-include pybind11/include/pybind11 *.h
recursive-include pybind11 *.py
recursive-include pybind11 py.typed
recursive-include pybind11 *.pyi
include pybind11/share/cmake/pybind11/*.cmake
include LICENSE README.rst pyproject.toml setup.py setup.cfg

View File

@ -1,9 +1,11 @@
.. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
:alt: pybind11 logo
**pybind11 — Seamless operability between C++11 and Python**
**pybind11 (v3) — Seamless interoperability between C++ and Python**
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions|
|CI| |Build status| |SPEC 4 — Using and Creating Nightly Wheels|
|Repology| |PyPI package| |Conda-forge| |Python Versions|
@ -32,14 +34,14 @@ this heavy machinery has become an excessively large and unnecessary
dependency.
Think of this library as a tiny self-contained version of Boost.Python
with everything stripped away that isnt relevant for binding
with everything stripped away that isn't relevant for binding
generation. Without comments, the core header files only require ~4K
lines of code and depend on Python (2.7 or 3.5+, or PyPy) and the C++
standard library. This compact implementation was possible thanks to
some of the new C++11 language features (specifically: tuples, lambda
functions and variadic templates). Since its creation, this library has
grown beyond Boost.Python in many ways, leading to dramatically simpler
binding code in many common situations.
lines of code and depend on Python (CPython 3.8+, PyPy, or GraalPy) and the C++
standard library. This compact implementation was possible thanks to some C++11
language features (specifically: tuples, lambda functions and variadic
templates). Since its creation, this library has grown beyond Boost.Python in
many ways, leading to dramatically simpler binding code in many common
situations.
Tutorial and reference documentation is provided at
`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
@ -71,6 +73,7 @@ pybind11 can map the following core C++ features to Python:
- Internal references with correct reference counting
- C++ classes with virtual (and pure virtual) methods can be extended
in Python
- Integrated NumPy support (NumPy 2 requires pybind11 2.12+)
Goodies
-------
@ -78,8 +81,9 @@ Goodies
In addition to the core functionality, pybind11 provides some extra
goodies:
- Python 2.7, 3.5+, and PyPy/PyPy3 7.3 are supported with an
implementation-agnostic interface.
- CPython 3.8+, PyPy3 7.3.17+, and GraalPy 24.1+ are supported with an
implementation-agnostic interface (see older versions for older CPython
and PyPy versions).
- It is possible to bind C++11 lambda functions with captured
variables. The lambda capture data is stored inside the resulting
@ -88,8 +92,8 @@ goodies:
- pybind11 uses C++11 move constructors and move assignment operators
whenever possible to efficiently transfer custom data types.
- Its easy to expose the internal storage of custom data types through
Pythons buffer protocols. This is handy e.g. for fast conversion
- It's easy to expose the internal storage of custom data types through
Pythons' buffer protocols. This is handy e.g. for fast conversion
between C++ matrix classes like Eigen and NumPy without expensive
copy operations.
@ -119,25 +123,55 @@ goodies:
Supported compilers
-------------------
1. Clang/LLVM 3.3 or newer (for Apple Xcodes clang, this is 5.0.0 or
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
newer)
2. GCC 4.8 or newer
3. Microsoft Visual Studio 2015 Update 3 or newer
3. Microsoft Visual Studio 2022 or newer (2019 probably works, but was dropped in CI)
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
5. Cygwin/GCC (previously tested on 2.5.1)
6. NVCC (CUDA 11.0 tested in CI)
7. NVIDIA PGI (20.9 tested in CI)
Supported Platforms
-------------------
* Windows, Linux, macOS, and iOS
* CPython 3.8+, Pyodide, PyPy, and GraalPy
* C++11, C++14, C++17, C++20, and C++23
About
-----
This project was created by `Wenzel
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
improvements to the code were contributed by
Jonas Adler,
Lori A. Burns,
Sylvain Corlay,
Eric Cousineau,
Aaron Gokaslan,
Ralf Grosse-Kunstleve,
Trent Houliston,
Axel Huebl,
@hulucc,
Yannick Jadoul,
Sergey Lyskov,
Johan Mabille,
Tomasz Miąsko,
Dean Moldovan,
Ben Pritchard,
Jason Rhinelander,
Boris Schäling,
Pim Schellart,
Henry Schreiner,
Ivan Smirnov,
Dustin Spicuzza,
Boris Staletic,
Ethan Steinberg,
Patrick Stewart,
Ivor Wanders,
and
Xiaofei Wang.
We thank Google for a generous financial contribution to the continuous
integration infrastructure used by this project.
@ -178,3 +212,5 @@ to the terms and conditions of this license.
:target: https://pypi.org/project/pybind11/
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
:target: https://github.com/pybind/pybind11/discussions
.. |SPEC 4 — Using and Creating Nightly Wheels| image:: https://img.shields.io/badge/SPEC-4-green?labelColor=%23004811&color=%235CA038
:target: https://scientific-python.org/specs/spec-0004/

13
thirdparty/pybind11/SECURITY.md vendored Normal file
View File

@ -0,0 +1,13 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/pybind/pybind11/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.

View File

@ -18,5 +18,4 @@ ALIASES += "endrst=\endverbatim"
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
PREDEFINED = PY_MAJOR_VERSION=3 \
PYBIND11_NOINLINE
PREDEFINED = PYBIND11_NOINLINE

Some files were not shown because too many files have changed in this diff Show More