kexi

kexidblineedit.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This program is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this program; see the file COPYING.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kexidblineedit.h"
00022 #include "kexidbautofield.h"
00023 
00024 #include <kdebug.h>
00025 #include <knumvalidator.h>
00026 #include <kdatetbl.h>
00027 
00028 #include <qpopupmenu.h>
00029 #include <qpainter.h>
00030 
00031 #include <kexiutils/utils.h>
00032 #include <kexidb/queryschema.h>
00033 #include <kexidb/fieldvalidator.h>
00034 #include <kexiutils/utils.h>
00035 
00037 //#define USE_KLineEdit_setReadOnly
00038 
00040 class KexiDBLineEdit_ReadOnlyValidator : public QValidator
00041 {
00042     public:
00043         KexiDBLineEdit_ReadOnlyValidator( QObject * parent ) 
00044          : QValidator(parent)
00045         {
00046         }
00047         ~KexiDBLineEdit_ReadOnlyValidator() {}
00048         virtual State validate( QString &, int & ) const { return Invalid; }
00049 };
00050 
00051 //-----
00052 
00053 KexiDBLineEdit::KexiDBLineEdit(QWidget *parent, const char *name)
00054  : KLineEdit(parent, name)
00055  , KexiDBTextWidgetInterface()
00056  , KexiFormDataItemInterface()
00057  , m_dateFormatter(0)
00058  , m_timeFormatter(0)
00059  , m_menuExtender(this, this)
00060  , m_internalReadOnly(false)
00061  , m_slotTextChanged_enabled(true)
00062 {
00063 #ifdef USE_KLineEdit_setReadOnly
00065     QPalette p(widget->palette());
00066     p.setColor( lighterGrayBackgroundColor(palette()) );
00067     widget->setPalette(p);
00068 #endif
00069 
00070     connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged(const QString&)));
00071 }
00072 
00073 KexiDBLineEdit::~KexiDBLineEdit()
00074 {
00075     delete m_dateFormatter;
00076     delete m_timeFormatter;
00077 }
00078 
00079 void KexiDBLineEdit::setInvalidState( const QString& displayText )
00080 {
00081     KLineEdit::setReadOnly(true);
00083     if (focusPolicy() & TabFocus)
00084         setFocusPolicy(QWidget::ClickFocus);
00085     setText(displayText);
00086 }
00087 
00088 void KexiDBLineEdit::setValueInternal(const QVariant& add, bool removeOld)
00089 {
00090     QVariant value;
00091     if (removeOld)
00092         value = add;
00093     else {
00094         if (add.toString().isEmpty())
00095             value = m_origValue;
00096         else
00097             value = m_origValue.toString() + add.toString();
00098     }
00099 
00100     if (m_columnInfo) {
00101         const KexiDB::Field::Type t = m_columnInfo->field->type();
00102         if (t == KexiDB::Field::Boolean) {
00104             setText( value.toBool() ? "1" : "0" );
00105             return;
00106         }
00107         else if (t == KexiDB::Field::Date) {
00108             setText( dateFormatter()->dateToString( value.toString().isEmpty() ? QDate() : value.toDate() ) );
00109             setCursorPosition(0); //ok?
00110             return;
00111         }
00112         else if (t == KexiDB::Field::Time) {
00113             setText( 
00114                 timeFormatter()->timeToString( 
00115                     //hack to avoid converting null variant to valid QTime(0,0,0)
00116                     value.toString().isEmpty() ? value.toTime() : QTime(99,0,0) 
00117                 )
00118             );
00119             setCursorPosition(0); //ok?
00120             return;
00121         }
00122         else if (t == KexiDB::Field::DateTime) {
00123             if (value.toString().isEmpty() ) {
00124                 setText( QString::null );
00125             }
00126             else {
00127                 setText(
00128                     dateFormatter()->dateToString( value.toDateTime().date() ) + " " +
00129                     timeFormatter()->timeToString( value.toDateTime().time() )
00130                 );
00131             }
00132             setCursorPosition(0); //ok?
00133             return;
00134         }
00135     }
00136     
00137     m_slotTextChanged_enabled = false;
00138      setText( value.toString() );
00139      setCursorPosition(0); //ok?
00140     m_slotTextChanged_enabled = true;
00141 }
00142 
00143 QVariant KexiDBLineEdit::value()
00144 {
00145     if (! m_columnInfo)
00146         return QVariant();
00147     const KexiDB::Field::Type t = m_columnInfo->field->type();
00148     switch (t) {
00149     case KexiDB::Field::Text:
00150     case KexiDB::Field::LongText:
00151         return text();
00152     case KexiDB::Field::Byte:
00153     case KexiDB::Field::ShortInteger:
00154         return text().toShort();
00156     case KexiDB::Field::Integer:
00157         return text().toInt();
00158     case KexiDB::Field::BigInteger:
00159         return text().toLongLong();
00160     case KexiDB::Field::Boolean:
00162         return text() == "1" ? QVariant(true,1) : QVariant(false,0);
00163     case KexiDB::Field::Date:
00164         return dateFormatter()->stringToVariant( text() );
00165     case KexiDB::Field::Time:
00166         return timeFormatter()->stringToVariant( text() );
00167     case KexiDB::Field::DateTime:
00168         return stringToDateTime(*dateFormatter(), *timeFormatter(), text());
00169     case KexiDB::Field::Float:
00170         return text().toFloat();
00171     case KexiDB::Field::Double:
00172         return text().toDouble();
00173     default:
00174         return QVariant();
00175     }
00177 
00178     return text();
00179 }
00180 
00181 void KexiDBLineEdit::slotTextChanged(const QString&)
00182 {
00183     if (!m_slotTextChanged_enabled)
00184         return;
00185     signalValueChanged();
00186 }
00187 
00188 bool KexiDBLineEdit::valueIsNull()
00189 {
00190     return valueIsEmpty(); //ok??? text().isNull();
00191 }
00192 
00193 bool KexiDBLineEdit::valueIsEmpty()
00194 {
00195     if (text().isEmpty())
00196         return true;
00197 
00198     if (m_columnInfo) {
00199         const KexiDB::Field::Type t = m_columnInfo->field->type();
00200         if (t == KexiDB::Field::Date)
00201             return dateFormatter()->isEmpty( text() );
00202         else if (t == KexiDB::Field::Time)
00203             return timeFormatter()->isEmpty( text() );
00204         else if (t == KexiDB::Field::Time)
00205             return dateTimeIsEmpty( *dateFormatter(), *timeFormatter(), text() );
00206     }
00207 
00209     return text().isEmpty();
00210 }
00211 
00212 bool KexiDBLineEdit::valueIsValid()
00213 {
00214     if (!m_columnInfo)
00215         return true;
00217     if (valueIsEmpty()/*ok?*/)
00218         return true;
00219 
00220     const KexiDB::Field::Type t = m_columnInfo->field->type();
00221     if (t == KexiDB::Field::Date)
00222         return dateFormatter()->stringToVariant( text() ).isValid();
00223     else if (t == KexiDB::Field::Time)
00224         return timeFormatter()->stringToVariant( text() ).isValid();
00225     else if (t == KexiDB::Field::DateTime)
00226         return dateTimeIsValid( *dateFormatter(), *timeFormatter(), text() );
00227 
00229     return true;
00230 }
00231 
00232 bool KexiDBLineEdit::isReadOnly() const
00233 {
00234     return m_internalReadOnly;
00235 }
00236 
00237 void KexiDBLineEdit::setReadOnly( bool readOnly )
00238 {
00239 #ifdef USE_KLineEdit_setReadOnly
00241     return KLineEdit::setReadOnly( readOnly );
00242 #else
00243     m_internalReadOnly = readOnly;
00244     if (m_internalReadOnly) {
00245         m_readWriteValidator = validator();
00246         if (!m_readOnlyValidator)
00247         m_readOnlyValidator = new KexiDBLineEdit_ReadOnlyValidator(this);
00248         setValidator( m_readOnlyValidator );
00249     }
00250     else {
00251         //revert to r/w validator
00252         setValidator( m_readWriteValidator );
00253     }
00254     m_menuExtender.updatePopupMenuActions();
00255 #endif
00256 }
00257 
00258 QPopupMenu * KexiDBLineEdit::createPopupMenu()
00259 {
00260     QPopupMenu *contextMenu = KLineEdit::createPopupMenu();
00261     m_menuExtender.createTitle(contextMenu);
00262     return contextMenu;
00263 }
00264 
00265 
00266 QWidget* KexiDBLineEdit::widget()
00267 {
00268     return this;
00269 }
00270 
00271 bool KexiDBLineEdit::cursorAtStart()
00272 {
00273     return cursorPosition()==0;
00274 }
00275 
00276 bool KexiDBLineEdit::cursorAtEnd()
00277 {
00278     return cursorPosition()==(int)text().length();
00279 }
00280 
00281 void KexiDBLineEdit::clear()
00282 {
00283     if (!m_internalReadOnly)
00284         KLineEdit::clear();
00285 }
00286 
00287 
00288 void KexiDBLineEdit::setColumnInfo(KexiDB::QueryColumnInfo* cinfo)
00289 {
00290     KexiFormDataItemInterface::setColumnInfo(cinfo);
00291     if (!cinfo)
00292         return;
00294     const KexiDB::Field::Type t = cinfo->field->type();
00295 
00296     setValidator( new KexiDB::FieldValidator(*cinfo->field, this) );
00297 
00298     if (t==KexiDB::Field::Date) {
00300         setInputMask( dateFormatter()->inputMask() );
00301     }
00302     else if (t==KexiDB::Field::Time) {
00304 //      setInputMask("00:00:00");
00305         setInputMask( timeFormatter()->inputMask() );
00306     }
00307     else if (t==KexiDB::Field::DateTime) {
00308         setInputMask( 
00309             dateTimeInputMask( *dateFormatter(), *timeFormatter() ) );
00310     }
00311 
00312     KexiDBTextWidgetInterface::setColumnInfo(cinfo, this);
00313 }
00314 
00315 /*todo
00316 void KexiDBLineEdit::paint( QPainter *p )
00317 {
00318     KexiDBTextWidgetInterface::paint( this, &p, text().isEmpty(), alignment(), hasFocus() );
00319 }*/
00320 
00321 void KexiDBLineEdit::paintEvent ( QPaintEvent *pe )
00322 {
00323     KLineEdit::paintEvent( pe );
00324     QPainter p(this);
00325     KexiDBTextWidgetInterface::paint( this, &p, text().isEmpty(), alignment(), hasFocus() );
00326 }
00327 
00328 bool KexiDBLineEdit::event( QEvent * e )
00329 {
00330     const bool ret = KLineEdit::event( e );
00331     KexiDBTextWidgetInterface::event(e, this, text().isEmpty());
00332     if (e->type()==QEvent::FocusOut) {
00333         QFocusEvent *fe = static_cast<QFocusEvent *>(e);
00334 //      if (fe->reason()!=QFocusEvent::ActiveWindow && fe->reason()!=QFocusEvent::Popup) {
00335         if (fe->reason()==QFocusEvent::Tab || fe->reason()==QFocusEvent::Backtab) {
00336         //display aligned to left after loosing the focus (only if this is tab/backtab event)
00338             setCursorPosition(0); //ok?
00339         }
00340     }
00341     return ret;
00342 }
00343 
00344 bool KexiDBLineEdit::appendStretchRequired(KexiDBAutoField* autoField) const
00345 {
00346     return KexiDBAutoField::Top == autoField->labelPosition();
00347 }
00348 
00349 void KexiDBLineEdit::handleAction(const QString& actionName)
00350 {
00351     if (actionName=="edit_copy") {
00352         copy();
00353     }
00354     else if (actionName=="edit_paste") {
00355         paste();
00356     }
00357     else if (actionName=="edit_cut") {
00358         cut();
00359     }
00361 }
00362 
00363 void KexiDBLineEdit::setDisplayDefaultValue(QWidget *widget, bool displayDefaultValue)
00364 {
00365     KexiFormDataItemInterface::setDisplayDefaultValue(widget, displayDefaultValue);
00366     // initialize display parameters for default / entered value
00367     KexiDisplayUtils::DisplayParameters * const params 
00368         = displayDefaultValue ? m_displayParametersForDefaultValue : m_displayParametersForEnteredValue;
00369     setFont(params->font);
00370     QPalette pal(palette());
00371     pal.setColor(QPalette::Active, QColorGroup::Text, params->textColor);
00372     setPalette(pal);
00373 }
00374 
00375 void KexiDBLineEdit::undo()
00376 {
00377     cancelEditor();
00378 }
00379 
00380 void KexiDBLineEdit::moveCursorToEnd()
00381 {
00382     KLineEdit::end(false);
00383 }
00384 
00385 void KexiDBLineEdit::moveCursorToStart()
00386 {
00387     KLineEdit::home(false);
00388 }
00389 
00390 void KexiDBLineEdit::selectAll()
00391 {
00392     KLineEdit::selectAll();
00393 }
00394 
00395 bool KexiDBLineEdit::keyPressed(QKeyEvent *ke)
00396 {
00397     Q_UNUSED(ke);
00398     return false;
00399 }
00400 
00401 #include "kexidblineedit.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys