diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 8f05616062..382c9c9164 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -157,7 +157,7 @@ bool EDA_BASE_FRAME::Enable( bool enable ) #if defined(DEBUG) const char* type_id = typeid( *this ).name(); - printf( "wxFrame %s: %s\n", type_id, enable ? "enabled" : "disabled" ); + printf( "wxFrame %-28s: %s\n", type_id, enable ? "enabled" : "disabled" ); #endif return wxFrame::Enable( enable ); diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index f8236c1ac6..1d3e9b6054 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -244,8 +244,12 @@ int DIALOG_SHIM::ShowQuasiModal() if( win ) win->ReleaseMouse(); + // Get the optimal parent wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() ); + // Show the optimal parent + DBG( if( parent ) printf( "%s: optimal parent: %s\n", __func__, typeid(*parent).name() );) + ENABLE_DISABLE toggle( parent ); // quasi-modal: disable only my "optimal" parent Show( true ); diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index f69ccd2ea5..2b5a47aa9c 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -137,6 +137,12 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) : } +FP_LIB_TABLE::~FP_LIB_TABLE() +{ + // *fallBack is not owned here. +} + + wxArrayString FP_LIB_TABLE::FootprintEnumerate( const wxString& aNickname ) { const ROW* row = FindRow( aNickname ); @@ -514,9 +520,16 @@ std::vector FP_LIB_TABLE::GetLogicalLibs() } while( ( cur = cur->fallBack ) != 0 ); + ret.reserve( unique.size() ); + + // DBG(printf( "%s: count:%zd\n", __func__, unique.size() );) + // return a sorted, unique set of nicknames in a std::vector to caller for( std::set::const_iterator it = unique.begin(); it!=unique.end(); ++it ) + { + //DBG(printf( " %s\n", TO_UTF8( *it ) );) ret.push_back( *it ); + } return ret; } @@ -738,7 +751,7 @@ wxString FP_LIB_TABLE::GetGlobalTableFileName() void FP_LIB_TABLE::Load( const wxString& aFileName ) throw( IO_ERROR ) { - // Empty footprint library tables are valid. + // It's OK if footprint library tables are missing. if( wxFileName::IsFileReadable( aFileName ) ) { FILE_LINE_READER reader( aFileName ); diff --git a/common/kiway.cpp b/common/kiway.cpp index 8f2ebf9824..396c5cb417 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -53,7 +53,7 @@ KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ): // Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are -// propogated upwards to parent windows if not handled below. Therefor the +// propogated upwards to parent windows if not handled below. Therefore the // m_top window should receive all wxWindowDestroyEvents originating from // KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops // on that event stream looking for KIWAY_PLAYERs being closed. @@ -67,10 +67,14 @@ void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event ) // if destroying one of our flock, then mark it as deceased. if( (wxWindow*) m_player[i] == w ) { - DBG(printf( "%s: marking m_player[%d] as destroyed\n", __func__, i );) + DBG(printf( "%s: m_player[%d] destroyed: %s\n", + __func__, i, TO_UTF8( m_player[i]->GetName() ) );) + m_player[i] = 0; } } + + // event.Skip(); skip to who, the wxApp? I'm the top window. } diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index ab0ae3e571..fda3962d2d 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -45,7 +45,7 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), KIWAY_HOLDER( aKiway ), m_modal( false ), - m_modal_loop( 0 ) + m_modal_loop( 0 ), m_modal_resultant_parent( 0 ) { // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) } @@ -57,7 +57,7 @@ KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& a EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), KIWAY_HOLDER( 0 ), m_modal( false ), - m_modal_loop( 0 ) + m_modal_loop( 0 ), m_modal_resultant_parent( 0 ) { // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) } @@ -72,7 +72,7 @@ void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) } -bool KIWAY_PLAYER::ShowModal( wxString* aResult ) +bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow ) { wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) ); @@ -94,24 +94,31 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction } clear_this( (void*&) m_modal_loop ); - // exception safe way to disable all frames except the modal one, - // re-enables only those that were disabled on exit - wxWindowDisabler toggle( this ); + m_modal_resultant_parent = aResultantFocusWindow; Show( true ); + SetFocus(); - WX_EVENT_LOOP event_loop; + { + // exception safe way to disable all frames except the modal one, + // re-enables only those that were disabled on exit + wxWindowDisabler toggle( this ); + + WX_EVENT_LOOP event_loop; #if wxCHECK_VERSION( 2, 9, 4 ) // 2.9.4 is only approximate. - // new code needs this, old code does it in wxEventLoop::Run() and cannot - // tolerate it here. Where that boundary is as a version number, I don't know. - // A closer look at the subversion repo for wx would tell. - wxEventLoopActivator event_loop_stacker( &event_loop ); + // new code needs this, old code does it in wxEventLoop::Run() and cannot + // tolerate it here. Where that boundary is as a version number, I don't know. + // A closer look at the subversion repo for wx would tell. + wxEventLoopActivator event_loop_stacker( &event_loop ); #endif - m_modal_loop = &event_loop; + m_modal_loop = &event_loop; - event_loop.Run(); + event_loop.Run(); + + } // End of scop for some variables. + // End nesting before setting focus below. if( aResult ) *aResult = m_modal_string; @@ -119,9 +126,29 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) DBG(printf( "~%s: aResult:'%s' ret:%d\n", __func__, TO_UTF8( m_modal_string ), m_modal_ret_val );) + if( aResultantFocusWindow ) + { + aResultantFocusWindow->Raise(); + + // have the final say, after wxWindowDisabler reenables my parent and + // the events settle down, set the focus + wxYield(); + aResultantFocusWindow->SetFocus(); + } + return m_modal_ret_val; } +bool KIWAY_PLAYER::Destroy() +{ + // Needed on Windows to leave the modal parent on top with focus +#ifdef __WINDOWS__ + if( m_modal_resultant_parent && GetParent() != m_modal_resultant_parent ) + Reparent( m_modal_resultant_parent ); +#endif + + return EDA_BASE_FRAME::Destroy(); +} bool KIWAY_PLAYER::IsDismissed() { diff --git a/common/project.cpp b/common/project.cpp index df31c81c1b..2e10d8a661 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -42,15 +42,22 @@ PROJECT::PROJECT() memset( m_elems, 0, sizeof(m_elems) ); } + +void PROJECT::ElemsClear() +{ + // careful here, this should work, but the virtual destructor may not + // be in the same link image as PROJECT. + for( unsigned i = 0; iClear(); - - /* this is done by ConfigLoad(), and that sets the env var too. - prj.SetProjectFullName( fn.GetFullPath() ); - */ - - wxString projectFpLibTableFileName = prj.FootprintLibTblName(); - - try - { - FootprintLibs()->Load( projectFpLibTableFileName ); - } - catch( const IO_ERROR& ioe ) - { - DisplayError( this, ioe.errorText ); - } + // Force it to be loaded on demand. + prj.ElemClear( PROJECT::ELEM_FPTBL ); } diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index 33abb79fc4..7b8b836f6f 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -488,7 +488,8 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName ) wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ), fpname.c_str(), nickname.c_str() ); - footprint = FootprintLibs()->FootprintLoad( FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) ); + footprint = Prj().PcbFootprintLibs()->FootprintLoad( + FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) ); } catch( const IO_ERROR& ioe ) { diff --git a/cvpcb/class_library_listbox.cpp b/cvpcb/class_library_listbox.cpp index db86776145..4149f285ca 100644 --- a/cvpcb/class_library_listbox.cpp +++ b/cvpcb/class_library_listbox.cpp @@ -128,7 +128,7 @@ void LIBRARY_LISTBOX::SetLibraryList( const wxArrayString& aList ) { RefreshItems( 0L, m_libraryList.Count()-1 ); -#if defined (__WXGTK__ ) // && wxMINOR_VERSION == 8 +#if defined (__WXGTK__ ) && wxMINOR_VERSION == 8 // @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the // column parameter is -1. This was the only way to prevent GTK3 from // ellipsizing long strings down to a few characters. It still doesn't set diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 3ffd306b7d..7079e40287 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -200,24 +200,6 @@ CVPCB_MAINFRAME::~CVPCB_MAINFRAME() } -FP_LIB_TABLE* CVPCB_MAINFRAME::FootprintLibs() const -{ - PROJECT& prj = Prj(); - FP_LIB_TABLE* tbl = dynamic_cast( prj.Elem( PROJECT::FPTBL ) ); - - if( !tbl ) - { - // Stack the project specific FP_LIB_TABLE overlay on top of the global table. - // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may - // stack this way, all using the same global fallback table. - tbl = new FP_LIB_TABLE( &GFootprintTable ); - prj.Elem( PROJECT::FPTBL, tbl ); - } - - return tbl; -} - - void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg ) { EDA_BASE_FRAME::LoadSettings( aCfg ); @@ -493,7 +475,7 @@ void CVPCB_MAINFRAME::ConfigCvpcb( wxCommandEvent& event ) void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) { bool tableChanged = false; - int r = InvokePcbLibTableEditor( this, &GFootprintTable, FootprintLibs() ); + int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() ); if( r & 1 ) { @@ -521,7 +503,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) try { - FootprintLibs()->Save( fileName ); + Prj().PcbFootprintLibs()->Save( fileName ); tableChanged = true; } catch( const IO_ERROR& ioe ) @@ -538,7 +520,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) if( tableChanged ) { BuildLIBRARY_LISTBOX(); - m_footprints.ReadFootprintFiles( FootprintLibs() ); + m_footprints.ReadFootprintFiles( Prj().PcbFootprintLibs() ); } } @@ -735,7 +717,7 @@ void CVPCB_MAINFRAME::DisplayStatus() bool CVPCB_MAINFRAME::LoadFootprintFiles() { - FP_LIB_TABLE* fptbl = FootprintLibs(); + FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); // Check if there are footprint libraries in the footprint library table. if( !fptbl || !fptbl->GetLogicalLibs().size() ) @@ -1012,11 +994,13 @@ void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX() wxFONTWEIGHT_NORMAL ) ); } - if( FootprintLibs() ) + FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); + + if( tbl ) { wxArrayString libNames; - std::vector< wxString > libNickNames = FootprintLibs()->GetLogicalLibs(); + std::vector< wxString > libNickNames = tbl->GetLogicalLibs(); for( unsigned ii = 0; ii < libNickNames.size(); ii++ ) libNames.Add( libNickNames[ii] ); diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index 3993091dda..7b136746a9 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -88,12 +88,6 @@ public: bool OpenProjectFiles( const std::vector& aFileSet, int aCtl=0 ); // overload KIWAY_PLAYER - /** - * Function FootprintLibs - * @return the project #FP_LIB_TABLE. - */ - FP_LIB_TABLE* FootprintLibs() const; - /** * @return a pointer on the Footprint Viewer frame, if exists, or NULL */ diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index 538fe34841..939abc7acb 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -119,346 +119,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName ) } -#if 0 - - /* - - This code block was based on two major assumptions that are no longer true: - 1) Footprint library basenames would remain the same. - (But no, basenames have been renamed in the github repo.) - 2) *.mod files would still be around and merely reside in the FP_LIB_TABLE. - (But no, they have been converted to *.pretty.) - - There is a newer replacement code block in the #else region. - - */ - -/** - * Function missingLegacyLibs - * tests the list of \a aLibNames by URI to determine if any of them are missing from - * the #FP_LIB_TABLE. - * - * @note The missing legacy footprint library test is performed by using old library - * file path lookup method. If the library is found, it is compared against all - * of the URIs in the table rather than the nickname. This was done because the - * user could change the nicknames from the default table. Using the full path - * is more reliable. - * - * @param aLibNames is the list of legacy library names. - * @param aErrorMsg is a pointer to a wxString object to store the URIs of any missing - * legacy library paths. Can be NULL. - * @return true if there are missing legacy libraries. Otherwise false. - */ -static bool missingLegacyLibs( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, - const wxArrayString& aLibNames, wxString* aErrorMsg ) -{ - bool missing = false; - - for( unsigned i = 0; i < aLibNames.GetCount(); i++ ) - { - wxFileName fn( wxEmptyString, aLibNames[i], LegacyFootprintLibPathExtension ); - - wxString legacyLibPath = aSStack.FindValidPath( fn.GetFullPath() ); - - /* - if( legacyLibPath.IsEmpty() ) - continue; - */ - - if( !aTbl->FindRowByURI( legacyLibPath ) ) - { - missing = true; - - if( aErrorMsg ) - { - *aErrorMsg += wxChar( '"' ); - - if( !legacyLibPath ) - *aErrorMsg += !legacyLibPath ? aLibNames[i] : legacyLibPath; - - *aErrorMsg += wxT( "\"\n" ); - } - } - } - - return missing; -} - - -/** - * Function convertFromLegacy - * converts the footprint names in \a aNetList from the legacy format to the #FPID format. - * - * @param aNetList is the #NETLIST object to convert. - * @param aLibNames is the list of legacy footprint library names from the currently loaded - * project. - * @param aReporter is the #REPORTER object to dump messages into. - * @return true if all footprint names were successfully converted to a valid FPID. - */ -static bool convertFromLegacy( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, NETLIST& aNetList, - const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR ) -{ - wxString msg; - FPID lastFPID; - COMPONENT* component; - MODULE* module = 0; - bool retv = true; - - if( aNetList.IsEmpty() ) - return true; - - aNetList.SortByFPID(); - - wxString libPath; - - PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) ); - - for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ ) - { - component = aNetList.GetComponent( ii ); - - // The footprint hasn't been assigned yet so ignore it. - if( component->GetFPID().empty() ) - continue; - - if( component->GetFPID() != lastFPID ) - { - module = NULL; - - for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ ) - { - wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension ); - - libPath = aSStack.FindValidPath( fn.GetFullPath() ); - - if( !libPath ) - { - if( aReporter ) - { - msg.Printf( _( "Cannot find footprint library file '%s' in any of the " - "KiCad legacy library search paths.\n" ), - GetChars( fn.GetFullPath() ) ); - aReporter->Report( msg ); - } - - retv = false; - continue; - } - - module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() ); - - if( module ) - { - lastFPID = component->GetFPID(); - break; - } - } - } - - if( !module ) - { - if( aReporter ) - { - msg.Printf( _( "Component '%s' footprint '%s' was not found in any legacy " - "library.\n" ), - GetChars( component->GetReference() ), - GetChars( component->GetFPID().Format() ) ); - aReporter->Report( msg ); - } - - // Clear the footprint assignment since the old library lookup method is no - // longer valid. - FPID emptyFPID; - - component->SetFPID( emptyFPID ); - retv = false; - continue; - } - else - { - wxString libNickname; - - const FP_LIB_TABLE::ROW* row; - - if( ( row = aTbl->FindRowByURI( libPath ) ) != NULL ) - libNickname = row->GetNickName(); - - if( libNickname.IsEmpty() ) - { - if( aReporter ) - { - msg.Printf( _( "Component '%s' with footprint '%s' and legacy library path '%s' " - "was not found in the footprint library table.\n" ), - GetChars( component->GetReference() ), - GetChars( component->GetFPID().Format() ), - GetChars( libPath ) - ); - aReporter->Report( msg ); - } - - retv = false; - } - else - { - FPID newFPID = lastFPID; - newFPID.SetLibNickname( libNickname ); - - if( !newFPID.IsValid() ) - { - if( aReporter ) - { - msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ), - GetChars( component->GetReference() ), - GetChars( newFPID.Format() ) ); - aReporter->Report( msg ); - } - - retv = false; - } - else - { - // The footprint name should already be set. - component->SetFPID( newFPID ); - } - } - } - } - - return retv; -} - - -bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() -{ - COMPONENT* component; - wxString msg; - bool isLegacy = true; - - ReadSchematicNetlist(); - - if( m_ListCmp == NULL ) - return false; - - LoadProjectFile( m_NetlistFileName.GetFullPath() ); - LoadFootprintFiles(); - BuildFOOTPRINTS_LISTBOX(); - BuildLIBRARY_LISTBOX(); - - m_ListCmp->Clear(); - m_undefinedComponentCnt = 0; - - if( m_netlist.AnyFootprintsLinked() ) - { - for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) - { - component = m_netlist.GetComponent( i ); - - if( component->GetFPID().empty() ) - continue; - - if( isLegacy ) - { - if( !component->GetFPID().IsLegacy() ) - isLegacy = false; - } - } - } - else - { - isLegacy = false; // None of the components have footprints assigned. - } - - wxString missingLibs; - - // Check if footprint links were generated before the footprint library table was implemented. - if( isLegacy ) - { - if( missingLegacyLibs( FootprintLibs(), Prj().PcbSearchS(), m_ModuleLibNames, &missingLibs ) ) - { - msg = wxT( "The following legacy libraries are defined in the project file " - "but were not found in the footprint library table:\n\n" ) + missingLibs; - msg += wxT( "\nDo you want to update the footprint library table before " - "attempting to update the assigned footprints?" ); - - if( IsOK( this, msg ) ) - { - wxCommandEvent cmd; - - OnEditFootprintLibraryTable( cmd ); - } - } - - msg = wxT( "Some or all of the assigned footprints contain legacy entries. Would you " - "like CvPcb to attempt to convert them to the new footprint library table " - "format?" ); - - if( IsOK( this, msg ) ) - { - msg.Clear(); - WX_STRING_REPORTER reporter( &msg ); - - SEARCH_STACK& search = Prj().SchSearchS(); - - if( !convertFromLegacy( FootprintLibs(), search, m_netlist, m_ModuleLibNames, &reporter ) ) - { - HTML_MESSAGE_BOX dlg( this, wxEmptyString ); - - dlg.MessageSet( wxT( "The following errors occurred attempting to convert the " - "footprint assignments:\n\n" ) ); - dlg.ListSet( msg ); - dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them " - "to be updated correctly the next time you import the " - "netlist in Pcbnew." ) ); - dlg.ShowModal(); - } - - m_modified = true; - } - else - { - // Clear the legacy footprint assignments. - for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) - { - FPID emptyFPID; - component = m_netlist.GetComponent( i ); - component->SetFPID( emptyFPID ); - m_modified = true; - } - } - } - - for( unsigned i = 0; i < m_netlist.GetCount(); i++ ) - { - component = m_netlist.GetComponent( i ); - - msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1, - GetChars( component->GetReference() ), - GetChars( component->GetValue() ), - GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) ); - - m_ListCmp->AppendLine( msg ); - - if( component->GetFPID().empty() ) - { - m_undefinedComponentCnt += 1; - continue; - } - } - - if( !m_netlist.IsEmpty() ) - m_ListCmp->SetSelection( 0, true ); - - DisplayStatus(); - - UpdateTitle(); - - UpdateFileHistory( m_NetlistFileName.GetFullPath() ); - - return true; -} - -#else // new strategy - /// Return true if the resultant FPID has a certain nickname. The guess /// is only made if this footprint resides in only one library. /// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches @@ -503,7 +163,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() { wxString msg; bool hasMissingNicks = false; - FP_LIB_TABLE* tbl = FootprintLibs(); ReadSchematicNetlist(); @@ -512,6 +171,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() LoadProjectFile( m_NetlistFileName.GetFullPath() ); LoadFootprintFiles(); + BuildFOOTPRINTS_LISTBOX(); BuildLIBRARY_LISTBOX(); @@ -554,6 +214,9 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() if( component->GetFPID().IsLegacy() ) { + // get this first here, it's possibly obsoleted if we get it too soon. + FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); + int guess = guessNickname( tbl, (FPID*) &component->GetFPID() ); switch( guess ) @@ -659,9 +322,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() } -#endif - - int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) { wxFileName fn; @@ -685,7 +345,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) fn.SetExt( ComponentFileExtension ); // Save the project specific footprint library table. - if( !FootprintLibs()->IsEmpty( false ) ) + if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) { wxString fp_lib_tbl = Prj().FootprintLibTblName(); @@ -695,7 +355,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) { try { - FootprintLibs()->Save( fp_lib_tbl ); + Prj().PcbFootprintLibs()->Save( fp_lib_tbl ); } catch( const IO_ERROR& ioe ) { diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index b139726841..a57179691d 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -311,20 +311,18 @@ if( USE_KIWAY_DLLS ) DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( TARGETS eeschema_kiface - # actual filename subject to change at milestone C) - # modular-kicad blueprint. - DESTINATION ${KICAD_BIN} - COMPONENT binary - ) - if( APPLE ) - # copies kiface into the bundle - add_custom_target( _eeschema_kiface_copy ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/eeschema/_eeschema.kiface "${CMAKE_BINARY_DIR}/eeschema/eeschema.app/Contents/MacOS/" - DEPENDS eeschema_kiface - COMMENT "Copying kiface into eeschema" - ) + # puts the *.kiface into the *.app bundle while linking + set_target_properties( eeschema_kiface PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/eeschema.app/Contents/MacOS/ + ) + else() + install( TARGETS eeschema_kiface + # actual filename subject to change at milestone C) + # modular-kicad blueprint. + DESTINATION ${KICAD_BIN} + COMPONENT binary + ) endif() else() diff --git a/eeschema/Info.plist b/eeschema/Info.plist index 80d58bfc7d..d9ad6ea8b2 100644 --- a/eeschema/Info.plist +++ b/eeschema/Info.plist @@ -2,54 +2,36 @@ - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - CFBundleTypeExtensions - - sch - - CFBundleTypeIconFile - eeschema.icns - CFBundleTypeName - eeschema document - LSHandlerRank - Owner - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - eeschema - CFBundleGetInfoString - - CFBundleIconFile - eeschema.icns - CFBundleIdentifier - org.kicad-eda.eeschema - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundleName - EESchema - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True + CFBundleDocumentTypes + + + CFBundleTypeRole Editor + CFBundleTypeExtensions + + sch + + + CFBundleTypeIconFile eeschema.icns + CFBundleTypeName eeschema document + LSHandlerRank Owner + + + + CFBundleDevelopmentRegion English + CFBundleExecutable eeschema + CFBundleGetInfoString + CFBundleIconFile eeschema.icns + CFBundleIdentifier org.kicad-eda.eeschema + CFBundleInfoDictionaryVersion 6.0 + CFBundleLongVersionString + CFBundleName EESchema + CFBundlePackageType APPL + CFBundleShortVersionString + CFBundleSignature ???? + CFBundleVersion + CSResourcesFileMapped + LSRequiresCarbon + NSHumanReadableCopyright + NSHighResolutionCapable True diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index cb9fcbc4ee..0ea32ac16e 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -436,13 +436,8 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::deleteFieldButtonHandler( wxCommandEven void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& event ) { -#if 0 - wxString datasheet_uri = fieldValueTextCtrl->GetValue(); - ::wxLaunchDefaultBrowser( datasheet_uri ); - -#else - unsigned fieldNdx = getSelectedFieldNdx(); + if( fieldNdx == DATASHEET ) { wxString datasheet_uri = fieldValueTextCtrl->GetValue(); @@ -455,17 +450,14 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& even KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); - if( frame->ShowModal( &fpid ) ) + if( frame->ShowModal( &fpid, this ) ) { - printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); + // DBG( printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); ) fieldValueTextCtrl->SetValue( fpid ); - } frame->Destroy(); } -#endif - } @@ -771,8 +763,6 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copySelectedFieldToPanel() else m_show_datasheet_button->SetLabel( wxEmptyString ); - m_show_datasheet_button->Enable( fieldNdx == DATASHEET || fieldNdx == FOOTPRINT ); - // For power symbols, the value is NOR editable, because value and pin // name must be same and can be edited only in library editor if( fieldNdx == VALUE && m_LibEntry && m_LibEntry->IsPower() ) diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp index 4036c36cb5..37831227d9 100644 --- a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp +++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -141,7 +142,7 @@ void LIB_EDIT_FRAME::InstallFieldsEditorDialog( wxCommandEvent& event ) DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB dlg( this, m_component ); - int abort = dlg.ShowModal(); + int abort = dlg.ShowQuasiModal(); if( abort ) return; @@ -211,7 +212,7 @@ void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnListItemSelected( wxListEvent& event void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnCancelButtonClick( wxCommandEvent& event ) { - EndModal( 1 ); + EndQuasiModal( 1 ); } @@ -282,7 +283,7 @@ void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnOKButtonClick( wxCommandEvent& event m_parent->OnModify(); - EndModal( 0 ); + EndQuasiModal( 0 ); } @@ -381,8 +382,28 @@ void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB:: moveUpButtonHandler( wxCommandEvent& e void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::showButtonHandler( wxCommandEvent& event ) { - wxString datasheet_uri = fieldValueTextCtrl->GetValue(); - ::wxLaunchDefaultBrowser( datasheet_uri ); + unsigned fieldNdx = getSelectedFieldNdx(); + + if( fieldNdx == DATASHEET ) + { + wxString datasheet_uri = fieldValueTextCtrl->GetValue(); + ::wxLaunchDefaultBrowser( datasheet_uri ); + } + else if( fieldNdx == FOOTPRINT ) + { + // pick a footprint using the footprint picker. + wxString fpid; + + KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); + + if( frame->ShowModal( &fpid, this ) ) + { + // DBG( printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); ) + fieldValueTextCtrl->SetValue( fpid ); + } + + frame->Destroy(); + } } @@ -652,7 +673,14 @@ void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::copySelectedFieldToPanel() textSizeTextCtrl->SetValue( EDA_GRAPHIC_TEXT_CTRL::FormatSize( g_UserUnit, field.GetSize().x ) ); - m_show_datasheet_button->Enable( fieldNdx == DATASHEET ); + m_show_datasheet_button->Enable( fieldNdx == DATASHEET || fieldNdx == FOOTPRINT ); + + if( fieldNdx == DATASHEET ) + m_show_datasheet_button->SetLabel( _( "Show in Browser" ) ); + else if( fieldNdx == FOOTPRINT ) + m_show_datasheet_button->SetLabel( _( "Assign Footprint" ) ); + else + m_show_datasheet_button->SetLabel( wxEmptyString ); wxPoint coord = field.GetTextPosition(); wxPoint zero; diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp index a859617859..956e092640 100644 --- a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp +++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp @@ -9,7 +9,7 @@ /////////////////////////////////////////////////////////////////////////// -DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp index d6a0535ca9..94ef7e29cf 100644 --- a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp +++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp @@ -46,7 +46,7 @@ -1,-1 wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU - + DIALOG_SHIM; dialog_shim.h Field Properties diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h index 82188f2008..fdd0464897 100644 --- a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h +++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h @@ -11,6 +11,9 @@ #include #include #include +class DIALOG_SHIM; + +#include "dialog_shim.h" #include #include #include @@ -33,7 +36,7 @@ /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE /////////////////////////////////////////////////////////////////////////////// -class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE : public wxDialog +class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE : public DIALOG_SHIM { private: diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index 911c1d138d..52da445fd0 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -99,8 +99,7 @@ static struct IFACE : public KIFACE_I case FRAME_SCH_LIB_EDITOR: { - LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, - dynamic_cast( aParent ) ); + LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, aParent ); return frame; } break; diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index e81d028bfa..8821cfb31e 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -79,7 +79,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedA wxString cmpname; - if( viewlibFrame->ShowModal( &cmpname ) ) + if( viewlibFrame->ShowModal( &cmpname, this ) ) { if( aUnit ) *aUnit = viewlibFrame->GetUnit(); diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 49ea88353d..5edc5badb4 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -187,7 +187,7 @@ END_EVENT_TABLE() #define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" ) -LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) : +LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() ) { diff --git a/eeschema/libeditframe.h b/eeschema/libeditframe.h index 07a52b6203..106ef8830b 100644 --- a/eeschema/libeditframe.h +++ b/eeschema/libeditframe.h @@ -122,7 +122,7 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME public: - LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ); + LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); ~LIB_EDIT_FRAME(); diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index db9e8f50ce..fad9539da9 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -101,6 +101,8 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer ) EVT_TOOL( ID_TO_PCB, SCH_EDIT_FRAME::OnOpenPcbnew ) + EVT_TOOL( ID_TO_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor ) + EVT_TOOL( ID_TO_CVPCB, SCH_EDIT_FRAME::OnOpenCvpcb ) EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings ) @@ -794,6 +796,22 @@ void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) } +void SCH_EDIT_FRAME::OnOpenPcbModuleEditor( wxCommandEvent& event ) +{ + if( !Kiface().IsSingle() ) + { + wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); + + if( fn.IsOk() ) + { + KIWAY_PLAYER* player = Kiway().Player( FRAME_PCB_MODULE_EDITOR ); + player->Show( true ); + player->Raise(); + } + } +} + + void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) { wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); diff --git a/eeschema/tool_sch.cpp b/eeschema/tool_sch.cpp index 2bbed5bd48..962ef3847f 100644 --- a/eeschema/tool_sch.cpp +++ b/eeschema/tool_sch.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -139,10 +140,8 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_TO_LIBVIEW, wxEmptyString, KiBitmap( library_browse_xpm ), HELP_RUN_LIB_VIEWER ); - m_mainToolBar->AddSeparator(); - m_mainToolBar->AddTool( ID_GET_ANNOTATE, wxEmptyString, KiBitmap( annotate_xpm ), HELP_ANNOTATE ); @@ -158,6 +157,13 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddSeparator(); + // The user must HAVE footprints before he can assign them. So put this before + // the CVPCB. + if( !Kiface().IsSingle() ) // if pcbnew is not a separate process + { + m_mainToolBar->AddTool( ID_TO_PCB_MODULE_EDITOR, wxEmptyString, KiBitmap( module_editor_xpm ), + _( "Footprint Editor" ) ); + } m_mainToolBar->AddTool( ID_TO_CVPCB, wxEmptyString, KiBitmap( cvpcb_xpm ), _( "Run CvPcb to associate components and footprints" ) ); diff --git a/eeschema/viewlib_frame.h b/eeschema/viewlib_frame.h index 4e67d0eafc..e87952a64e 100644 --- a/eeschema/viewlib_frame.h +++ b/eeschema/viewlib_frame.h @@ -36,7 +36,6 @@ #include #include -class wxSashLayoutWindow; class wxListBox; class CMP_LIBRARY; diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index 7eff8d254e..4ffae72958 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -81,11 +81,11 @@ endif() if( APPLE ) - set(GERBVIEW_RESOURCES gerbview.icns gerbview_doc.icns) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gerbview.icns" PROPERTIES + set( GERBVIEW_RESOURCES gerbview.icns gerbview_doc.icns ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/gerbview.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gerbview_doc.icns" PROPERTIES + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/gerbview_doc.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) set( MACOSX_BUNDLE_ICON_FILE gerbview.icns ) @@ -120,7 +120,6 @@ if( USE_KIWAY_DLLS ) ${GERBVIEW_SRCS} ${DIALOGS_SRCS} ${GERBVIEW_EXTRA_SRCS} -# ${GERBVIEW_RESOURCES} ) set_target_properties( gerbview_kiface PROPERTIES OUTPUT_NAME gerbview @@ -152,18 +151,16 @@ if( USE_KIWAY_DLLS ) DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( TARGETS gerbview_kiface - DESTINATION ${KICAD_BIN} - COMPONENT binary - ) - if( APPLE ) - # copies kiface into the bundle - add_custom_target( _gerbview_kiface_copy ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/gerbview/_gerbview.kiface "${CMAKE_BINARY_DIR}/gerbview/gerbview.app/Contents/MacOS/" - DEPENDS gerbview_kiface - COMMENT "Copying kiface into gerbview" - ) + # puts the *.kiface into the *.app bundle while linking + set_target_properties( gerbview_kiface PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gerbview.app/Contents/MacOS/ + ) + else() + install( TARGETS gerbview_kiface + DESTINATION ${KICAD_BIN} + COMPONENT binary + ) endif() else() @@ -194,5 +191,3 @@ if( APPLE ) set_target_properties( gerbview PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) endif() - - diff --git a/gerbview/Info.plist b/gerbview/Info.plist index a9d27ad02e..a37434eca2 100644 --- a/gerbview/Info.plist +++ b/gerbview/Info.plist @@ -2,72 +2,54 @@ - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - pen - gba - gbr - gbx - gbo - gbl - gtl - gto - gta - gbp - gbp - gbs - gts - gtp - gbx - lgr - ger - pho - drl - - CFBundleTypeIconFile - gerbview_doc.icns - CFBundleTypeName - gerbview document - LSHandlerRank - Default - CFBundleTypeRole - Viewer - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - gerbview - CFBundleGetInfoString - - CFBundleIconFile - gerbview.icns - CFBundleIdentifier - org.kicad-eda.gerbview - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundleName - GerbView - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + pen + gba + gbr + gbx + gbo + gbl + gtl + gto + gta + gbp + gbp + gbs + gts + gtp + gbx + lgr + ger + pho + drl + + + CFBundleTypeIconFile gerbview_doc.icns + CFBundleTypeName gerbview document + LSHandlerRank Default + CFBundleTypeRole Viewer + + + + CFBundleDevelopmentRegion English + CFBundleExecutable gerbview + CFBundleGetInfoString + CFBundleIconFile gerbview.icns + CFBundleIdentifier org.kicad-eda.gerbview + CFBundleInfoDictionaryVersion 6.0 + CFBundleLongVersionString + CFBundleName GerbView + CFBundlePackageType APPL + CFBundleShortVersionString + CFBundleSignature ???? + CFBundleVersion + CSResourcesFileMapped + LSRequiresCarbon + NSHumanReadableCopyright + NSHighResolutionCapable True diff --git a/include/common.h b/include/common.h index ef03ea0e6a..f7d222adc6 100644 --- a/include/common.h +++ b/include/common.h @@ -102,7 +102,7 @@ enum pseudokeys { #define GERBVIEW_EXE wxT( "gerbview.app/Contents/MacOS/gerbview" ) #define BITMAPCONVERTER_EXE wxT( "bitmap2component.app/Contents/MacOS/bitmap2component" ) #define PCB_CALCULATOR_EXE wxT( "pcb_calculator.app/Contents/MacOS/pcb_calculator" ) -#define PL_EDITOR_EXE wxT( "pcb_calculator.app/Contents/MacOS/pl_editor" ) +#define PL_EDITOR_EXE wxT( "pl_editor.app/Contents/MacOS/pl_editor" ) # endif #endif diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index 679d437b42..4a2b822137 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -270,6 +270,8 @@ public: */ FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL ); + ~FP_LIB_TABLE(); + /// Delete all rows. void Clear() { diff --git a/include/id.h b/include/id.h index 0c60acd429..a243491c30 100644 --- a/include/id.h +++ b/include/id.h @@ -45,6 +45,7 @@ enum main_id { ID_TO_PCB = wxID_HIGHEST, + ID_TO_PCB_MODULE_EDITOR, ID_TO_CVPCB, ID_LOAD_PROJECT, ID_APPEND_PROJECT, diff --git a/include/kiway_player.h b/include/kiway_player.h index e62981ab54..0bdc2e8045 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -185,11 +185,12 @@ public: * event which ends the modal behavior. * * @param aResult if not NULL, indicates a place to put a resultant string. + * @param aResultantFocusWindow if not NULL, indicates what window to pass focus to on return. * * @return bool - true if frame implementation called KIWAY_PLAYER::DismissModal() * with aRetVal of true. */ - VTBL_ENTRY bool ShowModal( wxString* aResult = NULL ); + VTBL_ENTRY bool ShowModal( wxString* aResult = NULL, wxWindow* aResultantFocusWindow = NULL ); //-------------------------------------------------------- @@ -201,6 +202,11 @@ public: */ virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); + /** + * Our version of Destroy() which is virtual from wxWidgets + */ + bool Destroy(); + protected: bool IsModal() { return m_modal; } @@ -228,6 +234,7 @@ protected: // variables for modal behavior support, only used by a few derivatives. bool m_modal; // true if frame is intended to be modal, not modeless WX_EVENT_LOOP* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed + wxWindow* m_modal_resultant_parent; // the window caller in modal mode wxString m_modal_string; bool m_modal_ret_val; // true if a selection was made diff --git a/include/project.h b/include/project.h index a4928f4e5c..c7f7a7f3dd 100644 --- a/include/project.h +++ b/include/project.h @@ -35,7 +35,7 @@ class wxConfigBase; class PARAM_CFG_ARRAY; - +class FP_LIB_TABLE; #define VTBL_ENTRY virtual @@ -49,11 +49,12 @@ class PROJECT { public: - /// Derive PROJECT elements from this, it has a virtual destructor, and - /// Elem*() functions can work with it. Implementation is opaque in - /// class PROJECT. If find you have to include derived class headers in this - /// file, you are doing something wrong. Keep knowledge of derived classes - /// opaque to class PROJECT please. + /// A PROJECT can hold stuff it knows nothing about, in the form of + /// _ELEM derivatives. Derive PROJECT elements from this, it has a virtual + /// destructor, and Elem*() functions can work with it. Implementation is + /// opaque in class PROJECT. If find you have to include derived class headers + /// in this file, you are doing incompatible with the goal of this class. + /// Keep knowledge of derived classes opaque to class PROJECT please. class _ELEM { public: @@ -63,6 +64,8 @@ public: PROJECT(); ~PROJECT(); + //--------------------------------------------------------- + // VTBL_ENTRY bool MaybeLoadProjectSettings( const std::vector& aFileSet ); /** @@ -154,18 +157,12 @@ public: */ enum ELEM_T { - FPTBL, + ELEM_FPTBL, ELEM_COUNT }; /** - * A PROJECT can hold stuff it knows nothing about, in the form of - * _ELEM derivatives. This function gives access to a PROJECT::_ELEM using - * enum ELEM_T as an index. - *

- * Acts as setter iff aElem is not NULL, else getter. - *

* Typically wrapped somewhere else in a more meaningful function wrapper. * This is a cross module API, therefore the _ELEM destructor is virtual and * can point to a destructor function in another link image. Be careful that @@ -174,7 +171,47 @@ public: * Summary: 1) cross module API, 2) PROJECT knows nothing about _ELEM objects, * except how to delete them and set and get pointers to them. */ - VTBL_ENTRY _ELEM* Elem( ELEM_T aIndex, _ELEM* aElem = NULL ); + VTBL_ENTRY _ELEM* GetElem( ELEM_T aIndex ); + VTBL_ENTRY void SetElem( ELEM_T aIndex, _ELEM* aElem ); + + /// Inline, clear the _ELEM at position aIndex + void ElemClear( ELEM_T aIndex ) + { + _ELEM* existing = GetElem( aIndex ); + delete existing; // virtual + SetElem( aIndex, NULL ); + } + + /** + * Function ElemsClear + * deletes all the _ELEMs and set their pointers to NULL. + */ + VTBL_ENTRY void ElemsClear(); + + //-------------------------------------------------------- + + //----------------------------------------------------- + + // These are the non-virtual DATA LOAD ON DEMAND members. They load project related + // data on demand, and do so typicallly into m_elems[] at a particular index using + // SetElem() & GetElem(). That is, they wrap SetElem() and GetElem(). + // To get the data to reload on demand, first SetProjectFullName(), + // then call ElemClear() from client code. + + // non-virtuals resident in PCBNEW link image(s). By being non-virtual, these + // functions can get linked into the KIFACE that needs them, and only there. + // In fact, the other KIFACEs don't even know they exist. +#if defined(PCBNEW) || defined(CVPCB) + // These are all prefaced with "Pcb" + FP_LIB_TABLE* PcbFootprintLibs(); +#endif + + +#if defined(EESCHEMA) + // These are all prefaced with "Sch" +#endif + + //---------------------------------------------------- private: @@ -215,10 +252,6 @@ private: //-------------------------------------------------------------- #if 0 - VTBL_ENTRY int ElemAllocNdx(); - VTBL_ENTRY void ElemSet( int aIndex, ELEMENT_BASE* aBlock ); - VTBL_ENTRY ELEM_BASE* ElemGet( int aIndex ) - /** * Function Value * fetches a project variable @a aVariable and returns true if that variable was diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index cd23d6fdd1..b2ce7d9a23 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -103,7 +103,7 @@ protected: * * @param aFootprintId is the #FPID of component footprint to load. * @return the #MODULE if found or NULL if \a aFootprintId not found in any of the - * libraries in the table returned from #FootprintLibs(). + * libraries in the table returned from #Prj().PcbFootprintLibs(). * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error * occurs while reading footprint library files. */ @@ -127,7 +127,7 @@ public: * * @param aFootprintId is the #FPID of component footprint to load. * @return the #MODULE if found or NULL if \a aFootprintId not found in any of the - * libraries in table returned from #FootprintLibs(). + * libraries in table returned from #Prj().PcbFootprintLibs(). */ MODULE* LoadFootprint( const FPID& aFootprintId ); @@ -463,12 +463,6 @@ public: */ wxString SelectFootprintFromLibBrowser(); - /** - * Function FootprintLibs - * @return the project #FP_LIB_TABLE. - */ - FP_LIB_TABLE* FootprintLibs() const; - // ratsnest functions /** * Function Compile_Ratsnest diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 171351d321..852b65c3fc 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -368,7 +368,7 @@ public: */ virtual void ExecuteRemoteCommand( const char* cmdline ); - void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // virtual overload from KIWAY_PLAYER + void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // override virtual from KIWAY_PLAYER void OnLeftClick( wxDC* aDC, const wxPoint& aPosition ); void OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ); @@ -793,6 +793,7 @@ private: void OnLoadProject( wxCommandEvent& event ); void OnAppendProject( wxCommandEvent& event ); void OnOpenPcbnew( wxCommandEvent& event ); + void OnOpenPcbModuleEditor( wxCommandEvent& event ); void OnOpenCvpcb( wxCommandEvent& event ); void OnOpenLibraryEditor( wxCommandEvent& event ); void OnSetOptions( wxCommandEvent& event ); diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 1d76b4696b..121c5af247 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -57,6 +57,22 @@ if( UNIX ) endif() +if( APPLE ) + # In this CMakeLists.txt's build directory, create kiface symlinks should get + # "installed()" as part of the kicad.app bundle. These are pointers on the + # target which point up and over to the stand alone kicad app's *.kiface files. + foreach( symlink pcbnew eeschema cvpcb ) + add_custom_command( TARGET kicad + COMMAND ${CMAKE_COMMAND} -E remove + "${CMAKE_CURRENT_BINARY_DIR}/kicad.app/Contents/MacOS/_${symlink}.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink + "../../../${symlink}.app/Contents/MacOS/_${symlink}.kiface" + "${CMAKE_CURRENT_BINARY_DIR}/kicad.app/Contents/MacOS/_${symlink}.kiface" + COMMENT "kicad.app ${symlink} symlink" + ) + endforeach() +endif() + if( APPLE ) set_target_properties( kicad PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist diff --git a/kicad/Info.plist b/kicad/Info.plist index fa990ed54d..d55a08c51a 100644 --- a/kicad/Info.plist +++ b/kicad/Info.plist @@ -2,54 +2,36 @@ - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - CFBundleTypeIconFile - kicad_doc.icns - CFBundleTypeExtensions - - pro - - CFBundleTypeName - kicad project files - LSHandlerRank - Owner - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - kicad - CFBundleGetInfoString - - CFBundleIconFile - kicad.icns - CFBundleIdentifier - org.kicad-eda.kicad - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundleName - KiCad - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True + CFBundleDocumentTypes + + + CFBundleTypeRole Editor + CFBundleTypeIconFile kicad_doc.icns + + CFBundleTypeExtensions + pro + + + CFBundleTypeName kicad project files + LSHandlerRank Owner + + + + CFBundleDevelopmentRegion English + CFBundleExecutable kicad + CFBundleGetInfoString + CFBundleIconFile kicad.icns + CFBundleIdentifier org.kicad-eda.kicad + CFBundleInfoDictionaryVersion 6.0 + CFBundleLongVersionString + CFBundleName KiCad + CFBundlePackageType APPL + CFBundleShortVersionString + CFBundleSignature ???? + CFBundleVersion + CSResourcesFileMapped + LSRequiresCarbon + NSHumanReadableCopyright + NSHighResolutionCapable True diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index cd6e41acdd..2f6a544db8 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -49,7 +49,20 @@ set( PL_EDITOR_EXTRA_SRCS if( MINGW ) # PL_EDITOR_RESOURCES variable is set by the macro. - mingw_resource_compiler(pl_editor) + mingw_resource_compiler( pl_editor ) +endif() + + +if( APPLE ) + set( PL_EDITOR_RESOURCES pl_editor.icns pl_editor_doc.icns ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pl_editor.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pl_editor_doc.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set( MACOSX_BUNDLE_ICON_FILE pl_editor.icns ) + set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.pl_editor ) endif() @@ -82,7 +95,6 @@ if( USE_KIWAY_DLLS ) ${PL_EDITOR_SRCS} ${DIALOGS_SRCS} ${PL_EDITOR_EXTRA_SRCS} -# ${PL_EDITOR_RESOURCES} ) target_link_libraries( pl_editor_kiface common @@ -114,18 +126,16 @@ if( USE_KIWAY_DLLS ) DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( TARGETS pl_editor_kiface - DESTINATION ${KICAD_BIN} - COMPONENT binary - ) - if( APPLE ) - # copies kiface into the bundle - add_custom_target( _pleditor_kiface_copy ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/pagelayout_editor/_pl_editor.kiface "${CMAKE_BINARY_DIR}/pagelayout_editor/pl_editor.app/Contents/MacOS/" - DEPENDS pl_editor_kiface - COMMENT "Copying kiface into pleditor" - ) + # puts the *.kiface into the *.app bundle while linking + set_target_properties( pl_editor_kiface PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pl_editor.app/Contents/MacOS/ + ) + else() + install( TARGETS pl_editor_kiface + DESTINATION ${KICAD_BIN} + COMPONENT binary + ) endif() else() @@ -137,13 +147,6 @@ else() ${PL_EDITOR_EXTRA_SRCS} ${PL_EDITOR_RESOURCES} ) - - if( APPLE ) - set_target_properties( pl_editor PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist - ) - endif() - target_link_libraries( pl_editor common polygon @@ -152,28 +155,15 @@ else() ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES} ) - install( TARGETS pl_editor DESTINATION ${KICAD_BIN} COMPONENT binary ) - endif() if( APPLE ) - set( PL_EDITOR_RESOURCES pl_editor.icns pl_editor_doc.icns ) - set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pl_editor.icns" PROPERTIES - MACOSX_PACKAGE_LOCATION Resources - ) - set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pl_editor_doc.icns" PROPERTIES - MACOSX_PACKAGE_LOCATION Resources - ) - set( MACOSX_BUNDLE_ICON_FILE pl_editor.icns ) - set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.pl_editor ) - set_target_properties( pl_editor PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ) endif() - diff --git a/pagelayout_editor/Info.plist b/pagelayout_editor/Info.plist index 64d9326613..9db98f05b2 100644 --- a/pagelayout_editor/Info.plist +++ b/pagelayout_editor/Info.plist @@ -2,54 +2,36 @@ - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - CFBundleTypeExtensions - - kicad_wks - - CFBundleTypeIconFile - pl_editor.icns - CFBundleTypeName - pl_editor document - LSHandlerRank - Owner - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - pl_editor - CFBundleGetInfoString - - CFBundleIconFile - pl_editor.icns - CFBundleIdentifier - org.kicad-eda.pl_editor - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundleName - pl_editor - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True + CFBundleDocumentTypes + + + CFBundleTypeRole Editor + CFBundleTypeExtensions + + kicad_wks + + + CFBundleTypeIconFile pl_editor.icns + CFBundleTypeName pl_editor document + LSHandlerRank Owner + + + + CFBundleDevelopmentRegion English + CFBundleExecutable pl_editor + CFBundleGetInfoString + CFBundleIconFile pl_editor.icns + CFBundleIdentifier org.kicad-eda.pl_editor + CFBundleInfoDictionaryVersion 6.0 + CFBundleLongVersionString + CFBundleName pl_editor + CFBundlePackageType APPL + CFBundleShortVersionString + CFBundleSignature ???? + CFBundleVersion + CSResourcesFileMapped + LSRequiresCarbon + NSHumanReadableCopyright + NSHighResolutionCapable True diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt index 14db6b9ff6..8e1dad619c 100644 --- a/pcb_calculator/CMakeLists.txt +++ b/pcb_calculator/CMakeLists.txt @@ -122,14 +122,15 @@ if( USE_KIWAY_DLLS ) DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( TARGETS pcb_calculator_kiface - DESTINATION ${KICAD_BIN} - COMPONENT binary - ) - if( APPLE ) - set_target_properties( pcb_calculator PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist + # puts the *.kiface into the *.app bundle while linking + set_target_properties( pcb_calculator_kiface PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pcb_calculator.app/Contents/MacOS/ + ) + else() + install( TARGETS pcb_calculator_kiface + DESTINATION ${KICAD_BIN} + COMPONENT binary ) endif() @@ -156,13 +157,6 @@ else() set_source_files_properties( pcb_calculator.cpp PROPERTIES COMPILE_DEFINITIONS "COMPILING_DLL" ) - - if( APPLE ) - set_target_properties( pcb_calculator PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist - ) - endif() - target_link_libraries( pcb_calculator common bitmaps @@ -175,3 +169,10 @@ else() ) endif() + + +if( APPLE ) + set_target_properties( pcb_calculator PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist + ) +endif() diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 3e7e89fafa..ae2292bf13 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -594,17 +594,15 @@ if( USE_KIWAY_DLLS ) DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( TARGETS pcbnew_kiface - DESTINATION ${KICAD_BIN} - COMPONENT binary - ) - if( APPLE ) - # copies kiface into the bundle - add_custom_target( _pcbnew_kiface_copy ALL - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.kiface "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.app/Contents/MacOS/" - DEPENDS pcbnew_kiface - COMMENT "Copying kiface into pcbnew" + # puts the *.kiface into the *.app bundle while linking + set_target_properties( pcbnew_kiface PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.app/Contents/MacOS/ + ) + else() + install( TARGETS pcbnew_kiface + DESTINATION ${KICAD_BIN} + COMPONENT binary ) endif() @@ -768,3 +766,4 @@ if( false ) # haven't been used in years. ) target_link_libraries( layer_widget_test common ${wxWidgets_LIBRARIES} ) endif() + diff --git a/pcbnew/Info.plist b/pcbnew/Info.plist index 1f4b5bfdd5..3f31259d06 100644 --- a/pcbnew/Info.plist +++ b/pcbnew/Info.plist @@ -2,53 +2,36 @@ - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - CFBundleTypeIconFile - pcbnew_doc.icns - CFBundleTypeExtensions - - kicad_pcb - brd - - CFBundleTypeName - pcbnew board - LSHandlerRank - Owner - - - CFBundleExecutable - pcbnew - CFBundleGetInfoString - - CFBundleIconFile - pcbnew.icns - CFBundleIdentifier - org.kicad-eda.pcbnew - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundleName - PCBNew - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True + CFBundleDocumentTypes + + + CFBundleTypeRole Editor + CFBundleTypeIconFile pcbnew_doc.icns + CFBundleTypeExtensions + + kicad_pcb + brd + + + CFBundleTypeName pcbnew board + LSHandlerRank Owner + + + + CFBundleExecutable pcbnew + CFBundleGetInfoString + CFBundleIconFile pcbnew.icns + CFBundleIdentifier org.kicad-eda.pcbnew + CFBundleInfoDictionaryVersion 6.0 + CFBundleLongVersionString + CFBundleName PCBNew + CFBundlePackageType APPL + CFBundleShortVersionString + CFBundleSignature ???? + CFBundleVersion + CSResourcesFileMapped + LSRequiresCarbon + NSHumanReadableCopyright + NSHighResolutionCapable True diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 22b847ad30..3bbade6770 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -175,10 +175,15 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME() } -FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const +FP_LIB_TABLE* PROJECT::PcbFootprintLibs() { - PROJECT& prj = Prj(); - FP_LIB_TABLE* tbl = dynamic_cast( prj.Elem( PROJECT::FPTBL ) ); + // This is a lazy loading function, it loads the project specific table when + // that table is asked for, not before. + + FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL ); + + // its gotta be NULL or a FP_LIB_TABLE, or a bug. + wxASSERT( !tbl || dynamic_cast( tbl ) ); if( !tbl ) { @@ -187,7 +192,18 @@ FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const // stack this way, all using the same global fallback table. tbl = new FP_LIB_TABLE( &GFootprintTable ); - prj.Elem( PROJECT::FPTBL, tbl ); + SetElem( ELEM_FPTBL, tbl ); + + wxString projectFpLibTableFileName = FootprintLibTblName(); + + try + { + tbl->Load( projectFpLibTableFileName ); + } + catch( const IO_ERROR& ioe ) + { + DisplayError( NULL, ioe.errorText ); + } } return tbl; diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 34f20d5a13..130104e0b1 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1231,7 +1231,7 @@ void VIA::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) } -bool TRACK::HitTest( const wxPoint& aPosition ) +bool TRACK::HitTest( const wxPoint& aPosition ) const { return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ); } diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 4340c33e6d..c5ca9d03d7 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -223,7 +223,7 @@ public: const KICAD_T scanTypes[] ); - virtual bool HitTest( const wxPoint& aPosition ); + virtual bool HitTest( const wxPoint& aPosition ) const; /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index bc1e6eb5ef..fce7fd632c 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -25,7 +25,7 @@ /** * @file clean.cpp - * @brief functions to clean tracks: remove null lenght and redundant segments + * @brief functions to clean tracks: remove null length and redundant segments */ @@ -44,7 +44,7 @@ class TRACKS_CLEANER: CONNECTIONS { private: - BOARD * m_Brd; + BOARD *m_Brd; public: TRACKS_CLEANER( BOARD * aPcb ); @@ -53,8 +53,8 @@ public: * the cleanup function. * return true if some item was modified */ - bool CleanupBoard(PCB_EDIT_FRAME *aFrame, bool aCleanVias, - bool aMergeSegments, bool aDeleteUnconnected); + bool CleanupBoard( PCB_EDIT_FRAME *aFrame, bool aCleanVias, + bool aMergeSegments, bool aDeleteUnconnected); private: @@ -64,13 +64,30 @@ private: */ bool clean_vias(); + /** + * Removes all the following THT vias on the same position of the + * specified one + */ + bool remove_duplicates_of_via( const VIA *aVia ); + + /** + * Removes all the following duplicates tracks of the specified one + */ + bool remove_duplicates_of_track( const TRACK *aTrack ); + /** * Removes dangling tracks */ bool deleteUnconnectedTracks(); + /// Delete null length track segments + bool delete_null_segments(); + + /// Try to merge the segment to a following collinear one + bool merge_collinear_of_track( TRACK *aSegment ); + /** - * Merge colinear segments and remove null len segments + * Merge collinear segments and remove duplicated and null len segments */ bool clean_segments(); @@ -194,6 +211,30 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() } } +bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia ) +{ + bool modified = false; + + // Search and delete others vias at same location + VIA* next_via; + for( VIA* alt_via = GetFirstVia( aVia->Next() ); alt_via != NULL; + alt_via = next_via ) + { + next_via = GetFirstVia( alt_via->Next() ); + + if( (alt_via->GetViaType() == VIA_THROUGH) && + (alt_via->GetStart() == aVia->GetStart()) ) + { + // delete via + m_Brd->GetRatsnest()->Remove( alt_via ); + alt_via->ViewRelease(); + alt_via->DeleteStructure(); + modified = true; + } + } + return modified; +} + bool TRACKS_CLEANER::clean_vias() { bool modified = false; @@ -212,23 +253,7 @@ bool TRACKS_CLEANER::clean_vias() * (yet) handle high density interconnects */ if( via->GetViaType() != VIA_THROUGH ) { - // 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 ) - { - next_via = GetFirstVia( alt_via->Next() ); - - if( (alt_via->GetViaType() == VIA_THROUGH) && - (alt_via->GetStart() == via->GetStart()) ) - { - // delete via - m_Brd->GetRatsnest()->Remove( alt_via ); - alt_via->ViewRelease(); - alt_via->DeleteStructure(); - modified = true; - } - } + modified |= remove_duplicates_of_via( via ); /* To delete through Via on THT pads at same location * Examine the list of connected pads: @@ -367,16 +392,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() return modified; } - -// Delete null length segments, and intermediate points .. -bool TRACKS_CLEANER::clean_segments() +// Delete null length track segments +bool TRACKS_CLEANER::delete_null_segments() { + TRACK *nextsegment; bool modified = false; - TRACK* segment, * nextsegment; - TRACK* other; // Delete null segments - for( segment = m_Brd->m_Track; segment; segment = nextsegment ) + for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment ) { nextsegment = segment->Next(); @@ -388,151 +411,217 @@ bool TRACKS_CLEANER::clean_segments() modified = true; } } + return modified; +} - // Delete redundant segments, i.e. segments having the same end points - // and layers - for( segment = m_Brd->m_Track; segment; segment = segment->Next() ) +bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack ) +{ + bool modified = false; + + TRACK *nextsegment; + for( TRACK *other = aTrack->Next(); other; other = nextsegment ) { - for( other = segment->Next(); other; other = nextsegment ) + nextsegment = other->Next(); + + // New netcode, break out (can't be there any other) + if( aTrack->GetNetCode() != other->GetNetCode() ) + break; + + // Must be of the same type, on the same layer and the endpoints + // must be the same (maybe swapped) + if( (aTrack->Type() != other->Type()) && + (aTrack->GetLayer() != other->GetLayer()) ) { - nextsegment = other->Next(); - bool erase = false; - - if( segment->Type() != other->Type() ) - continue; - - if( segment->GetLayer() != other->GetLayer() ) - continue; - - if( segment->GetNetCode() != other->GetNetCode() ) - break; - - if( ( segment->GetStart() == other->GetStart() ) && - ( segment->GetEnd() == other->GetEnd() ) ) - erase = true; - - if( ( segment->GetStart() == other->GetEnd() ) && - ( segment->GetEnd() == other->GetStart() ) ) - erase = true; - - // Delete redundant point - if( erase ) + if( ((aTrack->GetStart() == other->GetStart()) && + (aTrack->GetEnd() == other->GetEnd())) || + ((aTrack->GetStart() == other->GetEnd()) && + (aTrack->GetEnd() == other->GetStart()))) { - m_Brd->GetRatsnest()->Remove( other ); - other->ViewRelease(); + m_Brd->GetRatsnest()->Remove( other ); + other->ViewRelease(); other->DeleteStructure(); modified = true; } } } + return modified; +} - // merge collinear segments: - for( segment = m_Brd->m_Track; segment; segment = nextsegment ) +bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment ) +{ + bool merged_this = false; + bool flag = false; // If there are connections to this on the endpoint + + // search for a possible point connected to the START point of the current segment + TRACK *segStart = aSegment->Next(); + while( true ) { - TRACK* segStart; - TRACK* segEnd; - TRACK* segDelete; + segStart = aSegment->GetTrack( segStart, NULL, ENDPOINT_START ); - nextsegment = segment->Next(); - - if( segment->Type() != PCB_TRACE_T ) - continue; - - unsigned flag = 0; - bool no_inc = false; - - // search for a possible point connected to the START point of the current segment - for( segStart = segment->Next(); ; ) + if( segStart ) { - segStart = segment->GetTrack( segStart, NULL, ENDPOINT_START ); - - if( segStart ) - { - // the two segments must have the same width - if( segment->GetWidth() != segStart->GetWidth() ) - break; - - // it cannot be a via - if( segStart->Type() != PCB_TRACE_T ) - break; - - // We must have only one segment connected - segStart->SetState( BUSY, true ); - other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); - segStart->SetState( BUSY, false ); - - if( other == NULL ) - flag = 1; // OK - + // the two segments must have the same width + if( aSegment->GetWidth() != segStart->GetWidth() ) break; - } + + // it cannot be a via + if( segStart->Type() != PCB_TRACE_T ) + break; + + // We must have only one segment connected + segStart->SetState( BUSY, true ); + TRACK *other = aSegment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); + segStart->SetState( BUSY, false ); + + if( other == NULL ) + flag = true; // OK + break; } + break; + } - if( flag ) // We have the starting point of the segment is connected to an other segment + if( flag ) // We have the starting point of the segment is connected to an other segment + { + TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment, segStart, ENDPOINT_START ); + + if( segDelete ) { - segDelete = mergeCollinearSegmentIfPossible( segment, segStart, ENDPOINT_START ); - - if( segDelete ) - { - no_inc = 1; - m_Brd->GetRatsnest()->Remove( segDelete ); - segDelete->ViewRelease(); - segDelete->DeleteStructure(); - modified = true; - } + m_Brd->GetRatsnest()->Remove( segDelete ); + segDelete->ViewRelease(); + segDelete->DeleteStructure(); + merged_this = true; } + } - // search for a possible point connected to the END point of the current segment: - for( segEnd = segment->Next(); ; ) + // Do the same with the other endpoint + flag = false; + + // search for a possible point connected to the END point of the current segment: + TRACK *segEnd = aSegment->Next(); + while( true ) + { + segEnd = aSegment->GetTrack( segEnd, NULL, ENDPOINT_END ); + + if( segEnd ) { - segEnd = segment->GetTrack( segEnd, NULL, ENDPOINT_END ); - - if( segEnd ) - { - if( segment->GetWidth() != segEnd->GetWidth() ) - break; - - if( segEnd->Type() != PCB_TRACE_T ) - break; - - // We must have only one segment connected - segEnd->SetState( BUSY, true ); - other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); - segEnd->SetState( BUSY, false ); - - if( other == NULL ) - flag |= 2; // Ok - + if( aSegment->GetWidth() != segEnd->GetWidth() ) break; - } - else - { + + if( segEnd->Type() != PCB_TRACE_T ) break; - } - } - if( flag & 2 ) // We have the ending point of the segment is connected to an other segment + // We must have only one segment connected + segEnd->SetState( BUSY, true ); + TRACK *other = aSegment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); + segEnd->SetState( BUSY, false ); + + if( other == NULL ) + flag = true; // Ok + + break; + } + else { - segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, ENDPOINT_END ); - - if( segDelete ) - { - no_inc = true; - m_Brd->GetRatsnest()->Remove( segDelete ); - segDelete->ViewRelease(); - segDelete->DeleteStructure(); - modified = true; - } + break; } + } - if( no_inc ) // The current segment was modified, retry to merge it - nextsegment = segment->Next(); + if( flag ) // We have the ending point of the segment is connected to an other segment + { + TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment, segEnd, ENDPOINT_END ); + + if( segDelete ) + { + m_Brd->GetRatsnest()->Remove( segDelete ); + segDelete->ViewRelease(); + segDelete->DeleteStructure(); + merged_this = true; + } + } + return merged_this; +} + +// Delete null length segments, and intermediate points .. +bool TRACKS_CLEANER::clean_segments() +{ + bool modified = false; + + // Easy things first + modified |= delete_null_segments(); + + // Delete redundant segments, i.e. segments having the same end points + // and layers + for( TRACK *segment = m_Brd->m_Track; segment; segment = segment->Next() ) + { + modified |= remove_duplicates_of_track( segment ); + } + + // merge collinear segments: + TRACK *nextsegment; + for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment ) + { + nextsegment = segment->Next(); + + if( segment->Type() == PCB_TRACE_T ) + { + bool merged_this = merge_collinear_of_track( segment ); + modified |= merged_this; + + if( merged_this ) // The current segment was modified, retry to merge it + nextsegment = segment->Next(); + } } return modified; } +/* Utility: check for parallelism between two segments */ +static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 ) +{ + // The following condition tree is ugly and repetitive, but I have + // not a better way to express clearly the trivial cases. Hope the + // compiler optimize it better than always doing the product + // below... + + // test for vertical alignment (easy to handle) + if( dx1 == 0 ) + { + if( dx2 != 0 ) + return false; + else + return true; + } + + if( dx2 == 0 ) + { + if( dx1 != 0 ) + return false; + else + return true; + } + + // test for horizontal alignment (easy to handle) + if( dy1 == 0 ) + { + if( dy2 != 0 ) + return false; + else + return true; + } + + if( dy2 == 0 ) + { + if( dy1 != 0 ) + return false; + else + return true; + } + + /* test for alignment in other cases: Do the usual cross product test + * (the same as testing the slope, but without a division) */ + return ((double)dy1 * dx2 == (double)dx1 * dy2); +} /** Function used by clean_segments. * Test if aTrackRef and aCandidate (which must have a common end) are collinear. @@ -549,63 +638,32 @@ bool TRACKS_CLEANER::clean_segments() TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, ENDPOINT_T aEndType ) { - if( aTrackRef->GetWidth() != aCandidate->GetWidth() ) + // First of all, they must be of the same width and must be both actual tracks + if( (aTrackRef->GetWidth() != aCandidate->GetWidth()) || + (aTrackRef->Type() != PCB_TRACE_T) || + (aCandidate->Type() != PCB_TRACE_T) ) return NULL; - bool is_colinear = false; + // Trivial case: exactly the same track + if( ( aTrackRef->GetStart() == aCandidate->GetStart() ) && + ( aTrackRef->GetEnd() == aCandidate->GetEnd() ) ) + return aCandidate; - // Trivial case: superimposed tracks ( tracks, not vias ): - if( aTrackRef->Type() == PCB_TRACE_T && aCandidate->Type() == PCB_TRACE_T ) - { - if( ( aTrackRef->GetStart() == aCandidate->GetStart() ) && - ( aTrackRef->GetEnd() == aCandidate->GetEnd() ) ) - return aCandidate; + if( ( aTrackRef->GetStart() == aCandidate->GetEnd() ) && + ( aTrackRef->GetEnd() == aCandidate->GetStart() ) ) + return aCandidate; - if( ( aTrackRef->GetStart() == aCandidate->GetEnd() ) && - ( aTrackRef->GetEnd() == aCandidate->GetStart() ) ) - return aCandidate; - } - - int refdx = aTrackRef->GetEnd().x - aTrackRef->GetStart().x; - int refdy = aTrackRef->GetEnd().y - aTrackRef->GetStart().y; - - int segmdx = aCandidate->GetEnd().x - aCandidate->GetStart().x; - int segmdy = aCandidate->GetEnd().y - aCandidate->GetStart().y; - - // test for vertical alignment (easy to handle) - if( refdx == 0 ) - { - if( segmdx != 0 ) - return NULL; - else - is_colinear = true; - } - - // test for horizontal alignment (easy to handle) - if( refdy == 0 ) - { - if( segmdy != 0 ) - return NULL; - else - is_colinear = true; - } - - /* test if alignment in other cases - * We must have refdy/refdx == segmdy/segmdx, (i.e. same slope) - * or refdy * segmdx == segmdy * refdx - */ - if( is_colinear == false ) - { - if( ( double)refdy * segmdx != (double)refdx * segmdy ) - return NULL; - - is_colinear = true; - } + // Weed out non-parallel tracks + if ( !parallelism_test( aTrackRef->GetEnd().x - aTrackRef->GetStart().x, + aTrackRef->GetEnd().y - aTrackRef->GetStart().y, + aCandidate->GetEnd().x - aCandidate->GetStart().x, + aCandidate->GetEnd().y - aCandidate->GetStart().y ) ) + return NULL; /* Here we have 2 aligned segments: * We must change the pt_ref common point only if not on a pad * (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 + * and if this point is not on a pad, it can be removed and the 2 segments will be merged */ if( aEndType == ENDPOINT_START ) { diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index ec1da8e310..27262d6f38 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -173,7 +173,7 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) Clear_Pcb( true ); // Clear footprint library table for the new board. - FootprintLibs()->Clear(); + Prj().PcbFootprintLibs()->Clear(); wxFileName fn; @@ -603,7 +603,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF return false; // Save the project specific footprint library table. - if( !FootprintLibs()->IsEmpty( false ) ) + if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) { wxString fp_lib_tbl = Prj().FootprintLibTblName(); @@ -613,7 +613,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF { try { - FootprintLibs()->Save( fp_lib_tbl ); + Prj().PcbFootprintLibs()->Save( fp_lib_tbl ); } catch( const IO_ERROR& ioe ) { diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index 487f356e6a..c55cad44b5 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -469,7 +469,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() { wxString nickname = getLibNickName(); - if( !FootprintLibs()->IsFootprintLibWritable( nickname ) ) + if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) ) { wxString msg = wxString::Format( _( "Library '%s' is read only" ), @@ -481,7 +481,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() } wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, - wxEmptyString, wxEmptyString, FootprintLibs() ); + wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() ); if( !fpid_txt ) return false; @@ -497,7 +497,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() try { - FootprintLibs()->FootprintDelete( nickname, fpname ); + Prj().PcbFootprintLibs()->FootprintDelete( nickname, fpname ); } catch( const IO_ERROR& ioe ) { @@ -545,22 +545,24 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly ) try { + FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); + // Delete old library if we're replacing it entirely. if( !aNewModulesOnly ) { - FootprintLibs()->FootprintLibDelete( nickname ); - FootprintLibs()->FootprintLibCreate( nickname ); + tbl->FootprintLibDelete( nickname ); + tbl->FootprintLibCreate( nickname ); for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { - FootprintLibs()->FootprintSave( nickname, m, true ); + tbl->FootprintSave( nickname, m, true ); } } else { for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { - FootprintLibs()->FootprintSave( nickname, m, false ); + tbl->FootprintSave( nickname, m, false ); // Check for request to stop backup (ESCAPE key actuated) if( m_canvas->GetAbortRequest() ) @@ -627,7 +629,9 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, try { - MODULE* m = FootprintLibs()->FootprintLoad( aLibrary, footprintName ); + FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); + + MODULE* m = tbl->FootprintLoad( aLibrary, footprintName ); if( m ) { @@ -653,7 +657,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, // this always overwrites any existing footprint, but should yell on its // own if the library or footprint is not writable. - FootprintLibs()->FootprintSave( aLibrary, aModule ); + tbl->FootprintSave( aLibrary, aModule ); } catch( const IO_ERROR& ioe ) { @@ -738,7 +742,7 @@ wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting ) headers.Add( _( "Nickname" ) ); headers.Add( _( "Description" ) ); - FP_LIB_TABLE* fptbl = FootprintLibs(); + FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); std::vector< wxArrayString > itemsToDisplay; std::vector< wxString > nicknames = fptbl->GetLogicalLibs(); diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 6e66b00c55..cd3f85d00d 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -135,7 +135,7 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser() wxString fpid; - viewer->ShowModal( &fpid ); + viewer->ShowModal( &fpid, this ); //DBG(printf("%s: fpid:'%s'\n", __func__, TO_UTF8( fpid ) );) @@ -274,7 +274,6 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, module->SetTimeStamp( GetNewTimeStamp() ); GetBoard()->m_Status_Pcb = 0; - // Put it on FRONT layer, // (Can be stored flipped if the lib is an archive built from a board) if( module->IsFlipped() ) @@ -316,7 +315,7 @@ MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId ) MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) throw( IO_ERROR, PARSE_ERROR ) { - FP_LIB_TABLE* fptbl = FootprintLibs(); + FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) ); diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 26e6ca7fde..81b74eebe7 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -491,7 +491,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) Clear_Pcb( true ); SetCrossHairPosition( wxPoint( 0, 0 ) ); - LoadModuleFromLibrary( getLibNickName(), FootprintLibs(), true ); + LoadModuleFromLibrary( getLibNickName(), Prj().PcbFootprintLibs(), true ); redraw = true; if( GetBoard()->m_Modules ) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 076dc14999..4ef660f343 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -31,7 +31,7 @@ #include #include -//#include +#include #include #include #include @@ -50,7 +50,6 @@ #include #include #include -#include static PCB_SCREEN* s_screenModule; // the PCB_SCREEN used by the footprint editor @@ -275,7 +274,7 @@ wxString FOOTPRINT_EDIT_FRAME::getLibPath() { const wxString& nickname = getLibNickName(); - const FP_LIB_TABLE::ROW* row = FootprintLibs()->FindRow( nickname ); + const FP_LIB_TABLE::ROW* row = Prj().PcbFootprintLibs()->FindRow( nickname ); return row->GetFullURI( true ); } @@ -296,7 +295,8 @@ BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const { // get the BOARD_DESIGN_SETTINGS from the parent editor, not our BOARD. - PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent(); + // @todo(DICK) change the routing to some default or the board directly, parent may not exist + PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true ); wxASSERT( parentFrame ); @@ -308,7 +308,8 @@ void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSett { // set the BOARD_DESIGN_SETTINGS into parent editor, not our BOARD. - PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent(); + // @todo(DICK) change the routing to some default or the board directly, parent may not exist + PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true ); wxASSERT( parentFrame ); @@ -320,7 +321,8 @@ const PCB_PLOT_PARAMS& FOOTPRINT_EDIT_FRAME::GetPlotSettings() const { // get the settings from the parent editor, not our BOARD. - PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent(); + // @todo(DICK) change the routing to some default or the board directly, parent may not exist + PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true ); wxASSERT( parentFrame ); @@ -332,7 +334,8 @@ void FOOTPRINT_EDIT_FRAME::SetPlotSettings( const PCB_PLOT_PARAMS& aSettings ) { // set the settings into parent editor, not our BOARD. - PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent(); + // @todo(DICK) change the routing to some default or the board directly, parent may not exist + PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true ); wxASSERT( parentFrame ); @@ -478,7 +481,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent ) { - FP_LIB_TABLE* fptbl = FootprintLibs(); + FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); aEvent.Enable( fptbl && !fptbl->IsEmpty() ); } @@ -618,7 +621,7 @@ void FOOTPRINT_EDIT_FRAME::updateTitle() { try { - bool writable = FootprintLibs()->IsFootprintLibWritable( nickname ); + bool writable = Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ); // no exception was thrown, this means libPath is valid, but it may be read only. title = _( "Module Editor (active library: " ) + nickname + wxT( ")" ); diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 1bcbd5fcd5..dc24cf3208 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -309,7 +309,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList() { m_libList->Clear(); - std::vector< wxString > nicknames = FootprintLibs()->GetLogicalLibs(); + std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs(); for( unsigned ii = 0; ii < nicknames.size(); ii++ ) m_libList->Append( nicknames[ii] ); @@ -348,7 +348,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() FOOTPRINT_LIST fp_info_list; - fp_info_list.ReadFootprintFiles( FootprintLibs(), &m_libraryName ); + fp_info_list.ReadFootprintFiles( Prj().PcbFootprintLibs(), &m_libraryName ); if( fp_info_list.GetErrorCount() ) { @@ -509,7 +509,7 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event ) m_selectedFootprintName.Empty(); // Ensure we have the right library list: - std::vector< wxString > libNicknames = FootprintLibs()->GetLogicalLibs(); + std::vector< wxString > libNicknames = Prj().PcbFootprintLibs()->GetLogicalLibs(); if( libNicknames.size() == m_libList->GetCount() ) { @@ -742,13 +742,16 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event ) { +#if 0 // cannot remember why this is here // The PCB_EDIT_FRAME may not be the FOOTPRINT_VIEW_FRAME's parent, // so use Kiway().Player() to fetch. PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, true ); + (void*) parent; +#endif wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension; MODULE* oldmodule = GetBoard()->m_Modules; - MODULE* module = LoadModuleFromLibrary( libname, parent->FootprintLibs(), false ); + MODULE* module = LoadModuleFromLibrary( libname, Prj().PcbFootprintLibs(), false ); if( module ) { @@ -808,7 +811,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode ) // Delete the current footprint GetBoard()->m_Modules.DeleteAll(); - MODULE* footprint = FootprintLibs()->FootprintLoad( m_libraryName, m_footprintName ); + MODULE* footprint = Prj().PcbFootprintLibs()->FootprintLoad( m_libraryName, m_footprintName ); if( footprint ) GetBoard()->Add( footprint, ADD_APPEND ); diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index 45fe7c7b03..bb840c658f 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -192,7 +192,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) MODULE* module = 0; MODULE* fpOnBoard; - if( aNetlist.IsEmpty() || FootprintLibs()->IsEmpty() ) + if( aNetlist.IsEmpty() || Prj().PcbFootprintLibs()->IsEmpty() ) return; aNetlist.SortByFPID(); diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index f4a6024c90..dc5b0b97ee 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -355,7 +356,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { m_canvas->MoveCursorToCrossHair(); DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary( - wxEmptyString, FootprintLibs(), true, aDC ); + wxEmptyString, Prj().PcbFootprintLibs(), true, aDC ); SetCurItem( DrawStruct ); diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index df8df9fcc3..00452262ce 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -96,7 +96,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) case ID_PCB_LIB_TABLE_EDIT: { bool tableChanged = false; - int r = InvokePcbLibTableEditor( this, &GFootprintTable, FootprintLibs() ); + int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() ); if( r & 1 ) { @@ -126,7 +126,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) try { - FootprintLibs()->Save( tblName ); + Prj().PcbFootprintLibs()->Save( tblName ); tableChanged = true; } catch( const IO_ERROR& ioe ) @@ -259,18 +259,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName ) SetElementVisibility( RATSNEST_VISIBLE, showRats ); #endif - wxString projectFpLibTableFileName = Prj().FootprintLibTblName(); - - FootprintLibs()->Clear(); - - try - { - FootprintLibs()->Load( projectFpLibTableFileName ); - } - catch( const IO_ERROR& ioe ) - { - DisplayError( this, ioe.errorText ); - } + Prj().ElemClear( PROJECT::ELEM_FPTBL ); // Force it to be reloaded on demand. // Load the page layout decr file, from the filename stored in // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 34af899d35..c9a5467583 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -27,6 +27,7 @@ #include "common_actions.h" #include +#include #include #include #include @@ -711,7 +712,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { // Init the new item attributes module = m_frame->LoadModuleFromLibrary( wxEmptyString, - m_frame->FootprintLibs(), + m_frame->Prj().PcbFootprintLibs(), true, NULL ); if( module == NULL ) continue; diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index 9f3c31f404..7fafc6a914 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -492,7 +493,7 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) wxString newname; newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString, - m_parent->FootprintLibs() ); + Prj().PcbFootprintLibs() ); if( newname != wxEmptyString ) m_NewModule->SetValue( newname ); diff --git a/scripts/bom-in-python/round_value_robin.py b/scripts/bom-in-python/round_value_robin.py index 536f5a1239..028312fc2a 100644 --- a/scripts/bom-in-python/round_value_robin.py +++ b/scripts/bom-in-python/round_value_robin.py @@ -30,7 +30,7 @@ def checkvalue(self): if v.isdigit(): i = int(v) if (i > 1000000): - i = i / 100000 + i = i / 1000000 v = str(i) + "M" if (i > 1000): i = i / 1000 diff --git a/scripts/kicad-install.sh b/scripts/kicad-install.sh index d5e9877926..7ddd906881 100755 --- a/scripts/kicad-install.sh +++ b/scripts/kicad-install.sh @@ -34,6 +34,17 @@ # Set where the 3 source trees will go, use a full path WORKING_TREES=~/kicad_sources +STABLE=tag:pre-kiway # currently the best mix of features and stabilty +TESTING=last:1 # the most recent + + +# Set this to STABLE or TESTING or other known revision number: +REVISION=$STABLE + +# For info on revision syntax: +# $ bzr help revisionspec + + # CMake Options #OPTS="$OPTS -DBUILD_GITHUB_PLUGIN=OFF" @@ -45,9 +56,6 @@ WORKING_TREES=~/kicad_sources # https results in read only access. REPOS=https://code.launchpad.net -# This is no longer maintained, is old -#LEGACY_LIB_REPO=$REPOS/~dickelbeck/kicad/library-read-only - # This branch is a bzr/launchpad import of the Git repository # at https://github.com/KiCad/kicad-library.git. # It has schematic parts and 3D models in it. @@ -212,11 +220,11 @@ install_or_update() echo "step 3) checking out the source code from launchpad repo..." if [ ! -d "$WORKING_TREES/kicad.bzr" ]; then - bzr checkout $SRCS_REPO kicad.bzr + bzr checkout -r $REVISION $SRCS_REPO kicad.bzr echo " source repo to local working tree." else cd kicad.bzr - bzr up + bzr up -r $REVISION echo " local source working tree updated." cd ../ fi