Compare commits

...

37 Commits

Author SHA1 Message Date
Rohan Agrawal bff0068065 Merge lp:~rohbotics/kicad/bug_1424003 into lp:kicad 2016-02-13 15:23:08 -05:00
unknown d0932944fc Fix long text values truncated in position file and serious cleanup of gen_modules_placefile.cpp code. (fixes lp:1412628) 2016-02-13 15:20:59 -05:00
Tomasz Wlostowski 5c3a56bdcc Fixed segfault in selection tool. (fixes lp:1542856) 2016-02-13 15:15:15 -05:00
jean-pierre charras e9bfcc28c3 Fix HPGL plot divide by zero bug. 2016-02-11 19:12:06 -05:00
Maciej Suminski 3cdac44ac2 GAL::DrawPolygon() and GAL::DrawPolyline() variants that work with VECTOR2D array. 2016-02-11 19:05:24 -05:00
jean-pierre charras 2cebaa2d79 3D Viewer: fix no solder mask unless there is something on the layer. (fixes lp:542935) 2016-02-10 20:47:34 -05:00
jean-pierre charras 609b996abe Pcbnew: zone keepout incorrectly created if previously a corner-smoothed copper zone was created. (fixes lp:1540967) 2016-02-10 20:21:26 -05:00
Simon Richter ea0c187e09 Executable icon resource build configuration fixes.
* The resource setting for bitmap2component is too late in the CMakeLists.txt,
  and is being ignored. Bitmap2component does not have an icon resource on
  Windows. Moving the entire section resolves the issue.
* The other programs only have the mingw special case listed, not the generic
  declaration for the resource file so added them.
2016-02-10 20:14:35 -05:00
jean-pierre charras bf6cd8445a Page layout editor: custom text size not saved when X or Y size value is not default. (fixes lp:1538603) 2016-02-10 20:12:16 -05:00
Chris Pavlina c50763bd5b libedit: fix iterator off end of vector (fixes lp:1537946) 2016-02-09 19:04:36 -05:00
Andrew Zonenberg 1aa6932b12 Pcbnew DRC: allow technical->copper pad overlap
* This permits things like mask "pads" over copper pads for custom mask openings.
2016-02-09 18:59:56 -05:00
Maciej Suminski 342ec2be0e Highlight a net when crossprobing with eeschema and highlight net tool is enabled. 2016-02-09 18:57:46 -05:00
Martin d'Allens d451800d0a Eeschema: Set modified flag after "Append Schematic Sheet" 2016-02-09 18:56:10 -05:00
jean-pierre charras 48435c5cb3 Fix bug in "User Custom" size selection in"Page Settings" in non English languages. (fixes lp:1536427) 2016-02-09 18:41:47 -05:00
Maciej Suminski 8999ae9fb2 Make DRC markers not editable with the standard tools (GAL). 2016-02-09 18:38:26 -05:00
Maciej Suminski 8184ba1cf3 Draw arrows for DRC markers (GAL). 2016-02-09 18:36:43 -05:00
Simon Wells 228ed4ea41 GAL: Update grid color when changed by user 2016-02-09 18:34:16 -05:00
Chris Pavlina 3031a3f5cf Pcbnew: fix Flip hotkey for blocks in legacy (fixes lp:1534120) 2016-02-09 18:31:39 -05:00
Tomasz Wlostowski 42aa93e34b GAL: apply grid offset when board is loaded and respect grid color setting. (fixes lp:1533168) 2016-02-09 18:27:13 -05:00
Tomasz Wlostowski eb8b407717 Router: check layers of all traversed joints in FindLinesBetweenJoints(). (fixes lp:1531762) 2016-02-08 21:28:22 -05:00
Johannes Agricola eaea15fbef Properly set keepout flag for new zones in GAL 2016-02-08 21:26:03 -05:00
Maciej Suminski 72a69f9428 pcbnew asks before rotating/flipping a locked item (GAL). 2016-02-08 20:06:22 -05:00
Simon Wells c66656c5d4 Open PDF viewer improvements. (fixes lp:1530162)
* Fix broken ExecuteCommand() when path contains spaces on OSX.
* Only use system defined mime type for PDF files.
* Remove system dependent fallback applications for opening PDF files.
2016-02-08 20:03:57 -05:00
Element Green 14363262c2 Pcbnew: fix VRML export dialog settings having no effect. (fixes lp:1529214) 2016-02-08 19:58:21 -05:00
Jean-Pierre Charras 509e71fdb3 Pcbnew: fix bug when flipping a block that dosesn't flip inner layers nor their connected microvias. (fixes lp:1527446) 2016-02-08 19:16:07 -05:00
Jean-Pierre Charras 6c5e2f3900 Pcbnew: avoid crash if something is wrong when opening the Python Console (for instance missing python module). 2016-02-07 19:38:08 -05:00
Chris Pavlina f46272bed9 Pcbnew: fix zone tool bug when minimum width is compared against thermal relief spoke when Pad connection set to none. (fixes lp 1526158) 2016-02-07 19:35:43 -05:00
Jean-Pierre Charras 2f7b3ab56e Eeschema: fix segfault when loading malformed libraries. (fixes lp:1527804) 2015-12-20 16:46:33 -05:00
Maciej Suminski b526227529 Fixed crash on undo pad placement in the footprint editor using GAL canvases. (fixes lp:1525552) 2015-12-15 10:22:49 -05:00
Maciej Suminski e93c815e02 Fixed ratsnest for PCBs imported using plugins (GAL). 2015-12-15 10:16:15 -05:00
Mark Roszko 5c8f7c7a3a Use defined environment variables before falling back to DEFAULT_INSTALL_PATH. 2015-12-09 09:46:56 -05:00
Jean-Pierre Charras 7fb6698e29 Kicad manager: fix a potential bug which could crash Kicad manager. 2015-12-07 09:55:59 -05:00
Jean-Pierre Charras f11b426151 Better sizing of wx_html_report_panel in dialog_netlist (fix bug #1522758) 2015-12-06 18:24:32 -05:00
Maciej Suminski 827dad3197 GAL bug fixes cherry picked from product branch. 2015-12-06 18:22:13 -05:00
Wayne Stambaugh 593c974063 One last update before 4.0.0 stable release. 2015-11-29 14:53:12 -05:00
Wayne Stambaugh a68b3cb486 Merge with tip of product branch for 4.0.0 stable release. 2015-11-29 14:06:50 -05:00
Wayne Stambaugh ce81524b83 Merge with tip of product branch r6303, 4.0.0-rc1. 2015-11-08 16:22:19 -05:00
66 changed files with 811 additions and 662 deletions
+4 -1
View File
@@ -572,7 +572,10 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
// bufferPolys contains polygons to merge. Many overlaps .
// Calculate merged polygons and remove pads and vias holes
if( bufferPolys.IsEmpty() )
if( layer != B_Mask && layer != F_Mask && bufferPolys.IsEmpty() )
// if a layer has no iten to draw, skip it
// However solder mask layers are negative layers, so no item
// means only a full layer mask
continue;
// Solder mask layers are "negative" layers.
+7 -8
View File
@@ -21,6 +21,13 @@ set_source_files_properties( bitmap2cmp_gui.cpp PROPERTIES
COMPILE_DEFINITIONS "COMPILING_DLL"
)
if( MINGW )
# BITMAP2COMPONENT_RESOURCES variable is set by the macro.
mingw_resource_compiler( bitmap2component )
else()
set( BITMAP2COMPONENT_RESOURCES bitmap2component.rc )
endif()
if( APPLE )
# setup bundle
set( BITMAP2COMPONENT_RESOURCES bitmap2component.icns )
@@ -81,11 +88,3 @@ if( false ) # linker map with cross reference
LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=bitmap2component.map"
)
endif()
if( MINGW )
# BITMAP2COMPONENT_RESOURCES variable is set by the macro.
mingw_resource_compiler( bitmap2component )
else()
set( BITMAP2COMPONENT_RESOURCES bitmap2component.rc )
endif()
-30
View File
@@ -89,36 +89,6 @@ const PAGE_INFO PAGE_INFO::pageUSLedger( wxSize( 17000, 11000 ), wxT( "USLedge
int PAGE_INFO::s_user_width = 17000;
int PAGE_INFO::s_user_height = 11000;
/*
wxArrayString PAGE_INFO::GetStandardSizes()
{
wxArrayString ret;
static const PAGE_INFO* stdPageSizes[] = {
&pageA4,
&pageA3,
&pageA2,
&pageA1,
&pageA0,
&pageA,
&pageB,
&pageC,
&pageD,
&pageE,
// &pageGERBER, // standard?
&pageUSLetter,
&pageUSLegal,
&pageUSLedger,
&pageUser,
};
for( unsigned i=0; i < DIM( stdPageSizes ); ++i )
ret.Add( stdPageSizes[i]->GetType() );
return ret;
}
*/
inline void PAGE_INFO::updatePortrait()
{
+6 -3
View File
@@ -223,8 +223,6 @@ void HPGL_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
paperSize.y *= 10.0 * aIusPerDecimil;
SetDefaultLineWidth( 0 ); // HPGL has pen sizes instead
m_plotMirror = aMirror;
penOverlap = 0;
penDiameter = 0;
}
@@ -685,7 +683,12 @@ void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorne
}
// Calculation of dd = number of segments was traced to fill.
jj = jj / (int) ( penDiameter - penOverlap );
int delta = (int) ( penDiameter - penOverlap );
if( delta )
jj = jj / delta;
else
jj = 0;
// Trace the outline.
for( ; jj > 0; jj-- )
+19 -16
View File
@@ -52,26 +52,29 @@
// List of page formats.
// should be statically initialized, because we need both
// the translated and the not translated version.
// they are prefixed by "_HKI" (already in use for hotkeys) instead of "_",
// because we need both the translated and the not translated version.
// when displayed in dialog we should explicitely call wxGetTranslation()
// to show the translated version.
// See hotkeys_basic.h for more info
#define _HKI( x ) wxT( x )
static const wxString pageFmts[] =
{
_("A4 210x297mm"),
_("A3 297x420mm"),
_("A2 420x594mm"),
_("A1 594x841mm"),
_("A0 841x1189mm"),
_("A 8.5x11in"),
_("B 11x17in"),
_("C 17x22in"),
_("D 22x34in"),
_("E 34x44in"),
_("USLetter 8.5x11in"), // USLetter without space is correct
_("USLegal 8.5x14in"), // USLegal without space is correct
_("USLedger 11x17in"), // USLedger without space is correct
_("User (Custom)"),
_HKI("A4 210x297mm"),
_HKI("A3 297x420mm"),
_HKI("A2 420x594mm"),
_HKI("A1 594x841mm"),
_HKI("A0 841x1189mm"),
_HKI("A 8.5x11in"),
_HKI("B 11x17in"),
_HKI("C 17x22in"),
_HKI("D 22x34in"),
_HKI("E 34x44in"),
_HKI("USLetter 8.5x11in"), // USLetter without space is correct
_HKI("USLegal 8.5x14in"), // USLegal without space is correct
_HKI("USLedger 11x17in"), // USLedger without space is correct
_HKI("User (Custom)"), // size defined by user. The string must contain "Custom"
// to be reconized in code
};
void EDA_DRAW_FRAME::Process_PageSettings( wxCommandEvent& event )
+7
View File
@@ -45,6 +45,13 @@ WX_HTML_REPORT_PANEL::~WX_HTML_REPORT_PANEL()
}
void WX_HTML_REPORT_PANEL::MsgPanelSetMinSize( const wxSize& aMinSize )
{
m_htmlView->SetMinSize( aMinSize );
GetSizer()->SetSizeHints( this );
}
REPORTER& WX_HTML_REPORT_PANEL::Reporter()
{
return m_reporter;
+3
View File
@@ -46,6 +46,9 @@ public:
const wxSize& size = wxSize( 500,300 ), long style = wxTAB_TRAVERSAL );
~WX_HTML_REPORT_PANEL();
///> Set the min size of the area which displays html messages:
void MsgPanelSetMinSize( const wxSize& aMinSize );
///> returns the reporter object that reports to this panel
REPORTER& Reporter();
+3
View File
@@ -147,6 +147,9 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_gal->BeginDrawing();
m_gal->ClearScreen( m_painter->GetSettings()->GetBackgroundColor() );
KIGFX::COLOR4D gridColor = static_cast<KIGFX::PCB_RENDER_SETTINGS*> (m_painter->GetSettings())->GetLayerColor( ITEM_GAL_LAYER ( GRID_VISIBLE ) );
m_gal->SetGridColor ( gridColor );
if( m_view->IsDirty() )
{
m_view->ClearTargets();
+33 -32
View File
@@ -257,38 +257,6 @@ void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
}
void CAIRO_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
{
// Iterate over the point list and draw the segments
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
cairo_move_to( currentContext, it->x, it->y );
for( ++it; it != aPointList.end(); ++it )
{
cairo_line_to( currentContext, it->x, it->y );
}
isElementAdded = true;
}
void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
{
// Iterate over the point list and draw the polygon
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
cairo_move_to( currentContext, it->x, it->y );
for( ++it; it != aPointList.end(); ++it )
{
cairo_line_to( currentContext, it->x, it->y );
}
isElementAdded = true;
}
void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
{
@@ -1059,6 +1027,39 @@ void CAIRO_GAL::setCompositor()
}
void CAIRO_GAL::drawPoly( const std::deque<VECTOR2D>& aPointList )
{
// Iterate over the point list and draw the segments
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
cairo_move_to( currentContext, it->x, it->y );
for( ++it; it != aPointList.end(); ++it )
{
cairo_line_to( currentContext, it->x, it->y );
}
isElementAdded = true;
}
void CAIRO_GAL::drawPoly( const VECTOR2D aPointList[], int aListSize )
{
// Iterate over the point list and draw the segments
const VECTOR2D* ptr = aPointList;
cairo_move_to( currentContext, ptr->x, ptr->y );
for( int i = 0; i < aListSize; ++i )
{
++ptr;
cairo_line_to( currentContext, ptr->x, ptr->y );
}
isElementAdded = true;
}
unsigned int CAIRO_GAL::getNewGroupNumber()
{
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
+64 -5
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Graphics Abstraction Layer (GAL) for OpenGL
@@ -358,7 +358,7 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
SWAP( aStartAngle, >, aEndAngle );
Save();
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, layerDepth );
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0 );
if( isStrokeEnabled )
{
@@ -448,7 +448,7 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
}
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
void OPENGL_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
{
if( aPointList.empty() )
return;
@@ -476,19 +476,43 @@ void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
}
void OPENGL_GAL::DrawPolyline( const VECTOR2D aPointList[], int aListSize )
{
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
// Start from the second point
for( int i = 1; i < aListSize; ++i )
{
const VECTOR2D startEndVector = ( aPointList[i] - aPointList[i - 1] );
double lineAngle = startEndVector.Angle();
drawLineQuad( aPointList[i - 1], aPointList[i] );
// There is no need to draw line caps on both ends of polyline's segments
drawFilledSemiCircle( aPointList[i - 1], lineWidth / 2, lineAngle + M_PI / 2 );
}
// ..and now - draw the ending cap
const VECTOR2D startEndVector = ( aPointList[aListSize - 1] - aPointList[aListSize - 2] );
double lineAngle = startEndVector.Angle();
drawFilledSemiCircle( aPointList[aListSize - 1], lineWidth / 2, lineAngle - M_PI / 2 );
}
void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
{
// Any non convex polygon needs to be tesselated
// for this purpose the GLU standard functions are used
currentManager->Shader( SHADER_NONE );
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
// Any non convex polygon needs to be tesselated
// for this purpose the GLU standard functions are used
TessParams params = { currentManager, tessIntersects };
gluTessBeginPolygon( tesselator, &params );
gluTessBeginContour( tesselator );
boost::shared_array<GLdouble> points( new GLdouble[3 * aPointList.size()] );
int v = 0;
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it )
{
points[v] = it->x;
@@ -508,6 +532,41 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
}
void OPENGL_GAL::DrawPolygon( const VECTOR2D aPointList[], int aListSize )
{
currentManager->Shader( SHADER_NONE );
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
// Any non convex polygon needs to be tesselated
// for this purpose the GLU standard functions are used
TessParams params = { currentManager, tessIntersects };
gluTessBeginPolygon( tesselator, &params );
gluTessBeginContour( tesselator );
boost::shared_array<GLdouble> points( new GLdouble[3 * aListSize] );
int v = 0;
const VECTOR2D* ptr = aPointList;
for( int i = 0; i < aListSize; ++i )
{
points[v] = ptr->x;
points[v + 1] = ptr->y;
points[v + 2] = layerDepth;
gluTessVertex( tesselator, &points[v], &points[v] );
++ptr;
v += 3;
}
gluTessEndContour( tesselator );
gluTessEndPolygon( tesselator );
// Free allocated intersecting points
tessIntersects.clear();
// vertexList destroyed here
}
void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
{
+22 -80
View File
@@ -28,33 +28,26 @@
* @brief Functions for file management
*/
// For compilers that support precompilation, includes "wx.h".
#include <fctsys.h>
#include <pgm_base.h>
#include <confirm.h>
#include <common.h>
#include <macros.h>
#include <gestfich.h>
#include <wx/mimetype.h>
#include <wx/filename.h>
#include <wx/dir.h>
// For compilers that support precompilation, includes "wx.h".
#include <fctsys.h>
#include <pgm_base.h>
#include <confirm.h>
#include <common.h>
#include <macros.h>
#include <gestfich.h>
void AddDelimiterString( wxString& string )
{
wxString text;
if( !string.StartsWith( wxT( "\"" ) ) )
text = wxT( "\"" );
text += string;
if( (text.Last() != '"' ) || (text.length() <= 1) )
text += wxT( "\"" );
string = text;
{
string.Prepend ( wxT( "\"" ) );
string.Append ( wxT( "\"" ) );
}
}
@@ -227,6 +220,8 @@ int ExecuteFile( wxWindow* frame, const wxString& ExecFile, const wxString& para
#ifdef __WXMAC__
else
{
AddDelimiterString( fullFileName );
if( !param.IsEmpty() )
fullFileName += wxT( " " ) + param;
@@ -351,8 +346,6 @@ bool OpenPDF( const wxString& file )
{
wxString command;
wxString filename = file;
wxString type;
bool success = false;
Pgm().ReadPdfBrowserInfos();
@@ -363,71 +356,21 @@ bool OpenPDF( const wxString& file )
}
else
{
wxFileType* filetype = NULL;
wxFileType::MessageParameters params( filename, type );
filetype = wxTheMimeTypesManager->GetFileTypeFromExtension( wxT( "pdf" ) );
wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension( wxT( "pdf" ) );
if( filetype )
success = filetype->GetOpenCommand( &command, params );
command = filetype->GetOpenCommand( filename );
delete filetype;
#ifndef __WINDOWS__
// Bug ? under linux wxWidgets returns acroread as PDF viewer, even if
// it does not exist.
if( command.StartsWith( wxT( "acroread" ) ) ) // Workaround
success = false;
#endif
if( success && !command.IsEmpty() )
{
success = ProcessExecute( command );
if( success )
return success;
}
success = false;
command.clear();
if( !success )
{
#if !defined(__WINDOWS__)
AddDelimiterString( filename );
// here is a list of PDF viewers candidates
static const wxChar* tries[] =
{
wxT( "/usr/bin/evince" ),
wxT( "/usr/bin/okular" ),
wxT( "/usr/bin/gpdf" ),
wxT( "/usr/bin/konqueror" ),
wxT( "/usr/bin/kpdf" ),
wxT( "/usr/bin/xpdf" ),
wxT( "/usr/bin/open" ), // BSD and OSX file & dir opener
wxT( "/usr/bin/xdg-open" ), // Freedesktop file & dir opener
};
for( unsigned ii = 0; ii<DIM(tries); ii++ )
{
if( wxFileExists( tries[ii] ) )
{
command = tries[ii];
command += wxT( ' ' );
command += filename;
break;
}
}
#endif
}
}
if( !command.IsEmpty() )
{
success = ProcessExecute( command );
if( !success )
if( ProcessExecute( command ) )
{
return true;
}
else
{
wxString msg;
msg.Printf( _( "Problem while running the PDF viewer\nCommand is '%s'" ),
@@ -440,10 +383,9 @@ bool OpenPDF( const wxString& file )
wxString msg;
msg.Printf( _( "Unable to find a PDF viewer for <%s>" ), GetChars( filename ) );
DisplayError( NULL, msg );
success = false;
}
return success;
return false;
}
+1 -1
View File
@@ -212,7 +212,7 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
if( ! wxFileExists( dname ) )
msg << wxT( "It is missing.\n" );
else
msg << wxT( "Perhaps a wxWidgets shared (.dll or .so) file is missing.\n" );
msg << wxT( "Perhaps a shared library (.dll or .so) file is missing.\n" );
msg << wxT( "From command line: argv[0]:\n'" );
msg << wxStandardPaths::Get().GetExecutablePath() << wxT( "'\n" );
+6 -7
View File
@@ -101,14 +101,14 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
m_modal_resultant_parent = aResultantFocusWindow;
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();
{
// We have to disable all frames but the the modal one.
// wxWindowDisabler does that, but remember it disables all top level windows
// We do not want to disable top level windows which are child off the modal one,
// wxWindowDisabler does that, but it also disables all top level windows
// We do not want to disable top level windows which are child of the modal one,
// if they are enabled.
// An example is an aui toolbar which was moved
// or a dialog or an other frame or miniframe opened by the modal one.
@@ -119,19 +119,18 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
enabledTopLevelWindows.push_back( wlist[ii] );
// exception safe way to disable all top level windows except the modal one,
// re-enables only those that were disabled on exit
wxWindowDisabler toggle( this );
wxWindowDisabler toggle( this );
for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
enabledTopLevelWindows[ii]->Enable( true );
enabledTopLevelWindows[ii]->Enable( true );
WX_EVENT_LOOP event_loop;
m_modal_loop = &event_loop;
event_loop.Run();
} // End of scop for some variables.
} // End of scope for some variables.
// End nesting before setting focus below.
if( aResult )
+37 -4
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 )
{
@@ -466,14 +466,28 @@ LAYER_ID FlipLayer( LAYER_ID aLayerId )
case B_Fab: return F_Fab;
case F_Fab: return B_Fab;
// No change for the other layers
default:
default: // change internal layer if aCopperLayersCount is >= 4
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;
}
}
LSET FlipLayerMask( LSET aMask )
LSET FlipLayerMask( LSET aMask, int aCopperLayersCount )
{
// layers on physical outside of a board:
const static LSET and_mask( 16, // !! update count
@@ -537,6 +551,25 @@ LSET FlipLayerMask( LSET aMask )
if( aMask[F_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;
}
+40 -11
View File
@@ -416,6 +416,8 @@ bool PGM_BASE::initPgm()
{
wxString envVarName = wxT( "KIGITHUB" );
ENV_VAR_ITEM envVarItem;
wxString envValue;
wxFileName tmpFileName;
envVarItem.SetValue( wxString( wxT( "https://github.com/KiCad" ) ) );
envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) );
@@ -429,24 +431,51 @@ bool PGM_BASE::initPgm()
baseSharePath.AppendDir( wxT( "kicad" ) );
#endif
wxFileName tmpFileName = baseSharePath;
tmpFileName.AppendDir( wxT( "modules" ) );
// KISYSMOD
envVarName = wxT( "KISYSMOD" );
envVarItem.SetValue( tmpFileName.GetPath() );
envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) );
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
{
tmpFileName.AssignDir( envValue );
envVarItem.SetDefinedExternally( true );
}
else
{
tmpFileName = baseSharePath;
tmpFileName.AppendDir( wxT( "modules" ) );
envVarItem.SetDefinedExternally( false );
}
envVarItem.SetValue( tmpFileName.GetFullPath() );
m_local_env_vars[ envVarName ] = envVarItem;
// KISYS3DMOD
envVarName = wxT( "KISYS3DMOD" );
tmpFileName.AppendDir( wxT( "packages3d" ) );
envVarItem.SetValue( tmpFileName.GetPath() );
envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) );
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
{
tmpFileName.AssignDir( envValue );
envVarItem.SetDefinedExternally( true );
}
else
{
tmpFileName.AppendDir( wxT( "packages3d" ) );
envVarItem.SetDefinedExternally( false );
}
envVarItem.SetValue( tmpFileName.GetFullPath() );
m_local_env_vars[ envVarName ] = envVarItem;
// KICAD_PTEMPLATES
envVarName = wxT( "KICAD_PTEMPLATES" );
tmpFileName = baseSharePath;
tmpFileName.AppendDir( wxT( "template" ) );
envVarItem.SetValue( tmpFileName.GetPath() );
envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) );
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
{
tmpFileName.AssignDir( envValue );
envVarItem.SetDefinedExternally( true );
}
else
{
tmpFileName = baseSharePath;
tmpFileName.AppendDir( wxT( "template" ) );
envVarItem.SetDefinedExternally( false );
}
envVarItem.SetValue( tmpFileName.GetFullPath() );
m_local_env_vars[ envVarName ] = envVarItem;
}
+3 -1
View File
@@ -66,6 +66,8 @@ void TOOL_INTERACTIVE::goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIS
void TOOL_INTERACTIVE::SetContextMenu( CONTEXT_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger )
{
aMenu->SetTool( this );
if( aMenu )
aMenu->SetTool( this );
m_toolMgr->ScheduleContextMenu( this, aMenu, aTrigger );
}
+2
View File
@@ -56,6 +56,8 @@ set( CVPCB_SRCS
if( MINGW )
# CVPCB_RESOURCES variable is set by the macro.
mingw_resource_compiler( cvpcb )
else()
set( CVPCB_RESOURCES cvpcb.rc )
endif()
+2
View File
@@ -191,6 +191,8 @@ set( EESCHEMA_COMMON_SRCS
if( MINGW )
# EESCHEMA_RESOURCES variable is set by the macro.
mingw_resource_compiler( eeschema )
else()
set( EESCHEMA_RESOURCES eeschema.rc )
endif()
# Create a C++ compilable string initializer containing html text into a *.h file:
+15 -7
View File
@@ -886,7 +886,7 @@ bool LIB_PART::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
{
p = strtok( line, " \t\n" );
if( stricmp( p, "ENDDEF" ) == 0 )
if( p && stricmp( p, "ENDDEF" ) == 0 )
break;
}
@@ -948,6 +948,9 @@ bool LIB_PART::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
if( *line == '#' ) // a comment
continue;
if( p == NULL ) // empty line
continue;
if( line[0] == 'T' && line[1] == 'i' )
result = LoadDateAndTime( aLineReader );
else if( *line == 'F' )
@@ -1036,7 +1039,12 @@ bool LIB_PART::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorMsg )
break;
case '#': // Comment
continue;
continue;
case '\n':
case '\r':
case 0: // empty line
continue;
default:
aErrorMsg.Printf( wxT( "undefined DRAW command %c" ), line[0] );
@@ -1746,16 +1754,16 @@ void LIB_PART::SetAliases( const wxArrayString& aAliasList )
}
// Remove names in the current component that are not in the new alias list.
LIB_ALIASES::iterator it;
LIB_ALIASES::iterator it = m_aliases.begin();
for( it = m_aliases.begin(); it < m_aliases.end(); it++ )
while( it != m_aliases.end() )
{
int index = aAliasList.Index( (*it)->GetName(), false );
if( index != wxNOT_FOUND || (*it)->IsRoot() )
continue;
it = m_aliases.erase( it );
++it;
else
it = m_aliases.erase( it );
}
}
+2
View File
@@ -447,6 +447,8 @@ bool SCH_EDIT_FRAME::AppendOneEEProject()
bs = nextbs;
}
}
OnModify();
// redraw base screen (ROOT) if necessary
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+1 -3
View File
@@ -912,11 +912,9 @@ bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
SCH_SHEET* SCH_SHEET_LIST::FindSheetByName( const wxString& aSheetName )
{
SCH_SHEET* sheet = NULL;
for( int i = 0; i < m_count; i++ )
{
sheet = m_list[i].FindSheetByName( aSheetName );
SCH_SHEET* sheet = m_list[i].FindSheetByName( aSheetName );
if( sheet )
return sheet;
+2
View File
@@ -78,6 +78,8 @@ set( GERBVIEW_EXTRA_SRCS
if( MINGW )
# GERBVIEW_RESOURCES variable is set by the macro.
mingw_resource_compiler( gerbview )
else()
set( GERBVIEW_RESOURCES gerbview.rc )
endif()
if( APPLE )
+1
View File
@@ -130,6 +130,7 @@ void GERBER_LAYER_WIDGET::ReFillRender()
void GERBER_LAYER_WIDGET::installRightLayerClickHandler()
{
int rowCount = GetLayerRowCount();
for( int row=0; row<rowCount; ++row )
{
for( int col=0; col<LYR_COLUMN_COUNT; ++col )
+8 -2
View File
@@ -112,10 +112,12 @@ public:
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/// @copydoc GAL::DrawPolyline()
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) { drawPoly( aPointList ); }
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); }
/// @copydoc GAL::DrawPolygon()
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) { drawPoly( aPointList ); }
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); }
/// @copydoc GAL::DrawCurve()
virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
@@ -381,6 +383,10 @@ private:
/// Prepare the compositor
void setCompositor();
/// Drawing polygons & polylines is the same in cairo, so here is the common code
void drawPoly( const std::deque<VECTOR2D>& aPointList );
void drawPoly( const VECTOR2D aPointList[], int aListSize );
/**
* @brief Returns a valid key that can be used as a new group number.
*
+8 -3
View File
@@ -105,7 +105,8 @@ public:
*
* @param aPointList is a list of 2D-Vectors containing the polyline points.
*/
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList ) {};
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) {};
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) {};
/**
* @brief Draw a circle using world coordinates.
@@ -140,6 +141,7 @@ public:
* @param aPointList is the list of the polygon points.
*/
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) {};
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) {};
/**
* @brief Draw a cubic bezier spline.
@@ -635,8 +637,11 @@ public:
{
gridOrigin = aGridOrigin;
gridOffset = VECTOR2D( (long) gridOrigin.x % (long) gridSize.x,
(long) gridOrigin.y % (long) gridSize.y );
if( gridSize.x == 0.0 || gridSize.y == 0.0 )
gridOffset = VECTOR2D(0.0, 0.0);
else
gridOffset = VECTOR2D( (long) gridOrigin.x % (long) gridSize.x,
(long) gridOrigin.y % (long) gridSize.y );
}
/**
+4 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Graphics Abstraction Layer (GAL) for OpenGL
@@ -113,10 +113,12 @@ public:
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/// @copydoc GAL::DrawPolyline()
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList );
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize );
/// @copydoc GAL::DrawPolygon()
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize );
/// @copydoc GAL::DrawCurve()
virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
+11 -3
View File
@@ -616,16 +616,24 @@ inline bool IsBackLayer( LAYER_ID aLayerId )
/**
* Function FlippedLayerNumber
* @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
* 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
* 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.
+10
View File
@@ -495,6 +495,16 @@ public:
*/
bool OnHotkeyRotateItem( int aIdCommand );
/**
* Function OnHotkeyFlipItem
* Flip the item (text or footprint) found under the mouse cursor
* @note This command can be used with an item currently in edit.
* Only some items can be rotated (footprints and texts).
* @param aIdCommand = the hotkey command id
* @return true if an item was moved
*/
bool OnHotkeyFlipItem( int aIdCommand );
/**
* Function OnHotkeyBeginRoute
* If the current active layer is a copper layer,
+2
View File
@@ -25,6 +25,8 @@ set( KICAD_SRCS
if( MINGW )
# KICAD_RESOURCES variable is set by the macro.
mingw_resource_compiler( kicad )
else()
set( KICAD_RESOURCES kicad.rc )
endif()
if( APPLE )
+2 -1
View File
@@ -173,7 +173,8 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe )
wxString fullFileName = GetFileName();
wxTreeItemId id = GetId();
KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) Pgm().App().GetTopWindow();
KICAD_MANAGER_FRAME* frame = prjframe->m_Parent;
wxASSERT( frame );
switch( GetType() )
{
+2
View File
@@ -50,6 +50,8 @@ set( PL_EDITOR_EXTRA_SRCS
if( MINGW )
# PL_EDITOR_RESOURCES variable is set by the macro.
mingw_resource_compiler( pl_editor )
else()
set( PL_EDITOR_RESOURCES pl_editor.rc )
endif()
+3 -2
View File
@@ -237,8 +237,9 @@ void WORKSHEET_LAYOUT_IO::format( WORKSHEET_DATAITEM_TEXT* aItem, int aNestLevel
m_out->Print( 0, " (%s %s)", getTokenName( T_rotate ),
double2Str(aItem->m_Orient ).c_str() );
// Write font info
bool write_size = aItem->m_TextSize.x != 0.0 && aItem->m_TextSize.y != 0.0;
// Write font info, only if it is not the default setup
bool write_size = aItem->m_TextSize.x != 0.0 || aItem->m_TextSize.y != 0.0;
if( write_size || aItem->IsBold() || aItem->IsItalic() )
{
m_out->Print( 0, " (%s", getTokenName( T_font ) );
+2
View File
@@ -40,6 +40,8 @@ set( PCB_CALCULATOR_SRCS
if( MINGW )
# PCB_CALCULATOR_RESOURCES variable is set by the macro.
mingw_resource_compiler( pcb_calculator )
else()
set( PCB_CALCULATOR_RESOURCES pcb_calculator.rc )
endif()
if( APPLE )
+2
View File
@@ -497,6 +497,8 @@ endif()
if( MINGW )
# PCBNEW_RESOURCES variable is set by the macro.
mingw_resource_compiler( pcbnew )
else()
set( PCBNEW_RESOURCES pcbnew.rc )
endif()
+3 -3
View File
@@ -752,6 +752,7 @@ void PCB_EDIT_FRAME::Block_Flip()
itemsList->SetPickedItemStatus( UR_FLIPPED, ii );
item->Flip( center );
// If a connected item is flipped, the ratsnest is no more OK
switch( item->Type() )
{
case PCB_MODULE_T:
@@ -759,9 +760,8 @@ void PCB_EDIT_FRAME::Block_Flip()
m_Pcb->m_Status_Pcb = 0;
break;
// Move and rotate the track segments
case PCB_TRACE_T: // a track segment (segment on a copper layer)
case PCB_VIA_T: // a via (like track segment on a copper layer)
case PCB_TRACE_T:
case PCB_VIA_T:
m_Pcb->m_Status_Pcb = 0;
break;
+3
View File
@@ -161,6 +161,9 @@ void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle )
void DIMENSION::Flip( const wxPoint& 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() ) );
}
+2
View File
@@ -138,6 +138,8 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
if( m_Shape == S_ARC )
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() ) );
}
+4
View File
@@ -318,6 +318,10 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre )
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() ) );
}
+7 -25
View File
@@ -292,6 +292,9 @@ void D_PAD::Flip( const wxPoint& aCentre )
SetOrientation( -GetOrientation() );
// 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 ) );
// 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 )
return m_Pos;
wxPoint shape_pos;
int dX, dY;
wxPoint loc_offset = m_Offset;
dX = m_Offset.x;
dY = m_Offset.y;
RotatePoint( &loc_offset, m_Orient );
RotatePoint( &dX, &dY, m_Orient );
shape_pos.x = m_Pos.x + dX;
shape_pos.y = m_Pos.y + dY;
wxPoint shape_pos = m_Pos + loc_offset;
return shape_pos;
}
@@ -352,26 +350,10 @@ const wxPoint D_PAD::ShapePos() 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;
StringPadName( 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 ) )
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
+8
View File
@@ -480,6 +480,14 @@ void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal
void PCB_LAYER_WIDGET::OnRenderColorChange( int aId, EDA_COLOR_T aColor )
{
myframe->GetBoard()->SetVisibleElementColor( aId, aColor );
if( myframe->GetGalCanvas() )
{
KIGFX::VIEW* view = myframe->GetGalCanvas()->GetView();
view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->GetBoard()->GetColorsSettings() );
view->UpdateLayerColor( aId );
}
myframe->GetCanvas()->Refresh();
}
+2 -1
View File
@@ -179,7 +179,8 @@ void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
void TEXTE_PCB::Flip(const wxPoint& aCentre )
{
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;
}
+13 -1
View File
@@ -339,7 +339,8 @@ void TRACK::Flip( const wxPoint& aCentre )
{
m_Start.y = aCentre.y - (m_Start.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_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 );
}
}
+3 -2
View File
@@ -722,7 +722,8 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
void ZONE_CONTAINER::Flip( const wxPoint& 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() ) );
return msg;
}
}
+15 -10
View File
@@ -38,14 +38,15 @@
*/
void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
{
char line[1024];
wxString msg;
wxString modName;
char* idcmd;
char* text;
MODULE* module = 0;
BOARD* pcb = GetBoard();
wxPoint pos;
char line[1024];
wxString msg;
wxString modName;
char* idcmd;
char* text;
MODULE* module = NULL;
D_PAD* pad = NULL;
BOARD* pcb = GetBoard();
wxPoint pos;
strncpy( line, cmdline, sizeof(line) - 1 );
line[sizeof(line) - 1] = 0;
@@ -75,7 +76,6 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
else if( strcmp( idcmd, "$PIN:" ) == 0 )
{
wxString pinName;
D_PAD* pad = NULL;
int netcode = -1;
pinName = FROM_UTF8( text );
@@ -132,7 +132,12 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
{
if( IsGalCanvasActive() )
{
GetToolManager()->RunAction( COMMON_ACTIONS::crossProbeSchToPcb, true, module );
GetToolManager()->RunAction( COMMON_ACTIONS::crossProbeSchToPcb,
true,
pad ?
static_cast<BOARD_ITEM*>( pad ) :
static_cast<BOARD_ITEM*>( module )
);
}
else
{
+3 -1
View File
@@ -452,7 +452,9 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab
(double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS );
}
if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
if( ( m_settings.GetPadConnection() == PAD_ZONE_CONN_THT_THERMAL
|| m_settings.GetPadConnection() == PAD_ZONE_CONN_THERMAL )
&& m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
{
DisplayError( this,
_( "Thermal relief spoke must be greater than the minimum width." ) );
+3 -3
View File
@@ -206,6 +206,9 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
dlg.FilePicker()->SetPath( fn.GetFullPath() );
dlg.SetSubdir( subDirFor3Dshapes );
if( dlg.ShowModal() != wxID_OK )
return;
double aXRef = dlg.GetXRef();
double aYRef = dlg.GetYRef();
@@ -221,9 +224,6 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
bool useRelativePaths = dlg.GetUseRelativePathsOption();
bool usePlainPCB = dlg.GetUsePlainPCBOption();
if( dlg.ShowModal() != wxID_OK )
return;
last_vrmlName = dlg.FilePicker()->GetPath();
wxFileName modelPath = last_vrmlName;
wxBusyCursor dummy;
+2
View File
@@ -112,6 +112,8 @@ DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC,
int severities = m_config->Read( NETLIST_FILTER_MESSAGES_KEY, -1l );
m_MessageWindow->SetVisibleSeverities( severities );
// Update sizes and sizers:
m_MessageWindow->MsgPanelSetMinSize( wxSize( -1, 150 ) );
GetSizer()->SetSizeHints( this );
}
+16 -10
View File
@@ -275,7 +275,7 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
{
dim = m_dummyPad->GetDrillSize().y;
if( dim == 0 )
dim = 1000000;
dim = Millimeter2iu( 0.1 );
}
if( m_dummyPad->GetLocalClearance() > 0 )
@@ -731,6 +731,7 @@ void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
bool DIALOG_PAD_PROPERTIES::padValuesOK()
{
bool error = transferDataToPad( m_dummyPad );
bool skip_tstoffset = false; // the offset prm is not always tested
wxArrayString error_msgs;
wxString msg;
@@ -746,6 +747,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
(m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
{
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();
@@ -772,16 +775,19 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
}
}
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 ) )
if( !skip_tstoffset )
{
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 )
+11
View File
@@ -43,6 +43,9 @@
#include <view/view.h>
#include <geometry/seg.h>
#include <tool/tool_manager.h>
#include <tools/common_actions.h>
#include <pcbnew.h>
#include <drc_stuff.h>
@@ -54,6 +57,7 @@ void DRC::ShowDialog()
{
if( !m_ui )
{
m_mainWindow->GetToolManager()->RunAction( COMMON_ACTIONS::selectionClear, true );
m_ui = new DIALOG_DRC_CONTROL( this, m_mainWindow );
updatePointers();
@@ -951,6 +955,13 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
if( pad->PadNameEqual( aRefPad ) )
continue;
}
// if either pad has no drill and is only on technical layers, not a clearance violation
if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
{
continue;
}
if( !checkClearancePadToPad( aRefPad, pad ) )
{
+138 -286
View File
@@ -34,7 +34,6 @@
#include <kicad_string.h>
#include <gestfich.h>
#include <wxPcbStruct.h>
#include <trigo.h>
#include <pgm_base.h>
#include <build_version.h>
#include <macros.h>
@@ -42,12 +41,8 @@
#include <class_board.h>
#include <class_module.h>
#include <class_drawsegment.h>
#include <legacy_plugin.h>
#include <pcbnew.h>
#include <pcbplot.h>
#include <pcb_plot_params.h>
#include <wildcards_and_files_ext.h>
#include <kiface_i.h>
#include <wx_html_report_panel.h>
@@ -66,7 +61,7 @@
* ## Side : bottom
* or
* ## Side : all
* # Ref Val Package PosX PosY Rot Side
* # Ref Val Package PosX PosY Rot Side
* C123 0,1uF/50V SM0603 1.6024 -2.6280 180.0 Front
* C124 0,1uF/50V SM0603 1.6063 -2.7579 180.0 Front
* C125 0,1uF/50V SM0603 1.6010 -2.8310 180.0 Front
@@ -77,6 +72,10 @@
#define PLACEFILE_OPT_KEY wxT( "PlaceFileOpts" )
#define PCB_BACK_SIDE 0
#define PCB_FRONT_SIDE 1
#define PCB_BOTH_SIDES 2
class LIST_MOD // An helper class used to build a list of useful footprints.
{
public:
@@ -228,7 +227,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles()
// Count the footprints to place, do not yet create a file
int fpcount = m_parent->DoGenFootprintsPositionFile( wxEmptyString, UnitsMM(),
ForceAllSmd(), 2 );
ForceAllSmd(), PCB_BOTH_SIDES );
if( fpcount == 0)
{
wxMessageBox( _( "No footprint for automated placement." ) );
@@ -255,11 +254,11 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles()
// Create the the Front or Top side placement file,
// or the single file
int side = 1;
int side = PCB_FRONT_SIDE;
if( singleFile )
{
side = 2;
side = PCB_BOTH_SIDES;
fn.SetName( fn.GetName() + wxT( "-" ) + wxT("all") );
}
else
@@ -295,7 +294,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles()
// Create the Back or Bottom side placement file
fullcount = fpcount;
side = 0;
side = PCB_BACK_SIDE;
fn = brd->GetFileName();
fn.SetPath( outputDir.GetPath() );
fn.SetName( fn.GetName() + wxT( "-" ) + backSideName );
@@ -344,9 +343,6 @@ static const char unit_text_mm[] = "## Unit = mm, Angle = deg.\n";
static wxPoint File_Place_Offset; // Offset coordinates for generated file.
static void WriteDrawSegmentPcb( DRAWSEGMENT* PtDrawSegment, FILE* rptfile,
double aConvUnit );
// Sort function use by GenereModulesPosition()
// sort is made by side (layer) top layer first
@@ -396,45 +392,57 @@ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName,
bool aUnitsMM,
bool aForceSmdItems, int aSide )
{
MODULE* module;
char line[1024];
MODULE* footprint;
// Minimal text lenghts:
int lenRefText = 8;
int lenValText = 8;
int lenPkgText = 16;
File_Place_Offset = GetAuxOrigin();
// Calculating the number of useful modules (CMS attribute, not VIRTUAL)
int moduleCount = 0;
// Calculating the number of useful footprints (CMS attribute, not VIRTUAL)
int footprintCount = 0;
for( module = GetBoard()->m_Modules; module; module = module->Next() )
// Select units:
double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch;
const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch;
// Build and sort the list of footprints alphabetically
std::vector<LIST_MOD> list;
list.reserve( footprintCount );
for( footprint = GetBoard()->m_Modules; footprint; footprint = footprint->Next() )
{
if( aSide < 2 )
if( aSide != PCB_BOTH_SIDES )
{
if( module->GetLayer() == B_Cu && aSide == 1)
if( footprint->GetLayer() == B_Cu && aSide == PCB_FRONT_SIDE)
continue;
if( module->GetLayer() == F_Cu && aSide == 0)
if( footprint->GetLayer() == F_Cu && aSide == PCB_BACK_SIDE)
continue;
}
if( module->GetAttributes() & MOD_VIRTUAL )
if( footprint->GetAttributes() & MOD_VIRTUAL )
{
DBG( printf( "skipping module %s because it's virtual\n",
TO_UTF8( module->GetReference() ) );)
DBG( printf( "skipping footprint %s because it's virtual\n",
TO_UTF8( footprint->GetReference() ) );)
continue;
}
if( ( module->GetAttributes() & MOD_CMS ) == 0 )
if( ( footprint->GetAttributes() & MOD_CMS ) == 0 )
{
if( aForceSmdItems ) // true to fix a bunch of mis-labeled modules:
if( aForceSmdItems ) // true to fix a bunch of mis-labeled footprints:
{
if( !HasNonSMDPins( module ) )
if( !HasNonSMDPins( footprint ) )
{
// all module's pins are SMD, mark the part for pick and place
module->SetAttributes( module->GetAttributes() | MOD_CMS );
// all footprint's pins are SMD, mark the part for pick and place
footprint->SetAttributes( footprint->GetAttributes() | MOD_CMS );
OnModify();
}
else
{
DBG(printf( "skipping %s because its attribute is not CMS and it has non SMD pins\n",
TO_UTF8(module->GetReference()) ) );
TO_UTF8(footprint->GetReference()) ) );
continue;
}
}
@@ -442,47 +450,27 @@ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName,
continue;
}
moduleCount++;
footprintCount++;
LIST_MOD item;
item.m_Module = footprint;
item.m_Reference = footprint->GetReference();
item.m_Value = footprint->GetValue();
item.m_Layer = footprint->GetLayer();
list.push_back( item );
lenRefText = std::max( lenRefText, int(item.m_Reference.length()) );
lenValText = std::max( lenValText, int(item.m_Value.length()) );
lenPkgText = std::max( lenPkgText, int(item.m_Module->GetFPID().GetFootprintName().length()) );
}
if( aFullFileName.IsEmpty() )
return moduleCount;
return footprintCount;
FILE * file = wxFopen( aFullFileName, wxT( "wt" ) );
if( file == NULL )
return -1;
// Select units:
double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch;
const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch;
// Build and sort the list of modules alphabetically
std::vector<LIST_MOD> list;
list.reserve(moduleCount);
for( module = GetBoard()->m_Modules; module; module = module->Next() )
{
if( aSide < 2 )
{
if( module->GetLayer() == B_Cu && aSide == 1)
continue;
if( module->GetLayer() == F_Cu && aSide == 0)
continue;
}
if( module->GetAttributes() & MOD_VIRTUAL )
continue;
if( (module->GetAttributes() & MOD_CMS) == 0 )
continue;
LIST_MOD item;
item.m_Module = module;
item.m_Reference = module->GetReference();
item.m_Value = module->GetValue();
item.m_Layer = module->GetLayer();
list.push_back( item );
}
if( list.size() > 1 )
sort( list.begin(), list.end(), sortFPlist );
@@ -490,70 +478,60 @@ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName,
LOCALE_IO toggle;
// Write file header
sprintf( line, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) );
fputs( line, file );
fprintf( file, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) );
wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion();
sprintf( line, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( line, file );
fprintf( file, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( unit_text, file );
fputs( "## Side : ", file );
if( aSide == 0 )
if( aSide == PCB_BACK_SIDE )
fputs( TO_UTF8( backSideName ), file );
else if( aSide == 1 )
else if( aSide == PCB_FRONT_SIDE )
fputs( TO_UTF8( frontSideName ), file );
else
fputs( "All", file );
fputs( "\n", file );
fputs( "# Ref Val Package PosX PosY Rot Side\n",
file );
fprintf(file, "%-*s %-*s %-*s %9.9s %9.9s %8.8s %s\n",
int(lenRefText), "# Ref",
int(lenValText), "Val",
int(lenPkgText), "Package",
"PosX", "PosY", "Rot", "Side" );
for( int ii = 0; ii < moduleCount; ii++ )
for( int ii = 0; ii < footprintCount; ii++ )
{
wxPoint module_pos;
wxPoint footprint_pos;
footprint_pos = list[ii].m_Module->GetPosition();
footprint_pos -= File_Place_Offset;
LAYER_NUM layer = list[ii].m_Module->GetLayer();
wxASSERT( layer==F_Cu || layer==B_Cu );
const wxString& ref = list[ii].m_Reference;
const wxString& val = list[ii].m_Value;
const wxString& pkg = list[ii].m_Module->GetFPID().GetFootprintName();
sprintf( line, "%-8.8s %-16.16s %-16.16s",
TO_UTF8( ref ), TO_UTF8( val ), TO_UTF8( pkg ) );
module_pos = list[ii].m_Module->GetPosition();
module_pos -= File_Place_Offset;
char* text = line + strlen( line );
/* Keep the coordinates in the first quadrant, like the gerbers
* (i.e. change sign to y) */
sprintf( text, " %9.4f %9.4f %8.1f ",
module_pos.x * conv_unit,
-module_pos.y * conv_unit,
list[ii].m_Module->GetOrientation() / 10.0 );
LAYER_NUM layer = list[ii].m_Module->GetLayer();
fputs( line, file );
wxASSERT( layer==F_Cu || layer==B_Cu );
if( layer == F_Cu )
fputs( TO_UTF8( frontSideName ), file );
else if( layer == B_Cu )
fputs( TO_UTF8( backSideName ), file );
fputs( "\n", file );
fprintf(file, "%-*s %-*s %-*s %9.4f %9.4f %8.4f %s\n",
lenRefText, TO_UTF8( ref ),
lenValText, TO_UTF8( val ),
lenPkgText, TO_UTF8( pkg ),
footprint_pos.x * conv_unit,
// Keep the coordinates in the first quadrant,
// (i.e. change y sign
-footprint_pos.y * conv_unit,
list[ii].m_Module->GetOrientation() / 10.0,
(layer == F_Cu ) ? TO_UTF8( frontSideName ) : TO_UTF8( backSideName ));
}
// Write EOF
fputs( "## End\n", file );
fclose( file );
return moduleCount;
return footprintCount;
}
@@ -571,7 +549,8 @@ void PCB_EDIT_FRAME::GenFootprintsReport( wxCommandEvent& event )
fn.SetPath( dirDialog.GetPath() );
fn.SetExt( wxT( "rpt" ) );
bool success = DoGenFootprintsReport( fn.GetFullPath(), false );
bool unitMM = g_UserUnit != INCHES;
bool success = DoGenFootprintsReport( fn.GetFullPath(), unitMM );
wxString msg;
if( success )
@@ -592,8 +571,6 @@ void PCB_EDIT_FRAME::GenFootprintsReport( wxCommandEvent& event )
*/
bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool aUnitsMM )
{
D_PAD* pad;
char line[1024];
wxString msg;
FILE* rptfile;
wxPoint module_pos;
@@ -612,157 +589,96 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
LOCALE_IO toggle;
// Generate header file comments.)
sprintf( line, "## Module report - date %s\n", TO_UTF8( DateAndTime() ) );
fputs( line, rptfile );
fprintf( rptfile, "## Footprint report - date %s\n", TO_UTF8( DateAndTime() ) );
wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion();
sprintf( line, "## Created by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( line, rptfile );
fprintf( rptfile, "## Created by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( unit_text, rptfile );
fputs( "##\n", rptfile );
fputs( "\n$BeginDESCRIPTION\n", rptfile );
EDA_RECT bbbox = GetBoard()->ComputeBoundingBox();
fputs( "\n$BOARD\n", rptfile );
fputs( "unit INCH\n", rptfile );
sprintf( line, "upper_left_corner %9.6f %9.6f\n",
fprintf( rptfile, "upper_left_corner %9.6f %9.6f\n",
bbbox.GetX() * conv_unit,
bbbox.GetY() * conv_unit );
fputs( line, rptfile );
sprintf( line, "lower_right_corner %9.6f %9.6f\n",
fprintf( rptfile, "lower_right_corner %9.6f %9.6f\n",
bbbox.GetRight() * conv_unit,
bbbox.GetBottom() * conv_unit );
fputs( line, rptfile );
fputs( "$EndBOARD\n\n", rptfile );
try
for( MODULE* Module = GetBoard()->m_Modules; Module; Module = Module->Next() )
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
fprintf( rptfile, "$MODULE %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
LEGACY_PLUGIN* legacy = (LEGACY_PLUGIN*) (PLUGIN*) pi;
fprintf( rptfile, "reference %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
fprintf( rptfile, "value %s\n", EscapedUTF8( Module->GetValue() ).c_str() );
fprintf( rptfile, "footprint %s\n",
EscapedUTF8( FROM_UTF8( Module->GetFPID().Format().c_str() ) ).c_str() );
legacy->SetFilePtr( rptfile );
msg = wxT( "attribut" );
for( MODULE* Module = GetBoard()->m_Modules; Module; Module = Module->Next() )
if( Module->GetAttributes() & MOD_VIRTUAL )
msg += wxT( " virtual" );
if( Module->GetAttributes() & MOD_CMS )
msg += wxT( " smd" );
if( ( Module->GetAttributes() & (MOD_VIRTUAL | MOD_CMS) ) == 0 )
msg += wxT( " none" );
msg += wxT( "\n" );
fputs( TO_UTF8( msg ), rptfile );
module_pos = Module->GetPosition();
module_pos.x -= File_Place_Offset.x;
module_pos.y -= File_Place_Offset.y;
fprintf( rptfile, "position %9.6f %9.6f orientation %.2f\n",
module_pos.x * conv_unit,
module_pos.y * conv_unit,
Module->GetOrientation() / 10.0 );
if( Module->GetLayer() == F_Cu )
fputs( "layer front\n", rptfile );
else if( Module->GetLayer() == B_Cu )
fputs( "layer back\n", rptfile );
else
fputs( "layer other\n", rptfile );
for( D_PAD* pad = Module->Pads(); pad != NULL; pad = pad->Next() )
{
sprintf( line, "$MODULE %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
fputs( line, rptfile );
fprintf( rptfile, "$PAD \"%s\"\n", TO_UTF8( pad->GetPadName() ) );
int layer = 0;
sprintf( line, "reference %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
fputs( line, rptfile );
sprintf( line, "value %s\n", EscapedUTF8( Module->GetValue() ).c_str() );
fputs( line, rptfile );
sprintf( line, "footprint %s\n",
EscapedUTF8( FROM_UTF8( Module->GetFPID().Format().c_str() ) ).c_str() );
fputs( line, rptfile );
if( pad->GetLayerSet()[B_Cu] )
layer = 1;
msg = wxT( "attribut" );
if( pad->GetLayerSet()[F_Cu] )
layer |= 2;
if( Module->GetAttributes() & MOD_VIRTUAL )
msg += wxT( " virtual" );
static const char* layer_name[4] = { "nocopper", "back", "front", "both" };
fprintf( rptfile, "Shape %s Layer %s\n", TO_UTF8( pad->ShowPadShape() ), layer_name[layer] );
if( Module->GetAttributes() & MOD_CMS )
msg += wxT( " smd" );
fprintf( rptfile, "position %9.6f %9.6f size %9.6f %9.6f orientation %.2f\n",
pad->GetPos0().x * conv_unit, pad->GetPos0().y * conv_unit,
pad->GetSize().x * conv_unit, pad->GetSize().y * conv_unit,
(pad->GetOrientation() - Module->GetOrientation()) / 10.0 );
if( ( Module->GetAttributes() & (MOD_VIRTUAL | MOD_CMS) ) == 0 )
msg += wxT( " none" );
fprintf( rptfile, "drill %9.6f\n", pad->GetDrillSize().x * conv_unit );
msg += wxT( "\n" );
fputs( TO_UTF8( msg ), rptfile );
fprintf( rptfile, "shape_offset %9.6f %9.6f\n",
pad->GetOffset().x * conv_unit,
pad->GetOffset().y * conv_unit );
module_pos = Module->GetPosition();
module_pos.x -= File_Place_Offset.x;
module_pos.y -= File_Place_Offset.y;
sprintf( line, "position %9.6f %9.6f\n",
module_pos.x * conv_unit,
module_pos.y * conv_unit );
fputs( line, rptfile );
sprintf( line, "orientation %.2f\n", Module->GetOrientation() / 10.0 );
if( Module->GetLayer() == F_Cu )
strcat( line, "layer component\n" );
else if( Module->GetLayer() == B_Cu )
strcat( line, "layer copper\n" );
else
strcat( line, "layer other\n" );
fputs( line, rptfile );
legacy->SaveModule3D( Module );
for( pad = Module->Pads(); pad != NULL; pad = pad->Next() )
{
fprintf( rptfile, "$PAD \"%s\"\n", TO_UTF8( pad->GetPadName() ) );
sprintf( line, "position %9.6f %9.6f\n",
pad->GetPos0().x * conv_unit,
pad->GetPos0().y * conv_unit );
fputs( line, rptfile );
sprintf( line, "size %9.6f %9.6f\n",
pad->GetSize().x * conv_unit,
pad->GetSize().y * conv_unit );
fputs( line, rptfile );
sprintf( line, "drill %9.6f\n", pad->GetDrillSize().x * conv_unit );
fputs( line, rptfile );
sprintf( line, "shape_offset %9.6f %9.6f\n",
pad->GetOffset().x * conv_unit,
pad->GetOffset().y * conv_unit );
fputs( line, rptfile );
sprintf( line, "orientation %.2f\n",
(pad->GetOrientation() - Module->GetOrientation()) / 10.0 );
fputs( line, rptfile );
static const char* shape_name[6] = { "???", "Circ", "Rect", "Oval", "Trap", "Spec" };
sprintf( line, "Shape %s\n", shape_name[pad->GetShape()] );
fputs( line, rptfile );
int layer = 0;
if( pad->GetLayerSet()[B_Cu] )
layer = 1;
if( pad->GetLayerSet()[F_Cu] )
layer |= 2;
static const char* layer_name[4] = { "none", "back", "front", "both" };
sprintf( line, "Layer %s\n", layer_name[layer] );
fputs( line, rptfile );
fprintf( rptfile, "$EndPAD\n" );
}
fprintf( rptfile, "$EndMODULE %s\n\n", TO_UTF8 (Module->GetReference() ) );
fprintf( rptfile, "$EndPAD\n" );
}
}
catch( const IO_ERROR& ioe )
{
DisplayError( NULL, ioe.errorText );
}
// Write board Edges
EDA_ITEM* PtStruct;
for( PtStruct = GetBoard()->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
{
if( PtStruct->Type() != PCB_LINE_T )
continue;
if( ( (DRAWSEGMENT*) PtStruct )->GetLayer() != Edge_Cuts )
continue;
WriteDrawSegmentPcb( (DRAWSEGMENT*) PtStruct, rptfile, conv_unit );
fprintf( rptfile, "$EndMODULE %s\n\n", TO_UTF8 (Module->GetReference() ) );
}
// Generate EOF.
@@ -772,67 +688,3 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool
return true;
}
/* Output to rpt file a segment type from the PCB drawing.
* The contours are of different types:
* Segment
* Circle
* Arc
*/
void WriteDrawSegmentPcb( DRAWSEGMENT* PtDrawSegment, FILE* rptfile, double aConvUnit )
{
double ux0, uy0, dx, dy;
double radius, width;
char line[1024];
ux0 = PtDrawSegment->GetStart().x * aConvUnit;
uy0 = PtDrawSegment->GetStart().y * aConvUnit;
dx = PtDrawSegment->GetEnd().x * aConvUnit;
dy = PtDrawSegment->GetEnd().y * aConvUnit;
width = PtDrawSegment->GetWidth() * aConvUnit;
switch( PtDrawSegment->GetShape() )
{
case S_CIRCLE:
radius = Distance( ux0, uy0, dx, dy );
fprintf( rptfile, "$CIRCLE \n" );
fprintf( rptfile, "centre %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "radius %.6lf\n", radius );
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndCIRCLE \n" );
break;
case S_ARC:
{
int endx = PtDrawSegment->GetEnd().x;
int endy = PtDrawSegment->GetEnd().y;
RotatePoint( &endx,
&endy,
PtDrawSegment->GetStart().x,
PtDrawSegment->GetStart().y,
PtDrawSegment->GetAngle() );
fprintf( rptfile, "$ARC \n" );
fprintf( rptfile, "centre %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "start %.6lf %.6lf\n",
endx * aConvUnit, endy * aConvUnit );
fprintf( rptfile, "end %.6lf %.6lf\n", dx, dy );
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndARC \n" );
}
break;
default:
sprintf( line, "$LINE \n" );
fputs( line, rptfile );
fprintf( rptfile, "start %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "end %.6lf %.6lf\n", dx, dy );
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndLINE \n" );
break;
}
}
+2
View File
@@ -41,6 +41,7 @@
#include <pgm_base.h>
#include <msgpanel.h>
#include <fp_lib_table.h>
#include <ratsnest_data.h>
#include <pcbnew.h>
#include <pcbnew_id.h>
@@ -590,6 +591,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{
wxBusyCursor dummy; // Displays an Hourglass while building connectivity
Compile_Ratsnest( NULL, true );
GetBoard()->GetRatsnest()->ProcessBoard();
}
SetMsgPanel( GetBoard() );
+59 -14
View File
@@ -563,7 +563,7 @@ bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_FLIP_ITEM:
OnHotkeyRotateItem( HK_FLIP_ITEM );
OnHotkeyFlipItem( HK_FLIP_ITEM );
break;
case HK_MOVE_ITEM_EXACT:
@@ -1026,12 +1026,67 @@ TRACK * PCB_EDIT_FRAME::OnHotkeyBeginRoute( wxDC* aDC )
return track;
}
bool PCB_EDIT_FRAME::OnHotkeyFlipItem( int aIdCommand )
{
BOARD_ITEM* item = GetCurItem();
bool itemCurrentlyEdited = item && item->GetFlags();
int evt_type = 0; // Used to post a wxCommandEvent on demand
wxASSERT( aIdCommand == HK_FLIP_ITEM );
if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
{
evt_type = ID_POPUP_FLIP_BLOCK;
}
else
{
if( !itemCurrentlyEdited )
item = PcbGeneralLocateAndDisplay();
if( item == NULL )
return false;
SetCurItem( item );
switch( item->Type() )
{
case PCB_MODULE_T:
evt_type = ID_POPUP_PCB_CHANGE_SIDE_MODULE;
break;
case PCB_TEXT_T:
evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
break;
default:
break;
}
}
if( evt_type != 0 )
{
wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
evt.SetEventObject( this );
evt.SetId( evt_type );
GetEventHandler()->ProcessEvent( evt );
return true;
}
else
{
return false;
}
}
bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
{
BOARD_ITEM* item = GetCurItem();
bool itemCurrentlyEdited = item && item->GetFlags();
int evt_type = 0; // Used to post a wxCommandEvent on demand
wxASSERT( aIdCommand == HK_ROTATE_ITEM );
// Allows block rotate operation on hot key.
if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
{
@@ -1050,25 +1105,15 @@ bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
switch( item->Type() )
{
case PCB_MODULE_T:
if( aIdCommand == HK_ROTATE_ITEM ) // Rotation
evt_type = ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE;
if( aIdCommand == HK_FLIP_ITEM ) // move to other side
evt_type = ID_POPUP_PCB_CHANGE_SIDE_MODULE;
evt_type = ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE;
break;
case PCB_TEXT_T:
if( aIdCommand == HK_ROTATE_ITEM ) // Rotation
evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
else if( aIdCommand == HK_FLIP_ITEM )
evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
break;
case PCB_MODULE_TEXT_T:
if( aIdCommand == HK_ROTATE_ITEM ) // Rotation
evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
break;
default:
+3 -1
View File
@@ -25,6 +25,7 @@
#include <pcb_base_edit_frame.h>
#include <tool/tool_manager.h>
#include <pcb_draw_panel_gal.h>
#include <gal/graphics_abstraction_layer.h>
#include <class_board.h>
void PCB_BASE_EDIT_FRAME::SetRotationAngle( int aRotationAngle )
@@ -73,6 +74,8 @@ void PCB_BASE_EDIT_FRAME::SetBoard( BOARD* aBoard )
PCB_BASE_FRAME::SetBoard( aBoard );
GetGalCanvas()->GetGAL()->SetGridOrigin( VECTOR2D( aBoard->GetGridOrigin() ) );
// update the tool manager with the new board and its view.
if( m_toolManager )
{
@@ -86,4 +89,3 @@ void PCB_BASE_EDIT_FRAME::SetBoard( BOARD* aBoard )
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
}
}
+19 -14
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013-2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@@ -1001,20 +1001,25 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
void PCB_PAINTER::draw( const MARKER_PCB* aMarker )
{
const BOARD_ITEM* item = aMarker->GetItem();
const int scale = 100000;
const VECTOR2D arrow[] = {
VECTOR2D( 0 * scale, 0 * scale ),
VECTOR2D( 8 * scale, 1 * scale ),
VECTOR2D( 4 * scale, 3 * scale ),
VECTOR2D( 13 * scale, 8 * scale ),
VECTOR2D( 9 * scale, 9 * scale ),
VECTOR2D( 8 * scale, 13 * scale ),
VECTOR2D( 3 * scale, 4 * scale ),
VECTOR2D( 1 * scale, 8 * scale )
};
if( item ) // By default draw an item in a different color
{
Draw( item, ITEM_GAL_LAYER( DRC_VISIBLE ) );
}
else // If there is no item associated - draw a circle marking the DRC error
{
m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( 10000 );
m_gal->DrawCircle( VECTOR2D( aMarker->GetPosition() ), 200000 );
}
m_gal->Save();
m_gal->Translate( aMarker->GetPosition() );
m_gal->SetFillColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) );
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
m_gal->DrawPolygon( arrow, sizeof( arrow ) / sizeof( VECTOR2D ) );
m_gal->Restore();
}
+7 -3
View File
@@ -2694,11 +2694,13 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
break;
case T_chamfer:
zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
break;
case T_fillet:
zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
break;
default:
@@ -2708,7 +2710,9 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
break;
case T_radius:
zone->SetCornerRadius( parseBoardUnits( "corner radius" ) );
tmp = parseBoardUnits( "corner radius" );
if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
zone->SetCornerRadius( tmp );
NeedRIGHT();
break;
+16 -1
View File
@@ -784,7 +784,19 @@ EDA_COLOR_T PCB_EDIT_FRAME::GetGridColor() const
void PCB_EDIT_FRAME::SetGridColor( EDA_COLOR_T aColor )
{
GetBoard()->SetVisibleElementColor( GRID_VISIBLE, aColor );
if( IsGalCanvasActive() )
{
StructColors c = g_ColorRefs[ aColor ];
KIGFX::COLOR4D color( (double) c.m_Red / 255.0,
(double) c.m_Green / 255.0,
(double) c.m_Blue / 255.0,
0.7 );
GetGalCanvas()->GetGAL()->SetGridColor( color );
}
}
@@ -994,7 +1006,10 @@ void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent )
else
pythonPanelShown = ! pythonPanelFrame->IsShown();
pythonPanelFrame->Show( pythonPanelShown );
if( pythonPanelFrame )
pythonPanelFrame->Show( pythonPanelShown );
else
wxMessageBox( wxT( "Error: unable to create the Python Console" ) );
}
+3
View File
@@ -885,6 +885,9 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
PNS_LINE line = AssembleLine( seg );
if ( !line.Layers().Overlaps( aB.Layers() ) )
continue;
PNS_JOINT j_start, j_end;
FindLineEnds( line, j_start, j_end );
+7 -4
View File
@@ -602,8 +602,10 @@ void ROUTER_TOOL::performRouting()
}
else if( evt->IsAction( &ACT_EndTrack ) )
{
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
break;
bool still_routing = true;
while( still_routing )
still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
break;
}
handleCommonEvents( *evt );
@@ -722,6 +724,9 @@ int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
m_savedSettings = m_router->Settings();
m_savedSizes = m_router->Sizes();
// Disable the context menu before it is destroyed
SetContextMenu( NULL, CMENU_OFF );
return 0;
}
@@ -745,8 +750,6 @@ void ROUTER_TOOL::performDragging()
{
ctls->ForceCursorPosition( false );
VECTOR2I p0 = ctls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
break;
else if( evt->IsMotion() )
+1
View File
@@ -1159,6 +1159,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
// Get the current default settings for zones
ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings();
zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer;
zoneInfo.SetIsKeepout(aKeepout);
m_controls->SetAutoPan( true );
m_controls->CaptureCursor( true );
+4 -4
View File
@@ -429,7 +429,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection ) )
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
wxPoint rotatePoint = getModificationPoint( selection );
@@ -479,7 +479,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection ) )
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
wxPoint flipPoint = getModificationPoint( selection );
@@ -524,7 +524,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( !hoverSelection( selection ) )
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
// Get a copy of the selected items set
@@ -649,7 +649,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection ) )
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
wxPoint translation;
+10 -11
View File
@@ -105,10 +105,9 @@ int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
MODULE* module = m_board->m_Modules;
assert( module );
assert( m_board->m_Modules );
D_PAD* pad = new D_PAD( module );
D_PAD* pad = new D_PAD( m_board->m_Modules );
m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad
VECTOR2I cursorPos = m_controls->GetCursorPosition();
@@ -159,11 +158,12 @@ int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
module->SetLastEditTime();
module->Pads().PushBack( pad );
pad->SetParent( m_board->m_Modules );
m_board->m_Modules->SetLastEditTime();
m_board->m_Modules->Pads().PushBack( pad );
// Set the relative pad position
// ( pad position for module orient, 0, and relative to the module position)
@@ -177,7 +177,7 @@ int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
m_view->Add( pad );
// Start placing next pad
pad = new D_PAD( module );
pad = new D_PAD( m_board->m_Modules );
m_frame->Import_Pad_Settings( pad, false );
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.Add( pad );
@@ -199,9 +199,8 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
{
std::list<D_PAD*> pads;
std::set<D_PAD*> allPads;
MODULE* module = m_board->m_Modules;
if( !module || !module->Pads() )
if( !m_board->m_Modules || !m_board->m_Modules->Pads() )
return 0;
GENERAL_COLLECTOR collector;
@@ -215,7 +214,7 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
guide.SetIgnoreModulesRefs( true );
// Create a set containing all pads (to avoid double adding to the list)
for( D_PAD* p = module->Pads(); p; p = p->Next() )
for( D_PAD* p = m_board->m_Modules->Pads(); p; p = p->Next() )
allPads.insert( p );
DIALOG_ENUM_PADS settingsDlg( m_frame );
@@ -309,7 +308,7 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
{
// Accept changes
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_MODEDIT );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
BOOST_FOREACH( D_PAD* pad, pads )
pad->SetPadName( wxString::Format( wxT( "%s%d" ), padPrefix.c_str(), padNumber++ ) );
+25 -2
View File
@@ -642,7 +642,18 @@ int PCB_EDITOR_CONTROL::CrossProbeSchToPcb( const TOOL_EVENT& aEvent )
m_probingSchToPcb = true;
getView()->SetCenter( VECTOR2D( item->GetPosition() ) );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
// If it is a pad and the net highlighting tool is enabled, highlight the net
if( item->Type() == PCB_PAD_T && m_frame->GetToolId() == ID_PCB_HIGHLIGHT_BUTT )
{
int net = static_cast<D_PAD*>( item )->GetNetCode();
m_toolMgr->RunAction( COMMON_ACTIONS::highlightNet, false, net );
}
else
// Otherwise simply select the corresponding item
{
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
}
}
return 0;
@@ -714,7 +725,19 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
int PCB_EDITOR_CONTROL::HighlightNet( const TOOL_EVENT& aEvent )
{
highlightNet( m_toolMgr, getView()->ToWorld( getViewControls()->GetMousePosition() ) );
int netcode = aEvent.Parameter<long>();
if( netcode > 0 )
{
KIGFX::RENDER_SETTINGS* render = m_toolMgr->GetView()->GetPainter()->GetSettings();
render->SetHighlight( true, netcode );
m_toolMgr->GetView()->UpdateAllLayersColor();
}
else
{
// No net code specified, pick the net code belonging to the item under the cursor
highlightNet( m_toolMgr, getView()->ToWorld( getViewControls()->GetMousePosition() ) );
}
return 0;
}
+4 -1
View File
@@ -69,11 +69,14 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
if( !getNext )
break;
else
setControls();
m_toolMgr->PassEvent();
}
else if( evt->IsCancel() || evt->IsActivate() )
break;
else
m_toolMgr->PassEvent();
}
reset();
+69 -35
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@@ -121,6 +121,10 @@ bool SELECTION_TOOL::Init()
void SELECTION_TOOL::Reset( RESET_REASON aReason )
{
m_frame = getEditFrame<PCB_BASE_FRAME>();
m_locked = true;
m_preliminary = true;
if( aReason == TOOL_BASE::MODEL_RELOAD )
{
// Remove pointers to the selected items from containers
@@ -133,10 +137,6 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
// Restore previous properties of selected items and remove them from containers
clearSelection();
m_frame = getEditFrame<PCB_BASE_FRAME>();
m_locked = true;
m_preliminary = true;
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
getView()->Remove( m_selection.group );
getView()->Add( m_selection.group );
@@ -302,6 +302,31 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
}
const SELECTION& SELECTION_TOOL::GetSelection()
{
// The selected items list has been requested, so it is no longer preliminary
m_preliminary = false;
// Filter out not modifiable items
for( int i = 0; i < m_selection.Size(); )
{
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
if( !modifiable( item ) )
{
m_selection.items.RemovePicker( i );
m_selection.group->Remove( item );
}
else
{
++i;
}
}
return m_selection;
}
void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
{
if( aItem->IsSelected() )
@@ -466,11 +491,9 @@ bool SELECTION_TOOL::selectMultiple()
else
m_frame->SetCurItem( NULL );
// Inform other potentially interested tools
if( !m_selection.Empty() )
{
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( SelectedEvent );
}
break; // Stop waiting for events
}
@@ -604,14 +627,10 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
return 0;
BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
clearSelection();
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
{
clearSelection();
return 0;
}
clearSelection();
int segmentCount;
TRACK* trackList = getModel<BOARD>()->MarkTrace( static_cast<TRACK*>( item ), &segmentCount,
@@ -627,8 +646,7 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
}
// Inform other potentially interested tools
TOOL_EVENT selectEvent( SelectedEvent );
m_toolMgr->ProcessEvent( selectEvent );
m_toolMgr->ProcessEvent( SelectedEvent );
return 0;
}
@@ -640,17 +658,14 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
return 0;
BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
clearSelection();
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
{
clearSelection();
return 0;
}
std::list<BOARD_CONNECTED_ITEM*> itemsList;
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
clearSelection();
ratsnest->GetConnectedItems( item, itemsList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
BOOST_FOREACH( BOARD_CONNECTED_ITEM* i, itemsList )
@@ -658,10 +673,7 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
// Inform other potentially interested tools
if( itemsList.size() > 0 )
{
TOOL_EVENT selectEvent( SelectedEvent );
m_toolMgr->ProcessEvent( selectEvent );
}
m_toolMgr->ProcessEvent( SelectedEvent );
return 0;
}
@@ -686,10 +698,7 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
// Inform other potentially interested tools
if( itemsList.size() > 0 )
{
TOOL_EVENT selectEvent( SelectedEvent );
m_toolMgr->ProcessEvent( selectEvent );
}
m_toolMgr->ProcessEvent( SelectedEvent );
return 0;
}
@@ -756,6 +765,7 @@ void SELECTION_TOOL::clearSelection()
item->ClearSelected();
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ;
}
m_selection.clear();
m_frame->SetCurItem( NULL );
@@ -928,7 +938,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() );
// These are not selectable
case PCB_MODULE_EDGE_T:
case PCB_PAD_T:
{
@@ -942,6 +951,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
break;
}
// These are not selectable
case NOT_USED:
case TYPE_NOT_INIT:
return false;
@@ -955,8 +965,20 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
}
bool SELECTION_TOOL::modifiable( const BOARD_ITEM* aItem ) const
{
if( aItem->Type() == PCB_MARKER_T )
return false;
return true;
}
void SELECTION_TOOL::select( BOARD_ITEM* aItem )
{
if( aItem->IsSelected() )
return;
// Modules are treated in a special way - when they are selected, we have to mark
// all the parts that make the module as selected
if( aItem->Type() == PCB_MODULE_T )
@@ -992,6 +1014,9 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
{
if( !aItem->IsSelected() )
return;
// Modules are treated in a special way - when they are selected, we have to
// unselect all the parts that make the module, not the module itself
if( aItem->Type() == PCB_MODULE_T )
@@ -1011,9 +1036,6 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
m_frame->SetCurItem( NULL );
m_locked = true;
}
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( UnselectedEvent );
}
@@ -1379,11 +1401,23 @@ bool SELECTION_TOOL::SanitizeSelection()
}
}
BOOST_FOREACH( BOARD_ITEM* item, rejected )
unselect( item );
if( !rejected.empty() )
{
BOOST_FOREACH( BOARD_ITEM* item, rejected )
unselect( item );
BOOST_FOREACH( BOARD_ITEM* item, added )
select( item );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( UnselectedEvent );
}
if( !added.empty() )
{
BOOST_FOREACH( BOARD_ITEM* item, added )
select( item );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( UnselectedEvent );
}
return true;
}
+11 -7
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@@ -135,12 +135,7 @@ public:
*
* Returns the set of currently selected items.
*/
inline const SELECTION& GetSelection()
{
// The selected items list has been requested, so it is no longer preliminary
m_preliminary = false;
return m_selection;
}
const SELECTION& GetSelection();
/**
* Function EditModules()
@@ -277,6 +272,15 @@ private:
*/
bool selectable( const BOARD_ITEM* aItem ) const;
/**
* Function modifiable()
* Checks if an item might be modified. This function is used to filter out items
* from the selection when it is passed to other tools.
*
* @return True if the item fulfills conditions to be modified.
*/
bool modifiable( const BOARD_ITEM* aItem ) const;
/**
* Function select()
* Takes necessary action mark an item as selected.
+4 -1
View File
@@ -591,9 +591,12 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT )
{
zoneInfo.SetIsKeepout( true );
// Netcode and netname are irrelevant,
// Netcode, netname and some other settings are irrelevant,
// so ensure they are cleared
zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
zoneInfo.SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
zoneInfo.SetCornerRadius( 0 );
edited = InvokeKeepoutAreaEditor( this, &zoneInfo );
}
else