7#include <qwt_plot_grid.h> 
    8#include <qwt_plot_spectrogram.h> 
   10#include <qwt_scale_engine.h> 
   14#include <QApplication> 
   25#include <QPrintDialog> 
   26#include <QProgressDialog> 
   29#include <QTableWidget> 
   33#include "CubePlotCurve.h" 
   34#include "CubePlotCurveConfigureDialog.h"  
   35#include "CubeViewport.h" 
   37#include "Interpolator.h" 
   38#include "MainWindow.h" 
   39#include "MdiCubeViewport.h" 
   40#include "PlotWindowBestFitDialog.h" 
   43#include "PvlKeyword.h" 
   44#include "QHistogram.h" 
   46#include "TableMainWindow.h" 
   77    setObjectName(
"Plot Window: " + title);
 
   84      IString msg = 
"PlotWindow cannot be instantiated with a NULL parent";
 
   88    installEventFilter(
this);
 
   92    setWindowTitle(title);
 
   96    connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)),
 
  100    connect(
this, SIGNAL(requestFillTable()),
 
  101            this, SLOT(
fillTable()), Qt::QueuedConnection);
 
  103    QMap<PlotCurve::Units, QString> unitLabels;
 
  122    setWindowFlags(Qt::Tool);
 
  124    setWindowFlags(Qt::Dialog);
 
 
  130  PlotWindow::~PlotWindow() {
 
  147    m_plot->installEventFilter(
this);
 
  148    m_plot->setAxisMaxMinor(QwtPlot::yLeft, 5);
 
  149    m_plot->setAxisMaxMajor(QwtPlot::xBottom, 30);
 
  150    m_plot->setAxisMaxMinor(QwtPlot::xBottom, 5);
 
  151    m_plot->setAxisLabelRotation(QwtPlot::xBottom, 45);
 
  152    m_plot->setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignRight);
 
  156    m_legend->setDefaultItemMode(QwtLegendData::Clickable);
 
  157    m_legend->setWhatsThis(
"Right Click on a legend item to display the context " 
  165    m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
 
  166    m_grid->setMinorPen(QPen(Qt::gray, 1, Qt::DotLine));
 
  168    m_grid->setVisible(
false);
 
  172    m_zoomer->setRubberBandPen(QPen(Qt::lightGray));
 
  173    m_zoomer->setTrackerPen(QPen(Qt::lightGray));
 
 
  208    m_plot->setAxisTitle(axisId, title);
 
 
  241    return m_plot->title().text();
 
 
  289    m_plot->setCanvasBackground(c);
 
 
  317    return m_plot->canvasBackground().color();
 
 
  328    QList<CubePlotCurve *> foundCurves;
 
  330    const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  332    for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
 
  335      if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
 
  338        if (curve && curve->color().alpha() != 0)
 
  339          foundCurves.append(curve);
 
 
  354    QList<const CubePlotCurve *> foundCurves;
 
  356    const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  358    for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
 
  361      if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
 
  365          foundCurves.append(curve);
 
 
  381    QList<QwtPlotSpectrogram *> foundSpectrograms;
 
  383    const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  385    for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
 
  388      if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
 
  389        QwtPlotSpectrogram *spectrogram =
 
  390            dynamic_cast<QwtPlotSpectrogram *
>(item);
 
  393          foundSpectrograms.append(spectrogram);
 
  397    return foundSpectrograms;
 
 
  409    QList<const QwtPlotSpectrogram *> foundSpectrograms;
 
  411    const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  413    for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
 
  416      if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
 
  417        const QwtPlotSpectrogram *spectrogram =
 
  418            dynamic_cast<const QwtPlotSpectrogram *
>(item);
 
  421          foundSpectrograms.append(spectrogram);
 
  425    return foundSpectrograms;
 
 
  437      QMessageBox::warning(NULL, 
"Failed to add plot curve",
 
  438          "Can not add plot curves with x/y units that do not match the plot's " 
  442      QString curveTitle = pc->title().text();
 
  444      bool titleAccepted = 
false;
 
  445      int titleTryCount = 0;
 
  446      while (!titleAccepted) {
 
  447        if (titleTryCount > 0) {
 
  448          curveTitle = pc->title().text() + 
" (" +
 
  449              QString::number(titleTryCount + 1) + 
")";
 
  453        titleAccepted = 
true;
 
  455        const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  457        for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex ++) {
 
  460          if (item->title().text() == curveTitle)
 
  461            titleAccepted = 
false;
 
  465      pc->setTitle(curveTitle);
 
  472      connect(pc, SIGNAL(needsRepaint()),
 
  474      connect(pc, SIGNAL(destroyed(
QObject *)),
 
  479      pc->updateLegendItemWidget(legendWidget);
 
 
 
  511    if (curves.size() < 1) {
 
  516    configDialog->exec();
 
 
  540    const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  542    for (
int itemIndex = plotItems.size()- 1; itemIndex >= 0; itemIndex --) {
 
  545      if (item->rtti() == QwtPlotItem::Rtti_PlotCurve ||
 
  546          item->rtti() == QwtPlotItem::Rtti_PlotHistogram) {
 
 
  560    if (
m_zoomer->trackerMode() == QwtPicker::ActiveOnly) {
 
  561      m_zoomer->setTrackerMode(QwtPicker::AlwaysOn);
 
  564      m_zoomer->setTrackerMode(QwtPicker::ActiveOnly);
 
 
  575    static QPrinter *printer = NULL;
 
  576    if (printer == NULL) printer = 
new QPrinter;
 
  577    printer->setPageSize(QPrinter::Letter);
 
  578    printer->setColorMode(QPrinter::Color);
 
  580    QPrintDialog printDialog(printer, (
QWidget *)parent());
 
  582    if (printDialog.exec() == QDialog::Accepted) {
 
  585      QImage img = pixmap.toImage();
 
  587      QPainter painter(printer);
 
  588      QRect rect = painter.viewport();
 
  589      QSize size = img.size();
 
  590      size.scale(rect.size(), Qt::KeepAspectRatio);
 
  591      painter.setViewport(rect.x(), rect.y(),
 
  592                          size.width(), size.height());
 
  593      painter.setWindow(img.rect());
 
  594      painter.drawImage(0, 0, img);
 
 
  607    QFileDialog::getSaveFileName((
QWidget *)parent(),
 
  608                                 "Choose output file",
 
  610                                 QString(
"Images (*.png *.jpg *.tif)"));
 
  611    if (output.isEmpty()) 
return;
 
  613    if (!output.isEmpty()) {
 
  614      if (!output.endsWith(
".png") && !output.endsWith(
".jpg") && !output.endsWith(
".tif")) {
 
  615        output = output + 
".png";
 
  619    QString format = QFileInfo(output).suffix();
 
  622    std::string formatString = format.toStdString();
 
  623    if (!pixmap.save(output, formatString.c_str())) {
 
  624      QMessageBox::information((
QWidget *)parent(), 
"Error", 
"Unable to save " + output);
 
 
  635    QPen *pen = 
new QPen(Qt::white);
 
  637    if (
m_plot->canvasBackground() == Qt::white) {
 
  638      m_plot->setCanvasBackground(Qt::black);
 
  639      m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
 
  642      m_plot->setCanvasBackground(Qt::white);
 
  643      pen->setColor(Qt::black);
 
  644      m_grid->setMajorPen(QPen(Qt::black, 1, Qt::DotLine));
 
 
  664        m_plot->setAxisAutoScale(QwtPlot::xBottom);
 
  669        m_plot->setAxisScale(QwtPlot::xBottom, calculatedXRange.first,
 
  670                             calculatedXRange.second);
 
  674        m_plot->setAxisAutoScale(QwtPlot::yLeft);
 
  679        m_plot->setAxisScale(QwtPlot::yLeft, calculatedYRange.first,
 
  680                             calculatedYRange.second);
 
 
  695      m_plot->setAxisScaleEngine(QwtPlot::xBottom, 
new QwtLogScaleEngine);
 
  699      m_plot->setAxisScaleEngine(QwtPlot::xBottom, 
new QwtLinearScaleEngine);
 
  704      m_plot->setAxisScaleEngine(QwtPlot::yLeft, 
new QwtLogScaleEngine);
 
  708      m_plot->setAxisScaleEngine(QwtPlot::yLeft, 
new QwtLinearScaleEngine);
 
  721      m_plot->setAxisScale(QwtPlot::xBottom, xMin, xMax);
 
  729      m_plot->setAxisScale(QwtPlot::yLeft, yMin, yMax);
 
 
  744    dialog->setWindowTitle(
"Set Display Range");
 
  746    QGridLayout *dialogLayout = 
new QGridLayout;
 
  750    QLabel *autoLabel = 
new QLabel(
"Auto-Scale: ");
 
  751    dialogLayout->addWidget(autoLabel, row, 0);
 
  760    QLabel *xLabel = 
new QLabel(
"<h3>X-Axis</h3>");
 
  761    dialogLayout->addWidget(xLabel, row, 0, 1, 2);
 
  764    QLabel *xMinLabel = 
new QLabel(
"Minimum: ");
 
  765    dialogLayout->addWidget(xMinLabel, row, 0);
 
  767    double xMin = 
plot()->axisScaleDiv(QwtPlot::xBottom).lowerBound();
 
  768    m_xMinEdit = 
new QLineEdit(QString::number(xMin));
 
  772    QLabel *xMaxLabel = 
new QLabel(
"Maximum: ");
 
  773    dialogLayout->addWidget(xMaxLabel, row, 0);
 
  775    double xMax = 
plot()->axisScaleDiv(QwtPlot::xBottom).upperBound();
 
  776    m_xMaxEdit = 
new QLineEdit(QString::number(xMax));
 
  780    QLabel *xLogLabel = 
new QLabel(
"Logarithmic Scale");
 
  781    dialogLayout->addWidget(xLogLabel, row, 0);
 
  791    QLabel *yLabel = 
new QLabel(
"<h3>Y-Axis</h3>");
 
  792    dialogLayout->addWidget(yLabel, row, 0, 1, 2);
 
  795    QLabel *yMinLabel = 
new QLabel(
"Minimum: ");
 
  796    dialogLayout->addWidget(yMinLabel, row, 0);
 
  798    double yMin = 
plot()->axisScaleDiv(QwtPlot::yLeft).lowerBound();
 
  799    m_yMinEdit = 
new QLineEdit(QString::number(yMin));
 
  803    QLabel *yMaxLabel = 
new QLabel(
"Maximum: ");
 
  804    dialogLayout->addWidget(yMaxLabel, row, 0);
 
  806    double yMax = 
plot()->axisScaleDiv(QwtPlot::yLeft).upperBound();
 
  807    m_yMaxEdit = 
new QLineEdit(QString::number(yMax));
 
  811    QLabel *yLogLabel = 
new QLabel(
"Logarithmic Scale");
 
  812    dialogLayout->addWidget(yLogLabel, row, 0);
 
  822    QHBoxLayout *buttonsLayout = 
new QHBoxLayout;
 
  823    buttonsLayout->addStretch();
 
  825    QPushButton *okButton = 
new QPushButton(
"&Ok");
 
  826    okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
 
  827    connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
 
  828    connect(dialog, SIGNAL(accepted()), 
this, SLOT(
setUserValues()));
 
  829    okButton->setShortcut(Qt::Key_Enter);
 
  830    buttonsLayout->addWidget(okButton);
 
  832    QPushButton *cancelButton = 
new QPushButton(
"&Cancel");
 
  833    cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
 
  834    connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
 
  835    buttonsLayout->addWidget(cancelButton);
 
  838    buttonsWrapper->setLayout(buttonsLayout);
 
  839    dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
 
  844    dialog->setLayout(dialogLayout);
 
 
  855    dialog->setWindowTitle(
"Name Plot Labels");
 
  857    QGridLayout *dialogLayout = 
new QGridLayout;
 
  860    QLabel *plotLabel = 
new QLabel(
"Plot Title: ");
 
  861    dialogLayout->addWidget(plotLabel, row, 0);
 
  867    QLabel *xAxisLabel = 
new QLabel(
"X-Axis Label: ");
 
  868    dialogLayout->addWidget(xAxisLabel, row, 0);
 
  874    QLabel *yAxisLabel = 
new QLabel(
"Y-Axis Label: ");
 
  875    dialogLayout->addWidget(yAxisLabel, row, 0);
 
  881    QHBoxLayout *buttonsLayout = 
new QHBoxLayout;
 
  882    buttonsLayout->addStretch();
 
  884    QPushButton *okButton = 
new QPushButton(
"&Ok");
 
  885    okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
 
  886    connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
 
  887    connect(dialog, SIGNAL(accepted()), 
this, SLOT(
setLabels()));
 
  888    okButton->setShortcut(Qt::Key_Enter);
 
  889    buttonsLayout->addWidget(okButton);
 
  891    QPushButton *cancelButton = 
new QPushButton(
"&Cancel");
 
  892    cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
 
  893    connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
 
  894    buttonsLayout->addWidget(cancelButton);
 
  897    buttonsWrapper->setLayout(buttonsLayout);
 
  898    dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
 
  901    dialog->setLayout(dialogLayout);
 
 
  925    if (
m_grid->isVisible()) {
 
 
  941      method = &QwtPlotItem::hide;
 
  947      method = &QwtPlotItem::show;
 
  952    for (
int i = 0; i < 
m_plot->itemList().size(); i ++) {
 
  954      if (plotItem->rtti() == QwtPlotItem::Rtti_PlotMarker)
 
  955        (plotItem->*method)();
 
 
  969      method = &QwtPlotItem::hide;
 
  973          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
 
  977      method = &QwtPlotItem::show;
 
  981          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_hideCurves.png").expanded()));
 
  984    for (
int i = 0; i < 
m_plot->itemList().size(); i ++) {
 
  986      if (plotItem->rtti() == QwtPlotItem::Rtti_PlotCurve)
 
  987        (plotItem->*method)();
 
 
 1000    d->setWindowTitle(
"Basic Help");
 
 1002    QLabel *zoomLabel = 
new QLabel(
"<U>Zoom Options:</U>");
 
 1003    QLabel *zoomIn = 
new 
 1004                     QLabel(
"  <b>Left click</b> on the mouse, drag, and release to select an area to zoom in on");
 
 1005    QLabel *zoomOut = 
new 
 1006                      QLabel(
"  <b>Middle click</b> on the mouse to zoom out one level");
 
 1007    QLabel *zoomReset = 
new 
 1008                        QLabel(
"  <b>Right click</b> on the mouse and select <I>Reset  Scale</I> to clear the zoom and return to the original plot");
 
 1010    QLabel *curveConfigLabel = 
new QLabel(
"<br><U>Curve Configuration:</U>");
 
 1011    QLabel *configDirections = 
new 
 1012                               QLabel(
"  <b>To configure the curve properties</b>  Right click on the legend and select <I>Configure</I> from <br>  the menu" 
 1013                                      " or click on the configure icon in the tool bar.");
 
 1014    QLabel *config = 
new QLabel();
 
 1015    config->setPixmap(QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_configure.png").expanded()));
 
 1017    QLabel *tableLabel = 
new QLabel(
"<br><U>Table Options:</U>");
 
 1018    QLabel *tableDirections = 
new 
 1019                              QLabel(
"  <b>To view the table</b> Click on the File menu and select <I>Show Table</I> or click on the table icon in the <br>   tool bar.");
 
 1020    QLabel *table = 
new QLabel();
 
 1021    table->setPixmap(QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_table.png").expanded()));
 
 1023    QVBoxLayout *layout = 
new QVBoxLayout();
 
 1024    layout->addWidget(zoomLabel);
 
 1025    layout->addWidget(zoomIn);
 
 1026    layout->addWidget(zoomOut);
 
 1027    layout->addWidget(zoomReset);
 
 1028    layout->addWidget(curveConfigLabel);
 
 1029    layout->addWidget(config);
 
 1030    layout->addWidget(configDirections);
 
 1031    layout->addWidget(tableLabel);
 
 1032    layout->addWidget(table);
 
 1033    layout->addWidget(tableDirections);
 
 1035    d->setLayout(layout);
 
 
 1048    QList<QMenu *> menu;
 
 1049    QList<QAction *> actions;
 
 1058      save->setText(
"&Save Plot As");
 
 1059      save->setIcon(QIcon::fromTheme(
"document-save-as"));
 
 1061          "<b>Function:</b>  Save the plot as a png, jpg, or tif file.";
 
 1062      save->setWhatsThis(text);
 
 1063      connect(save, SIGNAL(triggered()), 
this, SLOT(
savePlot()));
 
 1064      fileMenu->addAction(save);
 
 1065      actions.push_back(save);
 
 1070      prt->setText(
"&Print Plot");
 
 1071      prt->setIcon(QIcon::fromTheme(
"document-print"));
 
 1073          "<b>Function:</b>  Sends the plot image to the printer";
 
 1074      prt->setWhatsThis(text);
 
 1075      connect(prt, SIGNAL(triggered()), 
this, SLOT(
printPlot()));
 
 1076      fileMenu->addAction(prt);
 
 1077      actions.push_back(prt);
 
 1082      table->setText(
"Show Table");
 
 1084          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_table.png").expanded()));
 
 1086          "<b>Function:</b>  Activates the table which displays the data of the " 
 1088      table->setWhatsThis(text);
 
 1089      connect(table, SIGNAL(triggered()), 
this, SLOT(
showTable()));
 
 1090      fileMenu->addAction(table);
 
 1091      actions.push_back(table);
 
 1094    QAction *close = 
new QAction(QIcon::fromTheme(
"document-close"), 
"&Close",
 
 1096    connect(close, SIGNAL(triggered()), 
this, SLOT(close()));
 
 1097    fileMenu->addAction(close);
 
 1101      track->setText(
"Show Mouse &Tracking");
 
 1103          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/goto.png").expanded()));
 
 1104      track->setCheckable(
true);
 
 1106          "<b>Function:</b>  Displays the x,y coordinates as the cursor moves " 
 1107          "around on the plot.";
 
 1108      track->setWhatsThis(text);
 
 1109      connect(track, SIGNAL(triggered()), 
this, SLOT(
trackerEnabled()));
 
 1110      optionsMenu->addAction(track);
 
 1116      backgrdSwitch->setText(
"White/Black &Background");
 
 1117      backgrdSwitch->setIcon(
 
 1118          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_switchBackgrd.png").expanded()));
 
 1120          "<b>Function:</b>  Switch the background color between black and " 
 1122      backgrdSwitch->setWhatsThis(text);
 
 1123      connect(backgrdSwitch, SIGNAL(triggered()),
 
 1125      optionsMenu->addAction(backgrdSwitch);
 
 1126      actions.push_back(backgrdSwitch);
 
 1133          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_grid.png").expanded()));
 
 1135          "<b>Function:</b>  Display grid lines on the plot.";
 
 1144      changeLabels->setText(
"Rename Plot &Labels");
 
 1145      changeLabels->setIcon(
 
 1146          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_renameLabels.png").expanded()));
 
 1148          "<b>Function:</b>  Edit the plot title, x and y axis labels.";
 
 1149      changeLabels->setWhatsThis(text);
 
 1150      connect(changeLabels, SIGNAL(triggered()),
 
 1152      optionsMenu->addAction(changeLabels);
 
 1153      actions.push_back(changeLabels);
 
 1159      changeScale->setText(
"Set &Display Range");
 
 1160      changeScale->setIcon(
 
 1161          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_setScale.png").expanded()));
 
 1163          "<b>Function:</b>  Adjust the scale for the x and y axis on the " 
 1165      changeScale->setWhatsThis(text);
 
 1166      connect(changeScale, SIGNAL(triggered()), 
this, SLOT(
setDefaultRange()));
 
 1167      optionsMenu->addAction(changeScale);
 
 1168      actions.push_back(changeScale);
 
 1176          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
 
 1178          "<b>Function:</b>  Displays or hides all the curves currently " 
 1179                            "displayed on the plot.";
 
 1192          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_markers.png").expanded()));
 
 1193      QString text = 
"<b>Function:</b>  Displays or hides a symbol for each " 
 1194                     "data point plotted on a plot.";
 
 1204      resetScaleButton->setText(
"Reset Scale");
 
 1205      resetScaleButton->setIcon(
 
 1206          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_resetscale.png").expanded()));
 
 1208          "<b>Function:</b>  Reset the plot's scale.";
 
 1209      resetScaleButton->setWhatsThis(text);
 
 1210      connect(resetScaleButton, SIGNAL(triggered()), 
this, SLOT(
resetScale()));
 
 1211      actions.push_back(resetScaleButton);
 
 1216      clear->setText(
"Clear Plot");
 
 1218          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_clear.png").expanded()));
 
 1220          "<b>Function:</b>  Removes all the curves from the plot.";
 
 1221      clear->setWhatsThis(text);
 
 1222      connect(clear, SIGNAL(triggered()), 
this, SLOT(
clearPlot()));
 
 1223      actions.push_back(clear);
 
 1228      lineFit->setText(
"Create Best Fit Line");
 
 1230          QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/linefit.png").expanded()));
 
 1231      QString text = 
"<b>Function:</b>  Calculates a best fit line from an " 
 1233      lineFit->setWhatsThis(text);
 
 1235      optionsMenu->addAction(lineFit);
 
 1236      actions.push_back(lineFit);
 
 1241      configurePlot->setText(
"Configure Plot");
 
 1242      configurePlot->setIcon(
 
 1243          QPixmap( 
FileName(
"$ISISROOT/appdata/images/icons/plot_configure.png").expanded() ) );
 
 1244      QString text = 
"<b>Function:</b> Change the name, color, style, and vertex symbol of the " 
 1246      configurePlot->setWhatsThis(text);
 
 1247      connect( configurePlot, SIGNAL( triggered() ),
 
 1249      optionsMenu->addAction(configurePlot);
 
 1250      actions.push_back(configurePlot);
 
 1254    basicHelp->setText(
"Basic Help");
 
 1255    QString text = 
"<b>Function:</b> Provides a basic overview on using components " 
 1256                   "of the qview plot window";
 
 1257    basicHelp->setWhatsThis(text);
 
 1258    connect( basicHelp, SIGNAL( triggered() ),
 
 1260    helpMenu->addAction(basicHelp);
 
 1266    m_pasteAct->setShortcut(Qt::CTRL | Qt::Key_V);
 
 1271    menu.push_back(fileMenu);
 
 1272    menu.push_back(editMenu);
 
 1274    if (optionsMenu->actions().size()) {
 
 1275      menu.push_back(optionsMenu);
 
 1282   if (helpMenu->actions().size()) {
 
 1283      menu.push_back(helpMenu);
 
 
 1306    bool userCanAdd = 
false;
 
 1309        curve->hasFormat(
"application/isis3-plot-curve")) {
 
 1312          curve->data(
"application/isis3-plot-curve"));
 
 1314      userCanAdd = 
canAdd(testCurve);
 
 
 1339        curve->setMarkerVisible(
true);
 
 1342        curve->setMarkerVisible(
false);
 
 
 1361      m_toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea);
 
 1362      addToolBar(Qt::TopToolBarArea, 
m_toolBar);
 
 1371    for (
int i = 0; i < menu.size(); i++) {
 
 1375    for (
int i = 0; i < actions.size(); i++) {
 
 
 1399    if (!m_scheduledFillTable) {
 
 1400      m_scheduledFillTable = 
true;
 
 1401      emit requestFillTable();
 
 
 1411    m_scheduledFillTable = 
false;
 
 1420                              m_plot->axisTitle(QwtPlot::xBottom).text(),
 
 1421                              m_plot->axisTitle(QwtPlot::xBottom).text());
 
 1423    QList<CubePlotCurve *> curves = 
plotCurves();
 
 1426                                curve->title().text(),
 
 1427                                curve->title().text());
 
 1442    QList<QString> xAxisPoints;
 
 1444    QProgressDialog progress(tr(
"Re-calculating Table"), tr(
""), 0, 1000, 
this);
 
 1445    double percentPerCurve = 0.5 * 1.0 / curves.count();
 
 1447    for (
int curveIndex = 0; curveIndex < curves.count(); curveIndex++) {
 
 1448      progress.setValue(qRound(curveIndex * percentPerCurve * 1000.0));
 
 1452      double percentPerDataIndex = (1.0 / curve->data()->size()) * percentPerCurve;
 
 1456      for (
int dataIndex = (
int)curve->data()->size() - 1;
 
 1459        double xValue = curve->data()->sample(dataIndex).x();
 
 1460        QString xValueString = 
toString(xValue);
 
 1462        int inverseDataIndex = (curve->data()->size() - 1) - dataIndex;
 
 1464            qRound( ((curveIndex * percentPerCurve) +
 
 1465                     (inverseDataIndex * percentPerDataIndex)) * 1000.0));
 
 1471            qBinaryFind(xAxisPoints.begin(), xAxisPoints.end(), xValueString);
 
 1473        if (foundPos == xAxisPoints.end()) {
 
 1474          bool inserted = 
false;
 
 1476          for (
int searchIndex = 0;
 
 1477             searchIndex < xAxisPoints.size() && !inserted;
 
 1479            if (xAxisPoints[searchIndex] > xValueString) {
 
 1481              xAxisPoints.insert(searchIndex, xValueString);
 
 1486            xAxisPoints.append(xValueString);
 
 1491    qSort(xAxisPoints.begin(), xAxisPoints.end(), &numericStringLessThan);
 
 1495    QList<int> lastSuccessfulSamples;
 
 1497    for (
int i = 0; i < curves.count(); i++) {
 
 1498      lastSuccessfulSamples.append(-1);
 
 1504      progress.setValue(500 + qRound(row * progressPerRow * 1000.0));
 
 1506      QString xValueString = xAxisPoints[row];
 
 1507      double xValue = 
toDouble(xValueString);
 
 1509      QTableWidgetItem *xAxisItem = 
new QTableWidgetItem(xValueString);
 
 1521        bool tooFar = 
false;
 
 1523        for (
int dataIndex = lastSuccessfulSamples[col - 1] + 1;
 
 1524             dataIndex < (int)curve->data()->size() && y == 
Null && !tooFar;
 
 1527          if (
toString(curve->data()->sample(dataIndex).x()) == xValueString) {
 
 1529            if (dataIndex > 0 &&
 
 1530                curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x()) {
 
 1531              lastSuccessfulSamples[col - 1] = dataIndex;
 
 1533            y = curve->data()->sample(dataIndex).y();
 
 1536          else if (dataIndex > 0 &&
 
 1537              curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x() &&
 
 1538              curve->data()->sample(dataIndex).x() > xValue) {
 
 1543        QTableWidgetItem *item = NULL;
 
 1546          item = 
new QTableWidgetItem(QString(
"N/A"));
 
 1548          item = 
new QTableWidgetItem(
toString(y));
 
 
 1590    bool blockWidgetFromEvent = 
false;
 
 1592    switch (e->type()) {
 
 1593      case QEvent::MouseButtonPress:
 
 1595            childAt(((QMouseEvent *)e)->pos()) != 
plot()->canvas()) {
 
 1597          blockWidgetFromEvent = 
true;
 
 1605    bool stopHandlingEvent = 
false;
 
 1606    if (!blockWidgetFromEvent && o == 
this) {
 
 1607      stopHandlingEvent = MainWindow::eventFilter(o, e);
 
 1609      if (e->type() == QEvent::Close && !stopHandlingEvent) {
 
 1614    return stopHandlingEvent || blockWidgetFromEvent;
 
 
 1628    if (qobject_cast<QWidget *>(
object) &&
 
 1629        event->button() == Qt::RightButton &&
 
 1633      QAction *pasteAct = 
new QAction(QIcon::fromTheme(
"edit-paste"), 
"Paste",
 
 1635      contextMenu.addAction(pasteAct);
 
 1637      QAction *chosenAct = contextMenu.exec(
 
 1638          qobject_cast<QWidget *>(
object)->mapToGlobal(event->pos()));
 
 1640      if (chosenAct == pasteAct) {
 
 
 1698      QClipboard *globalClipboard = QApplication::clipboard();
 
 1699      const QMimeData *globalData = globalClipboard->mimeData();
 
 1701      if (globalData->hasFormat(
"application/isis3-plot-curve")) {
 
 1703                globalData->data(
"application/isis3-plot-curve"));
 
 
 1722    QList<const CubePlotCurve *> curves = 
plotCurves();
 
 1724    bool foundDataValue = 
false;
 
 1725    QPair<double, double> rangeMinMax;
 
 1728      for (
int dataIndex = 0; dataIndex < (int)curve->dataSize(); dataIndex++) {
 
 1729        if (axisId == QwtPlot::xBottom) {
 
 1730          if (!foundDataValue) {
 
 1731            rangeMinMax.first = curve->sample(dataIndex).x();
 
 1732            rangeMinMax.second = curve->sample(dataIndex).x();
 
 1733            foundDataValue = 
true;
 
 1736            rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).x());
 
 1737            rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).x());
 
 1740        else if (axisId == QwtPlot::yLeft) {
 
 1741          if (!foundDataValue) {
 
 1742            rangeMinMax.first = curve->sample(dataIndex).y();
 
 1743            rangeMinMax.second = curve->sample(dataIndex).y();
 
 1744            foundDataValue = 
true;
 
 1747            rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).y());
 
 1748            rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).y());
 
 1754    if (!foundDataValue) {
 
 1755      rangeMinMax.first = 1;
 
 1756      rangeMinMax.second = 10;
 
 1758    else if(rangeMinMax.first == rangeMinMax.second) {
 
 1759      rangeMinMax.first -= 0.5;
 
 1760      rangeMinMax.second += 0.5;
 
 
 1767  bool PlotWindow::numericStringLessThan(QString left, QString right) {
 
 1768    bool result = 
false;
 
 1773    catch (IException &) {
 
 1788      curve->paint(vp, painter);
 
 
 1823    QObject *source = 
event->source();
 
 1825    if (source != 
m_legend->contentsWidget() &&
 
 1827      event->acceptProposedAction();
 
 
 1845        event->mimeData()->hasFormat(
"application/isis3-plot-curve")) {
 
 1846      Qt::DropActions possibleActions = 
event->possibleActions();
 
 1847      Qt::DropAction actionToTake = 
event->proposedAction();
 
 1850      boldFont.setBold(
true);
 
 1851      QMenu dropActionsMenu;
 
 1854      if (possibleActions.testFlag(Qt::CopyAction)) {
 
 1855        dropActionsMenu.addAction(copyAct);
 
 1857        if (actionToTake == Qt::CopyAction)
 
 1858          copyAct->setFont(boldFont);
 
 1862      if (possibleActions.testFlag(Qt::MoveAction)) {
 
 1863        dropActionsMenu.addAction(moveAct);
 
 1865        if (actionToTake == Qt::MoveAction)
 
 1866          moveAct->setFont(boldFont);
 
 1869      if (dropActionsMenu.actions().size() > 1) {
 
 1870        dropActionsMenu.addSeparator();
 
 1873        dropActionsMenu.addAction(cancelAct);
 
 1875        QAction *chosenAct = dropActionsMenu.exec(mapToGlobal(event->pos()));
 
 1877        if (chosenAct == copyAct) {
 
 1878          actionToTake = Qt::CopyAction;
 
 1880        else if (chosenAct == moveAct) {
 
 1881          actionToTake = Qt::MoveAction;
 
 1884          actionToTake = Qt::IgnoreAction;
 
 1888      if (actionToTake != Qt::IgnoreAction) {
 
 1890                event->mimeData()->data(
"application/isis3-plot-curve"));
 
 1895        event->setDropAction(actionToTake);
 
 
This is a plot curve with information relating it to a particular cube or region of a cube.
 
File name manipulation and expansion.
 
@ Programmer
This error is for when a programmer made an API call that was illegal.
 
Adds specific functionality to C++ strings.
 
Base class for the Qisis main windows.
 
virtual void readSettings(QSize defaultSize=QSize())
This method ensure that the settings get written even if the Main window was only hidden,...
 
Cube display widget for certain Isis MDI applications.
 
Units
These are all the possible units for the x or y data in a plot curve.
 
@ Elevation
The data is an elevation (in meters).
 
@ Band
The data is a band number.
 
@ CubeDN
The data is a Cube DN value.
 
@ Wavelength
The data is a wavelength.
 
@ Kilometers
The data is in kilometers.
 
@ PixelNumber
The data is a pixel #.
 
@ Meters
The data is in meters.
 
@ Percentage
The data is a percentage (0-100).
 
QLineEdit * m_plotTitleText
Set Labels Dialog's edit for the plot title.
 
QList< CubePlotCurve * > plotCurves()
Get a comprehensive list of the plot curves inside of this plot window, excluding plot curves that ar...
 
QPointer< QAction > m_showHideAllCurves
Hide all curves action.
 
QwtPlot * m_plot
The plot in this window.
 
void createWidgets(MenuOptions optionsToProvide)
This method is called by the constructor to create the plot, legend.
 
void closed()
Emitted when there is a close event on this window that will be accepted.
 
void setAxisLabel(int axisId, QString title)
Sets the plots given axis title to the given string.
 
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
 
virtual void dragEnterEvent(QDragEnterEvent *event)
When a user drags data into our plot window, we need to indicate whether or not this data is compatib...
 
QLineEdit * m_xMinEdit
Set Scale Dialog's edit for the min X-axis value.
 
void autoScaleCheckboxToggled()
This is a helper method for the set scale configuration dialog.
 
void showHideAllMarkers()
Shows/Hides all the markers(symbols)
 
bool m_plotXLogScale
Tracks if the plot X axis is using a log (true) or linear (false) scale.
 
void plotChanged()
Emitted every time there is a change to the plot window.
 
QMenuBar * m_menubar
Plot window's menu bar.
 
QLineEdit * m_xMaxEdit
Set Scale Dialog's edit for the max X-axis value.
 
QLineEdit * m_yMinEdit
Set Scale Dialog's edit for the min Y-axis value.
 
bool m_allowUserToAddCurves
Is the window showing the curve markers?
 
QString plotTitle() const
Returns the plot title.
 
QLineEdit * m_xAxisText
Set Labels Dialog's edit for the x-axis label.
 
void showHideAllCurves()
This method shows or hides all of the curves in the plotWindow.
 
QPointer< QAction > m_showHideGrid
Show plot grid lines action.
 
void printPlot()
Provides printing support of the plot image.
 
QwtPlotZoomer * m_zoomer
Plot Zoomer.
 
void setPlotBackground(QColor c)
Sets the plot background color to the given color.
 
MenuOptions
There is a menu option for everything in the plot window's menu.
 
@ LineFitMenuOption
This option allows the user to create a best fit line for any of the scatter plot data or cube plot c...
 
@ PrintMenuOption
This option sends the plot to a printer.
 
@ ResetScaleMenuOption
This option provides the user with an alternative zoom out button.
 
@ ShowHideMarkersMenuOption
This option is titled 'Hide All Symbols' which hides all markers.
 
@ ConfigurePlotMenuOption
This option allows the user to change the curve name, color, style size, and symbol of the curve.
 
@ SaveMenuOption
This option exports the plot into a standard image format.
 
@ ShowHideGridMenuOption
This option enables the ability for a user to enable a grid over the plot area.
 
@ ShowTableMenuOption
This option brings up the table.
 
@ ClearPlotMenuOption
This option allows the user to delete all of the data inside the plot.
 
@ RenameLabelsMenuOption
This option enables the ability for a user to change the x/y axis labels and plot title.
 
@ TrackMenuOption
This option enables mouse tracking on the plot area (displays next to the mouse which x/y point you a...
 
@ ShowHideCurvesMenuOption
This option is titled 'Hide All Curves' which makes all curves invisible.
 
@ BackgroundSwitchMenuOption
This option enables the ability for a user to change the background color of the plot from black to w...
 
@ SetDisplayRangeMenuOption
This option allows the user to set the x/y axis display value ranges.
 
QLineEdit * m_yMaxEdit
Set Scale Dialog's edit for the max Y-axis value.
 
void pasteCurve()
When the user pastes a curve try to put it into this plot window.
 
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
 
void showWindow()
Shows the plot window, and raises it to the front of any overlapping sibling widgets.
 
QCheckBox * m_yLogCheckBox
Set Scale Dialog's checkbox for using logarithmic scale for the y axis.
 
void resetScale()
Sets plot scale back to the defaults.
 
QPointer< QAction > m_showHideAllMarkers
Hide all markers action.
 
void createBestFitLine()
This method prompts the user to select the best fit line criterea.
 
QAction * m_pasteAct
This is the paste action in the edit menu to paste a curve into the plot window.
 
bool userCanAddCurve(const QMimeData *curve)
Ask if a user action can add this curve to this window.
 
void setupDefaultMenu(MenuOptions optionsToProvide)
The user can add menu items from parent classes, but there are some menu items that are common betwee...
 
QColor plotBackgroundColor() const
Returns the plot's background color.
 
QLineEdit * m_yAxisText
Set Labels Dialog's edit for the y-axis label.
 
TableMainWindow * m_tableWindow
Table window.
 
virtual void dropEvent(QDropEvent *event)
This is called when a user drops data into our window.
 
void onClipboardChanged()
This slot will be called when the system clipboard is changed.
 
void replot()
Reset the scale of the plot, replot it and emit plot changed.
 
QPair< double, double > findDataRange(int axisId) const
This calculates the data range of the specified axis (works with xBottom and yLeft only).
 
void trackerEnabled()
Enables the plot mouse tracker.
 
void updateVisibility(PlotCurve *curve)
This method sets the visibility states in the curve (and it's symbols) to match with this window's cu...
 
PlotCurve::Units xAxisUnits() const
This is the data-type of the curves' x data in this plot window.
 
void setPlotTitle(QString pt)
Sets the plot title to the given string.
 
QwtLegend * m_legend
The legend inserted in this plot.
 
void setUserCanAddCurves(bool)
Allow or disallow users from manually putting curves into this plot window through either copy-and-pa...
 
virtual bool eventFilter(QObject *o, QEvent *e)
This method filters the events of the objects it is connected to.
 
bool m_autoscaleAxes
True if we are autoscaling the x-bottom and y-left axes.
 
void changePlotLabels()
This method creates the dialog box which allows the user to relabel the plot window.
 
QWidget * m_parent
Parent widget.
 
void setUserValues()
This method sets the scale for the axis according to the user specified numbers.
 
virtual void update(MdiCubeViewport *activeViewport)
This is provided to allow children to react to tool updates.
 
void showHideGrid()
This method hides/shows the grid on the plotWindow and changes the text for the action.
 
void configurePlotCurves()
This method creates a CubePlotCurveConfigureDialog object.
 
PlotCurve::Units m_xAxisUnits
The units of the data on the x-bottom axis.
 
QCheckBox * m_autoScaleCheckBox
Set Scale Dialog's checkbox for enabling automatic scaling on x & y.
 
bool canAdd(CubePlotCurve *curveToTest) const
This method tests whethere or not a CubePlotCurve can be successfully added to this window.
 
void fillTable()
Fills in the table with the data from the current curves in the plotWindow immediately.
 
QToolBar * m_toolBar
Tool bar on the plot window.
 
QwtPlotGrid * m_grid
Plot grid lines.
 
void savePlot()
This method allows the user to save the plot as a png, jpg, or tif image file.
 
PlotCurve::Units m_yAxisUnits
The units of the data on the y-left axis.
 
void showHelp()
This method creates and shows the help dialog box for the plot window.
 
void showTable()
This method is called from the showTable action on the tool bar There are some checks done to make su...
 
void setDefaultRange()
Resets the x/y min/max to the defaults.
 
virtual void paint(MdiCubeViewport *vp, QPainter *painter)
Paint plot curve information onto the viewport.
 
PlotCurve::Units yAxisUnits() const
This is the data-type of the curves' y data in this plot window.
 
void clearPlot()
This method completely clears the plot of all plot items.
 
bool userCanAddCurves() const
Ask if a user action can add this curve to this window in general.
 
virtual void clearPlotCurves()
This method also clears the plot of all plot items, but does not call the table delete stuff This met...
 
void setLabels()
Makes the user specified changes to the plot labels.
 
QCheckBox * m_xLogCheckBox
Set Scale Dialog's checkbox for using logarithmic scale for the x axis.
 
void switchBackground()
This method toggles the plot background color between black and white.
 
void mousePressEvent(QObject *object, QMouseEvent *e)
This is a helper method for the eventFilter() method.
 
void scheduleFillTable()
Fills in the table with the data from the current curves in the plotWindow once all current actions/a...
 
void disableAxisAutoScale()
This turns off scaling the x/y axes automatically.
 
PlotWindow(QString title, PlotCurve::Units xAxisUnits, PlotCurve::Units yAxisUnits, QWidget *parent, MenuOptions optionsToProvide=AllMenuOptions)
This constructs a plot window.
 
QwtPlot * plot()
Get the plot encapsulated by this PlotWindow.
 
QList< QwtPlotSpectrogram * > plotSpectrograms()
Get a comprehensive list of the scatter plots (spectrograms) inside of this plot window.
 
QwtPlotZoomer * zoomer()
Get this window's plot's zoomer.
 
void setMenus(QList< QMenu * > menus, QList< QAction * > actions)
Sets up the menus added from a parent object.
 
bool m_plotYLogScale
Tracks if the plot Y axis is using a log (true) or linear (false) scale.
 
a subclass of the qisis mainwindow, tablemainwindow handles all of the table tasks.
 
QTableWidget * table() const
Returns the table.
 
void addToTable(bool setOn, const QString &heading, const QString &menuText="", int insertAt=-1, Qt::Orientation o=Qt::Horizontal, QString toolTip="")
Adds a new column to the table when a new curve is added to the plot.
 
void syncColumns()
This method hides and shows the columns according to which items the user has selected to be view-abl...
 
void setTrackListItems(bool track=false)
If this property is true, the class will keep track of the checked/unchecked items in the dock area w...
 
QListWidget * listWidget() const
Returns the list widget.
 
This is free and unencumbered software released into the public domain.
 
This is free and unencumbered software released into the public domain.
 
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
 
const double Null
Value for an Isis Null pixel.
 
bool IsSpecial(const double d)
Returns if the input pixel is special.
 
double toDouble(const QString &string)
Global function to convert from a string to a double.
 
Namespace for the standard library.