KiCad PCB EDA Suite
dialog_shim.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2012-2018 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <dialog_shim.h>
26 #include <kiway_player.h>
27 #include <wx/evtloop.h>
28 #include <pgm_base.h>
29 #include <eda_rect.h>
30 #include <wx/display.h>
31 
34 {
35  wxWindow* m_win;
36 
37 public:
38 
39  WDO_ENABLE_DISABLE( wxWindow* aWindow ) :
40  m_win( aWindow )
41  {
42  if( m_win )
43  m_win->Disable();
44  }
45 
47  {
48  if( m_win )
49  {
50  m_win->Enable();
51  m_win->SetFocus(); // let's focus back on the parent window
52  }
53  }
54 };
55 
56 
57 DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& title,
58  const wxPoint& pos, const wxSize& size, long style, const wxString& name ) :
59  wxDialog( aParent, id, title, pos, size, style, name ),
60  KIWAY_HOLDER( 0 ),
61  m_fixupsRun( false ),
62  m_qmodal_loop( 0 ),
63  m_qmodal_showing( false ),
64  m_qmodal_parent_disabler( 0 )
65 {
66  // pray that aParent is either a KIWAY_PLAYER or DIALOG_SHIM derivation.
67  KIWAY_HOLDER* h = dynamic_cast<KIWAY_HOLDER*>( aParent );
68 
69  // wxASSERT_MSG( h, wxT( "DIALOG_SHIM's parent is NULL or not derived from KIWAY_PLAYER nor DIALOG_SHIM" ) );
70 
71  if( h )
72  SetKiway( this, &h->Kiway() );
73 
74  Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
75  Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
76 
77 #ifdef __WINDOWS__
78  // On Windows, the app top windows can be brought to the foreground
79  // (at least temporary) in certain circumstances,
80  // for instance when calling an external tool in Eeschema boom generation.
81  // So set the parent KIWAY_PLAYER kicad frame (if exists) to top window
82  // to avoid this annoying behavior
83  KIWAY_PLAYER* parent_kiwayplayer = dynamic_cast<KIWAY_PLAYER*>( aParent );
84 
85  if( parent_kiwayplayer )
86  Pgm().App().SetTopWindow( parent_kiwayplayer );
87 #endif
88 
89  Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_SHIM::OnPaint ) );
90 }
91 
92 
94 {
95  // if the dialog is quasi-modal, this will end its event loop
96  if( IsQuasiModal() )
97  EndQuasiModal( wxID_CANCEL );
98 
100  delete m_qmodal_parent_disabler; // usually NULL by now
101 }
102 
103 
105 {
106  // must be called from the constructor of derived classes,
107  // when all widgets are initialized, and therefore their size fixed
108 
109  // SetSizeHints fixes the minimal size of sizers in the dialog
110  // (SetSizeHints calls Fit(), so no need to call it)
111  GetSizer()->SetSizeHints( this );
112 
113  // the default position, when calling the first time the dlg
114  Center();
115 }
116 
117 
118 void DIALOG_SHIM::SetSizeInDU( int x, int y )
119 {
120  wxSize sz( x, y );
121  SetSize( ConvertDialogToPixels( sz ) );
122 }
123 
124 
126 {
127  wxSize sz( x, 0 );
128  return ConvertDialogToPixels( sz ).x;
129 }
130 
131 
133 {
134  wxSize sz( 0, y );
135  return ConvertDialogToPixels( sz ).y;
136 }
137 
138 
139 // our hashtable is an implementation secret, don't need or want it in a header file
140 #include <hashtables.h>
141 #include <base_struct.h> // EDA_RECT
142 #include <typeinfo>
143 
145 
146 bool DIALOG_SHIM::Show( bool show )
147 {
148  bool ret;
149  const char* hash_key;
150 
151  if( m_hash_key.size() )
152  {
153  // a special case like EDA_LIST_DIALOG, which has multiple uses.
154  hash_key = m_hash_key.c_str();
155  }
156  else
157  {
158  hash_key = typeid(*this).name();
159  }
160 
161  // Show or hide the window. If hiding, save current position and size.
162  // If showing, use previous position and size.
163  if( show )
164  {
165 #ifndef __WINDOWS__
166  wxDialog::Raise(); // Needed on OS X and some other window managers (i.e. Unity)
167 #endif
168  ret = wxDialog::Show( show );
169 
170  // classname is key, returns a zeroed out default EDA_RECT if none existed before.
171  EDA_RECT savedDialogRect = class_map[ hash_key ];
172 
173  if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
174  {
175  SetSize( savedDialogRect.GetPosition().x,
176  savedDialogRect.GetPosition().y,
177  std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
178  std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
179  0 );
180  }
181 
182  // Be sure that the dialog appears in a visible area
183  // (the dialog position might have been stored at the time when it was
184  // shown on another display)
185  if( wxDisplay::GetFromWindow( this ) == wxNOT_FOUND )
186  Centre();
187  }
188  else
189  {
190  // Save the dialog's position & size before hiding, using classname as key
191  class_map[ hash_key ] = EDA_RECT( wxDialog::GetPosition(), wxDialog::GetSize() );
192 
193 #ifdef __WXMAC__
194  if ( m_eventLoop )
195  m_eventLoop->Exit( GetReturnCode() ); // Needed for APP-MODAL dlgs on OSX
196 #endif
197 
198  ret = wxDialog::Show( show );
199  }
200 
201  return ret;
202 }
203 
204 
205 bool DIALOG_SHIM::Enable( bool enable )
206 {
207  // so we can do logging of this state change:
208 
209 #if defined(DEBUG)
210  const char* type_id = typeid( *this ).name();
211  printf( "wxDialog %s: %s\n", type_id, enable ? "enabled" : "disabled" );
212 #endif
213 
214  return wxDialog::Enable( enable );
215 }
216 
217 
218 // Traverse all items in the dialog. If selectTextInTextCtrls, do a SelectAll()
219 // in each so that tab followed by typing will replace the existing value.
220 // Also collects the firstTextCtrl and the item with focus (if any).
221 static void recursiveDescent( wxWindowList& children, const bool selectTextInTextCtrls,
222  wxWindow* & firstTextCtrl, wxWindow* & windowWithFocus )
223 {
224  for( wxWindowList::iterator it = children.begin(); it != children.end(); ++it )
225  {
226  wxWindow* child = *it;
227 
228  if( child->HasFocus() )
229  windowWithFocus = child;
230 
231  wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child );
232  if( childTextCtrl )
233  {
234  if( !firstTextCtrl && childTextCtrl->IsEnabled() && childTextCtrl->IsEditable() )
235  firstTextCtrl = childTextCtrl;
236 
237  if( selectTextInTextCtrls )
238  {
239  wxTextEntry* asTextEntry = dynamic_cast<wxTextEntry*>( childTextCtrl );
240  // Respect an existing selection
241  if( asTextEntry->GetStringSelection().IsEmpty() )
242  asTextEntry->SelectAll();
243  }
244  }
245 
246  recursiveDescent( child->GetChildren(), selectTextInTextCtrls, firstTextCtrl,
247  windowWithFocus );
248  }
249 }
250 
251 #ifdef __WXMAC__
252 static void fixOSXCancelButtonIssue( wxWindow *aWindow )
253 {
254  // A ugly hack to fix an issue on OSX: cmd+c closes the dialog instead of
255  // copying the text if a button with wxID_CANCEL is used in a
256  // wxStdDialogButtonSizer created by wxFormBuilder: the label is &Cancel, and
257  // this accelerator key has priority over the standard copy accelerator.
258  wxButton* button = dynamic_cast<wxButton*>( wxWindow::FindWindowById( wxID_CANCEL, aWindow ) );
259 
260  if( button )
261  {
262  wxString buttonLabel = button->GetLabel();
263  buttonLabel.Replace( wxT( "&C" ), wxT( "C" ) );
264  buttonLabel.Replace( wxT( "&c" ), wxT( "c" ) );
265  button->SetLabel( buttonLabel );
266  }
267 }
268 #endif
269 
270 
271 void DIALOG_SHIM::OnPaint( wxPaintEvent &event )
272 {
273  if( !m_fixupsRun )
274  {
275 #if DLGSHIM_SELECT_ALL_IN_TEXT_CONTROLS
276  const bool selectAllInTextCtrls = true;
277 #else
278  const bool selectAllInTextCtrls = false;
279 #endif
280  wxWindow* firstTextCtrl = NULL;
281  wxWindow* windowWithFocus = NULL;
282 
283  recursiveDescent( GetChildren(), selectAllInTextCtrls, firstTextCtrl,
284  windowWithFocus );
285 
286 #if DLGSHIM_USE_SETFOCUS
287  // While it would be nice to honour any focus already set (which was
288  // recorded in windowWithFocus), the reality is that it's currently wrong
289  // far more often than it's right.
290  // So just focus on the first text control if we have one; otherwise the
291  // focus on the dialog itself, which will at least allow esc, return, etc.
292  // to function.
293  if( firstTextCtrl )
294  firstTextCtrl->SetFocus();
295  else
296  SetFocus();
297 #endif
298 
299 #ifdef __WXMAC__
300  fixOSXCancelButtonIssue( this );
301 #endif
302 
303  m_fixupsRun = true;
304  }
305 
306  event.Skip();
307 }
308 
309 
310 /*
311  Quasi-Modal Mode Explained:
312 
313  The gtk calls in wxDialog::ShowModal() cause event routing problems if that
314  modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up
315  and mostly works but does not respond to the window decoration close button.
316  There is no way to get around this without reversing the gtk calls temporarily.
317 
318  Quasi-Modal mode is our own almost modal mode which disables only the parent
319  of the DIALOG_SHIM, leaving other frames operable and while staying captured in the
320  nested event loop. This avoids the gtk calls and leaves event routing pure
321  and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using
322  ShowQuasiModal() you have to use EndQuasiModal() in your dialogs and not
323  EndModal(). There is also IsQuasiModal() but its value can only be true
324  when the nested event loop is active. Do not mix the modal and quasi-modal
325  functions. Use one set or the other.
326 
327  You might find this behavior preferable over a pure modal mode, and it was said
328  that only the Mac has this natively, but now other platforms have something
329  similar. You CAN use it anywhere for any dialog. But you MUST use it when
330  you want to use KIWAY_PLAYER::ShowModal() from a dialog event.
331 */
332 
333 
334 
335 /*
339 class ELOOP_ACTIVATOR
340 {
341  friend class EVENT_LOOP;
342 
343 public:
344  ELOOP_ACTIVATOR( WX_EVENT_LOOP* evtLoop )
345  {
346  m_evtLoopOld = wxEventLoopBase::GetActive();
347  // wxEventLoopBase::SetActive( evtLoop );
348  }
349 
350  ~ELOOP_ACTIVATOR()
351  {
352  // restore the previously active event loop
353  wxEventLoopBase::SetActive( m_evtLoopOld );
354  }
355 
356 private:
357  WX_EVENT_LOOP* m_evtLoopOld;
358 };
359 */
360 
361 
362 class EVENT_LOOP : public WX_EVENT_LOOP
363 {
364 public:
365 
367  {
368  ;
369  }
370 
372  {
373  }
374 
375 #if 0 // does not work any better than inherited wxGuiEventLoop functions:
376 
377  // sets the "should exit" flag and wakes up the loop so that it terminates
378  // soon
379  void ScheduleExit( int rc = 0 )
380  {
381  wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not running") );
382 
383  m_exitcode = rc;
384  m_shouldExit = true;
385 
386  OnExit();
387 
388  // all we have to do to exit from the loop is to (maybe) wake it up so that
389  // it can notice that Exit() had been called
390  //
391  // in particular, do *not* use here calls such as PostQuitMessage() (under
392  // MSW) which terminate the current event loop here because we're not sure
393  // that it is going to be processed by the correct event loop: it would be
394  // possible that another one is started and terminated by mistake if we do
395  // this
396  WakeUp();
397  }
398 
399  int Run()
400  {
401  // event loops are not recursive, you need to create another loop!
402  //wxCHECK_MSG( !IsInsideRun(), -1, wxT("can't reenter a message loop") );
403 
404  // ProcessIdle() and ProcessEvents() below may throw so the code here should
405  // be exception-safe, hence we must use local objects for all actions we
406  // should undo
407  wxEventLoopActivator activate(this);
408 
409  // We might be called again, after a previous call to ScheduleExit(), so
410  // reset this flag.
411  m_shouldExit = false;
412 
413  // Set this variable to true for the duration of this method.
414  setInsideRun( true );
415 
416  struct SET_FALSE
417  {
418  EVENT_LOOP* m_loop;
419  SET_FALSE( EVENT_LOOP* aLoop ) : m_loop( aLoop ) {}
420  ~SET_FALSE() { m_loop->setInsideRun( false ); }
421  } t( this );
422 
423  // Finally really run the loop.
424  return DoRun();
425  }
426 
427  bool ProcessEvents()
428  {
429  // process pending wx events first as they correspond to low-level events
430  // which happened before, i.e. typically pending events were queued by a
431  // previous call to Dispatch() and if we didn't process them now the next
432  // call to it might enqueue them again (as happens with e.g. socket events
433  // which would be generated as long as there is input available on socket
434  // and this input is only removed from it when pending event handlers are
435  // executed)
436  if( wxTheApp )
437  {
438  wxTheApp->ProcessPendingEvents();
439 
440  // One of the pending event handlers could have decided to exit the
441  // loop so check for the flag before trying to dispatch more events
442  // (which could block indefinitely if no more are coming).
443  if( m_shouldExit )
444  return false;
445  }
446 
447  return Dispatch();
448  }
449 
450 
451  int DoRun()
452  {
453  // we must ensure that OnExit() is called even if an exception is thrown
454  // from inside ProcessEvents() but we must call it from Exit() in normal
455  // situations because it is supposed to be called synchronously,
456  // wxModalEventLoop depends on this (so we can't just use ON_BLOCK_EXIT or
457  // something similar here)
458  #if wxUSE_EXCEPTIONS
459  for( ; ; )
460  {
461  try
462  {
463  #endif // wxUSE_EXCEPTIONS
464 
465  // this is the event loop itself
466  for( ; ; )
467  {
468  // generate and process idle events for as long as we don't
469  // have anything else to do
470  while ( !m_shouldExit && !Pending() && ProcessIdle() )
471  ;
472 
473  if ( m_shouldExit )
474  break;
475 
476  // a message came or no more idle processing to do, dispatch
477  // all the pending events and call Dispatch() to wait for the
478  // next message
479  if ( !ProcessEvents() )
480  {
481  // we got WM_QUIT
482  break;
483  }
484  }
485 
486  // Process the remaining queued messages, both at the level of the
487  // underlying toolkit level (Pending/Dispatch()) and wx level
488  // (Has/ProcessPendingEvents()).
489  //
490  // We do run the risk of never exiting this loop if pending event
491  // handlers endlessly generate new events but they shouldn't do
492  // this in a well-behaved program and we shouldn't just discard the
493  // events we already have, they might be important.
494  for( ; ; )
495  {
496  bool hasMoreEvents = false;
497  if ( wxTheApp && wxTheApp->HasPendingEvents() )
498  {
499  wxTheApp->ProcessPendingEvents();
500  hasMoreEvents = true;
501  }
502 
503  if ( Pending() )
504  {
505  Dispatch();
506  hasMoreEvents = true;
507  }
508 
509  if ( !hasMoreEvents )
510  break;
511  }
512 
513  #if wxUSE_EXCEPTIONS
514  // exit the outer loop as well
515  break;
516  }
517  catch ( ... )
518  {
519  try
520  {
521  if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() )
522  {
523  OnExit();
524  break;
525  }
526  //else: continue running the event loop
527  }
528  catch ( ... )
529  {
530  // OnException() throwed, possibly rethrowing the same
531  // exception again: very good, but we still need OnExit() to
532  // be called
533  OnExit();
534  throw;
535  }
536  }
537  }
538  #endif // wxUSE_EXCEPTIONS
539 
540  return m_exitcode;
541  }
542 
543 protected:
544  int m_exitcode;
545 
546  /* this only works if you add
547  friend class EVENT_LOOP
548  to EventLoopBase
549  */
550  void setInsideRun( bool aValue )
551  {
552  m_isInsideRun = aValue;
553  }
554 #endif
555 };
556 
557 
559 {
560  // This is an exception safe way to zero a pointer before returning.
561  // Yes, even though DismissModal() clears this first normally, this is
562  // here in case there's an exception before the dialog is dismissed.
563  struct NULLER
564  {
565  void*& m_what;
566  NULLER( void*& aPtr ) : m_what( aPtr ) {}
567  ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction
568  } clear_this( (void*&) m_qmodal_loop );
569 
570  // release the mouse if it's currently captured as the window having it
571  // will be disabled when this dialog is shown -- but will still keep the
572  // capture making it impossible to do anything in the modal dialog itself
573  wxWindow* win = wxWindow::GetCapture();
574  if( win )
575  win->ReleaseMouse();
576 
577  // Get the optimal parent
578  wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
579 
580  // Show the optimal parent
581  DBG( if( parent ) printf( "%s: optimal parent: %s\n", __func__, typeid(*parent).name() );)
582 
583  wxASSERT_MSG( !m_qmodal_parent_disabler,
584  wxT( "Caller using ShowQuasiModal() twice on same window?" ) );
585 
586  // quasi-modal: disable only my "optimal" parent
588 
589 #ifdef __WXMAC__
590  // Apple in its infinite wisdom will raise a disabled window before even passing
591  // us the event, so we have no way to stop it. Instead, we must set an order on
592  // the windows so that the quasi-modal will be pushed in front of the disabled
593  // window when it is raised.
594  ReparentQuasiModal();
595 #endif
596  Show( true );
597 
598  m_qmodal_showing = true;
599 
600  EVENT_LOOP event_loop;
601 
602  m_qmodal_loop = &event_loop;
603 
604  event_loop.Run();
605 
606  return GetReturnCode();
607 }
608 
609 
610 void DIALOG_SHIM::EndQuasiModal( int retCode )
611 {
612  // Hook up validator and transfer data from controls handling so quasi-modal dialogs
613  // handle validation in the same way as other dialogs.
614  if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
615  return;
616 
617  SetReturnCode( retCode );
618 
619  if( !IsQuasiModal() )
620  {
621  wxFAIL_MSG( wxT( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal wasn't called" ) );
622  return;
623  }
624 
625  m_qmodal_showing = false;
626 
627  if( m_qmodal_loop )
628  {
629  if( m_qmodal_loop->IsRunning() )
630  m_qmodal_loop->Exit( 0 );
631  else
632  m_qmodal_loop->ScheduleExit( 0 );
633 
634  m_qmodal_loop = NULL;
635  }
636 
639 
640  Show( false );
641 }
642 
643 
644 void DIALOG_SHIM::OnCloseWindow( wxCloseEvent& aEvent )
645 {
646  if( IsQuasiModal() )
647  {
648  EndQuasiModal( wxID_CANCEL );
649  return;
650  }
651 
652  // This is mandatory to allow wxDialogBase::OnCloseWindow() to be called.
653  aEvent.Skip();
654 }
655 
656 
657 void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
658 {
659  if( IsQuasiModal() )
660  {
661  const int id = aEvent.GetId();
662 
663  if( id == GetAffirmativeId() )
664  {
665  EndQuasiModal( id );
666  }
667  else if( id == wxID_APPLY )
668  {
669  // Dialogs that provide Apply buttons should make sure data is valid before
670  // allowing a transfer, as there is no other way to indicate failure
671  // (i.e. the dialog can't refuse to close as it might with OK, because it
672  // isn't closing anyway)
673  if( Validate() )
674  {
675  bool success = TransferDataFromWindow();
676  (void) success;
677  }
678  }
679  else if( id == GetEscapeId() ||
680  (id == wxID_CANCEL && GetEscapeId() == wxID_ANY) )
681  {
682  EndQuasiModal( wxID_CANCEL );
683  }
684  else // not a standard button
685  {
686  aEvent.Skip();
687  }
688 
689  return;
690  }
691 
692  // This is mandatory to allow wxDialogBase::OnButton() to be called.
693  aEvent.Skip();
694 }
bool m_qmodal_showing
Definition: dialog_shim.h:155
Class KIWAY_HOLDER is a mix in class which holds the location of a wxWindow&#39;s KIWAY.
Definition: kiway_player.h:48
Class KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a porti...
Definition: kiway_player.h:111
void SetKiway(wxWindow *aDest, KIWAY *aKiway)
Function SetKiway.
#define WX_EVENT_LOOP
Definition: kiway_player.h:91
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
void OnButton(wxCommandEvent &aEvent)
Function OnCloseWindow.
const wxSize GetSize() const
Definition: eda_rect.h:101
std::string m_hash_key
Definition: dialog_shim.h:151
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
VTBL_ENTRY wxApp & App()
Function App returns a bare naked wxApp, which may come from wxPython, SINGLE_TOP, or kicad.exe.
Definition: pgm_base.cpp:323
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
EVENT_LOOP * m_qmodal_loop
Definition: dialog_shim.h:154
void OnCloseWindow(wxCloseEvent &aEvent)
Function OnCloseWindow.
int ShowQuasiModal()
static RECT_MAP class_map
void SetSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
bool IsQuasiModal()
Definition: dialog_shim.h:103
void OnPaint(wxPaintEvent &event)
const wxPoint GetPosition() const
Definition: eda_rect.h:113
bool Show(bool show) override
int VertPixelsFromDU(int y)
Convert an integer number of dialog units to pixels, vertically.
WDO_ENABLE_DISABLE * m_qmodal_parent_disabler
Definition: dialog_shim.h:156
void EndQuasiModal(int retCode)
see class PGM_BASE
DIALOG_SHIM(wxWindow *aParent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const wxString &name=wxDialogNameStr)
Definition: dialog_shim.cpp:57
const char * name
Definition: DXF_plotter.cpp:61
#define max(a, b)
Definition: auxiliary.h:86
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
Toggle a window&#39;s "enable" status to disabled, then enabled on destruction.
Definition: dialog_shim.cpp:33
static void recursiveDescent(wxWindowList &children, const bool selectTextInTextCtrls, wxWindow *&firstTextCtrl, wxWindow *&windowWithFocus)
bool m_fixupsRun
Definition: dialog_shim.h:149
int HorizPixelsFromDU(int x)
Convert an integer number of dialog units to pixels, horizontally.
bool Enable(bool enable) override
#define DBG(x)
Definition: fctsys.h:33
Basic classes for most KiCad items.
WDO_ENABLE_DISABLE(wxWindow *aWindow)
Definition: dialog_shim.cpp:39
std::unordered_map< std::string, EDA_RECT > RECT_MAP
Map a C string to an EDA_RECT.
Definition: hashtables.h:136