-rw-r--r-- | microkde/kdeui/klistview.cpp | 9 | ||||
-rw-r--r-- | microkde/kdeui/klistview.h | 1 |
2 files changed, 10 insertions, 0 deletions
diff --git a/microkde/kdeui/klistview.cpp b/microkde/kdeui/klistview.cpp index 25327aa..f7d2187 100644 --- a/microkde/kdeui/klistview.cpp +++ b/microkde/kdeui/klistview.cpp @@ -1,1503 +1,1512 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org> Copyright (C) 2000 Charles Samuels <charles@kde.org> Copyright (C) 2000 Peter Putzer 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdragobject.h> #include <qtimer.h> #include <qheader.h> #include <qcursor.h> #include <qtooltip.h> #include <qstyle.h> #include <qpainter.h> #include <kglobalsettings.h> #include <kconfig.h> #include <kconfigbase.h> //US #include <kcursor.h> #include <kapplication.h> //US #include <kipc.h> #include <kdebug.h> #ifdef _WIN32_ #define Q_WS_QWS #endif #ifndef _WIN32_ #define private public #include <qlistview.h> #undef private #endif #include "klistview.h" //US #include "klistviewlineedit.h" #ifndef DESKTOP_VERSION #include <qpe/qpeapplication.h> #endif // /*US class KListView::Tooltip : public QToolTip { public: Tooltip (KListView* parent, QToolTipGroup* group = 0L); virtual ~Tooltip () {} protected: // */ /** * Reimplemented from QToolTip for internal reasons. */ // /*US virtual void maybeTip (const QPoint&); private: KListView* mParent; }; KListView::Tooltip::Tooltip (KListView* parent, QToolTipGroup* group) : QToolTip (parent, group), mParent (parent) { } void KListView::Tooltip::maybeTip (const QPoint&) { // FIXME } // */ class KListView::KListViewPrivate { public: KListViewPrivate (KListView* listview) : pCurrentItem (0L), autoSelectDelay(1), //US dragDelay (KGlobalSettings::dndEventDelay()), dragDelay (10), //US editor (new KListViewLineEdit (listview)), cursorInExecuteArea(false), bUseSingle(false), bChangeCursorOverItem(false), itemsMovable (true), selectedBySimpleMove(false), selectedUsingMouse(false), itemsRenameable (false), validDrag (false), dragEnabled (false), autoOpen (true), dropVisualizer (true), dropHighlighter (false), createChildren (true), pressedOnSelected (false), wasShiftEvent (false), fullWidth (false), sortAscending(true), tabRename(true), sortColumn(0), selectionDirection(0), tooltipColumn (0), selectionMode (Single), contextMenuKey ( Qt::Key_Menu ),//KGlobalSettings::contextMenuKey()), showContextMenusOnPress (true),//showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()), mDropVisualizerWidth (4) { renameable += 0; //US connect(editor, SIGNAL(done(QListViewItem*,int)), listview, SLOT(doneEditing(QListViewItem*,int))); } ~KListViewPrivate () { //US delete editor; } QListViewItem* pCurrentItem; QTimer autoSelect; int autoSelectDelay; QTimer dragExpand; QListViewItem* dragOverItem; QPoint dragOverPoint; QPoint startDragPos; int dragDelay; //US KListViewLineEdit *editor; QValueList<int> renameable; bool cursorInExecuteArea:1; bool bUseSingle:1; bool bChangeCursorOverItem:1; bool itemsMovable:1; bool selectedBySimpleMove : 1; bool selectedUsingMouse:1; bool itemsRenameable:1; bool validDrag:1; bool dragEnabled:1; bool autoOpen:1; bool dropVisualizer:1; bool dropHighlighter:1; bool createChildren:1; bool pressedOnSelected:1; bool wasShiftEvent:1; bool fullWidth:1; bool sortAscending:1; bool tabRename:1; int sortColumn; //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX int selectionDirection; int tooltipColumn; SelectionModeExt selectionMode; int contextMenuKey; bool showContextMenusOnPress; QRect mOldDropVisualizer; int mDropVisualizerWidth; QRect mOldDropHighlighter; QListViewItem *afterItemDrop; QListViewItem *parentItemDrop; QColor alternateBackground; }; /*US KListViewLineEdit::KListViewLineEdit(KListView *parent) : KLineEdit(parent->viewport()), item(0), col(0), p(parent) { setFrame( false ); hide(); connect( parent, SIGNAL( selectionChanged() ), SLOT( slotSelectionChanged() )); } KListViewLineEdit::~KListViewLineEdit() { } void KListViewLineEdit::load(QListViewItem *i, int c) { item=i; col=c; QRect rect(p->itemRect(i)); setText(item->text(c)); int fieldX = rect.x() - 1; int fieldW = p->columnWidth(col) + 2; int pos = p->header()->mapToIndex(col); for ( int index = 0; index < pos; index++ ) fieldX += p->columnWidth( p->header()->mapToSection( index )); if ( col == 0 ) { int d = i->depth() + (p->rootIsDecorated() ? 1 : 0); d *= p->treeStepSize(); fieldX += d; fieldW -= d; } if ( i->pixmap( col ) ) {// add width of pixmap int d = i->pixmap( col )->width(); fieldX += d; fieldW -= d; } setGeometry(fieldX, rect.y() - 1, fieldW, rect.height() + 2); show(); setFocus(); } */ /* Helper functions to for * tabOrderedRename functionality. */ static int nextCol (KListView *pl, QListViewItem *pi, int start, int dir) { if (pi) { // Find the next renameable column in the current row for (; ((dir == +1) ? (start < pl->columns()) : (start >= 0)); start += dir) if (pl->isRenameable(start)) return start; } return -1; } static QListViewItem *prevItem (QListViewItem *pi) { QListViewItem *pa = pi->itemAbove(); /* Does what the QListViewItem::previousSibling() * of my dreams would do. */ if (pa && pa->parent() == pi->parent()) return pa; return NULL; } static QListViewItem *lastQChild (QListViewItem *pi) { if (pi) { /* Since there's no QListViewItem::lastChild(). * This finds the last sibling for the given * item. */ for (QListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling()) pi = pt; } return pi; } /*US void KListViewLineEdit::selectNextCell (QListViewItem *pitem, int column, bool forward) { const int ncols = p->columns(); const int dir = forward ? +1 : -1; const int restart = forward ? 0 : (ncols - 1); QListViewItem *top = (pitem && pitem->parent()) ? pitem->parent()->firstChild() : p->firstChild(); QListViewItem *pi = pitem; terminate(); // Save current changes do { */ /* Check the rest of the current row for an editable column, * if that fails, check the entire next/previous row. The * last case goes back to the first item in the current branch * or the last item in the current branch depending on the * direction. */ /*US if ((column = nextCol(p, pi, column + dir, dir)) != -1 || (column = nextCol(p, (pi = (forward ? pi->nextSibling() : prevItem(pi))), restart, dir)) != -1 || (column = nextCol(p, (pi = (forward ? top : lastQChild(pitem))), restart, dir)) != -1) { if (pi) { p->setCurrentItem(pi); // Calls terminate p->rename(pi, column); */ /* Some listviews may override rename() to * prevent certain items from being renamed, * if this is done, [m_]item will be NULL * after the rename() call... try again. */ /*US if (!item) continue; break; } } } while (pi && !item); } */ /*US #ifdef KeyPress #undef KeyPress #endif bool KListViewLineEdit::event (QEvent *pe) { if (pe->type() == QEvent::KeyPress) { QKeyEvent *k = (QKeyEvent *) pe; if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) && p->tabOrderedRenaming() && p->itemsRenameable() && !(k->state() & ControlButton || k->state() & AltButton)) { selectNextCell(item, col, (k->key() == Key_Tab && !(k->state() & ShiftButton))); return true; } } return KLineEdit::event(pe); } void KListViewLineEdit::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) terminate(true); else if(e->key() == Qt::Key_Escape) terminate(false); else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Up) { terminate(true); KLineEdit::keyPressEvent(e); } else KLineEdit::keyPressEvent(e); } void KListViewLineEdit::terminate() { terminate(true); } void KListViewLineEdit::terminate(bool commit) { if ( item ) { //kdDebug() << "KListViewLineEdit::terminate " << commit << endl; if (commit) item->setText(col, text()); int c=col; QListViewItem *i=item; col=0; item=0; hide(); // will call focusOutEvent, that's why we set item=0 before emit done(i,c); } } void KListViewLineEdit::focusOutEvent(QFocusEvent *ev) { QFocusEvent * focusEv = static_cast<QFocusEvent*>(ev); // Don't let a RMB close the editor if (focusEv->reason() != QFocusEvent::Popup && focusEv->reason() != QFocusEvent::ActiveWindow) terminate(true); } void KListViewLineEdit::paintEvent( QPaintEvent *e ) { KLineEdit::paintEvent( e ); if ( !frame() ) { QPainter p( this ); p.setClipRegion( e->region() ); p.drawRect( rect() ); } } // selection changed -> terminate. As our "item" can be already deleted, // we can't call terminate(false), because that would emit done() with // a dangling pointer to "item". void KListViewLineEdit::slotSelectionChanged() { item = 0; col = 0; hide(); } */ KListView::KListView( QWidget *parent, const char *name ,bool emulateRightMouse ) : QListView( parent, name ), d (new KListViewPrivate (this)) { #ifndef DESKTOP_VERSION if ( emulateRightMouse ) QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); #endif //US setDragAutoScroll(true); connect( this, SIGNAL( onViewport() ), this, SLOT( slotOnViewport() ) ); connect( this, SIGNAL( onItem( QListViewItem * ) ), this, SLOT( slotOnItem( QListViewItem * ) ) ); connect (this, SIGNAL(contentsMoving(int,int)), this, SLOT(cleanDropVisualizer())); connect (this, SIGNAL(contentsMoving(int,int)), this, SLOT(cleanItemHighlighter())); /*US slotSettingsChanged(KApplication::SETTINGS_MOUSE); if (kapp) { connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) ); kapp->addKipcEventMask( KIPC::SettingsChanged ); } */ slotSettingsChanged(1); //US do this to initialize the connections connect(&d->autoSelect, SIGNAL( timeout() ), this, SLOT( slotAutoSelect() ) ); connect(&d->dragExpand, SIGNAL( timeout() ), this, SLOT( slotDragExpand() ) ); // context menu handling if (d->showContextMenusOnPress) { connect (this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)), this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); } else { connect (this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)), this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); } connect (this, SIGNAL (menuShortCutPressed (KListView*, QListViewItem*)), this, SLOT (emitContextMenu (KListView*, QListViewItem*))); //qDebug("KListView::KListView make alternate color configurable"); d->alternateBackground = KGlobalSettings::alternateBackgroundColor(); } KListView::~KListView() { delete d; } bool KListView::isExecuteArea( const QPoint& point ) { if ( itemAt( point ) ) return isExecuteArea( point.x() ); return false; } +QSize KListView::sizeHint() const +{ + //qDebug("KListView::QSize sizeHint() "); +#ifdef DESKTOP_VERSION + QListView::sizeHint(); +#else + return QSize ( 40, 40 ); +#endif +} bool KListView::isExecuteArea( int x ) { if( allColumnsShowFocus() ) return true; else { int offset = 0; int width = columnWidth( 0 ); int pos = header()->mapToIndex( 0 ); for ( int index = 0; index < pos; index++ ) offset += columnWidth( header()->mapToSection( index ) ); x += contentsX(); // in case of a horizontal scrollbar return ( x > offset && x < ( offset + width ) ); } } void KListView::slotOnItem( QListViewItem *item ) { QPoint vp = viewport()->mapFromGlobal( QCursor::pos() ); if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) { d->autoSelect.start( d->autoSelectDelay, true ); d->pCurrentItem = item; } } void KListView::slotOnViewport() { if ( d->bChangeCursorOverItem ) viewport()->unsetCursor(); d->autoSelect.stop(); d->pCurrentItem = 0L; } void KListView::slotSettingsChanged(int category) { //qDebug("KListView::slotSettingsChanged has to be verified"); switch (category) { //US I create my private category (=1) to set the settings case 1: d->dragDelay = 2; //US set explicitly d->bUseSingle = KGlobalSettings::singleClick(); // qDebug("KListView::slotSettingsChanged: single%i", d->bUseSingle); disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int))); if( d->bUseSingle ) connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int))); //US d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); //US d->autoSelectDelay = KGlobalSettings::autoSelectDelay(); if( !d->bUseSingle || !d->bChangeCursorOverItem ) viewport()->unsetCursor(); break; /*US case KApplication::SETTINGS_MOUSE: d->dragDelay = KGlobalSettings::dndEventDelay(); d->bUseSingle = KGlobalSettings::singleClick(); disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int))); if( d->bUseSingle ) connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int))); d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); d->autoSelectDelay = KGlobalSettings::autoSelectDelay(); if( !d->bUseSingle || !d->bChangeCursorOverItem ) viewport()->unsetCursor(); break; case KApplication::SETTINGS_POPUPMENU: d->contextMenuKey = KGlobalSettings::contextMenuKey (); d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress (); if (d->showContextMenusOnPress) { disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)), this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); } else { disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)), this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); } break; */ default: break; } } void KListView::slotAutoSelect() { // check that the item still exists if( itemIndex( d->pCurrentItem ) == -1 ) return; if (!isActiveWindow()) { d->autoSelect.stop(); return; } //Give this widget the keyboard focus. if( !hasFocus() ) setFocus(); QListViewItem* previousItem = currentItem(); setCurrentItem( d->pCurrentItem ); #if 0 #ifndef Q_WS_QWS // FIXME(E): Implement for Qt Embedded if( d->pCurrentItem ) { //Shift pressed? if( (keybstate & ShiftMask) ) { bool block = signalsBlocked(); blockSignals( true ); //No Ctrl? Then clear before! if( !(keybstate & ControlMask) ) clearSelection(); bool select = !d->pCurrentItem->isSelected(); bool update = viewport()->isUpdatesEnabled(); viewport()->setUpdatesEnabled( false ); bool down = previousItem->itemPos() < d->pCurrentItem->itemPos(); QListViewItemIterator lit( down ? previousItem : d->pCurrentItem ); for ( ; lit.current(); ++lit ) { if ( down && lit.current() == d->pCurrentItem ) { d->pCurrentItem->setSelected( select ); break; } if ( !down && lit.current() == previousItem ) { previousItem->setSelected( select ); break; } lit.current()->setSelected( select ); } blockSignals( block ); viewport()->setUpdatesEnabled( update ); triggerUpdate(); emit selectionChanged(); if( selectionMode() == QListView::Single ) emit selectionChanged( d->pCurrentItem ); } else if( (keybstate & ControlMask) ) setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() ); else { bool block = signalsBlocked(); blockSignals( true ); if( !d->pCurrentItem->isSelected() ) clearSelection(); blockSignals( block ); setSelected( d->pCurrentItem, true ); } } else kdDebug() << "KListView::slotAutoSelect: Thats not supposed to happen!!!!" << endl; #endif #endif } void KListView::slotHeaderChanged() { if (d->fullWidth && columns()) { int w = 0; for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i); setColumnWidth( columns() - 1, viewport()->width() - w - 1 ); } } void KListView::emitExecute( int buttonstate, QListViewItem *item, const QPoint &pos, int c) { // qDebug("KListView::emitExecute buttonstate=%i", buttonstate); if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) { // Double click mode ? if ( !d->bUseSingle ) { emit executed( item ); emit executed( item, pos, c ); } else { //US special implementation for embedded systems d->autoSelect.stop(); //Dont emit executed if in SC mode and Shift or Ctrl are pressed if( !( (buttonstate==ShiftButton) || (buttonstate==ControlButton) )) { // if( !( ((keybstate & ShiftMask) || (keybstate & ControlMask)) ) ) { emit executed( item ); emit executed( item, pos, c ); } } } } void KListView::focusInEvent( QFocusEvent *fe ) { // kdDebug()<<"KListView::focusInEvent()"<<endl; QListView::focusInEvent( fe ); if ((d->selectedBySimpleMove) && (d->selectionMode == FileManager) && (fe->reason()!=QFocusEvent::Popup) && (fe->reason()!=QFocusEvent::ActiveWindow) && (currentItem()!=0)) { currentItem()->setSelected(true); currentItem()->repaint(); emit selectionChanged(); }; } void KListView::focusOutEvent( QFocusEvent *fe ) { cleanDropVisualizer(); cleanItemHighlighter(); d->autoSelect.stop(); if ((d->selectedBySimpleMove) && (d->selectionMode == FileManager) && (fe->reason()!=QFocusEvent::Popup) && (fe->reason()!=QFocusEvent::ActiveWindow) && (currentItem()!=0) /*US && (!d->editor->isVisible()) */ ) { currentItem()->setSelected(false); currentItem()->repaint(); emit selectionChanged(); }; QListView::focusOutEvent( fe ); } void KListView::leaveEvent( QEvent *e ) { d->autoSelect.stop(); QListView::leaveEvent( e ); } bool KListView::event( QEvent *e ) { if (e->type() == QEvent::ApplicationPaletteChange) { //qDebug("KListView::event make alternate color configurable"); //US d->alternateBackground=KGlobalSettings::alternateBackgroundColor(); d->alternateBackground = QColor(240, 240, 240); } return QListView::event(e); } void KListView::contentsMousePressEvent( QMouseEvent *e ) { //qDebug("KListView::contentsMousePressEvent"); if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) { bool block = signalsBlocked(); blockSignals( true ); clearSelection(); blockSignals( block ); } else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove)) { d->selectedBySimpleMove=false; d->selectedUsingMouse=true; if (currentItem()!=0) { currentItem()->setSelected(false); currentItem()->repaint(); // emit selectionChanged(); }; }; QPoint p( contentsToViewport( e->pos() ) ); QListViewItem *at = itemAt (p); // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) bool rootDecoClicked = at && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); if (e->button() == LeftButton && !rootDecoClicked) { //Start a drag d->startDragPos = e->pos(); if (at) { d->validDrag = true; d->pressedOnSelected = at->isSelected(); } } QListView::contentsMousePressEvent( e ); } void KListView::contentsMouseMoveEvent( QMouseEvent *e ) { if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag) { QListView::contentsMouseMoveEvent (e); return; } QPoint vp = contentsToViewport(e->pos()); QListViewItem *item = itemAt( vp ); //do we process cursor changes at all? if ( item && d->bChangeCursorOverItem && d->bUseSingle ) { //Cursor moved on a new item or in/out the execute area if( (item != d->pCurrentItem) || (isExecuteArea(vp) != d->cursorInExecuteArea) ) { d->cursorInExecuteArea = isExecuteArea(vp); //qDebug("KListView::contentsMouseMoveEvent drag&drop not supported yet"); /*US if( d->cursorInExecuteArea ) //cursor moved in execute area viewport()->setCursor( KCursor::handCursor() ); else //cursor moved out of execute area viewport()->unsetCursor(); */ } } bool dragOn = dragEnabled(); QPoint newPos = e->pos(); if (dragOn && d->validDrag && (newPos.x() > d->startDragPos.x()+d->dragDelay || newPos.x() < d->startDragPos.x()-d->dragDelay || newPos.y() > d->startDragPos.y()+d->dragDelay || newPos.y() < d->startDragPos.y()-d->dragDelay)) //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) { QListView::contentsMouseReleaseEvent( 0 ); startDrag(); d->startDragPos = QPoint(); d->validDrag = false; } } void KListView::contentsMouseReleaseEvent( QMouseEvent *e ) { if (e->button() == LeftButton) { // If the row was already selected, maybe we want to start an in-place editing if ( d->pressedOnSelected && itemsRenameable() ) { QPoint p( contentsToViewport( e->pos() ) ); QListViewItem *at = itemAt (p); if ( at ) { // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) bool rootDecoClicked = ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); if (!rootDecoClicked) { int col = header()->mapToLogical( header()->cellAt( p.x() ) ); if ( d->renameable.contains(col) ) rename(at, col); } } } d->pressedOnSelected = false; d->validDrag = false; d->startDragPos = QPoint(); } QListView::contentsMouseReleaseEvent( e ); } void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e ) { //qDebug("KListView::contentsMouseDoubleClickEvent"); // We don't want to call the parent method because it does setOpen, // whereas we don't do it in single click mode... (David) //QListView::contentsMouseDoubleClickEvent( e ); QPoint vp = contentsToViewport(e->pos()); QListViewItem *item = itemAt( vp ); emit QListView::doubleClicked( item ); // we do it now int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1; if( item ) { //qDebug("KListView::contentsMouseDoubleClickEvent: emit doubleClicked"); emit doubleClicked( item, e->globalPos(), col ); if( (e->button() == LeftButton) && !d->bUseSingle ) { //qDebug("KListView::contentsMouseDoubleClickEvent: emitExecute"); emitExecute( e->button(), item, e->globalPos(), col); } } } void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c ) { //qDebug("KListView::slotMouseButtonClicked"); if( (btn == LeftButton) && item ) { //qDebug("KListView::slotMouseButtonClicked: emitExecute"); emitExecute(btn, item, pos, c); } } void KListView::contentsDropEvent(QDropEvent* e) { qDebug("KListView::contentsDropEvent drag&drop not supported yet"); /*US cleanDropVisualizer(); cleanItemHighlighter(); d->dragExpand.stop(); if (acceptDrag (e)) { e->acceptAction(); QListViewItem *afterme; QListViewItem *parent; findDrop(e->pos(), parent, afterme); if (e->source() == viewport() && itemsMovable()) movableDropEvent(parent, afterme); else { emit dropped(e, afterme); emit dropped(this, e, afterme); emit dropped(e, parent, afterme); emit dropped(this, e, parent, afterme); } } */ } void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme) { QPtrList<QListViewItem> items, afterFirsts, afterNows; QListViewItem *current=currentItem(); bool hasMoved=false; for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext) { iNext=i->itemBelow(); if (!i->isSelected()) continue; // don't drop an item after itself, or else // it moves to the top of the list if (i==afterme) continue; i->setSelected(false); QListViewItem *afterFirst = i->itemAbove(); if (!hasMoved) { emit aboutToMove(); hasMoved=true; } moveItem(i, parent, afterme); // ###### This should include the new parent !!! -> KDE 3.0 // If you need this right now, have a look at keditbookmarks. emit moved(i, afterFirst, afterme); items.append (i); afterFirsts.append (afterFirst); afterNows.append (afterme); afterme = i; } clearSelection(); for (QListViewItem *i=items.first(); i != 0; i=items.next() ) i->setSelected(true); if (current) setCurrentItem(current); emit moved(items,afterFirsts,afterNows); if (firstChild()) emit moved(); } void KListView::contentsDragMoveEvent(QDragMoveEvent *event) { qDebug("KListView::contentsDropEvent drag&drop not supported yet"); /*US if (acceptDrag(event)) { event->acceptAction(); //Clean up the view findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop); QPoint vp = contentsToViewport( event->pos() ); QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L; if ( item != d->dragOverItem ) { d->dragExpand.stop(); d->dragOverItem = item; d->dragOverPoint = vp; if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() ) d->dragExpand.start( QApplication::startDragTime(), true ); } if (dropVisualizer()) { QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop); if (tmpRect != d->mOldDropVisualizer) { cleanDropVisualizer(); d->mOldDropVisualizer=tmpRect; viewport()->repaint(tmpRect); } } if (dropHighlighter()) { QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop); if (tmpRect != d->mOldDropHighlighter) { cleanItemHighlighter(); d->mOldDropHighlighter=tmpRect; viewport()->repaint(tmpRect); } } } else event->ignore(); */ } void KListView::slotDragExpand() { if ( itemAt( d->dragOverPoint ) == d->dragOverItem ) d->dragOverItem->setOpen( true ); } void KListView::contentsDragLeaveEvent (QDragLeaveEvent*) { d->dragExpand.stop(); cleanDropVisualizer(); cleanItemHighlighter(); } void KListView::cleanDropVisualizer() { if (d->mOldDropVisualizer.isValid()) { QRect rect=d->mOldDropVisualizer; d->mOldDropVisualizer = QRect(); viewport()->repaint(rect, true); } } int KListView::depthToPixels( int depth ) { return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin(); } void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after) { QPoint p (contentsToViewport(pos)); // Get the position to put it in QListViewItem *atpos = itemAt(p); QListViewItem *above; if (!atpos) // put it at the end above = lastItem(); else { // Get the closest item before us ('atpos' or the one above, if any) if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2)) above = atpos->itemAbove(); else above = atpos; } if (above) { // Now, we know we want to go after "above". But as a child or as a sibling ? // We have to ask the "above" item if it accepts children. if (above->isExpandable()) { // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children if (p.x() >= depthToPixels( above->depth() + 1 ) || (above->isOpen() && above->childCount() > 0) ) { parent = above; after = 0L; return; } } // Ok, there's one more level of complexity. We may want to become a new // sibling, but of an upper-level group, rather than the "above" item QListViewItem * betterAbove = above->parent(); QListViewItem * last = above; while ( betterAbove ) { // We are allowed to become a sibling of "betterAbove" only if we are // after its last child if ( last->nextSibling() == 0 ) { if (p.x() < depthToPixels ( betterAbove->depth() + 1 )) above = betterAbove; // store this one, but don't stop yet, there may be a better one else break; // not enough on the left, so stop last = betterAbove; betterAbove = betterAbove->parent(); // up one level } else break; // we're among the child of betterAbove, not after the last one } } // set as sibling after = above; parent = after ? after->parent() : 0L ; } QListViewItem* KListView::lastChild () const { QListViewItem* lastchild = firstChild(); if (lastchild) for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling()); return lastchild; } QListViewItem *KListView::lastItem() const { QListViewItem* last = lastChild(); for (QListViewItemIterator it (last); it.current(); ++it) last = it.current(); return last; } KLineEdit *KListView::renameLineEdit() const { //US return d->editor; qDebug("KListView::renameLineEdit returns 0. Might crash"); return 0; } void KListView::startDrag() { qDebug("KListView::startDrag drag&drop not supported yet."); /*US QDragObject *drag = dragObject(); if (!drag) return; if (drag->drag() && drag->target() != viewport()) emit moved(); */ } QDragObject *KListView::dragObject() { if (!currentItem()) return 0; return new QStoredDrag("application/x-qlistviewitem", viewport()); } void KListView::setItemsMovable(bool b) { d->itemsMovable=b; } bool KListView::itemsMovable() const { return d->itemsMovable; } void KListView::setItemsRenameable(bool b) { d->itemsRenameable=b; } bool KListView::itemsRenameable() const { return d->itemsRenameable; } void KListView::setDragEnabled(bool b) { d->dragEnabled=b; } bool KListView::dragEnabled() const { return d->dragEnabled; } void KListView::setAutoOpen(bool b) { d->autoOpen=b; } bool KListView::autoOpen() const { return d->autoOpen; } bool KListView::dropVisualizer() const { return d->dropVisualizer; } void KListView::setDropVisualizer(bool b) { d->dropVisualizer=b; } QPtrList<QListViewItem> KListView::selectedItems() const { QPtrList<QListViewItem> list; for (QListViewItem *i=firstChild(); i!=0; i=i->itemBelow()) if (i->isSelected()) list.append(i); return list; } void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after) { // sanity check - don't move a item into it's own child structure QListViewItem *i = parent; while(i) { if(i == item) return; i = i->parent(); } // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor // in here, without ever deleting the item. if (item->parent()) item->parent()->takeItem(item); else takeItem(item); if (parent) parent->insertItem(item); else insertItem(item); if (after) ;//item->moveToJustAfter(after); } void KListView::contentsDragEnterEvent(QDragEnterEvent *event) { qDebug("KListView::contentsDragEnterEvent drag&drop not supported yet."); /*US if (acceptDrag (event)) event->accept(); */ } void KListView::setDropVisualizerWidth (int w) { d->mDropVisualizerWidth = w > 0 ? w : 1; } QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent, QListViewItem *after) { QRect insertmarker; if (!after && !parent) insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2); else { int level = 0; if (after) { QListViewItem* it = 0L; if (after->isOpen()) { // Look for the last child (recursively) it = after->firstChild(); if (it) while (it->nextSibling() || it->firstChild()) if ( it->nextSibling() ) it = it->nextSibling(); else it = it->firstChild(); } insertmarker = itemRect (it ? it : after); level = after->depth(); } else if (parent) { insertmarker = itemRect (parent); level = parent->depth() + 1; } insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() ); insertmarker.setRight (viewport()->width()); insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1); insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2); } // This is not used anymore, at least by KListView itself (see viewportPaintEvent) // Remove for KDE 3.0. if (p) p->fillRect(insertmarker, Dense4Pattern); return insertmarker; } QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item) { QRect r; if (item) { r = itemRect(item); r.setLeft(r.left()+(item->depth()+1)*treeStepSize()); if (painter) { //US style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(), //US QStyle::Style_FocusAtBorder, colorGroup().highlight()); const QColor* pHighl = &(colorGroup().highlight()); //LR style().drawFocusRect(painter, r, colorGroup(), pHighl, true); qDebug("KListView::drawItemHighlighter has to be verified"); } } return r; } void KListView::cleanItemHighlighter () { if (d->mOldDropHighlighter.isValid()) { QRect rect=d->mOldDropHighlighter; d->mOldDropHighlighter = QRect(); viewport()->repaint(rect, true); } } void KListView::rename(QListViewItem *item, int c) { if (d->renameable.contains(c)) { ensureItemVisible(item); //US d->editor->load(item,c); qDebug("KListView::rename has to be verified"); } } bool KListView::isRenameable (int col) const { return d->renameable.contains(col); } void KListView::setRenameable (int col, bool yesno) { if (col>=header()->count()) return; d->renameable.remove(col); if (yesno && d->renameable.find(col)==d->renameable.end()) d->renameable+=col; else if (!yesno && d->renameable.find(col)!=d->renameable.end()) d->renameable.remove(col); } void KListView::doneEditing(QListViewItem *item, int row) { emit itemRenamed(item, item->text(row), row); emit itemRenamed(item); } bool KListView::acceptDrag(QDropEvent* e) const { qDebug("KListView::acceptDrag drag&drop not supported yet"); //US return acceptDrops() && itemsMovable() && (e->source()==viewport()); return false; } void KListView::setCreateChildren(bool b) { d->createChildren=b; } bool KListView::createChildren() const { return d->createChildren; } int KListView::tooltipColumn() const { return d->tooltipColumn; } void KListView::setTooltipColumn(int column) { d->tooltipColumn=column; } void KListView::setDropHighlighter(bool b) { d->dropHighlighter=b; } bool KListView::dropHighlighter() const { return d->dropHighlighter; } bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const { return ((tooltip(item, column).length()>0) && (column==tooltipColumn())); } QString KListView::tooltip(QListViewItem *item, int column) const { return item->text(column); } void KListView::setTabOrderedRenaming(bool b) { d->tabRename = b; } bool KListView::tabOrderedRenaming() const { return d->tabRename; } void KListView::keyPressEvent (QKeyEvent* e) { //don't we need a contextMenuModifier too ? (aleXXX) if (e->key() == d->contextMenuKey) { emit menuShortCutPressed (this, currentItem()); return; } if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) { emit signalDelete ( ); return; } if (d->selectionMode != FileManager) QListView::keyPressEvent (e); else fileManagerKeyPressEvent (e); } void KListView::activateAutomaticSelection() { d->selectedBySimpleMove=true; d->selectedUsingMouse=false; if (currentItem()!=0) { selectAll(false); currentItem()->setSelected(true); currentItem()->repaint(); emit selectionChanged(); }; } void KListView::deactivateAutomaticSelection() { d->selectedBySimpleMove=false; } bool KListView::automaticSelection() const { return d->selectedBySimpleMove; } diff --git a/microkde/kdeui/klistview.h b/microkde/kdeui/klistview.h index 0058416..9f0d9fd 100644 --- a/microkde/kdeui/klistview.h +++ b/microkde/kdeui/klistview.h @@ -1,1039 +1,1040 @@ /* This file is part of the KDE libraries Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org> Copyright (C) 2000 Charles Samuels <charles@kde.org> Copyright (C) 2000 Peter Putzer <putzer@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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef KLISTVIEW_H #define KLISTVIEW_H #include <qlistview.h> #include <qptrlist.h> //US class QDropEvent; class QDragLeaveEvent; class QDragMoveEvent; class QDragEnterEvent; class QDragObject; class KConfig; class KLineEdit; /** * This Widget extends the functionality of QListView to honor the system * wide settings for Single Click/Double Click mode, AutoSelection and * ChangeCursorOverLink (TM). * * There is a new signal executed(). It gets connected to either * @ref QListView::clicked() or @ref QListView::doubleClicked() depending on the KDE * wide Single Click/Double Click settings. It is strongly recommended that * you use this signal instead of the above mentioned. This way you dont * need to care about the current settings. * If you want to get informed when the user selects something connect to the * QListView::selectionChanged() signal. * * Drag-and-Drop is supported with the signal @ref #dropped(), just @ref #setAcceptDrops(true) * and connect it to a suitable slot. * To see where you are dropping, @ref setDropVisualizer(true). * And also you'll need @ref acceptDrag(QDropEvent*) * * KListView is drag-enabled, too: to benefit from that you've got derive from it. * Reimplement @ref dragObject() and (possibly) @ref startDrag(), * and @ref setDragEnabled(true). * * @version $Id$ */ class KListView : public QListView { Q_OBJECT Q_ENUMS( SelectionModeExt ) Q_PROPERTY( bool fullWidth READ fullWidth WRITE setFullWidth ) Q_PROPERTY( bool itemsMovable READ itemsMovable WRITE setItemsMovable ) Q_PROPERTY( bool itemsRenameable READ itemsRenameable WRITE setItemsRenameable ) Q_PROPERTY( bool dragEnabled READ dragEnabled WRITE setDragEnabled ) Q_PROPERTY( bool autoOpen READ autoOpen WRITE setAutoOpen ) Q_PROPERTY( bool dropVisualizer READ dropVisualizer WRITE setDropVisualizer ) //US Q_PROPERTY( int tooltipColumn READ tooltipColumn WRITE setTooltipColumn ) Q_PROPERTY( int dropVisualizerWidth READ dropVisualizerWidth WRITE setDropVisualizerWidth ) Q_PROPERTY( QColor alternateBackground READ alternateBackground WRITE setAlternateBackground ) Q_OVERRIDE( SelectionModeExt selectionMode READ selectionModeExt WRITE setSelectionModeExt ) public: /** * Possible selection modes. * * The first four correspond directly to QListView::SelectionMode, while * the FileManager selection mode is defined as follows: * @li home: move to the first * @li end: move to the last * @li PgUp/PgDn: move one page up/down * @li up/down: move one item up/down * @li insert: toggle selection of current and move to the next * @li space: toggle selection of the current * @li CTRL+up: move to the previous item and toggle selection of this one * @li CTRL+down: toggle selection of the current item and move to the next * @li CTRL+end: toggle selection from (including) the current * item to (including) the last item * @li CTRL+home: toggle selection from (including) the current * item to the (including) the first item * @li CTRL+PgDn: toggle selection from (including) the current * item to (excluding) the item one page down * @li CTRL+PgUp: toggle selection from (excluding) the current * item to (including) the item one page up * * The combinations work the same with SHIFT instead of CTRL, except * that if you start selecting something using SHIFT everything selected * before will be deselected first. * * Additionally the current item is always selected automatically when * navigating using the keyboard, except other items were selected explicitely. * * This way e.g. SHIFT+up/PgUp then SHIFT+down/PgDn leaves no item selected */ enum SelectionModeExt { Single = QListView::Single, Multi = QListView::Multi, Extended = QListView::Extended, NoSelection = QListView::NoSelection, FileManager }; void repaintContents( bool erase = true ) { QScrollView::repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), erase ); }; /** * Constructor. * * The parameters @p parent and @p name are handled by * @ref QListView, as usual. */ KListView (QWidget *parent = 0, const char *name = 0, bool emulateRightMouse = true ); /** * Destructor. */ virtual ~KListView(); + virtual QSize sizeHint() const; /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void setAcceptDrops (bool); /** * This function determines whether the given coordinates are within the * execute area. The execute area is the part of a @ref QListViewItem where mouse * clicks or double clicks respectively generate a @ref #executed() signal. * Depending on @ref QListView::allColumnsShowFocus() this is either the * whole item or only the first column. * @return true if point is inside execute area of an item, false in all * other cases including the case that it is over the viewport. */ virtual bool isExecuteArea( const QPoint& point ); /** * Same thing, but from an x coordinate only. This only checks if x is in * the first column (if all columns don't show focus), without testing if * the y coordinate is over an item or not. */ bool isExecuteArea( int x ); /** * @return a list containing the currently selected items. */ QPtrList<QListViewItem> selectedItems() const; // ### BIC: KDE 4: use an implicitly shared class! (QValueList?) /** * Arbitrarily move @p item to @p parent, positioned immediately after item @p after. */ void moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after); /** * @return the last item (not child!) of this listview. * * @see lastChild() */ QListViewItem *lastItem() const; /** * @return the last child of this listview. * * @see lastItem() */ QListViewItem* lastChild () const; /** * @return the lineedit used for inline renaming. * Use that to setup a @ref KCompletion or @ref QValidator for the lineedit * * @since 3.2 */ KLineEdit* renameLineEdit() const; /** * @returns if it is legal to move items in the list view. True by default. * * @see #setDragEnabled() * @see #setItemsMovable() */ bool itemsMovable() const; /** * @return whether inplace-renaming has been enabled. False by default. * * @see #setItemsRenameable() */ bool itemsRenameable() const; /** * @return whether dragging is enabled. False by default. * * @see #setDragEnabled() */ bool dragEnabled() const; /** * @return true if AutoOpen is enabled (not implemented currently). * * @see #setAutoOpen() */ bool autoOpen() const; /** * @return true if @p column is renamable. * * @see #setRenameable() */ bool isRenameable (int column) const; /** * @return true if drawing of the drop-visualizer has been enabled. True by default. * * @see #setDropVisualizer() */ bool dropVisualizer() const; /** * @return the column for which tooltips are displayed (or -1 if none set). * * @see #setTooltipColumn() */ int tooltipColumn() const; /** * For future expansions. * * Do not use. * @deprecated */ bool createChildren() const; /** * @return true if drawing of the drop-highlighter has been enabled. False by default. * * @see #setDropHighlighter() */ bool dropHighlighter() const; /** * The dropVisualizerWidth defaults to 4. * * @see #setDropVisualizerWidth() * @return the current width of the drop-visualizer. */ int dropVisualizerWidth () const; /** * @return the "extended" selection mode of this listview. * * @see SelectionModeExt * @see setSelectionModeExt */ SelectionModeExt selectionModeExt () const; /** * Returns the index of @p item within the item tree or -1 if * @p item doesn't exist in this list view. This function takes * all items into account not only the visible ones. */ int itemIndex( const QListViewItem *item ) const; /** * Returns the item of @p index within the item tree or 0 if * @p index doesn't exist in this list view. This function takes * all items into account not only the visible ones. */ QListViewItem* itemAtIndex(int index); /** * @deprecated * @see #setFullWidth() */ void setFullWidth(); /** * Let the last column fit exactly all the available width. * * @see #fullWidth() */ void setFullWidth(bool fullWidth); /** * Returns whether the last column is set to fit the available width. * * @see #setFullWidth() */ bool fullWidth() const; /** * Reimplemented for full width support * * @see #removeColumn() */ virtual int addColumn(const QString& label, int width = -1); /** * Reimplemented for full width support */ virtual int addColumn(const QIconSet& iconset, const QString& label, int width = -1); /** * Reimplemented for full width support * * @see #addColumn() */ virtual void removeColumn(int index); /** * sets the alternate background background color. * This only has an effect if the items are KListViewItems * * @param c the color to use for every other item. Set to an invalid * colour to disable alternate colours. * * @see #alternateBackground() **/ void setAlternateBackground(const QColor &c); /** * @return the alternate background color * * @see #setAlternateBackground() */ const QColor &alternateBackground() const; /** * Saves the list view's layout (column widtsh, column order, sort column) * to a KConfig group * * @param config the @ref KConfig object to write to * @param group the config group to use */ void saveLayout(KConfig *config, const QString &group) const; /** * Reads the list view's layout from a KConfig group as stored with * @ref #saveLayout * * @param config the @ref KConfig object to read from * @param group the config group to use */ void restoreLayout(KConfig *config, const QString &group); /** * Reimplemented to remember the current sort column and order. * @param column is the column to be sorted, or -1 to sort in order of * insertion * @param whether to sort ascending (or descending) */ virtual void setSorting(int column, bool ascending = true); /** * @return the currently sorted column, or -1 if none is sorted */ int columnSorted(void) const; /** * @return whether the current sort is ascending (or descending) */ bool ascendingSort(void) const; //US we do not have a "global KDE" variable to setup singleClick functionality void setSingleClick(bool s); signals: /** * This signal is emitted whenever the user executes an listview item. * That means depending on the KDE wide Single Click/Double Click * setting the user clicked or double clicked on that item. * @param item is the pointer to the executed listview item. * * Note that you may not delete any @ref QListViewItem objects in slots * connected to this signal. */ void executed( QListViewItem *item ); /** * This signal is emitted whenever the user executes an listview item. * That means depending on the KDE wide Single Click/Double Click * setting the user clicked or double clicked on that item. * @param item is the pointer to the executed listview item. * @param pos is the position where the user has clicked * @param c is the column into which the user clicked. * * Note that you may not delete any @ref QListViewItem objects in slots * connected to this signal. */ void executed( QListViewItem *item, const QPoint &pos, int c ); /** * This signal gets emitted whenever the user double clicks into the * listview. * @param item is the pointer to the clicked listview item. * @param pos is the position where the user has clicked, and * @param c is the column into which the user clicked. * * Note that you may not delete any @ref QListViewItem objects in slots * connected to this signal. * * This signal is more or less here for the sake of completeness. * You should normally not need to use this. In most cases its better * to use @ref #executed() instead. */ void doubleClicked( QListViewItem *item, const QPoint &pos, int c ); void contextRequest( QListViewItem *item, const QPoint &pos, int c ); /** * This signal gets emitted whenever something acceptable is * dropped onto the listview. * * @param e is the drop event itself (it has already been accepted) * @param after is the item after which the drop occured (or 0L, if * the drop was above all items) * * @see #acceptDrop() */ void dropped (QDropEvent * e, QListViewItem *after); /** * This signal gets emitted whenever something acceptable is * dropped onto the listview. * * This is an overloaded version of the above (provided to simplify * processing drops outside of the class). * * @param list is the listview * @param e is the drop event itself (it has already been accepted) * @param after is the item after which the drop occured (or 0L, if * the drop was above all items */ void dropped (KListView* list, QDropEvent* e, QListViewItem* after); /** * This signal gets emitted whenever something acceptable is * dropped onto the listview. * * This function also provides a parent, in the event that your listview * is a tree * @param list is the listview * @param e is the drop event itself (it has already been accepted) * @param parent the item that is to be the parent of the new item * @param after is the item after which the drop occured (or 0L, if * the drop was above all items */ void dropped (KListView* list, QDropEvent* e, QListViewItem* parent, QListViewItem* after); /** * This signal gets emitted whenever something acceptable is * dropped onto the listview. * * This function also provides a parent, in the event that your listview * is a tree * @param e is the drop event itself (it has already been accepted) * @param parent the item that is to be the parent of the new item * @param after is the item after which the drop occured (or 0L, if * the drop was above all items */ void dropped (QDropEvent* e, QListViewItem* parent, QListViewItem* after); /** * This signal is emitted when ever the user moves an item in the list via * DnD. * If more than one item is moved at the same time, this signal is only emitted * once. */ void moved(); /** * Connect to this signal if you want to do some preprocessing before * a move is made, for example, to disable sorting * * This is sent only once per each groups of moves. That is, for each * drop that is a move this will be emitted once, before KListView calls * @see moveItem() */ void aboutToMove(); /** * This signal is emitted when ever the user moves an item in the list via * DnD. * If more than one item is moved at the same time, @p afterFirst and * @p afterNow will reflect what was true before the move. * This differs from @ref moved(), so be careful. All the items will have been * moved before @ref moved() is emitted, which is not true in this method. // FIXME * @param item the item that was moved * @param afterFirst the item that parameter item was in before the move, in the list * @param afterNow the item it's currently after. */ void moved (QListViewItem *item, QListViewItem *afterFirst, QListViewItem *afterNow); /** * This signal is emitted after all the items have been moved. It reports info for * each and every item moved, in order. The first element in @p items associates * with the first of afterFirst and afterNow. */ void moved(QPtrList<QListViewItem> &items, QPtrList<QListViewItem> &afterFirst, QPtrList<QListViewItem> &afterNow); /** * This signal gets emitted when an item is renamed via in-place renaming. * * @param item is the renamed item. * @param str is the new value of column @p col. * @param col is the renamed column. */ void itemRenamed(QListViewItem* item, const QString &str, int col); /** * Same as above, but without the extra information. */ void itemRenamed(QListViewItem* item); void signalDelete(); /** * This signal is emitted when the shortcut key for popup-menus is pressed. * * Normally you should not use this, just connect a slot to signal * @ref contextMenu (KListView*, QListViewItem*, const QPoint&) to correctly * handle showing context menus regardless of settings. * * @param list is this listview. * @param item is the @ref currentItem() at the time the key was pressed. May be 0L. */ void menuShortCutPressed (KListView* list, QListViewItem* item); /** * This signal is emitted whenever a context-menu should be shown for item @p i. * It automatically adjusts for all settings involved (Menu key, showMenuOnPress/Click). * * @param l is this listview. * @param i is the item for which the menu should be shown. May be 0L. * @param p is the point at which the menu should be shown. */ void contextMenu (KListView* l, QListViewItem* i, const QPoint& p); public slots: /** * Rename column @p c of @p item. */ virtual void rename(QListViewItem *item, int c); /** * By default, if you called setItemsRenameable(true), * only the first column is renameable. * Use this function to enable the feature on other columns. * * If you want more intelligent (dynamic) selection, * you'll have to derive from KListView, * and override @ref rename() and call only call it * if you want the item to be renamed. */ void setRenameable (int column, bool yesno=true); /** * Set whether items in the list view can be moved. * It is enabled by default. * * @see itemsMovable() */ virtual void setItemsMovable(bool b); /** * Enables inplace-renaming of items. * It is disabled by default. * * @see itemsRenameable() * @see setRenameable() */ virtual void setItemsRenameable(bool b); /** * Enable/Disable the dragging of items. * It is disabled by default. */ virtual void setDragEnabled(bool b); /** * Enable/Disable AutoOpen (not implemented currently). */ virtual void setAutoOpen(bool b); /** * Enable/Disable the drawing of a drop-visualizer * (a bar that shows where a dropped item would be inserted). * It is enabled by default, if dragging is enabled */ virtual void setDropVisualizer(bool b); /** * Set the width of the (default) drop-visualizer. * If you don't call this method, the width is set to 4. */ void setDropVisualizerWidth (int w); /** * Set which column should be used for automatic tooltips. * * @param column is the column for which tooltips will be shown. * Set -1 to disable this feature. */ virtual void setTooltipColumn(int column); /** * Enable/Disable the drawing of a drop-highlighter * (a rectangle around the item under the mouse cursor). * It is disabled by default. */ virtual void setDropHighlighter(bool b); /** * For future expansions. * * Do not use. * @deprecated */ virtual void setCreateChildren(bool b); /** * Set the selection mode. * * A different name was chosen to avoid API-clashes with @ref QListView::setSelectionMode(). */ void setSelectionModeExt (SelectionModeExt mode); /** * Enable/disable tabbing between editable cells * @since 3.1 */ void setTabOrderedRenaming(bool b); /** * Returns whether tab ordered renaming is enabled * @since 3.1 */ bool tabOrderedRenaming() const; protected: /** * Determine whether a drop on position @p p would count as * being above or below the QRect @p rect. * * @param rect is the rectangle we examine. * @param p is the point located in the rectangle, p is assumed to be in * viewport coordinates. */ inline bool below (const QRect& rect, const QPoint& p) { return (p.y() > (rect.top() + (rect.bottom() - rect.top())/2)); } /** * An overloaded version of below(const QRect&, const QPoint&). * * It differs from the above only in what arguments it takes. * * @param i the item whose rect() is passed to the above function. * @param p is translated from contents coordinates to viewport coordinates * before being passed to the above function. */ inline bool below (QListViewItem* i, const QPoint& p) { return below (itemRect(i), contentsToViewport(p)); } /** * Reimplemented to reload the alternate background in palette changes. * @internal */ virtual bool event( QEvent * ); /** * Emit signal @ref #executed. * @internal */ //US I added buttonstate to pass the current keyboard status void emitExecute( int buttonstate, QListViewItem *item, const QPoint &pos, int c); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void focusInEvent(QFocusEvent* fe); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void focusOutEvent( QFocusEvent *fe ); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void leaveEvent( QEvent *e ); /** * @return the tooltip for @p column of @p item. */ virtual QString tooltip(QListViewItem* item, int column) const; /** * @return whether the tooltip for @p column of @p item shall be shown at point @p pos. */ virtual bool showTooltip(QListViewItem *item, const QPoint &pos, int column) const; /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsDragMoveEvent (QDragMoveEvent *event); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsMousePressEvent( QMouseEvent *e ); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsMouseMoveEvent( QMouseEvent *e ); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsMouseDoubleClickEvent ( QMouseEvent *e ); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsDragLeaveEvent (QDragLeaveEvent *event); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsMouseReleaseEvent (QMouseEvent*); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsDropEvent (QDropEvent*); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void contentsDragEnterEvent (QDragEnterEvent *); /** * @return a dragobject encoding the current selection. * * @see setDragEnabled() */ virtual QDragObject *dragObject(); /** * @return true if the @p event provides some acceptable * format. * A common mistake is to forget the "const" in your reimplementation */ virtual bool acceptDrag (QDropEvent* event) const; /** * Paint the drag line. If painter is null, don't try to :) * * If after == 0 then the marker should be drawn at the top. * * @return the rectangle that you painted to. */ virtual QRect drawDropVisualizer (QPainter *p, QListViewItem *parent, QListViewItem *after); /** * Paint the drag rectangle. If painter is null, don't try to :) * * * @return the rectangle that you painted to. */ virtual QRect drawItemHighlighter(QPainter *painter, QListViewItem *item); /** * This method calls @ref dragObject() and starts the drag. * * Reimplement it to do fancy stuff like setting a pixmap or * using a non-default DragMode */ virtual void startDrag(); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void keyPressEvent (QKeyEvent*); /** * Reimplemented for internal reasons. * Further reimplementations should call this function or else * some features may not work correctly. * * The API is unaffected. */ virtual void viewportPaintEvent(QPaintEvent*); /** * In FileManager selection mode: explicitely activate the mode * in which the current item is automatically selected. */ void activateAutomaticSelection(); /** * In FileManager selection mode: explicitely deactivate the mode * in which the current item is automatically selected. */ void deactivateAutomaticSelection(); /** * In FileManager selection mode: return whether it is currently in the mode * where the current item is selected automatically. * Returns false if items were selected explicitely, e.g. using the mouse. */ bool automaticSelection() const; /** * Reimplemented for setFullWidth() */ virtual void viewportResizeEvent(QResizeEvent* e); protected slots: /** * Update internal settings whenever the global ones change. * @internal */ void slotSettingsChanged(int); void slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c ); void doneEditing(QListViewItem *item, int row); /** * Repaint the rect where I was drawing the drop line. */ void cleanDropVisualizer(); /** * Repaint the rect where I was drawing the drop rectangle. */ void cleanItemHighlighter(); /** * Emit the @ref contextMenu signal. This slot is for mouse actions. */ void emitContextMenu (QListViewItem*, const QPoint&, int); /** * Emit the @ref #contextMenu signal. This slot is for key presses. */ void emitContextMenu (KListView*, QListViewItem*); /** * Accessory slot for AutoSelect * @internal */ void slotOnItem( QListViewItem *item ); /** * Accessory slot for AutoSelect/ChangeCursorOverItem * @internal */ void slotOnViewport(); /** * Process AutoSelection. * @internal */ void slotAutoSelect(); void slotDragExpand(); /** * Reacts to header changes in full width mode * @internal */ void slotHeaderChanged(); protected: /** * Handle dropEvent when itemsMovable() is set to true. */ virtual void movableDropEvent (QListViewItem* parent, QListViewItem* afterme); /** * Where is the nearest QListViewItem that I'm going to drop? * * FIXME KDE 4.0: Make this method const so it can be called from an * acceptDrag method without ugly casts */ virtual void findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after); /** * A special keyPressEvent (for FileManager selection mode). */ void fileManagerKeyPressEvent (QKeyEvent*); /** * Convert the depth of an item into its indentation in pixels */ int depthToPixels( int depth ); private: class Tooltip; protected: virtual void virtual_hook( int id, void* data ); private: class KListViewPrivate; KListViewPrivate *d; }; /** * A listview item with support for alternate background colours. It is * a drop-in replacement for @ref QListViewItem * * @short listview item with alternate background colour support */ class KListViewItem : public QListViewItem { public: /** * constructors. The semantics remain as in @ref QListViewItem. * Although they accept a @ref QListViewItem as parent, please * don't mix KListViewItem (or subclasses) with QListViewItem * (or subclasses). */ KListViewItem(QListView *parent); KListViewItem(QListViewItem *parent); KListViewItem(QListView *parent, QListViewItem *after); KListViewItem(QListViewItem *parent, QListViewItem *after); KListViewItem(QListView *parent, QString, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null); KListViewItem(QListViewItem *parent, QString, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null); KListViewItem(QListView *parent, QListViewItem *after, QString, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null); KListViewItem(QListViewItem *parent, QListViewItem *after, QString, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null, QString = QString::null); virtual ~KListViewItem(); /** * retuns true if this item is to be drawn with the alternate background */ bool isAlternate(); /** * returns the background colour for this item */ const QColor &backgroundColor(); virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment); private: void init(); private: uint m_odd : 1; uint m_known : 1; uint m_unused : 30; }; #endif // vim: ts=2 sw=2 et |