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>
76 const wxPoint& pos, const wxSize& size,
long style,
77 const wxString&
name ) :
78 wxDialog( aParent,
id, title, pos, size, style,
name ),
81 m_useCalculatedSize( false ),
82 m_firstPaintEvent( true ),
83 m_initialFocusTarget(
nullptr ),
85 m_qmodal_loop(
nullptr ),
86 m_qmodal_showing( false ),
87 m_qmodal_parent_disabler(
nullptr ),
88 m_parentFrame(
nullptr )
97 while( !kiwayHolder && aParent->GetParent() )
99 aParent = aParent->GetParent();
114 TOOL_MANAGER* toolMgr = m_parentFrame->GetToolManager();
122 SetKiway(
this, &kiwayHolder->
Kiway() );
150 std::function<void( wxWindowList& )> disconnectFocusHandlers = [&]( wxWindowList& children )
152 for( wxWindow* child : children )
154 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
156 textCtrl->Disconnect( wxEVT_SET_FOCUS,
160 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
162 scintilla->Disconnect( wxEVT_SET_FOCUS,
168 disconnectFocusHandlers( child->GetChildren() );
173 disconnectFocusHandlers( GetChildren() );
193 GetSizer()->SetSizeHints(
this );
200 SetSize( ConvertDialogToPixels( sz ) );
207 return ConvertDialogToPixels( sz ).x;
214 return ConvertDialogToPixels( sz ).y;
222static std::unordered_map<std::string, wxRect>
class_map;
227 wxDialog::SetPosition( aNewPosition );
230 const char* hash_key;
239 hash_key =
typeid(*this).name();
242 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
247 wxRect rect = it->second;
248 rect.SetPosition( aNewPosition );
257 const char* hash_key;
266 hash_key =
typeid(*this).name();
276 ret = wxDialog::Show( show );
279 wxRect savedDialogRect =
class_map[ hash_key ];
281 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
285 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
286 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
290 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
291 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
292 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
296 if( m_parent !=
nullptr )
298 if( wxDisplay::GetFromPoint( m_parent->GetPosition() )
299 != wxDisplay::GetFromPoint( savedDialogRect.GetPosition() ) )
313 if( wxDisplay::GetFromWindow(
this ) == wxNOT_FOUND )
319 class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
323 m_eventLoop->Exit( GetReturnCode() );
326 ret = wxDialog::Show( show );
329 m_parent->SetFocus();
338 const char* hash_key;
347 hash_key =
typeid(*this).name();
350 std::unordered_map<std::string, wxRect>::iterator it =
class_map.find( hash_key );
355 wxRect rect = it->second;
356 rect.SetSize( wxSize( 0, 0 ) );
364 return wxDialog::Enable( enable );
373 for( wxWindow* child : children )
375 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
384#if defined( __WXMAC__ ) || defined( __WXMSW__ )
385 if( !textCtrl->GetStringSelection().IsEmpty() )
389 else if( textCtrl->IsEditable() )
391 textCtrl->SelectAll();
397 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
403 if( !scintilla->GetSelectedText().IsEmpty() )
407 else if( scintilla->GetMarginWidth( 0 ) > 0 )
411 else if( scintilla->IsEditable() )
413 scintilla->SelectAll();
419 else if(
dynamic_cast<wxBitmapButton*
>( child ) !=
nullptr )
422 wxRect rect = child->GetRect();
424 child->ConvertDialogToPixels(
minSize );
426 rect.Inflate( std::max( 0,
minSize.x - rect.GetWidth() ),
427 std::max( 0,
minSize.y - rect.GetHeight() ) );
429 child->SetMinSize( rect.GetSize() );
430 child->SetSize( rect );
463 if( !GetTitle().StartsWith( wxS(
"*" ) ) )
464 SetTitle( wxS(
"*" ) + GetTitle() );
470 if( GetTitle().StartsWith( wxS(
"*" ) ) )
471 SetTitle( GetTitle().AfterFirst(
'*' ) );
483 return wxDialog::ShowModal();
517 NULLER(
void*& aPtr ) : m_what( aPtr ) {}
518 ~NULLER() { m_what =
nullptr; }
524 wxWindow* win = wxWindow::GetCapture();
529 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
547 wxGUIEventLoop event_loop;
558 return GetReturnCode();
566 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
569 SetReturnCode( retCode );
573 wxFAIL_MSG( wxT(
"Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
612 const int id = aEvent.GetId();
616 if(
id == GetAffirmativeId() )
620 else if(
id == wxID_APPLY )
631 else if(
id == wxID_CANCEL )
654 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
656 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
666 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
675 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
676 && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
678 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
681 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
683 wxWindow* currentWindow = wxWindow::FindFocus();
685 int delta = aEvt.ShiftDown() ? -1 : 1;
692 idx = ( ( idx +
delta ) % size + size ) % size;
695 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
699 currentIdx = (int) i;
704 if( currentIdx >= 0 )
706 advance( currentIdx );
711 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
712 advance( currentIdx );
719 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
721 wxObject* eventSource = aEvt.GetEventObject();
723 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
729 textCtrl->SelectAll();
733 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
739 scintilla->SelectAll();
751 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
754 [&]( wxButton* aButton )
756 if( aLabels.count( aButton->GetId() ) > 0 )
758 aButton->SetLabel( aLabels[ aButton->GetId() ] );
764 switch( aButton->GetId() )
766 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
767 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
768 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
769 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
770 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
771 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
772 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
773 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
780 if( sdbSizer->GetAffirmativeButton() )
781 setupButton( sdbSizer->GetAffirmativeButton() );
783 if( sdbSizer->GetApplyButton() )
784 setupButton( sdbSizer->GetApplyButton() );
786 if( sdbSizer->GetNegativeButton() )
787 setupButton( sdbSizer->GetNegativeButton() );
789 if( sdbSizer->GetCancelButton() )
790 setupButton( sdbSizer->GetCancelButton() );
792 if( sdbSizer->GetHelpButton() )
793 setupButton( sdbSizer->GetHelpButton() );
797 if( sdbSizer->GetAffirmativeButton() )
798 sdbSizer->GetAffirmativeButton()->SetDefault();
801 for( wxSizerItem* item : aSizer->GetChildren() )
803 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 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()
Returns 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.
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)