~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/qt3support/widgets/q3datetimeedit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "q3datetimeedit.h"
 
30
 
 
31
#ifndef QT_NO_DATETIMEEDIT
 
32
 
 
33
#include <private/qinternal_p.h>
 
34
#include <private/q3richtext_p.h>
 
35
#include "qevent.h"
 
36
#include "q3rangecontrol.h"
 
37
#include "qapplication.h"
 
38
#include "qpixmap.h"
 
39
#include "qlist.h"
 
40
#include "qstring.h"
 
41
#include "qstyle.h"
 
42
 
 
43
#if defined(Q_WS_WIN)
 
44
#include "qt_windows.h"
 
45
#endif
 
46
 
 
47
#define QDATETIMEEDIT_HIDDEN_CHAR '0'
 
48
 
 
49
class Q_COMPAT_EXPORT QNumberSection
 
50
{
 
51
public:
 
52
    QNumberSection(int selStart = 0, int selEnd = 0, bool separat = true, int actual = -1)
 
53
        : selstart(selStart), selend(selEnd), act(actual), sep(separat)
 
54
    {}
 
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)
 
63
private:
 
64
    signed int selstart :12;
 
65
    signed int selend         :12;
 
66
    signed int act         :7;
 
67
    bool sep         :1;
 
68
};
 
69
 
 
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;
 
77
 
 
78
static void cleanup()
 
79
{
 
80
    delete lDateSep;
 
81
    lDateSep = 0;
 
82
    delete lTimeSep;
 
83
    lTimeSep = 0;
 
84
    delete lAM;
 
85
    lAM = 0;
 
86
    delete lPM;
 
87
    lPM = 0;
 
88
}
 
89
 
 
90
/*!
 
91
\internal
 
92
try to get the order of DMY and the date/time separator from the locale settings
 
93
*/
 
94
static void readLocaleSettings()
 
95
{
 
96
    int dpos, mpos, ypos;
 
97
    cleanup();
 
98
 
 
99
    lDateSep = new QString();
 
100
    lTimeSep = new QString();
 
101
 
 
102
#if defined(Q_WS_WIN)
 
103
    QT_WA({
 
104
        TCHAR data[10];
 
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);
 
113
        if (!am.isEmpty())
 
114
            lAM = new QString(am);
 
115
        GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10);
 
116
        QString pm = QString::fromUtf16((ushort*)data);
 
117
        if (!pm.isEmpty() )
 
118
            lPM = new QString(pm);
 
119
    } , {
 
120
        char data[10];
 
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);
 
129
        if (!am.isEmpty())
 
130
            lAM = new QString(am);
 
131
        GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10);
 
132
        QString pm = QString::fromLocal8Bit(data);
 
133
        if (!pm.isEmpty())
 
134
            lPM = new QString(pm);
 
135
    });
 
136
#else
 
137
    *lDateSep = "-";
 
138
    *lTimeSep = ":";
 
139
#endif
 
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;
 
154
        } else {
 
155
            // cannot determine the dateformat - use the default
 
156
            return;
 
157
        }
 
158
 
 
159
        // this code needs to change if new formats are added
 
160
 
 
161
#ifndef Q_WS_WIN
 
162
        QString sep = d.mid(qMin(dpos, mpos) + 2, QABS(dpos - mpos) - 2);
 
163
        if (d.count(sep) == 2) {
 
164
            *lDateSep = sep;
 
165
        }
 
166
#endif
 
167
    }
 
168
 
 
169
#ifndef Q_WS_WIN
 
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)) {
 
178
            *lTimeSep = sep;
 
179
        }
 
180
    }
 
181
#endif
 
182
}
 
183
 
 
184
static Q3DateEdit::Order localOrder() {
 
185
    if (!lDateSep) {
 
186
        readLocaleSettings();
 
187
    }
 
188
    return lOrder;
 
189
}
 
190
 
 
191
static QString localDateSep() {
 
192
    if (!lDateSep) {
 
193
        readLocaleSettings();
 
194
    }
 
195
    return *lDateSep;
 
196
}
 
197
 
 
198
static QString localTimeSep() {
 
199
    if (!lTimeSep) {
 
200
        readLocaleSettings();
 
201
    }
 
202
    return *lTimeSep;
 
203
}
 
204
 
 
205
class Q3DateTimeEditorPrivate
 
206
{
 
207
public:
 
208
    Q3DateTimeEditorPrivate()
 
209
        : frm(true),
 
210
          parag(new Q3TextParagraph(0, 0, 0, false)),
 
211
          focusSec(0)
 
212
    {
 
213
        parag->formatter()->setWrapEnabled(false);
 
214
        cursor = new Q3TextCursor(0);
 
215
        cursor->setParagraph(parag);
 
216
        offset = 0;
 
217
        sep = localDateSep();
 
218
        refcount++;
 
219
    }
 
220
    ~Q3DateTimeEditorPrivate()
 
221
    {
 
222
        delete parag;
 
223
        delete cursor;
 
224
        if (!--refcount)
 
225
            cleanup();
 
226
    }
 
227
 
 
228
    void appendSection(const QNumberSection& sec)
 
229
    {
 
230
        sections.append(sec);
 
231
 
 
232
    }
 
233
    void clearSections()
 
234
    {
 
235
        sections.clear();
 
236
    }
 
237
    void setSectionSelection(int sec, int selstart, int selend)
 
238
    {
 
239
        if (sec < 0 || sec > (int)sections.count())
 
240
            return;
 
241
        sections[sec].setSelectionStart(selstart);
 
242
        sections[sec].setSelectionEnd(selend);
 
243
    }
 
244
    uint sectionCount() const { return (uint)sections.count(); }
 
245
    void setSeparator(const QString& s) { sep = s; }
 
246
    QString separator() const { return sep; }
 
247
 
 
248
    void setFrame(bool f) { frm = f; }
 
249
    bool frame() const { return frm; }
 
250
 
 
251
    int focusSection() const { return focusSec; }
 
252
    int section(const QPoint& p)
 
253
    {
 
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())
 
259
                return i;
 
260
        }
 
261
        return -1;
 
262
    }
 
263
    QNumberSection section(int idx) const
 
264
    {
 
265
        return sections[idx];
 
266
    }
 
267
    bool setFocusSection(int idx)
 
268
    {
 
269
        if (idx > (int)sections.count()-1 || idx < 0)
 
270
            return false;
 
271
        if (idx != focusSec) {
 
272
            focusSec = idx;
 
273
            applyFocusSelection();
 
274
            return true;
 
275
        }
 
276
        return false;
 
277
    }
 
278
 
 
279
    bool inSectionSelection(int idx)
 
280
    {
 
281
        for (int i = 0; i < sections.count(); ++i) {
 
282
            if (idx >= sections[i].selectionStart() &&
 
283
                 idx <= sections[i].selectionEnd())
 
284
                return true;
 
285
        }
 
286
        return false;
 
287
    }
 
288
 
 
289
    void paint(const QString& txt, bool focus, QPainter& p,
 
290
                const QPalette&pal, const QRect& rect, QStyle *style)
 
291
    {
 
292
        int fw = 0;
 
293
        if (frm)
 
294
            fw = style->pixelMetric(QStyle::PM_DefaultFrameWidth);
 
295
 
 
296
        parag->truncate(0);
 
297
        parag->append(txt);
 
298
        if (!focus)
 
299
            parag->removeSelection(Q3TextDocument::Standard);
 
300
        else {
 
301
            applyFocusSelection();
 
302
        }
 
303
 
 
304
        /* color all QDATETIMEEDIT_HIDDEN_CHAR chars to background color */
 
305
        Q3TextFormat *fb = parag->formatCollection()->format(p.font(),
 
306
                                                             pal.base().color());
 
307
        Q3TextFormat *nf = parag->formatCollection()->format(p.font(),
 
308
                                                             pal.text().color());
 
309
        for (int i = 0; i < txt.length(); ++i) {
 
310
            parag->setFormat(i, 1, nf);
 
311
            if (inSectionSelection(i))
 
312
                continue;
 
313
            if (txt.at(i) == QDATETIMEEDIT_HIDDEN_CHAR)
 
314
                parag->setFormat(i, 1, fb);
 
315
            else
 
316
                parag->setFormat(i, 1, nf);
 
317
        }
 
318
        fb->removeRef();
 
319
        nf->removeRef();
 
320
 
 
321
        QRect r(rect.x(), rect.y(), rect.width() - 2 * (2 + fw), rect.height());
 
322
        parag->pseudoDocument()->docRect = r;
 
323
        parag->invalidate(0);
 
324
        parag->format();
 
325
 
 
326
        int xoff = 2 + fw - offset;
 
327
        int yoff = (rect.height() - parag->rect().height() + 1) / 2;
 
328
        if (yoff < 0)
 
329
            yoff = 0;
 
330
 
 
331
        p.translate(xoff, yoff);
 
332
        parag->paint(p, pal, 0, true);
 
333
        if (frm)
 
334
            p.translate(-xoff, -yoff);
 
335
    }
 
336
 
 
337
    void resize(const QSize& size) { sz = size; }
 
338
 
 
339
    int mapSection(int sec)
 
340
    {
 
341
        return sections[sec].index();
 
342
    }
 
343
 
 
344
protected:
 
345
    void applyFocusSelection()
 
346
    {
 
347
        if (focusSec > -1) {
 
348
            int selstart = sections[focusSec].selectionStart();
 
349
            int selend = sections[focusSec].selectionEnd();
 
350
            parag->setSelection(Q3TextDocument::Standard, selstart, selend);
 
351
            parag->format();
 
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;
 
355
            }
 
356
        }
 
357
    }
 
358
private:
 
359
    bool frm;
 
360
    Q3TextParagraph *parag;
 
361
    Q3TextCursor *cursor;
 
362
    QSize sz;
 
363
    int focusSec;
 
364
    QList< QNumberSection > sections;
 
365
    QString sep;
 
366
    int offset;
 
367
};
 
368
 
 
369
class Q3DateTimeEditor : public QWidget
 
370
{
 
371
    Q_OBJECT
 
372
public:
 
373
    Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char* name=0);
 
374
    ~Q3DateTimeEditor();
 
375
 
 
376
    void setControlWidget(Q3DateTimeEditBase * widget);
 
377
    Q3DateTimeEditBase * controlWidget() const;
 
378
 
 
379
    void setSeparator(const QString& s);
 
380
    QString separator() const;
 
381
 
 
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);
 
390
 
 
391
protected:
 
392
    void init();
 
393
    bool event(QEvent *e);
 
394
    void resizeEvent(QResizeEvent *);
 
395
    void paintEvent(QPaintEvent *);
 
396
    void mousePressEvent(QMouseEvent *e);
 
397
 
 
398
private:
 
399
    Q3DateTimeEditBase* cw;
 
400
    Q3DateTimeEditorPrivate* d;
 
401
};
 
402
 
 
403
class QDateTimeSpinWidget : public Q3SpinWidget
 
404
{
 
405
    Q_OBJECT
 
406
public:
 
407
    QDateTimeSpinWidget(QWidget *parent, const char *name)
 
408
        : Q3SpinWidget(parent, name)
 
409
    {
 
410
    }
 
411
 
 
412
    void changeEvent(QEvent *e)
 
413
    {
 
414
        if (e->type() == QEvent::EnabledChange && isEnabled()) {
 
415
            Q3DateEdit *de = ::qobject_cast<Q3DateEdit*>(parentWidget());
 
416
            if (de) {
 
417
                setUpEnabled(de->date() < de->maxValue());
 
418
                setDownEnabled(de->date() > de->minValue());
 
419
            } else {
 
420
                setUpEnabled(true);
 
421
                setDownEnabled(true);
 
422
            }
 
423
        }
 
424
    }
 
425
    void enabledChange(bool notenabled)
 
426
    {
 
427
        Q3DateEdit *de = qobject_cast<Q3DateEdit*>(parentWidget());
 
428
        if (de && !notenabled) {
 
429
            setUpEnabled(de->date() < de->maxValue());
 
430
            setDownEnabled(de->date() > de->minValue());
 
431
        } else {
 
432
            setUpEnabled(!notenabled);
 
433
            setDownEnabled(!notenabled);
 
434
        }
 
435
    }
 
436
 
 
437
 
 
438
protected:
 
439
#ifndef QT_NO_WHEELEVENT
 
440
    void wheelEvent(QWheelEvent *e)
 
441
    {
 
442
        Q3DateTimeEditor *editor = qobject_cast<Q3DateTimeEditor*>(editWidget());
 
443
        Q_ASSERT(editor);
 
444
        if (!editor)
 
445
            return;
 
446
 
 
447
        int section = editor->sectionAt(e->pos());
 
448
        editor->setFocusSection(section);
 
449
 
 
450
        if (section == -1)
 
451
            return;
 
452
        Q3SpinWidget::wheelEvent(e);
 
453
    }
 
454
#endif
 
455
};
 
456
 
 
457
/*!
 
458
    Constructs an empty datetime editor with parent \a parent and
 
459
    called \a name.
 
460
*/
 
461
Q3DateTimeEditor::Q3DateTimeEditor(Q3DateTimeEditBase *widget, QWidget *parent, const char * name)
 
462
    : QWidget(parent, name)
 
463
{
 
464
    d = new Q3DateTimeEditorPrivate();
 
465
    cw = widget;
 
466
    init();
 
467
}
 
468
 
 
469
/*!
 
470
    Destroys the object and frees any allocated resources.
 
471
*/
 
472
 
 
473
Q3DateTimeEditor::~Q3DateTimeEditor()
 
474
{
 
475
    delete d;
 
476
}
 
477
 
 
478
/*! \internal
 
479
 
 
480
*/
 
481
 
 
482
void Q3DateTimeEditor::init()
 
483
{
 
484
    setBackgroundRole(QPalette::Base);
 
485
    setFocusSection(-1);
 
486
    installEventFilter(this);
 
487
    setFocusPolicy(Qt::WheelFocus);
 
488
}
 
489
 
 
490
 
 
491
/*! \reimp
 
492
 
 
493
*/
 
494
 
 
495
bool Q3DateTimeEditor::event(QEvent *e)
 
496
{
 
497
    if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
 
498
        if (e->type() == QEvent::FocusOut)
 
499
            qApp->sendEvent(cw, e);
 
500
        update(rect());
 
501
    } else if (e->type() == QEvent::ShortcutOverride) {
 
502
        QKeyEvent* ke = (QKeyEvent*) e;
 
503
        switch (ke->key()) {
 
504
        case Qt::Key_Delete:
 
505
        case Qt::Key_Backspace:
 
506
        case Qt::Key_Up:
 
507
        case Qt::Key_Down:
 
508
        case Qt::Key_Left:
 
509
        case Qt::Key_Right:
 
510
            ke->accept();
 
511
        default:
 
512
            break;
 
513
        }
 
514
    }
 
515
    return QWidget::event(e);
 
516
}
 
517
 
 
518
/*! \reimp
 
519
 
 
520
*/
 
521
 
 
522
void Q3DateTimeEditor::resizeEvent(QResizeEvent *e)
 
523
{
 
524
    d->resize(e->size());
 
525
    QWidget::resizeEvent(e);
 
526
}
 
527
 
 
528
 
 
529
/*! \reimp
 
530
 
 
531
*/
 
532
 
 
533
void Q3DateTimeEditor::paintEvent(QPaintEvent *)
 
534
{
 
535
    QString txt;
 
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();
 
541
            else
 
542
                txt += " ";
 
543
        }
 
544
    }
 
545
 
 
546
    QPainter p(this);
 
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());
 
550
}
 
551
 
 
552
 
 
553
/*!
 
554
    Returns the section index at point \a p.
 
555
*/
 
556
int Q3DateTimeEditor::sectionAt(const QPoint &p)
 
557
{
 
558
    return d->section(p);
 
559
}
 
560
 
 
561
int Q3DateTimeEditor::mapSection(int sec)
 
562
{
 
563
    return d->mapSection(sec);
 
564
}
 
565
 
 
566
 
 
567
/*! \reimp
 
568
 
 
569
*/
 
570
 
 
571
void Q3DateTimeEditor::mousePressEvent(QMouseEvent *e)
 
572
{
 
573
    QPoint p(e->pos().x(), 0);
 
574
    int sec = sectionAt(p);
 
575
    if (sec != -1) {
 
576
        cw->setFocusSection(sec);
 
577
        repaint(rect());
 
578
    }
 
579
}
 
580
 
 
581
/*! \reimp
 
582
 
 
583
*/
 
584
bool Q3DateTimeEditor::eventFilter(QObject *o, QEvent *e)
 
585
{
 
586
    if (o == this) {
 
587
        if (e->type() == QEvent::KeyPress) {
 
588
            QKeyEvent *ke = (QKeyEvent*)e;
 
589
            switch (ke->key()) {
 
590
            case Qt::Key_Right:
 
591
                if (d->focusSection() < (int)d->sectionCount()-1) {
 
592
                    if (cw->setFocusSection(focusSection()+1))
 
593
                        repaint(rect());
 
594
                }
 
595
                return true;
 
596
            case Qt::Key_Left:
 
597
                if (d->focusSection() > 0) {
 
598
                    if (cw->setFocusSection(focusSection()-1))
 
599
                        repaint(rect());
 
600
                }
 
601
                return true;
 
602
            case Qt::Key_Up:
 
603
                cw->stepUp();
 
604
                return true;
 
605
            case Qt::Key_Down:
 
606
                cw->stepDown();
 
607
                return true;
 
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());
 
613
                return true;
 
614
            case Qt::Key_Delete:
 
615
                cw->removeLastNumber(d->focusSection());
 
616
                return true;
 
617
            case Qt::Key_Tab:
 
618
            case Qt::Key_BackTab: {
 
619
                if (ke->state() == Qt::ControlButton)
 
620
                    return false;
 
621
                QWidget *w = this;
 
622
                bool hadDateEdit = false;
 
623
                while (w) {
 
624
                    if (qobject_cast<QDateTimeSpinWidget*>(w) || qobject_cast<Q3DateTimeEdit*>(w))
 
625
                        break;
 
626
                    hadDateEdit = hadDateEdit || qobject_cast<Q3DateEdit*>(w);
 
627
                    w = w->parentWidget();
 
628
                }
 
629
                if (w) {
 
630
                    if (!qobject_cast<Q3DateTimeEdit*>(w)) {
 
631
                        w = w->parentWidget();
 
632
                    } else {
 
633
                        Q3DateTimeEdit *ed = (Q3DateTimeEdit*)w;
 
634
                        if (hadDateEdit && ke->key() == Qt::Key_Tab) {
 
635
                            ed->timeEdit()->setFocus();
 
636
                            return true;
 
637
                        } else if (!hadDateEdit && ke->key() == Qt::Key_BackTab) {
 
638
                            ed->dateEdit()->setFocus();
 
639
                            return true;
 
640
                        } else {
 
641
                            while (w && !qobject_cast<Q3DateTimeEdit*>(w))
 
642
                                w = w->parentWidget();
 
643
                        }
 
644
                    }
 
645
                    qApp->sendEvent(w, e);
 
646
                    return true;
 
647
                }
 
648
            } break;
 
649
            default:
 
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))
 
655
                            repaint(rect());
 
656
                    }
 
657
                    return true;
 
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());
 
665
                            te->setTime(time);
 
666
                        } else if (txt[0] == (*lPM).toLower()[0] && time.hour() < 12) {
 
667
                            time.setHMS(time.hour()+12, time.minute(), time.second(), time.msec());
 
668
                            te->setTime(time);
 
669
                        }
 
670
                    }
 
671
                }
 
672
 
 
673
                int num = txt[0].digitValue();
 
674
                if (num != -1) {
 
675
                    cw->addNumber(d->focusSection(), num);
 
676
                    return true;
 
677
                }
 
678
            }
 
679
        }
 
680
    }
 
681
    return false;
 
682
}
 
683
 
 
684
 
 
685
/*!
 
686
    Appends the number section \a sec to the editor.
 
687
*/
 
688
 
 
689
void Q3DateTimeEditor::appendSection(const QNumberSection& sec)
 
690
{
 
691
    d->appendSection(sec);
 
692
}
 
693
 
 
694
/*!
 
695
    Removes all sections from the editor.
 
696
*/
 
697
 
 
698
void Q3DateTimeEditor::clearSections()
 
699
{
 
700
    d->clearSections();
 
701
}
 
702
 
 
703
/*!
 
704
    Sets the selection of \a sec to start at \a selstart and end at \a
 
705
    selend.
 
706
*/
 
707
 
 
708
void Q3DateTimeEditor::setSectionSelection(int sec, int selstart, int selend)
 
709
{
 
710
    d->setSectionSelection(sec, selstart, selend);
 
711
}
 
712
 
 
713
/*!
 
714
    Sets the separator for all numbered sections to \a s. Note that
 
715
    currently, only the first character of \a s is used.
 
716
*/
 
717
 
 
718
void Q3DateTimeEditor::setSeparator(const QString& s)
 
719
{
 
720
    d->setSeparator(s);
 
721
    update();
 
722
}
 
723
 
 
724
 
 
725
/*!
 
726
    Returns the editor's separator.
 
727
*/
 
728
 
 
729
QString Q3DateTimeEditor::separator() const
 
730
{
 
731
    return d->separator();
 
732
}
 
733
 
 
734
/*!
 
735
    Returns the number of the section that has focus.
 
736
*/
 
737
 
 
738
int Q3DateTimeEditor::focusSection() const
 
739
{
 
740
    return d->focusSection();
 
741
}
 
742
 
 
743
 
 
744
/*!
 
745
    Sets the focus to section \a sec. If \a sec does not exist,
 
746
    nothing happens.
 
747
*/
 
748
 
 
749
bool Q3DateTimeEditor::setFocusSection(int sec)
 
750
{
 
751
    return d->setFocusSection(sec);
 
752
}
 
753
 
 
754
/*!
 
755
    \class Q3DateTimeEditBase
 
756
    \brief The Q3DateTimeEditBase class provides an abstraction for date and edit editors.
 
757
 
 
758
    \compat
 
759
 
 
760
    Small abstract class that provides some functions that are common
 
761
    for both Q3DateEdit and Q3TimeEdit. It is used internally by
 
762
    Q3DateTimeEditor.
 
763
*/
 
764
 
 
765
/*!
 
766
    \fn Q3DateTimeEditBase::Q3DateTimeEditBase(QWidget *, const char*)
 
767
    \internal
 
768
*/
 
769
 
 
770
/*!
 
771
    \fn Q3DateTimeEditBase::setFocusSection(int)
 
772
    \internal
 
773
*/
 
774
 
 
775
/*! \fn QString Q3DateTimeEditBase::sectionFormattedText(int sec)
 
776
    \internal
 
777
 
 
778
  Pure virtual function which returns the formatted text of section \a
 
779
  sec.
 
780
 
 
781
*/
 
782
 
 
783
/*! \fn void Q3DateTimeEditBase::stepUp()
 
784
    \internal
 
785
 
 
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.
 
789
*/
 
790
 
 
791
/*! \fn void Q3DateTimeEditBase::stepDown()
 
792
    \internal
 
793
 
 
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.
 
797
 
 
798
*/
 
799
 
 
800
/*! \fn void Q3DateTimeEditBase::addNumber(int sec, int num)
 
801
    \internal
 
802
 
 
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.
 
806
*/
 
807
 
 
808
/*! \fn void Q3DateTimeEditBase::removeLastNumber(int sec)
 
809
    \internal
 
810
 
 
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.
 
813
*/
 
814
 
 
815
////////////////
 
816
 
 
817
class Q3DateEditPrivate
 
818
{
 
819
public:
 
820
    int y;
 
821
    int m;
 
822
    int d;
 
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
 
827
    int dayCache;
 
828
    int yearSection;
 
829
    int monthSection;
 
830
    int daySection;
 
831
    Q3DateEdit::Order ord;
 
832
    bool overwrite;
 
833
    bool adv;
 
834
    int timerId;
 
835
    bool typing;
 
836
    QDate min;
 
837
    QDate max;
 
838
    bool changed;
 
839
    Q3DateTimeEditor *ed;
 
840
    Q3SpinWidget *controls;
 
841
};
 
842
 
 
843
 
 
844
/*!
 
845
    \class Q3DateEdit q3datetimeedit.h
 
846
    \brief The Q3DateEdit class provides a date editor.
 
847
 
 
848
    \compat
 
849
 
 
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
 
856
    with a date, e.g.
 
857
 
 
858
    \code
 
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);
 
864
    \endcode
 
865
 
 
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.
 
872
 
 
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().
 
876
 
 
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 "-".
 
882
 
 
883
    \img datetimewidgets.png Date Time Widgets
 
884
 
 
885
    \sa QDate Q3TimeEdit Q3DateTimeEdit
 
886
*/
 
887
 
 
888
/*!
 
889
    \enum Q3DateEdit::Order
 
890
 
 
891
    This enum defines the order in which the sections that comprise a
 
892
    date appear.
 
893
 
 
894
    \value MDY month-day-year
 
895
    \value DMY day-month-year
 
896
    \value YMD year-month-day (the default)
 
897
    \omitvalue YDM
 
898
*/
 
899
 
 
900
/*!
 
901
    \enum Q3TimeEdit::Display
 
902
 
 
903
    This enum defines the sections that comprise a time
 
904
 
 
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
 
909
 
 
910
    The values can be or'ed together to show any combination.
 
911
*/
 
912
 
 
913
/*!
 
914
    Constructs an empty date editor which is a child of \a parent and
 
915
    called name \a name.
 
916
*/
 
917
 
 
918
Q3DateEdit::Q3DateEdit(QWidget * parent, const char * name)
 
919
    : Q3DateTimeEditBase(parent, name)
 
920
{
 
921
    init();
 
922
    updateButtons();
 
923
}
 
924
 
 
925
/*!
 
926
    \overload
 
927
 
 
928
    Constructs a date editor with the initial value \a date, parent \a
 
929
    parent and called \a name.
 
930
 
 
931
    The date editor is initialized with \a date.
 
932
*/
 
933
 
 
934
Q3DateEdit::Q3DateEdit(const QDate& date, QWidget * parent, const char * name)
 
935
    : Q3DateTimeEditBase(parent, name)
 
936
{
 
937
    init();
 
938
    setDate(date);
 
939
}
 
940
 
 
941
/*! \internal
 
942
*/
 
943
void Q3DateEdit::init()
 
944
{
 
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));
 
956
 
 
957
    d->yearSection = -1;
 
958
    d->monthSection = -1;
 
959
    d->daySection = -1;
 
960
 
 
961
    d->y = 0;
 
962
    d->m = 0;
 
963
    d->d = 0;
 
964
    d->dayCache = 0;
 
965
    setOrder(localOrder());
 
966
    setFocusSection(0);
 
967
    d->overwrite = true;
 
968
    d->adv = false;
 
969
    d->timerId = 0;
 
970
    d->typing = false;
 
971
    d->min = QDate(1752, 9, 14);
 
972
    d->max = QDate(8000, 12, 31);
 
973
    d->changed = false;
 
974
 
 
975
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
 
976
 
 
977
    refcount++;
 
978
}
 
979
 
 
980
/*!
 
981
    Destroys the object and frees any allocated resources.
 
982
*/
 
983
 
 
984
Q3DateEdit::~Q3DateEdit()
 
985
{
 
986
    delete d;
 
987
    if (!--refcount)
 
988
        cleanup();
 
989
}
 
990
 
 
991
/*!
 
992
    \property Q3DateEdit::minValue
 
993
 
 
994
    \brief the editor's minimum value
 
995
 
 
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.
 
999
 
 
1000
    \sa maxValue setRange()
 
1001
*/
 
1002
 
 
1003
QDate Q3DateEdit::minValue() const
 
1004
{
 
1005
    return d->min;
 
1006
}
 
1007
 
 
1008
/*!
 
1009
    \property Q3DateEdit::maxValue
 
1010
 
 
1011
    \brief the editor's maximum value
 
1012
 
 
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.
 
1016
 
 
1017
    \sa minValue setRange()
 
1018
*/
 
1019
 
 
1020
QDate Q3DateEdit::maxValue() const
 
1021
{
 
1022
    return d->max;
 
1023
}
 
1024
 
 
1025
 
 
1026
/*!
 
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.
 
1030
*/
 
1031
 
 
1032
void Q3DateEdit::setRange(const QDate& min, const QDate& max)
 
1033
{
 
1034
    if (min.isValid())
 
1035
        d->min = min;
 
1036
    if (max.isValid())
 
1037
        d->max = max;
 
1038
}
 
1039
 
 
1040
/*!
 
1041
    Sets the separator to \a s. Note that currently only the first
 
1042
    character of \a s is used.
 
1043
*/
 
1044
 
 
1045
void Q3DateEdit::setSeparator(const QString& s)
 
1046
{
 
1047
    d->ed->setSeparator(s);
 
1048
}
 
1049
 
 
1050
/*!
 
1051
    Returns the editor's separator.
 
1052
*/
 
1053
 
 
1054
QString Q3DateEdit::separator() const
 
1055
{
 
1056
    return d->ed->separator();
 
1057
}
 
1058
 
 
1059
 
 
1060
/*!
 
1061
    Enables/disables the push buttons according to the min/max date
 
1062
    for this widget.
 
1063
*/
 
1064
 
 
1065
void Q3DateEdit::updateButtons()
 
1066
{
 
1067
    if (!isEnabled())
 
1068
        return;
 
1069
 
 
1070
    bool upEnabled = date() < maxValue();
 
1071
    bool downEnabled = date() > minValue();
 
1072
 
 
1073
    d->controls->setUpEnabled(upEnabled);
 
1074
    d->controls->setDownEnabled(downEnabled);
 
1075
}
 
1076
 
 
1077
/*! \reimp
 
1078
 */
 
1079
void Q3DateEdit::resizeEvent(QResizeEvent *)
 
1080
{
 
1081
    d->controls->resize(width(), height());
 
1082
}
 
1083
 
 
1084
/*! \reimp
 
1085
 
 
1086
*/
 
1087
QSize Q3DateEdit::sizeHint() const
 
1088
{
 
1089
    ensurePolished();
 
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;
 
1094
 
 
1095
    return QSize(w, qMax(h + fw * 2,20)).expandedTo(QApplication::globalStrut());
 
1096
}
 
1097
 
 
1098
/*! \reimp
 
1099
 
 
1100
*/
 
1101
QSize Q3DateEdit::minimumSizeHint() const
 
1102
{
 
1103
    return sizeHint();
 
1104
}
 
1105
 
 
1106
 
 
1107
/*!
 
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.
 
1111
 
 
1112
    \sa setOrder()
 
1113
*/
 
1114
 
 
1115
QString Q3DateEdit::sectionFormattedText(int sec)
 
1116
{
 
1117
    QString txt;
 
1118
    txt = sectionText(sec);
 
1119
    if (d->typing && sec == d->ed->focusSection())
 
1120
        d->ed->setSectionSelection(sec, sectionOffsetEnd(sec) - txt.length(),
 
1121
                             sectionOffsetEnd(sec));
 
1122
    else
 
1123
        d->ed->setSectionSelection(sec, sectionOffsetEnd(sec) - sectionLength(sec),
 
1124
                             sectionOffsetEnd(sec));
 
1125
    txt = txt.rightJustified(sectionLength(sec), QDATETIMEEDIT_HIDDEN_CHAR);
 
1126
    return txt;
 
1127
}
 
1128
 
 
1129
 
 
1130
/*!
 
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.
 
1134
 
 
1135
    \sa setOrder()
 
1136
*/
 
1137
 
 
1138
int Q3DateEdit::sectionLength(int sec) const
 
1139
{
 
1140
    int val = 0;
 
1141
    if (sec == d->yearSection) {
 
1142
        val = 4;
 
1143
    } else if (sec == d->monthSection) {
 
1144
        val = 2;
 
1145
    } else if (sec == d->daySection) {
 
1146
        val = 2;
 
1147
    }
 
1148
    return val;
 
1149
}
 
1150
 
 
1151
/*!
 
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
 
1154
    order.
 
1155
 
 
1156
    \sa setOrder()
 
1157
*/
 
1158
 
 
1159
QString Q3DateEdit::sectionText(int sec) const
 
1160
{
 
1161
    int val = 0;
 
1162
    if (sec == d->yearSection) {
 
1163
        val = d->y;
 
1164
    } else if (sec == d->monthSection) {
 
1165
        val = d->m;
 
1166
    } else if (sec == d->daySection) {
 
1167
        val = d->d;
 
1168
    }
 
1169
    return QString::number(val);
 
1170
}
 
1171
 
 
1172
/*! \internal
 
1173
 
 
1174
  Returns the end of the section offset \a sec.
 
1175
 
 
1176
*/
 
1177
 
 
1178
int Q3DateEdit::sectionOffsetEnd(int sec) const
 
1179
{
 
1180
    if (sec == d->yearSection) {
 
1181
        switch(d->ord) {
 
1182
        case DMY:
 
1183
        case MDY:
 
1184
            return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
 
1185
        case YMD:
 
1186
        case YDM:
 
1187
            return sectionLength(sec);
 
1188
        }
 
1189
    } else if (sec == d->monthSection) {
 
1190
        switch(d->ord) {
 
1191
        case DMY:
 
1192
        case YDM:
 
1193
        case YMD:
 
1194
            return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
 
1195
        case MDY:
 
1196
            return sectionLength(sec);
 
1197
        }
 
1198
    } else if (sec == d->daySection) {
 
1199
        switch(d->ord) {
 
1200
        case DMY:
 
1201
            return sectionLength(sec);
 
1202
        case YMD:
 
1203
        case MDY:
 
1204
        case YDM:
 
1205
            return sectionOffsetEnd(sec-1) + separator().length() + sectionLength(sec);
 
1206
        }
 
1207
    }
 
1208
    return 0;
 
1209
}
 
1210
 
 
1211
 
 
1212
/*!
 
1213
    \property Q3DateEdit::order
 
1214
    \brief the order in which the year, month and day appear
 
1215
 
 
1216
    The default order is locale dependent.
 
1217
 
 
1218
    \sa Order
 
1219
*/
 
1220
 
 
1221
void Q3DateEdit::setOrder(Q3DateEdit::Order order)
 
1222
{
 
1223
    d->ord = order;
 
1224
    switch(d->ord) {
 
1225
    case DMY:
 
1226
        d->yearSection = 2;
 
1227
        d->monthSection = 1;
 
1228
        d->daySection = 0;
 
1229
        break;
 
1230
    case MDY:
 
1231
        d->yearSection = 2;
 
1232
        d->monthSection = 0;
 
1233
        d->daySection = 1;
 
1234
        break;
 
1235
    case YMD:
 
1236
        d->yearSection = 0;
 
1237
        d->monthSection = 1;
 
1238
        d->daySection = 2;
 
1239
        break;
 
1240
    case YDM:
 
1241
        d->yearSection = 0;
 
1242
        d->monthSection = 2;
 
1243
        d->daySection = 1;
 
1244
        break;
 
1245
    }
 
1246
    if (isVisible())
 
1247
        d->ed->repaint(d->ed->rect());
 
1248
}
 
1249
 
 
1250
 
 
1251
Q3DateEdit::Order Q3DateEdit::order() const
 
1252
{
 
1253
    return d->ord;
 
1254
}
 
1255
 
 
1256
 
 
1257
/*! \reimp
 
1258
 
 
1259
*/
 
1260
void Q3DateEdit::stepUp()
 
1261
{
 
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)) {
 
1266
            accepted = true;
 
1267
            setYear(d->y+1);
 
1268
        }
 
1269
    } else if (sec == d->monthSection) {
 
1270
        if (!outOfRange(d->y, d->m+1, d->d)) {
 
1271
            accepted = true;
 
1272
            setMonth(d->m+1);
 
1273
        }
 
1274
    } else if (sec == d->daySection) {
 
1275
        if (!outOfRange(d->y, d->m, d->d+1)) {
 
1276
            accepted = true;
 
1277
            setDay(d->d+1);
 
1278
        }
 
1279
    }
 
1280
    if (accepted) {
 
1281
        d->changed = true;
 
1282
        emit valueChanged(date());
 
1283
    }
 
1284
    d->ed->repaint(d->ed->rect());
 
1285
}
 
1286
 
 
1287
 
 
1288
 
 
1289
/*! \reimp
 
1290
 
 
1291
*/
 
1292
 
 
1293
void Q3DateEdit::stepDown()
 
1294
{
 
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)) {
 
1299
            accepted = true;
 
1300
            setYear(d->y-1);
 
1301
        }
 
1302
    } else if (sec == d->monthSection) {
 
1303
        if (!outOfRange(d->y, d->m-1, d->d)) {
 
1304
            accepted = true;
 
1305
            setMonth(d->m-1);
 
1306
        }
 
1307
    } else if (sec == d->daySection) {
 
1308
        if (!outOfRange(d->y, d->m, d->d-1)) {
 
1309
            accepted = true;
 
1310
            setDay(d->d-1);
 
1311
        }
 
1312
    }
 
1313
    if (accepted) {
 
1314
        d->changed = true;
 
1315
        emit valueChanged(date());
 
1316
    }
 
1317
    d->ed->repaint(d->ed->rect());
 
1318
}
 
1319
 
 
1320
/*!
 
1321
    Sets the year to \a year, which must be a valid year. The range
 
1322
    currently supported is from 1752 to 8000.
 
1323
 
 
1324
    \sa QDate
 
1325
*/
 
1326
 
 
1327
void Q3DateEdit::setYear(int year)
 
1328
{
 
1329
    if (year < 1752)
 
1330
        year = 1752;
 
1331
    if (year > 8000)
 
1332
        year = 8000;
 
1333
    if (!outOfRange(year, d->m, d->d)) {
 
1334
        d->y = year;
 
1335
        setMonth(d->m);
 
1336
        int tmp = d->dayCache;
 
1337
        setDay(d->dayCache);
 
1338
        d->dayCache = tmp;
 
1339
    }
 
1340
}
 
1341
 
 
1342
 
 
1343
/*!
 
1344
    Sets the month to \a month, which must be a valid month, i.e.
 
1345
    between 1 and 12.
 
1346
*/
 
1347
 
 
1348
void Q3DateEdit::setMonth(int month)
 
1349
{
 
1350
    if (month < 1)
 
1351
        month = 1;
 
1352
    if (month > 12)
 
1353
        month = 12;
 
1354
    if (!outOfRange(d->y, month, d->d)) {
 
1355
        d->m = month;
 
1356
        int tmp = d->dayCache;
 
1357
        setDay(d->dayCache);
 
1358
        d->dayCache = tmp;
 
1359
    }
 
1360
}
 
1361
 
 
1362
 
 
1363
/*!
 
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.
 
1366
*/
 
1367
 
 
1368
void Q3DateEdit::setDay(int day)
 
1369
{
 
1370
    if (day < 1)
 
1371
        day = 1;
 
1372
    if (day > 31)
 
1373
        day = 31;
 
1374
    if (d->m > 0 && d->y > 1752) {
 
1375
        while (!QDate::isValid(d->y, d->m, day))
 
1376
            --day;
 
1377
        if (!outOfRange(d->y, d->m, day))
 
1378
            d->d = day;
 
1379
    } else if (d->m > 0) {
 
1380
        if (day > 0 && day < 32) {
 
1381
            if (!outOfRange(d->y, d->m, day))
 
1382
                d->d = day;
 
1383
        }
 
1384
    }
 
1385
    d->dayCache = d->d;
 
1386
}
 
1387
 
 
1388
 
 
1389
/*!
 
1390
    \property Q3DateEdit::date
 
1391
    \brief the editor's date value.
 
1392
 
 
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.
 
1398
 
 
1399
    When changing the date property, if the date is less than
 
1400
    minValue(), or is greater than maxValue(), nothing happens.
 
1401
*/
 
1402
 
 
1403
void Q3DateEdit::setDate(const QDate& date)
 
1404
{
 
1405
    if (!date.isValid()) {
 
1406
        d->y = 0;
 
1407
        d->m = 0;
 
1408
        d->d = 0;
 
1409
        d->dayCache = 0;
 
1410
    } else {
 
1411
        if (date > maxValue() || date < minValue())
 
1412
            return;
 
1413
        d->y = date.year();
 
1414
        d->m = date.month();
 
1415
        d->d = date.day();
 
1416
        d->dayCache = d->d;
 
1417
        emit valueChanged(date);
 
1418
    }
 
1419
    d->changed = false;
 
1420
    d->ed->repaint(d->ed->rect());
 
1421
}
 
1422
 
 
1423
QDate Q3DateEdit::date() const
 
1424
{
 
1425
    if (QDate::isValid(d->y, d->m, d->d))
 
1426
        return QDate(d->y, d->m, d->d);
 
1427
    return QDate();
 
1428
}
 
1429
 
 
1430
/*!  \internal
 
1431
 
 
1432
  Returns true if \a y, \a m, \a d is out of range, otherwise returns
 
1433
  false.
 
1434
 
 
1435
  \sa setRange()
 
1436
 
 
1437
*/
 
1438
 
 
1439
bool Q3DateEdit::outOfRange(int y, int m, int d) const
 
1440
{
 
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?
 
1446
            return true;
 
1447
        }
 
1448
        return false;
 
1449
    }
 
1450
    return false; /* assume ok */
 
1451
}
 
1452
 
 
1453
/*!  \reimp
 
1454
 
 
1455
*/
 
1456
 
 
1457
void Q3DateEdit::addNumber(int sec, int num)
 
1458
{
 
1459
    if (sec == -1)
 
1460
        return;
 
1461
    killTimer(d->timerId);
 
1462
    bool overwrite = false;
 
1463
    bool accepted = false;
 
1464
    d->typing = true;
 
1465
    QString txt;
 
1466
    if (sec == d->yearSection) {
 
1467
        txt = QString::number(d->y);
 
1468
        if (d->overwrite || txt.length() == 4) {
 
1469
            accepted = true;
 
1470
            d->y = num;
 
1471
        } else {
 
1472
            txt += QString::number(num);
 
1473
            if (txt.length() == 4 ) {
 
1474
                int val = txt.toInt();
 
1475
                if (val < 1792)
 
1476
                    d->y = 1792;
 
1477
                else if (val > 8000)
 
1478
                    d->y = 8000;
 
1479
                else if (outOfRange(val, d->m, d->d))
 
1480
                    txt = QString::number(d->y);
 
1481
                else {
 
1482
                    accepted = true;
 
1483
                    d->y = val;
 
1484
                }
 
1485
            } else {
 
1486
                accepted = true;
 
1487
                d->y = txt.toInt();
 
1488
            }
 
1489
            if (d->adv && txt.length() == 4) {
 
1490
                d->ed->setFocusSection(d->ed->focusSection()+1);
 
1491
                overwrite = true;
 
1492
            }
 
1493
        }
 
1494
    } else if (sec == d->monthSection) {
 
1495
        txt = QString::number(d->m);
 
1496
        if (d->overwrite || txt.length() == 2) {
 
1497
            accepted = true;
 
1498
            d->m = num;
 
1499
        } else {
 
1500
            txt += QString::number(num);
 
1501
            int temp = txt.toInt();
 
1502
            if (temp > 12)
 
1503
                temp = num;
 
1504
            if (outOfRange(d->y, temp, d->d))
 
1505
                txt = QString::number(d->m);
 
1506
            else {
 
1507
                accepted = true;
 
1508
                d->m = temp;
 
1509
            }
 
1510
            if (d->adv && txt.length() == 2) {
 
1511
                d->ed->setFocusSection(d->ed->focusSection()+1);
 
1512
                overwrite = true;
 
1513
            }
 
1514
        }
 
1515
    } else if (sec == d->daySection) {
 
1516
        txt = QString::number(d->d);
 
1517
        if (d->overwrite || txt.length() == 2) {
 
1518
            accepted = true;
 
1519
            d->d = num;
 
1520
            d->dayCache = d->d;
 
1521
        } else {
 
1522
            txt += QString::number(num);
 
1523
            int temp = txt.toInt();
 
1524
            if (temp > 31)
 
1525
                temp = num;
 
1526
            if (outOfRange(d->y, d->m, temp))
 
1527
                txt = QString::number(d->d);
 
1528
            else {
 
1529
                accepted = true;
 
1530
                d->d = temp;
 
1531
                d->dayCache = d->d;
 
1532
            }
 
1533
            if (d->adv && txt.length() == 2) {
 
1534
                d->ed->setFocusSection(d->ed->focusSection()+1);
 
1535
                overwrite = true;
 
1536
            }
 
1537
        }
 
1538
    }
 
1539
    if (accepted) {
 
1540
        d->changed = true;
 
1541
        emit valueChanged(date());
 
1542
    }
 
1543
    d->overwrite = overwrite;
 
1544
    d->timerId = startTimer(qApp->doubleClickInterval()*4);
 
1545
    d->ed->repaint(d->ed->rect());
 
1546
}
 
1547
 
 
1548
 
 
1549
/*! \reimp
 
1550
 
 
1551
*/
 
1552
 
 
1553
bool Q3DateEdit::setFocusSection(int s)
 
1554
{
 
1555
    if (s != d->ed->focusSection()) {
 
1556
        killTimer(d->timerId);
 
1557
        d->overwrite = true;
 
1558
        d->typing = false;
 
1559
        fix(); // will emit valueChanged if necessary
 
1560
    }
 
1561
    return d->ed->setFocusSection(s);
 
1562
}
 
1563
 
 
1564
 
 
1565
/*!
 
1566
    Attempts to fix any invalid date entries.
 
1567
 
 
1568
    The rules applied are as follows:
 
1569
 
 
1570
    \list
 
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.
 
1579
    \endlist
 
1580
*/
 
1581
 
 
1582
void Q3DateEdit::fix()
 
1583
{
 
1584
    bool changed = false;
 
1585
    int currentYear = QDate::currentDate().year();
 
1586
    int year = d->y;
 
1587
    if (year < 100) {
 
1588
        int currentCentury = currentYear / 100;
 
1589
        year += currentCentury * 100;
 
1590
        if (currentYear > year) {
 
1591
            if (currentYear > year + 70)
 
1592
                year += 100;
 
1593
        } else {
 
1594
            if (year >= currentYear + 30)
 
1595
                year -= 100;
 
1596
        }
 
1597
        changed = true;
 
1598
    } else if (year < 1000) {
 
1599
        int currentMillennium = currentYear / 10;
 
1600
        year += currentMillennium * 10;
 
1601
        changed = true;
 
1602
    } else if (d->d == 0) {
 
1603
        d->d = 1;
 
1604
        changed = true;
 
1605
    } else if (d->m == 0) {
 
1606
        d->m = 1;
 
1607
        changed = true;
 
1608
    }
 
1609
    if (outOfRange(year, d->m, d->d)) {
 
1610
        if (minValue().isValid() && date() < minValue()) {
 
1611
            d->d =  minValue().day();
 
1612
            d->dayCache = d->d;
 
1613
            d->m = minValue().month();
 
1614
            d->y = minValue().year();
 
1615
        }
 
1616
        if (date() > maxValue()) {
 
1617
            d->d =  maxValue().day();
 
1618
            d->dayCache = d->d;
 
1619
            d->m = maxValue().month();
 
1620
            d->y = maxValue().year();
 
1621
        }
 
1622
        changed = true;
 
1623
    } else if (changed)
 
1624
        setYear(year);
 
1625
    if (changed) {
 
1626
        emit valueChanged(date());
 
1627
        d->changed = false;
 
1628
    }
 
1629
}
 
1630
 
 
1631
 
 
1632
/*! \reimp
 
1633
 
 
1634
*/
 
1635
 
 
1636
bool Q3DateEdit::event(QEvent *e)
 
1637
{
 
1638
    if(e->type() == QEvent::FocusOut) {
 
1639
        d->typing = false;
 
1640
        fix();
 
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)) {
 
1644
            d->dayCache = d->d;
 
1645
            int i = d->d;
 
1646
            for (; i > 0; i--) {
 
1647
                d->d = i;
 
1648
                if (QDate::isValid(d->y, d->m, d->d))
 
1649
                    break;
 
1650
            }
 
1651
            d->changed = true;
 
1652
        }
 
1653
        if (d->changed) {
 
1654
            emit valueChanged(date());
 
1655
            d->changed = false;
 
1656
        }
 
1657
    } else if (e->type() == QEvent::LocaleChange) {
 
1658
        readLocaleSettings();
 
1659
        d->ed->setSeparator(localDateSep());
 
1660
        setOrder(localOrder());
 
1661
    }
 
1662
    return Q3DateTimeEditBase::event(e);
 
1663
}
 
1664
 
 
1665
/*!
 
1666
  \internal
 
1667
 
 
1668
  Function which is called whenever the user tries to
 
1669
  remove the first number from \a sec by pressing the backspace key.
 
1670
*/
 
1671
 
 
1672
void Q3DateEdit::removeFirstNumber(int sec)
 
1673
{
 
1674
    if (sec == -1)
 
1675
        return;
 
1676
    QString txt;
 
1677
    if (sec == d->yearSection) {
 
1678
        txt = QString::number(d->y);
 
1679
        txt = txt.mid(1, txt.length()) + "0";
 
1680
        d->y = txt.toInt();
 
1681
    } else if (sec == d->monthSection) {
 
1682
        txt = QString::number(d->m);
 
1683
        txt = txt.mid(1, txt.length()) + "0";
 
1684
        d->m = txt.toInt();
 
1685
    } else if (sec == d->daySection) {
 
1686
        txt = QString::number(d->d);
 
1687
        txt = txt.mid(1, txt.length()) + "0";
 
1688
        d->d = txt.toInt();
 
1689
        d->dayCache = d->d;
 
1690
    }
 
1691
    d->ed->repaint(d->ed->rect());
 
1692
}
 
1693
 
 
1694
/*! \reimp
 
1695
 
 
1696
*/
 
1697
 
 
1698
void Q3DateEdit::removeLastNumber(int sec)
 
1699
{
 
1700
    if (sec == -1)
 
1701
        return;
 
1702
    QString txt;
 
1703
    if (sec == d->yearSection) {
 
1704
        txt = QString::number(d->y);
 
1705
        txt = txt.mid(0, txt.length()-1);
 
1706
        d->y = txt.toInt();
 
1707
    } else if (sec == d->monthSection) {
 
1708
        txt = QString::number(d->m);
 
1709
        txt = txt.mid(0, txt.length()-1);
 
1710
        d->m = txt.toInt();
 
1711
    } else if (sec == d->daySection) {
 
1712
        txt = QString::number(d->d);
 
1713
        txt = txt.mid(0, txt.length()-1);
 
1714
        d->d = txt.toInt();
 
1715
        d->dayCache = d->d;
 
1716
    }
 
1717
    d->ed->repaint(d->ed->rect());
 
1718
}
 
1719
 
 
1720
/*!
 
1721
    \property Q3DateEdit::autoAdvance
 
1722
    \brief whether the editor automatically advances to the next
 
1723
    section
 
1724
 
 
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.
 
1728
*/
 
1729
 
 
1730
void Q3DateEdit::setAutoAdvance(bool advance)
 
1731
{
 
1732
    d->adv = advance;
 
1733
}
 
1734
 
 
1735
 
 
1736
bool Q3DateEdit::autoAdvance() const
 
1737
{
 
1738
    return d->adv;
 
1739
}
 
1740
 
 
1741
/*! \reimp
 
1742
*/
 
1743
 
 
1744
void Q3DateEdit::timerEvent(QTimerEvent *)
 
1745
{
 
1746
    d->overwrite = true;
 
1747
}
 
1748
 
 
1749
/*!
 
1750
    \fn void Q3DateEdit::valueChanged(const QDate& date)
 
1751
 
 
1752
    This signal is emitted whenever the editor's value changes. The \a
 
1753
    date parameter is the new value.
 
1754
*/
 
1755
 
 
1756
///////////
 
1757
 
 
1758
class Q3TimeEditPrivate
 
1759
{
 
1760
public:
 
1761
    int h;
 
1762
    int m;
 
1763
    int s;
 
1764
    uint display;
 
1765
    bool adv;
 
1766
    bool overwrite;
 
1767
    int timerId;
 
1768
    bool typing;
 
1769
    QTime min;
 
1770
    QTime max;
 
1771
    bool changed;
 
1772
    Q3DateTimeEditor *ed;
 
1773
    Q3SpinWidget *controls;
 
1774
};
 
1775
 
 
1776
/*!
 
1777
    \class Q3TimeEdit q3datetimeedit.h
 
1778
    \brief The Q3TimeEdit class provides a time editor.
 
1779
 
 
1780
    \compat
 
1781
 
 
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.
 
1789
    \code
 
1790
    QTime timeNow = QTime::currentTime();
 
1791
    Q3TimeEdit *timeEdit = new Q3TimeEdit(timeNow, this);
 
1792
    timeEdit->setRange(timeNow, timeNow.addSecs(60 * 60));
 
1793
    \endcode
 
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.
 
1797
 
 
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().
 
1801
 
 
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.
 
1806
 
 
1807
    \img datetimewidgets.png Date Time Widgets
 
1808
 
 
1809
    \sa QTime Q3DateEdit Q3DateTimeEdit
 
1810
*/
 
1811
 
 
1812
 
 
1813
/*!
 
1814
    Constructs an empty time edit with parent \a parent and called \a
 
1815
    name.
 
1816
*/
 
1817
 
 
1818
Q3TimeEdit::Q3TimeEdit(QWidget * parent, const char * name)
 
1819
    : Q3DateTimeEditBase(parent, name)
 
1820
{
 
1821
    init();
 
1822
}
 
1823
 
 
1824
/*!
 
1825
    \overload
 
1826
 
 
1827
    Constructs a time edit with the initial time value, \a time,
 
1828
    parent \a parent and called \a name.
 
1829
*/
 
1830
 
 
1831
Q3TimeEdit::Q3TimeEdit(const QTime& time, QWidget * parent, const char * name)
 
1832
    : Q3DateTimeEditBase(parent, name)
 
1833
{
 
1834
    init();
 
1835
    setTime(time);
 
1836
}
 
1837
 
 
1838
/*! \internal
 
1839
 */
 
1840
 
 
1841
void Q3TimeEdit::init()
 
1842
{
 
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()));
 
1850
 
 
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());
 
1855
 
 
1856
    d->h = 0;
 
1857
    d->m = 0;
 
1858
    d->s = 0;
 
1859
    d->display = Hours | Minutes | Seconds;
 
1860
    if (lAMPM) {
 
1861
        d->display |= AMPM;
 
1862
        d->ed->appendSection(QNumberSection(0,0, false, 3));
 
1863
    }
 
1864
    d->adv = false;
 
1865
    d->overwrite = true;
 
1866
    d->timerId = 0;
 
1867
    d->typing = false;
 
1868
    d->min = QTime(0, 0, 0);
 
1869
    d->max = QTime(23, 59, 59);
 
1870
    d->changed = false;
 
1871
 
 
1872
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
 
1873
 
 
1874
    refcount++;
 
1875
}
 
1876
 
 
1877
/*!
 
1878
    Destroys the object and frees any allocated resources.
 
1879
*/
 
1880
 
 
1881
Q3TimeEdit::~Q3TimeEdit()
 
1882
{
 
1883
    delete d;
 
1884
    if (!--refcount)
 
1885
        cleanup();
 
1886
}
 
1887
 
 
1888
/*!
 
1889
    \property Q3TimeEdit::minValue
 
1890
    \brief the minimum time value
 
1891
 
 
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.
 
1895
 
 
1896
    \sa maxValue setRange()
 
1897
*/
 
1898
 
 
1899
QTime Q3TimeEdit::minValue() const
 
1900
{
 
1901
    return d->min;
 
1902
}
 
1903
 
 
1904
/*!
 
1905
    \property Q3TimeEdit::maxValue
 
1906
    \brief the maximum time value
 
1907
 
 
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.
 
1911
 
 
1912
    \sa minValue setRange()
 
1913
*/
 
1914
 
 
1915
QTime Q3TimeEdit::maxValue() const
 
1916
{
 
1917
    return d->max;
 
1918
}
 
1919
 
 
1920
 
 
1921
/*!
 
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.
 
1925
*/
 
1926
 
 
1927
void Q3TimeEdit::setRange(const QTime& min, const QTime& max)
 
1928
{
 
1929
    if (min.isValid())
 
1930
        d->min = min;
 
1931
    if (max.isValid())
 
1932
        d->max = max;
 
1933
}
 
1934
 
 
1935
/*!
 
1936
  \property Q3TimeEdit::display
 
1937
  \brief the sections that are displayed in the time edit
 
1938
 
 
1939
  The value can be any combination of the values in the Display enum.
 
1940
  By default, the widget displays hours, minutes and seconds.
 
1941
*/
 
1942
void Q3TimeEdit::setDisplay(uint display)
 
1943
{
 
1944
    if (d->display == display)
 
1945
        return;
 
1946
 
 
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));
 
1957
 
 
1958
    d->ed->setFocusSection(0);
 
1959
    d->ed->update();
 
1960
}
 
1961
 
 
1962
uint Q3TimeEdit::display() const
 
1963
{
 
1964
    return d->display;
 
1965
}
 
1966
 
 
1967
/*!
 
1968
    \property Q3TimeEdit::time
 
1969
    \brief the editor's time value.
 
1970
 
 
1971
    When changing the time property, if the time is less than
 
1972
    minValue(), or is greater than maxValue(), nothing happens.
 
1973
*/
 
1974
 
 
1975
void Q3TimeEdit::setTime(const QTime& time)
 
1976
{
 
1977
    if (!time.isValid()) {
 
1978
        d->h = 0;
 
1979
        d->m = 0;
 
1980
        d->s = 0;
 
1981
    } else {
 
1982
        if (time > maxValue() || time < minValue())
 
1983
            return;
 
1984
        d->h = time.hour();
 
1985
        d->m = time.minute();
 
1986
        d->s = time.second();
 
1987
        emit valueChanged(time);
 
1988
    }
 
1989
    d->changed = false;
 
1990
    d->ed->repaint(d->ed->rect());
 
1991
}
 
1992
 
 
1993
QTime Q3TimeEdit::time() const
 
1994
{
 
1995
    if (QTime::isValid(d->h, d->m, d->s))
 
1996
        return QTime(d->h, d->m, d->s);
 
1997
    return QTime();
 
1998
}
 
1999
 
 
2000
/*!
 
2001
    \property Q3TimeEdit::autoAdvance
 
2002
    \brief whether the editor automatically advances to the next
 
2003
    section
 
2004
 
 
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.
 
2008
*/
 
2009
 
 
2010
void Q3TimeEdit::setAutoAdvance(bool advance)
 
2011
{
 
2012
    d->adv = advance;
 
2013
}
 
2014
 
 
2015
bool Q3TimeEdit::autoAdvance() const
 
2016
{
 
2017
    return d->adv;
 
2018
}
 
2019
 
 
2020
/*!
 
2021
    Sets the separator to \a s. Note that currently only the first
 
2022
    character of \a s is used.
 
2023
*/
 
2024
 
 
2025
void Q3TimeEdit::setSeparator(const QString& s)
 
2026
{
 
2027
    d->ed->setSeparator(s);
 
2028
}
 
2029
 
 
2030
/*!
 
2031
    Returns the editor's separator.
 
2032
*/
 
2033
 
 
2034
QString Q3TimeEdit::separator() const
 
2035
{
 
2036
    return d->ed->separator();
 
2037
}
 
2038
 
 
2039
 
 
2040
/*!
 
2041
    \fn void Q3TimeEdit::valueChanged(const QTime& time)
 
2042
 
 
2043
    This signal is emitted whenever the editor's value changes. The \a
 
2044
    time parameter is the new value.
 
2045
*/
 
2046
 
 
2047
/*! \reimp
 
2048
 
 
2049
*/
 
2050
 
 
2051
bool Q3TimeEdit::event(QEvent *e)
 
2052
{
 
2053
    if (e->type() == QEvent::FocusOut) {
 
2054
        d->typing = false;
 
2055
        if (d->changed) {
 
2056
            emit valueChanged(time());
 
2057
            d->changed = false;
 
2058
        }
 
2059
    } else if (e->type() == QEvent::LocaleChange) {
 
2060
        readLocaleSettings();
 
2061
        d->ed->setSeparator(localTimeSep());
 
2062
    }
 
2063
    return Q3DateTimeEditBase::event(e);
 
2064
}
 
2065
 
 
2066
/*! \reimp
 
2067
 
 
2068
*/
 
2069
 
 
2070
void Q3TimeEdit::timerEvent(QTimerEvent *)
 
2071
{
 
2072
    d->overwrite = true;
 
2073
}
 
2074
 
 
2075
 
 
2076
/*! \reimp
 
2077
 
 
2078
*/
 
2079
 
 
2080
void Q3TimeEdit::stepUp()
 
2081
{
 
2082
    int sec = d->ed->mapSection(d->ed->focusSection());
 
2083
    bool accepted = true;
 
2084
    switch(sec) {
 
2085
    case 0:
 
2086
        if (!outOfRange(d->h+1, d->m, d->s))
 
2087
            setHour(d->h+1);
 
2088
        else
 
2089
            setHour(d->min.hour());
 
2090
        break;
 
2091
    case 1:
 
2092
        if (!outOfRange(d->h, d->m+1, d->s))
 
2093
            setMinute(d->m+1);
 
2094
        else
 
2095
            setMinute(d->min.minute());
 
2096
        break;
 
2097
    case 2:
 
2098
        if (!outOfRange(d->h, d->m, d->s+1))
 
2099
            setSecond(d->s+1);
 
2100
        else
 
2101
            setSecond(d->min.second());
 
2102
        break;
 
2103
    case 3:
 
2104
        if (d->h < 12)
 
2105
            setHour(d->h+12);
 
2106
        else
 
2107
            setHour(d->h-12);
 
2108
        break;
 
2109
    default:
 
2110
        accepted = false;
 
2111
        qWarning("Q3TimeEdit::stepUp: Focus section out of range!");
 
2112
        break;
 
2113
    }
 
2114
    if (accepted) {
 
2115
        d->changed = true;
 
2116
        emit valueChanged(time());
 
2117
    }
 
2118
    d->ed->repaint(d->ed->rect());
 
2119
}
 
2120
 
 
2121
 
 
2122
/*! \reimp
 
2123
 
 
2124
*/
 
2125
 
 
2126
void Q3TimeEdit::stepDown()
 
2127
{
 
2128
    int sec = d->ed->mapSection(d->ed->focusSection());
 
2129
 
 
2130
    bool accepted = true;
 
2131
    switch(sec) {
 
2132
    case 0:
 
2133
        if (!outOfRange(d->h-1, d->m, d->s))
 
2134
            setHour(d->h-1);
 
2135
        else
 
2136
            setHour(d->max.hour());
 
2137
        break;
 
2138
    case 1:
 
2139
        if (!outOfRange(d->h, d->m-1, d->s))
 
2140
            setMinute(d->m-1);
 
2141
        else
 
2142
            setMinute(d->max.minute());
 
2143
        break;
 
2144
    case 2:
 
2145
        if (!outOfRange(d->h, d->m, d->s-1))
 
2146
            setSecond(d->s-1);
 
2147
        else
 
2148
            setSecond(d->max.second());
 
2149
        break;
 
2150
    case 3:
 
2151
        if (d->h > 11)
 
2152
            setHour(d->h-12);
 
2153
        else
 
2154
            setHour(d->h+12);
 
2155
        break;
 
2156
    default:
 
2157
        accepted = false;
 
2158
        qWarning("Q3TimeEdit::stepDown: Focus section out of range!");
 
2159
        break;
 
2160
    }
 
2161
    if (accepted) {
 
2162
        d->changed = true;
 
2163
        emit valueChanged(time());
 
2164
    }
 
2165
    d->ed->repaint(d->ed->rect());
 
2166
}
 
2167
 
 
2168
 
 
2169
/*!
 
2170
    Returns the formatted number for section \a sec. This will
 
2171
    correspond to either the hour, minute or second section, depending
 
2172
    on \a sec.
 
2173
*/
 
2174
 
 
2175
QString Q3TimeEdit::sectionFormattedText(int sec)
 
2176
{
 
2177
    QString txt;
 
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);
 
2183
    else
 
2184
        d->ed->setSectionSelection(sec, offset - txt.length(), offset);
 
2185
 
 
2186
    return txt;
 
2187
}
 
2188
 
 
2189
 
 
2190
/*! \reimp
 
2191
 
 
2192
*/
 
2193
 
 
2194
bool Q3TimeEdit::setFocusSection(int sec)
 
2195
{
 
2196
    if (sec != d->ed->focusSection()) {
 
2197
        killTimer(d->timerId);
 
2198
        d->overwrite = true;
 
2199
        d->typing = false;
 
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);
 
2204
        if (d->changed) {
 
2205
            emit valueChanged(time());
 
2206
            d->changed = false;
 
2207
        }
 
2208
    }
 
2209
    return d->ed->setFocusSection(sec);
 
2210
}
 
2211
 
 
2212
 
 
2213
/*!
 
2214
    Sets the hour to \a h, which must be a valid hour, i.e. in the
 
2215
    range 0..24.
 
2216
*/
 
2217
 
 
2218
void Q3TimeEdit::setHour(int h)
 
2219
{
 
2220
    if (h < 0)
 
2221
        h = 0;
 
2222
    if (h > 23)
 
2223
        h = 23;
 
2224
    d->h = h;
 
2225
}
 
2226
 
 
2227
 
 
2228
/*!
 
2229
    Sets the minute to \a m, which must be a valid minute, i.e. in the
 
2230
    range 0..59.
 
2231
*/
 
2232
 
 
2233
void Q3TimeEdit::setMinute(int m)
 
2234
{
 
2235
    if (m < 0)
 
2236
        m = 0;
 
2237
    if (m > 59)
 
2238
        m = 59;
 
2239
    d->m = m;
 
2240
}
 
2241
 
 
2242
 
 
2243
/*!
 
2244
    Sets the second to \a s, which must be a valid second, i.e. in the
 
2245
    range 0..59.
 
2246
*/
 
2247
 
 
2248
void Q3TimeEdit::setSecond(int s)
 
2249
{
 
2250
    if (s < 0)
 
2251
        s = 0;
 
2252
    if (s > 59)
 
2253
        s = 59;
 
2254
    d->s = s;
 
2255
}
 
2256
 
 
2257
 
 
2258
/*! \internal
 
2259
 
 
2260
  Returns the text of section \a sec.
 
2261
 
 
2262
*/
 
2263
 
 
2264
QString Q3TimeEdit::sectionText(int sec)
 
2265
{
 
2266
    sec = d->ed->mapSection(sec);
 
2267
 
 
2268
    QString txt;
 
2269
    switch(sec) {
 
2270
    case 0:
 
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);
 
2273
        } else {
 
2274
            if (d->h)
 
2275
                txt = QString::number(d->h - 12);
 
2276
            else
 
2277
                txt = "12";
 
2278
        }
 
2279
        break;
 
2280
    case 1:
 
2281
        txt = QString::number(d->m);
 
2282
        break;
 
2283
    case 2:
 
2284
        txt = QString::number(d->s);
 
2285
        break;
 
2286
    case 3:
 
2287
        if (d->h < 12) {
 
2288
            if (lAM)
 
2289
                txt = *lAM;
 
2290
            else
 
2291
                txt = QString::fromLatin1("AM");
 
2292
        } else {
 
2293
            if (lPM)
 
2294
                txt = *lPM;
 
2295
            else
 
2296
                txt = QString::fromLatin1("PM");
 
2297
        }
 
2298
        break;
 
2299
    default:
 
2300
        break;
 
2301
    }
 
2302
    return txt;
 
2303
}
 
2304
 
 
2305
 
 
2306
/*! \internal
 
2307
 Returns true if \a h, \a m, and \a s are out of range.
 
2308
 */
 
2309
 
 
2310
bool Q3TimeEdit::outOfRange(int h, int m, int s) const
 
2311
{
 
2312
    if (QTime::isValid(h, m, s)) {
 
2313
        QTime currentTime(h, m, s);
 
2314
        if (currentTime > maxValue() ||
 
2315
             currentTime < minValue())
 
2316
            return true;
 
2317
        else
 
2318
            return false;
 
2319
    }
 
2320
    return true;
 
2321
}
 
2322
 
 
2323
/*! \reimp
 
2324
 
 
2325
*/
 
2326
 
 
2327
void Q3TimeEdit::addNumber(int sec, int num)
 
2328
{
 
2329
    if (sec == -1)
 
2330
        return;
 
2331
    sec = d->ed->mapSection(sec);
 
2332
    killTimer(d->timerId);
 
2333
    bool overwrite = false;
 
2334
    bool accepted = false;
 
2335
    d->typing = true;
 
2336
    QString txt;
 
2337
 
 
2338
    switch(sec) {
 
2339
    case 0:
 
2340
        txt = (d->display & AMPM && d->h > 12) ?
 
2341
            QString::number(d->h - 12) : QString::number(d->h);
 
2342
 
 
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)
 
2347
                num += 12;
 
2348
            if (!outOfRange(num, d->m, d->s)) {
 
2349
                accepted = true;
 
2350
                d->h = num;
 
2351
            }
 
2352
        } else {
 
2353
            txt += QString::number(num);
 
2354
            int temp = txt.toInt();
 
2355
 
 
2356
            if (d->display & AMPM) {
 
2357
                if (temp == 12) {
 
2358
                    if (d->h < 12) {
 
2359
                        temp = 0;
 
2360
                    }
 
2361
                    accepted = true;
 
2362
                } else if (outOfRange(temp + 12, d->m, d->s)) {
 
2363
                    txt = QString::number(d->h);
 
2364
                } else {
 
2365
                    if (d->h > 11) {
 
2366
                        temp += 12;
 
2367
                    }
 
2368
                    accepted = true;
 
2369
                }
 
2370
            } else if (!(d->display & AMPM) && outOfRange(temp, d->m, d->s)) {
 
2371
                txt = QString::number(d->h);
 
2372
            } else {
 
2373
                accepted = true;
 
2374
            }
 
2375
 
 
2376
            if (accepted)
 
2377
                d->h = temp;
 
2378
 
 
2379
            if (d->adv && txt.length() == 2) {
 
2380
                setFocusSection(d->ed->focusSection()+1);
 
2381
                overwrite = true;
 
2382
            }
 
2383
        }
 
2384
        break;
 
2385
 
 
2386
    case 1:
 
2387
        txt = QString::number(d->m);
 
2388
        if (d->overwrite || txt.length() == 2) {
 
2389
            if (!outOfRange(d->h, num, d->s)) {
 
2390
                accepted = true;
 
2391
                d->m = num;
 
2392
            }
 
2393
        } else {
 
2394
            txt += QString::number(num);
 
2395
            int temp = txt.toInt();
 
2396
            if (temp > 59)
 
2397
                temp = num;
 
2398
            if (outOfRange(d->h, temp, d->s))
 
2399
                txt = QString::number(d->m);
 
2400
            else {
 
2401
                accepted = true;
 
2402
                d->m = temp;
 
2403
            }
 
2404
            if (d->adv && txt.length() == 2) {
 
2405
                setFocusSection(d->ed->focusSection()+1);
 
2406
                overwrite = true;
 
2407
            }
 
2408
        }
 
2409
        break;
 
2410
 
 
2411
    case 2:
 
2412
        txt = QString::number(d->s);
 
2413
        if (d->overwrite || txt.length() == 2) {
 
2414
            if (!outOfRange(d->h, d->m, num)) {
 
2415
                accepted = true;
 
2416
                d->s = num;
 
2417
            }
 
2418
        } else {
 
2419
            txt += QString::number(num);
 
2420
            int temp = txt.toInt();
 
2421
            if (temp > 59)
 
2422
                temp = num;
 
2423
            if (outOfRange(d->h, d->m, temp))
 
2424
                txt = QString::number(d->s);
 
2425
            else {
 
2426
                accepted = true;
 
2427
                d->s = temp;
 
2428
            }
 
2429
            if (d->adv && txt.length() == 2) {
 
2430
                setFocusSection(d->ed->focusSection()+1);
 
2431
                overwrite = true;
 
2432
            }
 
2433
        }
 
2434
        break;
 
2435
 
 
2436
    case 3:
 
2437
        break;
 
2438
 
 
2439
    default:
 
2440
        break;
 
2441
    }
 
2442
    d->changed = accepted;
 
2443
    if (accepted)
 
2444
        emit valueChanged(time());
 
2445
    d->overwrite = overwrite;
 
2446
    d->timerId = startTimer(qApp->doubleClickInterval()*4);
 
2447
    d->ed->repaint(d->ed->rect());
 
2448
}
 
2449
 
 
2450
 
 
2451
/*!
 
2452
  \internal
 
2453
 
 
2454
  Function which is called whenever the user tries to
 
2455
  remove the first number from \a sec by pressing the backspace key.
 
2456
*/
 
2457
 
 
2458
void Q3TimeEdit::removeFirstNumber(int sec)
 
2459
{
 
2460
    if (sec == -1)
 
2461
        return;
 
2462
    sec = d->ed->mapSection(sec);
 
2463
    QString txt;
 
2464
    switch(sec) {
 
2465
    case 0:
 
2466
        txt = QString::number(d->h);
 
2467
        break;
 
2468
    case 1:
 
2469
        txt = QString::number(d->m);
 
2470
        break;
 
2471
    case 2:
 
2472
        txt = QString::number(d->s);
 
2473
        break;
 
2474
    }
 
2475
    txt = txt.mid(1, txt.length()) + "0";
 
2476
    switch(sec) {
 
2477
    case 0:
 
2478
        d->h = txt.toInt();
 
2479
        break;
 
2480
    case 1:
 
2481
        d->m = txt.toInt();
 
2482
        break;
 
2483
    case 2:
 
2484
        d->s = txt.toInt();
 
2485
        break;
 
2486
    }
 
2487
    d->ed->repaint(d->ed->rect());
 
2488
}
 
2489
 
 
2490
/*! \reimp
 
2491
 
 
2492
*/
 
2493
void Q3TimeEdit::removeLastNumber(int sec)
 
2494
{
 
2495
    if (sec == -1)
 
2496
        return;
 
2497
    sec = d->ed->mapSection(sec);
 
2498
    QString txt;
 
2499
    switch(sec) {
 
2500
    case 0:
 
2501
        txt = QString::number(d->h);
 
2502
        break;
 
2503
    case 1:
 
2504
        txt = QString::number(d->m);
 
2505
        break;
 
2506
    case 2:
 
2507
        txt = QString::number(d->s);
 
2508
        break;
 
2509
    }
 
2510
    txt = txt.mid(0, txt.length()-1);
 
2511
    switch(sec) {
 
2512
    case 0:
 
2513
        d->h = txt.toInt();
 
2514
        break;
 
2515
    case 1:
 
2516
        d->m = txt.toInt();
 
2517
        break;
 
2518
    case 2:
 
2519
        d->s = txt.toInt();
 
2520
        break;
 
2521
    }
 
2522
    d->ed->repaint(d->ed->rect());
 
2523
}
 
2524
 
 
2525
/*! \reimp
 
2526
 */
 
2527
void Q3TimeEdit::resizeEvent(QResizeEvent *)
 
2528
{
 
2529
    d->controls->resize(width(), height());
 
2530
}
 
2531
 
 
2532
/*! \reimp
 
2533
*/
 
2534
QSize Q3TimeEdit::sizeHint() const
 
2535
{
 
2536
    ensurePolished();
 
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) {
 
2543
        if (lAM)
 
2544
            w += fm.width(*lAM) + 4;
 
2545
        else
 
2546
            w += fm.width(QString::fromLatin1("AM")) + 4;
 
2547
    }
 
2548
 
 
2549
    return QSize(w, qMax(h + fw * 2,20)).expandedTo(QApplication::globalStrut());
 
2550
}
 
2551
 
 
2552
/*! \reimp
 
2553
*/
 
2554
QSize Q3TimeEdit::minimumSizeHint() const
 
2555
{
 
2556
    return sizeHint();
 
2557
}
 
2558
 
 
2559
/*!
 
2560
    \internal
 
2561
    Enables/disables the push buttons according to the min/max time
 
2562
    for this widget.
 
2563
*/
 
2564
 
 
2565
// ### Remove in 4.0?
 
2566
 
 
2567
void Q3TimeEdit::updateButtons()
 
2568
{
 
2569
    if (!isEnabled())
 
2570
        return;
 
2571
 
 
2572
    bool upEnabled = time() < maxValue();
 
2573
    bool downEnabled = time() > minValue();
 
2574
 
 
2575
    d->controls->setUpEnabled(upEnabled);
 
2576
    d->controls->setDownEnabled(downEnabled);
 
2577
}
 
2578
 
 
2579
 
 
2580
class Q3DateTimeEditPrivate
 
2581
{
 
2582
public:
 
2583
    bool adv;
 
2584
};
 
2585
 
 
2586
/*!
 
2587
    \class Q3DateTimeEdit q3datetimeedit.h
 
2588
    \brief The Q3DateTimeEdit class combines a Q3DateEdit and Q3TimeEdit
 
2589
    widget into a single widget for editing datetimes.
 
2590
 
 
2591
    \compat
 
2592
 
 
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
 
2600
    setDateTime().
 
2601
 
 
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.
 
2606
 
 
2607
    It is recommended that the Q3DateTimeEdit is initialised with a
 
2608
    datetime, e.g.
 
2609
    \code
 
2610
    Q3DateTimeEdit *dateTimeEdit = new Q3DateTimeEdit(QDateTime::currentDateTime(), this);
 
2611
    dateTimeEdit->dateEdit()->setRange(QDateTime::currentDate(),
 
2612
                                        QDateTime::currentDate().addDays(7));
 
2613
    \endcode
 
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.
 
2617
 
 
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
 
2623
    time sections.
 
2624
 
 
2625
    \img datetimewidgets.png Date Time Widgets
 
2626
 
 
2627
    \sa Q3DateEdit Q3TimeEdit
 
2628
*/
 
2629
 
 
2630
/*!
 
2631
    Constructs an empty datetime edit with parent \a parent and called
 
2632
    \a name.
 
2633
*/
 
2634
Q3DateTimeEdit::Q3DateTimeEdit(QWidget * parent, const char * name)
 
2635
    : QWidget(parent, name)
 
2636
{
 
2637
    init();
 
2638
}
 
2639
 
 
2640
 
 
2641
/*!
 
2642
    \overload
 
2643
 
 
2644
    Constructs a datetime edit with the initial value \a datetime,
 
2645
    parent \a parent and called \a name.
 
2646
*/
 
2647
Q3DateTimeEdit::Q3DateTimeEdit(const QDateTime& datetime,
 
2648
                              QWidget * parent, const char * name)
 
2649
    : QWidget(parent, name)
 
2650
{
 
2651
    init();
 
2652
    setDateTime(datetime);
 
2653
}
 
2654
 
 
2655
 
 
2656
 
 
2657
/*!
 
2658
    Destroys the object and frees any allocated resources.
 
2659
*/
 
2660
 
 
2661
Q3DateTimeEdit::~Q3DateTimeEdit()
 
2662
{
 
2663
    delete d;
 
2664
}
 
2665
 
 
2666
 
 
2667
/*!
 
2668
    \reimp
 
2669
 
 
2670
    Intercepts and handles resize events which have special meaning
 
2671
    for the Q3DateTimeEdit.
 
2672
*/
 
2673
 
 
2674
void Q3DateTimeEdit::resizeEvent(QResizeEvent *)
 
2675
{
 
2676
    int dw = de->sizeHint().width();
 
2677
    int tw = te->sizeHint().width();
 
2678
    int w = width();
 
2679
    int h = height();
 
2680
    int extra = w - (dw + tw);
 
2681
 
 
2682
    if (tw + extra < 0) {
 
2683
        dw = w;
 
2684
    } else {
 
2685
        dw += 9 * extra / 16;
 
2686
    }
 
2687
    tw = w - dw;
 
2688
 
 
2689
    de->setGeometry(0, 0, dw, h);
 
2690
    te->setGeometry(dw, 0, tw, h);
 
2691
}
 
2692
 
 
2693
/*! \reimp
 
2694
*/
 
2695
 
 
2696
QSize Q3DateTimeEdit::minimumSizeHint() const
 
2697
{
 
2698
    QSize dsh = de->minimumSizeHint();
 
2699
    QSize tsh = te->minimumSizeHint();
 
2700
    return QSize(dsh.width() + tsh.width(),
 
2701
                  qMax(dsh.height(), tsh.height()));
 
2702
}
 
2703
 
 
2704
/*!  \internal
 
2705
 */
 
2706
 
 
2707
void Q3DateTimeEdit::init()
 
2708
{
 
2709
    d = new Q3DateTimeEditPrivate();
 
2710
    de = new Q3DateEdit(this, "qt_datetime_dateedit");
 
2711
    te = new Q3TimeEdit(this, "qt_datetime_timeedit");
 
2712
    d->adv = false;
 
2713
    connect(de, SIGNAL(valueChanged(QDate)), this, SLOT(newValue(QDate)));
 
2714
    connect(te, SIGNAL(valueChanged(QTime)), this, SLOT(newValue(QTime)));
 
2715
    setFocusProxy(de);
 
2716
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
 
2717
}
 
2718
 
 
2719
/*! \reimp
 
2720
 */
 
2721
 
 
2722
QSize Q3DateTimeEdit::sizeHint() const
 
2723
{
 
2724
    ensurePolished();
 
2725
    QSize dsh = de->sizeHint();
 
2726
    QSize tsh = te->sizeHint();
 
2727
    return QSize(dsh.width() + tsh.width(),
 
2728
                  qMax(dsh.height(), tsh.height()));
 
2729
}
 
2730
 
 
2731
/*!
 
2732
    \property Q3DateTimeEdit::dateTime
 
2733
    \brief the editor's datetime value
 
2734
 
 
2735
    The datetime edit's datetime which may be an invalid datetime.
 
2736
*/
 
2737
 
 
2738
void Q3DateTimeEdit::setDateTime(const QDateTime & dt)
 
2739
{
 
2740
    if (dt.isValid()) {
 
2741
        de->setDate(dt.date());
 
2742
        te->setTime(dt.time());
 
2743
        emit valueChanged(dt);
 
2744
    }
 
2745
}
 
2746
 
 
2747
QDateTime Q3DateTimeEdit::dateTime() const
 
2748
{
 
2749
    return QDateTime(de->date(), te->time());
 
2750
}
 
2751
 
 
2752
/*!
 
2753
    \fn void Q3DateTimeEdit::valueChanged(const QDateTime& datetime)
 
2754
 
 
2755
    This signal is emitted every time the date or time changes. The \a
 
2756
    datetime argument is the new datetime.
 
2757
*/
 
2758
 
 
2759
 
 
2760
/*! \internal
 
2761
 
 
2762
  Re-emits the value \a d.
 
2763
 */
 
2764
 
 
2765
void Q3DateTimeEdit::newValue(const QDate&)
 
2766
{
 
2767
    QDateTime dt = dateTime();
 
2768
    emit valueChanged(dt);
 
2769
}
 
2770
 
 
2771
/*! \internal
 
2772
  \overload
 
2773
  Re-emits the value \a t.
 
2774
 */
 
2775
 
 
2776
void Q3DateTimeEdit::newValue(const QTime&)
 
2777
{
 
2778
    QDateTime dt = dateTime();
 
2779
    emit valueChanged(dt);
 
2780
}
 
2781
 
 
2782
 
 
2783
/*!
 
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.
 
2787
*/
 
2788
 
 
2789
void Q3DateTimeEdit::setAutoAdvance(bool advance)
 
2790
{
 
2791
    de->setAutoAdvance(advance);
 
2792
    te->setAutoAdvance(advance);
 
2793
}
 
2794
 
 
2795
/*!
 
2796
    Returns true if auto-advance is enabled, otherwise returns false.
 
2797
 
 
2798
    \sa setAutoAdvance()
 
2799
*/
 
2800
 
 
2801
bool Q3DateTimeEdit::autoAdvance() const
 
2802
{
 
2803
    return de->autoAdvance();
 
2804
}
 
2805
 
 
2806
/*!
 
2807
    \fn Q3DateEdit* Q3DateTimeEdit::dateEdit()
 
2808
 
 
2809
    Returns the internal widget used for editing the date part of the
 
2810
    datetime.
 
2811
*/
 
2812
 
 
2813
/*!
 
2814
    \fn Q3TimeEdit* Q3DateTimeEdit::timeEdit()
 
2815
 
 
2816
    Returns the internal widget used for editing the time part of the
 
2817
    datetime.
 
2818
*/
 
2819
 
 
2820
#include "q3datetimeedit.moc"
 
2821
 
 
2822
#endif