Compare commits

...

41 Commits

Author SHA1 Message Date
Jan Wichmann
36e38cd60a ADDED: Sort the templates alphabetically, leaving the default template at the top. 2025-09-13 03:15:44 -07:00
Seth Hillbrand
5fdfff2b9c Prevent lines from drawing on netclass layer
Only wires and busses get netclasses

Fixes https://gitlab.com/kicad/code/kicad/issues/21731
2025-09-13 02:51:00 -07:00
Seth Hillbrand
733a379ca3 Unify sheet name validators and apply to properties
Properties panel and properties dialog now share a validator with shared
strings

Fixes https://gitlab.com/kicad/code/kicad/issues/21689
2025-09-13 02:42:03 -07:00
Seth Hillbrand
497afffd48 Properly order netlist pages
We cannot reorder these without updating the defines.  So, keep the GUI
in line with the definitions

Fixes https://gitlab.com/kicad/code/kicad/issues/21730
2025-09-12 23:34:29 -07:00
Seth Hillbrand
89be756d1a Ensure that we are checking case differences
When comparing symbols, look for case differences in values since
netlists are indeed case sensitive
2025-09-12 23:27:06 -07:00
Seth Hillbrand
a6decf15b5 Don't assert on stderr messages
These can be things like missing library tables, directory creation, etc
2025-09-12 23:26:20 -07:00
Seth Hillbrand
4229b3cc76 Update cli golden files with new output format 2025-09-12 23:25:22 -07:00
Seth Hillbrand
32ee4ebdfa Fix QA.
QA was built with pin names outside but this was a bug.  For now, we
only want to test outside pin names.  The test can be expanded in the
future
2025-09-12 12:53:01 -07:00
Jeff Young
2c102a62e0 Auto-convert numeric values in fields when referencing them in expressions.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21723
2025-09-12 20:35:17 +01:00
jean-pierre charras
aa4de22ef4 EDA_3D_CANVAS: fix crash when used in dialogs and clicking in the 3D shape
It was due to the fact a message (using ExpressMail) was sent to the board
and schematic editor, but it is possible only if the manager of this canvas
is a EDA_3D_VIEWER_FRAME, because only this kind of frame has ExpressMail stuff

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21728
2025-09-12 20:00:10 +02:00
jean-pierre charras
79a3b7ac5f Add missing header to compil on msys2 2025-09-12 19:44:19 +02:00
Seth Hillbrand
56ad08cdd8 Prevent backannotation from changing variables
Updating to PCB always resolves text variables from the schematic.  This
means that back annotation will always start from resolved variables if
they exist in the schematic.  So to avoid this, we prevent overwriting
any text variables that exist in the schematic.

This does prevent the user from updating a text variable in a pcbnew
field and backannotating this variable change into the schematic where
the schematic had a text variable already.  Text variables are forward
annotation only until we add an additional property to each field to
include the unresolved text

Fixes https://gitlab.com/kicad/code/kicad/issues/21724
2025-09-12 07:24:39 -07:00
Seth Hillbrand
accbee3c6e Move git stuff to kicommon to fix build
And do other cool stuff
2025-09-12 07:17:42 -07:00
Seth Hillbrand
29025882fc Fix typo in pad table 2025-09-12 06:55:31 -07:00
Seth Hillbrand
c64f99c57a ADDED: VCSHASH and VCSSHORTHASH
Right now, git hashes only resolved by the variables ${VCSHASH} or
${VCSSHORTHASH}
2025-09-12 06:00:27 -07:00
Seth Hillbrand
5952c2fb9a ADDED: Pad edit table
Allows editing common pad properties in table format

Fixes https://gitlab.com/kicad/code/kicad/issues/10789
2025-09-12 05:39:25 -07:00
Jeff Young
0b6de964fd Fix initialization order. 2025-09-12 13:32:17 +01:00
Jeff Young
976278e5a6 ADDED: extra info for shape, pin and field differences.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21647
2025-09-12 13:32:17 +01:00
Roberto Fernandez Bautista
8d8bd7253f Windows CI: custom vcpkg triplet to ensure shareable binary cache 2025-09-12 11:18:50 +00:00
Seth Hillbrand
5dc6d43f43 Add via tenting/plugging representation to 3d-viewer
Fixes https://gitlab.com/kicad/code/kicad/issues/21704
2025-09-12 01:23:41 -07:00
jean-pierre charras
98dd5a68eb Fix a compil issue on gcc/msys2
gcc does not like implicit conversion from wxString to char*
2025-09-12 08:20:49 +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
453 changed files with 37463 additions and 10473 deletions

View File

@ -36,6 +36,8 @@ win64_build:
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON `
-DKICAD_USE_3DCONNEXION=ON `
-DVCPKG_BUILD_TYPE=debug `
-DVCPKG_INSTALL_OPTIONS="--x-abi-tools-use-exact-versions" `
-DVCPKG_OVERLAY_TRIPLETS="$Env:CI_PROJECT_DIR/tools/custom_vcpkg_triplets" `
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../

View File

@ -1087,14 +1087,16 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
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() );
// We send a message (by ExpressMail) to the board and schematic editor, but only
// if the manager of this canvas is a EDA_3D_VIEWER_FRAME, because only this
// kind of frame has ExpressMail stuff
EDA_3D_VIEWER_FRAME* frame = dynamic_cast<EDA_3D_VIEWER_FRAME*>( GetParent() );
if( frame )
{
std::string command = fmt::format( "$SELECT: 0,F{}",
EscapeString( footprint->GetReference(), CTX_IPC ).ToStdString() );
frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_SELECTION, command, frame );
frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SELECTION, command, frame );
}

View File

@ -26,6 +26,7 @@
#include "render_3d_opengl.h"
#include <board.h>
#include <footprint.h>
#include <pcb_track.h>
#include "../../3d_math.h"
#include "convert_basic_shapes_to_polygon.h"
#include <lset.h>
@ -726,6 +727,54 @@ void RENDER_3D_OPENGL::generateCylinder( const SFVEC2F& aCenter, float aInnerRad
}
void RENDER_3D_OPENGL::generateDisk( const SFVEC2F& aCenter, float aRadius, float aZ,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop )
{
const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
for( unsigned int i = 0; i < aNr_sides_per_circle; ++i )
{
float a0 = delta * i;
float a1 = delta * ( i + 1 );
const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
aCenter.y + sinf( a0 ) * aRadius, aZ );
const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
aCenter.y + sinf( a1 ) * aRadius, aZ );
const SFVEC3F c( aCenter.x, aCenter.y, aZ );
if( aTop )
aDstLayer->m_layer_top_triangles->AddTriangle( p1, p0, c );
else
aDstLayer->m_layer_bot_triangles->AddTriangle( p0, p1, c );
}
}
void RENDER_3D_OPENGL::generateDimple( const SFVEC2F& aCenter, float aRadius, float aZ,
float aDepth, unsigned int aNr_sides_per_circle,
TRIANGLE_DISPLAY_LIST* aDstLayer, bool aTop )
{
const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
for( unsigned int i = 0; i < aNr_sides_per_circle; ++i )
{
float a0 = delta * i;
float a1 = delta * ( i + 1 );
const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
aCenter.y + sinf( a0 ) * aRadius, aZ );
const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
aCenter.y + sinf( a1 ) * aRadius, aZ );
if( aTop )
aDstLayer->m_layer_top_triangles->AddTriangle( p0, p1, c );
else
aDstLayer->m_layer_bot_triangles->AddTriangle( p1, p0, c );
}
}
void RENDER_3D_OPENGL::generateViasAndPads()
{
if( !m_boardAdapter.GetBoard() )
@ -882,6 +931,63 @@ void RENDER_3D_OPENGL::generateViasAndPads()
delete layerTriangles;
}
}
TRIANGLE_DISPLAY_LIST* frontCover = new TRIANGLE_DISPLAY_LIST( m_boardAdapter.GetViaCount() );
TRIANGLE_DISPLAY_LIST* backCover = new TRIANGLE_DISPLAY_LIST( m_boardAdapter.GetViaCount() );
for( const PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
{
if( track->Type() != PCB_VIA_T )
continue;
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3dUnits();
const float hole_radius = holediameter / 2.0f + 2.0 * platingThickness3d;
const SFVEC2F center( via->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
-via->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
unsigned int seg = m_boardAdapter.GetCircleSegmentCount( via->GetDrillValue() );
PCB_LAYER_ID top_layer, bottom_layer;
via->LayerPair( &top_layer, &bottom_layer );
float ztop, zbot, dummy;
getLayerZPos( top_layer, ztop, dummy );
getLayerZPos( bottom_layer, dummy, zbot );
bool frontCovering = via->GetFrontCoveringMode() == COVERING_MODE::COVERED || via->IsTented( F_Mask );
bool backCovering = via->GetBackCoveringMode() == COVERING_MODE::COVERED || via->IsTented( B_Mask );
bool frontPlugged = via->GetFrontPluggingMode() == PLUGGING_MODE::PLUGGED;
bool backPlugged = via->GetBackPluggingMode() == PLUGGING_MODE::PLUGGED;
bool filled = via->GetFillingMode() == FILLING_MODE::FILLED
|| via->GetCappingMode() == CAPPING_MODE::CAPPED;
const float depth = hole_radius * 0.3f;
if( frontCovering )
{
if( filled || !frontPlugged )
generateDisk( center, hole_radius, ztop, seg, frontCover, true );
else
generateDimple( center, hole_radius, ztop, depth, seg, frontCover, true );
}
if( backCovering )
{
if( filled || !backPlugged )
generateDisk( center, hole_radius, zbot, seg, backCover, false );
else
generateDimple( center, hole_radius, zbot, depth, seg, backCover, false );
}
}
if( frontCover->m_layer_top_triangles->GetVertexSize() > 0 )
m_viaFrontCover = new OPENGL_RENDER_LIST( *frontCover, 0, 0.0f, 0.0f );
if( backCover->m_layer_bot_triangles->GetVertexSize() > 0 )
m_viaBackCover = new OPENGL_RENDER_LIST( *backCover, 0, 0.0f, 0.0f );
delete frontCover;
delete backCover;
}

View File

@ -72,6 +72,8 @@ RENDER_3D_OPENGL::RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdap
m_outerViaThroughHoles = nullptr;
m_microviaHoles = nullptr;
m_padHoles = nullptr;
m_viaFrontCover = nullptr;
m_viaBackCover = nullptr;
m_circleTexture = 0;
m_grid = 0;
@ -947,6 +949,8 @@ void RENDER_3D_OPENGL::freeAllLists()
DELETE_AND_FREE( m_microviaHoles )
DELETE_AND_FREE( m_padHoles )
DELETE_AND_FREE( m_viaFrontCover )
DELETE_AND_FREE( m_viaBackCover )
}
@ -968,6 +972,17 @@ void RENDER_3D_OPENGL::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos
setLayerMaterial( aLayerID );
m_board->SetItIsTransparent( true );
m_board->DrawCulled( aShowThickness, solder_mask, via_holes );
if( aLayerID == F_Mask && m_viaFrontCover )
{
m_viaFrontCover->ApplyScalePosition( aZPos, 4 * m_boardAdapter.GetNonCopperLayerThickness() );
m_viaFrontCover->DrawTop();
}
else if( aLayerID == B_Mask && m_viaBackCover )
{
m_viaBackCover->ApplyScalePosition( aZPos, 4 * m_boardAdapter.GetNonCopperLayerThickness() );
m_viaBackCover->DrawBot();
}
}
}

View File

@ -123,6 +123,14 @@ private:
float aZtop, float aZbot, unsigned int aNr_sides_per_circle,
TRIANGLE_DISPLAY_LIST* aDstLayer );
void generateDisk( const SFVEC2F& aCenter, float aRadius, float aZ,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop );
void generateDimple( const SFVEC2F& aCenter, float aRadius, float aZ, float aDepth,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop );
void generateViasAndPads();
/**
@ -236,6 +244,8 @@ private:
OPENGL_RENDER_LIST* m_microviaHoles;
OPENGL_RENDER_LIST* m_padHoles;
OPENGL_RENDER_LIST* m_viaFrontCover;
OPENGL_RENDER_LIST* m_viaBackCover;
// Caches
std::map<wxString, MODEL_3D*> m_3dModelMap;

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();

View File

@ -6,7 +6,12 @@
},
{
"environment": "vcpkg",
"VcPkgDir": "D:/vcpkg/"
"VcPkgDir": "D:/vcpkg/",
"VCPKG_BINARY_SOURCES": "nuget,kicad-gitlab,read"
},
{
"environment": "swig",
"SwigExePath": "D:/swigwin-4.1.1/swig.exe"
}
],
"configurations": [
@ -14,7 +19,7 @@
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
"buildRoot": "${env.BuildDir}\\${name}",
"installRoot": "${env.InstallDir}\\${name}",
"cmakeCommandArgs": "",
@ -30,6 +35,21 @@
"name": "KICAD_WIN32_DPI_AWARE",
"value": "ON",
"type": "BOOL"
},
{
"name": "SWIG_EXECUTABLE",
"value": "${env.SwigExePath}",
"type": "STRING"
},
{
"name": "VCPKG_OVERLAY_TRIPLETS",
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
"type": "STRING"
},
{
"name": "VCPKG_INSTALL_OPTIONS",
"value": "--x-abi-tools-use-exact-versions",
"type": "STRING"
}
],
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"
@ -38,7 +58,7 @@
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
"buildRoot": "${env.BuildDir}\\${name}",
"installRoot": "${env.InstallDir}\\${name}",
"cmakeCommandArgs": "",
@ -54,6 +74,21 @@
"name": "KICAD_WIN32_DPI_AWARE",
"value": "ON",
"type": "BOOL"
},
{
"name": "SWIG_EXECUTABLE",
"value": "${env.SwigExePath}",
"type": "STRING"
},
{
"name": "VCPKG_OVERLAY_TRIPLETS",
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
"type": "STRING"
},
{
"name": "VCPKG_INSTALL_OPTIONS",
"value": "--x-abi-tools-use-exact-versions",
"type": "STRING"
}
],
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"

View File

@ -67,6 +67,30 @@ set( KICOMMON_SRCS
# Gal
gal/color4d.cpp
gal/opengl/gl_context_mgr.cpp
# Git
git/git_add_to_index_handler.cpp
git/git_branch_handler.cpp
git/git_clone_handler.cpp
git/git_commit_handler.cpp
git/git_config_handler.cpp
git/git_compare_handler.cpp
git/git_init_handler.cpp
git/project_git_utils.cpp
git/git_pull_handler.cpp
git/git_push_handler.cpp
git/git_remove_from_index_handler.cpp
git/git_remove_vcs_handler.cpp
git/git_resolve_conflict_handler.cpp
git/git_revert_handler.cpp
git/git_status_handler.cpp
git/git_switch_branch_handler.cpp
git/git_sync_handler.cpp
git/kicad_git_common.cpp
git/kicad_git_errors.cpp
git/git_backend.cpp
git/libgit_backend.cpp
# Jobs
jobs/job.cpp
jobs/job_dispatcher.cpp
@ -616,26 +640,6 @@ set( COMMON_IMPORT_GFX_SRCS
import_gfx/svg_import_plugin.cpp
)
set( COMMON_GIT_SRCS
git/git_add_to_index_handler.cpp
git/git_branch_handler.cpp
git/git_clone_handler.cpp
git/git_commit_handler.cpp
git/git_config_handler.cpp
git/git_init_handler.cpp
git/git_pull_handler.cpp
git/git_push_handler.cpp
git/git_remove_from_index_handler.cpp
git/git_resolve_conflict_handler.cpp
git/git_revert_handler.cpp
git/git_status_handler.cpp
git/git_sync_handler.cpp
git/project_git_utils.cpp
git/kicad_git_common.cpp
git/kicad_git_errors.cpp
git/git_backend.cpp
git/libgit_backend.cpp
)
set( COMMON_SRCS
${LIB_KICAD_SRCS}
@ -648,7 +652,6 @@ set( COMMON_SRCS
${COMMON_IO_SRCS}
${FONT_SRCS}
${COMMON_IMPORT_GFX_SRCS}
${COMMON_GIT_SRCS}
${COMMON_TRANSLINE_CALCULATION_SRCS}
base_screen.cpp
bin_mod.cpp

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

@ -708,6 +708,104 @@ double EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale,
}
bool EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale, const wxString& aTextValue,
double& aDoubleValue )
{
double dtmp = 0;
// Acquire the 'right' decimal point separator
const struct lconv* lc = localeconv();
wxChar decimal_point = lc->decimal_point[0];
wxString buf( aTextValue.Strip( wxString::both ) );
// Convert any entered decimal point separators to the 'right' one
buf.Replace( wxT( "." ), wxString( decimal_point, 1 ) );
buf.Replace( wxT( "," ), wxString( decimal_point, 1 ) );
// Find the end of the numeric part
unsigned brk_point = 0;
while( brk_point < buf.Len() )
{
wxChar ch = buf[brk_point];
if( !( (ch >= '0' && ch <= '9') || (ch == decimal_point) || (ch == '-') || (ch == '+') ) )
break;
++brk_point;
}
if( brk_point == 0 )
return false;
// Extract the numeric part
buf.Left( brk_point ).ToDouble( &dtmp );
// Check the unit designator
wxString unit( buf.Mid( brk_point ).Strip( wxString::both ).Lower() );
EDA_UNITS units;
//check for um, μm (µ is MICRO SIGN) and µm (µ is GREEK SMALL LETTER MU) for micrometre
if( unit == wxT( "um" ) || unit == wxT( "\u00B5m" ) || unit == wxT( "\u03BCm" ) )
{
units = EDA_UNITS::UM;
}
else if( unit == wxT( "mm" ) )
{
units = EDA_UNITS::MM;
}
else if( unit == wxT( "cm" ) )
{
units = EDA_UNITS::CM;
}
else if( unit == wxT( "mil" ) || unit == wxT( "mils" ) || unit == wxT( "thou" ) )
{
units = EDA_UNITS::MILS;
}
else if( unit == wxT( "in" ) || unit == wxT( "\"" ) )
{
units = EDA_UNITS::INCH;
}
else if( unit == wxT( "oz" ) ) // 1 oz = 1.37 mils
{
units = EDA_UNITS::MILS;
dtmp *= 1.37;
}
else if( unit == wxT( "ra" ) ) // Radians
{
dtmp *= 180.0f / M_PI;
}
else if( unit == wxT( "fs" ) )
{
units = EDA_UNITS::FS;
}
else if( unit == wxT( "ps" ) )
{
units = EDA_UNITS::PS;
}
else if( unit == wxT( "ps/in" ) )
{
units = EDA_UNITS::PS_PER_INCH;
}
else if( unit == wxT( "ps/cm" ) )
{
units = EDA_UNITS::PS_PER_CM;
}
else if( unit == wxT( "ps/mm" ) )
{
units = EDA_UNITS::PS_PER_MM;
}
else
{
return false;
}
aDoubleValue = FromUserUnit( aIuScale, units, dtmp );
return true;
}
long long int EDA_UNIT_UTILS::UI::ValueFromString( const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
const wxString& aTextValue, EDA_DATA_TYPE aType )
{

View File

@ -25,12 +25,13 @@
#define GIT_ADD_TO_INDEX_HANDLER_H_
#include <git/kicad_git_common.h>
#include <import_export.h>
#include <vector>
#include <wx/string.h>
class LIBGIT_BACKEND;
class GIT_ADD_TO_INDEX_HANDLER : public KIGIT_COMMON
class APIEXPORT GIT_ADD_TO_INDEX_HANDLER : public KIGIT_COMMON
{
public:
GIT_ADD_TO_INDEX_HANDLER( git_repository* aRepository );

View File

@ -25,6 +25,7 @@
#define GIT_BACKEND_H_
#include <map>
#include <import_export.h>
#include <set>
#include <vector>
#include <wx/string.h>
@ -56,7 +57,7 @@ enum class CommitResult
Cancelled
};
class GIT_BACKEND
class APIEXPORT GIT_BACKEND
{
public:
virtual ~GIT_BACKEND() = default;
@ -121,7 +122,7 @@ public:
virtual void PerformRemoveFromIndex( GIT_REMOVE_FROM_INDEX_HANDLER* aHandler ) = 0;
};
GIT_BACKEND* GetGitBackend();
void SetGitBackend( GIT_BACKEND* aBackend );
APIEXPORT GIT_BACKEND* GetGitBackend();
APIEXPORT void SetGitBackend( GIT_BACKEND* aBackend );
#endif

View File

@ -25,6 +25,7 @@
#define GIT_BRANCH_HANDLER_H
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <wx/string.h>
#include <vector>
@ -36,7 +37,7 @@ enum class BranchResult
Error
};
class GIT_BRANCH_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_BRANCH_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_BRANCH_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -25,10 +25,11 @@
#define GIT_CLONE_HANDLER_H_
#include "kicad_git_common.h"
#include <import_export.h>
#include "git_repo_mixin.h"
#include "git_progress.h"
class GIT_CLONE_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_CLONE_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_CLONE_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -27,6 +27,7 @@
// Define a class to handle git commit operations
#include <git/kicad_git_common.h>
#include <import_export.h>
#include "git_backend.h"
#include <string>
@ -35,7 +36,7 @@
class LIBGIT_BACKEND;
class GIT_COMMIT_HANDLER : public KIGIT_COMMON
class APIEXPORT GIT_COMMIT_HANDLER : public KIGIT_COMMON
{
public:
GIT_COMMIT_HANDLER( git_repository* aRepo );

View File

@ -25,6 +25,7 @@
#define GIT_CONFIG_HANDLER_H
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <wx/string.h>
struct GitUserConfig
@ -35,7 +36,7 @@ struct GitUserConfig
bool hasEmail = false;
};
class GIT_CONFIG_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_CONFIG_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_CONFIG_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -25,6 +25,7 @@
#define GIT_INIT_HANDLER_H
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <wx/string.h>
enum class InitResult
@ -43,7 +44,7 @@ struct RemoteConfig
KIGIT_COMMON::GIT_CONN_TYPE connType;
};
class GIT_INIT_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_INIT_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_INIT_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -25,10 +25,11 @@
#define GIT_PROGRESS_H_
#include <widgets/wx_progress_reporters.h>
#include <import_export.h>
#include <memory>
class GIT_PROGRESS
class APIEXPORT GIT_PROGRESS
{
public:
GIT_PROGRESS() :

View File

@ -25,6 +25,7 @@
#define _GIT_PULL_HANDLER_H_
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <vector>
#include <string>
@ -51,7 +52,7 @@ enum class PullResult : int
class LIBGIT_BACKEND;
class GIT_PULL_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_PULL_HANDLER : public KIGIT_REPO_MIXIN
{
public:
friend class LIBGIT_BACKEND;

View File

@ -26,6 +26,7 @@
#include <git/git_progress.h>
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <git/kicad_git_errors.h>
#include <wx/string.h>
@ -37,7 +38,7 @@ enum class PushResult
Error
};
class GIT_PUSH_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_PUSH_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_PUSH_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -25,12 +25,13 @@
#define GIT_REMOVE_FROM_INDEX_HANDLER_H_
#include <git/kicad_git_common.h>
#include <import_export.h>
#include <vector>
#include <wx/string.h>
class LIBGIT_BACKEND;
class GIT_REMOVE_FROM_INDEX_HANDLER : public KIGIT_COMMON
class APIEXPORT GIT_REMOVE_FROM_INDEX_HANDLER : public KIGIT_COMMON
{
public:
GIT_REMOVE_FROM_INDEX_HANDLER( git_repository* aRepository );

View File

@ -17,8 +17,9 @@
#include "kicad_git_common.h"
#include "kicad_git_errors.h"
#include "git_progress.h"
#include <import_export.h>
class KIGIT_REPO_MIXIN: public KIGIT_ERRORS, public GIT_PROGRESS
class APIEXPORT KIGIT_REPO_MIXIN: public KIGIT_ERRORS, public GIT_PROGRESS
{
public:
KIGIT_REPO_MIXIN( KIGIT_COMMON* aCommon ) : m_common( aCommon )

View File

@ -25,10 +25,11 @@
#define GIT_RESOLVE_CONFLICT_HANDLER_H
#include <git2.h>
#include <import_export.h>
class wxString;
class GIT_RESOLVE_CONFLICT_HANDLER
class APIEXPORT GIT_RESOLVE_CONFLICT_HANDLER
{
public:
GIT_RESOLVE_CONFLICT_HANDLER( git_repository* aRepository );

View File

@ -25,6 +25,7 @@
#define GIT_REVERT_HANDLER_H_
#include <git2.h>
#include <import_export.h>
#include <vector>
#include <wx/string.h>
// TEMPORARY HACKFIX INCLUDE FOR STD::VECTOR EXPORT OUT OF KICOMMON ON WINDOWS
@ -32,7 +33,7 @@
class LIBGIT_BACKEND;
class GIT_REVERT_HANDLER
class APIEXPORT GIT_REVERT_HANDLER
{
public:
GIT_REVERT_HANDLER( git_repository* aRepository );

View File

@ -25,6 +25,7 @@
#define GIT_STATUS_HANDLER_H
#include <git/git_repo_mixin.h>
#include <import_export.h>
#include <wx/string.h>
#include <map>
#include <set>
@ -38,7 +39,7 @@ struct FileStatus
unsigned int gitStatus; // Raw git status flags
};
class GIT_STATUS_HANDLER : public KIGIT_REPO_MIXIN
class APIEXPORT GIT_STATUS_HANDLER : public KIGIT_REPO_MIXIN
{
public:
GIT_STATUS_HANDLER( KIGIT_COMMON* aCommon );

View File

@ -25,10 +25,11 @@
#define GIT_SYNC_HANDLER_H_
#include <git2.h>
#include <import_export.h>
class wxString;
class GIT_SYNC_HANDLER
class APIEXPORT GIT_SYNC_HANDLER
{
public:
GIT_SYNC_HANDLER( git_repository* aRepository );

View File

@ -25,11 +25,12 @@
#include <istream>
#include <string>
#include <git2.h>
#include <import_export.h>
#include <richio.h>
class BLOB_BUFFER_STREAM : public std::streambuf
class APIEXPORT BLOB_BUFFER_STREAM : public std::streambuf
{
public:
BLOB_BUFFER_STREAM( git_blob* aBlob )
@ -57,7 +58,7 @@ public:
};
// Build a class that implements LINE_READER for git_blobs
class BLOB_READER : public LINE_READER
class APIEXPORT BLOB_READER : public LINE_READER
{
public:
BLOB_READER( git_blob* aBlob ) : m_blob( aBlob )

View File

@ -25,6 +25,7 @@
#define _GIT_COMMON_H_
#include <git/kicad_git_errors.h>
#include <import_export.h>
#include <git2.h>
#include <atomic>
@ -35,7 +36,7 @@
class LIBGIT_BACKEND;
class KIGIT_COMMON
class APIEXPORT KIGIT_COMMON
{
public:
@ -193,19 +194,19 @@ private:
static const unsigned KIGIT_CREDENTIAL_SSH_AGENT = 1 << sizeof( m_testedTypes - 1 );
};
extern "C" int progress_cb( const char* str, int len, void* data );
extern "C" void clone_progress_cb( const char* str, size_t len, size_t total, void* data );
extern "C" int transfer_progress_cb( const git_transfer_progress* aStats, void* aPayload );
extern "C" int update_cb( const char* aRefname, const git_oid* aFirst, const git_oid* aSecond,
void* aPayload );
extern "C" int push_transfer_progress_cb( unsigned int aCurrent, unsigned int aTotal,
size_t aBytes, void* aPayload );
extern "C" int push_update_reference_cb( const char* aRefname, const char* aStatus,
void* aPayload );
extern "C" APIEXPORT int progress_cb( const char* str, int len, void* data );
extern "C" APIEXPORT void clone_progress_cb( const char* str, size_t len, size_t total, void* data );
extern "C" APIEXPORT int transfer_progress_cb( const git_transfer_progress* aStats, void* aPayload );
extern "C" APIEXPORT int update_cb( const char* aRefname, const git_oid* aFirst, const git_oid* aSecond,
void* aPayload );
extern "C" APIEXPORT int push_transfer_progress_cb( unsigned int aCurrent, unsigned int aTotal,
size_t aBytes, void* aPayload );
extern "C" APIEXPORT int push_update_reference_cb( const char* aRefname, const char* aStatus,
void* aPayload );
extern "C" int fetchhead_foreach_cb( const char*, const char*,
const git_oid* aOID, unsigned int aIsMerge, void* aPayload );
extern "C" int credentials_cb( git_cred** aOut, const char* aUrl, const char* aUsername,
unsigned int aAllowedTypes, void* aPayload );
extern "C" APIEXPORT int fetchhead_foreach_cb( const char*, const char*,
const git_oid* aOID, unsigned int aIsMerge, void* aPayload );
extern "C" APIEXPORT int credentials_cb( git_cred** aOut, const char* aUrl, const char* aUsername,
unsigned int aAllowedTypes, void* aPayload );
#endif // _GIT_COMMON_H_

View File

@ -25,10 +25,11 @@
#define KICAD_GIT_ERRORS_H
#include <vector>
#include <import_export.h>
#include <wx/translation.h>
class KIGIT_ERRORS
class APIEXPORT KIGIT_ERRORS
{
public:

View File

@ -25,11 +25,12 @@
#define LIBGIT_BACKEND_H_
#include "git_backend.h"
#include <import_export.h>
// Forward declarations to avoid exposing libgit2 headers
struct git_annotated_commit;
class LIBGIT_BACKEND : public GIT_BACKEND
class APIEXPORT LIBGIT_BACKEND : public GIT_BACKEND
{
public:
void Init() override;

View File

@ -24,6 +24,9 @@
#include "project_git_utils.h"
#include "git_backend.h"
#include <wx/string.h>
#include <string_utils.h>
namespace KIGIT
{
@ -43,4 +46,34 @@ bool PROJECT_GIT_UTILS::RemoveVCS( git_repository*& aRepo, const wxString& aProj
return GetGitBackend()->RemoveVCS( aRepo, aProjectPath, aRemoveGitDir, aErrors );
}
wxString PROJECT_GIT_UTILS::GetCurrentHash( const wxString& aProjectFile, bool aShort )
{
wxString result = wxT( "no hash" );
git_repository* repo = PROJECT_GIT_UTILS::GetRepositoryForFile( TO_UTF8( aProjectFile ) );
if( repo )
{
git_reference* head = nullptr;
if( git_repository_head( &head, repo ) == 0 )
{
const git_oid* oid = git_reference_target( head );
if( oid )
{
char buf[41];
size_t len = aShort ? 8 : 41;
git_oid_tostr( buf, len, oid );
result = wxString::FromUTF8( buf );
}
git_reference_free( head );
}
git_repository_free( repo );
}
return result;
}
} // namespace KIGIT

View File

@ -26,12 +26,13 @@
#include <git2.h>
#include <wx/string.h>
#include <import_export.h>
namespace KIGIT
{
/** Utility class with helper functions for project level git operations. */
class PROJECT_GIT_UTILS
class APIEXPORT PROJECT_GIT_UTILS
{
public:
/**
@ -51,6 +52,16 @@ public:
*/
static int CreateBranch( git_repository* aRepo, const wxString& aBranchName );
/**
* Return the current HEAD commit hash for the repository containing aProjectFile.
*
* @param aProjectFile Absolute path to any file within the repository (typically the
* project file path).
* @param aShort If true, return the short (8 char) hash, otherwise full hash.
* @return wxString containing the hash or "no hash" if unavailable.
*/
static wxString GetCurrentHash( const wxString& aProjectFile, bool aShort );
/**
* Remove version control from a directory by freeing the repository and
* optionally removing the .git directory.

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

@ -36,6 +36,8 @@
#include <kiway.h>
#include <lockfile.h>
#include <macros.h>
#include <git/project_git_utils.h>
#include <git2.h>
#include <project.h>
#include <project/project_file.h>
#include <trace_helpers.h>
@ -45,6 +47,7 @@
#include <title_block.h>
PROJECT::PROJECT() :
m_readOnly( false ),
m_textVarsTicker( 0 ),
@ -85,6 +88,16 @@ bool PROJECT::TextVarResolver( wxString* aToken ) const
*aToken = TITLE_BLOCK::GetCurrentDate();
return true;
}
else if( aToken->IsSameAs( wxT( "VCSHASH" ) ) )
{
*aToken = KIGIT::PROJECT_GIT_UTILS::GetCurrentHash( GetProjectFullName(), false );
return true;
}
else if( aToken->IsSameAs( wxT( "VCSSHORTHASH" ) ) )
{
*aToken = KIGIT::PROJECT_GIT_UTILS::GetCurrentHash( GetProjectFullName(), true );
return true;
}
else if( GetTextVars().count( *aToken ) > 0 )
{
*aToken = GetTextVars().at( *aToken );

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()
{

View File

@ -289,13 +289,14 @@ bool FIELD_VALIDATOR::Validate( wxWindow* aParent )
}
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
wxString GetFieldValidationErrorMessage( FIELD_T aFieldId, const wxString& aValue )
{
wxString msg;
FIELD_VALIDATOR validator( aFieldId );
wxString msg;
if( HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
if( validator.HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
{
switch( m_fieldId )
switch( aFieldId )
{
case FIELD_T::SHEET_NAME: msg = _( "A sheet must have a name." ); break;
case FIELD_T::SHEET_FILENAME: msg = _( "A sheet must have a file specified." ); break;
@ -303,11 +304,11 @@ bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
}
}
if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( aValue ) )
if( msg.empty() && validator.HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) )
{
wxArrayString badCharsFound;
for( const wxUniCharRef& excludeChar : GetCharExcludes() )
for( const wxUniCharRef& excludeChar : validator.GetCharExcludes() )
{
if( aValue.Find( excludeChar ) != wxNOT_FOUND )
{
@ -324,68 +325,83 @@ bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
}
}
wxString badChars;
for( size_t i = 0; i < badCharsFound.GetCount(); i++ )
if( !badCharsFound.IsEmpty() )
{
if( !badChars.IsEmpty() )
wxString badChars;
for( size_t i = 0; i < badCharsFound.GetCount(); i++ )
{
if( badCharsFound.GetCount() == 2 )
if( !badChars.IsEmpty() )
{
badChars += _( " or " );
}
else
{
if( i < badCharsFound.GetCount() - 2 )
badChars += _( ", or " );
if( badCharsFound.GetCount() == 2 )
{
badChars += _( " or " );
}
else
badChars += wxT( ", " );
{
if( i < badCharsFound.GetCount() - 2 )
badChars += _( ", or " );
else
badChars += wxT( ", " );
}
}
badChars += badCharsFound.Item( i );
}
badChars += badCharsFound.Item( i );
switch( aFieldId )
{
case FIELD_T::REFERENCE:
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::VALUE:
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::FOOTPRINT:
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::DATASHEET:
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::SHEET_NAME:
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::SHEET_FILENAME:
msg.Printf( _( "The sheet filename cannot contain %s character(s)." ), badChars );
break;
default:
msg.Printf( _( "The field cannot contain %s character(s)." ), badChars );
break;
};
}
}
switch( m_fieldId )
if( msg.empty() )
{
if( aFieldId == FIELD_T::REFERENCE && aValue.Contains( wxT( "${" ) ) )
{
case FIELD_T::REFERENCE:
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::VALUE:
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::FOOTPRINT:
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::DATASHEET:
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::SHEET_NAME:
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
break;
case FIELD_T::SHEET_FILENAME:
msg.Printf( _( "The sheet filename cannot contain %s character(s)." ), badChars );
break;
default:
msg.Printf( _( "The field cannot contain %s character(s)." ), badChars );
break;
};
}
else if( m_fieldId == FIELD_T::REFERENCE && aValue.Contains( wxT( "${" ) ) )
{
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
}
else if( m_fieldId == FIELD_T::REFERENCE && UTIL::GetRefDesPrefix( aValue ).IsEmpty() )
{
msg.Printf( _( "References must start with a letter." ) );
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
}
else if( aFieldId == FIELD_T::REFERENCE && UTIL::GetRefDesPrefix( aValue ).IsEmpty() )
{
msg.Printf( _( "References must start with a letter." ) );
}
}
return msg;
}
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
{
wxString msg = GetFieldValidationErrorMessage( m_fieldId, aValue );
if( !msg.empty() )
{
if( m_validatorWindow )

View File

@ -642,9 +642,13 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey += MD_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.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL;

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;
@ -698,9 +698,13 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
if( ( mods & wxMOD_SHIFT ) && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
key |= MD_SHIFT;
if( mods & wxMOD_ALTGR )
key |= MD_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.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
key |= MD_CTRL;

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

@ -227,16 +227,16 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame, wxWind
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
m_PanelNetType[PANELALLEGRO] = page;
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "PADS" ), NET_TYPE_PADS, false );
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in PADS format" ) );
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
m_PanelNetType[PANELPADS] = page;
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "CadStar" ), NET_TYPE_CADSTAR, false );
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in CadStar format" ) );
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
m_PanelNetType[PANELCADSTAR] = page;
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "PADS" ), NET_TYPE_PADS, false );
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in PADS format" ) );
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
m_PanelNetType[PANELPADS] = page;
InstallPageSpice();
InstallPageSpiceModel();

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

@ -152,10 +152,10 @@ const wxAuiPaneInfo& defaultDesignBlocksPaneInfo( wxWindow* aWindow )
EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
APP_SETTINGS_BASE( "eeschema", eeschemaSchemaVersion ),
m_Appearance(),
m_AutoplaceFields(),
m_Drawing(),
m_FindReplaceExtra(),
m_Input(),
m_AutoplaceFields(),
m_Selection(),
m_PageSettings(),
m_AnnotatePanel(),
m_BomPanel(),
@ -163,8 +163,9 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_LibViewPanel(),
m_NetlistPanel(),
m_SymChooserPanel(),
m_FindReplaceExtra(),
m_ERCDialog(),
m_ImportGraphics(),
m_Selection(),
m_Simulator(),
m_RescueNeverShow( false )
{
@ -189,9 +190,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 +589,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

@ -1542,7 +1542,7 @@ std::vector<LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUnitDrawItems()
#define REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider, true )
#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider, false )
int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aReporter ) const
{
@ -1586,35 +1586,34 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR
return retv;
}
// Make sure shapes and pins are sorted. No need with fields as those are
// matched by id/name.
// Make sure shapes are sorted. No need with fields or pins as those are matched by id/name and number.
std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> aShapes;
std::set<const SCH_ITEM*> aFields;
std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> aPins;
std::set<const SCH_FIELD*> aFields;
std::set<const SCH_PIN*> aPins;
for( auto it = m_drawings.begin(); it != m_drawings.end(); ++it )
{
if( it->Type() == SCH_SHAPE_T )
aShapes.insert( &(*it) );
else if( it->Type() == SCH_FIELD_T )
aFields.insert( &(*it) );
aFields.insert( static_cast<const SCH_FIELD*>( &(*it) ) );
else if( it->Type() == SCH_PIN_T )
aPins.insert( &(*it) );
aPins.insert( static_cast<const SCH_PIN*>( &(*it) ) );
}
std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> bShapes;
std::set<const SCH_ITEM*> bFields;
std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> bPins;
std::set<const SCH_FIELD*> bFields;
std::set<const SCH_PIN*> bPins;
for( auto it = aRhs.m_drawings.begin(); it != aRhs.m_drawings.end(); ++it )
{
if( it->Type() == SCH_SHAPE_T )
bShapes.insert( &(*it) );
else if( it->Type() == SCH_FIELD_T )
bFields.insert( &(*it) );
bFields.insert( static_cast<const SCH_FIELD*>( &(*it) ) );
else if( it->Type() == SCH_PIN_T )
bPins.insert( &(*it) );
bPins.insert( static_cast<const SCH_PIN*>( &(*it) ) );
}
if( int tmp = static_cast<int>( aShapes.size() - bShapes.size() ) )
@ -1632,7 +1631,9 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR
if( int tmp2 = (*aIt)->compare( *(*bIt), aCompareFlags ) )
{
retv = tmp2;
REPORT( wxString::Format( _( "%s differs." ), ITEM_DESC( *aIt ) ) );
REPORT( wxString::Format( _( "Graphic item differs: %s; %s." ),
ITEM_DESC( *aIt ),
ITEM_DESC( *bIt ) ) );
if( !aReporter )
return retv;
@ -1640,46 +1641,48 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR
}
}
if( int tmp = static_cast<int>( aPins.size() - bPins.size() ) )
for( const SCH_PIN* aPin : aPins )
{
retv = tmp;
REPORT( _( "Pin count differs." ) );
const SCH_PIN* bPin = aRhs.GetPin( aPin->GetNumber(), aPin->GetUnit(), aPin->GetBodyStyle() );
if( !aReporter )
return retv;
}
else
{
for( const SCH_ITEM* aPinItem : aPins )
if( !bPin )
{
const SCH_PIN* aPin = static_cast<const SCH_PIN*>( aPinItem );
const SCH_PIN* bPin = aRhs.GetPin( aPin->GetNumber(), aPin->GetUnit(),
aPin->GetBodyStyle() );
retv = 1;
REPORT( wxString::Format( _( "Extra pin in schematic symbol: %s." ), ITEM_DESC( aPin ) ) );
if( !bPin )
{
retv = 1;
REPORT( wxString::Format( _( "Pin %s not found." ), aPin->GetNumber() ) );
if( !aReporter )
return retv;
}
else if( int tmp = aPin->SCH_ITEM::compare( *bPin, aCompareFlags ) )
{
retv = tmp;
REPORT( wxString::Format( _( "Pin %s differs: %s; %s" ),
aPin->GetNumber(),
ITEM_DESC( aPin ),
ITEM_DESC( bPin ) ) );
if( !aReporter )
return retv;
}
else if( int tmp2 = aPinItem->compare( *bPin, aCompareFlags ) )
{
retv = tmp2;
REPORT( wxString::Format( _( "Pin %s differs." ), aPin->GetNumber() ) );
if( !aReporter )
return retv;
}
if( !aReporter )
return retv;
}
}
for( const SCH_ITEM* aFieldItem : aFields )
for( const SCH_PIN* bPin : bPins )
{
const SCH_PIN* aPin = aRhs.GetPin( bPin->GetNumber(), bPin->GetUnit(), bPin->GetBodyStyle() );
if( !aPin )
{
retv = 1;
REPORT( wxString::Format( _( "Missing pin in schematic symbol: %s." ), ITEM_DESC( bPin ) ) );
if( !aReporter )
return retv;
}
}
for( const SCH_FIELD* aField : aFields )
{
const SCH_FIELD* aField = static_cast<const SCH_FIELD*>( aFieldItem );
const SCH_FIELD* bField = nullptr;
int tmp = 0;
if( aField->IsMandatory() )
bField = aRhs.GetField( aField->GetId() );
@ -1687,33 +1690,68 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aR
bField = aRhs.GetField( aField->GetName() );
if( !bField )
tmp = 1;
else
tmp = aFieldItem->compare( *bField, aCompareFlags );
if( tmp )
{
retv = tmp;
REPORT( wxString::Format( _( "%s field differs." ), aField->GetName( false ) ) );
retv = 1;
REPORT( wxString::Format( _( "Extra field in schematic symbol: %s." ), ITEM_DESC( aField ) ) );
if( !aReporter )
return retv;
}
else
{
int tmp = 0;
// For EQUALITY comparison, we need to compare field content directly
// since SCH_ITEM::compare() returns 0 for EQUALITY flag
if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
{
// Compare field text content
tmp = aField->GetText().compare( bField->GetText() );
}
if( tmp == 0 )
{
// Fall back to base class comparison for other properties
tmp = aField->SCH_ITEM::compare( *bField, aCompareFlags );
}
if( tmp != 0 )
{
retv = tmp;
REPORT( wxString::Format( _( "Field '%s' differs: %s; %s." ),
aField->GetName( false ),
ITEM_DESC( aField ),
ITEM_DESC( bField ) ) );
if( !aReporter )
return retv;
}
}
}
for( const SCH_FIELD* bField : bFields )
{
const SCH_FIELD* aField = nullptr;
if( bField->IsMandatory() )
aField = aRhs.GetField( bField->GetId() );
else
aField = aRhs.GetField( bField->GetName() );
if( !aField )
{
retv = 1;
REPORT( wxString::Format( _( "Missing field in schematic symbol: %s." ), ITEM_DESC( bField ) ) );
if( !aReporter )
return retv;
}
}
if( int tmp = static_cast<int>( aFields.size() - bFields.size() ) )
{
retv = tmp;
REPORT( _( "Field count differs." ) );
if( !aReporter )
return retv;
}
if( int tmp = static_cast<int>( m_fpFilters.GetCount() - aRhs.m_fpFilters.GetCount() ) )
{
retv = tmp;
REPORT( _( "Footprint filters differs." ) );
REPORT( _( "Footprint filter count differs." ) );
if( !aReporter )
return retv;

View File

@ -750,7 +750,9 @@ std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNameInfo( int
info->m_Thickness = m_nameThickness;
info->m_Angle = ANGLE_HORIZONTAL;
if( m_pin.GetParentSymbol()->GetPinNameOffset() > 0 )
bool nameInside = m_pin.GetParentSymbol()->GetPinNameOffset() > 0;
if( nameInside )
{
// This means name inside the pin
VECTOR2I pos = { m_pin.GetLength() + m_pin.GetParentSymbol()->GetPinNameOffset(), 0 };
@ -760,6 +762,7 @@ std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNameInfo( int
info->m_TextPosition = pos + VECTOR2I{ thickOffset, 0 };
info->m_HAlign = GR_TEXT_H_ALIGN_LEFT;
info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
transformTextForPin( *info );
}
else
{
@ -769,42 +772,44 @@ std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNameInfo( int
info->m_TextPosition = pos;
info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM;
}
// New policy: names follow same positioning semantics as numbers.
const SYMBOL* parentSym = m_pin.GetParentSymbol();
if( parentSym )
{
int maxHalfHeight = 0;
for( const SCH_PIN* p : parentSym->GetPins() )
// New policy: names follow same positioning semantics as numbers except when
// specified as inside. When names are inside, they should not overlap with the
// number position.
const SYMBOL* parentSym = m_pin.GetParentSymbol();
if( parentSym )
{
wxString n = p->GetShownName();
if( n.IsEmpty() )
continue;
maxHalfHeight = std::max( maxHalfHeight, p->GetNameTextSize() / 2 );
}
int clearance = getPinTextOffset() + schIUScale.MilsToIU( PIN_TEXT_MARGIN );
VECTOR2I pinPos = m_pin.GetPosition();
PIN_ORIENTATION orient = m_pin.PinDrawOrient( DefaultTransform );
bool verticalOrient = ( orient == PIN_ORIENTATION::PIN_UP || orient == PIN_ORIENTATION::PIN_DOWN );
int maxHalfHeight = 0;
for( const SCH_PIN* p : parentSym->GetPins() )
{
wxString n = p->GetShownName();
if( n.IsEmpty() )
continue;
maxHalfHeight = std::max( maxHalfHeight, p->GetNameTextSize() / 2 );
}
int clearance = getPinTextOffset() + schIUScale.MilsToIU( PIN_TEXT_MARGIN );
VECTOR2I pinPos = m_pin.GetPosition();
PIN_ORIENTATION orient = m_pin.PinDrawOrient( DefaultTransform );
bool verticalOrient = ( orient == PIN_ORIENTATION::PIN_UP || orient == PIN_ORIENTATION::PIN_DOWN );
if( verticalOrient )
{
// Vertical pins: name mirrors number placement (left + rotated) for visual consistency.
int boxWidth = info->m_TextSize * (int) info->m_Text.Length() * 0.6; // heuristic width
int centerX = pinPos.x - clearance - boxWidth / 2;
info->m_TextPosition = { centerX, pinPos.y };
info->m_Angle = ANGLE_VERTICAL;
info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
}
else
{
// Horizontal pins: name above (negative Y) aligned to same Y offset logic as numbers.
info->m_TextPosition = { pinPos.x, pinPos.y - ( maxHalfHeight + clearance ) };
info->m_Angle = ANGLE_HORIZONTAL;
info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
if( verticalOrient )
{
// Vertical pins: name mirrors number placement (left + rotated) for visual consistency.
int boxWidth = info->m_TextSize * (int) info->m_Text.Length() * 0.6; // heuristic width
int centerX = pinPos.x - clearance - boxWidth / 2;
info->m_TextPosition = { centerX, pinPos.y };
info->m_Angle = ANGLE_VERTICAL;
info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
}
else
{
// Horizontal pins: name above (negative Y) aligned to same Y offset logic as numbers.
info->m_TextPosition = { pinPos.x, pinPos.y - ( maxHalfHeight + clearance ) };
info->m_Angle = ANGLE_HORIZONTAL;
info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
}
}
}
return info;

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

@ -974,9 +974,19 @@ void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
{
return wxString::Format( _( "Field %s '%s'" ),
UnescapeString( GetName() ),
aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
if( content.IsEmpty() )
{
return wxString::Format( _( "Field %s (empty)" ),
UnescapeString( GetName() ) );
}
else
{
return wxString::Format( _( "Field %s '%s'" ),
UnescapeString( GetName() ),
content );
}
}

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
@ -1858,10 +1937,20 @@ wxString SCH_DIRECTIVE_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider
}
else
{
return wxString::Format( _( "Directive Label [%s %s]" ),
UnescapeString( m_fields[0].GetName() ),
aFull ? m_fields[0].GetShownText( false )
: KIUI::EllipsizeMenuText( m_fields[0].GetText() ) );
const SCH_FIELD& firstField = m_fields[0];
wxString content = aFull ? firstField.GetShownText( false ) : KIUI::EllipsizeMenuText( firstField.GetText() );
if( content.IsEmpty() )
{
return wxString::Format( _( "Directive Label [%s (empty)]" ),
UnescapeString( m_fields[0].GetName() ) );
}
else
{
return wxString::Format( _( "Directive Label [%s %s]" ),
UnescapeString( m_fields[0].GetName() ),
content );
}
}
}

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

@ -198,8 +198,11 @@ void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
std::vector<int> SCH_LINE::ViewGetLayers() const
{
return { LAYER_DANGLING, m_layer, LAYER_SELECTION_SHADOWS, LAYER_NET_COLOR_HIGHLIGHT,
LAYER_OP_VOLTAGES };
if( IsWire() || IsBus() )
return { LAYER_DANGLING, m_layer, LAYER_SELECTION_SHADOWS, LAYER_NET_COLOR_HIGHLIGHT,
LAYER_OP_VOLTAGES };
return { LAYER_DANGLING, m_layer, LAYER_SELECTION_SHADOWS, LAYER_OP_VOLTAGES };
}

View File

@ -1825,6 +1825,9 @@ void SCH_PAINTER::draw( const SCH_LINE* aLine, int aLayer )
if( !highlightNetclassColors && drawingNetColorHighlights )
return;
if( drawingNetColorHighlights && !( aLine->IsWire() || aLine->IsBus() ) )
return;
if( m_schSettings.m_OverrideItemColors && drawingNetColorHighlights )
return;

View File

@ -46,6 +46,8 @@
#include <settings/color_settings.h>
#include <settings/settings_manager.h>
#include <trace_helpers.h>
#include <validators.h>
#include <properties/property_validators.h>
#include <pgm_base.h>
#include <wx/log.h>
@ -1169,7 +1171,7 @@ wxString SCH_SHEET::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFu
{
const SCH_FIELD* sheetnameField = GetField( FIELD_T::SHEET_NAME );
return wxString::Format( _( "Hierarchical Sheet %s" ),
return wxString::Format( _( "Hierarchical Sheet '%s'" ),
aFull ? sheetnameField->GetShownText( false )
: KIUI::EllipsizeMenuText( sheetnameField->GetText() ) );
}
@ -1657,7 +1659,21 @@ static struct SCH_SHEET_DESC
propMgr.InheritsAfter( TYPE_HASH( SCH_SHEET ), TYPE_HASH( SCH_ITEM ) );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, wxString>( _HKI( "Sheet Name" ),
&SCH_SHEET::SetName, &SCH_SHEET::GetName ) );
&SCH_SHEET::SetName, &SCH_SHEET::GetName ) )
.SetValidator( []( const wxAny&& aValue, EDA_ITEM* ) -> VALIDATOR_RESULT
{
wxString value;
if( !aValue.GetAs( &value ) )
return {};
wxString msg = GetFieldValidationErrorMessage( FIELD_T::SHEET_NAME, value );
if( msg.empty() )
return {};
return std::make_unique<VALIDATION_ERROR_MSG>( msg );
} );
propMgr.AddProperty( new PROPERTY<SCH_SHEET, int>( _HKI( "Border Width" ),
&SCH_SHEET::SetBorderWidth, &SCH_SHEET::GetBorderWidth,

View File

@ -328,7 +328,7 @@ void SCH_SHEET_PIN::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
wxString SCH_SHEET_PIN::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
{
return wxString::Format( _( "Hierarchical Sheet Pin %s" ),
return wxString::Format( _( "Hierarchical Sheet Pin '%s'" ),
aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
}

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

@ -384,7 +384,8 @@ void BACK_ANNOTATE::applyChangelist()
if( !m_dryRun )
commit.Modify( symbol, screen, RECURSE_MODE::NO_RECURSE );
if( m_processReferences && ref.GetRef() != fpData.m_ref && !skip )
if( m_processReferences && ref.GetRef() != fpData.m_ref && !skip
&& !symbol->GetField( FIELD_T::REFERENCE )->HasTextVars() )
{
++m_changesCount;
msg.Printf( _( "Change %s reference designator to '%s'." ),
@ -397,7 +398,8 @@ void BACK_ANNOTATE::applyChangelist()
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
if( m_processFootprints && oldFootprint != fpData.m_footprint && !skip )
if( m_processFootprints && oldFootprint != fpData.m_footprint && !skip
&& !symbol->GetField( FIELD_T::FOOTPRINT )->HasTextVars() )
{
++m_changesCount;
msg.Printf( _( "Change %s footprint assignment from '%s' to '%s'." ),
@ -411,7 +413,8 @@ void BACK_ANNOTATE::applyChangelist()
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
if( m_processValues && oldValue != fpData.m_value && !skip )
if( m_processValues && oldValue != fpData.m_value && !skip
&& !symbol->GetField( FIELD_T::VALUE )->HasTextVars() )
{
++m_changesCount;
msg.Printf( _( "Change %s value from '%s' to '%s'." ),
@ -502,6 +505,7 @@ void BACK_ANNOTATE::applyChangelist()
// with all the variables resolved. The footprints field value gets the symbol's
// resolved value when the PCB is updated from the schematic.
if( symField
&& !symField->HasTextVars()
&& symField->GetShownText( &ref.GetSheetPath(), false ) != fpFieldValue )
{
m_changesCount++;

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

@ -548,9 +548,13 @@ void HIERARCHY_PANE::onCharHook( wxKeyEvent& aKeyStroke )
int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey += MD_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.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL;

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

@ -256,6 +256,9 @@ namespace EDA_UNIT_UTILS
KICOMMON_API double DoubleValueFromString( const wxString& aTextValue );
KICOMMON_API bool DoubleValueFromString( const EDA_IU_SCALE& aIuScale, const wxString& aTextValue,
double& aDoubleValue );
/**
* Convert \a aTextValue in \a aUnits to internal units used by the application.
*

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

@ -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,38 +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;
int wxmods = aState->GetModifiers();
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
{
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;
}
/// 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

@ -162,5 +162,11 @@ private:
FIELD_T m_fieldId;
};
/**
* Return the error message if @a aValue is invalid for @a aFieldId.
* Returns an empty string when the value is valid.
*/
wxString GetFieldValidationErrorMessage( FIELD_T aFieldId, const wxString& aValue );
#endif // #ifndef VALIDATORS_H

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
@ -51,6 +54,56 @@ void TEMPLATE_SELECTION_PANEL::AddTemplateWidget( TEMPLATE_WIDGET* aTemplateWidg
}
// Sort the widgets alphabetically, leaving Default at the top
void TEMPLATE_SELECTION_PANEL::SortAlphabetically()
{
std::vector<TEMPLATE_WIDGET*> sortedList;
TEMPLATE_WIDGET* default_temp = nullptr;
size_t count = m_SizerChoice->GetItemCount();
if( count <= 1 )
return;
for( size_t idx = 0; idx < count; idx++ )
{
wxSizerItem* item = m_SizerChoice->GetItem( idx );
if( item && item->IsWindow() )
{
TEMPLATE_WIDGET* temp = static_cast<TEMPLATE_WIDGET*>( item->GetWindow() );
const wxString title = *temp->GetTemplate()->GetTitle();
if( default_temp == nullptr && title.CmpNoCase( "default" ) == 0 )
default_temp = temp;
else
sortedList.push_back( temp );
}
}
std::sort(
sortedList.begin(), sortedList.end(),
[]( TEMPLATE_WIDGET* aWidgetA, TEMPLATE_WIDGET* aWidgetB ) -> bool
{
const wxString* a = aWidgetA->GetTemplate()->GetTitle();
const wxString* b = aWidgetB->GetTemplate()->GetTitle();
return ( *a ).CmpNoCase( *b ) < 0;
});
m_SizerChoice->Clear( false );
if( default_temp != nullptr )
m_SizerChoice->Add( default_temp );
for (TEMPLATE_WIDGET* temp : sortedList)
{
m_SizerChoice->Add( temp );
}
Layout();
}
TEMPLATE_WIDGET::TEMPLATE_WIDGET( wxWindow* aParent, DIALOG_TEMPLATE_SELECTOR* aDialog ) :
TEMPLATE_WIDGET_BASE( aParent )
{
@ -99,7 +152,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 ) );
}
@ -317,6 +387,7 @@ void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPag
}
}
m_panels[aPage]->SortAlphabetically();
Layout();
}

View File

@ -81,6 +81,8 @@ public:
void AddTemplateWidget( TEMPLATE_WIDGET* aTemplateWidget );
void SortAlphabetically();
protected:
wxNotebookPage* m_parent;
wxString m_templatesPath; ///< the path to access to the folder

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

@ -120,6 +120,7 @@ set( PCBNEW_DIALOGS
dialogs/dialog_outset_items_base.cpp
dialogs/dialog_pad_properties.cpp
dialogs/dialog_pad_properties_base.cpp
dialogs/dialog_fp_edit_pad_table.cpp
dialogs/dialog_plot.cpp
dialogs/dialog_plot_base.cpp
dialogs/dialog_pns_diff_pair_dimensions.cpp

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

@ -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(); }

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