예제 #1
0
/* Add a new graphical text to the active module (footprint)
 *  Note there always are 2 mandatory texts: reference and value.
 *  New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
 */
TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
{
    TEXTE_MODULE* text = new TEXTE_MODULE( aModule );

    text->SetFlags( IS_NEW );

    if( LSET::AllTechMask().test( GetActiveLayer() ) )    // i.e. a possible layer for a text
        text->SetLayer( GetActiveLayer() );

    InstallTextOptionsFrame( text, NULL );

    if( text->GetText().IsEmpty() )
    {
        delete text;
        return NULL;
    }

    // Add the new text object to the beginning of the footprint draw list.
    if( aModule )
        aModule->GraphicalItemsList().PushFront( text );

    text->ClearFlags();

    if( aDC )
        text->Draw( m_canvas, aDC, GR_OR );

    SetMsgPanel( text );

    return text;
}
예제 #2
0
/* Initialize the drawing of a segment of type other than trace.
 */
DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T shape, wxDC* DC )
{
    int          lineWidth;
    DRAWSEGMENT* DrawItem;

    lineWidth = GetDesignSettings().GetLineThickness( GetActiveLayer() );

    if( Segment == NULL )        // Create new segment.
    {
        SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );
        Segment->SetFlags( IS_NEW );
        Segment->SetLayer( GetActiveLayer() );
        Segment->SetWidth( lineWidth );
        Segment->SetShape( shape );
        Segment->SetAngle( 900 );
        Segment->SetStart( GetCrossHairPosition() );
        Segment->SetEnd( GetCrossHairPosition() );
        m_canvas->SetMouseCapture( DrawSegment, Abort_EditEdge );
    }
    else
    {
        // The ending point coordinate Segment->m_End was updated by the function
        // DrawSegment() called on a move mouse event during the segment creation
        if( Segment->GetStart() != Segment->GetEnd() )
        {
            if( Segment->GetShape() == S_SEGMENT )
            {
                SaveCopyInUndoList( Segment, UR_NEW );
                GetBoard()->Add( Segment );

                OnModify();
                Segment->ClearFlags();

                Segment->Draw( m_canvas, DC, GR_OR );

                DrawItem = Segment;

                SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );

                Segment->SetFlags( IS_NEW );
                Segment->SetLayer( DrawItem->GetLayer() );
                Segment->SetWidth( lineWidth );
                Segment->SetShape( DrawItem->GetShape() );
                Segment->SetType( DrawItem->GetType() );
                Segment->SetAngle( DrawItem->GetAngle() );
                Segment->SetStart( DrawItem->GetEnd() );
                Segment->SetEnd( DrawItem->GetEnd() );
                DrawSegment( m_canvas, DC, wxDefaultPosition, false );
            }
            else
            {
                End_Edge( Segment, DC );
                Segment = NULL;
            }
        }
    }

    return Segment;
}
예제 #3
0
파일: files.cpp 프로젝트: cpavlina/kicad
bool GERBVIEW_FRAME::LoadZipArchiveFile( const wxString& aFullFileName )
{
#define ZipFileExtension "zip"

    wxFileName filename = aFullFileName;
    wxString currentPath;

    if( !filename.IsOk() )
    {
        // Use the current working directory if the file name path does not exist.
        if( filename.DirExists() )
            currentPath = filename.GetPath();
        else
            currentPath = m_mruPath;

        wxFileDialog dlg( this,
                          _( "Open Zip File" ),
                          currentPath,
                          filename.GetFullName(),
                          ZipFileWildcard(),
                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );

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

        filename = dlg.GetPath();
        currentPath = wxGetCwd();
        m_mruPath = currentPath;
    }
    else
    {
        currentPath = filename.GetPath();
        m_mruPath = currentPath;
    }

    wxString msg;
    WX_STRING_REPORTER reporter( &msg );

    if( filename.IsOk() )
        unarchiveFiles( filename.GetFullPath(), &reporter );

    Zoom_Automatique( false );

    // Synchronize layers tools with actual active layer:
    ReFillLayerWidget();
    SetActiveLayer( GetActiveLayer() );
    m_LayersManager->UpdateLayerIcons();
    syncLayerBox();

    if( !msg.IsEmpty() )
    {
        wxSafeYield();  // Allows slice of time to redraw the screen
                        // to refresh widgets, before displaying messages
        HTML_MESSAGE_BOX mbox( this, _( "Messages" ) );
        mbox.ListSet( msg );
        mbox.ShowModal();
    }

    return true;
}
예제 #4
0
파일: prpslyrs.cpp 프로젝트: vata/xarino
BOOL LayerPropertiesTab::ChangeControlStatus(const BOOL Status)
{
	BOOL Enable;

	Layer* pLayer = GetActiveLayer();
	Enable = (pLayer != NULL) && Status;

	BOOL EnableNonFrameItem = Enable;
	//It shouldn't be in Webster builds anyway but we will take it out jus tin case
#ifndef WEBSTER
	// Check if we are on a frame layer or not
	// If we are then we must disable some items
	// At present, these are the visible and editable flags as these are not user controlled.
//	BOOL FrameLayer = FALSE;
	if (pLayer != NULL && pLayer->IsFrame())
		EnableNonFrameItem = FALSE;
#endif

	pPropertiesDlg->EnableGadget(_R(IDC_GUIDETAB_GUIDELINELIST),Enable);
	pPropertiesDlg->EnableGadget(_R(IDC_LAYERTAB_NAME),			Enable);
	pPropertiesDlg->EnableGadget(_R(IDC_LAYERTAB_VISIBLE),		EnableNonFrameItem);
	pPropertiesDlg->EnableGadget(_R(IDC_LAYERTAB_EDITABLE),		EnableNonFrameItem);

	return TRUE;
}			
예제 #5
0
파일: prpslyrs.cpp 프로젝트: vata/xarino
BOOL LayerPropertiesTab::CommitSection()
{
TRACEUSER( "Neville", _T("LayerPropertiesTab::CommitSection\n"));
	ERROR2IF(pPropertiesDlg == NULL,FALSE,"LayerPropertiesTab::CommitSection called with no dialog pointer");

	BOOL ok = pPropertiesDlg->TalkToPage(GetPageID());
	if (!ok)
		return TRUE;			// Talk to page failed to return now

	Layer* pLayer = GetActiveLayer();

	// Only do the op if we have a layer with a different set of properties
	if (pLayer != NULL && HavePropertiesChanged(pLayer))
	{
		// Initialise the param structure
		OpLayerGalParam Param(LAYER_CHANGE, pSpread);
		Param.pLayer = pLayer;

		Param.VisibleState  =  pPropertiesDlg->GetBoolGadgetSelected(_R(IDC_LAYERTAB_VISIBLE));
		Param.LockedState   = !pPropertiesDlg->GetBoolGadgetSelected(_R(IDC_LAYERTAB_EDITABLE));
		Param.NewName		=  pPropertiesDlg->GetStringGadgetValue(_R(IDC_LAYERTAB_NAME),NULL);

		// Invoke the operation
		OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_LAYERGALCHANGE); 
		if (pOpDesc != NULL)
			pOpDesc->Invoke((OpParam*)&Param);
		else
		{
			ERROR3("Couldn't find OPTOKEN_LAYERGALCHANGE op descriptor");
		}
	}

	return TRUE;
}
void PCB_EDIT_FRAME::InstallPcbGlobalDeleteFrame( const wxPoint& pos )
{
    DIALOG_GLOBAL_DELETION dlg( this );
    dlg.SetCurrentLayer( GetActiveLayer() );

    dlg.ShowModal();
}
예제 #7
0
파일: dimension.cpp 프로젝트: OpenEE/micad
DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC )
{
    wxPoint pos;

    if( aDimension == NULL )
    {
        status_dimension = 1;
        pos = GetCrossHairPosition();

        aDimension = new DIMENSION( GetBoard() );
        aDimension->SetFlags( IS_NEW );
        aDimension->SetLayer( GetActiveLayer() );
        aDimension->SetOrigin( pos );
        aDimension->SetEnd( pos );

        aDimension->Text().SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
        int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
        int maxthickness = Clamp_Text_PenSize(width, aDimension->Text().GetSize() );

        if( width > maxthickness )
        {
            width = maxthickness;
        }

        aDimension->Text().SetThickness( width );
        aDimension->SetWidth( width );
        aDimension->AdjustDimensionDetails();
        aDimension->Draw( m_canvas, aDC, GR_XOR );

        m_canvas->SetMouseCapture( BuildDimension, AbortBuildDimension );
        return aDimension;
    }

    // Dimension != NULL
    if( status_dimension == 1 )
    {
        status_dimension = 2;
        return aDimension;
    }

    aDimension->Draw( m_canvas, aDC, GR_OR );
    aDimension->ClearFlags();

    /* ADD this new item in list */
    GetBoard()->Add( aDimension );

    // Add store it in undo/redo list
    SaveCopyInUndoList( aDimension, UR_NEW );

    OnModify();
    m_canvas->SetMouseCapture( NULL, NULL );

    return NULL;
}
예제 #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();
}
/* Add a new graphical text to the active module (footprint)
 *  Note there always are 2 mandatory texts: reference and value.
 *  New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
 */
TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
{
    TEXTE_MODULE* text = new TEXTE_MODULE( aModule );

    text->SetFlags( IS_NEW );

    GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth,
            std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
    text->SetTextSize( GetDesignSettings().m_ModuleTextSize );
    text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
    text->SetPosition( GetCrossHairPosition() );

    if( LSET::AllTechMask().test( GetActiveLayer() ) )    // i.e. a possible layer for a text
        text->SetLayer( GetActiveLayer() );

    InstallTextModOptionsFrame( text, NULL );

    m_canvas->MoveCursorToCrossHair();

    if( text->GetText().IsEmpty() )
    {
        delete text;
        return NULL;
    }

    // Add the new text object to the beginning of the footprint draw list.
    if( aModule )
        aModule->GraphicalItems().PushFront( text );

    text->ClearFlags();

    if( aDC )
        text->Draw( m_canvas, aDC, GR_OR );

    SetMsgPanel( text );

    return text;
}
예제 #10
0
// Note: virtual, overridden in PCB_EDIT_FRAME;
void PCB_BASE_FRAME::SwitchLayer( wxDC* DC, LAYER_ID layer )
{
    LAYER_ID preslayer = GetActiveLayer();
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();

    // Check if the specified layer matches the present layer
    if( layer == preslayer )
        return;

    // Copper layers cannot be selected unconditionally; how many
    // of those layers are currently enabled needs to be checked.
    if( IsCopperLayer( layer ) )
    {
        // If only one copper layer is enabled, the only such layer
        // that can be selected to is the "Copper" layer (so the
        // selection of any other copper layer is disregarded).
        if( m_Pcb->GetCopperLayerCount() < 2 )
        {
            if( layer != B_Cu )
            {
                return;
            }
        }

        // If more than one copper layer is enabled, the "Copper"
        // and "Component" layers can be selected, but the total
        // number of copper layers determines which internal
        // layers are also capable of being selected.
        else
        {
            if( ( layer != B_Cu ) && ( layer != F_Cu )
                && ( layer >= m_Pcb->GetCopperLayerCount() - 1 ) )
            {
                return;
            }
        }
    }

    // Is yet more checking required? E.g. when the layer to be selected
    // is a non-copper layer, or when switching between a copper layer
    // and a non-copper layer, or vice-versa?
    // ...

    GetScreen()->m_Active_Layer = layer;

    if( displ_opts->m_ContrastModeDisplay )
        m_canvas->Refresh();
}
void FOOTPRINT_EDIT_FRAME::UpdateUserInterface()
{
    // Update the layer manager and other widgets from the board setup
    // (layer and items visibility, colors ...)

    // Update the layer manager
    m_Layers->Freeze();
    ReFillLayerWidget();
    m_Layers->ReFillRender();

    // update the layer widget to match board visibility states.
    m_Layers->SyncLayerVisibilities();
    static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( m_Pcb );
    m_Layers->SelectLayer( GetActiveLayer() );
    m_Layers->OnLayerSelected();

    m_Layers->Thaw();
}
예제 #12
0
GENERAL_COLLECTORS_GUIDE PCB_BASE_FRAME::GetCollectorsGuide()
{
    GENERAL_COLLECTORS_GUIDE guide( m_Pcb->GetVisibleLayers(),
                                    GetActiveLayer() );

    // account for the globals
    guide.SetIgnoreMTextsMarkedNoShow( ! m_Pcb->IsElementVisible( MOD_TEXT_INVISIBLE ));
    guide.SetIgnoreMTextsOnBack( ! m_Pcb->IsElementVisible( MOD_TEXT_BK_VISIBLE ));
    guide.SetIgnoreMTextsOnFront( ! m_Pcb->IsElementVisible( MOD_TEXT_FR_VISIBLE ));
    guide.SetIgnoreModulesOnBack( ! m_Pcb->IsElementVisible( MOD_BK_VISIBLE ) );
    guide.SetIgnoreModulesOnFront( ! m_Pcb->IsElementVisible( MOD_FR_VISIBLE ) );
    guide.SetIgnorePadsOnBack( ! m_Pcb->IsElementVisible( PAD_BK_VISIBLE ) );
    guide.SetIgnorePadsOnFront( ! m_Pcb->IsElementVisible( PAD_FR_VISIBLE ) );
    guide.SetIgnoreModulesVals( ! m_Pcb->IsElementVisible( MOD_VALUES_VISIBLE ) );
    guide.SetIgnoreModulesRefs( ! m_Pcb->IsElementVisible( MOD_REFERENCES_VISIBLE ) );

    return guide;
}
예제 #13
0
void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
{
    int layer = GetActiveLayer();
    wxString msg;

    msg.Printf( _( "Clear layer %d?" ), layer + 1 );

    if( query && !IsOK( this, msg ) )
        return;

    SetCurItem( NULL );

    GetImagesList()->DeleteImage( layer );

    ReFillLayerWidget();
    syncLayerBox();
    m_canvas->Refresh();
}
bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
{
    int copperlayercnt = GetBoard()->GetCopperLayerCount( );
    LAYER_ID currLayer = GetActiveLayer();

    if( !GetDesignSettings().m_MicroViasAllowed )
        return false;   // Obvious..

    if( copperlayercnt < 4 )
        return false;   // Only on multilayer boards..

    if( ( currLayer == B_Cu )
       || ( currLayer == F_Cu )
       || ( currLayer == copperlayercnt - 2 )
       || ( currLayer == In1_Cu ) )
        return true;

    return false;
}
예제 #15
0
TRACK * PCB_EDIT_FRAME::OnHotkeyBeginRoute( wxDC* aDC )
{
    if( !IsCopperLayer( GetActiveLayer() ) )
        return NULL;

    bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();

    // Ensure the track tool is active
    if( GetToolId() != ID_TRACK_BUTT && !itemCurrentlyEdited )
    {
        wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
        cmd.SetEventObject( this );
        cmd.SetId( ID_TRACK_BUTT );
        GetEventHandler()->ProcessEvent( cmd );
    }

    if( GetToolId() != ID_TRACK_BUTT )
        return NULL;

    TRACK* track = NULL;

    if( !itemCurrentlyEdited )     // no track in progress:
    {
        track = Begin_Route( NULL, aDC );
        SetCurItem( track );

        if( track )
            m_canvas->SetAutoPanRequest( true );
    }
    else if( GetCurItem()->IsNew() )
    {
        track = Begin_Route( (TRACK*) GetCurItem(), aDC );

        // SetCurItem() must not write to the msg panel
        // because a track info is displayed while moving the mouse cursor
        if( track )      // A new segment was created
            SetCurItem( track, false );

        m_canvas->SetAutoPanRequest( true );
    }

    return track;
}
예제 #16
0
파일: prpslyrs.cpp 프로젝트: vata/xarino
BOOL LayerPropertiesTab::ShowDetails()
{
	String_256 LayerID;

	Layer* pLayer = GetActiveLayer();
	if (pLayer != NULL)
	{
		LayerID = pLayer->GetLayerID();

//		pPropertiesDlg->SetBoolGadgetSelected(_R(IDC_LAYERTAB_VISIBLE),pLayer->IsVisible());
//		pPropertiesDlg->SetBoolGadgetSelected(_R(IDC_LAYERTAB_EDITABLE),!pLayer->IsLocked());
		pPropertiesDlg->SetBoolGadgetSelected(_R(IDC_LAYERTAB_VISIBLE),pLayer->GetVisibleFlagState());
		pPropertiesDlg->SetBoolGadgetSelected(_R(IDC_LAYERTAB_EDITABLE),!pLayer->GetLockedFlagState());
	}

	pPropertiesDlg->SetStringGadgetValue(_R(IDC_LAYERTAB_NAME), LayerID);

	ChangeControlStatus(!GreyStatus);

	return TRUE;
}
예제 #17
0
파일: prpslyrs.cpp 프로젝트: vata/xarino
BOOL LayerPropertiesTab::UpdateApplyState()
{
	BOOL OldApplyNowState = LayerPropertiesTab::GetApplyNowState();

	Layer* pLayer = GetActiveLayer();

	if (pLayer != NULL)
		LayerPropertiesTab::SetApplyNowState(HavePropertiesChanged(pLayer));

	BOOL NewApplyNowState = LayerPropertiesTab::GetApplyNowState();

	if (OldApplyNowState != NewApplyNowState)
	{
		if (NewApplyNowState)
			LayerPropertiesTab::UngreyApplyNow();
		else
			LayerPropertiesTab::GreyApplyNow();
	}

	return TRUE;
}
예제 #18
0
GENERAL_COLLECTORS_GUIDE PCB_BASE_FRAME::GetCollectorsGuide()
{
    GENERAL_COLLECTORS_GUIDE guide( m_Pcb->GetVisibleLayers(), GetActiveLayer(),
                                    GetGalCanvas()->GetView() );

    // account for the globals
    guide.SetIgnoreMTextsMarkedNoShow( ! m_Pcb->IsElementVisible( LAYER_MOD_TEXT_INVISIBLE ) );
    guide.SetIgnoreMTextsOnBack( ! m_Pcb->IsElementVisible( LAYER_MOD_TEXT_BK ) );
    guide.SetIgnoreMTextsOnFront( ! m_Pcb->IsElementVisible( LAYER_MOD_TEXT_FR ) );
    guide.SetIgnoreModulesOnBack( ! m_Pcb->IsElementVisible( LAYER_MOD_BK ) );
    guide.SetIgnoreModulesOnFront( ! m_Pcb->IsElementVisible( LAYER_MOD_FR ) );
    guide.SetIgnorePadsOnBack( ! m_Pcb->IsElementVisible( LAYER_PAD_BK ) );
    guide.SetIgnorePadsOnFront( ! m_Pcb->IsElementVisible( LAYER_PAD_FR ) );
    guide.SetIgnoreThroughHolePads( ! m_Pcb->IsElementVisible( LAYER_PADS_TH ) );
    guide.SetIgnoreModulesVals( ! m_Pcb->IsElementVisible( LAYER_MOD_VALUES ) );
    guide.SetIgnoreModulesRefs( ! m_Pcb->IsElementVisible( LAYER_MOD_REFERENCES ) );
    guide.SetIgnoreThroughVias( ! m_Pcb->IsElementVisible( LAYER_VIA_THROUGH ) );
    guide.SetIgnoreBlindBuriedVias( ! m_Pcb->IsElementVisible( LAYER_VIA_BBLIND ) );
    guide.SetIgnoreMicroVias( ! m_Pcb->IsElementVisible( LAYER_VIA_MICROVIA ) );
    guide.SetIgnoreTracks( ! m_Pcb->IsElementVisible( LAYER_TRACKS ) );

    return guide;
}
예제 #19
0
//________________________________________________________________
Bool_t KVFAZIADetector::Fired(Option_t *)
{
    // Returns kTRUE if detector was hit (fired) in an event
    //
    // The actual meaning of hit/fired depends on the context and the option string opt.
    //
    // If the detector is in "simulation mode", i.e. if SetSimMode(kTRUE) has been called,
    // this method returns kTRUE if the calculated energy loss in the active layer is > 0.
    //
    // In "experimental mode" (i.e. IsSimMode() returns kFALSE), depending on the option:
    //
 	 //Info("Fired","Appel - %s",GetName());	
    if (!IsDetecting()) return kFALSE; //detector not working, no answer at all
    if (IsSimMode()) return (GetActiveLayer()->GetEnergyLoss()>0.); // simulation mode: detector fired if energy lost in active layer
	 KVSignal* sig;	
	 if (fSignals){
    	TIter next(fSignals);
    	while ( (sig = (KVSignal* )next()) )
    	{
    		if (sig->GetN()>0){
      		if (!strcmp(sig->GetTitle(),"Charge") && sig->GetRawAmplitude()>20){
         		return kTRUE;
         	}
         	else{
      		}
      	}
         else{
         	Warning("Fired","%s has empty signal %s",GetName(),sig->GetName());
         }
      }
    }
    else{
    	Warning("Fired","%s : No signal attached to this detector ...",GetName());
      return kFALSE;
    }
    return kFALSE;
}
예제 #20
0
파일: files.cpp 프로젝트: cpavlina/kicad
bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
{
    wxString   filetypes;
    wxArrayString filenamesList;
    wxFileName filename = aFullFileName;
    wxString currentPath;

    if( !filename.IsOk() )
    {
        /* Standard gerber filetypes
         * (See http://en.wikipedia.org/wiki/Gerber_File)
         * the .gbr (.pho in legacy files) extension is the default used in Pcbnew
         * However there are a lot of other extensions used for gerber files
         * Because the first letter is usually g, we accept g* as extension
         * (Mainly internal copper layers do not have specific extension,
         *  and filenames are like *.g1, *.g2 *.gb1 ...).
         * Now (2014) Ucamco (the company which manages the Gerber format) encourages
         * use of .gbr only and the Gerber X2 file format.
         */
        filetypes = _( "Gerber files (.g* .lgr .pho)" );
        filetypes << wxT("|");
        filetypes += wxT("*.g*;*.G*;*.pho;*.PHO" );
        filetypes << wxT("|");

        /* Special gerber filetypes */
        filetypes += _( "Top layer (*.GTL)|*.GTL;*.gtl|" );
        filetypes += _( "Bottom layer (*.GBL)|*.GBL;*.gbl|" );
        filetypes += _( "Bottom solder resist (*.GBS)|*.GBS;*.gbs|" );
        filetypes += _( "Top solder resist (*.GTS)|*.GTS;*.gts|" );
        filetypes += _( "Bottom overlay (*.GBO)|*.GBO;*.gbo|" );
        filetypes += _( "Top overlay (*.GTO)|*.GTO;*.gto|" );
        filetypes += _( "Bottom paste (*.GBP)|*.GBP;*.gbp|" );
        filetypes += _( "Top paste (*.GTP)|*.GTP;*.gtp|" );
        filetypes += _( "Keep-out layer (*.GKO)|*.GKO;*.gko|" );
        filetypes += _( "Mechanical layers (*.GMx)|*.GM1;*.gm1;*.GM2;*.gm2;*.GM3;*.gm3|" );
        filetypes += _( "Top Pad Master (*.GPT)|*.GPT;*.gpt|" );
        filetypes += _( "Bottom Pad Master (*.GPB)|*.GPB;*.gpb|" );

        // All filetypes
        filetypes += AllFilesWildcard;

        // Use the current working directory if the file name path does not exist.
        if( filename.DirExists() )
            currentPath = filename.GetPath();
        else
        {
            currentPath = m_mruPath;

            // On wxWidgets 3.1 (bug?) the path in wxFileDialog is ignored when
            // finishing by the dir separator. Remove it if any:
            if( currentPath.EndsWith( '\\' ) || currentPath.EndsWith( '/' ) )
                currentPath.RemoveLast();
        }

        wxFileDialog dlg( this, _( "Open Gerber File" ),
                          currentPath,
                          filename.GetFullName(),
                          filetypes,
                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );

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

        dlg.GetPaths( filenamesList );

        // @todo Take a closer look at the CWD switching here.  The current working directory
        // gets changed by wxFileDialog because the wxFD_CHANGE_DIR flag is set.  Is this the
        // appropriate behavior?  The current working directory is not returned to the previous
        // value so this may be an issue elsewhere.
        currentPath = wxGetCwd();
        m_mruPath = currentPath;
    }
    else
    {
        filenamesList.Add( aFullFileName );
        currentPath = filename.GetPath();
        m_mruPath = currentPath;
    }

    // Set the busy cursor
    wxBusyCursor wait;

    // Read gerber files: each file is loaded on a new GerbView layer
    bool success = true;
    int layer = GetActiveLayer();

    // Manage errors when loading files
    wxString msg;
    WX_STRING_REPORTER reporter( &msg );

    for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
    {
        filename = filenamesList[ii];

        if( !filename.IsAbsolute() )
            filename.SetPath( currentPath );

        m_lastFileName = filename.GetFullPath();

        SetActiveLayer( layer, false );

        if( Read_GERBER_File( filename.GetFullPath() ) )
        {
            UpdateFileHistory( m_lastFileName );

            layer = getNextAvailableLayer( layer );

            if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 )
            {
                success = false;
                reporter.Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR );

                // Report the name of not loaded files:
                ii += 1;
                while( ii < filenamesList.GetCount() )
                {
                    filename = filenamesList[ii++];
                    wxString txt;
                    txt.Printf( MSG_NOT_LOADED,
                                GetChars( filename.GetFullName() ) );
                    reporter.Report( txt, REPORTER::RPT_ERROR );
                }
                break;
            }

            SetActiveLayer( layer, false );
        }
    }

    if( !success )
    {
        HTML_MESSAGE_BOX mbox( this, _( "Errors" ) );
        mbox.ListSet( msg );
        mbox.ShowModal();
    }

    Zoom_Automatique( false );

    // Synchronize layers tools with actual active layer:
    ReFillLayerWidget();
    SetActiveLayer( GetActiveLayer() );
    m_LayersManager->UpdateLayerIcons();
    syncLayerBox();
    return success;
}
예제 #21
0
bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition,
                               EDA_ITEM* aItem )
{
    if( aHotkeyCode == 0 )
        return false;

    bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
    MODULE* module = NULL;
    int evt_type = 0;       //Used to post a wxCommandEvent on demand
    PCB_SCREEN* screen = GetScreen();
    auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();

    /* Convert lower to upper case
     * (the usual toupper function has problem with non ascii codes like function keys
     */
    if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') )
        aHotkeyCode += 'A' - 'a';

    EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, common_Hotkey_List );

    if( HK_Descr == NULL )
        HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, board_edit_Hotkey_List );

    if( HK_Descr == NULL )
        return false;

    int hk_id = HK_Descr->m_Idcommand;

    // Create a wxCommandEvent that will be posted in some hot keys functions
    wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
    cmd.SetEventObject( this );

    LAYER_NUM  ll;

    switch( hk_id )
    {
    default:
    case HK_NOT_FOUND:
        return false;

    case HK_LEFT_CLICK:
        OnLeftClick( aDC, aPosition );
        break;

    case HK_LEFT_DCLICK:    // Simulate a double left click: generate 2 events
        OnLeftClick( aDC, aPosition );
        OnLeftDClick( aDC, aPosition );
        break;

    case HK_SWITCH_TRACK_WIDTH_TO_NEXT:
        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        if( GetDesignSettings().GetTrackWidthIndex() < GetDesignSettings().m_TrackWidthList.size() - 1 )
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() + 1 );
        else
            GetDesignSettings().SetTrackWidthIndex( 0 );

        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        break;

    case HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS:
        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        if( GetDesignSettings().GetTrackWidthIndex() <= 0 )
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().m_TrackWidthList.size() -1 );
        else
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() - 1 );

        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        break;

    case HK_SWITCH_GRID_TO_FASTGRID1:
        SetFastGrid1();
        break;

    case HK_SWITCH_GRID_TO_FASTGRID2:
        SetFastGrid2();
        break;

    case HK_SWITCH_GRID_TO_NEXT:
        evt_type = ID_POPUP_GRID_NEXT;
        break;

    case HK_SWITCH_GRID_TO_PREVIOUS:
        evt_type = ID_POPUP_GRID_PREV;
        break;

    case HK_SWITCH_LAYER_TO_PREVIOUS:
        ll = GetActiveLayer();

        if( !IsCopperLayer( ll ) )
            break;

        if( ll == F_Cu )
            ll = B_Cu;
        else if( ll == B_Cu )
            ll = ToLAYER_ID( GetBoard()->GetCopperLayerCount() - 2 );
        else
            ll = ll - 1;

        SwitchLayer( aDC, ToLAYER_ID( ll ) );
        break;

    case HK_SWITCH_LAYER_TO_NEXT:
        ll = GetActiveLayer();

        if( !IsCopperLayer( ll ) )
            break;

        if( ll == B_Cu )
            ll = F_Cu;
        else if( ++ll >= GetBoard()->GetCopperLayerCount() - 1 )
            ll = B_Cu;

        SwitchLayer( aDC, ToLAYER_ID( ll ) );
        break;

    case HK_SWITCH_LAYER_TO_COMPONENT:
        SwitchLayer( aDC, F_Cu );
        break;

    case HK_SWITCH_LAYER_TO_COPPER:
        SwitchLayer( aDC, B_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER1:
        SwitchLayer( aDC, In1_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER2:
        SwitchLayer( aDC, In2_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER3:
        SwitchLayer( aDC, In3_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER4:
        SwitchLayer( aDC, In4_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER5:
        SwitchLayer( aDC, In5_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER6:
        SwitchLayer( aDC, In6_Cu );
        break;

    case HK_HELP: // Display Current hotkey list
        DisplayHotkeyList( this, g_Board_Editor_Hotkeys_Descr );
        break;

    case HK_PREFERENCES:
        evt_type = wxID_PREFERENCES;
        break;

    case HK_ZOOM_IN:
        evt_type = ID_KEY_ZOOM_IN;
        break;

    case HK_ZOOM_OUT:
        evt_type = ID_KEY_ZOOM_OUT;
        break;

    case HK_ZOOM_REDRAW:
        evt_type = ID_ZOOM_REDRAW;
        break;

    case HK_ZOOM_AUTO:
        evt_type = ID_ZOOM_PAGE;
        break;

    case HK_ZOOM_CENTER:
        evt_type = ID_POPUP_ZOOM_CENTER;
        break;

    case HK_ZOOM_SELECTION:
        evt_type = ID_ZOOM_SELECTION;
        break;

    case HK_ADD_MODULE:
        evt_type = ID_PCB_MODULE_BUTT;
        break;

    case HK_UNDO:
    case HK_REDO:
        if( !itemCurrentlyEdited )
        {
            wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
            wxPostEvent( this, event );
        }

        break;

    case HK_RESET_LOCAL_COORD:  // Set the relative coord
        GetScreen()->m_O_Curseur = GetCrossHairPosition();
        break;

    case HK_SET_GRID_ORIGIN:
        PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
                                       new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ),
                                       GetCrossHairPosition() );
        m_canvas->Refresh();
        break;

    case HK_RESET_GRID_ORIGIN:
        PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
                                       new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ),
                                       wxPoint( 0, 0 ) );
        m_canvas->Refresh();
        break;

    case HK_SWITCH_UNITS:
        evt_type = (GetUserUnits() == INCHES) ?
                    ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH;
        break;

    case HK_SWITCH_TRACK_DISPLAY_MODE:
        displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
        m_canvas->Refresh();
        break;

    case HK_DELETE:
        OnHotkeyDeleteItem( aDC );
        break;

    case HK_BACK_SPACE:
        if( IsCopperLayer( GetActiveLayer() ) )
        {
            if( !itemCurrentlyEdited )
            {
                // no track is currently being edited - select a segment and remove it.
                // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay()
                // so it can restrict its search to specific item types.
                BOARD_ITEM * item = PcbGeneralLocateAndDisplay();

                // don't let backspace delete modules!!
                if( item && item->IsTrack() )
                {
                    Delete_Segment( aDC, (TRACK*) item );
                    SetCurItem( NULL );
                }

                OnModify();
            }
            else if( GetCurItem()->IsTrack() )
            {
                // then an element is being edited - remove the last segment.
                // simple lines for debugger:
                TRACK* track = (TRACK*) GetCurItem();
                track = Delete_Segment( aDC, track );
                SetCurItem( track );
                OnModify();
            }
        }

        break;

    case HK_GET_AND_MOVE_FOOTPRINT:
        if( !itemCurrentlyEdited )
            evt_type = ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST;

        break;

    case HK_FIND_ITEM:
        if( !itemCurrentlyEdited )
            evt_type = ID_FIND_ITEMS;

        break;

    case HK_OPEN:
        if( !itemCurrentlyEdited )
            evt_type = ID_LOAD_FILE ;

        break;

    case HK_SAVE:
        if( !itemCurrentlyEdited )
            evt_type = ID_SAVE_BOARD;

        break;

    case HK_ADD_MICROVIA: // Place a micro via if a track is in progress
        if( GetToolId() != ID_TRACK_BUTT )
            return true;

        if( !itemCurrentlyEdited )                         // no track in progress: nothing to do
            break;

        if( GetCurItem()->Type() != PCB_TRACE_T )           // Should not occur
            return true;

        if( !GetCurItem()->IsNew() )
            return true;

        // place micro via and switch layer
        if( IsMicroViaAcceptable() )
            evt_type = ID_POPUP_PCB_PLACE_MICROVIA;

        break;

    case HK_ADD_BLIND_BURIED_VIA:
    case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress
        if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed &&
            hk_id == HK_ADD_BLIND_BURIED_VIA  )
            GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
        else
            GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH;

        if( !itemCurrentlyEdited ) // no track in progress: switch layer only
        {
            Other_Layer_Route( NULL, aDC );
            if( displ_opts->m_ContrastModeDisplay )
                m_canvas->Refresh();
            break;
        }

        if( GetToolId() != ID_TRACK_BUTT )
            return true;

        if( GetCurItem()->Type() != PCB_TRACE_T )
            return true;

        if( !GetCurItem()->IsNew() )
            return true;

        evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
            ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA : ID_POPUP_PCB_PLACE_THROUGH_VIA;
        break;

    case HK_SEL_LAYER_AND_ADD_THROUGH_VIA:
    case HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA:
        if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
            GetCurItem()->Type() != PCB_TRACE_T )
            break;

        evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
            ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA :
            ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA;
        break;

    case HK_SWITCH_TRACK_POSTURE:
        /* change the position of initial segment when creating new tracks
         * switch from _/  to -\ .
         */
        evt_type = ID_POPUP_PCB_SWITCH_TRACK_POSTURE ;
        break;

    case HK_DRAG_TRACK_KEEP_SLOPE:
        OnHotkeyMoveItem( HK_DRAG_TRACK_KEEP_SLOPE );
        break;

    case HK_PLACE_ITEM:
        OnHotkeyPlaceItem( aDC );
        break;

    case HK_ADD_NEW_TRACK: // Start new track, if possible
        OnHotkeyBeginRoute( aDC );
        break;

    case HK_EDIT_ITEM:      // Edit board item
        OnHotkeyEditItem( HK_EDIT_ITEM );
        break;

    case HK_EDIT_MODULE_WITH_MODEDIT:      // Edit module with module editor
        OnHotkeyEditItem( HK_EDIT_MODULE_WITH_MODEDIT );
        break;

    case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
        // get any module, locked or not locked and toggle its locked status
        if( !itemCurrentlyEdited )
        {
            wxPoint pos = RefPos( true );
            module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
        }
        else if( GetCurItem()->Type() == PCB_MODULE_T )
        {
            module = (MODULE*) GetCurItem();
        }

        if( module )
        {
            SetCurItem( module );
            module->SetLocked( !module->IsLocked() );
            OnModify();
            SetMsgPanel( module );
        }
        break;

    case HK_DRAG_ITEM:    // Start drag module or track segment
        OnHotkeyMoveItem( HK_DRAG_ITEM );
        break;

    case HK_MOVE_ITEM:                  // Start move item
        OnHotkeyMoveItem( HK_MOVE_ITEM );
        break;

    case HK_COPY_ITEM:
        evt_type = OnHotkeyCopyItem();
        break;

    case HK_ROTATE_ITEM:        // Rotation
        OnHotkeyRotateItem( HK_ROTATE_ITEM );
        break;

    case HK_FLIP_ITEM:
        OnHotkeyFlipItem( HK_FLIP_ITEM );
        break;

    case HK_MOVE_ITEM_EXACT:
    case HK_DUPLICATE_ITEM:
    case HK_DUPLICATE_ITEM_AND_INCREMENT:
    case HK_CREATE_ARRAY:
        OnHotkeyDuplicateOrArrayItem( HK_Descr->m_Idcommand );
        break;

    case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
        displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
        m_canvas->Refresh();
        break;

    case HK_CANVAS_CAIRO:
        evt_type = ID_MENU_CANVAS_CAIRO;
        break;

    case HK_CANVAS_OPENGL:
        evt_type = ID_MENU_CANVAS_OPENGL;
        break;

    case HK_CANVAS_LEGACY:
        evt_type = ID_MENU_CANVAS_LEGACY;
        break;

    case HK_ZONE_FILL_OR_REFILL:
        evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
        break;

    case HK_ZONE_REMOVE_FILLED:
        evt_type = ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES;
        break;
    }

    if( evt_type != 0 )
    {
        wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
        evt.SetEventObject( this );
        evt.SetId( evt_type );
        GetEventHandler()->ProcessEvent( evt );
    }

    return true;
}
예제 #22
0
bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC )
{
    BOARD_ITEM* item = GetCurItem();
    bool ItemFree = (item == NULL) || (item->GetFlags() == 0);

    switch( GetToolId() )
    {
    case ID_TRACK_BUTT:
        if( !IsCopperLayer ( GetActiveLayer() ) )
            return false;

        if( ItemFree )
        {
            item = PcbGeneralLocateAndDisplay();

            if( item && !item->IsTrack() )
                return false;

            Delete_Track( aDC, (TRACK*) item );
        }
        else if( item->IsTrack( ) )
        {
            // simple lines for debugger:
            TRACK* track = (TRACK*) item;
            track = Delete_Segment( aDC, track );
            SetCurItem( track );
            OnModify();
            return true;
        }
        break;

    case ID_PCB_MODULE_BUTT:
        if( ItemFree )
        {
            wxPoint pos    = RefPos( false );
            MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false );

            if( module == NULL || module->IsLocked() )
                return false;

            RemoveStruct( module, aDC );
        }
        else
            return false;
        break;

    default:
        if( ItemFree )
        {
            item = PcbGeneralLocateAndDisplay();

            // Shouldn't there be a check for locked tracks and vias here?
            if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) )
                return false;

            RemoveStruct( item, aDC );
        }
        else
            return false;
    }

    OnModify();
    SetCurItem( NULL );
    return true;
}
void PCB_EDIT_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
{
    m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
}
예제 #24
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" ) );
    }
}
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
{
    unsigned    itmp;

    if( aTrack == NULL )
    {
        if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP )
            SetActiveLayer( GetScreen()->m_Route_Layer_TOP );
        else
            SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM );

        UpdateStatusBar();
        return true;
    }

    // Avoid more than one via on the current location:
    if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(),
                                      g_CurrentTrackSegment->GetLayer() ) )
        return false;

    for( TRACK* segm = g_FirstTrackSegment;  segm;  segm = segm->Next() )
    {
        if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() )
            return false;
    }

    // Is the current segment Ok (no DRC error) ?
    if( g_Drc_On )
    {
        if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
            // DRC error, the change layer is not made
            return false;

        // Handle 2 segments.
        if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() )
        {
            if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
                return false;
        }
    }

    /* Save current state before placing a via.
     * If the via cannot be placed this current state will be reused
     */
    itmp = g_CurrentTrackList.GetCount();
    Begin_Route( g_CurrentTrackSegment, DC );

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

    // create the via
    VIA* via = new VIA( GetBoard() );
    via->SetFlags( IS_NEW );
    via->SetViaType( GetDesignSettings().m_CurrentViaType );
    via->SetNetCode( GetBoard()->GetHighLightNetCode() );
    via->SetPosition( g_CurrentTrackSegment->GetEnd() );

    // for microvias, the size and hole will be changed later.
    via->SetWidth( GetDesignSettings().GetCurrentViaSize());
    via->SetDrill( GetDesignSettings().GetCurrentViaDrill() );

    // Usual via is from copper to component.
    // layer pair is B_Cu and F_Cu.
    via->SetLayerPair( B_Cu, F_Cu );

    LAYER_ID first_layer = GetActiveLayer();
    LAYER_ID last_layer;

    // prepare switch to new active layer:
    if( first_layer != GetScreen()->m_Route_Layer_TOP )
        last_layer = GetScreen()->m_Route_Layer_TOP;
    else
        last_layer = GetScreen()->m_Route_Layer_BOTTOM;

    // Adjust the actual via layer pair
    switch( via->GetViaType() )
    {
    case VIA_BLIND_BURIED:
        via->SetLayerPair( first_layer, last_layer );
        break;

    case VIA_MICROVIA:  // from external to the near neighbor inner layer
        {
            LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) );

            if( first_layer == B_Cu )
                last_layer = last_inner_layer;
            else if( first_layer == F_Cu )
                last_layer = In1_Cu;
            else if( first_layer == last_inner_layer )
                last_layer = B_Cu;
            else if( first_layer == In1_Cu )
                last_layer = F_Cu;
            // else error: will be removed later
            via->SetLayerPair( first_layer, last_layer );

            // Update diameter and hole size, which where set previously
            // for normal vias
            NETINFO_ITEM* net = via->GetNet();
            via->SetWidth( net->GetMicroViaSize() );
            via->SetDrill( net->GetMicroViaDrillSize() );
        }
        break;

    default:
        break;
    }

    if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) )
    {
        // DRC fault: the Via cannot be placed here ...
        delete via;

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

        // delete the track(s) added in Begin_Route()
        while( g_CurrentTrackList.GetCount() > itmp )
        {
            Delete_Segment( DC, g_CurrentTrackSegment );
        }

         SetCurItem( g_CurrentTrackSegment, false );

        // Refresh DRC diag, erased by previous calls
        if( m_drc->GetCurrentMarker() )
            SetMsgPanel( m_drc->GetCurrentMarker() );

        return false;
    }

    SetActiveLayer( last_layer );

    TRACK*  lastNonVia = g_CurrentTrackSegment;

    /* A new via was created. It was Ok.
     */
    g_CurrentTrackList.PushBack( via );

    /* The via is now in linked list and we need a new track segment
     * after the via, starting at via location.
     * it will become the new current segment (from via to the mouse cursor)
     */

    TRACK* track = (TRACK*)lastNonVia->Clone();

    /* the above creates a new segment from the last entered segment, with the
     * current width, flags, netcode, etc... values.
     * layer, start and end point are not correct,
     * and will be modified next
     */

    // set the layer to the new value
    track->SetLayer( GetActiveLayer() );

    /* the start point is the via position and the end point is the cursor
     * which also is on the via (will change when moving mouse)
     */
    track->SetEnd( via->GetStart() );
    track->SetStart( via->GetStart() );

    g_CurrentTrackList.PushBack( track );

    if( g_TwoSegmentTrackBuild )
    {
        // Create a second segment (we must have 2 track segments to adjust)
        g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
    }

    m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
    SetMsgPanel( via );
    UpdateStatusBar();

    return true;
}
bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
{
    wxString msg;
    int layerId = GetActiveLayer();      // current layer used in GerbView
    GERBER_FILE_IMAGE_LIST* images = GetGerberLayout()->GetImagesList();
    auto gerber_layer = images->GetGbrImage( layerId );
    auto drill_layer = dynamic_cast<EXCELLON_IMAGE*>( gerber_layer );

    if( gerber_layer && !drill_layer )
    {
        // The active layer contains old gerber data we have to clear
        Erase_Current_DrawLayer( false );
    }

    if( drill_layer == nullptr )
    {
        drill_layer = new EXCELLON_IMAGE( layerId );
        layerId = images->AddGbrImage( drill_layer, layerId );
    }

    if( layerId < 0 )
    {
        DisplayError( this, _( "No room to load file" ) );
        return false;
    }

    // Read the Excellon drill file:
    bool success = drill_layer->LoadFile( aFullFileName );

    if( !success )
    {
        msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) );
        DisplayError( this, msg );
        return false;
    }

    // Display errors list
    if( drill_layer->GetMessages().size() > 0 )
    {
        HTML_MESSAGE_BOX dlg( this, _( "Error reading EXCELLON drill file" ) );
        dlg.ListSet( drill_layer->GetMessages() );
        dlg.ShowModal();
    }

    if( success )
    {
        EDA_DRAW_PANEL_GAL* canvas = GetGalCanvas();

        if( canvas )
        {
            KIGFX::VIEW* view = canvas->GetView();

            for( GERBER_DRAW_ITEM* item = drill_layer->GetItemsList(); item; item = item->Next() )
            {
                view->Add( (KIGFX::VIEW_ITEM*) item );
            }
        }
    }

    return success;
}
예제 #27
0
TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
{
    int current_net_code;

    if( aTrack == NULL )
        return NULL;

    if( aTrack->IsNew() )  // Trace in progress, erase the last segment
    {
        if( g_CurrentTrackList.GetCount() > 0 )
        {
            LAYER_NUM previous_layer = GetActiveLayer();

            DBG( g_CurrentTrackList.VerifyListIntegrity(); )

            // Delete the current trace
            ShowNewTrackWhenMovingCursor( m_canvas, DC, wxDefaultPosition, false );

            // delete the most recently entered
            delete g_CurrentTrackList.PopBack();

            if( g_TwoSegmentTrackBuild )
            {
                // if in 2 track mode, and the next most recent is a segment
                // not a via, and the one previous to that is a via, then
                // delete up to the via.
                if( g_CurrentTrackList.GetCount() >= 2
                    && g_CurrentTrackSegment->Type() != PCB_VIA_T
                    && g_CurrentTrackSegment->Back()->Type() == PCB_VIA_T )
                {
                    delete g_CurrentTrackList.PopBack();
                }
            }

            while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() == PCB_VIA_T )
            {
                delete g_CurrentTrackList.PopBack();

                if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() != PCB_VIA_T )
                    previous_layer = g_CurrentTrackSegment->GetLayer();
            }

            // Correct active layer which could change if a via
            // has been erased
            SetActiveLayer( previous_layer );

            UpdateStatusBar();

            if( g_TwoSegmentTrackBuild )   // We must have 2 segments or more, or 0
            {
                if( g_CurrentTrackList.GetCount() == 1
                    && g_CurrentTrackSegment->Type() != PCB_VIA_T )
                {
                    delete g_CurrentTrackList.PopBack();
                }
            }

            if( g_CurrentTrackList.GetCount() == 0 )
            {
                m_canvas->SetMouseCapture( NULL, NULL );

                if( GetBoard()->IsHighLightNetON() )
                    HighLight( DC );

                SetCurItem( NULL );
                return NULL;
            }
            else
            {
                if( m_canvas->IsMouseCaptured() )
                    m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );

                return g_CurrentTrackSegment;
            }
        }
예제 #28
0
파일: files.cpp 프로젝트: cpavlina/kicad
bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aReporter )
{
    wxString msg;

    // Extract the path of aFullFileName. We use it to store temporary files
    wxFileName fn( aFullFileName );
    wxString unzipDir = fn.GetPath();

    wxFFileInputStream zipFile( aFullFileName );

    if( !zipFile.IsOk() )
    {
        if( aReporter )
        {
            msg.Printf( _( "Zip file \"%s\" cannot be opened" ), GetChars( aFullFileName ) );
            aReporter->Report( msg, REPORTER::RPT_ERROR );
        }

        return false;
    }

    // Update the list of recent zip files.
    UpdateFileHistory( aFullFileName, &m_zipFileHistory );

    // The unzipped file in only a temporary file. Give it a filename
    // which cannot conflict with an usual filename.
    // TODO: make Read_GERBER_File() and Read_EXCELLON_File() able to
    // accept a stream, and avoid using a temp file.
    wxFileName temp_fn( "$tempfile.tmp" );
    temp_fn.MakeAbsolute( unzipDir );
    wxString unzipped_tempfile = temp_fn.GetFullPath();


    bool success = true;
    wxZipInputStream zipArchive( zipFile );
    wxZipEntry* entry;
    bool reported_no_more_layer = false;

    while( ( entry = zipArchive.GetNextEntry() ) )
    {
        wxString fname = entry->GetName();
        wxFileName uzfn = fname;
        wxString curr_ext = uzfn.GetExt().Lower();

        // The archive contains Gerber and/or Excellon drill files. Use the right loader.
        // However it can contain a few other files (reports, pdf files...),
        // which will be skipped.
        // Gerber files ext is usually "gbr", but can be also an other value, starting by "g"
        // old gerber files ext from kicad is .pho
        // drill files do not have a well defined ext
        // It is .drl in kicad, but .txt in Altium for instance
        // Allows only .drl for drill files.
        if( curr_ext[0] != 'g' && curr_ext != "pho" && curr_ext != "drl" )
        {
            if( aReporter )
            {
                msg.Printf( _( "Info: skip file <i>\"%s\"</i> (unknown type)\n" ),
                            GetChars( entry->GetName() ) );
                aReporter->Report( msg, REPORTER::RPT_WARNING );
            }

            continue;
        }

        int layer = GetActiveLayer();

        if( layer == NO_AVAILABLE_LAYERS )
        {
            success = false;

            if( aReporter )
            {
                if( !reported_no_more_layer )
                    aReporter->Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR );

                reported_no_more_layer = true;

                // Report the name of not loaded files:
                msg.Printf( MSG_NOT_LOADED, GetChars( entry->GetName() ) );
                aReporter->Report( msg, REPORTER::RPT_ERROR );
            }

            delete entry;
            continue;
        }

        // Create the unzipped temporary file:
        {
            wxFFileOutputStream temporary_ofile( unzipped_tempfile );

            if( temporary_ofile.Ok() )
                temporary_ofile.Write( zipArchive );
            else
            {
                success = false;

                if( aReporter )
                {
                    msg.Printf( _( "<b>Unable to create temporary file \"%s\"</b>\n"),
                                GetChars( unzipped_tempfile ) );
                    aReporter->Report( msg, REPORTER::RPT_ERROR );
                }
            }
        }

        bool read_ok = true;

        if( curr_ext[0] == 'g' || curr_ext == "pho" )
        {
            // Read gerber files: each file is loaded on a new GerbView layer
            read_ok = Read_GERBER_File( unzipped_tempfile );
        }
        else // if( curr_ext == "drl" )
        {
            read_ok = Read_EXCELLON_File( unzipped_tempfile );
        }

        delete entry;

        // The unzipped file is only a temporary file, delete it.
        wxRemoveFile( unzipped_tempfile );

        if( !read_ok )
        {
            success = false;

            if( aReporter )
            {
                msg.Printf( _("<b>unzipped file %s read error</b>\n"),
                            GetChars( unzipped_tempfile ) );
                aReporter->Report( msg, REPORTER::RPT_ERROR );
            }
        }
        else
        {
            GERBER_FILE_IMAGE* gerber_image = GetGbrImage( layer );

            if( gerber_image )
                gerber_image->m_FileName = fname;

            layer = getNextAvailableLayer( layer );
            SetActiveLayer( layer, false );
        }
    }

    return success;
}
예제 #29
0
파일: files.cpp 프로젝트: cpavlina/kicad
bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
{
    wxString   filetypes;
    wxArrayString filenamesList;
    wxFileName filename = aFullFileName;
    wxString currentPath;

    if( !filename.IsOk() )
    {
        filetypes = DrillFileWildcard();
        filetypes << wxT( "|" );

        /* All filetypes */
        filetypes += wxGetTranslation( AllFilesWildcard );

        /* Use the current working directory if the file name path does not exist. */
        if( filename.DirExists() )
            currentPath = filename.GetPath();
        else
            currentPath = m_mruPath;

        wxFileDialog dlg( this, _( "Open Drill File" ),
                          currentPath, filename.GetFullName(), filetypes,
                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );

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

        dlg.GetPaths( filenamesList );
        currentPath = wxGetCwd();
        m_mruPath = currentPath;
    }
    else
    {
        filenamesList.Add( aFullFileName );
        currentPath = filename.GetPath();
        m_mruPath = currentPath;
    }

    // Read Excellon drill files: each file is loaded on a new GerbView layer
    bool success = true;
    int layer = GetActiveLayer();

    // Manage errors when loading files
    wxString msg;
    WX_STRING_REPORTER reporter( &msg );

    for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
    {
        filename = filenamesList[ii];

        if( !filename.IsAbsolute() )
            filename.SetPath( currentPath );

        m_lastFileName = filename.GetFullPath();

        SetActiveLayer( layer, false );

        if( Read_EXCELLON_File( filename.GetFullPath() ) )
        {
            // Update the list of recent drill files.
            UpdateFileHistory( filename.GetFullPath(),  &m_drillFileHistory );

            layer = getNextAvailableLayer( layer );

            if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 )
            {
                success = false;
                reporter.Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR );

                // Report the name of not loaded files:
                ii += 1;
                while( ii < filenamesList.GetCount() )
                {
                    filename = filenamesList[ii++];
                    wxString txt;
                    txt.Printf( MSG_NOT_LOADED,
                                GetChars( filename.GetFullName() ) );
                    reporter.Report( txt, REPORTER::RPT_ERROR );
                }
                break;
            }

            SetActiveLayer( layer, false );
        }
    }

    if( !success )
    {
        HTML_MESSAGE_BOX mbox( this, _( "Errors" ) );
        mbox.ListSet( msg );
        mbox.ShowModal();
    }

    Zoom_Automatique( false );

    // Synchronize layers tools with actual active layer:
    ReFillLayerWidget();
    SetActiveLayer( GetActiveLayer() );
    m_LayersManager->UpdateLayerIcons();
    syncLayerBox();

    return success;
}
예제 #30
0
파일: edgemod.cpp 프로젝트: johnbeard/kicad
EDGE_MODULE* FOOTPRINT_EDIT_FRAME::Begin_Edge_Module( EDGE_MODULE* aEdge,
                                                      wxDC*        DC,
                                                      STROKE_T     type_edge )
{
    MODULE* module = GetBoard()->m_Modules;

    if( module == NULL )
        return NULL;

    if( aEdge == NULL )       // Start a new edge item
    {
        SaveCopyInUndoList( module, UR_CHANGED );

        aEdge = new EDGE_MODULE( module );
        MoveVector.x = MoveVector.y = 0;

        // Add the new item to the Drawings list head
        module->GraphicalItemsList().PushFront( aEdge );

        // Update characteristics of the segment or arc.
        aEdge->SetFlags( IS_NEW );
        aEdge->SetAngle( 0 );
        aEdge->SetShape( type_edge );

        if( aEdge->GetShape() == S_ARC )
            aEdge->SetAngle( ArcValue );

        aEdge->SetWidth( GetDesignSettings().GetLineThickness( GetActiveLayer() ) );
        aEdge->SetLayer( GetActiveLayer() );

        // Initialize the starting point of the new segment or arc
        aEdge->SetStart( GetCrossHairPosition() );

        // Initialize the ending point of the new segment or arc
        aEdge->SetEnd( aEdge->GetStart() );

        // Initialize the relative coordinates
        aEdge->SetStart0( aEdge->GetStart() - module->GetPosition() );

        RotatePoint( &aEdge->m_Start0, -module->GetOrientation() );

        aEdge->m_End0 = aEdge->m_Start0;
        module->CalculateBoundingBox();
        m_canvas->SetMouseCapture( ShowNewEdgeModule, Abort_Move_ModuleOutline );
    }
    /* Segment creation in progress.
     * The ending coordinate is updated by the function
     * ShowNewEdgeModule() called on move mouse event
     * during the segment creation
     */
    else
    {
        if( type_edge == S_SEGMENT )
        {
            if( aEdge->m_Start0 != aEdge->m_End0 )
            {
                aEdge->Draw( m_canvas, DC, GR_OR );

                EDGE_MODULE* newedge = new EDGE_MODULE( *aEdge );

                // insert _after_ aEdge, which is the same as inserting before aEdge->Next()
                module->GraphicalItemsList().Insert( newedge, aEdge->Next() );
                aEdge->ClearFlags();

                aEdge = newedge;     // point now new item

                aEdge->SetFlags( IS_NEW );
                aEdge->SetWidth( GetDesignSettings().GetLineThickness( aEdge->GetLayer() ) );
                aEdge->SetStart( GetCrossHairPosition() );
                aEdge->SetEnd( aEdge->GetStart() );

                // Update relative coordinate.
                aEdge->SetStart0( aEdge->GetStart() - module->GetPosition() );

                wxPoint pt( aEdge->GetStart0() );

                RotatePoint( &pt, -module->GetOrientation() );

                aEdge->SetStart0( pt );

                aEdge->SetEnd0( aEdge->GetStart0() );

                module->CalculateBoundingBox();
                module->SetLastEditTime();
                OnModify();
            }
        }
        else
        {
            wxLogDebug( wxT( "Begin_Edge() error" ) );
        }
    }

    return aEdge;
}