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