34#include <wx/display.h>
35#include <wx/evtloop.h>
39#include <wx/bmpbuttn.h>
40#include <wx/textctrl.h>
41#include <wx/stc/stc.h>
51 const wxPoint& pos, const wxSize& size,
long style,
52 const wxString&
name ) :
53 wxDialog( aParent,
id, title, pos, size, style,
name ),
56 m_useCalculatedSize( false ),
57 m_firstPaintEvent( true ),
58 m_initialFocusTarget(
nullptr ),
60 m_qmodal_loop(
nullptr ),
61 m_qmodal_showing( false ),
62 m_qmodal_parent_disabler(
nullptr ),
63 m_parentFrame(
nullptr )
72 while( !kiwayHolder && aParent->GetParent() )
74 aParent = aParent->GetParent();
97 SetKiway(
this, &kiwayHolder->
Kiway() );
125 std::function<void( wxWindowList& )> disconnectFocusHandlers = [&]( wxWindowList& children )
127 for( wxWindow* child : children )
129 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
131 textCtrl->Disconnect( wxEVT_SET_FOCUS,
135 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
137 scintilla->Disconnect( wxEVT_SET_FOCUS,
143 disconnectFocusHandlers( child->GetChildren() );
148 disconnectFocusHandlers( GetChildren() );
168 GetSizer()->SetSizeHints(
this );
175 SetSize( ConvertDialogToPixels( sz ) );
182 return ConvertDialogToPixels( sz ).x;
189 return ConvertDialogToPixels( sz ).y;
197static std::unordered_map<std::string, wxRect>
class_map;
202 wxDialog::SetPosition( aNewPosition );
205 const char* hash_key;
214 hash_key =
typeid(*this).name();
217 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
222 wxRect rect = it->second;
223 rect.SetPosition( aNewPosition );
232 const char* hash_key;
241 hash_key =
typeid(*this).name();
251 ret = wxDialog::Show( show );
254 wxRect savedDialogRect =
class_map[ hash_key ];
256 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
260 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
261 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
265 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
266 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
267 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
271 if( m_parent !=
nullptr )
273 if( wxDisplay::GetFromPoint( m_parent->GetPosition() )
274 != wxDisplay::GetFromPoint( savedDialogRect.GetPosition() ) )
288 if( wxDisplay::GetFromWindow(
this ) == wxNOT_FOUND )
294 class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
298 m_eventLoop->Exit( GetReturnCode() );
301 ret = wxDialog::Show( show );
304 m_parent->SetFocus();
313 const char* hash_key;
322 hash_key =
typeid(*this).name();
325 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
330 wxRect rect = it->second;
331 rect.SetSize( wxSize( 0, 0 ) );
339 return wxDialog::Enable( enable );
348 for( wxWindow* child : children )
350 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
359#if defined( __WXMAC__ ) || defined( __WXMSW__ )
360 if( !textCtrl->GetStringSelection().IsEmpty() )
364 else if( textCtrl->IsEditable() )
366 textCtrl->SelectAll();
372 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
375 scintilla->Connect( wxEVT_SET_FOCUS,
379 if( !scintilla->GetSelectedText().IsEmpty() )
383 else if( scintilla->GetMarginWidth( 0 ) > 0 )
387 else if( scintilla->IsEditable() )
389 scintilla->SelectAll();
395 else if(
dynamic_cast<wxBitmapButton*
>( child ) !=
nullptr )
398 wxRect rect = child->GetRect();
400 child->ConvertDialogToPixels(
minSize );
402 rect.Inflate( std::max( 0,
minSize.x - rect.GetWidth() ),
403 std::max( 0,
minSize.y - rect.GetHeight() ) );
405 child->SetMinSize( rect.GetSize() );
406 child->SetSize( rect );
439 if( !GetTitle().StartsWith( wxS(
"*" ) ) )
440 SetTitle( wxS(
"*" ) + GetTitle() );
446 if( GetTitle().StartsWith( wxS(
"*" ) ) )
447 SetTitle( GetTitle().AfterFirst(
'*' ) );
459 return wxDialog::ShowModal();
492 wxWindow* win = wxWindow::GetCapture();
497 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
515 wxGUIEventLoop event_loop;
526 return GetReturnCode();
548 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
551 SetReturnCode( retCode );
555 wxFAIL_MSG( wxT(
"Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
594 const int id = aEvent.GetId();
598 if(
id == GetAffirmativeId() )
602 else if(
id == wxID_APPLY )
613 else if(
id == wxID_CANCEL )
636 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
638 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
648 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
657 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
658 && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
660 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
663 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
665 wxWindow* currentWindow = wxWindow::FindFocus();
667 int delta = aEvt.ShiftDown() ? -1 : 1;
674 idx = ( ( idx +
delta ) % size + size ) % size;
677 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
681 currentIdx = (int) i;
686 if( currentIdx >= 0 )
688 advance( currentIdx );
693 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
694 advance( currentIdx );
701 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
703 wxObject* eventSource = aEvt.GetEventObject();
705 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
711 textCtrl->SelectAll();
715 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
721 scintilla->SelectAll();
733 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
736 [&]( wxButton* aButton )
738 if( aLabels.count( aButton->GetId() ) > 0 )
740 aButton->SetLabel( aLabels[ aButton->GetId() ] );
746 switch( aButton->GetId() )
748 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
749 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
750 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
751 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
752 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
753 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
754 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
755 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
762 if( sdbSizer->GetAffirmativeButton() )
763 setupButton( sdbSizer->GetAffirmativeButton() );
765 if( sdbSizer->GetApplyButton() )
766 setupButton( sdbSizer->GetApplyButton() );
768 if( sdbSizer->GetNegativeButton() )
769 setupButton( sdbSizer->GetNegativeButton() );
771 if( sdbSizer->GetCancelButton() )
772 setupButton( sdbSizer->GetCancelButton() );
774 if( sdbSizer->GetHelpButton() )
775 setupButton( sdbSizer->GetHelpButton() );
779 if( sdbSizer->GetAffirmativeButton() )
780 sdbSizer->GetAffirmativeButton()->SetDefault();
783 for( wxSizerItem* item : aSizer->GetChildren() )
785 if( item->GetSizer() )
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
void SelectAllInTextCtrls(wxWindowList &children)
std::vector< wxWindow * > m_tabOrder
void OnPaint(wxPaintEvent &event)
virtual void TearDownQuasiModal()
Override this method to perform dialog tear down actions not suitable for object dtor.
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
bool Show(bool show) override
wxGUIEventLoop * m_qmodal_loop
void onChildSetFocus(wxFocusEvent &aEvent)
void SetupStandardButtons(std::map< int, wxString > aLabels={})
WINDOW_DISABLER * m_qmodal_parent_disabler
int horizPixelsFromDU(int x) const
Convert an integer number of dialog units to pixels, horizontally.
void resetSize()
Clear the existing dialog size and position.
std::map< wxWindow *, wxString > m_beforeEditValues
void setSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
bool IsQuasiModal() const
void EndQuasiModal(int retCode)
void CleanupAfterModalSubDialog()
void PrepareForModalSubDialog()
void OnButton(wxCommandEvent &aEvent)
Properly handle the default button events when in the quasimodal mode when not calling EndQuasiModal ...
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxWindow * m_initialFocusTarget
bool Enable(bool enable) override
void SetPosition(const wxPoint &aNewPosition)
Force the position of the dialog to a new position.
void OnCloseWindow(wxCloseEvent &aEvent)
Properly handle the wxCloseEvent when in the quasimodal mode when not calling EndQuasiModal which is ...
EDA_BASE_FRAME * m_parentFrame
virtual void OnCharHook(wxKeyEvent &aEvt)
EDA_UNITS GetUserUnits() const
The base frame for deriving all KiCad main window classes.
virtual void ToggleUserUnits()
A mix in class which holds the location of a wxWindow's KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
bool HasKiway() const
Safety check before asking for the Kiway reference.
HOLDER_TYPE GetType() const
void SetBlockingDialog(wxWindow *aWin)
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
EDA_UNITS GetUserUnits() const
Temporarily disable a window, and then re-enable on destruction.
void SuspendForTrueModal()
void ResumeAfterTrueModal()
static void recursiveDescent(wxSizer *aSizer, std::map< int, wxString > &aLabels)
static std::unordered_map< std::string, wxRect > class_map
const int minSize
Push and Shove router track width and via size dialog.
void ignore_unused(const T &)
PGM_BASE & Pgm()
The global program "get" accessor.
KIWAY Kiway(KFCTL_STANDALONE)