moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / libkdeedu / extdate / extdatetimeedit.cpp
blob5933c304eae96e2fbc2b88890170752ed6af53a5
1 /****************************************************************************
2 **
3 **
4 ** Implementation of date and time edit classes
5 **
6 ** Created : 001103
7 **
8 ** Original qatetimeedit.cpp Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9 **>> ExtDate modifications (C) 2004 Jason Harris <jharris@30doradus.org>
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 as published by the Free Software
13 ** Foundation and appearing in the file LICENSE.GPL included in the
14 ** packaging of this file.
16 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
17 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
21 **********************************************************************/
23 //DEBUG
24 #include <kdebug.h>
26 #include "extdatetimeedit.h"
28 #ifndef QT_NO_DATETIMEEDIT
30 //#include "../kernel/qinternal_p.h"
31 //#include "../kernel/qrichtext_p.h"
32 #include <private/qinternal_p.h>
33 #include <private/qrichtext_p.h>
34 #include <qrangecontrol.h>
35 #include <qapplication.h>
36 #include <qpixmap.h>
37 #include <qapplication.h>
38 #include <qvaluelist.h>
39 #include <qstring.h>
40 #include <qstyle.h>
41 #include <qdatetimeedit.h> //need for QTimeEdit
43 #define EXTDATETIMEEDIT_HIDDEN_CHAR '0'
45 static QString *lDateSep = 0;
46 static QString *lTimeSep = 0;
47 static bool lAMPM = FALSE;
48 static QString *lAM = 0;
49 static QString *lPM = 0;
50 static ExtDateEdit::Order lOrder = ExtDateEdit::YMD;
51 static int refcount = 0;
53 static void cleanup()
55 delete lDateSep;
56 lDateSep = 0;
57 delete lTimeSep;
58 lTimeSep = 0;
59 delete lAM;
60 lAM = 0;
61 delete lPM;
62 lPM = 0;
65 /*!
66 \internal
67 try to get the order of DMY and the date/time separator from the locale settings
69 static void readLocaleSettings()
71 int dpos, mpos, ypos;
72 cleanup();
74 lDateSep = new QString();
75 lTimeSep = new QString();
77 #if defined(Q_WS_WIN)
78 QT_WA( {
79 TCHAR data[10];
80 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10 );
81 *lDateSep = QString::fromUcs2( (ushort*)data );
82 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10 );
83 *lTimeSep = QString::fromUcs2( (ushort*)data );
84 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10 );
85 lAMPM = QString::fromUcs2( (ushort*)data ).toInt()==0;
86 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10 );
87 QString am = QString::fromUcs2( (ushort*)data );
88 if ( !am.isEmpty() )
89 lAM = new QString( am );
90 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10 );
91 QString pm = QString::fromUcs2( (ushort*)data );
92 if ( !pm.isEmpty() )
93 lPM = new QString( pm );
94 } , {
95 char data[10];
96 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10 );
97 *lDateSep = QString::fromLocal8Bit( data );
98 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10 );
99 *lTimeSep = QString::fromLocal8Bit( data );
100 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10 );
101 lAMPM = QString::fromLocal8Bit( data ).toInt()==0;
102 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10 );
103 QString am = QString::fromLocal8Bit( data );
104 if ( !am.isEmpty() )
105 lAM = new QString( am );
106 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10 );
107 QString pm = QString::fromLocal8Bit( data );
108 if ( !pm.isEmpty() )
109 lPM = new QString( pm );
110 } );
111 #else
112 *lDateSep = "-";
113 *lTimeSep = ":";
114 #endif
115 QString d = ExtDate( 1999, 11, 22 ).toString( Qt::LocalDate );
116 dpos = d.find( "22" );
117 mpos = d.find( "11" );
118 ypos = d.find( "99" );
119 if ( dpos > -1 && mpos > -1 && ypos > -1 ) {
120 // test for DMY, MDY, YMD, YDM
121 if ( dpos < mpos && mpos < ypos ) {
122 lOrder = ExtDateEdit::DMY;
123 } else if ( mpos < dpos && dpos < ypos ) {
124 lOrder = ExtDateEdit::MDY;
125 } else if ( ypos < mpos && mpos < dpos ) {
126 lOrder = ExtDateEdit::YMD;
127 } else if ( ypos < dpos && dpos < mpos ) {
128 lOrder = ExtDateEdit::YDM;
129 } else {
130 // cannot determine the dateformat - use the default
131 return;
134 // this code needs to change if new formats are added
136 #ifndef Q_WS_WIN
137 QString sep = d.mid( QMIN( dpos, mpos ) + 2, QABS( dpos - mpos ) - 2 );
138 if ( d.contains( sep ) == 2 ) {
139 *lDateSep = sep;
141 #endif
144 #ifndef Q_WS_WIN
145 QString t = QTime( 11, 22, 33 ).toString( Qt::LocalDate );
146 dpos = t.find( "11" );
147 mpos = t.find( "22" );
148 ypos = t.find( "33" );
149 // We only allow hhmmss
150 if ( dpos > -1 && dpos < mpos && mpos < ypos ) {
151 QString sep = t.mid( dpos + 2, mpos - dpos - 2 );
152 if ( sep == t.mid( mpos + 2, ypos - mpos - 2 ) ) {
153 *lTimeSep = sep;
156 #endif
159 static ExtDateEdit::Order localOrder() {
160 if ( !lDateSep ) {
161 readLocaleSettings();
163 return lOrder;
166 static QString localDateSep() {
167 if ( !lDateSep ) {
168 readLocaleSettings();
170 return *lDateSep;
173 static QString localTimeSep() {
174 if ( !lTimeSep ) {
175 readLocaleSettings();
177 return *lTimeSep;
180 class ExtDateTimeEditorPrivate
182 public:
183 ExtDateTimeEditorPrivate()
184 : frm( TRUE ),
185 parag( new QTextParagraph( 0, 0, 0, FALSE ) ),
186 focusSec(0)
188 parag->formatter()->setWrapEnabled( FALSE );
189 cursor = new QTextCursor( 0 );
190 cursor->setParagraph( parag );
191 offset = 0;
192 sep = localDateSep();
193 refcount++;
195 ~ExtDateTimeEditorPrivate()
197 delete parag;
198 delete cursor;
199 if ( !--refcount )
200 cleanup();
203 void appendSection( const QNumberSection& sec )
205 sections.append( sec );
208 void clearSections()
210 sections.clear();
212 void setSectionSelection( int sec, int selstart, int selend )
214 if ( sec < 0 || sec > (int)sections.count() )
215 return;
216 sections[sec].setSelectionStart( selstart );
217 sections[sec].setSelectionEnd( selend );
219 uint sectionCount() const { return (uint)sections.count(); }
220 void setSeparator( const QString& s ) { sep = s; }
221 QString separator() const { return sep; }
223 void setFrame( bool f ) { frm = f; }
224 bool frame() const { return frm; }
226 int focusSection() const { return focusSec; }
227 int section( const QPoint& p )
229 cursor->place( p + QPoint( offset, 0 ), parag );
230 int idx = cursor->index();
231 for ( uint i = 0; i < sections.count(); ++i ) {
232 if ( idx >= sections[i].selectionStart() &&
233 idx <= sections[i].selectionEnd() )
234 return i;
236 return -1;
238 QNumberSection section( int idx ) const
240 return sections[idx];
242 bool setFocusSection( int idx )
244 if ( idx > (int)sections.count()-1 || idx < 0 )
245 return FALSE;
246 if ( idx != focusSec ) {
247 focusSec = idx;
248 applyFocusSelection();
249 return TRUE;
251 return FALSE;
254 bool inSectionSelection( int idx )
256 for ( uint i = 0; i < sections.count(); ++i ) {
257 if ( idx >= sections[i].selectionStart() &&
258 idx <= sections[i].selectionEnd() )
259 return TRUE;
261 return FALSE;
264 void paint( const QString& txt, bool focus, QPainter& p,
265 const QColorGroup& cg, const QRect& rect, QStyle& style )
267 int fw = 0;
268 if ( frm )
269 fw = style.pixelMetric(QStyle::PM_DefaultFrameWidth);
271 parag->truncate( 0 );
272 parag->append( txt );
273 if ( !focus )
274 parag->removeSelection( QTextDocument::Standard );
275 else {
276 applyFocusSelection();
279 /* color all EXTDATETIMEEDIT_HIDDEN_CHAR chars to background color */
280 QTextFormat *fb = parag->formatCollection()->format( p.font(),
281 cg.base() );
282 QTextFormat *nf = parag->formatCollection()->format( p.font(),
283 cg.text() );
284 for ( uint i = 0; i < txt.length(); ++i ) {
285 parag->setFormat( i, 1, nf );
286 if ( inSectionSelection( i ) )
287 continue;
288 if ( txt.at(i) == EXTDATETIMEEDIT_HIDDEN_CHAR )
289 parag->setFormat( i, 1, fb );
290 else
291 parag->setFormat( i, 1, nf );
293 fb->removeRef();
294 nf->removeRef();
296 QRect r( rect.x(), rect.y(), rect.width() - 2 * ( 2 + fw ), rect.height() );
297 parag->pseudoDocument()->docRect = r;
298 parag->invalidate(0);
299 parag->format();
301 int xoff = 2 + fw - offset;
302 int yoff = ( rect.height() - parag->rect().height() + 1 ) / 2;
303 if ( yoff < 0 )
304 yoff = 0;
306 p.translate( xoff, yoff );
307 parag->paint( p, cg, 0, TRUE );
308 if ( frm )
309 p.translate( -xoff, -yoff );
312 void resize( const QSize& size ) { sz = size; }
314 int mapSection( int sec )
316 return sections[sec].index();
319 protected:
320 void applyFocusSelection()
322 if ( focusSec > -1 ) {
323 int selstart = sections[ focusSec ].selectionStart();
324 int selend = sections[ focusSec ].selectionEnd();
325 parag->setSelection( QTextDocument::Standard, selstart, selend );
326 parag->format();
327 if ( parag->at( selstart )->x < offset ||
328 parag->at( selend )->x + parag->string()->width( selend ) > offset + sz.width() ) {
329 offset = parag->at( selstart )->x;
333 private:
334 bool frm;
335 QTextParagraph *parag;
336 QTextCursor *cursor;
337 QSize sz;
338 int focusSec;
339 QValueList< QNumberSection > sections;
340 QString sep;
341 int offset;
344 class ExtDateTimeSpinWidget : public QSpinWidget
346 public:
347 ExtDateTimeSpinWidget( QWidget *parent, const char *name )
348 : QSpinWidget( parent, name )
352 protected:
353 #ifndef QT_NO_WHEELEVENT
354 void wheelEvent( QWheelEvent *e )
356 ExtDateTimeEditor *editor = (ExtDateTimeEditor*)editWidget()->qt_cast( "ExtDateTimeEditor" );
357 Q_ASSERT( editor );
358 if ( !editor )
359 return;
361 int section = editor->sectionAt( e->pos() );
362 editor->setFocusSection( section );
364 if ( section == -1 )
365 return;
366 QSpinWidget::wheelEvent( e );
368 #endif
372 Constructs an empty datetime editor with parent \a parent and
373 called \a name.
375 ExtDateTimeEditor::ExtDateTimeEditor( ExtDateTimeEditBase * parent,
376 const char * name )
377 : QWidget( parent, name, WNoAutoErase )
379 d = new ExtDateTimeEditorPrivate();
380 cw = parent;
381 init();
385 Destroys the object and frees any allocated resources.
388 ExtDateTimeEditor::~ExtDateTimeEditor()
390 delete d;
393 /*! \internal
397 void ExtDateTimeEditor::init()
399 setBackgroundMode( PaletteBase );
400 setFocusSection( -1 );
401 installEventFilter( this );
402 setFocusPolicy( WheelFocus );
406 /*! \reimp
410 bool ExtDateTimeEditor::event( QEvent *e )
412 if ( e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut ) {
413 if ( e->type() == QEvent::FocusOut )
414 qApp->sendEvent( cw, e );
415 update( rect() );
416 } else if ( e->type() == QEvent::AccelOverride ) {
417 QKeyEvent* ke = (QKeyEvent*) e;
418 switch ( ke->key() ) {
419 case Key_Delete:
420 case Key_Backspace:
421 case Key_Up:
422 case Key_Down:
423 case Key_Left:
424 case Key_Right:
425 ke->accept();
426 default:
427 break;
430 return QWidget::event( e );
433 /*! \reimp
437 void ExtDateTimeEditor::resizeEvent( QResizeEvent *e )
439 d->resize( e->size() );
440 QWidget::resizeEvent( e );
444 /*! \reimp
448 void ExtDateTimeEditor::paintEvent( QPaintEvent * )
450 QString txt;
451 for ( uint i = 0; i < d->sectionCount(); ++i ) {
452 txt += cw->sectionFormattedText( i );
453 if ( i < d->sectionCount()-1 ) {
454 if ( d->section( i+1 ).separator() )
455 txt += d->separator();
456 else
457 txt += " ";
461 QSharedDoubleBuffer buffer( this );
462 const QBrush &bg =
463 colorGroup().brush( isEnabled() ? QColorGroup::Base : QColorGroup::Background );
464 buffer.painter()->fillRect( 0, 0, width(), height(), bg );
465 d->paint( txt, hasFocus(), *buffer.painter(), colorGroup(), rect(),
466 style() );
467 buffer.end();
472 Returns the section index at point \a p.
474 int ExtDateTimeEditor::sectionAt( const QPoint &p )
476 return d->section( p );
479 int ExtDateTimeEditor::mapSection( int sec )
481 return d->mapSection( sec );
485 /*! \reimp
489 void ExtDateTimeEditor::mousePressEvent( QMouseEvent *e )
491 QPoint p( e->pos().x(), 0 );
492 int sec = sectionAt( p );
493 if ( sec != -1 ) {
494 cw->setFocusSection( sec );
495 repaint( rect(), FALSE );
499 /*! \reimp
502 bool ExtDateTimeEditor::eventFilter( QObject *o, QEvent *e )
504 if ( o == this ) {
505 if ( e->type() == QEvent::KeyPress ) {
506 QKeyEvent *ke = (QKeyEvent*)e;
507 switch ( ke->key() ) {
508 case Key_Right:
509 if ( d->focusSection() < (int)d->sectionCount()-1 ) {
510 if ( cw->setFocusSection( focusSection()+1 ) )
511 repaint( rect(), FALSE );
513 return TRUE;
514 case Key_Left:
515 if ( d->focusSection() > 0 ) {
516 if ( cw->setFocusSection( focusSection()-1 ) )
517 repaint( rect(), FALSE );
519 return TRUE;
520 case Key_Up:
521 cw->stepUp();
522 return TRUE;
523 case Key_Down:
524 cw->stepDown();
525 return TRUE;
526 case Key_Backspace:
527 if ( ::qt_cast<ExtDateEdit*>(cw) )
528 ((ExtDateEdit*)cw)->removeFirstNumber( d->focusSection() );
529 else if ( ::qt_cast<QTimeEdit*>(cw) )
530 ((QTimeEdit*)cw)->removeFirstNumber( d->focusSection() );
531 return TRUE;
532 case Key_Delete:
533 cw->removeLastNumber( d->focusSection() );
534 return TRUE;
535 case Key_Tab:
536 case Key_BackTab: {
537 if ( ke->state() == Qt::ControlButton )
538 return FALSE;
540 QWidget *w = this;
541 bool hadDateEdit = FALSE;
542 while ( w ) {
543 if ( ::qt_cast<ExtDateTimeSpinWidget*>(w) && qstrcmp( w->name(), "qt_spin_widget" ) != 0 ||
544 ::qt_cast<ExtDateTimeEdit*>(w) )
545 break;
546 hadDateEdit = hadDateEdit || ::qt_cast<ExtDateEdit*>(w);
547 w = w->parentWidget();
550 if ( w ) {
551 if ( !::qt_cast<ExtDateTimeEdit*>(w) ) {
552 w = w->parentWidget();
553 } else {
554 ExtDateTimeEdit *ed = (ExtDateTimeEdit*)w;
555 if ( hadDateEdit && ke->key() == Key_Tab ) {
556 ed->timeEdit()->setFocus();
557 return TRUE;
558 } else if ( !hadDateEdit && ke->key() == Key_BackTab ) {
559 ed->dateEdit()->setFocus();
560 return TRUE;
561 } else {
562 while ( w && !::qt_cast<ExtDateTimeEdit*>(w) )
563 w = w->parentWidget();
567 qApp->sendEvent( w, e );
568 return TRUE;
570 } break;
571 default:
572 QString txt = ke->text().lower();
573 if ( !txt.isEmpty() && !separator().isEmpty() && txt[0] == separator()[0] ) {
574 // do the same thing as KEY_RIGHT when the user presses the separator key
575 if ( d->focusSection() < 2 ) {
576 if ( cw->setFocusSection( focusSection()+1 ) )
577 repaint( rect(), FALSE );
579 return TRUE;
580 } else if ( !txt.isEmpty() && ::qt_cast<QTimeEdit*>(cw) && focusSection() == (int) d->sectionCount()-1 ) {
581 // the first character of the AM/PM indicator toggles if the section has focus
582 QTimeEdit *te = (QTimeEdit*)cw;
583 QTime time = te->time();
584 if ( lAMPM && lAM && lPM && (te->display()&QTimeEdit::AMPM) ) {
585 if ( txt[0] == (*lAM).lower()[0] && time.hour() >= 12 ) {
586 time.setHMS( time.hour()-12, time.minute(), time.second(), time.msec() );
587 te->setTime( time );
588 } else if ( txt[0] == (*lPM).lower()[0] && time.hour() < 12 ) {
589 time.setHMS( time.hour()+12, time.minute(), time.second(), time.msec() );
590 te->setTime( time );
595 int num = txt[0].digitValue();
596 if ( num != -1 ) {
597 cw->addNumber( d->focusSection(), num );
598 return TRUE;
603 return FALSE;
608 Appends the number section \a sec to the editor.
611 void ExtDateTimeEditor::appendSection( const QNumberSection& sec )
613 d->appendSection( sec );
617 Removes all sections from the editor.
620 void ExtDateTimeEditor::clearSections()
622 d->clearSections();
626 Sets the selection of \a sec to start at \a selstart and end at \a
627 selend.
630 void ExtDateTimeEditor::setSectionSelection( int sec, int selstart, int selend )
632 d->setSectionSelection( sec, selstart, selend );
636 Sets the separator for all numbered sections to \a s. Note that
637 currently, only the first character of \a s is used.
640 void ExtDateTimeEditor::setSeparator( const QString& s )
642 d->setSeparator( s );
643 update();
648 Returns the editor's separator.
651 QString ExtDateTimeEditor::separator() const
653 return d->separator();
657 Returns the number of the section that has focus.
660 int ExtDateTimeEditor::focusSection() const
662 return d->focusSection();
667 Sets the focus to section \a sec. If \a sec does not exist,
668 nothing happens.
671 bool ExtDateTimeEditor::setFocusSection( int sec )
673 return d->setFocusSection( sec );
676 /*! \class ExtDateTimeEditBase ExtDatetimeedit.h
677 \brief The ExtDateTimeEditBase class provides an abstraction for date and edit editors.
678 \internal
680 Small abstract class that provides some functions that are common
681 for both ExtDateEdit and QTimeEdit. Its used internally by
682 ExtDateTimeEditor.
685 /*! \fn QString ExtDateTimeEditBase::sectionFormattedText( int sec )
686 \internal
688 Pure virtual function which returns the formatted text of section \a
689 sec.
693 /*! \fn void ExtDateTimeEditBase::stepUp()
694 \internal
696 Pure virtual slot which is called whenever the user increases the
697 number in a section by pressing the widget's arrow buttons or the
698 keyboard's arrow keys.
701 /*! \fn void ExtDateTimeEditBase::stepDown()
702 \internal
704 Pure virtual slot which is called whenever the user decreases the
705 number in a section by pressing the widget's arrow buttons or the
706 keyboard's arrow keys.
710 /*! \fn void ExtDateTimeEditBase::addNumber( int sec, int num )
711 \internal
713 Pure virtual function which is called whenever the user types a number.
714 \a sec indicates the section where the number should be added. \a
715 num is the number that was pressed.
718 /*! \fn void ExtDateTimeEditBase::removeLastNumber( int sec )
719 \internal
721 Pure virtual function which is called whenever the user tries to
722 remove the last number from \a sec by pressing the delete key.
725 ////////////////
727 class ExtDateEditPrivate
729 public:
730 int y;
731 int m;
732 int d;
733 // remebers the last entry for the day.
734 // if the day is 31 and you cycle through the months,
735 // the day will be 31 again if you reach a month with 31 days
736 // otherwise it will be the highest day in the month
737 int dayCache;
738 int yearSection;
739 int monthSection;
740 int daySection;
741 ExtDateEdit::Order ord;
742 bool overwrite;
743 bool adv;
744 int timerId;
745 bool typing;
746 ExtDate min;
747 ExtDate max;
748 bool changed;
749 ExtDateTimeEditor *ed;
750 QSpinWidget *controls;
755 \class ExtDateEdit ExtDatetimeedit.h
756 \brief The ExtDateEdit class provides a date editor.
758 \ingroup advanced
759 \ingroup time
760 \mainclass
762 ExtDateEdit allows the user to edit dates by using the keyboard or
763 the arrow keys to increase/decrease date values. The arrow keys
764 can be used to move from section to section within the ExtDateEdit
765 box. Dates appear in accordance with the local date/time settings
766 or in year, month, day order if the system doesn't provide this
767 information. It is recommended that the ExtDateEdit be initialised
768 with a date, e.g.
770 \code
771 ExtDateEdit *dateEdit = new ExtDateEdit( ExtDate::currentDate(), this );
772 dateEdit->setRange( ExtDate::currentDate().addDays( -365 ),
773 ExtDate::currentDate().addDays( 365 ) );
774 dateEdit->setOrder( ExtDateEdit::MDY );
775 dateEdit->setAutoAdvance( TRUE );
776 \endcode
778 Here we've created a new ExtDateEdit object initialised with today's
779 date and restricted the valid date range to today plus or minus
780 365 days. We've set the order to month, day, year. If the auto
781 advance property is TRUE (as we've set it here) when the user
782 completes a section of the date, e.g. enters two digits for the
783 month, they are automatically taken to the next section.
785 The maximum and minimum values for a date value in the date editor
786 default to the maximum and minimum values for a ExtDate. You can
787 change this by calling setMinValue(), setMaxValue() or setRange().
789 Terminology: A ExtDateEdit widget comprises three 'sections', one
790 each for the year, month and day. You can change the separator
791 character using ExtDateTimeEditor::setSeparator(), by default the
792 separator will be taken from the systems settings. If that is
793 not possible, it defaults to "-".
795 \img datetimewidgets.png Date Time Widgets
797 \sa ExtDate QTimeEdit ExtDateTimeEdit
801 \enum ExtDateEdit::Order
803 This enum defines the order in which the sections that comprise a
804 date appear.
805 \value MDY month-day-year
806 \value DMY day-month-year
807 \value YMD year-month-day (the default)
808 \value YDM year-day-month (included for completeness; but should
809 not be used)
813 \enum QTimeEdit::Display
815 This enum defines the sections that comprise a time
817 \value Hours The hours section
818 \value Minutes The minutes section
819 \value Seconds The seconds section
820 \value AMPM The AM/PM section
822 The values can be or'ed together to show any combination.
826 Constructs an empty date editor which is a child of \a parent and
827 called name \a name.
830 ExtDateEdit::ExtDateEdit( QWidget * parent, const char * name )
831 : ExtDateTimeEditBase( parent, name )
833 init();
834 updateButtons();
838 \overload
840 Constructs a date editor with the initial value \a date, parent \a
841 parent and called \a name.
843 The date editor is initialized with \a date.
846 ExtDateEdit::ExtDateEdit( const ExtDate& date, QWidget * parent, const char * name )
847 : ExtDateTimeEditBase( parent, name )
849 init();
850 setDate( date );
853 /*! \internal
855 void ExtDateEdit::init()
857 d = new ExtDateEditPrivate();
858 d->controls = new ExtDateTimeSpinWidget( this,
859 qstrcmp( name(), "qt_datetime_dateedit" ) == 0 ?
860 "qt_spin_widget" : "date edit controls" );
861 d->ed = new ExtDateTimeEditor( this, "date editor" );
862 d->controls->setEditWidget( d->ed );
863 setFocusProxy( d->ed );
864 connect( d->controls, SIGNAL( stepUpPressed() ), SLOT( stepUp() ) );
865 connect( d->controls, SIGNAL( stepDownPressed() ), SLOT( stepDown() ) );
866 connect( this, SIGNAL( valueChanged(const ExtDate&) ),
867 SLOT( updateButtons() ) );
868 d->ed->appendSection( QNumberSection( 0,4 ) );
869 d->ed->appendSection( QNumberSection( 5,7 ) );
870 d->ed->appendSection( QNumberSection( 8,10 ) );
872 d->yearSection = -1;
873 d->monthSection = -1;
874 d->daySection = -1;
876 d->y = 0;
877 d->m = 0;
878 d->d = 0;
879 d->dayCache = 0;
880 setOrder( localOrder() );
881 setFocusSection( 0 );
882 d->overwrite = TRUE;
883 d->adv = FALSE;
884 d->timerId = 0;
885 d->typing = FALSE;
886 d->min = ExtDate( -50000, 1, 1 );
887 d->max = ExtDate( 50000, 12, 31 );
888 d->changed = FALSE;
890 setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
892 refcount++;
896 Destroys the object and frees any allocated resources.
899 ExtDateEdit::~ExtDateEdit()
901 delete d;
902 if ( !--refcount )
903 cleanup();
907 \property ExtDateEdit::minValue
909 \brief the editor's minimum value
911 Setting the minimum date value is equivalent to calling
912 ExtDateEdit::setRange( \e d, maxValue() ), where \e d is the minimum
913 date. The default minimum date is 1752-09-14.
915 \sa maxValue setRange()
918 ExtDate ExtDateEdit::minValue() const
920 return d->min;
924 \property ExtDateEdit::maxValue
926 \brief the editor's maximum value
928 Setting the maximum date value for the editor is equivalent to
929 calling ExtDateEdit::setRange( minValue(), \e d ), where \e d is the
930 maximum date. The default maximum date is 8000-12-31.
932 \sa minValue setRange()
935 ExtDate ExtDateEdit::maxValue() const
937 return d->max;
942 Sets the valid input range for the editor to be from \a min to \a
943 max inclusive. If \a min is invalid no minimum date will be set.
944 Similarly, if \a max is invalid no maximum date will be set.
947 void ExtDateEdit::setRange( const ExtDate& min, const ExtDate& max )
949 if ( min.isValid() )
950 d->min = min;
951 if ( max.isValid() )
952 d->max = max;
956 Sets the separator to \a s. Note that currently only the first
957 character of \a s is used.
960 void ExtDateEdit::setSeparator( const QString& s )
962 d->ed->setSeparator( s );
966 Returns the editor's separator.
969 QString ExtDateEdit::separator() const
971 return d->ed->separator();
976 Enables/disables the push buttons according to the min/max date
977 for this widget.
980 void ExtDateEdit::updateButtons()
982 if ( !isEnabled() )
983 return;
985 fix();
987 bool upEnabled = date() < maxValue();
988 bool downEnabled = date() > minValue();
990 d->controls->setUpEnabled( upEnabled );
991 d->controls->setDownEnabled( downEnabled );
994 /*! \reimp
996 void ExtDateEdit::resizeEvent( QResizeEvent * )
998 d->controls->resize( width(), height() );
1001 /*! \reimp
1004 QSize ExtDateEdit::sizeHint() const
1006 constPolish();
1007 QFontMetrics fm( font() );
1008 int fw = style().pixelMetric( QStyle::PM_DefaultFrameWidth, this );
1009 int h = QMAX( fm.lineSpacing(), 14 ) + 2;
1010 int w = 2 + fm.width( '9' ) * 8 + fm.width( d->ed->separator() ) * 2
1011 + d->controls->upRect().width() + fw * 4;
1013 return QSize( w, QMAX(h + fw * 2,20) ).expandedTo( QApplication::globalStrut() );
1016 /*! \reimp
1019 QSize ExtDateEdit::minimumSizeHint() const
1021 return sizeHint();
1026 Returns the formatted number for section \a sec. This will
1027 correspond to either the year, month or day section, depending on
1028 the current display order.
1030 \sa setOrder()
1033 QString ExtDateEdit::sectionFormattedText( int sec )
1035 QString txt;
1036 txt = sectionText( sec );
1037 if ( d->typing && sec == d->ed->focusSection() )
1038 d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - txt.length(),
1039 sectionOffsetEnd( sec ) );
1040 else
1041 d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - sectionLength( sec ),
1042 sectionOffsetEnd( sec ) );
1044 txt = txt.rightJustify( sectionLength( sec ), EXTDATETIMEEDIT_HIDDEN_CHAR );
1045 return txt;
1050 Returns the desired length (number of digits) of section \a sec.
1051 This will correspond to either the year, month or day section,
1052 depending on the current display order.
1054 \sa setOrder()
1057 int ExtDateEdit::sectionLength( int sec ) const
1059 int val = 0;
1060 if ( sec == d->yearSection )
1061 val = 4;
1062 else if ( sec == d->monthSection )
1063 val = 2;
1064 else if ( sec == d->daySection )
1065 val = 2;
1067 return val;
1071 Returns the text of section \a sec. This will correspond to either
1072 the year, month or day section, depending on the current display
1073 order.
1075 \sa setOrder()
1078 QString ExtDateEdit::sectionText( int sec ) const
1080 int val = 0;
1081 if ( sec == d->yearSection )
1082 val = d->y;
1083 else if ( sec == d->monthSection )
1084 val = d->m;
1085 else if ( sec == d->daySection )
1086 val = d->d;
1088 return QString::number( val );
1091 /*! \internal
1093 Returns the end of the section offset \a sec.
1097 int ExtDateEdit::sectionOffsetEnd( int sec ) const
1099 if ( sec == d->yearSection ) {
1100 switch( d->ord ) {
1101 case DMY:
1102 case MDY:
1103 return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec );
1104 case YMD:
1105 case YDM:
1106 return sectionLength( sec );
1108 } else if ( sec == d->monthSection ) {
1109 switch( d->ord ) {
1110 case DMY:
1111 case YDM:
1112 case YMD:
1113 return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec );
1114 case MDY:
1115 return sectionLength( sec );
1117 } else if ( sec == d->daySection ) {
1118 switch( d->ord ) {
1119 case DMY:
1120 return sectionLength( sec );
1121 case YMD:
1122 case MDY:
1123 case YDM:
1124 return sectionOffsetEnd( sec-1 ) + separator().length() + sectionLength( sec );
1127 return 0;
1132 \property ExtDateEdit::order
1133 \brief the order in which the year, month and day appear
1135 The default order is locale dependent.
1137 \sa Order
1140 void ExtDateEdit::setOrder( ExtDateEdit::Order order )
1142 d->ord = order;
1143 switch( d->ord ) {
1144 case DMY:
1145 d->yearSection = 2;
1146 d->monthSection = 1;
1147 d->daySection = 0;
1148 break;
1149 case MDY:
1150 d->yearSection = 2;
1151 d->monthSection = 0;
1152 d->daySection = 1;
1153 break;
1154 case YMD:
1155 d->yearSection = 0;
1156 d->monthSection = 1;
1157 d->daySection = 2;
1158 break;
1159 case YDM:
1160 d->yearSection = 0;
1161 d->monthSection = 2;
1162 d->daySection = 1;
1163 break;
1166 if ( isVisible() )
1167 d->ed->repaint( d->ed->rect(), FALSE );
1171 ExtDateEdit::Order ExtDateEdit::order() const
1173 return d->ord;
1177 /*! \reimp
1180 void ExtDateEdit::stepUp()
1182 int sec = d->ed->focusSection();
1183 bool accepted = FALSE;
1184 if ( sec == d->yearSection ) {
1185 if ( !outOfRange( d->y+1, d->m, d->d ) ) {
1186 accepted = TRUE;
1187 setYear( d->y+1 );
1189 } else if ( sec == d->monthSection ) {
1190 if ( !outOfRange( d->y, d->m+1, d->d ) ) {
1191 accepted = TRUE;
1192 setMonth( d->m+1 );
1194 } else if ( sec == d->daySection ) {
1195 if ( !outOfRange( d->y, d->m, d->d+1 ) ) {
1196 accepted = TRUE;
1197 setDay( d->d+1 );
1200 if ( accepted ) {
1201 d->changed = TRUE;
1202 emit valueChanged( date() );
1205 d->ed->repaint( d->ed->rect(), FALSE );
1210 /*! \reimp
1214 void ExtDateEdit::stepDown()
1216 int sec = d->ed->focusSection();
1217 bool accepted = FALSE;
1218 if ( sec == d->yearSection ) {
1219 if ( !outOfRange( d->y-1, d->m, d->d ) ) {
1220 accepted = TRUE;
1221 setYear( d->y-1 );
1223 } else if ( sec == d->monthSection ) {
1224 if ( !outOfRange( d->y, d->m-1, d->d ) ) {
1225 accepted = TRUE;
1226 setMonth( d->m-1 );
1228 } else if ( sec == d->daySection ) {
1229 if ( !outOfRange( d->y, d->m, d->d-1 ) ) {
1230 accepted = TRUE;
1231 setDay( d->d-1 );
1234 if ( accepted ) {
1235 d->changed = TRUE;
1236 emit valueChanged( date() );
1239 d->ed->repaint( d->ed->rect(), FALSE );
1243 Sets the year to \a year, which must be a valid year. The range
1244 currently supported is from 1752 to 8000.
1246 \sa ExtDate
1249 void ExtDateEdit::setYear( int year )
1251 if ( !outOfRange( year, d->m, d->d ) ) {
1252 d->y = year;
1253 setMonth( d->m );
1259 Sets the month to \a month, which must be a valid month, i.e.
1260 between 1 and 12.
1263 void ExtDateEdit::setMonth( int month )
1265 if ( month < 1 )
1266 month = 1;
1267 if ( month > 12 )
1268 month = 12;
1269 if ( !outOfRange( d->y, month, d->d ) ) {
1270 d->m = month;
1271 setDay( d->d );
1277 Sets the day to \a day, which must be a valid day. The function
1278 will ensure that the \a day set is valid for the month and year.
1281 void ExtDateEdit::setDay( int day )
1283 ExtDate test = ExtDate( d->y, d->m, 1 );
1285 if ( day < 1 )
1286 day = 1;
1287 if ( day > test.daysInMonth() )
1288 day = test.daysInMonth();
1290 d->dayCache = d->d;
1291 d->d = day;
1296 \property ExtDateEdit::date
1297 \brief the editor's date value.
1299 If the date property is not valid, the editor displays all zeroes
1300 and ExtDateEdit::date() will return an invalid date. It is strongly
1301 recommended that the editor is given a default date value (e.g.
1302 currentDate()). That way, attempts to set the date property to an
1303 invalid date will fail.
1305 When changing the date property, if the date is less than
1306 minValue(), or is greater than maxValue(), nothing happens.
1309 void ExtDateEdit::setDate( const ExtDate& date )
1311 if ( !date.isValid() ) {
1312 d->y = 0;
1313 d->m = 0;
1314 d->d = 0;
1315 d->dayCache = 0;
1316 } else {
1317 if ( date > maxValue() || date < minValue() )
1318 return;
1319 d->y = date.year();
1320 d->m = date.month();
1321 d->d = date.day();
1322 d->dayCache = d->d;
1323 emit valueChanged( date );
1325 d->changed = FALSE;
1326 d->ed->repaint( d->ed->rect(), FALSE );
1329 ExtDate ExtDateEdit::date() const
1331 if ( ExtDate::isValid( d->y, d->m, d->d ) )
1332 return ExtDate( d->y, d->m, d->d );
1333 return ExtDate();
1336 /*! \internal
1338 Returns TRUE if \a y, \a m, \a d is out of range, otherwise returns
1339 FALSE.
1341 \sa setRange()
1345 bool ExtDateEdit::outOfRange( int y, int m, int d ) const
1347 if ( ExtDate::isValid( y, m, d ) ) {
1348 ExtDate currentDate( y, m, d );
1349 if ( currentDate > maxValue() || currentDate < minValue() ) {
1350 //## outOfRange should set overwrite?
1351 return TRUE;
1353 return FALSE;
1355 return FALSE; /* assume ok */
1358 /*! \reimp
1362 void ExtDateEdit::addNumber( int sec, int num )
1364 if ( sec == -1 )
1365 return;
1366 killTimer( d->timerId );
1367 bool overwrite = FALSE;
1368 bool accepted = FALSE;
1369 d->typing = TRUE;
1370 QString txt;
1371 if ( sec == d->yearSection ) {
1372 txt = QString::number( d->y );
1373 if ( d->overwrite || txt.length() == 4 ) {
1374 accepted = TRUE;
1375 d->y = num;
1376 } else {
1377 txt += QString::number( num );
1378 if ( txt.length() == 4 ) {
1379 int val = txt.toInt();
1380 if ( val < 1792 )
1381 d->y = 1792;
1382 else if ( val > 8000 )
1383 d->y = 8000;
1384 else if ( outOfRange( val, d->m, d->d ) )
1385 txt = QString::number( d->y );
1386 else {
1387 accepted = TRUE;
1388 d->y = val;
1390 } else {
1391 accepted = TRUE;
1392 d->y = txt.toInt();
1394 if ( d->adv && txt.length() == 4 ) {
1395 d->ed->setFocusSection( d->ed->focusSection()+1 );
1396 overwrite = TRUE;
1399 } else if ( sec == d->monthSection ) {
1400 txt = QString::number( d->m );
1401 if ( d->overwrite || txt.length() == 2 ) {
1402 accepted = TRUE;
1403 d->m = num;
1404 } else {
1405 txt += QString::number( num );
1406 int temp = txt.toInt();
1407 if ( temp > 12 )
1408 temp = num;
1409 if ( outOfRange( d->y, temp, d->d ) )
1410 txt = QString::number( d->m );
1411 else {
1412 accepted = TRUE;
1413 d->m = temp;
1415 if ( d->adv && txt.length() == 2 ) {
1416 d->ed->setFocusSection( d->ed->focusSection()+1 );
1417 overwrite = TRUE;
1420 } else if ( sec == d->daySection ) {
1421 txt = QString::number( d->d );
1422 if ( d->overwrite || txt.length() == 2 ) {
1423 accepted = TRUE;
1424 d->d = num;
1425 d->dayCache = d->d;
1426 } else {
1427 txt += QString::number( num );
1428 int temp = txt.toInt();
1429 if ( temp > 31 )
1430 temp = num;
1431 if ( outOfRange( d->y, d->m, temp ) )
1432 txt = QString::number( d->d );
1433 else {
1434 accepted = TRUE;
1435 d->d = temp;
1436 d->dayCache = d->d;
1438 if ( d->adv && txt.length() == 2 ) {
1439 d->ed->setFocusSection( d->ed->focusSection()+1 );
1440 overwrite = TRUE;
1444 if ( accepted ) {
1445 d->changed = TRUE;
1446 emit valueChanged( date() );
1448 d->overwrite = overwrite;
1449 d->timerId = startTimer( qApp->doubleClickInterval()*4 );
1450 d->ed->repaint( d->ed->rect(), FALSE );
1454 /*! \reimp
1458 bool ExtDateEdit::setFocusSection( int s )
1460 if ( s != d->ed->focusSection() ) {
1461 killTimer( d->timerId );
1462 d->overwrite = TRUE;
1463 d->typing = FALSE;
1464 fix(); // will emit valueChanged if necessary
1466 return d->ed->setFocusSection( s );
1471 Attempts to fix any invalid date entries.
1473 The rules applied are as follows:
1475 \list
1476 \i if the day is larger than the number of days in the month,
1477 \i it is reset to that number
1478 \i If the year has four digits it is left unchanged.
1479 \i If the year has two digits, the year will be changed to four
1480 digits in the range current year - 70 to current year + 29.
1481 \i If the year has three digits in the range 100..999, the
1482 current millennium, i.e. 2000, will be added giving a year
1483 in the range 2100..2999.
1484 \endlist
1488 void ExtDateEdit::fix()
1490 bool changed = FALSE;
1492 ExtDate test = ExtDate( d->y, d->m, 1 );
1493 if ( d->d > test.daysInMonth() ) {
1495 d->d = test.daysInMonth();
1496 changed = TRUE;
1499 int currentYear = ExtDate::currentDate().year();
1500 int year = d->y;
1501 if ( year < 100 ) {
1502 int currentCentury = currentYear / 100;
1503 year += currentCentury * 100;
1504 if ( currentYear > year ) {
1505 if ( currentYear > year + 70 )
1506 year += 100;
1507 } else {
1508 if ( year >= currentYear + 30 )
1509 year -= 100;
1511 changed = TRUE;
1512 } else if ( year < 1000 ) {
1513 int currentMillennium = currentYear / 10;
1514 year += currentMillennium * 10;
1515 changed = TRUE;
1517 if ( changed && outOfRange( year, d->m, d->d ) ) {
1518 if ( minValue().isValid() && date() < minValue() ) {
1519 d->d = minValue().day();
1520 d->dayCache = d->d;
1521 d->m = minValue().month();
1522 d->y = minValue().year();
1524 if ( date() > maxValue() ) {
1525 d->d = maxValue().day();
1526 d->dayCache = d->d;
1527 d->m = maxValue().month();
1528 d->y = maxValue().year();
1530 } else if ( changed )
1531 setYear( year );
1533 if ( changed ) {
1534 // emit valueChanged( date() );
1535 // d->changed = FALSE;
1540 /*! \reimp
1544 bool ExtDateEdit::event( QEvent *e )
1546 if( e->type() == QEvent::FocusOut ) {
1547 d->typing = FALSE;
1548 // the following can't be done in fix() because fix() called
1549 // from all over the place and it will break the old behaviour
1550 if ( !ExtDate::isValid( d->y, d->m, d->d ) ) {
1551 d->dayCache = d->d;
1552 int i = d->d;
1553 for ( ; i > 0; i-- ) {
1554 d->d = i;
1555 if ( ExtDate::isValid( d->y, d->m, d->d ) )
1556 break;
1558 d->changed = TRUE;
1560 if ( d->changed ) {
1561 fix();
1562 emit valueChanged( date() );
1563 d->changed = FALSE;
1565 } else if ( e->type() == QEvent::LocaleChange ) {
1566 readLocaleSettings();
1567 d->ed->setSeparator( localDateSep() );
1568 setOrder( localOrder() );
1571 bool result = ExtDateTimeEditBase::event( e );
1573 return result;
1577 \internal
1579 Function which is called whenever the user tries to
1580 remove the first number from \a sec by pressing the backspace key.
1583 void ExtDateEdit::removeFirstNumber( int sec )
1585 if ( sec == -1 )
1586 return;
1587 QString txt;
1588 if ( sec == d->yearSection ) {
1589 txt = QString::number( d->y );
1590 txt = txt.mid( 1, txt.length() ) + "0";
1591 d->y = txt.toInt();
1592 } else if ( sec == d->monthSection ) {
1593 txt = QString::number( d->m );
1594 txt = txt.mid( 1, txt.length() ) + "0";
1595 d->m = txt.toInt();
1596 } else if ( sec == d->daySection ) {
1597 txt = QString::number( d->d );
1598 txt = txt.mid( 1, txt.length() ) + "0";
1599 d->d = txt.toInt();
1600 d->dayCache = d->d;
1602 d->ed->repaint( d->ed->rect(), FALSE );
1605 /*! \reimp
1609 void ExtDateEdit::removeLastNumber( int sec )
1611 if ( sec == -1 )
1612 return;
1613 QString txt;
1614 if ( sec == d->yearSection ) {
1615 txt = QString::number( d->y );
1616 txt = txt.mid( 0, txt.length()-1 );
1617 d->y = txt.toInt();
1618 } else if ( sec == d->monthSection ) {
1619 txt = QString::number( d->m );
1620 txt = txt.mid( 0, txt.length()-1 );
1621 d->m = txt.toInt();
1622 } else if ( sec == d->daySection ) {
1623 txt = QString::number( d->d );
1624 txt = txt.mid( 0, txt.length()-1 );
1625 d->d = txt.toInt();
1626 d->dayCache = d->d;
1628 d->ed->repaint( d->ed->rect(), FALSE );
1632 \property ExtDateEdit::autoAdvance
1633 \brief whether the editor automatically advances to the next
1634 section
1636 If autoAdvance is TRUE, the editor will automatically advance
1637 focus to the next date section if a user has completed a section.
1638 The default is FALSE.
1641 void ExtDateEdit::setAutoAdvance( bool advance )
1643 d->adv = advance;
1647 bool ExtDateEdit::autoAdvance() const
1649 return d->adv;
1652 /*! \reimp
1655 void ExtDateEdit::timerEvent( QTimerEvent * )
1657 d->overwrite = TRUE;
1661 \fn void ExtDateEdit::valueChanged( const ExtDate& date )
1663 This signal is emitted whenever the editor's value changes. The \a
1664 date parameter is the new value.
1667 ///////////
1669 class QTimeEditPrivate
1671 public:
1672 int h;
1673 int m;
1674 int s;
1675 uint display;
1676 bool adv;
1677 bool overwrite;
1678 int timerId;
1679 bool typing;
1680 QTime min;
1681 QTime max;
1682 bool changed;
1683 ExtDateTimeEditor *ed;
1684 QSpinWidget *controls;
1688 \class QTimeEdit ExtDatetimeedit.h
1689 \brief The QTimeEdit class provides a time editor.
1691 \ingroup advanced
1692 \ingroup time
1693 \mainclass
1695 QTimeEdit allows the user to edit times by using the keyboard or
1696 the arrow keys to increase/decrease time values. The arrow keys
1697 can be used to move from section to section within the QTimeEdit
1698 box. The user can automatically be moved to the next section once
1699 they complete a section using setAutoAdvance(). Times appear in
1700 hour, minute, second order. It is recommended that the QTimeEdit
1701 is initialised with a time, e.g.
1702 \code
1703 QTime timeNow = QTime::currentTime();
1704 QTimeEdit *timeEdit = new QTimeEdit( timeNow, this );
1705 timeEdit->setRange( timeNow, timeNow.addSecs( 60 * 60 ) );
1706 \endcode
1707 Here we've created a QTimeEdit widget set to the current time.
1708 We've also set the minimum value to the current time and the
1709 maximum time to one hour from now.
1711 The maximum and minimum values for a time value in the time editor
1712 default to the maximum and minimum values for a QTime. You can
1713 change this by calling setMinValue(), setMaxValue() or setRange().
1715 Terminology: A QTimeWidget consists of three sections, one each
1716 for the hour, minute and second. You can change the separator
1717 character using setSeparator(), by default the separator is read
1718 from the system's settings.
1720 \img datetimewidgets.png Date Time Widgets
1722 \sa QTime ExtDateEdit ExtDateTimeEdit
1726 // /*!
1727 // Constructs an empty time edit with parent \a parent and called \a
1728 // name.
1729 // */
1731 // QTimeEdit::QTimeEdit( QWidget * parent, const char * name )
1732 // : ExtDateTimeEditBase( parent, name )
1733 // {
1734 // init();
1735 // }
1737 // /*!
1738 // \overload
1740 // Constructs a time edit with the initial time value, \a time,
1741 // parent \a parent and called \a name.
1742 // */
1744 // QTimeEdit::QTimeEdit( const QTime& time, QWidget * parent, const char * name )
1745 // : ExtDateTimeEditBase( parent, name )
1746 // {
1747 // init();
1748 // setTime( time );
1749 // }
1751 // /*! \internal
1752 // */
1754 // void QTimeEdit::init()
1755 // {
1756 // d = new QTimeEditPrivate();
1757 // d->ed = new ExtDateTimeEditor( this, "time edit base" );
1758 // d->controls = new ExtDateTimeSpinWidget( this, qstrcmp( name(), "qt_datetime_timeedit" ) == 0 ? "qt_spin_widget" : "time edit controls" );
1759 // d->controls->setEditWidget( d->ed );
1760 // setFocusProxy( d->ed );
1761 // connect( d->controls, SIGNAL( stepUpPressed() ), SLOT( stepUp() ) );
1762 // connect( d->controls, SIGNAL( stepDownPressed() ), SLOT( stepDown() ) );
1764 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 0 ) );
1765 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 1 ) );
1766 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 2 ) );
1767 // d->ed->setSeparator( localTimeSep() );
1769 // d->h = 0;
1770 // d->m = 0;
1771 // d->s = 0;
1772 // d->display = Hours | Minutes | Seconds;
1773 // if ( lAMPM ) {
1774 // d->display |= AMPM;
1775 // d->ed->appendSection( QNumberSection( 0,0, FALSE, 3 ) );
1776 // }
1777 // d->adv = FALSE;
1778 // d->overwrite = TRUE;
1779 // d->timerId = 0;
1780 // d->typing = FALSE;
1781 // d->min = QTime( 0, 0, 0 );
1782 // d->max = QTime( 23, 59, 59 );
1783 // d->changed = FALSE;
1785 // setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
1787 // refcount++;
1788 // }
1790 // /*!
1791 // Destroys the object and frees any allocated resources.
1792 // */
1794 // QTimeEdit::~QTimeEdit()
1795 // {
1796 // delete d;
1797 // if ( !--refcount )
1798 // cleanup();
1799 // }
1801 // /*!
1802 // \property QTimeEdit::minValue
1803 // \brief the minimum time value
1805 // Setting the minimum time value is equivalent to calling
1806 // QTimeEdit::setRange( \e t, maxValue() ), where \e t is the minimum
1807 // time. The default minimum time is 00:00:00.
1809 // \sa maxValue setRange()
1810 // */
1812 // QTime QTimeEdit::minValue() const
1813 // {
1814 // return d->min;
1815 // }
1817 // /*!
1818 // \property QTimeEdit::maxValue
1819 // \brief the maximum time value
1821 // Setting the maximum time value is equivalent to calling
1822 // QTimeEdit::setRange( minValue(), \e t ), where \e t is the maximum
1823 // time. The default maximum time is 23:59:59.
1825 // \sa minValue setRange()
1826 // */
1828 // QTime QTimeEdit::maxValue() const
1829 // {
1830 // return d->max;
1831 // }
1834 // /*!
1835 // Sets the valid input range for the editor to be from \a min to \a
1836 // max inclusive. If \a min is invalid no minimum time is set.
1837 // Similarly, if \a max is invalid no maximum time is set.
1838 // */
1840 // void QTimeEdit::setRange( const QTime& min, const QTime& max )
1841 // {
1842 // if ( min.isValid() )
1843 // d->min = min;
1844 // if ( max.isValid() )
1845 // d->max = max;
1846 // }
1848 // /*!
1849 // \property QTimeEdit::display
1850 // \brief the sections that are displayed in the time edit
1852 // The value can be any combination of the values in the Display enum.
1853 // By default, the widget displays hours, minutes and seconds.
1854 // */
1855 // void QTimeEdit::setDisplay( uint display )
1856 // {
1857 // if ( d->display == display )
1858 // return;
1860 // d->ed->clearSections();
1861 // d->display = display;
1862 // if ( d->display & Hours )
1863 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 0 ) );
1864 // if ( d->display & Minutes )
1865 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 1 ) );
1866 // if ( d->display & Seconds )
1867 // d->ed->appendSection( QNumberSection( 0,0, TRUE, 2 ) );
1868 // if ( d->display & AMPM )
1869 // d->ed->appendSection( QNumberSection( 0,0, FALSE, 3 ) );
1871 // d->ed->setFocusSection( 0 );
1872 // d->ed->update();
1873 // }
1875 // uint QTimeEdit::display() const
1876 // {
1877 // return d->display;
1878 // }
1880 // /*!
1881 // \property QTimeEdit::time
1882 // \brief the editor's time value.
1884 // When changing the time property, if the time is less than
1885 // minValue(), or is greater than maxValue(), nothing happens.
1886 // */
1888 // void QTimeEdit::setTime( const QTime& time )
1889 // {
1890 // if ( !time.isValid() ) {
1891 // d->h = 0;
1892 // d->m = 0;
1893 // d->s = 0;
1894 // } else {
1895 // if ( time > maxValue() || time < minValue() )
1896 // return;
1897 // d->h = time.hour();
1898 // d->m = time.minute();
1899 // d->s = time.second();
1900 // emit valueChanged( time );
1901 // }
1902 // d->changed = FALSE;
1903 // d->ed->repaint( d->ed->rect(), FALSE );
1904 // }
1906 // QTime QTimeEdit::time() const
1907 // {
1908 // if ( QTime::isValid( d->h, d->m, d->s ) )
1909 // return QTime( d->h, d->m, d->s );
1910 // return QTime();
1911 // }
1913 // /*!
1914 // \property QTimeEdit::autoAdvance
1915 // \brief whether the editor automatically advances to the next
1916 // section
1918 // If autoAdvance is TRUE, the editor will automatically advance
1919 // focus to the next time section if a user has completed a section.
1920 // The default is FALSE.
1921 // */
1923 // void QTimeEdit::setAutoAdvance( bool advance )
1924 // {
1925 // d->adv = advance;
1926 // }
1928 // bool QTimeEdit::autoAdvance() const
1929 // {
1930 // return d->adv;
1931 // }
1933 // /*!
1934 // Sets the separator to \a s. Note that currently only the first
1935 // character of \a s is used.
1936 // */
1938 // void QTimeEdit::setSeparator( const QString& s )
1939 // {
1940 // d->ed->setSeparator( s );
1941 // }
1943 // /*!
1944 // Returns the editor's separator.
1945 // */
1947 // QString QTimeEdit::separator() const
1948 // {
1949 // return d->ed->separator();
1950 // }
1953 // /*!
1954 // \fn void QTimeEdit::valueChanged( const QTime& time )
1956 // This signal is emitted whenever the editor's value changes. The \a
1957 // time parameter is the new value.
1958 // */
1960 // /*! \reimp
1962 // */
1964 // bool QTimeEdit::event( QEvent *e )
1965 // {
1966 // if ( e->type() == QEvent::FocusOut ) {
1967 // d->typing = FALSE;
1968 // if ( d->changed ) {
1969 // emit valueChanged( time() );
1970 // d->changed = FALSE;
1971 // }
1972 // } else if ( e->type() == QEvent::LocaleChange ) {
1973 // readLocaleSettings();
1974 // d->ed->setSeparator( localTimeSep() );
1975 // }
1976 // return ExtDateTimeEditBase::event( e );
1977 // }
1979 // /*! \reimp
1981 // */
1983 // void QTimeEdit::timerEvent( QTimerEvent * )
1984 // {
1985 // d->overwrite = TRUE;
1986 // }
1989 // /*! \reimp
1991 // */
1993 // void QTimeEdit::stepUp()
1994 // {
1995 // int sec = d->ed->mapSection( d->ed->focusSection() );
1996 // bool accepted = TRUE;
1997 // switch( sec ) {
1998 // case 0:
1999 // if ( !outOfRange( d->h+1, d->m, d->s ) )
2000 // setHour( d->h+1 );
2001 // else
2002 // setHour( d->min.hour() );
2003 // break;
2004 // case 1:
2005 // if ( !outOfRange( d->h, d->m+1, d->s ) )
2006 // setMinute( d->m+1 );
2007 // else
2008 // setMinute( d->min.minute() );
2009 // break;
2010 // case 2:
2011 // if ( !outOfRange( d->h, d->m, d->s+1 ) )
2012 // setSecond( d->s+1 );
2013 // else
2014 // setSecond( d->min.second() );
2015 // break;
2016 // case 3:
2017 // if ( d->h < 12 )
2018 // setHour( d->h+12 );
2019 // else
2020 // setHour( d->h-12 );
2021 // break;
2022 // default:
2023 // accepted = FALSE;
2024 // #ifdef QT_CHECK_RANGE
2025 // qWarning( "QTimeEdit::stepUp: Focus section out of range!" );
2026 // #endif
2027 // break;
2028 // }
2029 // if ( accepted ) {
2030 // d->changed = TRUE;
2031 // emit valueChanged( time() );
2032 // }
2033 // d->ed->repaint( d->ed->rect(), FALSE );
2034 // }
2037 // /*! \reimp
2039 // */
2041 // void QTimeEdit::stepDown()
2042 // {
2043 // int sec = d->ed->mapSection( d->ed->focusSection() );
2045 // bool accepted = TRUE;
2046 // switch( sec ) {
2047 // case 0:
2048 // if ( !outOfRange( d->h-1, d->m, d->s ) )
2049 // setHour( d->h-1 );
2050 // else
2051 // setHour( d->max.hour() );
2052 // break;
2053 // case 1:
2054 // if ( !outOfRange( d->h, d->m-1, d->s ) )
2055 // setMinute( d->m-1 );
2056 // else
2057 // setMinute( d->max.minute() );
2058 // break;
2059 // case 2:
2060 // if ( !outOfRange( d->h, d->m, d->s-1 ) )
2061 // setSecond( d->s-1 );
2062 // else
2063 // setSecond( d->max.second() );
2064 // break;
2065 // case 3:
2066 // if ( d->h > 11 )
2067 // setHour( d->h-12 );
2068 // else
2069 // setHour( d->h+12 );
2070 // break;
2071 // default:
2072 // accepted = FALSE;
2073 // #ifdef QT_CHECK_RANGE
2074 // qWarning( "QTimeEdit::stepDown: Focus section out of range!" );
2075 // #endif
2076 // break;
2077 // }
2078 // if ( accepted ) {
2079 // d->changed = TRUE;
2080 // emit valueChanged( time() );
2081 // }
2082 // d->ed->repaint( d->ed->rect(), FALSE );
2083 // }
2086 // /*!
2087 // Returns the formatted number for section \a sec. This will
2088 // correspond to either the hour, minute or second section, depending
2089 // on \a sec.
2090 // */
2092 // QString QTimeEdit::sectionFormattedText( int sec )
2093 // {
2094 // QString txt;
2095 // txt = sectionText( sec );
2096 // txt = txt.rightJustify( 2, EXTDATETIMEEDIT_HIDDEN_CHAR );
2097 // int offset = sec*2+sec*separator().length() + txt.length();
2098 // if ( d->typing && sec == d->ed->focusSection() )
2099 // d->ed->setSectionSelection( sec, offset - txt.length(), offset );
2100 // else
2101 // d->ed->setSectionSelection( sec, offset - txt.length(), offset );
2103 // return txt;
2104 // }
2107 // /*! \reimp
2109 // */
2111 // bool QTimeEdit::setFocusSection( int sec )
2112 // {
2113 // if ( sec != d->ed->focusSection() ) {
2114 // killTimer( d->timerId );
2115 // d->overwrite = TRUE;
2116 // d->typing = FALSE;
2117 // QString txt = sectionText( sec );
2118 // txt = txt.rightJustify( 2, EXTDATETIMEEDIT_HIDDEN_CHAR );
2119 // int offset = sec*2+sec*separator().length() + txt.length();
2120 // d->ed->setSectionSelection( sec, offset - txt.length(), offset );
2121 // if ( d->changed ) {
2122 // emit valueChanged( time() );
2123 // d->changed = FALSE;
2124 // }
2125 // }
2126 // return d->ed->setFocusSection( sec );
2127 // }
2130 // /*!
2131 // Sets the hour to \a h, which must be a valid hour, i.e. in the
2132 // range 0..24.
2133 // */
2135 // void QTimeEdit::setHour( int h )
2136 // {
2137 // if ( h < 0 )
2138 // h = 0;
2139 // if ( h > 23 )
2140 // h = 23;
2141 // d->h = h;
2142 // }
2145 // /*!
2146 // Sets the minute to \a m, which must be a valid minute, i.e. in the
2147 // range 0..59.
2148 // */
2150 // void QTimeEdit::setMinute( int m )
2151 // {
2152 // if ( m < 0 )
2153 // m = 0;
2154 // if ( m > 59 )
2155 // m = 59;
2156 // d->m = m;
2157 // }
2160 // /*!
2161 // Sets the second to \a s, which must be a valid second, i.e. in the
2162 // range 0..59.
2163 // */
2165 // void QTimeEdit::setSecond( int s )
2166 // {
2167 // if ( s < 0 )
2168 // s = 0;
2169 // if ( s > 59 )
2170 // s = 59;
2171 // d->s = s;
2172 // }
2175 // /*! \internal
2177 // Returns the text of section \a sec.
2179 // */
2181 // QString QTimeEdit::sectionText( int sec )
2182 // {
2183 // sec = d->ed->mapSection( sec );
2185 // QString txt;
2186 // switch( sec ) {
2187 // case 0:
2188 // if ( !(d->display & AMPM) || ( d->h < 13 && d->h ) ) { // I wished the day stared at 0:00 for everybody
2189 // txt = QString::number( d->h );
2190 // } else {
2191 // if ( d->h )
2192 // txt = QString::number( d->h - 12 );
2193 // else
2194 // txt = "12";
2195 // }
2196 // break;
2197 // case 1:
2198 // txt = QString::number( d->m );
2199 // break;
2200 // case 2:
2201 // txt = QString::number( d->s );
2202 // break;
2203 // case 3:
2204 // if ( d->h < 12 ) {
2205 // if ( lAM )
2206 // txt = *lAM;
2207 // else
2208 // txt = QString::fromLatin1( "AM" );
2209 // } else {
2210 // if ( lPM )
2211 // txt = *lPM;
2212 // else
2213 // txt = QString::fromLatin1( "PM" );
2214 // }
2215 // break;
2216 // default:
2217 // break;
2218 // }
2219 // return txt;
2220 // }
2223 // /*! \internal
2224 // Returns TRUE if \a h, \a m, and \a s are out of range.
2225 // */
2227 // bool QTimeEdit::outOfRange( int h, int m, int s ) const
2228 // {
2229 // if ( QTime::isValid( h, m, s ) ) {
2230 // QTime currentTime( h, m, s );
2231 // if ( currentTime > maxValue() ||
2232 // currentTime < minValue() )
2233 // return TRUE;
2234 // else
2235 // return FALSE;
2236 // }
2237 // return TRUE;
2238 // }
2240 // /*! \reimp
2242 // */
2244 // void QTimeEdit::addNumber( int sec, int num )
2245 // {
2246 // if ( sec == -1 )
2247 // return;
2248 // sec = d->ed->mapSection( sec );
2249 // killTimer( d->timerId );
2250 // bool overwrite = FALSE;
2251 // bool accepted = FALSE;
2252 // d->typing = TRUE;
2253 // QString txt;
2255 // switch( sec ) {
2256 // case 0:
2257 // txt = ( d->display & AMPM && d->h > 12 ) ?
2258 // QString::number( d->h - 12 ) : QString::number( d->h );
2260 // if ( d->overwrite || txt.length() == 2 ) {
2261 // if ( d->display & AMPM && num == 0 )
2262 // break; // Don't process 0 in 12 hour clock mode
2263 // if ( d->display & AMPM && d->h > 11 )
2264 // num += 12;
2265 // if ( !outOfRange( num, d->m, d->s ) ) {
2266 // accepted = TRUE;
2267 // d->h = num;
2268 // }
2269 // } else {
2270 // txt += QString::number( num );
2271 // int temp = txt.toInt();
2273 // if ( d->display & AMPM ) {
2274 // if ( temp == 12 ) {
2275 // if ( d->h < 12 ) {
2276 // temp = 0;
2277 // }
2278 // accepted = TRUE;
2279 // } else if ( outOfRange( temp + 12, d->m, d->s ) ) {
2280 // txt = QString::number( d->h );
2281 // } else {
2282 // if ( d->h > 11 ) {
2283 // temp += 12;
2284 // }
2285 // accepted = TRUE;
2286 // }
2287 // } else if ( !(d->display & AMPM) && outOfRange( temp, d->m, d->s ) ) {
2288 // txt = QString::number( d->h );
2289 // } else {
2290 // accepted = TRUE;
2291 // }
2293 // if ( accepted )
2294 // d->h = temp;
2296 // if ( d->adv && txt.length() == 2 ) {
2297 // setFocusSection( d->ed->focusSection()+1 );
2298 // overwrite = TRUE;
2299 // }
2300 // }
2301 // break;
2303 // case 1:
2304 // txt = QString::number( d->m );
2305 // if ( d->overwrite || txt.length() == 2 ) {
2306 // if ( !outOfRange( d->h, num, d->s ) ) {
2307 // accepted = TRUE;
2308 // d->m = num;
2309 // }
2310 // } else {
2311 // txt += QString::number( num );
2312 // int temp = txt.toInt();
2313 // if ( temp > 59 )
2314 // temp = num;
2315 // if ( outOfRange( d->h, temp, d->s ) )
2316 // txt = QString::number( d->m );
2317 // else {
2318 // accepted = TRUE;
2319 // d->m = temp;
2320 // }
2321 // if ( d->adv && txt.length() == 2 ) {
2322 // setFocusSection( d->ed->focusSection()+1 );
2323 // overwrite = TRUE;
2324 // }
2325 // }
2326 // break;
2328 // case 2:
2329 // txt = QString::number( d->s );
2330 // if ( d->overwrite || txt.length() == 2 ) {
2331 // if ( !outOfRange( d->h, d->m, num ) ) {
2332 // accepted = TRUE;
2333 // d->s = num;
2334 // }
2335 // } else {
2336 // txt += QString::number( num );
2337 // int temp = txt.toInt();
2338 // if ( temp > 59 )
2339 // temp = num;
2340 // if ( outOfRange( d->h, d->m, temp ) )
2341 // txt = QString::number( d->s );
2342 // else {
2343 // accepted = TRUE;
2344 // d->s = temp;
2345 // }
2346 // if ( d->adv && txt.length() == 2 ) {
2347 // setFocusSection( d->ed->focusSection()+1 );
2348 // overwrite = TRUE;
2349 // }
2350 // }
2351 // break;
2353 // case 3:
2354 // break;
2356 // default:
2357 // break;
2358 // }
2359 // d->changed = accepted;
2360 // if ( accepted )
2361 // emit valueChanged( time() );
2362 // d->overwrite = overwrite;
2363 // d->timerId = startTimer( qApp->doubleClickInterval()*4 );
2364 // d->ed->repaint( d->ed->rect(), FALSE );
2365 // }
2368 // /*!
2369 // \internal
2371 // Function which is called whenever the user tries to
2372 // remove the first number from \a sec by pressing the backspace key.
2373 // */
2375 // void QTimeEdit::removeFirstNumber( int sec )
2376 // {
2377 // if ( sec == -1 )
2378 // return;
2379 // sec = d->ed->mapSection( sec );
2380 // QString txt;
2381 // switch( sec ) {
2382 // case 0:
2383 // txt = QString::number( d->h );
2384 // break;
2385 // case 1:
2386 // txt = QString::number( d->m );
2387 // break;
2388 // case 2:
2389 // txt = QString::number( d->s );
2390 // break;
2391 // }
2392 // txt = txt.mid( 1, txt.length() ) + "0";
2393 // switch( sec ) {
2394 // case 0:
2395 // d->h = txt.toInt();
2396 // break;
2397 // case 1:
2398 // d->m = txt.toInt();
2399 // break;
2400 // case 2:
2401 // d->s = txt.toInt();
2402 // break;
2403 // }
2404 // d->ed->repaint( d->ed->rect(), FALSE );
2405 // }
2407 // /*! \reimp
2409 // */
2410 // void QTimeEdit::removeLastNumber( int sec )
2411 // {
2412 // if ( sec == -1 )
2413 // return;
2414 // sec = d->ed->mapSection( sec );
2415 // QString txt;
2416 // switch( sec ) {
2417 // case 0:
2418 // txt = QString::number( d->h );
2419 // break;
2420 // case 1:
2421 // txt = QString::number( d->m );
2422 // break;
2423 // case 2:
2424 // txt = QString::number( d->s );
2425 // break;
2426 // }
2427 // txt = txt.mid( 0, txt.length()-1 );
2428 // switch( sec ) {
2429 // case 0:
2430 // d->h = txt.toInt();
2431 // break;
2432 // case 1:
2433 // d->m = txt.toInt();
2434 // break;
2435 // case 2:
2436 // d->s = txt.toInt();
2437 // break;
2438 // }
2439 // d->ed->repaint( d->ed->rect(), FALSE );
2440 // }
2442 // /*! \reimp
2443 // */
2444 // void QTimeEdit::resizeEvent( QResizeEvent * )
2445 // {
2446 // d->controls->resize( width(), height() );
2447 // }
2449 // /*! \reimp
2450 // */
2451 // QSize QTimeEdit::sizeHint() const
2452 // {
2453 // constPolish();
2454 // QFontMetrics fm( font() );
2455 // int fw = style().pixelMetric( QStyle::PM_DefaultFrameWidth, this );
2456 // int h = fm.lineSpacing() + 2;
2457 // int w = 2 + fm.width( '9' ) * 6 + fm.width( d->ed->separator() ) * 2 +
2458 // d->controls->upRect().width() + fw * 4;
2459 // if ( d->display & AMPM ) {
2460 // if ( lAM )
2461 // w += fm.width( *lAM ) + 4;
2462 // else
2463 // w += fm.width( QString::fromLatin1( "AM" ) ) + 4;
2464 // }
2466 // return QSize( w, QMAX(h + fw * 2,20) ).expandedTo( QApplication::globalStrut() );
2467 // }
2469 // /*! \reimp
2470 // */
2471 // QSize QTimeEdit::minimumSizeHint() const
2472 // {
2473 // return sizeHint();
2474 // }
2476 // /*!
2477 // \internal
2478 // Enables/disables the push buttons according to the min/max time
2479 // for this widget.
2480 // */
2482 // // ### Remove in 4.0?
2484 // void QTimeEdit::updateButtons()
2485 // {
2486 // if ( !isEnabled() )
2487 // return;
2489 // bool upEnabled = time() < maxValue();
2490 // bool downEnabled = time() > minValue();
2492 // d->controls->setUpEnabled( upEnabled );
2493 // d->controls->setDownEnabled( downEnabled );
2494 // }
2497 class ExtDateTimeEditPrivate
2499 public:
2500 bool adv;
2504 \class ExtDateTimeEdit ExtDatetimeedit.h
2505 \brief The ExtDateTimeEdit class combines a ExtDateEdit and QTimeEdit
2506 widget into a single widget for editing datetimes.
2508 \ingroup advanced
2509 \ingroup time
2510 \mainclass
2512 ExtDateTimeEdit consists of a ExtDateEdit and QTimeEdit widget placed
2513 side by side and offers the functionality of both. The user can
2514 edit the date and time by using the keyboard or the arrow keys to
2515 increase/decrease date or time values. The Tab key can be used to
2516 move from section to section within the ExtDateTimeEdit widget, and
2517 the user can be moved automatically when they complete a section
2518 using setAutoAdvance(). The datetime can be set with
2519 setDateTime().
2521 The date format is read from the system's locale settings. It is
2522 set to year, month, day order if that is not possible. See
2523 ExtDateEdit::setOrder() to change this. Times appear in the order
2524 hours, minutes, seconds using the 24 hour clock.
2526 It is recommended that the ExtDateTimeEdit is initialised with a
2527 datetime, e.g.
2528 \code
2529 ExtDateTimeEdit *dateTimeEdit = new ExtDateTimeEdit( ExtDateTime::currentDateTime(), this );
2530 dateTimeEdit->dateEdit()->setRange( ExtDateTime::currentDate(),
2531 ExtDateTime::currentDate().addDays( 7 ) );
2532 \endcode
2533 Here we've created a new ExtDateTimeEdit set to the current date and
2534 time, and set the date to have a minimum date of now and a maximum
2535 date of a week from now.
2537 Terminology: A ExtDateEdit widget consists of three 'sections', one
2538 each for the year, month and day. Similarly a QTimeEdit consists
2539 of three sections, one each for the hour, minute and second. The
2540 character that separates each date section is specified with
2541 setDateSeparator(); similarly setTimeSeparator() is used for the
2542 time sections.
2544 \img datetimewidgets.png Date Time Widgets
2546 \sa ExtDateEdit QTimeEdit
2550 Constructs an empty datetime edit with parent \a parent and called
2551 \a name.
2553 ExtDateTimeEdit::ExtDateTimeEdit( QWidget * parent, const char * name )
2554 : QWidget( parent, name )
2556 init();
2561 \overload
2563 Constructs a datetime edit with the initial value \a datetime,
2564 parent \a parent and called \a name.
2566 ExtDateTimeEdit::ExtDateTimeEdit( const ExtDateTime& datetime,
2567 QWidget * parent, const char * name )
2568 : QWidget( parent, name )
2570 init();
2571 setDateTime( datetime );
2577 Destroys the object and frees any allocated resources.
2580 ExtDateTimeEdit::~ExtDateTimeEdit()
2582 delete d;
2587 \reimp
2589 Intercepts and handles resize events which have special meaning
2590 for the ExtDateTimeEdit.
2593 void ExtDateTimeEdit::resizeEvent( QResizeEvent * )
2595 int dw = de->sizeHint().width();
2596 int tw = te->sizeHint().width();
2597 int w = width();
2598 int h = height();
2599 int extra = w - ( dw + tw );
2601 if ( tw + extra < 0 ) {
2602 dw = w;
2603 } else {
2604 dw += 9 * extra / 16;
2606 tw = w - dw;
2608 de->setGeometry( 0, 0, dw, h );
2609 te->setGeometry( dw, 0, tw, h );
2612 /*! \reimp
2615 QSize ExtDateTimeEdit::minimumSizeHint() const
2617 QSize dsh = de->minimumSizeHint();
2618 QSize tsh = te->minimumSizeHint();
2619 return QSize( dsh.width() + tsh.width(),
2620 QMAX( dsh.height(), tsh.height() ) );
2623 /*! \internal
2626 void ExtDateTimeEdit::init()
2628 d = new ExtDateTimeEditPrivate();
2629 de = new ExtDateEdit( this, "qt_datetime_dateedit" );
2630 te = new QTimeEdit( this, "qt_datetime_timeedit" );
2631 d->adv = FALSE;
2632 connect( de, SIGNAL( valueChanged( const ExtDate& ) ),
2633 this, SLOT( newValue( const ExtDate& ) ) );
2634 connect( te, SIGNAL( valueChanged( const QTime& ) ),
2635 this, SLOT( newValue( const QTime& ) ) );
2636 setFocusProxy( de );
2637 setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
2640 /*! \reimp
2643 QSize ExtDateTimeEdit::sizeHint() const
2645 constPolish();
2646 QSize dsh = de->sizeHint();
2647 QSize tsh = te->sizeHint();
2648 return QSize( dsh.width() + tsh.width(),
2649 QMAX( dsh.height(), tsh.height() ) );
2653 \property ExtDateTimeEdit::dateTime
2654 \brief the editor's datetime value
2656 The datetime edit's datetime which may be an invalid datetime.
2659 void ExtDateTimeEdit::setDateTime( const ExtDateTime & dt )
2661 if ( dt.isValid() ) {
2662 de->setDate( dt.date() );
2663 te->setTime( dt.time() );
2664 emit valueChanged( dt );
2668 ExtDateTime ExtDateTimeEdit::dateTime() const
2670 return ExtDateTime( de->date(), te->time() );
2674 \fn void ExtDateTimeEdit::valueChanged( const ExtDateTime& datetime )
2676 This signal is emitted every time the date or time changes. The \a
2677 datetime argument is the new datetime.
2681 /*! \internal
2683 Re-emits the value \a d.
2686 void ExtDateTimeEdit::newValue( const ExtDate& )
2688 ExtDateTime dt = dateTime();
2689 emit valueChanged( dt );
2692 /*! \internal
2693 \overload
2694 Re-emits the value \a t.
2697 void ExtDateTimeEdit::newValue( const QTime& )
2699 ExtDateTime dt = dateTime();
2700 emit valueChanged( dt );
2705 Sets the auto advance property of the editor to \a advance. If set
2706 to TRUE, the editor will automatically advance focus to the next
2707 date or time section if the user has completed a section.
2710 void ExtDateTimeEdit::setAutoAdvance( bool advance )
2712 de->setAutoAdvance( advance );
2713 te->setAutoAdvance( advance );
2717 Returns TRUE if auto-advance is enabled, otherwise returns FALSE.
2719 \sa setAutoAdvance()
2722 bool ExtDateTimeEdit::autoAdvance() const
2724 return de->autoAdvance();
2728 \fn ExtDateEdit* ExtDateTimeEdit::dateEdit()
2730 Returns the internal widget used for editing the date part of the
2731 datetime.
2735 \fn QTimeEdit* ExtDateTimeEdit::timeEdit()
2737 Returns the internal widget used for editing the time part of the
2738 datetime.
2741 #include "extdatetimeedit.moc"
2743 #endif