1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
17 This is a pure Qt widget - it can be used independently of YaST2.
24 #include <QMouseEvent>
25 #include "QY2ListView.h"
28 QY2ListView::QY2ListView( QWidget * parent )
29 : QTreeWidget( parent )
30 , _mousePressedItem(0)
31 , _mousePressedCol( -1 )
32 , _mousePressedButton( Qt::NoButton )
33 , _sortByInsertionSequence( false )
35 , _mouseButton1PressedInHeader( false )
36 , _finalSizeChangeExpected( false )
38 //FIXME QTreeWidget::setShowToolTips( false );
41 _toolTip = new QY2ListViewToolTip( this );
45 // header()->installEventFilter( this );
47 connect( this, SIGNAL( columnResized ( int, int, int ) ),
48 this, SLOT ( columnWidthChanged( int, int, int ) ) );
52 QY2ListView::~QY2ListView()
62 QY2ListView::selectSomething()
64 QTreeWidgetItemIterator it( this );
68 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
70 if ( item && (item->flags() & Qt::ItemIsSelectable) )
72 item->setSelected(true); // emits signal, too
85 restoreColumnWidths();
90 QY2ListView::updateItemStates()
92 QTreeWidgetItemIterator it( this );
96 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
107 QY2ListView::updateItemData()
109 QTreeWidgetItemIterator it( this );
113 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
124 QY2ListView::toolTip( QTreeWidgetItem * listViewItem, int column )
126 if ( ! listViewItem )
127 return QString::null;
132 text.sprintf( "Column %d:\n%s", column, (const char *) listViewItem->text( column ) );
135 // Try known item classes
137 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (listViewItem);
140 return item->toolTip( column );
142 QY2CheckListItem * checkListItem = dynamic_cast<QY2CheckListItem *> (listViewItem);
145 return checkListItem->toolTip( column );
147 return QString::null;
152 QY2ListView::saveColumnWidths()
154 _savedColumnWidth.clear();
155 _savedColumnWidth.reserve( columnCount() );
157 for ( int i = 0; i < columnCount(); i++ )
159 _savedColumnWidth.push_back( columnWidth(i) );
165 QY2ListView::restoreColumnWidths()
167 if ( _savedColumnWidth.size() != (unsigned) columnCount() ) // never manually resized
169 for ( int i = 0; i < columnCount(); i++ ) // use optimized column width
170 resizeColumnToContents(i);
172 else // stored settings after manual resizing
174 for ( int i = 0; i < columnCount(); i++ )
176 setColumnWidth( i, _savedColumnWidth[ i ] ); // restore saved column width
183 QY2ListView::contentsMousePressEvent( QMouseEvent * ev )
185 //FIXME may be convert to global
186 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
188 if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
190 _mousePressedItem = item;
191 //FIXME _mousePressedCol = header()->sectionAt( ev->pos().x() );
192 _mousePressedButton = ev->button();
194 else // invalidate last click data
196 _mousePressedItem = 0;
197 _mousePressedCol = -1;
198 _mousePressedButton = -1;
201 // Call base class method
202 //FIXME QTreeWidget::contentsMousePressEvent( ev );
207 QY2ListView::contentsMouseReleaseEvent( QMouseEvent * ev )
209 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
211 if ( item && ( item->flags() & Qt::ItemIsEnabled ) && item == _mousePressedItem )
214 // int col = header()->sectionAt( ev->pos().x() );
216 // if ( item == _mousePressedItem &&
217 // col == _mousePressedCol &&
218 // ev->button() == _mousePressedButton )
220 // emit( columnClicked( ev->button(), item, col, ev->globalPos() ) );
225 // invalidate last click data
227 _mousePressedItem = 0;
228 _mousePressedCol = -1;
229 _mousePressedButton = Qt::NoButton;
231 // Call base class method
232 //FIXME QTreeWidget::contentsMouseReleaseEvent( ev );
237 QY2ListView::contentsMouseDoubleClickEvent( QMouseEvent * ev )
239 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
241 // if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
243 // int col = header()->sectionAt( ev->pos().x() );
244 // emit( columnDoubleClicked( ev->button(), (QY2ListViewItem *) item, col, ev->globalPos() ) );
247 // // invalidate last click data
249 // _mousePressedItem = 0;
250 // _mousePressedCol = -1;
251 // _mousePressedButton = Qt::NoButton;
253 // // Call base class method
254 // QTreeWidget::contentsMouseDoubleClickEvent( ev );
259 QY2ListView::columnWidthChanged( int, int, int )
261 // Workaround for Qt bug:
263 // QHeader sends a sizeChange() signal for every size change, not only (as
264 // documented) when the user resizes a header column manually. But we only
265 // want to record the column widths if the user explicitly did that, so
266 // ignore those signals if the mouse isn't pressed. There is also one final
267 // sizeChange() signal immediately after the user releases the mouse button.
269 if ( _mouseButton1PressedInHeader || _finalSizeChangeExpected )
273 // Consume that one sizeChange() signal that is sent immediately after
274 // the mouse button is released, but make sure to reset that flag only
277 if ( ! _mouseButton1PressedInHeader )
278 _finalSizeChangeExpected = false;
284 QY2ListView::eventFilter( QObject * obj, QEvent * event )
286 // if ( event && obj && obj == header() )
288 // if ( event->type() == QEvent::MouseButtonPress )
290 // QMouseEvent * mouseEvent = (QMouseEvent *) event;
292 // if ( mouseEvent->button() == 1 )
294 // _mouseButton1PressedInHeader = true;
295 // _finalSizeChangeExpected = false;
298 // else if ( event->type() == QEvent::MouseButtonRelease )
300 // QMouseEvent * mouseEvent = (QMouseEvent *) event;
302 // if ( mouseEvent->button() == 1 )
304 // _finalSizeChangeExpected = true;
305 // _mouseButton1PressedInHeader = false;
310 return QTreeWidget::eventFilter( obj, event );
315 QY2ListView::minimumSizeHint() const
317 return QSize( 0, 0 );
322 QY2ListView::setSortByInsertionSequence( bool sortByInsertionSequence )
324 _sortByInsertionSequence = sortByInsertionSequence;
333 QY2ListViewItem::QY2ListViewItem( QY2ListView * parentListView,
334 const QString & text )
335 : QTreeWidgetItem( parentListView, QStringList(text), 1)
337 _serial = parentListView->nextSerial();
341 QY2ListViewItem::QY2ListViewItem( QTreeWidgetItem * parentItem,
342 const QString & text )
343 : QTreeWidgetItem( parentItem, QStringList(text), 1 )
347 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
349 if ( parentListView )
350 _serial = parentListView->nextSerial();
354 QY2ListViewItem::~QY2ListViewItem()
361 * Comparison function used for sorting the list.
368 QY2ListViewItem::compare( QTreeWidgetItem * otherListViewItem,
370 bool ascending ) const
372 bool sortByInsertionSequence = false;
373 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
375 if ( parentListView )
376 sortByInsertionSequence = parentListView->sortByInsertionSequence();
378 if ( sortByInsertionSequence )
380 QY2ListViewItem * other = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
384 if ( this->serial() < other->serial() ) return -1;
385 if ( this->serial() > other->serial() ) return 1;
389 // Still here? Try the other version: QY2CheckListItem.
391 QY2CheckListItem * otherCheckListItem = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
393 if ( otherCheckListItem )
395 if ( this->serial() < otherCheckListItem->serial() ) return -1;
396 if ( this->serial() > otherCheckListItem->serial() ) return 1;
402 //return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
408 // QY2ListViewItem::paintCell( QPainter * painter,
409 // const QColorGroup & colorGroup,
414 // QColorGroup cg = colorGroup;
416 // if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
417 // if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
419 // QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
427 QY2CheckListItem::QY2CheckListItem( QY2ListView * parentListView,
428 const QString & text )
429 : QTreeWidgetItem( parentListView, QStringList(text), 1 )
431 _serial = parentListView->nextSerial();
435 QY2CheckListItem::QY2CheckListItem( QTreeWidgetItem * parentItem,
436 const QString & text )
437 : QTreeWidgetItem( parentItem, QStringList(text), 1 )
440 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
442 if ( parentListView )
443 _serial = parentListView->nextSerial();
446 QY2CheckListItem::~QY2CheckListItem()
453 * Comparison function used for sorting the list.
460 QY2CheckListItem::compare( QTreeWidgetItem * otherListViewItem,
462 bool ascending ) const
464 bool sortByInsertionSequence = false;
465 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
467 if ( parentListView )
468 sortByInsertionSequence = parentListView->sortByInsertionSequence();
470 if ( sortByInsertionSequence )
472 QY2CheckListItem * other = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
476 if ( this->serial() < other->serial() ) return -1;
477 if ( this->serial() > other->serial() ) return 1;
482 // Still here? Try the other version: QY2ListViewItem.
484 QY2ListViewItem * otherCheckListItem = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
486 if ( otherCheckListItem )
488 if ( this->serial() < otherCheckListItem->serial() ) return -1;
489 if ( this->serial() > otherCheckListItem->serial() ) return 1;
495 //FIXME return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
501 QY2CheckListItem::paintCell( QPainter * painter,
502 const QColorGroup & colorGroup,
507 QColorGroup cg = colorGroup;
509 if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
510 if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
512 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
518 QY2ListViewToolTip::maybeTip( const QPoint & pos )
520 Q3Header * header = _listView->header();
521 QTreeWidgetItem * item = _listView->itemAt( pos );
526 int x = _listView->viewportToContents( pos ).x();
527 int column = header->sectionAt(x);
532 indent = item->depth() + ( _listView->rootIsDecorated() ? 1 : 0 );
533 indent *= _listView->treeStepSize();
535 if ( pos.x() < indent )
539 QString text = _listView->toolTip( item, column );
541 if ( ! text.isEmpty() )
543 QRect rect( _listView->itemRect( item ) );
548 rect.setWidth( indent );
552 QPoint topLeft( header->sectionPos( column ), 0 );
553 topLeft = _listView->contentsToViewport( topLeft );
554 rect.setX( topLeft.x() );
555 rect.setWidth( header->sectionSize( column ) );
565 #include "QY2ListView.moc"