Implement configuration for stop on image load with names.
- BreakConditionConfigWindow is now a team listener so it can watch for the appropriate events. - Implement reading/maintaining state in response to the various notifications. - Implement adding/removing names and enabling/disabling the use of the name list.
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include <MenuField.h>
|
#include <MenuField.h>
|
||||||
#include <ScrollView.h>
|
#include <ScrollView.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <AutoLocker.h>
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
#include "FunctionInstance.h"
|
#include "FunctionInstance.h"
|
||||||
@@ -33,6 +34,22 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int SortStringItems(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
BStringItem* item1 = *(BStringItem**)a;
|
||||||
|
BStringItem* item2 = *(BStringItem**)b;
|
||||||
|
|
||||||
|
return strcmp(item1->Text(), item2->Text());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool UpdateItemState(BListItem* item, void* enabled)
|
||||||
|
{
|
||||||
|
item->SetEnabled((bool)enabled);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BreakConditionConfigWindow::BreakConditionConfigWindow(::Team* team,
|
BreakConditionConfigWindow::BreakConditionConfigWindow(::Team* team,
|
||||||
UserInterfaceListener* listener, BHandler* target)
|
UserInterfaceListener* listener, BHandler* target)
|
||||||
:
|
:
|
||||||
@@ -48,14 +65,17 @@ BreakConditionConfigWindow::BreakConditionConfigWindow(::Team* team,
|
|||||||
fStopImageNameInput(NULL),
|
fStopImageNameInput(NULL),
|
||||||
fAddImageNameButton(NULL),
|
fAddImageNameButton(NULL),
|
||||||
fRemoveImageNameButton(NULL),
|
fRemoveImageNameButton(NULL),
|
||||||
|
fUseCustomImages(false),
|
||||||
fCloseButton(NULL),
|
fCloseButton(NULL),
|
||||||
fTarget(target)
|
fTarget(target)
|
||||||
{
|
{
|
||||||
|
fTeam->AddListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BreakConditionConfigWindow::~BreakConditionConfigWindow()
|
BreakConditionConfigWindow::~BreakConditionConfigWindow()
|
||||||
{
|
{
|
||||||
|
fTeam->RemoveListener(this);
|
||||||
BMessenger(fTarget).SendMessage(MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED);
|
BMessenger(fTarget).SendMessage(MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,28 +116,27 @@ BreakConditionConfigWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case MSG_SET_STOP_FOR_ALL_IMAGES:
|
case MSG_SET_STOP_FOR_ALL_IMAGES:
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fStopImageNames->CountItems(); i++)
|
fUseCustomImages = false;
|
||||||
fStopImageNames->ItemAt(i)->SetEnabled(false);
|
fListener->SetStopOnImageLoadRequested(
|
||||||
fStopImageNameInput->SetEnabled(false);
|
fStopOnImageLoad->Value() == B_CONTROL_ON,
|
||||||
fAddImageNameButton->SetEnabled(false);
|
fUseCustomImages);
|
||||||
fRemoveImageNameButton->SetEnabled(false);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MSG_SET_STOP_FOR_CUSTOM_IMAGES:
|
case MSG_SET_STOP_FOR_CUSTOM_IMAGES:
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fStopImageNames->CountItems(); i++)
|
fUseCustomImages = true;
|
||||||
fStopImageNames->ItemAt(i)->SetEnabled(true);
|
fListener->SetStopOnImageLoadRequested(
|
||||||
fStopImageNameInput->SetEnabled(true);
|
fStopOnImageLoad->Value() == B_CONTROL_ON,
|
||||||
fAddImageNameButton->SetEnabled(
|
fUseCustomImages);
|
||||||
fStopImageNameInput->TextView()->TextLength() > 0);
|
|
||||||
fRemoveImageNameButton->SetEnabled(
|
|
||||||
fStopImageNames->CurrentSelection() >= 0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MSG_IMAGE_NAME_SELECTION_CHANGED:
|
case MSG_IMAGE_NAME_SELECTION_CHANGED:
|
||||||
{
|
{
|
||||||
|
if (!fUseCustomImages)
|
||||||
|
break;
|
||||||
|
|
||||||
fRemoveImageNameButton->SetEnabled(
|
fRemoveImageNameButton->SetEnabled(
|
||||||
fStopImageNames->CurrentSelection() >= 0);
|
fStopImageNames->CurrentSelection() >= 0);
|
||||||
break;
|
break;
|
||||||
@@ -126,10 +145,79 @@ BreakConditionConfigWindow::MessageReceived(BMessage* message)
|
|||||||
case MSG_STOP_ON_IMAGE_LOAD:
|
case MSG_STOP_ON_IMAGE_LOAD:
|
||||||
{
|
{
|
||||||
fListener->SetStopOnImageLoadRequested(
|
fListener->SetStopOnImageLoadRequested(
|
||||||
fStopOnImageLoad->Value() == B_CONTROL_ON);
|
fStopOnImageLoad->Value() == B_CONTROL_ON,
|
||||||
|
fUseCustomImages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_STOP_IMAGE_SETTINGS_CHANGED:
|
||||||
|
{
|
||||||
|
_UpdateStopImageButtons();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MSG_ADD_IMAGE_NAME:
|
||||||
|
{
|
||||||
|
BString imageName(fStopImageNameInput->Text());
|
||||||
|
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<BStringItem> 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:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
@@ -146,6 +234,37 @@ BreakConditionConfigWindow::Show()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BreakConditionConfigWindow::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
|
||||||
|
BreakConditionConfigWindow::StopOnImageLoadNameAdded(
|
||||||
|
const Team::ImageLoadNameEvent& event)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_STOP_IMAGE_NAME_ADDED);
|
||||||
|
message.AddString("name", event.ImageName());
|
||||||
|
PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BreakConditionConfigWindow::StopOnImageLoadNameRemoved(
|
||||||
|
const Team::ImageLoadNameEvent& event)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_STOP_IMAGE_NAME_REMOVED);
|
||||||
|
message.AddString("name", event.ImageName());
|
||||||
|
PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BreakConditionConfigWindow::_Init()
|
BreakConditionConfigWindow::_Init()
|
||||||
{
|
{
|
||||||
@@ -179,7 +298,7 @@ BreakConditionConfigWindow::_Init()
|
|||||||
stopImageMenu->AddItem(new BMenuItem("Custom",
|
stopImageMenu->AddItem(new BMenuItem("Custom",
|
||||||
new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES)));
|
new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES)));
|
||||||
|
|
||||||
BListView* fStopImageNames = new BListView("customImageList",
|
fStopImageNames = new BListView("customImageList",
|
||||||
B_MULTIPLE_SELECTION_LIST);
|
B_MULTIPLE_SELECTION_LIST);
|
||||||
fStopImageNames->SetSelectionMessage(
|
fStopImageNames->SetSelectionMessage(
|
||||||
new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED));
|
new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED));
|
||||||
@@ -226,24 +345,11 @@ BreakConditionConfigWindow::_Init()
|
|||||||
fCloseButton->SetTarget(this);
|
fCloseButton->SetTarget(this);
|
||||||
stopImageMenu->SetTargetForItems(this);
|
stopImageMenu->SetTargetForItems(this);
|
||||||
stopImageMenu->SetLabelFromMarked(true);
|
stopImageMenu->SetLabelFromMarked(true);
|
||||||
stopImageMenu->ItemAt(0L)->SetMarked(true);
|
|
||||||
|
|
||||||
// check if the exception breakpoints are already installed
|
|
||||||
AutoLocker< ::Team> teamLocker(fTeam);
|
AutoLocker< ::Team> teamLocker(fTeam);
|
||||||
for (ImageList::ConstIterator it = fTeam->Images().GetIterator();
|
_UpdateStopImageState();
|
||||||
it.HasNext();) {
|
_UpdateExceptionState();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -286,3 +392,64 @@ BreakConditionConfigWindow::_FindExceptionFunction(ImageDebugInfo* info,
|
|||||||
|
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BreakConditionConfigWindow::_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
|
||||||
|
BreakConditionConfigWindow::_UpdateStopImageState()
|
||||||
|
{
|
||||||
|
fUseCustomImages = fTeam->StopImageNameListEnabled();
|
||||||
|
fStopImageConstraints->Menu()->ItemAt(0)->SetMarked(!fUseCustomImages);
|
||||||
|
fStopImageConstraints->Menu()->ItemAt(1)->SetMarked(fUseCustomImages);
|
||||||
|
|
||||||
|
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<BStringItem> itemDeleter(item);
|
||||||
|
if (!fStopImageNames->AddItem(item))
|
||||||
|
return;
|
||||||
|
itemDeleter.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
_UpdateStopImageButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BreakConditionConfigWindow::_UpdateStopImageButtons()
|
||||||
|
{
|
||||||
|
bool stopOnImageLoad = fTeam->StopOnImageLoad();
|
||||||
|
fStopOnImageLoad->SetValue(stopOnImageLoad ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||||
|
bool enabled = stopOnImageLoad && fUseCustomImages;
|
||||||
|
fStopImageConstraints->SetEnabled(stopOnImageLoad);
|
||||||
|
fAddImageNameButton->SetEnabled(enabled);
|
||||||
|
fRemoveImageNameButton->SetEnabled(enabled
|
||||||
|
&& fStopImageNames->CurrentSelection() >= 0);
|
||||||
|
fStopImageNames->DoForEach(UpdateItemState, (void*)enabled);
|
||||||
|
fStopImageNameInput->TextView()->MakeEditable(enabled);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Team.h"
|
||||||
|
|
||||||
#include "types/Types.h"
|
#include "types/Types.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -17,11 +19,10 @@ class BListView;
|
|||||||
class BMenuField;
|
class BMenuField;
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class ImageDebugInfo;
|
class ImageDebugInfo;
|
||||||
class Team;
|
|
||||||
class UserInterfaceListener;
|
class UserInterfaceListener;
|
||||||
|
|
||||||
|
|
||||||
class BreakConditionConfigWindow : public BWindow {
|
class BreakConditionConfigWindow : public BWindow, private Team::Listener {
|
||||||
public:
|
public:
|
||||||
BreakConditionConfigWindow(::Team* team,
|
BreakConditionConfigWindow(::Team* team,
|
||||||
UserInterfaceListener* listener,
|
UserInterfaceListener* listener,
|
||||||
@@ -38,12 +39,27 @@ public:
|
|||||||
|
|
||||||
virtual void Show();
|
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:
|
private:
|
||||||
void _Init();
|
void _Init();
|
||||||
void _UpdateThrownBreakpoints(bool enable);
|
void _UpdateThrownBreakpoints(bool enable);
|
||||||
status_t _FindExceptionFunction(ImageDebugInfo* info,
|
status_t _FindExceptionFunction(ImageDebugInfo* info,
|
||||||
target_addr_t& _foundAddress) const;
|
target_addr_t& _foundAddress) const;
|
||||||
|
|
||||||
|
void _UpdateExceptionState();
|
||||||
|
void _UpdateStopImageState();
|
||||||
|
void _UpdateStopImageButtons();
|
||||||
|
// must be called with team lock held
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Team* fTeam;
|
::Team* fTeam;
|
||||||
@@ -56,6 +72,7 @@ private:
|
|||||||
BTextControl* fStopImageNameInput;
|
BTextControl* fStopImageNameInput;
|
||||||
BButton* fAddImageNameButton;
|
BButton* fAddImageNameButton;
|
||||||
BButton* fRemoveImageNameButton;
|
BButton* fRemoveImageNameButton;
|
||||||
|
bool fUseCustomImages;
|
||||||
BButton* fCloseButton;
|
BButton* fCloseButton;
|
||||||
BHandler* fTarget;
|
BHandler* fTarget;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user