From e52d93429bde71cfeac5bce630d5ea88721de07f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 17 Apr 2014 17:02:36 -0500 Subject: [PATCH 01/36] The kicad.exe project manager was not finding the kicad.pro file because it did not know where the template directory was. --- kicad/kicad.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 742121c781..f6799d015f 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -79,6 +79,27 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) if( !initPgm() ) return false; + // Add search paths to feed the PGM_KICAD::SysSearch() function, + // currenly limited in support to only look for project templates + { + SEARCH_STACK bases; + + SystemDirsAppend( &bases ); + + // DBG( bases.Show( (std::string(__func__) + " bases").c_str() );) + + for( unsigned i = 0; i < bases.GetCount(); ++i ) + { + wxFileName fn( bases[i], wxEmptyString ); + + // Add KiCad template file path to search path list. + fn.AppendDir( wxT( "template" ) ); + m_bm.m_search.AddPaths( fn.GetPath() ); + } + + //DBG( m_bm.m_search.Show( (std::string( __func__ ) + " SysSearch()").c_str() );) + } + // Read current setup and reopen last directory if no filename to open on // command line. if( App().argc == 1 ) From 5f65d0da930cc8c299af7e755b1ab9ff89c7731b Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 17 Apr 2014 21:05:40 -0500 Subject: [PATCH 02/36] *) Add KIFACE_I::StartFlags() and IsSingle() so a KIFACE implementation can know if it is running under single_top.cpp or under a project manager. *) Test Kiface().IsSingle() when adding menus, some operations are not permitted when running under a project manager and the KIWAY_PLAYER is pegged to a specific project. *) Implemented KIWAY::KiFACE() so it loads *.kiface files. They still have to be in the same directory as the main *.exe launcher, so this presents some difficulty when the binaries are not yet installed but rather the *.kiface files are still in their original build directories. For today, I simply copied _pcbnew.kiface to build/kicad/. *) Add a test case to kicad/mainframe.cpp just to get an early peek at loading _pcbnew.kiface under the C++ project manager. Got that working for one specific invocation just for proof of concept. Surprise, it works. --- bitmap2component/bitmap2cmp_gui.cpp | 6 +- common/CMakeLists.txt | 1 + common/kiface_i.cpp | 4 +- common/kiway.cpp | 82 +++++++++---- common/prependpath.cpp | 70 +++++++++++ common/project.cpp | 16 ++- common/single_top.cpp | 78 ++----------- cvpcb/cvpcb.cpp | 6 +- cvpcb/readwrite_dlgs.cpp | 3 +- eeschema/eeschema.cpp | 28 ++--- eeschema/schframe.cpp | 4 +- gerbview/gerbview.cpp | 6 +- include/common.h | 4 + include/config_params.h | 1 - include/kiface_i.h | 23 +++- include/kiway.h | 61 ++++------ include/kiway_mgr.h | 68 +++++++++++ include/kiway_player.h | 49 +++++++- kicad/commandframe.cpp | 2 +- kicad/kicad.cpp | 87 +++++++------- kicad/mainframe.cpp | 23 +++- pagelayout_editor/pl_editor.cpp | 6 +- pcb_calculator/pcb_calculator.cpp | 6 +- pcbnew/edit.cpp | 12 +- pcbnew/editmod.cpp | 4 +- pcbnew/menubar_pcbframe.cpp | 174 ++++++++-------------------- pcbnew/modedit.cpp | 4 +- pcbnew/pcbframe.cpp | 10 +- pcbnew/pcbnew.cpp | 18 +-- pcbnew/ratsnest.cpp | 5 +- 30 files changed, 488 insertions(+), 373 deletions(-) create mode 100644 common/prependpath.cpp create mode 100644 include/kiway_mgr.h diff --git a/bitmap2component/bitmap2cmp_gui.cpp b/bitmap2component/bitmap2cmp_gui.cpp index 7b11ffb860..9e8968ecfb 100644 --- a/bitmap2component/bitmap2cmp_gui.cpp +++ b/bitmap2component/bitmap2cmp_gui.cpp @@ -639,7 +639,7 @@ namespace BMP2CMP { static struct IFACE : public KIFACE_I { - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) { @@ -706,8 +706,8 @@ PGM_BASE& Pgm() #endif -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - return start_common(); + return start_common( aCtlBits ); } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index cb3d0fceb6..53fdaff9e3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -186,6 +186,7 @@ set( COMMON_SRCS msgpanel.cpp netlist_keywords.cpp newstroke_font.cpp + prependpath.cpp project.cpp ptree.cpp reporter.cpp diff --git a/common/kiface_i.cpp b/common/kiface_i.cpp index 9432c057cd..3693d1998d 100644 --- a/common/kiface_i.cpp +++ b/common/kiface_i.cpp @@ -94,8 +94,10 @@ static void setSearchPaths( SEARCH_STACK* aDst, KIWAY::FACE_T aId ) } -bool KIFACE_I::start_common() +bool KIFACE_I::start_common( int aCtlBits ) { + m_start_flags = aCtlBits; + m_bm.Init(); m_bm.m_config->Read( showPageLimitsKey, &g_ShowPageLimits ); diff --git a/common/kiway.cpp b/common/kiway.cpp index 577f118e66..390586a24b 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -22,15 +22,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include #include #include -#include - - -// one for each FACE_T -wxDynamicLibrary KIWAY::s_sch_dso; -wxDynamicLibrary KIWAY::s_pcb_dso; +#include KIWAY::KIWAY() @@ -39,20 +36,30 @@ KIWAY::KIWAY() } -/* -const wxString KIWAY::dso_name( FACE_T aFaceId ) +const wxString KIWAY::dso_full_path( FACE_T aFaceId ) { + const wxChar* name = wxT(""); + switch( aFaceId ) { - case FACE_SCH: return KIFACE_PREFIX wxT( "eeschema" ) KIFACE_SUFFIX; - case FACE_PCB: return KIFACE_PREFIX wxT( "pcbnew" ) KIFACE_SUFFIX; + case FACE_SCH: name = KIFACE_PREFIX wxT( "eeschema" ); break; + case FACE_PCB: name = KIFACE_PREFIX wxT( "pcbnew" ); break; default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); return wxEmptyString; } + + wxFileName fn = wxStandardPaths::Get().GetExecutablePath(); + + fn.SetName( name ); + + // Here a "suffix" == an extension with a preceding '.', + // so skip the preceding '.' to get an extension + fn.SetExt( KIFACE_SUFFIX + 1 ); // + 1 => &KIFACE_SUFFIX[1] + + return fn.GetFullPath(); } -*/ PROJECT& KIWAY::Prj() const @@ -61,14 +68,15 @@ PROJECT& KIWAY::Prj() const } -KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) +KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad ) { switch( aFaceId ) { - case FACE_SCH: + // case FACE_SCH: case FACE_PCB: if( m_kiface[aFaceId] ) return m_kiface[aFaceId]; + break; default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); @@ -78,17 +86,47 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) // DSO with KIFACE has not been loaded yet, does user want to load it? if( doLoad ) { - switch( aFaceId ) + wxString dname = dso_full_path( aFaceId ); + + wxDynamicLibrary dso; + + void* addr = NULL; + + if( !dso.Load( dname, wxDL_VERBATIM | wxDL_NOW ) ) { - case FACE_SCH: - break; - - case FACE_PCB: - break; - - default: - ; + // Failure: error reporting UI was done via wxLogSysError(). + // No further reporting required here. } + + else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL ) + { + // Failure: error reporting UI was done via wxLogSysError(). + // No further reporting required here. + } + + else + { + KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr; + + KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, aProgram ); + + // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional. + wxASSERT_MSG( kiface, + wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) ); + + // Give the DSO a single chance to do its "process level" initialization. + // "Process level" specifically means stay away from any projects in there. + if( kiface->OnKifaceStart( aProgram, KFCTL_PROJECT_SUITE ) ) + { + // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. + (void) dso.Detach(); + + return m_kiface[aFaceId] = kiface; + } + } + + // In any of the failure cases above, dso.Unload() should be called here + // by dso destructor. } return NULL; diff --git a/common/prependpath.cpp b/common/prependpath.cpp new file mode 100644 index 0000000000..6f68678642 --- /dev/null +++ b/common/prependpath.cpp @@ -0,0 +1,70 @@ + +#include +#include +#include + + + +#if !wxCHECK_VERSION( 3, 0, 0 ) + +// implement missing wx2.8 function until >= wx3.0 pervades. +static wxString wxJoin(const wxArrayString& arr, const wxChar sep, + const wxChar escape = '\\') +{ + size_t count = arr.size(); + if ( count == 0 ) + return wxEmptyString; + + wxString str; + + // pre-allocate memory using the estimation of the average length of the + // strings in the given array: this is very imprecise, of course, but + // better than nothing + str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2); + + if ( escape == wxT('\0') ) + { + // escaping is disabled: + for ( size_t i = 0; i < count; i++ ) + { + if ( i ) + str += sep; + str += arr[i]; + } + } + else // use escape character + { + for ( size_t n = 0; n < count; n++ ) + { + if ( n ) + str += sep; + + for ( wxString::const_iterator i = arr[n].begin(), + end = arr[n].end(); + i != end; + ++i ) + { + const wxChar ch = *i; + if ( ch == sep ) + str += escape; // escape this separator + str += ch; + } + } + } + + str.Shrink(); // release extra memory if we allocated too much + return str; +} +#endif + + +/// Put aPriorityPath in front of all paths in the value of aEnvVar. +const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ) +{ + wxPathList paths; + + paths.AddEnvList( aEnvVar ); + paths.Insert( aPriorityPath, 0 ); + + return wxJoin( paths, wxPATH_SEP[0] ); +} diff --git a/common/project.cpp b/common/project.cpp index 002bfa7d4f..4825974a9c 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -43,14 +43,13 @@ PROJECT::PROJECT() PROJECT::~PROJECT() { - /* @todo - careful here, this may work, but the virtual destructor may not - be in the same link image as PROJECT. Won't enable this until - we're more stable and destructor is assuredly in same image, i.e. - libki.so +#if 1 + // careful here, this may work, but the virtual destructor may not + // be in the same link image as PROJECT. + for( unsigned i = 0; i cfg( configCreate( aSList, aFileName, aGroupName, FORCE_LOCAL_CONFIG ) ); + std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, true ) ); if( !cfg.get() ) { @@ -353,8 +352,7 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, wxString timestamp = cfg->Read( wxT( "update" ) ); - if( doLoadOnlyIfNew && timestamp.size() && - timestamp == m_pro_date_and_time ) + if( doLoadOnlyIfNew && timestamp.size() && timestamp == m_pro_date_and_time ) { return false; } diff --git a/common/single_top.cpp b/common/single_top.cpp index 19104c4261..b1d925c99c 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -51,74 +51,8 @@ // The functions we use will cause the program launcher to pull stuff in // during linkage, keep the map file in mind to see what's going into it. - -#if !wxCHECK_VERSION( 3, 0, 0 ) - -// implement missing wx2.8 function until >= wx3.0 pervades. -static wxString wxJoin(const wxArrayString& arr, const wxChar sep, - const wxChar escape = '\\') -{ - size_t count = arr.size(); - if ( count == 0 ) - return wxEmptyString; - - wxString str; - - // pre-allocate memory using the estimation of the average length of the - // strings in the given array: this is very imprecise, of course, but - // better than nothing - str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2); - - if ( escape == wxT('\0') ) - { - // escaping is disabled: - for ( size_t i = 0; i < count; i++ ) - { - if ( i ) - str += sep; - str += arr[i]; - } - } - else // use escape character - { - for ( size_t n = 0; n < count; n++ ) - { - if ( n ) - str += sep; - - for ( wxString::const_iterator i = arr[n].begin(), - end = arr[n].end(); - i != end; - ++i ) - { - const wxChar ch = *i; - if ( ch == sep ) - str += escape; // escape this separator - str += ch; - } - } - } - - str.Shrink(); // release extra memory if we allocated too much - return str; -} -#endif - - -/// Put aPriorityPath in front of all paths in the value of aEnvVar. -const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ) -{ - wxPathList paths; - - paths.AddEnvList( aEnvVar ); - paths.Insert( aPriorityPath, 0 ); - - return wxJoin( paths, wxPATH_SEP[0] ); -} - - /// Extend LIB_ENV_VAR list with the directory from which I came, prepending it. -void SetLibEnvVar( const wxString& aAbsoluteArgv0 ) +static void set_lib_env_var( const wxString& aAbsoluteArgv0 ) { // POLICY CHOICE 2: Keep same path, so that installer MAY put the // "subsidiary DSOs" in the same directory as the kiway top process modules. @@ -149,6 +83,7 @@ void SetLibEnvVar( const wxString& aAbsoluteArgv0 ) #endif } + // POLICY CHOICE 1: return the full path of the DSO to load from single_top. static const wxString dso_full_path( const wxString& aAbsoluteArgv0 ) { @@ -339,7 +274,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) // Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the // KIFACE has hard dependencies on subsidiary DSOs below it. - SetLibEnvVar( absoluteArgv0 ); + set_lib_env_var( absoluteArgv0 ); if( !initPgm() ) return false; @@ -364,7 +299,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) // Give the DSO a single chance to do its "process level" initialization. // "Process level" specifically means stay away from any projects in there. - if( !kiface->OnKifaceStart( this ) ) + if( !kiface->OnKifaceStart( this, KFCTL_STANDALONE ) ) return false; // Use KIFACE to create a top window that the KIFACE knows about. @@ -418,8 +353,11 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) if( !argv1.GetExt() ) argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) ); - argSet[0] = argv1.GetFullPath(); #endif + argv1.MakeAbsolute(); + + argSet[0] = argv1.GetFullPath(); + if( !Pgm().LockFile( argSet[0] ) ) { wxLogSysError( _( "This file is already open." ) ); diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp index ebc75ad5ff..266674667d 100644 --- a/cvpcb/cvpcb.cpp +++ b/cvpcb/cvpcb.cpp @@ -100,7 +100,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -276,13 +276,13 @@ FP_LIB_TABLE GFootprintTable; // we skip setting KISYSMOD here for now. User should set the environment // variable. -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Set 3D shape path from environment variable KISYS3DMOD set3DShapesPath( wxT("KISYS3DMOD") ); diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index 8683d50232..538fe34841 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -720,8 +720,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) return 0; } - wxString msg; - msg.Printf( _("File %s saved"), GetChars( fn.GetFullPath() ) ); + wxString msg = wxString::Format( _("File %s saved"), GetChars( fn.GetFullPath() ) ); SetStatusText( msg ); return 1; } diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index c7e72dd048..0d0d0c43e9 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -68,7 +68,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd( PGM_BASE* aProgram ) { @@ -79,14 +79,6 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case LIBEDITOR_FRAME_TYPE: - { - LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, - dynamic_cast( aParent ) ); - return frame; - } - break; - case SCHEMATIC_FRAME_TYPE: { SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent ); @@ -96,9 +88,19 @@ static struct IFACE : public KIFACE_I // Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); - // @todo temporary - CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER ); + if( Kiface().IsSingle() ) + { + // only run this under single_top, not under a project manager. + CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER ); + } + return frame; + } + break; + case LIBEDITOR_FRAME_TYPE: + { + LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, + dynamic_cast( aParent ) ); return frame; } break; @@ -152,13 +154,13 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Give a default colour for all layers // (actual color will be initialized by config) diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index a2fba0988d..a26598437f 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -819,7 +819,9 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) } else { - wxWindow* w = Kiface().CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + wxWindow* w = kf.CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); libeditFrame = dynamic_cast( w ); } diff --git a/gerbview/gerbview.cpp b/gerbview/gerbview.cpp index 4e52f3937a..e7ae04c786 100644 --- a/gerbview/gerbview.cpp +++ b/gerbview/gerbview.cpp @@ -73,7 +73,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -145,9 +145,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/include/common.h b/include/common.h index 31d95c897f..ef03ea0e6a 100644 --- a/include/common.h +++ b/include/common.h @@ -610,4 +610,8 @@ void SystemDirsAppend( SEARCH_STACK* aSearchStack ); wxString SearchHelpFileFullPath( const SEARCH_STACK& aSearchStack, const wxString& aBaseName ); +/// Put aPriorityPath in front of all paths in the value of aEnvVar. +const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ); + + #endif // INCLUDE__COMMON_H_ diff --git a/include/config_params.h b/include/config_params.h index e83899af85..5529fbfce5 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -49,7 +49,6 @@ #define CONFIG_VERSION 1 -#define FORCE_LOCAL_CONFIG true /** diff --git a/include/kiface_i.h b/include/kiface_i.h index d764c9de35..9fe034603a 100644 --- a/include/kiface_i.h +++ b/include/kiface_i.h @@ -43,7 +43,7 @@ public: // see base class KIFACE in kiway.h for doxygen docs - VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0; + VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0; /* { typically call start_common() in your overload @@ -58,7 +58,7 @@ public: } VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, - int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; + int aClassId, KIWAY* aKIWAY, int aCtlBits ) = 0; VTBL_ENTRY void* IfaceOrAddress( int aDataId ) = 0; @@ -76,7 +76,8 @@ public: */ KIFACE_I( const char* aKifaceName, KIWAY::FACE_T aId ) : m_id( aId ), - m_bm( aKifaceName ) + m_bm( aKifaceName ), + m_start_flags( 0 ) { } @@ -85,7 +86,7 @@ public: protected: /// Common things to do for a top program module, during OnKifaceStart(). - bool start_common(); + bool start_common( int aCtlBits ); /// Common things to do for a top program module, during OnKifaceEnd(); void end_common(); @@ -100,6 +101,18 @@ public: wxConfigBase* KifaceSettings() const { return m_bm.m_config; } + /** + * Function StartFlags + * returns whatever was passed as @a aCtlBits to OnKifaceStart() + */ + int StartFlags() const { return m_start_flags; } + + /** + * Function IsSingle + * is this KIFACE_I running under single_top? + */ + bool IsSingle() const { return m_start_flags & KFCTL_STANDALONE; } + /** * Function GetHelpFileName * returns just the basename portion of the current help file. @@ -116,6 +129,8 @@ private: KIWAY::FACE_T m_id; BIN_MOD m_bm; + + int m_start_flags; ///< flags provided in OnKifaceStart() }; diff --git a/include/kiway.h b/include/kiway.h index b13f8b88e4..92e20b93e4 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -112,25 +112,20 @@ as such! As such, it is OK to use UTF8 characters: // be mangled. #define KIFACE_INSTANCE_NAME_AND_VERSION "KIFACE_1" - #if defined(__linux__) #define LIB_ENV_VAR wxT( "LD_LIBRARY_PATH" ) - #elif defined(__WXMAC__) #define LIB_ENV_VAR wxT( "DYLD_LIBRARY_PATH" ) - #elif defined(__MINGW32__) #define LIB_ENV_VAR wxT( "PATH" ) #endif class wxConfigBase; - - -class KIWAY; class wxWindow; -class PGM_BASE; class wxConfigBase; +class PGM_BASE; +class KIWAY; /** @@ -151,6 +146,10 @@ struct KIFACE // order of functions in this listing unless you recompile all clients of // this interface. +#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top. +#define KFCTL_PROJECT_SUITE (1<<1) ///< Am running under a project mgr, possibly with others + + /** * Function OnKifaceStart * is called just once shortly after the DSO is loaded. It is the second @@ -161,13 +160,15 @@ struct KIFACE * * @param aProgram is the process block: PGM_BASE* * + * @param aCtlBits consists of bit flags from the set of KFCTL_* \#defines above. + * * @return bool - true if DSO initialized OK, false if not. When returning * false, the loader may optionally decide to terminate the process or not, * but will not put out any UI because that is the duty of this function to say * why it is returning false. Never return false without having reported * to the UI why. */ - VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0; + VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0; /** * Function OnKifaceEnd @@ -176,8 +177,6 @@ struct KIFACE */ VTBL_ENTRY void OnKifaceEnd() = 0; -#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top. - /** * Function CreateWindow * creates a wxWindow for the current project. The caller @@ -199,7 +198,7 @@ struct KIFACE * not contained in the caller's link image. */ VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, int aClassId, - KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; + KIWAY* aKIWAY, int aCtlBits ) = 0; /** * Function IfaceOrAddress @@ -249,7 +248,7 @@ class KIWAY : public wxEvtHandler { public: - /// DSO players on *this* KIWAY + /// Possible KIFACEs on *this* KIWAY enum FACE_T { FACE_SCH, ///< eeschema DSO @@ -257,6 +256,7 @@ public: FACE_PCB, ///< pcbnew DSO // FACE_MOD, FACE_CVPCB, + FACE_BMP2CMP, FACE_GERBVIEW, FACE_PL_EDITOR, @@ -265,41 +265,28 @@ public: FACE_COUNT, ///< how many KIWAY player types }; - /* from edaappl.h, now pgm_base.h, obsoleted by above FACE_T enum. - enum PGM_BASE_T - { - APP_UNKNOWN, - APP_EESCHEMA, - APP_PCBNEW, - APP_CVPCB, - APP_GERBVIEW, - APP_KICAD, - APP_PL_EDITOR, - APP_BM2CMP, - }; - */ + // If you change the vtable, recompile all of KiCad. - // Don't change the order of these VTBL_ENTRYs, add new ones at the end, - // unless you recompile all of KiCad. - VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad ); + /** + * Function KiFACE + * returns the KIFACE* given a FACE_T. If it is not already loaded, the + * KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart() + */ + VTBL_ENTRY KIFACE* KiFACE( PGM_BASE* aProgram, + FACE_T aFaceId, bool doLoad = true ); + VTBL_ENTRY PROJECT& Prj() const; KIWAY(); private: - /* - /// Get the name of the DSO holding the requested FACE_T. - static const wxString dso_name( FACE_T aFaceId ); - */ - - // one for each FACE_T - static wxDynamicLibrary s_sch_dso; - static wxDynamicLibrary s_pcb_dso; - //static wxDynamicLibrary s_cvpcb_dso; // will get merged into pcbnew + /// Get the full path & name of the DSO holding the requested FACE_T. + static const wxString dso_full_path( FACE_T aFaceId ); KIFACE* m_kiface[FACE_COUNT]; + int m_kiface_version[FACE_COUNT]; PROJECT m_project; // do not assume this is here, use Prj(). }; diff --git a/include/kiway_mgr.h b/include/kiway_mgr.h new file mode 100644 index 0000000000..4dde97c65f --- /dev/null +++ b/include/kiway_mgr.h @@ -0,0 +1,68 @@ + +#ifndef KIWAY_MGR_H_ +#define KIWAY_MGR_H_ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.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 + */ + + +#include +#include + + +/** + * Class KIWAY_MGR + * is a container for all KIWAYS [and PROJECTS]. This class needs to work both + * for a C++ project manager and an a wxPython one (after being moved into a + * header later). + */ +class KIWAY_MGR +{ +public: + //KIWAY_MGR(); + // ~KIWAY_MGR(); + + bool OnStart( wxApp* aProcess ); + + void OnEnd(); + + KIWAY& operator[]( int aIndex ) + { + wxASSERT( m_kiways.size() ); // stuffed in OnStart() + return m_kiways[aIndex]; + } + +private: + + // KIWAYs may not be moved once doled out, since window DNA depends on the + // pointer being good forever. + // boost_ptr::vector however never moves the object pointed to. + typedef boost::ptr_vector KIWAYS; + + KIWAYS m_kiways; +}; + +extern KIWAY_MGR Kiways; + +#endif // KIWAY_MGR_H_ diff --git a/include/kiway_player.h b/include/kiway_player.h index b61b6f195c..15d8489615 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -130,7 +130,7 @@ public: *

* Each derived class should handle this in a way specific to its needs. * No prompting is done inside here for any file or project. There should be - * need to call this with aFileList which is empty. However, calling it with + * no need to call this with aFileList which is empty. However, calling it with * a single filename which does not exist should indicate to the implementor * that a new session is being started and that the given name is the desired * name for the data file at time of save. @@ -166,4 +166,51 @@ public: } }; + +// psuedo code for OpenProjectFiles +#if 0 + +bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) +{ + if( aFileList.size() != 1 ) + { + complain via UI. + return false + } + + assert( aFileList[0] is absolute ) // bug in single_top.cpp or project manager. + + if (window does not support appending) || !(aCtl & KICTL_OPEN_APPEND) + { + close any currently open project files. + } + + if( aFileList[0] does not exist ) + { + notify user file does not exist. + + create an empty project file + mark file as modified. + + use the default project config file. + } + else + { + load aFileList[0] + + use the project config file for project given by aFileList[0]s full path. + } + + UpdateTitle(); + + show contents. +} + + + +#endif + + + + #endif // KIWAY_PLAYER_H_ diff --git a/kicad/commandframe.cpp b/kicad/commandframe.cpp index ca53048b0c..1dc1b03d6b 100644 --- a/kicad/commandframe.cpp +++ b/kicad/commandframe.cpp @@ -59,7 +59,7 @@ int LAUNCHER_PANEL::GetPanelHeight() const * Function CreateCommandToolbar * create the buttons to call Eeschema CvPcb, Pcbnew and GerbView */ -void LAUNCHER_PANEL::CreateCommandToolbar( void ) +void LAUNCHER_PANEL::CreateCommandToolbar() { wxBitmapButton* btn; diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index f6799d015f..028b1aff91 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -28,10 +28,11 @@ */ +#include #include - +#include #include -#include +#include #include #include #include @@ -40,6 +41,40 @@ #include + +/// Extend LIB_ENV_VAR list with the directory from which I came, prepending it. +static void set_lib_env_var( const wxString& aAbsoluteArgv0 ) +{ + // POLICY CHOICE 2: Keep same path, so that installer MAY put the + // "subsidiary DSOs" in the same directory as the kiway top process modules. + // A subsidiary shared library is one that is not a top level DSO, but rather + // some shared library that a top level DSO needs to even be loaded. It is + // a static link to a shared object from a top level DSO. + + // This directory POLICY CHOICE 2 is not the only dir in play, since LIB_ENV_VAR + // has numerous path options in it, as does DSO searching on linux, windows, and OSX. + // See "man ldconfig" on linux. What's being done here is for quick installs + // into a non-standard place, and especially for Windows users who may not + // know what the PATH environment variable is or how to set it. + + wxFileName fn( aAbsoluteArgv0 ); + + wxString ld_path( LIB_ENV_VAR ); + wxString my_path = fn.GetPath(); + wxString new_paths = PrePendPath( ld_path, my_path ); + + wxSetEnv( ld_path, new_paths ); + +#if defined(DEBUG) + { + wxString test; + wxGetEnv( ld_path, &test ); + printf( "LIB_ENV_VAR:'%s'\n", TO_UTF8( test ) ); + } +#endif +} + + // a dummy to quiet linking with EDA_BASE_FRAME::config(); #include KIFACE_I& Kiface() @@ -62,7 +97,6 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) m_bm.Init(); -#if 0 // copied from single_top.c, possibly for milestone B) wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath(); if( !wxIsAbsolutePath( absoluteArgv0 ) ) @@ -71,10 +105,9 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) return false; } - // Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the - // KIFACE has hard dependencies on subsidiary DSOs below it. - SetLibEnvVar( absoluteArgv0 ); -#endif + // Set LIB_ENV_VAR *before* loading the KIFACE DSOs, in case they have hard + // dependencies on subsidiary DSOs below it. + set_lib_env_var( absoluteArgv0 ); if( !initPgm() ) return false; @@ -218,39 +251,7 @@ void PGM_KICAD::destroy() } -/** - * Class KIWAY_MGR - * is a container for all KIWAYS [and PROJECTS]. This class needs to work both - * for a C++ project manager and an a wxPython one (after being moved into a - * header later). - */ -class KIWAY_MGR -{ -public: - //KIWAY_MGR(); - // ~KIWAY_MGR(); - - bool OnStart( wxApp* aProcess ); - - void OnEnd(); - - KIWAY& operator[]( int aIndex ) - { - wxASSERT( m_kiways.size() ); // stuffed in OnStart() - return m_kiways[aIndex]; - } - -private: - - // KIWAYs may not be moved once doled out, since window DNA depends on the - // pointer being good forever. - // boost_ptr::vector however never moves the object pointed to. - typedef boost::ptr_vector KIWAYS; - - KIWAYS m_kiways; -}; - -static KIWAY_MGR kiways; +KIWAY_MGR Kiways; /** @@ -261,7 +262,7 @@ struct APP_KICAD : public wxApp { bool OnInit() // overload wxApp virtual { - if( kiways.OnStart( this ) ) + if( Kiways.OnStart( this ) ) { return Pgm().OnPgmInit( this ); } @@ -270,7 +271,7 @@ struct APP_KICAD : public wxApp int OnExit() // overload wxApp virtual { - kiways.OnEnd(); + Kiways.OnEnd(); Pgm().OnPgmExit(); @@ -296,7 +297,7 @@ IMPLEMENT_APP( APP_KICAD ); // this link image need this function. PROJECT& Prj() { - return kiways[0].Prj(); + return Kiways[0].Prj(); } diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index e74c471dc1..d75e25f5ed 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include #include @@ -238,10 +240,23 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) legacy_board.SetExt( LegacyPcbFileExtension ); kicad_board.SetExt( KiCadPcbFileExtension ); - if( !legacy_board.FileExists() || kicad_board.FileExists() ) - Execute( this, PCBNEW_EXE, QuoteFullPath( kicad_board ) ); - else - Execute( this, PCBNEW_EXE, QuoteFullPath( legacy_board ) ); + wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ? + kicad_board : legacy_board; + + +#if 0 // it works! + KIFACE* kiface = Kiways[0].KiFACE( &Pgm(), KIWAY::FACE_PCB ); + + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( this, PCB_FRAME_TYPE, &Kiways[0], KFCTL_PROJECT_SUITE ); + + frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); + + frame->Show( true ); + frame->Raise(); + +#else + Execute( this, PCBNEW_EXE, QuoteFullPath( board ) ); +#endif } diff --git a/pagelayout_editor/pl_editor.cpp b/pagelayout_editor/pl_editor.cpp index b96b07d4aa..a72ee92505 100644 --- a/pagelayout_editor/pl_editor.cpp +++ b/pagelayout_editor/pl_editor.cpp @@ -54,7 +54,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -126,9 +126,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/pcb_calculator/pcb_calculator.cpp b/pcb_calculator/pcb_calculator.cpp index cfec7e2135..31f27c7a61 100644 --- a/pcb_calculator/pcb_calculator.cpp +++ b/pcb_calculator/pcb_calculator.cpp @@ -55,7 +55,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -117,9 +117,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); return true; } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index b957b10db6..de2c27b58f 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -194,7 +194,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); editor->Show( true ); editor->Zoom_Automatique( false ); @@ -220,7 +222,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !viewer ) { - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); @@ -839,7 +843,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() ); diff --git a/pcbnew/editmod.cpp b/pcbnew/editmod.cpp index 7eed255d4c..a7cc3cbe74 100644 --- a/pcbnew/editmod.cpp +++ b/pcbnew/editmod.cpp @@ -78,7 +78,9 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( Module ); diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 5aeaf4e4da..4192e44445 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -39,9 +39,6 @@ #include #include -/** - * Pcbnew mainframe menubar - */ void PCB_EDIT_FRAME::ReCreateMenuBar() { wxString text; @@ -49,7 +46,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() wxFileHistory& fhist = Kiface().GetFileHistory(); - if( ! menuBar ) + if( !menuBar ) menuBar = new wxMenuBar(); // Delete all existing menus so they can be rebuilt. @@ -64,17 +61,19 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() // Create File Menu wxMenu* filesMenu = new wxMenu; - // New - AddMenuItem( filesMenu, ID_NEW_BOARD, - _( "&New" ), - _( "Clear current board and initialize a new one" ), - KiBitmap( new_pcb_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( filesMenu, ID_NEW_BOARD, + _( "&New" ), + _( "Clear current board and initialize a new one" ), + KiBitmap( new_pcb_xpm ) ); - // Open - text = AddHotkeyName( _( "&Open" ), g_Board_Editor_Hokeys_Descr, HK_LOAD_BOARD ); - AddMenuItem( filesMenu, ID_LOAD_FILE, text, - _( "Delete current board and load new board" ), - KiBitmap( open_brd_file_xpm ) ); + // Open + text = AddHotkeyName( _( "&Open" ), g_Board_Editor_Hokeys_Descr, HK_LOAD_BOARD ); + AddMenuItem( filesMenu, ID_LOAD_FILE, text, + _( "Delete current board and load new board" ), + KiBitmap( open_brd_file_xpm ) ); + } // Load Recent submenu static wxMenu* openRecentMenu; @@ -89,44 +88,46 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() fhist.UseMenu( openRecentMenu ); fhist.AddFilesToMenu(); - AddMenuItem( filesMenu, openRecentMenu, - -1, _( "Open &Recent" ), - _( "Open a recent opened board" ), - KiBitmap( open_project_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( filesMenu, openRecentMenu, + -1, _( "Open &Recent" ), + _( "Open a recent opened board" ), + KiBitmap( open_project_xpm ) ); + } - // Pcbnew Board AddMenuItem( filesMenu, ID_APPEND_FILE, _( "&Append Board" ), _( "Append another Pcbnew board to the current loaded board" ), KiBitmap( import_xpm ) ); filesMenu->AppendSeparator(); - // Save text = AddHotkeyName( _( "&Save" ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD ); AddMenuItem( filesMenu, ID_SAVE_BOARD, text, _( "Save current board" ), KiBitmap( save_xpm ) ); - // Save As - text = AddHotkeyName( _( "Sa&ve As..." ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD_AS ); - AddMenuItem( filesMenu, ID_SAVE_BOARD_AS, text, - _( "Save the current board as..." ), - KiBitmap( save_as_xpm ) ); - filesMenu->AppendSeparator(); + if( Kiface().IsSingle() ) // not when under a project mgr + { + text = AddHotkeyName( _( "Sa&ve As..." ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD_AS ); + AddMenuItem( filesMenu, ID_SAVE_BOARD_AS, text, + _( "Save the current board as..." ), + KiBitmap( save_as_xpm ) ); + filesMenu->AppendSeparator(); + } - // Revert AddMenuItem( filesMenu, ID_MENU_READ_BOARD_BACKUP_FILE, _( "Revert to Last" ), _( "Clear board and get previous backup version of board" ), KiBitmap( help_xpm ) ); - // Rescue - AddMenuItem( filesMenu, ID_MENU_RECOVER_BOARD_AUTOSAVE, _( "Rescue" ), - _( "Clear board and get last rescue file automatically saved by Pcbnew" ), - KiBitmap( help_xpm ) ); + AddMenuItem( filesMenu, ID_MENU_RECOVER_BOARD_AUTOSAVE, + _( "Rescue" ), + _( "Clear board and get last rescue file automatically saved by Pcbnew" ), + KiBitmap( help_xpm ) ); filesMenu->AppendSeparator(); - /* Fabrication Outputs submenu */ + //----- Fabrication Outputs submenu ----------------------------------------- wxMenu* fabricationOutputsMenu = new wxMenu; AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_POS_MODULES_FILE, _( "&Modules Position (.pos) File" ), @@ -138,40 +139,34 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Generate excellon2 drill file" ), KiBitmap( post_drill_xpm ) ); - // Module Report AddMenuItem( fabricationOutputsMenu, ID_GEN_EXPORT_FILE_MODULE_REPORT, _( "&Module (.rpt) Report" ), _( "Create a report of all modules on the current board" ), KiBitmap( tools_xpm ) ); AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_D356_FILE, - _( "IPC-D-356 Netlist File" ), - _( "Generate IPC-D-356 netlist file" ), - KiBitmap( netlist_xpm ) ); + _( "IPC-D-356 Netlist File" ), + _( "Generate IPC-D-356 netlist file" ), + KiBitmap( netlist_xpm ) ); - // Component File AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_CMP_FILE, _( "&Component (.cmp) File" ), _( "(Re)create components file (*.cmp) for CvPcb" ), KiBitmap( create_cmp_file_xpm ) ); - // BOM File AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_BOM_FILE_FROM_BOARD, _( "&BOM File" ), _( "Create a bill of materials from schematic" ), KiBitmap( bom_xpm ) ); - // Fabrications Outputs submenu append AddMenuItem( filesMenu, fabricationOutputsMenu, -1, _( "&Fabrication Outputs" ), _( "Generate files for fabrication" ), KiBitmap( fabrication_xpm ) ); - - /** Import submenu **/ + //----- Import submenu ------------------------------------------------------ wxMenu* submenuImport = new wxMenu(); - // Specctra Session AddMenuItem( submenuImport, ID_GEN_IMPORT_SPECCTRA_SESSION, _( "&Specctra Session" ), _( "Import a routed \"Specctra Session\" (*.ses) file" ), @@ -187,27 +182,23 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Import files" ), KiBitmap( import_xpm ) ); - /** Export submenu **/ + //----- Export submenu ------------------------------------------------------ wxMenu* submenuexport = new wxMenu(); - // Specctra DSN AddMenuItem( submenuexport, ID_GEN_EXPORT_SPECCTRA, _( "&Specctra DSN" ), _( "Export the current board to a \"Specctra DSN\" file" ), KiBitmap( export_dsn_xpm ) ); - // GenCAD AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_GENCADFORMAT, _( "&GenCAD" ), _( "Export GenCAD format" ), KiBitmap( export_xpm ) ); - // VRML AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_VRML, _( "&VRML" ), _( "Export a VRML board representation" ), KiBitmap( three_d_xpm ) ); - // IDF3 AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_IDF3, _( "I&DFv3 Export" ), _( "IDFv3 board and component export" ), KiBitmap( export_idf_xpm ) ); @@ -218,24 +209,20 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() filesMenu->AppendSeparator(); - // Page settings AddMenuItem( filesMenu, ID_SHEET_SET, _( "Page s&ettings" ), _( "Page settings for paper size and texts" ), KiBitmap( sheetset_xpm ) ); - // Print AddMenuItem( filesMenu, wxID_PRINT, _( "&Print" ), _( "Print board" ), KiBitmap( print_button_xpm ) ); - // Create SVG file AddMenuItem( filesMenu, ID_GEN_PLOT_SVG, _( "Export SV&G" ), _( "Export a board file in Scalable Vector Graphics format" ), KiBitmap( plot_svg_xpm ) ); - // Plot AddMenuItem( filesMenu, ID_GEN_PLOT, _( "P&lot" ), _( "Plot board in HPGL, PostScript or Gerber RS-274X format)" ), @@ -243,15 +230,14 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() filesMenu->AppendSeparator(); + //----- archive submenu ----------------------------------------------------- wxMenu* submenuarchive = new wxMenu(); - // Archive New Footprints AddMenuItem( submenuarchive, ID_MENU_ARCHIVE_NEW_MODULES, _( "&Archive New Footprints" ), _( "Archive new footprints only in a library (keep other footprints in this lib)" ), KiBitmap( library_update_xpm ) ); - // Create FootPrint Archive AddMenuItem( submenuarchive, ID_MENU_ARCHIVE_ALL_MODULES, _( "&Create Footprint Archive" ), _( "Archive all footprints in a library (old library will be deleted)" ), @@ -263,54 +249,45 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Archive or add footprints in a library file" ), KiBitmap( library_xpm ) ); - // Quit filesMenu->AppendSeparator(); AddMenuItem( filesMenu, wxID_EXIT, _( "&Quit" ), _( "Quit Pcbnew" ), KiBitmap( exit_xpm ) ); - /** Create Edit menu **/ + //----- Edit menu ----------------------------------------------------------- wxMenu* editMenu = new wxMenu; - // Undo text = AddHotkeyName( _( "&Undo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_UNDO ); AddMenuItem( editMenu, wxID_UNDO, text, HELP_UNDO, KiBitmap( undo_xpm ) ); - // Redo text = AddHotkeyName( _( "&Redo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_REDO ); AddMenuItem( editMenu, wxID_REDO, text, HELP_REDO, KiBitmap( redo_xpm ) ); - // Delete AddMenuItem( editMenu, ID_PCB_DELETE_ITEM_BUTT, _( "&Delete" ), _( "Delete items" ), KiBitmap( delete_xpm ) ); editMenu->AppendSeparator(); - // Find text = AddHotkeyName( _( "&Find" ), g_Pcbnew_Editor_Hokeys_Descr, HK_FIND_ITEM ); AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND , KiBitmap( find_xpm ) ); editMenu->AppendSeparator(); - // Global Deletions AddMenuItem( editMenu, ID_PCB_GLOBAL_DELETE, _( "&Global Deletions" ), _( "Delete tracks, modules, texts... on board" ), KiBitmap( general_deletions_xpm ) ); - // Cleanup Tracks and Vias AddMenuItem( editMenu, ID_MENU_PCB_CLEAN, _( "&Cleanup Tracks and Vias" ), _( "Clean stubs, vias, delete break points, or connect dangling tracks to pads and vias" ), KiBitmap( delete_xpm ) ); - // Swap Layers AddMenuItem( editMenu, ID_MENU_PCB_SWAP_LAYERS, _( "&Swap Layers" ), _( "Swap tracks on copper layers or drawings on other layers" ), KiBitmap( swap_layer_xpm ) ); - // Reset module reference sizes AddMenuItem( editMenu, ID_MENU_PCB_RESET_TEXTMODULE_FIELDS_SIZES, _( "&Reset Module Field Sizes" ), _( "Reset text size and width of all module fields to current defaults" ), @@ -323,7 +300,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Interactive router push&shove tool." ), KiBitmap( ps_router_xpm ) ); - /** Create View menu **/ + //----- View menu ----------------------------------------------------------- wxMenu* viewMenu = new wxMenu; /* Important Note for ZOOM IN and ZOOM OUT commands from menubar: @@ -337,104 +314,84 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() * in other words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators * for Zoom in and Zoom out sub menus */ - // Zoom In text = AddHotkeyName( _( "Zoom &In" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_IN, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); - // Zoom Out text = AddHotkeyName( _( "Zoom &Out" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_OUT, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); - // Fit on Screen text = AddHotkeyName( _( "&Fit on Screen" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_AUTO ); - AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) ); viewMenu->AppendSeparator(); - // Redraw text = AddHotkeyName( _( "&Redraw" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_REDRAW ); - AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) ); viewMenu->AppendSeparator(); - // 3D Display AddMenuItem( viewMenu, ID_MENU_PCB_SHOW_3D_FRAME, _( "&3D Display" ),_( "Show board in 3D viewer" ), KiBitmap( three_d_xpm ) ); - // List Nets AddMenuItem( viewMenu, ID_MENU_LIST_NETS, _( "&List Nets" ), _( "View a list of nets with names and id's" ), KiBitmap( tools_xpm ) ); - // Switching GAL-based canvas on/off viewMenu->AppendSeparator(); text = AddHotkeyName( _( "&Switch canvas to default" ), g_Pcbnew_Editor_Hokeys_Descr, HK_CANVAS_DEFAULT, IS_ACCELERATOR ); - AddMenuItem( viewMenu, ID_MENU_CANVAS_DEFAULT, text, _( "Switch the canvas implementation to default" ), KiBitmap( tools_xpm ) ); text = AddHotkeyName( _( "&Switch canvas to OpenGL" ), g_Pcbnew_Editor_Hokeys_Descr, HK_CANVAS_OPENGL, IS_ACCELERATOR ); - AddMenuItem( viewMenu, ID_MENU_CANVAS_OPENGL, text, _( "Switch the canvas implementation to OpenGL" ), KiBitmap( tools_xpm ) ); text = AddHotkeyName( _( "&Switch canvas to Cairo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_CANVAS_CAIRO, IS_ACCELERATOR ); - AddMenuItem( viewMenu, ID_MENU_CANVAS_CAIRO, text, _( "Switch the canvas implementation to Cairo" ), KiBitmap( tools_xpm ) ); - /** Create Place Menu **/ + //----- Place Menu ---------------------------------------------------------- wxMenu* placeMenu = new wxMenu; - // Module text = AddHotkeyName( _( "&Module" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ADD_MODULE, IS_ACCELERATOR ); AddMenuItem( placeMenu, ID_PCB_MODULE_BUTT, text, _( "Add modules" ), KiBitmap( module_xpm ) ); - // Track text = AddHotkeyName( _( "&Track" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK, IS_ACCELERATOR ); AddMenuItem( placeMenu, ID_TRACK_BUTT, text, _( "Add tracks and vias" ), KiBitmap( add_tracks_xpm ) ); - // Zone AddMenuItem( placeMenu, ID_PCB_ZONES_BUTT, _( "&Zone" ), _( "Add filled zones" ), KiBitmap( add_zone_xpm ) ); - // Keepout areas AddMenuItem( placeMenu, ID_PCB_KEEPOUT_AREA_BUTT, _( "&Keepout Area" ), _( "Add keepout areas" ), KiBitmap( add_keepout_area_xpm ) ); - // Text AddMenuItem( placeMenu, ID_PCB_ADD_TEXT_BUTT, _( "Te&xt" ), _( "Add text on copper layers or graphic text" ), KiBitmap( add_text_xpm ) ); - // Graphic Arc AddMenuItem( placeMenu, ID_PCB_ARC_BUTT, _( "&Arc" ), _( "Add graphic arc" ),KiBitmap( add_arc_xpm ) ); - // Graphic Circle AddMenuItem( placeMenu, ID_PCB_CIRCLE_BUTT, _( "&Circle" ), _( "Add graphic circle" ), KiBitmap( add_circle_xpm ) ); - // Line or Polygon AddMenuItem( placeMenu, ID_PCB_ADD_LINE_BUTT, _( "&Line or Polygon" ), _( "Add graphic line or polygon" ), @@ -442,34 +399,29 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() placeMenu->AppendSeparator(); - // Dimension AddMenuItem( placeMenu, ID_PCB_DIMENSION_BUTT, _( "&Dimension" ), _( "Add dimension" ), KiBitmap( add_dimension_xpm ) ); - // Layer alignment target AddMenuItem( placeMenu, ID_PCB_MIRE_BUTT, _( "La&yer alignment target" ), _( "Add layer alignment target" ), KiBitmap( add_mires_xpm ) ); placeMenu->AppendSeparator(); - // Drill & Place Offset AddMenuItem( placeMenu, ID_PCB_PLACE_OFFSET_COORD_BUTT, _( "Drill and Place O&ffset" ), _( "Place the origin point for drill and place files" ), KiBitmap( pcb_offset_xpm ) ); - // Grid Origin AddMenuItem( placeMenu, ID_PCB_PLACE_GRID_COORD_BUTT, _( "&Grid Origin" ), _( "Set the origin point for the grid" ), KiBitmap( grid_select_axis_xpm ) ); - /* Create Preferences and configuration menu */ + //----- Preferences and configuration menu------------------------------------ wxMenu* configmenu = new wxMenu; - // Library AddMenuItem( configmenu, ID_PCB_LIB_TABLE_EDIT, _( "Li&brary Tables" ), _( "Setup footprint libraries" ), KiBitmap( library_table_xpm ) ); @@ -487,7 +439,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() HELP_SHOW_HIDE_MICROWAVE_TOOLS, KiBitmap( mw_toolbar_xpm ) ); - // General #ifdef __WXMAC__ configmenu->Append(wxID_PREFERENCES); @@ -497,52 +448,44 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() KiBitmap( preference_xpm ) ); #endif - // Display AddMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ), _( "Select how items (pads, tracks texts ... ) are displayed" ), KiBitmap( display_options_xpm ) ); - // Create sizes and dimensions submenu + //--- dimensions submenu ------------------------------------------------------ wxMenu* dimensionsMenu = new wxMenu; - // Grid AddMenuItem( dimensionsMenu, ID_PCB_USER_GRID_SETUP, _( "G&rid" ),_( "Adjust user grid dimensions" ), KiBitmap( grid_xpm ) ); - // Text and Drawings AddMenuItem( dimensionsMenu, ID_PCB_DRAWINGS_WIDTHS_SETUP, _( "Te&xts and Drawings" ), _( "Adjust dimensions for texts and drawings" ), KiBitmap( options_text_xpm ) ); - // Pads AddMenuItem( dimensionsMenu, ID_PCB_PAD_SETUP, _( "&Pads" ), _( "Adjust default pad characteristics" ), KiBitmap( pad_dimensions_xpm ) ); - // Pads Mask Clearance AddMenuItem( dimensionsMenu, ID_PCB_MASK_CLEARANCE, _( "Pads &Mask Clearance" ), _( "Adjust the global clearance between pads and the solder resist mask" ), KiBitmap( pads_mask_layers_xpm ) ); - // Save dimension preferences dimensionsMenu->AppendSeparator(); AddMenuItem( dimensionsMenu, ID_CONFIG_SAVE, _( "&Save" ), _( "Save dimension preferences" ), KiBitmap( save_xpm ) ); - // Language submenu Pgm().AddMenuLanguageList( configmenu ); // Hotkey submenu AddHotkeyConfigMenu( configmenu ); - - // Macros submenu + //--- Macros submenu -------------------------------------------------------- wxMenu* macrosMenu = new wxMenu; AddMenuItem( macrosMenu, ID_PREFRENCES_MACROS_SAVE, @@ -555,7 +498,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Read macros from file" ), KiBitmap( read_setup_xpm ) ); - // Append macros menu to config menu AddMenuItem( configmenu, macrosMenu, -1, _( "Ma&cros" ), _( "Macros save/read operations" ), @@ -563,75 +505,58 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() configmenu->AppendSeparator(); - // Save Preferences AddMenuItem( configmenu, ID_CONFIG_SAVE, _( "&Save Preferences" ), _( "Save application preferences" ), KiBitmap( save_setup_xpm ) ); - // Read Preferences AddMenuItem( configmenu, ID_CONFIG_READ, _( "&Read Preferences" ), _( "Read application preferences" ), KiBitmap( read_setup_xpm ) ); - /** - * Tools menu - */ + //----- Tools menu ---------------------------------------------------------- wxMenu* toolsMenu = new wxMenu; - /* Netlist */ AddMenuItem( toolsMenu, ID_GET_NETLIST, _( "&Netlist" ), _( "Read the netlist and update board connectivity" ), KiBitmap( netlist_xpm ) ); - /* Layer pair */ AddMenuItem( toolsMenu, ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, _( "&Layer Pair" ), _( "Change the active layer pair" ), KiBitmap( select_layer_pair_xpm ) ); - /* DRC */ AddMenuItem( toolsMenu, ID_DRC_CONTROL, _( "&DRC" ), _( "Perform design rules check" ), KiBitmap( erc_xpm ) ); - /* FreeRoute */ AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_FREEROUTE_ACCESS, _( "&FreeRoute" ), _( "Fast access to the Web Based FreeROUTE advanced router" ), KiBitmap( web_support_xpm ) ); -#ifdef KICAD_SCRIPTING_WXPYTHON - /* Scripting */ +#if defined(KICAD_SCRIPTING_WXPYTHON) AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, _( "&Scripting Console" ), _( "Show/Hide the Scripting console" ), KiBitmap( book_xpm ) ); #endif - /* Design Rules menu - */ wxMenu* designRulesMenu = new wxMenu; - // Design Rules AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, _( "Design Rules" ), _( "Open the design rules editor" ), KiBitmap( hammer_xpm ) ); - // Layers Setup AddMenuItem( designRulesMenu, ID_PCB_LAYERS_SETUP, _( "&Layers Setup" ), _( "Enable and set layer properties" ), KiBitmap( copper_layers_setup_xpm ) ); - /** - * Help menu - */ wxMenu* helpMenu = new wxMenu; AddHelpVersionInfoMenuEntry( helpMenu ); - // Contents AddMenuItem( helpMenu, wxID_HELP, _( "&Contents" ), _( "Open the Pcbnew handbook" ), @@ -642,16 +567,13 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Open the \"Getting Started in KiCad\" guide for beginners" ), KiBitmap( help_xpm ) ); - // About helpMenu->AppendSeparator(); AddMenuItem( helpMenu, wxID_ABOUT, _( "&About Pcbnew" ), _( "About Pcbnew printed circuit board designer" ), KiBitmap( info_xpm ) ); - /** - * Append all menus to the menuBar - */ + // Append all menus to the menuBar menuBar->Append( filesMenu, _( "&File" ) ); menuBar->Append( editMenu, _( "&Edit" ) ); menuBar->Append( viewMenu, _( "&View" ) ); diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 2729504ab1..22ef70221e 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -271,7 +271,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( top_project ); if( !viewer ) { - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 71918b8ef3..e815ed705a 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -85,9 +85,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) - EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, PCB_EDIT_FRAME::OnSockRequestServer ) - EVT_SOCKET( ID_EDA_SOCKET_EVENT, PCB_EDIT_FRAME::OnSockRequest ) - EVT_COMBOBOX( ID_ON_ZOOM_SELECT, PCB_EDIT_FRAME::OnSelectZoom ) EVT_COMBOBOX( ID_ON_GRID_SELECT, PCB_EDIT_FRAME::OnSelectGrid ) @@ -450,7 +447,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); -#ifdef KICAD_SCRIPTING_WXPYTHON +#if defined(KICAD_SCRIPTING_WXPYTHON) // Add the scripting panel EDA_PANEINFO pythonAuiInfo; pythonAuiInfo.ScriptingToolbarPane(); @@ -831,7 +828,7 @@ void PCB_EDIT_FRAME::SetGridColor(EDA_COLOR_T aColor) } -bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) +bool PCB_EDIT_FRAME::IsMicroViaAcceptable() { int copperlayercnt = GetBoard()->GetCopperLayerCount( ); LAYER_NUM currLayer = getActiveLayer(); @@ -1106,7 +1103,7 @@ void PCB_EDIT_FRAME::UpdateTitle() SetTitle( title ); } -#ifdef KICAD_SCRIPTING_WXPYTHON +#if defined(KICAD_SCRIPTING_WXPYTHON) void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) { if ( m_pythonPanelHidden ) @@ -1171,4 +1168,3 @@ void PCB_EDIT_FRAME::SetRotationAngle( int aRotationAngle ) m_rotationAngle = aRotationAngle; } - diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index c9a4129e1b..98e5a5b660 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -101,7 +101,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -116,14 +116,16 @@ static struct IFACE : public KIFACE_I frame->Zoom_Automatique( true ); -#ifdef KICAD_SCRIPTING +#if defined(KICAD_SCRIPTING) // give the scripting helpers access to our frame ScriptingSetPcbEditFrame( frame ); #endif - // @todo temporarily here - CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER ); - + if( Kiface().IsSingle() ) + { + // only run this under single_top, not under a project manager. + CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER ); + } return frame; } break; @@ -141,7 +143,6 @@ static struct IFACE : public KIFACE_I /* Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); */ - return frame; } break; @@ -159,7 +160,6 @@ static struct IFACE : public KIFACE_I /* Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); */ - return frame; } break; @@ -411,13 +411,13 @@ static bool scriptingSetup() FP_LIB_TABLE GFootprintTable; -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 028c632568..a9703a5450 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -234,9 +234,10 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest() { NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); - if( net == NULL ) //Should not occur + if( !net ) // Should not occur { - wxMessageBox( wxT( "Build_Board_Ratsnest() error: net not found" ) ); + UTF8 msg = StrPrintf( "%s: error, net %d not found", __func__, current_net_code ); + wxMessageBox( msg ); // BTW, it does happen. return; } From ee3e97e6cabab7de390a3e5cb810cc406302408d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nick=20=C3=98stergaard?= Date: Sat, 19 Apr 2014 18:05:58 +0200 Subject: [PATCH 03/36] Fix vertical offset for multiline text in VRML exporter. --- pcbnew/exporters/export_vrml.cpp | 40 +++++++++++++++----------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index ae1b37c194..5962ba276b 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -600,38 +600,36 @@ static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text ) if( text->IsMirrored() ) NEGATE( size.x ); + EDA_COLOR_T color = BLACK; // not actually used, but needed by DrawGraphicText + if( text->IsMultilineAllowed() ) { - wxPoint pos = text->GetTextPosition(); wxArrayString* list = wxStringSplit( text->GetText(), '\n' ); - wxPoint offset; + std::vector positions; + positions.reserve( list->Count() ); + text->GetPositionsOfLinesOfMultilineText( positions, list->Count() ); - offset.y = text->GetInterline(); - - RotatePoint( &offset, text->GetOrientation() ); - - for( unsigned i = 0; iCount(); i++ ) + for( unsigned ii = 0; ii < list->Count(); ii++ ) { - wxString txt = list->Item( i ); - DrawGraphicText( NULL, NULL, pos, BLACK, - txt, text->GetOrientation(), size, - text->GetHorizJustify(), text->GetVertJustify(), - text->GetThickness(), text->IsItalic(), - true, - vrml_text_callback ); - pos += offset; + wxString txt = list->Item( ii ); + DrawGraphicText( NULL, NULL, positions[ii], color, + txt, text->GetOrientation(), size, + text->GetHorizJustify(), text->GetVertJustify(), + text->GetThickness(), text->IsItalic(), + true, + vrml_text_callback ); } delete (list); } else { - DrawGraphicText( NULL, NULL, text->GetTextPosition(), BLACK, - text->GetText(), text->GetOrientation(), size, - text->GetHorizJustify(), text->GetVertJustify(), - text->GetThickness(), text->IsItalic(), - true, - vrml_text_callback ); + DrawGraphicText( NULL, NULL, text->GetTextPosition(), color, + text->GetText(), text->GetOrientation(), size, + text->GetHorizJustify(), text->GetVertJustify(), + text->GetThickness(), text->IsItalic(), + true, + vrml_text_callback ); } } From 0d6560a2182e1d70c563b7272cc6386319be02a7 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 19 Apr 2014 13:47:20 -0500 Subject: [PATCH 04/36] *) Switch kicad.exe to using KIFACE modules for all major top level windows. Eeschema, Pcbnew, and Cvpcb all run under the same process now, FOR THE VERY FIRST TIME! *) Added KIWAY::PlayerCreate(), PlayerClose(), and PlayersClose(). *) Factored FRAME_T into from ID_DRAWFRAME_TYPE. *) Found that the following command line is helpful for collecting all the *.kiface files into the /kicad/ directory so that kicad can find them. $ cp `find . -name '*.kiface'` kicad/ Maybe somebody will want to rework how the CMake files are organized so all the binaries can go into the same place. See python-a-mingw-us. *) This might fix the problem on the Mac where child process windows were not coming to the front. See ->Raise() in kicad/mainframe.cpp. *) You can set USE_KIFACE to 0 in kicad/mainframe.cpp to chain load child exes instead of using the KIFACE modules directly, i.e. revert. --- 3d-viewer/3d_frame.cpp | 2 +- common/basicframe.cpp | 2 +- common/draw_frame.cpp | 2 +- common/kiway.cpp | 140 ++++++++++++++++++++++--- common/single_top.cpp | 8 +- cvpcb/CMakeLists.txt | 2 +- cvpcb/class_DisplayFootprintsFrame.cpp | 2 +- cvpcb/cvframe.cpp | 2 +- cvpcb/cvpcb.cpp | 2 +- eeschema/CMakeLists.txt | 4 +- eeschema/eeschema.cpp | 4 +- eeschema/lib_pin.cpp | 2 +- eeschema/libeditframe.cpp | 2 +- eeschema/sch_base_frame.cpp | 2 +- eeschema/schframe.cpp | 4 +- eeschema/viewlib_frame.cpp | 2 +- gerbview/CMakeLists.txt | 2 +- gerbview/gerbview.cpp | 2 +- gerbview/gerbview_frame.cpp | 2 +- include/draw_frame.h | 2 +- include/frame_type.h | 32 ++++++ include/kiway.h | 92 +++++++++++++--- include/kiway_player.h | 4 +- include/sch_base_frame.h | 2 +- include/wxBasePcbFrame.h | 2 +- include/wxstruct.h | 27 +---- kicad/kicad.cpp | 16 ++- kicad/mainframe.cpp | 88 ++++++++++------ pagelayout_editor/CMakeLists.txt | 2 +- pagelayout_editor/pl_editor.cpp | 2 +- pagelayout_editor/pl_editor_frame.cpp | 2 +- pcbnew/CMakeLists.txt | 4 +- pcbnew/basepcbframe.cpp | 2 +- pcbnew/dialogs/dialog_set_grid.cpp | 2 +- pcbnew/edit.cpp | 6 +- pcbnew/editmod.cpp | 2 +- pcbnew/edtxtmod.cpp | 4 +- pcbnew/footprint_wizard_frame.cpp | 2 +- pcbnew/modedit.cpp | 2 +- pcbnew/moduleframe.cpp | 2 +- pcbnew/modview_frame.cpp | 2 +- pcbnew/pcbframe.cpp | 2 +- pcbnew/pcbnew.cpp | 6 +- pcbnew/printout_controler.cpp | 2 +- 44 files changed, 357 insertions(+), 140 deletions(-) create mode 100644 include/frame_type.h diff --git a/3d-viewer/3d_frame.cpp b/3d-viewer/3d_frame.cpp index 55058bc911..c1fabb0b7a 100644 --- a/3d-viewer/3d_frame.cpp +++ b/3d-viewer/3d_frame.cpp @@ -81,7 +81,7 @@ END_EVENT_TABLE() EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, const wxString& aTitle, long style ) : - KIWAY_PLAYER( aKiway, aParent, DISPLAY3D_FRAME_TYPE, aTitle, + KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition, wxDefaultSize, style, wxT( "Frame3D" ) ) { m_canvas = NULL; diff --git a/common/basicframe.cpp b/common/basicframe.cpp index f8a170211a..a19fbd96cf 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -62,7 +62,7 @@ static const wxChar entryPerspective[] = wxT( "Perspective" ); -EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, +EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ) diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 13fc21d68a..578520263e 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -90,7 +90,7 @@ END_EVENT_TABLE() EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aFrameType, + FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName ) : diff --git a/common/kiway.cpp b/common/kiway.cpp index 390586a24b..eaf3fcf14d 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -24,21 +24,29 @@ #include +#include #include +#include #include #include #include -KIWAY::KIWAY() +KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT]; +int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; + + +KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): + m_program( aProgram ), + m_top( aTop ) { - memset( &m_kiface, 0, sizeof( m_kiface ) ); + memset( m_player, 0, sizeof( m_player ) ); } const wxString KIWAY::dso_full_path( FACE_T aFaceId ) { - const wxChar* name = wxT(""); + const wxChar* name; switch( aFaceId ) { @@ -68,22 +76,24 @@ PROJECT& KIWAY::Prj() const } -KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad ) +KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) { - switch( aFaceId ) + // Since this will be called from python, cannot assume that code will + // not pass a bad aFaceId. + if( unsigned( aFaceId ) >= DIM( m_kiface ) ) { - // case FACE_SCH: - case FACE_PCB: - if( m_kiface[aFaceId] ) - return m_kiface[aFaceId]; - break; + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. - default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); return NULL; } - // DSO with KIFACE has not been loaded yet, does user want to load it? + // return the previously loaded KIFACE, if it was. + if( m_kiface[aFaceId] ) + return m_kiface[aFaceId]; + + // DSO with KIFACE has not been loaded yet, does caller want to load it? if( doLoad ) { wxString dname = dso_full_path( aFaceId ); @@ -108,7 +118,7 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad ) { KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr; - KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, aProgram ); + KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, m_program ); // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional. wxASSERT_MSG( kiface, @@ -116,7 +126,7 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad ) // Give the DSO a single chance to do its "process level" initialization. // "Process level" specifically means stay away from any projects in there. - if( kiface->OnKifaceStart( aProgram, KFCTL_PROJECT_SUITE ) ) + if( kiface->OnKifaceStart( m_program, KFCTL_PROJECT_SUITE ) ) { // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. (void) dso.Detach(); @@ -131,3 +141,105 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad ) return NULL; } + + +KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType ) +{ + switch( aFrameType ) + { + case FRAME_SCH: + case FRAME_SCH_LIB_EDITOR: + case FRAME_SCH_VIEWER: + return FACE_SCH; + + case FRAME_PCB: + case FRAME_PCB_MODULE_EDITOR: + case FRAME_PCB_MODULE_VIEWER: + case FRAME_PCB_FOOTPRINT_WIZARD: + case FRAME_PCB_DISPLAY3D: + return FACE_PCB; + + case FRAME_CVPCB: + case FRAME_CVPCB_DISPLAY: + return FACE_CVPCB; + + case FRAME_GERBER: + return FACE_GERBVIEW; + + case FRAME_PL_EDITOR: + return FACE_PL_EDITOR; + + default: + return FACE_T( -1 ); + } +} + + +KIWAY_PLAYER* KIWAY::PlayerCreate( FRAME_T aFrameType ) +{ + // Since this will be called from python, cannot assume that code will + // not pass a bad aFrameType. + if( unsigned( aFrameType ) >= DIM( m_player ) ) + { + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. + + wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) ); + return NULL; + } + + // return the previously opened window + if( m_player[aFrameType] ) + return m_player[aFrameType]; + + FACE_T face_type = KifaceType( aFrameType ); + + wxASSERT( face_type != FACE_T(-1) ); + + KIFACE* kiface = KiFACE( face_type ); + + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); + + return m_player[aFrameType] = frame; +} + + +bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce ) +{ + // Since this will be called from python, cannot assume that code will + // not pass a bad aFrameType. + if( unsigned( aFrameType ) >= DIM( m_player ) ) + { + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. + + wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) ); + return false; + } + + if( m_player[aFrameType] ) + { + if( m_player[aFrameType]->Close( doForce ) ) + { + m_player[aFrameType] = 0; + return true; + } + + return false; + } + + return true; // window is closed already. +} + + +bool KIWAY::PlayersClose( bool doForce ) +{ + bool ret = true; + + for( unsigned i=0; i < DIM( m_player ); ++i ) + { + ret = ret && PlayerClose( FRAME_T( i ), doForce ); + } + + return ret; +} diff --git a/common/single_top.cpp b/common/single_top.cpp index b1d925c99c..0200170b10 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -121,7 +121,7 @@ static const wxString dso_full_path( const wxString& aAbsoluteArgv0 ) // Only a single KIWAY is supported in this single_top top level component, // which is dedicated to loading only a single DSO. -static KIWAY kiway; +KIWAY Kiway( &Pgm() ); // implement a PGM_BASE and a wxApp side by side: @@ -304,17 +304,17 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) // Use KIFACE to create a top window that the KIFACE knows about. // TOP_FRAME is passed on compiler command line from CMake, and is one of - // the types in ID_DRAWFRAME_TYPE. + // the types in FRAME_T. // KIFACE::CreateWindow() is a virtual so we don't need to link to it. // Remember its in the *.kiface DSO. #if 0 // this pulls in EDA_DRAW_FRAME type info, which we don't want in // the single_top link image. KIWAY_PLAYER* frame = dynamic_cast( kiface->CreateWindow( - NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE ) ); + NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ) ); #else KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( - NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE ); + NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ); #endif App().SetTopWindow( frame ); // wxApp gets a face. diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 2e89204780..f36d47ee56 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -81,7 +81,7 @@ if( USE_KIWAY_DLLS ) ${CVPCB_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=CVPCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL" ) target_link_libraries( cvpcb #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index 4f9730ea4f..e1a0ab36dc 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -72,7 +72,7 @@ END_EVENT_TABLE() DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, CVPCB_DISPLAY_FRAME_TYPE, _( "Footprint Viewer" ), + PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME ) { diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index c878e61201..4adba22292 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -107,7 +107,7 @@ END_EVENT_TABLE() CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) : - KIWAY_PLAYER( aKiway, aParent, CVPCB_FRAME_TYPE, wxT( "CvPCB" ), wxDefaultPosition, + KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, wxT( "CvPCB" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME ) { m_FrameName = CVPCB_MAINFRAME_NAME; diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp index 266674667d..78fbebf619 100644 --- a/cvpcb/cvpcb.cpp +++ b/cvpcb/cvpcb.cpp @@ -108,7 +108,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case CVPCB_FRAME_TYPE: + case FRAME_CVPCB: { CVPCB_MAINFRAME* frame = new CVPCB_MAINFRAME( aKiway, aParent ); return frame; diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 87b71aa5f5..b139726841 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -251,7 +251,7 @@ if( USE_KIWAY_DLLS ) ${EESCHEMA_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" ) target_link_libraries( eeschema #singletop # replaces common, giving us restrictive control and link warnings. @@ -345,7 +345,7 @@ else() ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" ) if( APPLE ) diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index 0d0d0c43e9..fafcd90ac5 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -79,7 +79,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case SCHEMATIC_FRAME_TYPE: + case FRAME_SCH: { SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent ); @@ -97,7 +97,7 @@ static struct IFACE : public KIFACE_I } break; - case LIBEDITOR_FRAME_TYPE: + case FRAME_SCH_LIB_EDITOR: { LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, dynamic_cast( aParent ) ); diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index b8e8f7897a..e4f16b3a8f 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -810,7 +810,7 @@ void LIB_PIN::drawGraphic( EDA_DRAW_PANEL* aPanel, if( aPanel && aPanel->GetParent() ) frame = (EDA_DRAW_FRAME*)aPanel->GetParent(); - if( frame && frame->IsType( SCHEMATIC_FRAME_TYPE ) && + if( frame && frame->IsType( FRAME_SCH ) && ! ((SCH_EDIT_FRAME*)frame)->GetShowAllPins() ) return; diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 0eaa7aca20..1a79cba67e 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -190,7 +190,7 @@ END_EVENT_TABLE() #define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" ) LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) : - SCH_BASE_FRAME( aKiway, aParent, LIBEDITOR_FRAME_TYPE, _( "Library Editor" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() ) { wxASSERT( aParent ); // LIB_EDIT_FRAME needs a parent, since it peeks up there. diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 686efce6de..7908defdc1 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -29,7 +29,7 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aWindowType, const wxString& aTitle, + FRAME_T aWindowType, const wxString& aTitle, const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index a26598437f..69221fd9ec 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -176,7 +176,7 @@ END_EVENT_TABLE() #define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" ) SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): - SCH_BASE_FRAME( aKiway, aParent, SCHEMATIC_FRAME_TYPE, wxT( "Eeschema" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ), m_item_to_repeat( 0 ) { @@ -821,7 +821,7 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) { KIFACE_I& kf = Kiface(); - wxWindow* w = kf.CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + wxWindow* w = kf.CreateWindow( this, FRAME_SCH_LIB_EDITOR, &Kiway(), kf.StartFlags() ); libeditFrame = dynamic_cast( w ); } diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index 3963b03dbf..33b05c1bc6 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -97,7 +97,7 @@ static wxAcceleratorEntry accels[] = LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, CMP_LIBRARY* aLibrary, wxSemaphore* aSemaphore, long aStyle ) : - SCH_BASE_FRAME( aKiway, aParent, VIEWER_FRAME_TYPE, _( "Library Browser" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Library Browser" ), wxDefaultPosition, wxDefaultSize, aStyle, GetLibViewerFrameName() ) { wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index df67987d6f..7eff8d254e 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -100,7 +100,7 @@ if( USE_KIWAY_DLLS ) ${GERBVIEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=GERBER_FRAME_TYPE;BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_GERBER;BUILD_KIWAY_DLL" ) target_link_libraries( gerbview #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/gerbview/gerbview.cpp b/gerbview/gerbview.cpp index e7ae04c786..0423cd6b72 100644 --- a/gerbview/gerbview.cpp +++ b/gerbview/gerbview.cpp @@ -81,7 +81,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case GERBER_FRAME_TYPE: + case FRAME_GERBER: { GERBVIEW_FRAME* frame = new GERBVIEW_FRAME( aKiway, aParent ); diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index 1e2b073e8d..b6d6d412e4 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -65,7 +65,7 @@ static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBloc #define GERBVIEW_FRAME_NAME wxT( "GerberFrame" ) GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ): - EDA_DRAW_FRAME( aKiway, aParent, GERBER_FRAME_TYPE, wxT( "GerbView" ), + EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME ) { m_colorsSettings = &g_ColorsSettings; diff --git a/include/draw_frame.h b/include/draw_frame.h index b533688e55..67aba863c1 100644 --- a/include/draw_frame.h +++ b/include/draw_frame.h @@ -118,7 +118,7 @@ protected: public: EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aFrameType, + FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, diff --git a/include/frame_type.h b/include/frame_type.h new file mode 100644 index 0000000000..23411168c6 --- /dev/null +++ b/include/frame_type.h @@ -0,0 +1,32 @@ +#ifndef FRAME_T_H_ +#define FRAME_T_H_ + +/** + * Enum FRAME_T + * is the set of EDA_BASE_FRAME derivatives, typically stored in + * EDA_BASE_FRAME::m_Ident. + */ +enum FRAME_T +{ + FRAME_SCH, + FRAME_SCH_LIB_EDITOR, + FRAME_SCH_VIEWER, + FRAME_PCB, + FRAME_PCB_MODULE_EDITOR, + FRAME_PCB_MODULE_VIEWER, + FRAME_PCB_FOOTPRINT_WIZARD, + FRAME_PCB_DISPLAY3D, + FRAME_CVPCB, + FRAME_CVPCB_DISPLAY, + FRAME_GERBER, + + KIWAY_PLAYER_COUNT, // counts subset of FRAME_T's tracked in class KIWAY + + KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT, + FRAME_PL_EDITOR, + //TEXT_EDITOR_FRAME_T, + + FRAME_T_COUNT +}; + +#endif // FRAME_T_H_ diff --git a/include/kiway.h b/include/kiway.h index 92e20b93e4..f4f40ca980 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -101,6 +101,7 @@ as such! As such, it is OK to use UTF8 characters: #include #include #include +#include #define VTBL_ENTRY virtual @@ -126,6 +127,7 @@ class wxWindow; class wxConfigBase; class PGM_BASE; class KIWAY; +class KIWAY_PLAYER; /** @@ -248,50 +250,109 @@ class KIWAY : public wxEvtHandler { public: - /// Possible KIFACEs on *this* KIWAY + /// Known KIFACE implementations enum FACE_T { - FACE_SCH, ///< eeschema DSO - // FACE_LIB, - FACE_PCB, ///< pcbnew DSO - // FACE_MOD, + FACE_SCH, ///< eeschema DSO + FACE_PCB, ///< pcbnew DSO FACE_CVPCB, - FACE_BMP2CMP, + /// count of those above here, which is the subset managed in a KIWAY. + KIWAY_FACE_COUNT, + + FACE_BMP2CMP = KIWAY_FACE_COUNT, FACE_GERBVIEW, FACE_PL_EDITOR, FACE_PCB_CALCULATOR, - FACE_COUNT, ///< how many KIWAY player types + FACE_COUNT }; - // If you change the vtable, recompile all of KiCad. + /** + * Function KifaceType + * is a simple mapping function which returns the FACE_T which is known to + * implement @a aFrameType. + * + * @return KIWAY::FACE_T - a valid value or FACE_T(-1) if given a bad aFrameType. + */ + static FACE_T KifaceType( FRAME_T aFrameType ); + // If you change the vtable, recompile all of KiCad. + /** * Function KiFACE * returns the KIFACE* given a FACE_T. If it is not already loaded, the * KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart() */ - VTBL_ENTRY KIFACE* KiFACE( PGM_BASE* aProgram, - FACE_T aFaceId, bool doLoad = true ); + VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad = true ); - VTBL_ENTRY PROJECT& Prj() const; + /** + * Function PlayerCreate + * returns the KIWAY_PLAYER* given a FRAME_T. If it is not already created, + * the required KIFACE is found and loaded and initialized if necessary, then + * the KIWAY_PLAYER window is created but not shown. Caller must Show() it. + * If it is already created, then the existing KIWAY_PLAYER* pointer is returned. + * + * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there + * is something wrong. + */ + VTBL_ENTRY KIWAY_PLAYER* PlayerCreate( FRAME_T aFrameType ); - KIWAY(); + /** + * Function PlayerClose + * calls the KIWAY_PLAYER::Close( bool force ) function on the window and + * if not vetoed, returns true, else false. If window actually closes, then + * this KIWAY marks it as not opened internally. + * + * @return bool - true the window is closed and not vetoed, else false. + */ + VTBL_ENTRY bool PlayerClose( FRAME_T aFrameType, bool doForce ); + + /** + * Function PlayersClose + * calls the KIWAY_PLAYER::Close( bool force ) function on all the windows and + * if none are vetoed, returns true, else false. If window actually closes, then + * this KIWAY marks it as not opened internally. + * + * @return bool - true the window is closed and not vetoed, else false. + */ + VTBL_ENTRY bool PlayersClose( bool doForce ); + + + /** + * Function Prj + * returns the PROJECT associated with this KIWAY. This is here as an + * accessor, so that there is freedom to put the actual PROJECT storage + * in a place decided by the implementation, and not known to the caller. + */ + VTBL_ENTRY PROJECT& Prj() const; + + KIWAY( PGM_BASE* aProgram, wxFrame* aTop = NULL ); + + /// In case aTop may not be known at time of KIWAY construction: + void SetTop( wxFrame* aTop ) { m_top = aTop; } private: /// Get the full path & name of the DSO holding the requested FACE_T. static const wxString dso_full_path( FACE_T aFaceId ); - KIFACE* m_kiface[FACE_COUNT]; - int m_kiface_version[FACE_COUNT]; + static KIFACE* m_kiface[KIWAY_FACE_COUNT]; + static int m_kiface_version[KIWAY_FACE_COUNT]; - PROJECT m_project; // do not assume this is here, use Prj(). + KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h + + PROJECT m_project; // do not assume this is here, use Prj(). + + PGM_BASE* m_program; + wxFrame* m_top; }; +extern KIWAY Kiway; // provided by single_top.cpp and kicad.cpp + + /** * Function Pointer KIFACE_GETTER_FUNC * points to the one and only KIFACE export. The export's address @@ -310,4 +371,5 @@ typedef KIFACE* KIFACE_GETTER_FUNC( int* aKIFACEversion, int aKIWAYversion, /// No name mangling. Each KIFACE (DSO/DLL) will implement this once. extern "C" KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, PGM_BASE* aProgram ); + #endif // KIWAY_H_ diff --git a/include/kiway_player.h b/include/kiway_player.h index 15d8489615..9a48085dd2 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -98,7 +98,7 @@ private: class KIWAY_PLAYER : public EDA_BASE_FRAME, public KIWAY_HOLDER { public: - KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aWdoName = wxFrameNameStr ) : EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), @@ -110,7 +110,7 @@ public: KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, (ID_DRAWFRAME_TYPE) aId, aTitle, aPos, aSize, aStyle, aWdoName ), + EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), KIWAY_HOLDER( 0 ) {} diff --git a/include/sch_base_frame.h b/include/sch_base_frame.h index 27a4193446..261989c89a 100644 --- a/include/sch_base_frame.h +++ b/include/sch_base_frame.h @@ -47,7 +47,7 @@ class SCH_BASE_FRAME : public EDA_DRAW_FRAME { public: SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aWindowType, + FRAME_T aWindowType, const wxString& aTitle, const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString & aFrameName ); diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 3fd117ffb9..e60a969abb 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -115,7 +115,7 @@ protected: static const LAYER_NUM GAL_LAYER_ORDER[]; public: - PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ); diff --git a/include/wxstruct.h b/include/wxstruct.h index dbf8679ef5..73363cceed 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef USE_WX_OVERLAY #include @@ -81,26 +82,6 @@ enum id_librarytype { }; -enum ID_DRAWFRAME_TYPE -{ - NOT_INIT_FRAME_TYPE = 0, - SCHEMATIC_FRAME_TYPE, - LIBEDITOR_FRAME_TYPE, - VIEWER_FRAME_TYPE, - PCB_FRAME_TYPE, - MODULE_EDITOR_FRAME_TYPE, - MODULE_VIEWER_FRAME_TYPE, - FOOTPRINT_WIZARD_FRAME_TYPE, - CVPCB_FRAME_TYPE, - CVPCB_DISPLAY_FRAME_TYPE, - GERBER_FRAME_TYPE, - TEXT_EDITOR_FRAME_TYPE, - DISPLAY3D_FRAME_TYPE, - KICAD_MAIN_FRAME_TYPE, - PL_EDITOR_FRAME_TYPE -}; - - /// Custom trace mask to enable and disable auto save tracing. extern const wxChar traceAutoSave[]; @@ -132,7 +113,7 @@ class EDA_BASE_FRAME : public wxFrame void windowClosing( wxCloseEvent& event ); protected: - ID_DRAWFRAME_TYPE m_Ident; ///< Id Type (pcb, schematic, library..) + FRAME_T m_Ident; ///< Id Type (pcb, schematic, library..) wxPoint m_FramePos; wxSize m_FrameSize; @@ -196,7 +177,7 @@ protected: virtual wxString help_name(); public: - EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ); @@ -219,7 +200,7 @@ public: bool IsActive() const { return m_FrameIsActive; } - bool IsType( ID_DRAWFRAME_TYPE aType ) const { return m_Ident == aType; } + bool IsType( FRAME_T aType ) const { return m_Ident == aType; } void GetKicadHelp( wxCommandEvent& event ); diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 028b1aff91..ac0a734dc1 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -149,6 +149,8 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) wxDefaultPosition, wxDefaultSize ); App().SetTopWindow( frame ); + Kiway.SetTop( frame ); + bool prjloaded = false; // true when the project is loaded if( App().argc > 1 ) @@ -251,7 +253,7 @@ void PGM_KICAD::destroy() } -KIWAY_MGR Kiways; +KIWAY Kiway( &Pgm() ); /** @@ -262,7 +264,7 @@ struct APP_KICAD : public wxApp { bool OnInit() // overload wxApp virtual { - if( Kiways.OnStart( this ) ) + // if( Kiways.OnStart( this ) ) { return Pgm().OnPgmInit( this ); } @@ -271,7 +273,7 @@ struct APP_KICAD : public wxApp int OnExit() // overload wxApp virtual { - Kiways.OnEnd(); + // Kiways.OnEnd(); Pgm().OnPgmExit(); @@ -297,10 +299,12 @@ IMPLEMENT_APP( APP_KICAD ); // this link image need this function. PROJECT& Prj() { - return Kiways[0].Prj(); + return Kiway.Prj(); } +#if 0 // there can be only one in C++ project manager. + bool KIWAY_MGR::OnStart( wxApp* aProcess ) { // The C++ project manager supports only one open PROJECT @@ -314,3 +318,5 @@ bool KIWAY_MGR::OnStart( wxApp* aProcess ) void KIWAY_MGR::OnEnd() { } + +#endif diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index d75e25f5ed..4f2480f38d 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include #include @@ -41,13 +41,14 @@ #include #include +#define USE_KIFACE 1 -#define TreeFrameWidthEntry wxT( "LeftWinWidth" ) +#define TreeFrameWidthEntry wxT( "LeftWinWidth" ) KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title, const wxPoint& pos, const wxSize& size ) : - EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_TYPE, title, pos, size, + EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_T, title, pos, size, KICAD_DEFAULT_DRAWFRAME_STYLE, wxT( "KicadFrame" ) ) { m_leftWinWidth = 60; @@ -154,26 +155,29 @@ void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event ) void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { - int px, py; - - UpdateFileHistory( m_ProjectFileName.GetFullPath(), &Pgm().GetFileHistory() ); - - if( !IsIconized() ) // save main frame position and size + if( Kiway.PlayersClose( false ) ) { - GetPosition( &px, &py ); - m_FramePos.x = px; - m_FramePos.y = py; + int px, py; - GetSize( &px, &py ); - m_FrameSize.x = px; - m_FrameSize.y = py; + UpdateFileHistory( m_ProjectFileName.GetFullPath(), &Pgm().GetFileHistory() ); + + if( !IsIconized() ) // save main frame position and size + { + GetPosition( &px, &py ); + m_FramePos.x = px; + m_FramePos.y = py; + + GetSize( &px, &py ); + m_FrameSize.x = px; + m_FrameSize.y = py; + } + + Event.SetCanVeto( true ); + + m_LeftWin->Show( false ); + + Destroy(); } - - Event.SetCanVeto( true ); - - m_LeftWin->Show( false ); - - Destroy(); } @@ -243,17 +247,12 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ? kicad_board : legacy_board; - -#if 0 // it works! - KIFACE* kiface = Kiways[0].KiFACE( &Pgm(), KIWAY::FACE_PCB ); - - KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( this, PCB_FRAME_TYPE, &Kiways[0], KFCTL_PROJECT_SUITE ); +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_PCB ); frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); - frame->Show( true ); frame->Raise(); - #else Execute( this, PCBNEW_EXE, QuoteFullPath( board ) ); #endif @@ -265,25 +264,49 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event ) wxFileName fn( m_ProjectFileName ); fn.SetExt( NetlistFileExtension ); + +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_CVPCB ); + + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + frame->Raise(); +#else Execute( this, CVPCB_EXE, QuoteFullPath( fn ) ); +#endif } + void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) { wxFileName fn( m_ProjectFileName ); fn.SetExt( SchematicFileExtension ); - Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_SCH ); + + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + frame->Raise(); +#else + Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); +#endif } void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event ) { wxFileName fn( m_ProjectFileName ); + wxString path = wxT( "\"" ); + path += fn.GetPath( wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME ) + wxT( "\"" ); +#if USE_KIFACE && 0 + +#else Execute( this, GERBVIEW_EXE, path ); +#endif } @@ -353,10 +376,11 @@ void KICAD_MANAGER_FRAME::SaveSettings( wxConfigBase* aCfg ) */ void KICAD_MANAGER_FRAME::PrintPrjInfo() { - wxString msg; - msg.Printf( _( "Working dir: %s\nProject: %s\n" ), - GetChars( wxGetCwd() ), - GetChars( m_ProjectFileName.GetFullPath() ) ); + wxString msg = wxString::Format( _( + "Working dir: %s\nProject: %s\n" ), + GetChars( wxGetCwd() ), + GetChars( m_ProjectFileName.GetFullPath() ) + ); PrintMsg( msg ); } diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index 308bd94949..cd6e41acdd 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -62,7 +62,7 @@ if( USE_KIWAY_DLLS ) ${PL_EDITOR_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PL_EDITOR_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PL_EDITOR;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL" ) target_link_libraries( pl_editor #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/pagelayout_editor/pl_editor.cpp b/pagelayout_editor/pl_editor.cpp index a72ee92505..f15d34e8ab 100644 --- a/pagelayout_editor/pl_editor.cpp +++ b/pagelayout_editor/pl_editor.cpp @@ -62,7 +62,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case PL_EDITOR_FRAME_TYPE: + case FRAME_PL_EDITOR: { PL_EDITOR_FRAME* frame = new PL_EDITOR_FRAME( aKiway, aParent ); diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index d5defe8d16..dd1162b9f3 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -54,7 +54,7 @@ #define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" ) PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - EDA_DRAW_FRAME( aKiway, aParent, PL_EDITOR_FRAME_TYPE, wxT( "PlEditorFrame" ), + EDA_DRAW_FRAME( aKiway, aParent, FRAME_PL_EDITOR, wxT( "PlEditorFrame" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PL_EDITOR_FRAME_NAME ) { m_FrameName = PL_EDITOR_FRAME_NAME; diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 5cf723661c..42350320f5 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -512,7 +512,7 @@ if( USE_KIWAY_DLLS ) ${PCBNEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp pcbnew.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL" ) target_link_libraries( pcbnew #singletop # replaces common, giving us restrictive control and link warnings. @@ -614,7 +614,7 @@ else() # milestone A) kills this off: ${PCBNEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\"" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\"" ) target_link_libraries( pcbnew 3d-viewer diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 1afb7e71c6..2307a5b3c7 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -129,7 +129,7 @@ BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME ) END_EVENT_TABLE() -PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, +PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName ) : EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ) diff --git a/pcbnew/dialogs/dialog_set_grid.cpp b/pcbnew/dialogs/dialog_set_grid.cpp index d60e152805..689b803699 100644 --- a/pcbnew/dialogs/dialog_set_grid.cpp +++ b/pcbnew/dialogs/dialog_set_grid.cpp @@ -211,7 +211,7 @@ bool PCB_BASE_FRAME::InvokeDialogGrid() if( ret == wxID_OK ) { - if( GetGridOrigin() != grid_origin && IsType( PCB_FRAME_TYPE ) ) + if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) ) OnModify(); // because grid origin is saved in board, show as modified SetGridOrigin( grid_origin ); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index de2c27b58f..92b267c856 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -196,7 +196,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { KIFACE_I& kf = Kiface(); - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); editor->Show( true ); editor->Zoom_Automatique( false ); @@ -224,7 +224,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { KIFACE_I& kf = Kiface(); - viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); @@ -845,7 +845,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { KIFACE_I& kf = Kiface(); - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() ); diff --git a/pcbnew/editmod.cpp b/pcbnew/editmod.cpp index a7cc3cbe74..49325bc1eb 100644 --- a/pcbnew/editmod.cpp +++ b/pcbnew/editmod.cpp @@ -80,7 +80,7 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC ) { KIFACE_I& kf = Kiface(); - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( Module ); diff --git a/pcbnew/edtxtmod.cpp b/pcbnew/edtxtmod.cpp index d180cd00cd..78c1f40d30 100644 --- a/pcbnew/edtxtmod.cpp +++ b/pcbnew/edtxtmod.cpp @@ -108,7 +108,7 @@ void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC ) if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command { - if( IsType( PCB_FRAME_TYPE ) ) + if( IsType( FRAME_PCB ) ) SaveCopyInUndoList( module, UR_CHANGED ); } @@ -236,7 +236,7 @@ void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC ) double tmp = Text->GetOrientation(); Text->SetOrientation( TextInitialOrientation ); - if( IsType( PCB_FRAME_TYPE ) ) + if( IsType( FRAME_PCB ) ) SaveCopyInUndoList( Module, UR_CHANGED ); else SaveCopyInUndoList( Module, UR_MODEDIT ); diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index a5d5a5a325..b09623f074 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -121,7 +121,7 @@ static wxAcceleratorEntry accels[] = FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, FOOTPRINT_EDIT_FRAME* aParent, wxSemaphore* semaphore, long style ) : - PCB_BASE_FRAME( aKiway, aParent, FOOTPRINT_WIZARD_FRAME_TYPE, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_FOOTPRINT_WIZARD, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize, style, FOOTPRINT_WIZARD_FRAME_NAME ) { diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 22ef70221e..c9198d4a41 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -273,7 +273,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { KIFACE_I& kf = Kiface(); - viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() ); + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index fa28eca5b4..bf2983ccd0 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -153,7 +153,7 @@ END_EVENT_TABLE() #define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" ) FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, PCB_EDIT_FRAME* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, MODULE_EDITOR_FRAME_TYPE, wxEmptyString, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) { diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index b79a2c4d3c..30bb30063e 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -119,7 +119,7 @@ static wxAcceleratorEntry accels[] = FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, wxSemaphore* aSemaphore ) : - PCB_BASE_FRAME( aKiway, aParent, MODULE_VIEWER_FRAME_TYPE, _( "Footprint Library Browser" ), + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_VIEWER, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, !aSemaphore ? KICAD_DEFAULT_DRAWFRAME_STYLE : diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index e815ed705a..55c7a6b2ce 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -299,7 +299,7 @@ END_EVENT_TABLE() #define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" ) PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, PCB_FRAME_TYPE, wxT( "Pcbnew" ), wxDefaultPosition, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ) { m_FrameName = PCB_EDIT_FRAME_NAME; diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 98e5a5b660..3c47fb7f3d 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -110,7 +110,7 @@ static struct IFACE : public KIFACE_I switch( aClassId ) { - case PCB_FRAME_TYPE: + case FRAME_PCB: { PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent ); @@ -130,7 +130,7 @@ static struct IFACE : public KIFACE_I } break; - case MODULE_EDITOR_FRAME_TYPE: + case FRAME_PCB_MODULE_EDITOR: { // yuck: PCB_EDIT_FRAME* editor = dynamic_cast( aParent ); @@ -147,7 +147,7 @@ static struct IFACE : public KIFACE_I } break; - case MODULE_VIEWER_FRAME_TYPE: + case FRAME_PCB_MODULE_VIEWER: { // yuck: PCB_BASE_FRAME* editor = dynamic_cast( aParent ); diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp index 092304298c..c553cd83ed 100644 --- a/pcbnew/printout_controler.cpp +++ b/pcbnew/printout_controler.cpp @@ -263,7 +263,7 @@ void BOARD_PRINTOUT_CONTROLLER::DrawPage() // In module editor, the module is located at 0,0 but for printing // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. // So the equivalent board must be moved to the center of the page: - if( m_Parent->IsType( MODULE_EDITOR_FRAME_TYPE ) ) + if( m_Parent->IsType( FRAME_PCB_MODULE_EDITOR ) ) { boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); } From ea66e572a06c708dfe81a5471ea5e105d9c91161 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 19 Apr 2014 13:58:32 -0500 Subject: [PATCH 05/36] KIWAY::dso_full_path() was more incomplete. --- common/kiway.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index eaf3fcf14d..e0ff171aaa 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -50,8 +50,13 @@ const wxString KIWAY::dso_full_path( FACE_T aFaceId ) switch( aFaceId ) { - case FACE_SCH: name = KIFACE_PREFIX wxT( "eeschema" ); break; - case FACE_PCB: name = KIFACE_PREFIX wxT( "pcbnew" ); break; + case FACE_SCH: name = KIFACE_PREFIX wxT( "eeschema" ); break; + case FACE_PCB: name = KIFACE_PREFIX wxT( "pcbnew" ); break; + case FACE_CVPCB: name = KIFACE_PREFIX wxT( "cvpcb" ); break; + case FACE_GERBVIEW: name = KIFACE_PREFIX wxT( "gerbview" ); break; + case FACE_PL_EDITOR: name = KIFACE_PREFIX wxT( "pl_editor" ); break; + + // case FACE_PCB_CALCULATOR: who knows. default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); From f9f3ff22dcdf5bab6a921bff2843665e3d617b7a Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 19 Apr 2014 14:44:59 -0500 Subject: [PATCH 06/36] hook top frame with KIWAY::playerDestroyHandler() --- common/kiway.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- include/kiway.h | 11 +++++++---- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index e0ff171aaa..6e48c92dc5 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -38,11 +38,50 @@ int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): m_program( aProgram ), - m_top( aTop ) + m_top( 0 ) { + SetTop( aTop ); // hook playerDestroyHandler() into aTop. + memset( m_player, 0, sizeof( m_player ) ); } +// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are +// propogated upwards to parent windows if not handled below. Therefor the +// m_top window should receive all wxWindowDestroyEvents from originating +// from KIWAY_PLAYERs. It does anyways, but now playerDestroyHandler eavesdrops +// on that event stream looking for KIWAY_PLAYERs being closed. + +void KIWAY::playerDestroyHandler( wxWindowDestroyEvent& event ) +{ + wxWindow* w = event.GetWindow(); + + for( unsigned i=0; iDisconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + } + + if( aTop ) + { + aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + } + + m_top = aTop; +} + const wxString KIWAY::dso_full_path( FACE_T aFaceId ) { diff --git a/include/kiway.h b/include/kiway.h index f4f40ca980..7908990ffc 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -331,22 +331,25 @@ public: KIWAY( PGM_BASE* aProgram, wxFrame* aTop = NULL ); /// In case aTop may not be known at time of KIWAY construction: - void SetTop( wxFrame* aTop ) { m_top = aTop; } + void SetTop( wxFrame* aTop ); private: /// Get the full path & name of the DSO holding the requested FACE_T. static const wxString dso_full_path( FACE_T aFaceId ); + /// hooked into m_top in SetTop(), marks child frame as closed. + void playerDestroyHandler( wxWindowDestroyEvent& event ); + static KIFACE* m_kiface[KIWAY_FACE_COUNT]; static int m_kiface_version[KIWAY_FACE_COUNT]; + PGM_BASE* m_program; + wxFrame* m_top; + KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h PROJECT m_project; // do not assume this is here, use Prj(). - - PGM_BASE* m_program; - wxFrame* m_top; }; From a985255f9534c8aed150aa9de91206d2b2cec199 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 19 Apr 2014 23:35:34 -0500 Subject: [PATCH 07/36] add back missing pcbnew cross probing event handlers. eeschema launches kiface versions of pcbnew & cvpcb if not single. --- common/kiway.cpp | 23 +++++---- eeschema/controle.cpp | 3 +- eeschema/cross-probing.cpp | 83 +++++++++++++++++++------------- eeschema/menubar.cpp | 96 ++++++++++++------------------------- eeschema/schframe.cpp | 39 +++++++++++++-- include/kiway.h | 9 ++-- kicad/mainframe.cpp | 6 +-- pcbnew/cross-probing.cpp | 27 ++++++----- pcbnew/menubar_pcbframe.cpp | 1 - pcbnew/pcbframe.cpp | 3 ++ 10 files changed, 160 insertions(+), 130 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index 6e48c92dc5..5ee0300f9b 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -47,8 +47,8 @@ KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): // Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are // propogated upwards to parent windows if not handled below. Therefor the -// m_top window should receive all wxWindowDestroyEvents from originating -// from KIWAY_PLAYERs. It does anyways, but now playerDestroyHandler eavesdrops +// m_top window should receive all wxWindowDestroyEvents originating from +// KIWAY_PLAYERs. It does anyways, but now playerDestroyHandler eavesdrops // on that event stream looking for KIWAY_PLAYERs being closed. void KIWAY::playerDestroyHandler( wxWindowDestroyEvent& event ) @@ -57,7 +57,7 @@ void KIWAY::playerDestroyHandler( wxWindowDestroyEvent& event ) for( unsigned i=0; iCreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); - return m_player[aFrameType] = frame; + return m_player[aFrameType] = frame; + } + + return NULL; } diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index 6cf39282de..9e64f9219e 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -78,7 +78,7 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KIC return NULL; } - /* Cross probing to Pcbnew if a pin or a component is found */ + // Cross probing to Pcbnew if a pin or a component is found switch( item->Type() ) { case SCH_FIELD_T: @@ -105,6 +105,7 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KIC { // Force display pin information (the previous display could be a component info) MSG_PANEL_ITEMS items; + Pin->GetMsgPanelInfo( items ); if( LibItem ) diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index dcb7788c8d..5258944a90 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -107,56 +108,74 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } -void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem ) +std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) { - if( objectToSync == NULL ) - return; - - LIB_PIN* Pin = NULL; - char Line[1024]; - - /* Cross probing to Pcbnew if a pin or a component is found */ - switch( objectToSync->Type() ) + // Cross probing to Pcbnew if a pin or a component is found + switch( aComponent->Type() ) { case SCH_FIELD_T: case LIB_FIELD_T: { - if( !LibItem ) + if( !aPart ) break; - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - SendCommand( MSG_TO_PCB, Line ); + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); } break; case SCH_COMPONENT_T: - LibItem = (SCH_COMPONENT*) objectToSync; - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - SendCommand( MSG_TO_PCB, Line ); - break; + aPart = (SCH_COMPONENT*) aComponent; + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); case LIB_PIN_T: - if( !LibItem ) - break; - - Pin = (LIB_PIN*) objectToSync; - - if( Pin->GetNumber() ) { - wxString pinnum; - Pin->PinStringNum( pinnum ); - sprintf( Line, "$PIN: %s $PART: %s", TO_UTF8( pinnum ), - TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - } - else - { - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - } + if( !aPart ) + break; - SendCommand( MSG_TO_PCB, Line ); + LIB_PIN* pin = (LIB_PIN*) aComponent; + + if( pin->GetNumber() ) + { + wxString pinnum; + + pin->PinStringNum( pinnum ); + + return StrPrintf( "$PIN: %s $PART: %s", TO_UTF8( pinnum ), + TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); + } + else + { + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); + } + } break; default: break; } + + return ""; +} + + +void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) +{ +#if 1 + wxASSERT( aComponent ); // fix the caller + +#else // WTF? + if( objectToSync == NULL ) // caller remains eternally stupid. + return; +#endif + + std::string packet = FormatProbeItem( aComponent, aPart ); + + if( packet.size() ) + { + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_PCB, packet.c_str() ); + else + { + } + } } diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 086473b394..6d3e006b56 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -64,20 +64,22 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Menu File: wxMenu* fileMenu = new wxMenu; - // New - AddMenuItem( fileMenu, - ID_NEW_PROJECT, - _( "&New Schematic Project" ), - _( "Clear current schematic hierarchy and start a new schematic root sheet" ), - KiBitmap( new_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, + ID_NEW_PROJECT, + _( "&New Schematic Project" ), + _( "Clear current schematic hierarchy and start a new schematic root sheet" ), + KiBitmap( new_xpm ) ); - // Open - text = AddHotkeyName( _( "&Open Schematic Project" ), s_Schematic_Hokeys_Descr, HK_LOAD_SCH ); - AddMenuItem( fileMenu, - ID_LOAD_PROJECT, text, - _( "Open an existing schematic hierarchy" ), - KiBitmap( open_document_xpm ) ); + text = AddHotkeyName( _( "&Open Schematic Project" ), s_Schematic_Hokeys_Descr, HK_LOAD_SCH ); + AddMenuItem( fileMenu, + ID_LOAD_PROJECT, text, + _( "Open an existing schematic hierarchy" ), + KiBitmap( open_document_xpm ) ); + } + // @todo: static probably not OK in multiple open projects. // Open Recent submenu static wxMenu* openRecentMenu; @@ -91,21 +93,21 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() Kiface().GetFileHistory().UseMenu( openRecentMenu ); Kiface().GetFileHistory().AddFilesToMenu( openRecentMenu ); - AddMenuItem( fileMenu, openRecentMenu, - wxID_ANY, _( "Open &Recent" ), - _( "Open a recent opened schematic project" ), - KiBitmap( open_project_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, openRecentMenu, + wxID_ANY, _( "Open &Recent" ), + _( "Open a recent opened schematic project" ), + KiBitmap( open_project_xpm ) ); + } - // Import AddMenuItem( fileMenu, ID_APPEND_PROJECT, _( "&Append Schematic Sheet" ), _( "Append schematic sheet to current project" ), KiBitmap( open_document_xpm ) ); - // Separator fileMenu->AppendSeparator(); - // Save schematic project text = AddHotkeyName( _( "&Save Schematic Project" ), s_Schematic_Hokeys_Descr, HK_SAVE_SCH ); AddMenuItem( fileMenu, @@ -113,31 +115,29 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Save all sheets in schematic project" ), KiBitmap( save_project_xpm ) ); - // Save current sheet AddMenuItem( fileMenu, ID_UPDATE_ONE_SHEET, _( "Save &Current Sheet Only" ), _( "Save only current schematic sheet" ), KiBitmap( save_xpm ) ); - // Save current sheet as - AddMenuItem( fileMenu, - ID_SAVE_ONE_SHEET_UNDER_NEW_NAME, - _( "Save Current Sheet &As" ), - _( "Save current schematic sheet as..." ), - KiBitmap( save_as_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, + ID_SAVE_ONE_SHEET_UNDER_NEW_NAME, + _( "Save Current Sheet &As" ), + _( "Save current schematic sheet as..." ), + KiBitmap( save_as_xpm ) ); + } - // Separator fileMenu->AppendSeparator(); - // Page settings AddMenuItem( fileMenu, ID_SHEET_SET, _( "Pa&ge Settings" ), _( "Setting for sheet size and frame references" ), KiBitmap( sheetset_xpm ) ); - // Print AddMenuItem( fileMenu, wxID_PRINT, _( "Pri&nt" ), @@ -155,7 +155,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Plot to Clipboard (Windows only) - AddMenuItem( choice_plot_fmt, ID_GEN_COPY_SHEET_TO_CLIPBOARD, _( "Plot to &Clipboard" ), _( "Export drawings to clipboard" ), @@ -243,32 +242,26 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() * using in AddHotkeyName call the option "false" (not a shortcut) */ - // Zoom in text = AddHotkeyName( _( "Zoom &In" ), s_Schematic_Hokeys_Descr, HK_ZOOM_IN, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); - // Zoom out text = AddHotkeyName( _( "Zoom &Out" ), s_Schematic_Hokeys_Descr, HK_ZOOM_OUT, IS_ACCELERATOR ); // add accelerator, not a shortcut AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); - // Fit on screen text = AddHotkeyName( _( "&Fit on Screen" ), s_Schematic_Hokeys_Descr, HK_ZOOM_AUTO ); AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) ); - // Separator viewMenu->AppendSeparator(); - // Hierarchy AddMenuItem( viewMenu, ID_HIERARCHY, _( "Show &Hierarchical Navigator" ), _( "Navigate hierarchical sheets" ), KiBitmap( hierarchy_nav_xpm ) ); - // Redraw text = AddHotkeyName( _( "&Redraw" ), s_Schematic_Hokeys_Descr, HK_ZOOM_REDRAW ); AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) ); @@ -276,78 +269,66 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // @todo unify IDs wxMenu* placeMenu = new wxMenu; - // Component text = AddHotkeyName( _( "&Component" ), s_Schematic_Hokeys_Descr, HK_ADD_NEW_COMPONENT, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_SCH_PLACE_COMPONENT, text, HELP_PLACE_COMPONENTS, KiBitmap( add_component_xpm ) ); - // Power port text = AddHotkeyName( _( "&Power Port" ), s_Schematic_Hokeys_Descr, HK_ADD_NEW_POWER, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_PLACE_POWER_BUTT, text, HELP_PLACE_POWERPORT, KiBitmap( add_power_xpm ) ); - // Wire text = AddHotkeyName( _( "&Wire" ), s_Schematic_Hokeys_Descr, HK_BEGIN_WIRE, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_WIRE_BUTT, text, HELP_PLACE_WIRE, KiBitmap( add_line_xpm ) ); - // Bus text = AddHotkeyName( _( "&Bus" ), s_Schematic_Hokeys_Descr, HK_BEGIN_BUS, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_BUS_BUTT, text, HELP_PLACE_BUS, KiBitmap( add_bus_xpm ) ); - // Wire to Bus entry text = AddHotkeyName( _( "Wire to Bus &Entry" ), s_Schematic_Hokeys_Descr, HK_ADD_WIRE_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_WIRETOBUS_ENTRY_BUTT, text, HELP_PLACE_WIRE2BUS_ENTRY, KiBitmap( add_line2bus_xpm ) ); - // Bus to Bus entry text = AddHotkeyName( _( "Bus &to Bus Entry" ), s_Schematic_Hokeys_Descr, HK_ADD_BUS_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_BUSTOBUS_ENTRY_BUTT, text, HELP_PLACE_BUS2BUS_ENTRY, KiBitmap( add_bus2bus_xpm ) ); - // No Connect Flag text = AddHotkeyName( _( "&No Connect Flag" ), s_Schematic_Hokeys_Descr, HK_ADD_NOCONN_FLAG, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_NOCONN_BUTT, text, HELP_PLACE_NC_FLAG, KiBitmap( noconn_xpm ) ); - // Net name text = AddHotkeyName( _( "&Label" ), s_Schematic_Hokeys_Descr, HK_ADD_LABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_LABEL_BUTT, text, HELP_PLACE_NETLABEL, KiBitmap( add_line_label_xpm ) ); - // Global label text = AddHotkeyName( _( "Gl&obal Label" ), s_Schematic_Hokeys_Descr, HK_ADD_GLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_GLABEL_BUTT, text, HELP_PLACE_GLOBALLABEL, KiBitmap( add_glabel_xpm ) ); - // Junction text = AddHotkeyName( _( "&Junction" ), s_Schematic_Hokeys_Descr, HK_ADD_JUNCTION, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_JUNCTION_BUTT, text, HELP_PLACE_JUNCTION, KiBitmap( add_junction_xpm ) ); - // Separator placeMenu->AppendSeparator(); - // Hierarchical label text = AddHotkeyName( _( "&Hierarchical Label" ), s_Schematic_Hokeys_Descr, HK_ADD_HLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_HIERLABEL_BUTT, @@ -355,38 +336,32 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() KiBitmap( add_hierarchical_label_xpm ) ); - // Hierarchical sheet text = AddHotkeyName( _( "H&ierarchical &Sheet" ), s_Schematic_Hokeys_Descr, HK_ADD_HIER_SHEET, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_SHEET_SYMBOL_BUTT, text, HELP_PLACE_SHEET, KiBitmap( add_hierarchical_subsheet_xpm ) ); - // Import hierarchical sheet AddMenuItem( placeMenu, ID_IMPORT_HLABEL_BUTT, _( "I&mport Hierarchical Label" ), HELP_IMPORT_SHEETPIN, KiBitmap( import_hierarchical_label_xpm ) ); - // Add hierarchical Pin to Sheet AddMenuItem( placeMenu, ID_SHEET_PIN_BUTT, _( "Hierarchical Pi&n to Sheet" ), HELP_PLACE_SHEETPIN, KiBitmap( add_hierar_pin_xpm ) ); - // Separator placeMenu->AppendSeparator(); - // Graphic line or polygon text = AddHotkeyName( _( "Graphic Polyline" ), s_Schematic_Hokeys_Descr, HK_ADD_GRAPHIC_POLYLINE, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_LINE_COMMENT_BUTT, text, HELP_PLACE_GRAPHICLINES, KiBitmap( add_dashed_line_xpm ) ); - // Graphic text text = AddHotkeyName( _( "Graphic Text" ), s_Schematic_Hokeys_Descr, HK_ADD_GRAPHIC_TEXT, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_TEXT_COMMENT_BUTT, text, @@ -437,14 +412,12 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Separator preferencesMenu->AppendSeparator(); - // Save preferences AddMenuItem( preferencesMenu, ID_CONFIG_SAVE, _( "&Save Preferences" ), _( "Save application preferences" ), KiBitmap( save_setup_xpm ) ); - // Read preferences AddMenuItem( preferencesMenu, ID_CONFIG_READ, _( "&Read Preferences" ), @@ -454,22 +427,18 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Menu Tools: wxMenu* toolsMenu = new wxMenu; - // Library editor AddMenuItem( toolsMenu, ID_TO_LIBRARY, _( "Library &Editor" ), HELP_RUN_LIB_EDITOR, KiBitmap( libedit_xpm ) ); - // Library viewer AddMenuItem( toolsMenu, ID_TO_LIBVIEW, _( "Library &Browser" ), HELP_RUN_LIB_VIEWER, KiBitmap( library_browse_xpm ) ); - // Separator toolsMenu->AppendSeparator(); - // Annotate AddMenuItem( toolsMenu, ID_GET_ANNOTATE, _( "&Annotate Schematic" ), HELP_ANNOTATE, @@ -482,24 +451,21 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Perform electrical rule check" ), KiBitmap( erc_xpm ) ); - // Generate netlist AddMenuItem( toolsMenu, ID_GET_NETLIST, _( "Generate &Netlist File" ), _( "Generate the component netlist file" ), KiBitmap( netlist_xpm ) ); - // Generate bill of materials AddMenuItem( toolsMenu, ID_GET_TOOLS, _( "Generate Bill of &Materials" ), HELP_GENERATE_BOM, KiBitmap( bom_xpm ) ); - // Separator toolsMenu->AppendSeparator(); - //Run CvPcb + // Run CvPcb AddMenuItem( toolsMenu, ID_TO_CVPCB, _( "A&ssign Component Footprint" ), @@ -519,7 +485,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Version info AddHelpVersionInfoMenuEntry( helpMenu ); - // Contents AddMenuItem( helpMenu, wxID_HELP, _( "Eesc&hema Manual" ), @@ -532,7 +497,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Open \"Getting Started in KiCad\" guide for beginners" ), KiBitmap( help_xpm ) ); - // About Eeschema helpMenu->AppendSeparator(); AddMenuItem( helpMenu, wxID_ABOUT, diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 69221fd9ec..62aec927da 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -764,9 +764,23 @@ void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) { fn.SetExt( PcbFileExtension ); - wxString filename = QuoteFullPath( fn ); + if( Kiface().IsSingle() ) + { + wxString filename = QuoteFullPath( fn ); + ExecuteFile( this, PCBNEW_EXE, filename ); + } + else + { + KIWAY_PLAYER* player = Kiway().Player( FRAME_PCB, false ); // test open already. - ExecuteFile( this, PCBNEW_EXE, filename ); + if( !player ) + { + player = Kiway().Player( FRAME_PCB, true ); + player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + player->Show( true ); + } + player->Raise(); + } } else { @@ -783,7 +797,22 @@ void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) if( fn.IsOk() && fn.FileExists() ) { - ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); + if( Kiface().IsSingle() ) + { + ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); + } + else + { + KIWAY_PLAYER* player = Kiway().Player( FRAME_CVPCB, false ); // test open already. + + if( !player ) + { + player = Kiway().Player( FRAME_CVPCB, true ); + player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + player->Show( true ); + } + player->Raise(); + } } else { @@ -802,13 +831,15 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) if( (item == NULL) || (item->GetFlags() != 0) || ( item->Type() != SCH_COMPONENT_T ) ) { - wxMessageBox( _("Error: not a component or no component" ) ); + wxMessageBox( _( "Error: not a component or no component" ) ); return; } component = (SCH_COMPONENT*) item; } + // @todo: should be changed to use Kiway().Player()? + LIB_EDIT_FRAME* libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; if( libeditFrame ) { diff --git a/include/kiway.h b/include/kiway.h index 7908990ffc..9400bdf46d 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -288,16 +288,19 @@ public: VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad = true ); /** - * Function PlayerCreate + * Function Player * returns the KIWAY_PLAYER* given a FRAME_T. If it is not already created, * the required KIFACE is found and loaded and initialized if necessary, then * the KIWAY_PLAYER window is created but not shown. Caller must Show() it. * If it is already created, then the existing KIWAY_PLAYER* pointer is returned. * + * @param aFrameType is from enum #FRAME_T. + * @param doCreate when true asks that the player be created if it is not already created, false means do not create. + * * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there - * is something wrong. + * is something wrong or doCreate was false and the player has yet to be created. */ - VTBL_ENTRY KIWAY_PLAYER* PlayerCreate( FRAME_T aFrameType ); + VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true ); /** * Function PlayerClose diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index 4f2480f38d..b7b00ad9b4 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -248,7 +248,7 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) kicad_board : legacy_board; #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_PCB ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB ); frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); frame->Show( true ); @@ -266,7 +266,7 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event ) fn.SetExt( NetlistFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_CVPCB ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB ); frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); frame->Show( true ); @@ -284,7 +284,7 @@ void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) fn.SetExt( SchematicFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_SCH ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH ); frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); frame->Show( true ); diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 6aba44cb2b..93b98f3558 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -141,12 +142,12 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) */ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) { - char cmd[1024]; - const char* text_key; - MODULE* module = NULL; - D_PAD* pad; - TEXTE_MODULE* text_mod; - wxString msg; + std::string cmd; + const char* text_key; + MODULE* module = NULL; + D_PAD* pad; + TEXTE_MODULE* text_mod; + wxString msg; if( objectToSync == NULL ) return; @@ -155,14 +156,14 @@ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) { case PCB_MODULE_T: module = (MODULE*) objectToSync; - sprintf( cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); + StrPrintf( &cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); break; case PCB_PAD_T: module = (MODULE*) objectToSync->GetParent(); pad = (D_PAD*) objectToSync; msg = pad->GetPadName(); - sprintf( cmd, "$PART: \"%s\" $PAD: \"%s\"", + StrPrintf( &cmd, "$PART: \"%s\" $PAD: \"%s\"", TO_UTF8( module->GetReference() ), TO_UTF8( msg ) ); break; @@ -178,7 +179,7 @@ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) else break; - sprintf( cmd, "$PART: \"%s\" %s \"%s\"", + StrPrintf( &cmd, "$PART: \"%s\" %s \"%s\"", TO_UTF8( module->GetReference() ), text_key, TO_UTF8( text_mod->GetText() ) ); @@ -188,8 +189,12 @@ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) break; } - if( module ) + if( module && cmd.size() ) { - SendCommand( MSG_TO_SCH, cmd ); + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_SCH, cmd.c_str() ); + else + { + } } } diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 4192e44445..026e23df09 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -68,7 +68,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Clear current board and initialize a new one" ), KiBitmap( new_pcb_xpm ) ); - // Open text = AddHotkeyName( _( "&Open" ), g_Board_Editor_Hokeys_Descr, HK_LOAD_BOARD ); AddMenuItem( filesMenu, ID_LOAD_FILE, text, _( "Delete current board and load new board" ), diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 55c7a6b2ce..62a21ad005 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -85,6 +85,9 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) + EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, PCB_EDIT_FRAME::OnSockRequestServer ) + EVT_SOCKET( ID_EDA_SOCKET_EVENT, PCB_EDIT_FRAME::OnSockRequest ) + EVT_COMBOBOX( ID_ON_ZOOM_SELECT, PCB_EDIT_FRAME::OnSelectZoom ) EVT_COMBOBOX( ID_ON_GRID_SELECT, PCB_EDIT_FRAME::OnSelectGrid ) From e47a2bc5d4192e88b692c4b0ef2668f4234874a0 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 21 Apr 2014 01:28:17 -0500 Subject: [PATCH 08/36] happy Easter --- common/CMakeLists.txt | 2 + common/draw_frame.cpp | 2 +- common/kiway.cpp | 29 ++++++++++ common/kiway_express.cpp | 49 +++++++++++++++++ common/kiway_player.cpp | 56 +++++++++++++++++++ common/project.cpp | 3 +- eeschema/cross-probing.cpp | 5 +- include/kiway.h | 11 ++-- include/kiway_express.h | 94 ++++++++++++++++++++++++++++++++ include/kiway_player.h | 26 ++++++--- kicad/mainframe.cpp | 35 +++++++----- pcbnew/cross-probing.cpp | 107 +++++++++++++++++++++---------------- 12 files changed, 345 insertions(+), 74 deletions(-) create mode 100644 common/kiway_express.cpp create mode 100644 common/kiway_player.cpp create mode 100644 include/kiway_express.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 53fdaff9e3..176bffeb7c 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -182,7 +182,9 @@ set( COMMON_SRCS html_messagebox.cpp kiface_i.cpp kiway.cpp + kiway_express.cpp kiway_holder.cpp + kiway_player.cpp msgpanel.cpp netlist_keywords.cpp newstroke_font.cpp diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 578520263e..75461e5f22 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -64,7 +64,7 @@ static const wxString GridColorEntryKeyword( wxT( "GridColor" ) ); static const wxString LastGridSizeIdKeyword( wxT( "_LastGridSize" ) ); -BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, EDA_BASE_FRAME ) +BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, KIWAY_PLAYER ) EVT_MOUSEWHEEL( EDA_DRAW_FRAME::OnMouseEvent ) EVT_MENU_OPEN( EDA_DRAW_FRAME::OnMenuOpen ) EVT_ACTIVATE( EDA_DRAW_FRAME::OnActivate ) diff --git a/common/kiway.cpp b/common/kiway.cpp index 5ee0300f9b..72e31aad3e 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -292,3 +293,31 @@ bool KIWAY::PlayersClose( bool doForce ) return ret; } + + +void KIWAY::ExpressMail( FRAME_T aDestination, + int aCommand, const std::string& aPayload, wxWindow* aSource ) +{ + KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource ); + + ProcessEvent( mail ); +} + + +bool KIWAY::ProcessEvent( wxEvent& aEvent ) +{ + KIWAY_EXPRESS* mail = dynamic_cast( &aEvent ); + + if( mail ) + { + FRAME_T dest = mail->Dest(); + + // see if recipient is alive + KIWAY_PLAYER* alive = Player( dest, false ); + + if( alive ) + return alive->ProcessEvent( aEvent ); + } + + return false; +} diff --git a/common/kiway_express.cpp b/common/kiway_express.cpp new file mode 100644 index 0000000000..230880421d --- /dev/null +++ b/common/kiway_express.cpp @@ -0,0 +1,49 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.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 + */ + +#include + +//IMPLEMENT_DYNAMIC_CLASS( KIWAY_EXPRESS, wxEvent ) + + +const wxEventType KIWAY_EXPRESS::wxEVENT_ID = wxNewEventType(); + + +KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) : + wxEvent( anOther ) +{ + m_destination = anOther.m_destination; + m_payload = anOther.m_payload; +} + + +KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, int aCommand, + const std::string& aPayload, wxWindow* aSource ) : + wxEvent( aCommand, wxEVENT_ID ), + m_destination( aDestination ), + m_payload( aPayload ) +{ + SetEventObject( aSource ); +} + diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp new file mode 100644 index 0000000000..4706aac339 --- /dev/null +++ b/common/kiway_player.cpp @@ -0,0 +1,56 @@ + + +#include +#include +#include + + +BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) + /* have not been able to get this to work yet: + EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express ) + Use Connect() in constructor until this can be sorted out + */ +END_EVENT_TABLE() + + + +KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, + const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, + long aStyle, const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( aKiway ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, + const wxPoint& aPos, const wxSize& aSize, long aStyle, + const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( 0 ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +void KIWAY_PLAYER::kiway_express( KIWAY_EXPRESS& aEvent ) +{ + // logging support +#if defined(DEBUG) + const char* class_name = typeid(this).name(); + + printf( "%s: cmd:%d pay:'%s'\n", class_name, + aEvent.GetEventType(), aEvent.GetPayload().c_str() ); +#endif + + KiwayMailIn( aEvent ); // call the virtual, overload in derived. +} + + +void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) +{ + // overload this. +} diff --git a/common/project.cpp b/common/project.cpp index 4825974a9c..df43e60a5e 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // NAMELESS_PROJECT #include #include #include @@ -57,7 +58,7 @@ void PROJECT::SetProjectFullName( const wxString& aFullPathAndName ) { m_project_name = aFullPathAndName; - wxASSERT( m_project_name.IsAbsolute() ); + wxASSERT( m_project_name.GetName() == NAMELESS_PROJECT || m_project_name.IsAbsolute() ); #if 0 wxASSERT( m_project_name.GetExt() == wxT( ".pro" ) ) #else diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 5258944a90..0bc51934ab 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -161,10 +161,10 @@ std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) { #if 1 - wxASSERT( aComponent ); // fix the caller + wxASSERT( aComponent ); // fix the caller #else // WTF? - if( objectToSync == NULL ) // caller remains eternally stupid. + if( !aComponent ) // caller remains eternally stupid. return; #endif @@ -176,6 +176,7 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* a SendCommand( MSG_TO_PCB, packet.c_str() ); else { + Kiway().ExpressMail( FRAME_PCB, 0, packet, this ); } } } diff --git a/include/kiway.h b/include/kiway.h index 9400bdf46d..ae4337b563 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -295,7 +295,8 @@ public: * If it is already created, then the existing KIWAY_PLAYER* pointer is returned. * * @param aFrameType is from enum #FRAME_T. - * @param doCreate when true asks that the player be created if it is not already created, false means do not create. + * @param doCreate when true asks that the player be created if it is not + * already created, false means do not create and maybe return NULL. * * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there * is something wrong or doCreate was false and the player has yet to be created. @@ -315,13 +316,15 @@ public: /** * Function PlayersClose * calls the KIWAY_PLAYER::Close( bool force ) function on all the windows and - * if none are vetoed, returns true, else false. If window actually closes, then + * if none are vetoed, returns true, else false. If any window actually closes, then * this KIWAY marks it as not opened internally. * - * @return bool - true the window is closed and not vetoed, else false. + * @return bool - true indicates that all windows closed because none were vetoed, + * false means at least one cast a veto. Any that cast a veto are still open. */ VTBL_ENTRY bool PlayersClose( bool doForce ); + VTBL_ENTRY void ExpressMail( FRAME_T aDestination, int aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); /** * Function Prj @@ -336,6 +339,8 @@ public: /// In case aTop may not be known at time of KIWAY construction: void SetTop( wxFrame* aTop ); + bool ProcessEvent( wxEvent& aEvent ); // overload virtual + private: /// Get the full path & name of the DSO holding the requested FACE_T. diff --git a/include/kiway_express.h b/include/kiway_express.h new file mode 100644 index 0000000000..6e95d5ae39 --- /dev/null +++ b/include/kiway_express.h @@ -0,0 +1,94 @@ +#ifndef KIWAY_EXPRESS_H_ +#define KIWAY_EXPRESS_H_ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.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 + */ + +// @see http://wiki.wxwidgets.org/Custom_Events_Tutorial + +#include +#include + +/** + * Class KIWAY_EXPRESS + * carries a payload from one KIWAY_PLAYER to anothing within a PROJECT. + */ +class KIWAY_EXPRESS : public wxEvent +{ +public: + /** + * Function Dest + * returns the destination player id of the message. + */ + FRAME_T Dest() { return m_destination; } + + /** + * Function Payload + * returns the payload, which can be any text but it typicall self + * identifying s-expression. + */ + const std::string& GetPayload() { return m_payload; } + void SetPayload( const std::string& aPayload ) { m_payload = aPayload; } + + KIWAY_EXPRESS* Clone() const { return new KIWAY_EXPRESS( *this ); } + + //KIWAY_EXPRESS() {} + + KIWAY_EXPRESS( FRAME_T aDestination, + wxEventType aCommand, + const std::string& aPayload, + wxWindow* aSource = NULL ); + + KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ); + + /// Is the wxEventType argument to wxEvent() and identifies the class + /// in a hurry. Allocated at startup by wxNewEventType(); + static const wxEventType wxEVENT_ID; + + //DECLARE_DYNAMIC_CLASS( KIWAY_EXPRESS ) + +private: + + void kiway_express( KIWAY_EXPRESS& aEvent ); + + FRAME_T m_destination; + std::string m_payload; +}; + + +typedef void ( wxEvtHandler::*kiwayExpressFunction )( KIWAY_EXPRESS& ); + +#define wxKiwayExressHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(kiwayExpressFunction, &func) + + +#define EVT_KIWAY_EXPRESS( func ) \ + DECLARE_EVENT_TABLE_ENTRY( \ + KIWAY_EXPRESS::wxEVENT_ID, -1, -1, \ + (wxObjectEventFunction) \ + (kiwayExpressFunction) & func, \ + (wxObject*) NULL ), + + +#endif // KIWAY_EXPRESS_H_ + diff --git a/include/kiway_player.h b/include/kiway_player.h index 9a48085dd2..75b1189053 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -84,6 +84,8 @@ private: }; +class KIWAY_EXPRESS; + /** * Class KIWAY_PLAYER * is a wxFrame capable of the OpenProjectFiles function, meaning it can load @@ -100,19 +102,13 @@ class KIWAY_PLAYER : public EDA_BASE_FRAME, public KIWAY_HOLDER public: KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, - long aStyle, const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( aKiway ) - {} + long aStyle, const wxString& aWdoName = wxFrameNameStr ); /// Don't use this one, only wxformbuilder uses it, and it must be augmented with /// a SetKiway() early in derived constructor. KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, - const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( 0 ) - {} + const wxString& aWdoName = wxFrameNameStr ); // For the aCtl argument of OpenProjectFiles() @@ -164,6 +160,20 @@ public: return false; } + + /** + * Function KiwayMailIn + * receives KIWAY_EXPRESS messages from other players. Merely override it + * in derived classes. + */ + virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); + + DECLARE_EVENT_TABLE() + +//private: + + /// event handler, routes to virtual KiwayMailIn() + void kiway_express( KIWAY_EXPRESS& aEvent ); }; diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index b7b00ad9b4..32d19c8d37 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -248,10 +248,13 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) kicad_board : legacy_board; #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB ); - - frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_PCB, true ); + frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, PCBNEW_EXE, QuoteFullPath( board ) ); @@ -266,10 +269,13 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event ) fn.SetExt( NetlistFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB ); - - frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_CVPCB, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, CVPCB_EXE, QuoteFullPath( fn ) ); @@ -284,10 +290,13 @@ void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) fn.SetExt( SchematicFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH ); - - frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_SCH, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); @@ -304,6 +313,8 @@ void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event ) #if USE_KIFACE && 0 + // I cannot make sense of the fn. + #else Execute( this, GERBVIEW_EXE, path ); #endif diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 93b98f3558..7c764e0805 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -131,6 +131,55 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } +std::string FormatProbeItem( BOARD_ITEM* aItem ) +{ + MODULE* module; + + switch( aItem->Type() ) + { + case PCB_MODULE_T: + module = (MODULE*) aItem; + return StrPrintf( "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); + + case PCB_PAD_T: + { + module = (MODULE*) aItem->GetParent(); + wxString pad = ((D_PAD*)aItem)->GetPadName(); + + return StrPrintf( "$PART: \"%s\" $PAD: \"%s\"", + TO_UTF8( module->GetReference() ), + TO_UTF8( pad ) ); + } + + case PCB_MODULE_TEXT_T: + { + module = (MODULE*) aItem->GetParent(); + + TEXTE_MODULE* text_mod = (TEXTE_MODULE*) aItem; + + const char* text_key; + + if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) + text_key = "$REF:"; + else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) + text_key = "$VAL:"; + else + break; + + return StrPrintf( "$PART: \"%s\" %s \"%s\"", + TO_UTF8( module->GetReference() ), + text_key, + TO_UTF8( text_mod->GetText() ) ); + } + + default: + break; + } + + return ""; +} + + /** * Send a remote command to Eeschema via a socket, * @param objectToSync = item to be located on schematic (module, pin or text) @@ -140,61 +189,25 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) * $PART: "reference" $REF: "reference" put cursor on the component ref * $PART: "reference" $VAL: "value" put cursor on the component value */ -void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) +void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem ) { - std::string cmd; - const char* text_key; - MODULE* module = NULL; - D_PAD* pad; - TEXTE_MODULE* text_mod; - wxString msg; - - if( objectToSync == NULL ) +#if 1 + wxASSERT( aSyncItem ); // can't we fix the caller? +#else + if( !aSyncItem ) return; +#endif - switch( objectToSync->Type() ) - { - case PCB_MODULE_T: - module = (MODULE*) objectToSync; - StrPrintf( &cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); - break; + std::string packet = FormatProbeItem( aSyncItem ); - case PCB_PAD_T: - module = (MODULE*) objectToSync->GetParent(); - pad = (D_PAD*) objectToSync; - msg = pad->GetPadName(); - StrPrintf( &cmd, "$PART: \"%s\" $PAD: \"%s\"", - TO_UTF8( module->GetReference() ), - TO_UTF8( msg ) ); - break; - - case PCB_MODULE_TEXT_T: - module = (MODULE*) objectToSync->GetParent(); - text_mod = (TEXTE_MODULE*) objectToSync; - - if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) - text_key = "$REF:"; - else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) - text_key = "$VAL:"; - else - break; - - StrPrintf( &cmd, "$PART: \"%s\" %s \"%s\"", - TO_UTF8( module->GetReference() ), - text_key, - TO_UTF8( text_mod->GetText() ) ); - break; - - default: - break; - } - - if( module && cmd.size() ) + if( packet.size() ) { if( Kiface().IsSingle() ) - SendCommand( MSG_TO_SCH, cmd.c_str() ); + SendCommand( MSG_TO_SCH, packet.c_str() ); else { + Kiway().ExpressMail( FRAME_SCH, 0, packet, this ); } } } + From 1648d7fd431b8e10dd0ab72471d98aaefb692fe7 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 21 Apr 2014 01:51:33 -0500 Subject: [PATCH 09/36] Get cross-probing working under the Kiway. --- common/kiway.cpp | 8 ++++++++ eeschema/cross-probing.cpp | 12 ++++++++++++ eeschema/schframe.cpp | 1 + include/wxEeschemaStruct.h | 2 ++ include/wxPcbStruct.h | 2 ++ pcbnew/cross-probing.cpp | 11 +++++++++++ pcbnew/pcbframe.cpp | 1 + 7 files changed, 37 insertions(+) diff --git a/common/kiway.cpp b/common/kiway.cpp index 72e31aad3e..6031fe7bfa 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -316,7 +316,15 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent ) KIWAY_PLAYER* alive = Player( dest, false ); if( alive ) + { +#if 0 + // This is still broken, but is the way to go. return alive->ProcessEvent( aEvent ); +#else + alive->KiwayMailIn( *mail ); + return true; +#endif + } } return false; diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 0bc51934ab..102b3ff18f 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -180,3 +180,15 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* a } } } + + +#include + +void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) +{ + // @todo switch on command type + std::string payload = mail.GetPayload(); + + ExecuteRemoteCommand( payload.c_str() ); +} + diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 62aec927da..fe38369fd4 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -1073,3 +1073,4 @@ void SCH_EDIT_FRAME::UpdateTitle() SetTitle( title ); } + diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 5f22c1fab7..fea2499c69 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -368,6 +368,8 @@ public: */ virtual void ExecuteRemoteCommand( const char* cmdline ); + void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // virtual overload from KIWAY_PLAYER + void OnLeftClick( wxDC* aDC, const wxPoint& aPosition ); void OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ); bool OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ); diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 6498d7f0f3..70cefc2a36 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -239,6 +239,8 @@ public: */ virtual void ExecuteRemoteCommand( const char* cmdline ); + void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // virtual overload from KIWAY_PLAYER + /** * Function ToPlotter * Open a dialog frame to create plot and drill files diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 7c764e0805..bb119edf23 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -211,3 +211,14 @@ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem ) } } + +#include + +void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) +{ + // @todo switch on command type + std::string payload = mail.GetPayload(); + + ExecuteRemoteCommand( payload.c_str() ); +} + diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 62a21ad005..04ecd6af0b 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -1171,3 +1171,4 @@ void PCB_EDIT_FRAME::SetRotationAngle( int aRotationAngle ) m_rotationAngle = aRotationAngle; } + From 7a129e167b66a1c0412b60ba34481e3e162be710 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 21 Apr 2014 09:49:33 -0500 Subject: [PATCH 10/36] Functional *) void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); *) virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); *) enum MAIL_T expansion into the brave new world if cross KIWAY_PLAYER communications. Let the KIWAY_PLAYING begin..... through well conceived mail from one KIWAY_PLAYER to another. Get thinking now. Add a new MAIL_T value, then send ExpressMail(), and receive it in KiwayMailIn(), it's that easy. --- common/kiway.cpp | 4 ++-- common/kiway_express.cpp | 11 +++++++++++ common/kiway_player.cpp | 4 +++- eeschema/cross-probing.cpp | 21 +++++++++++++++------ include/kiway_express.h | 23 +++++++++++++++++++++++ pcbnew/cross-probing.cpp | 21 +++++++++++++++------ 6 files changed, 69 insertions(+), 15 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index 6031fe7bfa..56dff4a288 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -37,6 +37,7 @@ KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT]; int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; + KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): m_program( aProgram ), m_top( 0 ) @@ -317,8 +318,7 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent ) if( alive ) { -#if 0 - // This is still broken, but is the way to go. +#if 1 return alive->ProcessEvent( aEvent ); #else alive->KiwayMailIn( *mail ); diff --git a/common/kiway_express.cpp b/common/kiway_express.cpp index 230880421d..d11e6e7cee 100644 --- a/common/kiway_express.cpp +++ b/common/kiway_express.cpp @@ -27,7 +27,18 @@ //IMPLEMENT_DYNAMIC_CLASS( KIWAY_EXPRESS, wxEvent ) +#if 0 // requires that this code reside in only a single link image, rather than + // in each of kicad.exe, _pcbnew.kiface, and _eeschema.kiface as now. + // In the current case wxEVENT_ID will get a different value in each link + // image. We need to put this into a shared library for common utilization, + // I think that library should be libki.so. I am reluctant to do that now + // because the cost will be finding libki.so at runtime, and we need infrastructure + // to set our LIB_ENV_VAR to the proper place so libki.so can be reliably found. + // All things in due course. const wxEventType KIWAY_EXPRESS::wxEVENT_ID = wxNewEventType(); +#else +const wxEventType KIWAY_EXPRESS::wxEVENT_ID = 30000; // commmon accross all link images, hopefully unique. +#endif KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) : diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 4706aac339..427fdf3a51 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -8,7 +8,9 @@ BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) /* have not been able to get this to work yet: EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express ) - Use Connect() in constructor until this can be sorted out + Use Connect() in constructor until this can be sorted out. + + OK the problem is KIWAY_PLAYER::wxEVENT_ID not being unique accross all link images. */ END_EVENT_TABLE() diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 102b3ff18f..b8bd39884a 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -176,19 +177,27 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* a SendCommand( MSG_TO_PCB, packet.c_str() ); else { - Kiway().ExpressMail( FRAME_PCB, 0, packet, this ); + // Typically ExpressMail is going to be s-expression packets, but since + // we have existing interpreter of the cross probe packet on the other + // side in place, we use that here. + Kiway().ExpressMail( FRAME_PCB, MAIL_CROSS_PROBE, packet, this ); } } } -#include - void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) { - // @todo switch on command type - std::string payload = mail.GetPayload(); + const std::string& payload = mail.GetPayload(); - ExecuteRemoteCommand( payload.c_str() ); + switch( mail.Command() ) + { + case MAIL_CROSS_PROBE: + ExecuteRemoteCommand( payload.c_str() ); + break; + + // many many others. + + } } diff --git a/include/kiway_express.h b/include/kiway_express.h index 6e95d5ae39..e331f3fcb9 100644 --- a/include/kiway_express.h +++ b/include/kiway_express.h @@ -29,6 +29,20 @@ #include #include + +/** + * Enum MAIL_T + * is the set of mail types sendable via KIWAY::ExpressMail() and supplied as + * the @a aCommand parameter to that function. Such mail will be received in + * KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) and aEvent.Command() will + * match aCommand to ExpressMail(). + */ +enum MAIL_T +{ + MAIL_CROSS_PROBE, +}; + + /** * Class KIWAY_EXPRESS * carries a payload from one KIWAY_PLAYER to anothing within a PROJECT. @@ -42,6 +56,15 @@ public: */ FRAME_T Dest() { return m_destination; } + /** + * Function Command + * returns the EXPRESS_MAIL_T associated with this mail. + */ + MAIL_T Command() + { + return (MAIL_T) GetId(); // re-purposed control id. + } + /** * Function Payload * returns the payload, which can be any text but it typicall self diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index bb119edf23..05f12dc766 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -206,19 +207,27 @@ void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem ) SendCommand( MSG_TO_SCH, packet.c_str() ); else { - Kiway().ExpressMail( FRAME_SCH, 0, packet, this ); + // Typically ExpressMail is going to be s-expression packets, but since + // we have existing interpreter of the cross probe packet on the other + // side in place, we use that here. + Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this ); } } } -#include - void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) { - // @todo switch on command type - std::string payload = mail.GetPayload(); + const std::string& payload = mail.GetPayload(); - ExecuteRemoteCommand( payload.c_str() ); + switch( mail.Command() ) + { + case MAIL_CROSS_PROBE: + ExecuteRemoteCommand( payload.c_str() ); + break; + + // many many others. + + } } From 8afe4599d00921df775ae9433a7637050904f65e Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 22 Apr 2014 10:16:19 -0500 Subject: [PATCH 11/36] Teach cvpcb about new KIWAY based cross-probing, factor out MAIL_T into mail_type.h --- common/kiway.cpp | 2 +- common/kiway_express.cpp | 2 +- cvpcb/cvframe.cpp | 16 +++++++--------- include/kiway.h | 3 ++- include/kiway_express.h | 20 ++++---------------- include/mail_type.h | 16 ++++++++++++++++ 6 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 include/mail_type.h diff --git a/common/kiway.cpp b/common/kiway.cpp index 56dff4a288..9004566f14 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -297,7 +297,7 @@ bool KIWAY::PlayersClose( bool doForce ) void KIWAY::ExpressMail( FRAME_T aDestination, - int aCommand, const std::string& aPayload, wxWindow* aSource ) + MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource ) { KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource ); diff --git a/common/kiway_express.cpp b/common/kiway_express.cpp index d11e6e7cee..8056f4a37b 100644 --- a/common/kiway_express.cpp +++ b/common/kiway_express.cpp @@ -49,7 +49,7 @@ KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) : } -KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, int aCommand, +KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource ) : wxEvent( aCommand, wxEVENT_ID ), m_destination( aDestination ), diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 4adba22292..74b79b3567 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -786,14 +786,10 @@ void CVPCB_MAINFRAME::UpdateTitle() void CVPCB_MAINFRAME::SendMessageToEESCHEMA() { - char cmd[1024]; - int selection; - COMPONENT* Component; - if( m_netlist.IsEmpty() ) return; - selection = m_ListCmp->GetSelection(); + int selection = m_ListCmp->GetSelection(); if ( selection < 0 ) selection = 0; @@ -801,12 +797,14 @@ void CVPCB_MAINFRAME::SendMessageToEESCHEMA() if( m_netlist.GetComponent( selection ) == NULL ) return; - Component = m_netlist.GetComponent( selection ); + COMPONENT* component = m_netlist.GetComponent( selection ); - sprintf( cmd, "$PART: \"%s\"", TO_UTF8( Component->GetReference() ) ); - - SendCommand( MSG_TO_SCH, cmd ); + std::string packet = StrPrintf( "$PART: \"%s\"", TO_UTF8( component->GetReference() ) ); + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_SCH, packet.c_str() ); + else + Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this ); } diff --git a/include/kiway.h b/include/kiway.h index ae4337b563..9b2ffd6b2d 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -102,6 +102,7 @@ as such! As such, it is OK to use UTF8 characters: #include #include #include +#include #define VTBL_ENTRY virtual @@ -324,7 +325,7 @@ public: */ VTBL_ENTRY bool PlayersClose( bool doForce ); - VTBL_ENTRY void ExpressMail( FRAME_T aDestination, int aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); + VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); /** * Function Prj diff --git a/include/kiway_express.h b/include/kiway_express.h index e331f3fcb9..e5fba42f63 100644 --- a/include/kiway_express.h +++ b/include/kiway_express.h @@ -28,24 +28,12 @@ #include #include - - -/** - * Enum MAIL_T - * is the set of mail types sendable via KIWAY::ExpressMail() and supplied as - * the @a aCommand parameter to that function. Such mail will be received in - * KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) and aEvent.Command() will - * match aCommand to ExpressMail(). - */ -enum MAIL_T -{ - MAIL_CROSS_PROBE, -}; +#include /** * Class KIWAY_EXPRESS - * carries a payload from one KIWAY_PLAYER to anothing within a PROJECT. + * carries a payload from one KIWAY_PLAYER to another within a PROJECT. */ class KIWAY_EXPRESS : public wxEvent { @@ -58,7 +46,7 @@ public: /** * Function Command - * returns the EXPRESS_MAIL_T associated with this mail. + * returns the MAIL_T associated with this mail. */ MAIL_T Command() { @@ -78,7 +66,7 @@ public: //KIWAY_EXPRESS() {} KIWAY_EXPRESS( FRAME_T aDestination, - wxEventType aCommand, + MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource = NULL ); diff --git a/include/mail_type.h b/include/mail_type.h new file mode 100644 index 0000000000..9f30d3e284 --- /dev/null +++ b/include/mail_type.h @@ -0,0 +1,16 @@ +#ifndef MAIL_TYPE_H_ +#define MAIL_TYPE_H_ + +/** + * Enum MAIL_T + * is the set of mail types sendable via KIWAY::ExpressMail() and supplied as + * the @a aCommand parameter to that function. Such mail will be received in + * KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) and aEvent.Command() will + * match aCommand to KIWAY::ExpressMail(). + */ +enum MAIL_T +{ + MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing. +}; + +#endif // MAIL_TYPE_H_ From 01f7a53195f9219c1960807254a2f190e1735eec Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 22 Apr 2014 10:26:59 -0500 Subject: [PATCH 12/36] remove KIWAY_EXPRESS::kiway_express() typo, add comments. --- include/kiway_express.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/kiway_express.h b/include/kiway_express.h index e5fba42f63..cebc9dfd95 100644 --- a/include/kiway_express.h +++ b/include/kiway_express.h @@ -72,18 +72,18 @@ public: KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ); - /// Is the wxEventType argument to wxEvent() and identifies the class - /// in a hurry. Allocated at startup by wxNewEventType(); + /// The wxEventType argument to wxEvent() and identifies an event class + /// in a hurry. These wxEventTypes also allow a common class to be used + /// multiple ways. Should be allocated at startup by wxNewEventType(); static const wxEventType wxEVENT_ID; //DECLARE_DYNAMIC_CLASS( KIWAY_EXPRESS ) private: + FRAME_T m_destination; ///< could have been a bitmap indicating multiple recipients + std::string m_payload; ///< very often s-expression text, but not always - void kiway_express( KIWAY_EXPRESS& aEvent ); - - FRAME_T m_destination; - std::string m_payload; + // possible new ideas here. }; From 59d7303b03ea6a4eaa412d9d9a5c3f724554ac23 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 22 Apr 2014 11:10:07 -0500 Subject: [PATCH 13/36] KIWAY::Player() wxASSERT --- common/kiway.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/kiway.cpp b/common/kiway.cpp index 9004566f14..d8e93a00d5 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -246,6 +246,8 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) KIFACE* kiface = KiFACE( face_type ); + wxASSERT( kiface ); + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); return m_player[aFrameType] = frame; From 99a19d27cb22f9dc7769c1b537ef57b4e7d7f25b Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 22 Apr 2014 11:16:34 -0500 Subject: [PATCH 14/36] KIWAY::Player() wxASSERT --- common/kiway.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index d8e93a00d5..198a8a21b6 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -241,16 +241,17 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) if( doCreate ) { FACE_T face_type = KifaceType( aFrameType ); - wxASSERT( face_type != FACE_T(-1) ); KIFACE* kiface = KiFACE( face_type ); - wxASSERT( kiface ); - KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); + if( kiface ) + { + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); - return m_player[aFrameType] = frame; + return m_player[aFrameType] = frame; + } } return NULL; From 61fe97e666ba40b38e7140e624d45d54ed17729d Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Wed, 23 Apr 2014 08:53:07 -0500 Subject: [PATCH 15/36] the boost site is getting slower, somebody might need supply a better host and offer bandwidth there for downloading the boost tar. --- CMakeModules/download_boost.cmake | 2 +- common/kiway.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeModules/download_boost.cmake b/CMakeModules/download_boost.cmake index 601738413c..4a491ec191 100644 --- a/CMakeModules/download_boost.cmake +++ b/CMakeModules/download_boost.cmake @@ -187,7 +187,7 @@ ExternalProject_Add( boost URL http://downloads.sourceforge.net/project/boost/boost/${BOOST_RELEASE}/boost_${BOOST_VERS}.tar.bz2 DOWNLOAD_DIR "${DOWNLOAD_DIR}" - TIMEOUT 600 # 10 minutes + TIMEOUT 1200 # 20 minutes URL_MD5 ${BOOST_MD5} # If download fails, then enable "LOG_DOWNLOAD ON" and try again. # Upon a second failure with logging enabled, then look at these logs: diff --git a/common/kiway.cpp b/common/kiway.cpp index 198a8a21b6..c5e432ca9b 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -249,6 +249,7 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) if( kiface ) { KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); + wxASSERT( frame ); return m_player[aFrameType] = frame; } From 38f36ae45c06f786be3609659a18ecb23a72ca28 Mon Sep 17 00:00:00 2001 From: John Beard Date: Wed, 23 Apr 2014 18:36:31 +0200 Subject: [PATCH 16/36] Add John Beard's patch: new and useful footprint wizards (SIP/SIP, SOIC/SSOP/TSSOP/MSOP and BGA). Add Python utility tools to make wizard scripts more easy to write. --- .../plugins/FootprintWizardDrawingAids.py | 134 +++++++++ .../plugins/HelpfulFootprintWizardPlugin.py | 250 ++++++++++++++++ pcbnew/scripting/plugins/PadArray.py | 148 ++++++++++ pcbnew/scripting/plugins/bga_wizard.py | 98 +++++++ pcbnew/scripting/plugins/qfp_wizard.py | 272 ++++-------------- pcbnew/scripting/plugins/sdip_wizard.py | 200 +++++++++++++ 6 files changed, 893 insertions(+), 209 deletions(-) create mode 100644 pcbnew/scripting/plugins/FootprintWizardDrawingAids.py create mode 100644 pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py create mode 100644 pcbnew/scripting/plugins/PadArray.py create mode 100644 pcbnew/scripting/plugins/bga_wizard.py create mode 100644 pcbnew/scripting/plugins/sdip_wizard.py diff --git a/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py new file mode 100644 index 0000000000..d1046bdafb --- /dev/null +++ b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py @@ -0,0 +1,134 @@ +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +import pcbnew + +class FootprintWizardDrawingAids: + """ + Collection of handy functions to simplify drawing shapes from within + footprint wizards + + A "drawing context" is provided which can be used to set and retain + settings such as line width and layer + """ + def __init__(self, module): + self.module = module + #drawing context defaults + self.dc = { + 'layer': pcbnew.SILKSCREEN_N_FRONT, + 'width': pcbnew.FromMM(0.2) + } + + def SetWidth(self, width): + self.dc['width'] = width + + def SetLayer(self, layer): + self.dc['layer'] = layer + + def Line(self, x1, y1, x2, y2): + + outline = pcbnew.EDGE_MODULE(self.module) + outline.SetWidth(self.dc['width']) + outline.SetLayer(self.dc['layer']) + outline.SetShape(pcbnew.S_SEGMENT) + start = pcbnew.wxPoint(x1, y1) + end = pcbnew.wxPoint(x2, y2) + outline.SetStartEnd(start, end) + self.module.Add(outline) + + # extends from (x1,y1) right + def HLine(self, x, y, l): + """ + Draw a horizontal line from (x,y), rightwards + """ + self.Line(x, y, x + l, y) + + def VLine(self, x, y, l): + """ + Draw a vertical line from (x1,y1), downwards + """ + self.Line(x, y, x, y + l) + + def Polyline(self, pts): + + if len(pts) < 2: + return + + for i in range(0, len(pts) - 1): + self.Line(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1]) + + def Reference(self, x, y, size): + """ + Draw the module's reference as the given point. + + The actual setting of the reference is not done in this drawing + aid - that is up to the wizard + """ + + text_size = pcbnew.wxSize(size, size) + + self.module.Reference().SetPos0(pcbnew.wxPoint(x, y)) + self.module.Reference().SetTextPosition(self.module.Reference().GetPos0()) + self.module.Reference().SetSize(text_size) + + def Value(self, x, y, size): + """ + As for references, draw the module's value + """ + text_size = pcbnew.wxSize(size, size) + + self.module.Value().SetPos0(pcbnew.wxPoint(x, y)) + self.module.Value().SetTextPosition(self.module.Value().GetPos0()) + self.module.Value().SetSize(text_size) + + def Box(self, x, y, w, h): + """ + Draw a rectangular box, centred at (x,y), with given width and + height + """ + self.VLine(x - w/2, y - h/2, h) # left + self.VLine(x + w/2, y - h/2, h) # right + self.HLine(x - w/2, y + h/2, w) # bottom + self.HLine(x - w/2, y - h/2, w) # top + + def NotchedBox(self, x, y, w, h, notchW, notchH): + """ + Draw a box with a notch in the top edge + """ + #limit to half the overall width + notchW = min(x + w/2, notchW) + + # draw notch + self.Polyline([ #three sides of box + (x - w/2, y - h/2), + (x - w/2, y + h/2), + (x + w/2, y + h/2), + (x + w/2, y - h/2), + #the notch + (notchW/2, y - h/2), + (notchW/2, y - h/2 + notchH), + (-notchW/2, y - h/2 + notchH), + (-notchW/2, y - h/2), + (x - w/2, y - h/2) + ]) + + def BoxWithDiagonalAtCorner(self, x, y, w, h, diagSetback): + + self.Box(x, y, w, h) + + #diagonal corner + self.Line(x - w/2 + diagSetback, x - h/2, x - w/2, + x - h/2 + diagSetback) diff --git a/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py new file mode 100644 index 0000000000..de93cfda03 --- /dev/null +++ b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py @@ -0,0 +1,250 @@ +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +import pcbnew +import FootprintWizardDrawingAids + +class FootprintWizardParameterManager: + """ + Functions for helpfully managing parameters to a KiCAD Footprint + Wizard. + + Abstracts away from whatever structure is used by pcbnew's footprint + wizard class + """ + + def __init__(self): + self.parameters = {} + self.GenerateParameterList() + + def GenerateParameterList(self): + """ + Construct parameters here, or leave out to have no parameters + """ + pass + + def CheckParameters(self): + """ + Implement this to make checks on parameter values, filling + parameter_errors (or using the checker routines) + + Subclasses can implment their own and override the parent + defaults and add new ones + """ + pass + + uMM = 1 + uMils = 2 + uNatural = 3 + uBool = 4 + + def AddParam(self, section, param, unit, default, hint = ''): + """ + Add a parameter with some properties. + + TODO: Hints are not supported, as there is as yet nowhere to + put them in the KiCAD interface + """ + + val = None + if unit == self.uMM: + val = pcbnew.FromMM(default) + elif unit == self.uMils: + val = pcbnew.FromMils(default) + elif unit == self.uNatural: + val = default + elif unit == self.uBool: + val = "True" if default else "False" #ugly stringing + else: + print "Warning: Unknown unit type: %s" % unit + return + + if unit in [self.uNatural, self.uBool]: + param = "*%s" % param #star prefix for natural + + if section not in self.parameters: + self.parameters[section] = {} + + self.parameters[section][param] = val + + def _PrintParameterTable(self): + """ + Pretty-print the parameters we have + """ + for name, section in self.parameters.iteritems(): + print " %s:" % name + + for key, value in section.iteritems(): + unit = "" + if (type(value) is int or type(value) is float) and not "*" in key: + unit = "mm" + + if "*" in key: + key = key[1:] + else: + value = pcbnew.ToMM(value) + + print " %s: %s%s" % (key, value, unit) + + def _ParametersHaveErrors(self): + """ + Return true if we discovered errors suring parameter processing + """ + + for name, section in self.parameter_errors.iteritems(): + for k, v in section.iteritems(): + if v: + return True + + return False + + def _PrintParameterErrors(self): + """ + Pretty-print parameters with errors + """ + + for name, section in self.parameter_errors.iteritems(): + printed_section = False + + for key, value in section.iteritems(): + if value: + if not printed_section: + print " %s:" % name + + print " %s: %s (have %s)" % (key, value, + self.parameters[name][key]) + + def ProcessParameters(self): + """ + Make sure the parameters we have meet whatever expectations the + footprint wizard has of them + """ + + self.ClearErrors() + self.CheckParameters(); + + if self._ParametersHaveErrors(): + print "Cannot build footprint: Parameters have errors:" + self._PrintParameterErrors() + return False + + print "Building new %s footprint with the following parameters:" % self.name + + self._PrintParameterTable() + return True + + ################################################################# + # PARAMETER CHECKERS + ################################################################# + + def CheckParamPositiveInt(self, section, param, min_value = 1, + max_value = None, is_multiple_of = 1): + """ + Make sure a parameter can be made into an int, and enforce + limits if required + """ + + try: + self.parameters[section][param] = int(self.parameters[section][param]) + except ValueError: + self.parameter_errors[section][param] = "Must be a valid integer" + return + + if min_value is not None and (self.parameters[section][param] < min_value): + self.parameter_errors[section][param] = "Must be greater than or equal to %d" % (min_value) + return + + if max_value is not None and (self.parameters[section][param] > min_value): + self.parameter_errors[section][param] = "Must be less than or equal to %d" % (max_value) + return + + if is_multiple_of > 1 and (self.parameters[section][param] % is_multiple_of) > 0: + self.parameter_errors[section][param] = "Must be a multiple of %d" % is_multiple_of + return + + return + + def CheckParamBool(self, section, param): + """ + Make sure a parameter looks like a boolean, convert to native + boolean type if so + """ + if str(self.parameters[section][param]).lower() in ["true", "t", "y", "yes", "on", "1", "1.0"]: + self.parameters[section][param] = True; + return + elif str(self.parameters[section][param]).lower() in ["false", "f", "n", "no", "off", "0", "0.0"]: + self.parameters[section][param] = False; + return + + self.parameter_errors[section][param] = "Must be boolean (true/false)" + return + + +class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin, + FootprintWizardParameterManager): + """ + A class to simplify many aspects of footprint creation, leaving only + the foot-print specific routines to the wizards themselves + + Generally, you need to implement: + GetReference() + GetValue() + GenerateParameterList() + CheckParameters() + BuildThisFootprint() + GetName() + GetDescription() + """ + def __init__(self): + pcbnew.FootprintWizardPlugin.__init__(self) + FootprintWizardParameterManager.__init__(self) + + self.name = self.GetName() + self.decription = self.GetDescription() + self.image = self.GetImage() + + def GetReference(self): + raise NotImplementedError + + def GetValuePrefix(self): + return "U" # footprints needing wizards of often ICs + + def GetImage(self): + return "" + + def BuildThisFootprint(self): + raise NotImplementedError + + def BuildFootprint(self): + """ + Actually make the footprint. We defer all but the setup to + the implmenting class + """ + + if not self.ProcessParameters(): + return + + self.module = pcbnew.MODULE(None) # create a new module + + self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids(self.module) + + self.module.SetReference(self.GetReference()) + self.module.SetValue("%s**" % self.GetValuePrefix()) + + fpid = pcbnew.FPID(self.module.GetReference()) #the name in library + self.module.SetFPID( fpid ) + + self.BuildThisFootprint() # implementer's build function diff --git a/pcbnew/scripting/plugins/PadArray.py b/pcbnew/scripting/plugins/PadArray.py new file mode 100644 index 0000000000..99fa70e0dc --- /dev/null +++ b/pcbnew/scripting/plugins/PadArray.py @@ -0,0 +1,148 @@ + +import pcbnew + +class PadMaker: + """ + Useful construction functions for common types of pads + """ + + def __init__(self, module): + self.module = module + + def THPad(self, w, l, drill, shape = pcbnew.PAD_OVAL): + pad = pcbnew.D_PAD(self.module) + + pad.SetSize(pcbnew.wxSize(l, w)) + + pad.SetShape(shape) + + pad.SetAttribute(pcbnew.PAD_STANDARD) + pad.SetLayerMask(pcbnew.PAD_STANDARD_DEFAULT_LAYERS) + pad.SetDrillSize(pcbnew.wxSize(drill, drill)) + + return pad + + def SMDPad(self, w, l, shape = pcbnew.PAD_RECT): + pad = pcbnew.D_PAD(self.module) + pad.SetSize(pcbnew.wxSize(l, w)) + + pad.SetShape(shape) + + pad.SetAttribute(pcbnew.PAD_SMD) + pad.SetLayerMask(pcbnew.PAD_SMD_DEFAULT_LAYERS) + + return pad + + def SMTRoundPad(self, size): + pad = self.SMDPad(size, size, shape = pcbnew.PAD_CIRCLE) + return pad + +class PadArray: + + def __init__(self): + self.firstPad = 1; + + def SetFirstPadInArray(self, fpNum): + self.firstPad = fpNum + + # HACK! pad should one day have its own clone method + def ClonePad(self): + + pad = pcbnew.D_PAD(self.pad.GetParent()) + + pad.SetSize(self.pad.GetSize()) + pad.SetShape(self.pad.GetShape()) + pad.SetAttribute(self.pad.GetAttribute()) + pad.SetLayerMask(self.pad.GetLayerMask()) + pad.SetDrillSize(self.pad.GetDrillSize()) + + return pad + + def AddPad(self, pad): + self.pad.GetParent().Add(pad) + +class PadGridArray(PadArray): + + def __init__(self, pad, nx, ny, px, py, pin1Pos): + # this pad is more of a "context", we will use it as a source of + # pad data, but not actually add it + self.pad = pad + self.nx = int(nx) + self.ny = int(ny) + self.px = px + self.py = py + self.pin1Pos = pin1Pos + + # handy utility function 1 - A, 2 - B, 26 - AA, etc + # aIndex = 0 for 0 - A + def AlphaNameFromNumber(self, n, aIndex = 1): + + div, mod = divmod(n - aIndex, 26) + alpha = chr(65 + mod) + + if div > 0: + return self.AlphaNameFromNumber(div) + alpha; + + return alpha; + + # right to left, top to bottom + def NamingFunction(self, x, y): + return self.firstPad + (self.nx * y + x) + + #relocate the pad and add it as many times as we need + def AddPadsToModule(self): + + for x in range(0, self.nx): + for y in range(self.ny): + posX = self.pin1Pos.x + (self.px * x) + posY = self.pin1Pos.y + (self.py * y) + + pos = pcbnew.wxPoint(posX, posY) + + # THIS DOESN'T WORK yet! + #pad = self.pad.Clone() + pad = self.ClonePad() + + pad.SetPos0(pos) + pad.SetPosition(pos) + + pad.SetPadName(str(self.NamingFunction(x,y))) + + self.AddPad(pad) + +class PadLineArray(PadGridArray): + + def __init__(self, pad, n, pitch, isVertical, pin1Pos): + + if isVertical: + PadGridArray.__init__(self, pad, 1, n, 0, pitch, pin1Pos) + else: + PadGridArray.__init__(self, pad, n, 1, pitch, 0, pin1Pos) + +class RectPadArray(PadArray): + + def __init__(self, nx, ny, pitch, xpitch, ypitch, pin1Pos): + + #left row + pin1Pos = pcbnew.wxPoint(-h_pitch / 2, -row_len / 2) + array = PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(1) + array.AddPadsToModule() + + #bottom row + pin1Pos = pcbnew.wxPoint(-row_len / 2, v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(pads_per_row + 1) + array.AddPadsToModule() + + #right row + pin1Pos = pcbnew.wxPoint(h_pitch / 2, row_len / 2) + array = PadLineArray(h_pad, pads_per_row, -pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(2*pads_per_row + 1) + array.AddPadsToModule() + + #top row + pin1Pos = pcbnew.wxPoint(row_len / 2, -v_pitch / 2) + array = PadLineArray(v_pad, pads_per_row, -pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(3*pads_per_row + 1) + array.AddPadsToModule() diff --git a/pcbnew/scripting/plugins/bga_wizard.py b/pcbnew/scripting/plugins/bga_wizard.py new file mode 100644 index 0000000000..7fd6258f3e --- /dev/null +++ b/pcbnew/scripting/plugins/bga_wizard.py @@ -0,0 +1,98 @@ +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +from __future__ import division +import pcbnew + +import HelpfulFootprintWizardPlugin as HFPW +import PadArray as PA + + +class BGAPadGridArray(PA.PadGridArray): + + def NamingFunction(self, x, y): + return "%s%d" % (self.AlphaNameFromNumber(y + 1), x + 1) + + +class BGAWizard(HFPW.HelpfulFootprintWizardPlugin): + + def GetName(self): + return "BGA" + + def GetDescription(self): + return "Ball Grid Array Footprint Wizard" + + def GenerateParameterList(self): + + self.AddParam("Pads", "pad pitch", self.uMM, 1) + self.AddParam("Pads", "pad size", self.uMM, 0.5) + self.AddParam("Pads", "row count", self.uNatural, 5) + self.AddParam("Pads", "column count", self.uNatural, 5) + self.AddParam("Pads", "outline x margin", self.uMM, 1) + self.AddParam("Pads", "outline y margin", self.uMM, 1) + + def CheckParameters(self): + + self.CheckParamPositiveInt("Pads", "*row count") + self.CheckParamPositiveInt("Pads", "*column count") + + + def GetReference(self): + + pins = self.parameters["Pads"]["*row count"] * self.parameters["Pads"]["*column count"] + + return "BGA %d" % pins + + + def GetValuePrefix(self): + return "U" + + + def BuildThisFootprint(self): + + pads = self.parameters["Pads"] + + rows = pads["*row count"] + cols = pads["*column count"] + pad_size = pads["pad size"] + + pad_size = pcbnew.wxSize(pad_size, pad_size) + + pad_pitch = pads["pad pitch"] + + # add in the pads + pad = PA.PadMaker(self.module).SMTRoundPad(pads["pad size"]) + + pin1Pos = pcbnew.wxPoint(-((rows - 1) * pad_pitch) / 2, + -((cols - 1) * pad_pitch) / 2) + + array = BGAPadGridArray(pad, rows, cols, pad_pitch, pad_pitch, pin1Pos) + array.AddPadsToModule() + + #box + ssX = -pin1Pos.x + pads["outline x margin"] + ssY = -pin1Pos.y + pads["outline y margin"] + + self.draw.BoxWithDiagonalAtCorner(0, 0, ssX*2, ssY*2, pads["outline x margin"]) + + #reference and value + textSize = pcbnew.FromMM(0.8) + + self.draw.Value(0, - ssY - textSize, textSize) + self.draw.Reference(0, ssY + textSize, textSize) + + +BGAWizard().register() diff --git a/pcbnew/scripting/plugins/qfp_wizard.py b/pcbnew/scripting/plugins/qfp_wizard.py index 2df89e113b..0034c1fadb 100644 --- a/pcbnew/scripting/plugins/qfp_wizard.py +++ b/pcbnew/scripting/plugins/qfp_wizard.py @@ -1,235 +1,89 @@ +from __future__ import division import pcbnew -def abs(x): - if x < 0: - return -x +import HelpfulFootprintWizardPlugin +import PadArray as PA - return x +class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin): -class QFPWizard(pcbnew.FootprintWizardPlugin): - def __init__(self): - pcbnew.FootprintWizardPlugin.__init__(self) - self.name = "QFP" - self.description = "QFP Footprint Wizard" - self.parameters = { - "Pads": { - "*n": 100, - "pitch": pcbnew.FromMM(0.5), - "width": pcbnew.FromMM(0.25), - "length": pcbnew.FromMM(1.5), - "horizontal pitch": pcbnew.FromMM(15), - "vertical pitch": pcbnew.FromMM(15), - "*oval": "True" - }, - "Package": { - "width": pcbnew.FromMM(14), - "height": pcbnew.FromMM(14) - } - } + def GetName(self): + return "QFP" - self.ClearErrors() + def GetDescription(self): + return "QFP Footprint Wizard" - def smd_rect_pad(self, module, size, pos, name): - pad = pcbnew.D_PAD(module) + def GenerateParameterList(self): + self.AddParam("Pads", "n", self.uNatural, 100) + self.AddParam("Pads", "pad pitch", self.uMM, 0.5) + self.AddParam("Pads", "pad width", self.uMM, 0.25) + self.AddParam("Pads", "pad length", self.uMM, 1.5) + self.AddParam("Pads", "vertical pitch", self.uMM, 15) + self.AddParam("Pads", "horizontal pitch", self.uMM, 15) + self.AddParam("Pads", "oval", self.uBool, True) - pad.SetSize(size) - - if self.parameters['Pads'].get('*oval', "true").lower() == "true": - pad.SetShape(pcbnew.PAD_OVAL) - else: - pad.SetShape(pcbnew.PAD_RECT) - - pad.SetAttribute(pcbnew.PAD_SMD) - pad.SetLayerMask(pcbnew.PAD_SMD_DEFAULT_LAYERS) - pad.SetPos0(pos) - pad.SetPosition(pos) - pad.SetPadName(name) - - return pad + self.AddParam("Pads", "package width", self.uMM, 14) + self.AddParam("Pads", "package height", self.uMM, 14) def CheckParameters(self): - errors = "" - pads = self.parameters - num_pads = pads["Pads"]["*n"] - if (num_pads < 1): - self.parameter_errors["Pads"]["*n"] = "Must be positive" - errors +="Pads/n has wrong value, " - pads["Pads"]["*n"] = int(num_pads) # Reset to int instead of float + self.CheckParamPositiveInt("Pads", "*n", is_multiple_of = 4) - return errors + def GetReference(self): + return "QFP %d" % self.parameters["Pads"]["*n"] - def BuildFootprint(self): - if self.has_errors(): - print "Cannot build footprint: Parameters have errors:" - print self.parameter_errors - return + def BuildThisFootprint(self): - print "Building new QFP footprint with the following parameters:" - self.print_parameter_table() + pads = self.parameters["Pads"] - self.module = pcbnew.MODULE(None) # create a new module + pad_pitch = pads["pad pitch"] + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] - pads = self.parameters - num_pads = int(pads["Pads"]["*n"]) - pad_width = pads["Pads"]["width"] - pad_length = pads["Pads"]["length"] - pad_pitch = pads["Pads"]["pitch"] - pad_horizontal_pitch = pads["Pads"]["horizontal pitch"] - pad_vertical_pitch = pads["Pads"]["vertical pitch"] + v_pitch = pads["vertical pitch"] + h_pitch = pads["horizontal pitch"] - package_width = pads["Package"]["width"] - package_height = pads["Package"]["height"] + pads_per_row = pads["*n"] // 4 - side_length = pad_pitch * ((num_pads / 4) - 1) + row_len = (pads_per_row - 1) * pad_pitch - offsetX = pad_pitch * ((num_pads / 4) - 1) / 2 - text_size = pcbnew.wxSize(pcbnew.FromMM(0.8), pcbnew.FromMM(0.8)) + h_pad = PA.PadMaker(self.module).SMDPad(pad_width, pad_length, shape = pcbnew.PAD_OVAL) + v_pad = PA.PadMaker(self.module).SMDPad(pad_length, pad_width, shape = pcbnew.PAD_OVAL) - self.module.SetReference("QFP %d" % int(num_pads)) - self.module.Reference().SetPos0(pcbnew.wxPoint(0, pcbnew.FromMM(-0.8))) - self.module.Reference().SetTextPosition(self.module.Reference().GetPos0()) - self.module.Reference().SetSize(text_size) + #left row + pin1Pos = pcbnew.wxPoint(-h_pitch / 2, -row_len / 2) + array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(1) + array.AddPadsToModule() - self.module.SetValue("U**") - self.module.Value().SetPos0(pcbnew.wxPoint(0, pcbnew.FromMM(+0.8))) - self.module.Value().SetTextPosition(self.module.Value().GetPos0()) - self.module.Value().SetSize(text_size) + #bottom row + pin1Pos = pcbnew.wxPoint(-row_len / 2, v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(pads_per_row + 1) + array.AddPadsToModule() - fpid = pcbnew.FPID(self.module.GetReference()) #the name in library - self.module.SetFPID( fpid ) + #right row + pin1Pos = pcbnew.wxPoint(h_pitch / 2, row_len / 2) + array = PA.PadLineArray(h_pad, pads_per_row, -pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(2*pads_per_row + 1) + array.AddPadsToModule() - pad_size_left_right = pcbnew.wxSize(pad_length, pad_width) - pad_size_bottom_top = pcbnew.wxSize(pad_width, pad_length) + #top row + pin1Pos = pcbnew.wxPoint(row_len / 2, -v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, -pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(3*pads_per_row + 1) + array.AddPadsToModule() - for cur_pad in range(0, num_pads): - side = int(cur_pad / (num_pads / 4)) # 0 -> left, 1 -> bottom, 2 -> right, 3 -> top + limX = pads["package width"] / 2 + limY = pads["package height"] / 2 + inner = (row_len / 2) + pad_pitch - if side == 0 or side == 2: - pad_size = pad_size_left_right - - pad_pos_x = -(pad_horizontal_pitch / 2) - pad_pos_y = (cur_pad % (num_pads / 4)) * pad_pitch - (side_length / 2) - - if side == 2: - pad_pos_x = -pad_pos_x - pad_pos_y = -pad_pos_y - - else: - pad_size = pad_size_bottom_top - - pad_pos_x = (cur_pad % (num_pads / 4)) * pad_pitch - (side_length / 2) - pad_pos_y = -(pad_vertical_pitch / 2) - - if side == 1: - pad_pos_y = -pad_pos_y - else: - pad_pos_x = -pad_pos_x - - pad_pos = pcbnew.wxPoint(pad_pos_x, pad_pos_y) - - pad = self.smd_rect_pad(self.module, pad_size, pad_pos, str(cur_pad + 1)) - - self.module.Add(pad) - - half_package_width = package_width / 2 - half_package_height = package_height / 2 - - package_pad_height_offset = abs(package_height - side_length) / 2 - pad_pitch - package_pad_width_offset = abs(package_width - side_length) / 2 - pad_pitch - - # Bottom Left Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, half_package_height - package_pad_height_offset) - end = pcbnew.wxPoint(-half_package_width, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Left Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, half_package_height) - end = pcbnew.wxPoint(-half_package_width + package_pad_width_offset, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Right Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, half_package_height - package_pad_height_offset) - end = pcbnew.wxPoint(half_package_width, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Right Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, half_package_height) - end = pcbnew.wxPoint(half_package_width - package_pad_width_offset, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Right Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, -half_package_height + package_pad_height_offset) - end = pcbnew.wxPoint(half_package_width, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Right Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, -half_package_height) - end = pcbnew.wxPoint(half_package_width - package_pad_width_offset, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Left Edge, straight line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, -half_package_height + package_pad_height_offset) - end = pcbnew.wxPoint(-half_package_width + package_pad_width_offset, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - def print_parameter_table(self): - for name, section in self.parameters.iteritems(): - print " %s:" % name - - for key, value in section.iteritems(): - unit = "" - if (type(value) is int or type(value) is float) and not "*" in key: - unit = "mm" - - if "*" in key: - key = key[1:] - else: - value = pcbnew.ToMM(value) - - print " %s: %s%s" % (key, value, unit) - - def has_errors(self): - for name, section in self.parameter_errors.iteritems(): - for k, v in section.iteritems(): - if v: - return True - - return False + #top left - diagonal + self.draw.Line(-limX, -inner, -inner, -limY) + # top right + self.draw.Polyline([(inner, -limY), (limX, -limY), (limX, -inner)]) + # bottom left + self.draw.Polyline([(-inner, limY), (-limX, limY), (-limX, inner)]) + # bottom right + self.draw.Polyline([(inner, limY), (limX, limY), (limX, inner)]) QFPWizard().register() diff --git a/pcbnew/scripting/plugins/sdip_wizard.py b/pcbnew/scripting/plugins/sdip_wizard.py new file mode 100644 index 0000000000..c2a37653cb --- /dev/null +++ b/pcbnew/scripting/plugins/sdip_wizard.py @@ -0,0 +1,200 @@ +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +from __future__ import division +import pcbnew + +import HelpfulFootprintWizardPlugin as HFPW +import PadArray as PA + + +class RowedGridArray(PA.PadGridArray): + + def NamingFunction(self, x, y): + if (x % 2) == 0: # even row, count up + return (x * self.ny) + y + 1; + else: # odd row, count down + return (self.ny * (x + 1)) - y; + +class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin): + + def GenerateParameterList(self): + + # defaults for a DIP package + self.AddParam("Pads", "n", self.uNatural, 24) + self.AddParam("Pads", "silk screen inside", self.uBool, False) + self.AddParam("Pads", "row count", self.uNatural, 2) + + def CheckParameters(self): + self.CheckParamPositiveInt("Pads", "*row count") + self.CheckParamPositiveInt("Pads", "*n", is_multiple_of = self.parameters["Pads"]["*row count"]) + self.CheckParamBool("Pads", "*silk screen inside") #can do this internally to parameter manager? + + def BuildThisFootprint(self): + + pads = self.parameters["Pads"] + + num_pads = pads["*n"] + + pad_length = pads["pad length"] + pad_width = pads["pad width"] + row_pitch = pads["row spacing"] + pad_pitch = pads["pad pitch"] + num_rows = pads["*row count"] + + pads_per_row = num_pads // num_rows + + row_length = pad_pitch * (pads_per_row - 1) #fenceposts + + # add in the pads + pad = self.GetPad() + + pin1Pos = pcbnew.wxPoint(-((num_rows - 1) * row_pitch) / 2, -row_length / 2) + + array = RowedGridArray(pad, num_rows, pads_per_row, row_pitch, pad_pitch, pin1Pos) + array.AddPadsToModule() + + # draw the Silk Screen + + pad_length = pads["pad length"] + pad_width = pads["pad width"] + + ssXOffset = -pad_length / 2 - pads["outline x margin"] + ssYOffset = -pad_width / 2 - pads["outline y margin"] + + + if pads["*silk screen inside"]: + ssXOffset *= -1 + + ssX = -pin1Pos.x - ssXOffset + ssY = -pin1Pos.y - ssYOffset + + + self.DrawBox(ssX, ssY) + + #reference and value + textSize = pcbnew.FromMM(0.8) + + self.draw.Value(0, - ssY - textSize, textSize) + self.draw.Reference(0, ssY + textSize, textSize) + + +class SDIPWizard(RowedFootprint): + + def GetName(self): + return "S/DIP" + + def GetDescription(self): + return "Single/Dual Inline Package Footprint Wizard" + + def GenerateParameterList(self): + RowedFootprint.GenerateParameterList(self) + + self.AddParam("Pads", "pad pitch", self.uMils, 100) + self.AddParam("Pads", "pad width", self.uMils, 60) + self.AddParam("Pads", "pad length", self.uMils, 150) + self.AddParam("Pads", "row spacing", self.uMils, 300) + self.AddParam("Pads", "drill size", self.uMM, 1) + self.AddParam("Pads", "outline x margin", self.uMM, 0.5) + self.AddParam("Pads", "outline y margin", self.uMM, 1) + + def GetReference(self): + + rows = self.parameters["Pads"]["*row count"] + + if rows == 1: + name = "SIP" + elif rows == 2: + name = "DIP" + else: # triple and up aren't really a thing, but call it something! + name = "xIP" + + return "%s %d" % (name, self.parameters["Pads"]["*n"]) + + def GetPad(self): + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] + drill = self.parameters["Pads"]["drill size"] + return PA.PadMaker(self.module).THPad(pad_width, pad_length, drill, shape = pcbnew.PAD_OVAL) + + def DrawBox(self, ssX, ssY): + + if self.parameters["Pads"]["*row count"] == 2: + + # ---------- + # |8 7 6 5 | + # > | + # |1 2 3 4 | + # ---------- + + # draw the notch + notchWidth = pcbnew.FromMM(3) + notchHeight = pcbnew.FromMM(1) + + self.draw.NotchedBox(0, 0, ssX*2, ssY*2, notchWidth, notchHeight) + else: + # ----------------- + # |1|2 3 4 5 6 7 8| + # ----------------- + self.draw.Box(ssX*2, ssY*2) + + #line between pin1 and pin2 + pad_pitch = self.parameters["Pads"]["pad pitch"]; + self.draw.HLine(-ssX, pin1Pos.y + pad_pitch/2, ssX * 2) + + return ssX, ssY + +SDIPWizard().register() + + +class SOICWizard(RowedFootprint): + + def GetName(self): + return "SOIC" + + def GetDescription(self): + return "SOIC, MSOP, SSOP, TSSOP, etc, footprint wizard" + + def GetReference(self): + return "%s %d" % ("SOIC", self.parameters["Pads"]["*n"]) + + def GenerateParameterList(self): + RowedFootprint.GenerateParameterList(self) + + #and override some of them + self.AddParam("Pads", "pad pitch", self.uMM, 1.27) + self.AddParam("Pads", "pad width", self.uMM, 0.6) + self.AddParam("Pads", "pad length", self.uMM, 2.2) + self.AddParam("Pads", "row spacing", self.uMM, 5.2) + + self.AddParam("Pads", "outline x margin", self.uMM, 0.5) + self.AddParam("Pads", "outline y margin", self.uMM, 0.5) + + def GetPad(self): + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] + return PA.PadMaker(self.module).SMDPad(pad_width, pad_length, shape = pcbnew.PAD_RECT) + + def DrawBox(self, ssX, ssY): + + # ---------- + # |8 7 6 5 | + # |1 2 3 4 | + # \--------- + + self.draw.BoxWithDiagonalAtCorner(0, 0, ssX*2, ssY*2, pcbnew.FromMM(1)) + +SOICWizard().register() From 32a9a4a400a276fd7228b55701ce0a766cbf34fe Mon Sep 17 00:00:00 2001 From: Andrey Fedorushkov Date: Thu, 24 Apr 2014 09:44:27 +0400 Subject: [PATCH 17/36] fix not correct build if BUILD_GITHUB_PLUGIN=ON in linux rpm-based distro --- pcbnew/github/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pcbnew/github/CMakeLists.txt b/pcbnew/github/CMakeLists.txt index 34bf3c9cef..48596231ae 100644 --- a/pcbnew/github/CMakeLists.txt +++ b/pcbnew/github/CMakeLists.txt @@ -54,9 +54,7 @@ set( GITHUB_PLUGIN_SRCS github_plugin.cpp ) -add_library( github_plugin - github_plugin.cpp - ) +add_library( github_plugin STATIC ${GITHUB_PLUGIN_SRCS} ) # No, you don't get github without boost and openssl. Boost_LIBRARIES now moved up # into CMakeLists.txt for pcbnew and cvpcb: From 8416c5d65584b1acd5cdf456728d81a3e17e72f9 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 24 Apr 2014 06:30:14 -0500 Subject: [PATCH 18/36] Add diagnostic message for missing *.kiface, which is now a fatal installation bug. --- common/kiway.cpp | 18 ++++++++++++++++++ kicad/kicad.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/common/kiway.cpp b/common/kiway.cpp index c5e432ca9b..8e5966506c 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -183,6 +183,24 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) // In any of the failure cases above, dso.Unload() should be called here // by dso destructor. + // However: + + // There is a file installation bug. We only look for KIFACE_I's which we know + // to exist, and we did not find one. If we do not find one, this is an + // installation bug. + + wxString msg = wxString::Format( wxT( + "Fatal Installation Bug\nmissing file:\n'%s'\n\nargv[0]:\n'%s'" ), + GetChars( dname ), + GetChars( wxStandardPaths::Get().GetExecutablePath() ) + ); + + // This is a fatal error, one from which we cannot recover, nor do we want + // to protect against in client code which would require numerous noisy + // tests in numerous places. So we inform the user that the installation + // is bad. This exception will likely not get caught until way up in + // PGM_BASE or a derivative, at which point the process will exit gracefully. + THROW_IO_ERROR( msg ); } return NULL; diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index ac0a734dc1..44e9488e56 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -280,6 +280,30 @@ struct APP_KICAD : public wxApp return wxApp::OnExit(); } + int OnRun() // overload wxApp virtual + { + try + { + return wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) );; + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.errorText ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + return -1; + } + /** * Function MacOpenFile * is specific to MacOSX (not used under Linux or Windows). From 8f0a773bc46f5763f36d3d6f221403fc3beba327 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 24 Apr 2014 12:21:34 -0500 Subject: [PATCH 19/36] Add custom target on linux to make build-dir symlinks. --- kicad/CMakeLists.txt | 70 ++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 2647e93792..1d76b4696b 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -1,12 +1,12 @@ -add_definitions(-DKICAD) +add_definitions( -DKICAD ) -include_directories(BEFORE ${INC_BEFORE}) +include_directories( BEFORE ${INC_BEFORE} ) include_directories( ${INC_AFTER} ) -set(KICAD_SRCS +set( KICAD_SRCS class_treeprojectfiles.cpp class_treeproject_item.cpp commandframe.cpp @@ -19,48 +19,66 @@ set(KICAD_SRCS preferences.cpp prjconfig.cpp project_template.cpp - tree_project_frame.cpp) + tree_project_frame.cpp + ) -if(MINGW) +if( MINGW ) # KICAD_RESOURCES variable is set by the macro. - mingw_resource_compiler(kicad) + mingw_resource_compiler( kicad ) endif() -if(APPLE) - set(KICAD_RESOURCES kicad.icns kicad_doc.icns) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/kicad.icns" - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/kicad_doc.icns" - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set(MACOSX_BUNDLE_ICON_FILE kicad.icns) - set(MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.kicad) - set(MACOSX_BUNDLE_NAME kicad) -endif(APPLE) +if( APPLE ) + set( KICAD_RESOURCES kicad.icns kicad_doc.icns ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad_doc.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set( MACOSX_BUNDLE_ICON_FILE kicad.icns ) + set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.kicad ) + set( MACOSX_BUNDLE_NAME kicad ) +endif() -add_executable(kicad WIN32 MACOSX_BUNDLE +add_executable( kicad WIN32 MACOSX_BUNDLE ${KICAD_SRCS} ${KICAD_EXTRA_SRCS} ${KICAD_RESOURCES} ) -if(APPLE) - set_target_properties(kicad PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) - target_link_libraries(kicad +if( UNIX ) + # for build directory: create kiface symlinks so kicad (exe) can be run in-situ + add_custom_target( kiface_sym_links + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/eeschema/_eeschema.kiface" "${CMAKE_BINARY_DIR}/kicad/_eeschema.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.kiface" "${CMAKE_BINARY_DIR}/kicad/_pcbnew.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/cvpcb/_cvpcb.kiface" "${CMAKE_BINARY_DIR}/kicad/_cvpcb.kiface" + COMMENT "Making /kicad/" + ) +endif() + + +if( APPLE ) + set_target_properties( kicad PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist + ) + target_link_libraries( kicad common bitmaps polygon ${wxWidgets_LIBRARIES} ) -else(APPLE) - target_link_libraries(kicad +else() + target_link_libraries( kicad common bitmaps polygon ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES} ) -endif(APPLE) +endif() + +install( TARGETS kicad + DESTINATION ${KICAD_BIN} + COMPONENT binary + ) -install(TARGETS kicad - DESTINATION ${KICAD_BIN} - COMPONENT binary) From 1e68c5f8b3e1f1bc6038406fc90d2bfce7248988 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 24 Apr 2014 12:25:57 -0500 Subject: [PATCH 20/36] comment fix, simplified unhandled IO_ERROR exception report in single_top.cpp. --- CMakeLists.txt | 23 ++++++++++++----------- common/kiway.cpp | 4 ++-- common/single_top.cpp | 4 +--- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c061111f3..092cae2587 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -621,7 +621,6 @@ add_subdirectory( 3d-viewer ) add_subdirectory( cvpcb ) add_subdirectory( eeschema ) add_subdirectory( gerbview ) -add_subdirectory( kicad ) add_subdirectory( lib_dxf ) add_subdirectory( pcbnew ) add_subdirectory( polygon ) @@ -629,9 +628,11 @@ add_subdirectory( pagelayout_editor ) add_subdirectory( potrace ) add_subdirectory( bitmap2component ) add_subdirectory( pcb_calculator ) +add_subdirectory( kicad ) # should follow pcbnew, eeschema add_subdirectory( tools ) add_subdirectory( utils ) add_subdirectory( qa ) + #add_subdirectory( new ) @@ -651,16 +652,16 @@ add_dependencies( pnsrouter boost ) if ( KICAD_BUILD_STATIC OR KICAD_BUILD_DYNAMIC ) -add_dependencies( pcbnew lib-dependencies ) -add_dependencies( eeschema lib-dependencies ) -add_dependencies( cvpcb lib-dependencies ) -add_dependencies( common lib-dependencies ) -add_dependencies( gal lib-dependencies ) -add_dependencies( pcbcommon lib-dependencies ) -add_dependencies( 3d-viewer lib-dependencies ) -add_dependencies( pcad2kicadpcb lib-dependencies ) -add_dependencies( pl_editor lib-dependencies ) -add_dependencies( pnsrouter lib-dependencies ) + add_dependencies( pcbnew lib-dependencies ) + add_dependencies( eeschema lib-dependencies ) + add_dependencies( cvpcb lib-dependencies ) + add_dependencies( common lib-dependencies ) + add_dependencies( gal lib-dependencies ) + add_dependencies( pcbcommon lib-dependencies ) + add_dependencies( 3d-viewer lib-dependencies ) + add_dependencies( pcad2kicadpcb lib-dependencies ) + add_dependencies( pl_editor lib-dependencies ) + add_dependencies( pnsrouter lib-dependencies ) endif() if ( KICAD_BUILD_DYNAMIC ) diff --git a/common/kiway.cpp b/common/kiway.cpp index 8e5966506c..13c0072a92 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -198,8 +198,8 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) // This is a fatal error, one from which we cannot recover, nor do we want // to protect against in client code which would require numerous noisy // tests in numerous places. So we inform the user that the installation - // is bad. This exception will likely not get caught until way up in - // PGM_BASE or a derivative, at which point the process will exit gracefully. + // is bad. This exception will likely not get caught until way up in the + // wxApp derivative, at which point the process will exit gracefully. THROW_IO_ERROR( msg ); } diff --git a/common/single_top.cpp b/common/single_top.cpp index 0200170b10..c153f891d4 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -176,9 +176,7 @@ struct APP_SINGLE_TOP : public wxApp } catch( const IO_ERROR& ioe ) { - wxLogError( wxT( "Unhandled exception class: %s what: %s" ), - GetChars( FROM_UTF8( typeid( ioe ).name() ) ), - GetChars( ioe.errorText ) ); + wxLogError( GetChars( ioe.errorText ) ); } catch(...) { From b427aa49c1f52ad0a75d5cf48d5fc5cb90765077 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Thu, 24 Apr 2014 13:31:11 -0500 Subject: [PATCH 21/36] single_top w/o kiface whines and exits gracefully. --- common/basicframe.cpp | 7 ++-- common/single_top.cpp | 81 +++++++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index a19fbd96cf..91a5c0b4ee 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -107,7 +107,10 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event ) { - SaveSettings( config() ); // virtual, wxFrame specific + wxConfigBase* cfg = config(); + + if( cfg ) + SaveSettings( cfg ); // virtual, wxFrame specific event.Skip(); // we did not "handle" the event, only eavesdropped on it. } @@ -266,7 +269,7 @@ wxConfigBase* EDA_BASE_FRAME::config() { // KICAD_MANAGER_FRAME overrides this wxConfigBase* ret = Kiface().KifaceSettings(); - wxASSERT( ret ); + //wxASSERT( ret ); return ret; } diff --git a/common/single_top.cpp b/common/single_top.cpp index c153f891d4..2632a32eae 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -152,21 +152,10 @@ PGM_BASE& Pgm() struct APP_SINGLE_TOP : public wxApp { bool OnInit() // overload wxApp virtual - { - return Pgm().OnPgmInit( this ); - } - - int OnExit() // overload wxApp virtual - { - Pgm().OnPgmExit(); - return wxApp::OnExit(); - } - - int OnRun() // overload wxApp virtual { try { - return wxApp::OnRun(); + return Pgm().OnPgmInit( this ); } catch( const std::exception& e ) { @@ -183,7 +172,42 @@ struct APP_SINGLE_TOP : public wxApp wxLogError( wxT( "Unhandled exception of unknown type" ) ); } - return -1; + Pgm().OnPgmExit(); + + return false; + } + + int OnExit() // overload wxApp virtual + { + return wxApp::OnExit(); + } + + int OnRun() // overload wxApp virtual + { + int ret = -1; + + try + { + ret = wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) );; + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.errorText ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + Pgm().OnPgmExit(); + + return ret; } /** @@ -240,10 +264,30 @@ static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName ) // No further reporting required here. } - // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. - (void) dso.Detach(); + else + { + // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. + (void) dso.Detach(); - return (KIFACE_GETTER_FUNC*) addr; + return (KIFACE_GETTER_FUNC*) addr; + } + + // There is a file installation bug. We only look for KIFACE_I's which we know + // to exist, and we did not find one. If we do not find one, this is an + // installation bug. + + wxString msg = wxString::Format( wxT( + "Fatal Installation Bug\nmissing file:\n'%s'\n\nargv[0]:\n'%s'" ), + GetChars( aDSOName ), + GetChars( wxStandardPaths::Get().GetExecutablePath() ) + ); + + // This is a fatal error, one from which we cannot recover, nor do we want + // to protect against in client code which would require numerous noisy + // tests in numerous places. So we inform the user that the installation + // is bad. This exception will likely not get caught until way up in the + // wxApp derivative, at which point the process will exit gracefully. + THROW_IO_ERROR( msg ); #else return &KIFACE_GETTER; @@ -415,9 +459,8 @@ void PGM_SINGLE_TOP::OnPgmExit() saveCommonSettings(); - // write common settings to disk, and destroy everything in PGM_BASE, - // especially wxSingleInstanceCheckerImpl earlier than wxApp and earlier - // than static destruction would. + // Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl + // earlier than wxApp and earlier than static destruction would. PGM_BASE::destroy(); } From 9c1f6b7307423f4a962604746491c603491a3bf5 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 24 Apr 2014 20:54:49 +0200 Subject: [PATCH 22/36] Pcbnew: fix Bug #1304418 . Fix also a related issue which crashes Pcbnew in some corner cases. (for instance, when a footprint from the currently edited board is loaded in the footprint editor, and when the board is cleared or reloaded) In footprint editor, the net names are no more shown od modifiable (becuase the footprint editor does not know anything about net names. This change should allow the changes planned in pcbnew. --- common/dialog_about/dialog_about.cpp | 9 +- common/dialog_about/dialog_about_base.cpp | 5 +- common/dialog_about/dialog_about_base.fbp | 987 +++++++++++++--------- common/dialog_about/dialog_about_base.h | 15 +- pcbnew/class_netinfo.h | 4 +- pcbnew/class_netinfolist.cpp | 3 +- pcbnew/class_pad_draw_functions.cpp | 6 +- pcbnew/dialogs/dialog_pad_properties.cpp | 110 ++- pcbnew/loadcmp.cpp | 19 +- pcbnew/moduleframe.cpp | 1 - 10 files changed, 703 insertions(+), 456 deletions(-) diff --git a/common/dialog_about/dialog_about.cpp b/common/dialog_about/dialog_about.cpp index 13ab08a9a3..d4deb7122f 100644 --- a/common/dialog_about/dialog_about.cpp +++ b/common/dialog_about/dialog_about.cpp @@ -29,16 +29,9 @@ dialog_about::dialog_about(wxWindow *parent, AboutAppInfo& appInfo) m_staticTextBuildVersion->SetLabel( info.GetBuildVersion() ); m_staticTextLibVersion->SetLabel( info.GetLibVersion() ); - /* Affects m_titlepanel the parent of some wxStaticText. - * Changing the text afterwards makes it under Windows necessary to call 'Layout()' - * so that the new text gets properly layout. - */ -/* m_staticTextCopyright->GetParent()->Layout(); - m_staticTextBuildVersion->GetParent()->Layout(); - m_staticTextLibVersion->GetParent()->Layout(); -*/ DeleteNotebooks(); CreateNotebooks(); + GetSizer()->SetSizeHints(this); m_auiNotebook->Update(); SetFocus(); diff --git a/common/dialog_about/dialog_about_base.cpp b/common/dialog_about/dialog_about_base.cpp index de343ab237..66cb2f05a2 100644 --- a/common/dialog_about/dialog_about_base.cpp +++ b/common/dialog_about/dialog_about_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Sep 8 2010) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -46,11 +46,13 @@ dialog_about_base::dialog_about_base( wxWindow* parent, wxWindowID id, const wxS m_staticTextLibVersion->Wrap( -1 ); b_apptitleSizer->Add( m_staticTextLibVersion, 0, wxALIGN_CENTER|wxBOTTOM|wxLEFT|wxRIGHT, 5 ); + bSizer3->Add( b_apptitleSizer, 10, wxEXPAND, 5 ); bSizer3->Add( 0, 0, 2, wxEXPAND, 5 ); + bSizer1->Add( bSizer3, 0, wxEXPAND, 5 ); wxStaticLine* m_staticline1; @@ -67,6 +69,7 @@ dialog_about_base::dialog_about_base( wxWindow* parent, wxWindowID id, const wxS m_buttonOK->SetDefault(); bSizer1->Add( m_buttonOK, 0, wxALIGN_CENTER|wxALL, 5 ); + this->SetSizer( bSizer1 ); this->Layout(); diff --git a/common/dialog_about/dialog_about_base.fbp b/common/dialog_about/dialog_about_base.fbp index 2f6951303c..ce0bf7d57d 100644 --- a/common/dialog_about/dialog_about_base.fbp +++ b/common/dialog_about/dialog_about_base.fbp @@ -2,11 +2,13 @@ - + C++ 1 source_name + 0 0 + res UTF-8 connect dialog_about_base @@ -14,73 +16,80 @@ none 1 MyProject - + . - + 1 + 1 + 1 1 + UI 1 0 - - - + 0 + wxAUI_MGR_DEFAULT + + + 1 1 impl_virtual - - - + + + 0 wxID_ANY - + -1,-1 dialog_about_base - + 750,450 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP - + About... - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - + + + + + + + + + + + + + OnClose - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + bSizer1 wxVERTICAL none @@ -89,7 +98,7 @@ wxEXPAND 0 - + bSizer3 wxHORIZONTAL none @@ -108,53 +117,80 @@ wxALIGN_CENTER|wxALL 1 - - - + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - - + + 0 + + + 0 + + 1 m_bitmapApp + 1 + + protected - - - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -162,7 +198,7 @@ wxEXPAND 10 - + b_apptitleSizer wxVERTICAL none @@ -171,55 +207,82 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - + + 1 ,90,92,14,70,0 + 0 0 wxID_ANY App Title - - + + 0 + + + 0 + + 1 m_staticTextAppTitle + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -227,55 +290,82 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Copyright Info - - + + 0 + + + 0 + + 1 m_staticTextCopyright + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -283,55 +373,82 @@ wxALIGN_CENTER|wxLEFT|wxRIGHT|wxTOP 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Build Version Info - - + + 0 + + + 0 + + 1 m_staticTextBuildVersion + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -339,55 +456,82 @@ wxALIGN_CENTER|wxBOTTOM|wxLEFT|wxRIGHT 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Lib Version Info - - + + 0 + + + 0 + + 1 m_staticTextLibVersion + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -409,53 +553,80 @@ wxEXPAND | wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - - + + 0 + + + 0 + + 1 m_staticline1 + 1 + + none - - + 1 + + Resizable + 1 + wxLI_HORIZONTAL - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -463,63 +634,90 @@ wxEXPAND | wxALL 2 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - + + 0 + + + 0 750,350 + 1 m_auiNotebook + 1 + + protected - - + 1 + + Resizable + 1 + wxAUI_NB_SCROLL_BUTTONS|wxAUI_NB_TAB_FIXED_WIDTH - + -1 - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -527,56 +725,87 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_CANCEL OK - - + + 0 + + + 0 + + 1 m_buttonOK + 1 + + private - - - - - - + 1 + + Resizable + 1 + + + + 0 + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnOkClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/dialog_about/dialog_about_base.h b/common/dialog_about/dialog_about_base.h index 79253e9973..d0485f3575 100644 --- a/common/dialog_about/dialog_about_base.h +++ b/common/dialog_about/dialog_about_base.h @@ -1,15 +1,16 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Sep 8 2010) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#ifndef __dialog_about_base__ -#define __dialog_about_base__ +#ifndef __DIALOG_ABOUT_BASE_H__ +#define __DIALOG_ABOUT_BASE_H__ +#include +#include #include - #include #include #include @@ -37,13 +38,11 @@ class dialog_about_base : public wxDialog wxButton* m_buttonOK; protected: - wxStaticBitmap* m_bitmapApp; wxStaticText* m_staticTextAppTitle; wxStaticText* m_staticTextCopyright; wxStaticText* m_staticTextBuildVersion; wxStaticText* m_staticTextLibVersion; - wxAuiNotebook* m_auiNotebook; // Virtual event handlers, overide them in your derived class @@ -53,9 +52,9 @@ class dialog_about_base : public wxDialog public: - dialog_about_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,350 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP ); + dialog_about_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP ); ~dialog_about_base(); }; -#endif //__dialog_about_base__ +#endif //__DIALOG_ABOUT_BASE_H__ diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 64e6e9f8b8..88e77df440 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -234,7 +234,7 @@ private: /** - * Class NETINFO + * Class NETINFO_LIST * is a container class for NETINFO_ITEM elements, which are the nets. That makes * this class a container for the nets. */ diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index da3bd875d1..5f73ca0a98 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -1,8 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index dfa489041a..78fcaf457c 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -499,10 +499,10 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos = tpos0; wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x - int shortname_len = GetShortNetname().Len(); + int shortname_len = 0; - if( !aDrawInfo.m_Display_netname ) - shortname_len = 0; + if( aDrawInfo.m_Display_netname ) + shortname_len = GetShortNetname().Len(); if( GetShape() == PAD_CIRCLE ) angle = 0; diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 21c306b66f..fe5faeba66 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -97,11 +97,17 @@ private: PCB_BASE_FRAME* m_parent; D_PAD* m_currentPad; // pad currently being edited D_PAD* m_dummyPad; // a working copy used to show changes - BOARD* m_board; - D_PAD& m_padMaster; + D_PAD* m_padMaster; // The pad used to create new pads in board or + // footprint editor + BOARD* m_board; // the main board: this is the board handled by + // the PCB editor, if running or the dummy + // board used by the footprint editor + // (could happen when the Footprint editor will be run + // alone, outside the board editor bool m_isFlipped; // true if the parent footprint (therefore pads) is flipped (mirrored) // in this case, some Y coordinates values must be negated bool m_canUpdate; + bool m_canEditNetName; // true only if the called is the board editor private: void initValues(); @@ -139,25 +145,31 @@ private: void PadPropertiesAccept( wxCommandEvent& event ); }; +void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad ) +{ + DIALOG_PAD_PROPERTIES dlg( this, aPad ); + + dlg.ShowModal(); +} + DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad ) : - DIALOG_PAD_PROPERTIES_BASE( aParent ), - // use aParent's parent, which is the original BOARD, not the dummy module editor BOARD, - // since FOOTPRINT_EDIT_FRAME::GetDesignSettings() is tricked out to use the PCB_EDIT_FRAME's - // BOARD, not its own BOARD. - m_padMaster( aParent->GetDesignSettings().m_Pad_Master ) + DIALOG_PAD_PROPERTIES_BASE( aParent ) { m_canUpdate = false; m_parent = aParent; m_currentPad = aPad; // aPad can be NULL, if the dialog is called // from the module editor to set default pad characteristics + m_board = m_parent->GetBoard(); + + m_padMaster = &m_parent->GetDesignSettings().m_Pad_Master; m_dummyPad = new D_PAD( (MODULE*) NULL ); if( aPad ) m_dummyPad->Copy( aPad ); - else - m_dummyPad->Copy( &m_padMaster ); + else // We are editing a "master" pad, i.e. a pad used to create new pads + m_dummyPad->Copy( m_padMaster ); initValues(); @@ -238,19 +250,16 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) } -void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad ) -{ - DIALOG_PAD_PROPERTIES dlg( this, aPad ); - - dlg.ShowModal(); -} - - void DIALOG_PAD_PROPERTIES::initValues() { wxString msg; double angle; + // Disable pad net name wxTextCtrl if the caller is the footprint editor + // because nets are living only in the board managed by the board editor + m_canEditNetName = m_parent->IsType( FRAME_PCB ); + + // Setup layers names from board // Should be made first, before calling m_rbCopperLayersSel->SetSelection() m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( LAYER_N_FRONT ) ); @@ -471,7 +480,7 @@ void DIALOG_PAD_PROPERTIES::initValues() bool enable = m_dummyPad->GetAttribute() != PAD_HOLE_NOT_PLATED; m_PadNumCtrl->Enable( enable ); - m_PadNetNameCtrl->Enable( enable ); + m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL ); m_LengthPadToDieCtrl->Enable( enable ); if( m_dummyPad->GetDrillShape() != PAD_DRILL_OBLONG ) @@ -593,7 +602,7 @@ void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event ) void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) { - unsigned ii = m_PadType->GetSelection(); + unsigned ii = m_PadType->GetSelection(); if( ii >= NBTYPES ) // catches < 0 also ii = 0; @@ -614,7 +623,7 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) // (disable for NPTH pads (mechanical pads) bool enable = ii != 3; m_PadNumCtrl->Enable( enable ); - m_PadNetNameCtrl->Enable( enable ); + m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL ); m_LengthPadToDieCtrl->Enable( enable ); } @@ -752,7 +761,9 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) bool rastnestIsChanged = false; int isign = m_isFlipped ? -1 : 1; - transferDataToPad( &m_padMaster ); + transferDataToPad( m_padMaster ); + // m_padMaster is a pattern: ensure there is no net for this pad: + m_padMaster->SetNetCode( NETINFO_LIST::UNCONNECTED ); if( m_currentPad ) // Set current Pad parameters { @@ -768,12 +779,12 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) m_currentPad->ClearFlags( DO_NOT_DRAW ); // Update values - m_currentPad->SetShape( m_padMaster.GetShape() ); - m_currentPad->SetAttribute( m_padMaster.GetAttribute() ); + m_currentPad->SetShape( m_padMaster->GetShape() ); + m_currentPad->SetAttribute( m_padMaster->GetAttribute() ); - if( m_currentPad->GetPosition() != m_padMaster.GetPosition() ) + if( m_currentPad->GetPosition() != m_padMaster->GetPosition() ) { - m_currentPad->SetPosition( m_padMaster.GetPosition() ); + m_currentPad->SetPosition( m_padMaster->GetPosition() ); rastnestIsChanged = true; } @@ -785,54 +796,62 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) m_currentPad->SetPos0( pt ); - m_currentPad->SetOrientation( m_padMaster.GetOrientation() * isign + module->GetOrientation() ); + m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign + module->GetOrientation() ); - m_currentPad->SetSize( m_padMaster.GetSize() ); + m_currentPad->SetSize( m_padMaster->GetSize() ); - size = m_padMaster.GetDelta(); + size = m_padMaster->GetDelta(); size.y *= isign; m_currentPad->SetDelta( size ); - m_currentPad->SetDrillSize( m_padMaster.GetDrillSize() ); - m_currentPad->SetDrillShape( m_padMaster.GetDrillShape() ); + m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() ); + m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() ); - wxPoint offset = m_padMaster.GetOffset(); + wxPoint offset = m_padMaster->GetOffset(); offset.y *= isign; m_currentPad->SetOffset( offset ); - m_currentPad->SetPadToDieLength( m_padMaster.GetPadToDieLength() ); + m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() ); - if( m_currentPad->GetLayerMask() != m_padMaster.GetLayerMask() ) + if( m_currentPad->GetLayerMask() != m_padMaster->GetLayerMask() ) { rastnestIsChanged = true; - m_currentPad->SetLayerMask( m_padMaster.GetLayerMask() ); + m_currentPad->SetLayerMask( m_padMaster->GetLayerMask() ); } if( m_isFlipped ) m_currentPad->SetLayerMask( FlipLayerMask( m_currentPad->GetLayerMask() ) ); - m_currentPad->SetPadName( m_padMaster.GetPadName() ); + m_currentPad->SetPadName( m_padMaster->GetPadName() ); - if( m_currentPad->GetNetname() != m_PadNetNameCtrl->GetValue() ) + wxString padNetname; + + // For PAD_HOLE_NOT_PLATED, ensure there is no net name selected + if( m_padMaster->GetAttribute() != PAD_HOLE_NOT_PLATED ) + padNetname = m_PadNetNameCtrl->GetValue(); + + if( m_currentPad->GetNetname() != padNetname ) { - if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNetCode() == 0 ) + const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname ); + + if( !padNetname.IsEmpty() && netinfo == NULL ) { DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); } else { rastnestIsChanged = true; - m_currentPad->SetNetCode( m_padMaster.GetNetCode() ); + m_currentPad->SetNetCode( netinfo->GetNet() ); } } - m_currentPad->SetLocalClearance( m_padMaster.GetLocalClearance() ); - m_currentPad->SetLocalSolderMaskMargin( m_padMaster.GetLocalSolderMaskMargin() ); - m_currentPad->SetLocalSolderPasteMargin( m_padMaster.GetLocalSolderPasteMargin() ); - m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster.GetLocalSolderPasteMarginRatio() ); - m_currentPad->SetZoneConnection( m_padMaster.GetZoneConnection() ); - m_currentPad->SetThermalWidth( m_padMaster.GetThermalWidth() ); - m_currentPad->SetThermalGap( m_padMaster.GetThermalGap() ); + m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() ); + m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() ); + m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() ); + m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() ); + m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() ); + m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() ); + m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() ); module->CalculateBoundingBox(); m_parent->SetMsgPanel( m_currentPad ); @@ -984,6 +1003,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) // Check if user has set an existing net name const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() ); + if( netinfo != NULL ) aPad->SetNetCode( netinfo->GetNet() ); else diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 2db1223087..6c324b4d65 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -87,23 +87,28 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) aModule = newModule; - GetBoard()->Add( aModule ); + GetBoard()->Add( newModule ); - aModule->ClearFlags(); + newModule->ClearFlags(); - GetBoard()->BuildListOfNets(); + // Clear references to net info, because the footprint editor + // does know any thing about nets handled by the current edited board. + // Morever the main board can change or the net info relative to this main board + // can change while editing this footprint in the footprint editor + for( D_PAD* pad = newModule->Pads(); pad; pad = pad->Next() ) + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); SetCrossHairPosition( wxPoint( 0, 0 ) ); - PlaceModule( aModule, NULL ); + PlaceModule( newModule, NULL ); // Put it on FRONT layer, // because this is the default in ModEdit, and in libs - if( aModule->GetLayer() != LAYER_N_FRONT ) - aModule->Flip( aModule->GetPosition() ); + if( newModule->GetLayer() != LAYER_N_FRONT ) + newModule->Flip( newModule->GetPosition() ); // Put it in orientation 0, // because this is the default orientation in ModEdit, and in libs - Rotate_Module( NULL, aModule, 0, false ); + Rotate_Module( NULL, newModule, 0, false ); GetScreen()->ClrModify(); Zoom_Automatique( false ); diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index bf2983ccd0..cb7a0425fc 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -46,7 +46,6 @@ #include #include -#include #include #include #include From 3f2c0e1a8dc3e8cf18ac25f947af73e173aaf070 Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Fri, 25 Apr 2014 08:00:04 +0200 Subject: [PATCH 23/36] TRACK/SEGVIA cleanup - SEGVIA becomes VIA - Drill size moved from TRACK to VIA - Removed shape from TRACK, becomes ViaType in VIA - GetTrace becomes GetTrack, for uniformity - Some minor constification and typo fixes --- 3d-viewer/3d_canvas.h | 6 +- 3d-viewer/3d_draw.cpp | 34 +- include/class_board_design_settings.h | 3 +- include/view/view_item.h | 4 +- include/wxPcbStruct.h | 2 +- pcbnew/autorouter/auto_place_footprints.cpp | 7 +- pcbnew/autorouter/autorout.h | 2 + pcbnew/autorouter/graphpcb.cpp | 90 +-- pcbnew/autorouter/routing_matrix.cpp | 28 +- pcbnew/autorouter/solve.cpp | 13 +- pcbnew/board_undo_redo.cpp | 43 +- pcbnew/class_board.cpp | 38 +- pcbnew/class_board.h | 10 +- pcbnew/class_netinfo_item.cpp | 14 +- pcbnew/class_track.cpp | 599 +++++++++--------- pcbnew/class_track.h | 166 +++-- pcbnew/clean.cpp | 62 +- pcbnew/collectors.cpp | 4 +- pcbnew/dialogs/dialog_gendrill.cpp | 28 +- pcbnew/drc.cpp | 4 +- pcbnew/drc_clearance_test_functions.cpp | 21 +- pcbnew/drc_marker_functions.cpp | 5 +- pcbnew/drc_stuff.h | 4 +- pcbnew/eagle_plugin.cpp | 14 +- pcbnew/edit.cpp | 27 +- pcbnew/edit_track_width.cpp | 13 +- pcbnew/editrack-part2.cpp | 6 +- pcbnew/exporters/export_d356.cpp | 16 +- pcbnew/exporters/export_gencad.cpp | 25 +- pcbnew/exporters/export_vrml.cpp | 4 +- pcbnew/exporters/gendrill_Excellon_writer.cpp | 2 +- pcbnew/kicad_plugin.cpp | 10 +- pcbnew/legacy_plugin.cpp | 36 +- pcbnew/magnetic_tracks_functions.cpp | 2 +- pcbnew/move_or_drag_track.cpp | 8 +- pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp | 6 +- pcbnew/pcb_painter.cpp | 8 +- pcbnew/pcb_painter.h | 4 +- pcbnew/pcb_parser.cpp | 12 +- pcbnew/pcb_parser.h | 4 +- pcbnew/plot_board_layers.cpp | 22 +- pcbnew/plot_brditems_plotter.cpp | 9 +- pcbnew/print_board_functions.cpp | 15 +- pcbnew/ratsnest_data.cpp | 12 +- pcbnew/ratsnest_data.h | 8 +- pcbnew/router/pns_router.cpp | 6 +- pcbnew/router/pns_router.h | 4 +- pcbnew/specctra.h | 12 +- pcbnew/specctra_export.cpp | 4 +- pcbnew/specctra_import.cpp | 20 +- pcbnew/swap_layers.cpp | 4 +- pcbnew/tools/selection_tool.cpp | 2 +- pcbnew/tr_modif.cpp | 4 +- pcbnew/zones_polygons_test_connections.cpp | 9 +- 54 files changed, 806 insertions(+), 709 deletions(-) diff --git a/3d-viewer/3d_canvas.h b/3d-viewer/3d_canvas.h index 43a1f7ed85..d4ad84cebf 100644 --- a/3d-viewer/3d_canvas.h +++ b/3d-viewer/3d_canvas.h @@ -47,7 +47,7 @@ class BOARD_DESIGN_SETTINGS; class EDA_3D_FRAME; class S3D_VERTEX; -class SEGVIA; +class VIA; class D_PAD; // We are using GL lists to store layers and other items @@ -160,8 +160,8 @@ public: void Draw3DGrid( double aGriSizeMM ); void Draw3DAxis(); - void Draw3DViaHole( SEGVIA * aVia ); - void Draw3DPadHole( D_PAD * aPad ); + void Draw3DViaHole( const VIA * aVia ); + void Draw3DPadHole( const D_PAD * aPad ); DECLARE_EVENT_TABLE() }; diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 1afdfe9c27..3216947b8e 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -302,18 +302,19 @@ void EDA_3D_CANVAS::BuildBoard3DView() // Add via hole if( track->Type() == PCB_VIA_T ) { - int shape = track->GetShape(); - int holediameter = track->GetDrillValue(); - int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); + VIA *via = static_cast( track ); + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); + int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); int hole_outer_radius = (holediameter + thickness) / 2; - if( shape != VIA_THROUGH ) + if( viatype != VIA_THROUGH ) TransformCircleToPolygon( currLayerHoles, - track->GetStart(), hole_outer_radius, + via->GetStart(), hole_outer_radius, segcountLowQuality ); else if( !throughHolesListBuilt ) TransformCircleToPolygon( allLayerHoles, - track->GetStart(), hole_outer_radius, + via->GetStart(), hole_outer_radius, segcountLowQuality ); } } @@ -433,8 +434,10 @@ void EDA_3D_CANVAS::BuildBoard3DView() // Draw vias holes (vertical cylinders) for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) { - if( track->Type() == PCB_VIA_T ) - Draw3DViaHole( (SEGVIA*) track ); + const VIA *via = dynamic_cast(track); + + if( via ) + Draw3DViaHole( via ); } // Draw pads holes (vertical cylinders) @@ -529,13 +532,14 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() // Add via hole if( track->Type() == PCB_VIA_T ) { - int shape = track->GetShape(); - int holediameter = track->GetDrillValue(); + const VIA *via = static_cast( track ); + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); int hole_outer_radius = (holediameter + thickness) / 2; - if( shape == VIA_THROUGH ) + if( viatype == VIA_THROUGH ) TransformCircleToPolygon( allLayerHoles, - track->GetStart(), hole_outer_radius, + via->GetStart(), hole_outer_radius, segcountLowQuality ); } } @@ -1047,7 +1051,7 @@ void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM ) } -void EDA_3D_CANVAS::Draw3DViaHole( SEGVIA* aVia ) +void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia ) { LAYER_NUM top_layer, bottom_layer; int inner_radius = aVia->GetDrillValue() / 2; @@ -1060,7 +1064,7 @@ void EDA_3D_CANVAS::Draw3DViaHole( SEGVIA* aVia ) SetGLCopperColor(); else { - EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetShape() ); + EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ); SetGLColor( color ); } @@ -1111,7 +1115,7 @@ void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas, // Draw 3D pads. -void EDA_3D_CANVAS::Draw3DPadHole( D_PAD* aPad ) +void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad ) { // Draw the pad hole wxSize drillsize = aPad->GetDrillSize(); diff --git a/include/class_board_design_settings.h b/include/class_board_design_settings.h index 31ebfccfe5..67e0c73a88 100644 --- a/include/class_board_design_settings.h +++ b/include/class_board_design_settings.h @@ -7,6 +7,7 @@ #include // NB_COLORS #include +#include #include @@ -19,7 +20,7 @@ class BOARD_DESIGN_SETTINGS public: bool m_MicroViasAllowed; ///< true to allow micro vias bool m_BlindBuriedViaAllowed; ///< true to allow blind/buried vias - int m_CurrentViaType; ///< via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA) + VIATYPE_T m_CurrentViaType; ///< via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA) /// if true, when creating a new track starting on an existing track, use this track width bool m_UseConnectedTrackWidth; diff --git a/include/view/view_item.h b/include/view/view_item.h index c06538b224..f64bb4f1c7 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -57,8 +57,8 @@ enum KICAD_T PCB_TEXT_T, ///< class TEXTE_PCB, text on a layer PCB_MODULE_TEXT_T, ///< class TEXTE_MODULE, text in a footprint PCB_MODULE_EDGE_T, ///< class EDGE_MODULE, a footprint edge - PCB_TRACE_T, ///< class TRACKE, a track segment (segment on a copper layer) - PCB_VIA_T, ///< class SEGVIA, a via (like a track segment on a copper layer) + PCB_TRACE_T, ///< class TRACK, a track segment (segment on a copper layer) + PCB_VIA_T, ///< class VIA, a via (like a track segment on a copper layer) PCB_ZONE_T, ///< class SEGZONE, a segment used to fill a zone area (segment on a ///< copper layer) PCB_MARKER_T, ///< class MARKER_PCB, a marker used to show something diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 70cefc2a36..9ad56f1016 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -44,7 +44,7 @@ class TEXTE_PCB; class MODULE; class TRACK; class SEGZONE; -class SEGVIA; +class VIA; class D_PAD; class TEXTE_MODULE; class PCB_TARGET; diff --git a/pcbnew/autorouter/auto_place_footprints.cpp b/pcbnew/autorouter/auto_place_footprints.cpp index 0351c43bd1..a49ccd1b2c 100644 --- a/pcbnew/autorouter/auto_place_footprints.cpp +++ b/pcbnew/autorouter/auto_place_footprints.cpp @@ -516,12 +516,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel ) if( DrawSegm->GetLayer() != EDGE_N ) break; - TmpSegm.SetStart( DrawSegm->GetStart() ); - TmpSegm.SetEnd( DrawSegm->GetEnd() ); - TmpSegm.SetShape( DrawSegm->GetShape() ); - TmpSegm.m_Param = DrawSegm->GetAngle(); - - TraceSegmentPcb( &TmpSegm, HOLE | CELL_is_EDGE, + TraceSegmentPcb( DrawSegm, HOLE | CELL_is_EDGE, RoutingMatrix.m_GridRouting, WRITE_CELL ); break; diff --git a/pcbnew/autorouter/autorout.h b/pcbnew/autorouter/autorout.h index 98f5ac0b3a..b284b63ab8 100644 --- a/pcbnew/autorouter/autorout.h +++ b/pcbnew/autorouter/autorout.h @@ -38,6 +38,7 @@ class BOARD; +class DRAWSEGMENT; #define TOP 0 @@ -195,6 +196,7 @@ void PlacePad( D_PAD* pt_pad, int type, int marge, int op_logic ); /* Draws a segment of track on the board. */ void TraceSegmentPcb( TRACK* pt_segm, int type, int marge, int op_logic ); +void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int type, int marge, int op_logic ); /* Uses the color value of all cells included in the board * coord of the rectangle ux0, uy0 (top right corner) diff --git a/pcbnew/autorouter/graphpcb.cpp b/pcbnew/autorouter/graphpcb.cpp index 28dff7ff32..54b94a01f7 100644 --- a/pcbnew/autorouter/graphpcb.cpp +++ b/pcbnew/autorouter/graphpcb.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -256,29 +257,52 @@ void TraceFilledCircle( int cx, int cy, int radius, } } - -void TraceSegmentPcb( TRACK* pt_segm, int color, int marge, int op_logic ) +void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, int op_logic ) { - int half_width; - int ux0, uy0, ux1, uy1; - - half_width = ( pt_segm->GetWidth() / 2 ) + marge; + int half_width = ( pt_segm->GetWidth() / 2 ) + marge; // Calculate the bounding rectangle of the segment (if H, V or Via) - ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; - uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; - ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; - uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; - // Test if VIA (filled circle was drawn) - if( pt_segm->Type() == PCB_VIA_T ) + LAYER_NUM layer = pt_segm->GetLayer(); + + if( color == VIA_IMPOSSIBLE ) + layer = UNDEFINED_LAYER; + + switch( pt_segm->GetShape() ) + { + // The segment is here a straight line or a circle or an arc.: + case S_CIRCLE: + TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); + break; + + case S_ARC: + TraceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic ); + break; + + // The segment is here a line segment. + default: + DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); + break; + } +} + +void TraceSegmentPcb( TRACK* aTrack, int color, int marge, int op_logic ) +{ + int half_width = ( aTrack->GetWidth() / 2 ) + marge; + + // Test if VIA (filled circle need to be drawn) + if( aTrack->Type() == PCB_VIA_T ) { LAYER_MSK layer_mask = NO_LAYERS; - if( pt_segm->IsOnLayer( g_Route_Layer_BOTTOM ) ) + if( aTrack->IsOnLayer( g_Route_Layer_BOTTOM ) ) layer_mask = GetLayerMask( g_Route_Layer_BOTTOM ); - if( pt_segm->IsOnLayer( g_Route_Layer_TOP ) ) + if( aTrack->IsOnLayer( g_Route_Layer_TOP ) ) { if( layer_mask == 0 ) layer_mask = GetLayerMask( g_Route_Layer_TOP ); @@ -290,39 +314,25 @@ void TraceSegmentPcb( TRACK* pt_segm, int color, int marge, int op_logic ) layer_mask = FULL_LAYERS; if( layer_mask ) - TraceFilledCircle( pt_segm->GetStart().x, pt_segm->GetStart().y, + TraceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y, half_width, layer_mask, color, op_logic ); - return; } - - LAYER_NUM layer = pt_segm->GetLayer(); - - if( color == VIA_IMPOSSIBLE ) - layer = UNDEFINED_LAYER; - - // The segment is here a straight line or a circle or an arc.: - if( pt_segm->GetShape() == S_CIRCLE ) + else { - TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); - return; - } + // Calculate the bounding rectangle of the segment + int ux0 = aTrack->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy0 = aTrack->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux1 = aTrack->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy1 = aTrack->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; - if( pt_segm->GetShape() == S_ARC ) - { - TraceArc( ux0, uy0, ux1, uy1, pt_segm->m_Param, half_width, layer, color, op_logic ); - return; - } + // Ordinary track + LAYER_NUM layer = aTrack->GetLayer(); + + if( color == VIA_IMPOSSIBLE ) + layer = UNDEFINED_LAYER; - // The segment is here a line segment. - if( ( ux0 != ux1 ) && ( uy0 != uy1 ) ) // Segment tilts. - { DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); - return; } - - // The segment is horizontal or vertical. - // F4EXB 051018-01 - DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); } diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp index b5d02e926a..8449c90bc1 100644 --- a/pcbnew/autorouter/routing_matrix.cpp +++ b/pcbnew/autorouter/routing_matrix.cpp @@ -225,7 +225,6 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) // Place outlines of modules on matrix routing, if they are on a copper layer // or on the edge layer - TRACK tmpSegm( NULL ); // A dummy track used to create segments. for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { @@ -236,21 +235,13 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = (EDGE_MODULE*) item; + EDGE_MODULE tmpEdge( *edge ); - tmpSegm.SetLayer( edge->GetLayer() ); + if( tmpEdge.GetLayer() == EDGE_N ) + tmpEdge.SetLayer( UNDEFINED_LAYER ); - if( tmpSegm.GetLayer() == EDGE_N ) - tmpSegm.SetLayer( UNDEFINED_LAYER ); - - tmpSegm.SetStart( edge->GetStart() ); - tmpSegm.SetEnd( edge->GetEnd() ); - tmpSegm.SetShape( edge->GetShape() ); - tmpSegm.SetWidth( edge->GetWidth() ); - tmpSegm.m_Param = edge->GetAngle(); - tmpSegm.SetNetCode( -1 ); - - TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL ); - TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); + TraceSegmentPcb( &tmpEdge, HOLE, marge, WRITE_CELL ); + TraceSegmentPcb( &tmpEdge, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } break; @@ -271,7 +262,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) int type_cell = HOLE; DrawSegm = (DRAWSEGMENT*) item; - tmpSegm.SetLayer( DrawSegm->GetLayer() ); + DRAWSEGMENT tmpSegm( DrawSegm ); if( DrawSegm->GetLayer() == EDGE_N ) { @@ -279,13 +270,6 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) type_cell |= CELL_is_EDGE; } - tmpSegm.SetStart( DrawSegm->GetStart() ); - tmpSegm.SetEnd( DrawSegm->GetEnd() ); - tmpSegm.SetShape( DrawSegm->GetShape() ); - tmpSegm.SetWidth( DrawSegm->GetWidth() ); - tmpSegm.m_Param = DrawSegm->GetAngle(); - tmpSegm.SetNetCode( -1 ); - TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL ); } break; diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index 86e937073a..5e94db6b09 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -1159,14 +1159,11 @@ static int Retrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC, static void OrCell_Trace( BOARD* pcb, int col, int row, int side, int orient, int current_net_code ) { - int dx0, dy0, dx1, dy1; - TRACK* newTrack; - if( orient == HOLE ) // placement of a via { - newTrack = new SEGVIA( pcb ); + VIA *newVia = new VIA( pcb ); - g_CurrentTrackList.PushBack( newTrack ); + g_CurrentTrackList.PushBack( newVia ); g_CurrentTrackSegment->SetState( TRACK_AR, true ); g_CurrentTrackSegment->SetLayer( 0x0F ); @@ -1178,13 +1175,15 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, g_CurrentTrackSegment->SetEnd( g_CurrentTrackSegment->GetStart() ); g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() ); - g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType ); + newVia->SetViaType( pcb->GetDesignSettings().m_CurrentViaType ); g_CurrentTrackSegment->SetNetCode( current_net_code ); } else // placement of a standard segment { - newTrack = new TRACK( pcb ); + TRACK *newTrack = new TRACK( pcb ); + int dx0, dy0, dx1, dy1; + g_CurrentTrackList.PushBack( newTrack ); diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index a5a3ad314e..96d4c844da 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -232,31 +232,38 @@ void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); - atmp = track->GetShape(); - track->SetShape( image->GetShape() ); - image->SetShape( atmp ); - atmp = track->GetDrillValue(); + if( Type() == PCB_VIA_T ) + { + VIA *via = static_cast( this ); + VIA *viaimage = static_cast( aImage ); - if( track->IsDrillDefault() ) - atmp = -1; + VIATYPE_T viatmp = via->GetViaType(); + via->SetViaType( viaimage->GetViaType() ); + viaimage->SetViaType( viatmp ); - int itmp = image->GetDrillValue(); + int drilltmp = via->GetDrillValue(); - if( image->IsDrillDefault() ) - itmp = -1; + if( via->IsDrillDefault() ) + drilltmp = -1; - EXCHG(itmp, atmp ); + int itmp = viaimage->GetDrillValue(); - if( atmp > 0 ) - track->SetDrill( atmp ); - else - track->SetDrillDefault(); + if( viaimage->IsDrillDefault() ) + itmp = -1; - if( itmp > 0 ) - image->SetDrill( itmp ); - else - image->SetDrillDefault(); + EXCHG(itmp, drilltmp ); + + if( drilltmp > 0 ) + via->SetDrill( drilltmp ); + else + via->SetDrillDefault(); + + if( itmp > 0 ) + viaimage->SetDrill( itmp ); + else + viaimage->SetDrillDefault(); + } } break; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 20860474eb..6109e60945 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -242,7 +242,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, LAYER_MSK aLayerMask, TRACK_ segment = m_Track; candidate = NULL; NbSegm = 0; - while( ( segment = ::GetTrace( segment, NULL, aPosition, aLayerMask ) ) != NULL ) + while( ( segment = ::GetTrack( segment, NULL, aPosition, aLayerMask ) ) != NULL ) { if( segment->GetState( BUSY ) ) // already found and selected: skip it { @@ -1172,7 +1172,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData, #if 0 // both these are on same list, so we must scan it twice in order // to get VIA priority, using new #else code below. - // But we are not using separate lists for TRACKs and SEGVIAs, because + // But we are not using separate lists for TRACKs and VIA, because // items are ordered (sorted) in the linked // list by netcode AND by physical distance: // when created, if a track or via is connected to an existing track or @@ -1561,11 +1561,9 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) } -TRACK* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) +VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) const { - TRACK* track; - - for( track = m_Track; track; track = track->Next() ) + for( TRACK *track = m_Track; track; track = track->Next() ) { if( track->Type() != PCB_VIA_T ) continue; @@ -1576,14 +1574,11 @@ TRACK* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) if( track->GetState( BUSY | IS_DELETED ) ) continue; - if( aLayer == UNDEFINED_LAYER ) - break; - - if( track->IsOnLayer( aLayer ) ) - break; + if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) ) + return static_cast( track ); } - return track; + return NULL; } @@ -1777,9 +1772,10 @@ void BOARD::GetSortedPadListByXthenYCoord( std::vector& aVector, int aNe } -TRACK* BOARD::GetTrace( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) +TRACK* BOARD::GetTrack( TRACK* aTrace, const wxPoint& aPosition, + LAYER_MSK aLayerMask ) const { - for( TRACK* track = aTrace; track; track = track->Next() ) + for( TRACK* track = aTrace; track; track = track->Next() ) { LAYER_NUM layer = track->GetLayer(); @@ -1846,16 +1842,16 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, if( aTrace->Type() == PCB_VIA_T ) { TRACK* Segm1, * Segm2 = NULL, * Segm3 = NULL; - Segm1 = ::GetTrace( m_Track, NULL, aTrace->GetStart(), layerMask ); + Segm1 = ::GetTrack( m_Track, NULL, aTrace->GetStart(), layerMask ); if( Segm1 ) { - Segm2 = ::GetTrace( Segm1->Next(), NULL, aTrace->GetStart(), layerMask ); + Segm2 = ::GetTrack( Segm1->Next(), NULL, aTrace->GetStart(), layerMask ); } if( Segm2 ) { - Segm3 = ::GetTrace( Segm2->Next(), NULL, aTrace->GetStart(), layerMask ); + Segm3 = ::GetTrack( Segm2->Next(), NULL, aTrace->GetStart(), layerMask ); } if( Segm3 ) // More than 2 segments are connected to this via. the track" is only this via @@ -1903,7 +1899,7 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, layerMask = via->GetLayerMask(); - TRACK* track = ::GetTrace( m_Track, NULL, via->GetStart(), layerMask ); + TRACK* track = ::GetTrack( m_Track, NULL, via->GetStart(), layerMask ); // GetTrace does not consider tracks flagged BUSY. // So if no connected track found, this via is on the current track @@ -1925,7 +1921,7 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, */ LAYER_NUM layer = track->GetLayer(); - while( ( track = ::GetTrace( track->Next(), NULL, via->GetStart(), layerMask ) ) != NULL ) + while( ( track = ::GetTrack( track->Next(), NULL, via->GetStart(), layerMask ) ) != NULL ) { if( layer != track->GetLayer() ) { @@ -2127,10 +2123,10 @@ BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, LAYER_MSK a } /* No pad has been located so check for a segment of the trace. */ - TRACK* segment = ::GetTrace( m_Track, NULL, aPosition, aLayerMask ); + TRACK* segment = ::GetTrack( m_Track, NULL, aPosition, aLayerMask ); if( segment == NULL ) - segment = GetTrace( m_Track, aPosition, aLayerMask ); + segment = GetTrack( m_Track, aPosition, aLayerMask ); return segment; } diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 12150cda90..d899096819 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -286,7 +286,7 @@ public: DLIST m_Drawings; // linked list of lines & texts DLIST m_Modules; // linked list of MODULEs - DLIST m_Track; // linked list of TRACKs and SEGVIAs + DLIST m_Track; // linked list of TRACKs and VIAs DLIST m_Zone; // linked list of SEGZONEs /// Ratsnest list for the BOARD @@ -1370,9 +1370,9 @@ public: *

* @param aPosition The wxPoint to HitTest() against. * @param aLayer The layer to search. Use -1 for a don't care. - * @return TRACK* A point a to the SEGVIA object if found, else NULL. + * @return VIA* A point a to the VIA object if found, else NULL. */ - TRACK* GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); + VIA* GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ) const; /** * Function GetPad @@ -1438,7 +1438,7 @@ public: void GetSortedPadListByXthenYCoord( std::vector& aVector, int aNetCode = -1 ); /** - * Function GetTrace + * Function GetTrack * find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible. * Traces that are flagged as deleted or busy are ignored. * @@ -1448,7 +1448,7 @@ public: * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ - TRACK* GetTrace( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); + TRACK* GetTrack( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) const; /** * Function MarkTrace diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index f61705385f..447cf8a503 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -82,7 +82,6 @@ void NETINFO_ITEM::Draw( EDA_DRAW_PANEL* panel, void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { int count; - EDA_ITEM* Struct; wxString txt; MODULE* module; D_PAD* pad; @@ -113,20 +112,19 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) ); count = 0; - Struct = m_parent->GetBoard()->m_Track; - for( ; Struct != NULL; Struct = Struct->Next() ) + for( const TRACK *track = m_parent->GetBoard()->m_Track; track != NULL; track = track->Next() ) { - if( Struct->Type() == PCB_VIA_T ) + if( track->Type() == PCB_VIA_T ) { - if( ( (SEGVIA*) Struct )->GetNetCode() == GetNet() ) + if( track->GetNetCode() == GetNet() ) count++; } - if( Struct->Type() == PCB_TRACE_T ) + if( track->Type() == PCB_TRACE_T ) { - if( ( (TRACK*) Struct )->GetNetCode() == GetNet() ) - lengthnet += ( (TRACK*) Struct )->GetLength(); + if( track->GetNetCode() == GetNet() ) + lengthnet += track->GetLength(); } } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index f15033d3e1..48a665927d 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -88,15 +88,13 @@ inline bool IsNear( wxPoint& p1, wxPoint& p2, int max_dist ) } -TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, - LAYER_MSK aLayerMask ) +TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, + const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - TRACK* PtSegm; - if( aStartTrace == NULL ) return NULL; - for( PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) + for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) { if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) { @@ -125,9 +123,7 @@ TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_CONNECTED_ITEM( aParent, idtype ) { m_Width = Millimeter2iu( 0.2 ); - m_Shape = S_SEGMENT; start = end = NULL; - SetDrillDefault(); m_Param = 0; } @@ -179,34 +175,41 @@ wxString SEGZONE::GetSelectMenuText() const } -SEGVIA::SEGVIA( BOARD_ITEM* aParent ) : +VIA::VIA( BOARD_ITEM* aParent ) : TRACK( aParent, PCB_VIA_T ) { - SetShape( VIA_THROUGH ); + SetViaType( VIA_THROUGH ); m_Width = Millimeter2iu( 0.5 ); + SetDrillDefault(); } -EDA_ITEM* SEGVIA::Clone() const +EDA_ITEM* VIA::Clone() const { - return new SEGVIA( *this ); + return new VIA( *this ); } -wxString SEGVIA::GetSelectMenuText() const +wxString VIA::GetSelectMenuText() const { wxString text; wxString format; BOARD* board = GetBoard(); - int shape = GetShape(); - - if( shape == VIA_BLIND_BURIED ) + switch( GetViaType() ) + { + case VIA_BLIND_BURIED: format = _( "Blind/Buried Via %s, net[%s] (%d) on layers %s/%s" ); - else if( shape == VIA_MICROVIA ) + break; + case VIA_MICROVIA: format = _( "Micro Via %s, Net [%s] (%d) on layers %s/%s" ); + break; // else say nothing about normal (through) vias - else format = _( "Via %s net [%s] (%d) on layers %s/%s" ); + default: + format = _( "Via %s net [%s] (%d) on layers %s/%s" ); + break; + } + if( board ) { @@ -224,7 +227,7 @@ wxString SEGVIA::GetSelectMenuText() const } else { - wxFAIL_MSG( wxT( "SEGVIA::GetSelectMenuText: BOARD is NULL" ) ); + wxFAIL_MSG( wxT( "VIA::GetSelectMenuText: BOARD is NULL" ) ); text.Printf( format.GetData(), GetChars( ShowWidth() ), wxT( "???" ), 0, wxT( "??" ), wxT( "??" ) ); @@ -242,18 +245,15 @@ int TRACK::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const } -int TRACK::GetDrillValue() const +int VIA::GetDrillValue() const { - if( Type() != PCB_VIA_T ) - return 0; - if( m_Drill > 0 ) // Use the specific value. return m_Drill; // Use the default value from the Netclass NETCLASS* netclass = GetNetClass(); - if( m_Shape == VIA_MICROVIA ) + if( GetViaType() == VIA_MICROVIA ) return netclass->GetuViaDrill(); return netclass->GetViaDrill(); @@ -391,7 +391,7 @@ SEARCH_RESULT TRACK::Visit( INSPECTOR* inspector, const void* testData, } -bool SEGVIA::IsOnLayer( LAYER_NUM layer_number ) const +bool VIA::IsOnLayer( LAYER_NUM layer_number ) const { LAYER_NUM bottom_layer, top_layer; @@ -403,43 +403,38 @@ bool SEGVIA::IsOnLayer( LAYER_NUM layer_number ) const return false; } +LAYER_MSK VIA::GetLayerMask() const +{ + if( GetViaType() == VIA_THROUGH ) + return ALL_CU_LAYERS; + + // VIA_BLIND_BURIED or VIA_MICRVIA: + + LAYER_NUM bottom_layer, top_layer; + + // LayerPair() knows how layers are stored + LayerPair( &top_layer, &bottom_layer ); + + LAYER_MSK layermask = NO_LAYERS; + + while( bottom_layer <= top_layer ) + { + layermask |= ::GetLayerMask( bottom_layer ); + ++bottom_layer; + } + + return layermask; +} LAYER_MSK TRACK::GetLayerMask() const { - if( Type() == PCB_VIA_T ) - { - int via_type = GetShape(); - - if( via_type == VIA_THROUGH ) - return ALL_CU_LAYERS; - - // VIA_BLIND_BURIED or VIA_MICRVIA: - - LAYER_NUM bottom_layer, top_layer; - - // LayerPair() knows how layers are stored - ( (SEGVIA*) this )->LayerPair( &top_layer, &bottom_layer ); - - LAYER_MSK layermask = NO_LAYERS; - - while( bottom_layer <= top_layer ) - { - layermask |= ::GetLayerMask( bottom_layer ); - ++bottom_layer; - } - - return layermask; - } - else - { - return ::GetLayerMask( m_Layer ); - } + return ::GetLayerMask( m_Layer ); } -void SEGVIA::SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ) +void VIA::SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ) { - if( GetShape() == VIA_THROUGH ) + if( GetViaType() == VIA_THROUGH ) { top_layer = LAYER_N_FRONT; bottom_layer = LAYER_N_BACK; @@ -453,12 +448,12 @@ void SEGVIA::SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ) } -void SEGVIA::LayerPair( LAYER_NUM* top_layer, LAYER_NUM* bottom_layer ) const +void VIA::LayerPair( LAYER_NUM* top_layer, LAYER_NUM* bottom_layer ) const { LAYER_NUM b_layer = LAYER_N_BACK; LAYER_NUM t_layer = LAYER_N_FRONT; - if( GetShape() != VIA_THROUGH ) + if( GetViaType() != VIA_THROUGH ) { // XXX EVIL usage of LAYER b_layer = (m_Layer >> 4) & 15; @@ -557,116 +552,13 @@ TRACK* TRACK::GetEndNetCode( int NetCode ) return NULL; } - -void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, - const wxPoint& aOffset ) +void TRACK::DrawShortNetname( EDA_DRAW_PANEL* panel, + wxDC* aDC, GR_DRAWMODE aDrawMode, EDA_COLOR_T aBgColor ) { - int l_trace; - int radius; - LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; - - if( Type() == PCB_ZONE_T && DisplayOpt.DisplayZonesMode != 0 ) - return; - - BOARD * brd = GetBoard( ); - EDA_COLOR_T color = brd->GetLayerColor(m_Layer); - - if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) - return; - -#ifdef USE_WX_OVERLAY - // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay - if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) - return; -#endif - - if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) - { - if( !IsOnLayer( curr_layer ) ) - ColorTurnToDarkDarkGray( &color ); - } - - if( aDrawMode & GR_HIGHLIGHT ) - ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); - - ColorApplyHighlightFlag( &color ); - - SetAlpha( &color, 150 ); - - GRSetDrawMode( aDC, aDrawMode ); - - - l_trace = m_Width >> 1; - - if( m_Shape == S_CIRCLE ) - { - radius = KiROUND( GetLineLength( m_Start, m_End ) ); - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, color ); - } - else - { - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) // Line mode if too small - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, color ); - } - else if( ( !DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius - l_trace, color ); - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius + l_trace, color ); - } - else - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, m_Width, color ); - } - } - - return; - } - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) - { - GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); - return; - } - - if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) - { - GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); - } - else - { - GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, - m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); - } - - if( panel->GetScreen()->m_IsPrinting ) - return; - - // Show clearance for tracks, not for zone segments - if( ShowClearance( this ) ) - { - GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, - m_Width + (GetClearance() * 2), color ); - } - - /* Display the short netname for tracks, not for zone segments. - * we must filter tracks, to avoid a lot of texts. + /* we must filter tracks, to avoid a lot of texts. * - only tracks with a length > 10 * thickness are eligible * and, of course, if we are not printing the board */ - if( Type() == PCB_ZONE_T ) - return; - if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) return; @@ -703,7 +595,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // Calculate angle: if the track segment is vertical, angle = 90 degrees // If horizontal 0 degrees, otherwise compute it - double angle; // angle is in 0.1 degree + double angle; // angle is in 0.1 degree if( dy == 0 ) // Horizontal segment { @@ -723,6 +615,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } } + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; if( ( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) && ( !(!IsOnLayer( curr_layer )&& DisplayOpt.ContrastModeDisplay) ) ) { @@ -732,15 +625,136 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, tsize = (tsize * 7) / 10; // small reduction to give a better look EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL; DrawGraphicHaloText( clipbox, aDC, tpos, - color, BLACK, WHITE, net->GetShortNetname(), angle, - wxSize( tsize, tsize ), - GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - tsize / 7, - false, false ); + aBgColor, BLACK, WHITE, net->GetShortNetname(), angle, + wxSize( tsize, tsize ), + GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, + tsize / 7, + false, false ); } } } +void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + const wxPoint& aOffset ) +{ + BOARD * brd = GetBoard( ); + EDA_COLOR_T color = brd->GetLayerColor(m_Layer); + + if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) + return; + +#ifdef USE_WX_OVERLAY + // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay + if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) + return; +#endif + + if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) + { + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; + + if( !IsOnLayer( curr_layer ) ) + ColorTurnToDarkDarkGray( &color ); + } + + if( aDrawMode & GR_HIGHLIGHT ) + ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); + + ColorApplyHighlightFlag( &color ); + + SetAlpha( &color, 150 ); + + GRSetDrawMode( aDC, aDrawMode ); + + int l_trace = m_Width / 2; + + if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) + { + GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); + return; + } + + if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); + } + else + { + GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, + m_Start.y + aOffset.y, + m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); + } + + if( panel->GetScreen()->m_IsPrinting ) + return; + + // Show clearance for tracks, not for zone segments + if( ShowClearance( this ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, + m_Width + (GetClearance() * 2), color ); + } + + DrawShortNetname( panel, aDC, aDrawMode, color ); +} + +void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + const wxPoint& aOffset ) +{ + if( DisplayOpt.DisplayZonesMode != 0 ) + return; + + BOARD * brd = GetBoard( ); + EDA_COLOR_T color = brd->GetLayerColor(m_Layer); + + if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) + return; + +#ifdef USE_WX_OVERLAY + // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay + if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) + return; +#endif + + if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) + { + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; + + if( !IsOnLayer( curr_layer ) ) + ColorTurnToDarkDarkGray( &color ); + } + + if( aDrawMode & GR_HIGHLIGHT ) + ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); + + ColorApplyHighlightFlag( &color ); + + SetAlpha( &color, 150 ); + + GRSetDrawMode( aDC, aDrawMode ); + + int l_trace = m_Width / 2; + + if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) + { + GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); + return; + } + + if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); + } + else + { + GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, + m_Start.y + aOffset.y, + m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); + } + + // No clearance or netnames for zones +} + void TRACK::ViewGetLayers( int aLayers[], int& aCount ) const { @@ -764,7 +778,7 @@ unsigned int TRACK::ViewGetLOD( int aLayer ) const } -void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, +void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { int radius; @@ -780,9 +794,9 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, GRSetDrawMode( aDC, aDrawMode ); BOARD * brd = GetBoard( ); - EDA_COLOR_T color = brd->GetVisibleElementColor(VIAS_VISIBLE + m_Shape); + EDA_COLOR_T color = brd->GetVisibleElementColor(VIAS_VISIBLE + GetViaType()); - if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + m_Shape) ) == false + if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + GetViaType()) ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; @@ -879,7 +893,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer // (so we can see 2 superimposed microvias ): - if( GetShape() == VIA_MICROVIA ) + if( GetViaType() == VIA_MICROVIA ) { int ax, ay, bx, by; @@ -917,12 +931,12 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // for Buried Vias, draw a partial line : orient depending on layer pair // (so we can see superimposed buried vias ): - if( GetShape() == VIA_BLIND_BURIED ) + if( GetViaType() == VIA_BLIND_BURIED ) { int ax = 0, ay = radius, bx = 0, by = drill_radius; LAYER_NUM layer_top, layer_bottom; - ( (SEGVIA*) this )->LayerPair( &layer_top, &layer_bottom ); + ( (VIA*) this )->LayerPair( &layer_top, &layer_bottom ); // lines for the top layer RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) ); @@ -978,7 +992,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } -void SEGVIA::ViewGetLayers( int aLayers[], int& aCount ) const +void VIA::ViewGetLayers( int aLayers[], int& aCount ) const { // Just show it on common via & via holes layers aLayers[0] = ITEM_GAL_LAYER( VIAS_VISIBLE ); @@ -1035,56 +1049,12 @@ void TRACK::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } } - -void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +void TRACK::GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; - BOARD* board = GetBoard(); - switch( Type() ) - { - case PCB_VIA_T: - switch( GetShape() ) - { - default: - case 0: - msg = wxT( "???" ); // Not used yet, does not exist currently - break; - - case 1: - msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from - // the near neighbor inner layer only - break; - - case 2: - msg = _( "Blind/Buried Via" ); // from inner or external to inner - // or external layer (no restriction) - break; - - case 3: - msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only ) - break; - } - - break; - - case PCB_TRACE_T: - msg = _( "Track" ); - break; - - case PCB_ZONE_T: - msg = _( "Zone" ); - break; - - default: - msg = wxT( "???" ); - break; - } - - aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); - - // Display Net Name (in Pcbnew) - if( board ) + // Display Net Name + if( GetBoard() ) { NETINFO_ITEM* net = GetNet(); @@ -1095,7 +1065,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); - /* Display net code : (useful in test or debug) */ + // Display net code : (useful in test or debug) msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); } @@ -1127,7 +1097,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) #endif // defined(DEBUG) - /* Display the State member */ + // Display the State member msg = wxT( ". . " ); if( GetState( TRACK_LOCKED ) ) @@ -1137,64 +1107,126 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) msg[2] = 'A'; aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) ); +} - /* Display layer or layer pair) */ - if( Type() == PCB_VIA_T ) - { - SEGVIA* Via = (SEGVIA*) this; - LAYER_NUM top_layer, bottom_layer; +void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); - Via->LayerPair( &top_layer, &bottom_layer ); - if( board ) - msg = board->GetLayerName( top_layer ) + wxT( "/" ) - + board->GetLayerName( bottom_layer ); - else - msg.Printf(wxT("%d/%d"), top_layer, bottom_layer ); - } + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Track" ), DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + // Display layer + if( board ) + msg = board->GetLayerName( m_Layer ); else - { - if( board ) - msg = board->GetLayerName( m_Layer ); - else - msg.Printf(wxT("%d"), m_Layer ); - } + msg.Printf(wxT("%d"), m_Layer ); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) ); // Display width msg = ::CoordinateToString( (unsigned) m_Width ); - if( Type() == PCB_VIA_T ) // Display Diam and Drill values - { - // Display diameter value: - aList.push_back( MSG_PANEL_ITEM( _( "Diam" ), msg, DARKCYAN ) ); - - // Display drill value - int drill_value = GetDrillValue(); - - msg = ::CoordinateToString( drill_value ); - - wxString title = _( "Drill" ); - title += wxT( " " ); - - if( m_Drill >= 0 ) - title += _( "(Specific)" ); - else - title += _( "(Default)" ); - - aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) ); - } - else - { - aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); - } + aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); // Display segment length - if( Type() != PCB_VIA_T ) // Display Diam and Drill values + msg = ::LengthDoubleToString( GetLength() ); + aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); +} + +void SEGZONE::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); + + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Zone " ), DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + // Display layer + if( board ) + msg = board->GetLayerName( m_Layer ); + else + msg.Printf(wxT("%d"), m_Layer ); + + aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) ); + + // Display width + msg = ::CoordinateToString( (unsigned) m_Width ); + + aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); + + // Display segment length + msg = ::LengthDoubleToString( GetLength() ); + aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); +} + +void VIA::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); + + switch( GetViaType() ) { - msg = ::LengthDoubleToString( GetLength() ); - aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); + default: + case VIA_NOT_DEFINED: + msg = wxT( "???" ); // Not used yet, does not exist currently + break; + + case VIA_MICROVIA: + msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from + // the near neighbor inner layer only + break; + + case VIA_BLIND_BURIED: + msg = _( "Blind/Buried Via" ); // from inner or external to inner + // or external layer (no restriction) + break; + + case VIA_THROUGH: + msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only ) + break; } + + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + + // Display layer pair + LAYER_NUM top_layer, bottom_layer; + + LayerPair( &top_layer, &bottom_layer ); + if( board ) + msg = board->GetLayerName( top_layer ) + wxT( "/" ) + + board->GetLayerName( bottom_layer ); + else + msg.Printf(wxT("%d/%d"), top_layer, bottom_layer ); + + aList.push_back( MSG_PANEL_ITEM( _( "Layers" ), msg, BROWN ) ); + + // Display width + msg = ::CoordinateToString( (unsigned) m_Width ); + + // Display diameter value: + aList.push_back( MSG_PANEL_ITEM( _( "Diam" ), msg, DARKCYAN ) ); + + // Display drill value + int drill_value = GetDrillValue(); + + msg = ::CoordinateToString( drill_value ); + + wxString title = _( "Drill" ); + title += wxT( " " ); + + if( m_Drill >= 0 ) + title += _( "(Specific)" ); + else + title += _( "(Default)" ); + + aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) ); } @@ -1243,11 +1275,9 @@ bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con } -TRACK* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) +VIA* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) { - TRACK* track; - - for( track = this; track; track = track->Next() ) + for( TRACK *track = this; track; track = track->Next() ) { if( track->Type() != PCB_VIA_T ) continue; @@ -1258,22 +1288,17 @@ TRACK* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) if( track->GetState( BUSY | IS_DELETED ) ) continue; - if( aLayer == UNDEFINED_LAYER ) - break; - - if( track->IsOnLayer( aLayer ) ) - break; + if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) ) + return static_cast( track ); } - return track; + return NULL; } -TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) +VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - TRACK* trace; - - for( trace = this; trace != NULL; trace = trace->Next() ) + for( TRACK *trace = this; trace; trace = trace->Next() ) { if( trace->Type() == PCB_VIA_T ) { @@ -1282,7 +1307,7 @@ TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLay if( trace->GetState( BUSY | IS_DELETED ) == 0 ) { if( aLayerMask & trace->GetLayerMask() ) - return trace; + return static_cast( trace ); } } } @@ -1295,7 +1320,7 @@ TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLay } -TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) +TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) { const int NEIGHTBOUR_COUNT_MAX = 50; @@ -1466,7 +1491,7 @@ int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace ) } Track->SetState( BUSY, true ); - segm = ::GetTrace( this, TrackListEnd, Track->m_Start, layerMask ); + segm = ::GetTrack( this, TrackListEnd, Track->m_Start, layerMask ); Track->SetState( BUSY, false ); if( via ) @@ -1513,7 +1538,7 @@ int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace ) } Track->SetState( BUSY, true ); - segm = ::GetTrace( this, TrackListEnd, Track->m_End, layerMask ); + segm = ::GetTrack( this, TrackListEnd, Track->m_End, layerMask ); Track->SetState( BUSY, false ); if( via ) diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 56ac970102..8b727dde17 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -38,23 +38,27 @@ class TRACK; +class VIA; class D_PAD; class MSG_PANEL_ITEM; -// Via attributes (m_Shape parameter) -#define VIA_THROUGH 3 /* Always a through hole via */ -#define VIA_BLIND_BURIED 2 /* this via can be on internal layers */ -#define VIA_MICROVIA 1 /* this via which connect from an external layer - * to the near neighbor internal layer */ -#define VIA_NOT_DEFINED 0 /* not yet used */ +// Via types +enum VIATYPE_T +{ + VIA_THROUGH = 3, /* Always a through hole via */ + VIA_BLIND_BURIED = 2, /* this via can be on internal layers */ + VIA_MICROVIA = 1, /* this via which connect from an external layer + * to the near neighbor internal layer */ + VIA_NOT_DEFINED = 0 /* not yet used */ +}; #define UNDEFINED_DRILL_DIAMETER -1 //< Undefined via drill diameter. #define MIN_VIA_DRAW_SIZE 4 /// Minimum size in pixel for full drawing /** - * Function GetTrace + * Function GetTrack * is a helper function to locate a trace segment having an end point at \a aPosition * on \a aLayerMask starting at \a aStartTrace and end at \a aEndTrace. *

@@ -69,9 +73,8 @@ class MSG_PANEL_ITEM; * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ -extern TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, - LAYER_MSK aLayerMask ); - +extern TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, + const wxPoint& aPosition, LAYER_MSK aLayerMask ); class TRACK : public BOARD_CONNECTED_ITEM { @@ -85,9 +88,6 @@ protected: int m_Width; // Thickness of track, or via diameter wxPoint m_Start; // Line start point wxPoint m_End; // Line end point - int m_Shape; // vias: shape and type, Track = shape.. - - int m_Drill; // for vias: via drill (- 1 for default value) public: BOARD_CONNECTED_ITEM* start; // pointers to a connected item (pad or track) @@ -124,9 +124,6 @@ public: void SetStart( const wxPoint& aStart ) { m_Start = aStart; } const wxPoint& GetStart() const { return m_Start; } - int GetShape() const { return m_Shape; } - void SetShape( int aShape ) { m_Shape = aShape; } - // Virtual function const EDA_RECT GetBoundingBox() const; @@ -180,47 +177,13 @@ public: int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor ) const; - /** - * Function SetDrill - * sets the drill value for vias. - * @param aDrill is the new drill diameter - */ - void SetDrill( int aDrill ) { m_Drill = aDrill; } - - /** - * Function GetDrill - * returns the local drill setting for this VIA. If you want the calculated value, - * use GetDrillValue() instead. - */ - int GetDrill() const { return m_Drill; } - - /** - * Function GetDrillValue - * "calculates" the drill value for vias (m-Drill if > 0, or default - * drill value for the board. - * @return real drill_value - */ - int GetDrillValue() const; - - /** - * Function SetDrillDefault - * sets the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER. - */ - void SetDrillDefault() { m_Drill = UNDEFINED_DRILL_DIAMETER; } - - /** - * Function IsDrillDefault - * @return true if the drill value is default value (-1) - */ - bool IsDrillDefault() { return m_Drill <= 0; } - /** * Function GetLayerMask * returns a "layer mask", which is a bitmap of all layers on which the - * TRACK segment or SEGVIA physically resides. + * TRACK segment or VIA physically resides. * @return int - a layer mask, see pcbstruct.h's LAYER_BACK, etc. */ - LAYER_MSK GetLayerMask() const; + virtual LAYER_MSK GetLayerMask() const; /** * Function IsPointOnEnds @@ -239,13 +202,6 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - /** - * Function GetMsgPanelInfoBase - * Display info about the track segment only, and does not calculate the full track length - * @param aList A list of #MSG_PANEL_ITEM objects to add status information. - */ - void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); - /** * Function ShowWidth * returns the width of the track in displayable user units. @@ -265,28 +221,28 @@ public: /** * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace. + * finds the first VIA object at \a aPosition on \a aLayer starting at the trace. * * @param aPosition The wxPoint to HitTest() against. * @param aLayer The layer to match, pass -1 for a don't care. - * @return A pointer to a SEGVIA object if found, else NULL. + * @return A pointer to a VIA object if found, else NULL. */ - TRACK* GetVia( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); + VIA* GetVia( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); /** * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace + * finds the first VIA object at \a aPosition on \a aLayer starting at the trace * and ending at \a aEndTrace. * * @param aEndTrace Pointer to the last TRACK object to end search. * @param aPosition The wxPoint to HitTest() against. * @param aLayerMask The layers to match, pass -1 for a don't care. - * @return A pointer to a SEGVIA object if found, else NULL. + * @return A pointer to a VIA object if found, else NULL. */ - TRACK* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); + VIA* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); /** - * Function GetTrace + * Function GetTrack * return the trace segment connected to the segment at \a aEndPoint from \a * aStartTrace to \a aEndTrace. * @@ -296,7 +252,7 @@ public: * @param aEndPoint The start or end point of the segment to test against. * @return A TRACK object pointer if found otherwise NULL. */ - TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ); + TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ); /** * Function GetEndSegments @@ -349,6 +305,24 @@ public: static wxString ShowState( int stateBits ); #endif + +protected: + /** + * Function GetMsgPanelInfoBase + * Display info about the track segment only, and does not calculate the full track length + * @param aList A list of #MSG_PANEL_ITEM objects to add status information. + */ + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); + + + /** + * Helper function for the common panel info */ + void GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList ); + + /** + * Helper for drawing the short netname in tracks */ + void DrawShortNetname( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + EDA_COLOR_T aBgColor ); }; @@ -369,16 +343,22 @@ public: wxString GetSelectMenuText() const; + void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, + GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ); + BITMAP_DEF GetMenuImage() const { return add_zone_xpm; } EDA_ITEM* Clone() const; + +protected: + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); }; -class SEGVIA : public TRACK +class VIA : public TRACK { public: - SEGVIA( BOARD_ITEM* aParent ); + VIA( BOARD_ITEM* aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. @@ -387,6 +367,8 @@ public: bool IsOnLayer( LAYER_NUM aLayer ) const; + virtual LAYER_MSK GetLayerMask() const; + /** * Function SetLayerPair * set the .m_Layer member param: @@ -428,6 +410,52 @@ public: #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif + + VIATYPE_T GetViaType() const { return m_ViaType; } + void SetViaType( VIATYPE_T aViaType ) { m_ViaType = aViaType; } + + /** + * Function SetDrill + * sets the drill value for vias. + * @param aDrill is the new drill diameter + */ + void SetDrill( int aDrill ) { m_Drill = aDrill; } + + /** + * Function GetDrill + * returns the local drill setting for this VIA. If you want the calculated value, + * use GetDrillValue() instead. + */ + int GetDrill() const { return m_Drill; } + + /** + * Function GetDrillValue + * "calculates" the drill value for vias (m-Drill if > 0, or default + * drill value for the board. + * @return real drill_value + */ + int GetDrillValue() const; + + /** + * Function SetDrillDefault + * sets the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER. + */ + void SetDrillDefault() { m_Drill = UNDEFINED_DRILL_DIAMETER; } + + /** + * Function IsDrillDefault + * @return true if the drill value is default value (-1) + */ + bool IsDrillDefault() const { return m_Drill <= 0; } + + +protected: + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); + +private: + VIATYPE_T m_ViaType; // Type of via + + int m_Drill; // for vias: via drill (- 1 for default value) }; diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 63d72de226..443394157d 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -111,7 +111,7 @@ void PCB_EDIT_FRAME::Clean_Pcb() * Delete * - Redundant points on tracks (merge aligned segments) * - vias on pad - * - null lenght segments + * - null length segments * Create segments when track ends are incorrectly connected: * i.e. when a track end covers a pad or a via but is not exactly on the pad or the via center */ @@ -201,10 +201,13 @@ bool TRACKS_CLEANER::clean_vias() { if( track->GetStart() != track->GetEnd() ) track->SetEnd( track->GetStart() ); - } - if( track->GetShape() != VIA_THROUGH ) - continue; + VIA *via = static_cast( track ); + /* Important: this cleanup only does thru hole vias, it doesn't + * (yet) handle high density interconnects */ + if( via->GetViaType() != VIA_THROUGH ) + continue; + } // Search and delete others vias at same location TRACK* alt_track = track->Next(); @@ -213,17 +216,21 @@ bool TRACKS_CLEANER::clean_vias() for( ; alt_track != NULL; alt_track = next_track ) { next_track = alt_track->Next(); + VIA *alt_via = dynamic_cast( alt_track ); + if( alt_via ) + { - if( alt_track->GetShape() != VIA_THROUGH ) - continue; + if( alt_via->GetViaType() != VIA_THROUGH ) + continue; - if( alt_track->GetStart() != track->GetStart() ) - continue; + if( alt_via->GetStart() != track->GetStart() ) + continue; - // delete via - alt_track->UnLink(); - delete alt_track; - modified = true; + // delete via + alt_track->UnLink(); + delete alt_track; + modified = true; + } } } @@ -233,7 +240,8 @@ bool TRACKS_CLEANER::clean_vias() { next_track = track->Next(); - if( track->GetShape() != VIA_THROUGH ) + VIA *via = dynamic_cast( track ); + if( !via || (via->GetViaType() != VIA_THROUGH )) continue; // Examine the list of connected pads: @@ -296,7 +304,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() if( (type_end & START_ON_PAD ) == 0 ) { - TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START ); + TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, FLG_START ); if( other == NULL ) // Test a connection to zones { @@ -309,7 +317,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() } else { - ((SEGVIA*)track)->LayerPair( &top_layer, &bottom_layer ); + ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), top_layer, bottom_layer, track->GetNetCode() ); @@ -332,8 +340,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() // search for another segment following the via track->SetState( BUSY, true ); - SEGVIA* via = (SEGVIA*) other; - other = via->GetTrace( m_Brd->m_Track, NULL, FLG_START ); + VIA* via = (VIA*) other; + other = via->GetTrack( m_Brd->m_Track, NULL, FLG_START ); if( other == NULL ) { @@ -356,7 +364,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() // test if this track end point is connected to an other track if( (type_end & END_ON_PAD ) == 0 ) { - TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_END ); + TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, FLG_END ); if( other == NULL ) // Test a connection to zones { @@ -369,7 +377,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() } else { - ((SEGVIA*)track)->LayerPair( &top_layer, &bottom_layer ); + ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), top_layer, bottom_layer, track->GetNetCode() ); @@ -393,8 +401,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() track->SetState( BUSY, true ); - SEGVIA* via = (SEGVIA*) other; - other = via->GetTrace( m_Brd->m_Track, NULL, FLG_END ); + VIA* via = (VIA*) other; + other = via->GetTrack( m_Brd->m_Track, NULL, FLG_END ); if( other == NULL ) { @@ -500,7 +508,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the START point of the current segment for( segStart = segment->Next(); ; ) { - segStart = segment->GetTrace( segStart, NULL, FLG_START ); + segStart = segment->GetTrack( segStart, NULL, FLG_START ); if( segStart ) { @@ -514,7 +522,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segStart->SetState( BUSY, true ); - other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_START ); + other = segment->GetTrack( m_Brd->m_Track, NULL, FLG_START ); segStart->SetState( BUSY, false ); if( other == NULL ) @@ -540,7 +548,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the END point of the current segment: for( segEnd = segment->Next(); ; ) { - segEnd = segment->GetTrace( segEnd, NULL, FLG_END ); + segEnd = segment->GetTrack( segEnd, NULL, FLG_END ); if( segEnd ) { @@ -552,7 +560,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segEnd->SetState( BUSY, true ); - other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_END ); + other = segment->GetTrack( m_Brd->m_Track, NULL, FLG_END ); segEnd->SetState( BUSY, false ); if( other == NULL ) @@ -736,7 +744,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, FLG_START ); if( other ) net_code_s = other->GetNetCode(); @@ -754,7 +762,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, FLG_END ); if( other ) net_code_e = other->GetNetCode(); diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index 4aee57a556..2470684c6d 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -149,7 +149,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testDa MODULE* module = NULL; D_PAD* pad = NULL; bool pad_through = false; - SEGVIA* via = NULL; + VIA* via = NULL; MARKER_PCB* marker = NULL; #if 0 // debugging @@ -252,7 +252,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testDa break; case PCB_VIA_T: // vias are on many layers, so layer test is specific - via = (SEGVIA*) item; + via = (VIA*) item; break; case PCB_TRACE_T: diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index dc03481fca..6daa73471e 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -140,15 +140,27 @@ void DIALOG_GENDRILL::InitDisplayParams() for( TRACK* track = m_parent->GetBoard()->m_Track; track != NULL; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA *via = dynamic_cast( track ); + if( via ) + { + switch( via->GetViaType() ) + { + case VIA_THROUGH: + m_throughViasCount++; + break; - if( track->GetShape() == VIA_THROUGH ) - m_throughViasCount++; - else if( track->GetShape() == VIA_MICROVIA ) - m_microViasCount++; - else if( track->GetShape() == VIA_BLIND_BURIED ) - m_blindOrBuriedViasCount++; + case VIA_MICROVIA: + m_microViasCount++; + break; + + case VIA_BLIND_BURIED: + m_blindOrBuriedViasCount++; + break; + + default: + break; + } + } } m_MicroViaDrillValue->Enable( m_microViasCount ); diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index c53df84be0..07b8ebf0f9 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -597,7 +597,7 @@ void DRC::testKeepoutAreas() if( ! area->GetDoNotAllowVias() ) continue; - if( ! ((SEGVIA*)segm)->IsOnLayer( area->GetLayer() ) ) + if( ! ((VIA*)segm)->IsOnLayer( area->GetLayer() ) ) continue; if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) @@ -645,7 +645,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( ! area->GetDoNotAllowVias() ) continue; - if( ! ((SEGVIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) + if( ! ((VIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) continue; if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index 0550f6cfa2..04394d2d08 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -169,21 +169,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // Phase 0 : Test vias if( aRefSeg->Type() == PCB_VIA_T ) { + const VIA *refvia = static_cast( aRefSeg ); // test if the via size is smaller than minimum - if( aRefSeg->GetShape() == VIA_MICROVIA ) + if( refvia->GetViaType() == VIA_MICROVIA ) { - if( aRefSeg->GetWidth() < netclass->GetuViaMinDiameter() ) + if( refvia->GetWidth() < netclass->GetuViaMinDiameter() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_TOO_SMALL_MICROVIA, m_currentMarker ); return false; } } else { - if( aRefSeg->GetWidth() < netclass->GetViaMinDiameter() ) + if( refvia->GetWidth() < netclass->GetViaMinDiameter() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_TOO_SMALL_VIA, m_currentMarker ); return false; } @@ -192,9 +193,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // test if via's hole is bigger than its diameter // This test is necessary since the via hole size and width can be modified // and a default via hole can be bigger than some vias sizes - if( aRefSeg->GetDrillValue() > aRefSeg->GetWidth() ) + if( refvia->GetDrillValue() > refvia->GetWidth() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_VIA_HOLE_BIGGER, m_currentMarker ); return false; } @@ -202,12 +203,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // For microvias: test if they are blind vias and only between 2 layers // because they are used for very small drill size and are drill by laser // and **only one layer** can be drilled - if( aRefSeg->GetShape() == VIA_MICROVIA ) + if( refvia->GetViaType() == VIA_MICROVIA ) { LAYER_NUM layer1, layer2; bool err = true; - ( (SEGVIA*) aRefSeg )->LayerPair( &layer1, &layer2 ); + refvia->LayerPair( &layer1, &layer2 ); if( layer1 > layer2 ) EXCHG( layer1, layer2 ); @@ -222,7 +223,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( err ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); return false; } diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp index 817d7e17d9..9a5002521d 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc_marker_functions.cpp @@ -44,7 +44,8 @@ #include -MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ) +MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, + MARKER_PCB* fillMe ) { wxString textA = aTrack->GetSelectMenuText(); wxString textB; @@ -62,7 +63,7 @@ MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, M } else if( aItem->Type() == PCB_VIA_T ) { - posB = position = ((SEGVIA*)aItem)->GetPosition(); + posB = position = ((VIA*)aItem)->GetPosition(); } else if( aItem->Type() == PCB_TRACE_T ) { diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index f2daee5b95..927e94936a 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -212,14 +212,14 @@ private: * DRC problem, or unconnected pad problem. * * @param aTrack The reference track. - * @param aItem Another item on the BOARD, such as a SEGVIA, SEGZONE, + * @param aItem Another item on the BOARD, such as a VIA, SEGZONE, * or TRACK. * @param aErrorCode A categorizing identifier for the particular type * of error that is being reported. * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to * first be allocated, then filled. */ - MARKER_PCB* fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ); + MARKER_PCB* fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ); MARKER_PCB* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe ); diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index f8e31fddec..a78007761b 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -2410,9 +2410,9 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) if( IsCopperLayer( layer_front_most ) && IsCopperLayer( layer_back_most ) ) { - int kidiam; - int drillz = kicad( v.drill ); - SEGVIA* via = new SEGVIA( m_board ); + int kidiam; + int drillz = kicad( v.drill ); + VIA* via = new VIA( m_board ); m_board->m_Track.Insert( via, NULL ); via->SetLayerPair( layer_front_most, layer_back_most ); @@ -2439,11 +2439,11 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) m_min_via_hole = drillz; if( layer_front_most == LAYER_N_FRONT && layer_back_most == LAYER_N_BACK ) - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); else if( layer_front_most == LAYER_N_FRONT || layer_back_most == LAYER_N_BACK ) - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); else - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); via->SetTimeStamp( timeStamp( it->second ) ); @@ -2453,8 +2453,6 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) via->SetEnd( pos ); via->SetNetCode( netCode ); - - via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor } m_xpath->pop(); } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 92b267c856..98a3ec4fee 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -394,14 +394,23 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } else { - int v_type = GetDesignSettings().m_CurrentViaType; - if( id == ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA || - id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA ) - GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED; - else if( id == ID_POPUP_PCB_PLACE_MICROVIA ) - GetDesignSettings().m_CurrentViaType = VIA_MICROVIA; - else - GetDesignSettings().m_CurrentViaType = VIA_THROUGH; + BOARD_DESIGN_SETTINGS &settings = GetDesignSettings(); + VIATYPE_T v_type = settings.m_CurrentViaType; + switch( id ) + { + case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA: + case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA: + settings.m_CurrentViaType = VIA_BLIND_BURIED; + break; + + case ID_POPUP_PCB_PLACE_MICROVIA: + settings.m_CurrentViaType = VIA_MICROVIA; + break; + + default: + settings.m_CurrentViaType = VIA_THROUGH; + break; + } // place via and switch layer. if( id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA || @@ -426,7 +435,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) else Other_Layer_Route( (TRACK*) GetCurItem(), &dc ); - GetDesignSettings().m_CurrentViaType = v_type; + settings.m_CurrentViaType = v_type; if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 4c2d5e8327..c371ee0978 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -47,8 +47,10 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, if( aTrackItem->Type() == PCB_VIA_T ) { - if( !aTrackItem->IsDrillDefault() ) - initial_drill = aTrackItem->GetDrillValue(); + const VIA *via = static_cast( aTrackItem ); + + if( !via->IsDrillDefault() ) + initial_drill = via->GetDrillValue(); if( net ) { @@ -60,7 +62,7 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, new_drill = GetBoard()->GetCurrentViaDrill(); } - if( aTrackItem->GetShape() == VIA_MICROVIA ) + if( via->GetViaType() == VIA_MICROVIA ) { if( net ) new_width = net->GetMicroViaSize(); @@ -107,10 +109,11 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value + VIA *via = static_cast( aTrackItem ); if( new_drill > 0 ) - aTrackItem->SetDrill( new_drill ); + via->SetDrill( new_drill ); else - aTrackItem->SetDrillDefault(); + via->SetDrillDefault(); } } } diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index e394ad1ca3..bedbcac572 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -95,9 +95,9 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // create the via - SEGVIA* via = new SEGVIA( GetBoard() ); + VIA* via = new VIA( GetBoard() ); via->SetFlags( IS_NEW ); - via->SetShape( GetDesignSettings().m_CurrentViaType ); + via->SetViaType( GetDesignSettings().m_CurrentViaType ); via->SetWidth( GetBoard()->GetCurrentViaSize()); via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetEnd( g_CurrentTrackSegment->GetEnd() ); @@ -118,7 +118,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) last_layer = GetScreen()->m_Route_Layer_BOTTOM; // Adjust the actual via layer pair - switch ( via->GetShape() ) + switch ( via->GetViaType() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp index 865986acc9..f75dfbdeba 100644 --- a/pcbnew/exporters/export_d356.cpp +++ b/pcbnew/exporters/export_d356.cpp @@ -198,23 +198,23 @@ static void build_via_testpoints( BOARD *aPcb, { if( track->Type() == PCB_VIA_T ) { - SEGVIA *via = (SEGVIA*) track; - NETINFO_ITEM *net = track->GetNet(); + VIA *via = (VIA*) track; + NETINFO_ITEM *net = track->GetNet(); D356_RECORD rk; - rk.smd = false; + rk.smd = false; rk.hole = true; - if( net ) - rk.netname = net->GetNetname(); - else - rk.netname = wxEmptyString; + if( net ) + rk.netname = net->GetNetname(); + else + rk.netname = wxEmptyString; rk.refdes = wxT("VIA"); rk.pin = wxT(""); rk.midpoint = true; // Vias are always midpoints rk.drill = via->GetDrillValue(); rk.mechanical = false; LAYER_NUM top_layer, bottom_layer; - via->LayerPair( &top_layer, &bottom_layer ); + via->LayerPair( &top_layer, &bottom_layer ); rk.access = via_access_code( aPcb, top_layer, bottom_layer ); rk.x_location = via->GetPosition().x - origin.x; rk.y_location = origin.y - via->GetPosition().y; diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 8ef7e19214..601c91ae6d 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -222,8 +222,8 @@ static int PadListSortByShape( const void* aRefptr, const void* aObjptr ) // Sort vias for uniqueness static int ViaSort( const void* aRefptr, const void* aObjptr ) { - TRACK* padref = *(TRACK**) aRefptr; - TRACK* padcmp = *(TRACK**) aObjptr; + VIA* padref = *(VIA**) aRefptr; + VIA* padcmp = *(VIA**) aObjptr; if( padref->GetWidth() != padcmp->GetWidth() ) return padref->GetWidth() - padcmp->GetWidth(); @@ -253,8 +253,8 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) { std::vector pads; std::vector padstacks; - std::vector vias; - std::vector viastacks; + std::vector vias; + std::vector viastacks; padstacks.resize( 1 ); // We count pads from 1 // The master layermask (i.e. the enabled layers) for padstack generation @@ -275,17 +275,17 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) { if( track->Type() == PCB_VIA_T ) { - vias.push_back( track ); + vias.push_back( static_cast(track) ); } } - qsort( &vias[0], vias.size(), sizeof(TRACK*), ViaSort ); + qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort ); // Emit vias pads TRACK* old_via = 0; for( unsigned i = 0; i < vias.size(); i++ ) { - TRACK* via = vias[i]; + VIA* via = vias[i]; if( old_via && 0 == ViaSort( &old_via, &via ) ) continue; @@ -433,7 +433,7 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) // Via padstacks for( unsigned i = 0; i < viastacks.size(); i++ ) { - TRACK* via = viastacks[i]; + VIA* via = viastacks[i]; LAYER_MSK mask = via->GetLayerMask() & master_layermask; fprintf( aFile, "PADSTACK VIA%d.%d.%X %g\n", via->GetWidth(), via->GetDrillValue(), mask, @@ -832,11 +832,12 @@ static void CreateRoutesSection( FILE* aFile, BOARD* aPcb ) } if( track->Type() == PCB_VIA_T ) { + const VIA *via = static_cast(track); fprintf( aFile, "VIA VIA%d.%d.%X %g %g ALL %g via%d\n", - track->GetWidth(), track->GetDrillValue(), - track->GetLayerMask() & master_layermask, - MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ), - track->GetDrillValue() / SCALE_FACTOR, vianum++ ); + via->GetWidth(), via->GetDrillValue(), + via->GetLayerMask() & master_layermask, + MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ), + via->GetDrillValue() / SCALE_FACTOR, vianum++ ); } } diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index 5962ba276b..2522e813e2 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -801,7 +801,7 @@ static void export_round_padstack( MODEL_VRML& aModel, BOARD* pcb, } -static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, SEGVIA* via ) +static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via ) { double x, y, r, hole; LAYER_NUM top_layer, bottom_layer; @@ -827,7 +827,7 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb ) { if( track->Type() == PCB_VIA_T ) { - export_vrml_via( aModel, pcb, (SEGVIA*) track ); + export_vrml_via( aModel, pcb, (const VIA*) track ); } else if( track->GetLayer() == FIRST_COPPER_LAYER || track->GetLayer() == LAST_COPPER_LAYER ) diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index 8a3413db1f..a8a086187a 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -458,7 +458,7 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, if( track->Type() != PCB_VIA_T ) continue; - SEGVIA* via = (SEGVIA*) track; + const VIA* via = (const VIA*) track; hole_value = via->GetDrillValue(); if( hole_value == 0 ) diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index a675d8fcfd..fd7059399a 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1342,7 +1342,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const { LAYER_NUM layer1, layer2; - SEGVIA* via = (SEGVIA*) aTrack; + const VIA* via = static_cast(aTrack); BOARD* board = (BOARD*) via->GetParent(); wxCHECK_RET( board != 0, wxT( "Via " ) + via->GetSelectMenuText() + @@ -1352,7 +1352,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const via->LayerPair( &layer1, &layer2 ); - switch( aTrack->GetShape() ) + switch( via->GetViaType() ) { case VIA_THROUGH: // Default shape not saved. break; @@ -1366,15 +1366,15 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const break; default: - THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), aTrack->GetShape() ) ); + THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) ); } m_out->Print( 0, " (at %s) (size %s)", FMT_IU( aTrack->GetStart() ).c_str(), FMT_IU( aTrack->GetWidth() ).c_str() ); - if( aTrack->GetDrill() != UNDEFINED_DRILL_DIAMETER ) - m_out->Print( 0, " (drill %s)", FMT_IU( aTrack->GetDrill() ).c_str() ); + if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER ) + m_out->Print( 0, " (drill %s)", FMT_IU( via->GetDrill() ).c_str() ); m_out->Print( 0, " (layers %s %s)", m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(), diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index f548c2b997..12e500b023 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1998,7 +1998,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) assert( TESTLINE( "Po" ) ); - int shape = intParse( line + SZ( "Po" ), &data ); + VIATYPE_T viatype = static_cast( intParse( line + SZ( "Po" ), &data )); BIU start_x = biuParse( data, &data ); BIU start_y = biuParse( data, &data ); BIU end_x = biuParse( data, &data ); @@ -2059,7 +2059,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) break; case PCB_VIA_T: - newTrack = new SEGVIA( m_board ); + newTrack = new VIA( m_board ); m_board->m_Track.Append( newTrack ); break; @@ -2075,19 +2075,20 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) newTrack->SetEnd( wxPoint( end_x, end_y ) ); newTrack->SetWidth( width ); - newTrack->SetShape( shape ); - - if( drill < 0 ) - newTrack->SetDrillDefault(); - else - newTrack->SetDrill( drill ); - newTrack->SetLayer( layer ); if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible: { - if( newTrack->GetShape() == VIA_THROUGH ) - ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); + VIA *via = static_cast( newTrack ); + via->SetViaType( viatype ); + + if( drill < 0 ) + via->SetDrillDefault(); + else + via->SetDrill( drill ); + + if( via->GetViaType() == VIA_THROUGH ) + via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } newTrack->SetNetCode( net_code ); @@ -3620,17 +3621,24 @@ void LEGACY_PLUGIN::savePCB_LINE( const DRAWSEGMENT* me ) const void LEGACY_PLUGIN::saveTRACK( const TRACK* me ) const { int type = 0; + VIATYPE_T viatype = VIA_NOT_DEFINED; + int drill = UNDEFINED_DRILL_DIAMETER; if( me->Type() == PCB_VIA_T ) + { + const VIA *via = static_cast(me); type = 1; + viatype = via->GetViaType(); + drill = via->GetDrill(); + } fprintf(m_fp, "Po %d %s %s %s %s\n", - me->GetShape(), + viatype, fmtBIUPoint( me->GetStart() ).c_str(), fmtBIUPoint( me->GetEnd() ).c_str(), fmtBIU( me->GetWidth() ).c_str(), - me->GetDrill() == UNDEFINED_DRILL_DIAMETER ? - "-1" : fmtBIU( me->GetDrill() ).c_str() ); + drill == UNDEFINED_DRILL_DIAMETER ? + "-1" : fmtBIU( drill ).c_str() ); fprintf(m_fp, "De %d %d %d %lX %X\n", me->GetLayer(), type, me->GetNetCode(), diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp index 5c84d0d6d8..1c901cf760 100644 --- a/pcbnew/magnetic_tracks_functions.cpp +++ b/pcbnew/magnetic_tracks_functions.cpp @@ -193,7 +193,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, { LAYER_MSK layer_mask = GetLayerMask( layer ); - TRACK* track = m_Pcb->GetTrace( m_Pcb->m_Track, pos, layer_mask ); + TRACK* track = m_Pcb->GetTrack( m_Pcb->m_Track, pos, layer_mask ); if( !track || track->Type() != PCB_TRACE_T ) { diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 6525d7abd7..7d108eea4b 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -709,7 +709,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_StartSegmentPresent = s_EndSegmentPresent = true; if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) ) - TrackToStartPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); + TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, FLG_START ); // Test if more than one segment is connected to this point if( TrackToStartPoint ) @@ -717,14 +717,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToStartPoint->SetState( BUSY, true ); if( ( TrackToStartPoint->Type() == PCB_VIA_T ) - || track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, FLG_START ) ) error = true; TrackToStartPoint->SetState( BUSY, false ); } if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) ) - TrackToEndPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); + TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, FLG_END ); // Test if more than one segment is connected to this point if( TrackToEndPoint ) @@ -732,7 +732,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToEndPoint->SetState( BUSY, true ); if( (TrackToEndPoint->Type() == PCB_VIA_T) - || track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, FLG_END ) ) error = true; TrackToEndPoint->SetState( BUSY, false ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp index 4985958fc9..c1e7c416b2 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp @@ -329,7 +329,7 @@ void PCB_PAD::AddToBoard() if( IsCopperLayer( m_KiCadLayer ) ) { - SEGVIA* via = new SEGVIA( m_board ); + VIA* via = new VIA( m_board ); m_board->m_Track.Append( via ); via->SetTimeStamp( 0 ); @@ -338,8 +338,8 @@ void PCB_PAD::AddToBoard() via->SetEnd( wxPoint( m_positionX, m_positionY ) ); via->SetWidth( height ); - via->SetShape( VIA_THROUGH ); - ( (SEGVIA*) via )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); + via->SetViaType( VIA_THROUGH ); + via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); via->SetDrill( m_hole ); via->SetLayer( m_KiCadLayer ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index ff5d085939..c2d98603ed 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -210,15 +210,15 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) { case PCB_ZONE_T: case PCB_TRACE_T: - draw( (TRACK*) aItem, aLayer ); + draw( (const TRACK*) aItem, aLayer ); break; case PCB_VIA_T: - draw( (SEGVIA*) aItem, aLayer ); + draw( (const VIA*) aItem, aLayer ); break; case PCB_PAD_T: - draw( (D_PAD*) aItem, aLayer ); + draw( (const D_PAD*) aItem, aLayer ); break; case PCB_LINE_T: @@ -329,7 +329,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) } -void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) +void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) { VECTOR2D center( aVia->GetStart() ); double radius; diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index cf9f242b8c..85b1192936 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -37,7 +37,7 @@ class DISPLAY_OPTIONS; class BOARD_ITEM; class BOARD; -class SEGVIA; +class VIA; class TRACK; class D_PAD; class DRAWSEGMENT; @@ -161,7 +161,7 @@ protected: // Drawing functions for various types of PCB-specific items void draw( const TRACK* aTrack, int aLayer ); - void draw( const SEGVIA* aVia, int aLayer ); + void draw( const VIA* aVia, int aLayer ); void draw( const D_PAD* aPad, int aLayer ); void draw( const DRAWSEGMENT* aSegment ); void draw( const TEXTE_PCB* aText, int aLayer ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 11b4035090..97e073d1d5 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -432,7 +432,7 @@ BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR ) break; case T_via: - m_board->Add( parseSEGVIA(), ADD_APPEND ); + m_board->Add( parseVIA(), ADD_APPEND ); break; case T_zone: @@ -2310,15 +2310,15 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR ) } -SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) +VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR ) { wxCHECK_MSG( CurTok() == T_via, NULL, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as SEGVIA." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) ); wxPoint pt; T token; - std::auto_ptr< SEGVIA > via( new SEGVIA( m_board ) ); + std::auto_ptr< VIA > via( new VIA( m_board ) ); for( token = NextTok(); token != T_RIGHT; token = NextTok() ) { @@ -2328,11 +2328,11 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) switch( token ) { case T_blind: - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); break; case T_micro: - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); break; case T_at: diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h index 0dfb0bbdc5..eeb4faf9d6 100644 --- a/pcbnew/pcb_parser.h +++ b/pcbnew/pcb_parser.h @@ -49,7 +49,7 @@ class TEXTE_PCB; class TRACK; class MODULE; class PCB_TARGET; -class SEGVIA; +class VIA; class S3D_MASTER; class ZONE_CONTAINER; @@ -101,7 +101,7 @@ class PCB_PARSER : public PCB_LEXER EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ); D_PAD* parseD_PAD( MODULE* aParent = NULL ) throw( IO_ERROR, PARSE_ERROR ); TRACK* parseTRACK() throw( IO_ERROR, PARSE_ERROR ); - SEGVIA* parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ); + VIA* parseVIA() throw( IO_ERROR, PARSE_ERROR ); ZONE_CONTAINER* parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ); PCB_TARGET* parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR ); BOARD* parseBOARD() throw( IO_ERROR, PARSE_ERROR ); diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 34d708195b..f299787716 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -357,10 +357,10 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, // plot them on solder mask for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA* Via = dynamic_cast( track ); - SEGVIA* Via = (SEGVIA*) track; + if( !Via ) + continue; // vias are not plotted if not on selected layer, but if layer // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn, @@ -396,7 +396,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, if( diameter <= 0 ) continue; - EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetShape()); + EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetViaType()); // Set plot color (change WHITE to LIGHTGRAY because // the white items are not seen on a white paper or screen aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY); @@ -534,10 +534,10 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, int via_margin = via_clearance + inflate; for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA* via = dynamic_cast( track ); - SEGVIA* via = (SEGVIA*) track; + if( !via ) + continue; // vias are plotted only if they are on the corresponding // external copper layer @@ -553,11 +553,11 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, continue; via->TransformShapeWithClearanceToPolygon( bufferPolys, via_margin, - circleToSegmentsCount, - correction ); + circleToSegmentsCount, + correction ); via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance, - circleToSegmentsCount, - correction ); + circleToSegmentsCount, + correction ); } } diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index aa4dfc3860..1535b3593f 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -685,11 +685,12 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() for( TRACK *pts = m_board->m_Track; pts != NULL; pts = pts->Next() ) { - if( pts->Type() != PCB_VIA_T ) - continue; + const VIA *via = dynamic_cast( pts ); - plotOneDrillMark( PAD_DRILL_CIRCLE, pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ), - wxSize( pts->GetWidth(), 0 ), 0, small_drill ); + if( via ) + plotOneDrillMark( PAD_DRILL_CIRCLE, via->GetStart(), + wxSize( via->GetDrillValue(), 0 ), + wxSize( via->GetWidth(), 0 ), 0, small_drill ); } for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() ) diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp index f663521417..2683e268b5 100644 --- a/pcbnew/print_board_functions.cpp +++ b/pcbnew/print_board_functions.cpp @@ -249,12 +249,14 @@ void PCB_EDIT_FRAME::PrintPage( wxDC* aDC, if( track->Type() == PCB_VIA_T ) // VIA encountered. { - int radius = track->GetWidth() >> 1; - EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + track->GetShape() ); + int radius = track->GetWidth() / 2; + const VIA *via = static_cast( track ); + + EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->GetViaType() ); GRSetDrawMode( aDC, drawmode ); GRFilledCircle( m_canvas->GetClipBox(), aDC, - track->GetStart().x, - track->GetStart().y, + via->GetStart().x, + via->GetStart().y, radius, 0, color, color ); } @@ -313,11 +315,12 @@ void PCB_EDIT_FRAME::PrintPage( wxDC* aDC, if( track->Type() == PCB_VIA_T ) // VIA encountered. { int diameter; + const VIA *via = static_cast( track ); if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE ) - diameter = std::min( SMALL_DRILL, track->GetDrillValue() ); + diameter = std::min( SMALL_DRILL, via->GetDrillValue() ); else - diameter = track->GetDrillValue(); + diameter = via->GetDrillValue(); GRFilledCircle( m_canvas->GetClipBox(), aDC, track->GetStart().x, track->GetStart().y, diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 97f04e29b0..26a0d34bf2 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -393,7 +393,7 @@ void RN_NET::AddItem( const D_PAD* aPad ) } -void RN_NET::AddItem( const SEGVIA* aVia ) +void RN_NET::AddItem( const VIA* aVia ) { m_vias[aVia] = m_links.AddNode( aVia->GetPosition().x, aVia->GetPosition().y ); @@ -482,7 +482,7 @@ void RN_NET::RemoveItem( const D_PAD* aPad ) } -void RN_NET::RemoveItem( const SEGVIA* aVia ) +void RN_NET::RemoveItem( const VIA* aVia ) { try { @@ -686,7 +686,7 @@ std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con case PCB_VIA_T: { - const SEGVIA* via = static_cast( aItem ); + const VIA* via = static_cast( aItem ); nodes.push_back( m_vias.at( via ) ); } break; @@ -877,7 +877,7 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) break; case PCB_VIA_T: - m_nets[net].AddItem( static_cast( aItem ) ); + m_nets[net].AddItem( static_cast( aItem ) ); break; case PCB_ZONE_AREA_T: @@ -928,7 +928,7 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem ) break; case PCB_VIA_T: - m_nets[net].RemoveItem( static_cast( aItem ) ); + m_nets[net].RemoveItem( static_cast( aItem ) ); break; case PCB_ZONE_AREA_T: @@ -973,7 +973,7 @@ void RN_DATA::ProcessBoard() if( netCode > 0 ) { if( track->Type() == PCB_VIA_T ) - m_nets[netCode].AddItem( static_cast( track ) ); + m_nets[netCode].AddItem( static_cast( track ) ); else if( track->Type() == PCB_TRACE_T ) m_nets[netCode].AddItem( track ); } diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 712909f2fa..59f3f0e356 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -44,7 +44,7 @@ class BOARD_ITEM; class BOARD_CONNECTED_ITEM; class MODULE; class D_PAD; -class SEGVIA; +class VIA; class TRACK; class ZONE_CONTAINER; class CPolyPt; @@ -332,7 +332,7 @@ public: * taken into account during ratsnest computations. * @param aVia is a via for which node is added. */ - void AddItem( const SEGVIA* aVia ); + void AddItem( const VIA* aVia ); /** * Function AddItem() @@ -364,7 +364,7 @@ public: * taken into account during ratsnest computations anymore. * @param aVia is a via for which nodes and edges are removed. */ - void RemoveItem( const SEGVIA* aVia ); + void RemoveItem( const VIA* aVia ); /** * Function RemoveItem() @@ -522,7 +522,7 @@ protected: boost::unordered_map m_pads; ///> Map that associates nodes in the ratsnest model to respective vias. - boost::unordered_map m_vias; + boost::unordered_map m_vias; ///> Map that associates edges in the ratsnest model to respective tracks. boost::unordered_map m_tracks; diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index e3cf287596..5f63911751 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -189,7 +189,7 @@ PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack ) } -PNS_ITEM* PNS_ROUTER::syncVia( SEGVIA* aVia ) +PNS_ITEM* PNS_ROUTER::syncVia( VIA* aVia ) { PNS_VIA* v = new PNS_VIA( aVia->GetPosition(), @@ -268,7 +268,7 @@ void PNS_ROUTER::SyncWorld() if( type == PCB_TRACE_T ) item = syncTrack( t ); else if( type == PCB_VIA_T ) - item = syncVia( static_cast( t ) ); + item = syncVia( static_cast( t ) ); if( item ) m_world->Add( item ); @@ -618,7 +618,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) case PNS_ITEM::VIA: { - SEGVIA* via_board = new SEGVIA( m_board ); + VIA* via_board = new VIA( m_board ); PNS_VIA* via = static_cast( item ); via_board->SetPosition( wxPoint( via->GetPos().x, via->GetPos().y ) ); via_board->SetWidth( via->GetDiameter() ); diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 430f950a37..e5fabbeec2 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -37,7 +37,7 @@ class BOARD; class BOARD_ITEM; class D_PAD; class TRACK; -class SEGVIA; +class VIA; class PNS_NODE; class PNS_LINE_PLACER; class PNS_ITEM; @@ -169,7 +169,7 @@ private: PNS_ITEM* syncPad( D_PAD* aPad ); PNS_ITEM* syncTrack( TRACK* aTrack ); - PNS_ITEM* syncVia( SEGVIA* aVia ); + PNS_ITEM* syncVia( VIA* aVia ); void commitPad( PNS_SOLID* aPad ); void commitSegment( PNS_SEGMENT* aTrack ); diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h index 35572563fa..d2a5104d95 100644 --- a/pcbnew/specctra.h +++ b/pcbnew/specctra.h @@ -40,7 +40,7 @@ class TYPE_COLLECTOR; // outside the DSN namespace class BOARD; class TRACK; -class SEGVIA; +class VIA; class NETCLASS; class MODULE; @@ -3790,12 +3790,12 @@ class SPECCTRA_DB : public SPECCTRA_LEXER /** * Function makeVia - * makes any kind of PADSTACK using the given KiCad SEGVIA. - * @param aVia The SEGVIA to build the padstack from. + * makes any kind of PADSTACK using the given KiCad VIA. + * @param aVia The VIA to build the padstack from. * @return PADSTACK* - The padstack, which is on the heap only, user must save * or delete it. */ - PADSTACK* makeVia( const SEGVIA* aVia ); + PADSTACK* makeVia( const ::VIA* aVia ); /** * Function deleteNETs @@ -3827,10 +3827,10 @@ class SPECCTRA_DB : public SPECCTRA_LEXER /** * Function makeVIA - * instantiates a KiCad SEGVIA on the heap and initializes it with internal + * instantiates a KiCad VIA on the heap and initializes it with internal * values consistent with the given PADSTACK, POINT, and netcode. */ - SEGVIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ); + ::VIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ); //--------------------------------------------------------- diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 40aa2eeb97..ef452ce66d 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -834,7 +834,7 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter, } -PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) +PADSTACK* SPECCTRA_DB::makeVia( const ::VIA* aVia ) { LAYER_NUM topLayerNum; LAYER_NUM botLayerNum; @@ -1985,7 +1985,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) for( int i = 0; iType() == PCB_VIA_T ); int netcode = via->GetNetCode(); diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 417d433bb3..dbe998375c 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -214,9 +214,9 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro } -SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ) +::VIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ) { - SEGVIA* via = 0; + ::VIA* via = 0; SHAPE* shape; int shapeCount = aPadstack->Length(); @@ -261,10 +261,10 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); via->SetWidth( viaDiam ); via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } @@ -279,10 +279,10 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); via->SetWidth( viaDiam ); via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } @@ -321,15 +321,15 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet viaDiam = scale( circle->diameter, routeResolution ); } - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); if( (topLayerNdx==0 && botLayerNdx==1) || (topLayerNdx==copperLayerCount-2 && botLayerNdx==copperLayerCount-1)) - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); else - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); via->SetWidth( viaDiam ); @@ -546,7 +546,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) for( unsigned v=0; vvertexes.size(); ++v ) { - SEGVIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode ); + ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode ); aBoard->Add( via ); } } diff --git a/pcbnew/swap_layers.cpp b/pcbnew/swap_layers.cpp index 11180b107b..e3bf92bc59 100644 --- a/pcbnew/swap_layers.cpp +++ b/pcbnew/swap_layers.cpp @@ -360,9 +360,9 @@ void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event ) if( pt_segm->Type() == PCB_VIA_T ) { - SEGVIA* Via = (SEGVIA*) pt_segm; + VIA* Via = (VIA*) pt_segm; - if( Via->GetShape() == VIA_THROUGH ) + if( Via->GetViaType() == VIA_THROUGH ) continue; LAYER_NUM top_layer, bottom_layer; diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index fd567a16d1..d5d85b5431 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -459,7 +459,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const { // For vias it is enough if only one of layers is visible LAYER_NUM top, bottom; - static_cast( aItem )->LayerPair( &top, &bottom ); + static_cast( aItem )->LayerPair( &top, &bottom ); return board->IsLayerVisible( top ) || board->IsLayerVisible( bottom ); } diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp index 59c0f042fb..2e929fc9a1 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -168,7 +168,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, /* A segment must be connected to the starting point, otherwise * it is unnecessary to analyze the other point */ - pt_segm = GetTrace( bufStart, bufEnd, start, startmasklayer ); + pt_segm = GetTrack( bufStart, bufEnd, start, startmasklayer ); if( pt_segm == NULL ) // Not connected to the track starting point. { @@ -183,7 +183,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, */ for( pt_del = bufStart, nbconnect = 0; ; ) { - pt_segm = GetTrace( pt_del, bufEnd, end, endmasklayer ); + pt_segm = GetTrack( pt_del, bufEnd, end, endmasklayer ); if( pt_segm == NULL ) break; diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp index ce9c948c46..b1d69d0455 100644 --- a/pcbnew/zones_polygons_test_connections.cpp +++ b/pcbnew/zones_polygons_test_connections.cpp @@ -175,12 +175,15 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) } else if( item->Type() == PCB_VIA_T ) { - pos1 = pos2 = ( (SEGVIA*) item )->GetStart(); + const VIA *via = static_cast( item ); + pos1 = via->GetStart(); + pos2 = pos1; } else if( item->Type() == PCB_TRACE_T ) { - pos1 = ( (TRACK*) item )->GetStart(); - pos2 = ( (TRACK*) item )->GetEnd(); + const TRACK *trk = static_cast( item ); + pos1 = trk->GetStart(); + pos2 = trk->GetEnd(); } else { From c0879414a552a8c9c2909d4c9672b040ec41e7a1 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Fri, 25 Apr 2014 01:43:14 -0500 Subject: [PATCH 24/36] SEGVIA -> VIA for swig --- pcbnew/scripting/board_item.i | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/pcbnew/scripting/board_item.i b/pcbnew/scripting/board_item.i index 37e3ed1f83..1671c10da2 100644 --- a/pcbnew/scripting/board_item.i +++ b/pcbnew/scripting/board_item.i @@ -36,28 +36,27 @@ } %extend BOARD_ITEM -{ - TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } - DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } - MODULE* Cast_to_MODULE() { return dynamic_cast(self); } - TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } - DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } - MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } - BOARD* Cast_to_BOARD() { return dynamic_cast(self); } - EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } - D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } - TRACK* Cast_to_TRACK() { return dynamic_cast(self); } +{ + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE() { return dynamic_cast(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast(self); } SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } - SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } - + VIA* Cast_to_VIA() { return dynamic_cast(self); } %pythoncode { def Cast(self): - + ct = self.GetClass() - + if ct=="PTEXT": return self.Cast_to_TEXTE_PCB() elif ct=="BOARD": @@ -77,7 +76,7 @@ elif ct=="ZONE": return self.Cast_to_SEGZONE() elif ct=="VIA": - return self.Cast_to_SEGVIA() + return self.Cast_to_VIA() elif ct=="TRACK": return self.Cast_to_TRACK() else: From 948f22de6dd6fda8f3ca663155abcf2f1d3ae8c0 Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Fri, 25 Apr 2014 10:03:50 +0200 Subject: [PATCH 25/36] Removed the ugly bit stuffing for the bottom via layer number (just replaced it with a member) --- pcbnew/class_track.cpp | 20 ++++++++++---------- pcbnew/class_track.h | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 48a665927d..d1564f0066 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -179,6 +179,7 @@ VIA::VIA( BOARD_ITEM* aParent ) : TRACK( aParent, PCB_VIA_T ) { SetViaType( VIA_THROUGH ); + m_BottomLayer = LAYER_N_BACK; m_Width = Millimeter2iu( 0.5 ); SetDrillDefault(); } @@ -432,19 +433,19 @@ LAYER_MSK TRACK::GetLayerMask() const } -void VIA::SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ) +void VIA::SetLayerPair( LAYER_NUM aTopLayer, LAYER_NUM aBottomLayer ) { if( GetViaType() == VIA_THROUGH ) { - top_layer = LAYER_N_FRONT; - bottom_layer = LAYER_N_BACK; + aTopLayer = LAYER_N_FRONT; + aBottomLayer = LAYER_N_BACK; } - if( bottom_layer > top_layer ) - EXCHG( bottom_layer, top_layer ); + if( aBottomLayer > aTopLayer ) + EXCHG( aBottomLayer, aTopLayer ); - // XXX EVIL usage of LAYER - m_Layer = (top_layer & 15) + ( (bottom_layer & 15) << 4 ); + m_Layer = aTopLayer; + m_BottomLayer = aBottomLayer; } @@ -455,9 +456,8 @@ void VIA::LayerPair( LAYER_NUM* top_layer, LAYER_NUM* bottom_layer ) const if( GetViaType() != VIA_THROUGH ) { - // XXX EVIL usage of LAYER - b_layer = (m_Layer >> 4) & 15; - t_layer = m_Layer & 15; + b_layer = m_BottomLayer; + t_layer = m_Layer; if( b_layer > t_layer ) EXCHG( b_layer, t_layer ); diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 8b727dde17..34b651094a 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -371,15 +371,12 @@ public: /** * Function SetLayerPair - * set the .m_Layer member param: - * For a via m_Layer contains the 2 layers : - * top layer and bottom layer used by the via. - * The via connect all layers from top layer to bottom layer - * 4 bits for the first layer and 4 next bits for the second layer + * For a via m_Layer contains the top layer, the other layer is in + * m_BottomLayer * @param top_layer = first layer connected by the via * @param bottom_layer = last layer connected by the via */ - void SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ); + void SetLayerPair( LAYER_NUM aTopLayer, LAYER_NUM aBottomLayer ); /** * Function LayerPair @@ -453,6 +450,9 @@ protected: virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); private: + /// The bottom layer of the via (the top layer is in m_Layer) + LAYER_NUM m_BottomLayer; + VIATYPE_T m_ViaType; // Type of via int m_Drill; // for vias: via drill (- 1 for default value) From 802a59dc521e6d34e3dfbc6b031307aec7add266 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 25 Apr 2014 18:49:32 +0200 Subject: [PATCH 26/36] eeschema: fix the very minor bug #1298094. But it was due to a bad bounding box calculation, which is now fixed. --- common/eda_text.cpp | 13 +------------ eeschema/sch_field.cpp | 33 ++++----------------------------- 2 files changed, 5 insertions(+), 41 deletions(-) diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 97da020d55..1c253819ba 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -32,14 +32,6 @@ #include // RotatePoint #include // EDA_DRAW_PANEL -// until bzr rev 4476, Y position of vertical justification -// of multiline texts was incorrectly calculated for BOTTOM -// and CENTER vertical justification. (Only the first line was justified) -// If this line is left uncommented, the bug is fixed, but -// creates a (very minor) issue for existing texts, mainly in Pcbnew -// because the text position is sometimes critical. -#define FIX_MULTILINE_VERT_JUSTIF - // Conversion to application internal units defined at build time. #if defined( PCBNEW ) #include @@ -205,7 +197,6 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const if( linecount > 1 ) { -#ifdef FIX_MULTILINE_VERT_JUSTIF int yoffset; linecount -= 1; @@ -224,7 +215,6 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const rect.SetY( rect.GetY() - yoffset ); break; } -#endif } rect.Inflate( thickness / 2 ); @@ -305,7 +295,6 @@ void EDA_TEXT::GetPositionsOfLinesOfMultilineText( offset.y = GetInterline(); -#ifdef FIX_MULTILINE_VERT_JUSTIF if( aLineCount > 1 ) { switch( m_VJustify ) @@ -326,7 +315,7 @@ void EDA_TEXT::GetPositionsOfLinesOfMultilineText( // Rotate the position of the first line // around the center of the multiline text block RotatePoint( &pos, m_Pos, m_Orient ); -#endif + // Rotate the offset lines to increase happened in the right direction RotatePoint( &offset, m_Orient ); diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 942bf820e8..3eb8462e9f 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -35,19 +35,6 @@ * They can be renamed and can appear in reports */ -/* set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use - * a justification relative to the text itself - * i.e. justification relative to an horizontal text - * or to 1 to keep the initial Eeschema behavior - * The initial behavior is: - * For vertical texts, exchange the horizontal and the vertical justification - * The idea is to keep the justification always left or top for instance, - * no matter the text orientation - * This is a bit tricky when you want to change a text field justification - * when the fiels and the component are both rotated 90.0 degrees - */ -#define USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR 0 - #include #include #include @@ -206,7 +193,7 @@ void SCH_FIELD::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, textpos = m_Pos - origin; textpos = parentComponent->GetScreenCoord( textpos ); textpos += parentComponent->GetPosition(); - GRLine( clipbox, DC, origin.x, origin.y, textpos.x, textpos.y, 2, DARKGRAY ); + GRLine( clipbox, DC, origin, textpos, 2, DARKGRAY ); } /* Enable this to draw the bounding box around the text field to validate @@ -281,26 +268,14 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const // Calculate the text bounding box: EDA_RECT rect; - // set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use - // a justification relative to the text itself - // i.e. justification relative to an horizontal text - // or to 1 to keep the initial behavior -#if (USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR == 1 ) - if( m_Orient == TEXT_ORIENT_VERT ) + if( m_id == REFERENCE ) // multi units have one letter or more added to reference { - // For vertical texts, exchange the horizontal and the vertical justification - // The idea is to keep the justification always left or top for instance, - // no matter the text orientation - SCH_FIELD text( *this ); // Make a local copy to swap justifications + SCH_FIELD text( *this ); // Make a local copy to change text // because GetBoundingBox() is const - int tmp = (int)text.m_VJustify; - NEGATE( tmp ); - text.m_VJustify = (EDA_TEXT_VJUSTIFY_T)text.m_HJustify; - text.m_HJustify = (EDA_TEXT_HJUSTIFY_T)tmp; + text.SetText( GetFullyQualifiedText() ); rect = text.GetTextBox( -1, linewidth ); } else -#endif rect = GetTextBox( -1, linewidth ); // Calculate the bounding box position relative to the component: From c2af94ac03c7dd7291fa05cf7f4f6b3ef53d705d Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Fri, 25 Apr 2014 19:13:33 +0200 Subject: [PATCH 27/36] Reworked the endpoint designator constants FLG_BEGIN and FLG_END in a ENDPOINT_T enum type --- pcbnew/autorouter/solve.cpp | 6 ++++-- pcbnew/class_board.cpp | 15 +++------------ pcbnew/class_board.h | 2 +- pcbnew/class_track.cpp | 11 +++-------- pcbnew/class_track.h | 13 ++++++++++++- pcbnew/clean.cpp | 30 +++++++++++++++--------------- pcbnew/editrack.cpp | 4 ++-- pcbnew/move_or_drag_track.cpp | 8 ++++---- pcbnew/pcbnew.h | 8 +++++--- 9 files changed, 49 insertions(+), 48 deletions(-) diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index 5e94db6b09..8ddf52f040 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -1300,12 +1300,14 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) g_CurrentTrackList.PushBack( newTrack ); } - g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, FLG_START ); + g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, + ENDPOINT_START ); if( g_FirstTrackSegment->start ) g_FirstTrackSegment->SetState( BEGIN_ONPAD, true ); - g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, FLG_END ); + g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, + ENDPOINT_END ); if( g_CurrentTrackSegment->end ) g_CurrentTrackSegment->SetState( END_ONPAD, true ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 6109e60945..2960e9e315 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1598,22 +1598,13 @@ D_PAD* BOARD::GetPad( const wxPoint& aPosition, LAYER_MSK aLayerMask ) } -D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint ) +D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint ) { D_PAD* pad = NULL; - wxPoint aPosition; + const wxPoint &aPosition = aTrace->GetEndPoint( aEndPoint ); LAYER_MSK aLayerMask = GetLayerMask( aTrace->GetLayer() ); - if( aEndPoint == FLG_START ) - { - aPosition = aTrace->GetStart(); - } - else - { - aPosition = aTrace->GetEnd(); - } - for( MODULE* module = m_Modules; module; module = module->Next() ) { pad = module->GetPad( aPosition, aLayerMask ); @@ -2195,7 +2186,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS aSegment->end = newTrack; aSegment->SetState( END_ONPAD, false ); - D_PAD * pad = GetPad( newTrack, FLG_START ); + D_PAD * pad = GetPad( newTrack, ENDPOINT_START ); if ( pad ) { diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index d899096819..516d09ca1f 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -1392,7 +1392,7 @@ public: * @param aEndPoint The end point of \a aTrace the hit test against. * @return A pointer to a D_PAD object if found or NULL if not found. */ - D_PAD* GetPad( TRACK* aTrace, int aEndPoint ); + D_PAD* GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint ); /** * Function GetPadFast diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index d1564f0066..abf4d7a732 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -70,7 +70,7 @@ static bool ShowClearance( const TRACK* aTrack ) * return true if the dist between p1 and p2 < max_dist * Currently in test (currently ratsnest algos work only if p1 == p2) */ -inline bool IsNear( wxPoint& p1, wxPoint& p2, int max_dist ) +inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist ) { #if 0 // Do not change it: does not work int dist; @@ -1320,21 +1320,16 @@ VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayer } -TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) +TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint ) { const int NEIGHTBOUR_COUNT_MAX = 50; TRACK* previousSegment; TRACK* nextSegment; int Reflayer; - wxPoint position; int ii; int max_dist; - - if( aEndPoint == FLG_START ) - position = m_Start; - else - position = m_End; + const wxPoint &position = GetEndPoint( aEndPoint ); Reflayer = GetLayerMask(); diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 34b651094a..63c9026967 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -31,6 +31,7 @@ #define CLASS_TRACK_H +#include #include #include #include @@ -124,6 +125,16 @@ public: void SetStart( const wxPoint& aStart ) { m_Start = aStart; } const wxPoint& GetStart() const { return m_Start; } + + /// Return the selected endpoint (start or end) + const wxPoint& GetEndPoint( ENDPOINT_T aEndPoint ) const + { + if( aEndPoint == ENDPOINT_START ) + return m_Start; + else + return m_End; + } + // Virtual function const EDA_RECT GetBoundingBox() const; @@ -252,7 +263,7 @@ public: * @param aEndPoint The start or end point of the segment to test against. * @return A TRACK object pointer if found otherwise NULL. */ - TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ); + TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint ); /** * Function GetEndSegments diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 443394157d..9bf5a83c95 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -86,7 +86,7 @@ private: * i.e. when they are colinear, same width, and obviously same layer */ TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, - TRACK* aCandidate, int aEndType ); + TRACK* aCandidate, ENDPOINT_T aEndType ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -304,7 +304,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() if( (type_end & START_ON_PAD ) == 0 ) { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, FLG_START ); + TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); if( other == NULL ) // Test a connection to zones { @@ -341,7 +341,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() track->SetState( BUSY, true ); VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, FLG_START ); + other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); if( other == NULL ) { @@ -364,7 +364,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() // test if this track end point is connected to an other track if( (type_end & END_ON_PAD ) == 0 ) { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, FLG_END ); + TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); if( other == NULL ) // Test a connection to zones { @@ -402,7 +402,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() track->SetState( BUSY, true ); VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, FLG_END ); + other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); if( other == NULL ) { @@ -508,7 +508,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the START point of the current segment for( segStart = segment->Next(); ; ) { - segStart = segment->GetTrack( segStart, NULL, FLG_START ); + segStart = segment->GetTrack( segStart, NULL, ENDPOINT_START ); if( segStart ) { @@ -522,7 +522,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segStart->SetState( BUSY, true ); - other = segment->GetTrack( m_Brd->m_Track, NULL, FLG_START ); + other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); segStart->SetState( BUSY, false ); if( other == NULL ) @@ -535,7 +535,7 @@ bool TRACKS_CLEANER::clean_segments() if( flag ) // We have the starting point of the segment is connected to an other segment { - segDelete = mergeCollinearSegmentIfPossible( segment, segStart, FLG_START ); + segDelete = mergeCollinearSegmentIfPossible( segment, segStart, ENDPOINT_START ); if( segDelete ) { @@ -548,7 +548,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the END point of the current segment: for( segEnd = segment->Next(); ; ) { - segEnd = segment->GetTrack( segEnd, NULL, FLG_END ); + segEnd = segment->GetTrack( segEnd, NULL, ENDPOINT_END ); if( segEnd ) { @@ -560,7 +560,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segEnd->SetState( BUSY, true ); - other = segment->GetTrack( m_Brd->m_Track, NULL, FLG_END ); + other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); segEnd->SetState( BUSY, false ); if( other == NULL ) @@ -576,7 +576,7 @@ bool TRACKS_CLEANER::clean_segments() if( flag & 2 ) // We have the ending point of the segment is connected to an other segment { - segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, FLG_END ); + segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, ENDPOINT_END ); if( segDelete ) { @@ -607,7 +607,7 @@ bool TRACKS_CLEANER::clean_segments() * else return NULL */ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, - int aEndType ) + ENDPOINT_T aEndType ) { if( aTrackRef->GetWidth() != aCandidate->GetWidth() ) return NULL; @@ -667,7 +667,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* * (this function) is called when there is only 2 connected segments, *and if this point is not on a pad, it can be removed and the 2 segments will be merged */ - if( aEndType == FLG_START ) + if( aEndType == ENDPOINT_START ) { // We do not have a pad, which is a always terminal point for a track if( aTrackRef->GetState( START_ON_PAD) ) @@ -744,7 +744,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrack( GetBoard()->m_Track, NULL, FLG_START ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ); if( other ) net_code_s = other->GetNetCode(); @@ -762,7 +762,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrack( GetBoard()->m_Track, NULL, FLG_END ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ); if( other ) net_code_e = other->GetNetCode(); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 41cc2d7e30..683b7d41d7 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -266,7 +266,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) newTrack->SetState( BEGIN_ONPAD | END_ONPAD, false ); - D_PAD* pad = GetBoard()->GetPad( previousTrack, FLG_END ); + D_PAD* pad = GetBoard()->GetPad( previousTrack, ENDPOINT_END ); if( pad ) { @@ -1057,7 +1057,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST& aTrackList ) while( track != NULL ) { TRACK* next_track = track->Next(); - LockPoint = pcb->GetPad( track, FLG_END ); + LockPoint = pcb->GetPad( track, ENDPOINT_END ); if( LockPoint ) { diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 7d108eea4b..6631ce31dc 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -709,7 +709,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_StartSegmentPresent = s_EndSegmentPresent = true; if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) ) - TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, FLG_START ); + TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ); // Test if more than one segment is connected to this point if( TrackToStartPoint ) @@ -717,14 +717,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToStartPoint->SetState( BUSY, true ); if( ( TrackToStartPoint->Type() == PCB_VIA_T ) - || track->GetTrack( GetBoard()->m_Track, NULL, FLG_START ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ) ) error = true; TrackToStartPoint->SetState( BUSY, false ); } if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) ) - TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, FLG_END ); + TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ); // Test if more than one segment is connected to this point if( TrackToEndPoint ) @@ -732,7 +732,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToEndPoint->SetState( BUSY, true ); if( (TrackToEndPoint->Type() == PCB_VIA_T) - || track->GetTrack( GetBoard()->m_Track, NULL, FLG_END ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ) ) error = true; TrackToEndPoint->SetState( BUSY, false ); diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h index 25df567ebb..d2c6427ea6 100644 --- a/pcbnew/pcbnew.h +++ b/pcbnew/pcbnew.h @@ -25,9 +25,11 @@ #define MATCH_LAYER (1 << 2) ///< if module not on current layer, do not select #define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select - -#define FLG_START 0 // Flag used in locate routines -#define FLG_END 1 // Flag used in locate routines +/// Flag used in locate routines (from which endpoint work) +enum ENDPOINT_T { + ENDPOINT_START = 0, + ENDPOINT_END = 1 +}; #define DIM_ANCRE_MODULE 3 // Anchor size (footprint center) From 29c8ec422079a32b0cb5cda8f6b1d5a2cc7b499c Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Sat, 26 Apr 2014 13:23:00 +0200 Subject: [PATCH 28/36] Fixed bug in via cleanup control flow --- pcbnew/clean.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 9bf5a83c95..4bcfb5127e 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -208,6 +208,8 @@ bool TRACKS_CLEANER::clean_vias() if( via->GetViaType() != VIA_THROUGH ) continue; } + else + continue; // Search and delete others vias at same location TRACK* alt_track = track->Next(); @@ -219,7 +221,6 @@ bool TRACKS_CLEANER::clean_vias() VIA *alt_via = dynamic_cast( alt_track ); if( alt_via ) { - if( alt_via->GetViaType() != VIA_THROUGH ) continue; From 834699accb56580d76a7b61f1ec603a6c8a4394a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 27 Apr 2014 13:30:45 +0200 Subject: [PATCH 29/36] Pcbnew: fix bug #1313076 (Filled Zones on technical layers) does not show up on 3D rendering --- 3d-viewer/3d_draw.cpp | 41 ++++++++++++++++++------------ CMakeModules/download_avhttp.cmake | 8 +++++- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 3216947b8e..0a703179fa 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -257,8 +257,8 @@ void EDA_3D_CANVAS::BuildBoard3DView() // Build a polygon from edge cut items wxString msg; - if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines, - allLayerHoles, &msg ) ) + + if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) ) { msg << wxT("\n\n") << _("Unable to calculate the board outlines.\n" @@ -432,7 +432,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() } // Draw vias holes (vertical cylinders) - for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) + for( const TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) { const VIA *via = dynamic_cast(track); @@ -441,7 +441,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() } // Draw pads holes (vertical cylinders) - for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) + for( const MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() ) Draw3DPadHole( pad ); @@ -508,6 +508,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() // to reduce time calculations // for holes and items which do not need // a fine representation + double correctionFactorLQ = 1.0 / cos( M_PI / (segcountLowQuality * 2) ); CPOLYGONS_LIST bufferPolys; bufferPolys.reserve( 100000 ); // Reserve for large board @@ -517,8 +518,8 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() CPOLYGONS_LIST bufferPcbOutlines; // stores the board main outlines // Build a polygon from edge cut items wxString msg; - if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines, - allLayerHoles, &msg ) ) + + if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) ) { msg << wxT("\n\n") << _("Unable to calculate the board outlines.\n" @@ -610,22 +611,30 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() continue; BuildPadShapeThickOutlineAsPolygon( pad, bufferPolys, - linewidth, - segcountforcircle, correctionFactor ); + linewidth, segcountforcircle, correctionFactor ); } } else module->TransformPadsShapesWithClearanceToPolygon( layer, - bufferPolys, - 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); module->TransformGraphicShapesWithClearanceToPolygonSet( layer, - bufferPolys, - 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); + } + + // Draw non copper zones + if( g_Parm_3D_Visu.GetFlag( FL_ZONE ) ) + { + for( int ii = 0; ii < pcb->GetAreaCount(); ii++ ) + { + ZONE_CONTAINER* zone = pcb->GetArea( ii ); + + if( !zone->IsOnLayer( layer ) ) + continue; + + zone->TransformSolidAreasShapesToPolygonSet( + bufferPolys, segcountLowQuality, correctionFactorLQ ); + } } // bufferPolys contains polygons to merge. Many overlaps . diff --git a/CMakeModules/download_avhttp.cmake b/CMakeModules/download_avhttp.cmake index 6fa9f423b4..abc52b7e89 100644 --- a/CMakeModules/download_avhttp.cmake +++ b/CMakeModules/download_avhttp.cmake @@ -38,6 +38,12 @@ # Where the library is to be installed. set( PREFIX ${DOWNLOAD_DIR}/avhttp ) +if( KICAD_SKIP_BOOST ) + set( AVHTTP_DEPEND "" ) +else() + set( AVHTTP_DEPEND "boost" ) +endif() + # Install the AVHTTP header only library ${PREFIX} ExternalProject_Add( avhttp @@ -46,7 +52,7 @@ ExternalProject_Add( avhttp # grab it from a local zip file for now, cmake caller's source dir URL ${CMAKE_CURRENT_SOURCE_DIR}/avhttp-master.zip - DEPENDS boost + DEPENDS ${AVHTTP_DEPEND} CONFIGURE_COMMAND "" From 4456840a1f2649008548da9b12f417d0990bfc84 Mon Sep 17 00:00:00 2001 From: unknown <804778@bugs.launchpad.net> Date: Sun, 27 Apr 2014 15:49:41 +0200 Subject: [PATCH 30/36] 3D viewer: Commit patch to enable the rendering of wrl files generated with Meshlab. See https://bugs.launchpad.net/kicad/+bug/804778 --- 3d-viewer/vrmlmodelparser.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/3d-viewer/vrmlmodelparser.cpp b/3d-viewer/vrmlmodelparser.cpp index 8891a424aa..0e3877eea4 100644 --- a/3d-viewer/vrmlmodelparser.cpp +++ b/3d-viewer/vrmlmodelparser.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2013 Tuomas Vaherkoski * Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -71,7 +71,7 @@ void VRML_MODEL_PARSER::Load( const wxString aFilename ) if ( text == NULL ) continue; - if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0 ) + if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Transform" ) == 0 || stricmp( text, "Group" ) == 0 ) { while( GetLine( file, line, &LineNum, 512 ) ) { @@ -121,7 +121,7 @@ int VRML_MODEL_PARSER::readMaterial( FILE* file, int* LineNum ) return 0; } - if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0) + if( stricmp( command, "DEF" ) == 0 || stricmp( command,"Transform" ) == 0 || stricmp( command, "Material") == 0) { material = new S3D_MATERIAL( GetMaster(), mat_name ); @@ -197,6 +197,9 @@ int VRML_MODEL_PARSER::readChildren( FILE* file, int* LineNum ) { text = strtok( line, sep_chars ); + if( *text == '[' ) + continue; + if( *text == ']' ) return 0; @@ -233,6 +236,11 @@ int VRML_MODEL_PARSER::readShape( FILE* file, int* LineNum ) break; } + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "appearance" ) == 0 ) { readAppearance( file, LineNum ); @@ -267,6 +275,11 @@ int VRML_MODEL_PARSER::readAppearance( FILE* file, int* LineNum ) break; } + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "material" ) == 0 ) { readMaterial( file, LineNum ); @@ -380,6 +393,16 @@ int VRML_MODEL_PARSER::readGeometry( FILE* file, int* LineNum ) break; } + if( stricmp( text, "creaseAngle" ) == 0 ) + { + continue; + } + + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "normalPerVertex" ) == 0 ) { text = strtok( NULL, " ,\t\n\r" ); From d2083b06718aaf20aaca693a9729746968495bec Mon Sep 17 00:00:00 2001 From: Marco Serantoni Date: Sun, 27 Apr 2014 16:28:37 +0200 Subject: [PATCH 31/36] [MacOSX] Fix for name collision with OSX headers, Maciej, Tomasz or others feel free to rework if you want/like --- include/geometry/rtree.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/geometry/rtree.h b/include/geometry/rtree.h index 6d5a5561d7..4ae5fafae6 100644 --- a/include/geometry/rtree.h +++ b/include/geometry/rtree.h @@ -32,10 +32,10 @@ #define ASSERT assert // RTree uses ASSERT( condition ) #ifndef Min - #define Min std::min + #define rMin std::min #endif // Min #ifndef Max - #define Max std::max + #define rMax std::max #endif // Max // @@ -1326,8 +1326,8 @@ typename RTREE_QUAL::Rect RTREE_QUAL::CombineRect( Rect* a_rectA, Rect* a_rectB for( int index = 0; index < NUMDIMS; ++index ) { - newRect.m_min[index] = Min( a_rectA->m_min[index], a_rectB->m_min[index] ); - newRect.m_max[index] = Max( a_rectA->m_max[index], a_rectB->m_max[index] ); + newRect.m_min[index] = rMin( a_rectA->m_min[index], a_rectB->m_min[index] ); + newRect.m_max[index] = rMax( a_rectA->m_max[index], a_rectB->m_max[index] ); } return newRect; From 76771b856d185772ea9b5756df542be5c3407592 Mon Sep 17 00:00:00 2001 From: Marco Serantoni Date: Sun, 27 Apr 2014 16:30:49 +0200 Subject: [PATCH 32/36] [MacOSX] Fixing issue with kiface libs, now are symbolic linked to the owner bundle --- kicad/CMakeLists.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 1d76b4696b..0bb6ae8574 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -58,9 +58,35 @@ endif() if( APPLE ) + # binaries have to be build and kiface be in place + # Mockup the destination directory to linking symbolical + # Could be usefully also for debug in building place + add_custom_target( kiway-kicad-bundle-applinks ALL + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/eeschema/eeschema.app" "${CMAKE_BINARY_DIR}/kicad/eeschema.app" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.app" "${CMAKE_BINARY_DIR}/kicad/pcbnew.app" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/cvpcb/cvpcb.app" "${CMAKE_BINARY_DIR}/kicad/cvpcb.app" + DEPENDS eeschema pcbnew cvpcb eeschema_kiface pcbnew_kiface cvpcb_kiface + COMMENT "Making bundles links in kicad.app directory" + ) + + # Kicad is dependent by other applications (otherwise what we could symlink?) + add_dependencies( kicad kiway-kicad-bundle-applinks ) + + # making kiface links relative - .app symlinks are alredy in place ! + add_custom_target( kiway-kicad-bundle-kiface-links ALL + COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../eeschema.app/Contents/MacOS/_eeschema.kiface" "_eeschema.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../pcbnew.app/Contents/MacOS/_pcbnew.kiface" "_pcbnew.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../cvpcb.app/Contents/MacOS/_cvpcb.kiface" "_cvpcb.kiface" + DEPENDS kicad + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/kicad/kicad.app/Contents/MacOS" + COMMENT "Making Symbolik link to kiface libs in Kicad.app Bundle" + ) + set_target_properties( kicad PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ) + + target_link_libraries( kicad common bitmaps From a990c9f0474f34c13d0cbfa7418b33277e979fdc Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Mon, 28 Apr 2014 04:23:39 -0500 Subject: [PATCH 33/36] Reverse Marco's patch, pending a proper review of my last patch from an English speaking Mac developer. --- kicad/CMakeLists.txt | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 0bb6ae8574..1d76b4696b 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -58,35 +58,9 @@ endif() if( APPLE ) - # binaries have to be build and kiface be in place - # Mockup the destination directory to linking symbolical - # Could be usefully also for debug in building place - add_custom_target( kiway-kicad-bundle-applinks ALL - COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/eeschema/eeschema.app" "${CMAKE_BINARY_DIR}/kicad/eeschema.app" - COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.app" "${CMAKE_BINARY_DIR}/kicad/pcbnew.app" - COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/cvpcb/cvpcb.app" "${CMAKE_BINARY_DIR}/kicad/cvpcb.app" - DEPENDS eeschema pcbnew cvpcb eeschema_kiface pcbnew_kiface cvpcb_kiface - COMMENT "Making bundles links in kicad.app directory" - ) - - # Kicad is dependent by other applications (otherwise what we could symlink?) - add_dependencies( kicad kiway-kicad-bundle-applinks ) - - # making kiface links relative - .app symlinks are alredy in place ! - add_custom_target( kiway-kicad-bundle-kiface-links ALL - COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../eeschema.app/Contents/MacOS/_eeschema.kiface" "_eeschema.kiface" - COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../pcbnew.app/Contents/MacOS/_pcbnew.kiface" "_pcbnew.kiface" - COMMAND ${CMAKE_COMMAND} -E create_symlink "../../../cvpcb.app/Contents/MacOS/_cvpcb.kiface" "_cvpcb.kiface" - DEPENDS kicad - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/kicad/kicad.app/Contents/MacOS" - COMMENT "Making Symbolik link to kiface libs in Kicad.app Bundle" - ) - set_target_properties( kicad PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ) - - target_link_libraries( kicad common bitmaps From 7b843ecac8cb064d8b384a44e3d12a8f3b05a612 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 28 Apr 2014 18:13:18 +0200 Subject: [PATCH 34/36] Plots function: fix a bug about virtual PLOTTER::Text, which was not virtual for derived classes due to a missing parameter in ::Text in these classes. Noticeable only in SVG plot. SVG plot, fix a missing reinitialization in plot lines, which could define a filled polyline, instead of a simple polyline (these fixes solve Bug #1313084 ) --- common/common_plotDXF_functions.cpp | 17 +++++++++---- common/common_plotPDF_functions.cpp | 13 ++++++---- common/common_plotPS_functions.cpp | 37 ++++++++++++++++------------- common/common_plotSVG_functions.cpp | 14 +++++++++-- eeschema/sheet.cpp | 2 -- include/plot_common.h | 12 ++++++---- 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp index 2368cb98f7..0164ca628b 100644 --- a/common/common_plotDXF_functions.cpp +++ b/common/common_plotDXF_functions.cpp @@ -570,12 +570,21 @@ void DXF_PLOTTER::Text( const wxPoint& aPos, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ) + bool aBold, + bool aMultilineAllowed ) { - if( textAsLines || containsNonAsciiChars( aText ) ) - /* output text as graphics */ + // Fix me: see how to use DXF text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + + if( textAsLines || containsNonAsciiChars( aText ) || aMultilineAllowed ) + { + // output text as graphics. + // Perhaps miltiline texts could be handled as DXF text entity + // but I do not want spend time about this (JPC) PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); + } else { /* Emit text as a text entity. This loses formatting and shape but it's diff --git a/common/common_plotPDF_functions.cpp b/common/common_plotPDF_functions.cpp index ec9cef66d3..7d75be97d4 100644 --- a/common/common_plotPDF_functions.cpp +++ b/common/common_plotPDF_functions.cpp @@ -741,10 +741,15 @@ void PDF_PLOTTER::Text( const wxPoint& aPos, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ) + bool aBold, + bool aMultilineAllowed ) { + // Fix me: see how to use PDF text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + // Emit native PDF text (if requested) - if( m_textMode != PLOTTEXTMODE_STROKE ) + if( m_textMode != PLOTTEXTMODE_STROKE && !aMultilineAllowed ) { const char *fontname = aItalic ? (aBold ? "/KicadFontBI" : "/KicadFontI") : (aBold ? "/KicadFontB" : "/KicadFont"); @@ -800,10 +805,10 @@ void PDF_PLOTTER::Text( const wxPoint& aPos, } // Plot the stroked text (if requested) - if( m_textMode != PLOTTEXTMODE_NATIVE ) + if( m_textMode != PLOTTEXTMODE_NATIVE || aMultilineAllowed ) { PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); } } diff --git a/common/common_plotPS_functions.cpp b/common/common_plotPS_functions.cpp index 9e1644485b..627f079088 100644 --- a/common/common_plotPS_functions.cpp +++ b/common/common_plotPS_functions.cpp @@ -812,27 +812,32 @@ bool PS_PLOTTER::EndPlot() -void PS_PLOTTER::Text( const wxPoint& aPos, - enum EDA_COLOR_T aColor, - const wxString& aText, - double aOrient, - const wxSize& aSize, - enum EDA_TEXT_HJUSTIFY_T aH_justify, - enum EDA_TEXT_VJUSTIFY_T aV_justify, - int aWidth, - bool aItalic, - bool aBold ) +void PS_PLOTTER::Text( const wxPoint& aPos, + enum EDA_COLOR_T aColor, + const wxString& aText, + double aOrient, + const wxSize& aSize, + enum EDA_TEXT_HJUSTIFY_T aH_justify, + enum EDA_TEXT_VJUSTIFY_T aV_justify, + int aWidth, + bool aItalic, + bool aBold, + bool aMultilineAllowed ) { SetCurrentLineWidth( aWidth ); SetColor( aColor ); + // Fix me: see how to use PS text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + // Draw the native postscript text (if requested) - if( m_textMode == PLOTTEXTMODE_NATIVE ) + if( m_textMode == PLOTTEXTMODE_NATIVE && !aMultilineAllowed ) { const char *fontname = aItalic ? (aBold ? "/KicadFont-BoldOblique" : "/KicadFont-Oblique") - : (aBold ? "/KicadFont-Bold" - : "/KicadFont"); + : (aBold ? "/KicadFont-Bold" + : "/KicadFont"); // Compute the copious tranformation parameters double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f; @@ -874,16 +879,16 @@ void PS_PLOTTER::Text( const wxPoint& aPos, if( m_textMode == PLOTTEXTMODE_PHANTOM ) { fputsPostscriptString( outputFile, aText ); - DPOINT pos_dev = userToDeviceCoordinates( aPos ); + DPOINT pos_dev = userToDeviceCoordinates( aPos ); fprintf( outputFile, " %g %g phantomshow\n", pos_dev.x, pos_dev.y ); } // Draw the stroked text (if requested) - if( m_textMode != PLOTTEXTMODE_NATIVE ) + if( m_textMode != PLOTTEXTMODE_NATIVE || aMultilineAllowed ) { PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); } } diff --git a/common/common_plotSVG_functions.cpp b/common/common_plotSVG_functions.cpp index b883107c84..e5d00a63e5 100644 --- a/common/common_plotSVG_functions.cpp +++ b/common/common_plotSVG_functions.cpp @@ -478,6 +478,15 @@ void SVG_PLOTTER::PenTo( const wxPoint& pos, char plume ) if( penState == 'Z' ) // here plume = 'D' or 'U' { DPOINT pos_dev = userToDeviceCoordinates( pos ); + + // Ensure we do not use a fill mode when moving tne pen, + // in SVG mode (i;e. we are plotting only basic lines, not a filled area + if( m_fillMode != NO_FILL ) + { + setFillMode( NO_FILL ); + setSVGPlotStyle(); + } + fprintf( outputFile, " -//#include #include #include #include #include -//#include #include #include diff --git a/include/plot_common.h b/include/plot_common.h index f59a2fbd82..3f0aee4e75 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -568,7 +568,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: virtual void emitSetRGBColor( double r, double g, double b ); }; @@ -633,7 +634,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos, double aScaleFactor ); @@ -702,7 +704,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: FILL_T m_fillMode; // true if the current contour @@ -904,7 +907,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: bool textAsLines; From 7b4b3297dbbee1fcfaa689883dec72f3b07cb4dd Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Wed, 30 Apr 2014 21:16:22 +0200 Subject: [PATCH 35/36] - Better way to iterate on vias in the track list (GetFirstVia) - Converted the Next/Prev C casts to static casts and removed the type unsafe ones - Splitted as virtual the VIA::Flip member instead of using RTTI - Heavily refactored the 'unconnected track' cleanup routine - Misc constification --- 3d-viewer/3d_draw.cpp | 32 +- eeschema/sch_screen.cpp | 2 +- eeschema/sch_sheet_path.cpp | 12 +- eeschema/sch_sheet_path.h | 14 +- gerbview/class_gbr_screen.h | 2 +- gerbview/class_gerber_draw_item.h | 4 +- include/base_struct.h | 4 +- include/class_board_item.h | 4 +- include/class_pcb_screen.h | 2 +- include/class_sch_screen.h | 2 +- include/sch_item_struct.h | 4 +- pcbnew/class_board.cpp | 17 +- pcbnew/class_drawsegment.h | 3 - pcbnew/class_edge_mod.h | 3 - pcbnew/class_mire.h | 3 - pcbnew/class_module.cpp | 7 +- pcbnew/class_module.h | 4 +- pcbnew/class_pad.h | 2 +- pcbnew/class_text_mod.h | 4 - pcbnew/class_track.cpp | 15 +- pcbnew/class_track.h | 18 +- pcbnew/clean.cpp | 316 +++++++----------- pcbnew/edgemod.cpp | 19 +- pcbnew/editrack.cpp | 4 +- pcbnew/exporters/export_gencad.cpp | 8 +- pcbnew/exporters/gendrill_Excellon_writer.cpp | 7 +- pcbnew/plot_brditems_plotter.cpp | 15 +- 27 files changed, 217 insertions(+), 310 deletions(-) diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 0a703179fa..289d3c3c72 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -274,7 +274,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() bool hightQualityMode = false; for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; - layer++ ) + ++layer ) { if( layer != LAST_COPPER_LAYER && layer >= g_Parm_3D_Visu.m_CopperLayersCount ) @@ -528,21 +528,19 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() } int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); - for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) - { - // Add via hole - if( track->Type() == PCB_VIA_T ) - { - const VIA *via = static_cast( track ); - VIATYPE_T viatype = via->GetViaType(); - int holediameter = via->GetDrillValue(); - int hole_outer_radius = (holediameter + thickness) / 2; - if( viatype == VIA_THROUGH ) - TransformCircleToPolygon( allLayerHoles, - via->GetStart(), hole_outer_radius, - segcountLowQuality ); - } + // Add via holes + for( VIA* via = GetFirstVia( pcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) + { + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); + int hole_outer_radius = (holediameter + thickness) / 2; + + if( viatype == VIA_THROUGH ) + TransformCircleToPolygon( allLayerHoles, + via->GetStart(), hole_outer_radius, + segcountLowQuality ); } // draw pads holes @@ -562,7 +560,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() allLayerHoles.ExportTo( brdpolysetHoles ); for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER; layer <= LAST_NON_COPPER_LAYER; - layer++ ) + ++layer ) { // Skip user layers, which are not drawn here if( IsUserLayer( layer) ) @@ -713,7 +711,7 @@ void EDA_3D_CANVAS::BuildBoard3DAuxLayers() bufferPolys.reserve( 5000 ); // Reserve for items not on board for( LAYER_NUM layer = FIRST_USER_LAYER; layer <= LAST_USER_LAYER; - layer++ ) + ++layer ) { if( !Is3DLayerEnabled( layer ) ) continue; diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 86a8ed9727..9a7d2a5390 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1345,7 +1345,7 @@ SCH_SCREEN* SCH_SCREENS::GetNext() } -SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) +SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const { if( aIndex < m_screens.size() ) return m_screens[ aIndex ]; diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 23ef5272c3..230ea77fe3 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -112,7 +112,7 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const } -SCH_SHEET* SCH_SHEET_PATH::Last() +SCH_SHEET* SCH_SHEET_PATH::Last() const { if( m_numSheets ) return m_sheets[m_numSheets - 1]; @@ -121,7 +121,7 @@ SCH_SHEET* SCH_SHEET_PATH::Last() } -SCH_SCREEN* SCH_SHEET_PATH::LastScreen() +SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const { SCH_SHEET* lastSheet = Last(); @@ -132,7 +132,7 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() } -SCH_ITEM* SCH_SHEET_PATH::LastDrawList() +SCH_ITEM* SCH_SHEET_PATH::LastDrawList() const { SCH_SHEET* lastSheet = Last(); @@ -143,7 +143,7 @@ SCH_ITEM* SCH_SHEET_PATH::LastDrawList() } -SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() +SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const { SCH_ITEM* item = NULL; @@ -316,7 +316,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu } -SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; @@ -349,7 +349,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool } -SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index dcfe9b690a..f6a32fbeb9 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -129,20 +129,20 @@ public: * returns a pointer to the last sheet of the list * One can see the others sheet as the "path" to reach this last sheet */ - SCH_SHEET* Last(); + SCH_SHEET* Last() const; /** * Function LastScreen * @return the SCH_SCREEN relative to the last sheet in list */ - SCH_SCREEN* LastScreen(); + SCH_SCREEN* LastScreen() const; /** * Function LastDrawList * @return a pointer to the first schematic item handled by the * SCH_SCREEN relative to the last sheet in list */ - SCH_ITEM* LastDrawList(); + SCH_ITEM* LastDrawList() const; /** * Get the last schematic item relative to the first sheet in the list. @@ -150,7 +150,7 @@ public: * @return Last schematic item relative to the first sheet in the list if list * is not empty. Otherwise NULL. */ - SCH_ITEM* FirstDrawList(); + SCH_ITEM* FirstDrawList() const; /** * Function Push @@ -248,7 +248,7 @@ public: * is defined. * @return - The next schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; /** * Find the previous schematic item in this sheet path object. @@ -260,7 +260,7 @@ public: * is defined. * @return - The previous schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 ); @@ -318,7 +318,7 @@ public: * @return the number of sheets in list: * usually the number of sheets found in the whole hierarchy */ - int GetCount() { return m_count; } + int GetCount() const { return m_count; } /** * Function GetFirst diff --git a/gerbview/class_gbr_screen.h b/gerbview/class_gbr_screen.h index 8be96b21d5..9e89373e53 100644 --- a/gerbview/class_gbr_screen.h +++ b/gerbview/class_gbr_screen.h @@ -26,7 +26,7 @@ public: ~GBR_SCREEN(); - GBR_SCREEN* Next() { return (GBR_SCREEN*) Pnext; } + GBR_SCREEN* Next() const { return static_cast( Pnext ); } // void SetNextZoom(); // void SetPreviousZoom(); diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index 2989333c0a..70ad0a1164 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -116,8 +116,8 @@ public: */ GERBER_DRAW_ITEM* Copy() const; - GERBER_DRAW_ITEM* Next() const { return (GERBER_DRAW_ITEM*) Pnext; } - GERBER_DRAW_ITEM* Back() const { return (GERBER_DRAW_ITEM*) Pback; } + GERBER_DRAW_ITEM* Next() const { return static_cast( Pnext ); } + GERBER_DRAW_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/include/base_struct.h b/include/base_struct.h index 8679cfdd5b..9ec7af03c8 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -375,8 +375,8 @@ public: void SetTimeStamp( time_t aNewTimeStamp ) { m_TimeStamp = aNewTimeStamp; } time_t GetTimeStamp() const { return m_TimeStamp; } - EDA_ITEM* Next() const { return (EDA_ITEM*) Pnext; } - EDA_ITEM* Back() const { return (EDA_ITEM*) Pback; } + EDA_ITEM* Next() const { return Pnext; } + EDA_ITEM* Back() const { return Pback; } EDA_ITEM* GetParent() const { return m_Parent; } DHEAD* GetList() const { return m_List; } diff --git a/include/class_board_item.h b/include/class_board_item.h index ceb428af5e..26a30af896 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -108,8 +108,8 @@ public: */ static wxPoint ZeroOffset; - BOARD_ITEM* Next() const { return (BOARD_ITEM*) Pnext; } - BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; } + BOARD_ITEM* Next() const { return static_cast( Pnext ); } + BOARD_ITEM* Back() const { return static_cast( Pback ); } BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; } /** diff --git a/include/class_pcb_screen.h b/include/class_pcb_screen.h index e15082be40..59f3f3d592 100644 --- a/include/class_pcb_screen.h +++ b/include/class_pcb_screen.h @@ -31,7 +31,7 @@ public: ~PCB_SCREEN(); - PCB_SCREEN* Next() { return (PCB_SCREEN*) Pnext; } + PCB_SCREEN* Next() const { return static_cast( Pnext ); } void SetNextZoom(); void SetPreviousZoom(); diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index 02a6787679..acf8f20819 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -523,7 +523,7 @@ public: int GetCount() const { return m_screens.size(); } SCH_SCREEN* GetFirst(); SCH_SCREEN* GetNext(); - SCH_SCREEN* GetScreen( unsigned int aIndex ); + SCH_SCREEN* GetScreen( unsigned int aIndex ) const; /** * Function ClearAnnotation diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index e425e1d6b1..5fe90cd69f 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -136,8 +136,8 @@ public: */ virtual void SwapData( SCH_ITEM* aItem ); - SCH_ITEM* Next() { return (SCH_ITEM*) Pnext; } - SCH_ITEM* Back() { return (SCH_ITEM*) Pback; } + SCH_ITEM* Next() const { return static_cast( Pnext ); } + SCH_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 2960e9e315..a7b4e35987 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1563,19 +1563,12 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) const { - for( TRACK *track = m_Track; track; track = track->Next() ) + for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - if( track->GetStart() != aPosition ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) ) - return static_cast( track ); + if( (via->GetStart() == aPosition) && + (via->GetState( BUSY | IS_DELETED ) == 0) && + ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) ) + return via; } return NULL; diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 635a3235d7..64ce5dcb8c 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -68,9 +68,6 @@ public: /// skip the linked list stuff, and parent const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs ); - DRAWSEGMENT* Next() const { return (DRAWSEGMENT*) Pnext; } - DRAWSEGMENT* Back() const { return (DRAWSEGMENT*) Pback; } - void SetWidth( int aWidth ) { m_Width = aWidth; } int GetWidth() const { return m_Width; } diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 8c6559ad74..18790d9b9b 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -51,9 +51,6 @@ public: ~EDGE_MODULE(); - EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; } - EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; } - /// skip the linked list stuff, and parent const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs ); diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index da42a07fb0..0a7186b6b1 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -56,9 +56,6 @@ public: ~PCB_TARGET(); - PCB_TARGET* Next() const { return (PCB_TARGET*) Pnext; } - PCB_TARGET* Back() const { return (PCB_TARGET*) Pnext; } - void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override const wxPoint& GetPosition() const { return m_Pos; } // override diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 26527c095a..ca343a6333 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -422,9 +422,12 @@ EDA_RECT MODULE::GetFootprintRect() const area.SetEnd( m_Pos ); area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area - for( EDGE_MODULE* edge = (EDGE_MODULE*) m_Drawings.GetFirst(); edge; edge = edge->Next() ) - if( edge->Type() == PCB_MODULE_EDGE_T ) + for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() ) + { + const EDGE_MODULE *edge = dynamic_cast( item ); + if( edge ) area.Merge( edge->GetBoundingBox() ); + } for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) area.Merge( pad->GetBoundingBox() ); diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 3127d73fb1..189abfe6be 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -77,8 +77,8 @@ public: ~MODULE(); - MODULE* Next() const { return (MODULE*) Pnext; } - MODULE* Back() const { return (MODULE*) Pback; } + MODULE* Next() const { return static_cast( Pnext ); } + MODULE* Back() const { return static_cast( Pback ); } void Copy( MODULE* Module ); // Copy structure diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 11b49568c1..3cbdcbe82a 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -106,7 +106,7 @@ public: void Copy( D_PAD* source ); - D_PAD* Next() const { return (D_PAD*) Pnext; } + D_PAD* Next() const { return static_cast( Pnext ); } MODULE* GetParent() const { return (MODULE*) m_Parent; } diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 97e15ab202..bc207e7254 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -98,10 +98,6 @@ public: void Flip( const wxPoint& aCentre ); - TEXTE_MODULE* Next() const { return (TEXTE_MODULE*) Pnext; } - - TEXTE_MODULE* Back() const { return (TEXTE_MODULE*) Pback; } - /// @deprecated it seems (but the type is used to 'protect' //reference and value from deletion, and for identification) void SetType( TEXT_TYPE aType ) { m_Type = aType; } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index abf4d7a732..8b454c9610 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -88,12 +88,9 @@ inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist ) } -TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, +TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - if( aStartTrace == NULL ) - return NULL; - for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) { if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) @@ -180,7 +177,6 @@ VIA::VIA( BOARD_ITEM* aParent ) : { SetViaType( VIA_THROUGH ); m_BottomLayer = LAYER_N_BACK; - m_Width = Millimeter2iu( 0.5 ); SetDrillDefault(); } @@ -369,9 +365,14 @@ void TRACK::Flip( const wxPoint& aCentre ) { m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y); + SetLayer( FlipLayer( GetLayer() ) ); +} - if( Type() != PCB_VIA_T ) - SetLayer( FlipLayer( GetLayer() ) ); + +void VIA::Flip( const wxPoint& aCentre ) +{ + m_Start.y = aCentre.y - (m_Start.y - aCentre.y); + m_End.y = aCentre.y - (m_End.y - aCentre.y); } diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 63c9026967..0417048fa3 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -74,7 +74,7 @@ enum VIATYPE_T * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ -extern TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, +extern TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); class TRACK : public BOARD_CONNECTED_ITEM @@ -100,8 +100,8 @@ public: // Do not create a copy constructor. The one generated by the compiler is adequate. - TRACK* Next() const { return (TRACK*) Pnext; } - TRACK* Back() const { return (TRACK*) Pback; } + TRACK* Next() const { return static_cast( Pnext ); } + TRACK* Back() const { return static_cast( Pback ); } virtual void Move( const wxPoint& aMoveVector ) { @@ -350,7 +350,7 @@ public: } - SEGZONE* Next() const { return (SEGZONE*) Pnext; } + SEGZONE* Next() const { return static_cast( Pnext ); } wxString GetSelectMenuText() const; @@ -415,6 +415,8 @@ public: /// @copydoc VIEW_ITEM::ViewGetLayers() virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + virtual void Flip( const wxPoint& aCentre ); + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif @@ -469,5 +471,13 @@ private: int m_Drill; // for vias: via drill (- 1 for default value) }; +/// Scan a track list for the first VIA o NULL if not found (or NULL passed) +inline VIA *GetFirstVia( TRACK *aTrk, const TRACK *aStopPoint = NULL ) +{ + while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) ) + aTrk = aTrk->Next(); + + return static_cast( aTrk ); +} #endif /* CLASS_TRACK_H */ diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 4bcfb5127e..127f0cbae5 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -87,6 +87,11 @@ private: */ TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, ENDPOINT_T aEndType ); + + const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ); + + bool testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -101,7 +106,7 @@ void PCB_EDIT_FRAME::Clean_Pcb() wxBusyCursor( dummy ); TRACKS_CLEANER cleaner( GetBoard() ); - cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, + cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm ); m_canvas->Refresh( true ); } @@ -134,8 +139,6 @@ bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame, if( modified ) { // Clear undo and redo lists to avoid inconsistencies between lists - // XXX This is very involved... maybe a member in PCB_EDIT_FRAME - // would be better? aFrame->GetScreen()->ClearUndoRedoList(); aFrame->SetCurItem( NULL ); aFrame->Compile_Ratsnest( NULL, true ); @@ -158,7 +161,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() BuildTracksCandidatesList( m_Brd->m_Track, NULL); // clear flags and variables used in cleanup - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { track->start = NULL; track->end = NULL; @@ -168,7 +171,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() // Build connections info tracks to pads SearchTracksConnectedToPads(); - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { // Mark track if connected to pads for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) @@ -194,70 +197,50 @@ bool TRACKS_CLEANER::clean_vias() { bool modified = false; - for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - // Correct via m_End defects (if any) - if( track->Type() == PCB_VIA_T ) + // Correct via m_End defects (if any), should never happen + if( via->GetStart() != via->GetEnd() ) { - if( track->GetStart() != track->GetEnd() ) - track->SetEnd( track->GetStart() ); - - VIA *via = static_cast( track ); - /* Important: this cleanup only does thru hole vias, it doesn't - * (yet) handle high density interconnects */ - if( via->GetViaType() != VIA_THROUGH ) - continue; + wxFAIL_MSG( "Via with mismatching ends" ); + via->SetEnd( via->GetStart() ); } - else - continue; - // Search and delete others vias at same location - TRACK* alt_track = track->Next(); - - TRACK* next_track; - for( ; alt_track != NULL; alt_track = next_track ) + /* Important: these cleanups only do thru hole vias, they don't + * (yet) handle high density interconnects */ + if( via->GetViaType() != VIA_THROUGH ) { - next_track = alt_track->Next(); - VIA *alt_via = dynamic_cast( alt_track ); - if( alt_via ) + // Search and delete others vias at same location + VIA* next_via; + for( VIA* alt_via = GetFirstVia( via->Next() ); alt_via != NULL; + alt_via = next_via ) { - if( alt_via->GetViaType() != VIA_THROUGH ) - continue; + next_via = GetFirstVia( alt_via->Next() ); - if( alt_via->GetStart() != track->GetStart() ) - continue; - - // delete via - alt_track->UnLink(); - delete alt_track; - modified = true; + if( (alt_via->GetViaType() == VIA_THROUGH) && + (alt_via->GetStart() == via->GetStart()) ) + { + // delete via + alt_via->DeleteStructure(); + modified = true; + } } - } - } - // Delete Via on pads at same location - TRACK* next_track; - for( TRACK* track = m_Brd->m_Track; track != NULL; track = next_track ) - { - next_track = track->Next(); - - VIA *via = dynamic_cast( track ); - if( !via || (via->GetViaType() != VIA_THROUGH )) - continue; - - // Examine the list of connected pads: - // if one pad through is found, the via can be removed - for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) - { - D_PAD * pad = track->m_PadsConnected[ii]; - - if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + /* To delete through Via on THT pads at same location + * Examine the list of connected pads: + * if one through pad is found, the via can be removed */ + for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii ) { - // redundant: via delete it - track->UnLink(); - delete track; - modified = true; - break; + const D_PAD *pad = via->m_PadsConnected[ii]; + + if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + { + // redundant: delete the via + via->DeleteStructure(); + modified = true; + break; + } } } } @@ -265,6 +248,64 @@ bool TRACKS_CLEANER::clean_vias() return modified; } +/// Utility for checking if a track/via ends on a zone +const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ) +{ + // Vias are special cased, since they get a layer range, not a single one + LAYER_NUM top_layer, bottom_layer; + const VIA *via = dynamic_cast( aTrack ); + + if( via ) + via->LayerPair( &top_layer, &bottom_layer ); + else + { + top_layer = aTrack->GetLayer(); + bottom_layer = top_layer; + } + return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ), + top_layer, bottom_layer, aTrack->GetNetCode() ); +} + +/** Utility: does the endpoint unconnected processed for one endpoint of one track + * Returns true if the track must be deleted, false if not necessarily */ +bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ) +{ + bool flag_erase = false; + + TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + if( (other == NULL) && + (zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) ) + flag_erase = true; // Start endpoint is neither on pad, zone or other track + else // segment, via or zone connected to this end + { + // Fill connectivity informations + if( aEndPoint == ENDPOINT_START ) + aTrack->start = other; + else + aTrack->end = other; + + /* If a via is connected to this end, test if this via has a second item connected. + * If not, remove the current segment (the via would then become + * unconnected and remove on the following pass) */ + VIA* via = dynamic_cast( other ); + if( via ) + { + // search for another segment following the via + aTrack->SetState( BUSY, true ); + + other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + + // There is a via on the start but it goes nowhere + if( (other == NULL) && + (zoneForTrackEndpoint( via, aEndPoint ) == NULL) ) + flag_erase = true; + + aTrack->SetState( BUSY, false ); + } + } + return flag_erase; +} /* * Delete dangling tracks @@ -277,161 +318,44 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() return false; bool modified = false; - bool item_erased = true; - while( item_erased ) // Iterate when at least one track is deleted + bool item_erased; + do // Iterate when at least one track is deleted { item_erased = false; TRACK* next_track; - for( TRACK * track = m_Brd->m_Track; track ; track = next_track ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track ) { next_track = track->Next(); - int flag_erase = 0; //Not connected indicator - int type_end = 0; + bool flag_erase = false; // Start without a good reason to erase it - if( track->GetState( START_ON_PAD ) ) - type_end |= START_ON_PAD; + /* if a track endpoint is not connected to a pad, test if + * the endpoint is connected to another track or to a zone. + * For via test, an enhancement could be to test if + * connected to 2 items on different layers. Currently + * a via must be connected to 2 items, that can be on the + * same layer */ - if( track->GetState( END_ON_PAD ) ) - type_end |= END_ON_PAD; + // Check if there is nothing attached on the start + if( !(track->GetState( START_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START ); - // if the track start point is not connected to a pad, - // test if this track start point is connected to another track - // For via test, an enhancement could be to test if connected - // to 2 items on different layers. - // Currently a via must be connected to 2 items, that can be on the same layer - LAYER_NUM top_layer, bottom_layer; - ZONE_CONTAINER* zone; - - if( (type_end & START_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 1; - } - else // segment, via or zone connected to this end - { - track->start = other; - // If a via is connected to this end, - // test if this via has a second item connected. - // If no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - track->SetState( BUSY, true ); - - VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(), - bottom_layer, - top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 2; - - track->SetState( BUSY, false ); - } - } - } - - // if track end point is not connected to a pad, - // test if this track end point is connected to an other track - if( (type_end & END_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if ( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 0x10; - } - else // segment, via or zone connected to this end - { - track->end = other; - - // If a via is connected to this end, test if this via has a second item connected - // if no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - - track->SetState( BUSY, true ); - - VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(), - bottom_layer, top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 0x20; - - track->SetState( BUSY, false ); - } - } - } + // Check if there is nothing attached on the end + if( !(track->GetState( END_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END ); if( flag_erase ) { // remove segment from board track->DeleteStructure(); - // iterate, because a track connected to the deleted track - // is now perhaps now not connected and should be deleted + + /* keep iterating, because a track connected to the deleted track + * now perhaps is not connected and should be deleted */ item_erased = true; modified = true; } } - } + } while( item_erased ); return modified; } diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp index 7239dc37a8..77019494f2 100644 --- a/pcbnew/edgemod.cpp +++ b/pcbnew/edgemod.cpp @@ -169,12 +169,11 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge ) { aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems(); item; item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; - - aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); + aEdge = dynamic_cast( item ); + if( aEdge ) + aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); } } else @@ -216,14 +215,12 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge ) if( aEdge == NULL ) { - aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems() ; item != NULL; + item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; + aEdge = dynamic_cast( item ); - if( aEdge->GetLayer() != new_layer ) + if( aEdge && (aEdge->GetLayer() != new_layer) ) { if( ! modified ) // save only once SaveCopyInUndoList( module, UR_MODEDIT ); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 683b7d41d7..220668148c 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -62,9 +62,9 @@ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent(); BOARD* pcb = frame->GetBoard(); - TRACK* track = (TRACK*) frame->GetCurItem(); + TRACK* track = dynamic_cast( frame->GetCurItem() ); - if( track && ( track->Type()==PCB_VIA_T || track->Type()==PCB_TRACE_T ) ) + if( track ) { // Erase the current drawing ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false ); diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 601c91ae6d..c1895cbc7b 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -271,12 +271,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) } // The same for vias - for( TRACK* track = aPcb->m_Track; track != NULL; track = track->Next() ) + for( VIA* via = GetFirstVia( aPcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() == PCB_VIA_T ) - { - vias.push_back( static_cast(track) ); - } + vias.push_back( via ); } qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort ); diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index a8a086187a..679df5bed1 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -453,12 +453,9 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, // build hole list for vias if( ! aGenerateNPTH_list ) // vias are always plated ! { - for( TRACK* track = m_pcb->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - const VIA* via = (const VIA*) track; hole_value = via->GetDrillValue(); if( hole_value == 0 ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 1535b3593f..8494eb560b 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -148,10 +148,11 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) PlotTextModule( &aModule->Value(), GetValueColor() ); } - for( textModule = (TEXTE_MODULE*) aModule->GraphicalItems().GetFirst(); - textModule != NULL; textModule = textModule->Next() ) + for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst(); + item != NULL; item = item->Next() ) { - if( textModule->Type() != PCB_MODULE_TEXT_T ) + textModule = dynamic_cast( item ); + if( !textModule ) continue; if( !GetPlotOtherText() ) @@ -350,13 +351,11 @@ void BRDITEMS_PLOTTER::Plot_Edges_Modules() { for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { - for( EDGE_MODULE* edge = (EDGE_MODULE*) module->GraphicalItems().GetFirst(); - edge; edge = edge->Next() ) + for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() ) { - if( edge->Type() != PCB_MODULE_EDGE_T ) - continue; + EDGE_MODULE *edge = dynamic_cast( item ); - if( ( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0 ) + if( !edge || (( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0) ) continue; Plot_1_EdgeModule( edge ); From fca1ba6755120c27ee353c7879ccc0931ee451f7 Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Thu, 1 May 2014 08:50:11 +0200 Subject: [PATCH 36/36] Virtual split of TRACK/VIA::HitTest --- pcbnew/class_track.cpp | 92 +++++++++++++++++------------------------- pcbnew/class_track.h | 12 +++++- 2 files changed, 47 insertions(+), 57 deletions(-) diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 8b454c9610..2dd626a5c8 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1233,64 +1233,56 @@ void VIA::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) bool TRACK::HitTest( const wxPoint& aPosition ) { - int max_dist = m_Width >> 1; + return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ); +} - if( Type() == PCB_VIA_T ) - { - // rel_pos is aPosition relative to m_Start (or the center of the via) - wxPoint rel_pos = aPosition - m_Start; - double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y; - return dist <= (double) max_dist * max_dist; - } +bool VIA::HitTest( const wxPoint& aPosition ) +{ + int max_dist = m_Width / 2; - return TestSegmentHit( aPosition, m_Start, m_End, max_dist ); + // rel_pos is aPosition relative to m_Start (or the center of the via) + wxPoint rel_pos = aPosition - m_Start; + double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y; + return dist <= (double) max_dist * max_dist; } bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + EDA_RECT arect = aRect; + arect.Inflate( aAccuracy ); + + if( aContained ) + /* Tracks are a special case: + * they are considered inside the rect if one end is inside the rect */ + return arect.Contains( GetStart() ) || arect.Contains( GetEnd() ); + else + return arect.Intersects( GetStart(), GetEnd() ); +} + +bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT box; EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); - if( Type() == PCB_VIA_T ) - { - box.SetOrigin( GetStart() ); - box.Inflate( GetWidth() >> 1 ); + box.SetOrigin( GetStart() ); + box.Inflate( GetWidth() / 2 ); - if(aContained) - return arect.Contains( box ); - else - return arect.Intersects( box ); - } + if( aContained ) + return arect.Contains( box ); else - { - if( aContained ) - // Tracks are a specila case: - // they are considered inside the rect if one end - // is inside the rect - return arect.Contains( GetStart() ) || arect.Contains( GetEnd() ); - else - return arect.Intersects( GetStart(), GetEnd() ); - } + return arect.Intersects( box ); } - VIA* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) { - for( TRACK *track = this; track; track = track->Next() ) + for( VIA *via = GetFirstVia( this ); via; via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - if( !track->HitTest( aPosition ) ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) ) - return static_cast( track ); + if( via->HitTest( aPosition ) && + !via->GetState( BUSY | IS_DELETED ) && + ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) ) + return via; } return NULL; @@ -1299,22 +1291,12 @@ VIA* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - for( TRACK *trace = this; trace; trace = trace->Next() ) + for( VIA *via = GetFirstVia( this, aEndTrace ); via; via = GetFirstVia( via->Next() ) ) { - if( trace->Type() == PCB_VIA_T ) - { - if( aPosition == trace->m_Start ) - { - if( trace->GetState( BUSY | IS_DELETED ) == 0 ) - { - if( aLayerMask & trace->GetLayerMask() ) - return static_cast( trace ); - } - } - } - - if( trace == aEndTrace ) - break; + if( via->HitTest( aPosition ) && + !via->GetState( BUSY | IS_DELETED ) && + (aLayerMask & via->GetLayerMask()) ) + return via; } return NULL; diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 0417048fa3..9afc346788 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -228,7 +228,7 @@ public: /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const */ - bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; + virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; /** * Function GetVia @@ -401,6 +401,10 @@ public: const wxPoint& GetPosition() const { return m_Start; } // was overload void SetPosition( const wxPoint& aPoint ) { m_Start = aPoint; m_End = aPoint; } // was overload + virtual bool HitTest( const wxPoint& aPosition ); + + virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; + wxString GetClass() const { return wxT( "VIA" ); @@ -477,7 +481,11 @@ inline VIA *GetFirstVia( TRACK *aTrk, const TRACK *aStopPoint = NULL ) while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) ) aTrk = aTrk->Next(); - return static_cast( aTrk ); + // It could stop because of the stop point, not on a via + if( aTrk && (aTrk->Type() == PCB_VIA_T) ) + return static_cast( aTrk ); + else + return NULL; } #endif /* CLASS_TRACK_H */