src/hbwidgets/editors/hbvalidator_p.cpp
changeset 0 16d8024aca5e
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbvalidator_p.h"
       
    27 #include <QTextDocument>
       
    28 #include <QTextCursor>
       
    29 #include <QDebug>
       
    30 #include <QtAlgorithms>
       
    31 
       
    32 #ifdef HBVALIDATOR_DEBUG_ENABLE
       
    33 #define VALIDATORDEBUG(x) printFields(x)
       
    34 #else
       
    35 #define VALIDATORDEBUG(x)
       
    36 #endif
       
    37 
       
    38 HbValidatorPrivate::HbValidatorPrivate() :
       
    39     separatorToAdd("/")
       
    40 {
       
    41 }
       
    42 
       
    43 void HbValidatorPrivate::init()
       
    44 {
       
    45     // no implemantation needed
       
    46 }
       
    47 
       
    48 void HbValidatorPrivate::clear()
       
    49 {
       
    50     deleteAllFields();
       
    51 }
       
    52 
       
    53 void HbValidatorPrivate::addField(const QString &separator, QValidator *validator, const QString &defaultValue)
       
    54 {
       
    55     if(!fields.isEmpty()) {
       
    56         // set separator between this and previous field
       
    57         fields.back()->mNextSeparator = separator;
       
    58     }
       
    59 
       
    60     // creating new filed
       
    61     HbValidatorField *newField = new HbValidatorField();
       
    62     fields.append(newField);
       
    63     
       
    64     newField->mDefaultValue = defaultValue;
       
    65     newField->mValidator = validator;
       
    66 }
       
    67 
       
    68 QValidator::State HbValidatorPrivate::validateText(const QTextDocument *doc)
       
    69 {
       
    70     QValidator::State state = QValidator::Acceptable;
       
    71     int lastSeparatorPos = 0;
       
    72     QTextCursor suportCursor;
       
    73 
       
    74     foreach(HbValidatorField* field, fields) {
       
    75         int separatorPos;
       
    76 
       
    77         if(!field->mNextSeparator.isEmpty()) {
       
    78             suportCursor = doc->find(field->mNextSeparator, lastSeparatorPos, QTextDocument::FindCaseSensitively);
       
    79             if(suportCursor.isNull()) {
       
    80                 // parsing failed
       
    81                 return QValidator::Invalid;
       
    82             }
       
    83             separatorPos = suportCursor.anchor();
       
    84         } else {
       
    85             // last posible cursor position
       
    86             separatorPos = doc->characterCount()-1;
       
    87             Q_ASSERT_X(separatorPos == doc->toPlainText().length(), 
       
    88                 "HbValidatorPrivate::validateText", 
       
    89                 "problems with QTextDocument::characterCount (to big value)");
       
    90         }
       
    91 
       
    92         // select field:
       
    93         QTextCursor toValidate(const_cast<QTextDocument *>(doc));
       
    94         toValidate.setPosition(lastSeparatorPos);
       
    95         toValidate.setPosition(separatorPos, QTextCursor::KeepAnchor);
       
    96 
       
    97         QString fieldText = toValidate.selectedText();
       
    98         int cursorPos = fieldText.length();
       
    99         QValidator::State fieldState = field->mValidator->validate(fieldText, cursorPos);
       
   100 
       
   101         // maybe here changes done by field validator shold be copied to document using QTextCursor toValidate?
       
   102         // in this case const from method argument should be removed
       
   103 
       
   104         if(fieldState<state) {
       
   105             state = fieldState;
       
   106         }
       
   107 
       
   108         if(state == QValidator::Invalid) {
       
   109             break;
       
   110         }
       
   111 
       
   112         // position of cursor after separator
       
   113         lastSeparatorPos = suportCursor.position();
       
   114     }
       
   115 
       
   116     return state;
       
   117 }
       
   118 
       
   119 int HbValidatorPrivate::findFieldIndexUnderCursorPos(const QTextCursor &cursor)
       
   120 {
       
   121     const int cursorPosition(cursor.position());
       
   122     const int lastFieldIndex(fields.count()-1);
       
   123     int findFrom = 0;
       
   124     int i;
       
   125 
       
   126     QTextDocument *doc = cursor.document();
       
   127     for(i = 0; i<lastFieldIndex; ++i) {
       
   128         QTextCursor separatorFound = doc->find(fields.at(i)->mNextSeparator, findFrom, QTextDocument::FindCaseSensitively);
       
   129         if(separatorFound.isNull()) {
       
   130             return -1;
       
   131         }
       
   132         findFrom = separatorFound.position();
       
   133         if(findFrom>cursorPosition) {
       
   134             break;
       
   135         }
       
   136     }
       
   137     return i;
       
   138 }
       
   139 
       
   140 bool HbValidatorPrivate::fieldHasSelection(int fieldIndex, const QTextCursor &cursor)
       
   141 {
       
   142     if(!cursor.hasSelection()) {
       
   143         return false;
       
   144     }
       
   145 
       
   146     const int lastFieldIndex = fields.count() - 1;
       
   147 
       
   148     Q_ASSERT( fieldIndex >= 0 );
       
   149     Q_ASSERT( fieldIndex <= lastFieldIndex );
       
   150 
       
   151     const int cursorBegin = qMin(cursor.position(), cursor.anchor());
       
   152     const int cursorEnd   = qMax(cursor.position(), cursor.anchor());
       
   153 
       
   154     // cheching left side of cursor
       
   155     if(fieldIndex==0) {// boundary condition (front):
       
   156         if(cursorBegin != 0) {
       
   157             return false;
       
   158         }
       
   159     } else { // normal check
       
   160         QTextCursor supportCursor = cursor.document()->find( 
       
   161                     fields.at(fieldIndex-1)->mNextSeparator,
       
   162                     cursorBegin, 
       
   163                     QTextDocument::FindCaseSensitively | QTextDocument::FindBackward);
       
   164         Q_ASSERT(!supportCursor.isNull());
       
   165         if( supportCursor.position() != cursorBegin) {
       
   166             return false;
       
   167         }
       
   168     }
       
   169 
       
   170     // checking right side of cursor
       
   171     if(fieldIndex==lastFieldIndex) { // boundary condition (tail):
       
   172         if( cursorEnd != cursor.document()->characterCount()-1 ) {
       
   173             return false;
       
   174         }
       
   175     } else { // normal check
       
   176         QTextCursor supportCursor = cursor.document()->find( 
       
   177                     fields.at(fieldIndex)->mNextSeparator,
       
   178                     cursorEnd, 
       
   179                     QTextDocument::FindCaseSensitively);
       
   180         Q_ASSERT(!supportCursor.isNull());
       
   181         if( supportCursor.anchor() != cursorEnd) {
       
   182             return false;
       
   183         }
       
   184     }
       
   185 
       
   186     return true;
       
   187 }
       
   188 
       
   189 void HbValidatorPrivate::highlightField(QTextCursor* cursor, int fieldIndex)
       
   190 {
       
   191     const int lastFieldIndex = fields.count() - 1;
       
   192 
       
   193     Q_ASSERT( fieldIndex >= 0 );
       
   194     Q_ASSERT( fieldIndex <= lastFieldIndex );
       
   195 
       
   196     QTextDocument *doc = cursor->document();
       
   197     int lastFind = 0;
       
   198     for(int i=0; i<fieldIndex; ++i) {
       
   199         lastFind = doc->find(
       
   200             fields.at(i)->mNextSeparator, 
       
   201             lastFind, 
       
   202             QTextDocument::FindCaseSensitively ).position();
       
   203     }
       
   204     cursor->setPosition(lastFind);
       
   205 
       
   206     if(fieldIndex == lastFieldIndex) {
       
   207         lastFind = doc->characterCount()-1;
       
   208     } else {
       
   209         lastFind = doc->find(
       
   210                 fields.at(fieldIndex)->mNextSeparator, 
       
   211                 lastFind, 
       
   212                 QTextDocument::FindCaseSensitively ).anchor();
       
   213     }
       
   214     cursor->setPosition(lastFind, QTextCursor::KeepAnchor);
       
   215 }
       
   216 
       
   217 void HbValidatorPrivate::deleteAllFields()
       
   218 {
       
   219     Q_Q(HbValidator);
       
   220 
       
   221     foreach(HbValidatorField *field, fields) {
       
   222         if(field->mValidator) {
       
   223             if( field->mValidator->parent() == q ) {
       
   224                 delete field->mValidator;
       
   225             }
       
   226         }
       
   227         delete field;
       
   228     }
       
   229     fields.clear();
       
   230 }