Compare commits
455 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61a17e4c8b | |||
| 67dda92437 | |||
| 4dfe564243 | |||
| 5b3c0028ea | |||
| 53d219e9d5 | |||
| a4da356ac7 | |||
| 2915a9d1a2 | |||
| 6778eb8352 | |||
| bdf8c04daf | |||
| a32ca5d0c4 | |||
| 992bee7ec9 | |||
| 7216527224 | |||
| 09bbabeef3 | |||
| 3ee74e2966 | |||
| 312356c284 | |||
| 6b9dba3d45 | |||
| 02c03ba2b6 | |||
| c35ba8f4cd | |||
| c344e170b9 | |||
| 5b5253b6e2 | |||
| 2954378f58 | |||
| eea71b9209 | |||
| 8eb98a2094 | |||
| 85d9feefff | |||
| c059cbce12 | |||
| a84aa449b2 | |||
| a4a2ec07c4 | |||
| d5557caa33 | |||
| 47717ca779 | |||
| d7f742f911 | |||
| 86ebc85404 | |||
| 5d4ed4b21a | |||
| 1ca0737c34 | |||
| 3a29fa44e3 | |||
| 3517d25aec | |||
| 8d62a5fd3f | |||
| 9e5876df5c | |||
| fdc3806ed1 | |||
| 798b827a12 | |||
| 4ade0ac73d | |||
| 65fd8d22ed | |||
| 481c1592ae | |||
| 9af12e60d2 | |||
| 048448296d | |||
| e03308e5ca | |||
| 16691c8d03 | |||
| dac0296e3a | |||
| 52ce4c0313 | |||
| 1956204635 | |||
| b4bd14ba10 | |||
| 8f7f6739c3 | |||
| 4eebd8ad6c | |||
| 4b3d67ffda | |||
| f3e3236a43 | |||
| 82ee4a81ed | |||
| 55fbdddbb7 | |||
| 7cce1901b2 | |||
| 0f4f1c0d3b | |||
| 78849ba5c0 | |||
| a066c57fcc | |||
| 8684c0f9be | |||
| db94f8c8ef | |||
| db0f7ec457 | |||
| 2bf4cca58a | |||
| 4470f4e6d8 | |||
| e516ab5114 | |||
| 0282b142b8 | |||
| 676108952e | |||
| 8470091a4b | |||
| 3302ef537f | |||
| 366f7aea6b | |||
| eed2221651 | |||
| 90093c0fdd | |||
| 2adccce3b8 | |||
| 6bf9653bef | |||
| 04c083ac48 | |||
| 9a236e5972 | |||
| 521e773f2c | |||
| e28aa6d16c | |||
| 001c90c69f | |||
| cba73e6cea | |||
| 5af4f3f9df | |||
| e1b922ae19 | |||
| f1d988788a | |||
| 8e6cb7b350 | |||
| 6685eefc8e | |||
| 8d231b8c96 | |||
| 313e09cfd3 | |||
| 5a05a1337e | |||
| a40929fa71 | |||
| 37eb5f4a8d | |||
| b7d1fb944c | |||
| 9797d2d133 | |||
| e34bb98ba1 | |||
| 60440094ba | |||
| c198e5ee15 | |||
| ceedfd9b7e | |||
| a4fbbaaa0b | |||
| 6cbdac5bf1 | |||
| 26629928c3 | |||
| 55c864ec45 | |||
| 07b5fd342a | |||
| 4481fcc75e | |||
| a155dd32e8 | |||
| c4c804edf7 | |||
| b26ca0e21a | |||
| 97b15a1708 | |||
| e808ab7409 | |||
| 7dc8527022 | |||
| f7765ea5b9 | |||
| f1d687cfdb | |||
| 57468c29f9 | |||
| 30df673ffa | |||
| 55b7852a65 | |||
| 026685ee48 | |||
| 8b5c292397 | |||
| 941420abed | |||
| a042d1aab4 | |||
| 53c2543474 | |||
| bac0820864 | |||
| e0381f25f7 | |||
| ce2ea3f3ae | |||
| c0d38de280 | |||
| 9a728c37df | |||
| 6be6210b67 | |||
| b21165722b | |||
| fd5d68ca9b | |||
| 9f26cbb89a | |||
| 0dc894356b | |||
| 6b5acdea1f | |||
| 892c5726f5 | |||
| 6c7261a223 | |||
| ae11213622 | |||
| 4bf35cbed8 | |||
| 7916e56963 | |||
| b9b4ff6f5e | |||
| 734222bd88 | |||
| 01590385c7 | |||
| 9be4bf0d14 | |||
| b1677d5f47 | |||
| 1e13a7640e | |||
| 804283877c | |||
| 65ace8d03d | |||
| 890376d04f | |||
| 18990587b9 | |||
| 75ef003747 | |||
| b9a6f47929 | |||
| 857219d70d | |||
| 92275c41cc | |||
| 09985988e7 | |||
| 524d431438 | |||
| ccd052cc99 | |||
| 1f461c7508 | |||
| 4bea619855 | |||
| f3621496fb | |||
| 1238c081c6 | |||
| 663e857df6 | |||
| 92ffd898f5 | |||
| 76e0f94532 | |||
| ff2d0cfb10 | |||
| 1cc10be443 | |||
| d2db96886d | |||
| 3d4a7c7c3f | |||
| d46139d5e3 | |||
| 40f938dc75 | |||
| 30dbafaf7c | |||
| 05dedbd892 | |||
| c0dba1e00d | |||
| cc3e57b52f | |||
| 70a6697c16 | |||
| 869f30e291 | |||
| 4c78652690 | |||
| afcda88ee3 | |||
| 605fe4ce99 | |||
| a3ee317277 | |||
| f7bce264bb | |||
| dfe6cb7afa | |||
| 8bdc62c111 | |||
| 350687f355 | |||
| 3a5a911012 | |||
| b40d19eb79 | |||
| 3e4ca3a1c7 | |||
| 663918107e | |||
| 1ac1f0445f | |||
| bce982877c | |||
| 9704543b7a | |||
| f90c3ef075 | |||
| 11177bf658 | |||
| 81f55dfc9c | |||
| c935ef890a | |||
| 71af5b106a | |||
| d24012bef5 | |||
| e904731e28 | |||
| dcd304c5d8 | |||
| 8275176792 | |||
| 8589bd3773 | |||
| c07604bb03 | |||
| b4131f2575 | |||
| b718c228fe | |||
| 3d04d78f76 | |||
| 6ebccdecc6 | |||
| 4e8d6de1de | |||
| 8b281b4d1c | |||
| 8ce12fb1af | |||
| 9e4efe5d72 | |||
| ab6c64b49a | |||
| dd71173263 | |||
| 89ed09744b | |||
| ddec1d5317 | |||
| 50dd6185bb | |||
| 6df17bba99 | |||
| ed89827908 | |||
| b61f6c35c7 | |||
| f9253485da | |||
| 7dc554ec34 | |||
| c7608c4bad | |||
| 10ca34e2a7 | |||
| e4fc918b11 | |||
| c1a21c9ab1 | |||
| 4ac848f18a | |||
| 46faa0f678 | |||
| 4072bc05af | |||
| e196f71d58 | |||
| b9d3b571bc | |||
| 816e3efbd5 | |||
| 8afbe544a3 | |||
| c7b7830495 | |||
| af3654d389 | |||
| 838cefaf48 | |||
| 4dca966c5d | |||
| 2609882346 | |||
| 36fc9191b9 | |||
| 4583522ea2 | |||
| f0e2adc3df | |||
| 091b34c05f | |||
| 09bc9cd77a | |||
| e893ed4590 | |||
| c0ad519e53 | |||
| 03af8dcc88 | |||
| 45e17307a1 | |||
| 357226eb71 | |||
| ac408046cf | |||
| 1b3cf70eef | |||
| d295014a8c | |||
| c0fd138706 | |||
| 2af35ac4f1 | |||
| b7a193dc3a | |||
| 79e264249c | |||
| 51d335c0e8 | |||
| 2f010e77ea | |||
| 848dbb4d43 | |||
| 6384e7aea5 | |||
| 519e7bbfd4 | |||
| 1ad15075f8 | |||
| e21b4517d6 | |||
| 31c756addb | |||
| 4ea53e045b | |||
| 4ceb03a9ce | |||
| d0b840697b | |||
| 57b6e5cb85 | |||
| fb3790398d | |||
| 2a3e2d8f9f | |||
| 0f260d51c5 | |||
| 28afbe37ec | |||
| 13aafe828f | |||
| 1769b565f7 | |||
| a4ecb998aa | |||
| a54af04f4e | |||
| 4a260f74fa | |||
| 984c777286 | |||
| 33ced12295 | |||
| be6d07e962 | |||
| d0de1723ed | |||
| 39378fec87 | |||
| e8bf38fb24 | |||
| d27f17cef8 | |||
| c43892814e | |||
| 41b8e704b7 | |||
| b55c04ddfa | |||
| 587c9f8a27 | |||
| a8768b7a20 | |||
| 10e8dfaca5 | |||
| f2d9df65ff | |||
| 749ada552e | |||
| 044e7090be | |||
| 3a2b633e28 | |||
| 6ced4f72d0 | |||
| 0f8dac81cb | |||
| 1f1b97212b | |||
| aff3064187 | |||
| d1867bd728 | |||
| 1b5e18d95f | |||
| b57184efe0 | |||
| 8a66a7eab0 | |||
| e769fdfab0 | |||
| 31ae825b9d | |||
| 98d26e77c9 | |||
| 03120161d3 | |||
| ec7abb7bff | |||
| fa2ccdd083 | |||
| 4096c073b7 | |||
| 2ad3ccc4d8 | |||
| 3bab589405 | |||
| fab52bd95a | |||
| 27e4b2276b | |||
| 64f8310a94 | |||
| e765de6b3d | |||
| 742529da26 | |||
| b728eae651 | |||
| 676e70ec18 | |||
| 13fabb0564 | |||
| 4dc4b2bd51 | |||
| 32e6f424ec | |||
| 3890278505 | |||
| 1664e02fa6 | |||
| 63ffca0173 | |||
| ff4b59afeb | |||
| 64382a85fa | |||
| 4c51391cf6 | |||
| 5add7a0ca0 | |||
| 8340779f5b | |||
| 01cc91850c | |||
| 091f9c82e1 | |||
| f7ddd211d9 | |||
| 8dce6c0b67 | |||
| 655cee523b | |||
| fa4d759fcb | |||
| 25b033df2a | |||
| a0905ac87d | |||
| 3d67ab72c6 | |||
| ecb0c9b5d4 | |||
| 53d8e2c8c3 | |||
| 22f66fdf2f | |||
| a7c09964ba | |||
| 1e03266dfe | |||
| 09f32d8c86 | |||
| 67208df602 | |||
| 8047eed6f8 | |||
| dafd62ddba | |||
| 41f9baf9dc | |||
| 1cd5827078 | |||
| b07d43a24a | |||
| 985c3ad92a | |||
| 978fa63490 | |||
| c59fac4089 | |||
| 0dab086f0c | |||
| 7d1adff071 | |||
| 38df918993 | |||
| f45df48498 | |||
| 898b5bd992 | |||
| 100023e36f | |||
| d8ca6eda7e | |||
| 4d02817415 | |||
| ef281317ee | |||
| 16ea51fe5c | |||
| b70ff8a120 | |||
| b3572c4ba2 | |||
| b8859df610 | |||
| a26ed45b55 | |||
| cd3c2899d8 | |||
| 74f1fadcf2 | |||
| 6de3859d2c | |||
| 04440d8506 | |||
| 9508b79cc3 | |||
| bec068324e | |||
| b4e993e6e8 | |||
| 57b9b1b6b6 | |||
| fce4ec6a9b | |||
| c4a7af8a47 | |||
| d359fb8ab9 | |||
| 5618a6925d | |||
| e383c67e7f | |||
| 12dcdc8bbe | |||
| bbd4cfd3d4 | |||
| a9e6031ae6 | |||
| 0b5c0ef639 | |||
| 60dbd0ce0d | |||
| 1fc79b9a46 | |||
| aba24ec781 | |||
| 952c154422 | |||
| ffa1d19216 | |||
| 5b303b268f | |||
| 50c5b56781 | |||
| 35192f5bd4 | |||
| d84a5e6f03 | |||
| d94b0771ca | |||
| 2f8f7c11f1 | |||
| 81c22542e4 | |||
| c1755835eb | |||
| 11593a7c04 | |||
| 46555ab975 | |||
| 74339e9a9f | |||
| 2b09653abb | |||
| 1c639714f3 | |||
| 45910bc7c1 | |||
| 87944e06ac | |||
| b37c7afa8a | |||
| 5713384f35 | |||
| 99f9941067 | |||
| 339646a267 | |||
| 97ff48b426 | |||
| badc4e7411 | |||
| 764de7257f | |||
| 14d71c8ca6 | |||
| 7d5583f687 | |||
| ffd470d94d | |||
| 0184dfb625 | |||
| 711c6141a8 | |||
| fdf38256e8 | |||
| 7eeb1a19cf | |||
| e68df8e1d1 | |||
| 3e26e7b646 | |||
| a13e4e7d9f | |||
| 6feafedfbe | |||
| ed115075ce | |||
| be51c2ba73 | |||
| 78b38cc75f | |||
| c8495d81bb | |||
| 6aaf2411f6 | |||
| 3f47e03317 | |||
| 9004f92689 | |||
| a928299ae0 | |||
| 1a7237f38b | |||
| b3b6637b44 | |||
| ad311c33c6 | |||
| adae4de438 | |||
| c8b06d54cb | |||
| 51848a0b43 | |||
| 2d7f4faf72 | |||
| c75bb5d01a | |||
| df8f043c16 | |||
| 01d668c09d | |||
| f4a3613561 | |||
| 12922d9434 | |||
| b6036f368e | |||
| 25291d6e3a | |||
| f4a085575a | |||
| a34b242f4e | |||
| 8a3cbce8f8 | |||
| a9c4a17c38 | |||
| 1a7152d3eb | |||
| 08da9a4494 | |||
| baaed8ed84 | |||
| 7446fba70a | |||
| d36f189192 | |||
| 152c458b9c | |||
| 7ae14f9630 | |||
| a610542a19 | |||
| 2ab492474e | |||
| 3caede3799 | |||
| 9d40374baf | |||
| 0ead8a14a1 | |||
| e8b16fc64f | |||
| 162e8962f7 | |||
| fc66cb6805 |
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2015-2023 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 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
|
||||
@@ -142,8 +142,8 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_offboardPadsFront = nullptr;
|
||||
m_offboardPadsBack = nullptr;
|
||||
|
||||
m_frontPlatedPadPolys = nullptr;
|
||||
m_backPlatedPadPolys = nullptr;
|
||||
m_frontPlatedPadAndGraphicPolys = nullptr;
|
||||
m_backPlatedPadAndGraphicPolys = nullptr;
|
||||
m_frontPlatedCopperPolys = nullptr;
|
||||
m_backPlatedCopperPolys = nullptr;
|
||||
|
||||
@@ -397,13 +397,18 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
break;
|
||||
|
||||
case BS_ITEM_TYPE_COPPER:
|
||||
if( item->GetBrdLayerId() == F_Cu )
|
||||
m_frontCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
|
||||
else if( item->GetBrdLayerId() == B_Cu )
|
||||
m_backCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
|
||||
else if( item->IsEnabled() )
|
||||
thickness += item->GetThickness();
|
||||
{
|
||||
// The copper thickness must be > 0 to avoid draw issues (divide by 0 for instance)
|
||||
// We use a minimal arbitrary value = 1 micrometer here:
|
||||
int copper_thickness = std::max( item->GetThickness(), pcbIUScale.mmToIU( 0.001 ) );
|
||||
|
||||
if( item->GetBrdLayerId() == F_Cu )
|
||||
m_frontCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
|
||||
else if( item->GetBrdLayerId() == B_Cu )
|
||||
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
|
||||
else if( item->IsEnabled() )
|
||||
thickness += copper_thickness;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -449,7 +454,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
for( ; layer < MAX_CU_LAYERS; layer++ )
|
||||
{
|
||||
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
|
||||
m_layerZcoordTop[layer] = -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
|
||||
}
|
||||
|
||||
// This is the top of the copper layer thickness.
|
||||
@@ -530,7 +535,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
m_boardBoundingBox = BBOX_3D( boardMin, boardMax );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
int64_t stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -589,13 +594,20 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
std::map<int, COLOR4D> colors;
|
||||
|
||||
if( m_Cfg->m_CurrentPreset == FOLLOW_PCB || m_Cfg->m_CurrentPreset == FOLLOW_PLOT_SETTINGS )
|
||||
if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
colors = GetDefaultColors();
|
||||
colors = preset->colors;
|
||||
}
|
||||
else
|
||||
{
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
if( !m_board )
|
||||
return colors;
|
||||
for( const auto& [ layer, defaultColor /* unused */ ] : GetDefaultColors() )
|
||||
colors[ layer ] = settings->GetColor( layer );
|
||||
}
|
||||
|
||||
if( m_Cfg->m_UseStackupColors && m_board )
|
||||
{
|
||||
const BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
|
||||
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
|
||||
|
||||
@@ -683,26 +695,6 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Silver" ), g_FinishColors );
|
||||
}
|
||||
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
PCBNEW_SETTINGS* pcbnewSettings = mgr.GetAppSettings<PCBNEW_SETTINGS>();
|
||||
COLOR_SETTINGS* pcbnewColors = mgr.GetColorSettings( pcbnewSettings->m_ColorTheme );
|
||||
|
||||
colors[ LAYER_3D_USER_DRAWINGS ] = pcbnewColors->GetColor( Dwgs_User );
|
||||
colors[ LAYER_3D_USER_COMMENTS ] = pcbnewColors->GetColor( Cmts_User );
|
||||
colors[ LAYER_3D_USER_ECO1 ] = pcbnewColors->GetColor( Eco1_User );
|
||||
colors[ LAYER_3D_USER_ECO2 ] = pcbnewColors->GetColor( Eco2_User );
|
||||
}
|
||||
else if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
return preset->colors;
|
||||
}
|
||||
else
|
||||
{
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
for( const auto& [ layer, color ] : GetDefaultColors() )
|
||||
colors[ layer ] = settings->GetColor( layer );
|
||||
}
|
||||
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = colors[ LAYER_3D_COPPER_TOP ];
|
||||
@@ -860,6 +852,42 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
}
|
||||
|
||||
|
||||
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
|
||||
{
|
||||
std::bitset<LAYER_3D_END> ret;
|
||||
|
||||
ret.set( LAYER_3D_BOARD, true );
|
||||
ret.set( LAYER_3D_COPPER_TOP, true );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, true );
|
||||
ret.set( LAYER_3D_ADHESIVE, true );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, false );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, false );
|
||||
ret.set( LAYER_3D_USER_ECO1, false );
|
||||
ret.set( LAYER_3D_USER_ECO2, false );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, true );
|
||||
ret.set( LAYER_FP_VALUES, true );
|
||||
ret.set( LAYER_FP_TEXT, true );
|
||||
|
||||
ret.set( LAYER_3D_TH_MODELS, true );
|
||||
ret.set( LAYER_3D_SMD_MODELS, true );
|
||||
ret.set( LAYER_3D_VIRTUAL_MODELS, true );
|
||||
ret.set( LAYER_3D_MODELS_NOT_IN_POS, false );
|
||||
ret.set( LAYER_3D_MODELS_MARKED_DNP, false );
|
||||
|
||||
ret.set( LAYER_3D_BOUNDING_BOXES, false );
|
||||
ret.set( LAYER_3D_OFF_BOARD_SILK, false );
|
||||
ret.set( LAYER_3D_AXES, true );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
{
|
||||
m_board_poly.RemoveAllContours();
|
||||
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
void SetLayerColors( const std::map<int, COLOR4D>& aColors );
|
||||
|
||||
std::bitset<LAYER_3D_END> GetVisibleLayers() const;
|
||||
std::bitset<LAYER_3D_END> GetDefaultVisibleLayers() const;
|
||||
void SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers );
|
||||
|
||||
/**
|
||||
@@ -330,8 +331,8 @@ public:
|
||||
*/
|
||||
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
|
||||
|
||||
const SHAPE_POLY_SET* GetFrontPlatedPadPolys() { return m_frontPlatedPadPolys; }
|
||||
const SHAPE_POLY_SET* GetBackPlatedPadPolys() { return m_backPlatedPadPolys; }
|
||||
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() { return m_frontPlatedPadAndGraphicPolys; }
|
||||
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() { return m_backPlatedPadAndGraphicPolys; }
|
||||
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
|
||||
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
|
||||
|
||||
@@ -437,8 +438,8 @@ private:
|
||||
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
|
||||
///< of items
|
||||
|
||||
SHAPE_POLY_SET* m_frontPlatedPadPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedPadPolys;
|
||||
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedCopperPolys;
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ void BOARD_ADAPTER::destroyLayers()
|
||||
|
||||
DELETE_AND_FREE_MAP( m_layers_poly );
|
||||
|
||||
DELETE_AND_FREE( m_frontPlatedPadPolys )
|
||||
DELETE_AND_FREE( m_backPlatedPadPolys )
|
||||
DELETE_AND_FREE( m_frontPlatedPadAndGraphicPolys )
|
||||
DELETE_AND_FREE( m_backPlatedPadAndGraphicPolys )
|
||||
DELETE_AND_FREE( m_frontPlatedCopperPolys )
|
||||
DELETE_AND_FREE( m_backPlatedCopperPolys )
|
||||
|
||||
@@ -154,9 +154,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L692
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_startCopperLayersTime = GetRunningMicroSecs();
|
||||
int64_t stats_startCopperLayersTime = GetRunningMicroSecs();
|
||||
|
||||
unsigned start_Time = stats_startCopperLayersTime;
|
||||
int64_t start_Time = stats_startCopperLayersTime;
|
||||
#endif
|
||||
|
||||
PCB_LAYER_ID cu_seq[MAX_CU_LAYERS];
|
||||
@@ -241,8 +241,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
if( cfg.differentiate_plated_copper )
|
||||
{
|
||||
m_frontPlatedPadPolys = new SHAPE_POLY_SET;
|
||||
m_backPlatedPadPolys = new SHAPE_POLY_SET;
|
||||
m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
|
||||
m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
|
||||
m_frontPlatedCopperPolys = new SHAPE_POLY_SET;
|
||||
m_backPlatedCopperPolys = new SHAPE_POLY_SET;
|
||||
|
||||
@@ -586,10 +586,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// ADD PLATED PADS contours
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
footprint->TransformPadsToPolySet( *m_frontPlatedPadPolys, F_Cu, 0, maxError,
|
||||
footprint->TransformPadsToPolySet( *m_frontPlatedPadAndGraphicPolys, F_Cu, 0, maxError,
|
||||
ERROR_INSIDE, true, false, true );
|
||||
|
||||
footprint->TransformPadsToPolySet( *m_backPlatedPadPolys, B_Cu, 0, maxError,
|
||||
footprint->TransformPadsToPolySet( *m_backPlatedPadAndGraphicPolys, B_Cu, 0, maxError,
|
||||
ERROR_INSIDE, true, false, true );
|
||||
}
|
||||
}
|
||||
@@ -1050,21 +1050,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
// SUBTRACT PLATED COPPER FROM (UNPLATED) COPPER
|
||||
// Subtract plated copper from unplated copper
|
||||
bool hasF_Cu = false;
|
||||
bool hasB_Cu = false;
|
||||
|
||||
if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
hasF_Cu = true;
|
||||
}
|
||||
|
||||
if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
hasB_Cu = true;
|
||||
}
|
||||
|
||||
m_frontPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
// Add plated graphic items to build vertical walls
|
||||
if( hasF_Cu && m_frontPlatedCopperPolys->OutlineCount() )
|
||||
m_frontPlatedPadAndGraphicPolys->Append( *m_frontPlatedCopperPolys );
|
||||
|
||||
if( hasB_Cu && m_backPlatedCopperPolys->OutlineCount() )
|
||||
m_backPlatedPadAndGraphicPolys->Append( *m_backPlatedCopperPolys );
|
||||
|
||||
m_frontPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_frontPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
m_backPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
@@ -1134,6 +1146,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
if( layerPoly != m_layers_poly.end() )
|
||||
{
|
||||
// This will make a union of all added contours
|
||||
layerPoly->second->ClearArcs();
|
||||
layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
wxString err_messages;
|
||||
INFOBAR_REPORTER warningReporter( m_parentInfoBar );
|
||||
STATUSBAR_REPORTER activityReporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
|
||||
unsigned start_time = GetRunningMicroSecs();
|
||||
int64_t start_time = GetRunningMicroSecs();
|
||||
|
||||
// "Makes the OpenGL state that is represented by the OpenGL rendering
|
||||
// context context current, i.e. it will be used by all subsequent OpenGL calls.
|
||||
@@ -461,7 +461,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
|
||||
if( m_camera_is_moving )
|
||||
{
|
||||
const unsigned curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
curtime_delta_s = (curtime_delta / 1e6) * m_camera_moving_speed;
|
||||
m_camera.Interpolate( curtime_delta_s );
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ private:
|
||||
|
||||
bool m_render_pivot; // Render the pivot while camera moving
|
||||
float m_camera_moving_speed; // 1.0f will be 1:1
|
||||
unsigned m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
bool m_animation_enabled; // Camera animation enabled
|
||||
int m_moving_speed_multiplier; // Camera animation speed multiplier option
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
|
||||
|
||||
@@ -613,12 +613,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
{
|
||||
const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys();
|
||||
const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys();
|
||||
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
|
||||
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
|
||||
|
||||
if( frontPlatedPadPolys )
|
||||
if( frontPlatedPadAndGraphicPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = frontPlatedPadPolys->CloneDropTriangulation();
|
||||
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
@@ -630,9 +630,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
||||
}
|
||||
|
||||
if( backPlatedPadPolys )
|
||||
if( backPlatedPadAndGraphicPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = backPlatedPadPolys->CloneDropTriangulation();
|
||||
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
@@ -917,6 +917,10 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
// Building the 3D models late crashes on recent versions of macOS
|
||||
// Unclear the exact mechanism, but as a workaround, just build them
|
||||
// all the time. See https://gitlab.com/kicad/code/kicad/-/issues/17198
|
||||
#ifndef __WXMAC__
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
@@ -924,6 +928,7 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Go for all footprints
|
||||
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
|
||||
|
||||
@@ -368,7 +368,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
OBJECT_3D_STATS::Instance().ResetStats();
|
||||
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
@@ -771,8 +771,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
}
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_endConvertTime = GetRunningMicroSecs();
|
||||
unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
int64_t stats_endConvertTime = GetRunningMicroSecs();
|
||||
int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -781,7 +781,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
int64_t stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
@@ -955,7 +955,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
if( aStatusReporter )
|
||||
{
|
||||
// Calculation time in seconds
|
||||
double calculation_time = (double) GetRunningMicroSecs() - stats_startReloadTime / 1e6;
|
||||
double calculation_time = (double) ( GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
|
||||
|
||||
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
RT_RENDER_STATE m_renderState;
|
||||
|
||||
/// Time that the render starts
|
||||
unsigned long int m_renderStartTime;
|
||||
int64_t m_renderStartTime;
|
||||
|
||||
/// Save the number of blocks progress of the render
|
||||
size_t m_blockRenderProgressCount;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 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
|
||||
@@ -568,7 +568,8 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
m_boardAdapter.m_Cfg = cfg;
|
||||
applySettings( cfg );
|
||||
|
||||
m_boardAdapter.SetBoard( GetBoard() );
|
||||
|
||||
// When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
|
||||
@@ -576,28 +577,20 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
// (freeze window) with large boards.
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
|
||||
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
|
||||
|
||||
if( cfg->m_CurrentPreset == LEGACY_PRESET_FLAG )
|
||||
{
|
||||
wxString legacyColorsPresetName = _( "legacy colors" );
|
||||
|
||||
cfg->m_UseStackupColors = false;
|
||||
|
||||
if( !cfg->FindPreset( legacyColorsPresetName ) )
|
||||
{
|
||||
cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
|
||||
GetAdapter().GetVisibleLayers(),
|
||||
GetAdapter().GetLayerColors() );
|
||||
GetAdapter().GetDefaultVisibleLayers(),
|
||||
GetAdapter().GetDefaultColors() );
|
||||
}
|
||||
|
||||
if( Pgm().GetSettingsManager().GetColorSettings()->GetUseBoardStackupColors() )
|
||||
cfg->m_CurrentPreset = FOLLOW_PCB;
|
||||
else
|
||||
cfg->m_CurrentPreset = legacyColorsPresetName;
|
||||
cfg->m_CurrentPreset = wxEmptyString;
|
||||
}
|
||||
|
||||
m_boardAdapter.InitSettings( nullptr, nullptr );
|
||||
@@ -646,7 +639,7 @@ void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTex
|
||||
ReCreateMainToolbar();
|
||||
|
||||
loadCommonSettings();
|
||||
LoadSettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
|
||||
applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
|
||||
|
||||
m_appearancePanel->CommonSettingsChanged();
|
||||
|
||||
@@ -825,3 +818,15 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::applySettings( EDA_3D_VIEWER_SETTINGS* cfg )
|
||||
{
|
||||
m_boardAdapter.m_Cfg = cfg;
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 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
|
||||
@@ -167,6 +167,8 @@ private:
|
||||
*/
|
||||
void loadCommonSettings();
|
||||
|
||||
void applySettings( EDA_3D_VIEWER_SETTINGS* aSettings );
|
||||
|
||||
private:
|
||||
wxFileName m_defaultSaveScreenshotFileName;
|
||||
|
||||
|
||||
@@ -377,6 +377,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<int>( "camera.projection_mode",
|
||||
&m_Camera.projection_mode, 1 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "use_stackup_colors",
|
||||
&m_UseStackupColors, true ) );
|
||||
m_params.emplace_back( new PARAM_LAYER_PRESET_3D( "layer_presets",
|
||||
&m_LayerPresets ) );
|
||||
m_params.emplace_back( new PARAM<wxString>( "current_layer_preset",
|
||||
|
||||
@@ -169,6 +169,7 @@ public:
|
||||
RENDER_SETTINGS m_Render;
|
||||
CAMERA_SETTINGS m_Camera;
|
||||
|
||||
bool m_UseStackupColors;
|
||||
std::vector<LAYER_PRESET_3D> m_LayerPresets;
|
||||
wxString m_CurrentPreset;
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Clockwise" ) )
|
||||
.Tooltip( _( "Rotate X Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CW ) );
|
||||
@@ -62,7 +61,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate X Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CCW ) );
|
||||
@@ -71,7 +69,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Clockwise" ) )
|
||||
.Tooltip( _( "Rotate Y Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CW ) );
|
||||
@@ -80,7 +77,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate Y Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CCW ) );
|
||||
@@ -89,7 +85,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Clockwise" ) )
|
||||
.Tooltip( _( "Rotate Z Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CW ) );
|
||||
@@ -98,7 +93,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate Z Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CCW ) );
|
||||
@@ -108,7 +102,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveLeft( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_LEFT )
|
||||
.FriendlyName( _( "Move Board Left" ) )
|
||||
.Tooltip( _( "Move board Left" ) )
|
||||
.Icon( BITMAPS::left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_LEFT ) );
|
||||
@@ -118,7 +111,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveRight( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_RIGHT )
|
||||
.FriendlyName( _( "Move Board Right" ) )
|
||||
.Tooltip( _( "Move board Right" ) )
|
||||
.Icon( BITMAPS::right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_RIGHT ) );
|
||||
@@ -128,7 +120,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveUp( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_UP )
|
||||
.FriendlyName( _( "Move Board Up" ) )
|
||||
.Tooltip( _( "Move board Up" ) )
|
||||
.Icon( BITMAPS::up )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_UP ) );
|
||||
@@ -138,7 +129,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveDown( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_DOWN )
|
||||
.FriendlyName( _( "Move Board Down" ) )
|
||||
.Tooltip( _( "Move board Down" ) )
|
||||
.Icon( BITMAPS::down )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_DOWN ) );
|
||||
@@ -148,7 +138,7 @@ TOOL_ACTION EDA_3D_ACTIONS::homeView( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_HOME )
|
||||
.FriendlyName ( _( "Home View" ) )
|
||||
.Tooltip( _( "Home view" ) )
|
||||
.Tooltip( _( "Redraw at the home position and zoom" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FIT_SCREEN ) );
|
||||
|
||||
@@ -174,7 +164,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewFront( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Y' )
|
||||
.FriendlyName( _( "View Front" ) )
|
||||
.Tooltip( _( "View Front" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FRONT ) );
|
||||
@@ -184,7 +173,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewBack( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Y' )
|
||||
.FriendlyName( _( "View Back" ) )
|
||||
.Tooltip( _( "View Back" ) )
|
||||
.Icon( BITMAPS::axis3d_back )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BACK ) );
|
||||
@@ -194,7 +182,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewLeft( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'X' )
|
||||
.FriendlyName( _( "View Left" ) )
|
||||
.Tooltip( _( "View Left" ) )
|
||||
.Icon( BITMAPS::axis3d_left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_LEFT ) );
|
||||
@@ -204,7 +191,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewRight( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'X' )
|
||||
.FriendlyName( _( "View Right" ) )
|
||||
.Tooltip( _( "View Right" ) )
|
||||
.Icon( BITMAPS::axis3d_right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_RIGHT ) );
|
||||
@@ -214,7 +200,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewTop( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Z' )
|
||||
.FriendlyName( _( "View Top" ) )
|
||||
.Tooltip( _( "View Top" ) )
|
||||
.Icon( BITMAPS::axis3d_top )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_TOP ) );
|
||||
@@ -224,7 +209,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewBottom( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Z' )
|
||||
.FriendlyName( _( "View Bottom" ) )
|
||||
.Tooltip( _( "View Bottom" ) )
|
||||
.Icon( BITMAPS::axis3d_bottom )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BOTTOM ) );
|
||||
@@ -233,7 +217,6 @@ TOOL_ACTION EDA_3D_ACTIONS::noGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.noGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "No 3D Grid" ) )
|
||||
.Tooltip( _( "No 3D Grid" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::NONE ) );
|
||||
|
||||
@@ -241,7 +224,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show10mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 10mm" ) )
|
||||
.Tooltip( _( "3D Grid 10mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_10MM ) );
|
||||
|
||||
@@ -249,7 +231,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 5mm" ) )
|
||||
.Tooltip( _( "3D Grid 5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_5MM ) );
|
||||
|
||||
@@ -257,7 +238,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show2_5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 2.5mm" ) )
|
||||
.Tooltip( _( "3D Grid 2.5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_2P5MM ) );
|
||||
|
||||
@@ -265,7 +245,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show1mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 1mm" ) )
|
||||
.Tooltip( _( "3D Grid 1mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_1MM ) );
|
||||
|
||||
@@ -350,7 +329,6 @@ TOOL_ACTION EDA_3D_ACTIONS::showAxis( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.showAxis" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Show 3D Axis" ) )
|
||||
.Tooltip( _( "Show 3D Axis" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE ) );
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/checkbox.h>
|
||||
|
||||
#include <../3d_rendering/opengl/render_3d_opengl.h>
|
||||
|
||||
@@ -82,6 +83,13 @@ const APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D APPEARANCE_CONTROLS_3D::s_la
|
||||
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
|
||||
};
|
||||
|
||||
// The list of IDs that can have colors coming from the board stackup, and cannot be
|
||||
// modified if use colors from stackup is activated
|
||||
static std::vector<int> inStackupColors{ LAYER_3D_BOARD, LAYER_3D_COPPER_TOP,
|
||||
LAYER_3D_COPPER_BOTTOM, LAYER_3D_SOLDERPASTE,
|
||||
LAYER_3D_SILKSCREEN_TOP, LAYER_3D_SILKSCREEN_BOTTOM,
|
||||
LAYER_3D_SOLDERMASK_TOP, LAYER_3D_SOLDERMASK_BOTTOM
|
||||
};
|
||||
|
||||
APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
wxWindow* aFocusOwner ) :
|
||||
@@ -112,6 +120,24 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
m_presetsLabel->SetFont( infoFont );
|
||||
m_viewportsLabel->SetFont( infoFont );
|
||||
|
||||
// Create display options
|
||||
m_cbUseBoardStackupColors = new wxCheckBox( m_panelLayers, wxID_ANY,
|
||||
_( "Use board stackup colors" ) );
|
||||
m_cbUseBoardStackupColors->SetFont( infoFont );
|
||||
|
||||
m_cbUseBoardStackupColors->Bind( wxEVT_CHECKBOX,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
cfg->m_UseStackupColors = aEvent.IsChecked();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
m_frame->NewDisplay( true );
|
||||
} );
|
||||
|
||||
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
|
||||
|
||||
m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility "
|
||||
"combinations.\n"
|
||||
"Use %s+Tab to activate selector.\n"
|
||||
@@ -176,7 +202,9 @@ void APPEARANCE_CONTROLS_3D::OnSize( wxSizeEvent& aEvent )
|
||||
void APPEARANCE_CONTROLS_3D::OnLanguageChanged()
|
||||
{
|
||||
Freeze();
|
||||
|
||||
rebuildLayers();
|
||||
m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
|
||||
rebuildLayerPresetsWidget();
|
||||
rebuildViewportsWidget();
|
||||
|
||||
@@ -209,6 +237,9 @@ void APPEARANCE_CONTROLS_3D::OnDarkModeToggle()
|
||||
void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
|
||||
{
|
||||
OnLanguageChanged();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
}
|
||||
|
||||
|
||||
@@ -437,6 +468,19 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
SWATCH_SMALL );
|
||||
swatch->SetToolTip( _( "Left double click or middle click to change color" ) );
|
||||
|
||||
swatch->SetReadOnlyCallback(
|
||||
[this]()
|
||||
{
|
||||
WX_INFOBAR* infobar = m_frame->GetInfoBar();
|
||||
|
||||
infobar->RemoveAllButtons();
|
||||
infobar->AddCloseButton();
|
||||
|
||||
infobar->ShowMessageFor( _( "Uncheck 'Use board stackup colors' to "
|
||||
"allow color editing." ),
|
||||
10000, wxICON_INFORMATION );
|
||||
} );
|
||||
|
||||
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
|
||||
aSetting->m_Ctl_color = swatch;
|
||||
|
||||
@@ -515,6 +559,7 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
@@ -527,8 +572,22 @@ void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
|
||||
setting->m_Ctl_visibility->SetValue( visibleLayers.test( setting->m_Id ) );
|
||||
|
||||
if( setting->m_Ctl_color )
|
||||
{
|
||||
setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
|
||||
|
||||
// if cfg->m_UseStackupColors is set, board colors cannot be modified locally, but
|
||||
// other colors can be
|
||||
if( std::find( inStackupColors.begin(), inStackupColors.end(), setting->m_Id )
|
||||
!= inStackupColors.end() )
|
||||
{
|
||||
if( cfg )
|
||||
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( cfg )
|
||||
m_cbUseBoardStackupColors->SetValue( cfg->m_UseStackupColors );
|
||||
}
|
||||
|
||||
|
||||
@@ -563,9 +622,16 @@ void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
auto it = std::find_if( presets.begin(), presets.end(),
|
||||
auto it = std::find_if(
|
||||
presets.begin(), presets.end(),
|
||||
[&]( const LAYER_PRESET_3D& aPreset )
|
||||
{
|
||||
if( aPreset.name.Lower() == _( "legacy colors" )
|
||||
&& m_cbUseBoardStackupColors->GetValue() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
|
||||
@@ -578,9 +644,12 @@ void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_ADHESIVE; ++layer )
|
||||
for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( aPreset.colors.at( layer ) != colors.at( layer ) )
|
||||
auto it1 = aPreset.colors.find( layer );
|
||||
auto it2 = colors.find( layer );
|
||||
|
||||
if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -745,6 +814,9 @@ void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const LAYER_PRESET_3D& aPreset
|
||||
adapter.SetVisibleLayers( aPreset.layers );
|
||||
adapter.SetLayerColors( aPreset.colors );
|
||||
|
||||
if( aPreset.name.Lower() == _( "legacy colors" ) )
|
||||
adapter.m_Cfg->m_UseStackupColors = false;
|
||||
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
|
||||
@@ -166,26 +166,26 @@ private:
|
||||
void passOnFocus();
|
||||
|
||||
private:
|
||||
EDA_3D_VIEWER_FRAME* m_frame;
|
||||
wxWindow* m_focusOwner;
|
||||
|
||||
static const APPEARANCE_SETTING_3D s_layerSettings[];
|
||||
|
||||
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
|
||||
EDA_3D_VIEWER_FRAME* m_frame;
|
||||
wxWindow* m_focusOwner;
|
||||
|
||||
std::vector<std::unique_ptr<APPEARANCE_SETTING_3D>> m_layerSettings;
|
||||
std::map<int, APPEARANCE_SETTING_3D*> m_layerSettingsMap;
|
||||
|
||||
wxArrayString m_presetMRU;
|
||||
wxArrayString m_presetMRU;
|
||||
|
||||
std::map<wxString, VIEWPORT3D> m_viewports;
|
||||
VIEWPORT3D* m_lastSelectedViewport;
|
||||
wxArrayString m_viewportMRU;
|
||||
std::map<wxString, VIEWPORT3D> m_viewports;
|
||||
VIEWPORT3D* m_lastSelectedViewport;
|
||||
wxArrayString m_viewportMRU;
|
||||
|
||||
wxBoxSizer* m_layersOuterSizer;
|
||||
wxBoxSizer* m_envOuterSizer;
|
||||
int m_pointSize;
|
||||
wxColour m_layerPanelColour;
|
||||
wxBoxSizer* m_layersOuterSizer;
|
||||
wxBoxSizer* m_envOuterSizer;
|
||||
int m_pointSize;
|
||||
wxColour m_layerPanelColour;
|
||||
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
|
||||
wxCheckBox* m_cbUseBoardStackupColors;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -25,11 +25,14 @@ APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWi
|
||||
m_panelLayers->SetSizer( m_panelLayersSizer );
|
||||
m_panelLayers->Layout();
|
||||
m_panelLayersSizer->Fit( m_panelLayers );
|
||||
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND|wxBOTTOM, 5 );
|
||||
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bBottomMargin;
|
||||
bBottomMargin = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bBottomMargin->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 3 );
|
||||
|
||||
wxBoxSizer* bPresets;
|
||||
bPresets = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
@@ -44,7 +47,7 @@ APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWi
|
||||
bPresets->Add( m_cbLayerPresets, 0, wxALL|wxEXPAND, 2 );
|
||||
|
||||
|
||||
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bBottomMargin->Add( 0, 2, 0, wxEXPAND, 5 );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/choice.h>
|
||||
|
||||
@@ -38,6 +39,7 @@ class APPEARANCE_CONTROLS_3D_BASE : public WX_PANEL
|
||||
wxPanel* m_panelLayers;
|
||||
wxBoxSizer* m_panelLayersSizer;
|
||||
wxScrolledCanvas* m_windowLayers;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxStaticText* m_presetsLabel;
|
||||
wxChoice* m_cbLayerPresets;
|
||||
wxStaticText* m_viewportsLabel;
|
||||
|
||||
+12
-4
@@ -106,10 +106,9 @@ option( KICAD_SCRIPTING_WXPYTHON
|
||||
ON )
|
||||
mark_as_advanced( KICAD_SCRIPTING_WXPYTHON )
|
||||
|
||||
cmake_dependent_option( KICAD_UPDATE_CHECK
|
||||
option( KICAD_UPDATE_CHECK
|
||||
"Build in update check"
|
||||
ON "APPLE_OR_WIN32"
|
||||
OFF )
|
||||
ON )
|
||||
|
||||
# EGL is only needed on Linux with Wayland
|
||||
cmake_dependent_option( KICAD_USE_EGL
|
||||
@@ -515,6 +514,8 @@ if( MSVC )
|
||||
string( APPEND CMAKE_CXX_FLAGS " /wd4800" )
|
||||
# /Zi: create PDB
|
||||
string( APPEND CMAKE_CXX_FLAGS " /Zi" )
|
||||
# /Zc:__cplusplus: define this macro according to C++ standard version
|
||||
string( APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus" )
|
||||
# /GF: enable string pooling
|
||||
string( APPEND CMAKE_CXX_FLAGS_RELEASE " /GF" )
|
||||
string( APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /GF" )
|
||||
@@ -877,7 +878,14 @@ check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
|
||||
# Get the correct Python site package install path from the Python interpreter found by
|
||||
# FindPythonInterp unless the user specifically defined a custom path.
|
||||
if( NOT PYTHON_SITE_PACKAGE_PATH )
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig;print(\"%s\"%sysconfig.get_path('platlib', vars={'platbase': '.'}))"
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import sys, sysconfig
|
||||
if 'deb_system' in sysconfig.get_scheme_names():
|
||||
scheme = 'deb_system'
|
||||
elif sys.version_info > (3, 10):
|
||||
scheme = sysconfig.get_default_scheme()
|
||||
else:
|
||||
scheme = sysconfig._get_default_scheme()
|
||||
print(\"%s\"%sysconfig.get_path('platlib', vars={'platbase': '.'}, scheme=scheme))"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2015-2024 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
|
||||
@@ -72,6 +72,7 @@ set( _wvh_new_version_text
|
||||
#endif
|
||||
|
||||
#define KICAD_COMMIT_HASH \"${KICAD_COMMIT_HASH}\"
|
||||
#define KICAD_VERSION \"${KICAD_VERSION}\"
|
||||
#define KICAD_VERSION_FULL \"${KICAD_VERSION_FULL}\"
|
||||
#define KICAD_SEMANTIC_VERSION \"${KICAD_SEMANTIC_VERSION}\"
|
||||
#define KICAD_MAJOR_VERSION \"${KICAD_MAJOR_VERSION}\"
|
||||
|
||||
+39
-19
@@ -27,7 +27,7 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Set the needed libraries
|
||||
set( OCC_LIBS
|
||||
set( OCC_LIBS_COMMON
|
||||
TKBinL
|
||||
TKBin
|
||||
TKBinTObj
|
||||
@@ -45,7 +45,6 @@ set( OCC_LIBS
|
||||
TKGeomAlgo
|
||||
TKGeomBase
|
||||
TKHLR
|
||||
TKIGES
|
||||
TKLCAF
|
||||
TKMath
|
||||
TKMesh
|
||||
@@ -56,18 +55,10 @@ set( OCC_LIBS
|
||||
TKRWMesh
|
||||
TKService
|
||||
TKShHealing
|
||||
TKSTEP209
|
||||
TKSTEPAttr
|
||||
TKSTEPBase
|
||||
TKSTEP
|
||||
TKSTL
|
||||
TKTObj
|
||||
TKTopAlgo
|
||||
TKV3d
|
||||
TKVRML
|
||||
TKXCAF
|
||||
TKXDEIGES
|
||||
TKXDESTEP
|
||||
TKXMesh
|
||||
TKXmlL
|
||||
TKXml
|
||||
@@ -76,6 +67,27 @@ set( OCC_LIBS
|
||||
TKXSBase
|
||||
)
|
||||
|
||||
# Libraries valid pre-7.8.0
|
||||
set( OCC_LIBS_PRE_78
|
||||
TKIGES
|
||||
TKSTEP209
|
||||
TKSTEPAttr
|
||||
TKSTEPBase
|
||||
TKSTEP
|
||||
TKSTL
|
||||
TKVRML
|
||||
TKXDEIGES
|
||||
TKXDESTEP
|
||||
)
|
||||
|
||||
# Libraries for versions >= 7.8.0
|
||||
set( OCC_LIBS_POST_78
|
||||
TKDEIGES
|
||||
TKDEGLTF
|
||||
TKDESTEP
|
||||
TKDESTL
|
||||
)
|
||||
|
||||
set(OCC_TYPE "OpenCASCADE Standard Edition")
|
||||
if(WIN32)
|
||||
if(CYGWIN OR MINGW)
|
||||
@@ -178,9 +190,8 @@ endif(OCC_INCLUDE_DIR AND NOT ${OCC_INCLUDE_DIR} STREQUAL "OCC_INCLUDE_DIR-NOTFO
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OCC REQUIRED_VARS OCC_INCLUDE_DIR VERSION_VAR OCC_VERSION_STRING)
|
||||
|
||||
if(OCC_FOUND)
|
||||
foreach(lib IN LISTS OCC_LIBS)
|
||||
|
||||
macro(occ_lib_search SEARCH_LIST)
|
||||
foreach(lib IN LISTS ${SEARCH_LIST})
|
||||
#Use the specified library location if given
|
||||
find_library(OCC_TEMP_LIB ${lib} HINTS ${OCC_LIBRARY_DIR} NO_DEFAULT_PATH)
|
||||
if(${OCC_TEMP_LIB} STREQUAL "OCC_TEMP_LIB-NOTFOUND")
|
||||
@@ -197,11 +208,20 @@ if(OCC_FOUND)
|
||||
|
||||
unset(OCC_TEMP_LIB CACHE)
|
||||
endforeach(lib)
|
||||
endmacro()
|
||||
|
||||
#Convert path names to absolute for cleaner display
|
||||
get_filename_component(OCC_INCLUDE_DIR "${OCC_INCLUDE_DIR}" ABSOLUTE)
|
||||
get_filename_component(OCC_LIBRARY_DIR "${OCC_LIBRARY_DIR}" ABSOLUTE)
|
||||
message(STATUS "Found ${OCC_TYPE} version: ${OCC_VERSION_STRING}")
|
||||
message(STATUS " ++ ${OCC_TYPE} include directory: ${OCC_INCLUDE_DIR}")
|
||||
message(STATUS " ++ ${OCC_TYPE} shared libraries directory: ${OCC_LIBRARY_DIR}")
|
||||
if(OCC_FOUND)
|
||||
occ_lib_search( OCC_LIBS_COMMON )
|
||||
if(OCC_VERSION_STRING VERSION_LESS "7.8.0")
|
||||
occ_lib_search( OCC_LIBS_PRE_78 )
|
||||
else()
|
||||
occ_lib_search( OCC_LIBS_POST_78 )
|
||||
endif()
|
||||
|
||||
#Convert path names to absolute for cleaner display
|
||||
get_filename_component(OCC_INCLUDE_DIR "${OCC_INCLUDE_DIR}" ABSOLUTE)
|
||||
get_filename_component(OCC_LIBRARY_DIR "${OCC_LIBRARY_DIR}" ABSOLUTE)
|
||||
message(STATUS "Found ${OCC_TYPE} version: ${OCC_VERSION_STRING}")
|
||||
message(STATUS " ++ ${OCC_TYPE} include directory: ${OCC_INCLUDE_DIR}")
|
||||
message(STATUS " ++ ${OCC_TYPE} shared libraries directory: ${OCC_LIBRARY_DIR}")
|
||||
endif(OCC_FOUND)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.0" )
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.2" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -388,8 +388,10 @@ set( COMMON_IO_SRCS
|
||||
io/io_utils.cpp
|
||||
|
||||
# Altium
|
||||
io/altium/altium_parser.cpp
|
||||
io/altium/altium_binary_parser.cpp
|
||||
io/altium/altium_ascii_parser.cpp
|
||||
io/altium/altium_parser_utils.cpp
|
||||
io/altium/altium_props_utils.cpp
|
||||
|
||||
# Cadstar
|
||||
io/cadstar/cadstar_archive_parser.cpp
|
||||
|
||||
@@ -104,6 +104,11 @@ static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo"
|
||||
static const wxChar DisambiguationTime[] = wxT( "DisambiguationTime" );
|
||||
static const wxChar PcbSelectionVisibilityRatio[] = wxT( "PcbSelectionVisibilityRatio" );
|
||||
static const wxChar MinimumSegmentLength[] = wxT( "MinimumSegmentLength" );
|
||||
static const wxChar OcePluginLinearDeflection[] = wxT( "OcePluginLinearDeflection" );
|
||||
static const wxChar OcePluginAngularDeflection[] = wxT( "OcePluginAngularDeflection" );
|
||||
static const wxChar TriangulateSimplificationLevel[] = wxT( "TriangulateSimplificationLevel" );
|
||||
static const wxChar TriangulateMinimumArea[] = wxT( "TriangulateMinimumArea" );
|
||||
static const wxChar EnableCacheFriendlyFracture[] = wxT( "EnableCacheFriendlyFracture" );
|
||||
} // namespace KEYS
|
||||
|
||||
|
||||
@@ -248,6 +253,14 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_MinimumSegmentLength = 50;
|
||||
|
||||
m_OcePluginLinearDeflection = 0.14;
|
||||
m_OcePluginAngularDeflection = 30;
|
||||
|
||||
m_TriangulateSimplificationLevel = 50;
|
||||
m_TriangulateMinimumArea = 1000;
|
||||
|
||||
m_EnableCacheFriendlyFracture = true;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@@ -444,6 +457,26 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
&m_MinimumSegmentLength,
|
||||
m_MinimumSegmentLength, 10, 1000 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginLinearDeflection,
|
||||
&m_OcePluginLinearDeflection,
|
||||
m_OcePluginLinearDeflection, 0.01, 1.0 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginAngularDeflection,
|
||||
&m_OcePluginAngularDeflection,
|
||||
m_OcePluginAngularDeflection, 0.01, 360.0 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::TriangulateSimplificationLevel,
|
||||
&m_TriangulateSimplificationLevel,
|
||||
m_TriangulateSimplificationLevel, 0, 1000 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::TriangulateMinimumArea,
|
||||
&m_TriangulateMinimumArea,
|
||||
m_TriangulateMinimumArea, 0, 100000 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableCacheFriendlyFracture,
|
||||
&m_EnableCacheFriendlyFracture,
|
||||
m_EnableCacheFriendlyFracture ) );
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
// Because we even use wxLogTrace inside of advanced config
|
||||
wxString traceMasks;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 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
|
||||
@@ -71,6 +71,13 @@ wxString GetBuildVersion()
|
||||
}
|
||||
|
||||
|
||||
wxString GetBaseVersion()
|
||||
{
|
||||
wxString msg = wxString::Format( wxT( "%s" ), wxT( KICAD_VERSION ) );
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
wxString GetBuildDate()
|
||||
{
|
||||
wxString msg = wxString::Format( wxT( "%s %s" ), wxT( __DATE__ ), wxT( __TIME__ ) );
|
||||
|
||||
@@ -448,7 +448,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
{
|
||||
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
||||
}
|
||||
catch( nanodbc::null_access_error& e )
|
||||
catch( nanodbc::null_access_error& )
|
||||
{
|
||||
// Column was empty (null)
|
||||
aResult[column] = std::string();
|
||||
@@ -498,6 +498,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||
|
||||
aResults.reserve( cacheEntry.size() );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
@@ -605,7 +607,7 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
{
|
||||
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
||||
}
|
||||
catch( nanodbc::null_access_error& e )
|
||||
catch( nanodbc::null_access_error& )
|
||||
{
|
||||
// Column was empty (null)
|
||||
result[column] = std::string();
|
||||
|
||||
@@ -32,6 +32,17 @@
|
||||
const int dblibSchemaVersion = 1;
|
||||
|
||||
|
||||
DATABASE_FIELD_MAPPING::DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName,
|
||||
bool aVisibleOnAdd, bool aVisibleInChooser,
|
||||
bool aShowName, bool aInheritProperties ) :
|
||||
column( aColumn ),
|
||||
name( aName ), name_wx( aName.c_str(), wxConvUTF8 ), visible_on_add( aVisibleOnAdd ),
|
||||
visible_in_chooser( aVisibleInChooser ), show_name( aShowName ),
|
||||
inherit_properties( aInheritProperties )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, dblibSchemaVersion )
|
||||
{
|
||||
@@ -113,11 +124,8 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
|
||||
|
||||
table.fields.emplace_back(
|
||||
DATABASE_FIELD_MAPPING(
|
||||
{
|
||||
column, name, visible_on_add, visible_in_chooser, show_name,
|
||||
inherit
|
||||
} ) );
|
||||
DATABASE_FIELD_MAPPING( column, name, visible_on_add,
|
||||
visible_in_chooser, show_name, inherit ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tomasz Wlostowski" ), LEAD_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jeff Young" ), LEAD_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabien Corona" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dick Hollenbeck" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexis Lockwood" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Sidebotham" ), FORMER_DEV, nullptr ) );
|
||||
@@ -224,13 +225,16 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mikolaj Wielgus" ), FORMER_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Aberg" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yüksel Açikgöz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Rohan Agrawal" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Agricola" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Erik Agsjö" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nabeel Ahmad" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Werner Almesberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Shawn Anastasio" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Collin Anderson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tom Andrews" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Subaru Arai" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mikael Arguedas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lachlan Audas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean-Noel Avila" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -246,16 +250,19 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Bennett" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Roman Beranek" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Francois Berder" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Berglund" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gustav Bergquist" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Cirilo Bernardo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joël Bertrand" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andreas Beutling" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian F. G. Bidulock" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Anton Blanchard" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Steve Bollinger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Blair Bonnett" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Markus Bonk" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Franck Bourdonnec" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Carlo Bramini" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthias Breithaupt" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Brüns" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andreas Buhr" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ryan Bunch" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -271,8 +278,9 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marcus Comstedt" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Diogo Condeco" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Colin Cooper" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabien Corona" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Emile Cormier" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Garth Corral" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Sergio Costas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kevin Cozens" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dan Cross" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -283,11 +291,13 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Albin Dennevi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ruben De Smet" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Dewing" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Okan Demir" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonas Diemer" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ben Dooks" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Pavel Dovgalyuk" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrew Downing" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jan Dubiec" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lucas Dumont" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gerd Egidy" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean Philippe Eimer" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -301,6 +311,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joe Ferner" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Fiete" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Thomas Figueroa" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gilbert J.M. Forkel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vincenzo Fortunato" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Drew Fustini" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -316,6 +327,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jeff Glass" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Golubev" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Angus Gratton" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrea Greco" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Element Green" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mathias Grimmberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johan Grip" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -328,6 +340,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Haas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark Hämmerling" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Hamminga" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ma Han" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Scott Hanson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ben Harris" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lukas F. Hartmann" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -340,7 +353,11 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hans Henry von Tresckow" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Diego Herranz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marco Hess" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "David Holdeman" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Laurens Holst" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yang Hongbo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mario Hros" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Josue Huaroto" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matt Huszagh" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Torsten Hüter" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -351,13 +368,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vlad Ivanov" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andre Iwers" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hasan Jaafar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "James Jackson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jerry Jacobs" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Jacobsen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Michal Jahelka" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Janitschke" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Jara-Almonte" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gilbert J.M. Forkel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Zhuang Jiezhi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "José Jorge Enríquez" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Franck Jullien" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -371,6 +389,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Graham Keeth" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yury Khalyavin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Eldar Khayrullin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Georges Khaznadar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gary Kim" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ingo Kletti" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kliment" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -440,15 +459,18 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jason Oster" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Palazzolo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matus Pavelek" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "luz paz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Miguel Angel Ajo Pelayo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Patrick Pereira" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jacobo Aragunde Perez" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthew Petroff" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Pfister" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabian Pflug" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Pfluger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Piccioni" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nicolas Planel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Paweł Płóciennik" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Carl Poirier" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Reece Pollack" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alain Portal" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -461,6 +483,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Barabas Raffai" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Urja Rannikko" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hendrik v. Raven" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joshua Redstone" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Michele Renda" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean-Samuel Reynaud" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -478,6 +501,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabio Rossi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ian Roth" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Clément Saccoccio" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "J. Morio Sakaguchi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Simon Schaak" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ross Schlaikjer" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -495,6 +519,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yang Sheng" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Chetan Shinde" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Shuklin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Adam Simpkins" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Slawomir Siudym" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marco Serantoni" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Guillaume Simard" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -515,11 +540,15 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Stock" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Stoilov" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hiroki Suenaga" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kuba Sunderland-Ober" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nimish Telang" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Thierer" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Karl Thorén" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hiroshi Tokita" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vladimir Ur" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yon Uriarte" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthias Urlichs" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vladimir Uryvaev" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -527,20 +556,25 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dave Vandenbout" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Edwin van den Oetelaar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark van Doesburg" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nils van Zuijlen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabio Varesano" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Benjamin Vernoux" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Villaro-Dixon" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark Visser" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Forrest Voight" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tormod Volden" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Bartek Wacławik" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Wågen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Oliver Walters" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Warner" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dan Weatherill" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Weber" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Weickhmann" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Bevan Weiss" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Simon Wells" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dominik Wernberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jan Wichmann" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nick Winters" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Adam Wolf" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrzej Wolski" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -617,10 +651,18 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Danish (DA)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Ettore Atalan" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Ivan Chuba" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Julian Daube" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Benedikt Freisen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -633,6 +675,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Johannes Maibaum" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -641,6 +687,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ken Ovo" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Karl Schuh" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Dominik Wernberger" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -687,6 +741,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Gabriel Martinez" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jose Perez" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -721,6 +779,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Finnish (FI)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Toni Laiho" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Finnish (FI)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "J. Lavoie" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -756,6 +818,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Italian (IT)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Subaru Arai" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Japanese (JA)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ji Yoon Choi" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -865,6 +931,10 @@ 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( "KwonHyeokbeom" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -873,6 +943,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "pedrolinharesmoreira" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
@@ -891,6 +965,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Laurens Holst" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Pim Jansen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -899,10 +977,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Bas Wijnen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tom Niesse" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -911,6 +985,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Arend-Jan van Hilten" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Bas Wijnen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jarl Gjessing" ),
|
||||
wxEmptyString,
|
||||
@@ -945,6 +1027,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Eryk Michalak" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Filip Piękoś" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Mark Roszko" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -953,6 +1043,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jan Sobków" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Grzegorz Szymaszek" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1029,6 +1123,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Swedish (SV)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Elias Sjögreen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Swedish (SV)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Boonchai Kingrungped" ),
|
||||
wxEmptyString,
|
||||
@@ -1056,6 +1154,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Ukrainian (UK)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "向阳阳" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "欠陥電気" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Liu Guang" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1076,6 +1182,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Hubert Hu" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Pinpang Liao" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Rigo Ligo" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1084,15 +1198,35 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Zhen Sun" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jason Tan" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "yangyangdaji" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Li Yidong" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tian Yunhao" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Lao Zhu" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "撒景賢" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "David Chen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1105,11 +1239,15 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "William Lin" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Taotieren" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "william" ),
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Li Yidong" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
@@ -1249,6 +1387,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
ICON_CONTRIBUTION ) );
|
||||
aInfo.AddArtist( new CONTRIBUTOR( wxT( "Anda Subero" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
ICON_CONTRIBUTION ) );
|
||||
aInfo.AddArtist( new CONTRIBUTOR( wxT( "Iñigo Zuluaga" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
|
||||
@@ -51,11 +51,30 @@
|
||||
|
||||
|
||||
DIALOG_ABOUT::DIALOG_ABOUT( EDA_BASE_FRAME *aParent, ABOUT_APP_INFO& aAppInfo )
|
||||
: DIALOG_ABOUT_BASE( aParent ), m_info( aAppInfo )
|
||||
: DIALOG_ABOUT_BASE( aParent ),
|
||||
m_images( nullptr ),
|
||||
m_info( aAppInfo )
|
||||
{
|
||||
wxASSERT( aParent != nullptr );
|
||||
|
||||
SetEvtHandlerEnabled( false );
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// HiDPI-aware API; will be generally available in wxWidgets 3.4
|
||||
wxVector<wxBitmapBundle> images;
|
||||
|
||||
images.push_back( KiBitmapBundle( BITMAPS::info ) ); // INFORMATION
|
||||
images.push_back( KiBitmapBundle( BITMAPS::recent ) ); // VERSION
|
||||
images.push_back( KiBitmapBundle( BITMAPS::preference ) ); // DEVELOPERS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::editor ) ); // DOCWRITERS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::library ) ); // LIBRARIANS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::color_materials ) ); // ARTISTS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::language ) ); // TRANSLATORS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::zip ) ); // PACKAGERS
|
||||
images.push_back( KiBitmapBundle( BITMAPS::tools ) ); // LICENSE
|
||||
|
||||
m_notebook->SetImages( images );
|
||||
#else
|
||||
// TODO: Change these to 16x16 versions when available
|
||||
m_images = new wxImageList( 24, 24, false, 9 );
|
||||
|
||||
@@ -70,6 +89,7 @@ DIALOG_ABOUT::DIALOG_ABOUT( EDA_BASE_FRAME *aParent, ABOUT_APP_INFO& aAppInfo )
|
||||
m_images->Add( KiBitmap( BITMAPS::tools ) ); // LICENSE
|
||||
|
||||
m_notebook->SetImageList( m_images );
|
||||
#endif
|
||||
|
||||
if( m_info.GetAppIcon().IsOk() )
|
||||
{
|
||||
@@ -108,7 +128,9 @@ DIALOG_ABOUT::DIALOG_ABOUT( EDA_BASE_FRAME *aParent, ABOUT_APP_INFO& aAppInfo )
|
||||
|
||||
DIALOG_ABOUT::~DIALOG_ABOUT()
|
||||
{
|
||||
#ifndef __WXMAC__
|
||||
delete m_images;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,11 @@ DIALOG_CONFIGURE_PATHS::DIALOG_CONFIGURE_PATHS( wxWindow* aParent ) :
|
||||
m_EnvVars->ClearRows();
|
||||
m_EnvVars->AppendCols( 1 ); // for the isExternal flags
|
||||
m_EnvVars->HideCol( TV_FLAG_COL );
|
||||
#ifndef __WXMAC__
|
||||
// macos crashes on languages at least using non-ascii characters for the column header here of all places
|
||||
// if we use native column headers, so guard it for windows to still look nice
|
||||
m_EnvVars->UseNativeColHeader( true );
|
||||
#endif
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, m_EnvVars, &m_curdir, wxEmptyString ) );
|
||||
|
||||
@@ -57,6 +57,21 @@ DIALOG_GIT_COMMIT::DIALOG_GIT_COMMIT( wxWindow* parent, git_repository* repo,
|
||||
m_listCtrl->SetColumnWidth( 1, 200 );
|
||||
|
||||
// Set up image list for icons
|
||||
#ifdef __WXMAC__
|
||||
// HiDPI-aware API; will be generally available in wxWidgets 3.4
|
||||
wxVector<wxBitmapBundle> stateImages;
|
||||
stateImages.push_back( wxBitmapBundle() ); // GIT_STATUS_UNTRACKED
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_good_check ) ); // GIT_STATUS_CURRENT
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_modified ) ); // GIT_STATUS_MODIFIED
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_add ) ); // GIT_STATUS_ADDED
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_delete ) ); // GIT_STATUS_DELETED
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_out_of_date ) ); // GIT_STATUS_BEHIND
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_changed_ahead ) ); // GIT_STATUS_AHEAD
|
||||
stateImages.push_back( KiBitmapBundle( BITMAPS::git_conflict ) ); // GIT_STATUS_CONFLICTED
|
||||
|
||||
m_listCtrl->SetNormalImages( stateImages );
|
||||
m_listCtrl->SetSmallImages( stateImages );
|
||||
#else
|
||||
wxImageList* imageList = new wxImageList(
|
||||
16, 16, true, static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_LAST ) );
|
||||
|
||||
@@ -71,6 +86,7 @@ DIALOG_GIT_COMMIT::DIALOG_GIT_COMMIT( wxWindow* parent, git_repository* repo,
|
||||
|
||||
// Assign the image list to the list control
|
||||
m_listCtrl->SetImageList( imageList, wxIMAGE_LIST_SMALL );
|
||||
#endif
|
||||
|
||||
// Populate list control with items
|
||||
for( auto& [filename, status] : filesToCommit )
|
||||
|
||||
@@ -37,9 +37,15 @@
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
|
||||
DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository, wxString aURL ) :
|
||||
DIALOG_GIT_REPOSITORY_BASE( aParent ), m_repository( aRepository ), m_prevFile( wxEmptyString ),
|
||||
m_tested( 0 ), m_failedTest( false ), m_testError( wxEmptyString ), m_tempRepo( false ),
|
||||
DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository,
|
||||
wxString aURL ) :
|
||||
DIALOG_GIT_REPOSITORY_BASE( aParent ),
|
||||
m_repository( aRepository ),
|
||||
m_prevFile( wxEmptyString ),
|
||||
m_tested( 0 ),
|
||||
m_failedTest( false ),
|
||||
m_testError( wxEmptyString ),
|
||||
m_tempRepo( false ),
|
||||
m_repoType( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL )
|
||||
{
|
||||
m_txtURL->SetFocus();
|
||||
@@ -90,7 +96,9 @@ bool DIALOG_GIT_REPOSITORY::extractClipboardData()
|
||||
{
|
||||
if( std::get<0>( isValidHTTPS( clipboardText ) )
|
||||
|| std::get<0>( isValidSSH( clipboardText ) ) )
|
||||
{
|
||||
m_txtURL->SetValue( clipboardText );
|
||||
}
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
@@ -362,7 +370,8 @@ void DIALOG_GIT_REPOSITORY::OnFileUpdated( wxFileDirPickerEvent& aEvent )
|
||||
|
||||
if( !isValid )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Invalid SSH Key" ), _( "The selected file is not a valid SSH private key" ) );
|
||||
DisplayErrorMessage( this, _( "Invalid SSH Key" ),
|
||||
_( "The selected file is not a valid SSH private key" ) );
|
||||
CallAfter( [this] { SetRepoSSHPath( m_prevFile ); } );
|
||||
return;
|
||||
}
|
||||
@@ -386,7 +395,8 @@ void DIALOG_GIT_REPOSITORY::OnFileUpdated( wxFileDirPickerEvent& aEvent )
|
||||
|
||||
if( !pubIfs.good() || !pubIfs.is_open() )
|
||||
{
|
||||
DisplayErrorMessage( this, wxString::Format( _( "Could not open public key '%s'" ), file + ".pub" ),
|
||||
DisplayErrorMessage( this, wxString::Format( _( "Could not open public key '%s'" ),
|
||||
file + ".pub" ),
|
||||
wxString::Format( "%s: %d", std::strerror( errno ), errno ) );
|
||||
aEvent.SetPath( wxEmptyString );
|
||||
CallAfter( [this] { SetRepoSSHPath( m_prevFile ); } );
|
||||
@@ -404,19 +414,22 @@ void DIALOG_GIT_REPOSITORY::OnOKClick( wxCommandEvent& event )
|
||||
|
||||
if( m_txtName->GetValue().IsEmpty() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Missing information" ), _( "Please enter a name for the repository" ) );
|
||||
DisplayErrorMessage( this, _( "Missing information" ),
|
||||
_( "Please enter a name for the repository" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_txtURL->GetValue().IsEmpty() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Missing information" ), _( "Please enter a URL for the repository" ) );
|
||||
DisplayErrorMessage( this, _( "Missing information" ),
|
||||
_( "Please enter a URL for the repository" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GIT_REPOSITORY::updateAuthControls()
|
||||
{
|
||||
if( m_ConnType->GetSelection() == static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) )
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
class DIALOG_GIT_REPOSITORY : public DIALOG_GIT_REPOSITORY_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository, wxString aURL = wxEmptyString );
|
||||
DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository,
|
||||
wxString aURL = wxEmptyString );
|
||||
~DIALOG_GIT_REPOSITORY() override;
|
||||
|
||||
void SetTestResult( bool aFailed, const wxString& aError )
|
||||
@@ -47,7 +48,10 @@ public:
|
||||
updateAuthControls();
|
||||
}
|
||||
|
||||
KIGIT_COMMON::GIT_CONN_TYPE GetRepoType() const { return static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() ); }
|
||||
KIGIT_COMMON::GIT_CONN_TYPE GetRepoType() const
|
||||
{
|
||||
return static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() );
|
||||
}
|
||||
|
||||
void SetRepoName( const wxString& aName ) { m_txtName->SetValue( aName ); }
|
||||
wxString GetRepoName() const { return m_txtName->GetValue(); }
|
||||
@@ -106,19 +110,19 @@ private:
|
||||
std::tuple<bool,wxString,wxString,wxString> isValidHTTPS( const wxString& url );
|
||||
std::tuple<bool,wxString, wxString> isValidSSH( const wxString& url );
|
||||
|
||||
private:
|
||||
git_repository* m_repository;
|
||||
|
||||
wxString m_prevFile;
|
||||
wxString m_prevFile;
|
||||
|
||||
unsigned m_tested;
|
||||
bool m_failedTest;
|
||||
wxString m_testError;
|
||||
unsigned m_tested;
|
||||
bool m_failedTest;
|
||||
wxString m_testError;
|
||||
|
||||
bool m_tempRepo;
|
||||
wxString m_tempPath;
|
||||
bool m_tempRepo;
|
||||
wxString m_tempPath;
|
||||
|
||||
KIGIT_COMMON::GIT_CONN_TYPE m_repoType;
|
||||
|
||||
};
|
||||
|
||||
#endif /* DIALOG_GIT_REPOSITORY_H_ */
|
||||
@@ -55,7 +55,7 @@ void PANEL_GIT_REPOS::ResetPanel()
|
||||
m_authorEmail->SetValue( wxEmptyString );
|
||||
}
|
||||
|
||||
static std::pair<wxString, wxString> getDefaultAuthorEmail()
|
||||
static std::pair<wxString, wxString> getDefaultAuthorAndEmail()
|
||||
{
|
||||
wxString name;
|
||||
wxString email;
|
||||
@@ -94,8 +94,8 @@ static std::pair<wxString, wxString> getDefaultAuthorEmail()
|
||||
|
||||
bool PANEL_GIT_REPOS::TransferDataFromWindow()
|
||||
{
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
auto& repos = settings->m_Git.repositories;
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
std::vector<COMMON_SETTINGS::GIT_REPOSITORY>& repos = settings->m_Git.repositories;
|
||||
|
||||
repos.clear();
|
||||
|
||||
@@ -109,7 +109,8 @@ bool PANEL_GIT_REPOS::TransferDataFromWindow()
|
||||
repo.authType = m_grid->GetCellValue( row, COL_AUTH_TYPE );
|
||||
repo.username = m_grid->GetCellValue( row, COL_USERNAME );
|
||||
|
||||
KIPLATFORM::SECRETS::StoreSecret( repo.path, repo.username, m_grid->GetCellValue( row, COL_PASSWORD ) );
|
||||
KIPLATFORM::SECRETS::StoreSecret( repo.path, repo.username,
|
||||
m_grid->GetCellValue( row, COL_PASSWORD ) );
|
||||
repo.ssh_path = m_grid->GetCellValue( row, COL_SSH_PATH );
|
||||
repo.checkValid = m_grid->GetCellValue( row, COL_STATUS ) == "1";
|
||||
repos.push_back( repo );
|
||||
@@ -126,7 +127,8 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
{
|
||||
git_libgit2_init();
|
||||
|
||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
||||
git_remote_callbacks callbacks;
|
||||
callbacks.version = GIT_REMOTE_CALLBACKS_VERSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -134,35 +136,39 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
bool success;
|
||||
} callbacksPayload;
|
||||
|
||||
callbacksPayload cb_data( { &repository, true } ); // If we don't need authentication, then, we are successful
|
||||
callbacksPayload cb_data( { &repository, true } ); // If we don't need authentication, then,
|
||||
// we are successful
|
||||
callbacks.payload = &cb_data;
|
||||
callbacks.credentials = [](git_cred** out, const char* url, const char* username, unsigned int allowed_types, void* payload) -> int {
|
||||
callbacks.credentials =
|
||||
[](git_cred** out, const char* url, const char* username, unsigned int allowed_types,
|
||||
void* payload) -> int
|
||||
{
|
||||
|
||||
// If we are asking for credentials, then, we need authentication
|
||||
// If we are asking for credentials, then, we need authentication
|
||||
|
||||
callbacksPayload* data = static_cast<callbacksPayload*>(payload);
|
||||
callbacksPayload* data = static_cast<callbacksPayload*>(payload);
|
||||
|
||||
data->success = false;
|
||||
data->success = false;
|
||||
|
||||
if( allowed_types & GIT_CREDTYPE_USERNAME )
|
||||
{
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "ssh" && ( allowed_types & GIT_CREDTYPE_SSH_KEY ) )
|
||||
{
|
||||
wxString sshKeyPath = data->repo->ssh_path;
|
||||
if( allowed_types & GIT_CREDTYPE_USERNAME )
|
||||
{
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "ssh" && ( allowed_types & GIT_CREDTYPE_SSH_KEY ) )
|
||||
{
|
||||
wxString sshKeyPath = data->repo->ssh_path;
|
||||
|
||||
// Check if the SSH key exists and is readable
|
||||
if( wxFileExists( sshKeyPath ) && wxFile::Access( sshKeyPath, wxFile::read ) )
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "password" )
|
||||
{
|
||||
data->success = ( allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT );
|
||||
}
|
||||
// Check if the SSH key exists and is readable
|
||||
if( wxFileExists( sshKeyPath ) && wxFile::Access( sshKeyPath, wxFile::read ) )
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "password" )
|
||||
{
|
||||
data->success = ( allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT );
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Create a temporary directory to initialize the Git repository
|
||||
wxString tempDirPath = wxFileName::CreateTempFileName(wxT("kigit_temp"));
|
||||
@@ -177,9 +183,10 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
|
||||
// Initialize the Git repository
|
||||
git_repository* repo = nullptr;
|
||||
int result = git_repository_init(&repo, tempDirPath.mb_str(wxConvUTF8), 0);
|
||||
int result = git_repository_init( &repo, tempDirPath.mb_str( wxConvUTF8 ), 0 );
|
||||
|
||||
if (result != 0) {
|
||||
if (result != 0)
|
||||
{
|
||||
git_repository_free(repo);
|
||||
git_libgit2_shutdown();
|
||||
wxRmdir(tempDirPath);
|
||||
@@ -187,8 +194,10 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
}
|
||||
|
||||
git_remote* remote = nullptr;
|
||||
result = git_remote_create_anonymous(&remote, repo, tempDirPath.mb_str(wxConvUTF8));
|
||||
if (result != 0) {
|
||||
result = git_remote_create_anonymous( &remote, repo, tempDirPath.mb_str( wxConvUTF8 ) );
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
git_remote_free(remote);
|
||||
git_repository_free(repo);
|
||||
git_libgit2_shutdown();
|
||||
@@ -249,7 +258,7 @@ bool PANEL_GIT_REPOS::TransferDataToWindow()
|
||||
|
||||
if( settings->m_Git.useDefaultAuthor )
|
||||
{
|
||||
auto defaultAuthor = getDefaultAuthorEmail();
|
||||
std::pair<wxString, wxString> defaultAuthor = getDefaultAuthorAndEmail();
|
||||
m_author->SetValue( defaultAuthor.first );
|
||||
m_authorEmail->SetValue( defaultAuthor.second );
|
||||
m_author->Disable();
|
||||
|
||||
@@ -71,6 +71,18 @@ PANEL_GRID_SETTINGS::PANEL_GRID_SETTINGS( wxWindow* aParent, UNITS_PROVIDER* aUn
|
||||
m_checkGridOverrideWires->Show( false );
|
||||
m_gridOverrideWiresChoice->Show( false );
|
||||
}
|
||||
|
||||
if( m_frameType == FRAME_GERBER )
|
||||
{
|
||||
m_overridesLabel->Show( false );
|
||||
m_staticline3->Show( false );
|
||||
|
||||
m_checkGridOverrideText->Show( false );
|
||||
m_gridOverrideTextChoice->Show( false );
|
||||
|
||||
m_checkGridOverrideGraphics->Show( false );
|
||||
m_gridOverrideGraphicsChoice->Show( false );
|
||||
}
|
||||
}
|
||||
|
||||
int hk1 = ACTIONS::gridFast1.GetHotKey();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -111,7 +111,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
bSizerRightCol->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
|
||||
|
||||
wxFlexGridSizer* fgGridOverrides;
|
||||
fgGridOverrides = new wxFlexGridSizer( 0, 2, 4, 0 );
|
||||
fgGridOverrides = new wxFlexGridSizer( 0, 2, 5, 0 );
|
||||
fgGridOverrides->AddGrowableCol( 1 );
|
||||
fgGridOverrides->SetFlexibleDirection( wxBOTH );
|
||||
fgGridOverrides->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -122,7 +122,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
wxArrayString m_gridOverrideConnectedChoiceChoices;
|
||||
m_gridOverrideConnectedChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideConnectedChoiceChoices, 0 );
|
||||
m_gridOverrideConnectedChoice->SetSelection( 0 );
|
||||
fgGridOverrides->Add( m_gridOverrideConnectedChoice, 0, wxALL, 5 );
|
||||
fgGridOverrides->Add( m_gridOverrideConnectedChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_checkGridOverrideWires = new wxCheckBox( this, wxID_ANY, _("Wires:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgGridOverrides->Add( m_checkGridOverrideWires, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
|
||||
@@ -130,7 +130,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
wxArrayString m_gridOverrideWiresChoiceChoices;
|
||||
m_gridOverrideWiresChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideWiresChoiceChoices, 0 );
|
||||
m_gridOverrideWiresChoice->SetSelection( 0 );
|
||||
fgGridOverrides->Add( m_gridOverrideWiresChoice, 0, wxALL, 5 );
|
||||
fgGridOverrides->Add( m_gridOverrideWiresChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_checkGridOverrideVias = new wxCheckBox( this, wxID_ANY, _("Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgGridOverrides->Add( m_checkGridOverrideVias, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
|
||||
@@ -138,7 +138,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
wxArrayString m_gridOverrideViasChoiceChoices;
|
||||
m_gridOverrideViasChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideViasChoiceChoices, 0 );
|
||||
m_gridOverrideViasChoice->SetSelection( 0 );
|
||||
fgGridOverrides->Add( m_gridOverrideViasChoice, 0, wxALL, 5 );
|
||||
fgGridOverrides->Add( m_gridOverrideViasChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_checkGridOverrideText = new wxCheckBox( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgGridOverrides->Add( m_checkGridOverrideText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
|
||||
@@ -146,7 +146,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
wxArrayString m_gridOverrideTextChoiceChoices;
|
||||
m_gridOverrideTextChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideTextChoiceChoices, 0 );
|
||||
m_gridOverrideTextChoice->SetSelection( 0 );
|
||||
fgGridOverrides->Add( m_gridOverrideTextChoice, 0, wxALL, 5 );
|
||||
fgGridOverrides->Add( m_gridOverrideTextChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_checkGridOverrideGraphics = new wxCheckBox( this, wxID_ANY, _("Graphics:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgGridOverrides->Add( m_checkGridOverrideGraphics, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
|
||||
@@ -154,7 +154,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
||||
wxArrayString m_gridOverrideGraphicsChoiceChoices;
|
||||
m_gridOverrideGraphicsChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideGraphicsChoiceChoices, 0 );
|
||||
m_gridOverrideGraphicsChoice->SetSelection( 0 );
|
||||
fgGridOverrides->Add( m_gridOverrideGraphicsChoice, 0, wxALL, 5 );
|
||||
fgGridOverrides->Add( m_gridOverrideGraphicsChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizerRightCol->Add( fgGridOverrides, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 10 );
|
||||
|
||||
+1850
-1823
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -121,7 +121,7 @@ wxString DS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
|
||||
|
||||
if( token->IsSameAs( wxT( "KICAD_VERSION" ) ) && PgmOrNull() )
|
||||
{
|
||||
*token = wxString::Format( wxT( "%s %s" ), productName, GetSemanticVersion() );
|
||||
*token = wxString::Format( wxT( "%s %s" ), productName, GetBaseVersion() );
|
||||
tokenUpdated = true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "#" ) ) )
|
||||
|
||||
@@ -483,7 +483,7 @@ void EDA_BASE_FRAME::ReCreateMenuBar()
|
||||
* ensure that they do not occur within the same event handling call stack.
|
||||
*/
|
||||
|
||||
CallAfter( [&]()
|
||||
CallAfter( [this]()
|
||||
{
|
||||
if( !m_isClosing )
|
||||
doReCreateMenuBar();
|
||||
@@ -1202,6 +1202,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_GRIDS ), _( "Grids" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
|
||||
}
|
||||
catch( ... )
|
||||
|
||||
+29
-25
@@ -1955,16 +1955,6 @@ static struct EDA_SHAPE_DESC
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( EDA_SHAPE );
|
||||
|
||||
auto isNotPolygon =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() != SHAPE_T::POLY;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isNotPolygonOrCircle = []( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
@@ -1983,53 +1973,65 @@ static struct EDA_SHAPE_DESC
|
||||
return false;
|
||||
};
|
||||
|
||||
const wxString shapeProps = _HKI( "Shape Properties" );
|
||||
|
||||
auto shape = new PROPERTY_ENUM<EDA_SHAPE, SHAPE_T>( _HKI( "Shape" ),
|
||||
NO_SETTER( EDA_SHAPE, SHAPE_T ), &EDA_SHAPE::GetShape );
|
||||
propMgr.AddProperty( shape );
|
||||
propMgr.AddProperty( shape, shapeProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start X" ),
|
||||
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isNotPolygonOrCircle );
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start Y" ),
|
||||
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isNotPolygonOrCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center X" ),
|
||||
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center Y" ),
|
||||
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Radius" ),
|
||||
&EDA_SHAPE::SetRadius, &EDA_SHAPE::GetRadius, PROPERTY_DISPLAY::PT_SIZE,
|
||||
ORIGIN_TRANSFORMS::NOT_A_COORD ) )
|
||||
ORIGIN_TRANSFORMS::NOT_A_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End X" ),
|
||||
&EDA_SHAPE::SetEndX, &EDA_SHAPE::GetEndX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isNotPolygonOrCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End Y" ),
|
||||
&EDA_SHAPE::SetEndY, &EDA_SHAPE::GetEndY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isNotPolygonOrCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
|
||||
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
|
||||
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ),
|
||||
shapeProps );
|
||||
|
||||
void ( EDA_SHAPE::*lineStyleSetter )( LINE_STYLE ) = &EDA_SHAPE::SetLineStyle;
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>(
|
||||
_HKI( "Line Style" ), lineStyleSetter, &EDA_SHAPE::GetLineStyle ) );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>( _HKI( "Line Style" ),
|
||||
lineStyleSetter, &EDA_SHAPE::GetLineStyle ),
|
||||
shapeProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Line Color" ),
|
||||
&EDA_SHAPE::SetLineColor, &EDA_SHAPE::GetLineColor ) )
|
||||
&EDA_SHAPE::SetLineColor, &EDA_SHAPE::GetLineColor ),
|
||||
shapeProps )
|
||||
.SetIsHiddenFromRulesEditor();
|
||||
|
||||
auto angle = new PROPERTY<EDA_SHAPE, EDA_ANGLE>( _HKI( "Angle" ),
|
||||
@@ -2043,7 +2045,7 @@ static struct EDA_SHAPE_DESC
|
||||
|
||||
return false;
|
||||
} );
|
||||
propMgr.AddProperty( angle );
|
||||
propMgr.AddProperty( angle, shapeProps );
|
||||
|
||||
auto fillAvailable =
|
||||
[=]( INSPECTABLE* aItem ) -> bool
|
||||
@@ -2066,11 +2068,13 @@ static struct EDA_SHAPE_DESC
|
||||
};
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, bool>( _HKI( "Filled" ),
|
||||
&EDA_SHAPE::SetFilled, &EDA_SHAPE::IsFilled ) )
|
||||
&EDA_SHAPE::SetFilled, &EDA_SHAPE::IsFilled ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( fillAvailable );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Fill Color" ),
|
||||
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor ) )
|
||||
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( fillAvailable )
|
||||
.SetIsHiddenFromRulesEditor();
|
||||
}
|
||||
|
||||
+7
-7
@@ -364,8 +364,8 @@ void EDA_TEXT::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
|
||||
|
||||
if( aEnforceMinTextSize )
|
||||
{
|
||||
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
|
||||
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
|
||||
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
|
||||
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
|
||||
|
||||
aNewSize = VECTOR2I( alg::clamp( min, aNewSize.x, max ),
|
||||
alg::clamp( min, aNewSize.y, max ) );
|
||||
@@ -380,8 +380,8 @@ void EDA_TEXT::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
|
||||
|
||||
void EDA_TEXT::SetTextWidth( int aWidth )
|
||||
{
|
||||
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
|
||||
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
|
||||
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
|
||||
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
|
||||
|
||||
m_attributes.m_Size.x = alg::clamp( min, aWidth, max );
|
||||
ClearRenderCache();
|
||||
@@ -391,8 +391,8 @@ void EDA_TEXT::SetTextWidth( int aWidth )
|
||||
|
||||
void EDA_TEXT::SetTextHeight( int aHeight )
|
||||
{
|
||||
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
|
||||
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
|
||||
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
|
||||
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
|
||||
|
||||
m_attributes.m_Size.y = alg::clamp( min, aHeight, max );
|
||||
ClearRenderCache();
|
||||
@@ -1176,7 +1176,7 @@ static struct EDA_TEXT_DESC
|
||||
&EDA_TEXT::SetTextAngleDegrees, &EDA_TEXT::GetTextAngleDegrees,
|
||||
PROPERTY_DISPLAY::PT_DEGREE ) );
|
||||
|
||||
const wxString textProps = _( "Text Properties" );
|
||||
const wxString textProps = _HKI( "Text Properties" );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _HKI( "Text" ),
|
||||
&EDA_TEXT::SetText, &EDA_TEXT::GetText ),
|
||||
|
||||
+48
-15
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 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
|
||||
@@ -28,6 +28,22 @@
|
||||
#include <charconv>
|
||||
#include <wx/translation.h>
|
||||
|
||||
|
||||
static void removeTrailingZeros( wxString& aText )
|
||||
{
|
||||
int len = aText.length();
|
||||
int removeLast = 0;
|
||||
|
||||
while( --len > 0 && aText[len] == '0' )
|
||||
removeLast++;
|
||||
|
||||
if( len >= 0 && ( aText[len] == '.' || aText[len] == ',' ) )
|
||||
removeLast++;
|
||||
|
||||
aText = aText.RemoveLast( removeLast );
|
||||
}
|
||||
|
||||
|
||||
bool EDA_UNIT_UTILS::IsImperialUnit( EDA_UNITS aUnit )
|
||||
{
|
||||
switch( aUnit )
|
||||
@@ -305,29 +321,46 @@ wxString EDA_UNIT_UTILS::UI::StringFromValue( const EDA_IU_SCALE& aIuScale, EDA_
|
||||
break;
|
||||
}
|
||||
|
||||
char buf[50];
|
||||
const wxChar* format = nullptr;
|
||||
|
||||
if( value_to_print != 0.0 && fabs( value_to_print ) <= 0.0001 )
|
||||
switch( aUnits )
|
||||
{
|
||||
int len = snprintf( buf, sizeof( buf ) - 1, "%.10f", value_to_print );
|
||||
|
||||
while( --len > 0 && buf[len] == '0' )
|
||||
buf[len] = '\0';
|
||||
case EDA_UNITS::MILS:
|
||||
#if defined( EESCHEMA )
|
||||
format = wxT( "%.3f" );
|
||||
#else
|
||||
format = wxT( "%.5f" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
if( len >= 0 && ( buf[len] == '.' || buf[len] == ',' ) )
|
||||
buf[len] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( buf, sizeof( buf ) - 1, "%.10g", value_to_print );
|
||||
case EDA_UNITS::INCHES:
|
||||
#if defined( EESCHEMA )
|
||||
format = wxT( "%.6f" );
|
||||
#else
|
||||
format = wxT( "%.8f" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
format = wxT( "%.10f" );
|
||||
break;
|
||||
}
|
||||
|
||||
wxString stringValue( buf, wxConvUTF8 );
|
||||
wxString text;
|
||||
text.Printf( format, value_to_print );
|
||||
removeTrailingZeros( text );
|
||||
|
||||
if( value_to_print != 0.0 && ( text == wxS( "0" ) || text == wxS( "-0" ) ) )
|
||||
{
|
||||
text.Printf( wxS( "%.10f" ), value_to_print );
|
||||
removeTrailingZeros( text );
|
||||
}
|
||||
|
||||
if( aAddUnitsText )
|
||||
stringValue += EDA_UNIT_UTILS::GetText( aUnits, aType );
|
||||
text << EDA_UNIT_UTILS::GetText( aUnits, aType );
|
||||
|
||||
return stringValue;
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ void IO_ERROR::init( const wxString& aProblem, const char* aThrowersFile,
|
||||
// a short filename will be printed (it is better for user, the full filename has no meaning).
|
||||
wxString srcname = aThrowersFile;
|
||||
|
||||
where.Printf( _( "from %s : %s() line %d" ),
|
||||
// No need for translations of source code file/line messages (and wxWidget's translation
|
||||
// stuff has bitten us before. May be related to KICAD-YP.
|
||||
where.Printf( wxS( "from %s : %s() line %d" ),
|
||||
srcname.AfterLast( '/' ),
|
||||
wxString( aThrowersFunction ),
|
||||
aThrowersLineNumber );
|
||||
@@ -87,7 +89,9 @@ void PARSE_ERROR::init( const wxString& aProblem, const char* aThrowersFile,
|
||||
// a short filename will be printed (it is better for user, the full filename has no meaning).
|
||||
wxString srcname = aThrowersFile;
|
||||
|
||||
where.Printf( _( "from %s : %s() line:%d" ),
|
||||
// No need for translations of source code file/line messages (and wxWidget's translation
|
||||
// stuff has bitten us before. May be related to KICAD-YP.
|
||||
where.Printf( wxS( "from %s : %s() line %d" ),
|
||||
srcname.AfterLast( '/' ),
|
||||
wxString( aThrowersFunction ),
|
||||
aThrowersLineNumber );
|
||||
|
||||
+44
-8
@@ -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-2024 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
|
||||
@@ -82,19 +82,19 @@ std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons
|
||||
end.x *= aGlyphSize.x;
|
||||
end.y *= aGlyphSize.y;
|
||||
|
||||
if( aTilt )
|
||||
if( aTilt != 0.0 )
|
||||
end.x -= end.y * aTilt;
|
||||
|
||||
glyph->m_boundingBox.SetEnd( end );
|
||||
glyph->m_boundingBox.Offset( aOffset );
|
||||
|
||||
for( std::vector<VECTOR2D>& pointList : *glyph.get() )
|
||||
for( std::vector<VECTOR2D>& pointList : *glyph )
|
||||
{
|
||||
for( VECTOR2D& point : pointList )
|
||||
{
|
||||
point *= aGlyphSize;
|
||||
|
||||
if( aTilt )
|
||||
if( aTilt != 0.0 )
|
||||
point.x -= point.y * aTilt;
|
||||
|
||||
point += aOffset;
|
||||
@@ -111,6 +111,18 @@ std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons
|
||||
}
|
||||
|
||||
|
||||
void STROKE_GLYPH::Move( const VECTOR2I& aOffset )
|
||||
{
|
||||
m_boundingBox.Offset( aOffset );
|
||||
|
||||
for( std::vector<VECTOR2D>& pointList : *this )
|
||||
{
|
||||
for( VECTOR2D& point : pointList )
|
||||
point += aOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOX2D OUTLINE_GLYPH::BoundingBox()
|
||||
{
|
||||
BOX2I bbox = BBox();
|
||||
@@ -122,10 +134,7 @@ void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
|
||||
const VECTOR2I& aPt2,
|
||||
const VECTOR2I& aPt3 )> aCallback ) const
|
||||
{
|
||||
// Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
|
||||
// the triangulation to see if it has been edited, and glyphs after creation are read-only.
|
||||
if( TriangulatedPolyCount() == 0 )
|
||||
const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
|
||||
const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
|
||||
|
||||
for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
|
||||
{
|
||||
@@ -141,3 +150,30 @@ void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
|
||||
}
|
||||
|
||||
|
||||
void OUTLINE_GLYPH::CacheTriangulation( bool aPartition, bool aSimplify )
|
||||
{
|
||||
// Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
|
||||
// the triangulation to see if it has been edited, and glyphs are invariant after creation.
|
||||
//
|
||||
// Also forces "partition" to false as we never want to partition a glyph.
|
||||
|
||||
if( TriangulatedPolyCount() == 0 )
|
||||
SHAPE_POLY_SET::CacheTriangulation( false, aSimplify );
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> OUTLINE_GLYPH::GetTriangulationData() const
|
||||
{
|
||||
std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> data;
|
||||
|
||||
for( const std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>& poly : m_triangulatedPolys )
|
||||
data.push_back( std::make_unique<SHAPE_POLY_SET::TRIANGULATED_POLYGON>( *poly ) );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void OUTLINE_GLYPH::CacheTriangulation( std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>>& aHintData )
|
||||
{
|
||||
cacheTriangulation( false, false, &aHintData );
|
||||
}
|
||||
|
||||
@@ -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 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2024 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Outline font class
|
||||
*
|
||||
@@ -39,8 +39,8 @@ OUTLINE_DECOMPOSER::OUTLINE_DECOMPOSER( FT_Outline& aOutline ) :
|
||||
|
||||
static VECTOR2D toVector2D( const FT_Vector* aFreeTypeVector )
|
||||
{
|
||||
return VECTOR2D( aFreeTypeVector->x * GLYPH_SIZE_SCALER,
|
||||
aFreeTypeVector->y * GLYPH_SIZE_SCALER );
|
||||
return VECTOR2D( (double) aFreeTypeVector->x * GLYPH_SIZE_SCALER,
|
||||
(double) aFreeTypeVector->y * GLYPH_SIZE_SCALER );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2024 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
|
||||
@@ -255,6 +255,38 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
|
||||
struct GLYPH_CACHE_KEY {
|
||||
FT_Face face;
|
||||
hb_codepoint_t codepoint;
|
||||
bool fakeItalic;
|
||||
bool fakeBold;
|
||||
bool mirror;
|
||||
EDA_ANGLE angle;
|
||||
|
||||
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
|
||||
{
|
||||
return face == rhs.face && codepoint == rhs.codepoint
|
||||
&& fakeItalic == rhs.fakeItalic && fakeBold == rhs.fakeBold
|
||||
&& mirror == rhs.mirror && angle == rhs.angle;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<GLYPH_CACHE_KEY>
|
||||
{
|
||||
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
|
||||
{
|
||||
return hash<const void*>()( k.face ) ^ hash<unsigned>()( k.codepoint )
|
||||
^ hash<int>()( k.fakeItalic ) ^ hash<int>()( k.fakeBold )
|
||||
^ hash<int>()( k.mirror ) ^ hash<int>()( k.angle.AsTenthsOfADegree() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
@@ -295,6 +327,10 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
if( aGlyphs )
|
||||
aGlyphs->reserve( glyphCount );
|
||||
|
||||
// GLYPH_DATA is a collection of all outlines in the glyph; for example the 'o' glyph
|
||||
// generally contains 2 contours, one for the glyph outline and one for the hole
|
||||
static std::unordered_map<GLYPH_CACHE_KEY, GLYPH_DATA> s_glyphCache;
|
||||
|
||||
for( unsigned int i = 0; i < glyphCount; i++ )
|
||||
{
|
||||
// Don't process glyphs that were already included in a previous cluster
|
||||
@@ -303,64 +339,67 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
if( m_fakeItal )
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, m_fakeItal, m_fakeBold,
|
||||
aMirror, aAngle };
|
||||
GLYPH_DATA& glyphData = s_glyphCache[ key ];
|
||||
|
||||
if( glyphData.m_Contours.empty() )
|
||||
{
|
||||
FT_Matrix matrix;
|
||||
// Create a 12 degree slant
|
||||
const float angle = (float)( -M_PI * 12.0f ) / 180.0f;
|
||||
matrix.xx = (FT_Fixed) ( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed) ( -sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
matrix.yy = (FT_Fixed) ( 1 * 0x10000L );
|
||||
if( m_fakeItal )
|
||||
{
|
||||
FT_Matrix matrix;
|
||||
// Create a 12 degree slant
|
||||
const float angle = (float)( -M_PI * 12.0f ) / 180.0f;
|
||||
matrix.xx = (FT_Fixed) ( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed) ( -sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
matrix.yy = (FT_Fixed) ( 1 * 0x10000L );
|
||||
|
||||
FT_Set_Transform( face, &matrix, 0 );
|
||||
}
|
||||
FT_Set_Transform( face, &matrix, nullptr );
|
||||
}
|
||||
|
||||
FT_Load_Glyph( face, glyphInfo[i].codepoint, FT_LOAD_NO_BITMAP );
|
||||
FT_Load_Glyph( face, glyphInfo[i].codepoint, FT_LOAD_NO_BITMAP );
|
||||
|
||||
if( m_fakeBold )
|
||||
FT_Outline_Embolden( &face->glyph->outline, 1 << 6 );
|
||||
if( m_fakeBold )
|
||||
FT_Outline_Embolden( &face->glyph->outline, 1 << 6 );
|
||||
|
||||
// contours is a collection of all outlines in the glyph; for example the 'o' glyph
|
||||
// generally contains 2 contours, one for the glyph outline and one for the hole
|
||||
std::vector<CONTOUR> contours;
|
||||
OUTLINE_DECOMPOSER decomposer( face->glyph->outline );
|
||||
|
||||
OUTLINE_DECOMPOSER decomposer( face->glyph->outline );
|
||||
if( !decomposer.OutlineToSegments( &glyphData.m_Contours ) )
|
||||
{
|
||||
double hb_advance = glyphPos[i].x_advance * GLYPH_SIZE_SCALER;
|
||||
BOX2D tofuBox( { scaler * 0.03, 0.0 },
|
||||
{ hb_advance - scaler * 0.02, scaler * 0.72 } );
|
||||
|
||||
if( !decomposer.OutlineToSegments( &contours ) )
|
||||
{
|
||||
double hb_advance = glyphPos[i].x_advance * GLYPH_SIZE_SCALER;
|
||||
BOX2D tofuBox( { scaler * 0.03, 0.0 },
|
||||
{ hb_advance - scaler * 0.02, scaler * 0.72 } );
|
||||
glyphData.m_Contours.clear();
|
||||
|
||||
contours.clear();
|
||||
CONTOUR outline;
|
||||
outline.m_Winding = 1;
|
||||
outline.m_Orientation = FT_ORIENTATION_TRUETYPE;
|
||||
outline.m_Points.push_back( tofuBox.GetPosition() );
|
||||
outline.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
outline.m_Points.push_back( tofuBox.GetSize() );
|
||||
outline.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
glyphData.m_Contours.push_back( outline );
|
||||
|
||||
CONTOUR outline;
|
||||
outline.m_Winding = 1;
|
||||
outline.m_Orientation = FT_ORIENTATION_TRUETYPE;
|
||||
outline.m_Points.push_back( tofuBox.GetPosition() );
|
||||
outline.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
outline.m_Points.push_back( tofuBox.GetSize() );
|
||||
outline.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
contours.push_back( outline );
|
||||
|
||||
CONTOUR hole;
|
||||
tofuBox.Move( { scaler * 0.06, scaler * 0.06 } );
|
||||
tofuBox.SetSize( { tofuBox.GetWidth() - scaler * 0.06,
|
||||
tofuBox.GetHeight() - scaler * 0.06 } );
|
||||
hole.m_Winding = 1;
|
||||
hole.m_Orientation = FT_ORIENTATION_NONE;
|
||||
hole.m_Points.push_back( tofuBox.GetPosition() );
|
||||
hole.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
hole.m_Points.push_back( tofuBox.GetSize() );
|
||||
hole.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
contours.push_back( hole );
|
||||
CONTOUR hole;
|
||||
tofuBox.Move( { scaler * 0.06, scaler * 0.06 } );
|
||||
tofuBox.SetSize( { tofuBox.GetWidth() - scaler * 0.06,
|
||||
tofuBox.GetHeight() - scaler * 0.06 } );
|
||||
hole.m_Winding = 1;
|
||||
hole.m_Orientation = FT_ORIENTATION_NONE;
|
||||
hole.m_Points.push_back( tofuBox.GetPosition() );
|
||||
hole.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
hole.m_Points.push_back( tofuBox.GetSize() );
|
||||
hole.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
glyphData.m_Contours.push_back( hole );
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<OUTLINE_GLYPH> glyph = std::make_unique<OUTLINE_GLYPH>();
|
||||
std::vector<SHAPE_LINE_CHAIN> holes;
|
||||
|
||||
for( CONTOUR& c : contours )
|
||||
for( CONTOUR& c : glyphData.m_Contours )
|
||||
{
|
||||
std::vector<VECTOR2D> points = c.m_Points;
|
||||
SHAPE_LINE_CHAIN shape;
|
||||
@@ -411,6 +450,16 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
}
|
||||
}
|
||||
|
||||
if( glyphData.m_TriangulationData.empty() )
|
||||
{
|
||||
glyph->CacheTriangulation( false, false );
|
||||
glyphData.m_TriangulationData = glyph->GetTriangulationData();
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->CacheTriangulation( glyphData.m_TriangulationData );
|
||||
}
|
||||
|
||||
aGlyphs->push_back( std::move( glyph ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -327,8 +327,9 @@ const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname, bool a
|
||||
|
||||
if( !row )
|
||||
{
|
||||
wxString msg = wxString::Format( _( "fp-lib-table files contain no library named '%s'." ),
|
||||
aNickname );
|
||||
// We don't generally show this string to the user (who is unlikely to know what
|
||||
// "fp-lib-table" means), and translating it may produce Sentry KICAD-YP.
|
||||
wxString msg = wxString::Format( wxS( "'%s' not found in fp-lib-table." ), aNickname );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
|
||||
unsigned int CAIRO_COMPOSITOR::CreateBuffer()
|
||||
{
|
||||
// Pixel storage
|
||||
BitmapPtr bitmap = new uint32_t[m_bufferSize]();
|
||||
BitmapPtr bitmap = new uint8_t[m_bufferSize]();
|
||||
|
||||
// Create the Cairo surface
|
||||
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
||||
@@ -138,7 +138,7 @@ void CAIRO_COMPOSITOR::Begin()
|
||||
void CAIRO_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
||||
{
|
||||
// Clear the pixel storage
|
||||
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize * sizeof( int ) );
|
||||
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1413,20 +1413,34 @@ void CAIRO_GAL::EndDrawing()
|
||||
|
||||
// Now translate the raw context data from the format stored
|
||||
// by cairo into a format understood by wxImage.
|
||||
pixman_image_t* dstImg = pixman_image_create_bits(
|
||||
wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8
|
||||
: PIXMAN_r8g8b8,
|
||||
m_screenSize.x, m_screenSize.y, (uint32_t*) m_wxOutput, m_wxBufferWidth * 3 );
|
||||
pixman_image_t* srcImg =
|
||||
pixman_image_create_bits( PIXMAN_a8r8g8b8, m_screenSize.x, m_screenSize.y,
|
||||
(uint32_t*) m_bitmapBuffer, m_wxBufferWidth * 4 );
|
||||
int height = m_screenSize.y;
|
||||
int stride = m_stride;
|
||||
|
||||
pixman_image_composite( PIXMAN_OP_SRC, srcImg, nullptr, dstImg, 0, 0, 0, 0, 0, 0,
|
||||
m_screenSize.x, m_screenSize.y );
|
||||
unsigned char* srcRow = m_bitmapBuffer;
|
||||
unsigned char* dst = m_wxOutput;
|
||||
|
||||
// Free allocated memory
|
||||
pixman_image_unref( srcImg );
|
||||
pixman_image_unref( dstImg );
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
for( int x = 0; x < stride; x += 4 )
|
||||
{
|
||||
const unsigned char* src = srcRow + x;
|
||||
|
||||
#if defined( __BYTE_ORDER__ ) && ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
|
||||
// XRGB
|
||||
dst[0] = src[1];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[3];
|
||||
#else
|
||||
// BGRX
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
#endif
|
||||
dst += 3;
|
||||
}
|
||||
|
||||
srcRow += stride;
|
||||
}
|
||||
|
||||
wxImage img( m_wxBufferWidth, m_screenSize.y, m_wxOutput, true );
|
||||
wxBitmap bmp( img );
|
||||
@@ -1582,15 +1596,12 @@ void CAIRO_GAL::allocateBitmaps()
|
||||
{
|
||||
m_wxBufferWidth = m_screenSize.x;
|
||||
|
||||
while( ( ( m_wxBufferWidth * 3 ) % 4 ) != 0 )
|
||||
m_wxBufferWidth++;
|
||||
|
||||
// Create buffer, use the system independent Cairo context backend
|
||||
m_stride = cairo_format_stride_for_width( GAL_FORMAT, m_wxBufferWidth );
|
||||
m_bufferSize = m_stride * m_screenSize.y;
|
||||
|
||||
wxASSERT( m_bitmapBuffer == nullptr );
|
||||
m_bitmapBuffer = new unsigned char[m_bufferSize * 4];
|
||||
m_bitmapBuffer = new unsigned char[m_bufferSize];
|
||||
|
||||
wxASSERT( m_wxOutput == nullptr );
|
||||
m_wxOutput = new unsigned char[m_wxBufferWidth * 3 * m_screenSize.y];
|
||||
|
||||
@@ -185,7 +185,11 @@ void ANTIALIASING_SUPERSAMPLING::Present()
|
||||
glBindTexture( GL_TEXTURE_2D, compositor->GetBufferTexture( ssaaMainBuffer ) );
|
||||
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
|
||||
|
||||
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
|
||||
|
||||
draw_fullscreen_primitive();
|
||||
|
||||
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
}
|
||||
|
||||
|
||||
@@ -547,7 +551,11 @@ void ANTIALIASING_SMAA::Present()
|
||||
glActiveTexture( GL_TEXTURE1 );
|
||||
glBindTexture( GL_TEXTURE_2D, blendTex );
|
||||
|
||||
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
|
||||
|
||||
pass_3_shader->Use();
|
||||
draw_fullscreen_triangle();
|
||||
pass_3_shader->Deactivate();
|
||||
|
||||
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ void OPENGL_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
||||
{
|
||||
wxASSERT( m_initialized );
|
||||
|
||||
glClearColor( aColor.r, aColor.g, aColor.b, 0.0f );
|
||||
glClearColor( aColor.r, aColor.g, aColor.b, m_curFbo == DIRECT_RENDERING ? 1.0f : 0.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||
}
|
||||
|
||||
|
||||
@@ -1005,11 +1005,20 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
|
||||
VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
|
||||
double alpha;
|
||||
unsigned int lineCount = 0;
|
||||
|
||||
for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
|
||||
lineCount++;
|
||||
|
||||
if( alpha != endAngle )
|
||||
lineCount++;
|
||||
|
||||
reserveLineQuads( lineCount );
|
||||
|
||||
for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
|
||||
{
|
||||
VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
|
||||
DrawLine( p, p_next );
|
||||
drawLineQuad( p, p_next, false );
|
||||
|
||||
p = p_next;
|
||||
}
|
||||
@@ -1018,7 +1027,7 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
if( alpha != endAngle )
|
||||
{
|
||||
VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
|
||||
DrawLine( p, p_last );
|
||||
drawLineQuad( p, p_last, false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1058,9 +1067,21 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
if( seg_count % 2 != 0 )
|
||||
seg_count += 1;
|
||||
|
||||
// Our shaders have trouble rendering null line quads, so delegate this task to DrawSegment.
|
||||
if( seg_count == 0 )
|
||||
{
|
||||
VECTOR2D p_start( aCenterPoint.x + cos( startAngle ) * aRadius,
|
||||
aCenterPoint.y + sin( startAngle ) * aRadius );
|
||||
|
||||
VECTOR2D p_end( aCenterPoint.x + cos( endAngle ) * aRadius,
|
||||
aCenterPoint.y + sin( endAngle ) * aRadius );
|
||||
|
||||
DrawSegment( p_start, p_end, aWidth );
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate alphaIncrement with a even integer number of segment
|
||||
if( seg_count )
|
||||
alphaIncrement = ( endAngle - startAngle ) / seg_count;
|
||||
alphaIncrement = ( endAngle - startAngle ) / seg_count;
|
||||
|
||||
Save();
|
||||
m_currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0 );
|
||||
@@ -2891,30 +2912,9 @@ void OPENGL_GAL::DrawGlyphs( const std::vector<std::unique_ptr<KIFONT::GLYPH>>&
|
||||
}
|
||||
else if( allGlyphsAreOutline )
|
||||
{
|
||||
// Optimized path for stroke fonts that pre-reserves glyph triangles.
|
||||
// Optimized path for outline fonts that pre-reserves glyph triangles.
|
||||
int triangleCount = 0;
|
||||
|
||||
if( aGlyphs.size() > 0 )
|
||||
{
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_loop( aGlyphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
{
|
||||
auto glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( aGlyphs.at( ii ).get() );
|
||||
|
||||
// Only call CacheTriangulation() if it has never been done before.
|
||||
// Otherwise we'll hash the triangulation to see if it has been edited,
|
||||
// and all our glpyh editing ops update the triangulation anyway.
|
||||
if( glyph->TriangulatedPolyCount() == 0 )
|
||||
glyph->CacheTriangulation( false );
|
||||
}
|
||||
} );
|
||||
tp.wait_for_tasks();
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
|
||||
{
|
||||
const auto& outlineGlyph = static_cast<const KIFONT::OUTLINE_GLYPH&>( *glyph );
|
||||
|
||||
@@ -444,7 +444,7 @@ void GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
break;
|
||||
|
||||
default:
|
||||
if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE )
|
||||
if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE && m_grid->CommitPendingChanges( false ) )
|
||||
{
|
||||
int col = menu_id - GRIDTRICKS_FIRST_SHOWHIDE;
|
||||
|
||||
|
||||
@@ -32,14 +32,18 @@
|
||||
class PSEUDO_ACTION : public TOOL_ACTION
|
||||
{
|
||||
public:
|
||||
PSEUDO_ACTION( const wxString& aLabel, int aHotKey )
|
||||
PSEUDO_ACTION( const wxString& aLabel, int aHotKey, int aHotKeyAlt = 0 )
|
||||
{
|
||||
m_friendlyName = aLabel;
|
||||
m_hotKey = aHotKey;
|
||||
m_hotKeyAlt = aHotKeyAlt;
|
||||
}
|
||||
};
|
||||
|
||||
static PSEUDO_ACTION* g_gesturePseudoActions[] = {
|
||||
new PSEUDO_ACTION( _( "Accept Autocomplete" ), WXK_RETURN, WXK_NUMPAD_ENTER ),
|
||||
new PSEUDO_ACTION( _( "Cancel Autocomplete" ), WXK_ESCAPE ),
|
||||
new PSEUDO_ACTION( _( "Toggle Checkbox" ), WXK_SPACE ),
|
||||
new PSEUDO_ACTION( _( "Pan Left/Right" ), MD_CTRL + PSEUDO_WXK_WHEEL ),
|
||||
new PSEUDO_ACTION( _( "Pan Up/Down" ), MD_SHIFT + PSEUDO_WXK_WHEEL ),
|
||||
new PSEUDO_ACTION( _( "Finish Drawing" ), PSEUDO_WXK_DBLCLICK ),
|
||||
|
||||
+64
-63
@@ -63,79 +63,80 @@ struct hotkey_name_descr
|
||||
#define KEY_NON_FOUND -1
|
||||
static struct hotkey_name_descr hotkeyNameList[] =
|
||||
{
|
||||
{ wxT( "F1" ), WXK_F1 },
|
||||
{ wxT( "F2" ), WXK_F2 },
|
||||
{ wxT( "F3" ), WXK_F3 },
|
||||
{ wxT( "F4" ), WXK_F4 },
|
||||
{ wxT( "F5" ), WXK_F5 },
|
||||
{ wxT( "F6" ), WXK_F6 },
|
||||
{ wxT( "F7" ), WXK_F7 },
|
||||
{ wxT( "F8" ), WXK_F8 },
|
||||
{ wxT( "F9" ), WXK_F9 },
|
||||
{ wxT( "F10" ), WXK_F10 },
|
||||
{ wxT( "F11" ), WXK_F11 },
|
||||
{ wxT( "F12" ), WXK_F12 },
|
||||
{ wxT( "F13" ), WXK_F13 },
|
||||
{ wxT( "F14" ), WXK_F14 },
|
||||
{ wxT( "F15" ), WXK_F15 },
|
||||
{ wxT( "F16" ), WXK_F16 },
|
||||
{ wxT( "F17" ), WXK_F17 },
|
||||
{ wxT( "F18" ), WXK_F18 },
|
||||
{ wxT( "F19" ), WXK_F19 },
|
||||
{ wxT( "F20" ), WXK_F20 },
|
||||
{ wxT( "F21" ), WXK_F21 },
|
||||
{ wxT( "F22" ), WXK_F22 },
|
||||
{ wxT( "F23" ), WXK_F23 },
|
||||
{ wxT( "F24" ), WXK_F24 },
|
||||
{ wxT( "F1" ), WXK_F1 },
|
||||
{ wxT( "F2" ), WXK_F2 },
|
||||
{ wxT( "F3" ), WXK_F3 },
|
||||
{ wxT( "F4" ), WXK_F4 },
|
||||
{ wxT( "F5" ), WXK_F5 },
|
||||
{ wxT( "F6" ), WXK_F6 },
|
||||
{ wxT( "F7" ), WXK_F7 },
|
||||
{ wxT( "F8" ), WXK_F8 },
|
||||
{ wxT( "F9" ), WXK_F9 },
|
||||
{ wxT( "F10" ), WXK_F10 },
|
||||
{ wxT( "F11" ), WXK_F11 },
|
||||
{ wxT( "F12" ), WXK_F12 },
|
||||
{ wxT( "F13" ), WXK_F13 },
|
||||
{ wxT( "F14" ), WXK_F14 },
|
||||
{ wxT( "F15" ), WXK_F15 },
|
||||
{ wxT( "F16" ), WXK_F16 },
|
||||
{ wxT( "F17" ), WXK_F17 },
|
||||
{ wxT( "F18" ), WXK_F18 },
|
||||
{ wxT( "F19" ), WXK_F19 },
|
||||
{ wxT( "F20" ), WXK_F20 },
|
||||
{ wxT( "F21" ), WXK_F21 },
|
||||
{ wxT( "F22" ), WXK_F22 },
|
||||
{ wxT( "F23" ), WXK_F23 },
|
||||
{ wxT( "F24" ), WXK_F24 },
|
||||
|
||||
{ wxT( "Esc" ), WXK_ESCAPE },
|
||||
{ wxT( "Del" ), WXK_DELETE },
|
||||
{ wxT( "Tab" ), WXK_TAB },
|
||||
{ wxT( "Back" ), WXK_BACK },
|
||||
{ wxT( "Ins" ), WXK_INSERT },
|
||||
{ wxT( "Esc" ), WXK_ESCAPE },
|
||||
{ wxT( "Del" ), WXK_DELETE },
|
||||
{ wxT( "Tab" ), WXK_TAB },
|
||||
{ wxT( "Back" ), WXK_BACK },
|
||||
{ wxT( "Ins" ), WXK_INSERT },
|
||||
|
||||
{ wxT( "Home" ), WXK_HOME },
|
||||
{ wxT( "End" ), WXK_END },
|
||||
{ wxT( "PgUp" ), WXK_PAGEUP },
|
||||
{ wxT( "PgDn" ), WXK_PAGEDOWN },
|
||||
{ wxT( "Home" ), WXK_HOME },
|
||||
{ wxT( "End" ), WXK_END },
|
||||
{ wxT( "PgUp" ), WXK_PAGEUP },
|
||||
{ wxT( "PgDn" ), WXK_PAGEDOWN },
|
||||
|
||||
{ wxT( "Up" ), WXK_UP },
|
||||
{ wxT( "Down" ), WXK_DOWN },
|
||||
{ wxT( "Left" ), WXK_LEFT },
|
||||
{ wxT( "Right" ), WXK_RIGHT },
|
||||
{ wxT( "Up" ), WXK_UP },
|
||||
{ wxT( "Down" ), WXK_DOWN },
|
||||
{ wxT( "Left" ), WXK_LEFT },
|
||||
{ wxT( "Right" ), WXK_RIGHT },
|
||||
|
||||
{ wxT( "Return" ), WXK_RETURN },
|
||||
{ wxT( "Return" ), WXK_RETURN },
|
||||
|
||||
{ wxT( "Space" ), WXK_SPACE },
|
||||
{ wxT( "Space" ), WXK_SPACE },
|
||||
|
||||
{ wxT( "Num Pad 0" ), WXK_NUMPAD0 },
|
||||
{ wxT( "Num Pad 1" ), WXK_NUMPAD1 },
|
||||
{ wxT( "Num Pad 2" ), WXK_NUMPAD2 },
|
||||
{ wxT( "Num Pad 3" ), WXK_NUMPAD3 },
|
||||
{ wxT( "Num Pad 4" ), WXK_NUMPAD4 },
|
||||
{ wxT( "Num Pad 5" ), WXK_NUMPAD5 },
|
||||
{ wxT( "Num Pad 6" ), WXK_NUMPAD6 },
|
||||
{ wxT( "Num Pad 7" ), WXK_NUMPAD7 },
|
||||
{ wxT( "Num Pad 8" ), WXK_NUMPAD8 },
|
||||
{ wxT( "Num Pad 9" ), WXK_NUMPAD9 },
|
||||
{ wxT( "Num Pad +" ), WXK_NUMPAD_ADD },
|
||||
{ wxT( "Num Pad -" ), WXK_NUMPAD_SUBTRACT },
|
||||
{ wxT( "Num Pad *" ), WXK_NUMPAD_MULTIPLY },
|
||||
{ wxT( "Num Pad /" ), WXK_NUMPAD_DIVIDE },
|
||||
{ wxT( "Num Pad ." ), WXK_NUMPAD_SEPARATOR },
|
||||
{ wxT( "Num Pad F1"), WXK_NUMPAD_F1 },
|
||||
{ wxT( "Num Pad F2"), WXK_NUMPAD_F2 },
|
||||
{ wxT( "Num Pad F3"), WXK_NUMPAD_F3 },
|
||||
{ wxT( "Num Pad F4"), WXK_NUMPAD_F4 },
|
||||
{ wxT( "Num Pad 0" ), WXK_NUMPAD0 },
|
||||
{ wxT( "Num Pad 1" ), WXK_NUMPAD1 },
|
||||
{ wxT( "Num Pad 2" ), WXK_NUMPAD2 },
|
||||
{ wxT( "Num Pad 3" ), WXK_NUMPAD3 },
|
||||
{ wxT( "Num Pad 4" ), WXK_NUMPAD4 },
|
||||
{ wxT( "Num Pad 5" ), WXK_NUMPAD5 },
|
||||
{ wxT( "Num Pad 6" ), WXK_NUMPAD6 },
|
||||
{ wxT( "Num Pad 7" ), WXK_NUMPAD7 },
|
||||
{ wxT( "Num Pad 8" ), WXK_NUMPAD8 },
|
||||
{ wxT( "Num Pad 9" ), WXK_NUMPAD9 },
|
||||
{ wxT( "Num Pad +" ), WXK_NUMPAD_ADD },
|
||||
{ wxT( "Num Pad -" ), WXK_NUMPAD_SUBTRACT },
|
||||
{ wxT( "Num Pad *" ), WXK_NUMPAD_MULTIPLY },
|
||||
{ wxT( "Num Pad /" ), WXK_NUMPAD_DIVIDE },
|
||||
{ wxT( "Num Pad ." ), WXK_NUMPAD_SEPARATOR },
|
||||
{ wxT( "Num Pad Enter" ), WXK_NUMPAD_ENTER },
|
||||
{ wxT( "Num Pad F1"), WXK_NUMPAD_F1 },
|
||||
{ wxT( "Num Pad F2"), WXK_NUMPAD_F2 },
|
||||
{ wxT( "Num Pad F3"), WXK_NUMPAD_F3 },
|
||||
{ wxT( "Num Pad F4"), WXK_NUMPAD_F4 },
|
||||
|
||||
{ wxT( "" ), 0 },
|
||||
{ wxT( "" ), 0 },
|
||||
|
||||
{ wxT( "Click" ), PSEUDO_WXK_CLICK },
|
||||
{ wxT( "DblClick" ), PSEUDO_WXK_DBLCLICK },
|
||||
{ wxT( "Wheel" ), PSEUDO_WXK_WHEEL },
|
||||
{ wxT( "Click" ), PSEUDO_WXK_CLICK },
|
||||
{ wxT( "DblClick" ), PSEUDO_WXK_DBLCLICK },
|
||||
{ wxT( "Wheel" ), PSEUDO_WXK_WHEEL },
|
||||
|
||||
// Do not change this line: end of list
|
||||
{ wxT( "" ), KEY_NON_FOUND }
|
||||
{ wxT( "" ), KEY_NON_FOUND }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aCl
|
||||
if( aNumPoints > 0 )
|
||||
DrawCubicBezierPath( aPoints, aNumPoints, collectedPathPoints );
|
||||
|
||||
if( aClosedPath )
|
||||
if( aClosedPath && collectedPathPoints.size() > 2 )
|
||||
DrawPolygon( collectedPathPoints, aStroke, aFilled, aFillColor );
|
||||
else
|
||||
DrawLineSegments( collectedPathPoints, aStroke );
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2020-2024 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "altium_ascii_parser.h"
|
||||
#include "altium_parser_utils.h"
|
||||
|
||||
|
||||
ALTIUM_ASCII_PARSER::ALTIUM_ASCII_PARSER( const wxString& aInputFile ) :
|
||||
m_fileInput( aInputFile.fn_str() )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::map<wxString, wxString> ALTIUM_ASCII_PARSER::ReadProperties()
|
||||
{
|
||||
std::map<wxString, wxString> kv;
|
||||
std::string str;
|
||||
std::string line;
|
||||
|
||||
// Lines ending with |> continue on the next line
|
||||
do
|
||||
{
|
||||
if( !std::getline( m_fileInput, line ) )
|
||||
{
|
||||
m_error = true;
|
||||
return kv;
|
||||
}
|
||||
|
||||
if( ( line.size() > 2 && line[line.size() - 2] == '|' && line[line.size() - 1] == '>' ) )
|
||||
{
|
||||
str.append( line, 0, line.size() - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
str.append( line );
|
||||
break;
|
||||
}
|
||||
} while( true );
|
||||
|
||||
std::size_t token_end = 0;
|
||||
|
||||
while( token_end < str.size() && token_end != std::string::npos )
|
||||
{
|
||||
std::size_t token_start = str.find( '|', token_end );
|
||||
std::size_t token_equal = str.find( '=', token_end );
|
||||
std::size_t key_start;
|
||||
|
||||
if( token_start <= token_equal )
|
||||
{
|
||||
key_start = token_start + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leading "|" before "RECORD=28" may be missing in older schematic versions.
|
||||
key_start = token_end;
|
||||
}
|
||||
|
||||
token_end = str.find( '|', key_start );
|
||||
|
||||
if( token_equal >= token_end )
|
||||
{
|
||||
continue; // this looks like an error: skip the entry. Also matches on std::string::npos
|
||||
}
|
||||
|
||||
if( token_end == std::string::npos )
|
||||
{
|
||||
token_end = str.size() + 1; // this is the correct offset
|
||||
}
|
||||
|
||||
std::string keyS = str.substr( key_start, token_equal - key_start );
|
||||
std::string valueS = str.substr( token_equal + 1, token_end - token_equal - 1 );
|
||||
|
||||
// convert the strings to wxStrings, since we use them everywhere
|
||||
// value can have non-ASCII characters, so we convert them from LATIN1/ISO8859-1
|
||||
wxString key( keyS.c_str(), wxConvISO8859_1 );
|
||||
// Altium stores keys either in Upper, or in CamelCase. Lets unify it.
|
||||
wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper();
|
||||
// If the key starts with '%UTF8%' we have to parse the value using UTF8
|
||||
wxString value;
|
||||
|
||||
if( canonicalKey.StartsWith( "%UTF8%" ) )
|
||||
value = wxString( valueS.c_str(), wxConvUTF8 );
|
||||
else
|
||||
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
||||
|
||||
if( canonicalKey != wxS( "PATTERN" ) && canonicalKey != wxS( "SOURCEFOOTPRINTLIBRARY" ) )
|
||||
{
|
||||
// Breathless hack because I haven't a clue what the story is here (but this character
|
||||
// appears in a lot of radial dimensions and is rendered by Altium as a space).
|
||||
value.Replace( wxT( "ÿ" ), wxT( " " ) );
|
||||
}
|
||||
|
||||
// Storage binary data do not need conversion.
|
||||
if( str.rfind( "|BINARY", 0 ) != 0 )
|
||||
{
|
||||
if( canonicalKey == wxT( "DESIGNATOR" ) || canonicalKey == wxT( "NAME" )
|
||||
|| canonicalKey == wxT( "TEXT" ) )
|
||||
{
|
||||
value = AltiumPropertyToKiCadString( value );
|
||||
}
|
||||
}
|
||||
|
||||
kv.insert( { canonicalKey, value.Trim() } );
|
||||
}
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
|
||||
bool ALTIUM_ASCII_PARSER::CanRead()
|
||||
{
|
||||
return m_fileInput && m_fileInput.peek() != std::ifstream::traits_type::eof();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2020-2024 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _ALTIUM_PARSER_H
|
||||
#define _ALTIUM_PARSER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
class ALTIUM_ASCII_PARSER
|
||||
{
|
||||
public:
|
||||
ALTIUM_ASCII_PARSER( const wxString& aInputFile );
|
||||
|
||||
std::map<wxString, wxString> ReadProperties();
|
||||
|
||||
bool CanRead();
|
||||
|
||||
bool HasParsingError()
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
private:
|
||||
std::ifstream m_fileInput;
|
||||
bool m_error = false;
|
||||
};
|
||||
|
||||
#endif //_ALTIUM_PARSER_H
|
||||
@@ -22,7 +22,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "altium_parser.h"
|
||||
#include "altium_binary_parser.h"
|
||||
#include "altium_parser_utils.h"
|
||||
|
||||
#include <compoundfilereader.h>
|
||||
@@ -350,13 +350,13 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames()
|
||||
|
||||
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||
{
|
||||
ALTIUM_PARSER parametersReader( *this, entry );
|
||||
ALTIUM_BINARY_PARSER parametersReader( *this, entry );
|
||||
std::map<wxString, wxString> parameterProperties =
|
||||
parametersReader.ReadProperties();
|
||||
|
||||
wxString key = ALTIUM_PARSER::ReadString(
|
||||
wxString key = ALTIUM_PROPS_UTILS::ReadString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||
wxString fpName = ALTIUM_PROPS_UTILS::ReadUnicodeString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
m_libFootprintDirNameCache[key] = fpName;
|
||||
@@ -370,7 +370,7 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames()
|
||||
}
|
||||
|
||||
|
||||
ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
|
||||
ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
|
||||
const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
||||
{
|
||||
m_subrecord_end = nullptr;
|
||||
@@ -384,7 +384,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
|
||||
}
|
||||
|
||||
|
||||
ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
|
||||
ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
|
||||
{
|
||||
m_subrecord_end = nullptr;
|
||||
m_size = aSize;
|
||||
@@ -394,7 +394,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
|
||||
}
|
||||
|
||||
|
||||
std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties(
|
||||
std::map<wxString, wxString> ALTIUM_BINARY_PARSER::ReadProperties(
|
||||
std::function<std::map<wxString, wxString>( const std::string& )> handleBinaryData )
|
||||
{
|
||||
|
||||
@@ -502,123 +502,3 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties(
|
||||
return kv;
|
||||
}
|
||||
|
||||
|
||||
int32_t ALTIUM_PARSER::ConvertToKicadUnit( const double aValue )
|
||||
{
|
||||
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
|
||||
|
||||
int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
|
||||
|
||||
// Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
|
||||
// up most rounding errors. This allows lossless conversion of increments of 0.05mils and
|
||||
// 0.01um.
|
||||
return KiROUND( (double) iu / 10.0 ) * 10;
|
||||
}
|
||||
|
||||
|
||||
int ALTIUM_PARSER::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
int aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
return value == aProps.end() ? aDefault : wxAtoi( value->second );
|
||||
}
|
||||
|
||||
|
||||
double ALTIUM_PARSER::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
double aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
|
||||
if( value == aProps.end() )
|
||||
return aDefault;
|
||||
|
||||
// Locale independent str -> double conversation
|
||||
std::istringstream istr( (const char*) value->second.mb_str() );
|
||||
istr.imbue( std::locale::classic() );
|
||||
|
||||
double doubleValue;
|
||||
istr >> doubleValue;
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
|
||||
bool ALTIUM_PARSER::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
bool aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
|
||||
if( value == aProps.end() )
|
||||
return aDefault;
|
||||
else
|
||||
return value->second == "T" || value->second == "TRUE";
|
||||
}
|
||||
|
||||
|
||||
int32_t ALTIUM_PARSER::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const wxString& value = ReadString( aProps, aKey, aDefault );
|
||||
|
||||
wxString prefix;
|
||||
|
||||
if( !value.EndsWith( "mil", &prefix ) )
|
||||
{
|
||||
wxLogError( _( "Unit '%s' does not end with 'mil'." ), value );
|
||||
return 0;
|
||||
}
|
||||
|
||||
prefix.StartsWith( "+", &prefix );
|
||||
|
||||
double mils;
|
||||
|
||||
if( !prefix.ToCDouble( &mils ) )
|
||||
{
|
||||
wxLogError( _( "Cannot convert '%s' to double." ), prefix );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ConvertToKicadUnit( mils * 10000 );
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PARSER::ReadString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
|
||||
|
||||
if( utf8Value != aProps.end() )
|
||||
return utf8Value->second;
|
||||
|
||||
const auto& value = aProps.find( aKey );
|
||||
|
||||
if( value != aProps.end() )
|
||||
return value->second;
|
||||
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PARSER::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
|
||||
|
||||
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
|
||||
{
|
||||
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
|
||||
|
||||
if( unicodeValue != aProps.end() )
|
||||
{
|
||||
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
|
||||
wxString out;
|
||||
|
||||
for( wxString part : arr )
|
||||
out += wxString( wchar_t( wxAtoi( part ) ) );
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
return ReadString( aProps, aKey, aDefault );
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef ALTIUM_PARSER_H
|
||||
#define ALTIUM_PARSER_H
|
||||
#ifndef _ALTIUM_BINARY_PARSER_H
|
||||
#define _ALTIUM_BINARY_PARSER_H
|
||||
|
||||
#include "altium_props_utils.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -106,12 +108,12 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class ALTIUM_PARSER
|
||||
class ALTIUM_BINARY_PARSER
|
||||
{
|
||||
public:
|
||||
ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||
ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize );
|
||||
~ALTIUM_PARSER() = default;
|
||||
ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||
ALTIUM_BINARY_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize );
|
||||
~ALTIUM_BINARY_PARSER() = default;
|
||||
|
||||
template <typename Type>
|
||||
Type Read()
|
||||
@@ -229,7 +231,7 @@ public:
|
||||
|
||||
int32_t ReadKicadUnit()
|
||||
{
|
||||
return ConvertToKicadUnit( Read<int32_t>() );
|
||||
return ALTIUM_PROPS_UTILS::ConvertToKicadUnit( Read<int32_t>() );
|
||||
}
|
||||
|
||||
int32_t ReadKicadUnitX()
|
||||
@@ -270,26 +272,6 @@ public:
|
||||
return std::map<wxString, wxString>();
|
||||
} );
|
||||
|
||||
static int32_t ConvertToKicadUnit( const double aValue );
|
||||
|
||||
static int ReadInt( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, int aDefault );
|
||||
|
||||
static double ReadDouble( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, double aDefault );
|
||||
|
||||
static bool ReadBool( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, bool aDefault );
|
||||
|
||||
static int32_t ReadKicadUnit( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
|
||||
static wxString ReadString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
|
||||
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
|
||||
void Skip( size_t aLength )
|
||||
{
|
||||
if( GetRemainingBytes() >= aLength )
|
||||
@@ -447,4 +429,4 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#endif //ALTIUM_PARSER_H
|
||||
#endif //_ALTIUM_BINARY_PARSER_H
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2020-2024 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "altium_props_utils.h"
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <math/util.h>
|
||||
|
||||
#include <wx/crt.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
|
||||
int32_t ALTIUM_PROPS_UTILS::ConvertToKicadUnit( const double aValue )
|
||||
{
|
||||
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
|
||||
|
||||
int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
|
||||
|
||||
// Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
|
||||
// up most rounding errors. This allows lossless conversion of increments of 0.05mils and
|
||||
// 0.01um.
|
||||
return KiROUND( (double) iu / 10.0 ) * 10;
|
||||
}
|
||||
|
||||
|
||||
int ALTIUM_PROPS_UTILS::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
int aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
return value == aProps.end() ? aDefault : wxAtoi( value->second );
|
||||
}
|
||||
|
||||
|
||||
double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
double aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
|
||||
if( value == aProps.end() )
|
||||
return aDefault;
|
||||
|
||||
// Locale independent str -> double conversation
|
||||
std::istringstream istr( (const char*) value->second.mb_str() );
|
||||
istr.imbue( std::locale::classic() );
|
||||
|
||||
double doubleValue;
|
||||
istr >> doubleValue;
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
|
||||
bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
bool aDefault )
|
||||
{
|
||||
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
|
||||
|
||||
if( value == aProps.end() )
|
||||
return aDefault;
|
||||
else
|
||||
return value->second == "T" || value->second == "TRUE";
|
||||
}
|
||||
|
||||
|
||||
int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const wxString& value = ReadString( aProps, aKey, aDefault );
|
||||
|
||||
wxString prefix;
|
||||
|
||||
if( !value.EndsWith( "mil", &prefix ) )
|
||||
{
|
||||
wxLogError( _( "Unit '%s' does not end with 'mil'." ), value );
|
||||
return 0;
|
||||
}
|
||||
|
||||
prefix.StartsWith( "+", &prefix );
|
||||
|
||||
double mils;
|
||||
|
||||
if( !prefix.ToCDouble( &mils ) )
|
||||
{
|
||||
wxLogError( _( "Cannot convert '%s' to double." ), prefix );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ConvertToKicadUnit( mils * 10000 );
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
|
||||
|
||||
if( utf8Value != aProps.end() )
|
||||
return utf8Value->second;
|
||||
|
||||
const auto& value = aProps.find( aKey );
|
||||
|
||||
if( value != aProps.end() )
|
||||
return value->second;
|
||||
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
|
||||
|
||||
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
|
||||
{
|
||||
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
|
||||
|
||||
if( unicodeValue != aProps.end() )
|
||||
{
|
||||
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
|
||||
wxString out;
|
||||
|
||||
for( wxString part : arr )
|
||||
out += wxString( wchar_t( wxAtoi( part ) ) );
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
return ReadString( aProps, aKey, aDefault );
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2020-2024 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _ALTIUM_PROPS_UTILS_H
|
||||
#define _ALTIUM_PROPS_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
class ALTIUM_PROPS_UTILS
|
||||
{
|
||||
public:
|
||||
static int32_t ConvertToKicadUnit( const double aValue );
|
||||
|
||||
static int ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
int aDefault );
|
||||
|
||||
static double ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
double aDefault );
|
||||
|
||||
static bool ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
bool aDefault );
|
||||
|
||||
static int32_t ReadKicadUnit( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
const wxString& aDefault );
|
||||
|
||||
static wxString ReadString( const std::map<wxString, wxString>& aProps, const wxString& aKey,
|
||||
const wxString& aDefault );
|
||||
|
||||
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
};
|
||||
|
||||
#endif //_ALTIUM_PROPS_UTILS_H
|
||||
@@ -979,13 +979,20 @@ EELEMENT::EELEMENT( wxXmlNode* aElement )
|
||||
<!ATTLIST element
|
||||
name %String; #REQUIRED
|
||||
library %String; #REQUIRED
|
||||
library_urn %Urn; ""
|
||||
package %String; #REQUIRED
|
||||
package3d_urn %Urn; ""
|
||||
override_package3d_urn %Urn; ""
|
||||
override_package_urn %Urn; ""
|
||||
override_locally_modified %Bool; "no"
|
||||
value %String; #REQUIRED
|
||||
x %Coord; #REQUIRED
|
||||
y %Coord; #REQUIRED
|
||||
locked %Bool; "no"
|
||||
populate %Bool; "yes"
|
||||
smashed %Bool; "no"
|
||||
rot %Rotation; "R0"
|
||||
grouprefs IDREFS #IMPLIED
|
||||
>
|
||||
*/
|
||||
|
||||
@@ -1001,6 +1008,7 @@ EELEMENT::EELEMENT( wxXmlNode* aElement )
|
||||
y = parseRequiredAttribute<ECOORD>( aElement, "y" );
|
||||
|
||||
// optional
|
||||
library_urn = parseOptionalAttribute<wxString>( aElement, "library_urn" );
|
||||
locked = parseOptionalAttribute<bool>( aElement, "locked" );
|
||||
smashed = parseOptionalAttribute<bool>( aElement, "smashed" );
|
||||
rot = parseOptionalAttribute<EROT>( aElement, "rot" );
|
||||
|
||||
@@ -817,6 +817,7 @@ struct EELEMENT
|
||||
{
|
||||
wxString name;
|
||||
wxString library;
|
||||
opt_wxString library_urn;
|
||||
wxString package;
|
||||
wxString value;
|
||||
ECOORD x;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <bezier_curves.h>
|
||||
#include <ki_exception.h>
|
||||
#include <wx/translation.h>
|
||||
#include <eda_text.h>
|
||||
|
||||
|
||||
double EASYEDA_PARSER_BASE::Convert( const wxString& aValue )
|
||||
@@ -66,6 +67,49 @@ double EASYEDA_PARSER_BASE::RelPosY( const wxString& aValue )
|
||||
}
|
||||
|
||||
|
||||
void EASYEDA_PARSER_BASE::TransformTextToBaseline( EDA_TEXT* textItem,
|
||||
const wxString& baselineAlign, bool invertY )
|
||||
{
|
||||
int upOffset = 0;
|
||||
|
||||
if( baselineAlign == wxS( "" ) || baselineAlign == wxS( "auto" )
|
||||
|| baselineAlign == wxS( "use-script" ) || baselineAlign == wxS( "no-change" )
|
||||
|| baselineAlign == wxS( "reset-size" ) || baselineAlign == wxS( "alphabetic" )
|
||||
|| baselineAlign == wxS( "inherit" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y;
|
||||
}
|
||||
else if( baselineAlign == wxS( "ideographic" ) || baselineAlign == wxS( "text-after-edge" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 1.2;
|
||||
}
|
||||
else if( baselineAlign == wxS( "central" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.5;
|
||||
}
|
||||
else if( baselineAlign == wxS( "middle" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.6;
|
||||
}
|
||||
else if( baselineAlign == wxS( "mathematical" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.1;
|
||||
}
|
||||
else if( baselineAlign == wxS( "hanging" ) || baselineAlign == wxS( "text-before-edge" ) )
|
||||
{
|
||||
upOffset = 0;
|
||||
}
|
||||
|
||||
VECTOR2I offset( 0, -upOffset );
|
||||
RotatePoint( offset, textItem->GetTextAngle() );
|
||||
|
||||
if( invertY )
|
||||
offset.y = -offset.y;
|
||||
|
||||
textItem->SetTextPos( textItem->GetTextPos() + offset );
|
||||
}
|
||||
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN>
|
||||
EASYEDA_PARSER_BASE::ParseLineChains( const wxString& data, int aArcMinSegLen, bool aForceClosed )
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <math/vector2d.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class EDA_TEXT;
|
||||
|
||||
class EASYEDA_PARSER_BASE
|
||||
{
|
||||
public:
|
||||
@@ -58,7 +60,9 @@ public:
|
||||
return ScalePos( aVec - m_relOrigin );
|
||||
}
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen,
|
||||
void TransformTextToBaseline( EDA_TEXT* textItem, const wxString& baselineAlign, bool invertY );
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen,
|
||||
bool aForceClosed );
|
||||
|
||||
protected:
|
||||
|
||||
@@ -87,6 +87,7 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT& d )
|
||||
PARSE_VALUE( head );
|
||||
|
||||
PARSE_VALUE( canvas );
|
||||
PARSE_VALUE( title );
|
||||
PARSE_VALUE( shape );
|
||||
PARSE_VALUE( dataStr );
|
||||
}
|
||||
|
||||
@@ -73,9 +73,10 @@ struct DOCUMENT
|
||||
|
||||
// BBox
|
||||
// colors
|
||||
wxString canvas;
|
||||
wxArrayString shape;
|
||||
std::optional<nlohmann::json> dataStr;
|
||||
wxString canvas;
|
||||
wxString title;
|
||||
wxArrayString shape;
|
||||
std::optional<nlohmann::json> dataStr;
|
||||
};
|
||||
|
||||
struct C_PARA
|
||||
|
||||
@@ -150,14 +150,28 @@ nlohmann::json EASYEDAPRO::ReadProjectOrDeviceFile( const wxString& aZipFileName
|
||||
{
|
||||
wxString name = entry->GetName();
|
||||
|
||||
if( name == wxS( "project.json" ) || name == wxS( "device.json" ) )
|
||||
try
|
||||
{
|
||||
wxMemoryOutputStream memos;
|
||||
memos << zip;
|
||||
wxStreamBuffer* buf = memos.GetOutputStreamBuffer();
|
||||
wxString str( (char*) buf->GetBufferStart(), buf->GetBufferSize() );
|
||||
if( name == wxS( "project.json" ) || name == wxS( "device.json" ) )
|
||||
{
|
||||
wxMemoryOutputStream memos;
|
||||
memos << zip;
|
||||
wxStreamBuffer* buf = memos.GetOutputStreamBuffer();
|
||||
|
||||
return nlohmann::json::parse( str );
|
||||
wxString str =
|
||||
wxString::FromUTF8( (char*) buf->GetBufferStart(), buf->GetBufferSize() );
|
||||
|
||||
return nlohmann::json::parse( str );
|
||||
}
|
||||
}
|
||||
catch( nlohmann::json::exception& e )
|
||||
{
|
||||
THROW_IO_ERROR(
|
||||
wxString::Format( _( "JSON error reading '%s': %s" ), name, e.what() ) );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error reading '%s': %s" ), name, e.what() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -229,6 +229,9 @@ void Prettify( std::string& aSource, char aQuoteChar )
|
||||
++cursor;
|
||||
}
|
||||
|
||||
// newline required at end of line / file for POSIX compliance. Keeps git diffs clean.
|
||||
formatted += '\n';
|
||||
|
||||
aSource = std::move( formatted );
|
||||
}
|
||||
|
||||
|
||||
@@ -242,13 +242,21 @@ void LIB_TREE_NODE_ITEM::Update( LIB_TREE_ITEM* aItem )
|
||||
void LIB_TREE_NODE_ITEM::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
// aMatcher test is additive
|
||||
// aMatcher test is additive, but if we don't match the given term at all, it nulls out
|
||||
if( aMatcher )
|
||||
m_Score += aMatcher->ScoreTerms( m_SearchTerms );
|
||||
{
|
||||
int currentScore = aMatcher->ScoreTerms( m_SearchTerms );
|
||||
|
||||
// aLib test is additive
|
||||
if( !aLib.IsEmpty() && m_Parent->m_Name.Lower().Matches( aLib ) )
|
||||
m_Score += 1;
|
||||
// This is a hack: the second phase of search in the adapter will look for a tokenized
|
||||
// LIB_ID and send the lib part down here. While we generally want to prune ourselves
|
||||
// out here (by setting score to -1) the first time we fail to match a search term,
|
||||
// we want to give the same search term a second chance if it has been split from a library
|
||||
// name.
|
||||
if( ( m_Score >= 0 || !aLib.IsEmpty() ) && currentScore > 0 )
|
||||
m_Score += currentScore;
|
||||
else
|
||||
m_Score = -1; // Item has failed to match this term, rule it out
|
||||
}
|
||||
|
||||
// aFilter test is subtractive
|
||||
if( aFilter && !(*aFilter)(*this) )
|
||||
@@ -287,19 +295,42 @@ LIB_TREE_NODE_ITEM& LIB_TREE_NODE_LIBRARY::AddItem( LIB_TREE_ITEM* aItem )
|
||||
void LIB_TREE_NODE_LIBRARY::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
int maxChildScore = 0;
|
||||
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
{
|
||||
child->UpdateScore( aMatcher, aLib, aFilter );
|
||||
m_Score = std::max( m_Score, child->m_Score );
|
||||
maxChildScore = std::max( maxChildScore, child->m_Score );
|
||||
}
|
||||
|
||||
// aLib test is additive
|
||||
if( !aLib.IsEmpty() && m_Name.Lower().Matches( aLib ) )
|
||||
// Each time UpdateScore is called for a library, child (item) scores may go up or down.
|
||||
// If the all go down to zero, we need to make sure to drop the library from the list.
|
||||
if( maxChildScore > 0 )
|
||||
m_Score = std::max( m_Score, maxChildScore );
|
||||
else
|
||||
m_Score = 0;
|
||||
|
||||
// aLib test is additive, but only when we've already accumulated some score from children
|
||||
if( !aLib.IsEmpty()
|
||||
&& m_Name.Lower().Matches( aLib )
|
||||
&& ( m_Score > 0 || m_Children.empty() ) )
|
||||
{
|
||||
m_Score += 1;
|
||||
}
|
||||
|
||||
// aMatcher test is additive
|
||||
if( aMatcher )
|
||||
m_Score += aMatcher->ScoreTerms( m_SearchTerms );
|
||||
{
|
||||
int ownScore = aMatcher->ScoreTerms( m_SearchTerms );
|
||||
m_Score += ownScore;
|
||||
|
||||
// If we have a hit on a library, show all children in that library
|
||||
if( maxChildScore <= 0 && ownScore > 0 )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
child->ForceScore( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// show all nodes if no search/filter/etc. criteria are given
|
||||
if( m_Children.empty() && !aMatcher && aLib.IsEmpty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
|
||||
@@ -91,14 +91,19 @@ public:
|
||||
dc->DrawLines( 6, points );
|
||||
}
|
||||
|
||||
aRect.Deflate( 1 );
|
||||
|
||||
#ifdef __WXOSX__
|
||||
// We should be able to pass wxDATAVIEW_CELL_SELECTED into RenderText() and have it do
|
||||
// the right thing -- but it picks wxSYS_COLOUR_HIGHLIGHTTEXT on MacOS and GTK (instead
|
||||
// the right thing -- but it picks wxSYS_COLOUR_HIGHLIGHTTEXT on MacOS (instead
|
||||
// of wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT).
|
||||
if( aState & wxDATAVIEW_CELL_SELECTED )
|
||||
dc->SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
||||
|
||||
aRect.Deflate( 1 );
|
||||
RenderText( m_text, 0, aRect, dc, 0 );
|
||||
#else
|
||||
RenderText( m_text, 0, aRect, dc, aState );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -297,11 +302,6 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
|
||||
m_tree.UpdateScore( &itemNameMatcher, lib, nullptr );
|
||||
}
|
||||
else
|
||||
{
|
||||
// In case the full token happens to match a library name
|
||||
m_tree.UpdateScore( nullptr, '*' + term + '*', nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
if( firstTerm )
|
||||
@@ -674,10 +674,10 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
||||
{
|
||||
const wxString& key = m_colIdxMap.at( aCol );
|
||||
|
||||
if( node->m_Fields.count( key ) )
|
||||
valueStr = UnescapeString( node->m_Fields.at( key ) );
|
||||
else if( key == wxT( "Description" ) )
|
||||
if( key == wxT( "Description" ) )
|
||||
valueStr = UnescapeString( node->m_Desc );
|
||||
else if( node->m_Fields.count( key ) )
|
||||
valueStr = UnescapeString( node->m_Fields.at( key ) );
|
||||
else
|
||||
valueStr = wxEmptyString;
|
||||
}
|
||||
|
||||
+19
-15
@@ -169,6 +169,10 @@ wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
|
||||
path = GetExecutablePath() + wxT( ".." );
|
||||
#endif
|
||||
}
|
||||
else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )
|
||||
{
|
||||
return path;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined( __WXMAC__ )
|
||||
@@ -291,12 +295,16 @@ wxString PATHS::GetStockPlugins3DPath()
|
||||
{
|
||||
wxFileName fn;
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
|
||||
// corresponding to the install path used for constructing KICAD_USER_PLUGIN
|
||||
wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
|
||||
fn.Assign( tfname, "" );
|
||||
fn.AppendDir( wxT( "kicad" ) );
|
||||
#if defined( __WXMSW__ )
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
fn.AssignDir( getWindowsKiCadRoot() );
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.AssignDir( GetExecutablePath() );
|
||||
}
|
||||
|
||||
fn.AppendDir( wxT( "plugins" ) );
|
||||
#elif defined( __WXMAC__ )
|
||||
fn.Assign( wxStandardPaths::Get().GetPluginsDir(), wxEmptyString );
|
||||
@@ -319,15 +327,11 @@ wxString PATHS::GetStockPlugins3DPath()
|
||||
fn.AppendDir( wxT( "PlugIns" ) );
|
||||
}
|
||||
#else
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
fn.AssignDir( getWindowsKiCadRoot() );
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.AssignDir( GetExecutablePath() );
|
||||
}
|
||||
|
||||
// KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
|
||||
// corresponding to the install path used for constructing KICAD_USER_PLUGIN
|
||||
wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
|
||||
fn.Assign( tfname, "" );
|
||||
fn.AppendDir( wxT( "kicad" ) );
|
||||
fn.AppendDir( wxT( "plugins" ) );
|
||||
#endif
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ PGM_BASE::PGM_BASE()
|
||||
m_argcUtf8 = 0;
|
||||
m_argvUtf8 = nullptr;
|
||||
m_splash = nullptr;
|
||||
m_PropertyGridInitialized = false;
|
||||
|
||||
setLanguageId( wxLANGUAGE_DEFAULT );
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2024 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
|
||||
@@ -647,6 +647,16 @@ void GERBER_PLOTTER::writeApertureList()
|
||||
std::vector<VECTOR2I> corners;
|
||||
VECTOR2I half_size( tool.m_Size.x/2-tool.m_Radius, tool.m_Size.y/2-tool.m_Radius );
|
||||
|
||||
// Ensure half_size.x and half_size.y > minimal value to avoid shapes
|
||||
// with null size (especially the rectangle with coordinates corners)
|
||||
// Because the minimal value for a non nul Gerber coord in 10nm
|
||||
// in format 4.5, use 10 nm as minimal value.
|
||||
// (Even in 4.6 format, use 10 nm, because gerber viewers can have
|
||||
// a internal unit bigger than 1 nm)
|
||||
const int min_size_value = 10;
|
||||
half_size.x = std::max( half_size.x, min_size_value );
|
||||
half_size.y = std::max( half_size.y, min_size_value );
|
||||
|
||||
corners.emplace_back( -half_size.x, -half_size.y );
|
||||
corners.emplace_back( half_size.x, -half_size.y );
|
||||
corners.emplace_back( half_size.x, half_size.y );
|
||||
@@ -823,10 +833,21 @@ void GERBER_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
{
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
EDA_ANGLE endAngle = aStartAngle + aAngle;
|
||||
double arcLength = std::abs( aRadius * aAngle.AsRadians() );
|
||||
|
||||
// aFill is not used here.
|
||||
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
|
||||
if( arcLength < 100 || std::abs( aAngle.AsDegrees() ) < 0.1 )
|
||||
{
|
||||
// Prevent plotting very short arcs as full circles, especially with 4.5 mm precision.
|
||||
// Also reduce the risk of integer overflow issues.
|
||||
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
EDA_ANGLE endAngle = aStartAngle + aAngle;
|
||||
|
||||
// aFill is not used here.
|
||||
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -869,19 +890,19 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
|
||||
|
||||
|
||||
void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, int aRadius, bool aPlotInRegion )
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, bool aPlotInRegion )
|
||||
{
|
||||
VECTOR2I start, end;
|
||||
start.x = aCenter.x + KiROUND( aRadius * aStartAngle.Cos() );
|
||||
start.y = aCenter.y + KiROUND( aRadius * aStartAngle.Sin() );
|
||||
start.x = KiROUND( aCenter.x + aRadius * aStartAngle.Cos() );
|
||||
start.y = KiROUND( aCenter.y + aRadius * aStartAngle.Sin() );
|
||||
|
||||
if( !aPlotInRegion )
|
||||
MoveTo( start );
|
||||
else
|
||||
LineTo( start );
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
|
||||
end.y = aCenter.y + KiROUND( aRadius * aEndAngle.Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * aEndAngle.Cos() );
|
||||
end.y = KiROUND( aCenter.y + aRadius * aEndAngle.Sin() );
|
||||
VECTOR2D devEnd = userToDeviceCoordinates( end );
|
||||
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
|
||||
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
|
||||
|
||||
@@ -565,6 +565,13 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
||||
// Avoid integer overflow when calculating the center point
|
||||
if( std::abs( aAngle.AsDegrees() ) < 5 )
|
||||
{
|
||||
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
|
||||
return;
|
||||
}
|
||||
|
||||
double const radius_device = userToDeviceSize( aRadius );
|
||||
double const circumf_device = 2.0 * M_PI * radius_device;
|
||||
double const target_chord_length = m_arcTargetChordLength;
|
||||
@@ -581,11 +588,11 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
EDA_ANGLE startAngle = -aStartAngle;
|
||||
|
||||
// Calculate arc start point:
|
||||
VECTOR2I cmap( aCenter.x + KiROUND( aRadius * startAngle.Cos() ),
|
||||
aCenter.y - KiROUND( aRadius * startAngle.Sin() ) );
|
||||
VECTOR2I cmap( KiROUND( aCenter.x + aRadius * startAngle.Cos() ),
|
||||
KiROUND( aCenter.y - aRadius * startAngle.Sin() ) );
|
||||
VECTOR2D cmap_dev = userToDeviceCoordinates( cmap );
|
||||
|
||||
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%.0f,%g",
|
||||
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%g,%g",
|
||||
centre_device.x,
|
||||
centre_device.y,
|
||||
angle.AsDegrees(),
|
||||
|
||||
@@ -354,21 +354,21 @@ void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
// Usual trig arc plotting routine...
|
||||
start.x = aCenter.x + KiROUND( aRadius * (-startAngle).Cos() );
|
||||
start.y = aCenter.y + KiROUND( aRadius * (-startAngle).Sin() );
|
||||
start.x = KiROUND( aCenter.x + aRadius * ( -startAngle ).Cos() );
|
||||
start.y = KiROUND( aCenter.y + aRadius * ( -startAngle ).Sin() );
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( start );
|
||||
fprintf( m_workFile, "%g %g m ", pos_dev.x, pos_dev.y );
|
||||
|
||||
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
|
||||
{
|
||||
end.x = aCenter.x + KiROUND( aRadius * (-ii).Cos() );
|
||||
end.y = aCenter.y + KiROUND( aRadius * (-ii).Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * ( -ii ).Cos() );
|
||||
end.y = KiROUND( aCenter.y + aRadius * ( -ii ).Sin() );
|
||||
pos_dev = userToDeviceCoordinates( end );
|
||||
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
|
||||
}
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * (-endAngle).Cos() );
|
||||
end.y = aCenter.y + KiROUND( aRadius * (-endAngle).Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * ( -endAngle ).Cos() );
|
||||
end.y = KiROUND( aCenter.y + aRadius * ( -endAngle ).Sin() );
|
||||
pos_dev = userToDeviceCoordinates( end );
|
||||
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
|
||||
|
||||
|
||||
@@ -191,8 +191,8 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
start.x = aCenter.x + KiROUND( aRadius * startAngle.Cos() );
|
||||
start.y = aCenter.y + sign * KiROUND( aRadius * startAngle.Sin() );
|
||||
start.x = KiROUND( aCenter.x + aRadius * startAngle.Cos() );
|
||||
start.y = KiROUND( aCenter.y + sign * aRadius * startAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
@@ -206,13 +206,13 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
|
||||
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
|
||||
{
|
||||
end.x = aCenter.x + KiROUND( aRadius * ii.Cos() );
|
||||
end.y = aCenter.y + sign * KiROUND( aRadius * ii.Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * ii.Cos() );
|
||||
end.y = KiROUND( aCenter.y + sign * aRadius * ii.Sin() );
|
||||
LineTo( end );
|
||||
}
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * endAngle.Cos() );
|
||||
end.y = aCenter.y + sign * KiROUND( aRadius * endAngle.Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * endAngle.Cos() );
|
||||
end.y = KiROUND( aCenter.y + sign * aRadius * endAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
@@ -706,7 +706,6 @@ void PLOTTER::Text( const VECTOR2I& aPos,
|
||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||
|
||||
SetColor( aColor );
|
||||
SetCurrentLineWidth( aPenWidth, aData );
|
||||
|
||||
if( aPenWidth == 0 && aBold ) // Use default values if aPenWidth == 0
|
||||
aPenWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
|
||||
@@ -718,6 +717,7 @@ void PLOTTER::Text( const VECTOR2I& aPos,
|
||||
// Stroke callback
|
||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
||||
{
|
||||
SetCurrentLineWidth( aPenWidth );
|
||||
MoveTo( aPt1 );
|
||||
LineTo( aPt2 );
|
||||
PenFinish();
|
||||
|
||||
@@ -37,8 +37,7 @@ const wxString COLOR_SETTINGS::COLOR_BUILTIN_CLASSIC = "_builtin_classic";
|
||||
|
||||
COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) :
|
||||
JSON_SETTINGS( std::move( aFilename ), SETTINGS_LOC::COLORS, colorsSchemaVersion ),
|
||||
m_overrideSchItemColors( false ),
|
||||
m_useBoardStackupColors( true )
|
||||
m_overrideSchItemColors( false )
|
||||
{
|
||||
if( aAbsolutePath )
|
||||
SetLocation( SETTINGS_LOC::NONE );
|
||||
@@ -49,9 +48,6 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath )
|
||||
m_params.emplace_back( new PARAM<bool>( "schematic.override_item_colors",
|
||||
&m_overrideSchItemColors, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "3d_viewer.use_board_stackup_colors",
|
||||
&m_useBoardStackupColors, true ) );
|
||||
|
||||
#define CLR( x, y ) \
|
||||
wxASSERT( s_defaultTheme.count( y ) ); \
|
||||
m_params.emplace_back( new COLOR_MAP_PARAM( x, y, s_defaultTheme.at( y ), &m_colors ) );
|
||||
@@ -282,7 +278,6 @@ void COLOR_SETTINGS::initFromOther( const COLOR_SETTINGS& aOther )
|
||||
{
|
||||
m_displayName = aOther.m_displayName;
|
||||
m_overrideSchItemColors = aOther.m_overrideSchItemColors;
|
||||
m_useBoardStackupColors = aOther.m_useBoardStackupColors;
|
||||
m_colors = aOther.m_colors;
|
||||
m_defaultColors = aOther.m_defaultColors;
|
||||
m_writeFile = aOther.m_writeFile;
|
||||
|
||||
@@ -731,19 +731,47 @@ bool SETTINGS_MANAGER::GetPreviousVersionPaths( std::vector<wxString>* aPaths )
|
||||
}
|
||||
}
|
||||
|
||||
alg::delete_if( *aPaths, []( const wxString& aPath ) -> bool
|
||||
{
|
||||
wxFileName fulldir = wxFileName::DirName( aPath );
|
||||
const wxArrayString& dirs = fulldir.GetDirs();
|
||||
|
||||
if( dirs.empty() || !fulldir.IsDirReadable() )
|
||||
return true;
|
||||
|
||||
std::string ver = dirs.back().ToStdString();
|
||||
|
||||
if( !extractVersion( ver ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} );
|
||||
|
||||
std::sort( aPaths->begin(), aPaths->end(),
|
||||
[&]( const wxString& a, const wxString& b ) -> bool
|
||||
{
|
||||
wxString verA = wxFileName::DirName( a ).GetDirs().back();
|
||||
wxString verB = wxFileName::DirName( b ).GetDirs().back();
|
||||
wxFileName aPath = wxFileName::DirName( a );
|
||||
wxFileName bPath = wxFileName::DirName( b );
|
||||
|
||||
if( !extractVersion( verA.ToStdString() )
|
||||
|| !extractVersion( verB.ToStdString() ) )
|
||||
{
|
||||
const wxArrayString& aDirs = aPath.GetDirs();
|
||||
const wxArrayString& bDirs = bPath.GetDirs();
|
||||
|
||||
if( aDirs.empty() )
|
||||
return false;
|
||||
}
|
||||
|
||||
return compareVersions( verA.ToStdString(), verB.ToStdString() ) >= 0;
|
||||
if( bDirs.empty() )
|
||||
return true;
|
||||
|
||||
std::string verA = aDirs.back().ToStdString();
|
||||
std::string verB = bDirs.back().ToStdString();
|
||||
|
||||
if( !extractVersion( verA ) )
|
||||
return false;
|
||||
|
||||
if( !extractVersion( verB ) )
|
||||
return true;
|
||||
|
||||
return compareVersions( verA, verB ) >= 0;
|
||||
} );
|
||||
|
||||
return aPaths->size() > 0;
|
||||
|
||||
+26
-23
@@ -313,40 +313,40 @@ wxString UnescapeString( const wxString& aSource )
|
||||
}
|
||||
else
|
||||
{
|
||||
token.append( ch );
|
||||
token << ch;
|
||||
}
|
||||
}
|
||||
|
||||
if( !terminated )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
|
||||
newbuf << wxT( "{" ) << UnescapeString( token );
|
||||
}
|
||||
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
newbuf << 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( ">" ) );
|
||||
else if( token == wxT( "backslash" ) ) newbuf.append( wxT( "\\" ) );
|
||||
else if( token == wxT( "slash" ) ) newbuf.append( wxT( "/" ) );
|
||||
else if( token == wxT( "bar" ) ) newbuf.append( wxT( "|" ) );
|
||||
else if( token == wxT( "comma" ) ) newbuf.append( wxT( "," ) );
|
||||
else if( token == wxT( "colon" ) ) newbuf.append( wxT( ":" ) );
|
||||
else if( token == wxT( "space" ) ) newbuf.append( wxT( " " ) );
|
||||
else if( token == wxT( "dollar" ) ) newbuf.append( wxT( "$" ) );
|
||||
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 == wxT( "dblquote" ) ) newbuf << wxT( "\"" );
|
||||
else if( token == wxT( "quote" ) ) newbuf << wxT( "'" );
|
||||
else if( token == wxT( "lt" ) ) newbuf << wxT( "<" );
|
||||
else if( token == wxT( "gt" ) ) newbuf << wxT( ">" );
|
||||
else if( token == wxT( "backslash" ) ) newbuf << wxT( "\\" );
|
||||
else if( token == wxT( "slash" ) ) newbuf << wxT( "/" );
|
||||
else if( token == wxT( "bar" ) ) newbuf << wxT( "|" );
|
||||
else if( token == wxT( "comma" ) ) newbuf << wxT( "," );
|
||||
else if( token == wxT( "colon" ) ) newbuf << wxT( ":" );
|
||||
else if( token == wxT( "space" ) ) newbuf << wxT( " " );
|
||||
else if( token == wxT( "dollar" ) ) newbuf << wxT( "$" );
|
||||
else if( token == wxT( "tab" ) ) newbuf << wxT( "\t" );
|
||||
else if( token == wxT( "return" ) ) newbuf << wxT( "\n" );
|
||||
else if( token == wxT( "brace" ) ) newbuf << wxT( "{" );
|
||||
else
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( ch );
|
||||
newbuf << ch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,11 +785,14 @@ int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreC
|
||||
// Any numerical comparisons to here are identical.
|
||||
if( aIgnoreCase )
|
||||
{
|
||||
if( wxToupper( c1 ) < wxToupper( c2 ) )
|
||||
return -1;
|
||||
if( c1 != c2 )
|
||||
{
|
||||
wxUniChar uc1 = wxToupper( c1 );
|
||||
wxUniChar uc2 = wxToupper( c2 );
|
||||
|
||||
if( wxToupper( c1 ) > wxToupper( c2 ) )
|
||||
return 1;
|
||||
if( uc1 != uc2 )
|
||||
return uc1 < uc2 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -54,8 +54,16 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
|
||||
case FOOTPRINT_FIELD: return s_CanonicalFootprint; // The footprint for use with Pcbnew
|
||||
case DATASHEET_FIELD: return s_CanonicalDatasheet; // Link to a datasheet for symbol
|
||||
case DESCRIPTION_FIELD: return s_CanonicalDescription; // The symbol description
|
||||
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
|
||||
default: break;
|
||||
}
|
||||
|
||||
wxString str( wxS( "Field" ) );
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
str << std::to_wstring( aFieldNdx );
|
||||
#else
|
||||
str << std::to_string( aFieldNdx );
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
switch( aFieldNdx )
|
||||
|
||||
+16
-9
@@ -98,6 +98,18 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
|
||||
bool tokenUpdated = false;
|
||||
wxString originalToken = *aToken;
|
||||
|
||||
auto getCurrentDate =
|
||||
[]() -> wxString
|
||||
{
|
||||
// We can choose different formats. Should probably be kept in sync with ISSUE_DATE
|
||||
// formatting in DIALOG_PAGES_SETTINGS.
|
||||
//
|
||||
// return wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_SHORT_DATE_FMT ) );
|
||||
// return wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_LONG_DATE_FMT ) );
|
||||
// return wxDateTime::Now().Format( wxT("%Y-%b-%d") );
|
||||
return wxDateTime::Now().FormatISODate();
|
||||
};
|
||||
|
||||
if( aToken->IsSameAs( wxT( "ISSUE_DATE" ) ) )
|
||||
{
|
||||
*aToken = GetDate();
|
||||
@@ -105,14 +117,7 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
|
||||
}
|
||||
else if( aToken->IsSameAs( wxT( "CURRENT_DATE" ) ) )
|
||||
{
|
||||
// We can choose different formats. Should probably be kept in sync with ISSUE_DATE
|
||||
// formatting in DIALOG_PAGES_SETTINGS.
|
||||
//
|
||||
// *aToken = wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_SHORT_DATE_FMT ) );
|
||||
// *aToken = wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_LONG_DATE_FMT ) );
|
||||
// *aToken = wxDateTime::Now().Format( wxT("%Y-%b-%d") );
|
||||
*aToken = wxDateTime::Now().FormatISODate();
|
||||
|
||||
*aToken = getCurrentDate();
|
||||
tokenUpdated = true;
|
||||
}
|
||||
else if( aToken->IsSameAs( wxT( "REVISION" ) ) )
|
||||
@@ -152,7 +157,9 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
|
||||
|
||||
if( tokenUpdated )
|
||||
{
|
||||
if( aProject )
|
||||
if( aToken->IsSameAs( wxT( "CURRENT_DATE" ) ) )
|
||||
*aToken = getCurrentDate();
|
||||
else if( aProject )
|
||||
*aToken = ExpandTextVars( *aToken, aProject );
|
||||
|
||||
// This is the default fallback, so don't claim we resolved it
|
||||
|
||||
+16
-11
@@ -39,6 +39,7 @@
|
||||
#include <wx/stc/stc.h>
|
||||
#include <textentry_tricks.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/grid.h>
|
||||
#include <widgets/ui_common.h>
|
||||
|
||||
using namespace std::placeholders;
|
||||
@@ -436,7 +437,8 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
// events first.
|
||||
if( dynamic_cast<wxTextEntry*>( focus )
|
||||
|| dynamic_cast<wxStyledTextCtrl*>( focus )
|
||||
|| dynamic_cast<wxListView*>( focus ) )
|
||||
|| dynamic_cast<wxListView*>( focus )
|
||||
|| dynamic_cast<wxGrid*>( focus ) )
|
||||
{
|
||||
// Original key event has been lost, so we have to re-create it from the menu's
|
||||
// wxAcceleratorEntry.
|
||||
@@ -451,7 +453,7 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
keyEvent.m_shiftDown = ( acceleratorKey->GetFlags() & wxMOD_SHIFT ) > 0;
|
||||
keyEvent.m_altDown = ( acceleratorKey->GetFlags() & wxMOD_ALT ) > 0;
|
||||
|
||||
if( auto ctrl = dynamic_cast<wxTextEntry*>( focus ) )
|
||||
if( wxTextEntry* ctrl = dynamic_cast<wxTextEntry*>( focus ) )
|
||||
TEXTENTRY_TRICKS::OnCharHook( ctrl, keyEvent );
|
||||
else
|
||||
focus->HandleWindowEvent( keyEvent );
|
||||
@@ -462,10 +464,14 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
focus->HandleWindowEvent( keyEvent );
|
||||
}
|
||||
|
||||
// If the event was used as KEY event (not skipped) by the focused window,
|
||||
// just finish.
|
||||
// Otherwise this is actually a wxEVT_COMMAND_MENU_SELECTED, or the
|
||||
// focused window is read only
|
||||
// Don't bubble-up dangerous actions; the target may be behind a modeless dialog.
|
||||
// Cf. https://gitlab.com/kicad/code/kicad/-/issues/17229
|
||||
if( keyEvent.GetKeyCode() == WXK_BACK || keyEvent.GetKeyCode() == WXK_DELETE )
|
||||
return;
|
||||
|
||||
// If the event was used as a KEY event (not skipped) by the focused window,
|
||||
// just finish. Otherwise this is actually a wxEVT_COMMAND_MENU_SELECTED (or the
|
||||
// focused window is read only).
|
||||
if( !keyEvent.GetSkipped() )
|
||||
return;
|
||||
}
|
||||
@@ -546,11 +552,10 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
{
|
||||
evt->SetMousePosition( g_menu_open_position );
|
||||
}
|
||||
// Check if it is a menubar event, and don't get any position if it is.
|
||||
// The original hack is to see if g_last_menu_highlighted_id matches to see if it's a menubar menu event
|
||||
// IsAttached() checks to see if a menubar was attached to the menu by wx, and if there is one, then the event
|
||||
// is from a menubar menu.
|
||||
else if( IsAttached() || ( g_last_menu_highlighted_id == aEvent.GetId() ) )
|
||||
// Check if it is a menubar event, and don't get any position if it is. Note that we
|
||||
// can't use IsAttached() here, as it only differentiates a context menu, and we also
|
||||
// want a hotkey to generate a position.
|
||||
else if( g_last_menu_highlighted_id == aEvent.GetId() )
|
||||
{
|
||||
evt->SetHasPosition( false );
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void ACTION_TOOLBAR_PALETTE::AddAction( const TOOL_ACTION& aAction )
|
||||
button->SetBitmap( normalBmp );
|
||||
button->SetDisabledBitmap( KiDisabledBitmapBundle( aAction.GetIcon() ) );
|
||||
button->SetPadding( padding );
|
||||
button->SetToolTip( aAction.GetTooltip() );
|
||||
button->SetToolTip( aAction.GetButtonTooltip() );
|
||||
button->AcceptDragInAsClick();
|
||||
button->SetBitmapCentered();
|
||||
|
||||
@@ -233,7 +233,7 @@ void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction, bool aIsToggleEntry, bool
|
||||
AddTool( toolId, wxEmptyString, KiBitmapBundle( aAction.GetIcon() ),
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ),
|
||||
aIsToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL,
|
||||
aAction.GetTooltip(), wxEmptyString, nullptr );
|
||||
aAction.GetButtonTooltip(), wxEmptyString, nullptr );
|
||||
|
||||
m_toolKinds[ toolId ] = aIsToggleEntry;
|
||||
m_toolActions[ toolId ] = &aAction;
|
||||
@@ -246,8 +246,8 @@ void ACTION_TOOLBAR::AddButton( const TOOL_ACTION& aAction )
|
||||
int toolId = aAction.GetUIId();
|
||||
|
||||
AddTool( toolId, wxEmptyString, KiBitmapBundle( aAction.GetIcon() ),
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ),
|
||||
wxITEM_NORMAL, aAction.GetTooltip(), wxEmptyString, nullptr );
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ), wxITEM_NORMAL,
|
||||
aAction.GetButtonTooltip(), wxEmptyString, nullptr );
|
||||
|
||||
m_toolKinds[ toolId ] = false;
|
||||
m_toolActions[ toolId ] = &aAction;
|
||||
|
||||
+1
-13
@@ -120,14 +120,12 @@ TOOL_ACTION ACTIONS::print( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( MD_CTRL + 'P' )
|
||||
.LegacyHotkeyName( "Print" )
|
||||
.FriendlyName( _( "Print..." ) )
|
||||
.Tooltip( _( "Print" ) )
|
||||
.Icon( BITMAPS::print_button ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::plot( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.plot" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Plot..." ) )
|
||||
.Tooltip( _( "Plot" ) )
|
||||
.Icon( BITMAPS::plot ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::quit( TOOL_ACTION_ARGS()
|
||||
@@ -408,7 +406,6 @@ TOOL_ACTION ACTIONS::zoomFitScreen( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom Auto" )
|
||||
.FriendlyName( _( "Zoom to Fit" ) )
|
||||
.Tooltip( _( "Zoom to Fit" ) )
|
||||
.Icon( BITMAPS::zoom_fit_in_page ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomFitObjects( TOOL_ACTION_ARGS()
|
||||
@@ -416,7 +413,6 @@ TOOL_ACTION ACTIONS::zoomFitObjects( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_GLOBAL )
|
||||
.DefaultHotkey( MD_CTRL + WXK_HOME )
|
||||
.FriendlyName( _( "Zoom to Objects" ) )
|
||||
.Tooltip( _( "Zoom to Objects" ) )
|
||||
.Icon( BITMAPS::zoom_fit_to_objects ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomIn( TOOL_ACTION_ARGS()
|
||||
@@ -429,7 +425,6 @@ TOOL_ACTION ACTIONS::zoomIn( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom In" )
|
||||
.FriendlyName( _( "Zoom In at Cursor" ) )
|
||||
.Tooltip( _( "Zoom In at Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_in ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomOut( TOOL_ACTION_ARGS()
|
||||
@@ -442,21 +437,18 @@ TOOL_ACTION ACTIONS::zoomOut( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom Out" )
|
||||
.FriendlyName( _( "Zoom Out at Cursor" ) )
|
||||
.Tooltip( _( "Zoom Out at Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_out ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomInCenter( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.zoomInCenter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Zoom In" ) )
|
||||
.Tooltip( _( "Zoom In" ) )
|
||||
.Icon( BITMAPS::zoom_in ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomOutCenter( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.zoomOutCenter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Zoom Out" ) )
|
||||
.Tooltip( _( "Zoom Out" ) )
|
||||
.Icon( BITMAPS::zoom_out ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS()
|
||||
@@ -465,7 +457,6 @@ TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( WXK_F4 )
|
||||
.LegacyHotkeyName( "Zoom Center" )
|
||||
.FriendlyName( _( "Center on Cursor" ) )
|
||||
.Tooltip( _( "Center on Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_center_on_screen ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomTool( TOOL_ACTION_ARGS()
|
||||
@@ -474,7 +465,6 @@ TOOL_ACTION ACTIONS::zoomTool( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( MD_CTRL + WXK_F5 )
|
||||
.LegacyHotkeyName( "Zoom to Selection" )
|
||||
.FriendlyName( _( "Zoom to Selection" ) )
|
||||
.Tooltip( _( "Zoom to Selection" ) )
|
||||
.Icon( BITMAPS::zoom_area )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
@@ -819,19 +809,17 @@ TOOL_ACTION ACTIONS::toggleBoundingBoxes( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.toggleBoundingBoxes" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Draw Bounding Boxes" ) )
|
||||
.Tooltip( _( "Draw Bounding Boxes" ) )
|
||||
.Icon( BITMAPS::gerbview_show_negative_objects ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::selectionTool( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveSelection.selectionTool" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select item(s)" ) )
|
||||
.Tooltip( _( "Select item(s)" ) )
|
||||
.Icon( BITMAPS::cursor )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::measureTool( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveEdit.measureTool" )
|
||||
.Name( "common.Interactive.measureTool" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.DefaultHotkey( MD_CTRL + MD_SHIFT + 'M' )
|
||||
// Don't be tempted to remove "Modern Toolset only". It's in the legacy property name.
|
||||
|
||||
@@ -547,7 +547,7 @@ int COMMON_TOOLS::ToggleGridOverrides( const TOOL_EVENT& aEvent )
|
||||
int COMMON_TOOLS::GridProperties( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto showGridPrefs =
|
||||
[this]( wxString aParentName )
|
||||
[this]( const wxString& aParentName )
|
||||
{
|
||||
m_frame->CallAfter(
|
||||
[this, aParentName]()
|
||||
@@ -563,6 +563,7 @@ int COMMON_TOOLS::GridProperties( const TOOL_EVENT& aEvent )
|
||||
case FRAME_PCB_EDITOR: showGridPrefs( _( "PCB Editor" ) ); break;
|
||||
case FRAME_FOOTPRINT_EDITOR: showGridPrefs( _( "Footprint Editor" ) ); break;
|
||||
case FRAME_PL_EDITOR: showGridPrefs( _( "Drawing Sheet Editor" ) ); break;
|
||||
case FRAME_GERBER: showGridPrefs( _( "Gerber Viewer" ) ); break;
|
||||
default: wxFAIL_MSG( "Unknown frame: " + GetName() ); break;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,15 +39,7 @@ GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) :
|
||||
{
|
||||
UpdateTitle();
|
||||
SetIcon( BITMAPS::grid_select );
|
||||
|
||||
APP_SETTINGS_BASE* settings = m_parent->config();
|
||||
wxArrayString gridsList;
|
||||
int i = ID_POPUP_GRID_START;
|
||||
|
||||
BuildChoiceList( &gridsList, settings, m_parent );
|
||||
|
||||
for( const wxString& grid : gridsList )
|
||||
Append( i++, grid, wxEmptyString, wxITEM_CHECK );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +69,9 @@ void GRID_MENU::update()
|
||||
while( GetMenuItemCount() > 0 )
|
||||
Delete( FindItemByPosition( 0 ) );
|
||||
|
||||
Add( ACTIONS::gridOrigin );
|
||||
AppendSeparator();
|
||||
|
||||
for( const wxString& grid : gridsList )
|
||||
{
|
||||
int idx = i++;
|
||||
|
||||
@@ -167,6 +167,27 @@ size_t SELECTION::CountType( KICAD_T aType ) const
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I SELECTION::GetReferencePoint() const
|
||||
{
|
||||
if( m_referencePoint )
|
||||
return *m_referencePoint;
|
||||
else
|
||||
return GetBoundingBox().Centre();
|
||||
}
|
||||
|
||||
|
||||
void SELECTION::SetReferencePoint( const VECTOR2I& aP )
|
||||
{
|
||||
m_referencePoint = aP;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION::ClearReferencePoint()
|
||||
{
|
||||
m_referencePoint = std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<KIGFX::VIEW_ITEM*> SELECTION::updateDrawList() const
|
||||
{
|
||||
std::vector<VIEW_ITEM*> items;
|
||||
|
||||
@@ -183,6 +183,21 @@ wxString TOOL_ACTION::GetTooltip( bool aIncludeHotkey ) const
|
||||
}
|
||||
|
||||
|
||||
wxString TOOL_ACTION::GetButtonTooltip() const
|
||||
{
|
||||
// We don't show button text so use the action name as the first line of the tooltip
|
||||
wxString tooltip = GetFriendlyName();
|
||||
|
||||
if( GetHotKey() )
|
||||
tooltip += wxString::Format( wxT( " (%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
|
||||
|
||||
if( !GetTooltip( false ).IsEmpty() )
|
||||
tooltip += '\n' + GetTooltip( false );
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
|
||||
void TOOL_ACTION::SetHotKey( int aKeycode, int aKeycodeAlt )
|
||||
{
|
||||
m_hotKey = aKeycode;
|
||||
|
||||
@@ -362,7 +362,6 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const std
|
||||
|
||||
while( synchronousControl == STS_RUNNING )
|
||||
{
|
||||
wxMilliSleep( 50 );
|
||||
wxYield();
|
||||
}
|
||||
|
||||
@@ -705,7 +704,7 @@ TOOL_EVENT* TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool, const TOOL_EVENT_LIST&
|
||||
{
|
||||
TOOL_STATE* st = m_toolState[aTool];
|
||||
|
||||
wxASSERT( !st->pendingWait ); // everything collapses on two KiYield() in a row
|
||||
wxCHECK( !st->pendingWait, nullptr ); // everything collapses on two KiYield() in a row
|
||||
|
||||
// indicate to the manager that we are going to sleep and we shall be
|
||||
// woken up when an event matching aConditions arrive
|
||||
@@ -942,8 +941,14 @@ void TOOL_MANAGER::DispatchContextMenu( const TOOL_EVENT& aEvent )
|
||||
if( wxWindow* frame = dynamic_cast<wxWindow*>( m_frame ) )
|
||||
frame->PopupMenu( menu.get() );
|
||||
|
||||
// If a menu is canceled then notify tool
|
||||
if( menu->GetSelected() < 0 )
|
||||
// Warp the cursor if a menu item was selected
|
||||
if( menu->GetSelected() >= 0 )
|
||||
{
|
||||
if( m_viewControls && m_warpMouseAfterContextMenu )
|
||||
m_viewControls->WarpMouseCursor( m_menuCursor, true, false );
|
||||
}
|
||||
// Otherwise notify the tool of a cancelled menu
|
||||
else
|
||||
{
|
||||
TOOL_EVENT evt( TC_COMMAND, TA_CHOICE_MENU_CHOICE, -1 );
|
||||
evt.SetHasPosition( false );
|
||||
|
||||
@@ -213,6 +213,27 @@ EDA_ITEM_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) const
|
||||
}
|
||||
|
||||
|
||||
KIID PICKED_ITEMS_LIST::GetPickedItemGroupId( unsigned aIdx ) const
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
return m_ItemsList[aIdx].GetGroupId();
|
||||
|
||||
return KIID();
|
||||
}
|
||||
|
||||
|
||||
bool PICKED_ITEMS_LIST::SetPickedItemGroupId( KIID aGroupId, unsigned aIdx )
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
{
|
||||
m_ItemsList[aIdx].SetGroupId( aGroupId );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
|
||||
+27
-7
@@ -234,6 +234,8 @@ private:
|
||||
int m_groupsSize;
|
||||
|
||||
std::vector<int> m_layers; /// Stores layer numbers used by the item.
|
||||
|
||||
BOX2I m_bbox; /// Cached inserted Bbox for faster removals.
|
||||
};
|
||||
|
||||
|
||||
@@ -326,6 +328,8 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
|
||||
aItem->m_viewPrivData->m_view = this;
|
||||
aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
|
||||
const BOX2I bbox = aItem->ViewBBox();
|
||||
aItem->m_viewPrivData->m_bbox = bbox;
|
||||
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
aItem->viewPrivData()->saveLayers( layers, layers_count );
|
||||
@@ -338,7 +342,7 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
l.items->Insert( aItem, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
|
||||
@@ -362,11 +366,12 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
aItem->m_viewPrivData->getLayers( layers, layers_count );
|
||||
const BOX2I* bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Remove( aItem, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
@@ -617,6 +622,9 @@ void VIEW::SetCenter( const VECTOR2D& aCenter, const std::vector<BOX2D>& obscuri
|
||||
BOX2I bbox = unobscuredPoly.BBox();
|
||||
int step = std::min( bbox.GetWidth(), bbox.GetHeight() ) / 10;
|
||||
|
||||
if( step < 20 )
|
||||
step = 20;
|
||||
|
||||
while( !unobscuredPoly.IsEmpty() )
|
||||
{
|
||||
unobscuredCenter = unobscuredPoly.BBox().Centre();
|
||||
@@ -1327,12 +1335,17 @@ void VIEW::updateBbox( VIEW_ITEM* aItem )
|
||||
int layers[VIEW_MAX_LAYERS], layers_count;
|
||||
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
wxASSERT( aItem->m_viewPrivData ); //must have a viewPrivData
|
||||
|
||||
const BOX2I new_bbox = aItem->ViewBBox();
|
||||
const BOX2I* old_bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
aItem->m_viewPrivData->m_bbox = new_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Insert( aItem );
|
||||
l.items->Remove( aItem, old_bbox );
|
||||
l.items->Insert( aItem, new_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
}
|
||||
@@ -1348,11 +1361,12 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
|
||||
// Remove the item from previous layer set
|
||||
viewData->getLayers( layers, layers_count );
|
||||
const BOX2I* old_bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Remove( aItem, old_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
if( IsCached( l.id ) )
|
||||
@@ -1368,6 +1382,9 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
}
|
||||
}
|
||||
|
||||
const BOX2I new_bbox = aItem->ViewBBox();
|
||||
aItem->m_viewPrivData->m_bbox = new_bbox;
|
||||
|
||||
// Add the item to new layer set
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
viewData->saveLayers( layers, layers_count );
|
||||
@@ -1375,7 +1392,7 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
for( int i = 0; i < layers_count; i++ )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
l.items->Insert( aItem, new_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
}
|
||||
@@ -1463,6 +1480,9 @@ void VIEW::UpdateItems()
|
||||
// and re-insert items from scratch
|
||||
for( VIEW_ITEM* item : allItems )
|
||||
{
|
||||
const BOX2I bbox = item->ViewBBox();
|
||||
item->m_viewPrivData->m_bbox = bbox;
|
||||
|
||||
item->ViewGetLayers( layers, layers_count );
|
||||
item->viewPrivData()->saveLayers( layers, layers_count );
|
||||
|
||||
@@ -1471,7 +1491,7 @@ void VIEW::UpdateItems()
|
||||
wxCHECK2_MSG( layers[i] >= 0 && static_cast<unsigned>( layers[i] ) < m_layers.size(),
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( item );
|
||||
l.items->Insert( item, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, EDA_DRAW_PANEL_GAL* aParentPane
|
||||
m_lastTimestamp( 0 ),
|
||||
#endif
|
||||
m_cursorPos( 0, 0 ),
|
||||
m_updateCursor( true )
|
||||
m_updateCursor( true ),
|
||||
m_infinitePanWorks( false )
|
||||
{
|
||||
LoadSettings();
|
||||
|
||||
@@ -276,7 +277,8 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
if( !justWarped )
|
||||
{
|
||||
if( KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) )
|
||||
if( m_infinitePanWorks
|
||||
&& KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) )
|
||||
{
|
||||
m_dragStartPoint += VECTOR2D( warpX, warpY );
|
||||
justWarped = true;
|
||||
@@ -452,7 +454,7 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
|
||||
{
|
||||
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
|
||||
setState( DRAG_PANNING );
|
||||
KIPLATFORM::UI::InfiniteDragPrepareWindow( m_parentPanel );
|
||||
m_infinitePanWorks = KIPLATFORM::UI::InfiniteDragPrepareWindow( m_parentPanel );
|
||||
|
||||
#if defined USE_MOUSE_CAPTURE
|
||||
if( !m_parentPanel->HasCapture() )
|
||||
|
||||
@@ -92,6 +92,12 @@ void FOOTPRINT_PREVIEW_WIDGET::SetUserUnits( EDA_UNITS aUnits )
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_WIDGET::SetPinFunctions( const std::map<wxString, wxString>& aPinFunctions )
|
||||
{
|
||||
m_prev_panel->SetPinFunctions( aPinFunctions );
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_WIDGET::DisplayFootprint( const LIB_ID& aFPID )
|
||||
{
|
||||
if( !m_prev_panel || m_libid == aFPID )
|
||||
|
||||
@@ -287,8 +287,8 @@ protected:
|
||||
|
||||
/*
|
||||
* Symbol netlist format:
|
||||
* pinCount
|
||||
* fpFilters
|
||||
* pinNumber pinName <tab> pinNumber pinName...
|
||||
* fpFilter fpFilter...
|
||||
*/
|
||||
std::string m_symbolNetlist;
|
||||
};
|
||||
|
||||
@@ -128,11 +128,14 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
m_query_ctrl->Bind( wxEVT_SEARCH_CANCEL, &LIB_TREE::onQueryText, this );
|
||||
m_query_ctrl->Bind( wxEVT_CHAR_HOOK, &LIB_TREE::onQueryCharHook, this );
|
||||
m_query_ctrl->Bind( wxEVT_MOTION, &LIB_TREE::onQueryMouseMoved, this );
|
||||
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
m_query_ctrl->Bind( wxEVT_LEAVE_WINDOW,
|
||||
[this] ( wxMouseEvent& aEvt )
|
||||
[this]( wxMouseEvent& aEvt )
|
||||
{
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
} );
|
||||
#endif
|
||||
|
||||
m_query_ctrl->Bind( wxEVT_MENU,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
@@ -153,6 +156,12 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
m_tree_ctrl = new WX_DATAVIEWCTRL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, dvFlags );
|
||||
m_adapter->AttachTo( m_tree_ctrl );
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// The GTK renderer seems to calculate row height incorrectly sometimes; but can be overridden
|
||||
int rowHeight = FromDIP( 8 ) + GetTextExtent( wxS( "pdI" ) ).y;
|
||||
m_tree_ctrl->SetRowHeight( rowHeight );
|
||||
#endif
|
||||
|
||||
sizer->Add( m_tree_ctrl, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
|
||||
|
||||
// Description panel
|
||||
@@ -618,6 +627,7 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
|
||||
|
||||
void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_query_ctrl->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -628,6 +638,7 @@ void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -529,7 +529,9 @@ protected:
|
||||
|
||||
void doSetFocus( wxWindow* aWindow )
|
||||
{
|
||||
#ifndef __WXGTK__ // Cannot focus in non-toplevel windows on GTK
|
||||
KIPLATFORM::UI::ForceFocus( aWindow );
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -355,7 +355,8 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( dynamic_cast<wxTextEntry*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxListView*>( aEvent.GetEventObject() ) )
|
||||
|| dynamic_cast<wxListView*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxGrid*>( FindFocus() ) )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
@@ -373,7 +374,7 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
m_treebook->SetSelection( page - 1 );
|
||||
}
|
||||
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal focus
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal gridFocus
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_DOWN )
|
||||
{
|
||||
@@ -381,7 +382,7 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
|
||||
m_treebook->SetSelection( std::min<int>( page + 1, m_treebook->GetPageCount() - 1 ) );
|
||||
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal focus
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal gridFocus
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user