From 10b962261a1316c97dc6ca4c1e68e2109472d2d7 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 27 Jun 2015 21:48:44 -0400 Subject: [PATCH] Debugger: Layout changes to team settings window. TeamSettingsWindow: - Split out functionality into separate views for images and exceptions, which in turn are held in dedicated tabs. --- src/apps/debugger/Jamfile | 2 + .../ExceptionStopConfigView.cpp | 176 ++++++++ .../ExceptionStopConfigView.h | 52 +++ .../ImageStopConfigView.cpp | 337 ++++++++++++++ .../ImageStopConfigView.h | 70 +++ .../TeamSettingsWindow.cpp | 410 +----------------- .../team_settings_window/TeamSettingsWindow.h | 50 +-- 7 files changed, 652 insertions(+), 445 deletions(-) create mode 100644 src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.cpp create mode 100644 src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.h create mode 100644 src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.cpp create mode 100644 src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index ae3adc5187..800de9feee 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -290,6 +290,8 @@ Application Debugger : VariablesView.cpp # user_interface/gui/team_settings_window + ExceptionStopConfigView.cpp + ImageStopConfigView.cpp TeamSettingsWindow.cpp # user_interface/gui/util diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.cpp b/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.cpp new file mode 100644 index 0000000000..15d286d9c7 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.cpp @@ -0,0 +1,176 @@ +/* + * Copyright 2013-2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "ExceptionStopConfigView.h" + +#include +#include + +#include +#include + +#include "FunctionInstance.h" +#include "Image.h" +#include "ImageDebugInfo.h" +#include "MessageCodes.h" +#include "UserInterface.h" +#include "Team.h" + + +enum { + MSG_STOP_ON_THROWN_EXCEPTION_CHANGED = 'stec', + MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED = 'scec', +}; + + +ExceptionStopConfigView::ExceptionStopConfigView(::Team* team, + UserInterfaceListener* listener) + : + BGroupView(B_VERTICAL), + fTeam(team), + fListener(listener), + fExceptionThrown(NULL), + fExceptionCaught(NULL) +{ + SetName("Exceptions"); +} + + +ExceptionStopConfigView::~ExceptionStopConfigView() +{ +} + + +ExceptionStopConfigView* +ExceptionStopConfigView::Create(::Team* team, UserInterfaceListener* listener) +{ + ExceptionStopConfigView* self = new ExceptionStopConfigView( + team, listener); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; + +} + + +void +ExceptionStopConfigView::AttachedToWindow() +{ + fExceptionThrown->SetTarget(this); + fExceptionCaught->SetTarget(this); + + AutoLocker< ::Team> teamLocker(fTeam); + _UpdateExceptionState(); + + BGroupView::AttachedToWindow(); +} + + +void +ExceptionStopConfigView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_STOP_ON_THROWN_EXCEPTION_CHANGED: + { + _UpdateThrownBreakpoints(fExceptionThrown->Value() + == B_CONTROL_ON); + break; + } + case MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED: + { + break; + } + default: + BGroupView::MessageReceived(message); + break; + } + +} + + +void +ExceptionStopConfigView::_Init() +{ + BLayoutBuilder::Group<>(this, B_VERTICAL) + .SetInsets(B_USE_DEFAULT_SPACING) + .AddGlue() + .Add(fExceptionThrown = new BCheckBox("exceptionThrown", + "Stop when an exception is thrown", + new BMessage(MSG_STOP_ON_THROWN_EXCEPTION_CHANGED))) + .Add(fExceptionCaught = new BCheckBox("exceptionCaught", + "Stop when an exception is caught", + new BMessage(MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED))) + .AddGlue(); + + // TODO: enable once implemented + fExceptionCaught->SetEnabled(false); +} + + +void +ExceptionStopConfigView::_UpdateThrownBreakpoints(bool enable) +{ + AutoLocker< ::Team> teamLocker(fTeam); + for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); + it.HasNext();) { + Image* image = it.Next(); + + ImageDebugInfo* info = image->GetImageDebugInfo(); + target_addr_t address; + if (_FindExceptionFunction(info, address) != B_OK) + continue; + + if (enable) + fListener->SetBreakpointRequested(address, true, true); + else + fListener->ClearBreakpointRequested(address); + } +} + + +status_t +ExceptionStopConfigView::_FindExceptionFunction(ImageDebugInfo* info, + target_addr_t& _foundAddress) const +{ + if (info != NULL) { + FunctionInstance* instance = info->FunctionByName( + "__cxa_allocate_exception"); + if (instance == NULL) + instance = info->FunctionByName("__throw(void)"); + + if (instance != NULL) { + _foundAddress = instance->Address(); + return B_OK; + } + } + + return B_NAME_NOT_FOUND; +} + + +void +ExceptionStopConfigView::_UpdateExceptionState() +{ + // check if the exception breakpoints are already installed + for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); + it.HasNext();) { + Image* image = it.Next(); + + ImageDebugInfo* info = image->GetImageDebugInfo(); + target_addr_t address; + if (_FindExceptionFunction(info, address) != B_OK) + continue; + + if (fTeam->BreakpointAtAddress(address) != NULL) { + fExceptionThrown->SetValue(B_CONTROL_ON); + break; + } + } +} diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.h b/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.h new file mode 100644 index 0000000000..11a7835130 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_settings_window/ExceptionStopConfigView.h @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef EXCEPTION_STOP_CONFIG_VIEW_H +#define EXCEPTION_STOP_CONFIG_VIEW_H + + +#include + +#include "types/Types.h" + + +class BBox; +class BButton; +class BCheckBox; +class ImageDebugInfo; +class Team; +class UserInterfaceListener; + + +class ExceptionStopConfigView : public BGroupView { +public: + ExceptionStopConfigView(::Team* team, + UserInterfaceListener* listener); + + ~ExceptionStopConfigView(); + + static ExceptionStopConfigView* Create(::Team* team, + UserInterfaceListener* listener); + // throws + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + +private: + void _Init(); + void _UpdateThrownBreakpoints(bool enable); + status_t _FindExceptionFunction(ImageDebugInfo* info, + target_addr_t& _foundAddress) const; + + void _UpdateExceptionState(); + +private: + ::Team* fTeam; + UserInterfaceListener* fListener; + BCheckBox* fExceptionThrown; + BCheckBox* fExceptionCaught; +}; + + +#endif // EXCEPTION_STOP_CONFIG_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.cpp b/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.cpp new file mode 100644 index 0000000000..d5f554b6e1 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.cpp @@ -0,0 +1,337 @@ +/* + * Copyright 2013-2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "ImageStopConfigView.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "FunctionInstance.h" +#include "Image.h" +#include "ImageDebugInfo.h" +#include "MessageCodes.h" +#include "UserInterface.h" + + +enum { + MSG_SET_STOP_FOR_ALL_IMAGES = 'sfai', + MSG_SET_STOP_FOR_CUSTOM_IMAGES = 'sfci', + MSG_IMAGE_NAME_SELECTION_CHANGED = 'insc', + MSG_ADD_IMAGE_NAME = 'anin', + MSG_REMOVE_IMAGE_NAME = 'arin', + MSG_IMAGE_NAME_INPUT_CHANGED = 'inic' +}; + + +static int SortStringItems(const void* a, const void* b) +{ + BStringItem* item1 = *(BStringItem**)a; + BStringItem* item2 = *(BStringItem**)b; + + return strcmp(item1->Text(), item2->Text()); +} + + +ImageStopConfigView::ImageStopConfigView(::Team* team, + UserInterfaceListener* listener) + : + BGroupView(B_VERTICAL), + fTeam(team), + fListener(listener), + fStopOnImageLoad(NULL), + fStopImageConstraints(NULL), + fStopImageNames(NULL), + fStopImageNameInput(NULL), + fAddImageNameButton(NULL), + fRemoveImageNameButton(NULL), + fCustomImageGroup(NULL), + fStopOnLoadEnabled(false), + fUseCustomImages(false) +{ + SetName("Images"); + fTeam->AddListener(this); +} + + +ImageStopConfigView::~ImageStopConfigView() +{ + fTeam->RemoveListener(this); +} + + +ImageStopConfigView* +ImageStopConfigView::Create(::Team* team, UserInterfaceListener* listener) +{ + ImageStopConfigView* self = new ImageStopConfigView(team, listener); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; +} + + +void +ImageStopConfigView::AttachedToWindow() +{ + fAddImageNameButton->SetEnabled(false); + fRemoveImageNameButton->SetEnabled(false); + + fStopImageConstraints->Menu()->SetTargetForItems(this); + fStopOnImageLoad->SetTarget(this); + fAddImageNameButton->SetTarget(this); + fRemoveImageNameButton->SetTarget(this); + fStopImageNames->SetTarget(this); + fStopImageNameInput->SetTarget(this); + + AutoLocker< ::Team> teamLocker(fTeam); + _UpdateStopImageState(); + + BGroupView::AttachedToWindow(); +} + + +void +ImageStopConfigView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_SET_STOP_FOR_ALL_IMAGES: + { + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + false); + break; + } + + case MSG_SET_STOP_FOR_CUSTOM_IMAGES: + { + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + true); + break; + } + + case MSG_IMAGE_NAME_SELECTION_CHANGED: + { + if (!fUseCustomImages) + break; + + fRemoveImageNameButton->SetEnabled( + fStopImageNames->CurrentSelection() >= 0); + break; + } + + case MSG_IMAGE_NAME_INPUT_CHANGED: + { + BString imageName(fStopImageNameInput->Text()); + imageName.Trim(); + fAddImageNameButton->SetEnabled(!imageName.IsEmpty()); + break; + } + + case MSG_STOP_ON_IMAGE_LOAD: + { + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + fUseCustomImages); + break; + } + + case MSG_STOP_IMAGE_SETTINGS_CHANGED: + { + _UpdateStopImageState(); + break; + } + + case MSG_ADD_IMAGE_NAME: + { + BString imageName(fStopImageNameInput->Text()); + imageName.Trim(); + AutoLocker< ::Team> teamLocker(fTeam); + if (fTeam->StopImageNames().HasString(imageName)) + break; + + fStopImageNameInput->SetText(""); + fListener->AddStopImageNameRequested(imageName.String()); + break; + } + + case MSG_STOP_IMAGE_NAME_ADDED: + { + const char* imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + BStringItem* item = new(std::nothrow) BStringItem(imageName); + if (item == NULL) + break; + + ObjectDeleter itemDeleter(item); + if (!fStopImageNames->AddItem(item)) { + break; + } + itemDeleter.Detach(); + fStopImageNames->SortItems(SortStringItems); + break; + } + + case MSG_REMOVE_IMAGE_NAME: + { + BStringItem* item; + int32 selectedIndex; + AutoLocker< ::Team> teamLocker(fTeam); + int32 i = 0; + while ((selectedIndex = fStopImageNames->CurrentSelection(i++)) + >= 0) { + item = (BStringItem*)fStopImageNames->ItemAt(selectedIndex); + fListener->RemoveStopImageNameRequested(item->Text()); + } + break; + } + + case MSG_STOP_IMAGE_NAME_REMOVED: + { + const char* imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + for (int32 i = 0; i < fStopImageNames->CountItems(); i++) { + BStringItem* item = (BStringItem*)fStopImageNames->ItemAt(i); + if (strcmp(item->Text(), imageName) == 0) { + fStopImageNames->RemoveItem(i); + delete item; + } + } + break; + } + + + default: + BGroupView::MessageReceived(message); + break; + } + +} + + +void +ImageStopConfigView::StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_SETTINGS_CHANGED); + message.AddBool("enabled", event.StopOnImageLoad()); + message.AddBool("useNameList", event.StopImageNameListEnabled()); + BMessenger(this).SendMessage(&message); +} + + +void +ImageStopConfigView::StopOnImageLoadNameAdded( + const Team::ImageLoadNameEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_NAME_ADDED); + message.AddString("name", event.ImageName()); + BMessenger(this).SendMessage(&message); +} + + +void +ImageStopConfigView::StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_NAME_REMOVED); + message.AddString("name", event.ImageName()); + BMessenger(this).SendMessage(&message); +} + + +void +ImageStopConfigView::_Init() +{ + BMenu* stopImageMenu = new BMenu("stopImageTypesMenu"); + + stopImageMenu->AddItem(new BMenuItem("All", + new BMessage(MSG_SET_STOP_FOR_ALL_IMAGES))); + stopImageMenu->AddItem(new BMenuItem("Custom", + new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES))); + + fStopImageNames = new BListView("customImageList", + B_MULTIPLE_SELECTION_LIST); + fStopImageNames->SetSelectionMessage( + new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED)); + + fCustomImageGroup = new BGroupView(); + BLayoutBuilder::Group<>(fCustomImageGroup, B_VERTICAL, 0.0) + .Add(new BScrollView("stopImageScroll", fStopImageNames, + 0, false, true)) + .Add(fStopImageNameInput = new BTextControl("stopImageName", + "Image:", NULL, NULL)) + .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_SMALL_SPACING) + .AddGlue() + .Add(fAddImageNameButton = new BButton("Add", + new BMessage(MSG_ADD_IMAGE_NAME))) + .Add(fRemoveImageNameButton = new BButton("Remove", + new BMessage(MSG_REMOVE_IMAGE_NAME))) + .End(); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .SetInsets(B_USE_SMALL_SPACING) + .Add(fStopOnImageLoad = new BCheckBox("stopOnImage", + "Stop when an image is loaded", + new BMessage(MSG_STOP_ON_IMAGE_LOAD))) + .Add(fStopImageConstraints = new BMenuField( + "stopTypes", "Types:", stopImageMenu)) + .Add(fCustomImageGroup); + + font_height fontHeight; + be_plain_font->GetHeight(&fontHeight); + float minListHeight = 5 * (fontHeight.ascent + fontHeight.descent + + fontHeight.leading); + fStopImageNames->SetExplicitMinSize(BSize(B_SIZE_UNSET, minListHeight)); + + stopImageMenu->SetLabelFromMarked(true); + fStopImageNameInput->SetModificationMessage( + new BMessage(MSG_IMAGE_NAME_INPUT_CHANGED)); +} + + +void +ImageStopConfigView::_UpdateStopImageState() +{ + fStopOnLoadEnabled = fTeam->StopOnImageLoad(); + fStopOnImageLoad->SetValue( + fStopOnLoadEnabled ? B_CONTROL_ON : B_CONTROL_OFF); + fUseCustomImages = fTeam->StopImageNameListEnabled(); + fStopImageConstraints->Menu() + ->ItemAt(fUseCustomImages ? 1 : 0)->SetMarked(true); + + fStopImageNames->MakeEmpty(); + const BStringList& imageNames = fTeam->StopImageNames(); + for (int32 i = 0; i < imageNames.CountStrings(); i++) { + BStringItem* item = new(std::nothrow) BStringItem( + imageNames.StringAt(i)); + if (item == NULL) + return; + item->SetEnabled(fUseCustomImages); + ObjectDeleter itemDeleter(item); + if (!fStopImageNames->AddItem(item)) + return; + itemDeleter.Detach(); + } + + fStopImageConstraints->SetEnabled(fStopOnLoadEnabled); + fStopImageNameInput->SetEnabled(fUseCustomImages); +} diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.h b/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.h new file mode 100644 index 0000000000..6e0596ccec --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_settings_window/ImageStopConfigView.h @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef IMAGE_STOP_CONFIG_VIEW_H +#define IMAGE_STOP_CONFIG_VIEW_H + + +#include + +#include "Team.h" + +#include "types/Types.h" + + +class BBox; +class BButton; +class BCheckBox; +class BListView; +class BMenuField; +class BTextControl; +class ImageDebugInfo; +class UserInterfaceListener; + + +class ImageStopConfigView : public BGroupView, private Team::Listener { +public: + ImageStopConfigView(::Team* team, + UserInterfaceListener* listener); + + ~ImageStopConfigView(); + + static ImageStopConfigView* Create(::Team* team, + UserInterfaceListener* listener); + // throws + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + + // Team::Listener + virtual void StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event); + virtual void StopOnImageLoadNameAdded( + const Team::ImageLoadNameEvent& event); + virtual void StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event); + + +private: + void _Init(); + + void _UpdateStopImageState(); + // must be called with team lock held + +private: + ::Team* fTeam; + UserInterfaceListener* fListener; + BCheckBox* fStopOnImageLoad; + BMenuField* fStopImageConstraints; + BListView* fStopImageNames; + BTextControl* fStopImageNameInput; + BButton* fAddImageNameButton; + BButton* fRemoveImageNameButton; + BView* fCustomImageGroup; + bool fStopOnLoadEnabled; + bool fUseCustomImages; +}; + + +#endif // IMAGE_STOP_CONFIG_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.cpp b/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.cpp index d616b4e3cb..5152b2430e 100644 --- a/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.cpp @@ -4,44 +4,13 @@ */ #include "TeamSettingsWindow.h" -#include #include -#include #include -#include -#include -#include +#include -#include -#include - -#include "FunctionInstance.h" -#include "Image.h" -#include "ImageDebugInfo.h" +#include "ExceptionStopConfigView.h" +#include "ImageStopConfigView.h" #include "MessageCodes.h" -#include "UserInterface.h" -#include "Team.h" - - -enum { - MSG_STOP_ON_THROWN_EXCEPTION_CHANGED = 'stec', - MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED = 'scec', - MSG_SET_STOP_FOR_ALL_IMAGES = 'sfai', - MSG_SET_STOP_FOR_CUSTOM_IMAGES = 'sfci', - MSG_IMAGE_NAME_SELECTION_CHANGED = 'insc', - MSG_ADD_IMAGE_NAME = 'anin', - MSG_REMOVE_IMAGE_NAME = 'arin', - MSG_IMAGE_NAME_INPUT_CHANGED = 'inic' -}; - - -static int SortStringItems(const void* a, const void* b) -{ - BStringItem* item1 = *(BStringItem**)a; - BStringItem* item2 = *(BStringItem**)b; - - return strcmp(item1->Text(), item2->Text()); -} TeamSettingsWindow::TeamSettingsWindow(::Team* team, @@ -51,29 +20,14 @@ TeamSettingsWindow::TeamSettingsWindow(::Team* team, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fTeam(team), fListener(listener), - fExceptionSettingsBox(NULL), - fImageSettingsBox(NULL), - fExceptionThrown(NULL), - fExceptionCaught(NULL), - fStopOnImageLoad(NULL), - fStopImageConstraints(NULL), - fStopImageNames(NULL), - fStopImageNameInput(NULL), - fAddImageNameButton(NULL), - fRemoveImageNameButton(NULL), - fCustomImageGroup(NULL), - fStopOnLoadEnabled(false), - fUseCustomImages(false), fCloseButton(NULL), fTarget(target) { - fTeam->AddListener(this); } TeamSettingsWindow::~TeamSettingsWindow() { - fTeam->RemoveListener(this); BMessenger(fTarget).SendMessage(MSG_TEAM_SETTINGS_WINDOW_CLOSED); } @@ -93,141 +47,6 @@ TeamSettingsWindow::Create(::Team* team, } return self; - -} - -void -TeamSettingsWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - case MSG_STOP_ON_THROWN_EXCEPTION_CHANGED: - { - _UpdateThrownBreakpoints(fExceptionThrown->Value() - == B_CONTROL_ON); - break; - } - - case MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED: - { - break; - } - - case MSG_SET_STOP_FOR_ALL_IMAGES: - { - fListener->SetStopOnImageLoadRequested( - fStopOnImageLoad->Value() == B_CONTROL_ON, - false); - break; - } - - case MSG_SET_STOP_FOR_CUSTOM_IMAGES: - { - fListener->SetStopOnImageLoadRequested( - fStopOnImageLoad->Value() == B_CONTROL_ON, - true); - break; - } - - case MSG_IMAGE_NAME_SELECTION_CHANGED: - { - if (!fUseCustomImages) - break; - - fRemoveImageNameButton->SetEnabled( - fStopImageNames->CurrentSelection() >= 0); - break; - } - - case MSG_IMAGE_NAME_INPUT_CHANGED: - { - BString imageName(fStopImageNameInput->Text()); - imageName.Trim(); - fAddImageNameButton->SetEnabled(!imageName.IsEmpty()); - break; - } - - case MSG_STOP_ON_IMAGE_LOAD: - { - fListener->SetStopOnImageLoadRequested( - fStopOnImageLoad->Value() == B_CONTROL_ON, - fUseCustomImages); - break; - } - - case MSG_STOP_IMAGE_SETTINGS_CHANGED: - { - _UpdateStopImageState(); - break; - } - - case MSG_ADD_IMAGE_NAME: - { - BString imageName(fStopImageNameInput->Text()); - imageName.Trim(); - AutoLocker< ::Team> teamLocker(fTeam); - if (fTeam->StopImageNames().HasString(imageName)) - break; - - fStopImageNameInput->SetText(""); - fListener->AddStopImageNameRequested(imageName.String()); - break; - } - - case MSG_STOP_IMAGE_NAME_ADDED: - { - const char* imageName; - if (message->FindString("name", &imageName) != B_OK) - break; - - BStringItem* item = new(std::nothrow) BStringItem(imageName); - if (item == NULL) - break; - - ObjectDeleter itemDeleter(item); - if (!fStopImageNames->AddItem(item)) { - break; - } - itemDeleter.Detach(); - fStopImageNames->SortItems(SortStringItems); - break; - } - - case MSG_REMOVE_IMAGE_NAME: - { - BStringItem* item; - int32 selectedIndex; - AutoLocker< ::Team> teamLocker(fTeam); - int32 i = 0; - while ((selectedIndex = fStopImageNames->CurrentSelection(i++)) - >= 0) { - item = (BStringItem*)fStopImageNames->ItemAt(selectedIndex); - fListener->RemoveStopImageNameRequested(item->Text()); - } - break; - } - - case MSG_STOP_IMAGE_NAME_REMOVED: - { - const char* imageName; - if (message->FindString("name", &imageName) != B_OK) - break; - - for (int32 i = 0; i < fStopImageNames->CountItems(); i++) { - BStringItem* item = (BStringItem*)fStopImageNames->ItemAt(i); - if (strcmp(item->Text(), imageName) == 0) { - fStopImageNames->RemoveItem(i); - delete item; - } - } - break; - } - - - default: - BWindow::MessageReceived(message); - break; - } - } @@ -239,232 +58,25 @@ TeamSettingsWindow::Show() } -void -TeamSettingsWindow::StopOnImageLoadSettingsChanged( - const Team::ImageLoadEvent& event) -{ - BMessage message(MSG_STOP_IMAGE_SETTINGS_CHANGED); - message.AddBool("enabled", event.StopOnImageLoad()); - message.AddBool("useNameList", event.StopImageNameListEnabled()); - PostMessage(&message); -} - - -void -TeamSettingsWindow::StopOnImageLoadNameAdded( - const Team::ImageLoadNameEvent& event) -{ - BMessage message(MSG_STOP_IMAGE_NAME_ADDED); - message.AddString("name", event.ImageName()); - PostMessage(&message); -} - - -void -TeamSettingsWindow::StopOnImageLoadNameRemoved( - const Team::ImageLoadNameEvent& event) -{ - BMessage message(MSG_STOP_IMAGE_NAME_REMOVED); - message.AddString("name", event.ImageName()); - PostMessage(&message); -} - - void TeamSettingsWindow::_Init() { - fExceptionSettingsBox = new BBox("exceptionBox"); - fExceptionSettingsBox->SetLabel("Exceptions"); - fExceptionSettingsBox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .Add(fExceptionThrown = new BCheckBox("exceptionThrown", - "Stop when an exception is thrown", - new BMessage(MSG_STOP_ON_THROWN_EXCEPTION_CHANGED))) - .Add(fExceptionCaught = new BCheckBox("exceptionCaught", - "Stop when an exception is caught", - new BMessage(MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED))) - .View()); - - fExceptionThrown->SetTarget(this); - fExceptionCaught->SetTarget(this); - - // TODO: enable once implemented - fExceptionCaught->SetEnabled(false); - - - fImageSettingsBox = new BBox("imageBox"); - fImageSettingsBox->SetLabel("Images"); - BMenu* stopImageMenu = new BMenu("stopImageTypesMenu"); - - stopImageMenu->AddItem(new BMenuItem("All", - new BMessage(MSG_SET_STOP_FOR_ALL_IMAGES))); - stopImageMenu->AddItem(new BMenuItem("Custom", - new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES))); - - fStopImageNames = new BListView("customImageList", - B_MULTIPLE_SELECTION_LIST); - fStopImageNames->SetSelectionMessage( - new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED)); - - fCustomImageGroup = new BGroupView(); - BLayoutBuilder::Group<>(fCustomImageGroup, B_VERTICAL, 0.0) - .Add(new BScrollView("stopImageScroll", fStopImageNames, - 0, false, true)) - .Add(fStopImageNameInput = new BTextControl("stopImageName", - "Image:", NULL, NULL)) - .AddGroup(B_HORIZONTAL) - .AddGlue() - .Add(fAddImageNameButton = new BButton("Add", - new BMessage(MSG_ADD_IMAGE_NAME))) - .Add(fRemoveImageNameButton = new BButton("Remove", - new BMessage(MSG_REMOVE_IMAGE_NAME))) - .End(); - - fImageSettingsBox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .Add(fStopOnImageLoad = new BCheckBox("stopOnImage", - "Stop when an image is loaded", - new BMessage(MSG_STOP_ON_IMAGE_LOAD))) - .Add(fStopImageConstraints = new BMenuField( - "stopTypes", "Types:", stopImageMenu)) - .Add(fCustomImageGroup) - .View()); - - font_height fontHeight; - be_plain_font->GetHeight(&fontHeight); - float minListHeight = 5 * (fontHeight.ascent + fontHeight.descent - + fontHeight.leading); - fStopImageNames->SetExplicitMinSize(BSize(B_SIZE_UNSET, minListHeight)); - + BTabView* tabView = new BTabView("config tab view"); BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_DEFAULT_SPACING) - .Add(fExceptionSettingsBox) - .Add(fImageSettingsBox) + .Add(tabView) .AddGroup(B_HORIZONTAL) .AddGlue() .Add(fCloseButton = new BButton("Close", new BMessage( B_QUIT_REQUESTED))) .End(); + ImageStopConfigView* imageView = ImageStopConfigView::Create(fTeam, + fListener); + tabView->AddTab(imageView); + ExceptionStopConfigView* exceptionView = ExceptionStopConfigView::Create( + fTeam, fListener); + tabView->AddTab(exceptionView); fCloseButton->SetTarget(this); - fAddImageNameButton->SetEnabled(false); - fRemoveImageNameButton->SetEnabled(false); - stopImageMenu->SetTargetForItems(this); - stopImageMenu->SetLabelFromMarked(true); - fStopImageNameInput->SetModificationMessage( - new BMessage(MSG_IMAGE_NAME_INPUT_CHANGED)); - - fCustomImageGroup->Hide(); - - AutoLocker< ::Team> teamLocker(fTeam); - _UpdateStopImageState(); - _UpdateExceptionState(); - -} - - -void -TeamSettingsWindow::_UpdateThrownBreakpoints(bool enable) -{ - AutoLocker< ::Team> teamLocker(fTeam); - for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); - it.HasNext();) { - Image* image = it.Next(); - - ImageDebugInfo* info = image->GetImageDebugInfo(); - target_addr_t address; - if (_FindExceptionFunction(info, address) != B_OK) - continue; - - if (enable) - fListener->SetBreakpointRequested(address, true, true); - else - fListener->ClearBreakpointRequested(address); - } -} - - -status_t -TeamSettingsWindow::_FindExceptionFunction(ImageDebugInfo* info, - target_addr_t& _foundAddress) const -{ - if (info != NULL) { - FunctionInstance* instance = info->FunctionByName( - "__cxa_allocate_exception"); - if (instance == NULL) - instance = info->FunctionByName("__throw(void)"); - - if (instance != NULL) { - _foundAddress = instance->Address(); - return B_OK; - } - } - - return B_NAME_NOT_FOUND; -} - - -void -TeamSettingsWindow::_UpdateExceptionState() -{ - // check if the exception breakpoints are already installed - for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); - it.HasNext();) { - Image* image = it.Next(); - - ImageDebugInfo* info = image->GetImageDebugInfo(); - target_addr_t address; - if (_FindExceptionFunction(info, address) != B_OK) - continue; - - if (fTeam->BreakpointAtAddress(address) != NULL) { - fExceptionThrown->SetValue(B_CONTROL_ON); - break; - } - } -} - - -void -TeamSettingsWindow::_UpdateStopImageState() -{ - bool previousStop = fStopOnLoadEnabled; - bool previousCustomImages = fUseCustomImages && fStopOnLoadEnabled; - - fStopOnLoadEnabled = fTeam->StopOnImageLoad(); - fStopOnImageLoad->SetValue( - fStopOnLoadEnabled ? B_CONTROL_ON : B_CONTROL_OFF); - fUseCustomImages = fTeam->StopImageNameListEnabled(); - fStopImageConstraints->Menu() - ->ItemAt(fTeam->StopImageNameListEnabled() ? 1 : 0)->SetMarked(true); - - fStopImageNames->MakeEmpty(); - const BStringList& imageNames = fTeam->StopImageNames(); - for (int32 i = 0; i < imageNames.CountStrings(); i++) { - BStringItem* item = new(std::nothrow) BStringItem( - imageNames.StringAt(i)); - if (item == NULL) - return; - item->SetEnabled(fUseCustomImages); - ObjectDeleter itemDeleter(item); - if (!fStopImageNames->AddItem(item)) - return; - itemDeleter.Detach(); - } - - _UpdateStopImageButtons(previousStop, previousCustomImages); -} - - -void -TeamSettingsWindow::_UpdateStopImageButtons(bool previousStop, - bool previousCustomImages) -{ - fStopImageConstraints->SetEnabled(fStopOnLoadEnabled); - bool showCustomGroup = fUseCustomImages && fStopOnLoadEnabled; - if (!previousCustomImages && showCustomGroup) - fCustomImageGroup->Show(); - else if (previousCustomImages && !showCustomGroup) - fCustomImageGroup->Hide(); } diff --git a/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.h b/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.h index ec754a4344..6fd545ea69 100644 --- a/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.h +++ b/src/apps/debugger/user_interface/gui/team_settings_window/TeamSettingsWindow.h @@ -8,22 +8,15 @@ #include -#include "Team.h" -#include "types/Types.h" - - -class BBox; class BButton; -class BCheckBox; -class BListView; -class BMenuField; -class BTextControl; -class ImageDebugInfo; +class ExceptionStopConfigView; +class ImageStopConfigView; +class Team; class UserInterfaceListener; -class TeamSettingsWindow : public BWindow, private Team::Listener { +class TeamSettingsWindow : public BWindow { public: TeamSettingsWindow(::Team* team, UserInterfaceListener* listener, @@ -36,49 +29,14 @@ public: BHandler* target); // throws - virtual void MessageReceived(BMessage* message); - virtual void Show(); - // Team::Listener - virtual void StopOnImageLoadSettingsChanged( - const Team::ImageLoadEvent& event); - virtual void StopOnImageLoadNameAdded( - const Team::ImageLoadNameEvent& event); - virtual void StopOnImageLoadNameRemoved( - const Team::ImageLoadNameEvent& event); - - private: void _Init(); - void _UpdateThrownBreakpoints(bool enable); - status_t _FindExceptionFunction(ImageDebugInfo* info, - target_addr_t& _foundAddress) const; - - void _UpdateExceptionState(); - void _UpdateStopImageState(); - void _UpdateStopImageButtons(bool previousStop, - bool previousCustomImages); - // must be called with team lock held - - private: ::Team* fTeam; UserInterfaceListener* fListener; - BBox* fExceptionSettingsBox; - BBox* fImageSettingsBox; - BCheckBox* fExceptionThrown; - BCheckBox* fExceptionCaught; - BCheckBox* fStopOnImageLoad; - BMenuField* fStopImageConstraints; - BListView* fStopImageNames; - BTextControl* fStopImageNameInput; - BButton* fAddImageNameButton; - BButton* fRemoveImageNameButton; - BView* fCustomImageGroup; - bool fStopOnLoadEnabled; - bool fUseCustomImages; BButton* fCloseButton; BHandler* fTarget; };