xref: /haiku/src/servers/bluetooth/DeskbarReplicant.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Weirauch, dev@m-phasis.de
7  */
8 
9 
10 #include "DeskbarReplicant.h"
11 
12 #include <Alert.h>
13 #include <Application.h>
14 #include <Bitmap.h>
15 #include <Catalog.h>
16 #include <Deskbar.h>
17 #include <IconUtils.h>
18 #include <MenuItem.h>
19 #include <Message.h>
20 #include <PopUpMenu.h>
21 #include <Resources.h>
22 #include <Roster.h>
23 #include <String.h>
24 
25 #include <bluetoothserver_p.h>
26 
27 extern "C" _EXPORT BView *instantiate_deskbar_item(void);
28 status_t our_image(image_info& image);
29 
30 const uint32 kMsgOpenBluetoothPreferences = 'obtp';
31 const uint32 kMsgQuitBluetoothServer = 'qbts';
32 
33 const char* kDeskbarItemName = "BluetoothServerReplicant";
34 const char* kClassName = "DeskbarReplicant";
35 
36 
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "BluetoothReplicant"
39 
40 
41 //	#pragma mark -
42 
43 
44 DeskbarReplicant::DeskbarReplicant(BRect frame, int32 resizingMode)
45 	: BView(frame, kDeskbarItemName, resizingMode,
46 		B_WILL_DRAW | B_FRAME_EVENTS)
47 {
48 	_Init();
49 }
50 
51 
52 DeskbarReplicant::DeskbarReplicant(BMessage* archive)
53 	: BView(archive)
54 {
55 	_Init();
56 }
57 
58 
59 DeskbarReplicant::~DeskbarReplicant()
60 {
61 }
62 
63 
64 void
65 DeskbarReplicant::_Init()
66 {
67 	fIcon = NULL;
68 
69 	image_info info;
70 	if (our_image(info) != B_OK)
71 		return;
72 
73 	BFile file(info.name, B_READ_ONLY);
74 	if (file.InitCheck() < B_OK)
75 		return;
76 
77 	BResources resources(&file);
78 	if (resources.InitCheck() < B_OK)
79 		return;
80 
81 	size_t size;
82 	const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE,
83 		"tray_icon", &size);
84 	if (data != NULL) {
85 		BBitmap* icon = new BBitmap(Bounds(), B_RGBA32);
86 		if (icon->InitCheck() == B_OK
87 			&& BIconUtils::GetVectorIcon((const uint8 *)data,
88 				size, icon) == B_OK) {
89 			fIcon = icon;
90 		} else
91 			delete icon;
92 	}
93 }
94 
95 
96 DeskbarReplicant *
97 DeskbarReplicant::Instantiate(BMessage* archive)
98 {
99 	if (!validate_instantiation(archive, kClassName))
100 		return NULL;
101 
102 	return new DeskbarReplicant(archive);
103 }
104 
105 
106 status_t
107 DeskbarReplicant::Archive(BMessage* archive, bool deep) const
108 {
109 	status_t status = BView::Archive(archive, deep);
110 	if (status == B_OK)
111 		status = archive->AddString("add_on", BLUETOOTH_SIGNATURE);
112 	if (status == B_OK)
113 		status = archive->AddString("class", kClassName);
114 
115 	return status;
116 }
117 
118 
119 void
120 DeskbarReplicant::AttachedToWindow()
121 {
122 	BView::AttachedToWindow();
123 	AdoptParentColors();
124 
125 	SetLowColor(ViewColor());
126 }
127 
128 
129 void
130 DeskbarReplicant::Draw(BRect updateRect)
131 {
132 	if (!fIcon) {
133 		/* At least display something... */
134 		rgb_color lowColor = LowColor();
135 		SetLowColor(0, 113, 187, 255);
136 		FillRoundRect(Bounds().InsetBySelf(3.f, 0.f), 5.f, 7.f, B_SOLID_LOW);
137 		SetLowColor(lowColor);
138 	} else {
139 		SetDrawingMode(B_OP_ALPHA);
140 		DrawBitmap(fIcon);
141 		SetDrawingMode(B_OP_COPY);
142 	}
143 }
144 
145 
146 void
147 DeskbarReplicant::MessageReceived(BMessage* msg)
148 {
149 	switch (msg->what) {
150 		case kMsgOpenBluetoothPreferences:
151 			be_roster->Launch(BLUETOOTH_APP_SIGNATURE);
152 			break;
153 
154 		case kMsgQuitBluetoothServer:
155 			_QuitBluetoothServer();
156 			break;
157 
158 		default:
159 			BView::MessageReceived(msg);
160 	}
161 }
162 
163 
164 void
165 DeskbarReplicant::MouseDown(BPoint where)
166 {
167 	BPoint point;
168 	uint32 buttons;
169 	GetMouse(&point, &buttons);
170 	if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) {
171 		return;
172 	}
173 
174 	BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
175 
176 	menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
177 		new BMessage(kMsgOpenBluetoothPreferences)));
178 
179 	// TODO show list of known/paired devices
180 
181 	menu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
182 		new BMessage(kMsgQuitBluetoothServer)));
183 
184 	menu->SetTargetForItems(this);
185 	ConvertToScreen(&point);
186 	menu->Go(point, true, true, true);
187 
188 	delete menu;
189 }
190 
191 
192 void
193 DeskbarReplicant::_QuitBluetoothServer()
194 {
195 	if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
196 		// The server isn't running, so remove ourself
197 		BDeskbar deskbar;
198 		deskbar.RemoveItem(kDeskbarItemName);
199 
200 		return;
201 	}
202 	status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
203 		B_QUIT_REQUESTED);
204 	if (status < B_OK) {
205 		_ShowErrorAlert(B_TRANSLATE("Stopping the Bluetooth server failed."),
206 			status);
207 	}
208 }
209 
210 
211 void
212 DeskbarReplicant::_ShowErrorAlert(BString msg, status_t status)
213 {
214 	BString error = B_TRANSLATE("Error: %status%");
215 	error.ReplaceFirst("%status%", strerror(status));
216 	msg << "\n\n" << error;
217 	BAlert* alert = new BAlert(B_TRANSLATE("Bluetooth error"), msg.String(),
218 		B_TRANSLATE("OK"));
219 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
220 	alert->Go(NULL);
221 }
222 
223 //	#pragma mark -
224 
225 
226 extern "C" _EXPORT BView *
227 instantiate_deskbar_item(void)
228 {
229 	return new DeskbarReplicant(BRect(0, 0, 15, 15),
230 		B_FOLLOW_LEFT | B_FOLLOW_TOP);
231 }
232 
233 //	#pragma mark -
234 
235 
236 status_t
237 our_image(image_info& image)
238 {
239 	int32 cookie = 0;
240 	while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
241 		if ((char *)our_image >= (char *)image.text
242 			&& (char *)our_image <= (char *)image.text + image.text_size)
243 			return B_OK;
244 	}
245 
246 	return B_ERROR;
247 }
248