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