Compare commits
245 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54253ba8a3 | |||
| ddd533ee9c | |||
| 46133c76b2 | |||
| d4e9ace354 | |||
| 88dd914a31 | |||
| ca68d32a47 | |||
| 3c86dbe28c | |||
| 400bac868e | |||
| 7e765db562 | |||
| a993e179ab | |||
| 5253ff35f1 | |||
| cba0ec4de5 | |||
| ed0354dd06 | |||
| d255d6aeeb | |||
| 94abd0ee79 | |||
| 6a3cd9c0d7 | |||
| 81be16d058 | |||
| 3efdc963d8 | |||
| a4525bf88c | |||
| d7c7ff3dad | |||
| 987aec3fd6 | |||
| d5661c24bd | |||
| c3ee1111f9 | |||
| 9c1509b8c3 | |||
| 1020cdd7a6 | |||
| bff2f53996 | |||
| d5bf831f60 | |||
| 6c423be36f | |||
| 3c33e2c046 | |||
| 253ff41819 | |||
| 24d95b410d | |||
| db5aacf984 | |||
| 111a56dd8a | |||
| d1d0d61b4f | |||
| 640f279abe | |||
| 874191bd8d | |||
| 2066af9f28 | |||
| ef7b3c1715 | |||
| 6eb96851f9 | |||
| a42ef9de77 | |||
| fb23fe3084 | |||
| 57f0150a23 | |||
| 9b31a986b6 | |||
| 8fa46a1f9e | |||
| d805f5ceff | |||
| b4242e562d | |||
| 2effa810c1 | |||
| a78af6acc2 | |||
| fc084c84f4 | |||
| a846ab7443 | |||
| 9f53272d34 | |||
| aa53aac7be | |||
| db984fcad9 | |||
| 607713cdae | |||
| 7de0a61de3 | |||
| 1838460c38 | |||
| 3a4e00d0f5 | |||
| a9bd82150b | |||
| de5c3733d0 | |||
| 3ff662e710 | |||
| 669571799b | |||
| 81a98fc0d3 | |||
| f10157fb24 | |||
| 7d94508257 | |||
| 262a8607d0 | |||
| fd44a9552a | |||
| 8e2d6d8cb2 | |||
| 13b73cb51f | |||
| 5f730ba360 | |||
| 79dbbadf2d | |||
| cd150c265f | |||
| 7a50a91eab | |||
| b5561ee5d4 | |||
| 8dcda7fe35 | |||
| 9b679cc8dd | |||
| 674f8cc936 | |||
| 51a43ef45b | |||
| acc55d588a | |||
| d4990b30e9 | |||
| 920a8d34ea | |||
| c8dfcf4b39 | |||
| aa93632707 | |||
| cc55262cbc | |||
| f887b62a85 | |||
| 5b20781080 | |||
| 98a1efc123 | |||
| a628c1f5e4 | |||
| 6588e8fabf | |||
| 52d349538e | |||
| aad2b3a492 | |||
| 93180abf7b | |||
| e30c8d8949 | |||
| a90c5d71ad | |||
| 54f56813a5 | |||
| 8d29229c0f | |||
| dc498128be | |||
| 6d5b71b663 | |||
| 122fcbb40b | |||
| 4fc28bb65e | |||
| a7f92a3187 | |||
| dd16b68623 | |||
| df24d87245 | |||
| 6000e04c78 | |||
| 87181a8ecb | |||
| 7d0731754c | |||
| 962e63ab52 | |||
| 9f4b43f3f2 | |||
| ef722200c9 | |||
| 784f47fa86 | |||
| 90cdc28707 | |||
| 62844b321c | |||
| 8a6c7f5538 | |||
| 8c3eeb5201 | |||
| 5998fabadd | |||
| 97be02356f | |||
| e59867d479 | |||
| 8e1bcaed37 | |||
| f3c864c178 | |||
| 947923509e | |||
| 4e0f77c0f4 | |||
| 6f0505f19c | |||
| 98bf66cb25 | |||
| f9b641b24d | |||
| 3894314ab2 | |||
| edc9d38680 | |||
| ce5f72207e | |||
| ff8d009022 | |||
| 589c33ec05 | |||
| 28fe5b0df5 | |||
| 5a3dfe598f | |||
| d0c132ccd4 | |||
| 826541548c | |||
| e3adc76a72 | |||
| 2ae2d7ee1a | |||
| e28b50e8d6 | |||
| 9c78d86f58 | |||
| a6b23a751e | |||
| 34d5f1f9fe | |||
| 43ad15dc0e | |||
| d20147c79f | |||
| 7cc014cf9e | |||
| 9e735fc940 | |||
| 4fecf6c50d | |||
| c31c14e46b | |||
| 349dbb98a6 | |||
| f4fa5bb0fc | |||
| 4cdf75dc72 | |||
| 53eb39e033 | |||
| 57ae43890c | |||
| 1c59574cbf | |||
| 7ddef03aba | |||
| 4258738b89 | |||
| 594864e117 | |||
| a5698ce480 | |||
| 1a2c9011e6 | |||
| 600ac72a3d | |||
| 1118eed080 | |||
| e42c66bd0e | |||
| ff8fae377c | |||
| 6931252ed9 | |||
| ef8e549d86 | |||
| a5470029a8 | |||
| 13fb23d59d | |||
| a3197578d6 | |||
| ebc14b35f5 | |||
| b0235a2805 | |||
| d0069e0e1d | |||
| 878f136951 | |||
| bf364bf74c | |||
| 03c2850c59 | |||
| 4eddc7131d | |||
| 14be1935e8 | |||
| f08029354a | |||
| c18600b67f | |||
| 2acc0a6844 | |||
| 8ffba3a52f | |||
| 0fb2f35b10 | |||
| f8270b9cec | |||
| d3311ee231 | |||
| 21eb2c8dad | |||
| a11fd7a792 | |||
| a2ad9f8b10 | |||
| 9a0e2f3395 | |||
| cd9196ddb9 | |||
| c10fe673a2 | |||
| 105f8a1720 | |||
| 050f47daf1 | |||
| 683abd2029 | |||
| d08f937932 | |||
| 2f51742311 | |||
| b926d2f0bd | |||
| 89d1d36e79 | |||
| 999cd8cd11 | |||
| fd8b281731 | |||
| d8481b4528 | |||
| 6d93fa046c | |||
| c75672fd44 | |||
| 5484796745 | |||
| 4ed45e0515 | |||
| 9956c04526 | |||
| b74af71312 | |||
| 44640422f2 | |||
| be91f378ac | |||
| bdca18cc9f | |||
| 76cb15f545 | |||
| 4f9e754a51 | |||
| 955774a91a | |||
| e8a9485d5e | |||
| 0736c141b9 | |||
| 204549f55b | |||
| 82a5f307ed | |||
| 7a4650a1a9 | |||
| 518980d9ed | |||
| 5cc1e2e42d | |||
| c599385c8b | |||
| 1d37d3fdf7 | |||
| f3db64af05 | |||
| 3217372720 | |||
| 7a50654f3b | |||
| 9893921d76 | |||
| 5574f35473 | |||
| fd42e493c0 | |||
| 7843e6a709 | |||
| 4c129ec208 | |||
| 1bf44561da | |||
| ad612864ce | |||
| 1707436cad | |||
| b011d508f8 | |||
| f67a477f65 | |||
| 3573b97bfc | |||
| 37a42a3fb7 | |||
| 2d13ddc70c | |||
| 0be01f3c24 | |||
| eb492724c7 | |||
| 3b05d03220 | |||
| 4c04233a20 | |||
| 2b6d2fc117 | |||
| f64ef39687 | |||
| c1fb392333 | |||
| de60d5467c | |||
| c1274e24b0 | |||
| 7f593d3999 | |||
| 3a6a6097a7 | |||
| 69989e4e64 | |||
| 88999b34d3 |
@@ -36,6 +36,7 @@
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx/log.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
@@ -92,8 +93,7 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
|
||||
|
||||
if( PgmOrNull() )
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
ReloadColorSettings();
|
||||
|
||||
m_boardPos = VECTOR2I();
|
||||
m_boardSize = VECTOR2I();
|
||||
@@ -208,6 +208,15 @@ BOARD_ADAPTER::~BOARD_ADAPTER()
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::ReloadColorSettings() noexcept
|
||||
{
|
||||
wxASSERT( PgmOrNull() );
|
||||
|
||||
PCBNEW_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings( settings->m_ColorTheme );
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
|
||||
@@ -251,7 +260,8 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
|
||||
case B_Cu:
|
||||
case F_Cu:
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic;
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic
|
||||
|| m_board->IsFootprintHolder();
|
||||
|
||||
default:
|
||||
// the layer is an internal copper layer, used the visibility
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
|
||||
const BOARD* GetBoard() const noexcept { return m_board; }
|
||||
|
||||
void SetColorSettings( COLOR_SETTINGS* aSettings ) noexcept { m_colors = aSettings; }
|
||||
void ReloadColorSettings() noexcept;
|
||||
|
||||
/**
|
||||
* Function to be called by the render when it need to reload the settings for the board.
|
||||
|
||||
@@ -91,7 +91,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
callback_gal.SetIsFill( font->IsOutline() );
|
||||
callback_gal.SetIsStroke( font->IsStroke() );
|
||||
callback_gal.SetLineWidth( attrs.m_StrokeWidth );
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs );
|
||||
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
int margin = attrs.m_StrokeWidth * 1.5 +
|
||||
@@ -137,7 +137,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
|
||||
attrs.m_Angle = aText->GetDrawRotation();
|
||||
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
#include <board.h>
|
||||
#include <reporter.h>
|
||||
#include <gl_context_mgr.h>
|
||||
@@ -140,7 +141,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
// long calculation time)
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
wxASSERT( a3DCachePointer != nullptr );
|
||||
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
|
||||
@@ -303,7 +304,7 @@ void EDA_3D_CANVAS::ReloadRequest( BOARD* aBoard , S3D_CACHE* aCachePointer )
|
||||
if( aBoard != nullptr )
|
||||
m_boardAdapter.SetBoard( aBoard );
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
if( m_3d_render )
|
||||
m_3d_render->ReloadRequest();
|
||||
@@ -531,13 +532,11 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
render_pivot( curtime_delta_s, scale );
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_render3dmousePivot )
|
||||
if( m_render3dmousePivot && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
|
||||
render3dmousePivot( scale );
|
||||
}
|
||||
#endif
|
||||
|
||||
// "Swaps the double-buffer of this window, making the back-buffer the
|
||||
// front-buffer and vice versa, so that the output of the previous OpenGL
|
||||
|
||||
@@ -178,8 +178,6 @@ public:
|
||||
*/
|
||||
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Get a value indicating whether to render the 3dmouse pivot.
|
||||
*/
|
||||
@@ -209,7 +207,6 @@ public:
|
||||
{
|
||||
m_3dmousePivotPos = aPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -278,14 +275,12 @@ private:
|
||||
*/
|
||||
void render_pivot( float t, float aScale );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Render the 3dmouse pivot cursor.
|
||||
*
|
||||
* @param aScale scale to apply on the cursor.
|
||||
*/
|
||||
void render3dmousePivot( float aScale );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return true if OpenGL initialization succeeded.
|
||||
@@ -331,10 +326,8 @@ private:
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
|
||||
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
||||
@@ -120,7 +120,6 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
|
||||
}
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
{
|
||||
wxASSERT( aScale >= 0.0f );
|
||||
@@ -160,4 +159,3 @@ void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
"nl_3d_viewer_plugin_impl.cpp"
|
||||
@@ -23,9 +22,4 @@ if( KICAD_USE_3DCONNEXION )
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
else()
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
)
|
||||
endif(KICAD_USE_3DCONNEXION)
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
*/
|
||||
|
||||
#include "nl_3d_viewer_plugin.h"
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) :
|
||||
m_impl( new NL_3D_VIEWER_PLUGIN_IMPL( aViewport ) )
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
|
||||
}
|
||||
|
||||
|
||||
@@ -38,22 +38,6 @@ NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
m_impl->SetFocus( focus );
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) : m_impl( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <3d_viewer/tools/eda_3d_actions.h>
|
||||
#include <3d_viewer/tools/eda_3d_controller.h>
|
||||
#include <3d_viewer/tools/eda_3d_conditions.h>
|
||||
#include <advanced_config.h>
|
||||
#include <bitmaps.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
@@ -56,9 +57,7 @@
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include <3d_navlib/nl_3d_viewer_plugin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flag to enable 3D viewer main frame window debug tracing.
|
||||
@@ -166,16 +165,18 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
m_canvas->SetInfoBar( m_infoBar );
|
||||
m_canvas->SetStatusBar( status_bar );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
try
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
try
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
|
||||
// in order to receive mouse events. Otherwise, the user has to click somewhere on
|
||||
@@ -193,12 +194,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
|
||||
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
|
||||
{
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
delete m_spaceMouse;
|
||||
}
|
||||
#endif
|
||||
delete m_spaceMouse;
|
||||
|
||||
Prj().GetProjectFile().m_Viewports3D = GetUserViewports();
|
||||
|
||||
@@ -334,12 +330,11 @@ void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||
{
|
||||
KIWAY_PLAYER::handleIconizeEvent( aEvent );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized()
|
||||
&& ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse->SetFocus( false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -655,12 +650,8 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
if( m_spaceMouse != nullptr && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||
}
|
||||
#endif
|
||||
|
||||
aEvent.Skip(); // required under wxMAC
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ target_link_libraries( 3d-viewer
|
||||
|
||||
add_subdirectory( 3d_cache )
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
endif()
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
|
||||
@@ -56,14 +56,16 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_userUnits = aFrame->GetUserUnits();
|
||||
|
||||
m_dummyBoard = new BOARD();
|
||||
|
||||
m_dummyBoard->SetProject( &aFrame->Prj(), true );
|
||||
|
||||
// This board will only be used to hold a footprint for viewing
|
||||
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
|
||||
|
||||
BOARD_DESIGN_SETTINGS parent_bds = aFrame->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS& dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( parent_bds.GetBoardThickness() );
|
||||
dummy_bds.SetEnabledLayers( LSET::FrontMask() | LSET::BackMask() );
|
||||
BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
dummy_board_stackup.RemoveAll();
|
||||
dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.2" )
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.3" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -620,12 +620,9 @@ target_link_libraries( pcbcommon PUBLIC
|
||||
threadpool
|
||||
)
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
endif()
|
||||
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
|
||||
add_dependencies( pcbcommon delaunator )
|
||||
|
||||
|
||||
@@ -62,6 +62,16 @@ namespace AC_STACK
|
||||
namespace AC_KEYS
|
||||
{
|
||||
|
||||
/**
|
||||
* Should the schematic use the new incremental connectivity algorithm
|
||||
*/
|
||||
static const wxChar IncrementalConnectivity[] = wxT( "IncrementalConnectivity" );
|
||||
|
||||
/**
|
||||
* Decide whether to attempt usage of the 3DConnexion mouse
|
||||
*/
|
||||
static const wxChar Use3DConnexionDriver[] = wxT( "3DConnexionDriver" );
|
||||
|
||||
/**
|
||||
* When filling zones, we add an extra amount of clearance to each zone to ensure that rounding
|
||||
* errors do not overrun minimum clearance distances. This is the extra in mm.
|
||||
@@ -321,6 +331,15 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_UseClipper2 = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
// spacemouse is largely stable on Windows
|
||||
m_Use3DConnexionDriver = true;
|
||||
#else
|
||||
m_Use3DConnexionDriver = false;
|
||||
#endif
|
||||
|
||||
m_IncrementalConnectivity = false;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@@ -463,6 +482,12 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::UseClipper2,
|
||||
&m_UseClipper2, m_UseClipper2 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::Use3DConnexionDriver,
|
||||
&m_Use3DConnexionDriver, m_Use3DConnexionDriver ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::IncrementalConnectivity,
|
||||
&m_IncrementalConnectivity, m_IncrementalConnectivity ) );
|
||||
|
||||
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
|
||||
+37
-4
@@ -41,7 +41,8 @@ BITMAP_BASE::BITMAP_BASE( const VECTOR2I& pos )
|
||||
m_ppi = 300; // the bitmap definition. the default is 300PPI
|
||||
m_pixelSizeIu = 254000.0 / m_ppi; // a pixel size value OK for bitmaps using 300 PPI
|
||||
// for Eeschema which uses currently 254000PPI
|
||||
m_isMirrored = false;
|
||||
m_isMirroredX = false;
|
||||
m_isMirroredY = false;
|
||||
m_rotation = ANGLE_0;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,8 @@ BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap )
|
||||
m_scale = aSchBitmap.m_scale;
|
||||
m_ppi = aSchBitmap.m_ppi;
|
||||
m_pixelSizeIu = aSchBitmap.m_pixelSizeIu;
|
||||
m_isMirrored = aSchBitmap.m_isMirrored;
|
||||
m_isMirroredX = aSchBitmap.m_isMirroredX;
|
||||
m_isMirroredY = aSchBitmap.m_isMirroredY;
|
||||
m_rotation = aSchBitmap.m_rotation;
|
||||
|
||||
m_image = nullptr;
|
||||
@@ -115,7 +117,8 @@ void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
|
||||
m_scale = aItem->m_scale;
|
||||
m_ppi = aItem->m_ppi;
|
||||
m_pixelSizeIu = aItem->m_pixelSizeIu;
|
||||
m_isMirrored = aItem->m_isMirrored;
|
||||
m_isMirroredX = aItem->m_isMirroredX;
|
||||
m_isMirroredY = aItem->m_isMirroredY;
|
||||
m_rotation = aItem->m_rotation;
|
||||
}
|
||||
|
||||
@@ -400,8 +403,25 @@ void BITMAP_BASE::Mirror( bool aVertically )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Mirror() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Mirror( not aVertically );
|
||||
m_isMirrored = !m_isMirrored;
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
if( aVertically )
|
||||
m_isMirroredY = !m_isMirroredY;
|
||||
else
|
||||
m_isMirroredX = !m_isMirroredX;
|
||||
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
}
|
||||
@@ -411,7 +431,20 @@ void BITMAP_BASE::Rotate( bool aRotateCCW )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Rotate90() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Rotate90( aRotateCCW );
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
m_rotation += ( aRotateCCW ? -ANGLE_90 : ANGLE_90 );
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
|
||||
+54
-31
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -67,10 +67,6 @@ public:
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( DIALOG_SHIM, wxDialog )
|
||||
// If dialog has a grid and the grid has an active cell editor
|
||||
// Esc key closes cell editor, otherwise Esc key closes the dialog.
|
||||
EVT_GRID_EDITOR_SHOWN( DIALOG_SHIM::OnGridEditorShown )
|
||||
EVT_GRID_EDITOR_HIDDEN( DIALOG_SHIM::OnGridEditorHidden )
|
||||
EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -325,30 +321,38 @@ bool DIALOG_SHIM::Enable( bool enable )
|
||||
// Recursive descent doing a SelectAll() in wxTextCtrls.
|
||||
// MacOS User Interface Guidelines state that when tabbing to a text control all its
|
||||
// text should be selected. Since wxWidgets fails to implement this, we do it here.
|
||||
static void selectAllInTextCtrls( wxWindowList& children )
|
||||
void DIALOG_SHIM::selectAllInTextCtrls( wxWindowList& children )
|
||||
{
|
||||
for( wxWindow* child : children )
|
||||
{
|
||||
if( wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
textCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
// We don't currently run this on GTK because some window managers don't hide the
|
||||
// selection in non-active controls, and other window managers do the selection
|
||||
// automatically anyway.
|
||||
#if defined( __WXMAC__ ) || defined( __WXMSW__ )
|
||||
if( !childTextCtrl->GetStringSelection().IsEmpty() )
|
||||
if( !textCtrl->GetStringSelection().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
}
|
||||
else
|
||||
else if( textCtrl->IsEditable() )
|
||||
{
|
||||
childTextCtrl->SelectAll();
|
||||
textCtrl->SelectAll();
|
||||
}
|
||||
#else
|
||||
ignore_unused( childTextCtrl );
|
||||
ignore_unused( textCtrl );
|
||||
#endif
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
scintilla->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
if( !scintilla->GetSelectedText().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
@@ -533,11 +537,6 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
const int id = aEvent.GetId();
|
||||
|
||||
// If we are pressing a button to exit, we need to enable the escapeID
|
||||
// otherwise the dialog does not process cancel
|
||||
if( id == wxID_CANCEL )
|
||||
SetEscapeId( wxID_ANY );
|
||||
|
||||
if( IsQuasiModal() )
|
||||
{
|
||||
if( id == GetAffirmativeId() )
|
||||
@@ -555,7 +554,7 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
ignore_unused( TransferDataFromWindow() );
|
||||
}
|
||||
}
|
||||
else if( id == GetEscapeId() || (id == wxID_CANCEL && GetEscapeId() == wxID_ANY) )
|
||||
else if( id == wxID_CANCEL )
|
||||
{
|
||||
EndQuasiModal( wxID_CANCEL );
|
||||
}
|
||||
@@ -572,6 +571,19 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::onChildSetFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
// When setting focus to a text control reset the before-edit value.
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
{
|
||||
if( aEvt.GetKeyCode() == 'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
|
||||
@@ -626,25 +638,36 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( aEvt.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
wxObject* eventSource = aEvt.GetEventObject();
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( textCtrl->GetValue() != m_beforeEditValues[ textCtrl ] )
|
||||
{
|
||||
textCtrl->SetValue( m_beforeEditValues[ textCtrl ] );
|
||||
textCtrl->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( scintilla->GetText() != m_beforeEditValues[ scintilla ] )
|
||||
{
|
||||
scintilla->SetText( m_beforeEditValues[ scintilla ] );
|
||||
scintilla->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aEvt.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorShown( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_NONE );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorHidden( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_ANY );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
static void recursiveDescent( wxSizer* aSizer, std::map<int, wxString>& aLabels )
|
||||
{
|
||||
wxStdDialogButtonSizer* sdbSizer = dynamic_cast<wxStdDialogButtonSizer*>( aSizer );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -105,10 +105,7 @@ void DIALOG_ASSIGN_NETCLASS::onPatternText( wxCommandEvent& aEvent )
|
||||
|
||||
for( const wxString& net : m_netCandidates )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
{
|
||||
m_matchingNets->Report( net );
|
||||
matchingNetNames.push_back( net );
|
||||
|
||||
@@ -396,12 +396,12 @@ void DIALOG_COLOR_PICKER::drawRGBPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize/2;
|
||||
@@ -466,12 +466,12 @@ void DIALOG_COLOR_PICKER::drawHSVPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize / 2;
|
||||
@@ -701,11 +701,13 @@ void DIALOG_COLOR_PICKER::onHSVMouseDrag( wxMouseEvent& event )
|
||||
|
||||
void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event )
|
||||
{
|
||||
m_newColor4D.SetFromHexString( m_colorValue->GetValue() );
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
if( m_newColor4D.SetFromHexString( m_colorValue->GetValue() ) )
|
||||
{
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
|
||||
SetEditVals( HEX_CHANGED, true );
|
||||
drawAll();
|
||||
SetEditVals( HEX_CHANGED, false );
|
||||
drawAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -708,10 +708,7 @@ void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
|
||||
for( const wxString& net : m_netNames )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
m_matchingNets->Report( net );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -118,8 +118,12 @@ void DS_DRAW_ITEM_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
|
||||
break;
|
||||
|
||||
case DS_DATA_ITEM::DS_TEXT:
|
||||
aList.emplace_back( _( "Text" ), static_cast<DS_DRAW_ITEM_TEXT*>( this )->GetShownText() );
|
||||
{
|
||||
DS_DRAW_ITEM_TEXT* textItem = static_cast<DS_DRAW_ITEM_TEXT*>( this );
|
||||
// Don't use GetShownText(); we want to see the variable references here
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, textItem->GetText() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case DS_DATA_ITEM::DS_POLYPOLYGON:
|
||||
aList.emplace_back( _( "Imported Shape" ), wxEmptyString );
|
||||
@@ -190,7 +194,7 @@ bool DS_DRAW_ITEM_TEXT::HitTest( const BOX2I& aRect, bool aContains, int aAccura
|
||||
|
||||
wxString DS_DRAW_ITEM_TEXT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "Text '%s'" ), GetShownText() );
|
||||
return wxString::Format( _( "Text '%s'" ), KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
|
||||
m_renderSettings.GetDefaultPenWidth() );
|
||||
|
||||
font->Draw( m_gal, aItem->GetShownText(), aItem->GetTextPos(), attrs );
|
||||
font->Draw( m_gal, aItem->GetShownText( true ), aItem->GetTextPos(), attrs );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <widgets/wx_aui_art_providers.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <wx/app.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/display.h>
|
||||
@@ -403,6 +404,8 @@ void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAM
|
||||
enableRes = true;
|
||||
else if( textEntry && isPaste && textEntry->CanPaste() )
|
||||
enableRes = true;
|
||||
else if( dynamic_cast<WX_GRID*>( focus ) )
|
||||
enableRes = false; // Must disable menu in order to get command as CharHook event
|
||||
}
|
||||
|
||||
aEvent.Enable( enableRes );
|
||||
|
||||
@@ -144,6 +144,10 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
|
||||
wxFileName currentFileName( fullfilename );
|
||||
|
||||
// Use wxWidgets to resolve any "." and ".." in the path
|
||||
currentFileName.MakeAbsolute();
|
||||
fullfilename = currentFileName.GetFullPath();
|
||||
|
||||
wxString file_ext = currentFileName.GetExt();
|
||||
|
||||
if( file_ext.Lower() == wxT( "pdf" ) )
|
||||
|
||||
+16
-29
@@ -27,6 +27,7 @@
|
||||
#include <bitmaps.h>
|
||||
#include <confirm.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <file_history.h>
|
||||
@@ -741,21 +742,21 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
||||
void EDA_DRAW_FRAME::AppendMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::ClearMsgPanel()
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->EraseMsgBox();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
@@ -768,10 +769,9 @@ void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
}
|
||||
@@ -842,26 +842,15 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
// Not all classes derived from EDA_DRAW_FRAME can save the canvas type, because some
|
||||
// have a fixed type, or do not have a option to set the canvas type (they inherit from
|
||||
// a parent frame)
|
||||
FRAME_T allowed_frames[] =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
static std::vector<FRAME_T> s_allowedFrames =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
|
||||
bool allow_save = false;
|
||||
|
||||
for( unsigned ii = 0; ii < arrayDim( allowed_frames ); ii++ )
|
||||
{
|
||||
if( m_ident == allowed_frames[ii] )
|
||||
{
|
||||
allow_save = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !allow_save )
|
||||
if( !alg::contains( s_allowedFrames, m_ident ) )
|
||||
return false;
|
||||
|
||||
if( aCanvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
|
||||
@@ -871,9 +860,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
return false;
|
||||
}
|
||||
|
||||
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
|
||||
|
||||
if( cfg )
|
||||
if( APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings() )
|
||||
cfg->m_Graphics.canvas_type = static_cast<int>( aCanvasType );
|
||||
|
||||
return false;
|
||||
@@ -883,7 +870,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
@@ -897,7 +884,7 @@ VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) con
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestHalfGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
|
||||
@@ -412,6 +412,30 @@ bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm, int& aMatchersTriggered,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start >= 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::StartsWith( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
wxString const& EDA_COMBINED_MATCHER::GetPattern() const
|
||||
{
|
||||
return m_pattern;
|
||||
|
||||
+23
-11
@@ -37,6 +37,7 @@
|
||||
#include <callback_gal.h>
|
||||
#include <eda_text.h> // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF...
|
||||
#include <gal/color4d.h> // for COLOR4D, COLOR4D::BLACK
|
||||
#include <font/glyph.h>
|
||||
#include <gr_text.h>
|
||||
#include <string_utils.h> // for UnescapeString
|
||||
#include <math/util.h> // for KiROUND
|
||||
@@ -117,8 +118,10 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -149,8 +152,10 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -391,7 +396,12 @@ void EDA_TEXT::Offset( const VECTOR2I& aOffset )
|
||||
m_pos += aOffset;
|
||||
|
||||
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache )
|
||||
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( aOffset );
|
||||
{
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
outline->Move( aOffset );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = false;
|
||||
}
|
||||
@@ -467,7 +477,8 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
|
||||
|
||||
attrs.m_Angle = resolvedAngle;
|
||||
|
||||
font->GetLinesAsGlyphs( &m_render_cache, GetShownText(), GetDrawPos() + aOffset, attrs );
|
||||
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
|
||||
attrs );
|
||||
m_render_cache_angle = resolvedAngle;
|
||||
m_render_cache_text = forResolvedText;
|
||||
m_render_cache_offset = aOffset;
|
||||
@@ -514,7 +525,7 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
|
||||
BOX2I bbox;
|
||||
wxArrayString strings;
|
||||
wxString text = GetShownText();
|
||||
wxString text = GetShownText( true );
|
||||
int thickness = GetEffectiveTextPenWidth();
|
||||
|
||||
if( IsMultilineAllowed() )
|
||||
@@ -652,7 +663,7 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
{
|
||||
std::vector<VECTOR2I> positions;
|
||||
wxArrayString strings;
|
||||
wxStringSplit( GetShownText(), strings, '\n' );
|
||||
wxStringSplit( GetShownText( true ), strings, '\n' );
|
||||
|
||||
positions.reserve( strings.Count() );
|
||||
|
||||
@@ -663,7 +674,8 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
}
|
||||
else
|
||||
{
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText(), GetDrawPos() );
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText( true ),
|
||||
GetDrawPos() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +896,7 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( triShape );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), attrs );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -901,7 +913,7 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( aPoly.Clone() );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), attrs );
|
||||
}
|
||||
|
||||
return shape;
|
||||
|
||||
+139
-44
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Font abstract base class
|
||||
*
|
||||
@@ -35,6 +35,7 @@
|
||||
// The "official" name of the building Kicad stroke font (always existing)
|
||||
#include <font/kicad_font_name.h>
|
||||
#include "macros.h"
|
||||
#include "wx/tokenzr.h"
|
||||
|
||||
|
||||
// markup_parser.h includes pegtl.hpp which includes windows.h... which leaks #define DrawText
|
||||
@@ -187,10 +188,13 @@ void FONT::Draw( KIGFX::GAL* aGal, const wxString& aText, const VECTOR2I& aPosit
|
||||
*/
|
||||
VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const std::unique_ptr<MARKUP::NODE>& aNode, const VECTOR2I& aPosition,
|
||||
const KIFONT::FONT* aFont, const VECTOR2I& aSize, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin, TEXT_STYLE_FLAGS aTextStyle )
|
||||
const KIFONT::FONT* aFont, const VECTOR2I& aSize, const VECTOR2I& aOffset,
|
||||
const EDA_ANGLE& aAngle, bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle )
|
||||
{
|
||||
VECTOR2I nextPosition = aPosition;
|
||||
VECTOR2I nextPosition = aPosition + aOffset;
|
||||
bool drawUnderline = false;
|
||||
bool drawOverbar = false;
|
||||
|
||||
if( aNode )
|
||||
{
|
||||
@@ -199,30 +203,78 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
if( !aNode->is_root() )
|
||||
{
|
||||
if( aNode->isSubscript() )
|
||||
textStyle = TEXT_STYLE::SUBSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUBSCRIPT;
|
||||
else if( aNode->isSuperscript() )
|
||||
textStyle = TEXT_STYLE::SUPERSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUPERSCRIPT;
|
||||
|
||||
if( aNode->isOverbar() )
|
||||
textStyle |= TEXT_STYLE::OVERBAR;
|
||||
drawOverbar = true;
|
||||
|
||||
if( aNode->has_content() )
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
nextPosition = aFont->GetTextAsGlyphs( &bbox, aGlyphs, aNode->asWxString(), aSize,
|
||||
aPosition, aAngle, aMirror, aOrigin,
|
||||
nextPosition, aAngle, aMirror, aOrigin,
|
||||
textStyle );
|
||||
|
||||
if( aBoundingBox )
|
||||
aBoundingBox->Merge( bbox );
|
||||
}
|
||||
}
|
||||
else if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
drawUnderline = true;
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<MARKUP::NODE>& child : aNode->children )
|
||||
{
|
||||
nextPosition = drawMarkup( aBoundingBox, aGlyphs, child, nextPosition, aFont, aSize,
|
||||
aAngle, aMirror, aOrigin, textStyle );
|
||||
VECTOR2I(), aAngle, aMirror, aOrigin, textStyle );
|
||||
}
|
||||
}
|
||||
|
||||
if( drawUnderline )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeUnderlineVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( drawOverbar )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeOverbarVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,13 +284,13 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
|
||||
VECTOR2I FONT::drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aPosition, const VECTOR2I& aSize,
|
||||
const EDA_ANGLE& aAngle, bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
const VECTOR2I& aOffset, const EDA_ANGLE& aAngle, bool aMirror,
|
||||
const VECTOR2I& aOrigin, TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
MARKUP::MARKUP_PARSER markupParser( TO_UTF8( aText ) );
|
||||
std::unique_ptr<MARKUP::NODE> root = markupParser.Parse();
|
||||
|
||||
return ::drawMarkup( aBoundingBox, aGlyphs, root, aPosition, this, aSize, aAngle, aMirror,
|
||||
return ::drawMarkup( aBoundingBox, aGlyphs, root, aPosition, this, aSize, aOffset, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
@@ -252,7 +304,13 @@ void FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const wxSt
|
||||
return;
|
||||
|
||||
TEXT_STYLE_FLAGS textStyle = 0;
|
||||
VECTOR2I offset;
|
||||
|
||||
if( !IsOutline() )
|
||||
{
|
||||
offset.x = aGal->GetLineWidth() / 1.52;
|
||||
offset.y = -aGal->GetLineWidth() * 0.052;
|
||||
}
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
@@ -261,7 +319,7 @@ void FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const wxSt
|
||||
|
||||
std::vector<std::unique_ptr<GLYPH>> glyphs;
|
||||
|
||||
(void) drawMarkup( aBoundingBox, &glyphs, aText, aPosition, aSize, aAngle, aMirror, aOrigin,
|
||||
(void) drawMarkup( aBoundingBox, &glyphs, aText, aPosition, aSize, offset, aAngle, aMirror, aOrigin,
|
||||
textStyle );
|
||||
|
||||
aGal->DrawGlyphs( glyphs );
|
||||
@@ -281,7 +339,7 @@ VECTOR2I FONT::StringBoundaryLimits( const wxString& aText, const VECTOR2I& aSiz
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, ANGLE_0, false,
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, VECTOR2I(), ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
|
||||
if( IsStroke() )
|
||||
@@ -307,8 +365,8 @@ VECTOR2I FONT::boundingBoxSingleLine( BOX2I* aBBox, const wxString& aText,
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
VECTOR2I extents = drawMarkup( aBBox, nullptr, aText, aPosition, aSize, ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
VECTOR2I extents = drawMarkup( aBBox, nullptr, aText, aPosition, aSize, VECTOR2I(), ANGLE_0,
|
||||
false, VECTOR2I(), textStyle );
|
||||
|
||||
return extents;
|
||||
}
|
||||
@@ -376,20 +434,22 @@ void wordbreakMarkup( std::vector<std::pair<wxString, int>>* aWords,
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxArrayString words;
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxStringTokenizer tokenizer( textRun, " ", wxTOKEN_RET_DELIMS );
|
||||
std::vector<wxString> words;
|
||||
|
||||
wxStringSplit( textRun, words, ' ' );
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
words.emplace_back( tokenizer.GetNextToken() );
|
||||
|
||||
if( textRun.EndsWith( wxS( " " ) ) )
|
||||
words.Add( wxS( " " ) );
|
||||
|
||||
for( size_t ii = 0; ii < words.size(); ++ii )
|
||||
for( const wxString& word : words )
|
||||
{
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, words[ii], aSize, { 0, 0 },
|
||||
wxString chars = word;
|
||||
chars.Trim();
|
||||
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, chars, aSize, { 0, 0 },
|
||||
ANGLE_0, false, { 0, 0 }, textStyle ).x;
|
||||
|
||||
aWords->emplace_back( std::make_pair( words[ii], w ) );
|
||||
aWords->emplace_back( std::make_pair( word, w ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,35 +501,70 @@ void FONT::LinebreakText( wxString& aText, int aColumnWidth, const VECTOR2I& aSi
|
||||
|
||||
for( size_t ii = 0; ii < textLines.Count(); ++ii )
|
||||
{
|
||||
bool virginLine = true;
|
||||
int lineWidth = 0;
|
||||
std::vector<std::pair<wxString, int>> markup;
|
||||
std::vector<std::pair<wxString, int>> words;
|
||||
|
||||
wordbreakMarkup( &words, textLines[ii], aSize, textStyle );
|
||||
wordbreakMarkup( &markup, textLines[ii], aSize, textStyle );
|
||||
|
||||
for( size_t jj = 0; jj < words.size(); /* advance in loop */ )
|
||||
for( const auto& [ run, runWidth ] : markup )
|
||||
{
|
||||
if( virginLine )
|
||||
if( !words.empty() && !words.back().first.EndsWith( ' ' ) )
|
||||
{
|
||||
// First word is always placed, even when wider than columnWidth.
|
||||
aText += words[jj].first;
|
||||
lineWidth += words[jj].second;
|
||||
jj++;
|
||||
|
||||
virginLine = false;
|
||||
}
|
||||
else if( lineWidth + spaceWidth + words[jj].second < aColumnWidth - aThickness )
|
||||
{
|
||||
aText += " " + words[jj].first;
|
||||
lineWidth += spaceWidth + words[jj].second;
|
||||
jj++;
|
||||
words.back().first += run;
|
||||
words.back().second += runWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += '\n';
|
||||
words.emplace_back( std::make_pair( run, runWidth ) );
|
||||
}
|
||||
}
|
||||
|
||||
bool buryMode = false;
|
||||
int lineWidth = 0;
|
||||
wxString pendingSpaces;
|
||||
|
||||
for( const auto& [ word, wordWidth ] : words )
|
||||
{
|
||||
int pendingSpaceWidth = (int) pendingSpaces.Length() * spaceWidth;
|
||||
bool overflow = lineWidth + pendingSpaceWidth + wordWidth > aColumnWidth - aThickness;
|
||||
|
||||
if( overflow && pendingSpaces.Length() > 0 )
|
||||
{
|
||||
aText += '\n';
|
||||
lineWidth = 0;
|
||||
virginLine = true;
|
||||
pendingSpaces = wxEmptyString;
|
||||
pendingSpaceWidth = 0;
|
||||
buryMode = true;
|
||||
}
|
||||
|
||||
if( word == wxS( " " ) )
|
||||
{
|
||||
pendingSpaces += word;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( buryMode )
|
||||
{
|
||||
buryMode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += pendingSpaces;
|
||||
lineWidth += pendingSpaceWidth;
|
||||
}
|
||||
|
||||
if( word.EndsWith( ' ' ) )
|
||||
{
|
||||
aText += word.Left( word.Length() - 1 );
|
||||
pendingSpaces = wxS( " " );
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += word;
|
||||
pendingSpaces = wxEmptyString;
|
||||
}
|
||||
|
||||
lineWidth += wordWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Outline font class
|
||||
*
|
||||
@@ -255,7 +255,7 @@ void OUTLINE_FONT::GetLinesAsGlyphs( std::vector<std::unique_ptr<GLYPH>>* aGlyph
|
||||
|
||||
for( size_t i = 0; i < strings.GetCount(); i++ )
|
||||
{
|
||||
(void) drawMarkup( nullptr, aGlyphs, strings.Item( i ), positions[i], aAttrs.m_Size,
|
||||
(void) drawMarkup( nullptr, aGlyphs, strings.Item( i ), positions[i], aAttrs.m_Size, VECTOR2I(),
|
||||
aAttrs.m_Angle, aAttrs.m_Mirrored, aPosition, textStyle );
|
||||
}
|
||||
}
|
||||
@@ -313,22 +313,6 @@ VECTOR2I OUTLINE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
}
|
||||
|
||||
|
||||
double OUTLINE_FONT::getOverbarOffset( int ascender, int height, int thickness ) const
|
||||
{
|
||||
double thicknessRatio = abs( (double) thickness ) / (double) height;
|
||||
double ascenderRatio = (double) ascender / (double) height;
|
||||
|
||||
if( thicknessRatio < 0.05 )
|
||||
return 0.04;
|
||||
else if( ascenderRatio < 0.78 )
|
||||
return 0.00;
|
||||
else if( ascenderRatio < 0.80 )
|
||||
return -0.03;
|
||||
else
|
||||
return -0.06;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
@@ -338,14 +322,15 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
return getTextAsGlyphsUnlocked( aBBox, aGlyphs, aText, aSize, aPosition, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
VECTOR2D glyphSize = aSize;
|
||||
FT_Face face = m_face;
|
||||
@@ -478,75 +463,9 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
}
|
||||
|
||||
int ascender = abs( face->size->metrics.ascender * GLYPH_SIZE_SCALER );
|
||||
int height = abs( face->size->metrics.height * GLYPH_SIZE_SCALER );
|
||||
int descender = abs( face->size->metrics.descender * GLYPH_SIZE_SCALER );
|
||||
VECTOR2I extents( cursor.x * scaleFactor.x, ( ascender + descender ) * abs( scaleFactor.y ) );
|
||||
|
||||
// Font metrics don't include all descenders and diacriticals, so beef them up just a little.
|
||||
extents.y *= 1.05;
|
||||
|
||||
if( IsOverbar( aTextStyle ) )
|
||||
{
|
||||
std::vector<std::unique_ptr<GLYPH>> underscoreGlyphs;
|
||||
|
||||
getTextAsGlyphsUnlocked( nullptr, &underscoreGlyphs, wxT( "_" ), aSize, { 0, 0 }, ANGLE_0, false,
|
||||
{ 0, 0 }, aTextStyle & ~TEXT_STYLE::OVERBAR );
|
||||
|
||||
OUTLINE_GLYPH* underscoreGlyph = static_cast<OUTLINE_GLYPH*>( underscoreGlyphs[0].get() );
|
||||
BOX2I underscoreBBox;
|
||||
|
||||
for( const VECTOR2I& pt : underscoreGlyph->Outline( 0 ).CPoints() )
|
||||
underscoreBBox.Merge( pt );
|
||||
|
||||
int barThickness = underscoreBBox.GetHeight();
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = barThickness / 2.0;
|
||||
double barOffset = getOverbarOffset( ascender, height, barThickness / scaleFactor.y );
|
||||
|
||||
VECTOR2I topLeft( aPosition );
|
||||
VECTOR2I topRight( aPosition );
|
||||
|
||||
topLeft.y += ascender * scaleFactor.y * ( 1.0 + barOffset );
|
||||
topRight.y = topLeft.y;
|
||||
|
||||
topLeft.x += barTrim;
|
||||
topRight.x += extents.x - barTrim;
|
||||
|
||||
extents.y *= ( 1.0 + barOffset + barOffset );
|
||||
extents.x += barTrim;
|
||||
|
||||
if( IsItalic() )
|
||||
{
|
||||
topLeft.x += aSize.y * ITALIC_TILT;
|
||||
topRight.x += aSize.y * ITALIC_TILT;
|
||||
extents.x += aSize.y * ITALIC_TILT;
|
||||
}
|
||||
|
||||
if( aMirror )
|
||||
{
|
||||
topLeft.x = aOrigin.x - ( topLeft.x - aOrigin.x );
|
||||
topRight.x = aOrigin.x - ( topRight.x - aOrigin.x );
|
||||
}
|
||||
|
||||
if( !aAngle.IsZero() )
|
||||
{
|
||||
RotatePoint( topLeft, aOrigin, aAngle );
|
||||
RotatePoint( topRight, aOrigin, aAngle );
|
||||
}
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
int maxError = KiROUND( barThickness / 48 );
|
||||
SHAPE_POLY_SET poly;
|
||||
|
||||
TransformOvalToPolygon( poly, topLeft, topRight, barThickness, maxError, ERROR_INSIDE );
|
||||
|
||||
std::unique_ptr<OUTLINE_GLYPH> overbarGlyph = std::make_unique<OUTLINE_GLYPH>( poly );
|
||||
aGlyphs->push_back( std::move( overbarGlyph ) );
|
||||
}
|
||||
}
|
||||
|
||||
hb_buffer_destroy( buf );
|
||||
hb_font_destroy( referencedFont );
|
||||
|
||||
@@ -575,7 +494,7 @@ void OUTLINE_FONT::RenderToOpenGLCanvas( KIGFX::OPENGL_GAL& aGal, const wxString
|
||||
unsigned int glyphCount;
|
||||
hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( buf, &glyphCount );
|
||||
hb_glyph_position_t* glyphPos = hb_buffer_get_glyph_positions( buf, &glyphCount );
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* Copyright (C) 2016-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Stroke font class
|
||||
*
|
||||
@@ -44,7 +44,7 @@ using namespace KIFONT;
|
||||
|
||||
|
||||
///< Factor that determines relative vertical position of the overbar.
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.40;
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.23;
|
||||
|
||||
///< Factor that determines relative vertical position of the underline.
|
||||
static constexpr double UNDERLINE_POSITION_FACTOR = -0.16;
|
||||
@@ -128,7 +128,6 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe
|
||||
|
||||
while( aNewStrokeFont[j][i] )
|
||||
{
|
||||
|
||||
if( aNewStrokeFont[j][i] == ' ' && aNewStrokeFont[j][i+1] == 'R' )
|
||||
strokes++;
|
||||
|
||||
@@ -228,9 +227,9 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
{
|
||||
constexpr int TAB_WIDTH = 4;
|
||||
constexpr double INTER_CHAR = 0.2;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.7;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.5;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.3;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.8;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.35;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.15;
|
||||
|
||||
VECTOR2I cursor( aPosition );
|
||||
VECTOR2D glyphSize( aSize );
|
||||
@@ -295,71 +294,16 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
|
||||
glyphExtents *= glyphSize;
|
||||
|
||||
if( tilt > 0.0 )
|
||||
glyphExtents.x -= glyphExtents.y * tilt;
|
||||
|
||||
cursor.x += KiROUND( glyphExtents.x );
|
||||
}
|
||||
|
||||
++char_count;
|
||||
}
|
||||
|
||||
VECTOR2D barOffset( 0.0, 0.0 );
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = glyphSize.x * 0.1;
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::OVERBAR )
|
||||
{
|
||||
barOffset.y = ComputeOverbarVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH overbarGlyph;
|
||||
|
||||
overbarGlyph.AddPoint( barStart );
|
||||
overbarGlyph.AddPoint( barEnd );
|
||||
overbarGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( overbarGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
barOffset.y = ComputeUnderlineVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH underlineGlyph;
|
||||
|
||||
underlineGlyph.AddPoint( barStart );
|
||||
underlineGlyph.AddPoint( barEnd );
|
||||
underlineGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( underlineGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aBBox )
|
||||
{
|
||||
aBBox->SetOrigin( aPosition );
|
||||
aBBox->SetEnd( cursor.x + barOffset.x - KiROUND( glyphSize.x * INTER_CHAR ),
|
||||
cursor.y + std::max( glyphSize.y, barOffset.y * OVERBAR_POSITION_FACTOR ) );
|
||||
aBBox->SetEnd( cursor.x - KiROUND( glyphSize.x * INTER_CHAR ), cursor.y + glyphSize.y );
|
||||
aBBox->Normalize();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,11 @@ void FOOTPRINT_FILTER_IT::increment()
|
||||
candidate.GetLibNickname(),
|
||||
candidate.GetFootprintName(),
|
||||
candidate.GetSearchText() );
|
||||
int matches, position;
|
||||
bool exclude = false;
|
||||
bool exclude = false;
|
||||
|
||||
for( std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : m_filter->m_pattern_filters )
|
||||
{
|
||||
if( !matcher->Find( searchStr.Lower(), matches, position ) )
|
||||
if( !matcher->Find( searchStr.Lower() ) )
|
||||
{
|
||||
exclude = true;
|
||||
break;
|
||||
|
||||
@@ -180,7 +180,7 @@ bool COLOR4D::SetFromHexString( const wxString& aColorString )
|
||||
str.Trim( true );
|
||||
str.Trim( false );
|
||||
|
||||
if( str.length() < 7 || str.GetChar( 0 ) != '#' )
|
||||
if( str.length() < 7 || !str.StartsWith( '#' ) )
|
||||
return false;
|
||||
|
||||
unsigned long tmp;
|
||||
|
||||
@@ -1418,21 +1418,23 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, texture_id );
|
||||
|
||||
float texStartX = aBitmap.IsMirrored() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirrored() ? 0.0 : 1.0;
|
||||
float texStartX = aBitmap.IsMirroredX() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirroredX() ? 0.0 : 1.0;
|
||||
float texStartY = aBitmap.IsMirroredY() ? 1.0 : 0.0;
|
||||
float texEndY = aBitmap.IsMirroredY() ? 0.0 : 1.0;
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 0.0 );
|
||||
glTexCoord2f( texStartX, texStartY );
|
||||
glVertex3f( v0.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 0.0 );
|
||||
glTexCoord2f( texEndX, texStartY);
|
||||
glVertex3f( v1.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 1.0 );
|
||||
glTexCoord2f( texEndX, texEndY);
|
||||
glVertex3f( v1.x, v1.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 1.0 );
|
||||
glTexCoord2f( texStartX, texEndY);
|
||||
glVertex3f( v0.x, v1.y, m_layerDepth );
|
||||
glEnd();
|
||||
|
||||
|
||||
+17
-2
@@ -418,9 +418,16 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
if( ev.GetKeyCode() == WXK_RETURN && m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
if( ( ev.GetKeyCode() == WXK_RETURN || ev.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
&& ev.GetModifiers() == wxMOD_NONE
|
||||
&& m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
m_addHandler( dummy );
|
||||
@@ -449,6 +456,14 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
m_grid->ForceRefresh();
|
||||
}
|
||||
}
|
||||
else if( ev.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
m_grid->CancelPendingChanges();
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !handled )
|
||||
ev.Skip( true );
|
||||
|
||||
@@ -27,109 +27,21 @@
|
||||
// conflicts for some defines, at least on Windows
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <ki_exception.h> // THROW_IO_ERROR
|
||||
|
||||
|
||||
|
||||
// These are even more private than class members, and since there is only
|
||||
// one instance of KICAD_CURL ever, these statics are hidden here to simplify the
|
||||
// client (API) header file.
|
||||
static volatile bool s_initialized;
|
||||
|
||||
static std::mutex s_lock; // for s_initialized
|
||||
|
||||
/// At process termination, using atexit() keeps the CURL stuff out of the
|
||||
/// singletops and PGM_BASE.
|
||||
static void at_terminate()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Init()
|
||||
{
|
||||
// We test s_initialized twice in an effort to avoid
|
||||
// unnecessarily locking s_lock. This understands that the common case
|
||||
// will not need to lock.
|
||||
if( !s_initialized )
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( !s_initialized )
|
||||
{
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
}
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Cleanup()
|
||||
{
|
||||
/*
|
||||
|
||||
Calling lock_guard() from a static destructor will typically be bad, since the
|
||||
s_lock may already have been statically destroyed itself leading to a boost
|
||||
exception. (Remember C++ does not provide certain sequencing of static
|
||||
destructor invocation.)
|
||||
|
||||
To prevent this we test s_initialized twice, which ensures that the lock_guard
|
||||
is only instantiated on the first call, which should be from
|
||||
PGM_BASE::destroy() which is first called earlier than static destruction.
|
||||
Then when called again from the actual PGM_BASE::~PGM_BASE() function,
|
||||
lock_guard will not be instantiated because s_initialized will be false.
|
||||
|
||||
*/
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
curl_global_cleanup();
|
||||
|
||||
atexit( &at_terminate );
|
||||
|
||||
s_initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string KICAD_CURL::GetSimpleVersion()
|
||||
{
|
||||
if( !s_initialized )
|
||||
Init();
|
||||
|
||||
curl_version_info_data* info = curl_version_info( CURLVERSION_NOW );
|
||||
|
||||
std::string res;
|
||||
|
||||
if( info->version )
|
||||
{
|
||||
res += "libcurl version: " + std::string( info->version );
|
||||
}
|
||||
|
||||
res += " (";
|
||||
|
||||
if( info->features & CURL_VERSION_SSL )
|
||||
{
|
||||
res += "with SSL - ";
|
||||
res += std::string( info->ssl_version );
|
||||
}
|
||||
else
|
||||
{
|
||||
res += "without SSL";
|
||||
}
|
||||
res += ")";
|
||||
|
||||
return res;
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,12 +112,6 @@ static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double
|
||||
KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
m_headers( nullptr )
|
||||
{
|
||||
// Call KICAD_CURL::Init() from in here every time, but only the first time
|
||||
// will incur any overhead. This strategy ensures that libcurl is never loaded
|
||||
// unless it is needed.
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
m_CURL = curl_easy_init();
|
||||
|
||||
if( !m_CURL )
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*lib_tree_model
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -24,14 +24,12 @@
|
||||
#include <algorithm>
|
||||
#include <eda_pattern_match.h>
|
||||
#include <lib_tree_item.h>
|
||||
#include <utility>
|
||||
#include <pgm_base.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
// Each node gets this lowest score initially, without any matches applied.
|
||||
// Matches will then increase this score depending on match quality. This way,
|
||||
// an empty search string will result in all components being displayed as they
|
||||
// have the minimum score. However, in that case, we avoid expanding all the
|
||||
// Each node gets this lowest score initially, without any matches applied. Matches will then
|
||||
// increase this score. This way, an empty search string will result in all components being
|
||||
// displayed as they have the minimum score. However, in that case, we avoid expanding all the
|
||||
// nodes asd the result is very unspecific.
|
||||
static const unsigned kLowestDefaultScore = 1;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -213,17 +213,11 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
Thaw();
|
||||
}
|
||||
|
||||
LIB_TREE_NODE* bestMatch = ShowResults();
|
||||
const LIB_TREE_NODE* firstMatch = ShowResults();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowPreselect();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowSingleLibrary();
|
||||
|
||||
if( bestMatch )
|
||||
if( firstMatch )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( bestMatch );
|
||||
wxDataViewItem item = ToItem( firstMatch );
|
||||
m_widget->Select( item );
|
||||
|
||||
// Make sure the *parent* item is visible. The selected item is the
|
||||
@@ -619,93 +613,85 @@ bool LIB_TREE_MODEL_ADAPTER::GetAttr( const wxDataViewItem& aItem,
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::Find( LIB_TREE_NODE& aNode,
|
||||
std::function<bool( const LIB_TREE_NODE* )> aFunc,
|
||||
LIB_TREE_NODE** aHighScore )
|
||||
void recursiveDescent( LIB_TREE_NODE& aNode, const std::function<bool( const LIB_TREE_NODE* )>& f )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& node: aNode.m_Children )
|
||||
{
|
||||
if( aFunc( &*node ) )
|
||||
{
|
||||
if( !(*aHighScore) || node->m_Score > (*aHighScore)->m_Score )
|
||||
(*aHighScore) = &*node;
|
||||
}
|
||||
if( !f( node.get() ) )
|
||||
break;
|
||||
|
||||
Find( *node, aFunc, aHighScore );
|
||||
recursiveDescent( *node, f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
const LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
const LIB_TREE_NODE* firstMatch = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
// return leaf nodes with some level of matching
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowPreselect()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
if( !m_preselect_lib_id.IsValid() )
|
||||
return highScore;
|
||||
|
||||
Find( m_tree,
|
||||
[&]( LIB_TREE_NODE const* n )
|
||||
// Expand parents of leaf nodes with some level of matching
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID && ( n->m_Children.empty() ||
|
||||
!m_preselect_unit ) )
|
||||
return m_preselect_lib_id == n->m_LibId;
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT && m_preselect_unit )
|
||||
return m_preselect_lib_id == n->m_Parent->m_LibId &&
|
||||
m_preselect_unit == n->m_Unit;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
&highScore );
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1 )
|
||||
{
|
||||
if( !firstMatch )
|
||||
firstMatch = n;
|
||||
else if( n->m_Score > firstMatch->m_Score )
|
||||
firstMatch = n;
|
||||
|
||||
if( highScore)
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
}
|
||||
|
||||
return true; // keep going to expand ancestors of all found items
|
||||
} );
|
||||
|
||||
// If no matches, find and show the preselect node
|
||||
if( !firstMatch && m_preselect_lib_id.IsValid() )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID
|
||||
&& ( n->m_Children.empty() || !m_preselect_unit )
|
||||
&& m_preselect_lib_id == n->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT
|
||||
&& ( m_preselect_unit && m_preselect_unit == n->m_Unit )
|
||||
&& m_preselect_lib_id == n->m_Parent->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
// If still no matches expand a single library if there is only one
|
||||
if( !firstMatch )
|
||||
{
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID
|
||||
&& n->m_Parent->m_Parent->m_Children.size() == 1 )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return firstMatch;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowSingleLibrary()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID &&
|
||||
n->m_Parent->m_Parent->m_Children.size() == 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <wx/tooltip.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <cli/cli_names.h> // Needed for the pre wx 3.2 cli workaround
|
||||
#include <common.h>
|
||||
#include <config_params.h>
|
||||
#include <confirm.h>
|
||||
@@ -51,6 +52,7 @@
|
||||
#include <eda_draw_frame.h>
|
||||
#include <gestfich.h>
|
||||
#include <id.h>
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
#include <kiplatform/policy.h>
|
||||
#include <lockfile.h>
|
||||
#include <menus_helpers.h>
|
||||
@@ -150,6 +152,8 @@ PGM_BASE::~PGM_BASE()
|
||||
|
||||
void PGM_BASE::Destroy()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_close();
|
||||
#endif
|
||||
@@ -408,6 +412,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||
// In particular, the user cache path is the most likely to be hit by startup code
|
||||
PATHS::EnsureUserPathsExist();
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentryInit();
|
||||
#endif
|
||||
|
||||
@@ -513,10 +513,11 @@ void PDF_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||
|
||||
if( alpha < 0xFF )
|
||||
{
|
||||
float a = 1.0 - ( (float) alpha / 255.0 );
|
||||
r = ( int )( r + ( a * 0xFF ) ) & 0xFF;
|
||||
g = ( int )( g + ( a * 0xFF ) ) & 0xFF;
|
||||
b = ( int )( b + ( a * 0xFF ) ) & 0xFF;
|
||||
float d = alpha / 255.0;
|
||||
float a = 1.0 - d;
|
||||
r = std::min( KiROUND( r * d + ( a * 0xFF ) ), 0xFF );
|
||||
g = std::min( KiROUND( g * d + ( a * 0xFF ) ), 0xFF );
|
||||
b = std::min( KiROUND( b * d + ( a * 0xFF ) ), 0xFF );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,10 +139,10 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL
|
||||
|
||||
int penWidth = std::max( text->GetEffectiveTextPenWidth(), defaultPenWidth );
|
||||
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText(), text->GetTextAngle(),
|
||||
text->GetTextSize(), text->GetHorizJustify(), text->GetVertJustify(),
|
||||
penWidth, text->IsItalic(), text->IsBold(), text->IsMultilineAllowed(),
|
||||
font );
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText( true ),
|
||||
text->GetTextAngle(), text->GetTextSize(), text->GetHorizJustify(),
|
||||
text->GetVertJustify(), penWidth, text->IsItalic(), text->IsBold(),
|
||||
text->IsMultilineAllowed(), font );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ wxString escapeName( const wxString& aNetName )
|
||||
|
||||
wxString interpretText( const wxString& aText )
|
||||
{
|
||||
wxString token = aText.Upper();
|
||||
wxString token = aText;
|
||||
|
||||
if( substituteVariable( &token ) )
|
||||
return token;
|
||||
@@ -116,25 +116,32 @@ wxString interpretText( const wxString& aText )
|
||||
|
||||
bool substituteVariable( wxString* aText )
|
||||
{
|
||||
if ( *aText == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( *aText == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( *aText == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( *aText == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( *aText == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( *aText == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( *aText == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( *aText == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else return false;
|
||||
if( aText->StartsWith( '>' ) && aText->AfterFirst( ' ' ).IsEmpty() )
|
||||
{
|
||||
wxString token = aText->Upper();
|
||||
|
||||
return true;
|
||||
if ( token == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( token == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( token == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( token == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( token == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( token == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( token == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( token == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else *aText = wxString::Format( wxS( "${%s}" ), aText->Mid( 1 ).Trim() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 CERN
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
@@ -393,10 +393,7 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
|
||||
for( const auto& [ matcher, netclassName ] : m_NetClassPatternAssignments )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher->Find( aNetName, matches, offset ) && offset == 0 )
|
||||
if( matcher->StartsWith( aNetName ) )
|
||||
return getNetclass( netclassName );
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,8 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
||||
return;
|
||||
}
|
||||
|
||||
m_files.clear();
|
||||
|
||||
for( const nlohmann::json& file : aVal )
|
||||
{
|
||||
PROJECT_FILE_STATE fileState;
|
||||
|
||||
@@ -73,9 +73,14 @@ wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGPr
|
||||
m_unitBinder->SetUnits( m_frame->GetUserUnits() );
|
||||
|
||||
if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
|
||||
{
|
||||
m_unitBinder->SetCoordType( prop->CoordType() );
|
||||
}
|
||||
else if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
|
||||
{
|
||||
m_unitBinder->SetCoordType( ORIGIN_TRANSFORMS::NOT_A_COORD );
|
||||
m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
|
||||
}
|
||||
|
||||
UpdateControl( aProperty, win );
|
||||
|
||||
|
||||
+22
-32
@@ -333,73 +333,63 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
||||
{
|
||||
const RC_TREE_NODE* node = ToNode( aItem );
|
||||
const std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
|
||||
MARKER_BASE* marker = rcItem->GetParent();
|
||||
EDA_ITEM* item = nullptr;
|
||||
wxString msg;
|
||||
|
||||
switch( node->m_Type )
|
||||
{
|
||||
case RC_TREE_NODE::MARKER:
|
||||
{
|
||||
wxString prefix;
|
||||
|
||||
if( rcItem->GetParent() )
|
||||
if( marker )
|
||||
{
|
||||
SEVERITY severity = rcItem->GetParent()->GetSeverity();
|
||||
SEVERITY severity = marker->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
|
||||
prefix = _( "Excluded warning: " );
|
||||
msg = _( "Excluded warning: " );
|
||||
else
|
||||
prefix = _( "Excluded error: " );
|
||||
msg = _( "Excluded error: " );
|
||||
}
|
||||
else if( severity == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
prefix = _( "Warning: " );
|
||||
msg = _( "Warning: " );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = _( "Error: " );
|
||||
msg = _( "Error: " );
|
||||
}
|
||||
}
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
}
|
||||
msg += rcItem->GetErrorMessage();
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::MAIN_ITEM:
|
||||
if( rcItem->GetParent() && rcItem->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
{
|
||||
aVariant = _( "Drawing Sheet" );
|
||||
break;
|
||||
}
|
||||
if( marker && marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
msg = _( "Drawing Sheet" );
|
||||
else
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM2:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM3:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
break;
|
||||
}
|
||||
|
||||
if( item )
|
||||
msg += item->GetItemDescription( m_editFrame );
|
||||
|
||||
msg.Replace( wxS( "\n" ), wxS( " " ) );
|
||||
aVariant = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+42
-1
@@ -38,7 +38,7 @@
|
||||
#if !defined( HAVE_FGETC_NOLOCK )
|
||||
#ifdef _MSC_VER
|
||||
//getc is not a macro on windows and adds a tiny overhead for the indirection to eventually calling fgetc
|
||||
#define getc_unlocked fgetc
|
||||
#define getc_unlocked _fgetc_nolock
|
||||
#else
|
||||
#define getc_unlocked getc
|
||||
#endif
|
||||
@@ -106,6 +106,47 @@ std::string StrPrintf( const char* format, ... )
|
||||
}
|
||||
|
||||
|
||||
wxString SafeReadFile( const wxString& aFilePath, const wxString& aReadType )
|
||||
{
|
||||
auto FROM_UTF8_WINE =
|
||||
[]( const char* cstring )
|
||||
{
|
||||
wxString line = wxString::FromUTF8( cstring );
|
||||
|
||||
if( line.IsEmpty() ) // happens when cstring is not a valid UTF8 sequence
|
||||
line = wxConvCurrent->cMB2WC( cstring ); // try to use locale conversion
|
||||
|
||||
// We have trouble here *probably* because Wine-hosted LTSpice writes out MSW
|
||||
// encoded text on a macOS, where it isn't expected. In any case, wxWidgets'
|
||||
// wxSafeConvert() appears to get around it.
|
||||
|
||||
if( line.IsEmpty() )
|
||||
line = wxSafeConvertMB2WX( cstring );
|
||||
|
||||
// I'm not sure what the source of this style of line-endings is, but it can be
|
||||
// found in some Fairchild Semiconductor SPICE files.
|
||||
line.Replace( wxS( "\r\r\n" ), wxS( "\n" ) );
|
||||
|
||||
return line;
|
||||
};
|
||||
|
||||
// Open file
|
||||
FILE* fp = wxFopen( aFilePath, aReadType );
|
||||
|
||||
if( !fp )
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'." ), aFilePath ) );
|
||||
|
||||
FILE_LINE_READER fileReader( fp, aFilePath );
|
||||
|
||||
wxString contents;
|
||||
|
||||
while( fileReader.ReadLine() )
|
||||
contents += FROM_UTF8_WINE( fileReader.Line() );
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
||||
//-----<LINE_READER>------------------------------------------------------
|
||||
|
||||
LINE_READER::LINE_READER( unsigned aMaxLineLength ) :
|
||||
|
||||
@@ -242,6 +242,13 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_BACK )
|
||||
{
|
||||
if( aEvent.GetModifiers() == wxMOD_CONTROL )
|
||||
#ifdef __WXMAC__
|
||||
m_te->HomeExtend();
|
||||
else if( aEvent.GetModifiers() == wxMOD_ALT )
|
||||
#endif
|
||||
m_te->WordLeftExtend();
|
||||
|
||||
m_te->DeleteBack();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_DELETE )
|
||||
|
||||
@@ -109,8 +109,17 @@ void SETTINGS_MANAGER::Load()
|
||||
// TODO(JE) We should check for dirty settings here and write them if so, because
|
||||
// Load() could be called late in the application lifecycle
|
||||
|
||||
for( auto&& settings : m_settings )
|
||||
settings->LoadFromFile( GetPathForSettingsFile( settings.get() ) );
|
||||
std::vector<JSON_SETTINGS*> toLoad;
|
||||
|
||||
// Cache a copy of raw pointers; m_settings may be modified during the load loop
|
||||
std::transform( m_settings.begin(), m_settings.end(), std::back_inserter( toLoad ),
|
||||
[]( std::unique_ptr<JSON_SETTINGS>& aSettings )
|
||||
{
|
||||
return aSettings.get();
|
||||
} );
|
||||
|
||||
for( JSON_SETTINGS* settings : toLoad )
|
||||
settings->LoadFromFile( GetPathForSettingsFile( settings ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <kiway_player.h>
|
||||
#include <macros.h>
|
||||
#include <confirm.h>
|
||||
#include <settings/kicad_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
#include <kiplatform/app.h>
|
||||
@@ -340,6 +341,8 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
||||
// Tell the settings manager about the current Kiway
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
|
||||
GetSettingsManager().RegisterSettings( new KICAD_SETTINGS );
|
||||
|
||||
// Use KIWAY to create a top window, which registers its existence also.
|
||||
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
|
||||
// and is one of the types in FRAME_T.
|
||||
|
||||
+28
-19
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -159,9 +159,12 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
else
|
||||
converted += c;
|
||||
}
|
||||
else if( aContext == CTX_LIBID )
|
||||
else if( aContext == CTX_LIBID || aContext == CTX_LEGACY_LIBID )
|
||||
{
|
||||
if( c == '\\' )
|
||||
// We no longer escape '/' in LIB_IDs, but we used to
|
||||
if( c == '/' && aContext == CTX_LEGACY_LIBID )
|
||||
converted += wxT( "{slash}" );
|
||||
else if( c == '\\' )
|
||||
converted += wxT( "{backslash}" );
|
||||
else if( c == '<' )
|
||||
converted += wxT( "{lt}" );
|
||||
@@ -277,42 +280,49 @@ wxString UnescapeString( const wxString& aSource )
|
||||
wxString newbuf;
|
||||
newbuf.reserve( sourceLen );
|
||||
|
||||
wxUniChar prev = 0;
|
||||
wxUniChar ch = 0;
|
||||
|
||||
for( size_t i = 0; i < sourceLen; ++i )
|
||||
{
|
||||
wxUniChar ch = aSource[i];
|
||||
prev = ch;
|
||||
ch = aSource[i];
|
||||
|
||||
if( ( ch == '$' || ch == '~' || ch == '^' || ch == '_' )
|
||||
&& i + 1 < sourceLen && aSource[i+1] == '{' )
|
||||
{
|
||||
for( ; i < sourceLen; ++i )
|
||||
{
|
||||
ch = aSource[i];
|
||||
newbuf += ch;
|
||||
|
||||
if( ch == '}' )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( ch == '{' )
|
||||
if( ch == '{' )
|
||||
{
|
||||
wxString token;
|
||||
int depth = 1;
|
||||
bool terminated = false;
|
||||
|
||||
for( i = i + 1; i < sourceLen; ++i )
|
||||
{
|
||||
ch = aSource[i];
|
||||
|
||||
if( ch == '{' )
|
||||
depth++;
|
||||
else if( ch == '}' )
|
||||
depth--;
|
||||
|
||||
if( depth <= 0 )
|
||||
{
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
token.append( ch );
|
||||
}
|
||||
}
|
||||
|
||||
if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
||||
if( !terminated )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
|
||||
}
|
||||
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
}
|
||||
else if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
||||
else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
|
||||
else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
|
||||
else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
|
||||
@@ -326,7 +336,6 @@ wxString UnescapeString( const wxString& aSource )
|
||||
else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
|
||||
else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
|
||||
else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
|
||||
else if( token.IsEmpty() ) newbuf.append( wxT( "{" ) );
|
||||
else
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
|
||||
@@ -129,7 +129,10 @@ void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel, bool aGlobal ) cons
|
||||
const TEMPLATE_FIELDNAMES& source = aGlobal ? m_globals : m_project;
|
||||
|
||||
for( const TEMPLATE_FIELDNAME& temp : source )
|
||||
temp.Format( out, nestLevel+1 );
|
||||
{
|
||||
if( !temp.m_Name.IsEmpty() )
|
||||
temp.Format( out, nestLevel+1 );
|
||||
}
|
||||
|
||||
out->Print( 0, ")\n" );
|
||||
}
|
||||
@@ -162,7 +165,8 @@ void TEMPLATES::parse( TEMPLATE_FIELDNAMES_LEXER* in, bool aGlobal )
|
||||
field.Parse( in );
|
||||
|
||||
// add the field
|
||||
AddTemplateFieldName( field, aGlobal );
|
||||
if( !field.m_Name.IsEmpty() )
|
||||
AddTemplateFieldName( field, aGlobal );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ void TEXTENTRY_TRICKS::OnCharHook( wxTextEntry* aTextEntry, wxKeyEvent& aEvent )
|
||||
{
|
||||
aTextEntry->Paste();
|
||||
}
|
||||
else if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKeyCode() == 'A' )
|
||||
{
|
||||
aTextEntry->SelectAll();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_BACK )
|
||||
{
|
||||
long start, end;
|
||||
|
||||
@@ -130,7 +130,9 @@ int COMMON_CONTROL::ShowLibraryTable( const TOOL_EVENT& aEvent )
|
||||
try // Pcb frame was not available, try to start it
|
||||
{
|
||||
KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_PCB );
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_PCB_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
|
||||
if( kiface )
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_PCB_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
|
||||
+40
-43
@@ -240,16 +240,14 @@ private:
|
||||
|
||||
void VIEW::OnDestroy( VIEW_ITEM* aItem )
|
||||
{
|
||||
VIEW_ITEM_DATA* data = aItem->viewPrivData();
|
||||
if( aItem->m_viewPrivData )
|
||||
{
|
||||
if( aItem->m_viewPrivData->m_view )
|
||||
aItem->m_viewPrivData->m_view->VIEW::Remove( aItem );
|
||||
|
||||
if( !data )
|
||||
return;
|
||||
|
||||
if( data->m_view )
|
||||
data->m_view->VIEW::Remove( aItem );
|
||||
|
||||
delete data;
|
||||
aItem->ClearViewPrivData();
|
||||
delete aItem->m_viewPrivData;
|
||||
aItem->m_viewPrivData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -323,6 +321,10 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
if( !aItem->m_viewPrivData )
|
||||
aItem->m_viewPrivData = new VIEW_ITEM_DATA;
|
||||
|
||||
wxASSERT_MSG( aItem->m_viewPrivData->m_view == nullptr
|
||||
|| aItem->m_viewPrivData->m_view == this,
|
||||
wxS( "Already in a different view!" ) );
|
||||
|
||||
aItem->m_viewPrivData->m_view = this;
|
||||
aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
|
||||
|
||||
@@ -334,7 +336,7 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
wxCHECK2_MSG( layers[i] >= 0 && static_cast<unsigned>( layers[i] ) < m_layers.size(),
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
@@ -348,41 +350,36 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
|
||||
void VIEW::Remove( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( !aItem )
|
||||
return;
|
||||
|
||||
auto viewData = aItem->viewPrivData();
|
||||
|
||||
if( !viewData )
|
||||
return;
|
||||
|
||||
wxCHECK( viewData->m_view == this, /*void*/ );
|
||||
auto item = std::find( m_allItems->begin(), m_allItems->end(), aItem );
|
||||
|
||||
if( item != m_allItems->end() )
|
||||
if( aItem && aItem->m_viewPrivData )
|
||||
{
|
||||
m_allItems->erase( item );
|
||||
viewData->clearUpdateFlags();
|
||||
wxCHECK( aItem->m_viewPrivData->m_view == this, /*void*/ );
|
||||
auto item = std::find( m_allItems->begin(), m_allItems->end(), aItem );
|
||||
|
||||
if( item != m_allItems->end() )
|
||||
{
|
||||
m_allItems->erase( item );
|
||||
aItem->m_viewPrivData->clearUpdateFlags();
|
||||
}
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
aItem->m_viewPrivData->getLayers( layers, layers_count );
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
int prevGroup = aItem->m_viewPrivData->getGroup( layers[i] );
|
||||
|
||||
if( prevGroup >= 0 )
|
||||
m_gal->DeleteGroup( prevGroup );
|
||||
}
|
||||
|
||||
aItem->m_viewPrivData->deleteGroups();
|
||||
aItem->m_viewPrivData->m_view = nullptr;
|
||||
}
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
viewData->getLayers( layers, layers_count );
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
int prevGroup = viewData->getGroup( layers[i] );
|
||||
|
||||
if( prevGroup >= 0 )
|
||||
m_gal->DeleteGroup( prevGroup );
|
||||
}
|
||||
|
||||
viewData->deleteGroups();
|
||||
viewData->m_view = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <project.h>
|
||||
#include <widgets/footprint_choice.h>
|
||||
#include <widgets/footprint_select_widget.h>
|
||||
#include <widgets/wx_progress_reporters.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <footprint_info_impl.h>
|
||||
#include <wx/wupdlock.h>
|
||||
@@ -38,7 +39,8 @@ FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWind
|
||||
wxPanel( aParent ),
|
||||
m_update( aUpdate ),
|
||||
m_max_items( aMaxItems ),
|
||||
m_fp_list( aFpList )
|
||||
m_fp_list( aFpList ),
|
||||
m_frame( aFrame )
|
||||
{
|
||||
m_zero_filter = true;
|
||||
m_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
@@ -63,8 +65,13 @@ void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
|
||||
{
|
||||
// If the fp-info-cache is empty (or, more likely, hasn't been created in a new
|
||||
// project yet), load footprints the hard way.
|
||||
FP_LIB_TABLE* fpTable = aProject.PcbFootprintLibs( aKiway );
|
||||
static_cast<FOOTPRINT_LIST_IMPL*>( m_fp_list )->ReadFootprintFiles( fpTable );
|
||||
FP_LIB_TABLE* fpTable = aProject.PcbFootprintLibs( aKiway );
|
||||
WX_PROGRESS_REPORTER* progressReporter =
|
||||
new WX_PROGRESS_REPORTER( m_frame, _( "Loading Footprint Libraries" ), 3 );
|
||||
static_cast<FOOTPRINT_LIST_IMPL*>( m_fp_list )
|
||||
->ReadFootprintFiles( fpTable, nullptr, progressReporter );
|
||||
|
||||
delete progressReporter;
|
||||
}
|
||||
|
||||
m_fp_filter.SetList( *m_fp_list );
|
||||
|
||||
@@ -33,6 +33,7 @@ SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( SEARCH_HANDLER* handler, wxWindow* p
|
||||
RefreshColumnNames();
|
||||
|
||||
Bind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Bind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
|
||||
Bind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Bind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
|
||||
}
|
||||
@@ -41,6 +42,7 @@ SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( SEARCH_HANDLER* handler, wxWindow* p
|
||||
SEARCH_PANE_LISTVIEW::~SEARCH_PANE_LISTVIEW()
|
||||
{
|
||||
Unbind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Unbind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
|
||||
Unbind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
|
||||
Unbind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
|
||||
}
|
||||
@@ -65,10 +67,27 @@ void SEARCH_PANE_LISTVIEW::GetSelectRowsList( std::vector<long>& aSelectedList )
|
||||
}
|
||||
|
||||
|
||||
void SEARCH_PANE_LISTVIEW::OnItemActivated( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[=]()
|
||||
{
|
||||
m_handler->ActivateItem( aEvent.GetIndex() );
|
||||
|
||||
// Reset our selection to match the selected list items
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
m_handler->SelectItems( list );
|
||||
} );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[&]()
|
||||
[=]()
|
||||
{
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
@@ -82,7 +101,7 @@ void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
|
||||
void SEARCH_PANE_LISTVIEW::OnItemDeselected( wxListEvent& aEvent )
|
||||
{
|
||||
CallAfter(
|
||||
[&]()
|
||||
[=]()
|
||||
{
|
||||
std::vector<long> list;
|
||||
GetSelectRowsList( list );
|
||||
@@ -153,4 +172,4 @@ void SEARCH_PANE_TAB::Clear()
|
||||
void SEARCH_PANE_TAB::RefreshColumnNames()
|
||||
{
|
||||
m_listView->RefreshColumnNames();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ void UNIT_BINDER::SetDoubleValue( double aValue )
|
||||
setPrecision( displayValue, false ),
|
||||
false, m_dataType );
|
||||
|
||||
if( displayValue == 0 && m_negativeZero )
|
||||
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
|
||||
SetValue( wxT( "-" ) + textValue );
|
||||
else
|
||||
SetValue( textValue );
|
||||
@@ -424,7 +424,7 @@ void UNIT_BINDER::ChangeDoubleValue( double aValue )
|
||||
setPrecision( displayValue, false ),
|
||||
false, m_dataType );
|
||||
|
||||
if( displayValue == 0 && m_negativeZero )
|
||||
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
|
||||
ChangeValue( wxT( "-" ) + textValue );
|
||||
else
|
||||
ChangeValue( textValue );
|
||||
|
||||
@@ -443,6 +443,34 @@ void WX_GRID::DrawRowLabel( wxDC& dc, int row )
|
||||
}
|
||||
|
||||
|
||||
bool WX_GRID::CancelPendingChanges()
|
||||
{
|
||||
if( !IsCellEditControlEnabled() )
|
||||
return true;
|
||||
|
||||
HideCellEditControl();
|
||||
|
||||
// do it after HideCellEditControl()
|
||||
m_cellEditCtrlEnabled = false;
|
||||
|
||||
int row = m_currentCellCoords.GetRow();
|
||||
int col = m_currentCellCoords.GetCol();
|
||||
|
||||
wxString oldval = GetCellValue( row, col );
|
||||
wxString newval;
|
||||
|
||||
wxGridCellAttr* attr = GetCellAttr( row, col );
|
||||
wxGridCellEditor* editor = attr->GetEditor( this, row, col );
|
||||
|
||||
bool changed = editor->EndEdit( row, col, this, oldval, &newval );
|
||||
|
||||
editor->DecRef();
|
||||
attr->DecRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WX_GRID::CommitPendingChanges( bool aQuietMode )
|
||||
{
|
||||
if( !IsCellEditControlEnabled() )
|
||||
|
||||
@@ -463,15 +463,12 @@ target_link_libraries( eeschema_kiface_objects
|
||||
# declare the dependency
|
||||
add_dependencies( eeschema_kiface_objects common )
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in eeschema" )
|
||||
add_subdirectory( ./navlib )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in eeschema" )
|
||||
add_subdirectory( navlib )
|
||||
|
||||
target_link_libraries( eeschema_kiface_objects PUBLIC eeschema_navlib)
|
||||
|
||||
add_dependencies( eeschema_kiface_objects eeschema_navlib )
|
||||
endif()
|
||||
target_link_libraries( eeschema_kiface_objects PUBLIC eeschema_navlib)
|
||||
|
||||
add_dependencies( eeschema_kiface_objects eeschema_navlib )
|
||||
|
||||
add_library( eeschema_kiface MODULE
|
||||
eeschema.cpp
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -376,7 +376,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
if( symbol->GetUnitCount() > 1 )
|
||||
{
|
||||
msg.Printf( _( "Updated %s (unit %s) from %s to %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
|
||||
prevRef,
|
||||
newRef );
|
||||
@@ -384,7 +384,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Updated %s from %s to %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
prevRef,
|
||||
newRef );
|
||||
}
|
||||
@@ -394,14 +394,14 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
if( symbol->GetUnitCount() > 1 )
|
||||
{
|
||||
msg.Printf( _( "Annotated %s (unit %s) as %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
|
||||
newRef );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Annotated %s as %s." ),
|
||||
symbol->GetValueFieldText( true ),
|
||||
symbol->GetValueFieldText( true, sheet, false ),
|
||||
newRef );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,10 +65,10 @@
|
||||
#include <eeschema_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
|
||||
#define FIELD_PADDING schIUScale.MilsToIU( 10 ) // arbitrarily chosen for aesthetics
|
||||
#define FIELD_PADDING schIUScale.MilsToIU( 15 ) // arbitrarily chosen for aesthetics
|
||||
#define WIRE_V_SPACING schIUScale.MilsToIU( 100 )
|
||||
#define HPADDING schIUScale.MilsToIU( 25 )
|
||||
#define VPADDING schIUScale.MilsToIU( 25 )
|
||||
#define HPADDING schIUScale.MilsToIU( 25 ) // arbitrarily chosen for aesthetics
|
||||
#define VPADDING schIUScale.MilsToIU( 15 ) // arbitrarily chosen for aesthetics
|
||||
|
||||
/**
|
||||
* Round up/down to the nearest multiple of n
|
||||
@@ -219,10 +219,6 @@ protected:
|
||||
|
||||
max_field_width = std::max( max_field_width, field_width );
|
||||
|
||||
// Remove interline spacing from field_height for last line.
|
||||
if( field == visibleFields.back() )
|
||||
field_height *= 0.62;
|
||||
|
||||
if( !aDynamic )
|
||||
total_height += WIRE_V_SPACING;
|
||||
else if( m_align_to_grid )
|
||||
|
||||
+310
-58
@@ -228,6 +228,24 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_SUBGRAPH::getAllConnectedItems( std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>>& aItems, std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
|
||||
{
|
||||
CONNECTION_SUBGRAPH* sg = this;
|
||||
|
||||
while( sg->m_absorbed_by )
|
||||
sg = sg->m_absorbed_by;
|
||||
|
||||
aSubgraphs.insert( sg );
|
||||
aSubgraphs.insert( sg->m_absorbed_subgraphs.begin(), sg->m_absorbed_subgraphs.end() );
|
||||
|
||||
for( SCH_ITEM* item : sg->m_items )
|
||||
aItems.emplace( m_sheet, item );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* child_sg : sg->m_hier_children )
|
||||
child_sg->getAllConnectedItems( aItems, aSubgraphs );
|
||||
}
|
||||
|
||||
|
||||
wxString CONNECTION_SUBGRAPH::GetNetName() const
|
||||
{
|
||||
if( !m_driver || m_dirty )
|
||||
@@ -313,17 +331,19 @@ wxString CONNECTION_SUBGRAPH::driverName( SCH_ITEM* aItem ) const
|
||||
bool forceNoConnect = m_no_connect != nullptr;
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
|
||||
return pin->GetDefaultNetName( m_sheet, forceNoConnect );
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText( &m_sheet, false ),
|
||||
CTX_NETNAME );
|
||||
|
||||
case SCH_SHEET_PIN_T:
|
||||
{
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText(), CTX_NETNAME );
|
||||
break;
|
||||
}
|
||||
// Sheet pins need to use their parent sheet as their starting sheet or they will
|
||||
// resolve variables on the current sheet first
|
||||
return EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText( nullptr, false ),
|
||||
CTX_NETNAME );
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxS( "Unhandled item type in GetNameForDriver" ) );
|
||||
@@ -377,16 +397,30 @@ void CONNECTION_SUBGRAPH::Absorb( CONNECTION_SUBGRAPH* aOther )
|
||||
AddItem( item );
|
||||
}
|
||||
|
||||
m_absorbed_subgraphs.insert( aOther );
|
||||
m_absorbed_subgraphs.insert( aOther->m_absorbed_subgraphs.begin(),
|
||||
aOther->m_absorbed_subgraphs.end() );
|
||||
|
||||
m_bus_neighbors.insert( aOther->m_bus_neighbors.begin(), aOther->m_bus_neighbors.end() );
|
||||
m_bus_parents.insert( aOther->m_bus_parents.begin(), aOther->m_bus_parents.end() );
|
||||
|
||||
m_multiple_drivers |= aOther->m_multiple_drivers;
|
||||
|
||||
std::function<void( CONNECTION_SUBGRAPH* )> set_absorbed_by =
|
||||
[ & ]( CONNECTION_SUBGRAPH *child )
|
||||
{
|
||||
child->m_absorbed_by = this;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subchild : child->m_absorbed_subgraphs )
|
||||
set_absorbed_by( subchild );
|
||||
};
|
||||
|
||||
aOther->m_absorbed = true;
|
||||
aOther->m_dirty = false;
|
||||
aOther->m_driver = nullptr;
|
||||
aOther->m_driver_connection = nullptr;
|
||||
aOther->m_absorbed_by = this;
|
||||
|
||||
set_absorbed_by( aOther );
|
||||
}
|
||||
|
||||
|
||||
@@ -445,9 +479,12 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
SCH_PIN* sch_pin = static_cast<SCH_PIN*>( aDriver );
|
||||
SCH_SYMBOL* sym = sch_pin->GetParentSymbol();
|
||||
|
||||
if( sch_pin->IsPowerConnection() )
|
||||
return PRIORITY::POWER_PIN;
|
||||
else if( !sym || !sym->GetIncludeOnBoard() || sym->GetLibSymbolRef()->GetReferenceField().GetText().StartsWith( '#' ) )
|
||||
return PRIORITY::NONE;
|
||||
else
|
||||
return PRIORITY::PIN;
|
||||
}
|
||||
@@ -457,10 +494,66 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
{
|
||||
std::copy( aGraph.m_items.begin(), aGraph.m_items.end(),
|
||||
std::back_inserter( m_items ) );
|
||||
|
||||
for( SCH_ITEM* item : aGraph.m_items )
|
||||
item->SetConnectionGraph( this );
|
||||
|
||||
std::copy( aGraph.m_subgraphs.begin(), aGraph.m_subgraphs.end(),
|
||||
std::back_inserter( m_subgraphs ) );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aGraph.m_subgraphs )
|
||||
sg->m_graph = this;
|
||||
|
||||
std::copy( aGraph.m_driver_subgraphs.begin(),
|
||||
aGraph.m_driver_subgraphs.end(),
|
||||
std::back_inserter( m_driver_subgraphs ) );
|
||||
|
||||
std::copy( aGraph.m_invisible_power_pins.begin(),
|
||||
aGraph.m_invisible_power_pins.end(),
|
||||
std::back_inserter( m_invisible_power_pins ) );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_name_to_subgraphs_map )
|
||||
m_net_name_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_sheet_to_subgraphs_map )
|
||||
m_sheet_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_name_to_code_map )
|
||||
m_net_name_to_code_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_bus_name_to_code_map )
|
||||
m_bus_name_to_code_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_code_to_subgraphs_map )
|
||||
m_net_code_to_subgraphs_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_item_to_subgraph_map )
|
||||
m_item_to_subgraph_map.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_local_label_cache )
|
||||
m_local_label_cache.insert_or_assign( key, value );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_global_label_cache )
|
||||
m_global_label_cache.insert_or_assign( key, value );
|
||||
|
||||
m_last_bus_code = std::max( m_last_bus_code, aGraph.m_last_bus_code );
|
||||
m_last_net_code = std::max( m_last_net_code, aGraph.m_last_net_code );
|
||||
m_last_subgraph_code = std::max( m_last_subgraph_code, aGraph.m_last_subgraph_code );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::Reset()
|
||||
{
|
||||
for( auto& subgraph : m_subgraphs )
|
||||
delete subgraph;
|
||||
{
|
||||
/// Only delete subgraphs of which we are the owner
|
||||
if( subgraph->m_graph == this )
|
||||
delete subgraph;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
m_subgraphs.clear();
|
||||
@@ -552,6 +645,209 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
recalc_time.Show();
|
||||
}
|
||||
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffectedItems(
|
||||
const std::set<SCH_ITEM*> &aItems )
|
||||
{
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> retvals;
|
||||
std::set<CONNECTION_SUBGRAPH*> subgraphs;
|
||||
|
||||
auto traverse_subgraph = [&retvals, &subgraphs]( CONNECTION_SUBGRAPH* aSubgraph )
|
||||
{
|
||||
// Find the primary subgraph on this sheet
|
||||
while( aSubgraph->m_absorbed_by )
|
||||
aSubgraph = aSubgraph->m_absorbed_by;
|
||||
|
||||
// Find the top most connected subgraph on all sheets
|
||||
while( aSubgraph->m_hier_parent )
|
||||
aSubgraph = aSubgraph->m_hier_parent;
|
||||
|
||||
// Recurse through all subsheets to collect connected items
|
||||
aSubgraph->getAllConnectedItems( retvals, subgraphs );
|
||||
};
|
||||
|
||||
for( SCH_ITEM* item : aItems )
|
||||
{
|
||||
auto it = m_item_to_subgraph_map.find( item );
|
||||
|
||||
if( it == m_item_to_subgraph_map.end() )
|
||||
continue;
|
||||
|
||||
CONNECTION_SUBGRAPH* sg = it->second;
|
||||
|
||||
traverse_subgraph( sg );
|
||||
|
||||
for( auto& bus_it : sg->m_bus_neighbors )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
|
||||
traverse_subgraph( bus_sg );
|
||||
}
|
||||
|
||||
for( auto& bus_it : sg->m_bus_parents )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
|
||||
traverse_subgraph( bus_sg );
|
||||
}
|
||||
|
||||
alg::delete_matching( m_items, item );
|
||||
}
|
||||
|
||||
removeSubgraphs( subgraphs );
|
||||
|
||||
return retvals;
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
|
||||
{
|
||||
std::sort( m_driver_subgraphs.begin(), m_driver_subgraphs.end() );
|
||||
std::sort( m_subgraphs.begin(), m_subgraphs.end() );
|
||||
std::set<int> codes_to_remove;
|
||||
|
||||
for( auto el : m_sheet_to_subgraphs_map )
|
||||
{
|
||||
std::sort( el.second.begin(), el.second.end() );
|
||||
}
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
|
||||
{
|
||||
for( auto it : sg->m_bus_neighbors )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* neighbor : it.second )
|
||||
{
|
||||
auto& parents = neighbor->m_bus_parents[it.first];
|
||||
|
||||
for( auto test = parents.begin(); test != parents.end(); )
|
||||
{
|
||||
if( *test == sg )
|
||||
test = parents.erase( test );
|
||||
else
|
||||
++test;
|
||||
}
|
||||
|
||||
if( parents.empty() )
|
||||
neighbor->m_bus_parents.erase( it.first );
|
||||
}
|
||||
}
|
||||
|
||||
for( auto it : sg->m_bus_parents )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* parent : it.second )
|
||||
{
|
||||
auto& neighbors = parent->m_bus_neighbors[it.first];
|
||||
|
||||
for( auto test = neighbors.begin(); test != neighbors.end(); )
|
||||
{
|
||||
if( *test == sg )
|
||||
test = neighbors.erase( test );
|
||||
else
|
||||
++test;
|
||||
}
|
||||
|
||||
if( neighbors.empty() )
|
||||
parent->m_bus_neighbors.erase( it.first );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::lower_bound( m_driver_subgraphs.begin(), m_driver_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_driver_subgraphs.end() )
|
||||
m_driver_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::lower_bound( m_subgraphs.begin(), m_subgraphs.end(), sg );
|
||||
|
||||
if( it != m_subgraphs.end() )
|
||||
m_subgraphs.erase( it );
|
||||
}
|
||||
|
||||
for( auto el : m_sheet_to_subgraphs_map )
|
||||
{
|
||||
auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
|
||||
|
||||
if( it != el.second.end() )
|
||||
el.second.erase( it );
|
||||
}
|
||||
|
||||
auto remove_sg = [sg]( auto it ) -> bool
|
||||
{
|
||||
for( const CONNECTION_SUBGRAPH* test_sg : it->second )
|
||||
{
|
||||
if( sg == test_sg )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
for( auto it = m_global_label_cache.begin(); it != m_global_label_cache.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_global_label_cache.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_local_label_cache.begin(); it != m_local_label_cache.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_local_label_cache.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_net_code_to_subgraphs_map.begin(); it != m_net_code_to_subgraphs_map.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
{
|
||||
codes_to_remove.insert( it->first.Netcode );
|
||||
it = m_net_code_to_subgraphs_map.erase( it );
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_net_name_to_subgraphs_map.begin(); it != m_net_name_to_subgraphs_map.end(); )
|
||||
{
|
||||
if( remove_sg( it ) )
|
||||
it = m_net_name_to_subgraphs_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_item_to_subgraph_map.begin(); it != m_item_to_subgraph_map.end(); )
|
||||
{
|
||||
if( it->second == sg )
|
||||
it = m_item_to_subgraph_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
for( auto it = m_net_name_to_code_map.begin(); it != m_net_name_to_code_map.end(); )
|
||||
{
|
||||
if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
|
||||
it = m_net_name_to_code_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( auto it = m_bus_name_to_code_map.begin(); it != m_bus_name_to_code_map.end(); )
|
||||
{
|
||||
if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
|
||||
it = m_bus_name_to_code_map.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
|
||||
{
|
||||
sg->m_code = -1;
|
||||
delete sg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
const std::vector<SCH_ITEM*>& aItemList )
|
||||
@@ -1355,7 +1651,7 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : candidate_subgraphs )
|
||||
{
|
||||
if( candidate->m_absorbed )
|
||||
if( candidate->m_absorbed || candidate == subgraph )
|
||||
continue;
|
||||
|
||||
bool match = false;
|
||||
@@ -1582,6 +1878,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
conn->Clone( *subgraph->m_driver_connection );
|
||||
|
||||
candidate->m_dirty = false;
|
||||
propagateToNeighbors( candidate, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1912,6 +2209,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
candidate->m_code, candidate->m_driver_connection->Name() );
|
||||
|
||||
candidate->m_hier_parent = aParent;
|
||||
aParent->m_hier_children.insert( candidate );
|
||||
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
@@ -1919,53 +2217,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( SCH_HIERLABEL* label : aParent->m_hier_ports )
|
||||
{
|
||||
SCH_SHEET_PATH path = aParent->m_sheet;
|
||||
path.pop_back();
|
||||
|
||||
auto it = m_sheet_to_subgraphs_map.find( path );
|
||||
|
||||
if( it == m_sheet_to_subgraphs_map.end() )
|
||||
continue;
|
||||
|
||||
for( CONNECTION_SUBGRAPH* candidate : it->second )
|
||||
{
|
||||
if( candidate->m_hier_pins.empty()
|
||||
|| visited.count( candidate )
|
||||
|| candidate->m_driver_connection->Type() != aParent->m_driver_connection->Type() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
|
||||
|
||||
for( SCH_SHEET_PIN* pin : candidate->m_hier_pins )
|
||||
{
|
||||
// If the last sheet UUIDs won't match, no need to check the full path
|
||||
if( pin->GetParent()->m_Uuid != last_parent_uuid )
|
||||
continue;
|
||||
|
||||
SCH_SHEET_PATH pin_path = path;
|
||||
pin_path.push_back( pin->GetParent() );
|
||||
|
||||
if( pin_path != aParent->m_sheet )
|
||||
continue;
|
||||
|
||||
if( aParent->GetNameForDriver( label ) == candidate->GetNameForDriver( pin ) )
|
||||
{
|
||||
wxLogTrace( ConnTrace, wxS( "%lu: found additional parent %lu (%s)" ),
|
||||
aParent->m_code, candidate->m_code,
|
||||
candidate->m_driver_connection->Name() );
|
||||
|
||||
search_list.push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph ) {
|
||||
for( const auto& kv : aParentGraph->m_bus_neighbors )
|
||||
@@ -2332,11 +2584,11 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
|
||||
if( labels.size() > 1 )
|
||||
{
|
||||
bool different = false;
|
||||
wxString first = static_cast<SCH_TEXT*>( labels.at( 0 ) )->GetShownText();
|
||||
wxString first = static_cast<SCH_TEXT*>( labels.at( 0 ) )->GetShownText( false );
|
||||
|
||||
for( unsigned i = 1; i < labels.size(); ++i )
|
||||
{
|
||||
if( static_cast<SCH_TEXT*>( labels.at( i ) )->GetShownText() != first )
|
||||
if( static_cast<SCH_TEXT*>( labels.at( i ) )->GetShownText( false ) != first )
|
||||
{
|
||||
different = true;
|
||||
break;
|
||||
@@ -2676,7 +2928,7 @@ bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSu
|
||||
case SCH_HIER_LABEL_T:
|
||||
{
|
||||
SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
|
||||
conn.ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
|
||||
conn.ConfigureFromLabel( EscapeString( text->GetShownText( false ), CTX_NETNAME ) );
|
||||
|
||||
if( conn.IsBus() )
|
||||
bus_item = ( !bus_item ) ? item : bus_item;
|
||||
|
||||
@@ -129,6 +129,15 @@ public:
|
||||
/// Updates all items to match the driver connection
|
||||
void UpdateItemConnections();
|
||||
|
||||
/// Provides a read-only reference to the items in the subgraph
|
||||
const std::vector<SCH_ITEM*>& GetItems() const
|
||||
{
|
||||
return m_items;
|
||||
}
|
||||
|
||||
/// Finds all items in the subgraph as well as child subgraphs recursively
|
||||
void getAllConnectedItems( std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>>& aItems, std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
|
||||
|
||||
/**
|
||||
* Return the priority (higher is more important) of a candidate driver
|
||||
*
|
||||
@@ -173,6 +182,9 @@ public:
|
||||
/// If this subgraph is absorbed, points to the absorbing (and valid) subgraph
|
||||
CONNECTION_SUBGRAPH* m_absorbed_by;
|
||||
|
||||
/// Set of subgraphs that have been absorbed by this subgraph
|
||||
std::set<CONNECTION_SUBGRAPH*> m_absorbed_subgraphs;
|
||||
|
||||
long m_code;
|
||||
|
||||
/**
|
||||
@@ -211,7 +223,7 @@ public:
|
||||
*
|
||||
* For example, if this subgraph is a bus D[7..0], and on the same sheet there is
|
||||
* a net with label D7, this map will contain an entry for the D7 bus member, and
|
||||
* the vector will contain a pointer to the D7 net subgraph.
|
||||
* the set will contain a pointer to the D7 net subgraph.
|
||||
*/
|
||||
std::unordered_map< std::shared_ptr<SCH_CONNECTION>,
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_neighbors;
|
||||
@@ -233,6 +245,9 @@ public:
|
||||
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
|
||||
CONNECTION_SUBGRAPH* m_hier_parent;
|
||||
|
||||
// If not null, this indicates the subgraph(s) on a lower level sheet that are linked to this one
|
||||
std::unordered_set<CONNECTION_SUBGRAPH*> m_hier_children;
|
||||
|
||||
/// A cache of escaped netnames from schematic items
|
||||
mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
|
||||
|
||||
@@ -299,6 +314,13 @@ public:
|
||||
m_schematic = aSchematic;
|
||||
}
|
||||
|
||||
void SetLastCodes( const CONNECTION_GRAPH* aOther )
|
||||
{
|
||||
m_last_net_code = aOther->m_last_net_code;
|
||||
m_last_bus_code = aOther->m_last_bus_code;
|
||||
m_last_subgraph_code = aOther->m_last_subgraph_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection graph for the given list of sheets.
|
||||
*
|
||||
@@ -363,6 +385,24 @@ public:
|
||||
*/
|
||||
wxString GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const;
|
||||
|
||||
/**
|
||||
* For a set of items, this will remove the connected items and their
|
||||
* associated data including subgraphs and generated codes from the connection graph.
|
||||
*
|
||||
* @param aItems A vector of items whose presence should be removed from the graph
|
||||
* @return The full set of all items associated with the input items that were removed
|
||||
*/
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> ExtractAffectedItems(
|
||||
const std::set<SCH_ITEM*> &aItems );
|
||||
|
||||
/**
|
||||
* Combines the input graph contents into the current graph. After merging, the
|
||||
* original graph is invalid.
|
||||
*
|
||||
* @param aGraph Input graph reference to add to the current graph
|
||||
*/
|
||||
void Merge( CONNECTION_GRAPH& aGraph );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Updates the graphical connectivity between items (i.e. where they touch)
|
||||
@@ -472,6 +512,14 @@ private:
|
||||
*/
|
||||
void propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, bool aForce );
|
||||
|
||||
/**
|
||||
* Removes references to the given subgraphs from all structures in the
|
||||
* connection graph.
|
||||
*
|
||||
* @param aSubgraphs set of unique subgraphs to find/remove
|
||||
*/
|
||||
void removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
|
||||
|
||||
/**
|
||||
* Search for a matching bus member inside a bus connection
|
||||
*
|
||||
|
||||
@@ -883,6 +883,9 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
return;
|
||||
}
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
|
||||
RecalculateConnections( GLOBAL_CLEANUP );
|
||||
|
||||
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBO
|
||||
|
||||
m_newId->ChangeValue( UnescapeString( m_symbol->GetLibId().Format() ) );
|
||||
m_specifiedReference->ChangeValue( m_symbol->GetRef( currentSheet ) );
|
||||
m_specifiedValue->ChangeValue( m_symbol->GetValueFieldText( false ) );
|
||||
m_specifiedValue->ChangeValue( UnescapeString( m_symbol->GetField( VALUE_FIELD )->GetText() ) );
|
||||
m_specifiedId->ChangeValue( UnescapeString( m_symbol->GetLibId().Format() ) );
|
||||
}
|
||||
else
|
||||
@@ -426,12 +426,14 @@ bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInsta
|
||||
else if( m_matchByReference->GetValue() )
|
||||
{
|
||||
return WildCompareString( m_specifiedReference->GetValue(),
|
||||
aSymbol->GetRef( aInstance, false ), false );
|
||||
UnescapeString( aSymbol->GetRef( aInstance, false ) ),
|
||||
false );
|
||||
}
|
||||
else if( m_matchByValue->GetValue() )
|
||||
{
|
||||
return WildCompareString( m_specifiedValue->GetValue(),
|
||||
aSymbol->GetValueFieldText( false ), false );
|
||||
UnescapeString( aSymbol->GetField( VALUE_FIELD )->GetText() ),
|
||||
false );
|
||||
}
|
||||
else if( m_matchById )
|
||||
{
|
||||
@@ -589,8 +591,10 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
|
||||
if( m_resetAttributes->GetValue() )
|
||||
{
|
||||
symbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
|
||||
symbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
|
||||
// Fetch the attributes from the *flattened* library symbol. They are not supported
|
||||
// in derived symbols.
|
||||
symbol->SetIncludeInBom( symbol->GetLibSymbolRef()->GetIncludeInBom() );
|
||||
symbol->SetIncludeOnBoard( symbol->GetLibSymbolRef()->GetIncludeOnBoard() );
|
||||
}
|
||||
|
||||
bool removeExtras = m_removeExtraBox->GetValue();
|
||||
@@ -609,9 +613,9 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
continue;
|
||||
|
||||
if( i < MANDATORY_FIELDS )
|
||||
libField = libSymbol->GetFieldById( (int) i );
|
||||
libField = symbol->GetLibSymbolRef()->GetFieldById( (int) i );
|
||||
else
|
||||
libField = libSymbol->FindField( field.GetName() );
|
||||
libField = symbol->GetLibSymbolRef()->FindField( field.GetName() );
|
||||
|
||||
if( libField )
|
||||
{
|
||||
@@ -670,7 +674,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
}
|
||||
|
||||
std::vector<LIB_FIELD*> libFields;
|
||||
libSymbol->GetFields( libFields );
|
||||
symbol->GetLibSymbolRef()->GetFields( libFields );
|
||||
|
||||
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <gestfich.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_edit_frame.h>
|
||||
@@ -460,9 +461,6 @@ void DIALOG_ERC::testErc()
|
||||
|
||||
SCHEMATIC* sch = &m_parent->Schematic();
|
||||
|
||||
// Build the whole sheet list in hierarchy (sheet, not screen)
|
||||
sch->GetSheets().AnnotatePowerSymbols();
|
||||
|
||||
SCH_SCREENS screens( sch->Root() );
|
||||
ERC_SETTINGS& settings = sch->ErcSettings();
|
||||
ERC_TESTER tester( sch );
|
||||
@@ -483,7 +481,13 @@ void DIALOG_ERC::testErc()
|
||||
|
||||
// The connection graph has a whole set of ERC checks it can run
|
||||
AdvancePhase( _( "Checking conflicts..." ) );
|
||||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
// If we are using the new connectivity, make sure that we do a full-rebuild
|
||||
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
|
||||
m_parent->RecalculateConnections( GLOBAL_CLEANUP );
|
||||
else
|
||||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
sch->ConnectionGraph()->RunERC();
|
||||
|
||||
AdvancePhase( _( "Checking units..." ) );
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -287,7 +287,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataToWindow()
|
||||
// Ensure the symbol has the Power (i.e. equivalent to a global label
|
||||
// before adding its value in list
|
||||
if( power->IsSymbolLikePowerGlobalLabel() )
|
||||
existingLabels.insert( UnescapeString( power->GetValueFieldText( false ) ) );
|
||||
existingLabels.insert( UnescapeString( power->GetField( VALUE_FIELD )->GetText() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,7 +595,6 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
|
||||
m_Parent->UpdateItem( m_currentLabel );
|
||||
m_Parent->GetCanvas()->Refresh();
|
||||
m_Parent->OnModify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -874,7 +874,7 @@ void DIALOG_SHEET_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
|
||||
m_dummySheet.SetFields( *m_fields );
|
||||
m_dummySheetNameField.SetText( sheetName );
|
||||
path += m_dummySheetNameField.GetShownText();
|
||||
path += m_dummySheetNameField.GetShownText( false );
|
||||
|
||||
editor->DecRef();
|
||||
|
||||
|
||||
@@ -65,7 +65,12 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symb
|
||||
{
|
||||
m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
|
||||
|
||||
m_sortedPartPins = m_symbol.GetAllLibPins();
|
||||
for( LIB_PIN* pin : aSymbol.GetAllLibPins() )
|
||||
{
|
||||
// De Morgan conversions are equivalences, not additional items to simulate
|
||||
if( !pin->GetParent()->HasConversion() || pin->GetConvert() < 2 )
|
||||
m_sortedPartPins.push_back( pin );
|
||||
}
|
||||
|
||||
std::sort( m_sortedPartPins.begin(), m_sortedPartPins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
@@ -165,14 +170,6 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
m_fields[ VALUE_FIELD ].SetText( wxT( "${SIM.PARAMS}" ) );
|
||||
}
|
||||
|
||||
std::vector<LIB_PIN*> sourcePins = m_symbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
std::string libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||
|
||||
if( libraryFilename != "" )
|
||||
@@ -184,7 +181,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
{
|
||||
m_libraryPathText->ChangeValue( libraryFilename );
|
||||
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, &reporter );
|
||||
m_libraryModelsMgr.CreateModel( nullptr, sourcePins, m_fields );
|
||||
m_libraryModelsMgr.CreateModel( nullptr, m_sortedPartPins, m_fields );
|
||||
|
||||
m_modelNameChoice->Append( _( "<unknown>" ) );
|
||||
m_modelNameChoice->SetSelection( 0 );
|
||||
@@ -213,7 +210,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
if( isIbisLoaded() && ( m_modelNameChoice->GetSelection() >= 0 ) )
|
||||
{
|
||||
int idx = m_modelNameChoice->GetSelection();
|
||||
auto kibismodel = dynamic_cast<SIM_MODEL_KIBIS*>( &m_libraryModelsMgr.GetModels().at( idx ).get() );
|
||||
auto kibismodel = dynamic_cast<SIM_MODEL_KIBIS*>( &m_libraryModelsMgr.GetModels()[idx].get() );
|
||||
|
||||
if( kibismodel )
|
||||
{
|
||||
@@ -274,7 +271,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
|
||||
{
|
||||
msg.clear();
|
||||
m_builtinModelsMgr.CreateModel( m_fields, sourcePins, false );
|
||||
m_builtinModelsMgr.CreateModel( m_fields, m_sortedPartPins, false );
|
||||
|
||||
if( reporter.HasMessage() )
|
||||
{
|
||||
@@ -284,7 +281,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_builtinModelsMgr.CreateModel( type, sourcePins );
|
||||
m_builtinModelsMgr.CreateModel( type, m_sortedPartPins );
|
||||
}
|
||||
|
||||
SIM_MODEL::DEVICE_T deviceTypeT = SIM_MODEL::TypeInfo( type ).deviceType;
|
||||
@@ -698,22 +695,14 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<LIB_PIN*> sourcePins = m_symbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
|
||||
|
||||
for( const auto& [baseModelName, baseModel] : library()->GetModels() )
|
||||
{
|
||||
if( baseModelName == modelName )
|
||||
m_libraryModelsMgr.CreateModel( &baseModel, sourcePins, m_fields );
|
||||
m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins, m_fields );
|
||||
else
|
||||
m_libraryModelsMgr.CreateModel( &baseModel, sourcePins );
|
||||
m_libraryModelsMgr.CreateModel( &baseModel, m_sortedPartPins );
|
||||
}
|
||||
|
||||
if( reporter.HasMessage() )
|
||||
@@ -1202,13 +1191,6 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onTypeChoice( wxCommandEvent& aEvent )
|
||||
{
|
||||
SIM_MODEL::DEVICE_T deviceType = curModel().GetDeviceType();
|
||||
wxString typeDescription = m_typeChoice->GetString( m_typeChoice->GetSelection() );
|
||||
std::vector<LIB_PIN*> sourcePins = m_symbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
@@ -1223,13 +1205,14 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onTypeChoice( wxCommandEvent& aEvent )
|
||||
{
|
||||
int idx = m_modelNameChoice->GetSelection();
|
||||
|
||||
auto& baseModel = static_cast<SIM_MODEL_KIBIS&>( m_libraryModelsMgr.GetModels().at( idx ).get() );
|
||||
auto& baseModel = static_cast<SIM_MODEL_KIBIS&>( m_libraryModelsMgr.GetModels()[idx].get() );
|
||||
|
||||
m_libraryModelsMgr.SetModel( idx, std::make_unique<SIM_MODEL_KIBIS>( type, baseModel ) );
|
||||
|
||||
try
|
||||
{
|
||||
m_libraryModelsMgr.GetModels().at( idx ).get().ReadDataFields( &m_fields, sourcePins );
|
||||
m_libraryModelsMgr.GetModels()[idx].get().ReadDataFields( &m_fields,
|
||||
m_sortedPartPins );
|
||||
}
|
||||
catch( IO_ERROR& err )
|
||||
{
|
||||
|
||||
@@ -213,18 +213,8 @@ public:
|
||||
|
||||
for( unsigned i = 0; i < m_symbolsList.GetCount(); ++i )
|
||||
{
|
||||
SCH_SYMBOL* symbol = m_symbolsList[ i ].GetSymbol();
|
||||
|
||||
wxCHECK( symbol && ( symbol->GetInstanceReferences().size() != 0 ), /* void */ );
|
||||
|
||||
wxString val = symbol->GetFieldText( aFieldName );
|
||||
|
||||
if( aFieldName == wxT( "Value" ) )
|
||||
val = symbol->GetValueFieldText( true );
|
||||
else if( aFieldName == wxT( "Footprint" ) )
|
||||
val = symbol->GetFootprintFieldText( true );
|
||||
|
||||
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = val;
|
||||
if( SCH_SYMBOL* symbol = m_symbolsList[ i ].GetSymbol() )
|
||||
m_dataStore[ symbol->m_Uuid ][ aFieldName ] = symbol->GetFieldText( aFieldName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,10 @@ bool PANEL_TEMPLATE_FIELDNAMES::TransferDataFromWindow()
|
||||
m_templateMgr->DeleteAllFieldNameTemplates( m_global );
|
||||
|
||||
for( const TEMPLATE_FIELDNAME& field : m_fields )
|
||||
m_templateMgr->AddTemplateFieldName( field, m_global );
|
||||
{
|
||||
if( !field.m_Name.IsEmpty() )
|
||||
m_templateMgr->AddTemplateFieldName( field, m_global );
|
||||
}
|
||||
|
||||
if( m_global )
|
||||
{
|
||||
|
||||
@@ -332,7 +332,12 @@ 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() );
|
||||
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();
|
||||
|
||||
start_common( aCtlBits );
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -199,9 +199,15 @@ int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob )
|
||||
// Annotation warning check
|
||||
SCH_REFERENCE_LIST referenceList;
|
||||
sch->GetSheets().GetSymbols( referenceList );
|
||||
|
||||
if( referenceList.GetCount() > 0 )
|
||||
{
|
||||
if( referenceList.CheckAnnotation( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* ) {} ) > 0 )
|
||||
if( referenceList.CheckAnnotation(
|
||||
[]( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
|
||||
{
|
||||
// We're only interested in the end result -- either errors or not
|
||||
} )
|
||||
> 0 )
|
||||
{
|
||||
wxPrintf( _( "Warning: schematic has annotation errors, please use the schematic editor to fix them\n" ) );
|
||||
}
|
||||
@@ -294,11 +300,13 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
|
||||
// Annotation warning check
|
||||
SCH_REFERENCE_LIST referenceList;
|
||||
sch->GetSheets().GetSymbols( referenceList );
|
||||
|
||||
if( referenceList.GetCount() > 0 )
|
||||
{
|
||||
if( referenceList.CheckAnnotation(
|
||||
[]( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
|
||||
{
|
||||
// We're only interested in the end result -- either errors or not
|
||||
} )
|
||||
> 0 )
|
||||
{
|
||||
@@ -311,9 +319,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
|
||||
ERC_TESTER erc( sch );
|
||||
|
||||
if( erc.TestDuplicateSheetNames( false ) > 0 )
|
||||
{
|
||||
wxPrintf( _( "Warning: duplicate sheet names.\n" ) );
|
||||
}
|
||||
|
||||
std::unique_ptr<NETLIST_EXPORTER_XML> xmlNetlist =
|
||||
std::make_unique<NETLIST_EXPORTER_XML>( sch );
|
||||
@@ -330,17 +336,15 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
|
||||
bool res = xmlNetlist->WriteNetlist( aNetJob->m_outputFile, GNL_OPT_BOM, *this );
|
||||
|
||||
if( !res )
|
||||
{
|
||||
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return CLI::EXIT_CODES::OK;
|
||||
}
|
||||
|
||||
|
||||
int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
|
||||
KIGFX::SCH_RENDER_SETTINGS* aRenderSettings,
|
||||
LIB_SYMBOL* symbol )
|
||||
KIGFX::SCH_RENDER_SETTINGS* aRenderSettings,
|
||||
LIB_SYMBOL* symbol )
|
||||
{
|
||||
wxASSERT( symbol != nullptr );
|
||||
|
||||
@@ -372,73 +376,86 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
|
||||
// iterate from unit 1, unit 0 would be "all units" which we don't want
|
||||
for( int unit = 1; unit < symbol->GetUnitCount() + 1; unit++ )
|
||||
{
|
||||
int convert = 0;
|
||||
|
||||
wxFileName fn;
|
||||
|
||||
fn.SetPath( aSvgJob->m_outputDirectory );
|
||||
fn.SetExt( SVGFileExtension );
|
||||
|
||||
//simplify the name if its single unit
|
||||
if( symbol->IsMulti() )
|
||||
for( int convert = 1; convert < ( symbol->HasConversion() ? 2 : 1 ) + 1; ++convert )
|
||||
{
|
||||
fn.SetName( wxString::Format( "%s_%d", symbol->GetName().Lower(), unit ) );
|
||||
wxPrintf( _( "Plotting symbol '%s' unit %d to '%s'\n" ), symbol->GetName(), unit,
|
||||
fn.GetFullPath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.SetName( symbol->GetName().Lower() );
|
||||
wxPrintf( _( "Plotting symbol '%s' to '%s'\n" ), symbol->GetName(), fn.GetFullPath() );
|
||||
}
|
||||
wxString filename;
|
||||
wxFileName fn;
|
||||
|
||||
// Get the symbol bounding box to fit the plot page to it
|
||||
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, convert, false );
|
||||
PAGE_INFO pageInfo( PAGE_INFO::Custom );
|
||||
pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
|
||||
pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
|
||||
fn.SetPath( aSvgJob->m_outputDirectory );
|
||||
fn.SetExt( SVGFileExtension );
|
||||
|
||||
SVG_PLOTTER* plotter = new SVG_PLOTTER();
|
||||
plotter->SetRenderSettings( aRenderSettings );
|
||||
plotter->SetPageSettings( pageInfo );
|
||||
plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
|
||||
//simplify the name if its single unit
|
||||
if( symbol->IsMulti() )
|
||||
{
|
||||
filename = wxString::Format( "%s_%d", symbol->GetName().Lower(), unit );
|
||||
|
||||
if( convert == 2 )
|
||||
filename += wxS( "_demorgan" );
|
||||
|
||||
fn.SetName( filename );
|
||||
wxPrintf( _( "Plotting symbol '%s' unit %d to '%s'\n" ), symbol->GetName(), unit,
|
||||
fn.GetFullPath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = symbol->GetName().Lower();
|
||||
|
||||
if( convert == 2 )
|
||||
filename += wxS( "_demorgan" );
|
||||
|
||||
wxPrintf( _( "Plotting symbol '%s' to '%s'\n" ), symbol->GetName(), fn.GetFullPath() );
|
||||
}
|
||||
|
||||
// Get the symbol bounding box to fit the plot page to it
|
||||
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, convert, false );
|
||||
PAGE_INFO pageInfo( PAGE_INFO::Custom );
|
||||
pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
|
||||
pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
|
||||
|
||||
SVG_PLOTTER* plotter = new SVG_PLOTTER();
|
||||
plotter->SetRenderSettings( aRenderSettings );
|
||||
plotter->SetPageSettings( pageInfo );
|
||||
plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
|
||||
|
||||
wxPoint plot_offset;
|
||||
const double scale = 1.0;
|
||||
|
||||
// Currently, plot units are in decimil
|
||||
plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
|
||||
// Currently, plot units are in decimil
|
||||
plotter->SetViewport( plot_offset, schIUScale.IU_PER_MILS / 10, scale, false );
|
||||
|
||||
plotter->SetCreator( wxT( "Eeschema-SVG" ) );
|
||||
plotter->SetCreator( wxT( "Eeschema-SVG" ) );
|
||||
|
||||
if( !plotter->OpenFile( fn.GetFullPath() ) )
|
||||
{
|
||||
wxFprintf( stderr, _( "Unable to open destination '%s'" ), fn.GetFullPath() );
|
||||
if( !plotter->OpenFile( fn.GetFullPath() ) )
|
||||
{
|
||||
wxFprintf( stderr, _( "Unable to open destination '%s'" ), fn.GetFullPath() );
|
||||
|
||||
delete plotter;
|
||||
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
|
||||
}
|
||||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
plotter->StartPlot( wxT( "1" ) );
|
||||
|
||||
bool background = true;
|
||||
TRANSFORM temp; // Uses default transform
|
||||
VECTOR2I plotPos;
|
||||
|
||||
plotPos.x = pageInfo.GetWidthIU( schIUScale.IU_PER_MILS ) / 2;
|
||||
plotPos.y = pageInfo.GetHeightIU( schIUScale.IU_PER_MILS ) / 2;
|
||||
|
||||
// note, we want the fields from the original symbol pointer (in case of non-alias)
|
||||
symbolToPlot->Plot( plotter, unit, convert, background, plotPos, temp, false );
|
||||
symbol->PlotLibFields( plotter, unit, convert, background, plotPos, temp, false,
|
||||
aSvgJob->m_includeHiddenFields );
|
||||
|
||||
symbolToPlot->Plot( plotter, unit, convert, !background, plotPos, temp, false );
|
||||
symbol->PlotLibFields( plotter, unit, convert, !background, plotPos, temp, false,
|
||||
aSvgJob->m_includeHiddenFields );
|
||||
|
||||
plotter->EndPlot();
|
||||
delete plotter;
|
||||
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
|
||||
}
|
||||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
plotter->StartPlot( wxT( "1" ) );
|
||||
|
||||
bool background = true;
|
||||
TRANSFORM temp; // Uses default transform
|
||||
VECTOR2I plotPos;
|
||||
|
||||
plotPos.x = pageInfo.GetWidthIU( schIUScale.IU_PER_MILS ) / 2;
|
||||
plotPos.y = pageInfo.GetHeightIU( schIUScale.IU_PER_MILS ) / 2;
|
||||
|
||||
// note, we want to use the fields from the original symbol pointer (in case of non-alias)
|
||||
symbolToPlot->Plot( plotter, unit, convert, background, plotPos, temp, false );
|
||||
symbol->PlotLibFields( plotter, unit, convert, background, plotPos, temp, false, aSvgJob->m_includeHiddenFields );
|
||||
|
||||
symbolToPlot->Plot( plotter, unit, convert, !background, plotPos, temp, false );
|
||||
symbol->PlotLibFields( plotter, unit, convert, !background, plotPos, temp, false, aSvgJob->m_includeHiddenFields );
|
||||
|
||||
plotter->EndPlot();
|
||||
delete plotter;
|
||||
}
|
||||
|
||||
return CLI::EXIT_CODES::OK;
|
||||
@@ -465,10 +482,12 @@ int EESCHEMA_JOBS_HANDLER::JobSymExportSvg( JOB* aJob )
|
||||
}
|
||||
|
||||
LIB_SYMBOL* symbol = nullptr;
|
||||
|
||||
if( !svgJob->m_symbol.IsEmpty() )
|
||||
{
|
||||
// See if the selected symbol exists
|
||||
symbol = schLibrary.GetSymbol( svgJob->m_symbol );
|
||||
|
||||
if( !symbol )
|
||||
{
|
||||
wxFprintf( stderr, _( "There is no symbol selected to save." ) );
|
||||
@@ -487,6 +506,7 @@ int EESCHEMA_JOBS_HANDLER::JobSymExportSvg( JOB* aJob )
|
||||
renderSettings.SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS );
|
||||
|
||||
int exitCode = CLI::EXIT_CODES::OK;
|
||||
|
||||
if( symbol )
|
||||
{
|
||||
exitCode = doSymExportSvg( svgJob, &renderSettings, symbol );
|
||||
@@ -499,6 +519,7 @@ int EESCHEMA_JOBS_HANDLER::JobSymExportSvg( JOB* aJob )
|
||||
for( const std::pair<const wxString, LIB_SYMBOL*>& entry : libSymMap )
|
||||
{
|
||||
exitCode = doSymExportSvg( svgJob, &renderSettings, entry.second );
|
||||
|
||||
if( exitCode != CLI::EXIT_CODES::OK )
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
|
||||
// LibEdit settings were stored with eeschema. If eeschema is the first app to run,
|
||||
// we need to migrate the LibEdit settings here
|
||||
|
||||
auto libedit = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>( false );
|
||||
auto libedit = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
|
||||
libedit->MigrateFromLegacy( aCfg );
|
||||
libedit->Load();
|
||||
|
||||
|
||||
+24
-10
@@ -147,7 +147,7 @@ int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
|
||||
// We have found a second sheet: compare names
|
||||
// we are using case insensitive comparison to avoid mistakes between
|
||||
// similar names like Mysheet and mysheet
|
||||
if( sheet->GetName().CmpNoCase( test_item->GetName() ) == 0 )
|
||||
if( sheet->GetShownName( false ).CmpNoCase( test_item->GetShownName( false ) ) == 0 )
|
||||
{
|
||||
if( aCreateMarker )
|
||||
{
|
||||
@@ -206,7 +206,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
|
||||
for( SCH_FIELD& field : symbol->GetFields() )
|
||||
{
|
||||
if( unresolved( field.GetShownText() ) )
|
||||
if( unresolved( field.GetShownText( true ) ) )
|
||||
{
|
||||
VECTOR2I pos = field.GetPosition() - symbol->GetPosition();
|
||||
pos = symbol->GetTransform().TransformCoordinate( pos );
|
||||
@@ -227,7 +227,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
|
||||
for( SCH_FIELD& field : subSheet->GetFields() )
|
||||
{
|
||||
if( unresolved( field.GetShownText() ) )
|
||||
if( unresolved( field.GetShownText( true ) ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
|
||||
@@ -240,7 +240,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
|
||||
for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
|
||||
{
|
||||
if( pin->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
if( pin->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
|
||||
@@ -253,7 +253,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
}
|
||||
else if( SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( item ) )
|
||||
{
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
|
||||
@@ -265,7 +265,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
}
|
||||
else if( SCH_TEXTBOX* textBox = dynamic_cast<SCH_TEXTBOX*>( item ) )
|
||||
{
|
||||
if( textBox->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
if( textBox->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
|
||||
@@ -281,7 +281,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
{
|
||||
if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
|
||||
{
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> erc = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
|
||||
erc->SetErrorMessage( _( "Unresolved text variable in drawing sheet" ) );
|
||||
@@ -824,13 +824,14 @@ int ERC_TESTER::TestSimilarLabels()
|
||||
{
|
||||
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
|
||||
|
||||
wxString normalized = label->GetShownText().Lower();
|
||||
wxString normalized = label->GetShownText( false ).Lower();
|
||||
|
||||
if( !labelMap.count( normalized ) )
|
||||
{
|
||||
labelMap[normalized] = label;
|
||||
}
|
||||
else if( labelMap.at( normalized )->GetShownText() != label->GetShownText() )
|
||||
else if( labelMap.at( normalized )->GetShownText( false )
|
||||
!= label->GetShownText( false) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMILAR_LABELS );
|
||||
ercItem->SetItems( label, labelMap.at( normalized ) );
|
||||
@@ -1030,15 +1031,28 @@ int ERC_TESTER::TestSimModelIssues()
|
||||
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
// Power symbols and other symbols which have the reference starting with "#" are
|
||||
// not included in simulation
|
||||
if( symbol->GetRef( &sheet ).StartsWith( '#' )
|
||||
|| symbol->GetFieldText( SIM_ENABLE_FIELD ) == wxT( "0" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reset for each symbol
|
||||
msg.Clear();
|
||||
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( &sheet, *symbol );
|
||||
|
||||
if( !msg.IsEmpty() )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMULATION_MODEL );
|
||||
|
||||
//Remove \n and \r at e.o.l if any:
|
||||
msg.Trim();
|
||||
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( symbol );
|
||||
|
||||
|
||||
+21
-30
@@ -287,44 +287,41 @@ void ERC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
{
|
||||
const RC_TREE_NODE* node = ToNode( aItem );
|
||||
const std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
|
||||
MARKER_BASE* marker = rcItem->GetParent();
|
||||
EDA_ITEM* item = nullptr;
|
||||
wxString msg;
|
||||
|
||||
switch( node->m_Type )
|
||||
{
|
||||
case RC_TREE_NODE::MARKER:
|
||||
{
|
||||
wxString prefix;
|
||||
|
||||
if( rcItem->GetParent() )
|
||||
if( marker )
|
||||
{
|
||||
SEVERITY severity = rcItem->GetParent()->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
|
||||
prefix = _( "Excluded warning: " );
|
||||
msg = _( "Excluded warning: " );
|
||||
else
|
||||
prefix = _( "Excluded error: " );
|
||||
msg = _( "Excluded error: " );
|
||||
}
|
||||
else if( severity == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
prefix = _( "Warning: " );
|
||||
msg = _( "Warning: " );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = _( "Error: " );
|
||||
msg = _( "Error: " );
|
||||
}
|
||||
}
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
}
|
||||
break;
|
||||
msg += rcItem->GetErrorMessage();
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::MAIN_ITEM:
|
||||
if( rcItem->GetParent()
|
||||
&& rcItem->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
if( marker && marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
|
||||
{
|
||||
aVariant = _( "Drawing Sheet" );
|
||||
break;
|
||||
msg = _( "Drawing Sheet" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,8 +335,8 @@ void ERC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
if( ercItem->MainItemHasSheetPath() )
|
||||
ercItem->GetMainItemSheetPath().UpdateAllScreenReferences();
|
||||
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
msg = item->GetItemDescription( m_editFrame );
|
||||
|
||||
// Reset reference fields to current visible sheet
|
||||
if( ercItem->MainItemHasSheetPath() )
|
||||
@@ -360,8 +357,8 @@ void ERC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
if( ercItem->AuxItemHasSheetPath() )
|
||||
ercItem->GetAuxItemSheetPath().UpdateAllScreenReferences();
|
||||
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
msg = item->GetItemDescription( m_editFrame );
|
||||
|
||||
// Reset reference fields to current visible sheet
|
||||
if( ercItem->AuxItemHasSheetPath() )
|
||||
@@ -370,17 +367,11 @@ void ERC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM2:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM3:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
aVariant = item->GetItemDescription( m_editFrame );
|
||||
}
|
||||
break;
|
||||
UNIMPLEMENTED_FOR( wxS( "AUX_ITEM2 or AUX_ITEM3" ) );
|
||||
break;
|
||||
}
|
||||
|
||||
msg.Replace( wxS( "\n" ), wxS( " " ) );
|
||||
aVariant = msg;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
|
||||
m_ERCSeverities[ERCE_MISSING_UNIT] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_MISSING_INPUT_PIN] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_MISSING_BIDI_PIN] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_SIMULATION_MODEL] = RPT_SEVERITY_IGNORE;
|
||||
|
||||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
|
||||
[&]() -> nlohmann::json
|
||||
|
||||
@@ -72,9 +72,9 @@ static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
|
||||
*/
|
||||
wxString netlist;
|
||||
|
||||
netlist << EscapeString( aSymbol->GetFootprintFieldText( true ), CTX_LINE ) << wxS( "\r" );
|
||||
netlist << EscapeString( aSymbol->GetFootprintFieldText( true, &aSheetPath, false ), CTX_LINE ) << wxS( "\r" );
|
||||
netlist << EscapeString( aSymbol->GetRef( &aSheetPath ), CTX_LINE ) << wxS( "\r" );
|
||||
netlist << EscapeString( aSymbol->GetValueFieldText( true ), CTX_LINE );
|
||||
netlist << EscapeString( aSymbol->GetValueFieldText( true, &aSheetPath, false ), CTX_LINE );
|
||||
|
||||
for( SCH_PIN* pin : aSymbol->GetPins( &aSheetPath ) )
|
||||
{
|
||||
|
||||
@@ -1105,8 +1105,7 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs )
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordERCExclusions(); // ensure ERC Exclusions list is up to date
|
||||
GetSettingsManager()->SaveProject();
|
||||
saveProjectSettings();
|
||||
}
|
||||
|
||||
if( !Kiface().IsSingle() )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -166,7 +166,7 @@ protected:
|
||||
switch( aField.GetId() )
|
||||
{
|
||||
case DATASHEET_FIELD:
|
||||
text = m_symbol->GetDatasheetField().GetShownText( 0, false );
|
||||
text = m_symbol->GetDatasheetField().GetShownText( false );
|
||||
|
||||
if( text.IsEmpty() || text == wxT( "~" ) )
|
||||
{
|
||||
@@ -197,7 +197,7 @@ protected:
|
||||
break;
|
||||
|
||||
default:
|
||||
text = aField.GetShownText( 0, false );
|
||||
text = aField.GetShownText( false );
|
||||
fieldhtml.Replace( wxS( "__VALUE__" ), EscapeHTML( text ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ void LIB_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOffs
|
||||
attrs.m_Angle = orient;
|
||||
attrs.m_Multiline = false;
|
||||
|
||||
aPlotter->PlotText( textpos, color, GetShownText(), attrs, font );
|
||||
aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font );
|
||||
}
|
||||
|
||||
|
||||
@@ -411,9 +411,9 @@ wxString LIB_FIELD::GetFullText( int unit ) const
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
|
||||
wxString LIB_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
|
||||
{
|
||||
wxString text = EDA_TEXT::GetShownText( aDepth );
|
||||
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
|
||||
|
||||
if( IsNameShown() )
|
||||
text = GetName() << wxT( ": " ) << text;
|
||||
@@ -516,7 +516,9 @@ void LIB_FIELD::SetName( const wxString& aName )
|
||||
|
||||
wxString LIB_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( "%s '%s'", GetName(), KIUI::EllipsizeMenuText( GetShownText() ) );
|
||||
return wxString::Format( "%s '%s'",
|
||||
UnescapeString( GetName() ),
|
||||
KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -538,10 +540,11 @@ void LIB_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||
|
||||
LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
aList.emplace_back( _( "Field" ), GetName() );
|
||||
// Don't use GetShownText(); we want to see the variable references here
|
||||
aList.emplace_back( _( "Field" ), UnescapeString( GetName() ) );
|
||||
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text" ), UnescapeString( GetText() ) );
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
*/
|
||||
wxString GetFullText( int unit = 1 ) const;
|
||||
|
||||
wxString GetShownText( int aDepth = 0, bool aAllowExtraText = true ) const override;
|
||||
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override;
|
||||
|
||||
SCH_LAYER_ID GetDefaultLayer() const;
|
||||
|
||||
|
||||
+11
-4
@@ -36,6 +36,8 @@
|
||||
#include <settings/color_settings.h>
|
||||
#include <lib_shape.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
// the separator char between the subpart id and the reference
|
||||
// 0 (no separator) or '.' or some other character
|
||||
int LIB_SYMBOL::m_subpartIdSeparator = 0;
|
||||
@@ -78,7 +80,7 @@ void LIB_SYMBOL::GetChooserFields( std::map<wxString , wxString>& aColumnMap )
|
||||
LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
|
||||
|
||||
if( field->ShowInChooser() )
|
||||
aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText();
|
||||
aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +467,7 @@ std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
|
||||
wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
|
||||
|
||||
// Copy the parent.
|
||||
retv.reset( new LIB_SYMBOL( *parent.get() ) );
|
||||
retv = std::make_unique<LIB_SYMBOL>( *parent.get() );
|
||||
|
||||
retv->m_name = m_name;
|
||||
retv->SetLibId( m_libId );
|
||||
@@ -512,11 +514,15 @@ std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
|
||||
retv->SetKeyWords( m_keyWords.IsEmpty() ? parent->GetKeyWords() : m_keyWords );
|
||||
retv->SetDescription( m_description.IsEmpty() ? parent->GetDescription() : m_description );
|
||||
retv->SetFPFilters( m_fpFilters.IsEmpty() ? parent->GetFPFilters() : m_fpFilters );
|
||||
|
||||
retv->SetIncludeInBom( parent->GetIncludeInBom() );
|
||||
retv->SetIncludeOnBoard( parent->GetIncludeOnBoard() );
|
||||
|
||||
retv->UpdateFieldOrdinals();
|
||||
}
|
||||
else
|
||||
{
|
||||
retv.reset( new LIB_SYMBOL( *this ) );
|
||||
retv = std::make_unique<LIB_SYMBOL>( *this );
|
||||
}
|
||||
|
||||
return retv;
|
||||
@@ -718,6 +724,7 @@ void LIB_SYMBOL::Plot( PLOTTER *aPlotter, int aUnit, int aConvert, bool aBackgro
|
||||
color.Desaturate( );
|
||||
color = color.Mix( bg, 0.5f );
|
||||
}
|
||||
|
||||
aPlotter->SetColor( color );
|
||||
|
||||
for( const LIB_ITEM& item : m_drawings )
|
||||
@@ -780,7 +787,7 @@ void LIB_SYMBOL::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, bool
|
||||
|
||||
// The reference is a special case: we should change the basic text
|
||||
// to add '?' and the part id
|
||||
wxString tmp = field.GetShownText();
|
||||
wxString tmp = field.GetShownText( true );
|
||||
|
||||
if( field.GetId() == REFERENCE_FIELD )
|
||||
{
|
||||
|
||||
@@ -406,8 +406,9 @@ void LIB_TEXT::print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
// Calculate pos according to mirror/rotation.
|
||||
txtpos = aTransform.TransformCoordinate( txtpos ) + aOffset;
|
||||
|
||||
GRPrintText( DC, txtpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER,
|
||||
GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), font );
|
||||
GRPrintText( DC, txtpos, color, GetShownText( true ), orient, GetTextSize(),
|
||||
GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(),
|
||||
font );
|
||||
}
|
||||
|
||||
|
||||
@@ -418,7 +419,7 @@ void LIB_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
|
||||
LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
|
||||
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text" ), UnescapeString( GetText() ) );
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
|
||||
|
||||
@@ -473,7 +474,7 @@ const BOX2I LIB_TEXT::GetBoundingBox() const
|
||||
|
||||
wxString LIB_TEXT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "Graphic Text '%s'" ), KIUI::EllipsizeMenuText( GetShownText() ) );
|
||||
return wxString::Format( _( "Graphic Text '%s'" ), KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -320,15 +320,15 @@ void LIB_TEXTBOX::print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffs
|
||||
text.SetStart( VECTOR2I( pt1.x, -pt1.y ) );
|
||||
text.SetEnd( VECTOR2I( pt2.x, -pt2.y ) );
|
||||
|
||||
GRPrintText( DC, text.GetDrawPos(), color, text.GetShownText(), text.GetTextAngle(),
|
||||
GRPrintText( DC, text.GetDrawPos(), color, text.GetShownText( true ), text.GetTextAngle(),
|
||||
text.GetTextSize(), text.GetHorizJustify(), text.GetVertJustify(), penWidth,
|
||||
text.IsItalic(), text.IsBold(), font );
|
||||
}
|
||||
|
||||
|
||||
wxString LIB_TEXTBOX::GetShownText( int aDepth, bool aAllowExtraText ) const
|
||||
wxString LIB_TEXTBOX::GetShownText( bool aAllowExtraText, int aDepth ) const
|
||||
{
|
||||
wxString text = EDA_TEXT::GetShownText();
|
||||
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
|
||||
|
||||
KIFONT::FONT* font = GetFont();
|
||||
VECTOR2D size = GetEnd() - GetStart();
|
||||
@@ -460,7 +460,7 @@ void LIB_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOf
|
||||
|
||||
std::vector<VECTOR2I> positions;
|
||||
wxArrayString strings_list;
|
||||
wxStringSplit( GetShownText(), strings_list, '\n' );
|
||||
wxStringSplit( GetShownText( true ), strings_list, '\n' );
|
||||
positions.reserve( strings_list.Count() );
|
||||
|
||||
text.GetLinePositions( positions, (int) strings_list.Count() );
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
VECTOR2I GetDrawPos() const override;
|
||||
|
||||
wxString GetShownText( int aDepth = 0, bool aAllowExtraText = true ) const override;
|
||||
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override;
|
||||
|
||||
void MirrorHorizontally( const VECTOR2I& center );
|
||||
void MirrorVertically( const VECTOR2I& center );
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
add_library(eeschema_navlib STATIC
|
||||
"nl_schematic_plugin.cpp"
|
||||
"nl_schematic_plugin_impl.cpp"
|
||||
)
|
||||
|
||||
# eeschema_navlib depends on make_lexer outputs in common
|
||||
add_dependencies( eeschema_navlib common )
|
||||
add_library(eeschema_navlib STATIC
|
||||
"nl_schematic_plugin.cpp"
|
||||
"nl_schematic_plugin_impl.cpp"
|
||||
)
|
||||
|
||||
# Find the 3DxWare SDK component 3DxWare::NlClient
|
||||
# find_package(TDxWare_SDK 4.0 REQUIRED COMPONENTS 3DxWare::Navlib)
|
||||
target_compile_definitions(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
target_compile_options(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_OPTIONS>
|
||||
)
|
||||
target_include_directories(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:eeschema_kiface_objects,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_link_libraries(eeschema_navlib
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
else()
|
||||
add_library(eeschema_navlib STATIC
|
||||
"nl_schematic_plugin.cpp"
|
||||
)
|
||||
endif(KICAD_USE_3DCONNEXION)
|
||||
# eeschema_navlib depends on make_lexer outputs in common
|
||||
add_dependencies( eeschema_navlib common )
|
||||
|
||||
# Find the 3DxWare SDK component 3DxWare::NlClient
|
||||
# find_package(TDxWare_SDK 4.0 REQUIRED COMPONENTS 3DxWare::Navlib)
|
||||
target_compile_definitions(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
target_compile_options(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_OPTIONS>
|
||||
)
|
||||
target_include_directories(eeschema_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:eeschema_kiface_objects,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_link_libraries(eeschema_navlib
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
|
||||
@@ -19,13 +19,17 @@
|
||||
*/
|
||||
|
||||
#include "nl_schematic_plugin.h"
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include <advanced_config.h>
|
||||
|
||||
#include "nl_schematic_plugin_impl.h"
|
||||
|
||||
|
||||
NL_SCHEMATIC_PLUGIN::NL_SCHEMATIC_PLUGIN() : m_impl( new NL_SCHEMATIC_PLUGIN_IMPL() )
|
||||
NL_SCHEMATIC_PLUGIN::NL_SCHEMATIC_PLUGIN()
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl = new NL_SCHEMATIC_PLUGIN_IMPL();
|
||||
else
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,33 +41,13 @@ NL_SCHEMATIC_PLUGIN::~NL_SCHEMATIC_PLUGIN()
|
||||
|
||||
void NL_SCHEMATIC_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
m_impl->SetFocus( focus );
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
|
||||
|
||||
void NL_SCHEMATIC_PLUGIN::SetCanvas( EDA_DRAW_PANEL_GAL* aViewport )
|
||||
{
|
||||
m_impl->SetCanvas( aViewport );
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl->SetCanvas( aViewport );
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
NL_SCHEMATIC_PLUGIN::NL_SCHEMATIC_PLUGIN()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NL_SCHEMATIC_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NL_SCHEMATIC_PLUGIN::SetCanvas( EDA_DRAW_PANEL_GAL* aViewport )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NL_SCHEMATIC_PLUGIN::~NL_SCHEMATIC_PLUGIN()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2017 jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.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
|
||||
@@ -117,13 +117,15 @@ std::vector<PIN_INFO> NETLIST_EXPORTER_BASE::CreatePinList( SCH_SYMBOL* aSymbol,
|
||||
SCH_SHEET_PATH* aSheetPath,
|
||||
bool aKeepUnconnectedPins )
|
||||
{
|
||||
wxString ref( aSymbol->GetRef( aSheetPath ) );
|
||||
std::vector<PIN_INFO> pins;
|
||||
|
||||
wxCHECK( aSymbol, pins );
|
||||
|
||||
wxString ref( aSymbol->GetRef( aSheetPath ) );
|
||||
|
||||
// Power symbols and other symbols which have the reference starting with "#" are not
|
||||
// included in netlist (pseudo or virtual symbols)
|
||||
|
||||
if( ref[0] == wxChar( '#' ) )
|
||||
if( ( ref[0] == wxChar( '#' ) ) || aSymbol->IsPower() )
|
||||
return pins;
|
||||
|
||||
// if( aSymbol->m_FlagControlMulti == 1 )
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2018 jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.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
|
||||
@@ -79,7 +79,7 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName,
|
||||
if( !symbol->GetIncludeOnBoard() )
|
||||
continue;
|
||||
|
||||
footprint = symbol->GetFootprintFieldText( true );
|
||||
footprint = symbol->GetFootprintFieldText( true, &sheetList[ i ], false );
|
||||
|
||||
if( footprint.IsEmpty() )
|
||||
footprint = "$noname";
|
||||
@@ -88,7 +88,7 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName,
|
||||
ret |= fprintf( f, "%s ", TO_UTF8( StartCmpDesc ) );
|
||||
ret |= fprintf( f, "%s", TO_UTF8( msg ) );
|
||||
|
||||
msg = symbol->GetValueFieldText( true );
|
||||
msg = symbol->GetValueFieldText( true, &sheetList[ i ], false );
|
||||
msg.Replace( wxT( " " ), wxT( "_" ) );
|
||||
ret |= fprintf( f, " \"%s\"", TO_UTF8( msg ) );
|
||||
ret |= fprintf( f, " \"%s\"", TO_UTF8( footprint ) );
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2018 jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.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
|
||||
@@ -88,7 +88,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
||||
sheet ) );
|
||||
}
|
||||
|
||||
footprint = symbol->GetFootprintFieldText( true );
|
||||
footprint = symbol->GetFootprintFieldText( true, &sheet, false );
|
||||
footprint.Replace( wxT( " " ), wxT( "_" ) );
|
||||
|
||||
if( footprint.IsEmpty() )
|
||||
@@ -102,7 +102,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
||||
|
||||
ret |= fprintf( f, " %s", TO_UTF8( field ) );
|
||||
|
||||
field = symbol->GetValueFieldText( true );
|
||||
field = symbol->GetValueFieldText( true, &sheet, false );
|
||||
field.Replace( wxT( " " ), wxT( "_" ) );
|
||||
|
||||
ret |= fprintf( f, " %s", TO_UTF8( field ) );
|
||||
|
||||
@@ -214,26 +214,19 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||
if( !symbol || symbol->GetFieldText( SIM_ENABLE_FIELD ) == wxT( "0" ) )
|
||||
continue;
|
||||
|
||||
SPICE_ITEM spiceItem;
|
||||
std::vector<PIN_INFO> pins = CreatePinList( symbol, &sheet, true );
|
||||
|
||||
SPICE_ITEM spiceItem;
|
||||
|
||||
for( int i = 0; i < symbol->GetFieldCount(); ++i )
|
||||
for( const SCH_FIELD& field : symbol->GetFields() )
|
||||
{
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), i, symbol,
|
||||
symbol->GetFields()[ i ].GetName() );
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, field.GetName() );
|
||||
|
||||
if( i == REFERENCE_FIELD )
|
||||
if( field.GetId() == REFERENCE_FIELD )
|
||||
spiceItem.fields.back().SetText( symbol->GetRef( &sheet ) );
|
||||
else
|
||||
spiceItem.fields.back().SetText( symbol->GetFields()[i].GetShownText( 0, false ) );
|
||||
spiceItem.fields.back().SetText( field.GetShownText( &sheet, false ) );
|
||||
}
|
||||
|
||||
wxString deviceType;
|
||||
wxString modelType;
|
||||
wxString modelParams;
|
||||
wxString pinMap;
|
||||
|
||||
readRefName( sheet, *symbol, spiceItem, refNames );
|
||||
readModel( sheet, *symbol, spiceItem );
|
||||
readPinNumbers( *symbol, spiceItem, pins );
|
||||
@@ -340,9 +333,9 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||
{
|
||||
if( item->Type() == SCH_TEXT_T )
|
||||
text = static_cast<SCH_TEXT*>( item )->GetShownText();
|
||||
text = static_cast<SCH_TEXT*>( item )->GetShownText( &sheet, false );
|
||||
else if( item->Type() == SCH_TEXTBOX_T )
|
||||
text = static_cast<SCH_TEXTBOX*>( item )->GetShownText();
|
||||
text = static_cast<SCH_TEXTBOX*>( item )->GetShownText( &sheet, false );
|
||||
else
|
||||
continue;
|
||||
|
||||
@@ -481,10 +474,9 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
|
||||
|
||||
if( !cacheFile.IsOpened() )
|
||||
{
|
||||
DisplayErrorMessage( m_dialogParent,
|
||||
wxString::Format( _( "Could not open file '%s' to write "
|
||||
"IBIS model" ),
|
||||
cacheFn.GetFullPath() ) );
|
||||
DisplayErrorMessage( m_dialogParent, wxString::Format( _( "Could not open file '%s' "
|
||||
"to write IBIS model" ),
|
||||
cacheFn.GetFullPath() ) );
|
||||
}
|
||||
|
||||
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
|
||||
@@ -536,9 +528,9 @@ void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned
|
||||
|
||||
if( fullPath.IsEmpty() )
|
||||
{
|
||||
DisplayErrorMessage( m_dialogParent,
|
||||
wxString::Format( _( "Could not find library file '%s'" ),
|
||||
expandedPath ) );
|
||||
DisplayErrorMessage( m_dialogParent, wxString::Format( _( "Could not find library file "
|
||||
"'%s'" ),
|
||||
expandedPath ) );
|
||||
fullPath = expandedPath;
|
||||
}
|
||||
else if( wxFileName::GetPathSeparator() == '\\' )
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.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
|
||||
@@ -127,18 +127,19 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
||||
int unit = symbol2->GetUnitSelection( aSheet );
|
||||
|
||||
// The lowest unit number wins. User should only set fields in any one unit.
|
||||
candidate = symbol2->GetValueFieldText( m_resolveTextVars );
|
||||
candidate = symbol2->GetValueFieldText( m_resolveTextVars, &sheetList[i], false );
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
|
||||
value = candidate;
|
||||
|
||||
candidate = symbol2->GetFootprintFieldText( m_resolveTextVars );
|
||||
candidate = symbol2->GetFootprintFieldText( m_resolveTextVars, &sheetList[i], false );
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
|
||||
footprint = candidate;
|
||||
|
||||
candidate = m_resolveTextVars ? symbol2->GetField( DATASHEET_FIELD )->GetShownText()
|
||||
: symbol2->GetField( DATASHEET_FIELD )->GetText();
|
||||
candidate = m_resolveTextVars
|
||||
? symbol2->GetField( DATASHEET_FIELD )->GetShownText( &sheetList[i], false )
|
||||
: symbol2->GetField( DATASHEET_FIELD )->GetText();
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || datasheet.IsEmpty() ) )
|
||||
datasheet = candidate;
|
||||
@@ -151,7 +152,7 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
||||
&& ( unit < minUnit || userFields.count( f.GetName() ) == 0 ) )
|
||||
{
|
||||
if( m_resolveTextVars )
|
||||
userFields[ f.GetName() ] = f.GetShownText();
|
||||
userFields[ f.GetName() ] = f.GetShownText( aSheet, false );
|
||||
else
|
||||
userFields[ f.GetName() ] = f.GetText();
|
||||
}
|
||||
@@ -163,11 +164,11 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
||||
}
|
||||
else
|
||||
{
|
||||
value = aSymbol->GetValueFieldText( m_resolveTextVars );
|
||||
footprint = aSymbol->GetFootprintFieldText( m_resolveTextVars );
|
||||
value = aSymbol->GetValueFieldText( m_resolveTextVars, aSheet, false );
|
||||
footprint = aSymbol->GetFootprintFieldText( m_resolveTextVars, aSheet, false );
|
||||
|
||||
if( m_resolveTextVars )
|
||||
datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetShownText();
|
||||
datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetShownText( aSheet, false );
|
||||
else
|
||||
datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetText();
|
||||
|
||||
@@ -178,7 +179,7 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
||||
if( f.GetText().size() )
|
||||
{
|
||||
if( m_resolveTextVars )
|
||||
userFields[ f.GetName() ] = f.GetShownText();
|
||||
userFields[ f.GetName() ] = f.GetShownText( aSheet, false );
|
||||
else
|
||||
userFields[ f.GetName() ] = f.GetText();
|
||||
}
|
||||
@@ -221,6 +222,7 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
|
||||
m_libParts.clear();
|
||||
|
||||
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
|
||||
SCH_SHEET_PATH currentSheet = m_schematic->CurrentSheet();
|
||||
|
||||
// Output is xml, so there is no reason to remove spaces from the field values.
|
||||
// And XML element names need not be translated to various languages.
|
||||
@@ -229,6 +231,10 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
|
||||
{
|
||||
SCH_SHEET_PATH sheet = sheetList[ii];
|
||||
|
||||
// Change schematic CurrentSheet in each iteration to allow hierarchical
|
||||
// resolution of text variables in sheet fields.
|
||||
m_schematic->SetCurrentSheet( sheet );
|
||||
|
||||
auto cmp = [sheet]( SCH_SYMBOL* a, SCH_SYMBOL* b )
|
||||
{
|
||||
return ( StrNumCmp( a->GetRef( &sheet, false ),
|
||||
@@ -315,7 +321,7 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
|
||||
xproperty->AddAttribute( wxT( "name" ), fields[jj].GetCanonicalName() );
|
||||
|
||||
if( m_resolveTextVars )
|
||||
xproperty->AddAttribute( wxT( "value" ), fields[jj].GetShownText() );
|
||||
xproperty->AddAttribute( wxT( "value" ), fields[jj].GetShownText( &sheet, false ) );
|
||||
else
|
||||
xproperty->AddAttribute( wxT( "value" ), fields[jj].GetText() );
|
||||
}
|
||||
@@ -328,7 +334,7 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
|
||||
if( m_resolveTextVars )
|
||||
// do not allow GetShownText() to add any prefix useful only when displaying
|
||||
// the field on screen
|
||||
xproperty->AddAttribute( wxT( "value" ), sheetField.GetShownText( 0, false ) );
|
||||
xproperty->AddAttribute( wxT( "value" ), sheetField.GetShownText( &sheet, false ) );
|
||||
else
|
||||
xproperty->AddAttribute( wxT( "value" ), sheetField.GetText() );
|
||||
}
|
||||
@@ -399,6 +405,8 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl )
|
||||
}
|
||||
}
|
||||
|
||||
m_schematic->SetCurrentSheet( currentSheet );
|
||||
|
||||
return xcomps;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <common.h> // for ProcessExecute
|
||||
#include <string_utils.h>
|
||||
#include <gestfich.h>
|
||||
@@ -52,6 +53,10 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
|
||||
if( !ReadyToNetlist( _( "Exporting netlist requires a fully annotated schematic." ) ) )
|
||||
return false;
|
||||
|
||||
// If we are using the new connectivity, make sure that we do a full-rebuild
|
||||
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
|
||||
RecalculateConnections( GLOBAL_CLEANUP );
|
||||
|
||||
bool res = true;
|
||||
bool executeCommandLine = false;
|
||||
|
||||
|
||||
@@ -62,12 +62,11 @@ for group in grouped:
|
||||
# Add the reference of every component in the group and keep a reference
|
||||
# to the component so that the other data can be filled in once per group
|
||||
for component in group:
|
||||
refs += fromNetlistText( component.getRef() ) + ", "
|
||||
if refs != "":
|
||||
refs += ", "
|
||||
refs += fromNetlistText( component.getRef() )
|
||||
c = component
|
||||
|
||||
# remove last, not needed trailing comma and whitespace
|
||||
refs = refs.removesuffix(', ')
|
||||
|
||||
# Fill in the component groups common data
|
||||
out.writerow([refs, len(group),
|
||||
fromNetlistText( c.getValue() ),
|
||||
|
||||
+15
-31
@@ -22,6 +22,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <base_units.h>
|
||||
#include <kiway.h>
|
||||
#include <lib_tree_model_adapter.h>
|
||||
@@ -46,9 +47,7 @@
|
||||
#include <tools/ee_selection_tool.h>
|
||||
#include <wx/choicdlg.h>
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include <navlib/nl_schematic_plugin.h>
|
||||
#endif
|
||||
|
||||
LIB_SYMBOL* SchGetLibSymbol( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
|
||||
SYMBOL_LIB* aCacheLib, wxWindow* aParent, bool aShowErrorMsg )
|
||||
@@ -90,10 +89,7 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo
|
||||
const wxSize& aSize, long aStyle, const wxString& aFrameName ) :
|
||||
EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle,
|
||||
aFrameName, schIUScale ),
|
||||
m_base_frame_defaults( nullptr, "base_Frame_defaults" )
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
,m_spaceMouse( nullptr )
|
||||
#endif
|
||||
m_base_frame_defaults( nullptr, "base_Frame_defaults" ), m_spaceMouse( nullptr )
|
||||
{
|
||||
createCanvas();
|
||||
|
||||
@@ -115,10 +111,7 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo
|
||||
|
||||
SCH_BASE_FRAME::~SCH_BASE_FRAME()
|
||||
{
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
delete m_spaceMouse;
|
||||
#endif
|
||||
delete m_spaceMouse;
|
||||
}
|
||||
|
||||
|
||||
@@ -349,21 +342,20 @@ void SCH_BASE_FRAME::ActivateGalCanvas()
|
||||
{
|
||||
EDA_DRAW_FRAME::ActivateGalCanvas();
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
try
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
if( !m_spaceMouse )
|
||||
try
|
||||
{
|
||||
m_spaceMouse = new NL_SCHEMATIC_PLUGIN();
|
||||
}
|
||||
if( !m_spaceMouse )
|
||||
m_spaceMouse = new NL_SCHEMATIC_PLUGIN();
|
||||
|
||||
m_spaceMouse->SetCanvas( GetCanvas() );
|
||||
m_spaceMouse->SetCanvas( GetCanvas() );
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -538,12 +530,8 @@ void SCH_BASE_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
|
||||
{
|
||||
EDA_DRAW_FRAME::handleActivateEvent( aEvent );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse )
|
||||
{
|
||||
if( m_spaceMouse && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -551,12 +539,8 @@ void SCH_BASE_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||
{
|
||||
EDA_DRAW_FRAME::handleIconizeEvent( aEvent );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse && aEvent.IsIconized() )
|
||||
{
|
||||
if( m_spaceMouse && aEvent.IsIconized() && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_spaceMouse->SetFocus( false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -270,9 +270,7 @@ protected:
|
||||
SCHEMATIC_SETTINGS m_base_frame_defaults;
|
||||
|
||||
private:
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
NL_SCHEMATIC_PLUGIN* m_spaceMouse;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // SCH_BASE_FRAME_H_
|
||||
|
||||
@@ -1016,22 +1016,25 @@ void SCH_EDIT_FRAME::ShowFindReplaceDialog( bool aReplace )
|
||||
switch( front->Type() )
|
||||
{
|
||||
case SCH_SYMBOL_T:
|
||||
findString = static_cast<SCH_SYMBOL*>( front )->GetValueFieldText( true );
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( front );
|
||||
findString = UnescapeString( symbol->GetField( VALUE_FIELD )->GetText() );
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_FIELD_T:
|
||||
findString = static_cast<SCH_FIELD*>( front )->GetShownText();
|
||||
findString = UnescapeString( static_cast<SCH_FIELD*>( front )->GetText() );
|
||||
break;
|
||||
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
findString = static_cast<SCH_LABEL_BASE*>( front )->GetShownText();
|
||||
findString = UnescapeString( static_cast<SCH_LABEL_BASE*>( front )->GetText() );
|
||||
break;
|
||||
|
||||
case SCH_TEXT_T:
|
||||
findString = static_cast<SCH_TEXT*>( front )->GetShownText();
|
||||
findString = UnescapeString( static_cast<SCH_TEXT*>( front )->GetText() );
|
||||
|
||||
if( findString.Contains( wxT( "\n" ) ) )
|
||||
findString = findString.Before( '\n' );
|
||||
@@ -1046,9 +1049,10 @@ void SCH_EDIT_FRAME::ShowFindReplaceDialog( bool aReplace )
|
||||
if( m_findReplaceDialog )
|
||||
m_findReplaceDialog->Destroy();
|
||||
|
||||
m_findReplaceDialog = new DIALOG_SCH_FIND(
|
||||
this, static_cast<SCH_SEARCH_DATA*>( m_findReplaceData.get() ), wxDefaultPosition,
|
||||
wxDefaultSize, aReplace ? wxFR_REPLACEDIALOG : 0 );
|
||||
m_findReplaceDialog = new DIALOG_SCH_FIND( this,
|
||||
static_cast<SCH_SEARCH_DATA*>( m_findReplaceData.get() ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
aReplace ? wxFR_REPLACEDIALOG : 0 );
|
||||
|
||||
m_findReplaceDialog->SetFindEntries( m_findStringHistoryList, findString );
|
||||
m_findReplaceDialog->SetReplaceEntries( m_replaceStringHistoryList );
|
||||
@@ -1479,7 +1483,85 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
GetCanvas()->GetView()->Update( aChangedItem, KIGFX::REPAINT );
|
||||
};
|
||||
|
||||
Schematic().ConnectionGraph()->Recalculate( list, true, &changeHandler );
|
||||
if( !ADVANCED_CFG::GetCfg().m_IncrementalConnectivity || aCleanupFlags == GLOBAL_CLEANUP
|
||||
|| m_undoList.m_CommandsList.empty() )
|
||||
{
|
||||
Schematic().ConnectionGraph()->Recalculate( list, true, &changeHandler );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& changed_list = m_undoList.m_CommandsList.back();
|
||||
std::set<SCH_ITEM*> changed_items;
|
||||
std::vector<VECTOR2I> pts;
|
||||
|
||||
for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii )
|
||||
{
|
||||
EDA_ITEM* item = changed_list->GetPickedItem( ii );
|
||||
|
||||
if( !item || !IsEeschemaType( item->Type() ) )
|
||||
continue;
|
||||
|
||||
SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( item );
|
||||
|
||||
std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
|
||||
pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
|
||||
changed_items.insert( sch_item );
|
||||
}
|
||||
|
||||
for( VECTOR2I& pt: pts )
|
||||
{
|
||||
for( SCH_ITEM* item : GetScreen()->Items().Overlapping(pt ) )
|
||||
{
|
||||
if( !item->IsConnectable() )
|
||||
continue;
|
||||
|
||||
if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
|
||||
{
|
||||
if( line->HitTest( pt ) )
|
||||
{
|
||||
changed_items.insert( item );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( SCH_SYMBOL* sym = dyn_cast<SCH_SYMBOL*>( item ) )
|
||||
{
|
||||
std::vector<SCH_PIN*> pins = sym->GetPins();
|
||||
changed_items.insert( pins.begin(), pins.end() );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( item->IsConnected( pt ) )
|
||||
changed_items.insert( item );
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
|
||||
Schematic().ConnectionGraph()->ExtractAffectedItems(
|
||||
changed_items );
|
||||
|
||||
CONNECTION_GRAPH new_graph( &Schematic() );
|
||||
|
||||
new_graph.SetLastCodes( Schematic().ConnectionGraph() );
|
||||
|
||||
for( auto&[ path, item ] : all_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_FIELD_T:
|
||||
case SCH_PIN_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
static_cast<SCH_ITEM*>( item->GetParent() )->SetConnectivityDirty();
|
||||
break;
|
||||
|
||||
default:
|
||||
item->SetConnectivityDirty();
|
||||
}
|
||||
}
|
||||
|
||||
new_graph.Recalculate( list, false, &changeHandler );
|
||||
Schematic().ConnectionGraph()->Merge( new_graph );
|
||||
}
|
||||
|
||||
GetCanvas()->GetView()->UpdateAllItemsConditionally(
|
||||
[&]( KIGFX::VIEW_ITEM* aItem ) -> int
|
||||
@@ -1838,7 +1920,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
||||
|
||||
SCH_BASE_FRAME::SetScreen( screen );
|
||||
|
||||
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
|
||||
m_toolManager->ResetTools( TOOL_BASE::REDRAW );
|
||||
|
||||
// update the References
|
||||
GetCurrentSheet().UpdateAllScreenReferences();
|
||||
|
||||
+22
-20
@@ -172,12 +172,14 @@ void SCH_FIELD::SetId( int aId )
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
|
||||
wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
|
||||
int aDepth ) const
|
||||
{
|
||||
std::function<bool( wxString* )> symbolResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
return static_cast<SCH_SYMBOL*>( m_parent )->ResolveTextVar( token, aDepth + 1 );
|
||||
return static_cast<SCH_SYMBOL*>( m_parent )->ResolveTextVar( token, aDepth + 1,
|
||||
aPath );
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> sheetResolver =
|
||||
@@ -189,13 +191,13 @@ wxString SCH_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
|
||||
std::function<bool( wxString* )> labelResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
return static_cast<SCH_LABEL_BASE*>( m_parent )->ResolveTextVar( token,
|
||||
return static_cast<SCH_LABEL_BASE*>( m_parent )->ResolveTextVar( aPath, token,
|
||||
aDepth + 1 );
|
||||
};
|
||||
|
||||
wxString text = EDA_TEXT::GetShownText();
|
||||
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
|
||||
|
||||
if( IsNameShown() )
|
||||
if( IsNameShown() && aAllowExtraText )
|
||||
text = GetName() << wxS( ": " ) << text;
|
||||
|
||||
if( text == wxS( "~" ) ) // Legacy placeholder for empty string
|
||||
@@ -321,7 +323,7 @@ void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset
|
||||
VECTOR2I textpos;
|
||||
int penWidth = GetEffectiveTextPenWidth( aSettings->GetDefaultPenWidth() );
|
||||
|
||||
if( ( !IsVisible() && !IsForceVisible() ) || GetShownText().IsEmpty() )
|
||||
if( ( !IsVisible() && !IsForceVisible() ) || GetShownText( true ).IsEmpty() )
|
||||
return;
|
||||
|
||||
COLOR4D bg = aSettings->GetBackgroundColor();
|
||||
@@ -374,8 +376,9 @@ void SCH_FIELD::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset
|
||||
*/
|
||||
textpos = GetBoundingBox().Centre() + aOffset;
|
||||
|
||||
GRPrintText( DC, textpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_H_ALIGN_CENTER,
|
||||
GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(), font );
|
||||
GRPrintText( DC, textpos, color, GetShownText( true ), orient, GetTextSize(),
|
||||
GR_TEXT_H_ALIGN_CENTER, GR_TEXT_V_ALIGN_CENTER, penWidth, IsItalic(), IsBold(),
|
||||
font );
|
||||
}
|
||||
|
||||
|
||||
@@ -579,7 +582,7 @@ bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) co
|
||||
{
|
||||
}
|
||||
|
||||
wxString text = GetShownText();
|
||||
wxString text = UnescapeString( GetText() );
|
||||
|
||||
if( !IsVisible() && !searchHiddenFields )
|
||||
return false;
|
||||
@@ -596,7 +599,7 @@ bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) co
|
||||
// symbols with multiple parts.
|
||||
if( aAuxData )
|
||||
{
|
||||
text = parentSymbol->GetRef((SCH_SHEET_PATH*) aAuxData );
|
||||
text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
|
||||
|
||||
if( SCH_ITEM::Matches( text, aSearchData ) )
|
||||
return true;
|
||||
@@ -652,7 +655,6 @@ bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
|
||||
}
|
||||
|
||||
wxString text;
|
||||
bool resolve = false; // Replace in source text, not shown text
|
||||
bool isReplaced = false;
|
||||
|
||||
if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
|
||||
@@ -678,7 +680,7 @@ bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
|
||||
case VALUE_FIELD:
|
||||
wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in value field." ) );
|
||||
|
||||
text = parentSymbol->GetValueFieldText( resolve );
|
||||
text = parentSymbol->GetField( VALUE_FIELD )->GetText();
|
||||
isReplaced = EDA_ITEM::Replace( aSearchData, text );
|
||||
|
||||
if( isReplaced )
|
||||
@@ -689,7 +691,7 @@ bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
|
||||
case FOOTPRINT_FIELD:
|
||||
wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in footprint field." ) );
|
||||
|
||||
text = parentSymbol->GetFootprintFieldText( resolve );
|
||||
text = parentSymbol->GetField( FOOTPRINT_FIELD )->GetText();
|
||||
isReplaced = EDA_ITEM::Replace( aSearchData, text );
|
||||
|
||||
if( isReplaced )
|
||||
@@ -731,7 +733,7 @@ void SCH_FIELD::Rotate( const VECTOR2I& aCenter )
|
||||
|
||||
wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( "%s '%s'", GetName(), KIUI::EllipsizeMenuText( GetShownText() ) );
|
||||
return wxString::Format( "%s '%s'", GetName(), KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -739,10 +741,10 @@ void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
aList.emplace_back( _( "Symbol Field" ), GetName() );
|
||||
aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
|
||||
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text" ), UnescapeString( GetText() ) );
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
|
||||
|
||||
@@ -910,7 +912,7 @@ BITMAPS SCH_FIELD::GetMenuImage() const
|
||||
bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
{
|
||||
// Do not hit test hidden or empty fields.
|
||||
if( !IsVisible() || GetShownText().IsEmpty() )
|
||||
if( !IsVisible() || GetShownText( true ).IsEmpty() )
|
||||
return false;
|
||||
|
||||
BOX2I rect = GetBoundingBox();
|
||||
@@ -930,7 +932,7 @@ bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
|
||||
{
|
||||
// Do not hit test hidden fields.
|
||||
if( !IsVisible() || GetShownText().IsEmpty() )
|
||||
if( !IsVisible() || GetShownText( true ).IsEmpty() )
|
||||
return false;
|
||||
|
||||
BOX2I rect = aRect;
|
||||
@@ -952,7 +954,7 @@ bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
||||
|
||||
void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
||||
{
|
||||
if( GetShownText().IsEmpty() || aBackground )
|
||||
if( GetShownText( true ).IsEmpty() || aBackground )
|
||||
return;
|
||||
|
||||
RENDER_SETTINGS* settings = aPlotter->RenderSettings();
|
||||
@@ -1032,7 +1034,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
||||
attrs.m_Angle = orient;
|
||||
attrs.m_Multiline = false;
|
||||
|
||||
aPlotter->PlotText( textpos, color, GetShownText(), attrs, font );
|
||||
aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font );
|
||||
|
||||
if( IsHypertext() )
|
||||
{
|
||||
|
||||
@@ -126,7 +126,13 @@ public:
|
||||
|
||||
void SetId( int aId );
|
||||
|
||||
wxString GetShownText( int aDepth = 0, bool aAllowExtraText = true ) const override;
|
||||
wxString GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
|
||||
int aDepth = 0 ) const;
|
||||
|
||||
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override
|
||||
{
|
||||
return GetShownText( nullptr, aAllowExtraText, aDepth );
|
||||
}
|
||||
|
||||
COLOR4D GetFieldColor() const;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user