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