Compare commits
156 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fa2ccdd083 | |||
| 4096c073b7 | |||
| 2ad3ccc4d8 | |||
| 3bab589405 | |||
| fab52bd95a | |||
| 27e4b2276b | |||
| 64f8310a94 | |||
| e765de6b3d | |||
| 742529da26 | |||
| b728eae651 | |||
| 676e70ec18 | |||
| 13fabb0564 | |||
| 4dc4b2bd51 | |||
| 32e6f424ec | |||
| 3890278505 | |||
| 1664e02fa6 | |||
| 63ffca0173 | |||
| ff4b59afeb | |||
| 64382a85fa | |||
| 4c51391cf6 | |||
| 5add7a0ca0 | |||
| 8340779f5b | |||
| 01cc91850c | |||
| 091f9c82e1 | |||
| f7ddd211d9 | |||
| 8dce6c0b67 | |||
| 655cee523b | |||
| fa4d759fcb | |||
| 25b033df2a | |||
| a0905ac87d | |||
| 3d67ab72c6 | |||
| ecb0c9b5d4 | |||
| 53d8e2c8c3 | |||
| 22f66fdf2f | |||
| a7c09964ba | |||
| 1e03266dfe | |||
| 09f32d8c86 | |||
| 67208df602 | |||
| 8047eed6f8 | |||
| dafd62ddba | |||
| 41f9baf9dc | |||
| 1cd5827078 | |||
| b07d43a24a | |||
| 985c3ad92a | |||
| 978fa63490 | |||
| c59fac4089 | |||
| 0dab086f0c | |||
| 7d1adff071 | |||
| 38df918993 | |||
| f45df48498 | |||
| 898b5bd992 | |||
| 100023e36f | |||
| d8ca6eda7e | |||
| 4d02817415 | |||
| ef281317ee | |||
| 16ea51fe5c | |||
| b70ff8a120 | |||
| b3572c4ba2 | |||
| b8859df610 | |||
| a26ed45b55 | |||
| cd3c2899d8 | |||
| 74f1fadcf2 | |||
| 6de3859d2c | |||
| 04440d8506 | |||
| 9508b79cc3 | |||
| bec068324e | |||
| b4e993e6e8 | |||
| 57b9b1b6b6 | |||
| fce4ec6a9b | |||
| c4a7af8a47 | |||
| d359fb8ab9 | |||
| 5618a6925d | |||
| e383c67e7f | |||
| 12dcdc8bbe | |||
| bbd4cfd3d4 | |||
| a9e6031ae6 | |||
| 0b5c0ef639 | |||
| 60dbd0ce0d | |||
| 1fc79b9a46 | |||
| aba24ec781 | |||
| 952c154422 | |||
| ffa1d19216 | |||
| 5b303b268f | |||
| 50c5b56781 | |||
| 35192f5bd4 | |||
| d84a5e6f03 | |||
| d94b0771ca | |||
| 2f8f7c11f1 | |||
| 81c22542e4 | |||
| c1755835eb | |||
| 11593a7c04 | |||
| 46555ab975 | |||
| 74339e9a9f | |||
| 2b09653abb | |||
| 1c639714f3 | |||
| 45910bc7c1 | |||
| 87944e06ac | |||
| b37c7afa8a | |||
| 5713384f35 | |||
| 99f9941067 | |||
| 339646a267 | |||
| 97ff48b426 | |||
| badc4e7411 | |||
| 764de7257f | |||
| 14d71c8ca6 | |||
| 7d5583f687 | |||
| ffd470d94d | |||
| 0184dfb625 | |||
| 711c6141a8 | |||
| fdf38256e8 | |||
| 7eeb1a19cf | |||
| e68df8e1d1 | |||
| 3e26e7b646 | |||
| a13e4e7d9f | |||
| 6feafedfbe | |||
| ed115075ce | |||
| be51c2ba73 | |||
| 78b38cc75f | |||
| c8495d81bb | |||
| 6aaf2411f6 | |||
| 3f47e03317 | |||
| 9004f92689 | |||
| a928299ae0 | |||
| 1a7237f38b | |||
| b3b6637b44 | |||
| ad311c33c6 | |||
| adae4de438 | |||
| c8b06d54cb | |||
| 51848a0b43 | |||
| 2d7f4faf72 | |||
| c75bb5d01a | |||
| df8f043c16 | |||
| 01d668c09d | |||
| f4a3613561 | |||
| 12922d9434 | |||
| b6036f368e | |||
| 25291d6e3a | |||
| f4a085575a | |||
| a34b242f4e | |||
| 8a3cbce8f8 | |||
| a9c4a17c38 | |||
| 1a7152d3eb | |||
| 08da9a4494 | |||
| baaed8ed84 | |||
| 7446fba70a | |||
| d36f189192 | |||
| 152c458b9c | |||
| 7ae14f9630 | |||
| a610542a19 | |||
| 2ab492474e | |||
| 3caede3799 | |||
| 9d40374baf | |||
| 0ead8a14a1 | |||
| e8b16fc64f | |||
| 162e8962f7 | |||
| fc66cb6805 |
@@ -530,7 +530,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
m_boardBoundingBox = BBOX_3D( boardMin, boardMax );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
int64_t stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -589,13 +589,18 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
std::map<int, COLOR4D> colors;
|
||||
|
||||
if( m_Cfg->m_CurrentPreset == FOLLOW_PCB || m_Cfg->m_CurrentPreset == FOLLOW_PLOT_SETTINGS )
|
||||
if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
colors = GetDefaultColors();
|
||||
|
||||
if( !m_board )
|
||||
return colors;
|
||||
colors = preset->colors;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( const auto& [ layer, color ] : GetDefaultColors() )
|
||||
colors[ layer ] = color;
|
||||
}
|
||||
|
||||
if( m_Cfg->m_UseStackupColors && m_board )
|
||||
{
|
||||
const BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
|
||||
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
|
||||
|
||||
@@ -683,26 +688,6 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Silver" ), g_FinishColors );
|
||||
}
|
||||
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
PCBNEW_SETTINGS* pcbnewSettings = mgr.GetAppSettings<PCBNEW_SETTINGS>();
|
||||
COLOR_SETTINGS* pcbnewColors = mgr.GetColorSettings( pcbnewSettings->m_ColorTheme );
|
||||
|
||||
colors[ LAYER_3D_USER_DRAWINGS ] = pcbnewColors->GetColor( Dwgs_User );
|
||||
colors[ LAYER_3D_USER_COMMENTS ] = pcbnewColors->GetColor( Cmts_User );
|
||||
colors[ LAYER_3D_USER_ECO1 ] = pcbnewColors->GetColor( Eco1_User );
|
||||
colors[ LAYER_3D_USER_ECO2 ] = pcbnewColors->GetColor( Eco2_User );
|
||||
}
|
||||
else if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
return preset->colors;
|
||||
}
|
||||
else
|
||||
{
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
for( const auto& [ layer, color ] : GetDefaultColors() )
|
||||
colors[ layer ] = settings->GetColor( layer );
|
||||
}
|
||||
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = colors[ LAYER_3D_COPPER_TOP ];
|
||||
@@ -860,6 +845,42 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
}
|
||||
|
||||
|
||||
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
|
||||
{
|
||||
std::bitset<LAYER_3D_END> ret;
|
||||
|
||||
ret.set( LAYER_3D_BOARD, true );
|
||||
ret.set( LAYER_3D_COPPER_TOP, true );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, true );
|
||||
ret.set( LAYER_3D_ADHESIVE, true );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, false );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, false );
|
||||
ret.set( LAYER_3D_USER_ECO1, false );
|
||||
ret.set( LAYER_3D_USER_ECO2, false );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, true );
|
||||
ret.set( LAYER_FP_VALUES, true );
|
||||
ret.set( LAYER_FP_TEXT, true );
|
||||
|
||||
ret.set( LAYER_3D_TH_MODELS, true );
|
||||
ret.set( LAYER_3D_SMD_MODELS, true );
|
||||
ret.set( LAYER_3D_VIRTUAL_MODELS, true );
|
||||
ret.set( LAYER_3D_MODELS_NOT_IN_POS, false );
|
||||
ret.set( LAYER_3D_MODELS_MARKED_DNP, false );
|
||||
|
||||
ret.set( LAYER_3D_BOUNDING_BOXES, false );
|
||||
ret.set( LAYER_3D_OFF_BOARD_SILK, false );
|
||||
ret.set( LAYER_3D_AXES, true );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
{
|
||||
m_board_poly.RemoveAllContours();
|
||||
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
void SetLayerColors( const std::map<int, COLOR4D>& aColors );
|
||||
|
||||
std::bitset<LAYER_3D_END> GetVisibleLayers() const;
|
||||
std::bitset<LAYER_3D_END> GetDefaultVisibleLayers() const;
|
||||
void SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers );
|
||||
|
||||
/**
|
||||
|
||||
@@ -154,9 +154,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L692
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_startCopperLayersTime = GetRunningMicroSecs();
|
||||
int64_t stats_startCopperLayersTime = GetRunningMicroSecs();
|
||||
|
||||
unsigned start_Time = stats_startCopperLayersTime;
|
||||
int64_t start_Time = stats_startCopperLayersTime;
|
||||
#endif
|
||||
|
||||
PCB_LAYER_ID cu_seq[MAX_CU_LAYERS];
|
||||
|
||||
@@ -369,7 +369,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
wxString err_messages;
|
||||
INFOBAR_REPORTER warningReporter( m_parentInfoBar );
|
||||
STATUSBAR_REPORTER activityReporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
|
||||
unsigned start_time = GetRunningMicroSecs();
|
||||
int64_t start_time = GetRunningMicroSecs();
|
||||
|
||||
// "Makes the OpenGL state that is represented by the OpenGL rendering
|
||||
// context context current, i.e. it will be used by all subsequent OpenGL calls.
|
||||
@@ -461,7 +461,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
|
||||
if( m_camera_is_moving )
|
||||
{
|
||||
const unsigned curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
curtime_delta_s = (curtime_delta / 1e6) * m_camera_moving_speed;
|
||||
m_camera.Interpolate( curtime_delta_s );
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ private:
|
||||
|
||||
bool m_render_pivot; // Render the pivot while camera moving
|
||||
float m_camera_moving_speed; // 1.0f will be 1:1
|
||||
unsigned m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
bool m_animation_enabled; // Camera animation enabled
|
||||
int m_moving_speed_multiplier; // Camera animation speed multiplier option
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
|
||||
|
||||
|
||||
@@ -368,7 +368,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
OBJECT_3D_STATS::Instance().ResetStats();
|
||||
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
@@ -771,8 +771,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
}
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_endConvertTime = GetRunningMicroSecs();
|
||||
unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
int64_t stats_endConvertTime = GetRunningMicroSecs();
|
||||
int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -781,7 +781,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
int64_t stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
@@ -955,7 +955,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
if( aStatusReporter )
|
||||
{
|
||||
// Calculation time in seconds
|
||||
double calculation_time = (double) GetRunningMicroSecs() - stats_startReloadTime / 1e6;
|
||||
double calculation_time = (double) ( GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
|
||||
|
||||
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
RT_RENDER_STATE m_renderState;
|
||||
|
||||
/// Time that the render starts
|
||||
unsigned long int m_renderStartTime;
|
||||
int64_t m_renderStartTime;
|
||||
|
||||
/// Save the number of blocks progress of the render
|
||||
size_t m_blockRenderProgressCount;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -568,7 +568,8 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
m_boardAdapter.m_Cfg = cfg;
|
||||
applySettings( cfg );
|
||||
|
||||
m_boardAdapter.SetBoard( GetBoard() );
|
||||
|
||||
// When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
|
||||
@@ -576,28 +577,20 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
// (freeze window) with large boards.
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
|
||||
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
|
||||
|
||||
if( cfg->m_CurrentPreset == LEGACY_PRESET_FLAG )
|
||||
{
|
||||
wxString legacyColorsPresetName = _( "legacy colors" );
|
||||
|
||||
cfg->m_UseStackupColors = false;
|
||||
|
||||
if( !cfg->FindPreset( legacyColorsPresetName ) )
|
||||
{
|
||||
cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
|
||||
GetAdapter().GetVisibleLayers(),
|
||||
GetAdapter().GetLayerColors() );
|
||||
GetAdapter().GetDefaultVisibleLayers(),
|
||||
GetAdapter().GetDefaultColors() );
|
||||
}
|
||||
|
||||
if( Pgm().GetSettingsManager().GetColorSettings()->GetUseBoardStackupColors() )
|
||||
cfg->m_CurrentPreset = FOLLOW_PCB;
|
||||
else
|
||||
cfg->m_CurrentPreset = legacyColorsPresetName;
|
||||
cfg->m_CurrentPreset = wxEmptyString;
|
||||
}
|
||||
|
||||
m_boardAdapter.InitSettings( nullptr, nullptr );
|
||||
@@ -646,7 +639,7 @@ void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTex
|
||||
ReCreateMainToolbar();
|
||||
|
||||
loadCommonSettings();
|
||||
LoadSettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
|
||||
applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
|
||||
|
||||
m_appearancePanel->CommonSettingsChanged();
|
||||
|
||||
@@ -825,3 +818,15 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::applySettings( EDA_3D_VIEWER_SETTINGS* cfg )
|
||||
{
|
||||
m_boardAdapter.m_Cfg = cfg;
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -167,6 +167,8 @@ private:
|
||||
*/
|
||||
void loadCommonSettings();
|
||||
|
||||
void applySettings( EDA_3D_VIEWER_SETTINGS* aSettings );
|
||||
|
||||
private:
|
||||
wxFileName m_defaultSaveScreenshotFileName;
|
||||
|
||||
|
||||
@@ -377,6 +377,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<int>( "camera.projection_mode",
|
||||
&m_Camera.projection_mode, 1 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "use_stackup_colors",
|
||||
&m_UseStackupColors, true ) );
|
||||
m_params.emplace_back( new PARAM_LAYER_PRESET_3D( "layer_presets",
|
||||
&m_LayerPresets ) );
|
||||
m_params.emplace_back( new PARAM<wxString>( "current_layer_preset",
|
||||
|
||||
@@ -169,6 +169,7 @@ public:
|
||||
RENDER_SETTINGS m_Render;
|
||||
CAMERA_SETTINGS m_Camera;
|
||||
|
||||
bool m_UseStackupColors;
|
||||
std::vector<LAYER_PRESET_3D> m_LayerPresets;
|
||||
wxString m_CurrentPreset;
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Clockwise" ) )
|
||||
.Tooltip( _( "Rotate X Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CW ) );
|
||||
@@ -62,7 +61,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate X Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CCW ) );
|
||||
@@ -71,7 +69,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Clockwise" ) )
|
||||
.Tooltip( _( "Rotate Y Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CW ) );
|
||||
@@ -80,7 +77,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate Y Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CCW ) );
|
||||
@@ -89,7 +85,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Clockwise" ) )
|
||||
.Tooltip( _( "Rotate Z Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CW ) );
|
||||
@@ -98,7 +93,6 @@ TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Counterclockwise" ) )
|
||||
.Tooltip( _( "Rotate Z Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CCW ) );
|
||||
@@ -108,7 +102,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveLeft( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_LEFT )
|
||||
.FriendlyName( _( "Move Board Left" ) )
|
||||
.Tooltip( _( "Move board Left" ) )
|
||||
.Icon( BITMAPS::left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_LEFT ) );
|
||||
@@ -118,7 +111,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveRight( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_RIGHT )
|
||||
.FriendlyName( _( "Move Board Right" ) )
|
||||
.Tooltip( _( "Move board Right" ) )
|
||||
.Icon( BITMAPS::right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_RIGHT ) );
|
||||
@@ -128,7 +120,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveUp( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_UP )
|
||||
.FriendlyName( _( "Move Board Up" ) )
|
||||
.Tooltip( _( "Move board Up" ) )
|
||||
.Icon( BITMAPS::up )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_UP ) );
|
||||
@@ -138,7 +129,6 @@ TOOL_ACTION EDA_3D_ACTIONS::moveDown( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_DOWN )
|
||||
.FriendlyName( _( "Move Board Down" ) )
|
||||
.Tooltip( _( "Move board Down" ) )
|
||||
.Icon( BITMAPS::down )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_DOWN ) );
|
||||
@@ -148,7 +138,7 @@ TOOL_ACTION EDA_3D_ACTIONS::homeView( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_HOME )
|
||||
.FriendlyName ( _( "Home View" ) )
|
||||
.Tooltip( _( "Home view" ) )
|
||||
.Tooltip( _( "Redraw at the home position and zoom" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FIT_SCREEN ) );
|
||||
|
||||
@@ -174,7 +164,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewFront( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Y' )
|
||||
.FriendlyName( _( "View Front" ) )
|
||||
.Tooltip( _( "View Front" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FRONT ) );
|
||||
@@ -184,7 +173,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewBack( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Y' )
|
||||
.FriendlyName( _( "View Back" ) )
|
||||
.Tooltip( _( "View Back" ) )
|
||||
.Icon( BITMAPS::axis3d_back )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BACK ) );
|
||||
@@ -194,7 +182,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewLeft( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'X' )
|
||||
.FriendlyName( _( "View Left" ) )
|
||||
.Tooltip( _( "View Left" ) )
|
||||
.Icon( BITMAPS::axis3d_left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_LEFT ) );
|
||||
@@ -204,7 +191,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewRight( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'X' )
|
||||
.FriendlyName( _( "View Right" ) )
|
||||
.Tooltip( _( "View Right" ) )
|
||||
.Icon( BITMAPS::axis3d_right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_RIGHT ) );
|
||||
@@ -214,7 +200,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewTop( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Z' )
|
||||
.FriendlyName( _( "View Top" ) )
|
||||
.Tooltip( _( "View Top" ) )
|
||||
.Icon( BITMAPS::axis3d_top )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_TOP ) );
|
||||
@@ -224,7 +209,6 @@ TOOL_ACTION EDA_3D_ACTIONS::viewBottom( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Z' )
|
||||
.FriendlyName( _( "View Bottom" ) )
|
||||
.Tooltip( _( "View Bottom" ) )
|
||||
.Icon( BITMAPS::axis3d_bottom )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BOTTOM ) );
|
||||
@@ -233,7 +217,6 @@ TOOL_ACTION EDA_3D_ACTIONS::noGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.noGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "No 3D Grid" ) )
|
||||
.Tooltip( _( "No 3D Grid" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::NONE ) );
|
||||
|
||||
@@ -241,7 +224,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show10mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 10mm" ) )
|
||||
.Tooltip( _( "3D Grid 10mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_10MM ) );
|
||||
|
||||
@@ -249,7 +231,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 5mm" ) )
|
||||
.Tooltip( _( "3D Grid 5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_5MM ) );
|
||||
|
||||
@@ -257,7 +238,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show2_5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 2.5mm" ) )
|
||||
.Tooltip( _( "3D Grid 2.5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_2P5MM ) );
|
||||
|
||||
@@ -265,7 +245,6 @@ TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show1mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 1mm" ) )
|
||||
.Tooltip( _( "3D Grid 1mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_1MM ) );
|
||||
|
||||
@@ -350,7 +329,6 @@ TOOL_ACTION EDA_3D_ACTIONS::showAxis( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.showAxis" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Show 3D Axis" ) )
|
||||
.Tooltip( _( "Show 3D Axis" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE ) );
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/checkbox.h>
|
||||
|
||||
#include <../3d_rendering/opengl/render_3d_opengl.h>
|
||||
|
||||
@@ -112,6 +113,24 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
m_presetsLabel->SetFont( infoFont );
|
||||
m_viewportsLabel->SetFont( infoFont );
|
||||
|
||||
// Create display options
|
||||
m_cbUseBoardStackupColors = new wxCheckBox( m_panelLayers, wxID_ANY,
|
||||
_( "Use board stackup colors" ) );
|
||||
m_cbUseBoardStackupColors->SetFont( infoFont );
|
||||
|
||||
m_cbUseBoardStackupColors->Bind( wxEVT_CHECKBOX,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
cfg->m_UseStackupColors = aEvent.IsChecked();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
m_frame->NewDisplay( true );
|
||||
} );
|
||||
|
||||
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
|
||||
|
||||
m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility "
|
||||
"combinations.\n"
|
||||
"Use %s+Tab to activate selector.\n"
|
||||
@@ -176,7 +195,9 @@ void APPEARANCE_CONTROLS_3D::OnSize( wxSizeEvent& aEvent )
|
||||
void APPEARANCE_CONTROLS_3D::OnLanguageChanged()
|
||||
{
|
||||
Freeze();
|
||||
|
||||
rebuildLayers();
|
||||
m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
|
||||
rebuildLayerPresetsWidget();
|
||||
rebuildViewportsWidget();
|
||||
|
||||
@@ -209,6 +230,9 @@ void APPEARANCE_CONTROLS_3D::OnDarkModeToggle()
|
||||
void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
|
||||
{
|
||||
OnLanguageChanged();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
}
|
||||
|
||||
|
||||
@@ -437,6 +461,19 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
SWATCH_SMALL );
|
||||
swatch->SetToolTip( _( "Left double click or middle click to change color" ) );
|
||||
|
||||
swatch->SetReadOnlyCallback(
|
||||
[this]()
|
||||
{
|
||||
WX_INFOBAR* infobar = m_frame->GetInfoBar();
|
||||
|
||||
infobar->RemoveAllButtons();
|
||||
infobar->AddCloseButton();
|
||||
|
||||
infobar->ShowMessageFor( _( "Uncheck 'Use board stackup colors' to "
|
||||
"allow color editing." ),
|
||||
10000, wxICON_INFORMATION );
|
||||
} );
|
||||
|
||||
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
|
||||
aSetting->m_Ctl_color = swatch;
|
||||
|
||||
@@ -515,6 +552,7 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
@@ -527,8 +565,16 @@ void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
|
||||
setting->m_Ctl_visibility->SetValue( visibleLayers.test( setting->m_Id ) );
|
||||
|
||||
if( setting->m_Ctl_color )
|
||||
{
|
||||
setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
|
||||
|
||||
if( cfg )
|
||||
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
|
||||
}
|
||||
}
|
||||
|
||||
if( cfg )
|
||||
m_cbUseBoardStackupColors->SetValue( cfg->m_UseStackupColors );
|
||||
}
|
||||
|
||||
|
||||
@@ -563,9 +609,16 @@ void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
auto it = std::find_if( presets.begin(), presets.end(),
|
||||
auto it = std::find_if(
|
||||
presets.begin(), presets.end(),
|
||||
[&]( const LAYER_PRESET_3D& aPreset )
|
||||
{
|
||||
if( aPreset.name.Lower() == _( "legacy colors" )
|
||||
&& m_cbUseBoardStackupColors->GetValue() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
|
||||
@@ -578,9 +631,12 @@ void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_ADHESIVE; ++layer )
|
||||
for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( aPreset.colors.at( layer ) != colors.at( layer ) )
|
||||
auto it1 = aPreset.colors.find( layer );
|
||||
auto it2 = colors.find( layer );
|
||||
|
||||
if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -745,6 +801,9 @@ void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const LAYER_PRESET_3D& aPreset
|
||||
adapter.SetVisibleLayers( aPreset.layers );
|
||||
adapter.SetLayerColors( aPreset.colors );
|
||||
|
||||
if( aPreset.name.Lower() == _( "legacy colors" ) )
|
||||
adapter.m_Cfg->m_UseStackupColors = false;
|
||||
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
|
||||
@@ -166,26 +166,26 @@ private:
|
||||
void passOnFocus();
|
||||
|
||||
private:
|
||||
EDA_3D_VIEWER_FRAME* m_frame;
|
||||
wxWindow* m_focusOwner;
|
||||
|
||||
static const APPEARANCE_SETTING_3D s_layerSettings[];
|
||||
|
||||
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
|
||||
EDA_3D_VIEWER_FRAME* m_frame;
|
||||
wxWindow* m_focusOwner;
|
||||
|
||||
std::vector<std::unique_ptr<APPEARANCE_SETTING_3D>> m_layerSettings;
|
||||
std::map<int, APPEARANCE_SETTING_3D*> m_layerSettingsMap;
|
||||
|
||||
wxArrayString m_presetMRU;
|
||||
wxArrayString m_presetMRU;
|
||||
|
||||
std::map<wxString, VIEWPORT3D> m_viewports;
|
||||
VIEWPORT3D* m_lastSelectedViewport;
|
||||
wxArrayString m_viewportMRU;
|
||||
std::map<wxString, VIEWPORT3D> m_viewports;
|
||||
VIEWPORT3D* m_lastSelectedViewport;
|
||||
wxArrayString m_viewportMRU;
|
||||
|
||||
wxBoxSizer* m_layersOuterSizer;
|
||||
wxBoxSizer* m_envOuterSizer;
|
||||
int m_pointSize;
|
||||
wxColour m_layerPanelColour;
|
||||
wxBoxSizer* m_layersOuterSizer;
|
||||
wxBoxSizer* m_envOuterSizer;
|
||||
int m_pointSize;
|
||||
wxColour m_layerPanelColour;
|
||||
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
|
||||
wxCheckBox* m_cbUseBoardStackupColors;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -25,11 +25,14 @@ APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWi
|
||||
m_panelLayers->SetSizer( m_panelLayersSizer );
|
||||
m_panelLayers->Layout();
|
||||
m_panelLayersSizer->Fit( m_panelLayers );
|
||||
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND|wxBOTTOM, 5 );
|
||||
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bBottomMargin;
|
||||
bBottomMargin = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bBottomMargin->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 3 );
|
||||
|
||||
wxBoxSizer* bPresets;
|
||||
bPresets = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
@@ -44,7 +47,7 @@ APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWi
|
||||
bPresets->Add( m_cbLayerPresets, 0, wxALL|wxEXPAND, 2 );
|
||||
|
||||
|
||||
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bBottomMargin->Add( 0, 2, 0, wxEXPAND, 5 );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/choice.h>
|
||||
|
||||
@@ -38,6 +39,7 @@ class APPEARANCE_CONTROLS_3D_BASE : public WX_PANEL
|
||||
wxPanel* m_panelLayers;
|
||||
wxBoxSizer* m_panelLayersSizer;
|
||||
wxScrolledCanvas* m_windowLayers;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxStaticText* m_presetsLabel;
|
||||
wxChoice* m_cbLayerPresets;
|
||||
wxStaticText* m_viewportsLabel;
|
||||
|
||||
+10
-4
@@ -106,10 +106,9 @@ option( KICAD_SCRIPTING_WXPYTHON
|
||||
ON )
|
||||
mark_as_advanced( KICAD_SCRIPTING_WXPYTHON )
|
||||
|
||||
cmake_dependent_option( KICAD_UPDATE_CHECK
|
||||
option( KICAD_UPDATE_CHECK
|
||||
"Build in update check"
|
||||
ON "APPLE_OR_WIN32"
|
||||
OFF )
|
||||
ON )
|
||||
|
||||
# EGL is only needed on Linux with Wayland
|
||||
cmake_dependent_option( KICAD_USE_EGL
|
||||
@@ -877,7 +876,14 @@ check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
|
||||
# Get the correct Python site package install path from the Python interpreter found by
|
||||
# FindPythonInterp unless the user specifically defined a custom path.
|
||||
if( NOT PYTHON_SITE_PACKAGE_PATH )
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig;print(\"%s\"%sysconfig.get_path('platlib', vars={'platbase': '.'}))"
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import sys, sysconfig
|
||||
if 'deb_system' in sysconfig.get_scheme_names():
|
||||
scheme = 'deb_system'
|
||||
elif sys.version_info > (3, 10):
|
||||
scheme = sysconfig.get_default_scheme()
|
||||
else:
|
||||
scheme = sysconfig._get_default_scheme()
|
||||
print(\"%s\"%sysconfig.get_path('platlib', vars={'platbase': '.'}, scheme=scheme))"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@@ -72,6 +72,7 @@ set( _wvh_new_version_text
|
||||
#endif
|
||||
|
||||
#define KICAD_COMMIT_HASH \"${KICAD_COMMIT_HASH}\"
|
||||
#define KICAD_VERSION \"${KICAD_VERSION}\"
|
||||
#define KICAD_VERSION_FULL \"${KICAD_VERSION_FULL}\"
|
||||
#define KICAD_SEMANTIC_VERSION \"${KICAD_SEMANTIC_VERSION}\"
|
||||
#define KICAD_MAJOR_VERSION \"${KICAD_MAJOR_VERSION}\"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.0" )
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.1-rc1" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -71,6 +71,13 @@ wxString GetBuildVersion()
|
||||
}
|
||||
|
||||
|
||||
wxString GetBaseVersion()
|
||||
{
|
||||
wxString msg = wxString::Format( wxT( "%s" ), wxT( KICAD_VERSION ) );
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
wxString GetBuildDate()
|
||||
{
|
||||
wxString msg = wxString::Format( wxT( "%s %s" ), wxT( __DATE__ ), wxT( __TIME__ ) );
|
||||
|
||||
@@ -448,7 +448,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
{
|
||||
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
|
||||
}
|
||||
catch( nanodbc::null_access_error& e )
|
||||
catch( nanodbc::null_access_error& )
|
||||
{
|
||||
// Column was empty (null)
|
||||
aResult[column] = std::string();
|
||||
@@ -498,6 +498,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||
|
||||
aResults.reserve( cacheEntry.size() );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
@@ -605,7 +607,7 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
{
|
||||
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
|
||||
}
|
||||
catch( nanodbc::null_access_error& e )
|
||||
catch( nanodbc::null_access_error& )
|
||||
{
|
||||
// Column was empty (null)
|
||||
result[column] = std::string();
|
||||
|
||||
@@ -32,6 +32,17 @@
|
||||
const int dblibSchemaVersion = 1;
|
||||
|
||||
|
||||
DATABASE_FIELD_MAPPING::DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName,
|
||||
bool aVisibleOnAdd, bool aVisibleInChooser,
|
||||
bool aShowName, bool aInheritProperties ) :
|
||||
column( aColumn ),
|
||||
name( aName ), name_wx( aName.c_str(), wxConvUTF8 ), visible_on_add( aVisibleOnAdd ),
|
||||
visible_in_chooser( aVisibleInChooser ), show_name( aShowName ),
|
||||
inherit_properties( aInheritProperties )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, dblibSchemaVersion )
|
||||
{
|
||||
@@ -113,11 +124,8 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
|
||||
|
||||
table.fields.emplace_back(
|
||||
DATABASE_FIELD_MAPPING(
|
||||
{
|
||||
column, name, visible_on_add, visible_in_chooser, show_name,
|
||||
inherit
|
||||
} ) );
|
||||
DATABASE_FIELD_MAPPING( column, name, visible_on_add,
|
||||
visible_in_chooser, show_name, inherit ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tomasz Wlostowski" ), LEAD_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jeff Young" ), LEAD_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabien Corona" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dick Hollenbeck" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexis Lockwood" ), FORMER_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Sidebotham" ), FORMER_DEV, nullptr ) );
|
||||
@@ -224,13 +225,16 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mikolaj Wielgus" ), FORMER_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Aberg" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yüksel Açikgöz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Rohan Agrawal" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Agricola" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Erik Agsjö" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nabeel Ahmad" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Werner Almesberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Shawn Anastasio" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Collin Anderson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tom Andrews" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Subaru Arai" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mikael Arguedas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lachlan Audas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean-Noel Avila" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -246,16 +250,19 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Bennett" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Roman Beranek" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Francois Berder" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Berglund" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gustav Bergquist" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Cirilo Bernardo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joël Bertrand" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andreas Beutling" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian F. G. Bidulock" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Anton Blanchard" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Steve Bollinger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Blair Bonnett" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Markus Bonk" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Franck Bourdonnec" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Carlo Bramini" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthias Breithaupt" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Brüns" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andreas Buhr" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ryan Bunch" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -271,8 +278,9 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marcus Comstedt" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Diogo Condeco" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Colin Cooper" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabien Corona" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Emile Cormier" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Garth Corral" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Sergio Costas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kevin Cozens" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dan Cross" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -283,11 +291,13 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Albin Dennevi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ruben De Smet" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Dewing" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Okan Demir" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonas Diemer" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ben Dooks" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Pavel Dovgalyuk" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrew Downing" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jan Dubiec" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lucas Dumont" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gerd Egidy" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean Philippe Eimer" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -301,6 +311,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joe Ferner" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Fiete" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Thomas Figueroa" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gilbert J.M. Forkel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vincenzo Fortunato" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Drew Fustini" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -316,6 +327,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jeff Glass" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Golubev" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Angus Gratton" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrea Greco" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Element Green" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mathias Grimmberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johan Grip" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -328,6 +340,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Haas" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark Hämmerling" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Hamminga" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ma Han" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Scott Hanson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ben Harris" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Lukas F. Hartmann" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -340,7 +353,11 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hans Henry von Tresckow" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Diego Herranz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marco Hess" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "David Holdeman" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Laurens Holst" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yang Hongbo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mario Hros" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Josue Huaroto" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matt Huszagh" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Torsten Hüter" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -351,13 +368,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vlad Ivanov" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andre Iwers" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hasan Jaafar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "James Jackson" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jerry Jacobs" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Jacobsen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Michal Jahelka" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Janitschke" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Jara-Almonte" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gilbert J.M. Forkel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Zhuang Jiezhi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "José Jorge Enríquez" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Franck Jullien" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -371,6 +389,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Graham Keeth" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yury Khalyavin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Eldar Khayrullin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Georges Khaznadar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Gary Kim" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ingo Kletti" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kliment" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -440,15 +459,18 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jason Oster" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Palazzolo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matus Pavelek" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "luz paz" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Miguel Angel Ajo Pelayo" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Patrick Pereira" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jacobo Aragunde Perez" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthew Petroff" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Pfister" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabian Pflug" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Pfluger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Brian Piccioni" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nicolas Planel" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Paweł Płóciennik" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Carl Poirier" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Reece Pollack" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alain Portal" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -461,6 +483,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Barabas Raffai" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Urja Rannikko" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hendrik v. Raven" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Joshua Redstone" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Michele Renda" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jean-Samuel Reynaud" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -478,6 +501,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabio Rossi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ian Roth" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Clément Saccoccio" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "J. Morio Sakaguchi" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Simon Schaak" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Ross Schlaikjer" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -495,6 +519,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yang Sheng" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Chetan Shinde" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Shuklin" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Adam Simpkins" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Slawomir Siudym" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Marco Serantoni" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Guillaume Simard" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -515,11 +540,15 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Alexander Stock" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Stoilov" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hiroki Suenaga" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Kuba Sunderland-Ober" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nimish Telang" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Martin Thierer" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Karl Thorén" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Hiroshi Tokita" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vladimir Ur" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Yon Uriarte" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Matthias Urlichs" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Vladimir Uryvaev" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
@@ -527,20 +556,25 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dave Vandenbout" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Edwin van den Oetelaar" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark van Doesburg" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nils van Zuijlen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Fabio Varesano" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Benjamin Vernoux" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Frank Villaro-Dixon" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Mark Visser" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Forrest Voight" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Tormod Volden" ), CONTRIB_DEV, nullptr ) );
|
||||
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Bartek Wacławik" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Johannes Wågen" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Oliver Walters" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jonathan Warner" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dan Weatherill" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Stefan Weber" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Christian Weickhmann" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Bevan Weiss" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Simon Wells" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Dominik Wernberger" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Jan Wichmann" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Nick Winters" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Adam Wolf" ), CONTRIB_DEV, nullptr ) );
|
||||
aInfo.AddDeveloper( new CONTRIBUTOR( wxT( "Andrzej Wolski" ), CONTRIB_DEV, nullptr ) );
|
||||
@@ -617,10 +651,18 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Danish (DA)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Ettore Atalan" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Ivan Chuba" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Julian Daube" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Benedikt Freisen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -633,6 +675,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Johannes Maibaum" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -641,6 +687,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ken Ovo" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Karl Schuh" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "German (DE)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Dominik Wernberger" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -687,6 +741,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "Gabriel Martinez" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jose Perez" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -721,6 +779,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Finnish (FI)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Toni Laiho" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Finnish (FI)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "J. Lavoie" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -756,6 +818,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Italian (IT)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Subaru Arai" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Japanese (JA)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ji Yoon Choi" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -865,6 +931,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김랑기" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "KwonHyeokbeom" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -873,6 +943,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "pedrolinharesmoreira" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
@@ -891,6 +965,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Laurens Holst" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Pim Jansen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -899,10 +977,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Bas Wijnen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tom Niesse" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -911,6 +985,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Arend-Jan van Hilten" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Bas Wijnen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jarl Gjessing" ),
|
||||
wxEmptyString,
|
||||
@@ -945,6 +1027,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Eryk Michalak" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Filip Piękoś" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Mark Roszko" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -953,6 +1043,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jan Sobków" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Polish (PL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Grzegorz Szymaszek" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1029,6 +1123,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Swedish (SV)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Elias Sjögreen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Swedish (SV)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Boonchai Kingrungped" ),
|
||||
wxEmptyString,
|
||||
@@ -1056,6 +1154,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxS( "Ukrainian (UK)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "向阳阳" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "欠陥電気" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Liu Guang" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1076,6 +1182,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Hubert Hu" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Pinpang Liao" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Rigo Ligo" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1084,15 +1198,35 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Zhen Sun" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jason Tan" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "yangyangdaji" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Li Yidong" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tian Yunhao" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Lao Zhu" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Simplified Chinese (zh_CN)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "撒景賢" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "David Chen" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
@@ -1105,11 +1239,15 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "William Lin" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Taotieren" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "william" ),
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Li Yidong" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Traditional Chinese (zh_TW)" ) ) );
|
||||
@@ -1249,6 +1387,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
ICON_CONTRIBUTION ) );
|
||||
aInfo.AddArtist( new CONTRIBUTOR( wxT( "Anda Subero" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
ICON_CONTRIBUTION ) );
|
||||
aInfo.AddArtist( new CONTRIBUTOR( wxT( "Iñigo Zuluaga" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
|
||||
@@ -37,9 +37,15 @@
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
|
||||
DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository, wxString aURL ) :
|
||||
DIALOG_GIT_REPOSITORY_BASE( aParent ), m_repository( aRepository ), m_prevFile( wxEmptyString ),
|
||||
m_tested( 0 ), m_failedTest( false ), m_testError( wxEmptyString ), m_tempRepo( false ),
|
||||
DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository,
|
||||
wxString aURL ) :
|
||||
DIALOG_GIT_REPOSITORY_BASE( aParent ),
|
||||
m_repository( aRepository ),
|
||||
m_prevFile( wxEmptyString ),
|
||||
m_tested( 0 ),
|
||||
m_failedTest( false ),
|
||||
m_testError( wxEmptyString ),
|
||||
m_tempRepo( false ),
|
||||
m_repoType( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL )
|
||||
{
|
||||
m_txtURL->SetFocus();
|
||||
@@ -90,7 +96,9 @@ bool DIALOG_GIT_REPOSITORY::extractClipboardData()
|
||||
{
|
||||
if( std::get<0>( isValidHTTPS( clipboardText ) )
|
||||
|| std::get<0>( isValidSSH( clipboardText ) ) )
|
||||
{
|
||||
m_txtURL->SetValue( clipboardText );
|
||||
}
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
@@ -362,7 +370,8 @@ void DIALOG_GIT_REPOSITORY::OnFileUpdated( wxFileDirPickerEvent& aEvent )
|
||||
|
||||
if( !isValid )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Invalid SSH Key" ), _( "The selected file is not a valid SSH private key" ) );
|
||||
DisplayErrorMessage( this, _( "Invalid SSH Key" ),
|
||||
_( "The selected file is not a valid SSH private key" ) );
|
||||
CallAfter( [this] { SetRepoSSHPath( m_prevFile ); } );
|
||||
return;
|
||||
}
|
||||
@@ -386,7 +395,8 @@ void DIALOG_GIT_REPOSITORY::OnFileUpdated( wxFileDirPickerEvent& aEvent )
|
||||
|
||||
if( !pubIfs.good() || !pubIfs.is_open() )
|
||||
{
|
||||
DisplayErrorMessage( this, wxString::Format( _( "Could not open public key '%s'" ), file + ".pub" ),
|
||||
DisplayErrorMessage( this, wxString::Format( _( "Could not open public key '%s'" ),
|
||||
file + ".pub" ),
|
||||
wxString::Format( "%s: %d", std::strerror( errno ), errno ) );
|
||||
aEvent.SetPath( wxEmptyString );
|
||||
CallAfter( [this] { SetRepoSSHPath( m_prevFile ); } );
|
||||
@@ -404,19 +414,22 @@ void DIALOG_GIT_REPOSITORY::OnOKClick( wxCommandEvent& event )
|
||||
|
||||
if( m_txtName->GetValue().IsEmpty() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Missing information" ), _( "Please enter a name for the repository" ) );
|
||||
DisplayErrorMessage( this, _( "Missing information" ),
|
||||
_( "Please enter a name for the repository" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_txtURL->GetValue().IsEmpty() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Missing information" ), _( "Please enter a URL for the repository" ) );
|
||||
DisplayErrorMessage( this, _( "Missing information" ),
|
||||
_( "Please enter a URL for the repository" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GIT_REPOSITORY::updateAuthControls()
|
||||
{
|
||||
if( m_ConnType->GetSelection() == static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) )
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
class DIALOG_GIT_REPOSITORY : public DIALOG_GIT_REPOSITORY_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository, wxString aURL = wxEmptyString );
|
||||
DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository* aRepository,
|
||||
wxString aURL = wxEmptyString );
|
||||
~DIALOG_GIT_REPOSITORY() override;
|
||||
|
||||
void SetTestResult( bool aFailed, const wxString& aError )
|
||||
@@ -47,7 +48,10 @@ public:
|
||||
updateAuthControls();
|
||||
}
|
||||
|
||||
KIGIT_COMMON::GIT_CONN_TYPE GetRepoType() const { return static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() ); }
|
||||
KIGIT_COMMON::GIT_CONN_TYPE GetRepoType() const
|
||||
{
|
||||
return static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() );
|
||||
}
|
||||
|
||||
void SetRepoName( const wxString& aName ) { m_txtName->SetValue( aName ); }
|
||||
wxString GetRepoName() const { return m_txtName->GetValue(); }
|
||||
@@ -106,19 +110,19 @@ private:
|
||||
std::tuple<bool,wxString,wxString,wxString> isValidHTTPS( const wxString& url );
|
||||
std::tuple<bool,wxString, wxString> isValidSSH( const wxString& url );
|
||||
|
||||
private:
|
||||
git_repository* m_repository;
|
||||
|
||||
wxString m_prevFile;
|
||||
wxString m_prevFile;
|
||||
|
||||
unsigned m_tested;
|
||||
bool m_failedTest;
|
||||
wxString m_testError;
|
||||
unsigned m_tested;
|
||||
bool m_failedTest;
|
||||
wxString m_testError;
|
||||
|
||||
bool m_tempRepo;
|
||||
wxString m_tempPath;
|
||||
bool m_tempRepo;
|
||||
wxString m_tempPath;
|
||||
|
||||
KIGIT_COMMON::GIT_CONN_TYPE m_repoType;
|
||||
|
||||
};
|
||||
|
||||
#endif /* DIALOG_GIT_REPOSITORY_H_ */
|
||||
@@ -55,7 +55,7 @@ void PANEL_GIT_REPOS::ResetPanel()
|
||||
m_authorEmail->SetValue( wxEmptyString );
|
||||
}
|
||||
|
||||
static std::pair<wxString, wxString> getDefaultAuthorEmail()
|
||||
static std::pair<wxString, wxString> getDefaultAuthorAndEmail()
|
||||
{
|
||||
wxString name;
|
||||
wxString email;
|
||||
@@ -94,8 +94,8 @@ static std::pair<wxString, wxString> getDefaultAuthorEmail()
|
||||
|
||||
bool PANEL_GIT_REPOS::TransferDataFromWindow()
|
||||
{
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
auto& repos = settings->m_Git.repositories;
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
std::vector<COMMON_SETTINGS::GIT_REPOSITORY>& repos = settings->m_Git.repositories;
|
||||
|
||||
repos.clear();
|
||||
|
||||
@@ -109,7 +109,8 @@ bool PANEL_GIT_REPOS::TransferDataFromWindow()
|
||||
repo.authType = m_grid->GetCellValue( row, COL_AUTH_TYPE );
|
||||
repo.username = m_grid->GetCellValue( row, COL_USERNAME );
|
||||
|
||||
KIPLATFORM::SECRETS::StoreSecret( repo.path, repo.username, m_grid->GetCellValue( row, COL_PASSWORD ) );
|
||||
KIPLATFORM::SECRETS::StoreSecret( repo.path, repo.username,
|
||||
m_grid->GetCellValue( row, COL_PASSWORD ) );
|
||||
repo.ssh_path = m_grid->GetCellValue( row, COL_SSH_PATH );
|
||||
repo.checkValid = m_grid->GetCellValue( row, COL_STATUS ) == "1";
|
||||
repos.push_back( repo );
|
||||
@@ -126,7 +127,8 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
{
|
||||
git_libgit2_init();
|
||||
|
||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
||||
git_remote_callbacks callbacks;
|
||||
callbacks.version = GIT_REMOTE_CALLBACKS_VERSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -134,35 +136,39 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
bool success;
|
||||
} callbacksPayload;
|
||||
|
||||
callbacksPayload cb_data( { &repository, true } ); // If we don't need authentication, then, we are successful
|
||||
callbacksPayload cb_data( { &repository, true } ); // If we don't need authentication, then,
|
||||
// we are successful
|
||||
callbacks.payload = &cb_data;
|
||||
callbacks.credentials = [](git_cred** out, const char* url, const char* username, unsigned int allowed_types, void* payload) -> int {
|
||||
callbacks.credentials =
|
||||
[](git_cred** out, const char* url, const char* username, unsigned int allowed_types,
|
||||
void* payload) -> int
|
||||
{
|
||||
|
||||
// If we are asking for credentials, then, we need authentication
|
||||
// If we are asking for credentials, then, we need authentication
|
||||
|
||||
callbacksPayload* data = static_cast<callbacksPayload*>(payload);
|
||||
callbacksPayload* data = static_cast<callbacksPayload*>(payload);
|
||||
|
||||
data->success = false;
|
||||
data->success = false;
|
||||
|
||||
if( allowed_types & GIT_CREDTYPE_USERNAME )
|
||||
{
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "ssh" && ( allowed_types & GIT_CREDTYPE_SSH_KEY ) )
|
||||
{
|
||||
wxString sshKeyPath = data->repo->ssh_path;
|
||||
if( allowed_types & GIT_CREDTYPE_USERNAME )
|
||||
{
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "ssh" && ( allowed_types & GIT_CREDTYPE_SSH_KEY ) )
|
||||
{
|
||||
wxString sshKeyPath = data->repo->ssh_path;
|
||||
|
||||
// Check if the SSH key exists and is readable
|
||||
if( wxFileExists( sshKeyPath ) && wxFile::Access( sshKeyPath, wxFile::read ) )
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "password" )
|
||||
{
|
||||
data->success = ( allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT );
|
||||
}
|
||||
// Check if the SSH key exists and is readable
|
||||
if( wxFileExists( sshKeyPath ) && wxFile::Access( sshKeyPath, wxFile::read ) )
|
||||
data->success = true;
|
||||
}
|
||||
else if( data->repo->authType == "password" )
|
||||
{
|
||||
data->success = ( allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT );
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Create a temporary directory to initialize the Git repository
|
||||
wxString tempDirPath = wxFileName::CreateTempFileName(wxT("kigit_temp"));
|
||||
@@ -177,9 +183,10 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
|
||||
// Initialize the Git repository
|
||||
git_repository* repo = nullptr;
|
||||
int result = git_repository_init(&repo, tempDirPath.mb_str(wxConvUTF8), 0);
|
||||
int result = git_repository_init( &repo, tempDirPath.mb_str( wxConvUTF8 ), 0 );
|
||||
|
||||
if (result != 0) {
|
||||
if (result != 0)
|
||||
{
|
||||
git_repository_free(repo);
|
||||
git_libgit2_shutdown();
|
||||
wxRmdir(tempDirPath);
|
||||
@@ -187,8 +194,10 @@ static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repositor
|
||||
}
|
||||
|
||||
git_remote* remote = nullptr;
|
||||
result = git_remote_create_anonymous(&remote, repo, tempDirPath.mb_str(wxConvUTF8));
|
||||
if (result != 0) {
|
||||
result = git_remote_create_anonymous( &remote, repo, tempDirPath.mb_str( wxConvUTF8 ) );
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
git_remote_free(remote);
|
||||
git_repository_free(repo);
|
||||
git_libgit2_shutdown();
|
||||
@@ -249,7 +258,7 @@ bool PANEL_GIT_REPOS::TransferDataToWindow()
|
||||
|
||||
if( settings->m_Git.useDefaultAuthor )
|
||||
{
|
||||
auto defaultAuthor = getDefaultAuthorEmail();
|
||||
std::pair<wxString, wxString> defaultAuthor = getDefaultAuthorAndEmail();
|
||||
m_author->SetValue( defaultAuthor.first );
|
||||
m_authorEmail->SetValue( defaultAuthor.second );
|
||||
m_author->Disable();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -121,7 +121,7 @@ wxString DS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
|
||||
|
||||
if( token->IsSameAs( wxT( "KICAD_VERSION" ) ) && PgmOrNull() )
|
||||
{
|
||||
*token = wxString::Format( wxT( "%s %s" ), productName, GetSemanticVersion() );
|
||||
*token = wxString::Format( wxT( "%s %s" ), productName, GetBaseVersion() );
|
||||
tokenUpdated = true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "#" ) ) )
|
||||
|
||||
@@ -483,7 +483,7 @@ void EDA_BASE_FRAME::ReCreateMenuBar()
|
||||
* ensure that they do not occur within the same event handling call stack.
|
||||
*/
|
||||
|
||||
CallAfter( [&]()
|
||||
CallAfter( [this]()
|
||||
{
|
||||
if( !m_isClosing )
|
||||
doReCreateMenuBar();
|
||||
|
||||
@@ -1955,16 +1955,6 @@ static struct EDA_SHAPE_DESC
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( EDA_SHAPE );
|
||||
|
||||
auto isNotPolygon =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() != SHAPE_T::POLY;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isNotPolygonOrCircle = []( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
|
||||
+1
-1
@@ -1176,7 +1176,7 @@ static struct EDA_TEXT_DESC
|
||||
&EDA_TEXT::SetTextAngleDegrees, &EDA_TEXT::GetTextAngleDegrees,
|
||||
PROPERTY_DISPLAY::PT_DEGREE ) );
|
||||
|
||||
const wxString textProps = _( "Text Properties" );
|
||||
const wxString textProps = _HKI( "Text Properties" );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _HKI( "Text" ),
|
||||
&EDA_TEXT::SetText, &EDA_TEXT::GetText ),
|
||||
|
||||
+29
-5
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -122,10 +122,7 @@ void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
|
||||
const VECTOR2I& aPt2,
|
||||
const VECTOR2I& aPt3 )> aCallback ) const
|
||||
{
|
||||
// Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
|
||||
// the triangulation to see if it has been edited, and glyphs after creation are read-only.
|
||||
if( TriangulatedPolyCount() == 0 )
|
||||
const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
|
||||
const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
|
||||
|
||||
for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
|
||||
{
|
||||
@@ -141,3 +138,30 @@ void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
|
||||
}
|
||||
|
||||
|
||||
void OUTLINE_GLYPH::CacheTriangulation( bool aPartition, bool aSimplify )
|
||||
{
|
||||
// Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
|
||||
// the triangulation to see if it has been edited, and glyphs are invariant after creation.
|
||||
//
|
||||
// Also forces "partition" to false as we never want to partition a glyph.
|
||||
|
||||
if( TriangulatedPolyCount() == 0 )
|
||||
SHAPE_POLY_SET::CacheTriangulation( false, aSimplify );
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> OUTLINE_GLYPH::GetTriangulationData() const
|
||||
{
|
||||
std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> data;
|
||||
|
||||
for( const std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>& poly : m_triangulatedPolys )
|
||||
data.push_back( std::make_unique<SHAPE_POLY_SET::TRIANGULATED_POLYGON>( *poly ) );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void OUTLINE_GLYPH::CacheTriangulation( std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>>& aHintData )
|
||||
{
|
||||
cacheTriangulation( false, false, &aHintData );
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2024 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Outline font class
|
||||
*
|
||||
@@ -39,8 +39,8 @@ OUTLINE_DECOMPOSER::OUTLINE_DECOMPOSER( FT_Outline& aOutline ) :
|
||||
|
||||
static VECTOR2D toVector2D( const FT_Vector* aFreeTypeVector )
|
||||
{
|
||||
return VECTOR2D( aFreeTypeVector->x * GLYPH_SIZE_SCALER,
|
||||
aFreeTypeVector->y * GLYPH_SIZE_SCALER );
|
||||
return VECTOR2D( (double) aFreeTypeVector->x * GLYPH_SIZE_SCALER,
|
||||
(double) aFreeTypeVector->y * GLYPH_SIZE_SCALER );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2024 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -255,6 +255,38 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
|
||||
struct GLYPH_CACHE_KEY {
|
||||
FT_Face face;
|
||||
hb_codepoint_t codepoint;
|
||||
bool fakeItalic;
|
||||
bool fakeBold;
|
||||
bool mirror;
|
||||
EDA_ANGLE angle;
|
||||
|
||||
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
|
||||
{
|
||||
return face == rhs.face && codepoint == rhs.codepoint
|
||||
&& fakeItalic == rhs.fakeItalic && fakeBold == rhs.fakeBold
|
||||
&& mirror == rhs.mirror && angle == rhs.angle;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<GLYPH_CACHE_KEY>
|
||||
{
|
||||
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
|
||||
{
|
||||
return hash<const void*>()( k.face ) ^ hash<unsigned>()( k.codepoint )
|
||||
^ hash<int>()( k.fakeItalic ) ^ hash<int>()( k.fakeBold )
|
||||
^ hash<int>()( k.mirror ) ^ hash<int>()( k.angle.AsTenthsOfADegree() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
@@ -295,6 +327,10 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
if( aGlyphs )
|
||||
aGlyphs->reserve( glyphCount );
|
||||
|
||||
// GLYPH_DATA is a collection of all outlines in the glyph; for example the 'o' glyph
|
||||
// generally contains 2 contours, one for the glyph outline and one for the hole
|
||||
static std::unordered_map<GLYPH_CACHE_KEY, GLYPH_DATA> s_glyphCache;
|
||||
|
||||
for( unsigned int i = 0; i < glyphCount; i++ )
|
||||
{
|
||||
// Don't process glyphs that were already included in a previous cluster
|
||||
@@ -303,64 +339,67 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
if( m_fakeItal )
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, m_fakeItal, m_fakeBold,
|
||||
aMirror, aAngle };
|
||||
GLYPH_DATA& glyphData = s_glyphCache[ key ];
|
||||
|
||||
if( glyphData.m_Contours.empty() )
|
||||
{
|
||||
FT_Matrix matrix;
|
||||
// Create a 12 degree slant
|
||||
const float angle = (float)( -M_PI * 12.0f ) / 180.0f;
|
||||
matrix.xx = (FT_Fixed) ( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed) ( -sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
matrix.yy = (FT_Fixed) ( 1 * 0x10000L );
|
||||
if( m_fakeItal )
|
||||
{
|
||||
FT_Matrix matrix;
|
||||
// Create a 12 degree slant
|
||||
const float angle = (float)( -M_PI * 12.0f ) / 180.0f;
|
||||
matrix.xx = (FT_Fixed) ( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed) ( -sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
matrix.yy = (FT_Fixed) ( 1 * 0x10000L );
|
||||
|
||||
FT_Set_Transform( face, &matrix, 0 );
|
||||
}
|
||||
FT_Set_Transform( face, &matrix, nullptr );
|
||||
}
|
||||
|
||||
FT_Load_Glyph( face, glyphInfo[i].codepoint, FT_LOAD_NO_BITMAP );
|
||||
FT_Load_Glyph( face, glyphInfo[i].codepoint, FT_LOAD_NO_BITMAP );
|
||||
|
||||
if( m_fakeBold )
|
||||
FT_Outline_Embolden( &face->glyph->outline, 1 << 6 );
|
||||
if( m_fakeBold )
|
||||
FT_Outline_Embolden( &face->glyph->outline, 1 << 6 );
|
||||
|
||||
// contours is a collection of all outlines in the glyph; for example the 'o' glyph
|
||||
// generally contains 2 contours, one for the glyph outline and one for the hole
|
||||
std::vector<CONTOUR> contours;
|
||||
OUTLINE_DECOMPOSER decomposer( face->glyph->outline );
|
||||
|
||||
OUTLINE_DECOMPOSER decomposer( face->glyph->outline );
|
||||
if( !decomposer.OutlineToSegments( &glyphData.m_Contours ) )
|
||||
{
|
||||
double hb_advance = glyphPos[i].x_advance * GLYPH_SIZE_SCALER;
|
||||
BOX2D tofuBox( { scaler * 0.03, 0.0 },
|
||||
{ hb_advance - scaler * 0.02, scaler * 0.72 } );
|
||||
|
||||
if( !decomposer.OutlineToSegments( &contours ) )
|
||||
{
|
||||
double hb_advance = glyphPos[i].x_advance * GLYPH_SIZE_SCALER;
|
||||
BOX2D tofuBox( { scaler * 0.03, 0.0 },
|
||||
{ hb_advance - scaler * 0.02, scaler * 0.72 } );
|
||||
glyphData.m_Contours.clear();
|
||||
|
||||
contours.clear();
|
||||
CONTOUR outline;
|
||||
outline.m_Winding = 1;
|
||||
outline.m_Orientation = FT_ORIENTATION_TRUETYPE;
|
||||
outline.m_Points.push_back( tofuBox.GetPosition() );
|
||||
outline.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
outline.m_Points.push_back( tofuBox.GetSize() );
|
||||
outline.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
glyphData.m_Contours.push_back( outline );
|
||||
|
||||
CONTOUR outline;
|
||||
outline.m_Winding = 1;
|
||||
outline.m_Orientation = FT_ORIENTATION_TRUETYPE;
|
||||
outline.m_Points.push_back( tofuBox.GetPosition() );
|
||||
outline.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
outline.m_Points.push_back( tofuBox.GetSize() );
|
||||
outline.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
contours.push_back( outline );
|
||||
|
||||
CONTOUR hole;
|
||||
tofuBox.Move( { scaler * 0.06, scaler * 0.06 } );
|
||||
tofuBox.SetSize( { tofuBox.GetWidth() - scaler * 0.06,
|
||||
tofuBox.GetHeight() - scaler * 0.06 } );
|
||||
hole.m_Winding = 1;
|
||||
hole.m_Orientation = FT_ORIENTATION_NONE;
|
||||
hole.m_Points.push_back( tofuBox.GetPosition() );
|
||||
hole.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
hole.m_Points.push_back( tofuBox.GetSize() );
|
||||
hole.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
contours.push_back( hole );
|
||||
CONTOUR hole;
|
||||
tofuBox.Move( { scaler * 0.06, scaler * 0.06 } );
|
||||
tofuBox.SetSize( { tofuBox.GetWidth() - scaler * 0.06,
|
||||
tofuBox.GetHeight() - scaler * 0.06 } );
|
||||
hole.m_Winding = 1;
|
||||
hole.m_Orientation = FT_ORIENTATION_NONE;
|
||||
hole.m_Points.push_back( tofuBox.GetPosition() );
|
||||
hole.m_Points.push_back( { tofuBox.GetSize().x, tofuBox.GetPosition().y } );
|
||||
hole.m_Points.push_back( tofuBox.GetSize() );
|
||||
hole.m_Points.push_back( { tofuBox.GetPosition().x, tofuBox.GetSize().y } );
|
||||
glyphData.m_Contours.push_back( hole );
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<OUTLINE_GLYPH> glyph = std::make_unique<OUTLINE_GLYPH>();
|
||||
std::vector<SHAPE_LINE_CHAIN> holes;
|
||||
|
||||
for( CONTOUR& c : contours )
|
||||
for( CONTOUR& c : glyphData.m_Contours )
|
||||
{
|
||||
std::vector<VECTOR2D> points = c.m_Points;
|
||||
SHAPE_LINE_CHAIN shape;
|
||||
@@ -411,6 +450,16 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
}
|
||||
}
|
||||
|
||||
if( glyphData.m_TriangulationData.empty() )
|
||||
{
|
||||
glyph->CacheTriangulation( false, false );
|
||||
glyphData.m_TriangulationData = glyph->GetTriangulationData();
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->CacheTriangulation( glyphData.m_TriangulationData );
|
||||
}
|
||||
|
||||
aGlyphs->push_back( std::move( glyph ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
|
||||
unsigned int CAIRO_COMPOSITOR::CreateBuffer()
|
||||
{
|
||||
// Pixel storage
|
||||
BitmapPtr bitmap = new uint32_t[m_bufferSize]();
|
||||
BitmapPtr bitmap = new uint8_t[m_bufferSize]();
|
||||
|
||||
// Create the Cairo surface
|
||||
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
||||
@@ -138,7 +138,7 @@ void CAIRO_COMPOSITOR::Begin()
|
||||
void CAIRO_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
||||
{
|
||||
// Clear the pixel storage
|
||||
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize * sizeof( int ) );
|
||||
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1413,20 +1413,34 @@ void CAIRO_GAL::EndDrawing()
|
||||
|
||||
// Now translate the raw context data from the format stored
|
||||
// by cairo into a format understood by wxImage.
|
||||
pixman_image_t* dstImg = pixman_image_create_bits(
|
||||
wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8
|
||||
: PIXMAN_r8g8b8,
|
||||
m_screenSize.x, m_screenSize.y, (uint32_t*) m_wxOutput, m_wxBufferWidth * 3 );
|
||||
pixman_image_t* srcImg =
|
||||
pixman_image_create_bits( PIXMAN_a8r8g8b8, m_screenSize.x, m_screenSize.y,
|
||||
(uint32_t*) m_bitmapBuffer, m_wxBufferWidth * 4 );
|
||||
int height = m_screenSize.y;
|
||||
int stride = m_stride;
|
||||
|
||||
pixman_image_composite( PIXMAN_OP_SRC, srcImg, nullptr, dstImg, 0, 0, 0, 0, 0, 0,
|
||||
m_screenSize.x, m_screenSize.y );
|
||||
unsigned char* srcRow = m_bitmapBuffer;
|
||||
unsigned char* dst = m_wxOutput;
|
||||
|
||||
// Free allocated memory
|
||||
pixman_image_unref( srcImg );
|
||||
pixman_image_unref( dstImg );
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
for( int x = 0; x < stride; x += 4 )
|
||||
{
|
||||
const unsigned char* src = srcRow + x;
|
||||
|
||||
#if defined( __BYTE_ORDER__ ) && ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
|
||||
// XRGB
|
||||
dst[0] = src[1];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[3];
|
||||
#else
|
||||
// BGRX
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
#endif
|
||||
dst += 3;
|
||||
}
|
||||
|
||||
srcRow += stride;
|
||||
}
|
||||
|
||||
wxImage img( m_wxBufferWidth, m_screenSize.y, m_wxOutput, true );
|
||||
wxBitmap bmp( img );
|
||||
@@ -1582,15 +1596,12 @@ void CAIRO_GAL::allocateBitmaps()
|
||||
{
|
||||
m_wxBufferWidth = m_screenSize.x;
|
||||
|
||||
while( ( ( m_wxBufferWidth * 3 ) % 4 ) != 0 )
|
||||
m_wxBufferWidth++;
|
||||
|
||||
// Create buffer, use the system independent Cairo context backend
|
||||
m_stride = cairo_format_stride_for_width( GAL_FORMAT, m_wxBufferWidth );
|
||||
m_bufferSize = m_stride * m_screenSize.y;
|
||||
|
||||
wxASSERT( m_bitmapBuffer == nullptr );
|
||||
m_bitmapBuffer = new unsigned char[m_bufferSize * 4];
|
||||
m_bitmapBuffer = new unsigned char[m_bufferSize];
|
||||
|
||||
wxASSERT( m_wxOutput == nullptr );
|
||||
m_wxOutput = new unsigned char[m_wxBufferWidth * 3 * m_screenSize.y];
|
||||
|
||||
@@ -2891,30 +2891,9 @@ void OPENGL_GAL::DrawGlyphs( const std::vector<std::unique_ptr<KIFONT::GLYPH>>&
|
||||
}
|
||||
else if( allGlyphsAreOutline )
|
||||
{
|
||||
// Optimized path for stroke fonts that pre-reserves glyph triangles.
|
||||
// Optimized path for outline fonts that pre-reserves glyph triangles.
|
||||
int triangleCount = 0;
|
||||
|
||||
if( aGlyphs.size() > 0 )
|
||||
{
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_loop( aGlyphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
{
|
||||
auto glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( aGlyphs.at( ii ).get() );
|
||||
|
||||
// Only call CacheTriangulation() if it has never been done before.
|
||||
// Otherwise we'll hash the triangulation to see if it has been edited,
|
||||
// and all our glpyh editing ops update the triangulation anyway.
|
||||
if( glyph->TriangulatedPolyCount() == 0 )
|
||||
glyph->CacheTriangulation( false );
|
||||
}
|
||||
} );
|
||||
tp.wait_for_tasks();
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
|
||||
{
|
||||
const auto& outlineGlyph = static_cast<const KIFONT::OUTLINE_GLYPH&>( *glyph );
|
||||
|
||||
@@ -261,7 +261,7 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aCl
|
||||
if( aNumPoints > 0 )
|
||||
DrawCubicBezierPath( aPoints, aNumPoints, collectedPathPoints );
|
||||
|
||||
if( aClosedPath )
|
||||
if( aClosedPath && collectedPathPoints.size() > 2 )
|
||||
DrawPolygon( collectedPathPoints, aStroke, aFilled, aFillColor );
|
||||
else
|
||||
DrawLineSegments( collectedPathPoints, aStroke );
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <bezier_curves.h>
|
||||
#include <ki_exception.h>
|
||||
#include <wx/translation.h>
|
||||
#include <eda_text.h>
|
||||
|
||||
|
||||
double EASYEDA_PARSER_BASE::Convert( const wxString& aValue )
|
||||
@@ -66,6 +67,49 @@ double EASYEDA_PARSER_BASE::RelPosY( const wxString& aValue )
|
||||
}
|
||||
|
||||
|
||||
void EASYEDA_PARSER_BASE::TransformTextToBaseline( EDA_TEXT* textItem,
|
||||
const wxString& baselineAlign, bool invertY )
|
||||
{
|
||||
int upOffset = 0;
|
||||
|
||||
if( baselineAlign == wxS( "" ) || baselineAlign == wxS( "auto" )
|
||||
|| baselineAlign == wxS( "use-script" ) || baselineAlign == wxS( "no-change" )
|
||||
|| baselineAlign == wxS( "reset-size" ) || baselineAlign == wxS( "alphabetic" )
|
||||
|| baselineAlign == wxS( "inherit" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y;
|
||||
}
|
||||
else if( baselineAlign == wxS( "ideographic" ) || baselineAlign == wxS( "text-after-edge" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 1.2;
|
||||
}
|
||||
else if( baselineAlign == wxS( "central" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.5;
|
||||
}
|
||||
else if( baselineAlign == wxS( "middle" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.6;
|
||||
}
|
||||
else if( baselineAlign == wxS( "mathematical" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.1;
|
||||
}
|
||||
else if( baselineAlign == wxS( "hanging" ) || baselineAlign == wxS( "text-before-edge" ) )
|
||||
{
|
||||
upOffset = 0;
|
||||
}
|
||||
|
||||
VECTOR2I offset( 0, -upOffset );
|
||||
RotatePoint( offset, textItem->GetTextAngle() );
|
||||
|
||||
if( invertY )
|
||||
offset.y = -offset.y;
|
||||
|
||||
textItem->SetTextPos( textItem->GetTextPos() + offset );
|
||||
}
|
||||
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN>
|
||||
EASYEDA_PARSER_BASE::ParseLineChains( const wxString& data, int aArcMinSegLen, bool aForceClosed )
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <math/vector2d.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class EDA_TEXT;
|
||||
|
||||
class EASYEDA_PARSER_BASE
|
||||
{
|
||||
public:
|
||||
@@ -58,7 +60,9 @@ public:
|
||||
return ScalePos( aVec - m_relOrigin );
|
||||
}
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen,
|
||||
void TransformTextToBaseline( EDA_TEXT* textItem, const wxString& baselineAlign, bool invertY );
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN> ParseLineChains( const wxString& aData, int aArcMinSegLen,
|
||||
bool aForceClosed );
|
||||
|
||||
protected:
|
||||
|
||||
@@ -150,14 +150,28 @@ nlohmann::json EASYEDAPRO::ReadProjectOrDeviceFile( const wxString& aZipFileName
|
||||
{
|
||||
wxString name = entry->GetName();
|
||||
|
||||
if( name == wxS( "project.json" ) || name == wxS( "device.json" ) )
|
||||
try
|
||||
{
|
||||
wxMemoryOutputStream memos;
|
||||
memos << zip;
|
||||
wxStreamBuffer* buf = memos.GetOutputStreamBuffer();
|
||||
wxString str( (char*) buf->GetBufferStart(), buf->GetBufferSize() );
|
||||
if( name == wxS( "project.json" ) || name == wxS( "device.json" ) )
|
||||
{
|
||||
wxMemoryOutputStream memos;
|
||||
memos << zip;
|
||||
wxStreamBuffer* buf = memos.GetOutputStreamBuffer();
|
||||
|
||||
return nlohmann::json::parse( str );
|
||||
wxString str =
|
||||
wxString::FromUTF8( (char*) buf->GetBufferStart(), buf->GetBufferSize() );
|
||||
|
||||
return nlohmann::json::parse( str );
|
||||
}
|
||||
}
|
||||
catch( nlohmann::json::exception& e )
|
||||
{
|
||||
THROW_IO_ERROR(
|
||||
wxString::Format( _( "JSON error reading '%s': %s" ), name, e.what() ) );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error reading '%s': %s" ), name, e.what() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-10
@@ -242,13 +242,16 @@ void LIB_TREE_NODE_ITEM::Update( LIB_TREE_ITEM* aItem )
|
||||
void LIB_TREE_NODE_ITEM::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
// aMatcher test is additive
|
||||
// aMatcher test is additive, but if we don't match the given term at all, it nulls out
|
||||
if( aMatcher )
|
||||
m_Score += aMatcher->ScoreTerms( m_SearchTerms );
|
||||
{
|
||||
int currentScore = aMatcher->ScoreTerms( m_SearchTerms );
|
||||
|
||||
// aLib test is additive
|
||||
if( !aLib.IsEmpty() && m_Parent->m_Name.Lower().Matches( aLib ) )
|
||||
m_Score += 1;
|
||||
if( m_Score >= 0 && currentScore > 0 )
|
||||
m_Score += currentScore;
|
||||
else
|
||||
m_Score = -1; // Item has failed to match this term, rule it out
|
||||
}
|
||||
|
||||
// aFilter test is subtractive
|
||||
if( aFilter && !(*aFilter)(*this) )
|
||||
@@ -287,18 +290,27 @@ LIB_TREE_NODE_ITEM& LIB_TREE_NODE_LIBRARY::AddItem( LIB_TREE_ITEM* aItem )
|
||||
void LIB_TREE_NODE_LIBRARY::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
int newScore = 0;
|
||||
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
{
|
||||
child->UpdateScore( aMatcher, aLib, aFilter );
|
||||
m_Score = std::max( m_Score, child->m_Score );
|
||||
newScore = std::max( newScore, child->m_Score );
|
||||
}
|
||||
|
||||
// aLib test is additive
|
||||
if( !aLib.IsEmpty() && m_Name.Lower().Matches( aLib ) )
|
||||
// Each time UpdateScore is called for a library, child (item) scores may go up or down.
|
||||
// If the all go down to zero, we need to make sure to drop the library from the list.
|
||||
if( newScore > 0 )
|
||||
m_Score = std::max( m_Score, newScore );
|
||||
else
|
||||
m_Score = 0;
|
||||
|
||||
// aLib test is additive, but only when we've already accumulated some score from children
|
||||
if( !aLib.IsEmpty() && m_Name.Lower().Matches( aLib ) && m_Score > 0 )
|
||||
m_Score += 1;
|
||||
|
||||
// aMatcher test is additive
|
||||
if( aMatcher )
|
||||
// aMatcher test is additive, but only when we've already accumulated some score from children
|
||||
if( aMatcher && m_Score > 0 )
|
||||
m_Score += aMatcher->ScoreTerms( m_SearchTerms );
|
||||
|
||||
// show all nodes if no search/filter/etc. criteria are given
|
||||
|
||||
@@ -91,14 +91,19 @@ public:
|
||||
dc->DrawLines( 6, points );
|
||||
}
|
||||
|
||||
aRect.Deflate( 1 );
|
||||
|
||||
#ifdef __WXOSX__
|
||||
// We should be able to pass wxDATAVIEW_CELL_SELECTED into RenderText() and have it do
|
||||
// the right thing -- but it picks wxSYS_COLOUR_HIGHLIGHTTEXT on MacOS and GTK (instead
|
||||
// the right thing -- but it picks wxSYS_COLOUR_HIGHLIGHTTEXT on MacOS (instead
|
||||
// of wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT).
|
||||
if( aState & wxDATAVIEW_CELL_SELECTED )
|
||||
dc->SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
||||
|
||||
aRect.Deflate( 1 );
|
||||
RenderText( m_text, 0, aRect, dc, 0 );
|
||||
#else
|
||||
RenderText( m_text, 0, aRect, dc, aState );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -674,10 +679,10 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
||||
{
|
||||
const wxString& key = m_colIdxMap.at( aCol );
|
||||
|
||||
if( node->m_Fields.count( key ) )
|
||||
valueStr = UnescapeString( node->m_Fields.at( key ) );
|
||||
else if( key == wxT( "Description" ) )
|
||||
if( key == wxT( "Description" ) )
|
||||
valueStr = UnescapeString( node->m_Desc );
|
||||
else if( node->m_Fields.count( key ) )
|
||||
valueStr = UnescapeString( node->m_Fields.at( key ) );
|
||||
else
|
||||
valueStr = wxEmptyString;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@ PGM_BASE::PGM_BASE()
|
||||
m_argcUtf8 = 0;
|
||||
m_argvUtf8 = nullptr;
|
||||
m_splash = nullptr;
|
||||
m_PropertyGridInitialized = false;
|
||||
|
||||
setLanguageId( wxLANGUAGE_DEFAULT );
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -647,6 +647,16 @@ void GERBER_PLOTTER::writeApertureList()
|
||||
std::vector<VECTOR2I> corners;
|
||||
VECTOR2I half_size( tool.m_Size.x/2-tool.m_Radius, tool.m_Size.y/2-tool.m_Radius );
|
||||
|
||||
// Ensure half_size.x and half_size.y > minimal value to avoid shapes
|
||||
// with null size (especially the rectangle with coordinates corners)
|
||||
// Because the minimal value for a non nul Gerber coord in 10nm
|
||||
// in format 4.5, use 10 nm as minimal value.
|
||||
// (Even in 4.6 format, use 10 nm, because gerber viewers can have
|
||||
// a internal unit bigger than 1 nm)
|
||||
const int min_size_value = 10;
|
||||
half_size.x = std::max( half_size.x, min_size_value );
|
||||
half_size.y = std::max( half_size.y, min_size_value );
|
||||
|
||||
corners.emplace_back( -half_size.x, -half_size.y );
|
||||
corners.emplace_back( half_size.x, -half_size.y );
|
||||
corners.emplace_back( half_size.x, half_size.y );
|
||||
|
||||
@@ -37,8 +37,7 @@ const wxString COLOR_SETTINGS::COLOR_BUILTIN_CLASSIC = "_builtin_classic";
|
||||
|
||||
COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) :
|
||||
JSON_SETTINGS( std::move( aFilename ), SETTINGS_LOC::COLORS, colorsSchemaVersion ),
|
||||
m_overrideSchItemColors( false ),
|
||||
m_useBoardStackupColors( true )
|
||||
m_overrideSchItemColors( false )
|
||||
{
|
||||
if( aAbsolutePath )
|
||||
SetLocation( SETTINGS_LOC::NONE );
|
||||
@@ -49,9 +48,6 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath )
|
||||
m_params.emplace_back( new PARAM<bool>( "schematic.override_item_colors",
|
||||
&m_overrideSchItemColors, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "3d_viewer.use_board_stackup_colors",
|
||||
&m_useBoardStackupColors, true ) );
|
||||
|
||||
#define CLR( x, y ) \
|
||||
wxASSERT( s_defaultTheme.count( y ) ); \
|
||||
m_params.emplace_back( new COLOR_MAP_PARAM( x, y, s_defaultTheme.at( y ), &m_colors ) );
|
||||
@@ -282,7 +278,6 @@ void COLOR_SETTINGS::initFromOther( const COLOR_SETTINGS& aOther )
|
||||
{
|
||||
m_displayName = aOther.m_displayName;
|
||||
m_overrideSchItemColors = aOther.m_overrideSchItemColors;
|
||||
m_useBoardStackupColors = aOther.m_useBoardStackupColors;
|
||||
m_colors = aOther.m_colors;
|
||||
m_defaultColors = aOther.m_defaultColors;
|
||||
m_writeFile = aOther.m_writeFile;
|
||||
|
||||
+26
-23
@@ -313,40 +313,40 @@ wxString UnescapeString( const wxString& aSource )
|
||||
}
|
||||
else
|
||||
{
|
||||
token.append( ch );
|
||||
token << ch;
|
||||
}
|
||||
}
|
||||
|
||||
if( !terminated )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
|
||||
newbuf << wxT( "{" ) << UnescapeString( token );
|
||||
}
|
||||
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
|
||||
}
|
||||
else if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
|
||||
else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
|
||||
else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
|
||||
else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
|
||||
else if( token == wxT( "backslash" ) ) newbuf.append( wxT( "\\" ) );
|
||||
else if( token == wxT( "slash" ) ) newbuf.append( wxT( "/" ) );
|
||||
else if( token == wxT( "bar" ) ) newbuf.append( wxT( "|" ) );
|
||||
else if( token == wxT( "comma" ) ) newbuf.append( wxT( "," ) );
|
||||
else if( token == wxT( "colon" ) ) newbuf.append( wxT( ":" ) );
|
||||
else if( token == wxT( "space" ) ) newbuf.append( wxT( " " ) );
|
||||
else if( token == wxT( "dollar" ) ) newbuf.append( wxT( "$" ) );
|
||||
else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
|
||||
else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
|
||||
else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
|
||||
else if( token == wxT( "dblquote" ) ) newbuf << wxT( "\"" );
|
||||
else if( token == wxT( "quote" ) ) newbuf << wxT( "'" );
|
||||
else if( token == wxT( "lt" ) ) newbuf << wxT( "<" );
|
||||
else if( token == wxT( "gt" ) ) newbuf << wxT( ">" );
|
||||
else if( token == wxT( "backslash" ) ) newbuf << wxT( "\\" );
|
||||
else if( token == wxT( "slash" ) ) newbuf << wxT( "/" );
|
||||
else if( token == wxT( "bar" ) ) newbuf << wxT( "|" );
|
||||
else if( token == wxT( "comma" ) ) newbuf << wxT( "," );
|
||||
else if( token == wxT( "colon" ) ) newbuf << wxT( ":" );
|
||||
else if( token == wxT( "space" ) ) newbuf << wxT( " " );
|
||||
else if( token == wxT( "dollar" ) ) newbuf << wxT( "$" );
|
||||
else if( token == wxT( "tab" ) ) newbuf << wxT( "\t" );
|
||||
else if( token == wxT( "return" ) ) newbuf << wxT( "\n" );
|
||||
else if( token == wxT( "brace" ) ) newbuf << wxT( "{" );
|
||||
else
|
||||
{
|
||||
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
|
||||
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newbuf.append( ch );
|
||||
newbuf << ch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,11 +785,14 @@ int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreC
|
||||
// Any numerical comparisons to here are identical.
|
||||
if( aIgnoreCase )
|
||||
{
|
||||
if( wxToupper( c1 ) < wxToupper( c2 ) )
|
||||
return -1;
|
||||
if( c1 != c2 )
|
||||
{
|
||||
wxUniChar uc1 = wxToupper( c1 );
|
||||
wxUniChar uc2 = wxToupper( c2 );
|
||||
|
||||
if( wxToupper( c1 ) > wxToupper( c2 ) )
|
||||
return 1;
|
||||
if( uc1 != uc2 )
|
||||
return uc1 < uc2 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -54,8 +54,16 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
|
||||
case FOOTPRINT_FIELD: return s_CanonicalFootprint; // The footprint for use with Pcbnew
|
||||
case DATASHEET_FIELD: return s_CanonicalDatasheet; // Link to a datasheet for symbol
|
||||
case DESCRIPTION_FIELD: return s_CanonicalDescription; // The symbol description
|
||||
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
|
||||
default: break;
|
||||
}
|
||||
|
||||
wxString str( wxS( "Field" ) );
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
str << std::to_wstring( aFieldNdx );
|
||||
#else
|
||||
str << std::to_string( aFieldNdx );
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
switch( aFieldNdx )
|
||||
|
||||
+16
-11
@@ -39,6 +39,7 @@
|
||||
#include <wx/stc/stc.h>
|
||||
#include <textentry_tricks.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/grid.h>
|
||||
#include <widgets/ui_common.h>
|
||||
|
||||
using namespace std::placeholders;
|
||||
@@ -436,7 +437,8 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
// events first.
|
||||
if( dynamic_cast<wxTextEntry*>( focus )
|
||||
|| dynamic_cast<wxStyledTextCtrl*>( focus )
|
||||
|| dynamic_cast<wxListView*>( focus ) )
|
||||
|| dynamic_cast<wxListView*>( focus )
|
||||
|| dynamic_cast<wxGrid*>( focus ) )
|
||||
{
|
||||
// Original key event has been lost, so we have to re-create it from the menu's
|
||||
// wxAcceleratorEntry.
|
||||
@@ -451,7 +453,7 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
keyEvent.m_shiftDown = ( acceleratorKey->GetFlags() & wxMOD_SHIFT ) > 0;
|
||||
keyEvent.m_altDown = ( acceleratorKey->GetFlags() & wxMOD_ALT ) > 0;
|
||||
|
||||
if( auto ctrl = dynamic_cast<wxTextEntry*>( focus ) )
|
||||
if( wxTextEntry* ctrl = dynamic_cast<wxTextEntry*>( focus ) )
|
||||
TEXTENTRY_TRICKS::OnCharHook( ctrl, keyEvent );
|
||||
else
|
||||
focus->HandleWindowEvent( keyEvent );
|
||||
@@ -462,10 +464,14 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
focus->HandleWindowEvent( keyEvent );
|
||||
}
|
||||
|
||||
// If the event was used as KEY event (not skipped) by the focused window,
|
||||
// just finish.
|
||||
// Otherwise this is actually a wxEVT_COMMAND_MENU_SELECTED, or the
|
||||
// focused window is read only
|
||||
// Don't bubble-up dangerous actions; the target may be behind a modeless dialog.
|
||||
// Cf. https://gitlab.com/kicad/code/kicad/-/issues/17229
|
||||
if( keyEvent.GetKeyCode() == WXK_BACK || keyEvent.GetKeyCode() == WXK_DELETE )
|
||||
return;
|
||||
|
||||
// If the event was used as a KEY event (not skipped) by the focused window,
|
||||
// just finish. Otherwise this is actually a wxEVT_COMMAND_MENU_SELECTED (or the
|
||||
// focused window is read only).
|
||||
if( !keyEvent.GetSkipped() )
|
||||
return;
|
||||
}
|
||||
@@ -546,11 +552,10 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
|
||||
{
|
||||
evt->SetMousePosition( g_menu_open_position );
|
||||
}
|
||||
// Check if it is a menubar event, and don't get any position if it is.
|
||||
// The original hack is to see if g_last_menu_highlighted_id matches to see if it's a menubar menu event
|
||||
// IsAttached() checks to see if a menubar was attached to the menu by wx, and if there is one, then the event
|
||||
// is from a menubar menu.
|
||||
else if( IsAttached() || ( g_last_menu_highlighted_id == aEvent.GetId() ) )
|
||||
// Check if it is a menubar event, and don't get any position if it is. Note that we
|
||||
// can't use IsAttached() here, as it only differentiates a context menu, and we also
|
||||
// want a hotkey to generate a position.
|
||||
else if( g_last_menu_highlighted_id == aEvent.GetId() )
|
||||
{
|
||||
evt->SetHasPosition( false );
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void ACTION_TOOLBAR_PALETTE::AddAction( const TOOL_ACTION& aAction )
|
||||
button->SetBitmap( normalBmp );
|
||||
button->SetDisabledBitmap( KiDisabledBitmapBundle( aAction.GetIcon() ) );
|
||||
button->SetPadding( padding );
|
||||
button->SetToolTip( aAction.GetTooltip() );
|
||||
button->SetToolTip( aAction.GetButtonTooltip() );
|
||||
button->AcceptDragInAsClick();
|
||||
button->SetBitmapCentered();
|
||||
|
||||
@@ -233,7 +233,7 @@ void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction, bool aIsToggleEntry, bool
|
||||
AddTool( toolId, wxEmptyString, KiBitmapBundle( aAction.GetIcon() ),
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ),
|
||||
aIsToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL,
|
||||
aAction.GetTooltip(), wxEmptyString, nullptr );
|
||||
aAction.GetButtonTooltip(), wxEmptyString, nullptr );
|
||||
|
||||
m_toolKinds[ toolId ] = aIsToggleEntry;
|
||||
m_toolActions[ toolId ] = &aAction;
|
||||
@@ -246,8 +246,8 @@ void ACTION_TOOLBAR::AddButton( const TOOL_ACTION& aAction )
|
||||
int toolId = aAction.GetUIId();
|
||||
|
||||
AddTool( toolId, wxEmptyString, KiBitmapBundle( aAction.GetIcon() ),
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ),
|
||||
wxITEM_NORMAL, aAction.GetTooltip(), wxEmptyString, nullptr );
|
||||
KiDisabledBitmapBundle( aAction.GetIcon() ), wxITEM_NORMAL,
|
||||
aAction.GetButtonTooltip(), wxEmptyString, nullptr );
|
||||
|
||||
m_toolKinds[ toolId ] = false;
|
||||
m_toolActions[ toolId ] = &aAction;
|
||||
|
||||
+1
-13
@@ -120,14 +120,12 @@ TOOL_ACTION ACTIONS::print( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( MD_CTRL + 'P' )
|
||||
.LegacyHotkeyName( "Print" )
|
||||
.FriendlyName( _( "Print..." ) )
|
||||
.Tooltip( _( "Print" ) )
|
||||
.Icon( BITMAPS::print_button ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::plot( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.plot" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Plot..." ) )
|
||||
.Tooltip( _( "Plot" ) )
|
||||
.Icon( BITMAPS::plot ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::quit( TOOL_ACTION_ARGS()
|
||||
@@ -408,7 +406,6 @@ TOOL_ACTION ACTIONS::zoomFitScreen( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom Auto" )
|
||||
.FriendlyName( _( "Zoom to Fit" ) )
|
||||
.Tooltip( _( "Zoom to Fit" ) )
|
||||
.Icon( BITMAPS::zoom_fit_in_page ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomFitObjects( TOOL_ACTION_ARGS()
|
||||
@@ -416,7 +413,6 @@ TOOL_ACTION ACTIONS::zoomFitObjects( TOOL_ACTION_ARGS()
|
||||
.Scope( AS_GLOBAL )
|
||||
.DefaultHotkey( MD_CTRL + WXK_HOME )
|
||||
.FriendlyName( _( "Zoom to Objects" ) )
|
||||
.Tooltip( _( "Zoom to Objects" ) )
|
||||
.Icon( BITMAPS::zoom_fit_to_objects ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomIn( TOOL_ACTION_ARGS()
|
||||
@@ -429,7 +425,6 @@ TOOL_ACTION ACTIONS::zoomIn( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom In" )
|
||||
.FriendlyName( _( "Zoom In at Cursor" ) )
|
||||
.Tooltip( _( "Zoom In at Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_in ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomOut( TOOL_ACTION_ARGS()
|
||||
@@ -442,21 +437,18 @@ TOOL_ACTION ACTIONS::zoomOut( TOOL_ACTION_ARGS()
|
||||
#endif
|
||||
.LegacyHotkeyName( "Zoom Out" )
|
||||
.FriendlyName( _( "Zoom Out at Cursor" ) )
|
||||
.Tooltip( _( "Zoom Out at Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_out ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomInCenter( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.zoomInCenter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Zoom In" ) )
|
||||
.Tooltip( _( "Zoom In" ) )
|
||||
.Icon( BITMAPS::zoom_in ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomOutCenter( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.zoomOutCenter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Zoom Out" ) )
|
||||
.Tooltip( _( "Zoom Out" ) )
|
||||
.Icon( BITMAPS::zoom_out ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS()
|
||||
@@ -465,7 +457,6 @@ TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( WXK_F4 )
|
||||
.LegacyHotkeyName( "Zoom Center" )
|
||||
.FriendlyName( _( "Center on Cursor" ) )
|
||||
.Tooltip( _( "Center on Cursor" ) )
|
||||
.Icon( BITMAPS::zoom_center_on_screen ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::zoomTool( TOOL_ACTION_ARGS()
|
||||
@@ -474,7 +465,6 @@ TOOL_ACTION ACTIONS::zoomTool( TOOL_ACTION_ARGS()
|
||||
.DefaultHotkey( MD_CTRL + WXK_F5 )
|
||||
.LegacyHotkeyName( "Zoom to Selection" )
|
||||
.FriendlyName( _( "Zoom to Selection" ) )
|
||||
.Tooltip( _( "Zoom to Selection" ) )
|
||||
.Icon( BITMAPS::zoom_area )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
@@ -819,19 +809,17 @@ TOOL_ACTION ACTIONS::toggleBoundingBoxes( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.toggleBoundingBoxes" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Draw Bounding Boxes" ) )
|
||||
.Tooltip( _( "Draw Bounding Boxes" ) )
|
||||
.Icon( BITMAPS::gerbview_show_negative_objects ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::selectionTool( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveSelection.selectionTool" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select item(s)" ) )
|
||||
.Tooltip( _( "Select item(s)" ) )
|
||||
.Icon( BITMAPS::cursor )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::measureTool( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveEdit.measureTool" )
|
||||
.Name( "common.Interactive.measureTool" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.DefaultHotkey( MD_CTRL + MD_SHIFT + 'M' )
|
||||
// Don't be tempted to remove "Modern Toolset only". It's in the legacy property name.
|
||||
|
||||
@@ -39,15 +39,7 @@ GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) :
|
||||
{
|
||||
UpdateTitle();
|
||||
SetIcon( BITMAPS::grid_select );
|
||||
|
||||
APP_SETTINGS_BASE* settings = m_parent->config();
|
||||
wxArrayString gridsList;
|
||||
int i = ID_POPUP_GRID_START;
|
||||
|
||||
BuildChoiceList( &gridsList, settings, m_parent );
|
||||
|
||||
for( const wxString& grid : gridsList )
|
||||
Append( i++, grid, wxEmptyString, wxITEM_CHECK );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +69,9 @@ void GRID_MENU::update()
|
||||
while( GetMenuItemCount() > 0 )
|
||||
Delete( FindItemByPosition( 0 ) );
|
||||
|
||||
Add( ACTIONS::gridOrigin );
|
||||
AppendSeparator();
|
||||
|
||||
for( const wxString& grid : gridsList )
|
||||
{
|
||||
int idx = i++;
|
||||
|
||||
@@ -167,6 +167,27 @@ size_t SELECTION::CountType( KICAD_T aType ) const
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I SELECTION::GetReferencePoint() const
|
||||
{
|
||||
if( m_referencePoint )
|
||||
return *m_referencePoint;
|
||||
else
|
||||
return GetBoundingBox().Centre();
|
||||
}
|
||||
|
||||
|
||||
void SELECTION::SetReferencePoint( const VECTOR2I& aP )
|
||||
{
|
||||
m_referencePoint = aP;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION::ClearReferencePoint()
|
||||
{
|
||||
m_referencePoint = std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<KIGFX::VIEW_ITEM*> SELECTION::updateDrawList() const
|
||||
{
|
||||
std::vector<VIEW_ITEM*> items;
|
||||
|
||||
@@ -183,6 +183,21 @@ wxString TOOL_ACTION::GetTooltip( bool aIncludeHotkey ) const
|
||||
}
|
||||
|
||||
|
||||
wxString TOOL_ACTION::GetButtonTooltip() const
|
||||
{
|
||||
// We don't show button text so use the action name as the first line of the tooltip
|
||||
wxString tooltip = GetFriendlyName();
|
||||
|
||||
if( GetHotKey() )
|
||||
tooltip += wxString::Format( wxT( " (%s)" ), KeyNameFromKeyCode( GetHotKey() ) );
|
||||
|
||||
if( !GetTooltip( false ).IsEmpty() )
|
||||
tooltip += '\n' + GetTooltip( false );
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
|
||||
void TOOL_ACTION::SetHotKey( int aKeycode, int aKeycodeAlt )
|
||||
{
|
||||
m_hotKey = aKeycode;
|
||||
|
||||
@@ -362,7 +362,6 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const std
|
||||
|
||||
while( synchronousControl == STS_RUNNING )
|
||||
{
|
||||
wxMilliSleep( 50 );
|
||||
wxYield();
|
||||
}
|
||||
|
||||
@@ -705,7 +704,7 @@ TOOL_EVENT* TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool, const TOOL_EVENT_LIST&
|
||||
{
|
||||
TOOL_STATE* st = m_toolState[aTool];
|
||||
|
||||
wxASSERT( !st->pendingWait ); // everything collapses on two KiYield() in a row
|
||||
wxCHECK( !st->pendingWait, nullptr ); // everything collapses on two KiYield() in a row
|
||||
|
||||
// indicate to the manager that we are going to sleep and we shall be
|
||||
// woken up when an event matching aConditions arrive
|
||||
@@ -942,8 +941,14 @@ void TOOL_MANAGER::DispatchContextMenu( const TOOL_EVENT& aEvent )
|
||||
if( wxWindow* frame = dynamic_cast<wxWindow*>( m_frame ) )
|
||||
frame->PopupMenu( menu.get() );
|
||||
|
||||
// If a menu is canceled then notify tool
|
||||
if( menu->GetSelected() < 0 )
|
||||
// Warp the cursor if a menu item was selected
|
||||
if( menu->GetSelected() >= 0 )
|
||||
{
|
||||
if( m_viewControls && m_warpMouseAfterContextMenu )
|
||||
m_viewControls->WarpMouseCursor( m_menuCursor, true, false );
|
||||
}
|
||||
// Otherwise notify the tool of a cancelled menu
|
||||
else
|
||||
{
|
||||
TOOL_EVENT evt( TC_COMMAND, TA_CHOICE_MENU_CHOICE, -1 );
|
||||
evt.SetHasPosition( false );
|
||||
|
||||
@@ -213,6 +213,27 @@ EDA_ITEM_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) const
|
||||
}
|
||||
|
||||
|
||||
KIID PICKED_ITEMS_LIST::GetPickedItemGroupId( unsigned aIdx ) const
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
return m_ItemsList[aIdx].GetGroupId();
|
||||
|
||||
return KIID();
|
||||
}
|
||||
|
||||
|
||||
bool PICKED_ITEMS_LIST::SetPickedItemGroupId( KIID aGroupId, unsigned aIdx )
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
{
|
||||
m_ItemsList[aIdx].SetGroupId( aGroupId );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PICKED_ITEMS_LIST::SetPickedItem( EDA_ITEM* aItem, unsigned aIdx )
|
||||
{
|
||||
if( aIdx < m_ItemsList.size() )
|
||||
|
||||
+24
-7
@@ -234,6 +234,8 @@ private:
|
||||
int m_groupsSize;
|
||||
|
||||
std::vector<int> m_layers; /// Stores layer numbers used by the item.
|
||||
|
||||
BOX2I m_bbox; /// Cached inserted Bbox for faster removals.
|
||||
};
|
||||
|
||||
|
||||
@@ -326,6 +328,8 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
|
||||
aItem->m_viewPrivData->m_view = this;
|
||||
aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
|
||||
const BOX2I bbox = aItem->ViewBBox();
|
||||
aItem->m_viewPrivData->m_bbox = bbox;
|
||||
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
aItem->viewPrivData()->saveLayers( layers, layers_count );
|
||||
@@ -338,7 +342,7 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
l.items->Insert( aItem, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
|
||||
@@ -362,11 +366,12 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
aItem->m_viewPrivData->getLayers( layers, layers_count );
|
||||
const BOX2I* bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Remove( aItem, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
// Clear the GAL cache
|
||||
@@ -1327,12 +1332,17 @@ void VIEW::updateBbox( VIEW_ITEM* aItem )
|
||||
int layers[VIEW_MAX_LAYERS], layers_count;
|
||||
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
wxASSERT( aItem->m_viewPrivData ); //must have a viewPrivData
|
||||
|
||||
const BOX2I new_bbox = aItem->ViewBBox();
|
||||
const BOX2I* old_bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
aItem->m_viewPrivData->m_bbox = new_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Insert( aItem );
|
||||
l.items->Remove( aItem, old_bbox );
|
||||
l.items->Insert( aItem, new_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
}
|
||||
@@ -1348,11 +1358,12 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
|
||||
// Remove the item from previous layer set
|
||||
viewData->getLayers( layers, layers_count );
|
||||
const BOX2I* old_bbox = &aItem->m_viewPrivData->m_bbox;
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Remove( aItem );
|
||||
l.items->Remove( aItem, old_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
|
||||
if( IsCached( l.id ) )
|
||||
@@ -1368,6 +1379,9 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
}
|
||||
}
|
||||
|
||||
const BOX2I new_bbox = aItem->ViewBBox();
|
||||
aItem->m_viewPrivData->m_bbox = new_bbox;
|
||||
|
||||
// Add the item to new layer set
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
viewData->saveLayers( layers, layers_count );
|
||||
@@ -1375,7 +1389,7 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
|
||||
for( int i = 0; i < layers_count; i++ )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( aItem );
|
||||
l.items->Insert( aItem, new_bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
}
|
||||
@@ -1463,6 +1477,9 @@ void VIEW::UpdateItems()
|
||||
// and re-insert items from scratch
|
||||
for( VIEW_ITEM* item : allItems )
|
||||
{
|
||||
const BOX2I bbox = item->ViewBBox();
|
||||
item->m_viewPrivData->m_bbox = bbox;
|
||||
|
||||
item->ViewGetLayers( layers, layers_count );
|
||||
item->viewPrivData()->saveLayers( layers, layers_count );
|
||||
|
||||
@@ -1471,7 +1488,7 @@ void VIEW::UpdateItems()
|
||||
wxCHECK2_MSG( layers[i] >= 0 && static_cast<unsigned>( layers[i] ) < m_layers.size(),
|
||||
continue, wxS( "Invalid layer" ) );
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
l.items->Insert( item );
|
||||
l.items->Insert( item, bbox );
|
||||
MarkTargetDirty( l.target );
|
||||
}
|
||||
|
||||
|
||||
@@ -128,11 +128,14 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
m_query_ctrl->Bind( wxEVT_SEARCH_CANCEL, &LIB_TREE::onQueryText, this );
|
||||
m_query_ctrl->Bind( wxEVT_CHAR_HOOK, &LIB_TREE::onQueryCharHook, this );
|
||||
m_query_ctrl->Bind( wxEVT_MOTION, &LIB_TREE::onQueryMouseMoved, this );
|
||||
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
m_query_ctrl->Bind( wxEVT_LEAVE_WINDOW,
|
||||
[this] ( wxMouseEvent& aEvt )
|
||||
[this]( wxMouseEvent& aEvt )
|
||||
{
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
} );
|
||||
#endif
|
||||
|
||||
m_query_ctrl->Bind( wxEVT_MENU,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
@@ -153,6 +156,12 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
m_tree_ctrl = new WX_DATAVIEWCTRL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, dvFlags );
|
||||
m_adapter->AttachTo( m_tree_ctrl );
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// The GTK renderer seems to calculate row height incorrectly sometimes; but can be overridden
|
||||
int rowHeight = FromDIP( 8 ) + GetTextExtent( wxS( "pdI" ) ).y;
|
||||
m_tree_ctrl->SetRowHeight( rowHeight );
|
||||
#endif
|
||||
|
||||
sizer->Add( m_tree_ctrl, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
|
||||
|
||||
// Description panel
|
||||
@@ -618,6 +627,7 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
|
||||
|
||||
void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_query_ctrl->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -628,6 +638,7 @@ void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -529,7 +529,9 @@ protected:
|
||||
|
||||
void doSetFocus( wxWindow* aWindow )
|
||||
{
|
||||
#ifndef __WXGTK__ // Cannot focus in non-toplevel windows on GTK
|
||||
KIPLATFORM::UI::ForceFocus( aWindow );
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -355,7 +355,8 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( dynamic_cast<wxTextEntry*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxListView*>( aEvent.GetEventObject() ) )
|
||||
|| dynamic_cast<wxListView*>( aEvent.GetEventObject() )
|
||||
|| dynamic_cast<wxGrid*>( FindFocus() ) )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
@@ -373,7 +374,7 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
m_treebook->SetSelection( page - 1 );
|
||||
}
|
||||
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal focus
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal gridFocus
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_DOWN )
|
||||
{
|
||||
@@ -381,7 +382,7 @@ void PAGED_DIALOG::onCharHook( wxKeyEvent& aEvent )
|
||||
|
||||
m_treebook->SetSelection( std::min<int>( page + 1, m_treebook->GetPageCount() - 1 ) );
|
||||
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal focus
|
||||
m_treebook->GetTreeCtrl()->SetFocus(); // Don't allow preview canvas to steal gridFocus
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <eda_base_frame.h>
|
||||
#include <eda_item.h>
|
||||
#include <import_export.h>
|
||||
#include <pgm_base.h>
|
||||
#include <properties/pg_cell_renderer.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -65,10 +66,11 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
wxPGEditor_DatePickerCtrl = nullptr;
|
||||
}
|
||||
|
||||
if( !dynamic_cast<PG_CELL_RENDERER*>( wxPGGlobalVars->m_defaultRenderer ) )
|
||||
if( !Pgm().m_PropertyGridInitialized )
|
||||
{
|
||||
delete wxPGGlobalVars->m_defaultRenderer;
|
||||
wxPGGlobalVars->m_defaultRenderer = new PG_CELL_RENDERER();
|
||||
Pgm().m_PropertyGridInitialized = true;
|
||||
}
|
||||
|
||||
m_caption = new wxStaticText( this, wxID_ANY, _( "No objects selected" ) );
|
||||
@@ -133,7 +135,7 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
Bind( wxEVT_SIZE,
|
||||
[&]( wxSizeEvent& aEvent )
|
||||
{
|
||||
CallAfter( [&]()
|
||||
CallAfter( [this]()
|
||||
{
|
||||
RecalculateSplitterPos();
|
||||
} );
|
||||
@@ -144,6 +146,12 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
|
||||
void PROPERTIES_PANEL::OnLanguageChanged()
|
||||
{
|
||||
if( m_grid->IsEditorFocused() )
|
||||
m_grid->CommitChangesFromEditor();
|
||||
|
||||
m_grid->Clear();
|
||||
m_displayed.clear();
|
||||
|
||||
UpdateData();
|
||||
}
|
||||
|
||||
|
||||
@@ -80,10 +80,12 @@ void SEARCH_PANE_LISTVIEW::GetSelectRowsList( std::vector<long>& aSelectedList )
|
||||
|
||||
void SEARCH_PANE_LISTVIEW::OnItemActivated( wxListEvent& aEvent )
|
||||
{
|
||||
long item = aEvent.GetIndex();
|
||||
|
||||
CallAfter(
|
||||
[&]()
|
||||
[this, item]()
|
||||
{
|
||||
m_handler->ActivateItem( aEvent.GetIndex() );
|
||||
m_handler->ActivateItem( item );
|
||||
} );
|
||||
|
||||
m_selectionDirty = true;
|
||||
|
||||
@@ -541,7 +541,7 @@ WIDGET_HOTKEY_LIST::WIDGET_HOTKEY_LIST( wxWindow* aParent, HOTKEY_STORE& aHotkey
|
||||
dv->GetColumn( 2 )->SetMinWidth( aParent->GetTextExtent( longKey ).x + pad );
|
||||
dv->GetColumn( 3 )->SetMinWidth( aParent->GetTextExtent( command_header ).x * 5 + pad );
|
||||
|
||||
CallAfter( [&]()
|
||||
CallAfter( [this]()
|
||||
{
|
||||
GetDataView()->Update();
|
||||
} );
|
||||
|
||||
@@ -164,7 +164,7 @@ DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, wxWindow* aPa
|
||||
|
||||
// Register a call to update the toolbar sizes. It can't be done immediately because
|
||||
// it seems to require some sizes calculated that aren't yet (at least on GTK).
|
||||
CallAfter( [&]()
|
||||
CallAfter( [this]()
|
||||
{
|
||||
// Ensure the controls on the toolbars all are correctly sized
|
||||
UpdateToolbarControlSizes();
|
||||
|
||||
@@ -186,6 +186,28 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||
} );
|
||||
|
||||
|
||||
auto minX = []( const SCH_LINE* l )
|
||||
{
|
||||
return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
|
||||
};
|
||||
|
||||
auto maxX = []( const SCH_LINE* l )
|
||||
{
|
||||
return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
|
||||
};
|
||||
|
||||
auto minY = []( const SCH_LINE* l )
|
||||
{
|
||||
return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
|
||||
};
|
||||
|
||||
auto maxY = []( const SCH_LINE* l )
|
||||
{
|
||||
return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
|
||||
};
|
||||
|
||||
// Would be nice to put lines in a canonical form here by swapping
|
||||
// start <-> end as needed but I don't know what swapping breaks.
|
||||
while( changed )
|
||||
{
|
||||
changed = false;
|
||||
@@ -197,6 +219,13 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||
lines.push_back( static_cast<SCH_LINE*>( item ) );
|
||||
}
|
||||
|
||||
// Sort by minimum X position
|
||||
std::sort( lines.begin(), lines.end(),
|
||||
[&]( const SCH_LINE* a, const SCH_LINE* b )
|
||||
{
|
||||
return minX( a ) < minX( b );
|
||||
} );
|
||||
|
||||
for( auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
|
||||
{
|
||||
SCH_LINE* firstLine = *it1;
|
||||
@@ -210,11 +239,24 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||
continue;
|
||||
}
|
||||
|
||||
int firstRightXEdge = maxX( firstLine );
|
||||
auto it2 = it1;
|
||||
|
||||
for( ++it2; it2 != lines.end(); ++it2 )
|
||||
{
|
||||
SCH_LINE* secondLine = *it2;
|
||||
int secondLeftXEdge = minX( secondLine );
|
||||
|
||||
// impossible to overlap remaining lines
|
||||
if( secondLeftXEdge > firstRightXEdge )
|
||||
break;
|
||||
|
||||
// No Y axis overlap
|
||||
if( !( std::max( minY( firstLine ), minY( secondLine ) )
|
||||
<= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( secondLine->GetFlags() & STRUCT_DELETED )
|
||||
continue;
|
||||
|
||||
@@ -226,6 +226,7 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
|
||||
m_highlightedConn = wxEmptyString;
|
||||
|
||||
GetToolManager()->RunAction( EE_ACTIONS::updateNetHighlighting );
|
||||
RefreshNetNavigator();
|
||||
|
||||
SetStatusText( _( "Selected net:" ) + wxS( " " ) + UnescapeString( netName ) );
|
||||
return;
|
||||
|
||||
@@ -540,7 +540,8 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols( SCH_COMMIT* aCommit )
|
||||
|
||||
|
||||
int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols )
|
||||
const std::map<SCH_SYMBOL*,
|
||||
SYMBOL_CHANGE_INFO>& aSymbols )
|
||||
{
|
||||
wxCHECK( !aSymbols.empty(), 0 );
|
||||
|
||||
@@ -603,6 +604,9 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
|
||||
for( const auto& [ symbol, symbol_change_info ] : symbols )
|
||||
{
|
||||
// Remember initial link before changing for diags purpose
|
||||
wxString initialLibLinkName = UnescapeString( symbol->GetLibId().Format() );
|
||||
|
||||
if( symbol_change_info.m_LibId != symbol->GetLibId() )
|
||||
symbol->SetLibId( symbol_change_info.m_LibId );
|
||||
|
||||
@@ -650,10 +654,19 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
{
|
||||
if( i == REFERENCE_FIELD )
|
||||
{
|
||||
wxString prefix = UTIL::GetRefDesPrefix( libField->GetText() );
|
||||
|
||||
for( const SCH_SHEET_PATH& instance : symbol_change_info.m_Instances )
|
||||
{
|
||||
symbol->SetRef( &instance,
|
||||
UTIL::GetRefDesUnannotated( libField->GetText() ) );
|
||||
wxString ref = symbol->GetRef( &instance );
|
||||
int number = UTIL::GetRefDesNumber( ref );
|
||||
|
||||
if( number >= 0 )
|
||||
ref.Printf( wxS( "%s%d" ), prefix, number );
|
||||
else
|
||||
ref = UTIL::GetRefDesUnannotated( prefix );
|
||||
|
||||
symbol->SetRef( &instance, ref );
|
||||
}
|
||||
}
|
||||
else if( i == VALUE_FIELD )
|
||||
@@ -732,7 +745,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
|
||||
frame->GetCanvas()->GetView()->Update( symbol );
|
||||
|
||||
msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId );
|
||||
msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId, &initialLibLinkName );
|
||||
msg += wxS( ": OK" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
|
||||
matchesProcessed +=1;
|
||||
@@ -742,12 +755,21 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
}
|
||||
|
||||
|
||||
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId )
|
||||
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol,
|
||||
const LIB_ID& aNewId,
|
||||
const wxString* aOldLibLinkName )
|
||||
{
|
||||
wxString msg;
|
||||
wxString references;
|
||||
LIB_ID oldId = aSymbol.GetLibId();
|
||||
|
||||
wxString oldLibLinkName; // For report
|
||||
|
||||
if( aOldLibLinkName )
|
||||
oldLibLinkName = *aOldLibLinkName;
|
||||
else
|
||||
oldLibLinkName = UnescapeString( oldId.Format() );
|
||||
|
||||
SCH_EDIT_FRAME* parent = dynamic_cast< SCH_EDIT_FRAME* >( GetParent() );
|
||||
|
||||
wxCHECK( parent, msg );
|
||||
@@ -772,31 +794,31 @@ wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const
|
||||
{
|
||||
msg.Printf( _( "Update symbol %s from '%s' to '%s'" ),
|
||||
references,
|
||||
UnescapeString( oldId.Format() ),
|
||||
oldLibLinkName,
|
||||
UnescapeString( aNewId.Format() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Update symbols %s from '%s' to '%s'" ),
|
||||
references,
|
||||
UnescapeString( oldId.Format() ),
|
||||
oldLibLinkName,
|
||||
UnescapeString( aNewId.Format() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
else // mode is MODE::CHANGE
|
||||
{
|
||||
if( aSymbol.GetInstances().size() == 1 )
|
||||
{
|
||||
msg.Printf( _( "Change symbol %s from '%s' to '%s'" ),
|
||||
references,
|
||||
UnescapeString( oldId.Format() ),
|
||||
oldLibLinkName,
|
||||
UnescapeString( aNewId.Format() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Change symbols %s from '%s' to '%s'" ),
|
||||
references,
|
||||
UnescapeString( oldId.Format() ),
|
||||
oldLibLinkName,
|
||||
UnescapeString( aNewId.Format() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,8 @@ private:
|
||||
int processMatchingSymbols( SCH_COMMIT* aCommit );
|
||||
int processSymbols( SCH_COMMIT* aCommit,
|
||||
const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
|
||||
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
|
||||
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId,
|
||||
const wxString* aOldLibLinkName = nullptr );
|
||||
|
||||
SCH_SYMBOL* m_symbol;
|
||||
MODE m_mode;
|
||||
|
||||
@@ -502,11 +502,29 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
const wxString& fieldText = field.GetText();
|
||||
|
||||
if( fieldName.IsEmpty() && fieldText.IsEmpty() )
|
||||
{
|
||||
// delete empty, unnamed fields
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
}
|
||||
else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
{
|
||||
// delete empty Netclass fields if there are other Netclass fields present
|
||||
int netclassFieldCount = 0;
|
||||
|
||||
for( int jj = 0; jj < m_fields->GetNumberRows(); ++jj )
|
||||
{
|
||||
if( m_fields->at( jj ).GetCanonicalName() == wxT( "Netclass" ) )
|
||||
netclassFieldCount++;
|
||||
}
|
||||
|
||||
if( netclassFieldCount > 1 )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
}
|
||||
else if( fieldName.IsEmpty() )
|
||||
{
|
||||
// give non-empty, unnamed fields a name
|
||||
field.SetName( _( "untitled" ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_currentLabel->SetFields( *m_fields );
|
||||
|
||||
@@ -51,7 +51,10 @@ static void setStringSelection( wxChoice* aCtrl, const wxString& aStr )
|
||||
|
||||
static wxString getStringSelection( const wxChoice* aCtrl )
|
||||
{
|
||||
return aCtrl->GetString( aCtrl->GetSelection() );
|
||||
if( aCtrl->GetSelection() >= 0 )
|
||||
return aCtrl->GetString( aCtrl->GetSelection() );
|
||||
else
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
@@ -915,7 +918,15 @@ void DIALOG_SIM_COMMAND::onDCSource2Selected( wxCommandEvent& event )
|
||||
void DIALOG_SIM_COMMAND::onDCEnableSecondSource( wxCommandEvent& event )
|
||||
{
|
||||
bool is2ndSrcEnabled = m_dcEnable2->IsChecked();
|
||||
wxChar type = getStringSelection( m_dcSourceType2 ).Upper().GetChar( 0 );
|
||||
wxChar type = '?';
|
||||
|
||||
if( is2ndSrcEnabled )
|
||||
{
|
||||
wxString fullType = getStringSelection( m_dcSourceType2 ).Upper();
|
||||
|
||||
if( fullType.Length() > 0 )
|
||||
type = fullType.GetChar( 0 );
|
||||
}
|
||||
|
||||
m_dcSourceType2->Enable( is2ndSrcEnabled );
|
||||
m_dcSource2->Enable( is2ndSrcEnabled && type != 'T' );
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
|
||||
using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
|
||||
|
||||
#define FORCE_UPDATE_PINS true
|
||||
|
||||
|
||||
bool equivalent( SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b )
|
||||
{
|
||||
@@ -128,6 +130,7 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, EDA_BA
|
||||
grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
|
||||
#endif
|
||||
|
||||
m_pinAssignmentsGrid->ClearRows();
|
||||
m_pinAssignmentsGrid->PushEventHandler( new GRID_TRICKS( m_pinAssignmentsGrid ) );
|
||||
|
||||
m_subcktLabel->SetFont( KIUI::GetInfoFont( m_subcktLabel ) );
|
||||
@@ -349,6 +352,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
|
||||
if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
SIM_MODEL& model = curModel();
|
||||
std::string path;
|
||||
std::string name;
|
||||
|
||||
@@ -362,7 +366,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
|
||||
|
||||
if( !m_modelNameChoice->IsEmpty() )
|
||||
name = m_modelNameChoice->GetStringSelection().ToStdString();
|
||||
else if( dynamic_cast<SIM_MODEL_SPICE_FALLBACK*>( &curModel() ) )
|
||||
else if( dynamic_cast<SIM_MODEL_SPICE_FALLBACK*>( &model ) )
|
||||
name = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD, false );
|
||||
}
|
||||
|
||||
@@ -392,16 +396,27 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataFromWindow()
|
||||
}
|
||||
}
|
||||
|
||||
if( curModel().GetType() == SIM_MODEL::TYPE::RAWSPICE )
|
||||
if( model.GetType() == SIM_MODEL::TYPE::RAWSPICE )
|
||||
{
|
||||
if( m_modelNotebook->GetSelection() == 0 )
|
||||
updateModelCodeTab( &curModel() );
|
||||
updateModelCodeTab( &model );
|
||||
|
||||
wxString code = m_codePreview->GetText().Trim( true ).Trim( false );
|
||||
curModel().SetParamValue( "model", std::string( code.ToUTF8() ) );
|
||||
model.SetParamValue( "model", std::string( code.ToUTF8() ) );
|
||||
}
|
||||
|
||||
curModel().SetIsStoredInValue( m_saveInValueCheckbox->GetValue() );
|
||||
model.SetIsStoredInValue( m_saveInValueCheckbox->GetValue() );
|
||||
|
||||
for( int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
|
||||
{
|
||||
wxString modelPinName = m_pinAssignmentsGrid->GetCellValue( row, PIN_COLUMN::MODEL );
|
||||
wxString symbolPinName = m_sortedPartPins.at( row )->GetShownNumber();
|
||||
|
||||
model.SetPinSymbolPinNumber( getModelPinIndex( modelPinName ),
|
||||
std::string( symbolPinName.ToUTF8() ) );
|
||||
}
|
||||
|
||||
removeOrphanedPinAssignments( &model );
|
||||
|
||||
curModel().WriteFields( m_fields );
|
||||
|
||||
@@ -444,7 +459,7 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::updateWidgets()
|
||||
updateBuiltinModelWidgets( model );
|
||||
updateModelParamsTab( model );
|
||||
updateModelCodeTab( model );
|
||||
updatePinAssignments( model );
|
||||
updatePinAssignments( model, false );
|
||||
|
||||
std::string ref = SIM_MODEL::GetFieldValue( &m_fields, SIM_REFERENCE_FIELD );
|
||||
|
||||
@@ -696,45 +711,51 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::updateModelCodeTab( SIM_MODEL* aModel
|
||||
|
||||
|
||||
template <typename T_symbol, typename T_field>
|
||||
void DIALOG_SIM_MODEL<T_symbol, T_field>::updatePinAssignments( SIM_MODEL* aModel )
|
||||
void DIALOG_SIM_MODEL<T_symbol, T_field>::updatePinAssignments( SIM_MODEL* aModel,
|
||||
bool aForceUpdatePins )
|
||||
{
|
||||
removeOrphanedPinAssignments( aModel );
|
||||
|
||||
// Reset the grid.
|
||||
|
||||
m_pinAssignmentsGrid->ClearRows();
|
||||
m_pinAssignmentsGrid->AppendRows( static_cast<int>( m_sortedPartPins.size() ) );
|
||||
|
||||
for( int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
|
||||
m_pinAssignmentsGrid->SetCellValue( row, PIN_COLUMN::MODEL, _( "Not Connected" ) );
|
||||
|
||||
// Now set up the grid values in the Model column.
|
||||
for( int modelPinIndex = 0; modelPinIndex < aModel->GetPinCount(); ++modelPinIndex )
|
||||
if( m_pinAssignmentsGrid->GetNumberRows() == 0 )
|
||||
{
|
||||
wxString symbolPinNumber = aModel->GetPin( modelPinIndex ).symbolPinNumber;
|
||||
m_pinAssignmentsGrid->AppendRows( static_cast<int>( m_sortedPartPins.size() ) );
|
||||
|
||||
if( symbolPinNumber == "" )
|
||||
continue;
|
||||
for( int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
|
||||
{
|
||||
wxString symbolPinString = getSymbolPinString( ii );
|
||||
|
||||
int symbolPinRow = findSymbolPinRow( symbolPinNumber );
|
||||
m_pinAssignmentsGrid->SetReadOnly( ii, PIN_COLUMN::SYMBOL );
|
||||
m_pinAssignmentsGrid->SetCellValue( ii, PIN_COLUMN::SYMBOL, symbolPinString );
|
||||
}
|
||||
|
||||
if( symbolPinRow == -1 )
|
||||
continue;
|
||||
|
||||
wxString modelPinString = getModelPinString( aModel, modelPinIndex );
|
||||
m_pinAssignmentsGrid->SetCellValue( symbolPinRow, PIN_COLUMN::MODEL, modelPinString );
|
||||
aForceUpdatePins = true;
|
||||
}
|
||||
|
||||
if( aForceUpdatePins )
|
||||
{
|
||||
// Reset the grid.
|
||||
for( int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
|
||||
m_pinAssignmentsGrid->SetCellValue( row, PIN_COLUMN::MODEL, _( "Not Connected" ) );
|
||||
|
||||
// Now set up the grid values in the Model column.
|
||||
for( int modelPinIndex = 0; modelPinIndex < aModel->GetPinCount(); ++modelPinIndex )
|
||||
{
|
||||
wxString symbolPinNumber = aModel->GetPin( modelPinIndex ).symbolPinNumber;
|
||||
|
||||
if( symbolPinNumber == "" )
|
||||
continue;
|
||||
|
||||
int symbolPinRow = findSymbolPinRow( symbolPinNumber );
|
||||
|
||||
if( symbolPinRow == -1 )
|
||||
continue;
|
||||
|
||||
wxString modelPinString = getModelPinString( aModel, modelPinIndex );
|
||||
m_pinAssignmentsGrid->SetCellValue( symbolPinRow, PIN_COLUMN::MODEL, modelPinString );
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the Symbol column grid values and Model column cell editors with dropdown options.
|
||||
for( int ii = 0; ii < m_pinAssignmentsGrid->GetNumberRows(); ++ii )
|
||||
{
|
||||
wxString symbolPinString = getSymbolPinString( ii );
|
||||
|
||||
m_pinAssignmentsGrid->SetReadOnly( ii, PIN_COLUMN::SYMBOL );
|
||||
m_pinAssignmentsGrid->SetCellValue( ii, PIN_COLUMN::SYMBOL, symbolPinString );
|
||||
|
||||
wxString curModelPinString = m_pinAssignmentsGrid->GetCellValue( ii, PIN_COLUMN::MODEL );
|
||||
|
||||
// Set up the Model column cell editors with dropdown options.
|
||||
std::vector<BITMAPS> modelPinIcons;
|
||||
wxArrayString modelPinChoices;
|
||||
|
||||
@@ -1419,7 +1440,7 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onPinAssignmentsGridCellChange( wxGrid
|
||||
std::string( m_sortedPartPins.at( symbolPinIndex )->GetShownNumber().ToUTF8() ) );
|
||||
}
|
||||
|
||||
updatePinAssignments( &curModel() );
|
||||
updatePinAssignments( &curModel(), FORCE_UPDATE_PINS );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
void updateBuiltinModelWidgets( SIM_MODEL* aModel );
|
||||
void updateModelParamsTab( SIM_MODEL* aModel );
|
||||
void updateModelCodeTab( SIM_MODEL* aModel );
|
||||
void updatePinAssignments( SIM_MODEL* aModel );
|
||||
void updatePinAssignments( SIM_MODEL* aModel, bool aForceUpdatePins );
|
||||
|
||||
void removeOrphanedPinAssignments( SIM_MODEL* aModel );
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
{
|
||||
KIGFX::VIEW* view = m_preview->GetView();
|
||||
|
||||
std::vector<DANGLING_END_ITEM> endPoints;
|
||||
std::vector<DANGLING_END_ITEM> endPointsByType;
|
||||
|
||||
m_page = new PAGE_INFO( PAGE_INFO::Custom );
|
||||
m_titleBlock = new TITLE_BLOCK;
|
||||
@@ -258,7 +258,6 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
view->Add( m_drawingSheet );
|
||||
|
||||
// TODO: It would be nice to parse a schematic file here.
|
||||
// This is created from the color_settings.sch file in demos folder
|
||||
|
||||
auto addItem = [&]( EDA_ITEM* aItem )
|
||||
{
|
||||
@@ -275,8 +274,8 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
{ LAYER_WIRE, { { 3075, 1600 }, { 3075, 2000 } } },
|
||||
{ LAYER_WIRE, { { 3075, 1600 }, { 3250, 1600 } } },
|
||||
{ LAYER_WIRE, { { 3075, 2000 }, { 2150, 2000 } } },
|
||||
{ LAYER_BUS, { { 1750, 1400 }, { 1850, 1400 } } },
|
||||
{ LAYER_BUS, { { 1850, 2500 }, { 1850, 1400 } } },
|
||||
{ LAYER_BUS, { { 1750, 1300 }, { 1850, 1300 } } },
|
||||
{ LAYER_BUS, { { 1850, 2500 }, { 1850, 1300 } } },
|
||||
{ LAYER_NOTES, { { 2350, 2125 }, { 2350, 2300 } } },
|
||||
{ LAYER_NOTES, { { 2350, 2125 }, { 2950, 2125 } } },
|
||||
{ LAYER_NOTES, { { 2950, 2125 }, { 2950, 2300 } } },
|
||||
@@ -311,7 +310,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
#define MILS_POINT( x, y ) VECTOR2I( schIUScale.MilsToIU( x ), schIUScale.MilsToIU( y ) )
|
||||
|
||||
SCH_NO_CONNECT* nc = new SCH_NO_CONNECT;
|
||||
nc->SetPosition( MILS_POINT( 2525, 1300 ) );
|
||||
nc->SetPosition( MILS_POINT( 2350, 2600 ) );
|
||||
addItem( nc );
|
||||
|
||||
SCH_BUS_WIRE_ENTRY* e1 = new SCH_BUS_WIRE_ENTRY;
|
||||
@@ -322,7 +321,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
e2->SetPosition( MILS_POINT( 1850, 2500 ) );
|
||||
addItem( e2 );
|
||||
|
||||
SCH_TEXT* t1 = new SCH_TEXT( MILS_POINT( 2850, 2250 ), wxT( "PLAIN TEXT" ) );
|
||||
SCH_TEXT* t1 = new SCH_TEXT( MILS_POINT( 2650, 2240 ), wxT( "PLAIN TEXT" ) );
|
||||
addItem( t1 );
|
||||
|
||||
SCH_LABEL* t2 = new SCH_LABEL( MILS_POINT( 1975, 1500 ), wxT( "LABEL_{0}" ) );
|
||||
@@ -335,7 +334,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
t3->SetIsDangling( false );
|
||||
addItem( t3 );
|
||||
|
||||
SCH_GLOBALLABEL* t4 = new SCH_GLOBALLABEL( MILS_POINT( 1750, 1400 ), wxT( "GLOBAL[0..3]" ) );
|
||||
SCH_GLOBALLABEL* t4 = new SCH_GLOBALLABEL( MILS_POINT( 1750, 1300 ), wxT( "GLOBAL[0..3]" ) );
|
||||
t4->SetSpinStyle( SPIN_STYLE::SPIN::LEFT );
|
||||
t4->SetIsDangling( false );
|
||||
addItem( t4 );
|
||||
@@ -397,8 +396,10 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
|
||||
pin->SetNumber( wxT( "1" ) );
|
||||
pin->SetName( wxT( "-" ) );
|
||||
pin->SetNumberTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
pin->SetNameTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
|
||||
endPoints.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
endPointsByType.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
symbol->AddDrawItem( pin );
|
||||
|
||||
pin = new LIB_PIN( symbol );
|
||||
@@ -409,8 +410,10 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT );
|
||||
pin->SetNumber( wxT( "2" ) );
|
||||
pin->SetName( wxT( "+" ) );
|
||||
pin->SetNumberTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
pin->SetNameTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
|
||||
endPoints.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
endPointsByType.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
symbol->AddDrawItem( pin );
|
||||
|
||||
pin = new LIB_PIN( symbol );
|
||||
@@ -421,8 +424,10 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT );
|
||||
pin->SetNumber( wxT( "3" ) );
|
||||
pin->SetName( wxT( "OUT" ) );
|
||||
pin->SetNumberTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
pin->SetNameTextSize( schIUScale.MilsToIU( 50 ) );
|
||||
|
||||
endPoints.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
endPointsByType.emplace_back( PIN_END, pin, mapLibItemPosition( pin->GetPosition() ) );
|
||||
symbol->AddDrawItem( pin );
|
||||
|
||||
addItem( symbol );
|
||||
@@ -447,16 +452,19 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
|
||||
if( sch_item && sch_item->IsConnectable() )
|
||||
{
|
||||
sch_item->AutoplaceFields( nullptr, false );
|
||||
sch_item->GetEndPoints( endPoints );
|
||||
sch_item->GetEndPoints( endPointsByType );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
|
||||
DANGLING_END_ITEM_HELPER::sort_dangling_end_items( endPointsByType, endPointsByPos );
|
||||
|
||||
for( EDA_ITEM* item : m_previewItems )
|
||||
{
|
||||
SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
|
||||
|
||||
if( sch_item && sch_item->IsConnectable() )
|
||||
sch_item->UpdateDanglingState( endPoints, nullptr );
|
||||
sch_item->UpdateDanglingState( endPointsByType, endPointsByPos, nullptr );
|
||||
}
|
||||
|
||||
zoomFitPreview();
|
||||
|
||||
@@ -912,7 +912,7 @@ void PANEL_SYM_LIB_TABLE::onConvertLegacyLibraries( wxCommandEvent& event )
|
||||
wxString options = m_cur_grid->GetCellValue( row, COL_OPTIONS );
|
||||
std::unique_ptr<STRING_UTF8_MAP> props( LIB_TABLE::ParseOptions( options.ToStdString() ) );
|
||||
|
||||
if( convertLibrary( props.get(), legacyLib.GetFullPath(), newLib.GetFullPath() ) )
|
||||
if( SCH_IO_MGR::ConvertLibrary( props.get(), legacyLib.GetFullPath(), newLib.GetFullPath() ) )
|
||||
{
|
||||
relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(),
|
||||
m_project );
|
||||
@@ -938,66 +938,6 @@ void PANEL_SYM_LIB_TABLE::onConvertLegacyLibraries( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
|
||||
bool PANEL_SYM_LIB_TABLE::convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath,
|
||||
const wxString& aNewFilepath )
|
||||
{
|
||||
SCH_IO_MGR::SCH_FILE_T oldFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath );
|
||||
|
||||
if( oldFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
|
||||
return false;
|
||||
|
||||
IO_RELEASER<SCH_IO> oldFilePI( SCH_IO_MGR::FindPlugin( oldFileType ) );
|
||||
IO_RELEASER<SCH_IO> kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
|
||||
std::vector<LIB_SYMBOL*> symbols;
|
||||
std::vector<LIB_SYMBOL*> newSymbols;
|
||||
std::map<LIB_SYMBOL*, LIB_SYMBOL*> symbolMap;
|
||||
|
||||
try
|
||||
{
|
||||
oldFilePI->EnumerateSymbolLib( symbols, aOldFilePath, aOldFileProps );
|
||||
|
||||
// Copy non-aliases first so we can build a map from symbols to newSymbols
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
if( symbol->IsAlias() )
|
||||
continue;
|
||||
|
||||
symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
|
||||
|
||||
newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
|
||||
symbolMap[symbol] = newSymbols.back();
|
||||
}
|
||||
|
||||
// Now do the aliases using the map to hook them up to their newSymbol parents
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
if( !symbol->IsAlias() )
|
||||
continue;
|
||||
|
||||
symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
|
||||
|
||||
newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
|
||||
newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] );
|
||||
}
|
||||
|
||||
// Create a blank library
|
||||
kicadPI->SaveLibrary( aNewFilepath );
|
||||
|
||||
// Finally write out newSymbols
|
||||
for( LIB_SYMBOL* symbol : newSymbols )
|
||||
{
|
||||
kicadPI->SaveSymbol( aNewFilepath, symbol );
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
||||
{
|
||||
if( !m_cur_grid->CommitPendingChanges() )
|
||||
|
||||
@@ -65,9 +65,6 @@ private:
|
||||
/// by examining all the full_uri columns.
|
||||
void populateEnvironReadOnlyTable();
|
||||
|
||||
bool convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath,
|
||||
const wxString& aNewFilePath );
|
||||
|
||||
SYMBOL_LIB_TABLE_GRID* global_model() const;
|
||||
|
||||
SYMBOL_LIB_TABLE_GRID* project_model() const;
|
||||
|
||||
@@ -879,17 +879,7 @@ int EESCHEMA_JOBS_HANDLER::JobSymUpgrade( JOB* aJob )
|
||||
wxFileName fn( upgradeJob->m_libraryPath );
|
||||
fn.MakeAbsolute();
|
||||
|
||||
SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
|
||||
|
||||
try
|
||||
{
|
||||
schLibrary.Load();
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
|
||||
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
}
|
||||
SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
|
||||
|
||||
if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
|
||||
{
|
||||
@@ -901,33 +891,65 @@ int EESCHEMA_JOBS_HANDLER::JobSymUpgrade( JOB* aJob )
|
||||
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldSave = upgradeJob->m_force
|
||||
|| schLibrary.GetFileFormatVersionAtLoad() < SEXPR_SYMBOL_LIB_FILE_VERSION;
|
||||
|
||||
if( shouldSave )
|
||||
else if( fileType != SCH_IO_MGR::SCH_KICAD )
|
||||
{
|
||||
m_reporter->Report( _( "Saving symbol library in updated format\n" ), RPT_SEVERITY_ACTION );
|
||||
m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
|
||||
RPT_SEVERITY_ERROR );
|
||||
|
||||
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
|
||||
}
|
||||
|
||||
if( fileType == SCH_IO_MGR::SCH_KICAD )
|
||||
{
|
||||
SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() );
|
||||
|
||||
try
|
||||
{
|
||||
if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
|
||||
{
|
||||
schLibrary.SetFileName( upgradeJob->m_outputLibraryPath );
|
||||
}
|
||||
|
||||
schLibrary.SetModified();
|
||||
schLibrary.Save();
|
||||
schLibrary.Load();
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
|
||||
m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
|
||||
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
bool shouldSave =
|
||||
upgradeJob->m_force
|
||||
|| schLibrary.GetFileFormatVersionAtLoad() < SEXPR_SYMBOL_LIB_FILE_VERSION;
|
||||
|
||||
if( shouldSave )
|
||||
{
|
||||
m_reporter->Report( _( "Saving symbol library in updated format\n" ),
|
||||
RPT_SEVERITY_ACTION );
|
||||
|
||||
try
|
||||
{
|
||||
if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
|
||||
{
|
||||
schLibrary.SetFileName( upgradeJob->m_outputLibraryPath );
|
||||
}
|
||||
|
||||
schLibrary.SetModified();
|
||||
schLibrary.Save();
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
|
||||
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_INFO );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_INFO );
|
||||
if( !SCH_IO_MGR::ConvertLibrary( nullptr, fn.GetAbsolutePath(), upgradeJob->m_outputLibraryPath ) )
|
||||
{
|
||||
m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
|
||||
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return CLI::EXIT_CODES::OK;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -84,6 +84,28 @@ static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
|
||||
}
|
||||
|
||||
|
||||
static wxString netList( LIB_SYMBOL* aSymbol )
|
||||
{
|
||||
/*
|
||||
* Symbol netlist format:
|
||||
* pinCount
|
||||
* fpFilters
|
||||
*/
|
||||
wxString netlist;
|
||||
|
||||
netlist << wxString::Format( wxS( "%d\r" ), aSymbol->GetPinCount() );
|
||||
|
||||
wxArrayString fpFilters = aSymbol->GetFPFilters();
|
||||
|
||||
if( !fpFilters.IsEmpty() )
|
||||
netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
|
||||
|
||||
netlist << wxS( "\r" );
|
||||
|
||||
return netlist;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame,
|
||||
WX_GRID* aGrid, LIB_SYMBOL* aSymbol ) :
|
||||
@@ -93,6 +115,7 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
|
||||
m_parentType( SCH_SYMBOL_T ),
|
||||
m_mandatoryFieldCount( MANDATORY_FIELDS ),
|
||||
m_part( aSymbol ),
|
||||
m_symbolNetlist( netList( aSymbol ) ),
|
||||
m_fieldNameValidator( FIELD_NAME ),
|
||||
m_referenceValidator( REFERENCE_FIELD ),
|
||||
m_valueValidator( VALUE_FIELD ),
|
||||
@@ -432,8 +455,9 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
|
||||
else if( m_parentType == SCH_SYMBOL_T && aRow == FOOTPRINT_FIELD )
|
||||
{
|
||||
// Power symbols have do not appear in the board, so don't allow
|
||||
// a footprint
|
||||
if( m_part->IsPower() )
|
||||
// a footprint (m_part can be nullptr when loading a old schematic
|
||||
// (for instance Kicad 4) with libraries missing)
|
||||
if( m_part && m_part->IsPower() )
|
||||
{
|
||||
m_readOnlyAttr->IncRef();
|
||||
return m_readOnlyAttr;
|
||||
|
||||
@@ -176,7 +176,8 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddPolygon( const std::vector<VECTOR2D>& aVer
|
||||
|
||||
polygon->SetStroke( MapStrokeParams( aStroke ) );
|
||||
|
||||
addItem( std::move( polygon ) );
|
||||
if( polygon->IsPolyShapeValid() )
|
||||
addItem( std::move( polygon ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ int LIB_FIELD::compare( const LIB_ITEM& aOther, int aCompareFlags ) const
|
||||
|
||||
bool ignoreFieldText = false;
|
||||
|
||||
if( m_id == REFERENCE_FIELD && ( aCompareFlags & COMPARE_FLAGS::EQUALITY ) )
|
||||
if( m_id == REFERENCE_FIELD && !( aCompareFlags & COMPARE_FLAGS::EQUALITY ) )
|
||||
ignoreFieldText = true;
|
||||
|
||||
if( m_id == VALUE_FIELD && ( aCompareFlags & COMPARE_FLAGS::ERC ) )
|
||||
|
||||
@@ -537,3 +537,33 @@ void LIB_TEXTBOX::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
aLayers[1] = IsPrivate() ? LAYER_NOTES_BACKGROUND : LAYER_DEVICE_BACKGROUND;
|
||||
aLayers[2] = LAYER_SELECTION_SHADOWS;
|
||||
}
|
||||
|
||||
|
||||
static struct LIB_TEXTBOX_DESC
|
||||
{
|
||||
LIB_TEXTBOX_DESC()
|
||||
{
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( LIB_TEXTBOX );
|
||||
|
||||
propMgr.AddTypeCast( new TYPE_CAST<LIB_TEXTBOX, LIB_SHAPE> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<LIB_TEXTBOX, EDA_SHAPE> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<LIB_TEXTBOX, EDA_TEXT> );
|
||||
propMgr.InheritsAfter( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( LIB_SHAPE ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Visible" ) );
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<LIB_TEXTBOX, int>( _HKI( "Text Size" ),
|
||||
&LIB_TEXTBOX::SetLibTextSize, &LIB_TEXTBOX::GetLibTextSize, PROPERTY_DISPLAY::PT_SIZE ),
|
||||
_HKI( "Text Properties" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( LIB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
|
||||
}
|
||||
} _LIB_TEXTBOX_DESC;
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
|
||||
int GetTextMargin() const;
|
||||
|
||||
int GetLibTextSize() const { return GetTextWidth(); }
|
||||
void SetLibTextSize( int aSize ) { SetTextSize( VECTOR2I( aSize, aSize ) ); }
|
||||
|
||||
VECTOR2I GetDrawPos() const override;
|
||||
|
||||
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override;
|
||||
|
||||
@@ -89,17 +89,6 @@ const std::map<GRAPHIC_PINSHAPE, struct pinShapeStruct> pinShapes = {
|
||||
// clang-format on
|
||||
|
||||
|
||||
// bitmaps to show pins orientations in dialog editor
|
||||
// must have same order than pin_orientation_names
|
||||
static const BITMAPS iconsPinsOrientations[] =
|
||||
{
|
||||
BITMAPS::pinorient_right,
|
||||
BITMAPS::pinorient_left,
|
||||
BITMAPS::pinorient_up,
|
||||
BITMAPS::pinorient_down,
|
||||
};
|
||||
|
||||
|
||||
// clang-format off
|
||||
std::map<PIN_ORIENTATION, struct pinShapeStruct> pinOrientations = {
|
||||
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
*/
|
||||
|
||||
#include "sch_printout.h"
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/ee_selection_tool.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <math/vector2wx.h>
|
||||
#include <pgm_base.h>
|
||||
@@ -257,6 +259,7 @@ void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
|
||||
COLOR_SETTINGS* theme = mgr.GetColorSettings( cfg->m_Printing.color_theme );
|
||||
EE_SELECTION_TOOL* selTool = m_parent->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
|
||||
|
||||
// Target paper size
|
||||
wxRect pageSizePx = GetLogicalPageRect();
|
||||
@@ -345,6 +348,18 @@ void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
|
||||
view->SetLayerVisible( LAYER_DRAWINGSHEET, printDrawingSheet );
|
||||
|
||||
// Don't draw the selection if it's not from the current screen
|
||||
for( EDA_ITEM* item : selTool->GetSelection() )
|
||||
{
|
||||
if( SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item ) )
|
||||
{
|
||||
if( !m_parent->GetScreen()->CheckIfOnDrawList( schItem ) )
|
||||
view->SetLayerVisible( LAYER_SELECT_OVERLAY, false );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When is the actual paper size does not match the schematic page size,
|
||||
// we need to adjust the print scale to fit the selected paper size (pageSizeIU)
|
||||
double scaleX = (double) pageSizeIU.x / drawingAreaBBox.GetWidth();
|
||||
|
||||
+13
-10
@@ -312,8 +312,9 @@ void SCH_BUS_ENTRY_BASE::Rotate( const VECTOR2I& aCenter )
|
||||
}
|
||||
|
||||
|
||||
bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
{
|
||||
bool previousStateStart = m_isDanglingStart;
|
||||
bool previousStateEnd = m_isDanglingEnd;
|
||||
@@ -324,9 +325,9 @@ bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aI
|
||||
bool has_wire[2] = { false };
|
||||
bool has_bus[2] = { false };
|
||||
|
||||
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
||||
for( unsigned ii = 0; ii < aItemListByType.size(); ii++ )
|
||||
{
|
||||
DANGLING_END_ITEM& item = aItemList[ii];
|
||||
DANGLING_END_ITEM& item = aItemListByType[ii];
|
||||
|
||||
if( item.GetItem() == this )
|
||||
continue;
|
||||
@@ -344,7 +345,7 @@ bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aI
|
||||
case BUS_END:
|
||||
{
|
||||
// The bus has created 2 DANGLING_END_ITEMs, one per end.
|
||||
DANGLING_END_ITEM& nextItem = aItemList[++ii];
|
||||
DANGLING_END_ITEM& nextItem = aItemListByType[++ii];
|
||||
|
||||
if( IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), m_pos ) )
|
||||
has_bus[0] = true;
|
||||
@@ -371,17 +372,19 @@ bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aI
|
||||
}
|
||||
|
||||
|
||||
bool SCH_BUS_BUS_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
bool SCH_BUS_BUS_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
{
|
||||
bool previousStateStart = m_isDanglingStart;
|
||||
bool previousStateEnd = m_isDanglingEnd;
|
||||
|
||||
m_isDanglingStart = m_isDanglingEnd = true;
|
||||
|
||||
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
||||
// TODO: filter using get_lower as we only use one item type
|
||||
for( unsigned ii = 0; ii < aItemListByType.size(); ii++ )
|
||||
{
|
||||
DANGLING_END_ITEM& item = aItemList[ii];
|
||||
DANGLING_END_ITEM& item = aItemListByType[ii];
|
||||
|
||||
if( item.GetItem() == this )
|
||||
continue;
|
||||
@@ -391,7 +394,7 @@ bool SCH_BUS_BUS_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aIt
|
||||
case BUS_END:
|
||||
{
|
||||
// The bus has created 2 DANGLING_END_ITEMs, one per end.
|
||||
DANGLING_END_ITEM& nextItem = aItemList[++ii];
|
||||
DANGLING_END_ITEM& nextItem = aItemListByType[++ii];
|
||||
|
||||
if( IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), m_pos ) )
|
||||
m_isDanglingStart = false;
|
||||
|
||||
@@ -195,8 +195,9 @@ public:
|
||||
|
||||
BITMAPS GetMenuImage() const override;
|
||||
|
||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath = nullptr ) override;
|
||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Pointer to the bus item (usually a bus wire) connected to this bus-wire
|
||||
@@ -240,8 +241,9 @@ public:
|
||||
|
||||
BITMAPS GetMenuImage() const override;
|
||||
|
||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath = nullptr ) override;
|
||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Pointer to the bus items (usually bus wires) connected to this bus-bus
|
||||
|
||||
@@ -1400,6 +1400,10 @@ static struct SCH_FIELD_DESC
|
||||
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
|
||||
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_FIELD, int>( _HKI( "Text Size" ),
|
||||
&SCH_FIELD::SetSchTextSize, &SCH_FIELD::GetSchTextSize, PROPERTY_DISPLAY::PT_SIZE ),
|
||||
_HKI( "Text Properties" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
|
||||
|
||||
auto isNotNamedVariable =
|
||||
|
||||
@@ -152,6 +152,9 @@ public:
|
||||
return name.Trim().empty() && value.Trim().empty();
|
||||
}
|
||||
|
||||
int GetSchTextSize() const { return GetTextWidth(); }
|
||||
void SetSchTextSize( int aSize ) { SetTextSize( VECTOR2I( aSize, aSize ) ); }
|
||||
|
||||
COLOR4D GetFieldColor() const;
|
||||
|
||||
void SetLastResolvedState( const SCH_ITEM* aItem ) override
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#include <schematic.h>
|
||||
#include <project_sch.h>
|
||||
#include <project/project_file.h>
|
||||
#include <project/net_settings.h>
|
||||
|
||||
#include <lib_shape.h>
|
||||
#include <lib_id.h>
|
||||
@@ -57,13 +59,11 @@
|
||||
#include <geometry/ellipse.h>
|
||||
#include <string_utils.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <trigo.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/zstream.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <trigo.h>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
// Harness port object itself does not contain color information about itself
|
||||
@@ -134,46 +134,28 @@ static void SetSchShapeFillAndColor( const ASCH_FILL_INTERFACE& elem, SCH_SHAPE*
|
||||
}
|
||||
|
||||
|
||||
static void SetLibShapeLine( const ASCH_BORDER_INTERFACE& elem, LIB_SHAPE* shape, ALTIUM_SCH_RECORD aType )
|
||||
static void SetLibShapeLine( const ASCH_BORDER_INTERFACE& elem, LIB_SHAPE* shape,
|
||||
ALTIUM_SCH_RECORD aType )
|
||||
{
|
||||
COLOR4D color = GetColorFromInt( elem.Color );
|
||||
COLOR4D default_color;
|
||||
COLOR4D alt_default_color = COLOR4D( PUREBLUE ); // PUREBLUE is used for many objects, so if it is used,
|
||||
// we will assume that it should blend with the others
|
||||
COLOR4D alt_default_color = COLOR4D( PUREBLUE ); // PUREBLUE is used for many objects, so if
|
||||
// it is used, we will assume that it should
|
||||
// blend with the others
|
||||
STROKE_PARAMS stroke;
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
case ALTIUM_SCH_RECORD::ARC:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::BEZIER:
|
||||
default_color = COLOR4D( PURERED );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::ELLIPSE:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::LINE:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::POLYGON:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::POLYLINE:
|
||||
default_color = COLOR4D( BLACK );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::RECTANGLE:
|
||||
default_color = COLOR4D( 0.5, 0, 0, 1.0 );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
default:
|
||||
default_color = COLOR4D( PUREBLUE );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::ARC: default_color = COLOR4D( PUREBLUE ); break;
|
||||
case ALTIUM_SCH_RECORD::BEZIER: default_color = COLOR4D( PURERED ); break;
|
||||
case ALTIUM_SCH_RECORD::ELLIPSE: default_color = COLOR4D( PUREBLUE ); break;
|
||||
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: default_color = COLOR4D( PUREBLUE ); break;
|
||||
case ALTIUM_SCH_RECORD::LINE: default_color = COLOR4D( PUREBLUE ); break;
|
||||
case ALTIUM_SCH_RECORD::POLYGON: default_color = COLOR4D( PUREBLUE ); break;
|
||||
case ALTIUM_SCH_RECORD::POLYLINE: default_color = COLOR4D( BLACK ); break;
|
||||
case ALTIUM_SCH_RECORD::RECTANGLE: default_color = COLOR4D( 0.5, 0, 0, 1.0 ); break;
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: default_color = COLOR4D( PUREBLUE ); break;
|
||||
default: default_color = COLOR4D( PUREBLUE ); break;
|
||||
}
|
||||
|
||||
if( color == default_color || color == alt_default_color )
|
||||
@@ -202,7 +184,9 @@ static void SetLibShapeFillAndColor( const ASCH_FILL_INTERFACE& elem, LIB_SHAPE*
|
||||
bgcolor = bgcolor.WithAlpha( 0.5 );
|
||||
|
||||
if( !elem.IsSolid )
|
||||
{
|
||||
shape->SetFillMode( FILL_T::NO_FILL );
|
||||
}
|
||||
else if( elem.AreaColor == aStrokeColor )
|
||||
{
|
||||
bgcolor = shape->GetStroke().GetColor();
|
||||
@@ -210,14 +194,18 @@ static void SetLibShapeFillAndColor( const ASCH_FILL_INTERFACE& elem, LIB_SHAPE*
|
||||
shape->SetFillMode( FILL_T::FILLED_SHAPE );
|
||||
}
|
||||
else if( bgcolor.WithAlpha( 1.0 ) == default_bgcolor )
|
||||
{
|
||||
shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
|
||||
}
|
||||
else
|
||||
{
|
||||
shape->SetFillMode( FILL_T::FILLED_WITH_COLOR );
|
||||
}
|
||||
|
||||
shape->SetFillColor( bgcolor );
|
||||
|
||||
if( elem.AreaColor == aStrokeColor
|
||||
&& shape->GetStroke().GetWidth() == schIUScale.MilsToIU( 1 ) )
|
||||
&& shape->GetStroke().GetWidth() == schIUScale.MilsToIU( 1 ) )
|
||||
{
|
||||
STROKE_PARAMS stroke = shape->GetStroke();
|
||||
stroke.SetWidth( -1 );
|
||||
@@ -243,9 +231,7 @@ SCH_IO_ALTIUM::~SCH_IO_ALTIUM()
|
||||
for( auto& [libName, lib] : m_libCache )
|
||||
{
|
||||
for( auto& [name, symbol] : lib )
|
||||
{
|
||||
delete symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +301,7 @@ wxFileName SCH_IO_ALTIUM::getLibFileName()
|
||||
|
||||
|
||||
SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
|
||||
SCH_SHEET* aAppendToMe,
|
||||
SCH_SHEET* aAppendToMe,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
@@ -407,6 +393,36 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
|
||||
allSheets.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
||||
allSheets.ClearEditFlags();
|
||||
|
||||
// Set up the default netclass wire & bus width based on imported wires & buses.
|
||||
//
|
||||
|
||||
int minWireWidth = std::numeric_limits<int>::max();
|
||||
int minBusWidth = std::numeric_limits<int>::max();
|
||||
|
||||
for( SCH_SCREEN* screen = allSheets.GetFirst(); screen != nullptr; screen = allSheets.GetNext() )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_LINE_T ) )
|
||||
{
|
||||
SCH_LINE* line = static_cast<SCH_LINE*>( item );
|
||||
|
||||
if( line->IsWire() && line->GetLineWidth() > 0 )
|
||||
minWireWidth = std::min( minWireWidth, line->GetLineWidth() );
|
||||
|
||||
if( line->IsBus() && line->GetLineWidth() > 0 )
|
||||
minBusWidth = std::min( minBusWidth, line->GetLineWidth() );
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<NET_SETTINGS>& netSettings = m_schematic->Prj().GetProjectFile().NetSettings();
|
||||
|
||||
if( minWireWidth < std::numeric_limits<int>::max() )
|
||||
netSettings->m_DefaultNetClass->SetWireWidth( minWireWidth );
|
||||
|
||||
if( minBusWidth < std::numeric_limits<int>::max() )
|
||||
netSettings->m_DefaultNetClass->SetBusWidth( minBusWidth );
|
||||
|
||||
return m_rootSheet;
|
||||
}
|
||||
|
||||
@@ -467,7 +483,8 @@ void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName )
|
||||
{
|
||||
// Try case-insensitive search
|
||||
wxArrayString files;
|
||||
wxDir::GetAllFiles( parentFileName.GetPath(), &files, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN );
|
||||
wxDir::GetAllFiles( parentFileName.GetPath(), &files, wxEmptyString,
|
||||
wxDIR_FILES | wxDIR_HIDDEN );
|
||||
|
||||
for( const wxString& candidate : files )
|
||||
{
|
||||
@@ -543,9 +560,7 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
|
||||
THROW_IO_ERROR( "Storage weight is negative!" );
|
||||
|
||||
for( int i = 0; i < weight; i++ )
|
||||
{
|
||||
m_altiumStorage.emplace_back( reader );
|
||||
}
|
||||
|
||||
if( reader.HasParsingError() )
|
||||
THROW_IO_ERROR( "stream was not parsed correctly!" );
|
||||
@@ -692,8 +707,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
|
||||
m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ),
|
||||
RPT_SEVERITY_INFO );
|
||||
m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::LABEL:
|
||||
@@ -717,8 +731,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::PIECHART:
|
||||
m_reporter->Report( _( "Record 'PIECHART' not handled." ),
|
||||
RPT_SEVERITY_INFO );
|
||||
m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
|
||||
@@ -933,8 +946,7 @@ const ASCH_STORAGE_FILE* SCH_IO_ALTIUM::GetFileFromStorage( const wxString& aFil
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::ParseComponent( int aIndex,
|
||||
const std::map<wxString, wxString>& aProperties )
|
||||
void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxString>& aProperties )
|
||||
{
|
||||
SCH_SHEET* currentSheet = m_sheetPath.Last();
|
||||
wxCHECK( currentSheet, /* void */ );
|
||||
@@ -2141,7 +2153,7 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
|
||||
// TODO: e.g. can depend on Template (RECORD=39
|
||||
m_reporter->Report( wxString::Format( wxT( "Elliptical Arc's owner (%d) not found." ),
|
||||
elem.ownerindex ),
|
||||
RPT_SEVERITY_DEBUG );
|
||||
RPT_SEVERITY_DEBUG );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3041,6 +3053,11 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
|
||||
{
|
||||
libSymbol = powerSymbolIt->second; // cache hit
|
||||
}
|
||||
else if( LIB_SYMBOL* alreadyLoaded =
|
||||
m_pi->LoadSymbol( getLibFileName().GetFullPath(), elem.text, m_properties.get() ) )
|
||||
{
|
||||
libSymbol = alreadyLoaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
libSymbol = new LIB_SYMBOL( wxEmptyString );
|
||||
@@ -3064,8 +3081,8 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
|
||||
pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
pin->SetVisible( false );
|
||||
|
||||
VECTOR2I valueFieldPos =
|
||||
HelperGeneratePowerPortGraphics( libSymbol, elem.style, m_reporter );
|
||||
VECTOR2I valueFieldPos = HelperGeneratePowerPortGraphics( libSymbol, elem.style,
|
||||
m_reporter );
|
||||
|
||||
libSymbol->GetValueField().SetPosition( valueFieldPos );
|
||||
|
||||
@@ -3249,32 +3266,21 @@ void SCH_IO_ALTIUM::ParsePort( const ASCH_PORT& aElem )
|
||||
SCH_LABEL_BASE* label;
|
||||
|
||||
// TODO: detect correct label type depending on sheet settings, etc.
|
||||
#if 1 // Set to 1 to use SCH_HIERLABEL label, 0 to use SCH_GLOBALLABEL
|
||||
#if 1 // Set to 1 to use SCH_HIERLABEL label, 0 to use SCH_GLOBALLABEL
|
||||
{
|
||||
label = new SCH_HIERLABEL( position, aElem.Name );
|
||||
}
|
||||
#else
|
||||
#else
|
||||
label = new SCH_GLOBALLABEL( position, aElem.Name );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch( aElem.IOtype )
|
||||
{
|
||||
default:
|
||||
case ASCH_PORT_IOTYPE::UNSPECIFIED:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
|
||||
break;
|
||||
|
||||
case ASCH_PORT_IOTYPE::OUTPUT:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
|
||||
break;
|
||||
|
||||
case ASCH_PORT_IOTYPE::INPUT:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
|
||||
break;
|
||||
|
||||
case ASCH_PORT_IOTYPE::BIDI:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
|
||||
break;
|
||||
case ASCH_PORT_IOTYPE::UNSPECIFIED: label->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED ); break;
|
||||
case ASCH_PORT_IOTYPE::OUTPUT: label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT ); break;
|
||||
case ASCH_PORT_IOTYPE::INPUT: label->SetShape( LABEL_FLAG_SHAPE::L_INPUT ); break;
|
||||
case ASCH_PORT_IOTYPE::BIDI: label->SetShape( LABEL_FLAG_SHAPE::L_BIDI ); break;
|
||||
}
|
||||
|
||||
switch( aElem.Style )
|
||||
@@ -3288,6 +3294,7 @@ void SCH_IO_ALTIUM::ParsePort( const ASCH_PORT& aElem )
|
||||
label->SetSpinStyle( SPIN_STYLE::RIGHT );
|
||||
else
|
||||
label->SetSpinStyle( SPIN_STYLE::LEFT );
|
||||
|
||||
break;
|
||||
|
||||
case ASCH_PORT_STYLE::NONE_VERTICAL:
|
||||
@@ -3298,6 +3305,7 @@ void SCH_IO_ALTIUM::ParsePort( const ASCH_PORT& aElem )
|
||||
label->SetSpinStyle( SPIN_STYLE::UP );
|
||||
else
|
||||
label->SetSpinStyle( SPIN_STYLE::BOTTOM );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3393,8 +3401,8 @@ void SCH_IO_ALTIUM::ParseWire( const std::map<wxString, wxString>& aProperties )
|
||||
|
||||
for( size_t i = 0; i + 1 < elem.points.size(); i++ )
|
||||
{
|
||||
SCH_LINE* wire =
|
||||
new SCH_LINE( elem.points.at( i ) + m_sheetOffset, SCH_LAYER_ID::LAYER_WIRE );
|
||||
SCH_LINE* wire = new SCH_LINE( elem.points.at( i ) + m_sheetOffset,
|
||||
SCH_LAYER_ID::LAYER_WIRE );
|
||||
wire->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset );
|
||||
wire->SetLineWidth( elem.lineWidth );
|
||||
|
||||
@@ -3780,11 +3788,18 @@ void SCH_IO_ALTIUM::ParseLibParameter( const std::map<wxString, wxString>& aProp
|
||||
{
|
||||
ASCH_PARAMETER elem( aProperties );
|
||||
|
||||
// Part ID 1 is the current library part. Part ID -1 means all parts
|
||||
// Part ID 1 is the current library part.
|
||||
// Part ID ALTIUM_COMPONENT_NONE(-1) means all parts
|
||||
// If a parameter is assigned to a specific element such as a pin,
|
||||
// we will need to handle it here.
|
||||
// TODO: Handle HIDDENNETNAME property (others?)
|
||||
if( elem.ownerpartid != 1 && elem.ownerpartid != -1 )
|
||||
if( elem.ownerpartid != 1 && elem.ownerpartid != ALTIUM_COMPONENT_NONE )
|
||||
return;
|
||||
|
||||
// If ownerindex is populated, this is parameter belongs to a subelement (e.g. pin).
|
||||
// Ignore for now.
|
||||
// TODO: Update this when KiCad supports parameters for any object
|
||||
if( elem.ownerindex != ALTIUM_COMPONENT_NONE )
|
||||
return;
|
||||
|
||||
// TODO: fill in replacements from variant, sheet and project
|
||||
@@ -3806,25 +3821,26 @@ void SCH_IO_ALTIUM::ParseLibParameter( const std::map<wxString, wxString>& aProp
|
||||
else
|
||||
{
|
||||
int fieldIdx = libSymbol->GetFieldCount();
|
||||
wxString fieldName = elem.name.Upper();
|
||||
wxString fieldNameStem = elem.name;
|
||||
wxString fieldName = fieldNameStem;
|
||||
int disambiguate = 1;
|
||||
|
||||
if( fieldName.IsEmpty() )
|
||||
{
|
||||
int disambiguate = 1;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
fieldName = wxString::Format( "ALTIUM_UNNAMED_%d", disambiguate++ );
|
||||
|
||||
if( !libSymbol->FindField( fieldName ) )
|
||||
break;
|
||||
}
|
||||
fieldNameStem = "ALTIUM_UNNAMED";
|
||||
fieldName = "ALTIUM_UNNAMED_1";
|
||||
disambiguate = 2;
|
||||
}
|
||||
else if( fieldName == "VALUE" )
|
||||
else if( upperName == "VALUE" )
|
||||
{
|
||||
fieldNameStem = "ALTIUM_VALUE";
|
||||
fieldName = "ALTIUM_VALUE";
|
||||
}
|
||||
|
||||
// Avoid adding duplicate fields
|
||||
while( libSymbol->FindField( fieldName ) )
|
||||
fieldName = wxString::Format( "%s_%d", fieldNameStem, disambiguate++ );
|
||||
|
||||
LIB_FIELD* new_field = new LIB_FIELD( fieldIdx, fieldName );
|
||||
libSymbol->AddField( new_field );
|
||||
field = new_field;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@@ -38,6 +39,8 @@ SCH_IO_DATABASE::SCH_IO_DATABASE() : SCH_IO( wxS( "Database library" ) ),
|
||||
m_settings(),
|
||||
m_conn()
|
||||
{
|
||||
m_cacheTimestamp = 0;
|
||||
m_cacheModifyHash = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +68,7 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
wxCHECK_RET( m_libTable, "Database plugin missing library table handle!" );
|
||||
ensureSettings( aLibraryPath );
|
||||
ensureConnection();
|
||||
cacheLib();
|
||||
|
||||
if( !m_conn )
|
||||
THROW_IO_ERROR( m_lastError );
|
||||
@@ -73,36 +77,12 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) !=
|
||||
aProperties->end() );
|
||||
|
||||
for( const DATABASE_LIB_TABLE& table : m_settings->m_Tables )
|
||||
for( auto const& pair : m_nameToSymbolcache )
|
||||
{
|
||||
std::vector<DATABASE_CONNECTION::ROW> results;
|
||||
LIB_SYMBOL* symbol = pair.second;
|
||||
|
||||
if( !m_conn->SelectAll( table.table, table.key_col, results ) )
|
||||
{
|
||||
if( !m_conn->GetLastError().empty() )
|
||||
{
|
||||
wxString msg = wxString::Format( _( "Error reading database table %s: %s" ),
|
||||
table.table, m_conn->GetLastError() );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for( DATABASE_CONNECTION::ROW& result : results )
|
||||
{
|
||||
if( !result.count( table.key_col ) )
|
||||
continue;
|
||||
|
||||
std::string prefix = table.name.empty() ? "" : fmt::format( "{}/", table.name );
|
||||
wxString name( fmt::format( "{}{}", prefix,
|
||||
std::any_cast<std::string>( result[table.key_col] ) ) );
|
||||
|
||||
LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result );
|
||||
|
||||
if( symbol && ( !powerSymbolsOnly || symbol->IsPower() ) )
|
||||
aSymbolList.emplace_back( symbol );
|
||||
}
|
||||
if( !powerSymbolsOnly || symbol->IsPower() )
|
||||
aSymbolList.emplace_back( symbol );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +201,52 @@ bool SCH_IO_DATABASE::TestConnection( wxString* aErrorMsg )
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_DATABASE::cacheLib()
|
||||
{
|
||||
long long currentTimestampSeconds = wxDateTime::Now().GetValue().GetValue() / 1000;
|
||||
|
||||
if( m_libTable->GetModifyHash() == m_cacheModifyHash
|
||||
&& ( currentTimestampSeconds - m_cacheTimestamp ) < m_settings->m_Cache.max_age )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( const DATABASE_LIB_TABLE& table : m_settings->m_Tables )
|
||||
{
|
||||
std::vector<DATABASE_CONNECTION::ROW> results;
|
||||
|
||||
if( !m_conn->SelectAll( table.table, table.key_col, results ) )
|
||||
{
|
||||
if( !m_conn->GetLastError().empty() )
|
||||
{
|
||||
wxString msg = wxString::Format( _( "Error reading database table %s: %s" ),
|
||||
table.table, m_conn->GetLastError() );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for( DATABASE_CONNECTION::ROW& result : results )
|
||||
{
|
||||
if( !result.count( table.key_col ) )
|
||||
continue;
|
||||
|
||||
std::string prefix = table.name.empty() ? "" : fmt::format( "{}/", table.name );
|
||||
wxString name( fmt::format( "{}{}", prefix,
|
||||
std::any_cast<std::string>( result[table.key_col] ) ) );
|
||||
|
||||
LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result );
|
||||
|
||||
if( symbol )
|
||||
m_nameToSymbolcache.insert( { symbol->GetName(), symbol } );
|
||||
}
|
||||
}
|
||||
|
||||
m_cacheTimestamp = currentTimestampSeconds;
|
||||
m_cacheModifyHash = m_libTable->GetModifyHash();
|
||||
}
|
||||
|
||||
void SCH_IO_DATABASE::ensureSettings( const wxString& aSettingsPath )
|
||||
{
|
||||
auto tryLoad =
|
||||
@@ -542,6 +568,9 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
for( LIB_FIELD* field : fields )
|
||||
fieldsMap[field->GetName()] = field;
|
||||
|
||||
static const wxString c_valueFieldName( wxS( "Value" ) );
|
||||
static const wxString c_datasheetFieldName( wxS( "Datasheet" ) );
|
||||
|
||||
for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
|
||||
{
|
||||
if( !aRow.count( mapping.column ) )
|
||||
@@ -551,7 +580,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
continue;
|
||||
}
|
||||
|
||||
std:: string strValue;
|
||||
std::string strValue;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -563,7 +592,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
|
||||
wxString value( strValue.c_str(), wxConvUTF8 );
|
||||
|
||||
if( mapping.name == wxT( "Value" ) )
|
||||
if( mapping.name_wx == c_valueFieldName )
|
||||
{
|
||||
LIB_FIELD& field = symbol->GetValueField();
|
||||
field.SetText( value );
|
||||
@@ -575,7 +604,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if( mapping.name == wxT( "Datasheet" ) )
|
||||
else if( mapping.name_wx == c_datasheetFieldName )
|
||||
{
|
||||
LIB_FIELD& field = symbol->GetDatasheetField();
|
||||
field.SetText( value );
|
||||
@@ -595,16 +624,16 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
LIB_FIELD* field;
|
||||
bool isNew = false;
|
||||
|
||||
if( fieldsMap.count( mapping.name ) )
|
||||
if( fieldsMap.count( mapping.name_wx ) )
|
||||
{
|
||||
field = fieldsMap[mapping.name];
|
||||
field = fieldsMap[mapping.name_wx];
|
||||
}
|
||||
else
|
||||
{
|
||||
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
|
||||
field->SetName( mapping.name );
|
||||
field->SetName( mapping.name_wx );
|
||||
isNew = true;
|
||||
fieldsMap[mapping.name] = field;
|
||||
fieldsMap[mapping.name_wx] = field;
|
||||
}
|
||||
|
||||
if( !mapping.inherit_properties || isNew )
|
||||
@@ -617,13 +646,15 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
|
||||
field->SetText( value );
|
||||
|
||||
if( isNew )
|
||||
symbol->AddField( field );
|
||||
symbol->AddDrawItem( field, false );
|
||||
|
||||
m_customFields.insert( mapping.name );
|
||||
m_customFields.insert( mapping.name_wx );
|
||||
|
||||
if( mapping.visible_in_chooser )
|
||||
m_defaultShownFields.insert( mapping.name );
|
||||
m_defaultShownFields.insert( mapping.name_wx );
|
||||
}
|
||||
|
||||
symbol->GetDrawItems().sort();
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ public:
|
||||
bool TestConnection( wxString* aErrorMsg = nullptr );
|
||||
|
||||
private:
|
||||
void cacheLib();
|
||||
|
||||
void ensureSettings( const wxString& aSettingsPath );
|
||||
|
||||
void ensureConnection();
|
||||
@@ -108,6 +110,14 @@ private:
|
||||
|
||||
std::set<wxString> m_defaultShownFields;
|
||||
|
||||
std::map<wxString, LIB_SYMBOL*> m_nameToSymbolcache;
|
||||
|
||||
long long m_cacheTimestamp;
|
||||
|
||||
int m_cacheModifyHash;
|
||||
|
||||
|
||||
|
||||
wxString m_lastError;
|
||||
};
|
||||
|
||||
|
||||
@@ -175,48 +175,6 @@ static ELECTRICAL_PINTYPE ConvertElecType( const wxString& aType )
|
||||
}
|
||||
|
||||
|
||||
static void TransformToBaseline( EDA_TEXT* textItem, const wxString& baselineAlign, bool invertY )
|
||||
{
|
||||
int upOffset = 0;
|
||||
|
||||
if( baselineAlign == wxS( "" ) || baselineAlign == wxS( "auto" )
|
||||
|| baselineAlign == wxS( "use-script" ) || baselineAlign == wxS( "no-change" )
|
||||
|| baselineAlign == wxS( "reset-size" ) || baselineAlign == wxS( "alphabetic" )
|
||||
|| baselineAlign == wxS( "inherit" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y;
|
||||
}
|
||||
else if( baselineAlign == wxS( "ideographic" ) || baselineAlign == wxS( "text-after-edge" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 1.2;
|
||||
}
|
||||
else if( baselineAlign == wxS( "central" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.5;
|
||||
}
|
||||
else if( baselineAlign == wxS( "middle" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.6;
|
||||
}
|
||||
else if( baselineAlign == wxS( "mathematical" ) )
|
||||
{
|
||||
upOffset = textItem->GetTextSize().y * 0.1;
|
||||
}
|
||||
else if( baselineAlign == wxS( "hanging" ) || baselineAlign == wxS( "text-before-edge" ) )
|
||||
{
|
||||
upOffset = 0;
|
||||
}
|
||||
|
||||
VECTOR2I offset( 0, -upOffset );
|
||||
RotatePoint( offset, textItem->GetTextAngle() );
|
||||
|
||||
if( invertY )
|
||||
offset.y = -offset.y;
|
||||
|
||||
textItem->SetTextPos( textItem->GetTextPos() + offset );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, EASYEDA::POWER_FLAG_STYLE aStyle,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
@@ -936,7 +894,7 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
|
||||
|
||||
textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) );
|
||||
|
||||
TransformToBaseline( textItem, baselineAlign, true );
|
||||
TransformTextToBaseline( textItem, baselineAlign, true );
|
||||
|
||||
if( added )
|
||||
aSymbol->AddDrawItem( dynamic_cast<LIB_ITEM*>( textItem ) );
|
||||
@@ -1299,7 +1257,7 @@ void SCH_EASYEDA_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRoot
|
||||
|
||||
valField->SetTextSize( VECTOR2I( ktextSize, ktextSize ) );
|
||||
|
||||
//TransformToBaseline( valField, wxS( "" ), true );
|
||||
//TransformTextToBaseline( valField, wxS( "" ), true );
|
||||
|
||||
createdItems.push_back( std::move( schSym ) );
|
||||
}
|
||||
@@ -1418,7 +1376,7 @@ void SCH_EASYEDA_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRoot
|
||||
|
||||
textItem->SetTextSize( VECTOR2I( ktextSize, ktextSize ) );
|
||||
|
||||
TransformToBaseline( textItem.get(), baselineAlign, false );
|
||||
TransformTextToBaseline( textItem.get(), baselineAlign, false );
|
||||
|
||||
createdItems.push_back( std::move( textItem ) );
|
||||
}
|
||||
|
||||
@@ -670,7 +670,20 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
|
||||
}
|
||||
else
|
||||
{
|
||||
parseQuotedString( field->m_name, aReader, line, &line, true ); // Optional.
|
||||
wxString fieldName = wxEmptyString;
|
||||
parseQuotedString( fieldName, aReader, line, &line, true ); // Optional.
|
||||
|
||||
if( fieldName.IsEmpty() )
|
||||
return;
|
||||
|
||||
wxString candidateFieldName = fieldName;
|
||||
int suffix = 0;
|
||||
|
||||
//Deduplicate field name
|
||||
while( aSymbol->FindField( candidateFieldName ) != nullptr )
|
||||
candidateFieldName = wxString::Format( "%s_%d", fieldName, ++suffix );
|
||||
|
||||
field->m_name = candidateFieldName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::Load()
|
||||
SCH_IO_KICAD_SEXPR_PARSER parser( &reader );
|
||||
|
||||
parser.ParseLib( m_symbols );
|
||||
++m_modHash;
|
||||
IncrementModifyHash();
|
||||
|
||||
// Remember the file modification time of library file when the cache snapshot was made,
|
||||
// so that in a networked environment we will reload the cache as needed.
|
||||
@@ -562,6 +562,6 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::DeleteSymbol( const wxString& aSymbolName )
|
||||
delete symbol;
|
||||
}
|
||||
|
||||
++m_modHash;
|
||||
IncrementModifyHash();
|
||||
m_isModified = true;
|
||||
}
|
||||
|
||||
@@ -4006,7 +4006,7 @@ SCH_TEXT* SCH_IO_KICAD_SEXPR_PARSER::parseSchText()
|
||||
|
||||
case T_at:
|
||||
text->SetPosition( parseXY() );
|
||||
text->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), DEGREES_T ) );
|
||||
text->SetTextAngle( EDA_ANGLE( parseDouble( "text angle" ), DEGREES_T ).KeepUpright() );
|
||||
|
||||
if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( text.get() ) )
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <kiway_player.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#define FMT_UNIMPLEMENTED _( "Plugin \"%s\" does not implement the \"%s\" function." )
|
||||
#define FMT_NOTFOUND _( "Plugin type \"%s\" is not found." )
|
||||
@@ -185,3 +186,63 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& a
|
||||
|
||||
return SCH_IO_MGR::SCH_FILE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_IO_MGR::ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath,
|
||||
const wxString& aNewFilepath )
|
||||
{
|
||||
SCH_IO_MGR::SCH_FILE_T oldFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath );
|
||||
|
||||
if( oldFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
|
||||
return false;
|
||||
|
||||
IO_RELEASER<SCH_IO> oldFilePI( SCH_IO_MGR::FindPlugin( oldFileType ) );
|
||||
IO_RELEASER<SCH_IO> kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
|
||||
std::vector<LIB_SYMBOL*> symbols;
|
||||
std::vector<LIB_SYMBOL*> newSymbols;
|
||||
std::map<LIB_SYMBOL*, LIB_SYMBOL*> symbolMap;
|
||||
|
||||
try
|
||||
{
|
||||
oldFilePI->EnumerateSymbolLib( symbols, aOldFilePath, aOldFileProps );
|
||||
|
||||
// Copy non-aliases first, so we can build a map from symbols to newSymbols
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
if( symbol->IsAlias() )
|
||||
continue;
|
||||
|
||||
symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
|
||||
|
||||
newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
|
||||
symbolMap[symbol] = newSymbols.back();
|
||||
}
|
||||
|
||||
// Now do the aliases using the map to hook them up to their newSymbol parents
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
if( !symbol->IsAlias() )
|
||||
continue;
|
||||
|
||||
symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) );
|
||||
|
||||
newSymbols.push_back( new LIB_SYMBOL( *symbol ) );
|
||||
newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] );
|
||||
}
|
||||
|
||||
// Create a blank library
|
||||
kicadPI->SaveLibrary( aNewFilepath );
|
||||
|
||||
// Finally write out newSymbols
|
||||
for( LIB_SYMBOL* symbol : newSymbols )
|
||||
{
|
||||
kicadPI->SaveSymbol( aNewFilepath, symbol );
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,12 @@ public:
|
||||
* Return a plugin type given a schematic using the file extension of \a aSchematicPath.
|
||||
*/
|
||||
static SCH_FILE_T GuessPluginTypeFromSchPath( const wxString& aSchematicPath, int aCtl = 0 );
|
||||
|
||||
/**
|
||||
* Convert a schematic symbol library to the latest KiCad format
|
||||
*/
|
||||
static bool ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath,
|
||||
const wxString& aNewFilepath );
|
||||
};
|
||||
|
||||
#endif // _SCH_IO_MGR_H_
|
||||
|
||||
@@ -392,3 +392,50 @@ static struct SCH_ITEM_DESC
|
||||
} _SCH_ITEM_DESC;
|
||||
|
||||
IMPLEMENT_ENUM_TO_WXANY( SCH_LAYER_ID )
|
||||
|
||||
|
||||
static bool lessYX( const DANGLING_END_ITEM& a, const DANGLING_END_ITEM& b )
|
||||
{
|
||||
const auto aPos = a.GetPosition();
|
||||
const auto bPos = b.GetPosition();
|
||||
return aPos.y < bPos.y ? true : ( aPos.y > bPos.y ? false : aPos.x < bPos.x );
|
||||
};
|
||||
|
||||
|
||||
static bool lessType( const DANGLING_END_ITEM& a, const DANGLING_END_ITEM& b )
|
||||
{
|
||||
return a.GetType() < b.GetType();
|
||||
};
|
||||
|
||||
|
||||
std::vector<DANGLING_END_ITEM>::iterator
|
||||
DANGLING_END_ITEM_HELPER::get_lower_pos( std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const VECTOR2I& aPos )
|
||||
{
|
||||
DANGLING_END_ITEM needle = DANGLING_END_ITEM( PIN_END, nullptr, aPos );
|
||||
auto start = aItemListByPos.begin();
|
||||
auto end = aItemListByPos.end();
|
||||
return std::lower_bound( start, end, needle, lessYX );
|
||||
}
|
||||
|
||||
|
||||
std::vector<DANGLING_END_ITEM>::iterator
|
||||
DANGLING_END_ITEM_HELPER::get_lower_type( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
const DANGLING_END_T& aType )
|
||||
{
|
||||
DANGLING_END_ITEM needle = DANGLING_END_ITEM( aType, nullptr, VECTOR2I{} );
|
||||
auto start = aItemListByType.begin();
|
||||
auto end = aItemListByType.end();
|
||||
return std::lower_bound( start, end, needle, lessType );
|
||||
}
|
||||
|
||||
|
||||
void DANGLING_END_ITEM_HELPER::sort_dangling_end_items(
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos )
|
||||
{
|
||||
// WIRE_END pairs must be kept together. Hence stable sort.
|
||||
std::stable_sort( aItemListByType.begin(), aItemListByType.end(), lessType );
|
||||
// Sort by y first, pins are more likely to share x than y.
|
||||
std::sort( aItemListByPos.begin(), aItemListByPos.end(), lessYX );
|
||||
}
|
||||
|
||||
+20
-3
@@ -137,6 +137,20 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class DANGLING_END_ITEM_HELPER
|
||||
{
|
||||
public:
|
||||
static std::vector<DANGLING_END_ITEM>::iterator
|
||||
get_lower_pos( std::vector<DANGLING_END_ITEM>& aItemListByPos, const VECTOR2I& aPos );
|
||||
|
||||
static std::vector<DANGLING_END_ITEM>::iterator
|
||||
get_lower_type( std::vector<DANGLING_END_ITEM>& aItemListByType, const DANGLING_END_T& aType );
|
||||
|
||||
/** Both contain the same information */
|
||||
static void sort_dangling_end_items( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos );
|
||||
};
|
||||
|
||||
typedef std::vector<SCH_ITEM*> SCH_ITEM_SET;
|
||||
|
||||
|
||||
@@ -352,12 +366,15 @@ public:
|
||||
* If aSheet is passed a non-null pointer to a SCH_SHEET_PATH, the overridden method can
|
||||
* optionally use it to update sheet-local connectivity information
|
||||
*
|
||||
* @param aItemList is the list of items to test item against.
|
||||
* @param aItemListByType is the list of items to test item against. It's sorted
|
||||
* by item type, keeping WIRE_END pairs together.
|
||||
* @param aItemListByPos is the same list but sorted first by Y then by X.
|
||||
* @param aSheet is the sheet path to update connections for.
|
||||
* @return True if the dangling state has changed from it's current setting.
|
||||
*/
|
||||
virtual bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath = nullptr )
|
||||
virtual bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath = nullptr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
+58
-27
@@ -1101,16 +1101,19 @@ bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy
|
||||
}
|
||||
|
||||
|
||||
bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
|
||||
std::vector<DANGLING_END_ITEM>& aItemListByPos,
|
||||
const SCH_SHEET_PATH* aPath )
|
||||
{
|
||||
bool previousState = m_isDangling;
|
||||
m_isDangling = true;
|
||||
bool previousState = m_isDangling;
|
||||
VECTOR2I text_pos = GetTextPos();
|
||||
m_isDangling = true;
|
||||
m_connectionType = CONNECTION_TYPE::NONE;
|
||||
|
||||
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
||||
for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
|
||||
it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
|
||||
{
|
||||
DANGLING_END_ITEM& item = aItemList[ii];
|
||||
DANGLING_END_ITEM& item = *it;
|
||||
|
||||
if( item.GetItem() == this )
|
||||
continue;
|
||||
@@ -1121,33 +1124,68 @@ bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemL
|
||||
case LABEL_END:
|
||||
case SHEET_LABEL_END:
|
||||
case NO_CONNECT_END:
|
||||
if( GetTextPos() == item.GetPosition() )
|
||||
if( text_pos == item.GetPosition() )
|
||||
{
|
||||
m_isDangling = false;
|
||||
|
||||
if( aPath && item.GetType() != PIN_END )
|
||||
AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BUS_END:
|
||||
m_connectionType = CONNECTION_TYPE::BUS;
|
||||
KI_FALLTHROUGH;
|
||||
default: break;
|
||||
}
|
||||
|
||||
case WIRE_END:
|
||||
if( !m_isDangling )
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_isDangling )
|
||||
{
|
||||
for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
|
||||
it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
|
||||
{
|
||||
DANGLING_END_ITEM& nextItem = aItemList[++ii];
|
||||
DANGLING_END_ITEM& item = *it;
|
||||
DANGLING_END_ITEM& nextItem = *( ++it );
|
||||
|
||||
int accuracy = 1; // We have rounding issues with an accuracy of 0
|
||||
int accuracy = 1; // We have rounding issues with an accuracy of 0
|
||||
|
||||
m_isDangling = !TestSegmentHit( GetTextPos(), item.GetPosition(),
|
||||
nextItem.GetPosition(), accuracy );
|
||||
m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(),
|
||||
accuracy );
|
||||
|
||||
if( !m_isDangling )
|
||||
if( m_isDangling )
|
||||
continue;
|
||||
|
||||
m_connectionType = CONNECTION_TYPE::BUS;
|
||||
|
||||
// Add the line to the connected items, since it won't be picked
|
||||
// up by a search of intersecting connection points
|
||||
if( aPath )
|
||||
{
|
||||
if( m_connectionType != CONNECTION_TYPE::BUS )
|
||||
m_connectionType = CONNECTION_TYPE::NET;
|
||||
auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
|
||||
AddConnectionTo( *aPath, sch_item );
|
||||
sch_item->AddConnectionTo( *aPath, this );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_isDangling )
|
||||
{
|
||||
for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
|
||||
it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
|
||||
{
|
||||
DANGLING_END_ITEM& item = *it;
|
||||
DANGLING_END_ITEM& nextItem = *( ++it );
|
||||
|
||||
int accuracy = 1; // We have rounding issues with an accuracy of 0
|
||||
|
||||
m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(),
|
||||
nextItem.GetPosition(), accuracy );
|
||||
|
||||
if( m_isDangling )
|
||||
continue;
|
||||
|
||||
m_connectionType = CONNECTION_TYPE::NET;
|
||||
|
||||
// Add the line to the connected items, since it won't be picked
|
||||
// up by a search of intersecting connection points
|
||||
@@ -1157,16 +1195,9 @@ bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemL
|
||||
AddConnectionTo( *aPath, sch_item );
|
||||
sch_item->AddConnectionTo( *aPath, this );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !m_isDangling )
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_isDangling )
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user