Logo Search packages:      
Sourcecode: datakiosk version File versions  Download package

dateedit.cpp

/***************************************************************************
*   Copyright (C) 2005 by Adam Treat                                      *
*   treat@kde.org                                                         *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/

/***************************************************************************
*   This file adapted from libkdepim kdateedit.cpp                        *
*                                                                         *
*   Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>          *
*   Copyright (c) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>   *
*   Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>                      *
*                                                                         *
***************************************************************************/

/*
    If you have any questions about how this class works, please see the
    version in libkdepim.  Hopefully these classes will be cleaned up and
    put in kdelibs for KDE4.
*/

#include <qapplication.h>
#include <qlineedit.h>
#include <qlistbox.h>
#include <qvalidator.h>
#include <qvbox.h>

#include <kcalendarsystem.h>
#include <kdatepicker.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <klocale.h>

#include <kdebug.h>

#include "dateedit.h"

class DateValidator : public QValidator
{
public:
    DateValidator( const QStringList &keywords, QWidget* parent,
                   const char* name = 0 )
            : QValidator( parent, name ), mKeywords( keywords )
    {}

    virtual State validate( QString &str, int& ) const
    {
        int length = str.length();

        if ( length <= 0 )
            return Intermediate;

        if ( mKeywords.contains( str.lower() ) )
            return Acceptable;

        bool ok = false;
        KGlobal::locale() ->readDate( str, &ok );
        if ( ok )
            return Acceptable;
        else
            return Intermediate;
    }

private:
    QStringList mKeywords;
};

DateEdit::DateEdit( DataField* field, DataTable *dataTable,
                    QWidget *parent, const char *name )
        : DataComboBox( field, dataTable, true, parent, name ),
        mReadOnly( false ),
        mDiscardNextMousePress( false )
{
    setMaxCount( 1 );

    mDate = QDate::currentDate();
    QString today = KGlobal::locale() ->formatDate( mDate, true );

    insertItem( today );
    setCurrentItem( 0 );
    changeItem( today, 0 );
    setMinimumSize( sizeHint() );

    mDateFrame = new QVBox( 0, 0, WType_Popup );
    mDateFrame->setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
    mDateFrame->setLineWidth( 3 );
    mDateFrame->hide();
    mDateFrame->installEventFilter( this );

    mDatePicker = new KDatePicker( mDateFrame, mDate );

    connect( lineEdit(), SIGNAL( returnPressed() ),
             this, SLOT( lineEnterPressed() ) );
    connect( this, SIGNAL( textChanged( const QString& ) ),
             SLOT( slotTextChanged( const QString& ) ) );

    connect( mDatePicker, SIGNAL( dateEntered( QDate ) ),
             SLOT( dateEntered( QDate ) ) );
    connect( mDatePicker, SIGNAL( dateSelected( QDate ) ),
             SLOT( dateSelected( QDate ) ) );

    setupKeywords();
    lineEdit() ->installEventFilter( this );

//     setValidator( new DateValidator( mKeywordMap.keys(), this ) );

    mTextChanged = false;
}

DateEdit::~DateEdit()
{
    delete mDateFrame;
    mDateFrame = 0;
}

void DateEdit::setDate( const QDate& date )
{
    assignDate( date );
    updateView();
}

QDate DateEdit::date() const
{
    return mDate;
}

void DateEdit::setReadOnly( bool readOnly )
{
    mReadOnly = readOnly;
    lineEdit() ->setReadOnly( readOnly );
}

bool DateEdit::isReadOnly() const
{
    return mReadOnly;
}

void DateEdit::popup()
{
    if ( mReadOnly )
        return ;

    QRect desk = KGlobalSettings::desktopGeometry( this );

    QPoint popupPoint = mapToGlobal( QPoint( 0, 0 ) );

    int dateFrameHeight = mDateFrame->sizeHint().height();
    if ( popupPoint.y() + height() + dateFrameHeight > desk.bottom() )
        popupPoint.setY( popupPoint.y() - dateFrameHeight );
    else
        popupPoint.setY( popupPoint.y() + height() );

    int dateFrameWidth = mDateFrame->sizeHint().width();
    if ( popupPoint.x() + dateFrameWidth > desk.right() )
        popupPoint.setX( desk.right() - dateFrameWidth );

    if ( popupPoint.x() < desk.left() )
        popupPoint.setX( desk.left() );

    if ( popupPoint.y() < desk.top() )
        popupPoint.setY( desk.top() );

    mDateFrame->move( popupPoint );

    if ( mDate.isValid() )
        mDatePicker->setDate( mDate );
    else
        mDatePicker->setDate( QDate::currentDate() );

    mDateFrame->show();

    QDate date = parseDate();
    assignDate( date );
    updateView();
    QListBox *lb = listBox();
    if ( lb )
    {
        lb->setCurrentItem( 0 );
        QKeyEvent* keyEvent = new QKeyEvent( QEvent::KeyPress,
                                             Qt::Key_Enter, 0, 0 );
        QApplication::postEvent( lb, keyEvent );
    }
}

void DateEdit::dateSelected( QDate date )
{
    assignDate( date );
    updateView();
    emit dateChanged( date );

    if ( date.isValid() )
        mDateFrame->hide();
}

void DateEdit::dateEntered( QDate date )
{
    assignDate( date );
    updateView();
    emit dateChanged( date );
}

void DateEdit::lineEnterPressed()
{
    bool replaced = false;

    QDate date = parseDate( &replaced );

    assignDate( date );
    if ( replaced )
        updateView();

    emit dateChanged( date );
}

QDate DateEdit::parseDate( bool *replaced ) const
{
    QString text = currentText();
    QDate result;

    if ( replaced )
        ( *replaced ) = false;

    if ( text.isEmpty() )
        result = QDate();
    else if ( mKeywordMap.contains( text.lower() ) )
    {
        QDate today = QDate::currentDate();
        int i = mKeywordMap[ text.lower() ];
        if ( i >= 100 )
        {
            i -= 100;
            int currentDay = today.dayOfWeek();
            if ( i >= currentDay )
                i -= currentDay;
            else
                i += 7 - currentDay;
        }

        result = today.addDays( i );
        if ( replaced )
            ( *replaced ) = true;
    }
    else
    {
        result = KGlobal::locale() ->readDate( text );
    }

    return result;
}

bool DateEdit::eventFilter( QObject *object, QEvent *event )
{
    if ( object == lineEdit() )
    {
        if ( ( event->type() == QEvent::FocusOut ) && mTextChanged )
        {
            lineEnterPressed();
            mTextChanged = false;
        }
        else if ( event->type() == QEvent::KeyPress )
        {
            QKeyEvent * keyEvent = ( QKeyEvent* ) event;

            if ( keyEvent->key() == Qt::Key_Return )
            {
                lineEnterPressed();
                return true;
            }

            int step = 0;
            if ( keyEvent->key() == Qt::Key_Up )
                step = 1;
            else if ( keyEvent->key() == Qt::Key_Down )
                step = -1;
            if ( step && !mReadOnly )
            {
                QDate date = parseDate();
                if ( date.isValid() )
                {
                    date = date.addDays( step );
                    assignDate( date );
                    updateView();
                    emit dateChanged( date );
                    return true;
                }
            }
        }
    }
    else
    {
        switch ( event->type() )
        {
        case QEvent::MouseButtonDblClick:
        case QEvent::MouseButtonPress:
            {
                QMouseEvent * mouseEvent = ( QMouseEvent* ) event;
                if ( !mDateFrame->rect().contains( mouseEvent->pos() ) )
                {
                    QPoint globalPos = mDateFrame->mapToGlobal(
                        mouseEvent->pos() );
                    if ( QApplication::widgetAt( globalPos, true ) == this )
                    {
                        mDiscardNextMousePress = true;
                    }
                }

                break;
            }
        default:
            break;
        }
    }

    return false;
}

void DateEdit::mousePressEvent( QMouseEvent *event )
{
    if ( event->button() == Qt::LeftButton && mDiscardNextMousePress )
    {
        mDiscardNextMousePress = false;
        return ;
    }

    QComboBox::mousePressEvent( event );
}

void DateEdit::slotTextChanged( const QString& )
{
    QDate date = parseDate();

    assignDate( date );
    emit dateChanged( date );

    mTextChanged = true;
}

void DateEdit::setupKeywords()
{
    mKeywordMap.insert( i18n( "tomorrow" ), 1 );
    mKeywordMap.insert( i18n( "today" ), 0 );
    mKeywordMap.insert( i18n( "yesterday" ), -1 );

    QString dayName;
    for ( int i = 1; i <= 7; ++i )
    {
        dayName = KGlobal::locale() ->calendar() ->weekDayName( i ).lower();
        mKeywordMap.insert( dayName, i + 100 );
    }
}

void DateEdit::assignDate( const QDate& date )
{
    mDate = date;
    mTextChanged = false;
}

void DateEdit::updateView()
{
    QString dateString;
    if ( mDate.isValid() )
        dateString = KGlobal::locale() ->formatDate( mDate, true );

    bool blocked = signalsBlocked();
    blockSignals( true );
    changeItem( dateString, 0 );
    blockSignals( blocked );
}

#include "dateedit.moc"

Generated by  Doxygen 1.6.0   Back to index