xref: /haiku/src/apps/debugger/user_interface/gui/utility_windows/ConnectionConfigWindow.cpp (revision 76ca67192568e002bea3ee0e688937e19d5a2c58)
1 /*
2  * Copyright 2016-2017, Rene Gollent, rene@gollent.com.
3  * Distributed under the terms of the MIT License.
4  */
5 #include "ConnectionConfigWindow.h"
6 
7 #include <Application.h>
8 #include <Button.h>
9 #include <GroupView.h>
10 #include <MenuField.h>
11 #include <LayoutBuilder.h>
12 
13 #include <AutoDeleter.h>
14 #include <AutoLocker.h>
15 
16 #include "AppMessageCodes.h"
17 #include "ConnectionConfigHandlerRoster.h"
18 #include "Settings.h"
19 #include "TargetHostInterfaceInfo.h"
20 #include "TargetHostInterfaceRoster.h"
21 #include "TargetHostInterface.h"
22 
23 
24 enum {
25 	MSG_SWITCH_CONNECTION_TYPE 	= 'swct',
26 	MSG_CREATE_CONNECTION 		= 'crco'
27 };
28 
29 
ConnectionConfigWindow()30 ConnectionConfigWindow::ConnectionConfigWindow()
31 	:
32 	BWindow(BRect(), "Create new connection", B_TITLED_WINDOW,
33 		B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
34 	ConnectionConfigView::Listener(),
35 	fConnectionTypeField(NULL),
36 	fConfigGroupView(NULL),
37 	fCloseButton(NULL),
38 	fConnectButton(NULL),
39 	fCurrentSettings(NULL),
40 	fActiveInfo(NULL)
41 {
42 }
43 
44 
~ConnectionConfigWindow()45 ConnectionConfigWindow::~ConnectionConfigWindow()
46 {
47 	if (fCurrentSettings != NULL)
48 		fCurrentSettings->ReleaseReference();
49 }
50 
51 
52 ConnectionConfigWindow*
Create()53 ConnectionConfigWindow::Create()
54 {
55 	ConnectionConfigWindow* self = new ConnectionConfigWindow();
56 
57 	try {
58 		self->_Init();
59 	} catch (...) {
60 		delete self;
61 		throw;
62 	}
63 
64 	return self;
65 
66 }
67 
68 
69 void
Show()70 ConnectionConfigWindow::Show()
71 {
72 	CenterOnScreen();
73 	BWindow::Show();
74 }
75 
76 
77 bool
QuitRequested()78 ConnectionConfigWindow::QuitRequested()
79 {
80 	return be_app_messenger.SendMessage(MSG_CONNECTION_CONFIG_WINDOW_CLOSED)
81 		== B_OK;
82 }
83 
84 
85 void
ConfigurationChanged(Settings * settings)86 ConnectionConfigWindow::ConfigurationChanged(Settings* settings)
87 {
88 	if (fCurrentSettings != NULL)
89 		fCurrentSettings->ReleaseReference();
90 	fCurrentSettings = settings;
91 	fCurrentSettings->AcquireReference();
92 
93 	fConnectButton->SetEnabled(fActiveInfo->IsConfigured(settings));
94 }
95 
96 
97 void
MessageReceived(BMessage * message)98 ConnectionConfigWindow::MessageReceived(BMessage* message)
99 {
100 	switch (message->what) {
101 		case MSG_CREATE_CONNECTION:
102 		{
103 			TargetHostInterfaceRoster* roster
104 				= TargetHostInterfaceRoster::Default();
105 			AutoLocker<TargetHostInterfaceRoster> rosterLocker(roster);
106 
107 			TargetHostInterface* interface;
108 			status_t error = roster->CreateInterface(fActiveInfo,
109 				fCurrentSettings, interface);
110 
111 			// TODO: notify user.
112 			if (error != B_OK)
113 				break;
114 
115 			PostMessage(B_QUIT_REQUESTED);
116 			break;
117 		}
118 		default:
119 			BWindow::MessageReceived(message);
120 			break;
121 	}
122 }
123 
124 
125 void
_Init()126 ConnectionConfigWindow::_Init()
127 {
128 	BMenu* menu = _BuildTypeMenu();
129 
130 	fConfigGroupView = new BGroupView(B_HORIZONTAL);
131 
132 	BLayoutBuilder::Group<>(this, B_VERTICAL)
133 		.SetInsets(B_USE_DEFAULT_SPACING)
134 		.Add(fConnectionTypeField = new BMenuField("Type:", menu))
135 		.AddGroup(fConfigGroupView)
136 			// this group is a placeholder to contain
137 			// the actual config view
138 		.End()
139 		.AddGroup(B_HORIZONTAL)
140 			.SetInsets(B_USE_SMALL_SPACING)
141 			.AddGlue()
142 			.Add(fCloseButton = new BButton("Close",
143 					new BMessage(B_QUIT_REQUESTED)))
144 			.Add(fConnectButton = new BButton("Connect",
145 					new BMessage(MSG_CREATE_CONNECTION)))
146 		.End();
147 
148 	fConnectionTypeField->Menu()->SetLabelFromMarked(true);
149 	fConnectionTypeField->Menu()->SetTargetForItems(this);
150 
151 	fCloseButton->SetTarget(this);
152 	fConnectButton->SetTarget(this);
153 	fConnectButton->SetEnabled(false);
154 
155 	if (menu->CountItems() > 0) {
156 		BMenuItem* item = menu->ItemAt(0);
157 		BMessage* message = item->Message();
158 		TargetHostInterfaceInfo* info = NULL;
159 		if (message->FindPointer("info", reinterpret_cast<void**>(&info))
160 			== B_OK) {
161 			_UpdateActiveConfig(info);
162 			menu->ItemAt(0)->SetMarked(true);
163 		}
164 	}
165 }
166 
167 
168 BMenu*
_BuildTypeMenu()169 ConnectionConfigWindow::_BuildTypeMenu()
170 {
171 	BMenu* menu = new BMenu("Types");
172 	TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default();
173 
174 	AutoLocker<TargetHostInterfaceRoster> rosterLocker(roster);
175 
176 	for (int32 i = 0; i < roster->CountInterfaceInfos(); i++) {
177 		TargetHostInterfaceInfo* info = roster->InterfaceInfoAt(i);
178 		if (info->IsLocal())
179 			continue;
180 
181 		BMenuItem* item = new BMenuItem(info->Name(), new BMessage(
182 				MSG_SWITCH_CONNECTION_TYPE));
183 		item->Message()->AddPointer("info", info);
184 		menu->AddItem(item);
185 	}
186 
187 	return menu;
188 }
189 
190 
191 void
_UpdateActiveConfig(TargetHostInterfaceInfo * info)192 ConnectionConfigWindow::_UpdateActiveConfig(TargetHostInterfaceInfo* info)
193 {
194 	if (fConfigGroupView->CountChildren() > 0) {
195 		BView* view = fConfigGroupView->ChildAt(0);
196 		fConfigGroupView->RemoveChild(view);
197 		delete view;
198 	}
199 
200 	ConnectionConfigHandlerRoster* roster
201 		= ConnectionConfigHandlerRoster::Default();
202 
203 	if (roster->HasHandlerFor(info)) {
204 		ConnectionConfigView* view = NULL;
205 		status_t error = roster->CreateConfigView(info, this, view);
206 		if (error != B_OK)
207 			return;
208 
209 		ObjectDeleter<ConnectionConfigView> viewDeleter(view);
210 		BLayoutItem* item = fConfigGroupView->GroupLayout()->AddView(view);
211 		if (item != NULL)
212 			viewDeleter.Detach();
213 
214 		fActiveInfo = info;
215 	}
216 
217 	fConfigGroupView->InvalidateLayout();
218 }
219