bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName ) { FILE* cmpFile; cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) ); if( cmpFile == NULL ) return false; fprintf( cmpFile, "Cmp-Mod V01 Created by PcbNew date = %s\n", TO_UTF8( DateAndTime() ) ); MODULE* module = aBrd->m_Modules; for( ; module != NULL; module = module->Next() ) { fprintf( cmpFile, "\nBeginCmp\n" ); fprintf( cmpFile, "TimeStamp = %8.8lX\n", (unsigned long)module->GetTimeStamp() ); fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) ); fprintf( cmpFile, "Reference = %s;\n", !module->GetReference().IsEmpty() ? TO_UTF8( module->GetReference() ) : "[NoRef]" ); fprintf( cmpFile, "ValeurCmp = %s;\n", !module->GetValue().IsEmpty() ? TO_UTF8( module->GetValue() ) : "[NoVal]" ); fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() ); fprintf( cmpFile, "EndCmp\n" ); } fprintf( cmpFile, "\nEndListe\n" ); fclose( cmpFile ); return true; }
void DIALOG_EXCHANGE_MODULE::init() { SetFocus(); m_CurrentFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); m_NewFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); m_CmpValue->AppendText( m_currentModule->GetValue() ); m_CmpReference->AppendText( m_currentModule->GetReference() ); m_Selection->SetString( 0, wxString::Format( _( "Change footprint of '%s'" ), GetChars( m_currentModule->GetReference() ) ) ); wxString fpname = m_CurrentFootprintFPID->GetValue().AfterLast( ':' ); if( fpname.IsEmpty() ) // Happens for old fp names fpname = m_CurrentFootprintFPID->GetValue(); m_Selection->SetString( 1, wxString::Format( _( "Change footprints '%s'" ), GetChars( fpname.Left( 12 ) ) ) ); m_Selection->SetSelection( m_selectionMode ); // Enable/disable widgets: wxCommandEvent event; OnSelectionClicked( event ); }
/** * Send a remote command to Eeschema via a socket, * @param objectToSync = item to be located on schematic (module, pin or text) * Commands are * $PART: "reference" put cursor on component anchor * $PART: "reference" $PAD: "pad number" put cursor on the component pin * $PART: "reference" $REF: "reference" put cursor on the component ref * $PART: "reference" $VAL: "value" put cursor on the component value */ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) { char cmd[1024]; const char* text_key; MODULE* module = NULL; D_PAD* pad; TEXTE_MODULE* text_mod; wxString msg; if( objectToSync == NULL ) return; switch( objectToSync->Type() ) { case PCB_MODULE_T: module = (MODULE*) objectToSync; sprintf( cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); break; case PCB_PAD_T: module = (MODULE*) objectToSync->GetParent(); pad = (D_PAD*) objectToSync; msg = pad->GetPadName(); sprintf( cmd, "$PART: \"%s\" $PAD: \"%s\"", TO_UTF8( module->GetReference() ), TO_UTF8( msg ) ); break; case PCB_MODULE_TEXT_T: module = (MODULE*) objectToSync->GetParent(); text_mod = (TEXTE_MODULE*) objectToSync; if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) text_key = "$REF:"; else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) text_key = "$VAL:"; else break; sprintf( cmd, "$PART: \"%s\" %s \"%s\"", TO_UTF8( module->GetReference() ), text_key, TO_UTF8( text_mod->GetText() ) ); break; default: break; } if( module ) { SendCommand( MSG_TO_SCH, cmd ); } }
MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprint( BOARD* aPcb ) { static wxString oldName; // Save name of last module selected. wxString fpname; wxString msg; wxArrayString listnames; MODULE* module = aPcb->m_Modules; for( ; module; module = module->Next() ) listnames.Add( module->GetReference() ); msg.Printf( _( "Modules [%d items]" ), listnames.GetCount() ); wxArrayString headers; headers.Add( _( "Module" ) ); std::vector<wxArrayString> itemsToDisplay; // Conversion from wxArrayString to vector of ArrayString for( unsigned i = 0; i < listnames.GetCount(); i++ ) { wxArrayString item; item.Add( listnames[i] ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString, NULL, SORT_LIST ); if( dlg.ShowModal() == wxID_OK ) fpname = dlg.GetTextSelection(); else return NULL; oldName = fpname; module = aPcb->m_Modules; for( ; module; module = module->Next() ) { if( fpname == module->GetReference() ) break; } return module; }
/* * Creates a footprint position file * aSide = 0 -> Back (bottom) side) * aSide = 1 -> Front (top) side) * aSide = 2 -> both sides * if aFullFileName is empty, the file is not created, only the * count of footprints to place is returned */ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aForceSmdItems, int aSide ) { MODULE* module; char line[1024]; File_Place_Offset = GetAuxOrigin(); // Calculating the number of useful modules (CMS attribute, not VIRTUAL) int moduleCount = 0; for( module = GetBoard()->m_Modules; module; module = module->Next() ) { if( aSide < 2 ) { if( module->GetLayer() == B_Cu && aSide == 1) continue; if( module->GetLayer() == F_Cu && aSide == 0) continue; } if( module->GetAttributes() & MOD_VIRTUAL ) { DBG( printf( "skipping module %s because it's virtual\n", TO_UTF8( module->GetReference() ) );) continue; }
void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery ) { if( aPad == NULL ) return; MODULE* module = aPad->GetParent(); module->SetLastEditTime(); // aQuery = true to prompt for confirmation, false to delete silently if( aQuery ) { wxString msg = wxString::Format( _( "Delete pad (footprint %s %s)?" ), module->GetReference(), module->GetValue() ); if( !IsOK( this, msg ) ) return; } // Stores the initial bounding box to refresh the old area EDA_RECT bbox = module->GetBoundingBox(); m_Pcb->m_Status_Pcb = 0; GetBoard()->PadDelete( aPad ); // Update the bounding box module->CalculateBoundingBox(); // Refresh the modified screen area, using the initial bounding box // which is perhaps larger than the new bounding box m_canvas->RefreshDrawingRect( bbox ); OnModify(); }
void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery ) { if( aPad == NULL ) return; MODULE* module = (MODULE*) aPad->GetParent(); module->SetLastEditTime(); // aQuery = true to prompt for confirmation, false to delete silently if( aQuery ) { wxString msg; msg.Printf( _( "Delete Pad (footprint %s %s) ?" ), GetChars( module->GetReference() ), GetChars( module->GetValue() ) ); if( !IsOK( this, msg ) ) return; } m_Pcb->m_Status_Pcb = 0; aPad->DeleteStructure(); // Refresh the modified screen area, using the initial bounding box // which is perhaps larger than the new bounding box m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); // Update the bounding box module->CalculateBoundingBox(); OnModify(); }
/* Creates the section $DEVICES * This is a list of footprints properties * ( Shapes are in section $SHAPE ) */ static void CreateDevicesSection( FILE* aFile, BOARD* aPcb ) { MODULE* module; fputs( "$DEVICES\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) ); fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) ); fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() ); // The TYPE attribute is almost freeform const char* ty = "TH"; if( module->GetAttributes() & MOD_CMS ) ty = "SMD"; if( module->GetAttributes() & MOD_VIRTUAL ) ty = "VIRTUAL"; fprintf( aFile, "TYPE %s\n", ty ); } fputs( "$ENDDEVICES\n\n", aFile ); }
// see class_edge_mod.h void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; MODULE* module = (MODULE*) m_Parent; if( !module ) return; BOARD* board = (BOARD*) module->GetParent(); if( !board ) return; aList.push_back( MSG_PANEL_ITEM( _( "Graphic Item" ), wxEmptyString, DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Module" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) ); msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() ); aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Mod Layer" ), module->GetLayerName(), RED ) ); aList.push_back( MSG_PANEL_ITEM( _( "Seg Layer" ), GetLayerName(), RED ) ); msg = ::CoordinateToString( m_Width ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, BLUE ) ); }
MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName() { if( GetBoard()->m_Modules == NULL ) { DisplayError( this, _( "No footprints" ) ); return 0; } wxArrayString listnames; MODULE* module; for( module = GetBoard()->m_Modules; module; module = module->Next() ) listnames.Add( module->GetReference() ); wxArrayString headers; headers.Add( wxT( "Module" ) ); std::vector<wxArrayString> itemsToDisplay; // Conversion from wxArrayString to vector of ArrayString for( unsigned i = 0; i < listnames.GetCount(); i++ ) { wxArrayString item; item.Add( listnames[i] ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, _( "Components" ), headers, itemsToDisplay, wxEmptyString ); if( dlg.ShowModal() != wxID_OK ) return NULL; wxString ref = dlg.GetTextSelection(); for( module = GetBoard()->m_Modules; module; module = module->Next() ) { if( module->GetReference() == ref ) break; } return module; }
bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist ) { wxString msg; MODULE* nextModule; const COMPONENT* component; for( MODULE* module = m_board->m_Modules; module != NULL; module = nextModule ) { nextModule = module->Next(); if( m_lookupByTimestamp ) component = aNetlist.GetComponentByTimeStamp( module->GetPath() ); else component = aNetlist.GetComponentByReference( module->GetReference() ); if( component == NULL ) { if( module->IsLocked() ) { msg.Printf( _( "Component %s is locked, skipping removal.\n" ), GetChars( module->GetReference() ) ); m_reporter->Report( msg, REPORTER::RPT_INFO ); continue; } msg.Printf( _( "Remove component %s." ), GetChars( module->GetReference() ) ); m_reporter->Report( msg, REPORTER::RPT_ACTION ); msg.Printf( _( "Removing unused component \"%s:%s\".\n" ), GetChars( module->GetReference() ), GetChars( module->GetPath() ) ); m_reporter->Report( msg, REPORTER::RPT_INFO ); if( !m_isDryRun ) m_commit.Remove( module ); } } return true; }
// see class_text_mod.h void TEXTE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { MODULE* module = (MODULE*) m_Parent; if( module == NULL ) // Happens in modedit, and for new texts return; wxString msg, Line; static const wxString text_type_msg[3] = { _( "Ref." ), _( "Value" ), _( "Text" ) }; Line = module->GetReference(); aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), Line, DARKCYAN ) ); Line = GetShownText(); aList.push_back( MSG_PANEL_ITEM( _( "Text" ), Line, BROWN ) ); wxASSERT( m_Type >= TEXT_is_REFERENCE && m_Type <= TEXT_is_DIVERS ); aList.push_back( MSG_PANEL_ITEM( _( "Type" ), text_type_msg[m_Type], DARKGREEN ) ); if( !IsVisible() ) msg = _( "No" ); else msg = _( "Yes" ); aList.push_back( MSG_PANEL_ITEM( _( "Display" ), msg, DARKGREEN ) ); // Display text layer aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), DARKGREEN ) ); if( IsMirrored() ) msg = _( "Yes" ); else msg = _( "No" ); aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), msg, DARKGREEN ) ); msg.Printf( wxT( "%.1f" ), GetTextAngleDegrees() ); aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) ); msg = ::CoordinateToString( GetThickness() ); aList.push_back( MSG_PANEL_ITEM( _( "Thickness" ), msg, DARKGREEN ) ); msg = ::CoordinateToString( GetTextWidth() ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, RED ) ); msg = ::CoordinateToString( GetTextHeight() ); aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, RED ) ); }
// see class_text_mod.h void TEXTE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { MODULE* module = (MODULE*) m_Parent; if( module == NULL ) // Happens in modedit, and for new texts return; wxString msg, Line; static const wxString text_type_msg[3] = { _( "Ref." ), _( "Value" ), _( "Text" ) }; Line = module->GetReference(); aList.push_back( MSG_PANEL_ITEM( _( "Module" ), Line, DARKCYAN ) ); Line = m_Text; aList.push_back( MSG_PANEL_ITEM( _( "Text" ), Line, BROWN ) ); wxASSERT( m_Type >= TEXT_is_REFERENCE && m_Type <= TEXT_is_DIVERS ); aList.push_back( MSG_PANEL_ITEM( _( "Type" ), text_type_msg[m_Type], DARKGREEN ) ); if( m_NoShow ) msg = _( "No" ); else msg = _( "Yes" ); aList.push_back( MSG_PANEL_ITEM( _( "Display" ), msg, DARKGREEN ) ); // Display text layer aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), DARKGREEN ) ); if( m_Mirror ) msg = _( " Yes" ); else msg = _( " No" ); aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), msg, DARKGREEN ) ); msg.Printf( wxT( "%.1f" ), m_Orient / 10.0 ); aList.push_back( MSG_PANEL_ITEM( _( "Orient" ), msg, DARKGREEN ) ); msg = ::CoordinateToString( m_Thickness ); aList.push_back( MSG_PANEL_ITEM( _( "Thickness" ), msg, DARKGREEN ) ); msg = ::CoordinateToString( m_Size.x ); aList.push_back( MSG_PANEL_ITEM( _( "H Size" ), msg, RED ) ); msg = ::CoordinateToString( m_Size.y ); aList.push_back( MSG_PANEL_ITEM( _( "V Size" ), msg, RED ) ); }
/* Extract the D356 record from the modules (pads) */ static void build_pad_testpoints( BOARD *aPcb, std::vector <D356_RECORD>& aRecords ) { wxPoint origin = aPcb->GetAuxOrigin(); for( MODULE *module = aPcb->m_Modules; module; module = module->Next() ) { for( D_PAD *pad = module->Pads(); pad; pad = pad->Next() ) { D356_RECORD rk; rk.access = compute_pad_access_code( aPcb, pad->GetLayerSet() ); // It could be a mask only pad, we only handle pads with copper here if( rk.access != -1 ) { rk.netname = pad->GetNetname(); rk.refdes = module->GetReference(); pad->StringPadName( rk.pin ); rk.midpoint = false; // XXX MAYBE need to be computed (how?) const wxSize& drill = pad->GetDrillSize(); rk.drill = std::min( drill.x, drill.y ); rk.hole = (rk.drill != 0); rk.smd = pad->GetAttribute() == PAD_ATTRIB_SMD; rk.mechanical = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED); rk.x_location = pad->GetPosition().x - origin.x; rk.y_location = origin.y - pad->GetPosition().y; rk.x_size = pad->GetSize().x; // Rule: round pads have y = 0 if( pad->GetShape() == PAD_SHAPE_CIRCLE ) rk.y_size = 0; else rk.y_size = pad->GetSize().y; rk.rotation = -KiROUND( pad->GetOrientation() ) / 10; if( rk.rotation < 0 ) rk.rotation += 360; // the value indicates which sides are *not* accessible rk.soldermask = 3; if( pad->GetLayerSet()[F_Mask] ) rk.soldermask &= ~1; if( pad->GetLayerSet()[B_Mask] ) rk.soldermask &= ~2; aRecords.push_back( rk ); } } } }
/* Emit the netlist (which is actually the thing for which GenCAD is used these * days!); tracks are handled later */ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) { wxString msg; NETINFO_ITEM* net; D_PAD* pad; MODULE* module; int NbNoConn = 1; fputs( "$SIGNALS\n", aFile ); for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ ) { net = aPcb->FindNet( ii ); if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) { wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; } if( net->GetNet() <= 0 ) // dummy netlist (no connection) continue; msg = wxT( "SIGNAL " ) + net->GetNetname(); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { for( pad = module->Pads(); pad; pad = pad->Next() ) { wxString padname; if( pad->GetNetCode() != net->GetNet() ) continue; pad->StringPadName( padname ); msg.Printf( wxT( "NODE %s %s" ), GetChars( module->GetReference() ), GetChars( padname ) ); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); } } } fputs( "$ENDSIGNALS\n\n", aFile ); }
/* * Creates a footprint position file * aSide = 0 -> Back (bottom) side) * aSide = 1 -> Front (top) side) * aSide = 2 -> both sides * if aFullFileName is empty, the file is not created, only the * count of footprints to place is returned */ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aForceSmdItems, int aSide, bool aFormatCSV ) { MODULE* footprint; // Minimal text lengths: int lenRefText = 8; int lenValText = 8; int lenPkgText = 16; File_Place_Offset = GetAuxOrigin(); // Calculating the number of useful footprints (CMS attribute, not VIRTUAL) int footprintCount = 0; // Select units: double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch; const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch; // Build and sort the list of footprints alphabetically std::vector<LIST_MOD> list; list.reserve( footprintCount ); for( footprint = GetBoard()->m_Modules; footprint; footprint = footprint->Next() ) { if( aSide != PCB_BOTH_SIDES ) { if( footprint->GetLayer() == B_Cu && aSide == PCB_FRONT_SIDE) continue; if( footprint->GetLayer() == F_Cu && aSide == PCB_BACK_SIDE) continue; } if( footprint->GetAttributes() & MOD_VIRTUAL ) { DBG( printf( "skipping footprint %s because it's virtual\n", TO_UTF8( footprint->GetReference() ) );) continue; }
// see class_edge_mod.h void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; MODULE* module = (MODULE*) m_Parent; if( !module ) return; BOARD* board = (BOARD*) module->GetParent(); if( !board ) return; aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) ); msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() ); aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ), module->GetLayerName(), RED ) ); // append the features shared with the base class DRAWSEGMENT::GetMsgPanelInfo( aList ); }
void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList ) { MODULE* module; wxString Line; BOARD* board; module = (MODULE*) m_Parent; if( module ) { wxString msg = module->GetReference(); aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKCYAN ) ); StringPadName( Line ); aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) ); } aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) ); /* For test and debug only: display m_physical_connexion and * m_logical_connexion */ #if 1 // Used only to debug connectivity calculations Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), GetZoneSubNet() ); aList.push_back( MSG_PANEL_ITEM( wxT( "L-P-Z" ), Line, DARKGREEN ) ); #endif board = GetBoard(); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) ); aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) ); Line = ::CoordinateToString( m_Size.x ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), Line, RED ) ); Line = ::CoordinateToString( m_Size.y ); aList.push_back( MSG_PANEL_ITEM( _( "Height" ), Line, RED ) ); Line = ::CoordinateToString( (unsigned) m_Drill.x ); if( GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE ) { aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), Line, RED ) ); } else { Line = ::CoordinateToString( (unsigned) m_Drill.x ); wxString msg; msg = ::CoordinateToString( (unsigned) m_Drill.y ); Line += wxT( "/" ) + msg; aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), Line, RED ) ); } double module_orient = module ? module->GetOrientation() : 0; if( module_orient ) Line.Printf( wxT( "%3.1f(+%3.1f)" ), ( m_Orient - module_orient ) / 10.0, module_orient / 10.0 ); else Line.Printf( wxT( "%3.1f" ), m_Orient / 10.0 ); aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), Line, LIGHTBLUE ) ); Line = ::CoordinateToString( m_Pos.x ) + wxT( ", " ) + ::CoordinateToString( m_Pos.y ); aList.push_back( MSG_PANEL_ITEM( _( "Position" ), Line, LIGHTBLUE ) ); if( GetPadToDieLength() ) { Line = ::CoordinateToString( GetPadToDieLength() ); aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), Line, CYAN ) ); } }
void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList ) { MODULE* module; wxString Line; BOARD* board; module = (MODULE*) m_Parent; if( module ) { aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), m_name, BROWN ) ); } aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) ); board = GetBoard(); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) ); aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) ); Line = ::CoordinateToString( m_Size.x ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), Line, RED ) ); Line = ::CoordinateToString( m_Size.y ); aList.push_back( MSG_PANEL_ITEM( _( "Height" ), Line, RED ) ); Line = ::CoordinateToString( (unsigned) m_Drill.x ); if( GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE ) { aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), Line, RED ) ); } else { Line = ::CoordinateToString( (unsigned) m_Drill.x ); wxString msg; msg = ::CoordinateToString( (unsigned) m_Drill.y ); Line += wxT( "/" ) + msg; aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), Line, RED ) ); } double module_orient_degrees = module ? module->GetOrientationDegrees() : 0; if( module_orient_degrees != 0.0 ) Line.Printf( wxT( "%3.1f(+%3.1f)" ), GetOrientationDegrees() - module_orient_degrees, module_orient_degrees ); else Line.Printf( wxT( "%3.1f" ), GetOrientationDegrees() ); aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), Line, LIGHTBLUE ) ); Line = ::CoordinateToString( m_Pos.x ) + wxT( ", " ) + ::CoordinateToString( m_Pos.y ); aList.push_back( MSG_PANEL_ITEM( _( "Position" ), Line, LIGHTBLUE ) ); if( GetPadToDieLength() ) { Line = ::CoordinateToString( GetPadToDieLength() ); aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), Line, CYAN ) ); } }
void D_PAD::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM>& aList ) { MODULE* module; wxString msg; BOARD* board; module = (MODULE*) m_Parent; if( module ) { aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), m_name, BROWN ) ); } aList.push_back( MSG_PANEL_ITEM( _( "Net" ), UnescapeString( GetNetname() ), DARKCYAN ) ); board = GetBoard(); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) ); aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) ); msg = MessageTextFromValue( aUnits, m_Size.x, true ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, RED ) ); msg = MessageTextFromValue( aUnits, m_Size.y, true ); aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, RED ) ); msg = MessageTextFromValue( aUnits, m_Drill.x, true ); if( GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE ) { aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), msg, RED ) ); } else { msg = MessageTextFromValue( aUnits, m_Drill.x, true ) + wxT( "/" ) + MessageTextFromValue( aUnits, m_Drill.y, true ); aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), msg, RED ) ); } double module_orient_degrees = module ? module->GetOrientationDegrees() : 0; if( module_orient_degrees != 0.0 ) msg.Printf( wxT( "%3.1f(+%3.1f)" ), GetOrientationDegrees() - module_orient_degrees, module_orient_degrees ); else msg.Printf( wxT( "%3.1f" ), GetOrientationDegrees() ); aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, LIGHTBLUE ) ); msg = MessageTextFromValue( aUnits, m_Pos.x ) + wxT( ", " ) + MessageTextFromValue( aUnits, m_Pos.y ); aList.push_back( MSG_PANEL_ITEM( _( "Position" ), msg, LIGHTBLUE ) ); if( GetPadToDieLength() ) { msg = MessageTextFromValue( aUnits, GetPadToDieLength(), true ); aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), msg, CYAN ) ); } }
void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event ) { if( m_parent->GetBoard()->m_Modules == NULL ) { DisplayInfoMessage( this, _( "No footprints" ) ); return; } // Lists of duplicates, missing references and not in netlist footprints: std::vector <MODULE*> duplicate; wxArrayString missing; std::vector <MODULE*> notInNetlist; wxString netlistFilename = m_NetlistFilenameCtrl->GetValue(); if( !verifyFootprints( netlistFilename, wxEmptyString, duplicate, missing, notInNetlist ) ) return; #define ERR_CNT_MAX 100 // Max number of errors to output in dialog // to avoid a too long message list wxString list; // The messages to display m_parent->SetLastNetListRead( netlistFilename ); int err_cnt = 0; // Search for duplicate footprints. if( duplicate.size() == 0 ) list << wxT("<p><b>") << _( "No duplicate." ) << wxT("</b></p>"); else { list << wxT("<p><b>") << _( "Duplicates:" ) << wxT("</b></p>"); for( unsigned ii = 0; ii < duplicate.size(); ii++ ) { MODULE* module = duplicate[ii]; if( module->GetReference().IsEmpty() ) list << wxT("<br>") << wxT("[noref)"); else list << wxT("<br>") << module->GetReference(); list << wxT(" (<i>") << module->GetValue() << wxT("</i>)"); list << wxT(" @ "); list << CoordinateToString( module->GetPosition().x ), list << wxT(", ") << CoordinateToString( module->GetPosition().y ), err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } // Search for missing modules on board. if( missing.size() == 0 ) list << wxT("<p><b>") << _( "No missing footprints." ) << wxT("</b></p>"); else { list << wxT("<p><b>") << _( "Missing:" ) << wxT("</b></p>"); for( unsigned ii = 0; ii < missing.size(); ii += 2 ) { list << wxT("<br>") << missing[ii]; list << wxT(" (<i>") << missing[ii+1] << wxT("</i>)"); err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } // Search for modules found on board but not in net list. if( notInNetlist.size() == 0 ) list << wxT( "<p><b>" ) << _( "No extra footprints." ) << wxT( "</b></p>" ); else { list << wxT( "<p><b>" ) << _( "Not in Netlist:" ) << wxT( "</b></p>" ); for( unsigned ii = 0; ii < notInNetlist.size(); ii++ ) { MODULE* module = notInNetlist[ii]; if( module->GetReference().IsEmpty() ) list << wxT( "<br>" ) << wxT( "[noref)" ); else list << wxT( "<br>" ) << module->GetReference() ; list << wxT( " (<i>" ) << module->GetValue() << wxT( "</i>)" ); list << wxT( " @ " ); list << CoordinateToString( module->GetPosition().x ), list << wxT( ", " ) << CoordinateToString( module->GetPosition().y ), err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } if( ERR_CNT_MAX < err_cnt ) { list << wxT( "<p><b>" ) << _( "Too many errors: some are skipped" ) << wxT( "</b></p>" ); } HTML_MESSAGE_BOX dlg( this, _( "Check footprints" ) ); dlg.AddHTML_Text( list ); dlg.ShowModal(); }
bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename, const wxString & aCmpFilename, std::vector< MODULE* >& aDuplicates, wxArrayString& aMissing, std::vector< MODULE* >& aNotInNetlist ) { wxString msg; MODULE* module; MODULE* nextModule; NETLIST netlist; wxBusyCursor dummy; // Shows an hourglass while calculating. NETLIST_READER* netlistReader; COMPONENT* component; try { netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename, aCmpFilename ); if( netlistReader == NULL ) { msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) ); wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR ); return false; } std::auto_ptr< NETLIST_READER > nlr( netlistReader ); netlistReader->LoadNetlist(); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); return false; } BOARD* pcb = m_parent->GetBoard(); // Search for duplicate footprints. module = pcb->m_Modules; for( ; module != NULL; module = module->Next() ) { nextModule = module->Next(); for( ; nextModule != NULL; nextModule = nextModule->Next() ) { if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 ) { aDuplicates.push_back( module ); break; } } } // Search for component footprints in the netlist but not on the board. for( unsigned ii = 0; ii < netlist.GetCount(); ii++ ) { component = netlist.GetComponent( ii ); module = pcb->FindModuleByReference( component->GetReference() ); if( module == NULL ) { aMissing.Add( component->GetReference() ); aMissing.Add( component->GetValue() ); } } // Search for component footprints found on board but not in netlist. module = pcb->m_Modules; for( ; module != NULL; module = module->Next() ) { component = netlist.GetComponentByReference( module->GetReference() ); if( component == NULL ) aNotInNetlist.push_back( module ); } return true; }
void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList ) { MODULE* module; wxString Line; BOARD* board; module = (MODULE*) m_Parent; if( module ) { wxString msg = module->GetReference(); aList.push_back( MSG_PANEL_ITEM( _( "Module" ), msg, DARKCYAN ) ); ReturnStringPadName( Line ); aList.push_back( MSG_PANEL_ITEM( _( "RefP" ), Line, BROWN ) ); } aList.push_back( MSG_PANEL_ITEM( _( "Net" ), m_Netname, DARKCYAN ) ); /* For test and debug only: display m_physical_connexion and * m_logical_connexion */ #if 1 // Used only to debug connectivity calculations Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), GetZoneSubNet() ); aList.push_back( MSG_PANEL_ITEM( wxT( "L-P-Z" ), Line, DARKGREEN ) ); #endif board = GetBoard(); wxString layerInfo; if( (m_layerMask & ALL_CU_LAYERS) == 0 ) // pad is not on any copper layers { switch( m_layerMask & ~ALL_CU_LAYERS ) { case ADHESIVE_LAYER_BACK: layerInfo = board->GetLayerName( ADHESIVE_N_BACK ); break; case ADHESIVE_LAYER_FRONT: layerInfo = board->GetLayerName( ADHESIVE_N_FRONT ); break; case SOLDERPASTE_LAYER_BACK: layerInfo = board->GetLayerName( SOLDERPASTE_N_BACK ); break; case SOLDERPASTE_LAYER_FRONT: layerInfo = board->GetLayerName( SOLDERPASTE_N_FRONT ); break; case SILKSCREEN_LAYER_BACK: layerInfo = board->GetLayerName( SILKSCREEN_N_BACK ); break; case SILKSCREEN_LAYER_FRONT: layerInfo = board->GetLayerName( SILKSCREEN_N_FRONT ); break; case SOLDERMASK_LAYER_BACK: layerInfo = board->GetLayerName( SOLDERMASK_N_BACK ); break; case SOLDERMASK_LAYER_FRONT: layerInfo = board->GetLayerName( SOLDERMASK_N_FRONT ); break; case DRAW_LAYER: layerInfo = board->GetLayerName( DRAW_N ); break; case COMMENT_LAYER: layerInfo = board->GetLayerName( COMMENT_N ); break; case ECO1_LAYER: layerInfo = board->GetLayerName( ECO1_N ); break; case ECO2_LAYER: layerInfo = board->GetLayerName( ECO2_N ); break; case EDGE_LAYER: layerInfo = board->GetLayerName( EDGE_N ); break; default: layerInfo = _( "Non-copper" ); break; } } else { #define INTERIOR_COPPER (ALL_CU_LAYERS & ~(LAYER_BACK | LAYER_FRONT)) static const wxChar* andInternal = _( " & int" ); if( (m_layerMask & (LAYER_BACK | LAYER_FRONT)) == LAYER_BACK ) { layerInfo = board->GetLayerName( LAYER_N_BACK ); if( m_layerMask & INTERIOR_COPPER ) layerInfo += andInternal; } else if( (m_layerMask & (LAYER_BACK | LAYER_FRONT)) == (LAYER_BACK | LAYER_FRONT) ) { layerInfo = board->GetLayerName( LAYER_N_BACK ) + wxT(", ") + board->GetLayerName( LAYER_N_FRONT ); if( m_layerMask & INTERIOR_COPPER ) layerInfo += andInternal; } else if( (m_layerMask & (LAYER_BACK | LAYER_FRONT)) == LAYER_FRONT ) { layerInfo = board->GetLayerName( LAYER_N_FRONT ); if( m_layerMask & INTERIOR_COPPER ) layerInfo += andInternal; } else // necessarily true: if( m_layerMask & INTERIOR_COPPER ) { layerInfo = _( "internal" ); } } aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), layerInfo, DARKGREEN ) ); aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) ); Line = ::CoordinateToString( m_Size.x ); aList.push_back( MSG_PANEL_ITEM( _( "H Size" ), Line, RED ) ); Line = ::CoordinateToString( m_Size.y ); aList.push_back( MSG_PANEL_ITEM( _( "V Size" ), Line, RED ) ); Line = ::CoordinateToString( (unsigned) m_Drill.x ); if( m_DrillShape == PAD_CIRCLE ) { aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), Line, RED ) ); } else { Line = ::CoordinateToString( (unsigned) m_Drill.x ); wxString msg; msg = ::CoordinateToString( (unsigned) m_Drill.y ); Line += wxT( "/" ) + msg; aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), Line, RED ) ); } int module_orient = module ? module->GetOrientation() : 0; if( module_orient ) Line.Printf( wxT( "%3.1f(+%3.1f)" ), (double) ( m_Orient - module_orient ) / 10, (double) module_orient / 10 ); else Line.Printf( wxT( "%3.1f" ), (double) m_Orient / 10 ); aList.push_back( MSG_PANEL_ITEM( _( "Orient" ), Line, LIGHTBLUE ) ); Line = ::CoordinateToString( m_Pos.x ); aList.push_back( MSG_PANEL_ITEM( _( "X Pos" ), Line, LIGHTBLUE ) ); Line = ::CoordinateToString( m_Pos.y ); aList.push_back( MSG_PANEL_ITEM( _( "Y pos" ), Line, LIGHTBLUE ) ); if( GetPadToDieLength() ) { Line = ::CoordinateToString( GetPadToDieLength() ); aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), Line, CYAN ) ); } }
/* Creates the section $COMPONENTS (Footprints placement) * Bottom side components are difficult to handle: shapes must be mirrored or * flipped, silk layers need to be handled correctly and so on. Also it seems * that *noone* follows the specs... */ static void CreateComponentsSection( FILE* aFile, BOARD* aPcb ) { fputs( "$COMPONENTS\n", aFile ); int cu_count = aPcb->GetCopperLayerCount(); for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { const char* mirror; const char* flip; double fp_orient = module->GetOrientation(); if( module->GetFlag() ) { mirror = "0"; flip = "FLIP"; NEGATE_AND_NORMALIZE_ANGLE_POS( fp_orient ); } else { mirror = "0"; flip = "0"; } fprintf( aFile, "\nCOMPONENT %s\n", TO_UTF8( module->GetReference() ) ); fprintf( aFile, "DEVICE %s_%s\n", TO_UTF8( module->GetReference() ), TO_UTF8( module->GetValue() ) ); fprintf( aFile, "PLACE %g %g\n", MapXTo( module->GetPosition().x ), MapYTo( module->GetPosition().y ) ); fprintf( aFile, "LAYER %s\n", (module->GetFlag()) ? "BOTTOM" : "TOP" ); fprintf( aFile, "ROTATION %g\n", fp_orient / 10.0 ); fprintf( aFile, "SHAPE %s %s %s\n", TO_UTF8( module->GetReference() ), mirror, flip ); // Text on silk layer: RefDes and value (are they actually useful?) TEXTE_MODULE *textmod = &module->Reference(); for( int ii = 0; ii < 2; ii++ ) { double txt_orient = textmod->GetOrientation(); std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS ); fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"", textmod->GetPos0().x / SCALE_FACTOR, -textmod->GetPos0().y / SCALE_FACTOR, textmod->GetSize().x / SCALE_FACTOR, txt_orient / 10.0, mirror, layer.c_str(), TO_UTF8( textmod->GetText() ) ); // Please note, the width is approx fprintf( aFile, " 0 0 %g %g\n", ( textmod->GetSize().x * textmod->GetLength() ) / SCALE_FACTOR, textmod->GetSize().y / SCALE_FACTOR ); textmod = &module->Value(); // Dirty trick for the second iteration } // The SHEET is a 'generic description' for referencing the component fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n", TO_UTF8( module->GetReference() ), TO_UTF8( module->GetValue() ) ); } fputs( "$ENDCOMPONENTS\n\n", aFile ); }
void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) { wxFileName fn; FILE* fp_bom; MODULE* module = GetBoard()->m_Modules; wxString msg; if( module == NULL ) { DisplayError( this, _( "Cannot export BOM: there are no footprints in the PCB" ) ); return; } /* Set the file extension: */ fn = GetBoard()->GetFileName(); fn.SetExt( CsvFileExtension ); wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); wxFileDialog dlg( this, _( "Save Bill of Materials" ), pro_dir, fn.GetFullName(), CsvFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) return; fn = dlg.GetPath(); fp_bom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); if( fp_bom == NULL ) { msg.Printf( _( "Unable to create file \"%s\"" ), GetChars( fn.GetFullPath() ) ); DisplayError( this, msg ); return; } // Write header: msg = wxT( "\"" ); msg << _( "Id" ) << wxT( "\";\"" ); msg << _( "Designator" ) << wxT( "\";\"" ); msg << _( "Package" ) << wxT( "\";\"" ); msg << _( "Quantity" ) << wxT( "\";\"" ); msg << _( "Designation" ) << wxT( "\";\"" ); msg << _( "Supplier and ref" ) << wxT( "\";\n" ); fprintf( fp_bom, "%s", TO_UTF8( msg ) ); // Build list CmpList list; cmp* comp = NULL; CmpList::iterator iter; int i = 1; while( module != NULL ) { bool valExist = false; // try to find component in existing list for( iter = list.begin(); iter != list.end(); ++iter ) { cmp* current = *iter; if( (current->m_Val == module->GetValue()) && (current->m_fpid == module->GetFPID()) ) { current->m_Ref.Append( wxT( ", " ), 1 ); current->m_Ref.Append( module->GetReference() ); current->m_CmpCount++; valExist = true; break; } } // If component does not exist yet, create new one and append it to the list. if( valExist == false ) { comp = new cmp(); comp->m_Id = i++; comp->m_Val = module->GetValue(); comp->m_Ref = module->GetReference(); comp->m_fpid = module->GetFPID(); comp->m_CmpCount = 1; list.Append( comp ); } // increment module module = module->Next(); } // Print list. Also delete temporary created objects. for( size_t ii = list.GetCount(); ii > 0; ii-- ) { cmp* current = *list.begin(); // Because the first object will be removed // from list, all objects will be get here msg.Empty(); msg << current->m_Id << wxT( ";\"" ); msg << current->m_Ref << wxT( "\";\"" ); msg << FROM_UTF8( current->m_fpid.GetLibItemName().c_str() ) << wxT( "\";" ); msg << current->m_CmpCount << wxT( ";\"" ); msg << current->m_Val << wxT( "\";;;\n" ); fprintf( fp_bom, "%s", TO_UTF8( msg ) ); // We do not need this object, now: remove it from list and delete it list.DeleteObject( current ); delete (current); } fclose( fp_bom ); }
/** * Function Inspect * is the examining function within the INSPECTOR which is passed to the * Iterate function. Searches and collects all the objects that the old * function PcbGeneralLocateAndDisplay() would find, except that it keeps all * that it finds and does not do any displaying. * * @param testItem An EDA_ITEM to examine. * @param testData The const void* testData, not used here. * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, * else SCAN_CONTINUE; */ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData ) { BOARD_ITEM* item = (BOARD_ITEM*) testItem; MODULE* module = NULL; D_PAD* pad = NULL; bool pad_through = false; SEGVIA* via = NULL; MARKER_PCB* marker = NULL; #if 0 // debugging static int breakhere = 0; switch( item->Type() ) { case PCB_PAD_T: { MODULE* m = (MODULE*) item->GetParent(); if( m->GetReference() == wxT( "Y2" ) ) { breakhere++; } } break; case PCB_VIA_T: breakhere++; break; case PCB_TRACE_T: breakhere++; break; case PCB_ZONE_T: breakhere++; break; case PCB_TEXT_T: breakhere++; break; case PCB_LINE_T: breakhere++; break; case PCB_DIMENSION_T: breakhere++; break; case PCB_MODULE_TEXT_T: { TEXTE_MODULE* tm = (TEXTE_MODULE*) item; if( tm->GetText() == wxT( "10uH" ) ) { breakhere++; } } break; case PCB_MODULE_T: { MODULE* m = (MODULE*) item; if( m->GetReference() == wxT( "C98" ) ) { breakhere++; } } break; case PCB_MARKER_T: breakhere++; break; default: breakhere++; break; } #endif switch( item->Type() ) { case PCB_PAD_T: // there are pad specific visibility controls. // Criterias to select a pad is: // for smd pads: the module parent must be seen, and pads on the corresponding // board side must be seen // if pad is a thru hole, then it can be visible when its parent module is not. // for through pads: pads on Front or Back board sides must be seen pad = (D_PAD*) item; if( (pad->GetAttribute() != PAD_SMD) && (pad->GetAttribute() != PAD_CONN) ) // a hole is present, so multiple layers { // proceed to the common tests below, but without the parent module test, // by leaving module==NULL, but having pad != null pad_through = true; } else // smd, so use pads test after module test { module = (MODULE*) item->GetParent(); } break; case PCB_VIA_T: // vias are on many layers, so layer test is specific via = (SEGVIA*) item; break; case PCB_TRACE_T: break; case PCB_ZONE_T: break; case PCB_ZONE_AREA_T: break; case PCB_TEXT_T: break; case PCB_LINE_T: break; case PCB_DIMENSION_T: break; case PCB_TARGET_T: break; case PCB_MODULE_TEXT_T: module = (MODULE*) item->GetParent(); if( m_Guide->IgnoreMTextsMarkedNoShow() && !( (TEXTE_MODULE*) item )->IsVisible() ) goto exit; if( module ) { if( m_Guide->IgnoreMTextsOnCopper() && module->GetLayer()==LAYER_N_BACK ) goto exit; if( m_Guide->IgnoreMTextsOnCmp() && module->GetLayer()==LAYER_N_FRONT ) goto exit; if( m_Guide->IgnoreModulesVals() && item == &module->Value() ) goto exit; if( m_Guide->IgnoreModulesRefs() && item == &module->Reference() ) goto exit; } break; case PCB_MODULE_T: module = (MODULE*) item; break; case PCB_MARKER_T: marker = (MARKER_PCB*) item; break; default: break; } // common tests: if( module ) // true from case PCB_PAD_T, PCB_MODULE_TEXT_T, or PCB_MODULE_T { if( m_Guide->IgnoreModulesOnCu() && module->GetLayer()==LAYER_N_BACK ) goto exit; if( m_Guide->IgnoreModulesOnCmp() && module->GetLayer()==LAYER_N_FRONT ) goto exit; } // Pads are not sensitive to the layer visibility controls. // They all have their own separate visibility controls // skip them if not visible if( pad ) { if( m_Guide->IgnorePads() ) goto exit; if( ! pad_through ) { if( m_Guide->IgnorePadsOnFront() && pad->IsOnLayer(LAYER_N_FRONT ) ) goto exit; if( m_Guide->IgnorePadsOnBack() && pad->IsOnLayer(LAYER_N_BACK ) ) goto exit; } } if( marker ) { // Markers are not sensitive to the layer if( marker->HitTest( m_RefPos ) ) Append( item ); goto exit; } if( item->IsOnLayer( m_Guide->GetPreferredLayer() ) || m_Guide->IgnorePreferredLayer() ) { LAYER_NUM layer = item->GetLayer(); // Modules and their subcomponents: text and pads are not sensitive to the layer // visibility controls. They all have their own separate visibility controls // for vias, GetLayer() has no meaning, but IsOnLayer() works fine if( via || module || pad || m_Guide->IsLayerVisible( layer ) || !m_Guide->IgnoreNonVisibleLayers() ) { if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() ) { if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) { if( item->HitTest( m_RefPos ) ) { Append( item ); goto exit; } } } } } if( m_Guide->IncludeSecondary() ) { // for now, "secondary" means "tolerate any layer". It has // no effect on other criteria, since there is a separate "ignore" control for // those in the COLLECTORS_GUIDE LAYER_NUM layer = item->GetLayer(); // Modules and their subcomponents: text and pads are not sensitive to the layer // visibility controls. They all have their own separate visibility controls if( via || module || pad || m_Guide->IsLayerVisible( layer ) || !m_Guide->IgnoreNonVisibleLayers() ) { if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() ) { if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) { if( item->HitTest( m_RefPos ) ) { Append2nd( item ); goto exit; } } } } } exit: return SEARCH_CONTINUE; // always when collecting }
void DialogEditModuleText::initDlg( ) { SetFocus(); wxString msg; if( m_module ) { wxString format = m_ModuleInfoText->GetLabel(); msg.Printf( format, GetChars( m_module->GetReference() ), GetChars( m_module->GetValue() ), m_module->GetOrientation() / 10.0 ); } else { msg.Empty(); } m_ModuleInfoText->SetLabel( msg ); switch( m_currentText->GetType() ) { case TEXTE_MODULE::TEXT_is_VALUE: m_TextDataTitle->SetLabel( _( "Value:" ) ); break; case TEXTE_MODULE::TEXT_is_DIVERS: m_TextDataTitle->SetLabel( _( "Text:" ) ); break; default: m_TextDataTitle->SetLabel( _( "Reference:" ) ); break; } m_Name->SetValue( m_currentText->GetText() ); m_Style->SetSelection( m_currentText->IsItalic() ? 1 : 0 ); AddUnitSymbol( *m_SizeXTitle ); PutValueInLocalUnits( *m_TxtSizeCtrlX, m_currentText->GetSize().x ); AddUnitSymbol( *m_SizeYTitle ); PutValueInLocalUnits( *m_TxtSizeCtrlY, m_currentText->GetSize().y ); AddUnitSymbol( *m_PosXTitle ); PutValueInLocalUnits( *m_TxtPosCtrlX, m_currentText->GetPos0().x ); AddUnitSymbol( *m_PosYTitle ); PutValueInLocalUnits( *m_TxtPosCtrlY, m_currentText->GetPos0().y ); AddUnitSymbol( *m_WidthTitle ); PutValueInLocalUnits( *m_TxtWidthCtlr, m_currentText->GetThickness() ); double text_orient = m_currentText->GetOrientation(); NORMALIZE_ANGLE_90( text_orient ); if( (text_orient != 0) ) m_Orient->SetSelection( 1 ); if( !m_currentText->IsVisible() ) m_Show->SetSelection( 1 );; }
/* Plot a copper layer or mask. * Silk screen layers are not plotted here. */ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_MSK aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt ) { BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt ); itemplotter.SetLayerMask( aLayerMask ); EDA_DRAW_MODE_T plotMode = aPlotOpt.GetMode(); // Plot edge layer and graphic items itemplotter.PlotBoardGraphicItems(); // Draw footprint shapes without pads (pads will plotted later) // We plot here module texts, but they are usually on silkscreen layer, // so they are not plot here but plot by PlotSilkScreen() // Plot footprints fields (ref, value ...) for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { if( ! itemplotter.PlotAllTextsModule( module ) ) { wxLogMessage( _( "Your BOARD has a bad layer number for module %s" ), GetChars( module->GetReference() ) ); } } for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { if( ! (aLayerMask & GetLayerMask( item->GetLayer() ) ) ) continue; switch( item->Type() ) { case PCB_MODULE_EDGE_T: itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item ); break; default: break; } } } // Plot footprint pads for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { if( (pad->GetLayerMask() & aLayerMask) == 0 ) continue; wxSize margin; double width_adj = 0; if( aLayerMask & ALL_CU_LAYERS ) width_adj = itemplotter.getFineWidthAdj(); switch( aLayerMask & ( SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT | SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT ) ) { case SOLDERMASK_LAYER_FRONT: case SOLDERMASK_LAYER_BACK: margin.x = margin.y = pad->GetSolderMaskMargin(); break; case SOLDERPASTE_LAYER_FRONT: case SOLDERPASTE_LAYER_BACK: margin = pad->GetSolderPasteMargin(); break; default: break; } wxSize padPlotsSize; padPlotsSize.x = pad->GetSize().x + ( 2 * margin.x ) + width_adj; padPlotsSize.y = pad->GetSize().y + ( 2 * margin.y ) + width_adj; // Don't draw a null size item : if( padPlotsSize.x <= 0 || padPlotsSize.y <= 0 ) continue; EDA_COLOR_T color = BLACK; if( (pad->GetLayerMask() & LAYER_BACK) ) color = aBoard->GetVisibleElementColor( PAD_BK_VISIBLE ); if((pad->GetLayerMask() & LAYER_FRONT ) ) color = ColorFromInt( color | aBoard->GetVisibleElementColor( PAD_FR_VISIBLE ) ); // Temporary set the pad size to the required plot size: wxSize tmppadsize = pad->GetSize(); pad->SetSize( padPlotsSize ); switch( pad->GetShape() ) { case PAD_CIRCLE: case PAD_OVAL: if( aPlotOpt.GetSkipPlotNPTH_Pads() && (pad->GetSize() == pad->GetDrillSize()) && (pad->GetAttribute() == PAD_HOLE_NOT_PLATED) ) break; // Fall through: case PAD_TRAPEZOID: case PAD_RECT: default: itemplotter.PlotPad( pad, color, plotMode ); break; } pad->SetSize( tmppadsize ); // Restore the pad size } } // Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true, // plot them on solder mask for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { const VIA* Via = dynamic_cast<const VIA*>( track ); if( !Via ) continue; // vias are not plotted if not on selected layer, but if layer // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn, // only if they are on the corresponding external copper layer int via_mask_layer = Via->GetLayerMask(); if( aPlotOpt.GetPlotViaOnMaskLayer() ) { if( via_mask_layer & LAYER_BACK ) via_mask_layer |= SOLDERMASK_LAYER_BACK; if( via_mask_layer & LAYER_FRONT ) via_mask_layer |= SOLDERMASK_LAYER_FRONT; } if( ( via_mask_layer & aLayerMask ) == 0 ) continue; int via_margin = 0; double width_adj = 0; // If the current layer is a solder mask, use the global mask // clearance for vias if( ( aLayerMask & ( SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT ) ) ) via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin; if( aLayerMask & ALL_CU_LAYERS ) width_adj = itemplotter.getFineWidthAdj(); int diameter = Via->GetWidth() + 2 * via_margin + width_adj; // Don't draw a null size item : if( diameter <= 0 ) continue; EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetViaType()); // Set plot color (change WHITE to LIGHTGRAY because // the white items are not seen on a white paper or screen aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY); aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode ); } // Plot tracks (not vias) : for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { if( track->Type() == PCB_VIA_T ) continue; if( (GetLayerMask( track->GetLayer() ) & aLayerMask) == 0 ) continue; int width = track->GetWidth() + itemplotter.getFineWidthAdj(); aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) ); aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode ); } // Plot zones (outdated, for old boards compatibility): for( TRACK* track = aBoard->m_Zone; track; track = track->Next() ) { if( (GetLayerMask( track->GetLayer() ) & aLayerMask) == 0 ) continue; int width = track->GetWidth() + itemplotter.getFineWidthAdj(); aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) ); aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode ); } // Plot filled ares for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = aBoard->GetArea( ii ); if( ( GetLayerMask(zone->GetLayer() ) & aLayerMask ) == 0 ) continue; itemplotter.PlotFilledAreas( zone ); } // Adding drill marks, if required and if the plotter is able to plot them: if( aPlotOpt.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE ) itemplotter.PlotDrillMarks(); }
/* Creates the plot for silkscreen layers * Silkscreen layers have specific requirement for pads (not filled) and texts * (with option to remove them from some copper areas (pads...) */ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LAYER_MSK aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt ) { BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt ); itemplotter.SetLayerMask( aLayerMask ); // Plot edge layer and graphic items itemplotter.PlotBoardGraphicItems(); // Plot footprint outlines : itemplotter.Plot_Edges_Modules(); // Plot pads (creates pads outlines, for pads on silkscreen layers) int layersmask_plotpads = aLayerMask; // Calculate the mask layers of allowed layers for pads if( !aPlotOpt.GetPlotPadsOnSilkLayer() ) // Do not plot pads on silk screen layers layersmask_plotpads &= ~(SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT ); if( layersmask_plotpads ) { for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() ) { for( D_PAD * pad = Module->Pads(); pad != NULL; pad = pad->Next() ) { // See if the pad is on this layer LAYER_MSK masklayer = pad->GetLayerMask(); if( (masklayer & layersmask_plotpads) == 0 ) continue; EDA_COLOR_T color = ColorFromInt(0); if( (layersmask_plotpads & SILKSCREEN_LAYER_BACK) ) color = aBoard->GetLayerColor( SILKSCREEN_N_BACK ); if((layersmask_plotpads & SILKSCREEN_LAYER_FRONT ) ) color = ColorFromInt( color | aBoard->GetLayerColor( SILKSCREEN_N_FRONT ) ); itemplotter.PlotPad( pad, color, LINE ); } } } // Plot footprints fields (ref, value ...) for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { if( ! itemplotter.PlotAllTextsModule( module ) ) { wxLogMessage( _( "Your BOARD has a bad layer number for module %s" ), GetChars( module->GetReference() ) ); } } // Plot filled areas for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ ) { ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii ); if( ( GetLayerMask( edge_zone->GetLayer() ) & aLayerMask ) == 0 ) continue; itemplotter.PlotFilledAreas( edge_zone ); } // Plot segments used to fill zone areas (outdated, but here for old boards // compatibility): for( SEGZONE* seg = aBoard->m_Zone; seg != NULL; seg = seg->Next() ) { if( ( GetLayerMask( seg->GetLayer() ) & aLayerMask ) == 0 ) continue; aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(), itemplotter.GetMode() ); } }
// Handles the selection of command events. void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { int id = event.GetId(); LAYER_NUM itmp; INSTALL_UNBUFFERED_DC( dc, m_canvas ); MODULE* module; m_canvas->CrossHairOff( &dc ); switch( id ) // Some (not all ) edit commands must be finished or aborted { case wxID_CUT: case wxID_COPY: case ID_PCB_USER_GRID_SETUP: case ID_TOOLBARH_PCB_SELECT_LAYER: case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR: case ID_POPUP_PCB_ROTATE_TEXTEPCB: case ID_POPUP_PCB_FLIP_TEXTEPCB: case ID_POPUP_PCB_COPY_TEXTEPCB: case ID_POPUP_PCB_EDIT_TEXTEPCB: case ID_POPUP_PCB_EDIT_MIRE: case ID_POPUP_PCB_ROTATE_TEXTMODULE: case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE: case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE: case ID_POPUP_PCB_CHANGE_SIDE_MODULE: case ID_POPUP_PCB_EDIT_MODULE_PRMS: case ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT: case ID_POPUP_PCB_EDIT_TEXTMODULE: case ID_POPUP_PCB_STOP_CURRENT_DRAWING: case ID_POPUP_PCB_BEGIN_TRACK: case ID_POPUP_PCB_END_TRACK: case ID_POPUP_PCB_PLACE_THROUGH_VIA: case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA: case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA: case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA: case ID_POPUP_PCB_PLACE_MICROVIA: case ID_POPUP_PCB_SWITCH_TRACK_POSTURE: case ID_POPUP_PCB_IMPORT_PAD_SETTINGS: case ID_POPUP_PCB_EXPORT_PAD_SETTINGS: case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS: case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE: case ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER: case ID_POPUP_PCB_FILL_ALL_ZONES: case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES: case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE: case ID_POPUP_PCB_PLACE_ZONE_CORNER: case ID_POPUP_PCB_PLACE_ZONE_OUTLINES: case ID_POPUP_PCB_EDIT_ZONE_PARAMS: case ID_POPUP_PCB_DELETE_ZONE: case ID_POPUP_PCB_MOVE_ZONE_CORNER: case ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT: case ID_POPUP_PCB_MOVE_ZONE_OUTLINES: case ID_POPUP_PCB_ADD_ZONE_CORNER: case ID_POPUP_PCB_DELETE_TRACKSEG: case ID_POPUP_PCB_DELETE_TRACK: case ID_POPUP_PCB_DELETE_TRACKNET: case ID_POPUP_PCB_FILL_ZONE: case ID_POPUP_PCB_SELECT_LAYER: case ID_POPUP_PCB_SELECT_CU_LAYER: case ID_POPUP_PCB_SELECT_LAYER_PAIR: case ID_POPUP_PCB_SELECT_NO_CU_LAYER: case ID_POPUP_PCB_MOVE_TRACK_NODE: case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST: case ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE: case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: case ID_POPUP_PCB_MOVE_TRACK_SEGMENT: case ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE: case ID_POPUP_PCB_BREAK_TRACK: case ID_POPUP_PCB_EDIT_NET: case ID_POPUP_PCB_EDIT_TRACK: case ID_POPUP_PCB_EDIT_TRACKSEG: case ID_POPUP_PCB_LOCK_ON_TRACKSEG: case ID_POPUP_PCB_LOCK_OFF_TRACKSEG: case ID_POPUP_PCB_LOCK_ON_TRACK: case ID_POPUP_PCB_LOCK_OFF_TRACK: case ID_POPUP_PCB_LOCK_ON_NET: case ID_POPUP_PCB_LOCK_OFF_NET: case ID_POPUP_DELETE_BLOCK: case ID_POPUP_PLACE_BLOCK: case ID_POPUP_ZOOM_BLOCK: case ID_POPUP_FLIP_BLOCK: case ID_POPUP_ROTATE_BLOCK: case ID_POPUP_COPY_BLOCK: case ID_POPUP_PCB_EDIT_DRAWING: case ID_POPUP_PCB_GETINFO_MARKER: case ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST: case ID_POPUP_PCB_DRAG_MODULE_REQUEST: case ID_POPUP_PCB_MOVE_MODULE_REQUEST: case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST: case ID_POPUP_PCB_MOVE_MIRE_REQUEST: break; case ID_POPUP_CANCEL_CURRENT_COMMAND: if( m_canvas->IsMouseCaptured() ) { m_canvas->EndMouseCapture(); } // Should not be executed, just in case if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE ) { GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE ); GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK ); GetScreen()->m_BlockLocate.ClearItemsList(); } if( GetToolId() == ID_NO_TOOL_SELECTED ) SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); else SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() ); break; default: // Finish (abort) the command if( m_canvas->IsMouseCaptured() ) m_canvas->CallEndMouseCapture( &dc ); if( GetToolId() != id ) { if( m_lastDrawToolId != GetToolId() ) m_lastDrawToolId = GetToolId(); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); } break; } switch( id ) // Execute command { case 0: break; case ID_OPEN_MODULE_EDITOR: { FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, false ); if( !editor ) { editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); editor->Show( true ); editor->Zoom_Automatique( false ); } else { /* not needed on linux, other platforms need this? if( editor->IsIconized() ) editor->Iconize( false ); */ editor->Raise(); // Raising the window does not set the focus on Linux. This should work on // any platform. if( wxWindow::FindFocus() != editor ) editor->SetFocus(); } } break; case ID_OPEN_MODULE_VIEWER: { FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); if( !viewer ) { viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } else { /* not needed on linux, other platforms need this? if( viewer->IsIconized() ) viewer->Iconize( false ); */ viewer->Raise(); // Raising the window does not set the focus on Linux. This should work on // any platform. if( wxWindow::FindFocus() != viewer ) viewer->SetFocus(); } } break; case ID_PCB_GLOBAL_DELETE: InstallPcbGlobalDeleteFrame( wxDefaultPosition ); break; case ID_POPUP_PLACE_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE ); m_canvas->SetAutoPanRequest( false ); HandleBlockPlace( &dc ); break; case ID_POPUP_COPY_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY ); GetScreen()->m_BlockLocate.SetMessageBlock( this ); m_canvas->SetAutoPanRequest( false ); HandleBlockPlace( &dc ); break; case ID_POPUP_ZOOM_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM ); GetScreen()->m_BlockLocate.SetMessageBlock( this ); HandleBlockEnd( &dc ); break; case ID_POPUP_DELETE_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE ); GetScreen()->m_BlockLocate.SetMessageBlock( this ); HandleBlockEnd( &dc ); break; case ID_POPUP_ROTATE_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE ); GetScreen()->m_BlockLocate.SetMessageBlock( this ); HandleBlockEnd( &dc ); break; case ID_POPUP_FLIP_BLOCK: GetScreen()->m_BlockLocate.SetCommand( BLOCK_FLIP ); GetScreen()->m_BlockLocate.SetMessageBlock( this ); HandleBlockEnd( &dc ); break; case ID_DRC_CONTROL: m_drc->ShowDialog(); break; case ID_GET_NETLIST: InstallNetlistFrame( &dc ); break; case ID_FIND_ITEMS: InstallFindFrame(); break; case ID_POPUP_CLOSE_CURRENT_TOOL: SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); break; case ID_POPUP_CANCEL_CURRENT_COMMAND: break; case ID_POPUP_PCB_END_LINE: m_canvas->MoveCursorToCrossHair(); // EndSegment(&dc); break; case ID_POPUP_PCB_EDIT_TRACK: if( GetCurItem() == NULL ) break; Edit_Track_Width( &dc, (TRACK*) GetCurItem() ); m_canvas->MoveCursorToCrossHair(); OnModify(); break; case ID_POPUP_PCB_EDIT_TRACKSEG: if( GetCurItem() == NULL ) break; Edit_TrackSegm_Width( &dc, (TRACK*) GetCurItem() ); m_canvas->MoveCursorToCrossHair(); OnModify(); break; case ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE: if( GetCurItem() == NULL ) break; { int type = GetCurItem()->Type(); if( type == PCB_TRACE_T || type == PCB_VIA_T ) { BOARD_CONNECTED_ITEM*item = (BOARD_CONNECTED_ITEM*) GetCurItem(); DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNetCode() ); dlg.ShowModal(); } } m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_BEGIN_TRACK: m_canvas->MoveCursorToCrossHair(); OnHotkeyBeginRoute( &dc ); break; case ID_POPUP_PCB_END_TRACK: m_canvas->MoveCursorToCrossHair(); End_Route( (TRACK*) GetCurItem(), &dc ); break; case ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE: m_canvas->MoveCursorToCrossHair(); if( GetCurItem()->IsDragging() ) { PlaceDraggedOrMovedTrackSegment( (TRACK*) GetCurItem(), &dc ); } break; case ID_POPUP_PCB_SWITCH_TRACK_POSTURE: /* change the position of initial segment when creating new tracks * switch from _/ to -\ . * If a track is in progress, it will be redrawn */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false ); g_Alternate_Track_Posture = !g_Alternate_Track_Posture; if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false ); break; case ID_POPUP_PCB_PLACE_MICROVIA: if( !IsMicroViaAcceptable() ) break; // fall through case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA: case ID_POPUP_PCB_PLACE_THROUGH_VIA: case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA: case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA: m_canvas->MoveCursorToCrossHair(); if( GetCurItem()->IsDragging() ) { PlaceDraggedOrMovedTrackSegment( (TRACK*) GetCurItem(), &dc ); } else { BOARD_DESIGN_SETTINGS &settings = GetDesignSettings(); VIATYPE_T v_type = settings.m_CurrentViaType; switch( id ) { case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA: case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA: settings.m_CurrentViaType = VIA_BLIND_BURIED; break; case ID_POPUP_PCB_PLACE_MICROVIA: settings.m_CurrentViaType = VIA_MICROVIA; break; default: settings.m_CurrentViaType = VIA_THROUGH; break; } // place via and switch layer. if( id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA || id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA ) { m_canvas->SetIgnoreMouseEvents( true ); wxPoint dlgPosition; wxGetMousePosition( &dlgPosition.x, &dlgPosition.y ); LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS, dlgPosition ); m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); if( getActiveLayer() != layer ) { GetScreen()->m_Route_Layer_TOP = getActiveLayer(); GetScreen()->m_Route_Layer_BOTTOM = layer; Other_Layer_Route( (TRACK*) GetCurItem(), &dc ); } } else Other_Layer_Route( (TRACK*) GetCurItem(), &dc ); settings.m_CurrentViaType = v_type; if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); } break; case ID_POPUP_PCB_DELETE_TRACKSEG: if( GetCurItem() == NULL ) break; m_canvas->MoveCursorToCrossHair(); SetCurItem( Delete_Segment( &dc, (TRACK*) GetCurItem() ) ); OnModify(); break; case ID_POPUP_PCB_DELETE_TRACK: if( GetCurItem() == NULL ) break; m_canvas->MoveCursorToCrossHair(); Delete_Track( &dc, (TRACK*) GetCurItem() ); SetCurItem( NULL ); OnModify(); break; case ID_POPUP_PCB_DELETE_TRACKNET: m_canvas->MoveCursorToCrossHair(); Delete_net( &dc, (TRACK*) GetCurItem() ); SetCurItem( NULL ); OnModify(); break; case ID_POPUP_PCB_LOCK_ON_TRACKSEG: Attribut_Segment( (TRACK*) GetCurItem(), &dc, true ); break; case ID_POPUP_PCB_LOCK_OFF_TRACKSEG: Attribut_Segment( (TRACK*) GetCurItem(), &dc, false ); break; case ID_POPUP_PCB_LOCK_ON_TRACK: Attribut_Track( (TRACK*) GetCurItem(), &dc, true ); break; case ID_POPUP_PCB_LOCK_OFF_TRACK: Attribut_Track( (TRACK*) GetCurItem(), &dc, false ); break; case ID_POPUP_PCB_LOCK_ON_NET: Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), true ); break; case ID_POPUP_PCB_LOCK_OFF_NET: Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), false ); break; case ID_POPUP_PCB_SETFLAGS_TRACK_MNU: break; case ID_POPUP_PCB_DELETE_ZONE: m_canvas->MoveCursorToCrossHair(); if( GetCurItem() == NULL ) break; { SEGZONE* zsegm = (SEGZONE*) GetCurItem(); int netcode = zsegm->GetNetCode(); Delete_OldZone_Fill( zsegm ); SetCurItem( NULL ); TestNetConnection( NULL, netcode ); OnModify(); SetMsgPanel( GetBoard() ); } break; case ID_POPUP_PCB_EDIT_ZONE_PARAMS: Edit_Zone_Params( &dc, (ZONE_CONTAINER*) GetCurItem() ); SetCurItem( NULL ); // Outlines can have changed break; case ID_POPUP_PCB_ZONE_DUPLICATE: { ZONE_CONTAINER* zone = (ZONE_CONTAINER*) GetCurItem(); duplicateZone( &dc, zone ); } break; case ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE: m_canvas->MoveCursorToCrossHair(); m_canvas->SetAutoPanRequest( true ); Add_Similar_Zone( &dc, (ZONE_CONTAINER*) GetCurItem() ); break; case ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE: m_canvas->MoveCursorToCrossHair(); m_canvas->SetAutoPanRequest( true ); Add_Zone_Cutout( &dc, (ZONE_CONTAINER*) GetCurItem() ); break; case ID_POPUP_PCB_DELETE_ZONE_CONTAINER: case ID_POPUP_PCB_DELETE_ZONE_CUTOUT: m_canvas->MoveCursorToCrossHair(); { int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode(); Delete_Zone_Contour( &dc, (ZONE_CONTAINER*) GetCurItem() ); SetCurItem( NULL ); TestNetConnection( NULL, netcode ); SetMsgPanel( GetBoard() ); } break; case ID_POPUP_PCB_DELETE_ZONE_CORNER: Remove_Zone_Corner( &dc, (ZONE_CONTAINER*) GetCurItem() ); SetCurItem( NULL ); break; case ID_POPUP_PCB_MOVE_ZONE_CORNER: { m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); m_canvas->SetAutoPanRequest( true ); Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), false ); break; } case ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT: { m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); m_canvas->SetAutoPanRequest( true ); Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->GetSelectedCorner() ); break; } case ID_POPUP_PCB_MOVE_ZONE_OUTLINES: { m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); m_canvas->SetAutoPanRequest( true ); Start_Move_Zone_Outlines( &dc, zone_cont ); break; } case ID_POPUP_PCB_ADD_ZONE_CORNER: { m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); wxPoint pos = GetCrossHairPosition(); /* add corner between zone_cont->m_CornerSelection * and zone_cont->m_CornerSelection+1 * and start move the new corner */ zone_cont->Draw( m_canvas, &dc, GR_XOR ); zone_cont->Outline()->InsertCorner( zone_cont->GetSelectedCorner(), pos.x, pos.y ); zone_cont->SetSelectedCorner( zone_cont->GetSelectedCorner() + 1 ); zone_cont->Draw( m_canvas, &dc, GR_XOR ); m_canvas->SetAutoPanRequest( true ); Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), true ); break; } case ID_POPUP_PCB_PLACE_ZONE_OUTLINES: case ID_POPUP_PCB_PLACE_ZONE_CORNER: { m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); End_Move_Zone_Corner_Or_Outlines( &dc, zone_cont ); m_canvas->SetAutoPanRequest( false ); break; } case ID_POPUP_PCB_FILL_ALL_ZONES: m_canvas->MoveCursorToCrossHair(); Fill_All_Zones( this ); m_canvas->Refresh(); SetMsgPanel( GetBoard() ); break; case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE: if( ( GetCurItem() )->Type() == PCB_ZONE_AREA_T ) { ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem(); zone_container->UnFill(); TestNetConnection( NULL, zone_container->GetNetCode() ); OnModify(); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); } SetCurItem( NULL ); break; case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES: // Remove all zones : GetBoard()->m_Zone.DeleteAll(); // remove zone segments used to fill zones. for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) { // Remove filled areas in zone ZONE_CONTAINER* zone_container = GetBoard()->GetArea( ii ); zone_container->ClearFilledPolysList(); } SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer TestConnections(); TestForActiveLinksInRatsnest( 0 ); // Recalculate the active ratsnest, i.e. the unconnected links OnModify(); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); break; case ID_POPUP_PCB_FILL_ZONE: m_canvas->MoveCursorToCrossHair(); Fill_Zone( (ZONE_CONTAINER*) GetCurItem() ); TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode() ); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); break; case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST: StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc ); m_canvas->SetAutoPanRequest( true ); break; case ID_POPUP_PCB_DRAG_MODULE_REQUEST: case ID_POPUP_PCB_MOVE_MODULE_REQUEST: if( GetCurItem() == NULL ) break; // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; module = (MODULE*) GetCurItem(); if( module->IsLocked() ) { wxString msg; msg.Printf( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } SendMessageToEESCHEMA( module ); SetCrossHairPosition( module->GetPosition() ); m_canvas->MoveCursorToCrossHair(); StartMoveModule( module, &dc, id == ID_POPUP_PCB_DRAG_MODULE_REQUEST ); break; case ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST: // get module by name and move it SetCurItem( GetModuleByName() ); module = (MODULE*) GetCurItem(); if( module == NULL ) break; if( module->IsLocked() ) { wxString msg = wxString::Format( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } SendMessageToEESCHEMA( module ); m_canvas->MoveCursorToCrossHair(); StartMoveModule( module, &dc, false ); break; case ID_POPUP_PCB_DELETE_MODULE: m_canvas->MoveCursorToCrossHair(); // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; module = (MODULE*) GetCurItem(); if( module->IsLocked() ) { wxString msg; msg.Printf( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } if( Delete_Module( (MODULE*) GetCurItem(), &dc, true ) ) { SetCurItem( NULL ); } break; case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE: m_canvas->MoveCursorToCrossHair(); // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; module = (MODULE*) GetCurItem(); if( module->IsLocked() ) { wxString msg; msg.Printf( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } // This is a simple rotation, no other editing in progress if( !GetCurItem()->IsMoving() ) SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() ); Rotate_Module( &dc, (MODULE*) GetCurItem(), m_rotationAngle, true ); break; case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE: m_canvas->MoveCursorToCrossHair(); // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; module = (MODULE*) GetCurItem(); if( module->IsLocked() ) { wxString msg; msg.Printf( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } // This is a simple rotation, no other editing in progress if( !GetCurItem()->IsMoving() ) SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() ); Rotate_Module( &dc, (MODULE*) GetCurItem(), -m_rotationAngle, true ); break; case ID_POPUP_PCB_CHANGE_SIDE_MODULE: m_canvas->MoveCursorToCrossHair(); // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; module = (MODULE*) GetCurItem(); if( module->IsLocked() ) { wxString msg; msg.Printf( _( "Footprint %s found, but it is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } // This is a simple flip, no other editing in progress if( !GetCurItem()->IsMoving() ) SaveCopyInUndoList( GetCurItem(), UR_FLIPPED, ((MODULE*)GetCurItem())->GetPosition() ); Change_Side_Module( (MODULE*) GetCurItem(), &dc ); break; case ID_POPUP_PCB_EDIT_MODULE_PRMS: // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; InstallModuleOptionsFrame( (MODULE*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT: // If the current Item is a pad, text module ...: Get its parent if( GetCurItem()->Type() != PCB_MODULE_T ) SetCurItem( GetCurItem()->GetParent() ); if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) break; if( GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp { GetCurItem()->SetTimeStamp( GetNewTimeStamp() ); OnModify(); } { FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() ); SetCurItem( NULL ); // the current module could be deleted by editor->Show( true ); editor->Raise(); // Iconize( false ); } m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DRAG_PAD_REQUEST: module = (MODULE*) GetCurItem()->GetParent(); if( !module || module->Type() != PCB_MODULE_T ) break; if( module->IsLocked() ) { wxString msg; msg.Printf( _( "The parent (%s) of the pad is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } m_canvas->MoveCursorToCrossHair(); StartMovePad( (D_PAD*) GetCurItem(), &dc, true ); break; case ID_POPUP_PCB_MOVE_PAD_REQUEST: module = (MODULE*) GetCurItem()->GetParent(); if( !module || module->Type() != PCB_MODULE_T ) break; if( module->IsLocked() ) { wxString msg; msg.Printf( _( "The parent (%s) of the pad is locked" ), module->GetReference().GetData() ); DisplayInfoMessage( this, msg ); break; } m_canvas->MoveCursorToCrossHair(); StartMovePad( (D_PAD*) GetCurItem(), &dc, false ); break; case ID_POPUP_PCB_EDIT_PAD: InstallPadOptionsFrame( (D_PAD*) GetCurItem() ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_IMPORT_PAD_SETTINGS: m_canvas->MoveCursorToCrossHair(); SaveCopyInUndoList( GetCurItem()->GetParent(), UR_CHANGED ); Import_Pad_Settings( (D_PAD*) GetCurItem(), true ); break; case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS: m_canvas->MoveCursorToCrossHair(); DlgGlobalChange_PadSettings( (D_PAD*) GetCurItem(), true ); break; case ID_POPUP_PCB_EXPORT_PAD_SETTINGS: m_canvas->MoveCursorToCrossHair(); Export_Pad_Settings( (D_PAD*) GetCurItem() ); break; case ID_POPUP_PCB_DELETE_PAD: SaveCopyInUndoList( GetCurItem()->GetParent(), UR_CHANGED ); DeletePad( (D_PAD*) GetCurItem() ); SetCurItem( NULL ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_EDIT_TEXTMODULE: InstallTextModOptionsFrame( (TEXTE_MODULE*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_RESET_TEXT_SIZE: ResetTextSize( GetCurItem(), &dc ); break; case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST: m_canvas->MoveCursorToCrossHair(); StartMoveTexteModule( (TEXTE_MODULE*) GetCurItem(), &dc ); break; case ID_POPUP_PCB_ROTATE_TEXTMODULE: RotateTextModule( (TEXTE_MODULE*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DELETE_TEXTMODULE: DeleteTextModule( (TEXTE_MODULE*) GetCurItem() ); SetCurItem( NULL ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_SELECT_LAYER: itmp = SelectLayer( getActiveLayer() ); if( itmp >= 0 ) { // if user changed colors and we are in high contrast mode, then redraw // because the PAD_SMD pads may change color. if( DisplayOpt.ContrastModeDisplay && getActiveLayer() != itmp ) { m_canvas->Refresh(); } setActiveLayer( itmp ); } m_canvas->MoveCursorToCrossHair(); break; case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR: SelectCopperLayerPair(); break; case ID_POPUP_PCB_SELECT_NO_CU_LAYER: itmp = SelectLayer( getActiveLayer(), ALL_CU_LAYERS ); if( itmp >= 0 ) setActiveLayer( itmp ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_SELECT_CU_LAYER: itmp = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS ); if( itmp >= 0 ) setActiveLayer( itmp ); break; case ID_POPUP_PCB_SELECT_LAYER_PAIR: SelectCopperLayerPair(); m_canvas->MoveCursorToCrossHair(); break; case ID_TOOLBARH_PCB_SELECT_LAYER: setActiveLayer( m_SelLayerBox->GetLayerSelection() ); if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh( true ); break; case ID_POPUP_PCB_EDIT_TEXTEPCB: InstallTextPCBOptionsFrame( (TEXTE_PCB*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_ROTATE_TEXTEPCB: Rotate_Texte_Pcb( (TEXTE_PCB*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_COPY_TEXTEPCB: CreateTextePcb( &dc, (TEXTE_PCB*) GetCurItem() ); m_canvas->MoveCursorToCrossHair(); m_canvas->SetAutoPanRequest( true ); break; case ID_POPUP_PCB_FLIP_TEXTEPCB: FlipTextePcb( (TEXTE_PCB*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DELETE_TEXTEPCB: Delete_Texte_Pcb( (TEXTE_PCB*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_MOVE_MIRE_REQUEST: BeginMoveTarget( (PCB_TARGET*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_EDIT_MIRE: ShowTargetOptionsDialog( (PCB_TARGET*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DELETE_MIRE: m_canvas->MoveCursorToCrossHair(); DeleteTarget( (PCB_TARGET*) GetCurItem(), &dc ); SetCurItem( NULL ); break; case ID_POPUP_PCB_DELETE_DIMENSION: m_canvas->MoveCursorToCrossHair(); DeleteDimension( (DIMENSION*) GetCurItem(), &dc ); SetCurItem( NULL ); break; case ID_POPUP_PCB_EDIT_DIMENSION: ShowDimensionPropertyDialog( (DIMENSION*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST: BeginMoveDimensionText( (DIMENSION*) GetCurItem(), &dc ); break; case ID_POPUP_PCB_DELETE_DRAWING: Delete_Segment_Edge( (DRAWSEGMENT*) GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DELETE_MARKER: RemoveStruct( GetCurItem(), &dc ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_GETINFO_MARKER: if( GetCurItem() && GetCurItem()->Type() == PCB_MARKER_T ) ( (MARKER_PCB*) GetCurItem() )->DisplayMarkerInfo( this ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_DELETE_DRAWING_LAYER: if( GetCurItem()->GetFlags() != 0 ) break; Delete_Drawings_All_Layer( GetCurItem()->GetLayer() ); SetCurItem( NULL ); m_canvas->MoveCursorToCrossHair(); m_canvas->Refresh(); break; case ID_POPUP_PCB_EDIT_DRAWING: #ifndef USE_WX_OVERLAY InstallGraphicItemPropertiesDialog( (DRAWSEGMENT*) GetCurItem(), &dc ); #else // #1277772 - Draw into dialog converted in refresh request InstallGraphicItemPropertiesDialog( (DRAWSEGMENT*) GetCurItem(), NULL ); m_canvas->Refresh(); #endif m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_MOVE_DRAWING_REQUEST: m_canvas->MoveCursorToCrossHair(); Start_Move_DrawItem( (DRAWSEGMENT*) GetCurItem(), &dc ); break; case ID_POPUP_PCB_STOP_CURRENT_DRAWING: m_canvas->MoveCursorToCrossHair(); if( GetCurItem() && (GetCurItem()->IsNew()) ) { End_Edge( (DRAWSEGMENT*) GetCurItem(), &dc ); SetCurItem( NULL ); } break; case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE: m_canvas->MoveCursorToCrossHair(); if( GetCurItem() && (GetCurItem()->IsNew()) ) { if( End_Zone( &dc ) ) SetCurItem( NULL ); } m_canvas->SetAutoPanRequest( false ); break; case ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER: m_canvas->MoveCursorToCrossHair(); if( GetCurItem() && (GetCurItem()->IsNew()) ) { if( Delete_LastCreatedCorner( &dc ) == 0 ) // No more segment in outline, SetCurItem( NULL ); } break; case ID_POPUP_PCB_MOVE_TRACK_SEGMENT: m_canvas->MoveCursorToCrossHair(); StartMoveOneNodeOrSegment( (TRACK*) GetScreen()->GetCurItem(), &dc, id ); break; case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: case ID_POPUP_PCB_MOVE_TRACK_NODE: m_canvas->MoveCursorToCrossHair(); StartMoveOneNodeOrSegment( (TRACK*) GetScreen()->GetCurItem(), &dc, id ); break; case ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE: m_canvas->MoveCursorToCrossHair(); Start_DragTrackSegmentAndKeepSlope( (TRACK*) GetScreen()->GetCurItem(), &dc ); break; case ID_POPUP_PCB_BREAK_TRACK: m_canvas->MoveCursorToCrossHair(); { TRACK* track = (TRACK*) GetScreen()->GetCurItem(); wxPoint pos = GetCrossHairPosition(); track->Draw( m_canvas, &dc, GR_XOR ); PICKED_ITEMS_LIST itemsListPicker; TRACK* newtrack = GetBoard()->CreateLockPoint( pos, track, &itemsListPicker ); SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED ); track->Draw( m_canvas, &dc, GR_XOR ); newtrack->Draw( m_canvas, &dc, GR_XOR ); // compute the new ratsnest, because connectivity could change TestNetConnection( &dc, track->GetNetCode() ); } break; case ID_MENU_PCB_CLEAN: Clean_Pcb(); break; case ID_MENU_PCB_SWAP_LAYERS: Swap_Layers( event ); break; case ID_PCB_USER_GRID_SETUP: InvokeDialogGrid(); break; case ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC: { wxConfigBase* cfg = Pgm().CommonSettings(); cfg->Read( wxT( "module_doc_file" ), g_DocModulesFileName ); GetAssociatedDocument( this, g_DocModulesFileName, &Kiface().KifaceSearch() ); } break; case ID_MENU_ARCHIVE_NEW_MODULES: ArchiveModulesOnBoard( true ); break; case ID_MENU_ARCHIVE_ALL_MODULES: ArchiveModulesOnBoard( false ); break; case ID_GEN_IMPORT_DXF_FILE: InvokeDXFDialogImport( this ); m_canvas->Refresh(); break; default: wxString msg; msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ), id ); DisplayError( this, msg ); break; } m_canvas->CrossHairOn( &dc ); m_canvas->SetIgnoreMouseEvents( false ); }