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)
Workaround:
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
......
/************************/
/* Menu "CONFIRMATION" */
/* Function get_Message */
/* Test requires ESC */
/************************/
/*
* confirm.cpp
* utilities to display some error, warning and info short messges
*/
#include "fctsys.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.
* 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 )
......@@ -76,12 +17,11 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime )
wxMessageDialog* dialog;
if( displaytime > 0 )
dialog = new WinEDA_MessageDialog( parent, text, _( "Warning" ),
wxOK | wxICON_INFORMATION,
displaytime );
dialog = new wxMessageDialog( parent, text, _( "Warning" ),
wxOK | wxCENTRE | wxICON_INFORMATION );
else
dialog = new WinEDA_MessageDialog( parent, text, _( "Error" ),
wxOK | wxICON_ERROR, 0 );
dialog = new wxMessageDialog( parent, text, _( "Error" ),
wxOK | wxCENTRE | wxICON_ERROR );
dialog->ShowModal();
dialog->Destroy();
......@@ -89,14 +29,16 @@ void DisplayError( wxWindow* parent, const wxString& text, int displaytime )
/* 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,
int displaytime )
{
wxMessageDialog* dialog;
dialog = new WinEDA_MessageDialog( parent, text, _( "Info:" ),
wxOK | wxICON_INFORMATION, displaytime );
dialog = new wxMessageDialog( parent, text, _( "Info:" ),
wxOK | wxCENTRE | wxICON_INFORMATION );
dialog->ShowModal();
dialog->Destroy();
......
......@@ -93,6 +93,7 @@ set(PCBNEW_SRCS
block.cpp
block_module_editor.cpp
build_BOM_from_board.cpp
class_footprint_library.cpp
class_pcb_layer_widget.cpp
clean.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 @@
#include "dialog_helpers.h"
#include "filter_reader.h"
#include "footprint_info.h"
#include "class_footprint_library.h"
static void DisplayCmpDoc( wxString& Name );
......@@ -194,9 +195,7 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
const wxString& aModuleName,
bool aDisplayMessageError )
{
int found = 0;
wxFileName fn;
char* Line;
wxString Name;
wxString msg, tmp;
MODULE* NewModule;
......@@ -244,11 +243,9 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
msg.Printf( _( "Scan Lib: %s" ), GetChars( tmp ) );
SetStatusText( msg );
/* Reading header ENTETE_LIBRAIRIE */
reader.ReadLine();
Line = reader.Line();
StrPurge( Line );
if( strnicmp( Line, ENTETE_LIBRAIRIE, L_ENTETE_LIB ) != 0 )
FOOTPRINT_LIBRARY curr_lib( file, &reader );
if( !curr_lib.IsLibrary() )
{
msg.Printf( _( "<%s> is not a valid Kicad PCB footprint library file." ),
GetChars( tmp ) );
......@@ -258,60 +255,37 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena
}
/* Reading the list of modules in the library. */
found = 0;
while( !found && reader.ReadLine() )
{
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! */
}
}
}
}
curr_lib.ReadSectionIndex();
bool found = curr_lib.FindInList( aModuleName );
/* Read library. */
while( found && reader.ReadLine() )
if( found )
{
Line = reader.Line();
if( Line[0] != '$' )
continue;
if( Line[1] != 'M' )
continue;
if( strnicmp( Line, "$MODULE", 7 ) != 0 )
continue;
fileReader.Rewind();
while( reader.ReadLine() )
{
char * line = reader.Line();
StrPurge( line + 8 );
StrPurge( Line + 8 );
if( strnicmp( line, "$MODULE", 7 ) != 0 )
continue;
// Read module name.
Name = FROM_UTF8( Line + 8 );
// Read module name.
Name = FROM_UTF8( line + 8 );
if( Name.CmpNoCase( aModuleName ) == 0 )
{
NewModule = new MODULE( GetBoard() );
// Switch the locale to standard C (needed to print
// floating point numbers like 1.3)
SetLocaleTo_C_standard();
NewModule->ReadDescr( &reader );
SetLocaleTo_Default(); // revert to the current locale
GetBoard()->Add( NewModule, ADD_APPEND );
SetStatusText( wxEmptyString );
return NewModule;
if( Name.CmpNoCase( aModuleName ) == 0 )
{
NewModule = new MODULE( GetBoard() );
// Switch the locale to standard C (needed to print
// floating point numbers like 1.3)
SetLocaleTo_C_standard();
NewModule->ReadDescr( &reader );
SetLocaleTo_Default(); // revert to the current locale
GetBoard()->Add( NewModule, ADD_APPEND );
SetStatusText( wxEmptyString );
return NewModule;
}
}
}
......@@ -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++ )
footprint_names_list.Add( MList.GetItem(ii).m_Module );
msg.Printf( _( "Modules [%d items]" ), footprint_names_list.GetCount() );
WinEDAListBox dlg( aWindow, msg, footprint_names_list, OldName,
DisplayCmpDoc, GetComponentDialogPosition() );
if( footprint_names_list.GetCount() )
{
msg.Printf( _( "Modules [%d items]" ), footprint_names_list.GetCount() );
WinEDAListBox dlg( aWindow, msg, footprint_names_list, OldName,
DisplayCmpDoc, GetComponentDialogPosition() );
if( dlg.ShowModal() == wxID_OK )
CmpName = dlg.GetTextSelection();
if( dlg.ShowModal() == wxID_OK )
CmpName = dlg.GetTextSelection();
else
CmpName.Empty();
}
else
{
DisplayError( aWindow, _("No footprint found") );
CmpName.Empty();
}
if( CmpName != wxEmptyString )
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