bool GERBVIEW_FRAME::Clear_Pcb( bool query ) { int layer; if( GetLayout() == NULL ) return false; if( query && GetScreen()->IsModify() ) { if( !IsOK( this, _( "Current data will be lost?" ) ) ) return false; } GetLayout()->m_Drawings.DeleteAll(); for( layer = 0; layer < GERBVIEW_LAYER_COUNT; layer++ ) { if( g_GERBER_List[layer] ) { g_GERBER_List[layer]->InitToolTable(); g_GERBER_List[layer]->ResetDefaultValues(); } } GetLayout()->SetBoundingBox( EDA_RECT() ); SetScreen( new GBR_SCREEN( GetPageSettings().GetSizeIU() ) ); setActiveLayer(0); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); return true; }
/* Selects the active layer: * - if a file is loaded, it is loaded in this layer * _ this layer is displayed on top of other layers */ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) { int layer = getActiveLayer(); setActiveLayer( event.GetSelection() ); if( layer != getActiveLayer() ) m_canvas->Refresh(); }
/* Selects the active layer: * - if a file is loaded, it is loaded in this layer * _ this layer is displayed on top of other layers */ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) { LAYER_NUM layer = getActiveLayer(); setActiveLayer( event.GetSelection() ); if( layer != getActiveLayer() ) { if( m_LayersManager->OnLayerSelected() ) m_canvas->Refresh(); } }
bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // The current project path is also a valid command parameter. Check if a single path // rather than a file name was passed to GerbView and use it as the initial MRU path. if( aFileSet.size() > 0 ) { wxString path = aFileSet[0]; // For some reason wxApp appears to leave the trailing double quote on quoted // parameters which are required for paths with spaces. Maybe this should be // pushed back into PGM_SINGLE_TOP::OnPgmInit() but that may cause other issues. // We can't buy a break! if( path.Last() == wxChar( '\"' ) ) path.RemoveLast(); if( !wxFileExists( path ) && wxDirExists( path ) ) { wxLogDebug( wxT( "MRU path: %s." ), GetChars( path ) ); m_mruPath = path; return true; } const unsigned limit = std::min( unsigned( aFileSet.size() ), unsigned( GERBER_DRAWLAYERS_COUNT ) ); int layer = 0; for( unsigned i=0; i<limit; ++i, ++layer ) { setActiveLayer( layer ); // Try to guess the type of file by its ext // if it is .drl (Kicad files), it is a drill file wxFileName fn( aFileSet[i] ); wxString ext = fn.GetExt(); if( ext == "drl" ) LoadExcellonFiles( aFileSet[i] ); else LoadGerberFiles( aFileSet[i] ); } } Zoom_Automatique( true ); // Zoom fit in frame UpdateTitleAndInfo(); return true; }
bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { const unsigned limit = std::min( unsigned( aFileSet.size() ), unsigned( GERBER_DRAWLAYERS_COUNT ) ); int layer = 0; for( unsigned i=0; i<limit; ++i, ++layer ) { setActiveLayer( layer ); LoadGerberFiles( aFileSet[i] ); } Zoom_Automatique( true ); // Zoom fit in frame UpdateTitleAndInfo(); return true; }
bool GERBVIEW_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition, EDA_ITEM* aItem ) { #define CHANGE( x ) ( x ) = not (x ) wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); /* Convert lower to upper case (the usual toupper function has problem with non ascii * codes like function keys */ if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') ) aHotkeyCode += 'A' - 'a'; EDA_HOTKEY * HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, gerbviewHotkeyList ); if( HK_Descr == NULL ) return false; switch( HK_Descr->m_Idcommand ) { default: case HK_NOT_FOUND: return false; case HK_HELP: // Display Current hotkey list DisplayHotkeyList( this, GerbviewHokeysDescr ); break; case HK_ZOOM_IN: cmd.SetId( ID_POPUP_ZOOM_IN ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_OUT: cmd.SetId( ID_POPUP_ZOOM_OUT ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_REDRAW: cmd.SetId( ID_ZOOM_REDRAW ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_CENTER: cmd.SetId( ID_POPUP_ZOOM_CENTER ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_AUTO: cmd.SetId( ID_ZOOM_PAGE ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_RESET_LOCAL_COORD: // Reset the relative coord GetScreen()->m_O_Curseur = GetCrossHairPosition(); break; case HK_SWITCH_UNITS: g_UserUnit = (g_UserUnit == INCHES ) ? MILLIMETRES : INCHES; break; case HK_GBR_LINES_DISPLAY_MODE: CHANGE( m_DisplayOptions.m_DisplayLinesFill ); m_canvas->Refresh(); break; case HK_GBR_FLASHED_DISPLAY_MODE: CHANGE( m_DisplayOptions.m_DisplayFlashedItemsFill ); m_canvas->Refresh( true ); break; case HK_GBR_POLYGON_DISPLAY_MODE: CHANGE( m_DisplayOptions.m_DisplayPolygonsFill ); m_canvas->Refresh(); break; case HK_GBR_NEGATIVE_DISPLAY_ONOFF: SetElementVisibility( LAYER_NEGATIVE_OBJECTS, not IsElementVisible( LAYER_NEGATIVE_OBJECTS ) ); m_canvas->Refresh(); break; case HK_GBR_DCODE_DISPLAY_ONOFF: SetElementVisibility( LAYER_DCODES, not IsElementVisible( LAYER_DCODES ) ); m_canvas->Refresh(); break; case HK_SWITCH_LAYER_TO_PREVIOUS: if( getActiveLayer() > 0 ) { setActiveLayer( getActiveLayer() - 1 ); m_canvas->Refresh(); } break; case HK_SWITCH_LAYER_TO_NEXT: if( getActiveLayer() < 31 ) { setActiveLayer( getActiveLayer() + 1 ); m_canvas->Refresh(); } break; } return true; }
GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ): EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME ) { m_colorsSettings = &g_ColorsSettings; m_gerberLayout = NULL; m_zoomLevelCoeff = ZOOM_FACTOR( 110 ); // Adjusted to roughly displays zoom level = 1 // when the screen shows a 1:1 image // obviously depends on the monitor, // but this is an acceptable value PAGE_INFO pageInfo( wxT( "GERBER" ) ); SetPageSettings( pageInfo ); m_show_layer_manager_tools = true; m_showAxis = true; // true to show X and Y axis on screen m_showBorderAndTitleBlock = false; // true for reference drawings. m_HotkeysZoomAndGridList = GerbviewHokeysDescr; m_SelLayerBox = NULL; m_DCodeSelector = NULL; m_displayMode = 0; m_drillFileHistory.SetBaseId( ID_GERBVIEW_DRILL_FILE1 ); if( m_canvas ) m_canvas->SetEnableBlockCommands( true ); // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( icon_gerbview_xpm ) ); SetIcon( icon ); SetLayout( new GBR_LAYOUT() ); SetVisibleLayers( -1 ); // All draw layers visible. SetScreen( new GBR_SCREEN( GetPageSettings().GetSizeIU() ) ); // Create the PCB_LAYER_WIDGET *after* SetLayout(): wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); int pointSize = font.GetPointSize(); int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ); if( screenHeight <= 900 ) pointSize = (pointSize * 8) / 10; m_LayersManager = new GERBER_LAYER_WIDGET( this, m_canvas, pointSize ); // LoadSettings() *after* creating m_LayersManager, because LoadSettings() // initialize parameters in m_LayersManager LoadSettings( config() ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); if( m_LastGridSizeId < 0 ) m_LastGridSizeId = 0; if( m_LastGridSizeId > ID_POPUP_GRID_LEVEL_0_0_1MM-ID_POPUP_GRID_LEVEL_1000 ) m_LastGridSizeId = ID_POPUP_GRID_LEVEL_0_0_1MM-ID_POPUP_GRID_LEVEL_1000; GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); ReCreateMenuBar(); ReCreateHToolbar(); ReCreateOptToolbar(); m_auimgr.SetManagedWindow( this ); EDA_PANEINFO horiz; horiz.HorizontalToolbarPane(); EDA_PANEINFO vert; vert.VerticalToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template. // the Layers Manager is floatable, but initially docked at far right EDA_PANEINFO lyrs; lyrs.LayersToolbarPane(); lyrs.MinSize( m_LayersManager->GetBestSize() ); lyrs.BestSize( m_LayersManager->GetBestSize() ); lyrs.Caption( _( "Visibles" ) ); lyrs.TopDockable( false ).BottomDockable( false ); if( m_mainToolBar ) m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) ); if( m_drawToolBar ) m_auimgr.AddPane( m_drawToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right().Row( 1 ) ); m_auimgr.AddPane( m_LayersManager, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 0 ) ); if( m_optionsToolBar ) m_auimgr.AddPane( m_optionsToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() ); if( m_canvas ) m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); if( m_messagePanel ) m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) ); ReFillLayerWidget(); // this is near end because contents establish size m_LayersManager->ReFillRender(); // Update colors in Render after the config is read m_auimgr.Update(); setActiveLayer( 0, true ); Zoom_Automatique( false ); // Gives a default zoom value }
int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) { ZONE_SETTINGS zoneInfo = GetZoneSettings(); // verify if s_CurrentZone exists (could be deleted since last selection) : int ii; for( ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) { if( s_CurrentZone == GetBoard()->GetArea( ii ) ) break; } if( ii >= GetBoard()->GetAreaCount() ) // Not found: could be deleted since last selection { s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; } // If no zone contour in progress, a new zone is being created: if( !GetBoard()->m_CurrentZoneContour ) { if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT && getActiveLayer() >= FIRST_NON_COPPER_LAYER ) { DisplayError( this, _( "Error: a keepout area is allowed only on copper layers" ) ); return 0; } else GetBoard()->m_CurrentZoneContour = new ZONE_CONTAINER( GetBoard() ); } ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour; if( zone->GetNumCorners() == 0 ) // Start a new contour: init zone params (net, layer ...) { if( !s_CurrentZone ) // A new outline is created, from scratch { ZONE_EDIT_T edited; // Init zone params to reasonable values zone->SetLayer( getActiveLayer() ); // Prompt user for parameters: m_canvas->SetIgnoreMouseEvents( true ); if( zone->IsOnCopperLayer() ) { // Put a zone on a copper layer if( GetBoard()->GetHighLightNetCode() > 0 ) { zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode(); zone->SetNet( zoneInfo.m_NetcodeSelection ); zone->SetNetNameFromNetCode( ); } double tmp = ZONE_THERMAL_RELIEF_GAP_MIL; wxGetApp().GetSettings()->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp ); zoneInfo.m_ThermalReliefGap = KiROUND( tmp * IU_PER_MILS); tmp = ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL; wxGetApp().GetSettings()->Read( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ThermalReliefCopperBridge = KiROUND( tmp * IU_PER_MILS ); tmp = ZONE_CLEARANCE_MIL; wxGetApp().GetSettings()->Read( ZONE_CLEARANCE_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ZoneClearance = KiROUND( tmp * IU_PER_MILS ); tmp = ZONE_THICKNESS_MIL; wxGetApp().GetSettings()->Read( ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, &tmp ); zoneInfo.m_ZoneMinThickness = KiROUND( tmp * IU_PER_MILS ); zoneInfo.m_CurrentZone_Layer = zone->GetLayer(); if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT ) { zoneInfo.SetIsKeepout( true ); edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else { zoneInfo.SetIsKeepout( false ); edited = InvokeCopperZonesEditor( this, &zoneInfo ); } } else // Put a zone on a non copper layer (technical layer) { zoneInfo.SetIsKeepout( false ); zoneInfo.m_NetcodeSelection = 0; // No net for non copper zones edited = InvokeNonCopperZonesEditor( this, zone, &zoneInfo ); } m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); if( edited == ZONE_ABORT ) return 0; // Switch active layer to the selected zone layer setActiveLayer( zoneInfo.m_CurrentZone_Layer ); SetZoneSettings( zoneInfo ); } else { // Start a new contour: init zone params (net and layer) from an existing // zone (add cutout or similar zone) zoneInfo.m_CurrentZone_Layer = s_CurrentZone->GetLayer(); setActiveLayer( s_CurrentZone->GetLayer() ); zoneInfo << *s_CurrentZone; SetZoneSettings( zoneInfo ); } // Show the Net for zones on copper layers if( zoneInfo.m_CurrentZone_Layer < FIRST_NO_COPPER_LAYER && ! zoneInfo.GetIsKeepout() ) { if( s_CurrentZone ) { zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNet(); GetBoard()->SetZoneSettings( zoneInfo ); } if( GetBoard()->IsHighLightNetON() ) { HighLight( DC ); // Remove old highlight selection } GetBoard()->SetHighLightNet( zoneInfo.m_NetcodeSelection ); HighLight( DC ); } if( !s_AddCutoutToCurrentZone ) s_CurrentZone = NULL; // the zone is used only once ("add similar zone" command) } // if first segment if( zone->GetNumCorners() == 0 ) { zone->SetFlags( IS_NEW ); zone->SetTimeStamp( GetNewTimeStamp() ); zoneInfo.ExportSetting( *zone ); zone->m_Poly->Start( zoneInfo.m_CurrentZone_Layer, GetScreen()->GetCrossHairPosition().x, GetScreen()->GetCrossHairPosition().y, zone->GetHatchStyle() ); zone->AppendCorner( GetScreen()->GetCrossHairPosition() ); if( Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() ) { zone->ClearFlags(); zone->RemoveAllContours(); // use the form of SetCurItem() which does not write to the msg panel, // SCREEN::SetCurItem(), so the DRC error remains on screen. // PCB_EDIT_FRAME::SetCurItem() calls DisplayInfo(). GetScreen()->SetCurItem( NULL ); DisplayError( this, _( "DRC error: this start point is inside or too close an other area" ) ); return 0; } SetCurItem( zone ); m_canvas->SetMouseCapture( Show_New_Edge_While_Move_Mouse, Abort_Zone_Create_Outline ); } else // edge in progress: { ii = zone->GetNumCorners() - 1; // edge in progress : the current corner coordinate was set // by Show_New_Edge_While_Move_Mouse if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) ) { if( !Drc_On || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) ) { // Ok, we can add a new corner if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxPoint(0,0), false ); zone->AppendCorner( GetScreen()->GetCrossHairPosition() ); SetCurItem( zone ); // calls DisplayInfo(). if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxPoint(0,0), false ); } } } return zone->GetNumCorners(); }
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; }
/* Hot keys. Some commands are relatives to the item under the mouse cursor * Commands are case insensitive * @param DC = current device context * @param hotkey = hotkey code (ascii or wxWidget code for special keys) * @param DrawStruct = NULL or pointer on a EDA_ITEM under the mouse cursor */ void GERBVIEW_FRAME::OnHotKey( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct ) { wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); /* Convert lower to upper case (the usual toupper function has problem with non ascii * codes like function keys */ if( (hotkey >= 'a') && (hotkey <= 'z') ) hotkey += 'A' - 'a'; EDA_HOTKEY * HK_Descr = GetDescriptorFromHotkey( hotkey, s_Gerbview_Hotkey_List ); if( HK_Descr == NULL ) return; switch( HK_Descr->m_Idcommand ) { default: case HK_NOT_FOUND: return; case HK_HELP: // Display Current hotkey list DisplayHotkeyList( this, s_Gerbview_Hokeys_Descr ); break; case HK_ZOOM_IN: cmd.SetId( ID_POPUP_ZOOM_IN ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_OUT: cmd.SetId( ID_POPUP_ZOOM_OUT ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_REDRAW: cmd.SetId( ID_ZOOM_REDRAW ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_CENTER: cmd.SetId( ID_POPUP_ZOOM_CENTER ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_AUTO: cmd.SetId( ID_ZOOM_PAGE ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_RESET_LOCAL_COORD: /*Reset the relative coord */ GetScreen()->m_O_Curseur = GetScreen()->GetCrossHairPosition(); break; case HK_SWITCH_UNITS: g_UserUnit = (g_UserUnit == INCHES ) ? MILLIMETRES : INCHES; break; case HK_SWITCH_GBR_ITEMS_DISPLAY_MODE: DisplayOpt.DisplayPcbTrackFill ^= 1; DisplayOpt.DisplayPcbTrackFill &= 1; m_canvas->Refresh(); break; case HK_SWITCH_LAYER_TO_PREVIOUS: if( getActiveLayer() > 0 ) { setActiveLayer( getActiveLayer() - 1 ); m_canvas->Refresh(); } break; case HK_SWITCH_LAYER_TO_NEXT: if( getActiveLayer() < 31 ) { setActiveLayer( getActiveLayer() + 1 ); m_canvas->Refresh(); } break; } }
bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName ) { wxString filetypes; wxArrayString filenamesList; wxFileName filename = aFullFileName; wxString currentPath; if( !filename.IsOk() ) { filetypes = wxGetTranslation( DrillFileWildcard ); filetypes << wxT("|"); /* All filetypes */ filetypes += wxGetTranslation( AllFilesWildcard ); /* Use the current working directory if the file name path does not exist. */ if( filename.DirExists() ) currentPath = filename.GetPath(); else currentPath = wxGetCwd(); wxFileDialog dlg( this, _( "Open Drill File" ), currentPath, filename.GetFullName(), filetypes, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) return false; dlg.GetPaths( filenamesList ); currentPath = wxGetCwd(); } else { wxFileName filename = aFullFileName; filenamesList.Add( aFullFileName ); currentPath = filename.GetPath(); } // Read gerber files: each file is loaded on a new GerbView layer int layer = getActiveLayer(); for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ ) { wxFileName filename = filenamesList[ii]; if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); m_lastFileName = filename.GetFullPath(); setActiveLayer( layer, false ); if( Read_EXCELLON_File( filename.GetFullPath() ) ) { // Update the list of recentdrill files. UpdateFileHistory( filename.GetFullPath(), &m_drillFileHistory ); layer = getNextAvailableLayer( layer ); if( layer == NO_AVAILABLE_LAYERS ) { wxString msg = wxT( "No more empty layers are available. The remaining gerber " ); msg += wxT( "files will not be loaded." ); wxMessageBox( msg ); break; } setActiveLayer( layer, false ); } } Zoom_Automatique( false ); // Synchronize layers tools with actual active layer: setActiveLayer( getActiveLayer() ); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); return true; }
bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName ) { wxString filetypes; wxArrayString filenamesList; wxFileName filename = aFullFileName; wxString currentPath; if( !filename.IsOk() ) { /* Standard gerber filetypes * (See http://en.wikipedia.org/wiki/Gerber_File) * the .pho extension is the default used in Pcbnew * However there are a lot of other extensions used for gerber files * Because the first letter is usually g, we accept g* as extension * (Mainly internal copper layers do not have specific extention, * and filenames are like *.g1, *.g2 *.gb1 ...). */ filetypes = _( "Gerber files (.g* .lgr .pho)" ); filetypes << wxT("|"); filetypes += wxT("*.g*;*.G*;*.lgr;*.LGR;*.pho;*.PHO" ); filetypes << wxT("|"); /* Special gerber filetypes */ filetypes += _( "Top layer (*.GTL)|*.GTL;*.gtl|" ); filetypes += _( "Bottom layer (*.GBL)|*.GBL;*.gbl|" ); filetypes += _( "Bottom solder resist (*.GBS)|*.GBS;*.gbs|" ); filetypes += _( "Top solder resist (*.GTS)|*.GTS;*.gts|" ); filetypes += _( "Bottom overlay (*.GBO)|*.GBO;*.gbo|" ); filetypes += _( "Top overlay (*.GTO)|*.GTO;*.gto|" ); filetypes += _( "Bottom paste (*.GBP)|*.GBP;*.gbp|" ); filetypes += _( "Top paste (*.GTP)|*.GTP;*.gtp|" ); filetypes += _( "Keep-out layer (*.GKO)|*.GKO;*.gko|" ); filetypes += _( "Mechanical layers (*.GMx)|*.GM1;*.gm1;*.GM2;*.gm2;*.GM3;*.gm3|" ); filetypes += _( "Top Pad Master (*.GPT)|*.GPT;*.gpt|" ); filetypes += _( "Bottom Pad Master (*.GPB)|*.GPB;*.gpb|" ); /* All filetypes */ filetypes += AllFilesWildcard; /* Use the current working directory if the file name path does not exist. */ if( filename.DirExists() ) currentPath = filename.GetPath(); else currentPath = wxGetCwd(); wxFileDialog dlg( this, _( "Open Gerber File" ), currentPath, filename.GetFullName(), filetypes, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR ); if( dlg.ShowModal() == wxID_CANCEL ) return false; dlg.GetPaths( filenamesList ); currentPath = wxGetCwd(); } else { wxFileName filename = aFullFileName; filenamesList.Add( aFullFileName ); currentPath = filename.GetPath(); } // Read gerber files: each file is loaded on a new GerbView layer int layer = getActiveLayer(); for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ ) { wxFileName filename = filenamesList[ii]; if( !filename.IsAbsolute() ) filename.SetPath( currentPath ); m_lastFileName = filename.GetFullPath(); setActiveLayer( layer, false ); if( Read_GERBER_File( filename.GetFullPath(), filename.GetFullPath() ) ) { UpdateFileHistory( m_lastFileName ); layer = getNextAvailableLayer( layer ); if( layer == NO_AVAILABLE_LAYERS ) { wxString msg = wxT( "No more empty layers are available. The remaining gerber " ); msg += wxT( "files will not be loaded." ); wxMessageBox( msg ); break; } setActiveLayer( layer, false ); } } Zoom_Automatique( false ); // Synchronize layers tools with actual active layer: setActiveLayer( getActiveLayer() ); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); return true; }
TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) { int current_net_code; if( aTrack == NULL ) return NULL; if( aTrack->IsNew() ) // Trace in progress, erase the last segment { if( g_CurrentTrackList.GetCount() > 0 ) { LAYER_NUM previous_layer = getActiveLayer(); DBG( g_CurrentTrackList.VerifyListIntegrity(); ) // Delete the current trace ShowNewTrackWhenMovingCursor( m_canvas, DC, wxDefaultPosition, false ); // delete the most recently entered delete g_CurrentTrackList.PopBack(); if( g_TwoSegmentTrackBuild ) { // if in 2 track mode, and the next most recent is a segment // not a via, and the one previous to that is a via, then // delete up to the via. if( g_CurrentTrackList.GetCount() >= 2 && g_CurrentTrackSegment->Type() != PCB_VIA_T && g_CurrentTrackSegment->Back()->Type() == PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); } } while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() == PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() != PCB_VIA_T ) previous_layer = g_CurrentTrackSegment->GetLayer(); } // Correct active layer which could change if a via // has been erased setActiveLayer( previous_layer ); UpdateStatusBar(); if( g_TwoSegmentTrackBuild ) // We must have 2 segments or more, or 0 { if( g_CurrentTrackList.GetCount() == 1 && g_CurrentTrackSegment->Type() != PCB_VIA_T ) { delete g_CurrentTrackList.PopBack(); } } if( g_CurrentTrackList.GetCount() == 0 ) { m_canvas->SetMouseCapture( NULL, NULL ); if( GetBoard()->IsHighLightNetON() ) HighLight( DC ); SetCurItem( NULL ); return NULL; } else { if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); return g_CurrentTrackSegment; } }
// 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 ); }
void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer ) { LAYER_NUM curLayer = getActiveLayer(); // Check if the specified layer matches the present layer if( layer == curLayer ) return; // Copper layers cannot be selected unconditionally; how many // of those layers are currently enabled needs to be checked. if( IsCopperLayer( layer ) ) { // If only one copper layer is enabled, the only such layer // that can be selected to is the "Back" layer (so the // selection of any other copper layer is disregarded). if( GetBoard()->GetCopperLayerCount() < 2 ) { if( layer != LAYER_N_BACK ) return; } // If more than one copper layer is enabled, the "Copper" // and "Component" layers can be selected, but the total // number of copper layers determines which internal // layers are also capable of being selected. else { if( ( layer != LAYER_N_BACK ) && ( layer != LAYER_N_FRONT ) && ( layer >= GetBoard()->GetCopperLayerCount() - 1 ) ) return; } EDA_ITEM* current = GetScreen()->GetCurItem(); // See if we are drawing a segment; if so, add a via? if( GetToolId() == ID_TRACK_BUTT && current != NULL ) { if( current->Type() == PCB_TRACE_T && ( current->IsNew() ) ) { // Want to set the routing layers so that it switches properly - // see the implementation of Other_Layer_Route - the working // layer is used to 'start' the via and set the layer masks appropriately. GetScreen()->m_Route_Layer_TOP = curLayer; GetScreen()->m_Route_Layer_BOTTOM = layer; setActiveLayer( curLayer ); if( Other_Layer_Route( (TRACK*) GetScreen()->GetCurItem(), DC ) ) { if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); } // if the via was allowed by DRC, then the layer swap has already // been done by Other_Layer_Route(). if via not allowed, then // return now so assignment to setActiveLayer() below doesn't happen. return; } } } // Is yet more checking required? E.g. when the layer to be selected // is a non-copper layer, or when switching between a copper layer // and a non-copper layer, or vice-versa? // ... setActiveLayer( layer ); if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); }