mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00
274 lines
7.4 KiB
C++
274 lines
7.4 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "klistwidget.h"
|
|
|
|
#include <kglobalsettings.h>
|
|
#include <kdebug.h>
|
|
|
|
#include <QtCore/QTimer>
|
|
#include <QtGui/qevent.h>
|
|
#include <QApplication>
|
|
|
|
class KListWidget::KListWidgetPrivate
|
|
{
|
|
public:
|
|
KListWidgetPrivate(KListWidget *q)
|
|
: q(q),
|
|
m_pCurrentItem(0),
|
|
m_eventPos()
|
|
{
|
|
}
|
|
|
|
void _k_slotItemEntered(QListWidgetItem*);
|
|
void _k_slotOnViewport();
|
|
void _k_slotMouseChanged();
|
|
void _k_slotAutoSelect();
|
|
void _k_slotEmitExecute(QListWidgetItem *item);
|
|
|
|
KListWidget *q;
|
|
bool m_bUseSingle : 1;
|
|
bool m_bChangeCursorOverItem : 1;
|
|
|
|
QListWidgetItem* m_pCurrentItem;
|
|
QTimer* m_pAutoSelect;
|
|
int m_autoSelectDelay;
|
|
QPoint m_eventPos;
|
|
};
|
|
|
|
KListWidget::KListWidget( QWidget *parent )
|
|
: QListWidget(parent), d(new KListWidgetPrivate(this))
|
|
{
|
|
connect( this, SIGNAL(viewportEntered()),
|
|
this, SLOT(_k_slotOnViewport()) );
|
|
connect( this, SIGNAL(itemEntered(QListWidgetItem*)),
|
|
this, SLOT(_k_slotItemEntered(QListWidgetItem*)) );
|
|
d->_k_slotMouseChanged();
|
|
connect( KGlobalSettings::self(), SIGNAL(mouseChanged()), SLOT(_k_slotMouseChanged()) );
|
|
|
|
d->m_pAutoSelect = new QTimer( this );
|
|
connect( d->m_pAutoSelect, SIGNAL(timeout()),
|
|
this, SLOT(_k_slotAutoSelect()) );
|
|
}
|
|
|
|
KListWidget::~KListWidget()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void KListWidget::KListWidgetPrivate::_k_slotItemEntered( QListWidgetItem *item )
|
|
{
|
|
if ( item && m_bChangeCursorOverItem && m_bUseSingle )
|
|
q->viewport()->setCursor( QCursor( Qt::OpenHandCursor ) );
|
|
|
|
if ( item && (m_autoSelectDelay > -1) && m_bUseSingle ) {
|
|
m_pAutoSelect->setSingleShot( true );
|
|
m_pAutoSelect->start( m_autoSelectDelay );
|
|
m_pCurrentItem = item;
|
|
}
|
|
}
|
|
|
|
void KListWidget::KListWidgetPrivate::_k_slotOnViewport()
|
|
{
|
|
if ( m_bChangeCursorOverItem )
|
|
q->viewport()->unsetCursor();
|
|
|
|
m_pAutoSelect->stop();
|
|
m_pCurrentItem = 0;
|
|
}
|
|
|
|
|
|
void KListWidget::KListWidgetPrivate::_k_slotMouseChanged()
|
|
{
|
|
m_bUseSingle = KGlobalSettings::singleClick();
|
|
|
|
q->disconnect(q, SIGNAL(itemClicked(QListWidgetItem*)));
|
|
q->disconnect(q, SIGNAL(itemDoubleClicked(QListWidgetItem*)));
|
|
|
|
if( m_bUseSingle )
|
|
{
|
|
q->connect(q, SIGNAL(itemClicked(QListWidgetItem*)),
|
|
SLOT(_k_slotEmitExecute(QListWidgetItem*)));
|
|
}
|
|
else
|
|
{
|
|
q->connect(q, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
|
|
SLOT(_k_slotEmitExecute(QListWidgetItem*)));
|
|
}
|
|
|
|
m_bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
|
|
m_autoSelectDelay = KGlobalSettings::autoSelectDelay();
|
|
|
|
if( !m_bUseSingle || !m_bChangeCursorOverItem )
|
|
q->viewport()->unsetCursor();
|
|
}
|
|
|
|
void KListWidget::KListWidgetPrivate::_k_slotAutoSelect()
|
|
{
|
|
// check that the item still exists
|
|
if( q->row( m_pCurrentItem ) == -1 )
|
|
return;
|
|
|
|
//Give this widget the keyboard focus.
|
|
if( !q->hasFocus() )
|
|
q->setFocus();
|
|
|
|
Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers();
|
|
|
|
QListWidgetItem* previousItem = q->currentItem();
|
|
q->setCurrentItem( m_pCurrentItem );
|
|
|
|
if( m_pCurrentItem ) {
|
|
//Shift pressed?
|
|
if( (keybstate & Qt::ShiftModifier) ) {
|
|
bool block = q->signalsBlocked();
|
|
q->blockSignals( true );
|
|
|
|
//No Ctrl? Then clear before!
|
|
if( !(keybstate & Qt::ControlModifier) )
|
|
q->clearSelection();
|
|
|
|
bool select = !m_pCurrentItem->isSelected();
|
|
bool update = q->viewport()->updatesEnabled();
|
|
q->viewport()->setUpdatesEnabled( false );
|
|
|
|
bool down = q->row( previousItem ) < q->row( m_pCurrentItem );
|
|
QListWidgetItem* it = down ? previousItem : m_pCurrentItem;
|
|
|
|
for (int i = q->row(it) ; i < q->count() ; i++ ) {
|
|
if ( down && q->item(i) == m_pCurrentItem ) {
|
|
m_pCurrentItem->setSelected(select);
|
|
break;
|
|
}
|
|
|
|
if ( !down && q->item(i) == previousItem ) {
|
|
previousItem->setSelected(select);
|
|
break;
|
|
}
|
|
it->setSelected(select);
|
|
}
|
|
|
|
q->blockSignals( block );
|
|
q->viewport()->setUpdatesEnabled( update );
|
|
|
|
emit q->itemSelectionChanged();
|
|
|
|
if( q->selectionMode() == QAbstractItemView::SingleSelection )
|
|
q->emit itemSelectionChanged();
|
|
}
|
|
else if( (keybstate & Qt::ControlModifier) )
|
|
m_pCurrentItem->setSelected(!m_pCurrentItem->isSelected());
|
|
else {
|
|
bool block = q->signalsBlocked();
|
|
q->blockSignals( true );
|
|
|
|
if( !m_pCurrentItem->isSelected() )
|
|
q->clearSelection();
|
|
|
|
q->blockSignals( block );
|
|
|
|
m_pCurrentItem->setSelected(true);
|
|
}
|
|
}
|
|
else
|
|
kDebug() << "That's not supposed to happen!!!!";
|
|
}
|
|
|
|
void KListWidget::KListWidgetPrivate::_k_slotEmitExecute(QListWidgetItem *item)
|
|
{
|
|
Qt::KeyboardModifiers keybstate = QApplication::keyboardModifiers();
|
|
|
|
m_pAutoSelect->stop();
|
|
|
|
//Don't emit executed if in SC mode and Shift or Ctrl are pressed
|
|
if( !( m_bUseSingle && ((keybstate & Qt::ShiftModifier) || (keybstate & Qt::ControlModifier)) ) ) {
|
|
emit q->executed( item );
|
|
if (!m_eventPos.isNull()) {
|
|
emit q->executed( item, m_eventPos );
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// 2000-16-01 Espen Sand
|
|
// This widget is used in dialogs. It should ignore
|
|
// F1 (and combinations) and Escape since these are used
|
|
// to start help or close the dialog. This functionality
|
|
// should be done in QListView but it is not (at least now)
|
|
//
|
|
void KListWidget::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
if( e->key() == Qt::Key_Escape )
|
|
{
|
|
e->ignore();
|
|
}
|
|
else if( e->key() == Qt::Key_F1 )
|
|
{
|
|
e->ignore();
|
|
}
|
|
else
|
|
{
|
|
QListWidget::keyPressEvent(e);
|
|
}
|
|
}
|
|
|
|
void KListWidget::focusOutEvent( QFocusEvent *fe )
|
|
{
|
|
d->m_pAutoSelect->stop();
|
|
|
|
QListWidget::focusOutEvent( fe );
|
|
}
|
|
|
|
void KListWidget::leaveEvent( QEvent *e )
|
|
{
|
|
d->m_pAutoSelect->stop();
|
|
|
|
QListWidget::leaveEvent( e );
|
|
}
|
|
|
|
void KListWidget::mousePressEvent( QMouseEvent *e )
|
|
{
|
|
if( (selectionMode() == QAbstractItemView::ExtendedSelection) && (e->modifiers() & Qt::ShiftModifier) && !(e->modifiers() & Qt::ControlModifier) ) {
|
|
bool block = signalsBlocked();
|
|
blockSignals( true );
|
|
|
|
clearSelection();
|
|
|
|
blockSignals( block );
|
|
}
|
|
|
|
QListWidget::mousePressEvent( e );
|
|
}
|
|
|
|
void KListWidget::mouseDoubleClickEvent ( QMouseEvent * e )
|
|
{
|
|
QPoint oldPos = d->m_eventPos;
|
|
d->m_eventPos = e->globalPos();
|
|
QListWidget::mouseDoubleClickEvent(e);
|
|
d->m_eventPos = oldPos;
|
|
}
|
|
|
|
void KListWidget::mouseReleaseEvent ( QMouseEvent * e )
|
|
{
|
|
QPoint oldPos = d->m_eventPos;
|
|
d->m_eventPos = e->globalPos();
|
|
QListWidget::mouseReleaseEvent(e);
|
|
d->m_eventPos = oldPos;
|
|
}
|
|
|
|
#include "moc_klistwidget.cpp"
|