libkdepim 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(5300)<<"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(5300)<<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 KTimeEdit::KTimeEdit( 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 KTimeEdit::~KTimeEdit() 00133 { 00134 } 00135 00136 bool KTimeEdit::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 KTimeEdit::getTime() const 00146 { 00147 //kdDebug(5300) << "KTimeEdit::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(5300) << "KTimeEdit::getTime(): " << time.toString() << endl; 00161 return time; 00162 } 00163 00164 QSizePolicy KTimeEdit::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 KTimeEdit::setTime(QTime newTime) 00174 { 00175 if ( mTime != newTime ) 00176 { 00177 kdDebug(5300) << "KTimeEdit::setTime(): " << newTime.toString() << endl; 00178 00179 mTime = newTime; 00180 updateText(); 00181 } 00182 } 00183 00184 void KTimeEdit::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 KTimeEdit::hilit(int ) 00195 { 00196 // we don't currently need to do anything here. 00197 } 00198 00199 void KTimeEdit::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 KTimeEdit::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 KTimeEdit::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 KTimeEdit::updateText() 00254 { 00255 // kdDebug(5300) << "KTimeEdit::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(5300) << "KTimeEdit::updateText(): " << s << endl; 00266 00267 if (!mTime.minute() % 15) { 00268 setCurrentItem((mTime.hour()*4)+(mTime.minute()/15)); 00269 } 00270 } 00271 00272 bool KTimeEdit::inputIsValid() const 00273 { 00274 int cursorPos = lineEdit()->cursorPosition(); 00275 QString str = currentText(); 00276 return validator()->validate( str, cursorPos ) == QValidator::Acceptable; 00277 } 00278 00279 void KTimeEdit::changedText() 00280 { 00281 //kdDebug(5300) << "KTimeEdit::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 libkdepim Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:29 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003