Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / preferences / bluetooth / InquiryPanel.cpp
blob7f6560e303a5794f1a0412f7c9762aa2a0fa4b65
1 /*
2 * Copyright 2008-09, Oliver Ruiz Dorantes, <oliver.ruiz.dorantes_at_gmail.com>
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
6 #include <Alert.h>
7 #include <Button.h>
8 #include <Catalog.h>
9 #include <GroupLayoutBuilder.h>
10 #include <ListView.h>
11 #include <ListItem.h>
12 #include <MessageRunner.h>
13 #include <ScrollView.h>
14 #include <StatusBar.h>
15 #include <SpaceLayoutItem.h>
16 #include <TextView.h>
17 #include <TabView.h>
19 #include <bluetooth/bdaddrUtils.h>
20 #include <bluetooth/DiscoveryAgent.h>
21 #include <bluetooth/DiscoveryListener.h>
22 #include <bluetooth/LocalDevice.h>
24 #include "defs.h"
25 #include "DeviceListItem.h"
26 #include "InquiryPanel.h"
29 #undef B_TRANSLATION_CONTEXT
30 #define B_TRANSLATION_CONTEXT "Inquiry panel"
32 using Bluetooth::DeviceListItem;
34 // private funcionaility provided by kit
35 extern uint8 GetInquiryTime();
37 static const uint32 kMsgStart = 'InSt';
38 static const uint32 kMsgFinish = 'InFn';
39 static const uint32 kMsgShowDebug = 'ShDG';
41 static const uint32 kMsgInquiry = 'iQbt';
42 static const uint32 kMsgAddListDevice = 'aDdv';
44 static const uint32 kMsgSelected = 'isLt';
45 static const uint32 kMsgSecond = 'sCMs';
46 static const uint32 kMsgRetrieve = 'IrEt';
49 class PanelDiscoveryListener : public DiscoveryListener {
51 public:
53 PanelDiscoveryListener(InquiryPanel* iPanel)
55 DiscoveryListener(),
56 fInquiryPanel(iPanel)
62 void
63 DeviceDiscovered(RemoteDevice* btDevice, DeviceClass cod)
65 BMessage* message = new BMessage(kMsgAddListDevice);
67 message->AddPointer("remoteItem", new DeviceListItem(btDevice));
69 fInquiryPanel->PostMessage(message);
73 void
74 InquiryCompleted(int discType)
76 BMessage* message = new BMessage(kMsgFinish);
77 fInquiryPanel->PostMessage(message);
81 void
82 InquiryStarted(status_t status)
84 BMessage* message = new BMessage(kMsgStart);
85 fInquiryPanel->PostMessage(message);
88 private:
89 InquiryPanel* fInquiryPanel;
94 InquiryPanel::InquiryPanel(BRect frame, LocalDevice* lDevice)
96 BWindow(frame, B_TRANSLATE_SYSTEM_NAME("Bluetooth"), B_FLOATING_WINDOW,
97 B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES ),
98 fMessenger(this),
99 fScanning(false),
100 fRetrieving(false),
101 fLocalDevice(lDevice)
104 SetLayout(new BGroupLayout(B_HORIZONTAL));
106 fScanProgress = new BStatusBar("status",
107 B_TRANSLATE("Scanning progress"), "");
108 activeColor = fScanProgress->BarColor();
110 if (fLocalDevice == NULL)
111 fLocalDevice = LocalDevice::GetLocalDevice();
113 fMessage = new BTextView("description", B_WILL_DRAW);
114 fMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
115 fMessage->SetLowColor(fMessage->ViewColor());
116 fMessage->MakeEditable(false);
117 fMessage->MakeSelectable(false);
119 fInquiryButton = new BButton("Inquiry", B_TRANSLATE("Inquiry"),
120 new BMessage(kMsgInquiry), B_WILL_DRAW);
122 fAddButton = new BButton("add", B_TRANSLATE("Add device to list"),
123 new BMessage(kMsgAddToRemoteList), B_WILL_DRAW);
124 fAddButton->SetEnabled(false);
126 fRemoteList = new BListView("AttributeList", B_SINGLE_SELECTION_LIST);
127 fRemoteList->SetSelectionMessage(new BMessage(kMsgSelected));
129 fScrollView = new BScrollView("ScrollView", fRemoteList, 0, false, true);
130 fScrollView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
132 if (fLocalDevice != NULL) {
133 fMessage->SetText(B_TRANSLATE(
134 "Check that the Bluetooth capabilities of your"
135 " remote device are activated. Press 'Inquiry' to start scanning."
136 " The needed time for the retrieval of the names is unknown, "
137 "although should not take more than 3 seconds per device. "
138 "Afterwards you will be able to add them to your main list,"
139 " where you will be able to pair with them."));
140 fInquiryButton->SetEnabled(true);
141 fDiscoveryAgent = fLocalDevice->GetDiscoveryAgent();
142 fDiscoveryListener = new PanelDiscoveryListener(this);
145 SetTitle((const char*)(fLocalDevice->GetFriendlyName().String()));
148 } else {
149 fMessage->SetText(B_TRANSLATE("There isn't any Bluetooth LocalDevice "
150 "registered on the system."));
151 fInquiryButton->SetEnabled(false);
154 fRetrieveMessage = new BMessage(kMsgRetrieve);
155 fSecondsMessage = new BMessage(kMsgSecond);
158 AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
159 .Add(fMessage)
160 .Add(BSpaceLayoutItem::CreateVerticalStrut(5))
161 .Add(fScanProgress)
162 .Add(BSpaceLayoutItem::CreateVerticalStrut(5))
163 .Add(fScrollView)
164 .Add(BSpaceLayoutItem::CreateVerticalStrut(5))
165 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
166 .Add(fAddButton)
167 .AddGlue()
168 .Add(fInquiryButton)
170 .SetInsets(15, 25, 15, 15)
175 void
176 InquiryPanel::MessageReceived(BMessage* message)
178 static float timer = 0; // expected time of the inquiry process
179 static float scanningTime = 0;
180 static int32 retrievalIndex = 0;
181 static bool labelPlaced = false;
183 switch (message->what) {
184 case kMsgInquiry:
186 fDiscoveryAgent->StartInquiry(BT_GIAC, fDiscoveryListener, GetInquiryTime());
188 timer = BT_BASE_INQUIRY_TIME * GetInquiryTime() + 1;
189 // does it works as expected?
190 fScanProgress->SetMaxValue(timer);
192 break;
194 case kMsgAddListDevice:
196 DeviceListItem* listItem;
198 message->FindPointer("remoteItem", (void **)&listItem);
200 fRemoteList->AddItem(listItem);
202 break;
204 case kMsgAddToRemoteList:
206 message->PrintToStream();
207 int32 index = fRemoteList->CurrentSelection(0);
208 DeviceListItem* item = (DeviceListItem*) fRemoteList->RemoveItem(index);;
210 BMessage message(kMsgAddToRemoteList);
211 message.AddPointer("device", item);
213 be_app->PostMessage(&message);
214 // TODO: all others listitems can be deleted
216 break;
218 case kMsgSelected:
219 UpdateListStatus();
220 break;
222 case kMsgStart:
223 fRemoteList->MakeEmpty();
224 fScanProgress->Reset();
225 fScanProgress->SetTo(1);
226 fScanProgress->SetTrailingText(B_TRANSLATE("Starting scan..."));
227 fScanProgress->SetBarColor(activeColor);
229 fAddButton->SetEnabled(false);
230 fInquiryButton->SetEnabled(false);
232 BMessageRunner::StartSending(fMessenger, fSecondsMessage, 1000000, timer);
234 scanningTime = 1;
235 fScanning = true;
237 break;
239 case kMsgFinish:
241 retrievalIndex = 0;
242 fScanning = false;
243 fRetrieving = true;
244 labelPlaced = false;
245 fScanProgress->SetTo(100);
246 fScanProgress->SetTrailingText(B_TRANSLATE("Retrieving names..."));
247 BMessageRunner::StartSending(fMessenger, fRetrieveMessage, 1000000, 1);
249 break;
251 case kMsgSecond:
252 if (fScanning && scanningTime < timer) {
253 // TODO time formatting could use Locale Kit
255 // TODO should not be needed if SetMaxValue works...
256 fScanProgress->SetTo(scanningTime * 100 / timer);
257 BString elapsedTime = B_TRANSLATE("Remaining %1 seconds");
259 BString seconds("");
260 seconds << (int)(timer - scanningTime);
262 elapsedTime.ReplaceFirst("%1", seconds.String());
263 fScanProgress->SetTrailingText(elapsedTime.String());
265 scanningTime = scanningTime + 1;
267 break;
269 case kMsgRetrieve:
271 if (fRetrieving) {
273 if (retrievalIndex < fDiscoveryAgent->RetrieveDevices(0).CountItems()) {
275 if (!labelPlaced) {
277 labelPlaced = true;
278 BString progressText(B_TRANSLATE("Retrieving name of %1"));
280 BString namestr;
281 namestr << bdaddrUtils::ToString(fDiscoveryAgent
282 ->RetrieveDevices(0).ItemAt(retrievalIndex)
283 ->GetBluetoothAddress());
284 progressText.ReplaceFirst("%1", namestr.String());
285 fScanProgress->SetTrailingText(progressText.String());
287 } else {
288 // Really erally expensive operation should be done in a separate thread
289 // once Haiku gets a BarberPole in API replacing the progress bar
290 ((DeviceListItem*)fRemoteList->ItemAt(retrievalIndex))
291 ->SetDevice((BluetoothDevice*) fDiscoveryAgent
292 ->RetrieveDevices(0).ItemAt(retrievalIndex));
293 fRemoteList->InvalidateItem(retrievalIndex);
295 retrievalIndex++;
296 labelPlaced = false;
299 BMessageRunner::StartSending(fMessenger, fRetrieveMessage, 500000, 1);
301 } else {
303 fRetrieving = false;
304 retrievalIndex = 0;
306 fScanProgress->SetBarColor(
307 ui_color(B_PANEL_BACKGROUND_COLOR));
308 fScanProgress->SetTrailingText(
309 B_TRANSLATE("Scanning completed."));
310 fInquiryButton->SetEnabled(true);
311 UpdateListStatus();
315 break;
317 default:
318 BWindow::MessageReceived(message);
319 break;
324 void
325 InquiryPanel::UpdateListStatus(void)
327 if (fRemoteList->CurrentSelection() < 0 || fScanning || fRetrieving)
328 fAddButton->SetEnabled(false);
329 else
330 fAddButton->SetEnabled(true);
334 bool
335 InquiryPanel::QuitRequested(void)
338 return true;