void KVSpectroDetector::AddAbsorberLayer( TGeoVolume *vol, Bool_t active){ // Add an absorber layer to the detector made from the shape of the // volume. // If active = kTRUE the layer is set active. TGeoMaterial* material = vol->GetMaterial(); KVIonRangeTableMaterial* irmat = KVMaterial::GetRangeTable()->GetMaterial(material); if(!irmat){ Warning("AddAbsorberLayer", "Unknown material %s/%s used in layer %s of detector %s", material->GetName(), material->GetTitle(), vol->GetName(), GetName()); return; } TGeoBBox* sh = dynamic_cast<TGeoBBox*>(vol->GetShape()); if(!sh) { Warning("AddAbsorberLayer", "Unknown shape class %s used in layer %s of detector %s", vol->GetShape()->ClassName(), vol->GetName(), GetName()); return; // just in case - for now, all shapes derive from TGeoBBox... } Double_t width = 2.*sh->GetDZ(); // thickness in centimetres KVMaterial* absorber; if( irmat->IsGas() ){ Double_t p = material->GetPressure(); Double_t T = material->GetTemperature(); absorber = new KVMaterial(irmat->GetType(), width, p, T); } else absorber = new KVMaterial(irmat->GetType(), width); KVDetector::AddAbsorber(absorber); ClearHits(); if( active ) SetActiveLayer( GetListOfAbsorbers()->GetEntries()-1 ); }
bool GERBVIEW_FRAME::Clear_DrawLayers( bool query ) { if( GetGerberLayout() == NULL ) return false; if( query && GetScreen()->IsModify() ) { if( !IsOK( this, _( "Current data will be lost?" ) ) ) return false; } if( auto canvas = GetGalCanvas() ) { canvas->GetView()->Clear(); } GetImagesList()->DeleteAllImages(); GetGerberLayout()->SetBoundingBox( EDA_RECT() ); SetActiveLayer( 0 ); ReFillLayerWidget(); syncLayerBox(); return true; }
bool GERBVIEW_FRAME::LoadZipArchiveFile( const wxString& aFullFileName ) { #define ZipFileExtension "zip" wxFileName filename = aFullFileName; wxString currentPath; if( !filename.IsOk() ) { // Use the current working directory if the file name path does not exist. if( filename.DirExists() ) currentPath = filename.GetPath(); else currentPath = m_mruPath; wxFileDialog dlg( this, _( "Open Zip File" ), currentPath, filename.GetFullName(), ZipFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) return false; filename = dlg.GetPath(); currentPath = wxGetCwd(); m_mruPath = currentPath; } else { currentPath = filename.GetPath(); m_mruPath = currentPath; } wxString msg; WX_STRING_REPORTER reporter( &msg ); if( filename.IsOk() ) unarchiveFiles( filename.GetFullPath(), &reporter ); Zoom_Automatique( false ); // Synchronize layers tools with actual active layer: ReFillLayerWidget(); SetActiveLayer( GetActiveLayer() ); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); if( !msg.IsEmpty() ) { wxSafeYield(); // Allows slice of time to redraw the screen // to refresh widgets, before displaying messages HTML_MESSAGE_BOX mbox( this, _( "Messages" ) ); mbox.ListSet( msg ); mbox.ShowModal(); } return true; }
KVBIC::KVBIC(Float_t pressure, Float_t bomb): KVChIo() { //BIC detector. //Give pressure in Torr // //Segmentation index = 1 //because particles passing through BIC can only hit 1 detector - SIB - behind it //this is analogous to the Si-CsI telescopes of ring 1. //The type of these detectors is "BIC" //Pressure units are Torr SetType("BIC"); SetSegment(1); fLinCal = 0; fBomb = bomb; //build detector AddAbsorber(new KVMaterial("Myl", 1.5 * KVUnits::um)); //mylar entry window Float_t e = GetEffectiveEntryThickness(); KVMaterial* gas = new KVMaterial("CF4", e * KVUnits::mm, pressure); AddAbsorber(gas); //gas between two windows AddAbsorber(new KVMaterial("Myl", 1.0 * KVUnits::um)); //interior window gas = new KVMaterial("CF4", 60 * KVUnits::mm, pressure); AddAbsorber(gas); //main body of gas SetActiveLayer(gas); //active layer - energy loss is measured AddAbsorber(new KVMaterial("Myl", 1.0 * KVUnits::um)); //2nd interor window gas = new KVMaterial("CF4", e * KVUnits::mm, pressure); AddAbsorber(gas); //gas between two exit windows AddAbsorber(new KVMaterial("Myl", 1.5 * KVUnits::um)); //exit window }
void KVSpectroDetector::init(){ //default initialisations SetActiveLayer(-1); // Necessary to remove some warning with GetPressure and GetTemperature. fActiveVolumes = NULL; fFocalToTarget = NULL; fNabsorbers = 0; fTotThick = 0; //use by default random position SetBit( kRdmPos ); //a KVSpectroDetector can be used in a ID telescope SetBit( kOKforID ); }
//______________________________________________________________________________ KVChIo::KVChIo(Float_t pressure, Float_t thick):KVINDRADetector("Myl", 2.5*KVUnits::um) { // Make an INDRA ChIo: 2.5micron mylar windows enclosing 'thick' cm of C3F8, // give gas pressure in mbar // By default 'thick'=5cm // The type of these detectors is "CI" //gas layer KVMaterial *mat = new KVMaterial("C3F8", thick, pressure*KVUnits::mbar); AddAbsorber(mat); SetActiveLayer(mat); //gas is the active layer // mylar for second window mat = new KVMaterial("Myl", 2.5*KVUnits::um); AddAbsorber(mat); SetType("CI"); init(); }
void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) { int id = event.GetId(); wxFileName fn; switch( id ) { case ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG: m_show_layer_manager_tools = ! m_show_layer_manager_tools; m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools ); m_auimgr.Update(); GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG, m_show_layer_manager_tools ? _("Hide &Layers Manager" ) : _("Show &Layers Manager" )); break; case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: m_show_microwave_tools = ! m_show_microwave_tools; m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools ); m_auimgr.Update(); GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR, m_show_microwave_tools ? _( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" )); break; case ID_PCB_LAYERS_SETUP: if( InvokeLayerSetup( this, GetBoard() ) ) { LAYER_ID cur_layer = GetActiveLayer(); // If after showing the dialog the user has removed the active layer, // then select a new active layer (front copper layer). if( !GetBoard()->GetEnabledLayers()[ cur_layer ] ) cur_layer = F_Cu; SetActiveLayer( cur_layer ); OnModify(); ReCreateLayerBox(); ReFillLayerWidget(); if( IsGalCanvasActive() ) static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() ); } break; case ID_PCB_LIB_WIZARD: case ID_PCB_LIB_TABLE_EDIT: { bool tableChanged = false; int r = 0; if( id == ID_PCB_LIB_TABLE_EDIT ) r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() ); else r = InvokeFootprintWizard( this, &GFootprintTable, Prj().PcbFootprintLibs() ); if( r & 1 ) { try { FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() ); GFootprintTable.Format( &sf, 0 ); tableChanged = true; } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error occurred saving the global footprint library " "table:\n\n%s" ), GetChars( ioe.errorText.GetData() ) ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } // If no board file is defined, do not save the project specific library table. It // is kept in memory and created in the path when the new board is saved. if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() ) { wxString tblName = Prj().FootprintLibTblName(); try { Prj().PcbFootprintLibs()->Save( tblName ); tableChanged = true; } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error occurred saving project specific footprint library " "table:\n\n%s" ), GetChars( ioe.errorText ) ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } FOOTPRINT_VIEWER_FRAME* viewer; if( tableChanged && (viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false )) != NULL ) { viewer->ReCreateLibraryList(); } } break; case ID_PCB_3DSHAPELIB_WIZARD: #ifdef BUILD_GITHUB_PLUGIN Invoke3DShapeLibsDownloaderWizard( this ); #endif break; case ID_PCB_MASK_CLEARANCE: { DIALOG_PADS_MASK_CLEARANCE dlg( this ); if( dlg.ShowModal() == 1 && IsGalCanvasActive() ) { for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) module->ViewUpdate(); GetGalCanvas()->Refresh(); } } break; case wxID_PREFERENCES: { DIALOG_GENERALOPTIONS dlg( this ); dlg.ShowModal(); } break; case ID_PCB_PAD_SETUP: InstallPadOptionsFrame( NULL ); break; case ID_CONFIG_SAVE: SaveProjectSettings( true ); break; case ID_CONFIG_READ: { fn = GetBoard()->GetFileName(); fn.SetExt( ProjectFileExtension ); wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(), fn.GetFullName(), ProjectFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) break; if( !wxFileExists( dlg.GetPath() ) ) { wxString msg = wxString::Format( _( "File %s not found" ), GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); break; } wxString pro_file = dlg.GetPath(); Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_file ); } break; // Hotkey IDs case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG: ExportHotkeyConfigToFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) ); break; case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG: ImportHotkeyConfigFromFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) ); break; case ID_PREFERENCES_HOTKEY_SHOW_EDITOR: InstallHotkeyFrame( this, g_Board_Editor_Hokeys_Descr ); break; case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST: // Display current hotkey list for Pcbnew. DisplayHotkeyList( this, g_Board_Editor_Hokeys_Descr ); break; default: DisplayError( this, wxT( "PCB_EDIT_FRAME::Process_Config error" ) ); } }
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) { unsigned itmp; if( aTrack == NULL ) { if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP ) SetActiveLayer( GetScreen()->m_Route_Layer_TOP ); else SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM ); UpdateStatusBar(); return true; } // Avoid more than one via on the current location: if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(), g_CurrentTrackSegment->GetLayer() ) ) return false; for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() ) { if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() ) return false; } // Is the current segment Ok (no DRC error) ? if( g_Drc_On ) { if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) ) // DRC error, the change layer is not made return false; // Handle 2 segments. if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() ) { if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) ) return false; } } /* Save current state before placing a via. * If the via cannot be placed this current state will be reused */ itmp = g_CurrentTrackList.GetCount(); Begin_Route( g_CurrentTrackSegment, DC ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // create the via VIA* via = new VIA( GetBoard() ); via->SetFlags( IS_NEW ); via->SetViaType( GetDesignSettings().m_CurrentViaType ); via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetPosition( g_CurrentTrackSegment->GetEnd() ); // for microvias, the size and hole will be changed later. via->SetWidth( GetDesignSettings().GetCurrentViaSize()); via->SetDrill( GetDesignSettings().GetCurrentViaDrill() ); // Usual via is from copper to component. // layer pair is B_Cu and F_Cu. via->SetLayerPair( B_Cu, F_Cu ); LAYER_ID first_layer = GetActiveLayer(); LAYER_ID last_layer; // prepare switch to new active layer: if( first_layer != GetScreen()->m_Route_Layer_TOP ) last_layer = GetScreen()->m_Route_Layer_TOP; else last_layer = GetScreen()->m_Route_Layer_BOTTOM; // Adjust the actual via layer pair switch( via->GetViaType() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); break; case VIA_MICROVIA: // from external to the near neighbor inner layer { LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) ); if( first_layer == B_Cu ) last_layer = last_inner_layer; else if( first_layer == F_Cu ) last_layer = In1_Cu; else if( first_layer == last_inner_layer ) last_layer = B_Cu; else if( first_layer == In1_Cu ) last_layer = F_Cu; // else error: will be removed later via->SetLayerPair( first_layer, last_layer ); // Update diameter and hole size, which where set previously // for normal vias NETINFO_ITEM* net = via->GetNet(); via->SetWidth( net->GetMicroViaSize() ); via->SetDrill( net->GetMicroViaDrillSize() ); } break; default: break; } if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) ) { // DRC fault: the Via cannot be placed here ... delete via; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // delete the track(s) added in Begin_Route() while( g_CurrentTrackList.GetCount() > itmp ) { Delete_Segment( DC, g_CurrentTrackSegment ); } SetCurItem( g_CurrentTrackSegment, false ); // Refresh DRC diag, erased by previous calls if( m_drc->GetCurrentMarker() ) SetMsgPanel( m_drc->GetCurrentMarker() ); return false; } SetActiveLayer( last_layer ); TRACK* lastNonVia = g_CurrentTrackSegment; /* A new via was created. It was Ok. */ g_CurrentTrackList.PushBack( via ); /* The via is now in linked list and we need a new track segment * after the via, starting at via location. * it will become the new current segment (from via to the mouse cursor) */ TRACK* track = (TRACK*)lastNonVia->Clone(); /* the above creates a new segment from the last entered segment, with the * current width, flags, netcode, etc... values. * layer, start and end point are not correct, * and will be modified next */ // set the layer to the new value track->SetLayer( GetActiveLayer() ); /* the start point is the via position and the end point is the cursor * which also is on the via (will change when moving mouse) */ track->SetEnd( via->GetStart() ); track->SetStart( via->GetStart() ); g_CurrentTrackList.PushBack( track ); if( g_TwoSegmentTrackBuild ) { // Create a second segment (we must have 2 track segments to adjust) g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() ); } m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); SetMsgPanel( via ); UpdateStatusBar(); return true; }
bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aReporter ) { wxString msg; // Extract the path of aFullFileName. We use it to store temporary files wxFileName fn( aFullFileName ); wxString unzipDir = fn.GetPath(); wxFFileInputStream zipFile( aFullFileName ); if( !zipFile.IsOk() ) { if( aReporter ) { msg.Printf( _( "Zip file \"%s\" cannot be opened" ), GetChars( aFullFileName ) ); aReporter->Report( msg, REPORTER::RPT_ERROR ); } return false; } // Update the list of recent zip files. UpdateFileHistory( aFullFileName, &m_zipFileHistory ); // The unzipped file in only a temporary file. Give it a filename // which cannot conflict with an usual filename. // TODO: make Read_GERBER_File() and Read_EXCELLON_File() able to // accept a stream, and avoid using a temp file. wxFileName temp_fn( "$tempfile.tmp" ); temp_fn.MakeAbsolute( unzipDir ); wxString unzipped_tempfile = temp_fn.GetFullPath(); bool success = true; wxZipInputStream zipArchive( zipFile ); wxZipEntry* entry; bool reported_no_more_layer = false; while( ( entry = zipArchive.GetNextEntry() ) ) { wxString fname = entry->GetName(); wxFileName uzfn = fname; wxString curr_ext = uzfn.GetExt().Lower(); // The archive contains Gerber and/or Excellon drill files. Use the right loader. // However it can contain a few other files (reports, pdf files...), // which will be skipped. // Gerber files ext is usually "gbr", but can be also an other value, starting by "g" // old gerber files ext from kicad is .pho // drill files do not have a well defined ext // It is .drl in kicad, but .txt in Altium for instance // Allows only .drl for drill files. if( curr_ext[0] != 'g' && curr_ext != "pho" && curr_ext != "drl" ) { if( aReporter ) { msg.Printf( _( "Info: skip file <i>\"%s\"</i> (unknown type)\n" ), GetChars( entry->GetName() ) ); aReporter->Report( msg, REPORTER::RPT_WARNING ); } continue; } int layer = GetActiveLayer(); if( layer == NO_AVAILABLE_LAYERS ) { success = false; if( aReporter ) { if( !reported_no_more_layer ) aReporter->Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR ); reported_no_more_layer = true; // Report the name of not loaded files: msg.Printf( MSG_NOT_LOADED, GetChars( entry->GetName() ) ); aReporter->Report( msg, REPORTER::RPT_ERROR ); } delete entry; continue; } // Create the unzipped temporary file: { wxFFileOutputStream temporary_ofile( unzipped_tempfile ); if( temporary_ofile.Ok() ) temporary_ofile.Write( zipArchive ); else { success = false; if( aReporter ) { msg.Printf( _( "<b>Unable to create temporary file \"%s\"</b>\n"), GetChars( unzipped_tempfile ) ); aReporter->Report( msg, REPORTER::RPT_ERROR ); } } } bool read_ok = true; if( curr_ext[0] == 'g' || curr_ext == "pho" ) { // Read gerber files: each file is loaded on a new GerbView layer read_ok = Read_GERBER_File( unzipped_tempfile ); } else // if( curr_ext == "drl" ) { read_ok = Read_EXCELLON_File( unzipped_tempfile ); } delete entry; // The unzipped file is only a temporary file, delete it. wxRemoveFile( unzipped_tempfile ); if( !read_ok ) { success = false; if( aReporter ) { msg.Printf( _("<b>unzipped file %s read error</b>\n"), GetChars( unzipped_tempfile ) ); aReporter->Report( msg, REPORTER::RPT_ERROR ); } } else { GERBER_FILE_IMAGE* gerber_image = GetGbrImage( layer ); if( gerber_image ) gerber_image->m_FileName = fname; layer = getNextAvailableLayer( layer ); SetActiveLayer( layer, false ); } } return success; }
bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName ) { wxString filetypes; wxArrayString filenamesList; wxFileName filename = aFullFileName; wxString currentPath; if( !filename.IsOk() ) { filetypes = DrillFileWildcard(); filetypes << wxT( "|" ); /* All filetypes */ filetypes += wxGetTranslation( AllFilesWildcard ); /* Use the current working directory if the file name path does not exist. */ if( filename.DirExists() ) currentPath = filename.GetPath(); else currentPath = m_mruPath; wxFileDialog dlg( this, _( "Open Drill File" ), currentPath, filename.GetFullName(), filetypes, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) return false; dlg.GetPaths( filenamesList ); currentPath = wxGetCwd(); m_mruPath = currentPath; } else { filenamesList.Add( aFullFileName ); currentPath = filename.GetPath(); m_mruPath = currentPath; } // Read Excellon drill files: each file is loaded on a new GerbView layer bool success = true; int layer = GetActiveLayer(); // Manage errors when loading files wxString msg; WX_STRING_REPORTER reporter( &msg ); for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ ) { filename = filenamesList[ii]; if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); m_lastFileName = filename.GetFullPath(); SetActiveLayer( layer, false ); if( Read_EXCELLON_File( filename.GetFullPath() ) ) { // Update the list of recent drill files. UpdateFileHistory( filename.GetFullPath(), &m_drillFileHistory ); layer = getNextAvailableLayer( layer ); if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 ) { success = false; reporter.Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR ); // Report the name of not loaded files: ii += 1; while( ii < filenamesList.GetCount() ) { filename = filenamesList[ii++]; wxString txt; txt.Printf( MSG_NOT_LOADED, GetChars( filename.GetFullName() ) ); reporter.Report( txt, REPORTER::RPT_ERROR ); } break; } SetActiveLayer( layer, false ); } } if( !success ) { HTML_MESSAGE_BOX mbox( this, _( "Errors" ) ); mbox.ListSet( msg ); mbox.ShowModal(); } Zoom_Automatique( false ); // Synchronize layers tools with actual active layer: ReFillLayerWidget(); SetActiveLayer( GetActiveLayer() ); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); return success; }
bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName ) { wxString filetypes; wxArrayString filenamesList; wxFileName filename = aFullFileName; wxString currentPath; if( !filename.IsOk() ) { /* Standard gerber filetypes * (See http://en.wikipedia.org/wiki/Gerber_File) * the .gbr (.pho in legacy files) extension is the default used in Pcbnew * However there are a lot of other extensions used for gerber files * Because the first letter is usually g, we accept g* as extension * (Mainly internal copper layers do not have specific extension, * and filenames are like *.g1, *.g2 *.gb1 ...). * Now (2014) Ucamco (the company which manages the Gerber format) encourages * use of .gbr only and the Gerber X2 file format. */ filetypes = _( "Gerber files (.g* .lgr .pho)" ); filetypes << wxT("|"); filetypes += wxT("*.g*;*.G*;*.pho;*.PHO" ); filetypes << wxT("|"); /* Special gerber filetypes */ filetypes += _( "Top layer (*.GTL)|*.GTL;*.gtl|" ); filetypes += _( "Bottom layer (*.GBL)|*.GBL;*.gbl|" ); filetypes += _( "Bottom solder resist (*.GBS)|*.GBS;*.gbs|" ); filetypes += _( "Top solder resist (*.GTS)|*.GTS;*.gts|" ); filetypes += _( "Bottom overlay (*.GBO)|*.GBO;*.gbo|" ); filetypes += _( "Top overlay (*.GTO)|*.GTO;*.gto|" ); filetypes += _( "Bottom paste (*.GBP)|*.GBP;*.gbp|" ); filetypes += _( "Top paste (*.GTP)|*.GTP;*.gtp|" ); filetypes += _( "Keep-out layer (*.GKO)|*.GKO;*.gko|" ); filetypes += _( "Mechanical layers (*.GMx)|*.GM1;*.gm1;*.GM2;*.gm2;*.GM3;*.gm3|" ); filetypes += _( "Top Pad Master (*.GPT)|*.GPT;*.gpt|" ); filetypes += _( "Bottom Pad Master (*.GPB)|*.GPB;*.gpb|" ); // All filetypes filetypes += AllFilesWildcard; // Use the current working directory if the file name path does not exist. if( filename.DirExists() ) currentPath = filename.GetPath(); else { currentPath = m_mruPath; // On wxWidgets 3.1 (bug?) the path in wxFileDialog is ignored when // finishing by the dir separator. Remove it if any: if( currentPath.EndsWith( '\\' ) || currentPath.EndsWith( '/' ) ) currentPath.RemoveLast(); } wxFileDialog dlg( this, _( "Open Gerber File" ), currentPath, filename.GetFullName(), filetypes, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) return false; dlg.GetPaths( filenamesList ); // @todo Take a closer look at the CWD switching here. The current working directory // gets changed by wxFileDialog because the wxFD_CHANGE_DIR flag is set. Is this the // appropriate behavior? The current working directory is not returned to the previous // value so this may be an issue elsewhere. currentPath = wxGetCwd(); m_mruPath = currentPath; } else { filenamesList.Add( aFullFileName ); currentPath = filename.GetPath(); m_mruPath = currentPath; } // Set the busy cursor wxBusyCursor wait; // Read gerber files: each file is loaded on a new GerbView layer bool success = true; int layer = GetActiveLayer(); // Manage errors when loading files wxString msg; WX_STRING_REPORTER reporter( &msg ); for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ ) { filename = filenamesList[ii]; if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); m_lastFileName = filename.GetFullPath(); SetActiveLayer( layer, false ); if( Read_GERBER_File( filename.GetFullPath() ) ) { UpdateFileHistory( m_lastFileName ); layer = getNextAvailableLayer( layer ); if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 ) { success = false; reporter.Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR ); // Report the name of not loaded files: ii += 1; while( ii < filenamesList.GetCount() ) { filename = filenamesList[ii++]; wxString txt; txt.Printf( MSG_NOT_LOADED, GetChars( filename.GetFullName() ) ); reporter.Report( txt, REPORTER::RPT_ERROR ); } break; } SetActiveLayer( layer, false ); } } if( !success ) { HTML_MESSAGE_BOX mbox( this, _( "Errors" ) ); mbox.ListSet( msg ); mbox.ShowModal(); } Zoom_Automatique( false ); // Synchronize layers tools with actual active layer: ReFillLayerWidget(); SetActiveLayer( GetActiveLayer() ); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); return success; }
TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) { int current_net_code; if( aTrack == NULL ) return NULL; if( aTrack->IsNew() ) // Trace in progress, erase the last segment { if( g_CurrentTrackList.GetCount() > 0 ) { LAYER_NUM previous_layer = GetActiveLayer(); DBG( g_CurrentTrackList.VerifyListIntegrity(); ) // Delete the current trace ShowNewTrackWhenMovingCursor( m_canvas, DC, wxDefaultPosition, false ); // delete the most recently entered delete g_CurrentTrackList.PopBack(); if( g_TwoSegmentTrackBuild ) { // if in 2 track mode, and the next most recent is a segment // not a via, and the one previous to that is a via, then // delete up to the via. if( g_CurrentTrackList.GetCount() >= 2 && g_CurrentTrackSegment->Type() != PCB_VIA_T && g_CurrentTrackSegment->Back()->Type() == PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); } } while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() == PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() != PCB_VIA_T ) previous_layer = g_CurrentTrackSegment->GetLayer(); } // Correct active layer which could change if a via // has been erased SetActiveLayer( previous_layer ); UpdateStatusBar(); if( g_TwoSegmentTrackBuild ) // We must have 2 segments or more, or 0 { if( g_CurrentTrackList.GetCount() == 1 && g_CurrentTrackSegment->Type() != PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); } } if( g_CurrentTrackList.GetCount() == 0 ) { m_canvas->SetMouseCapture( NULL, NULL ); if( GetBoard()->IsHighLightNetON() ) HighLight( DC ); SetCurItem( NULL ); return NULL; } else { if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); return g_CurrentTrackSegment; } }
int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) { ZONE_SETTINGS zoneInfo = GetZoneSettings(); // verify if s_CurrentZone exists (could be deleted since last selection) : int ii; for( ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) { if( s_CurrentZone == GetBoard()->GetArea( ii ) ) break; } if( ii >= GetBoard()->GetAreaCount() ) // Not found: could be deleted since last selection { s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; } ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour; // Verify if a new zone is allowed on this layer: if( zone == NULL ) { if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT && !IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Error: a keepout area is allowed only on copper layers" ) ); return 0; } } // If no zone contour in progress, a new zone is being created, if( zone == NULL ) { zone = GetBoard()->m_CurrentZoneContour = new ZONE_CONTAINER( GetBoard() ); zone->SetFlags( IS_NEW ); zone->SetTimeStamp( GetNewTimeStamp() ); } if( zone->GetNumCorners() == 0 ) // Start a new contour: init zone params (net, layer ...) { if( !s_CurrentZone ) // A new outline is created, from scratch { ZONE_EDIT_T edited; // Init zone params to reasonable values zone->SetLayer( GetActiveLayer() ); // Prompt user for parameters: m_canvas->SetIgnoreMouseEvents( true ); if( zone->IsOnCopperLayer() ) { // Put a zone on a copper layer if( GetBoard()->GetHighLightNetCode() > 0 ) { zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode(); zone->SetNetCode( zoneInfo.m_NetcodeSelection ); } double tmp = ZONE_THERMAL_RELIEF_GAP_MIL; wxConfigBase* cfg = Kiface().KifaceSettings(); cfg->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp ); zoneInfo.m_ThermalReliefGap = KiROUND( tmp * IU_PER_MILS); tmp = ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL; cfg->Read( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ThermalReliefCopperBridge = KiROUND( tmp * IU_PER_MILS ); tmp = ZONE_CLEARANCE_MIL; cfg->Read( ZONE_CLEARANCE_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ZoneClearance = KiROUND( tmp * IU_PER_MILS ); tmp = ZONE_THICKNESS_MIL; cfg->Read( ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ZoneMinThickness = KiROUND( tmp * IU_PER_MILS ); zoneInfo.m_CurrentZone_Layer = zone->GetLayer(); if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT ) { zoneInfo.SetIsKeepout( true ); // Netcode, netname and some other settings are irrelevant, // so ensure they are cleared zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); zoneInfo.SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE ); zoneInfo.SetCornerRadius( 0 ); edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else { zoneInfo.SetIsKeepout( false ); edited = InvokeCopperZonesEditor( this, &zoneInfo ); } } else // Put a zone on a non copper layer (technical layer) { zoneInfo.SetIsKeepout( false ); zoneInfo.m_NetcodeSelection = 0; // No net for non copper zones edited = InvokeNonCopperZonesEditor( this, zone, &zoneInfo ); } m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); if( edited == ZONE_ABORT ) { GetBoard()->m_CurrentZoneContour = NULL; delete zone; return 0; } // Switch active layer to the selected zone layer SetActiveLayer( zoneInfo.m_CurrentZone_Layer ); SetZoneSettings( zoneInfo ); } else { // Start a new contour: init zone params (net and layer) from an existing // zone (add cutout or similar zone) zoneInfo.m_CurrentZone_Layer = s_CurrentZone->GetLayer(); SetActiveLayer( s_CurrentZone->GetLayer() ); zoneInfo << *s_CurrentZone; SetZoneSettings( zoneInfo ); } // Show the Net for zones on copper layers if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) && !zoneInfo.GetIsKeepout() ) { if( s_CurrentZone ) { zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNetCode(); GetBoard()->SetZoneSettings( zoneInfo ); } if( GetBoard()->IsHighLightNetON() ) { HighLight( DC ); // Remove old highlight selection } GetBoard()->SetHighLightNet( zoneInfo.m_NetcodeSelection ); HighLight( DC ); } if( !s_AddCutoutToCurrentZone ) s_CurrentZone = NULL; // the zone is used only once ("add similar zone" command) } // if first segment if( zone->GetNumCorners() == 0 ) { zoneInfo.ExportSetting( *zone ); zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, GetCrossHairPosition().x, GetCrossHairPosition().y, zone->GetHatchStyle() ); zone->AppendCorner( GetCrossHairPosition() ); if( g_Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() ) { zone->ClearFlags(); zone->RemoveAllContours(); // use the form of SetCurItem() which does not write to the msg panel, // SCREEN::SetCurItem(), so the DRC error remains on screen. // PCB_EDIT_FRAME::SetCurItem() calls DisplayInfo(). GetScreen()->SetCurItem( NULL ); DisplayError( this, _( "DRC error: this start point is inside or too close an other area" ) ); return 0; } SetCurItem( zone ); m_canvas->SetMouseCapture( Show_New_Edge_While_Move_Mouse, Abort_Zone_Create_Outline ); } else // edge in progress: { ii = zone->GetNumCorners() - 1; // edge in progress : the current corner coordinate was set // by Show_New_Edge_While_Move_Mouse if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) ) { if( !g_Drc_On || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) ) { // Ok, we can add a new corner if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxPoint(0,0), false ); zone->AppendCorner( GetCrossHairPosition() ); SetCurItem( zone ); // calls DisplayInfo(). if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxPoint(0,0), false ); } } } return zone->GetNumCorners(); }