diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b4d676ef67..ba0e2b0029 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -141,6 +141,7 @@ set(COMMON_SRCS selcolor.cpp string.cpp trigo.cpp + utf8.cpp wildcards_and_files_ext.cpp worksheet.cpp wxwineda.cpp diff --git a/common/confirm.cpp b/common/confirm.cpp index 738ad17003..d14109ce42 100644 --- a/common/confirm.cpp +++ b/common/confirm.cpp @@ -102,10 +102,10 @@ void DisplayInfoMessage( wxWindow* parent, const wxString& text, int displaytime void DisplayHtmlInfoMessage( wxWindow* parent, const wxString& title, const wxString& text, const wxSize& size ) { - HTML_MESSAGE_BOX *dlg = new HTML_MESSAGE_BOX(parent,title, wxDefaultPosition, size ); - dlg->AddHTML_Text( text ); - dlg->ShowModal(); - dlg->Destroy(); + HTML_MESSAGE_BOX dlg( parent, title, wxDefaultPosition, size ); + + dlg.AddHTML_Text( text ); + dlg.ShowModal(); } diff --git a/common/dialogs/dialog_display_info_HTML_base.cpp b/common/dialogs/dialog_display_info_HTML_base.cpp index 346b78692f..5a693c8e7c 100644 --- a/common/dialogs/dialog_display_info_HTML_base.cpp +++ b/common/dialogs/dialog_display_info_HTML_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 5 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -21,7 +21,7 @@ DIALOG_DISPLAY_HTML_TEXT_BASE::DIALOG_DISPLAY_HTML_TEXT_BASE( wxWindow* parent, m_buttonClose = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); m_buttonClose->SetDefault(); - bMainSizer->Add( m_buttonClose, 0, wxALIGN_RIGHT|wxRIGHT|wxLEFT, 5 ); + bMainSizer->Add( m_buttonClose, 0, wxALIGN_RIGHT|wxALL, 10 ); this->SetSizer( bMainSizer ); diff --git a/common/dialogs/dialog_display_info_HTML_base.fbp b/common/dialogs/dialog_display_info_HTML_base.fbp index 8b7ed6f157..6608c5cd50 100644 --- a/common/dialogs/dialog_display_info_HTML_base.fbp +++ b/common/dialogs/dialog_display_info_HTML_base.fbp @@ -20,8 +20,10 @@ . 1 + 1 1 1 + UI 0 0 @@ -42,7 +44,7 @@ 400,120 DIALOG_DISPLAY_HTML_TEXT_BASE - 431,120 + 465,202 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h @@ -176,8 +178,8 @@ - 5 - wxALIGN_RIGHT|wxRIGHT|wxLEFT + 10 + wxALIGN_RIGHT|wxALL 0 1 diff --git a/common/dialogs/dialog_display_info_HTML_base.h b/common/dialogs/dialog_display_info_HTML_base.h index a184872866..4cfa053813 100644 --- a/common/dialogs/dialog_display_info_HTML_base.h +++ b/common/dialogs/dialog_display_info_HTML_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 5 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -45,7 +45,7 @@ class DIALOG_DISPLAY_HTML_TEXT_BASE : public DIALOG_SHIM public: wxHtmlWindow* m_htmlWindow; - DIALOG_DISPLAY_HTML_TEXT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 431,120 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_DISPLAY_HTML_TEXT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 465,202 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_DISPLAY_HTML_TEXT_BASE(); }; diff --git a/common/footprint_info.cpp b/common/footprint_info.cpp index b2561a697a..7bf02db687 100644 --- a/common/footprint_info.cpp +++ b/common/footprint_info.cpp @@ -27,10 +27,14 @@ */ +#define USE_WORKER_THREADS 1 // 1:yes, 0:no. use worker thread to load libraries + + /* * Functions to read footprint libraries and fill m_footprints by available footprints names * and their documentation (comments and keywords) */ + #include #include #include @@ -40,9 +44,47 @@ #include #include #include - #include +#if defined(USE_FP_LIB_TABLE) + #include +#endif + + +/* +wxString ToHTML( const IO_ERROR** aList, int aCount ) +{ + wxString msg = wxT( "" ); + + msg += " + + for( int i=0; i" ); + + for ( unsigned ii = 0; ii < strings_list->GetCount(); ii++ ) + { + msg += wxT( "
  • " ); + msg += strings_list->Item( ii ) + wxT( "
  • " ); + } + + msg += wxT( "" ); + + m_htmlWindow->AppendToPage( msg ); + + delete strings_list; +} +*/ + + #if !defined( USE_FP_LIB_TABLE ) bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintLibNames ) @@ -50,9 +92,9 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintLibNames ) bool retv = true; // Clear data before reading files - m_filesNotFound.Empty(); - m_filesInvalid.Empty(); - m_List.clear(); + m_error_count = 0; + m_errors.clear(); + m_list.clear(); // try { @@ -80,13 +122,6 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintLibNames ) wxLogDebug( wxT( "Path <%s> -> <%s>." ), GetChars( aFootprintLibNames[ii] ), GetChars( filename.GetFullPath() ) ); - if( !filename.IsOk() || !filename.FileExists() ) - { - m_filesNotFound << aFootprintLibNames[ii] << wxT( "\n" ); - retv = false; - continue; - } - try { wxArrayString fpnames = pi->FootprintEnumerate( filename.GetFullPath() ); @@ -111,37 +146,133 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintLibNames ) AddItem( fpinfo ); } } - catch( IO_ERROR ioe ) + catch( const PARSE_ERROR& pe ) { - m_filesInvalid << ioe.errorText << wxT( "\n" ); + m_errors.push_back( new PARSE_ERROR( pe ) ); + retv = false; + } + catch( const IO_ERROR& ioe ) + { + m_errors.push_back( new IO_ERROR( ioe ) ); retv = false; } } } /* caller should catch this, UI seems not wanted here. - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( NULL, ioe.errorText ); return false; } */ - m_List.sort(); + m_list.sort(); return retv; } -#else +#else // yes USE_FP_LIB_TABLE, by all means: + + +#if USE_WORKER_THREADS //--------------------------------------------------------------------- + +#define USE_WORKER_THREADS 1 // 1:yes, 0:no. use worker threads to load libraries + +#define JOBZ 6 // no. libraries per worker thread. It takes about + // a second to load a GITHUB library, so assigning + // this no. libraries to each thread should give a little + // over this no. seconds total time if the original delay + // were caused by latencies alone. + // (If https://github.com does not mind.) + +#define NTOLERABLE_ERRORS 4 // max errors before aborting, although threads + // in progress will still pile on for a bit. e.g. if 9 threads + // expect 9 greater than this. + + +void FOOTPRINT_LIST::loader_job( const wxString* aNicknameList, int aJobZ ) +{ + //DBG(printf( "%s: first:'%s' count:%d\n", __func__, (char*) TO_UTF8( *aNicknameList ), aJobZ );) + + for( int i=0; i= NTOLERABLE_ERRORS ) + break; + + const wxString& nickname = aNicknameList[i]; + + try + { + wxArrayString fpnames = m_lib_table->FootprintEnumerate( nickname ); + + for( unsigned ni=0; ni m( m_lib_table->FootprintLoad( nickname, fpnames[ni] ) ); + + FOOTPRINT_INFO* fpinfo = new FOOTPRINT_INFO(); + + fpinfo->SetNickname( nickname ); + + fpinfo->m_Module = fpnames[ni]; + fpinfo->m_padCount = m->GetPadCount( MODULE::DO_NOT_INCLUDE_NPTH ); + fpinfo->m_KeyWord = m->GetKeywords(); + fpinfo->m_Doc = m->GetDescription(); + + AddItem( fpinfo ); + } + } + catch( const PARSE_ERROR& pe ) + { + // push_back is not thread safe, use the lock the MUTEX. + MUTLOCK lock( m_errors_lock ); + + ++m_error_count; // modify only under lock + m_errors.push_back( new IO_ERROR( pe ) ); + } + catch( const IO_ERROR& ioe ) + { + MUTLOCK lock( m_errors_lock ); + + ++m_error_count; + m_errors.push_back( new IO_ERROR( ioe ) ); + } + + // Catch anything unexpected and map it into the expected. + // Likely even more important since this function runs on GUI-less + // worker threads. + catch( const std::exception& se ) + { + // this is a round about way to do this, but who knows what THROW_IO_ERROR() + // may be tricked out to do someday, keep it in the game. + try + { + THROW_IO_ERROR( se.what() ); + } + catch( const IO_ERROR& ioe ) + { + MUTLOCK lock( m_errors_lock ); + + ++m_error_count; + m_errors.push_back( new IO_ERROR( ioe ) ); + } + } + } +} + +#endif // USE_WORKER_THREADS --------------------------------------------------- + bool FOOTPRINT_LIST::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname ) { bool retv = true; + m_lib_table = aTable; + // Clear data before reading files - m_filesNotFound.Empty(); - m_filesInvalid.Empty(); - m_List.clear(); + m_error_count = 0; + m_errors.clear(); + m_list.clear(); std::vector< wxString > nicknames; @@ -149,8 +280,68 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* a // do all of them nicknames = aTable->GetLogicalLibs(); else + // single footprint nicknames.push_back( *aNickname ); +#if USE_WORKER_THREADS + + // Something which will not invoke a thread copy constructor, one of many ways obviously: + typedef boost::ptr_vector< boost::thread > MYTHREADS; + + MYTHREADS threads; + + // Give each thread JOBZ nicknames to process. The last portion of, or if the entire + // size() is small, I'll do myself. + for( unsigned i=0; i= NTOLERABLE_ERRORS ) + { + // abort the remaining nicknames. + retv = false; + break; + } + + int jobz = JOBZ; + + if( i + jobz >= nicknames.size() ) + { + jobz = nicknames.size() - i; + + // Only a little bit to do, I'll do it myself, on current thread. + // This is the path for a single footprint also. + loader_job( &nicknames[i], jobz ); + } + else + { + // Delegate the job to a worker thread created here. + threads.push_back( new boost::thread( &FOOTPRINT_LIST::loader_job, + this, &nicknames[i], jobz ) ); + } + + i += jobz; + } + + // Wait for all the worder threads to complete, it does not matter in what order + // we wait for them as long as a full sweep is made. Think of the great race, + // everyone must finish. + for( unsigned i=0; i // until scaffolding goes. + +void FOOTPRINT_LIST::DisplayErrors( wxTopLevelWindow* aWindow ) +{ +#if 1 + // scaffolding until a better one is written, hopefully below. + + DBG(printf( "m_error_count:%d\n", m_error_count );) + + wxString msg = _( "Errors were encountered loading footprints" ); + + msg += wxT( '\n' ); + + for( unsigned i = 0; i! ? centric output, possibly with + // recommendations for remedy of errors. Add numeric error codes + // to PARSE_ERROR, and switch on them for remedies, etc. Full + // access is provided to everything in every exception! + + HTML_MESSAGE_BOX dlg( aWindow, _( "Load Error" ) ); + + dlg.MessageSet( _( "Errors were encountered loading footprints" ) ); + + wxString msg = my html wizardry. + + dlg.AddHTML_Text( msg ); + + dlg.ShowModal(); + +#endif +} diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index 77fa491615..09bcf826e9 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -637,6 +637,26 @@ const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname ) } +// wxGetenv( wchar_t* ) is not re-entrant on linux. +// Put a lock on multithreaded use of wxGetenv( wchar_t* ), called from wxEpandEnvVars(), +// needed by bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = NULL ); +#if 1 + +#include + +const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString ) +{ + static MUTEX getenv_mutex; + + MUTLOCK lock( getenv_mutex ); + + // We reserve the right to do this another way, by providing our own member + // function. + return wxExpandEnvVars( aString ); +} + +#else + const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString ) { // We reserve the right to do this another way, by providing our own member @@ -644,6 +664,7 @@ const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString ) return wxExpandEnvVars( aString ); } +#endif bool FP_LIB_TABLE::IsEmpty( bool aIncludeFallback ) { diff --git a/common/html_messagebox.cpp b/common/html_messagebox.cpp index c86879eae2..25532fb1e8 100644 --- a/common/html_messagebox.cpp +++ b/common/html_messagebox.cpp @@ -1,83 +1,78 @@ #include #include #include +#include -HTML_MESSAGE_BOX::HTML_MESSAGE_BOX( wxWindow* parent, const wxString & aTitle, - wxPoint aPos, wxSize aSize) - : DIALOG_DISPLAY_HTML_TEXT_BASE( parent, wxID_ANY, aTitle, aPos, aSize ) + +HTML_MESSAGE_BOX::HTML_MESSAGE_BOX( wxWindow* parent, const wxString& aTitle, + wxPoint aPos, wxSize aSize) : + DIALOG_DISPLAY_HTML_TEXT_BASE( parent, wxID_ANY, aTitle, aPos, aSize ) { ListClear(); Center(); } + void HTML_MESSAGE_BOX::OnCloseButtonClick( wxCommandEvent& event ) { - EndModal(0); + EndModal( 0 ); } -void HTML_MESSAGE_BOX::ListClear(void) +void HTML_MESSAGE_BOX::ListClear() { - m_htmlWindow->SetPage(wxEmptyString); + m_htmlWindow->SetPage( wxEmptyString ); } -/** - * Function ListSet - * Add a list of items. - * @param aList = a string containing items. Items are separated by '\n' - */ -void HTML_MESSAGE_BOX::ListSet(const wxString &aList) -{ - wxArrayString* wxStringSplit( wxString txt, wxChar splitter ); - wxArrayString* strings_list = wxStringSplit( aList, wxChar('\n') ); - wxString msg = wxT("
      "); - for ( unsigned ii = 0; ii < strings_list->GetCount(); ii ++ ) +void HTML_MESSAGE_BOX::ListSet( const wxString& aList ) +{ + // wxArrayString* wxStringSplit( wxString txt, wxChar splitter ); + + wxArrayString* strings_list = wxStringSplit( aList, wxChar( '\n' ) ); + + wxString msg = wxT( "
        " ); + + for ( unsigned ii = 0; ii < strings_list->GetCount(); ii++ ) { - msg += wxT("
      • "); - msg += strings_list->Item(ii) + wxT("
      • "); + msg += wxT( "
      • " ); + msg += strings_list->Item( ii ) + wxT( "
      • " ); } - msg += wxT("
      "); + + msg += wxT( "
    " ); + m_htmlWindow->AppendToPage( msg ); delete strings_list; } -/** - * Function ListSet - * Add a list of items. - * @param aList = a wxArrayString containing items - */ -void HTML_MESSAGE_BOX::ListSet(const wxArrayString &aList) + +void HTML_MESSAGE_BOX::ListSet( const wxArrayString& aList ) { - wxString msg = wxT("
      "); - for ( unsigned ii = 0; ii < aList.GetCount(); ii ++ ) + wxString msg = wxT( "
        " ); + + for( unsigned ii = 0; ii < aList.GetCount(); ii++ ) { - msg += wxT("
      • "); - msg += aList.Item(ii) + wxT("
      • "); + msg += wxT( "
      • " ); + msg += aList.Item( ii ) + wxT( "
      • " ); } - msg += wxT("
      "); + + msg += wxT( "
    " ); + m_htmlWindow->AppendToPage( msg ); } -/** - * Function MessageSet - * Add a message (in bold) to message list. - * @param message = the message - */ -void HTML_MESSAGE_BOX::MessageSet(const wxString &message) + +void HTML_MESSAGE_BOX::MessageSet( const wxString& message ) { - wxString message_value; - message_value.Printf(wxT("%s
    "), GetChars( message ) ); + wxString message_value = wxString::Format( + wxT( "%s
    " ), GetChars( message ) ); + m_htmlWindow->AppendToPage( message_value ); } -/** - * Function AddHTML_Text - * Add a text to message list. - * @param message = the text to add - */ -void HTML_MESSAGE_BOX::AddHTML_Text(const wxString &message) + +void HTML_MESSAGE_BOX::AddHTML_Text( const wxString& message ) { m_htmlWindow->AppendToPage( message ); } diff --git a/tools/UTF8.cpp b/common/utf8.cpp similarity index 52% rename from tools/UTF8.cpp rename to common/utf8.cpp index afcab52913..48478bb15b 100644 --- a/tools/UTF8.cpp +++ b/common/utf8.cpp @@ -1,259 +1,39 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +/* THROW_IO_ERROR needs this, but it will soon be including this file, so until some + factoring of THROW_IO_ERROR into a separate header, defer and use the asserts. +#include +*/ -#include -#include -#include #include - -/** - * Class UTF8 - * is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special - * conversion support to and from wxString, and has iteration over unicode characters. - * - *

    I've been careful to supply only conversion facilities and not try - * and duplicate wxString() with many member functions. In the end it is - * to be a std::string. There are multiple ways to create text into a std::string - * without the need of too many member functions: - * - *

      - *
    • richio.h's StrPrintf()
    • - *
    • std::ostringstream.
    • - *
    - * - *

    Because this class used no virtuals, it should be possible to cast any - * std::string into a UTF8 using this kind of cast: (UTF8 &) without construction - * or copying being the effect of the cast. Be sure the source std::string holds - * UTF8 encoded text before you do that. - * - * @author Dick Hollenbeck - */ -class UTF8 : public std::string -{ -public: - - UTF8( const wxString& o ); - - /// This is the only constructor for which you could end up with - /// non-UTF8 encoding, but that would be your fault. - UTF8( const char* txt ) : - std::string( txt ) - { - } - - /// For use with _() function on wx 2.8: - UTF8( const wchar_t* txt ); - - explicit UTF8( const std::string& o ) : - std::string( o ) - { - } - - UTF8() : - std::string() - { - } - - UTF8& operator=( const wxString& o ); - - UTF8& operator=( const std::string& o ) - { - std::string::operator=( o ); - return *this; - } - - operator wxString () const; - - /// This one is not in std::string, and one wonders why... might be a solid - /// enough reason to remove it still. - operator char* () const - { - return (char*) c_str(); - } - - /** - * Function uni_forward - * advances over a single UTF8 encoded multibyte character, capturing the - * unicode character as it goes, and returning the number of bytes consumed. - * - * @param aSequence is the UTF8 byte sequence, must be aligned on start of character. - * @param aResult is where to put the unicode character, and may be NULL if no interest. - * @return int - the count of bytes consumed. - */ - static int uni_forward( const unsigned char* aSequence, unsigned* aResult = NULL ); - - /** - * class uni_iter - * is a non-muting iterator that walks through unicode code points in the UTF8 encoded - * string. The normal ++(), ++(int), ->(), and *() operators are all supported - * for read only access and they return an unsigned holding the unicode character - * appropriate for the respective operator. - */ - class uni_iter - { - friend class UTF8; - - const unsigned char* it; - - // private constructor. - uni_iter( const char* start ) : - it( (const unsigned char*) start ) - { - // for the human: assert( sizeof(unsigned) >= 4 ); - } - - - public: - - uni_iter( const uni_iter& o ) - { - it = o.it; - } - - /// pre-increment and return uni_iter at new position - const uni_iter& operator++() - { - it += uni_forward( it ); - - return *this; - } - - /// post-increment and return uni_iter at initial position - uni_iter operator++( int ) - { - uni_iter ret = *this; - - it += uni_forward( it ); - return ret; - } - - /* - /// return unicode at current position - unsigned operator->() const - { - unsigned result; - - // grab the result, do not advance - uni_forward( it, &result ); - return result; - } - */ - - /// return unicode at current position - unsigned operator*() const - { - unsigned result; - - // grab the result, do not advance - uni_forward( it, &result ); - return result; - } - - bool operator==( const uni_iter& other ) const { return it == other.it; } - bool operator!=( const uni_iter& other ) const { return it != other.it; } - - /// Since the ++ operators advance more than one byte, this is your best - /// loop termination test, < end(), not == end(). - bool operator< ( const uni_iter& other ) const { return it < other.it; } - bool operator<=( const uni_iter& other ) const { return it <= other.it; } - bool operator> ( const uni_iter& other ) const { return it > other.it; } - bool operator>=( const uni_iter& other ) const { return it >= other.it; } - }; - - /** - * Function ubegin - * returns a @a uni_iter initialized to the start of "this" UTF8 byte sequence. - */ - uni_iter ubegin() const - { - return uni_iter( data() ); - } - - /** - * Function uend - * returns a @a uni_iter initialized to the end of "this" UTF8 byte sequence. - */ - uni_iter uend() const - { - return uni_iter( data() + size() ); - } -}; - - -wxString wxFunctionTaking_wxString( const wxString& wx ) -{ - printf( "%s:'%s'\n", __func__, (char*) UTF8( wx ) ); - printf( "%s:'%s'\n", __func__, (const char*) UTF8( wx ) ); - printf( "%s:'%s'\n", __func__, UTF8( wx ).c_str() ); - - return wx; -} - - -int main() -{ - std::string str = "input"; - - UTF8 u0 = L"wide string"; - UTF8 u1 = "initial"; - wxString wx = wxT( "input2" ); - - printf( "u0:'%s'\n", u0.c_str() ); - printf( "u1:'%s'\n", u1.c_str() ); - - u1 = str; - - wxString wx2 = u1; - - // force a std::string into a UTF8, then into a wxString, then copy construct: - wxString wx3 = (UTF8&) u1; - - UTF8 u2 = wx2; - - u2 += 'X'; - - printf( "u2:'%s'\n", u2.c_str() ); - - // key accomplishments here: - // 1) passing a UTF8 to a function which normally takes a wxString. - // 2) return a wxString back into a UTF8. - UTF8 result = wxFunctionTaking_wxString( u2 ); - - printf( "result:'%s'\n", result.c_str() ); - - // test the unicode iterator: - for( UTF8::uni_iter it = u2.ubegin(); it < u2.uend(); ) - { - // test post-increment: - printf( " _%c_", *it++ ); - - // after UTF8::uni_forward() is implemented, %c is no longer useable. - // printf( " _%02x_", *it++ ); - } - - printf( "\n" ); - - UTF8::uni_iter it = u2.ubegin(); - - UTF8::uni_iter it2 = it++; - - printf( "post_inc:'%c' should be 'i'\n", *it2 ); - - it2 = ++it; - - printf( "pre_inc:'%c' should be 'p'\n", *it2 ); - - printf( "u[1]:'%c' should be 'n'\n", u2[1] ); - - return 0; -} - - /* - - These to go into a library *.cpp, they are not inlined so that significant - code space is saved by encapsulating the creation of intermediate objects - and referencing wxConvUTF8. - + These are not inlined so that code space is saved by encapsulating the + creation of intermediate objects and referencing wxConvUTF8. */ @@ -405,3 +185,76 @@ UTF8::UTF8( const wchar_t* txt ) : resize( sz ); } + +#if 0 // some unit tests: + +#include + +wxString wxFunctionTaking_wxString( const wxString& wx ) +{ + printf( "%s:'%s'\n", __func__, (char*) UTF8( wx ) ); + printf( "%s:'%s'\n", __func__, (const char*) UTF8( wx ) ); + printf( "%s:'%s'\n", __func__, UTF8( wx ).c_str() ); + + return wx; +} + +int main() +{ + std::string str = "input"; + + UTF8 u0 = L"wide string"; + UTF8 u1 = "initial"; + wxString wx = wxT( "input2" ); + + printf( "u0:'%s'\n", u0.c_str() ); + printf( "u1:'%s'\n", u1.c_str() ); + + u1 = str; + + wxString wx2 = u1; + + // force a std::string into a UTF8, then into a wxString, then copy construct: + wxString wx3 = (UTF8&) u1; + + UTF8 u2 = wx2; + + u2 += 'X'; + + printf( "u2:'%s'\n", u2.c_str() ); + + // key accomplishments here: + // 1) passing a UTF8 to a function which normally takes a wxString. + // 2) return a wxString back into a UTF8. + UTF8 result = wxFunctionTaking_wxString( u2 ); + + printf( "result:'%s'\n", result.c_str() ); + + // test the unicode iterator: + for( UTF8::uni_iter it = u2.ubegin(); it < u2.uend(); ) + { + // test post-increment: + printf( " _%c_", *it++ ); + + // after UTF8::uni_forward() is implemented, %c is no longer useable. + // printf( " _%02x_", *it++ ); + } + + printf( "\n" ); + + UTF8::uni_iter it = u2.ubegin(); + + UTF8::uni_iter it2 = it++; + + printf( "post_inc:'%c' should be 'i'\n", *it2 ); + + it2 = ++it; + + printf( "pre_inc:'%c' should be 'p'\n", *it2 ); + + printf( "u[1]:'%c' should be 'n'\n", u2[1] ); + + return 0; +} + +#endif diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index cc337a40b1..f536f90cae 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -112,13 +112,13 @@ target_link_libraries( cvpcb # Only for win32 cross compilation using MXE if( WIN32 AND MSYS AND CMAKE_CROSSCOMPILING ) target_link_libraries(cvpcb - opengl32 - glu32 - pixman-1 - fontconfig - freetype - bz2 - ) + opengl32 + glu32 + pixman-1 + fontconfig + freetype + bz2 + ) endif() diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp index 7079a280ba..7cec4fe9b0 100644 --- a/cvpcb/autosel.cpp +++ b/cvpcb/autosel.cpp @@ -176,7 +176,7 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) /* filter alias so one can use multiple aliases (for polar and nonpolar caps for * example) */ - FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( alias.m_FootprintName ); + const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( alias.m_FootprintName ); if( module ) { @@ -210,7 +210,7 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) { /* we do not need to analyse wildcards: single footprint do not contain them */ /* and if there are wildcards it just will not match any */ - FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] ); + const FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] ); if( module ) { diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index 381e90dd97..f18ece57aa 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -558,9 +558,9 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay() msg.Printf( _( "Footprint: %s" ), GetChars( footprintName ) ); SetTitle( msg ); - FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName ); + const FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName ); - const wxChar *libname; + const wxChar* libname; if( module_info ) libname = GetChars( module_info->GetNickname() ); diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 11fb2d261d..d701106d00 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -703,8 +703,9 @@ void CVPCB_MAINFRAME::DisplayStatus() } else { - wxString footprintName = m_FootprintList->GetSelectedFootprint(); - FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( footprintName ); + wxString footprintName = m_FootprintList->GetSelectedFootprint(); + + const FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( footprintName ); if( module ) // can be NULL if no netlist loaded { @@ -716,7 +717,6 @@ void CVPCB_MAINFRAME::DisplayStatus() } } - msg.Empty(); if( m_FootprintList ) @@ -769,26 +769,9 @@ bool CVPCB_MAINFRAME::LoadFootprintFiles() m_footprints.ReadFootprintFiles( m_footprintLibTable ); #endif - // Display error messages, if any. - if( !m_footprints.m_filesNotFound.IsEmpty() || !m_footprints.m_filesInvalid.IsEmpty() ) + if( m_footprints.GetErrorCount() ) { - HTML_MESSAGE_BOX dialog( this, _( "Load Error" ) ); - - if( !m_footprints.m_filesNotFound.IsEmpty() ) - { - wxString message = _( "Some files could not be found!" ); - dialog.MessageSet( message ); - dialog.ListSet( m_footprints.m_filesNotFound ); - } - - // Display if there are invalid files. - if( !m_footprints.m_filesInvalid.IsEmpty() ) - { - dialog.MessageSet( _( "Some files are invalid!" ) ); - dialog.ListSet( m_footprints.m_filesInvalid ); - } - - dialog.ShowModal(); + m_footprints.DisplayErrors( this ); } return true; diff --git a/include/footprint_info.h b/include/footprint_info.h index 3ba4392e2b..2c078e5e78 100644 --- a/include/footprint_info.h +++ b/include/footprint_info.h @@ -33,10 +33,15 @@ #include #include +#if defined( USE_FP_LIB_TABLE ) + #include +#endif + #include class FP_LIB_TABLE; +class wxTopLevelWindow; /* @@ -106,64 +111,103 @@ inline bool operator<( const FOOTPRINT_INFO& item1, const FOOTPRINT_INFO& item2 } - +/** + * Class FOOTPRINT_LIST + * holds a list of FOOTPRINT_INFO objects, along with a list of IO_ERRORs or + * PARSE_ERRORs that were thrown acquiring the FOOTPRINT_INFOs. + */ class FOOTPRINT_LIST { -public: - boost::ptr_vector< FOOTPRINT_INFO > m_List; - wxString m_filesNotFound; - wxString m_filesInvalid; + FP_LIB_TABLE* m_lib_table; ///< no ownership + volatile int m_error_count; ///< thread safe to read. + + + typedef boost::ptr_vector< FOOTPRINT_INFO > FPILIST; + typedef boost::ptr_vector< IO_ERROR > ERRLIST; + + FPILIST m_list; + ERRLIST m_errors; ///< some can be PARSE_ERRORs also + +#if defined( USE_FP_LIB_TABLE ) + MUTEX m_errors_lock; + MUTEX m_list_lock; +#endif + + /** + * Function loader_job + * loads footprints from @a aNicknameList and calls AddItem() on to help fill + * m_list. + * + * @param aNicknameList is a wxString[] holding libraries to load all footprints from. + * @param aJobZ is the size of the job, i.e. the count of nicknames. + */ + void loader_job( const wxString* aNicknameList, int aJobZ ); public: + FOOTPRINT_LIST() : + m_lib_table( 0 ), + m_error_count( 0 ) + { + } + /** * Function GetCount * @return the number of items stored in list */ - unsigned GetCount() const { return m_List.size(); } + unsigned GetCount() const { return m_list.size(); } + + /// Was forced to add this by modview_frame.cpp + const FPILIST& GetList() const { return m_list; } /** * Function GetModuleInfo - * @return the item stored in list if found - * @param aFootprintName = the name of item + * @param aFootprintName = the footprint name inside the FOOTPRINT_INFO of interest. + * @return const FOOTPRINT_INF* - the item stored in list if found */ - FOOTPRINT_INFO* GetModuleInfo( const wxString & aFootprintName ); + const FOOTPRINT_INFO* GetModuleInfo( const wxString& aFootprintName ); /** * Function GetItem - * @return the aIdx item in list * @param aIdx = index of the given item + * @return the aIdx item in list */ - FOOTPRINT_INFO & GetItem( unsigned aIdx ) - { - return m_List[aIdx]; - } + const FOOTPRINT_INFO& GetItem( unsigned aIdx ) const { return m_list[aIdx]; } /** * Function AddItem * add aItem in list * @param aItem = item to add */ - void AddItem( FOOTPRINT_INFO* aItem ) - { - m_List.push_back( aItem ); - } + void AddItem( FOOTPRINT_INFO* aItem ); + unsigned GetErrorCount() const { return m_errors.size(); } + + const IO_ERROR* GetError( unsigned aIdx ) const { return &m_errors[aIdx]; } + +#if !defined( USE_FP_LIB_TABLE ) /** * Function ReadFootprintFiles * * @param aFootprintsLibNames = an array string giving the list of libraries to load */ bool ReadFootprintFiles( wxArrayString& aFootprintsLibNames ); +#endif /** * Function ReadFootprintFiles * reads all the footprints provided by the combination of aTable and aNickname. + * * @param aTable defines all the libraries. * @param aNickname is the library to read from, or if NULL means read all - * footprints from all known libraries. + * footprints from all known libraries in aTable. + * @return bool - true if it ran to completion, else false if it aborted after + * some number of errors. If true, it does not mean there were no errors, check + * GetErrorCount() for that, should be zero to indicate success. */ bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = NULL ); + + void DisplayErrors( wxTopLevelWindow* aCaller = NULL ); }; #endif // FOOTPRINT_INFO_H_ diff --git a/include/html_messagebox.h b/include/html_messagebox.h index fa83e33d7a..72c79dad3f 100644 --- a/include/html_messagebox.h +++ b/include/html_messagebox.h @@ -1,6 +1,7 @@ #ifndef _html_messagebox_ #define _html_messagebox_ + /** @file Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder. @@ -8,7 +9,10 @@ Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder. #include <../common/dialogs/dialog_display_info_HTML_base.h> -/** Implementing HTML_MESSAGE_BOX */ + +/** + * Class HTML_MESSAGE_BOX + */ class HTML_MESSAGE_BOX : public DIALOG_DISPLAY_HTML_TEXT_BASE { protected: @@ -16,8 +20,10 @@ protected: void OnCloseButtonClick( wxCommandEvent& event ); public: - /** Constructor */ - HTML_MESSAGE_BOX( wxWindow* parent, const wxString & aTitle, + /** + * Constructor + */ + HTML_MESSAGE_BOX( wxWindow* parent, const wxString& aTitle, wxPoint aPos = wxDefaultPosition, wxSize aSize = wxSize( 450,250 ) ); @@ -26,28 +32,30 @@ public: * Add a list of items. * @param aList = a string containing items. Items are separated by '\n' */ - void ListSet(const wxString &aList); + void ListSet( const wxString& aList ); + /** * Function ListSet * Add a list of items. * @param aList = a wxArrayString containing items. */ - void ListSet(const wxArrayString &aList); + void ListSet( const wxArrayString& aList ); void ListClear(); + /** * Function MessageSet - * Add a message (in bold) to message list. + * adds a message (in bold) to message list. * @param message = the message */ - void MessageSet(const wxString &message); + void MessageSet( const wxString& message ); /** * Function AddHTML_Text - * Add a html text (without any change) to message list. + * adds html text (without any change) to message list. * @param message = the text to add */ - void AddHTML_Text(const wxString &message); + void AddHTML_Text( const wxString& message ); }; #endif // _html_messagebox_ diff --git a/include/ki_mutex.h b/include/ki_mutex.h new file mode 100644 index 0000000000..1ae45155c0 --- /dev/null +++ b/include/ki_mutex.h @@ -0,0 +1,33 @@ + +#ifndef KI_MUTEX_H_ +#define KI_MUTEX_H_ + + +/// Establish KiCad MUTEX choices here in this file: +/// typedef MUTEX and typedef MUTLOCK. +/// +/// Using an unnamed resource is easier, providing a textual name for a +/// constructor is cumbersome, so we make choice on that criteria mostly: + +#if 0 + +// This is a fine choice between the two, but requires linking to ${Boost_LIBRARIES} +// which currently only happens when GITHUB_PLUGIN goes into pcbnew or _pcbnew. +// cvpcb is left out. Changing the 4 CMakeLists.txts fixes all this easily. + +#include +#include + +typedef boost::interprocess::interprocess_mutex MUTEX; +typedef boost::interprocess::scoped_lock MUTLOCK; + +#else + +#include + +typedef wxMutex MUTEX; +typedef wxMutexLocker MUTLOCK; + +#endif + +#endif // KI_MUTEX_H_ diff --git a/include/richio.h b/include/richio.h index dba6e95952..dc66d6c82b 100644 --- a/include/richio.h +++ b/include/richio.h @@ -93,7 +93,7 @@ std::string /** * Struct IO_ERROR - * is a class used to hold an error message and may be used to throw exceptions + * is a class used to hold an error message and may be used when throwing exceptions * containing meaningful error messages. * @author Dick Hollenbeck */ @@ -148,7 +148,9 @@ struct IO_ERROR // : std::exception IO_ERROR() {} - ~IO_ERROR() throw ( /*none*/ ){} + // Destructor is virtual because PARSE_ERROR is derived from it and + // boost::ptr_vector lists consisting of both will need a virtual destructor. + virtual ~IO_ERROR() throw ( /*none*/ ){} }; diff --git a/include/utf8.h b/include/utf8.h new file mode 100644 index 0000000000..4f5bf6d856 --- /dev/null +++ b/include/utf8.h @@ -0,0 +1,203 @@ +#ifndef UTF8_H_ +#define UTF8_H_ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +/** + * Class UTF8 + * is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special + * conversion support to and from wxString, and has iteration over unicode characters. + * + *

    I've been careful to supply only conversion facilities and not try + * and duplicate wxString() with many member functions. In the end it is + * to be a std::string. There are multiple ways to create text into a std::string + * without the need of too many member functions: + * + *

      + *
    • richio.h's StrPrintf()
    • + *
    • std::ostringstream.
    • + *
    + * + *

    Because this class used no virtuals, it should be possible to cast any + * std::string into a UTF8 using this kind of cast: (UTF8 &) without construction + * or copying being the effect of the cast. Be sure the source std::string holds + * UTF8 encoded text before you do that. + * + * @author Dick Hollenbeck + */ +class UTF8 : public std::string +{ +public: + + UTF8( const wxString& o ); + + /// This is the only constructor for which you could end up with + /// non-UTF8 encoding, but that would be your fault. + UTF8( const char* txt ) : + std::string( txt ) + { + } + + /// For use with _() function on wx 2.8: + UTF8( const wchar_t* txt ); + + explicit UTF8( const std::string& o ) : + std::string( o ) + { + } + + UTF8() : + std::string() + { + } + + UTF8& operator=( const wxString& o ); + + UTF8& operator=( const std::string& o ) + { + std::string::operator=( o ); + return *this; + } + + operator wxString () const; + + /// This one is not in std::string, and one wonders why... might be a solid + /// enough reason to remove it still. + operator char* () const + { + return (char*) c_str(); + } + + /** + * Function uni_forward + * advances over a single UTF8 encoded multibyte character, capturing the + * unicode character as it goes, and returning the number of bytes consumed. + * + * @param aSequence is the UTF8 byte sequence, must be aligned on start of character. + * @param aResult is where to put the unicode character, and may be NULL if no interest. + * @return int - the count of bytes consumed. + */ + static int uni_forward( const unsigned char* aSequence, unsigned* aResult = NULL ); + + /** + * class uni_iter + * is a non-muting iterator that walks through unicode code points in the UTF8 encoded + * string. The normal ++(), ++(int), ->(), and *() operators are all supported + * for read only access and they return an unsigned holding the unicode character + * appropriate for the respective operator. + */ + class uni_iter + { + friend class UTF8; + + const unsigned char* it; + + // private constructor. + uni_iter( const char* start ) : + it( (const unsigned char*) start ) + { + // for the human: assert( sizeof(unsigned) >= 4 ); + } + + + public: + + uni_iter( const uni_iter& o ) + { + it = o.it; + } + + /// pre-increment and return uni_iter at new position + const uni_iter& operator++() + { + it += uni_forward( it ); + + return *this; + } + + /// post-increment and return uni_iter at initial position + uni_iter operator++( int ) + { + uni_iter ret = *this; + + it += uni_forward( it ); + return ret; + } + + /* + /// return unicode at current position + unsigned operator->() const + { + unsigned result; + + // grab the result, do not advance + uni_forward( it, &result ); + return result; + } + */ + + /// return unicode at current position + unsigned operator*() const + { + unsigned result; + + // grab the result, do not advance + uni_forward( it, &result ); + return result; + } + + bool operator==( const uni_iter& other ) const { return it == other.it; } + bool operator!=( const uni_iter& other ) const { return it != other.it; } + + /// Since the ++ operators advance more than one byte, this is your best + /// loop termination test, < end(), not == end(). + bool operator< ( const uni_iter& other ) const { return it < other.it; } + bool operator<=( const uni_iter& other ) const { return it <= other.it; } + bool operator> ( const uni_iter& other ) const { return it > other.it; } + bool operator>=( const uni_iter& other ) const { return it >= other.it; } + }; + + /** + * Function ubegin + * returns a @a uni_iter initialized to the start of "this" UTF8 byte sequence. + */ + uni_iter ubegin() const + { + return uni_iter( data() ); + } + + /** + * Function uend + * returns a @a uni_iter initialized to the end of "this" UTF8 byte sequence. + */ + uni_iter uend() const + { + return uni_iter( data() + size() ); + } +}; + +#endif // UTF8_H__ diff --git a/pcb_calculator/UnitSelector.cpp b/pcb_calculator/UnitSelector.cpp index dca045cab1..4ede6764fe 100644 --- a/pcb_calculator/UnitSelector.cpp +++ b/pcb_calculator/UnitSelector.cpp @@ -28,20 +28,20 @@ double UNIT_SELECTOR_LEN::GetUnitScale() { switch( GetCurrentSelection() ) { - case 0: return UNIT_MM; break; - case 1: return UNIT_MICRON; break; - case 2: return UNIT_CM; break; - case 3: return UNIT_MIL; break; - case 4: return UNIT_INCH; break; + case 0: return UNIT_MM; break; + case 1: return UNIT_MICRON; break; + case 2: return UNIT_CM; break; + case 3: return UNIT_MIL; break; + case 4: return UNIT_INCH; break; } return 1.0; } -UNIT_SELECTOR_FREQUENCY::UNIT_SELECTOR_FREQUENCY(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - const wxArrayString& choices, long style ) - : UNIT_SELECTOR( parent, id, pos, size, choices, style ) +UNIT_SELECTOR_FREQUENCY::UNIT_SELECTOR_FREQUENCY( wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + const wxArrayString& choices, long style ): + UNIT_SELECTOR( parent, id, pos, size, choices, style ) { Append( _("GHz") ); Append( _("MHz") ); @@ -58,19 +58,19 @@ double UNIT_SELECTOR_FREQUENCY::GetUnitScale() { switch( GetCurrentSelection() ) { - case 0: return UNIT_GHZ; break; - case 1: return UNIT_MHZ; break; - case 2: return UNIT_KHZ; break; - case 3: return 1.0; break; + case 0: return UNIT_GHZ; + case 1: return UNIT_MHZ; + case 2: return UNIT_KHZ; + case 3: return 1.0; } return 1.0; } -UNIT_SELECTOR_ANGLE::UNIT_SELECTOR_ANGLE(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - const wxArrayString& choices, long style ) - : UNIT_SELECTOR( parent, id, pos, size, choices, style ) +UNIT_SELECTOR_ANGLE::UNIT_SELECTOR_ANGLE( wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + const wxArrayString& choices, long style ) : + UNIT_SELECTOR( parent, id, pos, size, choices, style ) { Append( _("Radian") ); Append( _("Degree") ); @@ -85,8 +85,8 @@ double UNIT_SELECTOR_ANGLE::GetUnitScale() { switch( GetCurrentSelection() ) { - case 0: return UNIT_RADIAN; break; - case 1: return UNIT_DEGREE; break; + case 0: return UNIT_RADIAN; break; + case 1: return UNIT_DEGREE; break; } return 1.0; } @@ -111,8 +111,8 @@ double UNIT_SELECTOR_RESISTOR::GetUnitScale() { switch( GetCurrentSelection() ) { - case 0: return UNIT_OHM; break; - case 1: return UNIT_KOHM; break; + case 0: return UNIT_OHM; break; + case 1: return UNIT_KOHM; break; } return 1.0; } diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 360f98a5c3..7c4f4f471d 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -372,8 +372,8 @@ if( KICAD_SCRIPTING_MODULES ) polygon bitmaps gal - ${GLEW_LIBRARIES} - ${CAIRO_LIBRARIES} + ${GLEW_LIBRARIES} + ${CAIRO_LIBRARIES} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${GDI_PLUS_LIBRARIES} @@ -548,20 +548,20 @@ target_link_libraries( pcbnew ${GDI_PLUS_LIBRARIES} ${PYTHON_LIBRARIES} ${PCBNEW_EXTRA_LIBS} - ${GLEW_LIBRARIES} - ${CAIRO_LIBRARIES} + ${GLEW_LIBRARIES} + ${CAIRO_LIBRARIES} ) # Only for win32 cross compilation using MXE if( WIN32 AND MSYS AND CMAKE_CROSSCOMPILING ) target_link_libraries(pcbnew - opengl32 - glu32 - pixman-1 - fontconfig - freetype - bz2 - ) + opengl32 + glu32 + pixman-1 + fontconfig + freetype + bz2 + ) endif() if( MAKE_LINK_MAPS ) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index a38c5aa9f9..e7c5b3fcee 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -537,18 +537,11 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow, wxASSERT( aTable != NULL ); - if( !MList.ReadFootprintFiles( aTable, !aLibraryName ? NULL : &aLibraryName ) ) + MList.ReadFootprintFiles( aTable, !aLibraryName ? NULL : &aLibraryName ); + + if( MList.GetErrorCount() ) { - msg.Format( _( "Error occurred attempting to load footprint library '%s':\n\n" ), - GetChars( aLibraryName ) ); - - if( !MList.m_filesNotFound.IsEmpty() ) - msg += _( "Files not found:\n\n" ) + MList.m_filesNotFound; - - if( !MList.m_filesInvalid.IsEmpty() ) - msg += _("\n\nFile load errors:\n\n" ) + MList.m_filesInvalid; - - DisplayError( this, msg ); + MList.DisplayErrors( this ); return wxEmptyString; } @@ -587,7 +580,7 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow, { for( unsigned ii = 0; ii < MList.GetCount(); ii++ ) { - wxString& candidate = MList.GetItem( ii ).m_Module; + const wxString& candidate = MList.GetItem( ii ).m_Module; if( WildCompareString( aMask, candidate, false ) ) { @@ -648,18 +641,18 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow, } -static void DisplayCmpDoc( wxString& Name ) +static void DisplayCmpDoc( wxString& aName ) { - FOOTPRINT_INFO* module_info = MList.GetModuleInfo( Name ); + const FOOTPRINT_INFO* module_info = MList.GetModuleInfo( aName ); if( !module_info ) { - Name.Empty(); + aName.Empty(); return; } - Name = _( "Description: " ) + module_info->m_Doc; - Name += _( "\nKey words: " ) + module_info->m_KeyWord; + aName = _( "Description: " ) + module_info->m_Doc; + aName += _( "\nKey words: " ) + module_info->m_KeyWord; } diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index dbe5ec59a5..48ab375e13 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -385,43 +385,29 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() return; } - bool libLoaded = false; FOOTPRINT_LIST fp_info_list; wxArrayString libsList; #if !defined( USE_FP_LIB_TABLE ) libsList.Add( m_libraryName ); - libLoaded = fp_info_list.ReadFootprintFiles( libsList ); + fp_info_list.ReadFootprintFiles( libsList ); #else - libLoaded = fp_info_list.ReadFootprintFiles( m_footprintLibTable, &m_libraryName ); + fp_info_list.ReadFootprintFiles( m_footprintLibTable, &m_libraryName ); #endif - if( !libLoaded ) + if( fp_info_list.GetErrorCount() ) { - m_footprintName = wxEmptyString; - m_libraryName = wxEmptyString; - - wxString msg; - msg.Format( _( "Error occurred attempting to load footprint library <%s>:\n\n" ), - GetChars( m_libraryName ) ); - - if( !fp_info_list.m_filesNotFound.IsEmpty() ) - msg += _( "Files not found:\n\n" ) + fp_info_list.m_filesNotFound; - - if( !fp_info_list.m_filesInvalid.IsEmpty() ) - msg += _( "\n\nFile load errors:\n\n" ) + fp_info_list.m_filesInvalid; - - DisplayError( this, msg ); + fp_info_list.DisplayErrors( this ); return; } wxArrayString fpList; - BOOST_FOREACH( FOOTPRINT_INFO& footprint, fp_info_list.m_List ) + BOOST_FOREACH( const FOOTPRINT_INFO& footprint, fp_info_list.GetList() ) { fpList.Add( footprint.m_Module ); } @@ -538,23 +524,23 @@ void FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::LoadSettings( ) { - wxConfig* cfg ; - EDA_DRAW_FRAME::LoadSettings(); wxConfigPathChanger cpc( wxGetApp().GetSettings(), m_configPath ); - cfg = wxGetApp().GetSettings(); + + // wxConfig* cfg = + wxGetApp().GetSettings(); } void FOOTPRINT_VIEWER_FRAME::SaveSettings() { - wxConfig* cfg; - EDA_DRAW_FRAME::SaveSettings(); wxConfigPathChanger cpc( wxGetApp().GetSettings(), m_configPath ); - cfg = wxGetApp().GetSettings(); + + // wxConfig* cfg = + wxGetApp().GetSettings(); }