Code::Blocks  SVN r11506
backtracedlg.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: 11217 $
6  * $Id: backtracedlg.cpp 11217 2017-10-24 17:43:51Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/src/backtracedlg.cpp $
8  */
9 #include "sdk.h"
10 
11 #ifndef CB_PRECOMP
12  #include <wx/filedlg.h>
13  #include <wx/listctrl.h>
14  #include <wx/menu.h>
15  #include <wx/sizer.h>
16  #include <wx/txtstrm.h>
17  #include <wx/wfstream.h>
18  #include <wx/dataobj.h>
19  #include "cbplugin.h"
20  #include "configmanager.h"
21 #endif
22 
23 #include <wx/clipbrd.h>
24 #include "filefilters.h"
25 
26 #include "backtracedlg.h"
27 #include "cbcolourmanager.h"
28 #include "debuggermanager.h"
29 
30 namespace
31 {
32  const int idList = wxNewId();
33  const int idSwitch = wxNewId();
34  const int idSave = wxNewId();
35  const int idJump = wxNewId();
36  const int idCopyToClipboard = wxNewId();
37  const int idSettingJumpDefault = wxNewId();
38  const int idSettingSwitchDefault = wxNewId();
39 }
40 
41 BEGIN_EVENT_TABLE(BacktraceDlg, wxPanel)
42  EVT_LIST_ITEM_RIGHT_CLICK(idList, BacktraceDlg::OnListRightClick)
43  EVT_LIST_ITEM_ACTIVATED(idList, BacktraceDlg::OnDoubleClick)
44  EVT_MENU(idSwitch, BacktraceDlg::OnSwitchFrame)
45  EVT_MENU(idSave, BacktraceDlg::OnSave)
46  EVT_MENU(idJump, BacktraceDlg::OnJump)
47  EVT_MENU(idCopyToClipboard, BacktraceDlg::OnCopyToClipboard)
48 
49  EVT_MENU(idSettingJumpDefault, BacktraceDlg::OnSettingJumpDefault)
50  EVT_MENU(idSettingSwitchDefault, BacktraceDlg::OnSettingSwitchDefault)
51 
52  EVT_UPDATE_UI(idSwitch, BacktraceDlg::OnUpdateUI)
53 END_EVENT_TABLE()
54 
56  wxPanel(parent)
57 {
58  m_list = new wxListCtrl(this, idList, wxDefaultPosition, wxDefaultSize,
60  wxBoxSizer* bs = new wxBoxSizer(wxVERTICAL);
61  bs->Add(m_list, 1, wxEXPAND | wxALL);
62  SetAutoLayout(true);
63  SetSizer(bs);
64 
65  m_list->InsertColumn(0, _("Nr"), wxLIST_FORMAT_RIGHT);
66  m_list->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT);
67  m_list->InsertColumn(2, _("Function"), wxLIST_FORMAT_LEFT);
68  m_list->InsertColumn(3, _("File"), wxLIST_FORMAT_LEFT, 128);
69  m_list->InsertColumn(4, _("Line"), wxLIST_FORMAT_RIGHT, 64);
70 
71  Manager::Get()->GetColourManager()->RegisterColour(_("Debugger"), _("Backtrace active frame background"),
72  wxT("dbg_backtrace_active_background"), *wxRED);
73  Manager::Get()->GetColourManager()->RegisterColour(_("Debugger"), _("Backtrace active frame foreground"),
74  wxT("dbg_backtrace_active_foreground"), *wxWHITE);
75 }
76 
78 {
80  if (!plugin)
81  return;
82 
84  const wxColour &activeBackground = colours.GetColour(wxT("dbg_backtrace_active_background"));
85  const wxColour &activeForeground = colours.GetColour(wxT("dbg_backtrace_active_foreground"));
86 
87  m_list->Freeze();
89 
90  int active_frame = plugin->GetActiveStackFrame();
91  int active_frame_index = 0;
92  for (int ii = 0; ii < plugin->GetStackFrameCount(); ++ii)
93  {
94  cb::shared_ptr<const cbStackFrame> frame = plugin->GetStackFrame(ii);
95  wxString addr = frame->GetAddressAsString();
96  wxString num;
97  num.Printf(wxT("%d"), frame->GetNumber());
98  int idx = m_list->InsertItem(m_list->GetItemCount(), num);
99  m_list->SetItem(idx, 1, addr);
100  m_list->SetItem(idx, 2, frame->GetSymbol());
101  m_list->SetItem(idx, 3, frame->GetFilename());
102  m_list->SetItem(idx, 4, frame->GetLine());
103 
104  if (active_frame == frame->GetNumber())
105  {
106  active_frame_index = ii;
107  m_list->SetItemBackgroundColour(ii, activeBackground);
108  m_list->SetItemTextColour(ii, activeForeground);
109  }
110  }
111 
112  if (active_frame_index < m_list->GetItemCount())
113  m_list->EnsureVisible(active_frame_index);
114  m_list->Thaw();
115  m_list->SetColumnWidth(0, 32);
116 
117  for (int i = 1; i < 4; ++i)
119 }
120 
121 void BacktraceDlg::EnableWindow(bool enable)
122 {
123  Enable(enable);
124  m_list->Enable(enable);
125 }
126 
127 
129 {
130  wxMenu m;
131  m.Append(idJump, _("Jump to this file/line"));
132  m.Append(idSwitch, _("Switch to this frame"));
133  m.AppendSeparator();
134  m.Append(idSave, _("Save to file..."));
135  m.Append(idCopyToClipboard, _("Copy to clipboard"));
136  m.AppendSeparator();
137  m.AppendRadioItem(idSettingJumpDefault, _("Jump on double-click"));
138  m.AppendRadioItem(idSettingSwitchDefault, _("Switch on double-click"));
139 
141 
142  m.Check(idSettingJumpDefault, jump_on_double_click);
143  m.Check(idSettingSwitchDefault, !jump_on_double_click);
144 
145  m_list->PopupMenu(&m);
146 }
147 
148 void BacktraceDlg::OnJump(cb_unused wxCommandEvent& event)
149 {
150  if (m_list->GetSelectedItemCount() == 0)
151  return;
152 
153  // find selected item index
155 
156  wxListItem info;
157  info.m_itemId = index;
158  info.m_mask = wxLIST_MASK_TEXT;
159  info.m_col = 3;
160  wxString file = m_list->GetItem(info) ? info.m_text : _T("");
161  info.m_col = 4;
162  wxString line = m_list->GetItem(info) ? info.m_text : _T("");
163  if (!file.IsEmpty() && !line.IsEmpty())
164  {
165  long line_number;
166  line.ToLong(&line_number, 10);
167 
168 
170  if(plugin)
171  plugin->SyncEditor(file, line_number, false);
172  }
173 }
174 
176 {
177  if (!IsSwitchFrameEnabled())
178  return;
179 
180  if (m_list->GetSelectedItemCount() == 0)
181  return;
182 
183  // find selected item index
185  // read the frame number from the first column
186  long realFrameNr;
187  if (m_list->GetItemText(index).ToLong(&realFrameNr))
188  {
189  // switch to this frame
191  if (plugin)
192  plugin->SwitchToFrame(realFrameNr);
193  }
194  else
195  cbMessageBox(_("Couldn't find out the frame number!"), _("Error"), wxICON_ERROR);
196 }
197 
199 {
201  wxCommandEvent evt;
202  if (jump || !IsSwitchFrameEnabled())
203  OnJump(evt);
204  else
205  OnSwitchFrame(evt);
206 }
207 
208 void BacktraceDlg::OnSave(cb_unused wxCommandEvent& event)
209 {
210  wxFileDialog dlg(this, _("Save as text file"), wxEmptyString, wxEmptyString,
212  PlaceWindow(&dlg);
213  if (dlg.ShowModal() != wxID_OK)
214  return;
215 
216  wxFFileOutputStream output(dlg.GetPath());
217  wxTextOutputStream text(output);
218 
219  for (int ii = 0; ii < m_list->GetItemCount(); ++ii)
220  {
221  wxListItem info;
222  info.m_itemId = ii;
223  info.m_col = 1;
224  info.m_mask = wxLIST_MASK_TEXT;
225  wxString addr = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
226  info.m_col = 2;
227  wxString func = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
228  info.m_col = 3;
229  wxString file = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
230  info.m_col = 4;
231  wxString line = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
232 
233  text << _T('#') << m_list->GetItemText(ii) << _T(' ')
234  << addr << _T('\t')
235  << func << _T(' ')
236  << _T('(') << file << _T(':') << line << _T(')')
237  << _T('\n');
238  }
239  cbMessageBox(_("File saved"), _("Result"), wxICON_INFORMATION);
240 }
241 
243 {
244  wxString text;
245  for (int ii = 0; ii < m_list->GetItemCount(); ++ii)
246  {
247  wxListItem info;
248  info.m_itemId = ii;
249  info.m_col = 1;
250  info.m_mask = wxLIST_MASK_TEXT;
251  wxString addr = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
252  info.m_col = 2;
253  wxString func = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
254  info.m_col = 3;
255  wxString file = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
256  info.m_col = 4;
257  wxString line = m_list->GetItem(info) && !info.m_text.IsEmpty() ? info.m_text : _T("??");
258 
259  text << _T('#') << m_list->GetItemText(ii) << _T(' ')
260  << addr << _T('\t')
261  << func << _T(' ')
262  << _T('(') << file << _T(':') << line << _T(')')
263  << _T('\n');
264  }
265  wxTextDataObject *object = new wxTextDataObject(text);
266  if(wxTheClipboard->Open())
267  {
268  wxTheClipboard->SetData(object);
269  wxTheClipboard->Close();
270  }
271 }
272 
274 {
275  bool checked = event.IsChecked();
277 }
278 
280 {
281  bool checked = event.IsChecked();
283 }
284 
286 {
287  event.Enable(IsSwitchFrameEnabled());
288 }
289 
291 {
293  return plugin && plugin->IsRunning() && plugin->IsStopped();
294 }
cbDebuggerPlugin * GetActiveDebugger()
virtual int ShowModal()
int wxNewId()
int GetSelectedItemCount() const
static bool GetFlag(Flags flag)
void SetItemBackgroundColour(long item, const wxColour &col)
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
long GetNextItem(long item, int geometry=wxLIST_NEXT_ALL, int state=wxLIST_STATE_DONTCARE) const
#define wxLC_HRULES
#define wxICON_ERROR
void RegisterColour(const wxString &category, const wxString &name, const wxString &id, const wxColour &defaultColour)
#define wxLC_REPORT
virtual int GetStackFrameCount() const =0
wxMenuItem * Append(int id, const wxString &item=wxEmptyString, const wxString &helpString=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
#define wxLIST_STATE_SELECTED
#define _T(string)
#define wxTheClipboard
DLLIMPORT wxString GetFilterAll()
Generates a simple special filter "All files".
Definition: filefilters.cpp:98
SyncEditorResult SyncEditor(const wxString &filename, int line, bool setMarker=true)
Definition: cbplugin.cpp:301
#define wxICON_INFORMATION
#define wxT(string)
bool IsSwitchFrameEnabled() const
#define wxLIST_MASK_TEXT
long InsertItem(wxListItem &info)
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
void Check(int id, bool check)
void OnSave(wxCommandEvent &event)
wxColour GetColour(const wxString &id) const
wxColour * wxRED
wxSizerItem * Add(wxWindow *window, const wxSizerFlags &flags)
void SetItemTextColour(long item, const wxColour &col)
void OnDoubleClick(wxListEvent &event)
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
wxMenuItem * AppendSeparator()
bool DeleteAllItems()
int GetItemCount() const
wxString GetItemText(long item, int col=0) const
wxColour * wxWHITE
wxString wxEmptyString
virtual wxString GetPath() const
#define wxLC_SINGLE_SEL
wxListCtrl * m_list
Definition: backtracedlg.h:44
const wxString & _(const wxString &string)
virtual cb::shared_ptr< const cbStackFrame > GetStackFrame(int index) const =0
void OnJump(wxCommandEvent &event)
bool ToLong(long *val, int base=10) const
ColourManager * GetColourManager() const
Definition: manager.cpp:489
virtual void SwitchToFrame(int number)=0
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
void OnCopyToClipboard(wxCommandEvent &event)
virtual bool IsRunning() const =0
Is the plugin currently debugging?
virtual int GetActiveStackFrame() const =0
void OnSwitchFrame(wxCommandEvent &event)
void EnableWindow(bool enable)
bool SetItem(wxListItem &info)
bool SetColumnWidth(int col, int width)
void OnSettingJumpDefault(wxCommandEvent &event)
wxMenuItem * AppendRadioItem(int id, const wxString &item, const wxString &help=wxEmptyString)
static void SetFlag(Flags flag, bool value)
void OnListRightClick(wxListEvent &event)
virtual bool IsStopped() const =0
Is the plugin stopped on breakpoint?
void OnUpdateUI(wxUpdateUIEvent &event)
int Printf(const wxString &pszFormat,...)
#define wxLC_VRULES
void OnSettingSwitchDefault(wxCommandEvent &event)
bool EnsureVisible(long item)
DLLIMPORT int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
wxMessageBox wrapper.
Definition: globals.cpp:1395
bool GetItem(wxListItem &info) const