KDEUI
kcombobox.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 00003 Copyright (c) 2000,2001 Dawit Alemayehu <adawit@kde.org> 00004 Copyright (c) 2000,2001 Carsten Pfeiffer <pfeiffer@kde.org> 00005 Copyright (c) 2000 Stefan Schimanski <1Stein@gmx.de> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License (LGPL) as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "kcombobox.h" 00024 00025 #include <QtGui/QClipboard> 00026 #include <QtGui/QLineEdit> 00027 #include <QtGui/QMenu> 00028 #include <QtGui/QApplication> 00029 #include <QtGui/QActionEvent> 00030 00031 #include <kselectaction.h> 00032 #include <kcompletionbox.h> 00033 #include <kcursor.h> 00034 #include <kiconloader.h> 00035 #include <kicontheme.h> 00036 #include <klineedit.h> 00037 #include <klocale.h> 00038 #include <kurl.h> 00039 #include <kicon.h> 00040 00041 #include <kdebug.h> 00042 00043 class KComboBox::KComboBoxPrivate 00044 { 00045 public: 00046 KComboBoxPrivate() : klineEdit(0L), trapReturnKey(false) 00047 { 00048 } 00049 ~KComboBoxPrivate() 00050 { 00051 } 00052 00053 KLineEdit *klineEdit; 00054 bool trapReturnKey; 00055 }; 00056 00057 KComboBox::KComboBox( QWidget *parent ) 00058 : QComboBox( parent ), d(new KComboBoxPrivate) 00059 { 00060 init(); 00061 } 00062 00063 KComboBox::KComboBox( bool rw, QWidget *parent ) 00064 : QComboBox( parent ), d(new KComboBoxPrivate) 00065 { 00066 init(); 00067 setEditable( rw ); 00068 } 00069 00070 KComboBox::~KComboBox() 00071 { 00072 delete d; 00073 } 00074 00075 void KComboBox::init() 00076 { 00077 // Permanently set some parameters in the parent object. 00078 QComboBox::setAutoCompletion( false ); 00079 00080 // Enable context menu by default if widget 00081 // is editable. 00082 if (lineEdit()) { 00083 lineEdit()->setContextMenuPolicy( Qt::DefaultContextMenu ); 00084 } 00085 } 00086 00087 00088 bool KComboBox::contains( const QString& _text ) const 00089 { 00090 if ( _text.isEmpty() ) 00091 return false; 00092 00093 const int itemCount = count(); 00094 for (int i = 0; i < itemCount; ++i ) 00095 { 00096 if ( itemText(i) == _text ) 00097 return true; 00098 } 00099 return false; 00100 } 00101 00102 int KComboBox::cursorPosition() const 00103 { 00104 return ( lineEdit() ) ? lineEdit()->cursorPosition() : -1; 00105 } 00106 00107 void KComboBox::setAutoCompletion( bool autocomplete ) 00108 { 00109 if ( d->klineEdit ) 00110 { 00111 if ( autocomplete ) 00112 { 00113 d->klineEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); 00114 setCompletionMode( KGlobalSettings::CompletionAuto ); 00115 } 00116 else 00117 { 00118 d->klineEdit->setCompletionMode( KGlobalSettings::completionMode() ); 00119 setCompletionMode( KGlobalSettings::completionMode() ); 00120 } 00121 } 00122 } 00123 00124 bool KComboBox::autoCompletion() const 00125 { 00126 return completionMode() == KGlobalSettings::CompletionAuto; 00127 } 00128 00129 #ifndef KDE_NO_DEPRECATED 00130 void KComboBox::setContextMenuEnabled( bool showMenu ) 00131 { 00132 if( d->klineEdit ) 00133 d->klineEdit->setContextMenuEnabled( showMenu ); 00134 } 00135 #endif 00136 00137 00138 void KComboBox::setUrlDropsEnabled( bool enable ) 00139 { 00140 if ( d->klineEdit ) 00141 d->klineEdit->setUrlDropsEnabled( enable ); 00142 } 00143 00144 bool KComboBox::urlDropsEnabled() const 00145 { 00146 return d->klineEdit && d->klineEdit->urlDropsEnabled(); 00147 } 00148 00149 00150 void KComboBox::setCompletedText( const QString& text, bool marked ) 00151 { 00152 if ( d->klineEdit ) 00153 d->klineEdit->setCompletedText( text, marked ); 00154 } 00155 00156 void KComboBox::setCompletedText( const QString& text ) 00157 { 00158 if ( d->klineEdit ) 00159 d->klineEdit->setCompletedText( text ); 00160 } 00161 00162 void KComboBox::makeCompletion( const QString& text ) 00163 { 00164 if( d->klineEdit ) 00165 d->klineEdit->makeCompletion( text ); 00166 00167 else // read-only combo completion 00168 { 00169 if( text.isNull() || !view() ) 00170 return; 00171 00172 view()->keyboardSearch(text); 00173 } 00174 } 00175 00176 void KComboBox::rotateText( KCompletionBase::KeyBindingType type ) 00177 { 00178 if ( d->klineEdit ) 00179 d->klineEdit->rotateText( type ); 00180 } 00181 00182 // Not needed anymore 00183 bool KComboBox::eventFilter( QObject* o, QEvent* ev ) 00184 { 00185 return QComboBox::eventFilter( o, ev ); 00186 } 00187 00188 void KComboBox::setTrapReturnKey( bool grab ) 00189 { 00190 d->trapReturnKey = grab; 00191 00192 if ( d->klineEdit ) 00193 d->klineEdit->setTrapReturnKey( grab ); 00194 else 00195 qWarning("KComboBox::setTrapReturnKey not supported with a non-KLineEdit."); 00196 } 00197 00198 bool KComboBox::trapReturnKey() const 00199 { 00200 return d->trapReturnKey; 00201 } 00202 00203 00204 void KComboBox::setEditUrl( const KUrl& url ) 00205 { 00206 QComboBox::setEditText( url.prettyUrl() ); 00207 } 00208 00209 void KComboBox::addUrl( const KUrl& url ) 00210 { 00211 QComboBox::addItem( url.prettyUrl() ); 00212 } 00213 00214 void KComboBox::addUrl( const QIcon& icon, const KUrl& url ) 00215 { 00216 QComboBox::addItem( icon, url.prettyUrl() ); 00217 } 00218 00219 void KComboBox::insertUrl( int index, const KUrl& url ) 00220 { 00221 QComboBox::insertItem( index, url.prettyUrl() ); 00222 } 00223 00224 void KComboBox::insertUrl( int index, const QIcon& icon, const KUrl& url ) 00225 { 00226 QComboBox::insertItem( index, icon, url.prettyUrl() ); 00227 } 00228 00229 void KComboBox::changeUrl( int index, const KUrl& url ) 00230 { 00231 QComboBox::setItemText( index, url.prettyUrl() ); 00232 } 00233 00234 void KComboBox::changeUrl( int index, const QIcon& icon, const KUrl& url ) 00235 { 00236 QComboBox::setItemIcon( index, icon ); 00237 QComboBox::setItemText( index, url.prettyUrl() ); 00238 } 00239 00240 void KComboBox::setCompletedItems( const QStringList& items, bool autosubject ) 00241 { 00242 if ( d->klineEdit ) 00243 d->klineEdit->setCompletedItems( items, autosubject ); 00244 } 00245 00246 KCompletionBox * KComboBox::completionBox( bool create ) 00247 { 00248 if ( d->klineEdit ) 00249 return d->klineEdit->completionBox( create ); 00250 return 0; 00251 } 00252 00253 // QWidget::create() turns off mouse-Tracking which would break auto-hiding 00254 void KComboBox::create( WId id, bool initializeWindow, bool destroyOldWindow ) 00255 { 00256 QComboBox::create( id, initializeWindow, destroyOldWindow ); 00257 KCursor::setAutoHideCursor( lineEdit(), true, true ); 00258 } 00259 00260 void KComboBox::wheelEvent( QWheelEvent *ev ) 00261 { 00262 // Not necessary anymore 00263 QComboBox::wheelEvent( ev ); 00264 } 00265 00266 QSize KComboBox::minimumSizeHint() const 00267 { 00268 QSize size = QComboBox::minimumSizeHint(); 00269 if (isEditable() && d->klineEdit) { 00270 // if it's a KLineEdit and it's editable add the clear button size 00271 // to the minimum size hint, otherwise looks ugly because the 00272 // clear button will cover the last 2/3 letters of the biggest entry 00273 QSize bs = d->klineEdit->clearButtonUsedSize(); 00274 if (bs.isValid()) { 00275 size.rwidth() += bs.width(); 00276 size.rheight() = qMax(size.height(), bs.height()); 00277 } 00278 } 00279 return size; 00280 } 00281 00282 void KComboBox::setLineEdit( QLineEdit *edit ) 00283 { 00284 if ( !isEditable() && edit && 00285 !qstrcmp( edit->metaObject()->className(), "QLineEdit" ) ) 00286 { 00287 // uic generates code that creates a read-only KComboBox and then 00288 // calls combo->setEditable( true ), which causes QComboBox to set up 00289 // a dumb QLineEdit instead of our nice KLineEdit. 00290 // As some KComboBox features rely on the KLineEdit, we reject 00291 // this order here. 00292 delete edit; 00293 KLineEdit* kedit = new KLineEdit( this ); 00294 00295 if ( isEditable() ) { 00296 kedit->setClearButtonShown( true ); 00297 } 00298 00299 edit = kedit; 00300 } 00301 00302 QComboBox::setLineEdit( edit ); 00303 d->klineEdit = qobject_cast<KLineEdit*>( edit ); 00304 setDelegate( d->klineEdit ); 00305 00306 // Connect the returnPressed signal for both Q[K]LineEdits' 00307 if (edit) 00308 connect( edit, SIGNAL( returnPressed() ), SIGNAL( returnPressed() )); 00309 00310 if ( d->klineEdit ) 00311 { 00312 // someone calling KComboBox::setEditable( false ) destroys our 00313 // lineedit without us noticing. And KCompletionBase::delegate would 00314 // be a dangling pointer then, so prevent that. Note: only do this 00315 // when it is a KLineEdit! 00316 connect( edit, SIGNAL( destroyed() ), SLOT( lineEditDeleted() )); 00317 00318 connect( d->klineEdit, SIGNAL( returnPressed( const QString& )), 00319 SIGNAL( returnPressed( const QString& ) )); 00320 00321 connect( d->klineEdit, SIGNAL( completion( const QString& )), 00322 SIGNAL( completion( const QString& )) ); 00323 00324 connect( d->klineEdit, SIGNAL( substringCompletion( const QString& )), 00325 SIGNAL( substringCompletion( const QString& )) ); 00326 00327 connect( d->klineEdit, 00328 SIGNAL( textRotation( KCompletionBase::KeyBindingType )), 00329 SIGNAL( textRotation( KCompletionBase::KeyBindingType )) ); 00330 00331 connect( d->klineEdit, 00332 SIGNAL( completionModeChanged( KGlobalSettings::Completion )), 00333 SIGNAL( completionModeChanged( KGlobalSettings::Completion))); 00334 00335 connect( d->klineEdit, 00336 SIGNAL( aboutToShowContextMenu( QMenu * )), 00337 SIGNAL( aboutToShowContextMenu( QMenu * )) ); 00338 00339 connect( d->klineEdit, 00340 SIGNAL( completionBoxActivated( const QString& )), 00341 SIGNAL( activated( const QString& )) ); 00342 00343 d->klineEdit->setTrapReturnKey( d->trapReturnKey ); 00344 } 00345 } 00346 00347 void KComboBox::setCurrentItem( const QString& item, bool insert, int index ) 00348 { 00349 int sel = -1; 00350 00351 const int itemCount = count(); 00352 for (int i = 0; i < itemCount; ++i) 00353 { 00354 if (itemText(i) == item) 00355 { 00356 sel = i; 00357 break; 00358 } 00359 } 00360 00361 if (sel == -1 && insert) 00362 { 00363 if (index >= 0) { 00364 insertItem(index, item); 00365 sel = index; 00366 } else { 00367 addItem(item); 00368 sel = count() - 1; 00369 } 00370 } 00371 setCurrentIndex(sel); 00372 } 00373 00374 void KComboBox::lineEditDeleted() 00375 { 00376 // yes, we need those ugly casts due to the multiple inheritance 00377 // sender() is guaranteed to be a KLineEdit (see the connect() to the 00378 // destroyed() signal 00379 const KCompletionBase *base = static_cast<const KCompletionBase*>( static_cast<const KLineEdit*>( sender() )); 00380 00381 // is it our delegate, that is destroyed? 00382 if ( base == delegate() ) 00383 setDelegate( 0L ); 00384 } 00385 00386 void KComboBox::setEditable(bool editable) 00387 { 00388 if (editable) { 00389 // Create a KLineEdit instead of a QLineEdit 00390 // Compared to QComboBox::setEditable, we might be missing the SH_ComboBox_Popup code though... 00391 // If a style needs this, then we'll need to call QComboBox::setEditable and then setLineEdit again 00392 KLineEdit *edit = new KLineEdit( this ); 00393 edit->setClearButtonShown( true ); 00394 setLineEdit( edit ); 00395 } else { 00396 QComboBox::setEditable(editable); 00397 } 00398 } 00399 00400 #include "kcombobox.moc"
KDE 4.6 API Reference