void SCH_EDIT_FRAME::OnUpdateBusOrientation( wxUpdateUIEvent& aEvent )
{
    wxString tool_tip = GetForceHVLines() ?
                        _( "Draw wires and buses in any direction" ) :
                        _( "Draw horizontal and vertical wires and buses only" );

    aEvent.Check( GetForceHVLines() );
    m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_BUS_WIRES_ORIENT, tool_tip );
}
void SCH_EDIT_FRAME::OnSetOptions( wxCommandEvent& event )
{
    wxArrayString units;
    GRIDS grid_list;

    GetScreen()->GetGrids( grid_list );

    DIALOG_EESCHEMA_OPTIONS dlg( this );

    units.Add( GetUnitsLabel( INCHES ) );
    units.Add( GetUnitsLabel( MILLIMETRES ) );

    dlg.SetUnits( units, g_UserUnit );
    dlg.SetGridSizes( grid_list, GetScreen()->GetGridId() );
    dlg.SetBusWidth( GetDefaultBusThickness() );
    dlg.SetLineWidth( GetDefaultLineThickness() );
    dlg.SetTextSize( GetDefaultLabelSize() );
    dlg.SetRepeatHorizontal( g_RepeatStep.x );
    dlg.SetRepeatVertical( g_RepeatStep.y );
    dlg.SetRepeatLabel( g_RepeatDeltaLabel );
    dlg.SetAutoSaveInterval( GetAutoSaveInterval() / 60 );
    dlg.SetRefIdSeparator( LIB_COMPONENT::GetSubpartIdSeparator( ),
                           LIB_COMPONENT::GetSubpartFirstId() );

    dlg.SetShowGrid( IsGridVisible() );
    dlg.SetShowHiddenPins( m_showAllPins );
    dlg.SetEnableMiddleButtonPan( m_canvas->GetEnableMiddleButtonPan() );
    dlg.SetEnableZoomNoCenter( m_canvas->GetEnableZoomNoCenter() );
    dlg.SetMiddleButtonPanLimited( m_canvas->GetMiddleButtonPanLimited() );
    dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() );
    dlg.SetEnableHVBusOrientation( GetForceHVLines() );
    dlg.SetShowPageLimits( g_ShowPageLimits );
    dlg.Layout();
    dlg.Fit();
    dlg.SetMinSize( dlg.GetSize() );

    const TEMPLATE_FIELDNAMES&  tfnames = m_TemplateFieldNames.GetTemplateFieldNames();

    for( unsigned i=0; i<tfnames.size(); ++i )
    {
        DBG(printf("dlg.SetFieldName(%d, '%s')\n", i, TO_UTF8( tfnames[i].m_Name) );)

        dlg.SetFieldName( i, tfnames[i].m_Name );
    }
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 );
    }
}
void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
{
    wxArrayString units;
    GRIDS grid_list = GetScreen()->GetGrids();
    bool saveProjectConfig = false;

    DIALOG_EESCHEMA_OPTIONS dlg( this );

    units.Add( GetUnitsLabel( INCHES ) );
    units.Add( GetUnitsLabel( MILLIMETRES ) );

    dlg.SetUnits( units, g_UserUnit );
    dlg.SetGridSizes( grid_list, GetScreen()->GetGridCmdId() );
    dlg.SetBusWidth( GetDefaultBusThickness() );
    dlg.SetLineWidth( GetDefaultLineThickness() );
    dlg.SetTextSize( GetDefaultTextSize() );
    dlg.SetRepeatHorizontal( GetRepeatStep().x );
    dlg.SetRepeatVertical( GetRepeatStep().y );
    dlg.SetRepeatLabel( GetRepeatDeltaLabel() );
    dlg.SetAutoSaveInterval( GetAutoSaveInterval() / 60 );
    dlg.SetRefIdSeparator( LIB_PART::GetSubpartIdSeparator(),
                           LIB_PART::GetSubpartFirstId() );

    dlg.SetShowGrid( IsGridVisible() );
    dlg.SetShowHiddenPins( m_showAllPins );
    dlg.SetEnableMousewheelPan( m_canvas->GetEnableMousewheelPan() );
    dlg.SetEnableZoomNoCenter( m_canvas->GetEnableZoomNoCenter() );
    dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() );
    dlg.SetEnableHVBusOrientation( GetForceHVLines() );
    dlg.SetShowPageLimits( m_showPageLimits );
    dlg.SetFootprintPreview( m_footprintPreview );
    dlg.SetAutoplaceFields( m_autoplaceFields );
    dlg.SetAutoplaceJustify( m_autoplaceJustify );
    dlg.SetAutoplaceAlign( m_autoplaceAlign );
    dlg.Layout();
    dlg.Fit();
    dlg.SetMinSize( dlg.GetSize() );
    dlg.SetTemplateFields( m_TemplateFieldNames.GetTemplateFieldNames() );

    if( dlg.ShowModal() == wxID_CANCEL )
        return;

    g_UserUnit = (EDA_UNITS_T)dlg.GetUnitsSelection();

    wxRealPoint  gridsize = grid_list[ (size_t) dlg.GetGridSelection() ].m_Size;
    m_LastGridSizeId = GetScreen()->SetGrid( gridsize );

    int sep, firstId;
    dlg.GetRefIdSeparator( sep, firstId);

    if( sep != (int)LIB_PART::GetSubpartIdSeparator() ||
        firstId != (int)LIB_PART::GetSubpartFirstId() )
    {
        LIB_PART::SetSubpartIdNotation( sep, firstId );
        saveProjectConfig = true;
    }

    SetDefaultBusThickness( dlg.GetBusWidth() );
    SetDefaultLineThickness( dlg.GetLineWidth() );

    if( dlg.GetTextSize() != GetDefaultTextSize() )
    {
        SetDefaultTextSize( dlg.GetTextSize() );
        saveProjectConfig = true;
    }

    wxPoint step;
    step.x = dlg.GetRepeatHorizontal();
    step.y = dlg.GetRepeatVertical();
    SetRepeatStep( step );
    SetRepeatDeltaLabel( dlg.GetRepeatLabel() );

    SetAutoSaveInterval( dlg.GetAutoSaveInterval() * 60 );
    SetGridVisibility( dlg.GetShowGrid() );
    m_showAllPins = dlg.GetShowHiddenPins();
    m_canvas->SetEnableMousewheelPan( dlg.GetEnableMousewheelPan() );
    m_canvas->SetEnableZoomNoCenter( dlg.GetEnableZoomNoCenter() );
    m_canvas->SetEnableAutoPan( dlg.GetEnableAutoPan() );
    SetForceHVLines( dlg.GetEnableHVBusOrientation() );
    m_showPageLimits = dlg.GetShowPageLimits();
    m_autoplaceFields = dlg.GetAutoplaceFields();
    m_autoplaceJustify = dlg.GetAutoplaceJustify();
    m_autoplaceAlign = dlg.GetAutoplaceAlign();
    m_footprintPreview = dlg.GetFootprintPreview();

    // Delete all template fieldnames and then restore them using the template field data from
    // the options dialog
    DeleteAllTemplateFieldNames();
    TEMPLATE_FIELDNAMES newFieldNames = dlg.GetTemplateFields();

    for( TEMPLATE_FIELDNAMES::iterator dlgfld = newFieldNames.begin();
         dlgfld != newFieldNames.end(); ++dlgfld )
    {
        TEMPLATE_FIELDNAME fld = *dlgfld;
        AddTemplateFieldName( fld );
    }

    SaveSettings( config() );  // save values shared by eeschema applications.

    if( saveProjectConfig )
        SaveProjectSettings( true );

    m_canvas->Refresh( true );
}