00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qapplication.h>
00013 #include <qpainter.h>
00014 #include <qbitmap.h>
00015 #include <qstyle.h>
00016 #include "qwt_text.h"
00017 #include "qwt_legend.h"
00018 #include "qwt_painter.h"
00019 #include "qwt_dyngrid_layout.h"
00020
00021 static const int IdentifierWidth = 8;
00022 static const int Margin = 2;
00023
00025 QwtLegendItem::QwtLegendItem():
00026 d_identifierMode(ShowLine | ShowText),
00027 d_curvePen(Qt::NoPen)
00028 {
00029 }
00030
00036 QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol, const QPen &curvePen):
00037 d_identifierMode(ShowLine | ShowText),
00038 d_symbol(symbol),
00039 d_curvePen(curvePen)
00040 {
00041 }
00042
00044 QwtLegendItem::~QwtLegendItem()
00045 {
00046 }
00047
00055 void QwtLegendItem::setIdentifierMode(int mode)
00056 {
00057 if ( mode != d_identifierMode )
00058 {
00059 d_identifierMode = mode;
00060 updateItem();
00061 }
00062 }
00063
00068 int QwtLegendItem::identifierMode() const
00069 {
00070 return d_identifierMode;
00071 }
00072
00079 void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
00080 {
00081 if ( symbol != d_symbol )
00082 {
00083 d_symbol = symbol;
00084 updateItem();
00085 }
00086 }
00087
00092 const QwtSymbol& QwtLegendItem::symbol() const
00093 {
00094 return d_symbol;
00095 }
00096
00097
00104 void QwtLegendItem::setCurvePen(const QPen &pen)
00105 {
00106 if ( pen != d_curvePen )
00107 {
00108 d_curvePen = pen;
00109 updateItem();
00110 }
00111 }
00112
00117 const QPen& QwtLegendItem::curvePen() const
00118 {
00119 return d_curvePen;
00120 }
00121
00123 void QwtLegendItem::updateItem()
00124 {
00125 }
00126
00132 void QwtLegendItem::drawIdentifier(
00133 QPainter *painter, const QRect &rect) const
00134 {
00135 if ( rect.isEmpty() )
00136 return;
00137
00138 if ( (d_identifierMode & ShowLine ) && (d_curvePen.style() != Qt::NoPen) )
00139 {
00140 painter->save();
00141 painter->setPen(d_curvePen);
00142 QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
00143 rect.right(), rect.center().y());
00144 painter->restore();
00145 }
00146
00147 if ( (d_identifierMode & ShowSymbol)
00148 && (d_symbol.style() != QwtSymbol::None) )
00149 {
00150 QSize symbolSize =
00151 QwtPainter::metricsMap().screenToLayout(d_symbol.size());
00152
00153
00154
00155 if ( rect.width() < symbolSize.width() )
00156 {
00157 const double ratio =
00158 double(symbolSize.width()) / double(rect.width());
00159 symbolSize.setWidth(rect.width());
00160 symbolSize.setHeight(qRound(symbolSize.height() / ratio));
00161 }
00162 if ( rect.height() < symbolSize.height() )
00163 {
00164 const double ratio =
00165 double(symbolSize.width()) / double(rect.width());
00166 symbolSize.setHeight(rect.height());
00167 symbolSize.setWidth(qRound(symbolSize.width() / ratio));
00168 }
00169
00170 QRect symbolRect;
00171 symbolRect.setSize(symbolSize);
00172 symbolRect.moveCenter(rect.center());
00173
00174 painter->save();
00175 painter->setBrush(d_symbol.brush());
00176 painter->setPen(d_symbol.pen());
00177 d_symbol.draw(painter, symbolRect);
00178 painter->restore();
00179 }
00180 }
00181
00188 void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
00189 {
00190 const QwtMetricsMap &map = QwtPainter::metricsMap();
00191
00192 const int margin = map.screenToLayoutX(Margin);
00193
00194 const QRect identifierRect(rect.x() + margin, rect.y(),
00195 map.screenToLayoutX(IdentifierWidth), rect.height());
00196 drawIdentifier(painter, identifierRect);
00197
00198
00199
00200 QwtText *txt = titleText();
00201 if ( txt )
00202 {
00203 QRect titleRect = rect;
00204 titleRect.setX(identifierRect.right() + 2 * margin);
00205
00206 txt->draw(painter, titleRect);
00207 delete txt;
00208 }
00209 }
00210
00211
00216 QwtLegendButton::QwtLegendButton(QWidget *parent, const char *name):
00217 QwtPushButton(parent, name)
00218 {
00219 init();
00220 }
00221
00229 QwtLegendButton::QwtLegendButton(
00230 const QwtSymbol &symbol, const QPen &curvePen, const QString &text,
00231 QWidget *parent, const char *name):
00232 QwtPushButton(text, parent, name),
00233 QwtLegendItem(symbol, curvePen)
00234 {
00235 init();
00236 }
00237
00238 void QwtLegendButton::init()
00239 {
00240 setFlat(TRUE);
00241 setAlignment(Qt::AlignLeft | Qt::AlignVCenter |
00242 Qt::ExpandTabs | Qt::WordBreak);
00243 setIndent(2 * Margin);
00244 updateIconset();
00245 }
00246
00247 void QwtLegendButton::updateItem()
00248 {
00249 updateIconset();
00250 }
00251
00255 void QwtLegendButton::updateIconset()
00256 {
00257 const QFontMetrics fm(font());
00258
00259 QPixmap pm(IdentifierWidth, fm.height());
00260 pm.fill(this, 0, 0);
00261
00262 QPainter p(&pm);
00263 drawIdentifier(&p, QRect(0, 0, pm.width(), pm.height()) );
00264 p.end();
00265
00266 pm.setMask(pm.createHeuristicMask());
00267
00268 setIconSet(QIconSet(pm));
00269 }
00270
00277 void QwtLegendButton::setTitle(const QString &title)
00278 {
00279 setText(title);
00280 }
00281
00286 QString QwtLegendButton::title() const
00287 {
00288 return text();
00289 }
00290
00295 QwtText *QwtLegendButton::titleText() const
00296 {
00297 return QwtText::makeText(text(), usedTextFormat(),
00298 alignment(), font());
00299 }
00300
00305 QwtLegendLabel::QwtLegendLabel(QWidget *parent, const char *name):
00306 QLabel(parent, name)
00307 {
00308 init();
00309 }
00310
00318 QwtLegendLabel::QwtLegendLabel(const QwtSymbol &symbol,
00319 const QPen &curvePen, const QString &text,
00320 QWidget *parent, const char *name):
00321 QLabel(text, parent, name),
00322 QwtLegendItem(symbol, curvePen)
00323 {
00324 init();
00325 }
00326
00327 void QwtLegendLabel::init()
00328 {
00329 setAlignment(Qt::AlignLeft | Qt::AlignVCenter |
00330 Qt::ExpandTabs | Qt::WordBreak);
00331 setIndent(Margin + IdentifierWidth + 2 * Margin);
00332 setMargin(Margin);
00333 }
00334
00341 void QwtLegendLabel::setTitle(const QString &title)
00342 {
00343 setText(title);
00344 }
00345
00350 QString QwtLegendLabel::title() const
00351 {
00352 return text();
00353 }
00354
00359 QwtText *QwtLegendLabel::titleText() const
00360 {
00361 return QwtText::makeText(text(), textFormat(),
00362 alignment(), font());
00363 }
00364
00368 void QwtLegendLabel::drawContents(QPainter *painter)
00369 {
00370 QLabel::drawContents(painter);
00371
00372 QRect rect = contentsRect();
00373 rect.setX(rect.x() + Margin);
00374 rect.setWidth(IdentifierWidth);
00375
00376 drawIdentifier(painter, rect);
00377 }
00378
00379 void QwtLegendLabel::updateItem()
00380 {
00381 update();
00382 }
00383
00388 QwtLegend::QwtLegend(QWidget *parent, const char *name):
00389 QScrollView(parent, name),
00390 d_readOnly(FALSE),
00391 d_displayPolicy(QwtLegend::Auto),
00392 d_identifierMode(QwtLegendButton::ShowLine
00393 | QwtLegendButton::ShowSymbol
00394 | QwtLegendButton::ShowText)
00395 {
00396 setFrameStyle(NoFrame);
00397 setResizePolicy(Manual);
00398
00399 viewport()->setBackgroundMode(NoBackground);
00400
00401 d_contentsWidget = new QWidget(viewport());
00402 d_contentsWidget->installEventFilter(this);
00403
00404 QwtDynGridLayout *layout = new QwtDynGridLayout(d_contentsWidget);
00405 layout->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
00406 layout->setAutoAdd(TRUE);
00407
00408 addChild(d_contentsWidget);
00409 }
00410
00415 void QwtLegend::setReadOnly(bool readOnly)
00416 {
00417 d_readOnly = readOnly;
00418 }
00419
00424 bool QwtLegend::isReadOnly() const
00425 {
00426 return d_readOnly;
00427 }
00428
00437 void QwtLegend::setDisplayPolicy(LegendDisplayPolicy policy, int mode)
00438 {
00439 d_displayPolicy = policy;
00440 if (-1 != mode)
00441 d_identifierMode = mode;
00442 }
00443
00450 QwtLegend::LegendDisplayPolicy QwtLegend::displayPolicy() const
00451 {
00452 return d_displayPolicy;
00453 }
00454
00462 int QwtLegend::identifierMode() const
00463 {
00464 return d_identifierMode;
00465 }
00466
00471 QWidget *QwtLegend::contentsWidget()
00472 {
00473 return d_contentsWidget;
00474 }
00475
00481 const QWidget *QwtLegend::contentsWidget() const
00482 {
00483 return d_contentsWidget;
00484 }
00485
00493 void QwtLegend::insertItem(QWidget *item, long key)
00494 {
00495 if ( item == NULL || key < 0 )
00496 return;
00497
00498 if ( item->parent() != d_contentsWidget )
00499 item->reparent(d_contentsWidget, QPoint(0, 0));
00500
00501 item->show();
00502
00503 if ( d_items.count() > d_items.size() - 5 )
00504 d_items.resize(d_items.count() + 5);
00505
00506 d_items.insert(key, item);
00507
00508 layoutContents();
00509
00510 QWidget *w = 0;
00511
00512 if ( d_contentsWidget->layout() )
00513 {
00514
00515
00516 QLayoutIterator layoutIterator =
00517 d_contentsWidget->layout()->iterator();
00518
00519 for ( QLayoutItem *item = layoutIterator.current();
00520 item != 0; item = ++layoutIterator)
00521 {
00522 if ( w && item->widget() )
00523 QWidget::setTabOrder(w, item->widget());
00524
00525 w = item->widget();
00526 }
00527 }
00528 }
00529
00531 QWidget *QwtLegend::findItem(long key)
00532 {
00533 return d_items.find(key);
00534 }
00535
00537 const QWidget *QwtLegend::findItem(long key) const
00538 {
00539 return d_items.find(key);
00540 }
00541
00543 QWidget *QwtLegend::takeItem(long key)
00544 {
00545 return d_items.take(key);
00546 }
00547
00553 long QwtLegend::key(const QWidget *item) const
00554 {
00555 QWidgetIntDictIt it(d_items);
00556 for ( const QWidget *w = it.toFirst(); w != 0; w = ++it)
00557 {
00558 if ( w == item )
00559 return it.currentKey();
00560 }
00561 return -1;
00562 }
00563
00565 void QwtLegend::clear()
00566 {
00567
00568
00569
00570
00571 QValueList<QWidget *> clearList;
00572
00573 QWidgetIntDictIt it(d_items);
00574 for ( QWidget *item = it.toFirst(); item != 0; item = ++it)
00575 clearList += item;
00576
00577 for ( uint i = 0; i < clearList.count(); i++ )
00578 delete clearList[i];
00579
00580 #if QT_VERSION < 232
00581
00582
00583
00584
00585
00586 d_items.clear();
00587 #endif
00588 }
00589
00591 QWidgetIntDictIt QwtLegend::itemIterator() const
00592 {
00593 return QWidgetIntDictIt(d_items);
00594 }
00595
00597 QSize QwtLegend::sizeHint() const
00598 {
00599 QSize hint = d_contentsWidget->sizeHint();
00600 hint += QSize(2 * frameWidth(), 2 * frameWidth());
00601
00602 return hint;
00603 }
00604
00608 int QwtLegend::heightForWidth(int w) const
00609 {
00610 w -= 2 * frameWidth();
00611
00612 int h = d_contentsWidget->heightForWidth(w);
00613 if ( h <= 0 )
00614 {
00615 QLayout *l = d_contentsWidget->layout();
00616 if ( l && l->hasHeightForWidth() )
00617 {
00618 h = l->heightForWidth(w);
00619 h += 2 * frameWidth();
00620 }
00621 }
00622
00623 return h;
00624 }
00625
00629 void QwtLegend::layoutContents()
00630 {
00631 const QSize visibleSize = viewport()->size();
00632
00633 const QLayout *l = d_contentsWidget->layout();
00634 if ( l && l->inherits("QwtDynGridLayout") )
00635 {
00636 const QwtDynGridLayout *tl = (const QwtDynGridLayout *)l;
00637
00638 const int minW = int(tl->maxItemWidth()) + 2 * tl->margin();
00639
00640 int w = QMAX(visibleSize.width(), minW);
00641 int h = QMAX(tl->heightForWidth(w), visibleSize.height());
00642
00643 const int vpWidth = viewportSize(w, h).width();
00644
00645 if ( w > vpWidth )
00646 {
00647 w = QMAX(vpWidth, minW);
00648 h = QMAX(tl->heightForWidth(w), visibleSize.height());
00649 }
00650
00651 d_contentsWidget->resize(w, h);
00652 resizeContents(w, h);
00653 }
00654 }
00655
00656
00657
00658
00659
00660
00662 bool QwtLegend::eventFilter(QObject *o, QEvent *e)
00663 {
00664 if ( o == d_contentsWidget )
00665 {
00666 switch(e->type())
00667 {
00668 case QEvent::ChildRemoved:
00669 {
00670 const QChildEvent *ce = (const QChildEvent *)e;
00671 if ( ce->child()->isWidgetType() )
00672 (void)takeItem(key((QWidget *)ce->child()));
00673 break;
00674 }
00675 case QEvent::LayoutHint:
00676 {
00677 layoutContents();
00678 break;
00679 }
00680 default:
00681 break;
00682 }
00683 }
00684
00685 return QScrollView::eventFilter(o, e);
00686 }
00687
00692 void QwtLegend::viewportResizeEvent(QResizeEvent *e)
00693 {
00694 QScrollView::viewportResizeEvent(e);
00695
00696
00697
00698
00699
00700 QApplication::postEvent(d_contentsWidget, new QEvent(QEvent::LayoutHint));
00701 }