Compare commits
331 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 063d9c8305 | |||
| 5e97608fa5 | |||
| 50dca2d02b | |||
| cd3785744c | |||
| 357810a5d5 | |||
| 1b71bc115d | |||
| de40286e81 | |||
| 8d0ff95760 | |||
| ffddf9fec3 | |||
| 3a35d96130 | |||
| 8add678d87 | |||
| a8bcf8c9e4 | |||
| 090374a1dc | |||
| e7aa95d53d | |||
| f6ccf18cf5 | |||
| 4542ce8c70 | |||
| f80287bc27 | |||
| e10ab74917 | |||
| 23ddb99026 | |||
| efbac9e128 | |||
| 62044c2731 | |||
| 7d1a38d46f | |||
| d885bc14e1 | |||
| 886937a3ea | |||
| 99eff43ab4 | |||
| 880269780d | |||
| 7f1b891679 | |||
| ceced2a9a4 | |||
| d3a8cb84a6 | |||
| 6b43bb8fe3 | |||
| a74cffac39 | |||
| 83d2891cef | |||
| 0faad370f9 | |||
| 23fab89131 | |||
| 48189172ea | |||
| 0c9eda44d4 | |||
| f0a9ce3ab4 | |||
| ea5878a0c9 | |||
| f67382612d | |||
| 3fe7ae07ed | |||
| 8bcfa81bea | |||
| c17918d9c1 | |||
| f752df0595 | |||
| 0836b5b661 | |||
| 2cefccf7bf | |||
| 3dc86c5a4f | |||
| 05ae712e77 | |||
| 04db374326 | |||
| e3558b7dcf | |||
| 99e10c6112 | |||
| 537934339e | |||
| ee343e1263 | |||
| 6eeca9aa90 | |||
| 86beb339b7 | |||
| 67b5af23aa | |||
| 88f65f4e47 | |||
| af5b6b0eba | |||
| 57ef739404 | |||
| 584eb9f531 | |||
| 36a4d5a511 | |||
| 72737b20cd | |||
| d05093e6f7 | |||
| a7e6928f4e | |||
| 951fd2d693 | |||
| be991cfcd6 | |||
| aab36d9b85 | |||
| 3cd6935acb | |||
| 6daef080e3 | |||
| 6ee909b958 | |||
| c11ae8bd02 | |||
| c7a4ea97c3 | |||
| 81ebb1030a | |||
| 86ec36d183 | |||
| 207f2e568b | |||
| 19753719cb | |||
| 5f025dcd73 | |||
| c796eeaf8b | |||
| bdbd7f0c9c | |||
| b0e09327db | |||
| 96a3621b8e | |||
| 8f259211e7 | |||
| 0d9d8c28f1 | |||
| 058a0bbf93 | |||
| 4d46e0ceb7 | |||
| 123ff326d4 | |||
| 14d4c38979 | |||
| 9c87a52b6e | |||
| 30c2028852 | |||
| 95e6be0e81 | |||
| 955313e97d | |||
| 32c2135047 | |||
| 702e08b083 | |||
| 8f58e1a9e0 | |||
| 0cc25f10c6 | |||
| 61ef88a0ac | |||
| 02a95b958d | |||
| 5cd88dbd20 | |||
| ec53ed6a37 | |||
| 242413a334 | |||
| f88dce1627 | |||
| 5c456370d9 | |||
| 93fdd35b31 | |||
| 70d5fccb54 | |||
| 6ca7c3a3a1 | |||
| 88448ce746 | |||
| 1fee2c626b | |||
| 480a9ac77d | |||
| 889689e31a | |||
| c8e49599ce | |||
| 351cb7e104 | |||
| 5c5e41500a | |||
| 2e739e743d | |||
| 1eee3d350b | |||
| d2d7e630bd | |||
| d11cd173dc | |||
| 12e0427038 | |||
| 9bcb6f0adf | |||
| 09490e1f46 | |||
| f33120c540 | |||
| 82ed223b02 | |||
| bfdbf969c2 | |||
| 7d409b9404 | |||
| 7673f220a9 | |||
| 75daa1afec | |||
| 27657e00fe | |||
| 26b8812f15 | |||
| 07e13c51d1 | |||
| f9b59b4fdf | |||
| 76a3b3db97 | |||
| 4b0416e92a | |||
| 5d6bb4b04f | |||
| 2764f292cb | |||
| 7ca59e24c6 | |||
| e1a2d60672 | |||
| 9672390104 | |||
| 33c2005c18 | |||
| 3e1309110e | |||
| aae7d94ffd | |||
| 5b0d752e0c | |||
| 0f93752f14 | |||
| 049ecc43e3 | |||
| 2209f5e93b | |||
| a17cd9d054 | |||
| 4497aaa3fa | |||
| 00226ae40a | |||
| 45963a3443 | |||
| 4aa1a881f3 | |||
| f3dd5b73f8 | |||
| fd049ef510 | |||
| 7d389f8024 | |||
| df63f47deb | |||
| c521efa35d | |||
| af1561b848 | |||
| 691931f74d | |||
| da5e1de1c8 | |||
| 043892bdc6 | |||
| 34d2aeaac3 | |||
| 4481e89046 | |||
| 8120e47bfd | |||
| db526e581c | |||
| 246be732a1 | |||
| 27a0bd2535 | |||
| 8f57fd82a0 | |||
| 1ef90c898e | |||
| cf133975c1 | |||
| c468b68c5a | |||
| acbddc904b | |||
| 83624acfd2 | |||
| d915ddc647 | |||
| 61b741c34e | |||
| aa1910a834 | |||
| dba36c07fe | |||
| 8451e6dcf1 | |||
| 88dfe6eb9c | |||
| 800b697d06 | |||
| 2176a654cd | |||
| 2176788d1c | |||
| 6389fa2d81 | |||
| 8a0b64dd00 | |||
| 79ac207532 | |||
| c33e12b66f | |||
| 5d0dfb80d4 | |||
| 7ebab92f16 | |||
| 1a851f7c33 | |||
| 74ee8bea5d | |||
| dec1748978 | |||
| 4ef47e1040 | |||
| 42f242ce42 | |||
| c4914a64bb | |||
| 4aa05dfcf2 | |||
| 255ff5d789 | |||
| 75f5186dec | |||
| 0cf6d80705 | |||
| 2d96c6ad22 | |||
| ef7ec13861 | |||
| 8008e09918 | |||
| 75ace76c6a | |||
| 9de58a29e3 | |||
| 56aff41b7e | |||
| a8417a7e23 | |||
| 582c9b7f08 | |||
| 2eb6ca75a8 | |||
| 4918ac6307 | |||
| acc03e91f3 | |||
| 8e1466a35a | |||
| 5b73af668f | |||
| deb035c7fe | |||
| 2075a99c9b | |||
| 74b1f603df | |||
| ed1eb1c018 | |||
| 4bed2e57cb | |||
| 0629f502b5 | |||
| fd93873cc1 | |||
| dbd58dbbc6 | |||
| b2edf61588 | |||
| 96b6975deb | |||
| 9449dab0b7 | |||
| 6da9dbcc53 | |||
| d1bdea21b4 | |||
| 5ea0f3253f | |||
| b1e5c02e0c | |||
| f48d97ab04 | |||
| 8f85e04d61 | |||
| 1eab9b34fe | |||
| 13a3c44b61 | |||
| f6b106598c | |||
| f6aed13605 | |||
| 62dd8e67df | |||
| ba7620e0ee | |||
| 931f6a35dd | |||
| d3394733b1 | |||
| 0f5d175b09 | |||
| c93111bf4b | |||
| adb0f0a46f | |||
| 60454c0c39 | |||
| de35de9e00 | |||
| d5d91ae592 | |||
| 9c852af5b7 | |||
| 24fcfd125c | |||
| 1ad42519d6 | |||
| 3052dcc95a | |||
| 17089d8316 | |||
| ce919632be | |||
| f3168c3603 | |||
| a6ca88b5ac | |||
| 8625a59d4c | |||
| cb4289fd19 | |||
| 9ac5f837f7 | |||
| 033ab9ac71 | |||
| 228fe71eb4 | |||
| 80462cf559 | |||
| e5df16ba2b | |||
| b0f4d56de1 | |||
| 7bc0f8731f | |||
| b4b49a4296 | |||
| 507054e9cd | |||
| 342b8b157b | |||
| 74fc8f6db0 | |||
| 04bb3dfe9d | |||
| 7fb15269d1 | |||
| 49772d2539 | |||
| 0f4bd34bce | |||
| 2451cbddec | |||
| b7363225da | |||
| a9c0756da4 | |||
| 2652068933 | |||
| 022105cdba | |||
| 2fa05ed245 | |||
| 124be52411 | |||
| 6f8272718d | |||
| bac1fb18f0 | |||
| 391204ea0d | |||
| 810f3efcbb | |||
| e4a80d887a | |||
| 45d496bd01 | |||
| 20a5b2d4c4 | |||
| cc2637b310 | |||
| 3fc404cd25 | |||
| e016fa913f | |||
| e1c6f4f58f | |||
| c50888fc79 | |||
| 7c0a911e9f | |||
| 0562776b7a | |||
| 9cf79ffb5a | |||
| 63b0ef65e0 | |||
| 62bf6a9d57 | |||
| 4ad6244d8d | |||
| b2f72020bd | |||
| d73f96e3d8 | |||
| f8210e4a2a | |||
| 1ccaf45740 | |||
| d268ccea5b | |||
| 10efb6e55a | |||
| 171c44507a | |||
| 9514f057dc | |||
| e154857aca | |||
| 59c06bcaf1 | |||
| 17f02b2ff0 | |||
| 6316b78a5e | |||
| e53269c37f | |||
| a43adf7d4f | |||
| 16d24d4b43 | |||
| 4a3ae82748 | |||
| 60fe2ce30e | |||
| b294530716 | |||
| 0652267d00 | |||
| b857374aa2 | |||
| 480ce08d39 | |||
| 63f33a42e3 | |||
| f6d1baa50a | |||
| 0df1ec8765 | |||
| 19e128041b | |||
| 76f8b3df22 | |||
| e1e791fc75 | |||
| bbf59a731d | |||
| 803bcbbea0 | |||
| 6f384c8802 | |||
| d6eb66c738 | |||
| 7078381175 | |||
| 0ffef66cb6 | |||
| dfc17244d4 | |||
| ecb9f607ed | |||
| 35126ba22c | |||
| 5cdf03ff6d | |||
| d128b30279 | |||
| cadea90109 | |||
| 90d1695bbc | |||
| 713cb032b5 | |||
| 24ed144200 | |||
| ebc584b2a7 | |||
| dcef21676d |
+4
-2
@@ -23,8 +23,10 @@ test_formatting:
|
||||
allow_failure: true
|
||||
before_script:
|
||||
# We must manually add the KiCad remote to ensure it is named sensibly
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git ||
|
||||
git remote set-url product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git ||
|
||||
git remote set-url source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git fetch -n product
|
||||
- git fetch -n source
|
||||
# Get the SHAs of the commits
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -294,6 +294,16 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
++bl;
|
||||
}
|
||||
|
||||
// prevent loading non-plugin dlls
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
if( !path.GetName().StartsWith( "s3d_plugin" )
|
||||
&& !path.GetName().StartsWith( "libs3d_plugin" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aPluginList.push_back( wxpath );
|
||||
|
||||
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] found 3D plugin '%s'\n" ), wxpath.GetData() );
|
||||
|
||||
@@ -201,7 +201,8 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
|
||||
|
||||
if( textbox->GetLayer() == aLayerId )
|
||||
{
|
||||
addShape( textbox, aContainer, aFootprint );
|
||||
if( textbox->IsBorderEnabled() )
|
||||
addShape( textbox, aContainer, aFootprint );
|
||||
addText( textbox, aContainer, aFootprint );
|
||||
}
|
||||
|
||||
@@ -260,6 +261,19 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
|
||||
{
|
||||
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
|
||||
|
||||
if( arc->IsDegenerated() )
|
||||
{
|
||||
// Draw this very small arc like a track segment (a PCB_TRACE_T)
|
||||
PCB_TRACK track( arc->GetParent() );
|
||||
track.SetStart( arc->GetStart() );
|
||||
track.SetEnd( arc->GetEnd() );
|
||||
track.SetWidth( arc->GetWidth() );
|
||||
track.SetLayer( arc->GetLayer() );
|
||||
|
||||
createTrack( &track, aDstContainer );
|
||||
return;
|
||||
}
|
||||
|
||||
VECTOR2D center( arc->GetCenter() );
|
||||
EDA_ANGLE arc_angle = arc->GetAngle();
|
||||
double radius = arc->GetRadius();
|
||||
@@ -625,16 +639,12 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
|
||||
if( inner_radius3DU < 0 )
|
||||
inner_radius3DU = 0.0;
|
||||
|
||||
if( outer_radius3DU == 0.0 )
|
||||
{
|
||||
// Don't attempt to render degenerate shapes
|
||||
}
|
||||
else if( aShape->IsFilled() )
|
||||
if( aShape->IsFilled() )
|
||||
{
|
||||
aContainer->Add( new FILLED_CIRCLE_2D( center3DU, outer_radius3DU,
|
||||
*aOwner ) );
|
||||
}
|
||||
else
|
||||
else if( outer_radius3DU > inner_radius3DU )
|
||||
{
|
||||
aContainer->Add( new RING_2D( center3DU, inner_radius3DU, outer_radius3DU,
|
||||
*aOwner ) );
|
||||
|
||||
@@ -605,7 +605,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
case PCB_TEXTBOX_T:
|
||||
addText( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
|
||||
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
|
||||
if( static_cast<PCB_TEXTBOX*>( item )->IsBorderEnabled() )
|
||||
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
|
||||
break;
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
|
||||
@@ -931,10 +931,33 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
{
|
||||
float ratio =
|
||||
std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D );
|
||||
m_camera.SetMaxZoom( CAMERA::DEFAULT_MAX_ZOOM * ratio );
|
||||
|
||||
m_camera.SetMinZoom( static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z ) );
|
||||
float max_zoom = CAMERA::DEFAULT_MAX_ZOOM * ratio;
|
||||
float min_zoom = static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z );
|
||||
|
||||
if( min_zoom > max_zoom )
|
||||
std::swap( min_zoom, max_zoom );
|
||||
|
||||
float zoom_ratio = max_zoom / min_zoom;
|
||||
|
||||
// Set the minimum number of zoom 'steps' between max and min.
|
||||
int steps = 3 * 3;
|
||||
steps -= static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
|
||||
steps = std::max( steps, 0 );
|
||||
|
||||
// Resize max and min zoom to accomplish the number of steps.
|
||||
float increased_zoom = pow( 1.26f, steps / 2 );
|
||||
max_zoom *= increased_zoom;
|
||||
min_zoom /= increased_zoom;
|
||||
|
||||
if( steps & 1 )
|
||||
min_zoom /= 1.26f;
|
||||
|
||||
min_zoom = std::min( min_zoom, 1.0f );
|
||||
|
||||
m_camera.SetMaxZoom( max_zoom );
|
||||
m_camera.SetMinZoom( min_zoom );
|
||||
}
|
||||
|
||||
// Create an accelerator
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "panel_preview_3d_model.h"
|
||||
#include <dialogs/dialog_unit_entry.h>
|
||||
#include <3d_canvas/eda_3d_canvas.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
@@ -46,14 +47,14 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
FOOTPRINT* aFootprint,
|
||||
std::vector<FP_3DMODEL>* aParentModelList ) :
|
||||
PANEL_PREVIEW_3D_MODEL_BASE( aParent, wxID_ANY ),
|
||||
m_parentFrame( aFrame ),
|
||||
m_previewPane( nullptr ),
|
||||
m_infobar( nullptr ),
|
||||
m_boardAdapter(),
|
||||
m_currentCamera( m_trackBallCamera ),
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D ),
|
||||
m_boardThickness( aFrame, nullptr, m_boardThicknessCtrl, m_boardThicknessUnits )
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D )
|
||||
{
|
||||
m_userUnits = aFrame->GetUserUnits();
|
||||
m_userUnits = m_parentFrame->GetUserUnits();
|
||||
|
||||
m_dummyBoard = new BOARD();
|
||||
|
||||
@@ -83,6 +84,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_bpvBottom->SetBitmap( KiBitmap( BITMAPS::axis3d_bottom ) );
|
||||
m_bpvISO->SetBitmap( KiBitmap( BITMAPS::ortho ) );
|
||||
m_bpUpdate->SetBitmap( KiBitmap( BITMAPS::reload ) );
|
||||
m_bpSettings->SetBitmap( KiBitmap( BITMAPS::options_3drender ) );
|
||||
|
||||
// Set the min and max values of spin buttons (mandatory on Linux)
|
||||
// They are not used, so they are set to min and max 32 bits int values
|
||||
@@ -103,6 +105,15 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
|
||||
m_dummyFootprint = new FOOTPRINT( *aFootprint );
|
||||
m_dummyFootprint->SetParentGroup( nullptr );
|
||||
|
||||
// Ensure the footprint is shown like in Fp editor: rot 0, not flipped
|
||||
// to avoid mistakes when setting the3D shape position/rotation
|
||||
if( m_dummyFootprint->IsFlipped() )
|
||||
m_dummyFootprint->Flip( m_dummyFootprint->GetPosition(), false );
|
||||
|
||||
m_dummyFootprint->SetOrientation( ANGLE_0 );
|
||||
|
||||
|
||||
m_dummyBoard->Add( m_dummyFootprint );
|
||||
|
||||
// Create the 3D canvas
|
||||
@@ -164,6 +175,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_bpvBottom->SetMinSize( m_bpvBottom->GetSize() + borderFix );
|
||||
m_bpvISO->SetMinSize( m_bpvISO->GetSize() + borderFix );
|
||||
m_bpUpdate->SetMinSize( m_bpUpdate->GetSize() + borderFix );
|
||||
m_bpSettings->SetMinSize( m_bpSettings->GetSize() + borderFix );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -327,9 +339,6 @@ void PANEL_PREVIEW_3D_MODEL::SetSelectedModel( int idx )
|
||||
|
||||
m_opacity->SetValue( 100 );
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
m_boardThickness.ChangeValue( dummy_bds.GetBoardThickness() );
|
||||
}
|
||||
|
||||
|
||||
@@ -382,16 +391,27 @@ void PANEL_PREVIEW_3D_MODEL::onOpacitySlider( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::updateBoardThickness( wxCommandEvent& event )
|
||||
void PANEL_PREVIEW_3D_MODEL::View3DSettings( wxCommandEvent& event )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( m_boardThickness.GetValue() );
|
||||
BOARD_DESIGN_SETTINGS bds = m_dummyBoard->GetDesignSettings();
|
||||
int thickness = bds.GetBoardThickness();
|
||||
|
||||
BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
dummy_board_stackup.RemoveAll();
|
||||
dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
|
||||
WX_UNIT_ENTRY_DIALOG dlg( m_parentFrame, _( "Board Thickness: " ),
|
||||
_( "Preview Settings" ), thickness );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
bds.SetBoardThickness( (int) dlg.GetValue() );
|
||||
|
||||
BOARD_STACKUP& boardStackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
boardStackup.RemoveAll();
|
||||
boardStackup.BuildDefaultStackupList( &bds, 2 );
|
||||
|
||||
UpdateDummyFootprint( true );
|
||||
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,8 +135,6 @@ private:
|
||||
|
||||
void onOpacitySlider( wxCommandEvent& event ) override;
|
||||
|
||||
void updateBoardThickness( wxCommandEvent& event ) override;
|
||||
|
||||
void doIncrementScale( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementRotation( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementOffset( wxSpinEvent& aEvent, double aSign );
|
||||
@@ -174,6 +172,8 @@ private:
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
void View3DSettings( wxCommandEvent& event ) override;
|
||||
|
||||
void View3DRight( wxCommandEvent& event ) override
|
||||
{
|
||||
m_previewPane->SetView3D( ID_VIEW3D_RIGHT );
|
||||
@@ -190,6 +190,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
PCB_BASE_FRAME* m_parentFrame;
|
||||
EDA_3D_CANVAS* m_previewPane;
|
||||
WX_INFOBAR* m_infobar;
|
||||
BOARD_ADAPTER m_boardAdapter;
|
||||
@@ -202,7 +203,6 @@ private:
|
||||
std::vector<FP_3DMODEL>* m_parentModelList;
|
||||
int m_selected; /// Index into m_parentInfoList
|
||||
|
||||
UNIT_BINDER m_boardThickness;
|
||||
EDA_UNITS m_userUnits;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerScale = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Scale") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerScale;
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerScale->AddGrowableCol( 1 );
|
||||
fgSizerScale->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerScale->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -66,7 +66,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerRotation = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Rotation") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerRotate;
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerRotate->AddGrowableCol( 1 );
|
||||
fgSizerRotate->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerRotate->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -111,7 +111,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerOffset = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Offset") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerOffset;
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerOffset->AddGrowableCol( 1 );
|
||||
fgSizerOffset->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerOffset->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -159,20 +159,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizer4->Add( m_opacity, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizer4, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizerBoardThickness;
|
||||
sbSizerBoardThickness = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Board Thickness") ), wxHORIZONTAL );
|
||||
|
||||
m_boardThicknessCtrl = new wxTextCtrl( sbSizerBoardThickness->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sbSizerBoardThickness->Add( m_boardThicknessCtrl, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_boardThicknessUnits = new wxStaticText( sbSizerBoardThickness->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_boardThicknessUnits->Wrap( -1 );
|
||||
sbSizerBoardThickness->Add( m_boardThicknessUnits, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizerBoardThickness, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
bSizerLeft->Add( sbSizer4, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerLeft, 0, 0, 5 );
|
||||
@@ -195,7 +182,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_SizerPanelView = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND|wxBOTTOM, 8 );
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerRight, 1, wxRIGHT|wxLEFT|wxEXPAND, 5 );
|
||||
@@ -212,7 +199,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_bpvLeft = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpvLeft, 0, wxALIGN_LEFT|wxALIGN_RIGHT|wxBOTTOM, 5 );
|
||||
bSizer3DButtons->Add( m_bpvLeft, 0, wxBOTTOM, 5 );
|
||||
|
||||
m_bpvRight = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpvRight, 0, wxBOTTOM, 5 );
|
||||
@@ -237,6 +224,9 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
|
||||
bSizer3DButtons->Add( m_bpUpdate, 0, wxBOTTOM, 5 );
|
||||
|
||||
m_bpSettings = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpSettings, 0, 0, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizer3DButtons, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
|
||||
|
||||
@@ -283,8 +273,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onIncrementOffset ), NULL, this );
|
||||
m_opacity->Connect( wxEVT_SLIDER, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onOpacitySlider ), NULL, this );
|
||||
m_boardThicknessCtrl->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onMouseWheelBoardThickness ), NULL, this );
|
||||
m_boardThicknessCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::updateBoardThickness ), NULL, this );
|
||||
m_bpvISO->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DRight ), NULL, this );
|
||||
@@ -293,6 +281,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_bpvTop->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpSettings->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DSettings ), NULL, this );
|
||||
}
|
||||
|
||||
PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
@@ -335,8 +324,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onIncrementOffset ), NULL, this );
|
||||
m_opacity->Disconnect( wxEVT_SLIDER, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onOpacitySlider ), NULL, this );
|
||||
m_boardThicknessCtrl->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onMouseWheelBoardThickness ), NULL, this );
|
||||
m_boardThicknessCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::updateBoardThickness ), NULL, this );
|
||||
m_bpvISO->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DRight ), NULL, this );
|
||||
@@ -345,5 +332,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
m_bpvTop->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpSettings->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DSettings ), NULL, this );
|
||||
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -686,7 +686,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -1279,7 +1279,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -1847,7 +1847,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxStaticBoxSizer" expanded="1">
|
||||
<property name="id">wxID_ANY</property>
|
||||
@@ -1925,147 +1925,6 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticBoxSizer" expanded="1">
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Board Thickness</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">sbSizerBoardThickness</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="parent">1</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_boardThicknessCtrl</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnMouseWheel">onMouseWheelBoardThickness</event>
|
||||
<event name="OnText">updateBoardThickness</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">mm</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_boardThicknessUnits</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
@@ -2150,7 +2009,7 @@
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">8</property>
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
@@ -2257,7 +2116,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALIGN_RIGHT|wxBOTTOM</property>
|
||||
<property name="flag">wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -2783,6 +2642,80 @@
|
||||
<event name="OnButtonClick">View3DUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag"></property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="current"></property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="disabled"></property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="focus"></property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">MyButton</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_bpSettings</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="position"></property>
|
||||
<property name="pressed"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">View3DSettings</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@@ -66,8 +66,6 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
wxTextCtrl* zoff;
|
||||
wxSpinButton* m_spinZoffset;
|
||||
wxSlider* m_opacity;
|
||||
wxTextCtrl* m_boardThicknessCtrl;
|
||||
wxStaticText* m_boardThicknessUnits;
|
||||
wxStaticText* m_previewLabel;
|
||||
wxBoxSizer* m_SizerPanelView;
|
||||
wxBitmapButton* m_bpvISO;
|
||||
@@ -78,6 +76,7 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
wxBitmapButton* m_bpvTop;
|
||||
wxBitmapButton* m_bpvBottom;
|
||||
wxBitmapButton* m_bpUpdate;
|
||||
wxBitmapButton* m_bpSettings;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onMouseWheelScale( wxMouseEvent& event ) { event.Skip(); }
|
||||
@@ -91,8 +90,6 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
virtual void onDecrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onOpacitySlider( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelBoardThickness( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void updateBoardThickness( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DISO( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DLeft( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DRight( wxCommandEvent& event ) { event.Skip(); }
|
||||
@@ -101,6 +98,7 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
virtual void View3DTop( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBottom( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DUpdate( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DSettings( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@@ -53,6 +53,13 @@ set( CMAKE_EXPORT_COMPILE_COMMANDS ON )
|
||||
set( KICAD_CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" )
|
||||
set( CMAKE_MODULE_PATH "${KICAD_CMAKE_MODULE_PATH}" )
|
||||
|
||||
# Create a flag to identify the non-Apple unix systems
|
||||
if( UNIX AND NOT APPLE )
|
||||
set( UNIX_NOT_APPLE ON )
|
||||
else()
|
||||
set( UNIX_NOT_APPLE OFF )
|
||||
endif()
|
||||
|
||||
# On Windows, binaries created by link option -g3 are very large (more than 1Gb for pcbnew,
|
||||
# and more than 3Gb for the full kicad suite)
|
||||
# This option create binaries using link option -g1 that create much smaller files, but
|
||||
@@ -93,6 +100,17 @@ option( KICAD_I18N_UNIX_STRICT_PATH
|
||||
"Use standard Unix locale lookup path (default OFF)."
|
||||
OFF )
|
||||
|
||||
# Options to build with flatpak platform defaults (only on Linux)
|
||||
cmake_dependent_option( KICAD_BUILD_FLATPAK
|
||||
"Build KiCad with metadata, launchers, icons, and MIME info following flatpak conventions"
|
||||
OFF "UNIX_NOT_APPLE"
|
||||
OFF )
|
||||
|
||||
cmake_dependent_option( KICAD_BUILD_NIGHTLY_FLATPAK
|
||||
"Build a Nightly flatpak (requires KICAD_BUILD_FLATPAK=ON)"
|
||||
OFF "UNIX_NOT_APPLE"
|
||||
OFF )
|
||||
|
||||
# Not supported by all platforms (for instance mingw)
|
||||
option( KICAD_SANITIZE_ADDRESS
|
||||
"Build KiCad with sanitizer options. WARNING: Not compatible with gold linker"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.6" )
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.8" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -176,6 +176,7 @@ set( COMMON_WIDGET_SRCS
|
||||
widgets/footprint_preview_widget.cpp
|
||||
widgets/footprint_select_widget.cpp
|
||||
widgets/gal_options_panel.cpp
|
||||
widgets/gal_options_panel_base.cpp
|
||||
widgets/grid_bitmap_toggle.cpp
|
||||
widgets/grid_color_swatch_helpers.cpp
|
||||
widgets/grid_combobox.cpp
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include <database/database_connection.h>
|
||||
#include <database/database_cache.h>
|
||||
#include <profile.h>
|
||||
|
||||
|
||||
const char* const traceDatabase = "KICAD_DATABASE";
|
||||
@@ -89,7 +90,7 @@ DATABASE_CONNECTION::DATABASE_CONNECTION( const std::string& aDataSourceName,
|
||||
m_pass = aPassword;
|
||||
m_timeout = aTimeoutSeconds;
|
||||
|
||||
m_cache = std::make_unique<DATABASE_CACHE>( 10, 1 );
|
||||
init();
|
||||
|
||||
if( aConnectNow )
|
||||
Connect();
|
||||
@@ -103,7 +104,7 @@ DATABASE_CONNECTION::DATABASE_CONNECTION( const std::string& aConnectionString,
|
||||
m_connectionString = aConnectionString;
|
||||
m_timeout = aTimeoutSeconds;
|
||||
|
||||
m_cache = std::make_unique<DATABASE_CACHE>( 10, 1 );
|
||||
init();
|
||||
|
||||
if( aConnectNow )
|
||||
Connect();
|
||||
@@ -117,6 +118,12 @@ DATABASE_CONNECTION::~DATABASE_CONNECTION()
|
||||
}
|
||||
|
||||
|
||||
void DATABASE_CONNECTION::init()
|
||||
{
|
||||
m_cache = std::make_unique<DB_CACHE_TYPE>( 10, 1 );
|
||||
}
|
||||
|
||||
|
||||
void DATABASE_CONNECTION::SetCacheParams( int aMaxSize, int aMaxAge )
|
||||
{
|
||||
if( !m_cache )
|
||||
@@ -159,12 +166,10 @@ bool DATABASE_CONNECTION::Connect()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_tables.clear();
|
||||
|
||||
if( IsConnected() )
|
||||
{
|
||||
syncTables();
|
||||
cacheColumns();
|
||||
getQuoteChar();
|
||||
}
|
||||
|
||||
return IsConnected();
|
||||
}
|
||||
@@ -201,65 +206,55 @@ bool DATABASE_CONNECTION::IsConnected() const
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::syncTables()
|
||||
bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
|
||||
const std::set<std::string>& aColumns )
|
||||
{
|
||||
if( !m_conn )
|
||||
return false;
|
||||
|
||||
m_tables.clear();
|
||||
|
||||
try
|
||||
{
|
||||
nanodbc::catalog catalog( *m_conn );
|
||||
nanodbc::catalog::tables tables = catalog.find_tables();
|
||||
nanodbc::catalog::tables tables = catalog.find_tables( fromUTF8( aTable ) );
|
||||
|
||||
while( tables.next() )
|
||||
if( !tables.next() )
|
||||
{
|
||||
std::string key = toUTF8( tables.table_name() );
|
||||
m_tables[key] = toUTF8( tables.table_type() );
|
||||
wxLogTrace( traceDatabase, wxT( "CacheTableInfo: table '%s' not found in catalog" ),
|
||||
aTable );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while syncing tables: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
std::string key = toUTF8( tables.table_name() );
|
||||
m_tables[key] = toUTF8( tables.table_type() );
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::cacheColumns()
|
||||
{
|
||||
if( !m_conn )
|
||||
return false;
|
||||
|
||||
m_columnCache.clear();
|
||||
|
||||
for( const auto& tableIter : m_tables )
|
||||
{
|
||||
try
|
||||
{
|
||||
nanodbc::catalog catalog( *m_conn );
|
||||
nanodbc::catalog::columns columns =
|
||||
catalog.find_columns( NANODBC_TEXT( "" ), fromUTF8( tableIter.first ) );
|
||||
catalog.find_columns( NANODBC_TEXT( "" ), tables.table_name() );
|
||||
|
||||
while( columns.next() )
|
||||
{
|
||||
std::string columnKey = toUTF8( columns.column_name() );
|
||||
m_columnCache[tableIter.first][columnKey] = columns.data_type();
|
||||
|
||||
if( aColumns.count( columnKey ) )
|
||||
m_columnCache[key][columnKey] = columns.data_type();
|
||||
}
|
||||
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while syncing columns for table %s: %s" ),
|
||||
tableIter.first, m_lastError );
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while syncing columns for table '%s': %s" ),
|
||||
key, m_lastError );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while caching table info: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -291,6 +286,35 @@ bool DATABASE_CONNECTION::getQuoteChar()
|
||||
}
|
||||
|
||||
|
||||
std::string DATABASE_CONNECTION::columnsFor( const std::string& aTable )
|
||||
{
|
||||
if( !m_columnCache.count( aTable ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "columnsFor: requested table %s missing from cache!" ),
|
||||
aTable );
|
||||
return "*";
|
||||
}
|
||||
|
||||
if( m_columnCache[aTable].empty() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "columnsFor: requested table %s has no columns mapped!" ),
|
||||
aTable );
|
||||
return "*";
|
||||
}
|
||||
|
||||
std::string ret;
|
||||
|
||||
for( const auto& [ columnName, columnType ] : m_columnCache[aTable] )
|
||||
ret += fmt::format( "{}{}{}, ", m_quoteChar, columnName, m_quoteChar );
|
||||
|
||||
// strip tailing ', '
|
||||
ret.resize( ret.length() - 2 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//next step, make SelectOne take from the SelectAll cache if the SelectOne cache is missing.
|
||||
//To do this, need to build a map of PK->ROW for the cache result.
|
||||
bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
const std::pair<std::string, std::string>& aWhere,
|
||||
DATABASE_CONNECTION::ROW& aResult )
|
||||
@@ -311,6 +335,18 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
}
|
||||
|
||||
const std::string& tableName = tableMapIter->first;
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( m_cache->Get( tableName, cacheEntry ) )
|
||||
{
|
||||
if( cacheEntry.count( aWhere.second ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
|
||||
tableName, aWhere.second );
|
||||
aResult = cacheEntry.at( aWhere.second );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_columnCache.count( tableName ) )
|
||||
{
|
||||
@@ -332,19 +368,15 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
|
||||
std::string cacheKey = fmt::format( "{}{}{}", tableName, columnName, aWhere.second );
|
||||
|
||||
std::string queryStr = fmt::format( "SELECT * FROM {}{}{} WHERE {}{}{} = ?",
|
||||
std::string queryStr = fmt::format( "SELECT {} FROM {}{}{} WHERE {}{}{} = ?",
|
||||
columnsFor( tableName ),
|
||||
m_quoteChar, tableName, m_quoteChar,
|
||||
m_quoteChar, columnName, m_quoteChar );
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
nanodbc::string query = fromUTF8( queryStr );
|
||||
|
||||
if( m_cache->Get( cacheKey, aResult ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
|
||||
toUTF8( query ), aWhere.second );
|
||||
return true;
|
||||
}
|
||||
PROF_TIMER timer;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -384,14 +416,17 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
|
||||
if( !results.first() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: no results returned from query" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: %ld results returned from query" ),
|
||||
results.rows() );
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: %ld results returned from query in %0.1f ms" ),
|
||||
results.rows(), timer.msecs() );
|
||||
|
||||
aResult.clear();
|
||||
|
||||
@@ -411,13 +446,12 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cache->Put( cacheKey, aResult );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>& aResults )
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
|
||||
std::vector<ROW>& aResults )
|
||||
{
|
||||
if( !m_conn )
|
||||
{
|
||||
@@ -434,13 +468,27 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( m_cache->Get( aTable, cacheEntry ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
|
||||
nanodbc::string query = fromUTF8( fmt::format( "SELECT * FROM {}{}{}", m_quoteChar,
|
||||
tableMapIter->first, m_quoteChar ) );
|
||||
nanodbc::string query = fromUTF8( fmt::format( "SELECT {} FROM {}{}{}", columnsFor( aTable ),
|
||||
m_quoteChar, aTable, m_quoteChar ) );
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s`" ), toUTF8( query ) );
|
||||
|
||||
PROF_TIMER timer;
|
||||
|
||||
try
|
||||
{
|
||||
statement.prepare( query );
|
||||
@@ -475,6 +523,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
while( results.next() )
|
||||
@@ -498,5 +548,17 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
|
||||
timer.msecs() );
|
||||
|
||||
for( const ROW& row : aResults )
|
||||
{
|
||||
wxASSERT( row.count( aKey ) );
|
||||
std::string keyStr = std::any_cast<std::string>( row.at( aKey ) );
|
||||
cacheEntry[keyStr] = row;
|
||||
}
|
||||
|
||||
m_cache->Put( aTable, cacheEntry );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
table.symbols_col = entry["symbols"].get<std::string>();
|
||||
table.footprints_col = entry["footprints"].get<std::string>();
|
||||
|
||||
// Sanitize library display names; currently only `/` is removed because we use it
|
||||
// as a separator and allow it in symbol names.
|
||||
table.name.erase( std::remove( table.name.begin(), table.name.end(), '/' ),
|
||||
table.name.end() );
|
||||
|
||||
if( entry.contains( "properties" ) && entry["properties"].is_object() )
|
||||
{
|
||||
const nlohmann::json& pj = entry["properties"];
|
||||
|
||||
@@ -159,6 +159,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
|
||||
m_cbTheme->SetSelection( idx );
|
||||
|
||||
m_optOverrideColors->SetValue( newSettings->GetOverrideSchItemColors() );
|
||||
m_optOverrideColors->Enable( !newSettings->IsReadOnly() );
|
||||
|
||||
*m_currentSettings = *newSettings;
|
||||
updateSwatches();
|
||||
@@ -174,6 +175,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
|
||||
return;
|
||||
|
||||
m_optOverrideColors->SetValue( selected->GetOverrideSchItemColors() );
|
||||
m_optOverrideColors->Enable( !selected->IsReadOnly() );
|
||||
|
||||
*m_currentSettings = *selected;
|
||||
onNewThemeSelected();
|
||||
|
||||
@@ -47,9 +47,9 @@ bool PANEL_DATA_COLLECTION::TransferDataToWindow()
|
||||
{
|
||||
applySettingsToPanel();
|
||||
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::STATE::NOT_CONFIGURED )
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED )
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
@@ -161,16 +161,18 @@ void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map<int, SEVERITY>& aSetti
|
||||
{
|
||||
int errorCode = item.GetErrorCode();
|
||||
|
||||
if(! m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
|
||||
continue;
|
||||
wxRadioButton* button = nullptr;
|
||||
|
||||
switch( aSettings[ errorCode ] )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: m_buttonMap[ errorCode ][0]->SetValue( true ); break;
|
||||
case RPT_SEVERITY_WARNING: m_buttonMap[ errorCode ][1]->SetValue( true ); break;
|
||||
case RPT_SEVERITY_IGNORE: m_buttonMap[ errorCode ][2]->SetValue( true ); break;
|
||||
default: break;
|
||||
case RPT_SEVERITY_ERROR: button = m_buttonMap[ errorCode ][0]; break;
|
||||
case RPT_SEVERITY_WARNING: button = m_buttonMap[ errorCode ][1]; break;
|
||||
case RPT_SEVERITY_IGNORE: button = m_buttonMap[ errorCode ][2]; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if( button ) // this entry must actually exist
|
||||
button->SetValue( true );
|
||||
}
|
||||
|
||||
if( m_pinMapSpecialCase )
|
||||
|
||||
@@ -110,6 +110,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
|
||||
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
|
||||
KIPLATFORM::UI::SetOverlayScrolling( this, false ); // Prevent excessive repaint on GTK
|
||||
KIPLATFORM::UI::ImmControl( this, false ); // Ensure our panel can't suck in IME events
|
||||
|
||||
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), nullptr, this );
|
||||
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), nullptr,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2016 CERN
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
*
|
||||
@@ -247,13 +247,14 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_TEXT* aItem, int aNestLevel ) const
|
||||
// Write font info, only if it is not the default setup
|
||||
bool write_size = aItem->m_TextSize.x != 0.0 || aItem->m_TextSize.y != 0.0;
|
||||
bool write_thickness = aItem->m_LineWidth != 0.0;
|
||||
bool write_face = aItem->m_Font && !aItem->m_Font->GetName().IsEmpty();
|
||||
|
||||
if( write_thickness || write_size || aItem->m_Bold
|
||||
|| aItem->m_Italic || aItem->m_TextColor != COLOR4D::UNSPECIFIED )
|
||||
if( write_thickness || write_size || aItem->m_Bold || aItem->m_Italic
|
||||
|| write_face || aItem->m_TextColor != COLOR4D::UNSPECIFIED )
|
||||
{
|
||||
m_out->Print( 0, " (font" );
|
||||
|
||||
if( aItem->m_Font && !aItem->m_Font->GetName().IsEmpty() )
|
||||
if( write_face )
|
||||
m_out->Print( 0, " (face \"%s\")", aItem->m_Font->NameAsToken() );
|
||||
|
||||
if( write_thickness )
|
||||
|
||||
+16
-4
@@ -114,6 +114,12 @@ wxString EDA_ITEM::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
}
|
||||
|
||||
|
||||
bool isWordChar( const wxUniChar& c )
|
||||
{
|
||||
return wxIsalnum( c ) || c == '_';
|
||||
}
|
||||
|
||||
|
||||
bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchData ) const
|
||||
{
|
||||
wxString text = aText;
|
||||
@@ -129,6 +135,12 @@ bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchDat
|
||||
searchText.MakeUpper();
|
||||
}
|
||||
|
||||
auto isWordChar =
|
||||
[]( const wxUniChar& c )
|
||||
{
|
||||
return wxIsalnum( c ) || c == '_';
|
||||
};
|
||||
|
||||
if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
|
||||
{
|
||||
int ii = 0;
|
||||
@@ -143,8 +155,8 @@ bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchDat
|
||||
ii = next;
|
||||
next += searchText.length();
|
||||
|
||||
bool startOK = ( ii == 0 || !wxIsalnum( text.GetChar( ii - 1 ) ) );
|
||||
bool endOK = ( next == (int) text.length() || !wxIsalnum( text.GetChar( next ) ) );
|
||||
bool startOK = ( ii == 0 || !isWordChar( text.GetChar( ii - 1 ) ) );
|
||||
bool endOK = ( next == (int) text.length() || !isWordChar( text.GetChar( next ) ) );
|
||||
|
||||
if( startOK && endOK )
|
||||
return true;
|
||||
@@ -201,8 +213,8 @@ bool EDA_ITEM::Replace( const EDA_SEARCH_DATA& aSearchData, wxString& aText )
|
||||
|
||||
if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
|
||||
{
|
||||
startOK = ( ii == 0 || !wxIsalnum( text.GetChar( ii - 1 ) ) );
|
||||
endOK = ( next == (int) text.length() || !wxIsalnum( text.GetChar( next ) ) );
|
||||
startOK = ( ii == 0 || !isWordChar( text.GetChar( ii - 1 ) ) );
|
||||
endOK = ( next == (int) text.length() || !isWordChar( text.GetChar( next ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -417,11 +417,11 @@ void EDA_SHAPE::RebuildBezierToSegmentsPointsList( int aMinSegLen )
|
||||
// Ensure last point respects aMinSegLen parameter
|
||||
if( m_bezierPoints.size() > 2 )
|
||||
{
|
||||
int idx = m_bezierPoints.size()-1;
|
||||
int idx = m_bezierPoints.size() - 1;
|
||||
|
||||
if( VECTOR2I( m_bezierPoints[idx] - m_bezierPoints[idx]-1 ).EuclideanNorm() < aMinSegLen )
|
||||
if( VECTOR2I( m_bezierPoints[idx] - m_bezierPoints[idx] - 1 ).EuclideanNorm() < aMinSegLen )
|
||||
{
|
||||
m_bezierPoints[idx]-1 = m_bezierPoints[idx];
|
||||
m_bezierPoints[idx - 1] = m_bezierPoints[idx];
|
||||
m_bezierPoints.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -898,7 +898,7 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
attrs.m_Angle = GetDrawRotation();
|
||||
|
||||
if( font->IsOutline() )
|
||||
cache = GetRenderCache( font, shownText, drawPos );
|
||||
cache = GetRenderCache( font, shownText, VECTOR2I() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -47,7 +47,6 @@ wxString FONTCONFIG::Version()
|
||||
|
||||
FONTCONFIG::FONTCONFIG()
|
||||
{
|
||||
(void) FcInitLoadConfigAndFonts();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2018 CERN
|
||||
*
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
@@ -537,17 +537,27 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
{
|
||||
for( int col = 0; col < w; col++ )
|
||||
{
|
||||
// Build the RGB24 pixel:
|
||||
uint32_t pixel = bm_pix_buffer.GetRed( col, row ) << 16;
|
||||
pixel += bm_pix_buffer.GetGreen( col, row ) << 8;
|
||||
pixel += bm_pix_buffer.GetBlue( col, row );
|
||||
unsigned char r = bm_pix_buffer.GetRed( col, row );
|
||||
unsigned char g = bm_pix_buffer.GetGreen( col, row );
|
||||
unsigned char b = bm_pix_buffer.GetBlue( col, row );
|
||||
unsigned char a = wxALPHA_OPAQUE;
|
||||
|
||||
if( bm_pix_buffer.HasAlpha() )
|
||||
pixel += bm_pix_buffer.GetAlpha( col, row ) << 24;
|
||||
else if( bm_pix_buffer.HasMask() && pixel == mask_color )
|
||||
pixel += ( wxALPHA_TRANSPARENT << 24 );
|
||||
else
|
||||
pixel += ( wxALPHA_OPAQUE << 24 );
|
||||
{
|
||||
a = bm_pix_buffer.GetAlpha( col, row );
|
||||
|
||||
// ARGB32 format needs pre-multiplied alpha
|
||||
r = int32_t( r ) * a / 0xFF;
|
||||
g = int32_t( g ) * a / 0xFF;
|
||||
b = int32_t( b ) * a / 0xFF;
|
||||
}
|
||||
else if( bm_pix_buffer.HasMask() && ( r << 16 | g << 8 | b ) == mask_color )
|
||||
{
|
||||
a = wxALPHA_TRANSPARENT;
|
||||
}
|
||||
|
||||
// Build the ARGB24 pixel:
|
||||
uint32_t pixel = a << 24 | r << 16 | g << 8 | b;
|
||||
|
||||
// Write the pixel to the cairo image buffer:
|
||||
uint32_t* pix_ptr = (uint32_t*) pix_buffer;
|
||||
|
||||
@@ -2257,13 +2257,13 @@ void OPENGL_GAL::drawSegmentChain( const std::function<VECTOR2D( int )>& aPointG
|
||||
auto start = aPointGetter( i - 1 );
|
||||
auto end = aPointGetter( i );
|
||||
|
||||
VECTOR2D startEndVector = start - end;
|
||||
VECTOR2D startEndVector = end - start;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
|
||||
float startx = start.x;
|
||||
float starty = end.y;
|
||||
float starty = start.y;
|
||||
float endx = start.x + lineLength;
|
||||
float endy = end.y + lineLength;
|
||||
float endy = start.y + lineLength;
|
||||
|
||||
// Be careful about floating point rounding. As we draw segments in larger and larger
|
||||
// coordinates, the shader (which uses floats) will lose precision and stop drawing small
|
||||
|
||||
@@ -55,6 +55,11 @@ public:
|
||||
bool m_plotBorderTitleBlocks;
|
||||
|
||||
LSET m_printMaskLayer;
|
||||
|
||||
// How holes in pads/vias are plotted:
|
||||
// 0 = no hole, 1 = small shape, 2 = actual shape
|
||||
// Not used in some plotters (Gerber)
|
||||
int m_drillShapeOption;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
m_outputFile(),
|
||||
m_xOrigin( 0.0 ),
|
||||
m_yOrigin( 0.0 ),
|
||||
m_minDistance( 0.01 ) // 0.01 mm is a good value to connect 2 items of the board outlines
|
||||
m_boardOutlinesChainingEpsilon( 0.01 ) // 0.01 mm is a good value to connect 2 items of the board outlines
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
wxString m_outputFile;
|
||||
double m_xOrigin;
|
||||
double m_yOrigin;
|
||||
double m_minDistance;
|
||||
double m_boardOutlinesChainingEpsilon;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -47,6 +47,11 @@ public:
|
||||
int m_pageSizeMode;
|
||||
|
||||
LSET m_printMaskLayer;
|
||||
|
||||
// How holes in pads/vias are plotted:
|
||||
// 0 = no hole, 1 = small shape, 2 = actual shape
|
||||
// Not used in some plotters (Gerber)
|
||||
int m_drillShapeOption;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <kiplatform/environment.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
#include <kiplatform/policy.h>
|
||||
#include <policy_keys.h>
|
||||
|
||||
struct CURL_PROGRESS
|
||||
{
|
||||
@@ -127,11 +129,29 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
// We need this to use the Windows Certificate store
|
||||
curl_easy_setopt( m_CURL, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA );
|
||||
long sslOpts = CURLSSLOPT_NATIVE_CA;
|
||||
|
||||
POLICY_CURL_SSL_REVOKE policyState = KIPLATFORM::POLICY::GetPolicyEnum<POLICY_CURL_SSL_REVOKE>( POLICY_KEY_REQUESTS_CURL_REVOKE );
|
||||
if( policyState == POLICY_CURL_SSL_REVOKE::BEST_EFFORT )
|
||||
{
|
||||
sslOpts |= CURLSSLOPT_REVOKE_BEST_EFFORT;
|
||||
}
|
||||
else if( policyState == POLICY_CURL_SSL_REVOKE::NONE )
|
||||
{
|
||||
sslOpts |= CURLSSLOPT_NO_REVOKE;
|
||||
}
|
||||
|
||||
curl_easy_setopt( m_CURL, CURLOPT_SSL_OPTIONS, sslOpts );
|
||||
#endif
|
||||
|
||||
if( wxGetEnv( wxT( "KICAD_CURL_VERBOSE" ), nullptr ) )
|
||||
{
|
||||
// note: curl verbose will end up in stderr
|
||||
curl_easy_setopt( m_CURL, CURLOPT_VERBOSE, 1L );
|
||||
}
|
||||
|
||||
wxPlatformInfo platformInfo;
|
||||
wxString application( Pgm().App().GetAppName() );
|
||||
wxString version( GetBuildVersion() );
|
||||
|
||||
@@ -32,6 +32,9 @@ wxString LayerName( int aLayer )
|
||||
switch( aLayer )
|
||||
{
|
||||
// PCB_LAYER_ID
|
||||
case UNDEFINED_LAYER: return _( "undefined" );
|
||||
|
||||
// Copper
|
||||
case F_Cu: return wxT( "F.Cu" );
|
||||
case In1_Cu: return wxT( "In1.Cu" );
|
||||
case In2_Cu: return wxT( "In2.Cu" );
|
||||
|
||||
+123
-31
@@ -127,6 +127,13 @@ LIB_TABLE::~LIB_TABLE()
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE::Clear()
|
||||
{
|
||||
m_rows.clear();
|
||||
m_rowsMap.clear();
|
||||
}
|
||||
|
||||
|
||||
bool LIB_TABLE::IsEmpty( bool aIncludeFallback )
|
||||
{
|
||||
if( !aIncludeFallback || !m_fallBack )
|
||||
@@ -191,31 +198,26 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
|
||||
|
||||
do
|
||||
{
|
||||
cur->ensureIndex();
|
||||
std::shared_lock<std::shared_mutex> lock( cur->m_mutex, std::try_to_lock );
|
||||
|
||||
std::shared_lock<std::shared_mutex> lock( cur->m_nickIndexMutex );
|
||||
if( !cur->m_rowsMap.count( aNickName ) )
|
||||
continue;
|
||||
|
||||
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
|
||||
{
|
||||
if( entry.first == aNickName )
|
||||
{
|
||||
row = &cur->m_rows[entry.second];
|
||||
row = &*cur->m_rowsMap.at( aNickName );
|
||||
|
||||
if( !aCheckIfEnabled || row->GetIsEnabled() )
|
||||
return row;
|
||||
}
|
||||
}
|
||||
if( !aCheckIfEnabled || row->GetIsEnabled() )
|
||||
return row;
|
||||
|
||||
// Repeat, this time looking for names that were "fixed" by legacy versions because
|
||||
// the old eeschema file format didn't support spaces in tokens.
|
||||
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
|
||||
for( const std::pair<const wxString, LIB_TABLE_ROWS_ITER>& entry : cur->m_rowsMap )
|
||||
{
|
||||
wxString legacyLibName = entry.first;
|
||||
legacyLibName.Replace( " ", "_" );
|
||||
|
||||
if( legacyLibName == aNickName )
|
||||
{
|
||||
row = &cur->m_rows[entry.second];
|
||||
row = &*entry.second;
|
||||
|
||||
if( !aCheckIfEnabled || row->GetIsEnabled() )
|
||||
return row;
|
||||
@@ -235,9 +237,7 @@ const LIB_TABLE_ROW* LIB_TABLE::FindRowByURI( const wxString& aURI )
|
||||
|
||||
do
|
||||
{
|
||||
cur->ensureIndex();
|
||||
|
||||
for( unsigned i = 0; i < cur->m_rows.size(); i++ )
|
||||
for( unsigned i = 0; i < cur->m_rows.size(); i++ )
|
||||
{
|
||||
wxString tmp = cur->m_rows[i].GetFullURI( true );
|
||||
|
||||
@@ -276,10 +276,10 @@ std::vector<wxString> LIB_TABLE::GetLogicalLibs()
|
||||
|
||||
do
|
||||
{
|
||||
for( LIB_TABLE_ROWS_CITER it = cur->m_rows.begin(); it!=cur->m_rows.end(); ++it )
|
||||
for( const LIB_TABLE_ROW& row : cur->m_rows )
|
||||
{
|
||||
if( it->GetIsEnabled() )
|
||||
unique.insert( it->GetNickName() );
|
||||
if( row.GetIsEnabled() )
|
||||
unique.insert( row.GetNickName() );
|
||||
}
|
||||
|
||||
} while( ( cur = cur->m_fallBack ) != nullptr );
|
||||
@@ -303,28 +303,120 @@ std::vector<wxString> LIB_TABLE::GetLogicalLibs()
|
||||
|
||||
bool LIB_TABLE::InsertRow( LIB_TABLE_ROW* aRow, bool doReplace )
|
||||
{
|
||||
ensureIndex();
|
||||
std::lock_guard<std::shared_mutex> lock( m_mutex );
|
||||
|
||||
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
|
||||
auto it = m_rowsMap.find( aRow->GetNickName() );
|
||||
|
||||
INDEX_CITER it = m_nickIndex.find( aRow->GetNickName() );
|
||||
if( it != m_rowsMap.end() )
|
||||
{
|
||||
if( !doReplace )
|
||||
return false;
|
||||
|
||||
aRow->SetParent( this );
|
||||
|
||||
if( it == m_nickIndex.end() )
|
||||
m_rows.replace( it->second, aRow );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rows.push_back( aRow );
|
||||
m_nickIndex.insert( INDEX_VALUE( aRow->GetNickName(), m_rows.size() - 1 ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( doReplace )
|
||||
aRow->SetParent( this );
|
||||
reindex();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LIB_TABLE::RemoveRow( const LIB_TABLE_ROW* aRow )
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock( m_mutex );
|
||||
|
||||
bool found = false;
|
||||
auto it = m_rowsMap.find( aRow->GetNickName() );
|
||||
|
||||
if( it != m_rowsMap.end() )
|
||||
{
|
||||
m_rows.replace( it->second, aRow );
|
||||
return true;
|
||||
if( &*it->second == aRow )
|
||||
{
|
||||
found = true;
|
||||
m_rows.erase( it->second );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if( !found )
|
||||
{
|
||||
// Bookkeeping got messed up...
|
||||
for( size_t i = m_rows.size() - 1; i >= 0; --i )
|
||||
{
|
||||
if( &m_rows[i] == aRow )
|
||||
{
|
||||
m_rows.erase( m_rows.begin() + i );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( found )
|
||||
reindex();
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
bool LIB_TABLE::ReplaceRow( size_t aIndex, LIB_TABLE_ROW* aRow )
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock( m_mutex );
|
||||
|
||||
if( aIndex >= m_rows.size() )
|
||||
return false;
|
||||
|
||||
m_rowsMap.erase( m_rows[aIndex].GetNickName() );
|
||||
|
||||
m_rows.replace( aIndex, aRow );
|
||||
reindex();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LIB_TABLE::ChangeRowOrder( size_t aIndex, int aOffset )
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock( m_mutex );
|
||||
|
||||
if( aIndex >= m_rows.size() )
|
||||
return false;
|
||||
|
||||
int newPos = static_cast<int>( aIndex ) + aOffset;
|
||||
|
||||
if( newPos < 0 || newPos > static_cast<int>( m_rows.size() ) - 1 )
|
||||
return false;
|
||||
|
||||
auto element = m_rows.release( m_rows.begin() + aIndex );
|
||||
|
||||
m_rows.insert( m_rows.begin() + newPos, element.release() );
|
||||
reindex();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE::TransferRows( LIB_TABLE_ROWS& aRowsList )
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock( m_mutex );
|
||||
|
||||
m_rows.transfer( m_rows.end(), aRowsList.begin(), aRowsList.end(), aRowsList );
|
||||
|
||||
reindex();
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE::reindex()
|
||||
{
|
||||
m_rowsMap.clear();
|
||||
|
||||
for( LIB_TABLE_ROWS_ITER it = m_rows.begin(); it != m_rows.end(); ++it )
|
||||
{
|
||||
it->SetParent( this );
|
||||
m_rowsMap[it->GetNickName()] = it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+21
-10
@@ -90,7 +90,7 @@ void LIB_TREE_NODE::SortNodes()
|
||||
std::sort( m_Children.begin(), m_Children.end(),
|
||||
[]( std::unique_ptr<LIB_TREE_NODE>& a, std::unique_ptr<LIB_TREE_NODE>& b )
|
||||
{
|
||||
return Compare( *a, *b ) > 0;
|
||||
return Compare( *a, *b );
|
||||
} );
|
||||
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& node: m_Children )
|
||||
@@ -98,27 +98,38 @@ void LIB_TREE_NODE::SortNodes()
|
||||
}
|
||||
|
||||
|
||||
int LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
|
||||
bool LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
|
||||
{
|
||||
if( aNode1.m_Type != aNode2.m_Type )
|
||||
return 0;
|
||||
return aNode1.m_Type < aNode2.m_Type;
|
||||
|
||||
// Recently used sorts at top
|
||||
if( aNode1.m_Name.StartsWith( wxT( "-- " ) ) )
|
||||
return 1;
|
||||
{
|
||||
if( aNode2.m_Name.StartsWith( wxT( "-- " ) ) )
|
||||
{
|
||||
return aNode1.m_IntrinsicRank > aNode2.m_IntrinsicRank;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( aNode2.m_Name.StartsWith( wxT( "-- " ) ) )
|
||||
return 0;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pinned nodes go next
|
||||
if( aNode1.m_Pinned && !aNode2.m_Pinned )
|
||||
return 1;
|
||||
return true;
|
||||
else if( aNode2.m_Pinned && !aNode1.m_Pinned )
|
||||
return -1;
|
||||
return false;
|
||||
|
||||
if( aNode1.m_Parent != aNode2.m_Parent )
|
||||
return 0;
|
||||
if( aNode1.m_IntrinsicRank != aNode2.m_IntrinsicRank )
|
||||
return aNode1.m_IntrinsicRank > aNode2.m_IntrinsicRank;
|
||||
|
||||
return aNode1.m_IntrinsicRank - aNode2.m_IntrinsicRank;
|
||||
return reinterpret_cast<const void*>( &aNode1 ) < reinterpret_cast<const void*>( &aNode2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@ void dumpNode( wxString& buf, TREE_NODE* tok, int depth = 0 )
|
||||
|
||||
case TR_OP_FUNC_CALL:
|
||||
buf += "CALL '";
|
||||
buf += *tok->leaf[0]->value.str;
|
||||
buf += formatNode( tok->leaf[0] );
|
||||
buf += "': ";
|
||||
dumpNode( buf, tok->leaf[1], depth + 1 );
|
||||
break;
|
||||
@@ -786,7 +786,7 @@ static std::vector<TREE_NODE*> squashParamList( TREE_NODE* root )
|
||||
std::reverse( args.begin(), args.end() );
|
||||
|
||||
for( size_t i = 0; i < args.size(); i++ )
|
||||
libeval_dbg( 10, "squash arg%d: %s\n", int( i ), *args[i]->value.str );
|
||||
libeval_dbg( 10, "squash arg%d: %s\n", int( i ), formatNode( args[i] ) );
|
||||
|
||||
return args;
|
||||
}
|
||||
@@ -845,7 +845,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
int pos = node->leaf[0]->srcPos;
|
||||
|
||||
if( node->leaf[0]->value.str )
|
||||
pos -= static_cast<int>( node->leaf[0]->value.str->length() );
|
||||
pos -= static_cast<int>( formatNode( node->leaf[0] ).length() );
|
||||
|
||||
reportError( CST_CODEGEN, _( "Unknown parent of property" ), pos );
|
||||
|
||||
@@ -864,8 +864,8 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: object
|
||||
// leaf[1]: field
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString propName = *node->leaf[1]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
wxString propName = formatNode( node->leaf[1] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, propName );
|
||||
|
||||
if( !vref )
|
||||
@@ -895,7 +895,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: function name
|
||||
// leaf[1]: parameter
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, "" );
|
||||
|
||||
if( !vref )
|
||||
@@ -905,7 +905,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
node->leaf[0]->srcPos - (int) itemName.length() );
|
||||
}
|
||||
|
||||
wxString functionName = *node->leaf[1]->leaf[0]->value.str;
|
||||
wxString functionName = formatNode( node->leaf[1]->leaf[0] );
|
||||
auto func = aCode->CreateFuncCall( functionName );
|
||||
std::vector<TREE_NODE*> params = squashParamList( node->leaf[1]->leaf[1] );
|
||||
|
||||
@@ -924,7 +924,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
for( TREE_NODE* pnode : params )
|
||||
{
|
||||
VALUE* param = aPreflightContext->AllocValue();
|
||||
param->Set( *pnode->value.str );
|
||||
param->Set( formatNode( pnode ) );
|
||||
aPreflightContext->Push( param );
|
||||
}
|
||||
|
||||
@@ -968,8 +968,8 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: object
|
||||
// leaf[1]: malformed syntax
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString propName = *node->leaf[1]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
wxString propName = formatNode( node->leaf[1] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, propName );
|
||||
|
||||
if( !vref )
|
||||
@@ -1006,12 +1006,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
{
|
||||
if( m_unitResolver->GetSupportedUnits().empty() )
|
||||
{
|
||||
msg.Printf( _( "Unexpected units for '%s'" ), *node->value.str );
|
||||
msg.Printf( _( "Unexpected units for '%s'" ), formatNode( node ) );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
}
|
||||
|
||||
int units = son->value.idx;
|
||||
value = m_unitResolver->Convert( *node->value.str, units );
|
||||
value = m_unitResolver->Convert( formatNode( node ), units );
|
||||
son->isVisited = true;
|
||||
}
|
||||
else
|
||||
@@ -1019,12 +1019,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
if( !m_unitResolver->GetSupportedUnitsMessage().empty() )
|
||||
{
|
||||
msg.Printf( _( "Missing units for '%s'| (%s)" ),
|
||||
*node->value.str,
|
||||
formatNode( node ),
|
||||
m_unitResolver->GetSupportedUnitsMessage() );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
}
|
||||
|
||||
value = EDA_UNIT_UTILS::UI::DoubleValueFromString( *node->value.str );
|
||||
value = EDA_UNIT_UTILS::UI::DoubleValueFromString( formatNode( node ) );
|
||||
}
|
||||
|
||||
node->SetUop( TR_UOP_PUSH_VALUE, value );
|
||||
@@ -1034,7 +1034,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
|
||||
case TR_STRING:
|
||||
{
|
||||
wxString str = *node->value.str;
|
||||
wxString str = formatNode( node );
|
||||
bool isWildcard = str.Contains("?") || str.Contains("*");
|
||||
node->SetUop( TR_UOP_PUSH_VALUE, str, isWildcard );
|
||||
node->isTerminal = true;
|
||||
@@ -1043,12 +1043,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
|
||||
case TR_IDENTIFIER:
|
||||
{
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( *node->value.str, "" );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( formatNode( node ), "" );
|
||||
|
||||
if( !vref )
|
||||
{
|
||||
msg.Printf( _( "Unrecognized item '%s'" ), *node->value.str );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos - (int) node->value.str->length() );
|
||||
msg.Printf( _( "Unrecognized item '%s'" ), formatNode( node ) );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos - (int) formatNode( node ).length() );
|
||||
}
|
||||
|
||||
node->SetUop( TR_UOP_PUSH_VAR, std::move( vref ) );
|
||||
|
||||
@@ -434,6 +434,17 @@ wxString PATHS::GetOSXKicadDataDir()
|
||||
|
||||
|
||||
#ifdef __WXWINDOWS__
|
||||
wxString PATHS::GetWindowsFontConfigDir()
|
||||
{
|
||||
wxFileName fn;
|
||||
fn.AssignDir( getWindowsKiCadRoot() );
|
||||
fn.AppendDir( wxS( "etc" ) );
|
||||
fn.AppendDir( wxS( "fonts" ) );
|
||||
|
||||
return fn.GetPathWithSep();
|
||||
}
|
||||
|
||||
|
||||
wxString PATHS::getWindowsKiCadRoot()
|
||||
{
|
||||
wxFileName root( Pgm().GetExecutablePath() + wxT( "/../" ) );
|
||||
|
||||
+17
-10
@@ -238,11 +238,11 @@ const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEdit
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
bool PGM_BASE::IsSentryOptedIn()
|
||||
{
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::STATE::NOT_CONFIGURED )
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED )
|
||||
{
|
||||
return policyState == KIPLATFORM::POLICY::STATE::ENABLED;
|
||||
return policyState == KIPLATFORM::POLICY::PBOOL::ENABLED;
|
||||
}
|
||||
|
||||
return m_sentry_optin_fn.Exists();
|
||||
@@ -349,10 +349,10 @@ void PGM_BASE::sentryPrompt()
|
||||
if( !IsGUI() )
|
||||
return;
|
||||
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
|
||||
if( policyState == KIPLATFORM::POLICY::STATE::NOT_CONFIGURED
|
||||
if( policyState == KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED
|
||||
&& !m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
|
||||
{
|
||||
wxMessageDialog optIn = wxMessageDialog(
|
||||
@@ -479,6 +479,13 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||
SetLanguagePath();
|
||||
SetDefaultLanguage( tmp );
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// We need to set this because the internal fontconfig logic
|
||||
// seems to search relative to the dll rather the other logic it
|
||||
// has to look for the /etc folder above the dll
|
||||
wxSetEnv( "FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
|
||||
#endif
|
||||
|
||||
m_settings_manager = std::make_unique<SETTINGS_MANAGER>( aHeadless );
|
||||
|
||||
// Our unit test mocks break if we continue
|
||||
@@ -655,7 +662,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
|
||||
// don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
|
||||
// false just because it failed to load wxstd catalog
|
||||
if( !m_locale->Init( m_language_id, wxLOCALE_DONT_LOAD_DEFAULT ) )
|
||||
if( !m_locale->Init( m_language_id ) )
|
||||
{
|
||||
wxLogTrace( traceLocale, wxT( "This language is not supported by the system." ) );
|
||||
|
||||
@@ -663,7 +670,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
delete m_locale;
|
||||
|
||||
m_locale = new wxLocale;
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT, wxLOCALE_DONT_LOAD_DEFAULT);
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT );
|
||||
|
||||
aErrMsg = _( "This language is not supported by the operating system." );
|
||||
return false;
|
||||
@@ -714,7 +721,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
delete m_locale;
|
||||
|
||||
m_locale = new wxLocale;
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT, wxLOCALE_DONT_LOAD_DEFAULT);
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT );
|
||||
|
||||
aErrMsg = _( "The KiCad language file for this language is not installed." );
|
||||
return false;
|
||||
|
||||
@@ -1217,7 +1217,7 @@ bool PDF_PLOTTER::EndPlot()
|
||||
|
||||
js += wxT( "var cChoice = app.popUpMenuEx.apply\\( app, aParams \\); " );
|
||||
js += wxT( "if\\( cChoice != null && cChoice.substring\\( 0, 1 \\) == '#' \\)"
|
||||
" this.pageNum = cChoice.slice\\( 1 \\); " );
|
||||
" this.pageNum = parseInt\\( cChoice.slice\\( 1 \\) \\); " );
|
||||
js += wxT( "else if\\( cChoice != null && cChoice.substring\\( 0, 4 \\) == 'http' \\)"
|
||||
" app.launchURL\\( cChoice \\);" );
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL
|
||||
case WSG_POLY_T:
|
||||
{
|
||||
DS_DRAW_ITEM_POLYPOLYGONS* poly = (DS_DRAW_ITEM_POLYPOLYGONS*) item;
|
||||
int penWidth = std::max( poly->GetPenWidth(), defaultPenWidth );
|
||||
int penWidth = poly->GetPenWidth();
|
||||
std::vector<VECTOR2I> points;
|
||||
|
||||
for( int idx = 0; idx < poly->GetPolygons().OutlineCount(); ++idx )
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* 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) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -88,26 +89,106 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
|
||||
}
|
||||
|
||||
|
||||
static const CFB::COMPOUND_FILE_ENTRY*
|
||||
FindStreamSingleLevel( const CFB::CompoundFileReader& aReader,
|
||||
const CFB::COMPOUND_FILE_ENTRY* aEntry, const std::string aName,
|
||||
const bool aIsStream )
|
||||
std::map<wxString, wxString> ALTIUM_COMPOUND_FILE::ListLibFootprints() const
|
||||
{
|
||||
std::map<wxString, wxString> patternMap;
|
||||
|
||||
if( !m_reader )
|
||||
return patternMap;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||
|
||||
if( !root )
|
||||
return patternMap;
|
||||
|
||||
m_reader->EnumFiles( root, 2,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||
|
||||
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||
{
|
||||
ALTIUM_PARSER parametersReader( *this, entry );
|
||||
std::map<wxString, wxString> parameterProperties =
|
||||
parametersReader.ReadProperties();
|
||||
|
||||
wxString key = ALTIUM_PARSER::ReadString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
patternMap.emplace( key, fpName );
|
||||
}
|
||||
} );
|
||||
|
||||
return patternMap;
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_COMPOUND_FILE::FindLibFootprintDirName( const wxString& aFpUnicodeName ) const
|
||||
{
|
||||
if( !m_reader )
|
||||
return wxEmptyString;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||
|
||||
if( !root )
|
||||
return wxEmptyString;
|
||||
|
||||
wxString ret;
|
||||
|
||||
m_reader->EnumFiles( root, 2,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||
|
||||
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||
{
|
||||
ALTIUM_PARSER parametersReader( *this, entry );
|
||||
std::map<wxString, wxString> parameterProperties =
|
||||
parametersReader.ReadProperties();
|
||||
|
||||
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
if( fpName == aFpUnicodeName )
|
||||
{
|
||||
ret = dirName;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY*
|
||||
ALTIUM_COMPOUND_FILE::FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||
const std::string aName, const bool aIsStream ) const
|
||||
{
|
||||
if( !m_reader || !aEntry )
|
||||
return nullptr;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
|
||||
|
||||
aReader.EnumFiles( aEntry, 1,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
if( aReader.IsStream( entry ) == aIsStream )
|
||||
{
|
||||
std::string name = UTF16ToUTF8( entry->name );
|
||||
if( name == aName.c_str() )
|
||||
{
|
||||
ret = entry;
|
||||
}
|
||||
}
|
||||
} );
|
||||
m_reader->EnumFiles( aEntry, 1,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
if( m_reader->IsStream( entry ) == aIsStream )
|
||||
{
|
||||
std::string name = UTF16ToUTF8( entry->name );
|
||||
if( name == aName.c_str() )
|
||||
{
|
||||
ret = entry;
|
||||
}
|
||||
}
|
||||
} );
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -116,9 +197,7 @@ const CFB::COMPOUND_FILE_ENTRY*
|
||||
ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath ) const
|
||||
{
|
||||
if( !m_reader )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry();
|
||||
|
||||
@@ -129,12 +208,11 @@ ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath )
|
||||
|
||||
if( ++it == aStreamPath.cend() )
|
||||
{
|
||||
return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, true );
|
||||
return FindStreamSingleLevel( currentDirEntry, name, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDirEntry =
|
||||
FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, false );
|
||||
currentDirEntry = FindStreamSingleLevel( currentDirEntry, name, false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,9 +310,12 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
||||
else
|
||||
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
||||
|
||||
// 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( " " ) );
|
||||
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( " " ) );
|
||||
}
|
||||
|
||||
if( canonicalKey == wxT( "DESIGNATOR" )
|
||||
|| canonicalKey == wxT( "NAME" )
|
||||
@@ -341,3 +422,28 @@ wxString ALTIUM_PARSER::ReadString( const std::map<wxString, wxString>& aProps,
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -63,8 +63,16 @@ public:
|
||||
|
||||
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
|
||||
|
||||
std::map<wxString, wxString> ListLibFootprints() const;
|
||||
|
||||
wxString FindLibFootprintDirName( const wxString& aFpUnicodeName ) const;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||
const std::string aName,
|
||||
const bool aIsStream ) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<CFB::CompoundFileReader> m_reader;
|
||||
std::vector<char> m_buffer;
|
||||
@@ -107,24 +115,31 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
wxString ReadWxString()
|
||||
wxScopedCharBuffer ReadCharBuffer()
|
||||
{
|
||||
uint8_t len = Read<uint8_t>();
|
||||
if( GetRemainingBytes() >= len )
|
||||
{
|
||||
// TODO: Identify where the actual code page is stored. For now, this default code page
|
||||
// has limited impact, because recent Altium files come with a UTF16 string table
|
||||
wxString val = wxString( m_pos, wxConvISO8859_1, len );
|
||||
char* buf = new char[len];
|
||||
memcpy( buf, m_pos, len );
|
||||
m_pos += len;
|
||||
return val;
|
||||
|
||||
return wxScopedCharBuffer::CreateOwned( buf, len );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_error = true;
|
||||
return wxString( "" );
|
||||
return wxScopedCharBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
wxString ReadWxString()
|
||||
{
|
||||
// TODO: Identify where the actual code page is stored. For now, this default code page
|
||||
// has limited impact, because recent Altium files come with a UTF16 string table
|
||||
return wxString( ReadCharBuffer(), wxConvISO8859_1 );
|
||||
}
|
||||
|
||||
std::map<uint32_t, wxString> ReadWideStringTable()
|
||||
{
|
||||
std::map<uint32_t, wxString> table;
|
||||
@@ -225,6 +240,9 @@ public:
|
||||
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 )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -117,6 +117,12 @@ bool POLYGON_GEOM_MANAGER::IsPolygonInProgress() const
|
||||
}
|
||||
|
||||
|
||||
int POLYGON_GEOM_MANAGER::PolygonPointCount() const
|
||||
{
|
||||
return m_lockedPoints.PointCount();
|
||||
}
|
||||
|
||||
|
||||
bool POLYGON_GEOM_MANAGER::NewPointClosesOutline( const VECTOR2I& aPt ) const
|
||||
{
|
||||
return m_lockedPoints.PointCount() > 0 && m_lockedPoints.CPoint( 0 ) == aPt;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -154,6 +154,22 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView, const VECTOR2D& a
|
||||
textPos.x -= 15.0 / gal->GetWorldScale();
|
||||
}
|
||||
|
||||
// text is left (or right) aligned, so a shadow text need a small offset to be draw
|
||||
// around the basic text
|
||||
int shadowXoffset = aDrawingDropShadows ? textDims.ShadowWidth : 0;
|
||||
|
||||
// Due to the fact a shadow text is drawn left or right aligned,
|
||||
// it needs an offset = shadowWidth/2 to be drawn at the same place as normal text
|
||||
// But for some reason we need to slightly modify this offset
|
||||
// for a better look for KiCad font (better alignment of shadow shape)
|
||||
const float adjust = 1.2f; // Value chosen after tests
|
||||
shadowXoffset *= adjust;
|
||||
|
||||
if( ( textAttrs.m_Halign == GR_TEXT_H_ALIGN_LEFT ) != viewFlipped )
|
||||
textPos.x -= shadowXoffset;
|
||||
else
|
||||
textPos.x += shadowXoffset;
|
||||
|
||||
gal->SetStrokeColor( aView->GetPainter()->GetSettings()->GetLayerColor( LAYER_AUX_ITEMS ) );
|
||||
textAttrs.m_Mirrored = viewFlipped; // Prevent text flipping when view is flipped
|
||||
textAttrs.m_Size = textDims.GlyphSize;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2022 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -167,25 +167,50 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
EDA_ANGLE labelAngle = - EDA_ANGLE( tickLine );
|
||||
VECTOR2I labelOffset = tickLine.Resize( majorTickLen );
|
||||
|
||||
// text is left (or right) aligned, so shadow text need a small offset to be draw
|
||||
// around the basic text
|
||||
int shadowXoffset = 0;
|
||||
|
||||
if( aDrawingDropShadows )
|
||||
{
|
||||
labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
|
||||
shadowXoffset = labelDims.ShadowWidth;
|
||||
// Due to the fact a shadow text is drawn left or right aligned,
|
||||
// it needs an offset = shadowXoffset to be drawn at the same place as normal text
|
||||
// But for some reason we need to slightly modify this offset
|
||||
// for a better look for KiCad font (better alignment of shadow shape)
|
||||
const float adjust = 1.2f; // Value chosen after tests
|
||||
shadowXoffset *= adjust;
|
||||
}
|
||||
|
||||
if( aView->IsMirroredX() )
|
||||
{
|
||||
labelOffset = -labelOffset;
|
||||
shadowXoffset = -shadowXoffset;
|
||||
}
|
||||
|
||||
TEXT_ATTRIBUTES labelAttrs;
|
||||
labelAttrs.m_Size = labelDims.GlyphSize;
|
||||
labelAttrs.m_StrokeWidth = labelDims.StrokeWidth;
|
||||
labelAttrs.m_Mirrored = aView->IsMirroredX(); // Prevent text mirrored when view is mirrored
|
||||
|
||||
if( EDA_ANGLE( aLine ) > ANGLE_0 )
|
||||
{
|
||||
labelAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||
labelAttrs.m_Angle = labelAngle;
|
||||
|
||||
// Adjust the text position of the shadow shape:
|
||||
labelOffset.x -= shadowXoffset * labelAttrs.m_Angle.Cos();;
|
||||
labelOffset.y += shadowXoffset * labelAttrs.m_Angle.Sin();;
|
||||
}
|
||||
else
|
||||
{
|
||||
labelAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
|
||||
labelAttrs.m_Angle = labelAngle + ANGLE_180;
|
||||
|
||||
// Adjust the text position of the shadow shape:
|
||||
labelOffset.x += shadowXoffset * labelAttrs.m_Angle.Cos();;
|
||||
labelOffset.y -= shadowXoffset * labelAttrs.m_Angle.Sin();;
|
||||
}
|
||||
|
||||
BOX2D viewportD = aView->GetViewport();
|
||||
@@ -194,6 +219,8 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
viewport.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
|
||||
// to exclude anything that should be partially drawn
|
||||
|
||||
int isign = aView->IsMirroredX() ? -1 : 1;
|
||||
|
||||
for( int i = 0; i < numTicks; ++i )
|
||||
{
|
||||
const VECTOR2D tickPos = aOrigin + aLine.Resize( tickSpace * i );
|
||||
@@ -216,7 +243,7 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
}
|
||||
|
||||
gal->SetLineWidth( labelAttrs.m_StrokeWidth / 2 );
|
||||
gal->DrawLine( tickPos, tickPos + tickLine.Resize( length ) );
|
||||
gal->DrawLine( tickPos, tickPos + tickLine.Resize( length*isign ) );
|
||||
|
||||
if( drawLabel )
|
||||
{
|
||||
@@ -244,9 +271,10 @@ void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTO
|
||||
TEXT_DIMS textDims = GetConstantGlyphHeight( gal, -1 );
|
||||
const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
|
||||
VECTOR2D backTickVec = aLine;
|
||||
int isign = aView->IsMirroredX() ? -1 : 1;
|
||||
|
||||
RotatePoint( backTickVec, -ANGLE_90 );
|
||||
backTickVec = backTickVec.Resize( aTickLen );
|
||||
backTickVec = backTickVec.Resize( aTickLen * isign );
|
||||
|
||||
BOX2D viewportD = aView->GetViewport();
|
||||
BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
|
||||
|
||||
+37
-12
@@ -159,6 +159,21 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
wxString c = aEvent.GetUnicodeKey();
|
||||
|
||||
if( m_te->AutoCompActive() )
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
m_te->AutoCompCancel();
|
||||
m_suppressAutocomplete = true; // Don't run autocomplete again on the next char...
|
||||
}
|
||||
else
|
||||
{
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( !isalpha( aEvent.GetKeyCode() ) )
|
||||
m_suppressAutocomplete = false;
|
||||
|
||||
@@ -260,18 +275,6 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
if( m_te->GetSelectionEnd() > m_te->GetSelectionStart() )
|
||||
m_te->DeleteBack();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
if( m_te->AutoCompActive() )
|
||||
{
|
||||
m_te->AutoCompCancel();
|
||||
m_suppressAutocomplete = true; // Don't run autocomplete again on the next char...
|
||||
}
|
||||
else
|
||||
{
|
||||
aEvent.Skip();
|
||||
}
|
||||
}
|
||||
else if( isCtrlSlash( aEvent ) )
|
||||
{
|
||||
int startLine = m_te->LineFromPosition( m_te->GetSelectionStart() );
|
||||
@@ -303,6 +306,28 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
m_te->LineEndWrap();
|
||||
}
|
||||
else if( ( aEvent.GetModifiers() & wxMOD_RAW_CONTROL ) && aEvent.GetKeyCode() == 'B' )
|
||||
{
|
||||
if( aEvent.GetModifiers() & wxMOD_ALT )
|
||||
m_te->WordLeft();
|
||||
else
|
||||
m_te->CharLeft();
|
||||
}
|
||||
else if( ( aEvent.GetModifiers() & wxMOD_RAW_CONTROL ) && aEvent.GetKeyCode() == 'F' )
|
||||
{
|
||||
if( aEvent.GetModifiers() & wxMOD_ALT )
|
||||
m_te->WordRight();
|
||||
else
|
||||
m_te->CharRight();
|
||||
}
|
||||
else if( aEvent.GetModifiers() == wxMOD_RAW_CONTROL && aEvent.GetKeyCode() == 'D' )
|
||||
{
|
||||
if( m_te->GetSelectionEnd() == m_te->GetSelectionStart() )
|
||||
m_te->CharRightExtend();
|
||||
|
||||
if( m_te->GetSelectionEnd() > m_te->GetSelectionStart() )
|
||||
m_te->DeleteBack();
|
||||
}
|
||||
#endif
|
||||
else if( aEvent.GetKeyCode() == WXK_SPECIAL20 )
|
||||
{
|
||||
|
||||
@@ -32,6 +32,15 @@
|
||||
using namespace STROKEPARAMS_T;
|
||||
|
||||
|
||||
const std::map<PLOT_DASH_TYPE, struct lineTypeStruct> lineTypeNames = {
|
||||
{ PLOT_DASH_TYPE::SOLID, { _( "Solid" ), BITMAPS::stroke_solid } },
|
||||
{ PLOT_DASH_TYPE::DASH, { _( "Dashed" ), BITMAPS::stroke_dash } },
|
||||
{ PLOT_DASH_TYPE::DOT, { _( "Dotted" ), BITMAPS::stroke_dot } },
|
||||
{ PLOT_DASH_TYPE::DASHDOT, { _( "Dash-Dot" ), BITMAPS::stroke_dashdot } },
|
||||
{ PLOT_DASH_TYPE::DASHDOTDOT, { _( "Dash-Dot-Dot" ), BITMAPS::stroke_dashdotdot } }
|
||||
};
|
||||
|
||||
|
||||
void STROKE_PARAMS::Stroke( const SHAPE* aShape, PLOT_DASH_TYPE aLineStyle, int aWidth,
|
||||
const KIGFX::RENDER_SETTINGS* aRenderSettings,
|
||||
std::function<void( const VECTOR2I& a, const VECTOR2I& b )> aStroker )
|
||||
|
||||
@@ -697,3 +697,8 @@ const TOOL_EVENT EVENTS::InhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common
|
||||
const TOOL_EVENT EVENTS::UninhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common.Interactive.uninhibit" );
|
||||
|
||||
const TOOL_EVENT EVENTS::DisambiguatePoint( TC_MESSAGE, TA_ACTION, "common.Interactive.disambiguate" );
|
||||
|
||||
// System-wide undo/redo Events
|
||||
|
||||
const TOOL_EVENT EVENTS::UndoRedoPreEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL );
|
||||
const TOOL_EVENT EVENTS::UndoRedoPostEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL );
|
||||
|
||||
@@ -305,9 +305,15 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
|
||||
// Currently "Zoom to Objects" is only supported in Eeschema & Pcbnew. Support for other
|
||||
// programs in the suite can be added as needed.
|
||||
|
||||
if( aFitType == ZOOM_FIT_ALL )
|
||||
{
|
||||
if( frame->IsType( FRAME_PCB_EDITOR ) )
|
||||
bBox = m_frame->GetDocumentExtents( false );
|
||||
}
|
||||
|
||||
if( aFitType == ZOOM_FIT_OBJECTS )
|
||||
{
|
||||
if( frame->IsType( FRAME_SCH ) || frame->IsType( FRAME_PCB_EDITOR ) )
|
||||
if( frame->IsType( FRAME_SCH ) )
|
||||
bBox = m_frame->GetDocumentExtents( false );
|
||||
else
|
||||
aFitType = ZOOM_FIT_ALL; // Just do a "Zoom to Fit" for unsupported editors
|
||||
@@ -327,6 +333,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
|
||||
if( !std::isfinite( scale ) )
|
||||
{
|
||||
view->SetCenter( VECTOR2D( 0, 0 ) );
|
||||
canvas->Refresh();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -355,6 +362,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
|
||||
|
||||
view->SetScale( scale / margin_scale_factor );
|
||||
view->SetCenter( bBox.Centre() );
|
||||
canvas->Refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -374,6 +382,7 @@ int COMMON_TOOLS::CenterContents( const TOOL_EVENT& aEvent )
|
||||
VECTOR2D scrollbarSize = VECTOR2D( canvas->GetSize() - canvas->GetClientSize() );
|
||||
VECTOR2D worldScrollbarSize = getView()->ToWorld( scrollbarSize, false );
|
||||
getView()->SetCenter( getView()->GetCenter() + worldScrollbarSize / 2.0 );
|
||||
canvas->Refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -415,6 +424,8 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
|
||||
getView()->SetScale( scale );
|
||||
}
|
||||
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,11 +56,9 @@ VECTOR2I GRID_HELPER::GetGrid() const
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::GetVisibleGrid() const
|
||||
VECTOR2D GRID_HELPER::GetVisibleGrid() const
|
||||
{
|
||||
VECTOR2D size = m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize();
|
||||
|
||||
return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
|
||||
return m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -521,7 +521,7 @@ void VIEW::SetViewport( const BOX2D& aViewport )
|
||||
{
|
||||
VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
|
||||
|
||||
wxCHECK( ssize.x > 0 && ssize.y > 0, /*void*/ );
|
||||
wxCHECK( fabs(ssize.x) > 0 && fabs(ssize.y) > 0, /*void*/ );
|
||||
|
||||
VECTOR2D centre = aViewport.Centre();
|
||||
VECTOR2D vsize = aViewport.GetSize();
|
||||
|
||||
@@ -21,17 +21,6 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/radiobox.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/statline.h>
|
||||
|
||||
#include <ignore.h>
|
||||
#include <widgets/gal_options_panel.h>
|
||||
#include <settings/app_settings.h>
|
||||
#include <eda_draw_frame.h>
|
||||
@@ -45,9 +34,9 @@ static const double gridThicknessMin = 1.0;
|
||||
static const double gridThicknessMax = 10.0;
|
||||
static const double gridThicknessStep = 0.5;
|
||||
|
||||
static const double gridMinSpacingMin = 5;
|
||||
static const double gridMinSpacingMax = 200;
|
||||
static const double gridMinSpacingStep = 5;
|
||||
static const int gridMinSpacingMin = 5;
|
||||
static const int gridMinSpacingMax = 200;
|
||||
static const int gridMinSpacingStep = 5;
|
||||
|
||||
|
||||
///TODO: These are duplicated in gal_display_options - Unify!
|
||||
@@ -68,153 +57,35 @@ static const UTIL::CFG_MAP<KIGFX::GRID_SNAPPING> gridSnapConfigVals =
|
||||
|
||||
|
||||
GAL_OPTIONS_PANEL::GAL_OPTIONS_PANEL( wxWindow* aParent, APP_SETTINGS_BASE* aAppSettings ) :
|
||||
wxPanel( aParent, wxID_ANY ),
|
||||
GAL_OPTIONS_PANEL_BASE( aParent ),
|
||||
m_cfg( aAppSettings )
|
||||
{
|
||||
// the main sizer that holds "columns" of settings
|
||||
m_mainSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
SetSizer( m_mainSizer );
|
||||
|
||||
// second-level sizers that are one "column" of settings each
|
||||
wxBoxSizer* sLeftSizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_mainSizer->Add( sLeftSizer, 1, wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
|
||||
|
||||
/*
|
||||
* Rendering engine
|
||||
*/
|
||||
#ifndef __WXMAC__
|
||||
{
|
||||
wxString engineChoices[] = { _( "Accelerated graphics" ), _( "Fallback graphics" ) };
|
||||
m_renderingEngine = new wxRadioBox( this, wxID_ANY, _( "Rendering Engine" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
sizeof( engineChoices ) / sizeof( wxString ),
|
||||
engineChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_renderingEngine->SetItemToolTip( 0, _( "Hardware-accelerated graphics (recommended)" ) );
|
||||
m_renderingEngine->SetItemToolTip( 1, _( "Software graphics (for computers which do not "
|
||||
"support KiCad's hardware acceleration "
|
||||
"requirements)" ) );
|
||||
|
||||
sLeftSizer->Add( m_renderingEngine, 0, wxTOP | wxBOTTOM | wxRIGHT | wxEXPAND, 5 );
|
||||
}
|
||||
// Rendering engine
|
||||
#ifdef __WXMAC__
|
||||
// On MAC, Cairo render does not work.
|
||||
m_renderingEngine->Hide();
|
||||
#endif
|
||||
m_renderingEngine->SetItemToolTip( 0, _( "Hardware-accelerated graphics (recommended)" ) );
|
||||
m_renderingEngine->SetItemToolTip( 1, _( "Software graphics (for computers which do not "
|
||||
"support KiCad's hardware acceleration "
|
||||
"requirements)" ) );
|
||||
|
||||
/*
|
||||
* Grid settings subpanel
|
||||
*/
|
||||
// Grid settings subpanel
|
||||
int selection = 0; // default selection
|
||||
|
||||
for( double size = gridThicknessMin; size <= gridThicknessMax; size += gridThicknessStep )
|
||||
{
|
||||
wxStaticText* gridLabel = new wxStaticText( this, wxID_ANY, _( "Grid Options" ) );
|
||||
sLeftSizer->Add( gridLabel, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
|
||||
m_gridThicknessList.push_back( size );
|
||||
m_gridLineWidth->Append( wxString::Format( wxT( "%.1f" ), size ) );
|
||||
|
||||
wxStaticLine* staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition,
|
||||
wxDefaultSize, wxLI_HORIZONTAL );
|
||||
sLeftSizer->Add( staticline1, 0, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
wxBoxSizer* sGridSettings = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxString m_gridStyleChoices[] = {
|
||||
_( "Dots" ),
|
||||
_( "Lines" ),
|
||||
_( "Small crosses" )
|
||||
};
|
||||
|
||||
int m_gridStyleNChoices = sizeof( m_gridStyleChoices ) / sizeof( wxString );
|
||||
m_gridStyle = new wxRadioBox( this, wxID_ANY, _( "Grid Style" ), wxDefaultPosition,
|
||||
wxDefaultSize, m_gridStyleNChoices, m_gridStyleChoices, 1,
|
||||
wxRA_SPECIFY_COLS );
|
||||
sGridSettings->Add( m_gridStyle, 0, wxALL | wxEXPAND, 5 );
|
||||
|
||||
wxFlexGridSizer* sGridSettingsGrid;
|
||||
sGridSettingsGrid = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
sGridSettingsGrid->AddGrowableCol( 1 );
|
||||
sGridSettingsGrid->SetFlexibleDirection( wxBOTH );
|
||||
sGridSettingsGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
l_gridLineWidth = new wxStaticText( this, wxID_ANY, _( "Grid thickness:" ) );
|
||||
l_gridLineWidth->Wrap( -1 );
|
||||
sGridSettingsGrid->Add( l_gridLineWidth, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
|
||||
|
||||
m_gridLineWidth = new wxSpinCtrlDouble( this, wxID_ANY );
|
||||
m_gridLineWidth->SetRange( gridThicknessMin, gridThicknessMax );
|
||||
m_gridLineWidth->SetIncrement( gridThicknessStep );
|
||||
m_gridLineWidth->SetDigits( 1 );
|
||||
sGridSettingsGrid->Add( m_gridLineWidth, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP, 5 );
|
||||
|
||||
l_gridLineWidthUnits = new wxStaticText( this, wxID_ANY, _( "px" ) );
|
||||
l_gridLineWidthUnits->Wrap( -1 );
|
||||
sGridSettingsGrid->Add( l_gridLineWidthUnits, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT | wxTOP, 5 );
|
||||
|
||||
l_gridMinSpacing = new wxStaticText( this, wxID_ANY, _( "Min grid spacing:" ) );
|
||||
l_gridMinSpacing->Wrap( -1 );
|
||||
sGridSettingsGrid->Add( l_gridMinSpacing, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
|
||||
|
||||
m_gridMinSpacing = new wxSpinCtrlDouble( this, wxID_ANY);
|
||||
m_gridMinSpacing->SetRange( gridMinSpacingMin, gridMinSpacingMax );
|
||||
m_gridMinSpacing->SetIncrement( gridMinSpacingStep );
|
||||
m_gridMinSpacing->SetDigits( 0 );
|
||||
sGridSettingsGrid->Add( m_gridMinSpacing, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP, 5 );
|
||||
|
||||
l_gridMinSpacingUnits = new wxStaticText( this, wxID_ANY, _( "px" ) );
|
||||
l_gridMinSpacingUnits->Wrap( -1 );
|
||||
sGridSettingsGrid->Add( l_gridMinSpacingUnits, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT | wxTOP, 5 );
|
||||
|
||||
l_gridSnapOptions = new wxStaticText( this, wxID_ANY, _( "Snap to Grid:" ) );
|
||||
l_gridSnapOptions->Wrap( -1 );
|
||||
sGridSettingsGrid->Add( l_gridSnapOptions, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
|
||||
|
||||
wxString gridSnapChoices[] = { _( "Always" ), _( "When grid shown" ), _( "Never" ) };
|
||||
int gridSnapNChoices = sizeof( gridSnapChoices ) / sizeof( wxString );
|
||||
m_gridSnapOptions = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
gridSnapNChoices, gridSnapChoices );
|
||||
m_gridSnapOptions->Select( 0 );
|
||||
sGridSettingsGrid->Add( m_gridSnapOptions, 0,
|
||||
wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP | wxBOTTOM, 5 );
|
||||
|
||||
l_gridSnapSpace = new wxStaticText( this, wxID_ANY, _( "px" ) );
|
||||
l_gridSnapSpace->Wrap( -1 );
|
||||
l_gridSnapSpace->Hide();
|
||||
sGridSettingsGrid->Add( l_gridSnapSpace, 0,
|
||||
wxALIGN_CENTER_VERTICAL | wxALL | wxRESERVE_SPACE_EVEN_IF_HIDDEN,
|
||||
5 );
|
||||
|
||||
|
||||
sGridSettings->Add( sGridSettingsGrid, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
|
||||
|
||||
sLeftSizer->Add( sGridSettings, 0, wxEXPAND|wxLEFT, 5 );
|
||||
if( m_cfg->m_Window.grid.line_width == size )
|
||||
selection = m_gridLineWidth->GetCount() - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cursor settings subpanel
|
||||
*/
|
||||
{
|
||||
sLeftSizer->Add( 0, 15, 0, wxEXPAND, 5 );
|
||||
m_gridLineWidth->SetSelection( selection );
|
||||
|
||||
wxStaticText* gridLabel = new wxStaticText( this, wxID_ANY, _( "Cursor Options" ) );
|
||||
sLeftSizer->Add( gridLabel, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
|
||||
|
||||
wxStaticLine* staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition,
|
||||
wxDefaultSize, wxLI_HORIZONTAL );
|
||||
sLeftSizer->Add( staticline2, 0, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
wxBoxSizer* sCursorSettings = new wxBoxSizer( wxVERTICAL );
|
||||
sLeftSizer->Add( sCursorSettings, 0, wxEXPAND|wxLEFT, 5 );
|
||||
|
||||
wxString m_CursorShapeChoices[] = {
|
||||
_( "Small crosshair" ),
|
||||
_( "Full window crosshair" )
|
||||
};
|
||||
|
||||
int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString );
|
||||
m_cursorShape = new wxRadioBox( this, wxID_ANY, _( "Cursor Shape" ), wxDefaultPosition,
|
||||
wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices,
|
||||
1, wxRA_SPECIFY_COLS );
|
||||
|
||||
m_cursorShape->SetSelection( 0 );
|
||||
m_cursorShape->SetToolTip( _( "Cursor shape for drawing, placement and movement tools" ) );
|
||||
sCursorSettings->Add( m_cursorShape, 0, wxALL | wxEXPAND, 5 );
|
||||
|
||||
m_forceCursorDisplay = new wxCheckBox( this, wxID_ANY, _( "Always show crosshairs" ) );
|
||||
sCursorSettings->Add( m_forceCursorDisplay, 0, wxALL | wxEXPAND, 5 );
|
||||
}
|
||||
m_gridMinSpacing->SetRange( gridMinSpacingMin, gridMinSpacingMax );
|
||||
m_gridMinSpacing->SetIncrement( gridMinSpacingStep );
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +102,7 @@ bool GAL_OPTIONS_PANEL::TransferDataToWindow()
|
||||
|
||||
m_gridSnapOptions->SetSelection( m_cfg->m_Window.grid.snap );
|
||||
m_gridStyle->SetSelection( m_cfg->m_Window.grid.style );
|
||||
m_gridLineWidth->SetValue( m_cfg->m_Window.grid.line_width );
|
||||
|
||||
m_gridMinSpacing->SetValue( m_cfg->m_Window.grid.min_spacing );
|
||||
|
||||
m_cursorShape->SetSelection( m_cfg->m_Window.cursor.fullscreen_cursor );
|
||||
@@ -245,7 +116,10 @@ bool GAL_OPTIONS_PANEL::TransferDataFromWindow()
|
||||
{
|
||||
m_cfg->m_Window.grid.snap = m_gridSnapOptions->GetSelection();
|
||||
m_cfg->m_Window.grid.style = m_gridStyle->GetSelection();
|
||||
m_cfg->m_Window.grid.line_width = m_gridLineWidth->GetValue();
|
||||
|
||||
if( m_gridLineWidth->GetSelection() >= 0 )
|
||||
m_cfg->m_Window.grid.line_width = m_gridThicknessList[ m_gridLineWidth->GetSelection() ];
|
||||
|
||||
m_cfg->m_Window.grid.min_spacing = m_gridMinSpacing->GetValue();
|
||||
|
||||
m_cfg->m_Window.cursor.fullscreen_cursor = m_cursorShape->GetSelection();
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gal_options_panel_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GAL_OPTIONS_PANEL_BASE::GAL_OPTIONS_PANEL_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
|
||||
{
|
||||
wxBoxSizer* mainSizer;
|
||||
mainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* sLeftSizer;
|
||||
sLeftSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxString m_renderingEngineChoices[] = { _("Accelerated graphics"), _("Fallback graphics") };
|
||||
int m_renderingEngineNChoices = sizeof( m_renderingEngineChoices ) / sizeof( wxString );
|
||||
m_renderingEngine = new wxRadioBox( this, wxID_ANY, _("Rendering Engine"), wxDefaultPosition, wxDefaultSize, m_renderingEngineNChoices, m_renderingEngineChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_renderingEngine->SetSelection( 0 );
|
||||
sLeftSizer->Add( m_renderingEngine, 0, wxALL, 5 );
|
||||
|
||||
|
||||
mainSizer->Add( sLeftSizer, 0, wxEXPAND, 5 );
|
||||
|
||||
m_staticText1 = new wxStaticText( this, wxID_ANY, _("Grid Options"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText1->Wrap( -1 );
|
||||
mainSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
mainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
wxString m_gridStyleChoices[] = { _("Dots"), _("Lines"), _("Small crosses") };
|
||||
int m_gridStyleNChoices = sizeof( m_gridStyleChoices ) / sizeof( wxString );
|
||||
m_gridStyle = new wxRadioBox( this, wxID_ANY, _("Grid Style"), wxDefaultPosition, wxDefaultSize, m_gridStyleNChoices, m_gridStyleChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_gridStyle->SetSelection( 0 );
|
||||
mainSizer->Add( m_gridStyle, 0, wxALL, 5 );
|
||||
|
||||
wxFlexGridSizer* fgGridSettingsGrid;
|
||||
fgGridSettingsGrid = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgGridSettingsGrid->AddGrowableCol( 1 );
|
||||
fgGridSettingsGrid->SetFlexibleDirection( wxBOTH );
|
||||
fgGridSettingsGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
l_gridLineWidth = new wxStaticText( this, wxID_ANY, _("Grid thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
l_gridLineWidth->Wrap( -1 );
|
||||
fgGridSettingsGrid->Add( l_gridLineWidth, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
wxArrayString m_gridLineWidthChoices;
|
||||
m_gridLineWidth = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridLineWidthChoices, 0 );
|
||||
m_gridLineWidth->SetSelection( 0 );
|
||||
fgGridSettingsGrid->Add( m_gridLineWidth, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
l_gridLineWidthUnits = new wxStaticText( this, wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
l_gridLineWidthUnits->Wrap( -1 );
|
||||
fgGridSettingsGrid->Add( l_gridLineWidthUnits, 0, wxALL, 5 );
|
||||
|
||||
l_gridMinSpacing = new wxStaticText( this, wxID_ANY, _("Min grid spacing:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
l_gridMinSpacing->Wrap( -1 );
|
||||
fgGridSettingsGrid->Add( l_gridMinSpacing, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_gridMinSpacing = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 5, 200, 10 );
|
||||
fgGridSettingsGrid->Add( m_gridMinSpacing, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
l_gridMinSpacingUnits = new wxStaticText( this, wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
l_gridMinSpacingUnits->Wrap( -1 );
|
||||
fgGridSettingsGrid->Add( l_gridMinSpacingUnits, 0, wxALL, 5 );
|
||||
|
||||
l_gridSnapOptions = new wxStaticText( this, wxID_ANY, _("Snap to grid:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
l_gridSnapOptions->Wrap( -1 );
|
||||
fgGridSettingsGrid->Add( l_gridSnapOptions, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
wxString m_gridSnapOptionsChoices[] = { _("Always"), _("When grid shown"), _("Never") };
|
||||
int m_gridSnapOptionsNChoices = sizeof( m_gridSnapOptionsChoices ) / sizeof( wxString );
|
||||
m_gridSnapOptions = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridSnapOptionsNChoices, m_gridSnapOptionsChoices, 0 );
|
||||
m_gridSnapOptions->SetSelection( 0 );
|
||||
fgGridSettingsGrid->Add( m_gridSnapOptions, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgGridSettingsGrid->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
mainSizer->Add( fgGridSettingsGrid, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
mainSizer->Add( 0, 15, 0, 0, 5 );
|
||||
|
||||
m_stGridLabel = new wxStaticText( this, wxID_ANY, _("Cursor Options"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_stGridLabel->Wrap( -1 );
|
||||
mainSizer->Add( m_stGridLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
mainSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
wxBoxSizer* sCursorSettings;
|
||||
sCursorSettings = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxString m_cursorShapeChoices[] = { _("Small crosshair"), _("Full window crosshair") };
|
||||
int m_cursorShapeNChoices = sizeof( m_cursorShapeChoices ) / sizeof( wxString );
|
||||
m_cursorShape = new wxRadioBox( this, wxID_ANY, _("Cursor Shape"), wxDefaultPosition, wxDefaultSize, m_cursorShapeNChoices, m_cursorShapeChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_cursorShape->SetSelection( 0 );
|
||||
m_cursorShape->SetToolTip( _("Cursor shape for drawing, placement and movement tools") );
|
||||
|
||||
sCursorSettings->Add( m_cursorShape, 0, wxALL, 5 );
|
||||
|
||||
m_forceCursorDisplay = new wxCheckBox( this, wxID_ANY, _("Always show crosshairs"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sCursorSettings->Add( m_forceCursorDisplay, 0, wxALL, 5 );
|
||||
|
||||
|
||||
mainSizer->Add( sCursorSettings, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( mainSizer );
|
||||
this->Layout();
|
||||
}
|
||||
|
||||
GAL_OPTIONS_PANEL_BASE::~GAL_OPTIONS_PANEL_BASE()
|
||||
{
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/radiobox.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/panel.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class GAL_OPTIONS_PANEL_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class GAL_OPTIONS_PANEL_BASE : public wxPanel
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxRadioBox* m_renderingEngine;
|
||||
wxStaticText* m_staticText1;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxRadioBox* m_gridStyle;
|
||||
wxStaticText* l_gridLineWidth;
|
||||
wxChoice* m_gridLineWidth;
|
||||
wxStaticText* l_gridLineWidthUnits;
|
||||
wxStaticText* l_gridMinSpacing;
|
||||
wxSpinCtrl* m_gridMinSpacing;
|
||||
wxStaticText* l_gridMinSpacingUnits;
|
||||
wxStaticText* l_gridSnapOptions;
|
||||
wxChoice* m_gridSnapOptions;
|
||||
wxStaticText* m_stGridLabel;
|
||||
wxStaticLine* m_staticline2;
|
||||
wxRadioBox* m_cursorShape;
|
||||
wxCheckBox* m_forceCursorDisplay;
|
||||
|
||||
public:
|
||||
|
||||
GAL_OPTIONS_PANEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 387,523 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
|
||||
~GAL_OPTIONS_PANEL_BASE();
|
||||
|
||||
};
|
||||
|
||||
@@ -66,8 +66,11 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
|
||||
if( textEntry )
|
||||
{
|
||||
wxClientDC dc( m_valueCtrl );
|
||||
|
||||
// Gives enough room to display a value in inches i )n textEntry
|
||||
// 4 digits + '.' + 10 digits + 2 chars (units) look enough.
|
||||
wxSize minSize = m_valueCtrl->GetMinSize();
|
||||
int minWidth = dc.GetTextExtent( wxT( "XXX.XXXXXXX" ) ).GetWidth();
|
||||
int minWidth = dc.GetTextExtent( wxT( "XXXX.XXXXXXXXXXUU" ) ).GetWidth();
|
||||
|
||||
if( minSize.GetWidth() < minWidth )
|
||||
m_valueCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
||||
|
||||
@@ -276,12 +276,19 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
|
||||
case ANNOTATE_CURRENT_SHEET:
|
||||
currentSheet.GetMultiUnitSymbols( lockedSymbols );
|
||||
|
||||
if( aRecursive )
|
||||
subSheets.GetMultiUnitSymbols( lockedSymbols );
|
||||
|
||||
break;
|
||||
|
||||
case ANNOTATE_SELECTION:
|
||||
for( SCH_SYMBOL* symbol : selectedSymbols )
|
||||
currentSheet.AppendMultiUnitSymbol( lockedSymbols, symbol );
|
||||
|
||||
if( aRecursive )
|
||||
selectedSheets.GetMultiUnitSymbols( lockedSymbols );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+218
-168
@@ -55,7 +55,7 @@
|
||||
* Flag to enable connectivity profiling
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
|
||||
static const wxChar DanglingProfileMask[] = wxT( "CONN_PROFILE" );
|
||||
|
||||
/*
|
||||
* Flag to enable connectivity tracing
|
||||
@@ -64,11 +64,79 @@ static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
|
||||
static const wxChar ConnTrace[] = wxT( "CONN" );
|
||||
|
||||
|
||||
void CONNECTION_SUBGRAPH::RemoveItem( SCH_ITEM* aItem )
|
||||
{
|
||||
m_items.erase( aItem );
|
||||
m_drivers.erase( aItem );
|
||||
|
||||
if( aItem == m_driver )
|
||||
{
|
||||
m_driver = nullptr;
|
||||
m_driver_connection = nullptr;
|
||||
}
|
||||
|
||||
if( aItem->Type() == SCH_SHEET_PIN_T )
|
||||
m_hier_pins.erase( static_cast<SCH_SHEET_PIN*>( aItem ) );
|
||||
|
||||
if( aItem->Type() == SCH_HIER_LABEL_T )
|
||||
m_hier_ports.erase( static_cast<SCH_HIERLABEL*>( aItem ) );
|
||||
}
|
||||
|
||||
|
||||
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
{
|
||||
PRIORITY highest_priority = PRIORITY::INVALID;
|
||||
std::vector<SCH_ITEM*> candidates;
|
||||
std::vector<SCH_ITEM*> strong_drivers;
|
||||
auto candidate_cmp = [&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
|
||||
{
|
||||
// meet irreflexive requirements of std::sort
|
||||
if( a == b )
|
||||
return false;
|
||||
|
||||
SCH_CONNECTION* ac = a->Connection( &m_sheet );
|
||||
SCH_CONNECTION* bc = b->Connection( &m_sheet );
|
||||
|
||||
// Ensure we don't pick the subset over the superset
|
||||
if( ac->IsBus() && bc->IsBus() )
|
||||
return bc->IsSubsetOf( ac );
|
||||
|
||||
// Ensure we don't pick a hidden power pin on a regular symbol over
|
||||
// one on a power symbol
|
||||
if( a->Type() == SCH_PIN_T && b->Type() == SCH_PIN_T )
|
||||
{
|
||||
SCH_PIN* pa = static_cast<SCH_PIN*>( a );
|
||||
SCH_PIN* pb = static_cast<SCH_PIN*>( b );
|
||||
|
||||
bool aPower = pa->GetLibPin()->GetParent()->IsPower();
|
||||
bool bPower = pb->GetLibPin()->GetParent()->IsPower();
|
||||
|
||||
if( aPower && !bPower )
|
||||
return true;
|
||||
else if( bPower && !aPower )
|
||||
return false;
|
||||
}
|
||||
|
||||
const wxString& a_name = GetNameForDriver( a );
|
||||
const wxString& b_name = GetNameForDriver( b );
|
||||
bool a_lowQualityName = a_name.Contains( "-Pad" );
|
||||
bool b_lowQualityName = b_name.Contains( "-Pad" );
|
||||
|
||||
if( a_lowQualityName && !b_lowQualityName )
|
||||
return false;
|
||||
else if( b_lowQualityName && !a_lowQualityName )
|
||||
return true;
|
||||
else
|
||||
return a_name < b_name;
|
||||
};
|
||||
|
||||
auto strong_cmp = [this]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
|
||||
{
|
||||
const wxString& a_name = GetNameForDriver( a );
|
||||
const wxString& b_name = GetNameForDriver( b );
|
||||
return a_name < b_name;
|
||||
};
|
||||
|
||||
PRIORITY highest_priority = PRIORITY::INVALID;
|
||||
std::set<SCH_ITEM*, decltype( candidate_cmp )> candidates( candidate_cmp );
|
||||
std::set<SCH_ITEM*, decltype( strong_cmp )> strong_drivers( strong_cmp );
|
||||
|
||||
m_driver = nullptr;
|
||||
|
||||
@@ -88,17 +156,17 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
continue;
|
||||
|
||||
if( item_priority >= PRIORITY::HIER_LABEL )
|
||||
strong_drivers.push_back( item );
|
||||
strong_drivers.insert( item );
|
||||
|
||||
if( item_priority > highest_priority )
|
||||
{
|
||||
candidates.clear();
|
||||
candidates.push_back( item );
|
||||
candidates.insert( item );
|
||||
highest_priority = item_priority;
|
||||
}
|
||||
else if( !candidates.empty() && ( item_priority == highest_priority ) )
|
||||
{
|
||||
candidates.push_back( item );
|
||||
candidates.insert( item );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,56 +196,10 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For all other driver types, sort by quality of name
|
||||
std::sort( candidates.begin(), candidates.end(),
|
||||
[&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
|
||||
{
|
||||
// meet irreflexive requirements of std::sort
|
||||
if( a == b )
|
||||
return false;
|
||||
|
||||
SCH_CONNECTION* ac = a->Connection( &m_sheet );
|
||||
SCH_CONNECTION* bc = b->Connection( &m_sheet );
|
||||
|
||||
// Ensure we don't pick the subset over the superset
|
||||
if( ac->IsBus() && bc->IsBus() )
|
||||
return bc->IsSubsetOf( ac );
|
||||
|
||||
// Ensure we don't pick a hidden power pin on a regular symbol over
|
||||
// one on a power symbol
|
||||
if( a->Type() == SCH_PIN_T && b->Type() == SCH_PIN_T )
|
||||
{
|
||||
SCH_PIN* pa = static_cast<SCH_PIN*>( a );
|
||||
SCH_PIN* pb = static_cast<SCH_PIN*>( b );
|
||||
|
||||
bool aPower = pa->GetLibPin()->GetParent()->IsPower();
|
||||
bool bPower = pb->GetLibPin()->GetParent()->IsPower();
|
||||
|
||||
if( aPower && !bPower )
|
||||
return true;
|
||||
else if( bPower && !aPower )
|
||||
return false;
|
||||
}
|
||||
|
||||
const wxString& a_name = GetNameForDriver( a );
|
||||
const wxString& b_name = GetNameForDriver( b );
|
||||
bool a_lowQualityName = a_name.Contains( "-Pad" );
|
||||
bool b_lowQualityName = b_name.Contains( "-Pad" );
|
||||
|
||||
if( a_lowQualityName && !b_lowQualityName )
|
||||
return false;
|
||||
else if( b_lowQualityName && !a_lowQualityName )
|
||||
return true;
|
||||
else
|
||||
return a_name < b_name;
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_driver )
|
||||
m_driver = candidates[0];
|
||||
m_driver = *candidates.begin();
|
||||
}
|
||||
|
||||
if( strong_drivers.size() > 1 )
|
||||
@@ -185,7 +207,10 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
|
||||
// Drop weak drivers
|
||||
if( m_strong_driver )
|
||||
m_drivers = strong_drivers;
|
||||
{
|
||||
m_drivers.clear();
|
||||
m_drivers.insert( strong_drivers.begin(), strong_drivers.end() );
|
||||
}
|
||||
|
||||
// Cache driver connection
|
||||
if( m_driver )
|
||||
@@ -200,30 +225,6 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
m_driver_connection = nullptr;
|
||||
}
|
||||
|
||||
if( aCheckMultipleDrivers && m_multiple_drivers )
|
||||
{
|
||||
// First check if all the candidates are actually the same
|
||||
bool same = true;
|
||||
const wxString& first = GetNameForDriver( candidates[0] );
|
||||
SCH_ITEM* second_item = nullptr;
|
||||
|
||||
for( unsigned i = 1; i < candidates.size(); i++ )
|
||||
{
|
||||
if( GetNameForDriver( candidates[i] ) != first )
|
||||
{
|
||||
second_item = candidates[i];
|
||||
same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !same )
|
||||
{
|
||||
m_first_driver = m_driver;
|
||||
m_second_driver = second_item;
|
||||
}
|
||||
}
|
||||
|
||||
return ( m_driver != nullptr );
|
||||
}
|
||||
|
||||
@@ -233,7 +234,10 @@ void CONNECTION_SUBGRAPH::getAllConnectedItems( std::set<std::pair<SCH_SHEET_PAT
|
||||
CONNECTION_SUBGRAPH* sg = this;
|
||||
|
||||
while( sg->m_absorbed_by )
|
||||
{
|
||||
wxASSERT( sg->m_graph == sg->m_absorbed_by->m_graph );
|
||||
sg = sg->m_absorbed_by;
|
||||
}
|
||||
|
||||
aSubgraphs.insert( sg );
|
||||
aSubgraphs.insert( sg->m_absorbed_subgraphs.begin(), sg->m_absorbed_subgraphs.end() );
|
||||
@@ -356,9 +360,12 @@ wxString CONNECTION_SUBGRAPH::driverName( SCH_ITEM* aItem ) const
|
||||
|
||||
const wxString& CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
|
||||
{
|
||||
auto [it, success] = m_driver_name_cache.try_emplace( aItem, driverName( aItem ) );
|
||||
auto it = m_driver_name_cache.find( aItem );
|
||||
|
||||
return it->second;
|
||||
if( it != m_driver_name_cache.end() )
|
||||
return it->second;
|
||||
|
||||
return m_driver_name_cache.emplace( aItem, driverName( aItem ) ).first->second;
|
||||
}
|
||||
|
||||
|
||||
@@ -426,15 +433,15 @@ void CONNECTION_SUBGRAPH::Absorb( CONNECTION_SUBGRAPH* aOther )
|
||||
|
||||
void CONNECTION_SUBGRAPH::AddItem( SCH_ITEM* aItem )
|
||||
{
|
||||
m_items.push_back( aItem );
|
||||
m_items.insert( aItem );
|
||||
|
||||
if( aItem->Connection( &m_sheet )->IsDriver() )
|
||||
m_drivers.push_back( aItem );
|
||||
m_drivers.insert( aItem );
|
||||
|
||||
if( aItem->Type() == SCH_SHEET_PIN_T )
|
||||
m_hier_pins.push_back( static_cast<SCH_SHEET_PIN*>( aItem ) );
|
||||
m_hier_pins.insert( static_cast<SCH_SHEET_PIN*>( aItem ) );
|
||||
else if( aItem->Type() == SCH_HIER_LABEL_T )
|
||||
m_hier_ports.push_back( static_cast<SCH_HIERLABEL*>( aItem ) );
|
||||
m_hier_ports.insert( static_cast<SCH_HIERLABEL*>( aItem ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -506,7 +513,12 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
std::back_inserter( m_subgraphs ) );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aGraph.m_subgraphs )
|
||||
{
|
||||
if( sg->m_driver_connection )
|
||||
sg->m_driver_connection->SetGraph( this );
|
||||
|
||||
sg->m_graph = this;
|
||||
}
|
||||
|
||||
std::copy( aGraph.m_driver_subgraphs.begin(),
|
||||
aGraph.m_driver_subgraphs.end(),
|
||||
@@ -543,6 +555,7 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
m_last_bus_code = std::max( m_last_bus_code, aGraph.m_last_bus_code );
|
||||
m_last_net_code = std::max( m_last_net_code, aGraph.m_last_net_code );
|
||||
m_last_subgraph_code = std::max( m_last_subgraph_code, aGraph.m_last_subgraph_code );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -585,6 +598,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
PROF_TIMER update_items( "updateItemConnectivity" );
|
||||
|
||||
m_sheetList = aSheetList;
|
||||
std::set<SCH_ITEM*> dirty_items;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : aSheetList )
|
||||
{
|
||||
@@ -596,8 +610,12 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||
{
|
||||
if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
|
||||
{
|
||||
wxLogTrace( ConnTrace, wxT( "Adding item %s to connectivity graph update" ),
|
||||
item->GetTypeDesc() );
|
||||
items.push_back( item );
|
||||
|
||||
dirty_items.insert( item );
|
||||
}
|
||||
// Ensure the hierarchy info stored in SCREENS is built and up to date
|
||||
// (multi-unit symbols)
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
@@ -629,19 +647,22 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
}
|
||||
}
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
for( SCH_ITEM* item : dirty_items )
|
||||
item->SetConnectivityDirty( false );
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
update_items.Show();
|
||||
|
||||
PROF_TIMER build_graph( "buildConnectionGraph" );
|
||||
|
||||
buildConnectionGraph( aChangedItemHandler );
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
build_graph.Show();
|
||||
|
||||
recalc_time.Stop();
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
recalc_time.Show();
|
||||
}
|
||||
|
||||
@@ -655,11 +676,17 @@ std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffected
|
||||
{
|
||||
// Find the primary subgraph on this sheet
|
||||
while( aSubgraph->m_absorbed_by )
|
||||
{
|
||||
wxASSERT( aSubgraph->m_graph == aSubgraph->m_absorbed_by->m_graph );
|
||||
aSubgraph = aSubgraph->m_absorbed_by;
|
||||
}
|
||||
|
||||
// Find the top most connected subgraph on all sheets
|
||||
while( aSubgraph->m_hier_parent )
|
||||
{
|
||||
wxASSERT( aSubgraph->m_graph == aSubgraph->m_hier_parent->m_graph );
|
||||
aSubgraph = aSubgraph->m_hier_parent;
|
||||
}
|
||||
|
||||
// Recurse through all subsheets to collect connected items
|
||||
aSubgraph->getAllConnectedItems( retvals, subgraphs );
|
||||
@@ -751,23 +778,23 @@ void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgrap
|
||||
{
|
||||
auto it = std::lower_bound( m_driver_subgraphs.begin(), m_driver_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_driver_subgraphs.end() )
|
||||
m_driver_subgraphs.erase( it );
|
||||
while( it != m_driver_subgraphs.end() && *it == sg )
|
||||
it = m_driver_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::lower_bound( m_subgraphs.begin(), m_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_subgraphs.end() )
|
||||
m_subgraphs.erase( it );
|
||||
while( it != m_subgraphs.end() && *it == sg )
|
||||
it = m_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
for( auto el : m_sheet_to_subgraphs_map )
|
||||
{
|
||||
auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
|
||||
|
||||
if( it != el.second.end() )
|
||||
el.second.erase( it );
|
||||
while( it != el.second.end() && *it == sg )
|
||||
it = el.second.erase( it );
|
||||
}
|
||||
|
||||
auto remove_sg = [sg]( auto it ) -> bool
|
||||
@@ -844,6 +871,7 @@ void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgrap
|
||||
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
|
||||
{
|
||||
sg->m_code = -1;
|
||||
sg->m_graph = nullptr;
|
||||
delete sg;
|
||||
}
|
||||
}
|
||||
@@ -931,8 +959,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
for( const VECTOR2I& point : points )
|
||||
connection_map[ point ].push_back( item );
|
||||
}
|
||||
|
||||
item->SetConnectivityDirty( false );
|
||||
}
|
||||
|
||||
for( const auto& it : connection_map )
|
||||
@@ -1637,10 +1663,16 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
// by the chosen driver of the subgraph, so we need to create a dummy connection
|
||||
add_connections_to_check( subgraph );
|
||||
|
||||
std::set<SCH_CONNECTION*> checked_connections;
|
||||
|
||||
for( unsigned i = 0; i < connections_to_check.size(); i++ )
|
||||
{
|
||||
auto member = connections_to_check[i];
|
||||
|
||||
// Don't check the same connection twice
|
||||
if( !checked_connections.insert( member.get() ).second )
|
||||
continue;
|
||||
|
||||
if( member->IsBus() )
|
||||
{
|
||||
connections_to_check.insert( connections_to_check.end(),
|
||||
@@ -1776,7 +1808,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
PROF_TIMER sub_graph( "buildItemSubGraphs" );
|
||||
buildItemSubGraphs();
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
sub_graph.Show();
|
||||
|
||||
|
||||
@@ -1796,7 +1828,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
|
||||
processSubGraphs();
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
proc_sub_graph.Show();
|
||||
|
||||
// Absorbed subgraphs should no longer be considered
|
||||
@@ -2178,49 +2210,98 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
SCH_CONNECTION* conn = aSubgraph->m_driver_connection;
|
||||
std::vector<CONNECTION_SUBGRAPH*> search_list;
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> visited;
|
||||
std::vector<SCH_CONNECTION*> stale_bus_members;
|
||||
std::unordered_set<SCH_CONNECTION*> stale_bus_members;
|
||||
|
||||
auto visit =
|
||||
[&]( CONNECTION_SUBGRAPH* aParent )
|
||||
auto visit =[&]( CONNECTION_SUBGRAPH* aParent )
|
||||
{
|
||||
for( SCH_SHEET_PIN* pin : aParent->m_hier_pins )
|
||||
{
|
||||
SCH_SHEET_PATH path = aParent->m_sheet;
|
||||
path.push_back( pin->GetParent() );
|
||||
|
||||
auto it = m_sheet_to_subgraphs_map.find( path );
|
||||
|
||||
if( it == m_sheet_to_subgraphs_map.end() )
|
||||
continue;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : it->second )
|
||||
{
|
||||
for( SCH_SHEET_PIN* pin : aParent->m_hier_pins )
|
||||
if( !candidate->m_strong_driver
|
||||
|| candidate->m_hier_ports.empty()
|
||||
|| visited.count( candidate ) )
|
||||
{
|
||||
SCH_SHEET_PATH path = aParent->m_sheet;
|
||||
path.push_back( pin->GetParent() );
|
||||
continue;
|
||||
}
|
||||
|
||||
auto it = m_sheet_to_subgraphs_map.find( path );
|
||||
|
||||
if( it == m_sheet_to_subgraphs_map.end() )
|
||||
continue;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : it->second )
|
||||
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
|
||||
{
|
||||
if( candidate->GetNameForDriver( label ) == aParent->GetNameForDriver( pin ) )
|
||||
{
|
||||
if( !candidate->m_strong_driver
|
||||
|| candidate->m_hier_ports.empty()
|
||||
|| visited.count( candidate ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
wxLogTrace( ConnTrace, wxS( "%lu: found child %lu (%s)" ), aParent->m_code,
|
||||
candidate->m_code, candidate->m_driver_connection->Name() );
|
||||
|
||||
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
|
||||
{
|
||||
if( candidate->GetNameForDriver( label ) == aParent->GetNameForDriver( pin ) )
|
||||
{
|
||||
wxLogTrace( ConnTrace, wxS( "%lu: found child %lu (%s)" ), aParent->m_code,
|
||||
candidate->m_code, candidate->m_driver_connection->Name() );
|
||||
candidate->m_hier_parent = aParent;
|
||||
aParent->m_hier_children.insert( candidate );
|
||||
|
||||
candidate->m_hier_parent = aParent;
|
||||
aParent->m_hier_children.insert( candidate );
|
||||
wxASSERT( candidate->m_graph == aParent->m_graph );
|
||||
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph ) {
|
||||
for( SCH_HIERLABEL* label : aParent->m_hier_ports )
|
||||
{
|
||||
SCH_SHEET_PATH path = aParent->m_sheet;
|
||||
path.pop_back();
|
||||
|
||||
auto it = m_sheet_to_subgraphs_map.find( path );
|
||||
|
||||
if( it == m_sheet_to_subgraphs_map.end() )
|
||||
continue;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : it->second )
|
||||
{
|
||||
if( candidate->m_hier_pins.empty()
|
||||
|| visited.count( candidate )
|
||||
|| candidate->m_driver_connection->Type() != aParent->m_driver_connection->Type() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
|
||||
|
||||
for( SCH_SHEET_PIN* pin : candidate->m_hier_pins )
|
||||
{
|
||||
// If the last sheet UUIDs won't match, no need to check the full path
|
||||
if( pin->GetParent()->m_Uuid != last_parent_uuid )
|
||||
continue;
|
||||
|
||||
SCH_SHEET_PATH pin_path = path;
|
||||
pin_path.push_back( pin->GetParent() );
|
||||
|
||||
if( pin_path != aParent->m_sheet )
|
||||
continue;
|
||||
|
||||
if( aParent->GetNameForDriver( label ) == candidate->GetNameForDriver( pin ) )
|
||||
{
|
||||
wxLogTrace( ConnTrace, wxS( "%lu: found additional parent %lu (%s)" ),
|
||||
aParent->m_code, candidate->m_code,
|
||||
candidate->m_driver_connection->Name() );
|
||||
|
||||
aParent->m_hier_children.insert( candidate );
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph )
|
||||
{
|
||||
for( const auto& kv : aParentGraph->m_bus_neighbors )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* neighbor : kv.second )
|
||||
@@ -2290,7 +2371,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
>= CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN )
|
||||
{
|
||||
member->Clone( *neighbor_conn );
|
||||
stale_bus_members.push_back( member );
|
||||
stale_bus_members.insert( member );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2338,9 +2419,8 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
{
|
||||
auto child = search_list[i];
|
||||
|
||||
visited.insert( child );
|
||||
|
||||
visit( child );
|
||||
if( visited.insert( child ).second )
|
||||
visit( child );
|
||||
|
||||
child->m_dirty = false;
|
||||
}
|
||||
@@ -2417,7 +2497,9 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
// member to have the correct connection info
|
||||
if( conn->IsBus() && !stale_bus_members.empty() )
|
||||
{
|
||||
for( SCH_CONNECTION* stale_member : stale_bus_members )
|
||||
std::unordered_set<SCH_CONNECTION*> cached_members = stale_bus_members;
|
||||
|
||||
for( SCH_CONNECTION* stale_member : cached_members )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* subgraph : visited )
|
||||
{
|
||||
@@ -2791,38 +2873,7 @@ int CONNECTION_GRAPH::RunERC()
|
||||
bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubgraph )
|
||||
{
|
||||
wxCHECK( aSubgraph, false );
|
||||
/*
|
||||
* This was changed late in 6.0 to fix https://gitlab.com/kicad/code/kicad/-/issues/9367
|
||||
* so I'm going to leave the original code in for just a little while. If anyone comes
|
||||
* across this in 7.0 development (or later), feel free to delete.
|
||||
*/
|
||||
#if 0
|
||||
if( aSubgraph->m_second_driver )
|
||||
{
|
||||
SCH_ITEM* primary = aSubgraph->m_first_driver;
|
||||
SCH_ITEM* secondary = aSubgraph->m_second_driver;
|
||||
|
||||
wxPoint pos = primary->Type() == SCH_PIN_T ?
|
||||
static_cast<SCH_PIN*>( primary )->GetTransformedPosition() :
|
||||
primary->GetPosition();
|
||||
|
||||
const wxString& primaryName = aSubgraph->GetNameForDriver( primary );
|
||||
const wxString& secondaryName = aSubgraph->GetNameForDriver( secondary );
|
||||
|
||||
wxString msg = wxString::Format( _( "Both %s and %s are attached to the same "
|
||||
"items; %s will be used in the netlist" ),
|
||||
primaryName, secondaryName, primaryName );
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DRIVER_CONFLICT );
|
||||
ercItem->SetItems( primary, secondary );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
|
||||
aSubgraph->m_sheet.LastScreen()->Append( marker );
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if( aSubgraph->m_multiple_drivers )
|
||||
{
|
||||
for( SCH_ITEM* driver : aSubgraph->m_drivers )
|
||||
@@ -2857,7 +2908,6 @@ bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubg
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,9 +86,7 @@ public:
|
||||
m_bus_entry( nullptr ),
|
||||
m_driver( nullptr ),
|
||||
m_driver_connection( nullptr ),
|
||||
m_hier_parent( nullptr ),
|
||||
m_first_driver( nullptr ),
|
||||
m_second_driver( nullptr )
|
||||
m_hier_parent( nullptr )
|
||||
{}
|
||||
|
||||
~CONNECTION_SUBGRAPH() = default;
|
||||
@@ -130,7 +128,7 @@ public:
|
||||
void UpdateItemConnections();
|
||||
|
||||
/// Provides a read-only reference to the items in the subgraph
|
||||
const std::vector<SCH_ITEM*>& GetItems() const
|
||||
const std::set<SCH_ITEM*>& GetItems() const
|
||||
{
|
||||
return m_items;
|
||||
}
|
||||
@@ -162,6 +160,8 @@ public:
|
||||
return PRIORITY::NONE;
|
||||
}
|
||||
|
||||
void RemoveItem( SCH_ITEM* aItem );
|
||||
|
||||
private:
|
||||
wxString driverName( SCH_ITEM* aItem ) const;
|
||||
|
||||
@@ -206,9 +206,9 @@ public:
|
||||
/// Bus entry in graph, if any
|
||||
SCH_ITEM* m_bus_entry;
|
||||
|
||||
std::vector<SCH_ITEM*> m_items;
|
||||
std::set<SCH_ITEM*> m_items;
|
||||
|
||||
std::vector<SCH_ITEM*> m_drivers;
|
||||
std::set<SCH_ITEM*> m_drivers;
|
||||
|
||||
SCH_ITEM* m_driver;
|
||||
|
||||
@@ -237,10 +237,10 @@ public:
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_parents;
|
||||
|
||||
// Cache for lookup of any hierarchical (sheet) pins on this subgraph (for referring down)
|
||||
std::vector<SCH_SHEET_PIN*> m_hier_pins;
|
||||
std::set<SCH_SHEET_PIN*> m_hier_pins;
|
||||
|
||||
// Cache for lookup of any hierarchical ports on this subgraph (for referring up)
|
||||
std::vector<SCH_HIERLABEL*> m_hier_ports;
|
||||
std::set<SCH_HIERLABEL*> m_hier_ports;
|
||||
|
||||
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
|
||||
CONNECTION_SUBGRAPH* m_hier_parent;
|
||||
@@ -251,14 +251,6 @@ public:
|
||||
/// A cache of escaped netnames from schematic items
|
||||
mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
|
||||
|
||||
/**
|
||||
* Stores the primary driver for the multiple drivers ERC check. This is the chosen driver
|
||||
* before subgraphs are absorbed (so m_driver may be different)
|
||||
*/
|
||||
SCH_ITEM* m_first_driver;
|
||||
|
||||
/// Used for multiple drivers ERC message; stores the second possible driver (or nullptr)
|
||||
SCH_ITEM* m_second_driver;
|
||||
};
|
||||
|
||||
struct NET_NAME_CODE_CACHE_KEY
|
||||
|
||||
@@ -226,8 +226,6 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
|
||||
|
||||
m_Parent->GetCanvas()->Refresh();
|
||||
|
||||
m_btnClear->Enable();
|
||||
|
||||
m_sdbSizer1Cancel->SetDefault();
|
||||
|
||||
// Don't close dialog if there are things the user needs to address
|
||||
@@ -248,7 +246,6 @@ void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event )
|
||||
bool appendUndo = false;
|
||||
|
||||
m_Parent->DeleteAnnotation( GetScope(), GetRecursive(), &appendUndo );
|
||||
m_btnClear->Enable( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <schematic.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <widgets/wx_html_report_panel.h>
|
||||
#include <widgets/std_bitmap_button.h>
|
||||
|
||||
bool g_selectRefDes = false;
|
||||
bool g_selectValue = false;
|
||||
@@ -242,7 +243,7 @@ void DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_specifiedId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true );
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
@@ -258,7 +259,7 @@ void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_newId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true );
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
@@ -702,6 +703,10 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
|
||||
symbol->SetSchSymbolLibraryName( wxEmptyString );
|
||||
screen->Append( symbol );
|
||||
|
||||
if( resetPositions )
|
||||
symbol->AutoAutoplaceFields( screen );
|
||||
|
||||
frame->GetCanvas()->GetView()->Update( symbol );
|
||||
|
||||
msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId );
|
||||
@@ -720,8 +725,18 @@ wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const
|
||||
wxString references;
|
||||
LIB_ID oldId = aSymbol.GetLibId();
|
||||
|
||||
SCH_EDIT_FRAME* parent = dynamic_cast< SCH_EDIT_FRAME* >( GetParent() );
|
||||
|
||||
wxCHECK( parent, msg );
|
||||
|
||||
SCH_SHEET_LIST sheets = parent->Schematic().GetSheets();
|
||||
|
||||
for( const SCH_SYMBOL_INSTANCE& instance : aSymbol.GetInstanceReferences() )
|
||||
{
|
||||
// Only include the symbol instances for the current project.
|
||||
if( !sheets.HasPath( instance.m_Path ) )
|
||||
continue;
|
||||
|
||||
if( references.IsEmpty() )
|
||||
references = instance.m_Reference;
|
||||
else
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "widgets/std_bitmap_button.h"
|
||||
#include "widgets/wx_html_report_panel.h"
|
||||
|
||||
#include "dialog_change_symbols_base.h"
|
||||
@@ -20,7 +21,7 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
|
||||
wxBoxSizer* matchSizerMargins;
|
||||
matchSizerMargins = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_matchSizer = new wxGridBagSizer( 3, 5 );
|
||||
m_matchSizer = new wxGridBagSizer( 3, 0 );
|
||||
m_matchSizer->SetFlexibleDirection( wxBOTH );
|
||||
m_matchSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
@@ -48,7 +49,7 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
|
||||
m_specifiedId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
m_matchSizer->Add( m_specifiedId, wxGBPosition( 5, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_matchIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
m_matchIdBrowserButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
m_matchSizer->Add( m_matchIdBrowserButton, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
|
||||
|
||||
|
||||
@@ -77,9 +78,9 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
|
||||
bSizer1 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_newId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
bSizer1->Add( m_newId, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
bSizer1->Add( m_newId, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_newIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
m_newIdBrowserButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bSizer1->Add( m_newIdBrowserButton, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<property name="flexible_direction">wxBOTH</property>
|
||||
<property name="growablecols">1</property>
|
||||
<property name="growablerows">1</property>
|
||||
<property name="hgap">5</property>
|
||||
<property name="hgap">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_matchSizer</property>
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
@@ -694,7 +694,7 @@
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
@@ -860,7 +860,7 @@
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -984,7 +984,7 @@
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class STD_BITMAP_BUTTON;
|
||||
class WX_HTML_REPORT_PANEL;
|
||||
|
||||
#include "dialog_shim.h"
|
||||
@@ -56,11 +57,11 @@ class DIALOG_CHANGE_SYMBOLS_BASE : public DIALOG_SHIM
|
||||
wxTextCtrl* m_specifiedValue;
|
||||
wxRadioButton* m_matchById;
|
||||
wxTextCtrl* m_specifiedId;
|
||||
wxBitmapButton* m_matchIdBrowserButton;
|
||||
STD_BITMAP_BUTTON* m_matchIdBrowserButton;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxBoxSizer* m_newIdSizer;
|
||||
wxTextCtrl* m_newId;
|
||||
wxBitmapButton* m_newIdBrowserButton;
|
||||
STD_BITMAP_BUTTON* m_newIdBrowserButton;
|
||||
wxStaticBoxSizer* m_updateFieldsSizer;
|
||||
wxCheckListBox* m_fieldsBox;
|
||||
wxButton* m_selAllBtn;
|
||||
|
||||
@@ -482,7 +482,11 @@ void DIALOG_CHOOSE_SYMBOL::PopulateFootprintSelector( LIB_ID const& aLibId )
|
||||
LIB_FIELD* fp_field = symbol->GetFieldById( FOOTPRINT_FIELD );
|
||||
wxString fp_name = fp_field ? fp_field->GetFullText() : wxString( "" );
|
||||
|
||||
symbol->GetPins( temp_pins );
|
||||
// All units, but only a single De Morgan variant.
|
||||
if( symbol->HasConversion() )
|
||||
symbol->GetPins( temp_pins, 0, 1 );
|
||||
else
|
||||
symbol->GetPins( temp_pins );
|
||||
|
||||
m_fp_sel_ctrl->FilterByPinCount( temp_pins.size() );
|
||||
m_fp_sel_ctrl->FilterByFootprintFilters( symbol->GetFPFilters(), true );
|
||||
|
||||
@@ -438,7 +438,9 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
|
||||
{
|
||||
wxMilliSleep( 500 );
|
||||
m_runningResultsBook->ChangeSelection( 1 );
|
||||
#ifndef __WXGTK__
|
||||
KIPLATFORM::UI::ForceFocus( m_markerDataView );
|
||||
#endif
|
||||
}
|
||||
|
||||
m_ercRun = true;
|
||||
|
||||
@@ -73,8 +73,16 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
|
||||
{
|
||||
wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
|
||||
} );
|
||||
|
||||
m_StyledTextCtrl->SetEOLMode( wxSTC_EOL_LF ); // Normalize EOL across platforms
|
||||
|
||||
#ifdef _WIN32
|
||||
// Without this setting, on Windows, some esoteric unicode chars create display issue
|
||||
// in a wxStyledTextCtrl.
|
||||
// for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
|
||||
m_StyledTextCtrl->SetTechnology(wxSTC_TECHNOLOGY_DIRECTWRITE);
|
||||
#endif
|
||||
|
||||
m_textColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
|
||||
m_textColorSwatch->SetSwatchBackground( schematicBackground );
|
||||
|
||||
@@ -419,6 +427,7 @@ void DIALOG_FIELD_PROPERTIES::updateText( EDA_TEXT* aText )
|
||||
if( aText->GetTextWidth() != m_size )
|
||||
aText->SetTextSize( wxSize( m_size, m_size ) );
|
||||
|
||||
aText->SetFont( m_font );
|
||||
aText->SetVisible( m_isVisible );
|
||||
aText->SetTextAngle( m_isVertical ? ANGLE_VERTICAL : ANGLE_HORIZONTAL );
|
||||
aText->SetItalic( m_isItalic );
|
||||
@@ -439,6 +448,8 @@ DIALOG_LIB_FIELD_PROPERTIES::DIALOG_LIB_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen
|
||||
if( m_fieldId == VALUE_FIELD )
|
||||
m_text = UnescapeString( aField->GetText() );
|
||||
|
||||
m_font = aField->GetFont();
|
||||
|
||||
m_nameVisible->Show();
|
||||
m_cbAllowAutoPlace->Show();
|
||||
|
||||
@@ -656,7 +667,7 @@ void DIALOG_SCH_FIELD_PROPERTIES::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH
|
||||
}
|
||||
else if( parent && parent->Type() == SCH_GLOBAL_LABEL_T )
|
||||
{
|
||||
if( fieldType == 0 )
|
||||
if( aField->GetCanonicalName() == wxT( "Intersheetrefs" ) )
|
||||
{
|
||||
if( m_visible->GetValue() != parent->Schematic()->Settings().m_IntersheetRefsShow )
|
||||
{
|
||||
@@ -688,8 +699,6 @@ void DIALOG_SCH_FIELD_PROPERTIES::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH
|
||||
updateText( aField );
|
||||
aField->SetPosition( m_position );
|
||||
|
||||
aField->SetFont( m_font );
|
||||
|
||||
aField->SetNameShown( m_isNameVisible );
|
||||
aField->SetCanAutoplace( m_allowAutoplace );
|
||||
|
||||
|
||||
@@ -422,7 +422,9 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
}
|
||||
}
|
||||
|
||||
if( aItem->Type() == SCH_SYMBOL_T )
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case SCH_SYMBOL_T:
|
||||
{
|
||||
SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
|
||||
|
||||
@@ -446,8 +448,11 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if( aItem->Type() == SCH_SHEET_T )
|
||||
|
||||
case SCH_SHEET_T:
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
|
||||
|
||||
@@ -488,19 +493,30 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
|
||||
processItem( aSheetPath, pin );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if( m_wires->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_WIRE_T,
|
||||
SCH_LABEL_LOCATE_WIRE_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( m_buses->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_BUS_T,
|
||||
SCH_LABEL_LOCATE_BUS_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( aItem->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
|
||||
{
|
||||
|
||||
case SCH_LINE_T:
|
||||
if( m_schTextAndGraphics->GetValue() && aItem->GetLayer() == LAYER_NOTES )
|
||||
processItem( aSheetPath, aItem );
|
||||
else if( m_wires->GetValue() && aItem->GetLayer() == LAYER_WIRE )
|
||||
processItem( aSheetPath, aItem );
|
||||
else if( m_buses->GetValue() && aItem->GetLayer() == LAYER_BUS )
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
break;
|
||||
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
case SCH_DIRECTIVE_LABEL_T:
|
||||
if( m_wires->GetValue() && aItem->IsType( { SCH_LABEL_LOCATE_WIRE_T } ) )
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
if( m_buses->GetValue() && aItem->IsType( { SCH_LABEL_LOCATE_BUS_T } ) )
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
if( m_globalLabels->GetValue() && aItem->Type() == SCH_GLOBAL_LABEL_T )
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
@@ -520,8 +536,10 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( aItem->Type() == SCH_JUNCTION_T )
|
||||
|
||||
break;
|
||||
|
||||
case SCH_JUNCTION_T:
|
||||
{
|
||||
SCH_JUNCTION* junction = static_cast<SCH_JUNCTION*>( aItem );
|
||||
|
||||
@@ -538,12 +556,20 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if( m_schTextAndGraphics->GetValue() && aItem->IsType( { SCH_TEXT_T, SCH_TEXTBOX_T,
|
||||
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
|
||||
SCH_SHAPE_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
case SCH_TEXT_T:
|
||||
case SCH_TEXTBOX_T:
|
||||
case SCH_SHAPE_T:
|
||||
if( m_schTextAndGraphics->GetValue() )
|
||||
processItem( aSheetPath, aItem );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,6 +604,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow()
|
||||
|
||||
// Reset the view to where we left the user
|
||||
m_parent->SetCurrentSheet( currentSheet );
|
||||
m_parent->Refresh();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataToWindow()
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::shared_ptr<BUS_ALIAS>> sheetAliases = screen->GetBusAliases();
|
||||
auto& sheetAliases = screen->GetBusAliases();
|
||||
busAliases.insert( busAliases.end(), sheetAliases.begin(), sheetAliases.end() );
|
||||
}
|
||||
|
||||
|
||||
@@ -592,6 +592,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
m_grid->CommitPendingChanges( true /* quiet mode */ );
|
||||
m_grid->ClearSelection();
|
||||
|
||||
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
||||
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
||||
|
||||
@@ -64,6 +64,13 @@ DIALOG_LIB_TEXTBOX_PROPERTIES::DIALOG_LIB_TEXTBOX_PROPERTIES( SYMBOL_EDIT_FRAME*
|
||||
|
||||
m_textCtrl->SetEOLMode( wxSTC_EOL_LF );
|
||||
|
||||
#ifdef _WIN32
|
||||
// Without this setting, on Windows, some esoteric unicode chars create display issue
|
||||
// in a wxStyledTextCtrl.
|
||||
// for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
|
||||
m_textCtrl->SetTechnology(wxSTC_TECHNOLOGY_DIRECTWRITE);
|
||||
#endif
|
||||
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS( m_textCtrl, wxT( "{}" ), false,
|
||||
[this]()
|
||||
{
|
||||
|
||||
@@ -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-2022 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -324,7 +324,69 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataFromWindow()
|
||||
|
||||
int sheet_count = m_parent->Schematic().Root().CountSheets();
|
||||
|
||||
wxPrintDialogData printDialogData( m_parent->GetPageSetupData().GetPrintData() );
|
||||
wxPrintData data = m_parent->GetPageSetupData().GetPrintData();
|
||||
|
||||
#if defined( __WXGTK__ ) && !wxCHECK_VERSION( 3, 2, 3 )
|
||||
// In GTK, the default bottom margin is bigger by 0.31 inches for
|
||||
// Letter, Legal, A4 paper sizes (see gtk_paper_size_get_default_bottom_margin).
|
||||
//
|
||||
// wxWidgets doesn't handle this properly when paper is in
|
||||
// landscape orientation.
|
||||
//
|
||||
// Using custom page size avoids the problematic
|
||||
// gtk_page_setup_set_paper_size_and_default_margins call in wxWidgets.
|
||||
|
||||
wxPaperSize paperId = data.GetPaperId();
|
||||
const wxChar* paperType = nullptr;
|
||||
|
||||
// clang-format off
|
||||
std::set<wxPaperSize> letterSizes = {
|
||||
// na_letter
|
||||
wxPAPER_LETTER,
|
||||
wxPAPER_LETTERSMALL,
|
||||
wxPAPER_NOTE,
|
||||
wxPAPER_LETTER_TRANSVERSE,
|
||||
wxPAPER_LETTER_ROTATED
|
||||
};
|
||||
|
||||
std::set<wxPaperSize> legalSizes = {
|
||||
// na_legal
|
||||
wxPAPER_LEGAL
|
||||
};
|
||||
|
||||
std::set<wxPaperSize> a4Sizes = {
|
||||
// iso_a4
|
||||
wxPAPER_A4,
|
||||
wxPAPER_A4SMALL,
|
||||
wxPAPER_A4_TRANSVERSE,
|
||||
wxPAPER_A4_ROTATED
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
if( letterSizes.count( paperId ) )
|
||||
paperType = PAGE_INFO::USLetter;
|
||||
else if( legalSizes.count( paperId ) )
|
||||
paperType = PAGE_INFO::USLegal;
|
||||
else if( a4Sizes.count( paperId ) )
|
||||
paperType = PAGE_INFO::A4;
|
||||
|
||||
if( paperType )
|
||||
{
|
||||
PAGE_INFO pageInfo( paperType, data.GetOrientation() == wxPORTRAIT );
|
||||
|
||||
if( pageInfo.IsPortrait() )
|
||||
data.SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ),
|
||||
EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ) ) );
|
||||
else
|
||||
data.SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ),
|
||||
EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ) ) );
|
||||
|
||||
data.SetOrientation( pageInfo.GetWxOrientation() );
|
||||
data.SetPaperId( wxPAPER_NONE );
|
||||
}
|
||||
#endif
|
||||
|
||||
wxPrintDialogData printDialogData( data );
|
||||
printDialogData.SetMaxPage( sheet_count );
|
||||
|
||||
if( sheet_count > 1 )
|
||||
@@ -468,11 +530,15 @@ void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
// All the coordinates will be rotated 90 deg when printing,
|
||||
// so the X,Y offset vector must be rotated -90 deg before printing
|
||||
std::swap( xoffset, yoffset );
|
||||
std::swap( fitRect.width, fitRect.height );
|
||||
yoffset = -yoffset;
|
||||
}
|
||||
|
||||
matrix.Translate( xoffset, yoffset );
|
||||
dc->SetTransformMatrix( matrix );
|
||||
|
||||
fitRect.x -= xoffset;
|
||||
fitRect.y -= yoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -67,6 +67,8 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
|
||||
}, _( "Field Name Templates" ) );
|
||||
|
||||
m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Electrical Rules" ) );
|
||||
|
||||
m_severitiesPage = m_treebook->GetPageCount();
|
||||
m_treebook->AddLazySubPage(
|
||||
[this]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
|
||||
@@ -208,9 +208,8 @@ bool DIALOG_SHEET_PROPERTIES::Validate()
|
||||
for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields->size(); ++i )
|
||||
{
|
||||
SCH_FIELD& field = m_fields->at( i );
|
||||
wxString fieldName = field.GetName( false );
|
||||
|
||||
if( fieldName.IsEmpty() )
|
||||
if( field.GetName( false ).empty() && !field.GetText().empty() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Fields must have a name." ) );
|
||||
|
||||
@@ -367,7 +366,7 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
|
||||
SCH_FIELD& field = m_fields->at( ii );
|
||||
const wxString& fieldName = field.GetCanonicalName();
|
||||
|
||||
if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
|
||||
if( field.IsEmpty() )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
else if( fieldName.IsEmpty() )
|
||||
field.SetName( _( "untitled" ) );
|
||||
|
||||
@@ -185,6 +185,9 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
{
|
||||
m_libraryPathText->ChangeValue( libraryFilename );
|
||||
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, &reporter );
|
||||
|
||||
// load library will mangle the set reporter
|
||||
m_libraryModelsMgr.SetReporter( &reporter );
|
||||
m_libraryModelsMgr.CreateModel( nullptr, m_sortedPartPins, m_fields );
|
||||
|
||||
m_modelNameChoice->Append( _( "<unknown>" ) );
|
||||
|
||||
@@ -102,6 +102,13 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_ITE
|
||||
|
||||
m_textCtrl->SetEOLMode( wxSTC_EOL_LF );
|
||||
|
||||
#ifdef _WIN32
|
||||
// Without this setting, on Windows, some esoteric unicode chars create display issue
|
||||
// in a wxStyledTextCtrl.
|
||||
// for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
|
||||
m_textCtrl->SetTechnology(wxSTC_TECHNOLOGY_DIRECTWRITE);
|
||||
#endif
|
||||
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS( m_textCtrl, wxT( "{}" ), false,
|
||||
[this]()
|
||||
{
|
||||
|
||||
@@ -53,9 +53,6 @@ PANEL_SETUP_BUSES::PANEL_SETUP_BUSES( wxWindow* aWindow, SCH_EDIT_FRAME* aFrame
|
||||
m_membersGrid->PushEventHandler( new GRID_TRICKS( m_membersGrid,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxIdleEvent dummy;
|
||||
reloadMembersGridOnIdle( dummy );
|
||||
|
||||
OnAddMember( aEvent );
|
||||
} ) );
|
||||
|
||||
@@ -306,6 +303,12 @@ void PANEL_SETUP_BUSES::OnMemberGridCellChanging( wxGridEvent& event )
|
||||
// Parse a space-separated list and add each one
|
||||
wxStringTokenizer tok( name, " " );
|
||||
|
||||
if( tok.CountTokens() > 1 )
|
||||
{
|
||||
m_membersGridDirty = true;
|
||||
Bind( wxEVT_IDLE, &PANEL_SETUP_BUSES::reloadMembersGridOnIdle, this );
|
||||
}
|
||||
|
||||
while( tok.HasMoreTokens() )
|
||||
alias->Members().push_back( tok.GetNextToken() );
|
||||
}
|
||||
@@ -314,9 +317,6 @@ void PANEL_SETUP_BUSES::OnMemberGridCellChanging( wxGridEvent& event )
|
||||
alias->Members().push_back( m_membersGrid->GetCellValue( ii, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_membersGridDirty = true;
|
||||
Bind( wxEVT_IDLE, &PANEL_SETUP_BUSES::reloadMembersGridOnIdle, this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ protected:
|
||||
tbl->AppendRows( tmp_tbl.GetCount() - tbl->GetNumberRows() );
|
||||
|
||||
for( unsigned i = 0; i < tmp_tbl.GetCount(); ++i )
|
||||
tbl->m_rows.replace( i, tmp_tbl.At( i ).clone() );
|
||||
tbl->ReplaceRow( i, tmp_tbl.At( i ).clone() );
|
||||
}
|
||||
|
||||
m_grid->AutoSizeColumns( false );
|
||||
@@ -447,9 +447,6 @@ bool PANEL_SYM_LIB_TABLE::verifyTables()
|
||||
{
|
||||
SYMBOL_LIB_TABLE_ROW& row = dynamic_cast<SYMBOL_LIB_TABLE_ROW&>( table->At( r ) );
|
||||
|
||||
if( !row.GetParent() )
|
||||
row.SetParent( table );
|
||||
|
||||
if( !row.GetIsEnabled() )
|
||||
continue;
|
||||
|
||||
@@ -667,11 +664,7 @@ void PANEL_SYM_LIB_TABLE::moveUpHandler( wxCommandEvent& event )
|
||||
// @todo: add multiple selection moves.
|
||||
if( curRow >= 1 )
|
||||
{
|
||||
boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
|
||||
tbl->m_rows.release( tbl->m_rows.begin() + curRow );
|
||||
|
||||
--curRow;
|
||||
tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
|
||||
tbl->ChangeRowOrder( curRow--, -1 );
|
||||
|
||||
if( tbl->GetView() )
|
||||
{
|
||||
@@ -697,11 +690,7 @@ void PANEL_SYM_LIB_TABLE::moveDownHandler( wxCommandEvent& event )
|
||||
// @todo: add multiple selection moves.
|
||||
if( unsigned( curRow + 1 ) < tbl->m_rows.size() )
|
||||
{
|
||||
boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
|
||||
tbl->m_rows.release( tbl->m_rows.begin() + curRow );
|
||||
|
||||
++curRow;
|
||||
tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
|
||||
tbl->ChangeRowOrder( curRow++, 1 );
|
||||
|
||||
if( tbl->GetView() )
|
||||
{
|
||||
@@ -889,9 +878,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
||||
m_parent->m_GlobalTableChanged = true;
|
||||
|
||||
m_globalTable->Clear();
|
||||
m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(),
|
||||
global_model()->m_rows.end(), global_model()->m_rows );
|
||||
m_globalTable->reindex();
|
||||
m_globalTable->TransferRows( global_model()->m_rows );
|
||||
}
|
||||
|
||||
if( project_model() && *project_model() != *m_projectTable )
|
||||
@@ -899,9 +886,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
||||
m_parent->m_ProjectTableChanged = true;
|
||||
|
||||
m_projectTable->Clear();
|
||||
m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(),
|
||||
project_model()->m_rows.end(), project_model()->m_rows );
|
||||
m_projectTable->reindex();
|
||||
m_projectTable->TransferRows( project_model()->m_rows );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -332,12 +332,15 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
|
||||
// This is process-level-initialization, not project-level-initialization of the DSO.
|
||||
// Do nothing in here pertinent to a project!
|
||||
InitSettings( new EESCHEMA_SETTINGS );
|
||||
aProgram->GetSettingsManager().RegisterSettings( KifaceSettings(), false );
|
||||
|
||||
// Register the symbol editor settings as well because they share a KiFACE and need to be
|
||||
// loaded prior to use to avoid threading deadlocks
|
||||
aProgram->GetSettingsManager().RegisterSettings( new SYMBOL_EDITOR_SETTINGS, false );
|
||||
aProgram->GetSettingsManager().Load();
|
||||
aProgram->GetSettingsManager().RegisterSettings( new SYMBOL_EDITOR_SETTINGS );
|
||||
|
||||
// We intentionally register KifaceSettings after SYMBOL_EDITOR_SETTINGS
|
||||
// In legacy configs, many settings were in a single editor config nd the migration routine
|
||||
// for the main editor file will try and call into the now separate settings stores
|
||||
// to move the settings into them
|
||||
aProgram->GetSettingsManager().RegisterSettings( KifaceSettings() );
|
||||
|
||||
start_common( aCtlBits );
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ void SCH_EDIT_FRAME::saveProjectSettings()
|
||||
|
||||
void SCH_EDIT_FRAME::SaveProjectLocalSettings()
|
||||
{
|
||||
// No schematic local settings yet
|
||||
RecordERCExclusions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -307,7 +307,7 @@ int ERC_TESTER::TestConflictingBusAliases()
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
{
|
||||
const std::set< std::shared_ptr<BUS_ALIAS> > screen_aliases = screen->GetBusAliases();
|
||||
const auto& screen_aliases = screen->GetBusAliases();
|
||||
|
||||
for( const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
|
||||
{
|
||||
|
||||
@@ -638,6 +638,9 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
Schematic().SetProject( nullptr );
|
||||
GetSettingsManager()->UnloadProject( &Prj(), false );
|
||||
|
||||
// Clear view before destroying schematic as repaints depend on schematic being valid
|
||||
SetScreen( nullptr );
|
||||
|
||||
Schematic().Reset();
|
||||
|
||||
wxFileName projectFn( dlg.GetPath() );
|
||||
@@ -696,6 +699,17 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
|
||||
if( !IsWritable( schematicFileName ) )
|
||||
return false;
|
||||
|
||||
wxFileName projectFile( schematicFileName );
|
||||
|
||||
projectFile.SetExt( ProjectFileExtension );
|
||||
|
||||
if( projectFile.FileExists() )
|
||||
{
|
||||
// Save various ERC settings, such as violation severities (which may have been edited
|
||||
// via the ERC dialog as well as the Schematic Setup dialog), ERC exclusions, etc.
|
||||
saveProjectSettings();
|
||||
}
|
||||
|
||||
wxString tempFile = wxFileName::CreateTempFileName( wxS( "eeschema" ) );
|
||||
|
||||
// Save
|
||||
|
||||
@@ -415,7 +415,7 @@ wxString LIB_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
|
||||
{
|
||||
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
|
||||
|
||||
if( IsNameShown() )
|
||||
if( IsNameShown() && aAllowExtraText )
|
||||
text = GetName() << wxT( ": " ) << text;
|
||||
|
||||
return text;
|
||||
|
||||
@@ -847,7 +847,7 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
|
||||
* when m_convert == 0, the body item is common to shapes
|
||||
*/
|
||||
|
||||
LIB_SYMBOL_SPTR parent = m_parent.lock();
|
||||
LIB_SYMBOL_SPTR parent = m_parent.lock();
|
||||
const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
|
||||
|
||||
for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
|
||||
@@ -856,7 +856,7 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
|
||||
if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
|
||||
continue;
|
||||
|
||||
// Shape filtering:
|
||||
// De Morgan variant filtering:
|
||||
if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
|
||||
continue;
|
||||
|
||||
@@ -1276,6 +1276,7 @@ bool LIB_SYMBOL::HasConversion() const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int LIB_SYMBOL::GetMaxPinNumber() const
|
||||
{
|
||||
int maxPinNumber = 0;
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
bool IsDanglingStart() const { return m_isDanglingStart; }
|
||||
bool IsDanglingEnd() const { return m_isDanglingEnd; }
|
||||
|
||||
void SetEndDangling( bool aDanglingState ) { m_isDanglingEnd = aDanglingState; }
|
||||
|
||||
// Do not create a copy constructor. The one generated by the compiler is adequate.
|
||||
|
||||
~SCH_BUS_ENTRY_BASE() { }
|
||||
|
||||
@@ -398,7 +398,7 @@ void SCH_EDIT_FRAME::setupUIConditions()
|
||||
{
|
||||
SCH_BASE_FRAME::setupUIConditions();
|
||||
|
||||
ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
|
||||
ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
|
||||
SCH_EDITOR_CONDITIONS cond( this );
|
||||
|
||||
wxASSERT( mgr );
|
||||
@@ -417,11 +417,20 @@ void SCH_EDIT_FRAME::setupUIConditions()
|
||||
};
|
||||
|
||||
|
||||
auto undoCond =
|
||||
[ this ] (const SELECTION& aSel )
|
||||
{
|
||||
if( SCH_LINE_WIRE_BUS_TOOL::IsDrawingLineWireOrBus( aSel ) )
|
||||
return true;
|
||||
|
||||
return GetUndoCommandCount() > 0;
|
||||
};
|
||||
|
||||
#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
|
||||
#define CHECK( x ) ACTION_CONDITIONS().Check( x )
|
||||
|
||||
mgr->SetConditions( ACTIONS::save, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
|
||||
mgr->SetConditions( ACTIONS::undo, ENABLE( cond.UndoAvailable() ) );
|
||||
mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) );
|
||||
mgr->SetConditions( ACTIONS::redo, ENABLE( cond.RedoAvailable() ) );
|
||||
|
||||
mgr->SetConditions( EE_ACTIONS::showHierarchy, CHECK( hierarchyNavigatorCond ) );
|
||||
@@ -1487,9 +1496,10 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& changed_list = m_undoList.m_CommandsList.back();
|
||||
PICKED_ITEMS_LIST* changed_list = m_undoList.m_CommandsList.back();
|
||||
std::set<SCH_ITEM*> changed_items;
|
||||
std::vector<VECTOR2I> pts;
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
|
||||
|
||||
for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii )
|
||||
{
|
||||
@@ -1498,11 +1508,16 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
if( !item || !IsEeschemaType( item->Type() ) )
|
||||
continue;
|
||||
|
||||
SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( changed_list->GetScreenForItem( ii ) );
|
||||
SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( item );
|
||||
SCH_SHEET_PATHS& paths = screen->GetClientSheetPaths();
|
||||
|
||||
std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
|
||||
pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
|
||||
changed_items.insert( sch_item );
|
||||
|
||||
for( SCH_SHEET_PATH& path : paths )
|
||||
item_paths.insert( std::make_pair( path, sch_item ) );
|
||||
}
|
||||
|
||||
for( VECTOR2I& pt: pts )
|
||||
@@ -1537,6 +1552,8 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
Schematic().ConnectionGraph()->ExtractAffectedItems(
|
||||
changed_items );
|
||||
|
||||
all_items.insert( item_paths.begin(), item_paths.end() );
|
||||
|
||||
CONNECTION_GRAPH new_graph( &Schematic() );
|
||||
|
||||
new_graph.SetLastCodes( Schematic().ConnectionGraph() );
|
||||
@@ -1547,7 +1564,6 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
{
|
||||
case SCH_FIELD_T:
|
||||
case SCH_PIN_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
static_cast<SCH_ITEM*>( item->GetParent() )->SetConnectivityDirty();
|
||||
break;
|
||||
|
||||
|
||||
@@ -92,8 +92,10 @@ SCH_FIELD::SCH_FIELD( const SCH_FIELD& aField ) :
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_renderCacheValid = aField.m_renderCacheValid;
|
||||
@@ -116,8 +118,10 @@ SCH_FIELD& SCH_FIELD::operator=( const SCH_FIELD& aField )
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_renderCacheValid = aField.m_renderCacheValid;
|
||||
|
||||
+13
-1
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
bool IsHypertext() const override
|
||||
{
|
||||
return m_id == 0 && m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T;
|
||||
return GetCanonicalName() == wxT( "Intersheetrefs" );
|
||||
}
|
||||
|
||||
void DoHypertextAction( EDA_DRAW_FRAME* aFrame ) const override;
|
||||
@@ -134,6 +134,18 @@ public:
|
||||
return GetShownText( nullptr, aAllowExtraText, aDepth );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if both the name and value of the field are empty. Whitespace
|
||||
* does not count as non-empty
|
||||
*/
|
||||
bool IsEmpty()
|
||||
{
|
||||
wxString name( m_name );
|
||||
wxString value( GetText() );
|
||||
|
||||
return name.Trim().empty() && value.Trim().empty();
|
||||
}
|
||||
|
||||
COLOR4D GetFieldColor() const;
|
||||
|
||||
void SetLastResolvedState( const SCH_ITEM* aItem ) override
|
||||
|
||||
@@ -149,9 +149,6 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const
|
||||
if( !IsConnectable() )
|
||||
return nullptr;
|
||||
|
||||
wxCHECK_MSG( !IsConnectivityDirty(), nullptr,
|
||||
wxT( "Shouldn't be asking for connection if connectivity is dirty!" ) );
|
||||
|
||||
if( !aSheet )
|
||||
aSheet = &Schematic()->CurrentSheet();
|
||||
|
||||
@@ -167,7 +164,12 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const
|
||||
void SCH_ITEM::SetConnectionGraph( CONNECTION_GRAPH* aGraph )
|
||||
{
|
||||
for( auto& [path, conn] : m_connection_map )
|
||||
{
|
||||
conn->SetGraph( aGraph );
|
||||
|
||||
for( auto& member : conn->AllMembers() )
|
||||
member->SetGraph( aGraph );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,10 +215,11 @@ void SCH_ITEM::AddConnectionTo( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aItem )
|
||||
SCH_CONNECTION* SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet,
|
||||
CONNECTION_GRAPH* aGraph )
|
||||
{
|
||||
SetConnectivityDirty( false );
|
||||
|
||||
SCH_CONNECTION* connection = Connection( &aSheet );
|
||||
|
||||
// N.B. Do not clear the dirty connectivity flag here because we may need
|
||||
// to create a connection for a different sheet, and we don't want to
|
||||
// skip the connection creation because the flag is cleared.
|
||||
if( connection )
|
||||
{
|
||||
connection->Reset();
|
||||
@@ -239,8 +242,6 @@ SCH_CONNECTION* SCH_ITEM::GetOrInitConnection( const SCH_SHEET_PATH& aSheet,
|
||||
if( !IsConnectable() )
|
||||
return nullptr;
|
||||
|
||||
SetConnectivityDirty( false );
|
||||
|
||||
SCH_CONNECTION* connection = Connection( &aSheet );
|
||||
|
||||
if( connection )
|
||||
|
||||
+131
-107
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 CERN
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
@@ -86,7 +86,10 @@ std::vector<KICAD_T> SCH_PAINTER::g_ScaledSelectionTypes = {
|
||||
SCH_LINE_T,
|
||||
LIB_SHAPE_T, SCH_SHAPE_T,
|
||||
SCH_BITMAP_T,
|
||||
SCH_GLOBAL_LABEL_T,
|
||||
SCH_DIRECTIVE_LABEL_T,
|
||||
SCH_HIER_LABEL_T,
|
||||
SCH_SHEET_PIN_T,
|
||||
LIB_SYMBOL_T, SCH_SYMBOL_T,
|
||||
SCH_SHEET_T,
|
||||
LIB_PIN_T, SCH_PIN_T
|
||||
@@ -186,7 +189,7 @@ SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
|
||||
m_schematic( nullptr )
|
||||
{ }
|
||||
|
||||
bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
|
||||
bool SCH_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
||||
{
|
||||
const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
|
||||
|
||||
@@ -198,7 +201,7 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCH_PAINTER::draw( const EDA_ITEM *aItem, int aLayer, bool aDimmed )
|
||||
void SCH_PAINTER::draw( const EDA_ITEM* aItem, int aLayer, bool aDimmed )
|
||||
{
|
||||
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
@@ -369,7 +372,7 @@ float SCH_PAINTER::getShadowWidth( bool aForHighlight ) const
|
||||
}
|
||||
|
||||
|
||||
COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM *aItem, int aLayer, bool aDrawingShadows,
|
||||
COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDrawingShadows,
|
||||
bool aDimmed ) const
|
||||
{
|
||||
COLOR4D color = m_schSettings.GetLayerColor( aLayer );
|
||||
@@ -666,7 +669,7 @@ void SCH_PAINTER::triLine( const VECTOR2D &a, const VECTOR2D &b, const VECTOR2D
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const LIB_SYMBOL *aSymbol, int aLayer, bool aDrawFields, int aUnit,
|
||||
void SCH_PAINTER::draw( const LIB_SYMBOL* aSymbol, int aLayer, bool aDrawFields, int aUnit,
|
||||
int aConvert, bool aDimmed )
|
||||
{
|
||||
if( !aUnit )
|
||||
@@ -751,7 +754,11 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer, bool aDimm
|
||||
{
|
||||
COLOR4D fillColour = shape->GetFillColor();
|
||||
|
||||
if( aDimmed )
|
||||
if( m_schSettings.m_OverrideItemColors )
|
||||
{
|
||||
fillColour = getRenderColor( aItem, LAYER_DEVICE_BACKGROUND, false, aDimmed );
|
||||
}
|
||||
else if( aDimmed )
|
||||
{
|
||||
fillColour = fillColour.Mix(
|
||||
m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ), 0.5f );
|
||||
@@ -928,7 +935,7 @@ void SCH_PAINTER::draw( const LIB_SHAPE *aShape, int aLayer, bool aDimmed )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const LIB_FIELD *aField, int aLayer, bool aDimmed )
|
||||
void SCH_PAINTER::draw( const LIB_FIELD* aField, int aLayer, bool aDimmed )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
@@ -1047,25 +1054,38 @@ void SCH_PAINTER::draw( const LIB_TEXT* aText, int aLayer, bool aDimmed )
|
||||
|
||||
attrs.m_StrokeWidth = KiROUND( getTextThickness( aText ) );
|
||||
|
||||
// Due to the fact a shadow text can be drawn left or right aligned,
|
||||
// it needs an offset = shadowWidth/2 to be drawn at the same place as normal text
|
||||
// texts drawn as GR_TEXT_H_ALIGN_CENTER do not need a specific offset.
|
||||
// this offset is shadowWidth/2 but for some reason we need to slightly modify this offset
|
||||
// for a better look (better alignment of shadow shape), for KiCad font only
|
||||
double shadowOffset = 0.0;
|
||||
|
||||
if( drawingShadows )
|
||||
{
|
||||
double shadowWidth = getShadowWidth( !aText->IsSelected() );
|
||||
attrs.m_StrokeWidth += getShadowWidth( !aText->IsSelected() );
|
||||
|
||||
const double adjust = 1.2f; // Value chosen after tests
|
||||
shadowOffset = shadowWidth/2.0f * adjust;
|
||||
}
|
||||
|
||||
if( attrs.m_Angle == ANGLE_VERTICAL )
|
||||
{
|
||||
switch( attrs.m_Halign )
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: pos.y = bBox.GetBottom(); break;
|
||||
case GR_TEXT_H_ALIGN_LEFT: pos.y = bBox.GetBottom() + shadowOffset; break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: pos.y = ( bBox.GetTop() + bBox.GetBottom() ) / 2; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: pos.y = bBox.GetTop(); break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: pos.y = bBox.GetTop() - shadowOffset; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( attrs.m_Halign )
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: pos.x = bBox.GetLeft(); break;
|
||||
case GR_TEXT_H_ALIGN_LEFT: pos.x = bBox.GetLeft() - shadowOffset; break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: pos.x = ( bBox.GetLeft() + bBox.GetRight() ) / 2; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: pos.x = bBox.GetRight(); break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: pos.x = bBox.GetRight() + shadowOffset; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1512,6 +1532,19 @@ void SCH_PAINTER::draw( const LIB_PIN *aPin, int aLayer, bool aDimmed )
|
||||
|
||||
for( float& t : thickness )
|
||||
t += shadowWidth;
|
||||
|
||||
// Due to the fact a shadow text in position INSIDE or OUTSIDE is drawn left or right aligned,
|
||||
// it needs an offset = shadowWidth/2 to be drawn at the same place as normal text
|
||||
// texts drawn as GR_TEXT_H_ALIGN_CENTER do not need a specific offset.
|
||||
// this offset is shadowWidth/2 but for some reason we need to slightly modify this offset
|
||||
// for a better look (better alignment of shadow shape), for KiCad font only
|
||||
if( !KIFONT::FONT::GetFont( eeconfig()->m_Appearance.default_font )->IsOutline() )
|
||||
{
|
||||
const float adjust = 1.2f; // Value chosen after tests
|
||||
float shadowOffset = shadowWidth/2.0f * adjust;
|
||||
insideOffset -= shadowOffset;
|
||||
outsideOffset -= shadowOffset;
|
||||
}
|
||||
}
|
||||
|
||||
auto drawText =
|
||||
@@ -1678,7 +1711,7 @@ void SCH_PAINTER::drawDanglingSymbol( const VECTOR2I& aPos, const COLOR4D& aColo
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_JUNCTION *aJct, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_JUNCTION* aJct, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
@@ -1910,7 +1943,6 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
bool drawingDangling = aLayer == LAYER_DANGLING;
|
||||
|
||||
if( drawingShadows && !( aText->IsBrightened() || aText->IsSelected() ) )
|
||||
return;
|
||||
@@ -1946,18 +1978,6 @@ void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer )
|
||||
return;
|
||||
}
|
||||
|
||||
if( drawingDangling )
|
||||
{
|
||||
if( aText->IsDangling() )
|
||||
{
|
||||
drawDanglingSymbol( aText->GetTextPos(), color,
|
||||
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
|
||||
drawingShadows, aText->IsBrightened() );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->SetFillColor( color );
|
||||
|
||||
@@ -2324,15 +2344,14 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
|
||||
|
||||
if( aSymbol->GetDNP() )
|
||||
{
|
||||
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
BOX2I bbox = aSymbol->GetBodyAndPinsBoundingBox();
|
||||
VECTOR2I pt1 = bbox.GetOrigin();
|
||||
VECTOR2I pt2 = bbox.GetEnd();
|
||||
BOX2I bbox = aSymbol->GetBodyAndPinsBoundingBox();
|
||||
VECTOR2I pt1 = bbox.GetOrigin();
|
||||
VECTOR2I pt2 = bbox.GetEnd();
|
||||
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetStrokeColor( colors->GetColor( LAYER_ERC_ERR ) );
|
||||
m_gal->SetFillColor( colors->GetColor( LAYER_ERC_ERR ) );
|
||||
m_gal->SetStrokeColor( m_schSettings.GetLayerColor( LAYER_ERC_ERR ) );
|
||||
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_ERC_ERR ) );
|
||||
|
||||
m_gal->DrawSegment( pt1, pt2, 3.0 * schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS ) );
|
||||
std::swap( pt1.x, pt2.x );
|
||||
@@ -2482,9 +2501,10 @@ void SCH_PAINTER::draw( const SCH_FIELD* aField, int aLayer, bool aDimmed )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_GLOBALLABEL* aLabel, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
bool drawingDangling = aLayer == LAYER_DANGLING;
|
||||
|
||||
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
|
||||
{
|
||||
@@ -2500,6 +2520,18 @@ void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
|
||||
|
||||
COLOR4D color = getRenderColor( aLabel, LAYER_GLOBLABEL, drawingShadows );
|
||||
|
||||
if( drawingDangling )
|
||||
{
|
||||
if( aLabel->IsDangling() )
|
||||
{
|
||||
drawDanglingSymbol( aLabel->GetTextPos(), color,
|
||||
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
|
||||
drawingShadows, aLabel->IsBrightened() );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<VECTOR2I> pts;
|
||||
std::deque<VECTOR2D> pts2;
|
||||
|
||||
@@ -2508,46 +2540,30 @@ void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
|
||||
for( const VECTOR2I& p : pts )
|
||||
pts2.emplace_back( VECTOR2D( p.x, p.y ) );
|
||||
|
||||
// The text is drawn inside the graphic shape.
|
||||
// On Cairo the graphic shape is filled by the background before drawing the text.
|
||||
// However if the text is selected, it is draw twice: first on LAYER_SELECTION_SHADOWS
|
||||
// and second on the text layer. The second must not erase the first drawing.
|
||||
bool fillBg = ( ( aLayer == LAYER_SELECTION_SHADOWS ) || !aLabel->IsSelected() )
|
||||
&& aLayer != LAYER_DANGLING;
|
||||
m_gal->SetIsFill( fillBg );
|
||||
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetLineWidth( getTextThickness( aLabel ) );
|
||||
m_gal->SetLineWidth( getLineWidth( aLabel, drawingShadows ) );
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->DrawPolyline( pts2 );
|
||||
|
||||
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_LABEL *aLabel, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
|
||||
if( drawingShadows )
|
||||
{
|
||||
for( const SCH_FIELD& field : aLabel->GetFields() )
|
||||
draw( &field, aLayer, false );
|
||||
m_gal->SetIsFill( eeconfig()->m_Selection.fill_shapes );
|
||||
m_gal->SetFillColor( color );
|
||||
m_gal->DrawPolygon( pts2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gal->SetIsFill( false );
|
||||
m_gal->DrawPolyline( pts2 );
|
||||
}
|
||||
|
||||
if( isFieldsLayer( aLayer ) )
|
||||
return;
|
||||
|
||||
if( drawingShadows && !( aLabel->IsBrightened() || aLabel->IsSelected() ) )
|
||||
return;
|
||||
|
||||
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_LABEL* aLabel, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
bool drawingDangling = aLayer == LAYER_DANGLING;
|
||||
|
||||
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
|
||||
{
|
||||
@@ -2563,6 +2579,53 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
|
||||
|
||||
COLOR4D color = getRenderColor( aLabel, LAYER_HIERLABEL, drawingShadows );
|
||||
|
||||
if( drawingDangling )
|
||||
{
|
||||
if( aLabel->IsDangling() )
|
||||
{
|
||||
drawDanglingSymbol( aLabel->GetTextPos(), color,
|
||||
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
|
||||
drawingShadows, aLabel->IsBrightened() );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_HIERLABEL* aLabel, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
bool drawingDangling = aLayer == LAYER_DANGLING;
|
||||
|
||||
if( !( drawingShadows || drawingDangling ) || eeconfig()->m_Selection.draw_selected_children )
|
||||
{
|
||||
for( const SCH_FIELD& field : aLabel->GetFields() )
|
||||
draw( &field, aLayer, false );
|
||||
}
|
||||
|
||||
if( isFieldsLayer( aLayer ) )
|
||||
return;
|
||||
|
||||
if( drawingShadows && !( aLabel->IsBrightened() || aLabel->IsSelected() ) )
|
||||
return;
|
||||
|
||||
COLOR4D color = getRenderColor( aLabel, LAYER_HIERLABEL, drawingShadows );
|
||||
|
||||
if( drawingDangling )
|
||||
{
|
||||
if( aLabel->IsDangling() )
|
||||
{
|
||||
drawDanglingSymbol( aLabel->GetTextPos(), color,
|
||||
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
|
||||
drawingShadows, aLabel->IsBrightened() );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_schematic )
|
||||
{
|
||||
SCH_CONNECTION* conn = nullptr;
|
||||
@@ -2585,7 +2648,7 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetLineWidth( getTextThickness( aLabel ) );
|
||||
m_gal->SetLineWidth( getLineWidth( aLabel, drawingShadows ) );
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->DrawPolyline( pts2 );
|
||||
|
||||
@@ -2593,7 +2656,7 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_DIRECTIVE_LABEL *aLabel, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_DIRECTIVE_LABEL* aLabel, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
@@ -2663,53 +2726,14 @@ void SCH_PAINTER::draw( const SCH_SHEET *aSheet, int aLayer )
|
||||
{
|
||||
for( const SCH_FIELD& field : aSheet->GetFields() )
|
||||
draw( &field, aLayer, false );
|
||||
|
||||
for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() )
|
||||
draw( static_cast<SCH_HIERLABEL*>( sheetPin ), aLayer );
|
||||
}
|
||||
|
||||
if( isFieldsLayer( aLayer ) )
|
||||
return;
|
||||
|
||||
if( aLayer == LAYER_HIERLABEL || aLayer == LAYER_SELECTION_SHADOWS )
|
||||
{
|
||||
for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() )
|
||||
{
|
||||
if( drawingShadows )
|
||||
{
|
||||
if( ( aSheet->IsBrightened() || aSheet->IsSelected() )
|
||||
&& eeconfig()->m_Selection.draw_selected_children )
|
||||
{
|
||||
// fall through to draw
|
||||
}
|
||||
else if( sheetPin->IsBrightened() || sheetPin->IsSelected() )
|
||||
{
|
||||
// fall through to draw
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int width = std::max( aSheet->GetPenWidth(), m_schSettings.GetDefaultPenWidth() );
|
||||
VECTOR2I initial_pos = sheetPin->GetTextPos();
|
||||
VECTOR2I offset_pos = initial_pos;
|
||||
|
||||
// For aesthetic reasons, the SHEET_PIN is drawn with a small offset of width / 2
|
||||
switch( sheetPin->GetSide() )
|
||||
{
|
||||
case SHEET_SIDE::TOP: offset_pos.y += KiROUND( width / 2.0 ); break;
|
||||
case SHEET_SIDE::BOTTOM: offset_pos.y -= KiROUND( width / 2.0 ); break;
|
||||
case SHEET_SIDE::RIGHT: offset_pos.x -= KiROUND( width / 2.0 ); break;
|
||||
case SHEET_SIDE::LEFT: offset_pos.x += KiROUND( width / 2.0 ); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
sheetPin->SetTextPos( offset_pos );
|
||||
draw( static_cast<SCH_HIERLABEL*>( sheetPin ), aLayer );
|
||||
m_gal->DrawLine( offset_pos, initial_pos );
|
||||
sheetPin->SetTextPos( initial_pos );
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2D pos = aSheet->GetPosition();
|
||||
VECTOR2D size = aSheet->GetSize();
|
||||
|
||||
@@ -2734,7 +2758,7 @@ void SCH_PAINTER::draw( const SCH_SHEET *aSheet, int aLayer )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_NO_CONNECT *aNC, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_NO_CONNECT* aNC, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
@@ -2813,7 +2837,7 @@ void SCH_PAINTER::draw( const SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_BITMAP *aBitmap, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_BITMAP* aBitmap, int aLayer )
|
||||
{
|
||||
m_gal->Save();
|
||||
m_gal->Translate( aBitmap->GetPosition() );
|
||||
@@ -2858,7 +2882,7 @@ void SCH_PAINTER::draw( const SCH_BITMAP *aBitmap, int aLayer )
|
||||
}
|
||||
|
||||
|
||||
void SCH_PAINTER::draw( const SCH_MARKER *aMarker, int aLayer )
|
||||
void SCH_PAINTER::draw( const SCH_MARKER* aMarker, int aLayer )
|
||||
{
|
||||
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map<wxString, wxString>& aProps )
|
||||
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
|
||||
BorderColor = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
|
||||
|
||||
IsSolid = ALTIUM_PARSER::ReadBool( aProps, "WORDWRAP", true );
|
||||
IsSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false );
|
||||
|
||||
Alignment = ReadEnum<ASCH_TEXT_FRAME_ALIGNMENT>( aProps, "ALIGNMENT", 1, 3,
|
||||
ASCH_TEXT_FRAME_ALIGNMENT::LEFT );
|
||||
@@ -331,13 +331,8 @@ ASCH_POLYLINE::ASCH_POLYLINE( const std::map<wxString, wxString>& aProps )
|
||||
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
|
||||
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
|
||||
|
||||
int linestyleVar = ALTIUM_PARSER::ReadInt( aProps, "LINESTYLEEXT", 0 );
|
||||
|
||||
// overwrite if present.
|
||||
linestyleVar = ALTIUM_PARSER::ReadInt( aProps, "LINESTYLE", linestyleVar );
|
||||
LineStyle = linestyleVar >= 0 && linestyleVar <= 3 ?
|
||||
static_cast<ASCH_POLYLINE_LINESTYLE>( linestyleVar ) :
|
||||
ASCH_POLYLINE_LINESTYLE::SOLID;
|
||||
auto lineStyleExt = ReadEnum( aProps, "LINESTYLEEXT", 0, 3, ASCH_POLYLINE_LINESTYLE::SOLID );
|
||||
LineStyle = ReadEnum( aProps, "LINESTYLE", 0, 3, lineStyleExt ); // overwrite if present.
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +442,11 @@ ASCH_LINE::ASCH_LINE( const std::map<wxString, wxString>& aProps )
|
||||
point2 = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ),
|
||||
-ReadKiCadUnitFrac( aProps, "CORNER.Y" ) );
|
||||
|
||||
lineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
|
||||
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
|
||||
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
|
||||
|
||||
auto lineStyleExt = ReadEnum( aProps, "LINESTYLEEXT", 0, 3, ASCH_POLYLINE_LINESTYLE::SOLID );
|
||||
LineStyle = ReadEnum( aProps, "LINESTYLE", 0, 3, lineStyleExt ); // overwrite if present.
|
||||
}
|
||||
|
||||
|
||||
@@ -667,6 +666,9 @@ ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map<wxString, wxString>& aProps )
|
||||
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
|
||||
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
|
||||
|
||||
justification = ReadEnum<ASCH_LABEL_JUSTIFICATION>( aProps, "JUSTIFICATION", 0, 8,
|
||||
ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT );
|
||||
|
||||
orientation = ReadEnum<ASCH_RECORD_ORIENTATION>( aProps, "ORIENTATION", 0, 3,
|
||||
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
|
||||
}
|
||||
@@ -676,8 +678,6 @@ ASCH_BUS::ASCH_BUS( const std::map<wxString, wxString>& aProps )
|
||||
{
|
||||
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS );
|
||||
|
||||
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
|
||||
|
||||
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
|
||||
|
||||
for( int i = 1; i <= locationcount; i++ )
|
||||
@@ -695,8 +695,6 @@ ASCH_WIRE::ASCH_WIRE( const std::map<wxString, wxString>& aProps )
|
||||
{
|
||||
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE );
|
||||
|
||||
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
|
||||
|
||||
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
|
||||
|
||||
for( int i = 1; i <= locationcount; i++ )
|
||||
@@ -797,6 +795,11 @@ ASCH_SHEET::ASCH_SHEET( const std::map<wxString, wxString>& aProps )
|
||||
for( int i = 1; i <= fontidcount; i++ )
|
||||
fonts.emplace_back( aProps, i );
|
||||
|
||||
useCustomSheet = ALTIUM_PARSER::ReadBool( aProps, "USECUSTOMSHEET", false );
|
||||
|
||||
customSize = VECTOR2I( ReadKiCadUnitFrac( aProps, "CUSTOMX" ),
|
||||
ReadKiCadUnitFrac( aProps, "CUSTOMY" ) );
|
||||
|
||||
sheetSize = ReadEnum<ASCH_SHEET_SIZE>( aProps, "SHEETSTYLE", 0, 17, ASCH_SHEET_SIZE::A4 );
|
||||
sheetOrientation = ReadEnum<ASCH_SHEET_WORKSPACEORIENTATION>(
|
||||
aProps, "WORKSPACEORIENTATION", 0, 1, ASCH_SHEET_WORKSPACEORIENTATION::LANDSCAPE );
|
||||
|
||||
@@ -437,7 +437,10 @@ struct ASCH_LINE
|
||||
VECTOR2I point1;
|
||||
VECTOR2I point2;
|
||||
|
||||
int lineWidth;
|
||||
int LineWidth;
|
||||
int Color;
|
||||
|
||||
ASCH_POLYLINE_LINESTYLE LineStyle;
|
||||
|
||||
explicit ASCH_LINE( const std::map<wxString, wxString>& aProps );
|
||||
};
|
||||
@@ -663,6 +666,7 @@ struct ASCH_NET_LABEL
|
||||
|
||||
VECTOR2I location;
|
||||
|
||||
ASCH_LABEL_JUSTIFICATION justification;
|
||||
ASCH_RECORD_ORIENTATION orientation;
|
||||
|
||||
explicit ASCH_NET_LABEL( const std::map<wxString, wxString>& aProps );
|
||||
@@ -772,6 +776,9 @@ struct ASCH_SHEET
|
||||
{
|
||||
std::vector<ASCH_SHEET_FONT> fonts;
|
||||
|
||||
bool useCustomSheet;
|
||||
VECTOR2I customSize;
|
||||
|
||||
ASCH_SHEET_SIZE sheetSize;
|
||||
ASCH_SHEET_WORKSPACEORIENTATION sheetOrientation;
|
||||
|
||||
|
||||
@@ -1743,7 +1743,10 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
|
||||
// close polygon
|
||||
SCH_LINE* line = new SCH_LINE( elem.point1 + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
|
||||
line->SetEndPoint( elem.point2 + m_sheetOffset );
|
||||
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) ); // TODO?
|
||||
|
||||
COLOR4D color = GetColorFromInt( elem.Color );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, GetPlotDashType( elem.LineStyle ),
|
||||
color == PUREBLUE ? COLOR4D::UNSPECIFIED : color ) );
|
||||
|
||||
line->SetFlags( IS_NEW );
|
||||
screen->Append( line );
|
||||
@@ -1773,7 +1776,9 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
|
||||
line->AddPoint( GetRelativePosition( elem.point1 + m_sheetOffset, symbol ) );
|
||||
line->AddPoint( GetRelativePosition( elem.point2 + m_sheetOffset, symbol ) );
|
||||
|
||||
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
|
||||
COLOR4D color = GetColorFromInt( elem.Color );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, GetPlotDashType( elem.LineStyle ),
|
||||
color == PUREBLUE ? COLOR4D::UNSPECIFIED : color ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2639,27 +2644,7 @@ void SCH_ALTIUM_PLUGIN::ParseNetLabel( const std::map<wxString, wxString>& aProp
|
||||
SCH_SCREEN* screen = getCurrentScreen();
|
||||
wxCHECK( screen, /* void */ );
|
||||
|
||||
switch( elem.orientation )
|
||||
{
|
||||
case ASCH_RECORD_ORIENTATION::RIGHTWARDS:
|
||||
label->SetTextSpinStyle( TEXT_SPIN_STYLE::RIGHT );
|
||||
break;
|
||||
|
||||
case ASCH_RECORD_ORIENTATION::UPWARDS:
|
||||
label->SetTextSpinStyle( TEXT_SPIN_STYLE::UP );
|
||||
break;
|
||||
|
||||
case ASCH_RECORD_ORIENTATION::LEFTWARDS:
|
||||
label->SetTextSpinStyle( TEXT_SPIN_STYLE::LEFT );
|
||||
break;
|
||||
|
||||
case ASCH_RECORD_ORIENTATION::DOWNWARDS:
|
||||
label->SetTextSpinStyle( TEXT_SPIN_STYLE::BOTTOM );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetTextPositioning( label, elem.justification, elem.orientation );
|
||||
|
||||
label->SetFlags( IS_NEW );
|
||||
screen->Append( label );
|
||||
@@ -2808,27 +2793,36 @@ void SCH_ALTIUM_PLUGIN::ParseSheet( const std::map<wxString, wxString>& aPropert
|
||||
|
||||
bool isPortrait = m_altiumSheet->sheetOrientation == ASCH_SHEET_WORKSPACEORIENTATION::PORTRAIT;
|
||||
|
||||
switch( m_altiumSheet->sheetSize )
|
||||
if( m_altiumSheet->useCustomSheet )
|
||||
{
|
||||
default:
|
||||
case ASCH_SHEET_SIZE::A4: pageInfo.SetType( "A4", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A3: pageInfo.SetType( "A3", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A2: pageInfo.SetType( "A2", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A1: pageInfo.SetType( "A1", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A0: pageInfo.SetType( "A0", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A: pageInfo.SetType( "A", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::B: pageInfo.SetType( "B", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::C: pageInfo.SetType( "C", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::D: pageInfo.SetType( "D", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::E: pageInfo.SetType( "E", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::LETTER: pageInfo.SetType( "USLetter", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::LEGAL: pageInfo.SetType( "USLegal", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::TABLOID: pageInfo.SetType( "A3", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.SetType( "A", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.SetType( "B", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.SetType( "C", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.SetType( "D", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.SetType( "E", isPortrait ); break;
|
||||
PAGE_INFO::SetCustomWidthMils( schIUScale.IUToMils( m_altiumSheet->customSize.x ) );
|
||||
PAGE_INFO::SetCustomHeightMils( schIUScale.IUToMils( m_altiumSheet->customSize.y ) );
|
||||
pageInfo.SetType( PAGE_INFO::Custom, isPortrait );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( m_altiumSheet->sheetSize )
|
||||
{
|
||||
default:
|
||||
case ASCH_SHEET_SIZE::A4: pageInfo.SetType( "A4", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A3: pageInfo.SetType( "A3", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A2: pageInfo.SetType( "A2", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A1: pageInfo.SetType( "A1", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A0: pageInfo.SetType( "A0", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::A: pageInfo.SetType( "A", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::B: pageInfo.SetType( "B", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::C: pageInfo.SetType( "C", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::D: pageInfo.SetType( "D", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::E: pageInfo.SetType( "E", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::LETTER: pageInfo.SetType( "USLetter", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::LEGAL: pageInfo.SetType( "USLegal", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::TABLOID: pageInfo.SetType( "A3", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.SetType( "A", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.SetType( "B", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.SetType( "C", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.SetType( "D", isPortrait ); break;
|
||||
case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.SetType( "E", isPortrait ); break;
|
||||
}
|
||||
}
|
||||
|
||||
screen->SetPageSettings( pageInfo );
|
||||
|
||||
@@ -73,7 +73,7 @@ void SCH_DATABASE_PLUGIN::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolL
|
||||
{
|
||||
std::vector<DATABASE_CONNECTION::ROW> results;
|
||||
|
||||
if( !m_conn->SelectAll( table.table, results ) )
|
||||
if( !m_conn->SelectAll( table.table, table.key_col, results ) )
|
||||
{
|
||||
if( !m_conn->GetLastError().empty() )
|
||||
{
|
||||
@@ -287,6 +287,26 @@ void SCH_DATABASE_PLUGIN::ensureConnection()
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
for( const DATABASE_LIB_TABLE& tableIter : m_settings->m_Tables )
|
||||
{
|
||||
std::set<std::string> columns;
|
||||
|
||||
columns.insert( tableIter.key_col );
|
||||
columns.insert( tableIter.footprints_col );
|
||||
columns.insert( tableIter.symbols_col );
|
||||
|
||||
columns.insert( tableIter.properties.description );
|
||||
columns.insert( tableIter.properties.footprint_filters );
|
||||
columns.insert( tableIter.properties.keywords );
|
||||
columns.insert( tableIter.properties.exclude_from_bom );
|
||||
columns.insert( tableIter.properties.exclude_from_board );
|
||||
|
||||
for( const DATABASE_FIELD_MAPPING& field : tableIter.fields )
|
||||
columns.insert( field.column );
|
||||
|
||||
m_conn->CacheTableInfo( tableIter.table, columns );
|
||||
}
|
||||
|
||||
m_conn->SetCacheParams( m_settings->m_Cache.max_size, m_settings->m_Cache.max_age );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ LIB_PIN* SCH_SEXPR_PARSER::parsePin()
|
||||
{
|
||||
// The EDA_TEXT font effects formatting is used so use and EDA_TEXT object
|
||||
// so duplicate parsing is not required.
|
||||
EDA_TEXT text( schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) );
|
||||
EDA_TEXT text( schIUScale );
|
||||
|
||||
parseEDA_TEXT( &text, true );
|
||||
pin->SetNameTextSize( text.GetTextHeight() );
|
||||
@@ -1431,7 +1431,7 @@ LIB_PIN* SCH_SEXPR_PARSER::parsePin()
|
||||
{
|
||||
// The EDA_TEXT font effects formatting is used so use and EDA_TEXT object
|
||||
// so duplicate parsing is not required.
|
||||
EDA_TEXT text( schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) );
|
||||
EDA_TEXT text( schIUScale );
|
||||
|
||||
parseEDA_TEXT( &text, false );
|
||||
pin->SetNumberTextSize( text.GetTextHeight() );
|
||||
|
||||
@@ -1495,6 +1495,13 @@ LIB_SYMBOL* SCH_SEXPR_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wx
|
||||
if( it == m_cache->m_symbols.end() && aSymbolName.Contains( '/' ) )
|
||||
it = m_cache->m_symbols.find( EscapeString( aSymbolName, CTX_LEGACY_LIBID ) );
|
||||
|
||||
if( it == m_cache->m_symbols.end() && aSymbolName.Contains( wxT( "{slash}" ) ) )
|
||||
{
|
||||
wxString unescaped = aSymbolName;
|
||||
unescaped.Replace( wxT( "{slash}" ), wxT( "/" ) );
|
||||
it = m_cache->m_symbols.find( unescaped );
|
||||
}
|
||||
|
||||
if( it == m_cache->m_symbols.end() )
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -652,8 +652,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
}
|
||||
|
||||
// Remove aAdditionalRefs references
|
||||
for( size_t i = originalSize; i < ( aAdditionalRefs.GetCount() + originalSize ); i++ )
|
||||
RemoveItem( originalSize );
|
||||
m_flatList.erase( m_flatList.begin() + originalSize, m_flatList.end() );
|
||||
|
||||
wxASSERT( originalSize == GetCount() ); // Make sure we didn't make a mistake
|
||||
}
|
||||
|
||||
+37
-15
@@ -63,6 +63,12 @@
|
||||
#include "sch_bus_entry.h"
|
||||
#include "sim/sim_model_ideal.h"
|
||||
|
||||
/*
|
||||
* Flag to enable profiling of the TestDanglingEnds() function.
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
static const wxChar DanglingProfileMask[] = wxT( "DANGLING_PROFILE" );
|
||||
|
||||
SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) :
|
||||
BASE_SCREEN( aParent, SCH_SCREEN_T ),
|
||||
m_fileFormatVersionAtLoad( 0 ),
|
||||
@@ -835,7 +841,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
|
||||
|
||||
label = GetLabel( aPosition );
|
||||
|
||||
if( label && label->IsConnected( aPosition ) )
|
||||
if( label && !label->IsNew() && label->IsConnected( aPosition ) )
|
||||
return true;
|
||||
|
||||
break;
|
||||
@@ -847,7 +853,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
|
||||
break;
|
||||
|
||||
case LAYER_WIRE:
|
||||
if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T) )
|
||||
if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T ) )
|
||||
return true;
|
||||
|
||||
if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
|
||||
@@ -861,7 +867,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
|
||||
|
||||
label = GetLabel( aPosition, 1 );
|
||||
|
||||
if( label && label->IsConnected( aPosition ) )
|
||||
if( label && !label->IsNew() && label->IsConnected( aPosition ) )
|
||||
return true;
|
||||
|
||||
sheetPin = GetSheetPin( aPosition );
|
||||
@@ -1355,24 +1361,40 @@ void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
|
||||
void SCH_SCREEN::TestDanglingEnds( const SCH_SHEET_PATH* aPath,
|
||||
std::function<void( SCH_ITEM* )>* aChangedHandler ) const
|
||||
{
|
||||
PROF_TIMER timer( __FUNCTION__ );
|
||||
|
||||
std::vector<DANGLING_END_ITEM> endPoints;
|
||||
|
||||
auto getends =
|
||||
[&]( SCH_ITEM* item )
|
||||
{
|
||||
if( item->IsConnectable() )
|
||||
item->GetEndPoints( endPoints );
|
||||
};
|
||||
auto update_state =
|
||||
[&]( SCH_ITEM* item )
|
||||
{
|
||||
if( item->UpdateDanglingState( endPoints, aPath ) )
|
||||
{
|
||||
if( aChangedHandler )
|
||||
(*aChangedHandler)( item );
|
||||
}
|
||||
};
|
||||
|
||||
for( SCH_ITEM* item : Items() )
|
||||
{
|
||||
if( item->IsConnectable() )
|
||||
{
|
||||
endPoints.clear();
|
||||
|
||||
for( SCH_ITEM* overlapping : Items().Overlapping( item->GetBoundingBox() ) )
|
||||
overlapping->GetEndPoints( endPoints );
|
||||
|
||||
if( item->UpdateDanglingState( endPoints, aPath ) )
|
||||
{
|
||||
if( aChangedHandler )
|
||||
(*aChangedHandler)( item );
|
||||
}
|
||||
}
|
||||
getends( item );
|
||||
item->RunOnChildren( getends );
|
||||
}
|
||||
|
||||
for( SCH_ITEM* item : Items() )
|
||||
{
|
||||
update_state( item );
|
||||
item->RunOnChildren( update_state );
|
||||
}
|
||||
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
|
||||
timer.Show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+15
-3
@@ -505,9 +505,9 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of bus aliases defined in this screen
|
||||
* Return a set of bus aliases defined in this screen
|
||||
*/
|
||||
std::set< std::shared_ptr<BUS_ALIAS> > GetBusAliases() const
|
||||
auto& GetBusAliases() const
|
||||
{
|
||||
return m_aliases;
|
||||
}
|
||||
@@ -571,6 +571,18 @@ private:
|
||||
*/
|
||||
size_t getLibSymbolNameMatches( const SCH_SYMBOL& aSymbol, std::vector<wxString>& aMatches );
|
||||
|
||||
|
||||
/**
|
||||
* Compare two #BUS_ALIAS objects by name. For sorting in the set.
|
||||
*/
|
||||
struct BusAliasCmp
|
||||
{
|
||||
bool operator()( const std::shared_ptr<BUS_ALIAS>& a, const std::shared_ptr<BUS_ALIAS>& b ) const
|
||||
{
|
||||
return a->GetName() < b->GetName();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* last value for the zoom level, useful in Eeschema when changing the current displayed
|
||||
@@ -610,7 +622,7 @@ private:
|
||||
bool m_fileExists;
|
||||
|
||||
/// List of bus aliases stored in this screen.
|
||||
std::set< std::shared_ptr< BUS_ALIAS > > m_aliases;
|
||||
std::set< std::shared_ptr< BUS_ALIAS >, BusAliasCmp > m_aliases;
|
||||
|
||||
/// Library symbols required for this schematic.
|
||||
std::map<wxString, LIB_SYMBOL*> m_libSymbols;
|
||||
|
||||
+19
-19
@@ -347,19 +347,17 @@ void SCH_SHEET::SwapData( SCH_ITEM* aItem )
|
||||
void SCH_SHEET::SetFields( const std::vector<SCH_FIELD>& aFields )
|
||||
{
|
||||
m_fields = aFields;
|
||||
int next_id = SHEET_MANDATORY_FIELDS;
|
||||
|
||||
for( int ii = 0; ii < int( m_fields.size() ); )
|
||||
{
|
||||
if( m_fields[ii].GetId() < 0 || m_fields[ii].GetId() >= ssize_t( m_fields.size() ) )
|
||||
m_fields[ii].SetId( next_id++ );
|
||||
// Ensure that mandatory fields are at the beginning
|
||||
std::sort( m_fields.begin(), m_fields.end(),
|
||||
[]( const SCH_FIELD& a, const SCH_FIELD& b )
|
||||
{
|
||||
return a.GetId() < b.GetId();
|
||||
} );
|
||||
|
||||
if( m_fields[ii].GetId() != ii )
|
||||
std::swap( m_fields[ii], m_fields[m_fields[ii].GetId()]);
|
||||
|
||||
if( m_fields[ii].GetId() == ii )
|
||||
++ii;
|
||||
}
|
||||
// After mandatory fields, the rest should be sequential user fields
|
||||
for( int ii = SHEET_MANDATORY_FIELDS; ii < static_cast<int>( m_fields.size() ); ++ii )
|
||||
m_fields[ii].SetId( ii );
|
||||
|
||||
// Make sure that we get the UNIX variant of the file path
|
||||
SetFileName( m_fields[SHEETFILENAME].GetText() );
|
||||
@@ -648,14 +646,16 @@ void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool /* aManual */ )
|
||||
|
||||
void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
aCount = 7;
|
||||
aLayers[0] = LAYER_HIERLABEL;
|
||||
aLayers[1] = LAYER_SHEETNAME;
|
||||
aLayers[2] = LAYER_SHEETFILENAME;
|
||||
aLayers[3] = LAYER_SHEETFIELDS;
|
||||
aLayers[4] = LAYER_SHEET;
|
||||
aLayers[5] = LAYER_SHEET_BACKGROUND;
|
||||
aLayers[6] = LAYER_SELECTION_SHADOWS;
|
||||
aCount = 8;
|
||||
aLayers[0] = LAYER_DANGLING; // Sheet pins are drawn by their parent sheet, so the
|
||||
// parent needs to draw to LAYER_DANGLING
|
||||
aLayers[1] = LAYER_HIERLABEL;
|
||||
aLayers[2] = LAYER_SHEETNAME;
|
||||
aLayers[3] = LAYER_SHEETFILENAME;
|
||||
aLayers[4] = LAYER_SHEETFIELDS;
|
||||
aLayers[5] = LAYER_SHEET;
|
||||
aLayers[6] = LAYER_SHEET_BACKGROUND;
|
||||
aLayers[7] = LAYER_SELECTION_SHADOWS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1045,15 +1045,15 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForPath( const SCH_SHEET_PATH* aPath )
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForScreen( const SCH_SCREEN* aScreen )
|
||||
SCH_SHEET_PATH SCH_SHEET_LIST::FindSheetForScreen( const SCH_SCREEN* aScreen )
|
||||
{
|
||||
for( SCH_SHEET_PATH& sheetpath : *this )
|
||||
{
|
||||
if( sheetpath.LastScreen() == aScreen )
|
||||
return &sheetpath;
|
||||
return sheetpath;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return SCH_SHEET_PATH();
|
||||
}
|
||||
|
||||
|
||||
@@ -1302,3 +1302,14 @@ int SCH_SHEET_LIST::GetLastVirtualPageNumber() const
|
||||
return lastVirtualPageNumber;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_LIST::HasPath( const KIID_PATH& aPath ) const
|
||||
{
|
||||
for( const SCH_SHEET_PATH& path : *this )
|
||||
{
|
||||
if( path.Path() == aPath )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -573,10 +573,10 @@ public:
|
||||
SCH_SHEET_PATH* FindSheetForPath( const SCH_SHEET_PATH* aPath );
|
||||
|
||||
/**
|
||||
* Return a pointer to the first #SCH_SHEET_PATH object (not necessarily the only one) using
|
||||
* a particular screen.
|
||||
* Return the first #SCH_SHEET_PATH object (not necessarily the only one) using a particular
|
||||
* screen.
|
||||
*/
|
||||
SCH_SHEET_PATH* FindSheetForScreen( const SCH_SCREEN* aScreen );
|
||||
SCH_SHEET_PATH FindSheetForScreen( const SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Return a #SCH_SHEET_LIST with a copy of all the #SCH_SHEET_PATH using a particular screen.
|
||||
@@ -672,6 +672,8 @@ public:
|
||||
|
||||
void RemoveSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
|
||||
|
||||
bool HasPath( const KIID_PATH& aPath ) const;
|
||||
|
||||
private:
|
||||
SCH_SHEET_PATH m_currentSheetPath;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user