26 #include <wx/aui/aui.h> 34 const int idMenuDebug = XRCID(
"idDebuggerMenuDebug");
35 const int idMenuDebugActive = XRCID(
"idDebuggerMenuActive");
36 const int idMenuDebugActiveTargetsDefault =
wxNewId();
37 const int idMenuRunToCursor = XRCID(
"idDebuggerMenuRunToCursor");
38 const int idMenuSetNextStatement = XRCID(
"idDebuggerMenuSetNextStatement");
39 const int idMenuNext = XRCID(
"idDebuggerMenuNext");
40 const int idMenuStep = XRCID(
"idDebuggerMenuStep");
41 const int idMenuNextInstr = XRCID(
"idDebuggerMenuNextInstr");
42 const int idMenuStepIntoInstr = XRCID(
"idDebuggerMenuStepIntoInstr");
43 const int idMenuStepOut = XRCID(
"idDebuggerMenuStepOut");
44 const int idMenuBreak = XRCID(
"idDebuggerMenuBreak");
45 const int idMenuStop = XRCID(
"idDebuggerMenuStop");
46 const int idToolbarStop = XRCID(
"idDebuggerToolbarStop");
47 const int idMenuToggleBreakpoint = XRCID(
"idDebuggerMenuToggleBreakpoint");
48 const int idMenuRemoveAllBreakpoints = XRCID(
"idDebuggerMenuRemoveAllBreakpoints");
49 const int idMenuAddDataBreakpoint = XRCID(
"idMenuAddDataBreakpoint");
50 const int idMenuSendCommand = XRCID(
"idDebuggerMenuSendCommand");
51 const int idMenuAddSymbolFile = XRCID(
"idDebuggerMenuAddSymbolFile");
52 const int idMenuAttachToProcess = XRCID(
"idDebuggerMenuAttachToProcess");
53 const int idMenuDetach = XRCID(
"idDebuggerMenuDetach");
55 const long idMenuDebuggingWindows = XRCID(
"idDebuggingWindows");
56 const long idMenuTools = XRCID(
"idDebuggerInfo");
58 const int idDebuggerToolInfo = XRCID(
"idDebuggerToolInfo");
59 const int idDebuggerToolWindows = XRCID(
"idDebuggerToolWindows");
61 const int idMenuDebuggerAddWatch =
wxNewId();
70 wxMenu* GetMenuById(
long menuId,
bool recreate =
false)
90 if (pos != wxNOT_FOUND)
95 menu->
Insert(pos, newItem);
146 m_activeDebugger(
nullptr),
147 m_disableContinue(false)
153 template<
typename DlgType>
158 m_enableFeature(enableFeature),
159 m_requestUpdate(requestUpdate),
160 m_getWindowFunc(func)
163 void OnClick(
bool enable)
override 167 DlgType *dialog = (manager->*(m_getWindowFunc))();
170 evt.
pWindow = dialog->GetWindow();
179 return Support(
Manager::Get()->GetDebuggerManager()->GetActiveDebugger(), m_enableFeature);
189 GetWindowFunc m_getWindowFunc;
192 template<
typename DlgType>
197 return new CommonItem<DlgType>(enableFeature, requestUpdate, func);
206 void OnClick(
bool enable)
override 216 bool IsEnabled()
override 220 bool IsChecked()
override 226 struct Watches : CommonItem<cbWatchesDlg>
232 bool IsEnabled()
override 238 RegisterWindowMenu(
_(
"Breakpoints"),
_(
"Edit breakpoints"),
new Breakpoints);
239 RegisterWindowMenu(
_(
"Watches"),
_(
"Watch variables"),
new Watches);
240 RegisterWindowMenu(
_(
"Call stack"),
_(
"Displays the current call stack"),
243 RegisterWindowMenu(
_(
"CPU Registers"),
_(
"Display the CPU registers"),
246 RegisterWindowMenu(
_(
"Disassembly"),
_(
"Disassembles the current stack frame"),
249 RegisterWindowMenu(
_(
"Memory dump"),
_(
"Displays the contents of a memory location"),
252 RegisterWindowMenu(
_(
"Running threads"),
253 _(
"Displays the currently running threads and allows switching between them"),
260 for (WindowMenuItemsMap::iterator it = m_windowMenuItems.begin(); it != m_windowMenuItems.end(); ++it)
262 if (it->second.name == name)
272 i.
item = cb::shared_ptr<cbDebuggerWindowMenuItem>(item);
277 m_windowMenuItems[id] = i;
286 for (WindowMenuItemsMap::iterator it = m_windowMenuItems.begin(); it != m_windowMenuItems.end(); ++it)
288 if (it->second.name == name)
291 Disconnect(it->first, wxEVT_COMMAND_MENU_SELECTED);
293 m_windowMenuItems.erase(it);
301 WindowMenuItemsMap::iterator it = m_windowMenuItems.find(event.GetId());
302 if (it != m_windowMenuItems.end())
304 event.Check(it->second.item->IsChecked());
305 event.Enable(it->second.item->IsEnabled());
311 WindowMenuItemsMap::iterator it = m_windowMenuItems.find(event.GetId());
312 if (it != m_windowMenuItems.end())
313 it->second.item->OnClick(event.IsChecked());
318 std::map<wxString, long> sortedNames;
320 for (WindowMenuItemsMap::iterator it = m_windowMenuItems.begin(); it != m_windowMenuItems.end(); ++it)
321 sortedNames[it->second.name] = it->first;
323 for (std::map<wxString, long>::iterator it = sortedNames.begin(); it != sortedNames.end(); ++it)
324 menu.
AppendCheckItem(it->second, it->first, m_windowMenuItems[it->second].help);
329 m_activeDebugger = active;
334 wxMenu *menu = GetMenuById(idMenuDebugActive);
339 #if wxCHECK_VERSION(3, 0, 0) 340 item->
SetItemLabel(valid ?
_(
"Target's default") :
_(
"Target's default (invalid)"));
342 item->
SetText(valid ?
_(
"Target's default") :
_(
"Target's default (invalid)"));
348 wxMenu *menuWindows = GetMenuById(idMenuDebuggingWindows,
true);
350 AppendWindowMenuItems(*menuWindows);
351 if (m_activeDebugger)
353 wxMenu *menuTools = GetMenuById(idMenuTools,
true);
355 m_activeDebugger->SetupToolsMenu(*menuTools);
359 wxMenu *menu = GetMenuById(idMenuDebugActive,
true);
363 menu->
AppendRadioItem(idMenuDebugActiveTargetsDefault,
_(
"Target's default"),
364 _(
"Use the debugger associated with the compiler for the active target"));
367 for (DebuggerManager::RegisteredPlugins::const_iterator it = allDebugger.begin(); it != allDebugger.end(); ++it)
370 for (DebuggerManager::ConfigurationVector::const_iterator itConf = configs.begin(); itConf != configs.end(); ++itConf)
372 long id = (*itConf)->GetMenuId();
376 (*itConf)->SetMenuId(
id);
379 menu->
AppendRadioItem(
id, it->first->GetGUIName() +
wxT(
": ") + (*itConf)->GetName());
380 Connect(
id, -1, wxEVT_COMMAND_MENU_SELECTED,
381 (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
388 DebuggerManager::RegisteredPlugins::const_iterator it = allDebugger.find(m_activeDebugger);
393 DebuggerManager::ConfigurationVector::const_iterator itConf = configs.begin();
394 std::advance(itConf, m_activeDebugger->GetIndexOfActiveConfig());
396 if (itConf != configs.end())
397 menu->
Check((*itConf)->GetMenuId(),
true);
399 menu->
Check(configs.front()->GetMenuId(),
true);
402 menu->
Check(idMenuDebugActiveTargetsDefault,
true);
421 int item = initialItem;
425 menu.
Insert(item++, idMenuRunToCursor,
_(
"Run to cursor"));
429 menu.
Insert(item++, idMenuSetNextStatement,
_(
"Set next statement"));
432 if (!word_at_caret.
empty())
439 menu.
Insert(item++, idMenuAddDataBreakpoint,
446 menu.
Insert(item++, idMenuToggleBreakpoint,
_(
"Toggle breakpoint"));
457 bool en =
false, stopped =
false, isRunning =
false, isAttached =
false;
459 if (m_activeDebugger)
461 isAttached = m_activeDebugger->IsAttachedToProcess();
463 stopped = m_activeDebugger->IsStopped() && !m_activeDebugger->IsBusy();
464 isRunning = m_activeDebugger->IsRunning();
471 bool otherPlugin =
false;
472 if (runningPlugin !=
NULL && runningPlugin != m_activeDebugger)
478 if (mbar &&
Manager::Get()->GetDebuggerManager()->HasMenu())
482 mbar->
Enable(idMenuDebug, (!isRunning || stopped) && en);
483 mbar->
Enable(idMenuNext, isRunning && en && stopped);
484 mbar->
Enable(idMenuNextInstr, isRunning && en && stopped);
485 mbar->
Enable(idMenuStepIntoInstr, isRunning && en && stopped);
486 mbar->
Enable(idMenuStep, en && stopped);
487 mbar->
Enable(idMenuStepOut, isRunning && en && stopped);
488 mbar->
Enable(idMenuRunToCursor,
490 mbar->
Enable(idMenuSetNextStatement,
492 mbar->
Enable(idMenuToggleBreakpoint, ed && m_activeDebugger && hasBreaks);
493 mbar->
Enable(idMenuRemoveAllBreakpoints, m_activeDebugger && hasBreaks);
494 mbar->
Enable(idMenuSendCommand, isRunning && stopped);
495 mbar->
Enable(idMenuAddSymbolFile, isRunning && stopped);
496 mbar->
Enable(idMenuStop, isRunning && en);
497 mbar->
Enable(idMenuBreak, isRunning && !stopped && en);
498 mbar->
Enable(idMenuAttachToProcess, !isRunning && !otherPlugin && m_activeDebugger);
499 mbar->
Enable(idMenuDetach, isRunning && stopped && isAttached);
501 wxMenu *activeMenu = GetMenuById(idMenuDebugActive);
508 mbar->
Enable(idMenuTools, m_activeDebugger && m_activeDebugger->ToolMenuEnabled());
520 DebuggerManager::RegisteredPlugins::const_iterator it = allDebuggers.find(m_activeDebugger);
522 if (it != allDebuggers.end())
525 configName = it->first->GetGUIName() +
wxT(
":") + config.
GetName();
527 m_activeDebugger->Log(
_(
"Active debugger config: ") + configName);
533 if (!m_activeDebugger->IsRunning())
535 m_disableContinue =
true;
542 m_activeDebugger->ClearLog();
545 if (!m_activeDebugger->Debug(
false))
548 m_disableContinue =
false;
550 else if (m_activeDebugger->IsStopped() && !m_disableContinue)
553 m_activeDebugger->Continue();
561 m_activeDebugger->Break();
568 m_activeDebugger->Stop();
574 if(!m_disableContinue)
577 m_activeDebugger->Continue();
585 m_activeDebugger->Next();
592 m_activeDebugger->NextInstruction();
599 m_activeDebugger->StepIntoInstruction();
605 if (m_activeDebugger->IsRunning())
607 if(!m_disableContinue)
610 m_activeDebugger->Step();
615 m_disableContinue =
true;
620 m_activeDebugger->ClearLog();
623 if (!m_activeDebugger->Debug(
true))
626 m_disableContinue =
false;
634 m_activeDebugger->StepOut();
649 if (!m_activeDebugger->IsRunning())
651 m_activeDebugger->ClearLog();
688 const wxString& word_at_caret = m_activeDebugger->GetEditorWordAtCaret();
689 if (!word_at_caret.
empty())
691 if (m_activeDebugger->AddDataBreakpoint(word_at_caret))
702 m_activeDebugger->AttachToProcess(pidStr);
709 m_activeDebugger->DetachFromProcess();
719 m_activeDebugger->SendCommand(cmd,
false);
725 if (!m_activeDebugger)
728 wxString const &src = m_activeDebugger->GetEditorWordAtCaret();
731 cb::shared_ptr<cbWatch> watch = m_activeDebugger->AddWatch(src);
751 for(DebuggerManager::RegisteredPlugins::const_iterator it = plugins.begin(); it != plugins.end(); ++it)
754 for (DebuggerManager::ConfigurationVector::const_iterator itConf = configs.begin(); itConf != configs.end(); ++itConf)
756 if((*itConf)->GetMenuId() ==
event.GetId())
790 m_menuHandler(menuHandler)
805 m_Toolbar->Realize();
806 m_Toolbar->SetInitialSize();
817 bool stopped =
false, isRunning =
false;
832 if (runningPlugin !=
NULL && runningPlugin != plugin)
835 m_Toolbar->EnableTool(idMenuDebug, (!isRunning || stopped) && en);
836 m_Toolbar->EnableTool(idMenuRunToCursor, en && ed && stopped);
837 m_Toolbar->EnableTool(idMenuNext, isRunning && en && stopped);
838 m_Toolbar->EnableTool(idMenuNextInstr, isRunning && en && stopped);
839 m_Toolbar->EnableTool(idMenuStepIntoInstr, isRunning && en && stopped);
840 m_Toolbar->EnableTool(idMenuStep, en && stopped);
841 m_Toolbar->EnableTool(idMenuStepOut, isRunning && en && stopped);
842 m_Toolbar->EnableTool(idToolbarStop, isRunning && en);
843 m_Toolbar->EnableTool(idMenuBreak, isRunning && !stopped && en);
844 m_Toolbar->EnableTool(idDebuggerToolInfo, plugin && plugin->
ToolMenuEnabled());
866 m_menuHandler->AppendWindowMenuItems(m);
882 m.
Append(idMenuDetach,
_(
"Detach"));
885 wxMenuItem *detach_item = m.
Append(idMenuDetach,
_(
"Detach (debugger is running)"));
886 detach_item->
Enable(
false);
889 m.
Append(idMenuStop,
_(
"Stop debugger (kills the debuggee)"));
896 m_Toolbar->GetEventHandler()->ProcessEvent(event2);
cbDebuggerPlugin * GetActiveDebugger()
void OnWindowMenuItemUpdateUI(wxUpdateUIEvent &event)
void OnRemoveAllBreakpoints(wxCommandEvent &event)
PluginManager * GetPluginManager() const
cbExamineMemoryDlg * GetExamineMemoryDialog()
Returns a pointer to the memory dialog.
EVTIMPORT const wxEventType cbEVT_HIDE_DOCK_WINDOW
void OnDetachFromProcess(wxCommandEvent &event)
void OnActiveDebuggerClick(wxCommandEvent &event)
void SetIsRunning(cbPlugin *plugin)
This method should be called when the applications is started by a plugin.
Base class for debugger plugins.
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
void OnWindowMenuItemClicked(wxCommandEvent &event)
void OnStart(wxCommandEvent &event)
void OnAddWatch(wxCommandEvent &event)
void OnRunToCursor(wxCommandEvent &event)
void OnAddDataBreakpoint(wxCommandEvent &event)
virtual void BuildContextMenu(wxMenu &menu, const wxString &word_at_caret, bool is_running)
void OnBreak(wxCommandEvent &event)
DLLIMPORT wxString cbGetTextFromUser(const wxString &message, const wxString &caption=cbGetTextFromUserPromptStr, const wxString &default_value=wxEmptyString, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord, bool centre=true)
wxWindow * pWindow
The window to dock.
void OnStep(wxCommandEvent &event)
void OnStop(wxCommandEvent &event)
const wxString & GetName() const
Event used to request from the main app to add a window to the docking system.
cbCPURegistersDlg * GetCPURegistersDialog()
Returns a pointer to the CPU registers dialog.
wxString GetLine(int line) const
Retrieve the contents of a line.
void SetTargetsDefaultAsActiveDebugger()
void OnContinue(wxCommandEvent &event)
void OnNextInstr(wxCommandEvent &event)
virtual void RebuildMenus()
ProjectBuildTarget * GetCurrentlyCompilingTarget()
Get a pointer to the currently compiling target.
wxWindow * GetAppWindow() const
void OnToggleBreakpoint(wxCommandEvent &event)
void OnSetNextStatement(wxCommandEvent &event)
EditorManager * GetEditorManager() const
ProjectManager * GetProjectManager() const
Functions returning pointers to the respective sub-manager instances.
PluginManager manages plugins.
DebuggerManager * GetDebuggerManager() const
virtual const wxString & GetFilename() const
Get the editor's filename (if applicable).
virtual void MarkActiveTargetAsValid(bool valid)
Represents a Code::Blocks project.
int GetCurrentLine()
Manually declared methods.
cbStyledTextCtrl * GetControl() const
Returns a pointer to the underlying cbStyledTextCtrl object (which itself is the wxWindows implementa...
cbPlugin * GetIsRunning() const
Return a pointer to the plugin which is running the application.
cbDisassemblyDlg * GetDisassemblyDialog()
Returns a pointer to the disassembly dialog.
bool IsActiveDebuggerTargetsDefault() const
wxFrame * GetAppFrame() const
cbThreadsDlg * GetThreadsDialog()
Returns a pointer to the threads dialog.
cbEditor * GetBuiltinActiveEditor()
void OnNext(wxCommandEvent &event)
cbWatchesDlg * GetWatchesDialog()
Returns a pointer to the watches dialog.
LogManager * GetLogManager() const
DLLIMPORT bool IsWindowReallyShown(wxWindow *win)
Finds out if a window is really shown.
cbProject * GetActiveProject()
Retrieve the active project.
const wxStringCharType * wx_str() const
virtual void AddWatch(cb::shared_ptr< cbWatch > watch)=0
cb::shared_ptr< cbDebuggerWindowMenuItem > item
void RegisterDefaultWindowItems()
const wxString & _(const wxString &string)
void OnSendCommand(wxCommandEvent &event)
std::map< cbDebuggerPlugin *, PluginData > RegisteredPlugins
void AppendWindowMenuItems(wxMenu &menu)
virtual wxWindow * GetWindow()=0
void OnStepOut(wxCommandEvent &event)
void OnActiveDebuggerTargetsDefaultClick(wxCommandEvent &event)
virtual void UnregisterWindowMenu(const wxString &name)
RegisteredPlugins const & GetAllDebuggers() const
The entry point singleton for working with projects.
void OnAttachToProcess(wxCommandEvent &event)
virtual wxWindow * GetWindow()=0
virtual void RemoveAllBreakpoints()=0
cbBacktraceDlg * GetBacktraceDialog()
cbBreakpointsDlg * GetBreakpointDialog()
Returns a pointer to the breakpoints dialog.
EVTIMPORT const wxEventType cbEVT_SHOW_DOCK_WINDOW
void DebugLog(const wxString &msg, Logger::level lv=Logger::info)
bool ProcessEvent(CodeBlocksEvent &event)
virtual bool RegisterWindowMenu(const wxString &name, const wxString &help, cbDebuggerWindowMenuItem *item)
virtual void SetActiveDebugger(cbDebuggerPlugin *active)
virtual bool IsRunning() const =0
Is the plugin currently debugging?
std::vector< cbDebuggerConfiguration * > ConfigurationVector
virtual void ToggleBreakpoint(int line=-1, bool notifyDebugger=true)
Toggle debugger breakpoint at specified line.
void SetActiveDebugger(cbDebuggerPlugin *activeDebugger, ConfigurationVector::const_iterator config)
virtual bool SupportsFeature(cbDebuggerFeature::Flags flag)=0
wxEventType wxEVT_UPDATE_UI
virtual bool IsStopped() const =0
Is the plugin stopped on breakpoint?
static wxString Format(const wxString &format,...)
virtual void RequestUpdate(DebugWindows window)=0
cbDebugInterfaceFactory * GetInterfaceFactory()
virtual bool IsAttachedToProcess() const =0
void OnUpdateUI(wxUpdateUIEvent &event)
void OnStepIntoInstr(wxCommandEvent &event)