39#include <wx/display.h>
40#include <wx/evtloop.h>
44#include <wx/propgrid/propgrid.h>
45#include <wx/checklst.h>
46#include <wx/dataview.h>
47#include <wx/bmpbuttn.h>
48#include <wx/textctrl.h>
49#include <wx/stc/stc.h>
50#include <wx/combobox.h>
51#include <wx/odcombo.h>
53#include <wx/checkbox.h>
54#include <wx/spinctrl.h>
55#include <wx/splitter.h>
56#include <wx/radiobox.h>
57#include <wx/radiobut.h>
58#include <wx/variant.h>
62#include <nlohmann/json.hpp>
71 const wxPoint& pos, const wxSize& size,
long style,
72 const wxString&
name ) :
73 wxDialog( aParent,
id, title, pos, size, style,
name ),
95 while( !kiwayHolder && aParent->GetParent() )
97 aParent = aParent->GetParent();
111 m_parentFrame = static_cast<EDA_BASE_FRAME*>( kiwayHolder );
112 TOOL_MANAGER* toolMgr = m_parentFrame->GetToolManager();
114 if( toolMgr && toolMgr->IsContextMenuActive() )
115 toolMgr->VetoContextMenuMouseWarp();
123 Kiway().SetBlockingDialog(
this );
141 wxString msg = wxString::Format(
"Opening dialog %s", GetTitle() );
157 std::function<void( wxWindowList& )> disconnectFocusHandlers =
158 [&]( wxWindowList& children )
160 for( wxWindow* child : children )
162 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
167 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
174 disconnectFocusHandlers( child->GetChildren() );
179 disconnectFocusHandlers( GetChildren() );
181 std::function<void( wxWindowList& )> disconnectUndoRedoHandlers =
182 [&]( wxWindowList& children )
184 for( wxWindow* child : children )
186 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
190 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
194 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( child ) )
199 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( child ) )
203 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( child ) )
207 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( child ) )
212 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( child ) )
217 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( child ) )
221 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( child ) )
225 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( child ) )
229 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( child ) )
233 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( child ) )
237 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( child ) )
243 disconnectUndoRedoHandlers( child->GetChildren() );
248 disconnectUndoRedoHandlers( GetChildren() );
275 GetSizer()->SetSizeHints(
this );
282 SetSize( ConvertDialogToPixels( sz ) );
289 return ConvertDialogToPixels( sz ).x;
296 return ConvertDialogToPixels( sz ).y;
308 wxDialog::SetPosition( aNewPosition );
321 ret = wxDialog::Show( show );
323 wxRect savedDialogRect;
328 auto dlgIt = settings->m_dialogControlValues.find( key );
330 if( dlgIt != settings->m_dialogControlValues.end() )
332 auto geoIt = dlgIt->second.find(
"__geometry" );
334 if( geoIt != dlgIt->second.end() && geoIt->second.is_object() )
336 const nlohmann::json& g = geoIt->second;
337 savedDialogRect.SetPosition( wxPoint( g.value(
"x", 0 ), g.value(
"y", 0 ) ) );
338 savedDialogRect.SetSize( wxSize( g.value(
"w", 500 ), g.value(
"h", 300 ) ) );
343 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
347 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
348 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
352 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
353 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
354 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ), 0 );
357 if( m_parent !=
nullptr )
359 if( wxDisplay::GetFromPoint( m_parent->GetPosition() )
360 != wxDisplay::GetFromPoint( savedDialogRect.GetPosition() ) )
373 if( wxDisplay::GetFromWindow(
this ) == wxNOT_FOUND )
386 m_eventLoop->Exit( GetReturnCode() );
389 ret = wxDialog::Show( show );
394 m_parent->SetFocus();
407 auto dlgIt = settings->m_dialogControlValues.find( key );
409 if( dlgIt == settings->m_dialogControlValues.end() )
412 dlgIt->second.erase(
"__geometry" );
434 return wxDialog::Enable( enable );
440 auto getSiblingIndex =
441 [](
const wxWindow* parent,
const wxWindow* child )
443 wxString childClass = child->GetClassInfo()->GetClassName();
446 for(
const wxWindow* sibling : parent->GetChildren() )
448 if( sibling->GetClassInfo()->GetClassName() != childClass )
451 if( sibling == child )
461 [&](
const wxWindow* window )
463 std::string key = wxString( window->GetClassInfo()->GetClassName() ).ToStdString();
465 if( window->GetParent() )
466 key +=
"_" + std::to_string( getSiblingIndex( window->GetParent(), window ) );
471 std::string key =
makeKey( aWin );
473 for(
const wxWindow* parent = aWin->GetParent(); parent && parent !=
this; parent = parent->GetParent() )
490 wxRect rect( GetPosition(), GetSize() );
492 geom[
"x" ] = rect.GetX();
493 geom[
"y" ] = rect.GetY();
494 geom[
"w" ] = rect.GetWidth();
495 geom[
"h" ] = rect.GetHeight();
496 dlgMap[
"__geometry" ] = geom;
498 std::function<void( wxWindow* )> saveFn =
503 if( !props->GetPropertyOr(
"persist",
false ) )
515 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( win ) )
517 dlgMap[ key ] = combo->GetValue();
519 else if( wxOwnerDrawnComboBox* od_combo =
dynamic_cast<wxOwnerDrawnComboBox*
>( win ) )
521 dlgMap[ key ] = od_combo->GetSelection();
523 else if( wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>( win ) )
525 dlgMap[ key ] = textEntry->GetValue();
527 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( win ) )
529 dlgMap[ key ] = choice->GetSelection();
531 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( win ) )
533 dlgMap[ key ] = check->GetValue();
535 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( win ) )
537 dlgMap[ key ] = spin->GetValue();
539 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( win ) )
541 dlgMap[ key ] = radio->GetValue();
543 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( win ) )
545 dlgMap[ key ] = radioBox->GetSelection();
547 else if( wxSplitterWindow* splitter =
dynamic_cast<wxSplitterWindow*
>( win ) )
549 dlgMap[ key ] = splitter->GetSashPosition();
551 else if( wxScrolledWindow* scrolled =
dynamic_cast<wxScrolledWindow*
>( win ) )
553 dlgMap[ key ] = scrolled->GetScrollPos( wxVERTICAL );
555 else if( wxNotebook* notebook =
dynamic_cast<wxNotebook*
>( win ) )
557 int index = notebook->GetSelection();
559 if(
index >= 0 &&
index < (
int) notebook->GetPageCount() )
560 dlgMap[ key ] = notebook->GetPageText( notebook->GetSelection() );
564 dlgMap[ key ] =
grid->GetShownColumnsAsString();
568 for( wxWindow* child : win->GetChildren() )
574 if( !props->GetPropertyOr(
"persist",
false ) )
578 for( wxWindow* child : GetChildren() )
596 const std::map<std::string, nlohmann::json>& dlgMap = dlgIt->second;
598 std::function<void( wxWindow* )> loadFn =
603 if( !props->GetPropertyOr(
"persist",
false ) )
611 auto it = dlgMap.find( key );
613 if( it != dlgMap.end() )
615 const nlohmann::json& j = it->second;
619 if( j.is_number_integer() )
622 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( win ) )
625 combo->SetValue( wxString::FromUTF8( j.get<std::string>().c_str() ) );
627 else if( wxOwnerDrawnComboBox* od_combo =
dynamic_cast<wxOwnerDrawnComboBox*
>( win ) )
629 if( j.is_number_integer() )
631 int index = j.get<
int>();
633 if(
index >= 0 &&
index < (
int) od_combo->GetCount() )
634 od_combo->SetSelection(
index );
637 else if( wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>( win ) )
640 textEntry->ChangeValue( wxString::FromUTF8( j.get<std::string>().c_str() ) );
642 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( win ) )
644 if( j.is_number_integer() )
646 int index = j.get<
int>();
648 if(
index >= 0 &&
index < (
int) choice->GetCount() )
649 choice->SetSelection(
index );
652 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( win ) )
655 check->SetValue( j.get<
bool>() );
657 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( win ) )
659 if( j.is_number_integer() )
660 spin->SetValue( j.get<
int>() );
662 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( win ) )
670 radio->SetValue(
true );
673 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( win ) )
675 if( j.is_number_integer() )
677 int index = j.get<
int>();
679 if(
index >= 0 &&
index < (
int) radioBox->GetCount() )
680 radioBox->SetSelection(
index );
683 else if( wxSplitterWindow* splitter =
dynamic_cast<wxSplitterWindow*
>( win ) )
685 if( j.is_number_integer() )
686 splitter->SetSashPosition( j.get<
int>() );
688 else if( wxScrolledWindow* scrolled =
dynamic_cast<wxScrolledWindow*
>( win ) )
690 if( j.is_number_integer() )
691 scrolled->SetScrollPos( wxVERTICAL, j.get<
int>() );
693 else if( wxNotebook* notebook =
dynamic_cast<wxNotebook*
>( win ) )
697 wxString pageTitle = wxString::FromUTF8( j.get<std::string>().c_str() );
699 for(
int page = 0; page < (int) notebook->GetPageCount(); ++page )
701 if( notebook->GetPageText( page ) == pageTitle )
702 notebook->SetSelection( page );
709 grid->ShowHideColumns( wxString::FromUTF8( j.get<std::string>().c_str() ) );
714 for( wxWindow* child : win->GetChildren() )
720 if( !props->GetPropertyOr(
"persist",
false ) )
724 for( wxWindow* child : GetChildren() )
733 aWindow->SetClientData( props );
748 for( wxWindow* child : children )
750 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
759#if defined( __WXMAC__ ) || defined( __WXMSW__ )
760 if( !textCtrl->GetStringSelection().IsEmpty() )
764 else if( textCtrl->IsEditable() )
766 textCtrl->SelectAll();
772 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
775 scintilla->Connect( wxEVT_SET_FOCUS,
779 if( !scintilla->GetSelectedText().IsEmpty() )
783 else if( scintilla->GetMarginWidth( 0 ) > 0 )
787 else if( scintilla->IsEditable() )
789 scintilla->SelectAll();
795 else if(
dynamic_cast<wxBitmapButton*
>( child ) !=
nullptr )
798 wxRect rect = child->GetRect();
800 child->ConvertDialogToPixels(
minSize );
802 rect.Inflate( std::max( 0,
minSize.x - rect.GetWidth() ),
803 std::max( 0,
minSize.y - rect.GetHeight() ) );
805 child->SetMinSize( rect.GetSize() );
806 child->SetSize( rect );
819 for( wxWindow* child : children )
821 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
826 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
831 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( child ) )
837 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( child ) )
840 m_currentValues[ choice ] =
static_cast<long>( choice->GetSelection() );
842 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( child ) )
847 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( child ) )
853 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( child ) )
859 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( child ) )
864 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( child ) )
867 m_currentValues[ radioBox ] =
static_cast<long>( radioBox->GetSelection() );
869 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( child ) )
874 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( child ) )
879 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( child ) )
884 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( child ) )
902 if( before != after )
973 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aCtrl ) )
974 return wxVariant( textCtrl->GetValue() );
975 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aCtrl ) )
976 return wxVariant( scintilla->GetText() );
977 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( aCtrl ) )
978 return wxVariant( combo->GetValue() );
979 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( aCtrl ) )
980 return wxVariant( (
long) choice->GetSelection() );
981 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( aCtrl ) )
982 return wxVariant( check->GetValue() );
983 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( aCtrl ) )
984 return wxVariant( (
long) spin->GetValue() );
985 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( aCtrl ) )
986 return wxVariant( spinD->GetValue() );
987 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( aCtrl ) )
988 return wxVariant( radio->GetValue() );
989 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( aCtrl ) )
990 return wxVariant( (
long) radioBox->GetSelection() );
991 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( aCtrl ) )
993 nlohmann::json j = nlohmann::json::array();
994 int rows =
grid->GetNumberRows();
995 int cols =
grid->GetNumberCols();
997 for(
int r = 0; r < rows; ++r )
999 nlohmann::json row = nlohmann::json::array();
1001 for(
int c = 0; c < cols; ++c )
1002 row.push_back( std::string(
grid->GetCellValue( r, c ).ToUTF8() ) );
1007 return wxVariant( wxString( j.dump() ) );
1009 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( aCtrl ) )
1013 for( wxPropertyGridIterator it = propGrid->GetIterator(); !it.AtEnd(); ++it )
1015 wxPGProperty* prop = *it;
1016 j[ prop->GetName().ToStdString() ] = prop->GetValueAsString().ToStdString();
1019 return wxVariant( wxString( j.dump() ) );
1021 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( aCtrl ) )
1023 nlohmann::json j = nlohmann::json::array();
1024 unsigned int count = checkList->GetCount();
1026 for(
unsigned int i = 0; i < count; ++i )
1028 if( checkList->IsChecked( i ) )
1032 return wxVariant( wxString( j.dump() ) );
1034 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( aCtrl ) )
1036 nlohmann::json j = nlohmann::json::array();
1037 unsigned int rows = dataList->GetItemCount();
1038 unsigned int cols = dataList->GetColumnCount();
1040 for(
unsigned int r = 0; r < rows; ++r )
1042 nlohmann::json row = nlohmann::json::array();
1044 for(
unsigned int c = 0; c < cols; ++c )
1047 dataList->GetValue( val, r, c );
1048 row.push_back( std::string( val.GetString().ToUTF8() ) );
1054 return wxVariant( wxString( j.dump() ) );
1063 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aCtrl ) )
1064 textCtrl->SetValue( aValue.GetString() );
1065 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aCtrl ) )
1066 scintilla->SetText( aValue.GetString() );
1067 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( aCtrl ) )
1068 combo->SetValue( aValue.GetString() );
1069 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( aCtrl ) )
1070 choice->SetSelection( (
int) aValue.GetLong() );
1071 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( aCtrl ) )
1072 check->SetValue( aValue.GetBool() );
1073 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( aCtrl ) )
1074 spin->SetValue( (
int) aValue.GetLong() );
1075 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( aCtrl ) )
1076 spinD->SetValue( aValue.GetDouble() );
1077 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( aCtrl ) )
1078 radio->SetValue( aValue.GetBool() );
1079 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( aCtrl ) )
1080 radioBox->SetSelection( (
int) aValue.GetLong() );
1081 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( aCtrl ) )
1083 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1087 int rows = std::min( (
int) j.size(),
grid->GetNumberRows() );
1089 for(
int r = 0; r < rows; ++r )
1091 nlohmann::json row = j[r];
1092 int cols = std::min( (
int) row.size(),
grid->GetNumberCols() );
1094 for(
int c = 0; c < cols; ++c )
1095 grid->SetCellValue( r, c, wxString( row[c].get<std::string>() ) );
1099 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( aCtrl ) )
1101 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1105 for(
auto it = j.begin(); it != j.end(); ++it )
1106 propGrid->SetPropertyValue( wxString( it.key() ), wxString( it.value().get<std::string>() ) );
1109 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( aCtrl ) )
1111 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1115 unsigned int count = checkList->GetCount();
1117 for(
unsigned int i = 0; i < count; ++i )
1118 checkList->Check( i,
false );
1120 for(
auto& idx : j )
1122 unsigned int i = idx.get<
unsigned int>();
1125 checkList->Check( i,
true );
1129 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( aCtrl ) )
1131 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1135 unsigned int rows = std::min(
static_cast<unsigned int>( j.size() ),
1136 static_cast<unsigned int>( dataList->GetItemCount() ) );
1138 for(
unsigned int r = 0; r < rows; ++r )
1140 nlohmann::json row = j[r];
1141 unsigned int cols = std::min( (
unsigned int) row.size(), dataList->GetColumnCount() );
1143 for(
unsigned int c = 0; c < cols; ++c )
1145 wxVariant val( wxString( row[c].get<std::string>() ) );
1146 dataList->SetValue( val, r, c );
1207 if( !GetTitle().StartsWith( wxS(
"*" ) ) )
1208 SetTitle( wxS(
"*" ) + GetTitle() );
1214 if( GetTitle().StartsWith( wxS(
"*" ) ) )
1215 SetTitle( GetTitle().AfterFirst(
'*' ) );
1227 return wxDialog::ShowModal();
1263 wxWindow* win = wxWindow::GetCapture();
1265 win->ReleaseMouse();
1268 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
1285 wxGUIEventLoop event_loop;
1296 return GetReturnCode();
1318 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
1321 SetReturnCode( retCode );
1325 wxFAIL_MSG( wxT(
"Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
1326 "wasn't called" ) );
1349 wxString msg = wxString::Format(
"Closing dialog %s", GetTitle() );
1365 const int id = aEvent.GetId();
1369 if(
id == GetAffirmativeId() )
1373 else if(
id == wxID_APPLY )
1384 else if(
id == wxID_CANCEL )
1407 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
1409 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
1419 int key = aEvt.GetKeyCode();
1422 if( aEvt.ControlDown() )
1424 if( aEvt.ShiftDown() )
1426 if( aEvt.AltDown() )
1429 int hotkey = key | mods;
1432 if( hotkey == (
MD_CTRL +
'Z') )
1443 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
1452 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ShiftDown() )
1454 wxObject* eventSource = aEvt.GetEventObject();
1456 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
1459 if( !textCtrl->IsMultiLine() )
1461 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1465#if defined( __WXMAC__ ) || defined( __WXMSW__ )
1466 wxString eol =
"\r\n";
1468 wxString eol =
"\n";
1471 long pos = textCtrl->GetInsertionPoint();
1472 textCtrl->WriteText( eol );
1473 textCtrl->SetInsertionPoint( pos + eol.length() );
1476 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
1478 wxString eol =
"\n";
1479 switch( scintilla->GetEOLMode() )
1481 case wxSTC_EOL_CRLF: eol =
"\r\n";
break;
1482 case wxSTC_EOL_CR: eol =
"\r";
break;
1483 case wxSTC_EOL_LF: eol =
"\n";
break;
1486 long pos = scintilla->GetCurrentPos();
1487 scintilla->InsertText( pos, eol );
1488 scintilla->GotoPos( pos + eol.length() );
1494 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ControlDown() )
1496 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1499 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
1501 wxWindow* currentWindow = wxWindow::FindFocus();
1502 int currentIdx = -1;
1503 int delta = aEvt.ShiftDown() ? -1 : 1;
1510 idx = ( ( idx +
delta ) % size + size ) % size;
1513 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
1517 currentIdx = (int) i;
1522 if( currentIdx >= 0 )
1524 advance( currentIdx );
1529 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
1530 advance( currentIdx );
1537 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
1539 wxObject* eventSource = aEvt.GetEventObject();
1541 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
1547 textCtrl->SelectAll();
1551 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
1557 scintilla->SelectAll();
1569 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
1572 [&]( wxButton* aButton )
1574 if( aLabels.count( aButton->GetId() ) > 0 )
1576 aButton->SetLabel( aLabels[ aButton->GetId() ] );
1582 switch( aButton->GetId() )
1584 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
1585 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
1586 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
1587 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
1588 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
1589 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
1590 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
1591 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
1598 if( sdbSizer->GetAffirmativeButton() )
1599 setupButton( sdbSizer->GetAffirmativeButton() );
1601 if( sdbSizer->GetApplyButton() )
1602 setupButton( sdbSizer->GetApplyButton() );
1604 if( sdbSizer->GetNegativeButton() )
1605 setupButton( sdbSizer->GetNegativeButton() );
1607 if( sdbSizer->GetCancelButton() )
1608 setupButton( sdbSizer->GetCancelButton() );
1610 if( sdbSizer->GetHelpButton() )
1611 setupButton( sdbSizer->GetHelpButton() );
1615 if( sdbSizer->GetAffirmativeButton() )
1616 sdbSizer->GetAffirmativeButton()->SetDefault();
1619 for( wxSizerItem* item : aSizer->GetChildren() )
1621 if( item->GetSizer() )
std::map< std::string, std::map< std::string, nlohmann::json > > m_dialogControlValues
Persistent dialog control values.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
void SelectAllInTextCtrls(wxWindowList &children)
wxVariant getControlValue(wxWindow *aCtrl)
void onPropertyGridChanged(wxPropertyGridEvent &aEvent)
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.
void recordControlChange(wxWindow *aCtrl)
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
bool Show(bool show) override
std::vector< UNDO_STEP > m_redoStack
void setControlValue(wxWindow *aCtrl, const wxVariant &aValue)
wxGUIEventLoop * m_qmodal_loop
void onChildSetFocus(wxFocusEvent &aEvent)
void LoadControlState()
Load persisted control values from the current project's local settings.
void OptOut(wxWindow *aWindow)
Opt out of control state saving.
void SaveControlState()
Save control values and geometry to the current project's local settings.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
WINDOW_DISABLER * m_qmodal_parent_disabler
void onInitDialog(wxInitDialogEvent &aEvent)
void onSpinDoubleEvent(wxSpinDoubleEvent &aEvent)
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".
void onDataViewListChanged(wxDataViewEvent &aEvent)
bool IsQuasiModal() const
std::map< wxWindow *, UNIT_BINDER * > m_unitBinders
void EndQuasiModal(int retCode)
void RegisterUnitBinder(UNIT_BINDER *aUnitBinder, wxWindow *aWindow)
Register a UNIT_BINDER so that it can handle units in control-state save/restore.
void OnMove(wxMoveEvent &aEvent)
void onCommandEvent(wxCommandEvent &aEvent)
void CleanupAfterModalSubDialog()
std::string generateKey(const wxWindow *aWin) const
void PrepareForModalSubDialog()
void OnButton(wxCommandEvent &aEvent)
Properly handle the default button events when in the quasimodal mode when not calling EndQuasiModal ...
void onGridCellChanged(wxGridEvent &aEvent)
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void registerUndoRedoHandlers(wxWindowList &aChildren)
wxWindow * m_initialFocusTarget
void OnSize(wxSizeEvent &aEvent)
bool Enable(bool enable) override
DIALOG_SHIM(wxWindow *aParent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER, const wxString &name=wxDialogNameStr)
void SetPosition(const wxPoint &aNewPosition)
Force the position of the dialog to a new position.
void onSpinEvent(wxSpinEvent &aEvent)
void OnCloseWindow(wxCloseEvent &aEvent)
Properly handle the wxCloseEvent when in the quasimodal mode when not calling EndQuasiModal which is ...
std::map< wxWindow *, wxVariant > m_currentValues
EDA_BASE_FRAME * m_parentFrame
virtual void OnCharHook(wxKeyEvent &aEvt)
std::vector< UNDO_STEP > m_undoStack
void onStyledTextChanged(wxStyledTextEvent &aEvent)
The base frame for deriving all KiCad main window classes.
KIWAY_HOLDER(KIWAY *aKiway, HOLDER_TYPE aType)
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
void SetKiway(wxWindow *aDest, KIWAY *aKiway)
It is only used for debugging, since "this" is not a wxWindow*.
bool HasKiway() const
Safety check before asking for the Kiway reference.
HOLDER_TYPE GetType() const
void SetBlockingDialog(wxWindow *aWin)
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
bool SetProperty(const std::string &aKey, T &&aValue)
Set a property with the given key and value.
static PROPERTY_HOLDER * SafeCast(void *aPtr) noexcept
Safely cast a void pointer to PROPERTY_HOLDER*.
EDA_UNITS GetUserUnits() const
Temporarily disable a window, and then re-enable on destruction.
static void recursiveDescent(wxSizer *aSizer, std::map< int, wxString > &aLabels)
const int minSize
Push and Shove router track width and via size dialog.
void ignore_unused(const T &)
void AddNavigationBreadcrumb(const wxString &aMsg, const wxString &aCategory)
Add a navigation breadcrumb.
static wxString makeKey(const wxString &aFirst, const wxString &aSecond)
Assemble a two part key as a simple concatenation of aFirst and aSecond parts, using a separator.
PGM_BASE & Pgm()
The global program "get" accessor.
KIWAY Kiway(KFCTL_STANDALONE)