1/*
2 * Copyright 2014-2016, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
5#include "BreakpointEditWindow.h"
6
7#include <Button.h>
8#include <LayoutBuilder.h>
9#include <RadioButton.h>
10#include <StringView.h>
11#include <TextControl.h>
12
13#include <AutoDeleter.h>
14#include <AutoLocker.h>
15
16#include "AppMessageCodes.h"
17#include "Team.h"
18#include "UserBreakpoint.h"
19#include "UserInterface.h"
20
21
22enum {
23	MSG_SET_BREAK_ALWAYS 			= 'sbal',
24	MSG_SET_BREAK_ON_CONDITION		= 'sboc',
25	MSG_SAVE_BREAKPOINT_SETTINGS 	= 'sbps'
26};
27
28
29BreakpointEditWindow::BreakpointEditWindow(::Team* team,
30	UserBreakpoint* breakpoint, UserInterfaceListener* listener,
31	BHandler* target)
32	:
33	BWindow(BRect(), "Edit breakpoint", B_FLOATING_WINDOW,
34		B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
35	fTeam(team),
36	fListener(listener),
37	fTargetBreakpoint(breakpoint),
38	fSaveButton(NULL),
39	fCancelButton(NULL),
40	fTarget(target)
41{
42	fTargetBreakpoint->AcquireReference();
43}
44
45
46BreakpointEditWindow::~BreakpointEditWindow()
47{
48	fTargetBreakpoint->ReleaseReference();
49	BMessenger(fTarget).SendMessage(MSG_BREAKPOINT_EDIT_WINDOW_CLOSED);
50}
51
52
53BreakpointEditWindow*
54BreakpointEditWindow::Create(::Team* team, UserBreakpoint* breakpoint,
55	UserInterfaceListener* listener, BHandler* target)
56{
57	BreakpointEditWindow* self = new BreakpointEditWindow(
58		team, breakpoint, listener, target);
59
60	try {
61		self->_Init();
62	} catch (...) {
63		delete self;
64		throw;
65	}
66
67	return self;
68
69}
70
71void
72BreakpointEditWindow::MessageReceived(BMessage* message)
73{
74	switch (message->what) {
75		case MSG_SET_BREAK_ALWAYS:
76			fConditionInput->SetEnabled(false);
77			break;
78		case MSG_SET_BREAK_ON_CONDITION:
79			fConditionInput->SetEnabled(true);
80			break;
81		case MSG_SAVE_BREAKPOINT_SETTINGS:
82		{
83			if (fConditionRadio->Value() == B_CONTROL_ON) {
84				fListener->SetBreakpointConditionRequested(
85					fTargetBreakpoint, fConditionInput->Text());
86			} else {
87				fListener->ClearBreakpointConditionRequested(
88					fTargetBreakpoint);
89			}
90			// fall through
91		}
92		case B_CANCEL:
93			Quit();
94			break;
95
96		default:
97			BWindow::MessageReceived(message);
98			break;
99	}
100
101}
102
103
104void
105BreakpointEditWindow::Show()
106{
107	CenterOnScreen();
108	BWindow::Show();
109}
110
111
112void
113BreakpointEditWindow::_Init()
114{
115	fConditionInput = new BTextControl(NULL, NULL, NULL);
116	BLayoutItem* textLayoutItem = fConditionInput->CreateTextViewLayoutItem();
117	textLayoutItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET));
118	BLayoutBuilder::Group<>(this, B_VERTICAL)
119		.SetInsets(B_USE_DEFAULT_SPACING)
120		.Add((fAlwaysRadio = new BRadioButton("Break always",
121				new BMessage(MSG_SET_BREAK_ALWAYS))))
122		.AddGroup(B_HORIZONTAL)
123			.Add((fConditionRadio = new BRadioButton("Break on condition: ",
124				new BMessage(MSG_SET_BREAK_ON_CONDITION))))
125			.Add(textLayoutItem)
126		.End()
127		.AddGroup(B_HORIZONTAL)
128			.AddGlue()
129			.Add((fSaveButton = new BButton("Save",
130				new BMessage(MSG_SAVE_BREAKPOINT_SETTINGS))))
131			.Add((fCancelButton = new BButton("Cancel",
132				new BMessage(B_CANCEL))))
133		.End()
134	.End();
135
136	AutoLocker< ::Team> teamLocker(fTeam);
137	if (fTargetBreakpoint->HasCondition()) {
138		fConditionRadio->SetValue(B_CONTROL_ON);
139		fConditionInput->SetText(fTargetBreakpoint->Condition());
140	} else {
141		fAlwaysRadio->SetValue(B_CONTROL_ON);
142		fConditionInput->SetEnabled(false);
143	}
144}
145