void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent ) { SCH_SCREEN* screen; wxFileName fn; wxFileName tmp; SCH_SCREENS ScreenList; fn = g_RootSheet->GetFileName(); // Ensure a path exists. if no path, assume the cwd is used // The IsWritable function expects the path to be set if( !fn.GetPath().IsEmpty() ) tmp.AssignDir( fn.GetPath() ); else tmp.AssignDir( wxGetCwd() ); if( !IsWritable( tmp ) ) return; for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) SaveEEFile( screen ); CreateArchiveLibraryCacheFile(); UpdateTitle(); }
/** * Function get_components * Fills a vector with all of the project's components, to ease iterating over them. * * @param aComponents - a vector that will take the components */ static void get_components( std::vector<SCH_COMPONENT*>& aComponents ) { SCH_SCREENS screens; for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( item ); aComponents.push_back( component ); } } }
int TestDuplicateSheetNames( bool aCreateMarker ) { SCH_SCREEN* screen; SCH_ITEM* item; SCH_ITEM* test_item; int err_count = 0; SCH_SCREENS screenList; // Created the list of screen for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() ) { for( item = screen->GetDrawItems(); item != NULL; item = item->Next() ) { // search for a sheet; if( item->Type() != SCH_SHEET_T ) continue; for( test_item = item->Next(); test_item != NULL; test_item = test_item->Next() ) { if( test_item->Type() != SCH_SHEET_T ) continue; // We have found a second sheet: compare names // we are using case insensitive comparison to avoid mistakes between // similar names like Mysheet and mysheet if( ( (SCH_SHEET*) item )->GetName().CmpNoCase( ( ( SCH_SHEET* ) test_item )->GetName() ) == 0 ) { if( aCreateMarker ) { /* Create a new marker type ERC error*/ SCH_MARKER* marker = new SCH_MARKER(); marker->SetTimeStamp( GetNewTimeStamp() ); marker->SetData( ERCE_DUPLICATE_SHEET_NAME, ( (SCH_SHEET*) test_item )->GetPosition(), _( "Duplicate sheet name" ), ( (SCH_SHEET*) test_item )->GetPosition() ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); screen->Append( marker ); } err_count++; } } } } return err_count; }
void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter ) { wxString msg; SCH_SCREENS schematic; SCH_COMPONENT* symbol; SCH_ITEM* item; SCH_ITEM* nextItem; SCH_SCREEN* screen; for( screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) { for( item = screen->GetDrawItems(); item; item = nextItem ) { nextItem = item->Next(); if( item->Type() != SCH_COMPONENT_T ) continue; symbol = dynamic_cast< SCH_COMPONENT* >( item ); if( !remapSymbolToLibTable( symbol ) ) { msg.Printf( _( "No symbol \"%s\" found in symbol library table." ), symbol->GetLibId().GetLibItemName().wx_str() ); aReporter.Report( msg, REPORTER::RPT_WARNING ); } else { msg.Printf( _( "Symbol \"%s\" mapped to symbol library \"%s\"." ), symbol->GetLibId().GetLibItemName().wx_str(), symbol->GetLibId().GetLibNickname().wx_str() ); aReporter.Report( msg, REPORTER::RPT_ACTION ); screen->SetModify(); } } } aReporter.Report( _( "Symbol library table mapping complete!" ), REPORTER::RPT_INFO ); schematic.UpdateSymbolLinks( true ); }
bool SCH_EDIT_FRAME::doAutoSave() { wxFileName tmpFileName = g_RootSheet->GetFileName(); wxFileName fn = tmpFileName; wxFileName tmp; SCH_SCREENS screens; bool autoSaveOk = true; tmp.AssignDir( fn.GetPath() ); if( !IsWritable( tmp ) ) return false; for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { // Only create auto save files for the schematics that have been modified. if( !screen->IsSave() ) continue; tmpFileName = fn = screen->GetFileName(); // Auto save file name is the normal file name prefixed with $. fn.SetName( wxT( "$" ) + fn.GetName() ); screen->SetFileName( fn.GetFullPath() ); if( SaveEEFile( screen, false, NO_BACKUP_FILE ) ) screen->SetModify(); else autoSaveOk = false; screen->SetFileName( tmpFileName.GetFullPath() ); } if( autoSaveOk ) m_autoSaveState = false; return autoSaveOk; }
bool DIALOG_SYMBOL_REMAP::backupProject( REPORTER& aReporter ) { static wxString backupFolder = "rescue-backup"; wxString tmp; wxString errorMsg; wxFileName srcFileName; wxFileName destFileName; wxFileName backupPath; SCH_SCREENS schematic; // Copy backup files to different folder so as not to pollute the project folder. destFileName.SetPath( Prj().GetProjectPath() ); destFileName.AppendDir( backupFolder ); backupPath = destFileName; if( !destFileName.DirExists() ) { if( !destFileName.Mkdir() ) { errorMsg.Printf( _( "Cannot create project remap back up folder \"%s\"." ), destFileName.GetPath() ); wxMessageDialog dlg( this, errorMsg, _( "Backup Error" ), wxYES_NO | wxCENTRE | wxRESIZE_BORDER | wxICON_QUESTION ); dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Continue with Rescue" ) ), wxMessageDialog::ButtonLabel( _( "Abort Rescue" ) ) ); if( dlg.ShowModal() == wxID_NO ) return false; } } // Time stamp to append to file name in case multiple remappings are performed. wxString timeStamp = wxDateTime::Now().Format( "-%Y-%m-%d-%H-%M-%S" ); // Back up symbol library table. srcFileName.SetPath( Prj().GetProjectPath() ); srcFileName.SetName( SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); destFileName = srcFileName; destFileName.AppendDir( backupFolder ); destFileName.SetName( destFileName.GetName() + timeStamp ); tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), srcFileName.GetFullPath(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( wxFileName::Exists( srcFileName.GetFullPath() ) && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() ); errorMsg += tmp; } // Back up the schematic files. for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) { destFileName = screen->GetFileName(); destFileName.SetName( destFileName.GetName() + timeStamp ); // Check for nest hierarchical schematic paths. if( destFileName.GetPath() != backupPath.GetPath() ) { destFileName.SetPath( backupPath.GetPath() ); wxArrayString srcDirs = wxFileName( screen->GetFileName() ).GetDirs(); wxArrayString destDirs = wxFileName( Prj().GetProjectPath() ).GetDirs(); for( size_t i = destDirs.GetCount(); i < srcDirs.GetCount(); i++ ) destFileName.AppendDir( srcDirs[i] ); } else { destFileName.AppendDir( backupFolder ); } tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), screen->GetFileName(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( !destFileName.DirExists() && !destFileName.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) ) { tmp.Printf( _( "Failed to create backup folder \"%s\"\n" ), destFileName.GetPath() ); errorMsg += tmp; continue; } if( wxFileName::Exists( screen->GetFileName() ) && !wxCopyFile( screen->GetFileName(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), screen->GetFileName() ); errorMsg += tmp; } } // Back up the project file. destFileName = Prj().GetProjectFullName(); destFileName.SetName( destFileName.GetName() + timeStamp ); destFileName.AppendDir( backupFolder ); tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), Prj().GetProjectFullName(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( wxFileName::Exists( Prj().GetProjectFullName() ) && !wxCopyFile( Prj().GetProjectFullName(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), Prj().GetProjectFullName() ); errorMsg += tmp; } // Back up the cache library. srcFileName.SetPath( Prj().GetProjectPath() ); srcFileName.SetName( Prj().GetProjectName() + "-cache" ); srcFileName.SetExt( SchematicLibraryFileExtension ); destFileName = srcFileName; destFileName.SetName( destFileName.GetName() + timeStamp ); destFileName.AppendDir( backupFolder ); tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), srcFileName.GetFullPath(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( srcFileName.Exists() && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() ); errorMsg += tmp; } // Back up the rescue symbol library if it exists. srcFileName.SetName( Prj().GetProjectName() + "-rescue" ); destFileName.SetName( srcFileName.GetName() + timeStamp ); tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), srcFileName.GetFullPath(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( srcFileName.Exists() && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() ); errorMsg += tmp; } // Back up the rescue symbol library document file if it exists. srcFileName.SetExt( "dcm" ); destFileName.SetExt( srcFileName.GetExt() ); tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ), srcFileName.GetFullPath(), destFileName.GetFullPath() ); aReporter.Report( tmp, REPORTER::RPT_INFO ); if( srcFileName.Exists() && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) ) { tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() ); errorMsg += tmp; } if( !errorMsg.IsEmpty() ) { wxMessageDialog dlg( this, _( "Some of the project files could not be backed up." ), _( "Backup Error" ), wxYES_NO | wxCENTRE | wxRESIZE_BORDER | wxICON_QUESTION ); errorMsg.Trim(); dlg.SetExtendedMessage( errorMsg ); dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Continue with Rescue" ) ), wxMessageDialog::ButtonLabel( _( "Abort Rescue" ) ) ); if( dlg.ShowModal() == wxID_NO ) return false; } return true; }
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // implement the pseudo code from KIWAY_PLAYER.h: SCH_SCREENS screenList; // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "bug in single_top.cpp or project manager." ) ); if( !LockFile( fullFileName ) ) { wxString msg = wxString::Format( _( "Schematic file '%s' is already open." ), GetChars( fullFileName ) ); DisplayError( this, msg ); return false; } // save any currently open and modified project files. for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() ) { if( screen->IsModify() ) { int response = YesNoCancelDialog( this, _( "The current schematic has been modified. Do you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) ); if( response == wxID_CANCEL ) { return false; } else if( response == wxID_YES ) { wxCommandEvent dummy; OnSaveProject( dummy ); } else { // response == wxID_NO, fall thru } break; } } wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "Schematic '%s' does not exist. Do you wish to create it?" ), GetChars( fullFileName ) ); if( !IsOK( this, ask ) ) return false; } // unload current project file before loading new { delete g_RootSheet; g_RootSheet = NULL; CreateScreens(); } GetScreen()->SetFileName( fullFileName ); g_RootSheet->SetFileName( fullFileName ); SetStatusText( wxEmptyString ); ClearMsgPanel(); wxString msg = wxString::Format( _( "Ready\nProject dir: '%s'\n" ), GetChars( wxPathOnly( Prj().GetProjectFullName() ) ) ); SetStatusText( msg ); // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); LoadProjectFile(); // load the libraries here, not in SCH_SCREEN::Draw() which is a context // that will not tolerate DisplayError() dialog since we're already in an // event handler in there. // And when a schematic file is loaded, we need these libs to initialize // some parameters (links to PART LIB, dangling ends ...) Prj().SchLibs(); if( is_new ) { // mark new, unsaved file as modified. GetScreen()->SetModify(); } else { g_RootSheet->SetScreen( NULL ); DBG( printf( "%s: loading schematic %s\n", __func__, TO_UTF8( fullFileName ) );) bool diag = g_RootSheet->Load( this ); (void) diag; SetScreen( m_CurrentSheet->LastScreen() ); GetScreen()->ClrModify(); UpdateFileHistory( fullFileName ); }
bool DIALOG_PAGES_SETTINGS::SavePageSettings() { bool success = false; wxString fileName = GetWksFileName(); if( fileName != BASE_SCREEN::m_PageLayoutDescrFileName ) { wxString fullFileName = WORKSHEET_LAYOUT::MakeFullFileName( fileName, m_projectPath ); if( !fullFileName.IsEmpty() && !wxFileExists( fullFileName ) ) { wxString msg; msg.Printf( _( "Page layout description file \"%s\" not found." ), GetChars( fullFileName ) ); wxMessageBox( msg ); return false; } BASE_SCREEN::m_PageLayoutDescrFileName = fileName; WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance(); pglayout.SetPageLayout( fullFileName ); m_localPrjConfigChanged = true; } int idx = std::max( m_paperSizeComboBox->GetSelection(), 0 ); const wxString paperType = m_pageFmt[idx]; if( paperType.Contains( PAGE_INFO::Custom ) ) { GetCustomSizeMilsFromDialog(); success = m_pageInfo.SetType( PAGE_INFO::Custom ); if( success ) { PAGE_INFO::SetCustomWidthMils( m_layout_size.x ); PAGE_INFO::SetCustomHeightMils( m_layout_size.y ); m_pageInfo.SetWidthMils( m_layout_size.x ); m_pageInfo.SetHeightMils( m_layout_size.y ); } } else { // search for longest common string first, e.g. A4 before A if( paperType.Contains( PAGE_INFO::USLetter ) ) success = m_pageInfo.SetType( PAGE_INFO::USLetter ); else if( paperType.Contains( PAGE_INFO::USLegal ) ) success = m_pageInfo.SetType( PAGE_INFO::USLegal ); else if( paperType.Contains( PAGE_INFO::USLedger ) ) success = m_pageInfo.SetType( PAGE_INFO::USLedger ); else if( paperType.Contains( PAGE_INFO::GERBER ) ) success = m_pageInfo.SetType( PAGE_INFO::GERBER ); else if( paperType.Contains( PAGE_INFO::A4 ) ) success = m_pageInfo.SetType( PAGE_INFO::A4 ); else if( paperType.Contains( PAGE_INFO::A3 ) ) success = m_pageInfo.SetType( PAGE_INFO::A3 ); else if( paperType.Contains( PAGE_INFO::A2 ) ) success = m_pageInfo.SetType( PAGE_INFO::A2 ); else if( paperType.Contains( PAGE_INFO::A1 ) ) success = m_pageInfo.SetType( PAGE_INFO::A1 ); else if( paperType.Contains( PAGE_INFO::A0 ) ) success = m_pageInfo.SetType( PAGE_INFO::A0 ); else if( paperType.Contains( PAGE_INFO::A ) ) success = m_pageInfo.SetType( PAGE_INFO::A ); else if( paperType.Contains( PAGE_INFO::B ) ) success = m_pageInfo.SetType( PAGE_INFO::B ); else if( paperType.Contains( PAGE_INFO::C ) ) success = m_pageInfo.SetType( PAGE_INFO::C ); else if( paperType.Contains( PAGE_INFO::D ) ) success = m_pageInfo.SetType( PAGE_INFO::D ); else if( paperType.Contains( PAGE_INFO::E ) ) success = m_pageInfo.SetType( PAGE_INFO::E ); if( success ) { int choice = m_orientationComboBox->GetSelection(); m_pageInfo.SetPortrait( choice != 0 ); } } if( !success ) { wxASSERT_MSG( false, _( "the translation for paper size must preserve original spellings" ) ); m_pageInfo.SetType( PAGE_INFO::A4 ); } m_parent->SetPageSettings( m_pageInfo ); m_tb.SetRevision( m_TextRevision->GetValue() ); m_tb.SetDate( m_TextDate->GetValue() ); m_tb.SetCompany( m_TextCompany->GetValue() ); m_tb.SetTitle( m_TextTitle->GetValue() ); m_tb.SetComment1( m_TextComment1->GetValue() ); m_tb.SetComment2( m_TextComment2->GetValue() ); m_tb.SetComment3( m_TextComment3->GetValue() ); m_tb.SetComment4( m_TextComment4->GetValue() ); m_parent->SetTitleBlock( m_tb ); #ifdef EESCHEMA // Exports settings to other sheets if requested: SCH_SCREEN* screen; // Build the screen list SCH_SCREENS ScreenList; // Update title blocks for all screens for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) { if( screen == m_screen ) continue; TITLE_BLOCK tb2 = screen->GetTitleBlock(); if( m_RevisionExport->IsChecked() ) tb2.SetRevision( m_tb.GetRevision() ); if( m_DateExport->IsChecked() ) tb2.SetDate( m_tb.GetDate() ); if( m_TitleExport->IsChecked() ) tb2.SetTitle( m_tb.GetTitle() ); if( m_CompanyExport->IsChecked() ) tb2.SetCompany( m_tb.GetCompany() ); if( m_Comment1Export->IsChecked() ) tb2.SetComment1( m_tb.GetComment1() ); if( m_Comment2Export->IsChecked() ) tb2.SetComment2( m_tb.GetComment2() ); if( m_Comment3Export->IsChecked() ) tb2.SetComment3( m_tb.GetComment3() ); if( m_Comment4Export->IsChecked() ) tb2.SetComment4( m_tb.GetComment4() ); screen->SetTitleBlock( tb2 ); } #endif return true; }
bool SCH_EDIT_FRAME::LoadOneEEProject( const wxString& aFileName, bool aIsNew ) { SCH_SCREEN* screen; wxString FullFileName, msg; bool LibCacheExist = false; SCH_SCREENS ScreenList; for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) { if( screen->IsModify() ) break; } if( screen ) { int response = YesNoCancelDialog( this, _( "The current schematic has been modified. Do " "you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) ); if( response == wxID_CANCEL ) { return false; } else if( response == wxID_YES ) { wxCommandEvent dummy; OnSaveProject( dummy ); } } FullFileName = aFileName; if( FullFileName.IsEmpty() && !aIsNew ) { wxFileDialog dlg( this, _( "Open Schematic" ), wxGetCwd(), wxEmptyString, SchematicFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); if( dlg.ShowModal() == wxID_CANCEL ) return false; FullFileName = dlg.GetPath(); } wxFileName fn = FullFileName; if( fn.IsRelative() ) { fn.MakeAbsolute(); FullFileName = fn.GetFullPath(); } if( !wxGetApp().LockFile( FullFileName ) ) { DisplayError( this, _( "This file is already open." ) ); return false; } // Clear the screen before open a new file if( g_RootSheet ) { delete g_RootSheet; g_RootSheet = NULL; } CreateScreens(); screen = GetScreen(); wxLogDebug( wxT( "Loading schematic " ) + FullFileName ); wxSetWorkingDirectory( fn.GetPath() ); screen->SetFileName( FullFileName ); g_RootSheet->SetFileName( FullFileName ); SetStatusText( wxEmptyString ); ClearMsgPanel(); screen->ClrModify(); if( aIsNew ) { /* SCH_SCREEN constructor does this now screen->SetPageSettings( PAGE_INFO( wxT( "A4" ) ) ); */ screen->SetZoom( 32 ); screen->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); TITLE_BLOCK tb; wxString title; title += NAMELESS_PROJECT; title += wxT( ".sch" ); tb.SetTitle( title ); screen->SetTitleBlock( tb ); GetScreen()->SetFileName( title ); LoadProjectFile( wxEmptyString, true ); Zoom_Automatique( false ); SetSheetNumberAndCount(); m_canvas->Refresh(); return true; } // Reloading configuration. msg.Printf( _( "Ready\nWorking dir: <%s>\n" ), GetChars( wxGetCwd() ) ); PrintMsg( msg ); LoadProjectFile( wxEmptyString, false ); // Clear (if needed) the current active library in libedit because it could be // removed from memory LIB_EDIT_FRAME::EnsureActiveLibExists(); // Delete old caches. CMP_LIBRARY::RemoveCacheLibrary(); LibCacheExist = LoadCacheLibrary( g_RootSheet->GetScreen()->GetFileName() ); if( !wxFileExists( g_RootSheet->GetScreen()->GetFileName() ) && !LibCacheExist ) { Zoom_Automatique( false ); msg.Printf( _( "File <%s> not found." ), GetChars( g_RootSheet->GetScreen()->GetFileName() ) ); DisplayInfoMessage( this, msg ); return false; } // load the project. g_RootSheet->SetScreen( NULL ); bool diag = g_RootSheet->Load( this ); SetScreen( m_CurrentSheet->LastScreen() ); UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); /* Redraw base screen (ROOT) if necessary. */ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); Zoom_Automatique( false ); SetSheetNumberAndCount(); m_canvas->Refresh( true ); return diag; }
bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) { SCH_SCREENS screens; PART_LIBS* libs = Prj().SchLibs(); std::unique_ptr<PART_LIB> libCache( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) ); libCache->SetCache(); /* examine all screens (not sheets) used and build the list of components * found in lib. * Complex hierarchies are not a problem because we just want * to know used components in libraries */ for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; SCH_COMPONENT* component = (SCH_COMPONENT*) item; // If not already saved in the new cache, put it: if( !libCache->FindEntry( component->GetPartName() ) ) { if( LIB_PART* part = libs->FindLibPart( component->GetPartName() ) ) { // AddPart() does first clone the part before adding. libCache->AddPart( part ); } } } } try { FILE_OUTPUTFORMATTER formatter( aFileName ); if( !libCache->Save( formatter ) ) { wxString msg = wxString::Format( _( "An error occurred attempting to save component library '%s'." ), GetChars( aFileName ) ); DisplayError( this, msg ); return false; } } catch( ... /* IO_ERROR ioe */ ) { wxString msg = wxString::Format( _( "Failed to create component library file '%s'" ), GetChars( aFileName ) ); DisplayError( this, msg ); return false; } return true; }
void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) { wxFileName fn; m_writeErcFile = m_WriteResultOpt->GetValue(); m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue(); m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue(); // Build the whole sheet list in hierarchy (sheet, not screen) SCH_SHEET_LIST sheets; sheets.AnnotatePowerSymbols( Prj().SchLibs() ); if( m_parent->CheckAnnotate( aMessagesList, false ) ) { if( aMessagesList ) { wxString msg = _( "Annotation required!" ); msg += wxT( "\n" ); aMessagesList->Add( msg ); } return; } SCH_SCREENS screens; // Erase all previous DRC markers. screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC ); for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted * data problems. */ if( screen->SchematicCleanUp( NULL ) ) screen->ClearUndoRedoList(); } /* Test duplicate sheet names inside a given sheet, one cannot have sheets with * duplicate names (file names can be duplicated). */ TestDuplicateSheetNames( true ); std::auto_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() ); // Reset the connection type indicator objectsConnectedList->ResetConnectionsType(); unsigned lastNet; unsigned nextNet = lastNet = 0; int MinConn = NOC; for( unsigned net = 0; net < objectsConnectedList->size(); net++ ) { if( objectsConnectedList->GetItemNet( lastNet ) != objectsConnectedList->GetItemNet( net ) ) { // New net found: MinConn = NOC; nextNet = net; } switch( objectsConnectedList->GetItemType( net ) ) { // These items do not create erc problems case NET_ITEM_UNSPECIFIED: case NET_SEGMENT: case NET_BUS: case NET_JUNCTION: case NET_LABEL: case NET_BUSLABELMEMBER: case NET_PINLABEL: case NET_GLOBBUSLABELMEMBER: break; case NET_HIERLABEL: case NET_HIERBUSLABELMEMBER: case NET_SHEETLABEL: case NET_SHEETBUSLABELMEMBER: // ERC problems when pin sheets do not match hierarchical labels. // Each pin sheet must match a hierarchical label // Each hierarchical label must match a pin sheet objectsConnectedList->TestforNonOrphanLabel( net, nextNet ); break; case NET_GLOBLABEL: if( m_tstUniqueGlobalLabels ) objectsConnectedList->TestforNonOrphanLabel( net, nextNet ); break; case NET_NOCONNECT: // ERC problems when a noconnect symbol is connected to more than one pin. MinConn = NET_NC; if( objectsConnectedList->CountPinsInNet( nextNet ) > 1 ) Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC ); break; case NET_PIN: // Look for ERC problems between pins: TestOthersItems( objectsConnectedList.get(), net, nextNet, &MinConn ); break; } lastNet = net; } // Test similar labels (i;e. labels which are identical when // using case insensitive comparisons) if( m_TestSimilarLabels ) objectsConnectedList->TestforSimilarLabels(); // Displays global results: updateMarkerCounts( &screens ); // Display diags: DisplayERC_MarkersList(); // Display new markers: m_parent->GetCanvas()->Refresh(); if( m_writeErcFile ) { fn = g_RootSheet->GetScreen()->GetFileName(); fn.SetExt( wxT( "erc" ) ); wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(), _( "Electronic rule check file (.erc)|*.erc" ), wxFD_SAVE ); if( dlg.ShowModal() == wxID_CANCEL ) return; if( WriteDiagnosticERC( dlg.GetPath() ) ) { Close( true ); ExecuteFile( this, Pgm().GetEditorName(), QuoteFullPath( fn ) ); } } }
int TestConflictingBusAliases( bool aCreateMarker ) { using std::pair; using std::shared_ptr; using std::vector; int err_count = 0; SCH_SCREENS screens; vector< shared_ptr<BUS_ALIAS> > aliases; vector< pair< shared_ptr<BUS_ALIAS>, shared_ptr<BUS_ALIAS> > > conflicts; for( auto screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { auto screen_aliases = screen->GetBusAliases(); for( auto alias : screen_aliases ) { for( auto test : aliases ) { if( alias->GetName() == test->GetName() && alias->Members() != test->Members() ) { conflicts.push_back( std::make_pair( alias, test ) ); } } } aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() ); } if( !conflicts.empty() ) { if( aCreateMarker ) { wxString msg; for( auto conflict : conflicts ) { auto marker = new SCH_MARKER(); auto a1 = conflict.first; auto a2 = conflict.second; msg.Printf( _( "Bus alias %s has conflicting definitions on multiple sheets: " ), GetChars( a1->GetName() ) ); wxFileName f1 = a1->GetParent()->GetFileName(); wxFileName f2 = a2->GetParent()->GetFileName(); msg << f1.GetFullName() << " and " << f2.GetFullName(); marker->SetData( ERCE_BUS_ALIAS_CONFLICT, wxPoint( 0, 0 ), msg, wxPoint( 0, 0 ) ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); a2->GetParent()->Append( marker ); ++err_count; } } } return err_count; }
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) { LIB_EDIT_FRAME * libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; if( libeditFrame && !libeditFrame->Close() ) // Can close component editor? return; LIB_VIEW_FRAME* viewlibFrame = LIB_VIEW_FRAME::GetActiveLibraryViewer( this ); if( viewlibFrame && !viewlibFrame->Close() ) // Can close component viewer? return; SCH_SHEET_LIST SheetList; if( SheetList.IsModified() ) { wxString msg; msg.Printf( _("Save the changes in\n<%s>\nbefore closing?"), GetChars( g_RootSheet->GetScreen()->GetFileName() ) ); int ii = DisplayExitDialog( this, msg ); switch( ii ) { case wxID_CANCEL: aEvent.Veto(); return; case wxID_NO: break; case wxID_YES: wxCommandEvent tmp( ID_SAVE_PROJECT ); OnSaveProject( tmp ); break; } } // Close the find dialog and perserve it's setting if it is displayed. if( m_dlgFindReplace ) { m_findDialogPosition = m_dlgFindReplace->GetPosition(); m_findDialogSize = m_dlgFindReplace->GetSize(); m_findStringHistoryList = m_dlgFindReplace->GetFindEntries(); m_replaceStringHistoryList = m_dlgFindReplace->GetReplaceEntries(); m_dlgFindReplace->Destroy(); m_dlgFindReplace = NULL; } SCH_SCREENS screens; wxFileName fn; for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { fn = screen->GetFileName(); // Auto save file name is the normal file name prepended with $. fn.SetName( wxT( "$" ) + fn.GetName() ); if( fn.FileExists() && fn.IsFileWritable() ) wxRemoveFile( fn.GetFullPath() ); } SheetList.ClearModifyStatus(); if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() && (g_RootSheet->GetScreen()->GetDrawItems() != NULL) ) UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); g_RootSheet->GetScreen()->Clear(); // all sub sheets are deleted, only the main sheet is usable m_CurrentSheet->Clear(); Destroy(); }
void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) { wxFileName fn; if( !DiagErcTableInit ) { memcpy( DiagErc, DefaultDiagErc, sizeof(DefaultDiagErc) ); DiagErcTableInit = true; } m_writeErcFile = m_WriteResultOpt->GetValue(); /* Build the whole sheet list in hierarchy (sheet, not screen) */ SCH_SHEET_LIST sheets; sheets.AnnotatePowerSymbols(); if( m_parent->CheckAnnotate( aMessagesList, false ) ) { if( aMessagesList ) { wxString msg = _( "Annotation required!" ); msg += wxT( "\n" ); aMessagesList->Add( msg ); } return; } SCH_SCREENS screens; // Erase all previous DRC markers. screens.DeleteAllMarkers( MARK_ERC ); for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted * data problems. */ if( screen->SchematicCleanUp( NULL ) ) screen->ClearUndoRedoList(); } /* Test duplicate sheet names inside a given sheet, one cannot have sheets with * duplicate names (file names can be duplicated). */ TestDuplicateSheetNames( true ); NETLIST_OBJECT_LIST* objectsConnectedList = m_parent->BuildNetListBase(); // Reset the connection type indicator objectsConnectedList->ResetConnectionsType(); unsigned lastNet; unsigned nextNet = lastNet = 0; int NetNbItems = 0; int MinConn = NOC; for( unsigned net = 0; net < objectsConnectedList->size(); net++ ) { if( objectsConnectedList->GetItemNet( lastNet ) != objectsConnectedList->GetItemNet( net ) ) { // New net found: MinConn = NOC; NetNbItems = 0; nextNet = net; } switch( objectsConnectedList->GetItemType( net ) ) { // These items do not create erc problems case NET_ITEM_UNSPECIFIED: case NET_SEGMENT: case NET_BUS: case NET_JUNCTION: case NET_LABEL: case NET_BUSLABELMEMBER: case NET_PINLABEL: case NET_GLOBLABEL: case NET_GLOBBUSLABELMEMBER: break; case NET_HIERLABEL: case NET_HIERBUSLABELMEMBER: case NET_SHEETLABEL: case NET_SHEETBUSLABELMEMBER: // ERC problems when pin sheets do not match hierarchical labels. // Each pin sheet must match a hierarchical label // Each hierarchical label must match a pin sheet TestLabel( objectsConnectedList, net, nextNet ); break; case NET_NOCONNECT: // ERC problems when a noconnect symbol is connected to more than one pin. MinConn = NET_NC; if( NetNbItems != 0 ) Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC ); break; case NET_PIN: // Look for ERC problems between pins: TestOthersItems( objectsConnectedList, net, nextNet, &NetNbItems, &MinConn ); break; } lastNet = net; } // Displays global results: wxString num; int markers = screens.GetMarkerCount(); int warnings = screens.GetMarkerCount( WAR ); num.Printf( wxT( "%d" ), markers ); m_TotalErrCount->SetLabel( num ); num.Printf( wxT( "%d" ), markers - warnings ); m_LastErrCount->SetLabel( num ); num.Printf( wxT( "%d" ), warnings ); m_LastWarningCount->SetLabel( num ); // Display diags: DisplayERC_MarkersList(); // Display new markers: m_parent->GetCanvas()->Refresh(); if( m_writeErcFile ) { fn = g_RootSheet->GetScreen()->GetFileName(); fn.SetExt( wxT( "erc" ) ); wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(), _( "Electronic rule check file (.erc)|*.erc" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) return; if( WriteDiagnosticERC( dlg.GetPath() ) ) { Close( true ); ExecuteFile( this, wxGetApp().GetEditorName(), QuoteFullPath( fn ) ); } } }