Compare commits

...

40 Commits

Author SHA1 Message Date
Daniel Treffenstädt
df6ce87f32 Merge branch 'HatchingOffsets' into 'master'
UI Controls for zone hatching offsets (Follow-on for !2070)

See merge request kicad/code/kicad!2272
2025-09-11 21:31:15 +02:00
Jeff Young
18b56539a6 Keep Board Setup in front when called from DRC dialog. 2025-09-11 15:47:13 +01:00
Jeff Young
9b006c4f3b Formatting. 2025-09-11 15:47:13 +01:00
Jeff Young
8035a66152 Flag non-compiling rule conditions when running DRC.
Also, clear custom rules after an error before
trying to reload just implicit rules.
2025-09-11 15:47:13 +01:00
jean-pierre charras
45166bf5c3 Gerbview: fix broken behavior for deprecated command IPPOS and IPNEG
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21715
2025-09-11 14:30:50 +02:00
Jeff Young
6ab6283e2e LIBEVAL::CONTEXT manages its own local VALUEs.
Don't use std::unique_ptr as we'll just free the
value right after storing it.

Also, don't try to execute a non-existent function.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21697
2025-09-11 12:49:41 +01:00
Seth Hillbrand
fc7d91214d Make pasting in lib tables easier
You generally copy/paste whole rows in lib tables, so make this workflow
easier.  Allows pasting rows as new data.  Prevent overwriting existing
data and don't force pasting from the first column
2025-09-11 02:30:49 -07:00
Seth Hillbrand
dcbadb5857 Allow drag-drop for schematic elements
Dragging screen elements over a subsheet allows moving elements into a
subsheet
2025-09-11 02:16:47 -07:00
jean-pierre charras
3b97804cb6 DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR: add missing layers to always allowed list 2025-09-11 11:07:16 +02:00
Mark Roszko
e72def55a9 Remove moronic pybind forcing expectation of python release builds 2025-09-11 07:16:52 +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
Daniel Treffenstädt
1082ba3c8a
Implemented per layer properties in dialog_copper_zones 2025-09-08 09:57:14 +02:00
Daniel Treffenstädt
a4c8da229e
Modified UI: auto generated classes 2025-09-08 09:57:14 +02:00
Daniel Treffenstädt
b0a21df548
Implemented zone hatching offsets in UI 2025-09-08 09:57:14 +02:00
Daniel Treffenstädt
d969ba2572
Modified auto-generated classes in zone manager 2025-09-08 09:57:13 +02:00
434 changed files with 43735 additions and 14654 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>
@ -92,28 +100,12 @@ END_EVENT_TABLE()
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs,
BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera,
S3D_CACHE* a3DCachePointer ) :
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 )
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, aGLAttribs,
EDA_3D_CANVAS_ID, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
m_boardAdapter( aBoardAdapter )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
@ -481,8 +473,10 @@ 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;
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
// 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();
@ -1066,9 +1061,45 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
{
RAY mouseRay = getRayAtCurrentMousePosition();
BOARD_ITEM *intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
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,32 +1059,35 @@ 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;
BOX2D r = GetCanvas()->GetView()->GetViewport();
// Center if we're off the current view, or within 10% of its edge
r.Inflate( - r.GetWidth() / 10.0 );
if( !r.Contains( aPos ) )
centerView = true;
bool centerView = false;
std::vector<BOX2D> dialogScreenRects;
for( wxWindow* dialog : findDialogs() )
if( aAllowScroll )
{
dialogScreenRects.emplace_back( ToVECTOR2D( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ) ),
ToVECTOR2D( dialog->GetSize() ) );
}
BOX2D r = GetCanvas()->GetView()->GetViewport();
// Center if we're behind an obscuring dialog, or within 10% of its edge
for( BOX2D rect : dialogScreenRects )
{
rect.Inflate( rect.GetWidth() / 10 );
// Center if we're off the current view, or within 10% of its edge
r.Inflate( - r.GetWidth() / 10.0 );
if( rect.Contains( GetCanvas()->GetView()->ToScreen( aPos ) ) )
if( !r.Contains( aPos ) )
centerView = true;
for( wxWindow* dialog : findDialogs() )
{
dialogScreenRects.emplace_back( ToVECTOR2D( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ) ),
ToVECTOR2D( dialog->GetSize() ) );
}
// Center if we're behind an obscuring dialog, or within 10% of its edge
for( BOX2D rect : dialogScreenRects )
{
rect.Inflate( rect.GetWidth() / 10 );
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

@ -19,11 +19,23 @@
#include "lib_table_grid_tricks.h"
#include "lib_table_grid.h"
#include <wx/clipbrd.h>
#include <wx/log.h>
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) :
GRID_TRICKS( aGrid )
{
m_grid->Disconnect( wxEVT_CHAR_HOOK );
m_grid->Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( LIB_TABLE_GRID_TRICKS::onCharHook ), nullptr, this );
}
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid,
std::function<void( wxCommandEvent& )> aAddHandler ) :
GRID_TRICKS( aGrid, aAddHandler )
{
m_grid->Disconnect( wxEVT_CHAR_HOOK );
m_grid->Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( LIB_TABLE_GRID_TRICKS::onCharHook ), nullptr, this );
}
@ -134,6 +146,61 @@ void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
GRID_TRICKS::doPopupSelection( event );
}
}
void LIB_TABLE_GRID_TRICKS::onCharHook( wxKeyEvent& ev )
{
if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' && m_grid->IsCellEditControlShown() )
{
wxLogNull doNotLog;
if( wxTheClipboard->Open() )
{
if( wxTheClipboard->IsSupported( wxDF_TEXT ) || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
{
wxTextDataObject data;
wxTheClipboard->GetData( data );
wxString text = data.GetText();
if( !text.Contains( '\t' ) && text.Contains( ',' ) )
text.Replace( ',', '\t' );
if( text.Contains( '\t' ) || text.Contains( '\n' ) || text.Contains( '\r' ) )
{
m_grid->CancelPendingChanges();
int row = m_grid->GetGridCursorRow();
// Check if the current row already has data (has a nickname)
wxGridTableBase* table = m_grid->GetTable();
if( table && row >= 0 && row < table->GetNumberRows() )
{
// Check if the row has a nickname (indicating it has existing data)
wxString nickname = table->GetValue( row, COL_NICKNAME );
if( !nickname.IsEmpty() )
{
// Row already has data, don't allow pasting over it
wxTheClipboard->Close();
wxBell(); // Provide audio feedback
return;
}
}
m_grid->ClearSelection();
m_grid->SelectRow( row );
m_grid->SetGridCursor( row, 0 );
getSelectedArea();
paste_text( text );
wxTheClipboard->Close();
m_grid->ForceRefresh();
return;
}
}
wxTheClipboard->Close();
}
}
GRID_TRICKS::onCharHook( ev );
}
bool LIB_TABLE_GRID_TRICKS::handleDoubleClick( wxGridEvent& aEvent )

View File

@ -1160,7 +1160,9 @@ void UOP::Exec( CONTEXT* ctx )
return;
case TR_OP_METHOD_CALL:
m_func( ctx, m_ref.get() );
if( m_func )
m_func( ctx, m_ref.get() );
return;
default:
@ -1321,9 +1323,8 @@ VALUE* UCODE::Run( CONTEXT* ctx )
}
catch(...)
{
// rules which fail outright should not be fired
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
return ctx->StoreValue( temp_false.get() );
// rules which fail outright should not be fired; return 0/false
return ctx->StoreValue( new VALUE( 0 ) );
}
if( ctx->SP() == 1 )
@ -1339,8 +1340,7 @@ VALUE* UCODE::Run( CONTEXT* ctx )
wxASSERT( ctx->SP() == 1 );
// non-well-formed rules should not be fired on a release build
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
return ctx->StoreValue( temp_false.get() );
return ctx->StoreValue( new VALUE( 0 ) );
}
}

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 )
hotkey += MD_CTRL;
int mods = aKeyStroke.GetModifiers();
if( aKeyStroke.GetModifiers() & wxMOD_ALT )
hotkey += MD_ALT;
// 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_SHIFT )
if( mods & wxMOD_ALT )
hotkey += MD_ALT;
}
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() )
int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey |= MD_ALTGR;
else
{
if( mods & wxMOD_ALT )
hotkey |= MD_ALT;
if( mods & wxMOD_CONTROL )
hotkey |= MD_CTRL;
}
if( mods & wxMOD_SHIFT )
hotkey |= MD_SHIFT;
if( aKeyStroke.AltDown() )
hotkey |= MD_ALT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey |= MD_META;
#endif
if( aKeyStroke.ControlDown() )
hotkey |= MD_CTRL;
#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() )
key |= MD_CTRL;
// 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() )
key |= MD_ALT;
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,11 +1614,10 @@ 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] );
update_lambda( dirty_graphs[ii] );
});
results.wait();
@ -2257,11 +2256,10 @@ 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();
m_driver_subgraphs[ii]->UpdateItemConnections();
});
results.wait();
@ -2464,12 +2462,11 @@ 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] );
});
updateItemConnectionsTask( m_driver_subgraphs[ii] );
} );
results2.wait();
m_net_code_to_subgraphs_map.clear();

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

@ -38,6 +38,7 @@
#include <lib_table_grid.h>
#include <wildcards_and_files_ext.h>
#include <env_paths.h>
#include <functional>
#include <eeschema_id.h>
#include <symbol_edit_frame.h>
#include <symbol_viewer_frame.h>
@ -153,6 +154,13 @@ public:
{
}
SYMBOL_GRID_TRICKS( DIALOG_EDIT_LIBRARY_TABLES* aParent, WX_GRID* aGrid,
std::function<void( wxCommandEvent& )> aAddHandler ) :
LIB_TABLE_GRID_TRICKS( aGrid, aAddHandler ),
m_dialog( aParent )
{
}
protected:
DIALOG_EDIT_LIBRARY_TABLES* m_dialog;
@ -224,8 +232,21 @@ protected:
}
else
{
// paste spreadsheet formatted text.
GRID_TRICKS::paste_text( cb_text );
wxString text = cb_text;
if( !text.Contains( '\t' ) && text.Contains( ',' ) )
text.Replace( ',', '\t' );
if( text.Contains( '\t' ) )
{
int row = m_grid->GetGridCursorRow();
m_grid->ClearSelection();
m_grid->SelectRow( row );
m_grid->SetGridCursor( row, 0 );
getSelectedArea();
}
GRID_TRICKS::paste_text( text );
m_grid->AutoSizeColumns( false );
}
@ -250,7 +271,8 @@ void PANEL_SYM_LIB_TABLE::setupGrid( WX_GRID* aGrid )
};
// add Cut, Copy, and Paste to wxGrids
aGrid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, aGrid ) );
aGrid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, aGrid,
[this]( wxCommandEvent& event ) { appendRowHandler( event ); } ) );
aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );

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;
@ -328,40 +333,31 @@ private:
static std::vector<NETLIST_PLUGIN_SETTINGS> netlistSettingsFromJson( const nlohmann::json& aObj );
public:
APPEARANCE m_Appearance;
APPEARANCE m_Appearance;
AUI_PANELS m_AuiPanels;
AUTOPLACE_FIELDS m_AutoplaceFields;
DRAWING m_Drawing;
INPUT m_Input;
AUTOPLACE_FIELDS m_AutoplaceFields;
SELECTION m_Selection;
AUI_PANELS m_AuiPanels;
DRAWING m_Drawing;
FIND_REPLACE_EXTRA m_FindReplaceExtra;
INPUT m_Input;
PAGE_SETTINGS m_PageSettings;
PANEL_ANNOTATE m_AnnotatePanel;
PANEL_BOM m_BomPanel;
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;
PANEL_LIB_VIEW m_LibViewPanel;
FIND_REPLACE_EXTRA m_FindReplaceExtra;
DIALOG_ERC m_ERCDialog;
DIALOG_IMPORT_GRAPHICS m_ImportGraphics;
PANEL_NETLIST m_NetlistPanel;
SIMULATOR m_Simulator;
PANEL_SYM_CHOOSER m_SymChooserPanel;
bool m_RescueNeverShow;
DIALOG_IMPORT_GRAPHICS m_ImportGraphics;
SELECTION m_Selection;
SIMULATOR m_Simulator;
bool m_RescueNeverShow;
wxString m_lastSymbolLibDir;
wxString m_lastSymbolLibDir;
};

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

@ -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,11 +140,10 @@ 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 );
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;
@ -3265,10 +3275,11 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
m_view->ClearPreview();
m_view->AddToPreview( sheet->Clone() );
}
else if( sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick )
|| evt->IsAction( &ACTIONS::finishInteractive ) ) )
else if( sheet && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &ACTIONS::cursorClick ) || evt->IsAction( &ACTIONS::cursorDblClick )
|| 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

@ -46,6 +46,9 @@
#include <pgm_base.h>
#include <view/view_controls.h>
#include <settings/settings_manager.h>
#include <math/box2.h>
#include <base_units.h>
#include <sch_screen.h>
#include "sch_move_tool.h"
@ -500,6 +503,7 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
TOOL_EVENT* evt = &copy;
VECTOR2I prevPos;
GRID_HELPER_GRIDS snapLayer = GRID_CURRENT;
SCH_SHEET* hoverSheet = nullptr;
m_cursor = controls->GetCursorPosition();
@ -771,7 +775,65 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
m_cursor = grid.BestSnapAnchor( controls->GetCursorPosition( false ),
snapLayer, selection );
// Determine potential target sheet.
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( m_frame->GetScreen()->GetItem( m_cursor, 0,
SCH_SHEET_T ) );
if( sheet && sheet->IsSelected() )
sheet = nullptr; // Never target a selected sheet
if( !sheet )
{
// Build current selection bounding box in its (already moved) position.
BOX2I selBBox;
for( EDA_ITEM* it : selection )
{
if( SCH_ITEM* schIt = dynamic_cast<SCH_ITEM*>( it ) )
selBBox.Merge( schIt->GetBoundingBox() );
}
if( selBBox.GetWidth() > 0 && selBBox.GetHeight() > 0 )
{
VECTOR2I selCenter( selBBox.GetX() + selBBox.GetWidth() / 2,
selBBox.GetY() + selBBox.GetHeight() / 2 );
// Find first non-selected sheet whose body fully contains the selection
// or at least contains its center point.
for( SCH_ITEM* it : m_frame->GetScreen()->Items().OfType( SCH_SHEET_T ) )
{
SCH_SHEET* candidate = static_cast<SCH_SHEET*>( it );
if( candidate->IsSelected() || candidate->IsRootSheet() )
continue;
BOX2I body = candidate->GetBodyBoundingBox();
if( body.Contains( selBBox ) || body.Contains( selCenter ) )
{
sheet = candidate;
break;
}
}
}
}
if( sheet != hoverSheet )
{
if( hoverSheet )
{
hoverSheet->ClearFlags( BRIGHTENED );
m_frame->UpdateItem( hoverSheet, false );
}
hoverSheet = sheet;
if( hoverSheet )
{
hoverSheet->SetFlags( BRIGHTENED );
m_frame->UpdateItem( hoverSheet, false );
}
}
m_frame->GetCanvas()->SetCurrentCursor( hoverSheet ? KICURSOR::PLACE
: KICURSOR::MOVING );
VECTOR2I delta( m_cursor - prevPos );
m_anchorPos = m_cursor;
@ -1032,6 +1094,22 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
} while( ( evt = Wait() ) ); //Should be assignment not equality test
SCH_SHEET* targetSheet = hoverSheet;
if( hoverSheet )
{
hoverSheet->ClearFlags( BRIGHTENED );
m_frame->UpdateItem( hoverSheet, false );
}
if( targetSheet )
{
moveSelectionToSheet( selection, targetSheet, aCommit );
m_toolMgr->RunAction( ACTIONS::selectionClear );
m_newDragLines.clear();
m_changedDragLines.clear();
}
// Create a selection of original selection, drag selected/changed items, and new
// bend lines for later before we clear them in the aCommit. We'll need these
// to check for new junctions needed, etc.
@ -1135,6 +1213,60 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
}
void SCH_MOVE_TOOL::moveSelectionToSheet( SCH_SELECTION& aSelection, SCH_SHEET* aTargetSheet,
SCH_COMMIT* aCommit )
{
SCH_SCREEN* destScreen = aTargetSheet->GetScreen();
SCH_SCREEN* srcScreen = m_frame->GetScreen();
BOX2I bbox;
for( EDA_ITEM* item : aSelection )
bbox.Merge( static_cast<SCH_ITEM*>( item )->GetBoundingBox() );
VECTOR2I offset = VECTOR2I( 0, 0 ) - bbox.GetPosition();
int step = schIUScale.MilsToIU( 50 );
bool overlap = false;
do
{
BOX2I moved = bbox;
moved.Move( offset );
overlap = false;
for( SCH_ITEM* existing : destScreen->Items() )
{
if( moved.Intersects( existing->GetBoundingBox() ) )
{
overlap = true;
break;
}
}
if( overlap )
offset += VECTOR2I( step, step );
} while( overlap );
for( EDA_ITEM* item : aSelection )
{
SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
// Remove from current screen and view manually
m_frame->RemoveFromScreen( schItem, srcScreen );
// Move the item
schItem->Move( offset );
// Add to destination screen manually (won't add to view since it's not current)
destScreen->Append( schItem );
// Record in commit with CHT_DONE flag to bypass automatic screen/view operations
aCommit->Stage( schItem, CHT_REMOVE | CHT_DONE, srcScreen );
aCommit->Stage( schItem, CHT_ADD | CHT_DONE, destScreen );
}
}
void SCH_MOVE_TOOL::trimDanglingLines( SCH_COMMIT* aCommit )
{
// Need a local cleanup first to ensure we remove unneeded junctions
@ -1163,8 +1295,7 @@ void SCH_MOVE_TOOL::trimDanglingLines( SCH_COMMIT* aCommit )
{
line->SetFlags( STRUCT_DELETED );
aCommit->Removed( line, m_frame->GetScreen() );
updateItem( line, false );
updateItem( line, false ); // Update any cached visuals before commit processes
m_frame->RemoveFromScreen( line, m_frame->GetScreen() );
}
}

View File

@ -35,6 +35,9 @@ class SCH_LINE;
class SCH_LABEL_BASE;
class SCH_SHEET_PIN;
class SCH_JUNCTION;
class SCH_SELECTION;
class SCH_SHEET;
class SCH_COMMIT;
struct SPECIAL_CASE_LABEL_INFO
@ -81,6 +84,8 @@ private:
void orthoLineDrag( SCH_COMMIT* aCommit, SCH_LINE* line, const VECTOR2I& splitDelta,
int& xBendCount, int& yBendCount, const EE_GRID_HELPER& grid );
void moveSelectionToSheet( SCH_SELECTION& aSelection, SCH_SHEET* aTarget, SCH_COMMIT* aCommit );
///< Clears the new drag lines and removes them from the screen
void clearNewDragLines();

View File

@ -546,15 +546,36 @@ void HIERARCHY_PANE::onCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL )
hotkey += MD_CTRL;
int mods = aKeyStroke.GetModifiers();
if( aKeyStroke.GetModifiers() & wxMOD_ALT )
hotkey += MD_ALT;
// 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_SHIFT )
if( mods & wxMOD_ALT )
hotkey += MD_ALT;
}
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

@ -671,8 +671,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int aCommand, char* aBuff,
break;
case IMAGE_POLARITY:
// These commands are deprecated since 2012.
// So do nothing and prompt the user about this command
// Note: these commands IPPOS and IPNEG are deprecated since 2012.
if( strncasecmp( aText, "NEG", 3 ) == 0 )
{
m_ImageNegative = true;
@ -688,7 +687,6 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int aCommand, char* aBuff,
// actual effect. Just skip it.
}
ok = false;
break;
case LOAD_POLARITY:

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

@ -18,6 +18,7 @@
*/
#include "grid_tricks.h"
#include <functional>
class LIB_TABLE_GRID_TRICKS : public GRID_TRICKS
{
@ -33,6 +34,7 @@ class LIB_TABLE_GRID_TRICKS : public GRID_TRICKS
public:
explicit LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid );
LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid, std::function<void( wxCommandEvent& )> aAddHandler );
virtual ~LIB_TABLE_GRID_TRICKS(){};
@ -43,5 +45,7 @@ protected:
virtual void optionsEditor( int aRow ) = 0;
bool handleDoubleClick( wxGridEvent& aEvent ) override;
void onCharHook( wxKeyEvent& ev );
virtual bool supportsVisibilityColumn() { return false; }
};

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

@ -327,7 +327,9 @@ class INFOBAR_REPORTER : public REPORTER
{
public:
INFOBAR_REPORTER( WX_INFOBAR* aInfoBar ) :
REPORTER(), m_messageSet( false ), m_infoBar( aInfoBar ),
REPORTER(),
m_messageSet( false ),
m_infoBar( aInfoBar ),
m_severity( RPT_SEVERITY_UNDEFINED )
{
}

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() )
m_bitmapIcon->SetBitmap( *icon );
{
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,25 +2297,21 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
thread_pool& tp = GetKiCadThreadPool();
tp.push_task(
[this]()
{
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
tp.submit_task( [this]()
{
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
if( !gitCommon )
{
wxLogTrace( traceGit, "onGitSyncTimer: No git repository found" );
return;
}
if( !gitCommon )
{
wxLogTrace( traceGit, "onGitSyncTimer: No git repository found" );
return;
}
GIT_PULL_HANDLER handler( gitCommon );
handler.PerformFetch();
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
{
if( aReporter && aReporter->IsCancelled() )
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
{
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,19 +191,17 @@ 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();
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();
dirty_nets[ii]->OptimizeRNEdges();
} );
results2.wait();
@ -370,11 +368,10 @@ 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 );
update_lambda( ii );
});
results.wait();

View File

@ -55,8 +55,8 @@
#define RESOLVE_PAGE( T, pageIndex ) static_cast<T*>( m_treebook->ResolvePage( pageIndex ) )
DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
PAGED_DIALOG( aFrame, _( "Board Setup" ), false, false,
DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParent ) :
PAGED_DIALOG( aParent ? aParent : aFrame, _( "Board Setup" ), false, false,
_( "Import Settings from Another Board..." ), wxSize( 980, 600 ) ),
m_frame( aFrame ),
m_layers( nullptr ),

View File

@ -42,7 +42,7 @@ class PANEL_TEXT_VARIABLES;
class DIALOG_BOARD_SETUP : public PAGED_DIALOG
{
public:
DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame );
DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aWindow = nullptr );
~DIALOG_BOARD_SETUP();
protected:

View File

@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "layer_ids.h"
#include <wx/radiobut.h>
#include <kiface_base.h>
#include <confirm.h>
@ -36,6 +37,7 @@
#include <trigo.h>
#include <eda_pattern_match.h>
#include <pcb_layer_box_selector.h>
#include <dialog_copper_zones_base.h>
#include <string_utils.h>
@ -76,6 +78,8 @@ private:
void OnNetSelectionUpdated( wxCommandEvent& event ) override;
void OnRemoveIslandsSelection( wxCommandEvent& event ) override;
void OnPadInZoneSelection( wxCommandEvent& event ) override;
void OnLayerSelectorChanged( wxCommandEvent& event ) override;
void OnHatchingOffsetChecked( wxCommandEvent& event ) override;
void readNetInformation();
void readFilteringAndSortingCriteria();
@ -91,6 +95,7 @@ private:
void updateInfoBar();
void storePersistentNetSortConfigurations();
void loadPersistentNetSortConfigurations();
void updatePerLayerProperties();
private:
PCB_BASE_FRAME* m_Parent;
@ -130,6 +135,11 @@ private:
wxRadioButton* m_rbCenterline;
wxRadioButton* m_rbEnvelope;
wxCheckBox* m_cbDeleteOriginals;
UNIT_BINDER m_hatchingOffsetX;
UNIT_BINDER m_hatchingOffsetY;
PCB_LAYER_ID m_currentLayer;
};
@ -191,7 +201,10 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
m_convertSettings( aConvertSettings ),
m_rbCenterline( nullptr ),
m_rbEnvelope( nullptr ),
m_cbDeleteOriginals( nullptr )
m_cbDeleteOriginals( nullptr ),
m_hatchingOffsetX( aParent, m_hatchingOffsetXLabel, m_hatchingOffsetXValue, m_hatchingOffsetXUnit ),
m_hatchingOffsetY( aParent, m_hatchingOffsetYLabel, m_hatchingOffsetYValue, m_hatchingOffsetYUnit ),
m_currentLayer( UNDEFINED_LAYER )
{
m_Parent = aParent;
@ -264,6 +277,8 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
m_gap = nullptr;
}
m_currentLayer = m_settings.m_Layers.Seq().at( 0 );
m_currentlySelectedNetcode = INVALID_NET_CODE;
m_maxNetCode = INVALID_NET_CODE;
@ -377,6 +392,32 @@ bool DIALOG_COPPER_ZONE::TransferDataToWindow()
m_tcZoneName->SetValue( m_settings.m_Name );
m_layerSelector->SetLayersHotkeys( false );
m_layerSelector->SetBoardFrame( m_Parent );
m_layerSelector->SetNotAllowedLayerSet( ~( m_settings.m_Layers ) );
m_layerSelector->Resync();
if( !m_settings.m_LayerProperties.empty() )
{
m_currentLayer = m_settings.m_LayerProperties.begin()->first;
m_hatchingOffsetUseDefault->SetValue(
!m_settings.m_LayerProperties[m_currentLayer].hatching_offset.has_value() );
VECTOR2I value = m_settings.m_LayerProperties[m_currentLayer].hatching_offset.value_or( VECTOR2I( 0, 0 ) );
m_hatchingOffsetX.SetValue( value.x );
m_hatchingOffsetY.SetValue( value.y );
m_hatchingOffsetXValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
m_hatchingOffsetYValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
}
else
{
m_currentLayer = m_settings.m_Layers.Seq().at( 0 );
}
m_layerSelector->SetLayerSelection( m_currentLayer );
SetInitialFocus( m_ShowNetNameFilter );
// Enable/Disable some widgets
@ -485,6 +526,35 @@ void DIALOG_COPPER_ZONE::OnPadInZoneSelection( wxCommandEvent& event )
}
void DIALOG_COPPER_ZONE::OnLayerSelectorChanged( wxCommandEvent& aEvent )
{
if( m_currentLayer != UNDEFINED_LAYER )
{
if( !m_hatchingOffsetUseDefault->IsChecked() )
{
m_settings.m_LayerProperties[m_currentLayer].hatching_offset =
VECTOR2I( m_hatchingOffsetX.GetIntValue(), m_hatchingOffsetY.GetIntValue() );
}
else
{
m_settings.m_LayerProperties[m_currentLayer].hatching_offset.reset();
}
}
updatePerLayerProperties();
aEvent.Skip();
}
void DIALOG_COPPER_ZONE::OnHatchingOffsetChecked( wxCommandEvent& aEvent )
{
m_hatchingOffsetXValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
m_hatchingOffsetYValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
aEvent.Skip();
}
bool DIALOG_COPPER_ZONE::TransferDataFromWindow()
{
if( m_GridStyleCtrl->GetSelection() > 0 )
@ -512,6 +582,23 @@ bool DIALOG_COPPER_ZONE::TransferDataFromWindow()
m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
if( m_currentLayer != UNDEFINED_LAYER )
{
if( !m_settings.m_LayerProperties.contains( m_currentLayer ) )
m_settings.m_LayerProperties.emplace( m_currentLayer, ZONE_LAYER_PROPERTIES() );
if( !m_hatchingOffsetUseDefault->IsChecked() )
{
m_settings.m_LayerProperties[m_currentLayer].hatching_offset =
VECTOR2I( m_hatchingOffsetX.GetIntValue(), m_hatchingOffsetY.GetIntValue() );
}
else
{
m_settings.m_LayerProperties[m_currentLayer].hatching_offset.reset();
}
}
*m_ptr = m_settings;
return true;
}
@ -656,6 +743,15 @@ void DIALOG_COPPER_ZONE::OnLayerSelection( wxDataViewEvent& event )
m_layers->GetValue( layerID, row, 2 );
m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), checked );
m_layerSelector->SetNotAllowedLayerSet( ~( m_settings.m_Layers ) );
m_layerSelector->Resync();
m_currentLayer = m_settings.m_Layers.Seq().at( 0 );
m_layerSelector->SetLayerSelection( m_currentLayer );
updatePerLayerProperties();
}
@ -697,6 +793,28 @@ void DIALOG_COPPER_ZONE::loadPersistentNetSortConfigurations()
}
void DIALOG_COPPER_ZONE::updatePerLayerProperties()
{
m_currentLayer = ToLAYER_ID( m_layerSelector->GetLayerSelection() );
if( m_currentLayer != UNDEFINED_LAYER )
{
if( !m_settings.m_LayerProperties.contains( m_currentLayer ) )
m_settings.m_LayerProperties.emplace( m_currentLayer, ZONE_LAYER_PROPERTIES() );
m_hatchingOffsetUseDefault->SetValue(
!m_settings.m_LayerProperties[m_currentLayer].hatching_offset.has_value() );
VECTOR2I value = m_settings.m_LayerProperties[m_currentLayer].hatching_offset.value_or( VECTOR2I( 0, 0 ) );
m_hatchingOffsetX.SetValue( value.x );
m_hatchingOffsetY.SetValue( value.y );
m_hatchingOffsetXValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
m_hatchingOffsetYValue->Enable( !m_hatchingOffsetUseDefault->IsChecked() );
}
}
void DIALOG_COPPER_ZONE::OnShowNetNameFilterChange( wxCommandEvent& event )
{
updateDisplayedListOfNets();

View File

@ -1,10 +1,12 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "pcb_layer_box_selector.h"
#include "dialog_copper_zones_base.h"
///////////////////////////////////////////////////////////////////////////
@ -274,8 +276,10 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
bSizerMiddle->Add( bMiddleColumn, 1, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerZoneStyle;
sbSizerZoneStyle = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fill") ), wxVERTICAL );
m_fillNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_fillPanel = new wxPanel( m_fillNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer11;
bSizer11 = new wxBoxSizer( wxVERTICAL );
wxGridBagSizer* gbSizer3;
gbSizer3 = new wxGridBagSizer( 0, 0 );
@ -283,72 +287,72 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
gbSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
gbSizer3->SetEmptyCellSize( wxSize( -1,10 ) );
m_staticTextGridFillType = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Fill type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridFillType = new wxStaticText( m_fillPanel, wxID_ANY, _("Fill type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridFillType->Wrap( -1 );
gbSizer3->Add( m_staticTextGridFillType, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_GridStyleCtrlChoices[] = { _("Solid fill"), _("Hatch pattern") };
int m_GridStyleCtrlNChoices = sizeof( m_GridStyleCtrlChoices ) / sizeof( wxString );
m_GridStyleCtrl = new wxChoice( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_GridStyleCtrlNChoices, m_GridStyleCtrlChoices, 0 );
m_GridStyleCtrl = new wxChoice( m_fillPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_GridStyleCtrlNChoices, m_GridStyleCtrlChoices, 0 );
m_GridStyleCtrl->SetSelection( 0 );
gbSizer3->Add( m_GridStyleCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_staticTextGrindOrient = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGrindOrient = new wxStaticText( m_fillPanel, wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGrindOrient->Wrap( -1 );
gbSizer3->Add( m_staticTextGrindOrient, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
m_tcGridStyleOrientation = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_tcGridStyleOrientation = new wxTextCtrl( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer3->Add( m_tcGridStyleOrientation, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_staticTextRotUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextRotUnits = new wxStaticText( m_fillPanel, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextRotUnits->Wrap( -1 );
gbSizer3->Add( m_staticTextRotUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
m_staticTextStyleThickness = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Hatch width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextStyleThickness = new wxStaticText( m_fillPanel, wxID_ANY, _("Hatch width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextStyleThickness->Wrap( -1 );
gbSizer3->Add( m_staticTextStyleThickness, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_tcGridStyleThickness = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_tcGridStyleThickness = new wxTextCtrl( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer3->Add( m_tcGridStyleThickness, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_GridStyleThicknessUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_GridStyleThicknessUnits = new wxStaticText( m_fillPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_GridStyleThicknessUnits->Wrap( -1 );
gbSizer3->Add( m_GridStyleThicknessUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_staticTextGridGap = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Hatch gap:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridGap = new wxStaticText( m_fillPanel, wxID_ANY, _("Hatch gap:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridGap->Wrap( -1 );
gbSizer3->Add( m_staticTextGridGap, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_tcGridStyleGap = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_tcGridStyleGap = new wxTextCtrl( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer3->Add( m_tcGridStyleGap, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_GridStyleGapUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_GridStyleGapUnits = new wxStaticText( m_fillPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_GridStyleGapUnits->Wrap( -1 );
gbSizer3->Add( m_GridStyleGapUnits, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_staticTextGridSmoothingLevel = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Smoothing effort:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridSmoothingLevel = new wxStaticText( m_fillPanel, wxID_ANY, _("Smoothing effort:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridSmoothingLevel->Wrap( -1 );
m_staticTextGridSmoothingLevel->SetToolTip( _("Value of smoothing effort\n0 = no smoothing\n1 = chamfer\n2 = round corners\n3 = round corners (finer shape)") );
gbSizer3->Add( m_staticTextGridSmoothingLevel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spinCtrlSmoothLevel = new wxSpinCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 3, 0 );
m_spinCtrlSmoothLevel = new wxSpinCtrl( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 3, 0 );
gbSizer3->Add( m_spinCtrlSmoothLevel, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticTextGridSmootingVal = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Smoothing amount:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridSmootingVal = new wxStaticText( m_fillPanel, wxID_ANY, _("Smoothing amount:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextGridSmootingVal->Wrap( -1 );
m_staticTextGridSmootingVal->SetToolTip( _("Ratio between smoothed corners size and the gap between lines\n0 = no smoothing\n1.0 = max radius/chamfer size (half gap value)") );
gbSizer3->Add( m_staticTextGridSmootingVal, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spinCtrlSmoothValue = new wxSpinCtrlDouble( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1, 0.1, 0.1 );
m_spinCtrlSmoothValue = new wxSpinCtrlDouble( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1, 0.1, 0.1 );
m_spinCtrlSmoothValue->SetDigits( 2 );
gbSizer3->Add( m_spinCtrlSmoothValue, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticline5 = new wxStaticLine( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_staticline5 = new wxStaticLine( m_fillPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
gbSizer3->Add( m_staticline5, wxGBPosition( 6, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_staticText40 = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Remove islands:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText40 = new wxStaticText( m_fillPanel, wxID_ANY, _("Remove islands:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText40->Wrap( -1 );
m_staticText40->SetToolTip( _("Choose what to do with unconnected copper islands") );
@ -356,23 +360,23 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
wxString m_cbRemoveIslandsChoices[] = { _("Always"), _("Never"), _("Below area limit") };
int m_cbRemoveIslandsNChoices = sizeof( m_cbRemoveIslandsChoices ) / sizeof( wxString );
m_cbRemoveIslands = new wxChoice( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbRemoveIslandsNChoices, m_cbRemoveIslandsChoices, 0 );
m_cbRemoveIslands = new wxChoice( m_fillPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbRemoveIslandsNChoices, m_cbRemoveIslandsChoices, 0 );
m_cbRemoveIslands->SetSelection( 0 );
gbSizer3->Add( m_cbRemoveIslands, wxGBPosition( 7, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_islandThresholdLabel = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("Area limit:"), wxDefaultPosition, wxDefaultSize, 0 );
m_islandThresholdLabel = new wxStaticText( m_fillPanel, wxID_ANY, _("Area limit:"), wxDefaultPosition, wxDefaultSize, 0 );
m_islandThresholdLabel->Wrap( -1 );
m_islandThresholdLabel->Enable( false );
m_islandThresholdLabel->SetToolTip( _("Isolated islands smaller than this will be removed") );
gbSizer3->Add( m_islandThresholdLabel, wxGBPosition( 8, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_tcIslandThreshold = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_tcIslandThreshold = new wxTextCtrl( m_fillPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_tcIslandThreshold->Enable( false );
gbSizer3->Add( m_tcIslandThreshold, wxGBPosition( 8, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_islandThresholdUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_islandThresholdUnits = new wxStaticText( m_fillPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_islandThresholdUnits->Wrap( -1 );
m_islandThresholdUnits->Enable( false );
@ -381,10 +385,60 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
gbSizer3->AddGrowableCol( 0 );
sbSizerZoneStyle->Add( gbSizer3, 1, wxEXPAND|wxBOTTOM, 5 );
bSizer11->Add( gbSizer3, 1, wxEXPAND|wxBOTTOM, 5 );
bSizerMiddle->Add( sbSizerZoneStyle, 0, wxEXPAND|wxTOP|wxRIGHT, 10 );
m_fillPanel->SetSizer( bSizer11 );
m_fillPanel->Layout();
bSizer11->Fit( m_fillPanel );
m_fillNotebook->AddPage( m_fillPanel, _("Fill"), true );
m_layerPropertiesPanel = new wxPanel( m_fillNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxGridBagSizer* gbSizer4;
gbSizer4 = new wxGridBagSizer( 0, 0 );
gbSizer4->SetFlexibleDirection( wxBOTH );
gbSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_layerSelectorLabel = new wxStaticText( m_layerPropertiesPanel, wxID_ANY, _("Layer"), wxDefaultPosition, wxDefaultSize, 0 );
m_layerSelectorLabel->Wrap( -1 );
gbSizer4->Add( m_layerSelectorLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_layerSelector = new PCB_LAYER_BOX_SELECTOR( m_layerPropertiesPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
gbSizer4->Add( m_layerSelector, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
m_hatchingOffsetXLabel = new wxStaticText( m_layerPropertiesPanel, wxID_ANY, _("Hatching offset x"), wxDefaultPosition, wxDefaultSize, 0 );
m_hatchingOffsetXLabel->Wrap( -1 );
gbSizer4->Add( m_hatchingOffsetXLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_hatchingOffsetXValue = new wxTextCtrl( m_layerPropertiesPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer4->Add( m_hatchingOffsetXValue, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
m_hatchingOffsetXUnit = new wxStaticText( m_layerPropertiesPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_hatchingOffsetXUnit->Wrap( -1 );
gbSizer4->Add( m_hatchingOffsetXUnit, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_hatchingOffsetYLabel = new wxStaticText( m_layerPropertiesPanel, wxID_ANY, _("Hatching offset y"), wxDefaultPosition, wxDefaultSize, 0 );
m_hatchingOffsetYLabel->Wrap( -1 );
gbSizer4->Add( m_hatchingOffsetYLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_hatchingOffsetYValue = new wxTextCtrl( m_layerPropertiesPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer4->Add( m_hatchingOffsetYValue, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
m_hatchingOffsetYUnit = new wxStaticText( m_layerPropertiesPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_hatchingOffsetYUnit->Wrap( -1 );
gbSizer4->Add( m_hatchingOffsetYUnit, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_hatchingOffsetUseDefault = new wxCheckBox( m_layerPropertiesPanel, wxID_ANY, _("Use default value"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer4->Add( m_hatchingOffsetUseDefault, wxGBPosition( 3, 0 ), wxGBSpan( 1, 3 ), wxALL|wxEXPAND, 5 );
gbSizer4->AddGrowableCol( 1 );
m_layerPropertiesPanel->SetSizer( gbSizer4 );
m_layerPropertiesPanel->Layout();
gbSizer4->Fit( m_layerPropertiesPanel );
m_fillNotebook->AddPage( m_layerPropertiesPanel, _("Per layer properties"), false );
bSizerMiddle->Add( m_fillNotebook, 1, wxEXPAND | wxALL, 5 );
m_MainBoxSizer->Add( bSizerMiddle, 0, wxEXPAND, 5 );
@ -421,6 +475,8 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
m_PadInZoneOpt->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnPadInZoneSelection ), NULL, this );
m_GridStyleCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnStyleSelection ), NULL, this );
m_cbRemoveIslands->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnRemoveIslandsSelection ), NULL, this );
m_layerSelector->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnLayerSelectorChanged ), NULL, this );
m_hatchingOffsetUseDefault->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnHatchingOffsetChecked ), NULL, this );
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnButtonCancelClick ), NULL, this );
}
@ -438,6 +494,8 @@ DIALOG_COPPER_ZONE_BASE::~DIALOG_COPPER_ZONE_BASE()
m_PadInZoneOpt->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnPadInZoneSelection ), NULL, this );
m_GridStyleCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnStyleSelection ), NULL, this );
m_cbRemoveIslands->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnRemoveIslandsSelection ), NULL, this );
m_layerSelector->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnLayerSelectorChanged ), NULL, this );
m_hatchingOffsetUseDefault->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnHatchingOffsetChecked ), NULL, this );
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_ZONE_BASE::OnButtonCancelClick ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -10,6 +10,8 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class PCB_LAYER_BOX_SELECTOR;
#include "dialog_shim.h"
#include <wx/infobar.h>
#include <wx/gdicmn.h>
@ -28,6 +30,12 @@
#include <wx/choice.h>
#include <wx/statline.h>
#include <wx/gbsizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/bmpcbox.h>
#include <wx/notebook.h>
#include <wx/button.h>
#include <wx/dialog.h>
@ -93,6 +101,8 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
wxStaticText* m_spokeWidthLabel;
wxTextCtrl* m_spokeWidthCtrl;
wxStaticText* m_spokeWidthUnits;
wxNotebook* m_fillNotebook;
wxPanel* m_fillPanel;
wxStaticText* m_staticTextGridFillType;
wxChoice* m_GridStyleCtrl;
wxStaticText* m_staticTextGrindOrient;
@ -114,6 +124,16 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
wxStaticText* m_islandThresholdLabel;
wxTextCtrl* m_tcIslandThreshold;
wxStaticText* m_islandThresholdUnits;
wxPanel* m_layerPropertiesPanel;
wxStaticText* m_layerSelectorLabel;
PCB_LAYER_BOX_SELECTOR* m_layerSelector;
wxStaticText* m_hatchingOffsetXLabel;
wxTextCtrl* m_hatchingOffsetXValue;
wxStaticText* m_hatchingOffsetXUnit;
wxStaticText* m_hatchingOffsetYLabel;
wxTextCtrl* m_hatchingOffsetYValue;
wxStaticText* m_hatchingOffsetYUnit;
wxCheckBox* m_hatchingOffsetUseDefault;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
@ -128,6 +148,8 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
virtual void OnPadInZoneSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnStyleSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveIslandsSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLayerSelectorChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void OnHatchingOffsetChecked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }

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,9 +261,49 @@ 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" ) );
m_frame->ShowBoardSetupDialog( _( "Custom Rules" ), this );
}
@ -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 dist = selectedItemPos.Distance( unSelectedItemPos );
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 );
}
}
@ -930,7 +993,7 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
}
case ID_EDIT_SEVERITIES:
m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
m_frame->ShowBoardSetupDialog( _( "Violation Severity" ), this );
break;
}
@ -972,7 +1035,7 @@ void DIALOG_DRC::OnIgnoredItemRClick( wxListEvent& event )
void DIALOG_DRC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
{
m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
m_frame->ShowBoardSetupDialog( _( "Violation Severity" ), this );
}

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,136 +84,6 @@
<property name="name">bSizer12</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>
<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">1</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">Refill all zones before performing DRC</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_cbRefillZones</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"></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 class="sizeritem" expanded="false">
<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">
@ -225,71 +95,237 @@
<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>
<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">Test for parity between PCB and schematic</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_cbTestFootprints</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"></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>
</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>
<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">1</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">Refill all zones before performing DRC</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_cbRefillZones</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"></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 class="gbsizeritem" expanded="true">
<property name="border">5</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>
<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">Test for parity between PCB and schematic</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_cbTestFootprints</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"></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 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

@ -674,6 +674,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
// Check that the user isn't trying to remove a layer that is used by the footprint
usedLayers &= ~getCustomLayersFromControls();
usedLayers &= ~LSET::AllTechMask();
usedLayers &= ~LSET::UserMask();
if( usedLayers.any() )
{

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

@ -38,6 +38,7 @@
#include <wx/dirdlg.h>
#include <wx/filedlg.h>
#include <wx/msgdlg.h>
#include <functional>
#include <project.h>
#include <env_vars.h>
@ -147,6 +148,12 @@ public:
m_dialog( aParent )
{ }
FP_GRID_TRICKS( DIALOG_EDIT_LIBRARY_TABLES* aParent, WX_GRID* aGrid,
std::function<void( wxCommandEvent& )> aAddHandler ) :
LIB_TABLE_GRID_TRICKS( aGrid, aAddHandler ),
m_dialog( aParent )
{ }
protected:
DIALOG_EDIT_LIBRARY_TABLES* m_dialog;
@ -217,8 +224,21 @@ protected:
}
else
{
// paste spreadsheet formatted text.
GRID_TRICKS::paste_text( cb_text );
wxString text = cb_text;
if( !text.Contains( '\t' ) && text.Contains( ',' ) )
text.Replace( ',', '\t' );
if( text.Contains( '\t' ) )
{
int row = m_grid->GetGridCursorRow();
m_grid->ClearSelection();
m_grid->SelectRow( row );
m_grid->SetGridCursor( row, 0 );
getSelectedArea();
}
GRID_TRICKS::paste_text( text );
m_grid->AutoSizeColumns( false );
}
@ -254,7 +274,8 @@ void PANEL_FP_LIB_TABLE::setupGrid( WX_GRID* aGrid )
aGrid->SetRowSize( ii, aGrid->GetDefaultRowSize() + 4 );
// add Cut, Copy, and Paste to wxGrids
aGrid->PushEventHandler( new FP_GRID_TRICKS( m_parent, aGrid ) );
aGrid->PushEventHandler( new FP_GRID_TRICKS( m_parent, aGrid,
[this]( wxCommandEvent& event ) { appendRowHandler( event ); } ) );
aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );

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,56 +2317,54 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
}
}
auto processWorkItems = [&]( size_t start_idx, size_t end_idx ) -> bool
auto processWorkItems = [&]( size_t idx ) -> bool
{
for( size_t idx = start_idx; idx < end_idx; ++idx )
auto [gn1, gn2] = work_items[idx];
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
{
auto [gn1, gn2] = work_items[idx];
std::vector<const BOARD_ITEM*> IgnoreForTest = {
gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
};
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
{ false, true }, m_minGrooveWidth ) )
continue;
std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
std::lock_guard<std::mutex> lock( nodes_lock );
// Handle non-point node1
if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
{
std::vector<const BOARD_ITEM*> IgnoreForTest = {
gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
};
auto gnt1 = AddNode( GRAPH_NODE::POINT, gn1->m_parent, pc.a1 );
gnt1->m_connectDirectly = false;
connect1 = gnt1;
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
{ false, true }, m_minGrooveWidth ) )
continue;
std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
std::lock_guard<std::mutex> lock( nodes_lock );
// Handle non-point node1
if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
if( gn1->m_parent->IsConductive() )
{
auto gnt1 = AddNode( GRAPH_NODE::POINT, gn1->m_parent, pc.a1 );
gnt1->m_connectDirectly = false;
connect1 = gnt1;
if( gn1->m_parent->IsConductive() )
{
if( auto gc = AddConnection( gn1, gnt1 ) )
gc->m_path.m_show = false;
}
if( auto gc = AddConnection( gn1, gnt1 ) )
gc->m_path.m_show = false;
}
// Handle non-point node2
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
{
auto gnt2 = AddNode( GRAPH_NODE::POINT, gn2->m_parent, pc.a2 );
gnt2->m_connectDirectly = false;
connect2 = gnt2;
if( gn2->m_parent->IsConductive() )
{
if( auto gc = AddConnection( gn2, gnt2 ) )
gc->m_path.m_show = false;
}
}
AddConnection( connect1, connect2, pc );
}
// Handle non-point node2
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
{
auto gnt2 = AddNode( GRAPH_NODE::POINT, gn2->m_parent, pc.a2 );
gnt2->m_connectDirectly = false;
connect2 = gnt2;
if( gn2->m_parent->IsConductive() )
{
if( auto gc = AddConnection( gn2, gnt2 ) )
gc->m_path.m_show = false;
}
}
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

@ -527,10 +527,9 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
void DRC_ENGINE::compileRules()
{
if( m_logReporter )
{
m_logReporter->Report( ( wxString::Format( wxT( "Compiling Rules (%d rules): " ),
(int) m_rules.size() ) ) );
}
m_logReporter->Report( wxT( "Compiling Rules" ) );
REPORTER error_semaphore;
for( std::shared_ptr<DRC_RULE>& rule : m_rules )
{
@ -539,9 +538,12 @@ void DRC_ENGINE::compileRules()
if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
{
condition = rule->m_Condition;
condition->Compile( nullptr );
condition->Compile( &error_semaphore );
}
if( error_semaphore.HasMessageOfSeverity( RPT_SEVERITY_ERROR ) )
THROW_PARSE_ERROR( wxT( "Parse error" ), rule->m_Name, rule->m_Condition->GetExpression(), 0, 0 );
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
{
if( !m_constraintMap.count( constraint.m_Type ) )
@ -594,6 +596,8 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
}
catch( PARSE_ERROR& original_parse_error )
{
m_rules.clear();
try // try again with just our implicit rules
{
loadImplicitRules();

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,115 +594,112 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
auto testTrack = [&]( const int start_idx, const int end_idx )
auto testTrack = [&]( const int trackIdx )
{
for( int trackIdx = start_idx; trackIdx < end_idx; ++trackIdx )
PCB_TRACK* track = m_board->Tracks()[trackIdx];
for( PCB_LAYER_ID layer : LSET( track->GetLayerSet() & boardCopperLayers ) )
{
PCB_TRACK* track = m_board->Tracks()[trackIdx];
std::shared_ptr<SHAPE> trackShape = track->GetEffectiveShape( layer );
for( PCB_LAYER_ID layer : LSET( track->GetLayerSet() & boardCopperLayers ) )
m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
// Filter:
[&]( BOARD_ITEM* other ) -> bool
{
BOARD_CONNECTED_ITEM* otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
return false;
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both directions
// (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end()
&& ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
// Visitor:
[&]( BOARD_ITEM* other ) -> bool
{
if( m_drcEngine->IsCancelled() )
return false;
if( other->Type() == PCB_PAD_T && static_cast<PAD*>( other )->IsFreePad() )
{
if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) )
{
std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
auto it = freePadsUsageMap.find( other );
if( it == freePadsUsageMap.end() )
{
freePadsUsageMap[ other ] = track->GetNetCode();
return true; // Continue colliding tests
}
else if( it->second == track->GetNetCode() )
{
return true; // Continue colliding tests
}
}
}
// If we get an error, mark the pair as having a clearance error already
if( !testSingleLayerItemAgainstItem( track, trackShape.get(), layer, other ) )
{
if( !m_drcEngine->GetReportAllTrackErrors() )
{
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both directions
// (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end() )
it->second.has_error = true;
return false; // We're done with this track
}
}
return !m_drcEngine->IsCancelled();
},
m_board->m_DRCMaxClearance );
for( ZONE* zone : m_board->m_DRCCopperZones )
{
std::shared_ptr<SHAPE> trackShape = track->GetEffectiveShape( layer );
testItemAgainstZone( track, zone, layer );
m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
// Filter:
[&]( BOARD_ITEM* other ) -> bool
{
BOARD_CONNECTED_ITEM* otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
return false;
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both directions
// (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end()
&& ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
// Visitor:
[&]( BOARD_ITEM* other ) -> bool
{
if( m_drcEngine->IsCancelled() )
return false;
if( other->Type() == PCB_PAD_T && static_cast<PAD*>( other )->IsFreePad() )
{
if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) )
{
std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
auto it = freePadsUsageMap.find( other );
if( it == freePadsUsageMap.end() )
{
freePadsUsageMap[ other ] = track->GetNetCode();
return true; // Continue colliding tests
}
else if( it->second == track->GetNetCode() )
{
return true; // Continue colliding tests
}
}
}
// If we get an error, mark the pair as having a clearance error already
if( !testSingleLayerItemAgainstItem( track, trackShape.get(), layer, other ) )
{
if( !m_drcEngine->GetReportAllTrackErrors() )
{
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both directions
// (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end() )
it->second.has_error = true;
return false; // We're done with this track
}
}
return !m_drcEngine->IsCancelled();
},
m_board->m_DRCMaxClearance );
for( ZONE* zone : m_board->m_DRCCopperZones )
{
testItemAgainstZone( track, zone, layer );
if( m_drcEngine->IsCancelled() )
break;
}
if( m_drcEngine->IsCancelled() )
break;
}
done.fetch_add( 1 );
}
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,82 +965,79 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
const auto fp_check = [&]( size_t aFromIdx, size_t aToIdx )
const auto fp_check = [&]( size_t ii )
{
for( size_t ii = aFromIdx; ii < aToIdx; ++ii )
FOOTPRINT* footprint = m_board->Footprints()[ ii ];
for( PAD* pad : footprint->Pads() )
{
FOOTPRINT* footprint = m_board->Footprints()[ ii ];
for( PAD* pad : footprint->Pads() )
for( PCB_LAYER_ID layer : LSET( pad->GetLayerSet() & boardCopperLayers ) )
{
for( PCB_LAYER_ID layer : LSET( pad->GetLayerSet() & boardCopperLayers ) )
{
if( m_drcEngine->IsCancelled() )
return;
if( m_drcEngine->IsCancelled() )
return;
std::shared_ptr<SHAPE> padShape = pad->GetEffectiveShape( layer );
std::shared_ptr<SHAPE> padShape = pad->GetEffectiveShape( layer );
m_board->m_CopperItemRTreeCache->QueryColliding( pad, layer, layer,
// Filter:
[&]( BOARD_ITEM* other ) -> bool
m_board->m_CopperItemRTreeCache->QueryColliding( pad, layer, layer,
// Filter:
[&]( BOARD_ITEM* other ) -> bool
{
BOARD_ITEM* a = pad;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both
// directions (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end()
&& ( it->second.layers.test( layer ) || it->second.has_error ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
// Visitor
[&]( BOARD_ITEM* other ) -> bool
{
if( !testPadAgainstItem( pad, padShape.get(), layer, other ) )
{
BOARD_ITEM* a = pad;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both
// directions (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end()
&& ( it->second.layers.test( layer ) || it->second.has_error ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
// Visitor
[&]( BOARD_ITEM* other ) -> bool
{
if( !testPadAgainstItem( pad, padShape.get(), layer, other ) )
{
BOARD_ITEM* a = pad;
BOARD_ITEM* b = other;
if( it != checkedPairs.end() )
it->second.has_error = true;
}
std::lock_guard<std::mutex> lock( checkedPairsMutex );
auto it = checkedPairs.find( { a, b } );
return !m_drcEngine->IsCancelled();
},
m_board->m_DRCMaxClearance );
if( it != checkedPairs.end() )
it->second.has_error = true;
}
for( ZONE* zone : m_board->m_DRCCopperZones )
{
testItemAgainstZone( pad, zone, layer );
return !m_drcEngine->IsCancelled();
},
m_board->m_DRCMaxClearance );
for( ZONE* zone : m_board->m_DRCCopperZones )
{
testItemAgainstZone( pad, zone, layer );
if( m_drcEngine->IsCancelled() )
return;
}
if( m_drcEngine->IsCancelled() )
return;
}
}
done.fetch_add( 1 );
}
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,50 +737,47 @@ 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
auto returns = tp.submit_loop( 0, test_items.size(), [&]( size_t i ) -> bool
{
BOARD_ITEM* item = test_items[ i ];
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SOLDERMASK_BRIDGE ) )
return false;
BOX2I itemBBox = item->GetBoundingBox();
if( item->IsOnLayer( F_Mask ) && !isNullAperture( item ) )
{
for( size_t i = a; i < b; ++i )
{
BOARD_ITEM* item = test_items[ i ];
// Test for aperture-to-aperture collisions
testItemAgainstItems( item, itemBBox, F_Mask, F_Mask );
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SOLDERMASK_BRIDGE ) )
return false;
// Test for aperture-to-zone collisions
testMaskItemAgainstZones( item, itemBBox, F_Mask, F_Cu );
}
else if( item->IsOnLayer( PADSTACK::ALL_LAYERS ) )
{
// Test for copper-item-to-aperture collisions
testItemAgainstItems( item, itemBBox, F_Cu, F_Mask );
}
BOX2I itemBBox = item->GetBoundingBox();
if( item->IsOnLayer( B_Mask ) && !isNullAperture( item ) )
{
// Test for aperture-to-aperture collisions
testItemAgainstItems( item, itemBBox, B_Mask, B_Mask );
if( item->IsOnLayer( F_Mask ) && !isNullAperture( item ) )
{
// Test for aperture-to-aperture collisions
testItemAgainstItems( item, itemBBox, F_Mask, F_Mask );
// Test for aperture-to-zone collisions
testMaskItemAgainstZones( item, itemBBox, B_Mask, B_Cu );
}
else if( item->IsOnLayer( B_Cu ) )
{
// Test for copper-item-to-aperture collisions
testItemAgainstItems( item, itemBBox, B_Cu, B_Mask );
}
// Test for aperture-to-zone collisions
testMaskItemAgainstZones( item, itemBBox, F_Mask, F_Cu );
}
else if( item->IsOnLayer( PADSTACK::ALL_LAYERS ) )
{
// Test for copper-item-to-aperture collisions
testItemAgainstItems( item, itemBBox, F_Cu, F_Mask );
}
++count;
if( item->IsOnLayer( B_Mask ) && !isNullAperture( item ) )
{
// Test for aperture-to-aperture collisions
testItemAgainstItems( item, itemBBox, B_Mask, B_Mask );
// Test for aperture-to-zone collisions
testMaskItemAgainstZones( item, itemBBox, B_Mask, B_Cu );
}
else if( item->IsOnLayer( B_Cu ) )
{
// Test for copper-item-to-aperture collisions
testItemAgainstItems( item, itemBBox, B_Cu, B_Mask );
}
++count;
}
return true;
} );
return true;
} );
for( size_t i = 0; i < returns.size(); ++i )
{

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;
@ -195,17 +197,10 @@ bool DRC_TEST_PROVIDER_TRACK_ANGLE::Run()
const int progressDelta = 250;
int ii = 0;
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<bool>> returns;
thread_pool& tp = GetKiCadThreadPool();
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;
auto returns = tp.submit_loop( 0, zoneLayers.size(),
[&]( const int ii )
{
if( !m_drcEngine->IsCancelled() )
{
testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
}
} );
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
{
if( !m_drcEngine->IsCancelled() )
{
testZoneLayer( aZone, aLayer );
done.fetch_add( aZone->GetFilledPolysList( aLayer )->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,76 +2026,73 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
{
std::mutex mutex;
auto subtractLoopFn = [&]( const int a, const int b )
auto subtractLoopFn = [&]( const int shapeId )
{
for( int shapeId = a; shapeId < b; shapeId++ )
TopoDS_Shape& shape = vec[shapeId];
Bnd_Box shapeBbox;
BRepBndLib::Add( shape, shapeBbox );
TopTools_ListOfShape holelist;
{
TopoDS_Shape& shape = vec[shapeId];
std::unique_lock lock( mutex );
Bnd_Box shapeBbox;
BRepBndLib::Add( shape, shapeBbox );
const TColStd_ListOfInteger& indices = aBSBHoles.Compare( shapeBbox );
TopTools_ListOfShape holelist;
{
std::unique_lock lock( mutex );
const TColStd_ListOfInteger& indices = aBSBHoles.Compare( shapeBbox );
for( const Standard_Integer& index : indices )
holelist.Append( aHolesList[index] );
}
if( holelist.IsEmpty() )
continue;
TopTools_ListOfShape cutArgs;
cutArgs.Append( shape );
BRepAlgoAPI_Cut cut;
cut.SetRunParallel( true );
cut.SetToFillHistory( false );
cut.SetArguments( cutArgs );
cut.SetTools( holelist );
cut.Build();
if( cut.HasErrors() || cut.HasWarnings() )
{
m_reporter->Report( wxString::Format( _( "** Got problems while cutting "
"%s net '%s' **" ),
aWhat,
UnescapeString( netname ) ),
RPT_SEVERITY_ERROR );
shapeBbox.Dump();
if( cut.HasErrors() )
{
wxString msg = _( "Errors:\n" );
wxStringOutputStream os_stream( &msg );
wxStdOutputStream out( os_stream );
cut.DumpErrors( out );
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
}
if( cut.HasWarnings() )
{
wxString msg = _( "Warnings:\n" );
wxStringOutputStream os_stream( &msg );
wxStdOutputStream out( os_stream );
cut.DumpWarnings( out );
m_reporter->Report( msg, RPT_SEVERITY_WARNING );
}
}
shape = cut.Shape();
for( const Standard_Integer& index : indices )
holelist.Append( aHolesList[index] );
}
if( holelist.IsEmpty() )
return; // nothing to cut for this shape
TopTools_ListOfShape cutArgs;
cutArgs.Append( shape );
BRepAlgoAPI_Cut cut;
cut.SetRunParallel( true );
cut.SetToFillHistory( false );
cut.SetArguments( cutArgs );
cut.SetTools( holelist );
cut.Build();
if( cut.HasErrors() || cut.HasWarnings() )
{
m_reporter->Report( wxString::Format( _( "** Got problems while cutting "
"%s net '%s' **" ),
aWhat,
UnescapeString( netname ) ),
RPT_SEVERITY_ERROR );
shapeBbox.Dump();
if( cut.HasErrors() )
{
wxString msg = _( "Errors:\n" );
wxStringOutputStream os_stream( &msg );
wxStdOutputStream out( os_stream );
cut.DumpErrors( out );
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
}
if( cut.HasWarnings() )
{
wxString msg = _( "Warnings:\n" );
wxStringOutputStream os_stream( &msg );
wxStdOutputStream out( os_stream );
cut.DumpWarnings( out );
m_reporter->Report( msg, RPT_SEVERITY_WARNING );
}
}
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

@ -109,6 +109,7 @@
#include <widgets/pcb_net_inspector_panel.h>
#include <widgets/wx_aui_utils.h>
#include <kiplatform/app.h>
#include <kiplatform/ui.h>
#include <core/profile.h>
#include <math/box2_minmax.h>
#include <view/wx_view_controls.h>
@ -1466,7 +1467,7 @@ void PCB_EDIT_FRAME::ActivateGalCanvas()
}
void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage )
void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, wxWindow* aParent )
{
static std::mutex dialogMutex; // Local static mutex
@ -1486,7 +1487,7 @@ void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage )
// Make sure everything's up-to-date
GetBoard()->BuildListOfNets();
DIALOG_BOARD_SETUP dlg( this );
DIALOG_BOARD_SETUP dlg( this, aParent );
if( !aInitialPage.IsEmpty() )
dlg.SetInitialPage( aInitialPage, wxEmptyString );

View File

@ -301,7 +301,7 @@ public:
///< @copydoc EDA_DRAW_FRAME::UseGalCanvas()
void ActivateGalCanvas() override;
void ShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString );
void ShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString, wxWindow* aParent = nullptr );
void PrepareLayerIndicator( bool aForceRebuild = false );

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