Fix Bug #1527446 (Flipping a block in pcbnew doesn't flip inner layers nor their connected microvias).

Also fix a few typos and remove dead code.
This commit is contained in:
jean-pierre charras 2015-12-27 16:51:13 +01:00
parent c4ea4dc0df
commit 9d994663f1
14 changed files with 108 additions and 58 deletions

View File

@ -101,14 +101,14 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
m_modal_resultant_parent = aResultantFocusWindow; m_modal_resultant_parent = aResultantFocusWindow;
Show( true ); Show( true );
Raise(); // Needed on sole Window managers to always display the frame Raise(); // Needed on some Window managers to always display the frame
SetFocus(); SetFocus();
{ {
// We have to disable all frames but the the modal one. // We have to disable all frames but the the modal one.
// wxWindowDisabler does that, but remember it disables all top level windows // wxWindowDisabler does that, but it also disables all top level windows
// We do not want to disable top level windows which are child off the modal one, // We do not want to disable top level windows which are child of the modal one,
// if they are enabled. // if they are enabled.
// An example is an aui toolbar which was moved // An example is an aui toolbar which was moved
// or a dialog or an other frame or miniframe opened by the modal one. // or a dialog or an other frame or miniframe opened by the modal one.
@ -121,16 +121,16 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
// exception safe way to disable all top level windows except the modal one, // exception safe way to disable all top level windows except the modal one,
// re-enables only those that were disabled on exit // re-enables only those that were disabled on exit
wxWindowDisabler toggle( this ); wxWindowDisabler toggle( this );
for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ ) for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
enabledTopLevelWindows[ii]->Enable( true ); enabledTopLevelWindows[ii]->Enable( true );
WX_EVENT_LOOP event_loop; WX_EVENT_LOOP event_loop;
m_modal_loop = &event_loop; m_modal_loop = &event_loop;
event_loop.Run(); event_loop.Run();
} // End of scop for some variables. } // End of scope for some variables.
// End nesting before setting focus below. // End nesting before setting focus below.
if( aResult ) if( aResult )

View File

@ -441,7 +441,7 @@ LSEQ LSET::SeqStackupBottom2Top() const
} }
LAYER_ID FlipLayer( LAYER_ID aLayerId ) LAYER_ID FlipLayer( LAYER_ID aLayerId, int aCopperLayersCount )
{ {
switch( aLayerId ) switch( aLayerId )
{ {
@ -466,14 +466,28 @@ LAYER_ID FlipLayer( LAYER_ID aLayerId )
case B_Fab: return F_Fab; case B_Fab: return F_Fab;
case F_Fab: return B_Fab; case F_Fab: return B_Fab;
// No change for the other layers default: // change internal layer if aCopperLayersCount is >= 4
default: if( IsCopperLayer( aLayerId ) && aCopperLayersCount >= 4 )
{
// internal copper layers count is aCopperLayersCount-2
LAYER_ID fliplayer = LAYER_ID(aCopperLayersCount - 2 - ( aLayerId - In1_Cu ) );
// Ensure fliplayer has a value which does not crash pcbnew:
if( fliplayer < F_Cu )
fliplayer = F_Cu;
if( fliplayer > B_Cu )
fliplayer = B_Cu;
return fliplayer;
}
// No change for the other layers
return aLayerId; return aLayerId;
} }
} }
LSET FlipLayerMask( LSET aMask ) LSET FlipLayerMask( LSET aMask, int aCopperLayersCount )
{ {
// layers on physical outside of a board: // layers on physical outside of a board:
const static LSET and_mask( 16, // !! update count const static LSET and_mask( 16, // !! update count
@ -537,6 +551,25 @@ LSET FlipLayerMask( LSET aMask )
if( aMask[F_Fab] ) if( aMask[F_Fab] )
newMask.set( B_Fab ); newMask.set( B_Fab );
if( aCopperLayersCount >= 4 ) // Internal layers exist
{
LSET internalMask = aMask & ~LSET::InternalCuMask();
if( internalMask != LSET::InternalCuMask() )
{ // the mask does not include all internal layers. Therefore
// the flipped mask for internal copper layers must be built
int innerLayerCnt = aCopperLayersCount -2;
for( int ii = 0; ii < innerLayerCnt; ii++ )
{
if( internalMask[innerLayerCnt - ii + In1_Cu] )
newMask.set( ii + In1_Cu );
else
newMask.reset( ii + In1_Cu );
}
}
}
return newMask; return newMask;
} }

View File

@ -878,8 +878,6 @@ bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
SCH_SHEET* SCH_SHEET_LIST::FindSheetByName( const wxString& aSheetName ) SCH_SHEET* SCH_SHEET_LIST::FindSheetByName( const wxString& aSheetName )
{ {
SCH_SHEET* sheet = NULL;
for( int i = 0; i < m_count; i++ ) for( int i = 0; i < m_count; i++ )
{ {
SCH_SHEET* sheet = m_list[i].FindSheetByName( aSheetName ); SCH_SHEET* sheet = m_list[i].FindSheetByName( aSheetName );

View File

@ -616,16 +616,24 @@ inline bool IsBackLayer( LAYER_ID aLayerId )
/** /**
* Function FlippedLayerNumber * Function FlippedLayerNumber
* @return the layer number after flipping an item * @return the layer number after flipping an item
* some (not all) layers: external copper, Mask, Paste, and solder * some (not all) layers: external copper, and paired layers( Mask, Paste, solder ... )
* are swapped between front and back sides * are swapped between front and back sides
* internal layers are flipped only if the copper layers count is known
* @param aLayer = the LAYER_ID to flip
* @param aCopperLayersCount = the number of copper layers. if 0 (in fact if < 4 )
* internal layers will be not flipped because the layer count is not known
*/ */
LAYER_ID FlipLayer( LAYER_ID oldlayer ); LAYER_ID FlipLayer( LAYER_ID aLayerId, int aCopperLayersCount = 0 );
/** /**
* Calculate the mask layer when flipping a footprint * Calculate the mask layer when flipping a footprint
* BACK and FRONT copper layers, mask, paste, solder layers are swapped * BACK and FRONT copper layers, mask, paste, solder layers are swapped
* internal layers are flipped only if the copper layers count is known
* @param aMask = the LSET to flip
* @param aCopperLayersCount = the number of copper layers. if 0 (in fact if < 4 )
* internal layers will be not flipped because the layer count is not known
*/ */
LSET FlipLayerMask( LSET aMask ); LSET FlipLayerMask( LSET aMask, int aCopperLayersCount = 0 );
/** /**
* Return a string (to be shown to the user) describing a layer mask. * Return a string (to be shown to the user) describing a layer mask.

View File

@ -752,6 +752,7 @@ void PCB_EDIT_FRAME::Block_Flip()
itemsList->SetPickedItemStatus( UR_FLIPPED, ii ); itemsList->SetPickedItemStatus( UR_FLIPPED, ii );
item->Flip( center ); item->Flip( center );
// If a connected item is flipped, the ratsnest is no more OK
switch( item->Type() ) switch( item->Type() )
{ {
case PCB_MODULE_T: case PCB_MODULE_T:
@ -759,9 +760,8 @@ void PCB_EDIT_FRAME::Block_Flip()
m_Pcb->m_Status_Pcb = 0; m_Pcb->m_Status_Pcb = 0;
break; break;
// Move and rotate the track segments case PCB_TRACE_T:
case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T:
case PCB_VIA_T: // a via (like track segment on a copper layer)
m_Pcb->m_Status_Pcb = 0; m_Pcb->m_Status_Pcb = 0;
break; break;

View File

@ -161,6 +161,9 @@ void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle )
void DIMENSION::Flip( const wxPoint& aCentre ) void DIMENSION::Flip( const wxPoint& aCentre )
{ {
Mirror( aCentre ); Mirror( aCentre );
// DIMENSION items are not usually on copper layers, so
// copper layers count is not taken in accoun in Flip transform
SetLayer( FlipLayer( GetLayer() ) ); SetLayer( FlipLayer( GetLayer() ) );
} }

View File

@ -138,6 +138,8 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
if( m_Shape == S_ARC ) if( m_Shape == S_ARC )
m_Angle = -m_Angle; m_Angle = -m_Angle;
// DRAWSEGMENT items are not allowed on copper layers, so
// copper layers count is not taken in accoun in Flip transform
SetLayer( FlipLayer( GetLayer() ) ); SetLayer( FlipLayer( GetLayer() ) );
} }

View File

@ -318,6 +318,10 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre )
MIRROR( m_PolyPoints[ii].y, 0 ); MIRROR( m_PolyPoints[ii].y, 0 );
} }
// DRAWSEGMENT items are not usually on copper layers, but
// it can happen in microwave apps.
// However, currently, only on Front or Back layers.
// So the copper layers count is not taken in account
SetLayer( FlipLayer( GetLayer() ) ); SetLayer( FlipLayer( GetLayer() ) );
} }

View File

@ -292,6 +292,9 @@ void D_PAD::Flip( const wxPoint& aCentre )
SetOrientation( -GetOrientation() ); SetOrientation( -GetOrientation() );
// flip pads layers // flip pads layers
// PADS items are currently on all copper layers, or
// currently, only on Front or Back layers.
// So the copper layers count is not taken in account
SetLayerSet( FlipLayerMask( m_layerMask ) ); SetLayerSet( FlipLayerMask( m_layerMask ) );
// m_boundingRadius = -1; the shape has not been changed // m_boundingRadius = -1; the shape has not been changed
@ -335,16 +338,11 @@ const wxPoint D_PAD::ShapePos() const
if( m_Offset.x == 0 && m_Offset.y == 0 ) if( m_Offset.x == 0 && m_Offset.y == 0 )
return m_Pos; return m_Pos;
wxPoint shape_pos; wxPoint loc_offset = m_Offset;
int dX, dY;
dX = m_Offset.x; RotatePoint( &loc_offset, m_Orient );
dY = m_Offset.y;
RotatePoint( &dX, &dY, m_Orient ); wxPoint shape_pos = m_Pos + loc_offset;
shape_pos.x = m_Pos.x + dX;
shape_pos.y = m_Pos.y + dY;
return shape_pos; return shape_pos;
} }
@ -352,26 +350,10 @@ const wxPoint D_PAD::ShapePos() const
const wxString D_PAD::GetPadName() const const wxString D_PAD::GetPadName() const
{ {
#if 0 // m_Padname is not ASCII and not UTF8, it is LATIN1 basically, whatever
// 8 bit font is supported in KiCad plotting and drawing.
// Return pad name as wxString, assume it starts as a non-terminated
// utf8 character sequence
char temp[sizeof(m_Padname)+1]; // a place to terminate with '\0'
strncpy( temp, m_Padname, sizeof(m_Padname) );
temp[sizeof(m_Padname)] = 0;
return FROM_UTF8( temp );
#else
wxString name; wxString name;
StringPadName( name ); StringPadName( name );
return name; return name;
#endif
} }
@ -988,7 +970,7 @@ unsigned int D_PAD::ViewGetLOD( int aLayer ) const
if( ( m_Size.x == 0 ) && ( m_Size.y == 0 ) ) if( ( m_Size.x == 0 ) && ( m_Size.y == 0 ) )
return UINT_MAX; return UINT_MAX;
return ( 100000000 / std::max( m_Size.x, m_Size.y ) ); return ( Millimeter2iu( 100 ) / std::max( m_Size.x, m_Size.y ) );
} }
// Other layers are shown without any conditions // Other layers are shown without any conditions

View File

@ -179,7 +179,8 @@ void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
void TEXTE_PCB::Flip(const wxPoint& aCentre ) void TEXTE_PCB::Flip(const wxPoint& aCentre )
{ {
m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y ); m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y );
SetLayer( FlipLayer( GetLayer() ) ); int copperLayerCount = GetBoard()->GetCopperLayerCount();
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
m_Mirror = !m_Mirror; m_Mirror = !m_Mirror;
} }

View File

@ -339,7 +339,8 @@ void TRACK::Flip( const wxPoint& aCentre )
{ {
m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
m_End.y = aCentre.y - (m_End.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y);
SetLayer( FlipLayer( GetLayer() ) ); int copperLayerCount = GetBoard()->GetCopperLayerCount();
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
} }
@ -347,6 +348,17 @@ void VIA::Flip( const wxPoint& aCentre )
{ {
m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
m_End.y = aCentre.y - (m_End.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y);
if( GetViaType() != VIA_THROUGH )
{
int copperLayerCount = GetBoard()->GetCopperLayerCount();
LAYER_ID top_layer;
LAYER_ID bottom_layer;
LayerPair( &top_layer, &bottom_layer );
top_layer = FlipLayer( top_layer, copperLayerCount );
bottom_layer = FlipLayer( bottom_layer, copperLayerCount );
SetLayerPair( top_layer, bottom_layer );
}
} }

View File

@ -722,7 +722,8 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
void ZONE_CONTAINER::Flip( const wxPoint& aCentre ) void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
{ {
Mirror( aCentre ); Mirror( aCentre );
SetLayer( FlipLayer( GetLayer() ) ); int copperLayerCount = GetBoard()->GetCopperLayerCount();
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
} }
@ -852,4 +853,4 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const
GetChars( GetLayerName() ) ); GetChars( GetLayerName() ) );
return msg; return msg;
} }

View File

@ -275,7 +275,7 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
{ {
dim = m_dummyPad->GetDrillSize().y; dim = m_dummyPad->GetDrillSize().y;
if( dim == 0 ) if( dim == 0 )
dim = 1000000; dim = Millimeter2iu( 0.1 );
} }
if( m_dummyPad->GetLocalClearance() > 0 ) if( m_dummyPad->GetLocalClearance() > 0 )
@ -731,6 +731,7 @@ void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
bool DIALOG_PAD_PROPERTIES::padValuesOK() bool DIALOG_PAD_PROPERTIES::padValuesOK()
{ {
bool error = transferDataToPad( m_dummyPad ); bool error = transferDataToPad( m_dummyPad );
bool skip_tstoffset = false; // the offset prm is not always tested
wxArrayString error_msgs; wxArrayString error_msgs;
wxString msg; wxString msg;
@ -746,6 +747,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
(m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) ) (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
{ {
error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) ); error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
skip_tstoffset = true; // offset prm will be not tested because if the drill value
// is incorrect the offset prm is always seen as incorrect, even if it is 0
} }
LSET padlayers_mask = m_dummyPad->GetLayerSet(); LSET padlayers_mask = m_dummyPad->GetLayerSet();
@ -772,16 +775,19 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
} }
} }
wxPoint max_size; if( !skip_tstoffset )
max_size.x = std::abs( m_dummyPad->GetOffset().x );
max_size.y = std::abs( m_dummyPad->GetOffset().y );
max_size.x += m_dummyPad->GetDrillSize().x / 2;
max_size.y += m_dummyPad->GetDrillSize().y / 2;
if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
( m_dummyPad->GetSize().y / 2 < max_size.y ) )
{ {
error_msgs.Add( _( "Incorrect value for pad offset" ) ); wxPoint max_size;
max_size.x = std::abs( m_dummyPad->GetOffset().x );
max_size.y = std::abs( m_dummyPad->GetOffset().y );
max_size.x += m_dummyPad->GetDrillSize().x / 2;
max_size.y += m_dummyPad->GetDrillSize().y / 2;
if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
( m_dummyPad->GetSize().y / 2 < max_size.y ) )
{
error_msgs.Add( _( "Incorrect value for pad offset" ) );
}
} }
if( error ) if( error )

View File

@ -244,7 +244,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
HK_CANVAS_LEGACY ); HK_CANVAS_LEGACY );
AddMenuItem( viewMenu, ID_MENU_CANVAS_LEGACY, AddMenuItem( viewMenu, ID_MENU_CANVAS_LEGACY,
text, _( "Switch the canvas implementation to legacy" ), text, _( "Switch the canvas implementation to Legacy" ),
KiBitmap( tools_xpm ) ); KiBitmap( tools_xpm ) );
text = AddHotkeyName( _( "Switch Canvas to Open&GL" ), m_hotkeysDescrList, text = AddHotkeyName( _( "Switch Canvas to Open&GL" ), m_hotkeysDescrList,