xref: /haiku/src/kits/mail/ProtocolConfigView.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
1 /* BMailProtocolConfigView - the standard config view for all protocols
2 **
3 ** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
4 */
5 
6 
7 #include <TextControl.h>
8 #include <MenuField.h>
9 #include <PopUpMenu.h>
10 #include <String.h>
11 #include <Message.h>
12 #include <MenuItem.h>
13 #include <CheckBox.h>
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 
18 #include <MDRLanguage.h>
19 
20 class _EXPORT BMailProtocolConfigView;
21 
22 #include <crypt.h>
23 
24 #include "ProtocolConfigView.h"
25 
26 
27 namespace {
28 
29 //--------------------Support functions and #defines---------------
30 #define enable_control(name) if (FindView(name) != NULL) ((BControl *)(FindView(name)))->SetEnabled(true)
31 #define disable_control(name) if (FindView(name) != NULL) ((BControl *)(FindView(name)))->SetEnabled(false)
32 
33 BTextControl *AddTextField (BRect &rect, const char *name, const char *label);
34 BMenuField *AddMenuField (BRect &rect, const char *name, const char *label);
35 float FindWidestLabel(BView *view);
36 
37 static float sItemHeight;
38 
39 inline const char *
40 TextControl(BView *parent,const char *name)
41 {
42 	BTextControl *control = (BTextControl *)(parent->FindView(name));
43 	if (control != NULL)
44 		return control->Text();
45 
46 	return "";
47 }
48 
49 
50 BTextControl *
51 AddTextField (BRect &rect, const char *name, const char *label)
52 {
53 	BTextControl *text_control = new BTextControl(rect,name,label,"",NULL,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
54 //	text_control->SetDivider(be_plain_font->StringWidth(label));
55 	rect.OffsetBy(0,sItemHeight);
56 	return text_control;
57 }
58 
59 
60 BMenuField *AddMenuField (BRect &rect, const char *name, const char *label) {
61 	BPopUpMenu *menu = new BPopUpMenu("Select");
62 	BMenuField *control = new BMenuField(rect,name,label,menu,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
63 	control->SetDivider(be_plain_font->StringWidth(label) + 6);
64 	rect.OffsetBy(0,sItemHeight);
65 	return control;
66 }
67 
68 
69 inline BCheckBox *
70 AddCheckBox(BRect &rect, const char *name, const char *label, BMessage *msg = NULL)
71 {
72 	BCheckBox *control = new BCheckBox(rect,name,label,msg);
73 	rect.OffsetBy(0,sItemHeight);
74 	return control;
75 }
76 
77 
78 inline void
79 SetTextControl(BView *parent, const char *name, const char *text)
80 {
81 	BTextControl *control = (BTextControl *)(parent->FindView(name));
82 	if (control != NULL)
83 		control->SetText(text);
84 }
85 
86 
87 float
88 FindWidestLabel(BView *view)
89 {
90 	float width = 0;
91 	for (int32 i = view->CountChildren();i-- > 0;) {
92 		if (BControl *control = dynamic_cast<BControl *>(view->ChildAt(i))) {
93 			float labelWidth = control->StringWidth(control->Label());
94 			if (labelWidth > width)
95 				width = labelWidth;
96 		}
97 	}
98 	return width;
99 }
100 
101 } // unnamed namspace
102 
103 
104 //----------------Real code----------------------
105 BMailProtocolConfigView::BMailProtocolConfigView(uint32 options_mask)
106 	:
107 	BView (BRect(0,0,100,20), "protocol_config_view", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW)
108 {
109 	BRect rect(5,5,245,25);
110 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
111 
112 	// determine font height
113 	font_height fontHeight;
114 	GetFontHeight(&fontHeight);
115 	sItemHeight = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 13;
116 	rect.bottom = rect.top - 2 + sItemHeight;
117 
118 	if (options_mask & B_MAIL_PROTOCOL_HAS_HOSTNAME)
119 		AddChild(AddTextField(rect,"host",MDR_DIALECT_CHOICE ("Mail server:","サーバ名 :")));
120 
121 	if (options_mask & B_MAIL_PROTOCOL_HAS_USERNAME)
122 		AddChild(AddTextField(rect,"user",MDR_DIALECT_CHOICE ("Username:","ユーザーID:")));
123 
124 	if (options_mask & B_MAIL_PROTOCOL_HAS_PASSWORD) {
125 		BTextControl *control = AddTextField(rect,"pass",MDR_DIALECT_CHOICE ("Password:","パスワード:"));
126 		control->TextView()->HideTyping(true);
127 		AddChild(control);
128 	}
129 
130 	if (options_mask & B_MAIL_PROTOCOL_HAS_FLAVORS)
131 		AddChild(AddMenuField(rect,"flavor","Connection type:"));
132 
133 	if (options_mask & B_MAIL_PROTOCOL_HAS_AUTH_METHODS)
134 		AddChild(AddMenuField(rect,"auth_method",MDR_DIALECT_CHOICE ("Login type:","認証方法 :")));
135 
136 	// set divider
137 	float width = FindWidestLabel(this);
138 	for (int32 i = CountChildren();i-- > 0;) {
139 		if (BTextControl *text = dynamic_cast<BTextControl *>(ChildAt(i)))
140 			text->SetDivider(width + 6);
141 	}
142 
143 	if (options_mask & B_MAIL_PROTOCOL_CAN_LEAVE_MAIL_ON_SERVER) {
144 		AddChild(AddCheckBox(rect,"leave_mail_remote",MDR_DIALECT_CHOICE ("Leave mail on server","受信後にサーバ内のメールを削除しない"),new BMessage('lmos')));
145 		BCheckBox *box = AddCheckBox(rect,"delete_remote_when_local",MDR_DIALECT_CHOICE ("Remove mail from server when deleted","端末で削除されたらサーバ保存分も削除"));
146 		box->SetEnabled(false);
147 		AddChild(box);
148 	}
149 
150 	// resize views
151 	float height;
152 	GetPreferredSize(&width,&height);
153 	ResizeTo(width,height);
154 	for (int32 i = CountChildren();i-- > 0;) {
155 		// this doesn't work with BTextControl, does anyone know why? -- axeld.
156 		if (BView *view = ChildAt(i))
157 			view->ResizeTo(width - 10,view->Bounds().Height());
158 	}
159 }
160 
161 
162 BMailProtocolConfigView::~BMailProtocolConfigView()
163 {
164 }
165 
166 
167 void
168 BMailProtocolConfigView::SetTo(BMessage *archive)
169 {
170 	BString host = archive->FindString("server");
171 	if (archive->HasInt32("port"))
172 		host << ':' << archive->FindInt32("port");
173 
174 	SetTextControl(this,"host",host.String());
175 	SetTextControl(this,"user",archive->FindString("username"));
176 
177 	char *password = get_passwd(archive,"cpasswd");
178 	if (password) {
179 		SetTextControl(this,"pass",password);
180 		delete[] password;
181 	} else
182 		SetTextControl(this,"pass",archive->FindString("password"));
183 
184 	if (archive->HasInt32("flavor")) {
185 		BMenuField *menu = (BMenuField *)(FindView("flavor"));
186 		if (menu != NULL) {
187 			if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("flavor")))
188 				item->SetMarked(true);
189 		}
190 	}
191 
192 	if (archive->HasInt32("auth_method")) {
193 		BMenuField *menu = (BMenuField *)(FindView("auth_method"));
194 		if (menu != NULL) {
195 			if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("auth_method"))) {
196 				item->SetMarked(true);
197 				if (item->Command() != 'none') {
198 					enable_control("user");
199 					enable_control("pass");
200 				}
201 			}
202 		}
203 	}
204 
205 
206 	BCheckBox *box = (BCheckBox *)(FindView("leave_mail_remote"));
207 	if (box != NULL)
208 		box->SetValue(archive->FindBool("leave_mail_on_server") ? B_CONTROL_ON : B_CONTROL_OFF);
209 
210 	box = (BCheckBox *)(FindView("delete_remote_when_local"));
211 	if (box != NULL) {
212 		box->SetValue(archive->FindBool("delete_remote_when_local") ? B_CONTROL_ON : B_CONTROL_OFF);
213 
214 		if (archive->FindBool("leave_mail_on_server"))
215 			box->SetEnabled(true);
216 		else
217 			box->SetEnabled(false);
218 	}
219 }
220 
221 
222 void
223 BMailProtocolConfigView::AddFlavor(const char *label)
224 {
225 	BMenuField *menu = (BMenuField *)(FindView("flavor"));
226 	if (menu != NULL) {
227 		menu->Menu()->AddItem(new BMenuItem(label,NULL));
228 		if (menu->Menu()->FindMarked() == NULL)
229 			menu->Menu()->ItemAt(0)->SetMarked(true);
230 	}
231 }
232 
233 
234 void
235 BMailProtocolConfigView::AddAuthMethod(const char *label,bool needUserPassword)
236 {
237 	BMenuField *menu = (BMenuField *)(FindView("auth_method"));
238 	if (menu != NULL) {
239 		BMenuItem *item = new BMenuItem(label,new BMessage(needUserPassword ? 'some' : 'none'));
240 
241 		menu->Menu()->AddItem(item);
242 
243 		if (menu->Menu()->FindMarked() == NULL) {
244 			menu->Menu()->ItemAt(0)->SetMarked(true);
245 			MessageReceived(menu->Menu()->ItemAt(0)->Message());
246 		}
247 	}
248 }
249 
250 
251 void
252 BMailProtocolConfigView::AttachedToWindow()
253 {
254 	BMenuField *menu = (BMenuField *)(FindView("auth_method"));
255 	if (menu != NULL)
256 		menu->Menu()->SetTargetForItems(this);
257 
258 	BCheckBox *box = (BCheckBox *)(FindView("leave_mail_remote"));
259 	if (box != NULL)
260 		box->SetTarget(this);
261 }
262 
263 
264 void
265 BMailProtocolConfigView::MessageReceived(BMessage *msg)
266 {
267 	switch (msg->what) {
268 		case 'some':
269 			enable_control("user");
270 			enable_control("pass");
271 			break;
272 		case 'none':
273 			disable_control("user");
274 			disable_control("pass");
275 			break;
276 
277 		case 'lmos':
278 			if (msg->FindInt32("be:value") == 1) {
279 				enable_control("delete_remote_when_local");
280 			} else {
281 				disable_control("delete_remote_when_local");
282 			}
283 			break;
284 	}
285 }
286 
287 
288 status_t
289 BMailProtocolConfigView::Archive(BMessage *into, bool) const
290 {
291 	const char *host = TextControl((BView *)this,"host");
292 	int32 port = -1;
293 	BString host_name = host;
294 	if (host_name.FindFirst(':') > -1) {
295 		port = atol(host_name.String() + host_name.FindFirst(':') + 1);
296 		host_name.Truncate(host_name.FindFirst(':'));
297 	}
298 
299 	if (into->ReplaceString("server",host_name.String()) != B_OK)
300 		into->AddString("server",host_name.String());
301 
302 	// since there is no need for the port option, remove it here
303 	into->RemoveName("port");
304 	if (port != -1)
305 		into->AddInt32("port",port);
306 
307 	if (into->ReplaceString("username",TextControl((BView *)this,"user")) != B_OK)
308 		into->AddString("username",TextControl((BView *)this,"user"));
309 
310 	// remove old unencrypted passwords
311 	into->RemoveName("password");
312 
313 	set_passwd(into,"cpasswd",TextControl((BView *)this,"pass"));
314 
315 	BMenuField *field;
316 	int32 index = -1;
317 
318 	if ((field = (BMenuField *)(FindView("flavor"))) != NULL) {
319 		BMenuItem *item = field->Menu()->FindMarked();
320 		if (item != NULL)
321 			index = field->Menu()->IndexOf(item);
322 	}
323 
324 	if (into->ReplaceInt32("flavor",index) != B_OK)
325 		into->AddInt32("flavor",index);
326 
327 	index = -1;
328 
329 	if ((field = (BMenuField *)(FindView("auth_method"))) != NULL) {
330 		BMenuItem *item = field->Menu()->FindMarked();
331 		if (item != NULL)
332 			index = field->Menu()->IndexOf(item);
333 	}
334 
335 	if (into->ReplaceInt32("auth_method",index) != B_OK)
336 		into->AddInt32("auth_method",index);
337 
338 	if (FindView("leave_mail_remote") != NULL) {
339 		if (into->ReplaceBool("leave_mail_on_server",((BControl *)(FindView("leave_mail_remote")))->Value() == B_CONTROL_ON) != B_OK)
340 			into->AddBool("leave_mail_on_server",((BControl *)(FindView("leave_mail_remote")))->Value() == B_CONTROL_ON);
341 
342 		if (into->ReplaceBool("delete_remote_when_local",((BControl *)(FindView("delete_remote_when_local")))->Value() == B_CONTROL_ON) != B_OK)
343 			into->AddBool("delete_remote_when_local",((BControl *)(FindView("delete_remote_when_local")))->Value() == B_CONTROL_ON);
344 	} else {
345 		if (into->ReplaceBool("leave_mail_on_server",false) != B_OK)
346 			into->AddBool("leave_mail_on_server",false);
347 
348 		if (into->ReplaceBool("delete_remote_when_local",false) != B_OK)
349 			into->AddBool("delete_remote_when_local",false);
350 	}
351 
352 	return B_OK;
353 }
354 
355 
356 void
357 BMailProtocolConfigView::GetPreferredSize(float *width, float *height)
358 {
359 	float minWidth = 250;
360 	if (BView *view = FindView("delete_remote_when_local")) {
361 		float ignore;
362 		view->GetPreferredSize(&minWidth,&ignore);
363 	}
364 	if (minWidth < 250)
365 		minWidth = 250;
366 	*width = minWidth + 10;
367 	*height = (CountChildren() * sItemHeight) + 5;
368 }
369 
370