KDEUI
klistwidget.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "klistwidget.h" 00020 00021 #include <kglobalsettings.h> 00022 #include <kdebug.h> 00023 00024 #include <QtCore/QTimer> 00025 #include <QKeyEvent> 00026 #include <QApplication> 00027 00028 class KListWidget::KListWidgetPrivate 00029 { 00030 public: 00031 KListWidgetPrivate(KListWidget *q) 00032 : q(q), 00033 m_pCurrentItem(0) 00034 { 00035 } 00036 00037 void emitExecute( QListWidgetItem *item, const QPoint &pos ); 00038 00039 void _k_slotItemEntered(QListWidgetItem*); 00040 void _k_slotOnViewport(); 00041 void _k_slotSettingsChanged(int); 00042 void _k_slotAutoSelect(); 00043 00044 KListWidget *q; 00045 bool m_bUseSingle : 1; 00046 bool m_bChangeCursorOverItem : 1; 00047 00048 QListWidgetItem* m_pCurrentItem; 00049 QTimer* m_pAutoSelect; 00050 int m_autoSelectDelay; 00051 }; 00052 00053 KListWidget::KListWidget( QWidget *parent ) 00054 : QListWidget(parent), d(new KListWidgetPrivate(this)) 00055 { 00056 connect( this, SIGNAL( viewportEntered() ), 00057 this, SLOT( _k_slotOnViewport() ) ); 00058 connect( this, SIGNAL( itemEntered( QListWidgetItem * ) ), 00059 this, SLOT( _k_slotItemEntered( QListWidgetItem * ) ) ); 00060 d->_k_slotSettingsChanged(KGlobalSettings::SETTINGS_MOUSE); 00061 connect( KGlobalSettings::self(), SIGNAL( settingsChanged(int) ), SLOT( _k_slotSettingsChanged(int) ) ); 00062 00063 d->m_pAutoSelect = new QTimer( this ); 00064 connect( d->m_pAutoSelect, SIGNAL( timeout() ), 00065 this, SLOT( _k_slotAutoSelect() ) ); 00066 } 00067 00068 KListWidget::~KListWidget() 00069 { 00070 delete d; 00071 } 00072 00073 void KListWidget::KListWidgetPrivate::_k_slotItemEntered( QListWidgetItem *item ) 00074 { 00075 if ( item && m_bChangeCursorOverItem && m_bUseSingle ) 00076 q->viewport()->setCursor( QCursor( Qt::OpenHandCursor ) ); 00077 00078 if ( item && (m_autoSelectDelay > -1) && m_bUseSingle ) { 00079 m_pAutoSelect->setSingleShot( true ); 00080 m_pAutoSelect->start( m_autoSelectDelay ); 00081 m_pCurrentItem = item; 00082 } 00083 } 00084 00085 void KListWidget::KListWidgetPrivate::_k_slotOnViewport() 00086 { 00087 if ( m_bChangeCursorOverItem ) 00088 q->viewport()->unsetCursor(); 00089 00090 m_pAutoSelect->stop(); 00091 m_pCurrentItem = 0; 00092 } 00093 00094 00095 void KListWidget::KListWidgetPrivate::_k_slotSettingsChanged(int category) 00096 { 00097 if (category != KGlobalSettings::SETTINGS_MOUSE) 00098 return; 00099 m_bUseSingle = KGlobalSettings::singleClick(); 00100 00101 q->disconnect(q, SIGNAL(itemClicked( QListWidgetItem *))); 00102 q->disconnect(q, SIGNAL(itemDoubleClicked( QListWidgetItem *))); 00103 00104 if( m_bUseSingle ) 00105 { 00106 q->connect(q, SIGNAL(itemClicked(QListWidgetItem *)), 00107 SIGNAL(executed(QListWidgetItem *))); 00108 } 00109 else 00110 { 00111 q->connect(q, SIGNAL(itemDoubleClicked(QListWidgetItem *)), 00112 SIGNAL(executed(QListWidgetItem *))); 00113 } 00114 00115 m_bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); 00116 m_autoSelectDelay = KGlobalSettings::autoSelectDelay(); 00117 00118 if( !m_bUseSingle || !m_bChangeCursorOverItem ) 00119 q->viewport()->unsetCursor(); 00120 } 00121 00122 void KListWidget::KListWidgetPrivate::_k_slotAutoSelect() 00123 { 00124 // check that the item still exists 00125 if( q->row( m_pCurrentItem ) == -1 ) 00126 return; 00127 00128 //Give this widget the keyboard focus. 00129 if( !q->hasFocus() ) 00130 q->setFocus(); 00131 00132 Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers(); 00133 00134 QListWidgetItem* previousItem = q->currentItem(); 00135 q->setCurrentItem( m_pCurrentItem ); 00136 00137 if( m_pCurrentItem ) { 00138 //Shift pressed? 00139 if( (keybstate & Qt::ShiftModifier) ) { 00140 bool block = q->signalsBlocked(); 00141 q->blockSignals( true ); 00142 00143 //No Ctrl? Then clear before! 00144 if( !(keybstate & Qt::ControlModifier) ) 00145 q->clearSelection(); 00146 00147 bool select = !m_pCurrentItem->isSelected(); 00148 bool update = q->viewport()->updatesEnabled(); 00149 q->viewport()->setUpdatesEnabled( false ); 00150 00151 bool down = q->row( previousItem ) < q->row( m_pCurrentItem ); 00152 QListWidgetItem* it = down ? previousItem : m_pCurrentItem; 00153 00154 for (int i = q->row(it) ; i < q->count() ; i++ ) { 00155 if ( down && q->item(i) == m_pCurrentItem ) { 00156 m_pCurrentItem->setSelected(select); 00157 break; 00158 } 00159 00160 if ( !down && q->item(i) == previousItem ) { 00161 previousItem->setSelected(select); 00162 break; 00163 } 00164 it->setSelected(select); 00165 } 00166 00167 q->blockSignals( block ); 00168 q->viewport()->setUpdatesEnabled( update ); 00169 00170 emit q->itemSelectionChanged(); 00171 00172 if( q->selectionMode() == QAbstractItemView::SingleSelection ) 00173 q->emit itemSelectionChanged(); 00174 } 00175 else if( (keybstate & Qt::ControlModifier) ) 00176 m_pCurrentItem->setSelected(!m_pCurrentItem->isSelected()); 00177 else { 00178 bool block = q->signalsBlocked(); 00179 q->blockSignals( true ); 00180 00181 if( !m_pCurrentItem->isSelected() ) 00182 q->clearSelection(); 00183 00184 q->blockSignals( block ); 00185 00186 m_pCurrentItem->setSelected(true); 00187 } 00188 } 00189 else 00190 kDebug() << "That's not supposed to happen!!!!"; 00191 } 00192 00193 void KListWidget::KListWidgetPrivate::emitExecute( QListWidgetItem *item, const QPoint &pos ) 00194 { 00195 Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers(); 00196 00197 m_pAutoSelect->stop(); 00198 00199 //Don't emit executed if in SC mode and Shift or Ctrl are pressed 00200 if( !( m_bUseSingle && ((keybstate & Qt::ShiftModifier) || (keybstate & Qt::ControlModifier)) ) ) { 00201 emit q->executed( item ); 00202 emit q->executed( item, pos ); 00203 } 00204 } 00205 00206 // 00207 // 2000-16-01 Espen Sand 00208 // This widget is used in dialogs. It should ignore 00209 // F1 (and combinations) and Escape since these are used 00210 // to start help or close the dialog. This functionality 00211 // should be done in QListView but it is not (at least now) 00212 // 00213 void KListWidget::keyPressEvent(QKeyEvent *e) 00214 { 00215 if( e->key() == Qt::Key_Escape ) 00216 { 00217 e->ignore(); 00218 } 00219 else if( e->key() == Qt::Key_F1 ) 00220 { 00221 e->ignore(); 00222 } 00223 else 00224 { 00225 QListWidget::keyPressEvent(e); 00226 } 00227 } 00228 00229 void KListWidget::focusOutEvent( QFocusEvent *fe ) 00230 { 00231 d->m_pAutoSelect->stop(); 00232 00233 QListWidget::focusOutEvent( fe ); 00234 } 00235 00236 void KListWidget::leaveEvent( QEvent *e ) 00237 { 00238 d->m_pAutoSelect->stop(); 00239 00240 QListWidget::leaveEvent( e ); 00241 } 00242 00243 void KListWidget::mousePressEvent( QMouseEvent *e ) 00244 { 00245 if( (selectionMode() == QAbstractItemView::ExtendedSelection) && (e->modifiers() & Qt::ShiftModifier) && !(e->modifiers() & Qt::ControlModifier) ) { 00246 bool block = signalsBlocked(); 00247 blockSignals( true ); 00248 00249 clearSelection(); 00250 00251 blockSignals( block ); 00252 } 00253 00254 QListWidget::mousePressEvent( e ); 00255 } 00256 00257 void KListWidget::mouseDoubleClickEvent ( QMouseEvent * e ) 00258 { 00259 QListWidget::mouseDoubleClickEvent( e ); 00260 00261 QListWidgetItem* item = itemAt( e->pos() ); 00262 00263 if( item ) { 00264 emit doubleClicked( item, e->globalPos() ); 00265 00266 if( (e->button() == Qt::LeftButton) && !d->m_bUseSingle ) 00267 d->emitExecute( item, e->globalPos() ); 00268 } 00269 } 00270 00271 #include "klistwidget.moc"
KDE 4.6 API Reference