Compare commits
208 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 761bfcd291 | |||
| 7663928a66 | |||
| dd3c846f4a | |||
| 6877bc32bc | |||
| 64564825c7 | |||
| b1ec1011b6 | |||
| 80539790c3 | |||
| 981772887a | |||
| 896b80652f | |||
| 968cf4267a | |||
| f3567cda99 | |||
| df372baff8 | |||
| dec96e6a77 | |||
| 8a1de8c6f8 | |||
| 255975f5fd | |||
| aa608ca147 | |||
| 682b74f7d2 | |||
| d662b2c34b | |||
| 7740c66479 | |||
| 4d4f6a810c | |||
| d74dca3a7a | |||
| 6513ca9168 | |||
| 6782bb73bd | |||
| 9c35689b04 | |||
| 8aff7cad17 | |||
| c2c6cad525 | |||
| 9b17ec5d2d | |||
| e971f90adc | |||
| 06c61a4831 | |||
| 7977f0f745 | |||
| 38a2b8eba7 | |||
| 951f0065ed | |||
| 22c06c7ed8 | |||
| 4f086271aa | |||
| 297999cb43 | |||
| 91aec9ac7f | |||
| 9105b380c3 | |||
| a285f86240 | |||
| b2f8a43c24 | |||
| 8383165269 | |||
| bc8af77aba | |||
| 7d0e1670ee | |||
| 877f7daa2b | |||
| 4c563e5ef3 | |||
| d6d6075a60 | |||
| 49c528f3ef | |||
| ae1bccfb85 | |||
| c2c13a5226 | |||
| 5b2e0d113a | |||
| 7ee8f786f2 | |||
| bd14224b42 | |||
| ccfec170b0 | |||
| 9852b535e7 | |||
| 758ac90069 | |||
| 697ff382f8 | |||
| 6b6aa84158 | |||
| a0d219c2d1 | |||
| 8af1af7f76 | |||
| 991d5812e2 | |||
| b019ce4515 | |||
| 168a1b3e75 | |||
| e8a6e579e4 | |||
| f2b1422ed5 | |||
| 63f4d45665 | |||
| 96ab1e47c9 | |||
| 4d69d966ee | |||
| e9294bee9e | |||
| d2b052b12c | |||
| 34f0a97cca | |||
| ad5ca38cc2 | |||
| 58bd7f3b24 | |||
| 5b2b4832d4 | |||
| a3618cbfeb | |||
| 8c6edc0414 | |||
| 1308fd7c4a | |||
| b241e09914 | |||
| 0a29c0dea3 | |||
| 8832b22952 | |||
| 33b93a3824 | |||
| b589da63d8 | |||
| 48077d77c4 | |||
| a605c4b6ff | |||
| 092ce30b40 | |||
| 28eb6dab97 | |||
| fb82130530 | |||
| a3d218ffbc | |||
| 471f72a340 | |||
| 2abbc601a0 | |||
| 522f1c7bea | |||
| 828f32649f | |||
| b39b54a92e | |||
| 6a55a47276 | |||
| 648d463b32 | |||
| 489f345fb2 | |||
| e308d65108 | |||
| ee0be76fb4 | |||
| 813fce2d2d | |||
| e0a27b430a | |||
| 73b2180c06 | |||
| b3f53ac862 | |||
| 9b49fc5a0d | |||
| 03c71b22d5 | |||
| 7d79bebcc6 | |||
| 5c2300022b | |||
| 91b042990f | |||
| 265e2d61be | |||
| df3924421d | |||
| 4ee2a007eb | |||
| b19a47fa2a | |||
| 7f3ca3b889 | |||
| a3d64d604c | |||
| 006f0a95c1 | |||
| 6afd865259 | |||
| d319cd4b89 | |||
| 566fefafc5 | |||
| 66bd0f850a | |||
| 491bb6e57a | |||
| 4fe74a9870 | |||
| 8f03f7c367 | |||
| 7f690d596b | |||
| be4c2715ab | |||
| 02f8260e18 | |||
| a8871fdda4 | |||
| d552ce00aa | |||
| 37dd7c6df9 | |||
| a5cbcd4abe | |||
| 4ede6f61b2 | |||
| 994c1c971a | |||
| ebdfeb4c0a | |||
| e1ffd956e6 | |||
| 3f4dc01d97 | |||
| be192d5df0 | |||
| efc35dec74 | |||
| 096566e857 | |||
| 944ee4af7d | |||
| 245894e8eb | |||
| 74abb40e84 | |||
| 1eb2983efe | |||
| 63b3e0cc4f | |||
| a8b127019c | |||
| 4d0ca33b47 | |||
| e2c53df13b | |||
| 03dd6c7a8e | |||
| bdd5a752dc | |||
| 8dbdc3717c | |||
| f60b76696a | |||
| 695505fc71 | |||
| b34dbf58c5 | |||
| 1fb19c0d81 | |||
| d6162196ec | |||
| 3ea314cb9f | |||
| 9d51fabe9b | |||
| c6b483acb9 | |||
| 96370f6665 | |||
| ad7bd9b5f8 | |||
| 2a1ef2d09d | |||
| 9f9fa0dd8d | |||
| 6ecfa65c4c | |||
| 831d438852 | |||
| a9b5b1728a | |||
| d304a30155 | |||
| 02ca96df48 | |||
| 5ca3414707 | |||
| 76a68b1f8d | |||
| 41ebd3c560 | |||
| fbc75656f4 | |||
| b882defb28 | |||
| 7d7decafd4 | |||
| 8705bea9ab | |||
| 64da49f22e | |||
| 0c9554a325 | |||
| dc24d13fef | |||
| 78cbb8e994 | |||
| ddd0ccbefd | |||
| f5797d367f | |||
| 89dff6411b | |||
| 093da7f73a | |||
| 2215e8906f | |||
| d34df3e951 | |||
| 044a2305e3 | |||
| 05264424b3 | |||
| 3e59c40283 | |||
| 2a99464fc1 | |||
| 412da66cf6 | |||
| c6215b08ed | |||
| 769060c584 | |||
| 0b48a66cb0 | |||
| 836b3219c1 | |||
| 2c0010fbcb | |||
| c1ed2506f9 | |||
| 299495a0aa | |||
| 6f3b6e3ad8 | |||
| cb9d78b46c | |||
| 46b3dcba4f | |||
| 06150388d8 | |||
| b07de4f6af | |||
| 6dd5422137 | |||
| 546ca18662 | |||
| de0f6ecf68 | |||
| 995c1a179e | |||
| bee4856a7f | |||
| 9721559005 | |||
| 7a1ab44207 | |||
| d269513857 | |||
| b4928f20a6 | |||
| 05d2893ac1 | |||
| 7ea205222d | |||
| e853b593b1 |
@@ -103,11 +103,6 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribL
|
||||
m_BiuTo3dUnits = 1.0;
|
||||
|
||||
m_glRC = nullptr;
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
SetScaleFactor( dpi.GetScaleFactor() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -812,9 +812,6 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
}
|
||||
|
||||
@@ -210,9 +210,6 @@ void PANEL_PREVIEW_3D_MODEL::loadSettings()
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
m_previewPane->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
|
||||
@@ -444,10 +441,15 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementScale( wxSpinEvent& event, double aSign
|
||||
else if( spinCtrl == m_spinZscale )
|
||||
textCtrl = zscale;
|
||||
|
||||
double step = SCALE_INCREMENT;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step = SCALE_INCREMENT_FINE;
|
||||
|
||||
double curr_value = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::UNSCALED,
|
||||
textCtrl->GetValue() );
|
||||
|
||||
curr_value += ( SCALE_INCREMENT * aSign );
|
||||
curr_value += ( step * aSign );
|
||||
curr_value = std::max( 1/MAX_SCALE, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_SCALE );
|
||||
|
||||
@@ -465,10 +467,15 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementRotation( wxSpinEvent& aEvent, double aS
|
||||
else if( spinCtrl == m_spinZrot )
|
||||
textCtrl = zrot;
|
||||
|
||||
double step = ROTATION_INCREMENT;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step = ROTATION_INCREMENT_FINE;
|
||||
|
||||
double curr_value = EDA_UNIT_UTILS::UI::DoubleValueFromString( unityScale, EDA_UNITS::DEGREES,
|
||||
textCtrl->GetValue() );
|
||||
|
||||
curr_value += ( ROTATION_INCREMENT * aSign );
|
||||
curr_value += ( step * aSign );
|
||||
curr_value = std::max( -MAX_ROTATION, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_ROTATION );
|
||||
|
||||
@@ -488,16 +495,22 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign
|
||||
textCtrl = zoff;
|
||||
|
||||
double step_mm = OFFSET_INCREMENT_MM;
|
||||
double curr_value_mm =
|
||||
EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
textCtrl->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step_mm = OFFSET_INCREMENT_MM_FINE;
|
||||
|
||||
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCHES )
|
||||
{
|
||||
step_mm = 25.4*OFFSET_INCREMENT_MIL/1000;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step_mm = 25.4*OFFSET_INCREMENT_MIL_FINE/1000;;
|
||||
}
|
||||
|
||||
double curr_value_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
textCtrl->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
|
||||
curr_value_mm += ( step_mm * aSign );
|
||||
curr_value_mm = std::max( -MAX_OFFSET, curr_value_mm );
|
||||
curr_value_mm = std::min( curr_value_mm, MAX_OFFSET );
|
||||
@@ -533,10 +546,10 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelRot( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
|
||||
double step = ROTATION_INCREMENT_WHEEL;
|
||||
double step = ROTATION_INCREMENT;
|
||||
|
||||
if( event.ShiftDown( ) )
|
||||
step = ROTATION_INCREMENT_WHEEL_FINE;
|
||||
step = ROTATION_INCREMENT_FINE;
|
||||
|
||||
if( event.GetWheelRotation() >= 0 )
|
||||
step = -step;
|
||||
|
||||
@@ -43,9 +43,8 @@
|
||||
#define SCALE_INCREMENT_FINE 0.02
|
||||
#define SCALE_INCREMENT 0.1
|
||||
|
||||
#define ROTATION_INCREMENT 90 // in degrees, for spin button command
|
||||
#define ROTATION_INCREMENT_WHEEL 90 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT_WHEEL_FINE 1 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT 90 // in degrees
|
||||
#define ROTATION_INCREMENT_FINE 1 // in degrees
|
||||
|
||||
#define OFFSET_INCREMENT_MM 0.5
|
||||
#define OFFSET_INCREMENT_MM_FINE 0.1
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.3" )
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.4" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -627,7 +627,6 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
}
|
||||
}
|
||||
|
||||
m_cache->Put( aTable, cacheEntry );
|
||||
wxASSERT( result.count( aKey ) );
|
||||
std::string keyStr = std::any_cast<std::string>( result.at( aKey ) );
|
||||
cacheEntry[keyStr] = result;
|
||||
|
||||
@@ -43,6 +43,9 @@ void DIALOG_EDIT_LIBRARY_TABLES::InstallPanel( wxPanel* aPanel )
|
||||
auto mainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
SetSizer( mainSizer );
|
||||
|
||||
m_infoBar = new WX_INFOBAR( this );
|
||||
mainSizer->Add( m_infoBar, 0, wxEXPAND, 0 );
|
||||
|
||||
mainSizer->Add( m_contentPanel, 1, wxEXPAND|wxLEFT|wxTOP|wxRIGHT, 5 );
|
||||
m_contentPanel->SetMinSize( FromDIP( wxSize( 1000, 600 ) ) );
|
||||
|
||||
|
||||
@@ -442,14 +442,11 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
|
||||
wxString netclass = m_assignmentGrid->GetCellValue( row, 1 );
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignments.push_back(
|
||||
{
|
||||
std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ),
|
||||
netclass
|
||||
} );
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignmentCache.clear();
|
||||
{ std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ), netclass } );
|
||||
}
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignmentCache.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -648,8 +648,21 @@ void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::SetCurrentCursor( KICURSOR aCursor )
|
||||
{
|
||||
if( m_gal )
|
||||
m_gal->SetNativeCursorStyle( aCursor );
|
||||
if( !m_gal )
|
||||
return;
|
||||
|
||||
DPI_SCALING_COMMON dpi( nullptr, m_parent );
|
||||
|
||||
bool hidpi = false;
|
||||
|
||||
// Cursor scaling factor cannot be set for a wxCursor on GTK and OSX (at least before wx 3.3),
|
||||
// resulting in 4x rendered size on 2x window scale.
|
||||
// MSW renders the bitmap as-is, without scaling, so this works here.
|
||||
#ifdef __WXMSW__
|
||||
hidpi = dpi.GetContentScaleFactor() >= 2.0;
|
||||
#endif
|
||||
|
||||
m_gal->SetNativeCursorStyle( aCursor, hidpi );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string_utils.h>
|
||||
#include <macros.h>
|
||||
#include <cstdint>
|
||||
#include <reporter.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -37,6 +38,8 @@ using namespace fontconfig;
|
||||
static FONTCONFIG* g_config = nullptr;
|
||||
static bool g_fcInitSuccess = false;
|
||||
|
||||
REPORTER* FONTCONFIG::s_reporter = nullptr;
|
||||
|
||||
/**
|
||||
* A simple wrapper to avoid exporing fontconfig in the header
|
||||
*/
|
||||
@@ -57,6 +60,12 @@ FONTCONFIG::FONTCONFIG()
|
||||
};
|
||||
|
||||
|
||||
void fontconfig::FONTCONFIG::SetReporter( REPORTER* aReporter )
|
||||
{
|
||||
s_reporter = aReporter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is simply a wrapper to call FcInit() with SEH for Windows
|
||||
* SEH on Windows can only be used in functions without objects that might be unwinded
|
||||
@@ -317,12 +326,15 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
|
||||
if( retval == FF_RESULT::FF_ERROR )
|
||||
{
|
||||
wxLogWarning( _( "Error loading font '%s'." ), qualifiedFontName );
|
||||
if( s_reporter )
|
||||
s_reporter->Report( wxString::Format( _( "Error loading font '%s'." ), qualifiedFontName ) );
|
||||
}
|
||||
else if( retval == FF_RESULT::FF_SUBSTITUTE )
|
||||
{
|
||||
fontName.Replace( ':', ' ' );
|
||||
wxLogWarning( _( "Font '%s' not found; substituting '%s'." ), qualifiedFontName, fontName );
|
||||
|
||||
if( s_reporter )
|
||||
s_reporter->Report( wxString::Format( _( "Font '%s' not found; substituting '%s'." ), qualifiedFontName, fontName ) );
|
||||
}
|
||||
|
||||
FcPatternDestroy( pat );
|
||||
|
||||
@@ -190,7 +190,7 @@ static double roundp( double x )
|
||||
|
||||
const VECTOR2D CAIRO_GAL_BASE::roundp( const VECTOR2D& v )
|
||||
{
|
||||
if( m_lineWidthIsOdd && m_isStrokeEnabled )
|
||||
if( m_lineWidthIsOdd )
|
||||
return VECTOR2D( ::roundp( v.x ), ::roundp( v.y ) );
|
||||
else
|
||||
return VECTOR2D( floor( v.x + 0.5 ), floor( v.y + 0.5 ) );
|
||||
@@ -352,13 +352,18 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
|
||||
double r = xform( aRadius );
|
||||
|
||||
// N.B. This is backwards. We set this because we want to adjust the center
|
||||
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||
// We cannot adjust radius or center based on the other because this causes the
|
||||
// whole arc to change position/size
|
||||
m_lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
||||
// Adjust center and radius slightly to better match the rounding of endpoints.
|
||||
VECTOR2D mid = roundp( xform( aCenterPoint ) );
|
||||
|
||||
auto mid = roundp( xform( aCenterPoint ) );
|
||||
VECTOR2D startPointS = VECTOR2D( r, 0.0 );
|
||||
VECTOR2D endPointS = VECTOR2D( r, 0.0 );
|
||||
RotatePoint( startPointS, -EDA_ANGLE( startAngle, RADIANS_T ) );
|
||||
RotatePoint( endPointS, -EDA_ANGLE( endAngle, RADIANS_T ) );
|
||||
|
||||
VECTOR2D refStart = roundp( xform( aCenterPoint ) + startPointS );
|
||||
VECTOR2D refEnd = roundp( xform( aCenterPoint ) + endPointS );
|
||||
|
||||
r = ( ( refStart - mid ).EuclideanNorm() + ( refEnd - mid ).EuclideanNorm() ) / 2.0;
|
||||
|
||||
cairo_set_line_width( m_currentContext, m_lineWidthInPixels );
|
||||
cairo_new_sub_path( m_currentContext );
|
||||
@@ -403,13 +408,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||
|
||||
double r = xform( aRadius );
|
||||
|
||||
// N.B. This is backwards. We set this because we want to adjust the center
|
||||
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||
// We cannot adjust radius or center based on the other because this causes the
|
||||
// whole arc to change position/size
|
||||
m_lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
||||
|
||||
VECTOR2D mid = roundp( xform( aCenterPoint ) );
|
||||
VECTOR2D mid = xform( aCenterPoint );
|
||||
double width = xform( aWidth / 2.0 );
|
||||
VECTOR2D startPointS = VECTOR2D( r, 0.0 );
|
||||
VECTOR2D endPointS = VECTOR2D( r, 0.0 );
|
||||
@@ -1672,13 +1671,16 @@ bool CAIRO_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||
}
|
||||
|
||||
|
||||
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
// Store the current cursor type and get the wxCursor for it
|
||||
if( !GAL::SetNativeCursorStyle( aCursor ) )
|
||||
if( !GAL::SetNativeCursorStyle( aCursor, aHiDPI ) )
|
||||
return false;
|
||||
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
if( aHiDPI )
|
||||
m_currentwxCursor = CURSOR_STORE::GetHiDPICursor( m_currentNativeCursor );
|
||||
else
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
|
||||
// Update the cursor in the wx control
|
||||
wxWindow::SetCursor( m_currentwxCursor );
|
||||
|
||||
+259
-51
@@ -44,85 +44,76 @@
|
||||
#include <cursors/cursor-subtract.xpm>
|
||||
#include <cursors/cursor-text.xpm>
|
||||
#include <cursors/cursor-xor.xpm>
|
||||
#include <cursors/cursor-zoom.xpm>
|
||||
#include <cursors/cursor-zoom-in.xpm>
|
||||
#include <cursors/cursor-zoom-out.xpm>
|
||||
#include <cursors/cursor_tune.xpm>
|
||||
#include <cursors/voltage_probe.xpm>
|
||||
#include <cursors/current_probe.xpm>
|
||||
|
||||
// HiDPI cursor files
|
||||
#include <cursors/cursor-add64.xpm>
|
||||
#include <cursors/cursor-component64.xpm>
|
||||
#include <cursors/cursor-eraser64.xpm>
|
||||
#include <cursors/cursor-label-global64.xpm>
|
||||
#include <cursors/cursor-label-hier64.xpm>
|
||||
#include <cursors/cursor-label-net64.xpm>
|
||||
#include <cursors/cursor-line-bus64.xpm>
|
||||
#include <cursors/cursor-line-graphic64.xpm>
|
||||
#include <cursors/cursor-line-wire64.xpm>
|
||||
#include <cursors/cursor-line-wire-add64.xpm>
|
||||
#include <cursors/cursor-measure64.xpm>
|
||||
#include <cursors/cursor-pencil64.xpm>
|
||||
#include <cursors/cursor-select-lasso64.xpm>
|
||||
#include <cursors/cursor-select-window64.xpm>
|
||||
#include <cursors/cursor-subtract64.xpm>
|
||||
#include <cursors/cursor-text64.xpm>
|
||||
#include <cursors/cursor-xor64.xpm>
|
||||
#include <cursors/cursor-zoom-in64.xpm>
|
||||
#include <cursors/cursor-zoom-out64.xpm>
|
||||
#include <cursors/cursor_tune64.xpm>
|
||||
#include <cursors/voltage_probe64.xpm>
|
||||
#include <cursors/current_probe64.xpm>
|
||||
|
||||
|
||||
// Under MSW, the standard cursor is white on black. Elsewhere it is black on white
|
||||
#ifdef __WINDOWS__
|
||||
#include <cursors/cursor-place.xpm>
|
||||
#include <cursors/cursor-place64.xpm>
|
||||
#include <cursors/cursor-select-m.xpm>
|
||||
#include <cursors/cursor-select-m64.xpm>
|
||||
#else
|
||||
#include <cursors/cursor-place-black.xpm>
|
||||
#include <cursors/cursor-place-black64.xpm>
|
||||
#include <cursors/cursor-select-m-black.xpm>
|
||||
#include <cursors/cursor-select-m-black64.xpm>
|
||||
#endif
|
||||
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/debug.h>
|
||||
|
||||
|
||||
static const unsigned char voltage_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
|
||||
0x00, 0x30, 0x06, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x80, 0x07, 0x08, 0x00,
|
||||
0xc0, 0x07, 0x18, 0x00, 0xe0, 0x07, 0x30, 0x00, 0xf0, 0x03, 0x60, 0x00, 0xf8, 0x01, 0x00, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
|
||||
0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char current_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00,
|
||||
0x00, 0x30, 0x0c, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x80, 0x0f, 0x18, 0x00,
|
||||
0xc0, 0x0f, 0x30, 0x80, 0xe1, 0x07, 0x60, 0x80, 0xf1, 0x03, 0x00, 0x80, 0xf9, 0x01, 0x00, 0x80,
|
||||
0xfd, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
|
||||
0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, 0x83,
|
||||
0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char cursor_tune[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00,
|
||||
0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
|
||||
0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
|
||||
0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
|
||||
0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x50,
|
||||
0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char cursor_tune_mask[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f,
|
||||
0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07,
|
||||
0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00,
|
||||
0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
|
||||
0x00, 0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00,
|
||||
0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x70, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
{
|
||||
KICURSOR::VOLTAGE_PROBE,
|
||||
voltage_probe,
|
||||
voltage_probe,
|
||||
nullptr,
|
||||
nullptr,
|
||||
voltage_probe_xpm,
|
||||
{ 32, 32 },
|
||||
{ 1, 31 },
|
||||
},
|
||||
{
|
||||
KICURSOR::CURRENT_PROBE,
|
||||
current_probe,
|
||||
current_probe,
|
||||
nullptr,
|
||||
nullptr,
|
||||
current_probe_xpm,
|
||||
{ 32, 32 },
|
||||
{ 4, 27 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TUNE,
|
||||
cursor_tune,
|
||||
cursor_tune_mask,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_tune_xpm,
|
||||
{ 32, 32 },
|
||||
{ 1, 30 },
|
||||
},
|
||||
@@ -198,7 +189,7 @@ static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
KICURSOR::ZOOM_IN,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_xpm,
|
||||
cursor_zoom_in_xpm,
|
||||
{ 32, 32 },
|
||||
{ 6, 6 },
|
||||
},
|
||||
@@ -305,6 +296,209 @@ static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
};
|
||||
|
||||
|
||||
static const std::vector<CURSOR_STORE::CURSOR_DEF> hidpi_cursors = {
|
||||
{
|
||||
KICURSOR::VOLTAGE_PROBE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
voltage_probe64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 1, 62 },
|
||||
},
|
||||
{
|
||||
KICURSOR::CURRENT_PROBE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
current_probe64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 54 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TUNE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_tune64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 2, 60 },
|
||||
},
|
||||
{
|
||||
KICURSOR::PENCIL,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_pencil64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 54 },
|
||||
},
|
||||
{
|
||||
KICURSOR::MOVING,
|
||||
nullptr,
|
||||
nullptr,
|
||||
#ifdef __WINDOWS__
|
||||
cursor_select_m64_xpm,
|
||||
#else
|
||||
cursor_select_m_black64_xpm,
|
||||
#endif
|
||||
{ 64, 64 },
|
||||
{ 2, 2 },
|
||||
},
|
||||
{
|
||||
KICURSOR::REMOVE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_eraser64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 8 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TEXT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_text64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::MEASURE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_measure64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 8 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ADD,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_add64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SUBTRACT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_subtract64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::XOR,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_xor64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ZOOM_IN,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_in64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 12, 12 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ZOOM_OUT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_out64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 12, 12 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_NET,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_net64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_GLOBAL,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_global64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::COMPONENT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_component64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SELECT_LASSO,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_select_lasso64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SELECT_WINDOW,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_select_window64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 20 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_BUS,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_bus64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_WIRE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_wire64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_WIRE_ADD,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_wire_add64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_GRAPHIC,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_graphic64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_HIER,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_hier64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::PLACE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
#ifdef __WINDOWS__
|
||||
cursor_place64_xpm,
|
||||
#else
|
||||
cursor_place_black64_xpm,
|
||||
#endif
|
||||
{ 64, 64 },
|
||||
{ 2, 2 },
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a cursor for the given definition.
|
||||
*
|
||||
@@ -393,8 +587,8 @@ const wxCursor& CURSOR_STORE::Get( KICURSOR aIdKey ) const
|
||||
|
||||
const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stock =
|
||||
GetStockCursor( aCursorType );
|
||||
wxStockCursor stock = GetStockCursor( aCursorType );
|
||||
|
||||
if( stock != wxCURSOR_MAX )
|
||||
{
|
||||
return wxCursor( stock );
|
||||
@@ -405,6 +599,20 @@ const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
|
||||
}
|
||||
|
||||
|
||||
const wxCursor CURSOR_STORE::GetHiDPICursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stock = GetStockCursor( aCursorType );
|
||||
|
||||
if( stock != wxCURSOR_MAX )
|
||||
{
|
||||
return wxCursor( stock );
|
||||
}
|
||||
|
||||
static CURSOR_STORE store( hidpi_cursors );
|
||||
return store.Get( aCursorType );
|
||||
}
|
||||
|
||||
|
||||
wxStockCursor CURSOR_STORE::GetStockCursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stockCursor;
|
||||
|
||||
@@ -81,7 +81,7 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||
SetCursorEnabled( false );
|
||||
|
||||
// Initialize the native widget to an arrow cursor
|
||||
SetNativeCursorStyle( KICURSOR::ARROW );
|
||||
SetNativeCursorStyle( KICURSOR::ARROW, false );
|
||||
|
||||
// Initialize text properties
|
||||
ResetTextAttributes();
|
||||
@@ -277,7 +277,7 @@ void GAL::BitmapText( const wxString& aText, const VECTOR2I& aPosition, const ED
|
||||
}
|
||||
|
||||
|
||||
bool GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
if( m_currentNativeCursor == aCursor )
|
||||
return false;
|
||||
|
||||
@@ -34,8 +34,7 @@ HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( const KIGFX::VC_SETTINGS& aSettings, wxWindow*
|
||||
const wxPoint& aPos, const wxSize& aSize, long aStyle,
|
||||
const wxString& aName, const wxPalette& aPalette ) :
|
||||
wxGLCanvas( aParent, aId, aAttribList, aPos, aSize, aStyle, aName, aPalette ),
|
||||
m_settings( aSettings ),
|
||||
m_scale_factor( DPI_SCALING::GetDefaultScaleFactor() )
|
||||
m_settings( aSettings )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -64,13 +63,7 @@ wxPoint HIDPI_GL_CANVAS::GetNativePosition( const wxPoint& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
void HIDPI_GL_CANVAS::SetScaleFactor( double aNewScaleFactor )
|
||||
{
|
||||
m_scale_factor = aNewScaleFactor;
|
||||
}
|
||||
|
||||
|
||||
double HIDPI_GL_CANVAS::GetScaleFactor() const
|
||||
{
|
||||
return m_scale_factor;
|
||||
return GetContentScaleFactor();
|
||||
}
|
||||
@@ -255,7 +255,8 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
bmp.accessTime = currentTime;
|
||||
|
||||
#ifndef DISABLE_BITMAP_CACHE
|
||||
if( m_cacheLru.size() + 1 > m_cacheMaxElements || m_cacheSize + bmp.size > m_cacheMaxSize )
|
||||
if( ( m_cacheLru.size() + 1 > m_cacheMaxElements || m_cacheSize + bmp.size > m_cacheMaxSize )
|
||||
&& !m_cacheLru.empty() )
|
||||
{
|
||||
KIID toRemove( 0 );
|
||||
auto toRemoveLru = m_cacheLru.end();
|
||||
@@ -507,13 +508,6 @@ bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if( m_options.m_scaleFactor != GetScaleFactor() )
|
||||
{
|
||||
SetScaleFactor( m_options.m_scaleFactor );
|
||||
m_gridLineWidth = m_options.m_scaleFactor * ( m_options.m_gridLineWidth + 0.25 );
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if( super::updatedGalDisplayOptions( aOptions ) || refresh )
|
||||
{
|
||||
Refresh();
|
||||
@@ -2134,13 +2128,16 @@ void OPENGL_GAL::EndDiffLayer()
|
||||
}
|
||||
|
||||
|
||||
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
// Store the current cursor type and get the wxCursor for it
|
||||
if( !GAL::SetNativeCursorStyle( aCursor ) )
|
||||
if( !GAL::SetNativeCursorStyle( aCursor, aHiDPI ) )
|
||||
return false;
|
||||
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
if( aHiDPI )
|
||||
m_currentwxCursor = CURSOR_STORE::GetHiDPICursor( m_currentNativeCursor );
|
||||
else
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
|
||||
// Update the cursor in the wx control
|
||||
HIDPI_GL_CANVAS::SetCursor( m_currentwxCursor );
|
||||
|
||||
@@ -642,10 +642,6 @@ void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData )
|
||||
if( startAngle > endAngle )
|
||||
endAngle += ANGLE_360;
|
||||
|
||||
// Angles are relative to major axis
|
||||
startAngle -= EDA_ANGLE( major );
|
||||
endAngle -= EDA_ANGLE( major );
|
||||
|
||||
if( aData.ratio == 1.0 )
|
||||
{
|
||||
double radius = major.EuclideanNorm();
|
||||
@@ -658,6 +654,10 @@ void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData )
|
||||
}
|
||||
else
|
||||
{
|
||||
// Angles are relative to major axis
|
||||
startAngle -= EDA_ANGLE( major );
|
||||
endAngle -= EDA_ANGLE( major );
|
||||
|
||||
DL_ArcData arc( aData.cx, aData.cy, aData.cz, radius, startAngle.AsDegrees(),
|
||||
endAngle.AsDegrees() );
|
||||
addArc( arc );
|
||||
|
||||
+14
-1
@@ -57,7 +57,6 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType
|
||||
|
||||
KIWAY_PLAYER::~KIWAY_PLAYER() throw()
|
||||
{
|
||||
|
||||
// socket server must be destructed before we complete
|
||||
// destructing the frame or else we could crash
|
||||
// as the socket server holds a reference to this frame
|
||||
@@ -69,6 +68,20 @@ KIWAY_PLAYER::~KIWAY_PLAYER() throw()
|
||||
delete m_socketServer;
|
||||
m_socketServer = nullptr;
|
||||
}
|
||||
|
||||
// remove active sockets as well
|
||||
for( wxSocketBase* socket : m_sockets )
|
||||
{
|
||||
if( !socket )
|
||||
continue;
|
||||
|
||||
// ensure any event handling stops
|
||||
socket->Notify( false );
|
||||
|
||||
delete socket;
|
||||
}
|
||||
|
||||
m_sockets.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "lib_table_grid.h"
|
||||
|
||||
|
||||
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) : GRID_TRICKS( aGrid )
|
||||
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) :
|
||||
GRID_TRICKS( aGrid )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,11 +66,14 @@ void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
|
||||
if( showDeactivate )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_DEACTIVATE_SELECTED, _( "Deactivate selected" ) );
|
||||
|
||||
if( showSetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_SET_VISIBLE, _( "Set visible flag" ) );
|
||||
if( supportsVisibilityColumn() )
|
||||
{
|
||||
if( showSetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_SET_VISIBLE, _( "Set visible flag" ) );
|
||||
|
||||
if( showUnsetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_UNSET_VISIBLE, _( "Unset visible flag" ) );
|
||||
if( showUnsetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_UNSET_VISIBLE, _( "Unset visible flag" ) );
|
||||
}
|
||||
|
||||
bool showSettings = false;
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader,
|
||||
|
||||
wxDataViewColumn* col = new wxDataViewColumn(
|
||||
translatedHeader, new LIB_TREE_RENDERER(), index, m_colWidths[aHeader], wxALIGN_NOT,
|
||||
wxDATAVIEW_CELL_INERT | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE );
|
||||
wxDATAVIEW_CELL_INERT | static_cast<int>( wxDATAVIEW_COL_RESIZABLE ) );
|
||||
m_widget->AppendColumn( col );
|
||||
|
||||
col->SetMinWidth( headerMinWidth.x );
|
||||
|
||||
+1
-1
@@ -989,7 +989,7 @@ void PGM_BASE::HandleAssert( const wxString& aFile, int aLine, const wxString& a
|
||||
{
|
||||
static std::set<SENTRY_ASSERT_CACHE_KEY> assertCache;
|
||||
|
||||
SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond, aMsg };
|
||||
SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
|
||||
|
||||
if( assertCache.find( key ) == assertCache.end() )
|
||||
{
|
||||
|
||||
@@ -851,7 +851,7 @@ void SVG_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"textLength=\"%.*f\" font-size=\"%.*f\" lengthAdjust=\"spacingAndGlyphs\"\n"
|
||||
"text-anchor=\"%s\" opacity=\"0\">%s</text>\n",
|
||||
"text-anchor=\"%s\" opacity=\"0\" stroke-opacity=\"0\">%s</text>\n",
|
||||
m_precision, sz_dev.x, m_precision, sz_dev.y, hjust, TO_UTF8( XmlEsc( aText ) ) );
|
||||
|
||||
if( !aOrient.IsZero() )
|
||||
|
||||
@@ -591,7 +591,7 @@ wxString RemoveHTMLTags( const wxString& aInput )
|
||||
|
||||
wxString LinkifyHTML( wxString aStr )
|
||||
{
|
||||
wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.<>\\s\u00b6])" ),
|
||||
wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.,:;<>\\s\u00b6])" ),
|
||||
wxRE_ICASE );
|
||||
|
||||
regex.ReplaceAll( &aStr, "<a href=\"\\0\">\\0</a>" );
|
||||
@@ -907,11 +907,12 @@ bool ApplyModifier( double& value, const wxString& aString )
|
||||
}
|
||||
|
||||
if( units.length()
|
||||
&& !units.CmpNoCase( wxT( "F" ) )
|
||||
&& !units.CmpNoCase( wxT( "hz" ) )
|
||||
&& !units.CmpNoCase( wxT( "W" ) )
|
||||
&& !units.CmpNoCase( wxT( "V" ) )
|
||||
&& !units.CmpNoCase( wxT( "H" ) ) )
|
||||
&& !units.IsSameAs( wxT( "F" ), false )
|
||||
&& !units.IsSameAs( wxT( "hz" ), false )
|
||||
&& !units.IsSameAs( wxT( "W" ), false )
|
||||
&& !units.IsSameAs( wxT( "V" ), false )
|
||||
&& !units.IsSameAs( wxT( "A" ), false )
|
||||
&& !units.IsSameAs( wxT( "H" ), false ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ VECTOR2I SELECTION::GetCenter() const
|
||||
}
|
||||
|
||||
|
||||
BOX2I SELECTION::GetBoundingBox() const
|
||||
BOX2I SELECTION::GetBoundingBox( bool aOnlyVisible ) const
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
|
||||
+25
-25
@@ -399,35 +399,19 @@ void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
|
||||
}
|
||||
|
||||
|
||||
// stupid C++... python lambda would do this in one line
|
||||
template <class CONTAINER>
|
||||
struct QUERY_VISITOR
|
||||
{
|
||||
typedef typename CONTAINER::value_type item_type;
|
||||
|
||||
QUERY_VISITOR( CONTAINER& aCont, int aLayer ) :
|
||||
m_cont( aCont ), m_layer( aLayer )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( aItem->viewPrivData()->GetFlags() & VISIBLE )
|
||||
m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CONTAINER& m_cont;
|
||||
int m_layer;
|
||||
};
|
||||
|
||||
|
||||
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
|
||||
{
|
||||
if( m_orderedLayers.empty() )
|
||||
return 0;
|
||||
|
||||
int layer = UNDEFINED_LAYER;
|
||||
auto visitor =
|
||||
[&]( VIEW_ITEM* item ) -> bool
|
||||
{
|
||||
aResult.push_back( VIEW::LAYER_ITEM_PAIR( item, layer ) );
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector<VIEW_LAYER*>::const_reverse_iterator i;
|
||||
|
||||
// execute queries in reverse direction, so that items that are on the top of
|
||||
@@ -438,7 +422,7 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
|
||||
if( ( *i )->displayOnly || !( *i )->visible )
|
||||
continue;
|
||||
|
||||
QUERY_VISITOR<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
|
||||
layer = ( *i )->id;
|
||||
( *i )->items->Query( aRect, visitor );
|
||||
}
|
||||
|
||||
@@ -446,6 +430,22 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
|
||||
}
|
||||
|
||||
|
||||
void VIEW::Query( const BOX2I& aRect, const std::function<bool( VIEW_ITEM* )>& aFunc ) const
|
||||
{
|
||||
if( m_orderedLayers.empty() )
|
||||
return;
|
||||
|
||||
for( const auto& i : m_orderedLayers )
|
||||
{
|
||||
// ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
|
||||
if( i->displayOnly || !i->visible )
|
||||
continue;
|
||||
|
||||
i->items->Query( aRect, aFunc );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
|
||||
{
|
||||
const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 CERN
|
||||
* 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
|
||||
@@ -249,6 +249,7 @@ public:
|
||||
m_preselect( aPreselect ),
|
||||
m_symbolNetlist( aSymbolNetlist.ToStdString() )
|
||||
{
|
||||
m_buttonFpChooserLock = false;
|
||||
SetButtonBitmaps( KiBitmap( BITMAPS::small_library ) );
|
||||
|
||||
// win32 fix, avoids drawing the "native dropdown caret"
|
||||
@@ -263,17 +264,21 @@ protected:
|
||||
|
||||
void OnButtonClick() override
|
||||
{
|
||||
if( m_buttonFpChooserLock ) // The button to show the FP chooser is clicked, but
|
||||
// a previous click is currently in progress.
|
||||
return;
|
||||
|
||||
// Disable the button until we have finished processing it. Normally this is not an issue
|
||||
// but if the footprint chooser is loading for the first time, it can be slow enough that
|
||||
// multiple clicks will cause multiple instances of the footprint loader process to start
|
||||
m_buttonFpChooserLock = true;
|
||||
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = GetValue();
|
||||
|
||||
if( fpid.IsEmpty() )
|
||||
fpid = m_preselect;
|
||||
|
||||
// Disable the button until we have finished processing it. Normally this is not an issue
|
||||
// but if the footprint chooser is loading for the first time, it can be slow enough that
|
||||
// multiple clicks will cause multiple instances of the footprint loader process to start
|
||||
Disable();
|
||||
|
||||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
|
||||
{
|
||||
if( !m_symbolNetlist.empty() )
|
||||
@@ -288,13 +293,16 @@ protected:
|
||||
frame->Destroy();
|
||||
}
|
||||
|
||||
Enable();
|
||||
m_buttonFpChooserLock = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
DIALOG_SHIM* m_dlg;
|
||||
wxString m_preselect;
|
||||
|
||||
// Lock flag to lock the button to show the FP chooser
|
||||
// true when the button is busy, waiting all footprints loaded to
|
||||
// avoid running more than once the FP chooser
|
||||
bool m_buttonFpChooserLock;
|
||||
/*
|
||||
* Symbol netlist format:
|
||||
* pinNumber pinName <tab> pinNumber pinName...
|
||||
|
||||
@@ -518,8 +518,10 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||
ys.insert( w.y2p( py ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
else for( int sweep = 0; sweep < GetSweepCount(); ++sweep )
|
||||
{
|
||||
SetSweepWindow( sweep );
|
||||
|
||||
int count = 0;
|
||||
int x0 = 0; // X position of merged current vertical line
|
||||
int ymin0 = 0; // y min coord of merged current vertical line
|
||||
@@ -2456,18 +2458,20 @@ double mpScaleXLog::TransformFromPlot( double xplot ) const
|
||||
void mpFXYVector::Rewind()
|
||||
{
|
||||
m_index = 0;
|
||||
m_sweepWindow = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
|
||||
size_t mpFXYVector::GetCount() const
|
||||
void mpFXYVector::SetSweepWindow( int aSweepIdx )
|
||||
{
|
||||
return m_xs.size();
|
||||
m_index = aSweepIdx * m_sweepSize;
|
||||
m_sweepWindow = ( aSweepIdx + 1 ) * m_sweepSize;
|
||||
}
|
||||
|
||||
|
||||
bool mpFXYVector::GetNextXY( double& x, double& y )
|
||||
{
|
||||
if( m_index >= m_xs.size() )
|
||||
if( m_index >= m_xs.size() || m_index >= m_sweepWindow )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2475,7 +2479,7 @@ bool mpFXYVector::GetNextXY( double& x, double& y )
|
||||
{
|
||||
x = m_xs[m_index];
|
||||
y = m_ys[m_index++];
|
||||
return m_index <= m_xs.size();
|
||||
return m_index <= m_xs.size() && m_index <= m_sweepWindow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -720,6 +720,20 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
item->GetTypeDesc() );
|
||||
items.push_back( item );
|
||||
dirty_items.insert( item );
|
||||
|
||||
// Add any symbol dirty pins to the dirty_items list
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
|
||||
{
|
||||
if( pin->IsConnectivityDirty() )
|
||||
{
|
||||
dirty_items.insert( pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the symbol isn't dirty, look at the pins
|
||||
// TODO: remove symbols from connectivity graph and only use pins
|
||||
@@ -736,6 +750,19 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
|
||||
|
||||
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
|
||||
{
|
||||
if( pin->IsConnectivityDirty() )
|
||||
{
|
||||
items.push_back( pin );
|
||||
dirty_items.insert( pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the hierarchy info stored in the SCH_SCREEN (such as symbol units) reflects
|
||||
// the current SCH_SHEET_PATH
|
||||
@@ -890,6 +917,9 @@ std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffected
|
||||
|
||||
removeSubgraphs( subgraphs );
|
||||
|
||||
for( const auto& [path, item] : retvals )
|
||||
alg::delete_matching( m_items, item );
|
||||
|
||||
return retvals;
|
||||
}
|
||||
|
||||
@@ -2304,6 +2334,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
|
||||
std::shared_ptr<NET_SETTINGS>& netSettings = m_schematic->Prj().GetProjectFile().m_NetSettings;
|
||||
std::map<wxString, wxString> oldAssignments = netSettings->m_NetClassLabelAssignments;
|
||||
std::set<wxString> affectedNetclassNetAssignments;
|
||||
|
||||
netSettings->m_NetClassLabelAssignments.clear();
|
||||
|
||||
@@ -2345,9 +2376,6 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
}
|
||||
|
||||
if( netclass.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( !driverSubgraph )
|
||||
driverSubgraph = subgraphs.front();
|
||||
|
||||
@@ -2357,7 +2385,10 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
{
|
||||
for( const auto& member : driverSubgraph->m_driver_connection->Members() )
|
||||
{
|
||||
netSettings->m_NetClassLabelAssignments[ member->Name() ] = netclass;
|
||||
if( netclass.IsEmpty() )
|
||||
netSettings->m_NetClassLabelAssignments.erase( member->Name() );
|
||||
else
|
||||
netSettings->m_NetClassLabelAssignments[member->Name()] = netclass;
|
||||
|
||||
auto ii = m_net_name_to_subgraphs_map.find( member->Name() );
|
||||
|
||||
@@ -2366,10 +2397,24 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
}
|
||||
|
||||
netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
|
||||
if( netclass.IsEmpty() )
|
||||
netSettings->m_NetClassLabelAssignments.erase( netname );
|
||||
else
|
||||
netSettings->m_NetClassLabelAssignments[netname] = netclass;
|
||||
|
||||
if( oldAssignments[ netname ] != netclass )
|
||||
if( oldAssignments.count( netname ) )
|
||||
{
|
||||
if( oldAssignments[netname] != netclass )
|
||||
{
|
||||
affectedNetclassNetAssignments.insert( netname );
|
||||
dirtySubgraphs( subgraphs );
|
||||
}
|
||||
}
|
||||
else if( !netclass.IsEmpty() )
|
||||
{
|
||||
affectedNetclassNetAssignments.insert( netname );
|
||||
dirtySubgraphs( subgraphs );
|
||||
}
|
||||
};
|
||||
|
||||
for( const auto& [ netname, subgraphs ] : m_net_name_to_subgraphs_map )
|
||||
@@ -2379,8 +2424,11 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
{
|
||||
for( auto& [ netname, netclass ] : oldAssignments )
|
||||
{
|
||||
if( netSettings->m_NetClassLabelAssignments.count( netname ) )
|
||||
if( netSettings->m_NetClassLabelAssignments.count( netname )
|
||||
|| affectedNetclassNetAssignments.count( netname ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
|
||||
}
|
||||
@@ -2988,7 +3036,7 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindFirstSubgraphByName( const wxString&
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem )
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem ) const
|
||||
{
|
||||
auto it = m_item_to_subgraph_map.find( aItem );
|
||||
CONNECTION_SUBGRAPH* ret = it != m_item_to_subgraph_map.end() ? it->second : nullptr;
|
||||
|
||||
@@ -428,7 +428,7 @@ public:
|
||||
*/
|
||||
CONNECTION_SUBGRAPH* FindFirstSubgraphByName( const wxString& aNetName );
|
||||
|
||||
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
|
||||
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem ) const;
|
||||
|
||||
const std::vector<CONNECTION_SUBGRAPH*> GetAllSubgraphs( const wxString& aNetName ) const;
|
||||
|
||||
|
||||
@@ -907,7 +907,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
KIID uuid( payload );
|
||||
SCH_SHEET_PATH path;
|
||||
|
||||
if( SCH_ITEM* item = m_schematic->GetSheets().GetItem( uuid, &path ) )
|
||||
if( SCH_ITEM* item = m_schematic->GetItem( uuid, &path ) )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
payload = static_cast<SCH_SHEET*>( item )->GetShownName( false );
|
||||
|
||||
@@ -513,7 +513,7 @@ void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
|
||||
{
|
||||
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
|
||||
SCH_SHEET_PATH sheet;
|
||||
SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
|
||||
SCH_ITEM* item = m_parent->Schematic().GetItem( itemID, &sheet );
|
||||
|
||||
if( m_centerMarkerOnIdle )
|
||||
{
|
||||
|
||||
@@ -677,7 +677,7 @@ void DIALOG_SCH_FIELD_PROPERTIES::UpdateField( SCH_COMMIT* aCommit, SCH_FIELD* a
|
||||
int unit = symbol->GetUnit();
|
||||
LIB_ID libId = symbol->GetLibId();
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() )
|
||||
for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetUnorderedSheets() )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
std::vector<SCH_SYMBOL*> otherUnits;
|
||||
|
||||
@@ -50,7 +50,7 @@ DIALOG_SIM_FORMAT_VALUE::DIALOG_SIM_FORMAT_VALUE( wxWindow* aParent, SPICE_VALUE
|
||||
m_units = aFormat->Range.Right( 2 );
|
||||
SetTitle( wxString::Format( GetTitle(), _( "Frequency" ) ) );
|
||||
}
|
||||
else if( aFormat->Range.EndsWith( wxS( "dBV" ) ) )
|
||||
else if( aFormat->Range.EndsWith( wxS( "dB" ) ) )
|
||||
{
|
||||
m_units = aFormat->Range.Right( 3 );
|
||||
SetTitle( wxString::Format( GetTitle(), _( "Gain" ) ) );
|
||||
|
||||
@@ -792,7 +792,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
int unit = m_symbol->GetUnit();
|
||||
LIB_ID libId = m_symbol->GetLibId();
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
|
||||
for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetUnorderedSheets() )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
std::vector<SCH_SYMBOL*> otherUnits;
|
||||
|
||||
@@ -150,7 +150,7 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_ITE
|
||||
|
||||
m_separator5->SetIsSeparator();
|
||||
|
||||
SCH_SHEET_LIST sheetList = m_frame->Schematic().GetSheets();
|
||||
SCH_SHEET_LIST sheetList = m_frame->Schematic().GetUnorderedSheets();
|
||||
sheetList.SortByPageNumbers( false );
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : sheetList )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 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
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <../sim/simulator_frame.h>
|
||||
#include <dialog_user_defined_signals.h>
|
||||
#include <string_utils.h>
|
||||
#include <validators.h>
|
||||
|
||||
|
||||
DIALOG_USER_DEFINED_SIGNALS::DIALOG_USER_DEFINED_SIGNALS( SIMULATOR_FRAME* aParent,
|
||||
@@ -86,12 +87,19 @@ void DIALOG_USER_DEFINED_SIGNALS::addGridRow( const wxString& aText, int aId )
|
||||
m_grid->SetCellValue( row, 1, wxString::Format( wxS( "%d" ), aId ) );
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr;
|
||||
#if defined( __WXMSW__ )
|
||||
// For some obscure reason, a GRID_CELL_STC_EDITOR does not work on MSW:
|
||||
// It has a strange behavior when entering data, making it unusable.
|
||||
// (see https://gitlab.com/kicad/code/kicad/-/issues/15837)
|
||||
// So use a GRID_CELL_TEXT_EDITOR.
|
||||
attr->SetEditor( new GRID_CELL_TEXT_EDITOR() );
|
||||
#else
|
||||
attr->SetEditor( new GRID_CELL_STC_EDITOR( true,
|
||||
[this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
|
||||
{
|
||||
onScintillaCharAdded( aEvent, aScintillaTricks );
|
||||
} ) );
|
||||
|
||||
#endif
|
||||
m_grid->SetAttr( row, 0, attr );
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,11 @@ PANEL_EESCHEMA_COLOR_SETTINGS::~PANEL_EESCHEMA_COLOR_SETTINGS()
|
||||
delete m_currentSettings;
|
||||
|
||||
for( EDA_ITEM* item : m_previewItems )
|
||||
{
|
||||
// Avoid referencing items after they are deleted (we don't control order)
|
||||
item->SetParent( nullptr );
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -226,6 +226,11 @@ protected:
|
||||
m_grid->AutoSizeColumns( false );
|
||||
}
|
||||
}
|
||||
|
||||
bool supportsVisibilityColumn() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
+65
-76
@@ -131,12 +131,9 @@ const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
|
||||
|
||||
int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
|
||||
{
|
||||
SCH_SCREEN* screen;
|
||||
int err_count = 0;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screenList( m_schematic->Root() );
|
||||
|
||||
for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_SHEET*> list;
|
||||
|
||||
@@ -197,7 +194,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock() );
|
||||
}
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
|
||||
@@ -300,13 +297,11 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
|
||||
int ERC_TESTER::TestConflictingBusAliases()
|
||||
{
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
const auto& screen_aliases = screen->GetBusAliases();
|
||||
|
||||
@@ -347,13 +342,9 @@ int ERC_TESTER::TestConflictingBusAliases()
|
||||
|
||||
int ERC_TESTER::TestMultiunitFootprints()
|
||||
{
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
|
||||
int errors = 0;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitSymbols( refMap, true );
|
||||
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
|
||||
{
|
||||
SCH_REFERENCE_LIST& refList = symbol.second;
|
||||
|
||||
@@ -412,14 +403,9 @@ int ERC_TESTER::TestMultiunitFootprints()
|
||||
|
||||
int ERC_TESTER::TestMissingUnits()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
|
||||
int errors = 0;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitSymbols( refMap, true );
|
||||
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
|
||||
{
|
||||
SCH_REFERENCE_LIST& refList = symbol.second;
|
||||
|
||||
@@ -437,38 +423,38 @@ int ERC_TESTER::TestMissingUnits()
|
||||
std::set<int> instance_units;
|
||||
std::set<int> missing_units;
|
||||
|
||||
auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg,
|
||||
int aErrorCode )
|
||||
{
|
||||
wxString msg;
|
||||
wxString missing_pin_units = wxS( "[ " );
|
||||
int ii = 0;
|
||||
|
||||
for( int missing_unit : aMissingUnits )
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
auto report_missing =
|
||||
[&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
|
||||
{
|
||||
missing_pin_units += wxS( "....." );
|
||||
break;
|
||||
}
|
||||
wxString msg;
|
||||
wxString missing_pin_units = wxS( "[ " );
|
||||
int ii = 0;
|
||||
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
}
|
||||
for( int missing_unit : aMissingUnits )
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
{
|
||||
missing_pin_units += wxS( "....." );
|
||||
break;
|
||||
}
|
||||
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
missing_pin_units += wxS( " ]" );
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
}
|
||||
|
||||
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
missing_pin_units += wxS( " ]" );
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( unit );
|
||||
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
|
||||
base_ref.GetSheetPath().LastScreen()->Append( marker );
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( unit );
|
||||
|
||||
++errors;
|
||||
};
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
|
||||
base_ref.GetSheetPath().LastScreen()->Append( marker );
|
||||
|
||||
++errors;
|
||||
};
|
||||
|
||||
for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
|
||||
lib_units.insert( lib_units.end(), ii );
|
||||
@@ -480,7 +466,7 @@ int ERC_TESTER::TestMissingUnits()
|
||||
instance_units.begin(), instance_units.end(),
|
||||
std::inserter( missing_units, missing_units.begin() ) );
|
||||
|
||||
if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
|
||||
if( !missing_units.empty() && m_settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
|
||||
{
|
||||
report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
|
||||
ERCE_MISSING_UNIT );
|
||||
@@ -528,21 +514,21 @@ int ERC_TESTER::TestMissingUnits()
|
||||
}
|
||||
}
|
||||
|
||||
if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
|
||||
if( !missing_power.empty() && m_settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_power,
|
||||
_( "Symbol %s has input power pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_POWER_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
|
||||
if( !missing_input.empty() && m_settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_input,
|
||||
_( "Symbol %s has input pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
if( !missing_bidi.empty() && m_settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
{
|
||||
report_missing( missing_bidi,
|
||||
_( "Symbol %s has bidirectional pins in units %s that are not "
|
||||
@@ -576,7 +562,7 @@ int ERC_TESTER::TestMissingNetclasses()
|
||||
sheet.LastScreen()->Append( marker );
|
||||
};
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||
{
|
||||
@@ -612,7 +598,7 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
{
|
||||
int err_count = 0;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
|
||||
|
||||
@@ -679,12 +665,9 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
|
||||
int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
std::vector<ERC_SCH_PIN_CONTEXT> pins;
|
||||
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
|
||||
@@ -705,6 +688,21 @@ int ERC_TESTER::TestPinToPin()
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( pins.begin(), pins.end(),
|
||||
[]( const ERC_SCH_PIN_CONTEXT& lhs, const ERC_SCH_PIN_CONTEXT& rhs )
|
||||
{
|
||||
int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
|
||||
rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
|
||||
|
||||
if( ret == 0 )
|
||||
ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
|
||||
|
||||
if( ret == 0 )
|
||||
ret = lhs < rhs; // Fallback to hash to guarantee deterministic sort
|
||||
|
||||
return ret < 0;
|
||||
} );
|
||||
|
||||
ERC_SCH_PIN_CONTEXT needsDriver;
|
||||
bool hasDriver = false;
|
||||
|
||||
@@ -765,9 +763,9 @@ int ERC_TESTER::TestPinToPin()
|
||||
else
|
||||
hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
|
||||
|
||||
PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
|
||||
PIN_ERROR erc = m_settings.GetPinMapValue( refType, testType );
|
||||
|
||||
if( erc != PIN_ERROR::OK && settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
|
||||
if( erc != PIN_ERROR::OK && m_settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
|
||||
@@ -793,7 +791,7 @@ int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
|
||||
|
||||
if( settings.IsTestEnabled( err_code ) )
|
||||
if( m_settings.IsTestEnabled( err_code ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
|
||||
|
||||
@@ -815,13 +813,11 @@ int ERC_TESTER::TestPinToPin()
|
||||
|
||||
int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
{
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
const wxString& netName = net.first.Name;
|
||||
|
||||
@@ -875,13 +871,11 @@ int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
|
||||
int ERC_TESTER::TestSimilarLabels()
|
||||
{
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unordered_map<wxString, std::pair<SCH_LABEL_BASE*, SCH_SHEET_PATH>> labelMap;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* subgraph : net.second )
|
||||
{
|
||||
@@ -942,9 +936,7 @@ int ERC_TESTER::TestLibSymbolIssues()
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
@@ -1027,11 +1019,9 @@ int ERC_TESTER::TestLibSymbolIssues()
|
||||
int ERC_TESTER::TestOffGridEndpoints()
|
||||
{
|
||||
const int gridSize = m_schematic->Settings().m_ConnectionGridSize;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
int err_count = 0;
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
@@ -1093,11 +1083,10 @@ int ERC_TESTER::TestSimModelIssues()
|
||||
{
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
int err_count = 0;
|
||||
SIM_LIB_MGR libMgr( &m_schematic->Prj() );
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : sheets )
|
||||
for( SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
|
||||
+14
-4
@@ -27,9 +27,10 @@
|
||||
#define ERC_H
|
||||
|
||||
#include <erc_settings.h>
|
||||
#include <sch_screen.h>
|
||||
#include <connection_graph.h>
|
||||
|
||||
|
||||
class SCH_SHEET_LIST;
|
||||
class SCHEMATIC;
|
||||
class DS_PROXY_VIEW_ITEM;
|
||||
class SCH_EDIT_FRAME;
|
||||
@@ -47,8 +48,13 @@ class ERC_TESTER
|
||||
public:
|
||||
|
||||
ERC_TESTER( SCHEMATIC* aSchematic ) :
|
||||
m_schematic( aSchematic )
|
||||
m_schematic( aSchematic ),
|
||||
m_settings( aSchematic->ErcSettings() ),
|
||||
m_sheetList( aSchematic->GetSheets() ),
|
||||
m_screens( aSchematic->Root() ),
|
||||
m_nets( aSchematic->ConnectionGraph()->GetNetMap() )
|
||||
{
|
||||
m_sheetList.GetMultiUnitSymbols( m_refMap, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,8 +145,12 @@ public:
|
||||
KIFACE* aCvPcb, PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter );
|
||||
|
||||
private:
|
||||
|
||||
SCHEMATIC* m_schematic;
|
||||
SCHEMATIC* m_schematic;
|
||||
ERC_SETTINGS& m_settings;
|
||||
SCH_SHEET_LIST m_sheetList;
|
||||
SCH_SCREENS m_screens;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP m_refMap;
|
||||
const NET_MAP& m_nets;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
#include <erc_sch_pin_context.h>
|
||||
|
||||
|
||||
SCH_PIN* ERC_SCH_PIN_CONTEXT::Pin()
|
||||
SCH_PIN* ERC_SCH_PIN_CONTEXT::Pin() const
|
||||
{
|
||||
return m_pin;
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET_PATH& ERC_SCH_PIN_CONTEXT::Sheet()
|
||||
const SCH_SHEET_PATH& ERC_SCH_PIN_CONTEXT::Sheet() const
|
||||
{
|
||||
return m_sheet;
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ public:
|
||||
/**
|
||||
* Get the SCH_PIN for this context.
|
||||
*/
|
||||
SCH_PIN* Pin();
|
||||
SCH_PIN* Pin() const;
|
||||
|
||||
/**
|
||||
* Get the #SCH_SHEET_PATH context for the paired #SCH_PIN.
|
||||
*/
|
||||
SCH_SHEET_PATH& Sheet();
|
||||
const SCH_SHEET_PATH& Sheet() const;
|
||||
|
||||
/**
|
||||
* Test two pin contexts for equality based on the deterministic hash.
|
||||
|
||||
@@ -53,11 +53,10 @@ void FIELDS_EDITOR_GRID_DATA_MODEL::AddColumn( const wxString& aFieldName, const
|
||||
void FIELDS_EDITOR_GRID_DATA_MODEL::updateDataStoreSymbolField( const SCH_SYMBOL& aSymbol,
|
||||
const wxString& aFieldName )
|
||||
{
|
||||
if( const SCH_FIELD* field = aSymbol.GetFieldByName( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = field->GetText();
|
||||
else if( isAttribute( aFieldName ) )
|
||||
if( isAttribute( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = getAttributeValue( aSymbol, aFieldName );
|
||||
|
||||
else if( const SCH_FIELD* field = aSymbol.GetFieldByName( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = field->GetText();
|
||||
// Handle fields with variables as names that are not present in the symbol
|
||||
// by giving them the correct value
|
||||
else if( IsTextVar( aFieldName ) )
|
||||
|
||||
@@ -146,6 +146,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
// unload current project file before loading new
|
||||
{
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
SetScreen( nullptr );
|
||||
m_toolManager->GetTool<EE_INSPECTION_TOOL>()->Reset( TOOL_BASE::SUPERMODEL_RELOAD );
|
||||
CreateScreens();
|
||||
@@ -180,7 +181,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
CreateScreens();
|
||||
}
|
||||
|
||||
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
|
||||
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName, KICTL_KICAD_ONLY );
|
||||
|
||||
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
||||
{
|
||||
@@ -230,7 +231,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
|
||||
if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
|
||||
{
|
||||
msg.Printf( _( "Unsupported schematic file '%s'." ), fullFileName );
|
||||
msg.Printf( _( "'%s' is not a KiCad schematic file.\nUse File -> Import for "
|
||||
"non-KiCad schematic files." ),
|
||||
fullFileName );
|
||||
|
||||
progressReporter.Hide();
|
||||
DisplayErrorMessage( this, msg );
|
||||
}
|
||||
@@ -742,6 +746,7 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
// Don't leave dangling pointers to previously-opened document.
|
||||
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
if( setProject )
|
||||
{
|
||||
@@ -1075,7 +1080,7 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs )
|
||||
// File doesn't exist yet; true if we just imported something
|
||||
updateFileHistory = true;
|
||||
}
|
||||
else if( !Schematic().GetSheets().IsModified() )
|
||||
else if( !IsContentModified() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1462,6 +1467,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
}
|
||||
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
initScreenZoom();
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
@@ -669,6 +669,7 @@ std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
|
||||
retv->SetExcludedFromBoard( parent->GetExcludedFromBoard() );
|
||||
|
||||
retv->UpdateFieldOrdinals();
|
||||
retv->m_parent.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -171,7 +171,8 @@ static wxString GetNetNavigatorItemText( const SCH_ITEM* aItem,
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection )
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection,
|
||||
bool aSingleSheetSchematic )
|
||||
{
|
||||
wxCHECK( !aNetName.IsEmpty(), /* void */ );
|
||||
wxCHECK( m_schematic, /* void */ );
|
||||
@@ -206,7 +207,7 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
|
||||
m_netNavigator->SelectItem( sheetId );
|
||||
|
||||
// If there is only one sheet in the schematic, always expand the sheet tree.
|
||||
if( Schematic().GetSheets().size() == 1 )
|
||||
if( aSingleSheetSchematic )
|
||||
expandId = sheetId;
|
||||
|
||||
for( const SCH_ITEM* item : subGraph->GetItems() )
|
||||
@@ -243,6 +244,8 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
if( m_netNavigator->IsEmpty() && m_highlightedConn.IsEmpty() )
|
||||
return;
|
||||
|
||||
bool singleSheetSchematic = m_schematic->GetUnorderedSheets().size() == 1;
|
||||
|
||||
if( !m_netNavigator->IsEmpty() && m_highlightedConn.IsEmpty() )
|
||||
{
|
||||
m_netNavigator->DeleteAllItems();
|
||||
@@ -259,7 +262,7 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection, singleSheetSchematic );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -273,14 +276,14 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
m_netNavigator->DeleteAllItems();
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, itemData );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, itemData, singleSheetSchematic );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection, singleSheetSchematic );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
||||
if( symbol->GetLibSymbolRef()
|
||||
&& symbol->GetLibSymbolRef()->GetFPFilters().GetCount() != 0 )
|
||||
{
|
||||
cmpList.push_back( SCH_REFERENCE( symbol, symbol->GetLibSymbolRef().get(),
|
||||
sheet ) );
|
||||
cmpList.push_back( SCH_REFERENCE( symbol, sheet ) );
|
||||
}
|
||||
|
||||
footprint = symbol->GetFootprintFieldText( true, &sheet, false );
|
||||
|
||||
+12
-10
@@ -404,6 +404,11 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
|
||||
if( m_schematic )
|
||||
m_schematic->RemoveAllListeners();
|
||||
|
||||
// Delete all items not in draw list before deleting schematic
|
||||
// to avoid dangling pointers stored in these items
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
delete m_schematic;
|
||||
m_schematic = nullptr;
|
||||
|
||||
@@ -774,7 +779,7 @@ void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* aItem )
|
||||
|
||||
EDA_ITEM* SCH_EDIT_FRAME::GetItem( const KIID& aId ) const
|
||||
{
|
||||
return Schematic().GetSheets().GetItem( aId );
|
||||
return Schematic().GetItem( aId );
|
||||
}
|
||||
|
||||
|
||||
@@ -894,7 +899,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
|
||||
// Shutdown blocks must be determined and vetoed as early as possible
|
||||
if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
|
||||
&& Schematic().GetSheets().IsModified() )
|
||||
&& IsContentModified() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -942,9 +947,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
if( !Schematic().IsValid() )
|
||||
return false;
|
||||
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
|
||||
|
||||
if( sheetlist.IsModified() )
|
||||
if( IsContentModified() )
|
||||
{
|
||||
wxFileName fileName = Schematic().RootScreen()->GetFileName();
|
||||
wxString msg = _( "Save changes to '%s' before closing?" );
|
||||
@@ -965,7 +968,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
|
||||
void SCH_EDIT_FRAME::doCloseWindow()
|
||||
{
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetUnorderedSheets();
|
||||
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
@@ -1057,7 +1060,7 @@ void SCH_EDIT_FRAME::doCloseWindow()
|
||||
// Make sure local settings are persisted
|
||||
SaveProjectLocalSettings();
|
||||
|
||||
Schematic().RootScreen()->Clear();
|
||||
Schematic().RootScreen()->Clear( true );
|
||||
|
||||
// all sub sheets are deleted, only the main sheet is usable
|
||||
GetCurrentSheet().clear();
|
||||
@@ -2037,7 +2040,7 @@ const BOX2I SCH_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
|
||||
|
||||
bool SCH_EDIT_FRAME::IsContentModified() const
|
||||
{
|
||||
return Schematic().GetSheets().IsModified();
|
||||
return Schematic().GetUnorderedSheets().IsModified();
|
||||
}
|
||||
|
||||
|
||||
@@ -2052,9 +2055,8 @@ void SCH_EDIT_FRAME::FocusOnItem( SCH_ITEM* aItem )
|
||||
{
|
||||
static KIID lastBrightenedItemID( niluuid );
|
||||
|
||||
SCH_SHEET_LIST sheetList = Schematic().GetSheets();
|
||||
SCH_SHEET_PATH dummy;
|
||||
SCH_ITEM* lastItem = sheetList.GetItem( lastBrightenedItemID, &dummy );
|
||||
SCH_ITEM* lastItem = Schematic().GetItem( lastBrightenedItemID, &dummy );
|
||||
|
||||
if( lastItem && lastItem != aItem )
|
||||
{
|
||||
|
||||
@@ -710,6 +710,15 @@ public:
|
||||
return m_items_to_repeat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of items which are to be repeated with the insert key.
|
||||
* These objects are owned by this container.
|
||||
*/
|
||||
void ClearRepeatItemsList()
|
||||
{
|
||||
m_items_to_repeat.clear();
|
||||
}
|
||||
|
||||
EDA_ITEM* GetItem( const KIID& aId ) const override;
|
||||
|
||||
/**
|
||||
@@ -866,7 +875,8 @@ public:
|
||||
void RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
|
||||
void MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection,
|
||||
bool aSingleSheetSchematic );
|
||||
|
||||
void SelectNetNavigatorItem( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
|
||||
|
||||
+36
-5
@@ -195,15 +195,30 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
return symbol->ResolveTextVar( aPath, token, aDepth + 1 );
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> schematicResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( SCHEMATIC* schematic = Schematic() )
|
||||
return schematic->ResolveTextVar( aPath, token, aDepth + 1 );
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> sheetResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
|
||||
|
||||
SCHEMATIC* schematic = Schematic();
|
||||
SCH_SHEET_PATH path = *aPath;
|
||||
path.push_back( sheet );
|
||||
|
||||
return sheet->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
bool retval = sheet->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
|
||||
if( schematic )
|
||||
retval |= schematic->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> labelResolver =
|
||||
@@ -222,7 +237,8 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
{
|
||||
text = wxS( "" );
|
||||
}
|
||||
else if( HasTextVars() )
|
||||
|
||||
for( int ii = 0; ii < 10 && text.Contains( wxT( "${" ) ); ++ii )
|
||||
{
|
||||
if( aDepth < 10 )
|
||||
{
|
||||
@@ -233,7 +249,10 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
|
||||
text = ExpandTextVars( text, &labelResolver );
|
||||
else if( Schematic() )
|
||||
{
|
||||
text = ExpandTextVars( text, &Schematic()->Prj() );
|
||||
text = ExpandTextVars( text, &schematicResolver );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,11 +759,10 @@ void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks,
|
||||
}
|
||||
else
|
||||
{
|
||||
SCH_SHEET_LIST sheets = schematic->GetSheets();
|
||||
SCH_REFERENCE_LIST refs;
|
||||
SCH_SYMBOL* refSymbol = nullptr;
|
||||
|
||||
sheets.GetSymbols( refs );
|
||||
schematic->GetUnorderedSheets().GetSymbols( refs );
|
||||
|
||||
for( size_t jj = 0; jj < refs.GetCount(); jj++ )
|
||||
{
|
||||
@@ -998,7 +1016,11 @@ void SCH_FIELD::SetText( const wxString& aText )
|
||||
if( m_isNamedVariable )
|
||||
return;
|
||||
|
||||
EDA_TEXT::SetText( aText );
|
||||
// Mandatory fields should not have leading or trailing whitespace.
|
||||
if( IsMandatory() )
|
||||
EDA_TEXT::SetText( aText.Strip( wxString::both ) );
|
||||
else
|
||||
EDA_TEXT::SetText( aText );
|
||||
}
|
||||
|
||||
|
||||
@@ -1291,6 +1313,15 @@ VECTOR2I SCH_FIELD::GetParentPosition() const
|
||||
}
|
||||
|
||||
|
||||
bool SCH_FIELD::IsMandatory() const
|
||||
{
|
||||
if( m_parent && m_parent->Type() == SCH_SHEET_T )
|
||||
return m_id >= 0 && m_id < SHEET_MANDATORY_FIELDS;
|
||||
else
|
||||
return m_id >= 0 && m_id < MANDATORY_FIELDS;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_FIELD::operator <( const SCH_ITEM& aItem ) const
|
||||
{
|
||||
if( Type() != aItem.Type() )
|
||||
|
||||
@@ -209,6 +209,8 @@ public:
|
||||
*/
|
||||
void ImportValues( const LIB_FIELD& aSource );
|
||||
|
||||
bool IsMandatory() const;
|
||||
|
||||
int GetPenWidth() const override;
|
||||
|
||||
void ClearCaches() override;
|
||||
|
||||
@@ -460,7 +460,8 @@ ASCH_ROUND_RECTANGLE::ASCH_ROUND_RECTANGLE( const std::map<wxString, wxString>&
|
||||
|
||||
ASCH_ARC::ASCH_ARC( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_OWNER_INTERFACE( aProps ),
|
||||
ASCH_BORDER_INTERFACE( aProps )
|
||||
ASCH_BORDER_INTERFACE( aProps ),
|
||||
ASCH_FILL_INTERFACE( aProps )
|
||||
{
|
||||
m_IsElliptical = ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ELLIPTICAL_ARC;
|
||||
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ARC || m_IsElliptical );
|
||||
@@ -478,6 +479,11 @@ ASCH_ARC::ASCH_ARC( const std::map<wxString, wxString>& aProps ) :
|
||||
}
|
||||
|
||||
|
||||
ASCH_PIECHART::ASCH_PIECHART( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_ARC( aProps )
|
||||
{}
|
||||
|
||||
|
||||
ASCH_ELLIPSE::ASCH_ELLIPSE( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_OWNER_INTERFACE( aProps ),
|
||||
ASCH_FILL_INTERFACE( aProps ),
|
||||
|
||||
@@ -482,7 +482,7 @@ struct ASCH_ROUND_RECTANGLE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BO
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE, ASCH_FILL_INTERFACE
|
||||
{
|
||||
bool m_IsElliptical;
|
||||
VECTOR2I m_Center;
|
||||
@@ -495,6 +495,12 @@ struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_PIECHART : ASCH_ARC
|
||||
{
|
||||
explicit ASCH_PIECHART( const std::map<wxString, wxString>& aProps );
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_ELLIPSE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
{
|
||||
VECTOR2I Center;
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
#include <bezier_curves.h>
|
||||
#include <compoundfilereader.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <geometry/ellipse.h>
|
||||
#include <string_utils.h>
|
||||
#include <sch_edit_frame.h>
|
||||
@@ -325,6 +326,9 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
|
||||
fileName.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
m_schematic = aSchematic;
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
// Delete on exception, if I own m_rootSheet, according to aAppendToMe
|
||||
std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
|
||||
|
||||
@@ -892,9 +896,9 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
|
||||
ParseEllipse( properties );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::PIECHART:
|
||||
m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::PIECHART:
|
||||
ParsePieChart( properties );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
|
||||
ParseRoundRectangle( properties );
|
||||
@@ -2152,7 +2156,9 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
|
||||
circle->SetPosition( elem.m_Center + m_sheetOffset );
|
||||
circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
|
||||
circle->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
SetSchShapeLine( elem, circle );
|
||||
SetSchShapeFillAndColor( elem, circle );
|
||||
|
||||
currentScreen->Append( circle );
|
||||
}
|
||||
@@ -2168,7 +2174,8 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
arc->SetStart( elem.m_Center + startOffset + m_sheetOffset );
|
||||
arc->SetArcAngleAndEnd( includedAngle.Normalize(), true );
|
||||
|
||||
arc->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
SetSchShapeLine( elem, arc );
|
||||
SetSchShapeFillAndColor( elem, arc );
|
||||
|
||||
currentScreen->Append( arc );
|
||||
}
|
||||
@@ -2214,6 +2221,7 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
|
||||
circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
|
||||
SetLibShapeLine( elem, circle, ALTIUM_SCH_RECORD::ARC );
|
||||
SetLibShapeFillAndColor( elem, circle, ALTIUM_SCH_RECORD::ARC, elem.Color );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2241,6 +2249,7 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
arc->SetArcAngleAndEnd( includedAngle.Normalize(), true );
|
||||
|
||||
SetLibShapeLine( elem, arc, ALTIUM_SCH_RECORD::ARC );
|
||||
SetLibShapeFillAndColor( elem, arc, ALTIUM_SCH_RECORD::ARC, elem.Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2341,6 +2350,92 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::ParsePieChart( const std::map<wxString, wxString>& aProperties,
|
||||
std::vector<LIB_SYMBOL*>& aSymbol )
|
||||
{
|
||||
ParseArc( aProperties, aSymbol );
|
||||
|
||||
ASCH_PIECHART elem( aProperties );
|
||||
|
||||
int arc_radius = elem.m_Radius;
|
||||
VECTOR2I center = elem.m_Center;
|
||||
EDA_ANGLE startAngle( elem.m_EndAngle, DEGREES_T );
|
||||
EDA_ANGLE endAngle( elem.m_StartAngle, DEGREES_T );
|
||||
VECTOR2I startOffset( KiROUND( arc_radius * startAngle.Cos() ),
|
||||
-KiROUND( arc_radius * startAngle.Sin() ) );
|
||||
VECTOR2I endOffset( KiROUND( arc_radius * endAngle.Cos() ),
|
||||
-KiROUND( arc_radius * endAngle.Sin() ) );
|
||||
|
||||
if( aSymbol.empty() && ShouldPutItemOnSheet( elem.ownerindex ) )
|
||||
{
|
||||
SCH_SCREEN* screen = getCurrentScreen();
|
||||
wxCHECK( screen, /* void */ );
|
||||
|
||||
// close polygon
|
||||
SCH_LINE* line = new SCH_LINE( center + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
|
||||
line->SetEndPoint( center + startOffset + m_sheetOffset );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
line->SetFlags( IS_NEW );
|
||||
screen->Append( line );
|
||||
|
||||
line = new SCH_LINE( center + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
|
||||
line->SetEndPoint( center + endOffset + m_sheetOffset );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
line->SetFlags( IS_NEW );
|
||||
screen->Append( line );
|
||||
}
|
||||
else
|
||||
{
|
||||
LIB_SYMBOL* symbol = (int) aSymbol.size() <= elem.ownerpartdisplaymode
|
||||
? nullptr
|
||||
: aSymbol[elem.ownerpartdisplaymode];
|
||||
SCH_SYMBOL* schsym = nullptr;
|
||||
|
||||
if( !symbol )
|
||||
{
|
||||
const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
|
||||
|
||||
if( libSymbolIt == m_libSymbols.end() )
|
||||
{
|
||||
// TODO: e.g. can depend on Template (RECORD=39
|
||||
m_reporter->Report( wxString::Format( wxT( "Piechart's owner (%d) not found." ),
|
||||
elem.ownerindex ),
|
||||
RPT_SEVERITY_DEBUG );
|
||||
return;
|
||||
}
|
||||
|
||||
symbol = libSymbolIt->second;
|
||||
schsym = m_symbols.at( libSymbolIt->first );
|
||||
}
|
||||
|
||||
if( aSymbol.empty() && !IsComponentPartVisible( elem ) )
|
||||
return;
|
||||
|
||||
LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY );
|
||||
symbol->AddDrawItem( line, false );
|
||||
|
||||
line->SetUnit( std::max( 0, elem.ownerpartid ) );
|
||||
|
||||
if( !schsym )
|
||||
{
|
||||
line->AddPoint( center + startOffset );
|
||||
line->AddPoint( center );
|
||||
line->AddPoint( center + endOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
line->AddPoint( GetRelativePosition( center + startOffset + m_sheetOffset, schsym ) );
|
||||
line->AddPoint( GetRelativePosition( center + m_sheetOffset, schsym ) );
|
||||
line->AddPoint( GetRelativePosition( center + endOffset + m_sheetOffset, schsym ) );
|
||||
}
|
||||
|
||||
SetLibShapeLine( elem, line, ALTIUM_SCH_RECORD::LINE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::ParseEllipse( const std::map<wxString, wxString>& aProperties,
|
||||
std::vector<LIB_SYMBOL*>& aSymbol )
|
||||
{
|
||||
@@ -3193,8 +3288,8 @@ 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() ) )
|
||||
else if( LIB_SYMBOL* alreadyLoaded = m_pi->LoadSymbol( getLibFileName().GetFullPath(), symName,
|
||||
m_properties.get() ) )
|
||||
{
|
||||
libSymbol = alreadyLoaded;
|
||||
}
|
||||
@@ -4210,6 +4305,8 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
|
||||
|
||||
case ALTIUM_SCH_RECORD::ELLIPSE: ParseEllipse( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::PIECHART: ParsePieChart( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: ParseRoundRectangle( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: ParseEllipticalArc( properties, symbols ); break;
|
||||
@@ -4292,6 +4389,9 @@ long long SCH_IO_ALTIUM::getLibraryTimestamp( const wxString& aLibraryPath ) con
|
||||
void SCH_IO_ALTIUM::ensureLoadedLibrary( const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( m_libCache.count( aLibraryPath ) )
|
||||
{
|
||||
wxCHECK( m_timestamps.count( aLibraryPath ), /*void*/ );
|
||||
|
||||
@@ -152,6 +152,7 @@ private:
|
||||
void ParseHarnessType( const std::map<wxString, wxString>& aProperties );
|
||||
void ParseHarnessPort( const ASCH_PORT& aElem );
|
||||
void ParseHyperlink( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParsePieChart( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParseRectangle( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParseSheetSymbol( int aIndex, const std::map<wxString, wxString>& aProperties );
|
||||
void ParseSheetEntry( const std::map<wxString, wxString>& aProperties );
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sch_io/cadstar/sch_io_cadstar_archive.h>
|
||||
#include <io/cadstar/cadstar_parts_lib_parser.h>
|
||||
|
||||
#include <font/fontconfig.h>
|
||||
#include <lib_symbol.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <project_sch.h>
|
||||
@@ -68,6 +69,9 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
|
||||
@@ -251,6 +255,9 @@ void SCH_IO_CADSTAR_ARCHIVE::ensureLoadedLibrary( const wxString& aLibraryPath,
|
||||
wxFileName csafn;
|
||||
wxString fplibname = "cadstarpcblib";
|
||||
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( aProperties && aProperties->count( "csa" ) )
|
||||
{
|
||||
csafn = wxFileName( aProperties->at( "csa" ) );
|
||||
|
||||
@@ -39,19 +39,21 @@
|
||||
#include <symbol_library.h>
|
||||
#include <io/eagle/eagle_parser.h>
|
||||
#include <string_utils.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <gr_text.h>
|
||||
#include <lib_shape.h>
|
||||
#include <lib_id.h>
|
||||
#include <lib_pin.h>
|
||||
#include <lib_text.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <project.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <project_sch.h>
|
||||
#include <sch_bus_entry.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_io/kicad_legacy/sch_io_kicad_legacy.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_label.h>
|
||||
#include <sch_marker.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_shape.h>
|
||||
@@ -59,9 +61,9 @@
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_label.h>
|
||||
#include <schematic.h>
|
||||
#include <string_utils.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <progress_reporter.h>
|
||||
|
||||
|
||||
// Eagle schematic axes are aligned with x increasing left to right and Y increasing bottom to top
|
||||
@@ -408,6 +410,9 @@ SCH_SHEET* SCH_IO_EAGLE::LoadSchematicFile( const wxString& aFileName, SCHEMATIC
|
||||
wxASSERT( !aFileName || aSchematic != nullptr );
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
m_filename = aFileName;
|
||||
m_schematic = aSchematic;
|
||||
|
||||
@@ -582,6 +587,9 @@ long long SCH_IO_EAGLE::getLibraryTimestamp( const wxString& aLibraryPath ) cons
|
||||
|
||||
void SCH_IO_EAGLE::ensureLoadedLibrary( const wxString& aLibraryPath )
|
||||
{
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( m_eagleLibs.find( m_libName ) != m_eagleLibs.end() )
|
||||
{
|
||||
wxCHECK( m_timestamps.count( m_libName ), /*void*/ );
|
||||
@@ -973,7 +981,7 @@ void SCH_IO_EAGLE::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
||||
ReplaceIllegalFileNameChars( &filename );
|
||||
replace( filename.begin(), filename.end(), ' ', '_' );
|
||||
|
||||
wxFileName fn( m_filename );
|
||||
wxFileName fn( m_schematic->Prj().GetProjectPath() );
|
||||
fn.SetName( filename );
|
||||
fn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
|
||||
@@ -1842,7 +1850,7 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
|
||||
|
||||
valueField->SetVisible( part->GetFieldById( VALUE_FIELD )->IsVisible() );
|
||||
|
||||
if( !userValue && epart->value )
|
||||
if( epart->value )
|
||||
{
|
||||
valueField->SetText( *epart->value );
|
||||
}
|
||||
@@ -1954,11 +1962,8 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
|
||||
// Use the instance attribute to determine the reference and value field visibility.
|
||||
if( einstance.smashed && einstance.smashed.Get() )
|
||||
{
|
||||
if( !valueAttributeFound )
|
||||
symbol->GetField( VALUE_FIELD )->SetVisible( false );
|
||||
|
||||
if( !nameAttributeFound )
|
||||
symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
|
||||
symbol->GetField( VALUE_FIELD )->SetVisible( valueAttributeFound );
|
||||
symbol->GetField( REFERENCE_FIELD )->SetVisible( nameAttributeFound );
|
||||
}
|
||||
|
||||
symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
#include "sch_easyeda_parser.h"
|
||||
#include "sch_io_easyeda.h"
|
||||
|
||||
#include <schematic.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_screen.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <kiplatform/environment.h>
|
||||
#include <project_sch.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <schematic.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdstream.h>
|
||||
#include <wx/zipstrm.h>
|
||||
@@ -309,6 +309,9 @@ void SCH_IO_EASYEDA::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
{
|
||||
std::map<wxString, int> namesCounter;
|
||||
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
try
|
||||
{
|
||||
wxFFileInputStream in( aLibraryPath );
|
||||
@@ -612,6 +615,9 @@ SCH_SHEET* SCH_IO_EASYEDA::LoadSchematicFile( const wxString& aFileName, SCHEMAT
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
if( aAppendToMe )
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "sch_easyedapro_parser.h"
|
||||
#include "sch_io_easyedapro.h"
|
||||
|
||||
#include <font/fontconfig.h>
|
||||
#include <schematic.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_screen.h>
|
||||
@@ -423,6 +424,9 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName,
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
if( aAppendToMe )
|
||||
|
||||
@@ -28,15 +28,25 @@
|
||||
#include <wx/base64.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <base_units.h>
|
||||
#include <build_version.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <ee_selection.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <io/kicad/kicad_io_utils.h>
|
||||
#include <locale_io.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <schematic.h>
|
||||
#include <schematic_lexer.h>
|
||||
#include <sch_bitmap.h>
|
||||
#include <sch_bus_entry.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <sch_edit_frame.h> // SYMBOL_ORIENTATION_T
|
||||
#include <sch_io/kicad_sexpr/sch_io_kicad_sexpr.h>
|
||||
#include <sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.h>
|
||||
#include <sch_io/kicad_sexpr/sch_io_kicad_sexpr_lib_cache.h>
|
||||
#include <sch_io/kicad_sexpr/sch_io_kicad_sexpr_parser.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_line.h>
|
||||
#include <sch_shape.h>
|
||||
@@ -62,9 +72,9 @@
|
||||
#include <symbol_lib_table.h> // for PropPowerSymsOnly definition.
|
||||
#include <ee_selection.h>
|
||||
#include <string_utils.h>
|
||||
#include <symbol_lib_table.h> // for PropPowerSymsOnly definition.
|
||||
#include <trace_helpers.h>
|
||||
#include <wx_filename.h> // for ::ResolvePossibleSymlinks()
|
||||
#include <progress_reporter.h>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
using namespace TSCHEMATIC_T;
|
||||
|
||||
@@ -109,6 +119,9 @@ SCH_SHEET* SCH_IO_KICAD_SEXPR::LoadSchematicFile( const wxString& aFileName, SCH
|
||||
|
||||
wxFileName fn = aFileName;
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
// Unfortunately child sheet file names the legacy schematic file format are not fully
|
||||
// qualified and are always appended to the project path. The aFileName attribute must
|
||||
// always be an absolute path so the project path can be used for load child sheet files.
|
||||
@@ -1416,6 +1429,9 @@ void SCH_IO_KICAD_SEXPR::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& a
|
||||
void SCH_IO_KICAD_SEXPR::cacheLib( const wxString& aLibraryFileName,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( !m_cache || !m_cache->IsFile( aLibraryFileName ) || m_cache->IsFileChanged() )
|
||||
{
|
||||
// a spectacular episode in memory management:
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <sch_draw_panel.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <schematic.h>
|
||||
#include <connection_graph.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <general.h>
|
||||
#include <netclass.h>
|
||||
@@ -88,6 +89,16 @@ SCH_ITEM::~SCH_ITEM()
|
||||
|
||||
for( const auto& it : m_connection_map )
|
||||
delete it.second;
|
||||
|
||||
// Do not try to modify SCHEMATIC::ConnectionGraph()
|
||||
// if the schematic does not exist
|
||||
if( !SCHEMATIC::m_IsSchematicExists )
|
||||
return;
|
||||
|
||||
SCHEMATIC* sch = Schematic();
|
||||
|
||||
if( sch != nullptr )
|
||||
sch->ConnectionGraph()->RemoveItem( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+19
-1
@@ -1223,7 +1223,25 @@ bool SCH_LABEL_BASE::HasConnectivityChanges( const SCH_ITEM* aItem,
|
||||
if( GetPosition() != label->GetPosition() )
|
||||
return true;
|
||||
|
||||
return GetShownText( aInstance ) != label->GetShownText( aInstance );
|
||||
if( GetShownText( aInstance ) != label->GetShownText( aInstance ) )
|
||||
return true;
|
||||
|
||||
std::vector<wxString> netclasses;
|
||||
std::vector<wxString> otherNetclasses;
|
||||
|
||||
for( const SCH_FIELD& field : m_fields )
|
||||
{
|
||||
if( field.GetCanonicalName() == wxT( "Netclass" ) )
|
||||
netclasses.push_back( field.GetText() );
|
||||
}
|
||||
|
||||
for( const SCH_FIELD& field : label->m_fields )
|
||||
{
|
||||
if( field.GetCanonicalName() == wxT( "Netclass" ) )
|
||||
otherNetclasses.push_back( field.GetText() );
|
||||
}
|
||||
|
||||
return netclasses != otherNetclasses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ wxString SCH_MARKER::Serialize() const
|
||||
}
|
||||
|
||||
|
||||
SCH_MARKER* SCH_MARKER::Deserialize( SCHEMATIC* schematic, const wxString& data )
|
||||
SCH_MARKER* SCH_MARKER::Deserialize( const SCH_SHEET_LIST& aSheetList, const wxString& data )
|
||||
{
|
||||
wxArrayString props = wxSplit( data, '|' );
|
||||
VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
|
||||
@@ -131,13 +131,11 @@ SCH_MARKER* SCH_MARKER::Deserialize( SCHEMATIC* schematic, const wxString& data
|
||||
{
|
||||
isLegacyMarker = false;
|
||||
|
||||
SCH_SHEET_LIST sheetPaths = schematic->GetSheets();
|
||||
|
||||
if( !props[5].IsEmpty() )
|
||||
{
|
||||
KIID_PATH sheetSpecificKiidPath( props[5] );
|
||||
std::optional<SCH_SHEET_PATH> sheetSpecificPath =
|
||||
sheetPaths.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
|
||||
aSheetList.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
|
||||
if( sheetSpecificPath.has_value() )
|
||||
ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
|
||||
}
|
||||
@@ -146,7 +144,7 @@ SCH_MARKER* SCH_MARKER::Deserialize( SCHEMATIC* schematic, const wxString& data
|
||||
{
|
||||
KIID_PATH mainItemKiidPath( props[6] );
|
||||
std::optional<SCH_SHEET_PATH> mainItemPath =
|
||||
sheetPaths.GetSheetPathByKIIDPath( mainItemKiidPath, true );
|
||||
aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
|
||||
if( mainItemPath.has_value() )
|
||||
{
|
||||
if( props[7].IsEmpty() )
|
||||
@@ -157,7 +155,7 @@ SCH_MARKER* SCH_MARKER::Deserialize( SCHEMATIC* schematic, const wxString& data
|
||||
{
|
||||
KIID_PATH auxItemKiidPath( props[7] );
|
||||
std::optional<SCH_SHEET_PATH> auxItemPath =
|
||||
sheetPaths.GetSheetPathByKIIDPath( auxItemKiidPath, true );
|
||||
aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
|
||||
|
||||
if( auxItemPath.has_value() )
|
||||
ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
void SwapData( SCH_ITEM* aItem ) override;
|
||||
|
||||
wxString Serialize() const;
|
||||
static SCH_MARKER* Deserialize( SCHEMATIC* schematic, const wxString& data );
|
||||
static SCH_MARKER* Deserialize( const SCH_SHEET_LIST& aSheetList, const wxString& data );
|
||||
|
||||
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
|
||||
@@ -286,11 +286,16 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
|
||||
|
||||
bool SCH_PIN::IsStacked( const SCH_PIN* aPin ) const
|
||||
{
|
||||
bool isConnectableType_a = GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE
|
||||
|| GetType() == ELECTRICAL_PINTYPE::PT_NIC;
|
||||
bool isConnectableType_b = aPin->GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE
|
||||
|| aPin->GetType() == ELECTRICAL_PINTYPE::PT_NIC;
|
||||
|
||||
return m_parent == aPin->GetParent()
|
||||
&& GetTransformedPosition() == aPin->GetTransformedPosition()
|
||||
&& GetName() == aPin->GetName()
|
||||
&& ( ( GetType() == aPin->GetType() ) || ( GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE )
|
||||
|| ( aPin->GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE ) );
|
||||
&& ( ( GetType() == aPin->GetType() )
|
||||
|| isConnectableType_a || isConnectableType_b );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -795,14 +795,11 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
|
||||
}
|
||||
|
||||
|
||||
SCH_REFERENCE::SCH_REFERENCE( SCH_SYMBOL* aSymbol, LIB_SYMBOL* aLibSymbol,
|
||||
const SCH_SHEET_PATH& aSheetPath )
|
||||
SCH_REFERENCE::SCH_REFERENCE( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH& aSheetPath )
|
||||
{
|
||||
wxASSERT( aSymbol != nullptr );
|
||||
|
||||
m_rootSymbol = aSymbol;
|
||||
m_libPart = aLibSymbol; // Warning: can be nullptr for orphan symbols
|
||||
// (i.e. with a symbol library not found)
|
||||
m_unit = aSymbol->GetUnitSelection( &aSheetPath );
|
||||
m_footprint = aSymbol->GetFootprintFieldText( true, &aSheetPath, false );
|
||||
m_sheetPath = aSheetPath;
|
||||
|
||||
@@ -80,7 +80,6 @@ public:
|
||||
m_sheetPath()
|
||||
{
|
||||
m_rootSymbol = nullptr;
|
||||
m_libPart = nullptr;
|
||||
m_unit = 0;
|
||||
m_isNew = false;
|
||||
m_numRef = 0;
|
||||
@@ -88,11 +87,11 @@ public:
|
||||
m_sheetNum = 0;
|
||||
}
|
||||
|
||||
SCH_REFERENCE( SCH_SYMBOL* aSymbol, LIB_SYMBOL* aLibSymbol, const SCH_SHEET_PATH& aSheetPath );
|
||||
SCH_REFERENCE( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH& aSheetPath );
|
||||
|
||||
SCH_SYMBOL* GetSymbol() const { return m_rootSymbol; }
|
||||
|
||||
LIB_SYMBOL* GetLibPart() const { return m_libPart; }
|
||||
LIB_SYMBOL* GetLibPart() const { return m_rootSymbol->GetLibSymbolRef().get(); }
|
||||
|
||||
const SCH_SHEET_PATH& GetSheetPath() const { return m_sheetPath; }
|
||||
|
||||
@@ -226,8 +225,8 @@ public:
|
||||
|
||||
bool IsUnitsLocked()
|
||||
{
|
||||
if( m_libPart )
|
||||
return m_libPart->UnitsLocked();
|
||||
if( GetLibPart() )
|
||||
return GetLibPart()->UnitsLocked();
|
||||
else
|
||||
return true; // Assume units locked when we don't have a library
|
||||
}
|
||||
@@ -238,7 +237,6 @@ private:
|
||||
/// Symbol reference prefix, without number (for IC1, this is IC) )
|
||||
wxString m_ref; // it's private, use the accessors please
|
||||
SCH_SYMBOL* m_rootSymbol; ///< The symbol associated the reference object.
|
||||
LIB_SYMBOL* m_libPart; ///< The source symbol from a library.
|
||||
VECTOR2I m_symbolPos; ///< The physical position of the symbol in schematic
|
||||
///< used to annotate by X or Y position
|
||||
int m_unit; ///< The unit number for symbol with multiple parts
|
||||
|
||||
+9
-22
@@ -283,8 +283,7 @@ bool SCH_SHEET::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, in
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "##" ) ) )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList = schematic->GetSheets();
|
||||
*token = wxString::Format( wxT( "%d" ), (int) sheetList.size() );
|
||||
*token = wxString::Format( wxT( "%d" ), (int) schematic->GetUnorderedSheets().size() );
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
|
||||
@@ -1307,25 +1306,22 @@ void SCH_SHEET::AddInstance( const SCH_SHEET_INSTANCE& aInstance )
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::addInstance( const SCH_SHEET_PATH& aSheetPath )
|
||||
bool SCH_SHEET::addInstance( const KIID_PATH& aPath )
|
||||
{
|
||||
wxCHECK( aSheetPath.IsFullPath(), false );
|
||||
wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), false );
|
||||
|
||||
for( const SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
// if aSheetPath is found, nothing to do:
|
||||
if( instance.m_Path == aSheetPath.Path() )
|
||||
if( instance.m_Path == aPath )
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceSchSheetPaths, wxT( "Adding instance `%s` to sheet `%s`." ),
|
||||
aSheetPath.Path().AsString(),
|
||||
aPath.AsString(),
|
||||
( GetName().IsEmpty() ) ? wxString( wxT( "root" ) ) : GetName() );
|
||||
|
||||
SCH_SHEET_INSTANCE instance;
|
||||
|
||||
instance.m_Path = aSheetPath.Path();
|
||||
instance.m_Path = aPath;
|
||||
|
||||
// This entry does not exist: add it with an empty page number.
|
||||
m_instances.emplace_back( instance );
|
||||
@@ -1385,17 +1381,13 @@ const SCH_SHEET_INSTANCE& SCH_SHEET::GetRootInstance() const
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_SHEET::getPageNumber( const SCH_SHEET_PATH& aSheetPath ) const
|
||||
wxString SCH_SHEET::getPageNumber( const KIID_PATH& aPath ) const
|
||||
{
|
||||
wxCHECK( aSheetPath.IsFullPath(), wxEmptyString );
|
||||
wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), wxEmptyString );
|
||||
|
||||
wxString pageNumber;
|
||||
KIID_PATH path = aSheetPath.Path();
|
||||
|
||||
for( const SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
if( instance.m_Path == path )
|
||||
if( instance.m_Path == aPath )
|
||||
{
|
||||
pageNumber = instance.m_PageNumber;
|
||||
break;
|
||||
@@ -1406,16 +1398,11 @@ wxString SCH_SHEET::getPageNumber( const SCH_SHEET_PATH& aSheetPath ) const
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET::setPageNumber( const SCH_SHEET_PATH& aSheetPath, const wxString& aPageNumber )
|
||||
void SCH_SHEET::setPageNumber( const KIID_PATH& aPath, const wxString& aPageNumber )
|
||||
{
|
||||
wxCHECK( aSheetPath.IsFullPath(), /* void */ );
|
||||
wxCHECK( !aSheetPath.Last() || ( aSheetPath.Last()->m_Uuid != m_Uuid ), /* void */ );
|
||||
|
||||
KIID_PATH path = aSheetPath.Path();
|
||||
|
||||
for( SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
if( instance.m_Path == path )
|
||||
if( instance.m_Path == aPath )
|
||||
{
|
||||
instance.m_PageNumber = aPageNumber;
|
||||
break;
|
||||
|
||||
+9
-15
@@ -449,40 +449,34 @@ protected:
|
||||
* in the list, do nothing. Sheet instances allow for the sharing in complex hierarchies
|
||||
* which allows for per instance data such as page number for sheets to stored.
|
||||
*
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return false
|
||||
* on release builds.
|
||||
* @warning The #KIID_PATH object must be a full hierarchical path which means the sheet
|
||||
* at index 0 must be the root sheet.
|
||||
*
|
||||
* @param[in] aInstance is the #SCH_SHEET_PATH of the sheet instance to the instance list.
|
||||
* @return false if the instance already exists, true if the instance was added.
|
||||
*/
|
||||
bool addInstance( const SCH_SHEET_PATH& aInstance );
|
||||
bool addInstance( const KIID_PATH& aInstance );
|
||||
|
||||
/**
|
||||
* Return the sheet page number for \a aInstance.
|
||||
*
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return an empty
|
||||
* page number on release builds.
|
||||
* @warning The #KIID_PATH object must be a full hierarchical path which means the sheet
|
||||
* at index 0 must be the root sheet.
|
||||
*
|
||||
* @return the page number for the requested sheet instance.
|
||||
*/
|
||||
wxString getPageNumber( const SCH_SHEET_PATH& aInstance ) const;
|
||||
wxString getPageNumber( const KIID_PATH& aInstance ) const;
|
||||
|
||||
/**
|
||||
* Set the page number for the sheet instance \a aInstance.
|
||||
*
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return on release
|
||||
* builds.
|
||||
* @warning The #KIID_PATH object must be a full hierarchical path which means the sheet
|
||||
* at index 0 must be the root sheet.
|
||||
*
|
||||
* @param[in] aInstance is the hierarchical path of the sheet.
|
||||
* @param[in] aReference is the new page number for the sheet.
|
||||
*/
|
||||
void setPageNumber( const SCH_SHEET_PATH& aInstance, const wxString& aPageNumber );
|
||||
void setPageNumber( const KIID_PATH& aInstance, const wxString& aPageNumber );
|
||||
|
||||
bool getInstance( SCH_SHEET_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
|
||||
bool aTestFromEnd = false ) const;
|
||||
|
||||
+28
-21
@@ -149,9 +149,10 @@ SCH_SHEET_PATH SCH_SHEET_PATH::operator+( const SCH_SHEET_PATH& aOther )
|
||||
|
||||
void SCH_SHEET_PATH::initFromOther( const SCH_SHEET_PATH& aOther )
|
||||
{
|
||||
m_sheets = aOther.m_sheets;
|
||||
m_virtualPageNumber = aOther.m_virtualPageNumber;
|
||||
m_current_hash = aOther.m_current_hash;
|
||||
m_sheets = aOther.m_sheets;
|
||||
m_virtualPageNumber = aOther.m_virtualPageNumber;
|
||||
m_current_hash = aOther.m_current_hash;
|
||||
m_cached_page_number = aOther.m_cached_page_number;
|
||||
|
||||
// Note: don't copy m_recursion_test_cache as it is slow and we want SCH_SHEET_PATHS to be
|
||||
// very fast to construct for use in the connectivity algorithm.
|
||||
@@ -290,6 +291,7 @@ wxString SCH_SHEET_PATH::PathAsString() const
|
||||
KIID_PATH SCH_SHEET_PATH::Path() const
|
||||
{
|
||||
KIID_PATH path;
|
||||
path.reserve( m_sheets.size() );
|
||||
|
||||
for( const SCH_SHEET* sheet : m_sheets )
|
||||
path.push_back( sheet->m_Uuid );
|
||||
@@ -397,11 +399,9 @@ void SCH_SHEET_PATH::AppendSymbol( SCH_REFERENCE_LIST& aReferences, SCH_SYMBOL*
|
||||
// affects power symbols.
|
||||
if( aIncludePowerSymbols || aSymbol->GetRef( this )[0] != wxT( '#' ) )
|
||||
{
|
||||
LIB_SYMBOL* symbol = aSymbol->GetLibSymbolRef().get();
|
||||
|
||||
if( symbol || aForceIncludeOrphanSymbols )
|
||||
if( aSymbol->GetLibSymbolRef() || aForceIncludeOrphanSymbols )
|
||||
{
|
||||
SCH_REFERENCE schReference( aSymbol, symbol, *this );
|
||||
SCH_REFERENCE schReference( aSymbol, *this );
|
||||
|
||||
schReference.SetSheetNumber( m_virtualPageNumber );
|
||||
aReferences.AddItem( schReference );
|
||||
@@ -434,7 +434,7 @@ void SCH_SHEET_PATH::AppendMultiUnitSymbol( SCH_MULTI_UNIT_REFERENCE_MAP& aRefLi
|
||||
|
||||
if( symbol && symbol->GetUnitCount() > 1 )
|
||||
{
|
||||
SCH_REFERENCE schReference = SCH_REFERENCE( aSymbol, symbol, *this );
|
||||
SCH_REFERENCE schReference = SCH_REFERENCE( aSymbol, *this );
|
||||
schReference.SetSheetNumber( m_virtualPageNumber );
|
||||
wxString reference_str = schReference.GetRef();
|
||||
|
||||
@@ -539,8 +539,7 @@ wxString SCH_SHEET_PATH::GetPageNumber() const
|
||||
|
||||
wxCHECK( sheet, wxEmptyString );
|
||||
|
||||
SCH_SHEET_PATH tmpPath = *this;
|
||||
|
||||
KIID_PATH tmpPath = Path();
|
||||
tmpPath.pop_back();
|
||||
|
||||
return sheet->getPageNumber( tmpPath );
|
||||
@@ -553,7 +552,7 @@ void SCH_SHEET_PATH::SetPageNumber( const wxString& aPageNumber )
|
||||
|
||||
wxCHECK( sheet, /* void */ );
|
||||
|
||||
SCH_SHEET_PATH tmpPath = *this;
|
||||
KIID_PATH tmpPath = Path();
|
||||
|
||||
tmpPath.pop_back();
|
||||
|
||||
@@ -741,17 +740,27 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity )
|
||||
|
||||
void SCH_SHEET_LIST::SortByPageNumbers( bool aUpdateVirtualPageNums )
|
||||
{
|
||||
for( const SCH_SHEET_PATH& path : *this )
|
||||
path.CachePageNumber();
|
||||
|
||||
std::sort( begin(), end(),
|
||||
[]( SCH_SHEET_PATH a, SCH_SHEET_PATH b ) -> bool
|
||||
[]( const SCH_SHEET_PATH& a, const SCH_SHEET_PATH& b ) -> bool
|
||||
{
|
||||
int retval = a.ComparePageNum( b );
|
||||
int retval = SCH_SHEET::ComparePageNum( a.GetCachedPageNumber(),
|
||||
b.GetCachedPageNumber() );
|
||||
|
||||
if( retval < 0 )
|
||||
return true;
|
||||
else if( retval > 0 )
|
||||
return false;
|
||||
else /// Enforce strict ordering. If the page numbers are the same, use UUIDs
|
||||
return a.GetCurrentHash() < b.GetCurrentHash();
|
||||
|
||||
if( a.GetVirtualPageNumber() < b.GetVirtualPageNumber() )
|
||||
return true;
|
||||
else if( a.GetVirtualPageNumber() > b.GetVirtualPageNumber() )
|
||||
return false;
|
||||
|
||||
/// Enforce strict ordering. If the page numbers are the same, use UUIDs
|
||||
return a.GetCurrentHash() < b.GetCurrentHash();
|
||||
} );
|
||||
|
||||
if( aUpdateVirtualPageNums )
|
||||
@@ -759,9 +768,7 @@ void SCH_SHEET_LIST::SortByPageNumbers( bool aUpdateVirtualPageNums )
|
||||
int virtualPageNum = 1;
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : *this )
|
||||
{
|
||||
sheet.SetVirtualPageNumber( virtualPageNum++ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,7 +916,7 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols()
|
||||
|
||||
if( libSymbol && libSymbol->IsPower() )
|
||||
{
|
||||
SCH_REFERENCE schReference( symbol, libSymbol, sheet );
|
||||
SCH_REFERENCE schReference( symbol, sheet );
|
||||
references.AddItem( schReference );
|
||||
}
|
||||
}
|
||||
@@ -1286,7 +1293,7 @@ void SCH_SHEET_LIST::AddNewSheetInstances( const SCH_SHEET_PATH& aPrefixSheetPat
|
||||
|
||||
for( SCH_SHEET_PATH& sheetPath : *this )
|
||||
{
|
||||
SCH_SHEET_PATH tmp( sheetPath );
|
||||
KIID_PATH tmp = sheetPath.Path();
|
||||
SCH_SHEET_PATH newSheetPath( aPrefixSheetPath );
|
||||
|
||||
// Prefix the new hierarchical path.
|
||||
@@ -1304,10 +1311,10 @@ void SCH_SHEET_LIST::AddNewSheetInstances( const SCH_SHEET_PATH& aPrefixSheetPat
|
||||
SCH_SHEET_INSTANCE instance;
|
||||
|
||||
// Add the instance if it doesn't already exist
|
||||
if( !sheet->getInstance( instance, tmp.Path(), true ) )
|
||||
if( !sheet->getInstance( instance, tmp, true ) )
|
||||
{
|
||||
sheet->addInstance( tmp );
|
||||
sheet->getInstance( instance, tmp.Path(), true );
|
||||
sheet->getInstance( instance, tmp, true );
|
||||
}
|
||||
|
||||
// Get a new page number if we don't have one
|
||||
|
||||
@@ -233,6 +233,9 @@ public:
|
||||
*/
|
||||
int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const;
|
||||
|
||||
void CachePageNumber() const { m_cached_page_number = GetPageNumber(); }
|
||||
wxString GetCachedPageNumber() const { return m_cached_page_number; }
|
||||
|
||||
/**
|
||||
* Compare sheets by their page number. If the actual page number is equal, use virtual page
|
||||
* numbers to compare.
|
||||
@@ -415,9 +418,10 @@ private:
|
||||
void initFromOther( const SCH_SHEET_PATH& aOther );
|
||||
|
||||
protected:
|
||||
std::vector< SCH_SHEET* > m_sheets;
|
||||
std::vector<SCH_SHEET*> m_sheets;
|
||||
|
||||
size_t m_current_hash;
|
||||
size_t m_current_hash;
|
||||
mutable wxString m_cached_page_number;
|
||||
|
||||
int m_virtualPageNumber; /// Page numbers are maintained by the sheet load order.
|
||||
|
||||
|
||||
+20
-18
@@ -37,6 +37,8 @@
|
||||
#include <sim/spice_value.h>
|
||||
#include <netlist_exporter_spice.h>
|
||||
|
||||
bool SCHEMATIC::m_IsSchematicExists = false;
|
||||
|
||||
SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
|
||||
EDA_ITEM( nullptr, SCHEMATIC_T ),
|
||||
m_project( nullptr ),
|
||||
@@ -44,6 +46,7 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
|
||||
{
|
||||
m_currentSheet = new SCH_SHEET_PATH();
|
||||
m_connectionGraph = new CONNECTION_GRAPH( this );
|
||||
m_IsSchematicExists = true;
|
||||
|
||||
SetProject( aPrj );
|
||||
|
||||
@@ -72,7 +75,7 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
|
||||
int unit = symbol->GetUnit();
|
||||
LIB_ID libId = symbol->GetLibId();
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
for( SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
{
|
||||
std::vector<SCH_SYMBOL*> otherUnits;
|
||||
|
||||
@@ -124,6 +127,8 @@ SCHEMATIC::~SCHEMATIC()
|
||||
|
||||
delete m_currentSheet;
|
||||
delete m_connectionGraph;
|
||||
|
||||
m_IsSchematicExists = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -314,7 +319,7 @@ std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
|
||||
|
||||
for( auto it = settings.m_ErcExclusions.begin(); it != settings.m_ErcExclusions.end(); )
|
||||
{
|
||||
SCH_MARKER* testMarker = SCH_MARKER::Deserialize( this, *it );
|
||||
SCH_MARKER* testMarker = SCH_MARKER::Deserialize( sheetList, *it );
|
||||
|
||||
if( testMarker->IsLegacyMarker() )
|
||||
{
|
||||
@@ -361,7 +366,7 @@ std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
|
||||
|
||||
for( const wxString& serialized : settings.m_ErcExclusions )
|
||||
{
|
||||
SCH_MARKER* marker = SCH_MARKER::Deserialize( this, serialized );
|
||||
SCH_MARKER* marker = SCH_MARKER::Deserialize( sheetList, serialized );
|
||||
|
||||
if( marker )
|
||||
{
|
||||
@@ -378,7 +383,7 @@ std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
|
||||
|
||||
std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
|
||||
{
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
{
|
||||
for( const std::shared_ptr<BUS_ALIAS>& alias : sheet.LastScreen()->GetBusAliases() )
|
||||
{
|
||||
@@ -412,11 +417,10 @@ std::set<wxString> SCHEMATIC::GetNetClassAssignmentCandidates()
|
||||
|
||||
bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
|
||||
{
|
||||
SCH_SHEET_LIST sheetList = GetSheets();
|
||||
wxString remainder;
|
||||
wxString ref = token->BeforeFirst( ':', &remainder );
|
||||
SCH_SHEET_PATH sheetPath;
|
||||
SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &sheetPath );
|
||||
SCH_ITEM* refItem = GetItem( KIID( ref ), &sheetPath );
|
||||
|
||||
if( refItem && refItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
@@ -449,7 +453,7 @@ std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetNamesMap() const
|
||||
{
|
||||
std::map<int, wxString> namesMap;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
{
|
||||
if( sheet.size() == 1 )
|
||||
namesMap[sheet.GetVirtualPageNumber()] = _( "<root sheet>" );
|
||||
@@ -465,7 +469,7 @@ std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetPagesMap() const
|
||||
{
|
||||
std::map<int, wxString> pagesMap;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
|
||||
|
||||
return pagesMap;
|
||||
@@ -509,12 +513,11 @@ wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList = GetSheets();
|
||||
wxString remainder;
|
||||
wxString ref = token.BeforeFirst( ':', &remainder );
|
||||
SCH_REFERENCE_LIST references;
|
||||
|
||||
sheetList.GetSymbols( references );
|
||||
GetUnorderedSheets().GetSymbols( references );
|
||||
|
||||
for( size_t jj = 0; jj < references.GetCount(); jj++ )
|
||||
{
|
||||
@@ -565,12 +568,11 @@ wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
|
||||
|
||||
if( isCrossRef )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList = GetSheets();
|
||||
wxString remainder;
|
||||
wxString ref = token.BeforeFirst( ':', &remainder );
|
||||
wxString remainder;
|
||||
wxString ref = token.BeforeFirst( ':', &remainder );
|
||||
|
||||
SCH_SHEET_PATH refSheetPath;
|
||||
SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &refSheetPath );
|
||||
SCH_ITEM* refItem = GetItem( KIID( ref ), &refSheetPath );
|
||||
|
||||
if( refItem && refItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
@@ -739,10 +741,10 @@ wxString SCHEMATIC::GetOperatingPoint( const wxString& aNetName, int aPrecision,
|
||||
|
||||
void SCHEMATIC::FixupJunctions()
|
||||
{
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
SCH_SCREENS screens( Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
std::deque<EDA_ITEM*> allItems;
|
||||
|
||||
for( auto item : screen->Items() )
|
||||
@@ -836,7 +838,7 @@ void SCHEMATIC::RecordERCExclusions()
|
||||
|
||||
void SCHEMATIC::ResolveERCExclusionsPostUpdate()
|
||||
{
|
||||
SCH_SHEET_LIST sheetList = GetSheets();
|
||||
SCH_SHEET_LIST sheetList = GetUnorderedSheets();
|
||||
|
||||
for( SCH_MARKER* marker : ResolveERCExclusions() )
|
||||
{
|
||||
|
||||
@@ -102,6 +102,18 @@ public:
|
||||
return SCH_SHEET_LIST( m_rootSheet );
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST GetUnorderedSheets() const
|
||||
{
|
||||
SCH_SHEET_LIST sheets;
|
||||
sheets.BuildSheetList( m_rootSheet, false );
|
||||
return sheets;
|
||||
}
|
||||
|
||||
SCH_ITEM* GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut = nullptr ) const
|
||||
{
|
||||
return GetUnorderedSheets().GetItem( aID, aPathOut );
|
||||
}
|
||||
|
||||
SCH_SHEET& Root() const
|
||||
{
|
||||
return *m_rootSheet;
|
||||
@@ -298,6 +310,11 @@ public:
|
||||
*/
|
||||
void RemoveAllListeners();
|
||||
|
||||
/**
|
||||
* True if a SCHEMATIC exists, false if not
|
||||
*/
|
||||
static bool m_IsSchematicExists;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override {}
|
||||
#endif
|
||||
|
||||
@@ -546,7 +546,7 @@ void SIM_PLOT_TAB::updateAxes( int aNewTraceType )
|
||||
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
|
||||
m_plotWin->AddLayer( m_axis_x );
|
||||
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dBV" ), mpALIGN_LEFT );
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT );
|
||||
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
|
||||
m_plotWin->AddLayer( m_axis_y1 );
|
||||
|
||||
@@ -818,11 +818,18 @@ void SIM_PLOT_TAB::OnLanguageChanged()
|
||||
void SIM_PLOT_TAB::UpdateTraceStyle( TRACE* trace )
|
||||
{
|
||||
int type = trace->GetType();
|
||||
wxPenStyle penStyle = ( ( ( type & SPT_AC_PHASE ) || ( type & SPT_CURRENT ) ) && m_dotted_cp )
|
||||
? wxPENSTYLE_DOT
|
||||
: wxPENSTYLE_SOLID;
|
||||
trace->SetPen( wxPen( trace->GetTraceColour(), 2, penStyle ) );
|
||||
wxPenStyle penStyle;
|
||||
|
||||
if( ( type & SPT_AC_GAIN ) > 0 )
|
||||
penStyle = wxPENSTYLE_SOLID;
|
||||
else if( ( type & SPT_AC_PHASE ) > 0 )
|
||||
penStyle = m_dotted_cp ? wxPENSTYLE_DOT : wxPENSTYLE_SOLID;
|
||||
else if( ( type & SPT_CURRENT ) > 0 )
|
||||
penStyle = m_dotted_cp ? wxPENSTYLE_DOT : wxPENSTYLE_SOLID;
|
||||
else
|
||||
penStyle = wxPENSTYLE_SOLID;
|
||||
|
||||
trace->SetPen( wxPen( trace->GetTraceColour(), 2, penStyle ) );
|
||||
m_sessionTraceColors[ trace->GetName() ] = trace->GetTraceColour();
|
||||
}
|
||||
|
||||
@@ -875,7 +882,8 @@ TRACE* SIM_PLOT_TAB::GetOrAddTrace( const wxString& aVectorName, int aType )
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vector<double>& aY )
|
||||
void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vector<double>& aY,
|
||||
int aSweepCount, size_t aSweepSize )
|
||||
{
|
||||
if( dynamic_cast<LOG_SCALE<mpScaleXLog>*>( m_axis_x ) )
|
||||
{
|
||||
@@ -906,6 +914,8 @@ void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vec
|
||||
}
|
||||
|
||||
trace->SetData( aX, aY );
|
||||
trace->SetSweepCount( aSweepCount );
|
||||
trace->SetSweepSize( aSweepSize );
|
||||
|
||||
if( ( trace->GetType() & SPT_AC_PHASE ) || ( trace->GetType() & SPT_CURRENT ) )
|
||||
trace->SetScale( m_axis_x, m_axis_y2 );
|
||||
|
||||
@@ -346,7 +346,8 @@ public:
|
||||
|
||||
TRACE* GetOrAddTrace( const wxString& aVectorName, int aType );
|
||||
|
||||
void SetTraceData( TRACE* aTrace, std::vector<double>& aX, std::vector<double>& aY );
|
||||
void SetTraceData( TRACE* aTrace, std::vector<double>& aX, std::vector<double>& aY,
|
||||
int aSweepCount, size_t aSweepSize );
|
||||
|
||||
bool DeleteTrace( const wxString& aVectorName, int aTraceType );
|
||||
void DeleteTrace( TRACE* aTrace );
|
||||
|
||||
@@ -340,6 +340,22 @@ void SIMULATOR_FRAME::UpdateTitle()
|
||||
}
|
||||
|
||||
|
||||
// Don't let the dialog grow too tall: you may not be able to get to the OK button
|
||||
#define MAX_MESSAGES 20
|
||||
|
||||
void SIMULATOR_FRAME::showNetlistErrors( const wxString& aErrors )
|
||||
{
|
||||
wxArrayString lines = wxSplit( aErrors, '\n' );
|
||||
|
||||
if( lines.size() > MAX_MESSAGES )
|
||||
{
|
||||
lines.RemoveAt( MAX_MESSAGES, lines.size() - MAX_MESSAGES );
|
||||
lines.Add( wxS( "..." ) );
|
||||
}
|
||||
|
||||
DisplayErrorMessage( this, _( "Errors during netlist generation." ), wxJoin( lines, '\n' ) );
|
||||
}
|
||||
|
||||
|
||||
bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
|
||||
{
|
||||
@@ -355,7 +371,7 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO
|
||||
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
|
||||
s_reporter ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + s_errors );
|
||||
showNetlistErrors( s_errors );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -365,10 +381,12 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO
|
||||
|
||||
void SIMULATOR_FRAME::ReloadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
|
||||
{
|
||||
s_errors.clear();
|
||||
|
||||
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
|
||||
s_reporter ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + s_errors );
|
||||
showNetlistErrors( s_errors );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,6 +541,7 @@ bool SIMULATOR_FRAME::LoadWorkbook( const wxString& aPath )
|
||||
return true;
|
||||
}
|
||||
|
||||
DisplayErrorMessage( this, wxString::Format( _( "Unable to load or parse file %s" ), aPath ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -560,8 +579,7 @@ bool SIMULATOR_FRAME::EditAnalysis()
|
||||
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS,
|
||||
s_reporter ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" )
|
||||
+ s_errors );
|
||||
showNetlistErrors( s_errors );
|
||||
}
|
||||
|
||||
dlg.SetSimCommand( simTab->GetSimCommand() );
|
||||
|
||||
@@ -194,6 +194,8 @@ private:
|
||||
|
||||
void setupUIConditions() override;
|
||||
|
||||
void showNetlistErrors( const wxString& aErrors );
|
||||
|
||||
bool canCloseWindow( wxCloseEvent& aEvent ) override;
|
||||
void doCloseWindow() override;
|
||||
|
||||
|
||||
@@ -1718,46 +1718,24 @@ void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceTyp
|
||||
wxFAIL_MSG( wxT( "Unhandled plot type" ) );
|
||||
}
|
||||
|
||||
// If we did a two-source DC analysis, we need to split the resulting vector and add traces
|
||||
// for each input step
|
||||
SPICE_DC_PARAMS source1, source2;
|
||||
int sweepCount = 1;
|
||||
size_t sweepSize = std::numeric_limits<size_t>::max();
|
||||
|
||||
if( simType == ST_DC
|
||||
&& circuitModel()->ParseDCCommand( aPlotTab->GetSimCommand(), &source1, &source2 )
|
||||
&& !source2.m_source.IsEmpty() )
|
||||
{
|
||||
// Source 1 is the inner loop, so lets add traces for each Source 2 (outer loop) step
|
||||
SPICE_VALUE v = source2.m_vstart;
|
||||
SPICE_VALUE v = ( source2.m_vend - source2.m_vstart ) / source2.m_vincrement;
|
||||
|
||||
size_t offset = 0;
|
||||
size_t outer = ( size_t )( ( source2.m_vend - v ) / source2.m_vincrement ).ToDouble();
|
||||
size_t inner = aDataX->size() / ( outer + 1 );
|
||||
|
||||
wxASSERT( aDataX->size() % ( outer + 1 ) == 0 );
|
||||
|
||||
for( size_t idx = 0; idx <= outer; idx++ )
|
||||
{
|
||||
if( TRACE* trace = aPlotTab->GetOrAddTrace( aVectorName, aTraceType ) )
|
||||
{
|
||||
if( data_y.size() >= size )
|
||||
{
|
||||
std::vector<double> sub_x( aDataX->begin() + offset,
|
||||
aDataX->begin() + offset + inner );
|
||||
std::vector<double> sub_y( data_y.begin() + offset,
|
||||
data_y.begin() + offset + inner );
|
||||
|
||||
aPlotTab->SetTraceData( trace, sub_x, sub_y );
|
||||
}
|
||||
}
|
||||
|
||||
v = v + source2.m_vincrement;
|
||||
offset += inner;
|
||||
}
|
||||
sweepCount = KiROUND( v.ToDouble() ) + 1;
|
||||
sweepSize = aDataX->size() / sweepCount;
|
||||
}
|
||||
else if( TRACE* trace = aPlotTab->GetOrAddTrace( aVectorName, aTraceType ) )
|
||||
|
||||
if( TRACE* trace = aPlotTab->GetOrAddTrace( aVectorName, aTraceType ) )
|
||||
{
|
||||
if( data_y.size() >= size )
|
||||
aPlotTab->SetTraceData( trace, *aDataX, data_y );
|
||||
aPlotTab->SetTraceData( trace, *aDataX, data_y, sweepCount, sweepSize );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2101,6 +2079,29 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
|
||||
|
||||
return false;
|
||||
}
|
||||
catch( nlohmann::json::type_error& error )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Json type error reading %s: %s" ), aPath, error.what() );
|
||||
|
||||
return false;
|
||||
}
|
||||
catch( nlohmann::json::invalid_iterator& error )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Json invalid_iterator error reading %s: %s" ), aPath, error.what() );
|
||||
|
||||
return false;
|
||||
}
|
||||
catch( nlohmann::json::out_of_range& error )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Json out_of_range error reading %s: %s" ), aPath, error.what() );
|
||||
|
||||
return false;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Error reading %s" ), aPath );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2160,10 +2161,20 @@ bool SIMULATOR_FRAME_UI::SaveWorkbook( const wxString& aPath )
|
||||
auto findSignalName =
|
||||
[&]( const wxString& aVectorName ) -> wxString
|
||||
{
|
||||
wxString vectorName;
|
||||
wxString suffix;
|
||||
|
||||
if( aVectorName.EndsWith( _( " (phase)" ) ) )
|
||||
suffix = _( " (phase)" );
|
||||
else if( aVectorName.EndsWith( _( " (gain)" ) ) )
|
||||
suffix = _( " (gain)" );
|
||||
|
||||
vectorName = aVectorName.Left( aVectorName.Length() - suffix.Length() );
|
||||
|
||||
for( const auto& [ id, signal ] : m_userDefinedSignals )
|
||||
{
|
||||
if( aVectorName == vectorNameFromSignalId( id ) )
|
||||
return signal;
|
||||
if( vectorName == vectorNameFromSignalId( id ) )
|
||||
return signal + suffix;
|
||||
}
|
||||
|
||||
return aVectorName;
|
||||
@@ -2173,7 +2184,7 @@ bool SIMULATOR_FRAME_UI::SaveWorkbook( const wxString& aPath )
|
||||
{
|
||||
nlohmann::json trace_js = nlohmann::json(
|
||||
{ { "trace_type", (int) trace->GetType() },
|
||||
{ "signal", findSignalName( trace->GetName() ) },
|
||||
{ "signal", findSignalName( trace->GetDisplayName() ) },
|
||||
{ "color", COLOR4D( trace->GetTraceColour() ).ToCSSString() } } );
|
||||
|
||||
if( CURSOR* cursor = trace->GetCursor( 1 ) )
|
||||
@@ -2478,23 +2489,43 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
|
||||
auto getUnitsY =
|
||||
[&]( TRACE* aTrace ) -> wxString
|
||||
{
|
||||
if( ( aTrace->GetType() & SPT_AC_PHASE ) || ( aTrace->GetType() & SPT_CURRENT ) )
|
||||
return plotTab->GetUnitsY2();
|
||||
else if( aTrace->GetType() & SPT_POWER )
|
||||
return plotTab->GetUnitsY3();
|
||||
if( plotTab->GetSimType() == ST_AC )
|
||||
{
|
||||
if( aTrace->GetType() & SPT_AC_PHASE )
|
||||
return plotTab->GetUnitsY2();
|
||||
else
|
||||
return plotTab->GetUnitsY1();
|
||||
}
|
||||
else
|
||||
return plotTab->GetUnitsY1();
|
||||
{
|
||||
if( aTrace->GetType() & SPT_POWER )
|
||||
return plotTab->GetUnitsY3();
|
||||
else if( aTrace->GetType() & SPT_CURRENT )
|
||||
return plotTab->GetUnitsY2();
|
||||
else
|
||||
return plotTab->GetUnitsY1();
|
||||
}
|
||||
};
|
||||
|
||||
auto getNameY =
|
||||
[&]( TRACE* aTrace ) -> wxString
|
||||
{
|
||||
if( ( aTrace->GetType() & SPT_AC_PHASE ) || ( aTrace->GetType() & SPT_CURRENT ) )
|
||||
return plotTab->GetLabelY2();
|
||||
else if( aTrace->GetType() & SPT_POWER )
|
||||
return plotTab->GetLabelY3();
|
||||
if( plotTab->GetSimType() == ST_AC )
|
||||
{
|
||||
if( aTrace->GetType() & SPT_AC_PHASE )
|
||||
return plotTab->GetLabelY2();
|
||||
else
|
||||
return plotTab->GetLabelY1();
|
||||
}
|
||||
else
|
||||
return plotTab->GetLabelY1();
|
||||
{
|
||||
if( aTrace->GetType() & SPT_POWER )
|
||||
return plotTab->GetLabelY3();
|
||||
else if( aTrace->GetType() & SPT_CURRENT )
|
||||
return plotTab->GetLabelY2();
|
||||
else
|
||||
return plotTab->GetLabelY1();
|
||||
}
|
||||
};
|
||||
|
||||
auto formatValue =
|
||||
@@ -2660,7 +2691,10 @@ void SIMULATOR_FRAME_UI::OnSimRefresh( bool aFinal )
|
||||
wxString msg;
|
||||
|
||||
if( aFinal )
|
||||
{
|
||||
applyUserDefinedSignals();
|
||||
updateSignalsGrid();
|
||||
}
|
||||
|
||||
// If there are any signals plotted, update them
|
||||
if( SIM_TAB::IsPlottable( simType ) )
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <confirm.h>
|
||||
#include <common.h>
|
||||
#include <locale_io.h>
|
||||
#include <geometry/eda_angle.h>
|
||||
|
||||
|
||||
void SPICE_VALUE_FORMAT::FromString( const wxString& aString )
|
||||
@@ -223,6 +224,13 @@ wxString SPICE_VALUE::ToString( const SPICE_VALUE_FORMAT& aFormat )
|
||||
{
|
||||
wxString range( aFormat.Range );
|
||||
|
||||
if( range.EndsWith( wxS( "°" ) ) )
|
||||
{
|
||||
EDA_ANGLE angle( m_base * std::pow( 10, (int) m_prefix ), DEGREES_T );
|
||||
angle.Normalize180();
|
||||
return wxString::FromCDouble( angle.AsDegrees(), aFormat.Precision ) + wxS( "°" );
|
||||
}
|
||||
|
||||
if( range.StartsWith( wxS( "~" ) ) )
|
||||
{
|
||||
Normalize();
|
||||
@@ -254,6 +262,11 @@ wxString SPICE_VALUE::ToString( const SPICE_VALUE_FORMAT& aFormat )
|
||||
mantissa *= std::pow( 10, scale - aFormat.Precision + 1 );
|
||||
|
||||
wxString res = wxString::FromCDouble( mantissa, std::max( 0, aFormat.Precision - scale - 1 ) );
|
||||
|
||||
// If we have an excessively long number, switch to scientific notation
|
||||
if( ssize_t( res.length() ) > aFormat.Precision + scale + 1 )
|
||||
res = wxString::FromCDouble( mantissa );
|
||||
|
||||
return res + range;
|
||||
}
|
||||
|
||||
|
||||
@@ -411,6 +411,15 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
|
||||
return IsSymbolEditable() && !IsSymbolAlias();
|
||||
};
|
||||
|
||||
auto isEditableInAliasCond =
|
||||
[this]( const SELECTION& )
|
||||
{
|
||||
// Less restrictive than isEditableCond
|
||||
// Symbols fields (root symbols and aliases) from the new s-expression libraries
|
||||
// or in the schematic are editable.
|
||||
return IsSymbolEditable();
|
||||
};
|
||||
|
||||
auto symbolModifiedCondition =
|
||||
[this]( const SELECTION& sel )
|
||||
{
|
||||
@@ -462,8 +471,10 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
|
||||
mgr->SetConditions( ACTIONS::selectAll, ENABLE( haveSymbolCond ) );
|
||||
mgr->SetConditions( ACTIONS::unselectAll, ENABLE( haveSymbolCond ) );
|
||||
|
||||
mgr->SetConditions( EE_ACTIONS::rotateCW, ENABLE( isEditableCond ) );
|
||||
mgr->SetConditions( EE_ACTIONS::rotateCCW, ENABLE( isEditableCond ) );
|
||||
// These actions in symbol editor when editing alias field rotations are allowed.
|
||||
mgr->SetConditions( EE_ACTIONS::rotateCW, ENABLE( isEditableInAliasCond ) );
|
||||
mgr->SetConditions( EE_ACTIONS::rotateCCW, ENABLE( isEditableInAliasCond ) );
|
||||
|
||||
mgr->SetConditions( EE_ACTIONS::mirrorH, ENABLE( isEditableCond ) );
|
||||
mgr->SetConditions( EE_ACTIONS::mirrorV, ENABLE( isEditableCond ) );
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023, 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
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <wx/filename.h>
|
||||
#include <wx/filedlg.h>
|
||||
#include <string_utils.h>
|
||||
#include <io/eagle/eagle_parser.h>
|
||||
|
||||
|
||||
void SYMBOL_EDIT_FRAME::ImportSymbol()
|
||||
@@ -108,6 +109,12 @@ void SYMBOL_EDIT_FRAME::ImportSymbol()
|
||||
DisplayErrorMessage( this, msg, ioe.What() );
|
||||
return;
|
||||
}
|
||||
catch( const XML_PARSER_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Cannot import symbol library '%s'." ), fn.GetFullPath() );
|
||||
DisplayErrorMessage( this, msg, ioe.what() );
|
||||
return;
|
||||
}
|
||||
|
||||
if( symbols.empty() )
|
||||
{
|
||||
|
||||
@@ -106,9 +106,9 @@ public:
|
||||
switch( shape->GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
points->AddPoint( mapCoords( shape->GetPosition() ) );
|
||||
points->AddPoint( mapCoords( shape->GetStart() ) );
|
||||
points->AddPoint( mapCoords( shape->GetEnd() ) );
|
||||
points->AddPoint( mapCoords( shape->GetPosition() ) );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
@@ -193,9 +193,9 @@ public:
|
||||
switch( shape->GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
points->AddPoint( shape->GetPosition() );
|
||||
points->AddPoint( shape->GetStart() );
|
||||
points->AddPoint( shape->GetEnd() );
|
||||
points->AddPoint( shape->GetPosition() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
@@ -864,12 +864,7 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
|
||||
switch( shape->GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
if( getEditedPointIndex() == ARC_CENTER )
|
||||
{
|
||||
shape->SetEditState( 4 );
|
||||
shape->CalcEdit( m_editPoints->Point( ARC_CENTER ).GetPosition() );
|
||||
}
|
||||
else if( getEditedPointIndex() == ARC_START )
|
||||
if( getEditedPointIndex() == ARC_START )
|
||||
{
|
||||
shape->SetEditState( 2 );
|
||||
shape->CalcEdit( m_editPoints->Point( ARC_START ).GetPosition() );
|
||||
@@ -879,6 +874,11 @@ void EE_POINT_EDITOR::updateParentItem( bool aSnapToGrid ) const
|
||||
shape->SetEditState( 3 );
|
||||
shape->CalcEdit( m_editPoints->Point( ARC_END ).GetPosition() );
|
||||
}
|
||||
else if( getEditedPointIndex() == ARC_CENTER )
|
||||
{
|
||||
shape->SetEditState( 4 );
|
||||
shape->CalcEdit( m_editPoints->Point( ARC_CENTER ).GetPosition() );
|
||||
}
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
@@ -1266,9 +1266,9 @@ void EE_POINT_EDITOR::updatePoints()
|
||||
switch( shape->GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
m_editPoints->Point( ARC_CENTER ).SetPosition( shape->GetPosition() );
|
||||
m_editPoints->Point( ARC_START ).SetPosition( shape->GetStart() );
|
||||
m_editPoints->Point( ARC_END ).SetPosition( shape->GetEnd() );
|
||||
m_editPoints->Point( ARC_CENTER ).SetPosition( shape->GetPosition() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
|
||||
@@ -82,7 +82,7 @@ EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
|
||||
}
|
||||
|
||||
|
||||
BOX2I EE_SELECTION::GetBoundingBox() const
|
||||
BOX2I EE_SELECTION::GetBoundingBox( bool aOnlyVisible ) const
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override;
|
||||
|
||||
BOX2I GetBoundingBox() const override;
|
||||
BOX2I GetBoundingBox( bool aOnlyVisible = false ) const override;
|
||||
|
||||
void SetScreen( SCH_SCREEN* aScreen ) { m_screen = aScreen; }
|
||||
SCH_SCREEN* GetScreen() { return m_screen; }
|
||||
|
||||
@@ -1034,8 +1034,11 @@ OPT_TOOL_EVENT EE_SELECTION_TOOL::autostartEvent( TOOL_EVENT* aEvent, EE_GRID_HE
|
||||
|
||||
wxCHECK( pin, OPT_TOOL_EVENT() );
|
||||
|
||||
if( !pin->IsVisible() && !m_frame->eeconfig()->m_Appearance.show_hidden_pins )
|
||||
if( !pin->IsVisible()
|
||||
&& !( m_frame->eeconfig()->m_Appearance.show_hidden_pins ) )
|
||||
{
|
||||
return OPT_TOOL_EVENT();
|
||||
}
|
||||
}
|
||||
|
||||
newEvt->SetMousePosition( pos );
|
||||
|
||||
@@ -196,7 +196,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
// Then we need to annotate all instances by sheet
|
||||
for( SCH_SHEET_PATH& instance : newInstances )
|
||||
{
|
||||
SCH_REFERENCE newReference( symbol, symbol->GetLibSymbolRef().get(), instance );
|
||||
SCH_REFERENCE newReference( symbol, instance );
|
||||
SCH_REFERENCE_LIST refs;
|
||||
refs.AddItem( newReference );
|
||||
|
||||
@@ -373,8 +373,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
annotate();
|
||||
|
||||
// Update the list of references for the next symbol placement.
|
||||
SCH_REFERENCE placedSymbolReference( symbol, symbol->GetLibSymbolRef().get(),
|
||||
m_frame->GetCurrentSheet() );
|
||||
SCH_REFERENCE placedSymbolReference( symbol, m_frame->GetCurrentSheet() );
|
||||
existingRefs.AddItem( placedSymbolReference );
|
||||
existingRefs.SortByReferenceOnly();
|
||||
|
||||
@@ -436,9 +435,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
annotate();
|
||||
|
||||
// Update the list of references for the next symbol placement.
|
||||
SCH_REFERENCE placedSymbolReference( symbol,
|
||||
symbol->GetLibSymbolRef().get(),
|
||||
m_frame->GetCurrentSheet() );
|
||||
SCH_REFERENCE placedSymbolReference( symbol, m_frame->GetCurrentSheet() );
|
||||
existingRefs.AddItem( placedSymbolReference );
|
||||
existingRefs.SortByReferenceOnly();
|
||||
}
|
||||
|
||||
@@ -101,10 +101,14 @@ private:
|
||||
|
||||
for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
|
||||
{
|
||||
wxString num_unit;
|
||||
num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
|
||||
wxString unit_text;
|
||||
|
||||
wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
|
||||
if( symbol->GetLibSymbolRef()->HasUnitDisplayName( ii + 1 ) )
|
||||
unit_text = symbol->GetLibSymbolRef()->GetUnitDisplayName( ii + 1 );
|
||||
else
|
||||
unit_text.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
|
||||
|
||||
wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, unit_text, wxEmptyString,
|
||||
wxITEM_CHECK );
|
||||
|
||||
if( unit == ii + 1 )
|
||||
|
||||
@@ -1809,7 +1809,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||
// Ignore symbols from a non-existant library.
|
||||
if( libSymbol )
|
||||
{
|
||||
SCH_REFERENCE schReference( symbol, libSymbol, sheetPath );
|
||||
SCH_REFERENCE schReference( symbol, sheetPath );
|
||||
schReference.SetSheetNumber( sheetPath.GetVirtualPageNumber() );
|
||||
pastedSymbols[sheetPath].AddItem( schReference );
|
||||
}
|
||||
|
||||
@@ -253,50 +253,39 @@ int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( !item && searchAllSheets )
|
||||
{
|
||||
SCH_SCREENS screens( m_frame->Schematic().Root() );
|
||||
std::vector<SCH_SHEET_PATH*> paths;
|
||||
SCH_SCREENS screens( m_frame->Schematic().Root() );
|
||||
SCH_SHEET_LIST paths;
|
||||
|
||||
screens.BuildClientSheetPathList();
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
for( SCH_SHEET_PATH& sheet : screen->GetClientSheetPaths() )
|
||||
paths.push_back( &sheet );
|
||||
paths.push_back( sheet );
|
||||
}
|
||||
|
||||
std::sort( paths.begin(), paths.end(), [] ( const SCH_SHEET_PATH* lhs,
|
||||
const SCH_SHEET_PATH* rhs ) -> bool
|
||||
{
|
||||
int retval = lhs->ComparePageNum( *rhs );
|
||||
|
||||
if( retval < 0 )
|
||||
return true;
|
||||
else if( retval > 0 )
|
||||
return false;
|
||||
else /// Enforce strict ordering. If the page numbers are the same, use UUIDs
|
||||
return lhs->GetCurrentHash() < rhs->GetCurrentHash();
|
||||
} );
|
||||
paths.SortByPageNumbers( false );
|
||||
|
||||
if( isReversed )
|
||||
std::reverse( paths.begin(), paths.end() );
|
||||
|
||||
for( SCH_SHEET_PATH* sheet : paths )
|
||||
for( SCH_SHEET_PATH& sheet : paths )
|
||||
{
|
||||
if( afterSheet )
|
||||
{
|
||||
if( afterSheet->GetCurrentHash() == sheet->GetCurrentHash() )
|
||||
if( afterSheet->GetCurrentHash() == sheet.GetCurrentHash() )
|
||||
afterSheet = nullptr;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
item = nextMatch( sheet->LastScreen(), sheet, nullptr, data, isReversed );
|
||||
item = nextMatch( sheet.LastScreen(), &sheet, nullptr, data, isReversed );
|
||||
|
||||
if( item )
|
||||
{
|
||||
if( m_frame->Schematic().CurrentSheet() != *sheet )
|
||||
if( m_frame->Schematic().CurrentSheet() != sheet )
|
||||
{
|
||||
m_frame->Schematic().SetCurrentSheet( *sheet );
|
||||
m_frame->Schematic().SetCurrentSheet( sheet );
|
||||
m_frame->DisplayCurrentSheet();
|
||||
}
|
||||
|
||||
@@ -442,7 +431,7 @@ int SCH_FIND_REPLACE_TOOL::ReplaceAll( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
else
|
||||
{
|
||||
SCH_SHEET_LIST allSheets = m_frame->Schematic().GetSheets();
|
||||
SCH_SHEET_LIST allSheets = m_frame->Schematic().GetUnorderedSheets();
|
||||
SCH_SCREENS screens( m_frame->Schematic().Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
|
||||
@@ -201,7 +201,7 @@ bool SCH_NAVIGATE_TOOL::CanGoPrevious()
|
||||
bool SCH_NAVIGATE_TOOL::CanGoNext()
|
||||
{
|
||||
return m_frame->GetCurrentSheet().GetVirtualPageNumber()
|
||||
< (int) m_frame->Schematic().GetSheets().size();
|
||||
< (int) m_frame->Schematic().GetUnorderedSheets().size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ int SYMBOL_EDITOR_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
||||
[&]( EDA_ITEM* item, const VECTOR2I& delta )
|
||||
{
|
||||
commit.Modify( item, m_frame->GetScreen() );
|
||||
static_cast<LIB_ITEM*>( item )->Offset( mapCoords( delta ) );
|
||||
static_cast<LIB_ITEM*>( item )->Offset( delta );
|
||||
updateItem( item, true );
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#define DIALOG_EDIT_LIBRARY_TABLES_H
|
||||
|
||||
#include <dialog_shim.h>
|
||||
#include <wx/panel.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
|
||||
|
||||
class DIALOG_EDIT_LIBRARY_TABLES : public DIALOG_SHIM
|
||||
@@ -38,8 +40,20 @@ public:
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
void ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton = false,
|
||||
WX_INFOBAR::MESSAGE_TYPE aType = WX_INFOBAR::MESSAGE_TYPE::GENERIC )
|
||||
{
|
||||
m_infoBar->RemoveAllButtons();
|
||||
|
||||
if( aShowCloseButton )
|
||||
m_infoBar->AddCloseButton();
|
||||
|
||||
m_infoBar->ShowMessageFor( aErrorMsg, 8000, wxICON_ERROR, aType );
|
||||
}
|
||||
|
||||
protected:
|
||||
wxPanel* m_contentPanel;
|
||||
WX_INFOBAR* m_infoBar;
|
||||
wxPanel* m_contentPanel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <unordered_map>
|
||||
#include <font/fontinfo.h>
|
||||
|
||||
class REPORTER;
|
||||
namespace fontconfig
|
||||
{
|
||||
|
||||
@@ -67,9 +68,17 @@ public:
|
||||
*/
|
||||
void ListFonts( std::vector<std::string>& aFonts, const std::string& aDesiredLang );
|
||||
|
||||
/**
|
||||
* Set the reporter to use for reporting font substitution warnings.
|
||||
*
|
||||
* @param aReporter The reporter to use for reporting font substitution warnings.
|
||||
*/
|
||||
static void SetReporter( REPORTER* aReporter );
|
||||
|
||||
private:
|
||||
std::map<std::string, FONTINFO> m_fontInfoCache;
|
||||
wxString m_fontCacheLastLang;
|
||||
static REPORTER* s_reporter;
|
||||
|
||||
/**
|
||||
* Matches the two rfc 3306 language entries, used for when searching for matching family names
|
||||
|
||||
@@ -191,10 +191,7 @@ public:
|
||||
/**
|
||||
* @return Clears the footprint info cache
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
m_list.clear();
|
||||
}
|
||||
virtual void Clear() = 0;
|
||||
|
||||
/**
|
||||
* Get info for a footprint by id.
|
||||
|
||||
@@ -444,7 +444,7 @@ public:
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetNativeCursorStyle()
|
||||
bool SetNativeCursorStyle( KICURSOR aCursor ) override;
|
||||
bool SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI ) override;
|
||||
|
||||
/// @copydoc GAL::BeginDrawing()
|
||||
void BeginDrawing() override;
|
||||
|
||||
+30
-1
@@ -34,32 +34,59 @@ enum class KICURSOR
|
||||
{
|
||||
DEFAULT,
|
||||
ARROW,
|
||||
ARROW64,
|
||||
MOVING,
|
||||
MOVING64,
|
||||
PENCIL,
|
||||
PENCIL64,
|
||||
REMOVE,
|
||||
REMOVE64,
|
||||
HAND,
|
||||
HAND64,
|
||||
BULLSEYE,
|
||||
BULLSEYE64,
|
||||
VOLTAGE_PROBE,
|
||||
VOLTAGE_PROBE64,
|
||||
CURRENT_PROBE,
|
||||
CURRENT_PROBE64,
|
||||
TUNE,
|
||||
TUNE64,
|
||||
TEXT,
|
||||
TEXT64,
|
||||
MEASURE,
|
||||
MEASURE64,
|
||||
ADD,
|
||||
ADD64,
|
||||
SUBTRACT,
|
||||
SUBTRACT64,
|
||||
XOR,
|
||||
XOR64,
|
||||
ZOOM_IN,
|
||||
ZOOM_IN64,
|
||||
ZOOM_OUT,
|
||||
ZOOM_OUT64,
|
||||
LABEL_NET,
|
||||
LABEL_NET64,
|
||||
LABEL_GLOBAL,
|
||||
LABEL_GLOBAL64,
|
||||
COMPONENT,
|
||||
COMPONENT64,
|
||||
SELECT_WINDOW,
|
||||
SELECT_WINDOW64,
|
||||
SELECT_LASSO,
|
||||
SELECT_LASSO64,
|
||||
LINE_BUS,
|
||||
LINE_BUS64,
|
||||
LINE_GRAPHIC,
|
||||
LINE_GRAPHIC64,
|
||||
LINE_WIRE,
|
||||
LINE_WIRE64,
|
||||
LINE_WIRE_ADD,
|
||||
LINE_WIRE_ADD64,
|
||||
LABEL_HIER,
|
||||
PLACE
|
||||
LABEL_HIER64,
|
||||
PLACE,
|
||||
PLACE64
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -113,6 +140,8 @@ public:
|
||||
|
||||
static const wxCursor GetCursor( KICURSOR aCursorType );
|
||||
|
||||
static const wxCursor GetHiDPICursor( KICURSOR aCursorType );
|
||||
|
||||
static wxStockCursor GetStockCursor( KICURSOR aCursorType );
|
||||
|
||||
private:
|
||||
|
||||
@@ -886,7 +886,7 @@ public:
|
||||
* @param aCursor is the cursor to use in the native panel
|
||||
* @return true if the cursor was updated, false if the cursor given was already set
|
||||
*/
|
||||
virtual bool SetNativeCursorStyle( KICURSOR aCursor );
|
||||
virtual bool SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI );
|
||||
|
||||
/**
|
||||
* Enable/disable cursor.
|
||||
|
||||
@@ -54,11 +54,6 @@ public:
|
||||
*/
|
||||
wxPoint GetNativePosition( const wxPoint& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Set the canvas scale factor, probably for a hi-DPI display.
|
||||
*/
|
||||
void SetScaleFactor( double aFactor );
|
||||
|
||||
/**
|
||||
* Get the current scale factor
|
||||
*/
|
||||
@@ -69,12 +64,6 @@ public:
|
||||
protected:
|
||||
///< Current VIEW_CONTROLS settings.
|
||||
KIGFX::VC_SETTINGS m_settings;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The current scale factor (e.g. for hi-DPI displays)
|
||||
*/
|
||||
double m_scale_factor;
|
||||
};
|
||||
|
||||
#endif // HIDPI_GL_CANVAS_H
|
||||
|
||||
@@ -276,7 +276,7 @@ public:
|
||||
// -------
|
||||
|
||||
/// @copydoc GAL::SetNativeCursorStyle()
|
||||
bool SetNativeCursorStyle( KICURSOR aCursor ) override;
|
||||
bool SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI ) override;
|
||||
|
||||
/// @copydoc GAL::DrawCursor()
|
||||
void DrawCursor( const VECTOR2D& aCursorPosition ) override;
|
||||
|
||||
@@ -114,7 +114,7 @@ protected:
|
||||
bool isCheckbox( int aRow, int aCol );
|
||||
bool isReadOnly( int aRow, int aCol );
|
||||
|
||||
bool toggleCell( int aRow, int aCol, bool aPreserveSelection = false );
|
||||
virtual bool toggleCell( int aRow, int aCol, bool aPreserveSelection = false );
|
||||
bool showEditor( int aRow, int aCol );
|
||||
|
||||
virtual void paste_clipboard();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user