Changeset 17037 for fact


Ignore:
Timestamp:
08/23/13 14:54:34 (11 years ago)
Author:
ogrimm
Message:
Evidence GUI ported to qwt 6.1.0. Added highlighting of curves in GUI.
Location:
fact
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fact/Evidence/GUI.cc

    r14187 r17037  
    5050        // If service is array and no index given, try to find out how many indices exist and add all
    5151        if (FromIndex == -1 && Format.size() == 1) {
    52           DimCurrentInfo X(Service, NULL, 0);
     52          DimCurrentInfo X(Service, (char *) NULL, 0);
    5353         
    5454          FromIndex = 0;
     
    336336  // Widget properties
    337337  setAcceptDrops(true);
    338   setAxisScaleDraw(QwtPlot::xBottom, new EddTimeScale);
    339 
    340   // Update time range on plot when axis change (update() results in paintEvent())
    341   connect(axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), SLOT(update()));
     338
     339  // Horizontal time scale
     340  setAxisScaleDraw(QwtPlot::xBottom, new EddDateScale());
     341  connect(axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), SLOT(ScaleUpdate()));
    342342
    343343  // Additonal context menu items
     
    354354  Menu->insertAction(Menu->actions().value(10), Action);
    355355   
    356   // Set timer to regularly update plot if new data available
     356  // Set timer update plot after new data added
    357357  SingleShot = new QTimer(this);
    358358  connect(SingleShot, SIGNAL(timeout()), this, SLOT(UpdatePlot()));
     
    390390  List.append(N);
    391391
    392   // Use custom legend widget
    393   EddLegend *Legend = new EddLegend(N.Curve, this);
    394   legend()->remove(N.Curve);
    395   legend()->insert(N.Curve, (QWidget *) Legend);
    396 
    397   // Context menu might delete curve and legend -> seg fault if using direct connection, as legend item deleted
    398   connect(Legend, SIGNAL(DeleteCurve(QwtPlotCurve *)), this, SLOT(RemoveService(QwtPlotCurve *)), Qt::QueuedConnection);
    399 
    400392  // Get history
    401393  struct EddDim::HistItem Hist = Handler->GetHistory(Name);
     
    403395  for (int i=0; i<Hist.DataText.size(); i++) {
    404396    if (Hist.DataText[i].second.size() > N.Index) {
    405           AddPoint(List.size()-1, Hist.DataText[i].first, Hist.DataText[i].second.at(N.Index).toFloat());
     397          AddPoint(List.size()-1, double(Hist.DataText[i].first)*1000, Hist.DataText[i].second.at(N.Index).toFloat());
    406398        }
    407399  }
    408 
     400 
    409401  // Subscribe to service and start updating plot after 100 ms (to allow addition of other curves)
    410402  Handler->Subscribe(Name, this, Index);
    411403  SingleShot->start(100);
    412404}
    413 
    414 // Update widget (must happen in GUI thread)
    415 void EddPlot::Update(const QString &Name, int Time, const QByteArray &, const QString &Format, const QString &Text, int Index) {
    416 
    417   for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name==Name && List[ItemNo].Index==Index) {
    418 
    419         // Append data if service available
    420         if (SetStatus(this, Name, Time, Format)) AddPoint(ItemNo, Time, atof(Text.toAscii().data()));
    421         NewData = true;
    422   }
    423 }
    424 
    425 // Add text indicating time range to plot
    426 void EddPlot::paintEvent(QPaintEvent *) {
    427 
    428   QString Text;
    429   QFont Font;
    430   QPainter Painter(this);
    431  
    432   Text = QDateTime::fromTime_t((int) axisScaleDiv(QwtPlot::xBottom)->lowerBound()).toString("d-MMM-yyyy hh:mm:ss") + " to " + QDateTime::fromTime_t((int) axisScaleDiv(QwtPlot::xBottom)->upperBound()).toString("d-MMM-yyyy hh:mm:ss");
    433 
    434   Font.setPointSize(6); 
    435   Painter.setFont(Font);
    436   Painter.drawText(0, height(), Text);
    437 }
    438 
    439 // Drag and drop methods
    440 void EddPlot::dragEnterEvent(QDragEnterEvent *Event) {
    441    
    442   if (Event->mimeData()->hasFormat("Edd/Service")) Event->acceptProposedAction();
    443 }
    444 
    445 void EddPlot::dropEvent(QDropEvent *Event) {
    446 
    447   QByteArray D(Event->mimeData()->data("Edd/Service"));
    448   AddService(D.left(D.lastIndexOf(' ')), D.right(D.size()-D.lastIndexOf(' ')).toInt());
    449 }
    450 
    451 // Add new service by pasting name
    452 void EddPlot::MenuPasteService() {
    453 
    454   const QMimeData *D = QApplication::clipboard()->mimeData();
    455   if (!D->hasFormat("Edd/Service")) return;
    456  
    457   QByteArray E(D->data("Edd/Service"));
    458   AddService(E.left(E.lastIndexOf(' ')), E.right(E.size()-E.lastIndexOf(' ')).toInt());
    459 }
    460 
    461 // Show last hour/last day
    462 void EddPlot::MenuShowLastHour() {
    463 
    464   setAxisScale(QwtPlot::xBottom, time(NULL)-60*60, time(NULL)+60);
    465   replot();
    466 }
    467 
    468 void EddPlot::MenuShowLastDay() {
    469 
    470   setAxisScale(QwtPlot::xBottom, time(NULL)-24*3600, time(NULL)+3600);
    471   replot();
    472 }
    473 
    474 void EddPlot::MenuAllAsText() {
    475 
    476   QMainWindow *M = new QMainWindow;
    477   M->setCentralWidget(new QWidget(M));
    478   M->setStatusBar(new QStatusBar(M));
    479   M->setAttribute(Qt::WA_DeleteOnClose);
    480   M->setWindowTitle("Edd Services");
    481 
    482   QGridLayout *Layout = new QGridLayout(M->centralWidget());
    483 
    484   for (int i=0; i<List.size(); i++) {
    485       Layout->addWidget(new EddLineDisplay(List[i].Name, List[i].Index), i/10, i%10);
    486   }
    487 
    488   M->resize(400,450);
    489   M->show();
    490 }
    491 
    492405
    493406// Remove subscription
     
    502415}
    503416
     417// Update widget (must happen in GUI thread)
     418void EddPlot::Update(const QString &Name, int Time, const QByteArray &, const QString &Format, const QString &Text, int Index) {
     419
     420  for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name==Name && List[ItemNo].Index==Index) {
     421
     422        // Append data if service available
     423        if (SetStatus(this, Name, Time, Format)) AddPoint(ItemNo, (double) Time*1000, atof(Text.toAscii().data()));
     424        NewData = true;
     425  }
     426}
     427
     428// Add text indicating time range to plot
     429void EddPlot::ScaleUpdate() {
     430
     431  QwtText Text;
     432  QFont Font;
     433 
     434  // Set footer
     435  Text = QDateTime::fromMSecsSinceEpoch(axisScaleDiv(QwtPlot::xBottom).lowerBound()).toString("d-MMM-yyyy hh:mm:ss") + " to " + QDateTime::fromMSecsSinceEpoch(axisScaleDiv(QwtPlot::xBottom).upperBound()).toString("d-MMM-yyyy hh:mm:ss");
     436
     437  Font.setPointSize(6);
     438  Text.setFont(Font);
     439  setFooter(Text);
     440}
     441
     442// Drag and drop methods
     443void EddPlot::dragEnterEvent(QDragEnterEvent *Event) {
     444   
     445  if (Event->mimeData()->hasFormat("Edd/Service")) Event->acceptProposedAction();
     446}
     447
     448void EddPlot::dropEvent(QDropEvent *Event) {
     449
     450  QByteArray D(Event->mimeData()->data("Edd/Service"));
     451  AddService(D.left(D.lastIndexOf(' ')), D.right(D.size()-D.lastIndexOf(' ')).toInt());
     452}
     453
     454// Add new service by pasting name
     455void EddPlot::MenuPasteService() {
     456
     457  const QMimeData *D = QApplication::clipboard()->mimeData();
     458  if (!D->hasFormat("Edd/Service")) return;
     459 
     460  QByteArray E(D->data("Edd/Service"));
     461  AddService(E.left(E.lastIndexOf(' ')), E.right(E.size()-E.lastIndexOf(' ')).toInt());
     462}
     463
     464// Show last hour/last day
     465void EddPlot::MenuShowLastHour() {
     466
     467  setAxisScale(QwtPlot::xBottom, (time(NULL)-60*60)*1000, (time(NULL)+60)*1000);
     468  replot();
     469}
     470
     471void EddPlot::MenuShowLastDay() {
     472
     473  setAxisScale(QwtPlot::xBottom, (time(NULL)-24*3600)*1000, (time(NULL)+3600)*1000);
     474  replot();
     475}
     476
     477void EddPlot::MenuAllAsText() {
     478
     479  QMainWindow *M = new QMainWindow;
     480  M->setCentralWidget(new QWidget(M));
     481  M->setStatusBar(new QStatusBar(M));
     482  M->setAttribute(Qt::WA_DeleteOnClose);
     483  M->setWindowTitle("Edd Services");
     484
     485  QGridLayout *Layout = new QGridLayout(M->centralWidget());
     486
     487  for (int i=0; i<List.size(); i++) {
     488      Layout->addWidget(new EddLineDisplay(List[i].Name, List[i].Index), i/10, i%10);
     489  }
     490
     491  M->resize(400,450);
     492  M->show();
     493}
     494
     495//
     496// Reimplementation of QwtDateScaleDraw::label()
     497//
     498QwtText EddDateScale::label(double Value) const {
     499
     500  QString Format;
     501   
     502  if (scaleDiv().range() > 30*24*60*60*1000.0) Format = "d-MMM\n yyyy";
     503  else if (scaleDiv().range() > 1*24*60*60*1000.0) Format = "  h 'h'\nd-MMM";
     504  else if (scaleDiv().range() > 60*60*1000.0) Format = "hh:mm";
     505  else Format = "hh:mm:ss"; 
     506
     507  return QwtDate::toString(toDateTime(Value), Format, QwtDate::FirstThursday);
     508}
    504509
    505510//////////////////
     
    514519  setAutoReplot(false);
    515520  setCanvasBackground(EddPlotBackgroundColor);
    516   setMargin(15);
    517521  NewData = false;
    518522
    519523  // Plot navigation
    520524  Zoomer = new QwtPlotZoomer(QwtPlot::xBottom,QwtPlot::yLeft,canvas());
    521   connect(Zoomer, SIGNAL(zoomed(const QwtDoubleRect &)), this, SLOT(HandleZoom(const QwtDoubleRect &)));
    522   connect(Zoomer, SIGNAL(zoomed(const QwtDoubleRect &)), this, SLOT(ReDoStats()));
     525  Zoomer->setTrackerMode(QwtPicker::AlwaysOff);
     526  connect(Zoomer, SIGNAL(zoomed(const QRectF &)), this, SLOT(HandleZoom(const QRectF &)));
     527  connect(Zoomer, SIGNAL(zoomed(const QRectF &)), this, SLOT(ReDoStats()));
    523528
    524529  Magnifier = new QwtPlotMagnifier(canvas());
    525   Magnifier->setMouseButton(Qt::NoButton,Qt::NoButton);
     530  Magnifier->setMouseButton(Qt::NoButton, Qt::NoModifier);
    526531  Magnifier->setZoomInKey(Qt::Key_M, Qt::NoModifier);
    527532  Magnifier->setZoomOutKey(Qt::Key_M, Qt::ShiftModifier);
     
    531536  connect(Panner, SIGNAL(panned(int, int)), this, SLOT(ReDoStats()));
    532537
    533   Picker = new QwtPicker(QwtPicker::CornerToCorner|QwtPicker::RectSelection, QwtPicker::RectRubberBand, QwtPicker::AlwaysOff, this);
    534   connect(Picker, SIGNAL(selected(const QwtPolygon &)), SLOT(MouseSelection(const QwtPolygon &)));
     538  Picker = new QwtPicker(QwtPicker::RectRubberBand, QwtPicker::AlwaysOff, this);
     539  Picker->setStateMachine(new QwtPickerDragRectMachine);
     540  connect(Picker, SIGNAL(selected(const QPolygon &)), SLOT(MouseSelection(const QPolygon &)));
    535541
    536542  // Grid and legend
    537543  Grid = new QwtPlotGrid;
    538   Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
     544  Grid->setMajorPen(QPen(Qt::gray, 0, Qt::DotLine));
    539545  Grid->attach(this);
    540546 
    541   insertLegend(new QwtLegend(), QwtPlot::TopLegend, 0.3);
     547  Legend = new EddLegend();
     548  insertLegend(Legend, QwtPlot::TopLegend, 0.3);
    542549
    543550  // Marker for statistics text
     
    599606    // Calculate mean and sigma for data points currently visible       
    600607        for (int j=0; j<Items[i].y.size(); j++) {
    601           if (!axisScaleDiv(QwtPlot::xBottom)->contains(Items[i].x[j])) continue;
     608          if (!axisScaleDiv(QwtPlot::xBottom).contains(Items[i].x[j])) continue;
    602609          Mean += Items[i].y[j];
    603610          Sigma += Items[i].y[j]*Items[i].y[j];
     
    620627  QwtText text(Text);
    621628  text.setFont(QFont("Helvetica", 8));
    622   Stats->setValue(axisScaleDiv(QwtPlot::xBottom)->upperBound(), axisScaleDiv(QwtPlot::yLeft)->upperBound());
     629  Stats->setValue(axisScaleDiv(QwtPlot::xBottom).upperBound(), axisScaleDiv(QwtPlot::yLeft).upperBound());
    623630  Stats->setLabel(text);
    624631
     
    630637void EddBasePlot::UpdatePlot() {
    631638
    632   double Lower = axisScaleDiv(QwtPlot::xBottom)->lowerBound();
    633   double Upper = axisScaleDiv(QwtPlot::xBottom)->upperBound();
     639  double Lower = axisScaleDiv(QwtPlot::xBottom).lowerBound();
     640  double Upper = axisScaleDiv(QwtPlot::xBottom).upperBound();
    634641  double MaxTime = DBL_MIN;
    635   static QwtSymbol Symbol, Sym1;
    636   Symbol.setStyle(QwtSymbol::Ellipse);
    637   Symbol.setSize(4);
    638642
    639643  // Only update if called by timer if new data is available
     
    645649    setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
    646650  }
    647   else setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
     651  else setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine);
    648652
    649653  for (int ItemNo=0; ItemNo<Items.size(); ItemNo++) {
     
    654658
    655659        // Set symbol if requested
    656     if (StyleAction->isChecked()) Items[ItemNo].Signal->setSymbol(Symbol);
    657     else Items[ItemNo].Signal->setSymbol(Sym1);
     660    if (StyleAction->isChecked()) {
     661          QwtSymbol *Symbol = new QwtSymbol();
     662          Symbol->setStyle(QwtSymbol::Ellipse);
     663          Symbol->setSize(4);
     664          Items[ItemNo].Signal->setSymbol(Symbol);
     665        }
     666    else Items[ItemNo].Signal->setSymbol(new QwtSymbol);
    658667
    659668        // Determine number of data points
     
    675684
    676685    // Plot data
    677     Items[ItemNo].Signal->setData(Items[ItemNo].x.data(), y, DataPoints);
     686    Items[ItemNo].Signal->setSamples(Items[ItemNo].x.data(), y, DataPoints);
    678687    Items[ItemNo].Signal->show();
    679688        delete[] y;
     
    704713  struct PlotItem N;
    705714
    706   N.Signal = new QwtPlotCurve;
     715  N.Signal = new QwtPlotCurve(Title);
    707716  N.Signal->attach(this);
    708   N.Signal->setTitle(Title);
    709717  N.Signal->setPen(QColor(LineColors[Items.size() % (sizeof(LineColors)/sizeof(Qt::GlobalColor))]));
    710718  N.Largest = DBL_MIN;
     
    712720  Items.append(N);
    713721 
     722  QVariant ItemInfo     = itemToInfo(N.Signal);
     723  ((EddLegendLabel *) Legend->legendWidget(ItemInfo))->Curve = N.Signal;
     724 
     725  // Context menu might delete curve and legend -> seg fault if using direct connection, as legend item deleted
     726  connect(((EddLegendLabel *) Legend->legendWidget(ItemInfo)), SIGNAL(DeleteCurve(QwtPlotCurve *)), SLOT(RemoveService(QwtPlotCurve *)), Qt::QueuedConnection);
     727
    714728  return N.Signal;
     729}
     730
     731// Remove item
     732void EddBasePlot::DeleteCurve(QwtPlotCurve *Curve) {
     733
     734  for (int i=0; i<Items.size(); i++) if (Items[i].Signal == Curve) {
     735        delete Curve;
     736        Items.takeAt(i);
     737        break;
     738  }
     739  UpdatePlot();
    715740}
    716741
     
    737762
    738763// Rescale plot in case selection has been made outside the canvas
    739 void EddBasePlot::MouseSelection(const QPolygon &P) {
     764void EddBasePlot::MouseSelection(const QPolygon &P_integer) {
    740765 
    741   QwtDoubleInterval xPlot, xMouse, yPlot, yMouse;
    742 
     766  QwtInterval xPlot, xMouse, yPlot, yMouse;
     767  QPolygonF P(P_integer);
     768 
    743769  // Shift selected rectangle so that upper left corner is 0/0 on canvas
    744   QRect R = P.boundingRect().translated(-plotLayout()->canvasRect().topLeft());
     770  QRectF R = P.boundingRect().translated(-plotLayout()->canvasRect().topLeft());
    745771
    746772  // Current axis intervals
    747   xPlot = axisScaleDiv(QwtPlot::xBottom)->interval();
    748   yPlot = axisScaleDiv(QwtPlot::yLeft)->interval();
     773  xPlot = axisScaleDiv(QwtPlot::xBottom).interval();
     774  yPlot = axisScaleDiv(QwtPlot::yLeft).interval();
    749775 
    750776  // Selected axis intervals
    751   xMouse = QwtDoubleInterval(invTransform(QwtPlot::xBottom, R.left()),
     777  xMouse = QwtInterval(invTransform(QwtPlot::xBottom, R.left()),
    752778                invTransform(QwtPlot::xBottom, R.right()));
    753   yMouse = QwtDoubleInterval(invTransform(QwtPlot::yLeft, R.bottom()),
     779  yMouse = QwtInterval(invTransform(QwtPlot::yLeft, R.bottom()),
    754780                invTransform(QwtPlot::yLeft, R.top()));
    755781
     
    773799  // Rescale y axis (increase range if selected rectangle larger than axis area)
    774800  if (R.right() < 0) {
    775         if (yMouse.maxValue() > axisScaleDiv(QwtPlot::yLeft)->upperBound()) {
     801        if (yMouse.maxValue() > axisScaleDiv(QwtPlot::yLeft).upperBound()) {
    776802          yMouse.setMaxValue(yMouse.maxValue() + yPlot.width());
    777803        }
    778         if (yMouse.minValue() < axisScaleDiv(QwtPlot::yLeft)->lowerBound()) {
     804        if (yMouse.minValue() < axisScaleDiv(QwtPlot::yLeft).lowerBound()) {
    779805          yMouse.setMinValue(yMouse.minValue() - yPlot.width());
    780806        }
     
    785811  // Rescale x axis (increase range if selected rectangle larger than axis area)
    786812  if (R.top() > plotLayout()->canvasRect().height()) {
    787         if (xMouse.maxValue() > axisScaleDiv(QwtPlot::xBottom)->upperBound()) {
     813        if (xMouse.maxValue() > axisScaleDiv(QwtPlot::xBottom).upperBound()) {
    788814          xMouse.setMaxValue(xMouse.maxValue() + xPlot.width());
    789815        }
    790         if (xMouse.minValue() < axisScaleDiv(QwtPlot::xBottom)->lowerBound()) {
     816        if (xMouse.minValue() < axisScaleDiv(QwtPlot::xBottom).lowerBound()) {
    791817          xMouse.setMinValue(xMouse.minValue() - xPlot.width());
    792818        }
     
    800826
    801827// Reset graph axes to autoscale when fully unzoomed
    802 void EddBasePlot::HandleZoom(const QwtDoubleRect &) {
     828void EddBasePlot::HandleZoom(const QRectF &) {
    803829
    804830  if(Zoomer->zoomRectIndex() == 0) {
     
    809835  UpdatePlot();
    810836}
     837
     838// Double clicking hightlights curve
     839void EddBasePlot::mouseDoubleClickEvent (QMouseEvent *Event) {
     840       
     841  double Dist, MinDistance = std::numeric_limits<double>::infinity();
     842  int Index = -1;
     843
     844  // Check which curve is closest
     845  for (int i=0; i<Items.size(); i++) {
     846        if (Items[i].Signal->closestPoint(Event->pos(), &Dist) != -1 && Dist < MinDistance) {
     847          MinDistance = Dist;
     848          Index = i;
     849        }
     850  }
     851
     852  // Toggle 'thick line' action
     853  if (Index != -1) {
     854        ((EddLegendLabel *) Legend->legendWidget(itemToInfo(Items[Index].Signal)))->ThickLineAction->toggle();
     855  }
     856}
    811857   
    812858// Opening context menu
     
    820866
    821867  Zoomer->zoom(0);
    822   UpdatePlot();
    823 }
    824 
    825 
    826 // Remove item
    827 void EddBasePlot::DeleteCurve(QwtPlotCurve *Curve) {
    828 
    829   for (int i=0; i<Items.size(); i++) if (Items[i].Signal == Curve) {
    830         delete Curve;
    831         Items.takeAt(i);
    832         break;
    833   }
    834868  UpdatePlot();
    835869}
     
    863897  for (int ItemNo=0; ItemNo<Items.size(); ItemNo++) {
    864898    Stream << QString("# ") + Items[ItemNo].Signal->title().text() + ".hist" << endl;
    865     for (int i=0; i<Items[ItemNo].Signal->dataSize(); i++) {
    866       Stream << Items[ItemNo].x.at(i) << " " << Items[ItemNo].Signal->y(i) << endl;
     899    for (unsigned int i=0; i<Items[ItemNo].Signal->dataSize(); i++) {
     900      //Stream << Items[ItemNo].x.at(i) << " " << Items[ItemNo].Signal->y(i) << endl;
     901      Stream << Items[ItemNo].x.at(i) << " " << Items[ItemNo].Signal->sample(i).y() << endl;
    867902    }
    868903  }
     
    908943    "Pan\tShift and left mouse button\n\n"
    909944        "ESC cancels selection\n"
     945        "Double-clicking highlights nearest curve\n"
    910946    "Cursor keys move mouse\n\n"
    911947        "Statistics are calculated over the current x axis extend\n\n"
     
    915951
    916952
    917 ////////////////
    918 // Edd Legend //
    919 ////////////////
    920 
    921 EddLegend::EddLegend(QwtPlotCurve *Curve, EddPlot *Plot): Curve(Curve), Plot(Plot) {
     953////////////////////////////////
     954// Edd Legend and LegendLabel //
     955////////////////////////////////
     956
     957// Reimplementation to return EddLegendLabel widget
     958QWidget *EddLegend::createWidget(const QwtLegendData &) const {
     959
     960  return new EddLegendLabel();
     961}
     962       
     963// Constructor for EddLegendLabel class
     964EddLegendLabel::EddLegendLabel() {
    922965
    923966  // Context menu
     
    925968  Menu->addAction("Open in new history", this, SLOT(MenuOpenHistory()));
    926969  Menu->addAction("Copy service", this, SLOT(MenuCopyService()));
    927   Menu->addAction("Normal line", this, SLOT(MenuNormalLine()));
    928   Menu->addAction("Thick line", this, SLOT(MenuThickLine()));
     970
     971  ThickLineAction = new QAction("Thick line", this);
     972  ThickLineAction->setCheckable(true);
     973  connect(ThickLineAction, SIGNAL(toggled(bool)), SLOT(MenuThickLine(bool)));
     974  Menu->addAction(ThickLineAction);
     975
    929976  Menu->addAction("Remove curve", this, SLOT(MenuRemove()));
    930 }
    931 
    932 //
     977
     978  Curve = NULL;
     979}
     980
    933981// Opening context menu
    934 //
    935 void EddLegend::contextMenuEvent(QContextMenuEvent *Event) {
     982void EddLegendLabel::contextMenuEvent(QContextMenuEvent *Event) {
    936983 
    937984  Menu->exec(Event->globalPos());
     
    939986
    940987// Handling of mouse press event: Register start position for drag
    941 void EddLegend::mousePressEvent(QMouseEvent *Event) {
     988void EddLegendLabel::mousePressEvent(QMouseEvent *Event) {
    942989
    943990  if (Event->button() == Qt::LeftButton) dragStart = Event->pos();
     
    945992
    946993// Handling of dragging (Drag and MimeData will be deleted by Qt)
    947 void EddLegend::mouseMoveEvent(QMouseEvent *Event) {
     994void EddLegendLabel::mouseMoveEvent(QMouseEvent *Event) {
    948995
    949996  if ((Event->buttons() & Qt::LeftButton) == 0) return;
     
    9621009
    9631010// Handling of mouse release event: Open history
    964 void EddLegend::mouseReleaseEvent(QMouseEvent *Event) {
     1011void EddLegendLabel::mouseReleaseEvent(QMouseEvent *Event) {
    9651012
    9661013  if (Event->button() != Qt::LeftButton) return;
     
    9741021
    9751022// Menu: Open history plot
    976 void EddLegend::MenuOpenHistory() {
     1023void EddLegendLabel::MenuOpenHistory() {
    9771024
    9781025  QString D(text().text());
     
    9841031
    9851032// Menu: Copy service name
    986 void EddLegend::MenuCopyService() {
     1033void EddLegendLabel::MenuCopyService() {
    9871034
    9881035  QString D(text().text());
     
    9951042}
    9961043
    997 // Menu: Normal line width
    998 void EddLegend::MenuNormalLine() {
    999 
     1044// Menu: Thick line width
     1045void EddLegendLabel::MenuThickLine(bool State) {
     1046
     1047  if (Curve == NULL) {
     1048        printf("Warning: No QwtPlotCurve set in EddLegendLabel::MenuThickLine(), programming error\n");
     1049        return;
     1050  }
     1051
     1052  // Set pxel width of curve
    10001053  QPen Pen = Curve->pen();
    1001   Pen.setWidth(1);
     1054  Pen.setWidth(State ? 4:1);
    10021055  Curve->setPen(Pen);
    10031056  Curve->plot()->replot();
     1057 
     1058  // Highlight legend entry
     1059  QFont Font = font();
     1060  Font.setWeight(State ? QFont::Bold:QFont::Normal);
     1061  setFont(Font);
    10041062}
    10051063
    10061064// Menu: Normal line width
    1007 void EddLegend::MenuThickLine() {
    1008 
    1009   QPen Pen = Curve->pen();
    1010   Pen.setWidth(4);
    1011   Curve->setPen(Pen);
    1012   Curve->plot()->replot();
    1013 }
    1014 
    1015 // Menu: Normal line width
    1016 void EddLegend::MenuRemove() {
     1065void EddLegendLabel::MenuRemove() {
    10171066
    10181067  emit(DeleteCurve(Curve));
     
    10311080  setAttribute(Qt::WA_DeleteOnClose);
    10321081  setAutoFillBackground(true);
    1033   //setText("connecting...");
    10341082  document()->setMaximumBlockCount(1000);
    10351083  Accumulate = true;
  • fact/Evidence/GUI.h

    r12940 r17037  
    1717#include <qwt_plot_layout.h>
    1818#include <qwt_legend.h>
    19 #include <qwt_legend_item.h>
     19#include <qwt_legend_label.h>
    2020#include <qwt_symbol.h>
    2121#include <qwt_plot_marker.h>
    22 #include <qwt_data.h>
    2322#include <qwt_color_map.h>
     23#include <qwt_date_scale_draw.h>
    2424
    2525#include <limits>
     
    4444
    4545// Base class for Edd plot
    46 // DeleteCurve() is pure virtual and needs to be implemented iin the application class
     46// RemoveService() is pure virtual and needs to be implemented in the application class,
     47// it will be called through signal by context menu of legend entries
    4748class EddBasePlot: public QwtPlot {
    4849  Q_OBJECT
     
    7475        QwtPlotMagnifier *Magnifier;
    7576    QwtPicker *Picker;
    76         QwtDoubleRect BBox;
     77        QRectF BBox;
    7778        QwtPlotMarker *Stats;
    78                
     79        class EddLegend *Legend;
     80       
    7981  public:
    8082    EddBasePlot(QWidget * = NULL);
     
    8486        bool NewData;
    8587        QwtPlotCurve *NewCurve(QwtText);
     88        virtual void RemoveService(QwtPlotCurve *) = 0;
    8689        void DeleteCurve(QwtPlotCurve *);
    8790        void ClearCurve(unsigned int);
     
    9396  private slots:
    9497        void ReDoStats();
    95     void HandleZoom(const QwtDoubleRect &);
    96         void MouseSelection(const QwtPolygon &);
     98    void HandleZoom(const QRectF &);
     99        void MouseSelection(const QPolygon &);
     100        void mouseDoubleClickEvent(QMouseEvent *);
    97101        void contextMenuEvent(QContextMenuEvent *);
    98102    void MenuSetUpdateRate();       
     
    154158    Q_OBJECT
    155159
    156         // Time scale for axis
    157         class EddTimeScale: public QwtScaleDraw {
    158 
    159           public:
    160                 EddTimeScale() {}
    161 
    162                 virtual QwtText label(double v) const {
    163                   // Adapt text format to time span
    164                   QString Format;
    165                   if (scaleDiv().range() < 60*60) Format = "hh' h\n'mm:ss";
    166                   else if (scaleDiv().range() < 24*60*60) Format = "hh:mm";
    167                   else if (scaleDiv().range() < 30*24*60*60) Format = "h' h\n'd-MMM";
    168                   else Format = "d-MMM'\n'yyyy";
    169 
    170                   // Generate text
    171                   QwtText Text = QDateTime::fromTime_t((int) v).toString(Format);
    172                   QFont Font = Text.font();
    173                   Font.setPointSize(7);
    174                   Text.setFont(Font);
    175 
    176           return Text;
    177                 }
    178         };
    179 
    180160    struct ItemDetails {
    181161      QString Name;
     
    186166
    187167  private:
     168    //EddDateScale *Scale;
    188169        QwtLegend *Legend;
    189170        QTimer *SingleShot;
     
    192173    void dragEnterEvent(QDragEnterEvent *);
    193174    void dropEvent(QDropEvent *);
    194         void paintEvent(QPaintEvent *);
    195175               
    196176  public:
     
    202182  public slots:
    203183        void RemoveService(QwtPlotCurve *);
    204 
    205   private slots:
     184    void borderPath(QRect) {}; //Dummy method for qwtPicker, prevents QMetaObject::invokeMethod: No such method EddPlot::borderPath(QRect)
     185   
     186  private slots:
     187    void ScaleUpdate();
    206188    void MenuPasteService();
    207189        void MenuShowLastHour();
     
    210192};
    211193
    212 
    213 // Legend
    214 class EddLegend: public QwtLegendItem {
     194// Scale showing date and time
     195class EddDateScale: public QwtDateScaleDraw {
     196
     197  public:
     198        QwtText label(double) const;
     199};
     200
     201// Legend and legend label with protected methods implemented
     202class EddLegend: public QwtLegend {
     203
     204  protected:
     205        QWidget *createWidget(const QwtLegendData &) const;
     206};
     207
     208class EddLegendLabel: public QwtLegendLabel {
    215209    Q_OBJECT
    216210
    217211    QMenu *Menu;
    218212    QPoint dragStart;
    219         QwtPlotCurve *Curve;
    220         EddPlot *Plot;
    221 
    222   public:
    223         EddLegend(QwtPlotCurve *, EddPlot *);
     213       
     214  public:
     215        EddLegendLabel();
    224216
    225217        void contextMenuEvent(QContextMenuEvent *);
     
    228220    void mouseMoveEvent(QMouseEvent *);
    229221       
     222        QwtPlotCurve *Curve;
     223        QAction *ThickLineAction;
     224
    230225  private slots:
    231226        void MenuOpenHistory();
    232227        void MenuCopyService();
    233         void MenuNormalLine();
    234         void MenuThickLine();
     228        void MenuThickLine(bool);
    235229        void MenuRemove();
    236230       
  • fact/tools/Edd/Edd.cc

    r14255 r17037  
    8585  N.Channel = Channel;
    8686  N.Trigger = new QwtPlotMarker();
    87   N.Trigger->setSymbol(QwtSymbol(QwtSymbol::Diamond, QBrush(N.Curve->pen().color()), N.Curve->pen(), QSize(10,10)));
     87  N.Trigger->setSymbol(new QwtSymbol(QwtSymbol::Diamond, QBrush(N.Curve->pen().color()), N.Curve->pen(), QSize(10,10)));
    8888  N.Trigger->attach(this);
    8989
     
    778778
    779779  for (int i=0; i<Data.size(); i++) {
    780         Pixel[i]->setPalette(QPalette(Map.color(QwtDoubleInterval(300, 400), Data[i])));
     780        Pixel[i]->setPalette(QPalette(Map.color(QwtInterval(300, 400), Data[i])));
    781781  }
    782782}
     
    10531053  static bool AlarmServerWarned = false;
    10541054
     1055
     1056  // Removed 19 August 2013
     1057  return;
     1058
    10551059  // === Check service Alarm/MasterAlarm ===
    10561060  DimCurrentInfo MasterAlarm("Alarm/MasterAlarm", -1);
  • fact/tools/Edd/Edd.h

    r12940 r17037  
    4949  public slots:
    5050        void OpenRawFile(QString=QString());
    51        
     51        void RemoveService(QwtPlotCurve *) {};
     52               
    5253  signals:
    5354        void PixelData(QVector<double>);
  • fact/tools/Scripts/Logon

    r11368 r17037  
    77if [ -z "$DIMDIR" ]; then export DIMDIR=/usr/local/dim/; fi
    88if [ -z "$QWTDIR" ]; then export QWTDIR=/usr/local/qwt/; fi
    9 if [ -z "$QTDIR" ]; then export QTDIR=/usr/local/Trolltech/Qt-4.6.2; fi
    109
    1110#Set paths
    1211export LD_LIBRARY_PATH=$QWTDIR/lib:$DIMDIR/linux:$LD_LIBRARY_PATH
    13 export PATH=.:$DIMDIR/linux:$QTDIR/bin:$PATH
     12export PATH=.:$DIMDIR/linux:$PATH
Note: See TracChangeset for help on using the changeset viewer.