/src/wt/src/Wt/WTimeValidator.C
Line | Count | Source |
1 | | |
2 | | #include "Wt/WApplication.h" |
3 | | |
4 | | #include "Wt/WTime.h" |
5 | | #include "Wt/WTimeValidator.h" |
6 | | #include "Wt/WLocale.h" |
7 | | #include "Wt/WLogger.h" |
8 | | #include "Wt/WStringStream.h" |
9 | | #include "Wt/WWebWidget.h" |
10 | | |
11 | | #ifndef WT_DEBUG_JS |
12 | | #include "js/WTimeValidator.min.js" |
13 | | #endif |
14 | | |
15 | | |
16 | | namespace Wt { |
17 | | |
18 | | LOGGER("WTimeValidator"); |
19 | | |
20 | | WTimeValidator::WTimeValidator() |
21 | 0 | { |
22 | 0 | #ifndef WT_TARGET_JAVA |
23 | 0 | setFormat(WLocale::currentLocale().timeFormat()); |
24 | | #else |
25 | | setFormat(WTime::defaultFormat()); |
26 | | #endif |
27 | 0 | } |
28 | | |
29 | | WTimeValidator::WTimeValidator(const WT_USTRING& format) |
30 | 0 | { |
31 | 0 | setFormat(format); |
32 | 0 | } |
33 | | |
34 | | WTimeValidator::WTimeValidator(const WT_USTRING &format, const WTime &bottom, |
35 | | const WTime &top) |
36 | 0 | : bottom_(bottom), |
37 | 0 | top_(top) |
38 | 0 | { |
39 | 0 | setFormat(format); |
40 | 0 | } |
41 | | |
42 | | void WTimeValidator::setFormat(const WT_USTRING& format) |
43 | 0 | { |
44 | 0 | if (formats_.empty() || formats_[0] != format){ |
45 | 0 | formats_.clear(); |
46 | 0 | formats_.push_back(format); |
47 | 0 | repaint(); |
48 | 0 | } |
49 | 0 | } |
50 | | |
51 | | void WTimeValidator::setFormats(const std::vector<WT_USTRING> &formats) |
52 | 0 | { |
53 | 0 | formats_ = formats; |
54 | 0 | repaint(); |
55 | 0 | } |
56 | | |
57 | | void WTimeValidator::setBottom(const WTime &bottom) |
58 | 0 | { |
59 | 0 | if(bottom_ != bottom){ |
60 | 0 | bottom_ = bottom; |
61 | 0 | repaint(); |
62 | 0 | } |
63 | 0 | } |
64 | | |
65 | | void WTimeValidator::setTop(const WTime &top) |
66 | 0 | { |
67 | 0 | if(top_ != top){ |
68 | 0 | top_ = top; |
69 | 0 | repaint(); |
70 | 0 | } |
71 | 0 | } |
72 | | |
73 | | void WTimeValidator::setStep(const std::chrono::seconds& step) |
74 | 0 | { |
75 | 0 | if (step < std::chrono::seconds(0)) { |
76 | 0 | LOG_ERROR("WTimeValidator::setStep(): ignoring call, value should not be negative"); |
77 | 0 | return; |
78 | 0 | } |
79 | | |
80 | 0 | if (step_ != step) { |
81 | 0 | step_ = step; |
82 | 0 | repaint(); |
83 | 0 | } |
84 | 0 | } |
85 | | |
86 | | void WTimeValidator::setInvalidNotATimeText(const WString &text) |
87 | 0 | { |
88 | 0 | notATimeText_ = text; |
89 | 0 | } |
90 | | |
91 | | WString WTimeValidator::invalidNotATimeText() const |
92 | 0 | { |
93 | 0 | if (!notATimeText_.empty()) { |
94 | 0 | return WString(notATimeText_).arg(formats_[0]); |
95 | 0 | } else |
96 | 0 | return WString::tr("Wt.WTimeValidator.WrongFormat").arg(formats_[0]); |
97 | 0 | } |
98 | | |
99 | | void WTimeValidator::setInvalidTooEarlyText(const WString &text) |
100 | 0 | { |
101 | 0 | tooEarlyText_ = text; |
102 | 0 | repaint(); |
103 | 0 | } |
104 | | |
105 | | WString WTimeValidator::invalidTooEarlyText() const |
106 | 0 | { |
107 | 0 | if (!tooEarlyText_.empty()) { |
108 | 0 | return WString(tooEarlyText_).arg(bottom_.toString(formats_[0])).arg(top_.toString(formats_[0])); |
109 | 0 | } else { |
110 | 0 | if(bottom_.isNull()) |
111 | 0 | return WString(); |
112 | 0 | else{ |
113 | 0 | if(top_.isNull()) |
114 | 0 | return WString::tr("Wt.WTimeValidator.TimeTooEarly").arg(bottom_.toString(formats_[0])); |
115 | 0 | else |
116 | 0 | return WString::tr("Wt.WTimeValidator.WrongTimeRange").arg(bottom_.toString(formats_[0])) |
117 | 0 | .arg(top_.toString(formats_[0])); |
118 | 0 | } |
119 | 0 | } |
120 | 0 | } |
121 | | |
122 | | void WTimeValidator::setInvalidTooLateText(const WString &text) |
123 | 0 | { |
124 | 0 | tooLateText_ = text; |
125 | 0 | repaint(); |
126 | 0 | } |
127 | | |
128 | | WString WTimeValidator::invalidTooLateText() const |
129 | 0 | { |
130 | 0 | if (!tooLateText_.empty()) { |
131 | 0 | return WString(tooLateText_).arg(bottom_.toString(formats_[0])).arg(top_.toString(formats_[0])); |
132 | 0 | } else{ |
133 | 0 | if(top_.isNull()) |
134 | 0 | return WString(); |
135 | 0 | else{ |
136 | 0 | if(bottom_.isNull()) |
137 | 0 | return WString::tr("Wt.WTimeValidator.TimeTooLate").arg(top_.toString(formats_[0])); |
138 | 0 | else |
139 | 0 | return WString::tr("Wt.WTimeValidator.WrongTimeRange").arg(bottom_.toString(formats_[0])) |
140 | 0 | .arg(top_.toString(formats_[0])); |
141 | 0 | } |
142 | 0 | } |
143 | |
|
144 | 0 | } |
145 | | |
146 | | void WTimeValidator::setInvalidWrongStepText(const WString &text) |
147 | 0 | { |
148 | 0 | wrongStepText_ = text; |
149 | 0 | repaint(); |
150 | 0 | } |
151 | | |
152 | | WString WTimeValidator::invalidWrongStepText() const |
153 | 0 | { |
154 | 0 | if (step_ <= std::chrono::seconds(0)) |
155 | 0 | return WString::Empty; |
156 | 0 | else if (!wrongStepText_.empty()) |
157 | 0 | return wrongStepText_; |
158 | 0 | else if (step_.count() % 60 == 0) |
159 | 0 | return WString::tr("Wt.WTimeValidator.WrongStep-minutes").arg(step_.count() / 60); |
160 | 0 | else if (step_.count() % 1 == 0) |
161 | 0 | return WString::tr("Wt.WTimeValidator.WrongStep-seconds").arg(step_.count() / 1); |
162 | 0 | else |
163 | 0 | return WString::tr("Wt.WTimeValidator.WrongStep"); |
164 | 0 | } |
165 | | |
166 | | WValidator::Result WTimeValidator::validate(const WT_USTRING &input) const |
167 | 0 | { |
168 | 0 | if (input.empty()) |
169 | 0 | return WValidator::validate(input); |
170 | 0 | for (unsigned i = 0; i < formats_.size(); i++){ |
171 | 0 | try { |
172 | 0 | WTime t = WTime::fromString(input, formats_[i]); |
173 | 0 | if(t.isValid()){ |
174 | 0 | if(!bottom_.isNull() && t < bottom_) |
175 | 0 | return Result(ValidationState::Invalid, |
176 | 0 | invalidTooEarlyText()); |
177 | 0 | if(!top_.isNull() && t > top_) |
178 | 0 | return Result(ValidationState::Invalid, |
179 | 0 | invalidTooLateText()); |
180 | 0 | if (step_ > std::chrono::seconds(0)) { |
181 | 0 | WTime start = !bottom_.isNull() ? bottom_ : WTime(0, 0); |
182 | 0 | long secs = start.secsTo(t); |
183 | 0 | if (secs % step_.count() != 0) |
184 | 0 | return Result(ValidationState::Invalid, invalidWrongStepText()); |
185 | 0 | } |
186 | 0 | return Result(ValidationState::Valid); |
187 | 0 | } |
188 | 0 | } catch (std::exception &e){ |
189 | 0 | LOG_WARN("validate(): " << e.what()); |
190 | 0 | } |
191 | 0 | } |
192 | 0 | return Result(ValidationState::Invalid, invalidNotATimeText()); |
193 | 0 | } |
194 | | |
195 | | void WTimeValidator::loadJavaScript(WApplication *app) |
196 | 0 | { |
197 | 0 | LOAD_JAVASCRIPT(app, "js/WTimeValidator.js", "WTimeValidator", wtjs1); |
198 | 0 | } |
199 | | |
200 | | std::string WTimeValidator::javaScriptValidate() const |
201 | 0 | { |
202 | 0 | loadJavaScript(WApplication::instance()); |
203 | |
|
204 | 0 | WStringStream js; |
205 | |
|
206 | 0 | js << "new " WT_CLASS ".WTimeValidator(" |
207 | 0 | << isMandatory() |
208 | 0 | << ",["; |
209 | |
|
210 | 0 | for(unsigned i = 0; i < formats_.size(); ++i){ |
211 | 0 | WTime::RegExpInfo r = WTime::formatToRegExp(formats_[i]); |
212 | |
|
213 | 0 | if(i != 0) |
214 | 0 | js << ','; |
215 | 0 | js << "{" |
216 | 0 | << "regexp:" << WWebWidget::jsStringLiteral(r.regexp) << ',' |
217 | 0 | << "getHour:function(results){" << r.hourGetJS << ";}," |
218 | 0 | << "getMinutes:function(results){" << r.minuteGetJS << ";}," |
219 | 0 | << "getSeconds:function(results){" << r.secGetJS << ";}," |
220 | 0 | << "getMilliseconds:function(results){" << r.msecGetJS << ";}," |
221 | 0 | << "}"; |
222 | 0 | } |
223 | 0 | js << "],"; |
224 | |
|
225 | 0 | if(!bottom_.isNull()) |
226 | 0 | js << "new Date(0,0,0," |
227 | 0 | << bottom_.hour() << "," << bottom_.minute() << "," |
228 | 0 | << bottom_.second() << "," << bottom_.msec() |
229 | 0 | << ")"; |
230 | 0 | else |
231 | 0 | js << "null"; |
232 | 0 | js << ','; |
233 | |
|
234 | 0 | if(!top_.isNull()) |
235 | 0 | js << "new Date(0,0,0," |
236 | 0 | << top_.hour() << "," << top_.minute() << "," |
237 | 0 | << top_.second() << "," << top_.msec() |
238 | 0 | << ")"; |
239 | 0 | else |
240 | 0 | js << "null"; |
241 | 0 | js << ','; |
242 | |
|
243 | 0 | if (step_ > std::chrono::seconds(0)) |
244 | 0 | js << static_cast<int>(step_.count()); |
245 | 0 | else |
246 | 0 | js << "null"; |
247 | |
|
248 | 0 | js << ',' << invalidBlankText().jsStringLiteral() |
249 | 0 | << ',' << invalidNotATimeText().jsStringLiteral() |
250 | 0 | << ',' << invalidTooEarlyText().jsStringLiteral() |
251 | 0 | << ',' << invalidTooLateText().jsStringLiteral() |
252 | 0 | << ',' << invalidWrongStepText().jsStringLiteral() |
253 | 0 | << ");"; |
254 | |
|
255 | 0 | return js.str(); |
256 | 0 | } |
257 | | |
258 | | |
259 | | } |