Common folder housekeeping part 2.

This commit is contained in:
Wayne Stambaugh 2025-01-13 13:05:29 -05:00
parent 7bf0d36057
commit f161d94521
72 changed files with 672 additions and 445 deletions

View File

@ -161,15 +161,6 @@ static struct hotkey_name_descr hotkeyNameList[] =
#define MODIFIER_SHIFT wxT( "Shift+" )
/**
* Return the key name from the key code.
*
* Only some wxWidgets key values are handled for function key ( see hotkeyNameList[] )
*
* @param aKeycode key code (ASCII value, or wxWidgets value for function keys).
* @param aIsFound a pointer to a bool to return true if found, or false. an be nullptr default).
* @return the key name in a wxString.
*/
wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
{
wxString keyname, modifier, fullkeyname;
@ -229,12 +220,6 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
}
/**
* @param aText the base text on which to append the hotkey.
* @param aHotKey the hotkey keycode.
* @param aStyle IS_HOTKEY to add <tab><keyname> (shortcuts in menus, same as hotkeys).
* IS_COMMENT to add <spaces><(keyname)> mainly in tool tips.
*/
wxString AddHotkeyName( const wxString& aText, int aHotKey, HOTKEY_ACTION_TYPE aStyle )
{
wxString msg = aText;
@ -273,9 +258,6 @@ wxString AddHotkeyName( const wxString& aText, int aHotKey, HOTKEY_ACTION_TYPE a
}
/**
* Return the key code from its user-friendly key name (ie: "Ctrl+M").
*/
int KeyCodeFromKeyName( const wxString& keyname )
{
int ii, keycode = KEY_NON_FOUND;
@ -339,9 +321,6 @@ int KeyCodeFromKeyName( const wxString& keyname )
}
/*
* Displays the hotkeys registered with the given tool manager.
*/
void DisplayHotkeyList( EDA_BASE_FRAME* aParent )
{
DIALOG_LIST_HOTKEYS dlg( aParent );
@ -399,11 +378,13 @@ void ReadHotKeyConfigIntoActions( const wxString& aFileName, std::vector<TOOL_AC
// Set each tool action hotkey to the config file hotkey if present
for( TOOL_ACTION* action : aActions )
{
if( hotkeys.find( action->GetName() ) != hotkeys.end() )
{
std::pair<int, int> keys = hotkeys[action->GetName()];
action->SetHotKey( keys.first, keys.second );
}
}
}
@ -420,7 +401,8 @@ int WriteHotKeyConfig( const std::vector<TOOL_ACTION*>& aActions )
// Overlay the current app's hotkey definitions onto the map
for( const TOOL_ACTION* action : aActions )
hotkeys[ action->GetName() ] = std::pair<int, int>( action->GetHotKey(), action->GetHotKeyAlt() );
hotkeys[ action->GetName() ] = std::pair<int, int>( action->GetHotKey(),
action->GetHotKeyAlt() );
// Write entire hotkey set
wxFFileOutputStream outStream( fn.GetFullPath() );

View File

@ -420,17 +420,7 @@ bool HTTP_LIB_CONNECTION::boolFromString( const std::any& aVal, bool aDefaultVal
return aDefaultValue;
}
/*
* HTTP response status codes indicate whether a specific HTTP request has been successfully completed.
* Responses are grouped in five classes:
* Informational responses (100 ? 199)
* Successful responses (200 ? 299)
* Redirection messages (300 ? 399)
* Client error responses (400 ? 499)
* Server error responses (500 ? 599)
*
* see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
*/
wxString HTTP_LIB_CONNECTION::httpErrorCodeDescription( uint16_t aHttpCode )
{
auto codeDescription =
@ -450,7 +440,7 @@ wxString HTTP_LIB_CONNECTION::httpErrorCodeDescription( uint16_t aHttpCode )
case 205: return wxS( "Reset Content" );
case 206: return wxS( "Partial Content" );
case 207: return wxS( "Multi-Status" );
case 208: return wxS( "Already Reporte" );
case 208: return wxS( "Already Reported" );
case 226: return wxS( "IM Used" );
case 300: return wxS( "Multiple Choices" );
@ -482,7 +472,7 @@ wxString HTTP_LIB_CONNECTION::httpErrorCodeDescription( uint16_t aHttpCode )
case 417: return wxS( "Expectation Failed" );
case 418: return wxS( "I'm a teapot" );
case 421: return wxS( "Misdirected Request" );
case 422: return wxS( "Unprocessable Conten" );
case 422: return wxS( "Unprocessable Content" );
case 423: return wxS( "Locked" );
case 424: return wxS( "Failed Dependency" );
case 425: return wxS( "Too Early (Experimental)" );
@ -499,8 +489,8 @@ wxString HTTP_LIB_CONNECTION::httpErrorCodeDescription( uint16_t aHttpCode )
case 504: return wxS( "Gateway Timeout" );
case 505: return wxS( "HTTP Version Not Supported" );
case 506: return wxS( "Variant Also Negotiates" );
case 507: return wxS( "Insufficient Storag" );
case 508: return wxS( "Loop Detecte" );
case 507: return wxS( "Insufficient Storage" );
case 508: return wxS( "Loop Detected" );
case 510: return wxS( "Not Extended" );
case 511: return wxS( "Network Authentication Required" );
default: return wxS( "Unknown" );

View File

@ -76,7 +76,7 @@
* 6. Blocks are virtual groups, blocks must be placed by a INSERT entity
* 7. Blocks may be repeated multiple times
* 8. There is no sane way to make text look perfect like the original CAD.
* DXF simply does mpt secifying text/font enough to make it portable.
* DXF simply does mpt specifying text/font enough to make it portable.
* We however make do try to get it somewhat close/visually appealing.
* 9. We silently drop the z coordinate on 3d polylines
*/
@ -464,7 +464,8 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData )
if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE )
insertLine( m_curr_entity.m_LastCoordinate, seg_end, lineWidth );
else
insertArc( m_curr_entity.m_LastCoordinate, seg_end, m_curr_entity.m_BulgeVertex, lineWidth );
insertArc( m_curr_entity.m_LastCoordinate, seg_end, m_curr_entity.m_BulgeVertex,
lineWidth );
m_curr_entity.m_LastCoordinate = seg_end;
m_curr_entity.m_BulgeVertex = vertex->bulge;
@ -691,9 +692,10 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData )
{
MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() );
VECTOR3D refPointCoords = ocsToWcs( arbAxis, VECTOR3D( aData.ipx, aData.ipy, aData.ipz ) );
VECTOR3D secPointCoords = ocsToWcs( arbAxis, VECTOR3D( std::isnan( aData.apx ) ? 0 : aData.apx,
std::isnan( aData.apy ) ? 0 : aData.apy,
std::isnan( aData.apz ) ? 0 : aData.apz ) );
VECTOR3D secPointCoords =
ocsToWcs( arbAxis, VECTOR3D( std::isnan( aData.apx ) ? 0 : aData.apx,
std::isnan( aData.apy ) ? 0 : aData.apy,
std::isnan( aData.apz ) ? 0 : aData.apz ) );
VECTOR2D refPoint( mapX( refPointCoords.x ), mapY( refPointCoords.y ) );
VECTOR2D secPoint( mapX( secPointCoords.x ), mapY( secPointCoords.y ) );
@ -713,6 +715,7 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData )
DXF_IMPORT_STYLE* style = getImportStyle( aData.style.c_str() );
double textHeight = mapDim( aData.height );
// The 0.9 factor gives a better height/width base ratio with our font
double charWidth = textHeight * 0.9;
@ -720,12 +723,12 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData )
charWidth *= style->m_widthFactor;
double textWidth = charWidth * text.length(); // Rough approximation
double textThickness = textHeight/8.0; // Use a reasonable line thickness for this text
double textThickness = textHeight / 8.0; // Use a reasonable line thickness for this text
VECTOR2D bottomLeft(0.0, 0.0);
VECTOR2D bottomRight(0.0, 0.0);
VECTOR2D topLeft(0.0, 0.0);
VECTOR2D topRight(0.0, 0.0);
VECTOR2D bottomLeft( 0.0, 0.0 );
VECTOR2D bottomRight( 0.0, 0.0 );
VECTOR2D topLeft( 0.0, 0.0 );
VECTOR2D topRight( 0.0, 0.0 );
GR_TEXT_H_ALIGN_T hJustify = GR_TEXT_H_ALIGN_LEFT;
GR_TEXT_V_ALIGN_T vJustify = GR_TEXT_V_ALIGN_BOTTOM;
@ -804,6 +807,7 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData )
// dxf_lib imports text angle in radians (although there are no comment about that.
// So, for the moment, convert this angle to degrees
double angle_degree = aData.angle * 180 / M_PI;
// We also need the angle in radians. so convert angle_degree to radians
// regardless the aData.angle unit
double angleInRads = angle_degree * M_PI / 180.0;
@ -957,6 +961,7 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData )
// dxf_lib imports text angle in radians (although there are no comment about that.
// So, for the moment, convert this angle to degrees
double angle_degree = aData.angle * 180/M_PI;
// We also need the angle in radians. so convert angle_degree to radians
// regardless the aData.angle unit
double angleInRads = angle_degree * M_PI / 180.0;
@ -1032,7 +1037,6 @@ double DXF_IMPORT_PLUGIN::getCurrentUnitScale()
}
void DXF_IMPORT_PLUGIN::setVariableInt( const std::string& key, int value, int code )
{
// Called for every int variable in the DXF file (e.g. "$INSUNITS").
@ -1334,6 +1338,7 @@ wxString DXF_IMPORT_PLUGIN::toNativeString( const wxString& aData )
// degree:
regexp.Compile( wxT( "%%[dD]" ) );
regexp.Replace( &res, wxChar( 0x00B0 ) );
// plus/minus
regexp.Compile( wxT( "%%[pP]" ) );
regexp.Replace( &res, wxChar( 0x00B1 ) );
@ -1410,10 +1415,13 @@ void DXF_IMPORT_PLUGIN::insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aS
// reflect the Y values to put everything in a RHCS
VECTOR2D sp( aSegStart.x, -aSegStart.y );
VECTOR2D ep( aSegEnd.x, -aSegEnd.y );
// angle from end->start
double offAng = atan2( ep.y - sp.y, ep.x - sp.x );
// length of subtended segment = 1/2 distance between the 2 points
double d = 0.5 * sqrt( (sp.x - ep.x) * (sp.x - ep.x) + (sp.y - ep.y) * (sp.y - ep.y) );
double d = 0.5 * sqrt( ( sp.x - ep.x ) * ( sp.x - ep.x ) + ( sp.y - ep.y ) * ( sp.y - ep.y ) );
// midpoint of the subtended segment
double xm = ( sp.x + ep.x ) * 0.5;
double ym = ( sp.y + ep.y ) * 0.5;
@ -1477,11 +1485,11 @@ void DXF_IMPORT_PLUGIN::insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aS
void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
{
#if 0 // Debug only
wxLogMessage("spl deg %d kn %d ctr %d fit %d",
m_curr_entity.m_SplineDegree,
m_curr_entity.m_SplineKnotsList.size(),
m_curr_entity.m_SplineControlPointList.size(),
m_curr_entity.m_SplineFitPointList.size() );
wxLogMessage( "spl deg %d kn %d ctr %d fit %d",
m_curr_entity.m_SplineDegree,
m_curr_entity.m_SplineKnotsList.size(),
m_curr_entity.m_SplineControlPointList.size(),
m_curr_entity.m_SplineFitPointList.size() );
#endif
unsigned imax = m_curr_entity.m_SplineControlPointList.size();

View File

@ -335,13 +335,13 @@ private:
MATRIX3x3D getArbitraryAxis( DL_Extrusion* aData );
/**
* Converts a given world coordinate point to object coordinate using the given arbitrary
* Convert a given world coordinate point to object coordinate using the given arbitrary
* axis vectors.
*/
VECTOR3D wcsToOcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point );
/**
* Converts a given object coordinate point to world coordinate using the given arbitrary
* Convert a given object coordinate point to world coordinate using the given arbitrary
* axis vectors.
*/
VECTOR3D ocsToWcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point );
@ -436,7 +436,7 @@ private:
/**
* Called for every spline.
* */
*/
virtual void addSpline( const DL_SplineData& aData ) override;
/**
@ -459,6 +459,7 @@ private:
{
ReportMsg( _( "DXF construction lines not currently supported." ) );
}
virtual void addRay( const DL_RayData& ) override
{
ReportMsg( _( "DXF construction lines not currently supported." ) );
@ -473,30 +474,37 @@ private:
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimLinear( const DL_DimensionData&, const DL_DimLinearData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimRadial( const DL_DimensionData&, const DL_DimRadialData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimDiametric( const DL_DimensionData&, const DL_DimDiametricData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimAngular( const DL_DimensionData&, const DL_DimAngular2LData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimAngular3P( const DL_DimensionData&, const DL_DimAngular3PData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addDimOrdinate( const DL_DimensionData&, const DL_DimOrdinateData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
}
virtual void addLeader( const DL_LeaderData& ) override
{
ReportMsg( _( "DXF dimensions not currently supported." ) );
@ -507,6 +515,7 @@ private:
{
ReportMsg( _( "DXF hatches not currently supported." ) );
}
virtual void addHatchLoop( const DL_HatchLoopData& ) override { }
virtual void addHatchEdge( const DL_HatchEdgeData& ) override { }

View File

@ -39,23 +39,23 @@ class wxString;
class GRAPHICS_IMPORT_MGR
{
public:
///< List of handled file types.
/// List of handled file types.
enum GFX_FILE_T
{
DXF,
SVG
};
///< Vector containing all GFX_FILE_T values that can be imported.
/// Vector containing all GFX_FILE_T values that can be imported.
std::vector<GFX_FILE_T> GetImportableFileTypes() const
{
return { DXF, SVG };
}
///< Returns a plugin that handles a specific file extension.
/// Return a plugin that handles a specific file extension.
std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> GetPluginByExt( const wxString& aExtension ) const;
///< Returns a plugin instance for a specific file type.
/// Return a plugin instance for a specific file type.
std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> GetPlugin( GFX_FILE_T aType ) const;
};

View File

@ -134,7 +134,7 @@ public:
virtual void ReportMsg( const wxString& aMessage ) = 0;
protected:
///< Importer used to create objects representing the imported shapes.
/// Importer used to create objects representing the imported shapes.
GRAPHICS_IMPORTER* m_importer;
};

View File

@ -233,7 +233,7 @@ public:
m_items.clear();
}
///< Default line thickness (in mm)
/// Default line thickness (in mm).
static constexpr unsigned int DEFAULT_LINE_WIDTH_DFX = 1;
virtual void NewShape( POLY_FILL_RULE aFillRule = PF_NONZERO );
@ -313,45 +313,46 @@ public:
const IMPORTED_STROKE& aStroke ) = 0;
protected:
///< Add an item to the imported shapes list.
/// Add an item to the imported shapes list.
void addItem( std::unique_ptr<EDA_ITEM> aItem );
/*
/**
* Configure a shape as a spline or a line segment if it's degenerate.
*
* @return false if the shape is near-zero length and should be ignored.
*/
bool setupSplineOrLine( EDA_SHAPE& aShape, int aAccuracy );
///< factor to convert millimeters to Internal Units
/// Factor to convert millimeters to Internal Units.
double m_millimeterToIu;
///< Offset (in mm) for imported coordinates
/// Offset (in mm) for imported coordinates.
VECTOR2D m_offsetCoordmm;
std::vector<POLY_FILL_RULE> m_shapeFillRules;
private:
///< List of imported items
/// List of imported items.
std::list<std::unique_ptr<EDA_ITEM>> m_items;
///< Plugin used to load a file
/// Plugin used to load a file.
std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> m_plugin;
///< Total image width
/// Total image width.
double m_originalWidth;
///< Total image Height;
/// Total image Height.
double m_originalHeight;
/**
* Scale factor applied to the imported graphics.
*
* 1.0 does not change the size of imported items
* scale < 1.0 reduce the size of imported items
*/
VECTOR2D m_scale;
///< Default line thickness for the imported graphics
/// Default line thickness for the imported graphics.
double m_lineWidth;
};

View File

@ -114,18 +114,22 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
boundingBox.GetSize().y * aImporter.GetScale().y );
// Check that the scaled graphics fit in the KiCad numeric limits
if( boundingBox.GetSize().x * aImporter.GetMillimeterToIuFactor() > std::numeric_limits<int>::max() ||
boundingBox.GetSize().y * aImporter.GetMillimeterToIuFactor() > std::numeric_limits<int>::max() )
if( boundingBox.GetSize().x * aImporter.GetMillimeterToIuFactor()
> std::numeric_limits<int>::max()
|| boundingBox.GetSize().y * aImporter.GetMillimeterToIuFactor()
> std::numeric_limits<int>::max() )
{
double scale_factor = std::numeric_limits<int>::max() / ( aImporter.GetMillimeterToIuFactor() + 100 );
double scale_factor = std::numeric_limits<int>::max() /
( aImporter.GetMillimeterToIuFactor() + 100 );
double max_scale = std::max( scale_factor / boundingBox.GetSize().x,
scale_factor / boundingBox.GetSize().y );
aImporter.ReportMsg( wxString::Format( _( "Imported graphic is too large. Maximum scale is %f" ),
max_scale ) );
aImporter.ReportMsg( wxString::Format( _( "Imported graphic is too large. Maximum scale "
"is %f" ),
max_scale ) );
return;
}
// They haven't set the import offset, so we set it to the bounding box origin to keep the graphics
// in the KiCad drawing area
// They haven't set the import offset, so we set it to the bounding box origin to keep
// the graphics in the KiCad drawing area.
else if( aImporter.GetImportOffsetMM() == VECTOR2D( 0, 0 ) )
{
if( boundingBox.GetRight() > std::numeric_limits<int>::max()
@ -156,7 +160,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
if( max_offset_x >= std::numeric_limits<int>::max() )
{
newOffset.x -= ( max_offset_x - std::numeric_limits<int>::max() + 100.0 ) / total_scale_x;
newOffset.x -= ( max_offset_x - std::numeric_limits<int>::max() + 100.0 ) /
total_scale_x;
needsAdjustment = true;
}
else if( min_offset_x <= std::numeric_limits<int>::min() )
@ -178,7 +183,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
if( needsAdjustment )
{
aImporter.ReportMsg( wxString::Format( _( "Import offset adjusted to (%f, %f) to fit within numeric limits" ),
aImporter.ReportMsg( wxString::Format( _( "Import offset adjusted to (%f, %f) to fit "
"within numeric limits" ),
newOffset.x, newOffset.y ) );
aImporter.SetImportOffsetMM( newOffset );
}
@ -188,7 +194,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
shape->ImportTo( aImporter );
}
// converts a single SVG-style polygon (multiple outlines, hole detection based on orientation, custom fill rule) to a format that can be digested by KiCad (single outline, fractured)
// converts a single SVG-style polygon (multiple outlines, hole detection based on orientation,
// custom fill rule) to a format that can be digested by KiCad (single outline, fractured).
static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
std::vector<IMPORTED_POLYGON*>& aPaths,
GRAPHICS_IMPORTER::POLY_FILL_RULE aFillRule,
@ -200,8 +207,8 @@ static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
double maxX = std::numeric_limits<double>::min();
double maxY = maxX;
// as Clipper/SHAPE_POLY_SET uses ints we first need to upscale to a reasonably large size (in integer coordinates)
// to avoid losing accuracy
// as Clipper/SHAPE_POLY_SET uses ints we first need to upscale to a reasonably large size
// (in integer coordinates) to avoid losing accuracy.
const double convert_scale = 1000000000.0;
for( IMPORTED_POLYGON* path : aPaths )
@ -254,13 +261,15 @@ static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
}
SHAPE_POLY_SET result;
result.BuildPolysetFromOrientedPaths( upscaledPaths, aFillRule == GRAPHICS_IMPORTER::PF_EVEN_ODD );
result.BuildPolysetFromOrientedPaths( upscaledPaths,
aFillRule == GRAPHICS_IMPORTER::PF_EVEN_ODD );
result.Fracture();
for( int outl = 0; outl < result.OutlineCount(); outl++ )
{
const SHAPE_LINE_CHAIN& ro = result.COutline( outl );
std::vector<VECTOR2D> pts;
for( int i = 0; i < ro.PointCount(); i++ )
{
double xp = (double) ro.CPoint( i ).x * ( origW / upscaledW ) + minX;

View File

@ -385,7 +385,7 @@ public:
void PostprocessNestedPolygons();
protected:
///< List of imported shapes
/// List of imported shapes.
std::list<std::unique_ptr<IMPORTED_SHAPE>> m_shapes;
};

View File

@ -191,16 +191,17 @@ bool SVG_IMPORT_PLUGIN::Import()
{
if( filled && !path->closed )
{
// KiCad doesn't support a single object representing a filled shape that is *not* closed
// so create a filled, closed shape for the fill, and an unfilled, open shape for the outline
// KiCad doesn't support a single object representing a filled shape that is
// *not* closed so create a filled, closed shape for the fill, and an unfilled,
// open shape for the outline
static IMPORTED_STROKE noStroke( -1, LINE_STYLE::SOLID, COLOR4D::UNSPECIFIED );
DrawPath( path->pts, path->npts, true, noStroke, true, fillColor );
DrawPath( path->pts, path->npts, false, stroke, false, COLOR4D::UNSPECIFIED );
}
else
{
// Either the shape has fill and no stroke, so we implicitly close it (for no difference),
// or it's really closed
// Either the shape has fill and no stroke, so we implicitly close it (for no
// difference), or it's really closed.
// We could choose to import a not-filled, closed outline as splines to keep the
// original editability and control points, but currently we don't.
const bool closed = path->closed || filled;
@ -310,6 +311,7 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aCl
{
// Closed paths are always polygons, which mean they need to be interpolated
std::vector<VECTOR2D> collectedPathPoints;
if( aNumPoints > 0 )
GatherInterpolatedCubicBezierPath( aPoints, aNumPoints, collectedPathPoints );
@ -489,4 +491,4 @@ void SVG_IMPORT_PLUGIN::ReportMsg( const wxString& aMessage )
// Add message to keep trace of not handled svg entities
m_messages += aMessage;
m_messages += '\n';
}
}

View File

@ -65,12 +65,13 @@ KICOMMON_API bool IncrementString( wxString& name, int aIncrement )
number += aIncrement;
// Don't let result go below zero
if( number > -1 )
{
name.Remove( ii + 1 );
//write out a format string with correct number of leading zeroes
outputFormat.Printf( wxS( "%%0%dld" ), dCount );
//write out the number using the format string
outputNumber.Printf( outputFormat, number );
name << outputNumber << suffix;
@ -96,13 +97,16 @@ std::optional<wxString> STRING_INCREMENTER::Increment( const wxString& aStr, int
while( goodParts < ( aRightIndex + 1 ) && !remaining.IsEmpty() )
{
static const std::regex integerRegex( R"(\d+$)" );
// ABC or abc but not Abc
static const std::regex sameCaseAlphabetRegex( R"(([a-z]+|[A-Z]+)$)" );
// Skippables - for now anything that isn't a letter or number
static const std::regex skipRegex( R"([^a-zA-Z0-9]+$)" );
std::string remainingStr = remaining.ToStdString();
std::smatch match;
if( std::regex_search( remainingStr, match, integerRegex ) )
{
parts.push_back( { match.str(), STRING_PART_TYPE::INTEGER } );
@ -139,10 +143,12 @@ std::optional<wxString> STRING_INCREMENTER::Increment( const wxString& aStr, int
// Reassemble the string - the left-over part, then parts in reverse
wxString result = remaining;
for( auto it = parts.rbegin(); it != parts.rend(); ++it )
{
result << it->first;
}
return result;
}
@ -150,11 +156,13 @@ std::optional<wxString> STRING_INCREMENTER::Increment( const wxString& aStr, int
static bool containsIOSQXZ( const wxString& aStr )
{
static const wxString iosqxz = "IOSQXZ";
for( const wxUniChar& c : aStr )
{
if( iosqxz.Contains( c ) )
return true;
}
return false;
}
@ -185,6 +193,7 @@ bool STRING_INCREMENTER::incrementPart( wxString& aPart, STRING_PART_TYPE aType,
{
aPart = wxString( "0", oldLen - aPart.Len() ) + aPart;
}
return true;
}

View File

@ -94,8 +94,10 @@ std::map<wxString, wxString> ALTIUM_ASCII_PARSER::ReadProperties()
// convert the strings to wxStrings, since we use them everywhere
// value can have non-ASCII characters, so we convert them from LATIN1/ISO8859-1
wxString key( keyS.c_str(), wxConvISO8859_1 );
// Altium stores keys either in Upper, or in CamelCase. Lets unify it.
wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper();
// If the key starts with '%UTF8%' we have to parse the value using UTF8
wxString value;

View File

@ -191,7 +191,8 @@ ALTIUM_COMPOUND_FILE::GetLibSymbols( const CFB::COMPOUND_FILE_ENTRY* aStart ) co
std::map<wxString, ALTIUM_SYMBOL_DATA> folders;
m_reader->EnumFiles( root, 1, [&]( const CFB::COMPOUND_FILE_ENTRY* tentry, const CFB::utf16string&, int ) -> int
m_reader->EnumFiles( root, 1, [&]( const CFB::COMPOUND_FILE_ENTRY* tentry,
const CFB::utf16string&, int ) -> int
{
wxString dirName = UTF16ToWstring( tentry->name, tentry->nameLen );
@ -199,7 +200,8 @@ ALTIUM_COMPOUND_FILE::GetLibSymbols( const CFB::COMPOUND_FILE_ENTRY* aStart ) co
return 0;
m_reader->EnumFiles( tentry, 1,
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string&, int ) -> int
[&]( const CFB::COMPOUND_FILE_ENTRY* entry,
const CFB::utf16string&, int ) -> int
{
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
@ -361,8 +363,8 @@ std::map<wxString, wxString> ALTIUM_BINARY_PARSER::ReadProperties(
if( !hasNullByte && !isBinary )
{
wxLogTrace( "ALTIUM", wxT( "Missing null byte at end of property list. Imported data might be "
"malformed or missing." ) );
wxLogTrace( "ALTIUM", wxT( "Missing null byte at end of property list. Imported data "
"might be malformed or missing." ) );
}
// we use std::string because std::string can handle NULL-bytes
@ -411,8 +413,10 @@ std::map<wxString, wxString> ALTIUM_BINARY_PARSER::ReadProperties(
// convert the strings to wxStrings, since we use them everywhere
// value can have non-ASCII characters, so we convert them from LATIN1/ISO8859-1
wxString key( keyS.c_str(), wxConvISO8859_1 );
// Altium stores keys either in Upper, or in CamelCase. Lets unify it.
wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper();
// If the key starts with '%UTF8%' we have to parse the value using UTF8
wxString value;
@ -440,4 +444,4 @@ std::map<wxString, wxString> ALTIUM_BINARY_PARSER::ReadProperties(
}
return kv;
}
}

View File

@ -96,7 +96,8 @@ public:
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::COMPOUND_FILE_ENTRY* aStart, const std::vector<std::string>& aStreamPath ) const;
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::COMPOUND_FILE_ENTRY* aStart,
const std::vector<std::string>& aStreamPath ) const;
const CFB::COMPOUND_FILE_ENTRY* FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
const std::string aName,
@ -116,7 +117,8 @@ private:
class ALTIUM_BINARY_PARSER
{
public:
ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry );
ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry );
ALTIUM_BINARY_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize );
~ALTIUM_BINARY_PARSER() = default;
@ -124,6 +126,7 @@ public:
Type Read()
{
const size_t remainingBytes = GetRemainingBytes();
if( remainingBytes >= sizeof( Type ) )
{
Type val = *(Type*) ( m_pos );
@ -188,7 +191,9 @@ public:
remaining -= 8;
if( length <= 2 )
{
length = 0; // for empty strings, not even the null bytes are present
}
else
{
if( length > remaining )
@ -405,6 +410,7 @@ public:
int id = -1;
uint8_t byte = ReadByte();
if( byte != 0xD0 )
throw std::runtime_error( "ALTIUM_COMPRESSED_READER: invalid compressed string" );

View File

@ -129,7 +129,8 @@ wxString AltiumSchSpecialStringsToKiCadVariables( const wxString&
}
else
{
wxString specialString = aString.substr( start, delimiter - start ).Trim().Trim( false );
wxString specialString =
aString.substr( start, delimiter - start ).Trim().Trim( false );
if( specialString.StartsWith( "\"" ) && specialString.EndsWith( "\"" ) )
specialString = specialString.Mid( 1, specialString.Length() - 2 );
@ -155,6 +156,7 @@ wxString AltiumSchSpecialStringsToKiCadVariables( const wxString&
return result;
}
// https://www.altium.com/documentation/altium-designer/text-objects-pcb
wxString AltiumPcbSpecialStringsToKiCadStrings( const wxString& aString,
const std::map<wxString, wxString>& aOverrides )
@ -182,6 +184,7 @@ wxString AltiumPcbSpecialStringsToKiCadStrings( const wxString&
return aString;
}
wxString AltiumPinNamesToKiCad( wxString& aString )
{
if( aString.IsEmpty() )
@ -195,6 +198,7 @@ wxString AltiumPinNamesToKiCad( wxString& aString )
return AltiumPropertyToKiCadString( aString );
}
VECTOR2I AltiumGetEllipticalPos( double aMajor, double aMinor, double aAngleRadians )
{
if( aMajor == 0 || aMinor == 0 )
@ -207,8 +211,9 @@ VECTOR2I AltiumGetEllipticalPos( double aMajor, double aMinor, double aAngleRadi
double radius = numerator / denominator;
VECTOR2I retval( KiROUND( radius * cos( aAngleRadians ) ), KiROUND( radius * sin( aAngleRadians ) ) );
VECTOR2I retval( KiROUND( radius * cos( aAngleRadians ) ),
KiROUND( radius * sin( aAngleRadians ) ) );
return retval;
}
}

View File

@ -54,8 +54,8 @@ int ALTIUM_PROPS_UTILS::ReadInt( const std::map<wxString, wxString>& aProps, con
}
double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
double aDefault )
double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps,
const wxString& aKey, double aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
@ -73,7 +73,7 @@ double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProp
bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
bool aDefault )
bool aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
@ -85,7 +85,7 @@ bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, c
int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
const wxString& aKey, const wxString& aDefault )
{
const wxString& value = ReadString( aProps, aKey, aDefault );
@ -112,7 +112,7 @@ int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& a
wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
const wxString& aKey, const wxString& aDefault )
{
const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
@ -129,7 +129,7 @@ wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aPr
wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
const wxString& aKey, const wxString& aDefault )
{
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
@ -150,4 +150,4 @@ wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxStrin
}
return ReadString( aProps, aKey, aDefault );
}
}

View File

@ -221,7 +221,7 @@ void CADSTAR_ARCHIVE_PARSER::LINECODE::Parse( XNODE* aNode, PARSER_CONTEXT* aCon
else
{
THROW_UNKNOWN_PARAMETER_IO_ERROR( wxString::Format( "STYLE %s", styleStr ),
wxString::Format( "LINECODE -> %s", Name ) );
wxString::Format( "LINECODE -> %s", Name ) );
}
}
@ -396,8 +396,8 @@ void CADSTAR_ARCHIVE_PARSER::EVALUE::Parse( XNODE* aNode, PARSER_CONTEXT* aConte
|| ( !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Exponent ) ) )
{
THROW_PARSING_IO_ERROR( wxT( "Base and Exponent" ),
wxString::Format(
"%s->%s", aNode->GetParent()->GetName(), aNode->GetParent()->GetName() ) );
wxString::Format( "%s->%s", aNode->GetParent()->GetName(),
aNode->GetParent()->GetName() ) );
}
}
@ -495,7 +495,8 @@ void CADSTAR_ARCHIVE_PARSER::VERTEX::AppendToChain( SHAPE_LINE_CHAIN* aChainToAp
wxCHECK_MSG( aChainToAppendTo->PointCount() > 0, /*void*/,
"Can't append an arc to vertex to an empty chain" );
aChainToAppendTo->Append( BuildArc( aChainToAppendTo->GetPoint( -1 ), aCadstarToKicadPointCallback),
aChainToAppendTo->Append( BuildArc( aChainToAppendTo->GetPoint( -1 ),
aCadstarToKicadPointCallback ),
aAccuracy );
}
@ -625,7 +626,8 @@ SHAPE_POLY_SET CADSTAR_ARCHIVE_PARSER::SHAPE::ConvertToPolySet(
{
SHAPE_POLY_SET polyset;
wxCHECK( Type != SHAPE_TYPE::OPENSHAPE, polyset ); // We shouldn't convert openshapes to polyset!
// We shouldn't convert openshapes to polyset!
wxCHECK( Type != SHAPE_TYPE::OPENSHAPE, polyset );
polyset.AddOutline( OutlineAsChain( aCadstarToKicadPointCallback, aAccuracy ) );
@ -885,7 +887,7 @@ wxString CADSTAR_ARCHIVE_PARSER::ParseTextFields( const wxString& aTextString,
while( remainingStr.size() > 0 )
{
//Find the start token
// Find the start token
size_t startpos = remainingStr.Find( wxT( "<@" ) );
if( static_cast<int>( startpos ) == wxNOT_FOUND )
@ -2449,7 +2451,8 @@ void CADSTAR_ARCHIVE_PARSER::InsertAttributeAtEnd( XNODE* aNode, wxString aValue
XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
const wxString& aFileTypeIdentifier, PROGRESS_REPORTER* aProgressReporter )
const wxString& aFileTypeIdentifier,
PROGRESS_REPORTER* aProgressReporter )
{
KEYWORD emptyKeywords[1] = {};
XNODE* rootNode = nullptr;
@ -2488,6 +2491,8 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
if( !aProgressReporter->KeepRefreshing() )
{
delete rootNode;
// @spellingerror
THROW_IO_ERROR( _( "File import cancelled by user." ) );
}
@ -2745,7 +2750,8 @@ long CADSTAR_ARCHIVE_PARSER::GetNumberOfChildNodes( XNODE* aNode )
}
long CADSTAR_ARCHIVE_PARSER::GetNumberOfStepsForReporting( XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
long CADSTAR_ARCHIVE_PARSER::GetNumberOfStepsForReporting(
XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
{
XNODE* level1Node = aRootNode->GetChildren();
long retval = 0;

View File

@ -87,7 +87,7 @@ class SHAPE_POLY_SET;
class SHAPE_ARC;
/**
* @brief Helper functions and common structures for CADSTAR PCB and Schematic archive files.
* Helper functions and common structures for CADSTAR PCB and Schematic archive files.
*/
class CADSTAR_ARCHIVE_PARSER
{
@ -206,11 +206,12 @@ public:
};
/**
* @brief Replaces CADSTAR fields for the equivalent in KiCad and stores the field values
* in aParserContext
* @param aTextString Text string to parse
* @param aParserContext PARSER_CONTEXT in which to store the values of the found fields
* @return
* Replaces CADSTAR fields for the equivalent in KiCad and stores the field values
* in \a aParserContext.
*
* @param aTextString Text string to parse.
* @param aParserContext #PARSER_CONTEXT in which to store the values of the found fields.
* @return the parsed field.
*/
static wxString ParseTextFields( const wxString& aTextString, PARSER_CONTEXT* aParserContext );
@ -335,10 +336,10 @@ public:
wxString Name = wxT( "CADSTAR" );
long Modifier1 = FONT_NORMAL; ///< It seems this is related to weight. 400=Normal, 700=Bold.
long Modifier2 = 0; ///< It seems this is always 0 regardless of settings
bool KerningPairs =
false; ///< From CADSTAR Help: "Kerning Pairs is for causing the system to
///< automatically reduce the spacing between certain pairs of
///< characters in order to improve the appearance of the text"
bool KerningPairs = false; ///< From CADSTAR Help: "Kerning Pairs is for causing the
///< system to automatically reduce the spacing between
///< certain pairs of characters in order to improve the
///< appearance of the text".
bool Italic = false;
void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override;
@ -388,7 +389,7 @@ public:
/**
* @brief Represents a floating value in E notation
* Represent a floating value in E notation.
*/
struct EVALUE : PARSER
{
@ -400,7 +401,7 @@ public:
};
/**
* @brief Represents a point in x,y coordinates
* Represent a point in x,y coordinates.
*/
struct POINT : VECTOR2I, PARSER
{
@ -436,12 +437,13 @@ public:
};
/**
* @brief Represents a vertex in a shape. E.g. A circle is made by two semicircles with the same
* Represents a vertex in a shape. E.g. A circle is made by two semicircles with the same
* center point.
*/
struct VERTEX : PARSER
{
VERTEX( VERTEX_TYPE aType = VERTEX_TYPE::POINT, POINT aEnd = POINT(), POINT aCenter = POINT() ) :
VERTEX( VERTEX_TYPE aType = VERTEX_TYPE::POINT, POINT aEnd = POINT(),
POINT aCenter = POINT() ) :
Type( aType ), End( aEnd ), Center( aCenter )
{}
@ -462,7 +464,7 @@ public:
};
/**
* @brief Represents a cutout in a closed shape (e.g. OUTLINE)
* Represent a cutout in a closed shape (e.g. OUTLINE).
*/
struct CUTOUT : PARSER
{
@ -593,21 +595,20 @@ public:
/**
* @brief From CADSTAR Help: "Text Alignment enables you to define the position of an alignment
* origin for all text items in CADSTAR. The alignment origin is a point on or within the text
* boundary and defines how the text is displayed.
* From CADSTAR Help: "Text Alignment enables you to define the position of an alignment
* origin for all text items in CADSTAR.
*
* For example, with an alignment of bottom-right the origin will be positioned at the bottom
* right of the text boundary. This makes it easier to right-align several text items
* regardless of the length of text displayed.
* The alignment origin is a point on or within the text boundary and defines how the text
* is displayed. For example, with an alignment of bottom-right the origin will be positioned
* at the bottom right of the text boundary. This makes it easier to right-align several text
* items regardless of the length of text displayed. Text Alignment applies to all CADSTAR
* text. [...]
*
* Text Alignment applies to all CADSTAR text. [...]
*
* Note: Unaligned text operates in the way CADSTAR text always has. In most cases this behaves
* @note Unaligned text operates in the way CADSTAR text always has. In most cases this behaves
* as Bottom Left alignment, but there are a few exceptions, e.g. pin names. Also unaligned
* multiline text has an origin Bottom Left of the first line."
*
* See also JUSTIFICATION
* @see JUSTIFICATION
*/
enum class ALIGNMENT
{
@ -627,13 +628,12 @@ public:
static ALIGNMENT ParseAlignment( XNODE* aNode );
/**
* @brief From CADSTAR Help: "Multi Line Text can also be justified as Left, Centre or Right.
* From CADSTAR Help: "Multi Line Text can also be justified as Left, Centre or Right.
*
* This does not affect the text alignment. Note: Justification of single line text has no
* effect."
* effect." This only affects multiline text
*
* This only affects multiline text
*
* See also ALIGNMENT
* @see ALIGNMENT
*/
enum class JUSTIFICATION
{
@ -646,12 +646,12 @@ public:
static JUSTIFICATION ParseJustification( XNODE* aNode );
/**
* @brief Sets the readability direction of text. From CADSTAR Help: "Horizontal text will
* always be displayed from left to right (i.e. never upside down). Vertical text can be set as
* readable from either the left or right edge of the design."
* Sets the readability direction of text. From CADSTAR Help: "Horizontal text will
* always be displayed from left to right (i.e. never upside down).
*
* I.e. Vertical text can either be rotated 90 degrees clockwise or 90 degrees anticlockwise from
* horizontal. This does not impact vertical text
* Vertical text can be set as readable from either the left or right edge of the design."
* I.e. Vertical text can either be rotated 90 degrees clockwise or 90 degrees counterclockwise
* from horizontal. This does not impact vertical text.
*/
enum class READABILITY
{
@ -725,7 +725,7 @@ public:
/**
* @brief NOTE from CADSTAR help: To convert a Part Definition Attribute into a hyperlink, prefix
* NOTE from CADSTAR help: To convert a Part Definition Attribute into a hyperlink, prefix
* the attribute name with "Link "
*/
struct ATTRNAME : PARSER
@ -783,7 +783,7 @@ public:
/**
* @brief Corresponds to CADSTAR "origin". This is used for setting a location of an attribute
* Corresponds to CADSTAR "origin". This is used for setting a location of an attribute
* e.g. Designator (called Component Name in CADSTAR), Part Name (name of component in the
* library), etc. The atom identifier is "TEXTLOC"
*/
@ -792,7 +792,7 @@ public:
TEXT_LOCATION()
{
// The default alignment for TEXT_LOCATION (when "NO_ALIGNMENT" is selected) is
// Bottom left, matching CADSTAR's default behaviour
// Bottom left, matching CADSTAR's default behavior
Alignment = ALIGNMENT::BOTTOMLEFT;
}
ATTRIBUTE_ID AttributeID;
@ -834,14 +834,12 @@ public:
};
/**
* @brief Corresponds to "Display when" Item property. From CADSTAR
* Help: "This parameter enables you to make the visibility of
* a component outline/area (or an area of component copper, or
* a string of component text) dependent on the current mirror
* status of the component.
* Corresponds to "Display when" Item property.
*
* For example, you may require a string of component text to
* be displayed only when the component is mirrored."
* From CADSTAR Help: "This parameter enables you to make the visibility of a component
* outline/area (or an area of component copper, or a string of component text) dependent
* on the current mirror status of the component. For example, you may require a string
* of component text to be displayed only when the component is mirrored."
*/
enum class SWAP_RULE
{
@ -867,7 +865,7 @@ public:
/**
* @brief References an element from a design reuse block
* References an element from a design reuse block.
*/
struct REUSEBLOCKREF : PARSER
{
@ -994,9 +992,9 @@ public:
wxString Identifier = wxEmptyString; ///< This should match a pad identifier
///< in the component footprint
///< subnode="PINIDENTIFIER". It is assumed
///< that this could be empty in earlier
///< versions of CADSTAR
///< subnode="PINIDENTIFIER". It is
///< assumed that this could be empty in
///< earlier versions of CADSTAR
wxString Name = wxEmptyString; ///< Can be empty. If empty the pin name
///< displayed will be Identifier
///< (subnode="PINNAME")
@ -1028,7 +1026,6 @@ public:
///< the pin (It is unclear what the units
///< are, but only accepted values are
///< integers) subnode ="PINLOAD"
///
CADSTAR_PIN_POSITION Position =
CADSTAR_PIN_POSITION::TOP_RIGHT; ///< The pin names will use these positions
///< when the symbol is added to a design
@ -1157,7 +1154,7 @@ public:
NETELEMENT_ID ID; ///< First character is "J"
LAYER_ID LayerID;
POINT Location;
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this JUCTION is part of a
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this JUNCTION is part of a
///< group
REUSEBLOCKREF ReuseBlockRef;
bool Fixed = false;
@ -1289,7 +1286,8 @@ public:
static void InsertAttributeAtEnd( XNODE* aNode, wxString aValue );
/**
* @brief Reads a CADSTAR Archive file (S-parameter format)
* Reads a CADSTAR Archive file (S-parameter format).
*
* @param aFileName
* @param aFileTypeIdentifier Identifier of the first node in the file to check against.
E.g. "CADSTARPCB"
@ -1303,25 +1301,22 @@ public:
PROGRESS_REPORTER* aProgressReporter = nullptr );
/**
* @brief
* @param aAttribute
* @return
*/
static bool IsValidAttribute( wxXmlAttribute* aAttribute );
/**
* @brief
* @param aNode
* @param aID
* @param aIsRequired Prevents exception throwing if false.
* @return returns the value (wxString) of attribute "attrX" in aNode where 'X' is aID
* @throws IO_ERROR if attribute does not exist
*/
static wxString GetXmlAttributeIDString(
XNODE* aNode, unsigned int aID, bool aIsRequired = true );
static wxString GetXmlAttributeIDString( XNODE* aNode, unsigned int aID,
bool aIsRequired = true );
/**
* @brief
* @param aNode
* @param aID
* @param aIsRequired Prevents exception throwing if false.
@ -1331,21 +1326,18 @@ public:
static long GetXmlAttributeIDLong( XNODE* aNode, unsigned int aID, bool aIsRequired = true );
/**
* @brief
* @param aNode
* @throw IO_ERROR if a child node was found
*/
static void CheckNoChildNodes( XNODE* aNode );
/**
* @brief
* @param aNode
* @throw IO_ERROR if a node adjacent to aNode was found
*/
static void CheckNoNextNodes( XNODE* aNode );
/**
* @brief
* @param aNode with a child node containing an EVALUE
* @param aValueToParse
* @throw IO_ERROR if unable to parse or node is not an EVALUE
@ -1353,8 +1345,8 @@ public:
static void ParseChildEValue( XNODE* aNode, PARSER_CONTEXT* aContext, EVALUE& aValueToParse );
/**
* @brief if no children are present, it just returns an empty
* vector (without throwing an exception)
* If no children are present, it just returns an empty vector (without throwing an exception).
*
* @param aNode containing a series of POINT objects
* @param aTestAllChildNodes
* @param aExpectedNumPoints if UNDEFINED_VALUE (i.e. -1), this is check is disabled
@ -1362,14 +1354,16 @@ public:
* @throw IO_ERROR if one of the following:
* - Unable to parse a POINT object
* - aTestAllChildNodes is true and one of the child nodes is not a valid POINT object
* - aExpectedNumPoints is non-negative and the number of POINT objects found is different
* - aExpectedNumPoints is non-negative and the number of POINT objects found is
* different
*/
static std::vector<POINT> ParseAllChildPoints( XNODE* aNode, PARSER_CONTEXT* aContext,
bool aTestAllChildNodes = false, int aExpectedNumPoints = UNDEFINED_VALUE );
bool aTestAllChildNodes = false,
int aExpectedNumPoints = UNDEFINED_VALUE );
/**
* @brief if no children are present, it just returns an empty
* vector (without throwing an exception)
* If no children are present, it just returns an empty vector (without throwing an exception).
*
* @param aNode containing a series of VERTEX objects
* @param aTestAllChildNodes
* @param aExpectedNumPoints if -1, this is check is disabled
@ -1378,12 +1372,12 @@ public:
* - Unable to parse a VERTEX object
* - aTestAllChildNodes is true and one of the child nodes is not a valid VERTEX object
*/
static std::vector<VERTEX> ParseAllChildVertices(
XNODE* aNode, PARSER_CONTEXT* aContext, bool aTestAllChildNodes = false );
static std::vector<VERTEX> ParseAllChildVertices( XNODE* aNode, PARSER_CONTEXT* aContext,
bool aTestAllChildNodes = false );
/**
* @brief if no children are present, it just returns an empty
* vector (without throwing an exception)
* If no children are present, it just returns an empty vector (without throwing an exception).
*
* @param aNode containing a series of CUTOUT objects
* @param aTestAllChildNodes
* @param aExpectedNumPoints if -1, this is check is disabled
@ -1392,8 +1386,8 @@ public:
* - Unable to parse a CUTOUT object
* - aTestAllChildNodes is true and one of the child nodes is not a valid CUTOUT object
*/
static std::vector<CUTOUT> ParseAllChildCutouts(
XNODE* aNode, PARSER_CONTEXT* aContext, bool aTestAllChildNodes = false );
static std::vector<CUTOUT> ParseAllChildCutouts( XNODE* aNode, PARSER_CONTEXT* aContext,
bool aTestAllChildNodes = false );
static long GetNumberOfChildNodes( XNODE* aNode );
@ -1412,16 +1406,19 @@ public:
}
/**
* @brief Convert a string with CADSTAR overbar characters to equivalent in KiCad
* Convert a string with CADSTAR overbar characters to equivalent in KiCad.
*
* @param aCadstarString Input string
* @return KiCad string with overbar characters
*/
*/
static wxString HandleTextOverbar( wxString aCadstarString );
/**
* Corrects the position of a text element that had NO_ALIGNMENT in CADSTAR. Assumes that the
* provided text element has been initialised with a position and orientation.
* @param aKiCadTextItem a Kicad item to correct
* Correct the position of a text element that had NO_ALIGNMENT in CADSTAR.
*
* Assumes that the provided text element has been initialised with a position and orientation.
*
* @param aKiCadTextItem a KiCad item to correct
*/
static void FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextItem );
@ -1429,7 +1426,7 @@ public:
protected:
void checkPoint(); ///< Updates m_progressReporter or throws if user cancelled
void checkPoint(); ///< Updates m_progressReporter or throws if user canceled
PARSER_CONTEXT m_context;
PROGRESS_REPORTER* m_progressReporter; // optional; may be nullptr

View File

@ -48,13 +48,15 @@ struct WHITESPACE_OR_CONTINUATION : sor<WHITESPACE, LINE_CONTINUATION> {};
* String segment( no line continuation ), with exclusion rules
*/
template <typename... EXCLUSION_RULES>
struct STR_SEGMENT_EXCLUDING : plus<not_at<sor<eolf, LINE_CONTINUATION, EXCLUSION_RULES...>>, any>{};
struct STR_SEGMENT_EXCLUDING : plus<not_at<sor<eolf, LINE_CONTINUATION,
EXCLUSION_RULES...>>, any>{};
/**
* String with optional line continuation and exclusion rules
*/
template <typename... EXCLUSION_RULES>
struct STRING_EXCLUDING : plus<STR_SEGMENT_EXCLUDING<EXCLUSION_RULES...>, opt<LINE_CONTINUATION>> {};
struct STRING_EXCLUDING : plus<STR_SEGMENT_EXCLUDING<EXCLUSION_RULES...>,
opt<LINE_CONTINUATION>> {};
/**
@ -122,7 +124,7 @@ struct FORMAT : seq
CURRENT_FORMAT_NUMBER,
opt<eol>
>
{};
{};
// Newer Parts files have possibility of specifying a tree-like structure to show hierarchy
@ -150,7 +152,7 @@ struct HIERARCHY_NODE_ENTRY :
star<HIERARCHY_PART_NAME, star<WHITESPACE_OR_CONTINUATION>>, // 'part1' 'part2'
opt<eol>
>
{};
{};
// **************
// * PART ENTRY *
@ -166,7 +168,7 @@ struct PART_NAME_FILTER : sor<spaced_ch<'('>, spaced_ch<':'>, spaced_ch<';'>>{};
struct PART_NUMBER_FILTER : one<')'>{};
struct PART_VERSION_FILTER : spaced_ch<';'>{};
// part header elements:
// part header elements:
struct PART_NAME : STRING_EXCLUDING<PART_NAME_FILTER> {};
struct PART_NUMBER : STRING_IN_BRACKETS {};
struct PART_VERSION : STRING_EXCLUDING<PART_VERSION_FILTER> {};
@ -189,11 +191,11 @@ struct PART_HEADER :
// --------------------
//<PCB Component Refname>[_(<PCB Alternate Refname>)]
// string filters:
// string filters:
struct PCB_COMPONENT_FILTER : spaced_ch<'('>{};
struct PCB_ALTERNATE_FILTER : one<')'>{};
// pcb component elements
// pcb component elements
struct PCB_COMPONENT : STRING_EXCLUDING<PCB_COMPONENT_FILTER> {};
struct PCB_ALTERNATE : STRING_IN_BRACKETS {};
@ -370,7 +372,7 @@ struct EXTERNAL_SWAP_GROUP :
// Part Definition
// -----------
//[*DFN_<Definition name>]
// [*DFN_<Definition name>]
struct DEFINITION_NAME : STRING_EXCLUDING<> {};
struct DFN_LINE :
seq
@ -383,7 +385,7 @@ struct DFN_LINE :
>
{};
//[*NGS]
// [*NGS]
struct NGS_LINE :
seq
<
@ -393,7 +395,7 @@ struct NGS_LINE :
>
{};
//[*NPV]
// [*NPV]
struct NPV_LINE :
seq
<
@ -403,7 +405,7 @@ struct NPV_LINE :
>
{};
//[*STM_<Component name stem>]
// [*STM_<Component name stem>]
struct STEM : STRING_EXCLUDING<> {};
struct STM_LINE :
seq
@ -416,7 +418,7 @@ struct STM_LINE :
>
{};
//[*MXP <Maximum number of connector pins>]
// [*MXP <Maximum number of connector pins>]
struct MAX_PIN_COUNT : plus<digit> {};
struct MXP_LINE :
seq
@ -429,7 +431,7 @@ struct MXP_LINE :
>
{};
//[*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
// [*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
struct SPICE_PART_NAME : STRING_IN_BRACKETS {};
struct SPICE_MODEL : sor<QUOTED_STRING, STRING_EXCLUDING<>> {};
struct SPI_LINE :
@ -446,7 +448,7 @@ struct SPI_LINE :
{};
//[*PAC_(<Part name>)_<Acceptance Text>]
// [*PAC_(<Part name>)_<Acceptance Text>]
struct ACCEPTANCE_PART_NAME : STRING_IN_BRACKETS {};
struct ACCEPTANCE_TEXT : STRING_EXCLUDING<> {};
struct PAC_LINE :
@ -464,7 +466,7 @@ struct PAC_LINE :
// User defined part attributes
// -----------
//[*<User-defined name>_<Value>]
// [*<User-defined name>_<Value>]
struct USER_PART_ATTRIBUTE_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<WHITESPACE>> {};
struct USER_PART_ATTRIBUTE_VALUE : STRING_EXCLUDING<> {};
struct USER_PART_ATTRIBUTE :
@ -499,28 +501,28 @@ struct GENERIC_ATTRIBUTE :
>
{};
//[$[!]<SCM Attribute name>(<Attribute value>)]
// [$[!]<SCM Attribute name>(<Attribute value>)]
struct SCM_ATTRIBUTE : GENERIC_ATTRIBUTE<'$'>{};
//[%[!]<PCB Attribute name>(<Attribute value>)]
// [%[!]<PCB Attribute name>(<Attribute value>)]
struct PCB_ATTRIBUTE : GENERIC_ATTRIBUTE<'%'>{};
//[~[!]<Parts Library Attribute Name>(<Attribute Value>)]
// [~[!]<Parts Library Attribute Name>(<Attribute Value>)]
struct PART_ATTRIBUTE : GENERIC_ATTRIBUTE<'~'>{};
//[@[!]<SCM/PCB Attribute name>(<Attribute value>)]
// [@[!]<SCM/PCB Attribute name>(<Attribute value>)]
struct SCH_PCB_ATTRIBUTE : GENERIC_ATTRIBUTE<'@'>{};
//[<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
// [<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
struct SCH_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<spaced_ch<'('>>> {};
struct SCH_ALTERNATE : STRING_IN_BRACKETS {};
struct SCH_SYMBOL_LINE : seq<SCH_NAME, opt<SCH_ALTERNATE>, opt<eol>>{};
//[<PinIdentifier>[.<Position>] [!<Pintype>] [:<Loading>]]
// [<PinIdentifier>[.<Position>] [!<Pintype>] [:<Loading>]]
struct PIN_IDENTIFIER : plus<digit>{};
struct PIN_POSITION : range<'0', '3'>{};
struct PIN_TYPE : star<alpha>{};
@ -553,41 +555,42 @@ struct HIDDEN_PIN_ENTRY : seq<PIN_SIGNAL_NAME, plus<WHITESPACE>, PIN_LIST, opt<e
struct PART_ENTRY :
seq
<
PART_HEADER, //.<Part name>[ (1234): 1 ;<Description>]
PART_PCB_COMPONENT, //<PCB Component Refname> [(Alternate)]
PART_HEADER, // .<Part name>[ (1234): 1 ;<Description>]
PART_PCB_COMPONENT, // <PCB Component Refname> [(Alternate)]
// In any order:
star<sor<
PART_VALUE, //[*VALUE <Value>]
PIN_NAMES_LIST, //[*PNM <ID><Name>[ <ID><Name>] ...]
PIN_LABELS_LIST, //[*PLB <ID><Label>[ <ID><Label>] ...]
PIN_EQUIVALENCES, //[*EQU_<ID>=<ID>[=<ID>=<ID>_etc ...]]
INTERNAL_SWAP_GROUP, //[*SYM SYM1 |*INT 2 3 |*INT 4 5]
EXTERNAL_SWAP_GROUP, //[*SYM SYM1 |*EXT 2 3 |*EXT 4 5]
DFN_LINE, //[*DFN_<Definition name>]
NGS_LINE, //[*NGS]
NPV_LINE, //[*NPV]
STM_LINE, //[*STM_<Component name stem>]
MXP_LINE, //[*MXP <Maximum number of connector pins>]
SPI_LINE, //[*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
PAC_LINE, //[*PAC_(<Part name>)_<Acceptance Text>]
USER_PART_ATTRIBUTE, //[*<User-defined name>_<Value>]
SCM_ATTRIBUTE, //[$[!]<SCM Attribute name>(<Attribute value>)]
PCB_ATTRIBUTE, //[%[!]<PCB Attribute name>(<Attribute value>)]
PART_ATTRIBUTE, //[~[!]<Parts Library Attribute Name>(<Attribute Value>)]
SCH_PCB_ATTRIBUTE //[@[!]<SCM/PCB Attribute name>(<Attribute value>)]
PART_VALUE, // [*VALUE <Value>]
PIN_NAMES_LIST, // [*PNM <ID><Name>[ <ID><Name>] ...]
PIN_LABELS_LIST, // [*PLB <ID><Label>[ <ID><Label>] ...]
PIN_EQUIVALENCES, // [*EQU_<ID>=<ID>[=<ID>=<ID>_etc ...]]
INTERNAL_SWAP_GROUP, // [*SYM SYM1 |*INT 2 3 |*INT 4 5]
EXTERNAL_SWAP_GROUP, // [*SYM SYM1 |*EXT 2 3 |*EXT 4 5]
DFN_LINE, // [*DFN_<Definition name>]
NGS_LINE, // [*NGS]
NPV_LINE, // [*NPV]
STM_LINE, // [*STM_<Component name stem>]
MXP_LINE, // [*MXP <Maximum number of connector pins>]
SPI_LINE, // [*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
PAC_LINE, // [*PAC_(<Part name>)_<Acceptance Text>]
USER_PART_ATTRIBUTE, // [*<User-defined name>_<Value>]
SCM_ATTRIBUTE, // [$[!]<SCM Attribute name>(<Attribute value>)]
PCB_ATTRIBUTE, // [%[!]<PCB Attribute name>(<Attribute value>)]
PART_ATTRIBUTE, // [~[!]<Parts Library Attribute Name>(<Attribute
// Value>)]
SCH_PCB_ATTRIBUTE // [@[!]<SCM/PCB Attribute name>(<Attribute value>)]
>>,
star<SYMBOL_ENTRY>, //[<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
//[Pin entry] [Pin entry] ...
star<SYMBOL_ENTRY>, // [<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
// [Pin entry] [Pin entry] ...
star<HIDDEN_PIN_ENTRY> //[/<Signame>_<Pin entry>]
star<HIDDEN_PIN_ENTRY> // [/<Signame>_<Pin entry>]
>
{};
/**
* Grammar for CADSTAR Parts Library file format (*.lib)
* Grammar for CADSTAR Parts Library file format (*.lib).
*/
struct GRAMMAR :
must<
@ -611,8 +614,9 @@ struct GRAMMAR :
/**
* Grammar to parse the file header only.
*
* In general a valid file should have `#FORMAT 32` in the first line but there appear to be some
* files that ommit the format specifier and start straight away with the part definitions. Just
* files that omit the format specifier and start straight away with the part definitions. Just
* in case, we will also allow the first part to be up to 5 lines into the file (arbitrary number
* just to limit the time spent in reading a file header to determine whether it is valid).
*/

View File

@ -69,7 +69,8 @@ struct CADSTAR_PART_ENTRY
bool m_PinsVisible = true;
/**
* Map of pin identifiers to alphanumeric pin names
* Map of pin identifiers to alphanumeric pin names.
*
* Pin names can be a maximum of 10 characters
* (Typically used for naming of BGA pads - equivalent to KiCad Pin Numbers)
*
@ -78,39 +79,41 @@ struct CADSTAR_PART_ENTRY
std::map<long, std::string> m_PinNamesMap;
/**
* Map of pin identifiers to alphanumeric pin labels. Equivalent to KiCad Pin Names
* Map of pin identifiers to alphanumeric pin labels.
*
* Equivalent to KiCad Pin Names
*
* E.g: *PLB 1=STROBE 2=OFFSET 3=OFFSET 5=+ 6=+v
*/
std::map<long, std::string> m_PinLabelsMap;
/**
* Groups of pins that are interchangeable with each other
* Groups of pins that are interchangeable with each other.
*
* E.g: *EQU 2=1, 6=5, 8=9=10, 12=13
*/
std::vector<std::vector<long>> m_PinEquivalences;
/**
* Groups of INTERNAL gates that are interchangeable with each other
* Groups of INTERNAL gates that are interchangeable with each other.
*
* E.g: *SYM SYM1
* *INT 1 3
* *INT 2 5
*
* The gate described by pins 1 and 3 above, can be swapped internally with the gate decribed
* The gate described by pins 1 and 3 above, can be swapped internally with the gate described
* by pins 2 and 5 but they CANNOT be swapped with gates in another part
*/
std::vector<CADSTAR_SWAP_GROUP> m_InternalSwapGroup;
/**
* Groups of EXTERNAL gates that are interchangeable with each other
* Groups of EXTERNAL gates that are interchangeable with each other.
*
* E.g: *SYM SYM2
* *EXT 1 3
* *EXT 2 5
*
* The gate described by pins 1 and 3 above, can be swapped internally with the gate decribed
* The gate described by pins 1 and 3 above, can be swapped internally with the gate described
* by pins 2 and 5 AND they can be swapped with same gates in another part
*/
std::vector<CADSTAR_SWAP_GROUP> m_ExternalSwapGroup;
@ -119,7 +122,8 @@ struct CADSTAR_PART_ENTRY
* Star (*) line
* *<User-defined name> <Value>
* This line is ignored by CADSTAR. Usually they are used by third party tools.
* These lines are treated as attributes of the Parts library (i.e. Attribute Type = Parts Library).
* These lines are treated as attributes of the Parts library (i.e. Attribute Type =
* Parts Library).
*/
std::map<std::string, std::string> m_UserAttributes;
@ -158,7 +162,7 @@ struct CADSTAR_PART_ENTRY
std::map<std::string, CADSTAR_ATTRIBUTE_VALUE> m_PartAttributes;
/**
* Symbols that form this part
* Symbols that form this part.
*/
std::vector<CADSTAR_PART_SYMBOL_ENTRY> m_Symbols;
@ -226,8 +230,9 @@ struct CADSTAR_SWAP_GROUP
std::optional<std::string> m_Name;
/**
* Each gate is a list of pin identifiers. The order of the pins is important
* as it defines the equivalence between gates
* Each gate is a list of pin identifiers.
*
* The order of the pins is important as it defines the equivalence between gates.
*/
std::vector<std::vector<long>> m_Gates;
};
@ -237,7 +242,7 @@ struct CADSTAR_PART_NODE
{
std::optional<long> m_ParentNodeIdx;
std::string m_Name;
std::vector<std::string> m_PartNames; ///< Part names belonging to this hierarchy
std::vector<std::string> m_PartNames; ///< Part names belonging to this hierarchy.
};
#endif //CADSTAR_PARTS_LIB_MODEL_H

View File

@ -55,16 +55,16 @@ typedef std::unordered_map<wxString, wxXmlNode*> NODE_MAP;
typedef std::map<wxString, EINSTANCE*> EINSTANCE_MAP;
typedef std::map<wxString, std::unique_ptr<EPART>> EPART_MAP;
///< Translates Eagle special characters to their counterparts in KiCad.
/// Translates Eagle special characters to their counterparts in KiCad.
wxString escapeName( const wxString& aNetName );
///< Interprets special characters in Eagle text and converts them to KiCAD notation.
/// Interprets special characters in Eagle text and converts them to KiCAD notation.
wxString interpretText( const wxString& aText );
///< Translates Eagle special text reference to a KiCad variable reference
/// Translates Eagle special text reference to a KiCad variable reference.
bool substituteVariable( wxString* aText );
///< Converts Eagle's HTML description into KiCad description format
/// Converts Eagle's HTML description into KiCad description format.
wxString convertDescription( wxString aDescr );
static inline wxXmlNode* getChildrenNodes( NODE_MAP& aMap, const wxString& aName )
@ -140,13 +140,13 @@ public:
p.back().value = aValue;
}
/// modify the last path node's attribute
/// Modify the last path node's attribute.
void Attribute( const char* aAttribute )
{
p.back().attribute = aAttribute;
}
/// return the contents of the XPATH as a single string
/// Return the contents of the XPATH as a single string.
wxString Contents()
{
typedef std::vector<TRIPLET>::const_iterator CITER_TRIPLET;
@ -178,7 +178,7 @@ public:
/**
* Convert a wxString to a generic type T.
*
* @param aValue is a wxString containing the value that will be converted to type T.
* @param aValue is a wxString containing the value that will be converted to type T.
* @throw XML_PARSER_ERROR - an exception is thrown if the parsing fails or if the conversion to
* type T is unknown.
*/
@ -217,9 +217,9 @@ public:
{}
/**
* @param aData is a wxString containing the value that should be converted to type T. If
* aData is empty, the attribute is understood as unavailable; otherwise, the
* conversion to T is tried.
* @param aData is a wxString containing the value that should be converted to type T. If
* aData is empty, the attribute is understood as unavailable; otherwise, the
* conversion to T is tried.
*/
OPTIONAL_XML_ATTRIBUTE( const wxString& aData )
{
@ -231,8 +231,8 @@ public:
}
/**
* @param aData is the value of the XML attribute. If this constructor is called, the
* attribute is available.
* @param aData is the value of the XML attribute. If this constructor is called, the
* attribute is available.
*/
template<typename V = T>
OPTIONAL_XML_ATTRIBUTE( T aData ) :
@ -380,7 +380,7 @@ size_t GetNodeCount( const wxXmlNode* aNode );
*/
NODE_MAP MapChildren( wxXmlNode* aCurrentNode );
///< Convert an Eagle curve end to a KiCad center for S_ARC
/// Convert an Eagle curve end to a KiCad center for S_ARC.
VECTOR2I ConvertArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle );
// Pre-declare for typedefs
@ -402,7 +402,7 @@ struct EAGLE_BASE
IO_BASE* io;
/*
/**
* Send a message to the #IO_BASE #REPORTER object if one exists.
*
* @param aMsg is the message to send to the #REPORTER object.
@ -447,10 +447,10 @@ struct ECOORD : public EAGLE_BASE
EU_MIL, ///< mils/thous
};
///< Value expressed in nanometers
/// Value expressed in nanometers.
long long int value;
///< Unit used for the value field
/// Unit used for the value field.
static constexpr EAGLE_UNIT ECOORD_UNIT = EU_NM;
ECOORD()
@ -503,7 +503,7 @@ struct ECOORD : public EAGLE_BASE
return value == aOther.value;
}
///< Converts a size expressed in a certain unit to nanometers.
/// Converts a size expressed in a certain unit to nanometers.
static long long int ConvertToNm( int aValue, enum EAGLE_UNIT aUnit );
};

View File

@ -50,6 +50,7 @@
d.name = j.at( #name ).get<double>(); \
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOC_TYPE& d )
{
if( j.is_string() )
@ -66,6 +67,7 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOC_TYPE& d )
}
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::HEAD& d )
{
PARSE_VALUE( docType );
@ -81,6 +83,7 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::HEAD& d )
PARSE_TO_DOUBLE( y, 0 );
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT& d )
{
PARSE_VALUE( docType );
@ -92,6 +95,7 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT& d )
PARSE_VALUE( dataStr );
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT_PCB& d )
{
PARSE_VALUE( c_para );
@ -101,16 +105,19 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT_PCB& d )
d.DRCRULE = j.at( "DRCRULE" );
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT_SYM& d )
{
PARSE_VALUE( c_para );
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT_SCHEMATICS& d )
{
PARSE_VALUE( schematics );
}
void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::C_PARA& d )
{
PARSE_VALUE( package );

View File

@ -58,7 +58,8 @@ void IterateZipFiles(
std::vector<nlohmann::json> ParseJsonLines( wxInputStream& aInput, const wxString& aSource );
/**
* Multiple document types (e.g. footprint and PCB) can be put into a single file, separated by empty line.
* Multiple document types (e.g. footprint and PCB) can be put into a single file, separated by
* empty line.
*/
std::vector<std::vector<nlohmann::json>> ParseJsonLinesWithSeparation( wxInputStream& aInput,
const wxString& aSource );

View File

@ -61,6 +61,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SCH_ATTR& d )
d.fontStyle = j.at( 10 ).get<wxString>();
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PCB_ATTR& d )
{
d.id = j.at( 1 ).get<wxString>();
@ -159,6 +160,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SYM_PIN& d )
d.inverted = j.at( 9 ).get<int>() == 2;
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SYM_HEAD& d )
{
if( !j.at( 1 ).is_object() )
@ -174,6 +176,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SYM_HEAD& d )
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SHEET& d )
{
d.name = j.value( "name", "" );
@ -181,18 +184,21 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SHEET& d )
d.id = j.value( "id", 0 );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SCHEMATIC& d )
{
d.name = j.value( "name", "" );
d.sheets = j.value( "sheets", std::vector<PRJ_SHEET>{} );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_BOARD& d )
{
d.schematic = j.value( "schematic", "" );
d.pcb = j.value( "pcb", "" );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SYMBOL& d )
{
if( j.at( "source" ).is_string() )
@ -221,6 +227,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SYMBOL& d )
d.custom_tags = j.at( "custom_tags" );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_FOOTPRINT& d )
{
if( j.at( "source" ).is_string() )
@ -249,6 +256,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_FOOTPRINT&
d.custom_tags = j.at( "custom_tags" );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_DEVICE& d )
{
if( j.at( "source" ).is_string() )
@ -277,12 +285,14 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_DEVICE& d )
d.attributes = AnyMapToStringMap( j.at( "attributes" ) );
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::BLOB& d )
{
d.objectId = j.at( 1 ).get<wxString>();
d.url = j.at( 3 ).get<wxString>();
}
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::POURED& d )
{
d.pouredId = j.at( 1 ).get<wxString>();
@ -290,4 +300,4 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::POURED& d )
d.unki = j.at( 3 ).get<int>();
d.isPoly = j.at( 4 ).get<bool>();
d.polyData = j.at( 5 );
}
}

View File

@ -43,13 +43,15 @@ wxString IO_BASE::IO_FILE_DESC::FileFilter() const
}
void IO_BASE::CreateLibrary( const wxString& aLibraryPath, const std::map<std::string, UTF8>* aProperties )
void IO_BASE::CreateLibrary( const wxString& aLibraryPath,
const std::map<std::string, UTF8>* aProperties )
{
NOT_IMPLEMENTED( __FUNCTION__ );
}
bool IO_BASE::DeleteLibrary( const wxString& aLibraryPath, const std::map<std::string, UTF8>* aProperties )
bool IO_BASE::DeleteLibrary( const wxString& aLibraryPath,
const std::map<std::string, UTF8>* aProperties )
{
NOT_IMPLEMENTED( __FUNCTION__ );
}

View File

@ -36,17 +36,20 @@ namespace IO_UTILS
extern KICOMMON_API const std::vector<uint8_t> COMPOUND_FILE_HEADER;
/**
* Check if a file starts with a defined string
* @param aFilePath path to the file where we want to check the prefix
* @param aPrefix prefix string which should match with the initial characters in the file
* @param aIgnoreWhitespace true if whitespace characters should be ignored before the prefix
* Check if a file starts with a defined string.
*
* @param aFilePath path to the file where we want to check the prefix.
* @param aPrefix prefix string which should match with the initial characters in the file.
* @param aIgnoreWhitespace true if whitespace characters should be ignored before the prefix.
*/
KICOMMON_API bool fileStartsWithPrefix( const wxString& aFilePath, const wxString& aPrefix, bool aIgnoreWhitespace );
KICOMMON_API bool fileStartsWithPrefix( const wxString& aFilePath, const wxString& aPrefix,
bool aIgnoreWhitespace );
/**
* Check if a file starts with a defined binary header
* @param aFilePath path to the file where we want to check the prefix
* @param aHeader vector of bytes which need to match with the start of the file
* Check if a file starts with a defined binary header.
*
* @param aFilePath path to the file where we want to check the prefix.
* @param aHeader vector of bytes which need to match with the start of the file.
*/
KICOMMON_API bool fileStartsWithBinaryHeader( const wxString& aFilePath,
const std::vector<uint8_t>& aHeader );

View File

@ -108,10 +108,12 @@ static int xferinfo( void* aProgress, curl_off_t aDLtotal, curl_off_t aDLnow, cu
#else
static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double aULtotal, double aULnow )
static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double aULtotal,
double aULnow )
{
return xferinfo( aProgress, static_cast<curl_off_t>( aDLtotal ), static_cast<curl_off_t>( aDLnow ),
static_cast<curl_off_t>( aULtotal ), static_cast<curl_off_t>( aULnow ) );
return xferinfo( aProgress, static_cast<curl_off_t>( aDLtotal ),
static_cast<curl_off_t>( aDLnow ), static_cast<curl_off_t>( aULtotal ),
static_cast<curl_off_t>( aULnow ) );
}
#endif
@ -138,7 +140,9 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
#ifdef _WIN32
long sslOpts = CURLSSLOPT_NATIVE_CA;
POLICY_CURL_SSL_REVOKE policyState = KIPLATFORM::POLICY::GetPolicyEnum<POLICY_CURL_SSL_REVOKE>( POLICY_KEY_REQUESTS_CURL_REVOKE );
POLICY_CURL_SSL_REVOKE policyState = KIPLATFORM::POLICY::GetPolicyEnum<POLICY_CURL_SSL_REVOKE>(
POLICY_KEY_REQUESTS_CURL_REVOKE );
if( policyState == POLICY_CURL_SSL_REVOKE::BEST_EFFORT )
{
sslOpts |= CURLSSLOPT_REVOKE_BEST_EFFORT;
@ -161,7 +165,8 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
wxPlatformInfo platformInfo;
wxString application( wxS( "KiCad" ) );
wxString version( GetBuildVersion() );
wxString platform = wxS( "(" ) + wxGetOsDescription() + wxS( ";" ) + GetPlatformGetBitnessName();
wxString platform = wxS( "(" ) + wxGetOsDescription() + wxS( ";" ) +
GetPlatformGetBitnessName();
#if defined( KICAD_BUILD_ARCH_X64 )
platform << wxS( ";64-bit" );
@ -175,7 +180,8 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
platform << wxS( ")" );
wxString user_agent = wxS( "KiCad/" ) + version + wxS( " " ) + platform + wxS( " " ) + application;
wxString user_agent = wxS( "KiCad/" ) + version + wxS( " " ) + platform + wxS( " " ) +
application;
user_agent << wxS( "/" ) << GetBuildDate();
setOption<const char*>( CURLOPT_USERAGENT, user_agent.ToStdString().c_str() );
@ -333,6 +339,7 @@ bool KICAD_CURL_EASY::SetTransferCallback( const TRANSFER_CALLBACK& aCallback, s
setOption( CURLOPT_PROGRESSFUNCTION, progressinfo );
setOption( CURLOPT_PROGRESSDATA, progress.get() );
#endif
setOption( CURLOPT_NOPROGRESS, 0L );
return true;
}
@ -357,6 +364,7 @@ int KICAD_CURL_EASY::GetTransferTotal( uint64_t& aDownloadedBytes ) const
int result = curl_easy_getinfo( m_CURL, CURLINFO_SIZE_DOWNLOAD, &dl );
aDownloadedBytes = static_cast<uint64_t>( dl );
#endif
return result;
}
@ -367,4 +375,4 @@ int KICAD_CURL_EASY::GetResponseStatusCode()
curl_easy_getinfo( m_CURL, CURLINFO_RESPONSE_CODE, &http_code );
return static_cast<int>( http_code );
}
}

View File

@ -150,7 +150,6 @@ const wxString KIWAY::dso_search_path( FACE_T aFaceId )
// To speed up development, it's sometimes nice to run kicad from inside
// the build path. In that case, each program will be in a subdirectory.
// To find the DSOs, we need to go up one directory and then enter a subdirectory.
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
#ifdef __WXMAC__
@ -317,7 +316,8 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
{
// OnKiFaceStart may generate an exception
// Before we continue and ultimately unload our module to retry we need
// to process the exception before we delete the free the memory space the exception resides in
// to process the exception before we delete the free the memory space the
// exception resides in
Pgm().HandleException( std::current_exception() );
}
@ -327,7 +327,7 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
}
else
{
// Usually means cancelled initial global library setup
// Usually means canceled initial global library setup
// But it could have been an exception/failure
// Let the module go out of scope to unload
dso.Attach( dsoHandle );
@ -666,11 +666,13 @@ void KIWAY::ProjectChanged()
}
}
wxWindow* KIWAY::GetBlockingDialog()
{
return wxWindow::FindWindowById( m_blockingDialog );
}
void KIWAY::SetBlockingDialog( wxWindow* aWin )
{
if( !aWin )

View File

@ -39,7 +39,8 @@
// All things in due course.
const wxEventType KIWAY_EXPRESS::wxEVENT_ID = wxNewEventType();
#else
const wxEventType KIWAY_EXPRESS::wxEVENT_ID = 30000; // common across all link images, hopefully unique.
const wxEventType KIWAY_EXPRESS::wxEVENT_ID = 30000; // common across all link images,
// hopefully unique.
#endif

View File

@ -215,8 +215,8 @@ bool LIB_ID::isLegalChar( unsigned aUniChar )
// This list of characters is also duplicated in validators.cpp and footprint.cpp
// TODO: Unify forbidden character lists - Warning, invalid filename characters are not the same
// as invalid LIB_ID characters. We will need to separate the FP filenames from FP names before this
// can be unified
// as invalid LIB_ID characters. We will need to separate the FP filenames from FP names
// before this can be unified
switch( aUniChar )
{
case ':':

View File

@ -51,6 +51,7 @@ std::unique_ptr<LINE_READER> FILE_LIB_TABLE_IO::GetReader( const wxString& aURI
return std::make_unique<FILE_LINE_READER>( aURI );
}
bool FILE_LIB_TABLE_IO::CanSaveToUri( const wxString& aURI ) const
{
const wxFileName fn( aURI );
@ -61,6 +62,7 @@ bool FILE_LIB_TABLE_IO::CanSaveToUri( const wxString& aURI ) const
return fn.IsFileWritable();
}
bool FILE_LIB_TABLE_IO::UrisAreEquivalent( const wxString& aURI1, const wxString& aURI2 ) const
{
// Avoid comparing filenames as wxURIs
@ -83,6 +85,7 @@ bool FILE_LIB_TABLE_IO::UrisAreEquivalent( const wxString& aURI1, const wxString
}
}
std::unique_ptr<OUTPUTFORMATTER> FILE_LIB_TABLE_IO::GetWriter( const wxString& aURI ) const
{
const wxFileName fn( aURI );
@ -121,7 +124,7 @@ const wxString LIB_TABLE_ROW::GetFullURI( bool aSubstituted ) const
void LIB_TABLE_ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
{
// In Kicad, we save path and file names using the Unix notation (separator = '/')
// In KiCad, we save path and file names using the Unix notation (separator = '/')
// So ensure separator is always '/' is saved URI string
wxString uri = GetFullURI();
uri.Replace( '\\', '/' );
@ -269,7 +272,7 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
}
// Repeat, this time looking for names that were "fixed" by legacy versions because
// the old eeschema file format didn't support spaces in tokens.
// the old Eeschema file format didn't support spaces in tokens.
for( const std::pair<const wxString, LIB_TABLE_ROWS_ITER>& entry : cur->m_rowsMap )
{
wxString legacyLibName = entry.first;
@ -618,7 +621,8 @@ UTF8 LIB_TABLE::FormatOptions( const std::map<std::string, UTF8>* aProperties )
if( aProperties )
{
for( std::map<std::string, UTF8>::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it )
for( std::map<std::string, UTF8>::const_iterator it = aProperties->begin();
it != aProperties->end(); ++it )
{
const std::string& name = it->first;

View File

@ -273,7 +273,9 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
}
ch = m_token.input[++m_token.pos];
// the below static cast is to avoid partial unicode chars triggering an assert in isdigit on msvc
// the below static cast is to avoid partial unicode chars triggering an
// assert in isdigit on msvc
} while( isdigit( static_cast<unsigned char>( ch ) ) || isDecimalSeparator( ch ) );
m_token.token[ idx ] = 0;
@ -305,7 +307,8 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
// Ideally we should also handle the unicode characters that can be used for micro,
// but unicode handling in this tokenizer doesn't work.
// (e.g. add support for μm (µ is MICRO SIGN), µm (µ is GREEK SMALL LETTER MU) later)
// (e.g. add support for μm (µ is MICRO SIGN), µm (µ is GREEK SMALL LETTER MU)
// later)
if( sizeLeft >= 2 && ch == 'u' && cptr[ 1 ] == 'm' && !isalnum( cptr[ 2 ] ) )
{
m_token.pos += 2;
@ -376,7 +379,8 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
}
else if( isdigit( static_cast<unsigned char>( ch ) ) || isDecimalSeparator( ch ) )
{
// the above static cast is to avoid partial unicode chars triggering an assert in isdigit on msvc
// the above static cast is to avoid partial unicode chars triggering an assert in
// isdigit on msvc
// VALUE
extractNumber( &siScaler );
retval.token = VALUE;
@ -484,11 +488,13 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
return retval;
}
void NUMERIC_EVALUATOR::SetVar( const wxString& aString, double aValue )
{
m_varMap[ aString ] = aValue;
}
double NUMERIC_EVALUATOR::GetVar( const wxString& aString )
{
auto it = m_varMap.find( aString );

View File

@ -236,6 +236,7 @@ wxString TOKENIZER::GetChars( const std::function<bool( wxUniChar )>& cond ) con
return rv;
}
bool TOKENIZER::MatchAhead( const wxString& match,
const std::function<bool( wxUniChar )>& stopCond ) const
{
@ -771,6 +772,7 @@ static void prepareTree( LIBEVAL::TREE_NODE *node )
prepareTree( node->leaf[1] );
}
static std::vector<TREE_NODE*> squashParamList( TREE_NODE* root )
{
std::vector<TREE_NODE*> args;

View File

@ -52,9 +52,10 @@
// So we disable alerts during the time a file is read or written
#if !USE_WXLOCALE
#if defined( _WIN32 ) && defined( DEBUG )
// a wxAssertHandler_t function to filter wxWidgets alert messages when reading/writing a file
// when switching the locale to LC_NUMERIC, "C"
// It is used in class LOCALE_IO to hide a useless (in kicad) wxWidgets alert message
// It is used in class LOCALE_IO to hide a useless (in KiCad) wxWidgets alert message
void KiAssertFilter( const wxString &file, int line,
const wxString &func, const wxString &cond,
const wxString &msg)

View File

@ -185,11 +185,6 @@ bool LSET::IsBetween( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, PCB_LAYER_ID aLaye
}
/**
* NOTE: These names must not be translated or changed. They are used as tokens in the board
* file format because the ordinal value of the PCB_LAYER_ID enum was not stable over time.
* @see LayerName() for what should be used to display the default name of a layer in the GUI.
*/
wxString LSET::Name( PCB_LAYER_ID aLayerId )
{
wxString txt;
@ -370,7 +365,8 @@ LSEQ LSET::SeqStackupTop2Bottom( PCB_LAYER_ID aSelectedLayer ) const
for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
seq.push_back( *it );
std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(), std::back_inserter( seq ) );
std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(),
std::back_inserter( seq ) );
if( aSelectedLayer != UNDEFINED_LAYER )
{
@ -601,12 +597,14 @@ LSET LSET::BackTechMask()
return saved;
}
LSET LSET::BackBoardTechMask()
{
static const LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste } );
return saved;
}
LSET LSET::FrontTechMask()
{
static const LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab } );
@ -672,6 +670,7 @@ LSET LSET::BackMask()
return saved;
}
LSET LSET::SideSpecificMask()
{
static const LSET saved = BackTechMask() | FrontTechMask() | AllCuMask();
@ -775,6 +774,7 @@ GAL_SET GAL_SET::DefaultVisible()
return saved;
}
#ifndef SWIG // Skip SWIG generators for the iterators because it requires a default constructor
// Custom iterators for Copper and Non-Copper layers
@ -785,11 +785,13 @@ LSET::copper_layers_iterator::copper_layers_iterator( const BASE_SET& set, size_
advance_to_next_set_copper_bit();
}
PCB_LAYER_ID LSET::copper_layers_iterator::operator*() const
{
return static_cast<PCB_LAYER_ID>( m_index );
}
LSET::copper_layers_iterator& LSET::copper_layers_iterator::operator++()
{
next_copper_layer();
@ -797,6 +799,7 @@ LSET::copper_layers_iterator& LSET::copper_layers_iterator::operator++()
return *this;
}
void LSET::copper_layers_iterator::next_copper_layer()
{
if( m_index == F_Cu )
@ -817,23 +820,27 @@ void LSET::copper_layers_iterator::next_copper_layer()
}
}
void LSET::copper_layers_iterator::advance_to_next_set_copper_bit()
{
while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
next_copper_layer();
}
LSET::non_copper_layers_iterator::non_copper_layers_iterator( const BASE_SET& set, size_t index ) :
BASE_SET::set_bits_iterator( set, index )
{
advance_to_next_set_non_copper_bit();
}
PCB_LAYER_ID LSET::non_copper_layers_iterator::operator*() const
{
return static_cast<PCB_LAYER_ID>( m_index );
}
LSET::non_copper_layers_iterator& LSET::non_copper_layers_iterator::operator++()
{
++m_index;
@ -841,6 +848,7 @@ LSET::non_copper_layers_iterator& LSET::non_copper_layers_iterator::operator++()
return *this;
}
void LSET::non_copper_layers_iterator::advance_to_next_set_non_copper_bit()
{
while( m_index < m_baseSet.size() && ( m_index % 2 != 1 || !m_baseSet.test( m_index ) ) )
@ -849,21 +857,25 @@ void LSET::non_copper_layers_iterator::advance_to_next_set_non_copper_bit()
}
}
LSET::copper_layers_iterator LSET::copper_layers_begin() const
{
return copper_layers_iterator( *this, 0 );
}
LSET::copper_layers_iterator LSET::copper_layers_end() const
{
return copper_layers_iterator( *this, size() );
}
LSET::non_copper_layers_iterator LSET::non_copper_layers_begin() const
{
return non_copper_layers_iterator( *this, 0 );
}
LSET::non_copper_layers_iterator LSET::non_copper_layers_end() const
{
return non_copper_layers_iterator( *this, size() );

View File

@ -38,10 +38,12 @@
#include "dialogs/dialog_display_html_text_base.h"
/* The graphic shape of markers is a polygon.
/**
* The graphic shape of markers is a polygon.
*
* MarkerShapeCorners contains the coordinates of corners of the polygonal default shape
* they are arbitrary units to make coding shape easy.
* internal units coordinates are these values scaled by .m_ScalingFactor
* Internal units coordinates are these values scaled by .m_ScalingFactor
*/
static const VECTOR2I MarkerShapeCorners[] =
{
@ -55,6 +57,7 @@ static const VECTOR2I MarkerShapeCorners[] =
VECTOR2I( 1, 8 ),
VECTOR2I( 0, 0 )
};
const unsigned CORNERS_COUNT = arrayDim( MarkerShapeCorners );

View File

@ -35,7 +35,9 @@
const char NETCLASS::Default[] = "Default";
// Initial values for netclass initialization
const int DEFAULT_CLEARANCE = pcbIUScale.mmToIU( 0.2 ); // track to track and track to pads clearance
// track to track and track to pads clearance.
const int DEFAULT_CLEARANCE = pcbIUScale.mmToIU( 0.2 );
const int DEFAULT_VIA_DIAMETER = pcbIUScale.mmToIU( 0.6 );
const int DEFAULT_VIA_DRILL = pcbIUScale.mmToIU( 0.3 );
const int DEFAULT_UVIA_DIAMETER = pcbIUScale.mmToIU( 0.3 );

View File

@ -73,7 +73,8 @@ public:
m_stTitle = new wxStaticText( this, wxID_ANY, aNoti->title );
m_stTitle->Wrap( -1 );
m_stTitle->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT,
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false,
wxEmptyString ) );
mainSizer->Add( m_stTitle, 0, wxALL | wxEXPAND, 1 );
m_stDescription = new wxStaticText( this, wxID_ANY, aNoti->description, wxDefaultPosition,
@ -206,7 +207,7 @@ public:
m_scrolledWindow->Layout();
m_contentSizer->Fit( m_scrolledWindow );
// call this at this window otherwise the child panels dont resize width properly
// call this at this window otherwise the child panels don't resize width properly
Layout();
m_panelMap[aNoti] = panel;
@ -216,6 +217,7 @@ public:
void Remove( NOTIFICATION* aNoti )
{
auto it = m_panelMap.find( aNoti );
if( it != m_panelMap.end() )
{
NOTIFICATION_PANEL* panel = m_panelMap[aNoti];
@ -237,11 +239,14 @@ public:
private:
wxScrolledWindow* m_scrolledWindow;
///< Inner content of the scrolled window, add panels here
/// Inner content of the scrolled window, add panels here.
wxBoxSizer* m_contentSizer;
std::unordered_map<NOTIFICATION*, NOTIFICATION_PANEL*> m_panelMap;
NOTIFICATIONS_MANAGER* m_manager;
///< Text to be displayed when no notifications are present, this gets a Show/Hide call as needed
/// Text to be displayed when no notifications are present, this gets a Show/Hide call as
/// needed.
wxStaticText* m_noNotificationsText;
};
@ -266,7 +271,7 @@ void NOTIFICATIONS_MANAGER::Load()
}
catch( std::exception& )
{
// failed to load the json, which is fine, default to no notificaitons
// failed to load the json, which is fine, default to no notifications
}
if( wxGetEnv( wxT( "KICAD_TEST_NOTI" ), nullptr ) )
@ -289,9 +294,9 @@ void NOTIFICATIONS_MANAGER::Save()
void NOTIFICATIONS_MANAGER::CreateOrUpdate( const wxString& aKey,
const wxString& aTitle,
const wxString& aDescription,
const wxString& aHref )
const wxString& aTitle,
const wxString& aDescription,
const wxString& aHref )
{
wxCHECK_RET( !aKey.IsEmpty(), wxS( "Notification key must not be empty" ) );
@ -418,4 +423,4 @@ void NOTIFICATIONS_MANAGER::UnregisterStatusBar( KISTATUSBAR* aStatusBar )
{
return statusBar == aStatusBar;
} ) );
}
}

View File

@ -28,6 +28,7 @@
ORIGIN_TRANSFORMS::ORIGIN_TRANSFORMS()
{}
ORIGIN_TRANSFORMS::~ORIGIN_TRANSFORMS()
{}
@ -38,30 +39,35 @@ int ORIGIN_TRANSFORMS::ToDisplay( int aValue,
return static_cast<int>( ToDisplay( static_cast<long long int>( aValue ), aCoordType ) );
}
long long int ORIGIN_TRANSFORMS::ToDisplay( long long int aValue,
COORD_TYPES_T aCoordType ) const
{
return aValue;
}
double ORIGIN_TRANSFORMS::ToDisplay( double aValue,
COORD_TYPES_T aCoordType ) const
{
return aValue;
}
int ORIGIN_TRANSFORMS::FromDisplay( int aValue,
COORD_TYPES_T aCoordType ) const
{
return static_cast<int>( FromDisplay( static_cast<long long int>( aValue ), aCoordType ) );
}
long long int ORIGIN_TRANSFORMS::FromDisplay( long long int aValue,
COORD_TYPES_T aCoordType ) const
{
return aValue;
}
double ORIGIN_TRANSFORMS::FromDisplay( double aValue,
COORD_TYPES_T aCoordType ) const
{

View File

@ -31,8 +31,9 @@
using namespace KIGFX;
ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, int aSize, const VECTOR2D& aPosition ) :
EDA_ITEM( nullptr, NOT_USED ), // this item is never added to a BOARD/SCHEMATIC so it needs no type
ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, int aSize,
const VECTOR2D& aPosition ) :
EDA_ITEM( nullptr, NOT_USED ), // never added to a BOARD/SCHEMATIC so it needs no type
m_position( aPosition ),
m_size( aSize ),
m_color( aColor ),
@ -43,7 +44,7 @@ ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, in
ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const VECTOR2D& aPosition, EDA_ITEM_FLAGS flags ) :
EDA_ITEM( nullptr, NOT_USED ), // this item is never added to a BOARD/SCHEMATIC so it needs no type
EDA_ITEM( nullptr, NOT_USED ), // never added to a BOARD/SCHEMATIC so it needs no type
m_position( aPosition ),
m_size( NOT_USED ),
m_color( UNSPECIFIED_COLOR ),
@ -81,7 +82,7 @@ void ORIGIN_VIEWITEM::ViewDraw( int, VIEW* aView ) const
gal->SetStrokeColor( m_color );
VECTOR2D scaledSize = aView->ToWorld( VECTOR2D( m_size, m_size ), false );
// Draw a circle around the marker's centre point if the style demands it
// Draw a circle around the marker's center point if the style demands it
if( ( m_style == CIRCLE_CROSS ) || ( m_style == CIRCLE_DOT ) || ( m_style == CIRCLE_X ) )
gal->DrawCircle( m_position, fabs( scaledSize.x ) );

View File

@ -83,7 +83,8 @@ const PAGE_INFO PAGE_INFO::pageGERBER( VECTOR2D( 32000, 32000 ), wxT( "GERBER" )
const PAGE_INFO PAGE_INFO::pageUser( VECTOR2D( 17000, 11000 ), Custom, wxPAPER_NONE );
// US paper sizes
const PAGE_INFO PAGE_INFO::pageUSLetter( VECTOR2D( 11000, 8500 ), wxT( "USLetter" ), wxPAPER_LETTER );
const PAGE_INFO PAGE_INFO::pageUSLetter( VECTOR2D( 11000, 8500 ), wxT( "USLetter" ),
wxPAPER_LETTER );
const PAGE_INFO PAGE_INFO::pageUSLegal( VECTOR2D( 14000, 8500 ), wxT( "USLegal" ), wxPAPER_LEGAL );
const PAGE_INFO PAGE_INFO::pageUSLedger( VECTOR2D( 17000, 11000 ), wxT( "USLedger" ),
wxPAPER_TABLOID );
@ -201,7 +202,7 @@ void PAGE_INFO::SetPortrait( bool aIsPortrait )
static double clampWidth( double aWidthInMils )
{
/* was giving EESCHEMA single component SVG plotter grief
However a minimal test is made to avoid values that crashes Kicad
However a minimal test is made to avoid values that crashes KiCad
if( aWidthInMils < 4000 ) // 4" is about a baseball card
aWidthInMils = 4000;
else if( aWidthInMils > 44000 ) //44" is plotter size
@ -209,6 +210,7 @@ static double clampWidth( double aWidthInMils )
*/
if( aWidthInMils < 10 )
aWidthInMils = 10;
return aWidthInMils;
}
@ -217,7 +219,7 @@ static double clampHeight( double aHeightInMils )
{
/* was giving EESCHEMA single component SVG plotter grief
clamping is best done at the UI, i.e. dialog, levels
However a minimal test is made to avoid values that crashes Kicad
However a minimal test is made to avoid values that crashes KiCad
if( aHeightInMils < 4000 )
aHeightInMils = 4000;
else if( aHeightInMils > 44000 )

View File

@ -128,6 +128,7 @@ wxString PATHS::GetDefaultUser3DModelsPath()
return tmp.GetPath();
}
wxString PATHS::GetDefault3rdPartyPath()
{
wxFileName tmp;
@ -138,6 +139,7 @@ wxString PATHS::GetDefault3rdPartyPath()
return tmp.GetPath();
}
wxString PATHS::GetDefaultUserProjectsPath()
{
wxFileName tmp;
@ -177,7 +179,7 @@ static wxString getBuildDirectoryRoot()
wxFileName fn = execPath;
// Climb the directory tree until we find a directory that looks like a build directory
// Noprmally we expect to climb one or two levels only.
// Normally we expect to climb one or two levels only.
while( fn.GetDirCount() > 0 && !looksLikeBuildDir( fn ) )
{
fn.RemoveLastDir();
@ -232,13 +234,12 @@ wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
#ifdef _WIN32
/**
* Gets the stock (install) data path, which is the base path for things like scripting, etc
*/
wxString PATHS::GetWindowsBaseSharePath()
{
return getWindowsKiCadRoot() + wxT( "share\\" );
}
#endif

View File

@ -334,9 +334,9 @@ void PGM_BASE::sentryInit()
sentry_options_t* options = sentry_options_new();
#ifndef KICAD_SENTRY_DSN
# error "Project configuration error, missing KICAD_SENTRY_DSN"
#endif
#ifndef KICAD_SENTRY_DSN
# error "Project configuration error, missing KICAD_SENTRY_DSN"
#endif
sentry_options_set_dsn( options, KICAD_SENTRY_DSN );
@ -509,9 +509,10 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
// their own lock files.
wxString instanceCheckerDir = PATHS::GetInstanceCheckerPath();
PATHS::EnsurePathExists( instanceCheckerDir );
wxChmod( instanceCheckerDir, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
wxChmod( instanceCheckerDir,
wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
wxString instanceCheckerName = wxString::Format( wxS( "%s-%s" ), pgm_name,
GetMajorMinorVersion() );
@ -617,7 +618,7 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
GetNotificationsManager().Load();
// Create the python scripting stuff
// Skip it fot applications that do not use it
// Skip it for applications that do not use it
if( !aSkipPyInit )
m_python_scripting = std::make_unique<SCRIPTING>();
@ -854,7 +855,9 @@ wxString PGM_BASE::GetLanguageTag()
const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo( m_language_id );
if( !langInfo )
{
return "";
}
else
{
wxString str = langInfo->GetCanonicalWithRegion();
@ -868,8 +871,7 @@ wxString PGM_BASE::GetLanguageTag()
void PGM_BASE::SetLanguagePath()
{
#ifdef _MSC_VER
wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath()
+ wxT( "locale" ) );
wxLocale::AddCatalogLookupPathPrefix( PATHS::GetWindowsBaseSharePath() + wxT( "locale" ) );
#endif
wxLocale::AddCatalogLookupPathPrefix( PATHS::GetLocaleDataPath() );
@ -1064,21 +1066,25 @@ void PGM_BASE::WritePdfBrowserInfos()
GetCommonSettings()->m_System.use_system_pdf_viewer = m_use_system_pdf_browser;
}
static PGM_BASE* process;
PGM_BASE& Pgm()
{
wxASSERT( process ); // KIFACE_GETTER has already been called.
return *process;
}
// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face is run from a python script.
PGM_BASE* PgmOrNull()
{
return process;
}
void SetPgm(PGM_BASE* pgm)
void SetPgm( PGM_BASE* pgm )
{
process = pgm;
}

View File

@ -38,19 +38,21 @@
*/
static const double DXF_OBLIQUE_ANGLE = 15;
/* The layer/colors palette. The acad/DXF palette is divided in 3 zones:
/**
* The layer/colors palette.
*
* The acad/DXF palette is divided in 3 zones:
*
* - The primary colors (1 - 9)
* - An HSV zone (10-250, 5 values x 2 saturations x 10 hues
* - Greys (251 - 255)
- The primary colors (1 - 9)
- An HSV zone (10-250, 5 values x 2 saturations x 10 hues
- Greys (251 - 255)
There is *no* black... the white does it on paper, usually, and
anyway it depends on the plotter configuration, since DXF colors
are meant to be logical only (they represent *both* line color and
width); later version with plot styles only complicate the matter!
As usual, brown and magenta/purple are difficult to place since
they are actually variations of other colors.
* There is *no* black... the white does it on paper, usually, and anyway it depends on the
* plotter configuration, since DXF colors are meant to be logical only (they represent *both*
* line color and width); later version with plot styles only complicate the matter!
*
* As usual, brown and magenta/purple are difficult to place since they are actually variations
* of other colors.
*/
static const struct
{
@ -321,6 +323,7 @@ bool DXF_PLOTTER::StartPlot( const wxString& aPageNumber )
"4\n", m_outputFile );
static const char *style_name[4] = {"KICAD", "KICADB", "KICADI", "KICADBI"};
for(int i = 0; i < 4; i++ )
{
fprintf( m_outputFile,
@ -625,6 +628,7 @@ void DXF_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
{
wxASSERT( m_currentLineType >= LINE_STYLE::FIRST_TYPE
&& m_currentLineType <= LINE_STYLE::LAST_TYPE );
// DXF LINE
wxString cname = getDXFColorName( m_currentColor );
const char* lname = getDXFLineType( static_cast<LINE_STYLE>( m_currentLineType ) );
@ -816,6 +820,7 @@ void DXF_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aS
FinishTo( VECTOR2I( poly.CPoint( 0 ).x, poly.CPoint( 0 ).y ) );
}
void DXF_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
OUTLINE_MODE aTraceMode, void* aData )
@ -940,6 +945,7 @@ void DXF_PLOTTER::PlotText( const VECTOR2I& aPos,
void* aData )
{
TEXT_ATTRIBUTES attrs = aAttributes;
// Fix me: see how to use DXF text mode for multiline texts
if( attrs.m_Multiline && !aText.Contains( wxT( "\n" ) ) )
attrs.m_Multiline = false; // the text has only one line.
@ -959,6 +965,7 @@ void DXF_PLOTTER::PlotText( const VECTOR2I& aPos,
}
}
void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor,
const wxString& aText, const TEXT_ATTRIBUTES& aAttributes )
{
@ -1027,7 +1034,8 @@ void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor
TO_UTF8( cname ),
formatCoord( origin_dev.x ).c_str(), formatCoord( origin_dev.x ).c_str(),
formatCoord( origin_dev.y ).c_str(), formatCoord( origin_dev.y ).c_str(),
formatCoord( size_dev.y ).c_str(), formatCoord( fabs( size_dev.x / size_dev.y ) ).c_str(),
formatCoord( size_dev.y ).c_str(),
formatCoord( fabs( size_dev.x / size_dev.y ) ).c_str(),
aAttributes.m_Angle.AsDegrees(),
aAttributes.m_Italic ? DXF_OBLIQUE_ANGLE : 0,
aAttributes.m_Mirrored ? 2 : 0, // X mirror flag

View File

@ -158,6 +158,7 @@ void GERBER_PLOTTER::emitDcode( const VECTOR2D& pt, int dcode )
fprintf( m_outputFile, "X%dY%dD%02d*\n", KiROUND( pt.x ), KiROUND( pt.y ), dcode );
}
void GERBER_PLOTTER::ClearAllAttributes()
{
// Remove all attributes from object attributes dictionary (TO. and TA commands)
@ -569,6 +570,7 @@ void GERBER_PLOTTER::selectAperture( int aDiameter, const EDA_ANGLE& aPolygonRot
selectAperture( VECTOR2I( 0, 0 ), aDiameter / 2, aPolygonRotation, aType, aApertureAttribute );
}
void GERBER_PLOTTER::writeApertureList()
{
wxASSERT( m_outputFile );
@ -709,7 +711,6 @@ void GERBER_PLOTTER::writeApertureList()
break;
}
// Output all corners (should be 4 to 8 corners)
// Remember: the Y coordinate must be negated, due to the fact in Pcbnew
// the Y axis is from top to bottom
@ -730,8 +731,10 @@ void GERBER_PLOTTER::writeApertureList()
{
// the seg_len is the distance between the 2 circle centers
int seg_len = tool.m_Size.x - tool.m_Size.y;
// Center of the circle on the segment start point:
VECTOR2I start( seg_len/2, 0 );
// Center of the circle on the segment end point:
VECTOR2I end( - seg_len/2, 0 );
@ -904,6 +907,7 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
end.x = KiROUND( aCenter.x + aRadius * aEndAngle.Cos() );
end.y = KiROUND( aCenter.y + aRadius * aEndAngle.Sin() );
VECTOR2D devEnd = userToDeviceCoordinates( end );
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
@ -1093,6 +1097,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
}
}
void GERBER_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
void * aData )
{
@ -1245,7 +1250,7 @@ void GERBER_PLOTTER::ThickCircle( const VECTOR2I& pos, int diametre, int width,
void GERBER_PLOTTER::FilledCircle( const VECTOR2I& pos, int diametre,
OUTLINE_MODE tracemode, void* aData )
OUTLINE_MODE tracemode, void* aData )
{
// A filled circle is a graphic item, not a pad.
// So it is drawn, not flashed.
@ -1356,6 +1361,7 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
emitDcode( pos_device, 3 );
return;
}
// Draw the oval as round rect pad with a radius = 50% min size)
// In gerber file, it will be drawn as a region with arcs, and can be
// detected as pads (similar to a flashed pad)
@ -1393,8 +1399,8 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
// so use it for rotation n*90 deg
if( aOrient.IsCardinal() )
{
// Build the not rotated equivalent shape:
if( aOrient.IsCardinal90() )
// Build the not rotated equivalent shape:
std::swap( size.x, size.y );
if( aTraceMode == SKETCH )
@ -1440,11 +1446,11 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
{
// plot pad shape as Gerber region
VECTOR2I coord[4];
// coord[0] is assumed the lower left
// coord[1] is assumed the upper left
// coord[2] is assumed the upper right
// coord[3] is assumed the lower right
coord[0].x = -size.x/2; // lower left
coord[0].y = size.y/2;
coord[1].x = -size.x/2; // upper left
@ -1459,9 +1465,10 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
}
}
void GERBER_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
int aCornerRadius, const EDA_ANGLE& aOrient,
OUTLINE_MODE aTraceMode, void* aData )
int aCornerRadius, const EDA_ANGLE& aOrient,
OUTLINE_MODE aTraceMode, void* aData )
{
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
@ -1475,6 +1482,7 @@ void GERBER_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I&
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
std::vector<VECTOR2I> cornerList;
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
cornerList.reserve( poly.PointCount() + 1 );
@ -1714,7 +1722,7 @@ void GERBER_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aS
}
else
{
// An AM will be created. the shape must be in position 0,0 and orientation 0
// An AM will be created. the shape must be in position 0,0 and orientation 0
// to be able to reuse the same AM for pads having the same shape
for( size_t ii = 0; ii < cornerList.size(); ii++ )
{
@ -1773,7 +1781,9 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const
cornerList.push_back( cornerList[0] );
if( aPlotMode == SKETCH )
{
PlotPoly( cornerList, FILL_T::NO_FILL, GetCurrentLineWidth(), &gbr_metadata );
}
else
{
#ifdef GBR_USE_MACROS_FOR_CHAMFERED_ROUND_RECT
@ -1783,7 +1793,7 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const
}
else
{
// An AM will be created. the shape must be in position 0,0 and orientation 0
// An AM will be created. the shape must be in position 0,0 and orientation 0
// to be able to reuse the same AM for pads having the same shape
for( size_t ii = 0; ii < cornerList.size(); ii++ )
{
@ -1898,6 +1908,7 @@ void GERBER_PLOTTER::FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aC
{
m_hasApertureOutline4P = true;
VECTOR2D pos_dev = userToDeviceCoordinates( aPadPos );
// polygon corners list
std::vector<VECTOR2I> corners = { aCorners[0], aCorners[1], aCorners[2], aCorners[3] };
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
@ -2004,6 +2015,7 @@ void GERBER_PLOTTER::PlotText( const VECTOR2I& aPos,
PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aFontMetrics, aData );
}
void GERBER_PLOTTER::SetLayerPolarity( bool aPositive )
{
if( aPositive )

View File

@ -482,9 +482,10 @@ void PDF_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
if( image.HasAlpha() != aCurrImage.HasAlpha() )
continue;
if( image.HasMask() != aCurrImage.HasMask() || image.GetMaskRed() != aCurrImage.GetMaskRed()
|| image.GetMaskGreen() != aCurrImage.GetMaskGreen()
|| image.GetMaskBlue() != aCurrImage.GetMaskBlue() )
if( image.HasMask() != aCurrImage.HasMask()
|| image.GetMaskRed() != aCurrImage.GetMaskRed()
|| image.GetMaskGreen() != aCurrImage.GetMaskGreen()
|| image.GetMaskBlue() != aCurrImage.GetMaskBlue() )
continue;
int pixCount = image.GetWidth() * image.GetHeight();
@ -492,7 +493,8 @@ void PDF_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
if( memcmp( image.GetData(), aCurrImage.GetData(), pixCount * 3 ) != 0 )
continue;
if( image.HasAlpha() && memcmp( image.GetAlpha(), aCurrImage.GetAlpha(), pixCount ) != 0 )
if( image.HasAlpha()
&& memcmp( image.GetAlpha(), aCurrImage.GetAlpha(), pixCount ) != 0 )
continue;
return imgHandle;
@ -886,7 +888,6 @@ void PDF_PLOTTER::ClosePage()
pageOutlineName = wxString::Format( _( "%s (Page %s)" ), m_pageName, m_pageNumbers.back() );
}
int actionHandle = emitGoToAction( pageHandle );
OUTLINE_NODE* pageOutlineNode =
addOutlineNode( m_outlineRoot.get(), actionHandle, pageOutlineName );
@ -1477,7 +1478,6 @@ function ShM(aEntries) {
">>\n", (long) m_pageHandles.size() );
closePdfObject();
// The info dictionary
int infoDictHandle = startPdfObject();
char date_buf[250];

View File

@ -558,6 +558,7 @@ void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
radius_device, startAngle.AsDegrees(), endAngle.AsDegrees(), getFillId( aFill ) );
}
void PS_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
void* aData )
{
@ -900,7 +901,6 @@ bool PS_PLOTTER::EndPlot()
}
void PS_PLOTTER::Text( const VECTOR2I& aPos,
const COLOR4D& aColor,
const wxString& aText,

View File

@ -102,7 +102,7 @@
// During tests, we (JPC) found issues when the coordinates used 6 digits in mantissa
// especially for stroke-width using very small (but not null) values < 0.00001 mm
// So to avoid this king of issue, we are using 4 digits in mantissa
// The resolution (m_precision ) is 0.1 micron, that looks enougt for a SVG file
// The resolution (m_precision ) is 0.1 micron, that looks enough for a SVG file
/**
* Translates '<' to "&lt;", '>' to "&gt;" and so on, according to the spec:
@ -251,11 +251,11 @@ void SVG_PLOTTER::setSVGPlotStyle( int aLineWidth, bool aIsGroup, const std::str
}
else
{
// Fix a strange issue found in Inkscape: aWidth < 100 nm create issues on degrouping objects
// Fix a strange issue found in Inkscape: aWidth < 100 nm create issues on degrouping
// objects.
// So we use only 4 digits in mantissa for stroke-width.
// TODO: perhaps used only 3 or 4 digits in mantissa for all values in mm, because some
// issues were previously reported reported when using nm as integer units
fprintf( m_outputFile, "\nstroke:#%6.6lX; stroke-width:%.*f; stroke-opacity:1; \n",
m_pen_rgb_color, m_precision, pen_w );
fputs( "stroke-linecap:round; stroke-linejoin:round;", m_outputFile );
@ -317,7 +317,6 @@ void SVG_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
aWidth = m_renderSettings->GetDefaultPenWidth();
// Note: aWidth == 0 is fine: used for filled shapes with no outline thickness
wxASSERT_MSG( aWidth >= 0, "Plotter called to set negative pen width" );
if( aWidth != m_currentPenWidth )
@ -346,7 +345,7 @@ void SVG_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
int red = (int) ( 255.0 * r );
int green = (int) ( 255.0 * g );
int blue = (int) ( 255.0 * b );
long rgb_color = (red << 16) | (green << 8) | blue;
long rgb_color = ( red << 16 ) | ( green << 8 ) | blue;
if( m_pen_rgb_color != rgb_color || m_brush_alpha != a )
{
@ -452,7 +451,6 @@ void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
*
* The arc is drawn in an anticlockwise direction from the start point to the end point.
*/
if( aRadius <= 0 )
{
Circle( aCenter, aWidth, FILL_T::FILLED_SHAPE, 0 );
@ -528,7 +526,8 @@ void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
if( m_graphics_changed )
setSVGPlotStyle( GetCurrentLineWidth() );
fprintf( m_outputFile, "<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f L %.*f %.*f Z\" />\n",
fprintf( m_outputFile,
"<path d=\"M%.*f %.*f A%.*f %.*f 0.0 %d %d %.*f %.*f L %.*f %.*f Z\" />\n",
m_precision, start.x,
m_precision, start.y,
m_precision, radius_device,
@ -780,7 +779,8 @@ bool SVG_PLOTTER::StartPlot( const wxString& aPageNumber )
// Write viewport pos and size
VECTOR2D origin; // TODO set to actual value
fprintf( m_outputFile, " width=\"%.*fmm\" height=\"%.*fmm\" viewBox=\"%.*f %.*f %.*f %.*f\">\n",
fprintf( m_outputFile,
" width=\"%.*fmm\" height=\"%.*fmm\" viewBox=\"%.*f %.*f %.*f %.*f\">\n",
m_precision, (double) m_paperSize.x / m_IUsPerDecimil * 2.54 / 1000,
m_precision, (double) m_paperSize.y / m_IUsPerDecimil * 2.54 / 1000,
m_precision, origin.x, m_precision, origin.y,
@ -879,7 +879,8 @@ void SVG_PLOTTER::Text( const VECTOR2I& aPos,
// aSize.x or aSize.y is < 0 for mirrored texts.
// The actual text size value is the absolute value
text_size.x = std::abs( GRTextWidth( aText, aFont, aSize, aWidth, aBold, aItalic, aFontMetrics ) );
text_size.x = std::abs( GRTextWidth( aText, aFont, aSize, aWidth, aBold, aItalic,
aFontMetrics ) );
text_size.y = std::abs( aSize.x * 4/3 ); // Hershey font height to em size conversion
VECTOR2D anchor_pos_dev = userToDeviceCoordinates( aPos );
VECTOR2D text_pos_dev = userToDeviceCoordinates( text_pos );

View File

@ -146,7 +146,7 @@ double PLOTTER::GetDashGapLenIU( int aLineWidth ) const
return userToDeviceSize( m_renderSettings->GetGapLength( aLineWidth ) );
}
#include <wx/log.h>
void PLOTTER::Arc( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd, FILL_T aFill,
int aWidth )
{
@ -232,7 +232,6 @@ void PLOTTER::BezierCurve( const VECTOR2I& aStart, const VECTOR2I& aControl1,
int aTolerance, int aLineThickness )
{
// Generic fallback: Quadratic Bezier curve plotted as a polyline
std::vector<VECTOR2I> ctrlPoints;
ctrlPoints.reserve( 4 );
@ -631,9 +630,9 @@ void PLOTTER::ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width,
{
SetCurrentLineWidth( -1 );
VECTOR2I offsetp1( p1.x - ( width - m_currentPenWidth ) / 2,
p1.y - (width - m_currentPenWidth) / 2 );
p1.y - ( width - m_currentPenWidth ) / 2 );
VECTOR2I offsetp2( p2.x + ( width - m_currentPenWidth ) / 2,
p2.y + (width - m_currentPenWidth) / 2 );
p2.y + ( width - m_currentPenWidth ) / 2 );
Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 );
offsetp1.x += ( width - m_currentPenWidth );
offsetp1.y += ( width - m_currentPenWidth );
@ -751,6 +750,7 @@ void PLOTTER::Text( const VECTOR2I& aPos,
aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );
}
void PLOTTER::PlotText( const VECTOR2I& aPos,
const COLOR4D& aColor,
const wxString& aText,

View File

@ -51,27 +51,32 @@ const BOX2I ANCHOR_DEBUG::ViewBBox() const
return bbox;
}
std::vector<int> ANCHOR_DEBUG::ViewGetLayers() const
{
return { LAYER_GP_OVERLAY };
}
void ANCHOR_DEBUG::ClearAnchors()
{
m_nearest.reset();
m_anchors.clear();
}
void ANCHOR_DEBUG::AddAnchor( const VECTOR2I& aAnchor )
{
m_anchors[aAnchor]++;
}
void ANCHOR_DEBUG::SetNearest( const OPT_VECTOR2I& aNearest )
{
m_nearest = aNearest;
}
void ANCHOR_DEBUG::ViewDraw( int, VIEW* aView ) const
{
GAL& gal = *aView->GetGAL();
@ -99,6 +104,7 @@ void ANCHOR_DEBUG::ViewDraw( int, VIEW* aView ) const
const KIFONT::FONT& font = *KIFONT::FONT::GetFont();
std::size_t total = 0;
for( const auto& [anchor, count] : m_anchors )
{
if( m_nearest && *m_nearest == anchor )

View File

@ -52,7 +52,7 @@ const BOX2I ARC_ASSISTANT::ViewBBox() const
if( m_constructMan.IsReset() )
return tmp;
// this is an edit-time artefact; no reason to try and be smart with the bounding box
// this is an edit-time artifact; no reason to try and be smart with the bounding box
// (besides, we can't tell the text extents without a view to know what the scale is)
tmp.SetMaximum();
return tmp;
@ -94,7 +94,8 @@ void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
cursorStrings.push_back(
DimensionLabel( "r", m_constructMan.GetRadius(), m_iuScale, m_units ) );
cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), initAngle.AsDegrees(), m_iuScale,
cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ),
initAngle.AsDegrees(), m_iuScale,
EDA_UNITS::DEGREES ) );
}
else

View File

@ -49,7 +49,7 @@ const BOX2I BEZIER_ASSISTANT::ViewBBox() const
if( m_constructMan.IsReset() )
return tmp;
// this is an edit-time artefact; no reason to try and be smart with the bounding box
// this is an edit-time artifact; no reason to try and be smart with the bounding box
// (besides, we can't tell the text extents without a view to know what the scale is)
tmp.SetMaximum();
return tmp;
@ -83,8 +83,9 @@ void BEZIER_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
if( step >= BEZIER_GEOM_MANAGER::BEZIER_STEPS::SET_CONTROL2 )
{
const VECTOR2I c2vec = m_constructMan.GetControlC2() - m_constructMan.GetEnd();
// Draw the second control point control line as a double length line
// centred on the end point
// centered on the end point
preview_ctx.DrawLineDashed( m_constructMan.GetEnd() - c2vec, m_constructMan.GetControlC2(),
dashSize, dashSize / 2, false );
}

View File

@ -46,16 +46,19 @@ VECTOR2I BEZIER_GEOM_MANAGER::GetStart() const
return m_start;
}
VECTOR2I BEZIER_GEOM_MANAGER::GetControlC1() const
{
return m_controlC1;
}
VECTOR2I BEZIER_GEOM_MANAGER::GetEnd() const
{
return m_end;
}
VECTOR2I BEZIER_GEOM_MANAGER::GetControlC2() const
{
// The actual bezier C2 point is the reflection over the end point
@ -63,10 +66,12 @@ VECTOR2I BEZIER_GEOM_MANAGER::GetControlC2() const
return m_end - ( m_controlC2 - m_end );
}
bool BEZIER_GEOM_MANAGER::setStart( const VECTOR2I& aStart )
{
m_start = aStart;
// Prevents wierd-looking loops if the control points aren't initialized
// Prevents weird-looking loops if the control points aren't initialized
m_end = aStart;
m_controlC1 = aStart;
m_controlC2 = aStart;
@ -83,6 +88,7 @@ bool BEZIER_GEOM_MANAGER::setControlC1( const VECTOR2I& aControlC1 )
return true;
}
bool BEZIER_GEOM_MANAGER::setEnd( const VECTOR2I& aEnd )
{
m_end = aEnd;
@ -90,9 +96,11 @@ bool BEZIER_GEOM_MANAGER::setEnd( const VECTOR2I& aEnd )
return m_end != m_start;
}
bool BEZIER_GEOM_MANAGER::setControlC2( const VECTOR2I& aControlC2 )
{
m_controlC2 = aControlC2;
// It's possible to set the control 2 point to the same as the end point
return true;
}

View File

@ -44,20 +44,23 @@ void CONSTRUCTION_GEOM::AddDrawable( const DRAWABLE& aItem, bool aPersistent )
m_drawables.push_back( { aItem, aPersistent } );
}
void CONSTRUCTION_GEOM::ClearDrawables()
{
m_drawables.clear();
}
const BOX2I CONSTRUCTION_GEOM::ViewBBox() const
{
// We could be a bit more circumspect here, but much of the time the
// enxtended lines go across the whole screen anyway
// extended lines go across the whole screen anyway
BOX2I bbox;
bbox.SetMaximum();
return bbox;
}
void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
{
GAL& gal = *aView->GetGAL();
@ -142,6 +145,7 @@ void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
const int dashSizeBasis = aView->ToWorld( 12 );
const int snapOriginMarkerSize = aView->ToWorld( 16 );
// Avoid clash with the snap marker if very close
const int omitStartMarkerIfWithinLength = aView->ToWorld( 8 );
@ -157,8 +161,9 @@ void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
}
}
std::vector<int> CONSTRUCTION_GEOM::ViewGetLayers() const
{
std::vector<int> layers{ LAYER_GP_OVERLAY };
return layers;
}
}

View File

@ -42,6 +42,7 @@ void KIGFX::DrawDashedLine( GAL& aGal, const SEG& aSeg, double aDashSize )
{
const std::array<double, 2> strokes = { aDashSize, aDashSize / 2 };
const double dashCycleLen = strokes[0] + strokes[1];
// The dash cycle length must be at least 1 pixel.
wxASSERT( dashCycleLen * aGal.GetWorldScale() > 1 );
@ -53,12 +54,14 @@ void KIGFX::DrawDashedLine( GAL& aGal, const SEG& aSeg, double aDashSize )
dashCycleLen * cos( theta ),
dashCycleLen * sin( theta ),
};
const VECTOR2D dashVec{
strokes[0] * cos( theta ),
strokes[0] * sin( theta ),
};
unsigned cyclei = 0;
while( true )
{
const VECTOR2D dashStart = aSeg.A + cycleVec * cyclei;
@ -73,4 +76,4 @@ void KIGFX::DrawDashedLine( GAL& aGal, const SEG& aSeg, double aDashSize )
aGal.DrawLine( dashSeg.A, dashSeg.B );
++cyclei;
}
}
}

View File

@ -110,8 +110,8 @@ static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace, EDA
/**
* Draw labelled ticks on a line. Ticks are spaced according to a
* maximum density. Minor ticks are not labelled.
* Draw labeled ticks on a line. Ticks are spaced according to a
* maximum density. Minor ticks are not labeled.
*
* @param aGal the GAL to draw on
* @param aOrigin start of line to draw ticks on
@ -119,7 +119,8 @@ static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace, EDA
* @param aMinorTickLen length of minor ticks in IU
*/
void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
double aMinorTickLen, const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits, bool aDrawingDropShadows )
double aMinorTickLen, const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
bool aDrawingDropShadows )
{
KIGFX::GAL* gal = aView->GetGAL();
KIFONT::FONT* font = KIFONT::FONT::GetFont();
@ -146,6 +147,7 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
{
labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
shadowXoffset = labelDims.ShadowWidth;
// Due to the fact a shadow text is drawn left or right aligned,
// it needs an offset = shadowXoffset to be drawn at the same place as normal text
// But for some reason we need to slightly modify this offset
@ -266,8 +268,8 @@ void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTO
}
RULER_ITEM::RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& aGeomMgr, const EDA_IU_SCALE& aIuScale, EDA_UNITS userUnits,
bool aFlipX, bool aFlipY )
RULER_ITEM::RULER_ITEM( const TWO_POINT_GEOMETRY_MANAGER& aGeomMgr, const EDA_IU_SCALE& aIuScale,
EDA_UNITS userUnits, bool aFlipX, bool aFlipY )
: EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
m_geomMgr( aGeomMgr ),
m_userUnits( userUnits ),
@ -393,4 +395,4 @@ wxArrayString RULER_ITEM::GetDimensionStrings() const
cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), angle.AsDegrees(),
m_iuScale, EDA_UNITS::DEGREES ) );
return cursorStrings;
}
}

View File

@ -118,6 +118,7 @@ void SELECTION_AREA::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
gal.SetIsFill( false );
gal.DrawRectangle( m_origin, m_end );
gal.SetIsFill( true );
// draw the fill as the second object so that Z test will not clamp
// the single-pixel-wide rectangle sides
gal.DrawRectangle( m_origin, m_end );

View File

@ -68,6 +68,7 @@ static void DrawCornerIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
DrawSnapNode( aGal, corner, nodeRad );
}
static void DrawLineEndpointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int nodeRadius = aSize / 8;
@ -77,6 +78,7 @@ static void DrawLineEndpointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSiz
aGal.DrawLine( lineStart, lineStart + VECTOR2I( aSize - nodeRadius, 0 ) );
}
static void DrawMidpointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int nodeRadius = aSize / 8;
@ -85,6 +87,7 @@ static void DrawMidpointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
aGal.DrawLine( aPosition - VECTOR2I( aSize / 2, 0 ), aPosition + VECTOR2I( aSize / 2, 0 ) );
}
static void DrawCentrePointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int ringRadius = aSize / 4;
@ -95,6 +98,7 @@ static void DrawCentrePointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize
aGal.DrawLine( aPosition - VECTOR2I( 0, aSize / 2 ), aPosition + VECTOR2I( 0, aSize / 2 ) );
}
static void DrawQuadrantPointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int nodeRadius = aSize / 8;
@ -110,6 +114,7 @@ static void DrawQuadrantPointIcon( GAL& aGal, const VECTOR2I& aPosition, int aSi
EDA_ANGLE( 140, EDA_ANGLE_T::DEGREES_T ) );
}
static void DrawIntersectionIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int nodeRadius = aSize / 8;
@ -124,6 +129,7 @@ static void DrawIntersectionIcon( GAL& aGal, const VECTOR2I& aPosition, int aSiz
aGal.DrawLine( aPosition - xLeg, aPosition + xLeg );
}
static void DrawOnElementIcon( GAL& aGal, const VECTOR2I& aPosition, int aSize )
{
const int nodeRadius = aSize / 8;

View File

@ -43,7 +43,8 @@
class PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER : public wxDirTraverser
{
public:
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER( const std::string& aExtRegex, const wxString& aPrjDir, wxZipOutputStream& aZipFileOutput,
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER( const std::string& aExtRegex, const wxString& aPrjDir,
wxZipOutputStream& aZipFileOutput,
REPORTER& aReporter, bool aVerbose ) :
m_zipFile( aZipFileOutput ),
m_prjDir( aPrjDir ),
@ -91,7 +92,7 @@ public:
}
private:
void addFileToZip( const wxString& aFilename)
void addFileToZip( const wxString& aFilename )
{
wxString msg;
wxFileSystem fsfile;
@ -104,7 +105,7 @@ private:
KIPLATFORM::IO::LongPathAdjustment( curr_prjdir );
// Note: MakeRelativeTo() works only if curr_fn and curr_prjdir use the same
// long path adjustement (no long path of both use long path)
// long path adjustment (no long path of both use long path)
curr_fn.MakeRelativeTo( curr_prjdir.GetFullPath() );
wxString currFilename = curr_fn.GetFullPath();
@ -154,10 +155,12 @@ private:
unsigned long m_uncompressedBytes = 0;
};
PROJECT_ARCHIVER::PROJECT_ARCHIVER()
{
}
bool PROJECT_ARCHIVER::AreZipArchivesIdentical( const wxString& aZipFileA,
const wxString& aZipFileB, REPORTER& aReporter )
{
@ -247,6 +250,7 @@ bool PROJECT_ARCHIVER::Unarchive( const wxString& aSrcFile, const wxString& aDes
// Now let's set the filetimes based on what's in the zip
wxFileName outputFileName( fullname );
wxDateTime fileTime = entry->GetDateTime();
// For now we set access, mod, create to the same datetime
// create (third arg) is only used on Windows
outputFileName.SetTimes( &fileTime, &fileTime, &fileTime );
@ -360,7 +364,7 @@ bool PROJECT_ARCHIVER::Archive( const wxString& aSrcDir, const wxString& aDestFi
try
{
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER traverser( fileExtensionRegex, aSrcDir, zipstream,
aReporter, aVerbose );
aReporter, aVerbose );
projectDir.Traverse( traverser );

View File

@ -147,10 +147,6 @@ PROJECT_FILE::PROJECT_FILE( const wxString& aFullPath ) :
}
/**
* Schema version 2: Bump for KiCad 9 layer numbering changes
* Migrate layer presets to use new enum values for copper layers
*/
bool PROJECT_FILE::migrateSchema1To2()
{
auto p( "/board/layer_presets"_json_pointer );
@ -169,9 +165,6 @@ bool PROJECT_FILE::migrateSchema1To2()
}
/**
* Schema version 3: move layer presets to use named render layers
*/
bool PROJECT_FILE::migrateSchema2To3()
{
auto p( "/board/layer_presets"_json_pointer );
@ -326,7 +319,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
fromLegacy<int>( aCfg, "JunctionSize", "schematic.drawing.default_junction_size" );
fromLegacyString( aCfg, "FieldNameTemplates", "schematic.drawing.field_names" );
fromLegacyString( aCfg, "FieldNameTemplates", "schematic.drawing.field_names" );
if( !fromLegacy<double>( aCfg, "TextOffsetRatio", "schematic.drawing.text_offset_ratio" ) )
{
@ -418,7 +411,8 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
fromLegacy<bool>( aCfg, "CopperTextUpright", bp + "defaults.copper_text_upright" );
if( !fromLegacy<double>( aCfg, "EdgeCutLineWidth", bp + "defaults.board_outline_line_width" ) )
fromLegacy<double>( aCfg, "BoardOutlineThickness", bp + "defaults.board_outline_line_width" );
fromLegacy<double>( aCfg, "BoardOutlineThickness",
bp + "defaults.board_outline_line_width" );
fromLegacy<double>( aCfg, "CourtyardLineWidth", bp + "defaults.courtyard_line_width" );
@ -640,8 +634,8 @@ bool PROJECT_FILE::SaveToFile( const wxString& aDirectory, bool aForce )
// Even if parameters were not modified, we should resave after migration
bool force = aForce || m_wasMigrated;
// If we're actually going ahead and doing the save, the flag that keeps code from doing the save
// should be cleared at this
// If we're actually going ahead and doing the save, the flag that keeps code from doing the
// save should be cleared at this.
m_wasMigrated = false;
return JSON_SETTINGS::SaveToFile( aDirectory, force );

View File

@ -493,8 +493,8 @@ bool PROJECT_LOCAL_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce
// Even if parameters were not modified, we should resave after migration
bool force = aForce || m_wasMigrated;
// If we're actually going ahead and doing the save, the flag that keeps code from doing the save
// should be cleared at this point
// If we're actually going ahead and doing the save, the flag that keeps code from doing the
// save should be cleared at this point.
m_wasMigrated = false;
return JSON_SETTINGS::SaveToFile( aDirectory, force );
@ -506,8 +506,8 @@ bool PROJECT_LOCAL_SETTINGS::SaveAs( const wxString& aDirectory, const wxString&
Set( "meta.filename", aFile + "." + FILEEXT::ProjectLocalSettingsFileExtension );
SetFilename( aFile );
// If we're actually going ahead and doing the save, the flag that keeps code from doing the save
// should be cleared at this point
// If we're actually going ahead and doing the save, the flag that keeps code from doing the
// save should be cleared at this point.
m_wasMigrated = false;
return JSON_SETTINGS::SaveToFile( aDirectory, true );

View File

@ -66,7 +66,7 @@ bool EDA_ANGLE_VARIANT_DATA::Read( wxString& aString )
bool EDA_ANGLE_VARIANT_DATA::Write( wxString& aString ) const
{
aString = wxString::Format( wxT("%g\u00B0"), m_angle.AsDegrees() );
aString = wxString::Format( wxT( "%g\u00B0" ), m_angle.AsDegrees() );
return true;
}

View File

@ -450,6 +450,7 @@ void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl )
}
else if( !aProperty->IsValueUnspecified() )
{
wxFAIL_MSG( wxT( "PG_RATIO_EDITOR should only be used with scale-free numeric properties!" ) );
wxFAIL_MSG( wxT( "PG_RATIO_EDITOR should only be used with scale-free numeric "
"properties!" ) );
}
}

View File

@ -70,9 +70,13 @@ private:
};
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<std::optional<int>>() );
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl::s_instance(
new wxAnyValueTypeImpl<std::optional<int>>() );
static wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl s_wxAnyToSTD_OPTIONAL_INT_VARIANTRegistration( &STD_OPTIONAL_INT_VARIANT_DATA::VariantDataFactory );
static wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl
s_wxAnyToSTD_OPTIONAL_INT_VARIANTRegistration(
&STD_OPTIONAL_INT_VARIANT_DATA::VariantDataFactory );
class wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
@ -108,9 +112,13 @@ private:
};
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<std::optional<double>>() );
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl::s_instance(
new wxAnyValueTypeImpl<std::optional<double>>() );
static wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl s_wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistration( &STD_OPTIONAL_DOUBLE_VARIANT_DATA::VariantDataFactory );
static wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl
s_wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistration(
&STD_OPTIONAL_DOUBLE_VARIANT_DATA::VariantDataFactory );
class wxAnyToEDA_ANGLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
@ -146,9 +154,12 @@ private:
};
wxAnyValueTypeScopedPtr wxAnyToEDA_ANGLE_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<EDA_ANGLE>() );
wxAnyValueTypeScopedPtr
wxAnyToEDA_ANGLE_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<EDA_ANGLE>() );
static wxAnyToEDA_ANGLE_VARIANTRegistrationImpl s_wxAnyToEDA_ANGLE_VARIANTRegistration( &EDA_ANGLE_VARIANT_DATA::VariantDataFactory );
static wxAnyToEDA_ANGLE_VARIANTRegistrationImpl
s_wxAnyToEDA_ANGLE_VARIANTRegistration( &EDA_ANGLE_VARIANT_DATA::VariantDataFactory );
class wxAnyToCOLOR4D_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
@ -183,9 +194,13 @@ private:
static wxAnyValueTypeScopedPtr s_instance;
};
wxAnyValueTypeScopedPtr wxAnyToCOLOR4D_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<KIGFX::COLOR4D>() );
static wxAnyToCOLOR4D_VARIANTRegistrationImpl s_wxAnyToCOLOR4D_VARIANTRegistration( &COLOR4D_VARIANT_DATA::VariantDataFactory );
wxAnyValueTypeScopedPtr wxAnyToCOLOR4D_VARIANTRegistrationImpl::s_instance(
new wxAnyValueTypeImpl<KIGFX::COLOR4D>() );
static wxAnyToCOLOR4D_VARIANTRegistrationImpl
s_wxAnyToCOLOR4D_VARIANTRegistration( &COLOR4D_VARIANT_DATA::VariantDataFactory );
wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* aFrame )
@ -274,6 +289,7 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME*
ret = new wxPropertyCategory();
ret->Enable( false );
}
break;
}
}

View File

@ -301,6 +301,7 @@ void PROPERTY_MANAGER::CLASS_DESC::rebuild()
PROPERTY_SET masked;
m_allProperties.clear();
collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked );
// We need to keep properties sorted to be able to use std::set_* functions
sort( m_allProperties.begin(), m_allProperties.end() );

View File

@ -35,22 +35,20 @@
typedef PTREE::const_iterator CITER;
typedef PTREE::iterator ITER;
#if defined(DEBUG)
#define D(x) x
#if defined( DEBUG )
#define D( x ) x
#else
#define D(x)
#define D( x )
#endif
#define CTL_OMIT_NL (1<<0)
#define CTL_IN_ATTRS (1<<1)
#define CTL_OMIT_NL ( 1 << 0 )
#define CTL_IN_ATTRS ( 1 << 1 )
//-----<Scan>------------------------------------------------------------------
/**
* Function scanList
* reads a sexpr list from the input stream into a new node with key
* aLexer->CurText().
* Read a sexpr list from the input stream into a new node with key aLexer->CurText().
*/
inline void scanList( PTREE* aTree, DSNLEXER* aLexer )
{
@ -175,14 +173,14 @@ static void formatNode( OUTPUTFORMATTER* out, int aNestLevel, int aCtl,
if( aTree.size() && !isAtom( aTree.begin()->second ) && !aTree.data().size() )
ctl = 0;
out->Print( aNestLevel, "(%s%s", out->Quotes( aKey ).c_str(), ctl & CTL_OMIT_NL ? "" : "\n" );
out->Print( aNestLevel, "(%s%s", out->Quotes( aKey ).c_str(),
ctl & CTL_OMIT_NL ? "" : "\n" );
if( aTree.data().size() ) // sexpr format does not use data()
{
out->Print( 0, " %s%s",
out->Quotes( aTree.data() ).c_str(),
aTree.size() ? "\n" : ""
);
out->Quotes( aTree.data() ).c_str(),
aTree.size() ? "\n" : "" );
}
formatList( out, aNestLevel, aCtl, aTree );

View File

@ -229,6 +229,7 @@ void REFERENCE_IMAGE::scaleBy( double aRatio )
m_bitmapBase->SetScale( m_bitmapBase->GetScale() * aRatio );
SetTransformOriginOffset( KiROUND( newOffset ) );
// Don't need to recheck the box, we just did that
m_pos = KiROUND( newCenter );
}
@ -317,4 +318,4 @@ void REFERENCE_IMAGE::SwapData( REFERENCE_IMAGE& aOther )
std::swap( m_pos, aOther.m_pos );
std::swap( m_transformOriginOffset, aOther.m_transformOriginOffset );
std::swap( m_bitmapBase, aOther.m_bitmapBase );
}
}

View File

@ -39,7 +39,9 @@
// Fall back to getc() when getc_unlocked() is not available on the target platform.
#if !defined( HAVE_FGETC_NOLOCK )
#ifdef _MSC_VER
//getc is not a macro on windows and adds a tiny overhead for the indirection to eventually calling fgetc
// getc is not a macro on windows and adds a tiny overhead for the indirection to eventually
// calling fgetc
#define getc_unlocked _fgetc_nolock
#else
#define getc_unlocked getc
@ -448,7 +450,7 @@ int OUTPUTFORMATTER::sprint( const char* fmt, ... )
va_list args;
va_start( args, fmt );
int ret = vprint( fmt, args);
int ret = vprint( fmt, args );
va_end( args );
return ret;
@ -558,6 +560,7 @@ void STRING_FORMATTER::write( const char* aOutBuf, int aCount )
m_mystring.append( aOutBuf, aCount );
}
void STRING_FORMATTER::StripUseless()
{
std::string copy = m_mystring;

View File

@ -57,10 +57,13 @@ class EDA_BASE_FRAME;
int KeyCodeFromKeyName( const wxString& keyname );
/**
* Return the user friendly key name (ie: "Ctrl+M") from the key code.
* Return the key name from the key code.
*
* Only some wxWidgets key values are handled for function key ( see hotkeyNameList[] )
*
* @param aKeycode key code (ASCII value, or wxWidgets value for function keys).
* @param aIsFound a pointer to a bool to return true if found, or false.
* @param aIsFound a pointer to a bool to return true if found, or false. an be nullptr default).
* @return the key name in a wxString.
*/
wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound = nullptr );

View File

@ -42,15 +42,17 @@ public:
bool IsValidEndpoint() const;
/**
* Retrieves a single part with full details from the HTTP library.
* Retrieve a single part with full details from the HTTP library.
*
* @param aPk is the primary key of the part
* @param aResult will conatain the part if one was found
* @param aResult will contain the part if one was found
* @return true if aResult was filled; false otherwise
*/
bool SelectOne( const std::string& aPartID, HTTP_LIB_PART& aFetchedPart );
/**
* Retrieves all parts from a specific category from the HTTP library.
* Retrieve all parts from a specific category from the HTTP library.
*
* @param aPk is the primary key of the category
* @param aResults will be filled with all parts in that category
* @return true if the query succeeded and at least one part was found, false otherwise
@ -91,6 +93,19 @@ private:
bool boolFromString( const std::any& aVal, bool aDefaultValue = false );
/**
* HTTP response status codes indicate whether a specific HTTP request has been
* successfully completed.
*
* Responses are grouped in five classes:
* - Informational responses (100 ? 199)
* - Successful responses (200 ? 299)
* - Redirection messages (300 ? 399)
* - Client error responses (400 ? 499)
* - Server error responses (500 ? 599)
*
* see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
*/
wxString httpErrorCodeDescription( uint16_t aHttpCode );
HTTP_LIB_SOURCE m_source;

View File

@ -78,6 +78,10 @@ public:
/**
* Return the fixed name association with @a aLayerId.
*
* @note These names must not be translated or changed. They are used as tokens in the board
* file format because the ordinal value of the PCB_LAYER_ID enum was not stable over time.
* @see LayerName() for what should be used to display the default name of a layer in the GUI.
*/
static wxString Name( PCB_LAYER_ID aLayerId );

View File

@ -191,7 +191,16 @@ public:
struct IP2581_BOM m_IP2581Bom; /// IPC-2581 BOM settings
private:
/**
* Schema version 2: Bump for KiCad 9 layer numbering changes.
*
* Migrate layer presets to use new enum values for copper layers.
*/
bool migrateSchema1To2();
/**
* Schema version 3: move layer presets to use named render layers.
*/
bool migrateSchema2To3();
/// An list of schematic sheets in this project