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 );
49 connect( this, SIGNAL( columnResized ( int, int, int ) ),
50 this, SLOT ( columnWidthChanged( int, int, int ) ) );
55 QY2ListView::~QY2ListView()
65 QY2ListView::selectSomething()
67 QTreeWidgetItemIterator it( this );
71 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
73 if ( item && (item->flags() & Qt::ItemIsSelectable) )
75 item->setSelected(true); // emits signal, too
88 restoreColumnWidths();
93 QY2ListView::updateItemStates()
95 QTreeWidgetItemIterator it( this );
99 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
102 item->updateStatus();
110 QY2ListView::updateItemData()
112 QTreeWidgetItemIterator it( this );
116 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
127 QY2ListView::toolTip( QTreeWidgetItem * listViewItem, int column )
129 if ( ! listViewItem )
130 return QString::null;
135 text.sprintf( "Column %d:\n%s", column, (const char *) listViewItem->text( column ) );
138 // Try known item classes
140 QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (listViewItem);
143 return item->toolTip( column );
145 QY2CheckListItem * checkListItem = dynamic_cast<QY2CheckListItem *> (listViewItem);
148 return checkListItem->toolTip( column );
150 return QString::null;
155 QY2ListView::saveColumnWidths()
157 _savedColumnWidth.clear();
158 _savedColumnWidth.reserve( columnCount() );
160 for ( int i = 0; i < columnCount(); i++ )
162 _savedColumnWidth.push_back( columnWidth(i) );
168 QY2ListView::restoreColumnWidths()
170 if ( _savedColumnWidth.size() != (unsigned) columnCount() ) // never manually resized
172 for ( int i = 0; i < columnCount(); i++ ) // use optimized column width
173 resizeColumnToContents(i);
175 else // stored settings after manual resizing
177 for ( int i = 0; i < columnCount(); i++ )
179 setColumnWidth( i, _savedColumnWidth[ i ] ); // restore saved column width
186 QY2ListView::contentsMousePressEvent( QMouseEvent * ev )
188 //FIXME may be convert to global
189 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
191 if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
193 _mousePressedItem = item;
194 //FIXME _mousePressedCol = header()->sectionAt( ev->pos().x() );
195 _mousePressedButton = ev->button();
197 else // invalidate last click data
199 _mousePressedItem = 0;
200 _mousePressedCol = -1;
201 _mousePressedButton = -1;
204 // Call base class method
205 //FIXME QTreeWidget::contentsMousePressEvent( ev );
210 QY2ListView::contentsMouseReleaseEvent( QMouseEvent * ev )
212 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
214 if ( item && ( item->flags() & Qt::ItemIsEnabled ) && item == _mousePressedItem )
217 // int col = header()->sectionAt( ev->pos().x() );
219 // if ( item == _mousePressedItem &&
220 // col == _mousePressedCol &&
221 // ev->button() == _mousePressedButton )
223 // emit( columnClicked( ev->button(), item, col, ev->globalPos() ) );
228 // invalidate last click data
230 _mousePressedItem = 0;
231 _mousePressedCol = -1;
232 _mousePressedButton = Qt::NoButton;
234 // Call base class method
235 //FIXME QTreeWidget::contentsMouseReleaseEvent( ev );
240 QY2ListView::contentsMouseDoubleClickEvent( QMouseEvent * ev )
242 QTreeWidgetItem * item = itemAt( mapToGlobal( ev->pos() ) );
244 if ( item && ( item->flags() & Qt::ItemIsEnabled ) )
246 int col = header()->logicalIndexAt( ev->pos().x() );
247 emit( columnDoubleClicked( ev->button(), (QY2ListViewItem *) item, col, ev->globalPos() ) );
250 // invalidate last click data
252 _mousePressedItem = 0;
253 _mousePressedCol = -1;
254 _mousePressedButton = Qt::NoButton;
256 // // Call base class method
257 // QTreeWidget::contentsMouseDoubleClickEvent( ev );
262 QY2ListView::columnWidthChanged( int, int, int )
264 // Workaround for Qt bug:
266 // QHeader sends a sizeChange() signal for every size change, not only (as
267 // documented) when the user resizes a header column manually. But we only
268 // want to record the column widths if the user explicitly did that, so
269 // ignore those signals if the mouse isn't pressed. There is also one final
270 // sizeChange() signal immediately after the user releases the mouse button.
272 if ( _mouseButton1PressedInHeader || _finalSizeChangeExpected )
276 // Consume that one sizeChange() signal that is sent immediately after
277 // the mouse button is released, but make sure to reset that flag only
280 if ( ! _mouseButton1PressedInHeader )
281 _finalSizeChangeExpected = false;
287 QY2ListView::eventFilter( QObject * obj, QEvent * event )
289 if ( event && obj && obj == header() )
291 if ( event->type() == QEvent::MouseButtonPress )
293 QMouseEvent * mouseEvent = (QMouseEvent *) event;
295 if ( mouseEvent->button() == 1 )
297 _mouseButton1PressedInHeader = true;
298 _finalSizeChangeExpected = false;
301 else if ( event->type() == QEvent::MouseButtonRelease )
303 QMouseEvent * mouseEvent = (QMouseEvent *) event;
305 if ( mouseEvent->button() == 1 )
307 _finalSizeChangeExpected = true;
308 _mouseButton1PressedInHeader = false;
313 return QTreeWidget::eventFilter( obj, event );
318 QY2ListView::minimumSizeHint() const
320 return QSize( 0, 0 );
325 QY2ListView::setSortByInsertionSequence( bool sortByInsertionSequence )
327 _sortByInsertionSequence = sortByInsertionSequence;
329 header()->setClickable( ! _sortByInsertionSequence );
337 QY2ListViewItem::QY2ListViewItem( QY2ListView * parentListView,
338 const QString & text )
339 : QTreeWidgetItem( parentListView, QStringList(text), 1)
341 _serial = parentListView->nextSerial();
345 QY2ListViewItem::QY2ListViewItem( QTreeWidgetItem * parentItem,
346 const QString & text )
347 : QTreeWidgetItem( parentItem, QStringList(text), 1 )
351 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
353 if ( parentListView )
354 _serial = parentListView->nextSerial();
358 QY2ListViewItem::~QY2ListViewItem()
365 * Comparison function used for sorting the list.
372 QY2ListViewItem::compare( QTreeWidgetItem * otherListViewItem,
374 bool ascending ) const
376 bool sortByInsertionSequence = false;
377 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
379 if ( parentListView )
380 sortByInsertionSequence = parentListView->sortByInsertionSequence();
382 if ( sortByInsertionSequence )
384 QY2ListViewItem * other = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
388 if ( this->serial() < other->serial() ) return -1;
389 if ( this->serial() > other->serial() ) return 1;
393 // Still here? Try the other version: QY2CheckListItem.
395 QY2CheckListItem * otherCheckListItem = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
397 if ( otherCheckListItem )
399 if ( this->serial() < otherCheckListItem->serial() ) return -1;
400 if ( this->serial() > otherCheckListItem->serial() ) return 1;
406 //return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
412 // QY2ListViewItem::paintCell( QPainter * painter,
413 // const QColorGroup & colorGroup,
418 // QColorGroup cg = colorGroup;
420 // if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
421 // if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
423 // QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
431 QY2CheckListItem::QY2CheckListItem( QY2ListView * parentListView,
432 const QString & text )
433 : QTreeWidgetItem( parentListView, QStringList(text))
435 setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
436 setCheckState(0, Qt::Unchecked);
437 _serial = parentListView->nextSerial();
441 QY2CheckListItem::QY2CheckListItem( QTreeWidgetItem * parentItem,
442 const QString & text )
443 : QTreeWidgetItem( parentItem, QStringList(text))
446 QY2ListView * parentListView = dynamic_cast<QY2ListView *> ( treeWidget() );
448 if ( parentListView )
449 _serial = parentListView->nextSerial();
452 QY2CheckListItem::~QY2CheckListItem()
459 * Comparison function used for sorting the list.
466 QY2CheckListItem::compare( QTreeWidgetItem * otherListViewItem,
468 bool ascending ) const
470 bool sortByInsertionSequence = false;
471 QY2ListView * parentListView = dynamic_cast<QY2ListView *> (treeWidget());
473 if ( parentListView )
474 sortByInsertionSequence = parentListView->sortByInsertionSequence();
476 if ( sortByInsertionSequence )
478 QY2CheckListItem * other = dynamic_cast<QY2CheckListItem *> (otherListViewItem);
482 if ( this->serial() < other->serial() ) return -1;
483 if ( this->serial() > other->serial() ) return 1;
488 // Still here? Try the other version: QY2ListViewItem.
490 QY2ListViewItem * otherCheckListItem = dynamic_cast<QY2ListViewItem *> (otherListViewItem);
492 if ( otherCheckListItem )
494 if ( this->serial() < otherCheckListItem->serial() ) return -1;
495 if ( this->serial() > otherCheckListItem->serial() ) return 1;
501 //FIXME return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
507 QY2CheckListItem::paintCell( QPainter * painter,
508 const QColorGroup & colorGroup,
513 QColorGroup cg = colorGroup;
515 if ( _textColor.isValid() ) cg.setColor( QColorGroup::Text, _textColor );
516 if ( _backgroundColor.isValid() ) cg.setColor( QColorGroup::Base, _backgroundColor );
518 QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
524 QY2ListViewToolTip::maybeTip( const QPoint & pos )
526 Q3Header * header = _listView->header();
527 QTreeWidgetItem * item = _listView->itemAt( pos );
532 int x = _listView->viewportToContents( pos ).x();
533 int column = header->sectionAt(x);
538 indent = item->depth() + ( _listView->rootIsDecorated() ? 1 : 0 );
539 indent *= _listView->treeStepSize();
541 if ( pos.x() < indent )
545 QString text = _listView->toolTip( item, column );
547 if ( ! text.isEmpty() )
549 QRect rect( _listView->itemRect( item ) );
554 rect.setWidth( indent );
558 QPoint topLeft( header->sectionPos( column ), 0 );
559 topLeft = _listView->contentsToViewport( topLeft );
560 rect.setX( topLeft.x() );
561 rect.setWidth( header->sectionSize( column ) );
571 #include "QY2ListView.moc"