Commit 0ae31f3e authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: better dialogs to select the active layer or a layer pair. Add an...

Pcbnew: better dialogs to select the active layer or a layer pair. Add an option (hotkey+popup menu) to place a via and select the new active layer
(useful for boards having more than 2 layers)
Eeschema:fix compatibility with old schematic files, when they  contain ERC markers.
Pcbnew: better test for allowed layers when creating/editing Dimensions and some other Graphic items
Drc:  fix comments and messages for some drc tests.
Fix minor bugs in cleanup dialog options and plot solder mask function (thanks to Lorenzo to locate these bugs)
parents 1e8430d5 c029dc39
......@@ -194,6 +194,7 @@ again." );
case 'K': // It is a Marker item.
// Markers are no more read from file. they are only created on
// demand in schematic
itemLoaded = true; // Just skip descr and disable err message
break;
case 'N': // It is a NoConnect item.
......@@ -242,6 +243,9 @@ again." );
if( !itemLoaded )
{
msgDiag.Printf( _( "Eeschema file object not loaded at line %d, aborted" ),
reader.LineNumber() );
msgDiag << wxT( "\n" ) << FROM_UTF8( line );
DisplayError( this, msgDiag );
break;
}
......
......@@ -139,14 +139,35 @@ typedef unsigned LAYER_MSK;
#define NO_LAYERS 0x00000000
/** return a one bit layer mask from a layer number
* aLayerNumber = the layer number to convert (0 .. LAYERS-1)
/**
* @return a one bit layer mask from a layer number
* @param aLayerNumber = the layer number to convert (0 .. LAYERS-1)
*/
inline LAYER_MSK GetLayerMask( LAYER_NUM aLayerNumber )
{
return 1 << aLayerNumber;
}
/**
* @return bool if aLayerNumber is a layer contained in aMask
* @param aMask = a layer mask
* @param aLayerNumber is the layer id to test
*/
inline bool IsLayerInList( LAYER_MSK aMask, LAYER_NUM aLayerNumber )
{
return (aMask & GetLayerMask( aLayerNumber )) != 0;
}
/**
* @return bool if 2 layer masks have a comman layer
* @param aMask1 = a layer mask
* @param aMask2 = an other layer mask
*/
inline bool IsLayerMasksIntersect( LAYER_MSK aMask1, LAYER_MSK aMask2 )
{
return (aMask1 & aMask2) != 0;
}
/**
* Count the number of set layers in the mask
*/
......@@ -244,11 +265,11 @@ inline bool IsPcbLayer( LAYER_NUM aLayer )
* Function IsCopperLayer
* tests whether a layer is a copper layer
* @param aLayer = Layer to test
* @return true if aLayer is a valid copper layer
* @return true if aLayer is a valid copper layer
*/
inline bool IsCopperLayer( LAYER_NUM aLayer )
{
return aLayer >= FIRST_COPPER_LAYER
return aLayer >= FIRST_COPPER_LAYER
&& aLayer <= LAST_COPPER_LAYER;
}
......@@ -269,12 +290,12 @@ inline bool IsNonCopperLayer( LAYER_NUM aLayer )
So a layer can be:
- Front
- Back
- Neither (internal or auxiliary)
- Neither (internal or auxiliary)
The check most frequent is for back layers, since it involves flips */
/**
/**
* Layer classification: check if it's a front layer
*/
inline bool IsFrontLayer( LAYER_NUM aLayer )
......@@ -286,7 +307,7 @@ inline bool IsFrontLayer( LAYER_NUM aLayer )
aLayer == SOLDERPASTE_N_FRONT );
}
/**
/**
* Layer classification: check if it's a back layer
*/
inline bool IsBackLayer( LAYER_NUM aLayer )
......@@ -314,7 +335,7 @@ LAYER_MSK FlipLayerMask( LAYER_MSK aMask );
/**
* Extract the set layer from a mask. Returns UNDEFINED_LAYER if more
* than one is set or UNSELECTED_LAYER if none is
* than one is set or UNSELECTED_LAYER if none is
*/
LAYER_NUM ExtractLayer( LAYER_MSK aMask );
......
......@@ -639,11 +639,19 @@ public:
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) = 0;
// layerhandling:
// (See pcbnew/sel_layer.cpp for description of why null_layer parameter
// is provided)
LAYER_NUM SelectLayer( LAYER_NUM default_layer, LAYER_NUM min_layer, LAYER_NUM max_layer, bool null_layer = false );
void SelectLayerPair();
/** Install the dialog box for layer selection
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aNotAllowedLayersMask = a layer mask for not allowed layers
* (= 0 to show all layers in use)
* @return the selected layer id
*/
LAYER_NUM SelectLayer( LAYER_NUM aDefaultLayer, LAYER_MSK aNotAllowedLayersMask = 0 );
/* Display a list of two copper layers to choose a pair of copper layers
* the layer pair is used to fast switch between copper layers when placing vias
*/
void SelectCopperLayerPair();
virtual void SwitchLayer( wxDC* DC, LAYER_NUM layer );
/**
......
......@@ -60,9 +60,9 @@ wxString DRC_ITEM::GetErrorText() const
case DRCE_ENDS_PROBLEM3:
case DRCE_ENDS_PROBLEM4:
case DRCE_ENDS_PROBLEM5:
return wxString( _("Two track ends") );
case DRCE_TRACK_UNKNOWN1:
return wxString( _("This looks bad") ); ///< @todo check source code and change this comment
return wxString( _("Two track ends too close") );
case DRCE_TRACK_SEGMENTS_TOO_CLOSE:
return wxString( _("Two parallel track segments too close") );
case DRCE_TRACKS_CROSSING:
return wxString( _("Tracks crossing") );
case DRCE_PAD_NEAR_PAD1:
......
......@@ -165,6 +165,7 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
m_LayerSelectionCtrl->SetLayerMask( ALL_CU_LAYERS );
m_LayerSelectionCtrl->SetBoardFrame( m_parent );
m_LayerSelectionCtrl->Resync();
if( m_LayerSelectionCtrl->SetLayerSelection( m_Item->GetLayer() ) < 0 )
{
wxMessageBox( _("This item has an illegal layer id.\n"
......
......@@ -77,9 +77,6 @@ DIALOG_LAYER_SELECTION_BASE::DIALOG_LAYER_SELECTION_BASE( wxWindow* parent, wxWi
bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
m_buttonClear = new wxButton( this, wxID_ANY, _("Clear Selection"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerMain->Add( m_buttonClear, 0, wxALL|wxALIGN_RIGHT, 5 );
this->SetSizer( bSizerMain );
this->Layout();
......@@ -87,17 +84,19 @@ DIALOG_LAYER_SELECTION_BASE::DIALOG_LAYER_SELECTION_BASE( wxWindow* parent, wxWi
this->Centre( wxBOTH );
// Connect Events
m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridClick ), NULL, this );
m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridClick ), NULL, this );
m_buttonClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYER_SELECTION_BASE::OnClearSelection ), NULL, this );
m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
m_leftGridLayers->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
m_rightGridLayers->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
}
DIALOG_LAYER_SELECTION_BASE::~DIALOG_LAYER_SELECTION_BASE()
{
// Disconnect Events
m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridClick ), NULL, this );
m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridClick ), NULL, this );
m_buttonClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYER_SELECTION_BASE::OnClearSelection ), NULL, this );
m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
m_leftGridLayers->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
m_rightGridLayers->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
}
......@@ -208,8 +207,8 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
this->Centre( wxBOTH );
// Connect Events
m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridClick ), NULL, this );
m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridClick ), NULL, this );
m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnCancelClick ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnOKClick ), NULL, this );
}
......@@ -217,8 +216,8 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::~DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE()
{
// Disconnect Events
m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridClick ), NULL, this );
m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridClick ), NULL, this );
m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnCancelClick ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnOKClick ), NULL, this );
......
......@@ -190,7 +190,7 @@
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnGridCellChange"></event>
<event name="OnGridCellLeftClick">OnLeftGridClick</event>
<event name="OnGridCellLeftClick">OnLeftGridCellClick</event>
<event name="OnGridCellLeftDClick"></event>
<event name="OnGridCellRightClick"></event>
<event name="OnGridCellRightDClick"></event>
......@@ -227,7 +227,7 @@
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnLeftUp">OnLeftButtonReleased</event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
......@@ -333,7 +333,7 @@
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnGridCellChange"></event>
<event name="OnGridCellLeftClick">OnRightGridClick</event>
<event name="OnGridCellLeftClick">OnRightGridCellClick</event>
<event name="OnGridCellLeftDClick"></event>
<event name="OnGridCellRightClick"></event>
<event name="OnGridCellRightDClick"></event>
......@@ -370,7 +370,7 @@
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnLeftUp">OnLeftButtonReleased</event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
......@@ -388,94 +388,6 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_RIGHT</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Clear Selection</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_buttonClear</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnClearSelection</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="Dialog" expanded="1">
......@@ -736,7 +648,7 @@
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnGridCellChange"></event>
<event name="OnGridCellLeftClick">OnLeftGridClick</event>
<event name="OnGridCellLeftClick">OnLeftGridCellClick</event>
<event name="OnGridCellLeftDClick"></event>
<event name="OnGridCellRightClick"></event>
<event name="OnGridCellRightDClick"></event>
......@@ -973,7 +885,7 @@
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnGridCellChange"></event>
<event name="OnGridCellLeftClick">OnRightGridClick</event>
<event name="OnGridCellLeftClick">OnRightGridCellClick</event>
<event name="OnGridCellLeftDClick"></event>
<event name="OnGridCellRightClick"></event>
<event name="OnGridCellRightDClick"></event>
......
......@@ -18,10 +18,10 @@
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/stattext.h>
#include <wx/statline.h>
#include <wx/button.h>
///////////////////////////////////////////////////////////////////////////
......@@ -38,12 +38,11 @@ class DIALOG_LAYER_SELECTION_BASE : public wxDialog
protected:
wxGrid* m_leftGridLayers;
wxGrid* m_rightGridLayers;
wxButton* m_buttonClear;
// Virtual event handlers, overide them in your derived class
virtual void OnLeftGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRightGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnClearSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLeftGridCellClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnLeftButtonReleased( wxMouseEvent& event ) { event.Skip(); }
virtual void OnRightGridCellClick( wxGridEvent& event ) { event.Skip(); }
public:
......@@ -71,8 +70,8 @@ class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE : public wxDialog
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnLeftGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRightGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnLeftGridCellClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRightGridCellClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
......
......@@ -138,7 +138,13 @@ DIALOG_DIMENSION_EDITOR::DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent,
m_SelLayerBox->SetLayerMask( ALL_CU_LAYERS | EDGE_LAYER );
m_SelLayerBox->SetBoardFrame( m_Parent );
m_SelLayerBox->Resync();
m_SelLayerBox->SetLayerSelection( aDimension->GetLayer() );
if( m_SelLayerBox->SetLayerSelection( aDimension->GetLayer() ) < 0 )
{
wxMessageBox( _("This item has an illegal layer id.\n"
"Now, forced on the drawings layer. Please, fix it") );
m_SelLayerBox->SetLayerSelection( DRAW_N );
}
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
......
......@@ -420,6 +420,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( segStartPoint.x > (-w_dist) && segStartPoint.x < (m_segmLength + w_dist) ) /* possible error drc */
{
// the start point is inside the reference range
// X........
// O--REF--+
// Fine test : we consider the rounded shape of each end of the track segment:
if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength )
{
......@@ -438,7 +442,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( segEndPoint.x > (-w_dist) && segEndPoint.x < (m_segmLength + w_dist) )
{
/* Fine test : we consider the rounded shape of the ends */
// the end point is inside the reference range
// .....X
// O--REF--+
// Fine test : we consider the rounded shape of the ends
if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength )
{
m_currentMarker = fillMarker( aRefSeg, track,
......@@ -456,8 +463,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( segStartPoint.x <=0 && segEndPoint.x >= 0 )
{
// the segment straddles the reference range (this actually only
// checks if it straddles the origin, because the other cases where already
// handled)
// X.............X
// O--REF--+
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_UNKNOWN1, m_currentMarker );
DRCE_TRACK_SEGMENTS_TOO_CLOSE, m_currentMarker );
return false;
}
}
......
......@@ -44,11 +44,11 @@
#define DRCE_TRACK_NEAR_VIA 5 ///< track too close to via
#define DRCE_VIA_NEAR_VIA 6 ///< via too close to via
#define DRCE_VIA_NEAR_TRACK 7 ///< via too close to track
#define DRCE_TRACK_ENDS1 8 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS2 9 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS3 10 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS4 11 ///< @todo say what this problem is
#define DRCE_TRACK_UNKNOWN1 12 ///< @todo check source code and change this comment
#define DRCE_TRACK_ENDS1 8 ///< 2 parallel track segments too close: fine start point test
#define DRCE_TRACK_ENDS2 9 ///< 2 parallel track segments too close: fine start point test
#define DRCE_TRACK_ENDS3 10 ///< 2 parallel track segments too close: fine end point test
#define DRCE_TRACK_ENDS4 11 ///< 2 parallel track segments too close: fine end point test
#define DRCE_TRACK_SEGMENTS_TOO_CLOSE 12 ///< 2 parallel track segments too close: segm ends between segref ends
#define DRCE_TRACKS_CROSSING 13 ///< tracks are crossing
#define DRCE_ENDS_PROBLEM1 14 ///< track ends are too close
#define DRCE_ENDS_PROBLEM2 15 ///< track ends are too close
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -190,16 +190,19 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
{
// note: if aEdge == NULL, all outline segments will be modified
MODULE* module = GetBoard()->m_Modules;
LAYER_NUM new_layer = SILKSCREEN_N_FRONT;
LAYER_NUM layer = SILKSCREEN_N_FRONT;
bool modified = false;
if( aEdge )
new_layer = aEdge->GetLayer();
layer = aEdge->GetLayer();
// Ask for the new layer
new_layer = SelectLayer( new_layer, FIRST_COPPER_LAYER, ECO2_N );
LAYER_NUM new_layer = SelectLayer(layer, EDGE_LAYER );
if( new_layer < 0 )
if( layer < 0 )
return;
if( IsCopperLayer( new_layer ) )
......@@ -211,8 +214,6 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
return;
}
SaveCopyInUndoList( module, UR_MODEDIT );
if( aEdge == NULL )
{
aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems();
......@@ -222,17 +223,27 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
if( aEdge->Type() != PCB_MODULE_EDGE_T )
continue;
aEdge->SetLayer( new_layer );
if( aEdge->GetLayer() != new_layer )
{
if( ! modified ) // save only once
SaveCopyInUndoList( module, UR_MODEDIT );
aEdge->SetLayer( new_layer );
modified = true;
}
}
}
else
else if( aEdge->GetLayer() != new_layer )
{
SaveCopyInUndoList( module, UR_MODEDIT );
aEdge->SetLayer( new_layer );
modified = true;
}
OnModify();
module->CalculateBoundingBox();
module->SetLastEditTime();
if( modified )
{
module->CalculateBoundingBox();
module->SetLastEditTime();
}
}
......
......@@ -95,7 +95,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_BEGIN_TRACK:
case ID_POPUP_PCB_END_TRACK:
case ID_POPUP_PCB_PLACE_THROUGH_VIA:
case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA:
case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA:
case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA:
case ID_POPUP_PCB_PLACE_MICROVIA:
case ID_POPUP_PCB_SWITCH_TRACK_POSTURE:
case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
......@@ -383,6 +385,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
// fall through
case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA:
case ID_POPUP_PCB_PLACE_THROUGH_VIA:
case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA:
case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA:
m_canvas->MoveCursorToCrossHair();
if( GetCurItem()->IsDragging() )
......@@ -392,7 +396,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
else
{
int v_type = GetDesignSettings().m_CurrentViaType;
if( id == ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA )
if( id == ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA ||
id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA )
GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
else if( id == ID_POPUP_PCB_PLACE_MICROVIA )
GetDesignSettings().m_CurrentViaType = VIA_MICROVIA;
......@@ -400,7 +405,25 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
GetDesignSettings().m_CurrentViaType = VIA_THROUGH;
// place via and switch layer.
Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
if( id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA ||
id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA )
{
m_canvas->SetIgnoreMouseEvents( true );
LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS );
m_canvas->SetIgnoreMouseEvents( false );
m_canvas->MoveCursorToCrossHair();
if( getActiveLayer() != layer )
{
GetScreen()->m_Route_Layer_TOP = getActiveLayer();
GetScreen()->m_Route_Layer_BOTTOM = layer;
Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
}
}
else
Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
GetDesignSettings().m_CurrentViaType = v_type;
if( DisplayOpt.ContrastModeDisplay )
......@@ -922,7 +945,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_SELECT_LAYER:
itmp = SelectLayer( getActiveLayer(), UNDEFINED_LAYER, UNDEFINED_LAYER );
itmp = SelectLayer( getActiveLayer() );
if( itmp >= 0 )
{
......@@ -939,11 +962,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR:
SelectLayerPair();
SelectCopperLayerPair();
break;
case ID_POPUP_PCB_SELECT_NO_CU_LAYER:
itmp = SelectLayer( getActiveLayer(), FIRST_NON_COPPER_LAYER, UNDEFINED_LAYER );
itmp = SelectLayer( getActiveLayer(), ALL_CU_LAYERS );
if( itmp >= 0 )
setActiveLayer( itmp );
......@@ -952,7 +975,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_SELECT_CU_LAYER:
itmp = SelectLayer( getActiveLayer(), UNDEFINED_LAYER, LAST_COPPER_LAYER );
itmp = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS );
if( itmp >= 0 )
setActiveLayer( itmp );
......@@ -960,7 +983,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_SELECT_LAYER_PAIR:
SelectLayerPair();
SelectCopperLayerPair();
m_canvas->MoveCursorToCrossHair();
break;
......
......@@ -61,8 +61,12 @@ static EDA_HOTKEY HkFindItem( wxT( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL
static EDA_HOTKEY HkBackspace( wxT( "Delete track segment" ), HK_BACK_SPACE, WXK_BACK );
static EDA_HOTKEY HkAddNewTrack( wxT( "Add new track" ), HK_ADD_NEW_TRACK, 'X' );
static EDA_HOTKEY HkAddThroughVia( wxT( "Add Through Via" ), HK_ADD_THROUGH_VIA, 'V' );
static EDA_HOTKEY HkSelLayerAndAddThroughVia( wxT( "Sel Layer and Add Through Via" ),
HK_SEL_LAYER_AND_ADD_THROUGH_VIA, '<' );
static EDA_HOTKEY HkAddMicroVia( wxT( "Add MicroVia" ), HK_ADD_MICROVIA, 'V' + GR_KB_CTRL );
static EDA_HOTKEY HkAddBlindBuriedVia( wxT( "Add Blind/Buried Via" ), HK_ADD_BLIND_BURIED_VIA, 'V' + GR_KB_ALT );
static EDA_HOTKEY HkSelLayerAndAddBlindBuriedVia( wxT( "Sel Layer and Add Blind/Buried Via" ),
HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA, '<' + GR_KB_ALT );
static EDA_HOTKEY HkSwitchTrackPosture( wxT( "Switch Track Posture" ), HK_SWITCH_TRACK_POSTURE, '/' );
static EDA_HOTKEY HkDragTrackKeepSlope( wxT( "Drag track keep slope" ), HK_DRAG_TRACK_KEEP_SLOPE, 'D' );
static EDA_HOTKEY HkPlaceItem( wxT( "Place Item" ), HK_PLACE_ITEM, 'P' );
......@@ -210,6 +214,7 @@ EDA_HOTKEY* board_edit_Hotkey_List[] =
&HkBackspace,
&HkAddNewTrack, &HkAddThroughVia, &HkAddBlindBuriedVia,
&HkAddMicroVia,
&HkSelLayerAndAddThroughVia, &HkSelLayerAndAddBlindBuriedVia,
&HkSwitchTrackPosture,
&HkDragTrackKeepSlope,
&HkPlaceItem, &HkCopyItem,
......
......@@ -22,7 +22,9 @@ enum hotkey_id_commnand {
HK_LOCK_UNLOCK_FOOTPRINT,
HK_ADD_NEW_TRACK,
HK_ADD_THROUGH_VIA,
HK_SEL_LAYER_AND_ADD_THROUGH_VIA,
HK_ADD_BLIND_BURIED_VIA,
HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA,
HK_ADD_MICROVIA,
HK_SWITCH_TRACK_POSTURE,
HK_DRAG_TRACK_KEEP_SLOPE,
......
......@@ -88,7 +88,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
if( aHotkeyCode == 0 )
return;
bool itemCurrentlyEdited = (GetCurItem() && GetCurItem()->GetFlags());
bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
MODULE* module = NULL;
int evt_type = 0; //Used to post a wxCommandEvent on demand
PCB_SCREEN* screen = GetScreen();
......@@ -374,7 +374,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_BACK_SPACE:
if( /*m_ID_current_state == ID_TRACK_BUTT &&*/ (getActiveLayer() <= LAYER_N_FRONT) )
if( IsCopperLayer( getActiveLayer() ) )
{
if( !itemCurrentlyEdited )
{
......@@ -461,7 +461,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
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 )
hk_id == HK_ADD_BLIND_BURIED_VIA )
GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
else
GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH;
......@@ -487,6 +487,17 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
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 -\ .
......
......@@ -367,9 +367,10 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
break;
case ID_PCB_DIMENSION_BUTT:
if( IsCopperLayer( getActiveLayer() ) )
if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS ,getActiveLayer() ) )
{
DisplayError( this, _( "Dimension not allowed on Copper layers" ) );
DisplayError( this,
_( "Dimension not allowed on Copper or Edge Cut layers" ) );
break;
}
......
......@@ -55,7 +55,9 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
{
wxString msg;
STATUS_FLAGS flags = 0;
bool locate_track = false;
bool trackFound = false; // Flag set to true,
// if a track is being the cursor, to avoid
// to display menus relative to tracks twice
bool blockActive = !GetScreen()->m_BlockLocate.IsIdle();
wxClientDC dc( m_canvas );
......@@ -118,8 +120,9 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
*/
if( !item || (item->GetFlags() == 0) )
{
// show "item selector" menu only if no item now or selected item was not
// previously picked at this position
// show the "item selector" menu if no item selected or
// if there is a selected item but the mouse has moved
// (therefore a new item is perhaps under the cursor)
if( !item || cursorPos != selectPos )
{
m_canvas->SetAbortRequest( false );
......@@ -140,6 +143,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
else
flags = 0;
// Add the context menu, which depends on the picked item:
if( item )
{
switch( item->Type() )
......@@ -238,7 +242,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
case PCB_TRACE_T:
case PCB_VIA_T:
locate_track = true;
trackFound = true;
createPopupMenuForTracks( (TRACK*) item, aPopMenu );
break;
......@@ -301,7 +305,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
break;
}
aPopMenu->AppendSeparator();
aPopMenu->AppendSeparator();
}
if( !flags )
......@@ -338,10 +342,9 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
break;
case ID_TRACK_BUTT:
aPopMenu->AppendSeparator();
if ( ! locate_track ) // This menu is already added when a track is located
if ( ! trackFound ) // This menu is already added when a track is located
{
aPopMenu->AppendSeparator();
msg = AddHotkeyName( _( "Begin Track" ),
g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK,
......@@ -350,12 +353,13 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ),
ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
KiBitmap( width_track_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
_( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) );
aPopMenu->AppendSeparator();
}
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
_( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) );
aPopMenu->AppendSeparator();
break;
case ID_PCB_CIRCLE_BUTT:
......@@ -369,9 +373,12 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
break;
case ID_PCB_MODULE_BUTT:
AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
_( "Footprint Documentation" ), KiBitmap( book_xpm ) );
aPopMenu->AppendSeparator();
if( !flags )
{
AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
_( "Footprint Documentation" ), KiBitmap( book_xpm ) );
aPopMenu->AppendSeparator();
}
break;
case ID_NO_TOOL_SELECTED:
......@@ -415,17 +422,19 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
aPopMenu->AppendSeparator();
}
msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) );
if( !trackFound )
{
msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) );
if( locate_track )
AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ),
ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
KiBitmap( width_track_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
aPopMenu->AppendSeparator();
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
aPopMenu->AppendSeparator();
}
break;
}
......@@ -466,6 +475,11 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
if( flags == 0 )
{
msg = AddHotkeyName( _( "Begin Track" ),
g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
AddMenuItem( PopMenu, ID_POPUP_PCB_BEGIN_TRACK,
msg, KiBitmap( add_tracks_xpm ) );
if( Track->Type() == PCB_VIA_T )
{
msg = AddHotkeyName( _( "Drag Via" ), g_Board_Editor_Hokeys_Descr,
......@@ -495,6 +509,9 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
_( "Break Track" ), KiBitmap( break_line_xpm ) );
}
}
AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
}
else if( flags & IS_DRAGGED ) // Drag via or node in progress
{
......@@ -506,11 +523,6 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
{
if( flags & IS_NEW )
{
msg = AddHotkeyName( _( "Begin Track" ),
g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
AddMenuItem( PopMenu, ID_POPUP_PCB_BEGIN_TRACK,
msg, KiBitmap( add_tracks_xpm ) );
msg = AddHotkeyName( _( "End Track" ), g_Board_Editor_Hokeys_Descr, HK_END_TRACK );
AddMenuItem( PopMenu, ID_POPUP_PCB_END_TRACK, msg, KiBitmap( apply_xpm ) );
}
......@@ -518,10 +530,21 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
msg = AddHotkeyName( _( "Place Through Via" ), g_Board_Editor_Hokeys_Descr, HK_ADD_THROUGH_VIA );
AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_THROUGH_VIA, msg, KiBitmap( via_xpm ) );
msg = AddHotkeyName( _( "Select Layer and Place Through Via" ),
g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_THROUGH_VIA );
AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA,
msg, KiBitmap( select_w_layer_xpm ) );
if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed )
{
msg = AddHotkeyName( _( "Place Blind/Buried Via" ), g_Board_Editor_Hokeys_Descr, HK_ADD_BLIND_BURIED_VIA );
msg = AddHotkeyName( _( "Place Blind/Buried Via" ),
g_Board_Editor_Hokeys_Descr, HK_ADD_BLIND_BURIED_VIA );
AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA, msg, KiBitmap( via_xpm ) );
msg = AddHotkeyName( _( "Select Layer and Place Blind/Buried Via" ),
g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA );
AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA,
msg, KiBitmap( select_w_layer_xpm ) );
}
msg = AddHotkeyName( _( "Switch Track Posture" ), g_Board_Editor_Hokeys_Descr,
......@@ -563,21 +586,21 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
// Delete control:
PopMenu->AppendSeparator();
wxMenu* track_mnu = new wxMenu;
AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ),
wxMenu* trackdel_mnu = new wxMenu;
AddMenuItem( PopMenu, trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ),
KiBitmap( delete_xpm ) );
msg = AddHotkeyName( Track->Type()==PCB_VIA_T ?
_( "Delete Via" ) : _( "Delete Segment" ),
g_Board_Editor_Hokeys_Descr, HK_BACK_SPACE );
AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACKSEG, msg, KiBitmap( delete_line_xpm ) );
AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKSEG, msg, KiBitmap( delete_line_xpm ) );
if( !flags )
{
msg = AddHotkeyName( _( "Delete Track" ), g_Board_Editor_Hokeys_Descr, HK_DELETE );
AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACK, msg, KiBitmap( delete_track_xpm ) );
AddMenuItem( track_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ),
AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK, msg, KiBitmap( delete_track_xpm ) );
AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ),
KiBitmap( delete_net_xpm ) );
}
......@@ -590,25 +613,25 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
}
// Add lock/unlock flags menu:
track_mnu = new wxMenu;
wxMenu* trackflg_mnu = new wxMenu;
AddMenuItem( PopMenu, track_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ),
AddMenuItem( PopMenu, trackflg_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ),
KiBitmap( flag_xpm ) );
track_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true );
track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true );
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true );
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true );
if( Track->GetState( TRACK_LOCKED ) )
track_mnu->Check( ID_POPUP_PCB_LOCK_ON_TRACKSEG, true );
trackflg_mnu->Check( ID_POPUP_PCB_LOCK_ON_TRACKSEG, true );
else
track_mnu->Check( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, true );
trackflg_mnu->Check( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, true );
if( !flags )
{
track_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACK, _( "Track Locked: Yes" ) );
track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACK, _( "Track Locked: No" ) );
track_mnu->AppendSeparator();
track_mnu->Append( ID_POPUP_PCB_LOCK_ON_NET, _( "Net Locked: Yes" ) );
track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_NET, _( "Net Locked: No" ) );
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACK, _( "Track Locked: Yes" ) );
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACK, _( "Track Locked: No" ) );
trackflg_mnu->AppendSeparator();
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_NET, _( "Net Locked: Yes" ) );
trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_NET, _( "Net Locked: No" ) );
}
}
......
......@@ -121,7 +121,9 @@ enum pcbnew_ids
ID_POPUP_PCB_EDIT_DIMENSION,
ID_POPUP_PCB_END_TRACK,
ID_POPUP_PCB_PLACE_THROUGH_VIA,
ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA,
ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA,
ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA,
ID_POPUP_PCB_PLACE_MICROVIA,
ID_POPUP_PCB_SWITCH_TRACK_POSTURE,
......
......@@ -70,34 +70,28 @@ protected:
{
return m_brd->GetLayerName( aLayer );
}
};
/*
* This class display a pcb layers list in adialog,
* This class display a pcb layers list in a dialog,
* to select one layer from this list
*/
class PCB_ONE_LAYER_SELECTOR : public PCB_LAYER_SELECTOR,
public DIALOG_LAYER_SELECTION_BASE
{
LAYER_NUM m_layerSelected;
LAYER_NUM m_minLayer;
LAYER_NUM m_maxLayer;
LAYER_MSK m_notAllowedLayersMask;
std::vector<LAYER_NUM> m_layersIdLeftColumn;
std::vector<LAYER_NUM> m_layersIdRightColumn;
public:
PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd,
LAYER_NUM aDefaultLayer,
LAYER_NUM aMinLayer = -1, LAYER_NUM aMaxLayer = -1,
bool aClearTool = false )
LAYER_MSK aNotAllowedLayersMask )
:PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
{
m_layerSelected = (int) aDefaultLayer;
// When not needed, remove the "Clear" button
m_buttonClear->Show( aClearTool );
m_minLayer = aMinLayer;
m_maxLayer = aMaxLayer;
m_notAllowedLayersMask = aNotAllowedLayersMask;
BuildList();
Layout();
GetSizer()->SetSizeHints(this);
......@@ -108,13 +102,8 @@ public:
private:
// Event handlers
void OnLeftGridClick( wxGridEvent& event );
void OnRightGridClick( wxGridEvent& event );
void OnClearSelection( wxCommandEvent& event )
{
m_layerSelected = NB_PCB_LAYERS;
EndModal( NB_PCB_LAYERS );
}
void OnLeftGridCellClick( wxGridEvent& event );
void OnRightGridCellClick( wxGridEvent& event );
void BuildList();
};
......@@ -146,10 +135,7 @@ void PCB_ONE_LAYER_SELECTOR::BuildList()
if( ! IsLayerEnabled( layerid ) )
continue;
if( m_minLayer >= 0 && layerid < m_minLayer )
continue;
if( m_maxLayer >= 0 && layerid > m_maxLayer )
if( (m_notAllowedLayersMask & GetLayerMask( layerid )) != 0 )
continue;
wxColour color = MakeColour( GetLayerColor( layerid ) );
......@@ -214,43 +200,31 @@ void PCB_ONE_LAYER_SELECTOR::BuildList()
m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
}
void PCB_ONE_LAYER_SELECTOR::OnLeftGridClick( wxGridEvent& event )
void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event )
{
m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
EndModal( 1 );
}
void PCB_ONE_LAYER_SELECTOR::OnRightGridClick( wxGridEvent& event )
void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event )
{
m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
EndModal( 2 );
}
/** Install the dialog box for layer selection
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aMinlayer = min layer id value (-1 if no min value)
* @param aMaxLayer = max layer id value (-1 if no max value)
* @param aDeselectTool = display a "Clear" button when true
* @return new layer value (NB_PCB_LAYERS when "(Deselect)" radiobutton selected),
* or -1 if canceled
*
* Providing the option to also display a "Clear" button makes the
* "Swap Layers" command more "user friendly",
* by permitting any layer to be "deselected" immediately after its
* corresponding radiobutton has been clicked on. (It would otherwise be
* necessary to first cancel the "Select Layer:" dialog box (invoked after a
* different radiobutton is clicked on) prior to then clicking on the
* "Clear" button provided within the "Swap Layers:"
* or "Layer selection:" dialog box).
* @param aNotAllowedLayers = a layer mask for not allowed layers
* (= 0 to show all layers in use)
* @return the selected layer id
*/
LAYER_NUM PCB_BASE_FRAME::SelectLayer( LAYER_NUM aDefaultLayer,
LAYER_NUM aMinlayer,
LAYER_NUM aMaxLayer,
bool aDeselectTool )
LAYER_MSK aNotAllowedLayersMask )
{
PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(),
aDefaultLayer, aMinlayer, aMaxLayer,
aDeselectTool );
aDefaultLayer, aNotAllowedLayersMask );
dlg.ShowModal();
LAYER_NUM layer = dlg.GetLayerSelection();
return layer;
......@@ -259,7 +233,7 @@ LAYER_NUM PCB_BASE_FRAME::SelectLayer( LAYER_NUM aDefaultLayer,
/*
* This class display a double pcb copper layers list in a dialog,
* to select a layer pair from this list
* to select a layer pair from these lists
*/
class SELECT_COPPER_LAYERS_PAIR_DIALOG: public PCB_LAYER_SELECTOR,
public DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
......@@ -283,8 +257,8 @@ public:
}
private:
void OnLeftGridClick( wxGridEvent& event );
void OnRightGridClick( wxGridEvent& event );
void OnLeftGridCellClick( wxGridEvent& event );
void OnRightGridCellClick( wxGridEvent& event );
void OnOkClick( wxCommandEvent& event )
{
......@@ -297,13 +271,13 @@ private:
}
void BuildList();
void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable );
};
/* Display a list of two copper layers to choose a pair of layers
* for auto-routing, vias ...
/* Display a list of two copper layers to choose a pair of copper layers
* the layer pair is used to fast switch between copper layers when placing vias
*/
void PCB_BASE_FRAME::SelectLayerPair()
void PCB_BASE_FRAME::SelectCopperLayerPair()
{
PCB_SCREEN* screen = GetScreen();
SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( this, GetBoard(),
......@@ -377,12 +351,8 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::BuildList()
if( m_frontLayer == layerid )
{
m_leftGridLayers->SetCellValue( row, SELECT_COLNUM,
wxT("X") );
m_leftGridLayers->SetCellBackgroundColour( row, SELECT_COLNUM,
color );
SetGridCursor( m_leftGridLayers, row, true );
m_leftRowSelected = row;
m_leftGridLayers->SetGridCursor( row, LAYERNAME_COLNUM );
}
if( row )
......@@ -394,12 +364,8 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::BuildList()
if( m_backLayer == layerid )
{
m_rightGridLayers->SetCellValue( row, SELECT_COLNUM,
wxT("X") );
m_rightGridLayers->SetCellBackgroundColour ( row, SELECT_COLNUM,
color );
SetGridCursor( m_rightGridLayers, row, true );
m_rightRowSelected = row;
m_rightGridLayers->SetGridCursor( row, LAYERNAME_COLNUM );
}
row++;
......@@ -411,7 +377,27 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::BuildList()
m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
}
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridClick( wxGridEvent& event )
void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow,
bool aEnable )
{
if( aEnable )
{
LAYER_NUM layerid = m_layersId[aRow];
wxColour color = MakeColour( GetLayerColor( layerid ) );
aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") );
aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color );
aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
}
else
{
aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString );
aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM,
aGrid->GetDefaultCellBackgroundColour() );
aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
}
}
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridCellClick( wxGridEvent& event )
{
int row = event.GetRow();
LAYER_NUM layer = m_layersId[row];
......@@ -419,22 +405,13 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridClick( wxGridEvent& event )
if( m_frontLayer == layer )
return;
m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM,
wxEmptyString );
m_leftGridLayers->SetCellBackgroundColour ( m_leftRowSelected, SELECT_COLNUM,
m_leftGridLayers->GetDefaultCellBackgroundColour() );
SetGridCursor( m_leftGridLayers, m_leftRowSelected, false );
m_frontLayer = layer;
m_leftRowSelected = row;
m_leftGridLayers->SetCellValue( row, SELECT_COLNUM,
wxT("X") );
m_leftGridLayers->SetCellBackgroundColour( row, SELECT_COLNUM,
MakeColour( GetLayerColor( layer ) ) );
m_leftGridLayers->SetGridCursor( row, LAYERNAME_COLNUM );
SetGridCursor( m_leftGridLayers, m_leftRowSelected, true );
}
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridClick( wxGridEvent& event )
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridCellClick( wxGridEvent& event )
{
int row = event.GetRow();
LAYER_NUM layer = m_layersId[row];
......@@ -442,16 +419,8 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridClick( wxGridEvent& event )
if( m_backLayer == layer )
return;
m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM,
wxEmptyString );
m_rightGridLayers->SetCellBackgroundColour ( m_rightRowSelected, SELECT_COLNUM,
m_rightGridLayers->GetDefaultCellBackgroundColour() );
SetGridCursor( m_rightGridLayers, m_rightRowSelected, false );
m_backLayer = layer;
m_rightRowSelected = row;
m_rightGridLayers->SetCellValue( row, SELECT_COLNUM,
wxT("X") );
m_rightGridLayers->SetCellBackgroundColour ( row, SELECT_COLNUM,
MakeColour( GetLayerColor( layer ) ) );
m_rightGridLayers->SetGridCursor( row, LAYERNAME_COLNUM );
SetGridCursor( m_rightGridLayers, m_rightRowSelected, true );
}
......@@ -195,12 +195,11 @@ WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( PCB_BASE_FRAME* parent ) :
item_ID = ID_TEXT_0 + ii;
/* When the first of these text strings is being added, determine
* what size is necessary to to be able to display any possible
* string without it being truncated. Then specify that size as the
* minimum size for all of these text strings. (If this minimum
* size is not determined in this fashion, then it is possible for
* the display of one or more of these strings to be truncated after
* different layers are selected.)
* what size is necessary to to be able to display the longest
* string without truncation. Then use that size as the
* minimum size for all text strings. (If the minimum
* size is not this size, strings can be truncated after
* some other layer is selected.)
*/
if( ii == 0 )
{
......@@ -235,8 +234,8 @@ WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( PCB_BASE_FRAME* parent ) :
}
/* Provide spacers to occupy otherwise blank cells within the second
* FlexGrid sizer. (As it incorporates three columns, three spacers
* are thus required for each otherwise unused row.)
* FlexGrid sizer. (Becuse there are three columns, three spacers
* are thus required for each unused row.)
*/
for( int ii = 3 * NB_PCB_LAYERS; ii < 96; ii++ )
{
......@@ -289,28 +288,16 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
if( (jj < 0) || (jj > NB_PCB_LAYERS) )
jj = LAYER_NO_CHANGE; // (Defaults to "No Change".)
jj = m_Parent->SelectLayer( jj, UNDEFINED_LAYER, UNDEFINED_LAYER, true );
jj = m_Parent->SelectLayer( jj );
if( !IsValidLayer( jj ) )
return;
// No change if the selected layer matches the layer being edited.
// (Hence the only way to restore a layer to the "No Change"
// state is by specifically deselecting it; any attempt
// to select the same layer (instead) will be ignored.)
if( jj == ii )
{
wxString msg;
msg = _( "Deselect this layer to select the No Change state" );
DisplayInfoMessage( this, msg );
return;
}
if( jj != New_Layer[ii] )
{
New_Layer[ii] = jj;
if( jj >= LAYER_NO_CHANGE )
if( jj >= LAYER_NO_CHANGE || jj == ii )
{
layer_list[ii]->SetLabel( _( "No Change" ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment