void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, const wxPoint& aOffset ) { int ux0, uy0, dx, dy; int l_trace; int mode; int radius; LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; EDA_COLOR_T color; BOARD * brd = GetBoard( ); if( brd->IsLayerVisible( GetLayer() ) == false ) return; color = brd->GetLayerColor( GetLayer() ); if( ( draw_mode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) && !IsOnLayer( EDGE_N ) ) ColorTurnToDarkDarkGray( &color ); } GRSetDrawMode( DC, draw_mode ); l_trace = m_Width >> 1; /* half trace width */ // Line start point or Circle and Arc center ux0 = m_Start.x + aOffset.x; uy0 = m_Start.y + aOffset.y; // Line end point or circle and arc start point dx = m_End.x + aOffset.x; dy = m_End.y + aOffset.y; mode = DisplayOpt.DisplayDrawItems; if( m_Flags & FORCE_SKETCH ) mode = SKETCH; if( DC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) mode = LINE; switch( m_Shape ) { case S_CIRCLE: radius = KiROUND( Distance( ux0, uy0, dx, dy ) ); if( mode == LINE ) { GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, color ); } else if( mode == SKETCH ) { GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - l_trace, color ); GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + l_trace, color ); } else { GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color ); } break; case S_ARC: double StAngle, EndAngle; radius = KiROUND( Distance( ux0, uy0, dx, dy ) ); StAngle = ArcTangente( dy - uy0, dx - ux0 ); EndAngle = StAngle + m_Angle; if( !panel->GetPrintMirrored() ) { if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); } else // Mirrored mode: arc orientation is reversed { if( StAngle < EndAngle ) EXCHG( StAngle, EndAngle ); } if( mode == LINE ) GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, color ); else if( mode == SKETCH ) { GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius - l_trace, color ); GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius + l_trace, color ); } else { GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color ); } break; case S_CURVE: m_BezierPoints = Bezier2Poly(m_Start, m_BezierC1, m_BezierC2, m_End); for (unsigned int i=1; i < m_BezierPoints.size(); i++) { if( mode == LINE ) GRLine( panel->GetClipBox(), DC, m_BezierPoints[i].x, m_BezierPoints[i].y, m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0, color ); else if( mode == SKETCH ) { GRCSegm( panel->GetClipBox(), DC, m_BezierPoints[i].x, m_BezierPoints[i].y, m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, m_Width, color ); } else { GRFillCSegm( panel->GetClipBox(), DC, m_BezierPoints[i].x, m_BezierPoints[i].y, m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, m_Width, color ); } } break; default: if( mode == LINE ) { GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, 0, color ); } else if( mode == SKETCH ) { GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color ); } else { GRFillCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color ); } break; } }
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, const wxString& aCmpFileName, REPORTER* aReporter, bool aChangeFootprints, bool aDeleteUnconnectedTracks, bool aDeleteExtraFootprints, bool aSelectByTimeStamp, bool aDeleteSinglePadNets, bool aIsDryRun ) { wxString msg; NETLIST netlist; NETLIST_READER* netlistReader; netlist.SetIsDryRun( aIsDryRun ); netlist.SetFindByTimeStamp( aSelectByTimeStamp ); netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints ); netlist.SetReplaceFootprints( aChangeFootprints ); 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, this ); return; } std::auto_ptr< NETLIST_READER > nlr( netlistReader ); SetLastNetListRead( aNetlistFileName ); netlistReader->LoadNetlist(); loadFootprints( netlist, aReporter ); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); return; } // Clear undo and redo lists to avoid inconsistencies between lists if( !netlist.IsDryRun() ) GetScreen()->ClearUndoRedoList(); netlist.SortByReference(); GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter ); // If it was a dry run, nothing has changed so we're done. if( netlist.IsDryRun() ) return; OnModify(); SetCurItem( NULL ); if( aDeleteUnconnectedTracks && GetBoard()->m_Track ) { // Remove erroneous tracks. This should probably pushed down to the #BOARD object. RemoveMisConnectedTracks(); } // Rebuild the board connectivity: Compile_Ratsnest( NULL, true ); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); }
void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) { BOARD_ITEM* item = GetCurItem(); m_canvas->CrossHairOff( DC ); if( GetToolId() == ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) // Move item command in progress { switch( item->Type() ) { case PCB_MODULE_TEXT_T: PlaceTexteModule( (TEXTE_MODULE*) item, DC ); break; case PCB_MODULE_EDGE_T: SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); Place_EdgeMod( (EDGE_MODULE*) item ); break; case PCB_PAD_T: PlacePad( (D_PAD*) item, DC ); break; default: { wxString msg; msg.Printf( wxT( "WinEDA_ModEditFrame::OnLeftClick err:Struct %d, m_Flag %X" ), item->Type(), item->GetFlags() ); DisplayError( this, msg ); item->ClearFlags(); break; } } } else { if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT ) && !wxGetKeyState( WXK_CONTROL ) ) item = ModeditLocateAndDisplay(); SetCurItem( item ); } } item = GetCurItem(); bool no_item_edited = item == NULL || item->GetFlags() == 0; switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: break; case ID_MODEDIT_CIRCLE_TOOL: case ID_MODEDIT_ARC_TOOL: case ID_MODEDIT_LINE_TOOL: if( no_item_edited ) { STROKE_T shape = S_SEGMENT; if( GetToolId() == ID_MODEDIT_CIRCLE_TOOL ) shape = S_CIRCLE; if( GetToolId() == ID_MODEDIT_ARC_TOOL ) shape = S_ARC; SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) NULL, DC, shape ) ); } else if( item->IsNew() ) { if( ( (EDGE_MODULE*) item )->GetShape() == S_CIRCLE ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } else if( ( (EDGE_MODULE*) item )->GetShape() == S_ARC ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } else if( ( (EDGE_MODULE*) item )->GetShape() == S_SEGMENT ) { SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) item, DC, S_SEGMENT ) ); } else { DisplayError( this, wxT( "ProcessCommand error: item flags error" ) ); } } break; case ID_MODEDIT_DELETE_TOOL: if( ! no_item_edited ) // Item in edit, cannot delete it break; item = ModeditLocateAndDisplay(); if( item->Type() != PCB_MODULE_T ) // Cannot delete the module itself { SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); RemoveStruct( item ); SetCurItem( NULL ); } break; case ID_MODEDIT_ANCHOR_TOOL: { MODULE* module = GetBoard()->m_Modules; if( module == NULL // No module loaded || (module->GetFlags() != 0) ) break; module->ClearFlags(); SaveCopyInUndoList( module, UR_MODEDIT ); Place_Ancre( module ); // set the new relatives internal coordinates of items RedrawScreen( wxPoint( 0, 0 ), true ); // Replace the module in position 0, to recalculate absolutes coordinates of items module->SetPosition( wxPoint( 0, 0 ) ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); SetCurItem( NULL ); m_canvas->Refresh(); } break; case ID_MODEDIT_PLACE_GRID_COORD: m_canvas->DrawGridAxis( DC, GR_XOR ); GetScreen()->m_GridOrigin = GetScreen()->GetCrossHairPosition(); m_canvas->DrawGridAxis( DC, GR_COPY ); GetScreen()->SetModify(); break; case ID_MODEDIT_TEXT_TOOL: if( GetBoard()->m_Modules == NULL ) break; SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); CreateTextModule( GetBoard()->m_Modules, DC ); break; case ID_MODEDIT_PAD_TOOL: if( GetBoard()->m_Modules ) { SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); AddPad( GetBoard()->m_Modules, true ); } break; default: DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); } m_canvas->CrossHairOn( DC ); }
void EDA_3D_CANVAS::CreateDrawGL_List( REPORTER* aErrorMessages, REPORTER* aActivity ) { BOARD* pcb = GetBoard(); wxBusyCursor dummy; // Build 3D board parameters: GetPrm3DVisu().InitSettings( pcb ); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); // Create axis gl list (if it is not shown, the list will be not called draw3DAxis(); // Create Board full gl lists: if( ! m_glLists[GL_ID_BOARD] ) { DBG( unsigned strtime = GetRunningMicroSecs() ); m_glLists[GL_ID_BOARD] = glGenLists( 1 ); m_glLists[GL_ID_BODY] = glGenLists( 1 ); buildBoard3DView(m_glLists[GL_ID_BOARD], m_glLists[GL_ID_BODY], aErrorMessages, aActivity ); CheckGLError( __FILE__, __LINE__ ); DBG( printf( " buildBoard3DView total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); } if( ! m_glLists[GL_ID_TECH_LAYERS] ) { DBG( unsigned strtime = GetRunningMicroSecs() ); m_glLists[GL_ID_TECH_LAYERS] = glGenLists( 1 ); glNewList( m_glLists[GL_ID_TECH_LAYERS], GL_COMPILE ); // when calling BuildTechLayers3DView, // do not show warnings, which are the same as buildBoard3DView buildTechLayers3DView( aErrorMessages, aActivity ); glEndList(); CheckGLError( __FILE__, __LINE__ ); DBG( printf( " buildTechLayers3DView total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); } if( ! m_glLists[GL_ID_AUX_LAYERS] ) { DBG( unsigned strtime = GetRunningMicroSecs() ); m_glLists[GL_ID_AUX_LAYERS] = glGenLists( 1 ); glNewList( m_glLists[GL_ID_AUX_LAYERS], GL_COMPILE ); buildBoard3DAuxLayers( aErrorMessages, aActivity ); glEndList(); CheckGLError( __FILE__, __LINE__ ); DBG( printf( " buildBoard3DAuxLayers total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); } // draw modules 3D shapes if( ! m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] && isEnabled( FL_MODULE ) ) { m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] = glGenLists( 1 ); // GL_ID_3DSHAPES_TRANSP_FRONT is an auxiliary list for 3D shapes; // Ensure it is cleared before rebuilding it if( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] ) glDeleteLists( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], 1 ); bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL ); if( useMaterial ) m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] = glGenLists( 1 ); else m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] = 0; buildFootprintShape3DList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT], m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], aErrorMessages, aActivity ); CheckGLError( __FILE__, __LINE__ ); } calcBBox(); // Create grid gl list if( ! m_glLists[GL_ID_GRID] ) { m_glLists[GL_ID_GRID] = glGenLists( 1 ); glNewList( m_glLists[GL_ID_GRID], GL_COMPILE ); draw3DGrid( GetPrm3DVisu().m_3D_Grid ); glEndList(); } if( !m_glLists[GL_ID_SHADOW_FRONT] ) m_glLists[GL_ID_SHADOW_FRONT] = glGenLists( 1 ); if( !m_glLists[GL_ID_SHADOW_BACK] ) m_glLists[GL_ID_SHADOW_BACK] = glGenLists( 1 ); if( !m_glLists[GL_ID_SHADOW_BOARD] ) m_glLists[GL_ID_SHADOW_BOARD] = glGenLists( 1 ); buildShadowList( m_glLists[GL_ID_SHADOW_FRONT], m_glLists[GL_ID_SHADOW_BACK], m_glLists[GL_ID_SHADOW_BOARD] ); CheckGLError( __FILE__, __LINE__ ); }
void EDA_3D_CANVAS::buildFootprintShape3DList( GLuint aOpaqueList, GLuint aTransparentList, REPORTER* aErrorMessages, REPORTER* aActivity ) { DBG( unsigned strtime = GetRunningMicroSecs() ); if( aActivity ) aActivity->Report( _( "Load 3D Shapes" ) ); // clean the parser list if it have any already loaded files m_model_parsers_list.clear(); m_model_filename_list.clear(); BOARD* pcb = GetBoard(); for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) read3DComponentShape( module ); DBG( printf( " read3DComponentShape total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); DBG( strtime = GetRunningMicroSecs() ); bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL ); if( useMaterial ) { // aOpaqueList is the gl list for non transparent items // aTransparentList is the gl list for non transparent items, // which need to be drawn after all other items glNewList( aOpaqueList, GL_COMPILE ); bool loadOpaqueObjects = true; for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) render3DComponentShape( module, loadOpaqueObjects, !loadOpaqueObjects ); glEndList(); glNewList( aTransparentList, GL_COMPILE ); bool loadTransparentObjects = true; for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) render3DComponentShape( module, !loadTransparentObjects, loadTransparentObjects ); glEndList(); } else { // Just create one list glNewList( aOpaqueList, GL_COMPILE ); for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) render3DComponentShape( module, false, false ); glEndList(); } DBG( printf( " render3DComponentShape total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); }
void EDA_3D_VIEWER::ReloadRequest() { // This will schedule a request to load later if( m_canvas ) m_canvas->ReloadRequest( GetBoard(), Prj().Get3DCacheManager() ); }
/* * This function starts a new track segment. * If a new track segment is in progress, ends this current new segment, * and created a new one. */ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) { TRACK* TrackOnStartPoint = NULL; LAYER_MSK layerMask = GetLayerMask( GetScreen()->m_Active_Layer ); BOARD_CONNECTED_ITEM* LockPoint; wxPoint pos = GetCrossHairPosition(); if( aTrack == NULL ) // Starting a new track segment { m_canvas->SetMouseCapture( ShowNewTrackWhenMovingCursor, Abort_Create_Track ); // Prepare the undo command info s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but... GetBoard()->PushHighLight(); // erase old highlight if( GetBoard()->IsHighLightNetON() ) HighLight( aDC ); g_CurrentTrackList.PushBack( new TRACK( GetBoard() ) ); g_CurrentTrackSegment->SetFlags( IS_NEW ); GetBoard()->SetHighLightNet( 0 ); // Search for a starting point of the new track, a track or pad LockPoint = GetBoard()->GetLockPoint( pos, layerMask ); D_PAD* pad = NULL; if( LockPoint ) // An item (pad or track) is found { if( LockPoint->Type() == PCB_PAD_T ) { pad = (D_PAD*) LockPoint; // A pad is found: put the starting point on pad center pos = pad->GetPosition(); GetBoard()->SetHighLightNet( pad->GetNetCode() ); } else // A track segment is found { TrackOnStartPoint = (TRACK*) LockPoint; GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNetCode() ); GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker ); } } else { // Not a starting point, but a filled zone area can exist. This is also a // good starting point. ZONE_CONTAINER* zone; zone = GetBoard()->HitTestForAnyFilledArea( pos, GetScreen()-> m_Active_Layer, GetScreen()-> m_Active_Layer, -1 ); if( zone ) GetBoard()->SetHighLightNet( zone->GetNetCode() ); } DBG( g_CurrentTrackList.VerifyListIntegrity() ); BuildAirWiresTargetsList( LockPoint, wxPoint( 0, 0 ), true ); DBG( g_CurrentTrackList.VerifyListIntegrity() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); // Display info about track Net class, and init track and vias sizes: g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() ); GetDesignSettings().SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() ); g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer ); g_CurrentTrackSegment->SetWidth( GetDesignSettings().GetCurrentTrackWidth() ); if( GetDesignSettings().m_UseConnectedTrackWidth ) { if( TrackOnStartPoint && TrackOnStartPoint->Type() == PCB_TRACE_T ) g_CurrentTrackSegment->SetWidth( TrackOnStartPoint->GetWidth()); } g_CurrentTrackSegment->SetStart( pos ); g_CurrentTrackSegment->SetEnd( pos ); if( pad ) { g_CurrentTrackSegment->m_PadsConnected.push_back( pad ); // Useful to display track length, if the pad has a die length: g_CurrentTrackSegment->SetState( BEGIN_ONPAD, true ); g_CurrentTrackSegment->start = pad; } if( g_TwoSegmentTrackBuild ) { // Create 2nd segment g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() ); DBG( g_CurrentTrackList.VerifyListIntegrity(); ); g_CurrentTrackSegment->start = g_FirstTrackSegment; g_FirstTrackSegment->end = g_CurrentTrackSegment; g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, false ); }
BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const { return GetBoard()->GetDesignSettings(); }
void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ) { GetBoard()->SetDesignSettings( aSettings ); }
BOARD_ITEM_CONTAINER* FOOTPRINT_EDIT_FRAME::GetModel() const { return GetBoard()->m_Modules; }
bool FOOTPRINT_EDIT_FRAME::IsCurrentFPFromBoard() const { MODULE* module = GetBoard()->m_Modules; return ( module && module->GetLink() > 0 ); }
FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, EDA_DRAW_PANEL_GAL::GAL_TYPE aBackend ) : PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) { m_showBorderAndTitleBlock = false; // true to show the frame references m_showAxis = true; // true to show X and Y axis on screen m_showGridAxis = true; // show the grid origin axis m_hotkeysDescrList = g_Module_Editor_Hotkeys_Descr; m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs m_canvasType = aBackend; m_AboutTitle = "ModEdit"; // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) ); SetIcon( icon ); // Create GAL canvas if( aBackend == EDA_DRAW_PANEL_GAL::GAL_TYPE_UNKNOWN ) m_canvasType = LoadCanvasTypeSetting(); else m_canvasType = aBackend; PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, GetGalDisplayOptions(), m_canvasType ); SetGalCanvas( drawPanel ); SetBoard( new BOARD() ); // In modedit, the default net clearance is not known. // (it depends on the actual board) // So we do not show the default clearance, by setting it to 0 // The footprint or pad specific clearance will be shown GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 ); // Don't show the default board solder mask clearance in the footprint editor. Only the // footprint or pad clearance setting should be shown if it is not 0. GetBoard()->GetDesignSettings().m_SolderMaskMargin = 0; // restore the last footprint from the project, if any restoreLastFootprint(); // Ensure all layers and items are visible: // In footprint editor, some layers have no meaning or // cannot be used, but we show all of them, at least to be able // to edit a bad layer GetBoard()->SetVisibleAlls(); // However the "no net" mark on pads is useless, because there is // no net in footprint editor: make it non visible GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, false ); m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas(), true ); // LoadSettings() *after* creating m_LayersManager, because LoadSettings() // initialize parameters in m_LayersManager LoadSettings( config() ); GetGalDisplayOptions().m_axesEnabled = true; SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); GetScreen()->AddGrid( m_UserGridSize, EDA_UNITS_T::UNSCALED_UNITS, ID_POPUP_GRID_USER ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); // In modedit, set the default paper size to A4: // this should be OK for all footprint to plot/print SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); initLibraryTree(); m_treePane = new FOOTPRINT_TREE_PANE( this ); // Create the manager and dispatcher & route draw panel events to the dispatcher setupTools(); // ReCreateMenuBar(); // UseGalCanvas() will do this for us. ReCreateHToolbar(); ReCreateVToolbar(); ReCreateOptToolbar(); m_Layers->ReFill(); m_Layers->ReFillRender(); GetScreen()->m_Active_Layer = F_SilkS; m_Layers->SelectLayer( F_SilkS ); m_Layers->OnLayerSelected(); m_auimgr.SetManagedWindow( this ); m_auimgr.SetArtProvider( new EDA_DOCKART( this ) ); // Horizontal items; layers 4 - 6 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer(6) ); m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" ).Bottom().Layer(6) ); // Vertical items; layers 1 - 3 m_auimgr.AddPane( m_optionsToolBar, EDA_PANE().VToolbar().Name( "OptToolbar" ).Left().Layer(3) ); m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "Footprints" ).Left().Layer(1) .Caption( _( "Libraries" ) ).MinSize( 250, 400 ) .BestSize( m_defaultLibWidth, -1 ) ); m_auimgr.AddPane( m_drawToolBar, EDA_PANE().VToolbar().Name( "ToolsToolbar" ).Right().Layer(1) ); m_auimgr.AddPane( m_Layers, EDA_PANE().Palette().Name( "LayersManager" ).Right().Layer(3) .Caption( _( "Layers Manager" ) ).PaneBorder( false ) .MinSize( 80, -1 ).BestSize( m_Layers->GetBestSize() ) ); m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( "DrawFrame" ).Center() ); m_auimgr.AddPane( GetGalCanvas(), EDA_PANE().Canvas().Name( "DrawFrameGal" ).Center().Hide() ); GetGalCanvas()->GetGAL()->SetAxesEnabled( true ); // Set up viewport KIGFX::VIEW* view = GetGalCanvas()->GetView(); view->SetScale( GetZoomLevelCoeff() / m_canvas->GetZoom() ); view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) ); UseGalCanvas(); m_auimgr.Update(); updateTitle(); Raise(); // On some window managers, this is needed Show( true ); Zoom_Automatique( false ); }
void PCB_EDIT_FRAME::Block_Rotate() { wxPoint centre; // rotation cent-re for the rotation transform int rotAngle = m_rotationAngle; // rotation angle in 0.1 deg. centre = GetScreen()->m_BlockLocate.Centre(); OnModify(); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems(); itemsList->m_Status = UR_CHANGED; for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); itemsList->SetPickedItemStatus( UR_CHANGED, ii ); switch( item->Type() ) { case PCB_MODULE_T: ( (MODULE*) item )->ClearFlags(); m_Pcb->m_Status_Pcb = 0; break; // Move and rotate the track segments case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) m_Pcb->m_Status_Pcb = 0; break; case PCB_ZONE_AREA_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TARGET_T: case PCB_DIMENSION_T: break; // This item is not put in undo list case PCB_ZONE_T: // SEG_ZONE items are now deprecated itemsList->RemovePicker( ii ); ii--; break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Rotate( ) error: unexpected type" ) ); break; } } // Save all the block items in there current state before applying the rotation. SaveCopyInUndoList( *itemsList, UR_CHANGED, centre ); // Now perform the rotation. for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); item->Rotate( centre, rotAngle ); GetBoard()->GetConnectivity()->Update( item ); } Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }
bool PCB_EDIT_FRAME::HandleBlockEnd( wxDC* DC ) { bool nextcmd = false; // Will be set to true if a block place is needed bool cancelCmd = false; // If coming here after cancel block, clean up and exit if( GetScreen()->m_BlockLocate.GetState() == STATE_NO_BLOCK ) { m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); GetScreen()->ClearBlockCommand(); return false; } // Show dialog if there are no selected items and we're not zooming if( !GetScreen()->m_BlockLocate.GetCount() && GetScreen()->m_BlockLocate.GetCommand() != BLOCK_ZOOM ) { if( InstallBlockCmdFrame( this, _( "Block Operation" ) ) == false ) { cancelCmd = true; // undraw block outline if( DC ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); } else { DrawAndSizingBlockOutlines( m_canvas, DC, wxDefaultPosition, false ); Block_SelectItems(); // Exit if no items found if( !GetScreen()->m_BlockLocate.GetCount() ) cancelCmd = true; } } if( !cancelCmd && m_canvas->IsMouseCaptured() ) { switch( GetScreen()->m_BlockLocate.GetCommand() ) { case BLOCK_IDLE: DisplayError( this, wxT( "Error in HandleBlockPLace" ) ); break; case BLOCK_DRAG: // Drag (not used, for future enhancements) case BLOCK_MOVE: // Move case BLOCK_DUPLICATE: // Duplicate case BLOCK_DUPLICATE_AND_INCREMENT: // Duplicate and increment relevant references case BLOCK_PRESELECT_MOVE: // Move with preselection list GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE ); nextcmd = true; m_canvas->SetMouseCaptureCallback( drawMovingBlock ); if( DC ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); break; case BLOCK_DELETE: // Delete m_canvas->SetMouseCaptureCallback( NULL ); GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP ); Block_Delete(); break; case BLOCK_ROTATE: // Rotation m_canvas->SetMouseCaptureCallback( NULL ); GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP ); Block_Rotate(); break; case BLOCK_FLIP: // Flip m_canvas->SetMouseCaptureCallback( NULL ); GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP ); Block_Flip(); break; case BLOCK_COPY: // Copy GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP ); if( GetScreen()->m_BlockLocate.GetCount() ) { // @todo (if useful) Save_Block( ); } break; case BLOCK_PASTE: break; case BLOCK_ZOOM: // Window Zoom // Turn off the redraw block routine now so it is not displayed // with one corner at the new center of the screen m_canvas->SetMouseCaptureCallback( NULL ); Window_Zoom( GetScreen()->m_BlockLocate ); break; default: break; } } if( ! nextcmd ) { GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST; GetScreen()->ClearBlockCommand(); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } return nextcmd; }
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) { unsigned itmp; if( aTrack == NULL ) { if( getActiveLayer() != ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ) setActiveLayer( ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ); else setActiveLayer(((PCB_SCREEN*)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 SEGVIA* via = new SEGVIA( GetBoard() ); via->SetFlags( IS_NEW ); via->SetShape( GetDesignSettings().m_CurrentViaType ); via->SetWidth( GetBoard()->GetCurrentViaSize()); via->SetNet( GetBoard()->GetHighLightNetCode() ); via->SetEnd( g_CurrentTrackSegment->GetEnd() ); via->SetStart( g_CurrentTrackSegment->GetEnd() ); // Usual via is from copper to component. // layer pair is LAYER_N_BACK and LAYER_N_FRONT. via->SetLayerPair( LAYER_N_BACK, LAYER_N_FRONT ); via->SetDrill( GetBoard()->GetCurrentViaDrill() ); LAYER_NUM first_layer = getActiveLayer(); LAYER_NUM 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->GetShape() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); break; case VIA_MICROVIA: // from external to the near neighbor inner layer { LAYER_NUM last_inner_layer = FIRST_LAYER + (GetBoard()->GetCopperLayerCount() - 2); if ( first_layer == LAYER_N_BACK ) last_layer = LAYER_N_2; else if ( first_layer == LAYER_N_FRONT ) last_layer = last_inner_layer; else if ( first_layer == LAYER_N_2 ) last_layer = LAYER_N_BACK; else if ( first_layer == last_inner_layer ) last_layer = LAYER_N_FRONT; // else error: will be removed later via->SetLayerPair( first_layer, last_layer ); { NETINFO_ITEM* net = GetBoard()->FindNet( via->GetNet() ); via->SetWidth( net->GetMicroViaSize() ); } } 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; }
void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent ) { aEvent.Enable( GetBoard()->m_Modules != NULL ); }
/* Save modules in a library: * param aNewModulesOnly: * true : save modules not already existing in this lib * false: save all modules */ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly ) { wxString fileName = aLibName; wxString path; if( GetBoard()->m_Modules == NULL ) { DisplayInfoMessage( this, FMT_NO_MODULES ); return; } path = wxGetApp().ReturnLastVisitedLibraryPath(); if( !aLibName ) { wxFileDialog dlg( this, FMT_LIBRARY, path, wxEmptyString, wxGetTranslation( LegacyFootprintLibPathWildcard ), wxFD_SAVE ); if( dlg.ShowModal() == wxID_CANCEL ) return; fileName = dlg.GetPath(); } wxFileName fn( fileName ); wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() ); bool lib_exists = wxFileExists( fileName ); if( !aNewModulesOnly && lib_exists ) { wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( fileName ) ); if( !IsOK( this, msg ) ) return; } m_canvas->SetAbortRequest( false ); try { PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); // Delete old library if we're replacing it entirely. if( lib_exists && !aNewModulesOnly ) { pi->FootprintLibDelete( fileName ); lib_exists = false; } if( !lib_exists ) { pi->FootprintLibCreate( fileName ); } if( !aNewModulesOnly ) { for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { pi->FootprintSave( fileName, m ); } } else { for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { if( !Save_Module_In_Library( fileName, m, false, false ) ) break; // Check for request to stop backup (ESCAPE key actuated) if( m_canvas->GetAbortRequest() ) break; } } } catch( IO_ERROR ioe ) { DisplayError( this, ioe.errorText ); return; } }
bool FOOTPRINT_EDIT_FRAME::IsElementVisible( GAL_LAYER_ID aElement ) const { return GetBoard()->IsElementVisible( aElement ); }
void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode, const wxPoint& offset ) { int ux0, uy0, dx, dy, radius, StAngle, EndAngle; LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; MODULE* module = (MODULE*) m_Parent; if( !module ) return; BOARD* brd = GetBoard( ); if( brd->IsLayerVisible( m_Layer ) == false ) return; EDA_COLOR_T color = brd->GetLayerColor( m_Layer ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } ux0 = m_Start.x - offset.x; uy0 = m_Start.y - offset.y; dx = m_End.x - offset.x; dy = m_End.y - offset.y; GRSetDrawMode( DC, draw_mode ); bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED; if( IsCopperLayer( m_Layer ) ) filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED; switch( m_Shape ) { case S_SEGMENT: if( filled ) GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color ); else // SKETCH Mode GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color ); break; case S_CIRCLE: radius = KiROUND( Distance( ux0, uy0, dx, dy ) ); if( filled ) { GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color ); } else // SKETCH Mode { GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color ); GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color ); } break; case S_ARC: radius = KiROUND( Distance( ux0, uy0, dx, dy ) ); StAngle = ArcTangente( dy - uy0, dx - ux0 ); EndAngle = StAngle + m_Angle; if( !panel->GetPrintMirrored() ) { if( StAngle > EndAngle ) std::swap( StAngle, EndAngle ); } else // Mirrored mode: arc orientation is reversed { if( StAngle < EndAngle ) std::swap( StAngle, EndAngle ); } if( filled ) { GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color ); } else // SKETCH Mode { GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius + (m_Width / 2), color ); GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius - (m_Width / 2), color ); } break; case S_POLYGON: { // We must compute true coordinates from m_PolyPoints // which are relative to module position, orientation 0 std::vector<wxPoint> points = m_PolyPoints; for( unsigned ii = 0; ii < points.size(); ii++ ) { wxPoint& pt = points[ii]; RotatePoint( &pt.x, &pt.y, module->GetOrientation() ); pt += module->GetPosition() - offset; } GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color ); } break; default: break; } }
void FOOTPRINT_EDIT_FRAME::SetElementVisibility( GAL_LAYER_ID aElement, bool aNewState ) { GetGalCanvas()->GetView()->SetLayerVisible( aElement , aNewState ); GetBoard()->SetElementVisibility( aElement, aNewState ); m_Layers->SetRenderState( aElement, aNewState ); }
/** * Function buildBoard3DAuxLayers * Called by CreateDrawGL_List() * Fills the OpenGL GL_ID_BOARD draw list with items * on aux layers only */ void EDA_3D_CANVAS::buildBoard3DAuxLayers( REPORTER* aErrorMessages, REPORTER* aActivity ) { const int segcountforcircle = 18; double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2) ); BOARD* pcb = GetBoard(); SHAPE_POLY_SET bufferPolys; static const LAYER_ID sequence[] = { Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, Margin }; for( LSEQ aux( sequence, sequence+DIM(sequence) ); aux; ++aux ) { LAYER_ID layer = *aux; if( !is3DLayerEnabled( layer ) ) continue; if( aActivity ) aActivity->Report( wxString::Format( _( "Build layer %s" ), LSET::Name( layer ) ) ); bufferPolys.RemoveAllContours(); for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() ) { if( !item->IsOnLayer( layer ) ) continue; switch( item->Type() ) { case PCB_LINE_T: ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( bufferPolys, 0, segcountforcircle, correctionFactor ); break; case PCB_TEXT_T: ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( bufferPolys, 0, segcountforcircle, correctionFactor ); break; default: break; } } for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) { module->TransformPadsShapesWithClearanceToPolygon( layer, bufferPolys, 0, segcountforcircle, correctionFactor ); module->TransformGraphicShapesWithClearanceToPolygonSet( layer, bufferPolys, 0, segcountforcircle, correctionFactor ); } // bufferPolys contains polygons to merge. Many overlaps . // Calculate merged polygons and remove pads and vias holes if( bufferPolys.IsEmpty() ) continue; bufferPolys.Simplify( polygonsCalcMode ); int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer ); int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer ); // for Draw3D_SolidHorizontalPolyPolygons, // zpos it the middle between bottom and top sides. // However for top layers, zpos should be the bottom layer pos, // and for bottom layers, zpos should be the top layer pos. if( Get3DLayer_Z_Orientation( layer ) > 0 ) zpos += thickness/2; else zpos -= thickness/2 ; float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted) // If we are not using thickness, then the znormal must face the layer direction // because it will draw just one plane if( !thickness ) zNormal = Get3DLayer_Z_Orientation( layer ); setGLTechLayersColor( layer ); Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, GetPrm3DVisu().m_BiuTo3Dunits, false, zNormal ); } }
/* Handle the left button mouse click, when a tool is active */ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { BOARD_ITEM* DrawStruct = GetCurItem(); bool exit = false; bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED; if( no_tool || ( DrawStruct && DrawStruct->GetFlags() ) ) { m_canvas->SetAutoPanRequest( false ); if( DrawStruct && DrawStruct->GetFlags() ) // Command in progress { m_canvas->SetIgnoreMouseEvents( true ); m_canvas->CrossHairOff( aDC ); switch( DrawStruct->Type() ) { case PCB_ZONE_AREA_T: if( DrawStruct->IsNew() ) { m_canvas->SetAutoPanRequest( true ); Begin_Zone( aDC ); } else { End_Move_Zone_Corner_Or_Outlines( aDC, (ZONE_CONTAINER*) DrawStruct ); } exit = true; break; case PCB_TRACE_T: case PCB_VIA_T: if( DrawStruct->IsDragging() ) { PlaceDraggedOrMovedTrackSegment( (TRACK*) DrawStruct, aDC ); exit = true; } break; case PCB_TEXT_T: Place_Texte_Pcb( (TEXTE_PCB*) DrawStruct, aDC ); exit = true; break; case PCB_MODULE_TEXT_T: PlaceTexteModule( (TEXTE_MODULE*) DrawStruct, aDC ); exit = true; break; case PCB_PAD_T: PlacePad( (D_PAD*) DrawStruct, aDC ); exit = true; break; case PCB_MODULE_T: PlaceModule( (MODULE*) DrawStruct, aDC ); exit = true; break; case PCB_TARGET_T: PlaceTarget( (PCB_TARGET*) DrawStruct, aDC ); exit = true; break; case PCB_LINE_T: if( no_tool ) // when no tools: existing item moving. { Place_DrawItem( (DRAWSEGMENT*) DrawStruct, aDC ); exit = true; } break; case PCB_DIMENSION_T: if( ! DrawStruct->IsNew() ) { // We are moving the text of an existing dimension. Place it PlaceDimensionText( (DIMENSION*) DrawStruct, aDC ); exit = true; } break; default: DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() err: DrawType %d m_Flags != 0" ), DrawStruct->Type() ); exit = true; break; } m_canvas->SetIgnoreMouseEvents( false ); m_canvas->CrossHairOn( aDC ); if( exit ) return; } else if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT ) && !wxGetKeyState( WXK_CONTROL ) ) { DrawStruct = PcbGeneralLocateAndDisplay(); if( DrawStruct ) SendMessageToEESCHEMA( DrawStruct ); } } if( DrawStruct ) // display netclass info for zones, tracks and pads { switch( DrawStruct->Type() ) { case PCB_ZONE_AREA_T: case PCB_TRACE_T: case PCB_VIA_T: case PCB_PAD_T: GetDesignSettings().SetCurrentNetClass( ((BOARD_CONNECTED_ITEM*)DrawStruct)->GetNetClassName() ); updateTraceWidthSelectBox(); updateViaSizeSelectBox(); break; default: break; } } switch( GetToolId() ) { case ID_MAIN_MENUBAR: case ID_NO_TOOL_SELECTED: break; case ID_PCB_MUWAVE_TOOL_SELF_CMD: case ID_PCB_MUWAVE_TOOL_GAP_CMD: case ID_PCB_MUWAVE_TOOL_STUB_CMD: case ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD: case ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD: MuWaveCommand( aDC, aPosition ); break; case ID_PCB_HIGHLIGHT_BUTT: { int netcode = SelectHighLight( aDC ); if( netcode < 0 ) SetMsgPanel( GetBoard() ); else { NETINFO_ITEM* net = GetBoard()->FindNet( netcode ); if( net ) { MSG_PANEL_ITEMS items; net->GetMsgPanelInfo( items ); SetMsgPanel( items ); } } } break; case ID_PCB_SHOW_1_RATSNEST_BUTT: DrawStruct = PcbGeneralLocateAndDisplay(); Show_1_Ratsnest( DrawStruct, aDC ); if( DrawStruct ) SendMessageToEESCHEMA( DrawStruct ); break; case ID_PCB_MIRE_BUTT: if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { SetCurItem( (BOARD_ITEM*) CreateTarget( aDC ) ); m_canvas->MoveCursorToCrossHair(); } else if( DrawStruct->Type() == PCB_TARGET_T ) { PlaceTarget( (PCB_TARGET*) DrawStruct, aDC ); } else { DisplayError( this, wxT( "OnLeftClick err: not a PCB_TARGET_T" ) ); } break; case ID_PCB_CIRCLE_BUTT: case ID_PCB_ARC_BUTT: case ID_PCB_ADD_LINE_BUTT: { STROKE_T shape = S_SEGMENT; if( GetToolId() == ID_PCB_CIRCLE_BUTT ) shape = S_CIRCLE; if( GetToolId() == ID_PCB_ARC_BUTT ) shape = S_ARC; if( IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Graphic not allowed on Copper layers" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) Begin_DrawSegment( NULL, shape, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && (DrawStruct->Type() == PCB_LINE_T) && DrawStruct->IsNew() ) { DrawStruct = (BOARD_ITEM*) Begin_DrawSegment( (DRAWSEGMENT*) DrawStruct, shape, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } } break; case ID_TRACK_BUTT: if( !IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Tracks on Copper layers only " ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) Begin_Route( NULL, aDC ); SetCurItem( DrawStruct ); if( DrawStruct ) m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && DrawStruct->IsNew() ) { TRACK* track = Begin_Route( (TRACK*) DrawStruct, aDC ); // SetCurItem() must not write to the msg panel // because a track info is displayed while moving the mouse cursor if( track ) // A new segment was created SetCurItem( DrawStruct = (BOARD_ITEM*) track, false ); m_canvas->SetAutoPanRequest( true ); } break; case ID_PCB_ZONES_BUTT: case ID_PCB_KEEPOUT_AREA_BUTT: /* ZONE or KEEPOUT Tool is selected. Determine action for a left click: * this can be start a new zone or select and move an existing zone outline corner * if found near the mouse cursor */ if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { if( Begin_Zone( aDC ) ) { m_canvas->SetAutoPanRequest( true ); DrawStruct = GetBoard()->m_CurrentZoneContour; GetScreen()->SetCurItem( DrawStruct ); } } else if( DrawStruct && (DrawStruct->Type() == PCB_ZONE_AREA_T) && DrawStruct->IsNew() ) { // Add a new corner to the current outline being created: m_canvas->SetAutoPanRequest( true ); Begin_Zone( aDC ); DrawStruct = GetBoard()->m_CurrentZoneContour; GetScreen()->SetCurItem( DrawStruct ); } else { DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() zone internal error" ) ); } break; case ID_PCB_ADD_TEXT_BUTT: if( IsLayerInList( EDGE_LAYER, GetActiveLayer() ) ) { DisplayError( this, _( "Texts not allowed on Edge Cut layer" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { SetCurItem( CreateTextePcb( aDC ) ); m_canvas->MoveCursorToCrossHair(); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct->Type() == PCB_TEXT_T ) { Place_Texte_Pcb( (TEXTE_PCB*) DrawStruct, aDC ); m_canvas->SetAutoPanRequest( false ); } else { DisplayError( this, wxT( "OnLeftClick err: not a PCB_TEXT_T" ) ); } break; case ID_PCB_MODULE_BUTT: if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { m_canvas->MoveCursorToCrossHair(); DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary( wxEmptyString, Prj().PcbFootprintLibs(), true, aDC ); SetCurItem( DrawStruct ); if( DrawStruct ) StartMoveModule( (MODULE*) DrawStruct, aDC, false ); } else if( DrawStruct->Type() == PCB_MODULE_T ) { PlaceModule( (MODULE*) DrawStruct, aDC ); m_canvas->SetAutoPanRequest( false ); } else { DisplayError( this, wxT( "Internal err: Struct not PCB_MODULE_T" ) ); } break; case ID_PCB_DIMENSION_BUTT: if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, GetActiveLayer() ) ) { DisplayError( this, _( "Dimension not allowed on Copper or Edge Cut layers" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) EditDimension( NULL, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && (DrawStruct->Type() == PCB_DIMENSION_T) && DrawStruct->IsNew() ) { DrawStruct = (BOARD_ITEM*) EditDimension( (DIMENSION*) DrawStruct, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else { DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() error item is not a DIMENSION" ) ); } break; case ID_PCB_DELETE_ITEM_BUTT: if( !DrawStruct || !DrawStruct->GetFlags() ) { DrawStruct = PcbGeneralLocateAndDisplay(); if( DrawStruct && (DrawStruct->GetFlags() == 0) ) { RemoveStruct( DrawStruct, aDC ); SetCurItem( DrawStruct = NULL ); } } break; case ID_PCB_PLACE_OFFSET_COORD_BUTT: m_canvas->DrawAuxiliaryAxis( aDC, GR_XOR ); SetAuxOrigin( GetCrossHairPosition() ); m_canvas->DrawAuxiliaryAxis( aDC, GR_COPY ); OnModify(); break; case ID_PCB_PLACE_GRID_COORD_BUTT: m_canvas->DrawGridAxis( aDC, GR_XOR, GetBoard()->GetGridOrigin() ); SetGridOrigin( GetCrossHairPosition() ); m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() ); break; default: DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); break; } }
void EDA_3D_CANVAS::calcBBox() { BOARD* pcb = GetBoard(); m_fastAABBox.Reset(); for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) { CBBOX tmpFastAABBox; // Compute the transformation matrix for this module based on translation, rotation and orientation. float zpos = GetPrm3DVisu().GetModulesZcoord3DIU( module->IsFlipped() ); wxPoint pos = module->GetPosition(); glm::mat4 fullTransformMatrix; fullTransformMatrix = glm::translate( glm::mat4(), S3D_VERTEX( (float)(pos.x * GetPrm3DVisu().m_BiuTo3Dunits), (float)(-pos.y * GetPrm3DVisu().m_BiuTo3Dunits), zpos ) ); if( module->GetOrientation() ) fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( (float)(module->GetOrientation() / 10.0f) ), S3D_VERTEX( 0.0f, 0.0f, 1.0f ) ); if( module->IsFlipped() ) { fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 1.0f, 0.0f ) ); fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 0.0f, 1.0f ) ); } // Compute a union bounding box for all the shapes of the model S3D_MASTER* shape3D = module->Models(); for( ; shape3D; shape3D = shape3D->Next() ) { if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) ) tmpFastAABBox.Union( shape3D->getFastAABBox() ); } tmpFastAABBox.ApplyTransformationAA( fullTransformMatrix ); m_fastAABBox.Union( tmpFastAABBox ); } // Create a board bounding box based on board size wxSize brd_size = getBoardSize(); wxPoint brd_center_pos = getBoardCenter(); float xsize = brd_size.x; float ysize = brd_size.y; float scale = GetPrm3DVisu().m_BiuTo3Dunits; float xmin = (brd_center_pos.x - xsize / 2.0) * scale; float xmax = (brd_center_pos.x + xsize / 2.0) * scale; float ymin = (brd_center_pos.y - ysize / 2.0) * scale; float ymax = (brd_center_pos.y + ysize / 2.0) * scale; float zmin = GetPrm3DVisu().GetLayerZcoordBIU( B_Adhes ) * scale; float zmax = GetPrm3DVisu().GetLayerZcoordBIU( F_Adhes ) * scale; m_boardAABBox = CBBOX( S3D_VERTEX(xmin, ymin, zmin), S3D_VERTEX(xmax, ymax, zmax) ); // Add BB board with BB models and scale it a bit m_fastAABBox.Union( m_boardAABBox ); m_fastAABBox_Shadow = m_fastAABBox; m_fastAABBox_Shadow.Scale( SHADOW_BOUNDING_BOX_SCALE ); }
int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) { int errorLevel = 0; int areaCount = GetBoard()->GetAreaCount(); wxBusyCursor dummyCursor; wxString msg; wxProgressDialog * progressDialog = NULL; // Create a message with a long net name, and build a wxProgressDialog // with a correct size to show this long net name msg.Printf( FORMAT_STRING, 000, areaCount, wxT("XXXXXXXXXXXXXXXXX" ) ); if( aActiveWindow ) progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg, areaCount+2, aActiveWindow, wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_ELAPSED_TIME ); // Display the actual message if( progressDialog ) progressDialog->Update( 0, _( "Starting zone fill..." ) ); // Remove segment zones GetBoard()->m_Zone.DeleteAll(); int ii; for( ii = 0; ii < areaCount; ii++ ) { ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii ); if( zoneContainer->GetIsKeepout() ) continue; msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ) ); if( progressDialog ) { if( !progressDialog->Update( ii+1, msg ) ) break; // Aborted by user } errorLevel = Fill_Zone( zoneContainer ); if( errorLevel && !aVerbose ) break; } if( progressDialog ) { progressDialog->Update( ii+2, _( "Updating ratsnest..." ) ); #ifdef __WXMAC__ // Work around a dialog z-order issue on OS X aActiveWindow->Raise(); #endif } TestConnections(); // Recalculate the active ratsnest, i.e. the unconnected links TestForActiveLinksInRatsnest( 0 ); if( progressDialog ) progressDialog->Destroy(); return errorLevel; }
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::RemoveMisConnectedTracks() { /* finds all track segments which are mis-connected (to more than one net). * When such a bad segment is found, it is flagged to be removed. * All tracks having at least one flagged segment are removed. */ TRACK* segment; TRACK* other; TRACK* next; int net_code_s, net_code_e; bool isModified = false; for( segment = GetBoard()->m_Track; segment; segment = (TRACK*) segment->Next() ) { segment->SetState( FLAG0, false ); // find the netcode for segment using anything connected to the "start" of "segment" net_code_s = -1; if( segment->start && segment->start->Type()==PCB_PAD_T ) { // get the netcode of the pad to propagate. net_code_s = ((D_PAD*)(segment->start))->GetNetCode(); } else { other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); if( other ) net_code_s = other->GetNetCode(); } if( net_code_s < 0 ) continue; // the "start" of segment is not connected // find the netcode for segment using anything connected to the "end" of "segment" net_code_e = -1; if( segment->end && segment->end->Type()==PCB_PAD_T ) { net_code_e = ((D_PAD*)(segment->end))->GetNetCode(); } else { other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); if( other ) net_code_e = other->GetNetCode(); } if( net_code_e < 0 ) continue; // the "end" of segment is not connected // Netcodes do not agree, so mark the segment as "to be removed" if( net_code_s != net_code_e ) { segment->SetState( FLAG0, true ); } } // Remove tracks having a flagged segment for( segment = GetBoard()->m_Track; segment; segment = next ) { next = (TRACK*) segment->Next(); if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed { segment->SetState( FLAG0, false ); isModified = true; GetBoard()->m_Status_Pcb = 0; Remove_One_Track( NULL, segment ); // the current segment is deleted, // we do not know the next "not yet tested" segment, // so restart to the beginning next = GetBoard()->m_Track; } } return isModified; }
void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event ) { NETINFO_ITEM* net; wxString netFilter; wxArrayString list; netFilter = wxT( "*" ); wxTextEntryDialog dlg( this, _( "Filter Net Names" ), _( "Net Filter" ), netFilter ); if( dlg.ShowModal() != wxID_OK ) return; // cancelled by user netFilter = dlg.GetValue( ); if( netFilter.IsEmpty() ) return; wxString Line; for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ ) { net = GetBoard()->m_NetInfo.GetNetItem( ii ); if( !WildCompareString( netFilter, net->GetNetname(), false ) ) continue; Line.Printf( wxT( "net %3.3d: %s" ), net->GetNet(), GetChars( net->GetNetname() ) ); list.Add( Line ); } wxSingleChoiceDialog choiceDlg( this, wxEmptyString, _( "Select Net" ), list ); if( (choiceDlg.ShowModal() == wxID_CANCEL) || (choiceDlg.GetSelection() == wxNOT_FOUND) ) return; bool found = false; unsigned netcode = (unsigned) choiceDlg.GetSelection(); // Search for the net selected. for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ ) { net = GetBoard()->FindNet( ii ); if( !WildCompareString( netFilter, net->GetNetname(), false ) ) continue; if( ii == netcode ) { netcode = net->GetNet(); found = true; break; } } if( found ) { INSTALL_UNBUFFERED_DC( dc, m_canvas ); if( GetBoard()->IsHighLightNetON() ) HighLight( &dc ); GetBoard()->SetHighLightNet( netcode ); HighLight( &dc ); } }
void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC ) { D_PAD* pt_pad = NULL; MODULE* Module = NULL; if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) ) return; if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 ) Compile_Ratsnest( DC, true ); if( item ) { if( item->Type() == PCB_PAD_T ) { pt_pad = (D_PAD*) item; Module = (MODULE*) pt_pad->GetParent(); } if( pt_pad ) // Displaying the ratsnest of the corresponding net. { SetMsgPanel( pt_pad ); for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) { RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; if( net->GetNet() == pt_pad->GetNet() ) { if( ( net->m_Status & CH_VISIBLE ) != 0 ) continue; net->m_Status |= CH_VISIBLE; if( ( net->m_Status & CH_ACTIF ) == 0 ) continue; net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) ); } } } else { if( item->Type() == PCB_MODULE_TEXT_T ) { if( item->GetParent() && ( item->GetParent()->Type() == PCB_MODULE_T ) ) Module = (MODULE*) item->GetParent(); } else if( item->Type() == PCB_MODULE_T ) { Module = (MODULE*) item; } if( Module ) { SetMsgPanel( Module ); pt_pad = Module->Pads(); for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Next() ) { for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) { RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; if( ( net->m_PadStart == pt_pad ) || ( net->m_PadEnd == pt_pad ) ) { if( net->m_Status & CH_VISIBLE ) continue; net->m_Status |= CH_VISIBLE; if( (net->m_Status & CH_ACTIF) == 0 ) continue; net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) ); } } } pt_pad = NULL; } } } // Erase if no pad or module has been selected. if( ( pt_pad == NULL ) && ( Module == NULL ) ) { DrawGeneralRatsnest( DC ); for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE; } }
MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() { // use the clipboard for this in the future? // Some day it might be useful save the last library type selected along with the path. static int lastFilterIndex = 0; wxString lastOpenedPathForLoading = m_mruPath; wxConfigBase* config = Kiface().KifaceSettings(); if( config ) config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading ); wxString wildCard; wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' ) << wxGetTranslation( ModLegacyExportFileWildcard ) << wxChar( '|' ) << wxGetTranslation( ModImportFileWildcard ) << wxChar( '|' ) << wxGetTranslation( GedaPcbFootprintLibFileWildcard ); wxFileDialog dlg( this, FMT_IMPORT_MODULE, lastOpenedPathForLoading, wxEmptyString, wildCard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); dlg.SetFilterIndex( lastFilterIndex ); if( dlg.ShowModal() == wxID_CANCEL ) return NULL; lastFilterIndex = dlg.GetFilterIndex(); FILE* fp = wxFopen( dlg.GetPath(), wxT( "rt" ) ); if( !fp ) { wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); return NULL; } if( config ) // Save file path { lastOpenedPathForLoading = wxPathOnly( dlg.GetPath() ); config->Write( EXPORT_IMPORT_LASTPATH_KEY, lastOpenedPathForLoading ); } wxString moduleName; bool isGeda = false; bool isLegacy = false; { FILE_LINE_READER freader( fp, dlg.GetPath() ); // I own fp, and will close it. WHITESPACE_FILTER_READER reader( freader ); // skip blank lines reader.ReadLine(); char* line = reader.Line(); if( !strnicmp( line, "(module", 7 ) ) { // isKicad = true; } else if( !strnicmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) ) { isLegacy = true; while( reader.ReadLine() ) { if( !strnicmp( line, "$MODULE", 7 ) ) { moduleName = FROM_UTF8( StrPurge( line + sizeof( "$MODULE" ) -1 ) ); break; } } } else if( !strnicmp( line, "Element", 7 ) ) { isGeda = true; } else { DisplayError( this, FMT_NOT_MODULE ); return NULL; } // fp is closed here by ~FILE_LINE_READER() } MODULE* module; if( isGeda ) { try { wxFileName fn = dlg.GetPath(); PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::GEDA_PCB ) ); moduleName = fn.GetName(); module = pi->FootprintLoad( fn.GetPath(), moduleName ); if( !module ) { wxString msg = wxString::Format( FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( fn.GetPath() ) ); DisplayError( this, msg ); return NULL; } } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; } } else if( isLegacy ) { try { PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); module = pi->FootprintLoad( dlg.GetPath(), moduleName ); if( !module ) { wxString msg = wxString::Format( FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); return NULL; } } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; } } else // if( isKicad ) { try { // This technique was chosen to create an example of how reading // the s-expression format from clipboard could be done. wxString fcontents; PCB_IO pcb_io; wxFFile f( dlg.GetPath() ); if( !f.IsOpened() ) { wxString msg = wxString::Format( FMT_BAD_PATH, GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); return NULL; } f.ReadAll( &fcontents ); module = dyn_cast<MODULE*>( pcb_io.Parse( fcontents ) ); if( !module ) { wxString msg = wxString::Format( FMT_BAD_PATH, GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); return NULL; } } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return NULL; } } // Insert footprint in list GetBoard()->Add( module ); // Display info : SetMsgPanel( module ); PlaceModule( module, NULL ); if( IsGalCanvasActive() ) module->SetPosition( wxPoint( 0, 0 ) ); GetBoard()->m_Status_Pcb = 0; GetBoard()->BuildListOfNets(); updateView(); return module; }
bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl ) { IO_MGR::PCB_FILE_T pluginType = plugin_type( aFullFileName, aCtl ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); // keep trace of existing items, in order to know what are the new items // (for undo command for instance) // Tracks are inserted, not append, so mark existing tracks to know what are // the new tracks for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) track->SetFlags( FLAG0 ); // Other items are append to the item list, so keep trace to the // last existing item is enough MODULE* module = GetBoard()->m_Modules.GetLast(); BOARD_ITEM* drawing = GetBoard()->DrawingsList().GetLast(); int zonescount = GetBoard()->GetAreaCount(); // Keep also the count of copper layers, because we can happen boards // with different copper layers counts, // and the enabled layers int initialCopperLayerCount = GetBoard()->GetCopperLayerCount(); LSET initialEnabledLayers = GetBoard()->GetEnabledLayers(); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; GetDesignSettings().m_NetClasses.Clear(); pi->Load( aFullFileName, GetBoard(), &props ); } catch( const IO_ERROR& ioe ) { for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) { track->ClearFlags( FLAG0 ); } DisplayErrorMessage( this, _( "Error loading board in AppendBoardFile" ), ioe.What() ); return false; } // Now prepare a block move command to place the new items, and // prepare the undo command. BLOCK_SELECTOR& blockmove = GetScreen()->m_BlockLocate; HandleBlockBegin( NULL, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) ); PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems(); PICKED_ITEMS_LIST undoListPicker; ITEM_PICKER picker( NULL, UR_NEW ); EDA_RECT bbox; // the new items bounding box, for block move bool bboxInit = true; // true until the bounding box is initialized for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) { if( track->GetFlags() & FLAG0 ) { track->ClearFlags( FLAG0 ); continue; } track->SetFlags( IS_MOVED ); picker.SetItem( track ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = track->GetBoundingBox(); else bbox.Merge( track->GetBoundingBox() ); bboxInit = false; } if( module ) module = module->Next(); else module = GetBoard()->m_Modules; for( ; module; module = module->Next() ) { module->SetFlags( IS_MOVED ); picker.SetItem( module ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = module->GetBoundingBox(); else bbox.Merge( module->GetBoundingBox() ); bboxInit = false; } if( drawing ) drawing = drawing->Next(); else drawing = GetBoard()->DrawingsList(); for( ; drawing; drawing = drawing->Next() ) { drawing->SetFlags( IS_MOVED ); picker.SetItem( drawing ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = drawing->GetBoundingBox(); else bbox.Merge( drawing->GetBoundingBox() ); bboxInit = false; } for( ZONE_CONTAINER* zone = GetBoard()->GetArea( zonescount ); zone; zone = GetBoard()->GetArea( zonescount ) ) { zone->SetFlags( IS_MOVED ); picker.SetItem( zone ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); zonescount++; if( bboxInit ) bbox = zone->GetBoundingBox(); else bbox.Merge( zone->GetBoundingBox() ); bboxInit = false; } SaveCopyInUndoList( undoListPicker, UR_NEW ); // we should not ask PLUGINs to do these items: int copperLayerCount = GetBoard()->GetCopperLayerCount(); if( copperLayerCount > initialCopperLayerCount ) GetBoard()->SetCopperLayerCount( copperLayerCount ); // Enable all used layers, and make them visible: LSET enabledLayers = GetBoard()->GetEnabledLayers(); enabledLayers |= initialEnabledLayers; GetBoard()->SetEnabledLayers( enabledLayers ); GetBoard()->SetVisibleLayers( enabledLayers ); ReCreateLayerBox(); ReFillLayerWidget(); if( IsGalCanvasActive() ) static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() ); GetBoard()->BuildListOfNets(); GetBoard()->SynchronizeNetsAndNetClasses(); SetStatusText( wxEmptyString ); BestZoom(); // Finish block move command: wxPoint cpos = GetNearestGridPosition( bbox.Centre() ); blockmove.SetOrigin( bbox.GetOrigin() ); blockmove.SetSize( bbox.GetSize() ); blockmove.SetLastCursorPosition( cpos ); HandleBlockEnd( NULL ); return true; }