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"
592 const int id = aEvent.GetId();
596 if(
id == GetAffirmativeId() )
600 else if(
id == wxID_APPLY )
611 else if(
id == wxID_CANCEL )
634 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
636 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
646 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
655 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ShiftDown() )
657 wxObject* eventSource = aEvt.GetEventObject();
659 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
661#if defined( __WXMAC__ ) || defined( __WXMSW__ )
662 wxString eol =
"\r\n";
667 long pos = textCtrl->GetInsertionPoint();
668 textCtrl->WriteText( eol );
669 textCtrl->SetInsertionPoint( pos + eol.length() );
672 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
675 switch( scintilla->GetEOLMode() )
677 case wxSTC_EOL_CRLF: eol =
"\r\n";
break;
678 case wxSTC_EOL_CR: eol =
"\r";
break;
679 case wxSTC_EOL_LF: eol =
"\n";
break;
682 long pos = scintilla->GetCurrentPos();
683 scintilla->InsertText( pos, eol );
684 scintilla->GotoPos( pos + eol.length() );
690 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ControlDown() )
692 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
695 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
697 wxWindow* currentWindow = wxWindow::FindFocus();
699 int delta = aEvt.ShiftDown() ? -1 : 1;
706 idx = ( ( idx +
delta ) % size + size ) % size;
709 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
713 currentIdx = (int) i;
718 if( currentIdx >= 0 )
720 advance( currentIdx );
725 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
726 advance( currentIdx );
733 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
735 wxObject* eventSource = aEvt.GetEventObject();
737 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
743 textCtrl->SelectAll();
747 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
753 scintilla->SelectAll();
765 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
768 [&]( wxButton* aButton )
770 if( aLabels.count( aButton->GetId() ) > 0 )
772 aButton->SetLabel( aLabels[ aButton->GetId() ] );
778 switch( aButton->GetId() )
780 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
781 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
782 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
783 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
784 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
785 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
786 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
787 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
794 if( sdbSizer->GetAffirmativeButton() )
795 setupButton( sdbSizer->GetAffirmativeButton() );
797 if( sdbSizer->GetApplyButton() )
798 setupButton( sdbSizer->GetApplyButton() );
800 if( sdbSizer->GetNegativeButton() )
801 setupButton( sdbSizer->GetNegativeButton() );
803 if( sdbSizer->GetCancelButton() )
804 setupButton( sdbSizer->GetCancelButton() );
806 if( sdbSizer->GetHelpButton() )
807 setupButton( sdbSizer->GetHelpButton() );
811 if( sdbSizer->GetAffirmativeButton() )
812 sdbSizer->GetAffirmativeButton()->SetDefault();
815 for( wxSizerItem* item : aSizer->GetChildren() )
817 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)