1/* 2 * Copyright 2003-2005, Waldemar Kornewald <wkornew@gmx.net> 3 * Distributed under the terms of the MIT License. 4 */ 5 6//----------------------------------------------------------------------- 7// IPCPAddon saves the loaded settings. 8// IPCPView saves the current settings. 9//----------------------------------------------------------------------- 10 11#include "IPCPAddon.h" 12 13#include "MessageDriverSettingsUtils.h" 14#include <stl_algobase.h> 15 // for max() 16 17#include <StringView.h> 18 19#include <PPPDefs.h> 20#include <IPCP.h> 21 // from IPCP addon 22 23 24// GUI constants 25static const uint32 kDefaultButtonWidth = 80; 26 27// message constants 28static const uint32 kMsgUpdateControls = 'UCTL'; 29 30// labels 31static const char *kLabelIPCP = "TCP/IP"; 32static const char *kLabelIPAddress = "IP Address: "; 33static const char *kLabelPrimaryDNS = "Primary DNS: "; 34static const char *kLabelSecondaryDNS = "Secondary DNS: "; 35static const char *kLabelOptional = "(Optional)"; 36static const char *kLabelExtendedOptions = "Extended Options:"; 37static const char *kLabelEnabled = "Enable TCP/IP Protocol"; 38 39// add-on descriptions 40static const char *kKernelModuleName = "ipcp"; 41 42 43IPCPAddon::IPCPAddon(BMessage *addons) 44 : DialUpAddon(addons), 45 fSettings(NULL), 46 fIPCPView(NULL) 47{ 48 CreateView(BPoint(0,0)); 49 fDeleteView = true; 50} 51 52 53IPCPAddon::~IPCPAddon() 54{ 55 if(fDeleteView) 56 delete fIPCPView; 57} 58 59 60bool 61IPCPAddon::LoadSettings(BMessage *settings, bool isNew) 62{ 63 fIsNew = isNew; 64 fIsEnabled = false; 65 fIPAddress = fPrimaryDNS = fSecondaryDNS = ""; 66 fSettings = settings; 67 68 fIPCPView->Reload(); 69 // reset all views (empty settings) 70 71 if(!settings || isNew) 72 return true; 73 74 BMessage protocol; 75 76 int32 protocolIndex = FindIPCPProtocol(*fSettings, &protocol); 77 if(protocolIndex < 0) 78 return true; 79 80 protocol.AddBool(MDSU_VALID, true); 81 fSettings->ReplaceMessage(MDSU_PARAMETERS, protocolIndex, &protocol); 82 83 fIsEnabled = true; 84 85 // the "Local" side parameter 86 BMessage local; 87 int32 localSideIndex = 0; 88 if(!FindMessageParameter(IPCP_LOCAL_SIDE_KEY, protocol, &local, &localSideIndex)) 89 local.MakeEmpty(); 90 // just fall through and pretend we have an empty "Local" side parameter 91 92 // now load the supported parameters (the client-relevant subset) 93 BString name; 94 BMessage parameter; 95 int32 index = 0; 96 if(!FindMessageParameter(IPCP_IP_ADDRESS_KEY, local, ¶meter, &index) 97 || parameter.FindString(MDSU_VALUES, &fIPAddress) != B_OK) 98 fIPAddress = ""; 99 else { 100 if(fIPAddress == "auto") 101 fIPAddress = ""; 102 103 parameter.AddBool(MDSU_VALID, true); 104 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter); 105 } 106 107 index = 0; 108 if(!FindMessageParameter(IPCP_PRIMARY_DNS_KEY, local, ¶meter, &index) 109 || parameter.FindString(MDSU_VALUES, &fPrimaryDNS) != B_OK) 110 fPrimaryDNS = ""; 111 else { 112 if(fPrimaryDNS == "auto") 113 fPrimaryDNS = ""; 114 115 parameter.AddBool(MDSU_VALID, true); 116 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter); 117 } 118 119 index = 0; 120 if(!FindMessageParameter(IPCP_SECONDARY_DNS_KEY, local, ¶meter, &index) 121 || parameter.FindString(MDSU_VALUES, &fSecondaryDNS) != B_OK) 122 fSecondaryDNS = ""; 123 else { 124 if(fSecondaryDNS == "auto") 125 fSecondaryDNS = ""; 126 127 parameter.AddBool(MDSU_VALID, true); 128 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter); 129 } 130 131 local.AddBool(MDSU_VALID, true); 132 protocol.ReplaceMessage(MDSU_PARAMETERS, localSideIndex, &local); 133 protocol.AddBool(MDSU_VALID, true); 134 fSettings->ReplaceMessage(MDSU_PARAMETERS, protocolIndex, &protocol); 135 136 fIPCPView->Reload(); 137 138 return true; 139} 140 141 142void 143IPCPAddon::IsModified(bool *settings) const 144{ 145 if(!fSettings) { 146 *settings = false; 147 return; 148 } 149 150 *settings = (fIsEnabled != fIPCPView->IsEnabled() 151 || fIPAddress != fIPCPView->IPAddress() 152 || fPrimaryDNS != fIPCPView->PrimaryDNS() 153 || fSecondaryDNS != fIPCPView->SecondaryDNS()); 154} 155 156 157bool 158IPCPAddon::SaveSettings(BMessage *settings) 159{ 160 if(!fSettings || !settings) 161 return false; 162 163 if(!fIPCPView->IsEnabled()) 164 return true; 165 166 BMessage protocol, local; 167 protocol.AddString(MDSU_NAME, PPP_PROTOCOL_KEY); 168 protocol.AddString(MDSU_VALUES, kKernelModuleName); 169 // the settings contain a simple "protocol ipcp" string 170 171 // now create the settings with all subparameters 172 local.AddString(MDSU_NAME, IPCP_LOCAL_SIDE_KEY); 173 bool needsLocal = false; 174 175 if(fIPCPView->IPAddress() && strlen(fIPCPView->IPAddress()) > 0) { 176 // save IP address, too 177 needsLocal = true; 178 BMessage ip; 179 ip.AddString(MDSU_NAME, IPCP_IP_ADDRESS_KEY); 180 ip.AddString(MDSU_VALUES, fIPCPView->IPAddress()); 181 local.AddMessage(MDSU_PARAMETERS, &ip); 182 } 183 184 if(fIPCPView->PrimaryDNS() && strlen(fIPCPView->PrimaryDNS()) > 0) { 185 // save service name, too 186 needsLocal = true; 187 BMessage dns; 188 dns.AddString(MDSU_NAME, IPCP_PRIMARY_DNS_KEY); 189 dns.AddString(MDSU_VALUES, fIPCPView->PrimaryDNS()); 190 local.AddMessage(MDSU_PARAMETERS, &dns); 191 } 192 193 if(fIPCPView->SecondaryDNS() && strlen(fIPCPView->SecondaryDNS()) > 0) { 194 // save service name, too 195 needsLocal = true; 196 BMessage dns; 197 dns.AddString(MDSU_NAME, IPCP_SECONDARY_DNS_KEY); 198 dns.AddString(MDSU_VALUES, fIPCPView->SecondaryDNS()); 199 local.AddMessage(MDSU_PARAMETERS, &dns); 200 } 201 202 if(needsLocal) 203 protocol.AddMessage(MDSU_PARAMETERS, &local); 204 205 settings->AddMessage(MDSU_PARAMETERS, &protocol); 206 207 return true; 208} 209 210 211bool 212IPCPAddon::GetPreferredSize(float *width, float *height) const 213{ 214 BRect rect; 215 if(Addons()->FindRect(DUN_TAB_VIEW_RECT, &rect) != B_OK) 216 rect.Set(0, 0, 200, 300); 217 // set default values 218 219 if(width) 220 *width = rect.Width(); 221 if(height) 222 *height = rect.Height(); 223 224 return true; 225} 226 227 228BView* 229IPCPAddon::CreateView(BPoint leftTop) 230{ 231 if(!fIPCPView) { 232 BRect rect; 233 Addons()->FindRect(DUN_TAB_VIEW_RECT, &rect); 234 fIPCPView = new IPCPView(this, rect); 235 } 236 237 fDeleteView = false; 238 239 fIPCPView->MoveTo(leftTop); 240 fIPCPView->Reload(); 241 return fIPCPView; 242} 243 244 245int32 246IPCPAddon::FindIPCPProtocol(const BMessage& message, BMessage *protocol) const 247{ 248 if(!protocol) 249 return -1; 250 251 BString name; 252 for(int32 index = 0; FindMessageParameter(PPP_PROTOCOL_KEY, message, protocol, 253 &index); index++) 254 if(protocol->FindString(MDSU_VALUES, &name) == B_OK 255 && name == kKernelModuleName) 256 return index; 257 258 return -1; 259} 260 261 262IPCPView::IPCPView(IPCPAddon *addon, BRect frame) 263 : BView(frame, kLabelIPCP, B_FOLLOW_NONE, 0), 264 fAddon(addon) 265{ 266 BRect rect = Bounds(); 267 rect.InsetBy(10, 10); 268 rect.bottom = rect.top + 20; 269 BRect optionalRect(rect); 270 rect.right -= 75; 271 fIPAddress = new BTextControl(rect, "ip", kLabelIPAddress, NULL, NULL); 272 optionalRect.left = rect.right + 5; 273 optionalRect.bottom = optionalRect.top + 15; 274 AddChild(new BStringView(optionalRect, "optional_1", kLabelOptional)); 275 rect.top = rect.bottom + 5; 276 rect.bottom = rect.top + 20; 277 fPrimaryDNS = new BTextControl(rect, "primaryDNS", kLabelPrimaryDNS, NULL, NULL); 278 optionalRect.top = rect.top; 279 optionalRect.bottom = optionalRect.top + 15; 280 AddChild(new BStringView(optionalRect, "optional_2", kLabelOptional)); 281 rect.top = rect.bottom + 5; 282 rect.bottom = rect.top + 20; 283 fSecondaryDNS = new BTextControl(rect, "secondaryDNS", kLabelSecondaryDNS, NULL, 284 NULL); 285 optionalRect.top = rect.top; 286 optionalRect.bottom = optionalRect.top + 15; 287 AddChild(new BStringView(optionalRect, "optional_3", kLabelOptional)); 288 rect.top = rect.bottom + 50; 289 rect.bottom = rect.top + 10; 290 AddChild(new BStringView(rect, "expert", kLabelExtendedOptions)); 291 rect.top = rect.bottom + 5; 292 rect.bottom = rect.top + 15; 293 fIsEnabled = new BCheckBox(rect, "isEnabled", kLabelEnabled, 294 new BMessage(kMsgUpdateControls)); 295 296 // set divider of text controls 297 float controlWidth = max(max(StringWidth(fIPAddress->Label()), 298 StringWidth(fPrimaryDNS->Label())), StringWidth(fSecondaryDNS->Label())); 299 fIPAddress->SetDivider(controlWidth + 5); 300 fPrimaryDNS->SetDivider(controlWidth + 5); 301 fSecondaryDNS->SetDivider(controlWidth + 5); 302 303 AddChild(fIsEnabled); 304 AddChild(fIPAddress); 305 AddChild(fPrimaryDNS); 306 AddChild(fSecondaryDNS); 307} 308 309 310void 311IPCPView::Reload() 312{ 313 fIsEnabled->SetValue(Addon()->IsEnabled() || Addon()->IsNew()); 314 // enable TCP/IP by default 315 fIPAddress->SetText(Addon()->IPAddress()); 316 fPrimaryDNS->SetText(Addon()->PrimaryDNS()); 317 fSecondaryDNS->SetText(Addon()->SecondaryDNS()); 318 319 UpdateControls(); 320} 321 322 323void 324IPCPView::AttachedToWindow() 325{ 326 SetViewColor(Parent()->ViewColor()); 327 fIsEnabled->SetTarget(this); 328} 329 330 331void 332IPCPView::MessageReceived(BMessage *message) 333{ 334 switch(message->what) { 335 case kMsgUpdateControls: 336 UpdateControls(); 337 break; 338 339 default: 340 BView::MessageReceived(message); 341 } 342} 343 344 345void 346IPCPView::UpdateControls() 347{ 348 fIPAddress->SetEnabled(IsEnabled()); 349 fPrimaryDNS->SetEnabled(IsEnabled()); 350 fSecondaryDNS->SetEnabled(IsEnabled()); 351} 352