Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_legend.cpp
- Timestamp:
- May 10, 2017, 3:20:54 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/qwt/qwt_legend.cpp
r4271 r8127 9 9 10 10 #include "qwt_legend.h" 11 #include "qwt_legend_itemmanager.h" 12 #include "qwt_legend_item.h" 11 #include "qwt_legend_label.h" 13 12 #include "qwt_dyngrid_layout.h" 14 13 #include "qwt_math.h" 14 #include "qwt_plot_item.h" 15 #include "qwt_painter.h" 15 16 #include <qapplication.h> 16 #include <qmap.h>17 17 #include <qscrollbar.h> 18 18 #include <qscrollarea.h> 19 #include <qpainter.h> 20 #include <qstyle.h> 21 #include <qstyleoption.h> 22 23 class QwtLegendMap 24 { 25 public: 26 inline bool isEmpty() const { return d_entries.isEmpty(); } 27 28 void insert( const QVariant &, const QList<QWidget *> & ); 29 void remove( const QVariant & ); 30 31 void removeWidget( const QWidget * ); 32 33 QList<QWidget *> legendWidgets( const QVariant & ) const; 34 QVariant itemInfo( const QWidget * ) const; 35 36 private: 37 // we don't know anything about itemInfo and therefore don't have 38 // any key that can be used for a map or hashtab. 39 // But a simple linear list is o.k. here, as we will never have 40 // more than a few entries. 41 42 class Entry 43 { 44 public: 45 QVariant itemInfo; 46 QList<QWidget *> widgets; 47 }; 48 49 QList< Entry > d_entries; 50 }; 51 52 void QwtLegendMap::insert( const QVariant &itemInfo, 53 const QList<QWidget *> &widgets ) 54 { 55 for ( int i = 0; i < d_entries.size(); i++ ) 56 { 57 Entry &entry = d_entries[i]; 58 if ( entry.itemInfo == itemInfo ) 59 { 60 entry.widgets = widgets; 61 return; 62 } 63 } 64 65 Entry newEntry; 66 newEntry.itemInfo = itemInfo; 67 newEntry.widgets = widgets; 68 69 d_entries += newEntry; 70 } 71 72 void QwtLegendMap::remove( const QVariant &itemInfo ) 73 { 74 for ( int i = 0; i < d_entries.size(); i++ ) 75 { 76 Entry &entry = d_entries[i]; 77 if ( entry.itemInfo == itemInfo ) 78 { 79 d_entries.removeAt( i ); 80 return; 81 } 82 } 83 } 84 85 void QwtLegendMap::removeWidget( const QWidget *widget ) 86 { 87 QWidget *w = const_cast<QWidget *>( widget ); 88 89 for ( int i = 0; i < d_entries.size(); i++ ) 90 d_entries[ i ].widgets.removeAll( w ); 91 } 92 93 QVariant QwtLegendMap::itemInfo( const QWidget *widget ) const 94 { 95 if ( widget != NULL ) 96 { 97 QWidget *w = const_cast<QWidget *>( widget ); 98 99 for ( int i = 0; i < d_entries.size(); i++ ) 100 { 101 const Entry &entry = d_entries[i]; 102 if ( entry.widgets.indexOf( w ) >= 0 ) 103 return entry.itemInfo; 104 } 105 } 106 107 return QVariant(); 108 } 109 110 QList<QWidget *> QwtLegendMap::legendWidgets( const QVariant &itemInfo ) const 111 { 112 if ( itemInfo.isValid() ) 113 { 114 for ( int i = 0; i < d_entries.size(); i++ ) 115 { 116 const Entry &entry = d_entries[i]; 117 if ( entry.itemInfo == itemInfo ) 118 return entry.widgets; 119 } 120 } 121 122 return QList<QWidget *>(); 123 } 19 124 20 125 class QwtLegend::PrivateData 21 126 { 22 127 public: 23 class LegendMap 24 { 25 public: 26 void insert( const QwtLegendItemManager *, QWidget * ); 27 28 void remove( const QwtLegendItemManager * ); 29 void remove( QWidget * ); 30 31 void clear(); 32 33 uint count() const; 34 35 inline const QWidget *find( const QwtLegendItemManager * ) const; 36 inline QWidget *find( const QwtLegendItemManager * ); 37 38 inline const QwtLegendItemManager *find( const QWidget * ) const; 39 inline QwtLegendItemManager *find( const QWidget * ); 40 41 const QMap<QWidget *, const QwtLegendItemManager *> &widgetMap() const; 42 QMap<QWidget *, const QwtLegendItemManager *> &widgetMap(); 43 44 private: 45 QMap<QWidget *, const QwtLegendItemManager *> d_widgetMap; 46 QMap<const QwtLegendItemManager *, QWidget *> d_itemMap; 47 }; 48 49 QwtLegend::LegendItemMode itemMode; 50 51 LegendMap map; 128 PrivateData(): 129 itemMode( QwtLegendData::ReadOnly ), 130 view( NULL ) 131 { 132 } 133 134 QwtLegendData::Mode itemMode; 135 QwtLegendMap itemMap; 52 136 53 137 class LegendView; … … 61 145 QScrollArea( parent ) 62 146 { 63 setFocusPolicy( Qt::NoFocus );64 65 147 contentsWidget = new QWidget( this ); 66 148 contentsWidget->setObjectName( "QwtLegendViewContents" ); … … 77 159 } 78 160 79 virtual bool viewportEvent( QEvent *e ) 80 { 81 bool ok = QScrollArea::viewportEvent( e ); 82 83 if ( e->type() == QEvent::Resize ) 84 { 85 QEvent event( QEvent::LayoutRequest ); 86 QApplication::sendEvent( contentsWidget, &event ); 161 virtual bool event( QEvent *event ) 162 { 163 if ( event->type() == QEvent::PolishRequest ) 164 { 165 setFocusPolicy( Qt::NoFocus ); 166 } 167 168 if ( event->type() == QEvent::Resize ) 169 { 170 // adjust the size to en/disable the scrollbars 171 // before QScrollArea adjusts the viewport size 172 173 const QRect cr = contentsRect(); 174 175 int w = cr.width(); 176 int h = contentsWidget->heightForWidth( cr.width() ); 177 if ( h > w ) 178 { 179 w -= verticalScrollBar()->sizeHint().width(); 180 h = contentsWidget->heightForWidth( w ); 181 } 182 183 contentsWidget->resize( w, h ); 184 } 185 186 return QScrollArea::event( event ); 187 } 188 189 virtual bool viewportEvent( QEvent *event ) 190 { 191 bool ok = QScrollArea::viewportEvent( event ); 192 193 if ( event->type() == QEvent::Resize ) 194 { 195 layoutContents(); 87 196 } 88 197 return ok; … … 112 221 } 113 222 223 void layoutContents() 224 { 225 const QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>( 226 contentsWidget->layout() ); 227 if ( tl == NULL ) 228 return; 229 230 const QSize visibleSize = viewport()->contentsRect().size(); 231 232 const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin(); 233 234 int w = qMax( visibleSize.width(), minW ); 235 int h = qMax( tl->heightForWidth( w ), visibleSize.height() ); 236 237 const int vpWidth = viewportSize( w, h ).width(); 238 if ( w > vpWidth ) 239 { 240 w = qMax( vpWidth, minW ); 241 h = qMax( tl->heightForWidth( w ), visibleSize.height() ); 242 } 243 244 contentsWidget->resize( w, h ); 245 } 246 114 247 QWidget *contentsWidget; 115 248 }; 116 249 117 void QwtLegend::PrivateData::LegendMap::insert(118 const QwtLegendItemManager *item, QWidget *widget )119 {120 d_itemMap.insert( item, widget );121 d_widgetMap.insert( widget, item );122 }123 124 void QwtLegend::PrivateData::LegendMap::remove( const QwtLegendItemManager *item )125 {126 QWidget *widget = d_itemMap[item];127 d_itemMap.remove( item );128 d_widgetMap.remove( widget );129 }130 131 void QwtLegend::PrivateData::LegendMap::remove( QWidget *widget )132 {133 const QwtLegendItemManager *item = d_widgetMap[widget];134 d_itemMap.remove( item );135 d_widgetMap.remove( widget );136 }137 138 void QwtLegend::PrivateData::LegendMap::clear()139 {140 141 /*142 We can't delete the widgets in the following loop, because143 we would get ChildRemoved events, changing d_itemMap, while144 we are iterating.145 */146 147 QList<const QWidget *> widgets;148 149 QMap<const QwtLegendItemManager *, QWidget *>::const_iterator it;150 for ( it = d_itemMap.begin(); it != d_itemMap.end(); ++it )151 widgets.append( it.value() );152 153 d_itemMap.clear();154 d_widgetMap.clear();155 156 for ( int i = 0; i < widgets.size(); i++ )157 delete widgets[i];158 }159 160 uint QwtLegend::PrivateData::LegendMap::count() const161 {162 return d_itemMap.count();163 }164 165 inline const QWidget *QwtLegend::PrivateData::LegendMap::find(166 const QwtLegendItemManager *item ) const167 {168 if ( !d_itemMap.contains( item ) )169 return NULL;170 171 return d_itemMap[item];172 }173 174 inline QWidget *QwtLegend::PrivateData::LegendMap::find(175 const QwtLegendItemManager *item )176 {177 if ( !d_itemMap.contains( item ) )178 return NULL;179 180 return d_itemMap[item];181 }182 183 inline const QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(184 const QWidget *widget ) const185 {186 QWidget *w = const_cast<QWidget *>( widget );187 if ( !d_widgetMap.contains( w ) )188 return NULL;189 190 return d_widgetMap[w];191 }192 193 inline QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(194 const QWidget *widget )195 {196 QWidget *w = const_cast<QWidget *>( widget );197 if ( !d_widgetMap.contains( w ) )198 return NULL;199 200 return const_cast<QwtLegendItemManager *>( d_widgetMap[w] );201 }202 203 inline const QMap<QWidget *, const QwtLegendItemManager *> &204 QwtLegend::PrivateData::LegendMap::widgetMap() const205 {206 return d_widgetMap;207 }208 209 inline QMap<QWidget *, const QwtLegendItemManager *> &210 QwtLegend::PrivateData::LegendMap::widgetMap()211 {212 return d_widgetMap;213 }214 215 250 /*! 216 251 Constructor 217 218 252 \param parent Parent widget 219 253 */ 220 254 QwtLegend::QwtLegend( QWidget *parent ): 221 Q Frame( parent )255 QwtAbstractLegend( parent ) 222 256 { 223 257 setFrameStyle( NoFrame ); 224 258 225 259 d_data = new QwtLegend::PrivateData; 226 d_data->itemMode = QwtLegend::ReadOnlyItem;227 260 228 261 d_data->view = new QwtLegend::PrivateData::LegendView( this ); … … 247 280 } 248 281 249 //! \sa LegendItemMode 250 void QwtLegend::setItemMode( LegendItemMode mode ) 282 /*! 283 \brief Set the maximum number of entries in a row 284 285 F.e when the maximum is set to 1 all items are aligned 286 vertically. 0 means unlimited 287 288 \param numColums Maximum number of entries in a row 289 290 \sa maxColumns(), QwtDynGridLayout::setMaxColumns() 291 */ 292 void QwtLegend::setMaxColumns( uint numColums ) 293 { 294 QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>( 295 d_data->view->contentsWidget->layout() ); 296 if ( tl ) 297 tl->setMaxColumns( numColums ); 298 } 299 300 /*! 301 \return Maximum number of entries in a row 302 \sa setMaxColumns(), QwtDynGridLayout::maxColumns() 303 */ 304 uint QwtLegend::maxColumns() const 305 { 306 uint maxCols = 0; 307 308 const QwtDynGridLayout *tl = qobject_cast<const QwtDynGridLayout *>( 309 d_data->view->contentsWidget->layout() ); 310 if ( tl ) 311 maxCols = tl->maxColumns(); 312 313 return maxCols; 314 } 315 316 /*! 317 \brief Set the default mode for legend labels 318 319 Legend labels will be constructed according to the 320 attributes in a QwtLegendData object. When it doesn't 321 contain a value for the QwtLegendData::ModeRole the 322 label will be initialized with the default mode of the legend. 323 324 \param mode Default item mode 325 326 \sa itemMode(), QwtLegendData::value(), QwtPlotItem::legendData() 327 \note Changing the mode doesn't have any effect on existing labels. 328 */ 329 void QwtLegend::setDefaultItemMode( QwtLegendData::Mode mode ) 251 330 { 252 331 d_data->itemMode = mode; 253 332 } 254 333 255 //! \sa LegendItemMode 256 QwtLegend::LegendItemMode QwtLegend::itemMode() const 334 /*! 335 \return Default item mode 336 \sa setDefaultItemMode() 337 */ 338 QwtLegendData::Mode QwtLegend::defaultItemMode() const 257 339 { 258 340 return d_data->itemMode; … … 261 343 /*! 262 344 The contents widget is the only child of the viewport of 263 the internal QScrollArea 345 the internal QScrollArea and the parent widget of all legend items. 264 346 265 347 \return Container widget of the legend items … … 290 372 /*! 291 373 The contents widget is the only child of the viewport of 292 the internal QScrollArea 374 the internal QScrollArea and the parent widget of all legend items. 293 375 294 376 \return Container widget of the legend items … … 301 383 302 384 /*! 303 Insert a new item for a plot item 304 \param plotItem Plot item 305 \param legendItem New legend item 306 \note The parent of item will be changed to contentsWidget() 307 */ 308 void QwtLegend::insert( const QwtLegendItemManager *plotItem, QWidget *legendItem ) 309 { 310 if ( legendItem == NULL || plotItem == NULL ) 311 return; 312 313 QWidget *contentsWidget = d_data->view->contentsWidget; 314 315 if ( legendItem->parent() != contentsWidget ) 316 legendItem->setParent( contentsWidget ); 317 318 legendItem->show(); 319 320 d_data->map.insert( plotItem, legendItem ); 321 322 layoutContents(); 323 324 if ( contentsWidget->layout() ) 325 { 326 contentsWidget->layout()->addWidget( legendItem ); 327 385 \brief Update the entries for an item 386 387 \param itemInfo Info for an item 388 \param data List of legend entry attributes for the item 389 */ 390 void QwtLegend::updateLegend( const QVariant &itemInfo, 391 const QList<QwtLegendData> &data ) 392 { 393 QList<QWidget *> widgetList = legendWidgets( itemInfo ); 394 395 if ( widgetList.size() != data.size() ) 396 { 397 QLayout *contentsLayout = d_data->view->contentsWidget->layout(); 398 399 while ( widgetList.size() > data.size() ) 400 { 401 QWidget *w = widgetList.takeLast(); 402 403 contentsLayout->removeWidget( w ); 404 405 // updates might be triggered by signals from the legend widget 406 // itself. So we better don't delete it here. 407 408 w->hide(); 409 w->deleteLater(); 410 } 411 412 for ( int i = widgetList.size(); i < data.size(); i++ ) 413 { 414 QWidget *widget = createWidget( data[i] ); 415 416 if ( contentsLayout ) 417 contentsLayout->addWidget( widget ); 418 419 if ( isVisible() ) 420 { 421 // QLayout does a delayed show, with the effect, that 422 // the size hint will be wrong, when applications 423 // call replot() right after changing the list 424 // of plot items. So we better do the show now. 425 426 widget->setVisible( true ); 427 } 428 429 widgetList += widget; 430 } 431 432 if ( widgetList.isEmpty() ) 433 { 434 d_data->itemMap.remove( itemInfo ); 435 } 436 else 437 { 438 d_data->itemMap.insert( itemInfo, widgetList ); 439 } 440 441 updateTabOrder(); 442 } 443 444 for ( int i = 0; i < data.size(); i++ ) 445 updateWidget( widgetList[i], data[i] ); 446 } 447 448 /*! 449 \brief Create a widget to be inserted into the legend 450 451 The default implementation returns a QwtLegendLabel. 452 453 \param data Attributes of the legend entry 454 \return Widget representing data on the legend 455 456 \note updateWidget() will called soon after createWidget() 457 with the same attributes. 458 */ 459 QWidget *QwtLegend::createWidget( const QwtLegendData &data ) const 460 { 461 Q_UNUSED( data ); 462 463 QwtLegendLabel *label = new QwtLegendLabel(); 464 label->setItemMode( defaultItemMode() ); 465 466 connect( label, SIGNAL( clicked() ), SLOT( itemClicked() ) ); 467 connect( label, SIGNAL( checked( bool ) ), SLOT( itemChecked( bool ) ) ); 468 469 return label; 470 } 471 472 /*! 473 \brief Update the widget 474 475 \param widget Usually a QwtLegendLabel 476 \param data Attributes to be displayed 477 478 \sa createWidget() 479 \note When widget is no QwtLegendLabel updateWidget() does nothing. 480 */ 481 void QwtLegend::updateWidget( QWidget *widget, const QwtLegendData &data ) 482 { 483 QwtLegendLabel *label = qobject_cast<QwtLegendLabel *>( widget ); 484 if ( label ) 485 { 486 label->setData( data ); 487 if ( !data.value( QwtLegendData::ModeRole ).isValid() ) 488 { 489 // use the default mode, when there is no specific 490 // hint from the legend data 491 492 label->setItemMode( defaultItemMode() ); 493 } 494 } 495 } 496 497 void QwtLegend::updateTabOrder() 498 { 499 QLayout *contentsLayout = d_data->view->contentsWidget->layout(); 500 if ( contentsLayout ) 501 { 328 502 // set tab focus chain 329 503 330 504 QWidget *w = NULL; 331 505 332 for ( int i = 0; i < contents Widget->layout()->count(); i++ )333 { 334 QLayoutItem *item = contents Widget->layout()->itemAt( i );506 for ( int i = 0; i < contentsLayout->count(); i++ ) 507 { 508 QLayoutItem *item = contentsLayout->itemAt( i ); 335 509 if ( w && item->widget() ) 336 510 QWidget::setTabOrder( w, item->widget() ); … … 339 513 } 340 514 } 341 if ( parentWidget() && parentWidget()->layout() == NULL )342 {343 /*344 updateGeometry() doesn't post LayoutRequest in certain345 situations, like when we are hidden. But we want the346 parent widget notified, so it can show/hide the legend347 depending on its items.348 */349 QApplication::postEvent( parentWidget(),350 new QEvent( QEvent::LayoutRequest ) );351 }352 }353 354 /*!355 Find the widget that represents a plot item356 357 \param plotItem Plot item358 \return Widget on the legend, or NULL359 */360 QWidget *QwtLegend::find( const QwtLegendItemManager *plotItem ) const361 {362 return d_data->map.find( plotItem );363 }364 365 /*!366 Find the widget that represents a plot item367 368 \param legendItem Legend item369 \return Widget on the legend, or NULL370 */371 QwtLegendItemManager *QwtLegend::find( const QWidget *legendItem ) const372 {373 return d_data->map.find( legendItem );374 }375 376 /*!377 Find the corresponding item for a plotItem and remove it378 from the item list.379 380 \param plotItem Plot item381 */382 void QwtLegend::remove( const QwtLegendItemManager *plotItem )383 {384 QWidget *legendItem = d_data->map.find( plotItem );385 d_data->map.remove( legendItem );386 delete legendItem;387 }388 389 //! Remove all items.390 void QwtLegend::clear()391 {392 bool doUpdate = updatesEnabled();393 if ( doUpdate )394 setUpdatesEnabled( false );395 396 d_data->map.clear();397 398 if ( doUpdate )399 setUpdatesEnabled( true );400 401 update();402 515 } 403 516 … … 412 525 413 526 /*! 414 \return The preferred height, for the width w.527 \return The preferred height, for a width. 415 528 \param width Width 416 529 */ … … 426 539 } 427 540 428 /*!429 Adjust contents widget and item layout to the size of the viewport().430 */431 void QwtLegend::layoutContents()432 {433 const QSize visibleSize =434 d_data->view->viewport()->contentsRect().size();435 436 const QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(437 d_data->view->contentsWidget->layout() );438 if ( tl )439 {440 const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin();441 442 int w = qMax( visibleSize.width(), minW );443 int h = qMax( tl->heightForWidth( w ), visibleSize.height() );444 445 const int vpWidth = d_data->view->viewportSize( w, h ).width();446 if ( w > vpWidth )447 {448 w = qMax( vpWidth, minW );449 h = qMax( tl->heightForWidth( w ), visibleSize.height() );450 }451 452 d_data->view->contentsWidget->resize( w, h );453 }454 }455 541 456 542 /*! … … 460 546 \param object Object to be filtered 461 547 \param event Event 548 549 \return Forwarded to QwtAbstractLegend::eventFilter() 462 550 */ 463 551 bool QwtLegend::eventFilter( QObject *object, QEvent *event ) … … 474 562 { 475 563 QWidget *w = static_cast< QWidget * >( ce->child() ); 476 d_data-> map.remove( w );564 d_data->itemMap.removeWidget( w ); 477 565 } 478 566 break; … … 480 568 case QEvent::LayoutRequest: 481 569 { 482 layoutContents(); 570 d_data->view->layoutContents(); 571 572 if ( parentWidget() && parentWidget()->layout() == NULL ) 573 { 574 /* 575 We want the parent widget ( usually QwtPlot ) to recalculate 576 its layout, when the contentsWidget has changed. But 577 because of the scroll view we have to forward the LayoutRequest 578 event manually. 579 580 We don't use updateGeometry() because it doesn't post LayoutRequest 581 events when the legend is hidden. But we want the 582 parent widget notified, so it can show/hide the legend 583 depending on its items. 584 */ 585 QApplication::postEvent( parentWidget(), 586 new QEvent( QEvent::LayoutRequest ) ); 587 } 483 588 break; 484 589 } … … 488 593 } 489 594 490 return QFrame::eventFilter( object, event ); 491 } 492 493 494 //! Return true, if there are no legend items. 595 return QwtAbstractLegend::eventFilter( object, event ); 596 } 597 598 /*! 599 Called internally when the legend has been clicked on. 600 Emits a clicked() signal. 601 */ 602 void QwtLegend::itemClicked() 603 { 604 QWidget *w = qobject_cast<QWidget *>( sender() ); 605 if ( w ) 606 { 607 const QVariant itemInfo = d_data->itemMap.itemInfo( w ); 608 if ( itemInfo.isValid() ) 609 { 610 const QList<QWidget *> widgetList = 611 d_data->itemMap.legendWidgets( itemInfo ); 612 613 const int index = widgetList.indexOf( w ); 614 if ( index >= 0 ) 615 Q_EMIT clicked( itemInfo, index ); 616 } 617 } 618 } 619 620 /*! 621 Called internally when the legend has been checked 622 Emits a checked() signal. 623 */ 624 void QwtLegend::itemChecked( bool on ) 625 { 626 QWidget *w = qobject_cast<QWidget *>( sender() ); 627 if ( w ) 628 { 629 const QVariant itemInfo = d_data->itemMap.itemInfo( w ); 630 if ( itemInfo.isValid() ) 631 { 632 const QList<QWidget *> widgetList = 633 d_data->itemMap.legendWidgets( itemInfo ); 634 635 const int index = widgetList.indexOf( w ); 636 if ( index >= 0 ) 637 Q_EMIT checked( itemInfo, on, index ); 638 } 639 } 640 } 641 642 /*! 643 Render the legend into a given rectangle. 644 645 \param painter Painter 646 \param rect Bounding rectangle 647 \param fillBackground When true, fill rect with the widget background 648 649 \sa renderLegend() is used by QwtPlotRenderer - not by QwtLegend itself 650 */ 651 void QwtLegend::renderLegend( QPainter *painter, 652 const QRectF &rect, bool fillBackground ) const 653 { 654 if ( d_data->itemMap.isEmpty() ) 655 return; 656 657 if ( fillBackground ) 658 { 659 if ( autoFillBackground() || 660 testAttribute( Qt::WA_StyledBackground ) ) 661 { 662 QwtPainter::drawBackgound( painter, rect, this ); 663 } 664 } 665 666 const QwtDynGridLayout *legendLayout = 667 qobject_cast<QwtDynGridLayout *>( contentsWidget()->layout() ); 668 if ( legendLayout == NULL ) 669 return; 670 671 int left, right, top, bottom; 672 getContentsMargins( &left, &top, &right, &bottom ); 673 674 QRect layoutRect; 675 layoutRect.setLeft( qCeil( rect.left() ) + left ); 676 layoutRect.setTop( qCeil( rect.top() ) + top ); 677 layoutRect.setRight( qFloor( rect.right() ) - right ); 678 layoutRect.setBottom( qFloor( rect.bottom() ) - bottom ); 679 680 uint numCols = legendLayout->columnsForWidth( layoutRect.width() ); 681 QList<QRect> itemRects = 682 legendLayout->layoutItems( layoutRect, numCols ); 683 684 int index = 0; 685 686 for ( int i = 0; i < legendLayout->count(); i++ ) 687 { 688 QLayoutItem *item = legendLayout->itemAt( i ); 689 QWidget *w = item->widget(); 690 if ( w ) 691 { 692 painter->save(); 693 694 painter->setClipRect( itemRects[index], Qt::IntersectClip ); 695 renderItem( painter, w, itemRects[index], fillBackground ); 696 697 index++; 698 painter->restore(); 699 } 700 } 701 } 702 703 /*! 704 Render a legend entry into a given rectangle. 705 706 \param painter Painter 707 \param widget Widget representing a legend entry 708 \param rect Bounding rectangle 709 \param fillBackground When true, fill rect with the widget background 710 711 \note When widget is not derived from QwtLegendLabel renderItem 712 does nothing beside the background 713 */ 714 void QwtLegend::renderItem( QPainter *painter, 715 const QWidget *widget, const QRectF &rect, bool fillBackground ) const 716 { 717 if ( fillBackground ) 718 { 719 if ( widget->autoFillBackground() || 720 widget->testAttribute( Qt::WA_StyledBackground ) ) 721 { 722 QwtPainter::drawBackgound( painter, rect, widget ); 723 } 724 } 725 726 const QwtLegendLabel *label = qobject_cast<const QwtLegendLabel *>( widget ); 727 if ( label ) 728 { 729 // icon 730 731 const QwtGraphic &icon = label->data().icon(); 732 const QSizeF sz = icon.defaultSize(); 733 734 const QRectF iconRect( rect.x() + label->margin(), 735 rect.center().y() - 0.5 * sz.height(), 736 sz.width(), sz.height() ); 737 738 icon.render( painter, iconRect, Qt::KeepAspectRatio ); 739 740 // title 741 742 QRectF titleRect = rect; 743 titleRect.setX( iconRect.right() + 2 * label->spacing() ); 744 745 painter->setFont( label->font() ); 746 painter->setPen( label->palette().color( QPalette::Text ) ); 747 const_cast< QwtLegendLabel *>( label )->drawText( painter, titleRect ); 748 } 749 } 750 751 /*! 752 \return List of widgets associated to a item 753 \param itemInfo Info about an item 754 \sa legendWidget(), itemInfo(), QwtPlot::itemToInfo() 755 */ 756 QList<QWidget *> QwtLegend::legendWidgets( const QVariant &itemInfo ) const 757 { 758 return d_data->itemMap.legendWidgets( itemInfo ); 759 } 760 761 /*! 762 \return First widget in the list of widgets associated to an item 763 \param itemInfo Info about an item 764 \sa itemInfo(), QwtPlot::itemToInfo() 765 \note Almost all types of items have only one widget 766 */ 767 QWidget *QwtLegend::legendWidget( const QVariant &itemInfo ) const 768 { 769 const QList<QWidget *> list = d_data->itemMap.legendWidgets( itemInfo ); 770 if ( list.isEmpty() ) 771 return NULL; 772 773 return list[0]; 774 } 775 776 /*! 777 Find the item that is associated to a widget 778 779 \param widget Widget on the legend 780 \return Associated item info 781 \sa legendWidget() 782 */ 783 QVariant QwtLegend::itemInfo( const QWidget *widget ) const 784 { 785 return d_data->itemMap.itemInfo( widget ); 786 } 787 788 //! \return True, when no item is inserted 495 789 bool QwtLegend::isEmpty() const 496 790 { 497 return d_data->map.count() == 0; 498 } 499 500 //! Return the number of legend items. 501 uint QwtLegend::itemCount() const 502 { 503 return d_data->map.count(); 504 } 505 506 //! Return a list of all legend items 507 QList<QWidget *> QwtLegend::legendItems() const 508 { 509 const QMap<QWidget *, const QwtLegendItemManager *> &map = 510 d_data->map.widgetMap(); 511 512 QList<QWidget *> list; 513 514 QMap<QWidget *, const QwtLegendItemManager *>::const_iterator it; 515 for ( it = map.begin(); it != map.end(); ++it ) 516 list += it.key(); 517 518 return list; 519 } 791 return d_data->itemMap.isEmpty(); 792 } 793 794 /*! 795 Return the extent, that is needed for the scrollbars 796 797 \param orientation Orientation ( 798 \return The width of the vertical scrollbar for Qt::Horizontal and v.v. 799 */ 800 int QwtLegend::scrollExtent( Qt::Orientation orientation ) const 801 { 802 int extent = 0; 803 804 if ( orientation == Qt::Horizontal ) 805 extent = verticalScrollBar()->sizeHint().width(); 806 else 807 extent = horizontalScrollBar()->sizeHint().height(); 808 809 return extent; 810 } 811
Note:
See TracChangeset
for help on using the changeset viewer.