]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/Validator.cpp
Fix -Winconsistent-missing-override
[lyx.git] / src / frontends / qt / Validator.cpp
1 /**
2  * \file Validator.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  * \author Richard Kimberly Heck
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12
13 #include <config.h>
14
15 #include "Validator.h"
16
17 #include "Dialog.h"
18 #include "LyXRC.h"
19 #include "qt_helpers.h"
20
21 #include "frontends/alert.h"
22
23 #include "support/docstring.h"
24 #include "support/gettext.h"
25 #include "support/lstrings.h"
26
27 #include <QLineEdit>
28 #include <QLocale>
29 #include <QWidget>
30
31 using namespace std;
32
33 namespace lyx {
34 namespace frontend {
35
36 LengthValidator::LengthValidator(QWidget * parent, bool const accept_empty)
37         : QValidator(parent), acceptable_if_empty_(accept_empty)
38 {}
39
40
41 QValidator::State LengthValidator::validate(QString & qtext, int &) const
42 {
43         if (!acceptable_if_empty_ && qtext.isEmpty())
44                 return QValidator::Intermediate;
45         QLocale loc;
46         bool ok;
47         double d = loc.toDouble(qtext.trimmed(), &ok);
48         // QLocale::toDouble accepts something like "1."
49         // We don't.
50         bool dp = qtext.endsWith(loc.decimalPoint());
51         if (!ok) {
52                 // Fall back to C
53                 QLocale c(QLocale::C);
54                 d = c.toDouble(qtext.trimmed(), &ok);
55                 dp = qtext.endsWith(c.decimalPoint());
56         }
57
58         if (ok && unsigned_ && d < 0)
59                 return QValidator::Invalid;
60
61         if (ok && positive_ && d == 0)
62                 // A plausible intermediate value, see #12508
63                 return QValidator::Intermediate;
64
65         if (ok && positive_ && d < 0)
66                 return QValidator::Invalid;
67
68         if (qtext.isEmpty() || (ok && !dp))
69                 return QValidator::Acceptable;
70
71         string const text = fromqstr(qtext);
72
73         if (glue_length_) {
74                 GlueLength gl;
75                 if (unsigned_ && gl.len().value() < 0)
76                         return QValidator::Invalid;
77                 if (isValidGlueLength(text, &gl))
78                         return QValidator::Acceptable;
79                 // Also check for localized variant
80                 if (isValidGlueLength(fromqstr(unlocLengthString(qtext)), &gl))
81                         return QValidator::Acceptable;
82                 return QValidator::Intermediate;
83         }
84
85         Length l;
86         bool const valid_length = isValidLength(text, &l);
87         if (!valid_length)
88                 return QValidator::Intermediate;
89
90         if (no_bottom_)
91                 return QValidator::Acceptable;
92
93         if (unsigned_ && l.value() < 0)
94                 return QValidator::Invalid;
95
96         if (positive_ && l.value() <= 0)
97                 return QValidator::Invalid;
98
99         return bottom_.inPixels(100) <= l.inPixels(100) ?
100                 QValidator::Acceptable : QValidator::Intermediate;
101 }
102
103
104 void LengthValidator::setBottom(Length const & b)
105 {
106         bottom_ = b;
107         no_bottom_ = false;
108 }
109
110
111 void LengthValidator::setBottom(GlueLength const & g)
112 {
113         glue_bottom_ = g;
114         no_bottom_ = false;
115         glue_length_ = true;
116 }
117
118
119 LengthValidator * unsignedLengthValidator(QLineEdit * ed)
120 {
121         LengthValidator * v = new LengthValidator(ed);
122         v->setBottom(Length());
123         v->setUnsigned(true);
124         return v;
125 }
126
127
128 LengthValidator * unsignedGlueLengthValidator(QLineEdit * ed)
129 {
130         LengthValidator * v = new LengthValidator(ed);
131         v->setBottom(GlueLength());
132         v->setUnsigned(true);
133         return v;
134 }
135
136
137 LengthAutoValidator::LengthAutoValidator(QWidget * parent, QString const & autotext)
138         : LengthValidator(parent),
139           autotext_(autotext)
140 {}
141
142
143 QValidator::State LengthAutoValidator::validate(QString & qtext, int & dummy) const
144 {
145         if (qtext == autotext_)
146                 return QValidator::Acceptable;
147         return LengthValidator::validate(qtext, dummy);
148 }
149
150
151 LengthAutoValidator * unsignedLengthAutoValidator(QLineEdit * ed, QString const & autotext)
152 {
153         LengthAutoValidator * v = new LengthAutoValidator(ed, autotext);
154         v->setBottom(Length());
155         v->setUnsigned(true);
156         return v;
157 }
158
159
160 LengthAutoValidator * positiveLengthAutoValidator(QLineEdit * ed, QString const & autotext)
161 {
162         LengthAutoValidator * v = new LengthAutoValidator(ed, autotext);
163         v->setBottom(Length());
164         v->setPositive(true);
165         return v;
166 }
167
168
169 DoubleAutoValidator::DoubleAutoValidator(QWidget * parent, QString const & autotext)
170         : QDoubleValidator(parent),
171           autotext_(autotext)
172 {}
173
174
175 DoubleAutoValidator::DoubleAutoValidator(double bottom,
176                 double top, int decimals, QObject * parent)
177         : QDoubleValidator(bottom, top, decimals, parent)
178 {}
179
180
181 QValidator::State DoubleAutoValidator::validate(QString & input, int & pos) const {
182         if (input == autotext_)
183                 return QValidator::Acceptable;
184         return QDoubleValidator::validate(input, pos);
185 }
186
187
188 NoNewLineValidator::NoNewLineValidator(QWidget * parent)
189         : QValidator(parent)
190 {}
191
192
193 QValidator::State NoNewLineValidator::validate(QString & qtext, int &) const
194 {
195 #if QT_VERSION < 0x060000
196         qtext.remove(QRegExp("[\\n\\r]"));
197 #else
198         qtext.remove(QRegularExpression("[\\n\\r]"));
199 #endif
200         return QValidator::Acceptable;
201 }
202
203
204 PathValidator::PathValidator(bool acceptable_if_empty,
205                              QWidget * parent)
206         : QValidator(parent),
207           acceptable_if_empty_(acceptable_if_empty),
208           latex_doc_(false),
209           tex_allows_spaces_(false)
210 {}
211
212
213 static docstring const printable_list(docstring const & invalid_chars)
214 {
215         docstring s;
216         docstring::const_iterator const begin = invalid_chars.begin();
217         docstring::const_iterator const end = invalid_chars.end();
218         docstring::const_iterator it = begin;
219
220         for (; it != end; ++it) {
221                 if (it != begin)
222                         s += ", ";
223                 if (*it == ' ')
224                         s += _("space");
225                 else
226                         s += *it;
227         }
228
229         return s;
230 }
231
232
233 QValidator::State PathValidator::validate(QString & qtext, int &) const
234 {
235         if (!latex_doc_)
236                 return QValidator::Acceptable;
237
238         docstring const text = support::trim(qstring_to_ucs4(qtext));
239         if (text.empty())
240                 return acceptable_if_empty_ ?
241                         QValidator::Acceptable : QValidator::Intermediate;
242
243         docstring invalid_chars = from_ascii("#$%{}()[]\"^");
244         if (!tex_allows_spaces_)
245                 invalid_chars += ' ';
246
247         if (text.find_first_of(invalid_chars) != docstring::npos) {
248
249                 static int counter = 0;
250                 if (counter == 0) {
251                         Alert::error(_("Invalid filename"),
252                                      _("LyX does not provide LaTeX support for file names containing any of these characters:\n") +
253                                          printable_list(invalid_chars));
254                 }
255                 ++counter;
256                 return QValidator::Intermediate;
257         }
258
259         return QValidator::Acceptable;
260 }
261
262
263 void PathValidator::setChecker(KernelDocType const & type, LyXRC const & rc)
264 {
265         latex_doc_ = type == KernelDocType::LaTeX;
266         tex_allows_spaces_ = rc.tex_allows_spaces;
267 }
268
269
270 PathValidator * getPathValidator(QLineEdit * ed)
271 {
272         if (!ed)
273                 return nullptr;
274         QValidator * validator = const_cast<QValidator *>(ed->validator());
275         if (!validator)
276                 return nullptr;
277         return dynamic_cast<PathValidator *>(validator);
278 }
279
280 } // namespace frontend
281 } // namespace lyx
282
283 #include "moc_Validator.cpp"