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 for( wxWindow* child : win->GetChildren() )
570 if( !props->GetPropertyOr(
"persist",
false ) )
574 for( wxWindow* child : GetChildren() )
592 const std::map<std::string, nlohmann::json>& dlgMap = dlgIt->second;
594 std::function<void( wxWindow* )> loadFn =
599 if( !props->GetPropertyOr(
"persist",
false ) )
607 auto it = dlgMap.find( key );
609 if( it != dlgMap.end() )
611 const nlohmann::json& j = it->second;
615 if( j.is_number_integer() )
618 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( win ) )
621 combo->SetValue( wxString::FromUTF8( j.get<std::string>().c_str() ) );
623 else if( wxOwnerDrawnComboBox* od_combo =
dynamic_cast<wxOwnerDrawnComboBox*
>( win ) )
625 if( j.is_number_integer() )
627 int index = j.get<
int>();
629 if( index >= 0 && index < (
int) od_combo->GetCount() )
630 od_combo->SetSelection( index );
633 else if( wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>( win ) )
636 textEntry->ChangeValue( wxString::FromUTF8( j.get<std::string>().c_str() ) );
638 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( win ) )
640 if( j.is_number_integer() )
642 int index = j.get<
int>();
644 if( index >= 0 && index < (
int) choice->GetCount() )
645 choice->SetSelection( index );
648 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( win ) )
651 check->SetValue( j.get<
bool>() );
653 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( win ) )
655 if( j.is_number_integer() )
656 spin->SetValue( j.get<
int>() );
658 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( win ) )
666 radio->SetValue(
true );
669 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( win ) )
671 if( j.is_number_integer() )
673 int index = j.get<
int>();
675 if( index >= 0 && index < (
int) radioBox->GetCount() )
676 radioBox->SetSelection( index );
679 else if( wxSplitterWindow* splitter =
dynamic_cast<wxSplitterWindow*
>( win ) )
681 if( j.is_number_integer() )
682 splitter->SetSashPosition( j.get<
int>() );
684 else if( wxScrolledWindow* scrolled =
dynamic_cast<wxScrolledWindow*
>( win ) )
686 if( j.is_number_integer() )
687 scrolled->SetScrollPos( wxVERTICAL, j.get<
int>() );
689 else if( wxNotebook* notebook =
dynamic_cast<wxNotebook*
>( win ) )
693 wxString pageTitle = wxString::FromUTF8( j.get<std::string>().c_str() );
695 for(
int page = 0; page < (int) notebook->GetPageCount(); ++page )
697 if( notebook->GetPageText( page ) == pageTitle )
698 notebook->SetSelection( page );
705 for( wxWindow* child : win->GetChildren() )
711 if( !props->GetPropertyOr(
"persist",
false ) )
715 for( wxWindow* child : GetChildren() )
724 aWindow->SetClientData( props );
739 for( wxWindow* child : children )
741 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
750#if defined( __WXMAC__ ) || defined( __WXMSW__ )
751 if( !textCtrl->GetStringSelection().IsEmpty() )
755 else if( textCtrl->IsEditable() )
757 textCtrl->SelectAll();
763 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
766 scintilla->Connect( wxEVT_SET_FOCUS,
770 if( !scintilla->GetSelectedText().IsEmpty() )
774 else if( scintilla->GetMarginWidth( 0 ) > 0 )
778 else if( scintilla->IsEditable() )
780 scintilla->SelectAll();
786 else if(
dynamic_cast<wxBitmapButton*
>( child ) !=
nullptr )
789 wxRect rect = child->GetRect();
791 child->ConvertDialogToPixels(
minSize );
793 rect.Inflate( std::max( 0,
minSize.x - rect.GetWidth() ),
794 std::max( 0,
minSize.y - rect.GetHeight() ) );
796 child->SetMinSize( rect.GetSize() );
797 child->SetSize( rect );
810 for( wxWindow* child : children )
812 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( child ) )
817 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( child ) )
822 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( child ) )
828 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( child ) )
831 m_currentValues[ choice ] =
static_cast<long>( choice->GetSelection() );
833 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( child ) )
838 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( child ) )
844 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( child ) )
850 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( child ) )
855 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( child ) )
858 m_currentValues[ radioBox ] =
static_cast<long>( radioBox->GetSelection() );
860 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( child ) )
865 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( child ) )
870 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( child ) )
875 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( child ) )
893 if( before != after )
964 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aCtrl ) )
965 return wxVariant( textCtrl->GetValue() );
966 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aCtrl ) )
967 return wxVariant( scintilla->GetText() );
968 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( aCtrl ) )
969 return wxVariant( combo->GetValue() );
970 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( aCtrl ) )
971 return wxVariant( (
long) choice->GetSelection() );
972 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( aCtrl ) )
973 return wxVariant( check->GetValue() );
974 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( aCtrl ) )
975 return wxVariant( (
long) spin->GetValue() );
976 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( aCtrl ) )
977 return wxVariant( spinD->GetValue() );
978 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( aCtrl ) )
979 return wxVariant( radio->GetValue() );
980 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( aCtrl ) )
981 return wxVariant( (
long) radioBox->GetSelection() );
982 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( aCtrl ) )
984 nlohmann::json j = nlohmann::json::array();
985 int rows =
grid->GetNumberRows();
986 int cols =
grid->GetNumberCols();
988 for(
int r = 0; r < rows; ++r )
990 nlohmann::json row = nlohmann::json::array();
992 for(
int c = 0; c < cols; ++c )
993 row.push_back( std::string(
grid->GetCellValue( r, c ).ToUTF8() ) );
998 return wxVariant( wxString( j.dump() ) );
1000 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( aCtrl ) )
1004 for( wxPropertyGridIterator it = propGrid->GetIterator(); !it.AtEnd(); ++it )
1006 wxPGProperty* prop = *it;
1007 j[ prop->GetName().ToStdString() ] = prop->GetValueAsString().ToStdString();
1010 return wxVariant( wxString( j.dump() ) );
1012 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( aCtrl ) )
1014 nlohmann::json j = nlohmann::json::array();
1015 unsigned int count = checkList->GetCount();
1017 for(
unsigned int i = 0; i < count; ++i )
1019 if( checkList->IsChecked( i ) )
1023 return wxVariant( wxString( j.dump() ) );
1025 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( aCtrl ) )
1027 nlohmann::json j = nlohmann::json::array();
1028 unsigned int rows = dataList->GetItemCount();
1029 unsigned int cols = dataList->GetColumnCount();
1031 for(
unsigned int r = 0; r < rows; ++r )
1033 nlohmann::json row = nlohmann::json::array();
1035 for(
unsigned int c = 0; c < cols; ++c )
1038 dataList->GetValue( val, r, c );
1039 row.push_back( std::string( val.GetString().ToUTF8() ) );
1045 return wxVariant( wxString( j.dump() ) );
1054 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aCtrl ) )
1055 textCtrl->SetValue( aValue.GetString() );
1056 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aCtrl ) )
1057 scintilla->SetText( aValue.GetString() );
1058 else if( wxComboBox* combo =
dynamic_cast<wxComboBox*
>( aCtrl ) )
1059 combo->SetValue( aValue.GetString() );
1060 else if( wxChoice* choice =
dynamic_cast<wxChoice*
>( aCtrl ) )
1061 choice->SetSelection( (
int) aValue.GetLong() );
1062 else if( wxCheckBox* check =
dynamic_cast<wxCheckBox*
>( aCtrl ) )
1063 check->SetValue( aValue.GetBool() );
1064 else if( wxSpinCtrl* spin =
dynamic_cast<wxSpinCtrl*
>( aCtrl ) )
1065 spin->SetValue( (
int) aValue.GetLong() );
1066 else if( wxSpinCtrlDouble* spinD =
dynamic_cast<wxSpinCtrlDouble*
>( aCtrl ) )
1067 spinD->SetValue( aValue.GetDouble() );
1068 else if( wxRadioButton* radio =
dynamic_cast<wxRadioButton*
>( aCtrl ) )
1069 radio->SetValue( aValue.GetBool() );
1070 else if( wxRadioBox* radioBox =
dynamic_cast<wxRadioBox*
>( aCtrl ) )
1071 radioBox->SetSelection( (
int) aValue.GetLong() );
1072 else if( wxGrid*
grid =
dynamic_cast<wxGrid*
>( aCtrl ) )
1074 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1078 int rows = std::min( (
int) j.size(),
grid->GetNumberRows() );
1080 for(
int r = 0; r < rows; ++r )
1082 nlohmann::json row = j[r];
1083 int cols = std::min( (
int) row.size(),
grid->GetNumberCols() );
1085 for(
int c = 0; c < cols; ++c )
1086 grid->SetCellValue( r, c, wxString( row[c].get<std::string>() ) );
1090 else if( wxPropertyGrid* propGrid =
dynamic_cast<wxPropertyGrid*
>( aCtrl ) )
1092 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1096 for(
auto it = j.begin(); it != j.end(); ++it )
1097 propGrid->SetPropertyValue( wxString( it.key() ), wxString( it.value().get<std::string>() ) );
1100 else if( wxCheckListBox* checkList =
dynamic_cast<wxCheckListBox*
>( aCtrl ) )
1102 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1106 unsigned int count = checkList->GetCount();
1108 for(
unsigned int i = 0; i < count; ++i )
1109 checkList->Check( i,
false );
1111 for(
auto& idx : j )
1113 unsigned int i = idx.get<
unsigned int>();
1116 checkList->Check( i,
true );
1120 else if( wxDataViewListCtrl* dataList =
dynamic_cast<wxDataViewListCtrl*
>( aCtrl ) )
1122 nlohmann::json j = nlohmann::json::parse( aValue.GetString().ToStdString(),
nullptr,
false );
1126 unsigned int rows = std::min(
static_cast<unsigned int>( j.size() ),
1127 static_cast<unsigned int>( dataList->GetItemCount() ) );
1129 for(
unsigned int r = 0; r < rows; ++r )
1131 nlohmann::json row = j[r];
1132 unsigned int cols = std::min( (
unsigned int) row.size(), dataList->GetColumnCount() );
1134 for(
unsigned int c = 0; c < cols; ++c )
1136 wxVariant val( wxString( row[c].get<std::string>() ) );
1137 dataList->SetValue( val, r, c );
1198 if( !GetTitle().StartsWith( wxS(
"*" ) ) )
1199 SetTitle( wxS(
"*" ) + GetTitle() );
1205 if( GetTitle().StartsWith( wxS(
"*" ) ) )
1206 SetTitle( GetTitle().AfterFirst(
'*' ) );
1218 return wxDialog::ShowModal();
1254 wxWindow* win = wxWindow::GetCapture();
1256 win->ReleaseMouse();
1259 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
1276 wxGUIEventLoop event_loop;
1287 return GetReturnCode();
1309 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
1312 SetReturnCode( retCode );
1316 wxFAIL_MSG( wxT(
"Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
1317 "wasn't called" ) );
1340 wxString msg = wxString::Format(
"Closing dialog %s", GetTitle() );
1356 const int id = aEvent.GetId();
1360 if(
id == GetAffirmativeId() )
1364 else if(
id == wxID_APPLY )
1375 else if(
id == wxID_CANCEL )
1398 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( aEvent.GetEventObject() ) )
1400 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( aEvent.GetEventObject() ) )
1410 int key = aEvt.GetKeyCode();
1413 if( aEvt.ControlDown() )
1415 if( aEvt.ShiftDown() )
1417 if( aEvt.AltDown() )
1420 int hotkey = key | mods;
1423 if( hotkey == (
MD_CTRL +
'Z') )
1434 if( aEvt.GetKeyCode() ==
'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
1443 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ShiftDown() )
1445 wxObject* eventSource = aEvt.GetEventObject();
1447 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
1450 if( !textCtrl->IsMultiLine() )
1452 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1456#if defined( __WXMAC__ ) || defined( __WXMSW__ )
1457 wxString eol =
"\r\n";
1459 wxString eol =
"\n";
1462 long pos = textCtrl->GetInsertionPoint();
1463 textCtrl->WriteText( eol );
1464 textCtrl->SetInsertionPoint( pos + eol.length() );
1467 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
1469 wxString eol =
"\n";
1470 switch( scintilla->GetEOLMode() )
1472 case wxSTC_EOL_CRLF: eol =
"\r\n";
break;
1473 case wxSTC_EOL_CR: eol =
"\r";
break;
1474 case wxSTC_EOL_LF: eol =
"\n";
break;
1477 long pos = scintilla->GetCurrentPos();
1478 scintilla->InsertText( pos, eol );
1479 scintilla->GotoPos( pos + eol.length() );
1485 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ControlDown() )
1487 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
1490 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
1492 wxWindow* currentWindow = wxWindow::FindFocus();
1493 int currentIdx = -1;
1494 int delta = aEvt.ShiftDown() ? -1 : 1;
1501 idx = ( ( idx +
delta ) % size + size ) % size;
1504 for(
size_t i = 0; i <
m_tabOrder.size(); ++i )
1508 currentIdx = (int) i;
1513 if( currentIdx >= 0 )
1515 advance( currentIdx );
1520 while(
dynamic_cast<wxTextEntry*
>(
m_tabOrder[ currentIdx ] ) ==
nullptr )
1521 advance( currentIdx );
1528 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
1530 wxObject* eventSource = aEvt.GetEventObject();
1532 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
1538 textCtrl->SelectAll();
1542 else if( wxStyledTextCtrl* scintilla =
dynamic_cast<wxStyledTextCtrl*
>( eventSource ) )
1548 scintilla->SelectAll();
1560 wxStdDialogButtonSizer* sdbSizer =
dynamic_cast<wxStdDialogButtonSizer*
>( aSizer );
1563 [&]( wxButton* aButton )
1565 if( aLabels.count( aButton->GetId() ) > 0 )
1567 aButton->SetLabel( aLabels[ aButton->GetId() ] );
1573 switch( aButton->GetId() )
1575 case wxID_OK: aButton->SetLabel(
_(
"&OK" ) );
break;
1576 case wxID_CANCEL: aButton->SetLabel(
_(
"&Cancel" ) );
break;
1577 case wxID_YES: aButton->SetLabel(
_(
"&Yes" ) );
break;
1578 case wxID_NO: aButton->SetLabel(
_(
"&No" ) );
break;
1579 case wxID_APPLY: aButton->SetLabel(
_(
"&Apply" ) );
break;
1580 case wxID_SAVE: aButton->SetLabel(
_(
"&Save" ) );
break;
1581 case wxID_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
1582 case wxID_CONTEXT_HELP: aButton->SetLabel(
_(
"&Help" ) );
break;
1589 if( sdbSizer->GetAffirmativeButton() )
1590 setupButton( sdbSizer->GetAffirmativeButton() );
1592 if( sdbSizer->GetApplyButton() )
1593 setupButton( sdbSizer->GetApplyButton() );
1595 if( sdbSizer->GetNegativeButton() )
1596 setupButton( sdbSizer->GetNegativeButton() );
1598 if( sdbSizer->GetCancelButton() )
1599 setupButton( sdbSizer->GetCancelButton() );
1601 if( sdbSizer->GetHelpButton() )
1602 setupButton( sdbSizer->GetHelpButton() );
1606 if( sdbSizer->GetAffirmativeButton() )
1607 sdbSizer->GetAffirmativeButton()->SetDefault();
1610 for( wxSizerItem* item : aSizer->GetChildren() )
1612 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)