1 /***************************************************************************
2     Copyright (C) 2008-2020 Robby Stephenson <robby@periapsis.org>
3  ***************************************************************************/
4 
5 /***************************************************************************
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or         *
8  *   modify it under the terms of the GNU General Public License as        *
9  *   published by the Free Software Foundation; either version 2 of        *
10  *   the License or (at your option) version 3 or any later version        *
11  *   accepted by the membership of KDE e.V. (or its successor approved     *
12  *   by the membership of KDE e.V.), which shall act as a proxy            *
13  *   defined in Section 14 of version 3 of the license.                    *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
22  *                                                                         *
23  ***************************************************************************/
24 
25 #include "lccnvalidator.h"
26 #include "../tellico_debug.h"
27 
28 using Tellico::LCCNValidator;
29 
LCCNValidator(QObject * parent_)30 LCCNValidator::LCCNValidator(QObject* parent_) : QRegularExpressionValidator(parent_) {
31   QRegularExpression rx(QLatin1String("[a-z ]{0,3}"
32                                       "("
33                                       "\\d{2}-?\\d{1,6}"
34                                       "|"
35                                       "\\d{4}-?\\d{1,6}"
36                                       ")"
37                                       " ?\\w*"));
38   setRegularExpression(rx);
39 }
40 
41 // static
formalize(const QString & value_)42 QString LCCNValidator::formalize(const QString& value_) {
43   QString value = value_.simplified();
44   // remove spaces
45   value.remove(QLatin1Char(' '));
46   // remove everything after the forward slash
47   value = value.section(QLatin1Char('/'), 0, 0);
48 
49   const int len = value_.length();
50   // first remove alpha prefix
51   QString alpha;
52   for(int pos = 0; pos < len; ++pos) {
53     QChar c = value.at(pos);
54     if(c.isNumber()) {
55       break;
56     }
57     alpha += value.at(pos);
58   }
59   QString afterAlpha = value.mid(alpha.length());
60   alpha = alpha.trimmed(); // possible to have a space at the end
61 
62   QString year;
63   QString serial;
64   // have to be able to differentiate 2 and 4-digit years, first check for hyphen position
65   int pos = afterAlpha.indexOf(QLatin1Char('-'));
66   if(pos > -1) {
67     year = afterAlpha.section(QLatin1Char('-'), 0, 0);
68     serial = afterAlpha.section(QLatin1Char('-'), 1);
69   } else {
70     // make two assumptions, the user will never have a book from the year 1920
71     // or from any year after 2100. Reasonable, right?
72     // so if the string starts with '20' we take the first 4 digits as the year
73     // otherwise the first 2
74     if(afterAlpha.startsWith(QLatin1String("20"))) {
75       year = afterAlpha.left(4);
76       serial = afterAlpha.mid(4);
77     } else {
78       year = afterAlpha.left(2);
79       serial = afterAlpha.mid(2);
80     }
81   }
82 
83   // now check for non digits in the serial
84   pos = 0;
85   for( ; pos < serial.length() && serial.at(pos).isNumber(); ++pos) { ; }
86   QString suffix = serial.mid(pos);
87   serial = serial.left(pos);
88   // serial must be left-padded with zeros to 6 characters
89   serial = serial.rightJustified(6, QLatin1Char('0'));
90   return alpha + year + serial + suffix;
91 }
92