Add input validation in Network preflet.

Now, if the user attempt to enter an invalid IPv4 address in a field, when he clicks apply :
* the focus goes back to the invalid field
* it displays an error message into the window, at the bottom
* it beeps
* it doesn't save the change, of course

DNS #2 is consider optional.  The check is made with a regex.

This should take care of ticket #4205.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32370 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Saint-Pierre 2009-08-14 15:49:07 +00:00
parent 1c8695a627
commit 4551e0670f
2 changed files with 58 additions and 1 deletions

View File

@ -7,6 +7,7 @@
* Stephan Assmuß
* Axel Dörfler
* Hugo Santos
* Philippe Saint-Pierre
*/
#include "EthernetSettingsView.h"
@ -59,6 +60,8 @@
#include <NetServer.h>
#include <support/Beep.h>
#include "AutoDeleter.h"
@ -164,6 +167,13 @@ EthernetSettingsView::EthernetSettingsView()
layout->AddItem(fSecondaryDNSTextControl->CreateLabelLayoutItem(), 0, 6);
layout->AddItem(fSecondaryDNSTextControl->CreateTextViewLayoutItem(), 1, 6);
fErrorMessage = new BStringView("error", "");
fErrorMessage->SetAlignment(B_ALIGN_LEFT);
fErrorMessage->SetFont(be_bold_font);
fErrorMessage->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
layout->AddView(fErrorMessage, 1, 7);
// button group (TODO: move to window, but take care of
// enabling/disabling)
BGroupView* buttonGroup = new BGroupView(B_HORIZONTAL);
@ -486,6 +496,38 @@ EthernetSettingsView::_GetPath(const char* name, BPath& path)
}
bool
MatchPattern(const char* string, const char* pattern)
{
regex_t compiled;
bool result = regcomp(&compiled, pattern, REG_NOSUB | REG_EXTENDED) == 0
&& regexec(&compiled, string, 0, NULL, 0) == 0;
regfree(&compiled);
return result;
}
bool
EthernetSettingsView::_ValidateControl(BTextControl* control)
{
static const char* pattern = "^(25[0-5]|2[0-4][0-9]|[01][0-9]{2}|[0-9]"
"{1,2})(\\.(25[0-5]|2[0-4][0-9]|[01][0-9]{2}|[0-9]{1,2})){3}$";
if (control->IsEnabled() && !MatchPattern(control->Text(), pattern)) {
control->MakeFocus();
BString errorMessage;
errorMessage << control->Label();
errorMessage.RemoveLast(":");
errorMessage << " is invalid";
fErrorMessage->SetText(errorMessage.String());
beep();
return false;
}
return true;
}
void
EthernetSettingsView::MessageReceived(BMessage* message)
{
@ -514,9 +556,16 @@ EthernetSettingsView::MessageReceived(BMessage* message)
fRevertButton->SetEnabled(false);
break;
case kMsgApply:
_SaveConfiguration();
if (_ValidateControl(fIPTextControl)
&& _ValidateControl(fNetMaskTextControl)
&& _ValidateControl(fGatewayTextControl)
&& _ValidateControl(fPrimaryDNSTextControl)
&& (strlen(fSecondaryDNSTextControl->Text()) == 0
|| _ValidateControl(fSecondaryDNSTextControl)))
_SaveConfiguration();
break;
case kMsgChange:
fErrorMessage->SetText("");
fApplyButton->SetEnabled(true);
break;
default:

View File

@ -16,10 +16,13 @@
#include <ObjectList.h>
#include <View.h>
#include <posix/regex.h>
class BButton;
class BMenuField;
class BPath;
class BTextControl;
class BStringView;
class EthernetSettingsView : public BView {
@ -46,6 +49,8 @@ private:
void _ApplyControlsToConfiguration();
status_t _GetPath(const char* name, BPath& path);
status_t _TriggerAutoConfig(const char* device);
bool _ValidateControl(BTextControl* control);
private:
BButton* fApplyButton;
@ -60,6 +65,9 @@ private:
BTextControl* fPrimaryDNSTextControl;
BTextControl* fSecondaryDNSTextControl;
BStringView* fErrorMessage;
// TODO: DNS settings do not belong here, do they?
BObjectList<BString> fInterfaces;
// TODO: the view should not know about the interfaces,