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"
610 const int id = aEvent.GetId();
614 if(
id == GetAffirmativeId() )
618 else if(
id == wxID_APPLY )
629 else if(
id == wxID_CANCEL )
652 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
654 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
664 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
673 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
674 && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
676 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
679 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
681 wxWindow* currentWindow = wxWindow::FindFocus();
683 int delta = aEvt.ShiftDown() ? -1 : 1;
690 idx = ( ( idx +
delta ) % size + size ) % size;
693 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
697 currentIdx = (int) i;
702 if( currentIdx >= 0 )
704 advance( currentIdx );
709 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
710 advance( currentIdx );
717 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
719 wxObject* eventSource = aEvt.GetEventObject();
721 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
727 textCtrl->SelectAll();
731 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
737 scintilla->SelectAll();
749 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
752 [&]( wxButton* aButton )
754 if( aLabels.count( aButton->GetId() ) > 0 )
756 aButton->SetLabel( aLabels[ aButton->GetId() ] );
762 switch( aButton->GetId() )
764 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
765 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
766 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
767 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
768 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
769 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
770 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
771 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
778 if( sdbSizer->GetAffirmativeButton() )
779 setupButton( sdbSizer->GetAffirmativeButton() );
781 if( sdbSizer->GetApplyButton() )
782 setupButton( sdbSizer->GetApplyButton() );
784 if( sdbSizer->GetNegativeButton() )
785 setupButton( sdbSizer->GetNegativeButton() );
787 if( sdbSizer->GetCancelButton() )
788 setupButton( sdbSizer->GetCancelButton() );
790 if( sdbSizer->GetHelpButton() )
791 setupButton( sdbSizer->GetHelpButton() );
795 if( sdbSizer->GetAffirmativeButton() )
796 sdbSizer->GetAffirmativeButton()->SetDefault();
799 for( wxSizerItem* item : aSizer->GetChildren() )
801 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)
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)