Code::Blocks  SVN r11506
breakpointsdlg.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: 10677 $
6  * $Id: breakpointsdlg.cpp 10677 2016-01-22 05:38:20Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/src/breakpointsdlg.cpp $
8  */
9 
10 #include "sdk.h"
11 
12 #ifndef CB_PRECOMP
13 # include <algorithm>
14 # include <set>
15 
16 # include "globals.h"
17 # include "manager.h"
18 # include "editormanager.h"
19 # include "cbeditor.h"
20 # include "cbplugin.h"
21 
22 # include <wx/button.h>
23 # include <wx/checkbox.h>
24 # include <wx/intl.h>
25 # include <wx/listbox.h>
26 # include <wx/listctrl.h>
27 # include <wx/menu.h>
28 # include <wx/textctrl.h>
29 # include <wx/spinctrl.h>
30 # include <wx/sizer.h>
31 #endif
32 
33 #include "debuggermanager.h"
34 
35 #include "breakpointsdlg.h"
36 #include "cbstyledtextctrl.h"
37 
38 namespace
39 {
40  const long idList = wxNewId();
41  // menu
42  const long idRemove = wxNewId();
43  const long idRemoveAll = wxNewId();
44  const long idProperties = wxNewId();
45  const long idOpen = wxNewId();
46  const long idEnable = wxNewId();
47  const long idDisable = wxNewId();
48  const long idShowTemp = wxNewId();
49 }
50 
51 BEGIN_EVENT_TABLE(BreakpointsDlg, wxPanel)
52  EVT_MENU(idRemove, BreakpointsDlg::OnRemove)
53  EVT_MENU(idRemoveAll, BreakpointsDlg::OnRemoveAll)
55  EVT_MENU(idOpen, BreakpointsDlg::OnOpen)
56  EVT_MENU(idEnable, BreakpointsDlg::OnEnable)
57  EVT_MENU(idDisable, BreakpointsDlg::OnEnable)
58  EVT_MENU(idShowTemp, BreakpointsDlg::OnShowTemp)
59 
60  EVT_KEY_UP(BreakpointsDlg::OnKeyUp)
61 
62  EVT_UPDATE_UI(idRemove, BreakpointsDlg::OnUpdateUI)
63  EVT_UPDATE_UI(idRemoveAll, BreakpointsDlg::OnUpdateUI)
65  EVT_UPDATE_UI(idOpen, BreakpointsDlg::OnUpdateUI)
66  EVT_UPDATE_UI(idShowTemp, BreakpointsDlg::OnUpdateUI)
67 END_EVENT_TABLE()
68 
70  wxPanel(Manager::Get()->GetAppWindow(), -1),
71  m_icons(16, 16, true)
72 {
73  wxBoxSizer* bs = new wxBoxSizer(wxVERTICAL);
74  m_pList = new wxListCtrl(this, idList, wxDefaultPosition, wxDefaultSize,
76  bs->Add(m_pList, 1, wxEXPAND | wxALL);
77  SetAutoLayout(TRUE);
78  SetSizer(bs);
79 
80  // Setup the image list for the enabled/disabled icons.
81  const wxString &basepath = ConfigManager::GetDataFolder() + wxT("/manager_resources.zip#zip:/images/16x16/");
82  wxBitmap icon = cbLoadBitmap(basepath + wxT("breakpoint.png"), wxBITMAP_TYPE_PNG);
83  if (icon.IsOk())
84  m_icons.Add(icon);
85  icon = cbLoadBitmap(basepath + wxT("breakpoint_disabled.png"), wxBITMAP_TYPE_PNG);
86  if (icon.IsOk())
87  m_icons.Add(icon);
88  icon = cbLoadBitmap(basepath + wxT("breakpoint_other.png"), wxBITMAP_TYPE_PNG);
89  if (icon.IsOk())
90  m_icons.Add(icon);
91  m_pList->SetImageList(&m_icons, wxIMAGE_LIST_SMALL);
92 
93  m_pList->InsertColumn(Type, _("Type"), wxLIST_FORMAT_LEFT, 128);
94  m_pList->InsertColumn(FilenameAddress, _("Filename/Address"), wxLIST_FORMAT_LEFT, 128);
95  m_pList->InsertColumn(Line, _("Line"), wxLIST_FORMAT_LEFT, 44);
96  m_pList->InsertColumn(Info, _("Info"), wxLIST_FORMAT_LEFT, 120);
97  m_pList->InsertColumn(Debugger, _("Debugger"), wxLIST_FORMAT_LEFT, 60);
98 
99  Connect(idList, -1, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
100  (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction)
102 
103  Connect(idList, -1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
104  (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction)
106 
107  Reload();
108 }
109 
111 {
112  m_pList->Freeze();
114  m_breakpoints.clear();
115 
117 
119  for (DebuggerManager::RegisteredPlugins::const_iterator dbg = debuggers.begin(); dbg != debuggers.end(); ++dbg)
120  {
121  int count = dbg->first->GetBreakpointsCount();
122  for (int ii = 0; ii < count; ++ii)
123  {
124  cb::shared_ptr<cbBreakpoint> bp = dbg->first->GetBreakpoint(ii);
125  if (showTemp || (!showTemp && !bp->IsTemporary()))
126  m_breakpoints.push_back(Item(bp, dbg->first, dbg->first->GetGUIName()));
127  }
128  }
129 
131 
132  for (Items::const_iterator it = m_breakpoints.begin(); it != m_breakpoints.end(); ++it)
133  {
135  long item = m_pList->GetItemCount() - 1;
136  int imageId;
137  if (it->plugin != activeDebugger)
138  imageId = 2;
139  else if (it->breakpoint->IsEnabled())
140  imageId = 0;
141  else
142  imageId = 1;
143  m_pList->SetItem(item, Type, it->breakpoint->GetType(), imageId);
144  m_pList->SetItem(item, FilenameAddress, it->breakpoint->GetLocation());
145  m_pList->SetItem(item, Line, it->breakpoint->GetLineString());
146  m_pList->SetItem(item, Info, it->breakpoint->GetInfo());
147  m_pList->SetItem(item, Debugger, it->pluginName);
148  }
149 
150  if (!m_breakpoints.empty())
151  {
152  for (int column = 0; column < m_pList->GetColumnCount(); ++column)
154  }
155  m_pList->Thaw();
156 }
157 
158 BreakpointsDlg::Items::iterator BreakpointsDlg::FindBreakpoint(const wxString &filename, int line)
159 {
160  for (Items::iterator it = m_breakpoints.begin(); it != m_breakpoints.end(); ++it)
161  {
162  if (it->breakpoint->IsVisibleInEditor())
163  {
164  if (it->breakpoint->GetLocation() == filename && it->breakpoint->GetLine() == line)
165  return it;
166  }
167  }
168  return m_breakpoints.end();
169 }
170 
171 bool BreakpointsDlg::AddBreakpoint(cbDebuggerPlugin *plugin, const wxString& filename, int line)
172 {
173  if (plugin && plugin->AddBreakpoint(filename, line))
174  {
175  Reload();
176  return true;
177  }
178  else
179  return false;
180 }
181 
183 {
184  FindBreakpointPred(cbDebuggerPlugin *plugin_in, const wxString &filename_in, int line_in) :
185  plugin(plugin_in),
186  filename(filename_in),
187  line(line_in)
188  {}
189  bool operator()(const BreakpointsDlg::Item &item) const
190  {
191  return plugin == item.plugin
192  && item.breakpoint->IsVisibleInEditor()
193  && item.breakpoint->GetLocation() == filename
194  && item.breakpoint->GetLine() == line;
195  }
196 private:
199  int line;
200 };
201 
202 bool BreakpointsDlg::RemoveBreakpoint(cbDebuggerPlugin *plugin, const wxString& filename, int line)
203 {
204  if (!plugin)
205  return false;
206  Items::iterator it;
207  it = std::find_if(m_breakpoints.begin(), m_breakpoints.end(), FindBreakpointPred(plugin, filename, line));
208  if (it != m_breakpoints.end())
209  {
210  it->plugin->DeleteBreakpoint(it->breakpoint);
211  Reload();
212  return true;
213  }
214  else
215  return false;
216 }
217 
219 {
220  std::set<cbDebuggerPlugin*> plugins;
221  std::set<cbEditor*> editors;
222 
223  for (Items::iterator it = m_breakpoints.begin(); it != m_breakpoints.end(); ++it)
224  {
225  cbBreakpoint& b = *it->breakpoint;
226 
227  if (b.IsVisibleInEditor())
228  {
230  if (ed)
231  {
232  plugins.insert(it->plugin);
233  editors.insert(ed);
234  }
235  }
236  else
237  plugins.insert(it->plugin);
238  }
239  for (std::set<cbDebuggerPlugin*>::iterator it = plugins.begin(); it != plugins.end(); ++it)
240  (*it)->DeleteAllBreakpoints();
241  for (std::set<cbEditor*>::iterator it = editors.begin(); it != editors.end(); ++it)
242  (*it)->RefreshBreakpointMarkers();
243 
244  Reload();
245 
246 }
247 
248 void BreakpointsDlg::EditBreakpoint(const wxString& filename, int line)
249 {
250  Items::iterator it = FindBreakpoint(filename, line);
251  if (it != m_breakpoints.end())
253 }
254 
255 void BreakpointsDlg::EnableBreakpoint(const wxString& filename, int line, bool enable)
256 {
257  Items::iterator it = FindBreakpoint(filename, line);
258  if (it != m_breakpoints.end())
259  {
260  it->plugin->EnableBreakpoint(it->breakpoint, enable);
261  if (it->breakpoint->IsVisibleInEditor())
262  {
263  cbEditor *ed = Manager::Get()->GetEditorManager()->IsBuiltinOpen(it->breakpoint->GetLocation());
264  if (ed)
266  }
267  Reload();
268  }
269 }
270 
272 {
273  long item = -1;
274  bool reload = false;
275  std::set<cbEditor*> editors;
276 
277  while ((item = m_pList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1)
278  {
279  if (item >= 0 || item < static_cast<int>(m_breakpoints.size()))
280  {
281  Item const &data = m_breakpoints[item];
282  if (data.breakpoint->IsVisibleInEditor())
283  {
284  cbEditor *ed = Manager::Get()->GetEditorManager()->IsBuiltinOpen(data.breakpoint->GetLocation());
285  if (ed)
286  editors.insert(ed);
287  }
288 
289  data.plugin->DeleteBreakpoint(data.breakpoint);
290  reload = true;
291  }
292  }
293  if (reload)
294  Reload();
295  for (std::set<cbEditor*>::iterator it = editors.begin(); it != editors.end(); ++it)
296  (*it)->RefreshBreakpointMarkers();
297 }
298 
300 {
302 }
303 
305 {
307  if (sel < 0 || sel >= static_cast<int>(m_breakpoints.size()))
308  return;
310 }
311 
313 {
314  item.plugin->UpdateBreakpoint(item.breakpoint);
315  if (item.breakpoint->IsVisibleInEditor())
316  {
317  cbEditor *ed = Manager::Get()->GetEditorManager()->IsBuiltinOpen(item.breakpoint->GetLocation());
318  if (ed)
320  }
321  Reload();
322 }
323 
325 {
326  long item_index = m_pList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
327  if (item_index < 0 || item_index >= static_cast<int>(m_breakpoints.size()))
328  return;
329 
330  Item const &item = m_breakpoints[item_index];
331 
332  if (item.breakpoint->IsVisibleInEditor())
333  {
334  cbEditor* ed = Manager::Get()->GetEditorManager()->Open(item.breakpoint->GetLocation());
335  if (ed)
336  {
337  ed->GotoLine(item.breakpoint->GetLine() - 1, true);
338  ed->Activate();
339  }
340  }
341 }
342 
344 {
345  long itemIndex = -1;
346  bool hasEnabled = false, hasDisabled = false;
347  bool found = false;
348  while ((itemIndex = m_pList->GetNextItem(itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1)
349  {
350  found = true;
351  bool enabled = m_breakpoints[itemIndex].breakpoint->IsEnabled();
352  if (enabled)
353  hasEnabled = true;
354  else
355  hasDisabled = true;
356  }
357 
358  wxMenu menu;
359  menu.Append(idOpen, _("Open in editor"));
360  menu.Append(idProperties, _("Edit"));
361  menu.AppendSeparator();
362  if (found)
363  {
364  if (hasDisabled)
365  menu.Append(idEnable, _("Enable"));
366  if (hasEnabled)
367  menu.Append(idDisable, _("Disable"));
368  menu.AppendSeparator();
369  }
370  menu.Append(idRemove, _("Remove"));
371  menu.Append(idRemoveAll, _("Remove all"));
372  menu.AppendSeparator();
373  menu.AppendCheckItem(idShowTemp, _("Show temporary"));
374 
375  if (!found)
376  {
377  menu.Enable(idOpen, false);
378  menu.Enable(idProperties, false);
379  menu.Enable(idRemove, false);
380  }
381  if (m_pList->GetItemCount() == 0)
382  menu.Enable(idRemoveAll, false);
383  PopupMenu(&menu);
384 }
385 
387 {
388  wxCommandEvent evt;
389  OnOpen(evt);
390 }
391 
393 {
394  if (event.GetKeyCode() == WXK_DELETE || event.GetKeyCode() == WXK_NUMPAD_DELETE)
395  {
396  wxCommandEvent empty_event;
397  OnRemove(empty_event);
398  }
399 }
400 
402 {
403 // TODO (obfuscated#) add the line text to the breakpoint
405  if(manager->GetActiveDebugger())
406  manager->GetActiveDebugger()->AddBreakpoint(event.GetString(), event.GetInt());
407 
408  Reload();
409 }
410 
412 {
413  const wxString& filename = event.GetString();
414  int line = event.GetInt();
415 
416  for (Items::iterator it = m_breakpoints.begin(); it != m_breakpoints.end(); ++it)
417  {
418  if (it->breakpoint->GetLocation() == filename && it->breakpoint->GetLine() == line)
419  {
420  it->plugin->UpdateBreakpoint(it->breakpoint);
421  if (it->breakpoint->IsVisibleInEditor())
422  {
423  EditorBase *ed = Manager::Get()->GetEditorManager()->GetEditor(filename);
424  if (ed && ed->IsBuiltinEditor())
425  static_cast<cbEditor*>(ed)->RefreshBreakpointMarkers();
426  }
427  break;
428  }
429  }
430  Reload();
431 }
432 
434 {
437  Reload();
438 }
439 
441 {
442  if (event.GetId() == idShowTemp)
444 }
445 
447 {
448  bool enable = (event.GetId() == idEnable);
449  typedef std::pair<cbEditor*, cbDebuggerPlugin*> EditorPair;
450  std::set<EditorPair> editorsToRefresh;
451  long itemIndex = -1;
452  bool reload = false;
453 
454  while ((itemIndex = m_pList->GetNextItem(itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1)
455  {
456  const Item &item = m_breakpoints[itemIndex];
457  if (item.breakpoint->IsEnabled() != enable)
458  {
459  item.plugin->EnableBreakpoint(item.breakpoint, enable);
460  reload = true;
461  if (item.breakpoint->IsVisibleInEditor())
462  {
463  cbEditor *editor = Manager::Get()->GetEditorManager()->IsBuiltinOpen(item.breakpoint->GetLocation());
464  if (editor)
465  editorsToRefresh.insert(EditorPair(editor, item.plugin));
466  }
467  }
468  }
469 
470  for (std::set<EditorPair>::iterator it = editorsToRefresh.begin(); it != editorsToRefresh.end(); ++it)
471  it->first->RefreshBreakpointMarkers();
472 
473  if (reload)
474  Reload();
475 }
void OnBreakpointEdit(CodeBlocksEvent &event)
cbEditor * IsBuiltinOpen(const wxString &filename)
Definition: editormanager.h:92
int GetKeyCode() const
cbDebuggerPlugin * GetActiveDebugger()
int wxNewId()
virtual cb::shared_ptr< cbBreakpoint > AddBreakpoint(const wxString &filename, int line)=0
Request to add a breakpoint.
static bool GetFlag(Flags flag)
Items::iterator FindBreakpoint(const wxString &filename, int line)
Base class for debugger plugins.
Definition: cbplugin.h:397
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 OnRemoveAll(wxCommandEvent &event)
long GetNextItem(long item, int geometry=wxLIST_NEXT_ALL, int state=wxLIST_STATE_DONTCARE) const
void RemoveAllBreakpoints()
cbDebuggerPlugin * plugin
void OnShowTemp(wxCommandEvent &event)
#define wxLC_HRULES
void OnBreakpointAdd(CodeBlocksEvent &event)
DLLIMPORT wxBitmap cbLoadBitmap(const wxString &filename, wxBitmapType bitmapType=wxBITMAP_TYPE_PNG)
This function loads a bitmap from disk.
Definition: globals.cpp:1102
void Enable(int id, bool enable)
void GotoLine(int line, bool centerOnScreen=true) override
Move the caret at the specified line.
Definition: cbeditor.cpp:2223
void OnUpdateUI(wxUpdateUIEvent &event)
void BreakpointProperties(const Item &item)
#define wxLC_REPORT
bool operator()(const BreakpointsDlg::Item &item) const
virtual bool IsOk() const
bool RemoveBreakpoint(cbDebuggerPlugin *plugin, const wxString &filename, int line)
virtual void Activate()
Activate this editor.
Definition: editorbase.cpp:175
wxMenuItem * Append(int id, const wxString &item=wxEmptyString, const wxString &helpString=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
#define wxLIST_STATE_SELECTED
#define _T(string)
void OnEnable(wxCommandEvent &event)
#define wxT(string)
virtual wxString GetLocation() const =0
virtual void UpdateBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint)=0
A generic Code::Blocks event.
Definition: sdk_events.h:20
EditorManager * GetEditorManager() const
Definition: manager.cpp:434
cb::shared_ptr< cbBreakpoint > breakpoint
void Check(bool check)
long InsertItem(wxListItem &info)
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
virtual bool IsVisibleInEditor() const =0
virtual void RefreshBreakpointMarkers()
Refresh all markers for the breakpoints (only the markers for the current debugger will be shown) ...
Definition: cbeditor.cpp:2379
wxSizerItem * Add(wxWindow *window, const wxSizerFlags &flags)
void OnDoubleClick(wxListEvent &event)
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
wxMenuItem * AppendSeparator()
cbDebuggerPlugin * plugin
Base class that all "editors" should inherit from.
Definition: editorbase.h:30
virtual void EnableBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint, bool enable)=0
bool DeleteAllItems()
int GetItemCount() const
void OnOpen(wxCommandEvent &event)
void EnableBreakpoint(const wxString &filename, int line, bool enable)
virtual bool IsBuiltinEditor() const
Is this a built-in editor?
Definition: editorbase.cpp:209
const wxString & filename
cbEditor * Open(const wxString &filename, int pos=0, ProjectFile *data=nullptr)
const wxString & _(const wxString &string)
void OnRightClick(wxListEvent &event)
EditorBase * GetEditor(int index)
std::map< cbDebuggerPlugin *, PluginData > RegisteredPlugins
virtual void DeleteBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint)=0
bool AddBreakpoint(cbDebuggerPlugin *plugin, const wxString &filename, int line)
static wxString GetDataFolder(bool global=true)
wxListCtrl * m_pList
A file editor.
Definition: cbeditor.h:43
friend struct FindBreakpointPred
RegisteredPlugins const & GetAllDebuggers() const
int GetColumnCount() const
void OnRemove(wxCommandEvent &event)
void OnKeyUp(wxKeyEvent &event)
FindBreakpointPred(cbDebuggerPlugin *plugin_in, const wxString &filename_in, int line_in)
bool SetItem(wxListItem &info)
bool SetColumnWidth(int col, int width)
void EditBreakpoint(const wxString &filename, int line)
static void SetFlag(Flags flag, bool value)
const int idProperties
Definition: cbeditor.cpp:535
#define wxLC_VRULES
void OnProperties(wxCommandEvent &event)
wxMenuItem * AppendCheckItem(int id, const wxString &item, const wxString &help=wxEmptyString)