Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qapplication.h>
00013 #include <qmap.h>
00014 #if QT_VERSION >= 0x040000
00015 #include <qscrollbar.h>
00016 #endif
00017 #include "qwt_math.h"
00018 #include "qwt_dyngrid_layout.h"
00019 #include "qwt_legend_itemmanager.h"
00020 #include "qwt_legend_item.h"
00021 #include "qwt_legend.h"
00022
00023 class QwtLegend::PrivateData
00024 {
00025 public:
00026 class LegendMap
00027 {
00028 public:
00029 void insert(const QwtLegendItemManager *, QWidget *);
00030
00031 void remove(const QwtLegendItemManager *);
00032 void remove(QWidget *);
00033
00034 void clear();
00035
00036 uint count() const;
00037
00038 inline const QWidget *find(const QwtLegendItemManager *) const;
00039 inline QWidget *find(const QwtLegendItemManager *);
00040
00041 inline const QwtLegendItemManager *find(const QWidget *) const;
00042 inline QwtLegendItemManager *find(const QWidget *);
00043
00044 const QMap<QWidget *, const QwtLegendItemManager *> &widgetMap() const;
00045 QMap<QWidget *, const QwtLegendItemManager *> &widgetMap();
00046
00047 private:
00048 QMap<QWidget *, const QwtLegendItemManager *> d_widgetMap;
00049 QMap<const QwtLegendItemManager *, QWidget *> d_itemMap;
00050 };
00051
00052 QwtLegend::LegendItemMode itemMode;
00053 QwtLegend::LegendDisplayPolicy displayPolicy;
00054 int identifierMode;
00055
00056 LegendMap map;
00057
00058 class LegendView;
00059 LegendView *view;
00060 };
00061
00062 #if QT_VERSION < 0x040000
00063 #include <qscrollview.h>
00064
00065 class QwtLegend::PrivateData::LegendView: public QScrollView
00066 {
00067 public:
00068 LegendView(QWidget *parent):
00069 QScrollView(parent)
00070 {
00071 setResizePolicy(Manual);
00072
00073 viewport()->setBackgroundMode(Qt::NoBackground);
00074
00075 contentsWidget = new QWidget(viewport());
00076
00077 addChild(contentsWidget);
00078 }
00079
00080 void viewportResizeEvent(QResizeEvent *e)
00081 {
00082 QScrollView::viewportResizeEvent(e);
00083
00084
00085
00086
00087
00088 QApplication::postEvent(contentsWidget,
00089 new QEvent(QEvent::LayoutHint));
00090 }
00091
00092 QWidget *contentsWidget;
00093 };
00094
00095 #else // QT_VERSION >= 0x040000
00096
00097 #include <qscrollarea.h>
00098
00099 class QwtLegend::PrivateData::LegendView: public QScrollArea
00100 {
00101 public:
00102 LegendView(QWidget *parent):
00103 QScrollArea(parent)
00104 {
00105 contentsWidget = new QWidget(this);
00106
00107 setWidget(contentsWidget);
00108 setWidgetResizable(false);
00109 setFocusPolicy(Qt::NoFocus);
00110 }
00111
00112 virtual bool viewportEvent(QEvent *e)
00113 {
00114 bool ok = QScrollArea::viewportEvent(e);
00115
00116 if ( e->type() == QEvent::Resize )
00117 {
00118 QEvent event(QEvent::LayoutRequest);
00119 QApplication::sendEvent(contentsWidget, &event);
00120 }
00121 return ok;
00122 }
00123
00124 QSize viewportSize(int w, int h) const
00125 {
00126 const int sbHeight = horizontalScrollBar()->sizeHint().height();
00127 const int sbWidth = verticalScrollBar()->sizeHint().width();
00128
00129 const int cw = contentsRect().width();
00130 const int ch = contentsRect().height();
00131
00132 int vw = cw;
00133 int vh = ch;
00134
00135 if ( w > vw )
00136 vh -= sbHeight;
00137
00138 if ( h > vh )
00139 {
00140 vw -= sbWidth;
00141 if ( w > vw && vh == ch )
00142 vh -= sbHeight;
00143 }
00144 return QSize(vw, vh);
00145 }
00146
00147 QWidget *contentsWidget;
00148 };
00149
00150 #endif
00151
00152
00153 void QwtLegend::PrivateData::LegendMap::insert(
00154 const QwtLegendItemManager *item, QWidget *widget)
00155 {
00156 d_itemMap.insert(item, widget);
00157 d_widgetMap.insert(widget, item);
00158 }
00159
00160 void QwtLegend::PrivateData::LegendMap::remove(const QwtLegendItemManager *item)
00161 {
00162 QWidget *widget = d_itemMap[item];
00163 d_itemMap.remove(item);
00164 d_widgetMap.remove(widget);
00165 }
00166
00167 void QwtLegend::PrivateData::LegendMap::remove(QWidget *widget)
00168 {
00169 const QwtLegendItemManager *item = d_widgetMap[widget];
00170 d_itemMap.remove(item);
00171 d_widgetMap.remove(widget);
00172 }
00173
00174 void QwtLegend::PrivateData::LegendMap::clear()
00175 {
00176
00177
00178
00179
00180
00181
00182
00183 #if QT_VERSION < 0x040000
00184 QValueList<QWidget *> widgets;
00185
00186 QMap<const QwtLegendItemManager *, QWidget *>::const_iterator it;
00187 for ( it = d_itemMap.begin(); it != d_itemMap.end(); ++it )
00188 widgets.append(it.data());
00189 #else
00190 QList<QWidget *> widgets;
00191
00192 QMap<const QwtLegendItemManager *, QWidget *>::const_iterator it;
00193 for ( it = d_itemMap.begin(); it != d_itemMap.end(); ++it )
00194 widgets.append(it.value());
00195 #endif
00196
00197 d_itemMap.clear();
00198 d_widgetMap.clear();
00199
00200 for ( int i = 0; i < (int)widgets.size(); i++ )
00201 delete widgets[i];
00202 }
00203
00204 uint QwtLegend::PrivateData::LegendMap::count() const
00205 {
00206 return d_itemMap.count();
00207 }
00208
00209 inline const QWidget *QwtLegend::PrivateData::LegendMap::find(const QwtLegendItemManager *item) const
00210 {
00211 if ( !d_itemMap.contains((QwtLegendItemManager *)item) )
00212 return NULL;
00213
00214 return d_itemMap[(QwtLegendItemManager *)item];
00215 }
00216
00217 inline QWidget *QwtLegend::PrivateData::LegendMap::find(const QwtLegendItemManager *item)
00218 {
00219 if ( !d_itemMap.contains((QwtLegendItemManager *)item) )
00220 return NULL;
00221
00222 return d_itemMap[(QwtLegendItemManager *)item];
00223 }
00224
00225 inline const QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
00226 const QWidget *widget) const
00227 {
00228 if ( !d_widgetMap.contains((QWidget *)widget) )
00229 return NULL;
00230
00231 return d_widgetMap[(QWidget *)widget];
00232 }
00233
00234 inline QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
00235 const QWidget *widget)
00236 {
00237 if ( !d_widgetMap.contains((QWidget *)widget) )
00238 return NULL;
00239
00240 return (QwtLegendItemManager *)d_widgetMap[(QWidget *)widget];
00241 }
00242
00243 inline const QMap<QWidget *, const QwtLegendItemManager *> &
00244 QwtLegend::PrivateData::LegendMap::widgetMap() const
00245 {
00246 return d_widgetMap;
00247 }
00248
00249 inline QMap<QWidget *, const QwtLegendItemManager *> &
00250 QwtLegend::PrivateData::LegendMap::widgetMap()
00251 {
00252 return d_widgetMap;
00253 }
00254
00260 QwtLegend::QwtLegend(QWidget *parent):
00261 QFrame(parent)
00262 {
00263 setFrameStyle(NoFrame);
00264
00265 d_data = new QwtLegend::PrivateData;
00266 d_data->itemMode = QwtLegend::ReadOnlyItem;
00267 d_data->displayPolicy = QwtLegend::AutoIdentifier;
00268 d_data->identifierMode = QwtLegendItem::ShowLine |
00269 QwtLegendItem::ShowSymbol | QwtLegendItem::ShowText;
00270
00271 d_data->view = new QwtLegend::PrivateData::LegendView(this);
00272 d_data->view->setFrameStyle(NoFrame);
00273
00274 QwtDynGridLayout *layout = new QwtDynGridLayout(
00275 d_data->view->contentsWidget);
00276 #if QT_VERSION < 0x040000
00277 layout->setAutoAdd(true);
00278 #endif
00279 layout->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
00280
00281 d_data->view->contentsWidget->installEventFilter(this);
00282 }
00283
00285 QwtLegend::~QwtLegend()
00286 {
00287 delete d_data;
00288 }
00289
00298 void QwtLegend::setDisplayPolicy(LegendDisplayPolicy policy, int mode)
00299 {
00300 d_data->displayPolicy = policy;
00301 if (-1 != mode)
00302 d_data->identifierMode = mode;
00303
00304 QMap<QWidget *, const QwtLegendItemManager *> &map =
00305 d_data->map.widgetMap();
00306
00307 QMap<QWidget *, const QwtLegendItemManager *>::iterator it;
00308 for ( it = map.begin(); it != map.end(); ++it )
00309 {
00310 #if QT_VERSION < 0x040000
00311 QwtLegendItemManager *item = (QwtLegendItemManager *)it.data();
00312 #else
00313 QwtLegendItemManager *item = (QwtLegendItemManager *)it.value();
00314 #endif
00315 if ( item )
00316 item->updateLegend(this);
00317 }
00318 }
00319
00326 QwtLegend::LegendDisplayPolicy QwtLegend::displayPolicy() const
00327 {
00328 return d_data->displayPolicy;
00329 }
00330
00332 void QwtLegend::setItemMode(LegendItemMode mode)
00333 {
00334 d_data->itemMode = mode;
00335 }
00336
00338 QwtLegend::LegendItemMode QwtLegend::itemMode() const
00339 {
00340 return d_data->itemMode;
00341 }
00342
00349 int QwtLegend::identifierMode() const
00350 {
00351 return d_data->identifierMode;
00352 }
00353
00358 QWidget *QwtLegend::contentsWidget()
00359 {
00360 return d_data->view->contentsWidget;
00361 }
00362
00367 QScrollBar *QwtLegend::horizontalScrollBar() const
00368 {
00369 return d_data->view->horizontalScrollBar();
00370 }
00371
00376 QScrollBar *QwtLegend::verticalScrollBar() const
00377 {
00378 return d_data->view->verticalScrollBar();
00379 }
00380
00385 const QWidget *QwtLegend::contentsWidget() const
00386 {
00387 return d_data->view->contentsWidget;
00388 }
00389
00396 void QwtLegend::insert(const QwtLegendItemManager *plotItem, QWidget *legendItem)
00397 {
00398 if ( legendItem == NULL || plotItem == NULL )
00399 return;
00400
00401 QWidget *contentsWidget = d_data->view->contentsWidget;
00402
00403 if ( legendItem->parent() != contentsWidget )
00404 {
00405 #if QT_VERSION >= 0x040000
00406 legendItem->setParent(contentsWidget);
00407 #else
00408 legendItem->reparent(contentsWidget, QPoint(0, 0));
00409 #endif
00410 }
00411
00412 legendItem->show();
00413
00414 d_data->map.insert(plotItem, legendItem);
00415
00416 layoutContents();
00417
00418 if ( contentsWidget->layout() )
00419 {
00420 #if QT_VERSION >= 0x040000
00421 contentsWidget->layout()->addWidget(legendItem);
00422 #endif
00423
00424
00425
00426 QWidget *w = NULL;
00427
00428 #if QT_VERSION < 0x040000
00429 QLayoutIterator layoutIterator =
00430 contentsWidget->layout()->iterator();
00431 for ( QLayoutItem *item = layoutIterator.current();
00432 item != 0; item = ++layoutIterator)
00433 {
00434 #else
00435 for (int i = 0; i < contentsWidget->layout()->count(); i++)
00436 {
00437 QLayoutItem *item = contentsWidget->layout()->itemAt(i);
00438 #endif
00439 if ( w && item->widget() )
00440 {
00441 QWidget::setTabOrder(w, item->widget());
00442 w = item->widget();
00443 }
00444 }
00445 }
00446 if ( parentWidget() && parentWidget()->layout() == NULL )
00447 {
00448
00449
00450
00451
00452
00453
00454 #if QT_VERSION < 0x040000
00455 QApplication::postEvent(parentWidget(),
00456 new QEvent(QEvent::LayoutHint));
00457 #else
00458 QApplication::postEvent(parentWidget(),
00459 new QEvent(QEvent::LayoutRequest));
00460 #endif
00461 }
00462 }
00463
00470 QWidget *QwtLegend::find(const QwtLegendItemManager *plotItem) const
00471 {
00472 return d_data->map.find(plotItem);
00473 }
00474
00481 QwtLegendItemManager *QwtLegend::find(const QWidget *legendItem) const
00482 {
00483 return d_data->map.find(legendItem);
00484 }
00485
00492 void QwtLegend::remove(const QwtLegendItemManager *plotItem)
00493 {
00494 QWidget *legendItem = d_data->map.find(plotItem);
00495 d_data->map.remove(legendItem);
00496 delete legendItem;
00497 }
00498
00500 void QwtLegend::clear()
00501 {
00502 #if QT_VERSION < 0x040000
00503 bool doUpdate = isUpdatesEnabled();
00504 #else
00505 bool doUpdate = updatesEnabled();
00506 #endif
00507 setUpdatesEnabled(false);
00508
00509 d_data->map.clear();
00510
00511 setUpdatesEnabled(doUpdate);
00512 update();
00513 }
00514
00516 QSize QwtLegend::sizeHint() const
00517 {
00518 QSize hint = d_data->view->contentsWidget->sizeHint();
00519 hint += QSize(2 * frameWidth(), 2 * frameWidth());
00520
00521 return hint;
00522 }
00523
00528 int QwtLegend::heightForWidth(int width) const
00529 {
00530 width -= 2 * frameWidth();
00531
00532 int h = d_data->view->contentsWidget->heightForWidth(width);
00533 #if QT_VERSION < 0x040000
00534
00535
00536
00537 if ( h <= 0 )
00538 {
00539 QLayout *l = d_data->view->contentsWidget->layout();
00540 if ( l && l->hasHeightForWidth() )
00541 h = l->heightForWidth(width);
00542 }
00543 #endif
00544 if ( h >= 0 )
00545 h += 2 * frameWidth();
00546
00547 return h;
00548 }
00549
00553 void QwtLegend::layoutContents()
00554 {
00555 const QSize visibleSize = d_data->view->viewport()->size();
00556
00557 const QLayout *l = d_data->view->contentsWidget->layout();
00558 if ( l && l->inherits("QwtDynGridLayout") )
00559 {
00560 const QwtDynGridLayout *tl = (const QwtDynGridLayout *)l;
00561
00562 const int minW = int(tl->maxItemWidth()) + 2 * tl->margin();
00563
00564 int w = qwtMax(visibleSize.width(), minW);
00565 int h = qwtMax(tl->heightForWidth(w), visibleSize.height());
00566
00567 const int vpWidth = d_data->view->viewportSize(w, h).width();
00568 if ( w > vpWidth )
00569 {
00570 w = qwtMax(vpWidth, minW);
00571 h = qwtMax(tl->heightForWidth(w), visibleSize.height());
00572 }
00573
00574 d_data->view->contentsWidget->resize(w, h);
00575 #if QT_VERSION < 0x040000
00576 d_data->view->resizeContents(w, h);
00577 #endif
00578 }
00579 }
00580
00587 bool QwtLegend::eventFilter(QObject *o, QEvent *e)
00588 {
00589 if ( o == d_data->view->contentsWidget )
00590 {
00591 switch(e->type())
00592 {
00593 case QEvent::ChildRemoved:
00594 {
00595 const QChildEvent *ce = (const QChildEvent *)e;
00596 if ( ce->child()->isWidgetType() )
00597 d_data->map.remove((QWidget *)ce->child());
00598 break;
00599 }
00600 #if QT_VERSION < 0x040000
00601 case QEvent::LayoutHint:
00602 #else
00603 case QEvent::LayoutRequest:
00604 #endif
00605 {
00606 layoutContents();
00607 break;
00608 }
00609 #if QT_VERSION < 0x040000
00610 case QEvent::Resize:
00611 {
00612 updateGeometry();
00613 break;
00614 }
00615 #endif
00616 default:
00617 break;
00618 }
00619 }
00620
00621 return QFrame::eventFilter(o, e);
00622 }
00623
00624
00626 bool QwtLegend::isEmpty() const
00627 {
00628 return d_data->map.count() == 0;
00629 }
00630
00632 uint QwtLegend::itemCount() const
00633 {
00634 return d_data->map.count();
00635 }
00636
00638 #if QT_VERSION < 0x040000
00639 QValueList<QWidget *> QwtLegend::legendItems() const
00640 #else
00641 QList<QWidget *> QwtLegend::legendItems() const
00642 #endif
00643 {
00644 const QMap<QWidget *, const QwtLegendItemManager *> &map =
00645 d_data->map.widgetMap();
00646
00647 #if QT_VERSION < 0x040000
00648 QValueList<QWidget *> list;
00649 #else
00650 QList<QWidget *> list;
00651 #endif
00652
00653 QMap<QWidget *, const QwtLegendItemManager *>::const_iterator it;
00654 for ( it = map.begin(); it != map.end(); ++it )
00655 list += it.key();
00656
00657 return list;
00658 }
00659
00664 void QwtLegend::resizeEvent(QResizeEvent *e)
00665 {
00666 QFrame::resizeEvent(e);
00667 d_data->view->setGeometry(contentsRect());
00668 }