File indexing completed on 2024-05-12 05:10:17
0001 /*************************************************************************** 0002 Copyright (C) 2005-2009 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "upcvalidator.h" 0026 #include "isbnvalidator.h" 0027 0028 using Tellico::UPCValidator; 0029 0030 UPCValidator::UPCValidator(QObject* parent_) 0031 : QValidator(parent_), m_checkISBN(false), m_isbn(false) { 0032 } 0033 0034 QValidator::State UPCValidator::validate(QString& input_, int& pos_) const { 0035 // check if it's a cuecat first 0036 State catState = CueCat::decode(input_); 0037 if(catState == Acceptable) { 0038 pos_ = input_.length(); 0039 return catState; 0040 } 0041 0042 // no spaces allowed 0043 if(input_.contains(QLatin1Char(' '))) { 0044 return QValidator::Invalid; 0045 } 0046 0047 // no real checking, just if starts with 978, use isbnvalidator 0048 const uint len = input_.length(); 0049 if(len < 10) { 0050 m_isbn = false; 0051 } 0052 0053 if(!m_checkISBN || (!m_isbn && len < 13)) { 0054 return QValidator::Intermediate; 0055 } 0056 0057 // once it gets converted to an ISBN, remember that, and use it for later 0058 if(input_.startsWith(QLatin1String("978")) || input_.startsWith(QLatin1String("979"))) { 0059 ISBNValidator val; 0060 QValidator::State s = val.validate(input_, pos_); 0061 if(s == QValidator::Acceptable) { 0062 m_isbn = true; 0063 emit signalISBN(); 0064 } 0065 return s; 0066 } 0067 0068 // TODO: return QValidator::Acceptable if check sum is correct 0069 return QValidator::Intermediate; 0070 } 0071 0072 void UPCValidator::fixup(QString& input_) const { 0073 if(input_.isEmpty()) { 0074 return; 0075 } 0076 input_ = input_.trimmed(); 0077 0078 int pos = input_.indexOf(QLatin1Char(' ')); 0079 if(pos > -1) { 0080 input_ = input_.left(pos); 0081 } 0082 0083 if(!m_checkISBN) { 0084 return; 0085 } 0086 0087 const uint len = input_.length(); 0088 if(len > 12 && (input_.startsWith(QLatin1String("978")) || input_.startsWith(QLatin1String("979")))) { 0089 QString s = input_; 0090 ISBNValidator val; 0091 int p = 0; 0092 int state = val.validate(s, p); 0093 if(state == QValidator::Acceptable) { 0094 emit signalISBN(); 0095 input_ = s; 0096 } 0097 } 0098 } 0099 0100 QValidator::State Tellico::CueCat::decode(QString& input_) { 0101 if(input_.length() < 3) { 0102 return QValidator::Intermediate; 0103 } 0104 if(!input_.startsWith(QLatin1String(".C3"))) { // all cuecat codes start with .C3 0105 return QValidator::Invalid; 0106 } 0107 const int periods = input_.count(QLatin1Char('.')); 0108 if(periods < 4) { 0109 return QValidator::Intermediate; // not enough yet 0110 } else if(periods > 4) { 0111 return QValidator::Invalid; 0112 } 0113 0114 // ok, let's have a go, take the third token 0115 QString code = input_.section(QLatin1Char('.'), 2, 2, QString::SectionSkipEmpty); 0116 while(code.length() % 4 > 0) { 0117 code += QLatin1Char('='); 0118 } 0119 0120 for(int i = 0; i < code.length(); ++i) { 0121 if(code[i] >= QLatin1Char('A') && code[i] <= QLatin1Char('Z')) { 0122 code.replace(i, 1, code[i].toLower()); 0123 } else if(code[i] >= QLatin1Char('a') && code[i] <= QLatin1Char('z')) { 0124 code.replace(i, 1, code[i].toUpper()); 0125 } 0126 } 0127 0128 code = QString::fromLatin1(QByteArray::fromBase64(code.toLatin1())); 0129 0130 for(int i = 0; i < code.length(); ++i) { 0131 char c = code[i].toLatin1() ^ 'C'; 0132 code.replace(i, 1, QLatin1Char(c)); 0133 } 0134 0135 input_ = code; 0136 return QValidator::Acceptable; 0137 }