1
2 #include "Wt/WTimeEdit.h"
3
4 #include "Wt/WApplication.h"
5 #include "Wt/WContainerWidget.h"
6 #include "Wt/WLineEdit.h"
7 #include "Wt/WLogger.h"
8 #include "Wt/WPopupWidget.h"
9 #include "Wt/WPushButton.h"
10 #include "Wt/WTemplate.h"
11 #include "Wt/WTheme.h"
12
13 #include "WebUtils.h"
14
15 #ifndef WT_DEBUG_JS
16 #include "js/WTimeEdit.min.js"
17 #endif
18
19 namespace Wt {
20
21 LOGGER("WTimeEdit");
22
WTimeEdit()23 WTimeEdit::WTimeEdit()
24 : WLineEdit()
25 {
26 setValidator(std::shared_ptr<WTimeValidator>(new WTimeValidator()));
27 changed().connect(this, &WTimeEdit::setFromLineEdit);
28
29 timePicker_ = new WTimePicker(this);
30 timePicker_->selectionChanged().connect(this, &WTimeEdit::setFromTimePicker);
31 timePicker_->setWrapAroundEnabled(true);
32 }
33
~WTimeEdit()34 WTimeEdit::~WTimeEdit()
35 {
36 if (!popup_) {
37 // timePicker_ is not owned by popup_, because it doesn't exist
38 delete timePicker_;
39 }
40 }
41
load()42 void WTimeEdit::load()
43 {
44 bool wasLoaded = loaded();
45
46 WLineEdit::load();
47 // Loading of popup_ is deferred (see issue #4897)
48
49 if (wasLoaded)
50 return;
51
52 const char *TEMPLATE = "${timePicker}";
53
54 std::unique_ptr<WTemplate> t(new WTemplate(WString::fromUTF8(TEMPLATE)));
55 t->bindWidget("timePicker", std::unique_ptr<WTimePicker>(timePicker_));
56 popup_.reset(new WPopupWidget(std::move(t)));
57 if (isHidden()) {
58 popup_->setHidden(true);
59 }
60 popup_->setAnchorWidget(this);
61 popup_->setTransient(true);
62
63 WApplication::instance()
64 ->theme()->apply(this, popup_.get(), TimePickerPopup);
65
66 escapePressed().connect(popup_.get(), &WPopupWidget::hide);
67 escapePressed().connect(this, &WWidget::setFocus);
68 }
69
setTime(const WTime & time)70 void WTimeEdit::setTime(const WTime& time)
71 {
72 if (!time.isNull()) {
73 setText(time.toString(format()));
74 timePicker_->setTime(time);
75 }
76 }
77
time()78 WTime WTimeEdit::time() const
79 {
80 return WTime::fromString(text(), format());
81 }
82
timeValidator()83 std::shared_ptr<WTimeValidator> WTimeEdit::timeValidator() const
84 {
85 return std::dynamic_pointer_cast<WTimeValidator>(WLineEdit::validator());
86 }
87
setFormat(const WT_USTRING & format)88 void WTimeEdit::setFormat(const WT_USTRING& format)
89 {
90 auto tv = timeValidator();
91
92 if (tv) {
93 WTime t = this->time();
94 tv->setFormat(format);
95 timePicker_->configure();
96 setTime(t);
97 } else
98 LOG_WARN("setFormat() ignored since validator is not WTimeValidator");
99 }
100
format()101 WT_USTRING WTimeEdit::format() const
102 {
103 auto tv = timeValidator();
104
105 if (tv)
106 return tv->format();
107 else {
108 LOG_WARN("format() is bogus since validator is not WTimeValidator.");
109 return WT_USTRING();
110 }
111 }
112
setBottom(const WTime & bottom)113 void WTimeEdit::setBottom(const WTime &bottom)
114 {
115 auto tv = timeValidator();
116 if(tv)
117 tv->setBottom(bottom);
118 }
119
bottom()120 WTime WTimeEdit::bottom() const
121 {
122 auto tv = timeValidator();
123 if(tv)
124 return tv->bottom();
125 return WTime();
126 }
127
setTop(const WTime & top)128 void WTimeEdit::setTop(const WTime &top)
129 {
130 auto tv = timeValidator();
131 if(tv)
132 tv->setTop(top);
133 }
134
top()135 WTime WTimeEdit::top() const
136 {
137 auto tv = timeValidator();
138 if(tv)
139 return tv->top();
140 return WTime();
141 }
142
setHidden(bool hidden,const WAnimation & animation)143 void WTimeEdit::setHidden(bool hidden, const WAnimation& animation)
144 {
145 WLineEdit::setHidden(hidden, animation);
146 if (popup_) {
147 popup_->setHidden(hidden, animation);
148 }
149 }
150
render(WFlags<RenderFlag> flags)151 void WTimeEdit::render(WFlags<RenderFlag> flags)
152 {
153 if (flags.test(RenderFlag::Full))
154 defineJavaScript();
155
156 WLineEdit::render(flags);
157 }
158
propagateSetEnabled(bool enabled)159 void WTimeEdit::propagateSetEnabled(bool enabled)
160 {
161 WLineEdit::propagateSetEnabled(enabled);
162 }
163
setFromTimePicker()164 void WTimeEdit::setFromTimePicker()
165 {
166 setTime(timePicker_->time());
167 textInput().emit();
168 changed().emit();
169 }
170
setFromLineEdit()171 void WTimeEdit::setFromLineEdit()
172 {
173 WTime t = WTime::fromString(text(), format());
174 if (t.isValid())
175 timePicker_->setTime(t);
176 }
177
defineJavaScript()178 void WTimeEdit::defineJavaScript()
179 {
180 WApplication *app = WApplication::instance();
181 LOAD_JAVASCRIPT(app, "js/WTimeEdit.js", "WTimeEdit", wtjs1);
182 std::string jsObj = "new " WT_CLASS ".WTimeEdit("
183 + app->javaScriptClass() + "," + jsRef() + ","
184 + jsStringLiteral(popup_->id()) + ");";
185 setJavaScriptMember(" WTimeEdit", jsObj);
186 #ifdef WT_CNOR
187 EventSignalBase& b = mouseMoved();
188 EventSignalBase& c = keyWentDown();
189 #endif
190 connectJavaScript(mouseMoved(), "mouseMove");
191 connectJavaScript(mouseWentUp(), "mouseUp");
192 connectJavaScript(mouseWentDown(), "mouseDown");
193 connectJavaScript(mouseWentOut(), "mouseOut");
194 }
195
connectJavaScript(Wt::EventSignalBase & s,const std::string & methodName)196 void WTimeEdit::connectJavaScript(Wt::EventSignalBase& s,
197 const std::string& methodName)
198 {
199 std::string jsFunction =
200 "function(dobj, event) {"
201 """var o = " + jsRef() + ";"
202 """if(o && o.wtDObj) o.wtDObj." + methodName + "(dobj, event);"
203 "}";
204 s.connect(jsFunction);
205 }
206
setHourStep(int step)207 void WTimeEdit::setHourStep(int step)
208 {
209 timePicker_->setHourStep(step);
210 }
211
hourStep()212 int WTimeEdit::hourStep() const
213 {
214 return timePicker_->hourStep();
215 }
216
setMinuteStep(int step)217 void WTimeEdit::setMinuteStep(int step)
218 {
219 timePicker_->setMinuteStep(step);
220 }
221
minuteStep()222 int WTimeEdit::minuteStep() const
223 {
224 return timePicker_->minuteStep();
225 }
226
setSecondStep(int step)227 void WTimeEdit::setSecondStep(int step)
228 {
229 timePicker_->setSecondStep(step);
230 }
231
secondStep()232 int WTimeEdit::secondStep() const
233 {
234 return timePicker_->secondStep();
235 }
236
setMillisecondStep(int step)237 void WTimeEdit::setMillisecondStep(int step)
238 {
239 timePicker_->setMillisecondStep(step);
240 }
241
millisecondStep()242 int WTimeEdit::millisecondStep() const
243 {
244 return timePicker_->millisecondStep();
245 }
246
setWrapAroundEnabled(bool enabled)247 void WTimeEdit::setWrapAroundEnabled(bool enabled)
248 {
249 timePicker_->setWrapAroundEnabled(enabled);
250 }
251
wrapAroundEnabled()252 bool WTimeEdit::wrapAroundEnabled() const
253 {
254 return timePicker_->wrapAroundEnabled();
255 }
256
257
258 }
259