1 /*
2 * Copyright 2003-2004 Waldemar Kornewald. All rights reserved.
3 * Copyright 2017 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "DialUpView.h"
9 #include "DialUpAddon.h"
10
11 #include <cstring>
12 #include "InterfaceUtils.h"
13 #include "MessageDriverSettingsUtils.h"
14 #include "TextRequestDialog.h"
15
16 // built-in add-ons
17 #include "ConnectionOptionsAddon.h"
18 #include "GeneralAddon.h"
19 #include "IPCPAddon.h"
20 #include "PPPoEAddon.h"
21
22 #include <PPPInterface.h>
23 #include <settings_tools.h>
24 #include <TemplateList.h>
25
26 #include <Application.h>
27
28 #include <Alert.h>
29 #include <Button.h>
30 #include <MenuField.h>
31 #include <MenuItem.h>
32 #include <Messenger.h>
33 #include <PopUpMenu.h>
34 #include <LayoutBuilder.h>
35 #include <StringView.h>
36 #include <TabView.h>
37
38 #include <Directory.h>
39 #include <Entry.h>
40 #include <File.h>
41 #include <Path.h>
42
43
44 // message constants
45 static const uint32 kMsgCreateNew = 'NEWI';
46 static const uint32 kMsgFinishCreateNew = 'FNEW';
47 static const uint32 kMsgDeleteCurrent = 'DELI';
48 static const uint32 kMsgSelectInterface = 'SELI';
49 static const uint32 kMsgConnectButton = 'CONI';
50
51 // labels
52 static const char *kLabelInterface = "Interface: ";
53 static const char *kLabelInterfaceName = "Interface Name: ";
54 static const char *kLabelCreateNewInterface = "Create New Interface";
55 static const char *kLabelCreateNew = "Create New...";
56 static const char *kLabelDeleteCurrent = "Delete Current";
57 static const char *kLabelConnect = "Connect";
58 static const char *kLabelDisconnect = "Disconnect";
59 static const char *kLabelOK = "OK";
60
61 // connection status strings
62 static const char *kTextConnecting = "Connecting...";
63 static const char *kTextConnectionEstablished = "Connection established.";
64 static const char *kTextNotConnected = "Not connected.";
65 static const char *kTextDeviceUpFailed = "Failed to connect.";
66 static const char *kTextAuthenticating = "Authenticating...";
67 static const char *kTextAuthenticationFailed = "Authentication failed!";
68 static const char *kTextConnectionLost = "Connection lost!";
69 static const char *kTextCreationError = "Error creating interface!";
70 static const char *kTextNoInterfacesFound = "Please create a new interface...";
71 static const char *kTextChooseInterfaceName = "Please choose a new name for this "
72 "interface.";
73
74 // error strings for alerts
75 static const char *kErrorTitle = "Error";
76 static const char *kErrorNoPPPStack = "Error: Could not access the PPP stack!";
77 static const char *kErrorInterfaceExists = "Error: An interface with this name "
78 "already exists!";
79 static const char *kErrorLoadingFailed = "Error: Failed loading interface! The "
80 "current settings will be deleted.";
81 static const char *kErrorSavingFailed = "Error: Failed saving interface settings!";
82
83
84 static
85 status_t
up_down_thread(void * data)86 up_down_thread(void *data)
87 {
88 static_cast<DialUpView*>(data)->UpDownThread();
89 return B_OK;
90 }
91
92
DialUpView()93 DialUpView::DialUpView()
94 : BView("DialUpView", 0),
95 fListener(this),
96 fUpDownThread(-1),
97 fDriverSettings(NULL),
98 fCurrentItem(NULL),
99 fWatching(PPP_UNDEFINED_INTERFACE_ID),
100 fKeepLabel(false)
101 {
102 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
103
104 // add messenger to us so add-ons can contact us
105 BMessenger messenger(this);
106 fAddons.AddMessenger(DUN_MESSENGER, messenger);
107
108 // create pop-up with all interfaces and "New..."/"Delete current" items
109 fInterfaceMenu = new BPopUpMenu(kLabelCreateNew);
110 fMenuField = new BMenuField("Interfaces", kLabelInterface, fInterfaceMenu);
111
112 fTabView = new BTabView("TabView", B_WIDTH_FROM_LABEL);
113 BRect tabViewRect(fTabView->Bounds());
114 fAddons.AddRect(DUN_TAB_VIEW_RECT, tabViewRect); // FIXME: remove
115
116 fStringView = new BStringView("NoInterfacesFound",
117 kTextNoInterfacesFound);
118 fStringView->SetAlignment(B_ALIGN_CENTER);
119 fStringView->Hide();
120 fCreateNewButton = new BButton("CreateNewButton",
121 kLabelCreateNewInterface, new BMessage(kMsgCreateNew));
122 fCreateNewButton->Hide();
123
124 fStatusView = new BStringView("StatusView", kTextNotConnected);
125
126 fConnectButton = new BButton("ConnectButton", kLabelConnect,
127 new BMessage(kMsgConnectButton));
128
129 BLayoutBuilder::Group<>(this, B_VERTICAL)
130 .Add(fMenuField)
131 .Add(fTabView)
132 .Add(fStringView)
133 .Add(fCreateNewButton)
134 .AddGroup(B_HORIZONTAL)
135 .Add(fStatusView)
136 .AddGlue()
137 .Add(fConnectButton)
138 .End()
139 .End();
140
141 // initialize
142 LoadInterfaces();
143 LoadAddons();
144 CreateTabs();
145 fCurrentItem = NULL;
146 // reset, otherwise SelectInterface will not load the settings
147 SelectInterface(0);
148 UpdateControls();
149 }
150
151
~DialUpView()152 DialUpView::~DialUpView()
153 {
154 SaveSettingsToFile();
155
156 int32 tmp;
157 wait_for_thread(fUpDownThread, &tmp);
158
159 // free known add-on types (these should free their known add-on types, etc.)
160 DialUpAddon *addon;
161 for(int32 index = 0;
162 fAddons.FindPointer(DUN_DELETE_ON_QUIT, index,
163 reinterpret_cast<void**>(&addon)) == B_OK;
164 index++)
165 delete addon;
166 }
167
168
169 void
AttachedToWindow()170 DialUpView::AttachedToWindow()
171 {
172 fInterfaceMenu->SetTargetForItems(this);
173 fCreateNewButton->SetTarget(this);
174 fConnectButton->SetTarget(this);
175
176 if(fListener.InitCheck() != B_OK) {
177 (new BAlert(kErrorTitle, kErrorNoPPPStack, kLabelOK,
178 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL);
179 fConnectButton->Hide();
180 }
181 }
182
183
184 void
MessageReceived(BMessage * message)185 DialUpView::MessageReceived(BMessage *message)
186 {
187 switch(message->what) {
188 case PPP_REPORT_MESSAGE:
189 HandleReportMessage(message);
190 break;
191
192 // -------------------------------------------------
193 case kMsgCreateNew: {
194 (new TextRequestDialog(kLabelCreateNewInterface, kTextChooseInterfaceName,
195 kLabelInterfaceName))->Go(
196 new BInvoker(new BMessage(kMsgFinishCreateNew), this));
197 } break;
198
199 case kMsgFinishCreateNew: {
200 int32 which;
201 message->FindInt32("which", &which);
202 const char *name = message->FindString("text");
203 if(which == 1 && name && strlen(name) > 0)
204 AddInterface(name, true);
205
206 if(fCurrentItem)
207 fCurrentItem->SetMarked(true);
208 } break;
209 // -------------------------------------------------
210
211 case kMsgDeleteCurrent: {
212 if(!fCurrentItem)
213 return;
214
215 fInterfaceMenu->RemoveItem(fCurrentItem);
216 BDirectory settings, profile;
217 GetPPPDirectories(&settings, &profile);
218 BEntry entry;
219 settings.FindEntry(fCurrentItem->Label(), &entry);
220 entry.Remove();
221 profile.FindEntry(fCurrentItem->Label(), &entry);
222 entry.Remove();
223 delete fCurrentItem;
224 fCurrentItem = NULL;
225
226 BMenuItem *marked = fInterfaceMenu->FindMarked();
227 if(marked)
228 marked->SetMarked(false);
229
230 UpdateControls();
231 SelectInterface(0);
232 // this stops watching the deleted interface
233 } break;
234
235 case kMsgSelectInterface: {
236 int32 index;
237 message->FindInt32("index", &index);
238 SelectInterface(index);
239 } break;
240
241 case kMsgConnectButton: {
242 if(!fCurrentItem || fUpDownThread != -1)
243 return;
244
245 fUpDownThread = spawn_thread(up_down_thread, "up_down_thread",
246 B_NORMAL_PRIORITY, this);
247 resume_thread(fUpDownThread);
248 } break;
249
250 default:
251 BView::MessageReceived(message);
252 }
253 }
254
255
256 bool
SelectInterfaceNamed(const char * name)257 DialUpView::SelectInterfaceNamed(const char *name)
258 {
259 BMenuItem *item = fInterfaceMenu->FindItem(name);
260
261 int32 index = fInterfaceMenu->IndexOf(item);
262 if(!item || index >= CountInterfaces())
263 return false;
264
265 SelectInterface(index);
266
267 return true;
268 }
269
270
271 bool
NeedsRequest() const272 DialUpView::NeedsRequest() const
273 {
274 return fGeneralAddon ? fGeneralAddon->NeedsAuthenticationRequest() : false;
275 }
276
277
278 BView*
StatusView() const279 DialUpView::StatusView() const
280 {
281 return fStatusView;
282 }
283
284
285 BView*
ConnectButton() const286 DialUpView::ConnectButton() const
287 {
288 return fConnectButton;
289 }
290
291
292 bool
LoadSettings(bool isNew)293 DialUpView::LoadSettings(bool isNew)
294 {
295 fSettings.MakeEmpty();
296 fProfile.MakeEmpty();
297 BMessage *settingsPointer = fCurrentItem ? &fSettings : NULL,
298 *profilePointer = fCurrentItem ? &fProfile : NULL;
299
300 if(fCurrentItem && !isNew) {
301 BString name("pppidf/");
302 name << fCurrentItem->Label();
303 if(!ReadMessageDriverSettings(name.String(), &fSettings))
304 return false;
305 name = "pppidf/profile/";
306 name << fCurrentItem->Label();
307 if(!ReadMessageDriverSettings(name.String(), &fProfile))
308 profilePointer = settingsPointer;
309 }
310
311 DialUpAddon *addon;
312 for(int32 index = 0; fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index,
313 reinterpret_cast<void**>(&addon)) == B_OK; index++) {
314 if(!addon)
315 continue;
316
317 if(!addon->LoadSettings(settingsPointer, profilePointer, isNew))
318 return false;
319 }
320
321 // TODO: check if settings are valid
322
323 return true;
324 }
325
326
327 void
IsModified(bool * settings,bool * profile)328 DialUpView::IsModified(bool *settings, bool *profile)
329 {
330 *settings = *profile = false;
331 bool addonSettingsChanged, addonProfileChanged;
332 // for current addon
333
334 DialUpAddon *addon;
335 for(int32 index = 0; fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index,
336 reinterpret_cast<void**>(&addon)) == B_OK; index++) {
337 if(!addon)
338 continue;
339
340 addon->IsModified(&addonSettingsChanged, &addonProfileChanged);
341 if(addonSettingsChanged)
342 *settings = true;
343 if(addonProfileChanged)
344 *profile = true;
345 }
346 }
347
348
349 bool
SaveSettings(BMessage * settings,BMessage * profile,bool saveTemporary)350 DialUpView::SaveSettings(BMessage *settings, BMessage *profile, bool saveTemporary)
351 {
352 if(!fCurrentItem || !settings || !profile)
353 return false;
354
355 DialUpAddon *addon;
356 TemplateList<DialUpAddon*> addons;
357 for(int32 index = 0;
358 fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index,
359 reinterpret_cast<void**>(&addon)) == B_OK; index++) {
360 if(!addon)
361 continue;
362
363 int32 insertIndex = 0;
364 for(; insertIndex < addons.CountItems(); insertIndex++)
365 if(addons.ItemAt(insertIndex)->Priority() <= addon->Priority())
366 break;
367
368 addons.AddItem(addon, insertIndex);
369 }
370
371 settings->AddInt32("Interface", static_cast<int32>(fWatching));
372 if(fCurrentItem)
373 settings->AddString("InterfaceName", fCurrentItem->Label());
374
375 for(int32 index = 0; index < addons.CountItems(); index++)
376 if(!addons.ItemAt(index)->SaveSettings(settings, profile, saveTemporary))
377 return false;
378
379 return true;
380 }
381
382
383 bool
SaveSettingsToFile()384 DialUpView::SaveSettingsToFile()
385 {
386 bool settingsChanged, profileChanged;
387 IsModified(&settingsChanged, &profileChanged);
388 if(!settingsChanged && !profileChanged)
389 return true;
390
391 BMessage settings, profile;
392 if(!SaveSettings(&settings, &profile, false))
393 return false;
394
395 BDirectory settingsDirectory;
396 BDirectory profileDirectory;
397 GetPPPDirectories(&settingsDirectory, &profileDirectory);
398 if(settingsDirectory.InitCheck() != B_OK || profileDirectory.InitCheck() != B_OK)
399 return false;
400
401 BFile file;
402 if(settingsChanged) {
403 settingsDirectory.CreateFile(fCurrentItem->Label(), &file);
404 WriteMessageDriverSettings(file, settings);
405 }
406
407 if(profileChanged) {
408 profileDirectory.CreateFile(fCurrentItem->Label(), &file);
409 WriteMessageDriverSettings(file, profile);
410 }
411
412 return true;
413 }
414
415
416 void
UpDownThread()417 DialUpView::UpDownThread()
418 {
419 SaveSettingsToFile();
420 BMessage settings, profile;
421 SaveSettings(&settings, &profile, true);
422 // save temporary profile
423 //driver_settings *temporaryProfile = MessageToDriverSettings(profile);
424
425 PPPInterface interface;
426 if (fWatching == PPP_UNDEFINED_INTERFACE_ID) {
427 interface = fListener.Manager().InterfaceWithName(fCurrentItem->Label());
428 if(interface.InitCheck() != B_OK)
429 interface = fListener.Manager().CreateInterfaceWithName(
430 fCurrentItem->Label());
431 } else {
432 interface = fWatching;
433 //interface.SetProfile(temporaryProfile);
434 }
435
436 //free_driver_settings(temporaryProfile);
437
438 if(interface.InitCheck() != B_OK) {
439 Window()->Lock();
440 fStatusView->SetText(kTextCreationError);
441 Window()->Unlock();
442 return;
443 }
444
445 ppp_interface_info_t info;
446 interface.GetInterfaceInfo(&info);
447 if(info.info.phase == PPP_DOWN_PHASE)
448 interface.Up();
449 else
450 interface.Down();
451
452 fUpDownThread = -1;
453 }
454
455
456 #define PPP_INTERFACE_SETTINGS_PATH "" // FIXME!
457 void
GetPPPDirectories(BDirectory * settingsDirectory,BDirectory * profileDirectory) const458 DialUpView::GetPPPDirectories(BDirectory *settingsDirectory,
459 BDirectory *profileDirectory) const
460 {
461 if(settingsDirectory) {
462 BDirectory settings(PPP_INTERFACE_SETTINGS_PATH);
463 if(settings.InitCheck() != B_OK) {
464 create_directory(PPP_INTERFACE_SETTINGS_PATH, 0750);
465 settings.SetTo(PPP_INTERFACE_SETTINGS_PATH);
466 }
467
468 *settingsDirectory = settings;
469 }
470
471 if(profileDirectory) {
472 BDirectory profile(PPP_INTERFACE_SETTINGS_PATH "/profile");
473 if(profile.InitCheck() != B_OK) {
474 create_directory(PPP_INTERFACE_SETTINGS_PATH "/profile", 0750);
475 profile.SetTo(PPP_INTERFACE_SETTINGS_PATH "/profile");
476 }
477
478 *profileDirectory = profile;
479 }
480 }
481
482
483 void
HandleReportMessage(BMessage * message)484 DialUpView::HandleReportMessage(BMessage *message)
485 {
486 thread_id sender;
487 message->FindInt32("sender", &sender);
488
489 send_data(sender, B_OK, NULL, 0);
490
491 if(!fCurrentItem)
492 return;
493
494 ppp_interface_id id;
495 if(message->FindInt32("interface", reinterpret_cast<int32*>(&id)) != B_OK
496 || (fWatching != PPP_UNDEFINED_INTERFACE_ID && id != fWatching))
497 return;
498
499 int32 type, code;
500 message->FindInt32("type", &type);
501 message->FindInt32("code", &code);
502
503 if(type == PPP_MANAGER_REPORT && code == PPP_REPORT_INTERFACE_CREATED) {
504 PPPInterface interface(id);
505 if(interface.InitCheck() != B_OK)
506 return;
507
508 ppp_interface_info_t info;
509 interface.GetInterfaceInfo(&info);
510 if(strcasecmp(info.info.name, fCurrentItem->Label()))
511 return;
512
513 WatchInterface(id);
514 } else if(type == PPP_CONNECTION_REPORT) {
515 if(fWatching == PPP_UNDEFINED_INTERFACE_ID)
516 return;
517
518 UpdateStatus(code);
519 } else if(type == PPP_DESTRUCTION_REPORT) {
520 if(fWatching == PPP_UNDEFINED_INTERFACE_ID)
521 return;
522
523 WatchInterface(fListener.Manager().InterfaceWithName(fCurrentItem->Label()));
524 }
525 }
526
527
528 void
CreateTabs()529 DialUpView::CreateTabs()
530 {
531 // create tabs for all registered and valid tab add-ons
532 DialUpAddon *addon = NULL;
533 BView *target = NULL;
534 TemplateList<DialUpAddon*> addons;
535
536 for (int32 index = 0;
537 fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index,
538 reinterpret_cast<void**>(&addon)) == B_OK;
539 index++) {
540 if (!addon || addon->Position() < 0)
541 continue;
542
543 int32 insertIndex = 0;
544 for(; insertIndex < addons.CountItems(); insertIndex++) {
545 if (addons.ItemAt(insertIndex)->Position() > addon->Position())
546 break;
547 }
548
549 addons.AddItem(addon, insertIndex);
550 }
551
552 for (int32 index = 0; index < addons.CountItems(); index++) {
553 addon = addons.ItemAt(index);
554
555 target = addon->CreateView();
556 if (target == NULL)
557 continue;
558
559 fTabView->AddTab(target, NULL);
560 }
561 }
562
563
564 void
UpdateStatus(int32 code)565 DialUpView::UpdateStatus(int32 code)
566 {
567 switch(code) {
568 case PPP_REPORT_DEVICE_UP_FAILED:
569 case PPP_REPORT_AUTHENTICATION_FAILED:
570 case PPP_REPORT_DOWN_SUCCESSFUL:
571 case PPP_REPORT_CONNECTION_LOST: {
572 fConnectButton->SetLabel(kLabelConnect);
573 } break;
574
575 default:
576 fConnectButton->SetLabel(kLabelDisconnect);
577 }
578
579 // maybe the status string must not be changed (codes that set fKeepLabel to false
580 // should still be handled)
581 if(fKeepLabel && code != PPP_REPORT_GOING_UP && code != PPP_REPORT_UP_SUCCESSFUL)
582 return;
583
584 if(fListener.InitCheck() != B_OK) {
585 fStatusView->SetText(kErrorNoPPPStack);
586 return;
587 }
588
589 // only errors should set fKeepLabel to true
590 switch(code) {
591 case PPP_REPORT_GOING_UP:
592 fKeepLabel = false;
593 fStatusView->SetText(kTextConnecting);
594 break;
595
596 case PPP_REPORT_UP_SUCCESSFUL:
597 fKeepLabel = false;
598 fStatusView->SetText(kTextConnectionEstablished);
599 break;
600
601 case PPP_REPORT_DOWN_SUCCESSFUL:
602 fStatusView->SetText(kTextNotConnected);
603 break;
604
605 case PPP_REPORT_DEVICE_UP_FAILED:
606 fKeepLabel = true;
607 fStatusView->SetText(kTextDeviceUpFailed);
608 break;
609
610 case PPP_REPORT_AUTHENTICATION_REQUESTED:
611 fStatusView->SetText(kTextAuthenticating);
612 break;
613
614 case PPP_REPORT_AUTHENTICATION_FAILED:
615 fKeepLabel = true;
616 fStatusView->SetText(kTextAuthenticationFailed);
617 break;
618
619 case PPP_REPORT_CONNECTION_LOST:
620 fKeepLabel = true;
621 fStatusView->SetText(kTextConnectionLost);
622 break;
623 }
624 }
625
626
627 void
WatchInterface(ppp_interface_id ID)628 DialUpView::WatchInterface(ppp_interface_id ID)
629 {
630 // This method can be used to update the interface's connection status.
631
632 if(fWatching != ID) {
633 //fListener.StopWatchingInterfaces(); // FIXME
634
635 if(ID == PPP_UNDEFINED_INTERFACE_ID || fListener.WatchInterface(ID))
636 fWatching = ID;
637 }
638
639 // update status
640 PPPInterface interface(fWatching);
641 if(interface.InitCheck() != B_OK) {
642 UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL);
643 return;
644 }
645
646 ppp_interface_info_t info;
647 interface.GetInterfaceInfo(&info);
648
649 // transform phase into status
650 switch(info.info.phase) {
651 case PPP_DOWN_PHASE:
652 UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL);
653 break;
654
655 case PPP_TERMINATION_PHASE:
656 break;
657
658 case PPP_ESTABLISHED_PHASE:
659 UpdateStatus(PPP_REPORT_UP_SUCCESSFUL);
660 break;
661
662 default:
663 UpdateStatus(PPP_REPORT_GOING_UP);
664 }
665 }
666
667
668 void
LoadInterfaces()669 DialUpView::LoadInterfaces()
670 {
671 fInterfaceMenu->AddSeparatorItem();
672 fInterfaceMenu->AddItem(new BMenuItem(kLabelCreateNewInterface,
673 new BMessage(kMsgCreateNew)));
674 fDeleterItem = new BMenuItem(kLabelDeleteCurrent,
675 new BMessage(kMsgDeleteCurrent));
676 fInterfaceMenu->AddItem(fDeleterItem);
677
678 BDirectory settingsDirectory;
679 BEntry entry;
680 BPath path;
681 GetPPPDirectories(&settingsDirectory, NULL);
682 while(settingsDirectory.GetNextEntry(&entry) == B_OK) {
683 if(entry.IsFile()) {
684 entry.GetPath(&path);
685 AddInterface(path.Leaf(), true);
686 }
687 }
688 }
689
690
691 void
LoadAddons()692 DialUpView::LoadAddons()
693 {
694 // Load integrated add-ons:
695 // "Connection Options" tab
696 ConnectionOptionsAddon *connectionOptionsAddon =
697 new ConnectionOptionsAddon(&fAddons);
698 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, connectionOptionsAddon);
699 fAddons.AddPointer(DUN_DELETE_ON_QUIT, connectionOptionsAddon);
700 // "General" tab
701 GeneralAddon *fGeneralAddon = new GeneralAddon(&fAddons);
702 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, fGeneralAddon);
703 fAddons.AddPointer(DUN_DELETE_ON_QUIT, fGeneralAddon);
704
705 // "IPCP" protocol
706 IPCPAddon *ipcpAddon = new IPCPAddon(&fAddons);
707 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, ipcpAddon);
708 fAddons.AddPointer(DUN_DELETE_ON_QUIT, ipcpAddon);
709 // "PPPoE" device
710 PPPoEAddon *pppoeAddon = new PPPoEAddon(&fAddons);
711 fAddons.AddPointer(DUN_DEVICE_ADDON_TYPE, pppoeAddon);
712 fAddons.AddPointer(DUN_DELETE_ON_QUIT, pppoeAddon);
713
714 // "PAP" authenticator
715 BMessage addon;
716 addon.AddString("FriendlyName", "Plain-text Authentication");
717 addon.AddString("TechnicalName", "PAP");
718 addon.AddString("KernelModuleName", "pap");
719 fAddons.AddMessage(DUN_AUTHENTICATOR_ADDON_TYPE, &addon);
720 // addon.MakeEmpty(); // for next authenticator
721
722 // TODO:
723 // load all add-ons from the add-ons folder
724 }
725
726
727 void
AddInterface(const char * name,bool isNew)728 DialUpView::AddInterface(const char *name, bool isNew)
729 {
730 if(fInterfaceMenu->FindItem(name)) {
731 (new BAlert(kErrorTitle, kErrorInterfaceExists, kLabelOK,
732 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL);
733 return;
734 }
735
736 BMenuItem *item = new BMenuItem(name, new BMessage(kMsgSelectInterface));
737 item->SetTarget(this);
738 int32 index = FindNextMenuInsertionIndex(fInterfaceMenu, name);
739 if(index > CountInterfaces())
740 index = CountInterfaces();
741 fInterfaceMenu->AddItem(item, index);
742 UpdateControls();
743
744 item->SetMarked(true);
745 SelectInterface(index, isNew);
746 }
747
748
749 void
SelectInterface(int32 index,bool isNew)750 DialUpView::SelectInterface(int32 index, bool isNew)
751 {
752 BMenuItem *item = fInterfaceMenu->FindMarked();
753 if(fCurrentItem && item == fCurrentItem)
754 return;
755
756 if(fCurrentItem && !SaveSettingsToFile())
757 (new BAlert(kErrorTitle, kErrorSavingFailed, kLabelOK,
758 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL);
759
760 if(index >= CountInterfaces() || index < 0) {
761 if(CountInterfaces() > 0)
762 SelectInterface(0);
763 else {
764 fCurrentItem = NULL;
765 WatchInterface(PPP_UNDEFINED_INTERFACE_ID);
766 }
767 } else {
768 fCurrentItem = fInterfaceMenu->ItemAt(index);
769 if(!fCurrentItem) {
770 SelectInterface(0);
771 return;
772 }
773
774 fCurrentItem->SetMarked(true);
775 fDeleterItem->SetEnabled(true);
776 WatchInterface(fListener.Manager().InterfaceWithName(fCurrentItem->Label()));
777 }
778
779 if(!fCurrentItem)
780 LoadSettings(false);
781 // tell modules to unload all settings
782 else if(!isNew && !LoadSettings(false)) {
783 (new BAlert(kErrorTitle, kErrorLoadingFailed, kLabelOK,
784 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL);
785 LoadSettings(true);
786 } else if(isNew && !LoadSettings(true))
787 (new BAlert(kErrorTitle, kErrorLoadingFailed, kLabelOK,
788 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL);
789 }
790
791
792 int32
CountInterfaces() const793 DialUpView::CountInterfaces() const
794 {
795 return fInterfaceMenu->CountItems() - 3;
796 }
797
798
799 void
UpdateControls()800 DialUpView::UpdateControls()
801 {
802 if(fTabView->IsHidden() && CountInterfaces() > 0) {
803 fInterfaceMenu->SetLabelFromMarked(true);
804 fStringView->Hide();
805 fCreateNewButton->Hide();
806 fTabView->Show();
807 fConnectButton->SetEnabled(true);
808 } else if(!fTabView->IsHidden() && CountInterfaces() == 0) {
809 fDeleterItem->SetEnabled(false);
810 fInterfaceMenu->SetRadioMode(false);
811 fInterfaceMenu->Superitem()->SetLabel(kLabelCreateNew);
812 fTabView->Hide();
813 fStringView->Show();
814 fCreateNewButton->Show();
815 fConnectButton->SetEnabled(false);
816 }
817 }
818