Compare commits
342 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 59091ec263 | |||
| 92fbc42214 | |||
| 00226cb0f2 | |||
| 7128f6adf0 | |||
| 38a7cb9731 | |||
| b6e7bf4768 | |||
| d600fd3498 | |||
| 48bad152bb | |||
| da80c6796d | |||
| 48d347ce45 | |||
| 76139ac110 | |||
| 1d65480097 | |||
| 338b7e4c78 | |||
| 5b64231b33 | |||
| cdaf829404 | |||
| e920cdf809 | |||
| 28ad719db6 | |||
| 83b5c5bf7f | |||
| f76678d20c | |||
| 9b46ed2449 | |||
| 70ab4c8e8d | |||
| 24d049c017 | |||
| 54c68080f5 | |||
| 16d63b7772 | |||
| 797cb2aaac | |||
| 2044fe591d | |||
| d5baea21cd | |||
| b59c334edb | |||
| bb8719b9d5 | |||
| 817c4645eb | |||
| f1462e9fd6 | |||
| 32aabaf010 | |||
| 72b7f9fe10 | |||
| 4d5b5d3791 | |||
| 4694a2622e | |||
| 92ba60628e | |||
| 2be352b9f9 | |||
| 8afb8190af | |||
| 275afdc1d5 | |||
| 3a8ad7165b | |||
| bbe70e2f67 | |||
| 4a5f74422c | |||
| 7053981835 | |||
| 895314b639 | |||
| 6253b878a0 | |||
| 5855a9ed89 | |||
| c861c31f24 | |||
| 87d55402e4 | |||
| 7168441a1b | |||
| 5d4e2aa595 | |||
| 2a91ba35c1 | |||
| 2553da38b4 | |||
| 8d8f96b094 | |||
| eb1164fc93 | |||
| a4aa447b95 | |||
| 53dbd3bb02 | |||
| 781e98acbc | |||
| ab70124b68 | |||
| c117708220 | |||
| 68d9b3cbf7 | |||
| aac4f30b7d | |||
| a2e9c0ea73 | |||
| 0f4eefc9fc | |||
| 19d9dcdd2a | |||
| 38c68b008c | |||
| 8f2060a3f6 | |||
| 837dba2419 | |||
| 2d092437f4 | |||
| c38da73151 | |||
| 37c5885946 | |||
| 2c2f69d05c | |||
| 592c2c6872 | |||
| 6b2bb4d808 | |||
| 8cd289cf69 | |||
| 30d07ac556 | |||
| 39f5c04821 | |||
| 161c7a38bc | |||
| a95360154d | |||
| 5f072eb7d5 | |||
| 1febd61583 | |||
| 0d8c066e05 | |||
| 6e6d88ec2e | |||
| 9db7a7f6f7 | |||
| 16d1a80f6e | |||
| b8ea9c59db | |||
| 962ccab3ed | |||
| 1fe956c069 | |||
| d9db4f7bfd | |||
| 0d93be0af2 | |||
| bda1f684fc | |||
| 7fdfd77422 | |||
| 49ba218264 | |||
| f117f14b58 | |||
| c143e49d94 | |||
| 627255f464 | |||
| ba90ef6c5f | |||
| 6a65f918f1 | |||
| ef419fee0a | |||
| c399b87fce | |||
| 20dffba10f | |||
| c07ac8b3db | |||
| f25d74628b | |||
| ebb3e04718 | |||
| d971cbefcb | |||
| e317818076 | |||
| f89d5f9949 | |||
| d45ce2f659 | |||
| 09a2d50e09 | |||
| d9ec998ff0 | |||
| 7563f51212 | |||
| 1101eb9f94 | |||
| 5a8845ad22 | |||
| 897ac863fc | |||
| f4080741b3 | |||
| c1018b1ff3 | |||
| e40f8f3a49 | |||
| 4bfcc42c10 | |||
| 1e5d93b54f | |||
| 75eb2b96d8 | |||
| 7a6f6d3fe9 | |||
| 117afb068f | |||
| bf61dfa008 | |||
| a2b197ad0e | |||
| 7be6d780c2 | |||
| fb6d9d7f74 | |||
| be87e71d53 | |||
| 8612010979 | |||
| b860dcb676 | |||
| eb676233fd | |||
| edacc3fbf1 | |||
| 01f56a070e | |||
| 83d1d57363 | |||
| c63230dec6 | |||
| ee1263ff53 | |||
| 1c7c0db7c7 | |||
| dc4a6732be | |||
| 3f5b65842d | |||
| ea0d9076e7 | |||
| bd97aaa63e | |||
| e811b9a2dd | |||
| 8524042352 | |||
| 5b24003f6c | |||
| 71ea56dea4 | |||
| 362eec7ee3 | |||
| c63c3d1891 | |||
| 058f6e0a9b | |||
| e3eaa50600 | |||
| f4b5b65342 | |||
| 624d88dff9 | |||
| c04a183141 | |||
| 1831e034be | |||
| 2dcff109df | |||
| 936040fe8b | |||
| 092c11b054 | |||
| 43b8adad1a | |||
| e05c8f8852 | |||
| 485e89f7a5 | |||
| 611311697e | |||
| 5bd3a9cca8 | |||
| f4d4f23876 | |||
| 827abb01a3 | |||
| 370ce6a74d | |||
| 9f2ca9b4d6 | |||
| b21f37e22f | |||
| 9dd8bc1060 | |||
| 511e862cfe | |||
| ed153bd7d7 | |||
| 6971e409bf | |||
| ea1a1a43c0 | |||
| 7890d78801 | |||
| 82631db1bb | |||
| fbc6c8f8f4 | |||
| 4e13677281 | |||
| ba276fe470 | |||
| 4d47857738 | |||
| 08c216e796 | |||
| 3d87537dd2 | |||
| 862d975c2c | |||
| 45d58fbefc | |||
| 7b7e4e1ae5 | |||
| 3f04b80ff4 | |||
| 5830cdd1c0 | |||
| 2416b28cda | |||
| 729cf7a39d | |||
| 4d56690a7e | |||
| e30128f6f5 | |||
| c4a42f28c8 | |||
| bdbbba54f9 | |||
| 80c2fb39b1 | |||
| 63506cf777 | |||
| 6c1d615f66 | |||
| c0ca2f1830 | |||
| cf5f36aac5 | |||
| cc51807241 | |||
| e1865c1178 | |||
| b81ba520f8 | |||
| edbb9c5194 | |||
| cda6aed408 | |||
| 74172612fa | |||
| 7209239a62 | |||
| 16edde8611 | |||
| 33f8bcb7c7 | |||
| fb6505d8cb | |||
| 39935311fc | |||
| 851f893e8e | |||
| bfa1661edf | |||
| 110663d214 | |||
| 847fa7f2c4 | |||
| ef798f446f | |||
| 2de1bd7a4a | |||
| 250942264b | |||
| 6818eff90e | |||
| b2eb1f829e | |||
| a60e7e27b6 | |||
| 601995c759 | |||
| 63ce2307c8 | |||
| 03bc9551c7 | |||
| c8cd214cb0 | |||
| fe11bc8330 | |||
| d0796399a2 | |||
| c2d72180f8 | |||
| 57729414e3 | |||
| b664fb7a7d | |||
| fe1a8bea8c | |||
| 3606ad725c | |||
| e8e24b372f | |||
| 3bfa5807c8 | |||
| b797735c24 | |||
| d0af5fb5fc | |||
| 5ca91c404a | |||
| 6ba7967adc | |||
| 9dfc492cb9 | |||
| 0876fed91b | |||
| 651f50a26d | |||
| 99456d4351 | |||
| 529048dac1 | |||
| be2e0cc272 | |||
| 48a776f7c5 | |||
| 43929781a2 | |||
| e02229a234 | |||
| 821fe6ea42 | |||
| e740db61f5 | |||
| a700531aba | |||
| 7d9cf00fd9 | |||
| 6127ae92a5 | |||
| f8c92e355b | |||
| f7f6ea54fe | |||
| fdfe5a813e | |||
| 636d009860 | |||
| 7d96d5940d | |||
| d3a60f7d83 | |||
| 604871518f | |||
| 5a68077f60 | |||
| 8054f1a948 | |||
| 80bf1048d0 | |||
| d85e52e9fd | |||
| e21f0ec9fb | |||
| 1adfca8f2d | |||
| f89256e51e | |||
| e98e9f72df | |||
| f8ff9705ff | |||
| e3e52d055a | |||
| 6de8b99cf2 | |||
| c9829cf9a8 | |||
| 0fc4ccf8d9 | |||
| 330b1fd733 | |||
| 455ec428f2 | |||
| 39959844e5 | |||
| d5de4bb5c7 | |||
| 6706a5c462 | |||
| 15fe2f2fd0 | |||
| c23679d9bd | |||
| f226772938 | |||
| 6a53e318e5 | |||
| 776a28a10e | |||
| 3a98eacdb9 | |||
| a8004cb161 | |||
| f00222b3a6 | |||
| 96dded48d4 | |||
| 950cccdc1c | |||
| 5b7a1a8177 | |||
| 96aa472ff9 | |||
| 0ec50e9096 | |||
| 6bc48e9ca8 | |||
| 5505add08e | |||
| 4d8297a1f6 | |||
| e1cd74dd78 | |||
| 2567f45c1d | |||
| 0ea7dabc12 | |||
| bf8c7d7697 | |||
| 891c919c23 | |||
| 375a7303c5 | |||
| e14e9cf8a9 | |||
| 4e98ce87c7 | |||
| 207820e112 | |||
| dbbecefcb9 | |||
| df8f166847 | |||
| 79ef8e14aa | |||
| 5081165611 | |||
| 3bfcaf2455 | |||
| 9e2416d2c9 | |||
| 49eecf66fe | |||
| bc3a4e4ede | |||
| 3645c3c0cc | |||
| 7902c1cc58 | |||
| 2a2781e1bc | |||
| 9510b07807 | |||
| 072c0f06cd | |||
| b75e782aef | |||
| d9fe48171b | |||
| eeee5afdfd | |||
| 790b810621 | |||
| e33bf78d96 | |||
| bd86999615 | |||
| 1b108afd0b | |||
| a8384beb6f | |||
| c44d31fcfb | |||
| d801a8689c | |||
| 4a1abd239a | |||
| 423732910d | |||
| e4ce5e5262 | |||
| 2998d31f2c | |||
| da98413f82 | |||
| f562466189 | |||
| 0deae6bdd2 | |||
| 31f8e73cf8 | |||
| e58f50602d | |||
| c870505141 | |||
| c20e81fbdd | |||
| 58d0c4112d | |||
| 1cb80e1ad0 | |||
| 2584c46c28 | |||
| 2ce96415a6 | |||
| 8eded13d96 | |||
| 069143dc05 | |||
| 9d09ce0538 | |||
| d9dd691108 | |||
| f69ebe55ad | |||
| ff604cc6a3 | |||
| 8ccc5bd8f2 | |||
| 02b1f552fd | |||
| f058dc9ed8 |
+1
-1
@@ -40,6 +40,6 @@ include:
|
||||
- local: '/.gitlab/templates.yml'
|
||||
- local: '/.gitlab/Fedora-Linux-CI.yml'
|
||||
- local: '/.gitlab/Ubuntu-20.04-CI.yml'
|
||||
- local: '/.gitlab/Windows-CI.yml'
|
||||
# - local: '/.gitlab/Windows-CI.yml'
|
||||
- local: '/.gitlab/coverity.yml'
|
||||
- local: '/.gitlab/linux-metadata-validate.yml'
|
||||
|
||||
+85
-14
@@ -1,10 +1,11 @@
|
||||
##########################################################################
|
||||
# Build KiCad on Fedora and save the results
|
||||
##########################################################################
|
||||
fedora_build_linux:
|
||||
.fedora_build_linux_base:
|
||||
stage: build
|
||||
tags:
|
||||
- kicad-fedora
|
||||
# Don't tag until we have separate CI for MRs
|
||||
# tags:
|
||||
# - kicad-fedora
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
|
||||
extends: .only_code
|
||||
interruptible: false
|
||||
@@ -22,7 +23,7 @@ fedora_build_linux:
|
||||
- cd build/linux
|
||||
- cmake
|
||||
-G Ninja
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DKICAD_STDLIB_LIGHT_DEBUG=ON
|
||||
-DKICAD_USE_OCC=ON
|
||||
-DKICAD_SPICE=ON
|
||||
@@ -42,15 +43,31 @@ fedora_build_linux:
|
||||
- build/linux/pcbnew/_pcbnew.so
|
||||
- build/linux/qa/
|
||||
- build/linux/compilation_log.txt
|
||||
exclude:
|
||||
- build/linux/**/*.o
|
||||
- build/linux/**/*.a
|
||||
|
||||
# This split is to ensure we can always use our runner for our jobs
|
||||
fedora_build_linux_kicad:
|
||||
extends: .fedora_build_linux_base
|
||||
tags:
|
||||
- kicad-fedora
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_build_linux_public:
|
||||
extends: .fedora_build_linux_base
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
|
||||
# Upload the compilation log in an easily downloadable form
|
||||
fedora_report_build_warn:
|
||||
.fedora_report_build_warn:
|
||||
stage: report
|
||||
extends: .only_code
|
||||
when: always
|
||||
needs:
|
||||
- job: fedora_build_linux
|
||||
artifacts: true
|
||||
script:
|
||||
- echo "Uploading compilation log"
|
||||
- cp build/linux/compilation_log.txt compilation_log.txt
|
||||
@@ -61,14 +78,32 @@ fedora_report_build_warn:
|
||||
paths:
|
||||
- compilation_log.txt
|
||||
|
||||
fedora_report_build_warn_kicad:
|
||||
extends: .fedora_report_build_warn
|
||||
tags:
|
||||
- kicad-fedora
|
||||
needs:
|
||||
- job: fedora_build_linux_kicad
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_report_build_warn_public:
|
||||
extends: .fedora_report_build_warn
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
|
||||
# Report on the metrics of the code
|
||||
fedora_report_metrics:
|
||||
.fedora_report_metrics:
|
||||
stage: report
|
||||
extends: .only_code
|
||||
when: always
|
||||
needs:
|
||||
- job: fedora_build_linux
|
||||
artifacts: true
|
||||
script:
|
||||
- cat build/linux/compilation_log.txt | { grep "warning:" || test $? = 1; } | awk 'END{print "number_of_fedora_warnings "NR}' > metrics.txt
|
||||
- cat metrics.txt
|
||||
@@ -76,11 +111,30 @@ fedora_report_metrics:
|
||||
reports:
|
||||
metrics: metrics.txt
|
||||
|
||||
fedora_report_metrics_kicad:
|
||||
extends: .fedora_report_metrics
|
||||
tags:
|
||||
- kicad-fedora
|
||||
needs:
|
||||
- job: fedora_build_linux_kicad
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_report_metrics_public:
|
||||
extends: .fedora_report_metrics
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
##########################################################################
|
||||
# Run the code unit tests.
|
||||
##########################################################################
|
||||
fedora_qa:
|
||||
.fedora_qa:
|
||||
extends:
|
||||
- .unit_test
|
||||
- .only_code
|
||||
@@ -88,6 +142,23 @@ fedora_qa:
|
||||
matrix:
|
||||
# The name of the test without the qa_ prefix
|
||||
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
|
||||
|
||||
fedora_qa_kicad:
|
||||
extends: .fedora_qa
|
||||
tags:
|
||||
- kicad-fedora
|
||||
needs:
|
||||
- job: fedora_build_linux
|
||||
- job: fedora_build_linux_kicad
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_qa_public:
|
||||
extends: .fedora_qa
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
@@ -194,12 +194,13 @@ S3D_CACHE::S3D_CACHE()
|
||||
|
||||
S3D_CACHE::~S3D_CACHE()
|
||||
{
|
||||
COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
|
||||
|
||||
FlushCache();
|
||||
|
||||
// We'll delete ".3dc" cache files older than this many days
|
||||
int clearCacheInterval = commonSettings->m_System.clear_3d_cache_interval;
|
||||
int clearCacheInterval = 0;
|
||||
|
||||
if( Pgm().GetCommonSettings() )
|
||||
clearCacheInterval = Pgm().GetCommonSettings()->m_System.clear_3d_cache_interval;
|
||||
|
||||
// An interval of zero means the user doesn't want to ever clear the cache
|
||||
|
||||
|
||||
@@ -493,15 +493,10 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint,
|
||||
{
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
if( !pad->IsOnLayer( aLayerId ) )
|
||||
if( !pad->FlashLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
// NPTH pads are not drawn on layers if the
|
||||
// shape size and pos is the same as their hole:
|
||||
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
|
||||
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
|
||||
{
|
||||
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
|
||||
@@ -526,19 +521,28 @@ void BOARD_ADAPTER::addPadsWithClearance( const FOOTPRINT* aFootprint,
|
||||
}
|
||||
}
|
||||
|
||||
const bool isPlated = ( ( aLayerId == F_Cu ) && pad->FlashLayer( F_Mask ) ) ||
|
||||
( ( aLayerId == B_Cu ) && pad->FlashLayer( B_Mask ) );
|
||||
|
||||
if( aSkipPlatedPads && isPlated )
|
||||
continue;
|
||||
|
||||
if( aSkipNonPlatedPads && !isPlated )
|
||||
continue;
|
||||
|
||||
wxSize margin( aInflateValue, aInflateValue );
|
||||
|
||||
switch( aLayerId )
|
||||
{
|
||||
case F_Cu:
|
||||
if( aSkipPlatedPads && pad->FlashLayer( F_Mask ) )
|
||||
continue;
|
||||
|
||||
if( aSkipNonPlatedPads && !pad->FlashLayer( F_Mask ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case B_Cu:
|
||||
if( aSkipPlatedPads && pad->FlashLayer( B_Mask ) )
|
||||
continue;
|
||||
|
||||
if( aSkipNonPlatedPads && !pad->FlashLayer( B_Mask ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case F_Mask:
|
||||
case B_Mask:
|
||||
margin.x += pad->GetSolderMaskMargin();
|
||||
|
||||
@@ -549,7 +549,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPadsWithClearance( footprint, m_platedPadsFront, F_Cu, 0, true, false, true );
|
||||
|
||||
addPadsWithClearance( footprint, m_platedPadsBack, B_Cu, 0, true, false, true );
|
||||
}
|
||||
|
||||
@@ -569,8 +568,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// Add pads to polygon list
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad
|
||||
// has same shape as its hole
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad has same shape as
|
||||
// its hole
|
||||
footprint->TransformPadsWithClearanceToPolygon( *layerPoly, curr_layer_id,
|
||||
0, ARC_HIGH_DEF, ERROR_INSIDE,
|
||||
true, renderPlatedPadsAsPlated,
|
||||
|
||||
@@ -374,6 +374,22 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
|
||||
}
|
||||
|
||||
|
||||
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayerId )
|
||||
{
|
||||
float layer_z_bot = 0.0f;
|
||||
float layer_z_top = 0.0f;
|
||||
|
||||
getLayerZPos( aLayerId, layer_z_top, layer_z_bot );
|
||||
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( 1 );
|
||||
|
||||
// store in a list so it will be latter deleted
|
||||
m_triangles.push_back( layerTriangles );
|
||||
|
||||
return new OPENGL_RENDER_LIST( *layerTriangles, m_circleTexture, layer_z_bot, layer_z_top );
|
||||
}
|
||||
|
||||
|
||||
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardPoly,
|
||||
const BVH_CONTAINER_2D* aThroughHoles )
|
||||
{
|
||||
@@ -388,9 +404,8 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardP
|
||||
|
||||
if( listBoardObject2d.size() > 0 )
|
||||
{
|
||||
// We will set a unitary Z so it will in future used with transformations
|
||||
// since the board poly will be used not only to draw itself but also the
|
||||
// solder mask layers.
|
||||
// We will set a unitary Z so it will in future used with transformations since the
|
||||
// board poly will be used not only to draw itself but also the solder mask layers.
|
||||
const float layer_z_top = 1.0f;
|
||||
const float layer_z_bot = 0.0f;
|
||||
|
||||
@@ -563,7 +578,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
const BVH_CONTAINER_2D* container2d = ii.second;
|
||||
|
||||
SHAPE_POLY_SET polyListSubtracted;
|
||||
SHAPE_POLY_SET* aPolyList = nullptr;
|
||||
SHAPE_POLY_SET* polyList = nullptr;
|
||||
|
||||
// Load the vertical (Z axis) component of shapes
|
||||
|
||||
@@ -580,9 +595,8 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract(
|
||||
m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) )
|
||||
@@ -600,10 +614,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
}
|
||||
}
|
||||
|
||||
aPolyList = &polyListSubtracted;
|
||||
polyList = &polyListSubtracted;
|
||||
}
|
||||
|
||||
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, aPolyList, layer_id,
|
||||
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer_id,
|
||||
&m_boardAdapter.GetThroughHoleIds() );
|
||||
|
||||
if( oglList != nullptr )
|
||||
@@ -626,6 +640,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(),
|
||||
&polySubtracted, F_Cu );
|
||||
|
||||
// An entry for F_Cu must exist in m_layers or we'll never look at m_platedPadsFront
|
||||
if( m_layers.count( F_Cu ) == 0 )
|
||||
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
||||
}
|
||||
|
||||
if( m_boardAdapter.GetBackPlatedPadPolys() )
|
||||
@@ -640,6 +658,10 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(),
|
||||
&polySubtracted, B_Cu );
|
||||
|
||||
// An entry for B_Cu must exist in m_layers or we'll never look at m_platedPadsBack
|
||||
if( m_layers.count( B_Cu ) == 0 )
|
||||
m_layers[B_Cu] = generateEmptyLayerList( B_Cu );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -650,6 +650,7 @@ GLuint OPENGL_RENDER_LIST::generate_top_or_bot_seg_ends(
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glDisable( GL_ALPHA_TEST );
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
@@ -504,7 +504,7 @@ void RENDER_3D_OPENGL::setCopperMaterial()
|
||||
void RENDER_3D_OPENGL::setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id )
|
||||
{
|
||||
glEnable( GL_POLYGON_OFFSET_FILL );
|
||||
glPolygonOffset(-0.1f, -2.0f );
|
||||
glPolygonOffset( -0.1f, -2.0f );
|
||||
setLayerMaterial( aLayer_id );
|
||||
}
|
||||
|
||||
@@ -704,18 +704,16 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
{
|
||||
pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
|
||||
|
||||
// Draw copper plated pads
|
||||
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
|
||||
( m_platedPadsFront || m_platedPadsBack ) )
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
|
||||
// Draw plated pads
|
||||
if( layer_id == F_Cu && m_platedPadsFront )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsFront->DrawAllCameraCulled( m_camera.GetPos().z,
|
||||
drawMiddleSegments );
|
||||
}
|
||||
else if( layer_id == B_Cu && m_platedPadsBack )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsBack->DrawAllCameraCulled( m_camera.GetPos().z,
|
||||
drawMiddleSegments );
|
||||
}
|
||||
@@ -751,16 +749,10 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
viasHolesLayer,
|
||||
m_antiBoard );
|
||||
|
||||
// Draw copper plated pads
|
||||
|
||||
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
|
||||
( m_platedPadsFront || m_platedPadsBack ) )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
}
|
||||
|
||||
// Draw plated pads
|
||||
if( layer_id == F_Cu && m_platedPadsFront )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsFront->DrawAllCameraCulledSubtractLayer(
|
||||
drawMiddleSegments,
|
||||
m_outerThroughHoles,
|
||||
@@ -769,6 +761,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
}
|
||||
else if( layer_id == B_Cu && m_platedPadsBack )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsBack->DrawAllCameraCulledSubtractLayer(
|
||||
drawMiddleSegments,
|
||||
m_outerThroughHoles,
|
||||
@@ -785,21 +778,16 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
m_outerThroughHoles,
|
||||
m_antiBoard );
|
||||
|
||||
// Draw copper plated pads
|
||||
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
|
||||
( m_platedPadsFront || m_platedPadsBack ) )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
}
|
||||
|
||||
if( layer_id == F_Cu && m_platedPadsFront )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsFront->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
|
||||
m_outerThroughHoles,
|
||||
m_antiBoard );
|
||||
}
|
||||
else if( layer_id == B_Cu && m_platedPadsBack )
|
||||
{
|
||||
setPlatedCopperAndDepthOffset( layer_id );
|
||||
m_platedPadsBack->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
|
||||
m_outerThroughHoles,
|
||||
m_antiBoard );
|
||||
@@ -938,7 +926,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_CONSTANT );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
|
||||
|
||||
render3dModels( false, true );
|
||||
render3dModels( true, true );
|
||||
|
||||
@@ -84,6 +84,8 @@ private:
|
||||
PCB_LAYER_ID aLayerId,
|
||||
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
||||
|
||||
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayerId );
|
||||
|
||||
void addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, const SFVEC2F& v0,
|
||||
const SFVEC2F& v1, const SFVEC2F& v2, float top, float bot );
|
||||
|
||||
|
||||
+11
-9
@@ -779,12 +779,6 @@ set( INC_AFTER
|
||||
find_package( SWIG 3.0 REQUIRED )
|
||||
include( ${SWIG_USE_FILE} )
|
||||
|
||||
# pybind11 is header-only, so include the subdir
|
||||
add_subdirectory(thirdparty/pybind11)
|
||||
|
||||
# Make sure that we get our pybind11 and not the system pybind11 (ours is patched to work with wx)
|
||||
include_directories( BEFORE SYSTEM ${PYBIND11_INCLUDE_DIR} )
|
||||
|
||||
set( PythonInterp_FIND_VERSION 3.6 )
|
||||
set( PythonLibs_FIND_VERSION 3.6 )
|
||||
|
||||
@@ -826,6 +820,12 @@ message( STATUS "Python module install path: ${PYTHON_DEST}" )
|
||||
|
||||
find_package( PythonLibs 3.6 REQUIRED )
|
||||
|
||||
# pybind11 is header-only, so include the subdir
|
||||
add_subdirectory(thirdparty/pybind11)
|
||||
|
||||
# Make sure that we get our pybind11 and not the system pybind11 (ours is patched to work with wx)
|
||||
include_directories( BEFORE SYSTEM ${PYBIND11_INCLUDE_DIR} )
|
||||
|
||||
# Infrequently needed headers go at end of search paths, append to INC_AFTER which
|
||||
# although is used for all components, should be a harmless hit for something like eeschema
|
||||
# so long as unused search paths are at the end like this.
|
||||
@@ -848,9 +848,11 @@ if( UNIX AND NOT APPLE AND KICAD_SCRIPTING_WXPYTHON )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message( STATUS "Found ${WXPYTHON_FLAVOR} "
|
||||
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
|
||||
"(wxWidgets ${WXPYTHON_WXVERSION})" )
|
||||
if( WXPYTHON_FLAVOR )
|
||||
message( STATUS "Found wxPython ${WXPYTHON_FLAVOR} "
|
||||
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
|
||||
"(wxWidgets ${WXPYTHON_WXVERSION})" )
|
||||
endif()
|
||||
|
||||
#
|
||||
# Find wxWidgets library, required
|
||||
|
||||
@@ -75,11 +75,15 @@ if( ${PYTHON_ROOT_DIR} )
|
||||
find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES}
|
||||
PATHS ${PYTHON_ROOT_DIR}
|
||||
NO_DEFAULT_PATH )
|
||||
elseif(VCPKG_TOOLCHAIN)
|
||||
# Our VCPKG usage will always place it in a known location
|
||||
find_program(PYTHON_EXECUTABLE
|
||||
NAMES ${_Python_NAMES}
|
||||
PATHS "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/python3"
|
||||
)
|
||||
else()
|
||||
if(NOT VCPKG_TOOLCHAIN)
|
||||
# If there is no specific path given, look for python in the path
|
||||
find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES})
|
||||
endif()
|
||||
# If there is no specific path given, look for python in the path
|
||||
find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES})
|
||||
endif()
|
||||
|
||||
# Set up the versions we know about, in the order we will search. Always add
|
||||
@@ -112,8 +116,6 @@ if(NOT PYTHON_EXECUTABLE)
|
||||
list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.2" )
|
||||
list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.1" )
|
||||
list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.0" )
|
||||
elseif(VCPKG_TOOLCHAIN)
|
||||
list( APPEND _Python_PPATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/python3" )
|
||||
else()
|
||||
list( APPEND _Python_PPATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath] )
|
||||
endif()
|
||||
|
||||
@@ -40,7 +40,7 @@ if( VCPKG_TOOLCHAIN )
|
||||
# python 3.8+ requires us to use python to add additional load directories (PATH no longer supported)
|
||||
# vcpkg does not copy all the dlls into the python folder so we need this for development
|
||||
# as the wxpython modules need the wxwidgets library DLLs to load
|
||||
set( _py_dll "import os;os.add_dll_directory(\"${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin\");os.add_dll_directory(\"${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin\");" )
|
||||
set( _py_dll "import os;os.add_dll_directory(\"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin\");os.add_dll_directory(\"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin\");" )
|
||||
else()
|
||||
set( _py_dll "" )
|
||||
endif()
|
||||
|
||||
@@ -231,11 +231,7 @@ endif()
|
||||
#=====================================================================
|
||||
if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
# Useful common wx libs needed by almost all components.
|
||||
if(VCPKG_TOOLCHAIN)
|
||||
set(wxWidgets_COMMON_LIBRARIES libpng16 tiff jpeg zlib libexpat)
|
||||
else()
|
||||
set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
|
||||
endif()
|
||||
set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
|
||||
|
||||
# DEPRECATED: Use find_package(wxWidgets COMPONENTS mono) instead.
|
||||
if(NOT wxWidgets_FIND_COMPONENTS)
|
||||
@@ -258,22 +254,24 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
#-------------------------------------------------------------------
|
||||
#
|
||||
# Get filename components for a configuration. For example,
|
||||
# if _CONFIGURATION = mswunivud, then _UNV=univ, _UCD=u _DBG=d
|
||||
# if _CONFIGURATION = mswu, then _UNV="", _UCD=u _DBG=""
|
||||
# if _CONFIGURATION = mswunivud, then _PF="msw", _UNV=univ, _UCD=u _DBG=d
|
||||
# if _CONFIGURATION = mswu, then _PF="msw", _UNV="", _UCD=u _DBG=""
|
||||
#
|
||||
macro(WX_GET_NAME_COMPONENTS _CONFIGURATION _UNV _UCD _DBG)
|
||||
macro(WX_GET_NAME_COMPONENTS _CONFIGURATION _PF _UNV _UCD _DBG)
|
||||
DBG_MSG_V(${_CONFIGURATION})
|
||||
string(REGEX MATCH "univ" ${_UNV} "${_CONFIGURATION}")
|
||||
string(REGEX REPLACE "msw.*(u)[d]*$" "u" ${_UCD} "${_CONFIGURATION}")
|
||||
string(REGEX REPLACE "[msw|qt].*(u)[d]*$" "u" ${_UCD} "${_CONFIGURATION}")
|
||||
if(${_UCD} STREQUAL ${_CONFIGURATION})
|
||||
set(${_UCD} "")
|
||||
endif()
|
||||
string(REGEX MATCH "d$" ${_DBG} "${_CONFIGURATION}")
|
||||
string(REGEX MATCH "^[msw|qt]*" ${_PF} "${_CONFIGURATION}")
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# Find libraries associated to a configuration.
|
||||
#
|
||||
macro(WX_FIND_LIBS _UNV _UCD _DBG)
|
||||
macro(WX_FIND_LIBS _PF _UNV _UCD _DBG)
|
||||
DBG_MSG_V("m_unv = ${_UNV}")
|
||||
DBG_MSG_V("m_ucd = ${_UCD}")
|
||||
DBG_MSG_V("m_dbg = ${_DBG}")
|
||||
@@ -286,7 +284,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
NAMES
|
||||
wx${LIB}${_UCD}${_DBG} # for regex
|
||||
wx${LIB}${_DBG}
|
||||
${LIB}${_DBG} # vcpkg libraries aren't specific to wx
|
||||
PATHS ${WX_LIB_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
@@ -326,13 +323,13 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
# Find wxWidgets monolithic library.
|
||||
find_library(WX_mono${_DBG}
|
||||
NAMES
|
||||
wxmsw${_UNV}31${_UCD}${_DBG}
|
||||
wxmsw${_UNV}30${_UCD}${_DBG}
|
||||
wxmsw${_UNV}29${_UCD}${_DBG}
|
||||
wxmsw${_UNV}28${_UCD}${_DBG}
|
||||
wxmsw${_UNV}27${_UCD}${_DBG}
|
||||
wxmsw${_UNV}26${_UCD}${_DBG}
|
||||
wxmsw${_UNV}25${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}31${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}30${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}29${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}28${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}27${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}26${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}25${_UCD}${_DBG}
|
||||
PATHS ${WX_LIB_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
@@ -340,16 +337,16 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
|
||||
# Find wxWidgets multilib libraries.
|
||||
foreach(LIB core adv aui html media xrc dbgrid gl qa richtext
|
||||
webview stc ribbon propgrid)
|
||||
stc ribbon propgrid webview)
|
||||
find_library(WX_${LIB}${_DBG}
|
||||
NAMES
|
||||
wxmsw${_UNV}31${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}30${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}29${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}28${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}27${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}26${_UCD}${_DBG}_${LIB}
|
||||
wxmsw${_UNV}25${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}31${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}30${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}29${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}28${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}27${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}26${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}25${_UCD}${_DBG}_${LIB}
|
||||
PATHS ${WX_LIB_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
@@ -515,74 +512,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
set(WX_LIB_DIR_PREFIX vc)
|
||||
endif()
|
||||
|
||||
if(VCPKG_TOOLCHAIN)
|
||||
set(wxWidgets_FOUND TRUE)
|
||||
find_path(wxWidgets_ROOT_DIR
|
||||
NAMES include/wx/wx.h
|
||||
PATHS
|
||||
ENV wxWidgets_ROOT_DIR
|
||||
DOC "wxWidgets base/installation directory"
|
||||
)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(wxWidgets_LIB_DIR ${wxWidgets_ROOT_DIR}/debug/lib)
|
||||
set(wxWidgets_CONFIGURATION mswud)
|
||||
else()
|
||||
set(wxWidgets_LIB_DIR ${wxWidgets_ROOT_DIR}/lib)
|
||||
set(wxWidgets_CONFIGURATION mswu)
|
||||
endif()
|
||||
|
||||
set(wxWidgets_BIN_DIR ${wxWidgets_ROOT_DIR}/bin)
|
||||
set(wxWidgets_INCLUDE_DIR ${wxWidgets_ROOT_DIR}/include)
|
||||
file(GLOB DLL ${wxWidgets_BIN_DIR}/wxmsw*.dll)
|
||||
if (DLL)
|
||||
set(wxWidgets_DEFINITIONS WXUSINGDLL)
|
||||
DBG_MSG_V("detected SHARED/DLL tree wxWidgets_LIB_DIR=${wxWidgets_LIB_DIR}")
|
||||
endif ()
|
||||
set(WX_ROOT_DIR ${wxWidgets_ROOT_DIR})
|
||||
set(WX_LIB_DIR ${wxWidgets_LIB_DIR}) # needed by macro
|
||||
set(WX_CONFIGURATION_LIST ${wxWidgets_CONFIGURATION})
|
||||
|
||||
# Set wxWidgets lib setup include directory.
|
||||
if (EXISTS ${wxWidgets_INCLUDE_DIR}/wx/setup.h)
|
||||
set(wxWidgets_INCLUDE_DIRS ${wxWidgets_INCLUDE_DIR})
|
||||
else ()
|
||||
DBG_MSG("wxWidgets_FOUND FALSE because ${wxWidgets_INCLUDE_DIR}/wx/setup.h does not exists.")
|
||||
set(wxWidgets_FOUND FALSE)
|
||||
endif ()
|
||||
|
||||
# Set wxWidgets main include directory.
|
||||
if (EXISTS ${wxWidgets_ROOT_DIR}/include/wx/wx.h)
|
||||
list(APPEND wxWidgets_INCLUDE_DIRS ${wxWidgets_ROOT_DIR}/include)
|
||||
else ()
|
||||
DBG_MSG("wxWidgets_FOUND FALSE because wxWidgets_ROOT_DIR=${wxWidgets_ROOT_DIR} has no ${wxWidgets_ROOT_DIR}/include/wx/wx.h")
|
||||
set(wxWidgets_FOUND FALSE)
|
||||
endif ()
|
||||
|
||||
DBG_MSG_V("WX_CONFIGURATION_LIST=${WX_CONFIGURATION_LIST}")
|
||||
|
||||
|
||||
# Get configuration parameters from the name.
|
||||
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} UNV UCD DBG)
|
||||
|
||||
|
||||
# Find wxWidgets libraries.
|
||||
WX_FIND_LIBS("${UNV}" "${UCD}" "${DBG}")
|
||||
if (WX_USE_REL_AND_DBG)
|
||||
WX_FIND_LIBS("${UNV}" "${UCD}" "d")
|
||||
endif ()
|
||||
|
||||
# Settings for requested libs (i.e., include dir, libraries, etc.).
|
||||
WX_SET_LIBRARIES(wxWidgets_FIND_COMPONENTS "${DBG}")
|
||||
|
||||
# Add necessary definitions for unicode builds
|
||||
if ("${UCD}" STREQUAL "u")
|
||||
list(APPEND wxWidgets_DEFINITIONS UNICODE _UNICODE)
|
||||
endif ()
|
||||
|
||||
# Add necessary definitions for debug builds
|
||||
set(wxWidgets_DEFINITIONS_DEBUG _DEBUG __WXDEBUG__)
|
||||
|
||||
else()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
find_path(wxWidgets_LIB_DIR
|
||||
NAMES
|
||||
@@ -617,7 +546,6 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
DOC "Path to wxWidgets libraries"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If wxWidgets_LIB_DIR changed, clear all libraries.
|
||||
@@ -675,7 +603,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
endif()
|
||||
|
||||
# Get configuration parameters from the name.
|
||||
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} UNV UCD DBG)
|
||||
WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} PF UNV UCD DBG)
|
||||
|
||||
# Set wxWidgets lib setup include directory.
|
||||
if(EXISTS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h)
|
||||
@@ -695,9 +623,9 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
endif()
|
||||
|
||||
# Find wxWidgets libraries.
|
||||
WX_FIND_LIBS("${UNV}" "${UCD}" "${DBG}")
|
||||
WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "${DBG}")
|
||||
if(WX_USE_REL_AND_DBG)
|
||||
WX_FIND_LIBS("${UNV}" "${UCD}" "d")
|
||||
WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "d")
|
||||
endif()
|
||||
|
||||
# Settings for requested libs (i.e., include dir, libraries, etc.).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.4" )
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.6" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -158,7 +158,6 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
|
||||
|
||||
wxMemoryInputStream is( data, count );
|
||||
wxImage image( is, wxBITMAP_TYPE_PNG );
|
||||
wxBitmap bitmap( image );
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -152,9 +152,8 @@ wxString DS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
|
||||
}
|
||||
else if( m_titleBlock )
|
||||
{
|
||||
m_titleBlock->TextVarResolver( token, m_project );
|
||||
// no need for tokenUpdated; TextVarResolver() did a full resolve
|
||||
return true;
|
||||
return m_titleBlock->TextVarResolver( token, m_project );
|
||||
}
|
||||
|
||||
if( tokenUpdated )
|
||||
|
||||
+1
-6
@@ -71,19 +71,14 @@ static const wxFileTypeInfo EDAfallbacks[] =
|
||||
};
|
||||
|
||||
|
||||
bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT* aProject )
|
||||
bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT* aProject, SEARCH_STACK* aPaths )
|
||||
{
|
||||
SEARCH_STACK* aPaths = nullptr;
|
||||
wxString docname;
|
||||
wxString fullfilename;
|
||||
wxString msg;
|
||||
wxString command;
|
||||
bool success = false;
|
||||
|
||||
#if defined( EESCHEMA )
|
||||
SEARCH_STACK* aPaths = aProject ? aProject->SchSearchS() : nullptr;
|
||||
#endif
|
||||
|
||||
// Is an internet url
|
||||
static const std::vector<wxString> url_header =
|
||||
{
|
||||
|
||||
@@ -387,6 +387,9 @@ void EDA_DRAW_FRAME::OnSelectGrid( wxCommandEvent& event )
|
||||
|
||||
UpdateStatusBar();
|
||||
m_canvas->Refresh();
|
||||
// Needed on Windows because clicking on m_gridSelectBox remove the focus from m_canvas
|
||||
// (Windows specific
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
@@ -463,6 +466,9 @@ void EDA_DRAW_FRAME::OnSelectZoom( wxCommandEvent& event )
|
||||
m_toolManager->RunAction( ACTIONS::zoomPreset, true, static_cast<intptr_t>( id ) );
|
||||
UpdateStatusBar();
|
||||
m_canvas->Refresh();
|
||||
// Needed on Windows because clicking on m_zoomSelectBox remove the focus from m_canvas
|
||||
// (Windows specific
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
@@ -694,7 +700,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
|
||||
|
||||
void EDA_DRAW_FRAME::UpdateMsgPanel()
|
||||
{
|
||||
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
|
||||
GetToolManager()->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -320,6 +320,7 @@ static struct EDA_ITEM_DESC
|
||||
.Map( PCB_FP_SHAPE_T, _HKI( "Graphic" ) )
|
||||
.Map( PCB_FP_ZONE_T, _HKI( "Zone" ) )
|
||||
.Map( PCB_TRACE_T, _HKI( "Track" ) )
|
||||
.Map( PCB_ARC_T, _HKI( "Track" ) )
|
||||
.Map( PCB_VIA_T, _HKI( "Via" ) )
|
||||
.Map( PCB_MARKER_T, _HKI( "Marker" ) )
|
||||
.Map( PCB_DIM_ALIGNED_T, _HKI( "Dimension" ) )
|
||||
|
||||
+13
-1
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -165,6 +165,18 @@ void FILE_HISTORY::doAddClearItem( wxMenu* aMenu )
|
||||
}
|
||||
|
||||
|
||||
void FILE_HISTORY::UpdateClearText( wxMenu* aMenu, wxString aClearText )
|
||||
{
|
||||
size_t itemPos;
|
||||
wxMenuItem* clearItem = aMenu->FindChildItem( m_clearId, &itemPos );
|
||||
|
||||
if( clearItem && itemPos > 1 ) // clearItem is the last menu, after a separator
|
||||
{
|
||||
clearItem->SetItemLabel( aClearText );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FILE_HISTORY::ClearFileHistory()
|
||||
{
|
||||
while( GetCount() > 0 )
|
||||
|
||||
+8
-2
@@ -40,8 +40,14 @@
|
||||
// boost:mt19937 is not thread-safe
|
||||
static std::mutex rng_mutex;
|
||||
|
||||
// Create only once, as seeding is *very* expensive
|
||||
static boost::mt19937 rng;
|
||||
// Static rng and generators are used because the overhead of constant seeding is expensive
|
||||
// We break out the rng separately from the generator because we want to control seeding in cases like unit tests
|
||||
#if BOOST_VERSION >= 106700
|
||||
static boost::uuids::detail::random_provider seeder; // required to ensure the rng has a random initial seed
|
||||
#else
|
||||
static boost::uuids::detail::seed_rng seeder; // required to ensure the rng has a random initial seed
|
||||
#endif
|
||||
static boost::mt19937 rng( seeder );
|
||||
static boost::uuids::basic_random_generator<boost::mt19937> randomGenerator( rng );
|
||||
|
||||
// These don't have the same performance penalty, but we might as well be consistent
|
||||
|
||||
+63
-60
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -23,79 +23,82 @@
|
||||
/**
|
||||
* Returns the default display name for a given layer. These are not the same as the canonical
|
||||
* name in LSET::Name(), which is used in board files and cannot be translated or changed.
|
||||
* WARNING: do not translate board physical layers names (F.Cu to User.9): because canonical names
|
||||
* are used in files (boards and fab files), using translated names in UI create mistakes for users.
|
||||
* Board physical layers names must be seen as proper nouns.
|
||||
*/
|
||||
wxString LayerName( int aLayer )
|
||||
{
|
||||
switch( aLayer )
|
||||
{
|
||||
// PCB_LAYER_ID
|
||||
case F_Cu: return _( "F.Cu" );
|
||||
case In1_Cu: return _( "In1.Cu" );
|
||||
case In2_Cu: return _( "In2.Cu" );
|
||||
case In3_Cu: return _( "In3.Cu" );
|
||||
case In4_Cu: return _( "In4.Cu" );
|
||||
case In5_Cu: return _( "In5.Cu" );
|
||||
case In6_Cu: return _( "In6.Cu" );
|
||||
case In7_Cu: return _( "In7.Cu" );
|
||||
case In8_Cu: return _( "In8.Cu" );
|
||||
case In9_Cu: return _( "In9.Cu" );
|
||||
case In10_Cu: return _( "In10.Cu" );
|
||||
case In11_Cu: return _( "In11.Cu" );
|
||||
case In12_Cu: return _( "In12.Cu" );
|
||||
case In13_Cu: return _( "In13.Cu" );
|
||||
case In14_Cu: return _( "In14.Cu" );
|
||||
case In15_Cu: return _( "In15.Cu" );
|
||||
case In16_Cu: return _( "In16.Cu" );
|
||||
case In17_Cu: return _( "In17.Cu" );
|
||||
case In18_Cu: return _( "In18.Cu" );
|
||||
case In19_Cu: return _( "In19.Cu" );
|
||||
case In20_Cu: return _( "In20.Cu" );
|
||||
case In21_Cu: return _( "In21.Cu" );
|
||||
case In22_Cu: return _( "In22.Cu" );
|
||||
case In23_Cu: return _( "In23.Cu" );
|
||||
case In24_Cu: return _( "In24.Cu" );
|
||||
case In25_Cu: return _( "In25.Cu" );
|
||||
case In26_Cu: return _( "In26.Cu" );
|
||||
case In27_Cu: return _( "In27.Cu" );
|
||||
case In28_Cu: return _( "In28.Cu" );
|
||||
case In29_Cu: return _( "In29.Cu" );
|
||||
case In30_Cu: return _( "In30.Cu" );
|
||||
case B_Cu: return _( "B.Cu" );
|
||||
case F_Cu: return wxT( "F.Cu" );
|
||||
case In1_Cu: return wxT( "In1.Cu" );
|
||||
case In2_Cu: return wxT( "In2.Cu" );
|
||||
case In3_Cu: return wxT( "In3.Cu" );
|
||||
case In4_Cu: return wxT( "In4.Cu" );
|
||||
case In5_Cu: return wxT( "In5.Cu" );
|
||||
case In6_Cu: return wxT( "In6.Cu" );
|
||||
case In7_Cu: return wxT( "In7.Cu" );
|
||||
case In8_Cu: return wxT( "In8.Cu" );
|
||||
case In9_Cu: return wxT( "In9.Cu" );
|
||||
case In10_Cu: return wxT( "In10.Cu" );
|
||||
case In11_Cu: return wxT( "In11.Cu" );
|
||||
case In12_Cu: return wxT( "In12.Cu" );
|
||||
case In13_Cu: return wxT( "In13.Cu" );
|
||||
case In14_Cu: return wxT( "In14.Cu" );
|
||||
case In15_Cu: return wxT( "In15.Cu" );
|
||||
case In16_Cu: return wxT( "In16.Cu" );
|
||||
case In17_Cu: return wxT( "In17.Cu" );
|
||||
case In18_Cu: return wxT( "In18.Cu" );
|
||||
case In19_Cu: return wxT( "In19.Cu" );
|
||||
case In20_Cu: return wxT( "In20.Cu" );
|
||||
case In21_Cu: return wxT( "In21.Cu" );
|
||||
case In22_Cu: return wxT( "In22.Cu" );
|
||||
case In23_Cu: return wxT( "In23.Cu" );
|
||||
case In24_Cu: return wxT( "In24.Cu" );
|
||||
case In25_Cu: return wxT( "In25.Cu" );
|
||||
case In26_Cu: return wxT( "In26.Cu" );
|
||||
case In27_Cu: return wxT( "In27.Cu" );
|
||||
case In28_Cu: return wxT( "In28.Cu" );
|
||||
case In29_Cu: return wxT( "In29.Cu" );
|
||||
case In30_Cu: return wxT( "In30.Cu" );
|
||||
case B_Cu: return wxT( "B.Cu" );
|
||||
|
||||
// Technicals
|
||||
case B_Adhes: return _( "B.Adhesive" );
|
||||
case F_Adhes: return _( "F.Adhesive" );
|
||||
case B_Paste: return _( "B.Paste" );
|
||||
case F_Paste: return _( "F.Paste" );
|
||||
case B_SilkS: return _( "B.Silkscreen" );
|
||||
case F_SilkS: return _( "F.Silkscreen" );
|
||||
case B_Mask: return _( "B.Mask" );
|
||||
case F_Mask: return _( "F.Mask" );
|
||||
case B_Adhes: return wxT( "B.Adhesive" );
|
||||
case F_Adhes: return wxT( "F.Adhesive" );
|
||||
case B_Paste: return wxT( "B.Paste" );
|
||||
case F_Paste: return wxT( "F.Paste" );
|
||||
case B_SilkS: return wxT( "B.Silkscreen" );
|
||||
case F_SilkS: return wxT( "F.Silkscreen" );
|
||||
case B_Mask: return wxT( "B.Mask" );
|
||||
case F_Mask: return wxT( "F.Mask" );
|
||||
|
||||
// Users
|
||||
case Dwgs_User: return _( "User.Drawings" );
|
||||
case Cmts_User: return _( "User.Comments" );
|
||||
case Eco1_User: return _( "User.Eco1" );
|
||||
case Eco2_User: return _( "User.Eco2" );
|
||||
case Edge_Cuts: return _( "Edge.Cuts" );
|
||||
case Margin: return _( "Margin" );
|
||||
case Dwgs_User: return wxT( "User.Drawings" );
|
||||
case Cmts_User: return wxT( "User.Comments" );
|
||||
case Eco1_User: return wxT( "User.Eco1" );
|
||||
case Eco2_User: return wxT( "User.Eco2" );
|
||||
case Edge_Cuts: return wxT( "Edge.Cuts" );
|
||||
case Margin: return wxT( "Margin" );
|
||||
|
||||
// Footprint
|
||||
case F_CrtYd: return _( "F.Courtyard" );
|
||||
case B_CrtYd: return _( "B.Courtyard" );
|
||||
case F_Fab: return _( "F.Fab" );
|
||||
case B_Fab: return _( "B.Fab" );
|
||||
case F_CrtYd: return wxT( "F.Courtyard" );
|
||||
case B_CrtYd: return wxT( "B.Courtyard" );
|
||||
case F_Fab: return wxT( "F.Fab" );
|
||||
case B_Fab: return wxT( "B.Fab" );
|
||||
|
||||
// User definable layers.
|
||||
case User_1: return _( "User.1" );
|
||||
case User_2: return _( "User.2" );
|
||||
case User_3: return _( "User.3" );
|
||||
case User_4: return _( "User.4" );
|
||||
case User_5: return _( "User.5" );
|
||||
case User_6: return _( "User.6" );
|
||||
case User_7: return _( "User.7" );
|
||||
case User_8: return _( "User.8" );
|
||||
case User_9: return _( "User.9" );
|
||||
case User_1: return wxT( "User.1" );
|
||||
case User_2: return wxT( "User.2" );
|
||||
case User_3: return wxT( "User.3" );
|
||||
case User_4: return wxT( "User.4" );
|
||||
case User_5: return wxT( "User.5" );
|
||||
case User_6: return wxT( "User.6" );
|
||||
case User_7: return wxT( "User.7" );
|
||||
case User_8: return wxT( "User.8" );
|
||||
case User_9: return wxT( "User.9" );
|
||||
|
||||
// Rescue
|
||||
case Rescue: return _( "Rescue" );
|
||||
|
||||
+4
-4
@@ -203,7 +203,7 @@ wxString PATHS::GetStockSymbolsPath()
|
||||
{
|
||||
wxString path;
|
||||
|
||||
path = GetStockDataPath() + wxT( "/symbols" );
|
||||
path = GetStockEDALibraryPath() + wxT( "/symbols" );
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ wxString PATHS::GetStockFootprintsPath()
|
||||
{
|
||||
wxString path;
|
||||
|
||||
path = GetStockDataPath() + wxT( "/footprints" );
|
||||
path = GetStockEDALibraryPath() + wxT( "/footprints" );
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ wxString PATHS::GetStock3dmodelsPath()
|
||||
{
|
||||
wxString path;
|
||||
|
||||
path = GetStockDataPath() + wxT( "/3dmodels" );
|
||||
path = GetStockEDALibraryPath() + wxT( "/3dmodels" );
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -243,7 +243,7 @@ wxString PATHS::GetStockTemplatesPath()
|
||||
{
|
||||
wxString path;
|
||||
|
||||
path = GetStockDataPath() + wxT( "/template" );
|
||||
path = GetStockEDALibraryPath() + wxT( "/template" );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
+1
-1
@@ -384,7 +384,7 @@ void PGM_BASE::SaveCommonSettings()
|
||||
|
||||
COMMON_SETTINGS* PGM_BASE::GetCommonSettings() const
|
||||
{
|
||||
return m_settings_manager ? GetSettingsManager().GetCommonSettings() : nullptr;
|
||||
return m_settings_manager ? m_settings_manager->GetCommonSettings() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1252,7 +1252,7 @@ void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_M
|
||||
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
|
||||
Circle( pos, diametre - m_currentPenWidth, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
Circle( pos, diametre, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1372,10 +1372,8 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
Rect( wxPoint( pos.x - (size.x - GetCurrentLineWidth()) / 2,
|
||||
pos.y - (size.y - GetCurrentLineWidth()) / 2 ),
|
||||
wxPoint( pos.x + (size.x - GetCurrentLineWidth()) / 2,
|
||||
pos.y + (size.y - GetCurrentLineWidth()) / 2 ),
|
||||
Rect( wxPoint( pos.x - ( size.x / 2 ), pos.y - ( size.y / 2 ) ),
|
||||
wxPoint( pos.x + ( size.x / 2 ), pos.y + ( size.y / 2 ) ),
|
||||
FILL_T::NO_FILL, GetCurrentLineWidth() );
|
||||
}
|
||||
else
|
||||
@@ -1445,7 +1443,6 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
||||
0.0, 0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
|
||||
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
|
||||
outline.Inflate( -GetCurrentLineWidth()/2, 16 );
|
||||
|
||||
std::vector< wxPoint > cornerList;
|
||||
// TransformRoundRectToPolygon creates only one convex polygon
|
||||
@@ -1657,7 +1654,6 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
|
||||
if( aTraceMode != FILLED )
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
|
||||
polyshape.Inflate( -GetCurrentLineWidth()/2, 16 );
|
||||
}
|
||||
|
||||
std::vector< wxPoint > cornerList;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -486,7 +486,7 @@ void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList, FILL_T aFi
|
||||
m_current_item->content << hpgl_end_polygon_cmd; // Close, fill polygon and draw outlines
|
||||
m_current_item->pen_returns = true;
|
||||
}
|
||||
else if( aWidth > 0 )
|
||||
else if( aWidth != 0 )
|
||||
{
|
||||
// Plot only the polygon outline.
|
||||
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
|
||||
@@ -659,10 +659,10 @@ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
|
||||
// if filled mode, the pen diameter is removed from diameter
|
||||
// to keep the pad size
|
||||
radius -= KiROUND( penDiameter ) / 2;
|
||||
}
|
||||
|
||||
if( radius < 0 )
|
||||
radius = 0;
|
||||
if( radius < 0 )
|
||||
radius = 0;
|
||||
}
|
||||
|
||||
double rsize = userToDeviceSize( radius );
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -127,13 +127,7 @@ void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
|
||||
else // Plot a ring:
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
int linewidth = GetCurrentLineWidth();
|
||||
|
||||
// avoid aDiameter <= 1 )
|
||||
if( linewidth > aDiameter-2 )
|
||||
linewidth = aDiameter-2;
|
||||
|
||||
Circle( aPadPos, aDiameter - linewidth, FILL_T::NO_FILL, linewidth );
|
||||
Circle( aPadPos, aDiameter, FILL_T::NO_FILL, GetCurrentLineWidth() );
|
||||
}
|
||||
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
@@ -152,15 +146,6 @@ void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
|
||||
else
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
|
||||
size.x -= GetCurrentLineWidth();
|
||||
size.y -= GetCurrentLineWidth();
|
||||
|
||||
if( size.x < 1 )
|
||||
size.x = 1;
|
||||
|
||||
if( size.y < 1 )
|
||||
size.y = 1;
|
||||
|
||||
int dx = size.x / 2;
|
||||
int dy = size.y / 2;
|
||||
|
||||
@@ -203,9 +188,6 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
size.x -= GetCurrentLineWidth();
|
||||
size.y -= GetCurrentLineWidth();
|
||||
aCornerRadius -= GetCurrentLineWidth() / 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,8 +225,6 @@ void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
size.x -= GetCurrentLineWidth();
|
||||
size.y -= GetCurrentLineWidth();
|
||||
}
|
||||
|
||||
|
||||
@@ -283,23 +263,6 @@ void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCor
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
int w = GetCurrentLineWidth();
|
||||
|
||||
// offset polygon by w
|
||||
// coord[0] is assumed the lower left
|
||||
// coord[1] is assumed the upper left
|
||||
// coord[2] is assumed the upper right
|
||||
// coord[3] is assumed the lower right
|
||||
|
||||
/* Trace the outline. */
|
||||
cornerList[0].x += w;
|
||||
cornerList[0].y -= w;
|
||||
cornerList[1].x += w;
|
||||
cornerList[1].y += w;
|
||||
cornerList[2].x -= w;
|
||||
cornerList[2].y += w;
|
||||
cornerList[3].x -= w;
|
||||
cornerList[3].y -= w;
|
||||
}
|
||||
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -93,12 +93,6 @@ DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& aCoordinate )
|
||||
{
|
||||
wxPoint pos = aCoordinate - m_plotOffset;
|
||||
|
||||
// Don't allow overflows; they can cause rendering failures in some file viewers
|
||||
// (such as Acrobat)
|
||||
int clampSize = MAX_PAGE_SIZE_MILS * m_IUsPerDecimil * 10 / 2;
|
||||
pos.x = std::max( -clampSize, std::min( pos.x, clampSize ) );
|
||||
pos.y = std::max( -clampSize, std::min( pos.y, clampSize ) );
|
||||
|
||||
double x = pos.x * m_plotScale;
|
||||
double y = ( m_paperSize.y - pos.y * m_plotScale );
|
||||
|
||||
@@ -492,7 +486,7 @@ void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient
|
||||
}
|
||||
|
||||
deltaxy = size.y - size.x; /* distance between centers of the oval */
|
||||
radius = ( size.x - width ) / 2;
|
||||
radius = size.x / 2;
|
||||
cx = -radius;
|
||||
cy = -deltaxy / 2;
|
||||
RotatePoint( &cx, &cy, orient );
|
||||
|
||||
@@ -2258,6 +2258,10 @@ void CADSTAR_ARCHIVE_PARSER::ATTRCOLORS::Parse( XNODE* aNode, PARSER_CONTEXT* aC
|
||||
attrcol.Parse( cNode, aContext );
|
||||
AttributeColors.insert( { attrcol.AttributeID, attrcol } );
|
||||
}
|
||||
else if( cNodeName == wxT( "INVISIBLE" ) )
|
||||
{
|
||||
IsVisible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
|
||||
|
||||
@@ -1253,6 +1253,8 @@ public:
|
||||
DFLTSETTINGS DefaultSettings;
|
||||
std::map<ATTRIBUTE_ID, ATTRCOL> AttributeColors;
|
||||
|
||||
bool IsVisible = true; // unclear what this represents - maybe all attributes are hidden?
|
||||
|
||||
void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -538,18 +538,20 @@ EDIMENSION::EDIMENSION( wxXmlNode* aDimension )
|
||||
y2 %Coord; #REQUIRED
|
||||
x3 %Coord; #REQUIRED
|
||||
y3 %Coord; #REQUIRED
|
||||
textsize %Coord;
|
||||
layer %Layer; #REQUIRED
|
||||
dtype %DimensionType; "parallel"
|
||||
>
|
||||
*/
|
||||
|
||||
x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
|
||||
y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
|
||||
x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
|
||||
y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
|
||||
x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
|
||||
y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
|
||||
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
|
||||
x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
|
||||
y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
|
||||
x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
|
||||
y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
|
||||
x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
|
||||
y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
|
||||
textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
|
||||
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
|
||||
dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -531,13 +531,13 @@ struct EJUNCTION
|
||||
/// Eagle label
|
||||
struct ELABEL
|
||||
{
|
||||
ECOORD x;
|
||||
ECOORD y;
|
||||
ECOORD size;
|
||||
LAYER_NUM layer;
|
||||
opt_erot rot;
|
||||
ECOORD x;
|
||||
ECOORD y;
|
||||
ECOORD size;
|
||||
LAYER_NUM layer;
|
||||
opt_erot rot;
|
||||
opt_wxString xref;
|
||||
wxString netname;
|
||||
wxString netname;
|
||||
|
||||
ELABEL( wxXmlNode* aLabel, const wxString& aNetName );
|
||||
};
|
||||
@@ -619,14 +619,14 @@ struct EATTR
|
||||
/// Eagle dimension element
|
||||
struct EDIMENSION
|
||||
{
|
||||
ECOORD x1;
|
||||
ECOORD y1;
|
||||
ECOORD x2;
|
||||
ECOORD y2;
|
||||
ECOORD x3;
|
||||
ECOORD y3;
|
||||
int layer;
|
||||
|
||||
ECOORD x1;
|
||||
ECOORD y1;
|
||||
ECOORD x2;
|
||||
ECOORD y2;
|
||||
ECOORD x3;
|
||||
ECOORD y3;
|
||||
opt_ecoord textsize;
|
||||
int layer;
|
||||
opt_wxString dimensionType;
|
||||
|
||||
EDIMENSION( wxXmlNode* aDimension );
|
||||
|
||||
@@ -37,6 +37,8 @@ SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString
|
||||
m_te( aScintilla ),
|
||||
m_braces( aBraces ),
|
||||
m_lastCaretPos( -1 ),
|
||||
m_lastSelStart( -1 ),
|
||||
m_lastSelEnd( -1 ),
|
||||
m_suppressAutocomplete( false ),
|
||||
m_singleLine( aSingleLine ),
|
||||
m_returnCallback( aReturnCallback )
|
||||
@@ -337,10 +339,14 @@ void SCINTILLA_TRICKS::onScintillaUpdateUI( wxStyledTextEvent& aEvent )
|
||||
|
||||
// Has the caret changed position?
|
||||
int caretPos = m_te->GetCurrentPos();
|
||||
int selStart = m_te->GetSelectionStart();
|
||||
int selEnd = m_te->GetSelectionEnd();
|
||||
|
||||
if( m_lastCaretPos != caretPos )
|
||||
if( m_lastCaretPos != caretPos || m_lastSelStart != selStart || m_lastSelEnd != selEnd )
|
||||
{
|
||||
m_lastCaretPos = caretPos;
|
||||
m_lastSelStart = selStart;
|
||||
m_lastSelEnd = selEnd;
|
||||
int bracePos1 = -1;
|
||||
int bracePos2 = -1;
|
||||
|
||||
|
||||
+12
-2
@@ -142,7 +142,15 @@ bool ConvertSmartQuotesAndDashes( wxString* aString )
|
||||
|
||||
wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
{
|
||||
wxString converted;
|
||||
wxString converted;
|
||||
std::vector<bool> braceStack; // true == formatting construct
|
||||
|
||||
auto hasFormattingPrefix =
|
||||
[&]()
|
||||
{
|
||||
static wxString prefixes = wxT( "~_^" );
|
||||
return !converted.IsEmpty() && prefixes.Find( converted.Last() ) >= 0;
|
||||
};
|
||||
|
||||
converted.reserve( aSource.length() );
|
||||
|
||||
@@ -159,7 +167,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
}
|
||||
else if( aContext == CTX_LIBID )
|
||||
{
|
||||
if( c == '{' )
|
||||
if( c == '{' && !hasFormattingPrefix() )
|
||||
converted += wxT( "{brace}" );
|
||||
else if( c == '/' )
|
||||
converted += wxT( "{slash}" );
|
||||
@@ -227,7 +235,9 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
converted += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted += c;
|
||||
}
|
||||
}
|
||||
|
||||
return converted;
|
||||
|
||||
@@ -183,21 +183,20 @@ wxMenuItem* ACTION_MENU::Add( const TOOL_ACTION& aAction, bool aIsCheckmarkEntry
|
||||
|
||||
wxMenuItem* ACTION_MENU::Add( ACTION_MENU* aMenu )
|
||||
{
|
||||
ACTION_MENU* menuCopy = aMenu->Clone();
|
||||
m_submenus.push_back( menuCopy );
|
||||
m_submenus.push_back( aMenu );
|
||||
|
||||
wxASSERT_MSG( !menuCopy->m_title.IsEmpty(), wxT( "Set a title for ACTION_MENU using SetTitle()" ) );
|
||||
wxASSERT_MSG( !aMenu->m_title.IsEmpty(), wxT( "Set a title for ACTION_MENU using SetTitle()" ) );
|
||||
|
||||
if( !!aMenu->m_icon )
|
||||
{
|
||||
wxMenuItem* newItem = new wxMenuItem( this, -1, menuCopy->m_title );
|
||||
wxMenuItem* newItem = new wxMenuItem( this, -1, aMenu->m_title );
|
||||
AddBitmapToMenuItem( newItem, KiBitmap( aMenu->m_icon ) );
|
||||
newItem->SetSubMenu( menuCopy );
|
||||
newItem->SetSubMenu( aMenu );
|
||||
return Append( newItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
return AppendSubMenu( menuCopy, menuCopy->m_title );
|
||||
return AppendSubMenu( aMenu, aMenu->m_title );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -335,7 +335,12 @@ void ACTION_TOOLBAR::doSelectAction( ACTION_GROUP* aGroup, const TOOL_ACTION& aA
|
||||
// Update the item information
|
||||
item->SetShortHelp( aAction.GetDescription() );
|
||||
item->SetBitmap( KiScaledBitmap( aAction.GetIcon(), GetParent() ) );
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
item->SetDisabledBitmap(
|
||||
MakeDisabledBitmap( item->GetBitmapBundle().GetBitmapFor( GetParent() ) ) );
|
||||
#else
|
||||
item->SetDisabledBitmap( MakeDisabledBitmap( item->GetBitmap() ) );
|
||||
#endif
|
||||
|
||||
// Register a new handler with the new UI conditions
|
||||
if( m_toolManager )
|
||||
|
||||
@@ -150,7 +150,7 @@ void CONDITIONAL_MENU::Evaluate( SELECTION& aSelection )
|
||||
|
||||
case ENTRY::MENU:
|
||||
entry.Menu()->UpdateTitle();
|
||||
Add( entry.Menu() );
|
||||
Add( entry.Menu()->Clone() );
|
||||
menu_count++;
|
||||
break;
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
||||
{
|
||||
wxWindow* holderWindow = dynamic_cast<wxWindow*>( m_toolMgr->GetToolHolder() );
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#if defined( _WIN32 ) || defined( __WXGTK__ )
|
||||
// Mouse events may trigger regardless of window status (windows feature)
|
||||
// However we need to avoid focus fighting (especially modals)
|
||||
if( holderWindow && KIPLATFORM::UI::IsWindowActive( holderWindow ) )
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <trace_helpers.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <widgets/ui_common.h>
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <kiplatform/ui.h>
|
||||
@@ -300,7 +301,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
}
|
||||
|
||||
if( m_updateCursor ) // do not update the cursor position if it was explicitly set
|
||||
m_cursorPos = m_view->ToWorld( mousePos );
|
||||
m_cursorPos = GetClampedCoords( m_view->ToWorld( mousePos ) );
|
||||
else
|
||||
m_updateCursor = true;
|
||||
|
||||
@@ -458,8 +459,8 @@ void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent )
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( _WIN32 )
|
||||
// Win32 transmits mouse move and wheel events to all controls below the mouse regardless
|
||||
#if defined( _WIN32 ) || defined( __WXGTK__ )
|
||||
// Win32 and some *nix WMs transmit mouse move and wheel events to all controls below the mouse regardless
|
||||
// of focus. Forcing the focus here will cause the EDA FRAMES to immediately become the
|
||||
// top level active window.
|
||||
if( m_parentPanel->GetParent() != nullptr )
|
||||
@@ -648,7 +649,7 @@ VECTOR2D WX_VIEW_CONTROLS::GetMousePosition( bool aWorldCoordinates ) const
|
||||
wxPoint msp = getMouseScreenPosition();
|
||||
VECTOR2D screenPos( msp.x, msp.y );
|
||||
|
||||
return aWorldCoordinates ? m_view->ToWorld( screenPos ) : screenPos;
|
||||
return aWorldCoordinates ? GetClampedCoords( m_view->ToWorld( screenPos ) ) : screenPos;
|
||||
}
|
||||
|
||||
|
||||
@@ -675,7 +676,7 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition( bool aEnableSnapping ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetRawCursorPosition( aEnableSnapping );
|
||||
return GetClampedCoords( GetRawCursorPosition( aEnableSnapping ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,10 +686,12 @@ void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpV
|
||||
{
|
||||
m_updateCursor = false;
|
||||
|
||||
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
|
||||
|
||||
if( aTriggeredByArrows )
|
||||
{
|
||||
m_settings.m_lastKeyboardCursorPositionValid = true;
|
||||
m_settings.m_lastKeyboardCursorPosition = aPosition;
|
||||
m_settings.m_lastKeyboardCursorPosition = clampedPosition;
|
||||
m_settings.m_lastKeyboardCursorCommand = aArrowCommand;
|
||||
m_cursorWarped = false;
|
||||
}
|
||||
@@ -700,8 +703,8 @@ void WX_VIEW_CONTROLS::SetCursorPosition( const VECTOR2D& aPosition, bool aWarpV
|
||||
m_cursorWarped = true;
|
||||
}
|
||||
|
||||
WarpCursor( aPosition, true, aWarpView );
|
||||
m_cursorPos = aPosition;
|
||||
WarpCursor( clampedPosition, true, aWarpView );
|
||||
m_cursorPos = clampedPosition;
|
||||
}
|
||||
|
||||
|
||||
@@ -710,14 +713,16 @@ void WX_VIEW_CONTROLS::SetCrossHairCursorPosition( const VECTOR2D& aPosition,
|
||||
{
|
||||
m_updateCursor = false;
|
||||
|
||||
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
|
||||
|
||||
const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
|
||||
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
|
||||
VECTOR2D screenPos = m_view->ToScreen( aPosition );
|
||||
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
|
||||
VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
|
||||
|
||||
if( aWarpView && !screen.Contains( screenPos ) )
|
||||
m_view->SetCenter( aPosition );
|
||||
m_view->SetCenter( clampedPosition );
|
||||
|
||||
m_cursorPos = aPosition;
|
||||
m_cursorPos = clampedPosition;
|
||||
}
|
||||
|
||||
|
||||
@@ -727,14 +732,15 @@ void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordin
|
||||
if( aWorldCoordinates )
|
||||
{
|
||||
const VECTOR2I& screenSize = m_view->GetGAL()->GetScreenPixelSize();
|
||||
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
|
||||
VECTOR2D screenPos = m_view->ToScreen( aPosition );
|
||||
BOX2I screen( VECTOR2I( 0, 0 ), screenSize );
|
||||
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
|
||||
VECTOR2D screenPos = m_view->ToScreen( clampedPosition );
|
||||
|
||||
if( !screen.Contains( screenPos ) )
|
||||
{
|
||||
if( aWarpView )
|
||||
{
|
||||
m_view->SetCenter( aPosition );
|
||||
m_view->SetCenter( clampedPosition );
|
||||
m_parentPanel->WarpPointer( screenSize.x / 2, screenSize.y / 2 );
|
||||
}
|
||||
}
|
||||
@@ -889,7 +895,7 @@ void WX_VIEW_CONTROLS::refreshMouse()
|
||||
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
|
||||
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
|
||||
|
||||
m_cursorPos = m_view->ToWorld( VECTOR2D( msp.x, msp.y ) );
|
||||
m_cursorPos = GetClampedCoords( m_view->ToWorld( VECTOR2D( msp.x, msp.y ) ) );
|
||||
wxPostEvent( m_parentPanel, moveEvent );
|
||||
}
|
||||
|
||||
@@ -943,6 +949,8 @@ void WX_VIEW_CONTROLS::UpdateScrollbars()
|
||||
|
||||
void WX_VIEW_CONTROLS::ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition )
|
||||
{
|
||||
VECTOR2D clampedPosition = GetClampedCoords( aPosition );
|
||||
|
||||
m_settings.m_forceCursorPosition = aEnabled;
|
||||
m_settings.m_forcedPosition = aPosition;
|
||||
m_settings.m_forcedPosition = clampedPosition;
|
||||
}
|
||||
|
||||
@@ -298,10 +298,11 @@ void GRID_CELL_FOOTPRINT_ID_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
|
||||
class TEXT_BUTTON_URL : public wxComboCtrl
|
||||
{
|
||||
public:
|
||||
TEXT_BUTTON_URL( wxWindow* aParent, DIALOG_SHIM* aParentDlg ) :
|
||||
TEXT_BUTTON_URL( wxWindow* aParent, DIALOG_SHIM* aParentDlg, SEARCH_STACK* aSearchStack ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_PROCESS_ENTER ),
|
||||
m_dlg( aParentDlg )
|
||||
m_dlg( aParentDlg ),
|
||||
m_searchStack( aSearchStack )
|
||||
{
|
||||
SetButtonBitmaps( KiBitmap( BITMAPS::www ) );
|
||||
|
||||
@@ -320,17 +321,18 @@ protected:
|
||||
wxString filename = GetValue();
|
||||
|
||||
if( !filename.IsEmpty() && filename != wxT( "~" ) )
|
||||
GetAssociatedDocument( m_dlg, GetValue(), &m_dlg->Prj() );
|
||||
GetAssociatedDocument( m_dlg, GetValue(), &m_dlg->Prj(), m_searchStack );
|
||||
}
|
||||
|
||||
DIALOG_SHIM* m_dlg;
|
||||
SEARCH_STACK* m_searchStack;
|
||||
};
|
||||
|
||||
|
||||
void GRID_CELL_URL_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
|
||||
wxEvtHandler* aEventHandler )
|
||||
{
|
||||
m_control = new TEXT_BUTTON_URL( aParent, m_dlg );
|
||||
m_control = new TEXT_BUTTON_URL( aParent, m_dlg, m_searchStack );
|
||||
|
||||
#if wxUSE_VALIDATORS
|
||||
// validate text in textctrl, if validator is set
|
||||
|
||||
@@ -250,7 +250,7 @@ bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
|
||||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::SetValue( int aValue )
|
||||
void UNIT_BINDER::SetValue( long long int aValue )
|
||||
{
|
||||
double value = aValue;
|
||||
double displayValue = m_originTransforms.ToDisplay( value, m_coordType );
|
||||
|
||||
@@ -40,6 +40,11 @@ WX_GRID::WX_GRID( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxS
|
||||
|
||||
// Make sure the GUI font scales properly on GTK
|
||||
SetDefaultCellFont( KIUI::GetControlFont( this ) );
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 )
|
||||
Connect( wxEVT_DPI_CHANGED, wxDPIChangedEventHandler( WX_GRID::onDPIChanged ), nullptr, this );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +52,25 @@ WX_GRID::~WX_GRID()
|
||||
{
|
||||
if( m_weOwnTable )
|
||||
DestroyTable( GetTable() );
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 )
|
||||
Disconnect( wxEVT_DPI_CHANGED, wxDPIChangedEventHandler( WX_GRID::onDPIChanged ), nullptr, this );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 )
|
||||
void WX_GRID::onDPIChanged(wxDPIChangedEvent& aEvt)
|
||||
{
|
||||
/// This terrible hack is a way to avoid the incredibly disruptive resizing of grids that happens on Macs
|
||||
/// when moving a window between monitors of different DPIs.
|
||||
#ifndef __WXMAC__
|
||||
aEvt.Skip();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void WX_GRID::SetColLabelSize( int aHeight )
|
||||
{
|
||||
if( aHeight == 0 )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -94,7 +94,10 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList,
|
||||
{
|
||||
fn = wxExpandEnvVars( equfile );
|
||||
|
||||
tmp = search.FindValidPath( fn.GetFullPath() );
|
||||
if( fn.IsAbsolute() || fn.FileExists() )
|
||||
tmp = fn.GetFullPath();
|
||||
else
|
||||
tmp = search.FindValidPath( fn.GetFullPath() );
|
||||
|
||||
if( !tmp )
|
||||
{
|
||||
@@ -102,8 +105,7 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList,
|
||||
|
||||
if( aErrorMessages )
|
||||
{
|
||||
error_msg.Printf( _( "Equivalence file '%s' could not be found in the "
|
||||
"default search paths." ),
|
||||
error_msg.Printf( _( "Equivalence file '%s' could not be found." ),
|
||||
fn.GetFullName() );
|
||||
|
||||
if( ! aErrorMessages->IsEmpty() )
|
||||
|
||||
@@ -276,9 +276,10 @@ void CVPCB_MAINFRAME::setupUIConditions()
|
||||
#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
|
||||
#define CHECK( x ) ACTION_CONDITIONS().Check( x )
|
||||
|
||||
mgr->SetConditions( CVPCB_ACTIONS::saveAssociations, ENABLE( cond.ContentModified() ) );
|
||||
mgr->SetConditions( ACTIONS::undo, ENABLE( cond.UndoAvailable() ) );
|
||||
mgr->SetConditions( ACTIONS::redo, ENABLE( cond.RedoAvailable() ) );
|
||||
mgr->SetConditions( CVPCB_ACTIONS::saveAssociationsToSchematic, ENABLE( cond.ContentModified() ) );
|
||||
mgr->SetConditions( CVPCB_ACTIONS::saveAssociationsToFile, ENABLE( cond.ContentModified() ) );
|
||||
mgr->SetConditions( ACTIONS::undo, ENABLE( cond.UndoAvailable() ) );
|
||||
mgr->SetConditions( ACTIONS::redo, ENABLE( cond.RedoAvailable() ) );
|
||||
|
||||
auto compFilter =
|
||||
[this] ( const SELECTION& )
|
||||
@@ -327,7 +328,7 @@ void CVPCB_MAINFRAME::setupEventHandlers()
|
||||
[this]( wxCommandEvent& )
|
||||
{
|
||||
// saveAssociations must be run immediately
|
||||
GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations, true );
|
||||
GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociationsToFile, true );
|
||||
} );
|
||||
|
||||
// Connect the handlers for the ok/cancel buttons
|
||||
@@ -335,7 +336,7 @@ void CVPCB_MAINFRAME::setupEventHandlers()
|
||||
[this]( wxCommandEvent& )
|
||||
{
|
||||
// saveAssociations must be run immediately, before running Close( true )
|
||||
GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations, true );
|
||||
GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociationsToSchematic, true );
|
||||
Close( true );
|
||||
}, wxID_OK );
|
||||
Bind( wxEVT_BUTTON,
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
|
||||
//
|
||||
ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
|
||||
|
||||
fileMenu->Add( CVPCB_ACTIONS::saveAssociations );
|
||||
fileMenu->Add( CVPCB_ACTIONS::saveAssociationsToSchematic );
|
||||
fileMenu->AppendSeparator();
|
||||
fileMenu->AddClose( _( "Assign Footprints" ) );
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
|
||||
m_mainToolBar->SetAuiManager( &m_auimgr );
|
||||
}
|
||||
|
||||
m_mainToolBar->Add( CVPCB_ACTIONS::saveAssociations );
|
||||
m_mainToolBar->Add( CVPCB_ACTIONS::saveAssociationsToSchematic );
|
||||
|
||||
m_mainToolBar->AddScaledSeparator( this );
|
||||
m_mainToolBar->Add( ACTIONS::showFootprintLibTable );
|
||||
|
||||
@@ -61,13 +61,20 @@ TOOL_ACTION CVPCB_ACTIONS::showEquFileTable( "cvpcb.Control.ShowEquFileTable",
|
||||
_( "Configure footprint association file (.equ) list. These files are "
|
||||
"used to automatically assign footprint names from symbol values." ) );
|
||||
|
||||
TOOL_ACTION CVPCB_ACTIONS::saveAssociations( "cvpcb.Control.SaveAssociations",
|
||||
TOOL_ACTION CVPCB_ACTIONS::saveAssociationsToSchematic( "cvpcb.Control.SaveAssociationsToSchematic",
|
||||
AS_GLOBAL,
|
||||
MD_CTRL + 'S', LEGACY_HK_NAME( "Save" ),
|
||||
_( "Save to Schematic" ),
|
||||
_( "Save footprint associations in schematic symbol footprint fields" ),
|
||||
BITMAPS::save );
|
||||
|
||||
TOOL_ACTION CVPCB_ACTIONS::saveAssociationsToFile( "cvpcb.Control.SaveAssociationsToFile",
|
||||
AS_GLOBAL,
|
||||
MD_CTRL + 'S', LEGACY_HK_NAME( "Save" ),
|
||||
_( "Save to Schematic and File" ),
|
||||
_( "Save footprint associations in schematic symbol footprint fields and schematic files" ),
|
||||
BITMAPS::save );
|
||||
|
||||
// Actions to navigate the display
|
||||
TOOL_ACTION CVPCB_ACTIONS::changeFocusRight( "cvpcb.Control.changeFocusRight",
|
||||
AS_GLOBAL,
|
||||
|
||||
@@ -53,7 +53,8 @@ public:
|
||||
static TOOL_ACTION gotoNextNA;
|
||||
|
||||
/// Management actions
|
||||
static TOOL_ACTION saveAssociations;
|
||||
static TOOL_ACTION saveAssociationsToSchematic;
|
||||
static TOOL_ACTION saveAssociationsToFile;
|
||||
static TOOL_ACTION showEquFileTable;
|
||||
|
||||
/// Footprint Association actions
|
||||
|
||||
@@ -210,13 +210,20 @@ int CVPCB_CONTROL::ShowEquFileTable( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::SaveAssociations( const TOOL_EVENT& aEvent )
|
||||
int CVPCB_CONTROL::SaveAssociationsToFile( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SaveFootprintAssociation( true );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::SaveAssociationsToSchematic( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SaveFootprintAssociation( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
int tmp = aEvent.Parameter<intptr_t>();
|
||||
@@ -231,8 +238,9 @@ int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
|
||||
return 0;
|
||||
|
||||
// Extract the current selection
|
||||
unsigned int curSel = -1;
|
||||
unsigned int newSel = -1;
|
||||
bool changeSel = false;
|
||||
unsigned int newSel = UINT_MAX;
|
||||
|
||||
switch( dir )
|
||||
{
|
||||
case CVPCB_MAINFRAME::ITEM_NEXT:
|
||||
@@ -240,11 +248,12 @@ int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
|
||||
newSel = tempSel.front();
|
||||
|
||||
// Find the next index in the component list
|
||||
for( unsigned int i : naComp )
|
||||
for( unsigned int idx : naComp )
|
||||
{
|
||||
if( i > newSel )
|
||||
if( idx > newSel )
|
||||
{
|
||||
newSel = i;
|
||||
changeSel = true;
|
||||
newSel = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -255,7 +264,19 @@ int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
|
||||
if( !tempSel.empty() )
|
||||
{
|
||||
newSel = tempSel.front();
|
||||
curSel = newSel - 1; // Break one before the current selection
|
||||
|
||||
// Find the previous index in the component list
|
||||
for( int jj = naComp.size()-1; jj >= 0; jj-- )
|
||||
{
|
||||
unsigned idx = naComp[jj];
|
||||
|
||||
if( idx < newSel )
|
||||
{
|
||||
changeSel = true;
|
||||
newSel = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -264,18 +285,9 @@ int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
|
||||
wxASSERT_MSG( false, wxT( "Invalid direction" ) );
|
||||
}
|
||||
|
||||
// Find the next index in the component list
|
||||
for( unsigned int i : naComp )
|
||||
{
|
||||
if( i >= curSel )
|
||||
{
|
||||
newSel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the component selection
|
||||
m_frame->SetSelectedComponent( newSel );
|
||||
// Set the new component selection
|
||||
if( changeSel )
|
||||
m_frame->SetSelectedComponent( newSel );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -310,7 +322,8 @@ void CVPCB_CONTROL::setTransitions()
|
||||
|
||||
// Management actions
|
||||
Go( &CVPCB_CONTROL::ShowEquFileTable, CVPCB_ACTIONS::showEquFileTable.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::SaveAssociations, CVPCB_ACTIONS::saveAssociations.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::SaveAssociationsToSchematic, CVPCB_ACTIONS::saveAssociationsToSchematic.MakeEvent() );
|
||||
Go( &CVPCB_CONTROL::SaveAssociationsToFile,CVPCB_ACTIONS::saveAssociationsToFile.MakeEvent() );
|
||||
|
||||
// Navigation actions
|
||||
Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoNextNA.MakeEvent() );
|
||||
|
||||
@@ -75,7 +75,14 @@ public:
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int SaveAssociations( const TOOL_EVENT& aEvent );
|
||||
int SaveAssociationsToSchematic( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Save the associations to the schematic and save schematic to file.
|
||||
*
|
||||
* @param aEvent is the event generated by the tool framework
|
||||
*/
|
||||
int SaveAssociationsToFile( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Create or Update the frame showing the current highlighted footprint
|
||||
|
||||
+136
-94
@@ -588,112 +588,140 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
// Pre-scan to see if we have a bus at this location
|
||||
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
|
||||
|
||||
for( auto primary_it = connection_vec.begin(); primary_it != connection_vec.end(); primary_it++ )
|
||||
// We don't want to spin up a new thread for fewer than 4 items (overhead costs)
|
||||
size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
|
||||
( connection_vec.size() + 3 ) / 4 );
|
||||
|
||||
std::atomic<size_t> nextItem( 0 );
|
||||
std::mutex update_mutex;
|
||||
std::vector<std::future<size_t>> returns( parallelThreadCount );
|
||||
|
||||
auto update_lambda = [&]() -> size_t
|
||||
{
|
||||
SCH_ITEM* connected_item = *primary_it;
|
||||
|
||||
// Bus entries are special: they can have connection points in the
|
||||
// middle of a wire segment, because the junction algo doesn't split
|
||||
// the segment in two where you place a bus entry. This means that
|
||||
// bus entries that don't land on the end of a line segment need to
|
||||
// have "virtual" connection points to the segments they graphically
|
||||
// touch.
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
for( size_t ii = nextItem++; ii < connection_vec.size(); ii = nextItem++ )
|
||||
{
|
||||
// If this location only has the connection point of the bus
|
||||
// entry itself, this means that either the bus entry is not
|
||||
// connected to anything graphically, or that it is connected to
|
||||
// a segment at some point other than at one of the endpoints.
|
||||
if( connection_vec.size() == 1 )
|
||||
{
|
||||
if( busLine )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
bus_entry->m_connected_bus_item = busLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bus-to-bus entries are treated just like bus wires
|
||||
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
|
||||
{
|
||||
if( connection_vec.size() < 2 )
|
||||
{
|
||||
if( busLine )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
|
||||
|
||||
if( it.first == bus_entry->GetPosition() )
|
||||
bus_entry->m_connected_bus_items[0] = busLine;
|
||||
else
|
||||
bus_entry->m_connected_bus_items[1] = busLine;
|
||||
|
||||
bus_entry->AddConnectionTo( aSheet, busLine );
|
||||
busLine->AddConnectionTo( aSheet, bus_entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change junctions to be on bus junction layer if they are touching a bus
|
||||
else if( connected_item->Type() == SCH_JUNCTION_T )
|
||||
{
|
||||
connected_item->SetLayer( busLine ? LAYER_BUS_JUNCTION : LAYER_JUNCTION );
|
||||
}
|
||||
|
||||
for( auto test_it = primary_it + 1; test_it != connection_vec.end(); test_it++ )
|
||||
{
|
||||
bool bus_connection_ok = true;
|
||||
SCH_ITEM* test_item = *test_it;
|
||||
|
||||
wxASSERT( test_item != connected_item );
|
||||
|
||||
// Set up the link between the bus entry net and the bus
|
||||
SCH_ITEM* connected_item = connection_vec[ii];
|
||||
// Bus entries are special: they can have connection points in the
|
||||
// middle of a wire segment, because the junction algo doesn't split
|
||||
// the segment in two where you place a bus entry. This means that
|
||||
// bus entries that don't land on the end of a line segment need to
|
||||
// have "virtual" connection points to the segments they graphically
|
||||
// touch.
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
if( test_item->GetLayer() == LAYER_BUS )
|
||||
// If this location only has the connection point of the bus
|
||||
// entry itself, this means that either the bus entry is not
|
||||
// connected to anything graphically, or that it is connected to
|
||||
// a segment at some point other than at one of the endpoints.
|
||||
if( connection_vec.size() == 1 )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
bus_entry->m_connected_bus_item = test_item;
|
||||
if( busLine )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
bus_entry->m_connected_bus_item = busLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bus entries only connect to bus lines on the end that is touching a bus line.
|
||||
// If the user has overlapped another net line with the endpoint of the bus entry
|
||||
// where the entry connects to a bus, we don't want to short-circuit it.
|
||||
// Bus-to-bus entries are treated just like bus wires
|
||||
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
|
||||
{
|
||||
if( connection_vec.size() < 2 )
|
||||
{
|
||||
if( busLine )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
|
||||
|
||||
if( it.first == bus_entry->GetPosition() )
|
||||
bus_entry->m_connected_bus_items[0] = busLine;
|
||||
else
|
||||
bus_entry->m_connected_bus_items[1] = busLine;
|
||||
|
||||
std::lock_guard<std::mutex> lock( update_mutex );
|
||||
bus_entry->AddConnectionTo( aSheet, busLine );
|
||||
busLine->AddConnectionTo( aSheet, bus_entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change junctions to be on bus junction layer if they are touching a bus
|
||||
else if( connected_item->Type() == SCH_JUNCTION_T )
|
||||
{
|
||||
connected_item->SetLayer( busLine ? LAYER_BUS_JUNCTION : LAYER_JUNCTION );
|
||||
}
|
||||
|
||||
SCH_ITEM_SET& connected_set = connected_item->ConnectedItems( aSheet );
|
||||
connected_set.reserve( connection_vec.size() );
|
||||
|
||||
for( SCH_ITEM* test_item : connection_vec )
|
||||
{
|
||||
bool bus_connection_ok = true;
|
||||
|
||||
if( test_item == connected_item )
|
||||
continue;
|
||||
|
||||
// Set up the link between the bus entry net and the bus
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
if( test_item->GetLayer() == LAYER_BUS )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
bus_entry->m_connected_bus_item = test_item;
|
||||
}
|
||||
}
|
||||
|
||||
// Bus entries only connect to bus lines on the end that is touching a bus line.
|
||||
// If the user has overlapped another net line with the endpoint of the bus entry
|
||||
// where the entry connects to a bus, we don't want to short-circuit it.
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
bus_connection_ok = !busLine || test_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
else if( test_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
|
||||
if( connected_item->ConnectionPropagatesTo( test_item ) &&
|
||||
test_item->ConnectionPropagatesTo( connected_item ) &&
|
||||
bus_connection_ok )
|
||||
{
|
||||
connected_set.push_back( test_item );
|
||||
}
|
||||
}
|
||||
|
||||
// If we got this far and did not find a connected bus item for a bus entry,
|
||||
// we should do a manual scan in case there is a bus item on this connection
|
||||
// point but we didn't pick it up earlier because there is *also* a net item here.
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
bus_connection_ok = !busLine || test_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
else if( test_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
|
||||
if( connected_item->ConnectionPropagatesTo( test_item ) &&
|
||||
test_item->ConnectionPropagatesTo( connected_item ) &&
|
||||
bus_connection_ok )
|
||||
{
|
||||
connected_item->AddConnectionTo( aSheet, test_item );
|
||||
test_item->AddConnectionTo( aSheet, connected_item );
|
||||
if( !bus_entry->m_connected_bus_item )
|
||||
{
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
SCH_LINE* bus = screen->GetBus( it.first );
|
||||
|
||||
if( bus )
|
||||
bus_entry->m_connected_bus_item = bus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we got this far and did not find a connected bus item for a bus entry,
|
||||
// we should do a manual scan in case there is a bus item on this connection
|
||||
// point but we didn't pick it up earlier because there is *also* a net item here.
|
||||
if( connected_item->Type() == SCH_BUS_WIRE_ENTRY_T )
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_WIRE_ENTRY*>( connected_item );
|
||||
return 1;
|
||||
};
|
||||
|
||||
if( !bus_entry->m_connected_bus_item )
|
||||
{
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
SCH_LINE* bus = screen->GetBus( it.first );
|
||||
|
||||
if( bus )
|
||||
bus_entry->m_connected_bus_item = bus;
|
||||
}
|
||||
}
|
||||
if( parallelThreadCount == 1 )
|
||||
update_lambda();
|
||||
else
|
||||
{
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii] = std::async( std::launch::async, update_lambda );
|
||||
|
||||
// Finalize the threads
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii].wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -736,7 +764,6 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
return ( unique && conn && ( conn->SubgraphCode() == 0 ) );
|
||||
};
|
||||
|
||||
|
||||
std::copy_if( item->ConnectedItems( sheet ).begin(),
|
||||
item->ConnectedItems( sheet ).end(),
|
||||
std::back_inserter( memberlist ), get_items );
|
||||
@@ -755,10 +782,16 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
connected_conn->SetSubgraphCode( subgraph->m_code );
|
||||
m_item_to_subgraph_map[connected_item] = subgraph;
|
||||
subgraph->AddItem( connected_item );
|
||||
SCH_ITEM_SET citemset = connected_item->ConnectedItems( sheet );
|
||||
SCH_ITEM_SET& citemset = connected_item->ConnectedItems( sheet );
|
||||
|
||||
std::copy_if( citemset.begin(), citemset.end(),
|
||||
std::back_inserter( memberlist ), get_items );
|
||||
for( SCH_ITEM* citem : citemset )
|
||||
{
|
||||
if( citem->HasFlag( CANDIDATE ) )
|
||||
continue;
|
||||
|
||||
if( get_items( citem ) )
|
||||
memberlist.push_back( citem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,8 +1366,13 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||
m_bus_alias_cache[ alias->GetName() ] = alias;
|
||||
}
|
||||
|
||||
PROF_TIMER sub_graph( "buildItemSubGraphs" );
|
||||
buildItemSubGraphs();
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
sub_graph.Show();
|
||||
|
||||
|
||||
/**
|
||||
* TODO(JE): Net codes are non-deterministic. Fortunately, they are also not really used for
|
||||
* anything. We should consider removing them entirely and just using net names everywhere.
|
||||
@@ -1346,8 +1384,12 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||
|
||||
generateInvisiblePinSubGraphs();
|
||||
|
||||
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
|
||||
processSubGraphs();
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
proc_sub_graph.Show();
|
||||
|
||||
// Absorbed subgraphs should no longer be considered
|
||||
alg::delete_if( m_driver_subgraphs, [&]( const CONNECTION_SUBGRAPH* candidate ) -> bool
|
||||
{
|
||||
|
||||
@@ -379,7 +379,8 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
|
||||
}
|
||||
|
||||
|
||||
std::string FormatProbeItem( EDA_ITEM* aItem, SCH_SYMBOL* aSymbol )
|
||||
std::string FormatProbeItem( const SCH_SHEET_PATH& aCurrentSheet, EDA_ITEM* aItem,
|
||||
SCH_SYMBOL* aSymbol )
|
||||
{
|
||||
// This is a keyword followed by a quoted string.
|
||||
|
||||
@@ -403,20 +404,8 @@ std::string FormatProbeItem( EDA_ITEM* aItem, SCH_SYMBOL* aSymbol )
|
||||
{
|
||||
// For cross probing, we need the full path of the sheet, because
|
||||
// in complex hierarchies the sheet uuid of not unique
|
||||
SCH_SHEET* sheet = (SCH_SHEET*)aItem;
|
||||
wxString full_path;
|
||||
|
||||
SCH_SHEET* parent = sheet;
|
||||
while( (parent = dynamic_cast<SCH_SHEET*>( parent->GetParent() ) ) )
|
||||
{
|
||||
if( parent->GetParent() ) // The root sheet has no parent and path is just "/"
|
||||
{
|
||||
full_path.Prepend( parent->m_Uuid.AsString() );
|
||||
full_path.Prepend( "/" );
|
||||
}
|
||||
}
|
||||
|
||||
full_path += "/" + sheet->m_Uuid.AsString();
|
||||
wxString full_path = aCurrentSheet.PathAsString() + aItem->m_Uuid.AsString();
|
||||
|
||||
return StrPrintf( "$SHEET: \"%s\"", TO_UTF8( full_path ) );
|
||||
}
|
||||
@@ -454,7 +443,7 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aObjectToSync, SCH_SYMBOL* a
|
||||
if( !aObjectToSync )
|
||||
return;
|
||||
|
||||
std::string packet = FormatProbeItem( aObjectToSync, aLibItem );
|
||||
std::string packet = FormatProbeItem( GetCurrentSheet(), aObjectToSync, aLibItem );
|
||||
|
||||
if( !packet.empty() )
|
||||
{
|
||||
|
||||
@@ -396,7 +396,7 @@ void DIALOG_ERC::testErc()
|
||||
|| settings.IsTestEnabled( ERCE_POWERPIN_NOT_DRIVEN )
|
||||
|| settings.IsTestEnabled( ERCE_PIN_NOT_DRIVEN ) )
|
||||
{
|
||||
tester.TestPinToPin();
|
||||
tester.TestPinToPin();
|
||||
}
|
||||
|
||||
// Test similar labels (i;e. labels which are identical when
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <sch_line.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_sheet_pin.h>
|
||||
#include <schematic.h>
|
||||
#include <advanced_config.h>
|
||||
#include <tool/tool_manager.h>
|
||||
@@ -412,6 +413,12 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
if( m_setBgColor->GetValue() )
|
||||
sheet->SetBackgroundColor( m_bgColorSwatch->GetSwatchColor() );
|
||||
}
|
||||
|
||||
if( m_sheetPins->GetValue() )
|
||||
{
|
||||
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
|
||||
processItem( aSheetPath, pin );
|
||||
}
|
||||
}
|
||||
else if( aItem->Type() == SCH_JUNCTION_T )
|
||||
{
|
||||
@@ -439,8 +446,6 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
processItem( aSheetPath, aItem );
|
||||
else if( m_hierLabels->GetValue() && aItem->Type() == SCH_HIER_LABEL_T )
|
||||
processItem( aSheetPath, aItem );
|
||||
else if( m_sheetPins->GetValue() && aItem->Type() == SCH_SHEET_PIN_T )
|
||||
processItem( aSheetPath, aItem );
|
||||
else if( m_schTextAndGraphics->GetValue() && aItem->IsType( schTextAndGraphics ) )
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_
|
||||
fgSizer1->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM, 7 );
|
||||
|
||||
m_staticline4 = new wxStaticLine( m_specifiedValues, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
fgSizer1->Add( m_staticline4, 0, wxEXPAND|wxBOTTOM, 7 );
|
||||
fgSizer1->Add( m_staticline4, 0, wxEXPAND|wxTOP|wxBOTTOM, 7 );
|
||||
|
||||
m_staticline5 = new wxStaticLine( m_specifiedValues, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
fgSizer1->Add( m_staticline5, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 7 );
|
||||
|
||||
@@ -2956,7 +2956,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">7</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticLine" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
||||
@@ -75,10 +75,10 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataToWindow()
|
||||
|
||||
bool enblConvOptStyle = symbol && symbol->HasConversion();
|
||||
|
||||
// if a symbol contains no graphic items, symbol->HasConversion() returns false.
|
||||
// but when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions
|
||||
// must be enabled even if symbol->HasConversion() returns false in order to be able
|
||||
// to create graphic items shared by all body styles
|
||||
// If a symbol contains no conversion-specific pins or graphic items, symbol->HasConversion()
|
||||
// will return false.
|
||||
// But when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions
|
||||
// must be enabled in order to be able to create graphic items shared by all body styles.
|
||||
if( m_frame->GetShowDeMorgan() )
|
||||
enblConvOptStyle = true;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES::DIALOG_LIB_SYMBOL_PROPERTIES( SYMBOL_EDIT_FRAME* a
|
||||
m_grid->ShowHideColumns( cfg->m_EditSymbolVisibleColumns );
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
|
||||
attr->SetEditor( new GRID_CELL_URL_EDITOR( this, Prj().SchSearchS() ) );
|
||||
m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
|
||||
|
||||
m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE_FIELD ) );
|
||||
@@ -174,7 +174,13 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||
m_SelNumberOfUnits->SetValue( m_libEntry->GetUnitCount() );
|
||||
m_OptionPartsInterchangeable->SetValue( !m_libEntry->UnitsLocked() ||
|
||||
m_libEntry->GetUnitCount() == 1 );
|
||||
m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
|
||||
|
||||
// If a symbol contains no conversion-specific pins or graphic items, symbol->HasConversion()
|
||||
// will return false. But when editing a symbol with DeMorgan option set, we don't want to
|
||||
// keep turning it off just because there aren't any conversion-specific items yet, so we force
|
||||
// it to on if the parent frame has it enabled.
|
||||
m_AsConvertButt->SetValue( m_Parent->GetShowDeMorgan() );
|
||||
|
||||
m_OptionPower->SetValue( m_libEntry->IsPower() );
|
||||
m_excludeFromBomCheckBox->SetValue( !m_libEntry->GetIncludeInBom() );
|
||||
m_excludeFromBoardCheckBox->SetValue( !m_libEntry->GetIncludeOnBoard() );
|
||||
@@ -367,6 +373,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
m_libEntry->LockUnits( m_libEntry->GetUnitCount() > 1 &&
|
||||
!m_OptionPartsInterchangeable->GetValue() );
|
||||
m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
|
||||
m_Parent->SetShowDeMorgan( m_AsConvertButt->GetValue() );
|
||||
|
||||
if( m_OptionPower->GetValue() )
|
||||
m_libEntry->SetPower();
|
||||
@@ -448,7 +455,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnSymbolNameText( wxCommandEvent& event )
|
||||
{
|
||||
if( !m_Parent->IsSymbolFromSchematic() )
|
||||
if( !m_Parent->IsSymbolFromSchematic() || m_OptionPower->IsChecked() )
|
||||
m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
|
||||
}
|
||||
|
||||
@@ -464,7 +471,10 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnSymbolNameKillFocus( wxFocusEvent& event )
|
||||
m_delayedFocusPage = 0;
|
||||
|
||||
if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
|
||||
{
|
||||
m_delayedFocusCtrl = nullptr;
|
||||
m_delayedFocusPage = -1;
|
||||
}
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
|
||||
@@ -802,7 +802,7 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotDrawingSheet
|
||||
plotter->SetRenderSettings( aRenderSettings );
|
||||
plotter->SetColorMode( getModeColor() );
|
||||
plotter->SetCreator( wxT( "Eeschema-PDF" ) );
|
||||
plotter->SetTitle( m_parent->GetTitleBlock().GetTitle() );
|
||||
plotter->SetTitle( ExpandTextVars( m_parent->GetTitleBlock().GetTitle(), &m_parent->Prj() ) );
|
||||
|
||||
wxString msg;
|
||||
wxFileName plotFileName;
|
||||
@@ -1250,7 +1250,15 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
|
||||
wxStandardPaths::Get().GetDocumentsDir() );
|
||||
|
||||
// Build the absolute path of current output directory to preselect it in the file browser.
|
||||
wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
|
||||
std::function<bool( wxString* )> textResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
return m_parent->Schematic().ResolveTextVar( token, 0 );
|
||||
};
|
||||
|
||||
wxString path = m_outputDirectoryName->GetValue();
|
||||
path = ExpandTextVars( path, &textResolver, nullptr, &Prj() );
|
||||
path = ExpandEnvVarSubstitutions( path, &Prj() );
|
||||
|
||||
fn.SetPath( path );
|
||||
|
||||
|
||||
@@ -171,6 +171,12 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataToWindow()
|
||||
{
|
||||
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
|
||||
|
||||
if( cfg->m_Printing.monochrome )
|
||||
{
|
||||
m_checkBackgroundColor->SetValue( false );
|
||||
m_checkBackgroundColor->Enable( false );
|
||||
}
|
||||
|
||||
m_checkReference->SetValue( cfg->m_Printing.title_block );
|
||||
m_checkMonochrome->SetValue( cfg->m_Printing.monochrome );
|
||||
m_checkBackgroundColor->SetValue( cfg->m_Printing.background );
|
||||
@@ -246,7 +252,10 @@ void DIALOG_PRINT_USING_PRINTER::SavePrintOptions()
|
||||
|
||||
cfg->m_Printing.monochrome = m_checkMonochrome->IsChecked();
|
||||
cfg->m_Printing.title_block = m_checkReference->IsChecked();
|
||||
cfg->m_Printing.background = m_checkBackgroundColor->IsChecked();
|
||||
|
||||
if( m_checkBackgroundColor->IsEnabled() )
|
||||
cfg->m_Printing.background = m_checkBackgroundColor->IsChecked();
|
||||
|
||||
cfg->m_Printing.use_theme = m_checkUseColorTheme->IsChecked();
|
||||
|
||||
COLOR_SETTINGS* theme = static_cast<COLOR_SETTINGS*>(
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <sch_reference_list.h>
|
||||
#include <schematic.h>
|
||||
#include <tools/sch_editor_control.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <widgets/grid_text_button_helpers.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <wx/grid.h>
|
||||
@@ -114,7 +115,7 @@ protected:
|
||||
{
|
||||
wxString datasheet_uri = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
|
||||
DATASHEET_FIELD );
|
||||
GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj() );
|
||||
GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj(), m_dlg->Prj().SchSearchS() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,8 +209,17 @@ public:
|
||||
for( unsigned i = 0; i < m_symbolsList.GetCount(); ++i )
|
||||
{
|
||||
SCH_SYMBOL* symbol = m_symbolsList[ i ].GetSymbol();
|
||||
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = symbol->GetFieldText( aFieldName,
|
||||
m_frame );
|
||||
|
||||
wxCHECK( symbol && ( symbol->GetInstanceReferences().size() != 0 ), /* void */ );
|
||||
|
||||
wxString val = symbol->GetFieldText( aFieldName, m_frame );
|
||||
|
||||
if( aFieldName == wxT( "Value" ) )
|
||||
val = symbol->GetInstanceReferences()[0].m_Value;
|
||||
else if( aFieldName == wxT( "Footprint" ) )
|
||||
val = symbol->GetInstanceReferences()[0].m_Footprint;
|
||||
|
||||
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,7 +779,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
|
||||
|
||||
// set datasheet column viewer button
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
|
||||
attr->SetEditor( new GRID_CELL_URL_EDITOR( this, Prj().SchSearchS() ) );
|
||||
m_grid->SetColAttr( DATASHEET_FIELD, attr );
|
||||
|
||||
// set quantities column attributes
|
||||
@@ -1170,8 +1180,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnTableItemContextMenu( wxGridEvent& event )
|
||||
|
||||
void DIALOG_SYMBOL_FIELDS_TABLE::OnSizeFieldList( wxSizeEvent& event )
|
||||
{
|
||||
int nameColWidth = event.GetSize().GetX() - m_showColWidth - m_groupByColWidth
|
||||
- wxSystemSettings::GetMetric( wxSYS_VSCROLL_X );
|
||||
int nameColWidth = KIPLATFORM::UI::GetUnobscuredSize( m_fieldsCtrl ).x - m_showColWidth
|
||||
- m_groupByColWidth;
|
||||
|
||||
// GTK loses its head and messes these up when resizing the splitter bar:
|
||||
m_fieldsCtrl->GetColumn( SHOW_FIELD_COLUMN )->SetWidth( m_showColWidth );
|
||||
@@ -1180,6 +1190,8 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSizeFieldList( wxSizeEvent& event )
|
||||
m_fieldsCtrl->GetColumn( CANONICAL_NAME_COLUMN )->SetHidden( true );
|
||||
m_fieldsCtrl->GetColumn( DISPLAY_NAME_COLUMN )->SetWidth( nameColWidth );
|
||||
|
||||
m_fieldsCtrl->Refresh(); // To refresh checkboxes on Windows.
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
|
||||
switch( m_mirrorCtrl->GetSelection() )
|
||||
{
|
||||
case 0: break;
|
||||
case 0: break;
|
||||
case 1: m_symbol->SetOrientation( SYM_MIRROR_X ); break;
|
||||
case 2: m_symbol->SetOrientation( SYM_MIRROR_Y ); break;
|
||||
}
|
||||
|
||||
@@ -176,17 +176,22 @@ bool DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataToWindow()
|
||||
if( !wxDialog::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
SCHEMATIC& schematic = m_Parent->Schematic();
|
||||
|
||||
if( m_CurrentText->Type() == SCH_TEXT_T )
|
||||
{
|
||||
SCHEMATIC& schematic = m_Parent->Schematic();
|
||||
|
||||
// show text variable cross-references in a human-readable format
|
||||
m_valueMultiLine->SetValue( schematic.ConvertKIIDsToRefs( m_CurrentText->GetText() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// show control characters in a human-readable format
|
||||
m_activeTextEntry->SetValue( UnescapeString( m_CurrentText->GetText() ) );
|
||||
wxString text = UnescapeString( m_CurrentText->GetText() );
|
||||
|
||||
// show text variable cross-references in a human-readable format
|
||||
text = schematic.ConvertKIIDsToRefs( text );
|
||||
|
||||
m_activeTextEntry->SetValue( text );
|
||||
}
|
||||
|
||||
if( m_valueCombo->IsShown() )
|
||||
@@ -315,7 +320,8 @@ bool DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
|
||||
return false;
|
||||
|
||||
wxString text;
|
||||
SCHEMATIC& schematic = m_Parent->Schematic();
|
||||
wxString text;
|
||||
|
||||
/* save old text in undo list if not already in edit */
|
||||
if( m_CurrentText->GetEditFlags() == 0 )
|
||||
@@ -325,8 +331,7 @@ bool DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
|
||||
if( m_CurrentText->Type() == SCH_TEXT_T )
|
||||
{
|
||||
// convert any text variable cross-references to their UUIDs
|
||||
text = m_Parent->Schematic().ConvertRefsToKIIDs( m_valueMultiLine->GetValue() );
|
||||
text = m_valueMultiLine->GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -334,6 +339,9 @@ bool DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
text = EscapeString( m_activeTextEntry->GetValue(), CTX_NETNAME );
|
||||
}
|
||||
|
||||
// convert any text variable cross-references to their UUIDs
|
||||
text = schematic.ConvertRefsToKIIDs( text );
|
||||
|
||||
if( !text.IsEmpty() )
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
// Saved dialog settings
|
||||
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB_SAVED_STATE
|
||||
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ true, true, true, true, false };
|
||||
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ false, true, true, true, false };
|
||||
|
||||
|
||||
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2017 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2021 CERN
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -510,12 +510,11 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
|
||||
wxString detailedMsg = _( "One of the nicknames will need to be changed after "
|
||||
"adding this library." );
|
||||
|
||||
wxArrayString files;
|
||||
dlg.GetFilenames( files );
|
||||
wxArrayString filePathsList;
|
||||
dlg.GetPaths( filePathsList );
|
||||
|
||||
for( const wxString& file : files )
|
||||
for( const wxString& filePath : filePathsList )
|
||||
{
|
||||
wxString filePath = dlg.GetDirectory() + wxFileName::GetPathSeparator() + file;
|
||||
wxFileName fn( filePath );
|
||||
wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), true );
|
||||
bool doAdd = true;
|
||||
@@ -561,7 +560,7 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
|
||||
}
|
||||
}
|
||||
|
||||
if( !files.IsEmpty() )
|
||||
if( !filePathsList.IsEmpty() )
|
||||
{
|
||||
m_cur_grid->MakeCellVisible( m_cur_grid->GetNumberRows() - 1, 0 );
|
||||
m_cur_grid->SetGridCursor( m_cur_grid->GetNumberRows() - 1, 1 );
|
||||
|
||||
+5
-5
@@ -439,9 +439,13 @@ int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
std::vector<SCH_PIN*> pins;
|
||||
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
|
||||
bool has_noconnect = false;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph: net.second )
|
||||
{
|
||||
if( subgraph->m_no_connect )
|
||||
has_noconnect = true;
|
||||
|
||||
for( EDA_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
@@ -452,10 +456,6 @@ int ERC_TESTER::TestPinToPin()
|
||||
}
|
||||
}
|
||||
|
||||
// Single-pin nets are handled elsewhere
|
||||
if( pins.size() < 2 )
|
||||
continue;
|
||||
|
||||
std::set<std::pair<SCH_PIN*, SCH_PIN*>> tested;
|
||||
|
||||
SCH_PIN* needsDriver = nullptr;
|
||||
@@ -542,7 +542,7 @@ int ERC_TESTER::TestPinToPin()
|
||||
}
|
||||
}
|
||||
|
||||
if( needsDriver && !hasDriver )
|
||||
if( needsDriver && !hasDriver && !has_noconnect )
|
||||
{
|
||||
int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
|
||||
|
||||
|
||||
@@ -119,7 +119,8 @@ void FIELDS_GRID_TABLE<T>::initGrid( WX_GRID* aGrid )
|
||||
m_footprintAttr->SetEditor( fpIdEditor );
|
||||
|
||||
m_urlAttr = new wxGridCellAttr;
|
||||
GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( m_dialog );
|
||||
GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( m_dialog,
|
||||
m_frame->Prj().SchSearchS() );
|
||||
urlEditor->SetValidator( m_urlValidator );
|
||||
m_urlAttr->SetEditor( urlEditor );
|
||||
|
||||
@@ -502,7 +503,7 @@ void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue
|
||||
value = fn.GetFullPath();
|
||||
}
|
||||
}
|
||||
else if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) && aRow == VALUE_FIELD )
|
||||
else if( m_parentType == LIB_SYMBOL_T && aRow == VALUE_FIELD )
|
||||
{
|
||||
value = EscapeString( value, CTX_LIBID );
|
||||
}
|
||||
@@ -647,7 +648,7 @@ void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
else if (event.GetId() == MYID_SHOW_DATASHEET )
|
||||
{
|
||||
wxString datasheet_uri = m_grid->GetCellValue( DATASHEET_FIELD, FDC_VALUE );
|
||||
GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj() );
|
||||
GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj(), m_dlg->Prj().SchSearchS() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -632,6 +632,10 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
// Don't leave dangling pointers to previously-opened document.
|
||||
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
|
||||
ClearUndoRedoList();
|
||||
|
||||
if( setProject )
|
||||
{
|
||||
Schematic().SetProject( nullptr );
|
||||
@@ -665,8 +669,6 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
return;
|
||||
}
|
||||
|
||||
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
|
||||
|
||||
importFile( dlg.GetPath(), pluginType );
|
||||
|
||||
RefreshCanvas();
|
||||
|
||||
+30
-1
@@ -205,6 +205,34 @@ void HIERARCHY_NAVIG_DLG::buildHierarchyTree( SCH_SHEET_PATH* aList, wxTreeItemI
|
||||
}
|
||||
|
||||
|
||||
void HIERARCHY_NAVIG_DLG::UpdateHierarchySelection()
|
||||
{
|
||||
m_currSheet = m_SchFrameEditor->GetCurrentSheet();
|
||||
|
||||
std::function<void( const wxTreeItemId& )> selectSheet = [&]( const wxTreeItemId& id )
|
||||
{
|
||||
wxCHECK_RET( id.IsOk(), wxT( "Invalid tree item" ) );
|
||||
|
||||
TreeItemData* itemData = static_cast<TreeItemData*>( m_Tree->GetItemData( id ) );
|
||||
if( itemData->m_SheetPath == m_currSheet )
|
||||
{
|
||||
m_Tree->EnsureVisible( id );
|
||||
m_Tree->SelectItem( id );
|
||||
}
|
||||
|
||||
wxTreeItemIdValue cookie = id;
|
||||
wxTreeItemId child = m_Tree->GetFirstChild( id, cookie );
|
||||
while( child.IsOk() )
|
||||
{
|
||||
selectSheet( child );
|
||||
child = m_Tree->GetNextChild( child, cookie );
|
||||
}
|
||||
};
|
||||
|
||||
selectSheet( m_Tree->GetRootItem() );
|
||||
}
|
||||
|
||||
|
||||
void HIERARCHY_NAVIG_DLG::UpdateHierarchyTree()
|
||||
{
|
||||
Freeze();
|
||||
@@ -315,5 +343,6 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
||||
TOOL_EVENT dummy;
|
||||
editTool->UpdateNetHighlighting( dummy );
|
||||
|
||||
UpdateHierarchyNavigator();
|
||||
if( FindHierarchyNavigator() )
|
||||
FindHierarchyNavigator()->UpdateHierarchySelection();
|
||||
}
|
||||
|
||||
@@ -76,6 +76,11 @@ public:
|
||||
*/
|
||||
void UpdateHierarchyTree();
|
||||
|
||||
/**
|
||||
* Updates the tree's selection to match current page
|
||||
*/
|
||||
void UpdateHierarchySelection();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create the hierarchical tree of the schematic.
|
||||
|
||||
+19
-7
@@ -214,15 +214,20 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
|
||||
if( m_me == aRhs.m_me )
|
||||
return 0;
|
||||
|
||||
int retv = m_name.Cmp( aRhs.m_name );
|
||||
int retv = 0;
|
||||
|
||||
if( retv )
|
||||
return retv;
|
||||
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
|
||||
{
|
||||
retv = m_name.Cmp( aRhs.m_name );
|
||||
|
||||
retv = m_libId.compare( aRhs.m_libId );
|
||||
if( retv )
|
||||
return retv;
|
||||
|
||||
if( retv )
|
||||
return retv;
|
||||
retv = m_libId.compare( aRhs.m_libId );
|
||||
|
||||
if( retv )
|
||||
return retv;
|
||||
}
|
||||
|
||||
if( m_parent.lock() < aRhs.m_parent.lock() )
|
||||
return -1;
|
||||
@@ -258,8 +263,15 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
|
||||
{
|
||||
const LIB_FIELD* lhsField = static_cast<const LIB_FIELD*>( lhsItem );
|
||||
|
||||
if( lhsField->IsMandatory() )
|
||||
if( lhsField->GetId() == VALUE_FIELD )
|
||||
{
|
||||
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 || IsPower() )
|
||||
retv = lhsItem->compare( *rhsItem, aCompareFlags );
|
||||
}
|
||||
else if( lhsField->IsMandatory() )
|
||||
{
|
||||
retv = lhsItem->compare( *rhsItem, aCompareFlags );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -73,6 +73,7 @@ EDA_ITEM* LIB_TEXT::Clone() const
|
||||
{
|
||||
LIB_TEXT* newitem = new LIB_TEXT( nullptr );
|
||||
|
||||
newitem->m_parent = m_parent;
|
||||
newitem->m_unit = m_unit;
|
||||
newitem->m_convert = m_convert;
|
||||
newitem->m_flags = m_flags;
|
||||
|
||||
@@ -62,17 +62,20 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
|
||||
if( !openRecentMenu )
|
||||
{
|
||||
openRecentMenu = new ACTION_MENU( false, selTool );
|
||||
openRecentMenu->SetTitle( _( "Open Recent" ) );
|
||||
openRecentMenu->SetIcon( BITMAPS::recent );
|
||||
|
||||
fileHistory.UseMenu( openRecentMenu );
|
||||
fileHistory.AddFilesToMenu( openRecentMenu );
|
||||
}
|
||||
|
||||
// Ensure the title is up to date after changing language
|
||||
openRecentMenu->SetTitle( _( "Open Recent" ) );
|
||||
fileHistory.UpdateClearText( openRecentMenu, _( "Clear Recent Files" ) );
|
||||
|
||||
fileMenu->Add( ACTIONS::doNew );
|
||||
fileMenu->Add( ACTIONS::open );
|
||||
|
||||
wxMenuItem* item = fileMenu->Add( openRecentMenu );
|
||||
wxMenuItem* item = fileMenu->Add( openRecentMenu->Clone() );
|
||||
|
||||
// Add the file menu condition here since it needs the item ID for the submenu
|
||||
ACTION_CONDITIONS cond;
|
||||
|
||||
@@ -63,9 +63,20 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceDevice( const wxString& aSymbol ) cons
|
||||
|
||||
bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
FILE_OUTPUTFORMATTER outputFile( aOutFileName, wxT( "wt" ), '\'' );
|
||||
try
|
||||
{
|
||||
FILE_OUTPUTFORMATTER outputFile( aOutFileName, wxT( "wt" ), '\'' );
|
||||
|
||||
return Format( &outputFile, aNetlistOptions );
|
||||
|
||||
return Format( &outputFile, aNetlistOptions );
|
||||
}
|
||||
catch( IO_ERROR& )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Failed to create file '%s'." ), aOutFileName );
|
||||
DisplayError( nullptr, msg );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -209,12 +220,12 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceFieldDefVal( SPICE_FIELD aField, SCH_S
|
||||
wxString value = aSymbol->GetField( VALUE_FIELD )->GetShownText();
|
||||
|
||||
// Is it a passive component?
|
||||
if( aCtl & NET_ADJUST_PASSIVE_VALS && ( prim == 'C' || prim == 'L' || prim == 'R' ) )
|
||||
if( ( aCtl & NET_ADJUST_PASSIVE_VALS ) && ( prim == 'C' || prim == 'L' || prim == 'R' ) )
|
||||
{
|
||||
// Regular expression to match common formats used for passive parts description
|
||||
// (e.g. 100k, 2k3, 1 uF)
|
||||
wxRegEx passiveVal(
|
||||
"^([0-9\\. ]+)([fFpPnNuUmMkKgGtT]|M(e|E)(g|G))?([fFhH]|ohm)?([-1-9 ]*)$" );
|
||||
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
|
||||
|
||||
if( passiveVal.Matches( value ) )
|
||||
{
|
||||
|
||||
+11
-13
@@ -25,9 +25,8 @@
|
||||
#include "pin_numbers.h"
|
||||
#include <wx/crt.h>
|
||||
|
||||
namespace {
|
||||
|
||||
wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
|
||||
wxString PIN_NUMBERS::getNextSymbol( const wxString& str, wxString::size_type& cursor )
|
||||
{
|
||||
if( str.size() <= cursor )
|
||||
return wxEmptyString;
|
||||
@@ -36,14 +35,15 @@ wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
|
||||
|
||||
wxChar c = str[cursor];
|
||||
|
||||
if( wxIsdigit( c ) || c == '+' || c == '-' )
|
||||
// Need to check that there is a digit in the string before we parse it as a numeric
|
||||
if( ( wxIsdigit( c ) || ( ( c == '+' || c == '-' ) && ( cursor < str.size() - 1 ) && wxIsdigit( str[cursor + 1] ) ) ) )
|
||||
{
|
||||
// number, possibly with sign
|
||||
while( ++cursor < str.size() )
|
||||
{
|
||||
c = str[cursor];
|
||||
|
||||
if( wxIsdigit( c ) || c == 'v' || c == 'V' )
|
||||
if( wxIsdigit( c ) || c == 'v' || c == 'V' || c == '.' )
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
@@ -65,8 +65,6 @@ wxString GetNextSymbol( const wxString& str, wxString::size_type& cursor )
|
||||
return str.substr( begin, cursor - begin );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
wxString PIN_NUMBERS::GetSummary() const
|
||||
{
|
||||
@@ -117,8 +115,8 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
symbol1 = GetNextSymbol( lhs, cursor1 );
|
||||
symbol2 = GetNextSymbol( rhs, cursor2 );
|
||||
symbol1 = getNextSymbol( lhs, cursor1 );
|
||||
symbol2 = getNextSymbol( rhs, cursor2 );
|
||||
|
||||
if( symbol1.empty() && symbol2.empty() )
|
||||
return 0;
|
||||
@@ -129,12 +127,12 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
|
||||
if( symbol2.empty() )
|
||||
return 2;
|
||||
|
||||
wxChar c1 = symbol1[0];
|
||||
wxChar c2 = symbol2[0];
|
||||
bool sym1_isnumeric = symbol1.find_first_of( "0123456789" ) != wxString::npos;
|
||||
bool sym2_isnumeric = symbol2.find_first_of( "0123456789" ) != wxString::npos;
|
||||
|
||||
if( wxIsdigit( c1 ) || c1 == '-' || c1 == '+' )
|
||||
if( sym1_isnumeric )
|
||||
{
|
||||
if( wxIsdigit( c2 ) || c2 == '-' || c2 == '+' )
|
||||
if( sym2_isnumeric )
|
||||
{
|
||||
// numeric comparison
|
||||
wxString::size_type v1 = symbol1.find_first_of( wxT( "vV" ) );
|
||||
@@ -173,7 +171,7 @@ int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( wxIsdigit( c2 ) || c2 == '-' || c2 == '+' )
|
||||
if( sym2_isnumeric )
|
||||
return 2;
|
||||
|
||||
int res = symbol1.Cmp( symbol2 );
|
||||
|
||||
@@ -47,6 +47,8 @@ private:
|
||||
|
||||
typedef std::set<wxString, less> container_type;
|
||||
|
||||
static wxString getNextSymbol( const wxString& str, wxString::size_type& cursor );
|
||||
|
||||
public:
|
||||
typedef container_type::value_type value_type;
|
||||
typedef container_type::iterator iterator;
|
||||
|
||||
+29
-8
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <core/arraydim.h>
|
||||
#include <lib_pin.h>
|
||||
#include <pin_type.h>
|
||||
#include "pgm_base.h"
|
||||
|
||||
|
||||
// These are true singletons so it's OK for them to be globals.
|
||||
@@ -46,8 +47,8 @@ struct pinTypeStruct
|
||||
BITMAPS bitmap;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
const std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> pinTypes = {
|
||||
|
||||
std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinTypes = {
|
||||
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
|
||||
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
|
||||
@@ -61,7 +62,9 @@ const std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> pinTypes = {
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
int g_pinTypesLanguage = wxLANGUAGE_UNKNOWN;
|
||||
|
||||
|
||||
struct pinShapeStruct
|
||||
@@ -236,9 +239,27 @@ const std::vector<BITMAPS>& PinOrientationIcons()
|
||||
|
||||
wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
auto findIt = pinTypes.find( aType );
|
||||
if( g_pinTypesLanguage != Pgm().GetSelectedLanguageIdentifier() )
|
||||
{
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_INPUT].name = _( "Input" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OUTPUT].name = _( "Output" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_BIDI].name = _( "Bidirectional" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_TRISTATE].name = _( "Tri-state" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_PASSIVE].name = _( "Passive" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_NIC].name = _( "Free" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_UNSPECIFIED].name = _( "Unspecified" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_IN].name = _( "Power input" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_OUT].name = _( "Power output" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR].name = _( "Open collector" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENEMITTER].name = _( "Open emitter" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_NC].name = _( "Unconnected" );
|
||||
|
||||
wxCHECK_MSG( findIt != pinTypes.end(), wxT( "???" ), "Could not find pin type in lookup map" );
|
||||
g_pinTypesLanguage = Pgm().GetSelectedLanguageIdentifier();
|
||||
}
|
||||
|
||||
auto findIt = g_pinTypes.find( aType );
|
||||
|
||||
wxCHECK_MSG( findIt != g_pinTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
|
||||
|
||||
return findIt->second.name;
|
||||
}
|
||||
@@ -246,9 +267,9 @@ wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
|
||||
|
||||
BITMAPS ElectricalPinTypeGetBitmap( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
auto findIt = pinTypes.find( aType );
|
||||
auto findIt = g_pinTypes.find( aType );
|
||||
|
||||
wxCHECK_MSG( findIt != pinTypes.end(), BITMAPS::INVALID_BITMAP,
|
||||
wxCHECK_MSG( findIt != g_pinTypes.end(), BITMAPS::INVALID_BITMAP,
|
||||
wxT( "Could not find pin type in lookup map" ) );
|
||||
|
||||
return findIt->second.bitmap;
|
||||
|
||||
+20
-14
@@ -34,6 +34,7 @@
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <schematic.h>
|
||||
#include <string_utils.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
@@ -100,17 +101,6 @@ static LIB_SYMBOL* findSymbol( const wxString& aName, SYMBOL_LIBS* aLibs, bool a
|
||||
|
||||
symbol = each_lib.FindSymbol( aName );
|
||||
|
||||
// At some point during V5 development, the LIB_ID delimiter character ':' was
|
||||
// replaced by '_' when writing the symbol cache library so we have to test for
|
||||
// the LIB_NICKNAME_LIB_SYMBOL_NAME case.
|
||||
if( symbol == nullptr && each_lib.IsCache() )
|
||||
{
|
||||
wxString name = aName;
|
||||
|
||||
if( name.Replace( wxT( ":" ), wxT( "_" ) ) )
|
||||
symbol = each_lib.FindSymbol( name );
|
||||
}
|
||||
|
||||
if( symbol )
|
||||
break;
|
||||
}
|
||||
@@ -160,7 +150,7 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
|
||||
for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) )
|
||||
{
|
||||
symbol_name = eachSymbol->GetLibId().GetLibItemName();
|
||||
search_name = LIB_ID::FixIllegalChars( symbol_name, false );
|
||||
search_name = EscapeString ( symbol_name, CTX_LIBID );
|
||||
|
||||
if( last_symbol_name != symbol_name )
|
||||
{
|
||||
@@ -265,7 +255,7 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
|
||||
for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) )
|
||||
{
|
||||
symbol_name = eachSymbol->GetLibId().GetLibItemName();
|
||||
search_name = LIB_ID::FixIllegalChars( symbol_name, false );
|
||||
search_name = EscapeString ( symbol_name, CTX_LIBID );
|
||||
|
||||
if( old_symbol_name != symbol_name )
|
||||
{
|
||||
@@ -388,6 +378,8 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
|
||||
LIB_SYMBOL* lib_match = nullptr;
|
||||
LIB_ID old_symbol_id;
|
||||
|
||||
wxString escapedSymbolName;
|
||||
|
||||
for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) )
|
||||
{
|
||||
const LIB_ID& symbol_id = eachSymbol->GetLibId();
|
||||
@@ -398,11 +390,25 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
|
||||
// Search the symbol names candidates only once for this group:
|
||||
old_symbol_id = symbol_id;
|
||||
|
||||
escapedSymbolName = EscapeString( symbol_id.Format().wx_str(), CTX_LIBID );
|
||||
|
||||
// Get the library symbol from the cache library. It will be a flattened
|
||||
// symbol by default (no inheritance).
|
||||
cache_match = findSymbol( symbol_id.Format().wx_str(), aRescuer.GetPrj()->SchLibs(),
|
||||
cache_match = findSymbol( escapedSymbolName, aRescuer.GetPrj()->SchLibs(),
|
||||
true );
|
||||
|
||||
// At some point during V5 development, the LIB_ID delimiter character ':' was
|
||||
// replaced by '_' when writing the symbol cache library so we have to test for
|
||||
// the LIB_NICKNAME_LIB_SYMBOL_NAME case.
|
||||
if( !cache_match )
|
||||
{
|
||||
escapedSymbolName = EscapeString( symbol_id.GetLibNickname().wx_str() +
|
||||
wxT( "_" ) + symbol_id.GetLibItemName().wx_str(),
|
||||
CTX_LIBID );
|
||||
cache_match = findSymbol( escapedSymbolName, aRescuer.GetPrj()->SchLibs(),
|
||||
true );
|
||||
}
|
||||
|
||||
// Get the library symbol from the symbol library table.
|
||||
lib_match = SchGetLibSymbol( symbol_id, aRescuer.GetPrj()->SchSymbolLibTable() );
|
||||
|
||||
|
||||
@@ -1502,6 +1502,8 @@ void SCH_EDIT_FRAME::ShowChangedLanguage()
|
||||
// status bar
|
||||
UpdateMsgPanel();
|
||||
|
||||
UpdateTitle();
|
||||
|
||||
// This ugly hack is to fix an option(left) toolbar update bug that seems to only affect
|
||||
// windows. See https://bugs.launchpad.net/kicad/+bug/1816492. For some reason, calling
|
||||
// wxWindow::Refresh() does not resolve the issue. Only a resize event seems to force the
|
||||
|
||||
@@ -1013,10 +1013,10 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
|
||||
c = getRenderColor( aPin, LAYER_HIDDEN, drawingShadows );
|
||||
}
|
||||
|
||||
float insideOffset = textOffset - thickness[INSIDE] / 2.0;
|
||||
float outsideOffset = 2 * Mils2iu( PIN_TEXT_MARGIN ) - thickness[OUTSIDE] / 2.0;
|
||||
float aboveOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[ABOVE] + penWidth ) / 2.0;
|
||||
float belowOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[BELOW] + penWidth ) / 2.0;
|
||||
float insideOffset = textOffset - thickness[INSIDE] / 2.0;
|
||||
float outsideOffset = Mils2iu( PIN_TEXT_MARGIN ) + TARGET_PIN_RADIUS - thickness[OUTSIDE] / 2.0;
|
||||
float aboveOffset = Mils2iu( PIN_TEXT_MARGIN ) + penWidth / 2.0 + thickness[ABOVE] / 2.0;
|
||||
float belowOffset = Mils2iu( PIN_TEXT_MARGIN ) + penWidth / 2.0 + thickness[BELOW] / 2.0;
|
||||
|
||||
if( isDangling )
|
||||
outsideOffset += TARGET_PIN_RADIUS / 2.0;
|
||||
|
||||
@@ -1308,6 +1308,13 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
|
||||
SYMDEF_SCM symbol = Library.SymbolDefinitions.at( aSymdefID );
|
||||
int gateNumber = getKiCadUnitNumberFromGate( aGateID );
|
||||
|
||||
// Ensure there are no items on this unit (e.g. if we already previously loaded the symbol from
|
||||
// the part definition)
|
||||
std::vector<LIB_ITEM*> drawItems = aSymbol->GetUnitDrawItems( gateNumber, 0 );
|
||||
|
||||
for( LIB_ITEM* item : drawItems )
|
||||
aSymbol->RemoveDrawItem( item );
|
||||
|
||||
for( std::pair<FIGURE_ID, FIGURE> figPair : symbol.Figures )
|
||||
{
|
||||
FIGURE fig = figPair.second;
|
||||
|
||||
@@ -692,15 +692,21 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
||||
if( sheet_count > 1 )
|
||||
{
|
||||
int x, y, i;
|
||||
i = 1;
|
||||
i = 2;
|
||||
x = 1;
|
||||
y = 1;
|
||||
|
||||
SCH_SHEET_PATH rootsheetpath;
|
||||
rootsheetpath.push_back( m_rootSheet );
|
||||
m_rootSheet->AddInstance( rootsheetpath );
|
||||
m_rootSheet->SetPageNumber( rootsheetpath, wxT( "1" ) );
|
||||
|
||||
while( sheetNode )
|
||||
{
|
||||
wxPoint pos = wxPoint( x * Mils2iu( 1000 ), y * Mils2iu( 1000 ) );
|
||||
std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( m_rootSheet, pos );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
|
||||
wxString pageNo = wxString::Format( wxT( "%d" ), i );
|
||||
|
||||
sheet->SetScreen( screen );
|
||||
sheet->GetScreen()->SetFileName( sheet->GetFileName() );
|
||||
@@ -711,10 +717,10 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
||||
|
||||
SCH_SHEET_PATH sheetpath;
|
||||
m_rootSheet->LocatePathOfScreen( m_currentSheet->GetScreen(), &sheetpath );
|
||||
sheetpath.push_back( m_currentSheet );
|
||||
|
||||
m_currentSheet->AddInstance( sheetpath );
|
||||
m_currentSheet->SetPageNumber( sheetpath, pageNo );
|
||||
m_rootSheet->AddInstance( sheetpath );
|
||||
m_rootSheet->SetPageNumber( sheetpath, wxString::Format( wxT( "%d" ), i ) );
|
||||
m_rootSheet->SetPageNumber( sheetpath, pageNo );
|
||||
|
||||
sheetNode = sheetNode->GetNext();
|
||||
x += 2;
|
||||
|
||||
@@ -1569,15 +1569,15 @@ void SCH_SEXPR_PARSER::parsePAGE_INFO( PAGE_INFO& aPageInfo )
|
||||
// Perform some controls to avoid crashes if the size is edited by hands
|
||||
if( width < MIN_PAGE_SIZE_MILS )
|
||||
width = MIN_PAGE_SIZE_MILS;
|
||||
else if( width > MAX_PAGE_SIZE_MILS )
|
||||
width = MAX_PAGE_SIZE_MILS;
|
||||
else if( width > MAX_PAGE_SIZE_EESCHEMA_MILS )
|
||||
width = MAX_PAGE_SIZE_EESCHEMA_MILS;
|
||||
|
||||
int height = Mm2mils( parseDouble( "height" ) ); // height stored in mm so we convert to mils
|
||||
|
||||
if( height < MIN_PAGE_SIZE_MILS )
|
||||
height = MIN_PAGE_SIZE_MILS;
|
||||
else if( height > MAX_PAGE_SIZE_MILS )
|
||||
height = MAX_PAGE_SIZE_MILS;
|
||||
else if( height > MAX_PAGE_SIZE_EESCHEMA_MILS )
|
||||
height = MAX_PAGE_SIZE_EESCHEMA_MILS;
|
||||
|
||||
aPageInfo.SetWidthMils( width );
|
||||
aPageInfo.SetHeightMils( height );
|
||||
|
||||
@@ -2833,7 +2833,13 @@ LIB_SYMBOL* SCH_LEGACY_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorV
|
||||
wxString name, prefix, tmp;
|
||||
|
||||
name = tokens.GetNextToken();
|
||||
name = EscapeString( name, CTX_LIBID );
|
||||
|
||||
// Don't escape symbol library name if it's already been escaped. Given that the original
|
||||
// change to escape the symbol library name has resulted in rescue libraries with escaped
|
||||
// names, we will have to live with the consequences.
|
||||
if( name == UnescapeString( name ) )
|
||||
name = EscapeString( name, CTX_LIBID );
|
||||
|
||||
pos += name.size() + 1;
|
||||
|
||||
prefix = tokens.GetNextToken();
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace std
|
||||
|
||||
SCH_SHEET_PATH::SCH_SHEET_PATH()
|
||||
{
|
||||
m_virtualPageNumber = 0;
|
||||
m_virtualPageNumber = 1;
|
||||
m_current_hash = 0;
|
||||
}
|
||||
|
||||
|
||||
+49
-6
@@ -237,6 +237,27 @@ void SCH_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SYMBOL::IsMovableFromAnchorPoint() const
|
||||
{
|
||||
// If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is
|
||||
// going to end up moving the symbol's pins off-grid.
|
||||
|
||||
// The minimal grid size allowed to place a pin is 25 mils
|
||||
const int min_grid_size = Mils2iu( 25 );
|
||||
|
||||
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
|
||||
{
|
||||
if( ( ( pin->GetPosition().x - m_pos.x ) % min_grid_size ) != 0 )
|
||||
return false;
|
||||
|
||||
if( ( ( pin->GetPosition().y - m_pos.y ) % min_grid_size ) != 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
|
||||
{
|
||||
if( m_lib_id != aLibId )
|
||||
@@ -604,9 +625,9 @@ void SCH_SYMBOL::SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue )
|
||||
{
|
||||
if( sheet == nullptr )
|
||||
{
|
||||
// Clear instance overrides and set primary field value
|
||||
// Set all instances to the updated value
|
||||
for( SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
instance.m_Value = wxEmptyString;
|
||||
instance.m_Value = aValue;
|
||||
|
||||
m_fields[ VALUE_FIELD ].SetText( aValue );
|
||||
return;
|
||||
@@ -655,9 +676,9 @@ void SCH_SYMBOL::SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFoo
|
||||
{
|
||||
if( sheet == nullptr )
|
||||
{
|
||||
// Clear instance overrides and set primary field value
|
||||
// Set all instances to new footprint value
|
||||
for( SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
|
||||
instance.m_Footprint = wxEmptyString;
|
||||
instance.m_Footprint = aFootprint;
|
||||
|
||||
m_fields[ FOOTPRINT_FIELD ].SetText( aFootprint );
|
||||
return;
|
||||
@@ -865,7 +886,7 @@ void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
|
||||
}
|
||||
|
||||
|
||||
SCH_PIN* SCH_SYMBOL::GetPin( LIB_PIN* aLibPin )
|
||||
SCH_PIN* SCH_SYMBOL::GetPin( LIB_PIN* aLibPin ) const
|
||||
{
|
||||
wxASSERT( m_pinMap.count( aLibPin ) );
|
||||
return m_pins[ m_pinMap.at( aLibPin ) ].get();
|
||||
@@ -1856,10 +1877,32 @@ void SCH_SYMBOL::Plot( PLOTTER* aPlotter ) const
|
||||
{
|
||||
if( m_part )
|
||||
{
|
||||
LIB_PINS libPins;
|
||||
m_part->GetPins( libPins, GetUnit(), GetConvert() );
|
||||
|
||||
// Copy the source so we can re-orient and translate it.
|
||||
LIB_SYMBOL tempSymbol( *m_part );
|
||||
LIB_PINS tempPins;
|
||||
tempSymbol.GetPins( tempPins, GetUnit(), GetConvert() );
|
||||
|
||||
// Copy the pin info from the symbol to the temp pins
|
||||
for( unsigned i = 0; i < tempPins.size(); ++ i )
|
||||
{
|
||||
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
|
||||
LIB_PIN* tempPin = tempPins[ i ];
|
||||
|
||||
tempPin->SetName( symbolPin->GetShownName() );
|
||||
tempPin->SetType( symbolPin->GetType() );
|
||||
tempPin->SetShape( symbolPin->GetShape() );
|
||||
|
||||
if( symbolPin->IsDangling() )
|
||||
tempPin->SetFlags( IS_DANGLING );
|
||||
}
|
||||
|
||||
TRANSFORM temp = GetTransform();
|
||||
aPlotter->StartBlock( nullptr );
|
||||
|
||||
m_part->Plot( aPlotter, GetUnit(), GetConvert(), m_pos, temp );
|
||||
tempSymbol.Plot( aPlotter, GetUnit(), GetConvert(), m_pos, temp );
|
||||
|
||||
for( SCH_FIELD field : m_fields )
|
||||
field.Plot( aPlotter );
|
||||
|
||||
@@ -138,9 +138,10 @@ public:
|
||||
* they are big. However, this annoyed some users and we now have a preference which
|
||||
* controls warping on move in general, so this was switched to true for symbols.
|
||||
*
|
||||
* @return true for a symbol.
|
||||
* @note We now use this to keep poorly-formed symbols from getting dragged off-grid. If
|
||||
* the symbol contains off-grid pins we will not allow it to be moved from its anchor.
|
||||
*/
|
||||
bool IsMovableFromAnchorPoint() const override { return true; }
|
||||
bool IsMovableFromAnchorPoint() const override;
|
||||
|
||||
void SetLibId( const LIB_ID& aName );
|
||||
|
||||
@@ -455,7 +456,7 @@ public:
|
||||
*/
|
||||
void GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const;
|
||||
|
||||
SCH_PIN* GetPin( LIB_PIN* aLibPin );
|
||||
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
||||
|
||||
/**
|
||||
* Retrieve a list of the SCH_PINs for the given sheet path.
|
||||
|
||||
+10
-13
@@ -619,21 +619,18 @@ wxString SCH_TEXT::GetShownText( int aDepth ) const
|
||||
return true;
|
||||
}
|
||||
|
||||
if( Type() == SCH_TEXT_T )
|
||||
if( token->Contains( ':' ) )
|
||||
{
|
||||
if( token->Contains( ':' ) )
|
||||
{
|
||||
if( Schematic()->ResolveCrossReference( token, aDepth ) )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCHEMATIC* schematic = Schematic();
|
||||
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
|
||||
if( Schematic()->ResolveCrossReference( token, aDepth ) )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCHEMATIC* schematic = Schematic();
|
||||
SCH_SHEET* sheet = schematic ? schematic->CurrentSheet().Last() : nullptr;
|
||||
|
||||
if( sheet && sheet->ResolveTextVar( token, aDepth + 1 ) )
|
||||
return true;
|
||||
}
|
||||
if( sheet && sheet->ResolveTextVar( token, aDepth + 1 ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,7 @@ SCH_VIEW::SCH_VIEW( bool aIsDynamic, SCH_BASE_FRAME* aFrame ) :
|
||||
// Set m_boundary to define the max working area size. The default value is acceptable for
|
||||
// Pcbnew and Gerbview, but too large for Eeschema due to very different internal units.
|
||||
// A full size = 3 * MAX_PAGE_SIZE_MILS size allows a wide margin around the drawing-sheet.
|
||||
double max_size = Mils2iu( MAX_PAGE_SIZE_MILS ) * 3.0;
|
||||
double max_size = Mils2iu( MAX_PAGE_SIZE_EESCHEMA_MILS ) * 3.0;
|
||||
m_boundary.SetOrigin( -max_size/4, -max_size/4 );
|
||||
m_boundary.SetSize( max_size, max_size );
|
||||
}
|
||||
|
||||
+192
-189
@@ -206,229 +206,232 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||
wxMessageDialog::ButtonLabel okButtonLabel( _( "Continue Load" ) );
|
||||
wxMessageDialog::ButtonLabel cancelButtonLabel( _( "Cancel Load" ) );
|
||||
|
||||
if( fileName.GetPathWithSep() == Prj().GetProjectPath()
|
||||
&& !prjScreens.HasSchematic( fullFilename ) )
|
||||
if( !prjScreens.HasSchematic( fullFilename ) )
|
||||
{
|
||||
// A schematic in the current project path that isn't part of the current project.
|
||||
// It's possible the user copied this schematic from another project so the library
|
||||
// links may not be available. Even this is check is no guarantee that all symbol
|
||||
// library links are valid but it's better than nothing.
|
||||
for( const wxString& name : names )
|
||||
if( fileName.GetPathWithSep() == Prj().GetProjectPath() )
|
||||
{
|
||||
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
|
||||
newLibNames.Add( name );
|
||||
}
|
||||
|
||||
if( !newLibNames.IsEmpty() )
|
||||
{
|
||||
msg = _( "There are library names in the loaded schematic that are missing "
|
||||
"from the project library table. This may result in broken symbol "
|
||||
"library links for the loaded schematic. Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg3( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
|
||||
if( msgDlg3.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
|
||||
{
|
||||
// A schematic loaded from a path other than the current project path.
|
||||
|
||||
// If there are symbol libraries in the imported schematic that are not in the
|
||||
// symbol library table of this project, there could be a lot of broken symbol
|
||||
// library links. Attempt to add the missing libraries to the project symbol
|
||||
// library table.
|
||||
wxArrayString duplicateLibNames;
|
||||
|
||||
for( const wxString& name : names )
|
||||
{
|
||||
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
|
||||
newLibNames.Add( name );
|
||||
else
|
||||
duplicateLibNames.Add( name );
|
||||
}
|
||||
|
||||
SYMBOL_LIB_TABLE table;
|
||||
wxFileName symLibTableFn( fileName.GetPath(),
|
||||
SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
|
||||
|
||||
// If there are any new or duplicate libraries, check to see if it's possible that
|
||||
// there could be any missing libraries that would cause broken symbol library links.
|
||||
if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
|
||||
{
|
||||
if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
|
||||
// A schematic in the current project path that isn't part of the current project.
|
||||
// It's possible the user copied this schematic from another project so the library
|
||||
// links may not be available. Even this is check is no guarantee that all symbol
|
||||
// library links are valid but it's better than nothing.
|
||||
for( const wxString& name : names )
|
||||
{
|
||||
msg.Printf( _( "The project library table '%s' does not exist or cannot "
|
||||
"be read. This may result in broken symbol links for the "
|
||||
"schematic. Do you wish to continue?" ),
|
||||
symLibTableFn.GetFullPath() );
|
||||
wxMessageDialog msgDlg4( this, msg, _( "Continue Load Schematic" ),
|
||||
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
|
||||
newLibNames.Add( name );
|
||||
}
|
||||
|
||||
if( !newLibNames.IsEmpty() )
|
||||
{
|
||||
msg = _( "There are library names in the selected schematic that are missing "
|
||||
"from the current project library table. This may result in broken "
|
||||
"symbol library references for the loaded schematic.\n\n"
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg3( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
|
||||
if( msgDlg4.ShowModal() == wxID_CANCEL )
|
||||
if( msgDlg3.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
table.Load( symLibTableFn.GetFullPath() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Error loading the symbol library table '%s'." ),
|
||||
symLibTableFn.GetFullPath() );
|
||||
DisplayErrorMessage( nullptr, msg, ioe.What() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if any of the symbol libraries found in the appended schematic do
|
||||
// not exist in the current project are missing from the appended project symbol
|
||||
// library table.
|
||||
if( !newLibNames.IsEmpty() )
|
||||
else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
|
||||
{
|
||||
bool missingLibNames = table.IsEmpty();
|
||||
// A schematic loaded from a path other than the current project path.
|
||||
|
||||
if( !missingLibNames )
|
||||
// If there are symbol libraries in the imported schematic that are not in the
|
||||
// symbol library table of this project, there could be a lot of broken symbol
|
||||
// library links. Attempt to add the missing libraries to the project symbol
|
||||
// library table.
|
||||
wxArrayString duplicateLibNames;
|
||||
|
||||
for( const wxString& name : names )
|
||||
{
|
||||
for( const wxString& newLibName : newLibNames )
|
||||
if( !Prj().SchSymbolLibTable()->HasLibrary( name ) )
|
||||
newLibNames.Add( name );
|
||||
else
|
||||
duplicateLibNames.Add( name );
|
||||
}
|
||||
|
||||
SYMBOL_LIB_TABLE table;
|
||||
wxFileName symLibTableFn( fileName.GetPath(),
|
||||
SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
|
||||
|
||||
// If there are any new or duplicate libraries, check to see if it's possible that
|
||||
// there could be any missing libraries that would cause broken symbol library links.
|
||||
if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
|
||||
{
|
||||
if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
|
||||
{
|
||||
if( !table.HasLibrary( newLibName ) )
|
||||
msg = _( "The selected file was created as part of a different project. "
|
||||
"Linking the file to this project may result in missing or "
|
||||
"incorrect symbol library references.\n\n"
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg4( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
|
||||
if( msgDlg4.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
missingLibNames = true;
|
||||
break;
|
||||
table.Load( symLibTableFn.GetFullPath() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Error loading the symbol library table '%s'." ),
|
||||
symLibTableFn.GetFullPath() );
|
||||
DisplayErrorMessage( nullptr, msg, ioe.What() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( missingLibNames )
|
||||
// Check to see if any of the symbol libraries found in the appended schematic do
|
||||
// not exist in the current project are missing from the appended project symbol
|
||||
// library table.
|
||||
if( !newLibNames.IsEmpty() )
|
||||
{
|
||||
msg = _( "There are library names in the loaded schematic that are missing "
|
||||
"from the loaded schematic project library table. This may result "
|
||||
"in broken symbol library links for the schematic. "
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg5( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
bool missingLibNames = table.IsEmpty();
|
||||
|
||||
if( msgDlg5.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The library name already exists in the current project. Check to see if the
|
||||
// duplicate name is the same library in the current project. If it's not, it's
|
||||
// most likely that the symbol library links will be broken.
|
||||
if( !duplicateLibNames.IsEmpty() && !table.IsEmpty() )
|
||||
{
|
||||
bool libNameConflict = false;
|
||||
|
||||
for( const wxString& duplicateLibName : duplicateLibNames )
|
||||
{
|
||||
const SYMBOL_LIB_TABLE_ROW* thisRow = nullptr;
|
||||
const SYMBOL_LIB_TABLE_ROW* otherRow = nullptr;
|
||||
|
||||
if( Prj().SchSymbolLibTable()->HasLibrary( duplicateLibName ) )
|
||||
thisRow = Prj().SchSymbolLibTable()->FindRow( duplicateLibName );
|
||||
|
||||
if( table.HasLibrary( duplicateLibName ) )
|
||||
otherRow = table.FindRow( duplicateLibName );
|
||||
|
||||
// It's in the global library table so there is no conflict.
|
||||
if( thisRow && !otherRow )
|
||||
continue;
|
||||
|
||||
if( !thisRow || !otherRow )
|
||||
continue;
|
||||
|
||||
wxFileName otherUriFileName;
|
||||
wxString thisURI = thisRow->GetFullURI( true );
|
||||
wxString otherURI = otherRow->GetFullURI( false);
|
||||
|
||||
if( otherURI.Contains( wxT( "${KIPRJMOD}" ) ) || otherURI.Contains( wxT( "$(KIPRJMOD)" ) ) )
|
||||
if( !missingLibNames )
|
||||
{
|
||||
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
|
||||
// not expand to a valid symbol library path.
|
||||
otherUriFileName.SetPath( fileName.GetPath() );
|
||||
otherUriFileName.SetFullName( otherURI.AfterLast( '}' ) );
|
||||
otherURI = otherUriFileName.GetFullPath();
|
||||
for( const wxString& newLibName : newLibNames )
|
||||
{
|
||||
if( !table.HasLibrary( newLibName ) )
|
||||
{
|
||||
missingLibNames = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( thisURI != otherURI )
|
||||
if( missingLibNames )
|
||||
{
|
||||
libNameConflict = true;
|
||||
break;
|
||||
msg = _( "There are symbol library names in the selected schematic that "
|
||||
"are missing from the selected schematic project library table. "
|
||||
"This may result in broken symbol library references.\n\n"
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg5( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
|
||||
if( msgDlg5.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( libNameConflict )
|
||||
// The library name already exists in the current project. Check to see if the
|
||||
// duplicate name is the same library in the current project. If it's not, it's
|
||||
// most likely that the symbol library links will be broken.
|
||||
if( !duplicateLibNames.IsEmpty() && !table.IsEmpty() )
|
||||
{
|
||||
msg = _( "A duplicate library name that references a different library exists "
|
||||
"in the current library table. This conflict cannot be resolved and "
|
||||
"may result in broken symbol library links for the schematic. "
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg6( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
bool libNameConflict = false;
|
||||
|
||||
if( msgDlg6.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
for( const wxString& duplicateLibName : duplicateLibNames )
|
||||
{
|
||||
const SYMBOL_LIB_TABLE_ROW* thisRow = nullptr;
|
||||
const SYMBOL_LIB_TABLE_ROW* otherRow = nullptr;
|
||||
|
||||
if( Prj().SchSymbolLibTable()->HasLibrary( duplicateLibName ) )
|
||||
thisRow = Prj().SchSymbolLibTable()->FindRow( duplicateLibName );
|
||||
|
||||
if( table.HasLibrary( duplicateLibName ) )
|
||||
otherRow = table.FindRow( duplicateLibName );
|
||||
|
||||
// It's in the global library table so there is no conflict.
|
||||
if( thisRow && !otherRow )
|
||||
continue;
|
||||
|
||||
if( !thisRow || !otherRow )
|
||||
continue;
|
||||
|
||||
wxFileName otherUriFileName;
|
||||
wxString thisURI = thisRow->GetFullURI( true );
|
||||
wxString otherURI = otherRow->GetFullURI( false);
|
||||
|
||||
if( otherURI.Contains( "${KIPRJMOD}" ) || otherURI.Contains( "$(KIPRJMOD)" ) )
|
||||
{
|
||||
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
|
||||
// not expand to a valid symbol library path.
|
||||
otherUriFileName.SetPath( fileName.GetPath() );
|
||||
otherUriFileName.SetFullName( otherURI.AfterLast( '}' ) );
|
||||
otherURI = otherUriFileName.GetFullPath();
|
||||
}
|
||||
|
||||
if( thisURI != otherURI )
|
||||
{
|
||||
libNameConflict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( libNameConflict )
|
||||
{
|
||||
msg = _( "A duplicate library name that references a different library exists "
|
||||
"in the current library table. This conflict cannot be resolved and "
|
||||
"may result in broken symbol library references.\n\n"
|
||||
"Do you wish to continue?" );
|
||||
wxMessageDialog msgDlg6( this, msg, _( "Continue Load Schematic" ),
|
||||
wxOK | wxCANCEL | wxCANCEL_DEFAULT |
|
||||
wxCENTER | wxICON_QUESTION );
|
||||
msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
|
||||
|
||||
if( msgDlg6.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All (most?) of the possible broken symbol library link cases are covered. Map the
|
||||
// new appended schematic project symbol library table entries to the current project
|
||||
// symbol library table.
|
||||
if( !newLibNames.IsEmpty() && !table.IsEmpty() )
|
||||
{
|
||||
for( const wxString& libName : newLibNames )
|
||||
// All (most?) of the possible broken symbol library link cases are covered. Map the
|
||||
// new appended schematic project symbol library table entries to the current project
|
||||
// symbol library table.
|
||||
if( !newLibNames.IsEmpty() && !table.IsEmpty() )
|
||||
{
|
||||
if( !table.HasLibrary( libName )
|
||||
|| Prj().SchSymbolLibTable()->HasLibrary( libName ) )
|
||||
for( const wxString& libName : newLibNames )
|
||||
{
|
||||
continue;
|
||||
if( !table.HasLibrary( libName )
|
||||
|| Prj().SchSymbolLibTable()->HasLibrary( libName ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't expand environment variable because KIPRJMOD will not be correct
|
||||
// for a different project.
|
||||
wxString uri = table.GetFullURI( libName, false );
|
||||
wxFileName newLib;
|
||||
|
||||
if( uri.Contains( "${KIPRJMOD}" ) || uri.Contains( "$(KIPRJMOD)" ) )
|
||||
{
|
||||
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
|
||||
// not expand to a valid symbol library path.
|
||||
newLib.SetPath( fileName.GetPath() );
|
||||
newLib.SetFullName( uri.AfterLast( '}' ) );
|
||||
uri = newLib.GetFullPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = table.GetFullURI( libName );
|
||||
}
|
||||
|
||||
// Add the library from the imported project to the current project
|
||||
// symbol library table.
|
||||
const SYMBOL_LIB_TABLE_ROW* row = table.FindRow( libName );
|
||||
|
||||
wxCHECK( row, false );
|
||||
|
||||
SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( libName, uri,
|
||||
row->GetType(),
|
||||
row->GetOptions(),
|
||||
row->GetDescr() );
|
||||
|
||||
Prj().SchSymbolLibTable()->InsertRow( newRow );
|
||||
libTableChanged = true;
|
||||
}
|
||||
|
||||
// Don't expand environment variable because KIPRJMOD will not be correct
|
||||
// for a different project.
|
||||
wxString uri = table.GetFullURI( libName, false );
|
||||
wxFileName newLib;
|
||||
|
||||
if( uri.Contains( wxT( "${KIPRJMOD}" ) ) || uri.Contains( wxT( "$(KIPRJMOD)" ) ) )
|
||||
{
|
||||
// Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
|
||||
// not expand to a valid symbol library path.
|
||||
newLib.SetPath( fileName.GetPath() );
|
||||
newLib.SetFullName( uri.AfterLast( '}' ) );
|
||||
uri = newLib.GetFullPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = table.GetFullURI( libName );
|
||||
}
|
||||
|
||||
// Add the library from the imported project to the current project
|
||||
// symbol library table.
|
||||
const SYMBOL_LIB_TABLE_ROW* row = table.FindRow( libName );
|
||||
|
||||
wxCHECK( row, false );
|
||||
|
||||
SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( libName, uri,
|
||||
row->GetType(),
|
||||
row->GetOptions(),
|
||||
row->GetDescr() );
|
||||
|
||||
Prj().SchSymbolLibTable()->InsertRow( newRow );
|
||||
libTableChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,10 +375,11 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
|
||||
return IsSymbolEditable() && !IsSymbolAlias();
|
||||
};
|
||||
|
||||
auto libModifiedCondition =
|
||||
auto symbolModifiedCondition =
|
||||
[this]( const SELECTION& sel )
|
||||
{
|
||||
return m_libMgr->HasModifications();
|
||||
return m_libMgr->IsSymbolModified( GetTargetLibId().GetLibItemName(),
|
||||
GetTargetLibId().GetLibNickname() );
|
||||
};
|
||||
|
||||
auto libSelectedCondition =
|
||||
@@ -408,7 +409,7 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
|
||||
|
||||
mgr->SetConditions( ACTIONS::undo, ENABLE( haveSymbolCond && cond.UndoAvailable() ) );
|
||||
mgr->SetConditions( ACTIONS::redo, ENABLE( haveSymbolCond && cond.RedoAvailable() ) );
|
||||
mgr->SetConditions( ACTIONS::revert, ENABLE( haveSymbolCond && libModifiedCondition ) );
|
||||
mgr->SetConditions( ACTIONS::revert, ENABLE( symbolModifiedCondition ) );
|
||||
|
||||
mgr->SetConditions( ACTIONS::toggleGrid, CHECK( cond.GridVisible() ) );
|
||||
mgr->SetConditions( ACTIONS::toggleCursorStyle, CHECK( cond.FullscreenCursor() ) );
|
||||
@@ -813,7 +814,9 @@ SYMBOL_LIBRARY_MANAGER& SYMBOL_EDIT_FRAME::GetLibManager()
|
||||
void SYMBOL_EDIT_FRAME::OnModify()
|
||||
{
|
||||
GetScreen()->SetContentModified();
|
||||
storeCurrentSymbol();
|
||||
|
||||
if( !IsSymbolFromSchematic() )
|
||||
storeCurrentSymbol();
|
||||
|
||||
m_treePane->GetLibTree()->RefreshLibTree();
|
||||
|
||||
@@ -1136,6 +1139,14 @@ void SYMBOL_EDIT_FRAME::ShowChangedLanguage()
|
||||
|
||||
// status bar
|
||||
UpdateMsgPanel();
|
||||
|
||||
if( GetRenderSettings()->m_ShowPinsElectricalType )
|
||||
{
|
||||
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
|
||||
GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -234,14 +234,33 @@ bool SYMBOL_EDIT_FRAME::saveCurrentSymbol()
|
||||
{
|
||||
if( GetCurSymbol() )
|
||||
{
|
||||
LIB_ID libId = GetCurSymbol()->GetLibId();
|
||||
const wxString& libName = libId.GetLibNickname();
|
||||
const wxString& symbolName = libId.GetLibItemName();
|
||||
|
||||
if( m_libMgr->FlushSymbol( symbolName, libName ) )
|
||||
if( IsSymbolFromSchematic() )
|
||||
{
|
||||
m_libMgr->ClearSymbolModified( symbolName, libName );
|
||||
return true;
|
||||
SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
|
||||
|
||||
if( !schframe ) // happens when the schematic editor has been closed
|
||||
{
|
||||
DisplayErrorMessage( this, _( "No schematic currently open." ) );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
schframe->SaveSymbolToSchematic( *m_symbol, m_schematicSymbolUUID );
|
||||
GetScreen()->SetContentModified( false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LIB_ID libId = GetCurSymbol()->GetLibId();
|
||||
const wxString& libName = libId.GetLibNickname();
|
||||
const wxString& symbolName = libId.GetLibItemName();
|
||||
|
||||
if( m_libMgr->FlushSymbol( symbolName, libName ) )
|
||||
{
|
||||
m_libMgr->ClearSymbolModified( symbolName, libName );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,14 +270,15 @@ bool SYMBOL_EDIT_FRAME::saveCurrentSymbol()
|
||||
|
||||
bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aConvert )
|
||||
{
|
||||
if( !IsSymbolFromSchematic()
|
||||
&& GetCurSymbol() && GetCurSymbol()->GetLibId() == aLibId
|
||||
&& GetUnit() == aUnit && GetConvert() == aConvert )
|
||||
if( GetCurSymbol() && !IsSymbolFromSchematic()
|
||||
&& GetCurSymbol()->GetLibId() == aLibId
|
||||
&& GetUnit() == aUnit
|
||||
&& GetConvert() == aConvert )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( GetScreen()->IsContentModified() && GetCurSymbol() )
|
||||
if( GetCurSymbol() && IsSymbolFromSchematic() && GetScreen()->IsContentModified() )
|
||||
{
|
||||
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
|
||||
[&]() -> bool
|
||||
@@ -318,7 +338,7 @@ bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, in
|
||||
return false;
|
||||
|
||||
// Enable synchronized pin edit mode for symbols with interchangeable units
|
||||
m_SyncPinEdit = !GetCurSymbol()->UnitsLocked();
|
||||
m_SyncPinEdit = GetCurSymbol()->IsMulti() && !GetCurSymbol()->UnitsLocked();
|
||||
|
||||
ClearUndoRedoList();
|
||||
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
||||
@@ -489,10 +509,6 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol()
|
||||
new_symbol.LockUnits( false );
|
||||
|
||||
new_symbol.SetConversion( dlg.GetAlternateBodyStyle() );
|
||||
|
||||
// must be called after loadSymbol, that calls SetShowDeMorgan, but
|
||||
// because the symbol is empty,it looks like it has no alternate body
|
||||
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -540,6 +556,10 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol()
|
||||
m_libMgr->UpdateSymbol( &new_symbol, lib );
|
||||
SyncLibraries( false );
|
||||
LoadSymbol( name, lib, 1 );
|
||||
|
||||
// must be called after loadSymbol, that calls SetShowDeMorgan, but
|
||||
// because the symbol is empty,it looks like it has no alternate body
|
||||
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
|
||||
}
|
||||
|
||||
|
||||
@@ -749,9 +769,12 @@ void SYMBOL_EDIT_FRAME::UpdateAfterSymbolProperties( wxString* aOldName )
|
||||
RebuildSymbolUnitsList();
|
||||
SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
|
||||
updateTitle();
|
||||
|
||||
// N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
|
||||
// the view pointers by rebuilting the field table
|
||||
RebuildView();
|
||||
UpdateMsgPanel();
|
||||
|
||||
RebuildView();
|
||||
OnModify();
|
||||
}
|
||||
|
||||
@@ -986,16 +1009,25 @@ void SYMBOL_EDIT_FRAME::RevertAll()
|
||||
|
||||
void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
|
||||
{
|
||||
if( GetCurSymbol() && IsSymbolFromSchematic() && GetScreen()->IsContentModified() )
|
||||
{
|
||||
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
|
||||
[&]() -> bool
|
||||
{
|
||||
return saveCurrentSymbol();
|
||||
} ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
|
||||
|
||||
if( !symbol )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "Symbol %s not found in library '%s'." ),
|
||||
aAlias,
|
||||
aLibrary );
|
||||
DisplayError( this, msg );
|
||||
DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
|
||||
aAlias,
|
||||
aLibrary ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -225,30 +225,38 @@ bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxStri
|
||||
{
|
||||
LIB_SYMBOL* newSymbol;
|
||||
|
||||
if( symbol->IsAlias() )
|
||||
try
|
||||
{
|
||||
std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
|
||||
|
||||
wxCHECK_MSG( oldParent, false,
|
||||
wxString::Format( wxT( "Derived symbol '%s' found with undefined parent." ),
|
||||
symbol->GetName() ) );
|
||||
|
||||
LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
|
||||
&properties );
|
||||
|
||||
if( !libParent )
|
||||
if( symbol->IsAlias() )
|
||||
{
|
||||
libParent = new LIB_SYMBOL( *oldParent.get() );
|
||||
pi->SaveSymbol( aLibrary, libParent, &properties );
|
||||
}
|
||||
std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
|
||||
|
||||
newSymbol = new LIB_SYMBOL( *symbol );
|
||||
newSymbol->SetParent( libParent );
|
||||
pi->SaveSymbol( aLibrary, newSymbol, &properties );
|
||||
wxCHECK_MSG( oldParent, false,
|
||||
wxString::Format( wxT( "Derived symbol '%s' found with undefined parent." ),
|
||||
symbol->GetName() ) );
|
||||
|
||||
LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
|
||||
&properties );
|
||||
|
||||
if( !libParent )
|
||||
{
|
||||
libParent = new LIB_SYMBOL( *oldParent.get() );
|
||||
pi->SaveSymbol( aLibrary, libParent, &properties );
|
||||
}
|
||||
|
||||
newSymbol = new LIB_SYMBOL( *symbol );
|
||||
newSymbol->SetParent( libParent );
|
||||
pi->SaveSymbol( aLibrary, newSymbol, &properties );
|
||||
}
|
||||
else if( !pi->LoadSymbol( aLibrary, symbol->GetName(), &properties ) )
|
||||
{
|
||||
pi->SaveSymbol( aLibrary, new LIB_SYMBOL( *symbol ), &properties );
|
||||
}
|
||||
}
|
||||
else if( !pi->LoadSymbol( aLibrary, symbol->GetName(), &properties ) )
|
||||
catch( ... )
|
||||
{
|
||||
pi->SaveSymbol( aLibrary, new LIB_SYMBOL( *symbol ), &properties );
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -951,11 +959,23 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFF
|
||||
PROPERTIES properties;
|
||||
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, wxEmptyString );
|
||||
|
||||
wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
|
||||
|
||||
// Delete the original symbol if the symbol name has been changed.
|
||||
if( libSymbol->GetName() != originalSymbol->GetName() )
|
||||
{
|
||||
if( aLibTable->LoadSymbol( m_libName, originalSymbol->GetName() ) )
|
||||
aLibTable->DeleteSymbol( m_libName, originalSymbol->GetName() );
|
||||
// DeleteSymbol may throw
|
||||
try
|
||||
{
|
||||
if( aLibTable->LoadSymbol( m_libName, originalSymbol->GetName() ) )
|
||||
aLibTable->DeleteSymbol( m_libName, originalSymbol->GetName() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), m_libName,
|
||||
ioe.What() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( libSymbol->IsAlias() )
|
||||
@@ -1046,8 +1066,17 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFF
|
||||
// Delete the original symbol if the symbol name has been changed.
|
||||
if( libSymbol->GetName() != originalSymbol->GetName() )
|
||||
{
|
||||
if( aPlugin->LoadSymbol( aFileName, originalSymbol->GetName() ) )
|
||||
aPlugin->DeleteSymbol( aFileName, originalSymbol->GetName(), &properties );
|
||||
try
|
||||
{
|
||||
if( aPlugin->LoadSymbol( aFileName, originalSymbol->GetName() ) )
|
||||
aPlugin->DeleteSymbol( aFileName, originalSymbol->GetName(), &properties );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), aFileName,
|
||||
ioe.What() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( libSymbol->IsAlias() )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -290,7 +290,7 @@ void BACK_ANNOTATE::checkForUnusedSymbols()
|
||||
wxString msg = wxString::Format( _( "Footprint '%s' is not present on PCB. "
|
||||
"Corresponding symbols in schematic must be "
|
||||
"manually deleted (if desired)." ),
|
||||
m_refs[i].GetFullRef() );
|
||||
m_refs[i].GetRef() );
|
||||
m_reporter.ReportTail( msg, RPT_SEVERITY_WARNING );
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
{
|
||||
++m_changesCount;
|
||||
msg.Printf( _( "Change '%s' reference designator to '%s'." ),
|
||||
ref.GetFullRef(),
|
||||
ref.GetRef(),
|
||||
fpData.m_ref );
|
||||
|
||||
if( !m_dryRun )
|
||||
@@ -344,7 +344,7 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
{
|
||||
++m_changesCount;
|
||||
msg.Printf( _( "Change %s footprint assignment from '%s' to '%s'." ),
|
||||
ref.GetFullRef(),
|
||||
ref.GetRef(),
|
||||
oldFootprint,
|
||||
fpData.m_footprint );
|
||||
|
||||
@@ -362,7 +362,7 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
{
|
||||
++m_changesCount;
|
||||
msg.Printf( _( "Change %s value from '%s' to '%s'." ),
|
||||
ref.GetFullRef(),
|
||||
ref.GetRef(),
|
||||
oldValue,
|
||||
fpData.m_value );
|
||||
|
||||
@@ -387,7 +387,7 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
if( !pin )
|
||||
{
|
||||
msg.Printf( _( "Cannot find %s pin '%s'." ),
|
||||
ref.GetFullRef(),
|
||||
ref.GetRef(),
|
||||
pinNumber );
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
|
||||
|
||||
@@ -398,7 +398,7 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
|
||||
if( connection && connection->Name( true ) != shortNetName )
|
||||
{
|
||||
processNetNameChange( ref.GetFullRef(), pin, connection,
|
||||
processNetNameChange( ref.GetRef(), pin, connection,
|
||||
connection->Name( true ), shortNetName );
|
||||
}
|
||||
}
|
||||
@@ -410,8 +410,6 @@ void BACK_ANNOTATE::applyChangelist()
|
||||
m_frame->RecalculateConnections( NO_CLEANUP );
|
||||
m_frame->UpdateNetHighlightStatus();
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_INFO );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -245,9 +245,17 @@ int EE_INSPECTION_TOOL::CheckSymbol( const TOOL_EVENT& aEvent )
|
||||
LIB_PIN* pin = pinList[ii - 1];
|
||||
LIB_PIN* next = pinList[ii];
|
||||
|
||||
if( pin->GetNumber() != next->GetNumber() || pin->GetConvert() != next->GetConvert() )
|
||||
if( pin->GetNumber() != next->GetNumber() )
|
||||
continue;
|
||||
|
||||
// Pins are not duplicated only if they are in different convert bodies
|
||||
// (but GetConvert() == 0 means commun to all convert bodies)
|
||||
if( pin->GetConvert() != 0 && next->GetConvert() != 0 )
|
||||
{
|
||||
if( pin->GetConvert() != next->GetConvert() )
|
||||
continue;
|
||||
}
|
||||
|
||||
wxString pinName;
|
||||
wxString nextName;
|
||||
|
||||
@@ -527,7 +535,7 @@ int EE_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAssociatedDocument( m_frame, datasheet, &m_frame->Prj() );
|
||||
GetAssociatedDocument( m_frame, datasheet, &m_frame->Prj(), m_frame->Prj().SchSearchS() );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 CERN
|
||||
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -133,6 +133,8 @@ protected:
|
||||
///< parents.
|
||||
void saveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aType, bool aAppend = false )
|
||||
{
|
||||
wxASSERT( aItem );
|
||||
|
||||
KICAD_T itemType = aItem->Type();
|
||||
bool selected = aItem->IsSelected();
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "sch_drawing_tools.h"
|
||||
#include "ee_selection_tool.h"
|
||||
#include "ee_grid_helper.h"
|
||||
#include <tools/sch_drawing_tools.h>
|
||||
#include <tools/ee_selection_tool.h>
|
||||
#include <tools/ee_grid_helper.h>
|
||||
#include <ee_actions.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <project.h>
|
||||
@@ -987,6 +987,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
SCH_ITEM* item = nullptr;
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
EE_GRID_HELPER grid( m_toolMgr );
|
||||
bool ignorePrimePosition = false;
|
||||
|
||||
if( m_inTwoClickPlace )
|
||||
return 0;
|
||||
@@ -1048,10 +1049,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
setCursor();
|
||||
|
||||
// Prime the pump if the tool isn't being re-activated
|
||||
if( aEvent.HasPosition() || ( !aEvent.IsReactivate()
|
||||
&& ( isText || isGlobalLabel || isHierLabel || isNetLabel ) ) )
|
||||
if( aEvent.HasPosition() )
|
||||
{
|
||||
m_toolMgr->RunAction( ACTIONS::cursorClick );
|
||||
m_toolMgr->PrimeTool( aEvent.Position() );
|
||||
}
|
||||
else if( !aEvent.IsReactivate() && ( isText
|
||||
|| isGlobalLabel
|
||||
|| isHierLabel
|
||||
|| isNetLabel ) )
|
||||
{
|
||||
m_toolMgr->PrimeTool( { 0, 0 } );
|
||||
ignorePrimePosition = true;
|
||||
}
|
||||
|
||||
// Main loop: keep receiving events
|
||||
@@ -1170,11 +1178,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
// Restore cursor after dialog
|
||||
controls->WarpCursor( controls->GetCursorPosition(), true );
|
||||
// If we started with a click on a tool button or menu then continue with the
|
||||
// current mouse position. Otherwise warp back to the original click position.
|
||||
if( evt->IsPrime() && ignorePrimePosition )
|
||||
cursorPos = grid.Align( controls->GetMousePosition() );
|
||||
else
|
||||
controls->WarpCursor( cursorPos, true );
|
||||
|
||||
if( item )
|
||||
{
|
||||
item->SetPosition( (wxPoint) cursorPos );
|
||||
|
||||
item->SetFlags( IS_NEW | IS_MOVING );
|
||||
item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
|
||||
updatePreview();
|
||||
@@ -1438,8 +1452,8 @@ void SCH_DRAWING_TOOLS::sizeSheet( SCH_SHEET* aSheet, const VECTOR2I& aPos )
|
||||
wxPoint pos = aSheet->GetPosition();
|
||||
wxPoint size = (wxPoint) aPos - pos;
|
||||
|
||||
size.x = std::max( size.x, MIN_SHEET_WIDTH );
|
||||
size.y = std::max( size.y, MIN_SHEET_HEIGHT );
|
||||
size.x = std::max( size.x, Mils2iu( MIN_SHEET_WIDTH ) );
|
||||
size.y = std::max( size.y, Mils2iu( MIN_SHEET_HEIGHT ) );
|
||||
|
||||
wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
|
||||
aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
|
||||
|
||||
@@ -671,6 +671,10 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||
if( selection.IsHover() )
|
||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
|
||||
|
||||
EE_SELECTION selectionCopy = selection;
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
|
||||
|
||||
m_frame->RecalculateConnections( LOCAL_CLEANUP );
|
||||
m_frame->TestDanglingEnds();
|
||||
|
||||
@@ -1197,22 +1201,35 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
|
||||
int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( rotatableItems );
|
||||
SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
|
||||
bool moving = head && head->IsMoving();
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
SCH_ITEM* head = static_cast<SCH_ITEM*>( selection.Front() );
|
||||
bool moving = head && head->IsMoving();
|
||||
std::vector<SCH_ITEM*> autoplaceItems;
|
||||
|
||||
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
|
||||
{
|
||||
SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
|
||||
|
||||
if( item->IsType( EE_COLLECTOR::FieldOwners ) )
|
||||
autoplaceItems.push_back( item );
|
||||
else if( item->GetParent() && item->GetParent()->IsType( EE_COLLECTOR::FieldOwners ) )
|
||||
autoplaceItems.push_back( static_cast<SCH_ITEM*>( item->GetParent() ) );
|
||||
}
|
||||
|
||||
bool appendUndo = false;
|
||||
|
||||
for( SCH_ITEM* sch_item : autoplaceItems )
|
||||
{
|
||||
if( !moving && !sch_item->IsNew() )
|
||||
saveCopyInUndoList( sch_item, UNDO_REDO::CHANGED, ii > 0 );
|
||||
{
|
||||
saveCopyInUndoList( sch_item, UNDO_REDO::CHANGED, appendUndo );
|
||||
appendUndo = true;
|
||||
}
|
||||
|
||||
if( sch_item->IsType( EE_COLLECTOR::FieldOwners ) )
|
||||
sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
|
||||
sch_item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
|
||||
|
||||
updateItem( sch_item, true );
|
||||
}
|
||||
|
||||
@@ -129,7 +129,8 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent )
|
||||
undoCmd.PushItem( wrapper );
|
||||
m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS, false );
|
||||
|
||||
DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_MILS, MAX_PAGE_SIZE_MILS ) );
|
||||
DIALOG_EESCHEMA_PAGE_SETTINGS dlg( m_frame, wxSize( MAX_PAGE_SIZE_EESCHEMA_MILS,
|
||||
MAX_PAGE_SIZE_EESCHEMA_MILS ) );
|
||||
dlg.SetWksFileName( BASE_SCREEN::m_DrawingSheetFileName );
|
||||
|
||||
if( dlg.ShowModal() )
|
||||
@@ -498,18 +499,17 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
|
||||
continue;
|
||||
}
|
||||
|
||||
SCH_SCREEN* screen = sheet->LastScreen();
|
||||
sheet->UpdateAllScreenReferences();
|
||||
|
||||
item = nextMatch( screen, sheet, nullptr, data );
|
||||
item = nextMatch( sheet->LastScreen(), sheet, nullptr, data );
|
||||
|
||||
if( item )
|
||||
{
|
||||
m_frame->Schematic().SetCurrentSheet( *sheet );
|
||||
m_frame->GetCurrentSheet().UpdateAllScreenReferences();
|
||||
|
||||
screen->TestDanglingEnds();
|
||||
sheet->LastScreen()->TestDanglingEnds();
|
||||
|
||||
m_frame->SetScreen( screen );
|
||||
m_frame->SetScreen( sheet->LastScreen() );
|
||||
m_frame->UpdateHierarchyNavigator();
|
||||
UpdateFind( ACTIONS::updateFind.MakeEvent() );
|
||||
|
||||
|
||||
@@ -753,8 +753,8 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
|
||||
if( aItem->HasFlag( ENDPOINT ) )
|
||||
line->MoveEnd( (wxPoint) aDelta );
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_PIN_T:
|
||||
case SCH_FIELD_T:
|
||||
@@ -778,13 +778,16 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_SHEET_PIN_T:
|
||||
{
|
||||
SCH_SHEET_PIN* pin = (SCH_SHEET_PIN*) aItem;
|
||||
|
||||
pin->SetStoredPos( pin->GetStoredPos() + (wxPoint) aDelta );
|
||||
pin->ConstrainOnEdge( pin->GetStoredPos() );
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_LABEL_T:
|
||||
{
|
||||
SCH_TEXT* label = static_cast<SCH_TEXT*>( aItem );
|
||||
@@ -802,6 +805,7 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
static_cast<SCH_ITEM*>( aItem )->Move( (wxPoint) aDelta );
|
||||
break;
|
||||
@@ -818,6 +822,17 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems );
|
||||
bool append_undo = false;
|
||||
|
||||
auto doMoveItem =
|
||||
[&]( EDA_ITEM* item, const VECTOR2I& delta )
|
||||
{
|
||||
saveCopyInUndoList( item, UNDO_REDO::CHANGED, append_undo );
|
||||
append_undo = true;
|
||||
|
||||
moveItem( item, delta );
|
||||
item->ClearFlags( IS_MOVING );
|
||||
updateItem( item, true );
|
||||
};
|
||||
|
||||
for( SCH_ITEM* it : m_frame->GetScreen()->Items() )
|
||||
{
|
||||
if( !it->IsSelected() )
|
||||
@@ -861,12 +876,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
||||
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
saveCopyInUndoList( dragItem, UNDO_REDO::CHANGED, append_undo );
|
||||
append_undo = true;
|
||||
|
||||
moveItem( dragItem, gridpt );
|
||||
dragItem->ClearFlags( IS_MOVING );
|
||||
updateItem( dragItem, true );
|
||||
doMoveItem( dragItem, gridpt );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,13 +886,49 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
||||
VECTOR2I gridpt = grid.AlignGrid( item->GetPosition() ) - item->GetPosition();
|
||||
|
||||
if( gridpt != VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
saveCopyInUndoList( item, UNDO_REDO::CHANGED, append_undo );
|
||||
append_undo = true;
|
||||
doMoveItem( item, gridpt );
|
||||
}
|
||||
else if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
|
||||
VECTOR2I topRight = sheet->GetPosition();
|
||||
VECTOR2I bottomRight = topRight + sheet->GetSize();
|
||||
VECTOR2I tl_gridpt = grid.AlignGrid( topRight ) - topRight;
|
||||
VECTOR2I br_gridpt = grid.AlignGrid( bottomRight ) - bottomRight;
|
||||
|
||||
moveItem( item, gridpt );
|
||||
updateItem( item, true );
|
||||
item->ClearFlags( IS_MOVING );
|
||||
if( tl_gridpt != VECTOR2I( 0, 0 ) || br_gridpt != VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
doMoveItem( sheet, tl_gridpt );
|
||||
|
||||
VECTOR2I newSize = (VECTOR2I) sheet->GetSize() - tl_gridpt + br_gridpt;
|
||||
sheet->SetSize( wxSize( newSize.x, newSize.y ) );
|
||||
updateItem( sheet, true );
|
||||
|
||||
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
|
||||
{
|
||||
VECTOR2I gridpt;
|
||||
|
||||
if( pin->GetSide() == SHEET_SIDE::TOP || pin->GetSide() == SHEET_SIDE::LEFT )
|
||||
gridpt = tl_gridpt;
|
||||
else
|
||||
gridpt = br_gridpt;
|
||||
|
||||
if( gridpt != VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
EDA_ITEMS drag_items;
|
||||
getConnectedDragItems( pin, pin->GetConnectionPoints()[0], drag_items );
|
||||
|
||||
doMoveItem( pin, gridpt );
|
||||
|
||||
for( EDA_ITEM* dragItem : drag_items )
|
||||
{
|
||||
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
doMoveItem( dragItem, gridpt );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -918,12 +964,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
||||
if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
saveCopyInUndoList( dragItem, UNDO_REDO::CHANGED, append_undo );
|
||||
append_undo = true;
|
||||
|
||||
moveItem( dragItem, most_common );
|
||||
dragItem->ClearFlags( IS_MOVING );
|
||||
updateItem( dragItem, true );
|
||||
doMoveItem( dragItem, most_common );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user