//
// $Source: /cvsroot/gambit/gambit/sources/gui/valnumber.cc,v $
// $Date: 2006/01/11 15:27:14 $
// $Revision: 1.14 $
//
// DESCRIPTION:
// wxValidator specialization to gbtNumber
//
// This file is part of Gambit
// Copyright (c) 2002, The Gambit Project
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif // WX_PRECOMP
#include "libgambit/libgambit.h"
#include "valnumber.h"
BEGIN_EVENT_TABLE(gbtNumberValidator, wxValidator)
EVT_CHAR(gbtNumberValidator::OnChar)
END_EVENT_TABLE()
static bool IsNumeric(const wxString &p_value)
{
bool seenDigit = false, seenSeparator = false;
for (int i = 0; i < (int) p_value.Length(); i++) {
if (isdigit(p_value[i])) {
seenDigit = true;
continue;
}
else if ((p_value[i] == '.' && !seenSeparator) ||
(p_value[i] == '/' && !seenSeparator && seenDigit)) {
seenSeparator = true;
continue;
}
else if (i == 0 && p_value[i] == '-') {
continue;
}
return false;
}
if (p_value[p_value.Length() - 1] == '/') {
return false;
}
else {
return true;
}
}
//------------------------------------------------------------------------
// class gbtNumberValidator: Member functions
//------------------------------------------------------------------------
gbtNumberValidator::gbtNumberValidator(wxString *p_value)
: m_stringValue(p_value), m_hasMin(false), m_hasMax(false)
{ }
gbtNumberValidator::gbtNumberValidator(wxString *p_value,
const Gambit::Rational &p_minValue)
: m_stringValue(p_value), m_hasMin(true), m_hasMax(false),
m_minValue(p_minValue)
{ }
gbtNumberValidator::gbtNumberValidator(wxString *p_value,
const Gambit::Rational &p_minValue,
const Gambit::Rational &p_maxValue)
: m_stringValue(p_value), m_hasMin(true), m_hasMax(true),
m_minValue(p_minValue), m_maxValue(p_maxValue)
{ }
gbtNumberValidator::gbtNumberValidator(const gbtNumberValidator &p_validator)
{
Copy(p_validator);
}
bool gbtNumberValidator::Copy(const gbtNumberValidator &p_validator)
{
wxValidator::Copy(p_validator);
m_stringValue = p_validator.m_stringValue;
m_hasMin = p_validator.m_hasMin;
m_hasMax = p_validator.m_hasMax;
m_minValue = p_validator.m_minValue;
m_maxValue = p_validator.m_maxValue;
return true;
}
bool gbtNumberValidator::Validate(wxWindow *p_parent)
{
if (!m_stringValue) {
return false;
}
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
if (!control->IsEnabled()) {
return true;
}
wxString value(control->GetValue());
if (!IsNumeric(value)) {
wxMessageBox(_T("The value ") + value + _T(" in ") +
m_validatorWindow->GetName() + _T(" is not a valid number."),
_("Error"), wxOK | wxICON_EXCLAMATION, p_parent);
m_validatorWindow->SetFocus();
return false;
}
if ((m_hasMin && Gambit::ToNumber((const char *) value.mb_str()) < m_minValue) ||
(m_hasMax && Gambit::ToNumber((const char *) value.mb_str()) > m_maxValue)) {
wxMessageBox(_T("The value ") + value + _T(" in ") +
m_validatorWindow->GetName() + _T(" is out of the range [") +
wxString(ToText(m_minValue).c_str(), *wxConvCurrent) + _T(", ") +
wxString(ToText(m_maxValue).c_str(), *wxConvCurrent) + _T("]."),
_("Error"), wxOK | wxICON_EXCLAMATION, p_parent);
m_validatorWindow->SetFocus();
return false;
}
return true;
}
bool gbtNumberValidator::TransferToWindow(void)
{
if (!m_stringValue) {
return false;
}
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
control->SetValue(*m_stringValue);
return true;
}
bool gbtNumberValidator::TransferFromWindow(void)
{
if (!m_stringValue) {
return false;
}
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
*m_stringValue = control->GetValue();
return TRUE;
}
void gbtNumberValidator::OnChar(wxKeyEvent &p_event)
{
if (m_validatorWindow) {
int keyCode = (int) p_event.GetKeyCode();
// we don't filter special keys and Delete
if (!(keyCode < WXK_SPACE || keyCode == WXK_DELETE ||
keyCode > WXK_START) &&
(!isdigit(keyCode) &&
keyCode != '.' && keyCode != '-' && keyCode != '/')) {
if (!wxValidator::IsSilent()) {
wxBell();
}
return;
}
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
wxString value = control->GetValue();
if ((keyCode == '.' || keyCode == '/') &&
(value.Find('.') != -1 || value.Find('/') != -1)) {
// At most one slash or decimal point is allowed
if (!wxValidator::IsSilent()) wxBell();
return;
}
if (keyCode == '/' &&
(control->GetInsertionPoint() == 0 ||
(control->GetInsertionPoint() == 1 && value == wxT("-")))) {
// Can't start with a slash
if (!wxValidator::IsSilent()) wxBell();
return;
}
if (keyCode == '-') {
// Only permit minus signs at the start of the text
long start, end;
control->GetSelection(&start, &end);
if (start == end) {
// No selection; just see if inserting is OK
if (control->GetInsertionPoint() != 0) {
if (!wxValidator::IsSilent()) wxBell();
return;
}
}
else {
// There is a selection; is selection at beginning?
if (start != 0) {
if (!wxValidator::IsSilent()) wxBell();
return;
}
}
}
}
p_event.Skip();
}
syntax highlighted by Code2HTML, v. 0.9.1