Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9a2dced07 | |||
| 52157acbfe | |||
| 17f220590b | |||
| 33027b8f66 | |||
| 064a9688c0 | |||
| c1ec63d4f9 | |||
| 995b2c517d | |||
| a8c0bc0430 | |||
| 902629c139 | |||
| 63e638cfab | |||
| 48b520a098 | |||
| b55352da7e | |||
| cd41a42775 | |||
| 6f82cec3a4 | |||
| 2f9cd25850 | |||
| 865bb54591 | |||
| 6d26e8e3e8 | |||
| 9c50a9fa4a | |||
| 406dd58002 | |||
| bd7ba5f6b1 | |||
| d174cff9ae | |||
| bbce24ab32 | |||
| ad2c5b40ff | |||
| 8e0784d4fa | |||
| 926818097b | |||
| fd65bd8e6e | |||
| d53c6f8abe | |||
| 2512375988 | |||
| 4b4d082fa4 | |||
| 374dfdbe16 | |||
| 3c476157c1 | |||
| 3af058a281 | |||
| 8a1e400d81 | |||
| fb4fa9ae41 | |||
| ede0ab5b79 | |||
| 2723898ff4 | |||
| b470d9ed8a | |||
| f0446aab90 | |||
| be3ee24826 | |||
| 68a1f9e512 | |||
| bf90966901 | |||
| 7a5e9cce6d | |||
| 3f7da644eb | |||
| e424dbea2d | |||
| 4d1fcff732 | |||
| dac08643c3 | |||
| 95fcf53353 | |||
| 7dc6abd533 | |||
| 042b49ee7b | |||
| 6a1dfd6e32 | |||
| b2855e6288 | |||
| 86f9f169cd | |||
| 9052b063de | |||
| 1a6be90c4f | |||
| 55de16e874 | |||
| ef2bb0b621 | |||
| 09d4543071 | |||
| 7ef63f0159 | |||
| d0e34bf013 | |||
| 46a17ff272 | |||
| 51cc4b8811 | |||
| 5634dfa6ed | |||
| 5a8d56f3db | |||
| 0c5ea8565d | |||
| 1431bd1143 | |||
| 7a3a7d1af6 | |||
| 761ddcad21 | |||
| 8aabdcff9c | |||
| 29d58ae063 | |||
| 90ef84b958 | |||
| 9cebea5f11 | |||
| b7b955e37b | |||
| 87d4249d9f | |||
| 8bf5240d60 | |||
| 20bebeb543 | |||
| 1f4b288664 | |||
| 5cf346c233 | |||
| 617755f991 | |||
| 45329ceafa | |||
| 69858ab4c0 | |||
| c53a1e00f6 | |||
| 178a36fc66 | |||
| 8ce38d3820 | |||
| e0802dcd26 | |||
| c8a1c5c707 |
@@ -36,9 +36,9 @@ string( REGEX MATCH
|
||||
if( CMAKE_MATCH_COUNT EQUAL 3 )
|
||||
# Match slot 0 is the full string, so we want slots 1 & 2
|
||||
set( KICAD_MAJOR_MINOR_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" )
|
||||
set( KICAD_MAJOR_MINOR_VERSION_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2} }" )
|
||||
|
||||
set( KICAD_MAJOR_MINOR_PATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" )
|
||||
set( KICAD_MAJOR_MINOR_PATCH_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3} }" )
|
||||
|
||||
set( KICAD_MAJOR_VERSION "${CMAKE_MATCH_1}" )
|
||||
set( KICAD_MINOR_VERSION "${CMAKE_MATCH_2}" )
|
||||
@@ -67,7 +67,7 @@ set( _wvh_new_version_text
|
||||
#define KICAD_MINOR_VERSION \"${KICAD_MINOR_VERSION}\"
|
||||
#define KICAD_PATCH_VERSION \"${KICAD_PATCH_VERSION}\"
|
||||
#define KICAD_MAJOR_MINOR_VERSION \"${KICAD_MAJOR_MINOR_VERSION}\"
|
||||
#define KICAD_MAJOR_MINOR_VERSION_TUPLE ${KICAD_MAJOR_MINOR_VERSION_TUPLE}
|
||||
#define KICAD_MAJOR_MINOR_PATCH_TUPLE ${KICAD_MAJOR_MINOR_PATCH_TUPLE}
|
||||
#define KICAD_WIN32_RC_PRODVER ${KICAD_WIN32_RC_PRODVER}
|
||||
#define KICAD_WIN32_RC_PRODVER_STR \"${KICAD_WIN32_RC_PRODVER_STR}\"
|
||||
#define KICAD_WIN32_RC_FILEVER ${KICAD_WIN32_RC_FILEVER}
|
||||
|
||||
@@ -293,6 +293,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
# Find wxWidgets multilib base libraries.
|
||||
find_library(WX_base${_DBG}
|
||||
NAMES
|
||||
wxbase32${_UCD}${_DBG}
|
||||
wxbase31${_UCD}${_DBG}
|
||||
wxbase30${_UCD}${_DBG}
|
||||
wxbase29${_UCD}${_DBG}
|
||||
@@ -307,6 +308,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
foreach(LIB net odbc xml)
|
||||
find_library(WX_${LIB}${_DBG}
|
||||
NAMES
|
||||
wxbase32${_UCD}${_DBG}_${LIB}
|
||||
wxbase31${_UCD}${_DBG}_${LIB}
|
||||
wxbase30${_UCD}${_DBG}_${LIB}
|
||||
wxbase29${_UCD}${_DBG}_${LIB}
|
||||
@@ -323,6 +325,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
# Find wxWidgets monolithic library.
|
||||
find_library(WX_mono${_DBG}
|
||||
NAMES
|
||||
wx${_PF}${_UNV}32${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}31${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}30${_UCD}${_DBG}
|
||||
wx${_PF}${_UNV}29${_UCD}${_DBG}
|
||||
@@ -340,6 +343,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
|
||||
stc ribbon propgrid webview)
|
||||
find_library(WX_${LIB}${_DBG}
|
||||
NAMES
|
||||
wx${_PF}${_UNV}32${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}31${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}30${_UCD}${_DBG}_${LIB}
|
||||
wx${_PF}${_UNV}29${_UCD}${_DBG}_${LIB}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.6" )
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.7" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -619,8 +619,8 @@ set( TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp" )
|
||||
# generate logs is useful only if you have problems
|
||||
set( CREATE_LOG_FILES true )
|
||||
|
||||
set( BITMAP_INFO_FILE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.h" )
|
||||
set( BITMAP_INFO_TEMPLATE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.h.in" )
|
||||
set( BITMAP_INFO_FILE "${CMAKE_SOURCE_DIR}/common/bitmap_info.cpp" )
|
||||
set( BITMAP_INFO_TEMPLATE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.cpp.in" )
|
||||
set( BITMAP_INFO_LIST "" )
|
||||
|
||||
set( ALL_PNGS "" )
|
||||
@@ -739,7 +739,7 @@ function( bitmap_dir pngWidth pngHeight bmapList )
|
||||
png2png( ${tmpFile} ${pngPath} )
|
||||
|
||||
set( bitmapInfo
|
||||
" { BITMAPS::${bmn}, wxT( \"${pngFile}\" ), ${pngHeight}, wxT( \"${theme}\" ) },\n"
|
||||
" aBitmapInfoCache[BITMAPS::${bmn}].emplace_back( BITMAPS::${bmn}, wxT( \"${pngFile}\" ), ${pngHeight}, wxT( \"${theme}\" ) );\n"
|
||||
)
|
||||
|
||||
set( BITMAP_INFO_LIST "${BITMAP_INFO_LIST}${bitmapInfo}" )
|
||||
|
||||
@@ -315,6 +315,7 @@ set( COMMON_SRCS
|
||||
bin_mod.cpp
|
||||
bitmap.cpp
|
||||
bitmap_base.cpp
|
||||
bitmap_info.cpp
|
||||
bitmap_store.cpp
|
||||
board_printout.cpp
|
||||
build_version.cpp
|
||||
|
||||
@@ -226,22 +226,17 @@ wxString StringFromValue( EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol,
|
||||
|
||||
if( value_to_print != 0.0 && fabs( value_to_print ) <= 0.0001 )
|
||||
{
|
||||
len = sprintf( buf, "%.10f", value_to_print );
|
||||
len = snprintf( buf, sizeof( buf ) - 1, "%.10f", value_to_print );
|
||||
|
||||
while( --len > 0 && buf[len] == '0' )
|
||||
buf[len] = '\0';
|
||||
|
||||
if( buf[len]=='.' || buf[len]==',' )
|
||||
if( len >= 0 && ( buf[len]=='.' || buf[len]==',' ) )
|
||||
buf[len] = '\0';
|
||||
else
|
||||
++len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aUnits == EDA_UNITS::MILS )
|
||||
len = sprintf( buf, "%.7g", value_to_print );
|
||||
else
|
||||
len = sprintf( buf, "%.10g", value_to_print );
|
||||
snprintf( buf, sizeof( buf ) - 1, "%.10g", value_to_print );
|
||||
}
|
||||
|
||||
wxString stringValue( buf, wxConvUTF8 );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -101,7 +101,7 @@ BITMAP_STORE::BITMAP_STORE()
|
||||
{
|
||||
wxFileName path( PATHS::GetStockDataPath() + wxT( "/resources" ), IMAGE_ARCHIVE );
|
||||
|
||||
wxLogTrace( traceBitmaps, wxT( "Loading bitmaps from " ) + path.GetFullPath() );
|
||||
wxLogTrace( traceBitmaps, "Loading bitmaps from " + path.GetFullPath() );
|
||||
|
||||
m_archive = std::make_unique<ASSET_ARCHIVE>( path.GetFullPath() );
|
||||
|
||||
@@ -148,8 +148,8 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
|
||||
|
||||
if( count < 0 )
|
||||
{
|
||||
wxLogTrace( traceBitmaps, wxT( "Bitmap for %d, %d, %s has an info tag with file %s," )
|
||||
wxT( "but that file could not be found in the archive!" ),
|
||||
wxLogTrace( traceBitmaps, "Bitmap for %d, %d, %s has an info tag with file %s,"
|
||||
"but that file could not be found in the archive!",
|
||||
aBitmapId, aHeight, m_theme );
|
||||
data = s_imageNotFound;
|
||||
count = sizeof( s_imageNotFound );
|
||||
@@ -204,7 +204,7 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
|
||||
{
|
||||
if( !m_bitmapInfoCache.count( aBitmapId ) )
|
||||
{
|
||||
wxLogTrace( traceBitmaps, wxT( "No bitmap info available for %d" ), aBitmapId );
|
||||
wxLogTrace( traceBitmaps, "No bitmap info available for %d", aBitmapId );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
|
||||
|
||||
if( fn.IsEmpty() )
|
||||
{
|
||||
wxLogTrace( traceBitmaps, wxT( "No bitmap found matching ID %d, height %d, theme %s" ),
|
||||
wxLogTrace( traceBitmaps, "No bitmap found matching ID %d, height %d, theme %s",
|
||||
aBitmapId, aHeight, m_theme );
|
||||
return m_bitmapInfoCache.at( aBitmapId ).begin()->filename;
|
||||
}
|
||||
@@ -235,6 +235,5 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
|
||||
|
||||
void BITMAP_STORE::buildBitmapInfoCache()
|
||||
{
|
||||
for( const BITMAP_INFO& entry : g_BitmapInfo )
|
||||
m_bitmapInfoCache[entry.id].emplace_back( entry );
|
||||
BuildBitmapInfo( m_bitmapInfoCache );
|
||||
}
|
||||
|
||||
@@ -116,6 +116,10 @@ void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPa
|
||||
{
|
||||
for( int i = 0; i < LAYER_ID_COUNT; ++i )
|
||||
dstSettings->SetLayerColor( i, COLOR4D::BLACK );
|
||||
|
||||
// In B&W mode, draw the background only in wxhite, because any other color
|
||||
// will be replaced by a black background
|
||||
dstSettings->SetBackgroundColor( COLOR4D::WHITE );
|
||||
}
|
||||
else // color enabled
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <dialog_shim.h>
|
||||
#include <ignore.h>
|
||||
#include <kiway_player.h>
|
||||
#include <kiway.h>
|
||||
#include <pgm_base.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <kiplatform/ui.h>
|
||||
@@ -122,6 +123,9 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
|
||||
if( kiwayHolder )
|
||||
SetKiway( this, &kiwayHolder->Kiway() );
|
||||
|
||||
if( HasKiway() )
|
||||
Kiway().SetBlockingDialog( this );
|
||||
|
||||
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
|
||||
Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
|
||||
|
||||
@@ -143,6 +147,9 @@ DIALOG_SHIM::~DIALOG_SHIM()
|
||||
if( IsQuasiModal() )
|
||||
EndQuasiModal( wxID_CANCEL );
|
||||
|
||||
if( HasKiway() )
|
||||
Kiway().SetBlockingDialog( nullptr );
|
||||
|
||||
if( m_qmodal_parent_disabler )
|
||||
delete m_qmodal_parent_disabler; // usually NULL by now
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ bool SHADER::Link()
|
||||
|
||||
// Check the Link state
|
||||
GLint tmp;
|
||||
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB, &tmp );
|
||||
glGetProgramiv( programNumber, GL_LINK_STATUS, &tmp );
|
||||
isShaderLinked = !!tmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
+14
-1
@@ -50,7 +50,7 @@ int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
|
||||
|
||||
|
||||
KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
|
||||
m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr )
|
||||
m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr ), m_blockingDialog( wxID_NONE )
|
||||
{
|
||||
SetTop( aTop ); // hook player_destroy_handler() into aTop.
|
||||
|
||||
@@ -606,6 +606,19 @@ void KIWAY::ProjectChanged()
|
||||
}
|
||||
}
|
||||
|
||||
wxWindow* KIWAY::GetBlockingDialog()
|
||||
{
|
||||
return wxWindow::FindWindowById( m_blockingDialog );
|
||||
}
|
||||
|
||||
void KIWAY::SetBlockingDialog( wxWindow* aWin )
|
||||
{
|
||||
if( !aWin )
|
||||
m_blockingDialog = wxID_NONE;
|
||||
else
|
||||
m_blockingDialog = aWin->GetId();
|
||||
}
|
||||
|
||||
|
||||
bool KIWAY::ProcessEvent( wxEvent& aEvent )
|
||||
{
|
||||
|
||||
@@ -96,7 +96,12 @@ static struct PGM_SINGLE_TOP : public PGM_BASE
|
||||
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
|
||||
#endif
|
||||
if( frame )
|
||||
{
|
||||
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,13 @@ int COMMON_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
|
||||
if( wxWindow::FindFocus() != editor )
|
||||
editor->SetFocus();
|
||||
|
||||
// If the player is currently blocked, focus the user attention on the correct window
|
||||
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
|
||||
{
|
||||
blocking_win->Raise();
|
||||
blocking_win->SetFocus();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,8 @@ TOOL_MANAGER::TOOL_MANAGER() :
|
||||
m_warpMouseAfterContextMenu( true ),
|
||||
m_menuActive( false ),
|
||||
m_menuOwner( -1 ),
|
||||
m_activeState( nullptr )
|
||||
m_activeState( nullptr ),
|
||||
m_shuttingDown( false )
|
||||
{
|
||||
m_actionMgr = new ACTION_MANAGER( this );
|
||||
}
|
||||
@@ -313,6 +314,9 @@ VECTOR2D TOOL_MANAGER::GetCursorPosition() const
|
||||
|
||||
bool TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow, void* aParam )
|
||||
{
|
||||
if( m_shuttingDown )
|
||||
return true;
|
||||
|
||||
bool handled = false;
|
||||
TOOL_EVENT event = aAction.MakeEvent();
|
||||
|
||||
@@ -446,10 +450,22 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
|
||||
|
||||
void TOOL_MANAGER::ShutdownAllTools()
|
||||
{
|
||||
m_shuttingDown = true;
|
||||
|
||||
// Create a temporary list of tools to iterate over since when the tools shutdown
|
||||
// they remove themselves from the list automatically (invalidating the iterator)
|
||||
ID_LIST tmpList = m_activeTools;
|
||||
|
||||
// Make sure each tool knows that it is shutting down, so that loops get shut down
|
||||
// at the dispatcher
|
||||
for( auto id : tmpList )
|
||||
{
|
||||
if( m_toolIdIndex.count( id ) == 0 )
|
||||
continue;
|
||||
|
||||
m_toolIdIndex[id]->shutdown = true;
|
||||
}
|
||||
|
||||
for( auto id : tmpList )
|
||||
{
|
||||
ShutdownTool( id );
|
||||
@@ -949,6 +965,11 @@ TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState )
|
||||
|
||||
bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Once the tool manager is shutting down, don't start
|
||||
// activating more tools
|
||||
if( m_shuttingDown )
|
||||
return true;
|
||||
|
||||
bool handled = processEvent( aEvent );
|
||||
|
||||
TOOL_STATE* activeTool = GetCurrentToolState();
|
||||
|
||||
@@ -167,6 +167,9 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( wxWindow* blocking_win = fpframe->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
if( fpframe->IsIconized() )
|
||||
fpframe->Iconize( false );
|
||||
|
||||
|
||||
@@ -49,10 +49,7 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map<wxString, wxString>& aMap )
|
||||
|
||||
curr_full_uuid.push_back( symbol->m_Uuid );
|
||||
|
||||
wxString ref = symbol->GetRef( curr_sheetpath );
|
||||
|
||||
if( symbol->GetUnitCount() > 1 )
|
||||
ref << LIB_SYMBOL::SubReference( symbol->GetUnitSelection( curr_sheetpath ) );
|
||||
wxString ref = symbol->GetRef( curr_sheetpath, true );
|
||||
|
||||
if( symbol->IsAnnotated( curr_sheetpath ) )
|
||||
aMap[ curr_full_uuid.AsString() ] = ref;
|
||||
|
||||
@@ -2714,8 +2714,21 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
|
||||
{
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
if( !pins.empty() )
|
||||
has_other_connections = true;
|
||||
// Stacked pins do not count as other connections but non-stacked pins do
|
||||
if( !has_other_connections && !pins.empty() )
|
||||
{
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
for( SCH_PIN* other_pin : pins )
|
||||
{
|
||||
if( other_pin->GetParent() != pin->GetParent()
|
||||
|| other_pin->GetPosition() != pin->GetPosition() )
|
||||
{
|
||||
has_other_connections = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pins.emplace_back( static_cast<SCH_PIN*>( item ) );
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
return false;
|
||||
|
||||
// We need to keep the name and the value the same at the moment!
|
||||
wxString newName = m_fields->at( VALUE_FIELD ).GetText();
|
||||
wxString newName = EscapeString( m_fields->at( VALUE_FIELD ).GetText(), CTX_LIBID );
|
||||
wxString oldName = m_libEntry->GetName();
|
||||
|
||||
if( oldName != newName )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 2010-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2010-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -196,6 +196,14 @@ void DIALOG_SCH_FIND::OnReplaceWithEnter( wxCommandEvent& aEvent )
|
||||
|
||||
void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateFlags();
|
||||
m_findDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SCH_FIND::updateFlags()
|
||||
{
|
||||
// Rebuild the search flags in m_findReplaceData from dialog settings
|
||||
int flags = 0;
|
||||
|
||||
if( m_radioForward->GetValue() )
|
||||
@@ -223,12 +231,13 @@ void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
|
||||
flags |= FR_REPLACE_REFERENCES;
|
||||
|
||||
m_findReplaceData->SetFlags( flags );
|
||||
m_findDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateFlags(); // Ensure search flags are up to date
|
||||
|
||||
int index = m_comboFind->FindString( m_comboFind->GetValue(), true );
|
||||
|
||||
if( index == wxNOT_FOUND )
|
||||
@@ -250,6 +259,8 @@ void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
|
||||
|
||||
void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateFlags(); // Ensure search flags are up to date
|
||||
|
||||
int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true );
|
||||
|
||||
if( index == wxNOT_FOUND )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2010-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2010-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -75,6 +75,9 @@ protected:
|
||||
void OnFind( wxCommandEvent& aEvent ) override;
|
||||
void OnReplace( wxCommandEvent& aEvent ) override;
|
||||
|
||||
// Rebuild the search flags from dialog settings
|
||||
void updateFlags();
|
||||
|
||||
SCH_EDIT_FRAME* m_frame;
|
||||
SCH_EDITOR_CONTROL* m_editorControl;
|
||||
wxFindReplaceData* m_findReplaceData;
|
||||
|
||||
+35
-17
@@ -669,13 +669,13 @@ void LEGACY_RESCUER::OpenRescueLibrary()
|
||||
wxFileName fn = GetRescueLibraryFileName( m_schematic );
|
||||
|
||||
std::unique_ptr<SYMBOL_LIB> rescue_lib = std::make_unique<SYMBOL_LIB>( SCH_LIB_TYPE::LT_EESCHEMA,
|
||||
fn.GetFullPath() );
|
||||
fn.GetFullPath() );
|
||||
|
||||
m_rescue_lib = std::move( rescue_lib );
|
||||
m_rescue_lib->EnableBuffering();
|
||||
|
||||
// If a rescue library already exists copy the contents of that library so we do not
|
||||
// lose an previous rescues.
|
||||
// lose any previous rescues.
|
||||
SYMBOL_LIB* rescueLib = m_prj->SchLibs()->FindLibrary( fn.GetName() );
|
||||
|
||||
if( rescueLib )
|
||||
@@ -810,6 +810,27 @@ void SYMBOL_LIB_TABLE_RESCUER::OpenRescueLibrary()
|
||||
{
|
||||
m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||
(*m_properties)[ SCH_LEGACY_PLUGIN::PropBuffering ] = "";
|
||||
|
||||
wxFileName fn = GetRescueLibraryFileName( m_schematic );
|
||||
|
||||
// If a rescue library already exists copy the contents of that library so we do not
|
||||
// lose any previous rescues.
|
||||
if( m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
|
||||
{
|
||||
std::vector<LIB_SYMBOL*> symbols;
|
||||
|
||||
try
|
||||
{
|
||||
m_prj->SchSymbolLibTable()->LoadSymbolLib( symbols, fn.GetName() );
|
||||
}
|
||||
catch( ... /* IO_ERROR */ )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
AddSymbol( symbol );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -818,21 +839,21 @@ bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( wxWindow *aParent )
|
||||
wxString msg;
|
||||
wxFileName fn = GetRescueLibraryFileName( m_schematic );
|
||||
|
||||
try
|
||||
{
|
||||
m_pi->SaveLibrary( fn.GetFullPath() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Failed to save rescue library %s." ), fn.GetFullPath() );
|
||||
DisplayErrorMessage( aParent, msg, ioe.What() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the rescue library already exists in the symbol library table no need save it to add
|
||||
// it to the table.
|
||||
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_pi->SaveLibrary( fn.GetFullPath() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
msg.Printf( _( "Failed to save rescue library %s." ), fn.GetFullPath() );
|
||||
DisplayErrorMessage( aParent, msg, ioe.What() );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString uri = wxT( "${KIPRJMOD}/" ) + fn.GetFullName();
|
||||
wxString libNickname = fn.GetName();
|
||||
|
||||
@@ -880,10 +901,7 @@ void SYMBOL_LIB_TABLE_RESCUER::AddSymbol( LIB_SYMBOL* aNewSymbol )
|
||||
|
||||
try
|
||||
{
|
||||
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
|
||||
m_pi->SaveSymbol( fn.GetFullPath(), new LIB_SYMBOL( *aNewSymbol ), m_properties.get() );
|
||||
else
|
||||
m_prj->SchSymbolLibTable()->SaveSymbol( fn.GetName(), new LIB_SYMBOL( *aNewSymbol ) );
|
||||
m_pi->SaveSymbol( fn.GetFullPath(), new LIB_SYMBOL( *aNewSymbol ), m_properties.get() );
|
||||
}
|
||||
catch( ... /* IO_ERROR */ )
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <convert_to_biu.h>
|
||||
#include <ki_exception.h>
|
||||
#include <math/util.h>
|
||||
|
||||
#include <wx/log.h>
|
||||
|
||||
@@ -43,7 +44,12 @@ ALTIUM_SCH_RECORD ReadRecord( const std::map<wxString, wxString>& aProps )
|
||||
|
||||
constexpr int Altium2KiCadUnit( const int val, const int frac )
|
||||
{
|
||||
return Mils2iu( val ) * 10 + Mils2iu( frac ) / 10000; // TODO: correct, rounding issues?
|
||||
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
|
||||
|
||||
double dbase = 10 * Mils2iu( val );
|
||||
double dfrac = Mils2iu( frac ) / 10000.0;
|
||||
|
||||
return KiROUND( Clamp<double>( -int_limit, ( dbase + dfrac ) / 10.0, int_limit ) ) * 10;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
|
||||
int CompareRef( const SCH_REFERENCE& item ) const
|
||||
{
|
||||
return m_ref.compare( item.m_ref );
|
||||
return m_ref.CmpNoCase( item.m_ref );
|
||||
}
|
||||
|
||||
int CompareLibName( const SCH_REFERENCE& item ) const
|
||||
@@ -168,7 +168,7 @@ private:
|
||||
friend class SCH_REFERENCE_LIST;
|
||||
|
||||
/// Symbol reference prefix, without number (for IC1, this is IC) )
|
||||
UTF8 m_ref; // it's private, use the accessors please
|
||||
wxString m_ref; // it's private, use the accessors please
|
||||
SCH_SYMBOL* m_rootSymbol; ///< The symbol associated the reference object.
|
||||
LIB_SYMBOL* m_libPart; ///< The source symbol from a library.
|
||||
wxPoint m_symbolPos; ///< The physical position of the symbol in schematic
|
||||
@@ -454,7 +454,7 @@ public:
|
||||
|
||||
printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n",
|
||||
i,
|
||||
schref.m_ref.c_str(),
|
||||
schref.m_ref.ToStdString().c_str(),
|
||||
schref.m_numRef,
|
||||
TO_UTF8( schref.GetLibPart()->GetName() ) );
|
||||
}
|
||||
|
||||
@@ -225,6 +225,11 @@ public:
|
||||
{
|
||||
return type_tree->end( m_rect );
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return type_tree->Count() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
EE_TYPE OfType( KICAD_T aType ) const
|
||||
|
||||
+31
-3
@@ -838,9 +838,10 @@ void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
|
||||
void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
|
||||
{
|
||||
// Ensure links are up to date, even if a library was reloaded for some reason:
|
||||
std::vector< SCH_ITEM* > junctions;
|
||||
std::vector< SCH_ITEM* > bitmaps;
|
||||
std::vector< SCH_ITEM* > other;
|
||||
std::vector<SCH_ITEM*> junctions;
|
||||
std::vector<SCH_ITEM*> bitmaps;
|
||||
std::vector<SCH_SYMBOL*> symbols;
|
||||
std::vector<SCH_ITEM*> other;
|
||||
|
||||
for( SCH_ITEM* item : Items() )
|
||||
{
|
||||
@@ -853,6 +854,21 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
|
||||
bitmaps.push_back( item );
|
||||
else
|
||||
other.push_back( item );
|
||||
|
||||
// Where the symbols overlap each other, we need to plot the text items a second
|
||||
// time to get them on top of the overlapping element. This collection is in addition
|
||||
// to the symbols already collected in `other`
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
for( SCH_ITEM* sym : m_rtree.Overlapping( SCH_SYMBOL_T, item->GetBoundingBox() ) )
|
||||
{
|
||||
if( sym != item )
|
||||
{
|
||||
symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sort to ensure plot-order consistency with screen drawing
|
||||
@@ -882,6 +898,18 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
|
||||
item->Plot( aPlotter );
|
||||
}
|
||||
|
||||
// After plotting the symbols as a group above (in `other`), we need to overplot the pins
|
||||
// and symbols to ensure that they are always visible
|
||||
for( const SCH_SYMBOL* sym :symbols )
|
||||
{
|
||||
aPlotter->SetCurrentLineWidth( std::max( sym->GetPenWidth(), defaultPenWidth ) );
|
||||
|
||||
for( SCH_FIELD field : sym->GetFields() )
|
||||
field.Plot( aPlotter );
|
||||
|
||||
sym->PlotPins( aPlotter );
|
||||
}
|
||||
|
||||
for( const SCH_ITEM* item : junctions )
|
||||
{
|
||||
aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
|
||||
|
||||
@@ -1912,6 +1912,35 @@ void SCH_SYMBOL::Plot( PLOTTER* aPlotter ) const
|
||||
}
|
||||
|
||||
|
||||
void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
|
||||
{
|
||||
if( m_part )
|
||||
{
|
||||
LIB_PINS libPins;
|
||||
m_part->GetPins( libPins, GetUnit(), GetConvert() );
|
||||
|
||||
// Copy the source to stay const
|
||||
LIB_SYMBOL tempSymbol( *m_part );
|
||||
LIB_PINS tempPins;
|
||||
tempSymbol.GetPins( tempPins, GetUnit(), GetConvert() );
|
||||
|
||||
TRANSFORM transform = GetTransform();
|
||||
|
||||
// Copy the pin info from the symbol to the temp pins
|
||||
for( unsigned i = 0; i < tempPins.size(); ++ i )
|
||||
{
|
||||
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
|
||||
LIB_PIN* tempPin = tempPins[ i ];
|
||||
|
||||
tempPin->SetName( symbolPin->GetShownName() );
|
||||
tempPin->SetType( symbolPin->GetType() );
|
||||
tempPin->SetShape( symbolPin->GetShape() );
|
||||
tempPin->Plot( aPlotter, m_pos, false, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SYMBOL::HasBrightenedPins()
|
||||
{
|
||||
for( const auto& pin : m_pins )
|
||||
|
||||
@@ -650,6 +650,14 @@ public:
|
||||
|
||||
void Plot( PLOTTER* aPlotter ) const override;
|
||||
|
||||
/**
|
||||
* Plot just the symbol pins. This is separated to match the GAL display order. The pins are
|
||||
* ALSO plotted with the symbol group. This replotting allows us to ensure that they are shown above
|
||||
* other elements in the schematic
|
||||
* @param aPlotter
|
||||
*/
|
||||
void PlotPins( PLOTTER* aPlotter ) const;
|
||||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
@@ -1528,6 +1528,11 @@ void SIM_PLOT_FRAME::onProbe( wxCommandEvent& event )
|
||||
if( m_schematicFrame == nullptr )
|
||||
return;
|
||||
|
||||
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe );
|
||||
m_schematicFrame->Raise();
|
||||
}
|
||||
@@ -1540,6 +1545,11 @@ void SIM_PLOT_FRAME::onTune( wxCommandEvent& event )
|
||||
if( m_schematicFrame == nullptr )
|
||||
return;
|
||||
|
||||
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune );
|
||||
m_schematicFrame->Raise();
|
||||
}
|
||||
|
||||
@@ -1119,6 +1119,9 @@ void SYMBOL_EDIT_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextV
|
||||
GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
|
||||
GetCanvas()->GetGAL()->DrawGrid();
|
||||
|
||||
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
|
||||
GetCanvas()->Refresh();
|
||||
|
||||
RecreateToolbars();
|
||||
|
||||
if( aEnvVarsChanged )
|
||||
@@ -1166,6 +1169,7 @@ void SYMBOL_EDIT_FRAME::RebuildView()
|
||||
GetCanvas()->GetView()->HideDrawingSheet();
|
||||
GetCanvas()->GetView()->ClearHiddenFlags();
|
||||
|
||||
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
|
||||
GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +460,11 @@ void SYMBOL_VIEWER_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent )
|
||||
m_unitChoice->Clear();
|
||||
|
||||
for( int ii = 0; ii < unit_count; ii++ )
|
||||
m_unitChoice->Append( wxString::Format( _( "Unit %c" ), 'A' + ii ) );
|
||||
{
|
||||
wxString sub = LIB_SYMBOL::SubReference( ii + 1, false );
|
||||
wxString unit = wxString::Format( _( "Unit %s" ), sub );
|
||||
m_unitChoice->Append( unit );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,9 @@ bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
|
||||
}
|
||||
|
||||
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -646,7 +646,8 @@ TOOL_ACTION EE_ACTIONS::toggleHiddenFields( "eeschema.EditorControl.showHiddenFi
|
||||
_( "Show Hidden Fields" ), _( "Toggle display of hidden text fields" ) );
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines",
|
||||
AS_GLOBAL, 0, "",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + ' ', "",
|
||||
_( "Force H/V Wires and Buses" ), _( "Switch H & V only mode for new wires and buses" ),
|
||||
BITMAPS::lines90 );
|
||||
|
||||
|
||||
@@ -482,6 +482,9 @@ int EE_INSPECTION_TOOL::RunSimulation( const TOOL_EVENT& aEvent )
|
||||
if( !simFrame )
|
||||
return -1;
|
||||
|
||||
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
simFrame->Show( true );
|
||||
|
||||
// On Windows, Raise() does not bring the window on screen, when iconized
|
||||
|
||||
@@ -348,6 +348,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
symbol->SetPosition( (wxPoint)cursorPos );
|
||||
m_view->Update( symbol );
|
||||
m_frame->SetMsgPanel( symbol );
|
||||
}
|
||||
else if( symbol && evt->IsAction( &ACTIONS::doDelete ) )
|
||||
{
|
||||
@@ -570,6 +571,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
|
||||
m_frame->SetMsgPanel( image );
|
||||
}
|
||||
else if( image && evt->IsAction( &ACTIONS::doDelete ) )
|
||||
{
|
||||
@@ -775,6 +777,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
|
||||
previewItem->SetPosition( (wxPoint)cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( previewItem->Clone() );
|
||||
m_frame->SetMsgPanel( previewItem );
|
||||
}
|
||||
else if( evt->Category() == TC_COMMAND )
|
||||
{
|
||||
@@ -1031,6 +1034,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_view->AddToPreview( aChild->Clone() );
|
||||
} );
|
||||
m_frame->SetMsgPanel( item );
|
||||
};
|
||||
|
||||
auto cleanup =
|
||||
@@ -1420,6 +1424,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
||||
sizeSheet( sheet, cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( sheet->Clone() );
|
||||
m_frame->SetMsgPanel( sheet );
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
|
||||
@@ -1394,6 +1394,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
|
||||
true );
|
||||
|
||||
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
editor->LoadSymbolFromSchematic( symbol );
|
||||
|
||||
editor->Show( true );
|
||||
@@ -1404,6 +1407,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
|
||||
true );
|
||||
|
||||
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
|
||||
|
||||
editor->Show( true );
|
||||
|
||||
@@ -765,6 +765,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||
if( !simFrame ) // Defensive coding; shouldn't happen.
|
||||
return 0;
|
||||
|
||||
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
// Deactivate other tools; particularly important if another PICKER is currently running
|
||||
Activate();
|
||||
|
||||
@@ -912,7 +915,12 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
|
||||
KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
|
||||
|
||||
if( simFrame )
|
||||
{
|
||||
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
static_cast<SIM_PLOT_FRAME*>( simFrame )->AddTuner( symbol );
|
||||
}
|
||||
|
||||
// We do not really want to keep a symbol selected in schematic,
|
||||
// so clear the current selection
|
||||
@@ -1986,6 +1994,9 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( symbolEditor )
|
||||
{
|
||||
if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
if( aEvent.IsAction( &EE_ACTIONS::editWithLibEdit ) )
|
||||
symbolEditor->LoadSymbolFromSchematic( symbol );
|
||||
else if( aEvent.IsAction( &EE_ACTIONS::editLibSymbolWithLibEdit ) )
|
||||
|
||||
@@ -518,6 +518,11 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
|
||||
return 0;
|
||||
}
|
||||
|
||||
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
wxCHECK( libSymbol->GetLibId().IsValid(), 0 );
|
||||
|
||||
SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),
|
||||
@@ -529,7 +534,7 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
|
||||
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
|
||||
|
||||
schframe->Raise();
|
||||
schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, true, symbol );
|
||||
schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, false, symbol );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -22,25 +21,10 @@
|
||||
* This file is auto-generated by CMake when MAINTAIN_PNGS is on. Do not edit by hand!
|
||||
*/
|
||||
|
||||
#ifndef KICAD_BITMAP_INFO_H
|
||||
#define KICAD_BITMAP_INFO_H
|
||||
|
||||
#include <vector>
|
||||
#include <bitmaps/bitmaps_list.h>
|
||||
#include <bitmaps/bitmap_info.h>
|
||||
|
||||
#include <wx/string.h> // wxT
|
||||
|
||||
struct BITMAP_INFO
|
||||
void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBitmapInfoCache )
|
||||
{
|
||||
BITMAPS id;
|
||||
wxString filename;
|
||||
int height;
|
||||
wxString theme;
|
||||
};
|
||||
|
||||
|
||||
const std::vector<BITMAP_INFO> g_BitmapInfo = {
|
||||
${BITMAP_INFO_LIST}
|
||||
};
|
||||
|
||||
#endif // KICAD_BITMAP_INFO_H
|
||||
+13
-1029
File diff suppressed because it is too large
Load Diff
+44
-44
@@ -24,7 +24,7 @@
|
||||
#ifndef GL_UTILS_H
|
||||
#define GL_UTILS_H
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
#include <wx/glcanvas.h>
|
||||
#include <wx/utils.h>
|
||||
|
||||
@@ -45,62 +45,63 @@ public:
|
||||
/// Windows would include <wglext.h> and call wglSwapIntervalEXT
|
||||
#if defined( __linux__ ) && !defined( KICAD_USE_EGL )
|
||||
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
GLXDrawable drawable = glXGetCurrentDrawable();
|
||||
std::string vendor( reinterpret_cast<const char*>( glGetString( GL_VENDOR ) ) );
|
||||
bool is_mesa = ( vendor.find( "Mesa" ) != std::string::npos );
|
||||
|
||||
if( !is_mesa && glXSwapIntervalEXT && glXQueryDrawable && dpy && drawable )
|
||||
if( Display* dpy = glXGetCurrentDisplay() )
|
||||
{
|
||||
GLXDrawable drawable = glXGetCurrentDrawable();
|
||||
|
||||
std::string exts( glXQueryExtensionsString( dpy, DefaultScreen( dpy ) ) );
|
||||
|
||||
if( aVal < 0 )
|
||||
if( glXSwapIntervalEXT && glXQueryDrawable && drawable
|
||||
&& exts.find( "GLX_EXT_swap_control" ) != std::string::npos )
|
||||
{
|
||||
if( exts.find( "GLX_EXT_swap_control_tear" ) == std::string::npos )
|
||||
if( aVal < 0 )
|
||||
{
|
||||
aVal = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Even though the extensions might be available,
|
||||
// we need to be sure that late/adaptive swaps are
|
||||
// enabled on the drawable.
|
||||
|
||||
unsigned lateSwapsEnabled = 0;
|
||||
glXQueryDrawable( dpy, drawable, GLX_LATE_SWAPS_TEAR_EXT, &lateSwapsEnabled );
|
||||
|
||||
if( !lateSwapsEnabled )
|
||||
if( exts.find( "GLX_EXT_swap_control_tear" ) == std::string::npos )
|
||||
{
|
||||
aVal = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Even though the extensions might be available,
|
||||
// we need to be sure that late/adaptive swaps are
|
||||
// enabled on the drawable.
|
||||
|
||||
unsigned lateSwapsEnabled = 0;
|
||||
glXQueryDrawable( dpy, drawable, GLX_LATE_SWAPS_TEAR_EXT,
|
||||
&lateSwapsEnabled );
|
||||
|
||||
if( !lateSwapsEnabled )
|
||||
{
|
||||
aVal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned clampedInterval;
|
||||
glXSwapIntervalEXT( dpy, drawable, aVal );
|
||||
glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval );
|
||||
|
||||
return clampedInterval;
|
||||
}
|
||||
|
||||
unsigned clampedInterval;
|
||||
glXSwapIntervalEXT( dpy, drawable, aVal );
|
||||
glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval );
|
||||
if( glXSwapIntervalMESA && glXGetSwapIntervalMESA
|
||||
&& exts.find( "GLX_MESA_swap_control" ) != std::string::npos )
|
||||
{
|
||||
if( aVal < 0 )
|
||||
aVal = 0;
|
||||
|
||||
return clampedInterval;
|
||||
}
|
||||
glXSwapIntervalMESA( aVal );
|
||||
return glXGetSwapIntervalMESA();
|
||||
}
|
||||
|
||||
if( glXSwapIntervalMESA &&glXGetSwapIntervalMESA )
|
||||
{
|
||||
if( aVal < 0 )
|
||||
aVal = 0;
|
||||
if( aVal > 0 && glXSwapIntervalSGI
|
||||
&& exts.find( "GLX_SGI_swap_control" ) != std::string::npos )
|
||||
{
|
||||
if( glXSwapIntervalSGI( aVal ) )
|
||||
glXSwapIntervalSGI( 1 );
|
||||
|
||||
glXSwapIntervalMESA( aVal );
|
||||
return glXGetSwapIntervalMESA();
|
||||
}
|
||||
|
||||
if( glXSwapIntervalSGI )
|
||||
{
|
||||
if( aVal < 1 )
|
||||
aVal = 1;
|
||||
|
||||
if( glXSwapIntervalSGI( aVal ) )
|
||||
glXSwapIntervalSGI( 1 );
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return std::numeric_limits<int>::max();
|
||||
@@ -111,4 +112,3 @@ public:
|
||||
};
|
||||
|
||||
#endif /* GL_CONTEXT_MANAGER_H */
|
||||
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <eda_rect.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
// First some utility classes and functions
|
||||
|
||||
/// Equality test for "const char*" type used in very specialized KEYWORD_MAP below
|
||||
struct iequal_to : std::binary_function< const char*, const char*, bool >
|
||||
struct iequal_to
|
||||
{
|
||||
bool operator()( const char* x, const char* y ) const
|
||||
{
|
||||
@@ -77,7 +76,7 @@ struct fnv_1a
|
||||
|
||||
|
||||
/// Hash function for wxString, counterpart of std::string hash
|
||||
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
|
||||
struct WXSTRING_HASH
|
||||
{
|
||||
std::size_t operator()( const wxString& aString ) const
|
||||
{
|
||||
@@ -128,9 +127,5 @@ struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
|
||||
*/
|
||||
typedef std::unordered_map< const char*, int, fnv_1a, iequal_to > KEYWORD_MAP;
|
||||
|
||||
/// Map a C string to an EDA_RECT.
|
||||
/// The key is the classname of the derived wxformbuilder dialog.
|
||||
typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP;
|
||||
|
||||
|
||||
#endif // HASHTABLES_H_
|
||||
|
||||
@@ -392,6 +392,13 @@ public:
|
||||
|
||||
bool ProcessEvent( wxEvent& aEvent ) override;
|
||||
|
||||
/**
|
||||
* Gets the window pointer to the blocking dialog (to send it signals)
|
||||
* @return Pointer to blocking dialog window or null if none
|
||||
*/
|
||||
wxWindow* GetBlockingDialog();
|
||||
void SetBlockingDialog( wxWindow* aWin );
|
||||
|
||||
private:
|
||||
/// Get the [path &] name of the DSO holding the requested FACE_T.
|
||||
const wxString dso_search_path( FACE_T aFaceId );
|
||||
@@ -426,6 +433,8 @@ private:
|
||||
|
||||
wxFrame* m_top; // Usually m_top is the Project manager
|
||||
|
||||
wxWindowID m_blockingDialog;
|
||||
|
||||
// An array to store the window ID of PLAYER frames which were run.
|
||||
// A non empty name means only a PLAYER was run at least one time.
|
||||
// Empty entries are represented by wxID_NONE.
|
||||
|
||||
@@ -56,6 +56,15 @@ public:
|
||||
return *m_kiway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safety check before asking for the Kiway reference
|
||||
* @return true if kiway is non-null
|
||||
*/
|
||||
bool HasKiway() const
|
||||
{
|
||||
return m_kiway != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the #PROJECT associated with this #KIWAY.
|
||||
*/
|
||||
|
||||
@@ -578,6 +578,9 @@ private:
|
||||
|
||||
///< Pointer to the state object corresponding to the currently executed tool.
|
||||
TOOL_STATE* m_activeState;
|
||||
|
||||
///< True if the tool manager is shutting down (don't process additional events)
|
||||
bool m_shuttingDown;
|
||||
};
|
||||
|
||||
#endif // __TOOL_MANAGER_H
|
||||
|
||||
@@ -183,6 +183,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
|
||||
{
|
||||
KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true );
|
||||
|
||||
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) );
|
||||
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
|
||||
|
||||
@@ -203,6 +208,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
|
||||
{
|
||||
KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true );
|
||||
|
||||
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
if( !pcbframe->IsVisible() )
|
||||
pcbframe->Show( true );
|
||||
|
||||
|
||||
+20
-9
@@ -45,8 +45,8 @@
|
||||
#include <wx/zipstrm.h>
|
||||
|
||||
|
||||
const std::tuple<int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
|
||||
KICAD_MAJOR_MINOR_VERSION_TUPLE;
|
||||
const std::tuple<int, int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
|
||||
KICAD_MAJOR_MINOR_PATCH_TUPLE;
|
||||
|
||||
|
||||
class THROWING_ERROR_HANDLER : public nlohmann::json_schema::error_handler
|
||||
@@ -510,19 +510,30 @@ void PLUGIN_CONTENT_MANAGER::preparePackage( PCM_PACKAGE& aPackage )
|
||||
// Determine compatibility
|
||||
ver.compatible = true;
|
||||
|
||||
auto parse_major_minor = []( const wxString& version )
|
||||
auto parse_version_tuple = []( const wxString& version, int deflt )
|
||||
{
|
||||
wxStringTokenizer tokenizer( version, wxT( "." ) );
|
||||
int ver_major = wxAtoi( tokenizer.GetNextToken() );
|
||||
int ver_minor = wxAtoi( tokenizer.GetNextToken() );
|
||||
return std::tuple<int, int>( ver_major, ver_minor );
|
||||
int ver_major = deflt;
|
||||
int ver_minor = deflt;
|
||||
int ver_patch = deflt;
|
||||
|
||||
wxStringTokenizer tokenizer( version, "." );
|
||||
|
||||
ver_major = wxAtoi( tokenizer.GetNextToken() );
|
||||
|
||||
if( tokenizer.HasMoreTokens() )
|
||||
ver_minor = wxAtoi( tokenizer.GetNextToken() );
|
||||
|
||||
if( tokenizer.HasMoreTokens() )
|
||||
ver_patch = wxAtoi( tokenizer.GetNextToken() );
|
||||
|
||||
return std::tuple<int, int, int>( ver_major, ver_minor, ver_patch );
|
||||
};
|
||||
|
||||
if( parse_major_minor( ver.kicad_version ) > m_kicad_version )
|
||||
if( parse_version_tuple( ver.kicad_version, 0 ) > m_kicad_version )
|
||||
ver.compatible = false;
|
||||
|
||||
if( ver.kicad_version_max
|
||||
&& parse_major_minor( ver.kicad_version_max.get() ) < m_kicad_version )
|
||||
&& parse_version_tuple( ver.kicad_version_max.get(), 999 ) < m_kicad_version )
|
||||
ver.compatible = false;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
+1
-1
@@ -313,7 +313,7 @@ private:
|
||||
STRING_TUPLE_LIST m_repository_list; // (id, name, url) tuples
|
||||
// Using sorted map to keep order of entries in installed list stable
|
||||
std::map<wxString, PCM_INSTALLATION_ENTRY> m_installed;
|
||||
const static std::tuple<int, int> m_kicad_version;
|
||||
const static std::tuple<int, int, int> m_kicad_version;
|
||||
};
|
||||
|
||||
#endif // PCM_H_
|
||||
|
||||
@@ -49,7 +49,7 @@ void kimathLogDebug( const char* aFormatString, ... );
|
||||
* result is: lower <= value <= upper
|
||||
*</p>
|
||||
*/
|
||||
template <typename T> inline const T& Clamp( const T& lower, const T& value, const T& upper )
|
||||
template <typename T> inline constexpr T Clamp( const T& lower, const T& value, const T& upper )
|
||||
{
|
||||
if( value < lower )
|
||||
return lower;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (C) CERN
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -29,6 +30,11 @@
|
||||
#include <math/util.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
// Fix compatibility with wxWidgets version < 3.1.4
|
||||
#ifndef wxASCII_STR
|
||||
#define wxASCII_STR(s) wxString::FromAscii(s)
|
||||
@@ -65,13 +71,42 @@ int rescale( int aNumerator, int aValue, int aDenominator )
|
||||
template<>
|
||||
int64_t rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator )
|
||||
{
|
||||
#ifdef __SIZEOF_INT128__
|
||||
#if defined( _M_X64 ) && ( _MSC_VER >= 1920 )
|
||||
int64_t productHi;
|
||||
uint64_t productLo = static_cast<uint64_t>( _mul128( aNumerator, aValue, &productHi ) );
|
||||
|
||||
int64_t r = ( ( productHi < 0 ) ^ ( aDenominator < 0 ) ) ? -aDenominator / 2 : aDenominator / 2;
|
||||
|
||||
uint64_t rLo = static_cast<uint64_t>( r );
|
||||
int64_t rHi = r < 0 ? -1ll : 0ll;
|
||||
|
||||
productLo += rLo;
|
||||
productHi += rHi + ( productLo < rLo );
|
||||
|
||||
__try
|
||||
{
|
||||
int64_t remainder;
|
||||
int64_t result = _div128( productHi, productLo, aDenominator, &remainder );
|
||||
|
||||
return result;
|
||||
}
|
||||
__except( ( GetExceptionCode() == EXCEPTION_INT_OVERFLOW ) ? EXCEPTION_EXECUTE_HANDLER
|
||||
: EXCEPTION_CONTINUE_SEARCH )
|
||||
{
|
||||
kimathLogDebug( "Overflow in rescale (%lld * %lld + %lld) / %lld", aNumerator, aValue, r,
|
||||
aDenominator );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined( __SIZEOF_INT128__ )
|
||||
__int128_t numerator = (__int128_t) aNumerator * (__int128_t) aValue;
|
||||
|
||||
if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
|
||||
return ( numerator - aDenominator / 2 ) / aDenominator;
|
||||
else
|
||||
return ( numerator + aDenominator / 2 ) / aDenominator;
|
||||
|
||||
#else
|
||||
int64_t r = 0;
|
||||
int64_t sign = ( ( aNumerator < 0 ) ? -1 : 1 ) * ( aDenominator < 0 ? -1 : 1 ) *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2019 Jean_Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -92,7 +92,7 @@ int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT;
|
||||
bool DIALOG_GENDRILL::m_MinimalHeader = false; // Only for Excellon format
|
||||
bool DIALOG_GENDRILL::m_Mirror = false; // Only for Excellon format
|
||||
bool DIALOG_GENDRILL::m_Merge_PTH_NPTH = false; // Only for Excellon format
|
||||
int DIALOG_GENDRILL::m_mapFileType = 1;
|
||||
int DIALOG_GENDRILL::m_mapFileType = 4; // The last choice in m_Choice_Drill_Map
|
||||
int DIALOG_GENDRILL::m_drillFileType = 0;
|
||||
bool DIALOG_GENDRILL::m_UseRouteModeForOvalHoles = true; // Use G00 route mode to "drill" oval holes
|
||||
|
||||
@@ -116,6 +116,10 @@ void DIALOG_GENDRILL::initDialog()
|
||||
|
||||
m_drillOriginIsAuxAxis = m_plotOpts.GetUseAuxOrigin();
|
||||
|
||||
// Ensure validity of m_mapFileType
|
||||
if( m_mapFileType < 0 || m_mapFileType >= (int)m_Choice_Drill_Map->GetCount() )
|
||||
m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF
|
||||
|
||||
InitDisplayParams();
|
||||
}
|
||||
|
||||
@@ -368,11 +372,10 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
|
||||
m_pcbEditFrame->ClearMsgPanel();
|
||||
WX_TEXT_CTRL_REPORTER reporter( m_messagesBox );
|
||||
|
||||
const PLOT_FORMAT filefmt[6] = {
|
||||
const PLOT_FORMAT filefmt[] = {
|
||||
// Keep these format ids in the same order than m_Choice_Drill_Map choices
|
||||
PLOT_FORMAT::HPGL,
|
||||
PLOT_FORMAT::POST,
|
||||
PLOT_FORMAT::GERBER,
|
||||
PLOT_FORMAT::GERBER, // Only X2 format because we need the .FileFunction attribute
|
||||
PLOT_FORMAT::DXF,
|
||||
PLOT_FORMAT::SVG,
|
||||
PLOT_FORMAT::PDF
|
||||
@@ -381,7 +384,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
|
||||
unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
|
||||
|
||||
if( choice >= arrayDim( filefmt ) )
|
||||
choice = 1;
|
||||
choice = arrayDim( filefmt )-1; // Last choice = PDF
|
||||
|
||||
// Create output directory if it does not exist (also transform it in absolute form).
|
||||
// Bail if it fails.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -79,11 +79,11 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
|
||||
bMiddleSizer->Add( sbSizer6, 1, wxEXPAND|wxALL, 5 );
|
||||
|
||||
wxString m_Choice_Drill_MapChoices[] = { _("HPGL"), _("PostScript"), _("Gerber"), _("DXF"), _("SVG"), _("PDF") };
|
||||
wxString m_Choice_Drill_MapChoices[] = { _("PostScript"), _("Gerber X2"), _("DXF"), _("SVG"), _("PDF") };
|
||||
int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString );
|
||||
m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Map File Format"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_Choice_Drill_Map->SetSelection( 1 );
|
||||
m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") );
|
||||
m_Choice_Drill_Map->SetSelection( 4 );
|
||||
m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PDF or other formats") );
|
||||
|
||||
bMiddleSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
@@ -133,7 +133,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
bLeftSizer->Add( fgSizer1, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bmiddlerSizer->Add( bLeftSizer, 1, wxEXPAND, 5 );
|
||||
bmiddlerSizer->Add( bLeftSizer, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bRightBoxSizer;
|
||||
bRightBoxSizer = new wxBoxSizer( wxVERTICAL );
|
||||
@@ -193,7 +193,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
bRightBoxSizer->Add( sbSizerHoles, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bmiddlerSizer->Add( bRightBoxSizer, 1, wxEXPAND|wxTOP, 5 );
|
||||
bmiddlerSizer->Add( bRightBoxSizer, 0, wxEXPAND|wxTOP, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND|wxTOP, 2 );
|
||||
@@ -231,7 +231,6 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
|
||||
this->SetSizer( bMainSizer );
|
||||
this->Layout();
|
||||
bMainSizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="15" />
|
||||
<FileVersion major="1" minor="16" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
@@ -14,6 +14,7 @@
|
||||
<property name="file">dialog_gendrill_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">dialog_gendrill_base</property>
|
||||
@@ -25,6 +26,7 @@
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
@@ -45,11 +47,12 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_GENDRILL_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="size">643,558</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
|
||||
<property name="title">Generate Drill Files</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
@@ -206,6 +209,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -717,7 +721,7 @@
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices">"HPGL" "PostScript" "Gerber" "DXF" "SVG" "PDF"</property>
|
||||
<property name="choices">"PostScript" "Gerber X2" "DXF" "SVG" "PDF"</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
@@ -749,13 +753,13 @@
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">1</property>
|
||||
<property name="selection">4</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxRA_SPECIFY_COLS</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Creates a drill map in PS, HPGL or other formats</property>
|
||||
<property name="tooltip">Creates a drill map in PDF or other formats</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
@@ -770,7 +774,7 @@
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bLeftSizer</property>
|
||||
@@ -1121,7 +1125,7 @@
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP</property>
|
||||
<property name="proportion">1</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bRightBoxSizer</property>
|
||||
@@ -1873,6 +1877,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -74,7 +74,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
|
||||
wxButton* m_sdbSizerApply;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onCloseDlg( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onFileFormatSelection( wxCommandEvent& event ) { event.Skip(); }
|
||||
@@ -88,7 +88,8 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 643,558 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
~DIALOG_GENDRILL_BASE();
|
||||
|
||||
};
|
||||
|
||||
+41
-37
@@ -782,11 +782,19 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
// Local overrides take precedence over everything *except* board min clearance
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT || aConstraintType == HOLE_CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
int override = 0;
|
||||
int override_val = 0;
|
||||
int overrideA = 0;
|
||||
int overrideB = 0;
|
||||
|
||||
if( ac && !b_is_non_copper )
|
||||
overrideA = ac->GetLocalClearanceOverrides( nullptr );
|
||||
|
||||
if( bc && !a_is_non_copper )
|
||||
overrideB = bc->GetLocalClearanceOverrides( nullptr );
|
||||
|
||||
if( overrideA > 0 || overrideB > 0 )
|
||||
{
|
||||
int overrideA = ac->GetLocalClearanceOverrides( nullptr );
|
||||
wxString msg;
|
||||
|
||||
if( overrideA > 0 )
|
||||
{
|
||||
@@ -795,13 +803,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
EscapeHTML( a->GetSelectMenuText( UNITS ) ),
|
||||
REPORT_VALUE( overrideA ) ) )
|
||||
|
||||
override = ac->GetLocalClearanceOverrides( &m_msg );
|
||||
override_val = ac->GetLocalClearanceOverrides( &msg );
|
||||
}
|
||||
}
|
||||
|
||||
if( bc && !a_is_non_copper )
|
||||
{
|
||||
int overrideB = bc->GetLocalClearanceOverrides( nullptr );
|
||||
|
||||
if( overrideB > 0 )
|
||||
{
|
||||
@@ -810,41 +813,41 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
EscapeHTML( b->GetSelectMenuText( UNITS ) ),
|
||||
EscapeHTML( REPORT_VALUE( overrideB ) ) ) )
|
||||
|
||||
if( overrideB > override )
|
||||
override = bc->GetLocalClearanceOverrides( &m_msg );
|
||||
if( overrideB > override_val )
|
||||
override_val = bc->GetLocalClearanceOverrides( &msg );
|
||||
}
|
||||
}
|
||||
|
||||
if( override )
|
||||
{
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT )
|
||||
if( override_val )
|
||||
{
|
||||
if( override < m_designSettings->m_MinClearance )
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
override = m_designSettings->m_MinClearance;
|
||||
m_msg = _( "board minimum" );
|
||||
if( override_val < m_designSettings->m_MinClearance )
|
||||
{
|
||||
override_val = m_designSettings->m_MinClearance;
|
||||
msg = _( "board minimum" );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
|
||||
REPORT_VALUE( override ) ) )
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
|
||||
REPORT_VALUE( override_val ) ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( override < m_designSettings->m_HoleClearance )
|
||||
else
|
||||
{
|
||||
override = m_designSettings->m_HoleClearance;
|
||||
m_msg = _( "board minimum hole" );
|
||||
if( override_val < m_designSettings->m_HoleClearance )
|
||||
{
|
||||
override_val = m_designSettings->m_HoleClearance;
|
||||
msg = _( "board minimum hole" );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum hole clearance: %s." ),
|
||||
REPORT_VALUE( override ) ) )
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum hole clearance: %s." ),
|
||||
REPORT_VALUE( override_val ) ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constraint.SetName( m_msg );
|
||||
constraint.m_Value.SetMin( override );
|
||||
return constraint;
|
||||
constraint.SetName( msg );
|
||||
constraint.m_Value.SetMin( override_val );
|
||||
return constraint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,10 +882,10 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
wxString min = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
|
||||
wxString opt = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
|
||||
wxString max = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
|
||||
wxString msg;
|
||||
|
||||
if( implicit )
|
||||
{
|
||||
wxString msg;
|
||||
opt = StringFromValue( UNITS, c->constraint.m_Value.Opt(), true );
|
||||
|
||||
switch( c->constraint.m_Type )
|
||||
@@ -1108,6 +1111,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
int localA = ac ? ac->GetLocalClearance( nullptr ) : 0;
|
||||
int localB = bc ? bc->GetLocalClearance( nullptr ) : 0;
|
||||
int clearance = global;
|
||||
wxString msg;
|
||||
|
||||
if( localA > 0 )
|
||||
{
|
||||
@@ -1117,7 +1121,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
REPORT_VALUE( localA ) ) )
|
||||
|
||||
if( localA > clearance )
|
||||
clearance = ac->GetLocalClearance( &m_msg );
|
||||
clearance = ac->GetLocalClearance( &msg );
|
||||
}
|
||||
|
||||
if( localB > 0 )
|
||||
@@ -1128,13 +1132,13 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||
REPORT_VALUE( localB ) ) )
|
||||
|
||||
if( localB > clearance )
|
||||
clearance = bc->GetLocalClearance( &m_msg );
|
||||
clearance = bc->GetLocalClearance( &msg );
|
||||
}
|
||||
|
||||
if( localA > global || localB > global )
|
||||
{
|
||||
constraint.SetParentRule( nullptr );
|
||||
constraint.SetName( m_msg );
|
||||
constraint.SetName( msg );
|
||||
constraint.m_Value.SetMin( clearance );
|
||||
return constraint;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,6 @@ protected:
|
||||
REPORTER* m_reporter;
|
||||
PROGRESS_REPORTER* m_progressReporter;
|
||||
|
||||
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
||||
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
|
||||
};
|
||||
|
||||
|
||||
@@ -132,8 +132,6 @@ protected:
|
||||
std::unordered_map<const DRC_RULE*, int> m_stats;
|
||||
bool m_isRuleDriven = true;
|
||||
bool m_enabled = true;
|
||||
|
||||
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
||||
};
|
||||
|
||||
#endif // DRC_TEST_PROVIDER__H
|
||||
|
||||
@@ -123,20 +123,21 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULAR_WIDTH );
|
||||
wxString msg;
|
||||
|
||||
if( fail_min )
|
||||
m_msg.Printf( _( "(%s min annular width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s min annular width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), v_min ),
|
||||
MessageTextFromValue( userUnits(), annularWidth ) );
|
||||
|
||||
if( fail_max )
|
||||
m_msg.Printf( _( "(%s max annular width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s max annular width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), v_max ),
|
||||
MessageTextFromValue( userUnits(), annularWidth ) );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -307,13 +307,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||
if( trackShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( track, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -353,14 +354,16 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( track, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -441,13 +444,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, zone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -486,13 +490,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, zone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -650,12 +655,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
&& testShorting )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(nets %s and %s)" ),
|
||||
msg.Printf( _( "(nets %s and %s)" ),
|
||||
pad->GetNetname(),
|
||||
otherPad->GetNetname() );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( pad, otherPad );
|
||||
|
||||
reportViolation( drce, otherPad->GetPosition() );
|
||||
@@ -674,13 +680,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( pad, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -702,13 +709,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( pad, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -724,13 +732,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( pad, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -749,13 +758,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( pad, otherVia );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -986,13 +996,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
else
|
||||
{
|
||||
drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), zone2zoneClearance ),
|
||||
MessageTextFromValue( userUnits(), conflict.second ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
}
|
||||
|
||||
drce->SetItems( zoneRef, zoneToTest );
|
||||
|
||||
@@ -210,12 +210,13 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
|
||||
|
||||
if( clearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
}
|
||||
|
||||
@@ -237,12 +238,13 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
|
||||
|
||||
if( clearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
}
|
||||
|
||||
|
||||
@@ -459,13 +459,14 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
if ( val.HasMax() && totalUncoupled > val.Max() )
|
||||
{
|
||||
auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG );
|
||||
wxString msg;
|
||||
|
||||
m_msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
|
||||
msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
|
||||
maxUncoupledConstraint->GetParentRule()->m_Name,
|
||||
MessageTextFromValue( userUnits(), val.Max() ),
|
||||
MessageTextFromValue( userUnits(), totalUncoupled ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
|
||||
auto pit = it.second.itemsP.begin();
|
||||
auto nit = it.second.itemsN.begin();
|
||||
@@ -495,22 +496,23 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
{
|
||||
auto val = gapConstraint->GetValue();
|
||||
auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE );
|
||||
wxString msg;
|
||||
|
||||
m_msg = drcItem->GetErrorText() + wxT( " (" ) +
|
||||
msg = drcItem->GetErrorText() + wxT( " (" ) +
|
||||
gapConstraint->GetParentRule()->m_Name + wxS( " " );
|
||||
|
||||
if( val.HasMin() )
|
||||
m_msg += wxString::Format( _( "minimum gap: %s; " ),
|
||||
msg += wxString::Format( _( "minimum gap: %s; " ),
|
||||
MessageTextFromValue( userUnits(), val.Min() ) );
|
||||
|
||||
if( val.HasMax() )
|
||||
m_msg += wxString::Format( _( "maximum gap: %s; " ),
|
||||
msg += wxString::Format( _( "maximum gap: %s; " ),
|
||||
MessageTextFromValue( userUnits(), val.Max() ) );
|
||||
|
||||
m_msg += wxString::Format( _( "actual: %s)" ),
|
||||
msg += wxString::Format( _( "actual: %s)" ),
|
||||
MessageTextFromValue( userUnits(), cpair.computedGap ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
|
||||
drcItem->AddItem( cpair.parentP );
|
||||
drcItem->AddItem( cpair.parentN );
|
||||
|
||||
@@ -85,11 +85,12 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
if( constraint.m_DisallowFlags )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ),
|
||||
msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ),
|
||||
constraint.GetName() );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -97,12 +97,13 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE*
|
||||
// Only report clearance info if there is any; otherwise it's just a straight collision
|
||||
if( minClearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
}
|
||||
|
||||
drce->SetItems( edge->m_Uuid, item->m_Uuid );
|
||||
|
||||
@@ -156,23 +156,24 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad )
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DRILL_OUT_OF_RANGE );
|
||||
wxString msg;
|
||||
|
||||
if( fail_min )
|
||||
{
|
||||
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintValue ),
|
||||
MessageTextFromValue( userUnits(), holeMinor ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintValue ),
|
||||
MessageTextFromValue( userUnits(), holeMajor ) );
|
||||
}
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( aPad );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
@@ -221,23 +222,24 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
|
||||
wxString msg;
|
||||
|
||||
if( fail_min )
|
||||
{
|
||||
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintValue ),
|
||||
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintValue ),
|
||||
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
|
||||
}
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( via );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -309,13 +309,14 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA
|
||||
if( minClearance >= 0 && actual < minClearance )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s min %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s min %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, aOther );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -116,13 +116,14 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_FOOTPRINT ) )
|
||||
break;
|
||||
|
||||
m_msg.Printf( _( "Missing footprint %s (%s)" ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "Missing footprint %s (%s)" ),
|
||||
component->GetReference(),
|
||||
component->GetValue() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
reportViolation( drcItem, wxPoint() );
|
||||
}
|
||||
else
|
||||
@@ -140,31 +141,34 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
||||
|
||||
if( !pcb_netname.IsEmpty() && sch_net.GetPinName().IsEmpty() )
|
||||
{
|
||||
m_msg.Printf( _( "No corresponding pin found in schematic." ) );
|
||||
wxString msg;
|
||||
msg.Printf( _( "No corresponding pin found in schematic." ) );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( pad );
|
||||
reportViolation( drcItem, footprint->GetPosition() );
|
||||
}
|
||||
else if( pcb_netname.IsEmpty() && !sch_net.GetNetName().IsEmpty() )
|
||||
{
|
||||
m_msg.Printf( _( "Pad missing net given by schematic (%s)." ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "Pad missing net given by schematic (%s)." ),
|
||||
sch_net.GetNetName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( pad );
|
||||
reportViolation( drcItem, footprint->GetPosition() );
|
||||
}
|
||||
else if( pcb_netname != sch_net.GetNetName() )
|
||||
{
|
||||
m_msg.Printf( _( "Pad net (%s) doesn't match net given by schematic (%s)." ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "Pad net (%s) doesn't match net given by schematic (%s)." ),
|
||||
pcb_netname,
|
||||
sch_net.GetNetName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( pad );
|
||||
reportViolation( drcItem, footprint->GetPosition() );
|
||||
}
|
||||
@@ -179,11 +183,12 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
||||
|
||||
if( !footprint->FindPadByNumber( sch_net.GetPinName() ) )
|
||||
{
|
||||
m_msg.Printf( _( "No pad found for pin %s in schematic." ),
|
||||
wxString msg;
|
||||
msg.Printf( _( "No pad found for pin %s in schematic." ),
|
||||
sch_net.GetPinName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( footprint );
|
||||
reportViolation( drcItem, footprint->GetPosition() );
|
||||
}
|
||||
|
||||
@@ -114,23 +114,24 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkLengths( DRC_CONSTRAINT& aConstraint
|
||||
if( ( minViolation || maxViolation ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_LENGTH_OUT_OF_RANGE );
|
||||
wxString msg;
|
||||
|
||||
if( minViolation )
|
||||
{
|
||||
m_msg.Printf( _( "(%s min length: %s; actual: %s)" ),
|
||||
msg.Printf( _( "(%s min length: %s; actual: %s)" ),
|
||||
aConstraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minLen ),
|
||||
MessageTextFromValue( userUnits(), ent.total ) );
|
||||
}
|
||||
else if( maxViolation )
|
||||
{
|
||||
m_msg.Printf( _( "(%s max length: %s; actual: %s)" ),
|
||||
msg.Printf( _( "(%s max length: %s; actual: %s)" ),
|
||||
aConstraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), maxLen ),
|
||||
MessageTextFromValue( userUnits(), ent.total ) );
|
||||
}
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
|
||||
for( auto offendingTrack : ent.items )
|
||||
drcItem->AddItem( offendingTrack );
|
||||
@@ -158,15 +159,16 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkSkews( DRC_CONSTRAINT& aConstraint,
|
||||
if( aConstraint.GetValue().HasMax() && abs( skew ) > aConstraint.GetValue().Max() )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SKEW_OUT_OF_RANGE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s max skew: %s; actual: %s; average net length: %s; actual: %s)" ),
|
||||
msg.Printf( _( "(%s max skew: %s; actual: %s; average net length: %s; actual: %s)" ),
|
||||
aConstraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), aConstraint.GetValue().Max() ),
|
||||
MessageTextFromValue( userUnits(), skew ),
|
||||
MessageTextFromValue( userUnits(), avgLength ),
|
||||
MessageTextFromValue( userUnits(), ent.total ) );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + " " + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + " " + msg );
|
||||
|
||||
for( BOARD_CONNECTED_ITEM* offendingTrack : ent.items )
|
||||
drcItem->SetItems( offendingTrack );
|
||||
@@ -187,13 +189,14 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkViaCounts( DRC_CONSTRAINT& aConstrai
|
||||
if( aConstraint.GetValue().HasMax() && ent.viaCount > aConstraint.GetValue().Max() )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_MANY_VIAS );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(%s max count: %d; actual: %d)" ),
|
||||
msg.Printf( _( "(%s max count: %d; actual: %d)" ),
|
||||
aConstraint.GetName(),
|
||||
aConstraint.GetValue().Max(),
|
||||
ent.viaCount );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
|
||||
for( auto offendingTrack : ent.items )
|
||||
drcItem->SetItems( offendingTrack );
|
||||
|
||||
@@ -112,10 +112,11 @@ void DRC_TEST_PROVIDER_MISC::testOutline()
|
||||
else
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(no edges found on Edge.Cuts layer)" ) );
|
||||
msg.Printf( _( "(no edges found on Edge.Cuts layer)" ) );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( m_board );
|
||||
|
||||
reportViolation( drcItem, m_board->GetBoundingBox().Centre() );
|
||||
@@ -199,10 +200,11 @@ void DRC_TEST_PROVIDER_MISC::testDisabledLayers()
|
||||
if( badLayer != UNDEFINED_LAYER )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
|
||||
wxString msg;
|
||||
|
||||
m_msg.Printf( _( "(layer %s)" ), LayerName( badLayer ) );
|
||||
msg.Printf( _( "(layer %s)" ), LayerName( badLayer ) );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( item );
|
||||
|
||||
reportViolation( drcItem, item->GetPosition() );
|
||||
|
||||
@@ -228,12 +228,14 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
|
||||
|
||||
if( minClearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetParentRule()->m_Name,
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
}
|
||||
|
||||
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
|
||||
|
||||
@@ -157,12 +157,14 @@ bool DRC_TEST_PROVIDER_SILK_TO_MASK::Run()
|
||||
|
||||
if( minClearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
}
|
||||
|
||||
drce->SetItems( aRefItem->parent, aTestItem->parent );
|
||||
|
||||
@@ -128,23 +128,24 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACK_WIDTH );
|
||||
wxString msg;
|
||||
|
||||
if( fail_min )
|
||||
{
|
||||
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s min width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintWidth ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
msg.Printf( _( "(%s max width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintWidth ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -114,26 +114,27 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
|
||||
constraintDiameter = constraint.Value().Max();
|
||||
}
|
||||
|
||||
if( fail_min )
|
||||
{
|
||||
m_msg.Printf( _( "(%s min diameter %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
else if( fail_max )
|
||||
{
|
||||
m_msg.Printf( _( "(%s max diameter %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_DIAMETER );
|
||||
wxString msg;
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
|
||||
if( fail_min )
|
||||
{
|
||||
msg.Printf( _( "(%s min diameter %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
else if( fail_max )
|
||||
{
|
||||
msg.Printf( _( "(%s max diameter %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
}
|
||||
|
||||
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <pcbplot.h>
|
||||
#include <gendrill_file_writer_base.h>
|
||||
#include <pcb_painter.h>
|
||||
#include <pcb_shape.h>
|
||||
|
||||
|
||||
/* Conversion utilities - these will be used often in there... */
|
||||
@@ -91,6 +92,12 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
|
||||
EDA_RECT bbbox = m_pcb->GetBoardEdgesBoundingBox();
|
||||
m_pcb->SetVisibleLayers( visibleLayers );
|
||||
|
||||
// Some formats cannot be used to generate a document like the map files
|
||||
// Currently HPGL (old format not very used)
|
||||
|
||||
if( aFormat == PLOT_FORMAT::HPGL )
|
||||
aFormat = PLOT_FORMAT::PDF;
|
||||
|
||||
// Calculate the scale for the format type, scale 1 in HPGL, drawing on
|
||||
// an A4 sheet in PS, + text description of symbols
|
||||
switch( aFormat )
|
||||
@@ -101,17 +108,6 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
|
||||
plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm
|
||||
break;
|
||||
|
||||
case PLOT_FORMAT::HPGL: // Scale for HPGL format.
|
||||
{
|
||||
HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER;
|
||||
plotter = hpgl_plotter;
|
||||
hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
|
||||
hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
|
||||
plotter->SetPageSettings( page_info );
|
||||
plotter->SetViewport( offset, IU_PER_MILS / 10, scale, false );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
wxASSERT( false );
|
||||
KI_FALLTHROUGH;
|
||||
@@ -191,30 +187,55 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
|
||||
return false;
|
||||
}
|
||||
|
||||
plotter->ClearHeaderLinesList();
|
||||
|
||||
// For the Gerber X2 format we need to set the "FileFunction" to Drillmap
|
||||
// and set a few other options.
|
||||
if( plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
|
||||
{
|
||||
GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
|
||||
gbrplotter->DisableApertMacros( false );
|
||||
gbrplotter->UseX2format( true ); // Mandatory
|
||||
gbrplotter->UseX2NetAttributes( false ); // net attributes hace no meaning here
|
||||
|
||||
// Attributes are added using X2 format
|
||||
AddGerberX2Header( gbrplotter, m_pcb, false );
|
||||
|
||||
wxString text;
|
||||
|
||||
// Add the TF.FileFunction
|
||||
text = "%TF.FileFunction,Drillmap*%";
|
||||
gbrplotter->AddLineToHeader( text );
|
||||
|
||||
// Add the TF.FilePolarity
|
||||
text = wxT( "%TF.FilePolarity,Positive*%" );
|
||||
gbrplotter->AddLineToHeader( text );
|
||||
}
|
||||
|
||||
plotter->StartPlot();
|
||||
|
||||
// Draw items on edge layer (not all, only items useful for drill map
|
||||
// Draw items on edge layer.
|
||||
// Not all, only items useful for drill map, i.e. board outlines.
|
||||
BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
|
||||
itemplotter.SetLayerSet( Edge_Cuts );
|
||||
|
||||
for( auto PtStruct : m_pcb->Drawings() )
|
||||
// Use attributes of a drawing layer (we are not really draw the Edge.Cuts layer)
|
||||
itemplotter.SetLayerSet( Dwgs_User );
|
||||
|
||||
for( BOARD_ITEM* item : m_pcb->Drawings() )
|
||||
{
|
||||
switch( PtStruct->Type() )
|
||||
if( item->GetLayer() != Edge_Cuts )
|
||||
continue;
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_SHAPE_T:
|
||||
itemplotter.PlotPcbShape( (PCB_SHAPE*) PtStruct );
|
||||
{
|
||||
PCB_SHAPE dummy_shape( *static_cast<PCB_SHAPE*>( item ) );
|
||||
dummy_shape.SetLayer( Dwgs_User );
|
||||
itemplotter.PlotPcbShape( &dummy_shape );
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
itemplotter.PlotPcbText( (PCB_TEXT*) PtStruct );
|
||||
break;
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_ORTHOGONAL_T:
|
||||
case PCB_DIM_LEADER_T:
|
||||
case PCB_TARGET_T:
|
||||
case PCB_MARKER_T: // do not draw
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -732,6 +732,11 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
|
||||
return;
|
||||
}
|
||||
|
||||
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
|
||||
|
||||
if( blocking_dialog )
|
||||
blocking_dialog->Close( true );
|
||||
|
||||
toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
BOARD_COMMIT commit( pcbframe );
|
||||
|
||||
@@ -768,7 +773,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
|
||||
commit.Push( wxT( "Insert footprint" ) );
|
||||
|
||||
pcbframe->Raise();
|
||||
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
|
||||
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, false, newFootprint );
|
||||
|
||||
newFootprint->ClearFlags();
|
||||
}
|
||||
|
||||
@@ -1726,8 +1726,17 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
|
||||
m_out->Print( 0, " (width %s)",
|
||||
FormatInternalUnits( primitive->GetWidth() ).c_str() );
|
||||
|
||||
if( primitive->IsFilled() )
|
||||
m_out->Print( 0, " (fill yes)" );
|
||||
// The filled flag represents if a solid fill is present on circles,
|
||||
// rectangles and polygons
|
||||
if( ( primitive->GetShape() == SHAPE_T::POLY )
|
||||
|| ( primitive->GetShape() == SHAPE_T::RECT )
|
||||
|| ( primitive->GetShape() == SHAPE_T::CIRCLE ) )
|
||||
{
|
||||
if( primitive->IsFilled() )
|
||||
m_out->Print( 0, " (fill yes)" );
|
||||
else
|
||||
m_out->Print( 0, " (fill none)" );
|
||||
}
|
||||
|
||||
m_out->Print( 0, ")" );
|
||||
}
|
||||
@@ -2040,7 +2049,7 @@ void PCB_PLUGIN::format( const ZONE* aZone, int aNestLevel ) const
|
||||
if( aZone->GetIsRuleArea() )
|
||||
{
|
||||
m_out->Print( aNestLevel + 1,
|
||||
"(keepout (tracks %s) (vias %s) (pads %s ) (copperpour %s) "
|
||||
"(keepout (tracks %s) (vias %s) (pads %s) (copperpour %s) "
|
||||
"(footprints %s))\n",
|
||||
aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
|
||||
aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/xml/xml.h>
|
||||
#include <wx/wxcrt.h> // for wxFopen
|
||||
|
||||
namespace PCAD2KICAD {
|
||||
|
||||
|
||||
@@ -143,10 +143,10 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
|
||||
return SaveBoard(filename,self)
|
||||
|
||||
def GetNetClasses(self):
|
||||
return self.GetDesignSettings().m_NetClasses
|
||||
return self.GetDesignSettings().GetNetClasses()
|
||||
|
||||
def GetCurrentNetClassName(self):
|
||||
return self.GetDesignSettings().m_CurrentNetClassName
|
||||
return self.GetDesignSettings().GetCurrentNetClassName()
|
||||
|
||||
def GetViasDimensionsList(self):
|
||||
return self.GetDesignSettings().m_ViasDimensionsList
|
||||
|
||||
@@ -119,9 +119,9 @@
|
||||
plug = GetPluginForPath(libname)
|
||||
return plug.FootprintEnumerate(libname)
|
||||
|
||||
def FootprintLoad(libname,name):
|
||||
def FootprintLoad(libname,name,preserveUUID=False):
|
||||
plug = GetPluginForPath(libname)
|
||||
return plug.FootprintLoad(libname,name)
|
||||
return plug.FootprintLoad(libname,name,preserveUUID)
|
||||
|
||||
def FootprintSave(libname,module):
|
||||
plug = GetPluginForPath(libname)
|
||||
|
||||
+25
-17
@@ -102,7 +102,15 @@ public:
|
||||
*/
|
||||
bool IsLineCorner( bool aAllowLockedSegs = false ) const
|
||||
{
|
||||
if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT_T | ARC_T ) != 2 )
|
||||
if( m_linkedItems.Size() == 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 )
|
||||
{
|
||||
LINKED_ITEM* seg1 = static_cast<LINKED_ITEM*>( m_linkedItems[0] );
|
||||
LINKED_ITEM* seg2 = static_cast<LINKED_ITEM*>( m_linkedItems[1] );
|
||||
|
||||
// joints between segments of different widths are not considered trivial.
|
||||
return seg1->Width() == seg2->Width();
|
||||
}
|
||||
else if( m_linkedItems.Size() > 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 )
|
||||
{
|
||||
if( !aAllowLockedSegs )
|
||||
{
|
||||
@@ -113,8 +121,10 @@ public:
|
||||
else if( ( m_linkedItems.Size() - m_linkedItems.Count( SEGMENT_T | ARC_T ) )
|
||||
== m_linkedItems.Count( VIA_T ) )
|
||||
{
|
||||
const VIA* via = nullptr;
|
||||
bool hasNonVirtualVia = false;
|
||||
const LINKED_ITEM* seg1 = nullptr;
|
||||
const LINKED_ITEM* seg2 = nullptr;
|
||||
const VIA* via = nullptr;
|
||||
bool hasNonVirtualVia = false;
|
||||
|
||||
for( const ITEM* item : m_linkedItems.CItems() )
|
||||
{
|
||||
@@ -123,28 +133,26 @@ public:
|
||||
via = static_cast<const VIA*>( item );
|
||||
|
||||
hasNonVirtualVia = !via->IsVirtual();
|
||||
|
||||
if( hasNonVirtualVia )
|
||||
break;
|
||||
}
|
||||
else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
|
||||
{
|
||||
if( !seg1 )
|
||||
seg1 = static_cast<const LINKED_ITEM*>( item );
|
||||
else
|
||||
seg2 = static_cast<const LINKED_ITEM*>( item );
|
||||
}
|
||||
}
|
||||
|
||||
assert( via );
|
||||
|
||||
if( !via || hasNonVirtualVia )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
||||
assert ( seg1 && seg2 );
|
||||
|
||||
return seg1->Width() == seg2->Width();
|
||||
}
|
||||
}
|
||||
|
||||
auto seg1 = static_cast<LINKED_ITEM*>( m_linkedItems[0] );
|
||||
auto seg2 = static_cast<LINKED_ITEM*>( m_linkedItems[1] );
|
||||
|
||||
// joints between segments of different widths are not considered trivial.
|
||||
return seg1->Width() == seg2->Width();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsNonFanoutVia() const
|
||||
|
||||
@@ -687,6 +687,10 @@ int BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB( const TOOL_EVENT& aEvent )
|
||||
if( frame )
|
||||
{
|
||||
std::string payload;
|
||||
|
||||
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
|
||||
blocking_win->Close( true );
|
||||
|
||||
m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -703,7 +703,9 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||
m_controls->SetAutoPan( false );
|
||||
m_controls->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
if( selection().Empty() )
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1151,7 +1153,9 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
m_view->Remove( &preview );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
if( selection().Empty() )
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1727,7 +1731,9 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic,
|
||||
|
||||
m_view->Remove( &twoPointAsst );
|
||||
m_view->Remove( &preview );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
if( selection().Empty() )
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_controls->SetAutoPan( false );
|
||||
@@ -1996,7 +2002,9 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool
|
||||
preview.Remove( graphic );
|
||||
m_view->Remove( &arcAsst );
|
||||
m_view->Remove( &preview );
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
if( selection().Empty() )
|
||||
m_frame->SetMsgPanel( board() );
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
m_controls->SetAutoPan( false );
|
||||
|
||||
@@ -1493,6 +1493,8 @@ void PCB_POINT_EDITOR::updateItem() const
|
||||
}
|
||||
|
||||
getView()->Update( item );
|
||||
|
||||
frame()->SetMsgPanel( item );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -797,12 +797,12 @@ bool PCB_SELECTION_TOOL::selectMultiple()
|
||||
* Left > Right : Select objects that are fully enclosed by selection
|
||||
* Right > Left : Select objects that are crossed by selection
|
||||
*/
|
||||
bool windowSelection = width >= 0 ? true : false;
|
||||
bool greedySelection = width >= 0 ? false : true;
|
||||
|
||||
if( view->IsMirroredX() )
|
||||
windowSelection = !windowSelection;
|
||||
greedySelection = !greedySelection;
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor( windowSelection ? KICURSOR::SELECT_WINDOW
|
||||
m_frame->GetCanvas()->SetCurrentCursor( !greedySelection ? KICURSOR::SELECT_WINDOW
|
||||
: KICURSOR::SELECT_LASSO );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
@@ -853,13 +853,37 @@ bool PCB_SELECTION_TOOL::selectMultiple()
|
||||
selectionRect.Normalize();
|
||||
|
||||
GENERAL_COLLECTOR collector;
|
||||
std::set<BOARD_ITEM*> group_items;
|
||||
|
||||
for( PCB_GROUP* group : board()->Groups() )
|
||||
{
|
||||
// The currently entered group does not get limited
|
||||
if( m_enteredGroup == group )
|
||||
continue;
|
||||
|
||||
std::unordered_set<BOARD_ITEM*>& newset = group->GetItems();
|
||||
|
||||
// If we are not greedy and have selected the whole group, add just one item
|
||||
// to allow it to be promoted to the group later
|
||||
if( !greedySelection && selectionRect.Contains( group->GetBoundingBox() )
|
||||
&& newset.size() )
|
||||
{
|
||||
collector.Append( *newset.begin() );
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* group_item : newset )
|
||||
group_items.emplace( group_item );
|
||||
}
|
||||
|
||||
for( auto it = candidates.begin(), it_end = candidates.end(); it != it_end; ++it )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
|
||||
|
||||
if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
|
||||
if( item && Selectable( item ) && item->HitTest( selectionRect, !greedySelection )
|
||||
&& ( greedySelection || !group_items.count( item ) ) )
|
||||
{
|
||||
collector.Append( item );
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the stateful filter
|
||||
@@ -2546,7 +2570,7 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
|
||||
for( int i = 0; i < aCollector.GetCount(); ++i )
|
||||
{
|
||||
BOARD_ITEM* item = aCollector[i];
|
||||
double area;
|
||||
double area = 0.0;
|
||||
|
||||
if( ( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
|
||||
&& static_cast<ZONE*>( item )->HitTestForEdge( where, MAX_SLOP * pixel / 2 ) )
|
||||
|
||||
@@ -66,16 +66,16 @@ static const std::vector<ALTIUM_TO_KICAD_UNIT_FRAC_CASE> altium_to_kicad_unit_fr
|
||||
// Decimal Places
|
||||
{ "0", "1", 0 },
|
||||
{ "0", "10", 0 },
|
||||
{ "0", "100", 2 },
|
||||
{ "0", "1000", 25 },
|
||||
{ "0", "10000", 254 },
|
||||
{ "1", "10000", 2794 },
|
||||
{ "0", "100", 0 },
|
||||
{ "0", "1000", 30 },
|
||||
{ "0", "10000", 250 },
|
||||
{ "1", "10000", 2790 },
|
||||
{ "0", "-1", 0 },
|
||||
{ "0", "-10", 0 },
|
||||
{ "0", "-100", -2 },
|
||||
{ "0", "-1000", -25 },
|
||||
{ "0", "-10000", -254 },
|
||||
{ "-1", "-10000", -2794 },
|
||||
{ "0", "-100", 0 },
|
||||
{ "0", "-1000", -30 },
|
||||
{ "0", "-10000", -250 },
|
||||
{ "-1", "-10000", -2790 },
|
||||
// Edge Cases
|
||||
// Clamp bigger values
|
||||
// imperial rounded units as input
|
||||
|
||||
Vendored
+18
-9
@@ -7,13 +7,18 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.22)
|
||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
else()
|
||||
cmake_policy(VERSION 3.18)
|
||||
cmake_policy(VERSION 3.22)
|
||||
endif()
|
||||
|
||||
# Avoid infinite recursion if tests include this as a subdirectory
|
||||
if(DEFINED PYBIND11_MASTER_PROJECT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Extract project version from source
|
||||
@@ -45,13 +50,8 @@ if(NOT pybind11_FIND_QUIETLY)
|
||||
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
||||
endif()
|
||||
|
||||
# Avoid infinite recursion if tests include this as a subdirectory
|
||||
if(DEFINED PYBIND11_MASTER_PROJECT)
|
||||
set(PYBIND11_TEST OFF)
|
||||
endif()
|
||||
|
||||
# Check if pybind11 is being used directly or via add_subdirectory
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_PROJECT)
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
### Warn if not an out-of-source builds
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
set(lines
|
||||
@@ -80,6 +80,8 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_
|
||||
endif()
|
||||
|
||||
set(pybind11_system "")
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
else()
|
||||
set(PYBIND11_MASTER_PROJECT OFF)
|
||||
set(pybind11_system SYSTEM)
|
||||
@@ -89,6 +91,9 @@ endif()
|
||||
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
|
||||
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
|
||||
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
|
||||
set(PYBIND11_INTERNALS_VERSION
|
||||
""
|
||||
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
|
||||
|
||||
cmake_dependent_option(
|
||||
USE_PYTHON_INCLUDE_DIR
|
||||
@@ -183,6 +188,10 @@ if(NOT TARGET pybind11_headers)
|
||||
|
||||
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
|
||||
cxx_right_angle_brackets)
|
||||
if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
|
||||
target_compile_definitions(
|
||||
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
# It is invalid to install a target twice, too.
|
||||
set(PYBIND11_INSTALL OFF)
|
||||
|
||||
Vendored
+7
-18
@@ -3,7 +3,7 @@
|
||||
|
||||
**pybind11 — Seamless operability between C++11 and Python**
|
||||
|
||||
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |CI| |Build status|
|
||||
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
|
||||
|
||||
|Repology| |PyPI package| |Conda-forge| |Python Versions|
|
||||
|
||||
@@ -13,19 +13,6 @@
|
||||
|
||||
.. start
|
||||
|
||||
.. warning::
|
||||
|
||||
Combining older versions of pybind11 (< 2.6.0) with Python 3.9.0 will
|
||||
trigger undefined behavior that typically manifests as crashes during
|
||||
interpreter shutdown (but could also destroy your data. **You have been
|
||||
warned.**)
|
||||
|
||||
We recommend that you update to the latest patch release of Python (3.9.1),
|
||||
which includes a `fix <https://github.com/python/cpython/pull/22670>`_
|
||||
that resolves this problem. If you do use Python 3.9.0, please update to
|
||||
the latest version of pybind11 (2.6.0 or newer), which includes a temporary
|
||||
workaround specifically when Python 3.9.0 is detected at runtime.
|
||||
|
||||
|
||||
**pybind11** is a lightweight header-only library that exposes C++ types
|
||||
in Python and vice versa, mainly to create Python bindings of existing
|
||||
@@ -110,7 +97,7 @@ goodies:
|
||||
transparently applied to all entries of one or more NumPy array
|
||||
arguments.
|
||||
|
||||
- Python’s slice-based access and assignment operations can be
|
||||
- Python's slice-based access and assignment operations can be
|
||||
supported with just a few lines of code.
|
||||
|
||||
- Everything is contained in just a few header files; there is no need
|
||||
@@ -119,7 +106,7 @@ goodies:
|
||||
- Binaries are generally smaller by a factor of at least 2 compared to
|
||||
equivalent bindings generated by Boost.Python. A recent pybind11
|
||||
conversion of PyRosetta, an enormous Boost.Python binding project,
|
||||
`reported <http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf>`_
|
||||
`reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
|
||||
a binary size reduction of **5.4x** and compile time reduction by
|
||||
**5.8x**.
|
||||
|
||||
@@ -147,9 +134,9 @@ About
|
||||
This project was created by `Wenzel
|
||||
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
|
||||
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
|
||||
Sylvain Corlay, Eric Cousineau, Ralf Grosse-Kunstleve, Trent Houliston, Axel
|
||||
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
|
||||
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,
|
||||
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
|
||||
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
|
||||
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
|
||||
|
||||
We thank Google for a generous financial contribution to the continuous
|
||||
@@ -189,3 +176,5 @@ to the terms and conditions of this license.
|
||||
:target: https://repology.org/project/python:pybind11/versions
|
||||
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
|
||||
:target: https://pypi.org/project/pybind11/
|
||||
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
|
||||
:target: https://github.com/pybind/pybind11/discussions
|
||||
|
||||
Vendored
+1
-2
@@ -18,6 +18,5 @@ ALIASES += "endrst=\endverbatim"
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \
|
||||
PY_MAJOR_VERSION=3 \
|
||||
PREDEFINED = PY_MAJOR_VERSION=3 \
|
||||
PYBIND11_NOINLINE
|
||||
|
||||
+3
-1
@@ -26,7 +26,9 @@ The following Python snippet demonstrates the intended usage from the Python sid
|
||||
def __int__(self):
|
||||
return 123
|
||||
|
||||
|
||||
from example import print
|
||||
|
||||
print(A())
|
||||
|
||||
To register the necessary conversion routines, it is necessary to add an
|
||||
@@ -44,7 +46,7 @@ type is explicitly allowed.
|
||||
* function signatures and declares a local variable
|
||||
* 'value' of type inty
|
||||
*/
|
||||
PYBIND11_TYPE_CASTER(inty, _("inty"));
|
||||
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
|
||||
|
||||
/**
|
||||
* Conversion part 1 (Python->C++): convert a PyObject into a inty
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ can be mapped *and* if the numpy array is writeable (that is
|
||||
the passed variable will be transparently carried out directly on the
|
||||
``numpy.ndarray``.
|
||||
|
||||
This means you can can write code such as the following and have it work as
|
||||
This means you can write code such as the following and have it work as
|
||||
expected:
|
||||
|
||||
.. code-block:: cpp
|
||||
@@ -112,7 +112,7 @@ example:
|
||||
.. code-block:: python
|
||||
|
||||
a = MyClass()
|
||||
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
|
||||
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
|
||||
v = a.view_matrix() # flags.writeable = False, flags.owndata = False
|
||||
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True
|
||||
# m[5,6] and v[5,6] refer to the same element, c[5,6] does not.
|
||||
@@ -203,7 +203,7 @@ adding the ``order='F'`` option when creating an array:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
myarray = np.array(source, order='F')
|
||||
myarray = np.array(source, order="F")
|
||||
|
||||
Such an object will be passable to a bound function accepting an
|
||||
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).
|
||||
|
||||
+90
-90
@@ -75,96 +75,96 @@ The following basic data types are supported out of the box (some may require
|
||||
an additional extension header to be included). To pass other data structures
|
||||
as arguments and return values, refer to the section on binding :ref:`classes`.
|
||||
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| Data type | Description | Header file |
|
||||
+====================================+===========================+===============================+
|
||||
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
|
||||
| ``std::u16string_view``, etc. | | |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-------------------------------+
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| Data type | Description | Header file |
|
||||
+====================================+===========================+===================================+
|
||||
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
|
||||
| ``std::u16string_view``, etc. | | |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl/filesystem.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
|
||||
.. [#] ``std::filesystem::path`` is converted to ``pathlib.Path`` and
|
||||
``os.PathLike`` is converted to ``std::filesystem::path``, but this requires
|
||||
|
||||
+16
-16
@@ -36,13 +36,13 @@ everywhere <http://utf8everywhere.org/>`_.
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> utf8_test('🎂')
|
||||
>>> utf8_test("🎂")
|
||||
utf-8 is icing on the cake.
|
||||
🎂
|
||||
|
||||
>>> utf8_charptr('🍕')
|
||||
>>> utf8_charptr("🍕")
|
||||
My favorite food is
|
||||
🍕
|
||||
|
||||
@@ -80,7 +80,7 @@ raise a ``UnicodeDecodeError``.
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> isinstance(example.std_string_return(), str)
|
||||
True
|
||||
@@ -114,7 +114,7 @@ conversion has the same overhead as implicit conversion.
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> str_output()
|
||||
'Send your résumé to Alice in HR'
|
||||
@@ -143,7 +143,7 @@ returned to Python as ``bytes``, then one can return the data as a
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.return_bytes()
|
||||
b'\xba\xd0\xba\xd0'
|
||||
@@ -160,7 +160,7 @@ encoding, but cannot convert ``std::string`` back to ``bytes`` implicitly.
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> isinstance(example.asymmetry(b"have some bytes"), str)
|
||||
True
|
||||
@@ -229,16 +229,16 @@ character.
|
||||
m.def("pass_char", [](char c) { return c; });
|
||||
m.def("pass_wchar", [](wchar_t w) { return w; });
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_char('A')
|
||||
>>> example.pass_char("A")
|
||||
'A'
|
||||
|
||||
While C++ will cast integers to character types (``char c = 0x65;``), pybind11
|
||||
does not convert Python integers to characters implicitly. The Python function
|
||||
``chr()`` can be used to convert integers to characters.
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_char(0x65)
|
||||
TypeError
|
||||
@@ -259,17 +259,17 @@ a combining acute accent). The combining character will be lost if the
|
||||
two-character sequence is passed as an argument, even though it renders as a
|
||||
single grapheme.
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_wchar('é')
|
||||
>>> example.pass_wchar("é")
|
||||
'é'
|
||||
|
||||
>>> combining_e_acute = 'e' + '\u0301'
|
||||
>>> combining_e_acute = "e" + "\u0301"
|
||||
|
||||
>>> combining_e_acute
|
||||
'é'
|
||||
|
||||
>>> combining_e_acute == 'é'
|
||||
>>> combining_e_acute == "é"
|
||||
False
|
||||
|
||||
>>> example.pass_wchar(combining_e_acute)
|
||||
@@ -278,9 +278,9 @@ single grapheme.
|
||||
Normalizing combining characters before passing the character literal to C++
|
||||
may resolve *some* of these issues:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_wchar(unicodedata.normalize('NFC', combining_e_acute))
|
||||
>>> example.pass_wchar(unicodedata.normalize("NFC", combining_e_acute))
|
||||
'é'
|
||||
|
||||
In some languages (Thai for example), there are `graphemes that cannot be
|
||||
|
||||
+92
-4
@@ -9,7 +9,7 @@ that you are already familiar with the basics from :doc:`/classes`.
|
||||
Overriding virtual functions in Python
|
||||
======================================
|
||||
|
||||
Suppose that a C++ class or interface has a virtual function that we'd like to
|
||||
Suppose that a C++ class or interface has a virtual function that we'd like
|
||||
to override from within Python (we'll focus on the class ``Animal``; ``Dog`` is
|
||||
given as a specific example of how one would do this with traditional C++
|
||||
code).
|
||||
@@ -136,7 +136,7 @@ a virtual method call.
|
||||
u'woof! woof! woof! '
|
||||
>>> class Cat(Animal):
|
||||
... def go(self, n_times):
|
||||
... return "meow! " * n_times
|
||||
... return "meow! " * n_times
|
||||
...
|
||||
>>> c = Cat()
|
||||
>>> call_go(c)
|
||||
@@ -159,8 +159,9 @@ Here is an example:
|
||||
|
||||
class Dachshund(Dog):
|
||||
def __init__(self, name):
|
||||
Dog.__init__(self) # Without this, a TypeError is raised.
|
||||
Dog.__init__(self) # Without this, a TypeError is raised.
|
||||
self.name = name
|
||||
|
||||
def bark(self):
|
||||
return "yap!"
|
||||
|
||||
@@ -1153,12 +1154,65 @@ error:
|
||||
|
||||
>>> class PyFinalChild(IsFinal):
|
||||
... pass
|
||||
...
|
||||
TypeError: type 'IsFinal' is not an acceptable base type
|
||||
|
||||
.. note:: This attribute is currently ignored on PyPy
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Binding classes with template parameters
|
||||
========================================
|
||||
|
||||
pybind11 can also wrap classes that have template parameters. Consider these classes:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Cat {};
|
||||
struct Dog {};
|
||||
|
||||
template <typename PetType>
|
||||
struct Cage {
|
||||
Cage(PetType& pet);
|
||||
PetType& get();
|
||||
};
|
||||
|
||||
C++ templates may only be instantiated at compile time, so pybind11 can only
|
||||
wrap instantiated templated classes. You cannot wrap a non-instantiated template:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// BROKEN (this will not compile)
|
||||
py::class_<Cage>(m, "Cage");
|
||||
.def("get", &Cage::get);
|
||||
|
||||
You must explicitly specify each template/type combination that you want to
|
||||
wrap separately.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// ok
|
||||
py::class_<Cage<Cat>>(m, "CatCage")
|
||||
.def("get", &Cage<Cat>::get);
|
||||
|
||||
// ok
|
||||
py::class_<Cage<Dog>>(m, "DogCage")
|
||||
.def("get", &Cage<Dog>::get);
|
||||
|
||||
If your class methods have template parameters you can wrap those as well,
|
||||
but once again each instantiation must be explicitly specified:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
typename <typename T>
|
||||
struct MyClass {
|
||||
template <typename V>
|
||||
T fn(V v);
|
||||
};
|
||||
|
||||
py::class<MyClass<int>>(m, "MyClassT")
|
||||
.def("fn", &MyClass<int>::fn<std::string>);
|
||||
|
||||
Custom automatic downcasters
|
||||
============================
|
||||
|
||||
@@ -1247,7 +1301,7 @@ Accessing the type object
|
||||
|
||||
You can get the type object from a C++ class that has already been registered using:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: cpp
|
||||
|
||||
py::type T_py = py::type::of<T>();
|
||||
|
||||
@@ -1259,3 +1313,37 @@ object, just like ``type(ob)`` in Python.
|
||||
Other types, like ``py::type::of<int>()``, do not work, see :ref:`type-conversions`.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Custom type setup
|
||||
=================
|
||||
|
||||
For advanced use cases, such as enabling garbage collection support, you may
|
||||
wish to directly manipulate the ``PyHeapTypeObject`` corresponding to a
|
||||
``py::class_`` definition.
|
||||
|
||||
You can do that using ``py::custom_type_setup``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct OwnsPythonObjects {
|
||||
py::object value = py::none();
|
||||
};
|
||||
py::class_<OwnsPythonObjects> cls(
|
||||
m, "OwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
||||
type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {
|
||||
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
|
||||
Py_VISIT(self.value.ptr());
|
||||
return 0;
|
||||
};
|
||||
type->tp_clear = [](PyObject *self_base) {
|
||||
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
|
||||
self.value = py::none();
|
||||
return 0;
|
||||
};
|
||||
}));
|
||||
cls.def(py::init<>());
|
||||
cls.def_readwrite("value", &OwnsPythonObjects::value);
|
||||
|
||||
.. versionadded:: 2.8
|
||||
|
||||
+14
-13
@@ -40,15 +40,15 @@ The essential structure of the ``main.cpp`` file looks like this:
|
||||
}
|
||||
|
||||
The interpreter must be initialized before using any Python API, which includes
|
||||
all the functions and classes in pybind11. The RAII guard class `scoped_interpreter`
|
||||
all the functions and classes in pybind11. The RAII guard class ``scoped_interpreter``
|
||||
takes care of the interpreter lifetime. After the guard is destroyed, the interpreter
|
||||
shuts down and clears its memory. No Python functions can be called after this.
|
||||
|
||||
Executing Python code
|
||||
=====================
|
||||
|
||||
There are a few different ways to run Python code. One option is to use `eval`,
|
||||
`exec` or `eval_file`, as explained in :ref:`eval`. Here is a quick example in
|
||||
There are a few different ways to run Python code. One option is to use ``eval``,
|
||||
``exec`` or ``eval_file``, as explained in :ref:`eval`. Here is a quick example in
|
||||
the context of an executable with an embedded interpreter:
|
||||
|
||||
.. code-block:: cpp
|
||||
@@ -108,7 +108,7 @@ The two approaches can also be combined:
|
||||
Importing modules
|
||||
=================
|
||||
|
||||
Python modules can be imported using `module_::import()`:
|
||||
Python modules can be imported using ``module_::import()``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -122,6 +122,7 @@ embedding the interpreter. This makes it easy to import local Python files:
|
||||
|
||||
"""calc.py located in the working directory"""
|
||||
|
||||
|
||||
def add(i, j):
|
||||
return i + j
|
||||
|
||||
@@ -133,7 +134,7 @@ embedding the interpreter. This makes it easy to import local Python files:
|
||||
int n = result.cast<int>();
|
||||
assert(n == 3);
|
||||
|
||||
Modules can be reloaded using `module_::reload()` if the source is modified e.g.
|
||||
Modules can be reloaded using ``module_::reload()`` if the source is modified e.g.
|
||||
by an external process. This can be useful in scenarios where the application
|
||||
imports a user defined data processing script which needs to be updated after
|
||||
changes by the user. Note that this function does not reload modules recursively.
|
||||
@@ -143,7 +144,7 @@ changes by the user. Note that this function does not reload modules recursively
|
||||
Adding embedded modules
|
||||
=======================
|
||||
|
||||
Embedded binary modules can be added using the `PYBIND11_EMBEDDED_MODULE` macro.
|
||||
Embedded binary modules can be added using the ``PYBIND11_EMBEDDED_MODULE`` macro.
|
||||
Note that the definition must be placed at global scope. They can be imported
|
||||
like any other module.
|
||||
|
||||
@@ -169,7 +170,7 @@ like any other module.
|
||||
|
||||
Unlike extension modules where only a single binary module can be created, on
|
||||
the embedded side an unlimited number of modules can be added using multiple
|
||||
`PYBIND11_EMBEDDED_MODULE` definitions (as long as they have unique names).
|
||||
``PYBIND11_EMBEDDED_MODULE`` definitions (as long as they have unique names).
|
||||
|
||||
These modules are added to Python's list of builtins, so they can also be
|
||||
imported in pure Python files loaded by the interpreter. Everything interacts
|
||||
@@ -215,9 +216,9 @@ naturally:
|
||||
Interpreter lifetime
|
||||
====================
|
||||
|
||||
The Python interpreter shuts down when `scoped_interpreter` is destroyed. After
|
||||
The Python interpreter shuts down when ``scoped_interpreter`` is destroyed. After
|
||||
this, creating a new instance will restart the interpreter. Alternatively, the
|
||||
`initialize_interpreter` / `finalize_interpreter` pair of functions can be used
|
||||
``initialize_interpreter`` / ``finalize_interpreter`` pair of functions can be used
|
||||
to directly set the state at any time.
|
||||
|
||||
Modules created with pybind11 can be safely re-initialized after the interpreter
|
||||
@@ -229,8 +230,8 @@ global data. All the details can be found in the CPython documentation.
|
||||
|
||||
.. warning::
|
||||
|
||||
Creating two concurrent `scoped_interpreter` guards is a fatal error. So is
|
||||
calling `initialize_interpreter` for a second time after the interpreter
|
||||
Creating two concurrent ``scoped_interpreter`` guards is a fatal error. So is
|
||||
calling ``initialize_interpreter`` for a second time after the interpreter
|
||||
has already been initialized.
|
||||
|
||||
Do not use the raw CPython API functions ``Py_Initialize`` and
|
||||
@@ -241,7 +242,7 @@ global data. All the details can be found in the CPython documentation.
|
||||
Sub-interpreter support
|
||||
=======================
|
||||
|
||||
Creating multiple copies of `scoped_interpreter` is not possible because it
|
||||
Creating multiple copies of ``scoped_interpreter`` is not possible because it
|
||||
represents the main Python interpreter. Sub-interpreters are something different
|
||||
and they do permit the existence of multiple interpreters. This is an advanced
|
||||
feature of the CPython API and should be handled with care. pybind11 does not
|
||||
@@ -257,5 +258,5 @@ We'll just mention a couple of caveats the sub-interpreters support in pybind11:
|
||||
2. Managing multiple threads, multiple interpreters and the GIL can be
|
||||
challenging and there are several caveats here, even within the pure
|
||||
CPython API (please refer to the Python docs for details). As for
|
||||
pybind11, keep in mind that `gil_scoped_release` and `gil_scoped_acquire`
|
||||
pybind11, keep in mind that ``gil_scoped_release`` and ``gil_scoped_acquire``
|
||||
do not take sub-interpreters into account.
|
||||
|
||||
+100
-12
@@ -56,13 +56,15 @@ at its exception handler.
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::buffer_error` | ``BufferError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::import_error` | ``import_error`` |
|
||||
| :class:`pybind11::import_error` | ``ImportError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::attribute_error` | ``AttributeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| Any other exception | ``RuntimeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
|
||||
Exception translation is not bidirectional. That is, *catching* the C++
|
||||
exceptions defined above above will not trap exceptions that originate from
|
||||
exceptions defined above will not trap exceptions that originate from
|
||||
Python. For that, catch :class:`pybind11::error_already_set`. See :ref:`below
|
||||
<handling_python_exceptions_cpp>` for further details.
|
||||
|
||||
@@ -75,9 +77,10 @@ Registering custom translators
|
||||
|
||||
If the default exception conversion policy described above is insufficient,
|
||||
pybind11 also provides support for registering custom exception translators.
|
||||
To register a simple exception conversion that translates a C++ exception into
|
||||
a new Python exception using the C++ exception's ``what()`` method, a helper
|
||||
function is available:
|
||||
Similar to pybind11 classes, exception translators can be local to the module
|
||||
they are defined in or global to the entire python session. To register a simple
|
||||
exception conversion that translates a C++ exception into a new Python exception
|
||||
using the C++ exception's ``what()`` method, a helper function is available:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -87,29 +90,39 @@ This call creates a Python exception class with the name ``PyExp`` in the given
|
||||
module and automatically converts any encountered exceptions of type ``CppExp``
|
||||
into Python exceptions of type ``PyExp``.
|
||||
|
||||
A matching function is available for registering a local exception translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_local_exception<CppExp>(module, "PyExp");
|
||||
|
||||
|
||||
It is possible to specify base class for the exception using the third
|
||||
parameter, a `handle`:
|
||||
parameter, a ``handle``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
||||
py::register_local_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
||||
|
||||
Then `PyExp` can be caught both as `PyExp` and `RuntimeError`.
|
||||
Then ``PyExp`` can be caught both as ``PyExp`` and ``RuntimeError``.
|
||||
|
||||
The class objects of the built-in Python exceptions are listed in the Python
|
||||
documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
|
||||
The default base class is `PyExc_Exception`.
|
||||
The default base class is ``PyExc_Exception``.
|
||||
|
||||
When more advanced exception translation is needed, the function
|
||||
``py::register_exception_translator(translator)`` can be used to register
|
||||
When more advanced exception translation is needed, the functions
|
||||
``py::register_exception_translator(translator)`` and
|
||||
``py::register_local_exception_translator(translator)`` can be used to register
|
||||
functions that can translate arbitrary exception types (and which may include
|
||||
additional logic to do so). The function takes a stateless callable (e.g. a
|
||||
additional logic to do so). The functions takes a stateless callable (e.g. a
|
||||
function pointer or a lambda function without captured variables) with the call
|
||||
signature ``void(std::exception_ptr)``.
|
||||
|
||||
When a C++ exception is thrown, the registered exception translators are tried
|
||||
in reverse order of registration (i.e. the last registered translator gets the
|
||||
first shot at handling the exception).
|
||||
first shot at handling the exception). All local translators will be tried
|
||||
before a global translator is tried.
|
||||
|
||||
Inside the translator, ``std::rethrow_exception`` should be used within
|
||||
a try block to re-throw the exception. One or more catch clauses to catch
|
||||
@@ -168,6 +181,53 @@ section.
|
||||
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI boundaries need to be explicitly exported, as exercised in ``tests/test_exceptions.h``.
|
||||
See also: "Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
|
||||
|
||||
|
||||
Local vs Global Exception Translators
|
||||
=====================================
|
||||
|
||||
When a global exception translator is registered, it will be applied across all
|
||||
modules in the reverse order of registration. This can create behavior where the
|
||||
order of module import influences how exceptions are translated.
|
||||
|
||||
If module1 has the following translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception_translator([](std::exception_ptr p) {
|
||||
try {
|
||||
if (p) std::rethrow_exception(p);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
PyErr_SetString("module1 handled this")
|
||||
}
|
||||
}
|
||||
|
||||
and module2 has the following similar translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception_translator([](std::exception_ptr p) {
|
||||
try {
|
||||
if (p) std::rethrow_exception(p);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
PyErr_SetString("module2 handled this")
|
||||
}
|
||||
}
|
||||
|
||||
then which translator handles the invalid_argument will be determined by the
|
||||
order that module1 and module2 are imported. Since exception translators are
|
||||
applied in the reverse order of registration, which ever module was imported
|
||||
last will "win" and that translator will be applied.
|
||||
|
||||
If there are multiple pybind11 modules that share exception types (either
|
||||
standard built-in or custom) loaded into a single python instance and
|
||||
consistent error handling behavior is needed, then local translators should be
|
||||
used.
|
||||
|
||||
Changing the previous example to use ``register_local_exception_translator``
|
||||
would mean that when invalid_argument is thrown in the module2 code, the
|
||||
module2 translator will always handle it, while in module1, the module1
|
||||
translator will do the same.
|
||||
|
||||
.. _handling_python_exceptions_cpp:
|
||||
|
||||
Handling exceptions from Python in C++
|
||||
@@ -265,6 +325,34 @@ Alternately, to ignore the error, call `PyErr_Clear
|
||||
Any Python error must be thrown or cleared, or Python/pybind11 will be left in
|
||||
an invalid state.
|
||||
|
||||
Chaining exceptions ('raise from')
|
||||
==================================
|
||||
|
||||
In Python 3.3 a mechanism for indicating that exceptions were caused by other
|
||||
exceptions was introduced:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
try:
|
||||
print(1 / 0)
|
||||
except Exception as exc:
|
||||
raise RuntimeError("could not divide by zero") from exc
|
||||
|
||||
To do a similar thing in pybind11, you can use the ``py::raise_from`` function. It
|
||||
sets the current python error indicator, so to continue propagating the exception
|
||||
you should ``throw py::error_already_set()`` (Python 3 only).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
try {
|
||||
py::eval("print(1 / 0"));
|
||||
} catch (py::error_already_set &e) {
|
||||
py::raise_from(e, PyExc_RuntimeError, "could not divide by zero");
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
.. versionadded:: 2.8
|
||||
|
||||
.. _unraisable_exceptions:
|
||||
|
||||
Handling unraisable exceptions
|
||||
|
||||
+55
-7
@@ -120,7 +120,7 @@ targeted arguments can be passed through the :class:`cpp_function` constructor:
|
||||
.. code-block:: cpp
|
||||
|
||||
class_<MyClass>(m, "MyClass")
|
||||
.def_property("data"
|
||||
.def_property("data",
|
||||
py::cpp_function(&MyClass::getData, py::return_value_policy::copy),
|
||||
py::cpp_function(&MyClass::setData)
|
||||
);
|
||||
@@ -232,7 +232,7 @@ is equivalent to the following pseudocode:
|
||||
});
|
||||
|
||||
The only requirement is that ``T`` is default-constructible, but otherwise any
|
||||
scope guard will work. This is very useful in combination with `gil_scoped_release`.
|
||||
scope guard will work. This is very useful in combination with ``gil_scoped_release``.
|
||||
See :ref:`gil`.
|
||||
|
||||
Multiple guards can also be specified as ``py::call_guard<T1, T2, T3...>``. The
|
||||
@@ -272,7 +272,7 @@ And used in Python as usual:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print_dict({'foo': 123, 'bar': 'hello'})
|
||||
>>> print_dict({"foo": 123, "bar": "hello"})
|
||||
key=foo, value=123
|
||||
key=bar, value=hello
|
||||
|
||||
@@ -306,8 +306,9 @@ The class ``py::args`` derives from ``py::tuple`` and ``py::kwargs`` derives
|
||||
from ``py::dict``.
|
||||
|
||||
You may also use just one or the other, and may combine these with other
|
||||
arguments as long as the ``py::args`` and ``py::kwargs`` arguments are the last
|
||||
arguments accepted by the function.
|
||||
arguments. Note, however, that ``py::kwargs`` must always be the last argument
|
||||
of the function, and ``py::args`` implies that any further arguments are
|
||||
keyword-only (see :ref:`keyword_only_arguments`).
|
||||
|
||||
Please refer to the other examples for details on how to iterate over these,
|
||||
and on how to cast their entries into C++ objects. A demonstration is also
|
||||
@@ -366,6 +367,8 @@ like so:
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg("arg") = static_cast<SomeType *>(nullptr));
|
||||
|
||||
.. _keyword_only_arguments:
|
||||
|
||||
Keyword-only arguments
|
||||
======================
|
||||
|
||||
@@ -377,10 +380,11 @@ argument in a function definition:
|
||||
def f(a, *, b): # a can be positional or via keyword; b must be via keyword
|
||||
pass
|
||||
|
||||
|
||||
f(a=1, b=2) # good
|
||||
f(b=2, a=1) # good
|
||||
f(1, b=2) # good
|
||||
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
|
||||
f(1, b=2) # good
|
||||
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
|
||||
|
||||
Pybind11 provides a ``py::kw_only`` object that allows you to implement
|
||||
the same behaviour by specifying the object between positional and keyword-only
|
||||
@@ -396,6 +400,15 @@ feature does *not* require Python 3 to work.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
As of pybind11 2.9, a ``py::args`` argument implies that any following arguments
|
||||
are keyword-only, as if ``py::kw_only()`` had been specified in the same
|
||||
relative location of the argument list as the ``py::args`` argument. The
|
||||
``py::kw_only()`` may be included to be explicit about this, but is not
|
||||
required. (Prior to 2.9 ``py::args`` may only occur at the end of the argument
|
||||
list, or immediately before a ``py::kwargs`` argument at the end).
|
||||
|
||||
.. versionadded:: 2.9
|
||||
|
||||
Positional-only arguments
|
||||
=========================
|
||||
|
||||
@@ -565,3 +578,38 @@ prefers earlier-defined overloads to later-defined ones.
|
||||
.. versionadded:: 2.6
|
||||
|
||||
The ``py::prepend()`` tag.
|
||||
|
||||
Binding functions with template parameters
|
||||
==========================================
|
||||
|
||||
You can bind functions that have template parameters. Here's a function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <typename T>
|
||||
void set(T t);
|
||||
|
||||
C++ templates cannot be instantiated at runtime, so you cannot bind the
|
||||
non-instantiated function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// BROKEN (this will not compile)
|
||||
m.def("set", &set);
|
||||
|
||||
You must bind each instantiated function template separately. You may bind
|
||||
each instantiation with the same name, which will be treated the same as
|
||||
an overloaded function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("set", &set<int>);
|
||||
m.def("set", &set<std::string>);
|
||||
|
||||
Sometimes it's more clear to bind them with separate names, which is also
|
||||
an option:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("setInt", &set<int>);
|
||||
m.def("setString", &set<std::string>);
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ could be realized as follows (important changes highlighted):
|
||||
});
|
||||
}
|
||||
|
||||
The ``call_go`` wrapper can also be simplified using the `call_guard` policy
|
||||
The ``call_go`` wrapper can also be simplified using the ``call_guard`` policy
|
||||
(see :ref:`call_policies`) which yields the same result:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
+35
-10
@@ -171,6 +171,31 @@ template parameter, and it ensures that non-conforming arguments are converted
|
||||
into an array satisfying the specified requirements instead of trying the next
|
||||
function overload.
|
||||
|
||||
There are several methods on arrays; the methods listed below under references
|
||||
work, as well as the following functions based on the NumPy API:
|
||||
|
||||
- ``.dtype()`` returns the type of the contained values.
|
||||
|
||||
- ``.strides()`` returns a pointer to the strides of the array (optionally pass
|
||||
an integer axis to get a number).
|
||||
|
||||
- ``.flags()`` returns the flag settings. ``.writable()`` and ``.owndata()``
|
||||
are directly available.
|
||||
|
||||
- ``.offset_at()`` returns the offset (optionally pass indices).
|
||||
|
||||
- ``.squeeze()`` returns a view with length-1 axes removed.
|
||||
|
||||
- ``.view(dtype)`` returns a view of the array with a different dtype.
|
||||
|
||||
- ``.reshape({i, j, ...})`` returns a view of the array with a different shape.
|
||||
``.resize({...})`` is also available.
|
||||
|
||||
- ``.index_at(i, j, ...)`` gets the count from the beginning to a given index.
|
||||
|
||||
|
||||
There are also several methods for getting references (described below).
|
||||
|
||||
Structured types
|
||||
================
|
||||
|
||||
@@ -233,8 +258,8 @@ by the compiler. The result is returned as a NumPy array of type
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> x = np.array([[1, 3],[5, 7]])
|
||||
>>> y = np.array([[2, 4],[6, 8]])
|
||||
>>> x = np.array([[1, 3], [5, 7]])
|
||||
>>> y = np.array([[2, 4], [6, 8]])
|
||||
>>> z = 3
|
||||
>>> result = vectorized_func(x, y, z)
|
||||
|
||||
@@ -345,21 +370,21 @@ The returned proxy object supports some of the same methods as ``py::array`` so
|
||||
that it can be used as a drop-in replacement for some existing, index-checked
|
||||
uses of ``py::array``:
|
||||
|
||||
- ``r.ndim()`` returns the number of dimensions
|
||||
- ``.ndim()`` returns the number of dimensions
|
||||
|
||||
- ``r.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
|
||||
- ``.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
|
||||
the ``const T`` or ``T`` data, respectively, at the given indices. The
|
||||
latter is only available to proxies obtained via ``a.mutable_unchecked()``.
|
||||
|
||||
- ``itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
|
||||
- ``.itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
|
||||
|
||||
- ``ndim()`` returns the number of dimensions.
|
||||
- ``.ndim()`` returns the number of dimensions.
|
||||
|
||||
- ``shape(n)`` returns the size of dimension ``n``
|
||||
- ``.shape(n)`` returns the size of dimension ``n``
|
||||
|
||||
- ``size()`` returns the total number of elements (i.e. the product of the shapes).
|
||||
- ``.size()`` returns the total number of elements (i.e. the product of the shapes).
|
||||
|
||||
- ``nbytes()`` returns the number of bytes used by the referenced elements
|
||||
- ``.nbytes()`` returns the number of bytes used by the referenced elements
|
||||
(i.e. ``itemsize()`` times ``size()``).
|
||||
|
||||
.. seealso::
|
||||
@@ -378,7 +403,7 @@ In Python 2, the syntactic sugar ``...`` is not available, but the singleton
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
a = # a NumPy array
|
||||
a = ... # a NumPy array
|
||||
b = a[0, ..., 0]
|
||||
|
||||
The function ``py::ellipsis()`` function can be used to perform the same
|
||||
|
||||
+36
-1
@@ -20,6 +20,40 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
|
||||
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
|
||||
your C++ API.
|
||||
|
||||
.. _instantiating_compound_types:
|
||||
|
||||
Instantiating compound Python types from C++
|
||||
============================================
|
||||
|
||||
Dictionaries can be initialized in the :class:`dict` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace pybind11::literals; // to bring in the `_a` literal
|
||||
py::dict d("spam"_a=py::none(), "eggs"_a=42);
|
||||
|
||||
A tuple of python objects can be instantiated using :func:`py::make_tuple`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::tuple tup = py::make_tuple(42, py::none(), "spam");
|
||||
|
||||
Each element is converted to a supported Python type.
|
||||
|
||||
A `simple namespace`_ can be instantiated using
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace pybind11::literals; // to bring in the `_a` literal
|
||||
py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace");
|
||||
py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42);
|
||||
|
||||
Attributes on a namespace can be modified with the :func:`py::delattr`,
|
||||
:func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can
|
||||
be useful as lightweight stand-ins for class instances.
|
||||
|
||||
.. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace
|
||||
|
||||
.. _casting_back_and_forth:
|
||||
|
||||
Casting back and forth
|
||||
@@ -30,7 +64,7 @@ types to Python, which can be done using :func:`py::cast`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
MyClass *cls = ..;
|
||||
MyClass *cls = ...;
|
||||
py::object obj = py::cast(cls);
|
||||
|
||||
The reverse direction uses the following syntax:
|
||||
@@ -132,6 +166,7 @@ Keyword arguments are also supported. In Python, there is the usual call syntax:
|
||||
def f(number, say, to):
|
||||
... # function code
|
||||
|
||||
|
||||
f(1234, say="hello", to=some_instance) # keyword call in Python
|
||||
|
||||
In C++, the same call can be made using:
|
||||
|
||||
+6
-6
@@ -28,7 +28,7 @@ Capturing standard output from ostream
|
||||
|
||||
Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
|
||||
but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
|
||||
redirection. Replacing a library's printing with `py::print <print>` may not
|
||||
redirection. Replacing a library's printing with ``py::print <print>`` may not
|
||||
be feasible. This can be fixed using a guard around the library function that
|
||||
redirects output to the corresponding Python streams:
|
||||
|
||||
@@ -62,11 +62,11 @@ This method respects flushes on the output streams and will flush if needed
|
||||
when the scoped guard is destroyed. This allows the output to be redirected in
|
||||
real time, such as to a Jupyter notebook. The two arguments, the C++ stream and
|
||||
the Python output, are optional, and default to standard output if not given. An
|
||||
extra type, `py::scoped_estream_redirect <scoped_estream_redirect>`, is identical
|
||||
extra type, ``py::scoped_estream_redirect <scoped_estream_redirect>``, is identical
|
||||
except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
|
||||
`py::call_guard`, which allows multiple items, but uses the default constructor:
|
||||
``py::call_guard``, which allows multiple items, but uses the default constructor:
|
||||
|
||||
.. code-block:: py
|
||||
.. code-block:: cpp
|
||||
|
||||
// Alternative: Call single function using call guard
|
||||
m.def("noisy_func", &call_noisy_function,
|
||||
@@ -74,7 +74,7 @@ except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful wi
|
||||
py::scoped_estream_redirect>());
|
||||
|
||||
The redirection can also be done in Python with the addition of a context
|
||||
manager, using the `py::add_ostream_redirect() <add_ostream_redirect>` function:
|
||||
manager, using the ``py::add_ostream_redirect() <add_ostream_redirect>`` function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -103,7 +103,7 @@ arguments to disable one of the streams if needed.
|
||||
Evaluating Python expressions from strings and files
|
||||
====================================================
|
||||
|
||||
pybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate
|
||||
pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate
|
||||
Python expressions and statements. The following example illustrates how they
|
||||
can be used.
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ segmentation fault).
|
||||
.. code-block:: python
|
||||
|
||||
from example import Parent
|
||||
|
||||
print(Parent().get_child())
|
||||
|
||||
The problem is that ``Parent::get_child()`` returns a pointer to an instance of
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user