예제 #1
0
void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
{
    KIGFX::VIEW* view = GetGalCanvas()->GetView();
    KIGFX::GAL* gal = GetGalCanvas()->GetGAL();

    double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();

    // Display the same view after canvas switching
    if( aEnable )
    {
        BASE_SCREEN* screen = GetScreen();

        // Switch to GAL rendering
        if( !IsGalCanvasActive() )
        {
            // Set up viewport
            double zoom = 1.0 / ( zoomFactor * m_canvas->GetZoom() );
            view->SetScale( zoom );
            view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) );
        }

        // Set up grid settings
        gal->SetGridVisibility( IsGridVisible() );
        gal->SetGridSize( VECTOR2D( screen->GetGridSize().x, screen->GetGridSize().y ) );
        gal->SetGridOrigin( VECTOR2D( GetGridOrigin() ) );
    }
    else
    {
        // Switch to standard rendering
        if( IsGalCanvasActive() )
        {
            // Change view settings only if GAL was active previously
            double zoom = 1.0 / ( zoomFactor * view->GetScale() );
            m_canvas->SetZoom( zoom );

            VECTOR2D center = view->GetCenter();
            RedrawScreen( wxPoint( center.x, center.y ), false );
        }
    }

    m_canvas->SetEvtHandlerEnabled( !aEnable );
    GetGalCanvas()->SetEvtHandlerEnabled( aEnable );

    // Switch panes
    m_auimgr.GetPane( wxT( "DrawFrame" ) ).Show( !aEnable );
    m_auimgr.GetPane( wxT( "DrawFrameGal" ) ).Show( aEnable );
    m_auimgr.Update();

    // Reset current tool on switch();
    SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    m_galCanvasActive = aEnable;
}
void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
{
    PCB_BASE_FRAME::SetPageSettings( aPageSettings );

    if( IsGalCanvasActive() )
    {
        PCB_DRAW_PANEL_GAL* drawPanel = static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() );

        // Prepare worksheet template
        KIGFX::WORKSHEET_VIEWITEM* worksheet;
        worksheet = new KIGFX::WORKSHEET_VIEWITEM( &m_Pcb->GetPageSettings(),
                                                   &m_Pcb->GetTitleBlock() );
        worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );

        BASE_SCREEN* screen = GetScreen();

        if( screen != NULL )
        {
            worksheet->SetSheetNumber( screen->m_ScreenNumber );
            worksheet->SetSheetCount( screen->m_NumberOfScreens );
        }

        // PCB_DRAW_PANEL_GAL takes ownership of the worksheet
        drawPanel->SetWorksheet( worksheet );
    }
}
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
    if( GetScreen()->IsModify() && GetBoard()->m_Modules )
    {
        if( !HandleUnsavedChanges( this, _( "Save changes to footprint before closing?" ),
                                   [&]()->bool { return SaveFootprint( GetBoard()->m_Modules ); } ) )
        {
            Event.Veto();
            return;
        }
    }

    if( IsGalCanvasActive() )
    {
        GetGalCanvas()->SetEventDispatcher( NULL );
        GetGalCanvas()->StopDrawing();
    }

    // Do not show the layer manager during closing to avoid flicker
    // on some platforms (Windows) that generate useless redraw of items in
    // the Layer Manger
    m_auimgr.GetPane( "LayersManager" ).Show( false );

    Clear_Pcb( false );

    //close the editor
    Destroy();
}
void PCB_EDIT_FRAME::enableGALSpecificMenus()
{
    // some menus are active only in GAL mode and do nothing in legacy mode.
    // So enable or disable them, depending on the display mode

    if( GetMenuBar() )
    {
        // Enable / disable some menus which are usable only on GAL
        pcbnew_ids id_list[] =
        {
            ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
            ID_DIFF_PAIR_BUTT,
            ID_TUNE_SINGLE_TRACK_LEN_BUTT,
            ID_TUNE_DIFF_PAIR_LEN_BUTT,
            ID_TUNE_DIFF_PAIR_SKEW_BUTT,
            ID_MENU_DIFF_PAIR_DIMENSIONS
        };

        bool enbl = IsGalCanvasActive();

        for( unsigned ii = 0; ii < DIM( id_list ); ii++ )
        {
            if( GetMenuBar()->FindItem( id_list[ii] ) )
                GetMenuBar()->FindItem( id_list[ii] )->Enable( enbl );
        }
    }
}
예제 #5
0
void EDA_DRAW_FRAME::OnSelectZoom( wxCommandEvent& event )
{
    if( m_zoomSelectBox == NULL )
        return;                        // Should not happen!

    int id = m_zoomSelectBox->GetCurrentSelection();

    if( id < 0 || !( id < (int)m_zoomSelectBox->GetCount() ) )
        return;

    if( id == 0 )                      // Auto zoom (Fit in Page)
    {
        Zoom_Automatique( true );
    }
    else
    {
        id--;
        double selectedZoom = GetScreen()->m_ZoomList[id];

        if( GetScreen()->GetZoom() == selectedZoom )
            return;

        GetScreen()->SetZoom( selectedZoom );
        RedrawScreen( GetScrollCenterPosition(), false );
    }

    // Notify GAL
    TOOL_MANAGER* mgr = GetToolManager();

    if( mgr && IsGalCanvasActive() )
        mgr->RunAction( "common.Control.zoomPreset", true, id );
}
예제 #6
0
int EDA_DRAW_FRAME::WriteHotkeyConfig( struct EDA_HOTKEY_CONFIG* aDescList, wxString* aFullFileName )
{
    int result = EDA_BASE_FRAME::WriteHotkeyConfig( aDescList, aFullFileName );

    if( IsGalCanvasActive() )
        GetToolManager()->UpdateHotKeys();

    return result;
}
예제 #7
0
void PCB_BASE_FRAME::OnModify()
{
    GetScreen()->SetModify();
    GetScreen()->SetSave();

    if( IsGalCanvasActive() )
    {
        UpdateStatusBar();
        UpdateMsgPanel();
    }
}
예제 #8
0
void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer )
{
    PCB_BASE_FRAME::SetActiveLayer( aLayer );

    GetGalCanvas()->SetHighContrastLayer( aLayer );

    m_Layers->SelectLayer( GetActiveLayer() );
    m_Layers->OnLayerSelected();

    if( IsGalCanvasActive() )
        GetGalCanvas()->Refresh();
}
예제 #9
0
파일: pcbframe.cpp 프로젝트: jerkey/kicad
void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate )
{
    ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer;

    setHighContrastLayer( aLayer );

    if( doLayerWidgetUpdate )
        syncLayerWidgetLayer();

    if( IsGalCanvasActive() )
        GetGalCanvas()->Refresh();
}
예제 #10
0
void EDA_DRAW_FRAME::OnToggleGridState( wxCommandEvent& aEvent )
{
    SetGridVisibility( !IsGridVisible() );

    if( IsGalCanvasActive() )
    {
        GetGalCanvas()->GetGAL()->SetGridVisibility( IsGridVisible() );
        GetGalCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
    }

    m_canvas->Refresh();
}
void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
{
    PCB_BASE_EDIT_FRAME::SetBoard( aBoard );

    if( IsGalCanvasActive() )
    {
        aBoard->GetRatsnest()->Recalculate();

        // reload the worksheet
        SetPageSettings( aBoard->GetPageSettings() );
    }
}
예제 #12
0
void EDA_DRAW_FRAME::SetNoToolSelected()
{
    // Select the ID_NO_TOOL_SELECTED id tool (Idle tool)

    int defaultCursor = wxCURSOR_DEFAULT;

    // Change GAL canvas cursor if requested.
    if( IsGalCanvasActive() )
        defaultCursor = GetGalCanvas()->GetDefaultCursor();
    else if( m_canvas )
        defaultCursor = m_canvas->GetDefaultCursor();

    SetToolID( ID_NO_TOOL_SELECTED, defaultCursor, wxEmptyString );
}
예제 #13
0
wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const
{
    // subject to change, borrow from old BASE_SCREEN for now.
    if( IsGalCanvasActive() )
    {
        VECTOR2I cursor = GetGalCanvas()->GetViewControls()->GetCursorPosition();

        return wxPoint( cursor.x, cursor.y );
    }
    else
    {
        BASE_SCREEN* screen = GetScreen();  // virtual call
        return screen->getCrossHairPosition( aInvertY );
    }
}
void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer )
{
    PCB_BASE_FRAME::SetActiveLayer( aLayer );

    GetGalCanvas()->SetHighContrastLayer( aLayer );

    syncLayerWidgetLayer();

    if( IsGalCanvasActive() )
    {
        m_toolManager->RunAction( COMMON_ACTIONS::layerChanged );       // notify other tools
        GetGalCanvas()->SetFocus();                 // otherwise hotkeys are stuck somewhere
        GetGalCanvas()->Refresh();
    }
}
void PCB_EDIT_FRAME::OnResetModuleTextSizes( wxCommandEvent& event )
{
    DIALOG_GLOBAL_MODULES_FIELDS_EDITION dlg(this);
    dlg.ShowModal();

    if( IsGalCanvasActive() )
    {
        for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
        {
            module->Value().ViewUpdate();
            module->Reference().ViewUpdate();
        }
    }

    m_canvas->Refresh();
}
예제 #16
0
void PCB_EDIT_FRAME::SetGridColor( EDA_COLOR_T aColor )
{

    GetBoard()->SetVisibleElementColor( GRID_VISIBLE, aColor );

    if( IsGalCanvasActive() )
    {
        StructColors c = g_ColorRefs[ aColor ];
        KIGFX::COLOR4D color(  (double) c.m_Red / 255.0,
                        (double) c.m_Green / 255.0,
                        (double) c.m_Blue / 255.0,
                        0.7 );

         GetGalCanvas()->GetGAL()->SetGridColor( color );
    }
}
bool PCB_BASE_FRAME::InvokeDialogGrid()
{
    wxPoint grid_origin = GetGridOrigin();

    DIALOG_SET_GRID dlg( this, &m_UserGridUnit, g_UserUnit, &m_UserGridSize,
        &grid_origin, &m_FastGrid1, &m_FastGrid2,
        m_gridSelectBox->GetStrings() );

    int ret = dlg.ShowModal();

    if( ret == wxID_OK )
    {
        if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) )
            OnModify();     // because grid origin is saved in board, show as modified

        SetGridOrigin( grid_origin );

        BASE_SCREEN* screen = GetScreen();

        screen->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );

        // If the user grid is the current option, recall SetGrid()
        // to force new values put in list as current grid value
        if( screen->GetGridCmdId() == ID_POPUP_GRID_USER )
            screen->SetGrid( ID_POPUP_GRID_USER );

        // Notify GAL
        TOOL_MANAGER* mgr = GetToolManager();

        if( mgr && IsGalCanvasActive() )
        {
            mgr->RunAction( "common.Control.gridPreset", true,
                    screen->GetGridCmdId() - ID_POPUP_GRID_LEVEL_1000 );

            TOOL_EVENT gridOriginUpdate = COMMON_ACTIONS::gridSetOrigin.MakeEvent();
            gridOriginUpdate.SetParameter( new VECTOR2D( grid_origin ) );
            mgr->ProcessEvent( gridOriginUpdate );
        }

        m_canvas->Refresh();

        return true;
    }

    return false;
}
예제 #18
0
void PCB_BASE_FRAME::UpdateMsgPanel()
{
    BOARD_ITEM* item = GetScreen()->GetCurItem();
    MSG_PANEL_ITEMS items;

    if( item )
    {
        item->GetMsgPanelInfo( items );
    }
    else       // show general information about the board
    {
        if( IsGalCanvasActive() )
            GetGalCanvas()->GetMsgPanelInfo( items );
        else
            m_Pcb->GetMsgPanelInfo( items );
    }

    SetMsgPanel( items );
}
예제 #19
0
void PCB_BASE_FRAME::OnUpdateSelectZoom( wxUpdateUIEvent& aEvent )
{
    if( m_zoomSelectBox == NULL || m_auxiliaryToolBar == NULL )
        return;

    int current = 0;
    double zoom = IsGalCanvasActive() ? GetGalCanvas()->GetLegacyZoom() : GetScreen()->GetZoom();

    for( unsigned i = 0; i < GetScreen()->m_ZoomList.size(); i++ )
    {
        if( std::fabs( zoom - GetScreen()->m_ZoomList[i] ) < 1e-6 )
        {
            current = i + 1;
            break;
        }
    }

    if( current != m_zoomSelectBox->GetSelection() )
        m_zoomSelectBox->SetSelection( current );
}
예제 #20
0
void EDA_DRAW_FRAME::OnSelectGrid( wxCommandEvent& event )
{
    int* clientData;
    int  eventId = ID_POPUP_GRID_LEVEL_100;

    if( event.GetEventType() == wxEVT_CHOICE )
    {
        if( m_gridSelectBox == NULL )   // Should not happen
            return;

        /*
         * Don't use wxCommandEvent::GetClientData() here.  It always
         * returns NULL in GTK.  This solution is not as elegant but
         * it works.
         */
        int index = m_gridSelectBox->GetSelection();
        wxASSERT( index != wxNOT_FOUND );
        clientData = (int*) m_gridSelectBox->wxItemContainer::GetClientData( index );

        if( clientData != NULL )
            eventId = *clientData;
    }
    else
    {
        eventId = event.GetId();
    }

    int idx = eventId - ID_POPUP_GRID_LEVEL_1000;

    // Notify GAL
    TOOL_MANAGER* mgr = GetToolManager();

    if( mgr && IsGalCanvasActive() )
    {
        mgr->RunAction( "common.Control.gridPreset", true, idx );
    }
    else
        SetPresetGrid( idx );

    m_canvas->Refresh();
}
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
    if( GetScreen()->IsModify() )
    {
        int ii = DisplayExitDialog( this, _( "Save the changes to the footprint before closing?" ) );

        switch( ii )
        {
        case wxID_NO:
            break;

        case wxID_YES:
            // code from FOOTPRINT_EDIT_FRAME::Process_Special_Functions,
            // at case ID_MODEDIT_SAVE_LIBMODULE
            if( GetBoard()->m_Modules && GetCurrentLib().size() )
            {
                if( SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true ) )
                {
                    // save was correct
                    GetScreen()->ClrModify();
                    break;
                }
            }
            else
            {
                DisplayError( this, _( "Library is not set, the footprint could not be saved." ) );
            }
            // fall through: cancel the close because of an error

        case wxID_CANCEL:
            Event.Veto();
            return;
        }
    }

    if( IsGalCanvasActive() )
        GetGalCanvas()->StopDrawing();

    //close the editor
    Destroy();
}
예제 #22
0
bool PCB_BASE_FRAME::InvokeDialogGrid()
{
    wxPoint grid_origin = GetGridOrigin();

    DIALOG_SET_GRID dlg( this, &m_UserGridUnit, g_UserUnit, &m_UserGridSize,
        &grid_origin, &m_FastGrid1, &m_FastGrid2,
        m_gridSelectBox->GetStrings() );

    int ret = dlg.ShowModal();

    if( ret == wxID_OK )
    {
        if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) )
            OnModify();     // because grid origin is saved in board, show as modified

        SetGridOrigin( grid_origin );

        BASE_SCREEN* screen = GetScreen();

        screen->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );

        // If the user grid is the current option, recall SetGrid()
        // to force new values put in list as current grid value
        if( screen->GetGridId() == ID_POPUP_GRID_USER )
            screen->SetGrid( ID_POPUP_GRID_USER );

        if( IsGalCanvasActive() )
        {
            GetGalCanvas()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGrid().m_Size.x,
                                                             screen->GetGrid().m_Size.y ) );
            GetGalCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
        }

        m_canvas->Refresh();

        return true;
    }

    return false;
}
예제 #23
0
void EDA_DRAW_FRAME::OnSelectZoom( wxCommandEvent& event )
{
    if( m_zoomSelectBox == NULL )
        return;                        // Should not happen!

    int id = m_zoomSelectBox->GetCurrentSelection();

    if( id < 0 || !( id < (int)m_zoomSelectBox->GetCount() ) )
        return;

    if( id == 0 )                      // Auto zoom (Fit in Page)
    {
        Zoom_Automatique( true );
    }
    else
    {
        id--;
        double selectedZoom = GetScreen()->m_ZoomList[id];

        if( GetScreen()->GetZoom() == selectedZoom )
            return;

        GetScreen()->SetZoom( selectedZoom );

        if( IsGalCanvasActive() )
        {
            // Apply computed view settings to GAL
            KIGFX::VIEW* view = GetGalCanvas()->GetView();
            KIGFX::GAL* gal = GetGalCanvas()->GetGAL();

            double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
            double zoom = 1.0 / ( zoomFactor * GetZoom() );

            view->SetScale( zoom );
            GetGalCanvas()->Refresh();
        }
        else
            RedrawScreen( GetScrollCenterPosition(), false );
    }
}
예제 #24
0
void EDA_DRAW_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
{
    // Keep default cursor in toolbars
    SetCursor( wxNullCursor );

    // Change m_canvas cursor if requested.
    if( m_canvas && aCursor >= 0 )
        m_canvas->SetCurrentCursor( aCursor );

    // Change GAL canvas cursor if requested.
    if( IsGalCanvasActive() && aCursor >= 0 )
        GetGalCanvas()->SetCurrentCursor( aCursor );

    DisplayToolMsg( aToolMsg );

    if( aId < 0 )
        return;

    wxCHECK2_MSG( aId >= ID_NO_TOOL_SELECTED, aId = ID_NO_TOOL_SELECTED,
                  wxString::Format( wxT( "Current tool ID cannot be set to %d." ), aId ) );

    m_toolId = aId;
}
예제 #25
0
const wxString EDA_DRAW_FRAME::GetZoomLevelIndicator() const
{
    wxString Line;
    double level = 0.0;

    if( IsGalCanvasActive() )
    {
        KIGFX::GAL* gal = m_galCanvas->GetGAL();
        KIGFX::VIEW* view = m_galCanvas->GetView();
        double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
        level = m_zoomLevelCoeff * zoomFactor * view->GetScale();
    }
    else if( BASE_SCREEN* screen = GetScreen() )
    {
        level = m_zoomLevelCoeff / (double) screen->GetZoom();
    }

    // returns a human readable value which can be displayed as zoom
    // level indicator in dialogs.
    Line.Printf( wxT( "Z %.2f" ), level );

    return Line;
}
예제 #26
0
void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
{
    PCB_BASE_FRAME::SetBoard( aBoard );

    if( IsGalCanvasActive() )
    {
        PCB_DRAW_PANEL_GAL* drawPanel = static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() );

        drawPanel->DisplayBoard( aBoard );
        aBoard->GetRatsnest()->Recalculate();

        // Prepare worksheet template
        KIGFX::WORKSHEET_VIEWITEM* worksheet;
        worksheet = new KIGFX::WORKSHEET_VIEWITEM( &aBoard->GetPageSettings(),
                                                   &aBoard->GetTitleBlock() );
        worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );

        BASE_SCREEN* screen = GetScreen();

        if( screen != NULL )
        {
            worksheet->SetSheetNumber( screen->m_ScreenNumber );
            worksheet->SetSheetCount( screen->m_NumberOfScreens );
        }

        // PCB_DRAW_PANEL_GAL takes ownership of the worksheet
        drawPanel->SetWorksheet( worksheet );

        // update the tool manager with the new board and its view.
        if( m_toolManager )
        {
            m_toolManager->SetEnvironment( aBoard, drawPanel->GetView(),
                                           drawPanel->GetViewControls(), this );
            m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
        }
    }
}
예제 #27
0
void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
{
    int         id = event.GetId();
    wxFileName  fn;

    switch( id )
    {
    case ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG:
        m_show_layer_manager_tools = ! m_show_layer_manager_tools;
        m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
        m_auimgr.Update();

        GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
                                m_show_layer_manager_tools ?
                                _("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
        break;

    case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR:
        m_show_microwave_tools  = ! m_show_microwave_tools;
        m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
        m_auimgr.Update();

        GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
                                m_show_microwave_tools ?
                                _( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" ));
        break;


    case ID_PCB_LAYERS_SETUP:
        if( InvokeLayerSetup( this, GetBoard() ) )
        {
            LAYER_ID cur_layer = GetActiveLayer();

            // If after showing the dialog the user has removed the active layer,
            // then select a new active layer (front copper layer).
            if( !GetBoard()->GetEnabledLayers()[ cur_layer ] )
                cur_layer = F_Cu;

            SetActiveLayer( cur_layer );

            OnModify();
            ReCreateLayerBox();
            ReFillLayerWidget();

            if( IsGalCanvasActive() )
                static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() );
        }
        break;

    case ID_PCB_LIB_WIZARD:
    case ID_PCB_LIB_TABLE_EDIT:
        {
            bool tableChanged = false;
            int r = 0;

            if( id == ID_PCB_LIB_TABLE_EDIT )
                r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
            else
                r = InvokeFootprintWizard( this, &GFootprintTable, Prj().PcbFootprintLibs() );

            if( r & 1 )
            {
                try
                {
                    FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );

                    GFootprintTable.Format( &sf, 0 );
                    tableChanged = true;
                }
                catch( const IO_ERROR& ioe )
                {
                    wxString msg = wxString::Format( _(
                        "Error occurred saving the global footprint library "
                        "table:\n\n%s" ),
                        GetChars( ioe.errorText.GetData() )
                        );
                    wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
                }
            }

            // If no board file is defined, do not save the project specific library table.  It
            // is kept in memory and created in the path when the new board is saved.
            if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() )
            {
                wxString    tblName   = Prj().FootprintLibTblName();

                try
                {
                    Prj().PcbFootprintLibs()->Save( tblName );
                    tableChanged = true;
                }
                catch( const IO_ERROR& ioe )
                {
                    wxString msg = wxString::Format( _(
                        "Error occurred saving project specific footprint library "
                        "table:\n\n%s" ),
                        GetChars( ioe.errorText )
                        );
                    wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
                }
            }

            FOOTPRINT_VIEWER_FRAME* viewer;

            if( tableChanged && (viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false )) != NULL )
            {
                viewer->ReCreateLibraryList();
            }
        }
        break;

    case ID_PCB_3DSHAPELIB_WIZARD:
#ifdef BUILD_GITHUB_PLUGIN
        Invoke3DShapeLibsDownloaderWizard( this );
#endif
        break;

    case ID_PCB_MASK_CLEARANCE:
        {
            DIALOG_PADS_MASK_CLEARANCE dlg( this );

            if( dlg.ShowModal() == 1 && IsGalCanvasActive() )
            {
                for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
                    module->ViewUpdate();

                GetGalCanvas()->Refresh();
            }
        }
        break;

    case wxID_PREFERENCES:
        {
            DIALOG_GENERALOPTIONS dlg( this );
            dlg.ShowModal();
        }
        break;

    case ID_PCB_PAD_SETUP:
        InstallPadOptionsFrame( NULL );
        break;

    case ID_CONFIG_SAVE:
        SaveProjectSettings( true );
        break;

    case ID_CONFIG_READ:
        {
            fn = GetBoard()->GetFileName();
            fn.SetExt( ProjectFileExtension );

            wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(),
                              fn.GetFullName(), ProjectFileWildcard,
                              wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );

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

            if( !wxFileExists( dlg.GetPath() ) )
            {
                wxString msg = wxString::Format( _(
                        "File %s not found" ),
                        GetChars( dlg.GetPath() )
                        );
                DisplayError( this, msg );
                break;
            }

            wxString pro_file = dlg.GetPath();

            Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_file );
        }
        break;

    // Hotkey IDs
    case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
        ExportHotkeyConfigToFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
        break;

    case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
        ImportHotkeyConfigFromFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
        break;

    case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
        InstallHotkeyFrame( this, g_Board_Editor_Hokeys_Descr );
        break;

    case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
        // Display current hotkey list for Pcbnew.
        DisplayHotkeyList( this, g_Board_Editor_Hokeys_Descr );
        break;

    default:
        DisplayError( this, wxT( "PCB_EDIT_FRAME::Process_Config error" ) );
    }
}
예제 #28
0
void EDA_DRAW_FRAME::OnSelectGrid( wxCommandEvent& event )
{
    int* clientData;
    int  eventId = ID_POPUP_GRID_LEVEL_100;

    if( event.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED )
    {
        if( m_gridSelectBox == NULL )
            return;

        /*
         * Don't use wxCommandEvent::GetClientData() here.  It always
         * returns NULL in GTK.  This solution is not as elegant but
         * it works.
         */
        int index = m_gridSelectBox->GetSelection();
        wxASSERT( index != wxNOT_FOUND );
        clientData = (int*) m_gridSelectBox->wxItemContainer::GetClientData( index );

        if( clientData != NULL )
            eventId = *clientData;
    }
    else
    {
        eventId = event.GetId();

        /* Update the grid select combobox if the grid size was changed
         * by menu event.
         */
        if( m_gridSelectBox != NULL )
        {
            for( size_t i = 0; i < m_gridSelectBox->GetCount(); i++ )
            {
                clientData = (int*) m_gridSelectBox->wxItemContainer::GetClientData( i );

                if( clientData && eventId == *clientData )
                {
                    m_gridSelectBox->SetSelection( i );
                    break;
                }
            }
        }
    }

    // Be sure m_LastGridSizeId is up to date.
    m_LastGridSizeId = eventId - ID_POPUP_GRID_LEVEL_1000;

    BASE_SCREEN* screen = GetScreen();

    if( screen->GetGridId() == eventId )
        return;

    /*
     * This allows for saving non-sequential command ID offsets used that
     * may be used in the grid size combobox.  Do not use the selection
     * index returned by GetSelection().
     */
    screen->SetGrid( eventId );
    SetCrossHairPosition( RefPos( true ) );

    if( IsGalCanvasActive() )
    {
        GetGalCanvas()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGrid().m_Size.x,
                                                         screen->GetGrid().m_Size.y ) );
        GetGalCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
    }

    m_canvas->Refresh();
}
void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand,
                                             bool aRebuildRatsnet )
{
    BOARD_ITEM* item;
    bool        not_found = false;
    bool        reBuild_ratsnest = false;
    KIGFX::VIEW* view = GetGalCanvas()->GetView();
    RN_DATA* ratsnest = GetBoard()->GetRatsnest();

    // Undo in the reverse order of list creation: (this can allow stacked changes
    // like the same item can be changes and deleted in the same complex command

    bool build_item_list = true;    // if true the list of existing items must be rebuilt

    for( int ii = aList->GetCount() - 1; ii >= 0 ; ii-- )
    {
        item = (BOARD_ITEM*) aList->GetPickedItem( ii );
        wxASSERT( item );

        /* Test for existence of item on board.
         * It could be deleted, and no more on board:
         *   - if a call to SaveCopyInUndoList was forgotten in Pcbnew
         *   - in zones outlines, when a change in one zone merges this zone with an other
         * This test avoids a Pcbnew crash
         * Obviously, this test is not made for deleted items
         */
        UNDO_REDO_T status = aList->GetPickedItemStatus( ii );

        if( status != UR_DELETED )
        {
            if( build_item_list )
                // Build list of existing items, for integrity test
                TestForExistingItem( GetBoard(), NULL );

            build_item_list = false;

            if( !TestForExistingItem( GetBoard(), item ) )
            {
                // Remove this non existent item
                aList->RemovePicker( ii );
                ii++;       // the current item was removed, ii points now the next item
                            // decrement it because it will be incremented later
                not_found = true;
                continue;
            }
        }

        item->ClearFlags();

        // see if we must rebuild ratsnets and pointers lists
        switch( item->Type() )
        {
        case PCB_MODULE_T:
        case PCB_ZONE_AREA_T:
        case PCB_TRACE_T:
        case PCB_VIA_T:
            reBuild_ratsnest = true;
            break;

        default:
            break;
        }

        switch( aList->GetPickedItemStatus( ii ) )
        {
        case UR_CHANGED:    /* Exchange old and new data for each item */
        {
            BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );

            // Remove all pads/drawings/texts, as they become invalid
            // for the VIEW after SwapData() called for modules
            if( item->Type() == PCB_MODULE_T )
            {
                MODULE* oldModule = static_cast<MODULE*>( item );
                oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
            }
            ratsnest->Remove( item );

            item->SwapData( image );

            // Update all pads/drawings/texts, as they become invalid
            // for the VIEW after SwapData() called for modules
            if( item->Type() == PCB_MODULE_T )
            {
                MODULE* newModule = static_cast<MODULE*>( item );
                newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
            }
            ratsnest->Add( item );

            item->ClearFlags( SELECTED );
            item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
        }
        break;

        case UR_NEW:        /* new items are deleted */
            aList->SetPickedItemStatus( UR_DELETED, ii );
            GetBoard()->Remove( item );

            if( item->Type() == PCB_MODULE_T )
            {
                MODULE* module = static_cast<MODULE*>( item );
                module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
            }
            view->Remove( item );

            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            break;

        case UR_DELETED:    /* deleted items are put in List, as new items */
            aList->SetPickedItemStatus( UR_NEW, ii );
            GetBoard()->Add( item );

            if( item->Type() == PCB_MODULE_T )
            {
                MODULE* module = static_cast<MODULE*>( item );
                module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1) );
            }
            view->Add( item );

            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            build_item_list = true;
            break;

        case UR_MOVED:
            item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            ratsnest->Update( item );
            break;

        case UR_ROTATED:
            item->Rotate( aList->m_TransformPoint,
                          aRedoCommand ? m_rotationAngle : -m_rotationAngle );
            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            ratsnest->Update( item );
            break;

        case UR_ROTATED_CLOCKWISE:
            item->Rotate( aList->m_TransformPoint,
                          aRedoCommand ? -m_rotationAngle : m_rotationAngle );
            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            ratsnest->Update( item );
            break;

        case UR_FLIPPED:
            item->Flip( aList->m_TransformPoint );
            item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
            ratsnest->Update( item );
            break;

        default:
        {
            wxString msg;
            msg.Printf( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
                        aList->GetPickedItemStatus( ii ) );
            wxMessageBox( msg );
        }
        break;
        }
    }

    if( not_found )
        wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );

    // Rebuild pointers and ratsnest that can be changed.
    if( reBuild_ratsnest && aRebuildRatsnet )
    {
        if( IsGalCanvasActive() )
            ratsnest->Recalculate();
        else
            Compile_Ratsnest( NULL, true );
    }
}
예제 #30
0
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
                                     const wxString& aCmpFileName,
                                     REPORTER*       aReporter,
                                     bool            aChangeFootprints,
                                     bool            aDeleteUnconnectedTracks,
                                     bool            aDeleteExtraFootprints,
                                     bool            aSelectByTimeStamp,
                                     bool            aDeleteSinglePadNets,
                                     bool            aIsDryRun )
{
    wxString        msg;
    NETLIST         netlist;
    KIGFX::VIEW*    view = GetGalCanvas()->GetView();
    BOARD*          board = GetBoard();

    netlist.SetIsDryRun( aIsDryRun );
    netlist.SetFindByTimeStamp( aSelectByTimeStamp );
    netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints );
    netlist.SetReplaceFootprints( aChangeFootprints );

    try
    {
        std::auto_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
            &netlist, aNetlistFileName, aCmpFileName ) );

        if( !netlistReader.get() )
        {
            msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFileName ) );
            wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR, this );
            return;
        }

        SetLastNetListRead( aNetlistFileName );
        netlistReader->LoadNetlist();
        loadFootprints( netlist, aReporter );
    }
    catch( const IO_ERROR& ioe )
    {
        msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
        wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
        return;
    }

    // Clear undo and redo lists to avoid inconsistencies between lists
    if( !netlist.IsDryRun() )
        GetScreen()->ClearUndoRedoList();

    if( !netlist.IsDryRun() )
    {
        // Remove old modules
        for( MODULE* module = board->m_Modules; module; module = module->Next() )
        {
            module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
            view->Remove( module );
        }
    }

    // Clear selection, just in case a selected item has to be removed
    m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );

    netlist.SortByReference();
    board->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter );

    // If it was a dry run, nothing has changed so we're done.
    if( netlist.IsDryRun() )
        return;

    OnModify();

    SetCurItem( NULL );

    // Reload modules
    for( MODULE* module = board->m_Modules; module; module = module->Next() )
    {
        module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
        view->Add( module );
        module->ViewUpdate();
    }

    if( aDeleteUnconnectedTracks && board->m_Track )
    {
        // Remove erroneous tracks.  This should probably pushed down to the #BOARD object.
        RemoveMisConnectedTracks();
    }

    // Rebuild the board connectivity:
    if( IsGalCanvasActive() )
        board->GetRatsnest()->ProcessBoard();

    Compile_Ratsnest( NULL, true );

    SetMsgPanel( board );
    m_canvas->Refresh();
}