Feature #3725 » timeedit.patch
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???fy???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);
|
||
}
|
||
}
|