Пример #1
0
void WinEDA_SchematicFrame::OnLeftDClick(wxDC * DC, const wxPoint& MousePos)
/***************************************************************************/
/* Appelé sur un double click:
	pour un élément editable (textes, composant):
		appel de l'editeur correspondant.
	pour une connexion en cours:
		termine la connexion
*/
{
EDA_BaseStruct * DrawStruct = m_CurrentScreen->m_CurrentItem;
wxPoint pos = GetPosition();

	switch ( m_ID_current_state )
	{
		case 0:
			if ( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) )
			{
				DrawStruct = SchematicGeneralLocateAndDisplay();
			}

			if ( (DrawStruct == NULL) || (DrawStruct->m_Flags != 0) )
				break;

				// Element localisé
			switch ( DrawStruct->m_StructType )
			{
				case DRAW_SHEET_STRUCT_TYPE:
					InstallNextScreen((DrawSheetStruct *) DrawStruct);
					break;
				
				case DRAW_LIB_ITEM_STRUCT_TYPE:
					InstallCmpeditFrame(this, pos, (EDA_SchComponentStruct *) DrawStruct);
					DrawPanel->MouseToCursorSchema();
					break;

				case DRAW_TEXT_STRUCT_TYPE:
				case DRAW_LABEL_STRUCT_TYPE:
				case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
					EditSchematicText( (DrawTextStruct*)DrawStruct, DC);
					break;

				case DRAW_PART_TEXT_STRUCT_TYPE:
					EditCmpFieldText( (PartTextStruct *)DrawStruct, DC);
					DrawPanel->MouseToCursorSchema();
					break;

				default:
					break;
			}
			break;	// end case 0

		case ID_BUS_BUTT:
		case ID_WIRE_BUTT:
			if ( DrawStruct && (DrawStruct->m_Flags & IS_NEW) )
				EndSegment(DC);
			break;
	}
}
void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
{
    SCH_LINE* segment;
    SCH_LINE* nextSegment;
    wxPoint   cursorpos = GetCrossHairPosition();

    // We should know if a segment is currently in progress
    segment = (SCH_LINE*) GetScreen()->GetCurItem();
    if( segment )   // a current item exists, but not necessary a currently edited item
    {
        if( !segment->GetFlags() || ( segment->Type() != SCH_LINE_T ) )
        {
            if( segment->GetFlags() )
            {
                wxLogDebug( wxT( "BeginSegment: item->GetFlags()== %X" ),
                    segment->GetFlags() );
            }
            // no wire, bus or graphic line in progress
            segment = NULL;
        }
    }

    if( !segment )      // first point : Create the first wire or bus segment
    {
        switch( type )
        {
        default:
            segment = new SCH_LINE( cursorpos, LAYER_NOTES );
            break;

        case LAYER_WIRE:
            segment = new SCH_LINE( cursorpos, LAYER_WIRE );

            /* A junction will be created later, when we'll know the
             * segment end position, and if the junction is really needed */
            break;

        case LAYER_BUS:
            segment = new SCH_LINE( cursorpos, LAYER_BUS );
            break;
        }

        segment->SetFlags( IS_NEW );
        s_wires.PushBack( segment );
        GetScreen()->SetCurItem( segment );

        // We need 2 segments to go from a given start pin to an end point when the horizontal
        // and vertical lines only switch is on.
        if( GetForceHVLines() )
        {
            nextSegment = new SCH_LINE( *segment );
            nextSegment->SetFlags( IS_NEW );
            s_wires.PushBack( nextSegment );
            GetScreen()->SetCurItem( nextSegment );
        }

        m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
        SetRepeatItem( NULL );
    }
    else    // A segment is in progress: terminates the current segment and add a new segment.
    {
        SCH_LINE* prevSegment = segment->Back();

        // Be aware prevSegment can be null when the horizontal and vertical lines only switch is off
        // when we create the first segment.

        if( !GetForceHVLines() )
        {
            // If only one segment is needed and it has a zero length, do not create a new one.
            if( segment->IsNull() )
                return;
        }
        else
        {
            wxCHECK_RET( prevSegment != NULL, wxT( "Failed to create second line segment." ) );

            // If two segments are required and they both have zero length, do not
            // create a new one.
            if( prevSegment && prevSegment->IsNull() && segment->IsNull() )
                return;
        }

        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );

        // Terminate the command if the end point is on a pin, junction, or another wire or bus.
        if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
        {
            EndSegment( DC );
            return;
        }

        // Create a new segment, and chain it after the current new segment.
        nextSegment = new SCH_LINE( *segment );
        nextSegment->SetStartPoint( cursorpos );
        s_wires.PushBack( nextSegment );

        segment->SetEndPoint( cursorpos );
        segment->ClearFlags( IS_NEW );
        segment->SetFlags( SELECTED );
        nextSegment->SetFlags( IS_NEW );
        GetScreen()->SetCurItem( nextSegment );
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
    }
}
Пример #3
0
void WinEDA_SchematicFrame::BeginSegment(wxDC * DC, int type)
/*************************************************************/
/* Routine de Trace de segments ( WIRES, BUS ) pour lesquels chaque segment
est une structure.
*/
{
DrawSegmentStruct * oldsegment, * newsegment;
wxPoint pos = GetScreen()->m_Curseur;

	if ( GetScreen()->m_CurrentItem &&
		 (GetScreen()->m_CurrentItem->m_Flags == 0) )
		GetScreen()->m_CurrentItem = NULL;

	if ( GetScreen()->m_CurrentItem )
		{
		switch (GetScreen()->m_CurrentItem->m_StructType )
			{
			case DRAW_SEGMENT_STRUCT_TYPE:
			case DRAW_POLYLINE_STRUCT_TYPE:
				break;

			default:
				return;
			}
		}

	oldsegment = newsegment =
			(DrawSegmentStruct *) GetScreen()->m_CurrentItem;

	if (!newsegment)  /* 1er point : creation de la 1ere structure */
	{

		switch(type)
		{
			default:
				newsegment = new DrawSegmentStruct(pos, LAYER_NOTES);
				break;
			case LAYER_WIRE:
				newsegment = new DrawSegmentStruct(pos, LAYER_WIRE);
				if ( LocatePinEnd(GetScreen()->EEDrawList, pos) )
					newsegment->m_StartIsDangling = FALSE;
				break;
			case LAYER_BUS:
				newsegment = new DrawSegmentStruct(pos, LAYER_BUS);
				break;
		}

		newsegment->m_Flags = IS_NEW;
		GetScreen()->m_CurrentItem = newsegment;
		GetScreen()->ManageCurseur = Segment_in_Ghost;
		GetScreen()->ForceCloseManageCurseur = ExitTrace;
		g_ItemToRepeat = NULL;
	}

	else	/* Trace en cours: Placement d'un point supplementaire */
	{
		if( (oldsegment->m_Start.x == oldsegment->m_End.x) &&
			(oldsegment->m_Start.y == oldsegment->m_End.y) )	/* Structure inutile */
			return;
		GetScreen()->ManageCurseur(DrawPanel, DC, FALSE);
		oldsegment->m_EndIsDangling = FALSE;

		/* Creation du segment suivant ou fin de tracé si point sur pin, jonction ...*/
		if ( IsTerminalPoint(GetScreen(), oldsegment->m_End, oldsegment->m_Layer) )
		{
			EndSegment(DC); return;
		}

		/* Placement en liste generale */
		oldsegment->Pnext = GetScreen()->EEDrawList;
		g_ItemToRepeat = GetScreen()->EEDrawList = oldsegment;
		GetScreen()->Trace_Curseur(DrawPanel, DC);	// Erase schematic cursor
		RedrawOneStruct(DrawPanel,DC, oldsegment, GR_DEFAULT_DRAWMODE);
		GetScreen()->Trace_Curseur(DrawPanel, DC);	// Display schematic cursor

		/* Creation du segment suivant */
		newsegment = oldsegment->GenCopy();
		newsegment->m_Start = oldsegment->m_End;
		newsegment->m_End = pos;
		oldsegment->m_Flags = 0;
		newsegment->m_Flags = IS_NEW;
		GetScreen()->m_CurrentItem = newsegment;
		GetScreen()->ManageCurseur(DrawPanel, DC, FALSE);
		newsegment->m_StartIsDangling = FALSE;
		newsegment->m_EndIsDangling = TRUE;
	}
}
Пример #4
0
void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
    int         id = event.GetId();
    wxPoint     pos;
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    pos = wxGetMousePosition();

    pos.y += 20;

    // If needed, stop the current command and deselect current tool
    switch( id )
    {
    case wxID_CUT:
    case wxID_COPY:
    case ID_POPUP_CANCEL_CURRENT_COMMAND:
    case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
    case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
    case ID_POPUP_SCH_BEGIN_WIRE:
    case ID_POPUP_SCH_BEGIN_BUS:
    case ID_POPUP_END_LINE:
    case ID_POPUP_SCH_SET_SHAPE_TEXT:
    case ID_POPUP_SCH_CLEANUP_SHEET:
    case ID_POPUP_SCH_END_SHEET:
    case ID_POPUP_SCH_RESIZE_SHEET:
    case ID_POPUP_IMPORT_GLABEL:
    case ID_POPUP_SCH_INIT_CMP:
    case ID_POPUP_SCH_DISPLAYDOC_CMP:
    case ID_POPUP_SCH_EDIT_CONVERT_CMP:
    case ID_POPUP_DELETE_BLOCK:
    case ID_POPUP_PLACE_BLOCK:
    case ID_POPUP_ZOOM_BLOCK:
    case ID_POPUP_DRAG_BLOCK:
    case ID_POPUP_COPY_BLOCK:
    case ID_POPUP_SCH_DELETE_NODE:
    case ID_POPUP_SCH_DELETE_CONNECTION:
    case ID_POPUP_SCH_ENTER_SHEET:
    case ID_POPUP_SCH_LEAVE_SHEET:
    case ID_POPUP_SCH_ADD_JUNCTION:
    case ID_POPUP_SCH_ADD_LABEL:
    case ID_POPUP_SCH_GETINFO_MARKER:

        /* At this point: Do nothing. these commands do not need to stop the
         * current command (mainly a block command) or reset the current state
         * They will be executed later, in next switch structure.
         */
        break;

    case ID_POPUP_SCH_DELETE_CMP:
    case ID_POPUP_SCH_DELETE:

        // Stop the current command (if any) but keep the current tool
        m_canvas->EndMouseCapture();
        break;

    default:

        // Stop the current command and deselect the current tool
        m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
        break;
    }

    INSTALL_UNBUFFERED_DC( dc, m_canvas );
    item = screen->GetCurItem();    // Can be modified by previous calls.

    switch( id )
    {
    case ID_HIERARCHY:
        InstallHierarchyFrame( &dc, pos );
        SetRepeatItem( NULL );
        break;

    case wxID_CUT:
        if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
            break;

        screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        SetRepeatItem( NULL );
        SetSheetNumberAndCount();
        break;

    case wxID_PASTE:
        HandleBlockBegin( &dc, BLOCK_PASTE, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
        m_canvas->MoveCursorToCrossHair();
        SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '/' );
        break;

    case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
        m_canvas->MoveCursorToCrossHair();
        SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '\\' );
        break;

    case ID_POPUP_CANCEL_CURRENT_COMMAND:
        if( m_canvas->IsMouseCaptured() )
        {
            m_canvas->EndMouseCapture();
            SetToolID( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString );
        }
        else
        {
            SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
        }

        break;

    case ID_POPUP_END_LINE:
        m_canvas->MoveCursorToCrossHair();
        EndSegment( &dc );
        break;

    case ID_POPUP_SCH_BEGIN_WIRE:
        m_canvas->MoveCursorToCrossHair();
        OnLeftClick( &dc, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_BEGIN_BUS:
        m_canvas->MoveCursorToCrossHair();
        OnLeftClick( &dc, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_SET_SHAPE_TEXT:
        // Not used
        break;

    case ID_POPUP_SCH_DELETE_NODE:
    case ID_POPUP_SCH_DELETE_CONNECTION:
        m_canvas->MoveCursorToCrossHair();
        DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
        screen->SetCurItem( NULL );
        SetRepeatItem( NULL );
        screen->TestDanglingEnds( m_canvas, &dc );
        m_canvas->Refresh();
        break;

    case ID_POPUP_SCH_BREAK_WIRE:
    {
        DLIST< SCH_ITEM > oldWires;

        oldWires.SetOwnership( false );      // Prevent DLIST for deleting items in destructor.
        m_canvas->MoveCursorToCrossHair();
        screen->ExtractWires( oldWires, true );
        screen->BreakSegment( GetCrossHairPosition() );

        if( oldWires.GetCount() != 0 )
        {
            PICKED_ITEMS_LIST oldItems;

            oldItems.m_Status = UR_WIRE_IMAGE;

            while( oldWires.GetCount() != 0 )
            {
                ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
                oldItems.PushItem( picker );
            }

            SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
        }

        screen->TestDanglingEnds( m_canvas, &dc );
    }
    break;

    case ID_POPUP_SCH_DELETE_CMP:
    case ID_POPUP_SCH_DELETE:
        if( item == NULL )
            break;

        DeleteItem( item );
        screen->SetCurItem( NULL );
        SetRepeatItem( NULL );
        screen->TestDanglingEnds( m_canvas, &dc );
        SetSheetNumberAndCount();
        OnModify();
        break;

    case ID_POPUP_SCH_END_SHEET:
        m_canvas->MoveCursorToCrossHair();
        addCurrentItemToList( &dc );
        break;

    case ID_POPUP_SCH_RESIZE_SHEET:
        ReSizeSheet( (SCH_SHEET*) item, &dc );
        screen->TestDanglingEnds( m_canvas, &dc );
        break;

    case ID_POPUP_IMPORT_GLABEL:
        if( item != NULL && item->Type() == SCH_SHEET_T )
            screen->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, &dc ) );
        break;

    case ID_POPUP_SCH_CLEANUP_SHEET:
        if( item != NULL && item->Type() == SCH_SHEET_T )
        {
            SCH_SHEET* sheet = (SCH_SHEET*) item;

            if( !sheet->HasUndefinedPins() )
            {
                DisplayInfoMessage( this,
                                    _( "There are no undefined labels in this sheet to clean up." ) );
                return;
            }

            if( !IsOK( this, _( "Do you wish to cleanup this sheet?" ) ) )
                return;

            /* Save sheet in undo list before cleaning up unreferenced hierarchical labels. */
            SaveCopyInUndoList( sheet, UR_CHANGED );
            sheet->CleanupSheet();
            OnModify();
            m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
        }
        break;

    case ID_POPUP_SCH_INIT_CMP:
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_SCH_EDIT_CONVERT_CMP:

        // Ensure the struct is a component (could be a struct of a component, like Field, text..)
        if( item && item->Type() == SCH_COMPONENT_T )
        {
            m_canvas->MoveCursorToCrossHair();
            ConvertPart( (SCH_COMPONENT*) item, &dc );
        }

        break;

    case ID_POPUP_SCH_DISPLAYDOC_CMP:

        // Ensure the struct is a component (could be a piece of a component, like Field, text..)
        if( item && item->Type() == SCH_COMPONENT_T )
        {
            LIB_ALIAS* LibEntry;
            LibEntry = CMP_LIBRARY::FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetLibName() );

            if( LibEntry && LibEntry->GetDocFileName() != wxEmptyString )
            {
                GetAssociatedDocument( this, LibEntry->GetDocFileName(),
                                       &wxGetApp().GetLibraryPathList() );
            }
        }
        break;

    case ID_POPUP_SCH_ENTER_SHEET:

        if( item && (item->Type() == SCH_SHEET_T) )
        {
            m_CurrentSheet->Push( (SCH_SHEET*) item );
            DisplayCurrentSheet();
        }

        break;

    case ID_POPUP_SCH_LEAVE_SHEET:
        m_CurrentSheet->Pop();
        DisplayCurrentSheet();
        break;

    case wxID_COPY:         // really this is a Save block for paste
        screen->m_BlockLocate.SetCommand( BLOCK_SAVE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_PLACE_BLOCK:
        m_canvas->SetAutoPanRequest( false );
        m_canvas->MoveCursorToCrossHair();
        HandleBlockPlace( &dc );
        break;

    case ID_POPUP_ZOOM_BLOCK:
        screen->m_BlockLocate.SetCommand( BLOCK_ZOOM );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_DELETE_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        SetSheetNumberAndCount();
        break;

    case ID_POPUP_COPY_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_COPY );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_DRAG_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_DRAG );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_SCH_ADD_JUNCTION:
        m_canvas->MoveCursorToCrossHair();
        screen->SetCurItem( AddJunction( &dc, GetCrossHairPosition(), true ) );
        screen->TestDanglingEnds( m_canvas, &dc );
        screen->SetCurItem( NULL );
        break;

    case ID_POPUP_SCH_ADD_LABEL:
    case ID_POPUP_SCH_ADD_GLABEL:
        screen->SetCurItem( CreateNewText( &dc, id == ID_POPUP_SCH_ADD_LABEL ?
                                           LAYER_LOCLABEL : LAYER_GLOBLABEL ) );
        item = screen->GetCurItem();

        if( item )
            addCurrentItemToList( &dc );

        break;

    case ID_POPUP_SCH_GETINFO_MARKER:
        if( item && item->Type() == SCH_MARKER_T )
            ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );

        break;

    default:        // Log error:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot process command event ID %d" ),
                                      event.GetId() ) );
        break;
    }

    // End switch ( id )    (Command execution)

    if( GetToolId() == ID_NO_TOOL_SELECTED )
        SetRepeatItem( NULL );
}
/**
 * Function OnLeftDClick
 * called on a double click event from the drawpanel mouse handler
 *  if an editable item is found (text, component)
 *      Call the suitable dialog editor.
 *  Id a create command is in progress:
 *      validate and finish the command
 */
void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )

{
    EDA_ITEM* item = GetScreen()->GetCurItem();

    switch( GetToolId() )
    {
    case ID_NO_TOOL_SELECTED:
        if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
        {
            item = LocateAndShowItem( aPosition );
        }

        if( ( item == NULL ) || ( item->GetFlags() != 0 ) )
            break;

        switch( item->Type() )
        {
        case SCH_SHEET_T:
            m_CurrentSheet->push_back( (SCH_SHEET*) item );
            DisplayCurrentSheet();
            break;

        case SCH_COMPONENT_T:
            EditComponent( (SCH_COMPONENT*) item );
            GetCanvas()->MoveCursorToCrossHair();

            if( item->GetFlags() == 0 )
                GetScreen()->SetCurItem( NULL );

            GetCanvas()->Refresh();
            break;

        case SCH_TEXT_T:
        case SCH_LABEL_T:
        case SCH_GLOBAL_LABEL_T:
        case SCH_HIERARCHICAL_LABEL_T:
            EditSchematicText( (SCH_TEXT*) item );
            break;

        case SCH_BITMAP_T:
            EditImage( (SCH_BITMAP*) item );
            break;

        case SCH_FIELD_T:
            EditComponentFieldText( (SCH_FIELD*) item );
            GetCanvas()->MoveCursorToCrossHair();
            break;

        case SCH_MARKER_T:
            ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );
            break;

        default:
            break;
        }

        break;

    case ID_BUS_BUTT:
    case ID_WIRE_BUTT:
    case ID_LINE_COMMENT_BUTT:
        if( item && item->IsNew() )
            EndSegment( aDC );

        break;
    }
}