Code::Blocks  SVN r11506
watchesdlg.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 11399 $
6  * $Id: watchesdlg.cpp 11399 2018-05-08 21:54:03Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/src/watchesdlg.cpp $
8  */
9 
10 #include "sdk.h"
11 #ifndef CB_PRECOMP
12  #include <wx/app.h>
13  #include <wx/dnd.h>
14  #include <wx/fontutil.h>
15  #include <wx/menu.h>
16  #include <wx/settings.h>
17  #include <wx/sizer.h>
18 
19  #include "cbexception.h"
20  #include "cbplugin.h"
21  #include "logmanager.h"
22  #include "scrollingdialog.h"
23 #endif
24 
25 #include <numeric>
26 #include <map>
27 #include <algorithm>
28 
29 #include <wx/propgrid/propgrid.h>
30 
31 #include "watchesdlg.h"
32 
33 #include "cbcolourmanager.h"
34 #include "debuggermanager.h"
35 
36 namespace
37 {
38  const long idGrid = wxNewId();
39  const long idTooltipGrid = wxNewId();
40  const long idTooltipTimer = wxNewId();
41 
42  const long idMenuRename = wxNewId();
43  const long idMenuProperties = wxNewId();
44  const long idMenuDelete = wxNewId();
45  const long idMenuDeleteAll = wxNewId();
46  const long idMenuAddDataBreak = wxNewId();
47  const long idMenuExamineMemory = wxNewId();
48  const long idMenuAutoUpdate = wxNewId();
49  const long idMenuUpdate = wxNewId();
50 }
51 
52 BEGIN_EVENT_TABLE(WatchesDlg, wxPanel)
53  EVT_PG_ITEM_EXPANDED(idGrid, WatchesDlg::OnExpand)
54  EVT_PG_ITEM_COLLAPSED(idGrid, WatchesDlg::OnCollapse)
55  EVT_PG_SELECTED(idGrid, WatchesDlg::OnPropertySelected)
56  EVT_PG_CHANGED(idGrid, WatchesDlg::OnPropertyChanged)
57  EVT_PG_CHANGING(idGrid, WatchesDlg::OnPropertyChanging)
58  EVT_PG_LABEL_EDIT_BEGIN(idGrid, WatchesDlg::OnPropertyLableEditBegin)
59  EVT_PG_LABEL_EDIT_ENDING(idGrid, WatchesDlg::OnPropertyLableEditEnd)
60  EVT_PG_RIGHT_CLICK(idGrid, WatchesDlg::OnPropertyRightClick)
61  EVT_IDLE(WatchesDlg::OnIdle)
62 
63  EVT_MENU(idMenuRename, WatchesDlg::OnMenuRename)
64  EVT_MENU(idMenuProperties, WatchesDlg::OnMenuProperties)
65  EVT_MENU(idMenuDelete, WatchesDlg::OnMenuDelete)
66  EVT_MENU(idMenuDeleteAll, WatchesDlg::OnMenuDeleteAll)
67  EVT_MENU(idMenuAddDataBreak, WatchesDlg::OnMenuAddDataBreak)
68  EVT_MENU(idMenuExamineMemory, WatchesDlg::OnMenuExamineMemory)
69  EVT_MENU(idMenuAutoUpdate, WatchesDlg::OnMenuAutoUpdate)
70  EVT_MENU(idMenuUpdate, WatchesDlg::OnMenuUpdate)
71 END_EVENT_TABLE()
72 
73 #if wxCHECK_VERSION(3, 0, 0)
75 #endif
76 
78 {
79  WatchItemPredicate(cb::shared_ptr<cbWatch> watch) : m_watch(watch) {}
80 
81  bool operator()(const WatchItem& item) const
82  {
83  return item.watch == m_watch;
84  }
85 private:
86  cb::shared_ptr<cbWatch> m_watch;
87 };
88 
89 class cbDummyEditor : public wxPGEditor
90 {
91  DECLARE_DYNAMIC_CLASS(cbDummyEditor)
92 public:
94  wxPG_CONST_WXCHAR_PTR GetName() const override
95  {
96  return wxT("cbDummyEditor");
97  }
98 
99  wxPGWindowList CreateControls(cb_unused wxPropertyGrid* propgrid,
100  cb_unused wxPGProperty* property,
101  cb_unused const wxPoint& pos,
102  cb_unused const wxSize& sz) const override
103  {
104  wxPGWindowList const list;
105  return list;
106  }
107  void UpdateControl(cb_unused wxPGProperty* property, cb_unused wxWindow* ctrl) const override {}
108  bool OnEvent(cb_unused wxPropertyGrid* propgrid, cb_unused wxPGProperty* property,
109  cb_unused wxWindow* wnd_primary, cb_unused wxEvent& event) const override
110  {
111  return false;
112  }
113 
114  bool GetValueFromControl(cb_unused wxVariant& variant, cb_unused wxPGProperty* property,
115  cb_unused wxWindow* ctrl ) const override
116  {
117  return false;
118  }
119  void SetValueToUnspecified(cb_unused wxPGProperty* property,
120  cb_unused wxWindow* ctrl) const override {}
121 };
122 
124 
125 static wxPGEditor *watchesDummyEditor = nullptr;
126 
127 class cbTextCtrlAndButtonTooltipEditor : public wxPGTextCtrlAndButtonEditor
128 {
129  DECLARE_DYNAMIC_CLASS(cbTextCtrlAndButtonTooltipEditor)
130 public:
131  wxPG_CONST_WXCHAR_PTR GetName() const override
132  {
133  return wxT("cbTextCtrlAndButtonTooltipEditor");
134  }
135 
136  wxPGWindowList CreateControls(wxPropertyGrid* propgrid, wxPGProperty* property,
137  const wxPoint& pos, const wxSize& sz) const override
138  {
139  wxPGWindowList const &list = wxPGTextCtrlAndButtonEditor::CreateControls(propgrid, property, pos, sz);
140 
141  list.m_secondary->SetToolTip(_("Click the button to see the value.\n"
142  "Hold CONTROL to see the raw output string returned by the debugger.\n"
143  "Hold SHIFT to see debugging representation of the cbWatch object."));
144  return list;
145  }
146 
147 };
148 
149 IMPLEMENT_DYNAMIC_CLASS(cbTextCtrlAndButtonTooltipEditor, wxPGTextCtrlAndButtonEditor);
151 
152 class WatchesProperty : public wxStringProperty
153 {
154  DECLARE_DYNAMIC_CLASS(WatchesProperty)
155 
157  public:
158  WatchesProperty(const wxString& label, const wxString& value, cb::shared_ptr<cbWatch> watch, bool readonly) :
159  wxStringProperty(label, wxPG_LABEL, value),
160  m_watch(watch),
161  m_readonly(readonly)
162  {
163  }
164 
165  // Set editor to have button
166  const wxPGEditor* DoGetEditorClass() const override
167  {
168  return m_readonly ? watchesDummyEditor : watchesPropertyEditor;
169  }
170 
171  // Set what happens on button click
172  wxPGEditorDialogAdapter* GetEditorDialog() const override;
173 
174  cb::shared_ptr<cbWatch> GetWatch() { return m_watch; }
175  cb::shared_ptr<const cbWatch> GetWatch() const { return m_watch; }
176  void SetWatch(cb::shared_ptr<cbWatch> watch) { m_watch = watch; }
177 
178  protected:
179  cb::shared_ptr<cbWatch> m_watch;
181 };
182 
183 class WatchRawDialogAdapter : public wxPGEditorDialogAdapter
184 {
185  public:
186 
188  {
189  }
190 
191  bool DoShowDialog(wxPropertyGrid* WXUNUSED(propGrid), wxPGProperty* property) override;
192 
193  protected:
194 };
195 
196 IMPLEMENT_DYNAMIC_CLASS(WatchesProperty, wxStringProperty);
197 
200 {
201  private:
202  enum Type
203  {
206  TypeWatchTree
207  };
208  public:
209  static WatchRawDialog* Create(const WatchesProperty* watch)
210  {
211  cbAssert(watch->GetWatch());
212 
213  WatchRawDialog *dlg;
214  const cbWatch *watchPtr = watch->GetWatch().get();
215  Map::iterator it = s_dialogs.find(watchPtr);
216  if (it != s_dialogs.end())
217  dlg = it->second;
218  else
219  {
220  dlg = new WatchRawDialog;
221  s_dialogs[watchPtr] = dlg;
222  }
223 
224  dlg->m_type = TypeNormal;
225 
226  if (wxGetKeyState(WXK_CONTROL))
227  dlg->m_type = TypeDebug;
228  else if (wxGetKeyState(WXK_SHIFT))
229  dlg->m_type = TypeWatchTree;
230 
231  dlg->SetTitle(wxString::Format(wxT("Watch '%s' raw value"), watch->GetName().c_str()));
232  dlg->SetValue(watch);
233  dlg->Raise();
234 
235  return dlg;
236  }
237 
238  static void UpdateValue(const WatchesProperty* watch)
239  {
240  Map::iterator it = s_dialogs.find(watch->GetWatch().get());
241  if (it != s_dialogs.end())
242  it->second->SetValue(watch);
243  }
244  private:
246  wxScrollingDialog(Manager::Get()->GetAppWindow(),
247  wxID_ANY,
250  wxSize(400, 400),
252  m_type(TypeNormal)
253  {
254  wxBoxSizer *bs = new wxBoxSizer(wxVERTICAL);
257  bs->Add(m_text, 1, wxEXPAND | wxALL, 5);
258  SetAutoLayout(TRUE);
259  SetSizer(bs);
260  }
261 
262  void OnClose(cb_unused wxCloseEvent &event)
263  {
264  for (Map::iterator it = s_dialogs.begin(); it != s_dialogs.end(); ++it)
265  {
266  if (it->second == this)
267  {
268  s_dialogs.erase(it);
269  break;
270  }
271  }
272  Destroy();
273  }
274 
275  void SetValue(const WatchesProperty* watch)
276  {
277  switch (m_type)
278  {
279  case TypeNormal:
280  m_text->SetValue(watch->GetValueAsString(wxPG_FULL_VALUE));
281  break;
282 
283  case TypeDebug:
284  m_text->SetValue(watch->GetWatch()->GetDebugString());
285  break;
286 
287  case TypeWatchTree:
288  {
289  wxString value;
290  WatchToString(value, *watch->GetWatch());
291  m_text->SetValue(value);
292  }
293  break;
294  default:
295  break;
296  }
297  }
298 
299  static void WatchToString(wxString &result, const cbWatch &watch, const wxString &indent = wxEmptyString)
300  {
301  wxString sym, value;
302  watch.GetSymbol(sym);
303  watch.GetValue(value);
304 
305  result += indent + wxT("[symbol = ") + sym + wxT("]\n");
306  result += indent + wxT("[value = ") + value + wxT("]\n");
307  result += indent + wxString::Format(wxT("[children = %d]\n"), watch.GetChildCount());
308 
309  for(int child_index = 0; child_index < watch.GetChildCount(); ++child_index)
310  {
311  cb::shared_ptr<const cbWatch> child = watch.GetChild(child_index);
312 
313  result += indent + wxString::Format(wxT("[child %d]\n"), child_index);
314  WatchToString(result, *child, indent + wxT(" "));
315  }
316  }
317  private:
318  DECLARE_EVENT_TABLE()
319  private:
320  typedef std::map<cbWatch const*, WatchRawDialog*> Map;
321 
322  static Map s_dialogs;
323 
326 };
327 
329 
330 BEGIN_EVENT_TABLE(WatchRawDialog, wxScrollingDialog)
331  EVT_CLOSE(WatchRawDialog::OnClose)
332 END_EVENT_TABLE()
333 
334 
335 bool WatchRawDialogAdapter::DoShowDialog(wxPropertyGrid* WXUNUSED(propGrid), wxPGProperty* property)
336 {
337  WatchesProperty *watch = static_cast<WatchesProperty*>(property);
338  if (watch->GetWatch())
339  {
341  dlg->Show();
342  }
343  return false;
344 }
345 
346 wxPGEditorDialogAdapter* WatchesProperty::GetEditorDialog() const
347 {
348  return new WatchRawDialogAdapter();
349 }
350 
352 {
353 public:
354  bool OnDropText(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxString& text) override
355  {
357  if (!activeDebugger->SupportsFeature(cbDebuggerFeature::Watches))
358  return false;
359  cb::shared_ptr<cbWatch> watch = activeDebugger->AddWatch(text);
360  if (watch.get())
362  // we return false here to veto the operation, otherwise the dragged text might get cut,
363  // because we use wxDrag_DefaultMove in ScintillaWX::StartDrag (seems to happen only on windows)
364  return false;
365  }
366  wxDragResult OnDragOver(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult WXUNUSED(def)) override
367  {
368  return wxDragCopy;
369  }
370 private:
371 };
372 
374  wxPanel(Manager::Get()->GetAppWindow(), -1),
375  m_append_empty_watch(false)
376 {
377  wxBoxSizer *bs = new wxBoxSizer(wxVERTICAL);
379  wxPG_SPLITTER_AUTO_CENTER | wxTAB_TRAVERSAL /*| wxWANTS_CHARS*/);
380 
381 #if wxCHECK_VERSION(3, 0, 0)
382  #define wxPG_EX_DISABLE_TLP_TRACKING 0x00000000
383 #endif
385  m_grid->SetDropTarget(new WatchesDropTarget);
387  m_grid->SetVirtualWidth(0);
388  bs->Add(m_grid, 1, wxEXPAND | wxALL);
389  SetAutoLayout(TRUE);
390  SetSizer(bs);
391 
393  {
394 #if wxCHECK_VERSION(3, 0, 0)
396 #else
398  wxT("cbTextCtrlAndButtonTooltipEditor"),
399  true);
400 #endif
401  }
402 
403  if (!watchesDummyEditor)
404  {
405 #if wxCHECK_VERSION(3, 0, 0)
407 #else
409 #endif
410  }
411 
412  m_grid->SetColumnProportion(0, 40);
413  m_grid->SetColumnProportion(1, 40);
414  m_grid->SetColumnProportion(2, 20);
415 
417  cb::shared_ptr<cbWatch>(), false));
418  m_grid->SetPropertyAttribute(prop, wxT("Units"), wxEmptyString);
419 
420  m_grid->Connect(idGrid, wxEVT_KEY_DOWN, wxKeyEventHandler(WatchesDlg::OnKeyDown), nullptr, this);
421 
423  colours->RegisterColour(_("Debugger"), _("Watches changed value"), wxT("dbg_watches_changed"), *wxRED);
424 }
425 
426 inline void AppendChildren(wxPropertyGrid &grid, wxPGProperty &property, cbWatch &watch,
427  bool readonly, const wxColour &changedColour)
428 {
429  for(int ii = 0; ii < watch.GetChildCount(); ++ii)
430  {
431  cb::shared_ptr<cbWatch> child = watch.GetChild(ii);
432 
433  wxString symbol, value, type;
434  child->GetSymbol(symbol);
435  child->GetValue(value);
436  child->GetType(type);
437 
438  wxPGProperty *prop = new WatchesProperty(symbol, value, child, readonly);
439  prop->SetExpanded(child->IsExpanded());
440  wxPGProperty *new_prop = grid.AppendIn(&property, prop);
441  grid.SetPropertyAttribute(new_prop, wxT("Units"), type);
442  if (value.empty())
443  grid.SetPropertyHelpString(new_prop, wxEmptyString);
444  else
445  grid.SetPropertyHelpString(new_prop, symbol + wxT("=") + value);
446  grid.EnableProperty(new_prop, grid.IsPropertyEnabled(&property));
447 
448  if (child->IsChanged())
449  {
450  grid.SetPropertyTextColour(prop, changedColour);
451  WatchRawDialog::UpdateValue(static_cast<const WatchesProperty*>(prop));
452  }
453  else
454  {
455 #if wxCHECK_VERSION(3, 0, 0)
456  grid.SetPropertyColoursToDefault(prop);
457 #else
458  grid.SetPropertyColourToDefault(prop);
459 #endif
460  }
461 
462  AppendChildren(grid, *prop, *child.get(), readonly, changedColour);
463  }
464 }
465 
466 inline void UpdateWatch(wxPropertyGrid *grid, wxPGProperty *property, cb::shared_ptr<cbWatch> watch, bool readonly)
467 {
468  if (!property)
469  return;
470  const wxColour &changedColour = Manager::Get()->GetColourManager()->GetColour(wxT("dbg_watches_changed"));
471 
472  wxString value, symbol, type;
473  watch->GetSymbol(symbol);
474  watch->GetValue(value);
475  property->SetLabel(symbol);
476  property->SetValue(value);
477  property->SetExpanded(watch->IsExpanded());
478  watch->GetType(type);
479  if (watch->IsChanged())
480  grid->SetPropertyTextColour(property, changedColour);
481  else
482  {
483 #if wxCHECK_VERSION(3, 0, 0)
484  grid->SetPropertyColoursToDefault(property);
485 #else
486  grid->SetPropertyColourToDefault(property);
487 #endif
488  }
489  grid->SetPropertyAttribute(property, wxT("Units"), type);
490  if (value.empty())
491  grid->SetPropertyHelpString(property, wxEmptyString);
492  else
493  {
494  wxString valueTruncated;
495  if (value.length() > 128)
496  valueTruncated = value.Left(128) + wxT("...");
497  else
498  valueTruncated=value;
499  grid->SetPropertyHelpString(property, symbol + wxT("=") + valueTruncated);
500  }
501 
502  property->DeleteChildren();
503 
504  if (property->GetName() != symbol)
505  {
506  grid->SetPropertyName(property, symbol);
507  grid->SetPropertyLabel(property, symbol);
508  }
509 
510  AppendChildren(*grid, *property, *watch, readonly, changedColour);
511 
512  WatchRawDialog::UpdateValue(static_cast<const WatchesProperty*>(property));
513 }
514 
515 inline void SetValue(WatchesProperty *prop)
516 {
517  if (prop)
518  {
519  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
520  if (watch)
521  {
523  if (plugin)
524  plugin->SetWatchValue(watch, prop->GetValue());
525  }
526  }
527 }
528 
530 {
531  for (WatchItems::iterator it = m_watches.begin(); it != m_watches.end(); ++it)
532  UpdateWatch(m_grid, it->property, it->watch, it->readonly);
533  m_grid->Refresh();
534 }
535 
536 void WatchesDlg::AddWatch(cb::shared_ptr<cbWatch> watch)
537 {
539 
540  WatchItem item;
541  wxString symbol, value;
542  watch->GetSymbol(symbol);
543 
544  if (last_prop && last_prop->GetLabel() == wxEmptyString)
545  {
546  item.property = last_prop;
547 
548  // if we are editing the label the calls SetPropertyLabel and SetPropertyName don't work,
549  // so we stop the edit operations
550  if (m_grid->GetLabelEditor())
551  m_grid->EndLabelEdit(0);
552  m_grid->SetPropertyLabel(item.property, symbol);
553  m_grid->SetPropertyName(item.property, symbol);
554 
555  WatchesProperty *watches_prop = static_cast<WatchesProperty*>(last_prop);
556  watches_prop->SetWatch(watch);
557  m_grid->Append(new WatchesProperty(wxEmptyString, wxEmptyString, cb::shared_ptr<cbWatch>(), false));
558  }
559  else
560  {
561  item.property = static_cast<WatchesProperty*>(m_grid->Append(new WatchesProperty(symbol, value, watch, false)));
562  }
563 
564  item.property->SetExpanded(watch->IsExpanded());
565  item.watch = watch;
566  m_watches.push_back(item);
567  m_grid->Refresh();
568 }
569 
570 void WatchesDlg::AddSpecialWatch(cb::shared_ptr<cbWatch> watch, bool readonly)
571 {
572  WatchItems::iterator it = std::find_if(m_watches.begin(), m_watches.end(), WatchItemPredicate(watch));
573  if (it != m_watches.end())
574  return;
575  wxPGProperty *first_prop = m_grid->wxPropertyGridInterface::GetFirst(wxPG_ITERATE_ALL);
576 
577  WatchItem item;
578  wxString symbol, value;
579  watch->GetSymbol(symbol);
580 
581  item.property = static_cast<WatchesProperty*>(m_grid->Insert(first_prop, new WatchesProperty(symbol, value, watch, true)));
582 
583  item.property->SetExpanded(watch->IsExpanded());
584  item.watch = watch;
585  item.readonly = readonly;
586  item.special = true;
587  m_watches.push_back(item);
588  m_grid->Refresh();
589 }
590 
591 void WatchesDlg::RemoveWatch(cb::shared_ptr<cbWatch> watch)
592 {
593  WatchItems::iterator it = std::find_if(m_watches.begin(), m_watches.end(), WatchItemPredicate(watch));
594  if (it != m_watches.end())
595  {
596  DeleteProperty(*it->property);
597  }
598 }
599 
601 {
602  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
603  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
604  watch->Expand(true);
605 
607  if (plugin)
608  plugin->ExpandWatch(watch);
609 }
610 
612 {
613  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
614  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
615  watch->Expand(false);
616 
618  if (plugin)
619  plugin->CollapseWatch(watch);
620 }
621 
623 {
624  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
625  SetValue(prop);
626 }
627 
629 {
630  if (event.GetProperty()->GetChildCount() > 0)
631  event.Veto(true);
632 }
633 
635 {
636  wxPGProperty *prop = event.GetProperty();
637 
638  if (prop)
639  {
640  wxPGProperty *prop_parent = prop->GetParent();
641  if (prop_parent && !prop_parent->IsRoot())
642  event.Veto(true);
643  }
644 }
645 
647 {
648  const wxString& label = m_grid->GetLabelEditor()->GetValue();
649  RenameWatch(event.GetProperty(), label);
650 }
651 
652 void WatchesDlg::OnIdle(cb_unused wxIdleEvent &event)
653 {
655  {
657  cb::shared_ptr<cbWatch>(), false));
658  m_grid->SelectProperty(new_prop, false);
659  m_grid->Refresh();
660  m_append_empty_watch = false;
662  }
663 }
664 
666 {
668  if (plugin && !plugin->SupportsFeature(cbDebuggerFeature::Watches))
669  return;
670 
671  // Newer wx versions seems to send selection events for the unselected property too
672  // and so they set the property to non null value. Thus we have to check for this case.
673  wxPGProperty *property = event.GetProperty();
674  wxPGProperty *selected = m_grid->GetSelection();
675  if (!selected || !property || property != selected)
676  return;
677  if (property->GetLabel() == wxEmptyString)
679 }
680 
682 {
683  cb::shared_ptr<cbWatch> watch = prop.GetWatch();
684  if (!watch)
685  return;
686 
688  if (debugger)
689  debugger->DeleteWatch(watch);
690 
691  wxPGProperty *parent = prop.GetParent();
692  if (parent && parent->IsRoot())
693  {
694  for (WatchItems::iterator it = m_watches.begin(); it != m_watches.end(); ++it)
695  {
696  if (!it->property)
697  continue;
698  if (it->property == &prop)
699  {
700  m_watches.erase(it);
701  break;
702  }
703  }
704  prop.DeleteChildren();
705  m_grid->DeleteProperty(&prop);
706  }
707 }
708 
710 {
711  wxPGProperty *prop = m_grid->GetSelection();
712  WatchesProperty *watches_prop = static_cast<WatchesProperty*>(prop);
713 
714  // don't delete the watch when editing the value or the label
716  return;
717 
718  if (!prop || !prop->GetParent() || !prop->GetParent()->IsRoot())
719  return;
720 
721  switch (event.GetKeyCode())
722  {
723  case WXK_DELETE:
724  {
725  cb::shared_ptr<cbWatch> watch = watches_prop->GetWatch();
726  WatchItems::const_iterator it = std::find_if(m_watches.begin(), m_watches.end(),
727  WatchItemPredicate(watch));
728  if (it != m_watches.end() && !it->special)
729  {
731  if (plugin && plugin->SupportsFeature(cbDebuggerFeature::Watches))
732  {
733  unsigned int index = watches_prop->GetIndexInParent();
734 
735  DeleteProperty(*watches_prop);
736 
737  wxPGProperty *root = m_grid->GetRoot();
738  if (index < root->GetChildCount())
739  m_grid->SelectProperty(root->Item(index), false);
740  else if (root->GetChildCount() > 0)
741  m_grid->SelectProperty(root->Item(root->GetChildCount() - 1), false);
742  }
743  }
744  }
745  break;
746  case WXK_INSERT:
747  {
748  cb::shared_ptr<cbWatch> watch = watches_prop->GetWatch();
749  WatchItems::const_iterator it = std::find_if(m_watches.begin(), m_watches.end(),
750  WatchItemPredicate(watch));
751  if (it != m_watches.end() && !it->special)
752  {
754  if (plugin && plugin->SupportsFeature(cbDebuggerFeature::Watches))
756  }
757  }
758  break;
759  default:
760  break;
761  }
762 }
763 
765 {
766  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
767  if (prop && prop->GetLabel()!=wxEmptyString)
768  {
769  wxMenu m;
770  m.Append(idMenuRename, _("Rename"), _("Rename the watch"));
771  m.Append(idMenuAddDataBreak, _("Add Data breakpoint"), _("Add Data breakpoing"));
772  m.AppendSeparator();
773  m.AppendCheckItem(idMenuAutoUpdate, _("Auto update"),
774  _("Flag which controls if this watch should be auto updated."));
775  m.Append(idMenuUpdate, _("Update"), _("Manually update the selected watch."));
776  m.AppendSeparator();
777  m.Append(idMenuProperties, _("Properties"), _("Show the properties for the watch"));
778  m.Append(idMenuDelete, _("Delete"), _("Delete the currently selected watch"));
779  m.Append(idMenuDeleteAll, _("Delete All"), _("Delete all watches"));
780 
781  if (prop->GetLabel()==wxEmptyString)
782  return;
783  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
784  if (watch)
785  {
788  cb::shared_ptr<cbWatch> rootWatch = cbGetRootWatch(watch);
789  cbDebuggerPlugin *plugin = dbgManager->GetDebuggerHavingWatch(watch);
790 
791  WatchItems::const_iterator itItem = std::find_if(m_watches.begin(), m_watches.end(),
792  WatchItemPredicate(rootWatch));
793  if (itItem != m_watches.end() && itItem->special)
794  {
800  }
801  else
802  {
803 
804  if (plugin && plugin->SupportsFeature(cbDebuggerFeature::Watches))
805  plugin->OnWatchesContextMenu(m, *watch, event.GetProperty(), disabled);
806  else
807  {
811  }
812 
813  if (plugin != dbgManager->GetActiveDebugger())
815  }
816 
818  m.Enable(idMenuRename, false);
820  m.Enable(idMenuProperties, false);
822  m.Enable(idMenuDelete, false);
824  m.Enable(idMenuDeleteAll, false);
826  m.Enable(idMenuAddDataBreak, false);
827 
828  if (rootWatch != watch)
829  {
830  m.Enable(idMenuAutoUpdate, false);
831  m.Enable(idMenuUpdate, false);
832  }
833  else
834  {
835  m.Check(idMenuAutoUpdate, watch->IsAutoUpdateEnabled());
836  if (plugin != dbgManager->GetActiveDebugger())
837  m.Enable(idMenuUpdate, false);
838  }
839 
840  // Add the Examine memory only if the plugin supports the ExamineMemory dialog.
841  if (plugin && plugin->SupportsFeature(cbDebuggerFeature::ExamineMemory) == true)
842  {
843  size_t position;
844  if (m.FindChildItem(idMenuAddDataBreak, &position))
845  position++;
846  else
847  position = 0;
848  m.Insert(position, idMenuExamineMemory, _("Examine memory"),
849  _("Opens the Examine memory window and shows the raw data for this variable"));
851  m.Enable(idMenuExamineMemory, false);
852  }
853  }
854  PopupMenu(&m);
855  }
856  else
857  {
858  wxMenu m;
859  m.Append(idMenuDelete, _("Delete"), _("Delete the currently selected watch"));
860  m.Append(idMenuDeleteAll, _("Delete All"), _("Delete all watches"));
861  PopupMenu(&m);
862  }
863 }
864 
866 {
867  if (!m_grid->GetLabelEditor())
868  {
869  m_grid->SetFocus();
871  }
872 }
873 
875 {
876  wxPGProperty *selected = m_grid->GetSelection();
877  if (selected)
878  {
879  WatchesProperty *prop = static_cast<WatchesProperty*>(selected);
880  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
881  if (watch)
882  {
884  if (debugger)
885  debugger->ShowWatchProperties(watch);
886  }
887  }
888 }
889 
891 {
892  wxPGProperty *selected = m_grid->GetSelection();
893  if (selected)
894  {
895  WatchesProperty *prop = static_cast<WatchesProperty*>(selected);
896  DeleteProperty(*prop);
897  }
898 }
899 
901 {
902  WatchItems specialWatches;
903 
904  for (WatchItems::iterator it = m_watches.begin(); it != m_watches.end(); ++it)
905  {
906  if (it->special)
907  specialWatches.push_back(*it);
908  else
909  {
911  debugger->DeleteWatch(it->watch);
912  m_grid->DeleteProperty(it->property);
913  }
914  }
915 
916  m_watches.swap(specialWatches);
917 }
918 
920 {
921  wxPGProperty *selected = m_grid->GetSelection();
922  if (!selected)
923  return;
924  WatchesProperty *prop = static_cast<WatchesProperty*>(selected);
925 
926  wxString expression;
927  prop->GetWatch()->GetSymbol(expression);
928 
930  if (plugin && !expression.empty())
931  {
932  if (plugin->AddDataBreakpoint(expression))
934  }
935 }
936 
938 {
939  wxPGProperty *selected = m_grid->GetSelection();
940  if (!selected)
941  return;
942  WatchesProperty *prop = static_cast<WatchesProperty*>(selected);
943 
944  wxString expression;
945  cb::shared_ptr<cbWatch> watch = prop->GetWatch();
946  if (watch->IsPointerType())
947  watch->GetSymbol(expression);
948  else
949  expression = watch->MakeSymbolToAddress();
950 
952  if (!dlg)
953  return;
954  if (!IsWindowReallyShown(dlg->GetWindow()))
955  {
957  evt.pWindow = dlg->GetWindow();
958  Manager::Get()->ProcessEvent(evt);
959  }
960 
961  dlg->SetBaseAddress(expression);
962 }
963 
965 {
966  WatchesProperty *selected = static_cast<WatchesProperty*>(m_grid->GetSelection());
967  if (!selected)
968  return;
969  cb::shared_ptr<cbWatch> watch = selected->GetWatch();
970  if (!watch)
971  return;
972  watch->AutoUpdate(!watch->IsAutoUpdateEnabled());
973 }
974 
975 // Must not be called on non-active debuggers!
977 {
978  WatchesProperty *selected = static_cast<WatchesProperty*>(m_grid->GetSelection());
979  if (!selected)
980  return;
981  cb::shared_ptr<cbWatch> watch = selected->GetWatch();
982  if (!watch)
983  return;
984  watch = cbGetRootWatch(watch);
986  if (plugin)
987  plugin->UpdateWatch(watch);
988 }
989 
990 void WatchesDlg::RenameWatch(wxObject *prop, const wxString &newSymbol)
991 {
993  if (!active_plugin)
994  return;
995  WatchesProperty *watchesProp = static_cast<WatchesProperty*>(prop);
996  if (newSymbol == wxEmptyString || !watchesProp)
997  return;
998 
999  // if the user have edited existing watch, we replace it. The new watch is added to the active plugin.
1000  if (watchesProp->GetWatch())
1001  {
1002  cb::shared_ptr<cbWatch> old_watch = watchesProp->GetWatch();
1004  watchesProp->SetWatch(cb::shared_ptr<cbWatch>());
1005  old_plugin->DeleteWatch(old_watch);
1006  cb::shared_ptr<cbWatch> new_watch = active_plugin->AddWatch(newSymbol);
1007  watchesProp->SetWatch(new_watch);
1008 
1009  for (WatchItems::iterator it = m_watches.begin(); it != m_watches.end(); ++it)
1010  {
1011  if (it->property == watchesProp)
1012  it->watch = new_watch;
1013  }
1014  watchesProp->SetExpanded(new_watch->IsExpanded());
1015  ::UpdateWatch(m_grid, watchesProp, new_watch, false);
1016  m_grid->Refresh();
1017  }
1018  else
1019  {
1020  WatchItem item;
1021  item.property = watchesProp;
1022  item.watch = active_plugin->AddWatch(newSymbol);
1023  watchesProp->SetWatch(item.watch);
1024  m_watches.push_back(item);
1025  watchesProp->SetExpanded(item.watch->IsExpanded());
1026 
1027  m_append_empty_watch = true;
1028  }
1029 }
1030 
1032 {
1034  cbDebuggerPlugin *active = manager->GetActiveDebugger();
1035 
1036  for (WatchItems::iterator it = m_watches.begin(); it != m_watches.end(); )
1037  {
1038  cbDebuggerPlugin *plugin = manager->GetDebuggerHavingWatch(it->watch);
1039  if (plugin)
1040  {
1041  bool supports = plugin->SupportsFeature(cbDebuggerFeature::Watches);
1042  WatchesProperty *prop = static_cast<WatchesProperty*>(it->property);
1043 
1044  if (!supports || plugin != active)
1045  m_grid->DisableProperty(prop);
1046  else
1047  m_grid->EnableProperty(prop);
1048  ++it;
1049  }
1050  else
1051  {
1052  m_grid->RemoveProperty(it->property);
1053  it = m_watches.erase(it);
1054  }
1055  }
1056 }
1057 
1061 
1062 #ifndef __WXMAC__
1063 IMPLEMENT_CLASS(ValueTooltip, wxPopupWindow)
1064 BEGIN_EVENT_TABLE(ValueTooltip, wxPopupWindow)
1065 #else
1066 IMPLEMENT_CLASS(ValueTooltip, wxWindow)
1067 BEGIN_EVENT_TABLE(ValueTooltip, wxWindow)
1068 #endif
1069  EVT_PG_ITEM_COLLAPSED(idTooltipGrid, ValueTooltip::OnCollapse)
1070  EVT_PG_ITEM_EXPANDED(idTooltipGrid, ValueTooltip::OnExpand)
1071  EVT_TIMER(idTooltipTimer, ValueTooltip::OnTimer)
1072 END_EVENT_TABLE()
1073 
1075 {
1076  wxPGProperty *property = grid->GetRoot();
1077  return property ? grid->GetFirstChild(property) : nullptr;
1078 }
1079 
1080 inline void GetColumnWidths(wxClientDC &dc, wxPropertyGrid *grid, wxPGProperty *root, int width[3])
1081 {
1082 #if wxCHECK_VERSION(3, 0, 0)
1083  wxPropertyGridPageState *state = grid->GetState();
1084 #else
1085  wxPropertyGridState *state = grid->GetState();
1086 #endif
1087 
1088  width[0] = width[1] = width[2] = 0;
1089  int minWidths[3] = { state->GetColumnMinWidth(0),
1090  state->GetColumnMinWidth(1),
1091  state->GetColumnMinWidth(2) };
1092 
1093  for (unsigned ii = 0; ii < root->GetChildCount(); ++ii)
1094  {
1095  wxPGProperty* p = root->Item(ii);
1096 
1097  width[0] = std::max(width[0], state->GetColumnFullWidth(dc, p, 0));
1098  width[1] = std::max(width[1], state->GetColumnFullWidth(dc, p, 1));
1099  width[2] = std::max(width[2], state->GetColumnFullWidth(dc, p, 2));
1100  }
1101  for (unsigned ii = 0; ii < root->GetChildCount(); ++ii)
1102  {
1103  wxPGProperty* p = root->Item(ii);
1104  if (p->IsExpanded())
1105  {
1106  int w[3];
1107  GetColumnWidths(dc, grid, p, w);
1108  width[0] = std::max(width[0], w[0]);
1109  width[1] = std::max(width[1], w[1]);
1110  width[2] = std::max(width[2], w[2]);
1111  }
1112  }
1113 
1114  width[0] = std::max(width[0], minWidths[0]);
1115  width[1] = std::max(width[1], minWidths[1]);
1116  width[2] = std::max(width[2], minWidths[2]);
1117 }
1118 
1119 inline void GetColumnWidths(wxPropertyGrid *grid, wxPGProperty *root, int width[3])
1120 {
1121  wxClientDC dc(grid);
1122  dc.SetFont(grid->GetFont());
1123  GetColumnWidths(dc, grid, root, width);
1124 }
1125 
1126 inline void SetMinSize(wxPropertyGrid *grid)
1127 {
1128  wxPGProperty *p = GetRealRoot(grid);
1129  wxPGProperty *first = grid->wxPropertyGridInterface::GetFirst(wxPG_ITERATE_ALL);
1131  wxRect rect = grid->GetPropertyRect(first, last);
1132  int height = rect.height + 2 * grid->GetVerticalSpacing();
1133 
1134  // add some height when the root item is collapsed,
1135  // this is needed to prevent the vertical scroll from showing
1136  if (!grid->IsPropertyExpanded(p))
1137  height += 2 * grid->GetVerticalSpacing();
1138 
1139  int width[3];
1140  GetColumnWidths(grid, grid->GetRoot(), width);
1141  rect.width = std::accumulate(width, width+3, 0);
1142 
1143  int minWidth = (wxSystemSettings::GetMetric(wxSYS_SCREEN_X, grid->GetParent())*3)/2;
1144  int minHeight = (wxSystemSettings::GetMetric(wxSYS_SCREEN_Y, grid->GetParent())*3)/2;
1145 
1146 #if wxCHECK_VERSION(3, 0, 0)
1147  wxSize size(std::min(minWidth, rect.width), std::min(minHeight, height));
1148 #else
1149  wxSize size(std::min(minWidth, rect.width + grid->GetMarginWidth()), std::min(minHeight, height));
1150 #endif
1151  grid->SetMinSize(size);
1152 
1153  int proportions[3];
1154  proportions[0] = static_cast<int>(floor((double)width[0]/size.x*100.0+0.5));
1155  proportions[1] = static_cast<int>(floor((double)width[1]/size.x*100.0+0.5));
1156  proportions[2]= std::max(100 - proportions[0] - proportions[1], 0);
1157  grid->SetColumnProportion(0, proportions[0]);
1158  grid->SetColumnProportion(1, proportions[1]);
1159  grid->SetColumnProportion(2, proportions[2]);
1160  grid->ResetColumnSizes(true);
1161 }
1162 
1163 ValueTooltip::ValueTooltip(const cb::shared_ptr<cbWatch> &watch, wxWindow *parent) :
1164 #ifndef __WXMAC__
1166 #else
1167  wxWindow(parent, -1),
1168 #endif
1169  m_timer(this, idTooltipTimer),
1170  m_outsideCount(0),
1171  m_watch(watch)
1172 {
1173  m_panel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(200, 200));
1175 
1176  m_grid->SetExtraStyle(wxPG_EX_DISABLE_TLP_TRACKING /*| wxPG_EX_HELP_AS_TOOLTIPS*/);
1177  m_grid->SetDropTarget(new WatchesDropTarget);
1178 
1179  wxNativeFontInfo fontInfo;
1181  wxFont font(fontInfo);
1182  m_grid->SetFont(font);
1183 
1184  m_grid->SetColumnCount(3);
1185 
1186  wxString symbol, value;
1187  m_watch->GetSymbol(symbol);
1188  m_watch->GetValue(value);
1189  wxPGProperty *root = m_grid->Append(new WatchesProperty(symbol, value, m_watch, true));
1190  m_watch->MarkAsChangedRecursive(false);
1191  ::UpdateWatch(m_grid, root, m_watch, true);
1192 
1194 
1195  m_sizer = new wxBoxSizer( wxVERTICAL );
1196  m_sizer->Add(m_grid, 0, wxALL | wxEXPAND, 0);
1197 
1198  m_panel->SetAutoLayout(true);
1199  m_panel->SetSizer(m_sizer);
1200  m_sizer->Fit(m_panel);
1201  m_sizer->Fit(this);
1202 
1203  m_timer.Start(100);
1204 }
1205 
1207 {
1208  ClearWatch();
1209 }
1210 
1212 {
1213  m_watch->MarkAsChangedRecursive(false);
1215  m_grid->Refresh();
1216  Fit();
1217 }
1218 
1220 {
1221  if (m_watch)
1222  {
1224  if (plugin)
1225  plugin->DeleteWatch(m_watch);
1226  m_watch.reset();
1227  }
1228 }
1229 
1231 {
1232  Hide();
1233  m_timer.Stop();
1234  ClearWatch();
1235 }
1236 
1238 {
1239  ClearWatch();
1240 }
1241 
1243 {
1245  m_sizer->Fit(m_panel);
1246  wxPoint pos = GetScreenPosition();
1247  wxSize size = m_panel->GetScreenRect().GetSize();
1248  SetSize(pos.x, pos.y, size.x, size.y);
1249 }
1250 
1252 {
1253  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
1254  prop->GetWatch()->Expand(false);
1255 
1257  if (plugin)
1258  plugin->CollapseWatch(prop->GetWatch());
1259  Fit();
1260 }
1261 
1263 {
1264  WatchesProperty *prop = static_cast<WatchesProperty*>(event.GetProperty());
1265  prop->GetWatch()->Expand(true);
1266 
1268  if (plugin)
1269  plugin->ExpandWatch(prop->GetWatch());
1270  Fit();
1271 }
1272 
1273 void ValueTooltip::OnTimer(cb_unused wxTimerEvent &event)
1274 {
1275  if (!wxTheApp->IsActive())
1276  Dismiss();
1277 
1278  wxPoint mouse = wxGetMousePosition();
1279  wxRect rect = GetScreenRect();
1280  rect.Inflate(5);
1281 
1282  if (!rect.Contains(mouse))
1283  {
1284  if (++m_outsideCount > 5)
1285  Dismiss();
1286  }
1287  else
1288  m_outsideCount = 0;
1289 }
void SetPropertyColoursToDefault(wxPGPropArg id)
wxSize Fit(wxWindow *window)
wxPoint wxGetMousePosition()
wxApp * wxTheApp
int GetKeyCode() const
cbDebuggerPlugin * GetActiveDebugger()
void UpdateControl(cb_unused wxPGProperty *property, cb_unused wxWindow *ctrl) const override
Definition: watchesdlg.cpp:107
wxPG_CONST_WXCHAR_PTR GetName() const override
Definition: watchesdlg.cpp:94
void OnMenuAddDataBreak(wxCommandEvent &event)
Definition: watchesdlg.cpp:919
int wxNewId()
wxPGProperty * Insert(wxPGPropArg priorThis, wxPGProperty *newProperty)
void BeginLabelEdit(unsigned int colIndex=0)
wxPGProperty * GetRealRoot(wxPropertyGrid *grid)
cbExamineMemoryDlg * GetExamineMemoryDialog()
Returns a pointer to the memory dialog.
void OnCollapse(wxPropertyGridEvent &event)
bool IsPropertyExpanded(wxPGPropArg id) const
#define wxTE_READONLY
bool FromString(const wxString &s)
cb::shared_ptr< cbWatch > m_watch
Definition: watchesdlg.h:110
void AddSpecialWatch(cb::shared_ptr< cbWatch > watch, bool readonly)
Definition: watchesdlg.cpp:570
WatchesProperty * property
Definition: watchesdlg.h:65
Base class for debugger plugins.
Definition: cbplugin.h:397
wxPGProperty * GetLastItem(int flags=wxPG_ITERATE_DEFAULT)
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
void OnPropertyRightClick(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:764
wxPGProperty * Item(unsigned int i) const
void OnMenuExamineMemory(cb_unused wxCommandEvent &event)
Definition: watchesdlg.cpp:937
wxPGEditorDialogAdapter * GetEditorDialog() const override
Definition: watchesdlg.cpp:346
bool OnDropText(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxString &text) override
Definition: watchesdlg.cpp:354
virtual void ShowWatchProperties(cb::shared_ptr< cbWatch > watch)=0
void OnExpand(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:600
wxPGProperty * Append(wxPGProperty *property)
void SetColumnCount(int colCount)
#define wxTE_MULTILINE
size_t length() const
void SetPropertyHelpString(wxPGPropArg id, const wxString &helpString)
void GetColumnWidths(wxClientDC &dc, wxPropertyGrid *grid, wxPGProperty *root, int width[3])
bool OnEvent(cb_unused wxPropertyGrid *propgrid, cb_unused wxPGProperty *property, cb_unused wxWindow *wnd_primary, cb_unused wxEvent &event) const override
Definition: watchesdlg.cpp:108
void OnMenuDelete(wxCommandEvent &event)
Definition: watchesdlg.cpp:890
void RegisterColour(const wxString &category, const wxString &name, const wxString &id, const wxColour &defaultColour)
bool IsPropertyEnabled(wxPGPropArg id) const
void Enable(int id, bool enable)
int m_outsideCount
Definition: watchesdlg.h:108
wxWindow * pWindow
The window to dock.
Definition: sdk_events.h:137
bool DisableProperty(wxPGPropArg id)
static wxPGEditor * watchesDummyEditor
Definition: watchesdlg.cpp:125
virtual void Reload()=0
bool IsEditorFocused() const
WatchesProperty(const wxString &label, const wxString &value, cb::shared_ptr< cbWatch > watch, bool readonly)
Definition: watchesdlg.cpp:158
void OnTimer(wxTimerEvent &event)
void SetPropertyTextColour(wxPGPropArg id, const wxColour &colour, int flags=wxPG_RECURSE)
virtual void DeleteWatch(cb::shared_ptr< cbWatch > watch)=0
Event used to request from the main app to add a window to the docking system.
Definition: sdk_events.h:83
virtual void ExpandWatch(cb::shared_ptr< cbWatch > watch)=0
std::map< cbWatch const *, WatchRawDialog * > Map
Definition: watchesdlg.cpp:320
wxMenuItem * Append(int id, const wxString &item=wxEmptyString, const wxString &helpString=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
wxPG_CONST_WXCHAR_PTR GetName() const override
Definition: watchesdlg.cpp:131
wxDragResult OnDragOver(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult WXUNUSED(def)) override
Definition: watchesdlg.cpp:366
void SetPropertyAttribute(wxPGPropArg id, const wxString &attrName, wxVariant value, long argFlags=0)
void DeleteProperty(WatchesProperty &prop)
Definition: watchesdlg.cpp:681
cb::shared_ptr< const cbWatch > GetWatch() const
Definition: watchesdlg.cpp:175
virtual void OnDismiss()
void SetValue(WatchesProperty *prop)
Definition: watchesdlg.cpp:515
void OnIdle(wxIdleEvent &event)
Definition: watchesdlg.cpp:652
const wxPGEditor * DoGetEditorClass() const override
Definition: watchesdlg.cpp:166
bool SetColumnProportion(unsigned int column, int proportion)
void OnMenuDeleteAll(wxCommandEvent &event)
Definition: watchesdlg.cpp:900
void OnMenuUpdate(wxCommandEvent &event)
Definition: watchesdlg.cpp:976
wxScrolled< wxPanel > wxScrolledWindow
cb::shared_ptr< cbWatch > GetChild(int index)
void OnMenuAutoUpdate(wxCommandEvent &event)
Definition: watchesdlg.cpp:964
wxPropertyGrid * m_grid
Definition: watchesdlg.h:103
#define wxT(string)
cbDebuggerPlugin * GetDebuggerHavingWatch(cb::shared_ptr< cbWatch > watch)
virtual bool Start(int milliseconds=-1, bool oneShot=wxTIMER_CONTINUOUS)
bool empty() const
void ResetColumnSizes(bool enableAutoResizing=false)
static int GetMetric(wxSystemMetric index, wxWindow *win=NULL)
void UpdateWatch(wxPropertyGrid *grid, wxPGProperty *property, cb::shared_ptr< cbWatch > watch, bool readonly)
Definition: watchesdlg.cpp:466
void OnMenuProperties(wxCommandEvent &event)
Definition: watchesdlg.cpp:874
void SetPropertyLabel(wxPGPropArg id, const wxString &newproplabel)
virtual cb::shared_ptr< cbBreakpoint > AddDataBreakpoint(const wxString &dataExpression)=0
Request to add a breakpoint based on a data expression.
#define wxWANTS_CHARS
wxTextCtrl * m_text
Definition: watchesdlg.cpp:324
virtual void GetSymbol(wxString &symbol) const =0
virtual wxWindow * GetWindow()=0
cb::shared_ptr< cbWatch > m_watch
Definition: watchesdlg.cpp:86
void OnExpand(wxPropertyGridEvent &event)
bool Contains(int x, int y) const
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
virtual void Stop()
wxPGProperty * GetProperty() const
void SetWatch(cb::shared_ptr< cbWatch > watch)
Definition: watchesdlg.cpp:176
void Check(int id, bool check)
void OnPropertyChanged(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:622
void ClearWatch()
bool GetValueFromControl(cb_unused wxVariant &variant, cb_unused wxPGProperty *property, cb_unused wxWindow *ctrl) const override
Definition: watchesdlg.cpp:114
wxColour GetColour(const wxString &id) const
int GetChildCount() const
virtual bool SetWatchValue(cb::shared_ptr< cbWatch > watch, const wxString &value)=0
wxString Left(size_t count) const
wxPGWindowList CreateControls(wxPropertyGrid *propgrid, wxPGProperty *property, const wxPoint &pos, const wxSize &sz) const override
Definition: watchesdlg.cpp:136
wxColour * wxRED
#define wxTAB_TRAVERSAL
wxSizerItem * Add(wxWindow *window, const wxSizerFlags &flags)
static void WatchToString(wxString &result, const cbWatch &watch, const wxString &indent=wxEmptyString)
Definition: watchesdlg.cpp:299
virtual void CollapseWatch(cb::shared_ptr< cbWatch > watch)=0
void RenameWatch(wxObject *prop, const wxString &newSymbol)
Definition: watchesdlg.cpp:990
cb::shared_ptr< cbWatch > GetWatch()
Definition: watchesdlg.cpp:174
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
IMPLEMENT_DYNAMIC_CLASS(cbDummyEditor, wxPGEditor)
wxMenuItem * AppendSeparator()
cbWatchesDlg * GetWatchesDialog()
Returns a pointer to the watches dialog.
DLLIMPORT bool IsWindowReallyShown(wxWindow *win)
Finds out if a window is really shown.
Definition: globals.cpp:931
bool EnableProperty(wxPGPropArg id, bool enable=true)
WatchItemPredicate(cb::shared_ptr< cbWatch > watch)
Definition: watchesdlg.cpp:79
bool SelectProperty(wxPGPropArg id, bool focus=false)
wxPGProperty * GetParent() const
void SetPropertyName(wxPGPropArg id, const wxString &newName)
static wxPGEditor * watchesPropertyEditor
Definition: watchesdlg.cpp:150
#define wxDEFAULT_DIALOG_STYLE
void OnCollapse(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:611
wxDragResult
wxString wxEmptyString
wxPGProperty * GetSelection() const
void EndLabelEdit(bool commit=true)
virtual void AddWatch(cb::shared_ptr< cbWatch > watch)=0
wxString WatchToString(cbWatch const &watch)
wxPropertyGrid * m_grid
Definition: watchesdlg.h:73
unsigned int GetChildCount() const
void OnClose(cb_unused wxCloseEvent &event)
Definition: watchesdlg.cpp:262
int width
const wxString & _(const wxString &string)
wxEventType wxEVT_KEY_DOWN
bool m_append_empty_watch
Definition: watchesdlg.h:75
ValueTooltip(const cb::shared_ptr< cbWatch > &watch, wxWindow *parent)
#define cbAssert(expr)
Definition: cbexception.h:48
void Veto(bool veto=true)
wxPGProperty * AppendIn(wxPGPropArg id, wxPGProperty *newProperty)
#define wxPG_EX_DISABLE_TLP_TRACKING
static void UpdateValue(const WatchesProperty *watch)
Definition: watchesdlg.cpp:238
void SetMinSize(wxPropertyGrid *grid)
std::vector< WatchItem > WatchItems
Definition: watchesdlg.h:69
void RefreshUI()
void AppendChildren(wxPropertyGrid &grid, wxPGProperty &property, cbWatch &watch, bool readonly, const wxColour &changedColour)
Definition: watchesdlg.cpp:426
wxPanel * m_panel
Definition: watchesdlg.h:105
virtual void SetBaseAddress(const wxString &addr)=0
ColourManager * GetColourManager() const
Definition: manager.cpp:489
cb::shared_ptr< cbWatch > watch
Definition: watchesdlg.h:64
wxString GetName() const
static Map s_dialogs
Definition: watchesdlg.cpp:322
static WatchRawDialog * Create(const WatchesProperty *watch)
Definition: watchesdlg.cpp:209
wxString wxPG_CONST_WXCHAR_PTR
Definition: watchesdlg.cpp:74
static wxString GetValueTooltipFont()
void OnKeyDown(wxKeyEvent &event)
Definition: watchesdlg.cpp:709
virtual void GetValue(wxString &value) const =0
virtual cb::shared_ptr< cbWatch > AddWatch(const wxString &symbol)=0
virtual void UpdateWatch(cb::shared_ptr< cbWatch > watch)=0
cbBreakpointsDlg * GetBreakpointDialog()
Returns a pointer to the breakpoints dialog.
EVTIMPORT const wxEventType cbEVT_SHOW_DOCK_WINDOW
Definition: sdk_events.cpp:131
void AddWatch(cb::shared_ptr< cbWatch > watch)
Definition: watchesdlg.cpp:536
static wxPGEditor * RegisterEditorClass(wxPGEditor *editor, bool noDefCheck=false)
bool IsExpanded() const
bool IsRoot() const
bool ProcessEvent(CodeBlocksEvent &event)
Definition: manager.cpp:246
void OnMenuRename(wxCommandEvent &event)
Definition: watchesdlg.cpp:865
void UpdateWatch()
wxRect & Inflate(wxCoord dx, wxCoord dy)
virtual void OnWatchesContextMenu(wxMenu &menu, const cbWatch &watch, wxObject *property, int &disabledMenus)
Definition: cbplugin.h:541
cb::shared_ptr< cbWatch > DLLIMPORT cbGetRootWatch(cb::shared_ptr< cbWatch > watch)
void SetValueToUnspecified(cb_unused wxPGProperty *property, cb_unused wxWindow *ctrl) const override
Definition: watchesdlg.cpp:119
wxMenuItem * FindChildItem(int id, size_t *pos=NULL) const
int height
wxPGProperty * GetRoot() const
bool operator()(const WatchItem &item) const
Definition: watchesdlg.cpp:81
void OnPropertySelected(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:665
int wxCoord
virtual bool SupportsFeature(cbDebuggerFeature::Flags flag)=0
void DeleteProperty(wxPGPropArg id)
#define wxRESIZE_BORDER
int GetVerticalSpacing() const
WatchItems m_watches
Definition: watchesdlg.h:74
virtual bool IsActive() const
void OnPropertyLableEditEnd(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:646
wxBoxSizer * m_sizer
Definition: watchesdlg.h:104
void UpdateWatches()
Definition: watchesdlg.cpp:529
bool wxGetKeyState(wxKeyCode key)
wxTextCtrl * GetLabelEditor() const
static wxString Format(const wxString &format,...)
void SetValue(const WatchesProperty *watch)
Definition: watchesdlg.cpp:275
wxPGWindowList CreateControls(cb_unused wxPropertyGrid *propgrid, cb_unused wxPGProperty *property, cb_unused const wxPoint &pos, cb_unused const wxSize &sz) const override
Definition: watchesdlg.cpp:99
void RemoveWatch(cb::shared_ptr< cbWatch > watch)
Definition: watchesdlg.cpp:591
wxMenuItem * Insert(size_t pos, wxMenuItem *menuItem)
wxPGProperty * RemoveProperty(wxPGPropArg id)
void OnPropertyChanging(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:628
void OnPropertyLableEditBegin(wxPropertyGridEvent &event)
Definition: watchesdlg.cpp:634
wxTimer m_timer
Definition: watchesdlg.h:107
cb::shared_ptr< cbWatch > m_watch
Definition: watchesdlg.cpp:179
dialog to show the value of a watch
Definition: watchesdlg.cpp:199
wxMenuItem * AppendCheckItem(int id, const wxString &item, const wxString &help=wxEmptyString)