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.
23 #include <QHeaderView>
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 );
39 setRootIsDecorated(false);
42 _toolTip = new QY2ListViewToolTip( this );
46 header()->installEventFilter( this );
48 connect( this, SIGNAL( columnResized ( int, int, int ) ),
49 this, SLOT ( columnWidthChanged( int, int, int ) ) );
53 QY2ListView::~QY2ListView()
63 QY2ListView::selectSomething()
65 QTreeWidgetItemIterator it( this );
69 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
71 if ( item && (item->flags() & Qt::ItemIsSelectable) )
73 item->setSelected(true); // emits signal, too
86 restoreColumnWidths();
91 QY2ListView::updateItemStates()
93 QTreeWidgetItemIterator it( this );
97 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
100 item->updateStatus();
108 QY2ListView::updateItemData()
110 QTreeWidgetItemIterator it( this );
114 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
125 QY2ListView::toolTip( QTreeWidgetItem * listViewItem, int column )
127 if ( ! listViewItem )
128 return QString::null;
133 text.sprintf( "Column %d:\n%s", column, (const char *) listViewItem->text( column ) );
136 // Try known item classes
138 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (listViewItem);
141 return item->toolTip( column );
143 QY2CheckListItem * checkListItem = dynamic_cast<QY2CheckListItem *> (listViewItem);
146 return checkListItem->toolTip( column );
148 return QString::null;
153 QY2ListView::saveColumnWidths()
155 _savedColumnWidth.clear();
156 _savedColumnWidth.reserve( columnCount() );
158 for ( int i = 0; i < columnCount(); i++ )
160 _savedColumnWidth.push_back( columnWidth(i) );
166 QY2ListView::restoreColumnWidths()
168 if ( _savedColumnWidth.size() != (unsigned) columnCount() ) // never manually resized
170 for ( int i = 0; i < columnCount(); i++ ) // use optimized column width
171 resizeColumnToContents(i);
173 else // stored settings after manual resizing
175 for ( int i = 0; i < columnCount(); i++ )
177 setColumnWidth( i, _savedColumnWidth[ i ] ); // restore saved column width
184 QY2ListView::contentsMousePressEvent( QMouseEvent * ev )
186 //FIXME may be convert to global
187 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
189 if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
191 _mousePressedItem = item;
192 //FIXME _mousePressedCol = header()->sectionAt( ev->pos().x() );
193 _mousePressedButton = ev->button();
195 else // invalidate last click data
197 _mousePressedItem = 0;
198 _mousePressedCol = -1;
199 _mousePressedButton = -1;
202 // Call base class method
203 //FIXME QTreeWidget::contentsMousePressEvent( ev );
208 QY2ListView::contentsMouseReleaseEvent( QMouseEvent * ev )
210 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
212 if ( item && ( item->flags() & Qt::ItemIsEnabled ) && item == _mousePressedItem )
215 // int col = header()->sectionAt( ev->pos().x() );
217 // if ( item == _mousePressedItem &&
218 // col == _mousePressedCol &&
219 // ev->button() == _mousePressedButton )
221 // emit( columnClicked( ev->button(), item, col, ev->globalPos() ) );
226 // invalidate last click data
228 _mousePressedItem = 0;
229 _mousePressedCol = -1;
230 _mousePressedButton = Qt::NoButton;
232 // Call base class method
233 //FIXME QTreeWidget::contentsMouseReleaseEvent( ev );
238 QY2ListView::contentsMouseDoubleClickEvent( QMouseEvent * ev )
240 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
242 if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
244 int col = header()->logicalIndexAt( ev->pos().x() );
245 emit( columnDoubleClicked( ev->button(), (QY2ListViewItem *) item, col, ev->globalPos() ) );
248 // invalidate last click data
250 _mousePressedItem = 0;
251 _mousePressedCol = -1;
252 _mousePressedButton = Qt::NoButton;
254 // // Call base class method
255 // QTreeWidget::contentsMouseDoubleClickEvent( ev );
260 QY2ListView::columnWidthChanged( int, int, int )
262 // Workaround for Qt bug:
264 // QHeader sends a sizeChange() signal for every size change, not only (as
265 // documented) when the user resizes a header column manually. But we only
266 // want to record the column widths if the user explicitly did that, so
267 // ignore those signals if the mouse isn't pressed. There is also one final
268 // sizeChange() signal immediately after the user releases the mouse button.
270 if ( _mouseButton1PressedInHeader || _finalSizeChangeExpected )
274 // Consume that one sizeChange() signal that is sent immediately after
275 // the mouse button is released, but make sure to reset that flag only
278 if ( ! _mouseButton1PressedInHeader )
279 _finalSizeChangeExpected = false;
285 QY2ListView::eventFilter( QObject * obj, QEvent * event )
287 if ( event && obj && obj == header() )
289 if ( event->type() == QEvent::MouseButtonPress )
291 QMouseEvent * mouseEvent = (QMouseEvent *) event;
293 if ( mouseEvent->button() == 1 )
295 _mouseButton1PressedInHeader = true;
296 _finalSizeChangeExpected = false;
299 else if ( event->type() == QEvent::MouseButtonRelease )
301 QMouseEvent * mouseEvent = (QMouseEvent *) event;
303 if ( mouseEvent->button() == 1 )
305 _finalSizeChangeExpected = true;
306 _mouseButton1PressedInHeader = false;
311 return QTreeWidget::eventFilter( obj, event );
316 QY2ListView::minimumSizeHint() const
318 return QSize( 0, 0 );
323 QY2ListView::setSortByInsertionSequence( bool sortByInsertionSequence )
325 _sortByInsertionSequence = sortByInsertionSequence;
334 QY2ListViewItem::QY2ListViewItem( QY2ListView * parentListView,
335 const QString & text )
336 : QTreeWidgetItem( parentListView, QStringList(text), 1)
338 _serial = parentListView->nextSerial();
342 QY2ListViewItem::QY2ListViewItem( QTreeWidgetItem * parentItem,
343 const QString & text )
344 : QTreeWidgetItem( parentItem, QStringList(text), 1 )
348 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
350 if ( parentListView )
351 _serial = parentListView->nextSerial();
355 QY2ListViewItem::~QY2ListViewItem()
362 * Comparison function used for sorting the list.
369 QY2ListViewItem::compare( QTreeWidgetItem * otherListViewItem,
371 bool ascending ) const
373 bool sortByInsertionSequence = false;
374 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
376 if ( parentListView )
377 sortByInsertionSequence = parentListView->sortByInsertionSequence();
379 if ( sortByInsertionSequence )
381 QY2ListViewItem * other = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
385 if ( this->serial() < other->serial() ) return -1;
386 if ( this->serial() > other->serial() ) return 1;
390 // Still here? Try the other version: QY2CheckListItem.
392 QY2CheckListItem * otherCheckListItem = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
394 if ( otherCheckListItem )
396 if ( this->serial() < otherCheckListItem->serial() ) return -1;
397 if ( this->serial() > otherCheckListItem->serial() ) return 1;
403 //return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
409 // QY2ListViewItem::paintCell( QPainter * painter,
410 // const QColorGroup & colorGroup,
415 // QColorGroup cg = colorGroup;
417 // if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
418 // if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
420 // QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
428 QY2CheckListItem::QY2CheckListItem( QY2ListView * parentListView,
429 const QString & text )
430 : QTreeWidgetItem( parentListView, QStringList(text))
432 setFlags(Qt::ItemIsUserCheckable);
433 setCheckState(0, Qt::Unchecked);
434 _serial = parentListView->nextSerial();
438 QY2CheckListItem::QY2CheckListItem( QTreeWidgetItem * parentItem,
439 const QString & text )
440 : QTreeWidgetItem( parentItem, QStringList(text))
443 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
445 if ( parentListView )
446 _serial = parentListView->nextSerial();
449 QY2CheckListItem::~QY2CheckListItem()
456 * Comparison function used for sorting the list.
463 QY2CheckListItem::compare( QTreeWidgetItem * otherListViewItem,
465 bool ascending ) const
467 bool sortByInsertionSequence = false;
468 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
470 if ( parentListView )
471 sortByInsertionSequence = parentListView->sortByInsertionSequence();
473 if ( sortByInsertionSequence )
475 QY2CheckListItem * other = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
479 if ( this->serial() < other->serial() ) return -1;
480 if ( this->serial() > other->serial() ) return 1;
485 // Still here? Try the other version: QY2ListViewItem.
487 QY2ListViewItem * otherCheckListItem = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
489 if ( otherCheckListItem )
491 if ( this->serial() < otherCheckListItem->serial() ) return -1;
492 if ( this->serial() > otherCheckListItem->serial() ) return 1;
498 //FIXME return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
504 QY2CheckListItem::paintCell( QPainter * painter,
505 const QColorGroup & colorGroup,
510 QColorGroup cg = colorGroup;
512 if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
513 if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
515 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
521 QY2ListViewToolTip::maybeTip( const QPoint & pos )
523 Q3Header * header = _listView->header();
524 QTreeWidgetItem * item = _listView->itemAt( pos );
529 int x = _listView->viewportToContents( pos ).x();
530 int column = header->sectionAt(x);
535 indent = item->depth() + ( _listView->rootIsDecorated() ? 1 : 0 );
536 indent *= _listView->treeStepSize();
538 if ( pos.x() < indent )
542 QString text = _listView->toolTip( item, column );
544 if ( ! text.isEmpty() )
546 QRect rect( _listView->itemRect( item ) );
551 rect.setWidth( indent );
555 QPoint topLeft( header->sectionPos( column ), 0 );
556 topLeft = _listView->contentsToViewport( topLeft );
557 rect.setX( topLeft.x() );
558 rect.setWidth( header->sectionSize( column ) );
568 #include "QY2ListView.moc"