From 274e88d381982916257db36f182861bd48f1a11f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Dec 2015 12:56:18 +0100 Subject: [PATCH 01/14] Fix Python demo script gen_gerber_and_drill_files_board.py to choose one or 2 drill files when calling SetOptions() if NPTH pads are used. --- .../gen_gerber_and_drill_files_board.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py b/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py index 0be356165a..55c1698b48 100644 --- a/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py +++ b/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py @@ -36,11 +36,11 @@ popt = pctl.GetPlotOptions() popt.SetOutputDirectory(plotDir) # Set some important plot options: -popt.SetPlotFrameRef(False) +popt.SetPlotFrameRef(False) #do not change it popt.SetLineWidth(FromMM(0.35)) -popt.SetAutoScale(False) -popt.SetScale(1) +popt.SetAutoScale(False) #do not change it +popt.SetScale(1) #do not change it popt.SetMirror(False) popt.SetUseGerberAttributes(True) popt.SetUseGerberProtelExtensions(False) @@ -100,7 +100,10 @@ drlwriter.SetMapFileFormat( PLOT_FORMAT_PDF ) mirror = False minimalHeader = False offset = wxPoint(0,0) -drlwriter.SetOptions( mirror, minimalHeader, offset ) +# False to generate 2 separate drill files (one for plated holes, one for non plated holes) +# True to generate only one drill file +mergeNPTH = False +drlwriter.SetOptions( mirror, minimalHeader, offset, mergeNPTH ) metricFmt = True drlwriter.SetFormat( metricFmt ) From 030c84d55dacd43596bf0560864f742362729464 Mon Sep 17 00:00:00 2001 From: Mark Roszko Date: Wed, 9 Dec 2015 09:41:41 -0500 Subject: [PATCH 02/14] Use defined environment variables before falling back to DEFAULT_INSTALL_PATH. --- common/pgm_base.cpp | 51 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 6322138c31..039a8572c4 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -416,6 +416,8 @@ bool PGM_BASE::initPgm() { wxString envVarName = wxT( "KIGITHUB" ); ENV_VAR_ITEM envVarItem; + wxString envValue; + wxFileName tmpFileName; envVarItem.SetValue( wxString( wxT( "https://github.com/KiCad" ) ) ); envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) ); @@ -429,24 +431,51 @@ bool PGM_BASE::initPgm() baseSharePath.AppendDir( wxT( "kicad" ) ); #endif - wxFileName tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "modules" ) ); + // KISYSMOD envVarName = wxT( "KISYSMOD" ); - envVarItem.SetValue( tmpFileName.GetPath() ); - envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( wxT( "modules" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); m_local_env_vars[ envVarName ] = envVarItem; + // KISYS3DMOD envVarName = wxT( "KISYS3DMOD" ); - tmpFileName.AppendDir( wxT( "packages3d" ) ); - envVarItem.SetValue( tmpFileName.GetPath() ); - envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName.AppendDir( wxT( "packages3d" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); m_local_env_vars[ envVarName ] = envVarItem; + // KICAD_PTEMPLATES envVarName = wxT( "KICAD_PTEMPLATES" ); - tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "template" ) ); - envVarItem.SetValue( tmpFileName.GetPath() ); - envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( wxT( "template" ) ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetFullPath() ); m_local_env_vars[ envVarName ] = envVarItem; } From 04271893ff8baa7fb3e61df406a073fd392316b7 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 9 Dec 2015 17:11:32 +0100 Subject: [PATCH 03/14] Fix Bug #1521282 (footprint wizard for SOIC ICs generates a wrong position pin mark) --- pcbnew/scripting/plugins/sdip_wizard.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pcbnew/scripting/plugins/sdip_wizard.py b/pcbnew/scripting/plugins/sdip_wizard.py index 31f53cd50d..69af86b796 100644 --- a/pcbnew/scripting/plugins/sdip_wizard.py +++ b/pcbnew/scripting/plugins/sdip_wizard.py @@ -232,6 +232,11 @@ class SOICWizard(RowedFootprint): # |1 2 3 4 | # \--------- - self.draw.BoxWithDiagonalAtCorner(0, 0, ssx*2, ssy*2, pcbnew.FromMM(1)) + setback = pcbnew.FromMM(0.8) + + if setback > ssy: + setback = ssy + + self.draw.BoxWithDiagonalAtCorner(0, 0, ssx*2, ssy*2, setback, self.draw.flipY) SOICWizard().register() From e87258510567cb95800178dec30b058c885c326c Mon Sep 17 00:00:00 2001 From: Simon Richter Date: Wed, 9 Dec 2015 15:53:52 -0500 Subject: [PATCH 04/14] CMake: move find OpenMP so it can be found for all compilers not just GCC. --- CMakeLists.txt | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0479c2431a..f612687ea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,20 +180,6 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG" ) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG" ) - find_package( OpenMP QUIET ) - - if( OPENMP_FOUND ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" ) - add_definitions( -DUSE_OPENMP ) - - # MinGW does not include the OpenMP link library and FindOpenMP.cmake does not - # set it either. Not sure this is the most elegant solution but it works. - if( MINGW ) - set( OPENMP_LIBRARIES gomp ) - endif() - endif() - if( MINGW ) set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" ) @@ -425,6 +411,25 @@ include( ExternalProject ) #================================================ include( CheckFindPackageResult ) +####################### +# Find OpenMP support # +####################### + +find_package( OpenMP QUIET ) +check_find_package_result( OPENMP_FOUND "OpenMP" ) + +if( OPENMP_FOUND ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" ) + add_definitions( -DUSE_OPENMP ) + + # MinGW does not include the OpenMP link library and FindOpenMP.cmake does not + # set it either. Not sure this is the most elegant solution but it works. + if( MINGW ) + set( OPENMP_LIBRARIES gomp ) + endif() +endif() + ########################## # Find wxWidgets library # ########################## From eaef5c1043de3d28607e75cb52725c8dfb89e331 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Dec 2015 09:13:35 +0100 Subject: [PATCH 05/14] * Replace questionable wxString::PrintfV() call (which doesn't work reliably on different platforms) with wxString::Format() * Extra win: due to use now of the THROW_IO_ERROR() macro, error messages contain line numbers. --- pcbnew/specctra.cpp | 14 ----------- pcbnew/specctra.h | 2 -- pcbnew/specctra_export.cpp | 19 +++++++-------- pcbnew/specctra_import.cpp | 49 ++++++++++++++++++-------------------- 4 files changed, 32 insertions(+), 52 deletions(-) diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp index 2358d3b07d..92ac465810 100644 --- a/pcbnew/specctra.cpp +++ b/pcbnew/specctra.cpp @@ -131,20 +131,6 @@ int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const return -1; } - -void SPECCTRA_DB::ThrowIOError( const wxString& fmt, ... ) throw( IO_ERROR ) -{ - wxString errText; - va_list args; - - va_start( args, fmt ); - errText.PrintfV( fmt, args ); - va_end( args ); - - THROW_IO_ERROR( errText ); -} - - void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IO_ERROR ) { T tok; diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h index 540fcf9b13..f9ce20a861 100644 --- a/pcbnew/specctra.h +++ b/pcbnew/specctra.h @@ -3919,8 +3919,6 @@ public: */ void LoadSESSION( const wxString& filename ) throw( IO_ERROR, boost::bad_pointer ); - void ThrowIOError( const wxString& fmt, ... ) throw( IO_ERROR ); - /** * Function ExportPCB * writes the internal PCB instance out as a SPECTRA DSN format file. diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 1754189bf6..7b760b4ae2 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1025,7 +1025,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) wxString error = wxString::Format( _( "Unsupported DRAWSEGMENT type %s" ), GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) ); - ThrowIOError( error ); + THROW_IO_ERROR( error ); } break; } @@ -1132,7 +1132,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) wxString error = wxString::Format( _( "Unsupported DRAWSEGMENT type %s" ), GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) ); - ThrowIOError( error ); + THROW_IO_ERROR( error ); } break; } @@ -1159,7 +1159,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ), GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) ) ); - ThrowIOError( error ); + THROW_IO_ERROR( error ); } break; } @@ -1268,7 +1268,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) _( "Unsupported DRAWSEGMENT type %s" ), GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) ); - ThrowIOError( error ); + THROW_IO_ERROR( error ); } break; } @@ -1296,7 +1296,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) ) ); - ThrowIOError( error ); + THROW_IO_ERROR( error ); } break; } @@ -1449,16 +1449,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) if( module->GetReference() == wxEmptyString ) { - ThrowIOError( _( "Component with value of '%s' has empty reference id." ), - GetChars( module->GetValue() ) ); + THROW_IO_ERROR( wxString::Format( _( "Component with value of '%s' has empty reference id." ), + GetChars( module->GetValue() ) ) ); } // if we cannot insert OK, that means the reference has been seen before. STRINGSET_PAIR refpair = refs.insert( TO_UTF8( module->GetReference() ) ); if( !refpair.second ) // insert failed { - ThrowIOError( _( "Multiple components have identical reference IDs of '%s'." ), - GetChars( module->GetReference() ) ); + THROW_IO_ERROR( wxString::Format( _( "Multiple components have identical reference IDs of '%s'." ), + GetChars( module->GetReference() ) ) ); } } } @@ -2235,4 +2235,3 @@ void SPECCTRA_DB::RevertMODULEs( BOARD* aBoard ) } } // namespace DSN - diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index b8e2d86090..984ab4e33c 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -197,8 +197,8 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro if( layerNdx == -1 ) { wxString layerName = FROM_UTF8( aPath->layer_id.c_str() ); - ThrowIOError( _("Session file uses invalid layer id \"%s\""), - GetChars( layerName ) ); + THROW_IO_ERROR( wxString::Format( _("Session file uses invalid layer id \"%s\""), + GetChars( layerName ) ) ); } TRACK* track = new TRACK( sessionBoard ); @@ -250,15 +250,15 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro if( shapeCount == 0 ) { - ThrowIOError( _( "Session via padstack has no shapes" ) ); + THROW_IO_ERROR( _( "Session via padstack has no shapes" ) ); } else if( shapeCount == 1 ) { shape = (SHAPE*) (*aPadstack)[0]; DSN_T type = shape->shape->Type(); if( type != T_circle ) - ThrowIOError( _( "Unsupported via shape: %s"), - GetChars( GetTokenString( type ) ) ); + THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s"), + GetChars( GetTokenString( type ) ) ) ); CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); @@ -275,8 +275,8 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro shape = (SHAPE*) (*aPadstack)[0]; DSN_T type = shape->shape->Type(); if( type != T_circle ) - ThrowIOError( _( "Unsupported via shape: %s"), - GetChars( GetTokenString( type ) ) ); + THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s"), + GetChars( GetTokenString( type ) ) ) ); CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); @@ -300,8 +300,8 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro shape = (SHAPE*) (*aPadstack)[i]; DSN_T type = shape->shape->Type(); if( type != T_circle ) - ThrowIOError( _( "Unsupported via shape: %s"), - GetChars( GetTokenString( type ) ) ); + THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s"), + GetChars( GetTokenString( type ) ) ) ); CIRCLE* circle = (CIRCLE*) shape->shape; @@ -309,8 +309,8 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro if( layerNdx == -1 ) { wxString layerName = FROM_UTF8( circle->layer_id.c_str() ); - ThrowIOError( _("Session file uses invalid layer id \"%s\""), - GetChars( layerName ) ); + THROW_IO_ERROR( wxString::Format( _("Session file uses invalid layer id \"%s\""), + GetChars( layerName ) ) ); } if( layerNdx > topLayerNdx ) @@ -356,18 +356,18 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) sessionBoard = aBoard; // not owned here if( !session ) - ThrowIOError( _("Session file is missing the \"session\" section") ); + THROW_IO_ERROR( _("Session file is missing the \"session\" section") ); /* Dick 16-Jan-2012: session need not have a placement section. if( !session->placement ) - ThrowIOError( _("Session file is missing the \"placement\" section") ); + THROW_IO_ERROR( _("Session file is missing the \"placement\" section") ); */ if( !session->route ) - ThrowIOError( _("Session file is missing the \"routes\" section") ); + THROW_IO_ERROR( _("Session file is missing the \"routes\" section") ); if( !session->route->library ) - ThrowIOError( _("Session file is missing the \"library_out\" section") ); + THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") ); // delete all the old tracks and vias aBoard->m_Track.DeleteAll(); @@ -393,9 +393,8 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) MODULE* module = aBoard->FindModuleByReference( reference ); if( !module ) { - ThrowIOError( - _("Session file has 'reference' to non-existent component \"%s\""), - GetChars( reference ) ); + THROW_IO_ERROR( wxString::Format( _("Session file has 'reference' to non-existent component \"%s\""), + GetChars( reference ) ) ); } if( !place->hasVertex ) @@ -478,11 +477,10 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) 'wire'. wxString netId = FROM_UTF8( wire->net_id.c_str() ); - ThrowIOError( - _("Unsupported wire shape: \"%s\" for net: \"%s\""), - DLEX::GetTokenString(shape).GetData(), - netId.GetData() - ); + THROW_IO_ERROR( wxString::Format( _("Unsupported wire shape: \"%s\" for net: \"%s\""), + DLEX::GetTokenString(shape).GetData(), + netId.GetData() + ) ); */ } else @@ -542,8 +540,8 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) // wire_via to text and put that text into the exception. wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) ); - ThrowIOError( _("A wire_via references a missing padstack \"%s\""), - GetChars( psid ) ); + THROW_IO_ERROR( wxString::Format( _("A wire_via references a missing padstack \"%s\""), + GetChars( psid ) ) ); } NETCLASSPTR netclass = aBoard->GetDesignSettings().m_NetClasses.GetDefault(); @@ -561,4 +559,3 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) } // namespace DSN - From 843c9b99d52d1da0f20ab2c3c7267bb3f10db5bd Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 10 Dec 2015 16:29:12 +0100 Subject: [PATCH 06/14] Fixed ratsnest for PCBs imported using plugins (GAL). --- pcbnew/files.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 582ffd28ec..1567f2ceae 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -590,6 +591,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in { wxBusyCursor dummy; // Displays an Hourglass while building connectivity Compile_Ratsnest( NULL, true ); + GetBoard()->GetRatsnest()->ProcessBoard(); } SetMsgPanel( GetBoard() ); From 204f025ff48ab98fca05a736eb79c7c065ee023c Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Thu, 10 Dec 2015 11:35:43 -0500 Subject: [PATCH 07/14] Build configuration fixes. * Fix broken include path in FindGLM.cmake ( credit Cirilo Bernardo ). * Fix if()/endif() warning in FindGLM.cmake. * Remove trailing white space in FindGLM.cmake. * Fix bug introduced in r6363 that inadvertently made OpenMP a required dependency instead of an optional dependency. * Remove quiet flag for FindOpenMP to report findings. --- CMakeLists.txt | 9 ++++---- CMakeModules/FindGLM.cmake | 47 ++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f612687ea7..2a0c9de2dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -411,12 +411,11 @@ include( ExternalProject ) #================================================ include( CheckFindPackageResult ) -####################### -# Find OpenMP support # -####################### +################################# +# Find OpenMP support, optional # +################################# -find_package( OpenMP QUIET ) -check_find_package_result( OPENMP_FOUND "OpenMP" ) +find_package( OpenMP ) if( OPENMP_FOUND ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) diff --git a/CMakeModules/FindGLM.cmake b/CMakeModules/FindGLM.cmake index 6a289ae803..028f2b425f 100644 --- a/CMakeModules/FindGLM.cmake +++ b/CMakeModules/FindGLM.cmake @@ -1,35 +1,31 @@ -if( ${CMAKE_MAJOR_VERSION} STREQUAL "2" AND ${CMAKE_MINOR_VERSION} STREQUAL "8" - AND ( ${CMAKE_PATCH_VERSION} STREQUAL "2" OR ${CMAKE_PATCH_VERSION} STREQUAL "7" - OR ${CMAKE_PATCH_VERSION} STREQUAL "10" ) ) - - message( FATAL_ERROR "\nThis version of CMake is known to not work\n" - "Known bad versions: 2.8.2, 2.8.7, 2.8.10\n" ) - -endif() +find_path( GLM_INCLUDE_DIR glm/glm.hpp + PATHS ${GLM_ROOT_DIR} $ENV{GLM_ROOT_DIR} + DOC "GLM library header path." + ) +if( NOT ${GLM_INCLUDE_DIR} STREQUAL "GLM_INCLUDE_DIR-NOTFOUND" ) -find_path( GLM_INCLUDE_DIR glm.hpp PATH_SUFFIXES glm ) - - -if( NOT ${GLM_INCLUDE_DIR} STREQUAL "" ) - # attempt to extract the GLM Version information from setup.hpp - find_file( GLM_SETUP setup.hpp PATHS ${GLM_INCLUDE_DIR} PATH_SUFFIXES core detail NO_DEFAULT_PATH ) + find_file( GLM_SETUP setup.hpp + PATHS ${GLM_INCLUDE_DIR} + PATH_SUFFIXES glm/core glm/detail + NO_DEFAULT_PATH ) + + if( NOT ${GLM_SETUP} STREQUAL "GLM_SETUP-NOTFOUND" ) - if( GLM_SETUP ) # extract the "#define GLM_VERSION*" lines file( STRINGS ${GLM_SETUP} _version REGEX "^#define.*GLM_VERSION.*" ) - + foreach( SVAR ${_version} ) string( REGEX MATCH GLM_VERSION_[M,A,J,O,R,I,N,P,T,C,H,E,V,I,S]* _VARNAME ${SVAR} ) string( REGEX MATCH [0-9]+ _VALUE ${SVAR} ) - + if( NOT ${_VARNAME} STREQUAL "" AND NOT ${_VALUE} STREQUAL "" ) set( _${_VARNAME} ${_VALUE} ) endif() - + endforeach() - + #ensure that NOT GLM_VERSION* will evaluate to '0' if( NOT _GLM_VERSION_MAJOR ) set( _GLM_VERSION_MAJOR 0 ) @@ -49,18 +45,19 @@ if( NOT ${GLM_INCLUDE_DIR} STREQUAL "" ) set( GLM_VERSION ${_GLM_VERSION_MAJOR}.${_GLM_VERSION_MINOR}.${_GLM_VERSION_PATCH}.${_GLM_VERSION_REVISION} ) unset( GLM_SETUP CACHE ) - - endif( GLM_SETUP ) - -endif( NOT ${GLM_INCLUDE_DIR} STREQUAL "" ) + + endif() +endif() include( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( GLM - REQUIRED_VARS GLM_INCLUDE_DIR + REQUIRED_VARS + GLM_INCLUDE_DIR + GLM_VERSION VERSION_VAR GLM_VERSION ) - + mark_as_advanced( GLM_INCLUDE_DIR ) set( GLM_VERSION_MAJOR ${_GLM_VERSION_MAJOR} CACHE INTERNAL "" ) set( GLM_VERSION_MINOR ${_GLM_VERSION_MINOR} CACHE INTERNAL "" ) From c5e9bda936494a541194f059eee9c45255f60721 Mon Sep 17 00:00:00 2001 From: Cirilo Bernardo Date: Thu, 10 Dec 2015 14:20:35 -0500 Subject: [PATCH 08/14] Fix OpenGLM build errors for OSX homebrew developers. --- cvpcb/CMakeLists.txt | 1 + pcbnew/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 5a00f2c569..3a106825b5 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -16,6 +16,7 @@ include_directories( ../pcbnew/dialogs ../polygon ../common + ${GLM_INCLUDE_DIR} ${INC_AFTER} ) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 12490691be..ff99a93764 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -43,6 +43,7 @@ include_directories( ../lib_dxf ./import_dxf ../utils/idftools + ${GLM_INCLUDE_DIR} ${INC_AFTER} ) From c6d591b534a24c33af9d02632389145a09e3a184 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sat, 12 Dec 2015 12:06:24 -0500 Subject: [PATCH 09/14] Eeschema: uncouple clearing annotation from SCH_SHEET_PATH. * Add code to SCH_SHEET object to clear annotation. * Change SCH_COMPONENT::GetPath() to derive path from SCH_SHEET object instead of SCH_SHEET_PATH object. * Remove clear annotation code from SCH_SCREENS object. --- eeschema/annotate.cpp | 11 ++++---- eeschema/class_sch_screen.h | 14 +++------- .../netlist_exporter_orcadpcb2.cpp | 2 +- eeschema/sch_component.cpp | 28 +++++++++---------- eeschema/sch_component.h | 10 +++---- eeschema/sch_screen.cpp | 11 ++------ eeschema/sch_sheet.cpp | 19 +++++++++++++ eeschema/sch_sheet.h | 2 ++ 8 files changed, 52 insertions(+), 45 deletions(-) diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 1b2a27d232..d0bae72a91 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -6,7 +6,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2015 KiCad Developers, see change_log.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 @@ -35,19 +35,18 @@ #include #include +#include + void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly ) { if( aCurrentSheetOnly ) { - SCH_SCREEN* screen = GetScreen(); - wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) ); - screen->ClearAnnotation( m_CurrentSheet ); + m_CurrentSheet->Last()->ClearAnnotation(); } else { - SCH_SCREENS ScreenList; - ScreenList.ClearAnnotation(); + m_CurrentSheet->Last()->GetRootSheet()->ClearAnnotation( true ); } // Update the references for the sheet that is currently being displayed. diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h index 67c6451b1c..a13249098e 100644 --- a/eeschema/class_sch_screen.h +++ b/eeschema/class_sch_screen.h @@ -425,11 +425,11 @@ public: /** * Function ClearAnnotation - * clears the annotation for the components in \a aSheetPath on the screen. - * @param aSheetPath The sheet path of the component annotation to clear. If NULL then - * the entire hierarchy is cleared. + * clears the annotation for the components in \a aSheet on the screen. + * @param aSheet The sheet of the component annotation to clear. If NULL then + * the entire hierarchy is cleared for this screen. */ - void ClearAnnotation( SCH_SHEET_PATH* aSheetPath ); + void ClearAnnotation( SCH_SHEET* aSheet ); /** * Function GetHierarchicalItems @@ -549,12 +549,6 @@ public: SCH_SCREEN* GetNext(); SCH_SCREEN* GetScreen( unsigned int aIndex ) const; - /** - * Function ClearAnnotation - * clears the annotation for all components in the hierarchy. - */ - void ClearAnnotation(); - /** * Function SchematicCleanUp * merges and breaks wire segments in the entire schematic hierarchy. diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp index 0aeaccc3d0..b0c8f6a286 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp @@ -102,7 +102,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, uns field = comp->GetRef( path ); ret |= fprintf( f, " ( %s %s", - TO_UTF8( comp->GetPath( path ) ), + TO_UTF8( comp->GetPath( path->Last() ) ), TO_UTF8( footprint ) ); ret |= fprintf( f, " %s", TO_UTF8( field ) ); diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 82694d8083..a8aac34e81 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -429,21 +429,21 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath, } -wxString SCH_COMPONENT::GetPath( const SCH_SHEET_PATH* sheet ) const +wxString SCH_COMPONENT::GetPath( const SCH_SHEET* aSheet ) const { - wxCHECK_MSG( sheet != NULL, wxEmptyString, + wxCHECK_MSG( aSheet != NULL, wxEmptyString, wxT( "Cannot get component path with invalid sheet object." ) ); wxString str; str.Printf( wxT( "%8.8lX" ), (long unsigned) m_TimeStamp ); - return sheet->Path() + str; + return aSheet->GetPath() + str; } const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet ) { - wxString path = GetPath( sheet ); + wxString path = GetPath( sheet->Last() ); wxString h_path, h_ref; wxStringTokenizer tokenizer; wxString separators( wxT( " " ) ); @@ -505,7 +505,7 @@ bool SCH_COMPONENT::IsReferenceStringValid( const wxString& aReferenceString ) void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref ) { - wxString path = GetPath( sheet ); + wxString path = GetPath( sheet->Last() ); bool notInArray = true; @@ -583,7 +583,7 @@ void SCH_COMPONENT::SetTimeStamp( time_t aNewTimeStamp ) int SCH_COMPONENT::GetUnitSelection( SCH_SHEET_PATH* aSheet ) { - wxString path = GetPath( aSheet ); + wxString path = GetPath( aSheet->Last() ); wxString h_path, h_multi; wxStringTokenizer tokenizer; wxString separators( wxT( " " ) ); @@ -611,7 +611,7 @@ int SCH_COMPONENT::GetUnitSelection( SCH_SHEET_PATH* aSheet ) void SCH_COMPONENT::SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection ) { - wxString path = GetPath( aSheet ); + wxString path = GetPath( aSheet->Last() ); bool notInArray = true; @@ -727,7 +727,7 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) } -void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) +void SCH_COMPONENT::ClearAnnotation( SCH_SHEET* aSheet ) { bool keepMulti = false; wxArrayString reference_fields; @@ -750,7 +750,7 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) } else { // This is a malformed reference: reinit this reference - m_prefix = defRef = wxT("U"); // Set to default ref prefix + m_prefix = defRef = wxT( "U" ); // Set to default ref prefix } defRef.Append( wxT( "?" ) ); @@ -759,22 +759,22 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) // For components with units locked, // we cannot remove all annotations: part selection must be kept - // For all components: if aSheetPath is not NULL, + // For all components: if aSheet is not NULL, // remove annotation only for the given path - if( keepMulti || aSheetPath ) + if( keepMulti || aSheet ) { wxString NewHref; wxString path; - if( aSheetPath ) - path = GetPath( aSheetPath ); + if( aSheet ) + path = GetPath( aSheet ); for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ ) { // Break hierarchical reference in path, ref and multi selection: reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators ); - if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 ) + if( aSheet == NULL || reference_fields[0].Cmp( path ) == 0 ) { if( keepMulti ) // Get and keep part selection multi = reference_fields[2]; diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 8984fc40e6..97cf97023a 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -240,10 +240,10 @@ public: /** * Function ClearAnnotation * clears exiting component annotation ( i.i IC23 changed to IC? and part reset to 1) - * @param aSheetPath: SCH_SHEET_PATH value: if NULL remove all annotations, - * else remove annotation relative to this sheetpath + * @param aSheet: SCH_SHEET value: if NULL remove all annotations, + * else remove annotation relative to \a aSheet. */ - void ClearAnnotation( SCH_SHEET_PATH* aSheetPath ); + void ClearAnnotation( SCH_SHEET* aSheet ); /** * Function SetTimeStamp @@ -329,8 +329,8 @@ public: void SwapData( SCH_ITEM* aItem ); - // returns a unique ID, in the form of a path. - wxString GetPath( const SCH_SHEET_PATH* sheet ) const; + // returns a unique ID, in the form of a path determined by \a aSheet. + wxString GetPath( const SCH_SHEET* sheet ) const; /** * Function IsReferenceStringValid (static) diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index c2f8201979..95f9d94010 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -755,7 +755,7 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) } -void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) +void SCH_SCREEN::ClearAnnotation( SCH_SHEET* aSheet ) { for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { @@ -763,7 +763,7 @@ void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) { SCH_COMPONENT* component = (SCH_COMPONENT*) item; - component->ClearAnnotation( aSheetPath ); + component->ClearAnnotation( aSheet ); // Clear the modified component flag set by component->ClearAnnotation // because we do not use it here and we should not leave this flag set, @@ -1431,13 +1431,6 @@ void SCH_SCREENS::BuildScreenList( EDA_ITEM* aItem ) } -void SCH_SCREENS::ClearAnnotation() -{ - for( size_t i = 0; i < m_screens.size(); i++ ) - m_screens[i]->ClearAnnotation( NULL ); -} - - void SCH_SCREENS::SchematicCleanUp() { for( size_t i = 0; i < m_screens.size(); i++ ) diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 6fb54e2a0d..c3c4b97f6a 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -1214,6 +1214,25 @@ wxString SCH_SHEET::GetHumanReadablePath() const } +void SCH_SHEET::ClearAnnotation( bool aIncludeSubSheets ) +{ + m_screen->ClearAnnotation( this ); + + if( aIncludeSubSheets ) + { + SCH_ITEM* item = m_screen->GetDrawItems(); + + while( item ) + { + if( item->Type() == SCH_SHEET_T ) + static_cast( item )->ClearAnnotation( aIncludeSubSheets ); + + item = item->Next(); + } + } +} + + SCH_ITEM& SCH_SHEET::operator=( const SCH_ITEM& aItem ) { wxLogDebug( wxT( "Sheet assignment operator." ) ); diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index e5fe0bd429..ce9f36422a 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -633,6 +633,8 @@ public: */ wxString GetHumanReadablePath() const; + void ClearAnnotation( bool aIncludeSubSheets = false ); + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const; // override #endif From 7dbefa29ac43c72a936fa8ba0f7889596bbfdc64 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 12 Dec 2015 19:32:18 +0100 Subject: [PATCH 10/14] Minor fix: Remove a duplicate title in eeschema dialog plot. --- .../dialogs/dialog_plot_schematic_base.cpp | 28 +++---- .../dialogs/dialog_plot_schematic_base.fbp | 83 ------------------- eeschema/dialogs/dialog_plot_schematic_base.h | 3 +- 3 files changed, 13 insertions(+), 101 deletions(-) diff --git a/eeschema/dialogs/dialog_plot_schematic_base.cpp b/eeschema/dialogs/dialog_plot_schematic_base.cpp index ca6467dd69..fb2d510945 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 6 2014) +// C++ code generated with wxFormBuilder (version Jun 17 2015) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -49,33 +49,33 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind wxString m_PaperSizeOptionChoices[] = { _("Schematic size"), _("Force size A4"), _("Force size A") }; int m_PaperSizeOptionNChoices = sizeof( m_PaperSizeOptionChoices ) / sizeof( wxString ); - m_PaperSizeOption = new wxRadioBox( this, wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, m_PaperSizeOptionNChoices, m_PaperSizeOptionChoices, 1, wxRA_SPECIFY_COLS ); + m_PaperSizeOption = new wxRadioBox( m_paperOptionsSizer->GetStaticBox(), wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, m_PaperSizeOptionNChoices, m_PaperSizeOptionChoices, 1, wxRA_SPECIFY_COLS ); m_PaperSizeOption->SetSelection( 1 ); m_paperOptionsSizer->Add( m_PaperSizeOption, 0, wxALL|wxEXPAND, 5 ); - m_paperHPGLSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("HPGL Options") ), wxVERTICAL ); + m_paperHPGLSizer = new wxStaticBoxSizer( new wxStaticBox( m_paperOptionsSizer->GetStaticBox(), wxID_ANY, _("HPGL Options") ), wxVERTICAL ); - m_staticText4 = new wxStaticText( this, wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText4 = new wxStaticText( m_paperHPGLSizer->GetStaticBox(), wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText4->Wrap( -1 ); m_paperHPGLSizer->Add( m_staticText4, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); wxString m_HPGLPaperSizeOptionChoices[] = { _("Schematic size"), _("Page size A4"), _("Page size A3"), _("Page size A2"), _("Page size A1"), _("Page size A0"), _("Page size A"), _("Page size B"), _("Page size C"), _("Page size D"), _("Page size E") }; int m_HPGLPaperSizeOptionNChoices = sizeof( m_HPGLPaperSizeOptionChoices ) / sizeof( wxString ); - m_HPGLPaperSizeOption = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_HPGLPaperSizeOptionNChoices, m_HPGLPaperSizeOptionChoices, 0 ); + m_HPGLPaperSizeOption = new wxChoice( m_paperHPGLSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_HPGLPaperSizeOptionNChoices, m_HPGLPaperSizeOptionChoices, 0 ); m_HPGLPaperSizeOption->SetSelection( 0 ); m_paperHPGLSizer->Add( m_HPGLPaperSizeOption, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); wxString m_plotOriginOptChoices[] = { _("Bottom left corner"), _("Center of the page") }; int m_plotOriginOptNChoices = sizeof( m_plotOriginOptChoices ) / sizeof( wxString ); - m_plotOriginOpt = new wxRadioBox( this, wxID_ANY, _("Origin"), wxDefaultPosition, wxDefaultSize, m_plotOriginOptNChoices, m_plotOriginOptChoices, 1, wxRA_SPECIFY_COLS ); + m_plotOriginOpt = new wxRadioBox( m_paperHPGLSizer->GetStaticBox(), wxID_ANY, _("Origin"), wxDefaultPosition, wxDefaultSize, m_plotOriginOptNChoices, m_plotOriginOptChoices, 1, wxRA_SPECIFY_COLS ); m_plotOriginOpt->SetSelection( 0 ); m_paperHPGLSizer->Add( m_plotOriginOpt, 0, wxALL, 5 ); - m_penHPLGWidthTitle = new wxStaticText( this, wxID_ANY, _("Pen width"), wxDefaultPosition, wxDefaultSize, 0 ); + m_penHPLGWidthTitle = new wxStaticText( m_paperHPGLSizer->GetStaticBox(), wxID_ANY, _("Pen width"), wxDefaultPosition, wxDefaultSize, 0 ); m_penHPLGWidthTitle->Wrap( -1 ); m_paperHPGLSizer->Add( m_penHPLGWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - m_penHPGLWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_penHPGLWidthCtrl = new wxTextCtrl( m_paperHPGLSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_penHPGLWidthCtrl->SetMaxLength( 0 ); m_paperHPGLSizer->Add( m_penHPGLWidthCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); @@ -94,11 +94,11 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind wxStaticBoxSizer* sbSizerPlotFormat; sbSizerPlotFormat = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("General Options") ), wxVERTICAL ); - m_defaultLineWidthTitle = new wxStaticText( this, wxID_ANY, _("Default line thickness"), wxDefaultPosition, wxDefaultSize, 0 ); + m_defaultLineWidthTitle = new wxStaticText( sbSizerPlotFormat->GetStaticBox(), wxID_ANY, _("Default line thickness"), wxDefaultPosition, wxDefaultSize, 0 ); m_defaultLineWidthTitle->Wrap( -1 ); sbSizerPlotFormat->Add( m_defaultLineWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - m_DefaultLineSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_DefaultLineSizeCtrl = new wxTextCtrl( sbSizerPlotFormat->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_DefaultLineSizeCtrl->SetMaxLength( 0 ); m_DefaultLineSizeCtrl->SetToolTip( _("Selection of the default pen thickness used to draw items, when their thickness is set to 0.") ); @@ -106,13 +106,13 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") }; int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString ); - m_ModeColorOption = new wxRadioBox( this, wxID_ANY, _("Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS ); + m_ModeColorOption = new wxRadioBox( sbSizerPlotFormat->GetStaticBox(), wxID_ANY, _("Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS ); m_ModeColorOption->SetSelection( 1 ); m_ModeColorOption->SetToolTip( _("Choose if you want to draw the sheet like it appears on screen,\nor in black and white mode, better to print it when using black and white printers") ); sbSizerPlotFormat->Add( m_ModeColorOption, 0, wxALL|wxEXPAND, 5 ); - m_PlotFrameRefOpt = new wxCheckBox( this, wxID_ANY, _("Plot border and title block"), wxDefaultPosition, wxDefaultSize, 0 ); + m_PlotFrameRefOpt = new wxCheckBox( sbSizerPlotFormat->GetStaticBox(), wxID_ANY, _("Plot border and title block"), wxDefaultPosition, wxDefaultSize, 0 ); m_PlotFrameRefOpt->SetValue(true); m_PlotFrameRefOpt->SetToolTip( _("Print (or not) the Frame references.") ); @@ -143,10 +143,6 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind wxBoxSizer* bSizer4; bSizer4 = new wxBoxSizer( wxVERTICAL ); - m_staticText2 = new wxStaticText( this, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText2->Wrap( -1 ); - bSizer4->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - m_MessagesBox = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_MessagesBox->SetMinSize( wxSize( 300,150 ) ); diff --git a/eeschema/dialogs/dialog_plot_schematic_base.fbp b/eeschema/dialogs/dialog_plot_schematic_base.fbp index 0018cb26cb..8777457ad6 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.fbp +++ b/eeschema/dialogs/dialog_plot_schematic_base.fbp @@ -1681,89 +1681,6 @@ bSizer4 wxVERTICAL none - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Messages: - - 0 - - - 0 - - 1 - m_staticText2 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - 5 wxEXPAND | wxALL diff --git a/eeschema/dialogs/dialog_plot_schematic_base.h b/eeschema/dialogs/dialog_plot_schematic_base.h index b983cca9ef..f5a406bfd0 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.h +++ b/eeschema/dialogs/dialog_plot_schematic_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 6 2014) +// C++ code generated with wxFormBuilder (version Jun 17 2015) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -68,7 +68,6 @@ class DIALOG_PLOT_SCHEMATIC_BASE : public DIALOG_SHIM wxButton* m_buttonPlotCurrent; wxButton* m_buttonPlotAll; wxButton* m_buttonQuit; - wxStaticText* m_staticText2; WX_HTML_REPORT_PANEL* m_MessagesBox; // Virtual event handlers, overide them in your derived class From 7cbf8a0bdab98d8b34e86ef38112f2cdc5ebf1c9 Mon Sep 17 00:00:00 2001 From: Simon Richter Date: Sat, 12 Dec 2015 14:56:55 -0500 Subject: [PATCH 11/14] CMake: remove older GCC optimization settings since boost::polygon is no longer used. --- CMakeLists.txt | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a0c9de2dd..660711eac3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,21 +159,6 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) set( CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}" ) - # The optimization level is -O1 instead of the usual -O2 level because - # boost::polygon has a function (inflate polygon) broken by the -O2 level - # with GCC 4.7.0 to 4.7.2 (works fine with with GCC 4.6 and 4.7.3). - # This lower optimization level does not have a significant change on the speed. - # See also: - # https://bugs.launchpad.net/kicad/+bug/1056926 - # https://svn.boost.org/trac/boost/ticket/7983 - if( GCC_VERSION VERSION_EQUAL 4.7.0 OR ( GCC_VERSION VERSION_GREATER 4.7.0 AND GCC_VERSION VERSION_LESS 4.7.3 ) ) - set( CMAKE_C_FLAGS_RELEASE "-O1" ) - set( CMAKE_CXX_FLAGS_RELEASE "-O1" ) - else() - set( CMAKE_C_FLAGS_RELEASE "-O2" ) - set( CMAKE_CXX_FLAGS_RELEASE "-O2" ) - endif() - set( CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG" ) set( CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG -Wno-deprecated-declarations" ) From 50c418a33227acb6a091c01527d017cefc5c16ee Mon Sep 17 00:00:00 2001 From: Chris Pavlina Date: Sun, 13 Dec 2015 11:56:47 -0500 Subject: [PATCH 12/14] Eeschema: add field automatic placement feature. --- bitmaps_png/CMakeLists.txt | 1 + bitmaps_png/cpp_26/autoplace_fields.cpp | 79 +++ bitmaps_png/sources/autoplace_fields.svg | 307 +++++++++ eeschema/CMakeLists.txt | 1 + eeschema/autoplace_fields.cpp | 648 ++++++++++++++++++ eeschema/class_libentry.cpp | 2 +- .../dialog_edit_component_in_schematic.cpp | 3 + eeschema/dialogs/dialog_edit_one_field.cpp | 13 + eeschema/dialogs/dialog_eeschema_options.h | 36 + .../dialogs/dialog_eeschema_options_base.cpp | 9 + .../dialogs/dialog_eeschema_options_base.fbp | 266 ++++++- .../dialogs/dialog_eeschema_options_base.h | 3 + eeschema/edit_component_in_schematic.cpp | 4 + eeschema/eeschema_config.cpp | 15 + eeschema/eeschema_config.h | 4 + eeschema/eeschema_id.h | 2 + eeschema/getpart.cpp | 32 +- eeschema/hotkeys.cpp | 6 + eeschema/hotkeys.h | 1 + eeschema/lib_pin.cpp | 4 +- eeschema/lib_pin.h | 10 +- eeschema/onrightclick.cpp | 3 + eeschema/sch_component.cpp | 22 + eeschema/sch_component.h | 72 +- eeschema/sch_field.cpp | 17 + eeschema/sch_field.h | 9 +- eeschema/schedit.cpp | 61 +- eeschema/schframe.cpp | 4 + eeschema/schframe.h | 10 + include/bitmaps.h | 1 + include/class_eda_rect.h | 1 + 31 files changed, 1596 insertions(+), 50 deletions(-) create mode 100644 bitmaps_png/cpp_26/autoplace_fields.cpp create mode 100644 bitmaps_png/sources/autoplace_fields.svg create mode 100644 eeschema/autoplace_fields.cpp diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt index 706758550b..1053e13ea3 100644 --- a/bitmaps_png/CMakeLists.txt +++ b/bitmaps_png/CMakeLists.txt @@ -160,6 +160,7 @@ set( BMAPS_MID auto_associe auto_delete_track auto_track_width + autoplace_fields axis3d_back axis3d_bottom axis3d_front diff --git a/bitmaps_png/cpp_26/autoplace_fields.cpp b/bitmaps_png/cpp_26/autoplace_fields.cpp new file mode 100644 index 0000000000..dda674b73f --- /dev/null +++ b/bitmaps_png/cpp_26/autoplace_fields.cpp @@ -0,0 +1,79 @@ + +/* Do not modify this file, it was automatically generated by the + * PNG2cpp CMake script, using a *.png file as input. + */ + +#include + +static const unsigned char png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, + 0xce, 0x00, 0x00, 0x03, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x95, 0x5b, 0x4c, 0x1c, + 0x55, 0x18, 0xc7, 0x17, 0x86, 0x65, 0x59, 0x96, 0xe5, 0xb6, 0x96, 0x94, 0x70, 0x09, 0x5a, 0x1e, + 0xec, 0x83, 0x24, 0x0a, 0x18, 0xa5, 0xd4, 0x27, 0x6d, 0xc0, 0x5b, 0x63, 0x43, 0x13, 0x1a, 0x23, + 0xd1, 0x90, 0xa6, 0x11, 0x1e, 0x2a, 0x0f, 0x5a, 0x48, 0x37, 0xb0, 0x4b, 0x40, 0x36, 0x43, 0x9b, + 0x46, 0xc1, 0xe0, 0x72, 0xe9, 0x83, 0xc5, 0x18, 0x78, 0x30, 0x36, 0x28, 0x89, 0xed, 0x43, 0xfb, + 0xd2, 0x9a, 0x1a, 0x74, 0x37, 0x69, 0x6d, 0x61, 0x4b, 0x69, 0xa1, 0x5c, 0xbb, 0x4b, 0x8a, 0x54, + 0xd7, 0x86, 0x86, 0xfe, 0xfd, 0x9f, 0x99, 0xb3, 0x66, 0x84, 0x96, 0xd4, 0xb8, 0x7b, 0x92, 0x5f, + 0x32, 0x33, 0x67, 0xe6, 0xfc, 0xce, 0xf9, 0xbe, 0xef, 0x9c, 0x31, 0x99, 0xfe, 0x7b, 0xeb, 0x24, + 0x35, 0xc4, 0x4e, 0x86, 0xc9, 0x0b, 0xe4, 0x25, 0x79, 0x2d, 0x70, 0x93, 0x78, 0x53, 0x14, 0x9a, + 0x9f, 0x1c, 0x27, 0x0e, 0x02, 0xf2, 0x26, 0x29, 0x26, 0x5e, 0xc9, 0x6f, 0xa4, 0x2b, 0x56, 0xa2, + 0x44, 0x92, 0x21, 0x19, 0x20, 0x17, 0x63, 0x25, 0xda, 0x2f, 0xaf, 0x05, 0x2b, 0x64, 0x57, 0x34, + 0x44, 0x2d, 0x64, 0x51, 0x0a, 0xa7, 0x48, 0x8e, 0x41, 0xb4, 0x4b, 0xde, 0x47, 0xad, 0x7d, 0x40, + 0x3a, 0x0c, 0x83, 0x3e, 0x47, 0x3c, 0xc4, 0xfc, 0x24, 0x1f, 0xd7, 0x3f, 0xe6, 0xc5, 0x83, 0x86, + 0x44, 0x3b, 0x49, 0x25, 0x69, 0x95, 0x7d, 0x75, 0x52, 0x9a, 0x46, 0xbe, 0x94, 0xef, 0x08, 0xe9, + 0xeb, 0x86, 0x6f, 0xde, 0xdb, 0x38, 0x60, 0xd0, 0x6c, 0x36, 0x07, 0x12, 0x12, 0x12, 0x36, 0xc6, + 0xf7, 0x23, 0x59, 0xb6, 0x33, 0xe4, 0x27, 0xe2, 0x22, 0xb3, 0xb2, 0xef, 0x47, 0xd9, 0xd7, 0x5c, + 0x58, 0x58, 0x88, 0x92, 0x92, 0x12, 0x11, 0xbe, 0x33, 0x64, 0x9f, 0x7c, 0x3e, 0x46, 0xd6, 0x37, + 0x89, 0x28, 0x41, 0x5c, 0x5c, 0x1c, 0xd2, 0xd3, 0xd3, 0xbf, 0xe7, 0x7d, 0xa6, 0xa1, 0x6f, 0x9b, + 0x4c, 0xf2, 0xbb, 0x52, 0xf4, 0x17, 0xf9, 0x8e, 0x2c, 0xc9, 0x01, 0x4f, 0xcd, 0xce, 0xce, 0x62, + 0x6d, 0x6d, 0x0d, 0x79, 0x79, 0x79, 0x01, 0xf9, 0x8d, 0x42, 0xbe, 0x26, 0x67, 0x37, 0x89, 0xda, + 0xda, 0xda, 0x71, 0xe2, 0xc4, 0x67, 0xb0, 0xdb, 0xed, 0x48, 0x4a, 0x4a, 0xfa, 0x33, 0x39, 0x39, + 0xf9, 0xa0, 0xec, 0xeb, 0x26, 0x3e, 0xb9, 0x11, 0x45, 0xe8, 0x3e, 0x97, 0x4c, 0x4b, 0xd1, 0x57, + 0xe3, 0xe3, 0xe3, 0x58, 0x5d, 0x5d, 0x45, 0x76, 0x76, 0xf6, 0x04, 0xef, 0x2d, 0x64, 0x88, 0x7c, + 0x4b, 0x92, 0x36, 0x89, 0x3c, 0x1e, 0x15, 0xf7, 0xef, 0x03, 0x93, 0x93, 0x73, 0x38, 0x70, 0xa0, + 0x46, 0x5b, 0x1d, 0xa5, 0xa2, 0xba, 0x1e, 0x90, 0x57, 0x1f, 0x91, 0xbf, 0x48, 0xe8, 0x3e, 0x76, + 0x38, 0x1c, 0xc8, 0xcd, 0xcd, 0x15, 0xa1, 0x3b, 0x25, 0xee, 0xc9, 0x43, 0xf2, 0x2b, 0xf9, 0x39, + 0xf2, 0xf2, 0x4e, 0x72, 0x8c, 0x84, 0x3a, 0x3a, 0x54, 0x84, 0xc3, 0xe0, 0xcc, 0x80, 0xbb, 0x77, + 0x81, 0xd3, 0xa7, 0xcf, 0xa3, 0xa0, 0x60, 0x07, 0xe2, 0xe3, 0xe3, 0xd7, 0x53, 0x53, 0x53, 0x5b, + 0x65, 0x38, 0x8c, 0x4d, 0x94, 0xf5, 0xdb, 0xc4, 0x4a, 0x3e, 0x21, 0x47, 0x48, 0x3e, 0x79, 0x59, + 0x5e, 0x1f, 0x91, 0xcf, 0xf9, 0x34, 0x3f, 0xff, 0x35, 0x9b, 0xcd, 0xe6, 0x57, 0x14, 0xe5, 0xf7, + 0xf6, 0x76, 0x15, 0xf7, 0xee, 0xe9, 0x92, 0x50, 0x08, 0x58, 0x5a, 0x02, 0xa6, 0xa7, 0x1f, 0xc0, + 0xe3, 0xf1, 0x22, 0x23, 0xc3, 0x01, 0xca, 0x66, 0x58, 0x30, 0x25, 0x52, 0x62, 0x95, 0xe7, 0xdc, + 0x33, 0x4f, 0xb4, 0x21, 0x7a, 0x7b, 0x7b, 0x2b, 0xfb, 0xfa, 0xfa, 0x90, 0x92, 0x92, 0x82, 0xb6, + 0x36, 0x15, 0x2b, 0x2b, 0xc0, 0xf2, 0xb2, 0x2e, 0x99, 0x9f, 0x07, 0x6e, 0xdf, 0x06, 0x6e, 0xde, + 0x04, 0xc6, 0xc6, 0x42, 0xa8, 0xa9, 0x39, 0x0c, 0x16, 0xcc, 0x43, 0x4e, 0xec, 0x07, 0x7e, 0x3a, + 0x6f, 0x38, 0x0d, 0xbe, 0x79, 0xc4, 0x6a, 0xff, 0xdd, 0x86, 0x87, 0x87, 0x95, 0xc1, 0xc1, 0xc1, + 0x54, 0xe6, 0x23, 0xd4, 0xda, 0xaa, 0x6a, 0x92, 0x3b, 0x77, 0x80, 0x85, 0x05, 0x5d, 0x72, 0xeb, + 0x16, 0x70, 0xe3, 0x06, 0x30, 0x31, 0x01, 0x5c, 0xbd, 0x0a, 0x0c, 0x0d, 0x8d, 0xc1, 0x66, 0xb3, + 0x63, 0xf7, 0xee, 0x57, 0xe0, 0xf7, 0x4f, 0xe3, 0xe4, 0xc9, 0x51, 0x28, 0x4a, 0x02, 0x4a, 0x4b, + 0x4b, 0x7d, 0x69, 0x69, 0x69, 0x55, 0xf2, 0x48, 0x7a, 0x6a, 0x2b, 0x67, 0xd0, 0xed, 0x56, 0x11, + 0x0c, 0xea, 0x12, 0x56, 0x2b, 0xc3, 0xa6, 0x4b, 0x02, 0x01, 0xe0, 0xda, 0x35, 0xe0, 0xf2, 0x65, + 0x70, 0x70, 0x20, 0x33, 0x33, 0x0b, 0x4e, 0xe7, 0xa7, 0x98, 0x9a, 0x02, 0x7c, 0x3e, 0x70, 0x3b, + 0x6c, 0x83, 0x61, 0x75, 0x82, 0x3d, 0x5b, 0x8a, 0x5a, 0x5a, 0x54, 0x2c, 0x2e, 0x02, 0x73, 0x73, + 0xba, 0x44, 0x0c, 0x74, 0xfd, 0xba, 0x2e, 0xb9, 0x72, 0x05, 0xb8, 0x74, 0x29, 0x8c, 0x43, 0x87, + 0x5c, 0x2c, 0x0e, 0x05, 0x59, 0x59, 0xd9, 0x68, 0x6a, 0xfa, 0x02, 0x7b, 0xf7, 0x7e, 0xa8, 0x55, + 0x67, 0x63, 0x63, 0x23, 0x98, 0x86, 0x30, 0x81, 0x48, 0x05, 0x19, 0xdc, 0x28, 0x10, 0xb1, 0x4d, + 0x11, 0xa2, 0xe6, 0x66, 0x55, 0x93, 0xcc, 0xcc, 0xe8, 0x79, 0x11, 0x12, 0x6e, 0x0f, 0x4d, 0xd2, + 0xd5, 0x35, 0x82, 0x9c, 0x9c, 0xa7, 0x29, 0xc8, 0x42, 0x7d, 0x7d, 0x3d, 0xca, 0xca, 0xca, 0xc4, + 0xc6, 0xe6, 0xb3, 0x1c, 0xd4, 0xd6, 0xd6, 0x6a, 0x83, 0xf7, 0xf7, 0xf7, 0x5f, 0x24, 0x6f, 0x49, + 0x9e, 0xdf, 0x28, 0x7a, 0x43, 0x2e, 0x77, 0xd9, 0xe9, 0x54, 0xff, 0x91, 0x4c, 0x4e, 0xea, 0x92, + 0xd1, 0xd1, 0x00, 0xca, 0xcb, 0x2b, 0x99, 0x07, 0x05, 0x15, 0x15, 0x15, 0xe8, 0xe9, 0xe9, 0x89, + 0xcc, 0xf8, 0x02, 0x39, 0x27, 0xaf, 0x05, 0x53, 0x64, 0xe7, 0x63, 0xe3, 0xd5, 0xd0, 0xd0, 0xb0, + 0xa7, 0xae, 0xae, 0xce, 0x67, 0xb5, 0x5a, 0xd7, 0x8e, 0x1e, 0x55, 0xb5, 0xe4, 0x0b, 0x89, 0xdf, + 0xff, 0x07, 0x67, 0xee, 0x42, 0x62, 0xa2, 0x05, 0xe2, 0x1c, 0x73, 0xbb, 0xdd, 0x91, 0x01, 0x57, + 0x18, 0x9e, 0xc3, 0x2e, 0x97, 0x4b, 0xfb, 0x5d, 0x7b, 0xbd, 0xde, 0x1d, 0x62, 0xf6, 0x2c, 0xaa, + 0xc4, 0x2d, 0xab, 0x4e, 0xcc, 0x82, 0x2f, 0x1e, 0xb7, 0x58, 0x2c, 0xe1, 0xa6, 0x26, 0x55, 0x4b, + 0xbe, 0xd7, 0x3b, 0x82, 0xed, 0xdb, 0xf3, 0xc0, 0x23, 0x08, 0xd5, 0xd5, 0xd5, 0x30, 0xc4, 0x7d, + 0x84, 0xe4, 0xfe, 0xdf, 0x7f, 0x4c, 0xb0, 0xaa, 0xea, 0x7d, 0x14, 0x17, 0x97, 0x6b, 0x95, 0x53, + 0x54, 0x54, 0x84, 0xce, 0xce, 0xce, 0x88, 0x60, 0x8e, 0xec, 0x8b, 0xd6, 0xcf, 0x2c, 0x28, 0x04, + 0x22, 0xc1, 0x0c, 0x65, 0x44, 0xb0, 0x4e, 0xbc, 0x03, 0x03, 0x03, 0xf6, 0x68, 0xfe, 0x35, 0x17, + 0xb8, 0x8a, 0x5f, 0xba, 0xbb, 0xbb, 0x35, 0x09, 0xc3, 0xe5, 0x67, 0x48, 0x5f, 0x34, 0xc5, 0xa0, + 0x3d, 0x4b, 0xc1, 0x31, 0x12, 0x26, 0x2e, 0x26, 0xd9, 0x6c, 0x8a, 0x55, 0xe3, 0x2a, 0xde, 0x61, + 0xf9, 0x16, 0xc4, 0x62, 0xec, 0xbf, 0x01, 0x96, 0xa8, 0x5c, 0xe1, 0x12, 0x7e, 0x2a, 0x61, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +const BITMAP_OPAQUE autoplace_fields_xpm[1] = {{ png, sizeof( png ), "autoplace_fields_xpm" }}; + +//EOF diff --git a/bitmaps_png/sources/autoplace_fields.svg b/bitmaps_png/sources/autoplace_fields.svg new file mode 100644 index 0000000000..a7f6728445 --- /dev/null +++ b/bitmaps_png/sources/autoplace_fields.svg @@ -0,0 +1,307 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 462cd276ee..3079318e97 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -73,6 +73,7 @@ set( EESCHEMA_DLGS ) set( EESCHEMA_SRCS + autoplace_fields.cpp annotate.cpp backanno.cpp block.cpp diff --git a/eeschema/autoplace_fields.cpp b/eeschema/autoplace_fields.cpp new file mode 100644 index 0000000000..001127ab2e --- /dev/null +++ b/eeschema/autoplace_fields.cpp @@ -0,0 +1,648 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Chris Pavlina + * Copyright (C) 2015 KiCad Developers, see change_log.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 Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/****************************************************************************** + * Field autoplacer: Tries to find an optimal place for component fields, and + * places them there. There are two modes: "auto"-autoplace, and "manual" autoplace. + * Auto mode is for when the process is run automatically, like when rotating parts, + * and it avoids doing things that would be helpful for the final positioning but + * annoying if they happened without permission. + * Short description of the process: + * + * 1. Compute the dimensions of the fields' bounding box ::ComputeFBoxSize + * 2. Determine which side the fields will go on. ::choose_side_for_fields + * 1. Sort the four sides in preference order, + * depending on the component's shape and + * orientation ::get_preferred_sides + * 2. If in manual mode, sift out the sides that would + * cause fields to overlap other items ::get_colliding_sides + * 3. If any remaining sides have zero pins there, + * choose the highest zero-pin side according to + * preference order. + * 4. If all sides have pins, choose the side with the + * fewest pins. + * 3. Compute the position of the fields' bounding box ::field_box_placement + * 4. In manual mode, shift the box vertically if possible + * to fit fields between adjacent wires ::fit_fields_between_wires + * 5. Move all fields to their final positions + * 1. Re-justify fields if options allow that ::justify_field + * 2. Round to a 50-mil grid coordinate if desired + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FIELD_V_SPACING 100 +#define HPADDING 25 +#define VPADDING 50 + +/** + * Function round_n + * Round up/down to the nearest multiple of n + */ +template T round_n( const T& value, const T& n, bool aRoundUp ) +{ + if( value % n ) + return n * (value / n + (aRoundUp ? 1 : 0)); + else + return value; +} + + +/** + * Function TO_HJUSTIFY + * Converts an integer to a horizontal justification; neg=L zero=C pos=R + */ +EDA_TEXT_HJUSTIFY_T TO_HJUSTIFY( int x ) +{ + return static_cast( x ); +} + + +class AUTOPLACER +{ + SCH_SCREEN* m_screen; + SCH_COMPONENT* m_component; + std::vector m_fields; + std::vector m_colliders; + EDA_RECT m_comp_bbox; + wxSize m_fbox_size; + bool m_allow_rejustify, m_align_to_grid; + bool m_power_symbol; + +public: + typedef wxPoint SIDE; + static const SIDE SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT; + enum COLLISION { COLLIDE_NONE, COLLIDE_OBJECTS, COLLIDE_H_WIRES }; + + struct SIDE_AND_NPINS + { + SIDE side; + unsigned pins; + }; + + struct SIDE_AND_COLL + { + SIDE side; + COLLISION collision; + }; + + + AUTOPLACER( SCH_COMPONENT* aComponent, SCH_SCREEN* aScreen ) + :m_screen( aScreen ), m_component( aComponent ) + { + m_component->GetFields( m_fields, /* aVisibleOnly */ true ); + Kiface().KifaceSettings()->Read( AUTOPLACE_JUSTIFY_KEY, &m_allow_rejustify, true ); + Kiface().KifaceSettings()->Read( AUTOPLACE_ALIGN_KEY, &m_align_to_grid, false ); + + m_comp_bbox = m_component->GetBodyBoundingBox(); + m_fbox_size = ComputeFBoxSize(); + + m_power_symbol = ! m_component->IsInNetlist(); + + if( aScreen ) + get_possible_colliders( m_colliders ); + } + + + /** + * Do the actual autoplacement. + * @param aManual - if true, use extra heuristics for smarter placement when manually + * called up. + */ + void DoAutoplace( bool aManual ) + { + SIDE field_side = choose_side_for_fields( aManual ); + wxPoint fbox_pos = field_box_placement( field_side ); + EDA_RECT field_box( fbox_pos, m_fbox_size ); + + if( aManual ) + { + fbox_pos = fit_fields_between_wires( field_box, field_side ); + field_box.SetOrigin( fbox_pos ); + } + + // Move the fields + for( int field_idx = 0; field_idx < m_fields.size(); ++field_idx ) + { + SCH_FIELD* field = m_fields[field_idx]; + + if( m_allow_rejustify ) + justify_field( field, field_side ); + + wxPoint pos( + field_horiz_placement( field, field_box ), + field_box.GetY() + (FIELD_V_SPACING * field_idx) ); + + if( m_align_to_grid ) + { + pos.x = round_n( pos.x, 50, field_side.x >= 0 ); + pos.y = round_n( pos.y, 50, field_side.y == 1 ); + } + + field->SetPosition( pos ); + } + } + + +protected: + /** + * Compute and return the size of the fields' bounding box. + */ + wxSize ComputeFBoxSize() + { + int max_field_width = 0; + BOOST_FOREACH( SCH_FIELD* field, m_fields ) + { + int field_width; + + if( m_component->GetTransform().y1 ) + { + field->SetOrientation( TEXT_ORIENT_VERT ); + field_width = field->GetBoundingBox().GetHeight(); + } + else + { + field->SetOrientation( TEXT_ORIENT_HORIZ ); + field_width = field->GetBoundingBox().GetWidth(); + } + + max_field_width = std::max( max_field_width, field_width ); + } + + return wxSize( max_field_width, int( FIELD_V_SPACING * (m_fields.size() - 1) ) ); + } + + + /** + * Function get_pin_side + * Return the side that a pin is on. + */ + SIDE get_pin_side( LIB_PIN* aPin ) + { + int pin_orient = aPin->PinDrawOrient( m_component->GetTransform() ); + switch( pin_orient ) + { + case PIN_RIGHT: return SIDE_LEFT; + case PIN_LEFT: return SIDE_RIGHT; + case PIN_UP: return SIDE_BOTTOM; + case PIN_DOWN: return SIDE_TOP; + default: + wxFAIL_MSG( "Invalid pin orientation" ); + return SIDE_LEFT; + } + } + + + /** + * Function pins_on_side + * Count the number of pins on a side of the component. + */ + unsigned pins_on_side( SIDE aSide ) + { + unsigned pin_count = 0; + + std::vector pins; + m_component->GetPins( pins ); + + BOOST_FOREACH( LIB_PIN* each_pin, pins ) + { + if( !each_pin->IsVisible() && !m_power_symbol ) + continue; + if( get_pin_side( each_pin ) == aSide ) + ++pin_count; + } + + return pin_count; + } + + + /** + * Function get_possible_colliders + * Populate a list of all drawing items that *may* collide with the fields. That is, + * all drawing items, including other fields, that are not the current component or + * its own fields. + */ + void get_possible_colliders( std::vector& aItems ) + { + wxASSERT_MSG( m_screen, "get_possible_colliders() with null m_screen" ); + for( SCH_ITEM* item = m_screen->GetDrawItems(); item; item = item->Next() ) + { + if( SCH_COMPONENT* comp = dynamic_cast( item ) ) + { + if( comp == m_component ) continue; + + std::vector fields; + comp->GetFields( fields, /* aVisibleOnly */ true ); + BOOST_FOREACH( SCH_FIELD* field, fields ) + aItems.push_back( field ); + } + aItems.push_back( item ); + } + } + + + /** + * Function filtered_colliders + * Filter a list of possible colliders to include only those that actually collide + * with a given rectangle. Returns the new vector. + */ + std::vector filtered_colliders( const EDA_RECT& aRect ) + { + std::vector filtered; + BOOST_FOREACH( SCH_ITEM* item, m_colliders ) + { + EDA_RECT item_box; + if( SCH_COMPONENT* item_comp = dynamic_cast( item ) ) + item_box = item_comp->GetBodyBoundingBox(); + else + item_box = item->GetBoundingBox(); + + if( item_box.Intersects( aRect ) ) + filtered.push_back( item ); + } + return filtered; + } + + + /** + * Function get_preferred_sides + * Return a list with the preferred field sides for the component, in + * decreasing order of preference. + */ + std::vector get_preferred_sides() + { + SIDE_AND_NPINS sides_init[] = { + { SIDE_RIGHT, pins_on_side( SIDE_RIGHT ) }, + { SIDE_TOP, pins_on_side( SIDE_TOP ) }, + { SIDE_LEFT, pins_on_side( SIDE_LEFT ) }, + { SIDE_BOTTOM, pins_on_side( SIDE_BOTTOM ) }, + }; + std::vector sides( sides_init, sides_init + DIM( sides_init ) ); + + int orient = m_component->GetOrientation(); + int orient_angle = orient & 0xff; // enum is a bitmask + bool h_mirrored = ( ( orient & CMP_MIRROR_X ) + && ( orient_angle == CMP_ORIENT_0 || orient_angle == CMP_ORIENT_180 ) ); + double w = double( m_comp_bbox.GetWidth() ); + double h = double( m_comp_bbox.GetHeight() ); + + // The preferred-sides heuristics are a bit magical. These were determined mostly + // by trial and error. + + if( m_power_symbol ) + { + // For power symbols, we generally want the label at the top first. + switch( orient_angle ) + { + case CMP_ORIENT_0: + std::swap( sides[0], sides[1] ); + std::swap( sides[1], sides[3] ); + // TOP, BOTTOM, RIGHT, LEFT + break; + case CMP_ORIENT_90: + std::swap( sides[0], sides[2] ); + std::swap( sides[1], sides[2] ); + // LEFT, RIGHT, TOP, BOTTOM + break; + case CMP_ORIENT_180: + std::swap( sides[0], sides[3] ); + // BOTTOM, TOP, LEFT, RIGHT + break; + case CMP_ORIENT_270: + std::swap( sides[1], sides[2] ); + // RIGHT, LEFT, TOP, BOTTOM + break; + } + } + else + { + // If the component is horizontally mirrored, swap left and right + if( h_mirrored ) + { + std::swap( sides[0], sides[2] ); + } + + // If the component is very long or is a power symbol, swap H and V + if( w/h > 3.0 ) + { + std::swap( sides[0], sides[1] ); + std::swap( sides[1], sides[3] ); + } + } + + return sides; + } + + + /** + * Function get_colliding_sides + * Return a list of the sides where a field set would collide with another item. + */ + std::vector get_colliding_sides() + { + SIDE sides_init[] = { SIDE_RIGHT, SIDE_TOP, SIDE_LEFT, SIDE_BOTTOM }; + std::vector sides( sides_init, sides_init + DIM( sides_init ) ); + std::vector colliding; + + // Iterate over all sides and find the ones that collide + BOOST_FOREACH( SIDE side, sides ) + { + EDA_RECT box( field_box_placement( side ), m_fbox_size ); + + COLLISION collision = COLLIDE_NONE; + BOOST_FOREACH( SCH_ITEM* collider, filtered_colliders( box ) ) + { + SCH_LINE* line = dynamic_cast( collider ); + if( line && !side.x ) + { + wxPoint start = line->GetStartPoint(), end = line->GetEndPoint(); + if( start.y == end.y && collision != COLLIDE_OBJECTS ) + collision = COLLIDE_H_WIRES; + else + collision = COLLIDE_OBJECTS; + } + else + collision = COLLIDE_OBJECTS; + } + + if( collision != COLLIDE_NONE ) + colliding.push_back( (SIDE_AND_COLL){ side, collision } ); + } + + return colliding; + } + + + /** + * Function choose_side_filtered + * Choose a side for the fields, filtered on only one side collision type. + * Removes the sides matching the filter from the list. + */ + SIDE_AND_NPINS choose_side_filtered( std::vector& aSides, + const std::vector& aCollidingSides, COLLISION aCollision, + SIDE_AND_NPINS aLastSelection) + { + SIDE_AND_NPINS sel = aLastSelection; + + std::vector::iterator it = aSides.begin(); + while( it != aSides.end() ) + { + bool collide = false; + BOOST_FOREACH( SIDE_AND_COLL collision, aCollidingSides ) + { + if( collision.side == it->side && collision.collision == aCollision ) + collide = true; + } + if( !collide ) + ++it; + else + { + if( it->pins <= sel.pins ) + { + sel.pins = it->pins; + sel.side = it->side; + } + it = aSides.erase( it ); + } + } + return sel; + } + + + /** + * Function choose_side_for_fields + * Look where a component's pins are to pick a side to put the fields on + * @param aAvoidCollisions - if true, pick last the sides where the label will collide + * with other items. + */ + SIDE choose_side_for_fields( bool aAvoidCollisions ) + { + std::vector sides = get_preferred_sides(); + + std::reverse( sides.begin(), sides.end() ); + SIDE_AND_NPINS side = { wxPoint( 1, 0 ), UINT_MAX }; + + if( aAvoidCollisions ) + { + std::vector colliding_sides = get_colliding_sides(); + side = choose_side_filtered( sides, colliding_sides, COLLIDE_OBJECTS, side ); + side = choose_side_filtered( sides, colliding_sides, COLLIDE_H_WIRES, side ); + } + + BOOST_REVERSE_FOREACH( SIDE_AND_NPINS& each_side, sides ) + { + if( !each_side.pins ) return each_side.side; + } + + BOOST_FOREACH( SIDE_AND_NPINS& each_side, sides ) + { + if( each_side.pins <= side.pins ) + { + side.pins = each_side.pins; + side.side = each_side.side; + } + } + + return side.side; + } + + + /** + * Function justify_field + * Set the justification of a field based on the side it's supposed to be on, taking + * into account whether the field will be displayed with flipped justification due to + * mirroring. + */ + void justify_field( SCH_FIELD* aField, SIDE aFieldSide ) + { + // Justification is set twice to allow IsHorizJustifyFlipped() to work correctly. + aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x ) ); + aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x * + ( aField->IsHorizJustifyFlipped() ? -1 : 1 ) ) ); + aField->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); + } + + + /** + * Function field_box_placement + * Returns the position of the field bounding box. + */ + wxPoint field_box_placement( SIDE aFieldSide ) + { + wxPoint fbox_center = m_comp_bbox.Centre(); + int offs_x = ( m_comp_bbox.GetWidth() + m_fbox_size.GetWidth() ) / 2 + HPADDING; + int offs_y = ( m_comp_bbox.GetHeight() + m_fbox_size.GetHeight() ) / 2 + VPADDING; + + fbox_center.x += aFieldSide.x * offs_x; + fbox_center.y += aFieldSide.y * offs_y; + + wxPoint fbox_pos( + fbox_center.x - m_fbox_size.GetWidth() / 2, + fbox_center.y - m_fbox_size.GetHeight() / 2 ); + + return fbox_pos; + } + + + /** + * Function fit_fields_between_wires + * Shift a field box up or down a bit to make the fields fit between some wires. + * Returns the new position of the field bounding box. + */ + wxPoint fit_fields_between_wires( const EDA_RECT& aBox, SIDE aSide ) + { + if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM ) + return aBox.GetPosition(); + + std::vector colliders = filtered_colliders( aBox ); + if( colliders.empty() ) + return aBox.GetPosition(); + + // Find the offset of the wires for proper positioning + int offset = 0; + + BOOST_FOREACH( SCH_ITEM* item, colliders ) + { + SCH_LINE* line = dynamic_cast( item ); + if( !line ) + return aBox.GetPosition(); + wxPoint start = line->GetStartPoint(), end = line->GetEndPoint(); + if( start.y != end.y ) + return aBox.GetPosition(); + + int this_offset = (3 * FIELD_V_SPACING / 2) - ( start.y % FIELD_V_SPACING ); + if( offset == 0 ) + offset = this_offset; + else if( offset != this_offset ) + return aBox.GetPosition(); + } + + if( aSide == SIDE_TOP ) + offset = -offset; + + wxPoint pos = aBox.GetPosition(); + pos.y = round_n( pos.y - offset, FIELD_V_SPACING, aSide == SIDE_BOTTOM ) + offset; + return pos; + } + + + /** + * Function field_horiz_placement + * Place a field horizontally, taking into account the field width and + * justification. + * + * @param aField - the field to place. + * @param aFieldBox - box in which fields will be placed + * + * @return Correct field horizontal position + */ + int field_horiz_placement( SCH_FIELD *aField, const EDA_RECT &aFieldBox ) + { + int field_hjust; + int field_xcoord; + + if( aField->IsHorizJustifyFlipped() ) + field_hjust = -aField->GetHorizJustify(); + else + field_hjust = aField->GetHorizJustify(); + + switch( field_hjust ) + { + case GR_TEXT_HJUSTIFY_LEFT: + field_xcoord = aFieldBox.GetLeft(); + break; + case GR_TEXT_HJUSTIFY_CENTER: + field_xcoord = aFieldBox.Centre().x; + break; + case GR_TEXT_HJUSTIFY_RIGHT: + field_xcoord = aFieldBox.GetRight(); + break; + default: + wxFAIL_MSG( "Unexpected value for SCH_FIELD::GetHorizJustify()" ); + field_xcoord = aFieldBox.Centre().x; // Most are centered + } + + return field_xcoord; + } + +}; + +const AUTOPLACER::SIDE AUTOPLACER::SIDE_TOP( 0, -1 ); +const AUTOPLACER::SIDE AUTOPLACER::SIDE_BOTTOM( 0, 1 ); +const AUTOPLACER::SIDE AUTOPLACER::SIDE_LEFT( -1, 0 ); +const AUTOPLACER::SIDE AUTOPLACER::SIDE_RIGHT( 1, 0 ); + + +void SCH_EDIT_FRAME::OnAutoplaceFields( wxCommandEvent& aEvent ) +{ + SCH_SCREEN* screen = GetScreen(); + SCH_ITEM* item = screen->GetCurItem(); + + // Get the item under cursor if we're not currently moving something + if( !item ) + { + if( aEvent.GetInt() == 0 ) + return; + + EDA_HOTKEY_CLIENT_DATA& data = dynamic_cast( + *aEvent.GetClientObject() ); + item = LocateItem( data.GetPosition(), SCH_COLLECTOR::MovableItems, aEvent.GetInt() ); + screen->SetCurItem( NULL ); + if( !item || item->GetFlags() ) + return; + } + + SCH_COMPONENT* component = dynamic_cast( item ); + if( !component ) + return; + + if( !component->IsNew() ) + SaveCopyInUndoList( component, UR_CHANGED ); + + component->AutoplaceFields( screen, /* aManual */ true ); + + GetCanvas()->Refresh(); + OnModify(); +} + + +void SCH_COMPONENT::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) +{ + if( aManual ) + wxASSERT_MSG( aScreen, "A SCH_SCREEN pointer must be given for manual autoplacement" ); + AUTOPLACER autoplacer( this, aScreen ); + autoplacer.DoAutoplace( aManual ); + m_fieldsAutoplaced = ( aManual? AUTOPLACED_MANUAL : AUTOPLACED_AUTO ); +} diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index 1d49ea3e42..755dcd81d3 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -1194,7 +1194,7 @@ const EDA_RECT LIB_PART::GetBodyBoundingBox( int aUnit, int aConvert ) const if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) ) continue; - if ( item.Type() == LIB_FIELD_T ) + if( item.Type() == LIB_FIELD_T ) continue; if( initialized ) diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 4b9eabd3ba..2e974e18d2 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -158,6 +158,9 @@ void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent ) // the QUASIMODAL macros here. int ret = dlg->ShowQuasiModal(); + if( m_autoplaceFields ) + aComponent->AutoAutoplaceFields( GetScreen() ); + m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); dlg->Destroy(); diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp index d3439da381..b3cad30b67 100644 --- a/eeschema/dialogs/dialog_edit_one_field.cpp +++ b/eeschema/dialogs/dialog_edit_one_field.cpp @@ -298,6 +298,19 @@ void DIALOG_SCH_EDIT_ONE_FIELD::TransfertDataToField( bool aIncludeText ) m_field->SetItalic( ( m_TextShapeOpt->GetSelection() & 1 ) != 0 ); m_field->SetBold( ( m_TextShapeOpt->GetSelection() & 2 ) != 0 ); + + // Because field autoplace can change justification, check whether this has + // been changed, and clear the autoplace flag if so. + EDA_TEXT_HJUSTIFY_T old_hjust = m_field->GetHorizJustify(); + EDA_TEXT_VJUSTIFY_T old_vjust = m_field->GetVertJustify(); + + if( old_hjust != m_textHjustify || old_vjust != m_textVjustify ) + { + EDA_ITEM *parent = m_field->GetParent(); + if( SCH_COMPONENT* component = dynamic_cast( parent ) ) + component->ClearFieldsAutoplaced(); + } + m_field->SetHorizJustify( m_textHjustify ); m_field->SetVertJustify( m_textVjustify ); } diff --git a/eeschema/dialogs/dialog_eeschema_options.h b/eeschema/dialogs/dialog_eeschema_options.h index df0c0bf9d2..71d575bcad 100644 --- a/eeschema/dialogs/dialog_eeschema_options.h +++ b/eeschema/dialogs/dialog_eeschema_options.h @@ -440,6 +440,42 @@ public: */ bool GetShowPageLimits( void ) { return m_checkPageLimits->GetValue(); } + /** + * Function + * Set the AutoplaceFields setting in the dialog + */ + void SetAutoplaceFields( bool enable ) { m_checkAutoplaceFields->SetValue( enable ); } + + /** + * Function + * Return the current AutoplaceFields setting from the dialog + */ + bool GetAutoplaceFields() { return m_checkAutoplaceFields->GetValue(); } + + /** + * Function + * Set the AutoplaceJustify setting in the dialog + */ + void SetAutoplaceJustify( bool enable ) { m_checkAutoplaceJustify->SetValue( enable ); } + + /** + * Function + * Return the current AutoplaceJustify setting from the dialog + */ + bool GetAutoplaceJustify() { return m_checkAutoplaceJustify->GetValue(); } + + /** + * Function + * Set the AutoplaceAlign setting in the dialog + */ + void SetAutoplaceAlign( bool enable ) { m_checkAutoplaceAlign->SetValue( enable ); } + + /** + * Function + * Return the current AutoplaceAlign setting from the dialog + */ + bool GetAutoplaceAlign() { return m_checkAutoplaceAlign->GetValue(); } + /** * Function SetTemplateFields * Set the template field data in the dialog diff --git a/eeschema/dialogs/dialog_eeschema_options_base.cpp b/eeschema/dialogs/dialog_eeschema_options_base.cpp index 56e1cf7a1a..ef62650781 100644 --- a/eeschema/dialogs/dialog_eeschema_options_base.cpp +++ b/eeschema/dialogs/dialog_eeschema_options_base.cpp @@ -214,6 +214,15 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx m_checkPageLimits = new wxCheckBox( m_panel1, wxID_ANY, _("Show page limi&ts"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer2->Add( m_checkPageLimits, 0, wxALL|wxEXPAND, 3 ); + m_checkAutoplaceFields = new wxCheckBox( m_panel1, wxID_ANY, _("Automatically place component fields"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_checkAutoplaceFields, 0, wxALL, 3 ); + + m_checkAutoplaceJustify = new wxCheckBox( m_panel1, wxID_ANY, _("Allow field autoplace to change justification"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_checkAutoplaceJustify, 0, wxALL, 3 ); + + m_checkAutoplaceAlign = new wxCheckBox( m_panel1, wxID_ANY, _("Always align autoplaced fields to the 50 mil grid"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_checkAutoplaceAlign, 0, wxALL, 3 ); + bSizer3->Add( bSizer2, 0, wxEXPAND, 0 ); diff --git a/eeschema/dialogs/dialog_eeschema_options_base.fbp b/eeschema/dialogs/dialog_eeschema_options_base.fbp index 9340f096ff..f270dfbd7b 100644 --- a/eeschema/dialogs/dialog_eeschema_options_base.fbp +++ b/eeschema/dialogs/dialog_eeschema_options_base.fbp @@ -2873,7 +2873,7 @@ 0 wxEXPAND 0 - + bSizer2 wxVERTICAL @@ -3663,6 +3663,270 @@ + + 3 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Automatically place component fields + + 0 + + + 0 + + 1 + m_checkAutoplaceFields + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Allow field autoplace to change justification + + 0 + + + 0 + + 1 + m_checkAutoplaceJustify + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Always align autoplaced fields to the 50 mil grid + + 0 + + + 0 + + 1 + m_checkAutoplaceAlign + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eeschema/dialogs/dialog_eeschema_options_base.h b/eeschema/dialogs/dialog_eeschema_options_base.h index d09b2f92d3..b3f2dd2912 100644 --- a/eeschema/dialogs/dialog_eeschema_options_base.h +++ b/eeschema/dialogs/dialog_eeschema_options_base.h @@ -109,6 +109,9 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM wxCheckBox* m_checkAutoPan; wxCheckBox* m_checkHVOrientation; wxCheckBox* m_checkPageLimits; + wxCheckBox* m_checkAutoplaceFields; + wxCheckBox* m_checkAutoplaceJustify; + wxCheckBox* m_checkAutoplaceAlign; wxPanel* m_panel2; wxListView* templateFieldListCtrl; wxStaticText* fieldNameLabel; diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp index 3b9104ae47..c9294a59cd 100644 --- a/eeschema/edit_component_in_schematic.cpp +++ b/eeschema/edit_component_in_schematic.cpp @@ -137,6 +137,10 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField ) { dlg.TransfertDataToField( /* aIncludeText = */ !( fieldNdx == VALUE && part->IsPower() ) ); OnModify(); + + if( m_autoplaceFields ) + component->AutoAutoplaceFields( GetScreen() ); + m_canvas->Refresh(); } diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 12c15988e6..1b585dbf1e 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -335,6 +335,9 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event ) dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() ); dlg.SetEnableHVBusOrientation( GetForceHVLines() ); dlg.SetShowPageLimits( m_showPageLimits ); + dlg.SetAutoplaceFields( m_autoplaceFields ); + dlg.SetAutoplaceJustify( m_autoplaceJustify ); + dlg.SetAutoplaceAlign( m_autoplaceAlign ); dlg.Layout(); dlg.Fit(); dlg.SetMinSize( dlg.GetSize() ); @@ -383,6 +386,9 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event ) m_canvas->SetEnableAutoPan( dlg.GetEnableAutoPan() ); SetForceHVLines( dlg.GetEnableHVBusOrientation() ); m_showPageLimits = dlg.GetShowPageLimits(); + m_autoplaceFields = dlg.GetAutoplaceFields(); + m_autoplaceJustify = dlg.GetAutoplaceJustify(); + m_autoplaceAlign = dlg.GetAutoplaceAlign(); // Delete all template fieldnames and then restore them using the template field data from // the options dialog @@ -503,6 +509,9 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) } +static const wxChar AutoplaceFieldsEntry[] = wxT( "AutoplaceFields" ); +static const wxChar AutoplaceJustifyEntry[] = AUTOPLACE_JUSTIFY_KEY; +static const wxChar AutoplaceAlignEntry[] = AUTOPLACE_ALIGN_KEY; static const wxChar DefaultBusWidthEntry[] = wxT( "DefaultBusWidth" ); static const wxChar DefaultDrawLineWidthEntry[] = wxT( "DefaultDrawLineWidth" ); static const wxChar ShowHiddenPinsEntry[] = wxT( "ShowHiddenPins" ); @@ -586,6 +595,9 @@ void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) SetDefaultLineThickness( aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) ); aCfg->Read( ShowHiddenPinsEntry, &m_showAllPins, false ); aCfg->Read( HorzVertLinesOnlyEntry, &m_forceHVLines, true ); + aCfg->Read( AutoplaceFieldsEntry, &m_autoplaceFields, true ); + aCfg->Read( AutoplaceJustifyEntry, &m_autoplaceJustify, true ); + aCfg->Read( AutoplaceAlignEntry, &m_autoplaceAlign, false ); // Load print preview window session settings. aCfg->Read( PreviewFramePositionXEntry, &tmp, -1 ); @@ -676,6 +688,9 @@ void SCH_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg ) aCfg->Write( DefaultDrawLineWidthEntry, (long) GetDefaultLineThickness() ); aCfg->Write( ShowHiddenPinsEntry, m_showAllPins ); aCfg->Write( HorzVertLinesOnlyEntry, GetForceHVLines() ); + aCfg->Write( AutoplaceFieldsEntry, m_autoplaceFields ); + aCfg->Write( AutoplaceJustifyEntry, m_autoplaceJustify ); + aCfg->Write( AutoplaceAlignEntry, m_autoplaceAlign ); // Save print preview window session settings. aCfg->Write( PreviewFramePositionXEntry, m_previewPosition.x ); diff --git a/eeschema/eeschema_config.h b/eeschema/eeschema_config.h index e93160b56a..e82f5df0d8 100644 --- a/eeschema/eeschema_config.h +++ b/eeschema/eeschema_config.h @@ -10,4 +10,8 @@ // a key to read write in user config the visibility of the rescue library dialog #define RESCUE_NEVER_SHOW_KEY wxT("RescueNeverShow") +// define autoplace key here to avoid having to take the long trip to get at the SCH_EDIT_FRAME +#define AUTOPLACE_JUSTIFY_KEY wxT("AutoplaceJustify") +#define AUTOPLACE_ALIGN_KEY wxT("AutoplaceAlign") + #endif // EESCHEMA_CONFIG_H diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index ca8eeeb88c..2a7e903d0f 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -168,6 +168,8 @@ enum id_eeschema_frm ID_SCH_MOVE_ITEM, ID_SCH_DRAG_ITEM, + ID_AUTOPLACE_FIELDS, + // Schematic editor commmands. These are command IDs that are generated by multiple // events (menus, toolbar, context menu, etc.) that result in the same event handler. ID_CANCEL_CURRENT_COMMAND, diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 8c8db7ea02..302a998e11 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -242,6 +242,10 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC, SetMsgPanel( items ); component->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode ); component->SetFlags( IS_NEW ); + + if( m_autoplaceFields ) + component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); + PrepareMoveItem( (SCH_ITEM*) component, aDC ); return component; @@ -268,29 +272,11 @@ void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation ) INSTALL_UNBUFFERED_DC( dc, m_canvas ); - // Erase the previous component in it's current orientation. - - m_canvas->CrossHairOff( &dc ); - - if( component->GetFlags() ) - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode ); - else - { - component->SetFlags( IS_MOVED ); // do not redraw the component - m_canvas->RefreshDrawingRect( component->GetBoundingBox() ); - component->ClearFlags( IS_MOVED ); - } - component->SetOrientation( aOrientation ); - /* Redraw the component in the new position. */ - if( component->GetFlags() ) - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode ); - else - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - m_canvas->CrossHairOn( &dc ); GetScreen()->TestDanglingEnds( m_canvas, &dc ); + m_canvas->Refresh(); OnModify(); } @@ -344,13 +330,11 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) component->ClearFlags(); component->SetFlags( flags ); // Restore m_Flag modified by SetUnit() - /* Redraw the component in the new position. */ - if( flags ) - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); - else - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + if( m_autoplaceFields ) + component->AutoAutoplaceFields( GetScreen() ); screen->TestDanglingEnds( m_canvas, &dc ); + m_canvas->Refresh(); OnModify(); } } diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp index 599422054e..d31c392669 100644 --- a/eeschema/hotkeys.cpp +++ b/eeschema/hotkeys.cpp @@ -219,6 +219,10 @@ static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CT static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL ); static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL ); +// Autoplace fields +static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FIELDS, 'O', + ID_AUTOPLACE_FIELDS ); + // List of common hotkey descriptors static EDA_HOTKEY* common_Hotkey_List[] = { @@ -292,6 +296,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] = &HkAddGraphicPolyLine, &HkAddGraphicText, &HkLeaveSheet, + &HkAutoplaceFields, &HkDeleteNode, NULL }; @@ -580,6 +585,7 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component) case HK_ROTATE: // Rotate schematic item. case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component + case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component { // force a new item search on hot keys at current position, // if there is no currently edited item, diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h index afcebcac0f..22f3f382e2 100644 --- a/eeschema/hotkeys.h +++ b/eeschema/hotkeys.h @@ -78,6 +78,7 @@ enum hotkey_id_commnand { HK_LEFT_CLICK, HK_LEFT_DCLICK, HK_LEAVE_SHEET, + HK_AUTOPLACE_FIELDS, HK_DELETE_NODE }; diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index e4b221f3bd..525e086dac 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -2012,7 +2012,7 @@ void LIB_PIN::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList ) } -const EDA_RECT LIB_PIN::GetBoundingBox() const +const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles ) const { LIB_PART* entry = (LIB_PART* ) m_Parent; EDA_RECT bbox; @@ -2023,6 +2023,8 @@ const EDA_RECT LIB_PIN::GetBoundingBox() const bool showNum = m_number != 0; int minsizeV = TARGET_PIN_RADIUS; + if( !aIncludeInvisibles && !IsVisible() ) + showName = false; if( entry ) { diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index 6cf68015c7..f91ccdd81e 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -151,7 +151,15 @@ public: bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); - const EDA_RECT GetBoundingBox() const; // Virtual + /* Cannot use a default parameter here as it will not be compatible with the virtual. */ + const EDA_RECT GetBoundingBox() const { return GetBoundingBox( false ); } + + /** + * Function GetBoundingBox + * @param aIncludeInvisibles - if false, do not include labels for invisible pins + * in the calculation. + */ + const EDA_RECT GetBoundingBox( bool aIncludeInvisibles ) const; /** * Function PinEndPoint diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index 442e2412ea..526b562890 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -394,6 +394,9 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CMP, msg, KiBitmap( delete_xpm ) ); } + msg = AddHotkeyName( _( "Autoplace Fields" ), g_Schematic_Hokeys_Descr, HK_AUTOPLACE_FIELDS ); + AddMenuItem( PopMenu, ID_AUTOPLACE_FIELDS, msg, KiBitmap( autoplace_fields_xpm ) ); + if( libEntry && !libEntry->GetDocFileName().IsEmpty() ) AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Doc" ), KiBitmap( datasheet_xpm ) ); } diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index a8aac34e81..4b22899a5c 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -217,6 +217,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) : } m_isDangling = aComponent.m_isDangling; + m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced; } @@ -660,6 +661,16 @@ SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const } +void SCH_COMPONENT::GetFields( std::vector& aVector, bool aVisibleOnly ) +{ + BOOST_FOREACH( SCH_FIELD& each_field, m_Fields ) + { + if( !aVisibleOnly || ( each_field.IsVisible() && !each_field.IsVoid() ) ) + aVector.push_back( &each_field ); + } +} + + SCH_FIELD* SCH_COMPONENT::AddField( const SCH_FIELD& aField ) { int newNdx = m_Fields.size(); @@ -691,6 +702,17 @@ LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number ) } +void SCH_COMPONENT::GetPins( std::vector& aPinsList ) +{ + if( PART_SPTR part = m_part.lock() ) + { + part->GetPins( aPinsList, m_unit, m_convert ); + } + else + wxFAIL_MSG( "Could not obtain PART_SPTR lock" ); +} + + void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T), diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 97cf97023a..5b1535a0b5 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -64,6 +64,10 @@ class SCH_COMPONENT : public SCH_ITEM { friend class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC; +public: + enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL }; +private: + wxPoint m_Pos; wxString m_part_name; ///< Name to look for in the library, i.e. "74LS00". @@ -82,6 +86,8 @@ class SCH_COMPONENT : public SCH_ITEM std::vector m_isDangling; ///< One isDangling per pin + AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement + /** * A temporary sheet path is required to generate the correct reference designator string * in complex heirarchies. Hopefully this is only a temporary hack to decouple schematic @@ -100,8 +106,6 @@ class SCH_COMPONENT : public SCH_ITEM void Init( const wxPoint& pos = wxPoint( 0, 0 ) ); - EDA_RECT GetBodyBoundingBox() const; - public: SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL ); @@ -255,6 +259,13 @@ public: const EDA_RECT GetBoundingBox() const; // Virtual + /** + * Function GetBodyBoundingBox + * Return a bounding box for the component body but not the fields. + */ + EDA_RECT GetBodyBoundingBox() const; + + //---------------------------------------------------------------- /** @@ -265,6 +276,14 @@ public: */ SCH_FIELD* GetField( int aFieldNdx ) const; + /** + * Function GetFields + * populates a std::vector with SCH_FIELDs. + * @param aVector - vector to populate. + * @param aVisibleOnly - if true, only get fields that are visible and contain text. + */ + void GetFields( std::vector& aVector, bool aVisibleOnly ); + /** * Function AddField * adds a field to the component. The field is copied as it is put into @@ -284,15 +303,52 @@ public: { m_Fields = aFields; // vector copying, length is changed possibly } - - //--------------------------------------------------------------- - /** * Function GetFieldCount * returns the number of fields in this component. */ int GetFieldCount() const { return (int) m_Fields.size(); } + /** + * Function GetFieldsAutoplaced + * returns whether the fields are autoplaced. + */ + AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } + + /** + * Function ClearFieldsAutoplaced + * Set fields autoplaced flag false. + */ + void ClearFieldsAutoplaced() { m_fieldsAutoplaced = AUTOPLACED_NO; } + + /** + * Function AutoplaceFields + * Automatically orient all the fields in the component. + * @param aScreen - the SCH_SCREEN associated with the current instance of the + * component. This can be NULL when aManual is false. + * @param aManual - True if the autoplace was manually initiated (e.g. by a hotkey + * or a menu item). Some more 'intelligent' routines will be used that would be + * annoying if done automatically during moves. + */ + void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ); + + /** + * Function AutoAutoplaceFields + * Autoplace fields only if correct to do so automatically. That is, do not + * autoplace if fields have been moved by hand. + * @param aScreen - the SCH_SCREEN associated with the current instance of the + * component. + */ + void AutoAutoplaceFields( SCH_SCREEN* aScreen ) + { + if( GetFieldsAutoplaced() ) + AutoplaceFields( aScreen, GetFieldsAutoplaced() == AUTOPLACED_MANUAL ); + } + + + //--------------------------------------------------------------- + + /** * Function GetPin * finds a component pin by number. @@ -302,6 +358,12 @@ public: */ LIB_PIN* GetPin( const wxString& number ); + /** + * Function GetPins + * populate a vector with all the pins. + */ + void GetPins( std::vector& aPinsList ); + /** * Virtual function, from the base class SCH_ITEM::Draw */ diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 46b8834b73..38cbe18277 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -299,6 +299,23 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const } +bool SCH_FIELD::IsHorizJustifyFlipped() const +{ + wxPoint render_center = GetBoundingBox().Centre(); + wxPoint pos = GetPosition(); + + switch( GetHorizJustify() ) + { + case GR_TEXT_HJUSTIFY_LEFT: + return render_center.x < pos.x; + case GR_TEXT_HJUSTIFY_RIGHT: + return render_center.x > pos.x; + default: + return false; + } +} + + bool SCH_FIELD::Save( FILE* aFile ) const { char hjustify = 'C'; diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index 8b458bc2ab..814876a819 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -102,6 +102,13 @@ public: const EDA_RECT GetBoundingBox() const; // Virtual + /** + * Function IsHorizJustifyFlipped + * Returns whether the field will be rendered with the horizontal justification + * inverted due to rotation or mirroring of the parent. + */ + bool IsHorizJustifyFlipped() const; + /** * Function IsVoid * returns true if the field is either empty or holds "~". @@ -131,7 +138,7 @@ public: */ bool IsVisible() const { - return (m_Attributs & TEXT_NO_VISIBLE) == 0 ? true : false; + return !( m_Attributs & TEXT_NO_VISIBLE ); } void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index 927e44c135..91bad6f34b 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -765,6 +765,13 @@ void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem, wxDC* aDC ) SetUndoItem( aItem ); } + if( aItem->Type() == SCH_FIELD_T && aItem->GetParent()->Type() == SCH_COMPONENT_T ) + { + // Now that we're moving a field, they're no longer autoplaced. + SCH_COMPONENT *parent = dynamic_cast( aItem->GetParent() ); + parent->ClearFieldsAutoplaced(); + } + aItem->SetFlags( IS_MOVED ); // For some items, moving the cursor to anchor is not good @@ -826,14 +833,22 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent ) switch( item->Type() ) { case SCH_COMPONENT_T: - if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE ) - OrientComponent( CMP_ROTATE_CLOCKWISE ); - else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ) - OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE ); - else - wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) ); + { + SCH_COMPONENT* component = dynamic_cast( item ); + if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE ) + OrientComponent( CMP_ROTATE_CLOCKWISE ); + else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ) + OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE ); + else + wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) ); - break; + if( m_autoplaceFields ) + component->AutoAutoplaceFields( GetScreen() ); + + m_canvas->Refresh(); + + break; + } case SCH_TEXT_T: case SCH_LABEL_T: @@ -846,6 +861,12 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent ) case SCH_FIELD_T: m_canvas->MoveCursorToCrossHair(); RotateField( (SCH_FIELD*) item, &dc ); + if( item->GetParent()->Type() == SCH_COMPONENT_T ) + { + // Now that we're moving a field, they're no longer autoplaced. + SCH_COMPONENT *parent = dynamic_cast( item->GetParent() ); + parent->ClearFieldsAutoplaced(); + } break; case SCH_BITMAP_T: @@ -1126,16 +1147,24 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent ) switch( item->Type() ) { case SCH_COMPONENT_T: - if( aEvent.GetId() == ID_SCH_MIRROR_X ) - OrientComponent( CMP_MIRROR_X ); - else if( aEvent.GetId() == ID_SCH_MIRROR_Y ) - OrientComponent( CMP_MIRROR_Y ); - else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL ) - OrientComponent( CMP_NORMAL ); - else - wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) ); + { + SCH_COMPONENT *component = dynamic_cast( item ); + if( aEvent.GetId() == ID_SCH_MIRROR_X ) + OrientComponent( CMP_MIRROR_X ); + else if( aEvent.GetId() == ID_SCH_MIRROR_Y ) + OrientComponent( CMP_MIRROR_Y ); + else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL ) + OrientComponent( CMP_NORMAL ); + else + wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) ); - break; + if( m_autoplaceFields ) + component->AutoAutoplaceFields( GetScreen() ); + + m_canvas->Refresh(); + + break; + } case SCH_BITMAP_T: if( aEvent.GetId() == ID_SCH_MIRROR_X ) diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index ab48a12eaf..953e7f68de 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -266,6 +266,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems ) EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile ) EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem ) + EVT_TOOL( ID_AUTOPLACE_FIELDS, SCH_EDIT_FRAME::OnAutoplaceFields ) EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp ) EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp ) EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout ) @@ -1121,6 +1122,9 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) libeditFrame->LoadComponentAndSelectLib( entry, library ); } } + + GetScreen()->SchematicCleanUp( m_canvas, NULL ); + m_canvas->Refresh(); } diff --git a/eeschema/schframe.h b/eeschema/schframe.h index 0db8ea8224..f7309bc171 100644 --- a/eeschema/schframe.h +++ b/eeschema/schframe.h @@ -146,6 +146,10 @@ private: bool m_forceHVLines; ///< force H or V directions for wires, bus, line + bool m_autoplaceFields; ///< automatically place component fields + bool m_autoplaceJustify; ///< allow autoplace to change justification + bool m_autoplaceAlign; ///< align autoplaced fields to the grid + /// An index to the last find item in the found items list #m_foundItems. int m_foundItemIndex; @@ -764,6 +768,12 @@ public: private: + /** + * Function OnAutoplaceFields + * handles the #ID_AUTOPLACE_FIELDS event. + */ + void OnAutoplaceFields( wxCommandEvent& aEvent ); + /** * Function OnMoveItem * handles the #ID_SCH_MOVE_ITEM event used to move schematic itams. diff --git a/include/bitmaps.h b/include/bitmaps.h index c0711c8f89..67373b581e 100644 --- a/include/bitmaps.h +++ b/include/bitmaps.h @@ -111,6 +111,7 @@ EXTERN_BITMAP( array_zone_xpm ) EXTERN_BITMAP( auto_associe_xpm ) EXTERN_BITMAP( auto_delete_track_xpm ) EXTERN_BITMAP( auto_track_width_xpm ) +EXTERN_BITMAP( autoplace_fields_xpm ) EXTERN_BITMAP( axis3d_back_xpm ) EXTERN_BITMAP( axis3d_bottom_xpm ) EXTERN_BITMAP( axis3d_front_xpm ) diff --git a/include/class_eda_rect.h b/include/class_eda_rect.h index 57aa3a4de1..a38cc66ba0 100644 --- a/include/class_eda_rect.h +++ b/include/class_eda_rect.h @@ -103,6 +103,7 @@ public: int GetHeight() const { return m_Size.y; } int GetRight() const { return m_Pos.x + m_Size.x; } int GetLeft() const { return m_Pos.x; } + int GetTop() const { return m_Pos.y; } int GetBottom() const { return m_Pos.y + m_Size.y; } // Y axis from top to bottom void SetOrigin( const wxPoint& pos ) { m_Pos = pos; } From 5d429ed977e7509a7916e796c1392fff32188b32 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 14 Dec 2015 09:00:49 +0100 Subject: [PATCH 13/14] Pcbnew: drill file generation: always creates a NPTH file in separate files mode (as it was made in initial code) to avoid mistakes (old broken NPTH file after board edition for instance). Eeschema: prepare case sensitive label comparison in netlist generation. --- eeschema/netlist.cpp | 22 +++++++++++++++++-- pcbnew/exporters/gendrill_Excellon_writer.cpp | 9 +++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp index 3a4c61fcfd..a518ec07b2 100644 --- a/eeschema/netlist.cpp +++ b/eeschema/netlist.cpp @@ -50,6 +50,24 @@ #define IS_WIRE false #define IS_BUS true +/** @brief Kicad can use case sensitive or case insensitive comparisons for labels + * Currently, it uses case insensitive. + * Can be changed by defining LABEL_KEEPCASE (uncomment next line). + */ +//#define LABEL_KEEPCASE +/// Compiler controlled string compare function, either case independent or not: +inline int CmpLabel_KEEPCASE( const wxString& aString1, const wxString& aString2 ) +{ +#ifdef LABEL_KEEPCASE + // case specificity, the normal behavior: + return aString1.Cmp( aString2 ); +#else + // case independence (only for guys who want that: not recommended) + return aString1.CmpNoCase( aString2 ); +#endif +} + + //Imported function: int TestDuplicateSheetNames( bool aCreateMarker ); @@ -602,7 +620,7 @@ void NETLIST_OBJECT_LIST::sheetLabelConnect( NETLIST_OBJECT* SheetLabel ) if( ObjetNet->GetNet() == SheetLabel->GetNet() ) continue; //already connected. - if( ObjetNet->m_Label.CmpNoCase( SheetLabel->m_Label ) != 0 ) + if( CmpLabel_KEEPCASE( ObjetNet->m_Label, SheetLabel->m_Label ) != 0 ) continue; //different names. // Propagate Netcode having all the objects of the same Netcode. @@ -853,7 +871,7 @@ void NETLIST_OBJECT_LIST::labelConnect( NETLIST_OBJECT* aLabelRef ) // NET_PINLABEL is a kind of global label (generated by a power pin invisible) if( item->IsLabelType() ) { - if( item->m_Label.CmpNoCase( aLabelRef->m_Label ) != 0 ) + if( CmpLabel_KEEPCASE( item->m_Label, aLabelRef->m_Label ) != 0 ) continue; if( item->GetNet() ) diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index b6d0bfe6d0..af2747ffe8 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -6,8 +6,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2012 Jean_Pierre Charras - * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2015 Jean_Pierre Charras + * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 1992-2015 KiCad Developers, see change_log.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 @@ -100,7 +101,9 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, BuildHolesList( pair, doing_npth ); - if( GetHolesCount() > 0 ) // has holes? + // The file is created if it has holes, or if it is the non plated drill file + // to be sure the NPTH file is up to date in separate files mode. + if( GetHolesCount() > 0 || doing_npth ) { fn = drillFileName( pair, doing_npth ); fn.SetPath( aPlotDirectory ); From 2128594a85967cfb21d4e01432d094b3a590dbbe Mon Sep 17 00:00:00 2001 From: Cirilo Bernardo Date: Mon, 14 Dec 2015 16:20:54 -0500 Subject: [PATCH 14/14] Coding policy fixes: remove trailing white space. --- 3d-viewer/CBBox.cpp | 16 ++++++++-------- 3d-viewer/CImage.cpp | 16 ++++++++-------- 3d-viewer/CImage.h | 2 +- eeschema/sch_sheet_path.h | 4 ++-- pcbnew/dialogs/dialog_plot.cpp | 6 +++--- pcbnew/router/time_limit.cpp | 2 +- pcbnew/tools/point_editor.cpp | 2 +- polygon/math_for_graphics.h | 2 +- polygon/poly2tri/poly2tri.h | 2 +- polygon/poly2tri/sweep/cdt.h | 28 ++++++++++++++-------------- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/3d-viewer/CBBox.cpp b/3d-viewer/CBBox.cpp index 23c1856a99..e14636536d 100644 --- a/3d-viewer/CBBox.cpp +++ b/3d-viewer/CBBox.cpp @@ -109,7 +109,7 @@ void CBBOX::Union( const S3D_VERTEX &aPoint ) m_max.x = glm::max( m_max.x, aPoint.x ); m_max.y = glm::max( m_max.y, aPoint.y ); m_max.z = glm::max( m_max.z, aPoint.z ); - } + } } @@ -117,7 +117,7 @@ void CBBOX::Union( const CBBOX &aBBox ) { if( aBBox.m_initialized == false ) return; - + if( !m_initialized ) { // Initialize the bounding box with the given bounding box @@ -159,7 +159,7 @@ void CBBOX::Scale( float aScale ) { if( m_initialized == false ) return; - + S3D_VERTEX scaleV = S3D_VERTEX( aScale, aScale, aScale ); S3D_VERTEX centerV = GetCenter(); @@ -168,7 +168,7 @@ void CBBOX::Scale( float aScale ) } -bool CBBOX::OverlapsBox( const CBBOX &aBBox ) const +bool CBBOX::OverlapsBox( const CBBOX &aBBox ) const { if( aBBox.m_initialized == false ) return false; @@ -181,7 +181,7 @@ bool CBBOX::OverlapsBox( const CBBOX &aBBox ) const } -bool CBBOX::Inside( const S3D_VERTEX &aPoint ) const +bool CBBOX::Inside( const S3D_VERTEX &aPoint ) const { if( m_initialized == false ) return false; @@ -192,7 +192,7 @@ bool CBBOX::Inside( const S3D_VERTEX &aPoint ) const } -float CBBOX::Volume() const +float CBBOX::Volume() const { if( m_initialized == false ) return 0.0f; @@ -206,7 +206,7 @@ void CBBOX::ApplyTransformation( glm::mat4 aTransformMatrix ) { if( m_initialized == false ) return; - + S3D_VERTEX v1 = S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) ); S3D_VERTEX v2 = S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) ); @@ -237,7 +237,7 @@ void CBBOX::ApplyTransformationAA( glm::mat4 aTransformMatrix ) } -void CBBOX::GLdebug() const +void CBBOX::GLdebug() const { if( m_initialized == false ) return; diff --git a/3d-viewer/CImage.cpp b/3d-viewer/CImage.cpp index 0315d65e55..157a0762fd 100644 --- a/3d-viewer/CImage.cpp +++ b/3d-viewer/CImage.cpp @@ -80,11 +80,11 @@ bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const default: break; } - + if( (x < 0) || (x >= (int)m_width) || (y < 0) || (y >= (int)m_height) ) return false; - + *aXo = x; *aYo = y; @@ -127,7 +127,7 @@ void CIMAGE::CopyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe else { if ( (aImgA == NULL) || (aImgB == NULL) ) - return; + return; } switch(aOperation) @@ -202,7 +202,7 @@ void CIMAGE::CopyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOpe m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it]; } break; - + case COPY_BLEND50: for( unsigned int it = 0;it < m_wxh; it++ ) { @@ -253,7 +253,7 @@ static const S_FILTER FILTERS[] = { 7, 255 }, - + // Blur { { { 3, 5, 7, 5, 3}, @@ -378,7 +378,7 @@ void CIMAGE::EfxFilter( CIMAGE *aInImg, E_FILTER aFilterType ) #ifdef USE_OPENMP #pragma omp parallel for #endif /* USE_OPENMP */ - + for( int iy = 0; iy < (int)m_height; iy++) { for( int ix = 0; ix < (int)m_width; ix++ ) @@ -394,7 +394,7 @@ void CIMAGE::EfxFilter( CIMAGE *aInImg, E_FILTER aFilterType ) v += pixelv * factor; } } - + v /= filter.div; v += filter.offset; @@ -421,7 +421,7 @@ void CIMAGE::SetPixelsFromNormalizedFloat( const float * aNormalizedFloatArray ) void CIMAGE::SaveAsPNG( wxString aFileName ) const { unsigned char* pixelbuffer = (unsigned char*) malloc( m_wxh * 3 ); - + wxImage image( m_width, m_height ); for( unsigned int i = 0; i < m_wxh; i++) diff --git a/3d-viewer/CImage.h b/3d-viewer/CImage.h index 9e46cd2d49..16c1a94cac 100644 --- a/3d-viewer/CImage.h +++ b/3d-viewer/CImage.h @@ -99,7 +99,7 @@ public: * @param aValue value to set the pixel */ void Setpixel( int aX, int aY, unsigned char aValue ); - + /** * Function Getpixel * get the pixel value from pixel position, position is clamped in accord with the diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 939d899a59..c301e030bd 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -137,8 +137,8 @@ public: * Function Cmp * Compare if this is the same sheet path as aSheetPathToTest * @param aSheetPathToTest = sheet path to compare - * @return 1 if this sheet path has more sheets than aSheetPathToTest, - * -1 if this sheet path has fewer sheets than aSheetPathToTest, + * @return 1 if this sheet path has more sheets than aSheetPathToTest, + * -1 if this sheet path has fewer sheets than aSheetPathToTest, * or 0 if same */ int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const; diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index f3d13a43e5..a893c18dc5 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -688,7 +688,7 @@ void DIALOG_PLOT::applyPlotSettings() // If someone enables more copper layers they will be selected by default. selectedLayers = selectedLayers | disabledCopperLayers; tempOptions.SetLayerSelection( selectedLayers ); - + tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() ); tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() ); @@ -786,7 +786,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq ) { LAYER_ID layer = *seq; - + // All copper layers that are disabled are actually selected // This is due to wonkyness in automatically selecting copper layers // for plotting when adding more than two layers to a board. @@ -795,7 +795,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) // This skips a copper layer if it is actually disabled on the board. if( ( LSET::AllCuMask() & ~m_board->GetEnabledLayers() )[layer] ) continue; - + // Pick the basename from the board file wxFileName fn( boardFilename ); diff --git a/pcbnew/router/time_limit.cpp b/pcbnew/router/time_limit.cpp index b4cef54869..e0f250b32a 100644 --- a/pcbnew/router/time_limit.cpp +++ b/pcbnew/router/time_limit.cpp @@ -22,7 +22,7 @@ #include "time_limit.h" -TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) : +TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) : m_limitMs( aMilliseconds ) { Restart(); diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index bb1bf3968a..d73a90b225 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -269,7 +269,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) { break; } - + if ( !modified ) updateEditedPoint( *evt ); diff --git a/polygon/math_for_graphics.h b/polygon/math_for_graphics.h index c8be901368..d7fb032871 100644 --- a/polygon/math_for_graphics.h +++ b/polygon/math_for_graphics.h @@ -60,7 +60,7 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int * if b > DBL_MAX/10, assume vertical line at x = a * returns closest point on line in xpp, ypp */ -double GetPointToLineDistance( double a, double b, int x, int y, +double GetPointToLineDistance( double a, double b, int x, int y, double * xp=NULL, double * yp=NULL ); inline double Distance( double x1, double y1, double x2, double y2 ) diff --git a/polygon/poly2tri/poly2tri.h b/polygon/poly2tri/poly2tri.h index 487755e2e9..042cb3dcb3 100644 --- a/polygon/poly2tri/poly2tri.h +++ b/polygon/poly2tri/poly2tri.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * diff --git a/polygon/poly2tri/sweep/cdt.h b/polygon/poly2tri/sweep/cdt.h index 3e6f024086..e7b703de1b 100644 --- a/polygon/poly2tri/sweep/cdt.h +++ b/polygon/poly2tri/sweep/cdt.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -28,7 +28,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #ifndef CDT_H #define CDT_H @@ -37,11 +37,11 @@ #include "sweep.h" /** - * + * * @author Mason Green * */ - + namespace p2t { class CDT @@ -50,40 +50,40 @@ public: /** * Constructor - add polyline with non repeating points - * + * * @param polyline */ CDT(std::vector polyline); - + /** * Destructor - clean up memory */ ~CDT(); - + /** * Add a hole - * + * * @param polyline */ void AddHole(std::vector polyline); - + /** * Add a steiner point - * + * * @param point */ void AddPoint(Point* point); - + /** * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points */ void Triangulate(); - + /** * Get CDT triangles */ std::vector GetTriangles(); - + /** * Get triangle map */ @@ -94,7 +94,7 @@ public: /** * Internals */ - + SweepContext* sweep_context_; Sweep* sweep_;