Esempio n. 1
0
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;
}
Esempio n. 2
0
/* 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;
}
Esempio n. 6
0
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;
}
Esempio n. 10
0
/* 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;
    }
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
            }
        }
Esempio n. 14
0
// 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 );
}
Esempio n. 15
0
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();
}