Coverage Report

Created: 2025-11-09 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}