Commit b28e976e authored by jean-pierre charras's avatar jean-pierre charras

Eeschema: BOM list generation: some fixes and enhancements.

drawframe.cpp: commit a fix about scrollbars  from lajos kamocsay
parent bed96be7
...@@ -554,68 +554,80 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPosition ) ...@@ -554,68 +554,80 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPosition )
{ {
virtualSize = drawingRect.GetSize(); virtualSize = drawingRect.GetSize();
} }
else if( drawingRect.Contains( logicalClientRect ) )
{
virtualSize = drawingRect.GetSize();
}
else else
{ {
int drawingCenterX = drawingRect.x + ( drawingRect.width / 2 ); if( drawingRect.GetLeft() < logicalClientRect.GetLeft() && drawingRect.GetRight() > logicalClientRect.GetRight() )
int clientCenterX = logicalClientRect.x + ( logicalClientRect.width / 2 );
int drawingCenterY = drawingRect.y + ( drawingRect.height / 2 );
int clientCenterY = logicalClientRect.y + ( logicalClientRect.height / 2 );
if( logicalClientRect.width > drawingRect.width )
{ {
if( drawingCenterX > clientCenterX ) virtualSize.x = drawingRect.GetSize().x;
virtualSize.x = ( drawingCenterX - logicalClientRect.GetLeft() ) * 2;
else if( drawingCenterX < clientCenterX )
virtualSize.x = ( logicalClientRect.GetRight() - drawingCenterX ) * 2;
else
virtualSize.x = logicalClientRect.width;
} }
else if( logicalClientRect.width < drawingRect.width ) else
{ {
if( drawingCenterX > clientCenterX ) int drawingCenterX = drawingRect.x + ( drawingRect.width / 2 );
virtualSize.x = drawingRect.width + int clientCenterX = logicalClientRect.x + ( logicalClientRect.width / 2 );
( (drawingRect.GetLeft() - logicalClientRect.GetLeft() ) * 2 );
else if( drawingCenterX < clientCenterX ) if( logicalClientRect.width > drawingRect.width )
virtualSize.x = drawingRect.width + {
( (logicalClientRect.GetRight() - drawingRect.GetRight() ) * 2 ); if( drawingCenterX > clientCenterX )
virtualSize.x = ( drawingCenterX - logicalClientRect.GetLeft() ) * 2;
else if( drawingCenterX < clientCenterX )
virtualSize.x = ( logicalClientRect.GetRight() - drawingCenterX ) * 2;
else
virtualSize.x = logicalClientRect.width;
}
else if( logicalClientRect.width < drawingRect.width )
{
if( drawingCenterX > clientCenterX )
virtualSize.x = drawingRect.width +
( (drawingRect.GetLeft() - logicalClientRect.GetLeft() ) * 2 );
else if( drawingCenterX < clientCenterX )
virtualSize.x = drawingRect.width +
( (logicalClientRect.GetRight() - drawingRect.GetRight() ) * 2 );
else
virtualSize.x = drawingRect.width;
}
else else
{
virtualSize.x = drawingRect.width; virtualSize.x = drawingRect.width;
} }
else
{
virtualSize.x = drawingRect.width;
} }
if( logicalClientRect.height > drawingRect.height ) if( drawingRect.GetTop() < logicalClientRect.GetTop() && drawingRect.GetBottom() > logicalClientRect.GetBottom() )
{ {
if( drawingCenterY > clientCenterY ) virtualSize.y = drawingRect.GetSize().y;
virtualSize.y = ( drawingCenterY - logicalClientRect.GetTop() ) * 2;
else if( drawingCenterY < clientCenterY )
virtualSize.y = ( logicalClientRect.GetBottom() - drawingCenterY ) * 2;
else
virtualSize.y = logicalClientRect.height;
} }
else if( logicalClientRect.height < drawingRect.height ) else
{ {
if( drawingCenterY > clientCenterY ) int drawingCenterY = drawingRect.y + ( drawingRect.height / 2 );
virtualSize.y = drawingRect.height + int clientCenterY = logicalClientRect.y + ( logicalClientRect.height / 2 );
( ( drawingRect.GetTop() - logicalClientRect.GetTop() ) * 2 );
else if( drawingCenterY < clientCenterY ) if( logicalClientRect.height > drawingRect.height )
virtualSize.y = drawingRect.height + {
( ( logicalClientRect.GetBottom() - drawingRect.GetBottom() ) * 2 ); if( drawingCenterY > clientCenterY )
virtualSize.y = ( drawingCenterY - logicalClientRect.GetTop() ) * 2;
else if( drawingCenterY < clientCenterY )
virtualSize.y = ( logicalClientRect.GetBottom() - drawingCenterY ) * 2;
else
virtualSize.y = logicalClientRect.height;
}
else if( logicalClientRect.height < drawingRect.height )
{
if( drawingCenterY > clientCenterY )
virtualSize.y = drawingRect.height +
( ( drawingRect.GetTop() - logicalClientRect.GetTop() ) * 2 );
else if( drawingCenterY < clientCenterY )
virtualSize.y = drawingRect.height +
( ( logicalClientRect.GetBottom() - drawingRect.GetBottom() ) * 2 );
else
virtualSize.y = drawingRect.height;
}
else else
{
virtualSize.y = drawingRect.height; virtualSize.y = drawingRect.height;
} }
else
{
virtualSize.y = drawingRect.height;
} }
} }
if( screen->m_Center ) if( screen->m_Center )
{ {
screen->m_DrawOrg.x = -( wxRound( (double) virtualSize.x / 2.0 ) ); screen->m_DrawOrg.x = -( wxRound( (double) virtualSize.x / 2.0 ) );
......
...@@ -110,29 +110,52 @@ bool SCH_REFERENCE_LIST::sortByValueAndRef( const SCH_REFERENCE& item1, ...@@ -110,29 +110,52 @@ bool SCH_REFERENCE_LIST::sortByValueAndRef( const SCH_REFERENCE& item1,
const SCH_REFERENCE& item2 ) const SCH_REFERENCE& item2 )
{ {
int ii = item1.CompareValue( item2 ); int ii = item1.CompareValue( item2 );
if( ii == 0 ) if( ii == 0 )
ii = RefDesStringCompare( item1.GetRef(), item2.GetRef() ); ii = RefDesStringCompare( item1.GetRef(), item2.GetRef() );
if( ii == 0 ) if( ii == 0 )
ii = item1.m_Unit - item2.m_Unit; ii = item1.m_Unit - item2.m_Unit;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_SheetNum - item2.m_SheetNum; ii = item1.m_SheetNum - item2.m_SheetNum;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.x - item2.m_CmpPos.x; ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.y - item2.m_CmpPos.y; ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_TimeStamp - item2.m_TimeStamp; ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii < 0; return ii < 0;
} }
/*
* Helper function to calculate in a component value string
* the value, depending on multiplier symbol:
* pico
* nano
* micro (u)
* milli (m)
* kilo (k ou K)
* Mega
* Giga
* Tera
*
* with notations like 1K; 1.5K; 1,5K; 1k5
* returns true if the string is a value, false if not
* (a value is a string starting by a number)
*/
static bool engStrToDouble( wxString aStr, double* aDouble ) static bool engStrToDouble( wxString aStr, double* aDouble )
{ {
// A trick to take care of strings without a multiplier // A trick to take care of strings without a multiplier
aStr.Append( wxT( "R" ) ); aStr.Append( wxT( "R" ) );
// Regular expression for a value string, e.g., 47k2 // Regular expression for a value string, e.g., 47k2
static wxRegEx valueRegEx( wxT( "^([0-9]+)([pnumRkMGT.])([0-9]*)" ) ); static wxRegEx valueRegEx( wxT( "^([0-9]+)([pnumRkKMGT.,])([0-9]*)([pnumRkKMGT]*)" ) );
if( !valueRegEx.Matches( aStr ) ) if( !valueRegEx.Matches( aStr ) )
return false; return false;
...@@ -141,6 +164,7 @@ static bool engStrToDouble( wxString aStr, double* aDouble ) ...@@ -141,6 +164,7 @@ static bool engStrToDouble( wxString aStr, double* aDouble )
+ wxT( "." ) + wxT( "." )
+ valueRegEx.GetMatch( aStr, 3 ) ); + valueRegEx.GetMatch( aStr, 3 ) );
wxString multiplierString = valueRegEx.GetMatch( aStr, 2 ); wxString multiplierString = valueRegEx.GetMatch( aStr, 2 );
wxString post_multiplierString = valueRegEx.GetMatch( aStr, 4 );
double multiplier; double multiplier;
switch( (wxChar)multiplierString[0] ) switch( (wxChar)multiplierString[0] )
...@@ -158,6 +182,7 @@ static bool engStrToDouble( wxString aStr, double* aDouble ) ...@@ -158,6 +182,7 @@ static bool engStrToDouble( wxString aStr, double* aDouble )
multiplier = 1e-3; multiplier = 1e-3;
break; break;
case 'k': case 'k':
case 'K':
multiplier = 1e3; multiplier = 1e3;
break; break;
case 'M': case 'M':
...@@ -170,12 +195,46 @@ static bool engStrToDouble( wxString aStr, double* aDouble ) ...@@ -170,12 +195,46 @@ static bool engStrToDouble( wxString aStr, double* aDouble )
multiplier = 1e12; multiplier = 1e12;
break; break;
case 'R': case 'R':
case '.': case '.': // floatting point separator
case ',': // floatting point separator (some languages)
default: default:
multiplier = 1; multiplier = 1;
break; break;
} }
switch( (wxChar)post_multiplierString[0] )
{
case 'p':
multiplier = 1e-12;
break;
case 'n':
multiplier = 1e-9;
break;
case 'u':
multiplier = 1e-6;
break;
case 'm':
multiplier = 1e-3;
break;
case 'k':
case 'K':
multiplier = 1e3;
break;
case 'M':
multiplier = 1e6;
break;
case 'G':
multiplier = 1e9;
break;
case 'T':
multiplier = 1e12;
break;
case 'R':
default:
break;
}
LOCALE_IO dummy; // set to C floatting point standard
valueStr.ToDouble( aDouble ); valueStr.ToDouble( aDouble );
*aDouble *= multiplier; *aDouble *= multiplier;
...@@ -183,11 +242,41 @@ static bool engStrToDouble( wxString aStr, double* aDouble ) ...@@ -183,11 +242,41 @@ static bool engStrToDouble( wxString aStr, double* aDouble )
} }
/* sort the list of references by value.
* Components are grouped by type and are sorted by value:
* The value of a component accept multiplier symbols (p, n, K ..)
* groups are made by first letter of reference
*/
bool SCH_REFERENCE_LIST::sortByValueOnly( const SCH_REFERENCE& item1, bool SCH_REFERENCE_LIST::sortByValueOnly( const SCH_REFERENCE& item1,
const SCH_REFERENCE& item2 ) const SCH_REFERENCE& item2 )
{ {
wxString text1 = item1.GetComponent()->GetField( VALUE )->GetText(); // First, group by type, assuming 2 first letter of references
wxString text2 = item2.GetComponent()->GetField( VALUE )->GetText(); // are different for different types of components.
wxString text1 = item1.GetComponent()->GetField( REFERENCE )->GetText().Left(2);
wxString text2 = item2.GetComponent()->GetField( REFERENCE )->GetText().Left(2);
if( text1[0] != text2[0] )
return text1[0] < text2[0];
// Compare the second letter, if exists
if( text1.length() > 1 && text2.length() > 1 )
{
if( (text1[1] < '0') || (text1[1] > '9') ||
(text2[1] < '0') || (text2[1] > '9') )
return text1[1] < text2[1];
}
// Inside a group of components of same value, it could be good to group per footprints
text1 = item1.GetComponent()->GetField( FOOTPRINT )->GetText();
text2 = item2.GetComponent()->GetField( FOOTPRINT )->GetText();
int same_footprint = text1.IsEmpty() || text2.IsEmpty();
if( same_footprint == 0 )
same_footprint = text1.CmpNoCase( text2 );
// We can compare here 2 values relative to components of the same type
// assuming references are correctly chosen
text1 = item1.GetComponent()->GetField( VALUE )->GetText();
text2 = item2.GetComponent()->GetField( VALUE )->GetText();
double value1, value2; double value1, value2;
...@@ -204,7 +293,11 @@ bool SCH_REFERENCE_LIST::sortByValueOnly( const SCH_REFERENCE& item1, ...@@ -204,7 +293,11 @@ bool SCH_REFERENCE_LIST::sortByValueOnly( const SCH_REFERENCE& item1,
return false; return false;
if( match1 && match2 ) if( match1 && match2 )
{
if( value1 == value2 )
return same_footprint < 0;
return value1 < value2; return value1 < value2;
}
// Fall back to normal string compare // Fall back to normal string compare
int ii = text1.CmpNoCase( text2 ); int ii = text1.CmpNoCase( text2 );
......
This diff is collapsed.
...@@ -20,7 +20,7 @@ class DIALOG_BUILD_BOM : public DIALOG_BUILD_BOM_BASE ...@@ -20,7 +20,7 @@ class DIALOG_BUILD_BOM : public DIALOG_BUILD_BOM_BASE
private: private:
EDA_DRAW_FRAME* m_Parent; EDA_DRAW_FRAME* m_Parent;
wxConfig* m_Config; wxConfig* m_Config;
wxString m_ListFileName; wxString m_ListFileName; // The full filename of the file report.
private: private:
void OnRadioboxSelectFormatSelected( wxCommandEvent& event ); void OnRadioboxSelectFormatSelected( wxCommandEvent& event );
...@@ -34,17 +34,27 @@ private: ...@@ -34,17 +34,27 @@ private:
char aExportSeparatorSymbol, char aExportSeparatorSymbol,
bool aRunBrowser ); bool aRunBrowser );
void GenereListeOfItems( const wxString& FullFileName, bool aIncludeSubComponents ); void GenereListeOfItems( bool aIncludeSubComponents );
void CreateExportList( const wxString& FullFileName, bool aIncludeSubComponents );
/** /**
* Function CreateParstList * Function CreateExportList
* prints a list of components, in a form which can be imported by a * prints a list of components, in a form which can be imported by a
* spreadsheet. Form is: * spreadsheet. Form is:
* cmp value; number of components; \<footprint\>; \<field1\>; ...; * reference; cmp value; \<footprint\>; \<field1\>; ...;
* list of references having the same value * Components are sorted by reference
*/ */
void CreatePartsList( const wxString& aFullFileName, bool aIncludeSubComponents ); void CreateExportList( bool aIncludeSubComponents );
/**
* Function CreatePartsList
* prints a list of components, in a form which can be imported by a spreadsheet.
* components having the same value and the same footprint
* are grouped on the same line
* Form is:
* value; number of components; list of references; \<footprint\>; \<field1\>; ...;
* list is sorted by values
*/
void CreatePartsList();
int PrintComponentsListByRef( FILE* f, SCH_REFERENCE_LIST& aList, int PrintComponentsListByRef( FILE* f, SCH_REFERENCE_LIST& aList,
bool CompactForm, bool aIncludeSubComponents ); bool CompactForm, bool aIncludeSubComponents );
...@@ -55,11 +65,7 @@ private: ...@@ -55,11 +65,7 @@ private:
int PrintComponentsListByPart( FILE* f, SCH_REFERENCE_LIST& aList, int PrintComponentsListByPart( FILE* f, SCH_REFERENCE_LIST& aList,
bool aIncludeSubComponents ); bool aIncludeSubComponents );
#if defined(KICAD_GOST)
wxString PrintFieldData( SCH_COMPONENT* DrawLibItem, bool CompactForm = false ); wxString PrintFieldData( SCH_COMPONENT* DrawLibItem, bool CompactForm = false );
#else
void PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem, bool CompactForm = false );
#endif
bool IsFieldChecked( int aFieldId ); bool IsFieldChecked( int aFieldId );
......
...@@ -416,13 +416,15 @@ public: ...@@ -416,13 +416,15 @@ public:
* Function SortByValueOnly * Function SortByValueOnly
* sort the list of references by value. * sort the list of references by value.
* <p> * <p>
* Components are sorted in the following order: * Components are grouped by type and are sorted in the following order:
* <ul> * <ul>
* <li>Value of component.</li> * <li>Value of component.</li>
* <li>Numeric value of reference designator.</li> * <li>Numeric value of reference designator.</li>
* <li>Unit number when component has multiple parts.</li> * <li>Unit number when component has multiple parts.</li>
* </ul> * </ul>
* </p> * </p>
* groups are made by the first letter of reference
* or the 2 first letters when existing
*/ */
void SortByValueOnly() void SortByValueOnly()
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment