1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "q3datetimeedit.h"
31
#ifndef QT_NO_DATETIMEEDIT
33
#include <private/qinternal_p.h>
34
#include <private/q3richtext_p.h>
36
#include "q3rangecontrol.h"
37
#include "qapplication.h"
44
#include "qt_windows.h"
47
#define QDATETIMEEDIT_HIDDEN_CHAR '0'
49
class Q_COMPAT_EXPORT QNumberSection
52
QNumberSection(int selStart = 0, int selEnd = 0, bool separat = true, int actual = -1)
53
: selstart(selStart), selend(selEnd), act(actual), sep(separat)
55
int selectionStart() const { return selstart; }
56
void setSelectionStart(int s) { selstart = s; }
57
int selectionEnd() const { return selend; }
58
void setSelectionEnd(int s) { selend = s; }
59
int width() const { return selend - selstart; }
60
int index() const { return act; }
61
bool separator() const { return sep; }
62
Q_DUMMY_COMPARISON_OPERATOR(QNumberSection)
64
signed int selstart :12;
65
signed int selend :12;
70
static QString *lDateSep = 0;
71
static QString *lTimeSep = 0;
72
static bool lAMPM = false;
73
static QString *lAM = 0;
74
static QString *lPM = 0;
75
static Q3DateEdit::Order lOrder = Q3DateEdit::YMD;
76
static int refcount = 0;
92
try to get the order of DMY and the date/time separator from the locale settings
94
static void readLocaleSettings()
99
lDateSep = new QString();
100
lTimeSep = new QString();
102
#if defined(Q_WS_WIN)
105
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10);
106
*lDateSep = QString::fromUtf16((ushort*)data);
107
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10);
108
*lTimeSep = QString::fromUtf16((ushort*)data);
109
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10);
110
lAMPM = QString::fromUtf16((ushort*)data).toInt()==0;
111
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10);
112
QString am = QString::fromUtf16((ushort*)data);
114
lAM = new QString(am);
115
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10);
116
QString pm = QString::fromUtf16((ushort*)data);
118
lPM = new QString(pm);
121
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10);
122
*lDateSep = QString::fromLocal8Bit(data);
123
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10);
124
*lTimeSep = QString::fromLocal8Bit(data);
125
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10);
126
lAMPM = QString::fromLocal8Bit(data).toInt()==0;
127
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10);
128
QString am = QString::fromLocal8Bit(data);
130
lAM = new QString(am);
131
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10);
132
QString pm = QString::fromLocal8Bit(data);
134
lPM = new QString(pm);
140
QString d = QDate(1999, 11, 22).toString(Qt::LocalDate);
141
dpos = d.indexOf("22");
142
mpos = d.indexOf("11");
143
ypos = d.indexOf("99");
144
if (dpos > -1 && mpos > -1 && ypos > -1) {
145
// test for DMY, MDY, YMD, YDM
146
if (dpos < mpos && mpos < ypos) {
147
lOrder = Q3DateEdit::DMY;
148
} else if (mpos < dpos && dpos < ypos) {
149
lOrder = Q3DateEdit::MDY;
150
} else if (ypos < mpos && mpos < dpos) {
151
lOrder = Q3DateEdit::YMD;
152
} else if (ypos < dpos && dpos < mpos) {
153
lOrder = Q3DateEdit::YDM;
155
// cannot determine the dateformat - use the default
159
// this code needs to change if new formats are added
162
QString sep = d.mid(qMin(dpos, mpos) + 2, QABS(dpos - mpos) - 2);
163
if (d.count(sep) == 2) {
170
QString t = QTime(11, 22, 33).toString(Qt::LocalDate);
171
dpos = t.indexOf("11");
172
mpos = t.indexOf("22");
173
ypos = t.indexOf("33");
174
// We only allow hhmmss
175
if (dpos > -1 && dpos < mpos && mpos < ypos) {
176
QString sep = t.mid(dpos + 2, mpos - dpos - 2);
177
if (sep == t.mid(mpos + 2, ypos - mpos - 2)) {
184
static Q3DateEdit::Order localOrder() {
186
readLocaleSettings();
191
static QString localDateSep() {
193
readLocaleSettings();
198
static QString localTimeSep() {
200
readLocaleSettings();
205
class Q3DateTimeEditorPrivate
208
Q3DateTimeEditorPrivate()
210
parag(new Q3TextParagraph(0, 0, 0, false)),
213
parag->formatter()->setWrapEnabled(false);
214
cursor = new Q3TextCursor(0);
215
cursor->setParagraph(parag);
217
sep = localDateSep();
220
~Q3DateTimeEditorPrivate()
228
void appendSection(const QNumberSection& sec)
230
sections.append(sec);
237
void setSectionSelection(int sec, int selstart, int selend)
239
if (sec < 0 || sec > (int)sections.count())
241
sections[sec].setSelectionStart(selstart);
242
sections[sec].setSelectionEnd(selend);
244
uint sectionCount() const { return (uint)sections.count(); }
245
void setSeparator(const QString& s) { sep = s; }
246
QString separator() const { return sep; }
248
void setFrame(bool f) { frm = f; }
249
bool frame() const { return frm; }
251
int focusSection() const { return focusSec; }
252
int section(const QPoint& p)
254
cursor->place(p + QPoint(offset, 0), parag);
255
int idx = cursor->index();
256
for (int i = 0; i < sections.count(); ++i) {
257
if (idx >= sections[i].selectionStart() &&
258
idx <= sections[i].selectionEnd())
263
QNumberSection section(int idx) const
265
return sections[idx];
267
bool setFocusSection(int idx)
269
if (idx > (int)sections.count()-1 || idx < 0)
271
if (idx != focusSec) {
273
applyFocusSelection();
279
bool inSectionSelection(int idx)
281
for (int i = 0; i < sections.count(); ++i) {
282
if (idx >= sections[i].selectionStart() &&
283
idx <= sections[i].selectionEnd())
289
void paint(const QString& txt, bool focus, QPainter& p,
290
const QPalette&pal, const QRect& rect, QStyle *style)
294
fw = style->pixelMetric(QStyle::PM_DefaultFrameWidth);
299
parag->removeSelection(Q3TextDocument::Standard);
301
applyFocusSelection();
304
/* color all QDATETIMEEDIT_HIDDEN_CHAR chars to background color */
305
Q3TextFormat *fb = parag->formatCollection()->format(p.font(),
307
Q3TextFormat *nf = parag->formatCollection()->format(p.font(),
309
for (int i = 0; i < txt.length(); ++i) {
310
parag->setFormat(i, 1, nf);
311
if (inSectionSelection(i))
313
if (txt.at(i) == QDATETIMEEDIT_HIDDEN_CHAR)
314
parag->setFormat(i, 1, fb);
316
parag->setFormat(i, 1, nf);
321
QRect r(rect.x(), rect.y(), rect.width() - 2 * (2 + fw), rect.height());
322
parag->pseudoDocument()->docRect = r;
323
parag->invalidate(0);
326
int xoff = 2 + fw - offset;
327
int yoff = (rect.height() - parag->rect().height() + 1) / 2;
331
p.translate(xoff, yoff);
332
parag->paint(p, pal, 0, true);
334
p.translate(-xoff, -yoff);
337
void resize(const QSize& size) { sz = size; }
339
int mapSection(int sec)
341
return sections[sec].index();
345
void applyFocusSelection()
348
int selstart = sections[focusSec].selectionStart();
349
int selend = sections[focusSec].selectionEnd();
350
parag->setSelection(Q3TextDocument::Standard, selstart, selend);
352
if (parag->at(selstart)->x < offset ||
353
parag->at(selend)->x + parag->string()->width(selend) > offset + sz.width()) {
354
offset = parag->at(selstart)->x;
360
Q3TextParagraph *parag;
361
Q3TextCursor *cursor;
364
QList< QNumberSection > sections;
369
class Q3DateTimeEditor : public QWidget
373
Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char* name=0);
376
void setControlWidget(Q3DateTimeEditBase * widget);
377
Q3DateTimeEditBase * controlWidget() const;
379
void setSeparator(const QString& s);
380
QString separator() const;
382
int focusSection() const;
383
bool setFocusSection(int s);
384
void appendSection(const QNumberSection& sec);
385
void clearSections();
386
void setSectionSelection(int sec, int selstart, int selend);
387
bool eventFilter(QObject *o, QEvent *e);
388
int sectionAt(const QPoint &p);
389
int mapSection(int sec);
393
bool event(QEvent *e);
394
void resizeEvent(QResizeEvent *);
395
void paintEvent(QPaintEvent *);
396
void mousePressEvent(QMouseEvent *e);
399
Q3DateTimeEditBase* cw;
400
Q3DateTimeEditorPrivate* d;
403
class QDateTimeSpinWidget : public Q3SpinWidget
407
QDateTimeSpinWidget(QWidget *parent, const char *name)
408
: Q3SpinWidget(parent, name)
412
void changeEvent(QEvent *e)
414
if (e->type() == QEvent::EnabledChange && isEnabled()) {
415
Q3DateEdit *de = ::qobject_cast<Q3DateEdit*>(parentWidget());
417
setUpEnabled(de->date() < de->maxValue());
418
setDownEnabled(de->date() > de->minValue());
421
setDownEnabled(true);
425
void enabledChange(bool notenabled)
427
Q3DateEdit *de = qobject_cast<Q3DateEdit*>(parentWidget());
428
if (de && !notenabled) {
429
setUpEnabled(de->date() < de->maxValue());
430
setDownEnabled(de->date() > de->minValue());
432
setUpEnabled(!notenabled);
433
setDownEnabled(!notenabled);
439
#ifndef QT_NO_WHEELEVENT
440
void wheelEvent(QWheelEvent *e)
442
Q3DateTimeEditor *editor = qobject_cast<Q3DateTimeEditor*>(editWidget());
447
int section = editor->sectionAt(e->pos());
448
editor->setFocusSection(section);
452
Q3SpinWidget::wheelEvent(e);
458
Constructs an empty datetime editor with parent \a parent and
461
Q3DateTimeEditor::Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char * name)
462
: QWidget(parent, name)
464
d = new Q3DateTimeEditorPrivate();
470
Destroys the object and frees any allocated resources.
473
Q3DateTimeEditor::~Q3DateTimeEditor()
482
void Q3DateTimeEditor::init()
484
setBackgroundRole(QPalette::Base);
486
installEventFilter(this);
487
setFocusPolicy(Qt::WheelFocus);
495
bool Q3DateTimeEditor::event(QEvent *e)
497
if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
498
if (e->type() == QEvent::FocusOut)
499
qApp->sendEvent(cw, e);
501
} else if (e->type() == QEvent::ShortcutOverride) {
502
QKeyEvent* ke = (QKeyEvent*) e;
505
case Qt::Key_Backspace:
515
return QWidget::event(e);
522
void Q3DateTimeEditor::resizeEvent(QResizeEvent *e)
524
d->resize(e->size());
525
QWidget::resizeEvent(e);
533
void Q3DateTimeEditor::paintEvent(QPaintEvent *)
536
for (uint i = 0; i < d->sectionCount(); ++i) {
537
txt += cw->sectionFormattedText(i);
538
if (i < d->sectionCount()-1) {
539
if (d->section(i+1).separator())
540
txt += d->separator();
547
const QBrush &bg = palette().brush(isEnabled() ? QPalette::Base : QPalette::Background);
548
p.fillRect(0, 0, width(), height(), bg);
549
d->paint(txt, hasFocus(), p, palette(), rect(), style());
554
Returns the section index at point \a p.
556
int Q3DateTimeEditor::sectionAt(const QPoint &p)
558
return d->section(p);
561
int Q3DateTimeEditor::mapSection(int sec)
563
return d->mapSection(sec);
571
void Q3DateTimeEditor::mousePressEvent(QMouseEvent *e)
573
QPoint p(e->pos().x(), 0);
574
int sec = sectionAt(p);
576
cw->setFocusSection(sec);
584
bool Q3DateTimeEditor::eventFilter(QObject *o, QEvent *e)
587
if (e->type() == QEvent::KeyPress) {
588
QKeyEvent *ke = (QKeyEvent*)e;
591
if (d->focusSection() < (int)d->sectionCount()-1) {
592
if (cw->setFocusSection(focusSection()+1))
597
if (d->focusSection() > 0) {
598
if (cw->setFocusSection(focusSection()-1))
608
case Qt::Key_Backspace:
609
if (qobject_cast<Q3DateEdit*>(cw))
610
((Q3DateEdit*)cw)->removeFirstNumber(d->focusSection());
611
else if (qobject_cast<Q3TimeEdit*>(cw))
612
((Q3TimeEdit*)cw)->removeFirstNumber(d->focusSection());
615
cw->removeLastNumber(d->focusSection());
618
case Qt::Key_BackTab: {
619
if (ke->state() == Qt::ControlButton)
622
bool hadDateEdit = false;
624
if (qobject_cast<QDateTimeSpinWidget*>(w) || qobject_cast<Q3DateTimeEdit*>(w))
626
hadDateEdit = hadDateEdit || qobject_cast<Q3DateEdit*>(w);
627
w = w->parentWidget();
630
if (!qobject_cast<Q3DateTimeEdit*>(w)) {
631
w = w->parentWidget();
633
Q3DateTimeEdit *ed = (Q3DateTimeEdit*)w;
634
if (hadDateEdit && ke->key() == Qt::Key_Tab) {
635
ed->timeEdit()->setFocus();
637
} else if (!hadDateEdit && ke->key() == Qt::Key_BackTab) {
638
ed->dateEdit()->setFocus();
641
while (w && !qobject_cast<Q3DateTimeEdit*>(w))
642
w = w->parentWidget();
645
qApp->sendEvent(w, e);
650
QString txt = ke->text().toLower();
651
if (!txt.isEmpty() && !separator().isEmpty() && txt[0] == separator()[0]) {
652
// do the same thing as KEY_RIGHT when the user presses the separator key
653
if (d->focusSection() < 2) {
654
if (cw->setFocusSection(focusSection()+1))
658
} else if (!txt.isEmpty() && qobject_cast<Q3TimeEdit*>(cw) && focusSection() == (int) d->sectionCount()-1) {
659
// the first character of the AM/PM indicator toggles if the section has focus
660
Q3TimeEdit *te = (Q3TimeEdit*)cw;
661
QTime time = te->time();
662
if (lAMPM && lAM && lPM && (te->display()&Q3TimeEdit::AMPM)) {
663
if (txt[0] == (*lAM).toLower()[0] && time.hour() >= 12) {
664
time.setHMS(time.hour()-12, time.minute(), time.second(), time.msec());
666
} else if (txt[0] == (*lPM).toLower()[0] && time.hour() < 12) {
667
time.setHMS(time.hour()+12, time.minute(), time.second(), time.msec());
673
int num = txt[0].digitValue();
675
cw->addNumber(d->focusSection(), num);
686
Appends the number section \a sec to the editor.
689
void Q3DateTimeEditor::appendSection(const QNumberSection& sec)
691
d->appendSection(sec);
695
Removes all sections from the editor.
698
void Q3DateTimeEditor::clearSections()
704
Sets the selection of \a sec to start at \a selstart and end at \a
708
void Q3DateTimeEditor::setSectionSelection(int sec, int selstart, int selend)
710
d->setSectionSelection(sec, selstart, selend);
714
Sets the separator for all numbered sections to \a s. Note that
715
currently, only the first character of \a s is used.
718
void Q3DateTimeEditor::setSeparator(const QString& s)
726
Returns the editor's separator.
729
QString Q3DateTimeEditor::separator() const
731
return d->separator();
735
Returns the number of the section that has focus.
738
int Q3DateTimeEditor::focusSection() const
740
return d->focusSection();
745
Sets the focus to section \a sec. If \a sec does not exist,
749
bool Q3DateTimeEditor::setFocusSection(int sec)
751
return d->setFocusSection(sec);
755
\class Q3DateTimeEditBase
756
\brief The Q3DateTimeEditBase class provides an abstraction for date and edit editors.
760
Small abstract class that provides some functions that are common
761
for both Q3DateEdit and Q3TimeEdit. It is used internally by
766
\fn Q3DateTimeEditBase::Q3DateTimeEditBase(QWidget *, const char*)
771
\fn Q3DateTimeEditBase::setFocusSection(int)
775
/*! \fn QString Q3DateTimeEditBase::sectionFormattedText(int sec)
778
Pure virtual function which returns the formatted text of section \a
783
/*! \fn void Q3DateTimeEditBase::stepUp()
786
Pure virtual slot which is called whenever the user increases the
787
number in a section by pressing the widget's arrow buttons or the
788
keyboard's arrow keys.
791
/*! \fn void Q3DateTimeEditBase::stepDown()
794
Pure virtual slot which is called whenever the user decreases the
795
number in a section by pressing the widget's arrow buttons or the
796
keyboard's arrow keys.
800
/*! \fn void Q3DateTimeEditBase::addNumber(int sec, int num)
803
Pure virtual function which is called whenever the user types a number.
804
\a sec indicates the section where the number should be added. \a
805
num is the number that was pressed.
808
/*! \fn void Q3DateTimeEditBase::removeLastNumber(int sec)
811
Pure virtual function which is called whenever the user tries to
812
remove the last number from \a sec by pressing the delete key.
817
class Q3DateEditPrivate
823
// remembers the last entry for the day.
824
// if the day is 31 and you cycle through the months,
825
// the day will be 31 again if you reach a month with 31 days
826
// otherwise it will be the highest day in the month
831
Q3DateEdit::Order ord;
839
Q3DateTimeEditor *ed;
840
Q3SpinWidget *controls;
845
\class Q3DateEdit q3datetimeedit.h
846
\brief The Q3DateEdit class provides a date editor.
850
Q3DateEdit allows the user to edit dates by using the keyboard or
851
the arrow keys to increase/decrease date values. The arrow keys
852
can be used to move from section to section within the Q3DateEdit
853
box. Dates appear in accordance with the local date/time settings
854
or in year, month, day order if the system doesn't provide this
855
information. It is recommended that the Q3DateEdit be initialised
859
Q3DateEdit *dateEdit = new Q3DateEdit(QDate::currentDate(), this);
860
dateEdit->setRange(QDate::currentDate().addDays(-365),
861
QDate::currentDate().addDays( 365));
862
dateEdit->setOrder(Q3DateEdit::MDY);
863
dateEdit->setAutoAdvance(true);
866
Here we've created a new Q3DateEdit object initialised with today's
867
date and restricted the valid date range to today plus or minus
868
365 days. We've set the order to month, day, year. If the auto
869
advance property is true (as we've set it here) when the user
870
completes a section of the date, e.g. enters two digits for the
871
month, they are automatically taken to the next section.
873
The maximum and minimum values for a date value in the date editor
874
default to the maximum and minimum values for a QDate. You can
875
change this by calling setMinValue(), setMaxValue() or setRange().
877
Terminology: A Q3DateEdit widget comprises three 'sections', one
878
each for the year, month and day. You can change the separator
879
character using Q3DateTimeEditor::setSeparator(), by default the
880
separator will be taken from the systems settings. If that is
881
not possible, it defaults to "-".
883
\img datetimewidgets.png Date Time Widgets
885
\sa QDate Q3TimeEdit Q3DateTimeEdit
889
\enum Q3DateEdit::Order
891
This enum defines the order in which the sections that comprise a
894
\value MDY month-day-year
895
\value DMY day-month-year
896
\value YMD year-month-day (the default)
901
\enum Q3TimeEdit::Display
903
This enum defines the sections that comprise a time
905
\value Hours The hours section
906
\value Minutes The minutes section
907
\value Seconds The seconds section
908
\value AMPM The AM/PM section
910
The values can be or'ed together to show any combination.
914
Constructs an empty date editor which is a child of \a parent and
918
Q3DateEdit::Q3DateEdit(QWidget * parent, const char * name)
919
: Q3DateTimeEditBase(parent, name)
928
Constructs a date editor with the initial value \a date, parent \a
929
parent and called \a name.
931
The date editor is initialized with \a date.
934
Q3DateEdit::Q3DateEdit(const QDate& date, QWidget * parent, const char * name)
935
: Q3DateTimeEditBase(parent, name)
943
void Q3DateEdit::init()
945
d = new Q3DateEditPrivate();
946
d->controls = new QDateTimeSpinWidget(this, 0);
947
d->ed = new Q3DateTimeEditor(this, d->controls);
948
d->controls->setEditWidget(d->ed);
949
setFocusProxy(d->ed);
950
connect(d->controls, SIGNAL(stepUpPressed()), SLOT(stepUp()));
951
connect(d->controls, SIGNAL(stepDownPressed()), SLOT(stepDown()));
952
connect(this, SIGNAL(valueChanged(QDate)), SLOT(updateButtons()));
953
d->ed->appendSection(QNumberSection(0,4));
954
d->ed->appendSection(QNumberSection(5,7));
955
d->ed->appendSection(QNumberSection(8,10));
958
d->monthSection = -1;
965
setOrder(localOrder());
971
d->min = QDate(1752, 9, 14);
972
d->max = QDate(8000, 12, 31);
975
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
981
Destroys the object and frees any allocated resources.
984
Q3DateEdit::~Q3DateEdit()
992
\property Q3DateEdit::minValue
994
\brief the editor's minimum value
996
Setting the minimum date value is equivalent to calling
997
Q3DateEdit::setRange(\e d, maxValue()), where \e d is the minimum
998
date. The default minimum date is 1752-09-14.
1000
\sa maxValue setRange()
1003
QDate Q3DateEdit::minValue() const
1009
\property Q3DateEdit::maxValue
1011
\brief the editor's maximum value
1013
Setting the maximum date value for the editor is equivalent to
1014
calling Q3DateEdit::setRange(minValue(), \e d), where \e d is the
1015
maximum date. The default maximum date is 8000-12-31.
1017
\sa minValue setRange()
1020
QDate Q3DateEdit::maxValue() const
1027
Sets the valid input range for the editor to be from \a min to \a
1028
max inclusive. If \a min is invalid no minimum date will be set.
1029
Similarly, if \a max is invalid no maximum date will be set.
1032
void Q3DateEdit::setRange(const QDate& min, const QDate& max)
1041
Sets the separator to \a s. Note that currently only the first
1042
character of \a s is used.
1045
void Q3DateEdit::setSeparator(const QString& s)
1047
d->ed->setSeparator(s);
1051
Returns the editor's separator.
1054
QString Q3DateEdit::separator() const
1056
return d->ed->separator();
1061
Enables/disables the push buttons according to the min/max date
1065
void Q3DateEdit::updateButtons()
1070
bool upEnabled = date() < maxValue();
1071
bool downEnabled = date() > minValue();
1073
d->controls->setUpEnabled(upEnabled);
1074
d->controls->setDownEnabled(downEnabled);
1079
void Q3DateEdit::resizeEvent(QResizeEvent *)
1081
d->controls->resize(width(), height());
1087
QSize Q3DateEdit::sizeHint() const
1090
QFontMetrics fm(font());
1091
int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
1092
int h = qMax(fm.lineSpacing(), 14) + 2;
1093
int w = 2 + fm.width('9') * 8 + fm.width(d->ed->separator()) * 2 + d->controls->upRect().width() + fw * 4;
1095
return QSize(w, qMax(h + fw * 2,20)).expandedTo(QApplication::globalStrut());
1101
QSize Q3DateEdit::minimumSizeHint() const
1108
Returns the formatted number for section \a sec. This will
1109
correspond to either the year, month or day section, depending on
1110
the current display order.
1115
QString Q3DateEdit::sectionFormattedText(int sec)
1118
txt = sectionText(sec);
1119
if (d->typing && sec == d->ed->focusSection())
1120
d->ed->setSectionSelection(sec, sectionOffsetEnd(sec) - txt.length(),
1121
sectionOffsetEnd(sec));
1123
d->ed->setSectionSelection(sec, sectionOffsetEnd(sec) - sectionLength(sec),
1124
sectionOffsetEnd(sec));
1125
txt = txt.rightJustified(sectionLength(sec), QDATETIMEEDIT_HIDDEN_CHAR);
1131
Returns the desired length (number of digits) of section \a sec.
1132
This will correspond to either the year, month or day section,
1133
depending on the current display order.
1138
int Q3DateEdit::sectionLength(int sec) const
1141
if (sec == d->yearSection) {
1143
} else if (sec == d->monthSection) {
1145
} else if (sec == d->daySection) {
1152
Returns the text of section \a sec. This will correspond to either
1153
the year, month or day section, depending on the current display
1159
QString Q3DateEdit::sectionText(int sec) const
1162
if (sec == d->yearSection) {
1164
} else if (sec == d->monthSection) {
1166
} else if (sec == d->daySection) {
1169
return QString::number(val);
1174
Returns the end of the section offset \a sec.
1178
int Q3DateEdit::sectionOffsetEnd(int sec) const
1180
if (sec == d->yearSection) {
1184
return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
1187
return sectionLength(sec);
1189
} else if (sec == d->monthSection) {
1194
return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
1196
return sectionLength(sec);
1198
} else if (sec == d->daySection) {
1201
return sectionLength(sec);
1205
return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
1213
\property Q3DateEdit::order
1214
\brief the order in which the year, month and day appear
1216
The default order is locale dependent.
1221
void Q3DateEdit::setOrder(Q3DateEdit::Order order)
1227
d->monthSection = 1;
1232
d->monthSection = 0;
1237
d->monthSection = 1;
1242
d->monthSection = 2;
1247
d->ed->repaint(d->ed->rect());
1251
Q3DateEdit::Order Q3DateEdit::order() const
1260
void Q3DateEdit::stepUp()
1262
int sec = d->ed->focusSection();
1263
bool accepted = false;
1264
if (sec == d->yearSection) {
1265
if (!outOfRange(d->y+1, d->m, d->d)) {
1269
} else if (sec == d->monthSection) {
1270
if (!outOfRange(d->y, d->m+1, d->d)) {
1274
} else if (sec == d->daySection) {
1275
if (!outOfRange(d->y, d->m, d->d+1)) {
1282
emit valueChanged(date());
1284
d->ed->repaint(d->ed->rect());
1293
void Q3DateEdit::stepDown()
1295
int sec = d->ed->focusSection();
1296
bool accepted = false;
1297
if (sec == d->yearSection) {
1298
if (!outOfRange(d->y-1, d->m, d->d)) {
1302
} else if (sec == d->monthSection) {
1303
if (!outOfRange(d->y, d->m-1, d->d)) {
1307
} else if (sec == d->daySection) {
1308
if (!outOfRange(d->y, d->m, d->d-1)) {
1315
emit valueChanged(date());
1317
d->ed->repaint(d->ed->rect());
1321
Sets the year to \a year, which must be a valid year. The range
1322
currently supported is from 1752 to 8000.
1327
void Q3DateEdit::setYear(int year)
1333
if (!outOfRange(year, d->m, d->d)) {
1336
int tmp = d->dayCache;
1337
setDay(d->dayCache);
1344
Sets the month to \a month, which must be a valid month, i.e.
1348
void Q3DateEdit::setMonth(int month)
1354
if (!outOfRange(d->y, month, d->d)) {
1356
int tmp = d->dayCache;
1357
setDay(d->dayCache);
1364
Sets the day to \a day, which must be a valid day. The function
1365
will ensure that the \a day set is valid for the month and year.
1368
void Q3DateEdit::setDay(int day)
1374
if (d->m > 0 && d->y > 1752) {
1375
while (!QDate::isValid(d->y, d->m, day))
1377
if (!outOfRange(d->y, d->m, day))
1379
} else if (d->m > 0) {
1380
if (day > 0 && day < 32) {
1381
if (!outOfRange(d->y, d->m, day))
1390
\property Q3DateEdit::date
1391
\brief the editor's date value.
1393
If the date property is not valid, the editor displays all zeroes
1394
and Q3DateEdit::date() will return an invalid date. It is strongly
1395
recommended that the editor is given a default date value (e.g.
1396
currentDate()). That way, attempts to set the date property to an
1397
invalid date will fail.
1399
When changing the date property, if the date is less than
1400
minValue(), or is greater than maxValue(), nothing happens.
1403
void Q3DateEdit::setDate(const QDate& date)
1405
if (!date.isValid()) {
1411
if (date > maxValue() || date < minValue())
1414
d->m = date.month();
1417
emit valueChanged(date);
1420
d->ed->repaint(d->ed->rect());
1423
QDate Q3DateEdit::date() const
1425
if (QDate::isValid(d->y, d->m, d->d))
1426
return QDate(d->y, d->m, d->d);
1432
Returns true if \a y, \a m, \a d is out of range, otherwise returns
1439
bool Q3DateEdit::outOfRange(int y, int m, int d) const
1441
if (QDate::isValid(y, m, d)) {
1442
QDate currentDate(y, m, d);
1443
if (currentDate > maxValue() ||
1444
currentDate < minValue()) {
1445
//## outOfRange should set overwrite?
1450
return false; /* assume ok */
1457
void Q3DateEdit::addNumber(int sec, int num)
1461
killTimer(d->timerId);
1462
bool overwrite = false;
1463
bool accepted = false;
1466
if (sec == d->yearSection) {
1467
txt = QString::number(d->y);
1468
if (d->overwrite || txt.length() == 4) {
1472
txt += QString::number(num);
1473
if (txt.length() == 4 ) {
1474
int val = txt.toInt();
1477
else if (val > 8000)
1479
else if (outOfRange(val, d->m, d->d))
1480
txt = QString::number(d->y);
1489
if (d->adv && txt.length() == 4) {
1490
d->ed->setFocusSection(d->ed->focusSection()+1);
1494
} else if (sec == d->monthSection) {
1495
txt = QString::number(d->m);
1496
if (d->overwrite || txt.length() == 2) {
1500
txt += QString::number(num);
1501
int temp = txt.toInt();
1504
if (outOfRange(d->y, temp, d->d))
1505
txt = QString::number(d->m);
1510
if (d->adv && txt.length() == 2) {
1511
d->ed->setFocusSection(d->ed->focusSection()+1);
1515
} else if (sec == d->daySection) {
1516
txt = QString::number(d->d);
1517
if (d->overwrite || txt.length() == 2) {
1522
txt += QString::number(num);
1523
int temp = txt.toInt();
1526
if (outOfRange(d->y, d->m, temp))
1527
txt = QString::number(d->d);
1533
if (d->adv && txt.length() == 2) {
1534
d->ed->setFocusSection(d->ed->focusSection()+1);
1541
emit valueChanged(date());
1543
d->overwrite = overwrite;
1544
d->timerId = startTimer(qApp->doubleClickInterval()*4);
1545
d->ed->repaint(d->ed->rect());
1553
bool Q3DateEdit::setFocusSection(int s)
1555
if (s != d->ed->focusSection()) {
1556
killTimer(d->timerId);
1557
d->overwrite = true;
1559
fix(); // will emit valueChanged if necessary
1561
return d->ed->setFocusSection(s);
1566
Attempts to fix any invalid date entries.
1568
The rules applied are as follows:
1571
\i If the year has four digits it is left unchanged.
1572
\i If the year has two digits, the year will be changed to four
1573
digits in the range current year - 70 to current year + 29.
1574
\i If the year has three digits in the range 100..999, the
1575
current millennium, i.e. 2000, will be added giving a year
1576
in the range 2100..2999.
1577
\i If the day or month is 0 then it will be set to 1 or the
1578
minimum valid day/month in the range.
1582
void Q3DateEdit::fix()
1584
bool changed = false;
1585
int currentYear = QDate::currentDate().year();
1588
int currentCentury = currentYear / 100;
1589
year += currentCentury * 100;
1590
if (currentYear > year) {
1591
if (currentYear > year + 70)
1594
if (year >= currentYear + 30)
1598
} else if (year < 1000) {
1599
int currentMillennium = currentYear / 10;
1600
year += currentMillennium * 10;
1602
} else if (d->d == 0) {
1605
} else if (d->m == 0) {
1609
if (outOfRange(year, d->m, d->d)) {
1610
if (minValue().isValid() && date() < minValue()) {
1611
d->d = minValue().day();
1613
d->m = minValue().month();
1614
d->y = minValue().year();
1616
if (date() > maxValue()) {
1617
d->d = maxValue().day();
1619
d->m = maxValue().month();
1620
d->y = maxValue().year();
1626
emit valueChanged(date());
1636
bool Q3DateEdit::event(QEvent *e)
1638
if(e->type() == QEvent::FocusOut) {
1641
// the following can't be done in fix() because fix() called
1642
// from all over the place and it will break the old behaviour
1643
if (!QDate::isValid(d->y, d->m, d->d)) {
1646
for (; i > 0; i--) {
1648
if (QDate::isValid(d->y, d->m, d->d))
1654
emit valueChanged(date());
1657
} else if (e->type() == QEvent::LocaleChange) {
1658
readLocaleSettings();
1659
d->ed->setSeparator(localDateSep());
1660
setOrder(localOrder());
1662
return Q3DateTimeEditBase::event(e);
1668
Function which is called whenever the user tries to
1669
remove the first number from \a sec by pressing the backspace key.
1672
void Q3DateEdit::removeFirstNumber(int sec)
1677
if (sec == d->yearSection) {
1678
txt = QString::number(d->y);
1679
txt = txt.mid(1, txt.length()) + "0";
1681
} else if (sec == d->monthSection) {
1682
txt = QString::number(d->m);
1683
txt = txt.mid(1, txt.length()) + "0";
1685
} else if (sec == d->daySection) {
1686
txt = QString::number(d->d);
1687
txt = txt.mid(1, txt.length()) + "0";
1691
d->ed->repaint(d->ed->rect());
1698
void Q3DateEdit::removeLastNumber(int sec)
1703
if (sec == d->yearSection) {
1704
txt = QString::number(d->y);
1705
txt = txt.mid(0, txt.length()-1);
1707
} else if (sec == d->monthSection) {
1708
txt = QString::number(d->m);
1709
txt = txt.mid(0, txt.length()-1);
1711
} else if (sec == d->daySection) {
1712
txt = QString::number(d->d);
1713
txt = txt.mid(0, txt.length()-1);
1717
d->ed->repaint(d->ed->rect());
1721
\property Q3DateEdit::autoAdvance
1722
\brief whether the editor automatically advances to the next
1725
If autoAdvance is true, the editor will automatically advance
1726
focus to the next date section if a user has completed a section.
1727
The default is false.
1730
void Q3DateEdit::setAutoAdvance(bool advance)
1736
bool Q3DateEdit::autoAdvance() const
1744
void Q3DateEdit::timerEvent(QTimerEvent *)
1746
d->overwrite = true;
1750
\fn void Q3DateEdit::valueChanged(const QDate& date)
1752
This signal is emitted whenever the editor's value changes. The \a
1753
date parameter is the new value.
1758
class Q3TimeEditPrivate
1772
Q3DateTimeEditor *ed;
1773
Q3SpinWidget *controls;
1777
\class Q3TimeEdit q3datetimeedit.h
1778
\brief The Q3TimeEdit class provides a time editor.
1782
Q3TimeEdit allows the user to edit times by using the keyboard or
1783
the arrow keys to increase/decrease time values. The arrow keys
1784
can be used to move from section to section within the Q3TimeEdit
1785
box. The user can automatically be moved to the next section once
1786
they complete a section using setAutoAdvance(). Times appear in
1787
hour, minute, second order. It is recommended that the Q3TimeEdit
1788
is initialised with a time, e.g.
1790
QTime timeNow = QTime::currentTime();
1791
Q3TimeEdit *timeEdit = new Q3TimeEdit(timeNow, this);
1792
timeEdit->setRange(timeNow, timeNow.addSecs(60 * 60));
1794
Here we've created a Q3TimeEdit widget set to the current time.
1795
We've also set the minimum value to the current time and the
1796
maximum time to one hour from now.
1798
The maximum and minimum values for a time value in the time editor
1799
default to the maximum and minimum values for a QTime. You can
1800
change this by calling setMinValue(), setMaxValue() or setRange().
1802
Terminology: A QTimeWidget consists of three sections, one each
1803
for the hour, minute and second. You can change the separator
1804
character using setSeparator(), by default the separator is read
1805
from the system's settings.
1807
\img datetimewidgets.png Date Time Widgets
1809
\sa QTime Q3DateEdit Q3DateTimeEdit
1814
Constructs an empty time edit with parent \a parent and called \a
1818
Q3TimeEdit::Q3TimeEdit(QWidget * parent, const char * name)
1819
: Q3DateTimeEditBase(parent, name)
1827
Constructs a time edit with the initial time value, \a time,
1828
parent \a parent and called \a name.
1831
Q3TimeEdit::Q3TimeEdit(const QTime& time, QWidget * parent, const char * name)
1832
: Q3DateTimeEditBase(parent, name)
1841
void Q3TimeEdit::init()
1843
d = new Q3TimeEditPrivate();
1844
d->controls = new QDateTimeSpinWidget(this, 0);
1845
d->ed = new Q3DateTimeEditor(this, d->controls, "time edit base");
1846
d->controls->setEditWidget(d->ed);
1847
setFocusProxy(d->ed);
1848
connect(d->controls, SIGNAL(stepUpPressed()), SLOT(stepUp()));
1849
connect(d->controls, SIGNAL(stepDownPressed()), SLOT(stepDown()));
1851
d->ed->appendSection(QNumberSection(0,0, true, 0));
1852
d->ed->appendSection(QNumberSection(0,0, true, 1));
1853
d->ed->appendSection(QNumberSection(0,0, true, 2));
1854
d->ed->setSeparator(localTimeSep());
1859
d->display = Hours | Minutes | Seconds;
1862
d->ed->appendSection(QNumberSection(0,0, false, 3));
1865
d->overwrite = true;
1868
d->min = QTime(0, 0, 0);
1869
d->max = QTime(23, 59, 59);
1872
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
1878
Destroys the object and frees any allocated resources.
1881
Q3TimeEdit::~Q3TimeEdit()
1889
\property Q3TimeEdit::minValue
1890
\brief the minimum time value
1892
Setting the minimum time value is equivalent to calling
1893
Q3TimeEdit::setRange(\e t, maxValue()), where \e t is the minimum
1894
time. The default minimum time is 00:00:00.
1896
\sa maxValue setRange()
1899
QTime Q3TimeEdit::minValue() const
1905
\property Q3TimeEdit::maxValue
1906
\brief the maximum time value
1908
Setting the maximum time value is equivalent to calling
1909
Q3TimeEdit::setRange(minValue(), \e t), where \e t is the maximum
1910
time. The default maximum time is 23:59:59.
1912
\sa minValue setRange()
1915
QTime Q3TimeEdit::maxValue() const
1922
Sets the valid input range for the editor to be from \a min to \a
1923
max inclusive. If \a min is invalid no minimum time is set.
1924
Similarly, if \a max is invalid no maximum time is set.
1927
void Q3TimeEdit::setRange(const QTime& min, const QTime& max)
1936
\property Q3TimeEdit::display
1937
\brief the sections that are displayed in the time edit
1939
The value can be any combination of the values in the Display enum.
1940
By default, the widget displays hours, minutes and seconds.
1942
void Q3TimeEdit::setDisplay(uint display)
1944
if (d->display == display)
1947
d->ed->clearSections();
1948
d->display = display;
1949
if (d->display & Hours)
1950
d->ed->appendSection(QNumberSection(0,0, true, 0));
1951
if (d->display & Minutes)
1952
d->ed->appendSection(QNumberSection(0,0, true, 1));
1953
if (d->display & Seconds)
1954
d->ed->appendSection(QNumberSection(0,0, true, 2));
1955
if (d->display & AMPM)
1956
d->ed->appendSection(QNumberSection(0,0, false, 3));
1958
d->ed->setFocusSection(0);
1962
uint Q3TimeEdit::display() const
1968
\property Q3TimeEdit::time
1969
\brief the editor's time value.
1971
When changing the time property, if the time is less than
1972
minValue(), or is greater than maxValue(), nothing happens.
1975
void Q3TimeEdit::setTime(const QTime& time)
1977
if (!time.isValid()) {
1982
if (time > maxValue() || time < minValue())
1985
d->m = time.minute();
1986
d->s = time.second();
1987
emit valueChanged(time);
1990
d->ed->repaint(d->ed->rect());
1993
QTime Q3TimeEdit::time() const
1995
if (QTime::isValid(d->h, d->m, d->s))
1996
return QTime(d->h, d->m, d->s);
2001
\property Q3TimeEdit::autoAdvance
2002
\brief whether the editor automatically advances to the next
2005
If autoAdvance is true, the editor will automatically advance
2006
focus to the next time section if a user has completed a section.
2007
The default is false.
2010
void Q3TimeEdit::setAutoAdvance(bool advance)
2015
bool Q3TimeEdit::autoAdvance() const
2021
Sets the separator to \a s. Note that currently only the first
2022
character of \a s is used.
2025
void Q3TimeEdit::setSeparator(const QString& s)
2027
d->ed->setSeparator(s);
2031
Returns the editor's separator.
2034
QString Q3TimeEdit::separator() const
2036
return d->ed->separator();
2041
\fn void Q3TimeEdit::valueChanged(const QTime& time)
2043
This signal is emitted whenever the editor's value changes. The \a
2044
time parameter is the new value.
2051
bool Q3TimeEdit::event(QEvent *e)
2053
if (e->type() == QEvent::FocusOut) {
2056
emit valueChanged(time());
2059
} else if (e->type() == QEvent::LocaleChange) {
2060
readLocaleSettings();
2061
d->ed->setSeparator(localTimeSep());
2063
return Q3DateTimeEditBase::event(e);
2070
void Q3TimeEdit::timerEvent(QTimerEvent *)
2072
d->overwrite = true;
2080
void Q3TimeEdit::stepUp()
2082
int sec = d->ed->mapSection(d->ed->focusSection());
2083
bool accepted = true;
2086
if (!outOfRange(d->h+1, d->m, d->s))
2089
setHour(d->min.hour());
2092
if (!outOfRange(d->h, d->m+1, d->s))
2095
setMinute(d->min.minute());
2098
if (!outOfRange(d->h, d->m, d->s+1))
2101
setSecond(d->min.second());
2111
qWarning("Q3TimeEdit::stepUp: Focus section out of range!");
2116
emit valueChanged(time());
2118
d->ed->repaint(d->ed->rect());
2126
void Q3TimeEdit::stepDown()
2128
int sec = d->ed->mapSection(d->ed->focusSection());
2130
bool accepted = true;
2133
if (!outOfRange(d->h-1, d->m, d->s))
2136
setHour(d->max.hour());
2139
if (!outOfRange(d->h, d->m-1, d->s))
2142
setMinute(d->max.minute());
2145
if (!outOfRange(d->h, d->m, d->s-1))
2148
setSecond(d->max.second());
2158
qWarning("Q3TimeEdit::stepDown: Focus section out of range!");
2163
emit valueChanged(time());
2165
d->ed->repaint(d->ed->rect());
2170
Returns the formatted number for section \a sec. This will
2171
correspond to either the hour, minute or second section, depending
2175
QString Q3TimeEdit::sectionFormattedText(int sec)
2178
txt = sectionText(sec);
2179
txt = txt.rightJustified(2, QDATETIMEEDIT_HIDDEN_CHAR);
2180
int offset = sec*2+sec*separator().length() + txt.length();
2181
if (d->typing && sec == d->ed->focusSection())
2182
d->ed->setSectionSelection(sec, offset - txt.length(), offset);
2184
d->ed->setSectionSelection(sec, offset - txt.length(), offset);
2194
bool Q3TimeEdit::setFocusSection(int sec)
2196
if (sec != d->ed->focusSection()) {
2197
killTimer(d->timerId);
2198
d->overwrite = true;
2200
QString txt = sectionText(sec);
2201
txt = txt.rightJustified(2, QDATETIMEEDIT_HIDDEN_CHAR);
2202
int offset = sec*2+sec*separator().length() + txt.length();
2203
d->ed->setSectionSelection(sec, offset - txt.length(), offset);
2205
emit valueChanged(time());
2209
return d->ed->setFocusSection(sec);
2214
Sets the hour to \a h, which must be a valid hour, i.e. in the
2218
void Q3TimeEdit::setHour(int h)
2229
Sets the minute to \a m, which must be a valid minute, i.e. in the
2233
void Q3TimeEdit::setMinute(int m)
2244
Sets the second to \a s, which must be a valid second, i.e. in the
2248
void Q3TimeEdit::setSecond(int s)
2260
Returns the text of section \a sec.
2264
QString Q3TimeEdit::sectionText(int sec)
2266
sec = d->ed->mapSection(sec);
2271
if (!(d->display & AMPM) || (d->h < 13 && d->h)) { // I wished the day stared at 0:00 for everybody
2272
txt = QString::number(d->h);
2275
txt = QString::number(d->h - 12);
2281
txt = QString::number(d->m);
2284
txt = QString::number(d->s);
2291
txt = QString::fromLatin1("AM");
2296
txt = QString::fromLatin1("PM");
2307
Returns true if \a h, \a m, and \a s are out of range.
2310
bool Q3TimeEdit::outOfRange(int h, int m, int s) const
2312
if (QTime::isValid(h, m, s)) {
2313
QTime currentTime(h, m, s);
2314
if (currentTime > maxValue() ||
2315
currentTime < minValue())
2327
void Q3TimeEdit::addNumber(int sec, int num)
2331
sec = d->ed->mapSection(sec);
2332
killTimer(d->timerId);
2333
bool overwrite = false;
2334
bool accepted = false;
2340
txt = (d->display & AMPM && d->h > 12) ?
2341
QString::number(d->h - 12) : QString::number(d->h);
2343
if (d->overwrite || txt.length() == 2) {
2344
if (d->display & AMPM && num == 0)
2345
break; // Don't process 0 in 12 hour clock mode
2346
if (d->display & AMPM && d->h > 11)
2348
if (!outOfRange(num, d->m, d->s)) {
2353
txt += QString::number(num);
2354
int temp = txt.toInt();
2356
if (d->display & AMPM) {
2362
} else if (outOfRange(temp + 12, d->m, d->s)) {
2363
txt = QString::number(d->h);
2370
} else if (!(d->display & AMPM) && outOfRange(temp, d->m, d->s)) {
2371
txt = QString::number(d->h);
2379
if (d->adv && txt.length() == 2) {
2380
setFocusSection(d->ed->focusSection()+1);
2387
txt = QString::number(d->m);
2388
if (d->overwrite || txt.length() == 2) {
2389
if (!outOfRange(d->h, num, d->s)) {
2394
txt += QString::number(num);
2395
int temp = txt.toInt();
2398
if (outOfRange(d->h, temp, d->s))
2399
txt = QString::number(d->m);
2404
if (d->adv && txt.length() == 2) {
2405
setFocusSection(d->ed->focusSection()+1);
2412
txt = QString::number(d->s);
2413
if (d->overwrite || txt.length() == 2) {
2414
if (!outOfRange(d->h, d->m, num)) {
2419
txt += QString::number(num);
2420
int temp = txt.toInt();
2423
if (outOfRange(d->h, d->m, temp))
2424
txt = QString::number(d->s);
2429
if (d->adv && txt.length() == 2) {
2430
setFocusSection(d->ed->focusSection()+1);
2442
d->changed = accepted;
2444
emit valueChanged(time());
2445
d->overwrite = overwrite;
2446
d->timerId = startTimer(qApp->doubleClickInterval()*4);
2447
d->ed->repaint(d->ed->rect());
2454
Function which is called whenever the user tries to
2455
remove the first number from \a sec by pressing the backspace key.
2458
void Q3TimeEdit::removeFirstNumber(int sec)
2462
sec = d->ed->mapSection(sec);
2466
txt = QString::number(d->h);
2469
txt = QString::number(d->m);
2472
txt = QString::number(d->s);
2475
txt = txt.mid(1, txt.length()) + "0";
2487
d->ed->repaint(d->ed->rect());
2493
void Q3TimeEdit::removeLastNumber(int sec)
2497
sec = d->ed->mapSection(sec);
2501
txt = QString::number(d->h);
2504
txt = QString::number(d->m);
2507
txt = QString::number(d->s);
2510
txt = txt.mid(0, txt.length()-1);
2522
d->ed->repaint(d->ed->rect());
2527
void Q3TimeEdit::resizeEvent(QResizeEvent *)
2529
d->controls->resize(width(), height());
2534
QSize Q3TimeEdit::sizeHint() const
2537
QFontMetrics fm(font());
2538
int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
2539
int h = fm.lineSpacing() + 2;
2540
int w = 2 + fm.width('9') * 6 + fm.width(d->ed->separator()) * 2 +
2541
d->controls->upRect().width() + fw * 4;
2542
if (d->display & AMPM) {
2544
w += fm.width(*lAM) + 4;
2546
w += fm.width(QString::fromLatin1("AM")) + 4;
2549
return QSize(w, qMax(h + fw * 2,20)).expandedTo(QApplication::globalStrut());
2554
QSize Q3TimeEdit::minimumSizeHint() const
2561
Enables/disables the push buttons according to the min/max time
2565
// ### Remove in 4.0?
2567
void Q3TimeEdit::updateButtons()
2572
bool upEnabled = time() < maxValue();
2573
bool downEnabled = time() > minValue();
2575
d->controls->setUpEnabled(upEnabled);
2576
d->controls->setDownEnabled(downEnabled);
2580
class Q3DateTimeEditPrivate
2587
\class Q3DateTimeEdit q3datetimeedit.h
2588
\brief The Q3DateTimeEdit class combines a Q3DateEdit and Q3TimeEdit
2589
widget into a single widget for editing datetimes.
2593
Q3DateTimeEdit consists of a Q3DateEdit and Q3TimeEdit widget placed
2594
side by side and offers the functionality of both. The user can
2595
edit the date and time by using the keyboard or the arrow keys to
2596
increase/decrease date or time values. The Tab key can be used to
2597
move from section to section within the Q3DateTimeEdit widget, and
2598
the user can be moved automatically when they complete a section
2599
using setAutoAdvance(). The datetime can be set with
2602
The date format is read from the system's locale settings. It is
2603
set to year, month, day order if that is not possible. See
2604
Q3DateEdit::setOrder() to change this. Times appear in the order
2605
hours, minutes, seconds using the 24 hour clock.
2607
It is recommended that the Q3DateTimeEdit is initialised with a
2610
Q3DateTimeEdit *dateTimeEdit = new Q3DateTimeEdit(QDateTime::currentDateTime(), this);
2611
dateTimeEdit->dateEdit()->setRange(QDateTime::currentDate(),
2612
QDateTime::currentDate().addDays(7));
2614
Here we've created a new Q3DateTimeEdit set to the current date and
2615
time, and set the date to have a minimum date of now and a maximum
2616
date of a week from now.
2618
Terminology: A Q3DateEdit widget consists of three 'sections', one
2619
each for the year, month and day. Similarly a Q3TimeEdit consists
2620
of three sections, one each for the hour, minute and second. The
2621
character that separates each date section is specified with
2622
setDateSeparator(); similarly setTimeSeparator() is used for the
2625
\img datetimewidgets.png Date Time Widgets
2627
\sa Q3DateEdit Q3TimeEdit
2631
Constructs an empty datetime edit with parent \a parent and called
2634
Q3DateTimeEdit::Q3DateTimeEdit(QWidget * parent, const char * name)
2635
: QWidget(parent, name)
2644
Constructs a datetime edit with the initial value \a datetime,
2645
parent \a parent and called \a name.
2647
Q3DateTimeEdit::Q3DateTimeEdit(const QDateTime& datetime,
2648
QWidget * parent, const char * name)
2649
: QWidget(parent, name)
2652
setDateTime(datetime);
2658
Destroys the object and frees any allocated resources.
2661
Q3DateTimeEdit::~Q3DateTimeEdit()
2670
Intercepts and handles resize events which have special meaning
2671
for the Q3DateTimeEdit.
2674
void Q3DateTimeEdit::resizeEvent(QResizeEvent *)
2676
int dw = de->sizeHint().width();
2677
int tw = te->sizeHint().width();
2680
int extra = w - (dw + tw);
2682
if (tw + extra < 0) {
2685
dw += 9 * extra / 16;
2689
de->setGeometry(0, 0, dw, h);
2690
te->setGeometry(dw, 0, tw, h);
2696
QSize Q3DateTimeEdit::minimumSizeHint() const
2698
QSize dsh = de->minimumSizeHint();
2699
QSize tsh = te->minimumSizeHint();
2700
return QSize(dsh.width() + tsh.width(),
2701
qMax(dsh.height(), tsh.height()));
2707
void Q3DateTimeEdit::init()
2709
d = new Q3DateTimeEditPrivate();
2710
de = new Q3DateEdit(this, "qt_datetime_dateedit");
2711
te = new Q3TimeEdit(this, "qt_datetime_timeedit");
2713
connect(de, SIGNAL(valueChanged(QDate)), this, SLOT(newValue(QDate)));
2714
connect(te, SIGNAL(valueChanged(QTime)), this, SLOT(newValue(QTime)));
2716
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
2722
QSize Q3DateTimeEdit::sizeHint() const
2725
QSize dsh = de->sizeHint();
2726
QSize tsh = te->sizeHint();
2727
return QSize(dsh.width() + tsh.width(),
2728
qMax(dsh.height(), tsh.height()));
2732
\property Q3DateTimeEdit::dateTime
2733
\brief the editor's datetime value
2735
The datetime edit's datetime which may be an invalid datetime.
2738
void Q3DateTimeEdit::setDateTime(const QDateTime & dt)
2741
de->setDate(dt.date());
2742
te->setTime(dt.time());
2743
emit valueChanged(dt);
2747
QDateTime Q3DateTimeEdit::dateTime() const
2749
return QDateTime(de->date(), te->time());
2753
\fn void Q3DateTimeEdit::valueChanged(const QDateTime& datetime)
2755
This signal is emitted every time the date or time changes. The \a
2756
datetime argument is the new datetime.
2762
Re-emits the value \a d.
2765
void Q3DateTimeEdit::newValue(const QDate&)
2767
QDateTime dt = dateTime();
2768
emit valueChanged(dt);
2773
Re-emits the value \a t.
2776
void Q3DateTimeEdit::newValue(const QTime&)
2778
QDateTime dt = dateTime();
2779
emit valueChanged(dt);
2784
Sets the auto advance property of the editor to \a advance. If set
2785
to true, the editor will automatically advance focus to the next
2786
date or time section if the user has completed a section.
2789
void Q3DateTimeEdit::setAutoAdvance(bool advance)
2791
de->setAutoAdvance(advance);
2792
te->setAutoAdvance(advance);
2796
Returns true if auto-advance is enabled, otherwise returns false.
2798
\sa setAutoAdvance()
2801
bool Q3DateTimeEdit::autoAdvance() const
2803
return de->autoAdvance();
2807
\fn Q3DateEdit* Q3DateTimeEdit::dateEdit()
2809
Returns the internal widget used for editing the date part of the
2814
\fn Q3TimeEdit* Q3DateTimeEdit::timeEdit()
2816
Returns the internal widget used for editing the time part of the
2820
#include "q3datetimeedit.moc"