diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:17:53 -0500 | 
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:17:53 -0500 | 
| commit | dda8474928bd7276e1fad8fb7a601e7c83ff2bc2 (patch) | |
| tree | 7f83910598b33b12730035f086df20b5a53ab99c /tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp | |
| parent | 6260b6178868c03aab1644bf93b0ef043654bdb0 (diff) | |
| download | experimental-dda8474928bd7276e1fad8fb7a601e7c83ff2bc2.tar.gz experimental-dda8474928bd7276e1fad8fb7a601e7c83ff2bc2.zip | |
Added TQt4 HEAD
Diffstat (limited to 'tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp')
| -rw-r--r-- | tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp | 2845 | 
1 files changed, 2845 insertions, 0 deletions
| diff --git a/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp b/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp new file mode 100644 index 0000000..4aaea53 --- /dev/null +++ b/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp @@ -0,0 +1,2845 @@ +/**************************************************************************** +** +** Implementation of date and time edit classes +** +** Created : 001103 +** +** Copyright (C) 2000-2008 Trolltech ASA.  All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file.  Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqdatetimeedit.h" + +#ifndef TQT_NO_DATETIMEEDIT + +#include "../kernel/tqinternal_p.h" +#include "../kernel/tqrichtext_p.h" +#include "tqrangecontrol.h" +#include "tqapplication.h" +#include "tqpixmap.h" +#include "tqapplication.h" +#include "tqvaluelist.h" +#include "tqstring.h" +#include "tqstyle.h" + +#if defined(TQ_WS_WIN) +#include "tqt_windows.h" +#endif + +#define TQDATETIMEEDIT_HIDDEN_CHAR '0' + +class TQ_EXPORT TQNumberSection +{ +public: +    TQNumberSection( int selStart = 0, int selEnd = 0, bool separat = TRUE, int actual = -1 ) +	: selstart( selStart ), selend( selEnd ), act( actual ), sep( separat ) +    {} +    int selectionStart() const { return selstart; } +    void setSelectionStart( int s ) { selstart = s; } +    int selectionEnd() const { return selend; } +    void setSelectionEnd( int s ) { selend = s; } +    int width() const { return selend - selstart; } +    int index() const { return act; } +    bool separator() const { return sep; } +    TQ_DUMMY_COMPARISON_OPERATOR( TQNumberSection ) +private: +    int selstart :12; +    int selend	 :12; +    int act	 :7; +    bool sep	 :1; +}; + +static TQString	*lDateSep = 0; +static TQString	*lTimeSep = 0; +static bool	lAMPM	  = FALSE; +static TQString	*lAM	  = 0; +static TQString	*lPM	  = 0; +static TQDateEdit::Order	lOrder = TQDateEdit::YMD; +static int refcount = 0; + +static void cleanup() +{ +    delete lDateSep; +    lDateSep = 0; +    delete lTimeSep; +    lTimeSep = 0; +    delete lAM; +    lAM = 0; +    delete lPM; +    lPM = 0; +} + +/*! +\internal +try to get the order of DMY and the date/time separator from the locale settings +*/ +static void readLocaleSettings() +{ +    int dpos, mpos, ypos; +    cleanup(); + +    lDateSep = new TQString(); +    lTimeSep = new TQString(); + +#if defined(TQ_WS_WIN) +    TQT_WA( { +	TCHAR data[10]; +	GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10 ); +	*lDateSep = TQString::fromUcs2( (ushort*)data ); +	GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10 ); +	*lTimeSep = TQString::fromUcs2( (ushort*)data ); +	GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10 ); +	lAMPM = TQString::fromUcs2( (ushort*)data ).toInt()==0; +	GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10 ); +	TQString am = TQString::fromUcs2( (ushort*)data ); +	if ( !am.isEmpty() ) +	    lAM = new TQString( am ); +	GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10 ); +	TQString pm = TQString::fromUcs2( (ushort*)data ); +	if ( !pm.isEmpty()  ) +	    lPM = new TQString( pm ); +    } , { +	char data[10]; +	GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10 ); +	*lDateSep = TQString::fromLocal8Bit( data ); +	GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10 ); +	*lTimeSep = TQString::fromLocal8Bit( data ); +	GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10 ); +	lAMPM = TQString::fromLocal8Bit( data ).toInt()==0; +	GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10 ); +	TQString am = TQString::fromLocal8Bit( data ); +	if ( !am.isEmpty() ) +	    lAM = new TQString( am ); +	GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10 ); +	TQString pm = TQString::fromLocal8Bit( data ); +	if ( !pm.isEmpty() ) +	    lPM = new TQString( pm ); +    } ); +#else +    *lDateSep = "-"; +    *lTimeSep = ":"; +#endif +    TQString d = TQDate( 1999, 11, 22 ).toString( Qt::LocalDate ); +    dpos = d.tqfind( "22" ); +    mpos = d.tqfind( "11" ); +    ypos = d.tqfind( "99" ); +    if ( dpos > -1 && mpos > -1 && ypos > -1 ) { +	// test for DMY, MDY, YMD, YDM +	if ( dpos < mpos && mpos < ypos ) { +	    lOrder = TQDateEdit::DMY; +	} else if ( mpos < dpos && dpos < ypos ) { +	    lOrder = TQDateEdit::MDY; +	} else if ( ypos < mpos && mpos < dpos ) { +	    lOrder = TQDateEdit::YMD; +	} else if ( ypos < dpos && dpos < mpos ) { +	    lOrder = TQDateEdit::YDM; +	} else { +	    // cannot determine the dateformat - use the default +	    return; +	} + +	// this code needs to change if new formats are added + +#ifndef TQ_WS_WIN +	TQString sep = d.mid( TQMIN( dpos, mpos ) + 2, TQABS( dpos - mpos ) - 2 ); +	if ( d.tqcontains( sep ) == 2 ) { +	    *lDateSep = sep; +	} +#endif +    } + +#ifndef TQ_WS_WIN +    TQString t = TQTime( 11, 22, 33 ).toString( Qt::LocalDate ); +    dpos = t.tqfind( "11" ); +    mpos = t.tqfind( "22" ); +    ypos = t.tqfind( "33" ); +    // We only allow hhmmss +    if ( dpos > -1 && dpos < mpos && mpos < ypos ) { +	TQString sep = t.mid( dpos + 2, mpos - dpos - 2 ); +	if ( sep == t.mid( mpos + 2, ypos - mpos - 2 ) ) { +	    *lTimeSep = sep; +	} +    } +#endif +} + +static TQDateEdit::Order localOrder() { +    if ( !lDateSep ) { +	readLocaleSettings(); +    } +    return lOrder; +} + +static TQString localDateSep() { +    if ( !lDateSep ) { +	readLocaleSettings(); +    } +    return *lDateSep; +} + +static TQString localTimeSep() { +    if ( !lTimeSep ) { +	readLocaleSettings(); +    } +    return *lTimeSep; +} + +class TQDateTimeEditorPrivate +{ +public: +    TQDateTimeEditorPrivate() +	: frm( TRUE ), +	  parag( new TQTextParagraph( 0, 0, 0, FALSE ) ), +	  focusSec(0) +    { +	parag->formatter()->setWrapEnabled( FALSE ); +	cursor = new TQTextCursor( 0 ); +	cursor->setParagraph( parag ); +	offset = 0; +	sep = localDateSep(); +	refcount++; +    } +    ~TQDateTimeEditorPrivate() +    { +	delete parag; +	delete cursor; +	if ( !--refcount ) +	    cleanup(); +    } + +    void appendSection( const TQNumberSection& sec ) +    { +	sections.append( sec ); + +    } +    void clearSections() +    { +	sections.clear(); +    } +    void setSectionSelection( int sec, int selstart, int selend ) +    { +	if ( sec < 0 || sec > (int)sections.count() ) +	    return; +	sections[sec].setSelectionStart( selstart ); +	sections[sec].setSelectionEnd( selend ); +    } +    uint sectionCount() const { return (uint)sections.count(); } +    void setSeparator( const TQString& s ) { sep = s; } +    TQString separator() const { return sep; } + +    void setFrame( bool f ) { frm = f; } +    bool frame() const { return frm; } + +    int focusSection() const { return focusSec; } +    int section( const TQPoint& p ) +    { +	cursor->place( p + TQPoint( offset, 0 ), parag ); +	int idx = cursor->index(); +	for ( uint i = 0; i < sections.count(); ++i ) { +	    if ( idx >= sections[i].selectionStart() && +		 idx <= sections[i].selectionEnd() ) +		return i; +	} +	return -1; +    } +    TQNumberSection section( int idx ) const +    { +	return sections[idx]; +    } +    bool setFocusSection( int idx ) +    { +	if ( idx > (int)sections.count()-1 || idx < 0 ) +	    return FALSE; +	if ( idx != focusSec ) { +	    focusSec = idx; +	    applyFocusSelection(); +	    return TRUE; +	} +	return FALSE; +    } + +    bool inSectionSelection( int idx ) +    { +	for ( uint i = 0; i < sections.count(); ++i ) { +	    if ( idx >= sections[i].selectionStart() && +		 idx <= sections[i].selectionEnd() ) +		return TRUE; +	} +	return FALSE; +    } + +    void paint( const TQString& txt, bool focus, TQPainter& p, +		const TQColorGroup& cg, const TQRect& rect, TQStyle& style ) +    { +	int fw = 0; +	if ( frm ) +	    fw = style.tqpixelMetric(TQStyle::PM_DefaultFrameWidth); + +	parag->truncate( 0 ); +	parag->append( txt ); +	if ( !focus ) +	    parag->removeSelection( TQTextDocument::Standard ); +	else { +	    applyFocusSelection(); +	} + +	/* color all TQDATETIMEEDIT_HIDDEN_CHAR chars to background color */ +	TQTextFormat *fb = parag->formatCollection()->format( p.font(), +							     cg.base() ); +	TQTextFormat *nf = parag->formatCollection()->format( p.font(), +							     cg.text() ); +	for ( uint i = 0; i < txt.length(); ++i ) { +	    parag->setFormat( i, 1, nf ); +	    if ( inSectionSelection( i ) ) +		continue; +	    if ( txt.at(i) == TQDATETIMEEDIT_HIDDEN_CHAR ) +		parag->setFormat( i, 1, fb ); +	    else +		parag->setFormat( i, 1, nf ); +	} +	fb->removeRef(); +	nf->removeRef(); + +	TQRect r( rect.x(), rect.y(), rect.width() - 2 * ( 2 + fw ), rect.height() ); +	parag->pseudoDocument()->docRect = r; +	parag->tqinvalidate(0); +	parag->format(); + +	int xoff = 2 + fw - offset; +	int yoff = ( rect.height() - parag->rect().height() + 1 ) / 2; +	if ( yoff < 0 ) +	    yoff = 0; + +	p.translate( xoff, yoff ); +	parag->paint( p, cg, 0, TRUE ); +	if ( frm ) +	    p.translate( -xoff, -yoff ); +    } + +    void resize( const TQSize& size ) { sz = size; } + +    int mapSection( int sec ) +    { +	return sections[sec].index(); +    } + +protected: +    void applyFocusSelection() +    { +	if ( focusSec > -1 ) { +	    int selstart = sections[ focusSec ].selectionStart(); +	    int selend = sections[ focusSec ].selectionEnd(); +	    parag->setSelection( TQTextDocument::Standard, selstart, selend ); +	    parag->format(); +	    if ( parag->at( selstart )->x < offset || +		 parag->at( selend )->x + parag->string()->width( selend ) > offset + sz.width() ) { +		offset = parag->at( selstart )->x; +	    } +	} +    } +private: +    bool frm; +    TQTextParagraph *parag; +    TQTextCursor *cursor; +    TQSize sz; +    int focusSec; +    TQValueList< TQNumberSection > sections; +    TQString sep; +    int offset; +}; + +class TQDateTimeEditor : public TQWidget +{ +    Q_OBJECT +    TQ_OBJECT +public: +    TQDateTimeEditor( TQDateTimeEditBase * widget, TQWidget *tqparent, +		       const char * name=0 ); +    ~TQDateTimeEditor(); + +    void setControlWidget( TQDateTimeEditBase * widget ); +    TQDateTimeEditBase * controlWidget() const; + +    void setSeparator( const TQString& s ); +    TQString separator() const; + +    int  focusSection() const; +    bool setFocusSection( int s ); +    void appendSection( const TQNumberSection& sec ); +    void clearSections(); +    void setSectionSelection( int sec, int selstart, int selend ); +    bool eventFilter( TQObject *o, TQEvent *e ); +    int  sectionAt( const TQPoint &p ); +    int mapSection( int sec ); + +protected: +    void init(); +    bool event( TQEvent *e ); +    void resizeEvent( TQResizeEvent * ); +    void paintEvent( TQPaintEvent * ); +    void mousePressEvent( TQMouseEvent *e ); + +private: +    TQDateTimeEditBase* cw; +    TQDateTimeEditorPrivate* d; +}; + +class TQDateTimeSpinWidget : public TQSpinWidget +{ +    Q_OBJECT +    TQ_OBJECT +public: +    TQDateTimeSpinWidget( TQWidget *tqparent, const char *name ) +	: TQSpinWidget( tqparent, name ) +    { +    } + +    void enabledChange(bool notenabled) +    { +        TQDateEdit *de = ::tqqt_cast<TQDateEdit*>(parentWidget()); +        if (de && !notenabled) { +	    setUpEnabled(de->date() < de->maxValue()); +	    setDownEnabled(de->date() > de->minValue()); +        } else { +            setUpEnabled(!notenabled); +            setDownEnabled(!notenabled); +        } +    } + +protected: +#ifndef TQT_NO_WHEELEVENT +    void wheelEvent( TQWheelEvent *e ) +    { +	TQDateTimeEditor *editor = (TQDateTimeEditor*)editWidget()->tqqt_cast( "TQDateTimeEditor" ); +	TQ_ASSERT( editor ); +	if ( !editor ) +	    return; + +	int section = editor->sectionAt( e->pos() ); +	editor->setFocusSection( section ); + +	if ( section == -1 ) +	    return; +	TQSpinWidget::wheelEvent( e ); +    } +#endif +}; + +/*! +    Constructs an empty datetime editor with tqparent \a tqparent and +    called \a name. +*/ +TQDateTimeEditor::TQDateTimeEditor( TQDateTimeEditBase * widget, TQWidget *tqparent, +				  const char * name ) +    : TQWidget( tqparent, name, TQt::WNoAutoErase ) +{ +    d = new TQDateTimeEditorPrivate(); +    cw = widget; +    init(); +} + +/*! +    Destroys the object and frees any allocated resources. +*/ + +TQDateTimeEditor::~TQDateTimeEditor() +{ +    delete d; +} + +/*! \internal + +*/ + +void TQDateTimeEditor::init() +{ +    setBackgroundMode( TQt::PaletteBase ); +    setFocusSection( -1 ); +    installEventFilter( this ); +    setFocusPolicy( Qt::WheelFocus ); +} + + +/*! \reimp + +*/ + +bool TQDateTimeEditor::event( TQEvent *e ) +{ +    if ( e->type() == TQEvent::FocusIn || e->type() == TQEvent::FocusOut ) { + 	if ( e->type() == TQEvent::FocusOut ) +  	    tqApp->sendEvent( cw, e ); +	update( rect() ); +    } else if ( e->type() == TQEvent::AccelOverride ) { +	TQKeyEvent* ke = (TQKeyEvent*) e; +	switch ( ke->key() ) { +	case Qt::Key_Delete: +	case Qt::Key_Backspace: +	case Qt::Key_Up: +	case Qt::Key_Down: +	case Qt::Key_Left: +	case Qt::Key_Right: +	    ke->accept(); +	default: +	    break; +	} +    } +    return TQWidget::event( e ); +} + +/*! \reimp + +*/ + +void TQDateTimeEditor::resizeEvent( TQResizeEvent *e ) +{ +    d->resize( e->size() ); +    TQWidget::resizeEvent( e ); +} + + +/*! \reimp + +*/ + +void TQDateTimeEditor::paintEvent( TQPaintEvent * ) +{ +    TQString txt; +    for ( uint i = 0; i < d->sectionCount(); ++i ) { +	txt += cw->sectionFormattedText( i ); +	if ( i < d->sectionCount()-1 ) { +	    if ( d->section( i+1 ).separator() ) +		txt += d->separator(); +	    else +		txt += " "; +	} +    } + +    TQSharedDoubleBuffer buffer( this ); +    const TQBrush &bg = +	tqcolorGroup().brush( isEnabled() ? TQColorGroup::Base : TQColorGroup::Background ); +    buffer.painter()->fillRect( 0, 0, width(), height(), bg ); +    d->paint( txt, hasFocus(), *buffer.painter(), tqcolorGroup(), rect(), +	      tqstyle() ); +    buffer.end(); +} + + +/*! +    Returns the section index at point \a p. +*/ +int TQDateTimeEditor::sectionAt( const TQPoint &p ) +{ +    return d->section( p ); +} + +int TQDateTimeEditor::mapSection( int sec ) +{ +    return d->mapSection( sec ); +} + + +/*! \reimp + +*/ + +void TQDateTimeEditor::mousePressEvent( TQMouseEvent *e ) +{ +    TQPoint p( e->pos().x(), 0 ); +    int sec = sectionAt( p ); +    if ( sec != -1 ) { +	cw->setFocusSection( sec ); +	tqrepaint( rect(), FALSE ); +    } +} + +/*! \reimp + +*/ +bool TQDateTimeEditor::eventFilter( TQObject *o, TQEvent *e ) +{ +    if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) { +	if ( e->type() == TQEvent::KeyPress ) { +	    TQKeyEvent *ke = (TQKeyEvent*)e; +	    switch ( ke->key() ) { +	    case Qt::Key_Right: +		if ( d->focusSection() < (int)d->sectionCount()-1 ) { +		    if ( cw->setFocusSection( focusSection()+1 ) ) +			tqrepaint( rect(), FALSE ); +		} +		return TRUE; +	    case Qt::Key_Left: +		if ( d->focusSection() > 0 ) { +		    if ( cw->setFocusSection( focusSection()-1 ) ) +			tqrepaint( rect(), FALSE ); +		} +		return TRUE; +	    case Qt::Key_Up: +		cw->stepUp(); +		return TRUE; +	    case Qt::Key_Down: +		cw->stepDown(); +		return TRUE; +	    case Qt::Key_Backspace: +		if ( ::tqqt_cast<TQDateEdit*>(cw) ) +		    ((TQDateEdit*)cw)->removeFirstNumber( d->focusSection() ); +		else if ( ::tqqt_cast<TQTimeEdit*>(cw) ) +		    ((TQTimeEdit*)cw)->removeFirstNumber( d->focusSection() ); +		return TRUE; +	    case Qt::Key_Delete: +		cw->removeLastNumber( d->focusSection() ); +		return TRUE; +	    case Qt::Key_Tab: +	    case TQt::Key_BackTab: { +		if ( ke->state() == ControlButton ) +		    return FALSE; + +		TQWidget *w = this; +		bool hadDateEdit = FALSE; +		while ( w ) { +		    if ( (::tqqt_cast<TQDateTimeSpinWidget*>(w) && qstrcmp( w->name(), "qt_spin_widget" ) != 0) || +			 ::tqqt_cast<TQDateTimeEdit*>(w) ) +			break; +		    hadDateEdit = hadDateEdit || ::tqqt_cast<TQDateEdit*>(w); +		    w = w->parentWidget(); +		} + +		if ( w ) { +		    if ( !::tqqt_cast<TQDateTimeEdit*>(w) ) { +			w = w->parentWidget(); +		    } else { +			TQDateTimeEdit *ed = (TQDateTimeEdit*)w; +			if ( hadDateEdit && ke->key() == Qt::Key_Tab ) { +			    ed->timeEdit()->setFocus(); +			    return TRUE; +			} else if ( !hadDateEdit && ke->key() == TQt::Key_BackTab ) { +			    ed->dateEdit()->setFocus(); +			    return TRUE; +			} else { +			    while ( w && !::tqqt_cast<TQDateTimeEdit*>(w) ) +				w = w->parentWidget(); +			} +		    } + +		    tqApp->sendEvent( w, e ); +		    return TRUE; +		} +	    } break; +	    default: +		TQString txt = TQT_TQSTRING(ke->text()).lower(); +		if ( !txt.isEmpty() && !separator().isEmpty() && txt[0] == separator()[0] ) { +		    // do the same thing as KEY_RIGHT when the user presses the separator key +		    if ( d->focusSection() < 2 ) { +			if ( cw->setFocusSection( focusSection()+1 ) ) +			    tqrepaint( rect(), FALSE ); +		    } +		    return TRUE; +		} else if ( !txt.isEmpty() && ::tqqt_cast<TQTimeEdit*>(cw) && focusSection() == (int) d->sectionCount()-1 ) { +		    // the first character of the AM/PM indicator toggles if the section has focus +		    TQTimeEdit *te = (TQTimeEdit*)cw; +		    TQTime time = te->time(); +		    if ( lAMPM && lAM && lPM && (te->display()&TQTimeEdit::AMPM) ) { +			if ( txt[0] == (*lAM).lower()[0] && time.hour() >= 12 ) { +			    time.setHMS( time.hour()-12, time.minute(), time.second(), time.msec() ); +			    te->setTime( time ); +			} else if ( txt[0] == (*lPM).lower()[0] && time.hour() < 12 ) { +			    time.setHMS( time.hour()+12, time.minute(), time.second(), time.msec() ); +			    te->setTime( time ); +			} +		    } +		} + +		int num = txt[0].digitValue(); +		if ( num != -1 ) { +		    cw->addNumber( d->focusSection(), num ); +		    return TRUE; +		} +	    } +	} +    } +    return FALSE; +} + + +/*! +    Appends the number section \a sec to the editor. +*/ + +void TQDateTimeEditor::appendSection( const TQNumberSection& sec ) +{ +    d->appendSection( sec ); +} + +/*! +    Removes all sections from the editor. +*/ + +void TQDateTimeEditor::clearSections() +{ +    d->clearSections(); +} + +/*! +    Sets the selection of \a sec to start at \a selstart and end at \a +    selend. +*/ + +void TQDateTimeEditor::setSectionSelection( int sec, int selstart, int selend ) +{ +    d->setSectionSelection( sec, selstart, selend ); +} + +/*! +    Sets the separator for all numbered sections to \a s. Note that +    currently, only the first character of \a s is used. +*/ + +void TQDateTimeEditor::setSeparator( const TQString& s ) +{ +    d->setSeparator( s ); +    update(); +} + + +/*! +    Returns the editor's separator. +*/ + +TQString TQDateTimeEditor::separator() const +{ +    return d->separator(); +} + +/*! +    Returns the number of the section that has focus. +*/ + +int TQDateTimeEditor::focusSection() const +{ +    return d->focusSection(); +} + + +/*! +    Sets the focus to section \a sec. If \a sec does not exist, +    nothing happens. +*/ + +bool TQDateTimeEditor::setFocusSection( int sec ) +{ +    return d->setFocusSection( sec ); +} + +/*! \class TQDateTimeEditBase +    \brief The TQDateTimeEditBase class provides an abstraction for date and edit editors. + +    Small abstract class that provides some functions that are common +    for both TQDateEdit and TQTimeEdit. It is used internally by +    TQDateTimeEditor. +*/ + +/*! +    \fn TQDateTimeEditBase::TQDateTimeEditBase(TQWidget *, const char*) +    \internal +*/ + +/*! +    \fn TQDateTimeEditBase::setFocusSection(int) +    \internal +*/ + +/*! \fn TQString TQDateTimeEditBase::sectionFormattedText( int sec ) +    \internal + +  Pure virtual function which returns the formatted text of section \a +  sec. + +*/ + +/*! \fn void TQDateTimeEditBase::stepUp() +    \internal + +  Pure virtual slot which is called whenever the user increases the +  number in a section by pressing the widget's arrow buttons or the +  keyboard's arrow keys. +*/ + +/*! \fn void TQDateTimeEditBase::stepDown() +    \internal + +  Pure virtual slot which is called whenever the user decreases the +  number in a section by pressing the widget's arrow buttons or the +  keyboard's arrow keys. + +*/ + +/*! \fn void TQDateTimeEditBase::addNumber( int sec, int num ) +    \internal + +  Pure virtual function which is called whenever the user types a number. +  \a sec indicates the section where the number should be added. \a +  num is the number that was pressed. +*/ + +/*! \fn void TQDateTimeEditBase::removeLastNumber( int sec ) +    \internal + +  Pure virtual function which is called whenever the user tries to +  remove the last number from \a sec by pressing the delete key. +*/ + +//////////////// + +class TQDateEditPrivate +{ +public: +    int y; +    int m; +    int d; +    // remebers the last entry for the day. +    // if the day is 31 and you cycle through the months, +    // the day will be 31 again if you reach a month with 31 days +    // otherwise it will be the highest day in the month +    int dayCache; +    int yearSection; +    int monthSection; +    int daySection; +    TQDateEdit::Order ord; +    bool overwrite; +    bool adv; +    int timerId; +    bool typing; +    TQDate min; +    TQDate max; +    bool changed; +    TQDateTimeEditor *ed; +    TQSpinWidget *controls; +}; + + +/*! +    \class TQDateEdit tqdatetimeedit.h +    \brief The TQDateEdit class provides a date editor. + +    \ingroup advanced +    \ingroup time +    \mainclass + +    TQDateEdit allows the user to edit dates by using the keyboard or +    the arrow keys to increase/decrease date values. The arrow keys +    can be used to move from section to section within the TQDateEdit +    box. Dates appear in accordance with the local date/time settings +    or in year, month, day order if the system doesn't provide this +    information. It is recommended that the TQDateEdit be initialised +    with a date, e.g. + +    \code +    TQDateEdit *dateEdit = new TQDateEdit( TQDate::tqcurrentDate(), this ); +    dateEdit->setRange( TQDate::tqcurrentDate().addDays( -365 ), +			TQDate::tqcurrentDate().addDays(  365 ) ); +    dateEdit->setOrder( TQDateEdit::MDY ); +    dateEdit->setAutoAdvance( TRUE ); +    \endcode + +    Here we've created a new TQDateEdit object initialised with today's +    date and restricted the valid date range to today plus or minus +    365 days. We've set the order to month, day, year. If the auto +    advance property is TRUE (as we've set it here) when the user +    completes a section of the date, e.g. enters two digits for the +    month, they are automatically taken to the next section. + +    The maximum and minimum values for a date value in the date editor +    default to the maximum and minimum values for a TQDate. You can +    change this by calling setMinValue(), setMaxValue() or setRange(). + +    Terminology: A TQDateEdit widget comprises three 'sections', one +    each for the year, month and day. You can change the separator +    character using TQDateTimeEditor::setSeparator(), by default the +    separator will be taken from the systems settings. If that is +    not possible, it defaults to "-". + +    \img datetimewidgets.png Date Time Widgets + +    \sa TQDate TQTimeEdit TQDateTimeEdit +*/ + +/*! +    \enum TQDateEdit::Order + +    This enum defines the order in which the sections that comprise a +    date appear. +    \value MDY month-day-year +    \value DMY day-month-year +    \value YMD year-month-day (the default) +    \value YDM year-day-month (included for completeness; but should +    not be used) +*/ + +/*! +    \enum TQTimeEdit::Display + +    This enum defines the sections that comprise a time + +    \value Hours The hours section +    \value Minutes The minutes section +    \value Seconds The seconds section +    \value AMPM The AM/PM section + +    The values can be or'ed together to show any combination. +*/ + +/*! +    Constructs an empty date editor which is a child of \a tqparent and +    called name \a name. +*/ + +TQDateEdit::TQDateEdit( TQWidget * tqparent, const char * name ) +    : TQDateTimeEditBase( tqparent, name ) +{ +    init(); +    updateButtons(); +} + +/*! +    \overload + +    Constructs a date editor with the initial value \a date, tqparent \a +    tqparent and called \a name. + +    The date editor is initialized with \a date. +*/ + +TQDateEdit::TQDateEdit( const QDate& date, QWidget * tqparent, const char * name ) +    : TQDateTimeEditBase( TQT_TQWIDGET(tqparent), name ) +{ +    init(); +    setDate( TQT_TQDATE_OBJECT(date) ); +} + +/*! \internal +*/ +void TQDateEdit::init() +{ +    d = new TQDateEditPrivate(); +    d->controls = new TQDateTimeSpinWidget( this, qstrcmp( name(), "qt_datetime_dateedit" ) == 0 ? "qt_spin_widget" : "date edit controls" ); +    d->ed = new TQDateTimeEditor( this, d->controls, "date editor" ); +    d->controls->setEditWidget( d->ed ); +    setFocusProxy( d->ed ); +    connect( d->controls, TQT_SIGNAL( stepUpPressed() ), TQT_SLOT( stepUp() ) ); +    connect( d->controls, TQT_SIGNAL( stepDownPressed() ), TQT_SLOT( stepDown() ) ); +    connect( this, TQT_SIGNAL( valueChanged(const TQDate&) ), +	     TQT_SLOT( updateButtons() ) ); +    d->ed->appendSection( TQNumberSection( 0,4 ) ); +    d->ed->appendSection( TQNumberSection( 5,7 ) ); +    d->ed->appendSection( TQNumberSection( 8,10 ) ); + +    d->yearSection = -1; +    d->monthSection = -1; +    d->daySection = -1; + +    d->y = 0; +    d->m = 0; +    d->d = 0; +    d->dayCache = 0; +    setOrder( localOrder() ); +    setFocusSection( 0 ); +    d->overwrite = TRUE; +    d->adv = FALSE; +    d->timerId = 0; +    d->typing = FALSE; +    d->min = TQDate( 1752, 9, 14 ); +    d->max = TQDate( 8000, 12, 31 ); +    d->changed = FALSE; + +    tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); + +    refcount++; +} + +/*! +    Destroys the object and frees any allocated resources. +*/ + +TQDateEdit::~TQDateEdit() +{ +    delete d; +    if ( !--refcount ) +	cleanup(); +} + +/*! +    \property TQDateEdit::minValue + +    \brief the editor's minimum value + +    Setting the minimum date value is equivalent to calling +    TQDateEdit::setRange( \e d, maxValue() ), where \e d is the minimum +    date. The default minimum date is 1752-09-14. + +    \sa maxValue setRange() +*/ + +TQDate TQDateEdit::minValue() const +{ +    return d->min; +} + +/*! +    \property TQDateEdit::maxValue + +    \brief the editor's maximum value + +    Setting the maximum date value for the editor is equivalent to +    calling TQDateEdit::setRange( minValue(), \e d ), where \e d is the +    maximum date. The default maximum date is 8000-12-31. + +    \sa minValue setRange() +*/ + +TQDate TQDateEdit::maxValue() const +{ +    return d->max; +} + + +/*! +    Sets the valid input range for the editor to be from \a min to \a +    max inclusive. If \a min is invalid no minimum date will be set. +    Similarly, if \a max is invalid no maximum date will be set. +*/ + +void TQDateEdit::setRange( const TQDate& min, const TQDate& max ) +{ +    if ( min.isValid() ) +	d->min = min; +    if ( max.isValid() ) +	d->max = max; +} + +/*! +    Sets the separator to \a s. Note that currently only the first +    character of \a s is used. +*/ + +void TQDateEdit::setSeparator( const TQString& s ) +{ +    d->ed->setSeparator( s ); +} + +/*! +    Returns the editor's separator. +*/ + +TQString TQDateEdit::separator() const +{ +    return d->ed->separator(); +} + + +/*! +    Enables/disables the push buttons according to the min/max date +    for this widget. +*/ + +void TQDateEdit::updateButtons() +{ +    if ( !isEnabled() ) +	return; + +    bool upEnabled = date() < maxValue(); +    bool downEnabled = date() > minValue(); + +    d->controls->setUpEnabled( upEnabled ); +    d->controls->setDownEnabled( downEnabled ); +} + +/*! \reimp + */ +void TQDateEdit::resizeEvent( TQResizeEvent * ) +{ +    d->controls->resize( width(), height() ); +} + +/*! \reimp + +*/ +TQSize TQDateEdit::tqsizeHint() const +{ +    constPolish(); +    TQFontMetrics fm( font() ); +    int fw = tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth, this ); +    int h = TQMAX( fm.lineSpacing(), 14 ) + 2; +    int w = 2 + fm.width( '9' ) * 8 + fm.width( d->ed->separator() ) * 2 + d->controls->upRect().width() + fw * 4; + +    return TQSize( w, TQMAX(h + fw * 2,20) ).expandedTo( TQApplication::globalStrut() ); +} + +/*! \reimp + +*/ +TQSize TQDateEdit::tqminimumSizeHint() const +{ +    return tqsizeHint(); +} + + +/*! +    Returns the formatted number for section \a sec. This will +    correspond to either the year, month or day section, depending on +    the current display order. + +    \sa setOrder() +*/ + +TQString TQDateEdit::sectionFormattedText( int sec ) +{ +    TQString txt; +    txt = sectionText( sec ); +    if ( d->typing && sec == d->ed->focusSection() ) +	d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - txt.length(), +			     sectionOffsetEnd( sec ) ); +    else +	d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - sectionLength( sec ), +			     sectionOffsetEnd( sec ) ); +    txt = txt.rightJustify( sectionLength( sec ), TQDATETIMEEDIT_HIDDEN_CHAR ); +    return txt; +} + + +/*! +    Returns the desired length (number of digits) of section \a sec. +    This will correspond to either the year, month or day section, +    depending on the current display order. + +    \sa setOrder() +*/ + +int TQDateEdit::sectionLength( int sec ) const +{ +    int val = 0; +    if ( sec == d->yearSection ) { +	val = 4; +    } else if ( sec == d->monthSection ) { +	val = 2; +    } else if ( sec == d->daySection ) { +	val = 2; +    } +    return val; +} + +/*! +    Returns the text of section \a sec. This will correspond to either +    the year, month or day section, depending on the current display +    order. + +    \sa setOrder() +*/ + +TQString TQDateEdit::sectionText( int sec ) const +{ +    int val = 0; +    if ( sec == d->yearSection ) { +	val = d->y; +    } else if ( sec == d->monthSection ) { +	val = d->m; +    } else if ( sec == d->daySection ) { +	val = d->d; +    } +    return TQString::number( val ); +} + +/*! \internal + +  Returns the end of the section offset \a sec. + +*/ + +int TQDateEdit::sectionOffsetEnd( int sec ) const +{ +    if ( sec == d->yearSection ) { +	switch( d->ord ) { +	case DMY: +	case MDY: +	    return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec ); +	case YMD: +	case YDM: +	    return sectionLength( sec ); +	} +    } else if ( sec == d->monthSection ) { +	switch( d->ord ) { +	case DMY: +	case YDM: +	case YMD: +	    return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec ); +	case MDY: +	    return sectionLength( sec ); +	} +    } else if ( sec == d->daySection ) { +	switch( d->ord ) { +	case DMY: +	    return sectionLength( sec ); +	case YMD: +	case MDY: +	case YDM: +	    return sectionOffsetEnd( sec-1 ) + separator().length() + sectionLength( sec ); +	} +    } +    return 0; +} + + +/*! +    \property TQDateEdit::order +    \brief the order in which the year, month and day appear + +    The default order is locale dependent. + +    \sa Order +*/ + +void TQDateEdit::setOrder( TQDateEdit::Order order ) +{ +    d->ord = order; +    switch( d->ord ) { +    case DMY: +	d->yearSection = 2; +	d->monthSection = 1; +	d->daySection = 0; +	break; +    case MDY: +	d->yearSection = 2; +	d->monthSection = 0; +	d->daySection = 1; +	break; +    case YMD: +	d->yearSection = 0; +	d->monthSection = 1; +	d->daySection = 2; +	break; +    case YDM: +	d->yearSection = 0; +	d->monthSection = 2; +	d->daySection = 1; +	break; +    } +    if ( isVisible() ) +	d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + +TQDateEdit::Order TQDateEdit::order() const +{ +    return d->ord; +} + + +/*! \reimp + +*/ +void TQDateEdit::stepUp() +{ +    int sec = d->ed->focusSection(); +    bool accepted = FALSE; +    if ( sec == d->yearSection ) { +	if ( !outOfRange( d->y+1, d->m, d->d ) ) { +	    accepted = TRUE; +	    setYear( d->y+1 ); +	} +    } else if ( sec == d->monthSection ) { +	if ( !outOfRange( d->y, d->m+1, d->d ) ) { +	    accepted = TRUE; +	    setMonth( d->m+1 ); +	} +    } else if ( sec == d->daySection ) { +	if ( !outOfRange( d->y, d->m, d->d+1 ) ) { +	    accepted = TRUE; +	    setDay( d->d+1 ); +	} +    } +    if ( accepted ) { +	d->changed = FALSE; +	emit valueChanged( date() ); +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + + +/*! \reimp + +*/ + +void TQDateEdit::stepDown() +{ +    int sec = d->ed->focusSection(); +    bool accepted = FALSE; +    if ( sec == d->yearSection ) { +	if ( !outOfRange( d->y-1, d->m, d->d ) ) { +	    accepted = TRUE; +	    setYear( d->y-1 ); +	} +    } else if ( sec == d->monthSection ) { +	if ( !outOfRange( d->y, d->m-1, d->d ) ) { +	    accepted = TRUE; +	    setMonth( d->m-1 ); +	} +    } else if ( sec == d->daySection ) { +	if ( !outOfRange( d->y, d->m, d->d-1 ) ) { +	    accepted = TRUE; +	    setDay( d->d-1 ); +	} +    } +    if ( accepted ) { +	d->changed = FALSE; +	emit valueChanged( date() ); +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +/*! +    Sets the year to \a year, which must be a valid year. The range +    currently supported is from 1752 to 8000. + +    \sa TQDate +*/ + +void TQDateEdit::setYear( int year ) +{ +    if ( year < 1752 ) +	year = 1752; +    if ( year > 8000 ) +	year = 8000; +    if ( !outOfRange( year, d->m, d->d ) ) { +	d->y = year; +	setMonth( d->m ); +	int tmp = d->dayCache; +	setDay( d->dayCache ); +	d->dayCache = tmp; +    } +} + + +/*! +    Sets the month to \a month, which must be a valid month, i.e. +    between 1 and 12. +*/ + +void TQDateEdit::setMonth( int month ) +{ +    if ( month < 1 ) +	month = 1; +    if ( month > 12 ) +	month = 12; +    if ( !outOfRange( d->y, month, d->d ) ) { +	d->m = month; +	int tmp = d->dayCache; +	setDay( d->dayCache ); +	d->dayCache = tmp; +    } +} + + +/*! +    Sets the day to \a day, which must be a valid day. The function +    will ensure that the \a day set is valid for the month and year. +*/ + +void TQDateEdit::setDay( int day ) +{ +    if ( day < 1 ) +	day = 1; +    if ( day > 31 ) +	day = 31; +    if ( d->m > 0 && d->y > 1752 ) { +	while ( !TQDate::isValid( d->y, d->m, day ) ) +	    --day; +	if ( !outOfRange( d->y, d->m, day ) ) +	    d->d = day; +    } else if ( d->m > 0 ) { +	if ( day > 0 && day < 32 ) { +	    if ( !outOfRange( d->y, d->m, day ) ) +		d->d = day; +	} +    } +    d->dayCache = d->d; +} + + +/*! +    \property TQDateEdit::date +    \brief the editor's date value. + +    If the date property is not valid, the editor displays all zeroes +    and TQDateEdit::date() will return an invalid date. It is strongly +    recommended that the editor is given a default date value (e.g. +    currentDate()). That way, attempts to set the date property to an +    invalid date will fail. + +    When changing the date property, if the date is less than +    minValue(), or is greater than maxValue(), nothing happens. +*/ + +void TQDateEdit::setDate( const TQDate& date ) +{ +    if ( !date.isValid() ) { +	d->y = 0; +	d->m = 0; +	d->d = 0; +	d->dayCache = 0; +    } else { +	if ( date > maxValue() || date < minValue() ) +	    return; +	d->y = date.year(); +	d->m = date.month(); +	d->d = date.day(); +	d->dayCache = d->d; +	emit valueChanged( date ); +    } +    d->changed = FALSE; +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +TQDate TQDateEdit::date() const +{ +    if ( TQDate::isValid( d->y, d->m, d->d ) ) +	return TQDate( d->y, d->m, d->d ); +    return TQDate(); +} + +/*!  \internal + +  Returns TRUE if \a y, \a m, \a d is out of range, otherwise returns +  FALSE. + +  \sa setRange() + +*/ + +bool TQDateEdit::outOfRange( int y, int m, int d ) const +{ +    if ( TQDate::isValid( y, m, d ) ) { +	TQDate tqcurrentDate( y, m, d ); +	if ( tqcurrentDate > maxValue() || +	     tqcurrentDate < minValue() ) { +	    //## outOfRange should set overwrite? +	    return TRUE; +	} +	return FALSE; +    } +    return FALSE; /* assume ok */ +} + +/*!  \reimp + +*/ + +void TQDateEdit::addNumber( int sec, int num ) +{ +    if ( sec == -1 ) +	return; +    killTimer( d->timerId ); +    bool overwrite = FALSE; +    bool accepted = FALSE; +    d->typing = TRUE; +    TQString txt; +    if ( sec == d->yearSection ) { +	txt = TQString::number( d->y ); +	if ( d->overwrite || txt.length() == 4 ) { +	    accepted = TRUE; +	    d->y = num; +	} else { +	    txt += TQString::number( num ); +	    if ( txt.length() == 4  ) { +		int val = txt.toInt(); +		if ( val < 1792 ) +		    d->y = 1792; +		else if ( val > 8000 ) +		    d->y = 8000; +		else if ( outOfRange( val, d->m, d->d ) ) +		    txt = TQString::number( d->y ); +		else { +		    accepted = TRUE; +		    d->y = val; +		} +	    } else { +		accepted = TRUE; +		d->y = txt.toInt(); +	    } +	    if ( d->adv && txt.length() == 4 ) { +		d->ed->setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +    } else if ( sec == d->monthSection ) { +	txt = TQString::number( d->m ); +	if ( d->overwrite || txt.length() == 2 ) { +	    accepted = TRUE; +	    d->m = num; +	} else { +	    txt += TQString::number( num ); +	    int temp = txt.toInt(); +	    if ( temp > 12 ) +		temp = num; +	    if ( outOfRange( d->y, temp, d->d ) ) +		txt = TQString::number( d->m ); +	    else { +		accepted = TRUE; +		d->m = temp; +	    } +	    if ( d->adv && txt.length() == 2 ) { +		d->ed->setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +    } else if ( sec == d->daySection ) { +	txt = TQString::number( d->d ); +	if ( d->overwrite || txt.length() == 2 ) { +	    accepted = TRUE; +	    d->d = num; +	    d->dayCache = d->d; +	} else { +	    txt += TQString::number( num ); +	    int temp = txt.toInt(); +	    if ( temp > 31 ) +		temp = num; +	    if ( outOfRange( d->y, d->m, temp ) ) +		txt = TQString::number( d->d ); +	    else { +		accepted = TRUE; +		d->d = temp; +		d->dayCache = d->d; +	    } +	    if ( d->adv && txt.length() == 2 ) { +		d->ed->setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +    } +    if ( accepted ) { +	d->changed = FALSE; +	emit valueChanged( date() ); +    } +    d->overwrite = overwrite; +    d->timerId = startTimer( tqApp->doubleClickInterval()*4 ); +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + +/*! \reimp + +*/ + +bool TQDateEdit::setFocusSection( int s ) +{ +    if ( s != d->ed->focusSection() ) { +	killTimer( d->timerId ); +	d->overwrite = TRUE; +	d->typing = FALSE; +	fix(); // will emit valueChanged if necessary +    } +    return d->ed->setFocusSection( s ); +} + + +/*! +    Attempts to fix any invalid date entries. + +    The rules applied are as follows: + +    \list +    \i If the year has four digits it is left unchanged. +    \i If the year has two digits, the year will be changed to four +    digits in the range current year - 70 to current year + 29. +    \i If the year has three digits in the range 100..999, the +    current millennium, i.e. 2000, will be added giving a year +    in the range 2100..2999. +    \i If the day or month is 0 then it will be set to 1 or the +    minimum valid day\month in the range. +    \endlist + +*/ + +void TQDateEdit::fix() +{ +    bool changed = FALSE; +    int currentYear = TQDate::currentDate().year(); +    int year = d->y; +    if ( year < 100 ) { +	int currentCentury = currentYear / 100; +	year += currentCentury * 100; +	if ( currentYear > year ) { +	    if ( currentYear > year + 70 ) +		year += 100; +	} else { +	    if ( year >= currentYear + 30 ) +		year -= 100; +	} +	changed = TRUE; +    } else if ( year < 1000 ) { +	int currentMillennium = currentYear / 10; +	year += currentMillennium * 10; +	changed = TRUE; +    } else if (d->d == 0) { +	d->d = 1; +	changed = TRUE; +    } else if (d->m == 0) { +	d->m = 1; +	changed = TRUE; +    } +    if ( outOfRange( year, d->m, d->d ) ) { +	if ( minValue().isValid() && date() < minValue() ) { +	    d->d =  minValue().day(); +	    d->dayCache = d->d; +	    d->m = minValue().month(); +	    d->y = minValue().year(); +	} +	if ( date() > maxValue() ) { +	    d->d =  maxValue().day(); +	    d->dayCache = d->d; +	    d->m = maxValue().month(); +	    d->y = maxValue().year(); +	} +	changed = TRUE; +    } else if ( changed ) +	setYear( year ); +    if ( changed ) { +	emit valueChanged( date() ); +	d->changed = FALSE; +    } +} + + +/*! \reimp + +*/ + +bool TQDateEdit::event( TQEvent *e ) +{ +    if( e->type() == TQEvent::FocusOut ) { +	d->typing = FALSE; +	fix(); +	// the following can't be done in fix() because fix() called +	// from all over the place and it will break the old behaviour +	if ( !TQDate::isValid( d->y, d->m, d->d ) ) { +	    d->dayCache = d->d; +	    int i = d->d; +	    for ( ; i > 0; i-- ) { +		d->d = i; +		if ( TQDate::isValid( d->y, d->m, d->d ) ) +		    break; +	    } +	    d->changed = TRUE; +	} +	if ( d->changed ) { +	    emit valueChanged( date() ); +	    d->changed = FALSE; +	} +    } else if ( e->type() == TQEvent::LocaleChange ) { +	readLocaleSettings(); +	d->ed->setSeparator( localDateSep() ); +	setOrder( localOrder() ); +    } +    return TQDateTimeEditBase::event( e ); +} + +/*! +  \internal + +  Function which is called whenever the user tries to +  remove the first number from \a sec by pressing the backspace key. +*/ + +void TQDateEdit::removeFirstNumber( int sec ) +{ +    if ( sec == -1 ) +	return; +    TQString txt; +    if ( sec == d->yearSection ) { +	txt = TQString::number( d->y ); +	txt = txt.mid( 1, txt.length() ) + "0"; +	d->y = txt.toInt(); +    } else if ( sec == d->monthSection ) { +	txt = TQString::number( d->m ); +	txt = txt.mid( 1, txt.length() ) + "0"; +	d->m = txt.toInt(); +    } else if ( sec == d->daySection ) { +	txt = TQString::number( d->d ); +	txt = txt.mid( 1, txt.length() ) + "0"; +	d->d = txt.toInt(); +	d->dayCache = d->d; +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +/*! \reimp + +*/ + +void TQDateEdit::removeLastNumber( int sec ) +{ +    if ( sec == -1 ) +	return; +    TQString txt; +    if ( sec == d->yearSection ) { +	txt = TQString::number( d->y ); +	txt = txt.mid( 0, txt.length()-1 ); +	d->y = txt.toInt(); +    } else if ( sec == d->monthSection ) { +	txt = TQString::number( d->m ); +	txt = txt.mid( 0, txt.length()-1 ); +	d->m = txt.toInt(); +    } else if ( sec == d->daySection ) { +	txt = TQString::number( d->d ); +	txt = txt.mid( 0, txt.length()-1 ); +	d->d = txt.toInt(); +	d->dayCache = d->d; +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +/*! +    \property TQDateEdit::autoAdvance +    \brief whether the editor automatically advances to the next +    section + +    If autoAdvance is TRUE, the editor will automatically advance +    focus to the next date section if a user has completed a section. +    The default is FALSE. +*/ + +void TQDateEdit::setAutoAdvance( bool advance ) +{ +    d->adv = advance; +} + + +bool TQDateEdit::autoAdvance() const +{ +    return d->adv; +} + +/*! \reimp +*/ + +void TQDateEdit::timerEvent( TQTimerEvent * ) +{ +    d->overwrite = TRUE; +} + +/*! +    \fn void TQDateEdit::valueChanged( const TQDate& date ) + +    This signal is emitted whenever the editor's value changes. The \a +    date parameter is the new value. +*/ + +/////////// + +class TQTimeEditPrivate +{ +public: +    int h; +    int m; +    int s; +    uint display; +    bool adv; +    bool overwrite; +    int timerId; +    bool typing; +    TQTime min; +    TQTime max; +    bool changed; +    TQDateTimeEditor *ed; +    TQSpinWidget *controls; +}; + +/*! +    \class TQTimeEdit tqdatetimeedit.h +    \brief The TQTimeEdit class provides a time editor. + +    \ingroup advanced +    \ingroup time +    \mainclass + +    TQTimeEdit allows the user to edit times by using the keyboard or +    the arrow keys to increase/decrease time values. The arrow keys +    can be used to move from section to section within the TQTimeEdit +    box. The user can automatically be moved to the next section once +    they complete a section using setAutoAdvance(). Times appear in +    hour, minute, second order. It is recommended that the TQTimeEdit +    is initialised with a time, e.g. +    \code +    TQTime timeNow = TQTime::currentTime(); +    TQTimeEdit *timeEdit = new TQTimeEdit( timeNow, this ); +    timeEdit->setRange( timeNow, timeNow.addSecs( 60 * 60 ) ); +    \endcode +    Here we've created a TQTimeEdit widget set to the current time. +    We've also set the minimum value to the current time and the +    maximum time to one hour from now. + +    The maximum and minimum values for a time value in the time editor +    default to the maximum and minimum values for a TQTime. You can +    change this by calling setMinValue(), setMaxValue() or setRange(). + +    Terminology: A TQTimeWidget consists of three sections, one each +    for the hour, minute and second. You can change the separator +    character using setSeparator(), by default the separator is read +    from the system's settings. + +    \img datetimewidgets.png Date Time Widgets + +    \sa TQTime TQDateEdit TQDateTimeEdit +*/ + + +/*! +    Constructs an empty time edit with tqparent \a tqparent and called \a +    name. +*/ + +TQTimeEdit::TQTimeEdit( TQWidget * tqparent, const char * name ) +    : TQDateTimeEditBase( tqparent, name ) +{ +    init(); +} + +/*! +    \overload + +    Constructs a time edit with the initial time value, \a time, +    tqparent \a tqparent and called \a name. +*/ + +TQTimeEdit::TQTimeEdit( const QTime& time, QWidget * tqparent, const char * name ) +    : TQDateTimeEditBase( TQT_TQWIDGET(tqparent), name ) +{ +    init(); +    setTime( TQT_TQTIME_OBJECT(time) ); +} + +/*! \internal + */ + +void TQTimeEdit::init() +{ +    d = new TQTimeEditPrivate(); +    d->controls = new TQDateTimeSpinWidget( this, qstrcmp( name(), "qt_datetime_timeedit" ) == 0 ? "qt_spin_widget" : "time edit controls" ); +    d->ed = new TQDateTimeEditor( this, d->controls, "time edit base" ); +    d->controls->setEditWidget( d->ed ); +    setFocusProxy( d->ed ); +    connect( d->controls, TQT_SIGNAL( stepUpPressed() ), TQT_SLOT( stepUp() ) ); +    connect( d->controls, TQT_SIGNAL( stepDownPressed() ), TQT_SLOT( stepDown() ) ); + +    d->ed->appendSection( TQNumberSection( 0,0, TRUE, 0 ) ); +    d->ed->appendSection( TQNumberSection( 0,0, TRUE, 1 ) ); +    d->ed->appendSection( TQNumberSection( 0,0, TRUE, 2 ) ); +    d->ed->setSeparator( localTimeSep() ); + +    d->h = 0; +    d->m = 0; +    d->s = 0; +    d->display = Hours | Minutes | Seconds; +    if ( lAMPM ) { +	d->display |= AMPM; +	d->ed->appendSection( TQNumberSection( 0,0, FALSE, 3 ) ); +    } +    d->adv = FALSE; +    d->overwrite = TRUE; +    d->timerId = 0; +    d->typing = FALSE; +    d->min = TQTime( 0, 0, 0 ); +    d->max = TQTime( 23, 59, 59 ); +    d->changed = FALSE; + +    tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); + +    refcount++; +} + +/*! +    Destroys the object and frees any allocated resources. +*/ + +TQTimeEdit::~TQTimeEdit() +{ +    delete d; +    if ( !--refcount ) +	cleanup(); +} + +/*! +    \property TQTimeEdit::minValue +    \brief the minimum time value + +    Setting the minimum time value is equivalent to calling +    TQTimeEdit::setRange( \e t, maxValue() ), where \e t is the minimum +    time. The default minimum time is 00:00:00. + +    \sa maxValue setRange() +*/ + +TQTime TQTimeEdit::minValue() const +{ +    return d->min; +} + +/*! +    \property TQTimeEdit::maxValue +    \brief the maximum time value + +    Setting the maximum time value is equivalent to calling +    TQTimeEdit::setRange( minValue(), \e t ), where \e t is the maximum +    time. The default maximum time is 23:59:59. + +    \sa minValue setRange() +*/ + +TQTime TQTimeEdit::maxValue() const +{ +    return d->max; +} + + +/*! +    Sets the valid input range for the editor to be from \a min to \a +    max inclusive. If \a min is invalid no minimum time is set. +    Similarly, if \a max is invalid no maximum time is set. +*/ + +void TQTimeEdit::setRange( const TQTime& min, const TQTime& max ) +{ +    if ( min.isValid() ) +	d->min = min; +    if ( max.isValid() ) +	d->max = max; +} + +/*! +  \property TQTimeEdit::display +  \brief the sections that are displayed in the time edit + +  The value can be any combination of the values in the Display enum. +  By default, the widget displays hours, minutes and seconds. +*/ +void TQTimeEdit::setDisplay( uint display ) +{ +    if ( d->display == display ) +	return; + +    d->ed->clearSections(); +    d->display = display; +    if ( d->display & Hours ) +	d->ed->appendSection( TQNumberSection( 0,0, TRUE, 0 ) ); +    if ( d->display & Minutes ) +	d->ed->appendSection( TQNumberSection( 0,0, TRUE, 1 ) ); +    if ( d->display & Seconds ) +	d->ed->appendSection( TQNumberSection( 0,0, TRUE, 2 ) ); +    if ( d->display & AMPM ) +	d->ed->appendSection( TQNumberSection( 0,0, FALSE, 3 ) ); + +    d->ed->setFocusSection( 0 ); +    d->ed->update(); +} + +uint TQTimeEdit::display() const +{ +    return d->display; +} + +/*! +    \property TQTimeEdit::time +    \brief the editor's time value. + +    When changing the time property, if the time is less than +    minValue(), or is greater than maxValue(), nothing happens. +*/ + +void TQTimeEdit::setTime( const TQTime& time ) +{ +    if ( !time.isValid() ) { +	d->h = 0; +	d->m = 0; +	d->s = 0; +    } else { +	if ( time > maxValue() || time < minValue() ) +	    return; +	d->h = time.hour(); +	d->m = time.minute(); +	d->s = time.second(); +	emit valueChanged( time ); +    } +    d->changed = FALSE; +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +TQTime TQTimeEdit::time() const +{ +    if ( TQTime::isValid( d->h, d->m, d->s ) ) +	return TQTime( d->h, d->m, d->s ); +    return TQTime(); +} + +/*! +    \property TQTimeEdit::autoAdvance +    \brief whether the editor automatically advances to the next +    section + +    If autoAdvance is TRUE, the editor will automatically advance +    focus to the next time section if a user has completed a section. +    The default is FALSE. +*/ + +void TQTimeEdit::setAutoAdvance( bool advance ) +{ +    d->adv = advance; +} + +bool TQTimeEdit::autoAdvance() const +{ +    return d->adv; +} + +/*! +    Sets the separator to \a s. Note that currently only the first +    character of \a s is used. +*/ + +void TQTimeEdit::setSeparator( const TQString& s ) +{ +    d->ed->setSeparator( s ); +} + +/*! +    Returns the editor's separator. +*/ + +TQString TQTimeEdit::separator() const +{ +    return d->ed->separator(); +} + + +/*! +    \fn void TQTimeEdit::valueChanged( const TQTime& time ) + +    This signal is emitted whenever the editor's value changes. The \a +    time parameter is the new value. +*/ + +/*! \reimp + +*/ + +bool TQTimeEdit::event( TQEvent *e ) +{ +    if ( e->type() == TQEvent::FocusOut ) { +	d->typing = FALSE; +	if ( d->changed ) { +	    emit valueChanged( time() ); +	    d->changed = FALSE; +	} +    } else if ( e->type() == TQEvent::LocaleChange ) { +	readLocaleSettings(); +	d->ed->setSeparator( localTimeSep() ); +    } +    return TQDateTimeEditBase::event( e ); +} + +/*! \reimp + +*/ + +void TQTimeEdit::timerEvent( TQTimerEvent * ) +{ +    d->overwrite = TRUE; +} + + +/*! \reimp + +*/ + +void TQTimeEdit::stepUp() +{ +    if (minValue() > maxValue()) { +        return; +    } +    int sec = d->ed->mapSection( d->ed->focusSection() ); +    bool accepted = TRUE; +    switch( sec ) { +    case 0: +        do { +            d->h = (d->h + 1) % 24; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 1: +        do { +            d->m = (d->m + 1) % 60; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 2: +        do { +            d->s = (d->s + 1) % 60; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 3: +	if ( d->h < 12 ) +	    setHour( d->h+12 ); +	else +	    setHour( d->h-12 ); +	break; +    default: +	accepted = FALSE; +#ifdef TQT_CHECK_RANGE +	qWarning( "TQTimeEdit::stepUp: Focus section out of range!" ); +#endif +	break; +    } +    if ( accepted ) { +	d->changed = FALSE; +	emit valueChanged( time() ); +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + +/*! \reimp + +*/ + +void TQTimeEdit::stepDown() +{ +    if (minValue() > maxValue()) { +        return; +    } + +    int sec = d->ed->mapSection( d->ed->focusSection() ); +    bool accepted = TRUE; +    switch( sec ) { +    case 0: +        do { +            if (--d->h < 0) +                d->h = 23; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 1: +        do { +            if (--d->m < 0) +                d->m = 59; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 2: +        do { +            if (--d->s < 0) +                d->s = 59; +        } while (outOfRange(d->h, d->m, d->s)); +	break; +    case 3: +	if ( d->h > 11 ) +	    setHour( d->h-12 ); +	else +	    setHour( d->h+12 ); +	break; +    default: +	accepted = FALSE; +#ifdef TQT_CHECK_RANGE +	qWarning( "TQTimeEdit::stepDown: Focus section out of range!" ); +#endif +	break; +    } +    if ( accepted ) { +	d->changed = FALSE; +	emit valueChanged( time() ); +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + +/*! +    Returns the formatted number for section \a sec. This will +    correspond to either the hour, minute or second section, depending +    on \a sec. +*/ + +TQString TQTimeEdit::sectionFormattedText( int sec ) +{ +    TQString txt; +    txt = sectionText( sec ); +    txt = txt.rightJustify( 2, TQDATETIMEEDIT_HIDDEN_CHAR ); +    int offset = sec*2+sec*separator().length() + txt.length(); +    if ( d->typing && sec == d->ed->focusSection() ) +	d->ed->setSectionSelection( sec, offset - txt.length(), offset ); +    else +	d->ed->setSectionSelection( sec, offset - txt.length(), offset ); + +    return txt; +} + + +/*! \reimp + +*/ + +bool TQTimeEdit::setFocusSection( int sec ) +{ +    if ( sec != d->ed->focusSection() ) { +	killTimer( d->timerId ); +	d->overwrite = TRUE; +	d->typing = FALSE; +	TQString txt = sectionText( sec ); +	txt = txt.rightJustify( 2, TQDATETIMEEDIT_HIDDEN_CHAR ); +	int offset = sec*2+sec*separator().length() + txt.length(); +	d->ed->setSectionSelection( sec, offset - txt.length(), offset ); +	if ( d->changed ) { +	    emit valueChanged( time() ); +	    d->changed = FALSE; +	} +    } +    return d->ed->setFocusSection( sec ); +} + + +/*! +    Sets the hour to \a h, which must be a valid hour, i.e. in the +    range 0..24. +*/ + +void TQTimeEdit::setHour( int h ) +{ +    if ( h < 0 ) +	h = 0; +    if ( h > 23 ) +	h = 23; +    d->h = h; +} + + +/*! +    Sets the minute to \a m, which must be a valid minute, i.e. in the +    range 0..59. +*/ + +void TQTimeEdit::setMinute( int m ) +{ +    if ( m < 0 ) +	m = 0; +    if ( m > 59 ) +	m = 59; +    d->m = m; +} + + +/*! +    Sets the second to \a s, which must be a valid second, i.e. in the +    range 0..59. +*/ + +void TQTimeEdit::setSecond( int s ) +{ +    if ( s < 0 ) +	s = 0; +    if ( s > 59 ) +	s = 59; +    d->s = s; +} + + +/*! \internal + +  Returns the text of section \a sec. + +*/ + +TQString TQTimeEdit::sectionText( int sec ) +{ +    sec = d->ed->mapSection( sec ); + +    TQString txt; +    switch( sec ) { +    case 0: +	if ( !(d->display & AMPM) || ( d->h < 13 && d->h ) ) {    // I wished the day stared at 0:00 for everybody +	    txt = TQString::number( d->h ); +	} else { +	    if ( d->h ) +		txt = TQString::number( d->h - 12 ); +	    else +		txt = "12"; +	} +	break; +    case 1: +	txt = TQString::number( d->m ); +	break; +    case 2: +	txt = TQString::number( d->s ); +	break; +    case 3: +	if ( d->h < 12 ) { +	    if ( lAM ) +		txt = *lAM; +	    else +		txt = TQString::tqfromLatin1( "AM" ); +	} else { +	    if ( lPM ) +		txt = *lPM; +	    else +		txt = TQString::tqfromLatin1( "PM" ); +	} +	break; +    default: +	break; +    } +    return txt; +} + + +/*! \internal + Returns TRUE if \a h, \a m, and \a s are out of range. + */ + +bool TQTimeEdit::outOfRange( int h, int m, int s ) const +{ +    if ( TQTime::isValid( h, m, s ) ) { +	TQTime currentTime( h, m, s ); +	if ( currentTime > maxValue() || +	     currentTime < minValue() ) +	    return TRUE; +	else +	    return FALSE; +    } +    return TRUE; +} + +/*! \reimp + +*/ + +void TQTimeEdit::addNumber( int sec, int num ) +{ +    if ( sec == -1 ) +	return; +    sec = d->ed->mapSection( sec ); +    killTimer( d->timerId ); +    bool overwrite = FALSE; +    bool accepted = FALSE; +    d->typing = TRUE; +    TQString txt; + +    switch( sec ) { +    case 0: +	txt = ( d->display & AMPM && d->h > 12 ) ? +	    TQString::number( d->h - 12 ) : TQString::number( d->h ); + +	if ( d->overwrite || txt.length() == 2 ) { +	    if ( d->display & AMPM && num == 0 ) +		break; // Don't process 0 in 12 hour clock mode +	    if ( d->display & AMPM && d->h > 11 ) +		num += 12; +	    if ( !outOfRange( num, d->m, d->s ) ) { +		accepted = TRUE; +		d->h = num; +	    } +	} else { +	    txt += TQString::number( num ); +	    int temp = txt.toInt(); + +	    if ( d->display & AMPM ) { +		if ( temp == 12 ) { +		    if ( d->h < 12 ) { +			temp = 0; +		    } +		    accepted = TRUE; +		} else if ( outOfRange( temp + 12, d->m, d->s ) ) { +		    txt = TQString::number( d->h ); +		} else { +		    if ( d->h > 11 ) { +			temp += 12; +		    } +		    accepted = TRUE; +		} +	    } else if ( !(d->display & AMPM) && outOfRange( temp, d->m, d->s ) ) { +		txt = TQString::number( d->h ); +	    } else { +		accepted = TRUE; +	    } + +	    if ( accepted ) +		d->h = temp; + +	    if ( d->adv && txt.length() == 2 ) { +		setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +	break; + +    case 1: +	txt = TQString::number( d->m ); +	if ( d->overwrite || txt.length() == 2 ) { +	    if ( !outOfRange( d->h, num, d->s ) ) { +		accepted = TRUE; +		d->m = num; +	    } +	} else { +	    txt += TQString::number( num ); +	    int temp = txt.toInt(); +	    if ( temp > 59 ) +		temp = num; +	    if ( outOfRange( d->h, temp, d->s ) ) +		txt = TQString::number( d->m ); +	    else { +		accepted = TRUE; +		d->m = temp; +	    } +	    if ( d->adv && txt.length() == 2 ) { +		setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +	break; + +    case 2: +	txt = TQString::number( d->s ); +	if ( d->overwrite || txt.length() == 2 ) { +	    if ( !outOfRange( d->h, d->m, num ) ) { +		accepted = TRUE; +		d->s = num; +	    } +	} else { +	    txt += TQString::number( num ); +	    int temp = txt.toInt(); +	    if ( temp > 59 ) +		temp = num; +	    if ( outOfRange( d->h, d->m, temp ) ) +		txt = TQString::number( d->s ); +	    else { +		accepted = TRUE; +		d->s = temp; +	    } +	    if ( d->adv && txt.length() == 2 ) { +		setFocusSection( d->ed->focusSection()+1 ); +		overwrite = TRUE; +	    } +	} +	break; + +    case 3: +	break; + +    default: +	break; +    } +    d->changed = !accepted; +    if ( accepted ) +	emit valueChanged( time() ); +    d->overwrite = overwrite; +    d->timerId = startTimer( tqApp->doubleClickInterval()*4 ); +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + + +/*! +  \internal + +  Function which is called whenever the user tries to +  remove the first number from \a sec by pressing the backspace key. +*/ + +void TQTimeEdit::removeFirstNumber( int sec ) +{ +    if ( sec == -1 ) +	return; +    sec = d->ed->mapSection( sec ); +    TQString txt; +    switch( sec ) { +    case 0: +	txt = TQString::number( d->h ); +	break; +    case 1: +	txt = TQString::number( d->m ); +	break; +    case 2: +	txt = TQString::number( d->s ); +	break; +    } +    txt = txt.mid( 1, txt.length() ) + "0"; +    switch( sec ) { +    case 0: +	d->h = txt.toInt(); +	break; +    case 1: +	d->m = txt.toInt(); +	break; +    case 2: +	d->s = txt.toInt(); +	break; +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +/*! \reimp + +*/ +void TQTimeEdit::removeLastNumber( int sec ) +{ +    if ( sec == -1 ) +	return; +    sec = d->ed->mapSection( sec ); +    TQString txt; +    switch( sec ) { +    case 0: +	txt = TQString::number( d->h ); +	break; +    case 1: +	txt = TQString::number( d->m ); +	break; +    case 2: +	txt = TQString::number( d->s ); +	break; +    } +    txt = txt.mid( 0, txt.length()-1 ); +    switch( sec ) { +    case 0: +	d->h = txt.toInt(); +	break; +    case 1: +	d->m = txt.toInt(); +	break; +    case 2: +	d->s = txt.toInt(); +	break; +    } +    d->ed->tqrepaint( d->ed->rect(), FALSE ); +} + +/*! \reimp + */ +void TQTimeEdit::resizeEvent( TQResizeEvent * ) +{ +    d->controls->resize( width(), height() ); +} + +/*! \reimp +*/ +TQSize TQTimeEdit::tqsizeHint() const +{ +    constPolish(); +    TQFontMetrics fm( font() ); +    int fw = tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth, this ); +    int h = fm.lineSpacing() + 2; +    int w = 2 + fm.width( '9' ) * 6 + fm.width( d->ed->separator() ) * 2 + +	d->controls->upRect().width() + fw * 4; +    if ( d->display & AMPM ) { +	if ( lAM ) +	    w += fm.width( *lAM ) + 4; +	else +	    w += fm.width( TQString::tqfromLatin1( "AM" ) ) + 4; +    } + +    return TQSize( w, TQMAX(h + fw * 2,20) ).expandedTo( TQApplication::globalStrut() ); +} + +/*! \reimp +*/ +TQSize TQTimeEdit::tqminimumSizeHint() const +{ +    return tqsizeHint(); +} + +/*! +    \internal +    Enables/disables the push buttons according to the min/max time +    for this widget. +*/ + +// ### Remove in 4.0? + +void TQTimeEdit::updateButtons() +{ +    if ( !isEnabled() ) +	return; + +    bool upEnabled = time() < maxValue(); +    bool downEnabled = time() > minValue(); + +    d->controls->setUpEnabled( upEnabled ); +    d->controls->setDownEnabled( downEnabled ); +} + + +class TQDateTimeEditPrivate +{ +public: +    bool adv; +}; + +/*! +    \class TQDateTimeEdit tqdatetimeedit.h +    \brief The TQDateTimeEdit class combines a TQDateEdit and TQTimeEdit +    widget into a single widget for editing datetimes. + +    \ingroup advanced +    \ingroup time +    \mainclass + +    TQDateTimeEdit consists of a TQDateEdit and TQTimeEdit widget placed +    side by side and offers the functionality of both. The user can +    edit the date and time by using the keyboard or the arrow keys to +    increase/decrease date or time values. The Tab key can be used to +    move from section to section within the TQDateTimeEdit widget, and +    the user can be moved automatically when they complete a section +    using setAutoAdvance(). The datetime can be set with +    setDateTime(). + +    The date format is read from the system's locale settings. It is +    set to year, month, day order if that is not possible. See +    TQDateEdit::setOrder() to change this. Times appear in the order +    hours, minutes, seconds using the 24 hour clock. + +    It is recommended that the TQDateTimeEdit is initialised with a +    datetime, e.g. +    \code +    TQDateTimeEdit *dateTimeEdit = new TQDateTimeEdit( TQDateTime::tqcurrentDateTime(), this ); +    dateTimeEdit->dateEdit()->setRange( TQDateTime::tqcurrentDate(), +					TQDateTime::tqcurrentDate().addDays( 7 ) ); +    \endcode +    Here we've created a new TQDateTimeEdit set to the current date and +    time, and set the date to have a minimum date of now and a maximum +    date of a week from now. + +    Terminology: A TQDateEdit widget consists of three 'sections', one +    each for the year, month and day. Similarly a TQTimeEdit consists +    of three sections, one each for the hour, minute and second. The +    character that separates each date section is specified with +    setDateSeparator(); similarly setTimeSeparator() is used for the +    time sections. + +    \img datetimewidgets.png Date Time Widgets + +    \sa TQDateEdit TQTimeEdit +*/ + +/*! +    Constructs an empty datetime edit with tqparent \a tqparent and called +    \a name. +*/ +TQDateTimeEdit::TQDateTimeEdit( TQWidget * tqparent, const char * name ) +    : TQWidget( tqparent, name ) +{ +    init(); +} + + +/*! +    \overload + +    Constructs a datetime edit with the initial value \a datetime, +    tqparent \a tqparent and called \a name. +*/ +TQDateTimeEdit::TQDateTimeEdit( const TQDateTime& datetime, +			      TQWidget * tqparent, const char * name ) +    : TQWidget( tqparent, name ) +{ +    init(); +    setDateTime( datetime ); +} + + + +/*! +    Destroys the object and frees any allocated resources. +*/ + +TQDateTimeEdit::~TQDateTimeEdit() +{ +    delete d; +} + + +/*! +    \reimp + +    Intercepts and handles resize events which have special meaning +    for the TQDateTimeEdit. +*/ + +void TQDateTimeEdit::resizeEvent( TQResizeEvent * ) +{ +    int dw = de->tqsizeHint().width(); +    int tw = te->tqsizeHint().width(); +    int w = width(); +    int h = height(); +    int extra = w - ( dw + tw ); + +    if ( tw + extra < 0 ) { +	dw = w; +    } else { +	dw += 9 * extra / 16; +    } +    tw = w - dw; + +    de->setGeometry( 0, 0, dw, h ); +    te->setGeometry( dw, 0, tw, h ); +} + +/*! \reimp +*/ + +TQSize TQDateTimeEdit::tqminimumSizeHint() const +{ +    TQSize dsh = de->tqminimumSizeHint(); +    TQSize tsh = te->tqminimumSizeHint(); +    return TQSize( dsh.width() + tsh.width(), +		  TQMAX( dsh.height(), tsh.height() ) ); +} + +/*!  \internal + */ + +void TQDateTimeEdit::init() +{ +    d = new TQDateTimeEditPrivate(); +    de = new TQDateEdit( this, "qt_datetime_dateedit" ); +    te = new TQTimeEdit( this, "qt_datetime_timeedit" ); +    d->adv = FALSE; +    connect( de, TQT_SIGNAL( valueChanged(const TQDate&) ), +	     this, TQT_SLOT( newValue(const TQDate&) ) ); +    connect( te, TQT_SIGNAL( valueChanged(const TQTime&) ), +	     this, TQT_SLOT( newValue(const TQTime&) ) ); +    setFocusProxy( de ); +    tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); +} + +/*! \reimp + */ + +TQSize TQDateTimeEdit::tqsizeHint() const +{ +    constPolish(); +    TQSize dsh = de->tqsizeHint(); +    TQSize tsh = te->tqsizeHint(); +    return TQSize( dsh.width() + tsh.width(), +		  TQMAX( dsh.height(), tsh.height() ) ); +} + +/*! +    \property TQDateTimeEdit::dateTime +    \brief the editor's datetime value + +    The datetime edit's datetime which may be an invalid datetime. +*/ + +void TQDateTimeEdit::setDateTime( const TQDateTime & dt ) +{ +    if ( dt.isValid() ) { +	de->setDate( TQT_TQDATE_OBJECT(dt.date()) ); +	te->setTime( TQT_TQTIME_OBJECT(dt.time()) ); +	emit valueChanged( dt ); +    } +} + +TQDateTime TQDateTimeEdit::dateTime() const +{ +    return TQDateTime( de->date(), te->time() ); +} + +/*! +    \fn void TQDateTimeEdit::valueChanged( const TQDateTime& datetime ) + +    This signal is emitted every time the date or time changes. The \a +    datetime argument is the new datetime. +*/ + + +/*! \internal + +  Re-emits the value \a d. + */ + +void TQDateTimeEdit::newValue( const TQDate& ) +{ +    TQDateTime dt = dateTime(); +    emit valueChanged( dt ); +} + +/*! \internal +  \overload +  Re-emits the value \a t. + */ + +void TQDateTimeEdit::newValue( const TQTime& ) +{ +    TQDateTime dt = dateTime(); +    emit valueChanged( dt ); +} + + +/*! +    Sets the auto advance property of the editor to \a advance. If set +    to TRUE, the editor will automatically advance focus to the next +    date or time section if the user has completed a section. +*/ + +void TQDateTimeEdit::setAutoAdvance( bool advance ) +{ +    de->setAutoAdvance( advance ); +    te->setAutoAdvance( advance ); +} + +/*! +    Returns TRUE if auto-advance is enabled, otherwise returns FALSE. + +    \sa setAutoAdvance() +*/ + +bool TQDateTimeEdit::autoAdvance() const +{ +    return de->autoAdvance(); +} + +/*! +    \fn TQDateEdit* TQDateTimeEdit::dateEdit() + +    Returns the internal widget used for editing the date part of the +    datetime. +*/ + +/*! +    \fn TQTimeEdit* TQDateTimeEdit::timeEdit() + +    Returns the internal widget used for editing the time part of the +    datetime. +*/ + +#include "tqdatetimeedit.tqmoc" + +#endif | 
