--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbwidgets/editors/hbvalidator_p.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbWidgets module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbvalidator_p.h"
+#include <QTextDocument>
+#include <QTextCursor>
+#include <QDebug>
+#include <QtAlgorithms>
+
+#ifdef HBVALIDATOR_DEBUG_ENABLE
+#define VALIDATORDEBUG(x) printFields(x)
+#else
+#define VALIDATORDEBUG(x)
+#endif
+
+HbValidatorPrivate::HbValidatorPrivate() :
+ separatorToAdd("/")
+{
+}
+
+void HbValidatorPrivate::init()
+{
+ // no implemantation needed
+}
+
+void HbValidatorPrivate::clear()
+{
+ deleteAllFields();
+}
+
+void HbValidatorPrivate::addField(const QString &separator, QValidator *validator, const QString &defaultValue)
+{
+ if(!fields.isEmpty()) {
+ // set separator between this and previous field
+ fields.back()->mNextSeparator = separator;
+ }
+
+ // creating new filed
+ HbValidatorField *newField = new HbValidatorField();
+ fields.append(newField);
+
+ newField->mDefaultValue = defaultValue;
+ newField->mValidator = validator;
+}
+
+QValidator::State HbValidatorPrivate::validateText(const QTextDocument *doc)
+{
+ QValidator::State state = QValidator::Acceptable;
+ int lastSeparatorPos = 0;
+ QTextCursor suportCursor;
+
+ foreach(HbValidatorField* field, fields) {
+ int separatorPos;
+
+ if(!field->mNextSeparator.isEmpty()) {
+ suportCursor = doc->find(field->mNextSeparator, lastSeparatorPos, QTextDocument::FindCaseSensitively);
+ if(suportCursor.isNull()) {
+ // parsing failed
+ return QValidator::Invalid;
+ }
+ separatorPos = suportCursor.anchor();
+ } else {
+ // last posible cursor position
+ separatorPos = doc->characterCount()-1;
+ Q_ASSERT_X(separatorPos == doc->toPlainText().length(),
+ "HbValidatorPrivate::validateText",
+ "problems with QTextDocument::characterCount (to big value)");
+ }
+
+ // select field:
+ QTextCursor toValidate(const_cast<QTextDocument *>(doc));
+ toValidate.setPosition(lastSeparatorPos);
+ toValidate.setPosition(separatorPos, QTextCursor::KeepAnchor);
+
+ QString fieldText = toValidate.selectedText();
+ int cursorPos = fieldText.length();
+ QValidator::State fieldState = field->mValidator->validate(fieldText, cursorPos);
+
+ // maybe here changes done by field validator shold be copied to document using QTextCursor toValidate?
+ // in this case const from method argument should be removed
+
+ if(fieldState<state) {
+ state = fieldState;
+ }
+
+ if(state == QValidator::Invalid) {
+ break;
+ }
+
+ // position of cursor after separator
+ lastSeparatorPos = suportCursor.position();
+ }
+
+ return state;
+}
+
+int HbValidatorPrivate::findFieldIndexUnderCursorPos(const QTextCursor &cursor)
+{
+ const int cursorPosition(cursor.position());
+ const int lastFieldIndex(fields.count()-1);
+ int findFrom = 0;
+ int i;
+
+ QTextDocument *doc = cursor.document();
+ for(i = 0; i<lastFieldIndex; ++i) {
+ QTextCursor separatorFound = doc->find(fields.at(i)->mNextSeparator, findFrom, QTextDocument::FindCaseSensitively);
+ if(separatorFound.isNull()) {
+ return -1;
+ }
+ findFrom = separatorFound.position();
+ if(findFrom>cursorPosition) {
+ break;
+ }
+ }
+ return i;
+}
+
+bool HbValidatorPrivate::fieldHasSelection(int fieldIndex, const QTextCursor &cursor)
+{
+ if(!cursor.hasSelection()) {
+ return false;
+ }
+
+ const int lastFieldIndex = fields.count() - 1;
+
+ Q_ASSERT( fieldIndex >= 0 );
+ Q_ASSERT( fieldIndex <= lastFieldIndex );
+
+ const int cursorBegin = qMin(cursor.position(), cursor.anchor());
+ const int cursorEnd = qMax(cursor.position(), cursor.anchor());
+
+ // cheching left side of cursor
+ if(fieldIndex==0) {// boundary condition (front):
+ if(cursorBegin != 0) {
+ return false;
+ }
+ } else { // normal check
+ QTextCursor supportCursor = cursor.document()->find(
+ fields.at(fieldIndex-1)->mNextSeparator,
+ cursorBegin,
+ QTextDocument::FindCaseSensitively | QTextDocument::FindBackward);
+ Q_ASSERT(!supportCursor.isNull());
+ if( supportCursor.position() != cursorBegin) {
+ return false;
+ }
+ }
+
+ // checking right side of cursor
+ if(fieldIndex==lastFieldIndex) { // boundary condition (tail):
+ if( cursorEnd != cursor.document()->characterCount()-1 ) {
+ return false;
+ }
+ } else { // normal check
+ QTextCursor supportCursor = cursor.document()->find(
+ fields.at(fieldIndex)->mNextSeparator,
+ cursorEnd,
+ QTextDocument::FindCaseSensitively);
+ Q_ASSERT(!supportCursor.isNull());
+ if( supportCursor.anchor() != cursorEnd) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void HbValidatorPrivate::highlightField(QTextCursor* cursor, int fieldIndex)
+{
+ const int lastFieldIndex = fields.count() - 1;
+
+ Q_ASSERT( fieldIndex >= 0 );
+ Q_ASSERT( fieldIndex <= lastFieldIndex );
+
+ QTextDocument *doc = cursor->document();
+ int lastFind = 0;
+ for(int i=0; i<fieldIndex; ++i) {
+ lastFind = doc->find(
+ fields.at(i)->mNextSeparator,
+ lastFind,
+ QTextDocument::FindCaseSensitively ).position();
+ }
+ cursor->setPosition(lastFind);
+
+ if(fieldIndex == lastFieldIndex) {
+ lastFind = doc->characterCount()-1;
+ } else {
+ lastFind = doc->find(
+ fields.at(fieldIndex)->mNextSeparator,
+ lastFind,
+ QTextDocument::FindCaseSensitively ).anchor();
+ }
+ cursor->setPosition(lastFind, QTextCursor::KeepAnchor);
+}
+
+void HbValidatorPrivate::deleteAllFields()
+{
+ Q_Q(HbValidator);
+
+ foreach(HbValidatorField *field, fields) {
+ if(field->mValidator) {
+ if( field->mValidator->parent() == q ) {
+ delete field->mValidator;
+ }
+ }
+ delete field;
+ }
+ fields.clear();
+}