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