Compare commits
404 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54253ba8a3 | |||
| ddd533ee9c | |||
| 46133c76b2 | |||
| d4e9ace354 | |||
| 88dd914a31 | |||
| ca68d32a47 | |||
| 3c86dbe28c | |||
| 400bac868e | |||
| 7e765db562 | |||
| a993e179ab | |||
| 5253ff35f1 | |||
| cba0ec4de5 | |||
| ed0354dd06 | |||
| d255d6aeeb | |||
| 94abd0ee79 | |||
| 6a3cd9c0d7 | |||
| 81be16d058 | |||
| 3efdc963d8 | |||
| a4525bf88c | |||
| d7c7ff3dad | |||
| 987aec3fd6 | |||
| d5661c24bd | |||
| c3ee1111f9 | |||
| 9c1509b8c3 | |||
| 1020cdd7a6 | |||
| bff2f53996 | |||
| d5bf831f60 | |||
| 6c423be36f | |||
| 3c33e2c046 | |||
| 253ff41819 | |||
| 24d95b410d | |||
| db5aacf984 | |||
| 111a56dd8a | |||
| d1d0d61b4f | |||
| 640f279abe | |||
| 874191bd8d | |||
| 2066af9f28 | |||
| ef7b3c1715 | |||
| 6eb96851f9 | |||
| a42ef9de77 | |||
| fb23fe3084 | |||
| 57f0150a23 | |||
| 9b31a986b6 | |||
| 8fa46a1f9e | |||
| d805f5ceff | |||
| b4242e562d | |||
| 2effa810c1 | |||
| a78af6acc2 | |||
| fc084c84f4 | |||
| a846ab7443 | |||
| 9f53272d34 | |||
| aa53aac7be | |||
| db984fcad9 | |||
| 607713cdae | |||
| 7de0a61de3 | |||
| 1838460c38 | |||
| 3a4e00d0f5 | |||
| a9bd82150b | |||
| de5c3733d0 | |||
| 3ff662e710 | |||
| 669571799b | |||
| 81a98fc0d3 | |||
| f10157fb24 | |||
| 7d94508257 | |||
| 262a8607d0 | |||
| fd44a9552a | |||
| 8e2d6d8cb2 | |||
| 13b73cb51f | |||
| 5f730ba360 | |||
| 79dbbadf2d | |||
| cd150c265f | |||
| 7a50a91eab | |||
| b5561ee5d4 | |||
| 8dcda7fe35 | |||
| 9b679cc8dd | |||
| 674f8cc936 | |||
| 51a43ef45b | |||
| acc55d588a | |||
| d4990b30e9 | |||
| 920a8d34ea | |||
| c8dfcf4b39 | |||
| aa93632707 | |||
| cc55262cbc | |||
| f887b62a85 | |||
| 5b20781080 | |||
| 98a1efc123 | |||
| a628c1f5e4 | |||
| 6588e8fabf | |||
| 52d349538e | |||
| aad2b3a492 | |||
| 93180abf7b | |||
| e30c8d8949 | |||
| a90c5d71ad | |||
| 54f56813a5 | |||
| 8d29229c0f | |||
| dc498128be | |||
| 6d5b71b663 | |||
| 122fcbb40b | |||
| 4fc28bb65e | |||
| a7f92a3187 | |||
| dd16b68623 | |||
| df24d87245 | |||
| 6000e04c78 | |||
| 87181a8ecb | |||
| 7d0731754c | |||
| 962e63ab52 | |||
| 9f4b43f3f2 | |||
| ef722200c9 | |||
| 784f47fa86 | |||
| 90cdc28707 | |||
| 62844b321c | |||
| 8a6c7f5538 | |||
| 8c3eeb5201 | |||
| 5998fabadd | |||
| 97be02356f | |||
| e59867d479 | |||
| 8e1bcaed37 | |||
| f3c864c178 | |||
| 947923509e | |||
| 4e0f77c0f4 | |||
| 6f0505f19c | |||
| 98bf66cb25 | |||
| f9b641b24d | |||
| 3894314ab2 | |||
| edc9d38680 | |||
| ce5f72207e | |||
| ff8d009022 | |||
| 589c33ec05 | |||
| 28fe5b0df5 | |||
| 5a3dfe598f | |||
| d0c132ccd4 | |||
| 826541548c | |||
| e3adc76a72 | |||
| 2ae2d7ee1a | |||
| e28b50e8d6 | |||
| 9c78d86f58 | |||
| a6b23a751e | |||
| 34d5f1f9fe | |||
| 43ad15dc0e | |||
| d20147c79f | |||
| 7cc014cf9e | |||
| 9e735fc940 | |||
| 4fecf6c50d | |||
| c31c14e46b | |||
| 349dbb98a6 | |||
| f4fa5bb0fc | |||
| 4cdf75dc72 | |||
| 53eb39e033 | |||
| 57ae43890c | |||
| 1c59574cbf | |||
| 7ddef03aba | |||
| 4258738b89 | |||
| 594864e117 | |||
| a5698ce480 | |||
| 1a2c9011e6 | |||
| 600ac72a3d | |||
| 1118eed080 | |||
| e42c66bd0e | |||
| ff8fae377c | |||
| 6931252ed9 | |||
| ef8e549d86 | |||
| a5470029a8 | |||
| 13fb23d59d | |||
| a3197578d6 | |||
| ebc14b35f5 | |||
| b0235a2805 | |||
| d0069e0e1d | |||
| 878f136951 | |||
| bf364bf74c | |||
| 03c2850c59 | |||
| 4eddc7131d | |||
| 14be1935e8 | |||
| f08029354a | |||
| c18600b67f | |||
| 2acc0a6844 | |||
| 8ffba3a52f | |||
| 0fb2f35b10 | |||
| f8270b9cec | |||
| d3311ee231 | |||
| 21eb2c8dad | |||
| a11fd7a792 | |||
| a2ad9f8b10 | |||
| 9a0e2f3395 | |||
| cd9196ddb9 | |||
| c10fe673a2 | |||
| 105f8a1720 | |||
| 050f47daf1 | |||
| 683abd2029 | |||
| d08f937932 | |||
| 2f51742311 | |||
| b926d2f0bd | |||
| 89d1d36e79 | |||
| 999cd8cd11 | |||
| fd8b281731 | |||
| d8481b4528 | |||
| 6d93fa046c | |||
| c75672fd44 | |||
| 5484796745 | |||
| 4ed45e0515 | |||
| 9956c04526 | |||
| b74af71312 | |||
| 44640422f2 | |||
| be91f378ac | |||
| bdca18cc9f | |||
| 76cb15f545 | |||
| 4f9e754a51 | |||
| 955774a91a | |||
| e8a9485d5e | |||
| 0736c141b9 | |||
| 204549f55b | |||
| 82a5f307ed | |||
| 7a4650a1a9 | |||
| 518980d9ed | |||
| 5cc1e2e42d | |||
| c599385c8b | |||
| 1d37d3fdf7 | |||
| f3db64af05 | |||
| 3217372720 | |||
| 7a50654f3b | |||
| 9893921d76 | |||
| 5574f35473 | |||
| fd42e493c0 | |||
| 7843e6a709 | |||
| 4c129ec208 | |||
| 1bf44561da | |||
| ad612864ce | |||
| 1707436cad | |||
| b011d508f8 | |||
| f67a477f65 | |||
| 3573b97bfc | |||
| 37a42a3fb7 | |||
| 2d13ddc70c | |||
| 0be01f3c24 | |||
| eb492724c7 | |||
| 3b05d03220 | |||
| 4c04233a20 | |||
| 2b6d2fc117 | |||
| f64ef39687 | |||
| c1fb392333 | |||
| de60d5467c | |||
| c1274e24b0 | |||
| 7f593d3999 | |||
| 3a6a6097a7 | |||
| 69989e4e64 | |||
| 88999b34d3 | |||
| 582732918d | |||
| f1f69c607e | |||
| 8e82fee494 | |||
| a51475a094 | |||
| f25e2d48bd | |||
| 2bbff64a12 | |||
| 70b4503187 | |||
| 912bd4458f | |||
| d3f4494925 | |||
| 464467ae8b | |||
| 8e579ec8e0 | |||
| 4ef6cbf4fb | |||
| 68dfcddbe9 | |||
| 907761f14e | |||
| be7917c8d8 | |||
| 2e25f09ae4 | |||
| ea95d8604a | |||
| 35def3ab2e | |||
| 5527c12a8d | |||
| fb1cc72013 | |||
| 1f34883a27 | |||
| 724262651f | |||
| d7b2247878 | |||
| 372e7b6312 | |||
| 323a2d83fa | |||
| 03c3393616 | |||
| cbff011e3c | |||
| 2ba6fad633 | |||
| bc4878d71e | |||
| e991ae504b | |||
| c18181042f | |||
| 3de80d3b20 | |||
| 39dcd0a352 | |||
| 199e31ea3f | |||
| dce2247925 | |||
| 89e78c0276 | |||
| 9a57c11348 | |||
| 1dbe8b2a79 | |||
| 29fd0caf58 | |||
| d30701ed59 | |||
| e39550e77f | |||
| a21e7a5eee | |||
| 927b5ae707 | |||
| f59626004c | |||
| 2ece2719d0 | |||
| 78ee542d8d | |||
| cea9b38815 | |||
| cb8f6db68d | |||
| 85038c2b46 | |||
| 1e8055f504 | |||
| a7a5f20d1c | |||
| 0d744a4e74 | |||
| 216ec60dc1 | |||
| 3d9047bec4 | |||
| 08d65beb26 | |||
| 5cab66fb18 | |||
| 9466624f9d | |||
| 80b842a704 | |||
| d513a9fe5c | |||
| c98081cb04 | |||
| 17a1dc18be | |||
| b22ff229db | |||
| 23b03fd6ab | |||
| 97b273905a | |||
| e759c4d27a | |||
| 76685ae2d9 | |||
| 3fad3ceb35 | |||
| dede9e8549 | |||
| 97c018118d | |||
| 8b1ce36402 | |||
| 7931f315b1 | |||
| abb6404ab2 | |||
| c434542c65 | |||
| 42b7aa6450 | |||
| f2ce9cf857 | |||
| 56134d0202 | |||
| f33bbe2d5d | |||
| 59a478bdc5 | |||
| 141b332d4f | |||
| d4a312d6cb | |||
| 31d688b34c | |||
| fbef9ea600 | |||
| 0688491e1b | |||
| 434161687e | |||
| 4b3709b96b | |||
| 1fa993303d | |||
| 01897e7755 | |||
| 7040b2178d | |||
| edf23c4c18 | |||
| b0b9e66fad | |||
| 89488a43b9 | |||
| 798e13f70d | |||
| e758391a23 | |||
| 00d1e01e12 | |||
| 4f265a52a2 | |||
| 560717de76 | |||
| 0f40894317 | |||
| 3915e882a8 | |||
| c5caa23a63 | |||
| 36978d2ddc | |||
| 3f90c895b9 | |||
| 2ada171806 | |||
| 5dc683c968 | |||
| 7026cfe140 | |||
| b7cd1dd764 | |||
| 09bb8fc4f4 | |||
| 746ab49d36 | |||
| 1614dc975a | |||
| ba7598d90d | |||
| 92fc4872e8 | |||
| 30dbfc33a4 | |||
| b3de5aa08e | |||
| ba4773e448 | |||
| a713ee852c | |||
| a65accd412 | |||
| 1dc9583e06 | |||
| 3afe02ac1f | |||
| 57aa61f1ba | |||
| 121ea14fe4 | |||
| 9d457dc0ab | |||
| befd836ab4 | |||
| 044c301d64 | |||
| 94fd0df2e2 | |||
| e5087ca3db | |||
| 819a9da599 | |||
| fb02e55424 | |||
| 70e86434ef | |||
| c41b1e2f06 | |||
| 64641c28ef | |||
| 69e9f4ada2 | |||
| d28cf632e4 | |||
| b466bfa6c8 | |||
| 1c06f4cf06 | |||
| 25f40566ed | |||
| e8fa2cbc4d | |||
| 779c441e0a | |||
| e33031ee7d | |||
| ae63313b55 | |||
| ae50b8d839 | |||
| 10a27156c2 | |||
| 94057886a3 | |||
| 2d9bcb6e4f | |||
| 249bcd9e1a | |||
| b2679b7648 | |||
| 9995b8714b | |||
| 7b4dd2f7f5 | |||
| cc6b01cf88 | |||
| 3568ff72bf | |||
| e20614660b | |||
| c5a69f073c | |||
| 3025671b1a | |||
| 74da0043b4 | |||
| c0ddca12df | |||
| bf55e610b9 | |||
| 4e775a4090 | |||
| 9f7b31b5c5 | |||
| 279641df73 | |||
| 9e1fd16329 | |||
| d6ff5f0239 |
@@ -36,6 +36,7 @@
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx/log.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
@@ -92,8 +93,7 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
|
||||
|
||||
if( PgmOrNull() )
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
ReloadColorSettings();
|
||||
|
||||
m_boardPos = VECTOR2I();
|
||||
m_boardSize = VECTOR2I();
|
||||
@@ -208,6 +208,15 @@ BOARD_ADAPTER::~BOARD_ADAPTER()
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::ReloadColorSettings() noexcept
|
||||
{
|
||||
wxASSERT( PgmOrNull() );
|
||||
|
||||
PCBNEW_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings( settings->m_ColorTheme );
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
|
||||
@@ -251,7 +260,8 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
|
||||
case B_Cu:
|
||||
case F_Cu:
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic;
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic
|
||||
|| m_board->IsFootprintHolder();
|
||||
|
||||
default:
|
||||
// the layer is an internal copper layer, used the visibility
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
|
||||
const BOARD* GetBoard() const noexcept { return m_board; }
|
||||
|
||||
void SetColorSettings( COLOR_SETTINGS* aSettings ) noexcept { m_colors = aSettings; }
|
||||
void ReloadColorSettings() noexcept;
|
||||
|
||||
/**
|
||||
* Function to be called by the render when it need to reload the settings for the board.
|
||||
@@ -342,8 +342,7 @@ private:
|
||||
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
|
||||
|
||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
|
||||
bool aSkipNonPlatedPads );
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||
|
||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
@@ -91,7 +91,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
callback_gal.SetIsFill( font->IsOutline() );
|
||||
callback_gal.SetIsStroke( font->IsStroke() );
|
||||
callback_gal.SetLineWidth( attrs.m_StrokeWidth );
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs );
|
||||
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
int margin = attrs.m_StrokeWidth * 1.5 +
|
||||
@@ -137,7 +137,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
|
||||
attrs.m_Angle = aText->GetDrawRotation();
|
||||
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner )
|
||||
{
|
||||
addText( &aDimension->Text(), aContainer, aDimension );
|
||||
addText( aDimension, aContainer, aDimension );
|
||||
|
||||
const int linewidth = aDimension->GetLineThickness();
|
||||
|
||||
@@ -275,6 +275,10 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
|
||||
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle );
|
||||
int circlesegcount;
|
||||
|
||||
// Avoid arcs that cannot be drawn
|
||||
if( radius < std::numeric_limits<double>::min() || arc_angle.IsZero() )
|
||||
break;
|
||||
|
||||
// We need a circle to segment count. However, the arc angle can be small, and the
|
||||
// radius very big. so we calculate a reasonable value for circlesegcount.
|
||||
if( arcsegcount <= 1 ) // The arc will be approximated by a segment
|
||||
@@ -488,41 +492,24 @@ OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
|
||||
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
{
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
if( !pad->IsOnLayer( 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:
|
||||
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
|
||||
if( IsCopperLayer( aLayerId ) )
|
||||
{
|
||||
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
|
||||
{
|
||||
switch( pad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE::CIRCLE:
|
||||
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
// Skip pad annulus when there isn't one (note: this is more discerning than
|
||||
// pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
|
||||
// the entire pad).
|
||||
if( !pad->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE::OVAL:
|
||||
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
VECTOR2I margin( 0, 0 );
|
||||
|
||||
@@ -525,9 +525,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// ADD PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad has the same shape
|
||||
// as its hole
|
||||
addPads( footprint, layerContainer, layer, true, renderPlatedPadsAsPlated, false );
|
||||
addPads( footprint, layerContainer, layer, renderPlatedPadsAsPlated, false );
|
||||
|
||||
// Micro-wave footprints may have items on copper layers
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
@@ -539,8 +537,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// ADD PLATED PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, true, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, true, false, true );
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
|
||||
}
|
||||
|
||||
m_platedPadsFront->BuildBVH();
|
||||
@@ -995,7 +993,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
else
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, false, false, false );
|
||||
addPads( footprint, layerContainer, layer, false, false );
|
||||
}
|
||||
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
#include <board.h>
|
||||
#include <reporter.h>
|
||||
#include <gl_context_mgr.h>
|
||||
@@ -140,7 +141,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
// long calculation time)
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
wxASSERT( a3DCachePointer != nullptr );
|
||||
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
|
||||
@@ -303,7 +304,7 @@ void EDA_3D_CANVAS::ReloadRequest( BOARD* aBoard , S3D_CACHE* aCachePointer )
|
||||
if( aBoard != nullptr )
|
||||
m_boardAdapter.SetBoard( aBoard );
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
if( m_3d_render )
|
||||
m_3d_render->ReloadRequest();
|
||||
@@ -531,13 +532,11 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
render_pivot( curtime_delta_s, scale );
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_render3dmousePivot )
|
||||
if( m_render3dmousePivot && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
|
||||
render3dmousePivot( scale );
|
||||
}
|
||||
#endif
|
||||
|
||||
// "Swaps the double-buffer of this window, making the back-buffer the
|
||||
// front-buffer and vice versa, so that the output of the previous OpenGL
|
||||
|
||||
@@ -178,8 +178,6 @@ public:
|
||||
*/
|
||||
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Get a value indicating whether to render the 3dmouse pivot.
|
||||
*/
|
||||
@@ -209,7 +207,6 @@ public:
|
||||
{
|
||||
m_3dmousePivotPos = aPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -278,14 +275,12 @@ private:
|
||||
*/
|
||||
void render_pivot( float t, float aScale );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Render the 3dmouse pivot cursor.
|
||||
*
|
||||
* @param aScale scale to apply on the cursor.
|
||||
*/
|
||||
void render3dmousePivot( float aScale );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return true if OpenGL initialization succeeded.
|
||||
@@ -331,10 +326,8 @@ private:
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
|
||||
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
||||
@@ -120,7 +120,6 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
|
||||
}
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
{
|
||||
wxASSERT( aScale >= 0.0f );
|
||||
@@ -160,4 +159,3 @@ void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
"nl_3d_viewer_plugin_impl.cpp"
|
||||
@@ -23,9 +22,4 @@ if( KICAD_USE_3DCONNEXION )
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
else()
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
)
|
||||
endif(KICAD_USE_3DCONNEXION)
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
*/
|
||||
|
||||
#include "nl_3d_viewer_plugin.h"
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) :
|
||||
m_impl( new NL_3D_VIEWER_PLUGIN_IMPL( aViewport ) )
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
|
||||
}
|
||||
|
||||
|
||||
@@ -38,22 +38,6 @@ NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
m_impl->SetFocus( focus );
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) : m_impl( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -912,7 +912,8 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
{
|
||||
|
||||
@@ -1202,7 +1202,8 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <3d_viewer/tools/eda_3d_actions.h>
|
||||
#include <3d_viewer/tools/eda_3d_controller.h>
|
||||
#include <3d_viewer/tools/eda_3d_conditions.h>
|
||||
#include <advanced_config.h>
|
||||
#include <bitmaps.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
@@ -56,9 +57,7 @@
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include <3d_navlib/nl_3d_viewer_plugin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flag to enable 3D viewer main frame window debug tracing.
|
||||
@@ -166,16 +165,18 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
m_canvas->SetInfoBar( m_infoBar );
|
||||
m_canvas->SetStatusBar( status_bar );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
try
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
try
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
|
||||
// in order to receive mouse events. Otherwise, the user has to click somewhere on
|
||||
@@ -193,12 +194,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
|
||||
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
|
||||
{
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
delete m_spaceMouse;
|
||||
}
|
||||
#endif
|
||||
delete m_spaceMouse;
|
||||
|
||||
Prj().GetProjectFile().m_Viewports3D = GetUserViewports();
|
||||
|
||||
@@ -334,12 +330,11 @@ void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||
{
|
||||
KIWAY_PLAYER::handleIconizeEvent( aEvent );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized()
|
||||
&& ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse->SetFocus( false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -655,12 +650,8 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
if( m_spaceMouse != nullptr && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||
}
|
||||
#endif
|
||||
|
||||
aEvent.Skip(); // required under wxMAC
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ target_link_libraries( 3d-viewer
|
||||
|
||||
add_subdirectory( 3d_cache )
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
endif()
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
|
||||
@@ -56,14 +56,16 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_userUnits = aFrame->GetUserUnits();
|
||||
|
||||
m_dummyBoard = new BOARD();
|
||||
|
||||
m_dummyBoard->SetProject( &aFrame->Prj(), true );
|
||||
|
||||
// This board will only be used to hold a footprint for viewing
|
||||
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
|
||||
|
||||
BOARD_DESIGN_SETTINGS parent_bds = aFrame->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS& dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( parent_bds.GetBoardThickness() );
|
||||
dummy_bds.SetEnabledLayers( LSET::FrontMask() | LSET::BackMask() );
|
||||
BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
dummy_board_stackup.RemoveAll();
|
||||
dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.1" )
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.3" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -620,12 +620,9 @@ target_link_libraries( pcbcommon PUBLIC
|
||||
threadpool
|
||||
)
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
endif()
|
||||
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
|
||||
add_dependencies( pcbcommon delaunator )
|
||||
|
||||
|
||||
@@ -62,6 +62,16 @@ namespace AC_STACK
|
||||
namespace AC_KEYS
|
||||
{
|
||||
|
||||
/**
|
||||
* Should the schematic use the new incremental connectivity algorithm
|
||||
*/
|
||||
static const wxChar IncrementalConnectivity[] = wxT( "IncrementalConnectivity" );
|
||||
|
||||
/**
|
||||
* Decide whether to attempt usage of the 3DConnexion mouse
|
||||
*/
|
||||
static const wxChar Use3DConnexionDriver[] = wxT( "3DConnexionDriver" );
|
||||
|
||||
/**
|
||||
* When filling zones, we add an extra amount of clearance to each zone to ensure that rounding
|
||||
* errors do not overrun minimum clearance distances. This is the extra in mm.
|
||||
@@ -321,6 +331,15 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_UseClipper2 = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
// spacemouse is largely stable on Windows
|
||||
m_Use3DConnexionDriver = true;
|
||||
#else
|
||||
m_Use3DConnexionDriver = false;
|
||||
#endif
|
||||
|
||||
m_IncrementalConnectivity = false;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@@ -463,6 +482,12 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::UseClipper2,
|
||||
&m_UseClipper2, m_UseClipper2 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::Use3DConnexionDriver,
|
||||
&m_Use3DConnexionDriver, m_Use3DConnexionDriver ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::IncrementalConnectivity,
|
||||
&m_IncrementalConnectivity, m_IncrementalConnectivity ) );
|
||||
|
||||
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
|
||||
+37
-4
@@ -41,7 +41,8 @@ BITMAP_BASE::BITMAP_BASE( const VECTOR2I& pos )
|
||||
m_ppi = 300; // the bitmap definition. the default is 300PPI
|
||||
m_pixelSizeIu = 254000.0 / m_ppi; // a pixel size value OK for bitmaps using 300 PPI
|
||||
// for Eeschema which uses currently 254000PPI
|
||||
m_isMirrored = false;
|
||||
m_isMirroredX = false;
|
||||
m_isMirroredY = false;
|
||||
m_rotation = ANGLE_0;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,8 @@ BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap )
|
||||
m_scale = aSchBitmap.m_scale;
|
||||
m_ppi = aSchBitmap.m_ppi;
|
||||
m_pixelSizeIu = aSchBitmap.m_pixelSizeIu;
|
||||
m_isMirrored = aSchBitmap.m_isMirrored;
|
||||
m_isMirroredX = aSchBitmap.m_isMirroredX;
|
||||
m_isMirroredY = aSchBitmap.m_isMirroredY;
|
||||
m_rotation = aSchBitmap.m_rotation;
|
||||
|
||||
m_image = nullptr;
|
||||
@@ -115,7 +117,8 @@ void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
|
||||
m_scale = aItem->m_scale;
|
||||
m_ppi = aItem->m_ppi;
|
||||
m_pixelSizeIu = aItem->m_pixelSizeIu;
|
||||
m_isMirrored = aItem->m_isMirrored;
|
||||
m_isMirroredX = aItem->m_isMirroredX;
|
||||
m_isMirroredY = aItem->m_isMirroredY;
|
||||
m_rotation = aItem->m_rotation;
|
||||
}
|
||||
|
||||
@@ -400,8 +403,25 @@ void BITMAP_BASE::Mirror( bool aVertically )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Mirror() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Mirror( not aVertically );
|
||||
m_isMirrored = !m_isMirrored;
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
if( aVertically )
|
||||
m_isMirroredY = !m_isMirroredY;
|
||||
else
|
||||
m_isMirroredX = !m_isMirroredX;
|
||||
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
}
|
||||
@@ -411,7 +431,20 @@ void BITMAP_BASE::Rotate( bool aRotateCCW )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Rotate90() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Rotate90( aRotateCCW );
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
m_rotation += ( aRotateCCW ? -ANGLE_90 : ANGLE_90 );
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
|
||||
@@ -177,12 +177,20 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
|
||||
|
||||
aMsg << eol;
|
||||
|
||||
aMsg << "Platform: "
|
||||
wxString osDescription;
|
||||
|
||||
#if __LINUX__
|
||||
<< wxGetLinuxDistributionInfo().Description << ", "
|
||||
#else
|
||||
<< wxGetOsDescription() << ", "
|
||||
osDescription = wxGetLinuxDistributionInfo().Description;
|
||||
#endif
|
||||
|
||||
// Linux uses the lsb-release program to get the description of the OS, if lsb-release
|
||||
// isn't installed, then the string will be empty and we fallback to the method used on
|
||||
// the other platforms (to at least get the kernel/uname info).
|
||||
if( osDescription.empty() )
|
||||
osDescription = wxGetOsDescription();
|
||||
|
||||
aMsg << "Platform: "
|
||||
<< osDescription << ", "
|
||||
<< GetPlatformGetBitnessName() << ", "
|
||||
<< platform.GetEndiannessName() << ", "
|
||||
<< platform.GetPortIdName();
|
||||
|
||||
+4
-21
@@ -31,30 +31,13 @@
|
||||
#include <dialogs/html_message_box.h>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <pgm_base.h>
|
||||
#include "cli/cli_names.h"
|
||||
|
||||
// Set of dialogs that have been chosen not to be shown again
|
||||
static std::unordered_map<unsigned long, int> doNotShowAgainDlgs;
|
||||
|
||||
|
||||
bool IsGUI()
|
||||
{
|
||||
if( !wxTheApp )
|
||||
return false;
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
return wxTheApp->IsGUI();
|
||||
#else
|
||||
// wxWidgets older than version 3.1.6 do not have a way to know if the app
|
||||
// has a GUI or is a console application.
|
||||
// So the trick is to set the App class name when starting kicad-cli, and when
|
||||
// the app class name is the kicad-cli class name the app is a console app
|
||||
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
|
||||
return run_gui;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
KIDIALOG::KIDIALOG( wxWindow* aParent, const wxString& aMessage, const wxString& aCaption,
|
||||
long aStyle )
|
||||
: wxRichMessageDialog( aParent, aMessage, aCaption, aStyle | wxCENTRE | wxSTAY_ON_TOP ),
|
||||
@@ -305,7 +288,7 @@ void DisplayError( wxWindow* aParent, const wxString& aText, int aDisplayTime )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !IsGUI() )
|
||||
if( !Pgm().IsGUI() )
|
||||
{
|
||||
wxFprintf( stderr, aText );
|
||||
return;
|
||||
@@ -330,7 +313,7 @@ void DisplayErrorMessage( wxWindow* aParent, const wxString& aText, const wxStri
|
||||
return;
|
||||
}
|
||||
|
||||
if( !IsGUI() )
|
||||
if( !Pgm().IsGUI() )
|
||||
{
|
||||
wxFprintf( stderr, aText );
|
||||
return;
|
||||
@@ -357,7 +340,7 @@ void DisplayInfoMessage( wxWindow* aParent, const wxString& aMessage, const wxSt
|
||||
return;
|
||||
}
|
||||
|
||||
if( !IsGUI() )
|
||||
if( !Pgm().IsGUI() )
|
||||
{
|
||||
wxFprintf( stdout, "%s %s", aMessage, aExtraInfo );
|
||||
return;
|
||||
|
||||
@@ -659,6 +659,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Greek (el_GR)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "aris-kimi" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Greek (el_GR)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Adolfo Jayme Barrientos" ),
|
||||
wxEmptyString,
|
||||
@@ -688,6 +692,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "VicSanRoPe" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish - Latin American (ES)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ulices Avila Hernandez" ),
|
||||
wxEmptyString,
|
||||
@@ -822,14 +830,46 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김낙환" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이기형" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "남우근" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "강명구" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김용재" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "서범기" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김세영" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이윤성" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "KwonHyeokbeom" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Minsu Kim (0xGabriel)" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
@@ -860,6 +900,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tom Niesse" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Christiaan Nieuwlaat" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jarl Gjessing" ),
|
||||
wxEmptyString,
|
||||
@@ -932,6 +980,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Portuguese (PT)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "ssantos" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Portuguese (PT)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Igor Plyatov" ),
|
||||
wxEmptyString,
|
||||
|
||||
+54
-31
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2023 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
|
||||
@@ -67,10 +67,6 @@ public:
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( DIALOG_SHIM, wxDialog )
|
||||
// If dialog has a grid and the grid has an active cell editor
|
||||
// Esc key closes cell editor, otherwise Esc key closes the dialog.
|
||||
EVT_GRID_EDITOR_SHOWN( DIALOG_SHIM::OnGridEditorShown )
|
||||
EVT_GRID_EDITOR_HIDDEN( DIALOG_SHIM::OnGridEditorHidden )
|
||||
EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -325,30 +321,38 @@ bool DIALOG_SHIM::Enable( bool enable )
|
||||
// Recursive descent doing a SelectAll() in wxTextCtrls.
|
||||
// MacOS User Interface Guidelines state that when tabbing to a text control all its
|
||||
// text should be selected. Since wxWidgets fails to implement this, we do it here.
|
||||
static void selectAllInTextCtrls( wxWindowList& children )
|
||||
void DIALOG_SHIM::selectAllInTextCtrls( wxWindowList& children )
|
||||
{
|
||||
for( wxWindow* child : children )
|
||||
{
|
||||
if( wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
textCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
// We don't currently run this on GTK because some window managers don't hide the
|
||||
// selection in non-active controls, and other window managers do the selection
|
||||
// automatically anyway.
|
||||
#if defined( __WXMAC__ ) || defined( __WXMSW__ )
|
||||
if( !childTextCtrl->GetStringSelection().IsEmpty() )
|
||||
if( !textCtrl->GetStringSelection().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
}
|
||||
else
|
||||
else if( textCtrl->IsEditable() )
|
||||
{
|
||||
childTextCtrl->SelectAll();
|
||||
textCtrl->SelectAll();
|
||||
}
|
||||
#else
|
||||
ignore_unused( childTextCtrl );
|
||||
ignore_unused( textCtrl );
|
||||
#endif
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
scintilla->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
if( !scintilla->GetSelectedText().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
@@ -533,11 +537,6 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
const int id = aEvent.GetId();
|
||||
|
||||
// If we are pressing a button to exit, we need to enable the escapeID
|
||||
// otherwise the dialog does not process cancel
|
||||
if( id == wxID_CANCEL )
|
||||
SetEscapeId( wxID_ANY );
|
||||
|
||||
if( IsQuasiModal() )
|
||||
{
|
||||
if( id == GetAffirmativeId() )
|
||||
@@ -555,7 +554,7 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
ignore_unused( TransferDataFromWindow() );
|
||||
}
|
||||
}
|
||||
else if( id == GetEscapeId() || (id == wxID_CANCEL && GetEscapeId() == wxID_ANY) )
|
||||
else if( id == wxID_CANCEL )
|
||||
{
|
||||
EndQuasiModal( wxID_CANCEL );
|
||||
}
|
||||
@@ -572,6 +571,19 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::onChildSetFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
// When setting focus to a text control reset the before-edit value.
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
{
|
||||
if( aEvt.GetKeyCode() == 'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
|
||||
@@ -626,25 +638,36 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( aEvt.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
wxObject* eventSource = aEvt.GetEventObject();
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( textCtrl->GetValue() != m_beforeEditValues[ textCtrl ] )
|
||||
{
|
||||
textCtrl->SetValue( m_beforeEditValues[ textCtrl ] );
|
||||
textCtrl->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( scintilla->GetText() != m_beforeEditValues[ scintilla ] )
|
||||
{
|
||||
scintilla->SetText( m_beforeEditValues[ scintilla ] );
|
||||
scintilla->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aEvt.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorShown( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_NONE );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorHidden( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_ANY );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
static void recursiveDescent( wxSizer* aSizer, std::map<int, wxString>& aLabels )
|
||||
{
|
||||
wxStdDialogButtonSizer* sdbSizer = dynamic_cast<wxStdDialogButtonSizer*>( aSizer );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2023 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
|
||||
@@ -105,10 +105,7 @@ void DIALOG_ASSIGN_NETCLASS::onPatternText( wxCommandEvent& aEvent )
|
||||
|
||||
for( const wxString& net : m_netCandidates )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
{
|
||||
m_matchingNets->Report( net );
|
||||
matchingNetNames.push_back( net );
|
||||
|
||||
@@ -396,12 +396,12 @@ void DIALOG_COLOR_PICKER::drawRGBPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize/2;
|
||||
@@ -466,12 +466,12 @@ void DIALOG_COLOR_PICKER::drawHSVPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize / 2;
|
||||
@@ -701,11 +701,13 @@ void DIALOG_COLOR_PICKER::onHSVMouseDrag( wxMouseEvent& event )
|
||||
|
||||
void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event )
|
||||
{
|
||||
m_newColor4D.SetFromHexString( m_colorValue->GetValue() );
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
if( m_newColor4D.SetFromHexString( m_colorValue->GetValue() ) )
|
||||
{
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
|
||||
SetEditVals( HEX_CHANGED, true );
|
||||
drawAll();
|
||||
SetEditVals( HEX_CHANGED, false );
|
||||
drawAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ bool DIALOG_PAGES_SETTINGS::TransferDataFromWindow()
|
||||
m_screen->SetContentModified();
|
||||
|
||||
if( LocalPrjConfigChanged() )
|
||||
m_parent->SaveProjectSettings();
|
||||
m_parent->OnModify();
|
||||
|
||||
// Call the post processing (if any) after changes
|
||||
m_parent->OnPageSettingsChange();
|
||||
@@ -674,9 +674,9 @@ void DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample()
|
||||
|
||||
GRFilledRect( &memDC, VECTOR2I( 0, 0 ), m_layout_size, 0, bgColor, bgColor );
|
||||
|
||||
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, m_tb,
|
||||
nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(), 1,
|
||||
&Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
|
||||
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, emptyString,
|
||||
m_tb, nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(),
|
||||
1, &Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
|
||||
|
||||
memDC.SelectObject( wxNullBitmap );
|
||||
m_PageLayoutExampleBitmap->SetBitmap( *m_pageBitmap );
|
||||
|
||||
@@ -117,8 +117,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
|
||||
|
||||
if( idx == static_cast<int>( m_cbTheme->GetCount() ) - 2 )
|
||||
{
|
||||
// separator; re-select active theme
|
||||
m_cbTheme->SetStringSelection( m_currentSettings->GetName() );
|
||||
m_cbTheme->SetStringSelection( GetSettingsDropdownName( m_currentSettings ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -217,10 +216,7 @@ void PANEL_COLOR_SETTINGS::createThemeList( const wxString& aCurrent )
|
||||
|
||||
for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
|
||||
{
|
||||
wxString name = settings->GetName();
|
||||
|
||||
if( settings->IsReadOnly() )
|
||||
name += wxS( " " ) + _( "(read-only)" );
|
||||
wxString name = GetSettingsDropdownName( settings );
|
||||
|
||||
int pos = m_cbTheme->Append( name, static_cast<void*>( settings ) );
|
||||
|
||||
@@ -286,6 +282,8 @@ void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLaye
|
||||
auto selected =
|
||||
static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( m_cbTheme->GetSelection() ) );
|
||||
|
||||
wxCHECK_RET( selected, wxT( "Invalid color theme selected" ) );
|
||||
|
||||
COLOR4D current = m_currentSettings->GetColor( aLayer );
|
||||
COLOR4D saved = selected->GetColor( aLayer );
|
||||
bool readOnly = m_currentSettings->IsReadOnly();
|
||||
@@ -379,3 +377,14 @@ bool PANEL_COLOR_SETTINGS::saveCurrentTheme( bool aValidate )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wxString PANEL_COLOR_SETTINGS::GetSettingsDropdownName(COLOR_SETTINGS* aSettings)
|
||||
{
|
||||
wxString name = aSettings->GetName();
|
||||
|
||||
if( aSettings->IsReadOnly() )
|
||||
name += wxS( " " ) + _( "(read-only)" );
|
||||
|
||||
return name;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 jean-pierre.charras
|
||||
* Copyright (C) 2011-2020 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2011-2023 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
|
||||
@@ -110,12 +110,19 @@ bool PANEL_IMAGE_EDITOR::TransferDataFromWindow()
|
||||
void PANEL_IMAGE_EDITOR::OnRedrawPanel( wxPaintEvent& event )
|
||||
{
|
||||
wxPaintDC dc( m_panelDraw );
|
||||
wxSize size = m_panelDraw->GetClientSize();
|
||||
dc.SetDeviceOrigin( size.x / 2, size.y / 2 );
|
||||
wxSize display_size = m_panelDraw->GetClientSize();
|
||||
|
||||
double scale = 1.0 / m_workingImage->GetScalingFactor();
|
||||
dc.SetUserScale( scale, scale );
|
||||
m_workingImage->DrawBitmap( &dc, wxPoint( 0, 0 ) );
|
||||
double img_scale = 1.0 / m_workingImage->GetScalingFactor();
|
||||
VECTOR2I img_size_pixels = m_workingImage->GetSizePixels();
|
||||
|
||||
// Adjust the display scale to use the full available display area
|
||||
double scale_X = (double)display_size.x/img_size_pixels.x;
|
||||
double scale_Y = (double)display_size.y/img_size_pixels.y;
|
||||
|
||||
double display_scale = img_scale * std::min( scale_X, scale_Y );
|
||||
|
||||
dc.SetUserScale( display_scale, display_scale );
|
||||
m_workingImage->DrawBitmap( &dc, VECTOR2I( m_workingImage->GetSize()/2 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="16" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">panel_image_editor_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">panel_image_editor_base</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Panel" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">PANEL_IMAGE_EDITOR_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">500,300</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerMain</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bUpperSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerLeft</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND | wxALL</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxPanel" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">256,256</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_panelDraw</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL|wxBORDER_SIMPLE</property>
|
||||
<event name="OnPaint">OnRedrawPanel</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerRight</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="current"></property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="disabled"></property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="focus"></property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Grey</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_buttonGrey</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="position"></property>
|
||||
<property name="pressed"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">OnGreyScaleConvert</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">10</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="spacer" expanded="1">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Image Scale:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticTextScale</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength">0</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_textCtrlScale</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
@@ -708,10 +708,7 @@ void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
|
||||
for( const wxString& net : m_netNames )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
m_matchingNets->Report( net );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( m_gal && m_gal->IsVisible() )
|
||||
if( m_gal && m_gal->IsInitialized() && m_gal->IsVisible() )
|
||||
{
|
||||
m_onShowTimer.Stop();
|
||||
OnShow();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -118,8 +118,12 @@ void DS_DRAW_ITEM_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
|
||||
break;
|
||||
|
||||
case DS_DATA_ITEM::DS_TEXT:
|
||||
aList.emplace_back( _( "Text" ), static_cast<DS_DRAW_ITEM_TEXT*>( this )->GetShownText() );
|
||||
{
|
||||
DS_DRAW_ITEM_TEXT* textItem = static_cast<DS_DRAW_ITEM_TEXT*>( this );
|
||||
// Don't use GetShownText(); we want to see the variable references here
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, textItem->GetText() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case DS_DATA_ITEM::DS_POLYPOLYGON:
|
||||
aList.emplace_back( _( "Imported Shape" ), wxEmptyString );
|
||||
@@ -190,7 +194,7 @@ bool DS_DRAW_ITEM_TEXT::HitTest( const BOX2I& aRect, bool aContains, int aAccura
|
||||
|
||||
wxString DS_DRAW_ITEM_TEXT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "Text '%s'" ), GetShownText() );
|
||||
return wxString::Format( _( "Text '%s'" ), KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
|
||||
m_renderSettings.GetDefaultPenWidth() );
|
||||
|
||||
font->Draw( m_gal, aItem->GetShownText(), aItem->GetTextPos(), attrs );
|
||||
font->Draw( m_gal, aItem->GetShownText( true ), aItem->GetTextPos(), attrs );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <widgets/wx_aui_art_providers.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <wx/app.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/display.h>
|
||||
@@ -219,6 +220,10 @@ void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
|
||||
if( canCloseWindow( event ) )
|
||||
{
|
||||
m_isClosing = true;
|
||||
|
||||
if( m_infoBar )
|
||||
m_infoBar->Dismiss();
|
||||
|
||||
APP_SETTINGS_BASE* cfg = config();
|
||||
|
||||
if( cfg )
|
||||
@@ -399,6 +404,8 @@ void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAM
|
||||
enableRes = true;
|
||||
else if( textEntry && isPaste && textEntry->CanPaste() )
|
||||
enableRes = true;
|
||||
else if( dynamic_cast<WX_GRID*>( focus ) )
|
||||
enableRes = false; // Must disable menu in order to get command as CharHook event
|
||||
}
|
||||
|
||||
aEvent.Enable( enableRes );
|
||||
@@ -1230,7 +1237,7 @@ bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
|
||||
|
||||
void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
{
|
||||
if( !IsGUI() )
|
||||
if( !Pgm().IsGUI() )
|
||||
return;
|
||||
|
||||
wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
|
||||
|
||||
@@ -144,6 +144,10 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
|
||||
wxFileName currentFileName( fullfilename );
|
||||
|
||||
// Use wxWidgets to resolve any "." and ".." in the path
|
||||
currentFileName.MakeAbsolute();
|
||||
fullfilename = currentFileName.GetFullPath();
|
||||
|
||||
wxString file_ext = currentFileName.GetExt();
|
||||
|
||||
if( file_ext.Lower() == wxT( "pdf" ) )
|
||||
|
||||
+34
-38
@@ -27,6 +27,7 @@
|
||||
#include <bitmaps.h>
|
||||
#include <confirm.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <file_history.h>
|
||||
@@ -289,7 +290,7 @@ void EDA_DRAW_FRAME::ToggleUserUnits()
|
||||
else
|
||||
{
|
||||
SetUserUnits( GetUserUnits() == EDA_UNITS::INCHES ? EDA_UNITS::MILLIMETRES
|
||||
: EDA_UNITS::INCHES );
|
||||
: EDA_UNITS::INCHES );
|
||||
unitsChangeRefresh();
|
||||
|
||||
wxCommandEvent e( UNITS_CHANGED );
|
||||
@@ -613,8 +614,8 @@ void EDA_DRAW_FRAME::DisplayGridMsg()
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( wxS( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x,
|
||||
false ) );
|
||||
msg.Printf( _( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x,
|
||||
false ) );
|
||||
|
||||
SetStatusText( msg, 4 );
|
||||
}
|
||||
@@ -741,21 +742,21 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
||||
void EDA_DRAW_FRAME::AppendMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::ClearMsgPanel()
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->EraseMsgBox();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
@@ -768,10 +769,9 @@ void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
}
|
||||
@@ -842,26 +842,15 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
// Not all classes derived from EDA_DRAW_FRAME can save the canvas type, because some
|
||||
// have a fixed type, or do not have a option to set the canvas type (they inherit from
|
||||
// a parent frame)
|
||||
FRAME_T allowed_frames[] =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
static std::vector<FRAME_T> s_allowedFrames =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
|
||||
bool allow_save = false;
|
||||
|
||||
for( unsigned ii = 0; ii < arrayDim( allowed_frames ); ii++ )
|
||||
{
|
||||
if( m_ident == allowed_frames[ii] )
|
||||
{
|
||||
allow_save = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !allow_save )
|
||||
if( !alg::contains( s_allowedFrames, m_ident ) )
|
||||
return false;
|
||||
|
||||
if( aCanvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
|
||||
@@ -871,9 +860,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
return false;
|
||||
}
|
||||
|
||||
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
|
||||
|
||||
if( cfg )
|
||||
if( APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings() )
|
||||
cfg->m_Graphics.canvas_type = static_cast<int>( aCanvasType );
|
||||
|
||||
return false;
|
||||
@@ -883,7 +870,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
@@ -897,7 +884,7 @@ VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) con
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestHalfGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
@@ -990,8 +977,8 @@ static const wxString productName = wxT( "KiCad E.D.A. " );
|
||||
|
||||
|
||||
void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPageInfo,
|
||||
const wxString& aFullSheetName, const wxString& aFileName,
|
||||
const TITLE_BLOCK& aTitleBlock,
|
||||
const wxString& aSheetName, const wxString& aSheetPath,
|
||||
const wxString& aFileName, const TITLE_BLOCK& aTitleBlock,
|
||||
const std::map<wxString, wxString>* aProperties, int aSheetCount,
|
||||
const wxString& aPageNumber, double aMils2Iu, const PROJECT* aProject,
|
||||
const wxString& aSheetLayer, bool aIsFirstPage )
|
||||
@@ -1003,7 +990,8 @@ void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPage
|
||||
drawList.SetPageNumber( aPageNumber );
|
||||
drawList.SetSheetCount( aSheetCount );
|
||||
drawList.SetFileName( aFileName );
|
||||
drawList.SetSheetName( aFullSheetName );
|
||||
drawList.SetSheetName( aSheetName );
|
||||
drawList.SetSheetPath( aSheetPath );
|
||||
drawList.SetSheetLayer( aSheetLayer );
|
||||
drawList.SetProject( aProject );
|
||||
drawList.SetIsFirstPage( aIsFirstPage );
|
||||
@@ -1033,9 +1021,10 @@ void EDA_DRAW_FRAME::PrintDrawingSheet( const RENDER_SETTINGS* aSettings, BASE_S
|
||||
DC->SetAxisOrientation( true, false );
|
||||
}
|
||||
|
||||
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), aFilename, GetTitleBlock(),
|
||||
aProperties, aScreen->GetPageCount(), aScreen->GetPageNumber(), aMils2Iu,
|
||||
&Prj(), aSheetLayer, aScreen->GetVirtualPageNumber() == 1 );
|
||||
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), GetFullScreenDesc(),
|
||||
aFilename, GetTitleBlock(), aProperties, aScreen->GetPageCount(),
|
||||
aScreen->GetPageNumber(), aMils2Iu, &Prj(), aSheetLayer,
|
||||
aScreen->GetVirtualPageNumber() == 1 );
|
||||
|
||||
if( origin.y > 0 )
|
||||
{
|
||||
@@ -1052,6 +1041,13 @@ wxString EDA_DRAW_FRAME::GetScreenDesc() const
|
||||
}
|
||||
|
||||
|
||||
wxString EDA_DRAW_FRAME::GetFullScreenDesc() const
|
||||
{
|
||||
// Virtual function. Base class implementation returns an empty string.
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
|
||||
const wxString& wildcard, const wxString& ext,
|
||||
bool isDirectory, bool aIsGlobal,
|
||||
|
||||
+1
-1
@@ -394,7 +394,7 @@ static struct EDA_ITEM_DESC
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_ITEM, KICAD_T>( wxS( "Type" ),
|
||||
NO_SETTER( EDA_ITEM, KICAD_T ), &EDA_ITEM::Type ) )
|
||||
.SetIsInternal();
|
||||
.SetIsHiddenFromPropertiesManager();
|
||||
}
|
||||
} _EDA_ITEM_DESC;
|
||||
|
||||
|
||||
@@ -412,6 +412,30 @@ bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm, int& aMatchersTriggered,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start >= 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::StartsWith( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
wxString const& EDA_COMBINED_MATCHER::GetPattern() const
|
||||
{
|
||||
return m_pattern;
|
||||
|
||||
+11
-1
@@ -1736,7 +1736,17 @@ static struct EDA_SHAPE_DESC
|
||||
filled->SetAvailableFunc(
|
||||
[=]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
SHAPE_T itemShape = aItem->Get<SHAPE_T>( shape );
|
||||
SHAPE_T itemShape;
|
||||
|
||||
try
|
||||
{
|
||||
itemShape = aItem->Get<SHAPE_T>( shape );
|
||||
}
|
||||
catch( std::runtime_error& err )
|
||||
{
|
||||
wxFAIL_MSG( err.what() );
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( itemShape )
|
||||
{
|
||||
|
||||
+24
-12
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2023 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
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <callback_gal.h>
|
||||
#include <eda_text.h> // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF...
|
||||
#include <gal/color4d.h> // for COLOR4D, COLOR4D::BLACK
|
||||
#include <font/glyph.h>
|
||||
#include <gr_text.h>
|
||||
#include <string_utils.h> // for UnescapeString
|
||||
#include <math/util.h> // for KiROUND
|
||||
@@ -117,8 +118,10 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -149,8 +152,10 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -391,7 +396,12 @@ void EDA_TEXT::Offset( const VECTOR2I& aOffset )
|
||||
m_pos += aOffset;
|
||||
|
||||
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache )
|
||||
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( aOffset );
|
||||
{
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
outline->Move( aOffset );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = false;
|
||||
}
|
||||
@@ -467,7 +477,8 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
|
||||
|
||||
attrs.m_Angle = resolvedAngle;
|
||||
|
||||
font->GetLinesAsGlyphs( &m_render_cache, GetShownText(), GetDrawPos() + aOffset, attrs );
|
||||
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
|
||||
attrs );
|
||||
m_render_cache_angle = resolvedAngle;
|
||||
m_render_cache_text = forResolvedText;
|
||||
m_render_cache_offset = aOffset;
|
||||
@@ -514,7 +525,7 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
|
||||
BOX2I bbox;
|
||||
wxArrayString strings;
|
||||
wxString text = GetShownText();
|
||||
wxString text = GetShownText( true );
|
||||
int thickness = GetEffectiveTextPenWidth();
|
||||
|
||||
if( IsMultilineAllowed() )
|
||||
@@ -652,7 +663,7 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
{
|
||||
std::vector<VECTOR2I> positions;
|
||||
wxArrayString strings;
|
||||
wxStringSplit( GetShownText(), strings, '\n' );
|
||||
wxStringSplit( GetShownText( true ), strings, '\n' );
|
||||
|
||||
positions.reserve( strings.Count() );
|
||||
|
||||
@@ -663,7 +674,8 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
}
|
||||
else
|
||||
{
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText(), GetDrawPos() );
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText( true ),
|
||||
GetDrawPos() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +896,7 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( triShape );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), attrs );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -901,7 +913,7 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( aPoly.Clone() );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), attrs );
|
||||
}
|
||||
|
||||
return shape;
|
||||
|
||||
+139
-44
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Font abstract base class
|
||||
*
|
||||
@@ -35,6 +35,7 @@
|
||||
// The "official" name of the building Kicad stroke font (always existing)
|
||||
#include <font/kicad_font_name.h>
|
||||
#include "macros.h"
|
||||
#include "wx/tokenzr.h"
|
||||
|
||||
|
||||
// markup_parser.h includes pegtl.hpp which includes windows.h... which leaks #define DrawText
|
||||
@@ -187,10 +188,13 @@ void FONT::Draw( KIGFX::GAL* aGal, const wxString& aText, const VECTOR2I& aPosit
|
||||
*/
|
||||
VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const std::unique_ptr<MARKUP::NODE>& aNode, const VECTOR2I& aPosition,
|
||||
const KIFONT::FONT* aFont, const VECTOR2I& aSize, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin, TEXT_STYLE_FLAGS aTextStyle )
|
||||
const KIFONT::FONT* aFont, const VECTOR2I& aSize, const VECTOR2I& aOffset,
|
||||
const EDA_ANGLE& aAngle, bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle )
|
||||
{
|
||||
VECTOR2I nextPosition = aPosition;
|
||||
VECTOR2I nextPosition = aPosition + aOffset;
|
||||
bool drawUnderline = false;
|
||||
bool drawOverbar = false;
|
||||
|
||||
if( aNode )
|
||||
{
|
||||
@@ -199,30 +203,78 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
if( !aNode->is_root() )
|
||||
{
|
||||
if( aNode->isSubscript() )
|
||||
textStyle = TEXT_STYLE::SUBSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUBSCRIPT;
|
||||
else if( aNode->isSuperscript() )
|
||||
textStyle = TEXT_STYLE::SUPERSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUPERSCRIPT;
|
||||
|
||||
if( aNode->isOverbar() )
|
||||
textStyle |= TEXT_STYLE::OVERBAR;
|
||||
drawOverbar = true;
|
||||
|
||||
if( aNode->has_content() )
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
nextPosition = aFont->GetTextAsGlyphs( &bbox, aGlyphs, aNode->asWxString(), aSize,
|
||||
aPosition, aAngle, aMirror, aOrigin,
|
||||
nextPosition, aAngle, aMirror, aOrigin,
|
||||
textStyle );
|
||||
|
||||
if( aBoundingBox )
|
||||
aBoundingBox->Merge( bbox );
|
||||
}
|
||||
}
|
||||
else if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
drawUnderline = true;
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<MARKUP::NODE>& child : aNode->children )
|
||||
{
|
||||
nextPosition = drawMarkup( aBoundingBox, aGlyphs, child, nextPosition, aFont, aSize,
|
||||
aAngle, aMirror, aOrigin, textStyle );
|
||||
VECTOR2I(), aAngle, aMirror, aOrigin, textStyle );
|
||||
}
|
||||
}
|
||||
|
||||
if( drawUnderline )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeUnderlineVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( drawOverbar )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeOverbarVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,13 +284,13 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
|
||||
VECTOR2I FONT::drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aPosition, const VECTOR2I& aSize,
|
||||
const EDA_ANGLE& aAngle, bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
const VECTOR2I& aOffset, const EDA_ANGLE& aAngle, bool aMirror,
|
||||
const VECTOR2I& aOrigin, TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
MARKUP::MARKUP_PARSER markupParser( TO_UTF8( aText ) );
|
||||
std::unique_ptr<MARKUP::NODE> root = markupParser.Parse();
|
||||
|
||||
return ::drawMarkup( aBoundingBox, aGlyphs, root, aPosition, this, aSize, aAngle, aMirror,
|
||||
return ::drawMarkup( aBoundingBox, aGlyphs, root, aPosition, this, aSize, aOffset, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
@@ -252,7 +304,13 @@ void FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const wxSt
|
||||
return;
|
||||
|
||||
TEXT_STYLE_FLAGS textStyle = 0;
|
||||
VECTOR2I offset;
|
||||
|
||||
if( !IsOutline() )
|
||||
{
|
||||
offset.x = aGal->GetLineWidth() / 1.52;
|
||||
offset.y = -aGal->GetLineWidth() * 0.052;
|
||||
}
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
@@ -261,7 +319,7 @@ void FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const wxSt
|
||||
|
||||
std::vector<std::unique_ptr<GLYPH>> glyphs;
|
||||
|
||||
(void) drawMarkup( aBoundingBox, &glyphs, aText, aPosition, aSize, aAngle, aMirror, aOrigin,
|
||||
(void) drawMarkup( aBoundingBox, &glyphs, aText, aPosition, aSize, offset, aAngle, aMirror, aOrigin,
|
||||
textStyle );
|
||||
|
||||
aGal->DrawGlyphs( glyphs );
|
||||
@@ -281,7 +339,7 @@ VECTOR2I FONT::StringBoundaryLimits( const wxString& aText, const VECTOR2I& aSiz
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, ANGLE_0, false,
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, VECTOR2I(), ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
|
||||
if( IsStroke() )
|
||||
@@ -307,8 +365,8 @@ VECTOR2I FONT::boundingBoxSingleLine( BOX2I* aBBox, const wxString& aText,
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
VECTOR2I extents = drawMarkup( aBBox, nullptr, aText, aPosition, aSize, ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
VECTOR2I extents = drawMarkup( aBBox, nullptr, aText, aPosition, aSize, VECTOR2I(), ANGLE_0,
|
||||
false, VECTOR2I(), textStyle );
|
||||
|
||||
return extents;
|
||||
}
|
||||
@@ -376,20 +434,22 @@ void wordbreakMarkup( std::vector<std::pair<wxString, int>>* aWords,
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxArrayString words;
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxStringTokenizer tokenizer( textRun, " ", wxTOKEN_RET_DELIMS );
|
||||
std::vector<wxString> words;
|
||||
|
||||
wxStringSplit( textRun, words, ' ' );
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
words.emplace_back( tokenizer.GetNextToken() );
|
||||
|
||||
if( textRun.EndsWith( wxS( " " ) ) )
|
||||
words.Add( wxS( " " ) );
|
||||
|
||||
for( size_t ii = 0; ii < words.size(); ++ii )
|
||||
for( const wxString& word : words )
|
||||
{
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, words[ii], aSize, { 0, 0 },
|
||||
wxString chars = word;
|
||||
chars.Trim();
|
||||
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, chars, aSize, { 0, 0 },
|
||||
ANGLE_0, false, { 0, 0 }, textStyle ).x;
|
||||
|
||||
aWords->emplace_back( std::make_pair( words[ii], w ) );
|
||||
aWords->emplace_back( std::make_pair( word, w ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,35 +501,70 @@ void FONT::LinebreakText( wxString& aText, int aColumnWidth, const VECTOR2I& aSi
|
||||
|
||||
for( size_t ii = 0; ii < textLines.Count(); ++ii )
|
||||
{
|
||||
bool virginLine = true;
|
||||
int lineWidth = 0;
|
||||
std::vector<std::pair<wxString, int>> markup;
|
||||
std::vector<std::pair<wxString, int>> words;
|
||||
|
||||
wordbreakMarkup( &words, textLines[ii], aSize, textStyle );
|
||||
wordbreakMarkup( &markup, textLines[ii], aSize, textStyle );
|
||||
|
||||
for( size_t jj = 0; jj < words.size(); /* advance in loop */ )
|
||||
for( const auto& [ run, runWidth ] : markup )
|
||||
{
|
||||
if( virginLine )
|
||||
if( !words.empty() && !words.back().first.EndsWith( ' ' ) )
|
||||
{
|
||||
// First word is always placed, even when wider than columnWidth.
|
||||
aText += words[jj].first;
|
||||
lineWidth += words[jj].second;
|
||||
jj++;
|
||||
|
||||
virginLine = false;
|
||||
}
|
||||
else if( lineWidth + spaceWidth + words[jj].second < aColumnWidth - aThickness )
|
||||
{
|
||||
aText += " " + words[jj].first;
|
||||
lineWidth += spaceWidth + words[jj].second;
|
||||
jj++;
|
||||
words.back().first += run;
|
||||
words.back().second += runWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += '\n';
|
||||
words.emplace_back( std::make_pair( run, runWidth ) );
|
||||
}
|
||||
}
|
||||
|
||||
bool buryMode = false;
|
||||
int lineWidth = 0;
|
||||
wxString pendingSpaces;
|
||||
|
||||
for( const auto& [ word, wordWidth ] : words )
|
||||
{
|
||||
int pendingSpaceWidth = (int) pendingSpaces.Length() * spaceWidth;
|
||||
bool overflow = lineWidth + pendingSpaceWidth + wordWidth > aColumnWidth - aThickness;
|
||||
|
||||
if( overflow && pendingSpaces.Length() > 0 )
|
||||
{
|
||||
aText += '\n';
|
||||
lineWidth = 0;
|
||||
virginLine = true;
|
||||
pendingSpaces = wxEmptyString;
|
||||
pendingSpaceWidth = 0;
|
||||
buryMode = true;
|
||||
}
|
||||
|
||||
if( word == wxS( " " ) )
|
||||
{
|
||||
pendingSpaces += word;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( buryMode )
|
||||
{
|
||||
buryMode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += pendingSpaces;
|
||||
lineWidth += pendingSpaceWidth;
|
||||
}
|
||||
|
||||
if( word.EndsWith( ' ' ) )
|
||||
{
|
||||
aText += word.Left( word.Length() - 1 );
|
||||
pendingSpaces = wxS( " " );
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += word;
|
||||
pendingSpaces = wxEmptyString;
|
||||
}
|
||||
|
||||
lineWidth += wordWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ std::string FONTCONFIG::getFamilyStringByLang( FONTCONFIG_PAT& aPat, const wxStr
|
||||
|
||||
|
||||
FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString &aFontFile,
|
||||
bool aBold, bool aItalic )
|
||||
int& aFaceIndex, bool aBold, bool aItalic )
|
||||
{
|
||||
FF_RESULT retval = FF_RESULT::FF_ERROR;
|
||||
wxString qualifiedFontName = aFontName;
|
||||
@@ -184,6 +184,8 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch )
|
||||
{
|
||||
aFontFile = wxString::FromUTF8( (char*) file );
|
||||
aFaceIndex = 0;
|
||||
|
||||
wxString styleStr;
|
||||
FcChar8* family = nullptr;
|
||||
FcChar8* style = nullptr;
|
||||
@@ -192,9 +194,13 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
|
||||
std::unordered_map<std::string, std::string> famStrings;
|
||||
FONTCONFIG_PAT patHolder{ font };
|
||||
|
||||
getAllFamilyStrings( patHolder, famStrings );
|
||||
|
||||
if( FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch )
|
||||
{
|
||||
FcPatternGetInteger( font, FC_INDEX, 0, &aFaceIndex );
|
||||
|
||||
fontName = wxString::FromUTF8( (char*) family );
|
||||
|
||||
if( FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch )
|
||||
@@ -248,8 +254,6 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Outline font class
|
||||
*
|
||||
@@ -98,9 +98,10 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
|
||||
std::unique_ptr<OUTLINE_FONT> font = std::make_unique<OUTLINE_FONT>();
|
||||
|
||||
wxString fontFile;
|
||||
int faceIndex;
|
||||
using fc = fontconfig::FONTCONFIG;
|
||||
|
||||
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, aBold, aItalic );
|
||||
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, faceIndex, aBold, aItalic );
|
||||
|
||||
if( retval == fc::FF_RESULT::FF_ERROR )
|
||||
return nullptr;
|
||||
@@ -111,7 +112,7 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
|
||||
if( retval == fc::FF_RESULT::FF_MISSING_ITAL || retval == fc::FF_RESULT::FF_MISSING_BOLD_ITAL )
|
||||
font->SetFakeItal();
|
||||
|
||||
if( font->loadFace( fontFile ) != 0 )
|
||||
if( font->loadFace( fontFile, faceIndex ) != 0 )
|
||||
return nullptr;
|
||||
|
||||
font->m_fontName = aFontName; // Keep asked-for name, even if we substituted.
|
||||
@@ -121,13 +122,13 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
|
||||
}
|
||||
|
||||
|
||||
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName )
|
||||
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName, int aFaceIndex )
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
// TODO: check that going from wxString to char* with UTF-8
|
||||
// conversion for filename makes sense on any/all platforms
|
||||
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), 0, &m_face );
|
||||
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), aFaceIndex, &m_face );
|
||||
|
||||
if( !e )
|
||||
{
|
||||
@@ -254,7 +255,7 @@ void OUTLINE_FONT::GetLinesAsGlyphs( std::vector<std::unique_ptr<GLYPH>>* aGlyph
|
||||
|
||||
for( size_t i = 0; i < strings.GetCount(); i++ )
|
||||
{
|
||||
(void) drawMarkup( nullptr, aGlyphs, strings.Item( i ), positions[i], aAttrs.m_Size,
|
||||
(void) drawMarkup( nullptr, aGlyphs, strings.Item( i ), positions[i], aAttrs.m_Size, VECTOR2I(),
|
||||
aAttrs.m_Angle, aAttrs.m_Mirrored, aPosition, textStyle );
|
||||
}
|
||||
}
|
||||
@@ -312,22 +313,6 @@ VECTOR2I OUTLINE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
}
|
||||
|
||||
|
||||
double OUTLINE_FONT::getOverbarOffset( int ascender, int height, int thickness ) const
|
||||
{
|
||||
double thicknessRatio = abs( (double) thickness ) / (double) height;
|
||||
double ascenderRatio = (double) ascender / (double) height;
|
||||
|
||||
if( thicknessRatio < 0.05 )
|
||||
return 0.04;
|
||||
else if( ascenderRatio < 0.78 )
|
||||
return 0.00;
|
||||
else if( ascenderRatio < 0.80 )
|
||||
return -0.03;
|
||||
else
|
||||
return -0.06;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
@@ -337,14 +322,15 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
return getTextAsGlyphsUnlocked( aBBox, aGlyphs, aText, aSize, aPosition, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
VECTOR2D glyphSize = aSize;
|
||||
FT_Face face = m_face;
|
||||
@@ -477,75 +463,9 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
}
|
||||
|
||||
int ascender = abs( face->size->metrics.ascender * GLYPH_SIZE_SCALER );
|
||||
int height = abs( face->size->metrics.height * GLYPH_SIZE_SCALER );
|
||||
int descender = abs( face->size->metrics.descender * GLYPH_SIZE_SCALER );
|
||||
VECTOR2I extents( cursor.x * scaleFactor.x, ( ascender + descender ) * abs( scaleFactor.y ) );
|
||||
|
||||
// Font metrics don't include all descenders and diacriticals, so beef them up just a little.
|
||||
extents.y *= 1.05;
|
||||
|
||||
if( IsOverbar( aTextStyle ) )
|
||||
{
|
||||
std::vector<std::unique_ptr<GLYPH>> underscoreGlyphs;
|
||||
|
||||
getTextAsGlyphsUnlocked( nullptr, &underscoreGlyphs, wxT( "_" ), aSize, { 0, 0 }, ANGLE_0, false,
|
||||
{ 0, 0 }, aTextStyle & ~TEXT_STYLE::OVERBAR );
|
||||
|
||||
OUTLINE_GLYPH* underscoreGlyph = static_cast<OUTLINE_GLYPH*>( underscoreGlyphs[0].get() );
|
||||
BOX2I underscoreBBox;
|
||||
|
||||
for( const VECTOR2I& pt : underscoreGlyph->Outline( 0 ).CPoints() )
|
||||
underscoreBBox.Merge( pt );
|
||||
|
||||
int barThickness = underscoreBBox.GetHeight();
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = barThickness / 2.0;
|
||||
double barOffset = getOverbarOffset( ascender, height, barThickness / scaleFactor.y );
|
||||
|
||||
VECTOR2I topLeft( aPosition );
|
||||
VECTOR2I topRight( aPosition );
|
||||
|
||||
topLeft.y += ascender * scaleFactor.y * ( 1.0 + barOffset );
|
||||
topRight.y = topLeft.y;
|
||||
|
||||
topLeft.x += barTrim;
|
||||
topRight.x += extents.x - barTrim;
|
||||
|
||||
extents.y *= ( 1.0 + barOffset + barOffset );
|
||||
extents.x += barTrim;
|
||||
|
||||
if( IsItalic() )
|
||||
{
|
||||
topLeft.x += aSize.y * ITALIC_TILT;
|
||||
topRight.x += aSize.y * ITALIC_TILT;
|
||||
extents.x += aSize.y * ITALIC_TILT;
|
||||
}
|
||||
|
||||
if( aMirror )
|
||||
{
|
||||
topLeft.x = aOrigin.x - ( topLeft.x - aOrigin.x );
|
||||
topRight.x = aOrigin.x - ( topRight.x - aOrigin.x );
|
||||
}
|
||||
|
||||
if( !aAngle.IsZero() )
|
||||
{
|
||||
RotatePoint( topLeft, aOrigin, aAngle );
|
||||
RotatePoint( topRight, aOrigin, aAngle );
|
||||
}
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
int maxError = KiROUND( barThickness / 48 );
|
||||
SHAPE_POLY_SET poly;
|
||||
|
||||
TransformOvalToPolygon( poly, topLeft, topRight, barThickness, maxError, ERROR_INSIDE );
|
||||
|
||||
std::unique_ptr<OUTLINE_GLYPH> overbarGlyph = std::make_unique<OUTLINE_GLYPH>( poly );
|
||||
aGlyphs->push_back( std::move( overbarGlyph ) );
|
||||
}
|
||||
}
|
||||
|
||||
hb_buffer_destroy( buf );
|
||||
hb_font_destroy( referencedFont );
|
||||
|
||||
@@ -574,7 +494,7 @@ void OUTLINE_FONT::RenderToOpenGLCanvas( KIGFX::OPENGL_GAL& aGal, const wxString
|
||||
unsigned int glyphCount;
|
||||
hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( buf, &glyphCount );
|
||||
hb_glyph_position_t* glyphPos = hb_buffer_get_glyph_positions( buf, &glyphCount );
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* Copyright (C) 2016-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Stroke font class
|
||||
*
|
||||
@@ -44,7 +44,7 @@ using namespace KIFONT;
|
||||
|
||||
|
||||
///< Factor that determines relative vertical position of the overbar.
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.40;
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.23;
|
||||
|
||||
///< Factor that determines relative vertical position of the underline.
|
||||
static constexpr double UNDERLINE_POSITION_FACTOR = -0.16;
|
||||
@@ -128,7 +128,6 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe
|
||||
|
||||
while( aNewStrokeFont[j][i] )
|
||||
{
|
||||
|
||||
if( aNewStrokeFont[j][i] == ' ' && aNewStrokeFont[j][i+1] == 'R' )
|
||||
strokes++;
|
||||
|
||||
@@ -228,9 +227,9 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
{
|
||||
constexpr int TAB_WIDTH = 4;
|
||||
constexpr double INTER_CHAR = 0.2;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.7;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.5;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.3;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.8;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.35;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.15;
|
||||
|
||||
VECTOR2I cursor( aPosition );
|
||||
VECTOR2D glyphSize( aSize );
|
||||
@@ -295,71 +294,16 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
|
||||
glyphExtents *= glyphSize;
|
||||
|
||||
if( tilt > 0.0 )
|
||||
glyphExtents.x -= glyphExtents.y * tilt;
|
||||
|
||||
cursor.x += KiROUND( glyphExtents.x );
|
||||
}
|
||||
|
||||
++char_count;
|
||||
}
|
||||
|
||||
VECTOR2D barOffset( 0.0, 0.0 );
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = glyphSize.x * 0.1;
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::OVERBAR )
|
||||
{
|
||||
barOffset.y = ComputeOverbarVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH overbarGlyph;
|
||||
|
||||
overbarGlyph.AddPoint( barStart );
|
||||
overbarGlyph.AddPoint( barEnd );
|
||||
overbarGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( overbarGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
barOffset.y = ComputeUnderlineVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH underlineGlyph;
|
||||
|
||||
underlineGlyph.AddPoint( barStart );
|
||||
underlineGlyph.AddPoint( barEnd );
|
||||
underlineGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( underlineGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aBBox )
|
||||
{
|
||||
aBBox->SetOrigin( aPosition );
|
||||
aBBox->SetEnd( cursor.x + barOffset.x - KiROUND( glyphSize.x * INTER_CHAR ),
|
||||
cursor.y + std::max( glyphSize.y, barOffset.y * OVERBAR_POSITION_FACTOR ) );
|
||||
aBBox->SetEnd( cursor.x - KiROUND( glyphSize.x * INTER_CHAR ), cursor.y + glyphSize.y );
|
||||
aBBox->Normalize();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,11 @@ void FOOTPRINT_FILTER_IT::increment()
|
||||
candidate.GetLibNickname(),
|
||||
candidate.GetFootprintName(),
|
||||
candidate.GetSearchText() );
|
||||
int matches, position;
|
||||
bool exclude = false;
|
||||
bool exclude = false;
|
||||
|
||||
for( std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : m_filter->m_pattern_filters )
|
||||
{
|
||||
if( !matcher->Find( searchStr.Lower(), matches, position ) )
|
||||
if( !matcher->Find( searchStr.Lower() ) )
|
||||
{
|
||||
exclude = true;
|
||||
break;
|
||||
|
||||
@@ -180,7 +180,7 @@ bool COLOR4D::SetFromHexString( const wxString& aColorString )
|
||||
str.Trim( true );
|
||||
str.Trim( false );
|
||||
|
||||
if( str.length() < 7 || str.GetChar( 0 ) != '#' )
|
||||
if( str.length() < 7 || !str.StartsWith( '#' ) )
|
||||
return false;
|
||||
|
||||
unsigned long tmp;
|
||||
|
||||
@@ -169,14 +169,6 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
bmp.w = imgData.GetSize().x;
|
||||
bmp.h = imgData.GetSize().y;
|
||||
|
||||
// The bitmap size needs to be a multiple of 4.
|
||||
// This is easiest to achieve by ensuring that each row
|
||||
// has a multiple of 4 pixels
|
||||
int extra_w = bmp.w % 4;
|
||||
|
||||
if( extra_w )
|
||||
extra_w = 4 - extra_w;
|
||||
|
||||
GLuint textureID;
|
||||
|
||||
if( m_freedTextureIds.empty() )
|
||||
@@ -189,15 +181,14 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
m_freedTextureIds.pop_front();
|
||||
}
|
||||
|
||||
// make_unique initializes this to 0, so extra pixels are transparent
|
||||
bmp.size = ( bmp.w + extra_w ) * bmp.h * 4;
|
||||
bmp.size = bmp.w * bmp.h * 4;
|
||||
auto buf = std::make_unique<uint8_t[]>( bmp.size );
|
||||
|
||||
for( int y = 0; y < bmp.h; y++ )
|
||||
{
|
||||
for( int x = 0; x < bmp.w; x++ )
|
||||
{
|
||||
uint8_t* p = buf.get() + ( ( bmp.w + extra_w ) * y + x ) * 4;
|
||||
uint8_t* p = buf.get() + ( bmp.w * y + x ) * 4;
|
||||
|
||||
p[0] = imgData.GetRed( x, y );
|
||||
p[1] = imgData.GetGreen( x, y );
|
||||
@@ -214,7 +205,7 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, textureID );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w + extra_w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
buf.get() );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||
@@ -1427,21 +1418,23 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, texture_id );
|
||||
|
||||
float texStartX = aBitmap.IsMirrored() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirrored() ? 0.0 : 1.0;
|
||||
float texStartX = aBitmap.IsMirroredX() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirroredX() ? 0.0 : 1.0;
|
||||
float texStartY = aBitmap.IsMirroredY() ? 1.0 : 0.0;
|
||||
float texEndY = aBitmap.IsMirroredY() ? 0.0 : 1.0;
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 0.0 );
|
||||
glTexCoord2f( texStartX, texStartY );
|
||||
glVertex3f( v0.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 0.0 );
|
||||
glTexCoord2f( texEndX, texStartY);
|
||||
glVertex3f( v1.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 1.0 );
|
||||
glTexCoord2f( texEndX, texEndY);
|
||||
glVertex3f( v1.x, v1.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 1.0 );
|
||||
glTexCoord2f( texStartX, texEndY);
|
||||
glVertex3f( v0.x, v1.y, m_layerDepth );
|
||||
glEnd();
|
||||
|
||||
|
||||
+17
-2
@@ -418,9 +418,16 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
if( ev.GetKeyCode() == WXK_RETURN && m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
if( ( ev.GetKeyCode() == WXK_RETURN || ev.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
&& ev.GetModifiers() == wxMOD_NONE
|
||||
&& m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
m_addHandler( dummy );
|
||||
@@ -449,6 +456,14 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
m_grid->ForceRefresh();
|
||||
}
|
||||
}
|
||||
else if( ev.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
m_grid->CancelPendingChanges();
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !handled )
|
||||
ev.Skip( true );
|
||||
|
||||
@@ -27,109 +27,21 @@
|
||||
// conflicts for some defines, at least on Windows
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <ki_exception.h> // THROW_IO_ERROR
|
||||
|
||||
|
||||
|
||||
// These are even more private than class members, and since there is only
|
||||
// one instance of KICAD_CURL ever, these statics are hidden here to simplify the
|
||||
// client (API) header file.
|
||||
static volatile bool s_initialized;
|
||||
|
||||
static std::mutex s_lock; // for s_initialized
|
||||
|
||||
/// At process termination, using atexit() keeps the CURL stuff out of the
|
||||
/// singletops and PGM_BASE.
|
||||
static void at_terminate()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Init()
|
||||
{
|
||||
// We test s_initialized twice in an effort to avoid
|
||||
// unnecessarily locking s_lock. This understands that the common case
|
||||
// will not need to lock.
|
||||
if( !s_initialized )
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( !s_initialized )
|
||||
{
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
}
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Cleanup()
|
||||
{
|
||||
/*
|
||||
|
||||
Calling lock_guard() from a static destructor will typically be bad, since the
|
||||
s_lock may already have been statically destroyed itself leading to a boost
|
||||
exception. (Remember C++ does not provide certain sequencing of static
|
||||
destructor invocation.)
|
||||
|
||||
To prevent this we test s_initialized twice, which ensures that the lock_guard
|
||||
is only instantiated on the first call, which should be from
|
||||
PGM_BASE::destroy() which is first called earlier than static destruction.
|
||||
Then when called again from the actual PGM_BASE::~PGM_BASE() function,
|
||||
lock_guard will not be instantiated because s_initialized will be false.
|
||||
|
||||
*/
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
curl_global_cleanup();
|
||||
|
||||
atexit( &at_terminate );
|
||||
|
||||
s_initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string KICAD_CURL::GetSimpleVersion()
|
||||
{
|
||||
if( !s_initialized )
|
||||
Init();
|
||||
|
||||
curl_version_info_data* info = curl_version_info( CURLVERSION_NOW );
|
||||
|
||||
std::string res;
|
||||
|
||||
if( info->version )
|
||||
{
|
||||
res += "libcurl version: " + std::string( info->version );
|
||||
}
|
||||
|
||||
res += " (";
|
||||
|
||||
if( info->features & CURL_VERSION_SSL )
|
||||
{
|
||||
res += "with SSL - ";
|
||||
res += std::string( info->ssl_version );
|
||||
}
|
||||
else
|
||||
{
|
||||
res += "without SSL";
|
||||
}
|
||||
res += ")";
|
||||
|
||||
return res;
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2023 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
|
||||
@@ -100,23 +100,18 @@ static int xferinfo( void* aProgress, curl_off_t aDLtotal, curl_off_t aDLnow, cu
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x072000 // 7.32.0
|
||||
static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double aULtotal, double aULnow )
|
||||
{
|
||||
return xferinfo( aProgress, static_cast<curl_off_t>( aDLtotal ), static_cast<curl_off_t>( aDLnow ),
|
||||
static_cast<curl_off_t>( aULtotal ), static_cast<curl_off_t>( aULnow ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
m_headers( nullptr )
|
||||
{
|
||||
// Call KICAD_CURL::Init() from in here every time, but only the first time
|
||||
// will incur any overhead. This strategy ensures that libcurl is never loaded
|
||||
// unless it is needed.
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
m_CURL = curl_easy_init();
|
||||
|
||||
if( !m_CURL )
|
||||
@@ -126,7 +121,11 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, static_cast<void*>( &m_buffer ) );
|
||||
|
||||
// Only allow HTTP and HTTPS protocols
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500 // version 7.85.0
|
||||
curl_easy_setopt(m_CURL, CURLOPT_PROTOCOLS_STR, "http,https");
|
||||
#else
|
||||
curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// We need this to use the Windows Certificate store
|
||||
|
||||
+6
-4
@@ -431,15 +431,17 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ), ioe.What() );
|
||||
wxLogError( ioe.What() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
catch( const std::exception& e)
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ), e.what() );
|
||||
wxLogError( e.what() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ) );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2023 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
|
||||
@@ -24,12 +24,16 @@ LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) : GRID_TRICKS( aG
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
|
||||
{
|
||||
bool showActivate = false;
|
||||
bool showDeactivate = false;
|
||||
LIB_TABLE_GRID* tbl = static_cast<LIB_TABLE_GRID*>( m_grid->GetTable() );
|
||||
|
||||
// Ensure selection parameters are up to date
|
||||
getSelectedArea();
|
||||
|
||||
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
|
||||
{
|
||||
if( tbl->GetValueAsBool( row, 0 ) )
|
||||
@@ -49,10 +53,14 @@ void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED, _( "Activate selected" ) );
|
||||
if( showDeactivate )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_DEACTIVATE_SELECTED, _( "Deactivate selected" ) );
|
||||
menu.AppendSeparator();
|
||||
|
||||
if( showActivate || showDeactivate )
|
||||
menu.AppendSeparator();
|
||||
|
||||
GRID_TRICKS::showPopupMenu( menu );
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
{
|
||||
int menu_id = event.GetId();
|
||||
@@ -61,10 +69,13 @@ void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
{
|
||||
LIB_TABLE_GRID* tbl = (LIB_TABLE_GRID*) m_grid->GetTable();
|
||||
|
||||
bool selected_state = menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED;
|
||||
|
||||
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
|
||||
{
|
||||
tbl->SetValueAsBool( row, 0, menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED );
|
||||
}
|
||||
tbl->SetValueAsBool( row, 0, selected_state );
|
||||
|
||||
// Ensure the new state (on/off) of the widgets is immediately shown:
|
||||
m_grid->Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*lib_tree_model
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -24,14 +24,12 @@
|
||||
#include <algorithm>
|
||||
#include <eda_pattern_match.h>
|
||||
#include <lib_tree_item.h>
|
||||
#include <utility>
|
||||
#include <pgm_base.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
// Each node gets this lowest score initially, without any matches applied.
|
||||
// Matches will then increase this score depending on match quality. This way,
|
||||
// an empty search string will result in all components being displayed as they
|
||||
// have the minimum score. However, in that case, we avoid expanding all the
|
||||
// Each node gets this lowest score initially, without any matches applied. Matches will then
|
||||
// increase this score. This way, an empty search string will result in all components being
|
||||
// displayed as they have the minimum score. However, in that case, we avoid expanding all the
|
||||
// nodes asd the result is very unspecific.
|
||||
static const unsigned kLowestDefaultScore = 1;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -213,17 +213,11 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
Thaw();
|
||||
}
|
||||
|
||||
LIB_TREE_NODE* bestMatch = ShowResults();
|
||||
const LIB_TREE_NODE* firstMatch = ShowResults();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowPreselect();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowSingleLibrary();
|
||||
|
||||
if( bestMatch )
|
||||
if( firstMatch )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( bestMatch );
|
||||
wxDataViewItem item = ToItem( firstMatch );
|
||||
m_widget->Select( item );
|
||||
|
||||
// Make sure the *parent* item is visible. The selected item is the
|
||||
@@ -269,7 +263,7 @@ void LIB_TREE_MODEL_ADAPTER::recreateColumns()
|
||||
for( const wxString& colName : m_shownColumns )
|
||||
{
|
||||
if( !m_colNameMap.count( colName ) )
|
||||
doAddColumn( colName, false );
|
||||
doAddColumn( colName, colName == wxT( "Description" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,93 +613,85 @@ bool LIB_TREE_MODEL_ADAPTER::GetAttr( const wxDataViewItem& aItem,
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::Find( LIB_TREE_NODE& aNode,
|
||||
std::function<bool( const LIB_TREE_NODE* )> aFunc,
|
||||
LIB_TREE_NODE** aHighScore )
|
||||
void recursiveDescent( LIB_TREE_NODE& aNode, const std::function<bool( const LIB_TREE_NODE* )>& f )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& node: aNode.m_Children )
|
||||
{
|
||||
if( aFunc( &*node ) )
|
||||
{
|
||||
if( !(*aHighScore) || node->m_Score > (*aHighScore)->m_Score )
|
||||
(*aHighScore) = &*node;
|
||||
}
|
||||
if( !f( node.get() ) )
|
||||
break;
|
||||
|
||||
Find( *node, aFunc, aHighScore );
|
||||
recursiveDescent( *node, f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
const LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
const LIB_TREE_NODE* firstMatch = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
// return leaf nodes with some level of matching
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowPreselect()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
if( !m_preselect_lib_id.IsValid() )
|
||||
return highScore;
|
||||
|
||||
Find( m_tree,
|
||||
[&]( LIB_TREE_NODE const* n )
|
||||
// Expand parents of leaf nodes with some level of matching
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID && ( n->m_Children.empty() ||
|
||||
!m_preselect_unit ) )
|
||||
return m_preselect_lib_id == n->m_LibId;
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT && m_preselect_unit )
|
||||
return m_preselect_lib_id == n->m_Parent->m_LibId &&
|
||||
m_preselect_unit == n->m_Unit;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
&highScore );
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1 )
|
||||
{
|
||||
if( !firstMatch )
|
||||
firstMatch = n;
|
||||
else if( n->m_Score > firstMatch->m_Score )
|
||||
firstMatch = n;
|
||||
|
||||
if( highScore)
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
}
|
||||
|
||||
return true; // keep going to expand ancestors of all found items
|
||||
} );
|
||||
|
||||
// If no matches, find and show the preselect node
|
||||
if( !firstMatch && m_preselect_lib_id.IsValid() )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID
|
||||
&& ( n->m_Children.empty() || !m_preselect_unit )
|
||||
&& m_preselect_lib_id == n->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT
|
||||
&& ( m_preselect_unit && m_preselect_unit == n->m_Unit )
|
||||
&& m_preselect_lib_id == n->m_Parent->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
// If still no matches expand a single library if there is only one
|
||||
if( !firstMatch )
|
||||
{
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID
|
||||
&& n->m_Parent->m_Parent->m_Children.size() == 1 )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return firstMatch;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowSingleLibrary()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID &&
|
||||
n->m_Parent->m_Parent->m_Children.size() == 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of libeval, a simple math expression evaluator
|
||||
*
|
||||
* Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 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
|
||||
@@ -356,10 +356,11 @@ void COMPILER::newString( const wxString& aString )
|
||||
m_parseFinished = false;
|
||||
}
|
||||
|
||||
|
||||
T_TOKEN COMPILER::getToken()
|
||||
{
|
||||
T_TOKEN rv;
|
||||
rv.value.str = nullptr;
|
||||
rv.value = defaultTokenValue;
|
||||
|
||||
bool done = false;
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <wx/tooltip.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <cli/cli_names.h> // Needed for the pre wx 3.2 cli workaround
|
||||
#include <common.h>
|
||||
#include <config_params.h>
|
||||
#include <confirm.h>
|
||||
@@ -51,6 +52,7 @@
|
||||
#include <eda_draw_frame.h>
|
||||
#include <gestfich.h>
|
||||
#include <id.h>
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
#include <kiplatform/policy.h>
|
||||
#include <lockfile.h>
|
||||
#include <menus_helpers.h>
|
||||
@@ -150,6 +152,8 @@ PGM_BASE::~PGM_BASE()
|
||||
|
||||
void PGM_BASE::Destroy()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_close();
|
||||
#endif
|
||||
@@ -408,6 +412,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||
// In particular, the user cache path is the most likely to be hit by startup code
|
||||
PATHS::EnsureUserPathsExist();
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentryInit();
|
||||
#endif
|
||||
@@ -857,3 +863,21 @@ ENV_VAR_MAP& PGM_BASE::GetLocalEnvVariables() const
|
||||
{
|
||||
return GetCommonSettings()->m_Env.vars;
|
||||
}
|
||||
|
||||
|
||||
bool PGM_BASE::IsGUI()
|
||||
{
|
||||
if( !wxTheApp )
|
||||
return false;
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
return wxTheApp->IsGUI();
|
||||
#else
|
||||
// wxWidgets older than version 3.1.6 do not have a way to know if the app
|
||||
// has a GUI or is a console application.
|
||||
// So the trick is to set the App class name when starting kicad-cli, and when
|
||||
// the app class name is the kicad-cli class name the app is a console app
|
||||
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
|
||||
return run_gui;
|
||||
#endif
|
||||
}
|
||||
@@ -848,11 +848,16 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
|
||||
LineTo( start );
|
||||
|
||||
VECTOR2D devEnd = userToDeviceCoordinates( end );
|
||||
VECTOR2D devCenter = userToDeviceCoordinates( center - start );
|
||||
|
||||
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
|
||||
// Warning: it is **not** userToDeviceCoordinates( center - start ) when the plotter
|
||||
// has an offset.
|
||||
VECTOR2D devRelCenter = userToDeviceCoordinates( center ) - userToDeviceCoordinates( start );
|
||||
|
||||
// We need to know if the arc is CW or CCW in device coordinates, so build this arc.
|
||||
SHAPE_ARC deviceArc( userToDeviceCoordinates( start ),
|
||||
userToDeviceCoordinates( aArc.GetArcMid() ), devEnd, 0 );
|
||||
userToDeviceCoordinates( aArc.GetArcMid() ),
|
||||
devEnd, 0 );
|
||||
|
||||
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
|
||||
|
||||
@@ -863,7 +868,7 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
|
||||
|
||||
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
|
||||
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
|
||||
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
|
||||
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
|
||||
|
||||
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
|
||||
}
|
||||
@@ -884,7 +889,8 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
||||
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
|
||||
end.y = aCenter.y - KiROUND( aRadius * aEndAngle.Sin() );
|
||||
VECTOR2D devEnd = userToDeviceCoordinates( end );
|
||||
VECTOR2D devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
|
||||
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
|
||||
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
|
||||
|
||||
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
|
||||
|
||||
@@ -895,7 +901,7 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
||||
|
||||
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
|
||||
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
|
||||
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
|
||||
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
|
||||
|
||||
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
|
||||
}
|
||||
@@ -1020,7 +1026,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
|
||||
{
|
||||
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
|
||||
|
||||
plotArc( arc, ii > 0 );
|
||||
plotArc( arc, true );
|
||||
|
||||
// skip points on arcs, since we plot the arc itself
|
||||
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
|
||||
@@ -1054,7 +1060,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
|
||||
{
|
||||
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
|
||||
|
||||
plotArc( arc, ii > 0 );
|
||||
plotArc( arc, true );
|
||||
|
||||
// skip points on arcs, since we plot the arc itself
|
||||
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
|
||||
|
||||
@@ -513,10 +513,11 @@ void PDF_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||
|
||||
if( alpha < 0xFF )
|
||||
{
|
||||
float a = 1.0 - ( (float) alpha / 255.0 );
|
||||
r = ( int )( r + ( a * 0xFF ) ) & 0xFF;
|
||||
g = ( int )( g + ( a * 0xFF ) ) & 0xFF;
|
||||
b = ( int )( b + ( a * 0xFF ) ) & 0xFF;
|
||||
float d = alpha / 255.0;
|
||||
float a = 1.0 - d;
|
||||
r = std::min( KiROUND( r * d + ( a * 0xFF ) ), 0xFF );
|
||||
g = std::min( KiROUND( g * d + ( a * 0xFF ) ), 0xFF );
|
||||
b = std::min( KiROUND( b * d + ( a * 0xFF ) ), 0xFF );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,10 +139,10 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL
|
||||
|
||||
int penWidth = std::max( text->GetEffectiveTextPenWidth(), defaultPenWidth );
|
||||
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText(), text->GetTextAngle(),
|
||||
text->GetTextSize(), text->GetHorizJustify(), text->GetVertJustify(),
|
||||
penWidth, text->IsItalic(), text->IsBold(), text->IsMultilineAllowed(),
|
||||
font );
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText( true ),
|
||||
text->GetTextAngle(), text->GetTextSize(), text->GetHorizJustify(),
|
||||
text->GetVertJustify(), penWidth, text->IsItalic(), text->IsBold(),
|
||||
text->IsMultilineAllowed(), font );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ wxString escapeName( const wxString& aNetName )
|
||||
|
||||
wxString interpretText( const wxString& aText )
|
||||
{
|
||||
wxString token = aText.Upper();
|
||||
wxString token = aText;
|
||||
|
||||
if( substituteVariable( &token ) )
|
||||
return token;
|
||||
@@ -116,25 +116,32 @@ wxString interpretText( const wxString& aText )
|
||||
|
||||
bool substituteVariable( wxString* aText )
|
||||
{
|
||||
if ( *aText == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( *aText == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( *aText == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( *aText == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( *aText == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( *aText == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( *aText == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( *aText == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else return false;
|
||||
if( aText->StartsWith( '>' ) && aText->AfterFirst( ' ' ).IsEmpty() )
|
||||
{
|
||||
wxString token = aText->Upper();
|
||||
|
||||
return true;
|
||||
if ( token == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( token == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( token == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( token == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( token == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( token == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( token == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( token == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else *aText = wxString::Format( wxS( "${%s}" ), aText->Mid( 1 ).Trim() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ struct EPART;
|
||||
struct ETEXT;
|
||||
|
||||
typedef std::unordered_map<wxString, wxXmlNode*> NODE_MAP;
|
||||
typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP;
|
||||
typedef std::map<wxString, EINSTANCE*> EINSTANCE_MAP;
|
||||
typedef std::map<wxString, std::unique_ptr<EPART>> EPART_MAP;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 CERN
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
@@ -393,10 +393,7 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
|
||||
for( const auto& [ matcher, netclassName ] : m_NetClassPatternAssignments )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher->Find( aNetName, matches, offset ) && offset == 0 )
|
||||
if( matcher->StartsWith( aNetName ) )
|
||||
return getNetclass( netclassName );
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,8 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
||||
return;
|
||||
}
|
||||
|
||||
m_files.clear();
|
||||
|
||||
for( const nlohmann::json& file : aVal )
|
||||
{
|
||||
PROJECT_FILE_STATE fileState;
|
||||
|
||||
@@ -73,9 +73,14 @@ wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGPr
|
||||
m_unitBinder->SetUnits( m_frame->GetUserUnits() );
|
||||
|
||||
if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
|
||||
{
|
||||
m_unitBinder->SetCoordType( prop->CoordType() );
|
||||
}
|
||||
else if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
|
||||
{
|
||||
m_unitBinder->SetCoordType( ORIGIN_TRANSFORMS::NOT_A_COORD );
|
||||
m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
|
||||
}
|
||||
|
||||
UpdateControl( aProperty, win );
|
||||
|
||||
|
||||
+22
-32
@@ -333,73 +333,63 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
||||
{
|
||||
const RC_TREE_NODE* node = ToNode( aItem );
|
||||
const std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
|
||||
MARKER_BASE* marker = rcItem->GetParent();
|
||||
EDA_ITEM* item = nullptr;
|
||||
wxString msg;
|
||||
|
||||
switch( node->m_Type )
|
||||
{
|
||||
case RC_TREE_NODE::MARKER:
|
||||
{
|
||||
wxString prefix;
|
||||
|
||||
if( rcItem->GetParent() )
|
||||
if( marker )
|
||||
{
|
||||
SEVERITY severity = rcItem->GetParent()->GetSeverity();
|
||||
SEVERITY severity = marker->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
|
||||
prefix = _( "Excluded warning: " );
|
||||
msg = _( "Excluded warning: " );
|
||||
else
|
||||
prefix = _( "Excluded error: " );
|
||||
msg = _( "Excluded error: " );
|
||||
}
|
||||
else if( severity == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
prefix = _( "Warning: " );
|
||||
msg = _( "Warning: " );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = _( "Error: " );
|
||||
msg = _( "Error: " );
|
||||
}
|
||||
}
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
}
|
||||
msg += rcItem->GetErrorMessage();
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::MAIN_ITEM:
|
||||
if( rcItem->GetParent() && rcItem->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
{
|
||||
aVariant = _( "Drawing Sheet" );
|
||||
break;
|
||||
}
|
||||
if( marker && marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
msg = _( "Drawing Sheet" );
|
||||
else
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM2:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM3:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
break;
|
||||
}
|
||||
|
||||
if( item )
|
||||
msg += item->GetItemDescription( m_editFrame );
|
||||
|
||||
msg.Replace( wxS( "\n" ), wxS( " " ) );
|
||||
aVariant = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+42
-1
@@ -38,7 +38,7 @@
|
||||
#if !defined( HAVE_FGETC_NOLOCK )
|
||||
#ifdef _MSC_VER
|
||||
//getc is not a macro on windows and adds a tiny overhead for the indirection to eventually calling fgetc
|
||||
#define getc_unlocked fgetc
|
||||
#define getc_unlocked _fgetc_nolock
|
||||
#else
|
||||
#define getc_unlocked getc
|
||||
#endif
|
||||
@@ -106,6 +106,47 @@ std::string StrPrintf( const char* format, ... )
|
||||
}
|
||||
|
||||
|
||||
wxString SafeReadFile( const wxString& aFilePath, const wxString& aReadType )
|
||||
{
|
||||
auto FROM_UTF8_WINE =
|
||||
[]( const char* cstring )
|
||||
{
|
||||
wxString line = wxString::FromUTF8( cstring );
|
||||
|
||||
if( line.IsEmpty() ) // happens when cstring is not a valid UTF8 sequence
|
||||
line = wxConvCurrent->cMB2WC( cstring ); // try to use locale conversion
|
||||
|
||||
// We have trouble here *probably* because Wine-hosted LTSpice writes out MSW
|
||||
// encoded text on a macOS, where it isn't expected. In any case, wxWidgets'
|
||||
// wxSafeConvert() appears to get around it.
|
||||
|
||||
if( line.IsEmpty() )
|
||||
line = wxSafeConvertMB2WX( cstring );
|
||||
|
||||
// I'm not sure what the source of this style of line-endings is, but it can be
|
||||
// found in some Fairchild Semiconductor SPICE files.
|
||||
line.Replace( wxS( "\r\r\n" ), wxS( "\n" ) );
|
||||
|
||||
return line;
|
||||
};
|
||||
|
||||
// Open file
|
||||
FILE* fp = wxFopen( aFilePath, aReadType );
|
||||
|
||||
if( !fp )
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'." ), aFilePath ) );
|
||||
|
||||
FILE_LINE_READER fileReader( fp, aFilePath );
|
||||
|
||||
wxString contents;
|
||||
|
||||
while( fileReader.ReadLine() )
|
||||
contents += FROM_UTF8_WINE( fileReader.Line() );
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
||||
//-----<LINE_READER>------------------------------------------------------
|
||||
|
||||
LINE_READER::LINE_READER( unsigned aMaxLineLength ) :
|
||||
|
||||
@@ -242,6 +242,13 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_BACK )
|
||||
{
|
||||
if( aEvent.GetModifiers() == wxMOD_CONTROL )
|
||||
#ifdef __WXMAC__
|
||||
m_te->HomeExtend();
|
||||
else if( aEvent.GetModifiers() == wxMOD_ALT )
|
||||
#endif
|
||||
m_te->WordLeftExtend();
|
||||
|
||||
m_te->DeleteBack();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_DELETE )
|
||||
|
||||
@@ -109,8 +109,17 @@ void SETTINGS_MANAGER::Load()
|
||||
// TODO(JE) We should check for dirty settings here and write them if so, because
|
||||
// Load() could be called late in the application lifecycle
|
||||
|
||||
for( auto&& settings : m_settings )
|
||||
settings->LoadFromFile( GetPathForSettingsFile( settings.get() ) );
|
||||
std::vector<JSON_SETTINGS*> toLoad;
|
||||
|
||||
// Cache a copy of raw pointers; m_settings may be modified during the load loop
|
||||
std::transform( m_settings.begin(), m_settings.end(), std::back_inserter( toLoad ),
|
||||
[]( std::unique_ptr<JSON_SETTINGS>& aSettings )
|
||||
{
|
||||
return aSettings.get();
|
||||
} );
|
||||
|
||||
for( JSON_SETTINGS* settings : toLoad )
|
||||
settings->LoadFromFile( GetPathForSettingsFile( settings ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -633,12 +642,12 @@ bool SETTINGS_MANAGER::GetPreviousVersionPaths( std::vector<wxString>* aPaths )
|
||||
wxFileName wxGtkPath;
|
||||
wxGtkPath.AssignDir( wxS( "~/.config/kicad" ) );
|
||||
wxGtkPath.MakeAbsolute();
|
||||
base_paths.emplace_back( wxGtkPath.GetPath() );
|
||||
base_paths.emplace_back( wxGtkPath );
|
||||
|
||||
// We also want to pick up regular flatpak if we are nightly
|
||||
wxGtkPath.AssignDir( wxS( "~/.var/app/org.kicad.KiCad/config/kicad" ) );
|
||||
wxGtkPath.MakeAbsolute();
|
||||
base_paths.emplace_back( wxGtkPath.GetPath() );
|
||||
base_paths.emplace_back( wxGtkPath );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <kiway_player.h>
|
||||
#include <macros.h>
|
||||
#include <confirm.h>
|
||||
#include <settings/kicad_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
#include <kiplatform/app.h>
|
||||
@@ -340,6 +341,8 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
||||
// Tell the settings manager about the current Kiway
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
|
||||
GetSettingsManager().RegisterSettings( new KICAD_SETTINGS );
|
||||
|
||||
// Use KIWAY to create a top window, which registers its existence also.
|
||||
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
|
||||
// and is one of the types in FRAME_T.
|
||||
|
||||
+29
-20
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023 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
|
||||
@@ -159,9 +159,12 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
else
|
||||
converted += c;
|
||||
}
|
||||
else if( aContext == CTX_LIBID )
|
||||
else if( aContext == CTX_LIBID || aContext == CTX_LEGACY_LIBID )
|
||||
{
|
||||
if( c == '\\' )
|
||||
// We no longer escape '/' in LIB_IDs, but we used to
|
||||
if( c == '/' && aContext == CTX_LEGACY_LIBID )
|
||||
converted += wxT( "{slash}" );
|
||||
else if( c == '\\' )
|
||||
converted += wxT( "{backslash}" );
|
||||
else if( c == '<' )
|
||||
converted += wxT( "{lt}" );
|
||||
@@ -196,7 +199,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
}
|
||||
else if( aContext == CTX_JS_STR )
|
||||
{
|
||||
if( c >= 0x7F || c == '\'' || c == '\\' )
|
||||
if( c >= 0x7F || c == '\'' || c == '\\' || c == '(' || c == ')' )
|
||||
{
|
||||
unsigned int code = c;
|
||||
char buffer[16];
|
||||
@@ -277,42 +280,49 @@ wxString UnescapeString( const wxString& aSource )
|
||||
wxString newbuf;
|
||||
newbuf.reserve( sourceLen );
|
||||
|
||||
wxUniChar prev = 0;
|
||||
wxUniChar ch = 0;
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
wxUniChar ch = aSource[i];
|
||||
prev = ch;
|
||||
ch = aSource[i];
|
||||
|
||||
if( ( ch == '$' || ch == '~' || ch == '^' || ch == '_' )
|
||||
&& i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
for( ; i < sourceLen; ++i )
|
||||
{
|
||||
ch = aSource[i];
|
||||
newbuf += ch;
|
||||
|
||||
if( ch == '}' )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( ch == '{' )
|
||||
if( ch == '{' )
|
||||
{
|
||||
wxString token;
|
||||
int depth = 1;
|
||||
bool terminated = false;
|
||||
|
||||
for( i = i + 1; i < sourceLen; ++i )
|
||||
{
|
||||
ch = aSource[i];
|
||||
|
||||
if( ch == '{' )
|
||||
depth++;
|
||||
else if( ch == '}' )
|
||||
depth--;
|
||||
|
||||
if( depth <= 0 )
|
||||
{
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
token.append( ch );
|
||||
}
|
||||
}
|
||||
|
||||
if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
||||
if( !terminated )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
|
||||
}
|
||||
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
}
|
||||
else if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
||||
else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
|
||||
else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
|
||||
else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
|
||||
@@ -326,7 +336,6 @@ wxString UnescapeString( const wxString& aSource )
|
||||
else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
|
||||
else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
|
||||
else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
|
||||
else if( token.IsEmpty() ) newbuf.append( wxT( "{" ) );
|
||||
else
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
|
||||
@@ -129,7 +129,10 @@ void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel, bool aGlobal ) cons
|
||||
const TEMPLATE_FIELDNAMES& source = aGlobal ? m_globals : m_project;
|
||||
|
||||
for( const TEMPLATE_FIELDNAME& temp : source )
|
||||
temp.Format( out, nestLevel+1 );
|
||||
{
|
||||
if( !temp.m_Name.IsEmpty() )
|
||||
temp.Format( out, nestLevel+1 );
|
||||
}
|
||||
|
||||
out->Print( 0, ")\n" );
|
||||
}
|
||||
@@ -162,7 +165,8 @@ void TEMPLATES::parse( TEMPLATE_FIELDNAMES_LEXER* in, bool aGlobal )
|
||||
field.Parse( in );
|
||||
|
||||
// add the field
|
||||
AddTemplateFieldName( field, aGlobal );
|
||||
if( !field.m_Name.IsEmpty() )
|
||||
AddTemplateFieldName( field, aGlobal );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ void TEXTENTRY_TRICKS::OnCharHook( wxTextEntry* aTextEntry, wxKeyEvent& aEvent )
|
||||
{
|
||||
aTextEntry->Paste();
|
||||
}
|
||||
else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'A' )
|
||||
{
|
||||
aTextEntry->SelectAll();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_BACK )
|
||||
{
|
||||
long start, end;
|
||||
|
||||
@@ -113,7 +113,9 @@ int COMMON_CONTROL::ShowLibraryTable( const TOOL_EVENT& aEvent )
|
||||
try // Sch frame was not available, try to start it
|
||||
{
|
||||
KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH );
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
|
||||
if( kiface )
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
@@ -128,7 +130,9 @@ int COMMON_CONTROL::ShowLibraryTable( const TOOL_EVENT& aEvent )
|
||||
try // Pcb frame was not available, try to start it
|
||||
{
|
||||
KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_PCB );
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_PCB_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
|
||||
if( kiface )
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_PCB_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
|
||||
+41
-44
@@ -240,16 +240,14 @@ private:
|
||||
|
||||
void VIEW::OnDestroy( VIEW_ITEM* aItem )
|
||||
{
|
||||
VIEW_ITEM_DATA* data = aItem->viewPrivData();
|
||||
if( aItem->m_viewPrivData )
|
||||
{
|
||||
if( aItem->m_viewPrivData->m_view )
|
||||
aItem->m_viewPrivData->m_view->VIEW::Remove( aItem );
|
||||
|
||||
if( !data )
|
||||
return;
|
||||
|
||||
if( data->m_view )
|
||||
data->m_view->VIEW::Remove( aItem );
|
||||
|
||||
delete data;
|
||||
aItem->ClearViewPrivData();
|
||||
delete aItem->m_viewPrivData;
|
||||
aItem->m_viewPrivData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -323,6 +321,10 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
if( !aItem->m_viewPrivData )
|
||||
aItem->m_viewPrivData = new VIEW_ITEM_DATA;
|
||||
|
||||
wxASSERT_MSG( aItem->m_viewPrivData->m_view == nullptr
|
||||
|| aItem->m_viewPrivData->m_view == this,
|
||||
wxS( "Already in a different view!" ) );
|
||||
|
||||
aItem->m_viewPrivData->m_view = this;
|
||||
aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
|
||||
|
||||
@@ -334,7 +336,7 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
wxCHECK2_MSG( layers[i] >= 0 && static_cast<unsigned>( layers[i] ) < m_layers.size(),
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
@@ -348,41 +350,36 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
|
||||
void VIEW::Remove( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( !aItem )
|
||||
return;
|
||||
|
||||
auto viewData = aItem->viewPrivData();
|
||||
|
||||
if( !viewData )
|
||||
return;
|
||||
|
||||
wxCHECK( viewData->m_view == this, /*void*/ );
|
||||
auto item = std::find( m_allItems->begin(), m_allItems->end(), aItem );
|
||||
|
||||
if( item != m_allItems->end() )
|
||||
if( aItem && aItem->m_viewPrivData )
|
||||
{
|
||||
m_allItems->erase( item );
|
||||
viewData->clearUpdateFlags();
|
||||
wxCHECK( aItem->m_viewPrivData->m_view == this, /*void*/ );
|
||||
auto item = std::find( m_allItems->begin(), m_allItems->end(), aItem );
|
||||
|
||||
if( item != m_allItems->end() )
|
||||
{
|
||||
m_allItems->erase( item );
|
||||
aItem->m_viewPrivData->clearUpdateFlags();
|
||||
}
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
aItem->m_viewPrivData->getLayers( layers, layers_count );
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
int prevGroup = aItem->m_viewPrivData->getGroup( layers[i] );
|
||||
|
||||
if( prevGroup >= 0 )
|
||||
m_gal->DeleteGroup( prevGroup );
|
||||
}
|
||||
|
||||
aItem->m_viewPrivData->deleteGroups();
|
||||
aItem->m_viewPrivData->m_view = nullptr;
|
||||
}
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
viewData->getLayers( layers, layers_count );
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
int prevGroup = viewData->getGroup( layers[i] );
|
||||
|
||||
if( prevGroup >= 0 )
|
||||
m_gal->DeleteGroup( prevGroup );
|
||||
}
|
||||
|
||||
viewData->deleteGroups();
|
||||
viewData->m_view = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1400,7 +1397,7 @@ void VIEW::RecacheAllItems()
|
||||
|
||||
void VIEW::UpdateItems()
|
||||
{
|
||||
if( !m_gal->IsVisible() )
|
||||
if( !m_gal->IsVisible() || !m_gal->IsInitialized() )
|
||||
return;
|
||||
|
||||
unsigned int cntGeomUpdate = 0;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <widgets/font_choice.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <wx/fontenum.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <pgm_base.h>
|
||||
@@ -54,7 +55,11 @@ FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize
|
||||
menuList.Add( wxString( name ) );
|
||||
|
||||
menuList.Sort();
|
||||
|
||||
Freeze();
|
||||
Append( menuList );
|
||||
KIPLATFORM::UI::LargeChoiceBoxHack( this );
|
||||
Thaw();
|
||||
|
||||
m_notFound = wxS( " " ) + _( "<not found>" );
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <project.h>
|
||||
#include <widgets/footprint_choice.h>
|
||||
#include <widgets/footprint_select_widget.h>
|
||||
#include <widgets/wx_progress_reporters.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <footprint_info_impl.h>
|
||||
#include <wx/wupdlock.h>
|
||||
@@ -38,7 +39,8 @@ FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWind
|
||||
wxPanel( aParent ),
|
||||
m_update( aUpdate ),
|
||||
m_max_items( aMaxItems ),
|
||||
m_fp_list( aFpList )
|
||||
m_fp_list( aFpList ),
|
||||
m_frame( aFrame )
|
||||
{
|
||||
m_zero_filter = true;
|
||||
m_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
@@ -63,8 +65,13 @@ void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
|
||||
{
|
||||
// If the fp-info-cache is empty (or, more likely, hasn't been created in a new
|
||||
// project yet), load footprints the hard way.
|
||||
FP_LIB_TABLE* fpTable = aProject.PcbFootprintLibs( aKiway );
|
||||
static_cast<FOOTPRINT_LIST_IMPL*>( m_fp_list )->ReadFootprintFiles( fpTable );
|
||||
FP_LIB_TABLE* fpTable = aProject.PcbFootprintLibs( aKiway );
|
||||
WX_PROGRESS_REPORTER* progressReporter =
|
||||
new WX_PROGRESS_REPORTER( m_frame, _( "Loading Footprint Libraries" ), 3 );
|
||||
static_cast<FOOTPRINT_LIST_IMPL*>( m_fp_list )
|
||||
->ReadFootprintFiles( fpTable, nullptr, progressReporter );
|
||||
|
||||
delete progressReporter;
|
||||
}
|
||||
|
||||
m_fp_filter.SetList( *m_fp_list );
|
||||
|
||||
@@ -185,6 +185,16 @@ LIB_TREE::~LIB_TREE()
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE::ShowChangedLanguage()
|
||||
{
|
||||
if( m_query_ctrl )
|
||||
m_query_ctrl->SetDescriptiveText( _( "Filter" ) );
|
||||
|
||||
if( m_adapter )
|
||||
m_adapter->ShowChangedLanguage();
|
||||
}
|
||||
|
||||
|
||||
LIB_ID LIB_TREE::GetSelectedLibId( int* aUnit ) const
|
||||
{
|
||||
wxDataViewItem sel = m_tree_ctrl->GetSelection();
|
||||
|
||||
+42
-33
@@ -61,7 +61,8 @@ double mpWindow::zoomIncrementalFactor = 1.1;
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS( mpLayer, wxObject )
|
||||
|
||||
mpLayer::mpLayer() : m_type( mpLAYER_UNDEF )
|
||||
mpLayer::mpLayer() :
|
||||
m_type( mpLAYER_UNDEF )
|
||||
{
|
||||
SetPen( (wxPen&) *wxBLACK_PEN );
|
||||
SetFont( (wxFont&) *wxNORMAL_FONT );
|
||||
@@ -197,12 +198,14 @@ wxSize mpInfoLayer::GetSize() const
|
||||
}
|
||||
|
||||
|
||||
mpInfoCoords::mpInfoCoords() : mpInfoLayer()
|
||||
mpInfoCoords::mpInfoCoords() :
|
||||
mpInfoLayer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
|
||||
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) :
|
||||
mpInfoLayer( rect, brush )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -273,12 +276,14 @@ void mpInfoCoords::Plot( wxDC& dc, mpWindow& w )
|
||||
}
|
||||
|
||||
|
||||
mpInfoLegend::mpInfoLegend() : mpInfoLayer()
|
||||
mpInfoLegend::mpInfoLegend() :
|
||||
mpInfoLayer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
|
||||
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) :
|
||||
mpInfoLayer( rect, brush )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -301,7 +306,7 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
int scrx = w.GetScrX();
|
||||
int scry = w.GetScrY();
|
||||
|
||||
if( (m_winX != scrx) || (m_winY != scry) )
|
||||
if( m_winX != scrx || m_winY != scry )
|
||||
{
|
||||
if( m_winX > 1 )
|
||||
m_dim.x = (int) floor( (double) (m_dim.x * scrx / m_winX) );
|
||||
@@ -322,26 +327,27 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
// wxBrush semiWhite(image1);
|
||||
dc.SetBrush( m_brush );
|
||||
dc.SetFont( m_font );
|
||||
const int baseWidth = (mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH);
|
||||
int textX = baseWidth, textY = mpLEGEND_MARGIN;
|
||||
int plotCount = 0;
|
||||
int posY = 0;
|
||||
int tmpX = 0, tmpY = 0;
|
||||
mpLayer* ly = nullptr;
|
||||
wxPen lpen;
|
||||
wxString label;
|
||||
|
||||
const int baseWidth = mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH;
|
||||
int textX = baseWidth, textY = mpLEGEND_MARGIN;
|
||||
int plotCount = 0;
|
||||
int posY = 0;
|
||||
int tmpX = 0;
|
||||
int tmpY = 0;
|
||||
mpLayer* layer = nullptr;
|
||||
wxPen lpen;
|
||||
wxString label;
|
||||
|
||||
for( unsigned int p = 0; p < w.CountAllLayers(); p++ )
|
||||
{
|
||||
ly = w.GetLayer( p );
|
||||
layer = w.GetLayer( p );
|
||||
|
||||
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
|
||||
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
|
||||
{
|
||||
label = ly->GetName();
|
||||
label = layer->GetDisplayName();
|
||||
dc.GetTextExtent( label, &tmpX, &tmpY );
|
||||
textX =
|
||||
( textX > (tmpX + baseWidth) ) ? textX : (tmpX + baseWidth + mpLEGEND_MARGIN);
|
||||
textY += (tmpY);
|
||||
textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth + mpLEGEND_MARGIN;
|
||||
textY += tmpY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,25 +363,25 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
|
||||
for( unsigned int p2 = 0; p2 < w.CountAllLayers(); p2++ )
|
||||
{
|
||||
ly = w.GetLayer( p2 );
|
||||
layer = w.GetLayer( p2 );
|
||||
|
||||
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
|
||||
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
|
||||
{
|
||||
label = ly->GetName();
|
||||
lpen = ly->GetPen();
|
||||
label = layer->GetDisplayName();
|
||||
lpen = layer->GetPen();
|
||||
dc.GetTextExtent( label, &tmpX, &tmpY );
|
||||
dc.SetPen( lpen );
|
||||
// textX = (textX > (tmpX + baseWidth)) ? textX : (tmpX + baseWidth);
|
||||
// textY += (tmpY + mpLEGEND_MARGIN);
|
||||
posY = m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY + (tmpY >> 1);
|
||||
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
|
||||
posY, // Y start coord
|
||||
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
|
||||
posY );
|
||||
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
|
||||
posY, // Y start coord
|
||||
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
|
||||
posY );
|
||||
// dc.DrawRectangle(m_dim.x + 5, m_dim.y + 5 + plotCount*tmpY, 5, 5);
|
||||
dc.DrawText( label,
|
||||
m_dim.x + baseWidth,
|
||||
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
|
||||
m_dim.x + baseWidth,
|
||||
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
|
||||
plotCount++;
|
||||
}
|
||||
}
|
||||
@@ -1612,7 +1618,8 @@ EVT_MENU( mpID_ZOOM_OUT, mpWindow::OnZoomOut )
|
||||
EVT_MENU( mpID_LOCKASPECT, mpWindow::OnLockAspect )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
mpWindow::mpWindow() : wxWindow(),
|
||||
mpWindow::mpWindow() :
|
||||
wxWindow(),
|
||||
m_lockaspect( false ),
|
||||
m_minX( 0.0 ),
|
||||
m_maxX( 0.0 ),
|
||||
@@ -2826,7 +2833,8 @@ void mpWindow::SetColourTheme( const wxColour& bgColour, const wxColour& drawCol
|
||||
IMPLEMENT_DYNAMIC_CLASS( mpFXYVector, mpFXY )
|
||||
|
||||
// Constructor
|
||||
mpFXYVector::mpFXYVector( const wxString& name, int flags ) : mpFXY( name, flags )
|
||||
mpFXYVector::mpFXYVector( const wxString& name, int flags ) :
|
||||
mpFXY( name, flags )
|
||||
{
|
||||
m_index = 0;
|
||||
m_minX = -1;
|
||||
@@ -3030,7 +3038,8 @@ void mpText::Plot( wxDC& dc, mpWindow& w )
|
||||
// mpPrintout - provided by Davide Rondini
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) : wxPrintout( title )
|
||||
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) :
|
||||
wxPrintout( title )
|
||||
{
|
||||
drawn = false;
|
||||
plotWindow = drawWindow;
|
||||
|
||||
@@ -205,7 +205,7 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
// Find a set of properties that is common to all selected items
|
||||
for( PROPERTY_BASE* property : commonProps )
|
||||
{
|
||||
if( property->IsInternal() )
|
||||
if( property->IsHiddenFromPropertiesManager() )
|
||||
continue;
|
||||
|
||||
if( propMgr.IsAvailableFor( TYPE_HASH( *firstItem ), property, firstItem ) )
|
||||
|
||||
@@ -33,6 +33,7 @@ SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( SEARCH_HANDLER* handler, wxWindow* p
|
||||
RefreshColumnNames();
|
||||
|
||||
Bind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Bind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
|
||||
Bind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Bind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
|
||||
}
|
||||
@@ -41,6 +42,7 @@ SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( SEARCH_HANDLER* handler, wxWindow* p
|
||||
SEARCH_PANE_LISTVIEW::~SEARCH_PANE_LISTVIEW()
|
||||
{
|
||||
Unbind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Unbind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
|
||||
Unbind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Unbind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
|
||||
}
|
||||
@@ -65,10 +67,27 @@ void SEARCH_PANE_LISTVIEW::GetSelectRowsList( std::vector<long>& aSelectedList )
|
||||
}
|
||||
|
||||
|
||||
void SEARCH_PANE_LISTVIEW::OnItemActivated( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[=]()
|
||||
{
|
||||
m_handler->ActivateItem( aEvent.GetIndex() );
|
||||
|
||||
// Reset our selection to match the selected list items
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
m_handler->SelectItems( list );
|
||||
} );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[&]()
|
||||
[=]()
|
||||
{
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
@@ -82,7 +101,7 @@ void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
|
||||
void SEARCH_PANE_LISTVIEW::OnItemDeselected( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[&]()
|
||||
[=]()
|
||||
{
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
@@ -153,4 +172,4 @@ void SEARCH_PANE_TAB::Clear()
|
||||
void SEARCH_PANE_TAB::RefreshColumnNames()
|
||||
{
|
||||
m_listView->RefreshColumnNames();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent, wxStaticText* aLabel, wxWindo
|
||||
UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource,
|
||||
wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
|
||||
bool aAllowEval, bool aBindFocusEvent ) :
|
||||
m_eventSource( aEventSource ),
|
||||
m_bindFocusEvent( aBindFocusEvent ),
|
||||
m_label( aLabel ),
|
||||
m_valueCtrl( aValueCtrl ),
|
||||
@@ -99,10 +98,10 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
|
||||
this );
|
||||
}
|
||||
|
||||
if( m_eventSource )
|
||||
if( aEventSource )
|
||||
{
|
||||
m_eventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
aEventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,12 +114,6 @@ UNIT_BINDER::~UNIT_BINDER()
|
||||
this );
|
||||
}
|
||||
|
||||
if( m_eventSource )
|
||||
{
|
||||
m_eventSource->Disconnect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
}
|
||||
|
||||
if( m_valueCtrl )
|
||||
{
|
||||
m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
|
||||
@@ -368,7 +361,7 @@ void UNIT_BINDER::SetDoubleValue( double aValue )
|
||||
setPrecision( displayValue, false ),
|
||||
false, m_dataType );
|
||||
|
||||
if( displayValue == 0 && m_negativeZero )
|
||||
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
|
||||
SetValue( wxT( "-" ) + textValue );
|
||||
else
|
||||
SetValue( textValue );
|
||||
@@ -395,7 +388,7 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
|
||||
|
||||
value += EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
|
||||
}
|
||||
|
||||
|
||||
if( textEntry )
|
||||
textEntry->SetValue( value );
|
||||
else if( staticText )
|
||||
@@ -431,7 +424,7 @@ void UNIT_BINDER::ChangeDoubleValue( double aValue )
|
||||
setPrecision( displayValue, false ),
|
||||
false, m_dataType );
|
||||
|
||||
if( displayValue == 0 && m_negativeZero )
|
||||
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
|
||||
ChangeValue( wxT( "-" ) + textValue );
|
||||
else
|
||||
ChangeValue( textValue );
|
||||
|
||||
@@ -273,7 +273,7 @@ void WX_GRID::DestroyTable( wxGridTableBase* aTable )
|
||||
}
|
||||
|
||||
|
||||
wxString WX_GRID::GetShownColumns()
|
||||
wxString WX_GRID::GetShownColumnsAsString()
|
||||
{
|
||||
wxString shownColumns;
|
||||
|
||||
@@ -292,6 +292,17 @@ wxString WX_GRID::GetShownColumns()
|
||||
}
|
||||
|
||||
|
||||
std::bitset<64> WX_GRID::GetShownColumns()
|
||||
{
|
||||
std::bitset<64> shownColumns;
|
||||
|
||||
for( int ii = 0; ii < GetNumberCols(); ++ii )
|
||||
shownColumns[ii] = IsColShown( ii );
|
||||
|
||||
return shownColumns;
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::ShowHideColumns( const wxString& shownColumns )
|
||||
{
|
||||
for( int i = 0; i < GetNumberCols(); ++i )
|
||||
@@ -310,6 +321,18 @@ void WX_GRID::ShowHideColumns( const wxString& shownColumns )
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::ShowHideColumns( const std::bitset<64>& aShownColumns )
|
||||
{
|
||||
for( int ii = 0; ii < GetNumberCols(); ++ ii )
|
||||
{
|
||||
if( aShownColumns[ii] )
|
||||
ShowCol( ii );
|
||||
else
|
||||
HideCol( ii );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::DrawCornerLabel( wxDC& dc )
|
||||
{
|
||||
if( m_nativeColumnLabels )
|
||||
@@ -420,6 +443,34 @@ void WX_GRID::DrawRowLabel( wxDC& dc, int row )
|
||||
}
|
||||
|
||||
|
||||
bool WX_GRID::CancelPendingChanges()
|
||||
{
|
||||
if( !IsCellEditControlEnabled() )
|
||||
return true;
|
||||
|
||||
HideCellEditControl();
|
||||
|
||||
// do it after HideCellEditControl()
|
||||
m_cellEditCtrlEnabled = false;
|
||||
|
||||
int row = m_currentCellCoords.GetRow();
|
||||
int col = m_currentCellCoords.GetCol();
|
||||
|
||||
wxString oldval = GetCellValue( row, col );
|
||||
wxString newval;
|
||||
|
||||
wxGridCellAttr* attr = GetCellAttr( row, col );
|
||||
wxGridCellEditor* editor = attr->GetEditor( this, row, col );
|
||||
|
||||
bool changed = editor->EndEdit( row, col, this, oldval, &newval );
|
||||
|
||||
editor->DecRef();
|
||||
attr->DecRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WX_GRID::CommitPendingChanges( bool aQuietMode )
|
||||
{
|
||||
if( !IsCellEditControlEnabled() )
|
||||
|
||||
@@ -63,7 +63,7 @@ WX_INFOBAR::WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr, wxWindowID aWinid
|
||||
|
||||
// Infobar is broken on Mac without the effects
|
||||
SetShowHideEffects( wxSHOW_EFFECT_ROLL_TO_BOTTOM, wxSHOW_EFFECT_ROLL_TO_TOP );
|
||||
SetEffectDuration( 300 );
|
||||
SetEffectDuration( 200 );
|
||||
#else
|
||||
// Infobar freezes canvas on Windows with the effect, and GTK looks bad with it
|
||||
SetShowHideEffects( wxSHOW_EFFECT_NONE, wxSHOW_EFFECT_NONE );
|
||||
|
||||
@@ -463,15 +463,12 @@ target_link_libraries( eeschema_kiface_objects
|
||||
# declare the dependency
|
||||
add_dependencies( eeschema_kiface_objects common )
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in eeschema" )
|
||||
add_subdirectory( ./navlib )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in eeschema" )
|
||||
add_subdirectory( navlib )
|
||||
|
||||
target_link_libraries( eeschema_kiface_objects PUBLIC eeschema_navlib)
|
||||
|
||||
add_dependencies( eeschema_kiface_objects eeschema_navlib )
|
||||
endif()
|
||||
target_link_libraries( eeschema_kiface_objects PUBLIC eeschema_navlib)
|
||||
|
||||
add_dependencies( eeschema_kiface_objects eeschema_navlib )
|
||||
|
||||
add_library( eeschema_kiface MODULE
|
||||
eeschema.cpp
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023 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
|
||||
@@ -376,7 +376,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
if( symbol->GetUnitCount() > 1 )
|
||||
{
|
||||
msg.Printf( _( "Updated %s (unit %s) from %s to %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
|
||||
prevRef,
|
||||
newRef );
|
||||
@@ -384,7 +384,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Updated %s from %s to %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
prevRef,
|
||||
newRef );
|
||||
}
|
||||
@@ -394,14 +394,14 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
if( symbol->GetUnitCount() > 1 )
|
||||
{
|
||||
msg.Printf( _( "Annotated %s (unit %s) as %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
|
||||
newRef );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Annotated %s as %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
newRef );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,10 +65,10 @@
|
||||
#include <eeschema_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
|
||||
#define FIELD_PADDING schIUScale.MilsToIU( 10 ) // arbitrarily chosen for aesthetics
|
||||
#define FIELD_PADDING schIUScale.MilsToIU( 15 ) // arbitrarily chosen for aesthetics
|
||||
#define WIRE_V_SPACING schIUScale.MilsToIU( 100 )
|
||||
#define HPADDING schIUScale.MilsToIU( 25 )
|
||||
#define VPADDING schIUScale.MilsToIU( 25 )
|
||||
#define HPADDING schIUScale.MilsToIU( 25 ) // arbitrarily chosen for aesthetics
|
||||
#define VPADDING schIUScale.MilsToIU( 15 ) // arbitrarily chosen for aesthetics
|
||||
|
||||
/**
|
||||
* Round up/down to the nearest multiple of n
|
||||
@@ -219,10 +219,6 @@ protected:
|
||||
|
||||
max_field_width = std::max( max_field_width, field_width );
|
||||
|
||||
// Remove interline spacing from field_height for last line.
|
||||
if( field == visibleFields.back() )
|
||||
field_height *= 0.62;
|
||||
|
||||
if( !aDynamic )
|
||||
total_height += WIRE_V_SPACING;
|
||||
else if( m_align_to_grid )
|
||||
|
||||
+418
-69
@@ -195,7 +195,7 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
m_driver_connection->SetDriver( m_driver );
|
||||
m_driver_connection->ClearDirty();
|
||||
}
|
||||
else
|
||||
else if( !m_is_bus_member )
|
||||
{
|
||||
m_driver_connection = nullptr;
|
||||
}
|
||||
@@ -228,6 +228,24 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_SUBGRAPH::getAllConnectedItems( std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>>& aItems, std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
|
||||
{
|
||||
CONNECTION_SUBGRAPH* sg = this;
|
||||
|
||||
while( sg->m_absorbed_by )
|
||||
sg = sg->m_absorbed_by;
|
||||
|
||||
aSubgraphs.insert( sg );
|
||||
aSubgraphs.insert( sg->m_absorbed_subgraphs.begin(), sg->m_absorbed_subgraphs.end() );
|
||||
|
||||
for( SCH_ITEM* item : sg->m_items )
|
||||
aItems.emplace( m_sheet, item );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* child_sg : sg->m_hier_children )
|
||||
child_sg->getAllConnectedItems( aItems, aSubgraphs );
|
||||
}
|
||||
|
||||
|
||||
wxString CONNECTION_SUBGRAPH::GetNetName() const
|
||||
{
|
||||
if( !m_driver || m_dirty )
|
||||
@@ -246,7 +264,36 @@ wxString CONNECTION_SUBGRAPH::GetNetName() const
|
||||
}
|
||||
|
||||
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetBusLabels() const
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetAllBusLabels() const
|
||||
{
|
||||
std::vector<SCH_ITEM*> labels;
|
||||
|
||||
for( SCH_ITEM* item : m_drivers )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
{
|
||||
CONNECTION_TYPE type = item->Connection( &m_sheet )->Type();
|
||||
|
||||
// Only consider bus vectors
|
||||
if( type == CONNECTION_TYPE::BUS || type == CONNECTION_TYPE::BUS_GROUP )
|
||||
labels.push_back( item );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetVectorBusLabels() const
|
||||
{
|
||||
std::vector<SCH_ITEM*> labels;
|
||||
|
||||
@@ -284,17 +331,19 @@ wxString CONNECTION_SUBGRAPH::driverName( SCH_ITEM* aItem ) const
|
||||
bool forceNoConnect = m_no_connect != nullptr;
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
|
||||
return pin->GetDefaultNetName( m_sheet, forceNoConnect );
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText( &m_sheet, false ),
|
||||
CTX_NETNAME );
|
||||
|
||||
case SCH_SHEET_PIN_T:
|
||||
{
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText(), CTX_NETNAME );
|
||||
break;
|
||||
}
|
||||
// Sheet pins need to use their parent sheet as their starting sheet or they will
|
||||
// resolve variables on the current sheet first
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText( nullptr, false ),
|
||||
CTX_NETNAME );
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxS( "Unhandled item type in GetNameForDriver" ) );
|
||||
@@ -348,16 +397,30 @@ void CONNECTION_SUBGRAPH::Absorb( CONNECTION_SUBGRAPH* aOther )
|
||||
AddItem( item );
|
||||
}
|
||||
|
||||
m_absorbed_subgraphs.insert( aOther );
|
||||
m_absorbed_subgraphs.insert( aOther->m_absorbed_subgraphs.begin(),
|
||||
aOther->m_absorbed_subgraphs.end() );
|
||||
|
||||
m_bus_neighbors.insert( aOther->m_bus_neighbors.begin(), aOther->m_bus_neighbors.end() );
|
||||
m_bus_parents.insert( aOther->m_bus_parents.begin(), aOther->m_bus_parents.end() );
|
||||
|
||||
m_multiple_drivers |= aOther->m_multiple_drivers;
|
||||
|
||||
std::function<void( CONNECTION_SUBGRAPH* )> set_absorbed_by =
|
||||
[ & ]( CONNECTION_SUBGRAPH *child )
|
||||
{
|
||||
child->m_absorbed_by = this;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subchild : child->m_absorbed_subgraphs )
|
||||
set_absorbed_by( subchild );
|
||||
};
|
||||
|
||||
aOther->m_absorbed = true;
|
||||
aOther->m_dirty = false;
|
||||
aOther->m_driver = nullptr;
|
||||
aOther->m_driver_connection = nullptr;
|
||||
aOther->m_absorbed_by = this;
|
||||
|
||||
set_absorbed_by( aOther );
|
||||
}
|
||||
|
||||
|
||||
@@ -416,9 +479,12 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
SCH_PIN* sch_pin = static_cast<SCH_PIN*>( aDriver );
|
||||
SCH_SYMBOL* sym = sch_pin->GetParentSymbol();
|
||||
|
||||
if( sch_pin->IsPowerConnection() )
|
||||
return PRIORITY::POWER_PIN;
|
||||
else if( !sym || !sym->GetIncludeOnBoard() || sym->GetLibSymbolRef()->GetReferenceField().GetText().StartsWith( '#' ) )
|
||||
return PRIORITY::NONE;
|
||||
else
|
||||
return PRIORITY::PIN;
|
||||
}
|
||||
@@ -428,10 +494,66 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
{
|
||||
std::copy( aGraph.m_items.begin(), aGraph.m_items.end(),
|
||||
std::back_inserter( m_items ) );
|
||||
|
||||
for( SCH_ITEM* item : aGraph.m_items )
|
||||
item->SetConnectionGraph( this );
|
||||
|
||||
std::copy( aGraph.m_subgraphs.begin(), aGraph.m_subgraphs.end(),
|
||||
std::back_inserter( m_subgraphs ) );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aGraph.m_subgraphs )
|
||||
sg->m_graph = this;
|
||||
|
||||
std::copy( aGraph.m_driver_subgraphs.begin(),
|
||||
aGraph.m_driver_subgraphs.end(),
|
||||
std::back_inserter( m_driver_subgraphs ) );
|
||||
|
||||
std::copy( aGraph.m_invisible_power_pins.begin(),
|
||||
aGraph.m_invisible_power_pins.end(),
|
||||
std::back_inserter( m_invisible_power_pins ) );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_name_to_subgraphs_map )
|
||||
m_net_name_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_sheet_to_subgraphs_map )
|
||||
m_sheet_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_name_to_code_map )
|
||||
m_net_name_to_code_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_bus_name_to_code_map )
|
||||
m_bus_name_to_code_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_code_to_subgraphs_map )
|
||||
m_net_code_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_item_to_subgraph_map )
|
||||
m_item_to_subgraph_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_local_label_cache )
|
||||
m_local_label_cache.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_global_label_cache )
|
||||
m_global_label_cache.insert_or_assign( key, value );
|
||||
|
||||
m_last_bus_code = std::max( m_last_bus_code, aGraph.m_last_bus_code );
|
||||
m_last_net_code = std::max( m_last_net_code, aGraph.m_last_net_code );
|
||||
m_last_subgraph_code = std::max( m_last_subgraph_code, aGraph.m_last_subgraph_code );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::Reset()
|
||||
{
|
||||
for( auto& subgraph : m_subgraphs )
|
||||
delete subgraph;
|
||||
{
|
||||
/// Only delete subgraphs of which we are the owner
|
||||
if( subgraph->m_graph == this )
|
||||
delete subgraph;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
m_subgraphs.clear();
|
||||
@@ -523,6 +645,209 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
recalc_time.Show();
|
||||
}
|
||||
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffectedItems(
|
||||
const std::set<SCH_ITEM*> &aItems )
|
||||
{
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> retvals;
|
||||
std::set<CONNECTION_SUBGRAPH*> subgraphs;
|
||||
|
||||
auto traverse_subgraph = [&retvals, &subgraphs]( CONNECTION_SUBGRAPH* aSubgraph )
|
||||
{
|
||||
// Find the primary subgraph on this sheet
|
||||
while( aSubgraph->m_absorbed_by )
|
||||
aSubgraph = aSubgraph->m_absorbed_by;
|
||||
|
||||
// Find the top most connected subgraph on all sheets
|
||||
while( aSubgraph->m_hier_parent )
|
||||
aSubgraph = aSubgraph->m_hier_parent;
|
||||
|
||||
// Recurse through all subsheets to collect connected items
|
||||
aSubgraph->getAllConnectedItems( retvals, subgraphs );
|
||||
};
|
||||
|
||||
for( SCH_ITEM* item : aItems )
|
||||
{
|
||||
auto it = m_item_to_subgraph_map.find( item );
|
||||
|
||||
if( it == m_item_to_subgraph_map.end() )
|
||||
continue;
|
||||
|
||||
CONNECTION_SUBGRAPH* sg = it->second;
|
||||
|
||||
traverse_subgraph( sg );
|
||||
|
||||
for( auto& bus_it : sg->m_bus_neighbors )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
|
||||
traverse_subgraph( bus_sg );
|
||||
}
|
||||
|
||||
for( auto& bus_it : sg->m_bus_parents )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
|
||||
traverse_subgraph( bus_sg );
|
||||
}
|
||||
|
||||
alg::delete_matching( m_items, item );
|
||||
}
|
||||
|
||||
removeSubgraphs( subgraphs );
|
||||
|
||||
return retvals;
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
|
||||
{
|
||||
std::sort( m_driver_subgraphs.begin(), m_driver_subgraphs.end() );
|
||||
std::sort( m_subgraphs.begin(), m_subgraphs.end() );
|
||||
std::set<int> codes_to_remove;
|
||||
|
||||
for( auto el : m_sheet_to_subgraphs_map )
|
||||
{
|
||||
std::sort( el.second.begin(), el.second.end() );
|
||||
}
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
|
||||
{
|
||||
for( auto it : sg->m_bus_neighbors )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* neighbor : it.second )
|
||||
{
|
||||
auto& parents = neighbor->m_bus_parents[it.first];
|
||||
|
||||
for( auto test = parents.begin(); test != parents.end(); )
|
||||
{
|
||||
if( *test == sg )
|
||||
test = parents.erase( test );
|
||||
else
|
||||
++test;
|
||||
}
|
||||
|
||||
if( parents.empty() )
|
||||
neighbor->m_bus_parents.erase( it.first );
|
||||
}
|
||||
}
|
||||
|
||||
for( auto it : sg->m_bus_parents )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* parent : it.second )
|
||||
{
|
||||
auto& neighbors = parent->m_bus_neighbors[it.first];
|
||||
|
||||
for( auto test = neighbors.begin(); test != neighbors.end(); )
|
||||
{
|
||||
if( *test == sg )
|
||||
test = neighbors.erase( test );
|
||||
else
|
||||
++test;
|
||||
}
|
||||
|
||||
if( neighbors.empty() )
|
||||
parent->m_bus_neighbors.erase( it.first );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::lower_bound( m_driver_subgraphs.begin(), m_driver_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_driver_subgraphs.end() )
|
||||
m_driver_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::lower_bound( m_subgraphs.begin(), m_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_subgraphs.end() )
|
||||
m_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
for( auto el : m_sheet_to_subgraphs_map )
|
||||
{
|
||||
auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
|
||||
|
||||
if( it != el.second.end() )
|
||||
el.second.erase( it );
|
||||
}
|
||||
|
||||
auto remove_sg = [sg]( auto it ) -> bool
|
||||
{
|
||||
for( const CONNECTION_SUBGRAPH* test_sg : it->second )
|
||||
{
|
||||
if( sg == test_sg )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
for( auto it = m_global_label_cache.begin(); it != m_global_label_cache.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_global_label_cache.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_local_label_cache.begin(); it != m_local_label_cache.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_local_label_cache.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_net_code_to_subgraphs_map.begin(); it != m_net_code_to_subgraphs_map.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
{
|
||||
codes_to_remove.insert( it->first.Netcode );
|
||||
it = m_net_code_to_subgraphs_map.erase( it );
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_net_name_to_subgraphs_map.begin(); it != m_net_name_to_subgraphs_map.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_net_name_to_subgraphs_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_item_to_subgraph_map.begin(); it != m_item_to_subgraph_map.end(); )
|
||||
{
|
||||
if( it->second == sg )
|
||||
it = m_item_to_subgraph_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
for( auto it = m_net_name_to_code_map.begin(); it != m_net_name_to_code_map.end(); )
|
||||
{
|
||||
if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
|
||||
it = m_net_name_to_code_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_bus_name_to_code_map.begin(); it != m_bus_name_to_code_map.end(); )
|
||||
{
|
||||
if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
|
||||
it = m_bus_name_to_code_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
|
||||
{
|
||||
sg->m_code = -1;
|
||||
delete sg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
const std::vector<SCH_ITEM*>& aItemList )
|
||||
@@ -971,6 +1296,58 @@ void CONNECTION_GRAPH::collectAllDriverValues()
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::generateBusAliasMembers()
|
||||
{
|
||||
std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
|
||||
|
||||
SCH_CONNECTION dummy( this );
|
||||
|
||||
for( auto&& subgraph : m_driver_subgraphs )
|
||||
{
|
||||
auto vec = subgraph->GetAllBusLabels();
|
||||
|
||||
for( auto& item : vec )
|
||||
{
|
||||
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
|
||||
|
||||
dummy.ConfigureFromLabel( label->GetText() );
|
||||
|
||||
wxLogTrace( ConnTrace, wxS( "new bus label (%s)" ), label->GetText() );
|
||||
|
||||
for( auto& conn : dummy.Members() )
|
||||
{
|
||||
wxString name = conn->FullLocalName();
|
||||
|
||||
CONNECTION_SUBGRAPH* new_sg = new CONNECTION_SUBGRAPH( this );
|
||||
SCH_CONNECTION* new_conn = new SCH_CONNECTION( this );
|
||||
|
||||
new_conn->SetName( name );
|
||||
new_conn->SetType( CONNECTION_TYPE::NET );
|
||||
int code = assignNewNetCode( *new_conn );
|
||||
|
||||
wxLogTrace( ConnTrace, wxS( "SG(%ld), Adding full local name (%s) with sg (%d)" ), subgraph->m_code,
|
||||
name, code );
|
||||
|
||||
new_sg->m_driver_connection = new_conn;
|
||||
new_sg->m_code = m_last_subgraph_code++;
|
||||
new_sg->m_sheet = subgraph->m_sheet;
|
||||
new_sg->m_is_bus_member = true;
|
||||
new_sg->m_strong_driver = true;
|
||||
/// Need to figure out why these sgs are not getting connected to their bus parents
|
||||
|
||||
NET_NAME_CODE_CACHE_KEY key = { new_sg->GetNetName(), code };
|
||||
m_net_code_to_subgraphs_map[ key ].push_back( new_sg );
|
||||
m_net_name_to_subgraphs_map[ name ].push_back( new_sg );
|
||||
m_subgraphs.push_back( new_sg );
|
||||
new_subgraphs.push_back( new_sg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::copy( new_subgraphs.begin(), new_subgraphs.end(), std::back_inserter( m_driver_subgraphs ) );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::generateInvisiblePinSubGraphs()
|
||||
{
|
||||
// Generate subgraphs for invisible power pins. These will be merged with other subgraphs
|
||||
@@ -1115,7 +1492,7 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
|
||||
name = new_name;
|
||||
}
|
||||
else
|
||||
else if( subgraph->m_driver )
|
||||
{
|
||||
// If there is no conflict, promote sheet pins to be strong drivers so that they
|
||||
// will be considered below for propagation/merging.
|
||||
@@ -1274,7 +1651,7 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : candidate_subgraphs )
|
||||
{
|
||||
if( candidate->m_absorbed )
|
||||
if( candidate->m_absorbed || candidate == subgraph )
|
||||
continue;
|
||||
|
||||
bool match = false;
|
||||
@@ -1355,7 +1732,8 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
if( subgraph->m_absorbed )
|
||||
continue;
|
||||
|
||||
subgraph->ResolveDrivers();
|
||||
if( !subgraph->ResolveDrivers() )
|
||||
continue;
|
||||
|
||||
if( subgraph->m_driver_connection->IsBus() )
|
||||
assignNetCodesToBus( subgraph->m_driver_connection );
|
||||
@@ -1412,6 +1790,8 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
|
||||
generateInvisiblePinSubGraphs();
|
||||
|
||||
generateBusAliasMembers();
|
||||
|
||||
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
|
||||
processSubGraphs();
|
||||
|
||||
@@ -1498,6 +1878,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
conn->Clone( *subgraph->m_driver_connection );
|
||||
|
||||
candidate->m_dirty = false;
|
||||
propagateToNeighbors( candidate, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1610,7 +1991,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
// As a visual aid, we can check sheet pins that are driven by themselves to see
|
||||
// if they should be promoted to buses
|
||||
|
||||
if( subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
|
||||
if( subgraph->m_driver && subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
|
||||
{
|
||||
SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( subgraph->m_driver );
|
||||
|
||||
@@ -1689,6 +2070,8 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
const CONNECTION_SUBGRAPH* driverSubgraph = nullptr;
|
||||
wxString netclass;
|
||||
|
||||
wxCHECK_RET( !subgraphs.empty(), wxT("Invalid empty subgraph" ) );
|
||||
|
||||
for( const CONNECTION_SUBGRAPH* subgraph : subgraphs )
|
||||
{
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
@@ -1699,7 +2082,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
break;
|
||||
}
|
||||
|
||||
if( !netclass.IsEmpty() || !driverSubgraph )
|
||||
if( !netclass.IsEmpty() )
|
||||
{
|
||||
driverSubgraph = subgraph;
|
||||
break;
|
||||
@@ -1709,6 +2092,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
if( netclass.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( !driverSubgraph )
|
||||
driverSubgraph = subgraphs.front();
|
||||
|
||||
const wxString netname = driverSubgraph->GetNetName();
|
||||
|
||||
if( driverSubgraph->m_driver_connection->IsBus() )
|
||||
@@ -1735,22 +2121,30 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
|
||||
|
||||
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
int CONNECTION_GRAPH::getOrCreateNetCode( const wxString& aNetName )
|
||||
{
|
||||
int code;
|
||||
|
||||
auto it = m_net_name_to_code_map.find( aConnection.Name() );
|
||||
auto it = m_net_name_to_code_map.find( aNetName );
|
||||
|
||||
if( it == m_net_name_to_code_map.end() )
|
||||
{
|
||||
code = m_last_net_code++;
|
||||
m_net_name_to_code_map[ aConnection.Name() ] = code;
|
||||
m_net_name_to_code_map[ aNetName ] = code;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = it->second;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
{
|
||||
int code = getOrCreateNetCode( aConnection.Name() );
|
||||
|
||||
aConnection.SetNetCode( code );
|
||||
|
||||
return code;
|
||||
@@ -1759,7 +2153,7 @@ int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
|
||||
void CONNECTION_GRAPH::assignNetCodesToBus( SCH_CONNECTION* aConnection )
|
||||
{
|
||||
std::vector< std::shared_ptr<SCH_CONNECTION>>& connections_to_check( aConnection->Members() );
|
||||
std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->Members() );
|
||||
|
||||
for( unsigned i = 0; i < connections_to_check.size(); i++ )
|
||||
{
|
||||
@@ -1815,6 +2209,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
candidate->m_code, candidate->m_driver_connection->Name() );
|
||||
|
||||
candidate->m_hier_parent = aParent;
|
||||
aParent->m_hier_children.insert( candidate );
|
||||
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
@@ -1822,53 +2217,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( SCH_HIERLABEL* label : aParent->m_hier_ports )
|
||||
{
|
||||
SCH_SHEET_PATH path = aParent->m_sheet;
|
||||
path.pop_back();
|
||||
|
||||
auto it = m_sheet_to_subgraphs_map.find( path );
|
||||
|
||||
if( it == m_sheet_to_subgraphs_map.end() )
|
||||
continue;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : it->second )
|
||||
{
|
||||
if( candidate->m_hier_pins.empty()
|
||||
|| visited.count( candidate )
|
||||
|| candidate->m_driver_connection->Type() != aParent->m_driver_connection->Type() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
|
||||
|
||||
for( SCH_SHEET_PIN* pin : candidate->m_hier_pins )
|
||||
{
|
||||
// If the last sheet UUIDs won't match, no need to check the full path
|
||||
if( pin->GetParent()->m_Uuid != last_parent_uuid )
|
||||
continue;
|
||||
|
||||
SCH_SHEET_PATH pin_path = path;
|
||||
pin_path.push_back( pin->GetParent() );
|
||||
|
||||
if( pin_path != aParent->m_sheet )
|
||||
continue;
|
||||
|
||||
if( aParent->GetNameForDriver( label ) == candidate->GetNameForDriver( pin ) )
|
||||
{
|
||||
wxLogTrace( ConnTrace, wxS( "%lu: found additional parent %lu (%s)" ),
|
||||
aParent->m_code, candidate->m_code,
|
||||
candidate->m_driver_connection->Name() );
|
||||
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph ) {
|
||||
for( const auto& kv : aParentGraph->m_bus_neighbors )
|
||||
@@ -2230,16 +2579,16 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
|
||||
if( !connection->IsBus() )
|
||||
continue;
|
||||
|
||||
auto labels = subgraph->GetBusLabels();
|
||||
auto labels = subgraph->GetVectorBusLabels();
|
||||
|
||||
if( labels.size() > 1 )
|
||||
{
|
||||
bool different = false;
|
||||
wxString first = static_cast<SCH_TEXT*>( labels.at( 0 ) )->GetShownText();
|
||||
wxString first = static_cast<SCH_TEXT*>( labels.at( 0 ) )->GetShownText( false );
|
||||
|
||||
for( unsigned i = 1; i < labels.size(); ++i )
|
||||
{
|
||||
if( static_cast<SCH_TEXT*>( labels.at( i ) )->GetShownText() != first )
|
||||
if( static_cast<SCH_TEXT*>( labels.at( i ) )->GetShownText( false ) != first )
|
||||
{
|
||||
different = true;
|
||||
break;
|
||||
@@ -2579,7 +2928,7 @@ bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSu
|
||||
case SCH_HIER_LABEL_T:
|
||||
{
|
||||
SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
|
||||
conn.ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
|
||||
conn.ConfigureFromLabel( EscapeString( text->GetShownText( false ), CTX_NETNAME ) );
|
||||
|
||||
if( conn.IsBus() )
|
||||
bus_item = ( !bus_item ) ? item : bus_item;
|
||||
|
||||
@@ -76,6 +76,7 @@ public:
|
||||
m_graph( aGraph ),
|
||||
m_dirty( false ),
|
||||
m_absorbed( false ),
|
||||
m_is_bus_member( false ),
|
||||
m_absorbed_by( nullptr ),
|
||||
m_code( -1 ),
|
||||
m_multiple_drivers( false ),
|
||||
@@ -108,8 +109,11 @@ public:
|
||||
*/
|
||||
wxString GetNetName() const;
|
||||
|
||||
/// Returns all the bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetBusLabels() const;
|
||||
/// Returns all the vector-based bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetVectorBusLabels() const;
|
||||
|
||||
/// Returns all the all bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetAllBusLabels() const;
|
||||
|
||||
/// Returns the candidate net name for a driver
|
||||
const wxString& GetNameForDriver( SCH_ITEM* aItem ) const;
|
||||
@@ -125,6 +129,15 @@ public:
|
||||
/// Updates all items to match the driver connection
|
||||
void UpdateItemConnections();
|
||||
|
||||
/// Provides a read-only reference to the items in the subgraph
|
||||
const std::vector<SCH_ITEM*>& GetItems() const
|
||||
{
|
||||
return m_items;
|
||||
}
|
||||
|
||||
/// Finds all items in the subgraph as well as child subgraphs recursively
|
||||
void getAllConnectedItems( std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>>& aItems, std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
|
||||
|
||||
/**
|
||||
* Return the priority (higher is more important) of a candidate driver
|
||||
*
|
||||
@@ -160,9 +173,18 @@ public:
|
||||
/// True if this subgraph has been absorbed into another. No pointers here are safe if so!
|
||||
bool m_absorbed;
|
||||
|
||||
/**
|
||||
* True if the subgraph is not actually part of a net. These are created for bus members
|
||||
* to ensure that bus-to-bus connection happens but they don't have any valid data
|
||||
*/
|
||||
bool m_is_bus_member;
|
||||
|
||||
/// If this subgraph is absorbed, points to the absorbing (and valid) subgraph
|
||||
CONNECTION_SUBGRAPH* m_absorbed_by;
|
||||
|
||||
/// Set of subgraphs that have been absorbed by this subgraph
|
||||
std::set<CONNECTION_SUBGRAPH*> m_absorbed_subgraphs;
|
||||
|
||||
long m_code;
|
||||
|
||||
/**
|
||||
@@ -201,7 +223,7 @@ public:
|
||||
*
|
||||
* For example, if this subgraph is a bus D[7..0], and on the same sheet there is
|
||||
* a net with label D7, this map will contain an entry for the D7 bus member, and
|
||||
* the vector will contain a pointer to the D7 net subgraph.
|
||||
* the set will contain a pointer to the D7 net subgraph.
|
||||
*/
|
||||
std::unordered_map< std::shared_ptr<SCH_CONNECTION>,
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_neighbors;
|
||||
@@ -223,6 +245,9 @@ public:
|
||||
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
|
||||
CONNECTION_SUBGRAPH* m_hier_parent;
|
||||
|
||||
// If not null, this indicates the subgraph(s) on a lower level sheet that are linked to this one
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> m_hier_children;
|
||||
|
||||
/// A cache of escaped netnames from schematic items
|
||||
mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
|
||||
|
||||
@@ -289,6 +314,13 @@ public:
|
||||
m_schematic = aSchematic;
|
||||
}
|
||||
|
||||
void SetLastCodes( const CONNECTION_GRAPH* aOther )
|
||||
{
|
||||
m_last_net_code = aOther->m_last_net_code;
|
||||
m_last_bus_code = aOther->m_last_bus_code;
|
||||
m_last_subgraph_code = aOther->m_last_subgraph_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection graph for the given list of sheets.
|
||||
*
|
||||
@@ -353,6 +385,24 @@ public:
|
||||
*/
|
||||
wxString GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const;
|
||||
|
||||
/**
|
||||
* For a set of items, this will remove the connected items and their
|
||||
* associated data including subgraphs and generated codes from the connection graph.
|
||||
*
|
||||
* @param aItems A vector of items whose presence should be removed from the graph
|
||||
* @return The full set of all items associated with the input items that were removed
|
||||
*/
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> ExtractAffectedItems(
|
||||
const std::set<SCH_ITEM*> &aItems );
|
||||
|
||||
/**
|
||||
* Combines the input graph contents into the current graph. After merging, the
|
||||
* original graph is invalid.
|
||||
*
|
||||
* @param aGraph Input graph reference to add to the current graph
|
||||
*/
|
||||
void Merge( CONNECTION_GRAPH& aGraph );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Updates the graphical connectivity between items (i.e. where they touch)
|
||||
@@ -421,6 +471,11 @@ private:
|
||||
*/
|
||||
void generateInvisiblePinSubGraphs();
|
||||
|
||||
/**
|
||||
* Iterate through labels to create placeholders for bus elements
|
||||
*/
|
||||
void generateBusAliasMembers();
|
||||
|
||||
/**
|
||||
* Process all subgraphs to assign netcodes and merge subgraphs based on labels
|
||||
*/
|
||||
@@ -433,6 +488,13 @@ private:
|
||||
*/
|
||||
int assignNewNetCode( SCH_CONNECTION& aConnection );
|
||||
|
||||
/**
|
||||
*
|
||||
* @param aNetName string with the netname for coding
|
||||
* @return existing netcode (if it exists) or newly created one
|
||||
*/
|
||||
int getOrCreateNetCode( const wxString& aNetName );
|
||||
|
||||
/**
|
||||
* Ensures all members of the bus connection have a valid net code assigned
|
||||
* @param aConnection is a bus connection
|
||||
@@ -450,6 +512,14 @@ private:
|
||||
*/
|
||||
void propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, bool aForce );
|
||||
|
||||
/**
|
||||
* Removes references to the given subgraphs from all structures in the
|
||||
* connection graph.
|
||||
*
|
||||
* @param aSubgraphs set of unique subgraphs to find/remove
|
||||
*/
|
||||
void removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
|
||||
|
||||
/**
|
||||
* Search for a matching bus member inside a bus connection
|
||||
*
|
||||
|
||||
@@ -883,6 +883,9 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
return;
|
||||
}
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
|
||||
RecalculateConnections( GLOBAL_CLEANUP );
|
||||
|
||||
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
|
||||
if( projSettings.m_AnnotateStartNum != startNum )
|
||||
{
|
||||
projSettings.m_AnnotateStartNum = startNum;
|
||||
schFrame->SaveProjectSettings();
|
||||
schFrame->OnModify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBO
|
||||
|
||||
m_newId->ChangeValue( UnescapeString( m_symbol->GetLibId().Format() ) );
|
||||
m_specifiedReference->ChangeValue( m_symbol->GetRef( currentSheet ) );
|
||||
m_specifiedValue->ChangeValue( m_symbol->GetValueFieldText( false ) );
|
||||
m_specifiedValue->ChangeValue( UnescapeString( m_symbol->GetField( VALUE_FIELD )->GetText() ) );
|
||||
m_specifiedId->ChangeValue( UnescapeString( m_symbol->GetLibId().Format() ) );
|
||||
}
|
||||
else
|
||||
@@ -426,12 +426,14 @@ bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInsta
|
||||
else if( m_matchByReference->GetValue() )
|
||||
{
|
||||
return WildCompareString( m_specifiedReference->GetValue(),
|
||||
aSymbol->GetRef( aInstance, false ), false );
|
||||
UnescapeString( aSymbol->GetRef( aInstance, false ) ),
|
||||
false );
|
||||
}
|
||||
else if( m_matchByValue->GetValue() )
|
||||
{
|
||||
return WildCompareString( m_specifiedValue->GetValue(),
|
||||
aSymbol->GetValueFieldText( false ), false );
|
||||
UnescapeString( aSymbol->GetField( VALUE_FIELD )->GetText() ),
|
||||
false );
|
||||
}
|
||||
else if( m_matchById )
|
||||
{
|
||||
@@ -589,8 +591,10 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
|
||||
if( m_resetAttributes->GetValue() )
|
||||
{
|
||||
symbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
|
||||
symbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
|
||||
// Fetch the attributes from the *flattened* library symbol. They are not supported
|
||||
// in derived symbols.
|
||||
symbol->SetIncludeInBom( symbol->GetLibSymbolRef()->GetIncludeInBom() );
|
||||
symbol->SetIncludeOnBoard( symbol->GetLibSymbolRef()->GetIncludeOnBoard() );
|
||||
}
|
||||
|
||||
bool removeExtras = m_removeExtraBox->GetValue();
|
||||
@@ -609,9 +613,9 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
continue;
|
||||
|
||||
if( i < MANDATORY_FIELDS )
|
||||
libField = libSymbol->GetFieldById( (int) i );
|
||||
libField = symbol->GetLibSymbolRef()->GetFieldById( (int) i );
|
||||
else
|
||||
libField = libSymbol->FindField( field.GetName() );
|
||||
libField = symbol->GetLibSymbolRef()->FindField( field.GetName() );
|
||||
|
||||
if( libField )
|
||||
{
|
||||
@@ -670,7 +674,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
}
|
||||
|
||||
std::vector<LIB_FIELD*> libFields;
|
||||
libSymbol->GetFields( libFields );
|
||||
symbol->GetLibSymbolRef()->GetFields( libFields );
|
||||
|
||||
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <gestfich.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_edit_frame.h>
|
||||
@@ -460,9 +461,6 @@ void DIALOG_ERC::testErc()
|
||||
|
||||
SCHEMATIC* sch = &m_parent->Schematic();
|
||||
|
||||
// Build the whole sheet list in hierarchy (sheet, not screen)
|
||||
sch->GetSheets().AnnotatePowerSymbols();
|
||||
|
||||
SCH_SCREENS screens( sch->Root() );
|
||||
ERC_SETTINGS& settings = sch->ErcSettings();
|
||||
ERC_TESTER tester( sch );
|
||||
@@ -483,7 +481,13 @@ void DIALOG_ERC::testErc()
|
||||
|
||||
// The connection graph has a whole set of ERC checks it can run
|
||||
AdvancePhase( _( "Checking conflicts..." ) );
|
||||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
// If we are using the new connectivity, make sure that we do a full-rebuild
|
||||
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
|
||||
m_parent->RecalculateConnections( GLOBAL_CLEANUP );
|
||||
else
|
||||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
sch->ConnectionGraph()->RunERC();
|
||||
|
||||
AdvancePhase( _( "Checking units..." ) );
|
||||
|
||||
@@ -129,7 +129,7 @@ private:
|
||||
void InstallPageSpiceModel();
|
||||
|
||||
bool TransferDataFromWindow() override;
|
||||
void NetlistUpdateOpt();
|
||||
bool NetlistUpdateOpt();
|
||||
|
||||
void updateGeneratorButtons();
|
||||
|
||||
@@ -254,7 +254,7 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType)
|
||||
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType )
|
||||
page = nullptr;
|
||||
|
||||
// Add notebook pages:
|
||||
@@ -463,22 +463,35 @@ void DIALOG_EXPORT_NETLIST::OnNetlistTypeSelection( wxNotebookEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
|
||||
bool DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
|
||||
{
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
bool changed = false;
|
||||
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
|
||||
wxString spiceCmdString = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
|
||||
bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
|
||||
bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
wxString netFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spiceCmdString;
|
||||
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
|
||||
changed |= ( settings.m_SpiceSaveAllVoltages != saveAllVoltages );
|
||||
changed |= ( settings.m_SpiceSaveAllCurrents != saveAllCurrents );
|
||||
changed |= ( settings.m_SpiceCommandString != spiceCmdString );
|
||||
changed |= ( settings.m_SpiceCurSheetAsRoot != curSheetAsRoot );
|
||||
changed |= ( settings.m_SpiceModelCurSheetAsRoot != spiceModelCurSheetAsRoot );
|
||||
changed |= ( settings.m_NetFormatName != netFormatName );
|
||||
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spiceCmdString;
|
||||
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
|
||||
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
|
||||
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
settings.m_NetFormatName = netFormatName;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
@@ -489,7 +502,8 @@ bool DIALOG_EXPORT_NETLIST::TransferDataFromWindow()
|
||||
wxString fileExt;
|
||||
wxString title = _( "Save Netlist File" );
|
||||
|
||||
NetlistUpdateOpt();
|
||||
if( NetlistUpdateOpt() )
|
||||
m_Parent->OnModify();
|
||||
|
||||
EXPORT_NETLIST_PAGE* currPage;
|
||||
currPage = (EXPORT_NETLIST_PAGE*) m_NoteBook->GetCurrentPage();
|
||||
@@ -621,7 +635,8 @@ bool DIALOG_EXPORT_NETLIST::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt
|
||||
|
||||
void DIALOG_EXPORT_NETLIST::WriteCurrentNetlistSetup()
|
||||
{
|
||||
NetlistUpdateOpt();
|
||||
if( NetlistUpdateOpt() )
|
||||
m_Parent->OnModify();
|
||||
|
||||
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( cfg );
|
||||
@@ -798,7 +813,7 @@ int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller )
|
||||
DIALOG_EXPORT_NETLIST dlg( aCaller );
|
||||
|
||||
int ret = dlg.ShowModal();
|
||||
aCaller->SaveProjectSettings();
|
||||
aCaller->SaveProjectLocalSettings();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -79,7 +79,6 @@ DIALOG_IMAGE_PROPERTIES_BASE::DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wx
|
||||
|
||||
this->SetSizer( m_GeneralBoxSizer );
|
||||
this->Layout();
|
||||
m_GeneralBoxSizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
@@ -47,8 +48,8 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_IMAGE_PROPERTIES_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
||||
<property name="size">363,281</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
|
||||
<property name="title"></property>
|
||||
<property name="tooltip"></property>
|
||||
@@ -87,6 +88,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -143,6 +145,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -231,6 +234,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -292,6 +296,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -356,6 +361,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -417,6 +423,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -478,6 +485,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -542,6 +550,7 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -52,7 +52,7 @@ class DIALOG_IMAGE_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 363,281 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
~DIALOG_IMAGE_PROPERTIES_BASE();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
@@ -118,13 +118,10 @@ DIALOG_LABEL_PROPERTIES::DIALOG_LABEL_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_L
|
||||
m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
|
||||
// Show/hide columns according to user's preference
|
||||
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( cfg );
|
||||
|
||||
if( cfg )
|
||||
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
|
||||
{
|
||||
m_shownColumns = cfg->m_Appearance.edit_label_visible_columns;
|
||||
m_grid->ShowHideColumns( m_shownColumns );
|
||||
m_grid->ShowHideColumns( cfg->m_Appearance.edit_label_visible_columns );
|
||||
m_shownColumns = m_grid->GetShownColumns();
|
||||
}
|
||||
|
||||
// Configure button logos
|
||||
@@ -221,19 +218,19 @@ DIALOG_LABEL_PROPERTIES::DIALOG_LABEL_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_L
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
|
||||
if( cfg && cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
|
||||
SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
|
||||
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
|
||||
{
|
||||
if( cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
|
||||
SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DIALOG_LABEL_PROPERTIES::~DIALOG_LABEL_PROPERTIES()
|
||||
{
|
||||
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( cfg );
|
||||
|
||||
if( cfg )
|
||||
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
|
||||
{
|
||||
cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumns();
|
||||
cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumnsAsString();
|
||||
cfg->m_Appearance.edit_label_width = GetSize().x;
|
||||
cfg->m_Appearance.edit_label_height = GetSize().y;
|
||||
}
|
||||
@@ -286,7 +283,11 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataToWindow()
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_LOCATE_POWER_T ) )
|
||||
{
|
||||
const SCH_SYMBOL* power = static_cast<const SCH_SYMBOL*>( item );
|
||||
existingLabels.insert( UnescapeString( power->GetValueFieldText( false ) ) );
|
||||
|
||||
// Ensure the symbol has the Power (i.e. equivalent to a global label
|
||||
// before adding its value in list
|
||||
if( power->IsSymbolLikePowerGlobalLabel() )
|
||||
existingLabels.insert( UnescapeString( power->GetField( VALUE_FIELD )->GetText() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,6 +499,20 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
else
|
||||
doAutoplace = true;
|
||||
|
||||
for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
|
||||
{
|
||||
SCH_FIELD& field = m_fields->at( ii );
|
||||
const wxString& fieldName = field.GetCanonicalName();
|
||||
const wxString& fieldText = field.GetText();
|
||||
|
||||
if( fieldName.IsEmpty() && fieldText.IsEmpty() )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
else if( fieldName.IsEmpty() )
|
||||
field.SetName( _( "untitled" ) );
|
||||
}
|
||||
|
||||
m_currentLabel->SetFields( *m_fields );
|
||||
|
||||
if( m_shapeSizer->AreAnyItemsShown() )
|
||||
@@ -580,7 +595,6 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
|
||||
m_Parent->UpdateItem( m_currentLabel );
|
||||
m_Parent->GetCanvas()->Refresh();
|
||||
m_Parent->OnModify();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -758,7 +772,7 @@ void DIALOG_LABEL_PROPERTIES::AdjustGridColumns( int aWidth )
|
||||
|
||||
void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
{
|
||||
wxString shownColumns = m_grid->GetShownColumns();
|
||||
std::bitset<64> shownColumns = m_grid->GetShownColumns();
|
||||
|
||||
if( shownColumns != m_shownColumns )
|
||||
{
|
||||
|
||||
@@ -71,7 +71,7 @@ private:
|
||||
SCH_NETNAME_VALIDATOR m_netNameValidator;
|
||||
|
||||
FIELDS_GRID_TABLE<SCH_FIELD>* m_fields;
|
||||
wxString m_shownColumns;
|
||||
std::bitset<64> m_shownColumns;
|
||||
|
||||
UNIT_BINDER m_textSize;
|
||||
|
||||
|
||||
@@ -723,10 +723,11 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
|
||||
} ) );
|
||||
|
||||
// Show/hide columns according to the user's preference
|
||||
SYMBOL_EDITOR_SETTINGS* cfg = parent->GetSettings();
|
||||
m_columnsShown = cfg->m_PinTableVisibleColumns;
|
||||
|
||||
m_grid->ShowHideColumns( m_columnsShown );
|
||||
if( SYMBOL_EDITOR_SETTINGS* cfg = parent->GetSettings() )
|
||||
{
|
||||
m_grid->ShowHideColumns( cfg->m_PinTableVisibleColumns );
|
||||
m_columnsShown = m_grid->GetShownColumns();
|
||||
}
|
||||
|
||||
// Set special attributes
|
||||
wxGridCellAttr* attr;
|
||||
@@ -838,8 +839,8 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
|
||||
|
||||
DIALOG_LIB_EDIT_PIN_TABLE::~DIALOG_LIB_EDIT_PIN_TABLE()
|
||||
{
|
||||
SYMBOL_EDITOR_SETTINGS* cfg = m_editFrame->GetSettings();
|
||||
cfg->m_PinTableVisibleColumns = m_grid->GetShownColumns().ToStdString();
|
||||
if( SYMBOL_EDITOR_SETTINGS* cfg = m_editFrame->GetSettings() )
|
||||
cfg->m_PinTableVisibleColumns = m_grid->GetShownColumnsAsString();
|
||||
|
||||
// Disconnect Events
|
||||
m_grid->Disconnect( wxEVT_GRID_COL_SORT,
|
||||
@@ -1130,7 +1131,7 @@ void DIALOG_LIB_EDIT_PIN_TABLE::OnSize( wxSizeEvent& event )
|
||||
|
||||
void DIALOG_LIB_EDIT_PIN_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
{
|
||||
wxString columnsShown = m_grid->GetShownColumns();
|
||||
std::bitset<64> columnsShown = m_grid->GetShownColumns();
|
||||
|
||||
if( columnsShown != m_columnsShown )
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user