korganizer Library API Documentation

ktimeedit.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 1999 Preston Brown, Ian Dawes
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (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
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qkeycode.h>
00025 #include <qcombobox.h>
00026 #include <qdatetime.h>
00027 #include <qlineedit.h>
00028 
00029 #include <kmessagebox.h>
00030 #include <kglobal.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 
00034 #include "ktimeedit.h"
00035 #include <qvalidator.h>
00036 #include "ktimeedit.moc"
00037 
00038 // Validator for a time value with only hours and minutes (no seconds)
00039 // Mostly locale aware. Author: David Faure <faure@kde.org>
00040 class KOTimeValidator : public QValidator
00041 {
00042 public:
00043     KOTimeValidator(QWidget* parent, const char* name=0) : QValidator(parent, name) {}
00044 
00045     virtual State validate(QString& str, int& /*cursorPos*/) const
00046     {
00047         int length = str.length();
00048         // empty string is intermediate so one can clear the edit line and start from scratch
00049         if ( length <= 0 ) 
00050             return Intermediate;
00051         
00052         bool ok = false;
00053         /*QTime time =*/ KGlobal::locale()->readTime(str, KLocale::WithoutSeconds, &ok);
00054         if ( ok )
00055             return Acceptable;
00056 //         kdDebug(5850)<<"Time "<<str<<" not directly acceptable, trying military format "<<endl;
00057         // Also try to accept times in "military format", i.e. no delimiter, like 1200
00058         int tm = str.toInt( &ok );
00059         if ( ok && ( 0 <= tm ) ) {
00060           if ( ( tm < 2400 ) && ( tm%100 < 60 ) )
00061             return Acceptable;
00062           else 
00063             return Intermediate;
00064         }
00065 //         kdDebug(5850)<<str<<" not acceptable or intermediate for military format, either "<<str<<endl;
00066         
00067         // readTime doesn't help knowing when the string is "Intermediate".
00068         // HACK. Not fully locale aware etc. (esp. the separator is '.' in sv_SE...)
00069         QChar sep = ':';
00070         // I want to allow "HH:", ":MM" and ":" to make editing easier
00071         if ( str[0] == sep )
00072         {
00073             if ( length == 1 ) // just ":"
00074                 return Intermediate;
00075             QString minutes = str.mid(1);
00076             int m = minutes.toInt(&ok);
00077             if ( ok && m >= 0 && m < 60 )
00078                 return Intermediate;
00079         } else if ( str[str.length()-1] == sep )
00080         {
00081             QString hours = str.left(length-1);
00082             int h = hours.toInt(&ok);
00083             if ( ok && h >= 0 && h < 24 )
00084                 return Intermediate;
00085         }
00086         return Invalid;
00087     }
00088     virtual void fixup ( QString & input ) const {
00089       bool ok = false;
00090       KGlobal::locale()->readTime( input, KLocale::WithoutSeconds, &ok );
00091       if ( !ok ) {
00092         // Also try to accept times in "military format", i.e. no delimiter, like 1200
00093         int tm = input.toInt( &ok );
00094         if ( ( 0 <= tm ) && ( tm < 2400 ) && ( tm%100 < 60 ) && ok ) {
00095           input = KGlobal::locale()->formatTime( QTime( tm / 100, tm % 100, 0 ) );
00096         }
00097       }
00098     }
00099 };
00100 
00101 // KTimeWidget/QTimeEdit provide nicer editing, but don't provide a combobox.
00102 // Difficult to get all in one...
00103 // But Qt-3.2 will offer QLineEdit::setMask, so a "99:99" mask would help.
00104 KOTimeEdit::KOTimeEdit( QWidget *parent, QTime qt, const char *name )
00105   : QComboBox( true, parent, name )
00106 {
00107   setInsertionPolicy( NoInsertion );
00108   setValidator( new KOTimeValidator( this ) );
00109 
00110   mTime = qt;
00111 
00112 //  mNoTimeString = i18n("No Time");
00113 //  insertItem( mNoTimeString );
00114 
00115   // Fill combo box with selection of times in localized format.
00116   QTime timeEntry(0,0,0);
00117   do {
00118     insertItem(KGlobal::locale()->formatTime(timeEntry));
00119     timeEntry = timeEntry.addSecs(60*15);
00120   } while (!timeEntry.isNull());
00121   // Add end of day.
00122   insertItem( KGlobal::locale()->formatTime( QTime( 23, 59, 59 ) ) );
00123 
00124   updateText();
00125   setFocusPolicy(QWidget::StrongFocus);
00126 
00127   connect(this, SIGNAL(activated(int)), this, SLOT(active(int)));
00128   connect(this, SIGNAL(highlighted(int)), this, SLOT(hilit(int)));
00129   connect(this, SIGNAL(textChanged(const QString&)),this,SLOT(changedText()));
00130 }
00131 
00132 KOTimeEdit::~KOTimeEdit()
00133 {
00134 }
00135 
00136 bool KOTimeEdit::hasTime() const
00137 {
00138   // Can't happen
00139   if ( currentText().isEmpty() ) return false;
00140   //if ( currentText() == mNoTimeString ) return false;
00141 
00142   return true; // always
00143 }
00144 
00145 QTime KOTimeEdit::getTime() const
00146 {
00147   //kdDebug(5850) << "KOTimeEdit::getTime(), currentText() = " << currentText() << endl;
00148   // TODO use KLocale::WithoutSeconds in HEAD
00149   bool ok = false;
00150   QTime time = KGlobal::locale()->readTime( currentText(), KLocale::WithoutSeconds, &ok );
00151   if ( !ok ) {
00152     // Also try to accept times in "military format", i.e. no delimiter, like 1200
00153     int tm = currentText().toInt( &ok );
00154     if ( ( 0 <= tm ) && ( tm < 2400 ) && ( tm%100 < 60 ) && ok ) {
00155       time.setHMS( tm / 100, tm % 100, 0 );
00156     } else {
00157       ok = false;
00158     }
00159   }
00160   kdDebug(5850) << "KOTimeEdit::getTime(): " << time.toString() << endl;
00161   return time;
00162 }
00163 
00164 QSizePolicy  KOTimeEdit::sizePolicy() const
00165 {
00166   // Set size policy to Fixed, because edit cannot contain more text than the
00167   // string representing the time. It doesn't make sense to provide more space.
00168   QSizePolicy sizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
00169 
00170   return sizePolicy;
00171 }
00172 
00173 void KOTimeEdit::setTime(QTime newTime)
00174 {
00175   if ( mTime != newTime )
00176   {
00177     kdDebug(5850) << "KOTimeEdit::setTime(): " << newTime.toString() << endl;
00178 
00179     mTime = newTime;
00180     updateText();
00181   }
00182 }
00183 
00184 void KOTimeEdit::active(int i)
00185 {
00186     // The last entry, 23:59, is a special case
00187     if( i == count() - 1 )
00188         mTime = QTime( 23, 59, 0 );
00189     else
00190         mTime = QTime(0,0,0).addSecs(i*15*60);
00191     emit timeChanged(mTime);
00192 }
00193 
00194 void KOTimeEdit::hilit(int )
00195 {
00196   // we don't currently need to do anything here.
00197 }
00198 
00199 void KOTimeEdit::addTime(QTime qt)
00200 {
00201   // Calculate the new time.
00202   mTime = qt.addSecs(mTime.minute()*60+mTime.hour()*3600);
00203   updateText();
00204   emit timeChanged(mTime);
00205 }
00206 
00207 void KOTimeEdit::subTime(QTime qt)
00208 {
00209   int h, m;
00210 
00211   // Note that we cannot use the same method for determining the new
00212   // time as we did in addTime, because QTime does not handle adding
00213   // negative seconds well at all.
00214   h = mTime.hour()-qt.hour();
00215   m = mTime.minute()-qt.minute();
00216 
00217   if(m < 0) {
00218     m += 60;
00219     h -= 1;
00220   }
00221 
00222   if(h < 0) {
00223     h += 24;
00224   }
00225 
00226   // store the newly calculated time.
00227   mTime.setHMS(h, m, 0);
00228   updateText();
00229   emit timeChanged(mTime);
00230 }
00231 
00232 void KOTimeEdit::keyPressEvent(QKeyEvent *qke)
00233 {
00234   switch(qke->key()) {
00235   case Key_Down:
00236     addTime(QTime(0,1,0));
00237     break;
00238   case Key_Up:
00239     subTime(QTime(0,1,0));
00240     break;
00241   case Key_Prior:
00242     subTime(QTime(1,0,0));
00243     break;
00244   case Key_Next:
00245     addTime(QTime(1,0,0));
00246     break;
00247   default:
00248     QComboBox::keyPressEvent(qke);
00249     break;
00250   } // switch
00251 }
00252 
00253 void KOTimeEdit::updateText()
00254 {
00255 //  kdDebug(5850) << "KOTimeEdit::updateText() " << endl;
00256   QString s = KGlobal::locale()->formatTime(mTime);
00257   // Set the text but without emitting signals, nor losing the cursor position
00258   QLineEdit *line = lineEdit();
00259   line->blockSignals(true);
00260   int pos = line->cursorPosition();
00261   line->setText(s);
00262   line->setCursorPosition(pos);
00263   line->blockSignals(false);
00264 
00265 //  kdDebug(5850) << "KOTimeEdit::updateText(): " << s << endl;
00266 
00267   if (!mTime.minute() % 15) {
00268     setCurrentItem((mTime.hour()*4)+(mTime.minute()/15));
00269   }
00270 }
00271 
00272 bool KOTimeEdit::inputIsValid() const
00273 {
00274   int cursorPos = lineEdit()->cursorPosition();
00275   QString str = currentText();
00276   return validator()->validate( str, cursorPos ) == QValidator::Acceptable;
00277 }
00278 
00279 void KOTimeEdit::changedText()
00280 {
00281   //kdDebug(5850) << "KOTimeEdit::changedText()" << endl;
00282   if ( inputIsValid() )
00283   {
00284     mTime = getTime();
00285     emit timeChanged(mTime);
00286   }
00287 }
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:31 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003