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

pcbnew: better code to read/modify/delete footprints in module libraries.

parent ec7475f3
...@@ -45,11 +45,6 @@ parameter is a double) ...@@ -45,11 +45,6 @@ parameter is a double)
Workaround: Workaround:
Use a version > 2.9.1 Use a version > 2.9.1
Currently ( 2011, april 12 ) the 2.9.2 is not yet finalized
(and can be found only on the wxWidgets snv server)
can be fixed by replacing the file <wxWidgets-2.9.1>/src/common/xlocale.cpp
by the corresponding file from the 2.9.2 version (from wxWidgets svn server)
************************************************************************************* *************************************************************************************
wxGTK version: All wxGTK version: All
......
/************************/ /*
/* Menu "CONFIRMATION" */ * confirm.cpp
/* Function get_Message */ * utilities to display some error, warning and info short messges
/* Test requires ESC */ */
/************************/
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
enum id_dialog {
ID_TIMOUT = 1500
};
/* Class for displaying messages, similar to wxMessageDialog,
* but can be erased after a time out expires.
*
* @note - Do not use the time feature. It is broken by design because
* the dialog is shown as modal and wxWidgets will assert when
* compiled in the debug mode. This is because the dialog steals
* the event queue when dialog is modal so the timer event never
* gets to the dialog event handle. Using dialogs to display
* transient is brain dead anyway. Use the message panel or some
* other method.
*/
class WinEDA_MessageDialog : public wxMessageDialog
{
private:
int m_LifeTime;
wxTimer m_Timer;
public:
WinEDA_MessageDialog( wxWindow * parent, const wxString &msg,
const wxString &title, int style, int lifetime );
~WinEDA_MessageDialog() { };
void OnTimeOut( wxTimerEvent& event );
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE( WinEDA_MessageDialog, wxMessageDialog )
EVT_TIMER( ID_TIMOUT, WinEDA_MessageDialog::OnTimeOut )
END_EVENT_TABLE()
WinEDA_MessageDialog::WinEDA_MessageDialog( wxWindow* parent,
const wxString& msg,
const wxString& title,
int style,
int lifetime ) :
wxMessageDialog( parent, msg, title, style )
{
m_LifeTime = lifetime;
m_Timer.SetOwner( this, ID_TIMOUT );
if( m_LifeTime > 0 )
m_Timer.Start( 100 * m_LifeTime, wxTIMER_ONE_SHOT );
}
void WinEDA_MessageDialog::OnTimeOut( wxTimerEvent& event )
{
m_Timer.Stop();
EndModal( wxID_YES ); /* Does not work, I do not know why (this
* function is correctly called after time out).
* See not above as to why this doesn't work. */
}
/* Display an error or warning message. /* Display an error or warning message.
* If display time > 0 the dialog disappears after displayTime 0.1 seconds * TODO:
* If display time > 0 the dialog disappears after displayTime ( in 0.1 second )
* *
*/ */
void DisplayError( wxWindow* parent, const wxString& text, int displaytime ) void DisplayError( wxWindow* parent, const wxString& text, int displaytime )
...@@ -76,12 +17,11 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime ) ...@@ -76,12 +17,11 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime )
wxMessageDialog* dialog; wxMessageDialog* dialog;
if( displaytime > 0 ) if( displaytime > 0 )
dialog = new WinEDA_MessageDialog( parent, text, _( "Warning" ), dialog = new wxMessageDialog( parent, text, _( "Warning" ),
wxOK | wxICON_INFORMATION, wxOK | wxCENTRE | wxICON_INFORMATION );
displaytime );
else else
dialog = new WinEDA_MessageDialog( parent, text, _( "Error" ), dialog = new wxMessageDialog( parent, text, _( "Error" ),
wxOK | wxICON_ERROR, 0 ); wxOK | wxCENTRE | wxICON_ERROR );
dialog->ShowModal(); dialog->ShowModal();
dialog->Destroy(); dialog->Destroy();
...@@ -89,14 +29,16 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime ) ...@@ -89,14 +29,16 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime )
/* Display an informational message. /* Display an informational message.
* TODO:
* If display time > 0 the message disappears after displayTime (in 0.1 second )
*/ */
void DisplayInfoMessage( wxWindow* parent, const wxString& text, void DisplayInfoMessage( wxWindow* parent, const wxString& text,
int displaytime ) int displaytime )
{ {
wxMessageDialog* dialog; wxMessageDialog* dialog;
dialog = new WinEDA_MessageDialog( parent, text, _( "Info:" ), dialog = new wxMessageDialog( parent, text, _( "Info:" ),
wxOK | wxICON_INFORMATION, displaytime ); wxOK | wxCENTRE | wxICON_INFORMATION );
dialog->ShowModal(); dialog->ShowModal();
dialog->Destroy(); dialog->Destroy();
......
...@@ -93,6 +93,7 @@ set(PCBNEW_SRCS ...@@ -93,6 +93,7 @@ set(PCBNEW_SRCS
block.cpp block.cpp
block_module_editor.cpp block_module_editor.cpp
build_BOM_from_board.cpp build_BOM_from_board.cpp
class_footprint_library.cpp
class_pcb_layer_widget.cpp class_pcb_layer_widget.cpp
clean.cpp clean.cpp
connect.cpp connect.cpp
......
/**
* @file class_footprint_library.cpp
* Helper class to read/write footprint libraries.
*/
#include "fctsys.h"
#include "kicad_string.h"
#include "pcbnew.h"
#include "wxPcbStruct.h"
#include "richio.h"
#include "filter_reader.h"
#include "class_footprint_library.h"
/*
* Module library header format:
* LIBRARY HEADER-datetime
* $INDEX
* List of modules names (1 name per line)
* $EndIndex
* List of descriptions of Modules
* $EndLIBRARY
*/
FOOTPRINT_LIBRARY::FOOTPRINT_LIBRARY( FILE * aFile, FILTER_READER * aReader )
{
wxASSERT( m_reader || m_file );
m_file = aFile;
m_reader = aReader;
m_LineNum = 0;
}
/* function IsLibrary
* Read the library file Header
* return > 0 if this file is a footprint lib
* (currentlu return 1 but could be a value > 1 for future file formats
*/
int FOOTPRINT_LIBRARY::IsLibrary( )
{
char *line;
char buffer[1024];
if( m_reader )
{
m_reader->ReadLine();
line = m_reader->Line();
}
else
{
line = buffer;
GetLine( m_file, line, &m_LineNum );
}
StrPurge( line );
if( strnicmp( line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) == 0 )
return 1;
return 0;
}
/*
* function RebuildIndex
* Read the full library file and build the list od footprints found
* and do not use the $INDEX ... $EndINDEX section
*/
bool FOOTPRINT_LIBRARY::RebuildIndex()
{
m_List.Clear();
char name[1024];
if( m_reader )
{
while( m_reader->ReadLine() )
{
char * line = m_reader->Line();
StrPurge( line );
if( strnicmp( line, "$MODULE", 7 ) == 0 )
{
sscanf( line + 7, " %s", name );
m_List.Add( FROM_UTF8( name ) );
}
}
}
else
{
char line[1024];
while( GetLine( m_file, line, &m_LineNum ) )
{
if( strnicmp( line, "$MODULE", 7 ) == 0 )
{
sscanf( line + 7, " %s", name );
m_List.Add( FROM_UTF8( name ) );
}
}
}
return true;
}
/* function ReadSectionIndex
* Read the $INDEX ... $EndINDEX section
* list of footprints is stored in m_List
*/
bool FOOTPRINT_LIBRARY::ReadSectionIndex()
{
// Some broken INDEX sections have more than one section
// So we must read the next line after $EndINDEX tag,
// to see if this is not a new $INDEX tag.
bool exit = false;
if( m_reader )
{
while( m_reader->ReadLine() )
{
char * line = m_reader->Line();
StrPurge( line );
if( strnicmp( line, "$INDEX", 6 ) == 0 )
{
exit = false;
while( m_reader->ReadLine() )
{
StrPurge( line );
m_List.Add( FROM_UTF8( line ) );
if( strnicmp( line, "$EndINDEX", 9 ) == 0 )
{
exit = true;
break;
}
}
}
else if( exit )
break;
}
}
else
{
char line[1024];
while( GetLine( m_file, line, &m_LineNum ) )
{
if( strnicmp( line, "$INDEX", 6 ) == 0 )
{
exit = false;
while( GetLine( m_file, line, &m_LineNum ) )
{
StrPurge( line );
m_List.Add( FROM_UTF8( line ) );
if( strnicmp( line, "$EndINDEX", 9 ) == 0 )
{
exit = true;
break;
}
}
}
else if( exit )
break;
}
}
return true;
}
/* Function WriteHeader
* Write the library header
*/
bool FOOTPRINT_LIBRARY::WriteHeader()
{
char line[256];
fprintf( m_file, "%s %s\n", ENTETE_LIBRAIRIE, DateAndTime( line ) );
fprintf( m_file, "# encoding utf-8\n");
return true;
}
/* Function WriteSectionIndex
* Write the $INDEX ... $EndINDEX section.
* This section is filled by names in m_List
*/
bool FOOTPRINT_LIBRARY::WriteSectionIndex()
{
fputs( "$INDEX\n", m_file );
for( unsigned ii = 0; ii < m_List.GetCount(); ii++ )
{
fprintf( m_file, "%s\n", TO_UTF8( m_List[ii] ) );
}
fputs( "$EndINDEX\n", m_file );
return true;
}
/* Function WriteEndOfFile
* Write the last line section.
*/
bool FOOTPRINT_LIBRARY::WriteEndOfFile()
{
fputs( "$EndLIBRARY\n", m_file );
return true;
}
/*
* Function FindInList
* Search for aName int m_List and return true if found
*/
bool FOOTPRINT_LIBRARY::FindInList( const wxString & aName )
{
for( unsigned ii = 0; ii < m_List.GetCount(); ii++ )
{
if( m_List[ii].CmpNoCase( aName ) == 0 )
return true;
}
return false;
}
/**
* Function RemoveFromList
* Search for aName int m_List and remove it
* @return true if found and removed
*/
bool FOOTPRINT_LIBRARY::RemoveFromList( const wxString & aName )
{
for( unsigned ii = 0; ii < m_List.GetCount(); ii++ )
{
if( m_List[ii].CmpNoCase( aName ) == 0 )
{
m_List.RemoveAt(ii);
return true;
}
}
return false;
}
/**
* Function SortList
* Sort m_List in alphabetic order
*/
void FOOTPRINT_LIBRARY::SortList()
{
m_List.Sort();
}
/* Helper class to read/write footprints libraries
*/
#ifndef _FOOTPRINT_LIBRARY_H_
#define _FOOTPRINT_LIBRARY_H_
#include "filter_reader.h"
class FOOTPRINT_LIBRARY
{
public:
wxArrayString m_List; // list of footprints, used to read/write INDEX section
wxString m_LibraryName; // the full library name
int m_LineNum; // the line count
private:
FILTER_READER * m_reader; // FILTER_READER to read file. id NULL, use m_file
FILE * m_file; // footprint file to read/write.
public:
/**
* ctor
* @param aFile = a FILE * pointer used for write operations,
* and read operations when aReader = NULL
* @param aReader = a FILTER_READER pointer used for read operations
* If NULL, a direct aFILE read is used
*/
FOOTPRINT_LIBRARY( FILE * aFile, FILTER_READER * aReader = NULL );
~FOOTPRINT_LIBRARY() { }
/**
* function IsLibrary
* Read the library file Header
* return > 0 if this file is a footprint lib
* (currentlu return 1 but could be a value > 1 for future file formats
*/
int IsLibrary( );
/**
* function RebuildIndex
* Read the full library file and build the list od footprints found
* Do not use the $INDEX ... $EndINDEX section
*/
bool RebuildIndex();
/**
* function ReadSectionIndex
* Read the $INDEX ... $EndINDEX section
* list of footprints is stored in m_List
*/
bool ReadSectionIndex();
/**
* Function WriteHeader
* Write the library header
*/
bool WriteHeader();
/**
* Function WriteSectionIndex
* Write the $INDEX ... $EndINDEX section.
* This section is filled by names in m_List
*/
bool WriteSectionIndex();
/**
* Function WriteEndOfFile
* Write the last line section.
*/
bool WriteEndOfFile();
/**
* Function FindInList
* Search for aName int m_List
* @return true if found
*/
bool FindInList( const wxString & aName );
/**
* Function RemoveFromList
* Search for aName int m_List and remove it
* @return true if found and removed
*/
bool RemoveFromList( const wxString & aName );
/**
* Function SortList
* Sort m_List in alphabetic order
*/
void SortList();
};
#endif
This diff is collapsed.
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "dialog_helpers.h" #include "dialog_helpers.h"
#include "filter_reader.h" #include "filter_reader.h"
#include "footprint_info.h" #include "footprint_info.h"
#include "class_footprint_library.h"
static void DisplayCmpDoc( wxString& Name ); static void DisplayCmpDoc( wxString& Name );
...@@ -194,9 +195,7 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena ...@@ -194,9 +195,7 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
const wxString& aModuleName, const wxString& aModuleName,
bool aDisplayMessageError ) bool aDisplayMessageError )
{ {
int found = 0;
wxFileName fn; wxFileName fn;
char* Line;
wxString Name; wxString Name;
wxString msg, tmp; wxString msg, tmp;
MODULE* NewModule; MODULE* NewModule;
...@@ -244,11 +243,9 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena ...@@ -244,11 +243,9 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) ); msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) );
SetStatusText( msg ); SetStatusText( msg );
/* Reading header ENTETE_LIBRAIRIE */ FOOTPRINT_LIBRARY curr_lib( file, &reader );
reader.ReadLine();
Line = reader.Line(); if( !curr_lib.IsLibrary() )
StrPurge( Line );
if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
{ {
msg.Printf( _( "<%s> is not a valid Kicad PCB footprint library file." ), msg.Printf( _( "<%s> is not a valid Kicad PCB footprint library file." ),
GetChars( tmp ) ); GetChars( tmp ) );
...@@ -258,60 +255,37 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena ...@@ -258,60 +255,37 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
} }
/* Reading the list of modules in the library. */ /* Reading the list of modules in the library. */
found = 0; curr_lib.ReadSectionIndex();
while( !found && reader.ReadLine() ) bool found = curr_lib.FindInList( aModuleName );
{
Line = reader.Line();
if( strnicmp( Line, "$MODULE", 6 ) == 0 )
break;
if( strnicmp( Line, "$INDEX", 6 ) == 0 )
{
while( reader.ReadLine() )
{
Line = reader.Line();
if( strnicmp( Line, "$EndINDEX", 9 ) == 0 )
break;
StrPurge( Line );
msg = FROM_UTF8( Line );
if( msg.CmpNoCase( aModuleName ) == 0 )
{
found = 1;
break; /* found! */
}
}
}
}
/* Read library. */ /* Read library. */
while( found && reader.ReadLine() ) if( found )
{ {
Line = reader.Line(); fileReader.Rewind();
if( Line[0] != '$' ) while( reader.ReadLine() )
continue; {
char * line = reader.Line();
if( Line[1] != 'M' ) StrPurge( line + 8 );
continue;
if( strnicmp( Line, "$MODULE", 7 ) != 0 )
continue;
StrPurge( Line + 8 ); if( strnicmp( line, "$MODULE", 7 ) != 0 )
continue;
// Read module name. // Read module name.
Name = FROM_UTF8( Line + 8 ); Name = FROM_UTF8( line + 8 );
if( Name.CmpNoCase( aModuleName ) == 0 ) if( Name.CmpNoCase( aModuleName ) == 0 )
{ {
NewModule = new MODULE( GetBoard() ); NewModule = new MODULE( GetBoard() );
// Switch the locale to standard C (needed to print // Switch the locale to standard C (needed to print
// floating point numbers like 1.3) // floating point numbers like 1.3)
SetLocaleTo_C_standard(); SetLocaleTo_C_standard();
NewModule->ReadDescr( &reader ); NewModule->ReadDescr( &reader );
SetLocaleTo_Default(); // revert to the current locale SetLocaleTo_Default(); // revert to the current locale
GetBoard()->Add( NewModule, ADD_APPEND ); GetBoard()->Add( NewModule, ADD_APPEND );
SetStatusText( wxEmptyString ); SetStatusText( wxEmptyString );
return NewModule; return NewModule;
}
} }
} }
...@@ -384,14 +358,22 @@ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow, ...@@ -384,14 +358,22 @@ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow,
for( unsigned ii = 0; ii < MList.GetCount(); ii++ ) for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
footprint_names_list.Add( MList.GetItem(ii).m_Module ); footprint_names_list.Add( MList.GetItem(ii).m_Module );
msg.Printf( _( "Modules [%d items]" ), footprint_names_list.GetCount() ); if( footprint_names_list.GetCount() )
WinEDAListBox dlg( aWindow, msg, footprint_names_list, OldName, {
DisplayCmpDoc, GetComponentDialogPosition() ); msg.Printf( _( "Modules [%d items]" ), footprint_names_list.GetCount() );
WinEDAListBox dlg( aWindow, msg, footprint_names_list, OldName,
DisplayCmpDoc, GetComponentDialogPosition() );
if( dlg.ShowModal() == wxID_OK ) if( dlg.ShowModal() == wxID_OK )
CmpName = dlg.GetTextSelection(); CmpName = dlg.GetTextSelection();
else
CmpName.Empty();
}
else else
{
DisplayError( aWindow, _("No footprint found") );
CmpName.Empty(); CmpName.Empty();
}
if( CmpName != wxEmptyString ) if( CmpName != wxEmptyString )
OldName = CmpName; OldName = CmpName;
......
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