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>
88 const wxPoint& pos, const wxSize& size,
long style,
89 const wxString&
name ) :
90 wxDialog( aParent,
id, title, pos, size, style,
name ),
93 m_useCalculatedSize( false ),
94 m_firstPaintEvent( true ),
95 m_initialFocusTarget(
nullptr ),
97 m_qmodal_loop(
nullptr ),
98 m_qmodal_showing( false ),
99 m_qmodal_parent_disabler(
nullptr ),
100 m_parentFrame(
nullptr )
103 m_initialSize = size;
109 while( !kiwayHolder && aParent->GetParent() )
111 aParent = aParent->GetParent();
126 TOOL_MANAGER* toolMgr = m_parentFrame->GetToolManager();
134 SetKiway(
this, &kiwayHolder->
Kiway() );
162 std::function<void( wxWindowList& )> disconnectFocusHandlers = [&]( wxWindowList& children )
164 for( wxWindow* child : children )
166 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
168 textCtrl->Disconnect( wxEVT_SET_FOCUS,
172 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
174 scintilla->Disconnect( wxEVT_SET_FOCUS,
180 disconnectFocusHandlers( child->GetChildren() );
185 disconnectFocusHandlers( GetChildren() );
205 GetSizer()->SetSizeHints(
this );
212 SetSize( ConvertDialogToPixels( sz ) );
219 return ConvertDialogToPixels( sz ).x;
226 return ConvertDialogToPixels( sz ).y;
234static std::unordered_map<std::string, wxRect>
class_map;
239 wxDialog::SetPosition( aNewPosition );
242 const char* hash_key;
251 hash_key =
typeid(*this).name();
254 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
259 wxRect rect = it->second;
260 rect.SetPosition( aNewPosition );
269 const char* hash_key;
278 hash_key =
typeid(*this).name();
288 ret = wxDialog::Show( show );
291 wxRect savedDialogRect =
class_map[ hash_key ];
293 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
297 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
298 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
302 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
303 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
304 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
308 if( m_parent !=
nullptr )
310 if( wxDisplay::GetFromPoint( m_parent->GetPosition() )
311 != wxDisplay::GetFromPoint( savedDialogRect.GetPosition() ) )
325 if( wxDisplay::GetFromWindow(
this ) == wxNOT_FOUND )
331 class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
335 m_eventLoop->Exit( GetReturnCode() );
338 ret = wxDialog::Show( show );
341 m_parent->SetFocus();
350 const char* hash_key;
359 hash_key =
typeid(*this).name();
362 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
367 wxRect rect = it->second;
368 rect.SetSize( wxSize( 0, 0 ) );
376 return wxDialog::Enable( enable );
385 for( wxWindow* child : children )
387 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
396#if defined( __WXMAC__ ) || defined( __WXMSW__ )
397 if( !textCtrl->GetStringSelection().IsEmpty() )
401 else if( textCtrl->IsEditable() )
403 textCtrl->SelectAll();
409 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
412 scintilla->Connect( wxEVT_SET_FOCUS,
416 if( !scintilla->GetSelectedText().IsEmpty() )
420 else if( scintilla->GetMarginWidth( 0 ) > 0 )
424 else if( scintilla->IsEditable() )
426 scintilla->SelectAll();
432 else if(
dynamic_cast<wxBitmapButton*
>( child ) !=
nullptr )
435 wxRect rect = child->GetRect();
437 child->ConvertDialogToPixels(
minSize );
439 rect.Inflate( std::max( 0,
minSize.x - rect.GetWidth() ),
440 std::max( 0,
minSize.y - rect.GetHeight() ) );
442 child->SetMinSize( rect.GetSize() );
443 child->SetSize( rect );
476 if( !GetTitle().StartsWith( wxS(
"*" ) ) )
477 SetTitle( wxS(
"*" ) + GetTitle() );
483 if( GetTitle().StartsWith( wxS(
"*" ) ) )
484 SetTitle( GetTitle().AfterFirst(
'*' ) );
496 return wxDialog::ShowModal();
530 NULLER(
void*& aPtr ) : m_what( aPtr ) {}
531 ~NULLER() { m_what =
nullptr; }
537 wxWindow* win = wxWindow::GetCapture();
542 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
560 wxGUIEventLoop event_loop;
571 return GetReturnCode();
593 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
596 SetReturnCode( retCode );
600 wxFAIL_MSG( wxT(
"Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
639 const int id = aEvent.GetId();
643 if(
id == GetAffirmativeId() )
647 else if(
id == wxID_APPLY )
658 else if(
id == wxID_CANCEL )
681 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
683 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
693 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
702 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
703 && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
705 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
708 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
710 wxWindow* currentWindow = wxWindow::FindFocus();
712 int delta = aEvt.ShiftDown() ? -1 : 1;
719 idx = ( ( idx +
delta ) % size + size ) % size;
722 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
726 currentIdx = (int) i;
731 if( currentIdx >= 0 )
733 advance( currentIdx );
738 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
739 advance( currentIdx );
746 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
748 wxObject* eventSource = aEvt.GetEventObject();
750 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
756 textCtrl->SelectAll();
760 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
766 scintilla->SelectAll();
778 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
781 [&]( wxButton* aButton )
783 if( aLabels.count( aButton->GetId() ) > 0 )
785 aButton->SetLabel( aLabels[ aButton->GetId() ] );
791 switch( aButton->GetId() )
793 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
794 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
795 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
796 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
797 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
798 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
799 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
800 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
807 if( sdbSizer->GetAffirmativeButton() )
808 setupButton( sdbSizer->GetAffirmativeButton() );
810 if( sdbSizer->GetApplyButton() )
811 setupButton( sdbSizer->GetApplyButton() );
813 if( sdbSizer->GetNegativeButton() )
814 setupButton( sdbSizer->GetNegativeButton() );
816 if( sdbSizer->GetCancelButton() )
817 setupButton( sdbSizer->GetCancelButton() );
819 if( sdbSizer->GetHelpButton() )
820 setupButton( sdbSizer->GetHelpButton() );
824 if( sdbSizer->GetAffirmativeButton() )
825 sdbSizer->GetAffirmativeButton()->SetDefault();
828 for( wxSizerItem* item : aSizer->GetChildren() )
830 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={})
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
WDO_ENABLE_DISABLE * m_qmodal_parent_disabler
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
Toggle a window's "enable" status to disabled, then enabled on destruction.
void ResumeAfterTrueModal()
void SuspendForTrueModal()
WDO_ENABLE_DISABLE(wxWindow *aWindow)
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)