diff --git a/eeschema/load_one_schematic_file.cpp b/eeschema/load_one_schematic_file.cpp index 9ca2183bba..8aa9243d79 100644 --- a/eeschema/load_one_schematic_file.cpp +++ b/eeschema/load_one_schematic_file.cpp @@ -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; } diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index 1dd41130f0..dc8185896a 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -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 ); diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 12843befbe..b74c6165e5 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -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 ); /** diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp index edbdf94308..b70d98d3c2 100644 --- a/pcbnew/class_drc_item.cpp +++ b/pcbnew/class_drc_item.cpp @@ -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: diff --git a/pcbnew/dialogs/dialog_graphic_item_properties.cpp b/pcbnew/dialogs/dialog_graphic_item_properties.cpp index c4271c7b1c..561c29fa2a 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties.cpp @@ -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" diff --git a/pcbnew/dialogs/dialog_layer_selection_base.cpp b/pcbnew/dialogs/dialog_layer_selection_base.cpp index 37e90f562b..bdd2b7d03b 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.cpp +++ b/pcbnew/dialogs/dialog_layer_selection_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/dialog_layer_selection_base.fbp b/pcbnew/dialogs/dialog_layer_selection_base.fbp index 2a702b9e3c..9bea630a96 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.fbp +++ b/pcbnew/dialogs/dialog_layer_selection_base.fbp @@ -190,7 +190,7 @@ - OnLeftGridClick + OnLeftGridCellClick @@ -227,7 +227,7 @@ - + OnLeftButtonReleased @@ -333,7 +333,7 @@ - OnRightGridClick + OnRightGridCellClick @@ -370,7 +370,7 @@ - + OnLeftButtonReleased @@ -388,94 +388,6 @@ - - 5 - wxALL|wxALIGN_RIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Clear Selection - - 0 - - - 0 - - 1 - m_buttonClear - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnClearSelection - - - - - - - - - - - - - - - - - - - - - - - - - @@ -736,7 +648,7 @@ - OnLeftGridClick + OnLeftGridCellClick @@ -973,7 +885,7 @@ - OnRightGridClick + OnRightGridCellClick diff --git a/pcbnew/dialogs/dialog_layer_selection_base.h b/pcbnew/dialogs/dialog_layer_selection_base.h index 4a2b40f2ac..d61d4bf6cd 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.h +++ b/pcbnew/dialogs/dialog_layer_selection_base.h @@ -18,10 +18,10 @@ #include #include #include -#include #include #include #include +#include /////////////////////////////////////////////////////////////////////////// @@ -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(); } diff --git a/pcbnew/dimension.cpp b/pcbnew/dimension.cpp index ab07b66fdb..819c1a3110 100644 --- a/pcbnew/dimension.cpp +++ b/pcbnew/dimension.cpp @@ -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 ); diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index b0d1d01a56..43d96d11d1 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -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; } } diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index e031cdc20a..f2daee5b95 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -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 diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp index 870e9e710a..14843623a1 100644 --- a/pcbnew/edgemod.cpp +++ b/pcbnew/edgemod.cpp @@ -1,10 +1,10 @@ /* * 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 - * Copyright (C) 2012 Wayne Stambaugh - * 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 + * Copyright (C) 2013 Wayne Stambaugh + * 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(); + } } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index ae445f1d8b..2007d3d1e6 100755 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -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; diff --git a/pcbnew/hotkeys.cpp b/pcbnew/hotkeys.cpp index ff10c1945d..014157a579 100644 --- a/pcbnew/hotkeys.cpp +++ b/pcbnew/hotkeys.cpp @@ -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, diff --git a/pcbnew/hotkeys.h b/pcbnew/hotkeys.h index 9e2c1fa5d1..48b391e03a 100644 --- a/pcbnew/hotkeys.h +++ b/pcbnew/hotkeys.h @@ -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, diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index 5f961d5e28..fdde78ef48 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -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 -\ . diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index 53703e3166..5c79ce4962 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -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; } diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index 44545393cf..1923608adb 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -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" ) ); } } diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index 7ca2e561d6..7d698a9718 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -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, diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp index fc8ebc10e1..7c78aef832 100644 --- a/pcbnew/sel_layer.cpp +++ b/pcbnew/sel_layer.cpp @@ -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 m_layersIdLeftColumn; std::vector 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 ); } diff --git a/pcbnew/swap_layers.cpp b/pcbnew/swap_layers.cpp index 545c063770..10847c99c5 100644 --- a/pcbnew/swap_layers.cpp +++ b/pcbnew/swap_layers.cpp @@ -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" ) );