Project

General

Profile

Feature #3725 » timeedit.patch

Benjamin Oldenburg, 01/12/2015 07:22 PM

View differences:

resources/themes/bootstrap/3/time-edit-button.png 1970-01-01 01:00:00.000000000 +0100 → resources/themes/bootstrap/3/time-edit-button.png 2014-12-30 09:51:22.000000000 +0000
?PNG

IHDR(f???qbKGD??????? pHYs ? ?B(?xtIME?  3???IDATx??]H?}??-7'󣌲XQl?:?Jʤ
R?e??9???:≨N:0t?h??ecA(??&?bs}@?u??vo??????>???x{wp_??{??????????1?????ٳH??@??dLV>RH?H? ʀr &EEQ???b????(555????h??ɡ?????QA ?I^C??x?]?v???DQdvv?ݎ?nG?Ra2?????Ǐ?|>"?uuu??ձe?
E?8
???ƃ8t? ;v???4B?/_???????DQ???????U???x<?Ν;W?ñ?1N?<????ikk#???~?۷o??????g?]???ׯ??易? q5??ՅJ?????????2?H???>|?͛7???\?z?JEWW??ܱcǪ?,77??H__?ׯgdd?>099??른??+W?PQQ???gff&q5 ??th?Z?????룿?A(++??ŋdee????N?# JZG)??????dggc6????c~~???"6n??L?@?????6?3g????c)//?ĉ9r?p8Ljj*J?Q???q??YI?H>$UUUD"?v;^??BAjj*???h4?^/v??H$BUU??u??l??t:ݪ?,##???E?<y???$:??M?6?P(<??۷o3::J]]f??J??-V??TWW#?"????Z?????t????D"???S]]?Z???????[?n?T??(??z?????r?????c6??t????h4I??8`nn?<n???AP>$2? ?<$j?:y3?????[???(נ (ʀ?
(?"?P???q???dgg???illd||?P(??iI??x?m۶I??????p??ىJ???{qMM V?um?UJ??a???<x???Z?=?F?!3<<Lkk+???ܸqC?a?????q???ٷo---?L???????a?~?:<{??$????Q?T???b2???bD?Qfgg????֭[l߾???T*??݉?A?^??`?ѣG?T*^?z?Ǐ??????q??i._? ??s?x??=??Ӊ???4?_?|??r??? A???? .?bX%σRbŰ
?@VV?????_ k8^?a?f????>???(++?Ű?????!??????Hl?^1?????|>RRRP??dee????B???????7?RB?a?????aMII??ϟ????9?*%4 V??????jX?Z?qo??6??[1???ݿ֪???cX??? (ʀ2? (?9?>?/??Y+?Y+֯_/o?׭[?t`???,,,?}P??ou?P??? ???0 ???b0hjjbbb?????Z???9?N'N??R??h????~??(?????͛YZZ??=w听ɰ:?N:::(((?j?RTT7?###ttt???@SS?t?*%???f???????1??k+?uzz???f޼y???b??ݫΠ????E?Tb?Z1?q?:77GOOw??A??c??P*????Jo?R??vc4)**????ӧO?{????)N?:E,????ш????ݻ?!nX?~??ӧO@JJJ8??? ? D??U&??Z?? kii)???߿SXXȆ ?)??jQ*???`YY.????aJJJ8~?8??Ű???1?͉mԕ??D?Q~????????p8?F???6??l??????????n޾}?N?#'''nX?w?cccX?VJKKQ*??z?EQ$??ͰZ,?N'????}??l6, ??????5ꕻ ??LMM??ۋ??F?Z-eeeTVV???7?????n?k?Vy`?e@P????Gc'/IEND?B`?
resources/themes/bootstrap/3/wt.css 2014-03-28 10:41:53.000000000 +0000 → resources/themes/bootstrap/3/wt.css 2014-12-30 09:42:15.000000000 +0000
}
/*
* WTimeEdit
*/
.Wt-timeedit {
padding-right: 40px;
background-image: url('time-edit-button.png');
background-position: right top;
background-repeat: no-repeat;
}
.Wt-timeedit:hover {
cursor: default;
background-position: right -34px;
}
.Wt-timeedit:active {
cursor: default;
background-position: right -68px;
}
.Wt-timeedit::-ms-clear {
display: none;
}
/*
* WDatePicker
*/
resources/themes/bootstrap/3/wt.less 2014-03-28 10:41:53.000000000 +0000 → resources/themes/bootstrap/3/wt.less 2015-01-04 07:18:00.000000000 +0000
}
/*
* WTimeEdit
*/
.Wt-timeedit {
background-image: url('date-edit-button.png');
background-repeat: no-repeat;
background-position: right top;
padding-right: 40px;
&:hover {
cursor: default;
background-position: right -34px;
}
&:active {
cursor: default;
background-position: right -68px;
}
}
.Wt-timeedit::-ms-clear {
display:none
}
/*
* WDatePicker
*/
.Wt-datepicker input {
src/CMakeLists.txt 2014-02-20 07:29:19.000000000 +0000 → src/CMakeLists.txt 2015-01-04 13:40:05.000000000 +0000
MACRO (FILE_TO_STRING infile outfile var)
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${outfile}
COMMAND ${CMAKE_COMMAND}
COMMAND ${CMAKE_COMMAND}
ARGS -Dinfile:FILEPATH=${CMAKE_CURRENT_SOURCE_DIR}/${infile}
-Doutfile:FILEPATH=${CMAKE_CURRENT_BINARY_DIR}/${outfile}
-Dvar:STRING=${var}
-P ${CMAKE_CURRENT_SOURCE_DIR}/filetostring.cmake
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/${infile}
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/${infile}
)
ENDMACRO (FILE_TO_STRING)
......
FILE_TO_STRING(xml/wt.xml Wt_xml.C Wt_xml)
FILE_TO_STRING(xml/auth_strings.xml AuthStrings_xml.C AuthStrings_xml)
FILE_TO_STRING(xml/bootstrap_theme.xml
BootstrapTheme_xml.C BootstrapTheme_xml)
BootstrapTheme_xml.C BootstrapTheme_xml)
FILE_TO_STRING(xml/bootstrap3_theme.xml
Bootstrap3Theme_xml.C Bootstrap3Theme_xml)
Bootstrap3Theme_xml.C Bootstrap3Theme_xml)
FILE_TO_STRING(xml/auth_css_theme.xml
AuthCssTheme_xml.C AuthCssTheme_xml)
AuthCssTheme_xml.C AuthCssTheme_xml)
SET(libsources
Wt/PopupWindow.C
......
Wt/WTextEdit.C
Wt/WTheme.C
Wt/WTime.C
Wt/WTimeEdit.C
Wt/WTimer.C
Wt/WTimerWidget.C
Wt/WTimePicker.C
Wt/WTimeValidator.C
Wt/WToolBar.C
Wt/WTransform.C
Wt/WTree.C
src/js/WTimeEdit.js 1970-01-01 01:00:00.000000000 +0100 → src/js/WTimeEdit.js 2014-12-30 09:31:02.000000000 +0000
/*
* Copyright (C) 2010 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
/* Note: this is at the same time valid JavaScript and C++. */
WT_DECLARE_WT_MEMBER
(1, JavaScriptConstructor, "WTimeEdit",
function(APP, edit, popup) {
/** @const */ var CLASS_HOVER = 'hover';
/** @const */ var CLASS_ACTIVE = 'active';
/** @const */ var CLASS_UNSELECTABLE = 'unselectable';
jQuery.data(edit, 'dobj', this);
var self = this, WT = APP.WT, $edit = $(edit);
function isReadOnly() {
return !!edit.getAttribute("readonly");
}
function isPopupVisible() {
return popup.style.display === '';
}
function getPopup() {
var p = $('#' + popup.id).get(0);
return jQuery.data(p, 'popup');
}
function resetButton() {
$edit.removeClass(CLASS_ACTIVE);
}
function showPopup() {
var p = getPopup();
p.bindHide(resetButton);
p.show(edit, WT.Vertical);
}
this.mouseOut = function(o, event) {
$edit.removeClass(CLASS_HOVER);
};
this.mouseMove = function(o, event) {
if (isReadOnly())
return;
var xy = WT.widgetCoordinates(edit, event);
if (xy.x > edit.offsetWidth - 40) {
$edit.addClass(CLASS_HOVER);
} else {
if ($edit.hasClass(CLASS_HOVER))
$edit.removeClass(CLASS_HOVER);
}
};
this.mouseDown = function(o, event) {
if (isReadOnly())
return;
var xy = WT.widgetCoordinates(edit, event);
if (xy.x > edit.offsetWidth - 40) {
$edit.addClass(CLASS_UNSELECTABLE).addClass(CLASS_ACTIVE);
}
};
this.mouseUp = function(o, event) {
$edit.removeClass(CLASS_UNSELECTABLE);
var xy = WT.widgetCoordinates(edit, event);
if (xy.x > edit.offsetWidth - 40)
showPopup();
};
});
src/js/WTimeEdit.min.js 1970-01-01 01:00:00.000000000 +0100 → src/js/WTimeEdit.min.js 2014-12-30 09:31:07.000000000 +0000
WT_DECLARE_WT_MEMBER(1,JavaScriptConstructor,"WTimeEdit",function(g,a,h){function f(){return!!a.getAttribute("readonly")}function i(){var b=$("#"+h.id).get(0);return jQuery.data(b,"popup")}function j(){c.removeClass("active")}function k(){var b=i();b.bindHide(j);b.show(a,e.Vertical)}jQuery.data(a,"dobj",this);var e=g.WT,c=$(a);this.mouseOut=function(){c.removeClass("hover")};this.mouseMove=function(b,d){if(!f())if(e.widgetCoordinates(a,d).x>a.offsetWidth-40)c.addClass("hover");else c.hasClass("hover")&&
c.removeClass("hover")};this.mouseDown=function(b,d){f()||e.widgetCoordinates(a,d).x>a.offsetWidth-40&&c.addClass("unselectable").addClass("active")};this.mouseUp=function(b,d){c.removeClass("unselectable");e.widgetCoordinates(a,d).x>a.offsetWidth-40&&k()}});
src/js/WTimeValidator.js 1970-01-01 01:00:00.000000000 +0100 → src/js/WTimeValidator.js 2015-01-04 13:40:05.000000000 +0000
/*
* Copyright (C) 2011 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
/* Note: this is at the same time valid JavaScript and C++. */
/*
* We could merge this with WIntValidator ...
*/
WT_DECLARE_WT_MEMBER
(1, JavaScriptConstructor, "WTimeValidator",
function(mandatory, formats, bottom, top, blankError,
formatError) {
this.validate = function(text) {
if (text.length == 0)
if (mandatory)
return { valid: false, message: blankError };
else
return { valid: true };
var results;
var s = -1, m = -1, h = -1;
for (var i = 0, il = formats.length; i < il; ++i) {
var f = formats[i];
var r = new RegExp("^" + f.regexp + "$");
results = r.exec(text);
if (results != null) {
//s = f.getSecond(results);
m = f.getMinute(results);
h = f.getHour(results);
break;
}
}
if (results == null)
return { valid: false, message: formatError };
if( /*(m < 0) || (m > 59) ||*/ (m < 0) || (m > 59) || (h < 0) || (h > 23))
return {valid: false, message: formatError };
var dt = new Date(0, 0, 0, h, m, 0, 0);
if(/*dt.getSeconds() != s ||*/ dt.getMinutes() != m || dt.getHours() != h)
{
return {valid: false, message: formatError };
}
/*
if (bottom)
if (dt.getTime() < bottom.getTime())
return { valid: false, message: tooSmallError};
if (top)
if (dt.getTime() > top.getTime())
return { valid:false, message: tooLargeError};
*/
return { valid: true };
};
});
src/js/WTimeValidator.min.js 1970-01-01 01:00:00.000000000 +0100 → src/js/WTimeValidator.min.js 2015-01-04 13:40:05.000000000 +0000
WT_DECLARE_WT_MEMBER(1,JavaScriptConstructor,"WDateValidator",function(l,i,j,k,m,f,n,o){this.validate=function(a){if(a.length==0)return l?{valid:false,message:m}:{valid:true};for(var b,c=-1,d=-1,g=-1,h=0,p=i.length;h<p;++h){var e=i[h];b=(new RegExp("^"+e.regexp+"$")).exec(a);if(b!=null){c=e.getMonth(b);d=e.getDay(b);g=e.getYear(b);break}}if(b==null)return{valid:false,message:f};if(d<=0||d>31||c<=0||c>12)return{valid:false,message:f};a=new Date(g,c-1,d);if(a.getDate()!=d||a.getMonth()!=c-1||a.getFullYear()!=
g||a.getFullYear()<1400)return{valid:false,message:f};if(j)if(a.getTime()<j.getTime())return{valid:false,message:n};if(k)if(a.getTime()>k.getTime())return{valid:false,message:o};return{valid:true}}});
src/Wt/WBootstrapTheme.C 2014-04-29 21:55:27.000000000 +0100 → src/Wt/WBootstrapTheme.C 2015-01-04 07:17:19.000000000 +0000
#include "Wt/WComboBox"
#include "Wt/WDateEdit"
#include "Wt/WDatePicker"
#include "Wt/WTimeEdit"
#include "Wt/WDialog"
#include "Wt/WEnvironment"
#include "Wt/WGoogleMap"
......
child->addStyleClass("Wt-datepicker");
break;
case TimePickerPopupRole:
child->addStyleClass("Wt-timepicker");
break;
case PanelTitleBarRole:
child->addStyleClass(classAccordionHeading());
break;
......
return;
}
WTimeEdit *timeEdit = dynamic_cast<WTimeEdit *>(widget);
if (timeEdit) {
element.addPropertyWord(PropertyClass, "Wt-timeedit");
return;
}
}
break;
src/Wt/WLocale 2014-02-25 22:12:04.000000000 +0000 → src/Wt/WLocale 2015-01-04 13:40:05.000000000 +0000
*/
WT_USTRING dateFormat() const { return dateFormat_; }
/*! \brief Sets the time format.
*
* Sets the default format for time entry, eg. as used in
* WTimeValidator. See WTime::toString() for the supported syntax.
*
* The default time format is "HH:mm:ss".
*/
void setTimeFormat(const WT_USTRING &format);
/*! \brief Returns the time format.
*
* Returns the time format.
*/
WT_USTRING timeFormat() const { return timeFormat_; }
/*! \brief Sets the date/time format.
*
* Sets the format for a localized time stamp (using
......
/*! \brief Casts to the locale string (for pre-3.3.0 compatibility).
*
* \deprecated Use name() instead.
* \deprecated Use name() instead.
*/
operator std::string() const { return name(); }
......
private:
std::string name_;
WT_UCHAR decimalPoint_, groupSeparator_;
WT_USTRING dateFormat_, dateTimeFormat_;
WT_USTRING dateFormat_, timeFormat_, dateTimeFormat_;
boost::local_time::time_zone_ptr time_zone_;
src/Wt/WLocale.C 2014-03-07 11:21:38.000000000 +0000 → src/Wt/WLocale.C 2015-01-04 13:40:05.000000000 +0000
: decimalPoint_("."),
groupSeparator_(""),
dateFormat_("yyyy-MM-dd"),
timeFormat_("HH:mm:ss"),
dateTimeFormat_("yyyy-MM-dd HH:mm:ss")
{ }
......
decimalPoint_(other.decimalPoint()),
groupSeparator_(other.groupSeparator()),
dateFormat_(other.dateFormat()),
timeFormat_(other.timeFormat()),
dateTimeFormat_(other.dateTimeFormat()),
time_zone_(other.time_zone_)
{ }
......
decimalPoint_(systemLocale.decimalPoint()),
groupSeparator_(systemLocale.groupSeparator()),
dateFormat_(systemLocale.dateFormat()),
timeFormat_(systemLocale.timeFormat()),
dateTimeFormat_(systemLocale.dateTimeFormat()),
time_zone_(systemLocale.time_zone_)
{ }
......
decimalPoint_(systemLocale.decimalPoint()),
groupSeparator_(systemLocale.groupSeparator()),
dateFormat_(systemLocale.dateFormat()),
timeFormat_(systemLocale.timeFormat()),
dateTimeFormat_(systemLocale.dateTimeFormat()),
time_zone_(systemLocale.time_zone_)
{ }
......
dateFormat_ = format;
}
void WLocale::setTimeFormat(const WT_USTRING &format)
{
timeFormat_ = format;
}
void WLocale::setTimeZone(const std::string& posixTimeZone)
{
time_zone_.reset(new boost::local_time::posix_time_zone(posixTimeZone));
src/Wt/WTheme 2014-04-29 21:55:27.000000000 +0100 → src/Wt/WTheme 2015-01-04 07:17:19.000000000 +0000
TableViewRowContainerRole = 300,
DatePickerPopupRole = 400,
TimePickerPopupRole = 410,
PanelTitleBarRole = 500,
PanelCollapseButtonRole = 501,
......
/*! \brief Applies a style that indicates the result of validation.
*/
virtual void applyValidationStyle(WWidget *widget,
const Wt::WValidator::Result& validation,
WFlags<ValidationStyleFlag> flags) const
const Wt::WValidator::Result& validation,
WFlags<ValidationStyleFlag> flags) const
= 0;
virtual bool canBorderBoxElement(const DomElement& element) const = 0;
src/Wt/WTime.C 2014-04-29 21:55:27.000000000 +0100 → src/Wt/WTime.C 2015-01-04 13:40:05.000000000 +0000
time_(t)
{ }
WTime::RegExpInfo WTime::formatToRegExp(const WT_USTRING &format)
{
RegExpInfo result;
return result;
}
}
src/Wt/WTimeEdit 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimeEdit 2015-01-04 13:50:33.000000000 +0000
#ifndef WTIME_EDIT_H_
#define WTIME_EDIT_H_
#include <Wt/WLineEdit>
#include <Wt/WTime>
#include <Wt/WTimeValidator>
#include <Wt/WTimePicker>
namespace Wt {
class WT_API WTimeEdit : public WLineEdit
{
public:
/*! \brief Creates a new time edit.
*/
WTimeEdit(WContainerWidget *parent = 0);
/*! \brief Sets the time
*
* Does nothing if the current time is \p Null.
*
* \sa time()
*/
void setTime(const WTime& time);
/*! \brief Returns the time.
*
* Returns an invalid time (for which WTime::isValid() returns
* \c false) if the time coult not be parsed using the current format(). <br>
*
* \sa setTime(), WTime::fromString(), WLineEdit::text()
*/
WTime time() const;
virtual WTimeValidator *validator() const;
void setFormat(const WT_USTRING& format);
WT_USTRING format() const;
virtual void setHidden(bool hidden, const WAnimation& animation = WAnimation());
int minuteStep() const { return timePicker_->minuteStep(); }
void setMinuteStep(int step) { timePicker_->setMinuteStep(step); }
protected:
virtual void render(WFlags<RenderFlag> flags);
virtual void propagateSetEnabled(bool enabled);
/*! \brief Sets the value from the time scroller to the line edit.
*/
virtual void setFromTimePicker();
/*! \brief Sets the value from the line edit to the time scroller.
*/
virtual void setFromLineEdit();
virtual void setText(const WString &text) { WLineEdit::setText(text); }
private:
WPopupWidget *popup_;
WTimePicker *timePicker_;
void defineJavaScript();
void connectJavaScript(Wt::EventSignalBase& s, const std::string& methodName);
};
}
#endif // WTIME_EDIT_H_
src/Wt/WTimeEdit.C 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimeEdit.C 2015-01-04 13:50:33.000000000 +0000
#include "Wt/WTimeEdit"
#include "Wt/WApplication"
#include "Wt/WContainerWidget"
#include "Wt/WLineEdit"
#include "Wt/WLogger"
#include "Wt/WPopupWidget"
#include "Wt/WPushButton"
#include "Wt/WTemplate"
#include "Wt/WTheme"
#include "WebUtils.h"
#ifndef WT_DEBUG_JS
#include "js/WTimeEdit.min.js"
#endif
namespace Wt {
LOGGER("WTimeEdit");
WTimeEdit::WTimeEdit(WContainerWidget *parent)
: WLineEdit(parent)
{
changed().connect(this, &WTimeEdit::setFromLineEdit);
const char *TEMPLATE = "${timePicker}";
WTemplate *t = new WTemplate(WString::fromUTF8(TEMPLATE));
popup_ = new WPopupWidget(t, this);
popup_->setAnchorWidget(this);
popup_->setTransient(true, 2);
timePicker_ = new WTimePicker();
timePicker_->selectionChanged().connect(this, &WTimeEdit::setFromTimePicker);
t->bindWidget("timePicker", timePicker_);
WApplication::instance()->theme()->apply(this, popup_, TimePickerPopupRole);
escapePressed().connect(popup_, &WPopupWidget::hide);
escapePressed().connect(this, &WTimeEdit::setFocus);
setValidator(new WTimeValidator("HH:mm", this));
}
void WTimeEdit::setTime(const WTime& time)
{
setText(time.toString(format()));
timePicker_->setTime(time);
}
WTime WTimeEdit::time() const
{
return WTime::fromString(text(), format());
}
WTimeValidator *WTimeEdit::validator() const
{
return dynamic_cast<WTimeValidator *>(WLineEdit::validator());
}
void WTimeEdit::setFormat(const WT_USTRING& format)
{
WTimeValidator *tv = validator();
if(tv)
{
WTime t = this->time();
tv->setFormat(format);
setTime(t);
}
else
{
LOG_WARN("setFormaT() ignored since validator is not WTimeValidator");
}
}
WT_USTRING WTimeEdit::format() const
{
WTimeValidator *tv = validator();
if(tv)
{
return tv->format();
}
else
{
LOG_WARN("format() is bogus since validator is not WTimeValidator.");
return WT_USTRING();
}
}
void WTimeEdit::setHidden(bool hidden, const WAnimation& animation)
{
WLineEdit::setHidden(hidden, animation);
popup_->setHidden(hidden, animation);
}
void WTimeEdit::render(WFlags<RenderFlag> flags)
{
if(flags & RenderFull) {
defineJavaScript();
}
WLineEdit::render(flags);
}
void WTimeEdit::propagateSetEnabled(bool enabled)
{
WLineEdit::propagateSetEnabled(enabled);
}
void WTimeEdit::setFromTimePicker()
{
setTime(timePicker_->time());
}
void WTimeEdit::setFromLineEdit()
{
WTime t = WTime::fromString(text(), format());
if(t.isValid())
{
timePicker_->setTime(t);
}
}
void WTimeEdit::defineJavaScript()
{
WApplication *app = WApplication::instance();
LOAD_JAVASCRIPT(app, "js/WTimeEdit.js", "WTimeEdit", wtjs1);
std::string jsObj = "new " WT_CLASS ".WTimeEdit("
+ app->javaScriptClass() + "," + jsRef() + ","
+ popup_->jsRef() + ");";
setJavaScriptMember(" WTimeEdit", jsObj);
#ifdef WT_CNOR
EventSignalBase& b = mouseMoved();
EventSignalBase& c = keyWentDown();
#endif
connectJavaScript(mouseMoved(), "mouseMove");
connectJavaScript(mouseWentUp(), "mouseUp");
connectJavaScript(mouseWentDown(), "mouseDown");
connectJavaScript(mouseWentOut(), "mouseOut");
}
void WTimeEdit::connectJavaScript(Wt::EventSignalBase& s, const std::string& methodName)
{
std::string jsFunction =
"function(dobj, event) {"
"""var o = jQuery.data(" + jsRef() + ", 'dobj');"
"""if(o) o." + methodName + "(dobj, event);"
"}";
s.connect(jsFunction);
}
}
src/Wt/WTimePicker 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimePicker 2014-12-31 10:08:39.000000000 +0000
#ifndef WTIME_PICKER_H_
#define WTIME_PICKER_H_
#include "WCompositeWidget"
#include "WContainerWidget"
#include "WTime"
namespace Wt {
class WT_API WTimePicker : public WCompositeWidget
{
public:
WTimePicker(WContainerWidget *parent = 0);
WTimePicker(const WTime &time, WContainerWidget *parent = 0);
WTime time();
void setTime(const WTime& time);
int minuteStep() const { return minuteStep_; }
void setMinuteStep(int step) { minuteStep_ = step; }
Signal<>& selectionChanged() { return selectionChanged_; }
private:
int minuteStep_;
void init(const WTime &time = WTime());
WText *hourText_;
WText *minuteText_;
void incrementMinutes();
void decrementMinutes();
void incrementHours();
void decrementHours();
Signal<> selectionChanged_;
};
} // end namespace Wt
#endif // WTIME_PICKER_H_
src/Wt/WTimePicker.C 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimePicker.C 2015-01-04 13:40:05.000000000 +0000
#include <boost/format.hpp>
#include "WTimePicker"
#include "WStringStream"
#include "WTemplate"
#include "WPushButton"
#include "WText"
namespace Wt {
WTimePicker::WTimePicker(WContainerWidget *parent)
: WCompositeWidget(parent), minuteStep_(1),
selectionChanged_(this)
{
init();
}
WTimePicker::WTimePicker(const WTime &time, WContainerWidget *parent)
: WCompositeWidget(parent), minuteStep_(1)
{
init(time);
}
void WTimePicker::init(const WTime &time)
{
Wt::WStringStream text;
text << "<table>"
"""<tr>"
"" "<th>${incrementHour}</th>"
"" "<th></th>"
"" "<th>${incrementMinute}</th>"
"""</tr>"
"""<tr style=\"height: 20px;\">"
"" "<td valign=\"middle\" align=\"center\">${hourText}</td>"
"" "<td valign=\"middle\" align=\"center\">:</td>"
"" "<td valign=\"middle\" align=\"center\">${minuteText}</td>"
"""</tr>"
"""<tr>"
"" "<th>${decrementHour}</th>"
"" "<th></th>"
"" "<th>${decrementMinute}</th>"
"""</tr>"
"</table>";
WTemplate *impl = new WTemplate();
setImplementation(impl);
impl->setTemplateText(WString::fromUTF8(text.str(), XHTMLUnsafeText));
WPushButton *incHourButton = new WPushButton();
incHourButton->setIcon("resources/themes/bootstrap/3/glyphicons_up.png");
WPushButton *decHourButton = new WPushButton();
decHourButton->setIcon("resources/themes/bootstrap/3/glyphicons_down.png");
WPushButton *incMinuteButton = new WPushButton();
incMinuteButton->setIcon("resources/themes/bootstrap/3/glyphicons_up.png");
WPushButton *decMinuteButton = new WPushButton();
decMinuteButton->setIcon("resources/themes/bootstrap/3/glyphicons_down.png");
hourText_ = new WText("0");
hourText_->setInline(false);
hourText_->setTextAlignment(AlignCenter);
minuteText_ = new WText("00");
minuteText_->setInline(false);
minuteText_->setTextAlignment(AlignCenter);
impl->bindWidget("incrementHour", incHourButton);
impl->bindWidget("decrementHour", decHourButton);
impl->bindWidget("hourText", hourText_);
impl->bindWidget("minuteText", minuteText_);
impl->bindWidget("incrementMinute", incMinuteButton);
impl->bindWidget("decrementMinute", decMinuteButton);
incHourButton->clicked().connect(this, &WTimePicker::incrementHours);
decHourButton->clicked().connect(this, &WTimePicker::decrementHours);
incMinuteButton->clicked().connect(this, &WTimePicker::incrementMinutes);
decMinuteButton->clicked().connect(this, &WTimePicker::decrementMinutes);
}
WTime WTimePicker::time()
{
int hours = 0, minutes = 0;
try
{
hours = boost::lexical_cast<int>(hourText_->text().toUTF8());
minutes = boost::lexical_cast<int>(minuteText_->text().toUTF8());
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
return WTime(hours, minutes);
}
void WTimePicker::setTime(const WTime& time)
{
if(!time.isValid())
{
Wt::log("error") << "Time is invalid!";
return;
}
std::string hoursStr("0"), minutesStr("00");
try
{
hoursStr = time.toString("hh").toUTF8();
minutesStr = time.toString("mm").toUTF8();
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
hourText_->setText(hoursStr);
minuteText_->setText(minutesStr);
}
void WTimePicker::incrementMinutes()
{
std::string str = minuteText_->text().toUTF8();
int curVal = 0;
if(!str.empty())
{
try
{
curVal = boost::lexical_cast<int>(str);
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
}
if((curVal += minuteStep_) >= 60)
{
curVal -= 60;
}
try
{
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << curVal;
str = ss.str();
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
minuteText_->setText(str);
selectionChanged_.emit();
}
void WTimePicker::decrementMinutes()
{
std::string str = minuteText_->text().toUTF8();
int curVal = 0;
if(!str.empty())
{
try
{
curVal = boost::lexical_cast<int>(str);
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
}
if((curVal -= minuteStep_) < 0)
{
curVal += 60;
}
try
{
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << curVal;
str = ss.str();
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
minuteText_->setText(str);
selectionChanged_.emit();
}
void WTimePicker::incrementHours()
{
std::string str = hourText_->text().toUTF8();
int curVal = 0;
if(!str.empty())
{
try
{
curVal = boost::lexical_cast<int>(str);
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
}
if((curVal + 1) < 24)
{
curVal++;
}
else
{
curVal -= 23;
}
try
{
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << curVal;
str = ss.str();
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
hourText_->setText(str);
selectionChanged_.emit();
}
void WTimePicker::decrementHours()
{
std::string str = hourText_->text().toUTF8();
int curVal = 0;
if(!str.empty())
{
try
{
curVal = boost::lexical_cast<int>(str);
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
}
if((curVal - 1) >= 0)
{
curVal--;
}
else
{
curVal += 23;
}
try
{
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << curVal;
str = ss.str();
}
catch(const boost::bad_lexical_cast& ex)
{
Wt::log("Error") << "boost::bad_lexical_cast caught in " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << "): " << ex.what();
}
hourText_->setText(str);
selectionChanged_.emit();
}
} // end namespace Wt
src/Wt/WTimeValidator 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimeValidator 2015-01-04 13:40:05.000000000 +0000
#ifndef WTIME_VALIDATOR_H_
#define WTIME_VALIDATOR_H_
#include "Wt/WValidator"
namespace Wt {
class WT_API WTimeValidator : public WValidator
{
public:
WTimeValidator(WObject *parent = 0);
WTimeValidator(const WT_USTRING &format, WObject *parent = 0);
void setFormat(const WT_USTRING &format);
virtual WT_USTRING format() const { return formats_[0]; }
/*! \brief Sets the time formats used to parse time strings.
*/
void setFormats(const std::vector<WT_USTRING>& formats);
/*! \brief Returns the time formats used to parse time strings.
*/
const std::vector<WT_USTRING>& formats() const { return formats_; }
virtual Result validate(const WT_USTRING &input) const;
void setInvalidNotATimeText(const WString &text);
WString invalidNotATimeText() const;
virtual std::string javaScriptValidate() const;
private:
std::vector<WT_USTRING> formats_;
WString notATimeText_;
static void loadJavascript(WApplication *app);
};
}
#endif // WTIME_VALIDATOR_H_
src/Wt/WTimeValidator.C 1970-01-01 01:00:00.000000000 +0100 → src/Wt/WTimeValidator.C 2015-01-04 13:40:05.000000000 +0000
#include "Wt/WApplication"
#include "Wt/WTime"
#include "Wt/WTimeValidator"
#include "Wt/WLocale"
#include "Wt/WLogger"
#include "Wt/WStringStream"
#ifndef WT_DEBUG_JS
#include "js/WTimeValidator.min.js"
#endif
namespace Wt {
LOGGER("WTimeValidator");
WTimeValidator::WTimeValidator(WObject *parent)
: WValidator(parent)
{
setFormat(WLocale::currentLocale().timeFormat());
}
WTimeValidator::WTimeValidator(const WString &format, WObject *parent)
: WValidator(parent)
{
setFormat(format);
}
void WTimeValidator::setFormat(const WT_USTRING &format)
{
if(formats_.empty() || formats_[0] != format) {
formats_.clear();
formats_.push_back(format);
repaint();
}
}
void WTimeValidator::setFormats(const std::vector<WT_USTRING>& formats)
{
formats_ = formats;
repaint();
}
WValidator::Result WTimeValidator::validate(const WT_USTRING &input) const
{
if(input.empty())
{
return WValidator::validate(input);
}
for(unsigned i = 0; i < formats_.size(); ++i)
{
try
{
WTime t = WTime::fromString(input, formats_[i]);
if(t.isValid())
{
return Result(Valid);
}
}
catch(std::exception &e)
{
LOG_WARN("validate(): " << e.what());
}
}
return Result(Invalid, invalidNotATimeText());
}
void WTimeValidator::setInvalidNotATimeText(const WString &text)
{
notATimeText_ = text;
}
WString WTimeValidator::invalidNotATimeText() const
{
if(!notATimeText_.empty())
{
WString s = notATimeText_;
s.arg(formats_[0]);
return s;
}
else
{
return WString::tr("Wt.WTimeValidator.WrongFormat").arg(formats_[0]);
}
}
std::string WTimeValidator::javaScriptValidate() const
{
loadJavascript(WApplication::instance());
WStringStream js;
js << "new " WT_CLASS ".WTimeValidator("
<< isMandatory()
<< ", [";
for(unsigned i = 0; i < formats_.size(); ++i)
{
WTime::RegExpInfo r = WTime::formatToRegExp(formats_[i]);
if(i != 0)
{
js << ',';
}
js << "{"
<< "regexp:" << WWebWidget::jsStringLiteral(r.regexp) << ','
<< "getSecond:function(results){" << r.secGetJS << ";},"
<< "getMinute:function(results){" << r.minuteGetJS << ";},"
<< "getHour:function(results){" << r.hourGetJS << ";}"
<< "}";
}
js << "],";
js << "null, ";
js << "null, ";
js << "," << invalidBlankText().jsStringLiteral()
<< "," << invalidNotATimeText().jsStringLiteral()
<< ");";
//return js.str();
return std::string();
}
void WTimeValidator::loadJavascript(WApplication *app)
{
LOAD_JAVASCRIPT(app, "js/WTimeValidator.js", "WTimeValidator", wtjs1);
}
}
    (1-1/1)