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