/* Draw in drag mode when moving a pad.
 */
static void Show_Pad_Move( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                           bool aErase )
{
    TRACK*       Track;
    BASE_SCREEN* screen = aPanel->GetScreen();
    D_PAD*       pad    = s_CurrentSelectedPad;

    if( pad == NULL )       // Should not occur
        return;

    if( aErase )
        pad->Draw( aPanel, aDC, GR_XOR );

    pad->SetPosition( screen->GetCrossHairPosition() );
    pad->Draw( aPanel, aDC, GR_XOR );

    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
    {
        Track = g_DragSegmentList[ii].m_Track;

        if( aErase )
            Track->Draw( aPanel, aDC, GR_XOR );

        g_DragSegmentList[ii].SetTrackEndsCoordinates( wxPoint(0, 0) );

        Track->Draw( aPanel, aDC, GR_XOR );
    }
}
/* Cancel move pad command.
 */
static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
    D_PAD* pad = s_CurrentSelectedPad;

    Panel->SetMouseCapture( NULL, NULL );

    if( pad == NULL )
        return;

    pad->Draw( Panel, DC, GR_XOR );
    pad->ClearFlags();
    pad->SetPosition( Pad_OldPos );
    pad->Draw( Panel, DC, GR_XOR );

    // Pad move in progress: restore origin of dragged tracks, if any.
    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
    {
        TRACK* Track = g_DragSegmentList[ii].m_Track;
        Track->Draw( Panel, DC, GR_XOR );
        Track->SetState( IN_EDIT, OFF );
        g_DragSegmentList[ii].RestoreInitialValues();
        Track->Draw( Panel, DC, GR_OR );
    }

    EraseDragList();
    s_CurrentSelectedPad = NULL;
}
static void Show_MoveTrack(WinEDA_DrawPanel * panel, wxDC * DC, bool erase)
/*************************************************************************/
/* redessin du contour de la piste lors des deplacements de la souris */
{
int ii, dx, dy;
TRACK * Track;
BASE_SCREEN * screen = panel->GetScreen();
int track_fill_copy = DisplayOpt.DisplayPcbTrackFill;

	DisplayOpt.DisplayPcbTrackFill = SKETCH ;

erase = TRUE;

	/* efface ancienne position si elle a ete deja dessinee */
	if( erase )
	{
		if ( NewTrack ) Trace_Une_Piste(panel, DC, NewTrack,NbPtNewTrack,GR_XOR) ;
	}

	/* mise a jour des coordonnees des segments de la piste */
	wxPoint Pos = screen->m_Curseur;
	dx = Pos.x - LastPos.x;
	dy = Pos.y - LastPos.y;
	LastPos = Pos;
	ii = NbPtNewTrack, Track = NewTrack;
	for( ; ii > 0; ii--, Track = Track->Next() )
	{
		if( Track->m_Flags & STARTPOINT)
		{
			Track->m_Start.x += dx; Track->m_Start.y += dy;
		}
		if( Track->m_Flags & ENDPOINT)
		{
			Track->m_End.x += dx; Track->m_End.y += dy;
		}
	}

	/* dessin de la nouvelle piste */
	Trace_Une_Piste(panel, DC, NewTrack,NbPtNewTrack,GR_XOR) ;

	/* Tracage des segments dragges */
	DRAG_SEGM * pt_drag = g_DragSegmentList;
	for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext)
	{
		Track = pt_drag->m_Segm;
		if ( erase ) Track->Draw(panel, DC, GR_XOR);
		if( Track->m_Flags & STARTPOINT)
		{
			Track->m_Start.x += dx; Track->m_Start.y += dy;
		}
		if( Track->m_Flags & ENDPOINT)
		{
			Track->m_End.x += dx; Track->m_End.y += dy;
		}
		Track->Draw(panel, DC, GR_XOR);
	}
	DisplayOpt.DisplayPcbTrackFill = track_fill_copy ;
}
Exemple #4
0
void WinEDA_BasePcbFrame::Block_Move(wxDC * DC)
/************************************************/
/*
	routine de deplacement des elements du block deja selectionne
*/
{
int deltaX, deltaY;
wxPoint oldpos;

	oldpos = GetScreen()->m_Curseur;
	GetScreen()->ManageCurseur = NULL;

	GetScreen()->m_Curseur = oldpos;
	DrawPanel->MouseToCursorSchema();
	GetScreen()->SetModify();
	GetScreen()->BlockLocate.Normalize();

	/* calcul du vecteur de deplacement pour les deplacements suivants */
	deltaX = GetScreen()->BlockLocate.m_MoveVector.x ;
	deltaY = GetScreen()->BlockLocate.m_MoveVector.y ;

/* Deplacement des Segments de piste */
	TRACK * track;
	track = m_Pcb->m_Track;
	while( track )
		{
		if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
			{	/* la piste est ici bonne a etre deplacee */
			m_Pcb->m_Status_Pcb = 0 ;
			track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
			track->m_Start.x += deltaX ; track->m_Start.y += deltaY ;
			track->m_End.x += deltaX ; track->m_End.y += deltaY ;
			track->m_Param += deltaX ; track->m_Sous_Netcode += deltaY ;
			track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
			}
		track = (TRACK*) track->Pnext;
		}

	/* Deplacement des Segments de Zone */
	track = (TRACK*)m_Pcb->m_Zone;
	while( track )
		{
		if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
			{  /* la piste est ici bonne a etre deplacee */
			track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
			track->m_Start.x += deltaX ; track->m_Start.y += deltaY ;
			track->m_End.x += deltaX ; track->m_End.y += deltaY ;
			track->m_Param += deltaX ; track->m_Sous_Netcode += deltaY ;
			track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
			}
		track = (TRACK*) track->Pnext;
		}

	DrawPanel->Refresh(TRUE);
}
// Redraw the moved node according to the mouse cursor position
static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                           bool aErase )
{
    auto displ_opts = (PCB_DISPLAY_OPTIONS*) aPanel->GetDisplayOptions();
    wxPoint      moveVector;
    int          tmp = displ_opts->m_DisplayPcbTrackFill;
    GR_DRAWMODE  draw_mode = GR_XOR | GR_HIGHLIGHT;

    displ_opts->m_DisplayPcbTrackFill = false;

#ifndef USE_WX_OVERLAY
    aErase = true;
#else
    aErase = false;
#endif

    // set the new track coordinates
    wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition();

    moveVector = Pos - s_LastPos;
    s_LastPos  = Pos;

    TRACK *track = NULL;

    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
    {
        track = g_DragSegmentList[ii].m_Track;

        if( aErase )
            track->Draw( aPanel, aDC, draw_mode );

        if( track->GetFlags() & STARTPOINT )
            track->SetStart( track->GetStart() + moveVector );

        if( track->GetFlags() & ENDPOINT )
            track->SetEnd( track->GetEnd() + moveVector );

        if( track->Type() == PCB_VIA_T )
            track->SetEnd( track->GetStart() );

        track->Draw( aPanel, aDC, draw_mode );
    }

    displ_opts->m_DisplayPcbTrackFill = tmp;

    // Display track length
    if( track )
    {
        PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
        frame->SetMsgPanel( track );
    }
}
Exemple #6
0
void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
{
    /* Modify a full track (a trace) width (using DRC control).
     * a full track is the set of track segments between 2 nodes: pads or a node that has
     * more than 2 segments connected
     * aDC = the curred device context (can be NULL)
     * aTrackSegment = a via or a track belonging to the trace to change
     */
    TRACK* pt_track;
    int    nb_segm;

    if( aTrackSegment == NULL )
        return;

    pt_track = GetBoard()->MarkTrace( GetBoard()->m_Track, aTrackSegment, &nb_segm,
                                      NULL, NULL, true );

    PICKED_ITEMS_LIST itemsListPicker;
    bool change = false;

    for( int ii = 0; ii < nb_segm; ii++, pt_track = pt_track->Next() )
    {
        pt_track->SetState( BUSY, false );

        if( !SetTrackSegmentWidth( pt_track, &itemsListPicker, false ) )
            change = true;
    }

    if( !change )
        return;

    // Some segment have changed: redraw them and save in undo list
    if( aDC )
    {
        m_canvas->CrossHairOff( aDC );                     // Erase cursor shape

        for( unsigned ii = 0; ii < itemsListPicker.GetCount(); ii++ )
        {
            TRACK* segm = (TRACK*) itemsListPicker.GetPickedItemLink( ii );
            segm->Draw( m_canvas, aDC, GR_XOR );            // Erase old track shape
            segm = (TRACK*) itemsListPicker.GetPickedItem( ii );
            segm->Draw( m_canvas, aDC, GR_OR );             // Display new track shape

// fixme: commit!
//          segm->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
        }

        m_canvas->CrossHairOn( aDC );                   // Display cursor shape
    }

    SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
}
Exemple #7
0
void DrawTraces( EDA_DRAW_PANEL* panel, wxDC* DC, TRACK* aTrackList, int nbsegment,
                 GR_DRAWMODE draw_mode )
{
    // preserve the start of the list for debugging.
    for( TRACK* track = aTrackList; nbsegment > 0 && track; nbsegment--, track = track->Next() )
    {
        track->Draw( panel, DC, draw_mode );
    }
}
/**
 * Function Edit_Track_Width
 * Modify a full track width (using DRC control).
 * a full track is the set of track segments between 2 ends: pads or a point that has
 * more than 2 segments ends connected
 * @param aDC = the curred device context (can be NULL)
 * @param aTrackSegment = a segment or via on the track to change
 */
void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
{
    TRACK* pt_track;
    int    nb_segm;

    if( aTrackSegment == NULL )
        return;

    pt_track = GetBoard()->MarkTrace( aTrackSegment, &nb_segm, NULL, NULL, true );

    PICKED_ITEMS_LIST itemsListPicker;
    bool change = false;

    for( int ii = 0; ii < nb_segm; ii++, pt_track = pt_track->Next() )
    {
        pt_track->SetState( BUSY, false );

        if( SetTrackSegmentWidth( pt_track, &itemsListPicker, false ) )
            change = true;
    }

    if( !change )
        return;

    // Some segment have changed: redraw them and save in undo list
    if( aDC )
    {
        m_canvas->CrossHairOff( aDC );                     // Erase cursor shape

        for( unsigned ii = 0; ii < itemsListPicker.GetCount(); ii++ )
        {
            TRACK* segm = (TRACK*) itemsListPicker.GetPickedItemLink( ii );
            segm->Draw( m_canvas, aDC, GR_XOR );            // Erase old track shape
            segm = (TRACK*) itemsListPicker.GetPickedItem( ii );
            segm->Draw( m_canvas, aDC, GR_OR );             // Display new track shape
        }

        m_canvas->CrossHairOn( aDC );                   // Display cursor shape
    }

    SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
}
void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
{
    GR_DRAWMODE draw_mode;

    if( IsHighLightNetON() )
        draw_mode = GR_HIGHLIGHT | GR_OR;
    else
        draw_mode = GR_AND | GR_HIGHLIGHT;

    // Redraw ZONE_CONTAINERS
    BOARD::ZONE_CONTAINERS& zones = m_ZoneDescriptorList;

    for( BOARD::ZONE_CONTAINERS::iterator zc = zones.begin(); zc!=zones.end(); ++zc )
    {
        if( (*zc)->GetNet() == aNetCode )
        {
            (*zc)->Draw( am_canvas, DC, draw_mode );
        }
    }

    // Redraw any pads that have aNetCode
    for( MODULE* module = m_Modules; module; module = module->Next() )
    {
        for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
        {
            if( pad->GetNet() == aNetCode )
            {
                pad->Draw( am_canvas, DC, draw_mode );
            }
        }
    }

    // Redraw track and vias that have aNetCode
    for( TRACK* seg = m_Track; seg; seg = seg->Next() )
    {
        if( seg->GetNet() == aNetCode )
        {
            seg->Draw( am_canvas, DC, draw_mode );
        }
    }
}
void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
{
    GR_DRAWMODE draw_mode;

    if( IsHighLightNetON() )
        draw_mode = GR_HIGHLIGHT | GR_OR;
    else
        draw_mode = GR_AND | GR_HIGHLIGHT;

    // Redraw zones
    for( int ii = 0; ii < GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = GetArea( ii );

        if( zone->GetNetCode() == aNetCode )
        {
            zone->Draw( am_canvas, DC, draw_mode );
        }
    }

    // Redraw any pads that have aNetCode
    for( MODULE* module = m_Modules; module; module = module->Next() )
    {
        for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
        {
            if( pad->GetNetCode() == aNetCode )
            {
                pad->Draw( am_canvas, DC, draw_mode );
            }
        }
    }

    // Redraw track and vias that have aNetCode
    for( TRACK* seg = m_Track; seg; seg = seg->Next() )
    {
        if( seg->GetNetCode() == aNetCode )
        {
            seg->Draw( am_canvas, DC, draw_mode );
        }
    }
}
/**
 * Function Edit_TrackSegm_Width
 * Modify one track segment width or one via diameter (using DRC control).
 * @param aDC = the curred device context (can be NULL)
 * @param aTrackItem = the track segment or via to modify
 */
void PCB_EDIT_FRAME::Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem )
{
    PICKED_ITEMS_LIST itemsListPicker;
    bool change = SetTrackSegmentWidth( aTrackItem, &itemsListPicker, false );

    if( change == 0 || aTrackItem->GetFlags() )
        return;     // No change

    // The segment has changed: redraw it and save it in undo list
    if( aDC )
    {
        TRACK* oldsegm = (TRACK*) itemsListPicker.GetPickedItemLink( 0 );
        wxASSERT( oldsegm );
        m_canvas->CrossHairOff( aDC );                  // Erase cursor shape
        oldsegm->Draw( m_canvas, aDC, GR_XOR );         // Erase old track shape
        aTrackItem->Draw( m_canvas, aDC, GR_OR );       // Display new track shape
        m_canvas->CrossHairOn( aDC );                   // Display cursor shape
    }

    SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
}
// Redraw the BOARD items but not cursors, axis or grid
void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
{
    /* The order of drawing is flexible on some systems and not on others.  For
     * OSes which use OR to draw, the order is not important except for the
     * effect of the highlight and its relationship to markers. See comment
     * below.
     * This order independence comes from the fact that a binary OR operation is
     * commutative in nature.
     * However on the OSX, the OR operation is not used, and so this sequence
     * below is chosen to give MODULEs the highest visible priority.
     */

    /* Draw all tracks and zones.  As long as dark colors are used for the
     * tracks,  Then the OR draw mode should show tracks underneath other
     * tracks.  But a white track will cover any other color since it has
     * more bits to OR in.
     */
    for( TRACK* track = m_Track; track; track = track->Next() )
    {
        if( track->IsMoving() )
            continue;

        track->Draw( aPanel, DC, aDrawMode );
    }

    // Draw areas (i.e. zones)
    for( int ii = 0; ii < GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = GetArea( ii );

        // Areas must be drawn here only if not moved or dragged,
        // because these areas are drawn by ManageCursor() in a specific manner
        if( ( zone->GetEditFlags() & (IN_EDIT | IS_DRAGGED | IS_MOVED) ) == 0 )
        {
            zone->Draw( aPanel, DC, aDrawMode );
            zone->DrawFilledArea( aPanel, DC, aDrawMode );
        }
    }

    // Draw the graphic items
    for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
    {
        if( item->IsMoving() )
            continue;

        switch( item->Type() )
        {
        case PCB_DIMENSION_T:
        case PCB_TEXT_T:
        case PCB_TARGET_T:
        case PCB_LINE_T:
            item->Draw( aPanel, DC, aDrawMode );
            break;

        default:
            break;
        }
    }

    LSET all_cu = LSET::AllCuMask();

    for( MODULE* module = m_Modules; module; module = module->Next() )
    {
        bool    display = true;
        LSET    layerMask = all_cu;

        if( module->IsMoving() )
            continue;

        if( !IsElementVisible( LAYER_MOD_FR ) )
        {
            if( module->GetLayer() == F_Cu )
                display = false;

            layerMask.set( F_Cu, false );
        }

        if( !IsElementVisible( LAYER_MOD_BK ) )
        {
            if( module->GetLayer() == B_Cu )
                display = false;

            layerMask.set( B_Cu, false );
        }

        if( display )
            module->Draw( aPanel, DC, aDrawMode );
        else
            Trace_Pads_Only( aPanel, DC, module, 0, 0, layerMask, aDrawMode );
    }

    // draw the BOARD's markers last, otherwise the high light will erase any marker on a pad
    for( unsigned i = 0; i < m_markers.size(); ++i )
    {
        m_markers[i]->Draw( aPanel, DC, aDrawMode );
    }
}
void PCB_EDIT_FRAME::PrintPage( wxDC* aDC,
                                LSET  aPrintMask,
                                bool  aPrintMirrorMode,
                                void* aData)
{
    const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
    DISPLAY_OPTIONS save_opt;
    BOARD*          Pcb   = GetBoard();
    int             defaultPenSize = Millimeter2iu( 0.2 );
    bool            onePagePerLayer = false;

    PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData; // can be null
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();

    if( printParameters && printParameters->m_OptionPrintPage == 0 )
        onePagePerLayer = true;

    PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;

    if( printParameters )
    {
        drillShapeOpt = printParameters->m_DrillShapeOpt;
        defaultPenSize = printParameters->m_PenDefaultSize;
    }

    save_opt = *displ_opts;

    LAYER_ID activeLayer = GetScreen()->m_Active_Layer;

    displ_opts->m_ContrastModeDisplay = false;
    displ_opts->m_DisplayPadFill = true;
    displ_opts->m_DisplayViaFill = true;

    if( !( aPrintMask & LSET::AllCuMask() ).any() )
    {
        if( onePagePerLayer )
        {
            // We can print mask layers (solder mask and solder paste) with the actual
            // pad sizes.  To do that, we must set ContrastModeDisplay to true and set
            // the GetScreen()->m_Active_Layer to the current printed layer
            displ_opts->m_ContrastModeDisplay = true;
            displ_opts->m_DisplayPadFill = true;

            // Calculate the active layer number to print from its mask layer:
            GetScreen()->m_Active_Layer = B_Cu;

            for( LAYER_NUM id = LAYER_ID_COUNT-1; id >= 0; --id )
            {
                if( aPrintMask[id] )
                {
                    GetScreen()->m_Active_Layer = LAYER_ID( id );
                    break;
                }
            }

            // pads on Silkscreen layer are usually plot in sketch mode:
            if( GetScreen()->m_Active_Layer == B_SilkS ||
                GetScreen()->m_Active_Layer == F_SilkS )
            {
                displ_opts->m_DisplayPadFill = false;
            }
        }
        else
        {
            displ_opts->m_DisplayPadFill = false;
        }
    }

    displ_opts->m_DisplayPadNum = false;

    bool nctmp = GetBoard()->IsElementVisible( NO_CONNECTS_VISIBLE );

    GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, false );

    bool anchorsTmp = GetBoard()->IsElementVisible( ANCHOR_VISIBLE );

    GetBoard()->SetElementVisibility( ANCHOR_VISIBLE, false );

    displ_opts->m_DisplayPadIsol = false;
    displ_opts->m_DisplayModEdgeFill = FILLED;
    displ_opts->m_DisplayModTextFill = FILLED;
    displ_opts->m_DisplayPcbTrackFill = true;
    displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
    displ_opts->m_DisplayDrawItemsFill    = FILLED;
    displ_opts->m_DisplayZonesMode    = 0;
    displ_opts->m_DisplayNetNamesMode = 0;

    m_canvas->SetPrintMirrored( aPrintMirrorMode );

    for( BOARD_ITEM* item = Pcb->m_Drawings; item; item = item->Next() )
    {
        switch( item->Type() )
        {
        case PCB_LINE_T:
        case PCB_DIMENSION_T:
        case PCB_TEXT_T:
        case PCB_TARGET_T:
            if( aPrintMask[item->GetLayer()] )
                item->Draw( m_canvas, aDC, drawmode );
            break;

        case PCB_MARKER_T:
        default:
            break;
        }
    }

    // Print tracks
    for( TRACK* track = Pcb->m_Track; track; track = track->Next() )
    {
        if( !( aPrintMask & track->GetLayerSet() ).any() )
            continue;

        if( track->Type() == PCB_VIA_T ) // VIA encountered.
        {
            int         radius = track->GetWidth() / 2;
            const VIA*  via = static_cast<const VIA*>( track );

            EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->GetViaType() );

            GRFilledCircle( m_canvas->GetClipBox(), aDC,
                            via->GetStart().x,
                            via->GetStart().y,
                            radius,
                            0, color, color );
        }
        else
        {
            track->Draw( m_canvas, aDC, drawmode );
        }
    }

    // Outdated: only for compatibility to old boards
    for( TRACK* track = Pcb->m_Zone; track; track = track->Next() )
    {
        if( !( aPrintMask & track->GetLayerSet() ).any() )
            continue;

        track->Draw( m_canvas, aDC, drawmode );
    }

    // Draw filled areas (i.e. zones)
    for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = Pcb->GetArea( ii );

        if( aPrintMask[zone->GetLayer()] )
            zone->DrawFilledArea( m_canvas, aDC, drawmode );
    }

    // Draw footprints, this is done at last in order to print the pad holes in
    // white after the tracks and zones
    int tmp = D_PAD::m_PadSketchModePenSize;
    D_PAD::m_PadSketchModePenSize = defaultPenSize;

    for( MODULE* module = (MODULE*) Pcb->m_Modules; module;  module = module->Next() )
    {
        Print_Module( m_canvas, aDC, module, drawmode, aPrintMask, drillShapeOpt );
    }

    D_PAD::m_PadSketchModePenSize = tmp;

    /* Print via holes in bg color: Not sure it is good for buried or blind
     * vias */
    if( drillShapeOpt != PRINT_PARAMETERS::NO_DRILL_SHAPE )
    {
        TRACK*      track = Pcb->m_Track;
        EDA_COLOR_T color = WHITE;

        bool blackpenstate = GetGRForceBlackPenState();

        GRForceBlackPen( false );

        for( ; track; track = track->Next() )
        {
            if( !( aPrintMask & track->GetLayerSet() ).any() )
                continue;

            if( track->Type() == PCB_VIA_T ) // VIA encountered.
            {
                int diameter;
                const VIA *via = static_cast<const VIA*>( track );

                if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE )
                    diameter = std::min( SMALL_DRILL, via->GetDrillValue() );
                else
                    diameter = via->GetDrillValue();

                GRFilledCircle( m_canvas->GetClipBox(), aDC,
                                track->GetStart().x, track->GetStart().y,
                                diameter/2,
                                0, color, color );
            }
        }

        GRForceBlackPen( blackpenstate );
    }

    m_canvas->SetPrintMirrored( false );

    *displ_opts = save_opt;
    GetScreen()->m_Active_Layer = activeLayer;

    GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp );
    GetBoard()->SetElementVisibility( ANCHOR_VISIBLE, anchorsTmp );
}
static void Exit_MoveTrack(WinEDA_DrawFrame * frame, wxDC *DC)
/***************************************************************/
/* routine d'annulation de la commande drag, copy ou move track  si une piste est en cours
	de tracage, ou de sortie de l'application EDITRACK.
	Appel par la touche ESC
 */
{
TRACK * NextS;
int ii;


	/* Effacement du trace en cours */
	wxPoint oldpos = frame->GetScreen()->m_Curseur;
	frame->GetScreen()->m_Curseur = PosInit;
	frame->GetScreen()->ManageCurseur(frame->DrawPanel, DC, TRUE);
	frame->GetScreen()->m_Curseur = oldpos;
	g_HightLigt_Status = FALSE;
	( (WinEDA_PcbFrame *)frame)->DrawHightLight( DC, g_HightLigth_NetCode) ;

	if( NewTrack )
	{
		if (NewTrack->m_Flags & IS_NEW )
		{
			for( ii = 0; ii < NbPtNewTrack; ii++, NewTrack = NextS)
			{
				if(NewTrack == NULL) break;
				NextS = (TRACK*) NewTrack->Pnext;
				delete NewTrack;
			}
		}
		else	/* Move : remise en ancienne position */
		{
			TRACK * Track = NewTrack;
			int dx = LastPos.x - PosInit.x;
			int dy = LastPos.y - PosInit.y;
			for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext)
			{
				if( Track == NULL ) break;
				Track->m_Start.x -= dx;
				Track->m_Start.y -= dy;
				Track->m_End.x -= dx;
				Track->m_End.y -= dy;
				Track->m_Flags = 0;

			}
			Trace_Une_Piste(frame->DrawPanel, DC, NewTrack,NbPtNewTrack,GR_OR);
		}

		NewTrack = NULL;
	}

	frame->GetScreen()->ManageCurseur = NULL;
	frame->GetScreen()->ForceCloseManageCurseur = NULL;
	frame->GetScreen()->m_CurrentItem = NULL;
	frame->EraseMsgBox();

	/* Annulation deplacement et Redessin des segments dragges */
	DRAG_SEGM * pt_drag = g_DragSegmentList;
	for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext)
	{
		TRACK * Track = pt_drag->m_Segm;
		pt_drag->SetInitialValues();
		Track->SetState(EDIT,OFF);
		Track->m_Flags = 0;
		Track->Draw(frame->DrawPanel, DC, GR_OR);
	}

	g_HightLigth_NetCode = Old_HightLigth_NetCode;
	g_HightLigt_Status = Old_HightLigt_Status;
	if(g_HightLigt_Status)
		( (WinEDA_PcbFrame *)frame)->DrawHightLight( DC, g_HightLigth_NetCode) ;

	EraseDragListe();
}
Exemple #15
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 );
}
// Routine to place a moved pad.
void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
{
    int     dX, dY;
    TRACK*  Track;

    if( aPad == NULL )
        return;

    MODULE* module = aPad->GetParent();

    ITEM_PICKER       picker( NULL, UR_CHANGED );
    PICKED_ITEMS_LIST pickList;

    // Save dragged track segments in undo list
    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
    {
        Track = g_DragSegmentList[ii].m_Track;

        // Set the old state
        if( g_DragSegmentList[ii].m_Pad_Start )
            Track->SetStart( Pad_OldPos );

        if( g_DragSegmentList[ii].m_Pad_End )
            Track->SetEnd( Pad_OldPos );

        picker.SetItem( Track );
        pickList.PushItem( picker );
    }

    // Save old module and old items values
    wxPoint pad_curr_position = aPad->GetPosition();

    aPad->SetPosition( Pad_OldPos );

    if( g_DragSegmentList.size() == 0 )
        SaveCopyInUndoList( module, UR_CHANGED );
    else
    {
        picker.SetItem( module );
        pickList.PushItem( picker );
        SaveCopyInUndoList( pickList, UR_CHANGED );
    }

    aPad->SetPosition( pad_curr_position );
    aPad->Draw( m_canvas, DC, GR_XOR );

    // Redraw dragged track segments
    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
    {
        Track = g_DragSegmentList[ii].m_Track;

        // Set the new state
        if( g_DragSegmentList[ii].m_Pad_Start )
            Track->SetStart( aPad->GetPosition() );

        if( g_DragSegmentList[ii].m_Pad_End )
            Track->SetEnd( aPad->GetPosition() );

        Track->SetState( IN_EDIT, OFF );

        if( DC )
            Track->Draw( m_canvas, DC, GR_OR );
    }

    // Compute local coordinates (i.e refer to module position and for module orient = 0)
    dX = aPad->GetPosition().x - Pad_OldPos.x;
    dY = aPad->GetPosition().y - Pad_OldPos.y;

    RotatePoint( &dX, &dY, -module->GetOrientation() );

    aPad->SetX0( dX + aPad->GetPos0().x );
    aPad->SetY0( dY + aPad->GetPos0().y );

    aPad->ClearFlags();

    if( DC )
        aPad->Draw( m_canvas, DC, GR_OR );

    module->CalculateBoundingBox();
    module->SetLastEditTime();

    EraseDragList();

    OnModify();
    m_canvas->SetMouseCapture( NULL, NULL );
    m_Pcb->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
}
/* drawing the track segment movement
 *  > s_MovingSegmentSlope slope = moving track segment slope
 *  > s_StartSegmentSlope slope = slope of the segment connected to the start
 * point of the moving segment
 *  > s_EndSegmentSlope slope = slope of the segment connected to the end point
 * of the moving segment
 *
 *  moved segment function :
 *      yt=s_MovingSegmentSlope * x + s_MovingSegment_Yorg
 *
 *  segment connected to moved segment's start:
 *      y1 = s_StartSegmentSlope * x + s_StartSegment_Yorg
 *
 *  segment connected to moved segment's end:
 *      y2=s_EndSegmentSlope * x + s_EndSegment_Yorg
 *
 *  first intersection point will be located at
 *      y1=yt ->
 *
 * xi1=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_StartSegmentSlope-s_MovingSegmentSlope)
 *      yi1=s_MovingSegmentSlope*xi1+s_MovingSegment_Yorg
 *      or yi1=s_StartSegmentSlope*xi1+s_MovingSegment_Yorg
 *
 *  second intersection point
 *      y2=yt ->
 *
 * xi2=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_MovingSegmentSlope-s_MovingSegmentSlope)
 *      yi2=s_MovingSegmentSlope*xi2+s_MovingSegment_Yorg
 *      or yi1=s_EndSegmentSlope*xi2+s_MovingSegment_Yorg
 *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *  !!!!!    special attention to vertical segments because
 *  !!!!!    their slope=infinite
 *  !!!!!    intersection point will be calculated using the
 *  !!!!!    segment intersecting it
 *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *
 *  Slope parameters are computed once, because they can become undetermined
 * when moving segments
 *  (i.e. when a segment length is 0) and we want keep them constant
 */
static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
                                                    const wxPoint& aPosition, bool aErase )
{
    double       xi1 = 0, yi1 = 0, xi2 = 0, yi2 = 0;    // calculated intersection points
    double       tx1, tx2, ty1, ty2;                    // temporary storage of points
    int          dx, dy;
    bool         update = true;
    TRACK*       Track;
    TRACK*       tSegmentToStart = NULL, * tSegmentToEnd = NULL;

    if( g_DragSegmentList.size() == 0 )
        return;

    /* get the segments :
     * from last to first in list are:
     * the segment to move
     * the segment connected to its end point (if exists)
     * the segment connected to its start point (if exists)
     */
    int ii = g_DragSegmentList.size() - 1;
    Track = g_DragSegmentList[ii].m_Track;

    if( Track == NULL )
        return;

    ii--;

    if( ii >= 0)
    {
        if( s_EndSegmentPresent )
        {
            // Get the segment connected to the end point
            tSegmentToEnd   = g_DragSegmentList[ii].m_Track;
            ii--;
        }

        if( s_StartSegmentPresent )
        {
            // Get the segment connected to the start point
            if( ii >= 0 )
                tSegmentToStart = g_DragSegmentList[ii].m_Track;
        }
    }

    GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT;

    // Undraw the current moved track segments before modification

#ifndef USE_WX_OVERLAY
//  if( erase )
    {
        Track->Draw( aPanel, aDC, draw_mode );

        if( tSegmentToStart )
            tSegmentToStart->Draw( aPanel, aDC, draw_mode );

        if( tSegmentToEnd )
            tSegmentToEnd->Draw( aPanel, aDC, draw_mode );
    }
#endif

    // Compute the new track segment position
    wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition();

    dx = Pos.x - s_LastPos.x;
    dy = Pos.y - s_LastPos.y;

    // move the line by dx and dy
    tx1 = (double) ( Track->GetStart().x + dx );
    ty1 = (double) ( Track->GetStart().y + dy );
    tx2 = (double) ( Track->GetEnd().x + dx );
    ty2 = (double) ( Track->GetEnd().y + dy );

    // recalculate the segments new parameters and intersection points
    // only the intercept will change, segment slopes does not change
    // because we are moving parallel with is initial state
    if( !s_MovingSegmentVertical )
    {
        s_MovingSegment_Yorg = ty1 - ( s_MovingSegmentSlope * tx1 );
    }

    if( ( !s_EndPointVertical ) && ( !s_MovingSegmentVertical ) )
    {
        xi2 = ( s_MovingSegment_Yorg - s_EndSegment_Yorg )
            / ( s_EndSegmentSlope - s_MovingSegmentSlope );
    }
    else
    {
        if( !s_EndPointVertical )
        {
            xi2 = tx2;
        }
        else
        {
            //P1=P2
            if( !s_EndPointHorizontal )
            {
                xi2 = tx2 - dx;
            }
            else
            {
                update = false;
            }
        }
    }

    if( !s_MovingSegmentVertical )
    {
        yi2 = s_MovingSegmentSlope * ( xi2 ) + s_MovingSegment_Yorg;
    }
    else
    {
        if( !s_EndPointVertical )
        {
            yi2 = s_EndSegmentSlope * ( xi2 ) + s_EndSegment_Yorg;
        }
        else
        {
            if( !s_EndPointHorizontal )
            {
                update = false;
            }
            else
            {
                yi2 = s_MovingSegmentSlope * ( xi2 ) + s_MovingSegment_Yorg;
            }
        }
    }

    if( ( !s_StartPointVertical ) && ( !s_MovingSegmentVertical ) )
    {
        xi1 = ( s_MovingSegment_Yorg - s_StartSegment_Yorg )
            / ( s_StartSegmentSlope - s_MovingSegmentSlope );
    }
    else
    {
        if( !s_StartPointVertical )
        {
            xi1 = tx1;
        }
        else
        {
            //P1=P2
            if( !s_StartPointHorizontal )
            {
                xi1 = tx1 - dx;
            }
            else
            {
                if( !s_StartPointHorizontal )
                {
                    update = false;
                }
            }
        }
    }

    if( !s_MovingSegmentVertical )
    {
        yi1 = s_MovingSegmentSlope * ( xi1 ) + s_MovingSegment_Yorg;
    }
    else
    {
        if( !s_StartPointVertical )
        {
            yi1 = s_StartSegmentSlope * ( xi1 ) + s_StartSegment_Yorg;
        }
        else
        {
            if( !s_StartPointHorizontal )
            {
                update = false;
            }
            else
            {
                yi2 = s_MovingSegmentSlope * ( xi1 ) + s_MovingSegment_Yorg;
            }
        }
    }

    // update the segment coordinates (if possible)
    if( tSegmentToStart == NULL )
    {
        xi1 = tx1;
        yi1 = ty1;
    }

    if( tSegmentToEnd == NULL )
    {
        xi2 = tx2;
        yi2 = ty2;
    }

    if( update )
    {
        s_LastPos = Pos;
        Track->SetStart( wxPoint( KiROUND( xi1 ), KiROUND( yi1 ) ) );
        Track->SetEnd( wxPoint( KiROUND( xi2 ), KiROUND( yi2 ) ) );

        if( tSegmentToEnd )
        {
            if( tSegmentToEnd->GetFlags() & STARTPOINT )
                tSegmentToEnd->SetStart( Track->GetEnd() );
            else
                tSegmentToEnd->SetEnd( Track->GetEnd() );
        }

        if( tSegmentToStart )
        {
            if( tSegmentToStart->GetFlags() & STARTPOINT )
                tSegmentToStart->SetStart( Track->GetStart() );
            else
                tSegmentToStart->SetEnd( Track->GetStart() );
        }
    }

    Track->Draw( aPanel, aDC, draw_mode );

    if( tSegmentToStart )
        tSegmentToStart->Draw( aPanel, aDC, draw_mode );

    if( tSegmentToEnd )
        tSegmentToEnd->Draw( aPanel, aDC, draw_mode );

    // Display track length
    PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
    frame->SetMsgPanel( Track );
}
Exemple #18
0
void WinEDA_PcbFrame::Process_Special_Functions(wxCommandEvent& event)
/*********************************************************************/
/* Traite les selections d'outils et les commandes appelees du menu POPUP
*/
{
    int id = event.GetId();
    wxPoint pos;
    wxClientDC dc(DrawPanel);
    int itmp;

    DrawPanel->PrepareGraphicContext(&dc);

    wxGetMousePosition(&pos.x, &pos.y);

    pos.y += 20;

    switch ( id )	// Arret eventuel de la commande de déplacement en cours
    {
    case wxID_CUT:
    case wxID_COPY:
    case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
    case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
    case ID_ON_GRID_SELECT:
    case ID_ON_ZOOM_SELECT:
    case ID_PCB_USER_GRID_SETUP:
    case ID_TOOLBARH_PCB_SELECT_LAYER:
    case ID_POPUP_PCB_ROTATE_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:
    case ID_POPUP_PCB_EDIT_TEXTMODULE:
    case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
    case ID_POPUP_PCB_END_TRACK:
    case ID_POPUP_PCB_PLACE_VIA:
    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_EDGE_ZONE:
    case ID_POPUP_PCB_DELETE_ZONE_LIMIT:
    case ID_POPUP_PCB_EDIT_ZONE:
    case ID_POPUP_PCB_DELETE_ZONE:
    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_NET_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_SELECT_WIDTH:
    case ID_POPUP_PCB_SELECT_WIDTH1:
    case ID_POPUP_PCB_SELECT_WIDTH2:
    case ID_POPUP_PCB_SELECT_WIDTH3:
    case ID_POPUP_PCB_SELECT_WIDTH4:
    case ID_POPUP_PCB_SELECT_WIDTH5:
    case ID_POPUP_PCB_SELECT_WIDTH6:
    case ID_POPUP_PCB_SELECT_WIDTH7:
    case ID_POPUP_PCB_SELECT_WIDTH8:
    case ID_POPUP_PCB_SELECT_VIASIZE:
    case ID_POPUP_PCB_SELECT_VIASIZE1:
    case ID_POPUP_PCB_SELECT_VIASIZE2:
    case ID_POPUP_PCB_SELECT_VIASIZE3:
    case ID_POPUP_PCB_SELECT_VIASIZE4:
    case ID_POPUP_PCB_SELECT_VIASIZE5:
    case ID_POPUP_PCB_SELECT_VIASIZE6:
    case ID_POPUP_PCB_SELECT_VIASIZE7:
    case ID_POPUP_PCB_SELECT_VIASIZE8:
    case ID_POPUP_PCB_MOVE_TRACK_NODE:
    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_INVERT_BLOCK:
    case ID_POPUP_ROTATE_BLOCK:
    case ID_POPUP_COPY_BLOCK:
    case ID_POPUP_PCB_VIA_EDITING:
    case ID_POPUP_PCB_VIA_HOLE_TO_DEFAULT:
    case ID_POPUP_PCB_VIA_HOLE_TO_VALUE:
    case ID_POPUP_PCB_VIA_HOLE_ENTER_VALUE:
    case ID_POPUP_PCB_VIA_HOLE_EXPORT:
    case ID_POPUP_PCB_VIA_HOLE_RESET_TO_DEFAULT:
    case ID_POPUP_PCB_VIA_HOLE_EXPORT_TO_OTHERS:
        break;

    case ID_POPUP_CANCEL_CURRENT_COMMAND:
        if( GetScreen()->ManageCurseur &&
                GetScreen()->ForceCloseManageCurseur )
        {
            GetScreen()->ForceCloseManageCurseur(this, &dc);
        }
        /* ne devrait pas etre execute, sauf bug */
        if (m_CurrentScreen->BlockLocate.m_Command != BLOCK_IDLE)
        {
            m_CurrentScreen->BlockLocate.m_Command = BLOCK_IDLE;
            m_CurrentScreen->BlockLocate.m_State = STATE_NO_BLOCK;
            m_CurrentScreen->BlockLocate.m_BlockDrawStruct = NULL;
        }
        if (m_ID_current_state == 0 )
            SetToolID(0, wxCURSOR_ARROW,wxEmptyString);
        else SetCursor(DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor);
        break;

    default:	// Arret de la commande de déplacement en cours
        if( GetScreen()->ManageCurseur &&
                GetScreen()->ForceCloseManageCurseur )
        {
            GetScreen()->ForceCloseManageCurseur(this, &dc);
        }
        SetToolID(0, wxCURSOR_ARROW,wxEmptyString);
        break;
    }

    switch ( id )	// Traitement des commandes
    {
    case ID_EXIT :
        Close(TRUE);
        break;

    case ID_OPEN_MODULE_EDITOR:
        if (m_Parent->m_ModuleEditFrame == NULL )
        {
            m_Parent->m_ModuleEditFrame = new WinEDA_ModuleEditFrame(this,
                    m_Parent,_("Module Editor"),
                    wxPoint(-1, -1), wxSize(600,400) );
            m_Parent->m_ModuleEditFrame->Show(TRUE);
            m_Parent->m_ModuleEditFrame->Zoom_Automatique(TRUE);
        }
        else m_Parent->m_ModuleEditFrame->Iconize(FALSE);
        break;

    case ID_NEW_PROJECT:
    case ID_LOAD_PROJECT:
        Files_io(event);
        break;

    case ID_PCB_GLOBAL_DELETE:
        InstallPcbGlobalDeleteFrame(pos);
        break;

    case ID_POPUP_PLACE_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_MOVE;
        DrawPanel->m_AutoPAN_Request = FALSE;
        HandleBlockPlace(&dc);
        break;

    case ID_POPUP_COPY_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_COPY;
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        DrawPanel->m_AutoPAN_Request = FALSE;
        HandleBlockPlace(&dc);
        break;

    case ID_POPUP_ZOOM_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_ZOOM;
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        HandleBlockEnd(&dc);
        break;

    case ID_POPUP_DELETE_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_DELETE;
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        HandleBlockEnd(&dc);
        break;

    case ID_POPUP_ROTATE_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_ROTATE;
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        HandleBlockEnd(&dc);
        break;

    case ID_POPUP_INVERT_BLOCK:
        GetScreen()->BlockLocate.m_Command = BLOCK_INVERT;
        m_CurrentScreen->BlockLocate.SetMessageBlock(this);
        HandleBlockEnd(&dc);
        break;

    case ID_UNDO_BUTT:
        UnDeleteItem(&dc);
        break;

    case ID_DRC_CONTROL:
        Install_Test_DRC_Frame(&dc);
        break;

    case ID_GET_NETLIST:
        InstallNetlistFrame(&dc, wxPoint(-1,-1));
        break;

    case ID_GET_TOOLS:
//			InstallToolsFrame(this, wxPoint(-1,-1) );
        break;

    case ID_FIND_ITEMS:
        InstallFindFrame(pos, &dc);
        break;

    case ID_TRACK_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Tracks"));
        DisplayTrackSettings();
        if ( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0)
        {
            Compile_Ratsnest( &dc, TRUE );
        }
        break;

    case ID_PCB_ZONES_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Zones"));
        if ( ! DisplayOpt.DisplayZones )
            DisplayInfo(this, _("Warning: Display Zone is OFF!!!") );
        DelLimitesZone(&dc, TRUE);
        if( ! g_HightLigt_Status && (g_HightLigth_NetCode > 0 ) )
            Hight_Light(&dc);
        break;

    case ID_PCB_MIRE_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Mire"));
        break;

    case ID_PCB_PLACE_OFFSET_COORD_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Adjust Zero"));
        break;

    case ID_LINE_COMMENT_BUTT:
    case ID_PCB_ARC_BUTT:
    case ID_PCB_CIRCLE_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Graphic"));
        break;

    case ID_TEXT_COMMENT_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Text"));
        break;

    case ID_COMPONENT_BUTT:
        SetToolID( id, wxCURSOR_HAND, _("Add Modules"));
        break;

    case ID_PCB_COTATION_BUTT:
        SetToolID( id, wxCURSOR_PENCIL, _("Add Cotation"));
        break;

    case ID_NO_SELECT_BUTT:
        SetToolID( 0, wxCURSOR_ARROW, wxEmptyString);
        break;

    case ID_PCB_HIGHLIGHT_BUTT:
        SetToolID( id, wxCURSOR_HAND, _("Net Highlight"));
        break;

    case ID_PCB_SHOW_1_RATSNEST_BUTT:
        SetToolID( id, wxCURSOR_HAND, _("Local Ratsnest"));
        if ( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0)
            Compile_Ratsnest( &dc, TRUE );
        break;

    case ID_POPUP_CLOSE_CURRENT_TOOL:
        SetToolID( 0, wxCURSOR_ARROW, wxEmptyString);
        break;


    case ID_POPUP_CANCEL_CURRENT_COMMAND:
        break;

    case ID_POPUP_END_LINE:
        DrawPanel->MouseToCursorSchema();
//			EndSegment(&dc);
        break;

    case ID_POPUP_PCB_EDIT_TRACK:
        if ( CURRENT_ITEM == NULL) break;
        Edit_Track_Width(&dc, (TRACK *) CURRENT_ITEM);
        DrawPanel->MouseToCursorSchema();
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_EDIT_TRACKSEG:
        if ( CURRENT_ITEM == NULL) break;
        Edit_TrackSegm_Width(&dc, (TRACK *) CURRENT_ITEM);
        DrawPanel->MouseToCursorSchema();
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_EDIT_NET:
        if ( CURRENT_ITEM == NULL) break;
        Edit_Net_Width(&dc, ((TRACK *) CURRENT_ITEM)->m_NetCode);
        DrawPanel->MouseToCursorSchema();
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE:
    case ID_POPUP_PCB_EDIT_ALL_VIAS_SIZE:
    case ID_POPUP_PCB_EDIT_ALL_TRACK_SIZE:
        if ( CURRENT_ITEM == NULL) break;
        {
            bool resize_vias = TRUE, resize_track = TRUE;
            if( id == ID_POPUP_PCB_EDIT_ALL_VIAS_SIZE) resize_track = FALSE;
            if( id == ID_POPUP_PCB_EDIT_ALL_TRACK_SIZE) resize_vias = FALSE;
            if ( Resize_Pistes_Vias(&dc, resize_track, resize_vias)) GetScreen()->SetModify();
        }
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_END_TRACK:
        DrawPanel->MouseToCursorSchema();
        End_Route( (TRACK *) CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM->m_Flags & IS_DRAGGED )
        {
            PlaceDraggedTrackSegment((TRACK *) CURRENT_ITEM, &dc);
        }
        break;

    case ID_POPUP_PCB_PLACE_VIA:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM->m_Flags & IS_DRAGGED )
        {
            PlaceDraggedTrackSegment((TRACK *) CURRENT_ITEM, &dc);
        }
        else
        {
            Other_Layer_Route( (TRACK *) CURRENT_ITEM, &dc);
            if ( DisplayOpt.ContrastModeDisplay )
                GetScreen()->SetRefreshReq();
        }
        break;


    case ID_POPUP_PCB_DELETE_TRACKSEG:
        DrawPanel->MouseToCursorSchema();
        GetScreen()->m_CurrentItem = Delete_Segment(&dc, (TRACK*)CURRENT_ITEM);
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_DELETE_TRACK:
        DrawPanel->MouseToCursorSchema();
        Delete_Track(&dc, (TRACK*)CURRENT_ITEM);
        GetScreen()->m_CurrentItem = NULL;
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_DELETE_TRACKNET:
        DrawPanel->MouseToCursorSchema();
        Delete_net(&dc, (TRACK*)CURRENT_ITEM);
        GetScreen()->m_CurrentItem = NULL;
        GetScreen()->SetModify();
        break;

    case ID_POPUP_PCB_LOCK_ON_TRACKSEG:
        Attribut_Segment((TRACK*)CURRENT_ITEM, &dc, TRUE);
        break;

    case ID_POPUP_PCB_LOCK_OFF_TRACKSEG:
        Attribut_Segment((TRACK*)CURRENT_ITEM, &dc, FALSE);
        break;

    case ID_POPUP_PCB_LOCK_ON_TRACK:
        Attribut_Track((TRACK*)CURRENT_ITEM, &dc, TRUE);
        break;

    case ID_POPUP_PCB_LOCK_OFF_TRACK:
        Attribut_Track((TRACK*)CURRENT_ITEM, &dc, FALSE);
        break;

    case ID_POPUP_PCB_LOCK_ON_NET:
        Attribut_net(&dc, ((TRACK*)CURRENT_ITEM)->m_NetCode, TRUE);
        break;

    case ID_POPUP_PCB_LOCK_OFF_NET:
        Attribut_net(&dc, ((TRACK*)CURRENT_ITEM)->m_NetCode, FALSE);
        break;

    case ID_POPUP_PCB_SETFLAGS_TRACK_MNU:
        break;

    case ID_POPUP_PCB_DELETE_ZONE:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM == NULL) break;
        Delete_Zone(&dc, (SEGZONE*)CURRENT_ITEM);
        GetScreen()->m_CurrentItem = NULL;
        break;

    case ID_POPUP_PCB_EDIT_ZONE:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM == NULL) break;
        Edit_Zone_Width(&dc, (SEGZONE*)CURRENT_ITEM);
        break;

    case ID_POPUP_PCB_DELETE_ZONE_LIMIT:
        DrawPanel->MouseToCursorSchema();
        DelLimitesZone(&dc, TRUE);
        break;

    case ID_PCB_DELETE_ITEM_BUTT:
        SetToolID( id, wxCURSOR_BULLSEYE, _("Delete item"));
        break;

    case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
        Process_Move_Item(this, CURRENT_ITEM, &dc);
        DrawPanel->m_AutoPAN_Request = TRUE;
        break;

    case ID_POPUP_PCB_DRAG_MODULE_REQUEST:
        g_Drag_Pistes_On = TRUE;
    case ID_POPUP_PCB_MOVE_MODULE_REQUEST:
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
        {
            g_Drag_Pistes_On = FALSE;
            break;
        }
        DrawPanel->MouseToCursorSchema();
        StartMove_Module( (MODULE*)CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_DELETE_MODULE:
        DrawPanel->MouseToCursorSchema();
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
            break;
        if ( Delete_Module((MODULE*) CURRENT_ITEM, &dc) )
        {
            GetScreen()->m_CurrentItem = NULL;
        }
        break;

    case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
        DrawPanel->MouseToCursorSchema();
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
            break;
        Rotate_Module(&dc, (MODULE*)CURRENT_ITEM, -900, TRUE);
        break;

    case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
        DrawPanel->MouseToCursorSchema();
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
            break;
        Rotate_Module(&dc, (MODULE*)CURRENT_ITEM, 900, TRUE);
        break;

    case ID_POPUP_PCB_CHANGE_SIDE_MODULE:
        DrawPanel->MouseToCursorSchema();
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
            break;
        Change_Side_Module((MODULE *) CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_EDIT_MODULE:
        // If the current Item is a pad, text module ...: Get the parent
        if ( CURRENT_ITEM->m_StructType != TYPEMODULE )
            CURRENT_ITEM = (MODULE *) CURRENT_ITEM->m_Parent;
        if ( !CURRENT_ITEM || CURRENT_ITEM->m_StructType != TYPEMODULE )
            break;
        InstallModuleOptionsFrame((MODULE *)CURRENT_ITEM,
                                  &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DRAG_PAD_REQUEST:
        g_Drag_Pistes_On = TRUE;
    case ID_POPUP_PCB_MOVE_PAD_REQUEST:
        DrawPanel->MouseToCursorSchema();
        StartMovePad((D_PAD *)CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_EDIT_PAD:
        InstallPadOptionsFrame((D_PAD *)CURRENT_ITEM,
                               &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
        DrawPanel->MouseToCursorSchema();
        Import_Pad_Settings((D_PAD *)CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
        DrawPanel->MouseToCursorSchema();
        Global_Import_Pad_Settings((D_PAD *)CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
        DrawPanel->MouseToCursorSchema();
        Export_Pad_Settings((D_PAD *)CURRENT_ITEM);
        break;


    case ID_POPUP_PCB_DELETE_PAD:
        DeletePad((D_PAD *)CURRENT_ITEM, &dc);
        GetScreen()->m_CurrentItem = NULL;
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_EDIT_TEXTMODULE:
        InstallTextModOptionsFrame((TEXTE_MODULE *)CURRENT_ITEM,
                                   &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
        DrawPanel->MouseToCursorSchema();
        StartMoveTexteModule( (TEXTE_MODULE *) CURRENT_ITEM,
                              &dc);
        break;

    case ID_POPUP_PCB_ROTATE_TEXTMODULE:
        RotateTextModule((TEXTE_MODULE *)CURRENT_ITEM,
                         &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DELETE_TEXTMODULE:
        DeleteTextModule((TEXTE_MODULE *)CURRENT_ITEM,
                         &dc);
        GetScreen()->m_CurrentItem = NULL;
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_SELECT_LAYER:
        itmp = SelectLayer(GetScreen()->m_Active_Layer, -1, -1);
        if ( itmp >= 0 ) GetScreen()->m_Active_Layer = itmp;
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_SELECT_NO_CU_LAYER:
        itmp = SelectLayer(GetScreen()->m_Active_Layer, CMP_N+1, -1);
        if ( itmp >= 0 ) GetScreen()->m_Active_Layer = itmp;
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_SELECT_CU_LAYER:
        itmp = SelectLayer(GetScreen()->m_Active_Layer, -1, CMP_N);
        if ( itmp >= 0 ) GetScreen()->m_Active_Layer = itmp;
        break;

    case ID_POPUP_PCB_SELECT_LAYER_PAIR:
        SelectLayerPair();
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_TOOLBARH_PCB_SELECT_LAYER:
        itmp = m_SelLayerBox->GetChoice();
        GetScreen()->m_Active_Layer = (int)((size_t) m_SelLayerBox->GetClientData(itmp));
        if ( DisplayOpt.ContrastModeDisplay ) DrawPanel->Refresh(TRUE);
        break;

    case ID_POPUP_PCB_EDIT_TEXTEPCB:
        InstallTextPCBOptionsFrame((TEXTE_PCB *)CURRENT_ITEM,
                                   &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_ROTATE_TEXTEPCB:
        Rotate_Texte_Pcb((TEXTE_PCB *)CURRENT_ITEM, &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DELETE_TEXTEPCB:
        Delete_Texte_Pcb((TEXTE_PCB *)CURRENT_ITEM, &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_MOVE_MIRE_REQUEST:
        StartMove_Mire((MIREPCB *)CURRENT_ITEM, &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_EDIT_MIRE:
        InstallMireOptionsFrame((MIREPCB *)CURRENT_ITEM, &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DELETE_MIRE:
        DrawPanel->MouseToCursorSchema();
        Delete_Mire((MIREPCB *)CURRENT_ITEM, &dc);
        GetScreen()->m_CurrentItem = NULL;
        break;

    case ID_POPUP_PCB_DELETE_COTATION:
        DrawPanel->MouseToCursorSchema();
        Delete_Cotation((COTATION*)CURRENT_ITEM, &dc);
        GetScreen()->m_CurrentItem = NULL;
        break;

    case ID_POPUP_PCB_EDIT_COTATION:
        Install_Edit_Cotation((COTATION*)CURRENT_ITEM, &dc, pos);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DELETE_DRAWING:
        Delete_Segment_Edge((DRAWSEGMENT *)CURRENT_ITEM, &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_DELETE_DRAWING_LAYER:
        Delete_Drawings_All_Layer((DRAWSEGMENT *)CURRENT_ITEM, &dc);
        GetScreen()->m_CurrentItem = NULL;
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_EDIT_DRAWING:
        Drawing_SetNewWidth((DRAWSEGMENT *)CURRENT_ITEM, &dc);
        DrawPanel->MouseToCursorSchema();
        break;

    case ID_POPUP_PCB_MOVE_DRAWING_REQUEST:
        DrawPanel->MouseToCursorSchema();
        Start_Move_DrawItem((DRAWSEGMENT *)CURRENT_ITEM, &dc);
        break;

    case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM && (CURRENT_ITEM->m_Flags & IS_NEW) )
        {
            End_Edge( (DRAWSEGMENT *)CURRENT_ITEM, &dc);
            GetScreen()->m_CurrentItem = NULL;
        }
        break;

    case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM && (CURRENT_ITEM->m_Flags & IS_NEW) )
        {
            End_Zone(&dc);
            GetScreen()->m_CurrentItem = NULL;
        }
        break;

    case ID_POPUP_PCB_DELETE_EDGE_ZONE:
        DrawPanel->MouseToCursorSchema();
        if ( CURRENT_ITEM && (CURRENT_ITEM->m_Flags & IS_NEW) )
        {
            GetScreen()->m_CurrentItem = Del_SegmEdgeZone(&dc,
                                         (EDGE_ZONE *) CURRENT_ITEM);
        }
        break;

    case ID_POPUP_PCB_FILL_ZONE:
        DrawPanel->MouseToCursorSchema();
        Fill_Zone(&dc);
        break;

    case ID_POPUP_PCB_SELECT_NET_ZONE:
        DrawPanel->MouseToCursorSchema();
        CaptureNetName(&dc);
        break;

    case ID_POPUP_PCB_SELECT_WIDTH:
        break;

    case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
    {
        int ii = m_SelTrackWidthBox->GetChoice();
        g_DesignSettings.m_CurrentTrackWidth = g_DesignSettings.m_TrackWidhtHistory[ii];
        DisplayTrackSettings();
        m_SelTrackWidthBox_Changed = FALSE;
        m_SelViaSizeBox_Changed = FALSE;
    }
    break;
    case ID_POPUP_PCB_SELECT_WIDTH1:
    case ID_POPUP_PCB_SELECT_WIDTH2:
    case ID_POPUP_PCB_SELECT_WIDTH3:
    case ID_POPUP_PCB_SELECT_WIDTH4:
    case ID_POPUP_PCB_SELECT_WIDTH5:
    case ID_POPUP_PCB_SELECT_WIDTH6:
    case ID_POPUP_PCB_SELECT_WIDTH7:
    case ID_POPUP_PCB_SELECT_WIDTH8:
        DrawPanel->MouseToCursorSchema();
        {
            int ii = id - ID_POPUP_PCB_SELECT_WIDTH1;
            g_DesignSettings.m_CurrentTrackWidth = g_DesignSettings.m_TrackWidhtHistory[ii];
            DisplayTrackSettings();
        }
        break;

    case ID_POPUP_PCB_SELECT_VIASIZE:
        break;

    case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
    {
        int ii = m_SelViaSizeBox->GetChoice();
        g_DesignSettings.m_CurrentViaSize = g_DesignSettings.m_ViaSizeHistory[ii];
        DisplayTrackSettings();
        m_SelTrackWidthBox_Changed = FALSE;
        m_SelViaSizeBox_Changed = FALSE;
    }
    break;

    case ID_POPUP_PCB_SELECT_VIASIZE1:
    case ID_POPUP_PCB_SELECT_VIASIZE2:
    case ID_POPUP_PCB_SELECT_VIASIZE3:
    case ID_POPUP_PCB_SELECT_VIASIZE4:
    case ID_POPUP_PCB_SELECT_VIASIZE5:
    case ID_POPUP_PCB_SELECT_VIASIZE6:
    case ID_POPUP_PCB_SELECT_VIASIZE7:
    case ID_POPUP_PCB_SELECT_VIASIZE8:
    case ID_POPUP_PCB_VIA_EDITING:
    case ID_POPUP_PCB_VIA_HOLE_TO_DEFAULT:
    case ID_POPUP_PCB_VIA_HOLE_TO_VALUE:
    case ID_POPUP_PCB_VIA_HOLE_ENTER_VALUE:
    case ID_POPUP_PCB_VIA_HOLE_EXPORT:
    case ID_POPUP_PCB_VIA_HOLE_RESET_TO_DEFAULT:
    case ID_POPUP_PCB_VIA_HOLE_EXPORT_TO_OTHERS:
        Via_Edit_Control(&dc, id, (SEGVIA *) GetScreen()->m_CurrentItem);
        break;

    case ID_POPUP_PCB_MOVE_TRACK_NODE:
        DrawPanel->MouseToCursorSchema();
        Start_MoveOneTrackSegment((TRACK *) GetScreen()->m_CurrentItem,
                                  &dc, TRUE);
        break;

    case ID_POPUP_PCB_BREAK_TRACK:
        DrawPanel->MouseToCursorSchema();
        {
            TRACK * track = (TRACK *) GetScreen()->m_CurrentItem;
            wxPoint pos = GetScreen()->m_Curseur;
            track->Draw(DrawPanel, &dc, GR_XOR);
            TRACK * newtrack = CreateLockPoint(&pos.x, &pos.y, track, NULL);
            track->Draw(DrawPanel, &dc, GR_XOR);
            newtrack->Draw(DrawPanel, &dc, GR_XOR);
        }
        break;

    case ID_MENU_PCB_CLEAN:
        Clean_Pcb(&dc);
        break;

    case ID_MENU_PCB_SWAP_LAYERS:
        Swap_Layers(event);
        break;

    case ID_POPUP_PCB_AUTOROUTE_GET_AUTOROUTER:
        GlobalRoute(&dc);
        break;

    case ID_POPUP_PCB_AUTOROUTE_GET_AUTOROUTER_DATA:
        ReadAutoroutedTracks(&dc);
        break;

    case ID_PCB_USER_GRID_SETUP:
        InstallGridFrame(pos);
        break;

    case ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC:
    {
        wxString msg = FindKicadHelpPath();
        msg += EDA_Appl->m_EDA_CommonConfig->Read(wxT("module_doc_file"),
                wxT("pcbnew/footprints.pdf"));
        GetAssociatedDocument(this, wxEmptyString, msg);
    }
    break;

    case ID_MENU_ARCHIVE_NEW_MODULES:
        Archive_Modules(wxEmptyString, TRUE);
        break;

    case ID_MENU_ARCHIVE_ALL_MODULES:
        Archive_Modules(wxEmptyString, FALSE);
        break;

    default:
    {
        DisplayError(this, wxT("WinEDA_PcbFrame::Process_Special_Functions() id error"));
        break;
    }
    }

    SetToolbars();
}