From 0ff0b9b835dd3e721dd77b80cd5b59ea4b3e9902 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 May 2014 08:28:40 +0200 Subject: [PATCH 01/10] Fix issue in bga footprint wizard. --- pcbnew/scripting/plugins/PadArray.py | 9 +++++---- pcbnew/scripting/plugins/bga_wizard.py | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pcbnew/scripting/plugins/PadArray.py b/pcbnew/scripting/plugins/PadArray.py index 99fa70e0dc..3c5d5f7cb1 100644 --- a/pcbnew/scripting/plugins/PadArray.py +++ b/pcbnew/scripting/plugins/PadArray.py @@ -75,13 +75,14 @@ class PadGridArray(PadArray): # handy utility function 1 - A, 2 - B, 26 - AA, etc # aIndex = 0 for 0 - A - def AlphaNameFromNumber(self, n, aIndex = 1): + # alphabet = set of allowable chars if not A-Z, eg ABCDEFGHJKLMNPRTUVWY for BGA + def AlphaNameFromNumber(self, n, aIndex = 1, alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"): - div, mod = divmod(n - aIndex, 26) - alpha = chr(65 + mod) + div, mod = divmod(n - aIndex, len(alphabet)) + alpha = alphabet[mod] if div > 0: - return self.AlphaNameFromNumber(div) + alpha; + return self.AlphaNameFromNumber(div, aIndex, alphabet) + alpha; return alpha; diff --git a/pcbnew/scripting/plugins/bga_wizard.py b/pcbnew/scripting/plugins/bga_wizard.py index 7fd6258f3e..9b68b48ef6 100644 --- a/pcbnew/scripting/plugins/bga_wizard.py +++ b/pcbnew/scripting/plugins/bga_wizard.py @@ -24,7 +24,7 @@ import PadArray as PA class BGAPadGridArray(PA.PadGridArray): def NamingFunction(self, x, y): - return "%s%d" % (self.AlphaNameFromNumber(y + 1), x + 1) + return "%s%d" % (self.AlphaNameFromNumber(y + 1, alphabet="ABCDEFGHJKLMNPRTUVWY"), x + 1) class BGAWizard(HFPW.HelpfulFootprintWizardPlugin): @@ -76,10 +76,10 @@ class BGAWizard(HFPW.HelpfulFootprintWizardPlugin): # 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) + pin1Pos = pcbnew.wxPoint(-((cols - 1) * pad_pitch) / 2, + -((rows - 1) * pad_pitch) / 2) - array = BGAPadGridArray(pad, rows, cols, pad_pitch, pad_pitch, pin1Pos) + array = BGAPadGridArray(pad, cols, rows, pad_pitch, pad_pitch, pin1Pos) array.AddPadsToModule() #box From c698a1da24492d1314cf7e40330f8362192efe75 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 2 May 2014 19:56:24 +0200 Subject: [PATCH 02/10] Eeschema: fix unwanted creation of noname.pro (or other useless config file), when opening eeschema. Fix also an issue when saving the config (from save config menu) which saved the config file in an unknow folder. --- common/project.cpp | 22 ++++++++++++++-------- eeschema/eeschema.cpp | 1 - eeschema/eeschema_config.cpp | 8 ++++---- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/common/project.cpp b/common/project.cpp index df43e60a5e..df31c81c1b 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -60,9 +60,9 @@ void PROJECT::SetProjectFullName( const wxString& aFullPathAndName ) wxASSERT( m_project_name.GetName() == NAMELESS_PROJECT || m_project_name.IsAbsolute() ); #if 0 - wxASSERT( m_project_name.GetExt() == wxT( ".pro" ) ) + wxASSERT( m_project_name.GetExt() == ProjectFileExtension ) #else - m_project_name.SetExt( wxT( ".pro" ) ); + m_project_name.SetExt( ProjectFileExtension ); #endif // until multiple projects are in play, set an environment variable for the @@ -269,19 +269,21 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& // No suitable pro file was found, either does not exist, or is too old. // Use the template kicad.pro file. Find it by using caller's SEARCH_STACK. - - wxString kicad_pro_template = aSList.FindValidPath( wxT( "kicad.pro" ) ); + wxString templateFile = wxT( "kicad." ) + ProjectFileExtension; + wxString kicad_pro_template = aSList.FindValidPath( templateFile ); if( !kicad_pro_template ) { - wxLogDebug( wxT( "Template file not found using search paths." ) ); + wxLogDebug( wxT( "Template file <%s> not found using search paths." ), + GetChars( templateFile ) ); wxFileName templ( wxStandardPaths::Get().GetDocumentsDir(), wxT( "kicad" ), ProjectFileExtension ); if( !templ.IsFileReadable() ) { - wxString msg = wxString::Format( _( "Unable to find kicad.pro template file." ) ); + wxString msg = wxString::Format( _( "Unable to find %s template config file." ), + GetChars( templateFile ) ); DisplayError( NULL, msg ); @@ -291,8 +293,12 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& kicad_pro_template = templ.GetFullPath(); } - // copy the template to cur_pro_fn, and open it at that destination. - wxCopyFile( kicad_pro_template, cur_pro_fn ); + // The project config file is not found (happens for new projects, + // or if the schematic editor is run outside an existing project + // In this case the default template (kicad.pro) is used + cur_pro_fn = kicad_pro_template; + wxLogDebug( wxT( "Use template file '%s' as project file." ), GetChars( cur_pro_fn ) ); + cfg = new wxFileConfig( wxEmptyString, wxEmptyString, cur_pro_fn, wxEmptyString ); cfg->DontCreateOnDemand(); diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index fafcd90ac5..c5e1432036 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -40,7 +40,6 @@ #include #include -//#include #include #include #include diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index ee091ae82c..caa3b2782b 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -139,7 +139,7 @@ void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) switch( id ) { case ID_CONFIG_SAVE: - schFrame->SaveProjectSettings( false ); + schFrame->SaveProjectSettings( true ); break; case ID_CONFIG_READ: @@ -205,7 +205,7 @@ void SCH_EDIT_FRAME::Process_Config( wxCommandEvent& event ) switch( id ) { case ID_CONFIG_SAVE: - SaveProjectSettings( false ); + SaveProjectSettings( true ); break; case ID_CONFIG_READ: @@ -456,8 +456,8 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) if( aAskForSave ) { wxFileDialog dlg( this, _( "Save Project File" ), - fn.GetPath(), fn.GetFullName(), - ProjectFileWildcard, wxFD_SAVE | wxFD_CHANGE_DIR ); + fn.GetPath(), fn.GetFullPath(), + ProjectFileWildcard, wxFD_SAVE ); if( dlg.ShowModal() == wxID_CANCEL ) return; From 25d1ab4008a20bc44e011a910783b68d002d09af Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 3 May 2014 12:40:19 -0500 Subject: [PATCH 03/10] Modular-Kicad milestone B), major portions: *) Rework the set language support, simplify it by using KIWAY. Now any major frame with a "change language" menu can change the language for all KIWAY_PLAYERs in the whole KIWAY. Multiple KIWAYs are not supported yet. *) Simplify "modal wxFrame" support, and add that support exclusively to KIWAY_PLAYER where it is inherited by all derivatives. The function KIWAY_PLAYER::ShowModal() is in the vtable and so is cross module capable. *) Remove the requirements and assumptions that the wxFrame hierarchy always had PCB_EDIT_FRAME and SCH_EDIT_FRAME as immediate parents of their viewers and editors. This is no longer the case, nor required. *) Use KIWAY::Player() everywhere to make KIWAY_PLAYERs, this registers the KIWAY_PLAYER within the KIWAY and makes it very easy to find an open frame quickly. It also gives control to the KIWAY as to frame hierarchical relationships. *) Change single_top to use the KIWAY for loading a KIFACE and instantiating the single KIWAY_PLAYER, see bullet immediately above. *) Add KIWAY::OnKiwayEnd() and call it from PGM_BASE at program termination, this gives the KIFACEs a chance to save their final configuration dope to disk. *) Add dedicated FRAME_T's for the modal frames, so m_Ident can be tested and these modal frames are distinctly different than their non-modal equivalents. KIWAY_PLAYER::IsModal() is !not! a valid test during the wxFrame's constructor, so this is another important reason for having a dedicated FRAME_T for each modal wxFrame. On balance, more lines were deleted than were added to achieve all this. --- bitmap2component/CMakeLists.txt | 2 +- common/basicframe.cpp | 30 +---- common/colors.cpp | 1 + common/draw_frame.cpp | 6 - common/fpid.cpp | 41 +++---- common/kiway.cpp | 99 +++++++++++++--- common/kiway_player.cpp | 148 +++++++++++++++++++++--- common/pgm_base.cpp | 2 +- common/single_top.cpp | 128 +++----------------- cvpcb/cvframe.cpp | 8 -- cvpcb/cvpcb_mainframe.h | 6 - eeschema/block_libedit.cpp | 2 +- eeschema/eeschema.cpp | 10 ++ eeschema/eeschema_config.cpp | 31 ++--- eeschema/getpart.cpp | 24 ++-- eeschema/libeditframe.cpp | 74 +++++------- eeschema/libeditframe.h | 13 --- eeschema/sch_base_frame.cpp | 9 +- eeschema/schedit.cpp | 2 +- eeschema/schframe.cpp | 51 ++++---- eeschema/sheet.cpp | 2 +- eeschema/tool_viewlib.cpp | 4 +- eeschema/viewlib_frame.cpp | 113 +++++++++--------- eeschema/viewlib_frame.h | 27 ++--- gerbview/events_called_functions.cpp | 41 +++---- gerbview/gerbview_frame.h | 6 +- include/draw_frame.h | 7 -- include/fpid.h | 20 ++-- include/frame_type.h | 23 +++- include/kiface_i.h | 2 +- include/kiway.h | 59 +++++++--- include/kiway_player.h | 57 ++++++++- include/wxEeschemaStruct.h | 6 - include/wxPcbStruct.h | 6 +- include/wxstruct.h | 23 +--- kicad/kicad.cpp | 4 +- kicad/kicad.h | 3 +- kicad/mainframe.cpp | 8 ++ kicad/menubar.cpp | 19 +-- kicad/preferences.cpp | 5 - pagelayout_editor/events_functions.cpp | 17 +-- pagelayout_editor/pl_editor_frame.h | 6 - pcb_calculator/CMakeLists.txt | 3 +- pcb_calculator/pcb_calculator_frame.cpp | 1 + pcbnew/block_module_editor.cpp | 2 +- pcbnew/edit.cpp | 28 ++--- pcbnew/editmod.cpp | 12 +- pcbnew/footprint_wizard.cpp | 2 +- pcbnew/footprint_wizard_frame.cpp | 58 +++------- pcbnew/footprint_wizard_frame.h | 28 ++--- pcbnew/gpcb_plugin.cpp | 3 +- pcbnew/kicad_plugin.cpp | 6 +- pcbnew/librairi.cpp | 2 +- pcbnew/loadcmp.cpp | 27 ++--- pcbnew/modedit.cpp | 70 +++++------ pcbnew/module_editor_frame.h | 13 +-- pcbnew/moduleframe.cpp | 15 +-- pcbnew/modview_frame.cpp | 116 +++++++++---------- pcbnew/modview_frame.h | 42 +++---- pcbnew/pcbframe.cpp | 12 +- pcbnew/pcbnew.cpp | 25 ++-- pcbnew/pcbnew_config.cpp | 2 +- pcbnew/tool_modview.cpp | 5 +- 63 files changed, 769 insertions(+), 848 deletions(-) diff --git a/bitmap2component/CMakeLists.txt b/bitmap2component/CMakeLists.txt index 5bf7debd48..489ff8f3f1 100644 --- a/bitmap2component/CMakeLists.txt +++ b/bitmap2component/CMakeLists.txt @@ -14,7 +14,7 @@ set( BITMAP2COMPONENT_SRCS ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=0" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_BM2CMP" ) set_source_files_properties( bitmap2cmp_gui.cpp PROPERTIES COMPILE_DEFINITIONS "COMPILING_DLL" diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 91a5c0b4ee..37be1fd12c 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -169,12 +169,8 @@ void EDA_BASE_FRAME::ReCreateMenuBar() } -void EDA_BASE_FRAME::SetLanguage( wxCommandEvent& event ) +void EDA_BASE_FRAME::ShowChangedLanguage() { - int id = event.GetId(); - - Pgm().SetLanguageIdentifier( id ); - Pgm().SetLanguage(); ReCreateMenuBar(); GetMenuBar()->Refresh(); } @@ -717,27 +713,3 @@ void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName, } } - -void EDA_BASE_FRAME::SetModalMode( bool aModal ) -{ - // Disable all other windows -#if wxCHECK_VERSION(2, 9, 4) - if( IsTopLevel() ) - { - wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); - - while( node ) - { - wxWindow* win = node->GetData(); - - if( win != this ) - win->Enable( !aModal ); - - node = node->GetNext(); - } - } -#else - // Deprecated since wxWidgets 2.9.4 - MakeModal( aModal ); -#endif -} diff --git a/common/colors.cpp b/common/colors.cpp index ca12867b6e..9016840865 100644 --- a/common/colors.cpp +++ b/common/colors.cpp @@ -122,6 +122,7 @@ EDA_COLOR_T ColorMix( EDA_COLOR_T aColor1, EDA_COLOR_T aColor2 ) // First easy thing: a black gives always the other colour if( aColor1 == BLACK ) return aColor2; + if( aColor2 == BLACK) return aColor1; diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 75461e5f22..a79503edd3 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -556,12 +556,6 @@ bool EDA_DRAW_FRAME::HandleBlockEnd( wxDC* DC ) } -void EDA_DRAW_FRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_BASE_FRAME::SetLanguage( event ); -} - - void EDA_DRAW_FRAME::UpdateStatusBar() { wxString Line; diff --git a/common/fpid.cpp b/common/fpid.cpp index ef9f35b89f..025b7b57e4 100644 --- a/common/fpid.cpp +++ b/common/fpid.cpp @@ -62,6 +62,7 @@ const char* EndsWithRev( const char* start, const char* tail, char separator ) } +#if 0 // Not used int RevCmp( const char* s1, const char* s2 ) { int r = strncmp( s1, s2, 3 ); @@ -76,6 +77,7 @@ int RevCmp( const char* s1, const char* s2 ) return -(rnum1 - rnum2); // swap the sign, higher revs first } +#endif //----------------------------------------- @@ -116,7 +118,7 @@ void FPID::clear() } -int FPID::Parse( const std::string& aId ) +int FPID::Parse( const UTF8& aId ) { clear(); @@ -171,12 +173,6 @@ int FPID::Parse( const std::string& aId ) } -int FPID::Parse( const wxString& aId ) -{ - return Parse( std::string( TO_UTF8( aId ) ) ); -} - - FPID::FPID( const std::string& aId ) throw( PARSE_ERROR ) { int offset = Parse( aId ); @@ -194,14 +190,14 @@ FPID::FPID( const std::string& aId ) throw( PARSE_ERROR ) FPID::FPID( const wxString& aId ) throw( PARSE_ERROR ) { - std::string id = TO_UTF8( aId ); + UTF8 id = aId; int offset = Parse( id ); if( offset != -1 ) { THROW_PARSE_ERROR( _( "Illegal character found in FPID string" ), - wxString::FromUTF8( id.c_str() ), + aId, id.c_str(), 0, offset ); @@ -209,7 +205,7 @@ FPID::FPID( const wxString& aId ) throw( PARSE_ERROR ) } -int FPID::SetLibNickname( const std::string& aLogical ) +int FPID::SetLibNickname( const UTF8& aLogical ) { int offset = okLogical( aLogical ); @@ -222,15 +218,9 @@ int FPID::SetLibNickname( const std::string& aLogical ) } -int FPID::SetLibNickname( const wxString& aLogical ) +int FPID::SetFootprintName( const UTF8& aFootprintName ) { - return SetLibNickname( std::string( TO_UTF8( aLogical ) ) ); -} - - -int FPID::SetFootprintName( const std::string& aFootprintName ) -{ - int separation = int( aFootprintName.find_first_of( "/" ) ); + int separation = int( aFootprintName.find_first_of( "/" ) ); if( separation != -1 ) { @@ -246,13 +236,7 @@ int FPID::SetFootprintName( const std::string& aFootprintName ) } -int FPID::SetFootprintName( const wxString& aFootprintName ) -{ - return SetFootprintName( std::string( TO_UTF8( aFootprintName ) ) ); -} - - -int FPID::SetRevision( const std::string& aRevision ) +int FPID::SetRevision( const UTF8& aRevision ) { int offset = okRevision( aRevision ); @@ -301,8 +285,10 @@ UTF8 FPID::GetFootprintNameAndRev() const } -UTF8 FPID::Format( const std::string& aLogicalLib, const std::string& aFootprintName, - const std::string& aRevision ) +#if 0 // this is broken, it does not output aFootprintName for some reason + +UTF8 FPID::Format( const UTF8& aLogicalLib, const UTF8& aFootprintName, + const UTF8& aRevision ) throw( PARSE_ERROR ) { UTF8 ret; @@ -344,6 +330,7 @@ UTF8 FPID::Format( const std::string& aLogicalLib, const std::string& aFootprint return ret; } +#endif int FPID::compare( const FPID& aFPID ) const diff --git a/common/kiway.cpp b/common/kiway.cpp index 13c0072a92..a599474f06 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -23,14 +23,16 @@ */ #include +#include +#include #include #include #include #include +#include #include -#include -#include +#include KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT]; @@ -38,22 +40,24 @@ int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; -KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): +KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ): m_program( aProgram ), + m_ctl( aCtlBits ), m_top( 0 ) { - SetTop( aTop ); // hook playerDestroyHandler() into aTop. + SetTop( aTop ); // hook player_destroy_handler() 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 originating from -// KIWAY_PLAYERs. It does anyways, but now playerDestroyHandler eavesdrops +// KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops // on that event stream looking for KIWAY_PLAYERs being closed. -void KIWAY::playerDestroyHandler( wxWindowDestroyEvent& event ) +void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event ) { wxWindow* w = event.GetWindow(); @@ -62,7 +66,7 @@ void KIWAY::playerDestroyHandler( 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: marking m_player[%d] as destroyed\n", __func__, i );) m_player[i] = 0; } } @@ -73,12 +77,12 @@ void KIWAY::SetTop( wxFrame* aTop ) { if( m_top ) { - m_top->Disconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + m_top->Disconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this ); } if( aTop ) { - aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this ); } m_top = aTop; @@ -91,13 +95,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_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. + 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: name = KIFACE_PREFIX wxT( "pcb_calculator" ); break; + case FACE_BMP2CMP: name = KIFACE_PREFIX wxT( "bitmap2component" ); break; default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); @@ -172,7 +176,7 @@ KIFACE* KIWAY::KiFACE( 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( m_program, KFCTL_PROJECT_SUITE ) ) + if( kiface->OnKifaceStart( m_program, m_ctl ) ) { // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. (void) dso.Detach(); @@ -214,12 +218,14 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType ) case FRAME_SCH: case FRAME_SCH_LIB_EDITOR: case FRAME_SCH_VIEWER: + case FRAME_SCH_VIEWER_MODAL: return FACE_SCH; case FRAME_PCB: case FRAME_PCB_MODULE_EDITOR: case FRAME_PCB_MODULE_VIEWER: - case FRAME_PCB_FOOTPRINT_WIZARD: + case FRAME_PCB_MODULE_VIEWER_MODAL: + case FRAME_PCB_FOOTPRINT_WIZARD_MODAL: case FRAME_PCB_DISPLAY3D: return FACE_PCB; @@ -233,6 +239,12 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType ) case FRAME_PL_EDITOR: return FACE_PL_EDITOR; + case FRAME_CALC: + return FACE_PCB_CALCULATOR; + + case FRAME_BM2CMP: + return FACE_BMP2CMP; + default: return FACE_T( -1 ); } @@ -266,7 +278,12 @@ 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 ); + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( + m_top, + aFrameType, + this, + m_ctl // questionable need, these same flags where passed to the KIFACE::OnKifaceStart() + ); wxASSERT( frame ); return m_player[aFrameType] = frame; @@ -327,6 +344,39 @@ void KIWAY::ExpressMail( FRAME_T aDestination, } +void KIWAY::SetLanguage( int aLanguage ) +{ + Pgm().SetLanguageIdentifier( aLanguage ); + Pgm().SetLanguage(); + +#if 1 + // This is a risky hack that goes away if we allow the language to be + // set only from the top most frame if !Kiface.IsSingle() + + // Only for the C++ project manager, and not for the python one and not for + // single_top do we look for the EDA_BASE_FRAME as the top level window. + // For single_top this is not needed because that window is registered in + // the array below. + if( m_ctl & KFCTL_CPP_PROJECT_SUITE ) + { + EDA_BASE_FRAME* top = (EDA_BASE_FRAME*) m_top; + if( top ) + top->ShowChangedLanguage(); + } +#endif + + for( unsigned i=0; i < DIM( m_player ); ++i ) + { + KIWAY_PLAYER* frame = m_player[i]; + + if( frame ) + { + frame->ShowChangedLanguage(); + } + } +} + + bool KIWAY::ProcessEvent( wxEvent& aEvent ) { KIWAY_EXPRESS* mail = dynamic_cast( &aEvent ); @@ -351,3 +401,14 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent ) return false; } + + +void KIWAY::OnKiwayEnd() +{ + for( unsigned i=0; i < DIM( m_kiface ); ++i ) + { + if( m_kiface[i] ) + m_kiface[i]->OnKifaceEnd(); + } +} + diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 427fdf3a51..31aca7d1d8 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -2,28 +2,26 @@ #include #include +#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. - - OK the problem is KIWAY_PLAYER::wxEVENT_ID not being unique accross all link images. - */ + EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KIWAY_PLAYER::language_change ) 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 ) + KIWAY_HOLDER( aKiway ), + m_modal_dismissed( 0 ) { DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) - Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); + //Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); } @@ -31,10 +29,125 @@ KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& a 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 ) + KIWAY_HOLDER( 0 ), + m_modal_dismissed( 0 ) { DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) - Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); + //Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +KIWAY_PLAYER::~KIWAY_PLAYER(){} + + +void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) +{ + // override this in derived classes. +} + + +static void makeModal( wxFrame* aFrame, bool IsModal ) +{ + // disable or enable all other top level windows +#if wxCHECK_VERSION(2, 9, 4) + wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); + + while( node ) + { + wxWindow* win = node->GetData(); + + if( win != aFrame ) + win->Enable( !IsModal ); + + node = node->GetNext(); + } +#else + // Deprecated since wxWidgets 2.9.4 + aFrame->MakeModal( IsModal ); +#endif +} + + +/** + * toggle global wxFrame enable/disable state, does the re-enable part even + * if an exception is thrown. + */ +struct ENABLE_DISABLE +{ + wxFrame* m_frame; + + ENABLE_DISABLE( wxFrame* aFrame ) : + m_frame( aFrame ) + { + makeModal( aFrame, true ); + } + + ~ENABLE_DISABLE() + { + // Re-enable all frames, (oops, even if they were previously inactive). + // This is probably why this function was deprecated in wx. + makeModal( m_frame, false ); + } +}; + + +bool KIWAY_PLAYER::ShowModal( wxString* aResult ) +{ + /* + This function has a nice interface but an unsightly implementation. + Now it is encapsulated, making it easier to improve. I am not sure + a wxSemaphore was needed, especially since no blocking happens. It seems + like a volatile bool is sufficient. + + It works in tandem with DismissModal(). But only ShowModal() is in the + vtable and therefore cross-module capable. + */ + + volatile bool dismissed = false; + + // disable all frames except the modal one, re-enable on exit, exception safe. + ENABLE_DISABLE toggle( this ); + + m_modal_dismissed = &dismissed; + + Show( true ); + Raise(); + + // Wait for the one and only active frame to call DismissModal() from + // some concluding event. + while( !dismissed ) + { + wxYield(); + wxMilliSleep( 50 ); + } + + // no longer modal, not to mention that the pointer would be invalid outside this scope. + m_modal_dismissed = NULL; + + if( aResult ) + *aResult = m_modal_string; + + return m_modal_ret_val; +} + + +bool KIWAY_PLAYER::IsDismissed() +{ + // if already dismissed, then m_modal_dismissed may be NULL, and if not, + // it can still be dismissed if the bool is true. + bool ret = !m_modal_dismissed || *m_modal_dismissed; + + return ret; +} + + +void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult ) +{ + m_modal_ret_val = aRetVal; + m_modal_string = aResult; + + if( m_modal_dismissed ) + *m_modal_dismissed = true; } @@ -42,17 +155,20 @@ void KIWAY_PLAYER::kiway_express( KIWAY_EXPRESS& aEvent ) { // logging support #if defined(DEBUG) - const char* class_name = typeid(this).name(); + const char* class_name = typeid( this ).name(); - printf( "%s: cmd:%d pay:'%s'\n", class_name, - aEvent.GetEventType(), aEvent.GetPayload().c_str() ); + printf( "%s: received cmd:%d pay:'%s'\n", class_name, + aEvent.Command(), aEvent.GetPayload().c_str() ); #endif - KiwayMailIn( aEvent ); // call the virtual, overload in derived. + KiwayMailIn( aEvent ); // call the virtual, override in derived. } -void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) +void KIWAY_PLAYER::language_change( wxCommandEvent& event ) { - // overload this. + int id = event.GetId(); + + // tell all the KIWAY_PLAYERs about the language change. + Kiway().SetLanguage( id ); } diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 1789f939ed..d7f923676c 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -622,7 +622,7 @@ bool PGM_BASE::SetLanguage( bool first_time ) void PGM_BASE::SetLanguageIdentifier( int menu_id ) { - wxLogDebug( wxT( "Select language ID %d from %zd possible languages." ), + wxLogDebug( wxT( "Select language ID %d from %d possible languages." ), menu_id, DIM( s_Languages ) ); for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ ) diff --git a/common/single_top.cpp b/common/single_top.cpp index 2632a32eae..7d7c816590 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. -KIWAY Kiway( &Pgm() ); +KIWAY Kiway( &Pgm(), KFCTL_STANDALONE ); // implement a PGM_BASE and a wxApp side by side: @@ -225,82 +225,6 @@ struct APP_SINGLE_TOP : public wxApp IMPLEMENT_APP( APP_SINGLE_TOP ); -/** - * Function get_kiface_getter - * returns a KIFACE_GETTER_FUNC for the current process's main implementation - * link image. - * - * @param aDSOName is an absolute full path to the DSO to load and find - * KIFACE_GETTER_FUNC within. - * - * @return KIFACE_GETTER_FUNC* - a pointer to a function which can be called to - * get the KIFACE or NULL if the getter func was not found. If not found, - * it is possibly not version compatible since the lookup is done by name and - * the name contains the API version. - */ -static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName ) -{ -#if defined(BUILD_KIWAY_DLL) - - // Remember single_top only knows about a single DSO. Using an automatic - // with a defeated destructor, see Detach() below, so that the DSO program - // image stays in RAM until process termination, and specifically - // beyond the point in time at which static destructors are run. Otherwise - // a static wxDynamicLibrary's destructor might create an out of sequence - // problem. This was never detected, so it's only a preventative strategy. - wxDynamicLibrary dso; - - void* addr = NULL; - - if( !dso.Load( aDSOName, wxDL_VERBATIM | wxDL_NOW ) ) - { - // 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 - { - // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. - (void) dso.Detach(); - - 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; - -#endif -} - - -static KIFACE* kiface; -static int kiface_version; - - - bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) { // first thing: set m_wx_app @@ -321,44 +245,27 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) if( !initPgm() ) return false; - wxString dname = dso_full_path( absoluteArgv0 ); +#if !defined(BUILD_KIWAY_DLL) + // Get the getter, it is statically linked into this binary image. + KIFACE_GETTER_FUNC* getter = &KIFACE_GETTER; - // Get the getter. - KIFACE_GETTER_FUNC* getter = get_kiface_getter( dname ); - - if( !getter ) - { - // get_kiface_getter() failed & already showed the UI message. - // Return failure without any further UI. - return false; - } + int kiface_version; // Get the KIFACE. - kiface = getter( &kiface_version, KIFACE_VERSION, this ); + KIFACE* kiface = getter( &kiface_version, KIFACE_VERSION, this ); - // 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( this, KFCTL_STANDALONE ) ) - return false; - - // 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 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 ) ); -#else - KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( - NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ); + // Trick the KIWAY into thinking it loaded a KIFACE, by recording the KIFACE + // in the KIWAY. It needs to be there for KIWAY::OnKiwayEnd() anyways. + Kiway.set_kiface( KIWAY::KifaceType( TOP_FRAME ), kiface ); #endif + // Use KIWAY to create a top window, which registers its existence also. + // "TOP_FRAME" is a macro that is passed on compiler command line from CMake, + // and is one of the types in FRAME_T. + KIWAY_PLAYER* frame = Kiway.Player( TOP_FRAME, true ); + + Kiway.SetTop( frame ); + App().SetTopWindow( frame ); // wxApp gets a face. // Open project or file specified on the command line: @@ -454,8 +361,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) void PGM_SINGLE_TOP::OnPgmExit() { - if( kiface ) - kiface->OnKifaceEnd(); + Kiway.OnKiwayEnd(); saveCommonSettings(); diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 74b79b3567..3ffd306b7d 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -76,8 +76,6 @@ BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME ) EVT_MENU( ID_CVPCB_LIB_TABLE_EDIT, CVPCB_MAINFRAME::OnEditFootprintLibraryTable ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, CVPCB_MAINFRAME::SetLanguage ) - // Toolbar events EVT_TOOL( ID_CVPCB_QUIT, CVPCB_MAINFRAME::OnQuit ) EVT_TOOL( ID_CVPCB_READ_INPUT_NETLIST, CVPCB_MAINFRAME::LoadNetList ) @@ -558,12 +556,6 @@ void CVPCB_MAINFRAME::DisplayModule( wxCommandEvent& event ) } -void CVPCB_MAINFRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_BASE_FRAME::SetLanguage( event ); -} - - void CVPCB_MAINFRAME::DisplayDocFile( wxCommandEvent& event ) { GetAssociatedDocument( this, m_DocModulesFileName, &Kiface().KifaceSearch() ); diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index 8cd8f5c322..3993091dda 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -123,12 +123,6 @@ public: void ChangeFocus( bool aMoveRight ); - /** - * Function SetLanguage - * is called on a language menu selection. - */ - void SetLanguage( wxCommandEvent& event ); - void ToFirstNA( wxCommandEvent& event ); void ToPreviousNA( wxCommandEvent& event ); diff --git a/eeschema/block_libedit.cpp b/eeschema/block_libedit.cpp index e9c89d14f5..abf7fc66ed 100644 --- a/eeschema/block_libedit.cpp +++ b/eeschema/block_libedit.cpp @@ -321,7 +321,7 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& wxPoint move_offset; block = &screen->m_BlockLocate; - LIB_EDIT_FRAME* parent = ( LIB_EDIT_FRAME* ) aPanel->GetParent(); + LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent(); wxASSERT( parent != NULL ); LIB_COMPONENT* component = parent->GetComponent(); diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index c5e1432036..911c1d138d 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,15 @@ static struct IFACE : public KIFACE_I } break; + + case FRAME_SCH_VIEWER: + case FRAME_SCH_VIEWER_MODAL: + { + LIB_VIEW_FRAME* frame = new LIB_VIEW_FRAME( aKiway, aParent, FRAME_T( aClassId ) ); + return frame; + } + break; + default: return NULL; } diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index caa3b2782b..2a0cccf33b 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -118,7 +118,10 @@ EDA_COLOR_T GetInvisibleItemColor() void LIB_EDIT_FRAME::InstallConfigFrame( wxCommandEvent& event ) { - InvokeEeschemaConfig( (SCH_EDIT_FRAME *)GetParent(), this ); + SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false ); + wxASSERT( frame ); + + InvokeEeschemaConfig( frame, this ); } @@ -134,7 +137,9 @@ void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) { int id = event.GetId(); wxFileName fn; - SCH_EDIT_FRAME* schFrame = ( SCH_EDIT_FRAME* ) GetParent(); + + SCH_EDIT_FRAME* schFrame = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false ); + wxASSERT( schFrame ); switch( id ) { @@ -143,20 +148,20 @@ void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) break; case ID_CONFIG_READ: - { - fn = g_RootSheet->GetScreen()->GetFileName(); - fn.SetExt( ProjectFileExtension ); + { + fn = g_RootSheet->GetScreen()->GetFileName(); + fn.SetExt( ProjectFileExtension ); - wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(), - fn.GetFullName(), ProjectFileWildcard, - wxFD_OPEN | wxFD_FILE_MUST_EXIST ); + wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(), + fn.GetFullName(), ProjectFileWildcard, + wxFD_OPEN | wxFD_FILE_MUST_EXIST ); - if( dlg.ShowModal() == wxID_CANCEL ) - break; + if( dlg.ShowModal() == wxID_CANCEL ) + break; - schFrame->LoadProjectFile( dlg.GetPath(), true ); - } - break; + schFrame->LoadProjectFile( dlg.GetPath(), true ); + } + break; // Hotkey IDs diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index fa1f083860..e977eee5c1 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -55,18 +56,14 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedAlias, int* aUnit, int* aConvert ) { - wxSemaphore semaphore( 0, 1 ); - wxString cmpname; - - // Close the current Lib browser, if open, and open a new one, in "modal" mode: - LIB_VIEW_FRAME* viewlibFrame = LIB_VIEW_FRAME::GetActiveLibraryViewer( this ); + // Close the any current non-modal Lib browser if open, and open a new one, in "modal" mode: + LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false ); if( viewlibFrame ) viewlibFrame->Destroy(); - viewlibFrame = new LIB_VIEW_FRAME( &Kiway(), this, NULL, &semaphore, - KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); + viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true ); - if ( aPreselectedAlias ) + if( aPreselectedAlias ) { viewlibFrame->SetSelectedLibrary( aPreselectedAlias->GetLibraryName() ); viewlibFrame->SetSelectedComponent( aPreselectedAlias->GetName() ); @@ -80,15 +77,9 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedA viewlibFrame->Refresh(); - // Show the library viewer frame until it is closed - // Wait for viewer closing event: - while( semaphore.TryWait() == wxSEMA_BUSY ) - { - wxYield(); - wxMilliSleep( 50 ); - } + wxString cmpname; - cmpname = viewlibFrame->GetSelectedComponent(); + viewlibFrame->ShowModal( &cmpname ); if( aUnit ) *aUnit = viewlibFrame->GetUnit(); @@ -101,6 +92,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedA return cmpname; } + wxString SCH_BASE_FRAME::SelectComponentFromLibrary( const wxString& aLibname, wxArrayString& aHistoryList, int& aHistoryLastUnit, diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 1a79cba67e..49ea88353d 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -99,7 +99,7 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_SIZE( LIB_EDIT_FRAME::OnSize ) EVT_ACTIVATE( LIB_EDIT_FRAME::OnActivate ) - /* Main horizontal toolbar. */ + // Main horizontal toolbar. EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnSaveActiveLibrary ) EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB, LIB_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_LIBEDIT_DELETE_PART, LIB_EDIT_FRAME::DeleteOnePart ) @@ -125,12 +125,12 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart ) EVT_COMBOBOX( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnSelectAlias ) - /* Right vertical toolbar. */ + // Right vertical toolbar. EVT_TOOL( ID_NO_TOOL_SELECTED, LIB_EDIT_FRAME::OnSelectTool ) EVT_TOOL_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_DELETE_ITEM_BUTT, LIB_EDIT_FRAME::OnSelectTool ) - /* menubar commands */ + // menubar commands EVT_MENU( wxID_EXIT, LIB_EDIT_FRAME::CloseWindow ) EVT_MENU( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnSaveActiveLibrary ) EVT_MENU( ID_LIBEDIT_GEN_PNG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent ) @@ -152,9 +152,7 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END, LIB_EDIT_FRAME::Process_Config ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, LIB_EDIT_FRAME::SetLanguage ) - - /* Context menu events and commands. */ + // Context menu events and commands. EVT_MENU( ID_LIBEDIT_EDIT_PIN, LIB_EDIT_FRAME::OnEditPin ) EVT_MENU( ID_LIBEDIT_ROTATE_ITEM, LIB_EDIT_FRAME::OnRotateItem ) @@ -165,7 +163,7 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE, LIB_EDIT_FRAME::Process_Special_Functions ) - /* Update user interface elements. */ + // Update user interface elements. EVT_UPDATE_UI( ExportPartId, LIB_EDIT_FRAME::OnUpdateEditingPart ) EVT_UPDATE_UI( CreateNewLibAndSavePartId, LIB_EDIT_FRAME::OnUpdateEditingPart ) EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart ) @@ -193,7 +191,7 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) : 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. + wxASSERT( aParent ); m_FrameName = GetLibEditFrameName(); m_showAxis = true; // true to draw axis @@ -204,6 +202,7 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) : m_tempCopyComponent = NULL; m_HotkeysZoomAndGridList = s_Libedit_Hokeys_Descr; m_editPinsPerPartOrConvert = false; + // Initialize grid id to the default value 50 mils: m_LastGridSizeId = ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000; @@ -293,12 +292,6 @@ const wxChar* LIB_EDIT_FRAME::GetLibEditFrameName() } -LIB_EDIT_FRAME* LIB_EDIT_FRAME::GetActiveLibraryEditor() -{ - return (LIB_EDIT_FRAME*) wxWindow::FindWindowByName(GetLibEditFrameName()); -} - - void LIB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) { #if 0 // original @@ -389,12 +382,12 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) double LIB_EDIT_FRAME::BestZoom() { -/* Please, note: wxMSW before version 2.9 seems have - * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched: - * edit file /src/msw/dc.cpp - * search for line static const int VIEWPORT_EXTENT = 1000; - * and replace by static const int VIEWPORT_EXTENT = 10000; - */ + /* Please, note: wxMSW before version 2.9 seems have + * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched: + * edit file /src/msw/dc.cpp + * search for line static const int VIEWPORT_EXTENT = 1000; + * and replace by static const int VIEWPORT_EXTENT = 10000; + */ int dx, dy; wxSize size; EDA_RECT BoundaryBox; @@ -750,23 +743,23 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT: - { - // Delete the last created segment, while creating a polyline draw item - if( m_drawItem == NULL ) - break; + { + // Delete the last created segment, while creating a polyline draw item + if( m_drawItem == NULL ) + break; - m_canvas->MoveCursorToCrossHair(); - STATUS_FLAGS oldFlags = m_drawItem->GetFlags(); - m_drawItem->ClearFlags(); - m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL, - DefaultTransform ); - ( (LIB_POLYLINE*) m_drawItem )->DeleteSegment( GetCrossHairPosition( true ) ); - m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL, - DefaultTransform ); - m_drawItem->SetFlags( oldFlags ); - m_lastDrawItem = NULL; + m_canvas->MoveCursorToCrossHair(); + STATUS_FLAGS oldFlags = m_drawItem->GetFlags(); + m_drawItem->ClearFlags(); + m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL, + DefaultTransform ); + ( (LIB_POLYLINE*) m_drawItem )->DeleteSegment( GetCrossHairPosition( true ) ); + m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL, + DefaultTransform ); + m_drawItem->SetFlags( oldFlags ); + m_lastDrawItem = NULL; + } break; - } case ID_POPUP_LIBEDIT_DELETE_ITEM: if( m_drawItem ) @@ -918,17 +911,6 @@ void LIB_EDIT_FRAME::EnsureActiveLibExists() } -void LIB_EDIT_FRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_BASE_FRAME::SetLanguage( event ); - SCH_EDIT_FRAME *parent = (SCH_EDIT_FRAME *)GetParent(); - // Call parent->EDA_BASE_FRAME::SetLanguage and NOT - // parent->SetLanguage because parent->SetLanguage call - // LIB_EDIT_FRAME::SetLanguage - parent->EDA_BASE_FRAME::SetLanguage( event ); -} - - void LIB_EDIT_FRAME::TempCopyComponent() { if( m_tempCopyComponent ) diff --git a/eeschema/libeditframe.h b/eeschema/libeditframe.h index 45582f34d8..07a52b6203 100644 --- a/eeschema/libeditframe.h +++ b/eeschema/libeditframe.h @@ -133,13 +133,6 @@ public: */ static const wxChar* GetLibEditFrameName(); - /** - * Function GetActiveLibraryEditor (static) - * @return a reference to the current opened Library editor - * or NULL if no Library editor currently opened - */ - static LIB_EDIT_FRAME* GetActiveLibraryEditor(); - void ReCreateMenuBar(); /** @@ -149,12 +142,6 @@ public: */ static void EnsureActiveLibExists(); - /** - * Function SetLanguage - * is called on a language menu selection - */ - void SetLanguage( wxCommandEvent& event ); - void InstallConfigFrame( wxCommandEvent& event ); void InstallDimensionsDialog( wxCommandEvent& event ); void OnColorConfig( wxCommandEvent& aEvent ); diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 7908defdc1..ca6ac2f9ed 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -26,6 +26,7 @@ #include #include #include +#include SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, @@ -40,12 +41,10 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, void SCH_BASE_FRAME::OnOpenLibraryViewer( wxCommandEvent& event ) { - LIB_VIEW_FRAME* viewlibFrame = LIB_VIEW_FRAME::GetActiveLibraryViewer( this ); + LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, true ); - if( viewlibFrame ) - viewlibFrame->Show( true ); - else - new LIB_VIEW_FRAME( &Kiway(), this ); + viewlibFrame->Show( true ); + viewlibFrame->Raise(); } diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index 8706b5c4b5..ff42fdc9af 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -664,7 +664,7 @@ static void abortMoveItem( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) { SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen(); SCH_ITEM* item = screen->GetCurItem(); - SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent(); + SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent(); parent->SetRepeatItem( NULL ); screen->SetCurItem( NULL ); diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index fe38369fd4..db9e8f50ce 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -96,8 +96,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_MENU( ID_COLORS_SETUP, SCH_EDIT_FRAME::OnColorConfig ) EVT_TOOL( wxID_PREFERENCES, SCH_EDIT_FRAME::OnSetOptions ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, SCH_EDIT_FRAME::SetLanguage ) - EVT_TOOL( ID_TO_LIBRARY, SCH_EDIT_FRAME::OnOpenLibraryEditor ) EVT_TOOL( ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, SCH_EDIT_FRAME::OnOpenLibraryEditor ) EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer ) @@ -442,13 +440,20 @@ void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem ) void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) { - LIB_EDIT_FRAME * libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; - if( libeditFrame && !libeditFrame->Close() ) // Can close component editor? - return; + if( Kiface().IsSingle() ) + { + LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false ); + if( libeditFrame && !libeditFrame->Close() ) // Can close component editor? + return; - LIB_VIEW_FRAME* viewlibFrame = LIB_VIEW_FRAME::GetActiveLibraryViewer( this ); - if( viewlibFrame && !viewlibFrame->Close() ) // Can close component viewer? - return; + LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false ); + if( viewlibFrame && !viewlibFrame->Close() ) // Can close component viewer? + return; + + viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, false ); + if( viewlibFrame && !viewlibFrame->Close() ) // Can close modal component viewer? + return; + } SCH_SHEET_LIST SheetList; @@ -829,7 +834,7 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) { SCH_ITEM* item = GetScreen()->GetCurItem(); - if( (item == NULL) || (item->GetFlags() != 0) || ( item->Type() != SCH_COMPONENT_T ) ) + if( !item || (item->GetFlags() != 0) || ( item->Type() != SCH_COMPONENT_T ) ) { wxMessageBox( _( "Error: not a component or no component" ) ); return; @@ -838,9 +843,21 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) component = (SCH_COMPONENT*) item; } - // @todo: should be changed to use Kiway().Player()? + LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false ); + if( !libeditFrame ) + { + libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, true ); + libeditFrame->Show( true ); + } + else + { + // if( libeditFrame->IsIconized() ) + // libeditFrame->Iconize( false ); + } - LIB_EDIT_FRAME* libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; + libeditFrame->Raise(); + +#if 0 if( libeditFrame ) { if( libeditFrame->IsIconized() ) @@ -855,6 +872,8 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) wxWindow* w = kf.CreateWindow( this, FRAME_SCH_LIB_EDITOR, &Kiway(), kf.StartFlags() ); libeditFrame = dynamic_cast( w ); } +#endif + if( component ) { @@ -875,16 +894,6 @@ void SCH_EDIT_FRAME::OnExit( wxCommandEvent& event ) } -void SCH_EDIT_FRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_BASE_FRAME::SetLanguage( event ); - - LIB_EDIT_FRAME * libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; - if( libeditFrame ) - libeditFrame->EDA_BASE_FRAME::SetLanguage( event ); -} - - void SCH_EDIT_FRAME::OnPrint( wxCommandEvent& event ) { wxFileName fn; diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 62d9fca131..23e9ae5100 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -283,7 +283,7 @@ static void ExitSheet( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen(); SCH_ITEM* item = screen->GetCurItem(); - SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent(); + SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent(); if( (item == NULL) || (item->Type() != SCH_SHEET_T) || (parent == NULL) ) return; diff --git a/eeschema/tool_viewlib.cpp b/eeschema/tool_viewlib.cpp index 5dce538405..f929ad5c28 100644 --- a/eeschema/tool_viewlib.cpp +++ b/eeschema/tool_viewlib.cpp @@ -116,9 +116,9 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() _( "View component documents" ) ); m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, false ); - if( m_semaphore ) + // if library browser is modal + if( m_Ident == FRAME_SCH_VIEWER_MODAL ) { - // The library browser is called from a "load component" command m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC, wxEmptyString, KiBitmap( export_xpm ), diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index 33b05c1bc6..e4af57c174 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -47,28 +47,25 @@ */ wxString LIB_VIEW_FRAME::m_libraryName; wxString LIB_VIEW_FRAME::m_entryName; + int LIB_VIEW_FRAME::m_unit = 1; int LIB_VIEW_FRAME::m_convert = 1; -/// When the viewer is used to select a component in schematic, the selected component is here. -wxString LIB_VIEW_FRAME::m_exportToEeschemaCmpName; - - BEGIN_EVENT_TABLE( LIB_VIEW_FRAME, EDA_DRAW_FRAME ) - /* Window events */ + // Window events EVT_CLOSE( LIB_VIEW_FRAME::OnCloseWindow ) EVT_SIZE( LIB_VIEW_FRAME::OnSize ) EVT_ACTIVATE( LIB_VIEW_FRAME::OnActivate ) - /* Toolbar events */ + // Toolbar events EVT_TOOL_RANGE( ID_LIBVIEW_NEXT, ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, LIB_VIEW_FRAME::Process_Special_Functions ) EVT_TOOL( ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC, LIB_VIEW_FRAME::ExportToSchematicLibraryPart ) EVT_COMBOBOX( ID_LIBVIEW_SELECT_PART_NUMBER, LIB_VIEW_FRAME::Process_Special_Functions ) - /* listbox events */ + // listbox events EVT_LISTBOX( ID_LIBVIEW_LIB_LIST, LIB_VIEW_FRAME::ClickOnLibList ) EVT_LISTBOX( ID_LIBVIEW_CMP_LIST, LIB_VIEW_FRAME::ClickOnCmpList ) EVT_LISTBOX_DCLICK( ID_LIBVIEW_CMP_LIST, LIB_VIEW_FRAME::DClickOnCmpList ) @@ -95,11 +92,17 @@ static wxAcceleratorEntry accels[] = #define ACCEL_TABLE_CNT ( sizeof( accels ) / sizeof( wxAcceleratorEntry ) ) #define LIB_VIEW_FRAME_NAME wxT( "ViewlibFrame" ) -LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, - CMP_LIBRARY* aLibrary, wxSemaphore* aSemaphore, long aStyle ) : - SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Library Browser" ), - wxDefaultPosition, wxDefaultSize, aStyle, GetLibViewerFrameName() ) +LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, + CMP_LIBRARY* aLibrary ) : + SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Library Browser" ), + wxDefaultPosition, wxDefaultSize, + aFrameType==FRAME_SCH_VIEWER ? + KICAD_DEFAULT_DRAWFRAME_STYLE : + KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT, + GetLibViewerFrameName() ) { + wxASSERT( aFrameType==FRAME_SCH_VIEWER || aFrameType==FRAME_SCH_VIEWER_MODAL ); + wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); m_FrameName = GetLibViewerFrameName(); @@ -114,12 +117,6 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, m_HotkeysZoomAndGridList = s_Viewlib_Hokeys_Descr; m_cmpList = NULL; m_libList = NULL; - m_semaphore = aSemaphore; - - if( m_semaphore ) - SetModalMode( true ); - - m_exportToEeschemaCmpName.Empty(); SetScreen( new SCH_SCREEN() ); GetScreen()->m_Center = true; // Axis origin centered on screen. @@ -139,10 +136,10 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, wxPoint win_pos( 0, 0 ); - if( aLibrary == NULL ) + if( !aLibrary ) { // Creates the libraries window display - m_libList = new wxListBox( this, ID_LIBVIEW_LIB_LIST, + m_libList = new wxListBox( this, ID_LIBVIEW_LIB_LIST, wxPoint( 0, 0 ), wxSize(m_libListWidth, -1), 0, NULL, wxLB_HSCROLL ); } @@ -243,25 +240,19 @@ const wxChar* LIB_VIEW_FRAME::GetLibViewerFrameName() } -LIB_VIEW_FRAME* LIB_VIEW_FRAME::GetActiveLibraryViewer( const wxWindow* aParent ) -{ - return (LIB_VIEW_FRAME*) wxWindow::FindWindowByName( GetLibViewerFrameName(), aParent ); -} - - void LIB_VIEW_FRAME::OnCloseWindow( wxCloseEvent& Event ) { - if( m_semaphore ) - { - m_semaphore->Post(); - // This window will be destroyed by the calling function, - // if needed - SetModalMode( false ); - } - else + if( !IsModal() ) { Destroy(); } + else if( !IsDismissed() ) + { + // only dismiss modal frame if not already dismissed. + DismissModal( false ); + + // Modal frame will be destroyed by the calling function. + } } @@ -283,12 +274,13 @@ void LIB_VIEW_FRAME::OnSetRelativeOffset( wxCommandEvent& event ) double LIB_VIEW_FRAME::BestZoom() { -/* Please, note: wxMSW before version 2.9 seems have - * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched: - * edit file /src/msw/dc.cpp - * search for line static const int VIEWPORT_EXTENT = 1000; - * and replace by static const int VIEWPORT_EXTENT = 10000; - */ + /* Please, note: wxMSW before version 2.9 seems have + * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched: + * edit file /src/msw/dc.cpp + * search for line static const int VIEWPORT_EXTENT = 1000; + * and replace by static const int VIEWPORT_EXTENT = 10000; + */ + LIB_COMPONENT* component = NULL; double bestzoom = 16.0; // default value for bestzoom CMP_LIBRARY* lib = CMP_LIBRARY::FindLibrary( m_libraryName ); @@ -344,8 +336,8 @@ void LIB_VIEW_FRAME::ReCreateListLib() } else { - /* If not found, clear current library selection because it can be - * deleted after a config change. */ + // If not found, clear current library selection because it can be + // deleted after a config change. m_libraryName = wxEmptyString; m_entryName = wxEmptyString; m_unit = 1; @@ -417,6 +409,7 @@ void LIB_VIEW_FRAME::SetSelectedLibrary( const wxString& aLibraryName ) m_canvas->Refresh(); DisplayLibInfos(); ReCreateHToolbar(); + // Ensure the corresponding line in m_libList is selected // (which is not necessary the case if SetSelectedLibrary is called // by an other caller than ClickOnLibList. @@ -440,9 +433,10 @@ void LIB_VIEW_FRAME::SetSelectedComponent( const wxString& aComponentName ) if( m_entryName.CmpNoCase( aComponentName ) != 0 ) { m_entryName = aComponentName; + // Ensure the corresponding line in m_cmpList is selected - // (which is not necessary the case if SetSelectedComponent is called - // by an other caller than ClickOnCmpList. + // (which is not necessarily the case if SetSelectedComponent is called + // by another caller than ClickOnCmpList. m_cmpList->SetStringSelection( aComponentName, true ); DisplayLibInfos(); m_unit = 1; @@ -456,14 +450,21 @@ void LIB_VIEW_FRAME::SetSelectedComponent( const wxString& aComponentName ) void LIB_VIEW_FRAME::DClickOnCmpList( wxCommandEvent& event ) { - if( m_semaphore ) + if( IsModal() ) { ExportToSchematicLibraryPart( event ); - // Prevent the double click from being as a single click in the parent - // window which would cause the part to be parked rather than staying - // in drag mode. - ((SCH_BASE_FRAME*) GetParent())->SkipNextLeftButtonReleaseEvent(); + // The schematic editor might not be the parent of the library viewer. + // It could be a python window. + SCH_EDIT_FRAME* schframe = dynamic_cast( GetParent() ); + + if( schframe ) + { + // Prevent the double click from being as a single click in the parent + // window which would cause the part to be parked rather than staying + // in drag mode. + schframe->SkipNextLeftButtonReleaseEvent(); + } } } @@ -473,9 +474,17 @@ void LIB_VIEW_FRAME::ExportToSchematicLibraryPart( wxCommandEvent& event ) int ii = m_cmpList->GetSelection(); if( ii >= 0 ) - m_exportToEeschemaCmpName = m_cmpList->GetString( ii ); + { + wxString part_name = m_cmpList->GetString( ii ); + + // a selection was made, pass true + DismissModal( true, part_name ); + } else - m_exportToEeschemaCmpName.Empty(); + { + // no selection was made, pass false + DismissModal( false ); + } Close( true ); } @@ -524,10 +533,6 @@ void LIB_VIEW_FRAME::OnActivate( wxActivateEvent& event ) { EDA_DRAW_FRAME::OnActivate( event ); - // Ensure we do not have old selection: - if( m_FrameIsActive ) - m_exportToEeschemaCmpName.Empty(); - if( m_libList ) ReCreateListLib(); diff --git a/eeschema/viewlib_frame.h b/eeschema/viewlib_frame.h index bdb304a312..4e67d0eafc 100644 --- a/eeschema/viewlib_frame.h +++ b/eeschema/viewlib_frame.h @@ -38,7 +38,6 @@ class wxSashLayoutWindow; class wxListBox; -class wxSemaphore; class CMP_LIBRARY; @@ -48,9 +47,14 @@ class CMP_LIBRARY; class LIB_VIEW_FRAME : public SCH_BASE_FRAME { public: - LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, - CMP_LIBRARY* aLibrary = NULL, wxSemaphore* aSemaphore = NULL, - long aStyle = KICAD_DEFAULT_DRAWFRAME_STYLE ); + + /** + * Constructor + * @param aFrameType must be given either FRAME_SCH_LIB_VIEWER or + * FRAME_SCH_LIB_VIEWER_MODAL + */ + LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, + FRAME_T aFrameType, CMP_LIBRARY* aLibrary = NULL ); ~LIB_VIEW_FRAME(); @@ -61,13 +65,6 @@ public: */ static const wxChar* GetLibViewerFrameName(); - /** - * Function GetActiveLibraryViewer (static) - * @return a reference to the current opened Library viewer - * or NULL if no Library viewer currently opened - */ - static LIB_VIEW_FRAME* GetActiveLibraryViewer( const wxWindow* aParent ); - void OnSize( wxSizeEvent& event ); /** @@ -109,7 +106,6 @@ public: * @param the alias name of the component to be selected. */ void SetSelectedComponent( const wxString& aComponentName ); - const wxString& GetSelectedComponent( void ) const { return m_exportToEeschemaCmpName; } void SetUnit( int aUnit ) { m_unit = aUnit; } int GetUnit( void ) { return m_unit; } @@ -147,8 +143,6 @@ private: wxListBox* m_cmpList; // The list of components int m_cmpListWidth; // Last width of the window - // Flags - wxSemaphore* m_semaphore; // != NULL if the frame must emulate a modal dialog wxString m_configPath; // subpath for configuration // TODO(hzeller): looks like these members were chosen to be static to survive different @@ -156,11 +150,8 @@ private: // ugly hack, and should be solved differently. static wxString m_libraryName; - // TODO(hzeller): figure out what the difference between these is and the motivation to - // have this distinction. Shouldn't these essentially be the same ? static wxString m_entryName; - static wxString m_exportToEeschemaCmpName; // When the viewer is used to select a component - // in schematic, the selected component is here + static int m_unit; static int m_convert; diff --git a/gerbview/events_called_functions.cpp b/gerbview/events_called_functions.cpp index a1021c1fab..6f258ab2b8 100644 --- a/gerbview/events_called_functions.cpp +++ b/gerbview/events_called_functions.cpp @@ -52,8 +52,6 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME ) GERBVIEW_FRAME::OnSelectOptionToolbar ) EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, EDA_DRAW_FRAME::SetLanguage ) - // menu Postprocess EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions ) EVT_MENU( ID_GERBVIEW_SHOW_SOURCE, GERBVIEW_FRAME::OnShowGerberSourceFile ) @@ -209,9 +207,6 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event ) } -/* Selects the active DCode for the current active layer. - * Items using this DCode are hightlighted - */ void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event ) { GERBER_IMAGE* gerber_image = g_GERBER_List[getActiveLayer()]; @@ -228,10 +223,7 @@ void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event ) } } -/* Selects the active layer: - * - if a file is loaded, it is loaded in this layer - * _ this layer is displayed on top of other layers - */ + void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) { LAYER_NUM layer = getActiveLayer(); @@ -246,9 +238,6 @@ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) } -/* Call preferred editor to show (and edit) the gerber source file - * loaded in the active layer - */ void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event ) { LAYER_NUM layer = getActiveLayer(); @@ -275,9 +264,6 @@ void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event ) } -/* Function OnSelectDisplayMode: called to select display mode - * (fast display, or exact mode with stacked images or with transparency - */ void GERBVIEW_FRAME::OnSelectDisplayMode( wxCommandEvent& event ) { int oldMode = GetDisplayMode(); @@ -301,20 +287,20 @@ void GERBVIEW_FRAME::OnSelectDisplayMode( wxCommandEvent& event ) m_canvas->Refresh(); } + void GERBVIEW_FRAME::OnQuit( wxCommandEvent& event ) { Close( true ); } -/** - * Function SetLanguage - * called on a language menu selection - * Update Layer manager title and tabs texts - */ -void GERBVIEW_FRAME::SetLanguage( wxCommandEvent& event ) + +void GERBVIEW_FRAME::ShowChangedLanguage() { - EDA_DRAW_FRAME::SetLanguage( event ); + // call my base class + EDA_DRAW_FRAME::ShowChangedLanguage(); + m_LayersManager->SetLayersManagerTabsText(); + wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_LayersManager ); pane_info.Caption( _( "Visibles" ) ); m_auimgr.Update(); @@ -322,14 +308,12 @@ void GERBVIEW_FRAME::SetLanguage( wxCommandEvent& event ) ReFillLayerWidget(); } -/** - * Function OnSelectOptionToolbar - * called to validate current choices - */ + void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) { - int id = event.GetId(); - bool state; + int id = event.GetId(); + bool state; + switch( id ) { case ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG: @@ -374,6 +358,7 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) break; case ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR: + // show/hide auxiliary Vertical layers and visibility manager toolbar m_show_layer_manager_tools = state; m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools ); diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h index f703ece8ee..df14fdaa4b 100644 --- a/gerbview/gerbview_frame.h +++ b/gerbview/gerbview_frame.h @@ -462,11 +462,7 @@ public: void SaveSettings( wxConfigBase* aCfg ); // override virtual - /** - * Function SetLanguage - * called on a language menu selection - */ - virtual void SetLanguage( wxCommandEvent& event ); + void ShowChangedLanguage(); // override EDA_BASE_FRAME virtual void Process_Special_Functions( wxCommandEvent& event ); void OnSelectOptionToolbar( wxCommandEvent& event ); diff --git a/include/draw_frame.h b/include/draw_frame.h index 67aba863c1..aaf999edec 100644 --- a/include/draw_frame.h +++ b/include/draw_frame.h @@ -281,13 +281,6 @@ public: void EraseMsgBox(); void Process_PageSettings( wxCommandEvent& event ); - /** - * Function SetLanguage - * called on a language menu selection - * when using a derived function, do not forget to call this one - */ - virtual void SetLanguage( wxCommandEvent& event ); - virtual void ReCreateHToolbar() = 0; virtual void ReCreateVToolbar() = 0; virtual void ReCreateMenuBar(); diff --git a/include/fpid.h b/include/fpid.h index 853983ad51..ec1ab80931 100644 --- a/include/fpid.h +++ b/include/fpid.h @@ -80,9 +80,7 @@ public: * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into * aId at which an error was detected. */ - int Parse( const std::string& aId ); - - int Parse( const wxString& aId ); + int Parse( const UTF8& aId ); /** * Function GetLibNickname @@ -100,9 +98,7 @@ public: * into the parameter at which an error was detected, usually because it * contained '/' or ':'. */ - int SetLibNickname( const std::string& aNickname ); - - int SetLibNickname( const wxString& aNickname ); + int SetLibNickname( const UTF8& aNickname ); /** * Function GetFootprintName @@ -114,11 +110,9 @@ public: * Function SetFootprintName * overrides the footprint name portion of the FPID to @a aFootprintName */ - int SetFootprintName( const std::string& aFootprintName ); + int SetFootprintName( const UTF8& aFootprintName ); - int SetFootprintName( const wxString& aFootprintName ); - - int SetRevision( const std::string& aRevision ); + int SetRevision( const UTF8& aRevision ); const UTF8& GetRevision() const { return revision; } @@ -136,10 +130,10 @@ public: * aLibNickname, aFootprintName, and aRevision. * * @throw PARSE_ERROR if any of the pieces are illegal. - */ - static UTF8 Format( const std::string& aLibNickname, const std::string& aFootprintName, - const std::string& aRevision ) + static UTF8 Format( const UTF8& aLibNickname, const UTF8& aFootprintName, + const UTF8& aRevision = "" ) throw( PARSE_ERROR ); + */ /** * Function IsValid diff --git a/include/frame_type.h b/include/frame_type.h index 23411168c6..e58f615659 100644 --- a/include/frame_type.h +++ b/include/frame_type.h @@ -11,22 +11,35 @@ enum FRAME_T FRAME_SCH, FRAME_SCH_LIB_EDITOR, FRAME_SCH_VIEWER, + FRAME_SCH_VIEWER_MODAL, + FRAME_PCB, FRAME_PCB_MODULE_EDITOR, FRAME_PCB_MODULE_VIEWER, - FRAME_PCB_FOOTPRINT_WIZARD, + FRAME_PCB_MODULE_VIEWER_MODAL, + FRAME_PCB_FOOTPRINT_WIZARD_MODAL, 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_BM2CMP, + + FRAME_CALC, + + KIWAY_PLAYER_COUNT, // counts subset of FRAME_T's which are KIWAY_PLAYER derivatives + + // C++ project manager is not a KIWAY_PLAYER + KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT, FRAME_T_COUNT }; + //TEXT_EDITOR_FRAME_T, + + #endif // FRAME_T_H_ diff --git a/include/kiface_i.h b/include/kiface_i.h index 9fe034603a..23f053580c 100644 --- a/include/kiface_i.h +++ b/include/kiface_i.h @@ -58,7 +58,7 @@ public: } VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, - int aClassId, KIWAY* aKIWAY, int aCtlBits ) = 0; + int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; VTBL_ENTRY void* IfaceOrAddress( int aDataId ) = 0; diff --git a/include/kiway.h b/include/kiway.h index 9b2ffd6b2d..469a0fde27 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -150,7 +150,8 @@ struct KIFACE // 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 +#define KFCTL_CPP_PROJECT_SUITE (1<<1) ///< Am running under C++ project mgr, possibly with others +#define KFCTL_PY_PROJECT_SUITE (1<<2) ///< Am running under python project mgr, possibly with others /** @@ -201,7 +202,7 @@ struct KIFACE * not contained in the caller's link image. */ VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, int aClassId, - KIWAY* aKIWAY, int aCtlBits ) = 0; + KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; /** * Function IfaceOrAddress @@ -249,6 +250,7 @@ struct KIFACE */ class KIWAY : public wxEvtHandler { + friend class PGM_SINGLE_TOP; // can use set_kiface() public: /// Known KIFACE implementations @@ -257,16 +259,12 @@ public: FACE_SCH, ///< eeschema DSO FACE_PCB, ///< pcbnew DSO FACE_CVPCB, - - /// 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_BMP2CMP, - FACE_COUNT + KIWAY_FACE_COUNT }; /** @@ -302,7 +300,7 @@ public: * @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. */ - VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true ); + VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true ); /** * Function PlayerClose @@ -312,7 +310,7 @@ public: * * @return bool - true the window is closed and not vetoed, else false. */ - VTBL_ENTRY bool PlayerClose( FRAME_T aFrameType, bool doForce ); + VTBL_ENTRY bool PlayerClose( FRAME_T aFrameType, bool doForce ); /** * Function PlayersClose @@ -325,7 +323,14 @@ public: */ VTBL_ENTRY bool PlayersClose( bool doForce ); - VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); + /** + * Function ExpressMail + * send aPayload to aDestination from aSource. Recipient receives this in its + * KIWAY_PLAYER::KiwayMailIn() function and can efficiently switch() based on + * aCommand in there. + */ + VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand, + const std::string& aPayload, wxWindow* aSource = NULL ); /** * Function Prj @@ -335,11 +340,26 @@ public: */ VTBL_ENTRY PROJECT& Prj() const; - KIWAY( PGM_BASE* aProgram, wxFrame* aTop = NULL ); + /** + * Function SetLanguage + * changes the language and then calls ShowChangedLanguage() on all KIWAY_PLAYERs. + */ + VTBL_ENTRY void SetLanguage( int aLanguage ); - /// In case aTop may not be known at time of KIWAY construction: + KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop = NULL ); + + /** + * Function SetTop + * tells this KIWAY about the top most frame in the program and optionally + * allows it to play the role of one of the KIWAY_PLAYERs if launched from + * single_top.cpp. + * + * @param aTop is the top most wxFrame in the entire program. + */ void SetTop( wxFrame* aTop ); + void OnKiwayEnd(); + bool ProcessEvent( wxEvent& aEvent ); // overload virtual private: @@ -348,12 +368,23 @@ private: static const wxString dso_full_path( FACE_T aFaceId ); /// hooked into m_top in SetTop(), marks child frame as closed. - void playerDestroyHandler( wxWindowDestroyEvent& event ); + void player_destroy_handler( wxWindowDestroyEvent& event ); + + bool set_kiface( FACE_T aFaceType, KIFACE* aKiface ) + { + if( unsigned( aFaceType ) < unsigned( KIWAY_FACE_COUNT ) ) + { + m_kiface[aFaceType] = aKiface; + return true; + } + return false; + } static KIFACE* m_kiface[KIWAY_FACE_COUNT]; static int m_kiface_version[KIWAY_FACE_COUNT]; PGM_BASE* m_program; + int m_ctl; wxFrame* m_top; KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h diff --git a/include/kiway_player.h b/include/kiway_player.h index 75b1189053..8188ad35c8 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -35,6 +35,8 @@ class PROJECT; struct KIFACE; class KIFACE_I; +#define VTBL_ENTRY virtual + /** * Class KIWAY_HOLDER @@ -80,7 +82,7 @@ public: private: // private, all setting is done through SetKiway(). - KIWAY* m_kiway; // no ownership. + KIWAY* m_kiway; // no ownership. }; @@ -110,6 +112,9 @@ public: const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aWdoName = wxFrameNameStr ); + ~KIWAY_PLAYER(); + + //--------------------------------------------------------- // For the aCtl argument of OpenProjectFiles() #define KICTL_OPEN_APPEND (1<<0) ///< append the data file, rather than replace @@ -149,7 +154,7 @@ public: * * @return bool - true if all requested files were opened OK, else false. */ - virtual bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) + VTBL_ENTRY bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) { // overload me for your wxFrame type. @@ -161,6 +166,25 @@ public: return false; } + /** + * Function ShowModal + * puts up this wxFrame as if it were a modal dialog, with all other instantiated + * wxFrames disabled until this KIWAY_PLAYER derivative calls DismissModal(). + * That is, behavior is similar to a modal dialog window. Not all KIWAY_PLAYERs + * use this interface, so don't call this unless the implementation knows how + * to call DismissModal() on a button click or double click or some special + * event which ends the modal behavior. + * + * @param aResult if not NULL, indicates a place to put a resultant string. + * + * @return bool - true if frame implementation called KIWAY_PLAYER::DismissModal() + * with aRetVal of true. + */ + VTBL_ENTRY bool ShowModal( wxString* aResult ); + + //-------------------------------------------------------- + + /** * Function KiwayMailIn * receives KIWAY_EXPRESS messages from other players. Merely override it @@ -168,12 +192,35 @@ public: */ virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); - DECLARE_EVENT_TABLE() +protected: -//private: + bool IsModal() { return m_modal_dismissed; } - /// event handler, routes to virtual KiwayMailIn() + /** + * Function IsDismissed + * returns false only if both the frame is acting in modal mode and it has not been + * dismissed yet with DismissModal(). IOW, it will return true if the dialog is + * not modal or if it is modal and has been dismissed. + */ + bool IsDismissed(); + + void DismissModal( bool aRetVal, const wxString& aResult = wxEmptyString ); + + /// event handler, routes to derivative specific virtual KiwayMailIn() void kiway_express( KIWAY_EXPRESS& aEvent ); + + /** + * Function language_change + * is an event handler called on a language menu selection. + */ + void language_change( wxCommandEvent& event ); + + // variables for modal behavior support, only used by a few derivatives. + volatile bool* m_modal_dismissed; // points to "dismissed state", NULL means not modal + wxString m_modal_string; + bool m_modal_ret_val; // true if a selection was made + + DECLARE_EVENT_TABLE() }; diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index fea2499c69..171351d321 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -813,12 +813,6 @@ private: void OnUpdateBusOrientation( wxUpdateUIEvent& event ); void OnUpdateSelectTool( wxUpdateUIEvent& aEvent ); - /** - * Function SetLanguage - * called on a language menu selection - */ - void SetLanguage( wxCommandEvent& event ); - /** * Function UpdateTitle * sets the main window title bar text. diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 9ad56f1016..21218d78a9 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1666,11 +1666,7 @@ public: */ MODULE* Genere_Self( wxDC* DC ); - /** - * Function SetLanguage - * called on a language menu selection - */ - virtual void SetLanguage( wxCommandEvent& event ); + void ShowChangedLanguage(); // override EDA_BASE_FRAME virtual /** * Function UpdateTitle diff --git a/include/wxstruct.h b/include/wxstruct.h index 73363cceed..22153455a2 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -113,7 +113,7 @@ class EDA_BASE_FRAME : public wxFrame void windowClosing( wxCloseEvent& event ); protected: - FRAME_T m_Ident; ///< Id Type (pcb, schematic, library..) + FRAME_T m_Ident; ///< Id Type (pcb, schematic, library..) wxPoint m_FramePos; wxSize m_FrameSize; @@ -302,13 +302,6 @@ public: */ void ExportHotkeyConfigToFile( struct EDA_HOTKEY_CONFIG* aDescList ); - /** - * Function SetLanguage - * called on a language menu selection - * when using a derived function, do not forget to call this one - */ - virtual void SetLanguage( wxCommandEvent& event ); - /** * Function GetFileFromHistory * fetches the file name from the file history list. @@ -380,17 +373,10 @@ public: void CheckForAutoSaveFile( const wxFileName& aFileName, const wxString& aBackupFileExtension ); /** - * Function SetModalMode - * Disable or enable all other windows, to emulate a dialog behavior - * Useful when the frame is used to show and selec items - * (see FOOTPRINT_VIEWER_FRAME and LIB_VIEW_FRAME) - * - * @param aModal = true to disable all other opened windows (i.e. - * this windows is in dialog mode - * = false to enable other windows - * This function is analog to MakeModal( aModal ), deprecated since wxWidgets 2.9.4 + * Function ShowChangedLanguage + * redraws the menus and what not in current language. */ - void SetModalMode( bool aModal ); + virtual void ShowChangedLanguage(); }; @@ -415,7 +401,6 @@ public: * then after a //==// break has additional calls to anchor toolbars in a way that matches * present functionality. */ - class EDA_PANEINFO : public wxAuiPaneInfo { diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 44e9488e56..5b696f5715 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -197,6 +197,8 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) void PGM_KICAD::OnPgmExit() { + Kiway.OnKiwayEnd(); + saveCommonSettings(); // write common settings to disk, and destroy everything in PGM_KICAD, @@ -253,7 +255,7 @@ void PGM_KICAD::destroy() } -KIWAY Kiway( &Pgm() ); +KIWAY Kiway( &Pgm(), KFCTL_CPP_PROJECT_SUITE ); /** diff --git a/kicad/kicad.h b/kicad/kicad.h index ffaac5afdc..ab76ac5cbc 100644 --- a/kicad/kicad.h +++ b/kicad/kicad.h @@ -140,6 +140,8 @@ public: private: int m_leftWinWidth; + void language_change( wxCommandEvent& event ); + public: KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title, const wxPoint& pos, const wxSize& size ); @@ -202,7 +204,6 @@ public: */ void ClearMsg(); - void SetLanguage( wxCommandEvent& event ); void OnRefresh( wxCommandEvent& event ); void OnSelectDefaultPdfBrowser( wxCommandEvent& event ); void OnSelectPreferredPdfBrowser( wxCommandEvent& event ); diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index 32d19c8d37..0d965c0af8 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -361,6 +361,14 @@ void KICAD_MANAGER_FRAME::OnRefresh( wxCommandEvent& event ) } +void KICAD_MANAGER_FRAME::language_change( wxCommandEvent& event ) +{ + int id = event.GetId(); + + Kiway.SetLanguage( id ); +} + + void KICAD_MANAGER_FRAME::ClearMsg() { m_MessagesBox->Clear(); diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index 0e1fce998d..e792987a3c 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -33,20 +33,20 @@ #include #include -/* Menubar and toolbar event table */ +// Menubar and toolbar event table BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) - /* Window events */ + // Window events EVT_SIZE( KICAD_MANAGER_FRAME::OnSize ) EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow ) - /* Toolbar events */ + // Toolbar events EVT_TOOL( ID_NEW_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject ) EVT_TOOL( ID_NEW_PROJECT_FROM_TEMPLATE, KICAD_MANAGER_FRAME::OnLoadProject ) EVT_TOOL( ID_LOAD_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject ) EVT_TOOL( ID_SAVE_PROJECT, KICAD_MANAGER_FRAME::OnSaveProject ) EVT_TOOL( ID_SAVE_AND_ZIP_FILES, KICAD_MANAGER_FRAME::OnArchiveFiles ) - /* Menu events */ + // Menu events EVT_MENU( ID_SAVE_PROJECT, KICAD_MANAGER_FRAME::OnSaveProject ) EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit ) EVT_MENU( ID_TO_EDITOR, KICAD_MANAGER_FRAME::OnOpenTextEditor ) @@ -63,16 +63,17 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) EVT_MENU( wxID_INDEX, KICAD_MANAGER_FRAME::GetKicadHelp ) EVT_MENU( wxID_ABOUT, KICAD_MANAGER_FRAME::GetKicadAbout ) - /* Range menu events */ - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::SetLanguage ) + // Range menu events + EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::language_change ) + EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, KICAD_MANAGER_FRAME::OnFileHistory ) // Special functions - #ifdef KICAD_USE_FILES_WATCHER +#ifdef KICAD_USE_FILES_WATCHER EVT_MENU( ID_INIT_WATCHED_PATHS, KICAD_MANAGER_FRAME::OnChangeWatchedPaths ) - #endif +#endif - /* Button events */ + // Button events EVT_BUTTON( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew ) EVT_BUTTON( ID_TO_CVPCB, KICAD_MANAGER_FRAME::OnRunCvpcb ) EVT_BUTTON( ID_TO_EESCHEMA, KICAD_MANAGER_FRAME::OnRunEeschema ) diff --git a/kicad/preferences.cpp b/kicad/preferences.cpp index 19bed9f1d1..2176d628bc 100644 --- a/kicad/preferences.cpp +++ b/kicad/preferences.cpp @@ -88,8 +88,3 @@ void KICAD_MANAGER_FRAME::OnSelectPreferredPdfBrowser( wxCommandEvent& event ) Pgm().WritePdfBrowserInfos(); } - -void KICAD_MANAGER_FRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_BASE_FRAME::SetLanguage( event ); -} diff --git a/pagelayout_editor/events_functions.cpp b/pagelayout_editor/events_functions.cpp index 0473900644..c2fd6982dc 100644 --- a/pagelayout_editor/events_functions.cpp +++ b/pagelayout_editor/events_functions.cpp @@ -70,12 +70,8 @@ BEGIN_EVENT_TABLE( PL_EDITOR_FRAME, EDA_DRAW_FRAME ) EVT_MENU( wxID_EXIT, PL_EDITOR_FRAME::OnQuit ) // menu Preferences - EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END, - PL_EDITOR_FRAME::Process_Config ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, - EDA_DRAW_FRAME::SetLanguage ) - EVT_MENU( ID_MENU_PL_EDITOR_SELECT_PREFERED_EDITOR, - EDA_BASE_FRAME::OnSelectPreferredEditor ) + EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END, PL_EDITOR_FRAME::Process_Config ) + EVT_MENU( ID_MENU_PL_EDITOR_SELECT_PREFERED_EDITOR, EDA_BASE_FRAME::OnSelectPreferredEditor ) EVT_MENU( wxID_PREFERENCES, PL_EDITOR_FRAME::Process_Config ) EVT_MENU( ID_MENU_SWITCH_BGCOLOR, PL_EDITOR_FRAME::Process_Config ) EVT_MENU( ID_MENU_GRID_ONOFF, PL_EDITOR_FRAME::Process_Config ) @@ -473,15 +469,6 @@ void PL_EDITOR_FRAME::OnQuit( wxCommandEvent& event ) Close( true ); } -/** - * Function SetLanguage - * called on a language menu selection - * Update Layer manager title and tabs texts - */ -void PL_EDITOR_FRAME::SetLanguage( wxCommandEvent& event ) -{ - EDA_DRAW_FRAME::SetLanguage( event ); -} void PL_EDITOR_FRAME::ToPlotter(wxCommandEvent& event) { diff --git a/pagelayout_editor/pl_editor_frame.h b/pagelayout_editor/pl_editor_frame.h index 7ba3a8dc15..e675cb9c9b 100644 --- a/pagelayout_editor/pl_editor_frame.h +++ b/pagelayout_editor/pl_editor_frame.h @@ -198,12 +198,6 @@ public: void SaveSettings( wxConfigBase* aCfg ); // override virtual - /** - * Function SetLanguage - * called on a language menu selection - */ - virtual void SetLanguage( wxCommandEvent& event ); - void Process_Special_Functions( wxCommandEvent& event ); void OnSelectOptionToolbar( wxCommandEvent& event ); diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt index fb8e189859..14db6b9ff6 100644 --- a/pcb_calculator/CMakeLists.txt +++ b/pcb_calculator/CMakeLists.txt @@ -75,7 +75,7 @@ if( USE_KIWAY_DLLS ) ${PCB_CALCULATOR_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=0;BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CALC;BUILD_KIWAY_DLL" ) target_link_libraries( pcb_calculator #singletop # replaces common, giving us restrictive control and link warnings. @@ -93,7 +93,6 @@ if( USE_KIWAY_DLLS ) add_library( pcb_calculator_kiface MODULE pcb_calculator.cpp ${PCB_CALCULATOR_SRCS} -# ${PCB_CALCULATOR_RESOURCES} ) set_target_properties( pcb_calculator_kiface PROPERTIES OUTPUT_NAME pcb_calculator diff --git a/pcb_calculator/pcb_calculator_frame.cpp b/pcb_calculator/pcb_calculator_frame.cpp index 7981201e25..3abd3601f2 100644 --- a/pcb_calculator/pcb_calculator_frame.cpp +++ b/pcb_calculator/pcb_calculator_frame.cpp @@ -134,6 +134,7 @@ PCB_CALCULATOR_FRAME::~PCB_CALCULATOR_FRAME() this->Freeze(); } + void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event ) { if( m_RegulatorListChanged ) diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp index 9fc22bd1e1..abba8d6d01 100644 --- a/pcbnew/block_module_editor.cpp +++ b/pcbnew/block_module_editor.cpp @@ -306,7 +306,7 @@ static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wx bool aErase ) { BASE_SCREEN* screen = aPanel->GetScreen(); - FOOTPRINT_EDIT_FRAME* moduleEditFrame = FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( aPanel->GetParent() ); + FOOTPRINT_EDIT_FRAME* moduleEditFrame = dynamic_cast( aPanel->GetParent() ); wxASSERT( moduleEditFrame ); MODULE* currentModule = moduleEditFrame->GetBoard()->m_Modules; diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 98a3ec4fee..e76623b0e4 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -190,21 +190,21 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_OPEN_MODULE_EDITOR: { - FOOTPRINT_EDIT_FRAME* editor = FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( this ); + FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, false ); if( !editor ) { - KIFACE_I& kf = Kiface(); - - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); + editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); editor->Show( true ); editor->Zoom_Automatique( false ); } else { + /* not needed on linux, other platforms need this? if( editor->IsIconized() ) editor->Iconize( false ); + */ editor->Raise(); @@ -218,21 +218,21 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_OPEN_MODULE_VIEWER: { - FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( this ); + FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); if( !viewer ) { - KIFACE_I& kf = Kiface(); - - viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); + viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } else { + /* not needed on linux, other platforms need this? if( viewer->IsIconized() ) viewer->Iconize( false ); + */ viewer->Raise(); @@ -848,20 +848,14 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } { - FOOTPRINT_EDIT_FRAME* editor = FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( this ); - - if( !editor ) - { - KIFACE_I& kf = Kiface(); - - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); - } + FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() ); SetCurItem( NULL ); // the current module could be deleted by editor->Show( true ); - editor->Iconize( false ); + + editor->Raise(); // Iconize( false ); } m_canvas->MoveCursorToCrossHair(); break; diff --git a/pcbnew/editmod.cpp b/pcbnew/editmod.cpp index 49325bc1eb..4a69ef6a02 100644 --- a/pcbnew/editmod.cpp +++ b/pcbnew/editmod.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -74,20 +75,13 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC ) if( retvalue == 2 ) { - FOOTPRINT_EDIT_FRAME* editor = FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( this ); - - if( !editor ) - { - KIFACE_I& kf = Kiface(); - - editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); - } + FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); editor->Load_Module_From_BOARD( Module ); SetCurItem( NULL ); editor->Show( true ); - editor->Iconize( false ); + editor->Raise(); // Iconize( false ); } } diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index e82db334fc..ab4023846a 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -145,7 +145,7 @@ MODULE* FOOTPRINT_WIZARD_FRAME::GetBuiltFootprint() { FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName ); - if( footprintWizard && m_exportRequest ) + if( footprintWizard && m_modal_ret_val ) { return footprintWizard->GetModule(); } diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index b09623f074..7fac217892 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -113,18 +113,18 @@ static wxAcceleratorEntry accels[] = #define EXTRA_BORDER_SIZE 2 -/* Function FOOTPRINT_WIZARD_FRAME - * it's the constructor for the footprint wizard frame, it creates everything inside - */ #define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" ) -FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, FOOTPRINT_EDIT_FRAME* aParent, - wxSemaphore* semaphore, long style ) : - PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_FOOTPRINT_WIZARD, - _( "Footprint Wizard" ), - wxDefaultPosition, wxDefaultSize, style, FOOTPRINT_WIZARD_FRAME_NAME ) +FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, + wxWindow* aParent, FRAME_T aFrameType ) : + PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Wizard" ), + wxDefaultPosition, wxDefaultSize, + KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT, + FOOTPRINT_WIZARD_FRAME_NAME ) { + wxASSERT( aFrameType==FRAME_PCB_FOOTPRINT_WIZARD_MODAL ); + wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); m_FrameName = FOOTPRINT_WIZARD_FRAME_NAME; @@ -137,14 +137,10 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, FOOTPRINT_EDIT_FR SetIcon( icon ); m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; - m_semaphore = semaphore; m_wizardName.Empty(); - m_exportRequest = false; - - if( m_semaphore ) - SetModalMode( true ); SetBoard( new BOARD() ); + // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); @@ -244,17 +240,14 @@ FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME() } -/* Function OnCloseWindow - * Handles the close event, saving settings an destroying or releasing a semaphore from caller - */ void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) { - if( m_semaphore ) + if( IsModal() ) { - m_semaphore->Post(); - SetModalMode( false ); - // This window will be destroyed by the calling function, - // to avoid side effects + // Only dismiss a modal frame once, so that the return values set by + // the prior DismissModal() are not bashed for ShowModal(). + if( !IsDismissed() ) + DismissModal( false ); } else { @@ -265,15 +258,11 @@ void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) void FOOTPRINT_WIZARD_FRAME::ExportSelectedFootprint( wxCommandEvent& aEvent ) { - m_exportRequest = true; + DismissModal( true ); Close(); } -/* Function OnSize - * It handles a dialog resize event, asking for an update - * - */ void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv ) { if( m_auimgr.GetManagedWindow() ) @@ -283,10 +272,6 @@ void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv ) } -/* Function OnSetRelativeOffset - * Updates the cursor position and the status bar - * - */ void FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset( wxCommandEvent& event ) { GetScreen()->m_O_Curseur = GetCrossHairPosition(); @@ -294,10 +279,6 @@ void FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset( wxCommandEvent& event ) } -/* Function ReCreatePageList - * It recreates the list of pages for a new loaded wizard - * - */ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() { if( m_pageList == NULL ) @@ -326,11 +307,6 @@ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() } -/* Function ReCreateParameterList - * It creates the parameter grid for a certain wizard page of the current wizard - * - */ - void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() { if( m_parameterGrid == NULL ) @@ -620,7 +596,7 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar() { wxString msg; - if( m_mainToolBar == NULL ) + if( !m_mainToolBar ) { m_mainToolBar = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT ); @@ -665,7 +641,7 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg ); - if( m_semaphore ) + if( m_Ident == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ) { // The library browser is called from a "load component" command m_mainToolBar->AddSeparator(); diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index c36ecc70c3..d65c309f34 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -35,41 +35,37 @@ #include class wxSashLayoutWindow; class wxListBox; -class wxSemaphore; class wxGrid; class wxGridEvent; class FOOTPRINT_EDIT_FRAME; /** - * Component library viewer main window. + * Class FOOTPRINT_WIZARD_FRAME */ class FOOTPRINT_WIZARD_FRAME : public PCB_BASE_FRAME { private: - wxListBox* m_pageList; // < The list of pages - int m_pageListWidth; // < width of the window - wxGrid* m_parameterGrid; // < The list of parameters - int m_parameterGridWidth; // < size of the grid + wxListBox* m_pageList; ///< The list of pages + int m_pageListWidth; ///< width of the window + wxGrid* m_parameterGrid; ///< The list of parameters + int m_parameterGridWidth; ///< size of the grid // Flags - wxSemaphore* m_semaphore; // < != NULL if the frame must emulate a modal dialog - wxString m_configPath; // < subpath for configuration - bool m_exportRequest; // < true if the current footprint should be exported + wxString m_configPath; ///< subpath for configuration protected: - wxString m_wizardName; // < name of the current wizard - wxString m_wizardDescription; // < description of the wizard - wxString m_wizardStatus; // < current wizard status + wxString m_wizardName; ///< name of the current wizard + wxString m_wizardDescription; ///< description of the wizard + wxString m_wizardStatus; ///< current wizard status public: - FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, - FOOTPRINT_EDIT_FRAME* parent, wxSemaphore* semaphore = NULL, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + + FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* parent, FRAME_T aFrameType ); ~FOOTPRINT_WIZARD_FRAME(); - MODULE* GetBuiltFootprint( void ); + MODULE* GetBuiltFootprint(); private: diff --git a/pcbnew/gpcb_plugin.cpp b/pcbnew/gpcb_plugin.cpp index 7585aad4f9..1f207eaaa6 100644 --- a/pcbnew/gpcb_plugin.cpp +++ b/pcbnew/gpcb_plugin.cpp @@ -285,7 +285,7 @@ void GPCB_FPL_CACHE::Load() MODULE* footprint = parseMODULE( &reader ); // The footprint name is the file name without the extension. - footprint->SetFPID( fn.GetName() ); + footprint->SetFPID( FPID( fn.GetName() ) ); m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) ); } while( dir.GetNext( &fpFileName ) ); @@ -299,7 +299,6 @@ void GPCB_FPL_CACHE::Load() void GPCB_FPL_CACHE::Remove( const wxString& aFootprintName ) { - std::string footprintName = TO_UTF8( aFootprintName ); MODULE_CITER it = m_modules.find( footprintName ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index fd7059399a..80015dc147 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -279,7 +279,7 @@ void FP_CACHE::Load() MODULE* footprint = (MODULE*) m_owner->m_parser->Parse(); // The footprint name is the file name without the extension. - footprint->SetFPID( fullPath.GetName() ); + footprint->SetFPID( FPID( fullPath.GetName() ) ); m_modules.insert( name, new FP_CACHE_ITEM( footprint, fullPath ) ); } while( dir.GetNext( &fpFileName ) ); @@ -657,14 +657,14 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel, ")\n\n" ); - // Save net codes and names + // Save net codes and names for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end(); net != netEnd; ++net ) { m_out->Print( aNestLevel, "(net %d %s)\n", m_mapping->Translate( net->GetNet() ), m_out->Quotew( net->GetNetname() ).c_str() ); - } + } m_out->Print( 0, "\n" ); diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index d8e47c0e46..487f356e6a 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -620,7 +620,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, if( footprintName.IsEmpty() ) { footprintName = wxT("noname"); - aModule->SetFPID( footprintName ); + aModule->SetFPID( FPID( footprintName ) ); } bool module_exists = false; diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 6c324b4d65..3aca4d620f 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -34,6 +34,8 @@ #include #include #include +#include +//#include #include #include #include @@ -118,32 +120,21 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser() { - wxString fpname; - wxString fpid; + // Close the current non-modal Lib browser if opened, and open a new one, in "modal" mode: + FOOTPRINT_VIEWER_FRAME* viewer; - wxSemaphore semaphore( 0, 1 ); - - // Close the current Lib browser, if opened, and open a new one, in "modal" mode: - FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( this ); + viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); if( viewer ) viewer->Destroy(); - viewer = new FOOTPRINT_VIEWER_FRAME( &Kiway(), this, &semaphore ); + viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); - // Show the library viewer frame until it is closed - while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event - { - wxYield(); - wxMilliSleep( 50 ); - } + wxString fpid; - fpname = viewer->GetSelectedFootprint(); + viewer->ShowModal( &fpid ); - if( !!fpname ) - { - fpid = viewer->GetSelectedLibrary() + wxT( ":" ) + fpname; - } + //DBG(printf("%s: fpid:'%s'\n", __func__, TO_UTF8( fpid ) );) viewer->Destroy(); diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index c9198d4a41..73a20509f8 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -262,25 +263,19 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_OPEN_MODULE_VIEWER: { - // Make a _project specific_ PCB_EDIT_FRAME be the start of the search in - // FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer(); - - PCB_EDIT_FRAME* top_project = dynamic_cast( GetParent() ); - wxASSERT( top_project ); // dynamic_cast returns NULL if class mismatch. - - FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( top_project ); + FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); if( !viewer ) { - KIFACE_I& kf = Kiface(); - - viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); + viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } else { + /* if( viewer->IsIconized() ) viewer->Iconize( false ); + */ viewer->Raise(); @@ -324,41 +319,37 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: { - wxSemaphore semaphore( 0, 1 ); + FOOTPRINT_WIZARD_FRAME* wizard = (FOOTPRINT_WIZARD_FRAME*) Kiway().Player( + FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true ); - FOOTPRINT_WIZARD_FRAME* wizard = new FOOTPRINT_WIZARD_FRAME( &Kiway(), this, &semaphore, - KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); - - wizard->Show( true ); wizard->Zoom_Automatique( false ); - while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event + wxString not_used; + + if( wizard->ShowModal( ¬_used ) ) { - wxYield(); - wxMilliSleep( 50 ); - } + // Creates the new footprint from python script wizard + MODULE* module = wizard->GetBuiltFootprint(); - // Creates the new footprint from python script wizard - MODULE* module = wizard->GetBuiltFootprint(); + if( module ) // i.e. if create module command not aborted + { + Clear_Pcb( true ); + GetScreen()->ClearUndoRedoList(); + SetCurItem( NULL ); + SetCrossHairPosition( wxPoint( 0, 0 ) ); - if( module ) // i.e. if create module command not aborted - { - Clear_Pcb( true ); - GetScreen()->ClearUndoRedoList(); - SetCurItem( NULL ); - SetCrossHairPosition( wxPoint( 0, 0 ) ); + // Add the new object to board + module->SetParent( (EDA_ITEM*)GetBoard() ); + GetBoard()->m_Modules.Append( module ); - // Add the new object to board - module->SetParent( (EDA_ITEM*)GetBoard() ); - GetBoard()->m_Modules.Append( module ); - - // Initialize data relative to nets and netclasses (for a new - // module the defaults are used) - // This is mandatory to handle and draw pads - GetBoard()->BuildListOfNets(); - redraw = true; - module->SetPosition( wxPoint( 0, 0 ) ); - module->ClearFlags(); + // Initialize data relative to nets and netclasses (for a new + // module the defaults are used) + // This is mandatory to handle and draw pads + GetBoard()->BuildListOfNets(); + redraw = true; + module->SetPosition( wxPoint( 0, 0 ) ); + module->ClearFlags(); + } } wizard->Destroy(); @@ -378,7 +369,8 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { // update module in the current board, // not just add it to the board with total disregard for the netlist... - PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) GetParent(); + PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, true ); + BOARD* mainpcb = pcbframe->GetBoard(); MODULE* source_module = NULL; MODULE* module_in_edit = GetBoard()->m_Modules; diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 4378beac06..438c4ed35e 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -53,17 +53,6 @@ public: */ static const wxChar* GetFootprintEditorFrameName(); - /** - * Function GetActiveFootprintEditor (static) - * - * @param aTopOfProject is a PCB_EDIT_FRAME* window which anchors the search in - * a project specific way. - * - * @return a reference to the current opened Footprint editor - * or NULL if no Footprint editor currently opened - */ - static FOOTPRINT_EDIT_FRAME* GetActiveFootprintEditor( const wxWindow* aTopOfProject ); - BOARD_DESIGN_SETTINGS& GetDesignSettings() const; // overload PCB_BASE_FRAME, get parent's void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ); // overload @@ -415,7 +404,7 @@ public: protected: /// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory. - FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, PCB_EDIT_FRAME* aParent ); + FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); static BOARD* s_Pcb; ///< retain board across invocations of module editor diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index cb7a0425fc..c2a9b93d4e 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -151,7 +151,7 @@ END_EVENT_TABLE() #define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" ) -FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, PCB_EDIT_FRAME* aParent ) : +FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) @@ -291,19 +291,6 @@ const wxChar* FOOTPRINT_EDIT_FRAME::GetFootprintEditorFrameName() } -/* return a reference to the current opened Footprint editor - * or NULL if no Footprint editor currently opened - */ -FOOTPRINT_EDIT_FRAME* FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( const wxWindow* aParent ) -{ - // top_of_project! - wxASSERT( dynamic_cast( aParent ) ); - - wxWindow* ret = wxWindow::FindWindowByName( GetFootprintEditorFrameName(), aParent ); - return (FOOTPRINT_EDIT_FRAME*) ret; -} - - BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const { // get the BOARD_DESIGN_SETTINGS from the parent editor, not our BOARD. diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 30bb30063e..1db99caf30 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -70,12 +71,12 @@ wxString FOOTPRINT_VIEWER_FRAME::m_selectedFootprintName; BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME ) - /* Window events */ + // Window events EVT_CLOSE( FOOTPRINT_VIEWER_FRAME::OnCloseWindow ) EVT_SIZE( FOOTPRINT_VIEWER_FRAME::OnSize ) EVT_ACTIVATE( FOOTPRINT_VIEWER_FRAME::OnActivate ) - /* Toolbar events */ + // Toolbar events EVT_TOOL( ID_MODVIEW_SELECT_LIB, FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary ) EVT_TOOL( ID_MODVIEW_SELECT_PART, @@ -88,7 +89,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME ) FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint ) EVT_TOOL( ID_MODVIEW_SHOW_3D_VIEW, FOOTPRINT_VIEWER_FRAME::Show3D_Frame ) - /* listbox events */ + // listbox events EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList ) EVT_LISTBOX( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList ) EVT_LISTBOX_DCLICK( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList ) @@ -118,14 +119,16 @@ static wxAcceleratorEntry accels[] = #define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" ) -FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, wxSemaphore* aSemaphore ) : - PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_VIEWER, _( "Footprint Library Browser" ), +FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : + PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, - !aSemaphore ? - KICAD_DEFAULT_DRAWFRAME_STYLE : - KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT, + aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ? + KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT : + KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintViewerFrameName() ) { + wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL ); + wxAcceleratorTable table( DIM( accels ), accels ); m_FrameName = GetFootprintViewerFrameName(); @@ -145,12 +148,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* a m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); - m_semaphore = aSemaphore; m_selectedFootprintName.Empty(); - if( m_semaphore ) - SetModalMode( true ); - SetBoard( new BOARD() ); // Ensure all layers and items are visible: @@ -237,7 +236,6 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* a } #if 0 // no. - // Set min size (overwrite params read in LoadPerspective(), if any) m_auimgr.GetPane( m_libList ).MinSize( minsize ); m_auimgr.GetPane( m_footprintList ).MinSize( minsize ); @@ -271,45 +269,16 @@ const wxChar* FOOTPRINT_VIEWER_FRAME::GetFootprintViewerFrameName() } -FOOTPRINT_VIEWER_FRAME* FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( const KIWAY_PLAYER* aParent ) -{ - wxASSERT( aParent ); - - // We search only within the current project, and do so by limiting - // the search scope to a wxWindow hierarchy subset. Find the top most - // KIWAY_PLAYER which is part of this PROJECT by matching its KIWAY* to the - // most immediate parent's. - - // NOTE: an open FOOTPRINT_VIEWER_FRAME may have either the PCB_EDIT_FRAME - // or the FOOTPRINT_EDIT_FRAME as parent. - - KIWAY* kiway = &aParent->Kiway(); - wxWindow* frame; - - while( (frame = aParent->GetParent()) != NULL ) - { - // will go NULL when we reach a non-KIWAY_PLAYER - KIWAY_PLAYER* kwp = dynamic_cast( frame ); - - if( kwp && &kwp->Kiway() == kiway ) - aParent = kwp; - else - break; - } - - return (FOOTPRINT_VIEWER_FRAME*) wxWindow::FindWindowByName( - GetFootprintViewerFrameName(), aParent ); -} - - void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { - if( m_semaphore ) + if( IsModal() ) { - m_semaphore->Post(); - SetModalMode( false ); - // This window will be destroyed by the calling function, - // to avoid side effects + // Only dismiss a modal frame once, so that the return values set by + // the prior DismissModal() are not bashed for ShowModal(). + if( !IsDismissed() ) + DismissModal( false ); + + // window will be destroyed by the calling function. } else Destroy(); @@ -464,15 +433,23 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList( wxCommandEvent& event ) { - if( m_semaphore ) + if( IsModal() ) { + // @todo(DICK) ExportSelectedFootprint( event ); + // Prevent the double click from being as a single mouse button release // event in the parent window which would cause the part to be parked - // rather than staying in mode mode. + // rather than staying in move mode. // Remember the mouse button will be released in the parent window // thus creating a mouse button release event which should be ignored - ((PCB_BASE_FRAME*)GetParent())->SkipNextLeftButtonReleaseEvent(); + PCB_EDIT_FRAME* pcbframe = dynamic_cast( GetParent() ); + + // The parent may not be the board editor: + if( pcbframe ) + { + pcbframe->SkipNextLeftButtonReleaseEvent(); + } } } @@ -482,9 +459,24 @@ void FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint( wxCommandEvent& event ) int ii = m_footprintList->GetSelection(); if( ii >= 0 ) - m_selectedFootprintName = m_footprintList->GetString( ii ); + { + wxString fp_name = m_footprintList->GetString( ii ); + + // @todo(DICK) assign to static now, later PROJECT retained string. + m_selectedFootprintName = fp_name; + + FPID fpid; + + fpid.SetLibNickname( GetSelectedLibrary() ); + fpid.SetFootprintName( fp_name ); + + DismissModal( true, fpid.Format() ); + } else + { m_selectedFootprintName.Empty(); + DismissModal( false ); + } Close( true ); } @@ -580,25 +572,25 @@ void FOOTPRINT_VIEWER_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition screen->m_O_Curseur = GetCrossHairPosition(); break; - case WXK_NUMPAD8: /* cursor moved up */ + case WXK_NUMPAD8: // cursor moved up case WXK_UP: pos.y -= KiROUND( gridSize.y ); m_canvas->MoveCursor( pos ); break; - case WXK_NUMPAD2: /* cursor moved down */ + case WXK_NUMPAD2: // cursor moved down case WXK_DOWN: pos.y += KiROUND( gridSize.y ); m_canvas->MoveCursor( pos ); break; - case WXK_NUMPAD4: /* cursor moved left */ + case WXK_NUMPAD4: // cursor moved left case WXK_LEFT: pos.x -= KiROUND( gridSize.x ); m_canvas->MoveCursor( pos ); break; - case WXK_NUMPAD6: /* cursor moved right */ + case WXK_NUMPAD6: // cursor moved right case WXK_RIGHT: pos.x += KiROUND( gridSize.x ); m_canvas->MoveCursor( pos ); @@ -621,7 +613,7 @@ void FOOTPRINT_VIEWER_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition } } - UpdateStatusBar(); /* Display new cursor coordinates */ + UpdateStatusBar(); // Display new cursor coordinates } @@ -746,11 +738,13 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event ) { - PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) GetParent(); + // 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 ); + wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension; MODULE* oldmodule = GetBoard()->m_Modules; - MODULE* module = LoadModuleFromLibrary( libname, parent->FootprintLibs(), - false ); + MODULE* module = LoadModuleFromLibrary( libname, parent->FootprintLibs(), false ); if( module ) { diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h index dab4432f3b..9595866458 100644 --- a/pcbnew/modview_frame.h +++ b/pcbnew/modview_frame.h @@ -34,7 +34,6 @@ class wxSashLayoutWindow; class wxListBox; -class wxSemaphore; class FP_LIB_TABLE; namespace PCB { struct IFACE; } @@ -44,25 +43,13 @@ namespace PCB { struct IFACE; } */ class FOOTPRINT_VIEWER_FRAME : public PCB_BASE_FRAME { - friend struct PCB::IFACE; - -private: - wxListBox* m_libList; // The list of libs names - wxListBox* m_footprintList; // The list of footprint names - - // Flags - wxSemaphore* m_semaphore; // != NULL if the frame emulates a modal dialog - wxString m_configPath; // subpath for configuration + friend struct PCB::IFACE; // constructor called from here only protected: - static wxString m_libraryName; // Current selected library - static wxString m_footprintName; // Current selected footprint - static wxString m_selectedFootprintName; // When the viewer is used to select a footprint - // the selected footprint is here + FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ); + public: - FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, wxSemaphore* aSemaphore = NULL ); - ~FOOTPRINT_VIEWER_FRAME(); /** @@ -72,17 +59,6 @@ public: */ static const wxChar* GetFootprintViewerFrameName(); - /** - * Function GetActiveFootprintViewer (static) - * - * @param aParent the KIWAY_PLAYER which is the parent of the calling wxWindow. - * This is used to traverse the window hierarchy upwards to the topmost - * KIWAY_PLAYER which is still part of the same project. - * - * @return Any currently opened Footprint viewer or NULL if none. - */ - static FOOTPRINT_VIEWER_FRAME* GetActiveFootprintViewer( const KIWAY_PLAYER* aParent ); - wxString& GetSelectedFootprint( void ) const { return m_selectedFootprintName; } const wxString GetSelectedLibraryFullName(); @@ -102,8 +78,19 @@ public: */ void ReCreateLibraryList(); + private: + wxListBox* m_libList; // The list of libs names + wxListBox* m_footprintList; // The list of footprint names + + wxString m_configPath; // subpath for configuration + + static wxString m_libraryName; // Current selected library + static wxString m_footprintName; // Current selected footprint + static wxString m_selectedFootprintName; // When the viewer is used to select a footprint + + void OnSize( wxSizeEvent& event ); void ReCreateFootprintList(); @@ -193,7 +180,6 @@ private: void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} - DECLARE_EVENT_TABLE() }; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 04ecd6af0b..a95e7804fa 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -152,8 +152,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( ID_PCB_DISPLAY_OPTIONS_SETUP, PCB_EDIT_FRAME::InstallDisplayOptionsDialog ) EVT_MENU( ID_PCB_USER_GRID_SETUP, PCB_EDIT_FRAME::Process_Special_Functions ) - EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, PCB_EDIT_FRAME::SetLanguage ) - // menu Postprocess EVT_MENU( ID_PCB_GEN_POS_MODULES_FILE, PCB_EDIT_FRAME::GenFootprintsPositionFile ) EVT_MENU( ID_PCB_GEN_DRILL_FILE, PCB_EDIT_FRAME::InstallDrillFrame ) @@ -1024,9 +1022,11 @@ void PCB_EDIT_FRAME::SetVisibleAlls() } -void PCB_EDIT_FRAME::SetLanguage( wxCommandEvent& event ) +void PCB_EDIT_FRAME::ShowChangedLanguage() { - EDA_DRAW_FRAME::SetLanguage( event ); + // call my base class + PCB_BASE_FRAME::ShowChangedLanguage(); + m_Layers->SetLayersManagerTabsText(); wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_Layers ); @@ -1034,10 +1034,6 @@ void PCB_EDIT_FRAME::SetLanguage( wxCommandEvent& event ) pane_info.Caption( _( "Visibles" ) ); m_auimgr.Update(); ReFillLayerWidget(); - - FOOTPRINT_EDIT_FRAME* moduleEditFrame = FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor( this ); - if( moduleEditFrame ) - moduleEditFrame->EDA_DRAW_FRAME::SetLanguage( event ); } diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 3c47fb7f3d..793a537885 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -60,6 +60,7 @@ #include #include #include +#include // Colors for layers and items @@ -109,7 +110,6 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case FRAME_PCB: { PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent ); @@ -132,11 +132,7 @@ static struct IFACE : public KIFACE_I case FRAME_PCB_MODULE_EDITOR: { - // yuck: - PCB_EDIT_FRAME* editor = dynamic_cast( aParent ); - wxASSERT( editor ); - - FOOTPRINT_EDIT_FRAME* frame = new FOOTPRINT_EDIT_FRAME( aKiway, editor ); + FOOTPRINT_EDIT_FRAME* frame = new FOOTPRINT_EDIT_FRAME( aKiway, aParent ); frame->Zoom_Automatique( true ); @@ -148,12 +144,10 @@ static struct IFACE : public KIFACE_I break; case FRAME_PCB_MODULE_VIEWER: + case FRAME_PCB_MODULE_VIEWER_MODAL: { - // yuck: - PCB_BASE_FRAME* editor = dynamic_cast( aParent ); - wxASSERT( editor ); - - FOOTPRINT_VIEWER_FRAME* frame = new FOOTPRINT_VIEWER_FRAME( aKiway, editor ); + FOOTPRINT_VIEWER_FRAME* frame = new FOOTPRINT_VIEWER_FRAME( + aKiway, aParent, FRAME_T( aClassId ) ); frame->Zoom_Automatique( true ); @@ -164,6 +158,15 @@ static struct IFACE : public KIFACE_I } break; + case FRAME_PCB_FOOTPRINT_WIZARD_MODAL: + { + FOOTPRINT_WIZARD_FRAME* frame = new FOOTPRINT_WIZARD_FRAME( + aKiway, aParent, FRAME_T( aClassId ) ); + + return frame; + } + break; + default: ; } diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index a9870c279d..df8df9fcc3 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -142,7 +142,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) FOOTPRINT_VIEWER_FRAME* viewer; - if( tableChanged && (viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( this )) != NULL ) + if( tableChanged && (viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false )) != NULL ) { viewer->ReCreateLibraryList(); } diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp index 02fccab586..3994a2a96d 100644 --- a/pcbnew/tool_modview.cpp +++ b/pcbnew/tool_modview.cpp @@ -95,9 +95,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg ); - // Enable this tool only if the library browser is called from - // a "load component" command - if( m_semaphore ) + // Enable this tool only if the library browser is intended for modal use. + if( m_Ident == FRAME_PCB_MODULE_VIEWER_MODAL ) { m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD, wxEmptyString, From f16f248bf96ce56a9b8cd8d68836335f1dd60167 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 3 May 2014 19:44:57 -0500 Subject: [PATCH 04/10] Change order of headers for wx 2.8, use wxWindowDisabler not ENABLE_DISABLE. --- common/kiway.cpp | 5 +- common/kiway_player.cpp | 74 +++++++------------ .../dialog_edit_component_in_schematic.cpp | 35 ++++++++- include/kiway_player.h | 2 +- pcbnew/modedit.cpp | 4 +- 5 files changed, 65 insertions(+), 55 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index a599474f06..8f2ebf9824 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -23,8 +23,6 @@ */ #include -#include -#include #include #include @@ -34,6 +32,9 @@ #include #include +#include +#include + KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT]; int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 31aca7d1d8..274e4e564c 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -1,3 +1,27 @@ +/* + * 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 @@ -5,6 +29,7 @@ #include #include #include +#include BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) @@ -46,51 +71,6 @@ void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) } -static void makeModal( wxFrame* aFrame, bool IsModal ) -{ - // disable or enable all other top level windows -#if wxCHECK_VERSION(2, 9, 4) - wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); - - while( node ) - { - wxWindow* win = node->GetData(); - - if( win != aFrame ) - win->Enable( !IsModal ); - - node = node->GetNext(); - } -#else - // Deprecated since wxWidgets 2.9.4 - aFrame->MakeModal( IsModal ); -#endif -} - - -/** - * toggle global wxFrame enable/disable state, does the re-enable part even - * if an exception is thrown. - */ -struct ENABLE_DISABLE -{ - wxFrame* m_frame; - - ENABLE_DISABLE( wxFrame* aFrame ) : - m_frame( aFrame ) - { - makeModal( aFrame, true ); - } - - ~ENABLE_DISABLE() - { - // Re-enable all frames, (oops, even if they were previously inactive). - // This is probably why this function was deprecated in wx. - makeModal( m_frame, false ); - } -}; - - bool KIWAY_PLAYER::ShowModal( wxString* aResult ) { /* @@ -103,10 +83,10 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) vtable and therefore cross-module capable. */ - volatile bool dismissed = false; + volatile bool dismissed = false; // disable all frames except the modal one, re-enable on exit, exception safe. - ENABLE_DISABLE toggle( this ); + wxWindowDisabler toggle( this ); m_modal_dismissed = &dismissed; diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 9a6644d327..4fc02d14fb 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -435,8 +436,38 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::deleteFieldButtonHandler( wxCommandEven void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& event ) { - wxString datasheet_uri = fieldValueTextCtrl->GetValue(); - ::wxLaunchDefaultBrowser( datasheet_uri ); +#if 1 + wxString datasheet_uri = fieldValueTextCtrl->GetValue(); + ::wxLaunchDefaultBrowser( datasheet_uri ); + +#else + unsigned fieldNdx = getSelectedFieldNdx(); + +/* + if( fieldNdx == DATASHEET ) + { + wxString datasheet_uri = fieldValueTextCtrl->GetValue(); + ::wxLaunchDefaultBrowser( datasheet_uri ); + } + else if( fieldNdx == FOOTPRINT ) +*/ + { + // pick a footprint + wxString fpid; + + KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); + + if( frame->ShowModal( &fpid ) ) + { + printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); + } + + frame->Show( false ); // keep the frame open, but hidden. + + Raise(); + } +#endif + } diff --git a/include/kiway_player.h b/include/kiway_player.h index 8188ad35c8..6a08e70ed0 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -180,7 +180,7 @@ public: * @return bool - true if frame implementation called KIWAY_PLAYER::DismissModal() * with aRetVal of true. */ - VTBL_ENTRY bool ShowModal( wxString* aResult ); + VTBL_ENTRY bool ShowModal( wxString* aResult = NULL ); //-------------------------------------------------------- diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 73a20509f8..26e6ca7fde 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -324,9 +324,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) wizard->Zoom_Automatique( false ); - wxString not_used; - - if( wizard->ShowModal( ¬_used ) ) + if( wizard->ShowModal() ) { // Creates the new footprint from python script wizard MODULE* module = wizard->GetBuiltFootprint(); From 85c5aa22c6b2c00c381f326df8a3805cc4856de6 Mon Sep 17 00:00:00 2001 From: Lorenzo Marcantonio Date: Sun, 4 May 2014 19:08:36 +0200 Subject: [PATCH 05/10] Constification of HitTest and GetParent In particular HitTest for zones *do not* select the nearest vertex/edge as a side effect --- 3d-viewer/3d_canvas.h | 2 +- 3d-viewer/3d_viewer.h | 2 +- common/draw_panel.cpp | 2 +- .../page_layout/page_layout_graphic_items.cpp | 12 +++--- cvpcb/cvstruct.h | 2 +- cvpcb/listboxes.cpp | 2 +- eeschema/class_libentry.h | 4 +- eeschema/lib_arc.cpp | 4 +- eeschema/lib_arc.h | 4 +- eeschema/lib_bezier.cpp | 4 +- eeschema/lib_bezier.h | 4 +- eeschema/lib_circle.cpp | 4 +- eeschema/lib_circle.h | 4 +- eeschema/lib_draw_item.h | 6 +-- eeschema/lib_field.cpp | 36 ++++++---------- eeschema/lib_field.h | 6 +-- eeschema/lib_pin.cpp | 4 +- eeschema/lib_pin.h | 4 +- eeschema/lib_polyline.cpp | 4 +- eeschema/lib_polyline.h | 4 +- eeschema/lib_rectangle.cpp | 4 +- eeschema/lib_rectangle.h | 4 +- eeschema/lib_text.cpp | 17 +++----- eeschema/lib_text.h | 6 +-- eeschema/sch_collectors.h | 2 +- gerbview/class_GERBER.h | 2 +- gerbview/class_gerber_draw_item.cpp | 6 +-- gerbview/class_gerber_draw_item.h | 6 +-- include/base_struct.h | 6 +-- include/class_board_item.h | 2 +- include/class_drawpanel.h | 2 +- include/sch_item_struct.h | 5 ++- include/worksheet_shape_builder.h | 14 +++--- kicad/class_treeprojectfiles.h | 2 +- pcbnew/class_dimension.cpp | 2 +- pcbnew/class_dimension.h | 2 +- pcbnew/class_drawsegment.cpp | 2 +- pcbnew/class_drawsegment.h | 2 +- pcbnew/class_marker_pcb.h | 2 +- pcbnew/class_mire.cpp | 2 +- pcbnew/class_mire.h | 2 +- pcbnew/class_module.cpp | 2 +- pcbnew/class_module.h | 2 +- pcbnew/class_pad.cpp | 2 +- pcbnew/class_pad.h | 7 +-- pcbnew/class_pcb_text.h | 2 +- pcbnew/class_text_mod.cpp | 5 ++- pcbnew/class_text_mod.h | 2 +- pcbnew/class_track.cpp | 2 +- pcbnew/class_track.h | 2 +- pcbnew/class_zone.cpp | 43 ++++++++++--------- pcbnew/class_zone.h | 15 ++++--- pcbnew/controle.cpp | 40 +++++++++++------ pcbnew/dialogs/dialog_general_options.h | 2 +- pcbnew/eagle_plugin.cpp | 2 + pcbnew/onrightclick.cpp | 4 +- pcbnew/router/pns_node.cpp | 6 +-- pcbnew/router/pns_node.h | 2 +- pcbnew/zones_by_polygon.cpp | 12 +++--- polygon/polygon_test_point_inside.cpp | 2 +- polygon/polygon_test_point_inside.h | 4 +- 61 files changed, 188 insertions(+), 176 deletions(-) diff --git a/3d-viewer/3d_canvas.h b/3d-viewer/3d_canvas.h index d4ad84cebf..b68541dfdf 100644 --- a/3d-viewer/3d_canvas.h +++ b/3d-viewer/3d_canvas.h @@ -80,7 +80,7 @@ public: EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList = 0 ); ~EDA_3D_CANVAS(); - EDA_3D_FRAME* Parent() { return (EDA_3D_FRAME*)GetParent(); } + EDA_3D_FRAME* Parent() const { return static_cast( GetParent() ); } BOARD* GetBoard() { return Parent()->GetBoard(); } diff --git a/3d-viewer/3d_viewer.h b/3d-viewer/3d_viewer.h index 46c92053b7..c0f950a67a 100644 --- a/3d-viewer/3d_viewer.h +++ b/3d-viewer/3d_viewer.h @@ -81,7 +81,7 @@ public: m_auimgr.UnInit(); }; - PCB_BASE_FRAME* Parent() { return (PCB_BASE_FRAME*)GetParent(); } + PCB_BASE_FRAME* Parent() const { return (PCB_BASE_FRAME*)GetParent(); } BOARD* GetBoard(); diff --git a/common/draw_panel.cpp b/common/draw_panel.cpp index 1e3adb750b..9ac1875616 100644 --- a/common/draw_panel.cpp +++ b/common/draw_panel.cpp @@ -165,7 +165,7 @@ EDA_DRAW_PANEL::~EDA_DRAW_PANEL() } -EDA_DRAW_FRAME* EDA_DRAW_PANEL::GetParent() +EDA_DRAW_FRAME* EDA_DRAW_PANEL::GetParent() const { wxWindow* mom = wxScrolledWindow::GetParent(); return (EDA_DRAW_FRAME*) mom; diff --git a/common/page_layout/page_layout_graphic_items.cpp b/common/page_layout/page_layout_graphic_items.cpp index aeb4b53696..c927e935df 100644 --- a/common/page_layout/page_layout_graphic_items.cpp +++ b/common/page_layout/page_layout_graphic_items.cpp @@ -192,7 +192,7 @@ void WS_DRAW_ITEM_TEXT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) } // return true if the point aPosition is on the text -bool WS_DRAW_ITEM_TEXT::HitTest( const wxPoint& aPosition) +bool WS_DRAW_ITEM_TEXT::HitTest( const wxPoint& aPosition) const { return EDA_TEXT::TextHitTest( aPosition, 0 ); } @@ -221,7 +221,7 @@ void WS_DRAW_ITEM_POLYGON::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) // return true if the point aPosition is inside one of polygons #include -bool WS_DRAW_ITEM_POLYGON::HitTest( const wxPoint& aPosition) +bool WS_DRAW_ITEM_POLYGON::HitTest( const wxPoint& aPosition) const { return TestPointInsidePolygon( &m_Corners[0], m_Corners.size(), aPosition ); @@ -249,7 +249,7 @@ void WS_DRAW_ITEM_RECT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) } // return true if the point aPosition is on the rect outline -bool WS_DRAW_ITEM_RECT::HitTest( const wxPoint& aPosition) +bool WS_DRAW_ITEM_RECT::HitTest( const wxPoint& aPosition) const { int dist = GetPenWidth()/2; wxPoint start = GetStart(); @@ -316,7 +316,7 @@ void WS_DRAW_ITEM_LINE::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) } // return true if the point aPosition is on the text -bool WS_DRAW_ITEM_LINE::HitTest( const wxPoint& aPosition) +bool WS_DRAW_ITEM_LINE::HitTest( const wxPoint& aPosition) const { return TestSegmentHit( aPosition, GetStart(), GetEnd(), GetPenWidth()/2 ); } @@ -394,9 +394,9 @@ void WS_DRAW_ITEM_BITMAP::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) * Virtual function * return true if the point aPosition is on bitmap */ -bool WS_DRAW_ITEM_BITMAP::HitTest( const wxPoint& aPosition) +bool WS_DRAW_ITEM_BITMAP::HitTest( const wxPoint& aPosition) const { - WORKSHEET_DATAITEM_BITMAP* parent = (WORKSHEET_DATAITEM_BITMAP*)GetParent(); + const WORKSHEET_DATAITEM_BITMAP* parent = static_cast( GetParent() ); if( parent->m_ImageBitmap == NULL ) return false; diff --git a/cvpcb/cvstruct.h b/cvpcb/cvstruct.h index 579aa44dc6..7078a8d8a8 100644 --- a/cvpcb/cvstruct.h +++ b/cvpcb/cvstruct.h @@ -52,7 +52,7 @@ public: int GetSelection(); void OnSize( wxSizeEvent& event ); - virtual CVPCB_MAINFRAME* GetParent(); + virtual CVPCB_MAINFRAME* GetParent() const; }; diff --git a/cvpcb/listboxes.cpp b/cvpcb/listboxes.cpp index d36d921625..bc7f364658 100644 --- a/cvpcb/listboxes.cpp +++ b/cvpcb/listboxes.cpp @@ -79,7 +79,7 @@ int ITEMS_LISTBOX_BASE::GetSelection() } -CVPCB_MAINFRAME* ITEMS_LISTBOX_BASE::GetParent() +CVPCB_MAINFRAME* ITEMS_LISTBOX_BASE::GetParent() const { return (CVPCB_MAINFRAME*) wxListView::GetParent(); } diff --git a/eeschema/class_libentry.h b/eeschema/class_libentry.h index a8c84ade03..a730d9d19b 100644 --- a/eeschema/class_libentry.h +++ b/eeschema/class_libentry.h @@ -654,14 +654,14 @@ public: */ void SetPartCount( int count ); - int GetPartCount() { return m_unitCount; } + int GetPartCount() const { return m_unitCount; } /** * Function IsMulti * @return true if the component has multiple parts per package. * When happens, the reference has a sub reference ti identify part */ - bool IsMulti() { return m_unitCount > 1; } + bool IsMulti() const { return m_unitCount > 1; } /** * Function SubReference diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index df4fb03f0d..686adbf8c0 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -171,7 +171,7 @@ bool LIB_ARC::Load( LINE_READER& aLineReader, wxString& aErrorMsg ) } -bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) +bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) const { int mindist = GetPenSize() / 2; @@ -183,7 +183,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) } -bool LIB_ARC::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index 2c017b9c20..74fc633071 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -100,9 +100,9 @@ public: bool Load( LINE_READER& aLineReader, wxString& aErrorMsg ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const; const EDA_RECT GetBoundingBox() const; // Virtual diff --git a/eeschema/lib_bezier.cpp b/eeschema/lib_bezier.cpp index b58e11cb6b..3378bb1603 100644 --- a/eeschema/lib_bezier.cpp +++ b/eeschema/lib_bezier.cpp @@ -345,7 +345,7 @@ void LIB_BEZIER::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& } -bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) +bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) const { int mindist = GetPenSize() / 2; @@ -357,7 +357,7 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) } -bool LIB_BEZIER::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const { wxPoint ref, start, end; diff --git a/eeschema/lib_bezier.h b/eeschema/lib_bezier.h index 00a320b43f..0a1be188f1 100644 --- a/eeschema/lib_bezier.h +++ b/eeschema/lib_bezier.h @@ -72,9 +72,9 @@ public: */ unsigned GetCornerCount() const { return m_PolyPoints.size(); } - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const; const EDA_RECT GetBoundingBox() const; // Virtual diff --git a/eeschema/lib_circle.cpp b/eeschema/lib_circle.cpp index 204db95d5f..6a249ec740 100644 --- a/eeschema/lib_circle.cpp +++ b/eeschema/lib_circle.cpp @@ -87,7 +87,7 @@ bool LIB_CIRCLE::Load( LINE_READER& aLineReader, wxString& aErrorMsg ) } -bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) +bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) const { int mindist = GetPenSize() / 2; @@ -99,7 +99,7 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) } -bool LIB_CIRCLE::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_CIRCLE::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) aThreshold = GetPenSize() / 2; diff --git a/eeschema/lib_circle.h b/eeschema/lib_circle.h index 49f0f605ac..cbd0b31778 100644 --- a/eeschema/lib_circle.h +++ b/eeschema/lib_circle.h @@ -61,9 +61,9 @@ public: bool Load( LINE_READER& aLineReader, wxString& aErrorMsg ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const; int GetPenSize( ) const; diff --git a/eeschema/lib_draw_item.h b/eeschema/lib_draw_item.h index 8efffd827e..10e972eb4a 100644 --- a/eeschema/lib_draw_item.h +++ b/eeschema/lib_draw_item.h @@ -237,12 +237,12 @@ public: virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) = 0; - LIB_COMPONENT* GetParent() + LIB_COMPONENT* GetParent() const { return (LIB_COMPONENT *)m_Parent; } - virtual bool HitTest( const wxPoint& aPosition ) + virtual bool HitTest( const wxPoint& aPosition ) const { return EDA_ITEM::HitTest( aPosition ); } @@ -255,7 +255,7 @@ public: * @param aTransform The transform matrix. * @return True if the point \a aPosition is near this object */ - virtual bool HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) = 0; + virtual bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const = 0; /** * @return the boundary box for this, in library coordinates diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index 392daecc8c..36f43f8c0d 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -320,7 +320,7 @@ void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& a } -bool LIB_FIELD::HitTest( const wxPoint& aPosition ) +bool LIB_FIELD::HitTest( const wxPoint& aPosition ) const { // Because HitTest is mainly used to select the field // return always false if this field is void @@ -331,49 +331,37 @@ bool LIB_FIELD::HitTest( const wxPoint& aPosition ) } -bool LIB_FIELD::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) aThreshold = 0; - int extraCharCount = 0; + // Build a temporary copy of the text for hit testing + EDA_TEXT tmp_text( *this ); // Reference designator text has one or 2 additional character (displays // U? or U?A) if( m_id == REFERENCE ) { - extraCharCount++; - m_Text.Append('?'); - LIB_COMPONENT* parent = (LIB_COMPONENT*)m_Parent; + wxString extended_text = tmp_text.GetText(); + extended_text.Append('?'); + const LIB_COMPONENT* parent = static_cast( m_Parent ); if ( parent && ( parent->GetPartCount() > 1 ) ) - { - m_Text.Append('A'); - extraCharCount++; - } + extended_text.Append('A'); + tmp_text.SetText( extended_text ); } - wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos ); - wxPoint tmp = m_Pos; - m_Pos = physicalpos; + tmp_text.SetTextPosition( aTransform.TransformCoordinate( m_Pos ) ); /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 ); - int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT; - EXCHG( m_Orient, orient ); + tmp_text.SetOrientation( t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT ); - bool hit = TextHitTest( aPosition ); - - EXCHG( m_Orient, orient ); - m_Pos = tmp; - - while( extraCharCount-- ) - m_Text.RemoveLast( ); - - return hit; + return tmp_text.TextHitTest( aPosition ); } diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h index 1e475fa913..49e36d8be5 100644 --- a/eeschema/lib_field.h +++ b/eeschema/lib_field.h @@ -151,7 +151,7 @@ public: * Function IsVoid * @return true if the field value is void (no text in this field) */ - bool IsVoid() + bool IsVoid() const { return m_Text.IsEmpty(); } @@ -169,9 +169,9 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const; void operator=( const LIB_FIELD& field ) { diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index e4f16b3a8f..29c4aee929 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -525,13 +525,13 @@ void LIB_PIN::EnableEditMode( bool enable, bool editPinByPin ) } -bool LIB_PIN::HitTest( const wxPoint& aPosition ) +bool LIB_PIN::HitTest( const wxPoint& aPosition ) const { return HitTest( aPosition, 0, DefaultTransform ); } -bool LIB_PIN::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_PIN::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) aThreshold = 0; diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index bf4c504776..dd85740de6 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -131,9 +131,9 @@ public: bool Load( LINE_READER& aLineReader, wxString& aErrorMsg ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const; void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); diff --git a/eeschema/lib_polyline.cpp b/eeschema/lib_polyline.cpp index 5b4b1ba49c..75eae61c71 100644 --- a/eeschema/lib_polyline.cpp +++ b/eeschema/lib_polyline.cpp @@ -321,7 +321,7 @@ void LIB_POLYLINE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint } -bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) +bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) const { int mindist = GetPenSize() / 2; @@ -333,7 +333,7 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) } -bool LIB_POLYLINE::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { wxPoint ref, start, end; diff --git a/eeschema/lib_polyline.h b/eeschema/lib_polyline.h index 81a4d8a08e..78a3891613 100644 --- a/eeschema/lib_polyline.h +++ b/eeschema/lib_polyline.h @@ -74,9 +74,9 @@ public: */ unsigned GetCornerCount() const { return m_PolyPoints.size(); } - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const; const EDA_RECT GetBoundingBox() const; // Virtual diff --git a/eeschema/lib_rectangle.cpp b/eeschema/lib_rectangle.cpp index 7efdb3dbf1..057b049eb1 100644 --- a/eeschema/lib_rectangle.cpp +++ b/eeschema/lib_rectangle.cpp @@ -267,7 +267,7 @@ const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const } -bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) +bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) const { int mindist = ( GetPenSize() / 2 ) + 1; @@ -279,7 +279,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) } -bool LIB_RECTANGLE::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) aThreshold = GetPenSize() / 2; diff --git a/eeschema/lib_rectangle.h b/eeschema/lib_rectangle.h index 739f20b60e..63e182691d 100644 --- a/eeschema/lib_rectangle.h +++ b/eeschema/lib_rectangle.h @@ -65,9 +65,9 @@ public: bool Load( LINE_READER& aLineReader, wxString& aErrorMsg ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const; int GetPenSize( ) const; diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp index d52acdda97..1b51b0f4e9 100644 --- a/eeschema/lib_text.cpp +++ b/eeschema/lib_text.cpp @@ -185,32 +185,27 @@ bool LIB_TEXT::Load( LINE_READER& aLineReader, wxString& errorMsg ) } -bool LIB_TEXT::HitTest( const wxPoint& aPosition ) +bool LIB_TEXT::HitTest( const wxPoint& aPosition ) const { return HitTest( aPosition, 0, DefaultTransform ); } -bool LIB_TEXT::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) +bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const { if( aThreshold < 0 ) aThreshold = 0; - wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos ); - wxPoint tmp = m_Pos; - m_Pos = physicalpos; + EDA_TEXT tmp_text( *this ); + tmp_text.SetTextPosition( aTransform.TransformCoordinate( m_Pos ) ); /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 ); - int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT; - EXCHG( m_Orient, orient ); - bool hit = TextHitTest( aPosition ); - EXCHG( m_Orient, orient ); - m_Pos = tmp; - return hit; + tmp_text.SetOrientation( t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT ); + return tmp_text.TextHitTest( aPosition ); } diff --git a/eeschema/lib_text.h b/eeschema/lib_text.h index 3db14c11a8..8353869226 100644 --- a/eeschema/lib_text.h +++ b/eeschema/lib_text.h @@ -82,11 +82,11 @@ public: bool Load( LINE_READER& aLineReader, wxString& aErrorMsg ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; - bool HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ); + bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const; - bool HitTest( EDA_RECT& aRect ) + bool HitTest( const EDA_RECT& aRect ) const { return TextHitTest( aRect ); } diff --git a/eeschema/sch_collectors.h b/eeschema/sch_collectors.h index 299ea9ec62..4813253919 100644 --- a/eeschema/sch_collectors.h +++ b/eeschema/sch_collectors.h @@ -210,7 +210,7 @@ public: wxString GetSheetPath() const { return m_sheetPath; } - SCH_ITEM* GetParent() { return m_parent; } + SCH_ITEM* GetParent() const { return m_parent; } }; diff --git a/gerbview/class_GERBER.h b/gerbview/class_GERBER.h index 632ac6487c..c975bf0233 100644 --- a/gerbview/class_GERBER.h +++ b/gerbview/class_GERBER.h @@ -148,7 +148,7 @@ public: * Function GetParent * @return the GERBVIEW_FRAME parent of this GERBER_IMAGE */ - GERBVIEW_FRAME* GetParent() + GERBVIEW_FRAME* GetParent() const { return m_Parent; } diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp index c73d8972da..f01f3d5d55 100644 --- a/gerbview/class_gerber_draw_item.cpp +++ b/gerbview/class_gerber_draw_item.cpp @@ -131,7 +131,7 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition ) const } -wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition ) +wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition ) const { // do the inverse transform made by GetABPosition wxPoint xyPos = aABPosition; @@ -577,7 +577,7 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } -bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) +bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const { // calculate aRefPos in XY gerber axis: wxPoint ref_pos = GetXYPosition( aRefPos ); @@ -592,7 +592,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) } -bool GERBER_DRAW_ITEM::HitTest( EDA_RECT& aRefArea ) +bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const { wxPoint pos = GetABPosition( m_Start ); diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index 70ad0a1164..c7a0b695cc 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -209,7 +209,7 @@ public: * @param aABPosition = position in A,B plotter axis * @return const wxPoint - The given position in X,Y axis. */ - wxPoint GetXYPosition( const wxPoint& aABPosition ); + wxPoint GetXYPosition( const wxPoint& aABPosition ) const; /** * Function GetDcodeDescr @@ -255,7 +255,7 @@ public: * @param aRefPos a wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( const wxPoint& aRefPos ); + bool HitTest( const wxPoint& aRefPos ) const; /** * Function HitTest (overloaded) @@ -264,7 +264,7 @@ public: * @param aRefArea a wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( EDA_RECT& aRefArea ); + bool HitTest( const EDA_RECT& aRefArea ) const; /** * Function GetClass diff --git a/include/base_struct.h b/include/base_struct.h index 9ec7af03c8..38e320ef38 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -456,14 +456,10 @@ public: * Function HitTest * tests if \a aPosition is contained within or on the bounding area of an item. * - * @note This function cannot be const because some of the derive objects perform - * intermediate calculations which change object members. Make sure derived - * objects do not declare this as const. - * * @param aPosition A reference to a wxPoint object containing the coordinates to test. * @return True if \a aPosition is within or on the item bounding area. */ - virtual bool HitTest( const wxPoint& aPosition ) + virtual bool HitTest( const wxPoint& aPosition ) const { return false; // derived classes should override this function } diff --git a/include/class_board_item.h b/include/class_board_item.h index 26a30af896..91fd3ead0c 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -254,7 +254,7 @@ public: */ wxString GetLayerName() const; - virtual bool HitTest( const wxPoint& aPosition ) + virtual bool HitTest( const wxPoint& aPosition ) const { return EDA_ITEM::HitTest( aPosition ); } diff --git a/include/class_drawpanel.h b/include/class_drawpanel.h index 3a9c3735b7..d3e69371b3 100644 --- a/include/class_drawpanel.h +++ b/include/class_drawpanel.h @@ -123,7 +123,7 @@ public: BASE_SCREEN* GetScreen(); - EDA_DRAW_FRAME* GetParent(); + EDA_DRAW_FRAME* GetParent() const; void OnPaint( wxPaintEvent& event ); diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index 5fe90cd69f..6a3d4913ba 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -291,7 +291,10 @@ public: bool IsConnected( const wxPoint& aPoint ) const; /** @copydoc EDA_ITEM::HitTest(const wxPoint&) */ - virtual bool HitTest( const wxPoint& aPosition ) { return HitTest( aPosition, 0 ); } + virtual bool HitTest( const wxPoint& aPosition ) const + { + return HitTest( aPosition, 0 ); + } /** * Function HitTest diff --git a/include/worksheet_shape_builder.h b/include/worksheet_shape_builder.h index de0bb5aa57..718213c9b7 100644 --- a/include/worksheet_shape_builder.h +++ b/include/worksheet_shape_builder.h @@ -59,7 +59,7 @@ public: EDA_COLOR_T GetColor() const { return m_color; } WS_DRAW_TYPE GetType() const { return m_type; }; - WORKSHEET_DATAITEM* GetParent() { return m_parent; } + WORKSHEET_DATAITEM* GetParent() const { return m_parent; } /** The function to draw a WS_DRAW_ITEM */ @@ -69,7 +69,7 @@ public: * Abstract function: should exist for derived items * return true if the point aPosition is on the item */ - virtual bool HitTest( const wxPoint& aPosition) = 0; + virtual bool HitTest( const wxPoint& aPosition) const = 0; /** * Abstract function: should exist for derived items @@ -124,7 +124,7 @@ public: * Virtual function * return true if the point aPosition is on the line */ - virtual bool HitTest( const wxPoint& aPosition); + virtual bool HitTest( const wxPoint& aPosition) const; /** * return true if the point aPosition is on the starting point of this item. @@ -174,7 +174,7 @@ public: * Virtual function * return true if the point aPosition is inside one polygon */ - virtual bool HitTest( const wxPoint& aPosition); + virtual bool HitTest( const wxPoint& aPosition) const; /** * return true if the point aPosition is on the starting point of this item. @@ -202,7 +202,7 @@ public: * Virtual function * return true if the point aPosition is on one edge of the rectangle */ - virtual bool HitTest( const wxPoint& aPosition); + virtual bool HitTest( const wxPoint& aPosition) const; /** * return true if the point aPosition is on the starting point of this item. @@ -239,7 +239,7 @@ public: * Virtual function * return true if the point aPosition is on the text */ - virtual bool HitTest( const wxPoint& aPosition); + virtual bool HitTest( const wxPoint& aPosition) const; /** * return true if the point aPosition is on the starting point of this item. @@ -274,7 +274,7 @@ public: * Virtual function * return true if the point aPosition is on bitmap */ - virtual bool HitTest( const wxPoint& aPosition); + virtual bool HitTest( const wxPoint& aPosition) const; /** * return true if the point aPosition is on the reference point of this item. diff --git a/kicad/class_treeprojectfiles.h b/kicad/class_treeprojectfiles.h index b671a02e0f..6d592d4696 100644 --- a/kicad/class_treeprojectfiles.h +++ b/kicad/class_treeprojectfiles.h @@ -17,7 +17,7 @@ private: public: - TREE_PROJECT_FRAME* GetParent() + TREE_PROJECT_FRAME* GetParent() const { return m_Parent; } diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp index e49ca7e5dd..59ff184ddc 100644 --- a/pcbnew/class_dimension.cpp +++ b/pcbnew/class_dimension.cpp @@ -396,7 +396,7 @@ void DIMENSION::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } -bool DIMENSION::HitTest( const wxPoint& aPosition ) +bool DIMENSION::HitTest( const wxPoint& aPosition ) const { if( m_Text.TextHitTest( aPosition ) ) return true; diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h index 1ea29bd8dc..d68fc7770d 100644 --- a/pcbnew/class_dimension.h +++ b/pcbnew/class_dimension.h @@ -127,7 +127,7 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index d1e9799258..2c976e90ee 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -475,7 +475,7 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const } -bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) +bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const { switch( m_Shape ) { diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 64ce5dcb8c..3cae1d9dcf 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -178,7 +178,7 @@ public: virtual const EDA_RECT GetBoundingBox() const; - 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/class_marker_pcb.h b/pcbnew/class_marker_pcb.h index 7728b152c0..5e794a743c 100644 --- a/pcbnew/class_marker_pcb.h +++ b/pcbnew/class_marker_pcb.h @@ -64,7 +64,7 @@ public: const wxPoint& GetPosition() const { return m_Pos; } void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } - bool HitTest( const wxPoint& aPosition ) + bool HitTest( const wxPoint& aPosition ) const { return HitTestMarker( aPosition ); } diff --git a/pcbnew/class_mire.cpp b/pcbnew/class_mire.cpp index d2fb096755..3abeaf95d0 100644 --- a/pcbnew/class_mire.cpp +++ b/pcbnew/class_mire.cpp @@ -158,7 +158,7 @@ void PCB_TARGET::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color, } -bool PCB_TARGET::HitTest( const wxPoint& aPosition ) +bool PCB_TARGET::HitTest( const wxPoint& aPosition ) const { int dX = aPosition.x - m_Pos.x; int dY = aPosition.y - m_Pos.y; diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index 0a7186b6b1..9f12ac7d73 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -82,7 +82,7 @@ public: void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index ca343a6333..257f34bd6e 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -549,7 +549,7 @@ void MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } -bool MODULE::HitTest( const wxPoint& aPosition ) +bool MODULE::HitTest( const wxPoint& aPosition ) const { if( m_BoundaryBox.Contains( aPosition ) ) return true; diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 189abfe6be..3b378c30a6 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -324,7 +324,7 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 43b2b17f04..f4a1282ed7 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -637,7 +637,7 @@ bool D_PAD::IsOnLayer( LAYER_NUM aLayer ) const } -bool D_PAD::HitTest( const wxPoint& aPosition ) +bool D_PAD::HitTest( const wxPoint& aPosition ) const { int dx, dy; diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 3cbdcbe82a..41ac5c3913 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -341,7 +341,7 @@ public: * Function GetBoundingRadius * returns the radius of a minimum sized circle which fully encloses this pad. */ - int GetBoundingRadius() + int GetBoundingRadius() const { // Any member function which would affect this calculation should set // m_boundingRadius to -1 to re-trigger the calculation from here. @@ -368,7 +368,7 @@ public: bool IsOnLayer( LAYER_NUM aLayer ) const; - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; wxString GetClass() const { @@ -450,7 +450,8 @@ private: */ int boundingRadius() const; - int m_boundingRadius; ///< radius of the circle containing the pad shape + // Actually computed and cached on demand by the accessor + mutable int m_boundingRadius; ///< radius of the circle containing the pad shape /// Pad name (4 char) or a long identifier (used in pad name /// comparisons because this is faster than string comparison) diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index 0ebd4119bf..7a6d853704 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -76,7 +76,7 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - bool HitTest( const wxPoint& aPosition ) + bool HitTest( const wxPoint& aPosition ) const { return TextHitTest( aPosition ); } diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index e5e7a2d2be..b103869775 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -163,7 +163,7 @@ void TEXTE_MODULE::SetLocalCoord() RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); } -bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) +bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) const { wxPoint rel_pos; EDA_RECT area = GetTextBox( -1, -1 ); @@ -455,6 +455,9 @@ void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const case LAYER_N_FRONT: aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ); // how about SILKSCREEN_N_FRONT? break; + + default: + wxFAIL_MSG( wxT( "Can't tell text layer" ) ); } break; } diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index bc207e7254..7ab96e516b 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -148,7 +148,7 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - bool HitTest( const wxPoint& aPosition ); + bool HitTest( const wxPoint& aPosition ) const; wxString GetClass() const { diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 2dd626a5c8..7a40e066fb 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1236,7 +1236,7 @@ bool TRACK::HitTest( const wxPoint& aPosition ) return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ); } -bool VIA::HitTest( const wxPoint& aPosition ) +bool VIA::HitTest( const wxPoint& aPosition ) const { int max_dist = m_Width / 2; diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 9afc346788..4340c33e6d 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -401,7 +401,7 @@ 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 wxPoint& aPosition ) const; virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 6679fee49a..a6b360f98a 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -440,37 +440,42 @@ int ZONE_CONTAINER::GetThermalReliefCopperBridge( D_PAD* aPad ) const } -bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) +bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const { - if( HitTestForCorner( aPosition ) ) + if( HitTestForCorner( aPosition ) >= 0 ) return true; - if( HitTestForEdge( aPosition ) ) + if( HitTestForEdge( aPosition ) >= 0 ) return true; return false; } +void ZONE_CONTAINER::SetSelectedCorner( const wxPoint& aPosition ) +{ + m_CornerSelection = HitTestForCorner( aPosition ); + + if( m_CornerSelection < 0 ) + m_CornerSelection = HitTestForEdge( aPosition ); +} + + // Zones outlines have no thickness, so it Hit Test functions // we must have a default distance between the test point // and a corner or a zone edge: #define MAX_DIST_IN_MM 0.25 -bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) +int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) const { int distmax = Millimeter2iu( MAX_DIST_IN_MM ); - m_CornerSelection = m_Poly->HitTestForCorner( refPos, distmax ); - - return m_CornerSelection >= 0; + return m_Poly->HitTestForCorner( refPos, distmax ); } -bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) +int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) const { int distmax = Millimeter2iu( MAX_DIST_IN_MM ); - m_CornerSelection = m_Poly->HitTestForEdge( refPos, distmax ); - - return m_CornerSelection >= 0; + return m_Poly->HitTestForEdge( refPos, distmax ); } @@ -700,25 +705,23 @@ void ZONE_CONTAINER::Move( const wxPoint& offset ) } -void ZONE_CONTAINER::MoveEdge( const wxPoint& offset ) +void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge ) { - int ii = m_CornerSelection; - // Move the start point of the selected edge: - SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); + SetCornerPosition( aEdge, GetCornerPosition( aEdge ) + offset ); // Move the end point of the selected edge: - if( m_Poly->m_CornersList.IsEndContour( ii ) || ii == GetNumCorners() - 1 ) + if( m_Poly->m_CornersList.IsEndContour( aEdge ) || aEdge == GetNumCorners() - 1 ) { - int icont = m_Poly->GetContour( ii ); - ii = m_Poly->GetContourStart( icont ); + int icont = m_Poly->GetContour( aEdge ); + aEdge = m_Poly->GetContourStart( icont ); } else { - ii++; + aEdge++; } - SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); + SetCornerPosition( aEdge, GetCornerPosition( aEdge ) + offset ); m_Poly->Hatch(); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 6423d85396..2642937d06 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -217,6 +217,10 @@ public: int GetSelectedCorner() const { return m_CornerSelection; } void SetSelectedCorner( int aCorner ) { m_CornerSelection = aCorner; } + /// + // Like HitTest but selects the current corner to be operated on + void SetSelectedCorner( const wxPoint& aPosition ); + int GetLocalFlags() const { return m_localFlgs; } void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; } @@ -234,7 +238,7 @@ public: * @param aRefPos A wxPoint to test * @return bool - true if a hit, else false */ - virtual bool HitTest( const wxPoint& aPosition ); + virtual bool HitTest( const wxPoint& aPosition ) const; /** * Function HitTest @@ -342,7 +346,7 @@ public: * @return true if found * @param refPos : A wxPoint to test */ - bool HitTestForCorner( const wxPoint& refPos ); + int HitTestForCorner( const wxPoint& refPos ) const; /** * Function HitTestForEdge @@ -351,7 +355,7 @@ public: * @return true if found * @param refPos : A wxPoint to test */ - bool HitTestForEdge( const wxPoint& refPos ); + int HitTestForEdge( const wxPoint& refPos ) const; /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const @@ -400,10 +404,11 @@ public: /** * Function MoveEdge - * Move the outline Edge. m_CornerSelection is the start point of the outline edge + * Move the outline Edge * @param offset = moving vector + * @param aEdge = start point of the outline edge */ - void MoveEdge( const wxPoint& offset ); + void MoveEdge( const wxPoint& offset, int aEdge ); /** * Function Rotate diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp index d6f8a79583..06f07af712 100644 --- a/pcbnew/controle.cpp +++ b/pcbnew/controle.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -160,8 +161,9 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode ) (*m_Collector)[i]->Show( 0, std::cout ); #endif - /* Remove redundancies: sometime, zones are found twice, + /* Remove redundancies: sometime, legacy zones are found twice, * because zones can be filled by overlapping segments (this is a fill option) + * Trigger the selection of the current edge for new-style zones */ time_t timestampzone = 0; @@ -169,18 +171,32 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode ) { item = (*m_Collector)[ii]; - if( item->Type() != PCB_ZONE_T ) - continue; + switch( item->Type() ) + { + case PCB_ZONE_T: + // Found a TYPE ZONE + if( item->GetTimeStamp() == timestampzone ) // Remove it, redundant, zone already found + { + m_Collector->Remove( ii ); + ii--; + } + else + { + timestampzone = item->GetTimeStamp(); + } + break; - // Found a TYPE ZONE - if( item->GetTimeStamp() == timestampzone ) // Remove it, redundant, zone already found - { - m_Collector->Remove( ii ); - ii--; - } - else - { - timestampzone = item->GetTimeStamp(); + case PCB_ZONE_AREA_T: + { + /* We need to do the selection now because the menu text + * depends on it */ + ZONE_CONTAINER *zone = static_cast( item ); + zone->SetSelectedCorner( RefPos( true ) ); + } + break; + + default: + break; } } diff --git a/pcbnew/dialogs/dialog_general_options.h b/pcbnew/dialogs/dialog_general_options.h index 7cdefdbe2e..89abaa7b1b 100644 --- a/pcbnew/dialogs/dialog_general_options.h +++ b/pcbnew/dialogs/dialog_general_options.h @@ -16,7 +16,7 @@ public: void OnOkClick( wxCommandEvent& event ); void OnCancelClick( wxCommandEvent& event ); - PCB_EDIT_FRAME* GetParent() { return (PCB_EDIT_FRAME*) wxDialog::GetParent(); } + PCB_EDIT_FRAME* GetParent() const { return (PCB_EDIT_FRAME*) wxDialog::GetParent(); } private: void OnMiddleBtnPanEnbl( wxCommandEvent& event ) diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index a78007761b..4f93574ab2 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -2234,6 +2234,8 @@ void EAGLE_PLUGIN::packageCircle( MODULE* aModule, CPTREE& aTree ) const case ECO1_N: layer = SILKSCREEN_N_FRONT; break; case ECO2_N: layer = SILKSCREEN_N_BACK; break; */ + default: + break; } gr->SetLayer( layer ); diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index c66adc4c64..372538c1b1 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -661,14 +661,14 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* edge_zone->GetIsKeepout() ? _("Keepout Area") : _( "Zones" ), KiBitmap( add_zone_xpm ) ); - if( edge_zone->HitTestForCorner( RefPos( true ) ) ) + if( edge_zone->HitTestForCorner( RefPos( true ) ) >= 0 ) { AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER, _( "Move Corner" ), KiBitmap( move_xpm ) ); AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER, _( "Delete Corner" ), KiBitmap( delete_xpm ) ); } - else if( edge_zone->HitTestForEdge( RefPos( true ) ) ) + else if( edge_zone->HitTestForEdge( RefPos( true ) ) >= 0 ) { AddMenuItem( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER, _( "Create Corner" ), KiBitmap( add_corner_xpm ) ); diff --git a/pcbnew/router/pns_node.cpp b/pcbnew/router/pns_node.cpp index e2349c4800..825be77e57 100644 --- a/pcbnew/router/pns_node.cpp +++ b/pcbnew/router/pns_node.cpp @@ -401,9 +401,9 @@ struct hitVisitor { PNS_ITEMSET& m_items; const VECTOR2I& m_point; - PNS_NODE* m_world; + const PNS_NODE* m_world; - hitVisitor( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, PNS_NODE* aWorld ) : + hitVisitor( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) : m_items( aTab ), m_point( aPoint ), m_world( aWorld ) {}; bool operator()( PNS_ITEM* aItem ) @@ -423,7 +423,7 @@ struct hitVisitor }; -const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) +const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const { PNS_ITEMSET items; // fixme: we treat a point as an infinitely small circle - this is inefficient. diff --git a/pcbnew/router/pns_node.h b/pcbnew/router/pns_node.h index f88b74bd4f..de3e886dc2 100644 --- a/pcbnew/router/pns_node.h +++ b/pcbnew/router/pns_node.h @@ -140,7 +140,7 @@ public: int aKindMask = PNS_ITEM::ANY ); ///> Hit detection - const PNS_ITEMSET HitTest( const VECTOR2I& aPoint ); + const PNS_ITEMSET HitTest( const VECTOR2I& aPoint ) const; void Add( PNS_ITEM* aItem ); void Remove( PNS_ITEM* aItem ); diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 44f669fce8..7b40a598e8 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -433,9 +433,9 @@ void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC ) } else if( zone->IsDragging() ) { - wxPoint offset; - offset = s_CornerInitialPosition - s_CursorLastPosition; - zone->MoveEdge( offset ); + wxPoint offset = s_CornerInitialPosition - s_CursorLastPosition; + int selection = zone->GetSelectedCorner(); + zone->MoveEdge( offset, selection ); } else { @@ -485,9 +485,9 @@ void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* } else if( zone->IsDragging() ) { - wxPoint offset; - offset = pos - s_CursorLastPosition; - zone->MoveEdge( offset ); + wxPoint offset = pos - s_CursorLastPosition; + int selection = zone->GetSelectedCorner(); + zone->MoveEdge( offset, selection ); s_CursorLastPosition = pos; } else diff --git a/polygon/polygon_test_point_inside.cpp b/polygon/polygon_test_point_inside.cpp index aafade407c..f63d9ba9d7 100644 --- a/polygon/polygon_test_point_inside.cpp +++ b/polygon/polygon_test_point_inside.cpp @@ -96,7 +96,7 @@ bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList, /* Function TestPointInsidePolygon (overlaid) * same as previous, but use wxPoint and aCount corners */ -bool TestPointInsidePolygon( wxPoint *aPolysList, int aCount,wxPoint aRefPoint ) +bool TestPointInsidePolygon( const wxPoint *aPolysList, int aCount, const wxPoint &aRefPoint ) { // count intersection points to right of (refx,refy). If odd number, point (refx,refy) is inside polyline int ics, ice; diff --git a/polygon/polygon_test_point_inside.h b/polygon/polygon_test_point_inside.h index b817380d1c..ff43798159 100644 --- a/polygon/polygon_test_point_inside.h +++ b/polygon/polygon_test_point_inside.h @@ -34,6 +34,6 @@ bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList, * @param aRefPoint: the point coordinate to test * @return true if the point is inside, false for outside */ -bool TestPointInsidePolygon( wxPoint* aPolysList, +bool TestPointInsidePolygon( const wxPoint* aPolysList, int aCount, - wxPoint aRefPoint ); + const wxPoint &aRefPoint ); From fef168aaed9cf6283fadf9eb9de0d0feeee1b301 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 4 May 2014 13:22:27 -0500 Subject: [PATCH 06/10] Modular-Kicad milestone B), minor portions: *) KIWAY_PLAYER::IsModal() is now a retained state, controlled by SetModal() *) Fully re-work the KIWAY_PLAYER::ShowModal() to use a nested event loop. *) Add support to DIALOG_SHIM for a "quasi-modal" dialog presentation and mode. See top of dialog_shim.cpp about that for benefits and need. *) You can now pick footprint from the schematic component field dialog, although if you do this before you open the BOARD, you will only get the global footprint libraries, not also the project specific ones. Opening the BOARD first avoids this problem. This is the first example of cross KIFACE invocation, it is also the first instance of using a TOP_FRAME other than FRAME_PCB as the first thing. It works, but it's missing support for opening the project specific table because historically the FRAME_PCB did that. This is now starting to expose all the near term needs for KIWAY_PLAYER <-> PROJECT interaction, independence and out of sequence usage. A fix for this will be coming in a few days. However it mostly starts to show why the KIWAY is terribly useful and important. --- common/basicframe.cpp | 11 ++ common/dialog_shim.cpp | 126 +++++++++++++++++- common/kiway_player.cpp | 71 +++++----- .../dialog_edit_component_in_schematic.cpp | 35 +++-- eeschema/getpart.cpp | 15 ++- eeschema/tool_viewlib.cpp | 11 +- eeschema/viewlib_frame.cpp | 3 + include/dialog_shim.h | 16 ++- include/kiway_player.h | 7 +- include/wxstruct.h | 4 +- pcbnew/footprint_wizard_frame.cpp | 5 +- pcbnew/modview_frame.cpp | 6 +- pcbnew/tool_modview.cpp | 6 +- 13 files changed, 245 insertions(+), 71 deletions(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 37be1fd12c..2fb7d4c604 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -151,6 +151,17 @@ bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent ) } +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" ); +#endif + + return wxFrame::Enable( enable ); +} + + void EDA_BASE_FRAME::onAutoSaveTimer( wxTimerEvent& aEvent ) { if( !doAutoSave() ) diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index 354444c4ff..8c1d94e794 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -25,17 +25,45 @@ #include #include +#include + +/* + Quasi-Modal Mode Explained: + + The gtk calls in wxDialog::ShowModal() cause event routing problems if that + modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up + and mostly works but does not respond to the window decoration close button. + There is no way to get around this without reversing the gtk calls temporarily. + + Quasi-Modal mode is our own almost modal mode which disables only the parent + of the DIALOG_SHIM, leaving other frames operable and while staying captured in the + nested event loop. This avoids the gtk calls and leaves event routing pure + and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using + ShowQuasiModal() you have to use EndQuasiModal() in your dialogs and not + EndModal(). There is also IsQuasiModal() but its value can only be true + when the nested event loop is active. Do not mix the modal and quasi-modal + functions. Use one set or the other. + + You might find this behavior preferable over a pure modal mode, and it was said + that only the Mac has this natively, but now other platforms have something + similar. You CAN use it anywhere for any dialog. But you MUST use it when + you want to use KIWAY_PLAYER::ShowModal() from a dialog event. +*/ + + DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxDialog( aParent, id, title, pos, size, style, name ), - KIWAY_HOLDER( 0 ) + KIWAY_HOLDER( 0 ), + m_qmodal_loop( 0 ), + m_qmodal_showing( false ) { // pray that aParent is either a KIWAY_PLAYER or DIALOG_SHIM derivation. KIWAY_HOLDER* h = dynamic_cast( aParent ); wxASSERT_MSG( h, - wxT( "DIALOG_SHIM's parent not derived from KIWAY_PLAYER nor DIALOG_SHIM" ) ); + wxT( "DIALOG_SHIM's parent is NULL or not derived from KIWAY_PLAYER nor DIALOG_SHIM" ) ); if( h ) SetKiway( this, &h->Kiway() ); @@ -46,6 +74,14 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl } +DIALOG_SHIM::~DIALOG_SHIM() +{ + // if the dialog is quasi-modal, this will end its event loop + if( IsQuasiModal() ) + EndQuasiModal( wxID_CANCEL ); +} + + // our hashtable is an implementation secret, don't need or want it in a header file #include #include // EDA_RECT @@ -92,6 +128,90 @@ bool DIALOG_SHIM::Show( bool show ) } +bool DIALOG_SHIM::Enable( bool enable ) +{ +#if defined(DEBUG) + const char* type_id = typeid( *this ).name(); + printf( "wxDialog %s: %s\n", type_id, enable ? "enabled" : "disabled" ); +#endif + + return wxDialog::Enable( enable ); +} + + +int DIALOG_SHIM::ShowQuasiModal() +{ + // toggle a window's "enable" status to disabled, then enabled on exit. + // exception safe. + struct ENABLE_DISABLE + { + wxWindow* m_win; + ENABLE_DISABLE( wxWindow* aWindow ) : m_win( aWindow ) { if( m_win ) m_win->Disable(); } + ~ENABLE_DISABLE() { if( m_win ) m_win->Enable(); } + }; + + // This is an exception safe way to zero a pointer before returning. + // Yes, even though DismissModal() clears this first normally, this is + // here in case there's an exception before the dialog is dismissed. + struct NULLER + { + void*& m_what; + NULLER( void*& aPtr ) : m_what( aPtr ) {} + ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction + } clear_this( (void*&) m_qmodal_loop ); + + + // release the mouse if it's currently captured as the window having it + // will be disabled when this dialog is shown -- but will still keep the + // capture making it impossible to do anything in the modal dialog itself + wxWindow* win = wxWindow::GetCapture(); + if( win ) + win->ReleaseMouse(); + + wxWindow* parent = GetParentForModalDialog(); + + ENABLE_DISABLE toggle( parent ); + + Show( true ); + + m_qmodal_showing = true; + + wxGUIEventLoop event_loop; + wxEventLoopActivator event_loop_stacker( &event_loop ); + + m_qmodal_loop = &event_loop; + + event_loop.Run(); + + if( toggle.m_win ) // let's focus back on the parent window + toggle.m_win->SetFocus(); + + return GetReturnCode(); +} + + +void DIALOG_SHIM::EndQuasiModal( int retCode ) +{ + SetReturnCode( retCode ); + + if( !IsQuasiModal() ) + { + wxFAIL_MSG( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal wasn't called" ); + return; + } + + m_qmodal_showing = false; + + if( m_qmodal_loop ) + { + m_qmodal_loop->Exit(); + m_qmodal_loop = NULL; + } + + Show( false ); +} + + #if DLGSHIM_USE_SETFOCUS static bool findWindowRecursively( const wxWindowList& children, const wxWindow* wanted ) @@ -113,7 +233,7 @@ static bool findWindowRecursively( const wxWindowList& children, const wxWindow* } -static bool findWindowRecursively( const wxWindow* topmost, const wxWindow* wanted ) +static bool findWindowReursively( const wxWindow* topmost, const wxWindow* wanted ) { // wanted may be NULL and that is ok. diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 274e4e564c..d171744227 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -23,13 +23,14 @@ */ - #include #include #include #include +#include #include #include +#include BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) @@ -43,10 +44,10 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType long aStyle, const wxString& aWdoName ) : EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), KIWAY_HOLDER( aKiway ), - m_modal_dismissed( 0 ) + m_modal( false ), + m_modal_loop( 0 ) { - DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) - //Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); + // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) } @@ -55,10 +56,10 @@ KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& a const wxString& aWdoName ) : EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), KIWAY_HOLDER( 0 ), - m_modal_dismissed( 0 ) + m_modal( false ), + m_modal_loop( 0 ) { - DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) - //Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); + // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) } @@ -73,49 +74,54 @@ void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) bool KIWAY_PLAYER::ShowModal( wxString* aResult ) { + wxASSERT_MSG( IsModal(), "ShowModal() shouldn't be called on non-modal frame" ); + /* - This function has a nice interface but an unsightly implementation. - Now it is encapsulated, making it easier to improve. I am not sure - a wxSemaphore was needed, especially since no blocking happens. It seems - like a volatile bool is sufficient. + This function has a nice interface but a necessarily unsightly implementation. + Now the implementation is encapsulated, localizing future changes. It works in tandem with DismissModal(). But only ShowModal() is in the vtable and therefore cross-module capable. */ - volatile bool dismissed = false; + // This is an exception safe way to zero a pointer before returning. + // Yes, even though DismissModal() clears this first normally, this is + // here in case there's an exception before the dialog is dismissed. + struct NULLER + { + void*& m_what; + NULLER( void*& aPtr ) : m_what( aPtr ) {} + ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction + } clear_this( (void*&) m_modal_loop ); - // disable all frames except the modal one, re-enable on exit, exception safe. + // exception safe way to disable all frames except the modal one, + // re-enable on exit wxWindowDisabler toggle( this ); - m_modal_dismissed = &dismissed; - Show( true ); - Raise(); - // Wait for the one and only active frame to call DismissModal() from - // some concluding event. - while( !dismissed ) - { - wxYield(); - wxMilliSleep( 50 ); - } + wxGUIEventLoop event_loop; + wxEventLoopActivator event_loop_stacker( &event_loop ); - // no longer modal, not to mention that the pointer would be invalid outside this scope. - m_modal_dismissed = NULL; + m_modal_loop = &event_loop; + + event_loop.Run(); if( aResult ) *aResult = m_modal_string; + DBG(printf( "~%s: aResult:'%s' ret:%d\n", + __func__, TO_UTF8( m_modal_string ), m_modal_ret_val );) + return m_modal_ret_val; } bool KIWAY_PLAYER::IsDismissed() { - // if already dismissed, then m_modal_dismissed may be NULL, and if not, - // it can still be dismissed if the bool is true. - bool ret = !m_modal_dismissed || *m_modal_dismissed; + bool ret = !m_modal_loop; + + DBG(printf( "%s: ret:%d\n", __func__, ret );) return ret; } @@ -126,8 +132,13 @@ void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult ) m_modal_ret_val = aRetVal; m_modal_string = aResult; - if( m_modal_dismissed ) - *m_modal_dismissed = true; + if( m_modal_loop ) + { + m_modal_loop->Exit(); + m_modal_loop = 0; // this marks it as dismissed. + } + + Show( false ); } diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 4fc02d14fb..cb9fcbc4ee 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -148,10 +148,10 @@ void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent ) // make sure the chipnameTextCtrl is wide enough to hold any unusually long chip names: EnsureTextCtrlWidth( dlg->chipnameTextCtrl ); - dlg->ShowModal(); + dlg->ShowQuasiModal(); - m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); + m_canvas->MoveCursorToCrossHair(); dlg->Destroy(); } @@ -214,7 +214,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnListItemSelected( wxListEvent& event void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnCancelButtonClick( wxCommandEvent& event ) { - EndModal( 1 ); + EndQuasiModal( 1 ); } @@ -379,7 +379,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event m_Parent->GetScreen()->TestDanglingEnds(); m_Parent->GetCanvas()->Refresh( true ); - EndModal( 0 ); + EndQuasiModal( 0 ); } @@ -436,23 +436,21 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::deleteFieldButtonHandler( wxCommandEven void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& event ) { -#if 1 +#if 0 wxString datasheet_uri = fieldValueTextCtrl->GetValue(); ::wxLaunchDefaultBrowser( datasheet_uri ); #else - unsigned fieldNdx = getSelectedFieldNdx(); -/* + unsigned fieldNdx = getSelectedFieldNdx(); if( fieldNdx == DATASHEET ) { wxString datasheet_uri = fieldValueTextCtrl->GetValue(); ::wxLaunchDefaultBrowser( datasheet_uri ); } else if( fieldNdx == FOOTPRINT ) -*/ { - // pick a footprint + // pick a footprint using the footprint picker. wxString fpid; KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); @@ -460,11 +458,11 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& even if( frame->ShowModal( &fpid ) ) { printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); + fieldValueTextCtrl->SetValue( fpid ); + } - frame->Show( false ); // keep the frame open, but hidden. - - Raise(); + frame->Destroy(); } #endif @@ -764,7 +762,16 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copySelectedFieldToPanel() fieldValueTextCtrl->SetValue( field.GetText() ); - 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 ); + + 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 @@ -1006,5 +1013,5 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::SetInitCmp( wxCommandEvent& event ) m_Parent->OnModify(); m_Cmp->Draw( m_Parent->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - EndModal( 1 ); + EndQuasiModal( 1 ); } diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index e977eee5c1..e81d028bfa 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -56,7 +56,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedAlias, int* aUnit, int* aConvert ) { - // Close the any current non-modal Lib browser if open, and open a new one, in "modal" mode: + // Close any open non-modal Lib browser, and open a new one, in "modal" mode: LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false ); if( viewlibFrame ) viewlibFrame->Destroy(); @@ -79,13 +79,14 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( LIB_ALIAS* aPreselectedA wxString cmpname; - viewlibFrame->ShowModal( &cmpname ); + if( viewlibFrame->ShowModal( &cmpname ) ) + { + if( aUnit ) + *aUnit = viewlibFrame->GetUnit(); - if( aUnit ) - *aUnit = viewlibFrame->GetUnit(); - - if( aConvert ) - *aConvert = viewlibFrame->GetConvert(); + if( aConvert ) + *aConvert = viewlibFrame->GetConvert(); + } viewlibFrame->Destroy(); diff --git a/eeschema/tool_viewlib.cpp b/eeschema/tool_viewlib.cpp index f929ad5c28..e1982ca1ca 100644 --- a/eeschema/tool_viewlib.cpp +++ b/eeschema/tool_viewlib.cpp @@ -116,8 +116,7 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() _( "View component documents" ) ); m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, false ); - // if library browser is modal - if( m_Ident == FRAME_SCH_VIEWER_MODAL ) + if( IsModal() ) { m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC, @@ -130,11 +129,11 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() m_mainToolBar->Realize(); } - if( (m_libraryName != wxEmptyString) && (m_entryName != wxEmptyString) ) + if( m_libraryName.size() && m_entryName.size() ) { lib = CMP_LIBRARY::FindLibrary( m_libraryName ); - if( lib != NULL ) + if( lib ) { component = lib->FindComponent( m_entryName ); @@ -161,7 +160,6 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, false ); } - int parts_count = 1; if( component ) @@ -171,8 +169,7 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() for( ii = 0; ii < parts_count; ii++ ) { - wxString msg; - msg.Printf( _( "Unit %c" ), 'A' + ii ); + wxString msg = wxString::Format( _( "Unit %c" ), 'A' + ii ); m_selpartBox->Append( msg ); } diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index e4af57c174..e8b368c118 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -103,6 +103,9 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame { wxASSERT( aFrameType==FRAME_SCH_VIEWER || aFrameType==FRAME_SCH_VIEWER_MODAL ); + if( aFrameType == FRAME_SCH_VIEWER_MODAL ) + SetModal( true ); + wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); m_FrameName = GetLibViewerFrameName(); diff --git a/include/dialog_shim.h b/include/dialog_shim.h index cab1d5f0f7..ae906dc97b 100644 --- a/include/dialog_shim.h +++ b/include/dialog_shim.h @@ -56,12 +56,26 @@ public: const wxString& name = wxDialogNameStr ); - bool Show( bool show ); // overload wxDialog::Show + ~DIALOG_SHIM(); + int ShowQuasiModal(); // disable only the parent window, otherwise modal. + + void EndQuasiModal( int retCode ); // End quasi-modal mode + + bool IsQuasiModal() { return m_qmodal_showing; } + + bool Show( bool show ); // override wxDialog::Show + + bool Enable( bool enable ); // override wxDialog::Enable virtual protected: std::string m_hash_key; // alternate for class_map when classname re-used. + // variables for quasi-modal behavior support, only used by a few derivatives. + wxGUIEventLoop* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed + bool m_qmodal_showing; + + #if DLGSHIM_USE_SETFOCUS private: void onInit( wxInitDialogEvent& aEvent ); diff --git a/include/kiway_player.h b/include/kiway_player.h index 6a08e70ed0..ff20714bbc 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -87,6 +87,7 @@ private: class KIWAY_EXPRESS; +class wxGUIEventLoop; /** * Class KIWAY_PLAYER @@ -194,7 +195,8 @@ public: protected: - bool IsModal() { return m_modal_dismissed; } + bool IsModal() { return m_modal; } + void SetModal( bool IsModal ) { m_modal = IsModal; } /** * Function IsDismissed @@ -216,7 +218,8 @@ protected: void language_change( wxCommandEvent& event ); // variables for modal behavior support, only used by a few derivatives. - volatile bool* m_modal_dismissed; // points to "dismissed state", NULL means not modal + bool m_modal; // true if frame is intended to be modal, not modeless + wxGUIEventLoop* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed wxString m_modal_string; bool m_modal_ret_val; // true if a selection was made diff --git a/include/wxstruct.h b/include/wxstruct.h index 22153455a2..daffa56d67 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -190,7 +190,9 @@ public: * @warning If you override this function in a derived class, make sure you call * down to this or the auto save feature will be disabled. */ - bool ProcessEvent( wxEvent& aEvent ); // overload wxFrame::ProcessEvent() + bool ProcessEvent( wxEvent& aEvent ); // override wxFrame::ProcessEvent() + + bool Enable( bool enable ); // override wxFrame::Enable virtual void SetAutoSaveInterval( int aInterval ) { m_autoSaveInterval = aInterval; } diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 7fac217892..0cff8d2bb1 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -125,6 +125,9 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, { wxASSERT( aFrameType==FRAME_PCB_FOOTPRINT_WIZARD_MODAL ); + if( aFrameType == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ) + SetModal( true ); + wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); m_FrameName = FOOTPRINT_WIZARD_FRAME_NAME; @@ -641,7 +644,7 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg ); - if( m_Ident == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ) + if( IsModal() ) { // The library browser is called from a "load component" command m_mainToolBar->AddSeparator(); diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 1db99caf30..1bcbd5fcd5 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -129,6 +129,9 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent { wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL ); + if( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ) + SetModal( true ); + wxAcceleratorTable table( DIM( accels ), accels ); m_FrameName = GetFootprintViewerFrameName(); @@ -271,6 +274,7 @@ const wxChar* FOOTPRINT_VIEWER_FRAME::GetFootprintViewerFrameName() void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { + DBG(printf( "%s:\n", __func__ );) if( IsModal() ) { // Only dismiss a modal frame once, so that the return values set by @@ -278,7 +282,7 @@ void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) if( !IsDismissed() ) DismissModal( false ); - // window will be destroyed by the calling function. + // window to be destroyed by the caller of KIWAY_PLAYER::ShowModal() } else Destroy(); diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp index 3994a2a96d..3101864a0c 100644 --- a/pcbnew/tool_modview.cpp +++ b/pcbnew/tool_modview.cpp @@ -48,8 +48,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar() { m_mainToolBar = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE - | wxAUI_TB_OVERFLOW - ); + | wxAUI_TB_OVERFLOW ); // Set up toolbar m_mainToolBar->AddTool( ID_MODVIEW_SELECT_LIB, wxEmptyString, @@ -95,8 +94,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg ); - // Enable this tool only if the library browser is intended for modal use. - if( m_Ident == FRAME_PCB_MODULE_VIEWER_MODAL ) + if( IsModal() ) { m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD, wxEmptyString, From 19dd876684c14a674bd3f894a4c1765a0aeeae25 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 4 May 2014 14:57:44 -0500 Subject: [PATCH 07/10] wx 2.8 now builds, but the quasi-modal support seems broken on 2.8. Wanted others to be able to build at least. --- common/basicframe.cpp | 2 + common/dialog_shim.cpp | 87 +++++++++++++++++++++++++++++++++++++---- common/kiway_player.cpp | 2 +- include/dialog_shim.h | 16 +++++++- include/kiway_player.h | 12 +++++- 5 files changed, 108 insertions(+), 11 deletions(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 2fb7d4c604..dbcf15d9f9 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -153,6 +153,8 @@ bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent ) bool EDA_BASE_FRAME::Enable( bool enable ) { + // so we can do logging of this state change: + #if defined(DEBUG) const char* type_id = typeid( *this ).name(); printf( "wxFrame %s: %s\n", type_id, enable ? "enabled" : "disabled" ); diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index 8c1d94e794..548a91cdb4 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -130,6 +130,8 @@ bool DIALOG_SHIM::Show( bool show ) bool DIALOG_SHIM::Enable( bool enable ) { + // so we can do logging of this state change: + #if defined(DEBUG) const char* type_id = typeid( *this ).name(); printf( "wxDialog %s: %s\n", type_id, enable ? "enabled" : "disabled" ); @@ -139,6 +141,73 @@ bool DIALOG_SHIM::Enable( bool enable ) } +#if !wxCHECK_VERSION( 2, 9, 4 ) +wxWindow* DIALOG_SHIM::CheckIfCanBeUsedAsParent( wxWindow* parent ) const +{ + if ( !parent ) + return NULL; + + extern WXDLLIMPEXP_DATA_BASE(wxList) wxPendingDelete; + + if ( wxPendingDelete.Member(parent) || parent->IsBeingDeleted() ) + { + // this window is being deleted and we shouldn't create any children + // under it + return NULL; + } + + if ( parent->GetExtraStyle() & wxWS_EX_TRANSIENT ) + { + // this window is not being deleted yet but it's going to disappear + // soon so still don't parent this window under it + return NULL; + } + + if ( !parent->IsShownOnScreen() ) + { + // using hidden parent won't work correctly neither + return NULL; + } + + // FIXME-VC6: this compiler requires an explicit const cast or it fails + // with error C2446 + if ( const_cast(parent) == this ) + { + // not sure if this can really happen but it doesn't hurt to guard + // against this clearly invalid situation + return NULL; + } + + return parent; +} + + +wxWindow* DIALOG_SHIM::GetParentForModalDialog(wxWindow *parent, long style) const +{ + // creating a parent-less modal dialog will result (under e.g. wxGTK2) + // in an unfocused dialog, so try to find a valid parent for it unless we + // were explicitly asked not to + if ( style & wxDIALOG_NO_PARENT ) + return NULL; + + // first try the given parent + if ( parent ) + parent = CheckIfCanBeUsedAsParent(wxGetTopLevelParent(parent)); + + // then the currently active window + if ( !parent ) + parent = CheckIfCanBeUsedAsParent( + wxGetTopLevelParent(wxGetActiveWindow())); + + // and finally the application main window + if ( !parent ) + parent = CheckIfCanBeUsedAsParent(wxTheApp->GetTopWindow()); + + return parent; +} +#endif + + int DIALOG_SHIM::ShowQuasiModal() { // toggle a window's "enable" status to disabled, then enabled on exit. @@ -147,7 +216,14 @@ int DIALOG_SHIM::ShowQuasiModal() { wxWindow* m_win; ENABLE_DISABLE( wxWindow* aWindow ) : m_win( aWindow ) { if( m_win ) m_win->Disable(); } - ~ENABLE_DISABLE() { if( m_win ) m_win->Enable(); } + ~ENABLE_DISABLE() + { + if( m_win ) + { + m_win->Enable(); + m_win->SetFocus(); // let's focus back on the parent window + } + } }; // This is an exception safe way to zero a pointer before returning. @@ -168,7 +244,7 @@ int DIALOG_SHIM::ShowQuasiModal() if( win ) win->ReleaseMouse(); - wxWindow* parent = GetParentForModalDialog(); + wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() ); ENABLE_DISABLE toggle( parent ); @@ -176,16 +252,13 @@ int DIALOG_SHIM::ShowQuasiModal() m_qmodal_showing = true; - wxGUIEventLoop event_loop; + WX_EVENT_LOOP event_loop; wxEventLoopActivator event_loop_stacker( &event_loop ); m_qmodal_loop = &event_loop; event_loop.Run(); - if( toggle.m_win ) // let's focus back on the parent window - toggle.m_win->SetFocus(); - return GetReturnCode(); } @@ -233,7 +306,7 @@ static bool findWindowRecursively( const wxWindowList& children, const wxWindow* } -static bool findWindowReursively( const wxWindow* topmost, const wxWindow* wanted ) +static bool findWindowRecursively( const wxWindow* topmost, const wxWindow* wanted ) { // wanted may be NULL and that is ok. diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index d171744227..bd993efa0b 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -100,7 +100,7 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) Show( true ); - wxGUIEventLoop event_loop; + WX_EVENT_LOOP event_loop; wxEventLoopActivator event_loop_stacker( &event_loop ); m_modal_loop = &event_loop; diff --git a/include/dialog_shim.h b/include/dialog_shim.h index ae906dc97b..3e2ab62cee 100644 --- a/include/dialog_shim.h +++ b/include/dialog_shim.h @@ -35,6 +35,14 @@ #define DLGSHIM_USE_SETFOCUS 0 #endif +#if wxCHECK_VERSION( 2, 9, 4 ) + #define WX_EVENT_LOOP wxGUIEventLoop +#else + #define WX_EVENT_LOOP wxEventLoop +#endif + +class WX_EVENT_LOOP; + /** * Class DIALOG_SHIM @@ -69,10 +77,16 @@ public: bool Enable( bool enable ); // override wxDialog::Enable virtual protected: + +#if !wxCHECK_VERSION( 2, 9, 4 ) + wxWindow* CheckIfCanBeUsedAsParent( wxWindow* parent ) const; + wxWindow* GetParentForModalDialog( wxWindow *parent, long style ) const; +#endif + std::string m_hash_key; // alternate for class_map when classname re-used. // variables for quasi-modal behavior support, only used by a few derivatives. - wxGUIEventLoop* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed + WX_EVENT_LOOP* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed bool m_qmodal_showing; diff --git a/include/kiway_player.h b/include/kiway_player.h index ff20714bbc..e62981ab54 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -87,7 +87,15 @@ private: class KIWAY_EXPRESS; -class wxGUIEventLoop; + +#if wxCHECK_VERSION( 2, 9, 4 ) + #define WX_EVENT_LOOP wxGUIEventLoop +#else + #define WX_EVENT_LOOP wxEventLoop +#endif + +class WX_EVENT_LOOP; + /** * Class KIWAY_PLAYER @@ -219,7 +227,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 - wxGUIEventLoop* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed + WX_EVENT_LOOP* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed wxString m_modal_string; bool m_modal_ret_val; // true if a selection was made From bb374d2616225df7393d3201599aad07d52fb772 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 4 May 2014 15:27:29 -0500 Subject: [PATCH 08/10] typeinfo.h missing in Debug build for wx2.8 --- common/basicframe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index dbcf15d9f9..8f05616062 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -46,7 +46,7 @@ #include #include - +#include /// The default auto save interval is 10 minutes. #define DEFAULT_AUTO_SAVE_INTERVAL 600 From 74cb23a958f376d6c6b608695ac499892460cb89 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 4 May 2014 19:19:16 -0500 Subject: [PATCH 09/10] Quasimodo is not a monster, he is your friend. --- common/dialog_shim.cpp | 10 ++++++++-- common/kiway_player.cpp | 10 ++++++++-- pcbnew/clean.cpp | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index 548a91cdb4..f8236c1ac6 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -246,14 +246,20 @@ int DIALOG_SHIM::ShowQuasiModal() wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() ); - ENABLE_DISABLE toggle( parent ); + ENABLE_DISABLE toggle( parent ); // quasi-modal: disable only my "optimal" parent Show( true ); m_qmodal_showing = true; 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 ); +#endif m_qmodal_loop = &event_loop; @@ -269,7 +275,7 @@ void DIALOG_SHIM::EndQuasiModal( int retCode ) if( !IsQuasiModal() ) { - wxFAIL_MSG( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal wasn't called" ); + wxFAIL_MSG( wxT( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal wasn't called" ) ); return; } diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index bd993efa0b..ab0ae3e571 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -74,7 +74,7 @@ void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) bool KIWAY_PLAYER::ShowModal( wxString* aResult ) { - wxASSERT_MSG( IsModal(), "ShowModal() shouldn't be called on non-modal frame" ); + wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) ); /* This function has a nice interface but a necessarily unsightly implementation. @@ -95,13 +95,19 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) } clear_this( (void*&) m_modal_loop ); // exception safe way to disable all frames except the modal one, - // re-enable on exit + // re-enables only those that were disabled on exit wxWindowDisabler toggle( this ); Show( true ); 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 ); +#endif m_modal_loop = &event_loop; diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 127f0cbae5..12ca312064 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -203,7 +203,7 @@ bool TRACKS_CLEANER::clean_vias() // Correct via m_End defects (if any), should never happen if( via->GetStart() != via->GetEnd() ) { - wxFAIL_MSG( "Via with mismatching ends" ); + wxFAIL_MSG( wxT( "Via with mismatching ends" ) ); via->SetEnd( via->GetStart() ); } From fc26cdfb7423f1e2b902e3b30b77215b73413a1f Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 5 May 2014 09:46:07 +0200 Subject: [PATCH 10/10] footprint editor: fix crashes. In this fix, I removed the assumption the parent frame is the board editor. However, this assumption is still present here and there in the moduleframe code. --- pcbnew/loadcmp.cpp | 9 ++++++--- pcbnew/moduleframe.cpp | 17 +++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 3aca4d620f..6e66b00c55 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -65,14 +65,17 @@ static FOOTPRINT_LIST MList; bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) { MODULE* newModule; - PCB_BASE_FRAME* parent = (PCB_BASE_FRAME*) GetParent(); + PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false ); + + if( frame == NULL ) // happens if no board editor opened + return false; if( aModule == NULL ) { - if( ! parent->GetBoard() || ! parent->GetBoard()->m_Modules ) + if( ! frame->GetBoard() || ! frame->GetBoard()->m_Modules ) return false; - aModule = SelectFootprint( parent->GetBoard() ); + aModule = SelectFootprint( frame->GetBoard() ); } if( aModule == NULL ) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index c2a9b93d4e..076dc14999 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -50,6 +50,7 @@ #include #include #include +#include static PCB_SCREEN* s_screenModule; // the PCB_SCREEN used by the footprint editor @@ -416,21 +417,21 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent ) { - PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent(); + PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false ); - aEvent.Enable( frame->GetBoard()->m_Modules != NULL ); + aEvent.Enable( frame && frame->GetBoard()->m_Modules != NULL ); } void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent ) { - PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent(); + PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false ); MODULE* module_in_edit = GetBoard()->m_Modules; - bool canInsert = ( module_in_edit && !module_in_edit->GetLink() ); + bool canInsert = frame && module_in_edit && !module_in_edit->GetLink(); // If the source was deleted, the module can inserted but not updated in the board. - if( module_in_edit && module_in_edit->GetLink() ) // this is not a new module + if( frame && module_in_edit && module_in_edit->GetLink() ) // this is not a new module { BOARD* mainpcb = frame->GetBoard(); MODULE* source_module = mainpcb->m_Modules; @@ -451,12 +452,12 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent ) { - PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent(); + PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false ); MODULE* module_in_edit = GetBoard()->m_Modules; - bool canReplace = ( module_in_edit && module_in_edit->GetLink() ); + bool canReplace = frame && module_in_edit && module_in_edit->GetLink(); - if( module_in_edit && module_in_edit->GetLink() ) // this is not a new module + if( canReplace ) // this is not a new module, but verify if the source is still on board { BOARD* mainpcb = frame->GetBoard(); MODULE* source_module = mainpcb->m_Modules;