Beispiel #1
0
/*----------------------------------------------------------------------
|    NPT_String::ToInteger
+---------------------------------------------------------------------*/
NPT_Result 
NPT_String::ToInteger(NPT_UInt64& value, bool relaxed) const
{
    return NPT_ParseInteger64U(GetChars(), value, relaxed);
}
Beispiel #2
0
void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
{
    wxString reportName;

    bool make_report = m_CreateRptCtrl->IsChecked();

    if( make_report )      // Create a rpt file
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent dummy;
            OnButtonBrowseRptFileClick( dummy );
        }

        if( !reportName.IsEmpty() )
            reportName = makeValidFileNameReport();
    }

    SetDrcParmeters();
    m_tester->SetSettings( true,        // Pad to pad DRC test enabled
                           true,        // unconnected pads DRC test enabled
                           true,        // DRC test for zones enabled
                           true,        // DRC test for keepout areas enabled
                           m_cbCourtyardOverlap->GetValue(),
                           m_cbCourtyardMissing->GetValue(),
                           reportName, make_report );

    DelDRCMarkers();

    wxBeginBusyCursor();

    // run all the tests, with no UI at this time.
    m_Messages->Clear();
    wxSafeYield();                          // Allows time slice to refresh the m_Messages window
    m_brdEditor->GetBoard()->m_Status_Pcb = 0; // Force full connectivity and ratsnest recalculations
    m_tester->RunTests(m_Messages);
    m_Notebook->ChangeSelection( 0 );       // display the 1at tab "...Markers ..."


    // Generate the report
    if( !reportName.IsEmpty() )
    {
        if( writeReport( reportName ) )
        {
            wxString        msg;
            msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );

            wxString        caption( _( "Disk File Report Completed" ) );
            wxMessageDialog popupWindow( this, msg, caption );
            popupWindow.ShowModal();
        }
        else
            DisplayError( this, wxString::Format( _( "Unable to create report file \"%s\" "),
                          GetChars( reportName ) ) );
    }

    wxEndBusyCursor();

    RedrawDrawPanel();
}
MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
                                               FP_LIB_TABLE*   aTable,
                                               bool            aUseFootprintViewer,
                                               wxDC*           aDC )
{
    MODULE*     module = NULL;
    wxPoint     curspos = GetCrossHairPosition();
    wxString    moduleName, keys;
    wxString    libName = aLibrary;
    bool        allowWildSeach = true;

    static wxArrayString HistoryList;
    static wxString      lastComponentName;

    // Ask for a component name or key words
    DIALOG_GET_COMPONENT dlg( this, HistoryList, _( "Load Footprint" ), aUseFootprintViewer );

    dlg.SetComponentName( lastComponentName );

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

    if( dlg.m_GetExtraFunction )
    {
        // SelectFootprintFromLibBrowser() returns the "full" footprint name, i.e.
        // <lib_name>/<footprint name> or FPID format "lib_name:fp_name:rev#"
        moduleName = SelectFootprintFromLibBrowser();
    }
    else
    {
        moduleName = dlg.GetComponentName();
    }

    if( moduleName.IsEmpty() )  // Cancel command
    {
        m_canvas->MoveCursorToCrossHair();
        return NULL;
    }

    if( dlg.IsKeyword() )       // Selection by keywords
    {
        allowWildSeach = false;
        keys = moduleName;
        moduleName = SelectFootprint( this, libName, wxEmptyString, keys, aTable );

        if( moduleName.IsEmpty() )  // Cancel command
        {
            m_canvas->MoveCursorToCrossHair();
            return NULL;
        }
    }
    else if( moduleName.Contains( wxT( "?" ) )
           || moduleName.Contains( wxT( "*" ) ) )  // Selection wild card
    {
        allowWildSeach = false;
        moduleName     = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );

        if( moduleName.IsEmpty() )
        {
            m_canvas->MoveCursorToCrossHair();
            return NULL;                           // Cancel command.
        }
    }

    FPID fpid;

    wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
                 wxString::Format( wxT( "Could not parse FPID string '%s'." ),
                                   GetChars( moduleName ) ) );

    try
    {
        module = loadFootprint( fpid );
    }
    catch( const IO_ERROR& ioe )
    {
        wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
                    fpid.Format().c_str(), GetChars( ioe.errorText ) );
    }

    if( !module && allowWildSeach )                // Search with wild card
    {
        allowWildSeach = false;

        wxString wildname = wxChar( '*' ) + moduleName + wxChar( '*' );
        moduleName = wildname;

        moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );

        if( moduleName.IsEmpty() )
        {
            m_canvas->MoveCursorToCrossHair();
            return NULL;    // Cancel command.
        }
        else
        {
            FPID fpid;

            wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
                         wxString::Format( wxT( "Could not parse FPID string '%s'." ),
                                           GetChars( moduleName ) ) );

            try
            {
                module = loadFootprint( fpid );
            }
            catch( const IO_ERROR& ioe )
            {
                wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
                            fpid.Format().c_str(), GetChars( ioe.errorText ) );
            }
        }
    }

    SetCrossHairPosition( curspos );
    m_canvas->MoveCursorToCrossHair();

    if( module )
    {
        GetBoard()->Add( module, ADD_APPEND );

        lastComponentName = moduleName;
        AddHistoryComponentName( HistoryList, moduleName );

        module->SetFlags( IS_NEW );
        module->SetLink( 0 );

        if( IsGalCanvasActive() )
            module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
        else
            module->SetPosition( curspos );

        module->SetTimeStamp( GetNewTimeStamp() );
        GetBoard()->m_Status_Pcb = 0;

        // Put it on FRONT layer,
        // (Can be stored flipped if the lib is an archive built from a board)
        if( module->IsFlipped() )
            module->Flip( module->GetPosition() );

        // Place it in orientation 0,
        // even if it is not saved with orientation 0 in lib
        // (Can happen if the lib is an archive built from a board)
        Rotate_Module( NULL, module, 0, false );

        RecalculateAllTracksNetcode();

        if( aDC )
            module->Draw( m_canvas, aDC, GR_OR );
    }

    return module;
}
/**
 * Function Append_Track_Width_List
 * creates a wxMenu * which shows the last used track widths and via diameters
 * @return a pointer to the menu
 */
static wxMenu* Append_Track_Width_List( BOARD* aBoard )
{
    wxString msg;
    wxMenu*  trackwidth_menu;
    wxString value;

    trackwidth_menu = new wxMenu;

    trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Auto Width" ),
                             _( "Use the track width when starting on a track, otherwise the current track width" ),
                             true );

    if( aBoard->GetDesignSettings().m_UseConnectedTrackWidth )
        trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, true );

    if(  aBoard->GetViaSizeIndex() != 0
      || aBoard->GetTrackWidthIndex() != 0
      || aBoard->GetDesignSettings().m_UseConnectedTrackWidth )
        trackwidth_menu->Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
                                 _( "Use Netclass Values" ),
                                 _( "Use track and via sizes from their Netclass values" ),
                                 true );

    for( unsigned ii = 0; ii < aBoard->m_TrackWidthList.size(); ii++ )
    {
        value = ReturnStringFromValue( g_UserUnit, aBoard->m_TrackWidthList[ii], true );
        msg.Printf( _( "Track %s" ), GetChars( value ) );

        if( ii == 0 )
            msg << _( " uses NetClass" );

        trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true );
    }

    trackwidth_menu->AppendSeparator();

    for( unsigned ii = 0; ii < aBoard->m_ViasDimensionsList.size(); ii++ )
    {
        value = ReturnStringFromValue( g_UserUnit, aBoard->m_ViasDimensionsList[ii].m_Diameter,
                                       true );
        wxString drill = ReturnStringFromValue( g_UserUnit,
                                                aBoard->m_ViasDimensionsList[ii].m_Drill,
                                                true );

        if( aBoard->m_ViasDimensionsList[ii].m_Drill <= 0 )
        {
            msg.Printf( _( "Via %s" ), GetChars( value ) );
        }
        else
        {
            msg.Printf( _( "Via %s, drill %s" ), GetChars( value ), GetChars( drill ) );
        }

        if( ii == 0 )
            msg << _( " uses NetClass" );

        trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true );
    }

    return trackwidth_menu;
}
Beispiel #5
0
int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
{
    wxFileName fn;

    if( !aFullFileName.IsEmpty() )
    {
        fn = m_NetlistFileName;
        fn.SetExt( ComponentFileExtension );
    }
    else
    {
        wxFileDialog dlg( this, _( "Save Component Footprint Link File" ), wxEmptyString,
                          _( "Unnamed file" ), ComponentFileWildcard, wxFD_SAVE );

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

        fn = dlg.GetPath();

        if( !fn.HasExt() )
            fn.SetExt( ComponentFileExtension );

        // Save the project specific footprint library table.
        if( !m_footprintLibTable->IsEmpty( false ) )
        {
            wxFileName fpLibFileName = fn;
            fpLibFileName.ClearExt();
            fpLibFileName.SetName( FP_LIB_TABLE::GetFileName() );

            if( fpLibFileName.FileExists()
              && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo "
                                "you want to overwrite it?" ) ) )
            {
                try
                {
                    m_footprintLibTable->Save( fpLibFileName );
                }
                catch( IO_ERROR& ioe )
                {
                    DisplayError( this,
                                  wxString::Format( _( "An error occurred attempting to save the "
                                                       "footprint library table <%s>\n\n%s" ),
                                                    GetChars( fpLibFileName.GetFullPath() ),
                                                    GetChars( ioe.errorText ) ) );
                }
            }
        }
    }

    if( !IsWritable( fn.GetFullPath() ) )
        return 0;

    if( WriteComponentLinkFile( fn.GetFullPath() ) == 0 )
    {
        DisplayError( this, _( "Unable to create component footprint link file (.cmp)" ) );
        return 0;
    }

    wxString msg;
    msg.Printf( _("File %s saved"), GetChars( fn.GetFullPath() ) );
    SetStatusText( msg );
    return 1;
}
Beispiel #6
0
/**
 * Function ClipAreaPolygon
 * Process an area that has been modified, by clipping its polygon against itself.
 * This may change the number and order of copper areas in the net.
 * @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in
 *                        undo commands) can be NULL
 * @param aCurrArea = the zone to process
 * @param bMessageBoxInt == true, shows message when clipping occurs.
 * @param  bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
 * @param bRetainArcs = true to handle arcs (not really used in KiCad)
 * @return:
 *  -1 if arcs intersect other sides, so polygon can't be clipped
 *   0 if no intersecting sides
 *   1 if intersecting sides
 * Also sets areas->utility1 flags if areas are modified
 */
int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
                            ZONE_CONTAINER* aCurrArea,
                            bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
{
    CPolyLine* curr_polygon = aCurrArea->m_Poly;
    int        test = TestAreaPolygon( aCurrArea ); // this sets utility2 flag

    if( test == -1 && !bRetainArcs )
        test = 1;

    if( test == -1 )
    {
        // arc intersections, don't clip unless bRetainArcs == false
        if( bMessageBoxArc && bDontShowSelfIntersectionArcsWarning == false )
        {
            wxString str;
            str.Printf( wxT( "Area %08lX of net \"%s\" has arcs intersecting other sides.\n" ),
                        aCurrArea->GetTimeStamp(), GetChars( aCurrArea->m_Netname ) );
            str += wxT( "This may cause problems with other editing operations,\n" );
            str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" );
            str += wxT( "Manual correction is recommended." );
            wxMessageBox( str );
        }

        return -1;  // arcs intersect with other sides, error
    }

    // mark all areas as unmodified except this one
    for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
        m_ZoneDescriptorList[ia]->utility = 0;

    aCurrArea->utility = 1;

    if( test == 1 )
    {
        // non-arc intersections, clip the polygon
        if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false )
        {
            wxString str;
            str.Printf( wxT( "Area %08lX of net \"%s\" is self-intersecting and will be clipped.\n" ),
                        aCurrArea->GetTimeStamp(), GetChars( aCurrArea->m_Netname ) );
            str += wxT( "This may result in splitting the area.\n" );
            str += wxT( "If the area is complex, this may take a few seconds." );
            wxMessageBox( str );

//          bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
        }
    }

//** TODO test for cutouts outside of area
//**    if( test == 1 )
    {
        std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
        curr_polygon->UnHatch();
        int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );

        // i.e if clipping has created some polygons, we must add these new copper areas.
        if( n_poly > 1 )
        {
            ZONE_CONTAINER* NewArea;

            for( int ip = 1; ip < n_poly; ip++ )
            {
                // create new copper area and copy poly into it
                CPolyLine* new_p = (*pa)[ip - 1];
                NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(),
                                   wxPoint(0, 0), CPolyLine::NO_HATCH );

                // remove the poly that was automatically created for the new area
                // and replace it with a poly from NormalizeAreaOutlines
                delete NewArea->m_Poly;
                NewArea->m_Poly = new_p;
                NewArea->m_Poly->Hatch();
                NewArea->utility = 1;
            }
        }

        curr_polygon->Hatch();
        delete pa;
    }

    return test;
}
void PCB_EDIT_FRAME::ReadMacros()
{
    wxString str;
    wxFileName fn;

    fn = GetBoard()->GetFileName();
    fn.SetExt( MacrosFileExtension );

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

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

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

    wxXmlDocument xml;

    xml.SetFileEncoding( wxT( "UTF-8" ) );

    if( !xml.Load( dlg.GetFilename() ) )
        return;

    XNODE *macrosNode = (XNODE*) xml.GetRoot()->GetChildren();

    while( macrosNode )
    {
        int number = -1;

        if( macrosNode->GetName() == wxT( "macros" ) )
        {
            number = wxAtoi( macrosNode->GetAttribute( wxT( "number" ), wxT( "-1" ) ) );

            if( number >= 0  && number < 10 )
            {
                m_Macros[number].m_Record.clear();

                XNODE *hotkeyNode = (XNODE*) macrosNode->GetChildren();

                while( hotkeyNode )
                {
                    if( hotkeyNode->GetName() == wxT( "hotkey" ) )
                    {
                        int x = wxAtoi( hotkeyNode->GetAttribute( wxT( "x" ), wxT( "0" ) ) );
                        int y = wxAtoi( hotkeyNode->GetAttribute( wxT( "y" ), wxT( "0" ) ) );
                        int hk = wxAtoi( hotkeyNode->GetAttribute( wxT( "hkcode" ), wxT( "0" ) ) );

                        MACROS_RECORD macros_record;
                        macros_record.m_HotkeyCode = hk;
                        macros_record.m_Position.x = x;
                        macros_record.m_Position.y = y;
                        m_Macros[number].m_Record.push_back( macros_record );
                    }

                    hotkeyNode = (XNODE*) hotkeyNode->GetNext();
                }
            }
        }

        macrosNode = (XNODE*) macrosNode->GetNext();
    }
}
Beispiel #8
0
PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
                                const wxPoint& pos, const wxSize& size,
                                long style ) :
    PCB_BASE_FRAME( parent, PCB_FRAME_TYPE, title, pos, size,
                    style, PCB_EDIT_FRAME_NAME )
{
    m_FrameName = PCB_EDIT_FRAME_NAME;
    m_showBorderAndTitleBlock = true;   // true to display sheet references
    m_showAxis = false;                 // true to display X and Y axis
    m_showOriginAxis = true;
    m_showGridAxis = true;
    m_SelTrackWidthBox = NULL;
    m_SelViaSizeBox = NULL;
    m_SelLayerBox = NULL;
    m_show_microwave_tools = false;
    m_show_layer_manager_tools = true;
    m_HotkeysZoomAndGridList = g_Board_Editor_Hokeys_Descr;
    m_hasAutoSave = true;
    m_RecordingMacros = -1;
    m_microWaveToolBar = NULL;
    m_useCmpFileForFpNames = true;

    m_footprintLibTable = NULL;
    m_globalFootprintTable = NULL;
    m_rotationAngle = 900;

#ifdef KICAD_SCRIPTING_WXPYTHON
    m_pythonPanel = NULL;
#endif

    for ( int i = 0; i < 10; i++ )
        m_Macros[i].m_Record.clear();

    SetBoard( new BOARD() );

    if( GetGalCanvas() )
    {
        ViewReloadBoard( m_Pcb );

        // update the tool manager with the new board and its view.
        if( m_toolManager )
            m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
                                           GetGalCanvas()->GetViewControls(), this );
    }

    // Create the PCB_LAYER_WIDGET *after* SetBoard():

    wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
    int pointSize = font.GetPointSize();
    int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );

    // printf( "pointSize:%d  80%%:%d\n", pointSize, (pointSize*8)/10 );

    if( screenHeight <= 900 )
        pointSize = (pointSize * 8) / 10;

    m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas(), pointSize );

    m_drc = new DRC( this );        // these 2 objects point to each other

    wxIcon  icon;
    icon.CopyFromBitmap( KiBitmap( icon_pcbnew_xpm ) );
    SetIcon( icon );

    SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );

    // PCB drawings start in the upper left corner.
    GetScreen()->m_Center = false;

    // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
    // initialize parameters in m_LayersManager
    LoadSettings();

    // Be sure options are updated
    m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
    m_DisplayPadFill = DisplayOpt.DisplayPadFill;
    m_DisplayViaFill = DisplayOpt.DisplayViaFill;
    m_DisplayPadNum  = DisplayOpt.DisplayPadNum;

    m_DisplayModEdge = DisplayOpt.DisplayModEdge;
    m_DisplayModText = DisplayOpt.DisplayModText;

    SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );

    GetScreen()->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId  );

    if( m_canvas )
        m_canvas->SetEnableBlockCommands( true );

    ReCreateMenuBar();
    ReCreateHToolbar();
    ReCreateAuxiliaryToolbar();
    ReCreateVToolbar();
    ReCreateOptToolbar();

    ReCreateMicrowaveVToolbar();

    m_auimgr.SetManagedWindow( this );

    EDA_PANEINFO horiz;
    horiz.HorizontalToolbarPane();

    EDA_PANEINFO vert;
    vert.VerticalToolbarPane();

    EDA_PANEINFO mesg;
    mesg.MessageToolbarPane();

    // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template.
    // LAYER_WIDGET is floatable, but initially docked at far right
    EDA_PANEINFO   lyrs;
    lyrs.LayersToolbarPane();
    lyrs.MinSize( m_Layers->GetBestSize() );    // updated in ReFillLayerWidget
    lyrs.BestSize( m_Layers->GetBestSize() );
    lyrs.Caption( _( "Visibles" ) );


    if( m_mainToolBar )    // The main horizontal toolbar
    {
        m_auimgr.AddPane( m_mainToolBar,
                          wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
    }

    if( m_auxiliaryToolBar )    // the auxiliary horizontal toolbar, that shows track and via sizes, zoom ...)
    {
        m_auimgr.AddPane( m_auxiliaryToolBar,
                          wxAuiPaneInfo( horiz ).Name( wxT( "m_auxiliaryToolBar" ) ).Top().Row( 1 ) );
    }

    if( m_microWaveToolBar )    // The auxiliary vertical right toolbar (currently microwave tools)
        m_auimgr.AddPane( m_microWaveToolBar,
                          wxAuiPaneInfo( vert ).Name( wxT( "m_microWaveToolBar" ) ).Right().Layer( 1 ).Position(1).Hide() );

    if( m_drawToolBar )    // The main right vertical toolbar
        m_auimgr.AddPane( m_drawToolBar,
                          wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Layer( 2 ) );

    // Add the layer manager ( most right side of pcbframe )
    m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 3 ) );

    if( m_optionsToolBar )    // The left vertical toolbar (fast acces display options of Pcbnew)
    {
        m_auimgr.AddPane( m_optionsToolBar,
                          wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left().Layer(1) );

        m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
        m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
    }

    if( m_canvas )
        m_auimgr.AddPane( m_canvas,
                          wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );

    if( GetGalCanvas() )
        m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
                          wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );

    if( m_messagePanel )
        m_auimgr.AddPane( m_messagePanel,
                          wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );


#ifdef KICAD_SCRIPTING_WXPYTHON
    // Add the scripting panel
    EDA_PANEINFO  pythonAuiInfo;
    pythonAuiInfo.ScriptingToolbarPane();
    pythonAuiInfo.Caption( wxT( "Python Scripting" ) );
    pythonAuiInfo.MinSize( wxSize( 200, 100 ) );
    pythonAuiInfo.BestSize( wxSize( GetClientSize().x/2, 200 ) );
    pythonAuiInfo.Hide();

    m_pythonPanel = CreatePythonShellWindow( this );
    m_auimgr.AddPane( m_pythonPanel,
                      pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) );

    m_pythonPanelHidden = true;
#endif

    ReFillLayerWidget();        // this is near end because contents establish size

    m_Layers->ReFillRender();   // Update colors in Render after the config is read

    syncLayerWidgetLayer();

    m_auimgr.Update();

    if( m_globalFootprintTable == NULL )
    {
        try
        {
            m_globalFootprintTable = new FP_LIB_TABLE();

            if( !FP_LIB_TABLE::LoadGlobalTable( *m_globalFootprintTable ) )
            {
                DisplayInfoMessage( this, wxT( "You have run Pcbnew for the first time using the "
                                               "new footprint library table method for finding "
                                               "footprints.  Pcbnew has either copied the default "
                                               "table or created an empty table in your home "
                                               "folder.  You must first configure the library "
                                               "table to include all footprint libraries not "
                                               "included with KiCad.  See the \"Footprint Library "
                                               "Table\" section of the CvPcb documentation for "
                                               "more information." ) );
            }
        }
        catch( IO_ERROR ioe )
        {
            wxString msg;
            msg.Printf( _( "An error occurred attempting to load the global footprint library "
                           "table:\n\n%s" ), GetChars( ioe.errorText ) );
            DisplayError( this, msg );
        }
    }

    setupTools();
}
/* Add some X2 attributes to the file header, as defined in the
 * Gerber file format specification J4 and "Revision 2015.06"
 */
void AddGerberX2Attribute( PLOTTER * aPlotter,
            const BOARD *aBoard, LAYER_NUM aLayer )
{
    wxString text;

    // Creates the TF,.GenerationSoftware. Format is:
    // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
    text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
    aPlotter->AddLineToHeader( text );

    // creates the TF.CreationDate ext:
    // The attribute value must conform to the full version of the ISO 8601
    // date and time format, including time and time zone. Note that this is
    // the date the Gerber file was effectively created,
    // not the time the project of PCB was started
    wxDateTime date( wxDateTime::GetTimeNow() );
    // Date format: see http://www.cplusplus.com/reference/ctime/strftime
    wxString msg = date.Format( wxT( "%z" ) );  // Extract the time zone offset
    // The time zone offset format is + (or -) mm or hhmm  (mm = number of minutes, hh = number of hours)
    // we want +(or -) hh:mm
    if( msg.Len() > 3 )
        msg.insert( 3, ":", 1 ),
    text.Printf( wxT( "%%TF.CreationDate,%s%s*%%" ), GetChars( date.FormatISOCombined() ), GetChars( msg ) );
    aPlotter->AddLineToHeader( text );

    // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
    // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
    // <project id> is the name of the project, restricted to basic ASCII symbols only,
    // and comma not accepted
    // All illegal chars will be replaced by underscore
    // <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
    // This is a random 128-bit number expressed in 32 hexadecimal digits.
    // See en.wikipedia.org/wiki/GUID for more information
    // However Kicad does not handle such a project GUID, so it is built from the board name
    // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
    wxFileName fn = aBoard->GetFileName();
    msg = fn.GetFullName();
    wxString guid;

    // Build a 32 digits GUID from the board name:
    for( unsigned ii = 0; ii < msg.Len(); ii++ )
    {
        int cc1 = int( msg[ii] ) & 0x0F;
        int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
        guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );

        if( guid.Len() >= 32 )
            break;
    }

    // guid has 32 digits, so add missing digits
    int cnt = 32 - guid.Len();

    if( cnt > 0 )
        guid.Append( '0', cnt );

    // build the <project id> string: this is the board short filename (without ext)
    // and all non ASCII chars and comma are replaced by '_'
    msg = fn.GetName();
    msg.Replace( wxT( "," ), wxT( "_" ) );

    // build the <rec> string. All non ASCII chars and comma are replaced by '_'
    wxString rev = ((BOARD*)aBoard)->GetTitleBlock().GetRevision();
    rev.Replace( wxT( "," ), wxT( "_" ) );

    if( rev.IsEmpty() )
        rev = wxT( "rev?" );

    text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
    aPlotter->AddLineToHeader( text );

    // Add the TF.FileFunction
    text = GetGerberFileFunctionAttribute( aBoard, aLayer, false );
    aPlotter->AddLineToHeader( text );

    // Add the TF.FilePolarity (for layers which support that)
    text = GetGerberFilePolarityAttribute( aLayer );

    if( !text.IsEmpty() )
        aPlotter->AddLineToHeader( text );
}
// Generate the drill map of the board
void DIALOG_GENDRILL::GenDrillMap( const wxString aFullFileNameWithoutExt,
                                   EXCELLON_WRITER& aExcellonWriter,
                                   PlotFormat     format )
{
    wxString   ext, wildcard;

    /* Init extension */
    switch( format )
    {
    case PLOT_FORMAT_HPGL:
        ext = HPGL_PLOTTER::GetDefaultFileExtension();
        wildcard = _( "HPGL plot files (.plt)|*.plt" );
        break;

    case PLOT_FORMAT_POST:
        ext = PS_PLOTTER::GetDefaultFileExtension();
        wildcard = PSFileWildcard;
        break;

    case PLOT_FORMAT_GERBER:
        ext = GERBER_PLOTTER::GetDefaultFileExtension();
        wildcard = _( "Gerber files (.pho)|*.pho" );
        break;

    case PLOT_FORMAT_DXF:
        ext = DXF_PLOTTER::GetDefaultFileExtension();
        wildcard = _( "DXF files (.dxf)|*.dxf" );
        break;

    case PLOT_FORMAT_SVG:
        ext = SVG_PLOTTER::GetDefaultFileExtension();
        wildcard = SVGFileWildcard;
        break;

    case PLOT_FORMAT_PDF:
        ext = PDF_PLOTTER::GetDefaultFileExtension();
        wildcard = PdfFileWildcard;
        break;

    default:
        wxLogMessage( wxT( "DIALOG_GENDRILL::GenDrillMap() error, fmt % unkown" ), format );
        return;
    }

    // Add file name extension
    wxString fullFilename = aFullFileNameWithoutExt;
    fullFilename << wxT(".") << ext;

    bool success = aExcellonWriter.GenDrillMapFile( fullFilename,
                                                   m_parent->GetPageSettings(),
                                                   format );

    wxString   msg;

    if( ! success )
    {
        msg.Printf( _( "** Unable to create %s **\n" ),
                    GetChars( fullFilename ) );
        m_messagesBox->AppendText( msg );
        return;
    }
    else
    {
        msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) );
        m_messagesBox->AppendText( msg );
    }

}
Beispiel #11
0
/* Prepare the right-click pullup menu.
 * The menu already has a list of zoom commands.
 */
bool GERBVIEW_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* aPopMenu )
{
    GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) GetScreen()->GetCurItem();
    wxString    msg;
    bool        BlockActive = !GetScreen()->m_BlockLocate.IsIdle();
    bool        busy = currItem && currItem->GetFlags();

    // Do not initiate a start block validation on menu.
    m_canvas->SetCanStartBlock( -1 );

    // Simple location of elements where possible.
    if( !busy )
    {
        currItem = Locate( aPosition, CURSEUR_OFF_GRILLE );
        busy = currItem && currItem->GetFlags();
    }

    // If command in progress, end command.
    if( GetToolId() != ID_NO_TOOL_SELECTED )
    {
        if( busy )
            AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
                         _( "Cancel" ), KiBitmap( cancel_xpm )  );
        else
            AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL,
                         _( "End Tool" ), KiBitmap( cursor_xpm ) );

        aPopMenu->AppendSeparator();
    }
    else
    {
        if( busy || BlockActive )
        {
            if( BlockActive )
            {
                AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
                             _( "Cancel Block" ), KiBitmap( cancel_xpm ) );
                aPopMenu->AppendSeparator();
                AddMenuItem( aPopMenu, ID_POPUP_PLACE_BLOCK,
                             _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
            }
            else
            {
                AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
                             _( "Cancel" ), KiBitmap( cancel_xpm ) );
            }

            aPopMenu->AppendSeparator();
        }
    }

    if( BlockActive )
        return true;

    if( currItem )
    {
        GetScreen()->SetCurItem( currItem );
        bool add_separator = false;

        // Now, display a context menu
        // to allow highlighting items which share the same attributes
        // as the selected item (net attributes and aperture attributes)
        const GBR_NETLIST_METADATA& net_attr = currItem->GetNetAttributes();

        if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) ||
            ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) )
        {
            AddMenuItem( aPopMenu, ID_HIGHLIGHT_CMP_ITEMS,
                         wxString::Format( _( "Highlight items of component \"%s\"" ),
                                            GetChars( net_attr.m_Cmpref ) ),
                         KiBitmap( file_footprint_xpm ) );
            add_separator = true;
        }

        if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) )
        {
            AddMenuItem( aPopMenu, ID_HIGHLIGHT_NET_ITEMS,
                         wxString::Format( _( "Highlight items of net \"%s\"" ),
                                            GetChars( net_attr.m_Netname ) ),
                         KiBitmap( general_ratsnest_xpm ) );
            add_separator = true;
        }

        D_CODE* apertDescr = currItem->GetDcodeDescr();

        if( apertDescr && !apertDescr->m_AperFunction.IsEmpty() )
        {
            AddMenuItem( aPopMenu, ID_HIGHLIGHT_APER_ATTRIBUTE_ITEMS,
                         wxString::Format( _( "Highlight aperture type \"%s\"" ),
                                            GetChars( apertDescr->m_AperFunction ) ),
                         KiBitmap( flag_xpm ) );
            add_separator = true;
        }

        if( add_separator )
            aPopMenu->AppendSeparator();
    }

    AddMenuItem( aPopMenu, ID_HIGHLIGHT_REMOVE_ALL,
                 _( "Clear highlight" ),
                 KiBitmap( gerbview_clear_layers_xpm ) );

    aPopMenu->AppendSeparator();

    return true;
}
/**
 * Function GenDrillAndMapFiles
 * Calls the functions to create EXCELLON drill files and/or drill map files
 * >When all holes are through holes, only one excellon file is created.
 * >When there are some partial holes (some blind or buried vias),
 *  one excellon file is created, for all plated through holes,
 *  and one file per layer pair, which have one or more holes, excluding
 *  through holes, already in the first file.
 *  one file for all Not Plated through holes
 */
void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap)
{
    wxString   layer_extend;              /* added to the  Board FileName to
                                           * create FullFileName (= Board
                                           * FileName + layer pair names) */
    wxString   msg;
    bool       hasBuriedVias = false;  /* If true, drill files are created
                                        * layer pair by layer pair for
                                        * buried vias */
    int        layer1 = LAYER_N_BACK;
    int        layer2 = LAYER_N_FRONT;
    bool       gen_through_holes = true;
    bool       gen_NPTH_holes    = false;

    wxString   currentWD = ::wxGetCwd();

    UpdateConfig(); // set params and Save drill options

    m_parent->ClearMsgPanel();

    if( m_microViasCount || m_blindOrBuriedViasCount )
        hasBuriedVias = true;

    EXCELLON_WRITER excellonWriter( m_parent->GetBoard(),
                                    m_FileDrillOffset );
    excellonWriter.SetFormat( !m_UnitDrillIsInch,
                              (EXCELLON_WRITER::zeros_fmt) m_ZerosFormat,
                              m_Precision.m_lhs, m_Precision.m_rhs );
    excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset );

    wxFileName fn;

    for( ; ; )
    {
        excellonWriter.BuildHolesList( layer1, layer2,
                          gen_through_holes ? false : true, gen_NPTH_holes );

        if( excellonWriter.GetHolesCount() > 0 ) // has holes?
        {
            fn = m_parent->GetBoard()->GetFileName();
            layer_extend.Empty();

            if( gen_NPTH_holes )
            {
                layer_extend << wxT( "-NPTH" );
            }
            else if( !gen_through_holes )
            {
                if( layer1 == LAYER_N_BACK )
                    layer_extend << wxT( "-back" );
                else
                    layer_extend << wxT( "-inner" ) << layer1;
                if( layer2 == LAYER_N_FRONT )
                    layer_extend << wxT( "-front" );
                else
                    layer_extend << wxT( "-inner" ) << layer2;
            }

            fn.SetName( fn.GetName() + layer_extend );
            wxString defaultPath = m_plotOpts.GetOutputDirectory();
            if( defaultPath.IsEmpty() )
                defaultPath = ::wxGetCwd();

            fn.SetPath( defaultPath );

            if( aGenDrill )
            {
                fn.SetExt( DrillFileExtension );
                wxString fullFilename = fn.GetFullPath();

                FILE* file = wxFopen( fullFilename, wxT( "w" ) );

                if( file == 0 )
                {
                    msg.Printf( _( "** Unable to create %s **\n" ),
                                GetChars( fullFilename ) );
                    m_messagesBox->AppendText( msg );
                    break;
                }
                else
                {
                    msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) );
                    m_messagesBox->AppendText( msg );
                }

                excellonWriter.CreateDrillFile( file );
            }

            if( aGenMap )
            {
                const PlotFormat filefmt[6] =
                {   // Keep these format ids in the same order than m_Choice_Drill_Map choices
                    PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
                    PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
                };
                unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();

                if( choice >= m_Choice_Drill_Map->GetCount() )
                    choice = 1;

                fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
                wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );

                GenDrillMap( fullfilename, excellonWriter, filefmt[choice] );
            }
        }

        if( gen_NPTH_holes )    // The last drill file was created
            break;

        if( !hasBuriedVias )
            gen_NPTH_holes = true;
        else
        {
            if(  gen_through_holes )
                layer2 = layer1 + 1;    // prepare generation of first layer pair
            else
            {
                if( layer2 >= LAYER_N_FRONT )    // no more layer pair to consider
                {
                    layer1 = LAYER_N_BACK;
                    layer2 = LAYER_N_FRONT;
                    gen_NPTH_holes = true;
                    continue;
                }
                layer1++;
                layer2++;                      // use next layer pair

                if( layer2 == m_parent->GetBoard()->GetCopperLayerCount() - 1 )
                    layer2 = LAYER_N_FRONT;         // the last layer is always the
                                                    // Front layer
            }

            gen_through_holes = false;
        }
    }

    ::wxSetWorkingDirectory( currentWD );
}
void DIALOG_PLOT::Plot( wxCommandEvent& event )
{
    applyPlotSettings();

    // Create output directory if it does not exist (also transform it in
    // absolute form). Bail if it fails
    wxFileName  outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
    wxString    boardFilename = m_parent->GetBoard()->GetFileName();
    REPORTER&   reporter = m_messagesPanel->Reporter();

    if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
    {
        wxString msg;
        msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
                    GetChars( outputDir.GetPath() ) );
        DisplayError( this, msg );
        return;
    }

    m_plotOpts.SetAutoScale( false );
    m_plotOpts.SetScale( 1 );

    switch( m_plotOpts.GetScaleSelection() )
    {
    default:
        break;

    case 0:     // Autoscale option
        m_plotOpts.SetAutoScale( true );
        break;

    case 2:     // 3:2 option
        m_plotOpts.SetScale( 1.5 );
        break;

    case 3:     // 2:1 option
        m_plotOpts.SetScale( 2 );
        break;

    case 4:     // 3:1 option
        m_plotOpts.SetScale( 3 );
        break;
    }

    /* If the scale factor edit controls are disabled or the scale value
     * is 0, don't adjust the base scale factor.   This fixes a bug when
     * the default scale adjust is initialized to 0 and saved in program
     * settings resulting in a divide by zero fault.
     */
    if( m_fineAdjustXscaleOpt->IsEnabled()  && m_XScaleAdjust != 0.0 )
        m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust );

    if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 )
        m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust );

    if( m_PSFineAdjustWidthOpt->IsEnabled() )
        m_plotOpts.SetWidthAdjust( m_PSWidthAdjust );

    wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );

    // Test for a reasonable scale value
    // XXX could this actually happen? isn't it constrained in the apply
    // function?
    if( m_plotOpts.GetScale() < PLOT_MIN_SCALE )
        DisplayInfoMessage( this,
                            _( "Warning: Scale option set to a very small value" ) );

    if( m_plotOpts.GetScale() > PLOT_MAX_SCALE )
        DisplayInfoMessage( this,
                            _( "Warning: Scale option set to a very large value" ) );

    // Save the current plot options in the board
    m_parent->SetPlotSettings( m_plotOpts );

    wxBusyCursor dummy;

    for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder();  seq;  ++seq )
    {
        LAYER_ID layer = *seq;

        // Pick the basename from the board file
        wxFileName fn( boardFilename );

        // Use Gerber Extensions based on layer number
        // (See http://en.wikipedia.org/wiki/Gerber_File)
        if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_useGerberExtensions->GetValue() )
            file_ext = GetGerberExtension( layer );

        // Create file name (from the English layer name for non copper layers).
        BuildPlotFileName( &fn, outputDir.GetPath(),
                           m_board->GetStandardLayerName( layer ),
                           file_ext );

        LOCALE_IO toggle;

        BOARD*      board = m_parent->GetBoard();
        PLOTTER*    plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );

        // Print diags in messages box:
        wxString msg;

        if( plotter )
        {
            PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
            plotter->EndPlot();
            delete plotter;

            msg.Printf( _( "Plot file '%s' created." ), GetChars( fn.GetFullPath() ) );
            reporter.Report( msg, REPORTER::RPT_ACTION );
        }
        else
        {
            msg.Printf( _( "Unable to create file '%s'." ), GetChars( fn.GetFullPath() ) );
            reporter.Report( msg, REPORTER::RPT_ERROR );
        }
    }

    // If no layer selected, we have nothing plotted.
    // Prompt user if it happens because he could think there is a bug in Pcbnew.
    if( !m_plotOpts.GetLayerSelection().any() )
        DisplayError( this, _( "No layer selected" ) );
}
Beispiel #14
0
/*----------------------------------------------------------------------
|    NPT_String::ToFloat
+---------------------------------------------------------------------*/
NPT_Result 
NPT_String::ToFloat(float& value, bool relaxed) const
{
    return NPT_ParseFloat(GetChars(), value, relaxed);
}
void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();     // sheetpath is saved here

    /* When printing all pages, the printed page is not the current page.  In
     * complex hierarchies, we must update component references and others
     * parameters in the given printed SCH_SCREEN, accordint to the sheet path
     * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared
     * between many sheets and component references depend on the actual sheet
     * path used
     */
    SCH_SHEET_LIST sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    // Allocate the plotter and set the job level parameter
    PDF_PLOTTER* plotter = new PDF_PLOTTER();
    plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
    plotter->SetColorMode( getModeColor() );
    plotter->SetCreator( wxT( "Eeschema-PDF" ) );

    wxString msg;
    wxFileName plotFileName;
    REPORTER& reporter = m_MessagesBox->Reporter();
    LOCALE_IO toggle;       // Switch the locale to standard C

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();
        screen = m_parent->GetCurrentSheet().LastScreen();

        if( i == 0 )
        {

            try
            {
                wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
                wxString ext = PDF_PLOTTER::GetDefaultFileExtension();
                plotFileName = createPlotFileName( m_outputDirectoryName,
                                                   fname, ext, &reporter );

                if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
                {
                    msg.Printf( _( "Unable to create file '%s'.\n" ),
                                GetChars( plotFileName.GetFullPath() ) );
                    reporter.Report( msg, REPORTER::RPT_ERROR );
                    delete plotter;
                    return;
                }

                // Open the plotter and do the first page
                setupPlotPagePDF( plotter, screen );
                plotter->StartPlot();
            }
            catch( const IO_ERROR& e )
            {
                // Cannot plot PDF file
                msg.Printf( wxT( "PDF Plotter exception: %s" ), GetChars( e.errorText ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );

                restoreEnvironment( plotter, oldsheetpath );
                return;
            }

        }
        else
        {
            /* For the following pages you need to close the (finished) page,
             *  reconfigure, and then start a new one */
            plotter->ClosePage();
            setupPlotPagePDF( plotter, screen );
            plotter->StartPage();
        }

        plotOneSheetPDF( plotter, screen, aPlotFrameRef );
    }

    // Everything done, close the plot and restore the environment
    msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
    reporter.Report( msg, REPORTER::RPT_ACTION );

    restoreEnvironment( plotter, oldsheetpath );
}
const wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
                LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
{
    wxString attrib;

    switch( aLayer )
    {
    case F_Adhes:
        attrib = "Glue,Top";
        break;

    case B_Adhes:
        attrib = "Glue,Bot";
        break;

    case F_SilkS:
        attrib = "Legend,Top";
        break;

    case B_SilkS:
        attrib = "Legend,Bot";
        break;

    case F_Mask:
        attrib = "Soldermask,Top";
        break;

    case B_Mask:
        attrib = "Soldermask,Bot";
        break;

    case F_Paste:
        attrib = "Paste,Top";
        break;

    case B_Paste:
        attrib = "Paste,Bot";
        break;

    case Edge_Cuts:
        // Board outline.
        // Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
        // This last is the exception (Plated)
        attrib = "Profile,NP";
        break;

    case Dwgs_User:
        attrib = "Drawing";
        break;

    case Cmts_User:
        attrib = "Other,Comment";
        break;

    case Eco1_User:
        attrib = "Other,ECO1";
        break;

    case Eco2_User:
        attrib = "Other,ECO2";
        break;

    case B_Fab:
        attrib = "Other,Fab,Bot";
        break;

    case F_Fab:
        attrib = "Other,Fab,Top";
        break;

    case B_Cu:
        attrib.Printf( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
        break;

    case F_Cu:
        attrib = "Copper,L1,Top";
        break;

    default:
        if( IsCopperLayer( aLayer ) )
            attrib.Printf( wxT( "Copper,L%d,Inr" ), aLayer+1 );
        else
            attrib.Printf( wxT( "Other,User" ), aLayer+1 );
        break;
    }

    // Add the signal type of the layer, if relevant
    if( IsCopperLayer( aLayer ) )
    {
        LAYER_T type = aBoard->GetLayerType( ToLAYER_ID( aLayer ) );

        switch( type )
        {
        case LT_SIGNAL:
            attrib += ",Signal";
            break;
        case LT_POWER:
            attrib += ",Plane";
            break;
        case LT_MIXED:
            attrib += ",Mixed";
            break;
        default:
            break;   // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
        }
    }

    wxString fileFct;

    if( aUseX1CompatibilityMode )
        fileFct.Printf( "G04 #@! TF.FileFunction,%s*", GetChars( attrib ) );
    else
        fileFct.Printf( "%%TF.FileFunction,%s*%%", GetChars( attrib ) );

    return fileFct;
}
void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef )
{
    wxString        plotFileName;
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH* sheetpath;
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();

    /* When printing all pages, the printed page is not the current page.
     *  In complex hierarchies, we must setup references and other parameters
     *  in the printed SCH_SCREEN
     *  because in complex hierarchies a SCH_SCREEN (a schematic drawings)
     *  is shared between many sheets
     */
    SCH_SHEET_LIST  SheetList( NULL );

    sheetpath = SheetList.GetFirst();
    SCH_SHEET_PATH  list;

    SetHPGLPenWidth();

    while( true )
    {
        if( aPlotAll )
        {
            if( sheetpath == NULL )
                break;

            list.Clear();

            if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
            {
                m_parent->SetCurrentSheet( list );
                m_parent->GetCurrentSheet().UpdateAllScreenReferences();
                m_parent->SetSheetNumberAndCount();

                screen = m_parent->GetCurrentSheet().LastScreen();

                if( !screen ) // LastScreen() may return NULL
                    screen = m_parent->GetScreen();
            }
            else // Should not happen
                return;

            sheetpath = SheetList.GetNext();
        }

        const PAGE_INFO&    curPage = screen->GetPageSettings();

        PAGE_INFO           plotPage = curPage;

        // if plotting on a page size other than curPage
        if( m_HPGLPaperSizeOption->GetSelection() != PAGE_DEFAULT )
            plotPage.SetType( plot_sheet_list( m_HPGLPaperSizeOption->GetSelection() ) );

        // Calculation of conversion scales.
        double  plot_scale = (double) plotPage.GetWidthMils() / curPage.GetWidthMils();

        // Calculate offsets
        wxPoint plotOffset;

        if( GetPlotOriginCenter() )
        {
            plotOffset.x    = plotPage.GetWidthIU() / 2;
            plotOffset.y    = -plotPage.GetHeightIU() / 2;
        }

        plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." )
                       + HPGL_PLOTTER::GetDefaultFileExtension();

        plotFileName = Prj().AbsolutePath( plotFileName );

        LOCALE_IO toggle;

        wxString msg;
        if( Plot_1_Page_HPGL( plotFileName, screen, plotPage, plotOffset,
                              plot_scale, aPlotFrameRef ) )
            msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName ) );
        else    // Error
            msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) );

        m_MessagesBox->AppendText( msg );

        if( !aPlotAll )
            break;
    }

    m_parent->SetCurrentSheet( oldsheetpath );
    m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    m_parent->SetSheetNumberAndCount();
}
Beispiel #18
0
void CVPCB_MAINFRAME::DisplayStatus()
{
    wxString   msg;
    COMPONENT* component;

    if( wxWindow::FindFocus() == m_compListBox || wxWindow::FindFocus() == m_libListBox )
    {
        msg.Printf( _( "Components: %d, unassigned: %d" ), (int) m_netlist.GetCount(),
                    m_undefinedComponentCnt );
        SetStatusText( msg, 0 );

        msg.Empty();

        component = GetSelectedComponent();

        if( component )
        {
            for( unsigned ii = 0;  ii < component->GetFootprintFilters().GetCount();  ii++ )
            {
                if( msg.IsEmpty() )
                    msg += component->GetFootprintFilters()[ii];
                else
                    msg += wxT( ", " ) + component->GetFootprintFilters()[ii];
            }

            msg = _( "Filter list: " ) + msg;
        }

        SetStatusText( msg, 1 );
    }
    else
    {
        wxString footprintName = GetSelectedFootprint();

        FOOTPRINT_INFO* module = m_FootprintsList.GetModuleInfo( footprintName );

        if( module )    // can be NULL if no netlist loaded
        {
            msg = _( "Description: " ) + module->GetDoc();
            SetStatusText( msg, 0 );

            msg  = _( "Key words: " ) + module->GetKeywords();
            SetStatusText( msg, 1 );
        }
    }

    msg.Empty();
    wxString filters;

    if( m_footprintListBox )
    {
        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD ) )
            filters = _( "key words" );

        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT ) )
        {
            if( !filters.IsEmpty() )
                filters += wxT( "+" );

            filters += _( "pin count" );
        }

        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY ) )
        {
            if( !filters.IsEmpty() )
                filters += wxT( "+" );

            filters += _( "library" );
        }

        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) )
        {
            if( !filters.IsEmpty() )
                filters += wxT( "+" );

            filters += _( "name" );
        }

        if( filters.IsEmpty() )
            msg = _( "No filtering" );
        else
            msg.Printf( _( "Filtered by %s" ), GetChars( filters ) );

        msg << wxT( ": " ) << m_footprintListBox->GetCount();

        SetStatusText( msg, 2 );
    }
}
Beispiel #19
0
/**
 * Function CombineAllAreasInNet
 * Checks all copper areas in net for intersections, combining them if found
 * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in
 *                       undo commands can be NULL
 * @param aNetCode = net to consider
 * @param bMessageBox : if true display warning message box
 * @param bUseUtility : if true, don't check areas if both utility flags are 0
 * Sets utility flag = 1 for any areas modified
 * If an area has self-intersecting arcs, doesn't try to combine it
 */
int BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
                                 bool bMessageBox, bool bUseUtility )
{
    if( m_ZoneDescriptorList.size() <= 1 )
        return 0;

    // start by testing all area polygons to set utility2 flags
    for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
        if( m_ZoneDescriptorList[ia]->GetNet() == aNetCode )
            TestAreaPolygon( m_ZoneDescriptorList[ia] );

    // now loop through all combinations
    for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ )
    {
        ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1];
        if( curr_area->GetNet() != aNetCode )
            continue;

        // legal polygon
        CRect b1 = curr_area->m_Poly->GetCornerBounds();
        bool  mod_ia1 = false;

        for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- )
        {
            ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];

            if( area2->GetNet() != aNetCode )
                continue;
            if( curr_area->GetPriority() != area2->GetPriority() )
                continue;

            if( curr_area->GetLayer() == area2->GetLayer()
                && curr_area->utility2 != -1 && area2->utility2 != -1 )
            {
                CRect b2 = area2->m_Poly->GetCornerBounds();
                if( !( b1.left > b2.right || b1.right < b2.left
                       || b1.bottom > b2.top || b1.top < b2.bottom ) )
                {
                    // check area2 against curr_area
                    if( curr_area->utility || area2->utility || bUseUtility == false )
                    {
                        int ret = TestAreaIntersection( curr_area, area2 );

                        if( ret == 1 )
                            ret = CombineAreas( aDeletedList, curr_area, area2 );

                        if( ret == 1 )
                        {
                            mod_ia1 = true;
                        }
                        else if( ret == 2 )
                        {
                            if( bMessageBox && bDontShowIntersectionArcsWarning == false )
                            {
                                wxString str;
                                str.Printf( wxT( "Areas %d and %d of net \"%s\" intersect, but some of the intersecting sides are arcs.\n" ),
                                            ia1 + 1,
                                            ia2 + 1,
                                            GetChars( curr_area->m_Netname ) );
                                str += wxT( "Therefore, these areas can't be combined." );
                                wxMessageBox( str );
                            }
                        }
                    }
                }
            }
        }

        if( mod_ia1 )
            ia1--;     // if modified, we need to check it again
    }

    return 0;
}
void DialogEditModuleText::initDlg( )
{
    SetFocus();

    wxString msg;

    if( m_module )
    {
        wxString format = m_ModuleInfoText->GetLabel();
        msg.Printf( format,
                    GetChars( m_module->GetReference() ),
                    GetChars( m_module->GetValue() ),
                    m_module->GetOrientation() / 10.0 );
    }
    else
    {
        msg.Empty();
    }

    m_ModuleInfoText->SetLabel( msg );

    switch( m_currentText->GetType() )
    {
    case TEXTE_MODULE::TEXT_is_VALUE:
        m_TextDataTitle->SetLabel( _( "Value:" ) );
        break;

    case TEXTE_MODULE::TEXT_is_DIVERS:
        m_TextDataTitle->SetLabel( _( "Text:" ) );
        break;

    default:
        m_TextDataTitle->SetLabel( _( "Reference:" ) );
        break;
    }

    m_Name->SetValue( m_currentText->GetText() );

    m_Style->SetSelection( m_currentText->IsItalic() ? 1 : 0 );

    AddUnitSymbol( *m_SizeXTitle );
    PutValueInLocalUnits( *m_TxtSizeCtrlX, m_currentText->GetSize().x );

    AddUnitSymbol( *m_SizeYTitle );
    PutValueInLocalUnits( *m_TxtSizeCtrlY, m_currentText->GetSize().y );

    AddUnitSymbol( *m_PosXTitle );
    PutValueInLocalUnits( *m_TxtPosCtrlX, m_currentText->GetPos0().x );

    AddUnitSymbol( *m_PosYTitle );
    PutValueInLocalUnits( *m_TxtPosCtrlY, m_currentText->GetPos0().y );

    AddUnitSymbol( *m_WidthTitle );
    PutValueInLocalUnits( *m_TxtWidthCtlr, m_currentText->GetThickness() );

    double text_orient = m_currentText->GetOrientation();
    NORMALIZE_ANGLE_90( text_orient );

    if( (text_orient != 0) )
        m_Orient->SetSelection( 1 );

    if( !m_currentText->IsVisible() )
        m_Show->SetSelection( 1 );;
}
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_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;

    // Macros IDs
    case ID_PREFRENCES_MACROS_SAVE:
        SaveMacros();
        break;

    case ID_PREFRENCES_MACROS_READ:
        ReadMacros();
        break;

    default:
        DisplayError( this, wxT( "PCB_EDIT_FRAME::Process_Config error" ) );
    }
}
Beispiel #22
0
bool CMP_READER::Load( NETLIST* aNetlist )
{
    wxCHECK_MSG( aNetlist != NULL,true, wxT( "No netlist passed to CMP_READER::Load()" ) );

    wxString reference;    // Stores value read from line like Reference = BUS1;
    wxString timestamp;    // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
    wxString footprint;    // Stores value read from line like IdModule  = CP6;
    wxString buffer;
    wxString value;

    bool ok = true;

    while( m_lineReader->ReadLine() )
    {
        buffer = FROM_UTF8( m_lineReader->Line() );

        if( !buffer.StartsWith( wxT( "BeginCmp" ) ) )
            continue;

        // Begin component description.
        reference.Empty();
        footprint.Empty();
        timestamp.Empty();

        while( m_lineReader->ReadLine() )
        {
            buffer = FROM_UTF8( m_lineReader->Line() );

            if( buffer.StartsWith( wxT( "EndCmp" ) ) )
                break;

            // store string value, stored between '=' and ';' delimiters.
            value = buffer.AfterFirst( '=' );
            value = value.BeforeLast( ';' );
            value.Trim( true );
            value.Trim( false );

            if( buffer.StartsWith( wxT( "Reference" ) ) )
            {
                reference = value;
                continue;
            }

            if( buffer.StartsWith( wxT( "IdModule  =" ) ) )
            {
                footprint = value;
                continue;
            }

            if( buffer.StartsWith( wxT( "TimeStamp =" ) ) )
            {
                timestamp = value;
                continue;
            }
        }

        // Find the corresponding item in component list:
        COMPONENT* component = aNetlist->GetComponentByReference( reference );

        // The corresponding component could no longer existing in the netlist.  This
        // can happen when it is removed from schematic and still exists in footprint
        // assignment list.  This is an usual case during the life of a design.
        if( component )
        {
            LIB_ID fpid;

            if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
            {
                wxString error;
                error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ),
                              GetChars( m_lineReader->GetSource() ),
                              m_lineReader->LineNumber() );

                THROW_IO_ERROR( error );
            }

            // For checking purpose, store the existing LIB_ID (if any) in the alternate fpid copy
            // if this existing LIB_ID differs from the LIB_ID read from the .cmp file.
            // CvPcb can ask for user to chose the right LIB_ID.
            // It happens if the LIB_ID was modified outside CvPcb.
            if( fpid != component->GetFPID() && !component->GetFPID().empty() )
                component->SetAltFPID( component->GetFPID() );

            component->SetFPID( fpid );
        }
        else
        {
            ok = false;     // can be used to display a warning in Pcbnew.
        }
    }

    return ok;
}
Beispiel #23
0
bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
{
    COMPONENT* component;
    wxString   msg;
    bool       isLegacy = true;

    ReadSchematicNetlist();

    if( m_ListCmp == NULL )
        return false;

    LoadProjectFile( m_NetlistFileName.GetFullPath() );
    LoadFootprintFiles();
    BuildFOOTPRINTS_LISTBOX();
    BuildLIBRARY_LISTBOX();

    m_ListCmp->Clear();
    m_undefinedComponentCnt = 0;

    if( m_netlist.AnyFootprintsLinked() )
    {
        for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
        {
            component = m_netlist.GetComponent( i );

            if( component->GetFPID().empty() )
                continue;

            if( isLegacy )
            {
                if( !component->GetFPID().IsLegacy() )
                    isLegacy = false;
            }
        }
    }
    else
    {
        isLegacy = false;  // None of the components have footprints assigned.
    }

    wxString missingLibs;

    // Check if footprint links were generated before the footprint library table was implemented.
    if( isLegacy )
    {
        if( m_footprintLibTable->MissingLegacyLibs( m_ModuleLibNames, &missingLibs ) )
        {
            msg = wxT( "The following legacy libraries are defined in the project file "
                       "were not found in the footprint library table:\n\n" ) + missingLibs;
            msg += wxT( "\nDo you want to update the footprint library table before "
                        "attempting to update the assigned footprints?" );

            if( IsOK( this, msg ) )
            {
                wxCommandEvent cmd;

                OnEditFootprintLibraryTable( cmd );
            }
        }

        msg = wxT( "Some or all of the assigned footprints contain legacy entries.  Would you "
                   "like CvPcb to attempt to convert them to the new footprint library table "
                   "format?" );

        if( IsOK( this, msg ) )
        {
            msg.Clear();
            WX_STRING_REPORTER reporter( &msg );

            if( !m_footprintLibTable->ConvertFromLegacy( m_netlist, m_ModuleLibNames, &reporter ) )
            {
                HTML_MESSAGE_BOX dlg( this, wxEmptyString );

                dlg.MessageSet( wxT( "The following errors occurred attempt to convert the "
                                     "footprint assignments:\n\n" ) );
                dlg.ListSet( msg );
                dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them "
                                     "to be updated correctly the next time you import the "
                                     "netlist in Pcbnew." ) );
                dlg.ShowModal();
            }

            m_modified = true;
        }
        else
        {
            // Clear the legacy footprint assignments.
            for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
            {
                FPID emptyFPID;
                component = m_netlist.GetComponent( i );
                component->SetFPID( emptyFPID );
                m_modified = true;
            }
        }
    }

    for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
    {
        component = m_netlist.GetComponent( i );

        msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
                    GetChars( component->GetReference() ),
                    GetChars( component->GetValue() ),
                    GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );

        m_ListCmp->AppendLine( msg );

        if( component->GetFPID().empty() )
        {
            m_undefinedComponentCnt += 1;
            continue;
        }
    }

    if( !m_netlist.IsEmpty() )
        m_ListCmp->SetSelection( 0, true );

    DisplayStatus();

    UpdateTitle();

    UpdateFileHistory( m_NetlistFileName.GetFullPath() );

    return true;
}
Beispiel #24
0
void DIALOG_LABEL_EDITOR::InitDialog()
{
    wxString msg;
    bool multiLine = false;

    if( m_CurrentText->IsMultilineAllowed() )
    {
        m_textLabel = m_textLabelMultiLine;
        m_textLabelSingleLine->Show( false );
        multiLine = true;
    }
    else
    {
        m_textLabel = m_textLabelSingleLine;
        m_textLabelMultiLine->Show( false );
        wxTextValidator* validator = (wxTextValidator*) m_textLabel->GetValidator();
        wxArrayString excludes;

        // Add invalid label characters to this list.
        excludes.Add( wxT( " " ) );
        validator->SetExcludes( excludes );
    }

    m_textLabel->SetValue( m_CurrentText->GetText() );
    m_textLabel->SetFocus();

    switch( m_CurrentText->Type() )
    {
    case SCH_GLOBAL_LABEL_T:
        SetTitle( _( "Global Label Properties" ) );
        break;

    case SCH_HIERARCHICAL_LABEL_T:
        SetTitle( _( "Hierarchical Label Properties" ) );
        break;

    case SCH_LABEL_T:
        SetTitle( _( "Label Properties" ) );
        break;

    case SCH_SHEET_PIN_T:
        SetTitle( _( "Hierarchical Sheet Pin Properties." ) );
        break;

    default:
        SetTitle( _( "Text Properties" ) );
        m_textLabel->Disconnect( wxEVT_COMMAND_TEXT_ENTER,
                                 wxCommandEventHandler ( DIALOG_LABEL_EDITOR::OnEnterKey ),
                                 NULL, this );
        break;
    }

    const int MINTEXTWIDTH = 40;    // M's are big characters, a few establish a lot of width

    int max_len = 0;

    if ( !multiLine )
    {
        max_len = m_CurrentText->GetText().Length();
    }
    else
    {
        // calculate the length of the biggest line
        // we cannot use the length of the entire text that has no meaning
        int curr_len = MINTEXTWIDTH;
        int imax = m_CurrentText->GetText().Length();

        for( int count = 0; count < imax; count++ )
        {
            if( m_CurrentText->GetText()[count] == '\n' ||
                m_CurrentText->GetText()[count] == '\r' ) // new line
            {
                curr_len = 0;
            }
            else
            {
                curr_len++;

                if ( max_len < curr_len )
                    max_len = curr_len;
            }
        }
    }

    if( max_len < MINTEXTWIDTH )
        max_len = MINTEXTWIDTH;

    wxString textWidth;
    textWidth.Append( 'M', MINTEXTWIDTH );
    EnsureTextCtrlWidth( m_textLabel, &textWidth );

    // Set validators
    m_TextOrient->SetSelection( m_CurrentText->GetOrientation() );
    m_TextShape->SetSelection( m_CurrentText->GetShape() );

    int style = 0;

    if( m_CurrentText->IsItalic() )
        style = 1;

    if( m_CurrentText->IsBold() )
        style += 2;

    m_TextStyle->SetSelection( style );

    wxString units = ReturnUnitSymbol( g_UserUnit, wxT( "(%s)" ) );
    msg.Printf( _( "H%s x W%s" ), GetChars( units ), GetChars( units ) );
    m_staticSizeUnits->SetLabel( msg );

    msg = StringFromValue( g_UserUnit, m_CurrentText->GetSize().x );
    m_TextSize->SetValue( msg );

    if( m_CurrentText->Type() != SCH_GLOBAL_LABEL_T
     && m_CurrentText->Type() != SCH_HIERARCHICAL_LABEL_T )
    {
        m_TextShape->Show( false );
    }

    m_sdbSizer1OK->SetDefault();
}
Beispiel #25
0
void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
{
    COMPONENT* component;
    bool       hasFootprint = false;
    int        componentIndex;
    wxString   description;

    if( m_netlist.IsEmpty() )
        return;

    // If no component is selected, select the first one
    if( m_ListCmp->GetFirstSelected() < 0 )
    {
        componentIndex = 0;
        m_ListCmp->SetSelection( componentIndex, true );
    }

    // iterate over the selection
    while( m_ListCmp->GetFirstSelected() != -1 )
    {
        // Get the component for the current iteration
        componentIndex = m_ListCmp->GetFirstSelected();
        component = m_netlist.GetComponent( componentIndex );

        if( component == NULL )
            return;

        // Check to see if the component has already a footprint set.
        hasFootprint = !component->GetFPID().empty();

        FPID fpid;

        if( !aFootprintName.IsEmpty() )
        {
            wxCHECK_RET( fpid.Parse( aFootprintName ) < 0,
                         wxString::Format( wxT( "<%s> is not a valid FPID." ),
                                           GetChars( aFootprintName ) ) );
        }

        component->SetFPID( fpid );

        // create the new component description
        description.Printf( CMP_FORMAT, componentIndex + 1,
                            GetChars( component->GetReference() ),
                            GetChars( component->GetValue() ),
                            GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );

        // If the component hasn't had a footprint associated with it
        // it now has, so we decrement the count of components without
        // a footprint assigned.
        if( !hasFootprint )
        {
            hasFootprint = true;
            m_undefinedComponentCnt -= 1;
        }

        // Set the new description and deselect the processed component
        m_ListCmp->SetString( componentIndex, description );
        m_ListCmp->SetSelection( componentIndex, false );
    }

    // Mark this "session" as modified
    m_modified = true;

    // select the next component, if there is one
    if( componentIndex < (m_ListCmp->GetCount() - 1) )
        componentIndex++;

    m_ListCmp->SetSelection( componentIndex, true );

    // update the statusbar
    DisplayStatus();
}
void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
{
    unsigned       i;
    SCH_ITEM*      item;
    SCH_SHEET_LIST hierarchy;    // This is the entire schematic hierarcy.

    if( m_blockItems.GetCount() == 0 )
    {
        DisplayError( this, _( "No item to paste." ) );
        return;
    }

    wxFileName destFn = m_CurrentSheet->Last()->GetFileName();

    if( destFn.IsRelative() )
        destFn.MakeAbsolute( Prj().GetProjectPath() );

    // Make sure any sheets in the block to be pasted will not cause recursion in
    // the destination sheet.
    for( i = 0; i < m_blockItems.GetCount(); i++ )
    {
        item = (SCH_ITEM*) m_blockItems.GetItem( i );

        if( item->Type() == SCH_SHEET_T )
        {
            SCH_SHEET* sheet = (SCH_SHEET*)item;
            wxFileName srcFn = sheet->GetFileName();

            if( srcFn.IsRelative() )
                srcFn.MakeAbsolute( Prj().GetProjectPath() );

            std::vector< std::vector< const SCH_SHEET* > > sheetHierarchy;
            sheet->GetSheetPaths( sheetHierarchy );

            if( g_RootSheet->TestForRecursion( sheetHierarchy,
                                               destFn.GetFullPath( wxPATH_UNIX ) ) )
            {
                wxString msg;

                msg.Printf( _( "The sheet changes cannot be made because the destination "
                               "sheet already has the sheet <%s> or one of it's subsheets "
                               "as a parent somewhere in the schematic hierarchy." ),
                            GetChars( sheet->GetFileName() ) );
                DisplayError( this, msg );
                return;
            }

            // Duplicate sheet names and sheet time stamps are not valid.  Use a time stamp
            // based sheet name and update the time stamp for each sheet in the block.
            unsigned long timeStamp = (unsigned long)GetNewTimeStamp();

            sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), timeStamp ) );
            sheet->SetTimeStamp( (time_t)timeStamp );
        }
    }

    PICKED_ITEMS_LIST picklist;

    for( i = 0; i < m_blockItems.GetCount(); i++ )
    {
        item = DuplicateStruct( (SCH_ITEM*) m_blockItems.GetItem( i ) );

        // Creates data, and push it as new data in undo item list buffer
        ITEM_PICKER picker( item, UR_NEW );
        picklist.PushItem( picker );

        // Clear annotation and init new time stamp for the new components and sheets:
        if( item->Type() == SCH_COMPONENT_T )
        {
            ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
            ( (SCH_COMPONENT*) item )->ClearAnnotation( NULL );
        }
        else if( item->Type() == SCH_SHEET_T )
        {
            ( (SCH_SHEET*) item )->SetTimeStamp( GetNewTimeStamp() );
        }

        SetSchItemParent( item, GetScreen() );
        item->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        GetScreen()->Append( item );
    }

    SaveCopyInUndoList( picklist, UR_NEW );

    MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() );

    // Clear flags for all items.
    GetScreen()->ClearDrawingState();

    OnModify();

    return;
}
Beispiel #27
0
void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event )
{
    wxString reportName;

    bool make_report = m_CreateRptCtrl->IsChecked();

    if( make_report )      // Create a file rpt
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent junk;
            OnButtonBrowseRptFileClick( junk );
        }

        if( !reportName.IsEmpty() )
            reportName = makeValidFileNameReport();
    }

    SetDrcParmeters();

    m_tester->SetSettings( true,        // Pad to pad DRC test enabled
                           true,        // unconnected pads DRC test enabled
                           true,        // DRC test for zones enabled
                           true,        // DRC test for keepout areas enabled
                           m_cbCourtyardOverlap->GetValue(),
                           m_cbCourtyardMissing->GetValue(),
                           reportName, make_report );

    DelDRCMarkers();

    wxBeginBusyCursor();

    m_Messages->Clear();
    m_tester->ListUnconnectedPads();

    m_Notebook->ChangeSelection( 1 );       // display the 2nd tab "Unconnected..."

    // Generate the report
    if( !reportName.IsEmpty() )
    {
        if( writeReport( reportName ) )
        {
            wxString        msg;
            msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );
            wxString        caption( _( "Disk File Report Completed" ) );
            wxMessageDialog popupWindow( this, msg, caption );
            popupWindow.ShowModal();
        }
        else
            DisplayError( this, wxString::Format( _( "Unable to create report file \"%s\""),
                          GetChars( reportName ) ) );
    }

    UpdateDisplayedCounts();

    wxEndBusyCursor();

    /* there is currently nothing visible on the DrawPanel for unconnected pads
     *  RedrawDrawPanel();
     */
}
/**
 * Function WriteHotkeyConfig
 * Store the current hotkey list
 * It is stored using the standard wxConfig mechanism or a file.
 *
 * @param aDescList = pointer to the current hotkey list.
 * @param aFullFileName = a wxString pointer to a full file name.
 *  if NULL, use the standard wxConfig mechanism (default)
 * the output format is: shortcut  "key"  "function"
 * lines starting with # are comments
 */
int EDA_BASE_FRAME::WriteHotkeyConfig( struct EDA_HOTKEY_CONFIG* aDescList,
                                       wxString*                 aFullFileName )
{
    wxString msg;
    wxString keyname, infokey;

    msg = wxT( "$hotkey list\n" );

    // Print the current hotkey list
    EDA_HOTKEY** list;

    for( ; aDescList->m_HK_InfoList != NULL; aDescList++ )
    {
        if( aDescList->m_Comment )
        {
            msg += wxT( "# " );
            msg += wxString( aDescList->m_Comment );
            msg += wxT( "\n" );
        }

        msg += *aDescList->m_SectionTag;
        msg += wxT( "\n" );

        list = aDescList->m_HK_InfoList;

        for( ; *list != NULL; list++ )
        {
            EDA_HOTKEY* hk_decr = *list;
            msg    += wxT( "shortcut   " );
            keyname = KeyNameFromKeyCode( hk_decr->m_KeyCode );
            AddDelimiterString( keyname );
            infokey = hk_decr->m_InfoMsg;
            AddDelimiterString( infokey );
            msg += keyname + wxT( ":    " ) + infokey + wxT( "\n" );
        }
    }

    msg += wxT( "$Endlist\n" );

    if( aFullFileName )
    {
        FILE* file = wxFopen( *aFullFileName, wxT( "wt" ) );

        if( file )
        {
            fputs( TO_UTF8( msg ), file );
            fclose( file );
        }
        else
        {
            msg.Printf( wxT( "Unable to write file %s" ), GetChars( *aFullFileName ) );
            return 0;
        }
    }
    else
    {
        wxConfig config( m_FrameName );
        config.Write( HOTKEYS_CONFIG_KEY, msg );
    }

    return 1;
}
Beispiel #29
0
wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
                                          const wxString& aLibraryName,
                                          const wxString& aMask,
                                          const wxString& aKeyWord,
                                          FP_LIB_TABLE*   aTable )
{
    static wxString oldName;    // Save the name of the last module loaded.

    wxString        fpname;
    wxString        msg;
    wxArrayString   libraries;

    std::vector< wxArrayString > rows;

    wxASSERT( aTable != NULL );

    MList.ReadFootprintFiles( aTable, !aLibraryName ? NULL : &aLibraryName );

    if( MList.GetErrorCount() )
    {
        MList.DisplayErrors( this );
        return wxEmptyString;
    }

    if( MList.GetCount() == 0 )
    {
        wxString tmp;

        for( unsigned i = 0;  i < libraries.GetCount();  i++ )
        {
            tmp += libraries[i] + wxT( "\n" );
        }

        msg.Printf( _( "No footprints could be read from library file(s):\n\n%s\nin any of "
                       "the library search paths.  Verify your system is configured properly "
                       "so the footprint libraries can be found." ), GetChars( tmp ) );
        DisplayError( aWindow, msg );
        return wxEmptyString;
    }

    if( !aKeyWord.IsEmpty() )       // Create a list of modules found by keyword.
    {
        for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
        {
            if( KeyWordOk( aKeyWord, MList.GetItem( ii ).GetKeywords() ) )
            {
                wxArrayString   cols;
                cols.Add( MList.GetItem( ii ).GetFootprintName() );
                cols.Add( MList.GetItem( ii ).GetNickname() );
                rows.push_back( cols );
            }
        }
    }
    else if( !aMask.IsEmpty() )     // Create a list of modules found by pattern
    {
        for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
        {
            const wxString& candidate = MList.GetItem( ii ).GetFootprintName();

            if( WildCompareString( aMask, candidate, false ) )
            {
                wxArrayString   cols;
                cols.Add( MList.GetItem( ii ).GetFootprintName() );
                cols.Add( MList.GetItem( ii ).GetNickname() );
                rows.push_back( cols );
            }
        }
    }
    else                            // Create the full list of modules
    {
        for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
        {
            wxArrayString   cols;
            cols.Add( MList.GetItem( ii ).GetFootprintName() );
            cols.Add( MList.GetItem( ii ).GetNickname() );
            rows.push_back( cols );
        }
    }

    if( !rows.empty() )
    {
        wxArrayString headers;

        headers.Add( _( "Footprint" ) );
        headers.Add( _( "Library" ) );

        msg.Printf( _( "Footprints [%d items]" ), (int) rows.size() );

        EDA_LIST_DIALOG dlg( aWindow, msg, headers, rows, oldName, DisplayCmpDoc );

        if( dlg.ShowModal() == wxID_OK )
        {
            fpname = dlg.GetTextSelection();

            fpname = dlg.GetTextSelection( 1 ) + wxT( ":" ) + fpname;

            SkipNextLeftButtonReleaseEvent();
        }
        else
            fpname.Empty();
    }
    else
    {
        DisplayError( aWindow, _( "No footprint found." ) );
        fpname.Empty();
    }

    if( fpname != wxEmptyString )
        oldName = fpname;

    wxLogDebug( wxT( "Footprint '%s' was selected." ), GetChars( fpname ) );

    return fpname;
}
Beispiel #30
0
/*----------------------------------------------------------------------
|    NPT_String::ToInteger
+---------------------------------------------------------------------*/
NPT_Result 
NPT_String::ToInteger(NPT_Int32& value, bool relaxed) const
{
    return NPT_ParseInteger32(GetChars(), value, relaxed);
}