Compare commits
263 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fda292bd08 | |||
| c666bf8626 | |||
| 96f20d102b | |||
| f57cdb52dd | |||
| a5d2294ec3 | |||
| 72fdb41b73 | |||
| 2ca04123d4 | |||
| 07a4710363 | |||
| c01e37304f | |||
| 52b57b1145 | |||
| 7b4e444f6c | |||
| a9f4f85746 | |||
| bc7ece44eb | |||
| 51cc22a4f2 | |||
| 38f2541a3f | |||
| a05e3de852 | |||
| 908e7205e7 | |||
| a80e410683 | |||
| fa234e4b58 | |||
| fb82e722e1 | |||
| b45f9e7392 | |||
| d496b281ef | |||
| 2a46ff370a | |||
| 44d0b27544 | |||
| 7d76868c5c | |||
| e4d9d1829f | |||
| e585948861 | |||
| e31b177335 | |||
| 4624d57bc2 | |||
| 4f2d1ec5a1 | |||
| 5bcb3edae1 | |||
| 30fbfd53c1 | |||
| dc979be459 | |||
| 450c4517b5 | |||
| 47cd4d6b7a | |||
| 8842c575c3 | |||
| 858c23f731 | |||
| 1d879d51c5 | |||
| 6e0df489eb | |||
| a9be5c5759 | |||
| 258e2fd46f | |||
| f5852f0869 | |||
| 1d0adbc5d6 | |||
| 34834fd963 | |||
| 2f095aeafb | |||
| 47bb72179f | |||
| 9f7af4a3a7 | |||
| dda127ceec | |||
| 68e6e0a742 | |||
| a844ba713a | |||
| 5d75bd0f0a | |||
| c492565ee8 | |||
| 879d2bef4b | |||
| 05376a39ac | |||
| 9c01c2aeb8 | |||
| 72db7bfedc | |||
| 95cfe2cc2e | |||
| c6f5daf87f | |||
| b1711d692a | |||
| d538182f1f | |||
| b4b87b5c38 | |||
| eed95e612d | |||
| 68d3c7f5c2 | |||
| 848d5484d8 | |||
| d3b84f219c | |||
| 58ccf62d2f | |||
| 021229647f | |||
| 9a812bc63c | |||
| 8a9201b79c | |||
| f8e9b3402f | |||
| 808c645933 | |||
| ea467c1bac | |||
| c51b6a0cd2 | |||
| 10f16ed82e | |||
| ab9cf326e8 | |||
| 4e6087c183 | |||
| e7abf472ba | |||
| f0c6b57ab9 | |||
| e830709cda | |||
| 415aac7fc5 | |||
| 21f15c3b2a | |||
| 0f8df0bcee | |||
| d6ef6252a2 | |||
| f13c9cbd49 | |||
| c2af66a44b | |||
| 40c50c94fb | |||
| 0103f92d0e | |||
| 0f27f8b7fc | |||
| 5631b61dbc | |||
| da659f5d05 | |||
| 2029c5389f | |||
| 4205e70775 | |||
| 4f66225de7 | |||
| 18e4682c3a | |||
| 6b540ae1e3 | |||
| 1f12b6c17d | |||
| e2c23c70f1 | |||
| f60f0394be | |||
| bd64bcf446 | |||
| 176d0f5820 | |||
| 118ee1c072 | |||
| fd15a1108b | |||
| 43b5d4d91f | |||
| d11ab8201f | |||
| 86bae558b4 | |||
| 68991a7644 | |||
| 0701640c5a | |||
| 9fe656a33c | |||
| 3fb8f22fd3 | |||
| 929930fb3a | |||
| 4195b874d5 | |||
| ae0d6c80dd | |||
| 4e2f84727c | |||
| 35889130e8 | |||
| 2e7145cc4b | |||
| e0d955993c | |||
| cd7a646fcc | |||
| cb2a09d17c | |||
| d0cb210427 | |||
| b89d77bf36 | |||
| 7fdeb4796a | |||
| e82088a59b | |||
| 5a5191361f | |||
| b47f8f4504 | |||
| 00ae91d6b5 | |||
| 097e0eadf1 | |||
| c8c293dca8 | |||
| e6cfd1cdcf | |||
| 905170b4f4 | |||
| 57fa8ea2b9 | |||
| c7730a00c4 | |||
| beaaf3b5be | |||
| b644f15d7f | |||
| af398762db | |||
| dfd40b566d | |||
| e056ef2693 | |||
| 02d0944546 | |||
| 1aba70ca37 | |||
| ff8b82d060 | |||
| 68d1e3223a | |||
| 9e64d52a38 | |||
| f7b3c0226b | |||
| 17fc05ec45 | |||
| b64f1f2bd3 | |||
| b32d8862da | |||
| ff061e51a0 | |||
| 6020e6d6f9 | |||
| a3fffc868f | |||
| 9670aa1b8a | |||
| 85ba5ae406 | |||
| faa3287fd6 | |||
| 33ab1d9242 | |||
| 01aa2d7e42 | |||
| b24e2ac00d | |||
| 2bc3ef82dc | |||
| 672ba5cd41 | |||
| 905b9ae6c5 | |||
| f81a203c22 | |||
| 7aa0431a60 | |||
| 57505674f8 | |||
| 558bef00cc | |||
| 28f9bd797a | |||
| 52d6fc66f1 | |||
| ab49e9b29d | |||
| f6710e64de | |||
| 804154e21d | |||
| 03cb8521bc | |||
| 3ee940e3fb | |||
| 8b25c3b0fe | |||
| 529cf246d2 | |||
| 7e7c281a64 | |||
| 350925f10a | |||
| 5e8982600a | |||
| e633af9216 | |||
| b0f21e5452 | |||
| d2d582cc00 | |||
| 4f11681c4a | |||
| 897ebee00f | |||
| be0a42a09a | |||
| 3069799a2d | |||
| ad22e53518 | |||
| 2ef05eb191 | |||
| 235e583182 | |||
| 76ce4ec535 | |||
| 0226481156 | |||
| 8fab2d8ca3 | |||
| 1c6d8b3f5e | |||
| 32e9ab9b75 | |||
| ca0207016e | |||
| 9ca1bf63d9 | |||
| 7e13870ae3 | |||
| 3c907b5589 | |||
| e9efd9971c | |||
| 2bf9a6f5d1 | |||
| 42c67b40b1 | |||
| 5ae3c55a99 | |||
| 54e9a97b26 | |||
| 1e3b879d93 | |||
| 7ca6a93436 | |||
| 05c11d023f | |||
| 996c3d7fa1 | |||
| b204742fe3 | |||
| 2b8e62e0b9 | |||
| c3d122becf | |||
| 43c828474a | |||
| 8073185c36 | |||
| f1ddcfe799 | |||
| 9d6f9c84d0 | |||
| 680a693c04 | |||
| 4f72dd421a | |||
| bc533de0a3 | |||
| c08109d63e | |||
| b11f0a31b9 | |||
| f6fabdc8ee | |||
| 965abb46d0 | |||
| c9f53c607e | |||
| 7b91b51bcf | |||
| a3354dc352 | |||
| 6723964cdd | |||
| df5f4ba541 | |||
| 926f41a0f5 | |||
| db801c8d7e | |||
| ad433b9468 | |||
| 1eefb2b70a | |||
| 3d6527c1be | |||
| 319530ad01 | |||
| 24efca1db1 | |||
| a009d859d0 | |||
| 44a3bb9274 | |||
| 72e1904708 | |||
| 279a30974e | |||
| efc6c3e45e | |||
| f7380ae015 | |||
| 26b6c28bef | |||
| 8cd7b73b2a | |||
| c2d31699bf | |||
| 47c5918c3d | |||
| 12cf3f9301 | |||
| 013aab58d6 | |||
| 316a9511e8 | |||
| 29fadcb931 | |||
| d73fecd2a1 | |||
| 35caf91c31 | |||
| 352cf21ffc | |||
| 21335f604f | |||
| c6b7f90408 | |||
| a5dee0c2b1 | |||
| bf73ad42ca | |||
| 7d905948f5 | |||
| 5c8c0e0648 | |||
| 4cfa2e3a38 | |||
| eecf0cd685 | |||
| 91e5e81bb4 | |||
| 5b3cd96641 | |||
| db0967d5c9 | |||
| 5165ced528 | |||
| eb4f9fa093 | |||
| 47381f3d90 | |||
| e697339bc6 | |||
| 6159cee2b0 | |||
| 3460b33ccf | |||
| 5baaa89131 | |||
| d45a38f086 |
@@ -8,6 +8,7 @@ win64_build:
|
||||
interruptible: false
|
||||
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/ltsc2022-msvc:latest
|
||||
variables:
|
||||
VCPKG_BINARY_SOURCES: 'nuget,gitlab,readwrite'
|
||||
# Switch the compressor to fastzip and reduce the compression level
|
||||
FF_USE_FASTZIP: "true"
|
||||
CACHE_COMPRESSION_LEVEL: "fast"
|
||||
@@ -23,6 +24,7 @@ win64_build:
|
||||
script:
|
||||
- C:\builder\build.ps1 -Env -Arch x64
|
||||
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
|
||||
- nuget.exe sources add -Name gitlab -Source "https://gitlab.com/api/v4/projects/27426693/packages/nuget/index.json" -UserName gitlab-ci-token -Password $env:CI_JOB_TOKEN
|
||||
- mkdir -p build/windows -Force
|
||||
- cd build/windows
|
||||
- cmake `
|
||||
@@ -34,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 ../../
|
||||
|
||||
@@ -486,9 +486,12 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
// Initialize ray packets
|
||||
const SFVEC2UI& blockPos = m_blockPositions[iBlock];
|
||||
const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset );
|
||||
const SFVEC2F randDisp = ( m_camera.GetProjection() == PROJECTION_TYPE::ORTHO ) ?
|
||||
SFVEC2F( 0.0f, 0.0f ) :
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR );
|
||||
|
||||
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) /* Displacement random factor */ );
|
||||
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + randDisp,
|
||||
randDisp /* Displacement random factor */ );
|
||||
|
||||
|
||||
HITINFO_PACKET hitPacket_X0Y0[RAYPACKET_RAYS_PER_PACKET];
|
||||
@@ -566,7 +569,7 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
|
||||
|
||||
RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f, 0.5f ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) );
|
||||
randDisp );
|
||||
|
||||
if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
|
||||
{
|
||||
@@ -603,16 +606,16 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - randDisp.x, randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X1Y0 );
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( randDisp.x, 0.5f - randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X0Y1 );
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - randDisp.x, 0.25f - randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X1Y1_half );
|
||||
|
||||
renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X1Y0,
|
||||
hitColor_AA_X1Y0 );
|
||||
|
||||
@@ -657,6 +657,12 @@ void PANEL_PREVIEW_3D_MODEL::UpdateDummyFootprint( bool aReloadRequired )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::SetEmbeddedFilesDelegate( EMBEDDED_FILES* aDelegate )
|
||||
{
|
||||
m_dummyBoard->SetEmbeddedFilesDelegate( aDelegate );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onModify()
|
||||
{
|
||||
KIWAY_HOLDER* kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( wxGetTopLevelParent( this ) );
|
||||
|
||||
@@ -59,6 +59,7 @@ wxDECLARE_EVENT( wxCUSTOM_PANEL_SHOWN_EVENT, wxCommandEvent );
|
||||
class WX_INFOBAR;
|
||||
class S3D_CACHE;
|
||||
class FILENAME_RESOLVER;
|
||||
class EMBEDDED_FILES;
|
||||
class BOARD;
|
||||
class BOARD_ADAPTER;
|
||||
class FOOTPRINT;
|
||||
@@ -97,6 +98,8 @@ public:
|
||||
*/
|
||||
void UpdateDummyFootprint( bool aRelaodRequired = true );
|
||||
|
||||
void SetEmbeddedFilesDelegate( EMBEDDED_FILES* aDelegate );
|
||||
|
||||
/**
|
||||
* Get the dummy footprint that is used for previewing the 3D model.
|
||||
* We use this to hold the temporary 3D model shapes.
|
||||
|
||||
+6
-1
@@ -22,7 +22,12 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
cmake_minimum_required( VERSION 3.21 FATAL_ERROR )
|
||||
if( MSVC )
|
||||
# CMake 3.28.1 or higher required for MSVC ARM builds for armasm64.exe support
|
||||
cmake_minimum_required( VERSION 3.28.1 FATAL_ERROR )
|
||||
else()
|
||||
cmake_minimum_required( VERSION 3.21 FATAL_ERROR )
|
||||
endif()
|
||||
|
||||
# Generate DEPFILES without transforming relative paths
|
||||
cmake_policy( SET CMP0116 OLD )
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -42,12 +42,45 @@ message BoardStackupResponse
|
||||
kiapi.board.BoardStackup stackup = 1;
|
||||
}
|
||||
|
||||
// Changes the stackup for the given board according to the contents of the message (**not yet implemented**)
|
||||
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
|
||||
// Returns BoardStackupResponse with the updated stackup, in normalized form
|
||||
message UpdateBoardStackup
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
kiapi.board.BoardStackup stackup = 2;
|
||||
}
|
||||
|
||||
message GetBoardEnabledLayers
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
}
|
||||
|
||||
message BoardEnabledLayersResponse
|
||||
{
|
||||
// The number of copper layers enabled in this board.
|
||||
uint32 copper_layer_count = 1;
|
||||
|
||||
// A list of all layers enabled in this board, including copper layers and ones which cannot be disabled.
|
||||
repeated kiapi.board.types.BoardLayer layers = 2;
|
||||
}
|
||||
|
||||
// Changes which layers are enabled in the board stackup
|
||||
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
|
||||
// Returns BoardEnabledLayersResponse with the updated layer set.
|
||||
message SetBoardEnabledLayers
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
|
||||
// The number of copper layers to enable in the board. Currently, this must be an even number >= 2.
|
||||
uint32 copper_layer_count = 2;
|
||||
|
||||
// The non-copper layers to enable. Note that any copper layers in this list are ignored; copper layers are enabled
|
||||
// by setting copper_layer_count. Note that the F/B.Courtyard, Edge.Cuts, and Margin layers cannot be disabled and
|
||||
// will be present in the board even if they are omitted from this list.
|
||||
repeated kiapi.board.types.BoardLayer layers = 3;
|
||||
}
|
||||
|
||||
message GetGraphicsDefaults
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
|
||||
@@ -36,7 +36,13 @@ if( MSVC )
|
||||
set( KICAD_HOST_ARCH "x64" )
|
||||
set( KICAD_HOST_ARCH_X64 1 )
|
||||
else()
|
||||
message(FATAL_ERROR "Failed to determine the host architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message(FATAL_ERROR "Failed to determine the host architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if( NOT KICAD_BUILD_ARCH STREQUAL KICAD_HOST_ARCH )
|
||||
set( CMAKE_CROSSCOMPILING TRUE )
|
||||
|
||||
string(TOUPPER ${KICAD_BUILD_ARCH} CMAKE_SYSTEM_PROCESSOR)
|
||||
endif()
|
||||
else()
|
||||
if ( NOT CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
@@ -58,38 +64,18 @@ if( MSVC )
|
||||
# cmake release AND when MSVC ships said cmake release
|
||||
if(KICAD_BUILD_ARCH_ARM)
|
||||
message( "Configuring ARM assembler" )
|
||||
# Explicitly specify the assembler to be used for Arm32 compile
|
||||
file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm\\armasm.exe" CMAKE_ASM_COMPILER)
|
||||
|
||||
set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
|
||||
message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
|
||||
|
||||
# Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
|
||||
# use ml[64].exe as the assembler.
|
||||
enable_language(ASM)
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
|
||||
enable_language(ASM_MARMASM)
|
||||
# Bugfix for CMake < 29.1
|
||||
set(ASM_DIALECT "_MARMASM")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
elseif(KICAD_BUILD_ARCH_ARM64)
|
||||
message( "Configuring ARM64 assembler" )
|
||||
|
||||
# Explicitly specify the assembler to be used for Arm64 compile
|
||||
file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER)
|
||||
|
||||
set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
|
||||
message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
|
||||
|
||||
# Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
|
||||
# use ml[64].exe as the assembler.
|
||||
enable_language(ASM)
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
enable_language(ASM_MARMASM)
|
||||
# Bugfix for CMake < 29.1
|
||||
set(ASM_DIALECT "_MARMASM")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
else()
|
||||
message( "Configuring MASM assembler" )
|
||||
if(KICAD_BUILD_ARCH_X86)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.4" )
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.5" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# compile_asm(TARGET target ASM_FILES file1 [file2 ...] OUTPUT_OBJECTS [variableName])
|
||||
# CMake does not support the ARM or ARM64 assemblers on Windows when using the
|
||||
# MSBuild generator. When the MSBuild generator is in use, we manually compile the assembly files
|
||||
# using this function.
|
||||
#
|
||||
# Borrowed from dotnet/runtime, licensed under MIT
|
||||
# Copyright (c) .NET Foundation and Contributors
|
||||
# https://github.com/dotnet/runtime/blob/main/eng/native/functions.cmake
|
||||
function(compile_asm)
|
||||
set(options "")
|
||||
set(oneValueArgs TARGET OUTPUT_OBJECTS)
|
||||
set(multiValueArgs ASM_FILES)
|
||||
cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
|
||||
|
||||
get_include_directories_asm(ASM_INCLUDE_DIRECTORIES)
|
||||
|
||||
set (ASSEMBLED_OBJECTS "")
|
||||
|
||||
foreach(ASM_FILE ${COMPILE_ASM_ASM_FILES})
|
||||
get_filename_component(name ${ASM_FILE} NAME_WE)
|
||||
# Produce object file where CMake would store .obj files for an OBJECT library.
|
||||
# ex: artifacts\obj\coreclr\windows.arm64.Debug\src\vm\wks\cee_wks.dir\Debug\AsmHelpers.obj
|
||||
set (OBJ_FILE "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_ASM_TARGET}.dir/${CMAKE_CFG_INTDIR}/${name}.obj")
|
||||
|
||||
# Need to compile asm file using custom command as include directories are not provided to asm compiler
|
||||
add_custom_command(OUTPUT ${OBJ_FILE}
|
||||
COMMAND "${CMAKE_ASM_COMPILER}" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}
|
||||
DEPENDS ${ASM_FILE}
|
||||
COMMENT "Assembling ${ASM_FILE} ---> \"${CMAKE_ASM_COMPILER}\" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}")
|
||||
|
||||
# mark obj as source that does not require compile
|
||||
set_source_files_properties(${OBJ_FILE} PROPERTIES EXTERNAL_OBJECT TRUE)
|
||||
|
||||
# Add the generated OBJ in the dependency list so that it gets consumed during linkage
|
||||
list(APPEND ASSEMBLED_OBJECTS ${OBJ_FILE})
|
||||
endforeach()
|
||||
|
||||
set(${COMPILE_ASM_OUTPUT_OBJECTS} ${ASSEMBLED_OBJECTS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Build a list of include directories for consumption by the assembler
|
||||
function(get_include_directories_asm IncludeDirectories)
|
||||
get_directory_property(dirs INCLUDE_DIRECTORIES)
|
||||
|
||||
foreach(dir IN LISTS dirs)
|
||||
list(APPEND INC_DIRECTORIES -I${dir};)
|
||||
endforeach()
|
||||
|
||||
set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
|
||||
endfunction(get_include_directories_asm)
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "clipboard.h"
|
||||
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
@@ -84,10 +85,10 @@ std::unique_ptr<wxImage> GetImageFromClipboard()
|
||||
{
|
||||
if( wxTheClipboard->IsSupported( wxDF_BITMAP ) )
|
||||
{
|
||||
wxImageDataObject data;
|
||||
wxBitmapDataObject data;
|
||||
if( wxTheClipboard->GetData( data ) )
|
||||
{
|
||||
image = std::make_unique<wxImage>( data.GetImage() );
|
||||
image = std::make_unique<wxImage>( data.GetBitmap().ConvertToImage() );
|
||||
}
|
||||
}
|
||||
else if( wxTheClipboard->IsSupported( wxDF_FILENAME ) )
|
||||
|
||||
@@ -161,7 +161,7 @@ bool DATABASE_CONNECTION::Connect()
|
||||
m_conn = std::make_unique<nanodbc::connection>( cs, m_timeout );
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
return false;
|
||||
@@ -188,7 +188,7 @@ bool DATABASE_CONNECTION::Disconnect()
|
||||
{
|
||||
m_conn->disconnect();
|
||||
}
|
||||
catch( boost::locale::conv::conversion_error& exc )
|
||||
catch( std::exception& exc )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "Disconnect() error \"%s\" occured." ), exc.what() );
|
||||
return false;
|
||||
@@ -250,7 +250,7 @@ bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while caching table info: %s" ), m_lastError );
|
||||
@@ -277,8 +277,9 @@ bool DATABASE_CONNECTION::getQuoteChar()
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "Quote char retrieved: %c" ), m_quoteChar );
|
||||
}
|
||||
catch( nanodbc::database_error& )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while querying quote char: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
@@ -401,14 +402,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
statement.prepare( *m_conn, query );
|
||||
statement.bind( 0, aWhere.second.c_str() );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while preparing statement for SelectOne: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -422,14 +423,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
{
|
||||
results = nanodbc::execute( statement );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while executing statement for SelectOne: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -480,7 +481,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while parsing results from SelectOne: %s" ),
|
||||
@@ -507,7 +508,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
{
|
||||
statement.prepare( query );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase,
|
||||
@@ -515,7 +516,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -526,7 +527,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
{
|
||||
results = nanodbc::execute( statement );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase,
|
||||
@@ -534,7 +535,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <build_version.h>
|
||||
#include <eda_base_frame.h>
|
||||
#include <wx/clipbrd.h>
|
||||
@@ -108,8 +107,20 @@ DIALOG_ABOUT::DIALOG_ABOUT( EDA_BASE_FRAME *aParent, ABOUT_APP_INFO& aAppInfo )
|
||||
m_titleName = aParent->GetAboutTitle();
|
||||
m_untranslatedTitleName = aParent->GetUntranslatedAboutTitle();
|
||||
m_staticTextAppTitle->SetLabel( m_titleName );
|
||||
|
||||
// On windows, display the number of GDI objects in use. Can be useful when some GDI objects
|
||||
// are not displayed because the max count of GDI objects (usually 10000) is reached
|
||||
// So displaying this number can help to diagnose strange display issues
|
||||
wxString extraInfo;
|
||||
|
||||
#if defined( _WIN32 )
|
||||
uint32_t gdi_count = GetGuiResources( GetCurrentProcess(), GR_GDIOBJECTS );
|
||||
extraInfo.Printf( _( "GDI objects in use %u" ), gdi_count );
|
||||
extraInfo.Prepend( wxT( "\n" ) );
|
||||
#endif
|
||||
|
||||
m_staticTextBuildVersion->SetLabel( wxS( "Version: " ) + m_info.GetBuildVersion() );
|
||||
m_staticTextLibVersion->SetLabel( m_info.GetLibVersion() );
|
||||
m_staticTextLibVersion->SetLabel( m_info.GetLibVersion() + extraInfo );
|
||||
|
||||
SetTitle( wxString::Format( _( "About %s" ), m_titleName ) );
|
||||
createNotebooks();
|
||||
|
||||
@@ -494,14 +494,17 @@ int DIALOG_SHIM::ShowModal()
|
||||
}
|
||||
|
||||
/*
|
||||
Quasi-Modal Mode Explained:
|
||||
QuasiModal Mode Explained:
|
||||
|
||||
The gtk calls in wxDialog::ShowModal() cause event routing problems if that
|
||||
modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up
|
||||
and mostly works but does not respond to the window decoration close button.
|
||||
There is no way to get around this without reversing the gtk calls temporarily.
|
||||
|
||||
Quasi-Modal mode is our own almost modal mode which disables only the parent
|
||||
There are also issues with the Scintilla text editor putting up autocomplete
|
||||
popups, which appear behind the dialog window if QuasiModal is not used.
|
||||
|
||||
QuasiModal mode is our own almost modal mode which disables only the parent
|
||||
of the DIALOG_SHIM, leaving other frames operable and while staying captured in the
|
||||
nested event loop. This avoids the gtk calls and leaves event routing pure
|
||||
and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <eda_item.h>
|
||||
#include <confirm.h>
|
||||
#include <bitmaps.h>
|
||||
#include <dialogs/panel_embedded_files.h>
|
||||
#include <embedded_files.h>
|
||||
@@ -161,9 +163,7 @@ void PANEL_EMBEDDED_FILES::resizeGrid()
|
||||
bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
|
||||
{
|
||||
m_files_grid->ClearGrid();
|
||||
|
||||
if( m_files_grid->GetNumberRows() > 0 )
|
||||
m_files_grid->DeleteRows( 0, m_files_grid->GetNumberRows() );
|
||||
m_files_grid->ClearRows();
|
||||
|
||||
int ii = 0;
|
||||
for( auto& [name, file] : m_localFiles->EmbeddedFileMap() )
|
||||
@@ -187,6 +187,51 @@ bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
|
||||
|
||||
bool PANEL_EMBEDDED_FILES::TransferDataFromWindow()
|
||||
{
|
||||
std::optional<bool> deleteReferences;
|
||||
|
||||
auto confirmDelete =
|
||||
[&]() -> bool
|
||||
{
|
||||
if( EDA_ITEM* parent = dynamic_cast<EDA_ITEM*>( m_files ) )
|
||||
{
|
||||
if( parent->Type() == PCB_T )
|
||||
{
|
||||
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some footprints.\n"
|
||||
"Delete from footprints as well?" ) );
|
||||
}
|
||||
else if( parent->Type() == SCHEMATIC_T )
|
||||
{
|
||||
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some symbols.\n"
|
||||
"Delete from symbols as well?" ) );
|
||||
}
|
||||
}
|
||||
|
||||
wxFAIL_MSG( wxT( "Unexpected embedded files owner" ) );
|
||||
return false;
|
||||
};
|
||||
|
||||
for( const auto& [name, file] : m_files->EmbeddedFileMap() )
|
||||
{
|
||||
if( !m_localFiles->HasFile( name ) )
|
||||
{
|
||||
m_files->RunOnNestedEmbeddedFiles(
|
||||
[&]( EMBEDDED_FILES* nested_files )
|
||||
{
|
||||
if( nested_files->HasFile( name ) )
|
||||
{
|
||||
if( !deleteReferences.has_value() )
|
||||
deleteReferences = confirmDelete();
|
||||
|
||||
if( deleteReferences.value() )
|
||||
nested_files->RemoveFile( name, true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if( deleteReferences.has_value() && deleteReferences.value() == false )
|
||||
break;
|
||||
}
|
||||
|
||||
m_files->ClearEmbeddedFiles();
|
||||
|
||||
std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;
|
||||
@@ -247,11 +292,6 @@ void PANEL_EMBEDDED_FILES::onFontEmbedClick( wxCommandEvent& event )
|
||||
font->GetFileName() ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
m_files_grid->AppendRows( 1 );
|
||||
int ii = m_files_grid->GetNumberRows() - 1;
|
||||
m_files_grid->SetCellValue( ii, 0, result->name );
|
||||
m_files_grid->SetCellValue( ii, 1, result->GetLink() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType )
|
||||
m_isNonUserClose = false;
|
||||
m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
|
||||
m_autoSaveRequired = false;
|
||||
m_autoSavePermissionError = false;
|
||||
m_mruPath = PATHS::GetDefaultUserProjectsPath();
|
||||
m_frameSize = defaultSize( aFrameType, this );
|
||||
m_displayIndex = -1;
|
||||
|
||||
@@ -322,6 +322,12 @@ void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& a
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawHoleWall( const VECTOR2D& aCenterPoint, double aRadius, double aWallWidth )
|
||||
{
|
||||
DrawCircle( aCenterPoint, aRadius + aWallWidth );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
{
|
||||
syncLineWidth();
|
||||
|
||||
@@ -67,6 +67,7 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||
SetLayerDepth( 0.0 );
|
||||
SetFlip( false, false );
|
||||
SetLineWidth( 1.0f );
|
||||
SetMinLineWidth( 1.0f );
|
||||
computeWorldScale();
|
||||
SetAxesEnabled( false );
|
||||
|
||||
|
||||
@@ -413,10 +413,13 @@ OPENGL_GAL::OPENGL_GAL( const KIGFX::VC_SETTINGS& aVcSettings, GAL_DISPLAY_OPTIO
|
||||
SetTarget( TARGET_NONCACHED );
|
||||
|
||||
// Avoid uninitialized variables:
|
||||
ufm_worldPixelSize = 1;
|
||||
ufm_screenPixelSize = 1;
|
||||
ufm_pixelSizeMultiplier = 1;
|
||||
ufm_antialiasingOffset = 1;
|
||||
ufm_worldPixelSize = -1;
|
||||
ufm_screenPixelSize = -1;
|
||||
ufm_pixelSizeMultiplier = -1;
|
||||
ufm_antialiasingOffset = -1;
|
||||
ufm_minLinePixelWidth = -1;
|
||||
ufm_fontTexture = -1;
|
||||
ufm_fontTextureWidth = -1;
|
||||
m_swapInterval = 0;
|
||||
}
|
||||
|
||||
@@ -672,14 +675,6 @@ void OPENGL_GAL::BeginDrawing()
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
}
|
||||
|
||||
// Set shader parameter
|
||||
GLint ufm_fontTexture = m_shader->AddParameter( "u_fontTexture" );
|
||||
GLint ufm_fontTextureWidth = m_shader->AddParameter( "u_fontTextureWidth" );
|
||||
ufm_worldPixelSize = m_shader->AddParameter( "u_worldPixelSize" );
|
||||
ufm_screenPixelSize = m_shader->AddParameter( "u_screenPixelSize" );
|
||||
ufm_pixelSizeMultiplier = m_shader->AddParameter( "u_pixelSizeMultiplier" );
|
||||
ufm_antialiasingOffset = m_shader->AddParameter( "u_antialiasingOffset" );
|
||||
|
||||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_fontTexture, (int) FONT_TEXTURE_UNIT );
|
||||
m_shader->SetParameter( ufm_fontTextureWidth, (int) font_image.width );
|
||||
@@ -700,6 +695,7 @@ void OPENGL_GAL::BeginDrawing()
|
||||
renderingOffset.x *= screenPixelSize.x;
|
||||
renderingOffset.y *= screenPixelSize.y;
|
||||
m_shader->SetParameter( ufm_antialiasingOffset, renderingOffset );
|
||||
m_shader->SetParameter( ufm_minLinePixelWidth, GetMinLineWidth() );
|
||||
m_shader->Deactivate();
|
||||
|
||||
// Something between BeginDrawing and EndDrawing seems to depend on
|
||||
@@ -716,6 +712,18 @@ void OPENGL_GAL::BeginDrawing()
|
||||
#endif /* KICAD_GAL_PROFILE */
|
||||
}
|
||||
|
||||
void OPENGL_GAL::SetMinLineWidth( float aLineWidth )
|
||||
{
|
||||
GAL::SetMinLineWidth( aLineWidth );
|
||||
|
||||
if( m_shader && ufm_minLinePixelWidth != -1 )
|
||||
{
|
||||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_minLinePixelWidth, aLineWidth );
|
||||
m_shader->Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::EndDrawing()
|
||||
{
|
||||
@@ -907,6 +915,25 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawHoleWall( const VECTOR2D& aCenterPoint, double aHoleRadius,
|
||||
double aWallWidth )
|
||||
{
|
||||
if( m_isFillEnabled )
|
||||
{
|
||||
m_currentManager->Color( m_fillColor.r, m_fillColor.g, m_fillColor.b, m_fillColor.a );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 1.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 2.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 3.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawCircle( const VECTOR2D& aCenterPoint, double aRadius, bool aReserve )
|
||||
{
|
||||
if( m_isFillEnabled )
|
||||
@@ -2662,6 +2689,10 @@ void OPENGL_GAL::blitCursor()
|
||||
glLineWidth( 1.0 );
|
||||
glColor4d( color.r, color.g, color.b, color.a );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPushMatrix();
|
||||
glTranslated( 0, 0, -0.5 );
|
||||
|
||||
glBegin( GL_LINES );
|
||||
glVertex2d( cursorCenter.x, cursorBegin.y );
|
||||
glVertex2d( cursorCenter.x, cursorEnd.y );
|
||||
@@ -2669,6 +2700,8 @@ void OPENGL_GAL::blitCursor()
|
||||
glVertex2d( cursorBegin.x, cursorCenter.y );
|
||||
glVertex2d( cursorEnd.x, cursorCenter.y );
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
@@ -2753,6 +2786,9 @@ void OPENGL_GAL::init()
|
||||
if( !m_shader->IsLinked() && !m_shader->Link() )
|
||||
throw std::runtime_error( "Cannot link the shaders!" );
|
||||
|
||||
// Set up shader parameters after linking
|
||||
setupShaderParameters();
|
||||
|
||||
// Check if video card supports textures big enough to fit the font atlas
|
||||
int maxTextureSize;
|
||||
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
|
||||
@@ -2781,6 +2817,19 @@ void OPENGL_GAL::init()
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::setupShaderParameters()
|
||||
{
|
||||
// Initialize shader uniform parameter locations
|
||||
ufm_fontTexture = m_shader->AddParameter( "u_fontTexture" );
|
||||
ufm_fontTextureWidth = m_shader->AddParameter( "u_fontTextureWidth" );
|
||||
ufm_worldPixelSize = m_shader->AddParameter( "u_worldPixelSize" );
|
||||
ufm_screenPixelSize = m_shader->AddParameter( "u_screenPixelSize" );
|
||||
ufm_pixelSizeMultiplier = m_shader->AddParameter( "u_pixelSizeMultiplier" );
|
||||
ufm_antialiasingOffset = m_shader->AddParameter( "u_antialiasingOffset" );
|
||||
ufm_minLinePixelWidth = m_shader->AddParameter( "u_minLinePixelWidth" );
|
||||
}
|
||||
|
||||
|
||||
// Callback functions for the tesselator. Compare Redbook Chapter 11.
|
||||
void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@ const float SHADER_FILLED_CIRCLE = 2.0;
|
||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||
const float SHADER_FONT = 4.0;
|
||||
const float SHADER_LINE_A = 5.0;
|
||||
const float SHADER_HOLE_WALL = 11.0;
|
||||
|
||||
varying vec4 v_shaderParams;
|
||||
varying vec2 v_circleCoords;
|
||||
@@ -124,6 +125,10 @@ void main()
|
||||
{
|
||||
strokedCircle( v_circleCoords, v_shaderParams[2], v_shaderParams[3] );
|
||||
}
|
||||
else if( mode == SHADER_HOLE_WALL )
|
||||
{
|
||||
strokedCircle( v_circleCoords, v_shaderParams[2], v_shaderParams[3] );
|
||||
}
|
||||
else if( mode == SHADER_FONT )
|
||||
{
|
||||
vec2 tex = v_shaderParams.yz;
|
||||
|
||||
@@ -36,6 +36,7 @@ const float SHADER_LINE_C = 7.0;
|
||||
const float SHADER_LINE_D = 8.0;
|
||||
const float SHADER_LINE_E = 9.0;
|
||||
const float SHADER_LINE_F = 10.0;
|
||||
const float SHADER_HOLE_WALL = 11.0;
|
||||
|
||||
// Minimum line width
|
||||
const float MIN_WIDTH = 1.0;
|
||||
@@ -72,8 +73,8 @@ void computeLineCoords( bool posture, vec2 vs, vec2 vp, vec2 texcoord, vec2 dir,
|
||||
vec2 s = sign( vec2( gl_ModelViewProjectionMatrix[0][0], gl_ModelViewProjectionMatrix[1][1] ) );
|
||||
|
||||
|
||||
if( pixelWidth < 1.0 )
|
||||
pixelWidth = 1.0;
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
|
||||
if ( pixelWidth > 1.0 || u_pixelSizeMultiplier > 1.0 )
|
||||
{
|
||||
@@ -126,8 +127,59 @@ void computeCircleCoords( float mode, float vertexIndex, float radius, float lin
|
||||
|
||||
vec4 adjust = vec4(-1, -1, 0, 0);
|
||||
|
||||
if( pixelWidth < 1.0 )
|
||||
pixelWidth = 1.0;
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
|
||||
if( vertexIndex == 1.0 )
|
||||
{
|
||||
v_circleCoords = vec2( -sqrt( 3.0 ), -1.0 );
|
||||
delta = vec4( -pixelR * sqrt(3.0), -pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 2.0 )
|
||||
{
|
||||
v_circleCoords = vec2( sqrt( 3.0 ), -1.0 );
|
||||
delta = vec4( pixelR * sqrt( 3.0 ), -pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 3.0 )
|
||||
{
|
||||
v_circleCoords = vec2( 0.0, 2.0 );
|
||||
delta = vec4( 0, 2 * pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 4.0 )
|
||||
{
|
||||
v_circleCoords = vec2( -sqrt( 3.0 ), 0.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 5.0 )
|
||||
{
|
||||
v_circleCoords = vec2( sqrt( 3.0 ), 0.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 6.0 )
|
||||
{
|
||||
v_circleCoords = vec2( 0.0, 2.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
v_shaderParams[2] = pixelR;
|
||||
v_shaderParams[3] = pixelWidth;
|
||||
|
||||
delta.x *= u_screenPixelSize.x;
|
||||
delta.y *= u_screenPixelSize.y;
|
||||
|
||||
gl_Position = center + delta + adjust;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
||||
void computeHoleWallCoords( float vertexIndex, float radius, float lineWidth )
|
||||
{
|
||||
vec4 delta;
|
||||
vec4 center = roundv( gl_ModelViewProjectionMatrix * gl_Vertex + vec4(1, 1, 0, 0), u_screenPixelSize );
|
||||
float pixelWidth = roundr( lineWidth / u_worldPixelSize, 1.0 );
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
float pixelR = roundr( radius / u_worldPixelSize, 1.0 ) + pixelWidth;
|
||||
vec4 adjust = vec4(-1, -1, 0, 0);
|
||||
|
||||
if( vertexIndex == 1.0 )
|
||||
{
|
||||
@@ -195,6 +247,8 @@ void main()
|
||||
computeLineCoords( posture, vs, vp, vec2( -1, 1 ), vec2( -1, 0 ), lineWidth, true );
|
||||
else if( mode == SHADER_LINE_F )
|
||||
computeLineCoords( posture, -vs, vp, vec2( 1, 1 ), vec2( -1, 0 ), lineWidth, false );
|
||||
else if( mode == SHADER_HOLE_WALL )
|
||||
computeHoleWallCoords( v_shaderParams.y, v_shaderParams.z, v_shaderParams.w );
|
||||
else if( mode == SHADER_FILLED_CIRCLE || mode == SHADER_STROKED_CIRCLE)
|
||||
computeCircleCoords( mode, v_shaderParams.y, v_shaderParams.z, v_shaderParams.w );
|
||||
else
|
||||
|
||||
@@ -40,19 +40,11 @@ HTTP_LIB_CONNECTION::HTTP_LIB_CONNECTION( const HTTP_LIB_SOURCE& aSource, bool a
|
||||
m_source = aSource;
|
||||
|
||||
if( aTestConnectionNow )
|
||||
{
|
||||
ValidateHTTPLibraryEndpoints();
|
||||
}
|
||||
validateHttpLibraryEndpoints();
|
||||
}
|
||||
|
||||
|
||||
HTTP_LIB_CONNECTION::~HTTP_LIB_CONNECTION()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
bool HTTP_LIB_CONNECTION::validateHttpLibraryEndpoints()
|
||||
{
|
||||
m_endpointValid = false;
|
||||
std::string res = "";
|
||||
@@ -78,11 +70,8 @@ bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
nlohmann::json response = nlohmann::json::parse( res );
|
||||
|
||||
// Check that the endpoints exist, if not fail.
|
||||
if( !response.at( http_endpoint_categories ).empty()
|
||||
&& !response.at( http_endpoint_parts ).empty() )
|
||||
{
|
||||
if( !response.at( "categories" ).empty() && !response.at( "parts" ).empty() )
|
||||
m_endpointValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
@@ -90,29 +79,19 @@ bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "ValidateHTTPLibraryEndpoints: Exception occurred while testing the API "
|
||||
"connection: %s" ),
|
||||
wxLogTrace( traceHTTPLib, wxT( "validateHttpLibraryEndpoints: Exception while testing API connection: %s" ),
|
||||
m_lastError );
|
||||
|
||||
m_endpointValid = false;
|
||||
}
|
||||
|
||||
if( m_endpointValid )
|
||||
{
|
||||
syncCategories();
|
||||
}
|
||||
|
||||
return m_endpointValid;
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::IsValidEndpoint() const
|
||||
{
|
||||
return m_endpointValid;
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
{
|
||||
if( !IsValidEndpoint() )
|
||||
@@ -124,7 +103,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
std::string res = "";
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
curl->SetURL( m_source.root_url + http_endpoint_categories + ".json" );
|
||||
curl->SetURL( m_source.root_url + "categories.json" );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -133,9 +112,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
res = curl->GetBuffer();
|
||||
|
||||
if( !checkServerResponse( curl ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nlohmann::json response = nlohmann::json::parse( res );
|
||||
|
||||
@@ -162,9 +139,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "syncCategories: Exception occurred while syncing categories: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "syncCategories: Exception while syncing categories: %s" ), m_lastError );
|
||||
|
||||
m_categories.clear();
|
||||
|
||||
@@ -187,8 +162,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
if( m_cachedParts.find( aPartID ) != m_cachedParts.end() )
|
||||
{
|
||||
// check if it's outdated, if so re-fetch
|
||||
if( std::difftime( std::time( nullptr ), m_cachedParts[aPartID].lastCached )
|
||||
< m_source.timeout_parts )
|
||||
if( std::difftime( std::time( nullptr ), m_cachedParts[aPartID].lastCached ) < m_source.timeout_parts )
|
||||
{
|
||||
aFetchedPart = m_cachedParts[aPartID];
|
||||
return true;
|
||||
@@ -198,7 +172,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
std::string res = "";
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
std::string url = m_source.root_url + fmt::format( "{}/{}.json", http_endpoint_parts, aPartID );
|
||||
std::string url = m_source.root_url + fmt::format( "parts/{}.json", aPartID );
|
||||
curl->SetURL( url );
|
||||
|
||||
try
|
||||
@@ -208,9 +182,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
res = curl->GetBuffer();
|
||||
|
||||
if( !checkServerResponse( curl ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nlohmann::ordered_json response = nlohmann::ordered_json::parse( res );
|
||||
std::string key = "";
|
||||
@@ -225,13 +197,9 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
|
||||
// API might not want to return an optional name.
|
||||
if( response.contains( "name" ) )
|
||||
{
|
||||
aFetchedPart.name = response.at( "name" );
|
||||
}
|
||||
else
|
||||
{
|
||||
aFetchedPart.name = aFetchedPart.id;
|
||||
}
|
||||
|
||||
aFetchedPart.symbolIdStr = response.at( "symbolIdStr" );
|
||||
|
||||
@@ -285,18 +253,36 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
}
|
||||
|
||||
// Add field to fields list
|
||||
aFetchedPart.fields.push_back(
|
||||
std::make_pair( key, std::make_tuple( value, visible ) ) );
|
||||
aFetchedPart.fields.push_back( std::make_pair( key, std::make_tuple( value, visible ) ) );
|
||||
}
|
||||
|
||||
if( response.contains( "description" ) )
|
||||
aFetchedPart.desc = response.at( "description" );
|
||||
|
||||
if( response.contains( "keywords" ) )
|
||||
aFetchedPart.keywords = response.at( "keywords" );
|
||||
|
||||
if( response.contains( "footprint_filters" ) )
|
||||
{
|
||||
nlohmann::json filters_json = response.at( "footprint_filters" );
|
||||
|
||||
if( filters_json.is_array() )
|
||||
{
|
||||
for( const auto& val : filters_json )
|
||||
aFetchedPart.fp_filters.push_back( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
aFetchedPart.fp_filters.push_back( filters_json );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "SelectOne: Exception occurred while retrieving part from REST API: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "SelectOne: Exception while fetching part: %s" ), m_lastError );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -307,8 +293,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
std::vector<HTTP_LIB_PART>& aParts )
|
||||
bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory, std::vector<HTTP_LIB_PART>& aParts )
|
||||
{
|
||||
if( !IsValidEndpoint() )
|
||||
{
|
||||
@@ -320,8 +305,7 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
|
||||
curl->SetURL( m_source.root_url
|
||||
+ fmt::format( "{}/category/{}.json", http_endpoint_parts, aCategory.id ) );
|
||||
curl->SetURL( m_source.root_url + fmt::format( "parts/category/{}.json", aCategory.id ) );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -341,19 +325,15 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
if( item.contains( "description" ) )
|
||||
{
|
||||
// At this point we don't display anything so just set it to false
|
||||
part.fields.push_back( std::make_pair(
|
||||
"description", std::make_tuple( item.at( "description" ), false ) ) );
|
||||
part.fields.push_back( std::make_pair( "description",
|
||||
std::make_tuple( item.at( "description" ), false ) ) );
|
||||
}
|
||||
|
||||
// API might not want to return an optional name.
|
||||
if( item.contains( "name" ) )
|
||||
{
|
||||
part.name = item.at( "name" );
|
||||
}
|
||||
else
|
||||
{
|
||||
part.name = part.id;
|
||||
}
|
||||
|
||||
// add to cache
|
||||
m_cache[part.name] = std::make_tuple( part.id, aCategory.id );
|
||||
@@ -363,11 +343,10 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib, wxT( "Exception occurred while syncing parts from REST API: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "Exception occurred while syncing parts: %s" ), m_lastError );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -379,6 +358,7 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
bool HTTP_LIB_CONNECTION::checkServerResponse( std::unique_ptr<KICAD_CURL_EASY>& aCurl )
|
||||
{
|
||||
int statusCode = aCurl->GetResponseStatusCode();
|
||||
|
||||
if( statusCode != 200 )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "API responded with error code: %s" ) + "\n",
|
||||
|
||||
@@ -35,10 +35,9 @@ const int httplibSchemaVersion = 1;
|
||||
HTTP_LIB_SETTINGS::HTTP_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, httplibSchemaVersion )
|
||||
{
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.type", &sourceType, "" ) );
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.type", &m_sourceType, "" ) );
|
||||
|
||||
m_params.emplace_back(
|
||||
new PARAM<std::string>( "source.api_version", &m_Source.api_version, "" ) );
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.api_version", &m_Source.api_version, "" ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.root_url", &m_Source.root_url, "" ) );
|
||||
|
||||
@@ -46,8 +45,7 @@ HTTP_LIB_SETTINGS::HTTP_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_parts_seconds", &m_Source.timeout_parts, 30 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_categories_seconds",
|
||||
&m_Source.timeout_categories, 600 ) );
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_categories_seconds", &m_Source.timeout_categories, 600 ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ JOB_EXPORT_PCB_ODB::JOB_EXPORT_PCB_ODB() :
|
||||
m_filename(),
|
||||
m_drawingSheet(),
|
||||
m_units( ODB_UNITS::MM ),
|
||||
m_precision( 2 ),
|
||||
m_precision( 4 ),
|
||||
m_compressionMode( ODB_COMPRESSION::ZIP )
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
|
||||
|
||||
@@ -85,6 +85,7 @@ JOB_PCB_RENDER::JOB_PCB_RENDER() :
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<FORMAT>( "format", &m_format, m_format ) );
|
||||
m_params.emplace_back( new JOB_PARAM<std::string>( "preset", &m_appearancePreset, m_appearancePreset ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "use_board_stackup_colors", &m_useBoardStackupColors, m_useBoardStackupColors ) );
|
||||
m_params.emplace_back( new JOB_PARAM<QUALITY>( "quality", &m_quality, m_quality ) );
|
||||
m_params.emplace_back( new JOB_PARAM<BG_STYLE>( "bg_style", &m_bgStyle, m_bgStyle ) );
|
||||
m_params.emplace_back( new JOB_PARAM<SIDE>( "side", &m_side, m_side ) );
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
std::string m_appearancePreset;
|
||||
bool m_useBoardStackupColors = true;
|
||||
SIDE m_side = SIDE::TOP;
|
||||
double m_zoom = 1.0;
|
||||
bool m_perspective = false;
|
||||
|
||||
@@ -39,7 +39,7 @@ JOB_RC::JOB_RC( const std::string& aType ) :
|
||||
m_units( JOB_RC::UNITS::MM ),
|
||||
m_severity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ),
|
||||
m_format( OUTPUT_FORMAT::REPORT ),
|
||||
m_exitCodeViolations( false )
|
||||
m_exitCodeViolations( true ) // this ensures GUI jobs default to treat violations as job failure, cli will default false elsewhere
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<UNITS>( "units", &m_units, m_units ) );
|
||||
m_params.emplace_back( new JOB_PARAM<int>( "severity", &m_severity, m_severity ) );
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <wx/zipstrm.h>
|
||||
#include <gestfich.h>
|
||||
#include <common.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
JOBS_OUTPUT_ARCHIVE::JOBS_OUTPUT_ARCHIVE() :
|
||||
JOBS_OUTPUT_HANDLER(),
|
||||
@@ -52,6 +53,8 @@ bool JOBS_OUTPUT_ARCHIVE::HandleOutputs( const wxString& baseTempPath, PROJECT*
|
||||
if( outputPath.StartsWith( "~" ) )
|
||||
outputPath.Replace( "~", wxGetHomeDir(), false );
|
||||
|
||||
outputPath = EnsureFileExtension( outputPath, FILEEXT::ArchiveFileExtension );
|
||||
|
||||
wxFFileOutputStream ostream( outputPath );
|
||||
|
||||
if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
|
||||
|
||||
@@ -134,29 +134,12 @@ LIB_TREE_NODE::LIB_TREE_NODE()
|
||||
|
||||
LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem, int aUnit )
|
||||
{
|
||||
static void* locale = nullptr;
|
||||
static wxString namePrefix;
|
||||
|
||||
// Fetching translations can take a surprising amount of time when loading libraries,
|
||||
// so only do it when necessary.
|
||||
if( Pgm().GetLocale() != locale )
|
||||
{
|
||||
namePrefix = _( "Unit" );
|
||||
locale = Pgm().GetLocale();
|
||||
}
|
||||
|
||||
m_Parent = aParent;
|
||||
m_Type = TYPE::UNIT;
|
||||
|
||||
m_Unit = aUnit;
|
||||
m_LibId = aParent->m_LibId;
|
||||
|
||||
m_Name = namePrefix + " " + aItem->GetUnitReference( aUnit );
|
||||
|
||||
if( aItem->HasUnitDisplayName( aUnit ) )
|
||||
m_Desc = aItem->GetUnitDisplayName( aUnit );
|
||||
else
|
||||
m_Desc = wxEmptyString;
|
||||
m_Name = aItem->GetUnitName( aUnit );
|
||||
|
||||
m_IntrinsicRank = -aUnit;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/dc.h>
|
||||
#include <wx/log.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
|
||||
@@ -308,6 +309,15 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
|
||||
const LIB_TREE_NODE* firstMatch = ShowResults();
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// Ensure the control is repainted with the updated data. Without an explicit
|
||||
// refresh the Gtk port can display stale rows until the user interacts with
|
||||
// them, leading to mismatched tree contents.
|
||||
m_widget->Refresh();
|
||||
m_widget->Update();
|
||||
wxYield();
|
||||
#endif
|
||||
|
||||
if( firstMatch )
|
||||
{
|
||||
wxDataViewItem item = ToItem( firstMatch );
|
||||
|
||||
@@ -1150,7 +1150,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:
|
||||
@@ -1283,9 +1285,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 )
|
||||
@@ -1301,8 +1302,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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ bool NETCLASS::ContainsNetclassWithName( const wxString& netclass ) const
|
||||
return std::any_of( m_constituents.begin(), m_constituents.end(),
|
||||
[&netclass]( const NETCLASS* nc )
|
||||
{
|
||||
return nc && nc->GetName() == netclass;
|
||||
return nc && nc->GetName().Matches( netclass );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,31 @@ enum class ELECTRICAL_PINTYPE
|
||||
|
||||
#define ELECTRICAL_PINTYPES_TOTAL ( static_cast<int>( ELECTRICAL_PINTYPE::PT_LAST_OPTION ) + 1 )
|
||||
|
||||
inline wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
// These strings are the canonical name of the electrictal type
|
||||
// Not translated, no space in name, only ASCII chars.
|
||||
// to use when the string name must be known and well defined
|
||||
// must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
|
||||
static const wxChar* msgPinElectricType[] =
|
||||
{
|
||||
wxT( "input" ),
|
||||
wxT( "output" ),
|
||||
wxT( "bidirectional" ),
|
||||
wxT( "tri_state" ),
|
||||
wxT( "passive" ),
|
||||
wxT( "free" ),
|
||||
wxT( "unspecified" ),
|
||||
wxT( "power_in" ),
|
||||
wxT( "power_out" ),
|
||||
wxT( "open_collector" ),
|
||||
wxT( "open_emitter" ),
|
||||
wxT( "no_connect" )
|
||||
};
|
||||
|
||||
return msgPinElectricType[static_cast<int>( aType )];
|
||||
}
|
||||
|
||||
enum class GRAPHIC_PINSHAPE
|
||||
{
|
||||
LINE,
|
||||
@@ -335,7 +335,86 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||
VECTOR2D rulerVec( end - origin );
|
||||
|
||||
wxArrayString cursorStrings = GetDimensionStrings();
|
||||
DrawTextNextToCursor( aView, end, -rulerVec, cursorStrings, drawingDropShadows );
|
||||
|
||||
// Choose a text quadrant that keeps the measurement text on-screen while avoiding
|
||||
// overlapping the ruler geometry. Start with the preferred direction (away from the
|
||||
// origin) and fall back to other quadrants as needed to keep the label visible.
|
||||
int prefX = rulerVec.y < 0.0 ? -1 : 1;
|
||||
int prefY = rulerVec.x < 0.0 ? 1 : -1;
|
||||
|
||||
double scale = gal->GetWorldScale();
|
||||
|
||||
TEXT_DIMS dims = GetConstantGlyphHeight( gal );
|
||||
KIFONT::FONT* font = KIFONT::FONT::GetFont();
|
||||
double width = 0.0;
|
||||
|
||||
for( const wxString& s : cursorStrings )
|
||||
{
|
||||
VECTOR2I extents = font->StringBoundaryLimits( s, dims.GlyphSize, dims.StrokeWidth, false, false,
|
||||
KIFONT::METRICS::Default() );
|
||||
width = std::max( width, (double) extents.x );
|
||||
}
|
||||
|
||||
double height = dims.LinePitch * cursorStrings.size();
|
||||
|
||||
// Convert to screen coordinates for visibility checks
|
||||
VECTOR2D cursorScreen = gal->ToScreen( end );
|
||||
VECTOR2I screenSize = gal->GetScreenPixelSize();
|
||||
double offsetX = 15.0; // same as DrawTextNextToCursor()
|
||||
double offsetY = dims.LinePitch * scale; // vertical spacing from cursor
|
||||
|
||||
auto fits = [&]( int sx, int sy )
|
||||
{
|
||||
double left, right, top, bottom;
|
||||
double xStart = cursorScreen.x + ( sx < 0 ? offsetX : -offsetX );
|
||||
|
||||
if( sx < 0 )
|
||||
{
|
||||
left = xStart;
|
||||
right = left + width * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = xStart;
|
||||
left = right - width * scale;
|
||||
}
|
||||
|
||||
if( sy > 0 ) // above cursor
|
||||
{
|
||||
bottom = cursorScreen.y - offsetY;
|
||||
top = bottom - height * scale;
|
||||
}
|
||||
else // below cursor
|
||||
{
|
||||
top = cursorScreen.y + offsetY;
|
||||
bottom = top + height * scale;
|
||||
}
|
||||
|
||||
return left >= 0 && right <= screenSize.x && top >= 0 && bottom <= screenSize.y;
|
||||
};
|
||||
|
||||
std::vector<VECTOR2I> candidates = { { prefX, prefY }, { -prefX, prefY },
|
||||
{ prefX, -prefY }, { -prefX, -prefY } };
|
||||
|
||||
VECTOR2I chosen = candidates[0];
|
||||
double bestDot = -1.0;
|
||||
|
||||
for( const VECTOR2I& c : candidates )
|
||||
{
|
||||
double dot = c.x * prefX + c.y * prefY;
|
||||
|
||||
if( dot >= 0 && fits( c.x, c.y ) )
|
||||
{
|
||||
if( dot > bestDot )
|
||||
{
|
||||
bestDot = dot;
|
||||
chosen = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2D quadrant( chosen.x, chosen.y );
|
||||
DrawTextNextToCursor( aView, end, quadrant, cursorStrings, drawingDropShadows );
|
||||
|
||||
// basic tick size
|
||||
double minorTickLen = 5.0 / gal->GetWorldScale();
|
||||
|
||||
@@ -25,10 +25,15 @@
|
||||
#include <properties/property.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <utility>
|
||||
#include <wx/wx.h>
|
||||
|
||||
static wxString EMPTY_STRING( wxEmptyString );
|
||||
|
||||
// Global to prevent simultaneous multi-threaded static initialization
|
||||
static const std::vector<PROPERTY_BASE*> EMPTY_PROP_LIST;
|
||||
static const std::map<PROPERTY_BASE*, int> EMPTY_PROP_DISPLAY_ORDER;
|
||||
std::vector<wxString> EMPTY_GROUP_DISPLAY_ORDER;
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
|
||||
@@ -38,13 +43,6 @@ void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
|
||||
}
|
||||
|
||||
|
||||
const wxString& PROPERTY_MANAGER::ResolveType( TYPE_ID aType ) const
|
||||
{
|
||||
auto it = m_classNames.find( aType );
|
||||
return it != m_classNames.end() ? it->second : EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aProperty ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
@@ -67,31 +65,29 @@ PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aPr
|
||||
}
|
||||
|
||||
|
||||
const PROPERTY_LIST& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const
|
||||
const std::vector<PROPERTY_BASE*>& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const PROPERTY_LIST empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_PROP_LIST;
|
||||
|
||||
return it->second.m_allProperties;
|
||||
}
|
||||
|
||||
|
||||
const PROPERTY_DISPLAY_ORDER& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const
|
||||
const std::map<PROPERTY_BASE*, int>& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const PROPERTY_DISPLAY_ORDER empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_PROP_DISPLAY_ORDER;
|
||||
|
||||
return it->second.m_displayOrder;
|
||||
}
|
||||
@@ -102,11 +98,10 @@ const std::vector<wxString>& PROPERTY_MANAGER::GetGroupDisplayOrder( TYPE_ID aTy
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const std::vector<wxString> empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_GROUP_DISPLAY_ORDER;
|
||||
|
||||
return it->second.m_groupDisplayOrder;
|
||||
}
|
||||
@@ -122,7 +117,7 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
|
||||
if( classDesc == m_classes.end() )
|
||||
return aSource;
|
||||
|
||||
auto& converters = classDesc->second.m_typeCasts;
|
||||
const std::map<TYPE_ID, std::unique_ptr<TYPE_CAST_BASE>>& converters = classDesc->second.m_typeCasts;
|
||||
auto converter = converters.find( aTarget );
|
||||
|
||||
if( converter == converters.end() ) // explicit type cast not found
|
||||
@@ -135,8 +130,9 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wxString& aGroup )
|
||||
{
|
||||
const wxString& name = aProperty->Name();
|
||||
TYPE_ID hash = aProperty->OwnerHash();
|
||||
CLASS_DESC& classDesc = getClass( hash );
|
||||
TYPE_ID hash = aProperty->OwnerHash();
|
||||
CLASS_DESC& classDesc = getClass( hash );
|
||||
|
||||
classDesc.m_ownProperties.emplace( name, aProperty );
|
||||
classDesc.m_ownDisplayOrder.emplace_back( aProperty );
|
||||
|
||||
@@ -153,8 +149,8 @@ PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wx
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName,
|
||||
PROPERTY_BASE* aNew, const wxString& aGroup )
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE* aNew,
|
||||
const wxString& aGroup )
|
||||
{
|
||||
CLASS_DESC& classDesc = getClass( aNew->OwnerHash() );
|
||||
classDesc.m_replaced.insert( std::make_pair( aBase, aName ) );
|
||||
@@ -164,31 +160,30 @@ PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString&
|
||||
|
||||
void PROPERTY_MANAGER::AddTypeCast( TYPE_CAST_BASE* aCast )
|
||||
{
|
||||
TYPE_ID derivedHash = aCast->DerivedHash();
|
||||
TYPE_ID derivedHash = aCast->DerivedHash();
|
||||
CLASS_DESC& classDesc = getClass( aCast->BaseHash() );
|
||||
auto& typeCasts = classDesc.m_typeCasts;
|
||||
wxASSERT_MSG( typeCasts.count( derivedHash ) == 0, "Such converter already exists" );
|
||||
typeCasts.emplace( derivedHash, aCast );
|
||||
|
||||
wxASSERT_MSG( classDesc.m_typeCasts.count( derivedHash ) == 0, wxT( "Such converter already exists" ) );
|
||||
classDesc.m_typeCasts.emplace( derivedHash, aCast );
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::InheritsAfter( TYPE_ID aDerived, TYPE_ID aBase )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot inherit from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot inherit from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
CLASS_DESC& base = getClass( aBase );
|
||||
derived.m_bases.push_back( base );
|
||||
derived.m_bases.push_back( getClass( aBase ) );
|
||||
m_dirty = true;
|
||||
|
||||
wxASSERT_MSG( derived.m_bases.size() == 1 || derived.m_typeCasts.count( aBase ) == 1,
|
||||
"You need to add a TYPE_CAST for classes inheriting from multiple bases" );
|
||||
wxT( "You need to add a TYPE_CAST for classes inheriting from multiple bases" ) );
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot mask from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot mask from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_maskedBaseProperties.insert( std::make_pair( aBase, aName ) );
|
||||
@@ -196,11 +191,10 @@ void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aN
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
const wxString& aName,
|
||||
void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
|
||||
std::function<bool( INSPECTABLE* )> aFunc )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_availabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
|
||||
@@ -208,11 +202,10 @@ void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
const wxString& aName,
|
||||
void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
|
||||
std::function<bool( INSPECTABLE* )> aFunc )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_writeabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
|
||||
@@ -220,16 +213,14 @@ void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
INSPECTABLE* aItem )
|
||||
bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
|
||||
{
|
||||
if( !aProp->Available( aItem ) )
|
||||
return false;
|
||||
|
||||
CLASS_DESC& derived = getClass( aItemClass );
|
||||
|
||||
auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(),
|
||||
aProp->Name() ) );
|
||||
auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
|
||||
|
||||
if( it != derived.m_availabilityOverrides.end() )
|
||||
return it->second( aItem );
|
||||
@@ -238,16 +229,14 @@ bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
INSPECTABLE* aItem )
|
||||
bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
|
||||
{
|
||||
if( !aProp->Writeable( aItem ) )
|
||||
return false;
|
||||
|
||||
CLASS_DESC& derived = getClass( aItemClass );
|
||||
|
||||
auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(),
|
||||
aProp->Name() ) );
|
||||
auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
|
||||
|
||||
if( it != derived.m_writeabilityOverrides.end() )
|
||||
return it->second( aItem );
|
||||
@@ -265,7 +254,7 @@ bool PROPERTY_MANAGER::IsOfType( TYPE_ID aDerived, TYPE_ID aBase ) const
|
||||
wxCHECK( derived != m_classes.end(), false ); // missing class description
|
||||
|
||||
// traverse the hierarchy seeking for the base class
|
||||
for( auto& base : derived->second.m_bases )
|
||||
for( const std::reference_wrapper<CLASS_DESC>& base : derived->second.m_bases )
|
||||
{
|
||||
if( IsOfType( base.get().m_id, aBase ) )
|
||||
return true;
|
||||
@@ -297,8 +286,8 @@ PROPERTY_MANAGER::CLASS_DESC& PROPERTY_MANAGER::getClass( TYPE_ID aTypeId )
|
||||
|
||||
void PROPERTY_MANAGER::CLASS_DESC::rebuild()
|
||||
{
|
||||
PROPERTY_SET replaced;
|
||||
PROPERTY_SET masked;
|
||||
std::set<std::pair<size_t, wxString>> replaced;
|
||||
std::set<std::pair<size_t, wxString>> masked;
|
||||
m_allProperties.clear();
|
||||
collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked );
|
||||
|
||||
@@ -338,10 +327,10 @@ void PROPERTY_MANAGER::CLASS_DESC::rebuild()
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
PROPERTY_SET& aReplaced,
|
||||
PROPERTY_DISPLAY_ORDER& aDisplayOrder,
|
||||
PROPERTY_SET& aMasked ) const
|
||||
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( std::vector<PROPERTY_BASE*>& aResult,
|
||||
std::set<std::pair<size_t, wxString>>& aReplaced,
|
||||
std::map<PROPERTY_BASE*, int>& aDisplayOrder,
|
||||
std::set<std::pair<size_t, wxString>>& aMasked ) const
|
||||
{
|
||||
for( const std::pair<size_t, wxString>& replacedEntry : m_replaced )
|
||||
aReplaced.emplace( replacedEntry );
|
||||
@@ -371,8 +360,8 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
|
||||
for( PROPERTY_BASE* property : m_ownDisplayOrder )
|
||||
{
|
||||
PROPERTY_SET::key_type propertyKey = std::make_pair( property->OwnerHash(),
|
||||
property->Name() );
|
||||
std::set<std::pair<size_t, wxString>>::key_type propertyKey = std::make_pair( property->OwnerHash(),
|
||||
property->Name() );
|
||||
// Do not store replaced properties
|
||||
if( aReplaced.count( propertyKey ) )
|
||||
continue;
|
||||
@@ -386,28 +375,8 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
}
|
||||
|
||||
// Iterate backwards so that replaced properties appear before base properties
|
||||
for( auto it = m_bases.rbegin(); it != m_bases.rend(); ++it )
|
||||
it->get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked );
|
||||
}
|
||||
|
||||
|
||||
std::vector<TYPE_ID> PROPERTY_MANAGER::GetMatchingClasses( PROPERTY_BASE* aProperty )
|
||||
{
|
||||
std::vector<TYPE_ID> ids;
|
||||
|
||||
/*
|
||||
for( auto& cls : m_classes )
|
||||
{
|
||||
CLASS_INFO info;
|
||||
|
||||
for( auto prop : cls.second.m_allProperties )
|
||||
info.properties.push_back(prop);
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
return ids;
|
||||
for( std::reference_wrapper<CLASS_DESC> base : std::ranges::reverse_view( m_bases ) )
|
||||
base.get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked );
|
||||
}
|
||||
|
||||
|
||||
@@ -458,7 +427,7 @@ void PROPERTY_MANAGER::PropertyChanged( INSPECTABLE* aObject, PROPERTY_BASE* aPr
|
||||
PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
|
||||
{
|
||||
wxCHECK2_MSG( PROPERTY_MANAGER::Instance().m_managedCommit == nullptr,
|
||||
return, "Can't have more than one managed commit at a time!" );
|
||||
return, wxT( "Can't have more than one managed commit at a time!" ) );
|
||||
|
||||
PROPERTY_MANAGER::Instance().m_managedCommit = aCommit;
|
||||
}
|
||||
@@ -467,7 +436,7 @@ PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
|
||||
PROPERTY_COMMIT_HANDLER::~PROPERTY_COMMIT_HANDLER()
|
||||
{
|
||||
wxASSERT_MSG( PROPERTY_MANAGER::Instance().m_managedCommit != nullptr,
|
||||
"Something went wrong: m_managedCommit already null!" );
|
||||
wxT( "Something went wrong: m_managedCommit already null!" ) );
|
||||
|
||||
PROPERTY_MANAGER::Instance().m_managedCommit = nullptr;
|
||||
}
|
||||
|
||||
+11
-21
@@ -65,12 +65,6 @@ REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText, SEVERITY aSeveri
|
||||
}
|
||||
|
||||
|
||||
bool WX_TEXT_CTRL_REPORTER::HasMessage() const
|
||||
{
|
||||
return !m_textCtrl->IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_STRING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
@@ -93,12 +87,6 @@ void WX_STRING_REPORTER::Clear()
|
||||
}
|
||||
|
||||
|
||||
bool WX_STRING_REPORTER::HasMessage() const
|
||||
{
|
||||
return !m_string.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
return REPORTER::Report( aText, aSeverity );
|
||||
@@ -211,6 +199,17 @@ REPORTER& WXLOG_REPORTER::GetInstance()
|
||||
}
|
||||
|
||||
|
||||
REPORTER& REDIRECT_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
|
||||
if( m_redirectTarget )
|
||||
m_redirectTarget->Report( aText, aSeverity );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
@@ -220,12 +219,3 @@ REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool STATUSBAR_REPORTER::HasMessage() const
|
||||
{
|
||||
if( m_statusBar )
|
||||
return !m_statusBar->GetStatusText( m_position ).IsEmpty();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -182,35 +182,38 @@ void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin )
|
||||
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
return computeNearest( aPoint, GetGrid() );
|
||||
return computeNearest( aPoint, GetGrid(), GetOrigin() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint, const VECTOR2D& aGrid,
|
||||
const VECTOR2D& aOffset ) const
|
||||
{
|
||||
return computeNearest( aPoint, aGrid );
|
||||
return computeNearest( aPoint, aGrid, aOffset );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::computeNearest( const VECTOR2I& aPoint, const VECTOR2I& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::computeNearest( const VECTOR2I& aPoint, const VECTOR2I& aGrid,
|
||||
const VECTOR2I& aOffset ) const
|
||||
{
|
||||
return VECTOR2I( KiROUND( static_cast<double>( aPoint.x ) / aGrid.x ) * aGrid.x,
|
||||
KiROUND( static_cast<double>( aPoint.y ) / aGrid.y ) * aGrid.y );
|
||||
return VECTOR2I( KiROUND( (double) ( aPoint.x - aOffset.x ) / aGrid.x ) * aGrid.x + aOffset.x,
|
||||
KiROUND( (double) ( aPoint.y - aOffset.y ) / aGrid.y ) * aGrid.y + aOffset.y );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
return Align( aPoint, GetGrid() );
|
||||
return Align( aPoint, GetGrid(), GetOrigin() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid,
|
||||
const VECTOR2D& aOffset ) const
|
||||
{
|
||||
if( !canUseGrid() )
|
||||
return aPoint;
|
||||
|
||||
VECTOR2I nearest = AlignGrid( aPoint, aGrid );
|
||||
VECTOR2I nearest = AlignGrid( aPoint, aGrid, aOffset );
|
||||
|
||||
if( !m_auxAxis )
|
||||
return nearest;
|
||||
|
||||
+79
-56
@@ -362,18 +362,26 @@ bool FIELD_VALIDATOR::Validate( wxWindow* aParent )
|
||||
}
|
||||
|
||||
|
||||
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
|
||||
wxString GetFieldValidationErrorMessage( int aFieldId, const wxString& aValue )
|
||||
{
|
||||
wxString msg;
|
||||
FIELD_VALIDATOR validator( aFieldId );
|
||||
wxString msg;
|
||||
|
||||
if( HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
|
||||
msg.Printf( _( "The value of the field cannot be empty." ) );
|
||||
if( validator.HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
|
||||
{
|
||||
switch( aFieldId )
|
||||
{
|
||||
case SHEETNAME_V: msg = _( "A sheet must have a name." ); break;
|
||||
case SHEETFILENAME_V: msg = _( "A sheet must have a file specified." ); break;
|
||||
default: msg = _( "The value of the field cannot be empty." ); break;
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
@@ -390,68 +398,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 REFERENCE_FIELD:
|
||||
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case VALUE_FIELD:
|
||||
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case FOOTPRINT_FIELD:
|
||||
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case DATASHEET_FIELD:
|
||||
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETNAME_V:
|
||||
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETFILENAME_V:
|
||||
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 == REFERENCE_FIELD && aValue.Contains( wxT( "${" ) ) )
|
||||
{
|
||||
case REFERENCE_FIELD:
|
||||
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case VALUE_FIELD:
|
||||
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case FOOTPRINT_FIELD:
|
||||
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case DATASHEET_FIELD:
|
||||
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETNAME_V:
|
||||
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETFILENAME_V:
|
||||
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 == REFERENCE_FIELD && aValue.Contains( wxT( "${" ) ) )
|
||||
{
|
||||
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
|
||||
}
|
||||
else if( m_fieldId == REFERENCE_FIELD && 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 == REFERENCE_FIELD && 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 )
|
||||
|
||||
@@ -326,7 +326,9 @@ void COLOR_SWATCH::GetNewSwatchColor()
|
||||
|
||||
void COLOR_SWATCH::OnDarkModeToggle()
|
||||
{
|
||||
m_checkerboardBg = m_parent->GetBackgroundColour();
|
||||
wxWindow* parent = GetParent();
|
||||
m_checkerboardBg = parent ? parent->GetBackgroundColour() : wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
|
||||
|
||||
m_swatch->SetBitmap( makeBitmap() );
|
||||
if( m_swatch )
|
||||
m_swatch->SetBitmap( makeBitmap() );
|
||||
}
|
||||
|
||||
@@ -443,7 +443,8 @@ public:
|
||||
TEXT_BUTTON_FILE_BROWSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg, WX_GRID* aGrid,
|
||||
wxString* aCurrentDir, const wxString& aFileFilter = wxEmptyString,
|
||||
bool aNormalize = false,
|
||||
const wxString& aNormalizeBasePath = wxEmptyString ) :
|
||||
const wxString& aNormalizeBasePath = wxEmptyString,
|
||||
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
|
||||
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
|
||||
m_dlg( aParentDlg ),
|
||||
@@ -451,7 +452,8 @@ public:
|
||||
m_currentDir( aCurrentDir ),
|
||||
m_normalize( aNormalize ),
|
||||
m_normalizeBasePath( aNormalizeBasePath ),
|
||||
m_fileFilter( aFileFilter )
|
||||
m_fileFilter( aFileFilter ),
|
||||
m_embedCallback( std::move( aEmbedCallback ) )
|
||||
{
|
||||
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
|
||||
|
||||
@@ -463,7 +465,8 @@ public:
|
||||
wxString* aCurrentDir,
|
||||
std::function<wxString( WX_GRID* grid, int row )> aFileFilterFn,
|
||||
bool aNormalize = false,
|
||||
const wxString& aNormalizeBasePath = wxEmptyString ) :
|
||||
const wxString& aNormalizeBasePath = wxEmptyString,
|
||||
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
|
||||
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
|
||||
m_dlg( aParentDlg ),
|
||||
@@ -471,7 +474,8 @@ public:
|
||||
m_currentDir( aCurrentDir ),
|
||||
m_normalize( aNormalize ),
|
||||
m_normalizeBasePath( aNormalizeBasePath ),
|
||||
m_fileFilterFn( std::move( aFileFilterFn ) )
|
||||
m_fileFilterFn( std::move( aFileFilterFn ) ),
|
||||
m_embedCallback( std::move( aEmbedCallback ) )
|
||||
{
|
||||
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
|
||||
|
||||
@@ -502,16 +506,30 @@ protected:
|
||||
|
||||
if( !m_fileFilter.IsEmpty() )
|
||||
{
|
||||
FILEDLG_OPEN_EMBED_FILE customize( false );
|
||||
wxFileDialog dlg( m_dlg, _( "Select a File" ), fn.GetPath(), fn.GetFullName(),
|
||||
m_fileFilter, wxFD_FILE_MUST_EXIST | wxFD_OPEN );
|
||||
|
||||
if( m_embedCallback )
|
||||
dlg.SetCustomizeHook( customize );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
wxString filePath = dlg.GetPath();
|
||||
wxString lastPath = dlg.GetDirectory();
|
||||
wxString relPath = wxEmptyString;
|
||||
|
||||
if( m_normalize )
|
||||
if( m_embedCallback && customize.GetEmbed() )
|
||||
{
|
||||
relPath = m_embedCallback( filePath );
|
||||
|
||||
if( relPath.IsEmpty() )
|
||||
{
|
||||
m_dlg->CleanupAfterModalSubDialog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( m_normalize )
|
||||
{
|
||||
relPath = NormalizePath( filePath, &Pgm().GetLocalEnvVariables(),
|
||||
m_normalizeBasePath );
|
||||
@@ -573,6 +591,7 @@ protected:
|
||||
|
||||
wxString m_fileFilter;
|
||||
std::function<wxString( WX_GRID* aGrid, int aRow )> m_fileFilterFn;
|
||||
std::function<wxString( const wxString& )> m_embedCallback;
|
||||
};
|
||||
|
||||
|
||||
@@ -583,12 +602,13 @@ void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
|
||||
{
|
||||
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
|
||||
m_fileFilterFn, m_normalize,
|
||||
m_normalizeBasePath );
|
||||
m_normalizeBasePath, m_embedCallback );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
|
||||
m_fileFilter, m_normalize, m_normalizeBasePath );
|
||||
m_fileFilter, m_normalize, m_normalizeBasePath,
|
||||
m_embedCallback );
|
||||
}
|
||||
|
||||
WX_GRID::CellEditorSetMargins( Combo() );
|
||||
|
||||
@@ -122,17 +122,14 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
m_grid->CenterSplitter();
|
||||
|
||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PROPERTIES_PANEL::onCharHook ), nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ),
|
||||
nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ),
|
||||
nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ), nullptr, this );
|
||||
Connect( wxEVT_SHOW, wxShowEventHandler( PROPERTIES_PANEL::onShow ), nullptr, this );
|
||||
|
||||
Bind( wxEVT_PG_COL_END_DRAG,
|
||||
[&]( wxPropertyGridEvent& )
|
||||
{
|
||||
m_splitter_key_proportion =
|
||||
static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
|
||||
m_splitter_key_proportion = static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
|
||||
} );
|
||||
|
||||
Bind( wxEVT_SIZE,
|
||||
@@ -225,33 +222,27 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
|
||||
wxCHECK( !types.empty(), /* void */ ); // already guarded above, but Coverity doesn't know that
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
std::set<PROPERTY_BASE*> commonProps;
|
||||
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() );
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
std::set<PROPERTY_BASE*> commonProps;
|
||||
const std::vector<PROPERTY_BASE*>& allProperties = propMgr.GetProperties( *types.begin() );
|
||||
|
||||
copy( allProperties.begin(), allProperties.end(),
|
||||
inserter( commonProps, commonProps.begin() ) );
|
||||
copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) );
|
||||
|
||||
PROPERTY_DISPLAY_ORDER displayOrder = propMgr.GetDisplayOrder( *types.begin() );
|
||||
|
||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||
std::map<PROPERTY_BASE*, int> displayOrder = propMgr.GetDisplayOrder( *types.begin() );
|
||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||
|
||||
std::set<PROPERTY_BASE*> availableProps;
|
||||
|
||||
// Get all possible properties
|
||||
for( const TYPE_ID& type : types )
|
||||
{
|
||||
const PROPERTY_LIST& itemProps = propMgr.GetProperties( type );
|
||||
const std::vector<PROPERTY_BASE*>& itemProps = propMgr.GetProperties( type );
|
||||
const std::map<PROPERTY_BASE*, int>& itemDisplayOrder = propMgr.GetDisplayOrder( type );
|
||||
|
||||
const PROPERTY_DISPLAY_ORDER& itemDisplayOrder = propMgr.GetDisplayOrder( type );
|
||||
copy( itemDisplayOrder.begin(), itemDisplayOrder.end(), inserter( displayOrder, displayOrder.begin() ) );
|
||||
|
||||
copy( itemDisplayOrder.begin(), itemDisplayOrder.end(),
|
||||
inserter( displayOrder, displayOrder.begin() ) );
|
||||
|
||||
const std::vector<wxString>& itemGroups = propMgr.GetGroupDisplayOrder( type );
|
||||
|
||||
for( const wxString& group : itemGroups )
|
||||
for( const wxString& group : propMgr.GetGroupDisplayOrder( type ) )
|
||||
{
|
||||
if( !groups.count( group ) )
|
||||
{
|
||||
@@ -305,9 +296,10 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
if( !property )
|
||||
continue;
|
||||
|
||||
wxVariant commonVal;
|
||||
wxVariant commonVal;
|
||||
wxPGChoices choices;
|
||||
|
||||
extractValueAndWritability( aSelection, property, commonVal, writeable );
|
||||
extractValueAndWritability( aSelection, property, commonVal, writeable, choices );
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
|
||||
@@ -326,13 +318,17 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
for( PROPERTY_BASE* property : availableProps )
|
||||
{
|
||||
wxPGProperty* pgProp = createPGProperty( property );
|
||||
wxVariant commonVal;
|
||||
wxVariant commonVal;
|
||||
wxPGChoices choices;
|
||||
|
||||
if( !extractValueAndWritability( aSelection, property, commonVal, writeable ) )
|
||||
if( !extractValueAndWritability( aSelection, property, commonVal, writeable, choices ) )
|
||||
continue;
|
||||
|
||||
if( pgProp )
|
||||
{
|
||||
if( choices.GetCount() )
|
||||
pgProp->SetChoices( choices );
|
||||
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
m_displayed.push_back( property );
|
||||
@@ -403,13 +399,12 @@ bool PROPERTIES_PANEL::getItemValue( EDA_ITEM* aItem, PROPERTY_BASE* aProperty,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection,
|
||||
PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable )
|
||||
bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices )
|
||||
{
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
bool different = false;
|
||||
wxVariant commonVal;
|
||||
bool first = true;
|
||||
|
||||
aWritable = true;
|
||||
|
||||
@@ -421,6 +416,22 @@ bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection,
|
||||
if( aProperty->IsHiddenFromPropertiesManager() )
|
||||
return false;
|
||||
|
||||
wxPGChoices choices = aProperty->GetChoices( item );
|
||||
|
||||
if( first )
|
||||
{
|
||||
aChoices = choices;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxArrayString labels = choices.GetLabels();
|
||||
wxArrayInt values = choices.GetValuesForStrings( labels );
|
||||
|
||||
if( labels != aChoices.GetLabels() || values != aChoices.GetValuesForStrings( labels ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// If read-only for any of the selection, read-only for the whole selection.
|
||||
if( !propMgr.IsWriteableFor( TYPE_HASH( *item ), aProperty, item ) )
|
||||
aWritable = false;
|
||||
@@ -494,10 +505,15 @@ void PROPERTIES_PANEL::onCharHook( wxKeyEvent& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER
|
||||
|| aEvent.GetKeyCode() == WXK_DOWN || aEvent.GetKeyCode() == WXK_UP )
|
||||
{
|
||||
m_grid->CommitChangesFromEditor();
|
||||
/* don't skip this one; if we're not the last property we'll also go to the next row */
|
||||
|
||||
CallAfter( [this]()
|
||||
{
|
||||
m_grid->SelectProperty( m_grid->GetSelectedProperty(), true );
|
||||
} );
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
|
||||
@@ -102,7 +102,7 @@ protected:
|
||||
* @return true if the property is available for all the items in the selection
|
||||
*/
|
||||
bool extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable );
|
||||
wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices );
|
||||
|
||||
public:
|
||||
int m_SuppressGridChangeEvents;
|
||||
|
||||
@@ -230,7 +230,11 @@ void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
|
||||
const long long int conv =
|
||||
EDA_UNIT_UTILS::UI::ValueFromString( *m_iuScale, m_units, value, m_dataType );
|
||||
|
||||
SetValue( conv );
|
||||
CallAfter(
|
||||
[this, conv]
|
||||
{
|
||||
SetValue( conv );
|
||||
} );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ HANDLER_RESULT<ItemRequestStatus> API_HANDLER_SCH::handleCreateUpdateItemsIntern
|
||||
if( aCreate )
|
||||
{
|
||||
item->Serialize( newItem );
|
||||
commit->Add( item.release() );
|
||||
commit->Add( item.release(), screen );
|
||||
|
||||
if( !m_activeClients.count( aClientName ) )
|
||||
pushCurrentCommit( aClientName, _( "Added items via API" ) );
|
||||
@@ -266,7 +266,7 @@ HANDLER_RESULT<ItemRequestStatus> API_HANDLER_SCH::handleCreateUpdateItemsIntern
|
||||
{
|
||||
schItem->SwapData( static_cast<SCH_ITEM*>( item.get() ) );
|
||||
schItem->Serialize( newItem );
|
||||
commit->Modify( schItem );
|
||||
commit->Modify( schItem, screen );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1141,21 +1141,22 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
aSheet.Last()->GetFileName(), aItemList.size() );
|
||||
std::map<VECTOR2I, std::vector<SCH_ITEM*>> connection_map;
|
||||
|
||||
auto updatePin = [&]( SCH_PIN* aPin, SCH_CONNECTION* aConn )
|
||||
{
|
||||
aConn->SetType( CONNECTION_TYPE::NET );
|
||||
auto updatePin =
|
||||
[&]( SCH_PIN* aPin, SCH_CONNECTION* aConn )
|
||||
{
|
||||
aConn->SetType( CONNECTION_TYPE::NET );
|
||||
|
||||
// because calling the first time is not thread-safe
|
||||
wxString name = aPin->GetDefaultNetName( aSheet );
|
||||
aPin->ClearConnectedItems( aSheet );
|
||||
// because calling the first time is not thread-safe
|
||||
wxString name = aPin->GetDefaultNetName( aSheet );
|
||||
aPin->ClearConnectedItems( aSheet );
|
||||
|
||||
// power symbol pins need to be post-processed later
|
||||
if( aPin->IsGlobalPower() )
|
||||
{
|
||||
aConn->SetName( name );
|
||||
m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) );
|
||||
}
|
||||
};
|
||||
// power symbol pins need to be post-processed later
|
||||
if( aPin->IsGlobalPower() )
|
||||
{
|
||||
aConn->SetName( name );
|
||||
m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) );
|
||||
}
|
||||
};
|
||||
|
||||
for( SCH_ITEM* item : aItemList )
|
||||
{
|
||||
@@ -1227,17 +1228,41 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
|
||||
for( const VECTOR2I& point : points )
|
||||
connection_map[ point ].push_back( item );
|
||||
|
||||
/// Special case for labels that overlap wires
|
||||
/// While this is an ERC error as there is not an explicit junction,
|
||||
/// we want to enforce connectivity for all items under the label position.
|
||||
if( dynamic_cast<SCH_LABEL_BASE*>( item ) )
|
||||
{
|
||||
VECTOR2I point = item->GetPosition();
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
auto items = screen->Items().Overlapping( point );
|
||||
std::vector<SCH_ITEM*> overlapping_items;
|
||||
|
||||
std::copy_if( items.begin(), items.end(), std::back_inserter( overlapping_items ),
|
||||
[&]( SCH_ITEM* test_item )
|
||||
{
|
||||
return test_item->Type() == SCH_LINE_T
|
||||
&& test_item->HitTest( point, -1 );
|
||||
} );
|
||||
|
||||
// We need at least two connnectable lines that are not the label here
|
||||
// Otherwise, the label will be normally assigned to one or the other
|
||||
if( overlapping_items.size() < 2 ) continue;
|
||||
|
||||
for( SCH_ITEM* test_item : overlapping_items )
|
||||
connection_map[point].push_back( test_item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( const auto& it : connection_map )
|
||||
for( auto& [point, connection_vec] : connection_map )
|
||||
{
|
||||
std::vector<SCH_ITEM*> connection_vec = it.second;
|
||||
std::sort( connection_vec.begin(), connection_vec.end() );
|
||||
alg::remove_duplicates( connection_vec );
|
||||
|
||||
// Pre-scan to see if we have a bus at this location
|
||||
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
|
||||
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( point );
|
||||
|
||||
std::mutex update_mutex;
|
||||
|
||||
@@ -1264,7 +1289,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bus-to-bus entries are treated just like bus wires
|
||||
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
|
||||
{
|
||||
@@ -1274,7 +1298,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
|
||||
|
||||
if( it.first == bus_entry->GetPosition() )
|
||||
if( point == bus_entry->GetPosition() )
|
||||
bus_entry->m_connected_bus_items[0] = busLine;
|
||||
else
|
||||
bus_entry->m_connected_bus_items[1] = busLine;
|
||||
@@ -1285,7 +1309,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change junctions to be on bus junction layer if they are touching a bus
|
||||
else if( connected_item->Type() == SCH_JUNCTION_T )
|
||||
{
|
||||
@@ -1321,9 +1344,9 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
|
||||
if( connected_item->ConnectionPropagatesTo( test_item ) &&
|
||||
test_item->ConnectionPropagatesTo( connected_item ) &&
|
||||
bus_connection_ok )
|
||||
if( connected_item->ConnectionPropagatesTo( test_item )
|
||||
&& test_item->ConnectionPropagatesTo( connected_item )
|
||||
&& bus_connection_ok )
|
||||
{
|
||||
connected_item->AddConnectionTo( aSheet, test_item );
|
||||
}
|
||||
@@ -1339,7 +1362,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
if( !bus_entry->m_connected_bus_item )
|
||||
{
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
SCH_LINE* bus = screen->GetBus( it.first );
|
||||
SCH_LINE* bus = screen->GetBus( point );
|
||||
|
||||
if( bus )
|
||||
bus_entry->m_connected_bus_item = bus;
|
||||
@@ -1378,11 +1401,8 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
// Build subgraphs from items (on a per-sheet basis)
|
||||
for( SCH_ITEM* item : m_items )
|
||||
{
|
||||
for( const auto& it : item->m_connection_map )
|
||||
for( const auto& [sheet, connection] : item->m_connection_map )
|
||||
{
|
||||
const SCH_SHEET_PATH& sheet = it.first;
|
||||
SCH_CONNECTION* connection = it.second;
|
||||
|
||||
if( connection->SubgraphCode() == 0 )
|
||||
{
|
||||
CONNECTION_SUBGRAPH* subgraph = new CONNECTION_SUBGRAPH( this );
|
||||
@@ -1448,7 +1468,6 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1467,44 +1486,45 @@ void CONNECTION_GRAPH::resolveAllDrivers()
|
||||
|
||||
std::vector<std::future<size_t>> returns( dirty_graphs.size() );
|
||||
|
||||
auto update_lambda = []( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
if( !subgraph->m_dirty )
|
||||
return 0;
|
||||
|
||||
// Special processing for some items
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
auto update_lambda =
|
||||
[]( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
case SCH_NO_CONNECT_T:
|
||||
subgraph->m_no_connect = item;
|
||||
break;
|
||||
if( !subgraph->m_dirty )
|
||||
return 0;
|
||||
|
||||
case SCH_BUS_WIRE_ENTRY_T:
|
||||
subgraph->m_bus_entry = item;
|
||||
break;
|
||||
// Special processing for some items
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_NO_CONNECT_T:
|
||||
subgraph->m_no_connect = item;
|
||||
break;
|
||||
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
auto pin = static_cast<SCH_PIN*>( item );
|
||||
case SCH_BUS_WIRE_ENTRY_T:
|
||||
subgraph->m_bus_entry = item;
|
||||
break;
|
||||
|
||||
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
subgraph->m_no_connect = item;
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
auto pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
break;
|
||||
}
|
||||
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
subgraph->m_no_connect = item;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
subgraph->ResolveDrivers( true );
|
||||
subgraph->m_dirty = false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
subgraph->ResolveDrivers( true );
|
||||
subgraph->m_dirty = false;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
@@ -2304,8 +2324,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
[&]( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
// Make sure weakly-driven single-pin nets get the unconnected_ prefix
|
||||
if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 &&
|
||||
subgraph->m_driver->Type() == SCH_PIN_T )
|
||||
if( !subgraph->m_strong_driver
|
||||
&& subgraph->m_drivers.size() == 1
|
||||
&& subgraph->m_driver->Type() == SCH_PIN_T )
|
||||
{
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( subgraph->m_driver );
|
||||
wxString name = pin->GetDefaultNetName( subgraph->m_sheet, true );
|
||||
|
||||
@@ -590,7 +590,16 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
{
|
||||
SCH_SYMBOL* symbol = it->first;
|
||||
|
||||
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
|
||||
wxCHECK2( symbol, ++it; continue );
|
||||
|
||||
if( !it->second.m_LibId.IsValid() )
|
||||
{
|
||||
msg = getSymbolReferences( *symbol, it->second.m_LibId );
|
||||
msg << wxT( ": " ) << _( "*** symbol lib id not valid ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
it = symbols.erase( it );
|
||||
continue;
|
||||
}
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( it->second.m_LibId );
|
||||
|
||||
@@ -647,10 +656,13 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
// Remember initial link before changing for diags purpose
|
||||
wxString initialLibLinkName = UnescapeString( symbol->GetLibId().Format() );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
|
||||
wxCHECK2( libSymbol, continue );
|
||||
|
||||
if( symbol_change_info.m_LibId != symbol->GetLibId() )
|
||||
symbol->SetLibId( symbol_change_info.m_LibId );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
|
||||
|
||||
@@ -325,6 +325,7 @@ void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
deleteAllMarkers( includeExclusions );
|
||||
m_ercRun = false;
|
||||
|
||||
// redraw the schematic
|
||||
redrawDrawPanel();
|
||||
|
||||
@@ -232,16 +232,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();
|
||||
|
||||
|
||||
@@ -463,12 +463,7 @@ bool DIALOG_FIELD_PROPERTIES::TransferDataToWindow()
|
||||
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_field->GetParentSymbol() );
|
||||
|
||||
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
|
||||
{
|
||||
if( symbol->HasUnitDisplayName( ii ) )
|
||||
m_unitChoice->Append( symbol->GetUnitDisplayName( ii ) );
|
||||
else
|
||||
m_unitChoice->Append( symbol->SubReference( ii, false ) );
|
||||
}
|
||||
m_unitChoice->Append( symbol->GetUnitDisplayName( ii, false ) );
|
||||
|
||||
if( symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
|
||||
m_unitChoice->SetSelection( symbol->GetUnit() - 1 );
|
||||
|
||||
@@ -827,7 +827,7 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
|
||||
m_unitFilter->Append( UNITS_ALL );
|
||||
|
||||
for( int ii = 0; ii < aSymbol->GetUnitCount(); ++ii )
|
||||
m_unitFilter->Append( aSymbol->GetUnitReference( ii + 1 ) );
|
||||
m_unitFilter->Append( LIB_SYMBOL::LetterSubReference( ii + 1, 'A' ) );
|
||||
|
||||
m_unitFilter->SetSelection( -1 );
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES::DIALOG_LIB_SYMBOL_PROPERTIES( SYMBOL_EDIT_FRAME* a
|
||||
} ) );
|
||||
m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
|
||||
|
||||
// Show/hide columns according to the user's preference
|
||||
SYMBOL_EDITOR_SETTINGS* cfg = m_Parent->GetSettings();
|
||||
m_grid->ShowHideColumns( cfg->m_EditSymbolVisibleColumns );
|
||||
@@ -110,8 +111,11 @@ DIALOG_LIB_SYMBOL_PROPERTIES::DIALOG_LIB_SYMBOL_PROPERTIES( SYMBOL_EDIT_FRAME* a
|
||||
|
||||
// wxFormBuilder doesn't include this event...
|
||||
m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ),
|
||||
nullptr, this );
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ), nullptr, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_CHANGED,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged ), nullptr, this );
|
||||
m_grid->GetGridWindow()->Bind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
|
||||
|
||||
|
||||
// Forward the delete button to the tricks
|
||||
m_deleteFilterButton->Bind( wxEVT_BUTTON,
|
||||
@@ -161,8 +165,10 @@ DIALOG_LIB_SYMBOL_PROPERTIES::~DIALOG_LIB_SYMBOL_PROPERTIES()
|
||||
m_grid->DestroyTable( m_fields );
|
||||
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ),
|
||||
nullptr, this );
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ), nullptr, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged ), nullptr, this );
|
||||
m_grid->GetGridWindow()->Unbind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
|
||||
|
||||
// Delete the GRID_TRICKS.
|
||||
m_grid->PopEventHandler( true );
|
||||
@@ -174,9 +180,58 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||
if( !wxDialog::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
// Push a copy of each field into m_updateFields
|
||||
// Ensure the fields vector is empty before (re)loading. Constructor no longer
|
||||
// pre-populates fields to avoid double insertion of mandatory fields.
|
||||
if( m_fields->size() > 0 )
|
||||
{
|
||||
// Clear existing entries; we recreate inheritance metadata via push_back()
|
||||
// Note: We cannot simply reuse existing entries because alias inheritance
|
||||
// state may have changed if the parent was edited prior to dialog open.
|
||||
m_fields->clear();
|
||||
}
|
||||
|
||||
// Load current symbol fields (mandatory first, then user fields)
|
||||
m_libEntry->CopyFields( *m_fields );
|
||||
|
||||
// Handle alias (derived) symbol inherited fields. We only inherit non-mandatory fields
|
||||
// and mark any matching names as inherited rather than duplicating them.
|
||||
if( m_libEntry->IsAlias() )
|
||||
{
|
||||
if( LIB_SYMBOL_SPTR parent = m_libEntry->GetParent().lock() )
|
||||
{
|
||||
std::vector<SCH_FIELD*> parentFields;
|
||||
parent->GetFields( parentFields );
|
||||
|
||||
for( SCH_FIELD* pf : parentFields )
|
||||
{
|
||||
if( pf->IsMandatory() )
|
||||
continue; // Never inherit mandatory fields
|
||||
|
||||
bool found = false;
|
||||
|
||||
for( size_t jj = 0; jj < m_fields->size(); ++jj )
|
||||
{
|
||||
SCH_FIELD& f = m_fields->at( jj );
|
||||
|
||||
if( f.IsMandatory() )
|
||||
continue; // Skip mandatory in child list for inheritance match
|
||||
|
||||
if( f.GetCanonicalName() == pf->GetCanonicalName() )
|
||||
{
|
||||
m_fields->SetFieldInherited( jj, *pf );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
m_fields->AddInheritedField( *pf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fields already loaded above; avoid re-copying to prevent duplication.
|
||||
|
||||
std::set<wxString> defined;
|
||||
|
||||
for( SCH_FIELD& field : *m_fields )
|
||||
@@ -416,37 +471,40 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
|
||||
}
|
||||
|
||||
// The Y axis for components in lib is from bottom to top while the screen axis is top
|
||||
// to bottom: we must change the y coord sign when writing back to the library
|
||||
for( int ii = 0; ii < (int) m_fields->size(); ++ii )
|
||||
{
|
||||
VECTOR2I pos = m_fields->at( ii ).GetPosition();
|
||||
pos.y = -pos.y;
|
||||
m_fields->at( ii ).SetPosition( pos );
|
||||
m_fields->at( ii ).SetId( ii );
|
||||
}
|
||||
std::vector<SCH_FIELD> fieldsToSave;
|
||||
|
||||
for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
|
||||
{
|
||||
SCH_FIELD& field = m_fields->at( ii );
|
||||
|
||||
if( field.IsMandatory() )
|
||||
continue;
|
||||
// The Y axis for components in lib is from bottom to top while the screen axis is top
|
||||
// to bottom: we must change the y coord sign when writing back to the library
|
||||
VECTOR2I pos = field.GetPosition();
|
||||
pos.y = -pos.y;
|
||||
field.SetPosition( pos );
|
||||
|
||||
const wxString& fieldName = field.GetCanonicalName();
|
||||
// if( !field.IsMandatory() )
|
||||
field.SetId( ii );
|
||||
|
||||
wxString fieldName = field.GetCanonicalName();
|
||||
|
||||
if( m_fields->IsInherited( ii ) && field == m_fields->ParentField( ii ) )
|
||||
continue; // Skip inherited fields
|
||||
|
||||
if( field.GetText().IsEmpty() )
|
||||
{
|
||||
if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
continue; // Skip empty fields that are not mandatory or template fields
|
||||
}
|
||||
else if( fieldName.IsEmpty() )
|
||||
{
|
||||
field.SetName( _( "untitled" ) );
|
||||
field.SetName( _( "untitled" ) ); // Set a default name for unnamed fields
|
||||
}
|
||||
|
||||
fieldsToSave.push_back( field );
|
||||
}
|
||||
|
||||
m_libEntry->SetFields( *m_fields );
|
||||
m_libEntry->SetFields( fieldsToSave );
|
||||
|
||||
// Update the parent for inherited symbols
|
||||
if( m_libEntry->IsAlias() )
|
||||
@@ -517,6 +575,27 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
aEvent.Skip();
|
||||
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxPoint unscolled_pos = m_grid->CalcUnscrolledPosition( pos );
|
||||
int row = m_grid->YToRow( unscolled_pos.y );
|
||||
int col = m_grid->XToCol( unscolled_pos.x );
|
||||
|
||||
if( row == wxNOT_FOUND || col == wxNOT_FOUND || !m_fields->IsInherited( row ) )
|
||||
{
|
||||
m_grid->SetToolTip( "" );
|
||||
return;
|
||||
}
|
||||
|
||||
m_grid->SetToolTip(
|
||||
wxString::Format( _( "This field is inherited from '%s'." ),
|
||||
m_fields->ParentField( row ).GetName() ) );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
|
||||
{
|
||||
wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
|
||||
@@ -555,6 +634,13 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged( wxGridEvent& event )
|
||||
{
|
||||
m_grid->ForceRefresh();
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnSymbolNameText( wxCommandEvent& event )
|
||||
{
|
||||
if( m_OptionPower->IsChecked() )
|
||||
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
void OnEditFootprintFilter( wxCommandEvent& event ) override;
|
||||
void OnSizeGrid( wxSizeEvent& event ) override;
|
||||
void OnGridCellChanging( wxGridEvent& event );
|
||||
void OnGridCellChanged( wxGridEvent& event );
|
||||
void OnGridMotion( wxMouseEvent& event );
|
||||
void OnEditSpiceModel( wxCommandEvent& event ) override;
|
||||
void OnUpdateUI( wxUpdateUIEvent& event ) override;
|
||||
void OnCancelButtonClick( wxCommandEvent& event ) override;
|
||||
|
||||
@@ -1003,6 +1003,7 @@ void DIALOG_SIM_COMMAND::OnFilterText( wxCommandEvent& aEvent )
|
||||
|
||||
void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_inputSignalsFilter->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -1014,6 +1015,7 @@ void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,8 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame
|
||||
m_filesStack.push_back( symbol->Schematic()->GetEmbeddedFiles() );
|
||||
}
|
||||
|
||||
m_filesStack.push_back( aSymbol.GetEmbeddedFiles() );
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = aSymbol.GetEmbeddedFiles() )
|
||||
m_filesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
m_libraryModelsMgr.SetFilesStack( m_filesStack );
|
||||
m_builtinModelsMgr.SetFilesStack( m_filesStack );
|
||||
|
||||
@@ -878,6 +878,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterText( wxCommandEvent& aEvent )
|
||||
|
||||
void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_filter->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -889,6 +890,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -484,12 +484,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||
m_symbol->SetUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) );
|
||||
|
||||
for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ )
|
||||
{
|
||||
if( m_symbol->HasUnitDisplayName( ii ) )
|
||||
m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) );
|
||||
else
|
||||
m_unitChoice->Append( m_symbol->SubReference( ii, false ) );
|
||||
}
|
||||
m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii, false ) );
|
||||
|
||||
if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
|
||||
m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 );
|
||||
|
||||
@@ -131,7 +131,7 @@ void DIALOG_UPDATE_SYMBOL_FIELDS::onOkButtonClicked( wxCommandEvent& aEvent )
|
||||
wxBusyCursor dummy;
|
||||
SCH_COMMIT commit( m_editFrame );
|
||||
|
||||
commit.Modify( m_symbol );
|
||||
commit.Modify( m_symbol, m_editFrame->GetScreen() );
|
||||
|
||||
// Create the set of fields to be updated
|
||||
m_updateFields.clear();
|
||||
|
||||
+31
-39
@@ -112,28 +112,28 @@ const wxString CommentERC_V[] =
|
||||
// i.e. pin type = ELECTRICAL_PINTYPE::PT_INPUT, but not PT_POWER_IN
|
||||
// that need only a PT_POWER_OUT pin type to be driven
|
||||
const std::set<ELECTRICAL_PINTYPE> DrivingPinTypes =
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_OUTPUT,
|
||||
ELECTRICAL_PINTYPE::PT_POWER_OUT,
|
||||
ELECTRICAL_PINTYPE::PT_PASSIVE,
|
||||
ELECTRICAL_PINTYPE::PT_TRISTATE,
|
||||
ELECTRICAL_PINTYPE::PT_BIDI
|
||||
};
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_OUTPUT,
|
||||
ELECTRICAL_PINTYPE::PT_POWER_OUT,
|
||||
ELECTRICAL_PINTYPE::PT_PASSIVE,
|
||||
ELECTRICAL_PINTYPE::PT_TRISTATE,
|
||||
ELECTRICAL_PINTYPE::PT_BIDI
|
||||
};
|
||||
|
||||
// List of pin types that are considered drivers for power pins
|
||||
// In fact only a ELECTRICAL_PINTYPE::PT_POWER_OUT pin type can drive
|
||||
// power input pins
|
||||
const std::set<ELECTRICAL_PINTYPE> DrivingPowerPinTypes =
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_POWER_OUT
|
||||
};
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_POWER_OUT
|
||||
};
|
||||
|
||||
// List of pin types that require a driver elsewhere on the net
|
||||
const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_INPUT,
|
||||
ELECTRICAL_PINTYPE::PT_POWER_IN
|
||||
};
|
||||
{
|
||||
ELECTRICAL_PINTYPE::PT_INPUT,
|
||||
ELECTRICAL_PINTYPE::PT_POWER_IN
|
||||
};
|
||||
|
||||
extern void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
UNITS_PROVIDER* aUnitsProvider );
|
||||
@@ -574,11 +574,11 @@ int ERC_TESTER::TestMissingUnits()
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
{
|
||||
missing_pin_units += wxS( "....." );
|
||||
missing_pin_units += wxS( "..." );
|
||||
break;
|
||||
}
|
||||
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit, false ) + ", " ;
|
||||
}
|
||||
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
@@ -692,8 +692,7 @@ int ERC_TESTER::TestMissingNetclasses()
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_UNDEFINED_NETCLASS );
|
||||
|
||||
ercItem->SetItems( item );
|
||||
ercItem->SetErrorMessage( wxString::Format( _( "Netclass %s is not defined" ),
|
||||
netclass ) );
|
||||
ercItem->SetErrorMessage( wxString::Format( _( "Netclass %s is not defined" ), netclass ) );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, item->GetPosition() );
|
||||
sheet.LastScreen()->Append( marker );
|
||||
@@ -886,7 +885,7 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
|
||||
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
|
||||
{
|
||||
if( pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
pinMap[pin->GetPosition()].emplace_back( pin );
|
||||
}
|
||||
}
|
||||
@@ -899,7 +898,7 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
|
||||
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
|
||||
{
|
||||
if( pin->GetLibPin()->GetType() != ELECTRICAL_PINTYPE::PT_NC )
|
||||
if( pin->GetType() != ELECTRICAL_PINTYPE::PT_NC )
|
||||
addOther( pin->GetPosition(), pin );
|
||||
}
|
||||
}
|
||||
@@ -1042,16 +1041,12 @@ int ERC_TESTER::TestPinToPin()
|
||||
|
||||
if( erc != PIN_ERROR::OK && m_settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
|
||||
{
|
||||
pin_mismatches.emplace_back(
|
||||
std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt, erc } );
|
||||
pin_mismatches.emplace_back( std::tuple<iterator_t, iterator_t, PIN_ERROR>{ refIt, testIt, erc } );
|
||||
|
||||
if( m_settings.GetERCSortingMetric() == ERC_PIN_SORTING_METRIC::SM_HEURISTICS )
|
||||
{
|
||||
pin_mismatch_counts[refIt] =
|
||||
m_settings.GetPinTypeWeight( ( *refIt ).Pin()->GetType() );
|
||||
|
||||
pin_mismatch_counts[testIt] =
|
||||
m_settings.GetPinTypeWeight( ( *testIt ).Pin()->GetType() );
|
||||
pin_mismatch_counts[refIt] = m_settings.GetPinTypeWeight( ( *refIt ).Pin()->GetType() );
|
||||
pin_mismatch_counts[testIt] = m_settings.GetPinTypeWeight( ( *testIt ).Pin()->GetType() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1132,17 +1127,15 @@ int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
SCH_PIN* other_pin = ( *nearest_pin ).Pin();
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING
|
||||
: ERCE_PIN_TO_PIN_ERROR );
|
||||
auto ercItem = ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING
|
||||
: ERCE_PIN_TO_PIN_ERROR );
|
||||
ercItem->SetItems( pin, other_pin );
|
||||
ercItem->SetSheetSpecificPath( ( *pinIt ).Sheet() );
|
||||
ercItem->SetItemsSheetPaths( ( *pinIt ).Sheet(), ( *nearest_pin ).Sheet() );
|
||||
|
||||
ercItem->SetErrorMessage(
|
||||
wxString::Format( _( "Pins of type %s and %s are connected" ),
|
||||
ElectricalPinTypeGetText( pin->GetType() ),
|
||||
ElectricalPinTypeGetText( other_pin->GetType() ) ) );
|
||||
ercItem->SetErrorMessage( wxString::Format( _( "Pins of type %s and %s are connected" ),
|
||||
ElectricalPinTypeGetText( pin->GetType() ),
|
||||
ElectricalPinTypeGetText( other_pin->GetType() ) ) );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetPosition() );
|
||||
pinToScreenMap[pin]->Append( marker );
|
||||
@@ -1162,7 +1155,7 @@ int ERC_TESTER::TestPinToPin()
|
||||
ercItem->SetSheetSpecificPath( needsDriver.Sheet() );
|
||||
ercItem->SetItemsSheetPaths( needsDriver.Sheet() );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, needsDriver.Pin()->GetPosition() );
|
||||
SCH_MARKER* marker = new SCH_MARKER( std::move( ercItem ), needsDriver.Pin()->GetPosition() );
|
||||
pinToScreenMap[needsDriver.Pin()]->Append( marker );
|
||||
errors++;
|
||||
}
|
||||
@@ -1195,8 +1188,7 @@ int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
if( !pin->GetLibPin()->GetParentSymbol()->IsMulti() )
|
||||
continue;
|
||||
|
||||
wxString name = pin->GetParentSymbol()->GetRef( &sheet ) +
|
||||
+ ":" + pin->GetShownNumber();
|
||||
wxString name = pin->GetParentSymbol()->GetRef( &sheet ) + ":" + pin->GetShownNumber();
|
||||
|
||||
if( !pinToNetMap.count( name ) )
|
||||
{
|
||||
@@ -1273,7 +1265,7 @@ int ERC_TESTER::TestSameLocalGlobalLabel()
|
||||
ercItem->SetSheetSpecificPath( globalItem.second );
|
||||
ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, globalItem.first->GetPosition() );
|
||||
SCH_MARKER* marker = new SCH_MARKER( std::move( ercItem ), globalItem.first->GetPosition() );
|
||||
globalItem.second.LastScreen()->Append( marker );
|
||||
|
||||
errCount++;
|
||||
@@ -1670,7 +1662,7 @@ int ERC_TESTER::TestFootprintFilters()
|
||||
wxJoin( filters, ' ' ) );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( sch_symbol );
|
||||
markers.emplace_back( new SCH_MARKER( ercItem, sch_symbol->GetPosition() ) );
|
||||
markers.emplace_back( new SCH_MARKER( std::move( ercItem ), sch_symbol->GetPosition() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <erc/erc_item.h>
|
||||
#include <erc/erc_settings.h>
|
||||
#include <schematic.h>
|
||||
@@ -397,6 +398,13 @@ void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities )
|
||||
if( markerSeverity & m_severities )
|
||||
m_filteredMarkers.push_back( aMarker );
|
||||
} );
|
||||
|
||||
// Sort markers so that errors appear before warnings
|
||||
std::stable_sort( m_filteredMarkers.begin(), m_filteredMarkers.end(),
|
||||
[]( const SCH_MARKER* a, const SCH_MARKER* b )
|
||||
{
|
||||
return a->GetSeverity() > b->GetSeverity();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+144
-24
@@ -225,6 +225,15 @@ int FIELDS_GRID_TABLE::GetMandatoryRowCount() const
|
||||
}
|
||||
|
||||
|
||||
void FIELDS_GRID_TABLE::push_back( const SCH_FIELD& aField )
|
||||
{
|
||||
std::vector<SCH_FIELD>::push_back( aField );
|
||||
|
||||
m_isInherited.resize( size() );
|
||||
m_parentFields.resize( size() );
|
||||
}
|
||||
|
||||
|
||||
void FIELDS_GRID_TABLE::initGrid( WX_GRID* aGrid )
|
||||
{
|
||||
// Build the various grid cell attributes.
|
||||
@@ -399,6 +408,9 @@ FIELDS_GRID_TABLE::~FIELDS_GRID_TABLE()
|
||||
m_fontAttr->DecRef();
|
||||
m_colorAttr->DecRef();
|
||||
|
||||
for( SCH_FIELD& field : m_parentFields )
|
||||
field.SetParent( nullptr );
|
||||
|
||||
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE::onUnitsChanged, this );
|
||||
}
|
||||
|
||||
@@ -538,33 +550,34 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::
|
||||
wxCHECK( aRow < GetNumberRows(), nullptr );
|
||||
|
||||
const SCH_FIELD& field = getField( aRow );
|
||||
wxGridCellAttr* tmp;
|
||||
wxGridCellAttr* attr = nullptr;
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case FDC_NAME:
|
||||
if( field.IsMandatory() )
|
||||
{
|
||||
tmp = m_fieldNameAttr->Clone();
|
||||
tmp->SetReadOnly( true );
|
||||
return enhanceAttr( tmp, aRow, aCol, aKind );
|
||||
attr = m_fieldNameAttr->Clone();
|
||||
attr->SetReadOnly( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fieldNameAttr->IncRef();
|
||||
return enhanceAttr( m_fieldNameAttr, aRow, aCol, aKind );
|
||||
attr = m_fieldNameAttr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FDC_VALUE:
|
||||
if( m_parentType == SCH_SYMBOL_T && field.GetId() == REFERENCE_FIELD )
|
||||
{
|
||||
m_referenceAttr->IncRef();
|
||||
return enhanceAttr( m_referenceAttr, aRow, aCol, aKind );
|
||||
attr = m_referenceAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SYMBOL_T && field.GetId() == VALUE_FIELD )
|
||||
{
|
||||
m_valueAttr->IncRef();
|
||||
return enhanceAttr( m_valueAttr, aRow, aCol, aKind );
|
||||
attr = m_valueAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SYMBOL_T && field.GetId() == FOOTPRINT_FIELD )
|
||||
{
|
||||
@@ -574,34 +587,34 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::
|
||||
if( m_part && m_part->IsPower() )
|
||||
{
|
||||
m_readOnlyAttr->IncRef();
|
||||
return enhanceAttr( m_readOnlyAttr, aRow, aCol, aKind );
|
||||
attr = m_readOnlyAttr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_footprintAttr->IncRef();
|
||||
return enhanceAttr( m_footprintAttr, aRow, aCol, aKind );
|
||||
attr = m_footprintAttr;
|
||||
}
|
||||
}
|
||||
else if( m_parentType == SCH_SYMBOL_T && field.GetId() == DATASHEET_FIELD )
|
||||
{
|
||||
m_urlAttr->IncRef();
|
||||
return enhanceAttr( m_urlAttr, aRow, aCol, aKind );
|
||||
attr = m_urlAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SHEET_T && field.GetId() == SHEETNAME )
|
||||
{
|
||||
m_referenceAttr->IncRef();
|
||||
return enhanceAttr( m_referenceAttr, aRow, aCol, aKind );
|
||||
attr = m_referenceAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SHEET_T && field.GetId() == SHEETFILENAME )
|
||||
{
|
||||
m_filepathAttr->IncRef();
|
||||
return enhanceAttr( m_filepathAttr, aRow, aCol, aKind );
|
||||
attr = m_filepathAttr;
|
||||
}
|
||||
else if( ( m_parentType == SCH_LABEL_LOCATE_ANY_T )
|
||||
&& field.GetCanonicalName() == wxT( "Netclass" ) )
|
||||
{
|
||||
m_netclassAttr->IncRef();
|
||||
return enhanceAttr( m_netclassAttr, aRow, aCol, aKind );
|
||||
attr = m_netclassAttr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -615,31 +628,36 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::
|
||||
if( ( templateFn && templateFn->m_URL ) || field.IsHypertext() )
|
||||
{
|
||||
m_urlAttr->IncRef();
|
||||
return enhanceAttr( m_urlAttr, aRow, aCol, aKind );
|
||||
attr = m_urlAttr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nonUrlAttr->IncRef();
|
||||
return enhanceAttr( m_nonUrlAttr, aRow, aCol, aKind );
|
||||
attr = m_nonUrlAttr;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FDC_TEXT_SIZE:
|
||||
case FDC_POSX:
|
||||
case FDC_POSY:
|
||||
return enhanceAttr( nullptr, aRow, aCol, aKind );
|
||||
break;
|
||||
|
||||
case FDC_H_ALIGN:
|
||||
m_hAlignAttr->IncRef();
|
||||
return enhanceAttr( m_hAlignAttr, aRow, aCol, aKind );
|
||||
attr = m_hAlignAttr;
|
||||
break;
|
||||
|
||||
case FDC_V_ALIGN:
|
||||
m_vAlignAttr->IncRef();
|
||||
return enhanceAttr( m_vAlignAttr, aRow, aCol, aKind );
|
||||
attr = m_vAlignAttr;
|
||||
break;
|
||||
|
||||
case FDC_ORIENTATION:
|
||||
m_orientationAttr->IncRef();
|
||||
return enhanceAttr( m_orientationAttr, aRow, aCol, aKind );
|
||||
attr = m_orientationAttr;
|
||||
break;
|
||||
|
||||
case FDC_SHOWN:
|
||||
case FDC_SHOW_NAME:
|
||||
@@ -648,20 +666,50 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::
|
||||
case FDC_ALLOW_AUTOPLACE:
|
||||
case FDC_PRIVATE:
|
||||
m_boolAttr->IncRef();
|
||||
return enhanceAttr( m_boolAttr, aRow, aCol, aKind );
|
||||
attr = m_boolAttr;
|
||||
break;
|
||||
|
||||
case FDC_FONT:
|
||||
m_fontAttr->IncRef();
|
||||
return enhanceAttr( m_fontAttr, aRow, aCol, aKind );
|
||||
attr = m_fontAttr;
|
||||
break;
|
||||
|
||||
case FDC_COLOR:
|
||||
m_colorAttr->IncRef();
|
||||
return enhanceAttr( m_colorAttr, aRow, aCol, aKind );
|
||||
attr = m_colorAttr;
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL;
|
||||
return enhanceAttr( nullptr, aRow, aCol, aKind );
|
||||
attr = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !attr )
|
||||
return nullptr;
|
||||
|
||||
attr = enhanceAttr( attr, aRow, aCol, aKind );
|
||||
|
||||
if( IsInherited( aRow ) )
|
||||
{
|
||||
wxGridCellAttr* text_attr = attr ? attr->Clone() : new wxGridCellAttr;
|
||||
wxFont font;
|
||||
|
||||
if( !text_attr->HasFont() )
|
||||
font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
|
||||
else
|
||||
font = text_attr->GetFont();
|
||||
|
||||
font.MakeItalic();
|
||||
text_attr->SetFont( font );
|
||||
text_attr->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
|
||||
|
||||
if( attr )
|
||||
attr->DecRef();
|
||||
|
||||
attr = text_attr;
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1042,10 +1090,82 @@ bool FIELDS_GRID_TABLE::BoolFromString( const wxString& aValue ) const
|
||||
}
|
||||
|
||||
|
||||
SCH_FIELD* FIELDS_GRID_TABLE::GetField( MANDATORY_FIELD_T aFieldId )
|
||||
{
|
||||
for( SCH_FIELD& field : *this )
|
||||
{
|
||||
if( field.GetId() == aFieldId )
|
||||
return &field;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int FIELDS_GRID_TABLE::GetFieldRow( MANDATORY_FIELD_T aFieldId )
|
||||
{
|
||||
for( int ii = 0; ii < (int) this->size(); ++ii )
|
||||
{
|
||||
if( this->at( ii ).GetId() == aFieldId )
|
||||
return ii;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void FIELDS_GRID_TABLE::AddInheritedField( const SCH_FIELD& aParent )
|
||||
{
|
||||
push_back( aParent );
|
||||
back().SetParent( m_part );
|
||||
m_isInherited.back() = true;
|
||||
m_parentFields.back() = aParent;
|
||||
}
|
||||
|
||||
|
||||
bool FIELDS_GRID_TABLE::EraseRow( size_t aRow )
|
||||
{
|
||||
if( m_isInherited.size() > aRow )
|
||||
{
|
||||
// You can't erase inherited fields, but you can reset them to the parent value.
|
||||
if( m_isInherited[aRow] )
|
||||
{
|
||||
at( aRow ) = m_parentFields[aRow];
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isInherited.erase( m_isInherited.begin() + aRow );
|
||||
}
|
||||
|
||||
if( m_parentFields.size() > aRow )
|
||||
m_parentFields.erase( m_parentFields.begin() + aRow );
|
||||
|
||||
std::vector<SCH_FIELD>::erase( begin() + aRow );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void FIELDS_GRID_TABLE::SwapRows( size_t a, size_t b )
|
||||
{
|
||||
wxCHECK( a < this->size() && b < this->size(), /*void*/ );
|
||||
|
||||
std::swap( at( a ), at( b ) );
|
||||
|
||||
bool tmpInherited = m_isInherited[a];
|
||||
m_isInherited[a] = m_isInherited[b];
|
||||
m_isInherited[b] = tmpInherited;
|
||||
|
||||
std::swap( m_parentFields[a], m_parentFields[b] );
|
||||
}
|
||||
|
||||
|
||||
void FIELDS_GRID_TABLE::DetachFields()
|
||||
{
|
||||
for( SCH_FIELD& field : *this )
|
||||
field.SetParent( nullptr );
|
||||
|
||||
for( SCH_FIELD& field : m_parentFields )
|
||||
field.SetParent( nullptr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <sch_symbol.h>
|
||||
#include <grid_tricks.h>
|
||||
#include <validators.h>
|
||||
#include <vector>
|
||||
|
||||
class SCH_BASE_FRAME;
|
||||
class DIALOG_SHIM;
|
||||
@@ -120,6 +121,37 @@ public:
|
||||
wxString StringFromBool( bool aValue ) const;
|
||||
bool BoolFromString( const wxString& aValue ) const;
|
||||
|
||||
SCH_FIELD* GetField( MANDATORY_FIELD_T aFieldId );
|
||||
int GetFieldRow( MANDATORY_FIELD_T aFieldId );
|
||||
|
||||
void AddInheritedField( const SCH_FIELD& aParent );
|
||||
|
||||
void SetFieldInherited( size_t aRow, const SCH_FIELD& aParent )
|
||||
{
|
||||
m_isInherited.resize( aRow + 1, false );
|
||||
m_parentFields.resize( aRow + 1 );
|
||||
m_parentFields[aRow] = aParent;
|
||||
m_isInherited[aRow] = true;
|
||||
}
|
||||
|
||||
|
||||
bool IsInherited( size_t aRow ) const
|
||||
{
|
||||
if( aRow >= m_isInherited.size() || aRow >= m_parentFields.size() )
|
||||
return false;
|
||||
|
||||
return m_isInherited[aRow] && m_parentFields[aRow].GetText() == at( aRow ).GetText();
|
||||
}
|
||||
|
||||
const SCH_FIELD& ParentField( size_t row ) const { return m_parentFields[row]; }
|
||||
|
||||
void push_back( const SCH_FIELD& field );
|
||||
// For std::vector compatibility, but we don't use it directly.
|
||||
void emplace_back( const SCH_FIELD& field ) { push_back( field ); }
|
||||
|
||||
bool EraseRow( size_t row );
|
||||
void SwapRows( size_t a, size_t b );
|
||||
|
||||
void DetachFields();
|
||||
|
||||
protected:
|
||||
@@ -164,6 +196,9 @@ private:
|
||||
wxGridCellAttr* m_fontAttr;
|
||||
wxGridCellAttr* m_colorAttr;
|
||||
|
||||
std::vector<bool> m_isInherited;
|
||||
std::vector<SCH_FIELD> m_parentFields;
|
||||
|
||||
std::unique_ptr<NUMERIC_EVALUATOR> m_eval;
|
||||
std::map< std::pair<int, int>, wxString > m_evalOriginal;
|
||||
};
|
||||
|
||||
+25
-1
@@ -1230,8 +1230,18 @@ bool SCH_EDIT_FRAME::doAutoSave()
|
||||
if( !tmp.IsOk() )
|
||||
return false;
|
||||
|
||||
if( !IsWritable( tmp ) )
|
||||
if( !IsWritable( tmp, false ) )
|
||||
{
|
||||
if( !m_autoSavePermissionError )
|
||||
{
|
||||
DisplayError( this, wxString::Format(
|
||||
_( "Could not autosave files to read-only folder: '%s'" ),
|
||||
tmp.GetPath() ) );
|
||||
m_autoSavePermissionError = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString title = GetTitle(); // Save frame title, that can be modified by the save process
|
||||
|
||||
@@ -1246,6 +1256,20 @@ bool SCH_EDIT_FRAME::doAutoSave()
|
||||
// Auto save file name is the normal file name prefixed with GetAutoSavePrefix().
|
||||
fn.SetName( FILEEXT::AutoSaveFilePrefix + fn.GetName() );
|
||||
|
||||
if( !IsWritable( fn, false ) )
|
||||
{
|
||||
if( !m_autoSavePermissionError )
|
||||
{
|
||||
DisplayError( this, wxString::Format(
|
||||
_( "Could not autosave files to read-only folder: '%s'" ),
|
||||
fn.GetPath() ) );
|
||||
m_autoSavePermissionError = true;
|
||||
}
|
||||
|
||||
autoSaveOk = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( saveSchematicFile( screens.GetSheet( i ), fn.GetFullPath() ) )
|
||||
{
|
||||
// This was only an auto-save, not a real save. Reset the modified flag.
|
||||
|
||||
+31
-20
@@ -281,24 +281,31 @@ LIB_SYMBOL_SPTR LIB_SYMBOL::GetRootSymbol() const
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_SYMBOL::GetUnitReference( int aUnit )
|
||||
{
|
||||
return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
|
||||
}
|
||||
|
||||
|
||||
bool LIB_SYMBOL::HasUnitDisplayName( int aUnit )
|
||||
bool LIB_SYMBOL::HasUnitDisplayName( int aUnit ) const
|
||||
{
|
||||
return ( m_unitDisplayNames.count( aUnit ) == 1 );
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit )
|
||||
wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
|
||||
{
|
||||
if( HasUnitDisplayName( aUnit ) )
|
||||
return m_unitDisplayNames[aUnit];
|
||||
if( m_unitDisplayNames.contains( aUnit ) )
|
||||
return m_unitDisplayNames.at( aUnit );
|
||||
else if( aLabel )
|
||||
return wxString::Format( _( "Unit %s" ), LIB_SYMBOL::LetterSubReference( aUnit, 'A' ) );
|
||||
else
|
||||
return wxString::Format( _( "Unit %s" ), GetUnitReference( aUnit ) );
|
||||
return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
|
||||
{
|
||||
if( aBodyStyle == BODY_STYLE::DEMORGAN )
|
||||
return aLabel ? _( "Alternate" ) : wxString( _HKI( "Alternate" ) );
|
||||
else if( aBodyStyle == BODY_STYLE::BASE )
|
||||
return aLabel ? _( "Standard" ) : wxString( _HKI( "Standard" ) );
|
||||
else
|
||||
return wxT( "?" );
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +487,7 @@ void LIB_SYMBOL::SetNormal()
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId )
|
||||
wxString LIB_SYMBOL::LetterSubReference( int aUnit, wxChar aInitialLetter )
|
||||
{
|
||||
// use letters as notation. To allow more than 26 units, the sub ref
|
||||
// use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
|
||||
@@ -491,7 +498,7 @@ wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId )
|
||||
do
|
||||
{
|
||||
u = ( aUnit - 1 ) % 26;
|
||||
suffix = wxChar( aFirstId + u ) + suffix;
|
||||
suffix = wxChar( aInitialLetter + u ) + suffix;
|
||||
aUnit = ( aUnit - u ) / 26;
|
||||
} while( aUnit > 0 );
|
||||
|
||||
@@ -1419,14 +1426,18 @@ void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
|
||||
|
||||
if( aCount < m_unitCount )
|
||||
{
|
||||
LIB_ITEMS_CONTAINER::ITERATOR i = m_drawings.begin();
|
||||
|
||||
while( i != m_drawings.end() )
|
||||
// Iterate each drawing-type bucket and erase items that belong to units > aCount.
|
||||
for( int type = LIB_ITEMS_CONTAINER::FIRST_TYPE; type <= LIB_ITEMS_CONTAINER::LAST_TYPE; ++type )
|
||||
{
|
||||
if( i->m_unit > aCount )
|
||||
i = m_drawings.erase( i );
|
||||
else
|
||||
++i;
|
||||
auto it = m_drawings.begin( type );
|
||||
|
||||
while( it != m_drawings.end( type ) )
|
||||
{
|
||||
if( it->m_unit > aCount )
|
||||
it = m_drawings.erase( it ); // returns next iterator
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( aDuplicateDrawItems )
|
||||
|
||||
+10
-8
@@ -554,20 +554,22 @@ public:
|
||||
void SetUnitCount( int aCount, bool aDuplicateDrawItems = true );
|
||||
int GetUnitCount() const override;
|
||||
|
||||
/**
|
||||
* Return an identifier for \a aUnit for symbols with units.
|
||||
*/
|
||||
wxString GetUnitReference( int aUnit ) override;
|
||||
|
||||
/**
|
||||
* Return true if the given unit \a aUnit has a display name defined
|
||||
*/
|
||||
bool HasUnitDisplayName( int aUnit ) override;
|
||||
bool HasUnitDisplayName( int aUnit ) const;
|
||||
|
||||
wxString GetUnitName( int aUnit ) const override
|
||||
{
|
||||
return GetUnitDisplayName( aUnit, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user-defined display name for \a aUnit for symbols with units.
|
||||
*/
|
||||
wxString GetUnitDisplayName( int aUnit ) override;
|
||||
wxString GetUnitDisplayName( int aUnit, bool aLabel ) const override;
|
||||
|
||||
wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const override;
|
||||
|
||||
/**
|
||||
* Copy all unit display names into the given map \a aTarget
|
||||
@@ -585,7 +587,7 @@ public:
|
||||
*/
|
||||
bool IsMulti() const override { return m_unitCount > 1; }
|
||||
|
||||
static wxString LetterSubReference( int aUnit, int aFirstId );
|
||||
static wxString LetterSubReference( int aUnit, wxChar aInitialLetter );
|
||||
|
||||
/**
|
||||
* Set or clear the alternate body style (DeMorgan) for the symbol.
|
||||
|
||||
@@ -34,17 +34,15 @@
|
||||
#include "netlist_exporter_allegro.h"
|
||||
#include "netlist_exporter_xml.h"
|
||||
#include <regex>
|
||||
|
||||
#include <fmt.h>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
bool NETLIST_EXPORTER_ALLEGRO::WriteNetlist( const wxString& aOutFileName,
|
||||
unsigned /* aNetlistOptions */,
|
||||
REPORTER& aReporter )
|
||||
{
|
||||
m_f = nullptr;
|
||||
wxString field;
|
||||
wxString footprint;
|
||||
int ret = 0; // zero now, OR in the sign bit on error
|
||||
wxString netName;
|
||||
bool success = true;
|
||||
|
||||
// Create the devices directory
|
||||
m_exportPath = wxFileName( aOutFileName ).GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR )
|
||||
@@ -67,31 +65,41 @@ bool NETLIST_EXPORTER_ALLEGRO::WriteNetlist( const wxString& aOutFileName,
|
||||
return false;
|
||||
}
|
||||
|
||||
ret |= fprintf( m_f, "(Source: %s)\n", TO_UTF8( m_schematic->GetFileName() ) );
|
||||
ret |= fprintf( m_f, "(Date: %s)\n", TO_UTF8( GetISO8601CurrentDateTime() ) );
|
||||
try
|
||||
{
|
||||
fmt::print( m_f, "(NETLIST)\n" );
|
||||
fmt::print( m_f, "(Source: {})\n", TO_UTF8( m_schematic->GetFileName() ) );
|
||||
fmt::print( m_f, "(Date: {})\n", TO_UTF8( GetISO8601CurrentDateTime() ) );
|
||||
|
||||
m_packageProperties.clear();
|
||||
m_componentGroups.clear();
|
||||
m_orderedSymbolsSheetpath.clear();
|
||||
m_netNameNodes.clear();
|
||||
m_packageProperties.clear();
|
||||
m_componentGroups.clear();
|
||||
m_orderedSymbolsSheetpath.clear();
|
||||
m_netNameNodes.clear();
|
||||
|
||||
extractComponentsInfo();
|
||||
extractComponentsInfo();
|
||||
|
||||
// Start with package definitions, which we create from component groups.
|
||||
toAllegroPackages();
|
||||
// Start with package definitions, which we create from component groups.
|
||||
toAllegroPackages();
|
||||
|
||||
// Write out nets
|
||||
toAllegroNets();
|
||||
// Write out package properties. NOTE: Allegro doesn't recognize much...
|
||||
toAllegroPackageProperties();
|
||||
|
||||
// Write out package properties. NOTE: Allegro doesn't recognize much...
|
||||
toAllegroPackageProperties();
|
||||
// Write out nets
|
||||
toAllegroNets();
|
||||
|
||||
fmt::print( m_f, "$END\n" );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Done with the netlist
|
||||
fclose( m_f );
|
||||
|
||||
m_f = nullptr;
|
||||
|
||||
return ret >= 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -437,8 +445,8 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( d, "PACKAGE '%s'\n", TO_UTF8( formatDevice( footprintText ) ) );
|
||||
fprintf( d, "CLASS IC\n" );
|
||||
fmt::print( d, "PACKAGE '{}'\n", TO_UTF8( formatDevice( footprintText ) ) );
|
||||
fmt::print( d, "CLASS IC\n" );
|
||||
|
||||
std::vector<SCH_PIN*> pinList = sym->GetLibSymbolRef()->GetPins();
|
||||
|
||||
@@ -463,36 +471,26 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
|
||||
}
|
||||
|
||||
unsigned int pinCount = pinList.size();
|
||||
fprintf( d, "PINCOUNT %u\n", pinCount );
|
||||
fmt::print( d, "PINCOUNT {}\n", pinCount );
|
||||
|
||||
if( pinCount > 0 )
|
||||
{
|
||||
fprintf( d, "%s", TO_UTF8( formatFunction( "main", pinList ) ) );
|
||||
fmt::print( d, "{}", TO_UTF8( formatFunction( "main", pinList ) ) );
|
||||
}
|
||||
|
||||
if( !value.IsEmpty() )
|
||||
{
|
||||
fprintf( d, "PACKAGEPROP VALUE %s\n", TO_UTF8( value ) );
|
||||
fmt::print( d, "PACKAGEPROP VALUE {}\n", TO_UTF8( value ) );
|
||||
}
|
||||
|
||||
if( !tol.IsEmpty() )
|
||||
{
|
||||
fprintf( d, "PACKAGEPROP TOL %s\n", TO_UTF8( tol ) );
|
||||
fmt::print( d, "PACKAGEPROP TOL {}\n", TO_UTF8( tol ) );
|
||||
}
|
||||
|
||||
if( !footprintAlt.IsEmpty() )
|
||||
{
|
||||
fprintf( d, "PACKAGEPROP ALT_SYMBOLS '(" );
|
||||
|
||||
wxString footprintAltSymbolsText;
|
||||
|
||||
for( const wxString& fp : footprintAlt )
|
||||
{
|
||||
footprintAltSymbolsText += fp + wxString( "," );
|
||||
}
|
||||
|
||||
footprintAltSymbolsText.Truncate( footprintAltSymbolsText.Length() - 1 );
|
||||
fprintf( d, "%s)'\n", TO_UTF8( footprintAltSymbolsText ) );
|
||||
fmt::print( d, "PACKAGEPROP ALT_SYMBOLS '({})'\n", fmt::join( footprintAlt, "," ) );
|
||||
}
|
||||
|
||||
wxArrayString propArray;
|
||||
@@ -503,7 +501,7 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
|
||||
|
||||
if(!data.IsEmpty())
|
||||
{
|
||||
fprintf( d, "PACKAGEPROP %s %s\n", TO_UTF8( propArray[0] ), TO_UTF8( data ) );
|
||||
fmt::print( d, "PACKAGEPROP {} {}\n", TO_UTF8( propArray[0] ), TO_UTF8( data ) );
|
||||
}
|
||||
|
||||
propArray.clear();
|
||||
@@ -512,14 +510,16 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
|
||||
|
||||
if(!data.IsEmpty())
|
||||
{
|
||||
fprintf( d, "PACKAGEPROP %s %s\n", TO_UTF8( propArray[0] ), TO_UTF8( data ) );
|
||||
fmt::print( d, "PACKAGEPROP {} {}\n", TO_UTF8( propArray[0] ), TO_UTF8( data ) );
|
||||
}
|
||||
|
||||
fprintf( d, "END\n" );
|
||||
fmt::print( d, "END\n" );
|
||||
|
||||
fclose( d );
|
||||
}
|
||||
|
||||
fmt::print( m_f, "$PACKAGES\n" );
|
||||
|
||||
for( auto iter = compPackageMap.begin(); iter != compPackageMap.end(); iter++ )
|
||||
{
|
||||
wxString deviceType = iter->first;
|
||||
@@ -528,25 +528,28 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackages()
|
||||
|
||||
if( value.IsEmpty() && tolerance.IsEmpty() )
|
||||
{
|
||||
fprintf( m_f, "!%s;", TO_UTF8( deviceType ) );
|
||||
fmt::print( m_f, "! '{}' ; ", TO_UTF8( deviceType ) );
|
||||
}
|
||||
else if( tolerance.IsEmpty() )
|
||||
{
|
||||
fprintf( m_f, "!%s!%s;", TO_UTF8( deviceType ), TO_UTF8( value ) );
|
||||
fmt::print( m_f, "! '{}' ! '{}' ; ", TO_UTF8( deviceType ), TO_UTF8( value ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( m_f, "!%s!%s!%s;", TO_UTF8( deviceType ), TO_UTF8( value ),
|
||||
fmt::print( m_f, "! '{}' ! '{}' ! {} ; ", TO_UTF8( deviceType ), TO_UTF8( value ),
|
||||
TO_UTF8( tolerance ) );
|
||||
}
|
||||
|
||||
std::vector<std::pair<SCH_SYMBOL*, SCH_SHEET_PATH>> symbolSheetpaths =
|
||||
iter->second.m_symbolSheetpaths;
|
||||
|
||||
std::vector<wxString> refTexts;
|
||||
for( const auto& [ sym, sheetPath ] : symbolSheetpaths)
|
||||
fprintf( m_f, ",\n\t%s", TO_UTF8( sym->GetRef( &sheetPath ) ) );
|
||||
refTexts.push_back( sym->GetRef( &sheetPath ) );
|
||||
|
||||
fprintf( m_f, "\n" );
|
||||
fmt::print( m_f, "{}", fmt::join( refTexts, ",\n\t" ) );
|
||||
|
||||
fmt::print( m_f, "\n" );
|
||||
}
|
||||
|
||||
if( !deviceFileCreatingError.IsEmpty() )
|
||||
@@ -680,15 +683,14 @@ wxString NETLIST_EXPORTER_ALLEGRO::formatDevice( wxString aString )
|
||||
|
||||
void NETLIST_EXPORTER_ALLEGRO::toAllegroPackageProperties()
|
||||
{
|
||||
fprintf( m_f, "%s\n", "$PACKAGES" );
|
||||
fprintf( m_f, "%s\n", "$A_PROPERTIES" );
|
||||
fmt::print( m_f, "$A_PROPERTIES\n" );
|
||||
|
||||
while( !m_packageProperties.empty() )
|
||||
{
|
||||
std::multimap<wxString, wxString>::iterator iter = m_packageProperties.begin();
|
||||
wxString sheetPathText = iter->first;
|
||||
|
||||
fprintf( m_f, "ROOM %s;", TO_UTF8( formatText( sheetPathText ) ) );
|
||||
fmt::print( m_f, "'ROOM' '{}' ; ", TO_UTF8( formatText( sheetPathText ) ) );
|
||||
|
||||
std::vector<wxString> refTexts;
|
||||
|
||||
@@ -705,17 +707,16 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroPackageProperties()
|
||||
std::stable_sort( refTexts.begin(), refTexts.end(),
|
||||
NETLIST_EXPORTER_ALLEGRO::CompareSymbolRef );
|
||||
|
||||
for( const wxString& ref : refTexts )
|
||||
fprintf( m_f, ",\n\t%s", TO_UTF8( ref ) );
|
||||
fmt::print( m_f, "{}", fmt::join( refTexts, ",\n\t" ) );
|
||||
|
||||
fprintf( m_f, "\n" );
|
||||
fmt::print( m_f, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_ALLEGRO::toAllegroNets()
|
||||
{
|
||||
fprintf( m_f, "%s\n", "$NETS" );
|
||||
fmt::print( m_f, "$NETS\n" );
|
||||
|
||||
while( !m_netNameNodes.empty() )
|
||||
{
|
||||
@@ -724,7 +725,7 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroNets()
|
||||
|
||||
wxString netName = iter->first;
|
||||
|
||||
fprintf( m_f, "%s;", TO_UTF8( formatText( netName ).MakeUpper() ) );
|
||||
fmt::print( m_f, "{}; ", TO_UTF8( formatText( netName ).MakeUpper() ) );
|
||||
|
||||
auto pairIter = m_netNameNodes.equal_range( netName );
|
||||
|
||||
@@ -738,14 +739,17 @@ void NETLIST_EXPORTER_ALLEGRO::toAllegroNets()
|
||||
|
||||
std::stable_sort( netNodes.begin(), netNodes.end() );
|
||||
|
||||
std::vector<wxString> nets;
|
||||
for( const NET_NODE& netNode : netNodes )
|
||||
{
|
||||
wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
|
||||
wxString pinText = netNode.m_Pin->GetShownNumber();
|
||||
fprintf( m_f, ",\n\t%s.%s", TO_UTF8( refText ), TO_UTF8( pinText ) );
|
||||
nets.push_back( refText + wxString( "." ) + pinText );
|
||||
}
|
||||
|
||||
fprintf( m_f, "\n" );
|
||||
fmt::print( m_f, "{}", fmt::join( nets, ",\n\t" ) );
|
||||
|
||||
fmt::print( m_f, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +119,8 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_SYMBOL* aSymbol, int aUnit )
|
||||
|
||||
if( otherSymbolRef )
|
||||
{
|
||||
const wxString targetUnitName = symbol->GetUnitDisplayName( aUnit );
|
||||
const wxString currUnitName = symbol->GetUnitDisplayName( currentUnit );
|
||||
const wxString targetUnitName = symbol->GetUnitDisplayName( aUnit, false );
|
||||
const wxString currUnitName = symbol->GetUnitDisplayName( currentUnit, false );
|
||||
wxString otherSheetName = otherSymbolRef->GetSheetPath().PathHumanReadable( true, true );
|
||||
|
||||
if( otherSheetName.IsEmpty() )
|
||||
|
||||
+25
-30
@@ -82,42 +82,37 @@ void InitTables()
|
||||
{
|
||||
// clang-format off
|
||||
g_pinElectricalTypes = {
|
||||
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
|
||||
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
|
||||
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
|
||||
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
|
||||
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, { _( "Open collector" ),
|
||||
BITMAPS::pintype_opencoll } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
|
||||
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
|
||||
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
|
||||
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
|
||||
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
|
||||
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, { _( "Open collector" ), BITMAPS::pintype_opencoll } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
|
||||
};
|
||||
|
||||
g_pinShapes = {
|
||||
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ),
|
||||
BITMAPS::pinshape_clock_invert } },
|
||||
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
|
||||
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ),
|
||||
BITMAPS::pinshape_active_low_output } },
|
||||
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ),
|
||||
BITMAPS::pinshape_clock_fall } },
|
||||
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ),
|
||||
BITMAPS::pinshape_nonlogic } },
|
||||
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ), BITMAPS::pinshape_clock_invert } },
|
||||
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
|
||||
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ), BITMAPS::pinshape_active_low_output } },
|
||||
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ), BITMAPS::pinshape_clock_fall } },
|
||||
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ), BITMAPS::pinshape_nonlogic } },
|
||||
};
|
||||
|
||||
g_pinOrientations = {
|
||||
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
|
||||
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
|
||||
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
|
||||
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
|
||||
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
|
||||
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
|
||||
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
|
||||
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -1614,7 +1614,9 @@ void SCH_EDIT_FRAME::RefreshOperatingPointDisplay()
|
||||
{
|
||||
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
|
||||
embeddedFilesStack.push_back( m_schematic->GetEmbeddedFiles() );
|
||||
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
|
||||
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
|
||||
embeddedFilesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
simLibMgr.SetFilesStack( embeddedFilesStack );
|
||||
|
||||
|
||||
+17
-1
@@ -47,6 +47,20 @@
|
||||
static const std::vector<KICAD_T> labelTypes = { SCH_LABEL_LOCATE_ANY_T };
|
||||
|
||||
|
||||
SCH_FIELD::SCH_FIELD() :
|
||||
SCH_ITEM( nullptr, SCH_FIELD_T ),
|
||||
EDA_TEXT( schIUScale, wxEmptyString ),
|
||||
m_id( MANDATORY_FIELD_T::INVALID_FIELD ),
|
||||
m_showName( false ),
|
||||
m_allowAutoPlace( true ),
|
||||
m_isGeneratedField( false ),
|
||||
m_autoAdded( false ),
|
||||
m_showInChooser( true ),
|
||||
m_renderCacheValid( false ),
|
||||
m_lastResolvedColor( COLOR4D::UNSPECIFIED )
|
||||
{
|
||||
}
|
||||
|
||||
SCH_FIELD::SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
|
||||
const wxString& aName ) :
|
||||
SCH_ITEM( aParent, SCH_FIELD_T ),
|
||||
@@ -937,7 +951,9 @@ void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks,
|
||||
|
||||
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
|
||||
embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
|
||||
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
|
||||
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
|
||||
embeddedFilesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
mgr.SetFilesStack( embeddedFilesStack );
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ class SCH_TEXT;
|
||||
class SCH_FIELD : public SCH_ITEM, public EDA_TEXT
|
||||
{
|
||||
public:
|
||||
SCH_FIELD(); // For std::map::operator[]
|
||||
|
||||
SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
|
||||
const wxString& aName = wxEmptyString );
|
||||
|
||||
|
||||
@@ -4894,8 +4894,7 @@ void SCH_IO_ALTIUM::doEnumerateSymbolLib( const wxString& aLibraryPath,
|
||||
{
|
||||
ensureLoadedLibrary( aLibraryPath, aProperties );
|
||||
|
||||
bool powerSymbolsOnly = ( aProperties &&
|
||||
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
|
||||
bool powerSymbolsOnly = ( aProperties && aProperties->contains( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) );
|
||||
|
||||
auto it = m_libCache.find( aLibraryPath );
|
||||
|
||||
|
||||
@@ -73,9 +73,7 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
if( !m_conn )
|
||||
THROW_IO_ERROR( m_lastError );
|
||||
|
||||
bool powerSymbolsOnly = ( aProperties &&
|
||||
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) !=
|
||||
aProperties->end() );
|
||||
bool powerSymbolsOnly = ( aProperties && aProperties->contains( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) );
|
||||
|
||||
for( auto const& pair : m_nameToSymbolcache )
|
||||
{
|
||||
@@ -465,13 +463,13 @@ std::unique_ptr<LIB_SYMBOL> SCH_IO_DATABASE::loadSymbolFromRow( const wxString&
|
||||
LIB_ID libId = symbol->GetLibId();
|
||||
libId.SetSubLibraryName( aTable.name );;
|
||||
symbol->SetLibId( libId );
|
||||
wxArrayString footprintsList;
|
||||
|
||||
if( aRow.count( aTable.footprints_col ) )
|
||||
{
|
||||
std::string footprints = std::any_cast<std::string>( aRow.at( aTable.footprints_col ) );
|
||||
|
||||
wxString footprintsStr = wxString( footprints.c_str(), wxConvUTF8 );
|
||||
wxArrayString footprintsList;
|
||||
wxStringTokenizer tokenizer( footprintsStr, ';' );
|
||||
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
@@ -479,8 +477,6 @@ std::unique_ptr<LIB_SYMBOL> SCH_IO_DATABASE::loadSymbolFromRow( const wxString&
|
||||
|
||||
if( footprintsList.size() > 0 )
|
||||
symbol->GetFootprintField().SetText( footprintsList[0] );
|
||||
|
||||
symbol->SetFPFilters( footprintsList );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -509,11 +505,11 @@ std::unique_ptr<LIB_SYMBOL> SCH_IO_DATABASE::loadSymbolFromRow( const wxString&
|
||||
wxString value( std::any_cast<std::string>( aRow.at( aTable.properties.footprint_filters ) )
|
||||
.c_str(),
|
||||
wxConvUTF8 );
|
||||
wxArrayString filters;
|
||||
filters.push_back( value );
|
||||
symbol->SetFPFilters( filters );
|
||||
footprintsList.push_back( value );
|
||||
}
|
||||
|
||||
symbol->SetFPFilters( footprintsList );
|
||||
|
||||
if( !aTable.properties.exclude_from_sim.empty()
|
||||
&& aRow.count( aTable.properties.exclude_from_sim ) )
|
||||
{
|
||||
|
||||
@@ -34,13 +34,7 @@ SCH_IO_HTTP_LIB::SCH_IO_HTTP_LIB() : SCH_IO( wxS( "HTTP library" ) ), m_libTable
|
||||
}
|
||||
|
||||
|
||||
SCH_IO_HTTP_LIB::~SCH_IO_HTTP_LIB()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_HTTP_LIB::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
const wxString& aLibraryPath,
|
||||
void SCH_IO_HTTP_LIB::EnumerateSymbolLib( wxArrayString& aSymbolNameList, const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
std::vector<LIB_SYMBOL*> symbols;
|
||||
@@ -51,23 +45,17 @@ void SCH_IO_HTTP_LIB::EnumerateSymbolLib( wxArrayString& aSymbolNameList
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
void SCH_IO_HTTP_LIB::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList, const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
wxCHECK_RET( m_libTable, _( "httplib plugin missing library table handle!" ) );
|
||||
ensureSettings( aLibraryPath );
|
||||
ensureConnection();
|
||||
|
||||
if( !m_conn )
|
||||
{
|
||||
THROW_IO_ERROR( m_lastError );
|
||||
return;
|
||||
}
|
||||
|
||||
bool powerSymbolsOnly =
|
||||
( aProperties
|
||||
&& aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
|
||||
bool powerSymbolsOnly = ( aProperties && aProperties->contains( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) );
|
||||
|
||||
for( const HTTP_LIB_CATEGORY& category : m_conn->getCategories() )
|
||||
{
|
||||
@@ -121,12 +109,10 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath, const wxS
|
||||
|
||||
std::vector<HTTP_LIB_CATEGORY> categories = m_conn->getCategories();
|
||||
|
||||
if( m_conn->getCachedParts().empty() )
|
||||
{
|
||||
if( m_conn->GetCachedParts().empty() )
|
||||
syncCache();
|
||||
}
|
||||
|
||||
std::tuple relations = m_conn->getCachedParts()[partName];
|
||||
std::tuple relations = m_conn->GetCachedParts()[partName];
|
||||
std::string associatedCatID = std::get<1>( relations );
|
||||
|
||||
// get the matching category
|
||||
@@ -158,13 +144,12 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::LoadSymbol( const wxString& aLibraryPath, const wxS
|
||||
|
||||
if( m_conn->SelectOne( part_id, result ) )
|
||||
{
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbol: SelectOne (%s) found in %s" ), part_id,
|
||||
foundCategory->name );
|
||||
wxLogTrace( traceHTTPLib, wxT( "LoadSymbol: SelectOne (%s) found in %s" ), part_id, foundCategory->name );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbol: SelectOne (%s) failed for category %s" ),
|
||||
part_id, foundCategory->name );
|
||||
wxLogTrace( traceHTTPLib, wxT( "LoadSymbol: SelectOne (%s) failed for category %s" ), part_id,
|
||||
foundCategory->name );
|
||||
|
||||
THROW_IO_ERROR( m_lastError );
|
||||
}
|
||||
@@ -193,11 +178,13 @@ void SCH_IO_HTTP_LIB::GetSubLibraryNames( std::vector<wxString>& aNames )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_IO_HTTP_LIB::GetSubLibraryDescription( const wxString& aName )
|
||||
{
|
||||
return m_conn->getCategoryDescription( std::string( aName.mb_str() ) );
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_HTTP_LIB::GetAvailableSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
// TODO: Implement this sometime; This is currently broken...
|
||||
@@ -207,8 +194,7 @@ void SCH_IO_HTTP_LIB::GetAvailableSymbolFields( std::vector<wxString>& aNames )
|
||||
|
||||
void SCH_IO_HTTP_LIB::GetDefaultSymbolFields( std::vector<wxString>& aNames )
|
||||
{
|
||||
std::copy( m_defaultShownFields.begin(), m_defaultShownFields.end(),
|
||||
std::back_inserter( aNames ) );
|
||||
std::copy( m_defaultShownFields.begin(), m_defaultShownFields.end(), std::back_inserter( aNames ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -330,14 +316,14 @@ void SCH_IO_HTTP_LIB::connect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_HTTP_LIB::syncCache()
|
||||
{
|
||||
for( const HTTP_LIB_CATEGORY& category : m_conn->getCategories() )
|
||||
{
|
||||
syncCache( category );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_HTTP_LIB::syncCache( const HTTP_LIB_CATEGORY& category )
|
||||
{
|
||||
std::vector<HTTP_LIB_PART> found_parts;
|
||||
@@ -363,9 +349,9 @@ void SCH_IO_HTTP_LIB::syncCache( const HTTP_LIB_CATEGORY& category )
|
||||
}
|
||||
|
||||
|
||||
LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbolName,
|
||||
LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbolName,
|
||||
const HTTP_LIB_CATEGORY& aCategory,
|
||||
const HTTP_LIB_PART& aPart )
|
||||
const HTTP_LIB_PART& aPart )
|
||||
{
|
||||
LIB_SYMBOL* symbol = nullptr;
|
||||
LIB_SYMBOL* originalSymbol = nullptr;
|
||||
@@ -379,14 +365,11 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
|
||||
symbolId.Parse( symbolIdStr );
|
||||
|
||||
if( symbolId.IsValid() )
|
||||
{
|
||||
originalSymbol = m_libTable->LoadSymbol( symbolId );
|
||||
}
|
||||
|
||||
if( originalSymbol )
|
||||
{
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbolFromPart: found original symbol '%s'" ),
|
||||
symbolIdStr );
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbolFromPart: found original symbol '%s'" ), symbolIdStr );
|
||||
|
||||
symbol = originalSymbol->Duplicate();
|
||||
symbol->SetSourceLibId( symbolId );
|
||||
@@ -397,17 +380,13 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
|
||||
}
|
||||
else if( !symbolId.IsValid() )
|
||||
{
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "loadSymbolFromPart: source symbol id '%s' is invalid, "
|
||||
"will create empty symbol" ),
|
||||
symbolIdStr );
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbolFromPart: source symbol id '%s' is invalid, "
|
||||
"will create empty symbol" ), symbolIdStr );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "loadSymbolFromPart: source symbol '%s' not found, "
|
||||
"will create empty symbol" ),
|
||||
symbolIdStr );
|
||||
wxLogTrace( traceHTTPLib, wxT( "loadSymbolFromPart: source symbol '%s' not found, "
|
||||
"will create empty symbol" ), symbolIdStr );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,44 +405,50 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
|
||||
symbol->SetExcludedFromBoard( aPart.exclude_from_board );
|
||||
symbol->SetExcludedFromSim( aPart.exclude_from_sim );
|
||||
|
||||
SCH_FIELD* field;
|
||||
wxArrayString fp_filters;
|
||||
|
||||
for( auto& _field : aPart.fields )
|
||||
for( auto& [fieldName, fieldProperties] : aPart.fields )
|
||||
{
|
||||
wxString fieldName = wxString( _field.first );
|
||||
std::tuple fieldProperties = _field.second;
|
||||
wxString lowerFieldName = wxString( fieldName ).Lower();
|
||||
|
||||
if( fieldName.Lower() == footprint_field )
|
||||
if( lowerFieldName == footprint_field )
|
||||
{
|
||||
field = &symbol->GetFootprintField();
|
||||
SCH_FIELD* field = &symbol->GetFootprintField();
|
||||
wxStringTokenizer tokenizer( std::get<0>( fieldProperties ), ';' );
|
||||
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
fp_filters.Add( tokenizer.GetNextToken() );
|
||||
|
||||
if( fp_filters.size() > 0 )
|
||||
field->SetText( fp_filters[0] );
|
||||
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( lowerFieldName == description_field )
|
||||
{
|
||||
SCH_FIELD* field = &symbol->GetDescriptionField();
|
||||
field->SetText( std::get<0>( fieldProperties ) );
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( fieldName.Lower() == description_field )
|
||||
else if( lowerFieldName == value_field )
|
||||
{
|
||||
field = &symbol->GetDescriptionField();
|
||||
SCH_FIELD* field = &symbol->GetValueField();
|
||||
field->SetText( std::get<0>( fieldProperties ) );
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( fieldName.Lower() == value_field )
|
||||
else if( lowerFieldName == datasheet_field )
|
||||
{
|
||||
field = &symbol->GetValueField();
|
||||
SCH_FIELD* field = &symbol->GetDatasheetField();
|
||||
field->SetText( std::get<0>( fieldProperties ) );
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( fieldName.Lower() == datasheet_field )
|
||||
else if( lowerFieldName == reference_field )
|
||||
{
|
||||
field = &symbol->GetDatasheetField();
|
||||
SCH_FIELD* field = &symbol->GetReferenceField();
|
||||
field->SetText( std::get<0>( fieldProperties ) );
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( fieldName.Lower() == reference_field )
|
||||
{
|
||||
field = &symbol->GetReferenceField();
|
||||
field->SetText( std::get<0>( fieldProperties ) );
|
||||
field->SetVisible( std::get<1>( fieldProperties ) );
|
||||
}
|
||||
else if( fieldName.Lower() == keywords_field )
|
||||
else if( lowerFieldName == keywords_field )
|
||||
{
|
||||
symbol->SetKeyWords( std::get<0>( fieldProperties ) );
|
||||
}
|
||||
@@ -474,7 +459,7 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
|
||||
// This proves useful in situations where, for instance, an individual requires a particular value, such as
|
||||
// the material type showcased at a specific position for a capacitor. Subsequently, this value could be defined
|
||||
// in the symbol itself and then, potentially, be modified by the HTTP library as necessary.
|
||||
field = symbol->FindField( fieldName );
|
||||
SCH_FIELD* field = symbol->FindField( fieldName );
|
||||
|
||||
if( field != nullptr )
|
||||
{
|
||||
@@ -497,6 +482,14 @@ LIB_SYMBOL* SCH_IO_HTTP_LIB::loadSymbolFromPart( const wxString& aSymbo
|
||||
}
|
||||
}
|
||||
|
||||
symbol->SetDescription( aPart.desc );
|
||||
symbol->SetKeyWords( aPart.keywords );
|
||||
|
||||
for( const std::string& filter : aPart.fp_filters )
|
||||
fp_filters.push_back( filter );
|
||||
|
||||
symbol->SetFPFilters( fp_filters );
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SCH_IO_HTTP_LIB_H
|
||||
#define SCH_IO_HTTP_LIB_H
|
||||
#pragma once
|
||||
|
||||
#include "http_lib/http_lib_settings.h"
|
||||
#include <http_lib/http_lib_connection.h>
|
||||
@@ -40,12 +38,11 @@ class SCH_IO_HTTP_LIB : public SCH_IO
|
||||
{
|
||||
public:
|
||||
SCH_IO_HTTP_LIB();
|
||||
virtual ~SCH_IO_HTTP_LIB();
|
||||
~SCH_IO_HTTP_LIB() override = default;
|
||||
|
||||
const IO_BASE::IO_FILE_DESC GetLibraryDesc() const override
|
||||
{
|
||||
return IO_BASE::IO_FILE_DESC( _HKI( "KiCad HTTP library files" ),
|
||||
{ FILEEXT::HTTPLibraryFileExtension } );
|
||||
return IO_BASE::IO_FILE_DESC( _HKI( "KiCad HTTP library files" ), { FILEEXT::HTTPLibraryFileExtension } );
|
||||
}
|
||||
|
||||
int GetModifyHash() const override { return 0; }
|
||||
@@ -94,18 +91,15 @@ private:
|
||||
LIB_SYMBOL* loadSymbolFromPart( const wxString& aSymbolName, const HTTP_LIB_CATEGORY& aCategory,
|
||||
const HTTP_LIB_PART& aPart );
|
||||
|
||||
SYMBOL_LIB_TABLE* m_libTable;
|
||||
private:
|
||||
SYMBOL_LIB_TABLE* m_libTable;
|
||||
|
||||
/// Generally will be null if no valid connection is established
|
||||
std::unique_ptr<HTTP_LIB_CONNECTION> m_conn;
|
||||
|
||||
std::unique_ptr<HTTP_LIB_SETTINGS> m_settings;
|
||||
|
||||
std::set<wxString> m_customFields;
|
||||
|
||||
std::set<wxString> m_defaultShownFields;
|
||||
|
||||
wxString m_lastError;
|
||||
std::unique_ptr<HTTP_LIB_SETTINGS> m_settings;
|
||||
std::set<wxString> m_customFields;
|
||||
std::set<wxString> m_defaultShownFields;
|
||||
wxString m_lastError;
|
||||
|
||||
wxString symbol_field = "symbol";
|
||||
wxString footprint_field = "footprint";
|
||||
@@ -118,5 +112,3 @@ private:
|
||||
// category.id category
|
||||
std::map<std::string, HTTP_LIB_CATEGORY> m_cachedCategories;
|
||||
};
|
||||
|
||||
#endif // SCH_IO_HTTP_LIB_H_
|
||||
|
||||
@@ -2170,8 +2170,8 @@ void SCH_IO_KICAD_LEGACY::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
|
||||
|
||||
void SCH_IO_KICAD_LEGACY::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
|
||||
@@ -514,7 +514,6 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SELECTION* aSelection, SCH_SHEET_PATH* aSel
|
||||
m_schematic = &aSchematic;
|
||||
m_out = aFormatter;
|
||||
|
||||
size_t i;
|
||||
std::map<wxString, LIB_SYMBOL*> libSymbols;
|
||||
SCH_SCREEN* screen = aSelection->GetScreen();
|
||||
std::set<SCH_TABLE*> promotedTables;
|
||||
|
||||
@@ -249,7 +249,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT
|
||||
// if the unit has a display name, write that
|
||||
if( aSymbol->HasUnitDisplayName( unit.m_unit ) )
|
||||
{
|
||||
name = aSymbol->GetUnitDisplayName( unit.m_unit );
|
||||
name = aSymbol->GetUnitDisplayName( unit.m_unit, false );
|
||||
aFormatter.Print( "(unit_name %s)", aFormatter.Quotes( name ).c_str() );
|
||||
}
|
||||
|
||||
|
||||
+85
-49
@@ -50,28 +50,6 @@
|
||||
#define BITMAP_FONT_SIZE_THRESHOLD 3
|
||||
|
||||
|
||||
wxString SCH_ITEM::GetUnitDescription( int aUnit )
|
||||
{
|
||||
if( aUnit == 0 )
|
||||
return _( "All" );
|
||||
else
|
||||
return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_ITEM::GetBodyStyleDescription( int aBodyStyle )
|
||||
{
|
||||
if( aBodyStyle == 0 )
|
||||
return _( "All" );
|
||||
else if( aBodyStyle == BODY_STYLE::DEMORGAN )
|
||||
return _( "Alternate" );
|
||||
else if( aBodyStyle == BODY_STYLE::BASE )
|
||||
return _( "Standard" );
|
||||
else
|
||||
return wxT( "?" );
|
||||
}
|
||||
|
||||
|
||||
/* Constructor and destructor for SCH_ITEM */
|
||||
/* They are not inline because this creates problems with gcc at linking time in debug mode */
|
||||
|
||||
@@ -148,25 +126,52 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const
|
||||
}
|
||||
|
||||
|
||||
void SCH_ITEM::SetUnitProp( int aUnit )
|
||||
wxString SCH_ITEM::GetUnitDisplayName( int aUnit, bool aLabel ) const
|
||||
{
|
||||
if( GetParentSymbol() )
|
||||
aUnit = std::min( aUnit, GetParentSymbol()->GetUnitCount() );
|
||||
if( aUnit == 0 )
|
||||
return aLabel ? _( "All units" ) : wxString( _HKI( "All units" ) );
|
||||
else if( const SYMBOL* symbol = GetParentSymbol() )
|
||||
return symbol->GetUnitDisplayName( aUnit, aLabel );
|
||||
|
||||
aUnit = std::max( aUnit, 0 );
|
||||
|
||||
m_unit = aUnit;
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
void SCH_ITEM::SetBodyStyleProp( int aBodyStyle )
|
||||
wxString SCH_ITEM::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
|
||||
{
|
||||
if( GetParentSymbol() && GetParentSymbol()->HasAlternateBodyStyle() )
|
||||
aBodyStyle = std::min( aBodyStyle, (int) BODY_STYLE::DEMORGAN );
|
||||
if( aBodyStyle == 0 )
|
||||
return aLabel ? _( "All body styles" ) : wxString( _HKI( "All body styles" ) );
|
||||
else if( const SYMBOL* symbol = GetParentSymbol() )
|
||||
return symbol->GetBodyStyleDescription( aBodyStyle, aLabel );
|
||||
|
||||
aBodyStyle = std::max( aBodyStyle, 0 );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
m_bodyStyle = aBodyStyle;
|
||||
void SCH_ITEM::SetBodyStyleProp( const wxString& aBodyStyle )
|
||||
{
|
||||
if( aBodyStyle == _HKI( "All body styles" ) )
|
||||
{
|
||||
m_bodyStyle = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if( SYMBOL* symbol = GetParentSymbol() )
|
||||
{
|
||||
for( int bodyStyle : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
|
||||
{
|
||||
if( symbol->GetBodyStyleDescription( bodyStyle, false ) == aBodyStyle )
|
||||
{
|
||||
m_bodyStyle = bodyStyle;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_ITEM::GetBodyStyleProp() const
|
||||
{
|
||||
return GetBodyStyleDescription( m_bodyStyle, false );
|
||||
}
|
||||
|
||||
|
||||
@@ -535,23 +540,21 @@ bool SCH_ITEM::RenderAsBitmap( double aWorldScale ) const
|
||||
}
|
||||
|
||||
|
||||
void SCH_ITEM::getSymbolEditorMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
|
||||
std::vector<MSG_PANEL_ITEM>& aList )
|
||||
void SCH_ITEM::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
wxString msg;
|
||||
SYMBOL* symbol = GetParentSymbol();
|
||||
|
||||
aList.emplace_back( _( "Type" ), GetFriendlyName() );
|
||||
if( !symbol )
|
||||
return;
|
||||
|
||||
if( const SYMBOL* parent = GetParentSymbol() )
|
||||
{
|
||||
if( parent->GetUnitCount() )
|
||||
aList.emplace_back( _( "Unit" ), GetUnitDescription( m_unit ) );
|
||||
if( symbol->GetUnitCount() )
|
||||
aList.emplace_back( _( "Unit" ), GetUnitDisplayName( GetUnit(), false ) );
|
||||
|
||||
if( parent->HasAlternateBodyStyle() )
|
||||
aList.emplace_back( _( "Body Style" ), GetBodyStyleDescription( m_bodyStyle ) );
|
||||
}
|
||||
if( symbol->HasAlternateBodyStyle() )
|
||||
aList.emplace_back( _( "Body Style" ), GetBodyStyleDescription( GetBodyStyle(), true ) );
|
||||
|
||||
if( IsPrivate() )
|
||||
if( dynamic_cast<LIB_SYMBOL*>( symbol ) && IsPrivate() )
|
||||
aList.emplace_back( _( "Private" ), wxEmptyString );
|
||||
}
|
||||
|
||||
@@ -595,14 +598,47 @@ static struct SCH_ITEM_DESC
|
||||
};
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_ITEM, int>( _HKI( "Unit" ),
|
||||
&SCH_ITEM::SetUnitProp, &SCH_ITEM::GetUnit ) )
|
||||
&SCH_ITEM::SetUnit, &SCH_ITEM::GetUnit ) )
|
||||
.SetAvailableFunc( multiUnit )
|
||||
.SetIsHiddenFromDesignEditors();
|
||||
.SetIsHiddenFromDesignEditors()
|
||||
.SetChoicesFunc( []( INSPECTABLE* aItem )
|
||||
{
|
||||
wxPGChoices choices;
|
||||
choices.Add( _HKI( "All units" ), 0 );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_ITEM, int>( _HKI( "Body Style" ),
|
||||
&SCH_ITEM::SetBodyStyle, &SCH_ITEM::GetBodyStyle ) )
|
||||
if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
|
||||
{
|
||||
if( SYMBOL* symbol = item->GetParentSymbol() )
|
||||
{
|
||||
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
|
||||
choices.Add( symbol->GetUnitDisplayName( ii, false ), ii );
|
||||
}
|
||||
}
|
||||
|
||||
return choices;
|
||||
} );
|
||||
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_ITEM, wxString>( _HKI( "Body Style" ),
|
||||
&SCH_ITEM::SetBodyStyleProp, &SCH_ITEM::GetBodyStyleProp ) )
|
||||
.SetAvailableFunc( multiBodyStyle )
|
||||
.SetIsHiddenFromDesignEditors();
|
||||
.SetIsHiddenFromDesignEditors()
|
||||
.SetChoicesFunc( []( INSPECTABLE* aItem )
|
||||
{
|
||||
wxPGChoices choices;
|
||||
choices.Add( _HKI( "All body styles" ) );
|
||||
|
||||
if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
|
||||
{
|
||||
if( SYMBOL* symbol = item->GetParentSymbol() )
|
||||
{
|
||||
for( int ii : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
|
||||
choices.Add( symbol->GetBodyStyleDescription( ii, false ) );
|
||||
}
|
||||
}
|
||||
|
||||
return choices;
|
||||
} );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_ITEM, bool>( _HKI( "Private" ),
|
||||
&SCH_ITEM::SetPrivate, &SCH_ITEM::IsPrivate ) )
|
||||
|
||||
+8
-7
@@ -226,16 +226,17 @@ public:
|
||||
*/
|
||||
SCH_ITEM* Duplicate( bool doClone = false ) const;
|
||||
|
||||
static wxString GetUnitDescription( int aUnit );
|
||||
static wxString GetBodyStyleDescription( int aBodyStyle );
|
||||
|
||||
virtual void SetUnit( int aUnit ) { m_unit = aUnit; }
|
||||
int GetUnit() const { return m_unit; }
|
||||
void SetUnitProp( int aUnit );
|
||||
|
||||
virtual wxString GetUnitDisplayName( int aUnit, bool aLabel ) const;
|
||||
virtual wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const;
|
||||
|
||||
virtual void SetBodyStyle( int aBodyStyle ) { m_bodyStyle = aBodyStyle; }
|
||||
int GetBodyStyle() const { return m_bodyStyle; }
|
||||
void SetBodyStyleProp( int aBodyStyle );
|
||||
|
||||
virtual void SetBodyStyleProp( const wxString& aBodyStyle );
|
||||
virtual wxString GetBodyStyleProp() const;
|
||||
|
||||
void SetPrivate( bool aPrivate ) { m_private = aPrivate; }
|
||||
bool IsPrivate() const { return m_private; }
|
||||
@@ -593,6 +594,8 @@ public:
|
||||
|
||||
virtual void SetStroke( const STROKE_PARAMS& aStroke ) { wxCHECK( false, /* void */ ); }
|
||||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
/**
|
||||
* Print an item.
|
||||
*
|
||||
@@ -688,8 +691,6 @@ protected:
|
||||
bool operator()( const SCH_ITEM* aFirst, const SCH_ITEM* aSecond ) const;
|
||||
};
|
||||
|
||||
void getSymbolEditorMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList );
|
||||
|
||||
/**
|
||||
* Provide the draw object specific comparison called by the == and < operators.
|
||||
*
|
||||
|
||||
@@ -2274,7 +2274,7 @@ static struct SCH_LABEL_DESC
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
|
||||
return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T } );
|
||||
return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_SHEET_PIN_T } );
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -191,8 +191,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 };
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1291,6 +1291,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;
|
||||
|
||||
|
||||
+16
-69
@@ -43,32 +43,6 @@
|
||||
// small margin in internal units between the pin text and the pin line
|
||||
#define PIN_TEXT_MARGIN 4
|
||||
|
||||
wxString SCH_PIN::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
// These strings are the canonical name of the electrictal type
|
||||
// Not translated, no space in name, only ASCII chars.
|
||||
// to use when the string name must be known and well defined
|
||||
// must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
|
||||
static const wxChar* msgPinElectricType[] =
|
||||
{
|
||||
wxT( "input" ),
|
||||
wxT( "output" ),
|
||||
wxT( "bidirectional" ),
|
||||
wxT( "tri_state" ),
|
||||
wxT( "passive" ),
|
||||
wxT( "free" ),
|
||||
wxT( "unspecified" ),
|
||||
wxT( "power_in" ),
|
||||
wxT( "power_out" ),
|
||||
wxT( "open_collector" ),
|
||||
wxT( "open_emitter" ),
|
||||
wxT( "no_connect" )
|
||||
};
|
||||
|
||||
return msgPinElectricType[static_cast<int>( aType )];
|
||||
}
|
||||
|
||||
|
||||
/// Utility for getting the size of the 'internal' pin decorators (as a radius)
|
||||
/// i.e. the clock symbols (falling clock is actually external but is of
|
||||
/// the same kind)
|
||||
@@ -334,29 +308,25 @@ void SCH_PIN::SetType( ELECTRICAL_PINTYPE aType )
|
||||
|
||||
wxString SCH_PIN::GetCanonicalElectricalTypeName() const
|
||||
{
|
||||
if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
{
|
||||
if( !m_libPin )
|
||||
return GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
return ::GetCanonicalElectricalTypeName( m_type );
|
||||
|
||||
return m_libPin->GetCanonicalElectricalTypeName();
|
||||
}
|
||||
if( !m_libPin )
|
||||
return ::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
|
||||
return GetCanonicalElectricalTypeName( m_type );
|
||||
return m_libPin->GetCanonicalElectricalTypeName();
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_PIN::GetElectricalTypeName() const
|
||||
{
|
||||
if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
{
|
||||
if( !m_libPin )
|
||||
return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
|
||||
return ElectricalPinTypeGetText( m_type );
|
||||
|
||||
return m_libPin->GetElectricalTypeName();
|
||||
}
|
||||
if( !m_libPin )
|
||||
return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
|
||||
|
||||
return ElectricalPinTypeGetText( m_type );
|
||||
return m_libPin->GetElectricalTypeName();
|
||||
}
|
||||
|
||||
|
||||
@@ -1472,10 +1442,10 @@ void SCH_PIN::ChangeLength( int aLength )
|
||||
offsetX = -1 * lengthChange;
|
||||
break;
|
||||
case PIN_ORIENTATION::PIN_UP:
|
||||
offsetY = lengthChange;
|
||||
offsetY = -1 * lengthChange;
|
||||
break;
|
||||
case PIN_ORIENTATION::PIN_DOWN:
|
||||
offsetY = -1 * lengthChange;
|
||||
offsetY = lengthChange;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1594,28 +1564,9 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
|
||||
wxString msg;
|
||||
SYMBOL* symbol = GetParentSymbol();
|
||||
|
||||
if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
|
||||
{
|
||||
getSymbolEditorMsgPanelInfo( aFrame, aList );
|
||||
}
|
||||
else
|
||||
{
|
||||
aList.emplace_back( _( "Type" ), _( "Pin" ) );
|
||||
aList.emplace_back( _( "Type" ), _( "Pin" ) );
|
||||
|
||||
if( symbol->GetUnitCount() )
|
||||
{
|
||||
msg = m_libPin ? GetUnitDescription( m_libPin->GetUnit() ) :
|
||||
wxString( "Undefined library pin." );
|
||||
aList.emplace_back( _( "Unit" ), msg );
|
||||
}
|
||||
|
||||
if( symbol->HasAlternateBodyStyle() )
|
||||
{
|
||||
msg = m_libPin ? GetBodyStyleDescription( m_libPin->GetBodyStyle() ) :
|
||||
wxString( "Undefined library pin." );
|
||||
aList.emplace_back( _( "Body Style" ), msg );
|
||||
}
|
||||
}
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
|
||||
aList.emplace_back( _( "Number" ), GetShownNumber() );
|
||||
@@ -1828,11 +1779,7 @@ bool SCH_PIN::HasConnectivityChanges( const SCH_ITEM* aItem,
|
||||
|
||||
bool SCH_PIN::ConnectionPropagatesTo( const EDA_ITEM* aItem ) const
|
||||
{
|
||||
if( !m_libPin )
|
||||
return false;
|
||||
|
||||
// Reciprocal checking is done in CONNECTION_GRAPH anyway
|
||||
return m_libPin->GetType() != ELECTRICAL_PINTYPE::PT_NC;
|
||||
return GetType() != ELECTRICAL_PINTYPE::PT_NC;
|
||||
}
|
||||
|
||||
|
||||
@@ -2207,7 +2154,7 @@ static struct SCH_PIN_DESC
|
||||
.SetWriteableFunc( isSymbolEditor );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Length" ),
|
||||
&SCH_PIN::SetLength, &SCH_PIN::GetLength,
|
||||
&SCH_PIN::ChangeLength, &SCH_PIN::GetLength,
|
||||
PROPERTY_DISPLAY::PT_SIZE ) )
|
||||
.SetWriteableFunc( isSymbolEditor );
|
||||
|
||||
|
||||
@@ -523,10 +523,7 @@ void SCH_SHAPE::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBod
|
||||
|
||||
void SCH_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
if( m_layer == LAYER_DEVICE )
|
||||
getSymbolEditorMsgPanelInfo( aFrame, aList );
|
||||
else
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
ShapeGetMsgPanelInfo( aFrame, aList );
|
||||
}
|
||||
|
||||
+17
-1
@@ -45,6 +45,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>
|
||||
|
||||
@@ -1729,7 +1731,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( SHEETNAME_V, 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,
|
||||
|
||||
+60
-27
@@ -330,6 +330,8 @@ void SCH_SYMBOL::UpdatePins()
|
||||
ii->second.erase( it );
|
||||
pin->SetLibPin( libPin );
|
||||
pin->SetPosition( libPin->GetPosition() );
|
||||
pin->SetUnit( libPin->GetUnit() );
|
||||
pin->SetBodyStyle( libPin->GetBodyStyle() );
|
||||
|
||||
unassignedSchPins.erase( pin );
|
||||
|
||||
@@ -362,6 +364,8 @@ void SCH_SYMBOL::UpdatePins()
|
||||
m_pinMap[ libPin ] = pin;
|
||||
pin->SetLibPin( libPin );
|
||||
pin->SetPosition( libPin->GetPosition() );
|
||||
pin->SetUnit( libPin->GetUnit() );
|
||||
pin->SetBodyStyle( libPin->GetBodyStyle() );
|
||||
pin->SetNumber( libPin->GetNumber() );
|
||||
|
||||
auto iii = altPinMap.find( libPin->GetNumber() );
|
||||
@@ -440,19 +444,27 @@ int SCH_SYMBOL::GetUnitCount() const
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit ) const
|
||||
wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
|
||||
{
|
||||
wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) );
|
||||
|
||||
return m_part->GetUnitDisplayName( aUnit );
|
||||
if( m_part )
|
||||
return m_part->GetUnitDisplayName( aUnit, aLabel );
|
||||
else if( aLabel )
|
||||
return wxString::Format( _( "Unit %s" ), SubReference( aUnit ) );
|
||||
else
|
||||
return SubReference( aUnit );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const
|
||||
wxString SCH_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
|
||||
{
|
||||
wxCHECK( m_part, false );
|
||||
|
||||
return m_part->HasUnitDisplayName( aUnit );
|
||||
if( m_part )
|
||||
return m_part->GetBodyStyleDescription( aBodyStyle, aLabel );
|
||||
else if( aBodyStyle == BODY_STYLE::DEMORGAN )
|
||||
return aLabel ? _( "Alternate" ) : wxString( _HKI( "Alternate" ) );
|
||||
else if( aBodyStyle == BODY_STYLE::BASE )
|
||||
return aLabel ? _( "Standard" ) : wxString( _HKI( "Standard" ) );
|
||||
else
|
||||
return wxT( "?" );
|
||||
}
|
||||
|
||||
|
||||
@@ -550,8 +562,8 @@ void SCH_SYMBOL::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBo
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SYMBOL::GetInstance( SCH_SYMBOL_INSTANCE& aInstance,
|
||||
const KIID_PATH& aSheetPath, bool aTestFromEnd ) const
|
||||
bool SCH_SYMBOL::GetInstance( SCH_SYMBOL_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
|
||||
bool aTestFromEnd ) const
|
||||
{
|
||||
for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
|
||||
{
|
||||
@@ -1224,15 +1236,12 @@ std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
|
||||
if( aSheet )
|
||||
unit = GetUnitSelection( aSheet );
|
||||
|
||||
for( const std::unique_ptr<SCH_PIN>& p : m_pins )
|
||||
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
|
||||
{
|
||||
if( unit && p->GetLibPin() && p->GetLibPin()->GetUnit()
|
||||
&& ( p->GetLibPin()->GetUnit() != unit ) )
|
||||
{
|
||||
if( unit && pin->GetUnit() && pin->GetUnit() != unit )
|
||||
continue;
|
||||
}
|
||||
|
||||
pins.push_back( p.get() );
|
||||
pins.push_back( pin.get() );
|
||||
}
|
||||
|
||||
return pins;
|
||||
@@ -2084,6 +2093,11 @@ BITMAPS SCH_SYMBOL::GetMenuImage() const
|
||||
|
||||
EMBEDDED_FILES* SCH_SYMBOL::GetEmbeddedFiles()
|
||||
{
|
||||
std::unique_ptr<LIB_SYMBOL>& libSymbolRef = GetLibSymbolRef();
|
||||
|
||||
if( !libSymbolRef )
|
||||
return nullptr;
|
||||
|
||||
return GetLibSymbolRef()->GetEmbeddedFiles();
|
||||
}
|
||||
|
||||
@@ -2525,15 +2539,10 @@ bool SCH_SYMBOL::doIsConnected( const VECTOR2I& aPosition ) const
|
||||
|
||||
// Collect only pins attached to the current unit and convert.
|
||||
// others are not associated to this symbol instance
|
||||
int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
|
||||
: GetUnit();
|
||||
int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
|
||||
: GetBodyStyle();
|
||||
|
||||
if( pin_unit > 0 && pin_unit != GetUnit() )
|
||||
if( pin->GetUnit() > 0 && pin->GetUnit() != GetUnit() )
|
||||
continue;
|
||||
|
||||
if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
|
||||
if( pin->GetBodyStyle() > 0 && pin->GetBodyStyle() != GetBodyStyle() )
|
||||
continue;
|
||||
|
||||
if( pin->GetLocalPosition() == new_pos )
|
||||
@@ -2981,13 +2990,37 @@ static struct SCH_SYMBOL_DESC
|
||||
return false;
|
||||
};
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ),
|
||||
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Unit" ),
|
||||
&SCH_SYMBOL::SetUnitProp, &SCH_SYMBOL::GetUnitProp ) )
|
||||
.SetAvailableFunc( multiUnit );
|
||||
.SetAvailableFunc( multiUnit )
|
||||
.SetChoicesFunc( []( INSPECTABLE* aItem )
|
||||
{
|
||||
wxPGChoices choices;
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Body Style" ),
|
||||
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
|
||||
{
|
||||
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
|
||||
choices.Add( symbol->GetUnitDisplayName( ii, false ), ii );
|
||||
}
|
||||
|
||||
return choices;
|
||||
} );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Body Style" ),
|
||||
&SCH_SYMBOL::SetBodyStyleProp, &SCH_SYMBOL::GetBodyStyleProp ) )
|
||||
.SetAvailableFunc( multiBodyStyle );
|
||||
.SetAvailableFunc( multiBodyStyle )
|
||||
.SetChoicesFunc( []( INSPECTABLE* aItem )
|
||||
{
|
||||
wxPGChoices choices;
|
||||
|
||||
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
|
||||
{
|
||||
for( int ii : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
|
||||
choices.Add( symbol->GetBodyStyleDescription( ii, false ) );
|
||||
}
|
||||
|
||||
return choices;
|
||||
} );
|
||||
|
||||
const wxString groupAttributes = _HKI( "Attributes" );
|
||||
|
||||
|
||||
+21
-40
@@ -221,19 +221,14 @@ public:
|
||||
*/
|
||||
void UpdatePins();
|
||||
|
||||
/**
|
||||
* Return true if the given unit \a aUnit has a display name set.
|
||||
*
|
||||
* @return true if the display name of a unit is set, otherwise false.
|
||||
*/
|
||||
bool HasUnitDisplayName( int aUnit ) const;
|
||||
|
||||
/**
|
||||
* Return the display name for a given unit \a aUnit.
|
||||
*
|
||||
* @return the display name of a unit if set, or the ordinal name of the unit otherwise.
|
||||
*/
|
||||
wxString GetUnitDisplayName( int aUnit ) const;
|
||||
wxString GetUnitDisplayName( int aUnit, bool aLabel ) const override;
|
||||
|
||||
wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const override;
|
||||
|
||||
void SetBodyStyle( int aBodyStyle ) override;
|
||||
|
||||
@@ -510,6 +505,7 @@ public:
|
||||
}
|
||||
|
||||
void SetRefProp( const wxString& aRef );
|
||||
|
||||
wxString GetValueProp() const
|
||||
{
|
||||
return GetValue( false, &Schematic()->CurrentSheet(), false );
|
||||
@@ -520,47 +516,32 @@ public:
|
||||
SetValueFieldText( aRef );
|
||||
}
|
||||
|
||||
wxString GetUnitProp() const
|
||||
int GetUnitProp() const
|
||||
{
|
||||
int unit = GetUnitSelection( &Schematic()->CurrentSheet() );
|
||||
|
||||
if( HasUnitDisplayName( unit ) )
|
||||
return GetUnitDisplayName( unit );
|
||||
else
|
||||
return SubReference( unit, false );
|
||||
return GetUnitSelection( &Schematic()->CurrentSheet() );
|
||||
}
|
||||
|
||||
void SetUnitProp( const wxString& aUnit )
|
||||
void SetUnitProp( int aUnit )
|
||||
{
|
||||
for( int unit = 1; unit <= GetUnitCount(); unit++ )
|
||||
SetUnitSelection( &Schematic()->CurrentSheet(), aUnit );
|
||||
SetUnit( aUnit );
|
||||
}
|
||||
|
||||
wxString GetBodyStyleProp() const override
|
||||
{
|
||||
return GetBodyStyleDescription( GetBodyStyle(), false );
|
||||
}
|
||||
|
||||
void SetBodyStyleProp( const wxString& aBodyStyle ) override
|
||||
{
|
||||
for( int bodyStyle : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
|
||||
{
|
||||
if( HasUnitDisplayName( unit ) && GetUnitDisplayName( unit ) == aUnit )
|
||||
if( GetBodyStyleDescription( bodyStyle, false ) == aBodyStyle )
|
||||
{
|
||||
SetUnitSelection( &Schematic()->CurrentSheet(), unit );
|
||||
SetUnit( unit );
|
||||
SetBodyStyle( bodyStyle );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for( int unit = 1; unit <= GetUnitCount(); unit++ )
|
||||
{
|
||||
if( SubReference( unit, false ) == aUnit )
|
||||
{
|
||||
SetUnitSelection( &Schematic()->CurrentSheet(), unit );
|
||||
SetUnit( unit );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetBodyStyleProp() const
|
||||
{
|
||||
return GetBodyStyle();
|
||||
}
|
||||
|
||||
void SetBodyStyleProp( int aBodyStyle )
|
||||
{
|
||||
SetBodyStyle( aBodyStyle );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -580,6 +580,8 @@ void SCH_TABLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||
{
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Table" ), wxString::Format( _( "%d Columns" ), m_colCount ) );
|
||||
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -636,6 +636,8 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
if( m_excludedFromSim )
|
||||
aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) );
|
||||
|
||||
|
||||
@@ -531,6 +531,8 @@ void SCH_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text Box" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
if( m_excludedFromSim )
|
||||
aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) );
|
||||
|
||||
|
||||
@@ -913,6 +913,18 @@ const EMBEDDED_FILES* SCHEMATIC::GetEmbeddedFiles() const
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
|
||||
{
|
||||
SCH_SCREENS screens( Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
for( auto& [name, libSym] : screen->GetLibSymbols() )
|
||||
aFunction( libSym->GetEmbeddedFiles() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::set<KIFONT::OUTLINE_FONT*> SCHEMATIC::GetFonts() const
|
||||
{
|
||||
std::set<KIFONT::OUTLINE_FONT*> fonts;
|
||||
@@ -1277,6 +1289,7 @@ void SCHEMATIC::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FLAGS a
|
||||
PICKED_ITEMS_LIST* aLastChangeList )
|
||||
{
|
||||
SCHEMATIC_SETTINGS& settings = Settings();
|
||||
RefreshHierarchy();
|
||||
SCH_SHEET_LIST list = Hierarchy();
|
||||
SCH_COMMIT localCommit( aToolManager );
|
||||
|
||||
|
||||
@@ -376,6 +376,8 @@ public:
|
||||
*/
|
||||
void RemoveAllListeners();
|
||||
|
||||
void RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction ) override;
|
||||
|
||||
/**
|
||||
* Embed fonts in the schematic.
|
||||
*/
|
||||
|
||||
@@ -1756,7 +1756,8 @@ void SIM_MODEL::MigrateSimModel( T& aSymbol, const PROJECT* aProject )
|
||||
embeddedFilesStack.push_back( symbol->Schematic()->GetEmbeddedFiles() );
|
||||
}
|
||||
|
||||
embeddedFilesStack.push_back( aSymbol.GetEmbeddedFiles() );
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = aSymbol.GetEmbeddedFiles() )
|
||||
embeddedFilesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
libMgr.SetFilesStack( embeddedFilesStack );
|
||||
|
||||
|
||||
@@ -1016,6 +1016,7 @@ void SIMULATOR_FRAME_UI::OnFilterText( wxCommandEvent& aEvent )
|
||||
|
||||
void SIMULATOR_FRAME_UI::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_filter->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -1026,6 +1027,7 @@ void SIMULATOR_FRAME_UI::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1483,7 +1485,9 @@ void SIMULATOR_FRAME_UI::UpdateTunerValue( const SCH_SHEET_PATH& aSheetPath, con
|
||||
|
||||
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
|
||||
embeddedFilesStack.push_back( m_schematicFrame->Schematic().GetEmbeddedFiles() );
|
||||
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
|
||||
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
|
||||
embeddedFilesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
mgr.SetFilesStack( embeddedFilesStack );
|
||||
|
||||
|
||||
+10
-10
@@ -86,7 +86,7 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
pin->GetName(),
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,9 +101,9 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
pinName,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
aSymbol->GetUnitReference( next->GetUnit() ),
|
||||
aSymbol->GetUnitReference( pin->GetUnit() ),
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetUnitDisplayName( next->GetUnit(), false ),
|
||||
aSymbol->GetUnitDisplayName( pin->GetUnit(), false ),
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -134,8 +134,8 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
pinName,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
aSymbol->GetUnitReference( next->GetUnit() ),
|
||||
aSymbol->GetUnitReference( pin->GetUnit() ) );
|
||||
aSymbol->GetUnitDisplayName( next->GetUnit(), false ),
|
||||
aSymbol->GetUnitDisplayName( pin->GetUnit(), false ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
pinName,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -283,7 +283,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
'A' + pin->GetUnit() - 1,
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -331,7 +331,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
pinName,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -342,7 +342,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
|
||||
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
|
||||
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
|
||||
'A' + pin->GetUnit() - 1,
|
||||
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() );
|
||||
aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -314,7 +314,7 @@ SYMBOL_EDIT_FRAME::~SYMBOL_EDIT_FRAME()
|
||||
|
||||
void SYMBOL_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_boardAdapter" );
|
||||
wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_settings" );
|
||||
|
||||
SCH_BASE_FRAME::LoadSettings( GetSettings() );
|
||||
|
||||
@@ -328,7 +328,7 @@ void SYMBOL_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
|
||||
|
||||
void SYMBOL_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_boardAdapter" );
|
||||
wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME:SaveSettings with null m_settings" );
|
||||
|
||||
GetGalDisplayOptions().m_axesEnabled = true;
|
||||
|
||||
@@ -715,7 +715,7 @@ void SYMBOL_EDIT_FRAME::RebuildSymbolUnitsList()
|
||||
{
|
||||
for( int i = 0; i < m_symbol->GetUnitCount(); i++ )
|
||||
{
|
||||
wxString unitDisplayName = m_symbol->GetUnitDisplayName( i + 1 );
|
||||
wxString unitDisplayName = m_symbol->GetUnitDisplayName( i + 1, true );
|
||||
m_unitSelectBox->Append( unitDisplayName );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ void SYMBOL_VIEWER_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent )
|
||||
|
||||
for( int ii = 0; ii < unit_count; ii++ )
|
||||
{
|
||||
wxString unit = symbol->GetUnitDisplayName( ii + 1 );
|
||||
wxString unit = symbol->GetUnitDisplayName( ii + 1, true );
|
||||
m_unitChoice->Append( unit );
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
|
||||
m_changesCount = 0;
|
||||
|
||||
if( !m_matchByReference && !m_processValues && !m_processFootprints && !m_processReferences
|
||||
&& !m_processNetNames && !m_processAttributes )
|
||||
&& !m_processNetNames && !m_processAttributes && !m_processOtherFields )
|
||||
{
|
||||
m_reporter.ReportTail( _( "Select at least one property to back annotate." ),
|
||||
RPT_SEVERITY_ERROR );
|
||||
|
||||
@@ -834,8 +834,10 @@ TOOL_ACTION SCH_ACTIONS::toLabel( TOOL_ACTION_ARGS()
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( SCH_LABEL_T ) );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::toCLabel( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.InteractiveEdit.toCLabel" )
|
||||
TOOL_ACTION SCH_ACTIONS::toDLabel(TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.InteractiveEdit.toCLabel" ) // Old name based on netClass label.
|
||||
// There's no sense losing hotkey assignments, so we
|
||||
// leave it as-is)
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Change to Directive Label" ) )
|
||||
.Tooltip( _( "Change existing item to a directive label" ) )
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
static TOOL_ACTION showDeMorganAlternate;
|
||||
static TOOL_ACTION editSymbolUnit;
|
||||
static TOOL_ACTION toLabel;
|
||||
static TOOL_ACTION toCLabel;
|
||||
static TOOL_ACTION toDLabel;
|
||||
static TOOL_ACTION toHLabel;
|
||||
static TOOL_ACTION toGLabel;
|
||||
static TOOL_ACTION toText;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user