diff --git a/CMakeLists.txt b/CMakeLists.txt index d009bd529c..5a0c3879f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,13 +364,13 @@ check_find_package_result( OPENGL_FOUND "OpenGL" ) # https://www.mail-archive.com/cmake@cmake.org/msg47501.html # Handle target used to specify if a target needs wx-widgets or other libraries -# Always defined, empty if no libraries are to be build +# Always defined, empty if no libraries are to be built add_custom_target( lib-dependencies ) if( KICAD_BUILD_STATIC OR KICAD_BUILD_DYNAMIC ) - # This should be build in all cases, if swig exec is not avaiable - # will be impossible also enable SCRIPTING being for PCBNEW required immediatly + # This should be built in all cases, if swig exec is not avaiable + # will be impossible also enable SCRIPTING being for PCBNEW required immediately include( download_pcre ) include( download_swig ) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 406e707cef..899bb609fa 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -172,6 +172,7 @@ set( COMMON_SRCS eda_dde.cpp eda_doc.cpp filter_reader.cpp +# findkicadhelppath.cpp.notused deprecated, use searchhelpfilefullpath.cpp gestfich.cpp getrunningmicrosecs.cpp grid_tricks.cpp @@ -189,6 +190,7 @@ set( COMMON_SRCS ptree.cpp reporter.cpp richio.cpp + searchhelpfilefullpath.cpp search_stack.cpp selcolor.cpp systemdirsappend.cpp diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 3efb4af478..f8a170211a 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -271,6 +271,18 @@ wxConfigBase* EDA_BASE_FRAME::config() } +const SEARCH_STACK& EDA_BASE_FRAME::sys_search() +{ + return Kiface().KifaceSearch(); +} + + +wxString EDA_BASE_FRAME::help_name() +{ + return Kiface().GetHelpFileName(); +} + + void EDA_BASE_FRAME::PrintMsg( const wxString& text ) { SetStatusText( text ); @@ -327,33 +339,28 @@ wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type, void EDA_BASE_FRAME::GetKicadHelp( wxCommandEvent& event ) { - wxString msg; + const SEARCH_STACK& search = sys_search(); /* We have to get document for beginners, - * or the the full specific doc + * or the full specific doc * if event id is wxID_INDEX, we want the document for beginners. * else the specific doc file (its name is in Kiface().GetHelpFileName()) * The document for beginners is the same for all KiCad utilities */ if( event.GetId() == wxID_INDEX ) { - // Temporarily change the help filename - wxString tmp = Kiface().GetHelpFileName(); - // Search for "getting_started_in_kicad.pdf" or "Getting_Started_in_KiCad.pdf" - Kiface().SetHelpFileName( wxT( "getting_started_in_kicad.pdf" ) ); - wxString helpFile = Kiface().GetHelpFile(); + wxString helpFile = SearchHelpFileFullPath( search, wxT( "getting_started_in_kicad.pdf" ) ); if( !helpFile ) - { // Try to find "Getting_Started_in_KiCad.pdf" - Kiface().SetHelpFileName( wxT( "Getting_Started_in_KiCad.pdf" ) ); - helpFile = Kiface().GetHelpFile(); - } + helpFile = SearchHelpFileFullPath( search, wxT( "Getting_Started_in_KiCad.pdf" ) ); if( !helpFile ) { - msg.Printf( _( "Help file %s could not be found." ), - GetChars( Kiface().GetHelpFileName() ) ); + wxString msg = wxString::Format( _( + "Help file '%s' could not be found." ), + wxT( "getting_started_in_kicad.pdf" ) + ); wxMessageBox( msg ); } else @@ -361,36 +368,36 @@ void EDA_BASE_FRAME::GetKicadHelp( wxCommandEvent& event ) GetAssociatedDocument( this, helpFile ); } - Kiface().SetHelpFileName( tmp ); return; } + wxString base_name = help_name(); + #if defined ONLINE_HELP_FILES_FORMAT_IS_HTML - if( Kiface().GetHtmlHelpController() == NULL ) + wxHtmlHelpController* hc = Pgm().GetHtmlHelpController(); + + wxString helpFile = SearchHelpFileFullPath( search, ); + + if( !!helpFile ) { - Kiface().InitOnLineHelp(); + hc->UseConfig( Pgm().CommonSettings() ); + hc->SetTitleFormat( wxT( "KiCad Help" ) ); + hc->AddBook( helpFile ); } - - if( Kiface().GetHtmlHelpController() ) - { - Kiface().GetHtmlHelpController()->DisplayContents(); - Kiface().GetHtmlHelpController()->Display( Kiface().GetHelpFileName() ); - } - else - { - msg.Printf( _( "Help file %s could not be found." ), GetChars( Kiface().GetHelpFileName() ) ); - wxMessageBox( msg ); - } + hc->DisplayContents(); + hc->Display( helpFile ); #elif defined ONLINE_HELP_FILES_FORMAT_IS_PDF - wxString helpFile = Kiface().GetHelpFile(); + wxString helpFile = SearchHelpFileFullPath( search, base_name ); if( !helpFile ) { - msg.Printf( _( "Help file %s could not be found." ), - GetChars( Kiface().GetHelpFileName() ) ); + wxString msg = wxString::Format( _( + "Help file '%s' could not be found." ), + GetChars( base_name ) + ); wxMessageBox( msg ); } else diff --git a/common/eda_doc.cpp b/common/eda_doc.cpp index 8a4dd423ee..407b1c5ed3 100644 --- a/common/eda_doc.cpp +++ b/common/eda_doc.cpp @@ -64,15 +64,19 @@ bool GetAssociatedDocument( wxFrame* aFrame, const wxPathList* aPaths) { - wxString docname, fullfilename, file_ext; + wxString docname, fullfilename; wxString msg; wxString command; bool success = false; // Is an internet url - static const wxString url_header[3] = { wxT( "http:" ), wxT( "ftp:" ), wxT( "www." ) }; + static const wxChar* url_header[3] = { + wxT( "http:" ), + wxT( "ftp:" ), + wxT( "www." ) + }; - for( int ii = 0; ii < 3; ii++ ) + for( unsigned ii = 0; ii < DIM(url_header); ii++ ) { if( aDocName.First( url_header[ii] ) == 0 ) //. seems an internet url { @@ -133,8 +137,9 @@ bool GetAssociatedDocument( wxFrame* aFrame, return false; } - wxFileName CurrentFileName( fullfilename ); - file_ext = CurrentFileName.GetExt(); + wxFileName currentFileName( fullfilename ); + + wxString file_ext = currentFileName.GetExt(); if( file_ext == wxT( "pdf" ) ) { diff --git a/common/findkicadhelppath.cpp.notused b/common/findkicadhelppath.cpp.notused new file mode 100644 index 0000000000..d2d781ef57 --- /dev/null +++ b/common/findkicadhelppath.cpp.notused @@ -0,0 +1,126 @@ + +#include +#include +#include +#include + + +/** + * Function FindKicadHelpPath + * finds the absolute path for KiCad "help" (or "help/<language>") + * Find path kicad/doc/help/xx/ or kicad/doc/help/: + * from BinDir + * else from environment variable KICAD + * else from one of s_HelpPathList + * typically c:/kicad/doc/help or /usr/share/kicad/help + * or /usr/local/share/kicad/help + * (must have kicad in path name) + * + * xx = iso639-1 language id (2 letters (generic) or 4 letters): + * fr = french (or fr_FR) + * en = English (or en_GB or en_US ...) + * de = deutch + * es = spanish + * pt = portuguese (or pt_BR ...) + * + * default = en (if not found = fr) + */ +wxString FindKicadHelpPath() +{ + bool found = false; + wxString bin_dir = Pgm().GetExecutablePath(); + + if( bin_dir.Last() == '/' ) + bin_dir.RemoveLast(); + + wxString fullPath = bin_dir.BeforeLast( '/' ); // cd .. + + fullPath += wxT( "/doc/help/" ); + + wxString localeString = Pgm().GetLocale()->GetCanonicalName(); + + wxString path_tmp = fullPath; + +#ifdef __WINDOWS__ + path_tmp.MakeLower(); +#endif + + if( path_tmp.Contains( wxT( "kicad" ) ) ) + { + if( wxDirExists( fullPath ) ) + found = true; + } + + // find kicad/help/ from environment variable KICAD + if( !found && Pgm().IsKicadEnvVariableDefined() ) + { + fullPath = Pgm().GetKicadEnvVariable() + wxT( "/doc/help/" ); + + if( wxDirExists( fullPath ) ) + found = true; + } + + if( !found ) + { + // Possibilities online help + const static wxChar* possibilities[] = { +#ifdef __WINDOWS__ + wxT( "c:/kicad/doc/help/" ), + wxT( "d:/kicad/doc/help/" ), + wxT( "c:/Program Files/kicad/doc/help/" ), + wxT( "d:/Program Files/kicad/doc/help/" ), +#else + wxT( "/usr/share/doc/kicad/help/" ), + wxT( "/usr/local/share/doc/kicad/help/" ), + wxT( "/usr/local/kicad/doc/help/" ), // default install for "universal + // tarballs" and build for a server + // (new) + wxT( "/usr/local/kicad/help/" ), // default install for "universal + // tarballs" and build for a server + // (old) +#endif + }; + + for( unsigned i=0; i const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString ) @@ -637,177 +635,44 @@ const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString ) 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 - // function. - return wxExpandEnvVars( aString ); -} - -#endif bool FP_LIB_TABLE::IsEmpty( bool aIncludeFallback ) { - if( !aIncludeFallback || (fallBack == NULL) ) + if( !aIncludeFallback || !fallBack ) return rows.empty(); - return fallBack->IsEmpty() && rows.empty(); + return rows.empty() && fallBack->IsEmpty( true ); } -bool FP_LIB_TABLE::ConvertFromLegacy( SEARCH_STACK& aSStack, NETLIST& aNetList, - const wxArrayString& aLibNames, REPORTER* aReporter ) throw( IO_ERROR ) +MODULE* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const FPID& aFootprintId ) + throw( IO_ERROR, PARSE_ERROR ) { - wxString msg; - FPID lastFPID; - COMPONENT* component; - MODULE* module = 0; - bool retv = true; + wxString nickname = aFootprintId.GetLibNickname(); + wxString fpname = aFootprintId.GetFootprintName(); - if( aNetList.IsEmpty() ) - return true; - - aNetList.SortByFPID(); - - wxString libPath; - - PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); - - for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ ) + if( nickname.size() ) { - component = aNetList.GetComponent( ii ); - - // The footprint hasn't been assigned yet so ignore it. - if( component->GetFPID().empty() ) - continue; - - if( component->GetFPID() != lastFPID ) - { - module = NULL; - - for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ ) - { - wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension ); - - libPath = aSStack.FindValidPath( fn ); - - if( !libPath ) - { - if( aReporter ) - { - msg.Printf( _( "Cannot find footprint library file '%s' in any of the " - "KiCad legacy library search paths.\n" ), - GetChars( fn.GetFullPath() ) ); - aReporter->Report( msg ); - } - - retv = false; - continue; - } - - module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() ); - - if( module ) - { - lastFPID = component->GetFPID(); - break; - } - } - } - - if( !module ) - { - if( aReporter ) - { - msg.Printf( _( "Component `%s` footprint '%s' was not found in any legacy " - "library.\n" ), - GetChars( component->GetReference() ), - GetChars( component->GetFPID().Format() ) ); - aReporter->Report( msg ); - } - - // Clear the footprint assignment since the old library lookup method is no - // longer valid. - FPID emptyFPID; - - component->SetFPID( emptyFPID ); - retv = false; - continue; - } - else - { - wxString libNickname; - - FP_LIB_TABLE* cur = this; - - do - { - cur->ensureIndex(); - - for( unsigned i = 0; i < cur->rows.size(); i++ ) - { - wxString uri = cur->rows[i].GetFullURI( true ); - - if( wxFileName::GetPathSeparator() == wxChar( '\\' ) - && uri.Find( wxChar( '/' ) ) >= 0 ) - { - uri.Replace( wxT( "/"), wxT( "\\" ) ); - } -#ifdef __WINDOWS__ - if( uri.CmpNoCase( libPath ) ) -#else - if( uri == libPath ) -#endif - { - libNickname = cur->rows[i].GetNickName(); - break; - } - } - - } while( ( cur = cur->fallBack ) != 0 && libNickname.IsEmpty() ); - - if( libNickname.IsEmpty() ) - { - if( aReporter ) - { - msg.Printf( _( "Component '%s' footprint '%s' legacy library path '%s' " - "was not found in the footprint library table.\n" ), - GetChars( component->GetReference() ), - GetChars( component->GetFPID().Format() ) ); - aReporter->Report( msg ); - } - - retv = false; - } - else - { - FPID newFPID = lastFPID; - newFPID.SetLibNickname( libNickname ); - - if( !newFPID.IsValid() ) - { - if( aReporter ) - { - msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ), - GetChars( component->GetReference() ), - GetChars( newFPID.Format() ) ); - aReporter->Report( msg ); - } - - retv = false; - } - else - { - // The footprint name should already be set. - component->SetFPID( newFPID ); - } - } - } + return FootprintLoad( nickname, fpname ); } - return retv; + // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match: + else + { + std::vector nicks = GetLogicalLibs(); + + // Search each library going through libraries alphabetically. + for( unsigned i = 0; iGetCanonicalName(); - - wxString path_tmp = FullPath; -#ifdef __WINDOWS__ - path_tmp.MakeLower(); -#endif - if( path_tmp.Contains( wxT( "kicad" ) ) ) - { - if( wxDirExists( FullPath ) ) - PathFound = true; - } - - /* find kicad/help/ from environment variable KICAD */ - if( !PathFound && Pgm().IsKicadEnvVariableDefined() ) - { - FullPath = Pgm().GetKicadEnvVariable() + wxT( "/doc/help/" ); - - if( wxDirExists( FullPath ) ) - PathFound = true; - } - - /* find kicad/help/ from "s_HelpPathList" */ - int ii = 0; - - while( !PathFound ) - { - FullPath = s_HelpPathList[ii++]; - - if( FullPath == wxT( "end_list" ) ) - break; - - if( wxDirExists( FullPath ) ) - PathFound = true; - } - - if( PathFound ) - { - LangFullPath = FullPath + LocaleString + UNIX_STRING_DIR_SEP; - - if( wxDirExists( LangFullPath ) ) - return LangFullPath; - - LangFullPath = FullPath + LocaleString.Left( 2 ) + UNIX_STRING_DIR_SEP; - - if( wxDirExists( LangFullPath ) ) - return LangFullPath; - - LangFullPath = FullPath + wxT( "en/" ); - - if( wxDirExists( LangFullPath ) ) - { - return LangFullPath; - } - else - { - LangFullPath = FullPath + wxT( "fr/" ); - - if( wxDirExists( LangFullPath ) ) - return LangFullPath; - } - return FullPath; - } - return wxEmptyString; -} - - wxString FindKicadFile( const wxString& shortname ) { - wxString FullFileName; + // Test the presence of the file in the directory shortname of + // the KiCad binary path. + wxString fullFileName = Pgm().GetExecutablePath() + shortname; - /* Test the presence of the file in the directory shortname of - * the KiCad binary path. - */ - FullFileName = Pgm().GetExecutablePath() + shortname; + if( wxFileExists( fullFileName ) ) + return fullFileName; - if( wxFileExists( FullFileName ) ) - return FullFileName; - - /* Test the presence of the file in the directory shortname - * defined by the environment variable KiCad. - */ + // Test the presence of the file in the directory shortname + // defined by the environment variable KiCad. if( Pgm().IsKicadEnvVariableDefined() ) { - FullFileName = Pgm().GetKicadEnvVariable() + shortname; + fullFileName = Pgm().GetKicadEnvVariable() + shortname; - if( wxFileExists( FullFileName ) ) - return FullFileName; + if( wxFileExists( fullFileName ) ) + return fullFileName; } - /* find binary file from default path list: - * /usr/local/kicad/linux or c:/kicad/winexe - * (see s_KicadDataPathList) */ - int ii = 0; + // find binary file from possibilities list: + // /usr/local/kicad/linux or c:/kicad/winexe - while( 1 ) + // Path list for KiCad binary files + const static wxChar* possibilities[] = { +#ifdef __WINDOWS__ + wxT( "c:/kicad/bin/" ), + wxT( "d:/kicad/bin/" ), + wxT( "c:/Program Files/kicad/bin/" ), + wxT( "d:/Program Files/kicad/bin/" ), +#else + wxT( "/usr/bin/" ), + wxT( "/usr/local/bin/" ), + wxT( "/usr/local/kicad/bin/" ), +#endif + }; + + for( unsigned i=0; i could not found" ), GetChars( FullFileName ) ); + msg.Printf( _( "Command <%s> could not found" ), GetChars( fullFileName ) ); DisplayError( frame, msg, 20 ); return -1; } @@ -452,13 +317,13 @@ int ExecuteFile( wxWindow* frame, const wxString& ExecFile, const wxString& para wxString KicadDatasPath() { - bool PathFound = false; + bool found = false; wxString data_path; if( Pgm().IsKicadEnvVariableDefined() ) // Path defined by the KICAD environment variable. { data_path = Pgm().GetKicadEnvVariable(); - PathFound = true; + found = true; } else // Path of executables. { @@ -485,33 +350,56 @@ wxString KicadDatasPath() if( wxDirExists( data_path ) ) { - PathFound = true; + found = true; } else if( wxDirExists( old_path ) ) { data_path = old_path; - PathFound = true; + found = true; } } } - /* find KiCad from default path list: - * /usr/local/kicad/ or c:/kicad/ - * (see s_KicadDataPathList) */ - int ii = 0; - - while( !PathFound ) + if( !found ) { - if( s_KicadDataPathList[ii] == wxT( "end_list" ) ) - break; + // find KiCad from possibilities list: + // /usr/local/kicad/ or c:/kicad/ - data_path = s_KicadDataPathList[ii++]; + const static wxChar* possibilities[] = { +#ifdef __WINDOWS__ + wxT( "c:/kicad/share/" ), + wxT( "d:/kicad/share/" ), + wxT( "c:/kicad/" ), + wxT( "d:/kicad/" ), + wxT( "c:/Program Files/kicad/share/" ), + wxT( "d:/Program Files/kicad/share/" ), + wxT( "c:/Program Files/kicad/" ), + wxT( "d:/Program Files/kicad/" ), +#else + wxT( "/usr/share/kicad/" ), + wxT( "/usr/local/share/kicad/" ), + wxT( "/usr/local/kicad/share/" ), // default data path for "universal + // tarballs" and build for a server + // (new) + wxT( "/usr/local/kicad/" ), // default data path for "universal + // tarballs" and build for a server + // (old) +#endif + }; - if( wxDirExists( data_path ) ) - PathFound = true; + for( unsigned i=0; i/library and /library/doc if( aId == KIWAY::FACE_SCH ) { + // Add schematic doc file path (library/doc) to search path list. + fn.AppendDir( wxT( "library" ) ); aDst->AddPaths( fn.GetPath() ); - // Add schematic doc file path (library/doc)to search path list. fn.AppendDir( wxT( "doc" ) ); aDst->AddPaths( fn.GetPath() ); @@ -85,8 +86,10 @@ static void setSearchPaths( SEARCH_STACK* aDst, KIWAY::FACE_T aId ) aDst->AddPaths( fn.GetPath() ); } + aDst->AddPaths( wxT( "/usr/local/share" ) ); + #if 1 && defined(DEBUG) - aDst->Show( "kiway" ); + aDst->Show( "kiface" ); #endif } @@ -121,86 +124,3 @@ void KIFACE_I::end_common() m_bm.End(); } - -wxString KIFACE_I::GetHelpFile() -{ - wxString fn; - wxArrayString subdirs; - wxArrayString altsubdirs; - - // FIXME: This is not the ideal way to handle this. Unfortunately, the - // CMake install paths seem to be a moving target so this crude - // hack solves the problem of install path differences between - // Windows and non-Windows platforms. - - // Partially fixed, but must be enhanced - - // Create subdir tree for "standard" linux distributions, when KiCad comes - // from a distribution files are in /usr/share/doc/kicad/help and binaries - // in /usr/bin or /usr/local/bin - subdirs.Add( wxT( "share" ) ); - subdirs.Add( wxT( "doc" ) ); - subdirs.Add( wxT( "kicad" ) ); - subdirs.Add( wxT( "help" ) ); - - // Create subdir tree for linux and Windows KiCad pack. - // Note the pack form under linux is also useful if a user wants to - // install KiCad to a server because there is only one path to mount - // or export (something like /usr/local/kicad). - // files are in /kicad/doc/help - // (often /usr/local/kicad/kicad/doc/help) - // /kicad/ is retrieved from m_BinDir - altsubdirs.Add( wxT( "doc" ) ); - altsubdirs.Add( wxT( "help" ) ); - - /* Search for a help file. - * we *must* find a help file. - * so help is searched in directories in this order: - * help/ like help/en_GB - * help/ like help/en - * help/en - */ - - wxLocale* i18n = Pgm().GetLocale(); - - // Step 1 : Try to find help file in help/ - subdirs.Add( i18n->GetCanonicalName() ); - altsubdirs.Add( i18n->GetCanonicalName() ); - - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &altsubdirs ); - - if( !fn ) - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &subdirs ); - - // Step 2 : if not found Try to find help file in help/ - if( !fn ) - { - subdirs.RemoveAt( subdirs.GetCount() - 1 ); - altsubdirs.RemoveAt( altsubdirs.GetCount() - 1 ); - - // wxLocale::GetName() does not return always the short name - subdirs.Add( i18n->GetName().BeforeLast( '_' ) ); - altsubdirs.Add( i18n->GetName().BeforeLast( '_' ) ); - - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &altsubdirs ); - - if( !fn ) - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &subdirs ); - } - - // Step 3 : if not found Try to find help file in help/en - if( !fn ) - { - subdirs.RemoveAt( subdirs.GetCount() - 1 ); - altsubdirs.RemoveAt( altsubdirs.GetCount() - 1 ); - subdirs.Add( wxT( "en" ) ); - altsubdirs.Add( wxT( "en" ) ); - - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &altsubdirs ); - - if( !fn ) - fn = m_bm.m_search.FindFileInSearchPaths( m_bm.m_help_file, &subdirs ); - } - - return fn; -} diff --git a/common/page_layout/page_layout_reader.cpp b/common/page_layout/page_layout_reader.cpp index f3fc48bbdb..87570b13be 100644 --- a/common/page_layout/page_layout_reader.cpp +++ b/common/page_layout/page_layout_reader.cpp @@ -744,7 +744,7 @@ void WORKSHEET_LAYOUT::SetDefaultLayout() { lp_parser.Parse( this ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogMessage( ioe.errorText ); } @@ -765,7 +765,7 @@ void WORKSHEET_LAYOUT::SetPageLayout( const char* aPageLayout, bool Append ) { lp_parser.Parse( this ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogMessage( ioe.errorText ); } @@ -828,7 +828,7 @@ void WORKSHEET_LAYOUT::SetPageLayout( const wxString& aFullFileName, bool Append { lp_parser.Parse( this ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogMessage( ioe.errorText ); } diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index e0af909af6..1789f939ed 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -297,6 +297,13 @@ void PGM_BASE::destroy() delete m_locale; m_locale = 0; + /* + // Close the help frame + if( m_html_ctrl && m_html_ctrl->GetFrame() ) // returns NULL if no help frame active + m_html_ctrl->GetFrame()->Close( true ); + } + */ + delete m_html_ctrl; m_html_ctrl = 0; } @@ -415,30 +422,18 @@ bool PGM_BASE::initPgm() } -void PGM_BASE::SetHtmlHelpController( wxHtmlHelpController* aController ) +void PGM_BASE::initHtmlHelpController() { - delete m_html_ctrl; - m_html_ctrl = aController; -} - - -void PGM_BASE::InitOnLineHelp() -{ - wxString fullfilename = FindKicadHelpPath(); - #if defined ONLINE_HELP_FILES_FORMAT_IS_HTML - m_HelpFileName = fullfilename + wxT( ".html" ); - fullfilename += wxT( "kicad.hhp" ); - if( wxFileExists( fullfilename ) ) - { - m_html_ctrl = new wxHtmlHelpController( wxHF_TOOLBAR | wxHF_CONTENTS | - wxHF_PRINT | wxHF_OPEN_FILES - /*| wxHF_SEARCH */ ); - m_html_ctrl->UseConfig( m_common_settings ); - m_html_ctrl->SetTitleFormat( wxT( "KiCad Help" ) ); - m_html_ctrl->AddBook( fullfilename ); - } + if( !m_html_ctrl ) + m_html_ctrl = new wxHtmlHelpController( + wxHF_TOOLBAR | wxHF_CONTENTS | + wxHF_PRINT | wxHF_OPEN_FILES + // | wxHF_SEARCH + ); + + wxASSERT( m_html_ctrl ); // may not leave here as NULL #elif defined ONLINE_HELP_FILES_FORMAT_IS_PDF m_html_ctrl = NULL; @@ -449,10 +444,22 @@ void PGM_BASE::InitOnLineHelp() } +wxHtmlHelpController* PGM_BASE::HtmlHelpController() +{ + if( !m_html_ctrl ) + initHtmlHelpController(); + + // there should not be calls to this unless ONLINE_HELP_FILES_FORMAT_IS_HTML is defined + wxASSERT( m_html_ctrl ); + + return m_html_ctrl; +} + + + bool PGM_BASE::setExecutablePath() { -// Apple MacOSx -#ifdef __APPLE__ +#ifdef __APPLE__ // Apple MacOSx // Derive path from location of the app bundle CFBundleRef mainBundle = CFBundleGetMainBundle(); diff --git a/common/project.cpp b/common/project.cpp index b69926e574..002bfa7d4f 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -23,18 +23,19 @@ */ +#include + #include #include #include #include #include -#include +#include #include #include #include - PROJECT::PROJECT() { memset( m_elems, 0, sizeof(m_elems) ); @@ -198,18 +199,18 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& const wxString& aGroupName, bool aForceUseLocalConfig ) { wxConfigBase* cfg = 0; - wxFileName fn = aFileName; + wxFileName fn = aFileName; fn.SetExt( ProjectFileExtension ); + wxString cur_pro_fn = fn.GetFullPath(); + // is there an edge transition, a change in m_project_filename? - if( m_project_name != fn ) + if( m_project_name != cur_pro_fn ) { m_sch_search.Clear(); - SetProjectFullName( fn.GetFullPath() ); - - // to the empty list, add project dir as first + // to the empty lists, add project dir as first m_sch_search.AddPaths( fn.GetPath() ); // append all paths from aSList @@ -228,8 +229,6 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& // Init local config filename if( aForceUseLocalConfig || fn.FileExists() ) { - wxString cur_pro_fn = fn.GetFullPath(); - cfg = new wxFileConfig( wxEmptyString, wxEmptyString, cur_pro_fn, wxEmptyString ); cfg->DontCreateOnDemand(); @@ -262,31 +261,43 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& } else // Version incorrect { + wxLogDebug( wxT( "Project file version is zero, not using this old project file, going with template." ) ); delete cfg; cfg = 0; } } - // Search for the template kicad.pro file by using caller's SEARCH_STACK. + // No suitable pro file was found, either does not exist, or is too old. + // Use the template kicad.pro file. Find it by using caller's SEARCH_STACK. wxString kicad_pro_template = aSList.FindValidPath( wxT( "kicad.pro" ) ); if( !kicad_pro_template ) { - wxLogDebug( wxT( "Template file not found." ) ); + wxLogDebug( wxT( "Template file not found using search paths." ) ); - fn = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), - wxT( "kicad" ), ProjectFileExtension ); - } - else - { - fn = kicad_pro_template; + wxFileName templ( wxStandardPaths::Get().GetDocumentsDir(), + wxT( "kicad" ), ProjectFileExtension ); + + if( !templ.IsFileReadable() ) + { + wxString msg = wxString::Format( _( "Unable to find kicad.pro template file." ) ); + + DisplayError( NULL, msg ); + + return NULL; + } + + kicad_pro_template = templ.GetFullPath(); } - cfg = new wxFileConfig( wxEmptyString, wxEmptyString, wxEmptyString, fn.GetFullPath() ); + // copy the template to cur_pro_fn, and open it at that destination. + wxCopyFile( kicad_pro_template, cur_pro_fn ); + cfg = new wxFileConfig( wxEmptyString, wxEmptyString, cur_pro_fn, wxEmptyString ); + cfg->DontCreateOnDemand(); - SetProjectFullName( fn.GetFullPath() ); + SetProjectFullName( cur_pro_fn ); return cfg; } @@ -296,6 +307,12 @@ void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aFileName { std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, FORCE_LOCAL_CONFIG ) ); + if( !cfg.get() ) + { + // could not find template + return; + } + cfg->SetPath( wxCONFIG_PATH_SEPARATOR ); cfg->Write( wxT( "update" ), DateAndTime() ); @@ -326,6 +343,12 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, { std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, false ) ); + if( !cfg.get() ) + { + // could not find template + return false; + } + cfg->SetPath( wxCONFIG_PATH_SEPARATOR ); wxString timestamp = cfg->Read( wxT( "update" ) ); diff --git a/common/search_stack.cpp b/common/search_stack.cpp index f4792f89c2..d9f6a5c870 100644 --- a/common/search_stack.cpp +++ b/common/search_stack.cpp @@ -104,31 +104,6 @@ void SEARCH_STACK::AddPaths( const wxString& aPaths, int aIndex ) } -wxString SEARCH_STACK::FindFileInSearchPaths( - const wxString& aFilename, const wxArrayString* aSubdirs ) -{ - wxPathList paths; - - for( unsigned i = 0; i < GetCount(); ++i ) - { - wxFileName fn( (*this)[i] ); - - if( aSubdirs ) - { - for( unsigned j = 0; j < aSubdirs->GetCount(); j++ ) - fn.AppendDir( (*aSubdirs)[j] ); - } - - if( fn.DirExists() ) - { - paths.Add( fn.GetPath() ); - } - } - - return paths.FindValidPath( aFilename ); -} - - void RETAINED_PATH::Clear() { m_retained_path.Clear(); diff --git a/common/searchhelpfilefullpath.cpp b/common/searchhelpfilefullpath.cpp new file mode 100644 index 0000000000..3ce17dfbd2 --- /dev/null +++ b/common/searchhelpfilefullpath.cpp @@ -0,0 +1,128 @@ + +#include +#include + + + +/** + * Function FindFileInSearchPaths + * looks in "this" for \a aFilename, but first modifies every search + * path by appending a list of path fragments from aSubdirs. That modification + * is not rentative. + */ +wxString FindFileInSearchPaths( const SEARCH_STACK& aStack, + const wxString& aFilename, const wxArrayString* aSubdirs ) +{ + wxPathList paths; + + for( unsigned i = 0; i < aStack.GetCount(); ++i ) + { + wxFileName fn( aStack[i], wxEmptyString ); + + if( aSubdirs ) + { + for( unsigned j = 0; j < aSubdirs->GetCount(); j++ ) + fn.AppendDir( (*aSubdirs)[j] ); + } + + if( fn.DirExists() ) + { + paths.Add( fn.GetPath() ); + } + } + + return paths.FindValidPath( aFilename ); +} + + +// See also FindKicadHelpPath.cpp.notused. +wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aBaseName ) +{ + wxArrayString subdirs; + wxArrayString altsubdirs; + SEARCH_STACK ss = aSStack; + + // It might already be in aSStack, but why depend on other code + // far away when it's so easy to add it again (to our copy) as the first place to look. + // This is CMAKE_INSTALL_PREFIX: + ss.AddPaths( wxT( DEFAULT_INSTALL_PATH ), 0 ); + + // If there's a KICAD environment variable set, use that guy's path also + ss.AddPaths( Pgm().GetKicadEnvVariable(), 0 ); + +#if 1 // && defined(__linux__) + // Based on kicad-doc.bzr/CMakeLists.txt, line 20, the help files are + // installed into "/share/doc/kicad/help" for linux. + // This is ${KICAD_HELP} var in that CMakeLists.txt file. + // Below we account for an international subdirectory. + subdirs.Add( wxT( "share" ) ); + subdirs.Add( wxT( "doc" ) ); + subdirs.Add( wxT( "kicad" ) ); + subdirs.Add( wxT( "help" ) ); +#endif + +#if 1 // && defined(__WINDOWS__) + // Based on kicad-doc.bzr/CMakeLists.txt, line 35, the help files are + // installed into "/doc/help" for Windows. + // This is ${KICAD_HELP} var in that CMakeLists.txt file. + // Below we account for an international subdirectory. + altsubdirs.Add( wxT( "doc" ) ); + altsubdirs.Add( wxT( "help" ) ); +#endif + + /* Search for a help file. + * we *must* find a help file. + * so help is searched in directories in this order: + * help/ like help/en_GB + * help/ like help/en + * help/en + */ + + wxLocale* i18n = Pgm().GetLocale(); + + // Step 1 : Try to find help file in help/ + subdirs.Add( i18n->GetCanonicalName() ); + altsubdirs.Add( i18n->GetCanonicalName() ); + +#if defined(DEBUG) && 0 + ss.Show( __func__ ); + printf( "%s: m_help_file:'%s'\n", __func__, TO_UTF8( aBaseName ) ); +#endif + + wxString fn = FindFileInSearchPaths( ss, aBaseName, &altsubdirs ); + + if( !fn ) + fn = FindFileInSearchPaths( ss, aBaseName, &subdirs ); + + // Step 2 : if not found Try to find help file in help/ + if( !fn ) + { + subdirs.RemoveAt( subdirs.GetCount() - 1 ); + altsubdirs.RemoveAt( altsubdirs.GetCount() - 1 ); + + // wxLocale::GetName() does not return always the short name + subdirs.Add( i18n->GetName().BeforeLast( '_' ) ); + altsubdirs.Add( i18n->GetName().BeforeLast( '_' ) ); + + fn = FindFileInSearchPaths( ss, aBaseName, &altsubdirs ); + + if( !fn ) + fn = FindFileInSearchPaths( ss, aBaseName, &subdirs ); + } + + // Step 3 : if not found Try to find help file in help/en + if( !fn ) + { + subdirs.RemoveAt( subdirs.GetCount() - 1 ); + altsubdirs.RemoveAt( altsubdirs.GetCount() - 1 ); + subdirs.Add( wxT( "en" ) ); + altsubdirs.Add( wxT( "en" ) ); + + fn = FindFileInSearchPaths( ss, aBaseName, &altsubdirs ); + + if( !fn ) + fn = FindFileInSearchPaths( ss, aBaseName, &subdirs ); + } + + return fn; +} diff --git a/common/single_top.cpp b/common/single_top.cpp index efb530e261..19104c4261 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -34,6 +34,7 @@ */ +#include #include #include #include @@ -182,10 +183,6 @@ static const wxString dso_full_path( const wxString& aAbsoluteArgv0 ) return fn.GetFullPath(); } -// Use of this is arbitrary, remember single_top only knows about a single DSO. -// Could have used one from the KIWAY also. -static wxDynamicLibrary dso; - // Only a single KIWAY is supported in this single_top top level component, // which is dedicated to loading only a single DSO. @@ -230,6 +227,32 @@ struct APP_SINGLE_TOP : public wxApp return wxApp::OnExit(); } + int OnRun() // overload wxApp virtual + { + try + { + return wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) );; + } + catch( const IO_ERROR& ioe ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid( ioe ).name() ) ), + GetChars( ioe.errorText ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + return -1; + } + /** * Function MacOpenFile * is specific to MacOSX (not used under Linux or Windows). @@ -261,6 +284,15 @@ IMPLEMENT_APP( APP_SINGLE_TOP ); static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName ) { #if defined(BUILD_KIWAY_DLL) + + // Remember single_top only knows about a single DSO. Using an automatic + // with a defeated destructor, see Detach() below, so that the DSO program + // image stays in RAM until process termination, and specifically + // beyond the point in time at which static destructors are run. Otherwise + // a static wxDynamicLibrary's destructor might create an out of sequence + // problem. This was never detected, so it's only a preventative strategy. + wxDynamicLibrary dso; + void* addr = NULL; if( !dso.Load( aDSOName, wxDL_VERBATIM | wxDL_NOW ) ) @@ -275,6 +307,9 @@ static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName ) // No further reporting required here. } + // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. + (void) dso.Detach(); + return (KIFACE_GETTER_FUNC*) addr; #else diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp index 2b40fa4e40..9a96a02457 100644 --- a/cvpcb/autosel.cpp +++ b/cvpcb/autosel.cpp @@ -107,7 +107,7 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) { fn.SetExt( fn.GetExt() + wxT( "." ) + FootprintAliasFileExtension ); } - tmp = search.FindValidPath( fn ); + tmp = search.FindValidPath( fn.GetFullPath() ); if( !tmp ) { diff --git a/cvpcb/cfg.cpp b/cvpcb/cfg.cpp index c7b5986362..55d2091048 100644 --- a/cvpcb/cfg.cpp +++ b/cvpcb/cfg.cpp @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include #include @@ -42,29 +42,24 @@ #include -#define GROUP wxT("/cvpcb") -#define GROUPLIB wxT("/pcbnew/libraries") -#define GROUPEQU wxT("/cvpcb/libraries") - - PARAM_CFG_ARRAY& CVPCB_MAINFRAME::GetProjectFileParameters() { if( !m_projectFileParams.empty() ) return m_projectFileParams; - m_projectFileParams.push_back( new PARAM_CFG_BASE( GROUPLIB, PARAM_COMMAND_ERASE ) ); + m_projectFileParams.push_back( new PARAM_CFG_BASE( GROUP_PCB_LIBS, PARAM_COMMAND_ERASE ) ); m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( - wxT( "LibName" ), &m_ModuleLibNames, GROUPLIB ) ); + wxT( "LibName" ), &m_ModuleLibNames, GROUP_PCB_LIBS ) ); m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( - wxT( "EquName" ), &m_AliasLibNames, GROUPEQU ) ); + wxT( "EquName" ), &m_AliasLibNames, GROUP_CVP_EQU ) ); m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetIExt" ), &m_NetlistFileExtension ) ); m_projectFileParams.push_back( new PARAM_CFG_FILENAME( - wxT( "LibDir" ), &m_UserLibraryPath, GROUPLIB ) ); + wxT( "LibDir" ), &m_UserLibraryPath, GROUP_PCB_LIBS ) ); return m_projectFileParams; } @@ -81,7 +76,7 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName ) fn.SetExt( ProjectFileExtension ); // was: Pgm().ReadProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); - prj.ConfigLoad( prj.PcbSearchS(), fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); + prj.ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_CVP, GetProjectFileParameters(), false ); if( m_NetlistFileExtension.IsEmpty() ) m_NetlistFileExtension = wxT( "net" ); @@ -133,7 +128,7 @@ void CVPCB_MAINFRAME::SaveProjectFile( wxCommandEvent& aEvent ) // Pgm().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() ); PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); - prj.ConfigSave( search, fn.GetFullPath(), GROUP, GetProjectFileParameters() ); + prj.ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_CVP, GetProjectFileParameters() ); } + diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index a43f6bdf99..8ff1330447 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -490,7 +490,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName ) footprint = FootprintLibs()->FootprintLoad( FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 256e12c641..c878e61201 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -301,13 +301,6 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event ) } } - // Close the help frame - if( Pgm().GetHtmlHelpController() ) - { - if( Pgm().GetHtmlHelpController()->GetFrame() )// returns NULL if no help frame active - Pgm().GetHtmlHelpController()->GetFrame()->Close( true ); - } - if( m_NetlistFileName.IsOk() ) { UpdateFileHistory( m_NetlistFileName.GetFullPath() ); @@ -846,7 +839,7 @@ int CVPCB_MAINFRAME::ReadSchematicNetlist() else wxMessageBox( _( "Unknown netlist format." ), wxEmptyString, wxOK | wxICON_ERROR ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index 6c07864ae0..8683d50232 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -119,6 +119,20 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName ) } +#if 0 + + /* + + This code block was based on two major assumptions that are no longer true: + 1) Footprint library basenames would remain the same. + (But no, basenames have been renamed in the github repo.) + 2) *.mod files would still be around and merely reside in the FP_LIB_TABLE. + (But no, they have been converted to *.pretty.) + + There is a newer replacement code block in the #else region. + + */ + /** * Function missingLegacyLibs * tests the list of \a aLibNames by URI to determine if any of them are missing from @@ -138,23 +152,175 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName ) static bool missingLegacyLibs( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, const wxArrayString& aLibNames, wxString* aErrorMsg ) { - bool retv = false; + bool missing = false; for( unsigned i = 0; i < aLibNames.GetCount(); i++ ) { wxFileName fn( wxEmptyString, aLibNames[i], LegacyFootprintLibPathExtension ); - wxString legacyLibPath = aSStack.FindValidPath( fn ); + wxString legacyLibPath = aSStack.FindValidPath( fn.GetFullPath() ); + /* if( legacyLibPath.IsEmpty() ) continue; + */ - if( aTbl->FindRowByURI( legacyLibPath ) == 0 ) + if( !aTbl->FindRowByURI( legacyLibPath ) ) { - retv = true; + missing = true; if( aErrorMsg ) - *aErrorMsg += wxT( "\"" ) + legacyLibPath + wxT( "\"\n" ); + { + *aErrorMsg += wxChar( '"' ); + + if( !legacyLibPath ) + *aErrorMsg += !legacyLibPath ? aLibNames[i] : legacyLibPath; + + *aErrorMsg += wxT( "\"\n" ); + } + } + } + + return missing; +} + + +/** + * Function convertFromLegacy + * converts the footprint names in \a aNetList from the legacy format to the #FPID format. + * + * @param aNetList is the #NETLIST object to convert. + * @param aLibNames is the list of legacy footprint library names from the currently loaded + * project. + * @param aReporter is the #REPORTER object to dump messages into. + * @return true if all footprint names were successfully converted to a valid FPID. + */ +static bool convertFromLegacy( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, NETLIST& aNetList, + const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR ) +{ + wxString msg; + FPID lastFPID; + COMPONENT* component; + MODULE* module = 0; + bool retv = true; + + if( aNetList.IsEmpty() ) + return true; + + aNetList.SortByFPID(); + + wxString libPath; + + PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); + + for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ ) + { + component = aNetList.GetComponent( ii ); + + // The footprint hasn't been assigned yet so ignore it. + if( component->GetFPID().empty() ) + continue; + + if( component->GetFPID() != lastFPID ) + { + module = NULL; + + for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ ) + { + wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension ); + + libPath = aSStack.FindValidPath( fn.GetFullPath() ); + + if( !libPath ) + { + if( aReporter ) + { + msg.Printf( _( "Cannot find footprint library file '%s' in any of the " + "KiCad legacy library search paths.\n" ), + GetChars( fn.GetFullPath() ) ); + aReporter->Report( msg ); + } + + retv = false; + continue; + } + + module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() ); + + if( module ) + { + lastFPID = component->GetFPID(); + break; + } + } + } + + if( !module ) + { + if( aReporter ) + { + msg.Printf( _( "Component '%s' footprint '%s' was not found in any legacy " + "library.\n" ), + GetChars( component->GetReference() ), + GetChars( component->GetFPID().Format() ) ); + aReporter->Report( msg ); + } + + // Clear the footprint assignment since the old library lookup method is no + // longer valid. + FPID emptyFPID; + + component->SetFPID( emptyFPID ); + retv = false; + continue; + } + else + { + wxString libNickname; + + const FP_LIB_TABLE::ROW* row; + + if( ( row = aTbl->FindRowByURI( libPath ) ) != NULL ) + libNickname = row->GetNickName(); + + if( libNickname.IsEmpty() ) + { + if( aReporter ) + { + msg.Printf( _( "Component '%s' with footprint '%s' and legacy library path '%s' " + "was not found in the footprint library table.\n" ), + GetChars( component->GetReference() ), + GetChars( component->GetFPID().Format() ), + GetChars( libPath ) + ); + aReporter->Report( msg ); + } + + retv = false; + } + else + { + FPID newFPID = lastFPID; + newFPID.SetLibNickname( libNickname ); + + if( !newFPID.IsValid() ) + { + if( aReporter ) + { + msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ), + GetChars( component->GetReference() ), + GetChars( newFPID.Format() ) ); + aReporter->Report( msg ); + } + + retv = false; + } + else + { + // The footprint name should already be set. + component->SetFPID( newFPID ); + } + } } } @@ -210,7 +376,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() if( missingLegacyLibs( FootprintLibs(), Prj().PcbSearchS(), m_ModuleLibNames, &missingLibs ) ) { msg = wxT( "The following legacy libraries are defined in the project file " - "were not found in the footprint library table:\n\n" ) + missingLibs; + "but were not found in the footprint library table:\n\n" ) + missingLibs; msg += wxT( "\nDo you want to update the footprint library table before " "attempting to update the assigned footprints?" ); @@ -233,11 +399,11 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() SEARCH_STACK& search = Prj().SchSearchS(); - if( !FootprintLibs()->ConvertFromLegacy( search, m_netlist, m_ModuleLibNames, &reporter ) ) + if( !convertFromLegacy( FootprintLibs(), search, m_netlist, m_ModuleLibNames, &reporter ) ) { HTML_MESSAGE_BOX dlg( this, wxEmptyString ); - dlg.MessageSet( wxT( "The following errors occurred attempt to convert the " + dlg.MessageSet( wxT( "The following errors occurred attempting to convert the " "footprint assignments:\n\n" ) ); dlg.ListSet( msg ); dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them " @@ -291,6 +457,210 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() return true; } +#else // new strategy + +/// Return true if the resultant FPID has a certain nickname. The guess +/// is only made if this footprint resides in only one library. +/// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches +static int guessNickname( FP_LIB_TABLE* aTbl, FPID* aFootprintId ) +{ + if( aFootprintId->GetLibNickname().size() ) + return 0; + + wxString nick; + wxString fpname = aFootprintId->GetFootprintName(); + + std::vector nicks = aTbl->GetLogicalLibs(); + + // Search each library going through libraries alphabetically. + for( unsigned libNdx = 0; libNdxFootprintEnumerate( nicks[libNdx] ); + + for( unsigned nameNdx = 0; nameNdxSetLibNickname( nick ); + return 0; + } + + return 1; +} + + +bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() +{ + wxString msg; + bool hasMissingNicks = false; + FP_LIB_TABLE* tbl = FootprintLibs(); + + ReadSchematicNetlist(); + + if( m_ListCmp == NULL ) + return false; + + LoadProjectFile( m_NetlistFileName.GetFullPath() ); + LoadFootprintFiles(); + BuildFOOTPRINTS_LISTBOX(); + BuildLIBRARY_LISTBOX(); + + m_ListCmp->Clear(); + m_undefinedComponentCnt = 0; + + if( m_netlist.AnyFootprintsLinked() ) + { + for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) + { + COMPONENT* component = m_netlist.GetComponent( i ); + + if( component->GetFPID().empty() ) + continue; + + if( component->GetFPID().IsLegacy() ) + hasMissingNicks = true; + } + } + + // Check if footprint links were generated before the footprint library table was implemented. + if( hasMissingNicks ) + { + msg = wxT( + "Some of the assigned footprints are legacy entries (are missing lib nicknames). " + "Would you like CvPcb to attempt to convert them to the new required FPID format? " + "(If you answer no, then these assignments will be cleared out and you will " + "have to re-assign these footprints yourself.)" + ); + + if( IsOK( this, msg ) ) + { + msg.Clear(); + + try + { + for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) + { + COMPONENT* component = m_netlist.GetComponent( i ); + + if( component->GetFPID().IsLegacy() ) + { + int guess = guessNickname( tbl, (FPID*) &component->GetFPID() ); + + switch( guess ) + { + case 0: + DBG(printf("%s: guessed OK ref:%s fpid:%s\n", __func__, + TO_UTF8( component->GetReference() ), component->GetFPID().Format().c_str() );) + m_modified = true; + break; + + case 1: + msg += wxString::Format( _( + "Component '%s' footprint '%s' was not found in any library.\n" ), + GetChars( component->GetReference() ), + GetChars( component->GetFPID().GetFootprintName() ) + ); + break; + + case 2: + msg += wxString::Format( _( + "Component '%s' footprint '%s' was found in multiple libraries.\n" ), + GetChars( component->GetReference() ), + GetChars( component->GetFPID().GetFootprintName() ) + ); + break; + } + } + } + } + catch( const IO_ERROR& ioe ) + { + wxString msg = ioe.errorText; + msg += wxT( "\n\n" ); + msg += _( "First check your fp-lib-table entries." ); + + wxMessageBox( msg, wxT( "Problematic fp-lib-tables" ) ); + return false; + } + + if( msg.size() ) + { + HTML_MESSAGE_BOX dlg( this, wxEmptyString ); + + dlg.MessageSet( wxT( "The following errors occurred attempting to convert the " + "footprint assignments:\n\n" ) ); + dlg.ListSet( msg ); + dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them " + "to be updated correctly the next time you import the " + "netlist in Pcbnew." ) ); + +#if 1 + dlg.ShowModal(); +#else + dlg.Fit(); + dlg.Show( true ); // modeless lets user watch while fixing the problems, but its not working. +#endif + } + } + else + { + // Clear the legacy footprint assignments. + for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) + { + COMPONENT* component = m_netlist.GetComponent( i ); + + if( component->GetFPID().IsLegacy() ) + { + component->SetFPID( FPID() /* empty */ ); + m_modified = true; + } + } + } + } + + for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) + { + COMPONENT* component = m_netlist.GetComponent( i ); + + msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1, + GetChars( component->GetReference() ), + GetChars( component->GetValue() ), + GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) ); + + m_ListCmp->AppendLine( msg ); + + if( component->GetFPID().empty() ) + { + m_undefinedComponentCnt += 1; + continue; + } + } + + if( !m_netlist.IsEmpty() ) + m_ListCmp->SetSelection( 0, true ); + + DisplayStatus(); + + UpdateTitle(); + + UpdateFileHistory( m_NetlistFileName.GetFullPath() ); + + return true; +} + + +#endif + int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) { diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index 904d7f4b86..bd7f81120f 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -136,7 +136,7 @@ bool LIB_ALIAS::SaveDoc( OUTPUTFORMATTER& aFormatter ) aFormatter.Print( 0, "$ENDCMP\n" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { return false; } diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp index 50e7da1ad2..39443a8e3f 100644 --- a/eeschema/class_library.cpp +++ b/eeschema/class_library.cpp @@ -731,7 +731,7 @@ bool CMP_LIBRARY::Save( OUTPUTFORMATTER& aFormatter ) aFormatter.Print( 0, "#\n#End Library\n" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { success = false; } @@ -756,7 +756,7 @@ bool CMP_LIBRARY::SaveDocs( OUTPUTFORMATTER& aFormatter ) aFormatter.Print( 0, "#\n#End Doc Library\n" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { success = false; } diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp index b293a39b17..ba64849867 100644 --- a/eeschema/dialogs/dialog_bom.cpp +++ b/eeschema/dialogs/dialog_bom.cpp @@ -249,7 +249,7 @@ void DIALOG_BOM::installPluginsList() { cfg_parser.Parse(); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { // wxLogMessage( ioe.errorText ); } diff --git a/eeschema/eelibs_read_libraryfiles.cpp b/eeschema/eelibs_read_libraryfiles.cpp index 8eaaafd8de..56b4e733eb 100644 --- a/eeschema/eelibs_read_libraryfiles.cpp +++ b/eeschema/eelibs_read_libraryfiles.cpp @@ -62,7 +62,7 @@ void SCH_EDIT_FRAME::LoadLibraries() if( !fn.FileExists() ) { - tmp = lib_search.FindValidPath( fn ); + tmp = lib_search.FindValidPath( fn.GetFullPath() ); if( !tmp ) { diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index fe8b75b635..57b05fc56a 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -368,7 +368,7 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList() &m_userLibraryPath ) ); m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ), &m_componentLibFiles, - GROUPLIB ) ); + GROUP_SCH_LIBS ) ); m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ), &m_netListFormat) ); @@ -408,7 +408,7 @@ bool SCH_EDIT_FRAME::LoadProjectFile( const wxString& aFileName, bool aForceRere // extension (.pro). fn.SetExt( ProjectFileExtension ); - if( !prj.ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP, + if( !prj.ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_SCH, GetProjectFileParametersList(), !aForceReread ) ) { m_componentLibFiles = liblist_tmp; @@ -427,7 +427,7 @@ bool SCH_EDIT_FRAME::LoadProjectFile( const wxString& aFileName, bool aForceRere pglayout.SetPageLayout(BASE_SCREEN::m_PageLayoutDescrFileName); // libraries in the *.pro file take precedence over standard library search paths, - // but not over the director of the project, which is at index 0. + // but not over the directory of the project, which is at index 0. prj.SchSearchS().AddPaths( m_userLibraryPath, 1 ); // If the list is empty, force loading the standard power symbol library. @@ -464,7 +464,7 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) } prj.ConfigSave( Kiface().KifaceSearch(), - fn.GetFullPath(), GROUP, GetProjectFileParametersList() ); + fn.GetFullPath(), GROUP_SCH, GetProjectFileParametersList() ); } @@ -666,7 +666,7 @@ void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) { m_TemplateFieldNames.Parse( &lexer ); } - catch( IO_ERROR& e ) + catch( const IO_ERROR& e ) { // @todo show error msg DBG( printf( "templatefieldnames parsing error: '%s'\n", diff --git a/eeschema/eeschema_config.h b/eeschema/eeschema_config.h index 8bdfa54ec6..e771964aaa 100644 --- a/eeschema/eeschema_config.h +++ b/eeschema/eeschema_config.h @@ -4,9 +4,6 @@ #include -#define GROUP wxT( "/eeschema" ) -#define GROUPCOMMON wxT( "/common" ) -#define GROUPLIB wxT( "libraries" ) /* saving parameters option : */ #define INSETUP true /* used when the parameter is saved in general config diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 3a97b08849..6201f4a538 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -1049,7 +1049,7 @@ bool NETLIST_EXPORT_TOOL::WriteKiCadNetList( const wxString& aOutFileName ) xroot->Format( &formatter, 0 ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( NULL, ioe.errorText ); return false; diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index fa7cb5c5df..a2fba0988d 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -868,7 +868,7 @@ void SCH_EDIT_FRAME::OnPrint( wxCommandEvent& event ) // was: wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParametersList() ); Prj().ConfigSave( Kiface().KifaceSearch(), - fn.GetFullPath(), GROUP, GetProjectFileParametersList() ); + fn.GetFullPath(), GROUP_SCH, GetProjectFileParametersList() ); } } diff --git a/eeschema/symbedit.cpp b/eeschema/symbedit.cpp index a5dc98738d..7836f5cbd8 100644 --- a/eeschema/symbedit.cpp +++ b/eeschema/symbedit.cpp @@ -225,14 +225,14 @@ void LIB_EDIT_FRAME::SaveOneSymbol() formatter.Print( 0, "ENDDRAW\n" ); formatter.Print( 0, "ENDDEF\n" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { msg.Printf( _( "An error occurred attempting to save symbol file '%s'" ), GetChars( fn.GetFullPath() ) ); DisplayError( this, msg ); } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return; diff --git a/include/bin_mod.h b/include/bin_mod.h index edfc9cf8e7..1f687ad480 100644 --- a/include/bin_mod.h +++ b/include/bin_mod.h @@ -59,6 +59,8 @@ struct BIN_MOD wxString m_help_file; SEARCH_STACK m_search; + + }; #endif // BIN_MOD_H_ diff --git a/include/common.h b/include/common.h index a6b282df08..31d95c897f 100644 --- a/include/common.h +++ b/include/common.h @@ -589,4 +589,25 @@ wxString FormatDateLong( const wxDateTime &aDate ); */ void SystemDirsAppend( SEARCH_STACK* aSearchStack ); + +/** + * Function SearchHelpFileFullPath + * returns the help file's full path. + *

+ * Return the KiCad help file with path. + * If the help file for the current locale is not found, an attempt to find + * the English version of the help file is made. + * Help file is searched in directories in this order: + * help/\ like help/en_GB + * help/\ like help/en + * help/en + *

+ * @param aSearchStack contains some possible base dirs that may be above the + * the one actually holding @a aBaseName. These are starting points for nested searches. + * @param aBaseName is the name of the help file to search for. + * @return wxEmptyString is returned if aBaseName is not found, else the full path & filename. + */ +wxString SearchHelpFileFullPath( const SEARCH_STACK& aSearchStack, const wxString& aBaseName ); + + #endif // INCLUDE__COMMON_H_ diff --git a/include/config_params.h b/include/config_params.h index a8002e0a9e..e83899af85 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -37,6 +37,17 @@ #include +#define GROUP_PCB wxT( "/pcbnew" ) +#define GROUP_SCH wxT( "/eeschema" ) +#define GROUP_PCB_LIBS wxT( "/pcbnew/libraries" ) +#define GROUP_SCH_LIBS wxT( "/eeschema/libraries" ) +#define GROUP_COMMON wxT( "/common" ) + +#define GROUP_CVP wxT("/cvpcb") +//#define GROUP_CVP_LIBS wxT("/pcbnew/libraries") +#define GROUP_CVP_EQU wxT("/cvpcb/libraries") + + #define CONFIG_VERSION 1 #define FORCE_LOCAL_CONFIG true diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index e4f589e53d..679d437b42 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -38,6 +38,7 @@ class wxFileName; class OUTPUTFORMATTER; class MODULE; class FP_LIB_TABLE_LEXER; +class FPID; class NETLIST; class REPORTER; class SEARCH_STACK; @@ -455,6 +456,21 @@ public: //-------------------------------- + /** + * Function FootprintLoadWithOptionalNickname + * loads a footprint having @a aFootprintId with possibly an empty nickname. + * + * @param aFootprintId the [nickname] & fooprint name of the footprint to load. + * + * @return MODULE* - if found caller owns it, else NULL if not found. + * + * @throw IO_ERROR if the library cannot be found or read. No exception + * is thrown in the case where aFootprintName cannot be found. + * @throw PARSE_ERROR if @a aFootprintId is not parsed OK. + */ + MODULE* FootprintLoadWithOptionalNickname( const FPID& aFootprintId ) + throw( IO_ERROR, PARSE_ERROR ); + /** * Function GetDescription * returns the library desicription from @a aNickname, or an empty string @@ -499,19 +515,6 @@ public: */ bool IsEmpty( bool aIncludeFallback = true ); - /** - * Function ConvertFromLegacy - * converts the footprint names in \a aNetList from the legacy format to the #FPID format. - * - * @param aNetList is the #NETLIST object to convert. - * @param aLibNames is the list of legacy footprint library names from the currently loaded - * project. - * @param aReporter is the #REPORTER object to dump messages into. - * @return true if all footprint names were successfully converted to a valid FPID. - */ - bool ConvertFromLegacy( SEARCH_STACK& aSStack, NETLIST& aNetList, - const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR ); - /** * Function ExpandSubstitutions * replaces any environment variable references with their values and is diff --git a/include/fpid.h b/include/fpid.h index 17155858b8..853983ad51 100644 --- a/include/fpid.h +++ b/include/fpid.h @@ -153,7 +153,6 @@ public: */ bool IsValid() const { return !nickname.empty() && !footprint.empty(); } - /** * Function IsLegacy * @return true if the #FPID only has the #footprint name defined. diff --git a/include/gestfich.h b/include/gestfich.h index 324a767eb0..6a972ea059 100644 --- a/include/gestfich.h +++ b/include/gestfich.h @@ -89,28 +89,6 @@ int ExecuteFile( wxWindow* frame, const wxString& ExecFile, */ void AddDelimiterString( wxString& string ); -/** - * Function FindKicadHelpPath - * finds the absolute path for KiCad "help" (or "help/<language>") - * Find path kicad/doc/help/xx/ or kicad/doc/help/: - * from BinDir - * else from environment variable KICAD - * else from one of s_HelpPathList - * typically c:/kicad/doc/help or /usr/share/kicad/help - * or /usr/local/share/kicad/help - * (must have kicad in path name) - * - * xx = iso639-1 language id (2 letters (generic) or 4 letters): - * fr = french (or fr_FR) - * en = English (or en_GB or en_US ...) - * de = deutch - * es = spanish - * pt = portuguese (or pt_BR ...) - * - * default = en (if not found = fr) - */ -wxString FindKicadHelpPath(); - /** * Function KicadDatasPath * returns the data path common to KiCad. diff --git a/include/kiface_i.h b/include/kiface_i.h index 23f89dffbf..d764c9de35 100644 --- a/include/kiface_i.h +++ b/include/kiface_i.h @@ -100,33 +100,17 @@ public: wxConfigBase* KifaceSettings() const { return m_bm.m_config; } - const wxString& GetHelpFileName() const { return m_bm.m_help_file; } - void SetHelpFileName( const wxString& aFileName ) { m_bm.m_help_file = aFileName; } - /** - * Function GetHelpFile - * gets the help file path. - *

- * Return the KiCad help file with path. The base paths defined in - * m_searchPaths are tested for a valid file. The path returned can - * be relative depending on the paths added to m_searchPaths. See the - * documentation for wxPathList for more information. If the help file - * for the current locale is not found, an attempt to find the English - * version of the help file is made. - * wxEmptyString is returned if help file not found. - * Help file is searched in directories in this order: - * help/\ like help/en_GB - * help/\ like help/en - * help/en - *

+ * Function GetHelpFileName + * returns just the basename portion of the current help file. */ - wxString GetHelpFile(); + const wxString& GetHelpFileName() const { return m_bm.m_help_file; } - wxFileHistory& GetFileHistory() { return m_bm.m_history; } + wxFileHistory& GetFileHistory() { return m_bm.m_history; } /// Only for DSO specific 'non-library' files. /// (The library search path is in the PROJECT class.) - SEARCH_STACK& KifaceSearch() { return m_bm.m_search; } + SEARCH_STACK& KifaceSearch() { return m_bm.m_search; } private: KIWAY::FACE_T m_id; diff --git a/include/pgm_base.h b/include/pgm_base.h index 9ffd028fc7..89587d00a1 100644 --- a/include/pgm_base.h +++ b/include/pgm_base.h @@ -86,9 +86,7 @@ public: //--------------------------------------------------------- - VTBL_ENTRY wxHtmlHelpController* GetHtmlHelpController() { return m_html_ctrl; } - - VTBL_ENTRY void SetHtmlHelpController( wxHtmlHelpController* aController ); + VTBL_ENTRY wxHtmlHelpController* HtmlHelpController(); VTBL_ENTRY wxConfigBase* CommonSettings() const { return m_common_settings; } @@ -161,12 +159,6 @@ public: VTBL_ENTRY void SetLanguagePath(); - /** - * Function InitOnLineHelp - * initializes KiCad's online help. - */ - VTBL_ENTRY void InitOnLineHelp(); - /** * Function ReadPdfBrowserInfos * reads the PDF browser choice from the common configuration. @@ -217,6 +209,8 @@ protected: */ bool initPgm(); + void initHtmlHelpController(); + /** * Function loadCommonSettings * loads the program (process) settings subset which are stored in .kicad_common diff --git a/include/project.h b/include/project.h index 202d957eb8..a4928f4e5c 100644 --- a/include/project.h +++ b/include/project.h @@ -131,15 +131,6 @@ public: /// Accessor for Eeschema search stack. VTBL_ENTRY SEARCH_STACK& SchSearchS() { return m_sch_search; } - /** - * Function PcbSearchS - * returns the obsolete footprint library search stack. - * Projects created before the FP_LIB_TABLE support will have footprint - * search paths in the *.pro files. Projects created after the FP_LIB_TABLE - * support will not. This stack is used for conversion from old to new only. - */ - VTBL_ENTRY SEARCH_STACK& PcbSearchS() { return m_pcb_search; } - VTBL_ENTRY wxString GetModuleLibraryNickname() { return m_module_library_nickname; } VTBL_ENTRY void SetModuleLibraryNickname( const wxString& aNickName ) { m_module_library_nickname = aNickName; } diff --git a/include/ptree.h b/include/ptree.h index 66943c63f9..0ffad8c8ed 100644 --- a/include/ptree.h +++ b/include/ptree.h @@ -78,7 +78,7 @@ typedef const PTREE CPTREE; * PTREE doc; * Scan( &doc, &lexer ); * } - * catch( IO_ERROR ioe ) + * catch( const IO_ERROR& ioe ) * { * fprintf( stderr, "%s\n", TO_UTF8( ioe.errorText ) ); * } diff --git a/include/search_stack.h b/include/search_stack.h index 29cf8af7b5..42534bb74a 100644 --- a/include/search_stack.h +++ b/include/search_stack.h @@ -39,21 +39,6 @@ public: return wxPathList::FindValidPath( aFileName ); } - /** - * Function FindValidPath - * KiCad saves user defined library files that are not in the standard - * library search path list with the full file path. Calling the library - * search path list with a user library file will fail. This helper method - * solves that problem. - * @param fileName - * @return a wxEmptyString if library file is not found. - */ - wxString FindValidPath( const wxFileName& aFileName ) const - { - // call wxPathList::FindValidPath( const wxString& ); - return wxPathList::FindValidPath( aFileName.GetFullPath() ); - } - /** * Function AddPaths * insert or append path(s) @@ -72,15 +57,6 @@ public: * ";" on windows, or ":" | ";" on unix. */ void RemovePaths( const wxString& aPaths ); - - /** - * Function FindFileInSearchPaths - * looks in "this" for \a aFilename, but first modifies every search - * path by appending a list of path fragments from aSubdirs. That modification - * is not rentative. - */ - wxString FindFileInSearchPaths( const wxString& aFilename, - const wxArrayString* aSubdirs = NULL ); }; diff --git a/include/wxstruct.h b/include/wxstruct.h index fb79aae9a7..dbf8679ef5 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -186,6 +186,15 @@ protected: */ virtual wxConfigBase* config(); + /** + * Function sys_search + * returns a SEARCH_STACK pertaining to entire program, and is overloaded in + * KICAD_MANAGER_FRAME + */ + virtual const SEARCH_STACK& sys_search(); + + virtual wxString help_name(); + public: EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, diff --git a/kicad/kicad.h b/kicad/kicad.h index 129d29dc82..ffaac5afdc 100644 --- a/kicad/kicad.h +++ b/kicad/kicad.h @@ -123,6 +123,11 @@ class KICAD_MANAGER_FRAME : public EDA_BASE_FRAME protected: wxConfigBase* config(); // override EDA_BASE_FRAME virtual + const SEARCH_STACK& sys_search(); // override EDA_BASE_FRAME virtual + + wxString help_name(); // override EDA_BASE_FRAME virtual + + public: TREE_PROJECT_FRAME* m_LeftWin; LAUNCHER_PANEL* m_Launcher; diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index 55f5f1ba0b..e74c471dc1 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -123,6 +123,18 @@ wxConfigBase* KICAD_MANAGER_FRAME::config() } +const SEARCH_STACK& KICAD_MANAGER_FRAME::sys_search() +{ + return Pgm().SysSearch(); +} + + +wxString KICAD_MANAGER_FRAME::help_name() +{ + return Pgm().GetHelpFileName(); +} + + void KICAD_MANAGER_FRAME::PrintMsg( const wxString& aText ) { m_MessagesBox->AppendText( aText ); @@ -157,15 +169,6 @@ void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event ) Event.SetCanVeto( true ); - // Close the help frame - if( Pgm().GetHtmlHelpController() ) - { - if( Pgm().GetHtmlHelpController()->GetFrame() ) // returns NULL if no help frame active - Pgm().GetHtmlHelpController()->GetFrame()->Close( true ); - - Pgm().SetHtmlHelpController( NULL ); - } - m_LeftWin->Show( false ); Destroy(); diff --git a/kicad/pgm_kicad.h b/kicad/pgm_kicad.h index 5de4cebbb7..bb1069efac 100644 --- a/kicad/pgm_kicad.h +++ b/kicad/pgm_kicad.h @@ -58,6 +58,8 @@ public: SEARCH_STACK& SysSearch() { return m_bm.m_search; } + wxString GetHelpFileName() { return m_bm.m_help_file; } + protected: // The PGM_* classes can have difficulties at termination if they diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp index 6e6c706371..0cc4add54d 100644 --- a/kicad/tree_project_frame.cpp +++ b/kicad/tree_project_frame.cpp @@ -94,10 +94,10 @@ static const wxChar* s_allowedExtensionsToList[] = */ /* File extension definitions. */ -const wxString TextFileExtension( wxT( "txt" ) ); +const wxChar TextFileExtension[] = wxT( "txt" ); /* File wildcard definitions. */ -const wxString TextFileWildcard( wxT( "Text files (*.txt)|*.txt" ) ); +const wxChar TextFileWildcard[] = wxT( "Text files (*.txt)|*.txt" ); /** @@ -177,7 +177,6 @@ void TREE_PROJECT_FRAME::RemoveFilter( const wxString& filter ) } - /** * Called by the popup menu in the tree frame * Creates a new subdirectory inside the current kicad project directory diff --git a/new/sch_dir_lib_source.cpp b/new/sch_dir_lib_source.cpp index 5b3913d7ac..c91e1b5bcd 100644 --- a/new/sch_dir_lib_source.cpp +++ b/new/sch_dir_lib_source.cpp @@ -716,7 +716,7 @@ void DIR_LIB_SOURCE::Test( int argc, char** argv ) printf( "std::exception\n" ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { printf( "exception: %s\n", (const char*) ioe.errorText.ToUTF8() ) ); } diff --git a/new/test_sch_lib_table.cpp b/new/test_sch_lib_table.cpp index 08c6261fec..a385794604 100644 --- a/new/test_sch_lib_table.cpp +++ b/new/test_sch_lib_table.cpp @@ -118,7 +118,7 @@ int main( int argc, char** argv ) printf( "%*s^\n", ioe.byteIndex>=1 ? ioe.byteIndex-1 : 0, "" ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { printf( "%s\n", (const char*) ioe.errorText.ToUTF8() ); } diff --git a/pagelayout_editor/page_layout_writer.cpp b/pagelayout_editor/page_layout_writer.cpp index 03497e849f..dfc6321511 100644 --- a/pagelayout_editor/page_layout_writer.cpp +++ b/pagelayout_editor/page_layout_writer.cpp @@ -98,7 +98,7 @@ public: m_fileout = new FILE_OUTPUTFORMATTER( aFilename ); m_out = m_fileout; } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxMessageBox( ioe.errorText, _("Error writing page layout descr file" ) ); } @@ -125,7 +125,7 @@ public: m_writer = new STRING_FORMATTER(); m_out = m_writer; } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxMessageBox( ioe.errorText, _("Error writing page layout descr file" ) ); } diff --git a/pcb_calculator/datafile_read_write.cpp b/pcb_calculator/datafile_read_write.cpp index aef8427ca9..ca63df67dd 100644 --- a/pcb_calculator/datafile_read_write.cpp +++ b/pcb_calculator/datafile_read_write.cpp @@ -66,13 +66,16 @@ bool PCB_CALCULATOR_FRAME::ReadDataFile() { datafile_parser.Parse( datafile ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { delete datafile; - ioe.errorText += '\n'; - ioe.errorText += _("Data file error."); - wxMessageBox( ioe.errorText ); + wxString msg = ioe.errorText; + + msg += wxChar('\n'); + msg += _("Data file error."); + + wxMessageBox( msg ); return false; } @@ -99,7 +102,7 @@ bool PCB_CALCULATOR_FRAME::WriteDataFile() while( nestlevel-- ) formatter.Print( nestlevel, ")\n" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { return false; } diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 247507fe4c..976ee30a9a 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -346,13 +346,10 @@ if( KICAD_SCRIPTING ) COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/fix_swig_imports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - ) + ) endif() -### -# _pcbnew DLL/DSO file creation -### if( BUILD_GITHUB_PLUGIN ) set( GITHUB_PLUGIN_LIBRARIES github_plugin ) @@ -401,9 +398,14 @@ if( KICAD_SCRIPTING_MODULES ) if( MAKE_LINK_MAPS ) set_target_properties( _pcbnew PROPERTIES - LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.so.map" ) + LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.so.map" + ) endif() + if( ${OPENMP_FOUND} ) + set_property( TARGET _pcbnew APPEND_STRING + PROPERTY LINK_FLAGS " ${OpenMP_CXX_FLAGS}" ) + endif() endif() @@ -422,14 +424,13 @@ if( DOXYGEN_FOUND ) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS Doxyfile_xml COMMENT "building doxygen docs into directory doxygen-python/html" - ) + ) # create .i files from XML doxygen parsing, docstrings.i will include all of them add_custom_target( xml-to-docstrings COMMAND ${CMAKE_COMMAND} -E remove_directory docstrings COMMAND ${CMAKE_COMMAND} -E make_directory docstrings COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/extract_docstrings.py pcbnew.py doxygen-xml/xml docstrings - COMMAND ${CMAKE_COMMAND} -E remove pcbnew.py # force removal so it will be recreated later with the new docstrings COMMENT "building docstring files" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} @@ -445,16 +446,14 @@ if( DOXYGEN_FOUND ) DEPENDS Doxyfile_python DEPENDS xml-to-docstrings DEPENDS pcbnew.py - COMMENT "building doxygen docs into directory doxygen-python/html" - ) + ) endif() else() message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" ) endif() - if( MINGW ) # PCBNEW_RESOURCES variable is set by the macro. mingw_resource_compiler( pcbnew ) @@ -485,9 +484,8 @@ add_custom_command( from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html" ) -set_source_files_properties( dialogs/dialog_freeroute_exchange.cpp - PROPERTIES - OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h +set_source_files_properties( dialogs/dialog_freeroute_exchange.cpp PROPERTIES + OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h ) @@ -511,14 +509,14 @@ endif() if( USE_KIWAY_DLLS ) +#if( false ) # a very small program launcher for pcbnew_kiface add_executable( pcbnew WIN32 MACOSX_BUNDLE ../common/single_top.cpp - ../common/pgm_base.cpp ${PCBNEW_RESOURCES} ) - set_source_files_properties( ../common/single_top.cpp PROPERTIES + set_source_files_properties( ../common/single_top.cpp pcbnew.cpp PROPERTIES COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL" ) target_link_libraries( pcbnew @@ -539,9 +537,7 @@ if( USE_KIWAY_DLLS ) ${PCBNEW_SRCS} ${PCBNEW_COMMON_SRCS} ${PCBNEW_SCRIPTING_SRCS} -# ${PCBNEW_RESOURCES} ) - set_target_properties( pcbnew_kiface PROPERTIES # Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like # _pcbnew.so, _pcbnew.dll, or _pcbnew.kiface @@ -552,7 +548,7 @@ if( USE_KIWAY_DLLS ) if( ${OPENMP_FOUND} ) set_target_properties( pcbnew_kiface PROPERTIES COMPILE_FLAGS ${OpenMP_CXX_FLAGS} - ) + ) endif() target_link_libraries( pcbnew_kiface @@ -583,7 +579,11 @@ if( USE_KIWAY_DLLS ) ) if( MAKE_LINK_MAPS ) set_target_properties( pcbnew_kiface PROPERTIES - LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_pcbnew.kiface.map" ) + LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_pcbnew.kiface.map" + ) + set_target_properties( pcbnew PROPERTIES + LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.map" + ) endif() # if building pcbnew, then also build pcbnew_kiface if out of date. @@ -605,18 +605,22 @@ if( USE_KIWAY_DLLS ) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.kiface "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.app/Contents/MacOS/" DEPENDS pcbnew_kiface COMMENT "Copying kiface into pcbnew" - ) + ) endif() else() # milestone A) kills this off: add_executable( pcbnew WIN32 MACOSX_BUNDLE + ../common/single_top.cpp pcbnew.cpp ${PCBNEW_SRCS} ${PCBNEW_COMMON_SRCS} ${PCBNEW_SCRIPTING_SRCS} ${PCBNEW_RESOURCES} ) + set_source_files_properties( ../common/single_top.cpp PROPERTIES + COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\"" + ) target_link_libraries( pcbnew 3d-viewer pcbcommon @@ -651,28 +655,25 @@ else() # milestone A) kills this off: ) endif() + if( MAKE_LINK_MAPS ) + # generate a link map with cross reference + set_target_properties( pcbnew PROPERTIES + LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.map" + ) + endif() + install( TARGETS pcbnew DESTINATION ${KICAD_BIN} COMPONENT binary ) - endif() add_dependencies( pcbnew lib-dependencies ) -### -# Set properties for APPLE on pcbnew target -### if( APPLE ) set_target_properties( pcbnew PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ) -endif() - - -if( MAKE_LINK_MAPS ) - # generate a link map with cross reference - set_target_properties( pcbnew PROPERTIES - LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.map" ) + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist + ) endif() @@ -691,19 +692,19 @@ if( KICAD_SCRIPTING ) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py "${PYTHON_DEST}/wx-3.0-osx_cocoa/" DEPENDS FixSwigImportsScripting COMMENT "Copying pcbnew.py into PYTHON_DEST/wx-3.0-osx_cocoa/" - ) + ) add_custom_target( pcbnew_copy_wxpython_scripting ALL COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBWXPYTHON_ROOT}/wxPython/ ${CMAKE_SOURCE_DIR}/pcbnew/pcbnew.app/Contents/Frameworks/wxPython/ DEPENDS FixSwigImportsScripting _pcbnew_py_copy COMMENT "Copying wxPython into pcbnew.app Framework" - ) + ) add_custom_target( pcbnew_copy_plugins ALL COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/pcbnew/scripting/plugins ${PROJECT_SOURCE_DIR}/pcbnew/pcbnew.app/Contents/PlugIns/scripting/plugins DEPENDS pcbnew_copy_wxpython_scripting COMMENT "Copying plugins into bundle" - ) + ) # fix bundle after copying wxpython, fixing and copying add_dependencies( osx_fix_bundles pcbnew_copy_wxpython_scripting ) @@ -738,13 +739,13 @@ if( KICAD_SCRIPTING_MODULES ) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so "${PYTHON_DEST}" DEPENDS _pcbnew FixSwigImportsModuleScripting COMMENT "Copying _pcbnew.so into PYTHON_DEST" - ) + ) add_custom_target( pcbnew_copy_wxpython_module ALL COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBWXPYTHON_ROOT}/wxPython/ ${PROJECT_SOURCE_DIR}/pcbnew/pcbnew.app/Contents/Frameworks/wxPython/ DEPENDS FixSwigImportsModuleScripting _pcbnew_so_copy COMMENT "Copying wxPython into pcbnew.app Frameworks" - ) + ) if( KICAD_BUILD_DYNAMIC ) # Tell that we have to run osx_fix_bundles fix after building _pcbnew and migrating wxPython @@ -755,14 +756,15 @@ if( KICAD_SCRIPTING_MODULES ) endif() -# This one gets made only when testing. -add_executable( specctra_test EXCLUDE_FROM_ALL specctra_test.cpp specctra.cpp ) -target_link_libraries( specctra_test common ${wxWidgets_LIBRARIES} ) +if( false ) # haven't been used in years. + # This one gets made only when testing. + add_executable( specctra_test EXCLUDE_FROM_ALL specctra_test.cpp specctra.cpp ) + target_link_libraries( specctra_test common ${wxWidgets_LIBRARIES} ) -# This one gets made only when testing. -add_executable( layer_widget_test WIN32 EXCLUDE_FROM_ALL - layer_widget.cpp - ) -target_link_libraries( layer_widget_test common ${wxWidgets_LIBRARIES} ) - + # This one gets made only when testing. + add_executable( layer_widget_test WIN32 EXCLUDE_FROM_ALL + layer_widget.cpp + ) + target_link_libraries( layer_widget_test common ${wxWidgets_LIBRARIES} ) +endif() diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp index 655595a41d..73729324ef 100644 --- a/pcbnew/class_netclass.cpp +++ b/pcbnew/class_netclass.cpp @@ -36,7 +36,7 @@ // This will get mapped to "kicad_default" in the specctra_export. -const wxString NETCLASS::Default = wxT("Default"); +const wxChar NETCLASS::Default[] = wxT( "Default" ); // Initial values for netclass initialization int NETCLASS::DEFAULT_CLEARANCE = DMils2iu( 100 ); // track to track and track to pads clearance diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h index 5780a83203..d5e0005357 100644 --- a/pcbnew/class_netclass.h +++ b/pcbnew/class_netclass.h @@ -80,7 +80,7 @@ protected: public: - static const wxString Default; ///< the name of the default NETCLASS + static const wxChar Default[]; ///< the name of the default NETCLASS /** * Constructor diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 9acd8215f5..03f68cffe1 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -41,37 +41,20 @@ #include // Helper class used to clean tracks and vias -class TRACKS_CLEANER : CONNECTIONS +class TRACKS_CLEANER: CONNECTIONS { private: - BOARD* m_Brd; - bool m_deleteUnconnectedTracks; - bool m_mergeSegments; - bool m_cleanVias; + BOARD * m_Brd; public: - TRACKS_CLEANER( BOARD* aPcb ); + TRACKS_CLEANER( BOARD * aPcb ); /** * the cleanup function. * return true if some item was modified */ - bool CleanupBoard(); - - void SetdeleteUnconnectedTracksOpt( bool aDelete ) - { - m_deleteUnconnectedTracks = aDelete; - } - - void SetMergeSegmentsOpt( bool aMerge ) - { - m_mergeSegments = aMerge; - } - - void SetCleanViasOpt( bool aClean ) - { - m_cleanVias = aClean; - } + bool CleanupBoard(PCB_EDIT_FRAME *aFrame, bool aCleanVias, + bool aMergeSegments, bool aDeleteUnconnected); private: @@ -89,7 +72,7 @@ private: /** * Merge colinear segments and remove null len segments */ - bool clean_segments(); + bool clean_segments(); /** * helper function @@ -103,7 +86,8 @@ private: * merge aTrackRef and aCandidate, when possible, * i.e. when they are colinear, same width, and obviously same layer */ - TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, int aEndType ); + TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, + TRACK* aCandidate, int aEndType ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -117,19 +101,9 @@ void PCB_EDIT_FRAME::Clean_Pcb() wxBusyCursor( dummy ); TRACKS_CLEANER cleaner( GetBoard() ); - cleaner.SetdeleteUnconnectedTracksOpt( dlg.m_deleteUnconnectedSegm ); - cleaner.SetMergeSegmentsOpt( dlg.m_mergeSegments ); - cleaner.SetCleanViasOpt( dlg.m_cleanVias ); - - if( cleaner.CleanupBoard() ) - { - // Clear undo and redo lists to avoid inconsistencies between lists - GetScreen()->ClearUndoRedoList(); - SetCurItem( NULL ); - Compile_Ratsnest( NULL, true ); - OnModify(); - } + cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, + dlg.m_deleteUnconnectedSegm ); m_canvas->Refresh( true ); } @@ -142,30 +116,38 @@ void PCB_EDIT_FRAME::Clean_Pcb() * Create segments when track ends are incorrectly connected: * i.e. when a track end covers a pad or a via but is not exactly on the pad or the via center */ -bool TRACKS_CLEANER::CleanupBoard() +bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame, + bool aCleanVias, + bool aMergeSegments, + bool aDeleteUnconnected ) { bool modified = false; // delete redundant vias - if( m_cleanVias && clean_vias() ) - modified = true; + modified |= (aCleanVias && clean_vias()); // Remove null segments and intermediate points on aligned segments - if( m_mergeSegments && clean_segments() ) - modified = true; + modified |= (aMergeSegments && clean_segments()); // Delete dangling tracks - if( m_deleteUnconnectedTracks && deleteUnconnectedTracks() ) - modified = true; + modified |= (aDeleteUnconnected && deleteUnconnectedTracks()); + if( modified ) + { + // Clear undo and redo lists to avoid inconsistencies between lists + // XXX This is very involved... maybe a member in PCB_EDIT_FRAME + // would be better? + aFrame->GetScreen()->ClearUndoRedoList(); + aFrame->SetCurItem( NULL ); + aFrame->Compile_Ratsnest( NULL, true ); + aFrame->OnModify(); + } return modified; } -TRACKS_CLEANER::TRACKS_CLEANER( BOARD* aPcb ) : CONNECTIONS( aPcb ) +TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb ) { m_Brd = aPcb; - m_deleteUnconnectedTracks = false; - m_mergeSegments = false; // Build connections info BuildPadsList(); @@ -177,22 +159,22 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() BuildTracksCandidatesList( m_Brd->m_Track, NULL); // clear flags and variables used in cleanup - for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) { track->start = NULL; track->end = NULL; track->m_PadsConnected.clear(); - track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false ); + track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false ); } // Build connections info tracks to pads SearchTracksConnectedToPads(); - for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) { // Mark track if connected to pads for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) { - D_PAD* pad = track->m_PadsConnected[jj]; + D_PAD * pad = track->m_PadsConnected[jj]; if( pad->HitTest( track->GetStart() ) ) { @@ -211,7 +193,6 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() bool TRACKS_CLEANER::clean_vias() { - TRACK* next_track; bool modified = false; for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) @@ -229,6 +210,7 @@ bool TRACKS_CLEANER::clean_vias() // Search and delete others vias at same location TRACK* alt_track = track->Next(); + TRACK* next_track; for( ; alt_track != NULL; alt_track = next_track ) { next_track = alt_track->Next(); @@ -249,6 +231,7 @@ bool TRACKS_CLEANER::clean_vias() } // Delete Via on pads at same location + TRACK* next_track; for( TRACK* track = m_Brd->m_Track; track != NULL; track = next_track ) { next_track = track->Next(); @@ -260,9 +243,9 @@ bool TRACKS_CLEANER::clean_vias() // if one pad through is found, the via can be removed for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) { - D_PAD* pad = track->m_PadsConnected[ii]; + D_PAD * pad = track->m_PadsConnected[ii]; - if( ( pad->GetLayerMask() & ALL_CU_LAYERS ) == ALL_CU_LAYERS ) + if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) { // redundant: via delete it m_Brd->GetRatsnest()->Remove( track ); @@ -295,8 +278,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() { item_erased = false; TRACK* next_track; - - for( TRACK* track = m_Brd->m_Track; track ; track = next_track ) + for( TRACK * track = m_Brd->m_Track; track ; track = next_track ) { next_track = track->Next(); @@ -317,7 +299,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() LAYER_NUM top_layer, bottom_layer; ZONE_CONTAINER* zone; - if( ( type_end & START_ON_PAD ) == 0 ) + if( (type_end & START_ON_PAD ) == 0 ) { TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START ); @@ -339,7 +321,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() } } - if( ( other == NULL ) && ( zone == NULL ) ) + if( (other == NULL) && (zone == NULL) ) { flag_erase |= 1; } @@ -427,7 +409,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() via->GetNetCode() ); } - if( ( other == NULL ) && ( zone == NULL ) ) + if( (other == NULL) && (zone == NULL) ) flag_erase |= 0x20; track->SetState( BUSY, false ); @@ -459,8 +441,6 @@ bool TRACKS_CLEANER::clean_segments() bool modified = false; TRACK* segment, * nextsegment; TRACK* other; - int flag, no_inc; - // Delete null segments for( segment = m_Brd->m_Track; segment; segment = nextsegment ) @@ -472,6 +452,7 @@ bool TRACKS_CLEANER::clean_segments() m_Brd->GetRatsnest()->Remove( segment ); segment->ViewRelease(); segment->DeleteStructure(); + modified = true; } } @@ -524,7 +505,8 @@ bool TRACKS_CLEANER::clean_segments() if( segment->Type() != PCB_TRACE_T ) continue; - flag = no_inc = 0; + unsigned flag = 0; + bool no_inc = false; // search for a possible point connected to the START point of the current segment for( segStart = segment->Next(); ; ) @@ -603,7 +585,7 @@ bool TRACKS_CLEANER::clean_segments() if( segDelete ) { - no_inc = 1; + no_inc = true; m_Brd->GetRatsnest()->Remove( segDelete ); segDelete->ViewRelease(); segDelete->DeleteStructure(); diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp index e7cb66c29e..2fc522383b 100644 --- a/pcbnew/dialogs/dialog_netlist.cpp +++ b/pcbnew/dialogs/dialog_netlist.cpp @@ -91,7 +91,7 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC ) // was: wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() ); Prj().ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), - GROUP, GetProjectFileParameters() ); + GROUP_PCB, GetProjectFileParameters() ); } } @@ -426,7 +426,7 @@ bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename, std::auto_ptr< NETLIST_READER > nlr( netlistReader ); netlistReader->LoadNetlist(); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); diff --git a/pcbnew/exporters/export_idf.cpp b/pcbnew/exporters/export_idf.cpp index 3d363f5caa..3e2f3e796e 100644 --- a/pcbnew/exporters/export_idf.cpp +++ b/pcbnew/exporters/export_idf.cpp @@ -403,7 +403,7 @@ bool Export_IDF3( BOARD* aPcb, const wxString& aFullFileName, double aUseThou ) idfBoard.Finish(); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogDebug( wxT( "An error occurred attemping export to IDFv3.\n\nError: %s" ), GetChars( ioe.errorText ) ); diff --git a/pcbnew/exporters/gen_modules_placefile.cpp b/pcbnew/exporters/gen_modules_placefile.cpp index b572338064..4507d65394 100644 --- a/pcbnew/exporters/gen_modules_placefile.cpp +++ b/pcbnew/exporters/gen_modules_placefile.cpp @@ -713,7 +713,7 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool fprintf( rptfile, "$EndMODULE %s\n\n", TO_UTF8 (Module->GetReference() ) ); } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( NULL, ioe.errorText ); } diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index d95a13df2c..ec1da8e310 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -404,7 +404,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in SetBoard( loadedBoard ); } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading board.\n%s" ), ioe.errorText.GetData() ); @@ -692,7 +692,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error saving board.\n%s" ), ioe.errorText.GetData() ); diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp index 28e9efb6ea..894c6ec322 100644 --- a/pcbnew/github/github_plugin.cpp +++ b/pcbnew/github/github_plugin.cpp @@ -570,7 +570,7 @@ int main( int argc, char** argv ) printf("[%d]:%s\n", i, TO_UTF8( fps[i] ) ); } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { printf( "%s\n", TO_UTF8(ioe.errorText) ); } diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h index 6ac100ff7f..e2b0135227 100644 --- a/pcbnew/io_mgr.h +++ b/pcbnew/io_mgr.h @@ -204,7 +204,7 @@ public: * or * IO_MGR::Save(...); * } - * catch( IO_ERROR ioe ) + * catch( const IO_ERROR& ioe ) * { * // grab text from ioe, show in error window. * } diff --git a/pcbnew/ioascii.cpp.notused b/pcbnew/ioascii.cpp.notused deleted file mode 100644 index 7e185f84ad..0000000000 --- a/pcbnew/ioascii.cpp.notused +++ /dev/null @@ -1,1260 +0,0 @@ - /** - * @file ioascii.cpp - * @brief Routines for reading and saving of structures in ASCII file common to Pcbnew and CvPcb. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @todo Fix having to recompile the same file with a different defintion. This is - * what C++ derivation was designed to solve. - */ -#ifdef PCBNEW -#include -#endif - -#ifdef CVPCB -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/* ASCII format of structures: - * - * Structure PAD: - * - * $PAD - * Sh "name" form DIMVA dimH dV dH East: general form dV, dH = delta size - * Dr. diam dV dH: drill: diameter drilling offsets - * At Type S / N layers: standard, cms, conn, hole, meca., - * Stack / Normal, 32-bit hexadecimal: occupation layers - * Nm net_code netname - * Po posrefX posrefy: reFX position, Y (0 = east position / anchor) - * $EndPAD - * - * Module Structure - * - * $MODULE namelib - * Po ax ay east layer masquelayer m_TimeCode - * ax ay ord = anchor (position module) - * east = east to 0.1 degree - * layer = layer number - * masquelayer = silkscreen layer for - * m_TimeCode internal use (groups) - * Li - * - * Cd description of the component (Component Doc) - * Kw List of key words - * - * Sc schematic timestamp, reference schematic - * - * Op rot90 rot180 placement Options Auto (court rot 90, 180) - * rot90 is about 2x4-bit: - * lsb = cost rot 90, rot court msb = -90; - * - * Tn px py DIMVA dimh East thickness mirror visible "text" - * n = type (0 = ref, val = 1,> 1 = qcq - * Texts POS x, y / anchor and orient module 0 - * DIMVA dimh East - * mirror thickness (Normal / Mirror) - * Visible V / I - * DS ox oy fx fy w - * Edge: coord segment ox, oy has fx, fy, on - * was the anchor and orient 0 - * thickness w - * DC ox oy fx fy w descr circle (center, 1 point, thickness) - * $PAD - * $EndPAD section pads if available - * $Endmodule - */ - -/// Get the length of a string constant, at compile time -#define SZ( x ) (sizeof(x)-1) - -static int NbDraw, NbTrack, NbZone, NbMod, NbNets; - -static const char delims[] = " =\n\r"; - - -/** Read a list of segments (Tracks, zones) - * @return items count or - count if no end block ($End...) found. - */ -int PCB_BASE_FRAME::ReadListeSegmentDescr( LINE_READER* aReader, - TRACK* insertBeforeMe, - int StructType, - int NumSegm ) -{ - int shape, width, drill, layer, type, flags, net_code; - int tempStartX, tempStartY; - int tempEndX, tempEndY; - int ii = 0; - - TRACK* newTrack; - - while( aReader->ReadLine() ) - { - char* line = aReader->Line(); - int makeType; - unsigned long timeStamp; - - if( line[0] == '$' ) - { - return ii; // end of segmentlist: OK - } - - int arg_count = sscanf( line + 2, " %d %d %d %d %d %d %d", &shape, - &tempStartX, &tempStartY, - &tempEndX, &tempEndY, &width, - &drill ); - - // Read the 2nd line to determine the exact type, one of: - // PCB_TRACE_T, PCB_VIA_T, or PCB_ZONE_T. The type field in 2nd line - // differentiates between PCB_TRACE_T and PCB_VIA_T. With virtual - // functions in use, it is critical to instantiate the PCB_VIA_T - // exactly. - if( !aReader->ReadLine() ) - break; - - line = aReader->Line(); - - if( line[0] == '$' ) - break; - - // parse the 2nd line first to determine the type of object - sscanf( line + 2, " %d %d %d %lX %X", &layer, &type, &net_code, - &timeStamp, &flags ); - - if( StructType==PCB_TRACE_T && type==1 ) - makeType = PCB_VIA_T; - else - makeType = StructType; - - switch( makeType ) - { - default: - case PCB_TRACE_T: - newTrack = new TRACK( GetBoard() ); - GetBoard()->m_Track.Insert( newTrack, insertBeforeMe ); - break; - - case PCB_VIA_T: - newTrack = new SEGVIA( GetBoard() ); - GetBoard()->m_Track.Insert( newTrack, insertBeforeMe ); - break; - - case PCB_ZONE_T: // this is now deprecated, but exist in old boards - newTrack = new SEGZONE( GetBoard() ); - GetBoard()->m_Zone.Insert( (SEGZONE*) newTrack, (SEGZONE*) insertBeforeMe ); - break; - } - - newTrack->SetTimeStamp( timeStamp ); - - newTrack->m_Start.x = tempStartX; - newTrack->m_Start.y = tempStartY; - newTrack->m_End.x = tempEndX; - newTrack->m_End.y = tempEndY; - - newTrack->m_Width = width; - newTrack->m_Shape = shape; - - if( arg_count < 7 || drill <= 0 ) - newTrack->SetDrillDefault(); - else - newTrack->SetDrill( drill ); - - newTrack->SetLayer( layer ); - - if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible: - { - if( newTrack->GetShape() == VIA_THROUGH ) - ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); - } - - newTrack->SetNet( net_code ); - newTrack->SetState( flags, ON ); - } - - DisplayError( this, _( "Error: Unexpected end of file !" ) ); - return -ii; -} - - -int PCB_BASE_FRAME::ReadGeneralDescrPcb( LINE_READER* aReader ) -{ - while( aReader->ReadLine() ) - { - char* line = aReader->Line(); - char* data = strtok( line, delims ); - - if( strnicmp( data, "$EndGENERAL", 10 ) == 0 ) - break; - - if( stricmp( data, "EnabledLayers" ) == 0 ) - { - int enabledLayers = 0; - - data = strtok( NULL, delims ); - sscanf( data, "%X", &enabledLayers ); - - // layer usage - GetBoard()->SetEnabledLayers( enabledLayers ); - - // layer visibility equals layer usage, unless overridden later via "VisibleLayers" - GetBoard()->SetVisibleLayers( enabledLayers ); - continue; - } - - if( stricmp( data, "VisibleLayers" ) == 0 ) - { - int visibleLayers = -1; - - data = strtok( NULL, delims ); - sscanf( data, "%X", &visibleLayers ); - - GetBoard()->SetVisibleLayers( visibleLayers ); - continue; - } - - if( strncmp( data, "Ly", 2 ) == 0 ) // Old format for Layer count - { - int Masque_Layer = 1, ii; - - data = strtok( NULL, delims ); - sscanf( data, "%X", &Masque_Layer ); - - // Setup layer count - int layer_count = 0; - - for( ii = 0; ii < NB_COPPER_LAYERS; ii++ ) - { - if( Masque_Layer & 1 ) - layer_count++; - - Masque_Layer >>= 1; - } - - GetBoard()->SetCopperLayerCount( layer_count ); - - continue; - } - - if( stricmp( data, "BoardThickness" ) == 0 ) - { - data = strtok( NULL, delims ); - GetBoard()->GetDesignSettings().m_BoardThickness = atoi( data ); - continue; - } - - if( strnicmp( data, "Links", 5 ) == 0 ) - { - // Info only, do nothing - continue; - } - - if( strnicmp( data, "NoConn", 6 ) == 0 ) - { - data = strtok( NULL, delims ); - GetBoard()->m_NbNoconnect = atoi( data ); - continue; - } - - if( strnicmp( data, "Di", 2 ) == 0 ) - { - data = strtok( NULL, delims ); - int x1 = atoi( data ); - - data = strtok( NULL, delims ); - int y1 = atoi( data ); - - data = strtok( NULL, delims ); - int x2 = atoi( data ); - - data = strtok( NULL, delims ); - int y2 = atoi( data ); - - EDA_RECT bbbox( wxPoint( x1, y1 ), wxSize( x2-x1, y2-y1 ) ); - - GetBoard()->SetBoundingBox( bbbox ); - - continue; - } - - // Read the number of segments of type DRAW, TRACK, ZONE - if( stricmp( data, "Ndraw" ) == 0 ) - { - data = strtok( NULL, delims ); - NbDraw = atoi( data ); - continue; - } - - if( stricmp( data, "Ntrack" ) == 0 ) - { - data = strtok( NULL, delims ); - NbTrack = atoi( data ); - continue; - } - - if( stricmp( data, "Nzone" ) == 0 ) - { - data = strtok( NULL, delims ); - NbZone = atoi( data ); - continue; - } - - if( stricmp( data, "Nmodule" ) == 0 ) - { - data = strtok( NULL, delims ); - NbMod = atoi( data ); - continue; - } - - if( stricmp( data, "Nnets" ) == 0 ) - { - data = strtok( NULL, delims ); - NbNets = atoi( data ); - continue; - } - } - - return 1; -} - - -int PCB_BASE_FRAME::ReadSetup( LINE_READER* aReader ) -{ - char* data; - - NETCLASS* netclass_default = GetBoard()->m_NetClasses.GetDefault(); - ZONE_SETTINGS zoneInfo = GetBoard()->GetZoneSettings(); - BOARD_DESIGN_SETTINGS bds = GetBoard()->GetDesignSettings(); - - while( aReader->ReadLine() ) - { - char* line = aReader->Line(); - - if( strnicmp( line, "PcbPlotParams", 13 ) == 0 ) - { - PCB_PLOT_PARAMS plot_opts; - PCB_PLOT_PARAMS_PARSER parser( &line[13], aReader->GetSource() ); - - try - { - plot_opts.Parse( &parser ); - } - catch( IO_ERROR& e ) - { - wxString msg; - msg.Printf( _( "Error reading PcbPlotParams from %s:\n%s" ), - aReader->GetSource().GetData(), - e.errorText.GetData() ); - wxMessageBox( msg, _( "Open Board File" ), wxOK | wxICON_ERROR ); - } - - GetBoard()->SetPlotOptions( plot_opts ); - - continue; - } - - strtok( line, delims ); - data = strtok( NULL, delims ); - - if( stricmp( line, "$EndSETUP" ) == 0 ) - { - // Until such time as the *.brd file does not have the - // global parameters: - // "TrackWidth", "TrackMinWidth", "ViaSize", "ViaDrill", - // "ViaMinSize", and "TrackClearence", put those same global - // values into the default NETCLASS until later board load - // code should override them. *.brd files which have been - // saved with knowledge of NETCLASSes will override these - // defaults, old boards will not. - // - // @todo: I expect that at some point we can remove said global - // parameters from the *.brd file since the ones in the - // default netclass serve the same purpose. If needed - // at all, the global defaults should go into a preferences - // file instead so they are there to start new board - // projects. - GetBoard()->m_NetClasses.GetDefault()->SetParams(); - - GetBoard()->SetDesignSettings( bds ); - - GetBoard()->SetZoneSettings( zoneInfo ); - - return 0; - } - - if( stricmp( line, "AuxiliaryAxisOrg" ) == 0 ) - { - int gx = 0, gy = 0; - gx = atoi( data ); - data = strtok( NULL, delims ); - - if( data ) - gy = atoi( data ); - - SetOriginAxisPosition( wxPoint( gx, gy ) ); - continue; - } - -#ifdef PCBNEW - - if( stricmp( line, "Layers" ) == 0 ) - { - int tmp; - sscanf( data, "%d", &tmp ); - GetBoard()->SetCopperLayerCount( tmp ); - continue; - } - - const int LAYERKEYZ = sizeof("Layer[") - 1; - - if( strncmp( line, "Layer[", LAYERKEYZ ) == 0 ) - { - // parse: - // Layer[n] - - char* cp = line + LAYERKEYZ; - int layer = atoi( cp ); - - if( data ) - { - wxString layerName = FROM_UTF8( data ); - GetBoard()->SetLayerName( layer, layerName ); - - data = strtok( NULL, " \n\r" ); - - if( data ) - { - LAYER_T type = LAYER::ParseType( data ); - GetBoard()->SetLayerType( layer, type ); - } - } - - continue; - } - - if( stricmp( line, "TrackWidth" ) == 0 ) // no more used - { - continue; - } - - if( stricmp( line, "TrackWidthList" ) == 0 ) - { - int tmp = atoi( data ); - GetBoard()->m_TrackWidthList.push_back( tmp ); - continue; - } - - if( stricmp( line, "TrackClearence" ) == 0 ) - { - netclass_default->SetClearance( atoi( data ) ); - continue; - } - - if( stricmp( line, "TrackMinWidth" ) == 0 ) - { - bds.m_TrackMinWidth = atoi( data ); - continue; - } - - if( stricmp( line, "ZoneClearence" ) == 0 ) - { - zoneInfo.m_ZoneClearance = atoi( data ); - continue; - } - - if( stricmp( line, "DrawSegmWidth" ) == 0 ) - { - bds.m_DrawSegmentWidth = atoi( data ); - continue; - } - - if( stricmp( line, "EdgeSegmWidth" ) == 0 ) - { - bds.m_EdgeSegmentWidth = atoi( data ); - continue; - } - - if( stricmp( line, "ViaSize" ) == 0 ) // no more used - { - continue; - } - - if( stricmp( line, "ViaMinSize" ) == 0 ) - { - bds.m_ViasMinSize = atoi( data ); - continue; - } - - if( stricmp( line, "MicroViaSize" ) == 0 ) // Not used - { - continue; - } - - if( stricmp( line, "MicroViaMinSize" ) == 0 ) - { - bds.m_MicroViasMinSize = atoi( data ); - continue; - } - - if( stricmp( line, "ViaSizeList" ) == 0 ) - { - int tmp = atoi( data ); - VIA_DIMENSION via_dim; - via_dim.m_Diameter = tmp; - data = strtok( NULL, " \n\r" ); - - if( data ) - { - tmp = atoi( data ); - via_dim.m_Drill = tmp > 0 ? tmp : 0; - } - - GetBoard()->m_ViasDimensionsList.push_back( via_dim ); - continue; - } - - if( stricmp( line, "ViaDrill" ) == 0 ) - { - int diameter = atoi( data ); - netclass_default->SetViaDrill( diameter ); - continue; - } - - if( stricmp( line, "ViaMinDrill" ) == 0 ) - { - bds.m_ViasMinDrill = atoi( data ); - continue; - } - - if( stricmp( line, "MicroViaDrill" ) == 0 ) - { - int diameter = atoi( data ); - netclass_default->SetuViaDrill( diameter ); - continue; - } - - if( stricmp( line, "MicroViaMinDrill" ) == 0 ) - { - int diameter = atoi( data ); - bds.m_MicroViasMinDrill = diameter; - continue; - } - - if( stricmp( line, "MicroViasAllowed" ) == 0 ) - { - bds.m_MicroViasAllowed = atoi( data ); - continue; - } - - if( stricmp( line, "TextPcbWidth" ) == 0 ) - { - bds.m_PcbTextWidth = atoi( data ); - continue; - } - - if( stricmp( line, "TextPcbSize" ) == 0 ) - { - bds.m_PcbTextSize.x = atoi( data ); - data = strtok( NULL, delims ); - bds.m_PcbTextSize.y = atoi( data ); - continue; - } - - if( stricmp( line, "EdgeModWidth" ) == 0 ) - { - bds.m_ModuleSegmentWidth = atoi( data ); - continue; - } - - if( stricmp( line, "TextModWidth" ) == 0 ) - { - bds.m_ModuleTextWidth = atoi( data ); - continue; - } - - if( stricmp( line, "TextModSize" ) == 0 ) - { - bds.m_ModuleTextSize.x = atoi( data ); - data = strtok( NULL, delims ); - bds.m_ModuleTextSize.y = atoi( data ); - continue; - } - - if( stricmp( line, "PadSize" ) == 0 ) - { - int x = atoi( data ); - data = strtok( NULL, delims ); - int y = atoi( data ); - bds.m_Pad_Master.SetSize( wxSize( x, y ) ); - continue; - } - - if( stricmp( line, "PadDrill" ) == 0 ) - { - int sz = atoi( data ); - bds.m_Pad_Master.SetSize( wxSize( sz, sz ) ); - continue; - } - - if( stricmp( line, "Pad2MaskClearance" ) == 0 ) - { - bds.m_SolderMaskMargin = atoi( data ); - continue; - } - - if( stricmp( line, "Pad2PasteClearance" ) == 0 ) - { - bds.m_SolderPasteMargin = atoi( data ); - continue; - } - - if( stricmp( line, "Pad2PasteClearanceRatio" ) == 0 ) - { - bds.m_SolderPasteMarginRatio = atof( data ); - continue; - } - - if( stricmp( line, "GridOrigin" ) == 0 ) - { - int Ox = 0; - int Oy = 0; - - Ox = atoi( data ); - data = strtok( NULL, delims ); - - if ( data ) - Oy = atoi( data ); - - GetScreen()->m_GridOrigin.x = Ox; - GetScreen()->m_GridOrigin.y = Oy; - continue; - } - - if( stricmp( line, "VisibleElements" ) == 0 ) - { - int visibleElements = strtoul( data, 0, 16 ); - bds.SetVisibleElements( visibleElements ); - continue; - } -#endif - - } - - /* Ensure tracks and vias sizes lists are ok: - * Sort lists by by increasing value and remove duplicates - * (the first value is not tested, because it is the netclass value - */ - sort( GetBoard()->m_ViasDimensionsList.begin() + 1, GetBoard()->m_ViasDimensionsList.end() ); - sort( GetBoard()->m_TrackWidthList.begin() + 1, GetBoard()->m_TrackWidthList.end() ); - - for( unsigned ii = 1; ii < GetBoard()->m_ViasDimensionsList.size() - 1; ii++ ) - { - if( GetBoard()->m_ViasDimensionsList[ii] == GetBoard()->m_ViasDimensionsList[ii + 1] ) - { - GetBoard()->m_ViasDimensionsList.erase( GetBoard()->m_ViasDimensionsList.begin() + ii ); - ii--; - } - } - - for( unsigned ii = 1; ii < GetBoard()->m_TrackWidthList.size() - 1; ii++ ) - { - if( GetBoard()->m_TrackWidthList[ii] == GetBoard()->m_TrackWidthList[ii + 1] ) - { - GetBoard()->m_TrackWidthList.erase( GetBoard()->m_TrackWidthList.begin() + ii ); - ii--; - } - } - - return 1; -} - - -#ifdef PCBNEW - -static int WriteSetup( FILE* aFile, PCB_EDIT_FRAME* aFrame, BOARD* aBoard ) -{ - const BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings(); - NETCLASS* netclass_default = aBoard->m_NetClasses.GetDefault(); - char text[1024]; - - fprintf( aFile, "$SETUP\n" ); - sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT ); - fprintf( aFile, "%s", text ); - - fprintf( aFile, "Layers %d\n", aBoard->GetCopperLayerCount() ); - - unsigned layerMask = g_TabAllCopperLayerMask[aBoard->GetCopperLayerCount() - 1]; - - for( int layer = 0; layerMask; ++layer, layerMask >>= 1 ) - { - if( layerMask & 1 ) - { - fprintf( aFile, "Layer[%d] %s %s\n", layer, - TO_UTF8( aBoard->GetLayerName( layer ) ), - LAYER::ShowType( aBoard->GetLayerType( layer ) ) ); - } - } - - // Save current default track width, for compatibility with older Pcbnew version; - fprintf( aFile, "TrackWidth %d\n", aBoard->GetCurrentTrackWidth() ); - - // Save custom tracks width list (the first is not saved here: this is the netclass value - for( unsigned ii = 1; ii < aBoard->m_TrackWidthList.size(); ii++ ) - fprintf( aFile, "TrackWidthList %d\n", aBoard->m_TrackWidthList[ii] ); - - - fprintf( aFile, "TrackClearence %d\n", netclass_default->GetClearance() ); - fprintf( aFile, "ZoneClearence %d\n", aBoard->GetZoneSettings().m_ZoneClearance ); - fprintf( aFile, "TrackMinWidth %d\n", bds.m_TrackMinWidth ); - - fprintf( aFile, "DrawSegmWidth %d\n", bds.m_DrawSegmentWidth ); - fprintf( aFile, "EdgeSegmWidth %d\n", bds.m_EdgeSegmentWidth ); - - // Save current default via size, for compatibility with older Pcbnew version; - fprintf( aFile, "ViaSize %d\n", netclass_default->GetViaDiameter() ); - fprintf( aFile, "ViaDrill %d\n", netclass_default->GetViaDrill() ); - fprintf( aFile, "ViaMinSize %d\n", bds.m_ViasMinSize ); - fprintf( aFile, "ViaMinDrill %d\n", bds.m_ViasMinDrill ); - - // Save custom vias diameters list (the first is not saved here: this is - // the netclass value - for( unsigned ii = 1; ii < aBoard->m_ViasDimensionsList.size(); ii++ ) - fprintf( aFile, "ViaSizeList %d %d\n", - aBoard->m_ViasDimensionsList[ii].m_Diameter, - aBoard->m_ViasDimensionsList[ii].m_Drill ); - - // for old versions compatibility: - fprintf( aFile, "MicroViaSize %d\n", netclass_default->GetuViaDiameter() ); - fprintf( aFile, "MicroViaDrill %d\n", netclass_default->GetuViaDrill() ); - fprintf( aFile, - "MicroViasAllowed %d\n", - bds.m_MicroViasAllowed ); - fprintf( aFile, - "MicroViaMinSize %d\n", - bds.m_MicroViasMinSize ); - fprintf( aFile, - "MicroViaMinDrill %d\n", - bds.m_MicroViasMinDrill ); - - fprintf( aFile, "TextPcbWidth %d\n", bds.m_PcbTextWidth ); - fprintf( aFile, - "TextPcbSize %d %d\n", - bds.m_PcbTextSize.x, - bds.m_PcbTextSize.y ); - - fprintf( aFile, "EdgeModWidth %d\n", bds.m_ModuleSegmentWidth ); - fprintf( aFile, "TextModSize %d %d\n", bds.m_ModuleTextSize.x, bds.m_ModuleTextSize.y ); - fprintf( aFile, "TextModWidth %d\n", bds.m_ModuleTextWidth ); - - fprintf( aFile, "PadSize %d %d\n", bds.m_Pad_Master.GetSize().x, - bds.m_Pad_Master.GetSize().y ); - - fprintf( aFile, "PadDrill %d\n", bds.m_Pad_Master.GetDrillSize().x ); - fprintf( aFile, - "Pad2MaskClearance %d\n", - bds.m_SolderMaskMargin ); - - if( bds.m_SolderPasteMargin != 0 ) - fprintf( aFile, - "Pad2PasteClearance %d\n", - bds.m_SolderPasteMargin ); - - if( bds.m_SolderPasteMarginRatio != 0 ) - fprintf( aFile, - "Pad2PasteClearanceRatio %g\n", - bds.m_SolderPasteMarginRatio ); - - if ( aFrame->GetScreen()->m_GridOrigin != wxPoint( 0, 0 ) ) - { - fprintf( aFile, - "GridOrigin %d %d\n", - aFrame->GetScreen()->m_GridOrigin.x, - aFrame->GetScreen()->m_GridOrigin.y ); - } - - fprintf( aFile, - "AuxiliaryAxisOrg %d %d\n", - aFrame->GetOriginAxisPosition().x, - aFrame->GetOriginAxisPosition().y ); - - fprintf( aFile, "VisibleElements %X\n", bds.GetVisibleElements() ); - - STRING_FORMATTER sf; - - aBoard->GetPlotOptions().Format( &sf, 0 ); - - wxString record = FROM_UTF8( sf.GetString().c_str() ); - record.Replace( wxT("\n"), wxT(""), true ); - record.Replace( wxT(" "), wxT(" "), true); - fprintf( aFile, "PcbPlotParams %s\n", TO_UTF8( record ) ); - fprintf( aFile, "$EndSETUP\n\n" ); - return 1; -} - - -#endif - - -bool PCB_EDIT_FRAME::WriteGeneralDescrPcb( FILE* File ) -{ - EDA_ITEM* PtStruct = GetBoard()->m_Modules; - int NbModules, NbDrawItem, NbLayers; - - // Write copper layer count - NbLayers = GetBoard()->GetCopperLayerCount(); - fprintf( File, "$GENERAL\n" ); - fprintf( File, "encoding utf-8\n"); - fprintf( File, "LayerCount %d\n", NbLayers ); - - // Write old format for Layer count (for compatibility with old versions of - // pcbnew - fprintf( File, - "Ly %8X\n", - g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS ); - - fprintf( File, "EnabledLayers %08X\n", GetBoard()->GetEnabledLayers() ); - - if( GetBoard()->GetEnabledLayers() != GetBoard()->GetVisibleLayers() ) - fprintf( File, "VisibleLayers %08X\n", GetBoard()->GetVisibleLayers() ); - - fprintf( File, "Links %d\n", GetBoard()->GetRatsnestsCount() ); - fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect ); - - // Write board's bounding box info - EDA_RECT bbbox = GetBoard()->ComputeBoundingBox(); - fprintf( File, "Di %d %d %d %d\n", - bbbox.GetX(), - bbbox.GetY(), - bbbox.GetRight(), - bbbox.GetBottom() ); - - // Write segment count for footprints, drawings, track and zones - // Calculate the footprint count - for( NbModules = 0; PtStruct != NULL; PtStruct = PtStruct->Next() ) - NbModules++; - - PtStruct = GetBoard()->m_Drawings; NbDrawItem = 0; - - for( ; PtStruct != NULL; PtStruct = PtStruct->Next() ) - NbDrawItem++; - - fprintf( File, "Ndraw %d\n", NbDrawItem ); - fprintf( File, "Ntrack %d\n", GetBoard()->GetNumSegmTrack() ); - fprintf( File, "Nzone %d\n", GetBoard()->GetNumSegmZone() ); - fprintf( File, "BoardThickness %d\n", GetBoard()->GetDesignSettings().m_BoardThickness ); - fprintf( File, "Nmodule %d\n", NbModules ); - fprintf( File, "Nnets %d\n", GetBoard()->GetNetCount() ); - fprintf( File, "$EndGENERAL\n\n" ); - return true; -} - - -/** - * Function WriteSheetDescr - * Save the page information (size, texts, date ..) - * @param aPageSettings The page settings to write to \a aFile. - * @param aTitleBlock The title block information to write to \a aFile. - * @param aFile An open FILE to write info. - */ -static bool WriteSheetDescr( const PAGE_INFO& aPageSettings, const TITLE_BLOCK& aTitleBlock, - FILE* aFile ) -{ - fprintf( aFile, "$SHEETDESCR\n" ); - fprintf( aFile, "Sheet %s %d %d%s\n", - TO_UTF8( aPageSettings.GetType() ), - aPageSettings.GetWidthMils(), - aPageSettings.GetHeightMils(), - !aPageSettings.IsCustom() && aPageSettings.IsPortrait() ? - " portrait" : "" - ); - - fprintf( aFile, "Title %s\n", EscapedUTF8( aTitleBlock.GetTitle() ).c_str() ); - fprintf( aFile, "Date %s\n", EscapedUTF8( aTitleBlock.GetDate() ).c_str() ); - fprintf( aFile, "Rev %s\n", EscapedUTF8( aTitleBlock.GetRevision() ).c_str() ); - fprintf( aFile, "Comp %s\n", EscapedUTF8( aTitleBlock.GetCompany() ).c_str() ); - fprintf( aFile, "Comment1 %s\n", EscapedUTF8( aTitleBlock.GetComment1() ).c_str() ); - fprintf( aFile, "Comment2 %s\n", EscapedUTF8( aTitleBlock.GetComment2() ).c_str() ); - fprintf( aFile, "Comment3 %s\n", EscapedUTF8( aTitleBlock.GetComment3() ).c_str() ); - fprintf( aFile, "Comment4 %s\n", EscapedUTF8( aTitleBlock.GetComment4() ).c_str() ); - - fprintf( aFile, "$EndSHEETDESCR\n\n" ); - return true; -} - - -#if !defined( USE_NEW_PCBNEW_LOAD ) - -static bool ReadSheetDescr( BOARD* aBoard, LINE_READER* aReader ) -{ - char buf[1024]; - TITLE_BLOCK tb; - - while( aReader->ReadLine() ) - { - char* line = aReader->Line(); - - if( strnicmp( line, "$End", 4 ) == 0 ) - { - aBoard->SetTitleBlock( tb ); - return true; - } - - if( strnicmp( line, "Sheet", 4 ) == 0 ) - { - // e.g. "Sheet A3 16535 11700" - // width and height are in 1/1000th of an inch, always - - PAGE_INFO page; - char* sname = strtok( line + SZ( "Sheet" ), delims ); - - if( sname ) - { - wxString wname = FROM_UTF8( sname ); - if( !page.SetType( wname ) ) - { - /* this entire file is soon to be deleted. - m_error.Printf( _( "Unknown sheet type '%s' on line:%d" ), - wname.GetData(), m_reader->LineNumber() ); - THROW_IO_ERROR( m_error ); - */ - } - - char* width = strtok( NULL, delims ); - char* height = strtok( NULL, delims ); - char* orient = strtok( NULL, delims ); - - // only keep width and height if page size is "User" - if( wname == PAGE_INFO::Custom ) - { - if( width && height ) - { - // legacy disk file describes paper in mils - // (1/1000th of an inch) - int w = atoi( width ); - int h = atoi( height ); - - page.SetWidthMils( w ); - page.SetHeightMils( h ); - } - } - - if( orient && !strcmp( orient, "portrait" ) ) - { - page.SetPortrait( true ); - } - - aBoard->SetPageSettings( page ); - } - - continue; - } - - if( strnicmp( line, "Title", 2 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetTitle( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Date", 2 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetDate( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Rev", 2 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetRevision( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Comp", 4 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetCompany( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Comment1", 8 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetComment1( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Comment2", 8 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetComment2( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Comment3", 8 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetComment3( FROM_UTF8( buf ) ); - continue; - } - - if( strnicmp( line, "Comment4", 8 ) == 0 ) - { - ReadDelimitedText( buf, line, 256 ); - tb.SetComment4( FROM_UTF8( buf ) ); - continue; - } - } - - return false; -} - - -int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append ) -{ - wxBusyCursor dummy; - - // Switch the locale to standard C (needed to read floating point numbers - // like 1.3) - SetLocaleTo_C_standard(); - - BOARD* board = GetBoard(); - - board->m_Status_Pcb = 0; - board->m_NetClasses.Clear(); - - // Put a dollar sign in front, and test for a specific length of characters - // The -1 is to omit the trailing \0 which is included in sizeof() on a - // string. -#define TESTLINE( x ) (strncmp( line, "$" x, sizeof("$" x) - 1 ) == 0) - - while( aReader->ReadLine() ) - { - char* line = aReader->Line(); - - // put the more frequent ones at the top - - if( TESTLINE( "MODULE" ) ) - { - MODULE* module = new MODULE( board ); - board->Add( module, ADD_APPEND ); - module->ReadDescr( aReader ); - continue; - } - - if( TESTLINE( "DRAWSEGMENT" ) ) - { - DRAWSEGMENT* dseg = new DRAWSEGMENT( board ); - board->Add( dseg, ADD_APPEND ); - dseg->ReadDrawSegmentDescr( aReader ); - continue; - } - - if( TESTLINE( "EQUIPOT" ) ) - { - NETINFO_ITEM* net = new NETINFO_ITEM( board ); - board->m_NetInfo.AppendNet( net ); - net->ReadDescr( aReader ); - continue; - } - - if( TESTLINE( "TEXTPCB" ) ) - { - TEXTE_PCB* pcbtxt = new TEXTE_PCB( board ); - board->Add( pcbtxt, ADD_APPEND ); - pcbtxt->ReadTextePcbDescr( aReader ); - continue; - } - - if( TESTLINE( "TRACK" ) ) - { - -#ifdef PCBNEW - TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst(); - ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_TRACE_T, NbTrack ); -#endif - - continue; - } - - if( TESTLINE( "NCLASS" ) ) - { - // create an empty NETCLASS without a name. - NETCLASS* netclass = new NETCLASS( board, wxEmptyString ); - - // fill it from the *.brd file, and establish its name. - netclass->ReadDescr( aReader ); - - if( !board->m_NetClasses.Add( netclass ) ) - { - // Must have been a name conflict, this is a bad board file. - // User may have done a hand edit to the file. - // Delete netclass if board could not take ownership of it. - delete netclass; - - // @todo: throw an exception here, this is a bad board file. - } - - continue; - } - - if( TESTLINE( "CZONE_OUTLINE" ) ) - { - ZONE_CONTAINER* zone_descr = new ZONE_CONTAINER( board ); - zone_descr->ReadDescr( aReader ); - if( zone_descr->GetNumCorners() > 2 ) // should always occur - board->Add( zone_descr ); - else - delete zone_descr; - continue; - } - - if( TESTLINE( "COTATION" ) ) - { - DIMENSION* dim = new DIMENSION( board ); - board->Add( dim, ADD_APPEND ); - dim->ReadDimensionDescr( aReader ); - continue; - } - - if( TESTLINE( "PCB_TARGET" ) || TESTLINE( "MIREPCB" ) ) - { - PCB_TARGET* t = new PCB_TARGET( board ); - board->Add( t, ADD_APPEND ); - t->ReadMirePcbDescr( aReader ); - continue; - } - - if( TESTLINE( "ZONE" ) ) - { -#ifdef PCBNEW - SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst(); - - ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_ZONE_T, NbZone ); -#endif - continue; - } - - if( TESTLINE( "GENERAL" ) ) - { - ReadGeneralDescrPcb( aReader ); - continue; - } - - if( TESTLINE( "SHEETDESCR" ) ) - { - ReadSheetDescr( board, aReader ); - continue; - } - - if( TESTLINE( "SETUP" ) ) - { - if( !Append ) - { - ReadSetup( aReader ); - } - else - { - while( aReader->ReadLine() ) - { - line = aReader->Line(); - - if( TESTLINE( "EndSETUP" ) ) - break; - } - } - - continue; - } - - if( TESTLINE( "EndPCB" ) ) - break; - } - - SetLocaleTo_Default(); // revert to the current locale - - board->m_Status_Pcb = 0; - - // Build the net info list - board->BuildListOfNets(); - - board->SynchronizeNetsAndNetClasses(); - - SetStatusText( wxEmptyString ); - BestZoom(); - return 1; -} - -#endif - - -#ifdef PCBNEW - -/* Save the current PCB in ASCII format - * Returns - * 1 if OK - * 0 if error occurs saving file. - */ -int PCB_EDIT_FRAME::SavePcbFormatAscii( FILE* aFile ) -{ - bool rc; - - GetBoard()->m_Status_Pcb &= ~CONNEXION_OK; - - wxBeginBusyCursor(); - - // Switch the locale to standard C (needed to print floating point numbers - // like 1.3) - LOCALE_IO toggle; - - // Writing file header. - fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", LEGACY_BOARD_FILE_VERSION, - TO_UTF8( DateAndTime() ) ); - fprintf( aFile, "# Created by Pcbnew%s\n\n", TO_UTF8( GetBuildVersion() ) ); - - GetBoard()->SynchronizeNetsAndNetClasses(); - - // Select default Netclass before writing file. - // Useful to save default values in headers - GetBoard()->SetCurrentNetClass( GetBoard()->m_NetClasses.GetDefault()->GetName() ); - - WriteGeneralDescrPcb( aFile ); - WriteSheetDescr( GetBoard()->GetPageSettings(), GetBoard()->GetTitleBlock(), aFile ); - WriteSetup( aFile, this, GetBoard() ); - - rc = GetBoard()->Save( aFile ); - - wxEndBusyCursor(); - - if( !rc ) - DisplayError( this, wxT( "Unable to save PCB file" ) ); - else - SetStatusText( wxEmptyString ); - - return rc; -} - -#endif diff --git a/pcbnew/item_io.cpp.notused b/pcbnew/item_io.cpp.notused deleted file mode 100644 index d145a2e213..0000000000 --- a/pcbnew/item_io.cpp.notused +++ /dev/null @@ -1,2266 +0,0 @@ - - /** - * @file item_io.cpp - * @brief Routines for reading and saving of structures in ASCII file common to Pcbnew and CvPcb. - * This is migrationary and temporary while we move the IO_MGR. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef CVPCB -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include <3d_struct.h> -#include -#include -#include -#include - -#define MAX_WIDTH 10000 // Thickness (in 1 / 10000 ") of maximum reasonable features, text... - - -#if 1 || !defined(USE_NEW_PCBNEW_SAVE) - -bool BOARD::Save( FILE* aFile ) const -{ - bool rc = false; - BOARD_ITEM* item; - - // save the nets - for( unsigned ii = 0; ii < GetNetCount(); ii++ ) - if( !FindNet( ii )->Save( aFile ) ) - goto out; - - // Saved nets do not include netclass names, so save netclasses after nets. - m_NetClasses.Save( aFile ); - - // save the modules - for( item = m_Modules; item; item = item->Next() ) - if( !item->Save( aFile ) ) - goto out; - - for( item = m_Drawings; item; item = item->Next() ) - { - switch( item->Type() ) - { - case PCB_TEXT_T: - case PCB_LINE_T: - case PCB_TARGET_T: - case PCB_DIMENSION_T: - if( !item->Save( aFile ) ) - goto out; - - break; - - default: - - // future: throw exception here -#if defined(DEBUG) - printf( "BOARD::Save() ignoring m_Drawings type %d\n", item->Type() ); -#endif - break; - } - } - - // do not save MARKER_PCBs, they can be regenerated easily - - // save the tracks & vias - fprintf( aFile, "$TRACK\n" ); - - for( item = m_Track; item; item = item->Next() ) - { - if( !item->Save( aFile ) ) - goto out; - } - - fprintf( aFile, "$EndTRACK\n" ); - - // save the zones - fprintf( aFile, "$ZONE\n" ); - - for( item = m_Zone; item; item = item->Next() ) - { - if( !item->Save( aFile ) ) - goto out; - } - - fprintf( aFile, "$EndZONE\n" ); - - // save the zone edges - for( unsigned ii = 0; ii < m_ZoneDescriptorList.size(); ii++ ) - { - ZONE_CONTAINER* edge_zone = m_ZoneDescriptorList[ii]; - edge_zone->Save( aFile ); - } - - - if( fprintf( aFile, "$EndBOARD\n" ) != sizeof("$EndBOARD\n") - 1 ) - goto out; - - rc = true; // wrote all OK - -out: - return rc; -} - - -bool DRAWSEGMENT::Save( FILE* aFile ) const -{ - if( fprintf( aFile, "$DRAWSEGMENT\n" ) != sizeof("$DRAWSEGMENT\n") - 1 ) - return false; - - fprintf( aFile, "Po %d %d %d %d %d %d\n", - m_Shape, - m_Start.x, m_Start.y, - m_End.x, m_End.y, m_Width ); - - if( m_Type != S_CURVE ) - { - fprintf( aFile, "De %d %d %g %lX %X\n", - m_Layer, m_Type, GetAngle(), - m_TimeStamp, GetStatus() ); - } - else - { - fprintf( aFile, "De %d %d %g %lX %X %d %d %d %d\n", - m_Layer, m_Type, GetAngle(), - m_TimeStamp, GetStatus(), - m_BezierC1.x,m_BezierC1.y, - m_BezierC2.x,m_BezierC2.y); - } - - if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 ) - return false; - - return true; -} - - -/** Note: the old name of class NETINFO_ITEM was EQUIPOT - * so in Save (and read) functions, for compatibility, we use EQUIPOT as - * keyword - */ -bool NETINFO_ITEM::Save( FILE* aFile ) const -{ - bool success = false; - - fprintf( aFile, "$EQUIPOT\n" ); - fprintf( aFile, "Na %d %s\n", GetNet(), EscapedUTF8( m_Netname ).c_str() ); - fprintf( aFile, "St %s\n", "~" ); - - if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 ) - goto out; - - success = true; - -out: - return success; -} - - -bool PCB_TARGET::Save( FILE* aFile ) const -{ - bool rc = false; - - if( fprintf( aFile, "$PCB_TARGET\n" ) != sizeof("$PCB_TARGET\n")-1 ) - goto out; - - fprintf( aFile, "Po %X %d %d %d %d %d %8.8lX\n", - m_Shape, m_Layer, - m_Pos.x, m_Pos.y, - m_Size, m_Width, m_TimeStamp ); - - if( fprintf( aFile, "$EndPCB_TARGET\n" ) != sizeof("$EndPCB_TARGET\n")-1 ) - goto out; - - rc = true; - -out: - return rc; -} - - -bool ZONE_CONTAINER::Save( FILE* aFile ) const -{ - unsigned item_pos; - int ret; - unsigned corners_count = m_Poly->corner.size(); - int outline_hatch; - - fprintf( aFile, "$CZONE_OUTLINE\n" ); - - // Save the outline main info - ret = fprintf( aFile, "ZInfo %8.8lX %d %s\n", - m_TimeStamp, GetNet(), - EscapedUTF8( m_Netname ).c_str() ); - - if( ret < 3 ) - return false; - - // Save the outline layer info - ret = fprintf( aFile, "ZLayer %d\n", m_Layer ); - - if( ret < 1 ) - return false; - - // Save the outline aux info - switch( m_Poly->GetHatchStyle() ) - { - default: - case CPolyLine::NO_HATCH: - outline_hatch = 'N'; - break; - - case CPolyLine::DIAGONAL_EDGE: - outline_hatch = 'E'; - break; - - case CPolyLine::DIAGONAL_FULL: - outline_hatch = 'F'; - break; - } - - ret = fprintf( aFile, "ZAux %d %c\n", corners_count, outline_hatch ); - - if( ret < 2 ) - return false; - - if( GetPriority() > 0 ) - { - ret = fprintf( aFile, "ZPriority %d\n", GetPriority() ); - if( ret < 1 ) - return false; - } - - // Save pad option and clearance - int padConnection; - switch( m_PadConnection ) - { - default: - case PAD_IN_ZONE: - padConnection = 'I'; - break; - - case THERMAL_PAD: - padConnection = 'T'; - break; - - case PAD_NOT_IN_ZONE: - padConnection = 'X'; - break; - } - - ret = fprintf( aFile, "ZClearance %d %c\n", m_ZoneClearance, padConnection ); - - if( ret < 2 ) - return false; - - ret = fprintf( aFile, "ZMinThickness %d\n", m_ZoneMinThickness ); - - if( ret < 1 ) - return false; - - ret = fprintf( aFile, - "ZOptions %d %d %c %d %d\n", - m_FillMode, - m_ArcToSegmentsCount, - m_IsFilled ? 'S' : 'F', - m_ThermalReliefGap, - m_ThermalReliefCopperBridge ); - - if( ret < 3 ) - return false; - - ret = fprintf( aFile, - "ZSmoothing %d %d\n", - cornerSmoothingType, cornerRadius ); - - if( ret < 2 ) - return false; - - // Save the corner list - for( item_pos = 0; item_pos < corners_count; item_pos++ ) - { - ret = fprintf( aFile, "ZCorner %d %d %d\n", - m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].y, - m_Poly->corner[item_pos].end_contour ); - - if( ret < 3 ) - return false; - } - - // Save the PolysList - if( m_FilledPolysList.size() ) - { - fprintf( aFile, "$POLYSCORNERS\n" ); - - for( unsigned ii = 0; ii < m_FilledPolysList.size(); ii++ ) - { - const CPolyPt* corner = &m_FilledPolysList[ii]; - ret = fprintf( aFile, - "%d %d %d %d\n", - corner->x, - corner->y, - corner->end_contour, - corner->utility ); - - if( ret < 4 ) - return false; - } - - fprintf( aFile, "$endPOLYSCORNERS\n" ); - } - - // Save the filling segments list - if( m_FillSegmList.size() ) - { - fprintf( aFile, "$FILLSEGMENTS\n" ); - - for( unsigned ii = 0; ii < m_FillSegmList.size(); ii++ ) - { - ret = fprintf( aFile, "%d %d %d %d\n", - m_FillSegmList[ii].m_Start.x, m_FillSegmList[ii].m_Start.y, - m_FillSegmList[ii].m_End.x, m_FillSegmList[ii].m_End.y ); - - if( ret < 4 ) - return false; - } - - fprintf( aFile, "$endFILLSEGMENTS\n" ); - } - - fprintf( aFile, "$endCZONE_OUTLINE\n" ); - - return true; -} - - -bool NETCLASSES::Save( FILE* aFile ) const -{ - bool result; - - // save the default first. - result = m_Default.Save( aFile ); - - if( result ) - { - // the rest will be alphabetical in the *.brd file. - for( const_iterator i = begin(); i!=end(); ++i ) - { - NETCLASS* netclass = i->second; - - result = netclass->Save( aFile ); - if( !result ) - break; - } - } - - return result; -} - - -bool NETCLASS::Save( FILE* aFile ) const -{ - bool result = true; - - fprintf( aFile, "$NCLASS\n" ); - fprintf( aFile, "Name %s\n", EscapedUTF8( m_Name ).c_str() ); - fprintf( aFile, "Desc %s\n", EscapedUTF8( GetDescription() ).c_str() ); - - // Write parameters - - fprintf( aFile, "Clearance %d\n", GetClearance() ); - fprintf( aFile, "TrackWidth %d\n", GetTrackWidth() ); - - fprintf( aFile, "ViaDia %d\n", GetViaDiameter() ); - fprintf( aFile, "ViaDrill %d\n", GetViaDrill() ); - - fprintf( aFile, "uViaDia %d\n", GetuViaDiameter() ); - fprintf( aFile, "uViaDrill %d\n", GetuViaDrill() ); - - // Write members: - for( const_iterator i = begin(); i!=end(); ++i ) - fprintf( aFile, "AddNet %s\n", EscapedUTF8( *i ).c_str() ); - - fprintf( aFile, "$EndNCLASS\n" ); - - return result; -} - - -bool TEXTE_PCB::Save( FILE* aFile ) const -{ - if( m_Text.IsEmpty() ) - return true; - - if( fprintf( aFile, "$TEXTPCB\n" ) != sizeof("$TEXTPCB\n") - 1 ) - return false; - - const char* style = m_Italic ? "Italic" : "Normal"; - - wxArrayString* list = wxStringSplit( m_Text, '\n' ); - - for( unsigned ii = 0; ii < list->Count(); ii++ ) - { - wxString txt = list->Item( ii ); - - if ( ii == 0 ) - fprintf( aFile, "Te %s\n", EscapedUTF8( txt ).c_str() ); - else - fprintf( aFile, "nl %s\n", EscapedUTF8( txt ).c_str() ); - } - - delete list; - - fprintf( aFile, "Po %d %d %d %d %d %g\n", - m_Pos.x, m_Pos.y, m_Size.x, m_Size.y, m_Thickness, GetOrientation() ); - - char hJustify = 'L'; - switch( m_HJustify ) - { - case GR_TEXT_HJUSTIFY_LEFT: - hJustify = 'L'; - break; - case GR_TEXT_HJUSTIFY_CENTER: - hJustify = 'C'; - break; - case GR_TEXT_HJUSTIFY_RIGHT: - hJustify = 'R'; - break; - default: - hJustify = 'C'; - break; - } - - fprintf( aFile, "De %d %d %lX %s %c\n", m_Layer, - m_Mirror ? 0 : 1, - m_TimeStamp, style, hJustify ); - - if( fprintf( aFile, "$EndTEXTPCB\n" ) != sizeof("$EndTEXTPCB\n") - 1 ) - return false; - - return true; -} - - -/** - * Function Save - * writes the data structures for this object out to a FILE in "*.brd" format. - * @param aFile The FILE to write to. - * @return bool - true if success writing else false. - */ -bool TEXTE_MODULE::Save( FILE* aFile ) const -{ - MODULE* parent = (MODULE*) GetParent(); - int orient = m_Orient; - - // Due to the Pcbnew history, m_Orient is saved in screen value - // but it is handled as relative to its parent footprint - if( parent ) - orient += parent->m_Orient; - - int ret = fprintf( aFile, "T%d %d %d %d %d %d %d %c %c %d %c %s\n", - m_Type, - m_Pos0.x, m_Pos0.y, - m_Size.y, m_Size.x, - orient, - m_Thickness, - m_Mirror ? 'M' : 'N', m_NoShow ? 'I' : 'V', - GetLayer(), - m_Italic ? 'I' : 'N', - EscapedUTF8( m_Text ).c_str() - ); - - return ret > 20; -} - - -bool EDGE_MODULE::Save( FILE* aFile ) const -{ - int ret = -1; - - switch( m_Shape ) - { - case S_SEGMENT: - ret = fprintf( aFile, "DS %d %d %d %d %d %d\n", - m_Start0.x, m_Start0.y, - m_End0.x, m_End0.y, - m_Width, m_Layer ); - break; - - case S_CIRCLE: - ret = fprintf( aFile, "DC %d %d %d %d %d %d\n", - m_Start0.x, m_Start0.y, - m_End0.x, m_End0.y, - m_Width, m_Layer ); - break; - - case S_ARC: - ret = fprintf( aFile, "DA %d %d %d %d %g %d %d\n", - m_Start0.x, m_Start0.y, - m_End0.x, m_End0.y, - GetAngle(), - m_Width, m_Layer ); - break; - - case S_POLYGON: - ret = fprintf( aFile, "DP %d %d %d %d %d %d %d\n", - m_Start0.x, m_Start0.y, - m_End0.x, m_End0.y, - (int) m_PolyPoints.size(), - m_Width, m_Layer ); - - for( unsigned i = 0; i 5; -} - - -bool TRACK::Save( FILE* aFile ) const -{ - int type = 0; - - if( Type() == PCB_VIA_T ) - type = 1; - - fprintf( aFile, "Po %d %d %d %d %d %d %d\n", m_Shape, - m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill ); - - fprintf( aFile, "De %d %d %d %lX %X\n", - m_Layer, type, GetNet(), - m_TimeStamp, GetStatus() ); - - return true; -} - - -bool DIMENSION::Save( FILE* aFile ) const -{ - bool rc = false; - - // note: COTATION was the previous name of DIMENSION - // this old keyword is used here for compatibility - const char keyWordLine[] = "$COTATION\n"; - const char keyWordLineEnd[] = "$endCOTATION\n"; - - if( fputs( keyWordLine, aFile ) == EOF ) - goto out; - - fprintf( aFile, "Ge %d %d %lX\n", m_Shape, m_Layer, m_TimeStamp ); - - fprintf( aFile, "Va %d\n", m_Value ); - - if( !m_Text.GetText().IsEmpty() ) - fprintf( aFile, "Te %s\n", EscapedUTF8( m_Text.GetText() ).c_str() ); - else - fprintf( aFile, "Te \"?\"\n" ); - - fprintf( aFile, "Po %d %d %d %d %d %g %d\n", - m_Text.m_Pos.x, m_Text.m_Pos.y, - m_Text.m_Size.x, m_Text.m_Size.y, - m_Text.GetThickness(), m_Text.GetOrientation(), - m_Text.m_Mirror ? 0 : 1 ); - - fprintf( aFile, "Sb %d %d %d %d %d %d\n", S_SEGMENT, - m_crossBarOx, m_crossBarOy, - m_crossBarFx, m_crossBarFy, m_Width ); - - fprintf( aFile, "Sd %d %d %d %d %d %d\n", S_SEGMENT, - m_featureLineDOx, m_featureLineDOy, - m_featureLineDFx, m_featureLineDFy, m_Width ); - - fprintf( aFile, "Sg %d %d %d %d %d %d\n", S_SEGMENT, - m_featureLineGOx, m_featureLineGOy, - m_featureLineGFx, m_featureLineGFy, m_Width ); - - fprintf( aFile, "S1 %d %d %d %d %d %d\n", S_SEGMENT, - m_arrowD1Ox, m_arrowD1Oy, - m_arrowD1Fx, m_arrowD1Fy, m_Width ); - - fprintf( aFile, "S2 %d %d %d %d %d %d\n", S_SEGMENT, - m_arrowD2Ox, m_arrowD2Oy, - m_arrowD2Fx, m_arrowD2Fy, m_Width ); - - - fprintf( aFile, "S3 %d %d %d %d %d %d\n", S_SEGMENT, - m_arrowG1Ox, m_arrowG1Oy, - m_arrowG1Fx, m_arrowG1Fy, m_Width ); - - fprintf( aFile, "S4 %d %d %d %d %d %d\n", S_SEGMENT, - m_arrowG2Ox, m_arrowG2Oy, - m_arrowG2Fx, m_arrowG2Fy, m_Width ); - - if( fputs( keyWordLineEnd, aFile ) == EOF ) - goto out; - - rc = true; - -out: - return rc; -} - - -bool D_PAD::Save( FILE* aFile ) const -{ - int cshape; - const char* texttype; - - // check the return values for first and last fprints() in this function - if( fprintf( aFile, "$PAD\n" ) != sizeof("$PAD\n") - 1 ) - return false; - - switch( m_PadShape ) - { - case PAD_CIRCLE: - cshape = 'C'; break; - - case PAD_RECT: - cshape = 'R'; break; - - case PAD_OVAL: - cshape = 'O'; break; - - case PAD_TRAPEZOID: - cshape = 'T'; break; - - default: - cshape = 'C'; - DisplayError( NULL, _( "Unknown pad shape" ) ); - break; - } - - fprintf( aFile, "Sh \"%.4s\" %c %d %d %d %d %g\n", - m_Padname, cshape, m_Size.x, m_Size.y, - m_DeltaSize.x, m_DeltaSize.y, m_Orient ); - - fprintf( aFile, "Dr %d %d %d", m_Drill.x, m_Offset.x, m_Offset.y ); - - if( m_DrillShape == PAD_OVAL ) - { - fprintf( aFile, " %c %d %d", 'O', m_Drill.x, m_Drill.y ); - } - - fprintf( aFile, "\n" ); - - switch( GetAttribute() ) - { - case PAD_STANDARD: - texttype = "STD"; break; - - case PAD_SMD: - texttype = "SMD"; break; - - case PAD_CONN: - texttype = "CONN"; break; - - case PAD_HOLE_NOT_PLATED: - texttype = "HOLE"; break; - - default: - texttype = "STD"; - DisplayError( NULL, wxT( "Invalid Pad attribute" ) ); - break; - } - - fprintf( aFile, "At %s N %8.8X\n", texttype, m_layerMask ); - - fprintf( aFile, "Ne %d %s\n", GetNet(), EscapedUTF8( m_Netname ).c_str() ); - - fprintf( aFile, "Po %d %d\n", m_Pos0.x, m_Pos0.y ); - - if( GetDieLength() != 0 ) - fprintf( aFile, "Le %d\n", GetDieLength() ); - - if( GetLocalSolderMaskMargin() != 0 ) - fprintf( aFile, ".SolderMask %d\n", GetLocalSolderMaskMargin() ); - - if( GetLocalSolderPasteMargin() != 0 ) - fprintf( aFile, ".SolderPaste %d\n", GetLocalSolderPasteMargin() ); - - if( GetLocalSolderPasteMarginRatio() != 0 ) - fprintf( aFile, ".SolderPasteRatio %g\n", GetLocalSolderPasteMarginRatio() ); - - if( GetLocalClearance() != 0 ) - fprintf( aFile, ".LocalClearance %d\n", GetLocalClearance() ); - - if( m_ZoneConnection != UNDEFINED_CONNECTION ) - fprintf( aFile, ".ZoneConnection %d\n", m_ZoneConnection ); - - if( m_ThermalWidth != 0 ) - fprintf( aFile, ".ThermalWidth %d\n", m_ThermalWidth ); - - if( m_ThermalGap != 0 ) - fprintf( aFile, ".ThermalGap %d\n", m_ThermalGap ); - - if( fprintf( aFile, "$EndPAD\n" ) != sizeof("$EndPAD\n") - 1 ) - return false; - - return true; -} - - -bool MODULE::Save( FILE* aFile ) const -{ - char statusTxt[8]; - BOARD_ITEM* item; - - bool rc = false; - - fprintf( aFile, "$MODULE %s\n", TO_UTF8( m_LibRef ) ); - - memset( statusTxt, 0, sizeof(statusTxt) ); - if( IsLocked() ) - statusTxt[0] = 'F'; - else - statusTxt[0] = '~'; - - if( m_ModuleStatus & MODULE_is_PLACED ) - statusTxt[1] = 'P'; - else - statusTxt[1] = '~'; - - fprintf( aFile, "Po %d %d %g %d %8.8lX %8.8lX %s\n", - m_Pos.x, m_Pos.y, - GetOrientation(), m_Layer, m_LastEdit_Time, - m_TimeStamp, statusTxt ); - - fprintf( aFile, "Li %s\n", TO_UTF8( m_LibRef ) ); - - if( !m_Doc.IsEmpty() ) - { - fprintf( aFile, "Cd %s\n", TO_UTF8( m_Doc ) ); - } - - if( !m_KeyWord.IsEmpty() ) - { - fprintf( aFile, "Kw %s\n", TO_UTF8( m_KeyWord ) ); - } - - fprintf( aFile, "Sc %8.8lX\n", m_TimeStamp ); - fprintf( aFile, "AR %s\n", TO_UTF8( m_Path ) ); - fprintf( aFile, "Op %X %X 0\n", m_CntRot90, m_CntRot180 ); - - if( GetLocalSolderMaskMargin() != 0 ) - fprintf( aFile, ".SolderMask %d\n", GetLocalSolderMaskMargin() ); - - if( m_LocalSolderPasteMargin != 0 ) - fprintf( aFile, ".SolderPaste %d\n", GetLocalSolderPasteMargin() ); - - if( GetLocalSolderPasteMarginRatio() != 0 ) - fprintf( aFile, ".SolderPasteRatio %g\n", GetLocalSolderPasteMarginRatio() ); - - if( m_LocalClearance != 0 ) - fprintf( aFile, ".LocalClearance %d\n", GetLocalClearance() ); - - if( m_ZoneConnection != UNDEFINED_CONNECTION ) - fprintf( aFile, ".ZoneConnection %d\n", m_ZoneConnection ); - - if( m_ThermalWidth != 0 ) - fprintf( aFile, ".ThermalWidth %d\n", m_ThermalWidth ); - - if( m_ThermalGap != 0 ) - fprintf( aFile, ".ThermalGap %d\n", m_ThermalGap ); - - // attributes - if( m_Attributs != MOD_DEFAULT ) - { - fprintf( aFile, "At " ); - - if( m_Attributs & MOD_CMS ) - fprintf( aFile, "SMD " ); - - if( m_Attributs & MOD_VIRTUAL ) - fprintf( aFile, "VIRTUAL " ); - - fprintf( aFile, "\n" ); - } - - // save reference - if( !m_Reference->Save( aFile ) ) - goto out; - - // save value - if( !m_Value->Save( aFile ) ) - goto out; - - // save drawing elements - for( item = m_Drawings; item; item = item->Next() ) - { - switch( item->Type() ) - { - case PCB_MODULE_TEXT_T: - case PCB_MODULE_EDGE_T: - if( !item->Save( aFile ) ) - goto out; - - break; - - default: -#if defined(DEBUG) - printf( "MODULE::Save() ignoring type %d\n", item->Type() ); -#endif - break; - } - } - - // save the pads - for( item = m_Pads; item; item = item->Next() ) - if( !item->Save( aFile ) ) - goto out; - - Write_3D_Descr( aFile ); - - fprintf( aFile, "$EndMODULE %s\n", TO_UTF8( m_LibRef ) ); - - rc = true; -out: - return rc; -} - -/* Save the description of 3D MODULE - */ -int MODULE::Write_3D_Descr( FILE* File ) const -{ - char buf[512]; - - for( S3D_MASTER* t3D = m_3D_Drawings; t3D; t3D = t3D->Next() ) - { - if( !t3D->m_Shape3DName.IsEmpty() ) - { - fprintf( File, "$SHAPE3D\n" ); - - fprintf( File, "Na %s\n", EscapedUTF8( t3D->m_Shape3DName ).c_str() ); - - sprintf( buf, "Sc %lf %lf %lf\n", - t3D->m_MatScale.x, - t3D->m_MatScale.y, - t3D->m_MatScale.z ); - fprintf( File, "%s", to_point( buf ) ); - - sprintf( buf, "Of %lf %lf %lf\n", - t3D->m_MatPosition.x, - t3D->m_MatPosition.y, - t3D->m_MatPosition.z ); - fprintf( File, "%s", to_point( buf ) ); - - sprintf( buf, "Ro %lf %lf %lf\n", - t3D->m_MatRotation.x, - t3D->m_MatRotation.y, - t3D->m_MatRotation.z ); - fprintf( File, "%s", to_point( buf ) ); - - fprintf( File, "$EndSHAPE3D\n" ); - } - } - - return 0; -} - -#endif // USE_NEW_PCBNEW_SAVE - - -#if 1 || !defined(USE_NEW_PCBNEW_LOAD) - -/* Read pad from file. - * The 1st line of descr ($PAD) is assumed to be already read - * Syntax: - * $PAD - * Sh "N1" C 550 550 0 0 1800 - * Dr 310 0 0 - * At STD N 00C0FFFF - * Do 3 "netname" - * Po 6000 -6000 - * $EndPAD - */ -int D_PAD::ReadDescr( LINE_READER* aReader ) -{ - char* Line; - char BufLine[1024], BufCar[256]; - char* PtLine; - int nn, ll, dx, dy; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( Line[0] == '$' ) - return 0; - - PtLine = Line + 3; - - /* Decode the first code and read the corresponding data - */ - switch( Line[0] ) - { - case 'S': // = Sh - // Read pad name - nn = 0; - - while( (*PtLine != '"') && *PtLine ) - PtLine++; - - if( *PtLine ) - PtLine++; - - memset( m_Padname, 0, sizeof(m_Padname) ); - - while( (*PtLine != '"') && *PtLine ) - { - if( nn < (int) sizeof(m_Padname) ) - { - if( *PtLine > ' ' ) - { - m_Padname[nn] = *PtLine; nn++; - } - } - PtLine++; - } - - if( *PtLine == '"' ) - PtLine++; - - nn = sscanf( PtLine, " %s %d %d %d %d %lf", - BufCar, &m_Size.x, &m_Size.y, - &m_DeltaSize.x, &m_DeltaSize.y, - &m_Orient ); - - ll = 0xFF & BufCar[0]; - - // Read pad shape - PAD_SHAPE_T shape; - - switch( ll ) - { - default: - case 'C': shape = PAD_CIRCLE; break; - case 'R': shape = PAD_RECT; break; - case 'O': shape = PAD_OVAL; break; - case 'T': shape = PAD_TRAPEZOID; break; - } - - SetShape( shape ); // sets m_boundingRadius = -1 - break; - - case 'D': - BufCar[0] = 0; - nn = sscanf( PtLine, "%d %d %d %s %d %d", &m_Drill.x, - &m_Offset.x, &m_Offset.y, BufCar, &dx, &dy ); - m_Drill.y = m_Drill.x; - m_DrillShape = PAD_CIRCLE; - - if( nn >= 6 ) // Drill shape = OVAL ? - { - if( BufCar[0] == 'O' ) - { - m_Drill.x = dx; - m_Drill.y = dy; - - m_DrillShape = PAD_OVAL; - } - } - - break; - - case 'A': - nn = sscanf( PtLine, "%s %s %X", BufLine, BufCar, - &m_layerMask ); - - // BufCar is not used now update attributes - SetAttribute( PAD_STANDARD ); - if( strncmp( BufLine, "SMD", 3 ) == 0 ) - SetAttribute( PAD_SMD ); - - if( strncmp( BufLine, "CONN", 4 ) == 0 ) - SetAttribute( PAD_CONN ); - - if( strncmp( BufLine, "HOLE", 4 ) == 0 ) - SetAttribute( PAD_HOLE_NOT_PLATED ); - - break; - - case 'N': // Read Netname - int netcode; - nn = sscanf( PtLine, "%d", &netcode ); - SetNet( netcode ); - - // read Netname - ReadDelimitedText( BufLine, PtLine, sizeof(BufLine) ); - SetNetname( FROM_UTF8( StrPurge( BufLine ) ) ); - break; - - case 'P': - nn = sscanf( PtLine, "%d %d", &m_Pos0.x, &m_Pos0.y ); - m_Pos = m_Pos0; - break; - - case 'L': - int lengthdie; - nn = sscanf( PtLine, "%d", &lengthdie ); - SetDieLength( lengthdie ); - break; - - case '.': // Read specific data - if( strnicmp( Line, ".SolderMask ", 12 ) == 0 ) - SetLocalSolderMaskMargin( atoi( Line + 12 ) ); - else if( strnicmp( Line, ".SolderPaste ", 13 ) == 0 ) - SetLocalSolderPasteMargin( atoi( Line + 13 ) ); - else if( strnicmp( Line, ".SolderPasteRatio ", 18 ) == 0 ) - SetLocalSolderPasteMarginRatio( atoi( Line + 18 ) ); - else if( strnicmp( Line, ".LocalClearance ", 16 ) == 0 ) - SetLocalClearance( atoi( Line + 16 ) ); - else if( strnicmp( Line, ".ZoneConnection ", 16 ) == 0 ) - m_ZoneConnection = (ZoneConnection)atoi( Line + 16 ); - else if( strnicmp( Line, ".ThermalWidth ", 14 ) == 0 ) - m_ThermalWidth = atoi( Line + 14 ); - else if( strnicmp( Line, ".ThermalGap ", 12 ) == 0 ) - m_ThermalGap = atoi( Line + 12 ); - break; - - default: - DisplayError( NULL, wxT( "Err Pad: Id inconnu" ) ); - return 1; - } - } - - return 2; // error : EOF -} - - -/* Read 3D module from file. (Ascii) - * The 1st line of descr ($MODULE) is assumed to be already read - * Returns 0 if OK - */ -int MODULE::Read_3D_Descr( LINE_READER* aReader ) -{ - char* Line = aReader->Line(); - char* text = Line + 3; - - S3D_MASTER* t3D = m_3D_Drawings; - - if( !t3D->m_Shape3DName.IsEmpty() ) - { - S3D_MASTER* n3D = new S3D_MASTER( this ); - - m_3D_Drawings.PushBack( n3D ); - - t3D = n3D; - } - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - switch( Line[0] ) - { - case '$': - if( Line[1] == 'E' ) - return 0; - - return 1; - - case 'N': // Shape File Name - { - char buf[512]; - ReadDelimitedText( buf, text, 512 ); - t3D->m_Shape3DName = FROM_UTF8( buf ); - break; - } - - case 'S': // Scale - sscanf( text, "%lf %lf %lf\n", - &t3D->m_MatScale.x, - &t3D->m_MatScale.y, - &t3D->m_MatScale.z ); - break; - - case 'O': // Offset - sscanf( text, "%lf %lf %lf\n", - &t3D->m_MatPosition.x, - &t3D->m_MatPosition.y, - &t3D->m_MatPosition.z ); - break; - - case 'R': // Rotation - sscanf( text, "%lf %lf %lf\n", - &t3D->m_MatRotation.x, - &t3D->m_MatRotation.y, - &t3D->m_MatRotation.z ); - break; - - default: - break; - } - } - - return 1; -} - - -/* Read a MODULE description - * The first description line ($MODULE) is already read - * @return 0 if no error - */ -int MODULE::ReadDescr( LINE_READER* aReader ) -{ - char* Line; - char BufLine[256], BufCar1[128], * PtLine; - int itmp1, itmp2; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - if( Line[0] == '$' ) - { - if( Line[1] == 'E' ) - break; - - if( Line[1] == 'P' ) - { - D_PAD* pad = new D_PAD( this ); - - pad->ReadDescr( aReader ); - - wxPoint padpos = pad->GetPosition(); - - RotatePoint( &padpos, m_Orient ); - - pad->SetPosition( padpos + m_Pos ); - - m_Pads.PushBack( pad ); - continue; - } - - if( Line[1] == 'S' ) - Read_3D_Descr( aReader ); - } - - if( strlen( Line ) < 4 ) - continue; - - PtLine = Line + 3; - - /* Decode the first code of the current line and read the - * corresponding data - */ - switch( Line[0] ) - { - case 'P': - double orientation; - memset( BufCar1, 0, sizeof(BufCar1) ); - sscanf( PtLine, "%d %d %lf %d %lX %lX %s", - &m_Pos.x, &m_Pos.y, - &orientation, &m_Layer, - &m_LastEdit_Time, &m_TimeStamp, BufCar1 ); - - SetOrientation( orientation ); - - m_ModuleStatus = 0; - - if( BufCar1[0] == 'F' ) - SetLocked( true ); - - if( BufCar1[1] == 'P' ) - m_ModuleStatus |= MODULE_is_PLACED; - - break; - - case 'L': // Li = read the library name of the footprint - *BufLine = 0; - sscanf( PtLine, " %s", BufLine ); - m_LibRef = FROM_UTF8( BufLine ); - break; - - case 'S': - sscanf( PtLine, " %lX", &m_TimeStamp ); - break; - - - case 'O': // (Op)tions for auto placement - itmp1 = itmp2 = 0; - sscanf( PtLine, " %X %X", &itmp1, &itmp2 ); - - m_CntRot180 = itmp2 & 0x0F; - - if( m_CntRot180 > 10 ) - m_CntRot180 = 10; - - m_CntRot90 = itmp1 & 0x0F; - - if( m_CntRot90 > 10 ) - m_CntRot90 = 0; - - itmp1 = (itmp1 >> 4) & 0x0F; - - if( itmp1 > 10 ) - itmp1 = 0; - - m_CntRot90 |= itmp1 << 4; - break; - - case 'A': - if( Line[1] == 't' ) - { - // At = (At)tributes of module - if( strstr( PtLine, "SMD" ) ) - m_Attributs |= MOD_CMS; - - if( strstr( PtLine, "VIRTUAL" ) ) - m_Attributs |= MOD_VIRTUAL; - } - - if( Line[1] == 'R' ) - { - // alternate reference, e.g. /478C2408/478AD1B6 - sscanf( PtLine, " %s", BufLine ); - m_Path = FROM_UTF8( BufLine ); - } - - break; - - case 'T': /* Read a footprint text description (ref, value, or - * drawing */ - TEXTE_MODULE * textm; - sscanf( Line + 1, "%d", &itmp1 ); - - if( itmp1 == TEXT_is_REFERENCE ) - textm = m_Reference; - else if( itmp1 == TEXT_is_VALUE ) - textm = m_Value; - else // text is a drawing - { - textm = new TEXTE_MODULE( this ); - m_Drawings.PushBack( textm ); - } - textm->ReadDescr( aReader ); - break; - - case 'D': // read a drawing item - EDGE_MODULE * edge; - edge = new EDGE_MODULE( this ); - m_Drawings.PushBack( edge ); - edge->ReadDescr( aReader ); - edge->SetDrawCoord(); - break; - - case 'C': // read documentation data - m_Doc = FROM_UTF8( StrPurge( PtLine ) ); - break; - - case 'K': // Read key words - m_KeyWord = FROM_UTF8( StrPurge( PtLine ) ); - break; - - case '.': // Read specific data - if( strnicmp( Line, ".SolderMask ", 12 ) == 0 ) - SetLocalSolderMaskMargin( atoi( Line + 12 ) ); - else if( strnicmp( Line, ".SolderPaste ", 13 ) == 0 ) - SetLocalSolderPasteMargin( atoi( Line + 13 ) ); - else if( strnicmp( Line, ".SolderPasteRatio ", 18 ) == 0 ) - SetLocalSolderPasteMarginRatio( atof( Line + 18 ) ); - else if( strnicmp( Line, ".LocalClearance ", 16 ) == 0 ) - SetLocalClearance( atoi( Line + 16 ) ); - else if( strnicmp( Line, ".ZoneConnection ", 16 ) == 0 ) - m_ZoneConnection = (ZoneConnection)atoi( Line + 16 ); - else if( strnicmp( Line, ".ThermalWidth ", 14 ) == 0 ) - m_ThermalWidth = atoi( Line + 14 ); - else if( strnicmp( Line, ".ThermalGap ", 12 ) == 0 ) - m_ThermalGap = atoi( Line + 12 ); - break; - - default: - break; - } - } - - // Recalculate the bounding box - CalculateBoundingBox(); - return 0; -} - - -/* Read a description line like: - * DS 2600 0 2600 -600 120 21 - * this description line is in Line - * EDGE_MODULE type can be: - * - Circle, - * - Segment (line) - * - Arc - * - Polygon - * - */ -int EDGE_MODULE::ReadDescr( LINE_READER* aReader ) -{ - int ii; - int error = 0; - char* Buf; - char* Line; - - Line = aReader->Line(); - - switch( Line[1] ) - { - case 'S': - m_Shape = S_SEGMENT; - break; - - case 'C': - m_Shape = S_CIRCLE; - break; - - case 'A': - m_Shape = S_ARC; - break; - - case 'P': - m_Shape = S_POLYGON; - break; - - default: - wxString msg; - msg.Printf( wxT( "Unknown EDGE_MODULE type <%s>" ), Line ); - DisplayError( NULL, msg ); - error = 1; - break; - } - - switch( m_Shape ) - { - case S_ARC: - double angle; - sscanf( Line + 3, "%d %d %d %d %lf %d %d", - &m_Start0.x, &m_Start0.y, - &m_End0.x, &m_End0.y, - &angle, &m_Width, &m_Layer ); - - NORMALIZE_ANGLE_360( angle ); - SetAngle( angle ); - break; - - case S_SEGMENT: - case S_CIRCLE: - sscanf( Line + 3, "%d %d %d %d %d %d", - &m_Start0.x, &m_Start0.y, - &m_End0.x, &m_End0.y, - &m_Width, &m_Layer ); - break; - - case S_POLYGON: - int pointCount; - sscanf( Line + 3, "%d %d %d %d %d %d %d", - &m_Start0.x, &m_Start0.y, - &m_End0.x, &m_End0.y, - &pointCount, &m_Width, &m_Layer ); - - m_PolyPoints.clear(); - m_PolyPoints.reserve( pointCount ); - - for( ii = 0; iiReadLine() ) - { - Buf = aReader->Line(); - - if( strncmp( Buf, "Dl", 2 ) != 0 ) - { - error = 1; - break; - } - - int x; - int y; - sscanf( Buf + 3, "%d %d\n", &x, &y ); - - m_PolyPoints.push_back( wxPoint( x, y ) ); - } - else - { - error = 1; - break; - } - } - - break; - - default: - sscanf( Line + 3, "%d %d %d %d %d %d", - &m_Start0.x, &m_Start0.y, - &m_End0.x, &m_End0.y, - &m_Width, &m_Layer ); - break; - } - - // Check for a reasonable width: - if( m_Width <= 1 ) - m_Width = 1; - - if( m_Width > MAX_WIDTH ) - m_Width = MAX_WIDTH; - - // Check for a reasonable layer: - // m_Layer must be >= FIRST_NON_COPPER_LAYER, but because microwave footprints - // can use the copper layers m_Layer < FIRST_NON_COPPER_LAYER is allowed. - // @todo: changes use of EDGE_MODULE these footprints and allows only - // m_Layer >= FIRST_NON_COPPER_LAYER - if( (m_Layer < 0) || (m_Layer > LAST_NON_COPPER_LAYER) ) - m_Layer = SILKSCREEN_N_FRONT; - - return error; -} - - -bool DIMENSION::ReadDimensionDescr( LINE_READER* aReader ) -{ - char* Line; - char Text[2048]; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "$EndDIMENSION", 4 ) == 0 ) - return true; - - if( Line[0] == 'V' ) - { - sscanf( Line + 2, " %d", &m_Value ); - continue; - } - - if( Line[0] == 'G' ) - { - int layer; - - sscanf( Line + 2, " %d %d %lX", &m_Shape, &layer, &m_TimeStamp ); - - if( layer < FIRST_NO_COPPER_LAYER ) - layer = FIRST_NO_COPPER_LAYER; - - if( layer > LAST_NO_COPPER_LAYER ) - layer = LAST_NO_COPPER_LAYER; - - SetLayer( layer ); - m_Text.SetLayer( layer ); - continue; - } - - if( Line[0] == 'T' ) - { - ReadDelimitedText( Text, Line + 2, sizeof(Text) ); - m_Text.m_Text = FROM_UTF8( Text ); - continue; - } - - if( Line[0] == 'P' ) - { - int normal_display = 1; - int orientation; - int thickness; - sscanf( Line + 2, " %d %d %d %d %d %d %d", - &m_Text.m_Pos.x, &m_Text.m_Pos.y, - &m_Text.m_Size.x, &m_Text.m_Size.y, - &thickness, &orientation, - &normal_display ); - - m_Text.m_Mirror = normal_display ? false : true; - m_Pos = m_Text.m_Pos; - m_Text.SetOrientation( orientation ); - m_Text.SetThickness( thickness ); - continue; - } - - if( Line[0] == 'S' ) - { - switch( Line[1] ) - { - int Dummy; - - case 'b': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_crossBarOx, &m_crossBarOy, - &m_crossBarFx, &m_crossBarFy, - &m_Width ); - break; - - case 'd': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_featureLineDOx, &m_featureLineDOy, - &m_featureLineDFx, &m_featureLineDFy, - &Dummy ); - break; - - case 'g': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_featureLineGOx, &m_featureLineGOy, - &m_featureLineGFx, &m_featureLineGFy, - &Dummy ); - break; - - case '1': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_arrowD1Ox, &m_arrowD1Oy, - &m_arrowD1Fx, &m_arrowD1Fy, - &Dummy ); - break; - - case '2': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_arrowD2Ox, &m_arrowD2Oy, - &m_arrowD2Fx, &m_arrowD2Fy, - &Dummy ); - break; - - case '3': - sscanf( Line + 2, " %d %d %d %d %d %d\n", - &Dummy, - &m_arrowG1Ox, &m_arrowG1Oy, - &m_arrowG1Fx, &m_arrowG1Fy, - &Dummy ); - break; - - case '4': - sscanf( Line + 2, " %d %d %d %d %d %d", - &Dummy, - &m_arrowG2Ox, &m_arrowG2Oy, - &m_arrowG2Fx, &m_arrowG2Fy, - &Dummy ); - break; - } - - continue; - } - } - - return false; -} - - -bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader ) -{ - char* Line; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "$End", 4 ) == 0 ) - return true; // End of description - - if( Line[0] == 'P' ) - { - sscanf( Line + 2, " %d %d %d %d %d %d", - &m_Shape, &m_Start.x, &m_Start.y, - &m_End.x, &m_End.y, &m_Width ); - - if( m_Width < 0 ) - m_Width = 0; - } - - if( Line[0] == 'D' ) - { - int status; - char* token = 0; - - token = strtok( Line," " ); - - for( int i = 0; (token = strtok( NULL," " )) != NULL; i++ ) - { - switch( i ) - { - case 0: - sscanf( token,"%d",&m_Layer ); - break; - case 1: - sscanf( token,"%d",&m_Type ); - break; - case 2: - double angle; - sscanf( token, "%lf", &angle ); - SetAngle( angle ); - break; - case 3: - sscanf( token,"%lX",&m_TimeStamp ); - break; - case 4: - sscanf( token,"%X",&status ); - break; - // Bezier Control Points - case 5: - sscanf( token,"%d",&m_BezierC1.x ); - break; - case 6: - sscanf( token,"%d",&m_BezierC1.y ); - break; - case 7: - sscanf( token,"%d",&m_BezierC2.x ); - break; - case 8: - sscanf( token,"%d",&m_BezierC2.y ); - break; - default: - break; - } - } - - if( m_Layer < FIRST_NO_COPPER_LAYER ) - m_Layer = FIRST_NO_COPPER_LAYER; - - if( m_Layer > LAST_NO_COPPER_LAYER ) - m_Layer = LAST_NO_COPPER_LAYER; - - SetState( status, ON ); - } - } - - return false; -} - - -/* Read NETINFO_ITEM from file. - * Returns 0 if OK - * 1 if incomplete reading - */ -int NETINFO_ITEM::ReadDescr( LINE_READER* aReader ) -{ - char* Line; - char Ltmp[1024]; - int tmp; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - if( strnicmp( Line, "$End", 4 ) == 0 ) - return 0; - - if( strncmp( Line, "Na", 2 ) == 0 ) - { - sscanf( Line + 2, " %d", &tmp ); - SetNet( tmp ); - - ReadDelimitedText( Ltmp, Line + 2, sizeof(Ltmp) ); - m_Netname = FROM_UTF8( Ltmp ); - continue; - } - } - - return 1; -} - - -/* Read the description from the PCB file. - */ -bool PCB_TARGET::ReadMirePcbDescr( LINE_READER* aReader ) -{ - char* Line; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "$End", 4 ) == 0 ) - return true; - - if( Line[0] == 'P' ) - { - sscanf( Line + 2, " %X %d %d %d %d %d %lX", - &m_Shape, &m_Layer, - &m_Pos.x, &m_Pos.y, - &m_Size, &m_Width, &m_TimeStamp ); - - if( m_Layer < FIRST_NO_COPPER_LAYER ) - m_Layer = FIRST_NO_COPPER_LAYER; - - if( m_Layer > LAST_NO_COPPER_LAYER ) - m_Layer = LAST_NO_COPPER_LAYER; - } - } - - return false; -} - - -int ZONE_CONTAINER::ReadDescr( LINE_READER* aReader ) -{ - char* Line, * text; - char netname_buffer[1024]; - int ret; - int outline_hatch = CPolyLine::NO_HATCH; - bool error = false, has_corner = false; - - netname_buffer[0] = 0; - - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "ZCorner", 7 ) == 0 ) // new corner found - { - int x; - int y; - int flag; - - text = Line + 7; - ret = sscanf( text, "%d %d %d", &x, &y, &flag ); - - if( ret < 3 ) - { - error = true; - } - else - { - if( !has_corner ) - m_Poly->Start( m_Layer, x, y, outline_hatch ); - else - AppendCorner( wxPoint( x, y ) ); - - has_corner = true; - - if( flag ) - m_Poly->Close(); - } - } - else if( strnicmp( Line, "ZInfo", 5 ) == 0 ) // general info found - { - int ts; - int netcode; - - text = Line + 5; - ret = sscanf( text, "%X %d %s", &ts, &netcode, netname_buffer ); - - if( ret < 3 ) - { - error = true; - } - else - { - SetTimeStamp( ts ); - SetNet( netcode ); - ReadDelimitedText( netname_buffer, netname_buffer, 1024 ); - m_Netname = FROM_UTF8( netname_buffer ); - } - } - else if( strnicmp( Line, "ZLayer", 6 ) == 0 ) // layer found - { - int x; - - text = Line + 6; - ret = sscanf( text, "%d", &x ); - - if( ret < 1 ) - error = true; - else - m_Layer = x; - } - else if( strnicmp( Line, "ZAux", 4 ) == 0 ) // aux info found - { - int x; - char hopt[10]; - - text = Line + 4; - ret = sscanf( text, "%d %c", &x, hopt ); - - if( ret < 2 ) - { - error = true; - } - else - { - switch( hopt[0] ) - { - case 'n': - case 'N': - outline_hatch = CPolyLine::NO_HATCH; - break; - - case 'e': - case 'E': - outline_hatch = CPolyLine::DIAGONAL_EDGE; - break; - - case 'f': - case 'F': - outline_hatch = CPolyLine::DIAGONAL_FULL; - break; - } - } - // Set hatch mode later, after reading outlines corners data - } - - else if( strnicmp( Line, "ZPriority", 9 ) == 0 ) - { - int tmp = 0; - text = Line + 9; - ret = sscanf( text, "%d", &tmp ); - if( ret < 1 ) - return false; - SetPriority( tmp ); - } - - else if( strnicmp( Line, "ZSmoothing", 10 ) == 0 ) - { - int tempSmoothingType; - int tempCornerRadius; - text = Line + 10; - ret = sscanf( text, "%d %d", &tempSmoothingType, &tempCornerRadius ); - - if( ret < 2 ) - return false; - - if( tempSmoothingType >= ZONE_SETTINGS::SMOOTHING_LAST ) - return false; - - if( tempSmoothingType < 0 ) - return false; - - cornerSmoothingType = tempSmoothingType; - SetCornerRadius( tempCornerRadius ); - } - else if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found - { - int fillmode = 1; - int arcsegmentcount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; - char fillstate = 'F'; - text = Line + 8; - ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &fillstate, - &m_ThermalReliefGap, &m_ThermalReliefCopperBridge ); - - if( ret < 1 ) // Must find 1 or more args. - return false; - else - m_FillMode = fillmode ? 1 : 0; - - if( arcsegmentcount >= ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ) - m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF; - - m_IsFilled = (fillstate == 'S') ? true : false; - } - else if( strnicmp( Line, "ZClearance", 10 ) == 0 ) // Clearance and pad options info found - { - int clearance = 200; - char padConnection; - text = Line + 10; - ret = sscanf( text, "%d %1c", &clearance, &padConnection ); - - if( ret < 2 ) - { - error = true; - } - else - { - m_ZoneClearance = clearance; - - switch( padConnection ) - { - case 'i': - case 'I': - m_PadConnection = PAD_IN_ZONE; - break; - - case 't': - case 'T': - m_PadConnection = THERMAL_PAD; - break; - - case 'x': - case 'X': - m_PadConnection = PAD_NOT_IN_ZONE; - break; - } - } - } - else if( strnicmp( Line, "ZMinThickness", 13 ) == 0 ) // Min Thickness info found - { - int thickness; - text = Line + 13; - ret = sscanf( text, "%d", &thickness ); - - if( ret < 1 ) - error = true; - else - m_ZoneMinThickness = thickness; - } - else if( strnicmp( Line, "$POLYSCORNERS", 13 ) == 0 ) // Read the PolysList (polygons used for fill areas in the zone) - { - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0 ) - break; - - CPolyPt corner; - int end_contour, utility; - utility = 0; - ret = sscanf( Line, - "%d %d %d %d", - &corner.x, - &corner.y, - &end_contour, - &utility ); - if( ret < 4 ) - return false; - - corner.end_contour = end_contour ? true : false; - corner.utility = utility; - m_FilledPolysList.push_back( corner ); - } - } - else if( strnicmp( Line, "$FILLSEGMENTS", 13 ) == 0 ) - { - SEGMENT segm; - while( aReader->ReadLine() ) - { - Line = aReader->Line(); - - if( strnicmp( Line, "$endFILLSEGMENTS", 4 ) == 0 ) - break; - - ret = sscanf( Line, - "%d %d %d %d", - &segm.m_Start.x, - &segm.m_Start.y, - &segm.m_End.x, - &segm.m_End.y ); - if( ret < 4 ) - return false; - - m_FillSegmList.push_back( segm ); - } - } - else if( strnicmp( Line, "$end", 4 ) == 0 ) // end of description - { - break; - } - } - - if( !IsOnCopperLayer() ) - { - m_FillMode = 0; - SetNet( 0 ); - } - - // Set hatch here, when outlines corners are read - m_Poly->SetHatch( outline_hatch, Mils2iu( m_Poly->GetDefaultHatchPitchMils() ) ); - - return error ? 0 : 1; -} - - -bool NETCLASS::ReadDescr( LINE_READER* aReader ) -{ - bool result = false; - char* line; - char buf[1024]; - wxString netname; - - while( aReader->ReadLine() ) - { - line = aReader->Line(); - if( strnicmp( line, "AddNet", 6 ) == 0 ) - { - ReadDelimitedText( buf, line + 6, sizeof(buf) ); - netname = FROM_UTF8( buf ); - Add( netname ); - continue; - } - - if( strnicmp( line, "$endNCLASS", sizeof( "$endNCLASS" ) - 1 ) == 0 ) - { - result = true; - break; - } - - if( strnicmp( line, "Clearance", 9 ) == 0 ) - { - SetClearance( atoi( line + 9 ) ); - continue; - } - if( strnicmp( line, "TrackWidth", 10 ) == 0 ) - { - SetTrackWidth( atoi( line + 10 ) ); - continue; - } - if( strnicmp( line, "ViaDia", 6 ) == 0 ) - { - SetViaDiameter( atoi( line + 6 ) ); - continue; - } - if( strnicmp( line, "ViaDrill", 8 ) == 0 ) - { - SetViaDrill( atoi( line + 8 ) ); - continue; - } - - if( strnicmp( line, "uViaDia", 7 ) == 0 ) - { - SetuViaDiameter( atoi( line + 7 ) ); - continue; - } - if( strnicmp( line, "uViaDrill", 9 ) == 0 ) - { - SetuViaDrill( atoi( line + 9 ) ); - continue; - } - - if( strnicmp( line, "Name", 4 ) == 0 ) - { - ReadDelimitedText( buf, line + 4, sizeof(buf) ); - m_Name = FROM_UTF8( buf ); - continue; - } - if( strnicmp( line, "Desc", 4 ) == 0 ) - { - ReadDelimitedText( buf, line + 4, sizeof(buf) ); - SetDescription( FROM_UTF8( buf ) ); - continue; - } - } - - return result; -} - - - -/** - * Function ReadTextePcbDescr - * Read a text description from pcb file. - * - * For a single line text: - * - * $TEXTPCB - * Te "Text example" - * Po 66750 53450 600 800 150 0 - * From 24 1 0 Italic - * $EndTEXTPCB - * - * For a multi line text - * - * $TEXTPCB - * Te "Text example" - * Nl "Line 2" - * Po 66750 53450 600 800 150 0 - * From 24 1 0 Italic - * $EndTEXTPCB - * Nl "line nn" is a line added to the current text - */ -int TEXTE_PCB::ReadTextePcbDescr( LINE_READER* aReader ) -{ - char* line; - char text[1024]; - char style[256]; - - while( aReader->ReadLine() ) - { - line = aReader->Line(); - if( strnicmp( line, "$EndTEXTPCB", 11 ) == 0 ) - return 0; - if( strncmp( line, "Te", 2 ) == 0 ) // Text line (first line for multi line texts - { - ReadDelimitedText( text, line + 2, sizeof(text) ); - m_Text = FROM_UTF8( text ); - continue; - } - if( strncmp( line, "nl", 2 ) == 0 ) // next line of the current text - { - ReadDelimitedText( text, line + 2, sizeof(text) ); - m_Text.Append( '\n' ); - m_Text += FROM_UTF8( text ); - continue; - } - if( strncmp( line, "Po", 2 ) == 0 ) - { - double angle; - sscanf( line + 2, " %d %d %d %d %d %lf", - &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Size.y, - &m_Thickness, &angle ); - - SetOrientation( angle ); - - // Ensure the text has minimal size to see this text on screen: - if( m_Size.x < 5 ) - m_Size.x = 5; - if( m_Size.y < 5 ) - m_Size.y = 5; - continue; - } - if( strncmp( line, "De", 2 ) == 0 ) - { - style[0] = 0; - int normal_display = 1; - char hJustify = 'c'; - sscanf( line + 2, " %d %d %lX %s %c\n", &m_Layer, &normal_display, - &m_TimeStamp, style, &hJustify ); - - m_Mirror = normal_display ? false : true; - - if( m_Layer < FIRST_COPPER_LAYER ) - m_Layer = FIRST_COPPER_LAYER; - if( m_Layer > LAST_NO_COPPER_LAYER ) - m_Layer = LAST_NO_COPPER_LAYER; - - if( strnicmp( style, "Italic", 6 ) == 0 ) - m_Italic = 1; - else - m_Italic = 0; - - switch( hJustify ) - { - case 'l': - case 'L': - m_HJustify = GR_TEXT_HJUSTIFY_LEFT; - break; - case 'c': - case 'C': - m_HJustify = GR_TEXT_HJUSTIFY_CENTER; - break; - case 'r': - case 'R': - m_HJustify = GR_TEXT_HJUSTIFY_RIGHT; - break; - default: - m_HJustify = GR_TEXT_HJUSTIFY_CENTER; - break; - } - continue; - } - } - - // Set a reasonable width: - if( m_Thickness < 1 ) - m_Thickness = 1; - m_Thickness = Clamp_Text_PenSize( m_Thickness, m_Size ); - - return 1; -} - -/** - * Function ReadDescr - * Read description from a given line in "*.brd" format. - * @param aReader The line reader object which contains the first line of description. - * @return int - > 0 if success reading else 0. - */ -int TEXTE_MODULE::ReadDescr( LINE_READER* aReader ) -{ - int success = true; - int type; - char BufCar1[128], BufCar2[128], BufCar3[128]; - char* line = aReader->Line(); - double angle; - - int layer = SILKSCREEN_N_FRONT; - - BufCar1[0] = 0; - BufCar2[0] = 0; - BufCar3[0] = 0; - - if( sscanf( line + 1, "%d %d %d %d %d %lf %d %s %s %d %s", - &type, - &m_Pos0.x, &m_Pos0.y, - &m_Size.y, &m_Size.x, - &angle, &m_Thickness, - BufCar1, BufCar2, &layer, BufCar3 ) >= 10 ) - { - success = true; - - SetOrientation( angle ); - } - - - if( (type != TEXT_is_REFERENCE) && (type != TEXT_is_VALUE) ) - type = TEXT_is_DIVERS; - - m_Type = type; - - // Due to the Pcbnew history, .m_Orient is saved in screen value - // but it is handled as relative to its parent footprint - m_Orient -= ( (MODULE*) m_Parent )->m_Orient; - - if( BufCar1[0] == 'M' ) - m_Mirror = true; - else - m_Mirror = false; - - if( BufCar2[0] == 'I' ) - m_NoShow = true; - else - m_NoShow = false; - - if( BufCar3[0] == 'I' ) - m_Italic = true; - else - m_Italic = false; - - // Test for a reasonable layer: - if( layer < 0 ) - layer = 0; - if( layer > LAST_NO_COPPER_LAYER ) - layer = LAST_NO_COPPER_LAYER; - if( layer == LAYER_N_BACK ) - layer = SILKSCREEN_N_BACK; - else if( layer == LAYER_N_FRONT ) - layer = SILKSCREEN_N_FRONT; - - SetLayer( layer ); - - // Calculate the actual position. - SetDrawCoord(); - - - // Search and read the "text" string (a quoted text). - ReadDelimitedText( &m_Text, line ); - - // Test for a reasonable size: - if( m_Size.x < TEXTS_MIN_SIZE ) - m_Size.x = TEXTS_MIN_SIZE; - if( m_Size.y < TEXTS_MIN_SIZE ) - m_Size.y = TEXTS_MIN_SIZE; - - // Set a reasonable width: - if( m_Thickness < 1 ) - m_Thickness = 1; - m_Thickness = Clamp_Text_PenSize( m_Thickness, m_Size ); - - return success; -} - -#endif // USE_NEW_PCBNEW_LOAD diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index 1b65c89b97..d8e47c0e46 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -199,7 +199,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() return NULL; } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; @@ -222,7 +222,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() return NULL; } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; @@ -259,7 +259,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() return NULL; } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; @@ -334,7 +334,7 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule ) fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() ); fclose( fp ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return; @@ -357,7 +357,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveCurrentModule( const wxString* aLibPath ) pi->FootprintSave( libPath, GetBoard()->m_Modules ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return false; @@ -429,7 +429,7 @@ wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary() writable = pi->IsFootprintLibWritable( libPath ); exists = true; // no exception was thrown, lib must exist. } - catch( IO_ERROR ) + catch( const IO_ERROR& ) { // ignore, original values of 'writable' and 'exists' are accurate. } @@ -455,7 +455,7 @@ wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary() pi->FootprintLibCreate( libPath ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return wxEmptyString; @@ -499,7 +499,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() { FootprintLibs()->FootprintDelete( nickname, fpname ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return false; @@ -568,7 +568,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly ) } } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); } @@ -655,7 +655,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, // own if the library or footprint is not writable. FootprintLibs()->FootprintSave( aLibrary, aModule ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return false; diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 990198953a..2db1223087 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -220,7 +220,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, { module = loadFootprint( fpid ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ), fpid.Format().c_str(), GetChars( ioe.errorText ) ); @@ -252,7 +252,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, { module = loadFootprint( fpid ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ), fpid.Format().c_str(), GetChars( ioe.errorText ) ); @@ -304,7 +304,7 @@ MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId ) { module = loadFootprint( aFootprintId ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ), aFootprintId.Format().c_str(), GetChars( ioe.errorText ) ); @@ -321,31 +321,7 @@ MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) ); - wxString nickname = aFootprintId.GetLibNickname(); - wxString fpname = aFootprintId.GetFootprintName(); - - if( nickname.size() ) - { - return fptbl->FootprintLoad( nickname, fpname ); - } - - // user did not enter a nickname, just a footprint name, help him out a little: - else - { - std::vector nicks = fptbl->GetLogicalLibs(); - - // Search each library going through libraries alphabetically. - for( unsigned i = 0; iFootprintLoad( nicks[i], fpname ); - if( ret ) - return ret; - } - - return NULL; - } + return fptbl->FootprintLoadWithOptionalNickname( aFootprintId ); } @@ -557,7 +533,7 @@ void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent ) // m is deleted here by auto_ptr. } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return; diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 4d11d4c7d1..fa28eca5b4 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -279,7 +279,7 @@ wxString FOOTPRINT_EDIT_FRAME::getLibPath() return row->GetFullURI( true ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { return wxEmptyString; } @@ -639,7 +639,7 @@ void FOOTPRINT_EDIT_FRAME::updateTitle() if( !writable ) title += _( " [Read Only]" ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { // user may be bewildered as to why after selecting a library it is not showing up // in the title, we could show an error message, but that should have been done at time diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index 764b5fbe5c..45fe7c7b03 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -85,7 +85,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, netlistReader->LoadNetlist(); loadFootprints( netlist, aReporter ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index a8eac6b21a..c9a4129e1b 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -208,13 +208,13 @@ MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BA return &kiface; } - +#if defined(BUILD_KIWAY_DLL) PGM_BASE& Pgm() { wxASSERT( process ); // KIFACE_GETTER has already been called. return *process; } - +#endif /** * Function set3DShapesPath @@ -484,6 +484,5 @@ void IFACE::OnKifaceEnd() // This should only be called if python was setup correctly. pcbnewFinishPythonScripting(); - #endif } diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 0a8934f528..a9870c279d 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -29,7 +29,6 @@ */ #include -//#include #include #include #include @@ -239,7 +238,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName ) fn.SetExt( ProjectFileExtension ); // was: wxGetApp().ReadProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); - Prj().ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); + Prj().ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_PCB, GetProjectFileParameters(), false ); // Dick 5-Feb-2012: I don't agree with this, the BOARD contents should dictate // what is visible or not, even initially. And since PCB_EDIT_FRAME projects settings @@ -302,9 +301,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) fn = dlg.GetPath(); } - SEARCH_STACK& search = Kiface().KifaceSearch(); - - Prj().ConfigSave( search, fn.GetFullPath(), GROUP, GetProjectFileParameters() ); + Prj().ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_PCB, GetProjectFileParameters() ); } @@ -315,7 +312,7 @@ PARAM_CFG_ARRAY PCB_EDIT_FRAME::GetProjectFileParameters() pca.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ), &BASE_SCREEN::m_PageLayoutDescrFileName ) ); - pca.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ), &g_UserLibDirBuffer, GROUPLIB ) ); + pca.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ), &g_UserLibDirBuffer, GROUP_PCB_LIBS ) ); pca.push_back( new PARAM_CFG_FILENAME( wxT( "LastNetListRead" ), &m_lastNetListRead ) ); diff --git a/pcbnew/pcbnew_config.h b/pcbnew/pcbnew_config.h index a0b0006bbd..f4c153e6cd 100644 --- a/pcbnew/pcbnew_config.h +++ b/pcbnew/pcbnew_config.h @@ -1,6 +1,6 @@ /** * @file pcbnew_config.h - * @brief Cconfiguration parameters for Pcbnew. + * @brief Configuration parameters for Pcbnew. */ #ifndef _PCBNEW_CONFIG_H_ @@ -9,10 +9,6 @@ #include #include -#define GROUP wxT( "/pcbnew" ) -#define GROUPLIB wxT( "/pcbnew/libraries" ) -#define GROUPCOMMON wxT( "/common" ) - /* Useful macro : */ #define LOC_COLOR(layer) &g_ColorsSettings.m_LayersColors[layer] #define ITEM_COLOR(item_visible) &g_ColorsSettings.m_ItemsColors[item_visible] diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index c9a85591d6..40aa2eeb97 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -162,7 +162,7 @@ bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename ) // if an exception is thrown by FromBOARD or ExportPCB(), then // ~SPECCTRA_DB() will close the file. } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { ok = false; @@ -1322,7 +1322,7 @@ bool SPECCTRA_DB::GetBoardPolygonOutlines( BOARD* aBoard, aHoles.CloseLastContour(); } } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { // Creates a valid polygon outline is not possible. // So uses the board edge cuts bounding box to create a diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 06d9a61843..417d433bb3 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -102,14 +102,15 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event ) db.LoadSESSION( fullFileName ); db.FromSESSION( GetBoard() ); } - catch( IO_ERROR& ioe ) + catch( const IO_ERROR& ioe ) { - ioe.errorText += '\n'; - ioe.errorText += _("BOARD may be corrupted, do not save it."); - ioe.errorText += '\n'; - ioe.errorText += _("Fix problem and try again."); + wxString msg = ioe.errorText; + msg += '\n'; + msg += _("BOARD may be corrupted, do not save it."); + msg += '\n'; + msg += _("Fix problem and try again."); - DisplayError( this, ioe.errorText ); + DisplayError( this, msg ); return; } diff --git a/pcbnew/specctra_test.cpp b/pcbnew/specctra_test.cpp index c0b95f7d72..ab11895393 100644 --- a/pcbnew/specctra_test.cpp +++ b/pcbnew/specctra_test.cpp @@ -63,7 +63,7 @@ int main( int argc, char** argv ) // db.LoadPCB( filename ); db.LoadSESSION( filename ); } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { fprintf( stderr, "%s\n", TO_UTF8(ioe.errorText) ); failed = true; diff --git a/scripts/kicad-install.sh b/scripts/kicad-install.sh index 8bd792fe87..d5e9877926 100755 --- a/scripts/kicad-install.sh +++ b/scripts/kicad-install.sh @@ -125,7 +125,10 @@ install_prerequisites() fi # ensure bzr name and email are set. No message since bzr prints an excellent diagnostic. - bzr whoami || exit 2 + bzr whoami || { + echo "WARNING: You have not set bzr whoami, so I will set a dummy." + export BZR_EMAIL="Kicad Build " + } } @@ -270,10 +273,12 @@ install_or_update() echo " kicad-lib.bzr installed." - echo "step 9) as non-root, install user configuration files..." + echo "step 9) as non-root, install global fp-lib-table if none already installed..." # install ~/fp-lib-table - make install_github_fp-lib-table - echo " kicad user-configuration files installed." + if [ ! -e ~/fp-lib-table ]; then + make install_github_fp-lib-table + echo " global fp-lib-table installed." + fi echo "step 10) installing documentation..." diff --git a/tools/property_tree.cpp b/tools/property_tree.cpp index ea1bb77175..dfe898b898 100644 --- a/tools/property_tree.cpp +++ b/tools/property_tree.cpp @@ -83,7 +83,7 @@ int main( int argc, char** argv ) #endif } - catch( IO_ERROR ioe ) + catch( const IO_ERROR& ioe ) { fprintf( stderr, "%s\n", TO_UTF8( ioe.errorText ) ); }