File indexing completed on 2024-05-12 05:10:16
0001 /*************************************************************************** 0002 Copyright (C) 2002-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 #ifndef TELLICO_ISBNVALIDATOR_H 0026 #define TELLICO_ISBNVALIDATOR_H 0027 0028 #include <QValidator> 0029 0030 namespace Tellico { 0031 0032 /** 0033 * @author Robby Stephenson 0034 * 0035 * @see https://web.archive.org/web/20130126042049/http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp 0036 * @see https://www.eblong.com/zarf/bookscan/ 0037 * @see https://doc.qt.io/archives/qq/qq01-seriously-weird-qregexp.html 0038 */ 0039 class ISBNValidator : public QValidator { 0040 Q_OBJECT 0041 0042 public: 0043 ISBNValidator(QObject* parent = nullptr); 0044 0045 /** 0046 * Certain conditions are checked. Character, length and position 0047 * restrictions are checked. Certain cases where the user is deleting 0048 * characters are caught and compensated for. The string is then passed to 0049 * @ref fixup. Finally, the text is @ref Valid if it is a certain length and 0050 * @ref Intermediate if not. 0051 * 0052 * @param input The text to validate 0053 * @param pos The position of the cursor 0054 * @return The condition of the text 0055 */ 0056 virtual QValidator::State validate(QString& input, int& pos) const Q_DECL_OVERRIDE; 0057 0058 /** 0059 * The input string is examined. Hyphens are inserted appropriately, 0060 * and the checksum is calculated. 0061 * 0062 * For correct presentation, the 10 digits of an ISBN must 0063 * be divided, by hyphens, into four parts: 0064 * @li Part 1: The country or group of countries identifier 0065 * @li Part 2: The publisher identifier 0066 * @li Part 3: The title identifier 0067 * @li Part 4: The check digit 0068 * For details 0069 * @see https://web.archive.org/web/20130126042049/http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp 0070 * For details on ranges 0071 * @see https://www.isbn-international.org/range_file_generation 0072 * For info on group codes 0073 * @see https://web.archive.org/web/20030609050408/http://www.isbn.spk-berlin.de/html/prefix/allpref.htm 0074 * For info on French language publisher codes 0075 * @see https://www.afnil.org/ 0076 * <pre> 0077 * Group Identifiers First Hyphen After 0078 * ----------------------------------------- 0079 * 0........7 1st digit 0080 * 80.......94 2nd " 0081 * 950......993 3rd " 0082 * 9940.....9989 4th " 0083 * 99900....99999 5th " 0084 * 0085 * Group Insert Hyphens 0086 * Identifier "0" After 0087 * ----------------------------------------- 0088 * 00.......19 1st 3rd 9th digit 0089 * 200......699 " 4th " 0090 * 7000.....8499 " 5th " 0091 * 85000....89999 " 6th " 0092 * 900000...949999 " 7th " 0093 * 9500000..9999999 " 8th " 0094 * 0095 * 0096 * Group Insert Hyphens 0097 * Identifier "1" After 0098 * ---------------------------------------- 0099 * 0........54999 illegal 0100 * 55000....86979 1st 6th 9th digit 0101 * 869800...998999 " 7th " 0102 * 9990000..9999999 " 8th " 0103 * 0104 * 0105 * Group Insert Hyphens 0106 * Identifier "2" After 0107 * ----------------------------------------- 0108 * 00.......19 1st 3rd 9th digit 0109 * 200......349 " 4th " 0110 * 34000....39999 " 6th " 0111 * 400......699 " 4th " 0112 * 7000.....8399 " 5th " 0113 * 84000....89999 " 6th " 0114 * 900000...949999 " 7th " 0115 * 9500000..9999999 " 8th " 0116 * 0117 * The position of the hyphens are determined by the publisher 0118 * prefix range established by each national agency in accordance 0119 * with the industry needs. The knowledge of the prefix ranges for 0120 * each country or group of countries is necessary to develop the 0121 * hyphenation output program. For groups 3 through 99999, the hyphenation 0122 * rules are currently unknown. So just leave out the hyphen between 0123 * the publisher and title for now, but allow it if the user inserts it. 0124 * </pre> 0125 * 0126 * @param input The raw string, hyphens included 0127 */ 0128 virtual void fixup(QString& input) const Q_DECL_OVERRIDE; 0129 0130 static void staticFixup(QString& input); 0131 static void fixup10(QString& input); 0132 static void fixup13(QString& input); 0133 0134 static QString isbn10(QString isbn13); 0135 static QString isbn13(QString isbn10); 0136 static QString cleanValue(QString isbn); 0137 // returns the values in list1 that are not in list2 0138 static QStringList listDifference(const QStringList& list1, const QStringList& list2); 0139 0140 private: 0141 static struct isbn_band { 0142 unsigned long MaxValue; 0143 int First; 0144 int Mid; 0145 int Last; 0146 } bands[]; 0147 0148 QValidator::State validate10(QString& input, int& pos) const; 0149 QValidator::State validate13(QString& input, int& pos) const; 0150 0151 /** 0152 * This function calculates and returns the ISBN checksum. The 0153 * algorithm is based on some code by Andrew Plotkin, available at 0154 * https://www.eblong.com/zarf/bookscan/ 0155 * 0156 * @see https://www.eblong.com/zarf/bookscan/ 0157 * 0158 * @param input The raw string, with no hyphens 0159 */ 0160 static QChar checkSum10(const QString& input); 0161 static QChar checkSum13(const QString& input); 0162 }; 0163 0164 class ISBNComparison { 0165 public: 0166 bool operator()(const QString& value1, const QString& value2) const; 0167 }; 0168 0169 } // end namespace 0170 #endif