Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_plot.cpp
- Timestamp:
- May 10, 2017, 3:20:54 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/qwt/qwt_plot.cpp
r4271 r8127 15 15 #include "qwt_text_label.h" 16 16 #include "qwt_legend.h" 17 #include "qwt_ dyngrid_layout.h"17 #include "qwt_legend_data.h" 18 18 #include "qwt_plot_canvas.h" 19 #include <qmath.h> 19 20 #include <qpainter.h> 20 21 #include <qpointer.h> … … 23 24 #include <qevent.h> 24 25 26 static inline void qwtEnableLegendItems( QwtPlot *plot, bool on ) 27 { 28 if ( on ) 29 { 30 QObject::connect( 31 plot, SIGNAL( legendDataChanged( 32 const QVariant &, const QList<QwtLegendData> & ) ), 33 plot, SLOT( updateLegendItems( 34 const QVariant &, const QList<QwtLegendData> & ) ) ); 35 } 36 else 37 { 38 QObject::disconnect( 39 plot, SIGNAL( legendDataChanged( 40 const QVariant &, const QList<QwtLegendData> & ) ), 41 plot, SLOT( updateLegendItems( 42 const QVariant &, const QList<QwtLegendData> & ) ) ); 43 } 44 } 45 46 static void qwtSetTabOrder( 47 QWidget *first, QWidget *second, bool withChildren ) 48 { 49 QList<QWidget *> tabChain; 50 tabChain += first; 51 tabChain += second; 52 53 if ( withChildren ) 54 { 55 QList<QWidget *> children = second->findChildren<QWidget *>(); 56 57 QWidget *w = second->nextInFocusChain(); 58 while ( children.contains( w ) ) 59 { 60 children.removeAll( w ); 61 62 tabChain += w; 63 w = w->nextInFocusChain(); 64 } 65 } 66 67 for ( int i = 0; i < tabChain.size() - 1; i++ ) 68 { 69 QWidget *from = tabChain[i]; 70 QWidget *to = tabChain[i+1]; 71 72 const Qt::FocusPolicy policy1 = from->focusPolicy(); 73 const Qt::FocusPolicy policy2 = to->focusPolicy(); 74 75 QWidget *proxy1 = from->focusProxy(); 76 QWidget *proxy2 = to->focusProxy(); 77 78 from->setFocusPolicy( Qt::TabFocus ); 79 from->setFocusProxy( NULL); 80 81 to->setFocusPolicy( Qt::TabFocus ); 82 to->setFocusProxy( NULL); 83 84 QWidget::setTabOrder( from, to ); 85 86 from->setFocusPolicy( policy1 ); 87 from->setFocusProxy( proxy1); 88 89 to->setFocusPolicy( policy2 ); 90 to->setFocusProxy( proxy2 ); 91 } 92 } 93 25 94 class QwtPlot::PrivateData 26 95 { 27 96 public: 28 QPointer<QwtTextLabel> lblTitle; 29 QPointer<QwtPlotCanvas> canvas; 30 QPointer<QwtLegend> legend; 97 QPointer<QwtTextLabel> titleLabel; 98 QPointer<QwtTextLabel> footerLabel; 99 QPointer<QWidget> canvas; 100 QPointer<QwtAbstractLegend> legend; 31 101 QwtPlotLayout *layout; 32 102 … … 58 128 QwtPlot::~QwtPlot() 59 129 { 130 setAutoReplot( false ); 60 131 detachItems( QwtPlotItem::Rtti_PlotItem, autoDelete() ); 61 132 … … 76 147 d_data->autoReplot = false; 77 148 78 d_data->lblTitle = new QwtTextLabel( title, this );79 d_data-> lblTitle->setObjectName( "QwtPlotTitle");80 81 d_data-> lblTitle->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );149 // title 150 d_data->titleLabel = new QwtTextLabel( this ); 151 d_data->titleLabel->setObjectName( "QwtPlotTitle" ); 152 d_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) ); 82 153 83 154 QwtText text( title ); 84 155 text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap ); 85 d_data->lblTitle->setText( text ); 86 156 d_data->titleLabel->setText( text ); 157 158 // footer 159 d_data->footerLabel = new QwtTextLabel( this ); 160 d_data->footerLabel->setObjectName( "QwtPlotFooter" ); 161 162 QwtText footer; 163 footer.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap ); 164 d_data->footerLabel->setText( footer ); 165 166 // legend 87 167 d_data->legend = NULL; 88 168 169 // axis 89 170 initAxesData(); 90 171 172 // canvas 91 173 d_data->canvas = new QwtPlotCanvas( this ); 92 174 d_data->canvas->setObjectName( "QwtPlotCanvas" ); 93 d_data->canvas->setFrameStyle( QFrame::Panel | QFrame::Sunken ); 94 d_data->canvas->setLineWidth( 2 ); 95 96 updateTabOrder(); 175 d_data->canvas->installEventFilter( this ); 97 176 98 177 setSizePolicy( QSizePolicy::MinimumExpanding, … … 100 179 101 180 resize( 200, 200 ); 181 182 QList<QWidget *> focusChain; 183 focusChain << this << d_data->titleLabel << axisWidget( xTop ) 184 << axisWidget( yLeft ) << d_data->canvas << axisWidget( yRight ) 185 << axisWidget( xBottom ) << d_data->footerLabel; 186 187 for ( int i = 0; i < focusChain.size() - 1; i++ ) 188 qwtSetTabOrder( focusChain[i], focusChain[i+1], false ); 189 190 qwtEnableLegendItems( this, true ); 191 } 192 193 /*! 194 \brief Set the drawing canvas of the plot widget 195 196 QwtPlot invokes methods of the canvas as meta methods ( see QMetaObject ). 197 In opposite to using conventional C++ techniques like virtual methods 198 they allow to use canvas implementations that are derived from 199 QWidget or QGLWidget. 200 201 The following meta methods could be implemented: 202 203 - replot() 204 When the canvas doesn't offer a replot method, QwtPlot calls 205 update() instead. 206 207 - borderPath() 208 The border path is necessary to clip the content of the canvas 209 When the canvas doesn't have any special border ( f.e rounded corners ) 210 it is o.k. not to implement this method. 211 212 The default canvas is a QwtPlotCanvas 213 214 \param canvas Canvas Widget 215 \sa canvas() 216 */ 217 void QwtPlot::setCanvas( QWidget *canvas ) 218 { 219 if ( canvas == d_data->canvas ) 220 return; 221 222 delete d_data->canvas; 223 d_data->canvas = canvas; 224 225 if ( canvas ) 226 { 227 canvas->setParent( this ); 228 canvas->installEventFilter( this ); 229 230 if ( isVisible() ) 231 canvas->show(); 232 } 102 233 } 103 234 … … 105 236 \brief Adds handling of layout requests 106 237 \param event Event 238 239 \return See QFrame::event() 107 240 */ 108 241 bool QwtPlot::event( QEvent *event ) … … 122 255 } 123 256 257 /*! 258 \brief Event filter 259 260 The plot handles the following events for the canvas: 261 262 - QEvent::Resize 263 The canvas margins might depend on its size 264 265 - QEvent::ContentsRectChange 266 The layout needs to be recalculated 267 268 \param object Object to be filtered 269 \param event Event 270 271 \return See QFrame::eventFilter() 272 273 \sa updateCanvasMargins(), updateLayout() 274 */ 275 bool QwtPlot::eventFilter( QObject *object, QEvent *event ) 276 { 277 if ( object == d_data->canvas ) 278 { 279 if ( event->type() == QEvent::Resize ) 280 { 281 updateCanvasMargins(); 282 } 283 else if ( event->type() == QEvent::ContentsRectChange ) 284 { 285 updateLayout(); 286 } 287 } 288 289 return QFrame::eventFilter( object, event ); 290 } 291 124 292 //! Replots the plot if autoReplot() is \c true. 125 293 void QwtPlot::autoRefresh() … … 164 332 void QwtPlot::setTitle( const QString &title ) 165 333 { 166 if ( title != d_data-> lblTitle->text().text() )167 { 168 d_data-> lblTitle->setText( title );334 if ( title != d_data->titleLabel->text().text() ) 335 { 336 d_data->titleLabel->setText( title ); 169 337 updateLayout(); 170 338 } … … 177 345 void QwtPlot::setTitle( const QwtText &title ) 178 346 { 179 if ( title != d_data-> lblTitle->text() )180 { 181 d_data-> lblTitle->setText( title );347 if ( title != d_data->titleLabel->text() ) 348 { 349 d_data->titleLabel->setText( title ); 182 350 updateLayout(); 183 351 } 184 352 } 185 353 186 //! \return the plot's title354 //! \return Title of the plot 187 355 QwtText QwtPlot::title() const 188 356 { 189 return d_data->lblTitle->text(); 190 } 191 192 //! \return the plot's title 357 return d_data->titleLabel->text(); 358 } 359 360 //! \return Title label widget. 361 QwtTextLabel *QwtPlot::titleLabel() 362 { 363 return d_data->titleLabel; 364 } 365 366 //! \return Title label widget. 367 const QwtTextLabel *QwtPlot::titleLabel() const 368 { 369 return d_data->titleLabel; 370 } 371 372 /*! 373 Change the text the footer 374 \param text New text of the footer 375 */ 376 void QwtPlot::setFooter( const QString &text ) 377 { 378 if ( text != d_data->footerLabel->text().text() ) 379 { 380 d_data->footerLabel->setText( text ); 381 updateLayout(); 382 } 383 } 384 385 /*! 386 Change the text the footer 387 \param text New text of the footer 388 */ 389 void QwtPlot::setFooter( const QwtText &text ) 390 { 391 if ( text != d_data->footerLabel->text() ) 392 { 393 d_data->footerLabel->setText( text ); 394 updateLayout(); 395 } 396 } 397 398 //! \return Text of the footer 399 QwtText QwtPlot::footer() const 400 { 401 return d_data->footerLabel->text(); 402 } 403 404 //! \return Footer label widget. 405 QwtTextLabel *QwtPlot::footerLabel() 406 { 407 return d_data->footerLabel; 408 } 409 410 //! \return Footer label widget. 411 const QwtTextLabel *QwtPlot::footerLabel() const 412 { 413 return d_data->footerLabel; 414 } 415 416 /*! 417 \brief Assign a new plot layout 418 419 \param layout Layout() 420 \sa plotLayout() 421 */ 422 void QwtPlot::setPlotLayout( QwtPlotLayout *layout ) 423 { 424 if ( layout != d_data->layout ) 425 { 426 delete d_data->layout; 427 d_data->layout = layout; 428 429 updateLayout(); 430 } 431 } 432 433 //! \return the plot's layout 193 434 QwtPlotLayout *QwtPlot::plotLayout() 194 435 { … … 196 437 } 197 438 198 //! \return the plot's titel label.439 //! \return the plot's layout 199 440 const QwtPlotLayout *QwtPlot::plotLayout() const 200 441 { 201 442 return d_data->layout; 202 }203 204 //! \return the plot's titel label.205 QwtTextLabel *QwtPlot::titleLabel()206 {207 return d_data->lblTitle;208 }209 210 /*!211 \return the plot's titel label.212 */213 const QwtTextLabel *QwtPlot::titleLabel() const214 {215 return d_data->lblTitle;216 443 } 217 444 … … 220 447 \sa insertLegend() 221 448 */ 222 Qwt Legend *QwtPlot::legend()449 QwtAbstractLegend *QwtPlot::legend() 223 450 { 224 451 return d_data->legend; … … 229 456 \sa insertLegend() 230 457 */ 231 const Qwt Legend *QwtPlot::legend() const458 const QwtAbstractLegend *QwtPlot::legend() const 232 459 { 233 460 return d_data->legend; … … 238 465 \return the plot's canvas 239 466 */ 240 Q wtPlotCanvas*QwtPlot::canvas()467 QWidget *QwtPlot::canvas() 241 468 { 242 469 return d_data->canvas; … … 246 473 \return the plot's canvas 247 474 */ 248 const Q wtPlotCanvas*QwtPlot::canvas() const475 const QWidget *QwtPlot::canvas() const 249 476 { 250 477 return d_data->canvas; … … 252 479 253 480 /*! 254 Return sizeHint481 \return Size hint for the plot widget 255 482 \sa minimumSizeHint() 256 483 */ 257 258 484 QSize QwtPlot::sizeHint() const 259 485 { … … 316 542 be refreshed explicitly in order to make changes visible. 317 543 318 \sa setAutoReplot() 319 \warning Calls canvas()->repaint, take care of infinite recursions 544 \sa updateAxes(), setAutoReplot() 320 545 */ 321 546 void QwtPlot::replot() … … 333 558 QApplication::sendPostedEvents( this, QEvent::LayoutRequest ); 334 559 335 d_data->canvas->replot(); 560 if ( d_data->canvas ) 561 { 562 const bool ok = QMetaObject::invokeMethod( 563 d_data->canvas, "replot", Qt::DirectConnection ); 564 if ( !ok ) 565 { 566 // fallback, when canvas has no a replot method 567 d_data->canvas->update( d_data->canvas->contentsRect() ); 568 } 569 } 336 570 337 571 setAutoReplot( doAutoReplot ); … … 347 581 348 582 QRect titleRect = d_data->layout->titleRect().toRect(); 583 QRect footerRect = d_data->layout->footerRect().toRect(); 349 584 QRect scaleRect[QwtPlot::axisCnt]; 350 585 for ( int axisId = 0; axisId < axisCnt; axisId++ ) … … 353 588 QRect canvasRect = d_data->layout->canvasRect().toRect(); 354 589 355 //356 590 // resize and show the visible widgets 357 // 358 if ( !d_data-> lblTitle->text().isEmpty() )359 { 360 d_data-> lblTitle->setGeometry( titleRect );361 if ( !d_data-> lblTitle->isVisibleTo( this ) )362 d_data-> lblTitle->show();591 592 if ( !d_data->titleLabel->text().isEmpty() ) 593 { 594 d_data->titleLabel->setGeometry( titleRect ); 595 if ( !d_data->titleLabel->isVisibleTo( this ) ) 596 d_data->titleLabel->show(); 363 597 } 364 598 else 365 d_data->lblTitle->hide(); 599 d_data->titleLabel->hide(); 600 601 if ( !d_data->footerLabel->text().isEmpty() ) 602 { 603 d_data->footerLabel->setGeometry( footerRect ); 604 if ( !d_data->footerLabel->isVisibleTo( this ) ) 605 d_data->footerLabel->show(); 606 } 607 else 608 { 609 d_data->footerLabel->hide(); 610 } 366 611 367 612 for ( int axisId = 0; axisId < axisCnt; axisId++ ) 368 613 { 614 QwtScaleWidget* scaleWidget = axisWidget( axisId ); 615 369 616 if ( axisEnabled( axisId ) ) 370 617 { 371 axisWidget( axisId )->setGeometry( scaleRect[axisId] ); 372 618 if ( scaleRect[axisId] != scaleWidget->geometry() ) 619 { 620 scaleWidget->setGeometry( scaleRect[axisId] ); 621 622 int startDist, endDist; 623 scaleWidget->getBorderDistHint( startDist, endDist ); 624 scaleWidget->setBorderDist( startDist, endDist ); 625 } 626 627 #if 1 373 628 if ( axisId == xBottom || axisId == xTop ) 374 629 { 630 // do we need this code any longer ??? 631 375 632 QRegion r( scaleRect[axisId] ); 376 633 if ( axisEnabled( yLeft ) ) 377 r = r.subtract ( QRegion( scaleRect[yLeft] ) );634 r = r.subtracted( QRegion( scaleRect[yLeft] ) ); 378 635 if ( axisEnabled( yRight ) ) 379 r = r.subtract ( QRegion( scaleRect[yRight] ) );380 r.translate( - d_data->layout->scaleRect( axisId ).x(),636 r = r.subtracted( QRegion( scaleRect[yRight] ) ); 637 r.translate( -scaleRect[ axisId ].x(), 381 638 -scaleRect[axisId].y() ); 382 639 383 axisWidget( axisId )->setMask( r );640 scaleWidget->setMask( r ); 384 641 } 385 if ( !axisWidget( axisId )->isVisibleTo( this ) ) 386 axisWidget( axisId )->show(); 642 #endif 643 if ( !scaleWidget->isVisibleTo( this ) ) 644 scaleWidget->show(); 387 645 } 388 646 else 389 axisWidget( axisId )->hide(); 390 } 391 392 if ( d_data->legend && 393 d_data->layout->legendPosition() != ExternalLegend ) 394 { 395 if ( d_data->legend->itemCount() > 0 ) 647 { 648 scaleWidget->hide(); 649 } 650 } 651 652 if ( d_data->legend ) 653 { 654 if ( d_data->legend->isEmpty() ) 655 { 656 d_data->legend->hide(); 657 } 658 else 396 659 { 397 660 d_data->legend->setGeometry( legendRect ); 398 661 d_data->legend->show(); 399 662 } 400 else401 d_data->legend->hide();402 663 } 403 664 … … 406 667 407 668 /*! 408 Update the focus tab order 409 410 The order is changed so that the canvas will be in front of the 411 first legend item, or behind the last legend item - depending 412 on the position of the legend. 413 */ 414 415 void QwtPlot::updateTabOrder() 416 { 417 if ( d_data->canvas->focusPolicy() == Qt::NoFocus ) 418 return; 419 if ( d_data->legend.isNull() 420 || d_data->layout->legendPosition() == ExternalLegend 421 || d_data->legend->legendItems().count() == 0 ) 422 { 423 return; 424 } 425 426 // Depending on the position of the legend the 427 // tab order will be changed that the canvas is 428 // next to the last legend item, or before 429 // the first one. 430 431 const bool canvasFirst = 432 d_data->layout->legendPosition() == QwtPlot::BottomLegend || 433 d_data->layout->legendPosition() == QwtPlot::RightLegend; 434 435 QWidget *previous = NULL; 436 437 QWidget *w = d_data->canvas; 438 while ( ( w = w->nextInFocusChain() ) != d_data->canvas ) 439 { 440 bool isLegendItem = false; 441 if ( w->focusPolicy() != Qt::NoFocus 442 && w->parent() && w->parent() == d_data->legend->contentsWidget() ) 443 { 444 isLegendItem = true; 445 } 446 447 if ( canvasFirst ) 448 { 449 if ( isLegendItem ) 450 break; 451 452 previous = w; 453 } 454 else 455 { 456 if ( isLegendItem ) 457 previous = w; 458 else 459 { 460 if ( previous ) 461 break; 462 } 463 } 464 } 465 466 if ( previous && previous != d_data->canvas ) 467 setTabOrder( previous, d_data->canvas ); 669 \brief Calculate the canvas margins 670 671 \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates 672 \param canvasRect Bounding rectangle where to paint 673 \param left Return parameter for the left margin 674 \param top Return parameter for the top margin 675 \param right Return parameter for the right margin 676 \param bottom Return parameter for the bottom margin 677 678 Plot items might indicate, that they need some extra space 679 at the borders of the canvas by the QwtPlotItem::Margins flag. 680 681 updateCanvasMargins(), QwtPlotItem::getCanvasMarginHint() 682 */ 683 void QwtPlot::getCanvasMarginsHint( 684 const QwtScaleMap maps[], const QRectF &canvasRect, 685 double &left, double &top, double &right, double &bottom) const 686 { 687 left = top = right = bottom = -1.0; 688 689 const QwtPlotItemList& itmList = itemList(); 690 for ( QwtPlotItemIterator it = itmList.begin(); 691 it != itmList.end(); ++it ) 692 { 693 const QwtPlotItem *item = *it; 694 if ( item->testItemAttribute( QwtPlotItem::Margins ) ) 695 { 696 double m[ QwtPlot::axisCnt ]; 697 item->getCanvasMarginHint( 698 maps[ item->xAxis() ], maps[ item->yAxis() ], 699 canvasRect, m[yLeft], m[xTop], m[yRight], m[xBottom] ); 700 701 left = qMax( left, m[yLeft] ); 702 top = qMax( top, m[xTop] ); 703 right = qMax( right, m[yRight] ); 704 bottom = qMax( bottom, m[xBottom] ); 705 } 706 } 707 } 708 709 /*! 710 \brief Update the canvas margins 711 712 Plot items might indicate, that they need some extra space 713 at the borders of the canvas by the QwtPlotItem::Margins flag. 714 715 getCanvasMarginsHint(), QwtPlotItem::getCanvasMarginHint() 716 */ 717 void QwtPlot::updateCanvasMargins() 718 { 719 QwtScaleMap maps[axisCnt]; 720 for ( int axisId = 0; axisId < axisCnt; axisId++ ) 721 maps[axisId] = canvasMap( axisId ); 722 723 double margins[axisCnt]; 724 getCanvasMarginsHint( maps, canvas()->contentsRect(), 725 margins[yLeft], margins[xTop], margins[yRight], margins[xBottom] ); 726 727 bool doUpdate = false; 728 for ( int axisId = 0; axisId < axisCnt; axisId++ ) 729 { 730 if ( margins[axisId] >= 0.0 ) 731 { 732 const int m = qCeil( margins[axisId] ); 733 plotLayout()->setCanvasMargin( m, axisId); 734 doUpdate = true; 735 } 736 } 737 738 if ( doUpdate ) 739 updateLayout(); 468 740 } 469 741 … … 488 760 /*! 489 761 Redraw the canvas items. 762 490 763 \param painter Painter used for drawing 491 764 \param canvasRect Bounding rectangle where to paint 492 \param map QwtPlot::axisCnt maps, mapping between plot and paint device coordinates 765 \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates 766 767 \note Usually canvasRect is contentsRect() of the plot canvas. 768 Due to a bug in Qt this rectangle might be wrong for certain 769 frame styles ( f.e QFrame::Box ) and it might be necessary to 770 fix the margins manually using QWidget::setContentsMargins() 493 771 */ 494 772 495 773 void QwtPlot::drawItems( QPainter *painter, const QRectF &canvasRect, 496 const QwtScaleMap map [axisCnt] ) const774 const QwtScaleMap maps[axisCnt] ) const 497 775 { 498 776 const QwtPlotItemList& itmList = itemList(); … … 507 785 painter->setRenderHint( QPainter::Antialiasing, 508 786 item->testRenderHint( QwtPlotItem::RenderAntialiased ) ); 787 painter->setRenderHint( QPainter::HighQualityAntialiasing, 788 item->testRenderHint( QwtPlotItem::RenderAntialiased ) ); 509 789 510 790 item->draw( painter, 511 map [item->xAxis()], map[item->yAxis()],791 maps[item->xAxis()], maps[item->yAxis()], 512 792 canvasRect ); 513 793 … … 532 812 map.setTransformation( axisScaleEngine( axisId )->transformation() ); 533 813 534 const QwtScaleDiv *sd = axisScaleDiv( axisId );535 map.setScaleInterval( sd ->lowerBound(), sd->upperBound() );814 const QwtScaleDiv &sd = axisScaleDiv( axisId ); 815 map.setScaleInterval( sd.lowerBound(), sd.upperBound() ); 536 816 537 817 if ( axisEnabled( axisId ) ) … … 553 833 else 554 834 { 555 int margin = 0;556 if ( !plotLayout()->alignCanvasToScales() )557 margin = plotLayout()->canvasMargin( axisId );558 559 835 const QRect &canvasRect = d_data->canvas->contentsRect(); 560 836 if ( axisId == yLeft || axisId == yRight ) 561 837 { 562 map.setPaintInterval( canvasRect.bottom() - margin, 563 canvasRect.top() + margin ); 838 int top = 0; 839 if ( !plotLayout()->alignCanvasToScale( xTop ) ) 840 top = plotLayout()->canvasMargin( xTop ); 841 842 int bottom = 0; 843 if ( !plotLayout()->alignCanvasToScale( xBottom ) ) 844 bottom = plotLayout()->canvasMargin( xBottom ); 845 846 map.setPaintInterval( canvasRect.bottom() - bottom, 847 canvasRect.top() + top ); 564 848 } 565 849 else 566 850 { 567 map.setPaintInterval( canvasRect.left() + margin, 568 canvasRect.right() - margin ); 569 } 570 } 851 int left = 0; 852 if ( !plotLayout()->alignCanvasToScale( yLeft ) ) 853 left = plotLayout()->canvasMargin( yLeft ); 854 855 int right = 0; 856 if ( !plotLayout()->alignCanvasToScale( yRight ) ) 857 right = plotLayout()->canvasMargin( yRight ); 858 859 map.setPaintInterval( canvasRect.left() + left, 860 canvasRect.right() - right ); 861 } 862 } 863 571 864 return map; 572 865 } … … 575 868 \brief Change the background of the plotting area 576 869 577 Sets brush to QPalette::Window of all color groups of870 Sets brush to QPalette::Window of all color groups of 578 871 the palette of the canvas. Using canvas()->setPalette() 579 872 is a more powerful way to set these colors. … … 585 878 { 586 879 QPalette pal = d_data->canvas->palette(); 587 588 for ( int i = 0; i < QPalette::NColorGroups; i++ ) 589 pal.setBrush( ( QPalette::ColorGroup )i, QPalette::Window, brush ); 880 pal.setBrush( QPalette::Window, brush ); 590 881 591 882 canvas()->setPalette( pal ); … … 606 897 607 898 /*! 608 \brief Change the border width of the plotting area609 610 Nothing else than canvas()->setLineWidth(w),611 left for compatibility only.612 613 \param width New border width614 */615 void QwtPlot::setCanvasLineWidth( int width )616 {617 canvas()->setLineWidth( width );618 updateLayout();619 }620 621 /*!622 Nothing else than: canvas()->lineWidth(),623 left for compatibility only.624 625 \return the border width of the plotting area626 */627 int QwtPlot::canvasLineWidth() const628 {629 return canvas()->lineWidth();630 }631 632 /*!633 899 \return \c true if the specified axis exists, otherwise \c false 634 900 \param axisId axis index … … 637 903 { 638 904 return ( ( axisId >= QwtPlot::yLeft ) && ( axisId < QwtPlot::axisCnt ) ); 639 }640 641 /*!642 Called internally when the legend has been clicked on.643 Emits a legendClicked() signal.644 */645 void QwtPlot::legendItemClicked()646 {647 if ( d_data->legend && sender()->isWidgetType() )648 {649 QwtPlotItem *plotItem =650 ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );651 if ( plotItem )652 Q_EMIT legendClicked( plotItem );653 }654 }655 656 /*!657 Called internally when the legend has been checked658 Emits a legendClicked() signal.659 */660 void QwtPlot::legendItemChecked( bool on )661 {662 if ( d_data->legend && sender()->isWidgetType() )663 {664 QwtPlotItem *plotItem =665 ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );666 if ( plotItem )667 Q_EMIT legendChecked( plotItem, on );668 }669 905 } 670 906 … … 677 913 with a best fit number of columns from left to right. 678 914 679 If pos != QwtPlot::ExternalLegend the plot widget will become 680 parent of the legend. It will be deleted when the plot is deleted, 681 or another legend is set with insertLegend(). 915 insertLegend() will set the plot widget as parent for the legend. 916 The legend will be deleted in the destructor of the plot or when 917 another legend is inserted. 918 919 Legends, that are not inserted into the layout of the plot widget 920 need to connect to the legendDataChanged() signal. Calling updateLegend() 921 initiates this signal for an initial update. When the application code 922 wants to implement its own layout this also needs to be done for 923 rendering plots to a document ( see QwtPlotRenderer ). 682 924 683 925 \param legend Legend 684 926 \param pos The legend's position. For top/left position the number 685 of colum s will be limited to 1, otherwise it will be set to927 of columns will be limited to 1, otherwise it will be set to 686 928 unlimited. 687 929 688 \param ratio Ratio between legend and the bounding rect 689 of title, canvas and axes. The legend will be shr inked930 \param ratio Ratio between legend and the bounding rectangle 931 of title, canvas and axes. The legend will be shrunk 690 932 if it would need more space than the given ratio. 691 933 The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 … … 696 938 QwtPlotLayout::setLegendPosition() 697 939 */ 698 void QwtPlot::insertLegend( Qwt Legend *legend,940 void QwtPlot::insertLegend( QwtAbstractLegend *legend, 699 941 QwtPlot::LegendPosition pos, double ratio ) 700 942 { … … 710 952 if ( d_data->legend ) 711 953 { 712 if ( pos != ExternalLegend ) 713 { 714 if ( d_data->legend->parent() != this ) 715 d_data->legend->setParent( this ); 716 } 717 718 const QwtPlotItemList& itmList = itemList(); 719 for ( QwtPlotItemIterator it = itmList.begin(); 720 it != itmList.end(); ++it ) 721 { 722 ( *it )->updateLegend( d_data->legend ); 723 } 724 725 QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>( 726 d_data->legend->contentsWidget()->layout() ); 727 if ( tl ) 954 connect( this, 955 SIGNAL( legendDataChanged( 956 const QVariant &, const QList<QwtLegendData> & ) ), 957 d_data->legend, 958 SLOT( updateLegend( 959 const QVariant &, const QList<QwtLegendData> & ) ) 960 ); 961 962 if ( d_data->legend->parent() != this ) 963 d_data->legend->setParent( this ); 964 965 qwtEnableLegendItems( this, false ); 966 updateLegend(); 967 qwtEnableLegendItems( this, true ); 968 969 QwtLegend *lgd = qobject_cast<QwtLegend *>( legend ); 970 if ( lgd ) 728 971 { 729 972 switch ( d_data->layout->legendPosition() ) … … 731 974 case LeftLegend: 732 975 case RightLegend: 733 tl->setMaxCols( 1 ); // 1 column: align vertical 976 { 977 if ( lgd->maxColumns() == 0 ) 978 lgd->setMaxColumns( 1 ); // 1 column: align vertical 734 979 break; 980 } 735 981 case TopLegend: 736 982 case BottomLegend: 737 tl->setMaxCols( 0 ); // unlimited 983 { 984 lgd->setMaxColumns( 0 ); // unlimited 738 985 break; 739 case ExternalLegend: 986 } 987 default: 740 988 break; 741 989 } 742 990 } 743 } 744 updateTabOrder(); 991 992 QWidget *previousInChain = NULL; 993 switch ( d_data->layout->legendPosition() ) 994 { 995 case LeftLegend: 996 { 997 previousInChain = axisWidget( QwtPlot::xTop ); 998 break; 999 } 1000 case TopLegend: 1001 { 1002 previousInChain = this; 1003 break; 1004 } 1005 case RightLegend: 1006 { 1007 previousInChain = axisWidget( QwtPlot::yRight ); 1008 break; 1009 } 1010 case BottomLegend: 1011 { 1012 previousInChain = footerLabel(); 1013 break; 1014 } 1015 } 1016 1017 if ( previousInChain ) 1018 qwtSetTabOrder( previousInChain, legend, true ); 1019 } 745 1020 } 746 1021 747 1022 updateLayout(); 748 1023 } 1024 1025 /*! 1026 Emit legendDataChanged() for all plot item 1027 1028 \sa QwtPlotItem::legendData(), legendDataChanged() 1029 */ 1030 void QwtPlot::updateLegend() 1031 { 1032 const QwtPlotItemList& itmList = itemList(); 1033 for ( QwtPlotItemIterator it = itmList.begin(); 1034 it != itmList.end(); ++it ) 1035 { 1036 updateLegend( *it ); 1037 } 1038 } 1039 1040 /*! 1041 Emit legendDataChanged() for a plot item 1042 1043 \param plotItem Plot item 1044 \sa QwtPlotItem::legendData(), legendDataChanged() 1045 */ 1046 void QwtPlot::updateLegend( const QwtPlotItem *plotItem ) 1047 { 1048 if ( plotItem == NULL ) 1049 return; 1050 1051 QList<QwtLegendData> legendData; 1052 1053 if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) ) 1054 legendData = plotItem->legendData(); 1055 1056 const QVariant itemInfo = itemToInfo( const_cast< QwtPlotItem *>( plotItem) ); 1057 Q_EMIT legendDataChanged( itemInfo, legendData ); 1058 } 1059 1060 /*! 1061 \brief Update all plot items interested in legend attributes 1062 1063 Call QwtPlotItem::updateLegend(), when the QwtPlotItem::LegendInterest 1064 flag is set. 1065 1066 \param itemInfo Info about the plot item 1067 \param legendData Entries to be displayed for the plot item ( usually 1 ) 1068 1069 \sa QwtPlotItem::LegendInterest, 1070 QwtPlotLegendItem, QwtPlotItem::updateLegend() 1071 */ 1072 void QwtPlot::updateLegendItems( const QVariant &itemInfo, 1073 const QList<QwtLegendData> &legendData ) 1074 { 1075 QwtPlotItem *plotItem = infoToItem( itemInfo ); 1076 if ( plotItem ) 1077 { 1078 const QwtPlotItemList& itmList = itemList(); 1079 for ( QwtPlotItemIterator it = itmList.begin(); 1080 it != itmList.end(); ++it ) 1081 { 1082 QwtPlotItem *item = *it; 1083 if ( item->testItemInterest( QwtPlotItem::LegendInterest ) ) 1084 item->updateLegend( plotItem, legendData ); 1085 } 1086 } 1087 } 1088 1089 /*! 1090 \brief Attach/Detach a plot item 1091 1092 \param plotItem Plot item 1093 \param on When true attach the item, otherwise detach it 1094 */ 1095 void QwtPlot::attachItem( QwtPlotItem *plotItem, bool on ) 1096 { 1097 if ( plotItem->testItemInterest( QwtPlotItem::LegendInterest ) ) 1098 { 1099 // plotItem is some sort of legend 1100 1101 const QwtPlotItemList& itmList = itemList(); 1102 for ( QwtPlotItemIterator it = itmList.begin(); 1103 it != itmList.end(); ++it ) 1104 { 1105 QwtPlotItem *item = *it; 1106 1107 QList<QwtLegendData> legendData; 1108 if ( on && item->testItemAttribute( QwtPlotItem::Legend ) ) 1109 { 1110 legendData = item->legendData(); 1111 plotItem->updateLegend( item, legendData ); 1112 } 1113 } 1114 } 1115 1116 if ( on ) 1117 insertItem( plotItem ); 1118 else 1119 removeItem( plotItem ); 1120 1121 Q_EMIT itemAttached( plotItem, on ); 1122 1123 if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) ) 1124 { 1125 // the item wants to be represented on the legend 1126 1127 if ( on ) 1128 { 1129 updateLegend( plotItem ); 1130 } 1131 else 1132 { 1133 const QVariant itemInfo = itemToInfo( plotItem ); 1134 Q_EMIT legendDataChanged( itemInfo, QList<QwtLegendData>() ); 1135 } 1136 } 1137 1138 autoRefresh(); 1139 } 1140 1141 /*! 1142 \brief Build an information, that can be used to identify 1143 a plot item on the legend. 1144 1145 The default implementation simply wraps the plot item 1146 into a QVariant object. When overloading itemToInfo() 1147 usually infoToItem() needs to reimplemeted too. 1148 1149 \code 1150 QVariant itemInfo; 1151 qVariantSetValue( itemInfo, plotItem ); 1152 \endcode 1153 1154 \param plotItem Plot item 1155 \return Plot item embedded in a QVariant 1156 \sa infoToItem() 1157 */ 1158 QVariant QwtPlot::itemToInfo( QwtPlotItem *plotItem ) const 1159 { 1160 QVariant itemInfo; 1161 qVariantSetValue( itemInfo, plotItem ); 1162 1163 return itemInfo; 1164 } 1165 1166 /*! 1167 \brief Identify the plot item according to an item info object, 1168 that has bee generated from itemToInfo(). 1169 1170 The default implementation simply tries to unwrap a QwtPlotItem 1171 pointer: 1172 1173 \code 1174 if ( itemInfo.canConvert<QwtPlotItem *>() ) 1175 return qvariant_cast<QwtPlotItem *>( itemInfo ); 1176 \endcode 1177 \param itemInfo Plot item 1178 \return A plot item, when successful, otherwise a NULL pointer. 1179 \sa itemToInfo() 1180 */ 1181 QwtPlotItem *QwtPlot::infoToItem( const QVariant &itemInfo ) const 1182 { 1183 if ( itemInfo.canConvert<QwtPlotItem *>() ) 1184 return qvariant_cast<QwtPlotItem *>( itemInfo ); 1185 1186 return NULL; 1187 } 1188 1189
Note:
See TracChangeset
for help on using the changeset viewer.