8 #include <qwt_legend.h> 
    9 #include <qwt_plot_grid.h> 
   10 #include <qwt_plot_spectrogram.h> 
   11 #include <qwt_symbol.h> 
   12 #include <qwt_scale_engine.h> 
   15 #include <QApplication> 
   17 #include <QFileDialog> 
   18 #include <QGridLayout> 
   24 #include <QMessageBox> 
   26 #include <QPrintDialog> 
   27 #include <QProgressDialog> 
   28 #include <QPushButton> 
   30 #include <QTableWidget> 
   35 #include "CubePlotCurveConfigureDialog.h"  
   39 #include "MainWindow.h" 
   41 #include "PlotWindowBestFitDialog.h" 
   47 #include "TableMainWindow.h" 
   78     setObjectName(
"Plot Window: " + title);
 
   85       IString msg = 
"PlotWindow cannot be instantiated with a NULL parent";
 
   89     installEventFilter(
this);
 
   93     setWindowTitle(title);
 
   97     connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)),
 
  101     connect(
this, SIGNAL(requestFillTable()),
 
  102             this, SLOT(
fillTable()), Qt::QueuedConnection);
 
  114     plot()->setAxisTitle(QwtPlot::xBottom, unitLabels[xAxisUnits]);
 
  115     plot()->setAxisTitle(QwtPlot::yLeft,   unitLabels[yAxisUnits]);
 
  123     setWindowFlags(Qt::Tool);
 
  125     setWindowFlags(Qt::Dialog);
 
  131   PlotWindow::~PlotWindow() {
 
  148     m_plot->installEventFilter(
this);
 
  149     m_plot->setAxisMaxMinor(QwtPlot::yLeft, 5);
 
  150     m_plot->setAxisMaxMajor(QwtPlot::xBottom, 30);
 
  151     m_plot->setAxisMaxMinor(QwtPlot::xBottom, 5);
 
  152     m_plot->setAxisLabelRotation(QwtPlot::xBottom, 45);
 
  153     m_plot->setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignRight);
 
  157     m_legend->setDefaultItemMode(QwtLegendData::Clickable);
 
  158     m_legend->setWhatsThis(
"Right Click on a legend item to display the context " 
  166     m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
 
  167     m_grid->setMinorPen(QPen(Qt::gray, 1, Qt::DotLine));
 
  169     m_grid->setVisible(
false);
 
  173     m_zoomer->setRubberBandPen(QPen(Qt::lightGray));
 
  174     m_zoomer->setTrackerPen(QPen(Qt::lightGray));
 
  209     m_plot->setAxisTitle(axisId, title);
 
  242     return m_plot->title().text();
 
  290     m_plot->setCanvasBackground(c);
 
  318     return m_plot->canvasBackground().color();
 
  331     const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  333     for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {  
 
  336       if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
 
  339         if (curve && curve->
color().alpha() != 0)
 
  340           foundCurves.append(curve);
 
  357     const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  359     for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
 
  362       if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
 
  366           foundCurves.append(curve);
 
  384     const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  386     for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {  
 
  389       if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
 
  390         QwtPlotSpectrogram *spectrogram =
 
  391             dynamic_cast<QwtPlotSpectrogram *
>(item);
 
  394           foundSpectrograms.append(spectrogram);
 
  398     return foundSpectrograms;
 
  412     const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  414     for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {  
 
  417       if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
 
  418         const QwtPlotSpectrogram *spectrogram =
 
  419             dynamic_cast<const QwtPlotSpectrogram *
>(item);
 
  422           foundSpectrograms.append(spectrogram);
 
  426     return foundSpectrograms;
 
  438       QMessageBox::warning(NULL, 
"Failed to add plot curve",
 
  439           "Can not add plot curves with x/y units that do not match the plot's " 
  443       QString curveTitle = pc->title().text();
 
  445       bool titleAccepted = 
false;
 
  446       int titleTryCount = 0;
 
  447       while (!titleAccepted) {
 
  448         if (titleTryCount > 0) {
 
  449           curveTitle = pc->title().text() + 
" (" +
 
  450               QString::number(titleTryCount + 1) + 
")";
 
  454         titleAccepted = 
true;
 
  456         const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  458         for (
int itemIndex = 0; itemIndex < plotItems.size(); itemIndex ++) {
 
  461           if (item->title().text() == curveTitle)
 
  462             titleAccepted = 
false;
 
  466       pc->setTitle(curveTitle);
 
  473       connect(pc, SIGNAL(needsRepaint()),
 
  475       connect(pc, SIGNAL(destroyed(
QObject *)),
 
  512     if (curves.size() < 1) {
 
  517     configDialog->exec();
 
  541     const QwtPlotItemList &plotItems = 
m_plot->itemList();
 
  543     for (
int itemIndex = plotItems.size()- 1; itemIndex >= 0; itemIndex --) {
 
  546       if (item->rtti() == QwtPlotItem::Rtti_PlotCurve ||
 
  547           item->rtti() == QwtPlotItem::Rtti_PlotHistogram) {
 
  561     if (
m_zoomer->trackerMode() == QwtPicker::ActiveOnly) {
 
  562       m_zoomer->setTrackerMode(QwtPicker::AlwaysOn);
 
  565       m_zoomer->setTrackerMode(QwtPicker::ActiveOnly);
 
  576     static QPrinter *printer = NULL;
 
  577     if (printer == NULL) printer = 
new QPrinter;
 
  578     printer->setPageSize(QPrinter::Letter);
 
  579     printer->setColorMode(QPrinter::Color);
 
  581     QPrintDialog printDialog(printer, (
QWidget *)parent());
 
  583     if (printDialog.exec() == QDialog::Accepted) {
 
  586       QImage img = pixmap.toImage();
 
  588       QPainter painter(printer);
 
  589       QRect rect = painter.viewport();
 
  590       QSize size = img.size();
 
  591       size.scale(rect.size(), Qt::KeepAspectRatio);
 
  592       painter.setViewport(rect.x(), rect.y(),
 
  593                           size.width(), size.height());
 
  594       painter.setWindow(img.rect());
 
  595       painter.drawImage(0, 0, img);
 
  608     QFileDialog::getSaveFileName((
QWidget *)parent(),
 
  609                                  "Choose output file",
 
  611                                  QString(
"Images (*.png *.jpg *.tif)"));
 
  612     if (output.isEmpty()) 
return;
 
  614     if (!output.isEmpty()) {
 
  615       if (!output.endsWith(
".png") && !output.endsWith(
".jpg") && !output.endsWith(
".tif")) {
 
  616         output = output + 
".png";
 
  620     QString format = QFileInfo(output).suffix();
 
  623     std::string formatString = format.toStdString();
 
  624     if (!pixmap.save(output, formatString.c_str())) {
 
  625       QMessageBox::information((
QWidget *)parent(), 
"Error", 
"Unable to save " + output);
 
  636     QPen *pen = 
new QPen(Qt::white);
 
  638     if (
m_plot->canvasBackground() == Qt::white) {
 
  639       m_plot->setCanvasBackground(Qt::black);
 
  640       m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
 
  643       m_plot->setCanvasBackground(Qt::white);
 
  644       pen->setColor(Qt::black);
 
  645       m_grid->setMajorPen(QPen(Qt::black, 1, Qt::DotLine));
 
  665         m_plot->setAxisAutoScale(QwtPlot::xBottom);
 
  670         m_plot->setAxisScale(QwtPlot::xBottom, calculatedXRange.first,
 
  671                              calculatedXRange.second);
 
  675         m_plot->setAxisAutoScale(QwtPlot::yLeft);
 
  680         m_plot->setAxisScale(QwtPlot::yLeft, calculatedYRange.first,
 
  681                              calculatedYRange.second);
 
  696       m_plot->setAxisScaleEngine(QwtPlot::xBottom, 
new QwtLogScaleEngine);
 
  700       m_plot->setAxisScaleEngine(QwtPlot::xBottom, 
new QwtLinearScaleEngine);
 
  705       m_plot->setAxisScaleEngine(QwtPlot::yLeft, 
new QwtLogScaleEngine);
 
  709       m_plot->setAxisScaleEngine(QwtPlot::yLeft, 
new QwtLinearScaleEngine);
 
  722       m_plot->setAxisScale(QwtPlot::xBottom, xMin, xMax);
 
  730       m_plot->setAxisScale(QwtPlot::yLeft, yMin, yMax);
 
  745     dialog->setWindowTitle(
"Set Display Range");
 
  747     QGridLayout *dialogLayout = 
new QGridLayout;
 
  751     QLabel *autoLabel = 
new QLabel(
"Auto-Scale: ");
 
  752     dialogLayout->addWidget(autoLabel, row, 0);
 
  761     QLabel *xLabel = 
new QLabel(
"<h3>X-Axis</h3>");
 
  762     dialogLayout->addWidget(xLabel, row, 0, 1, 2);
 
  765     QLabel *xMinLabel = 
new QLabel(
"Minimum: ");
 
  766     dialogLayout->addWidget(xMinLabel, row, 0);
 
  768     double xMin = 
plot()->axisScaleDiv(QwtPlot::xBottom).lowerBound();
 
  769     m_xMinEdit = 
new QLineEdit(QString::number(xMin));
 
  773     QLabel *xMaxLabel = 
new QLabel(
"Maximum: ");
 
  774     dialogLayout->addWidget(xMaxLabel, row, 0);
 
  776     double xMax = 
plot()->axisScaleDiv(QwtPlot::xBottom).upperBound();
 
  777     m_xMaxEdit = 
new QLineEdit(QString::number(xMax));
 
  781     QLabel *xLogLabel = 
new QLabel(
"Logarithmic Scale");
 
  782     dialogLayout->addWidget(xLogLabel, row, 0);
 
  792     QLabel *yLabel = 
new QLabel(
"<h3>Y-Axis</h3>");
 
  793     dialogLayout->addWidget(yLabel, row, 0, 1, 2);
 
  796     QLabel *yMinLabel = 
new QLabel(
"Minimum: ");
 
  797     dialogLayout->addWidget(yMinLabel, row, 0);
 
  799     double yMin = 
plot()->axisScaleDiv(QwtPlot::yLeft).lowerBound();
 
  800     m_yMinEdit = 
new QLineEdit(QString::number(yMin));
 
  804     QLabel *yMaxLabel = 
new QLabel(
"Maximum: ");
 
  805     dialogLayout->addWidget(yMaxLabel, row, 0);
 
  807     double yMax = 
plot()->axisScaleDiv(QwtPlot::yLeft).upperBound();
 
  808     m_yMaxEdit = 
new QLineEdit(QString::number(yMax));
 
  812     QLabel *yLogLabel = 
new QLabel(
"Logarithmic Scale");
 
  813     dialogLayout->addWidget(yLogLabel, row, 0);
 
  823     QHBoxLayout *buttonsLayout = 
new QHBoxLayout;
 
  824     buttonsLayout->addStretch();
 
  826     QPushButton *okButton = 
new QPushButton(
"&Ok");
 
  827     okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
 
  828     connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
 
  829     connect(dialog, SIGNAL(accepted()), 
this, SLOT(
setUserValues()));
 
  830     okButton->setShortcut(Qt::Key_Enter);
 
  831     buttonsLayout->addWidget(okButton);
 
  833     QPushButton *cancelButton = 
new QPushButton(
"&Cancel");
 
  834     cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
 
  835     connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
 
  836     buttonsLayout->addWidget(cancelButton);
 
  839     buttonsWrapper->setLayout(buttonsLayout);
 
  840     dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
 
  845     dialog->setLayout(dialogLayout);
 
  856     dialog->setWindowTitle(
"Name Plot Labels");
 
  858     QGridLayout *dialogLayout = 
new QGridLayout;
 
  861     QLabel *plotLabel = 
new QLabel(
"Plot Title: ");
 
  862     dialogLayout->addWidget(plotLabel, row, 0);
 
  868     QLabel *xAxisLabel = 
new QLabel(
"X-Axis Label: ");
 
  869     dialogLayout->addWidget(xAxisLabel, row, 0);
 
  875     QLabel *yAxisLabel = 
new QLabel(
"Y-Axis Label: ");
 
  876     dialogLayout->addWidget(yAxisLabel, row, 0);
 
  882     QHBoxLayout *buttonsLayout = 
new QHBoxLayout;
 
  883     buttonsLayout->addStretch();
 
  885     QPushButton *okButton = 
new QPushButton(
"&Ok");
 
  886     okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
 
  887     connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
 
  888     connect(dialog, SIGNAL(accepted()), 
this, SLOT(
setLabels()));
 
  889     okButton->setShortcut(Qt::Key_Enter);
 
  890     buttonsLayout->addWidget(okButton);
 
  892     QPushButton *cancelButton = 
new QPushButton(
"&Cancel");
 
  893     cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
 
  894     connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
 
  895     buttonsLayout->addWidget(cancelButton);
 
  898     buttonsWrapper->setLayout(buttonsLayout);
 
  899     dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
 
  902     dialog->setLayout(dialogLayout);
 
  926     if (
m_grid->isVisible()) {
 
  942       method = &QwtPlotItem::hide;
 
  948       method = &QwtPlotItem::show;
 
  953     for (
int i = 0; i < 
m_plot->itemList().size(); i ++) {
 
  955       if (plotItem->rtti() == QwtPlotItem::Rtti_PlotMarker)
 
  956         (plotItem->*method)();
 
  970       method = &QwtPlotItem::hide;
 
  974           QPixmap(
FileName(
"$base/icons/plot_showCurves.png").expanded()));
 
  978       method = &QwtPlotItem::show;
 
  982           QPixmap(
FileName(
"$base/icons/plot_hideCurves.png").expanded()));
 
  985     for (
int i = 0; i < 
m_plot->itemList().size(); i ++) {
 
  987       if (plotItem->rtti() == QwtPlotItem::Rtti_PlotCurve)
 
  988         (plotItem->*method)();
 
 1001     d->setWindowTitle(
"Basic Help");
 
 1003     QLabel *zoomLabel = 
new QLabel(
"<U>Zoom Options:</U>");
 
 1004     QLabel *zoomIn = 
new 
 1005                      QLabel(
"  <b>Left click</b> on the mouse, drag, and release to select an area to zoom in on");
 
 1006     QLabel *zoomOut = 
new 
 1007                       QLabel(
"  <b>Middle click</b> on the mouse to zoom out one level");
 
 1008     QLabel *zoomReset = 
new 
 1009                         QLabel(
"  <b>Right click</b> on the mouse and select <I>Reset  Scale</I> to clear the zoom and return to the original plot");
 
 1011     QLabel *curveConfigLabel = 
new QLabel(
"<br><U>Curve Configuration:</U>");
 
 1012     QLabel *configDirections = 
new 
 1013                                QLabel(
"  <b>To configure the curve properties</b>  Right click on the legend and select <I>Configure</I> from <br>  the menu" 
 1014                                       " or click on the configure icon in the tool bar.");
 
 1015     QLabel *config = 
new QLabel();
 
 1016     config->setPixmap(QPixmap(
FileName(
"$base/icons/plot_configure.png").expanded()));
 
 1018     QLabel *tableLabel = 
new QLabel(
"<br><U>Table Options:</U>");
 
 1019     QLabel *tableDirections = 
new 
 1020                               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.");
 
 1021     QLabel *table = 
new QLabel();
 
 1022     table->setPixmap(QPixmap(
FileName(
"$base/icons/plot_table.png").expanded()));
 
 1024     QVBoxLayout *layout = 
new QVBoxLayout();
 
 1025     layout->addWidget(zoomLabel);
 
 1026     layout->addWidget(zoomIn);
 
 1027     layout->addWidget(zoomOut);
 
 1028     layout->addWidget(zoomReset);
 
 1029     layout->addWidget(curveConfigLabel);
 
 1030     layout->addWidget(config);
 
 1031     layout->addWidget(configDirections);
 
 1032     layout->addWidget(tableLabel);
 
 1033     layout->addWidget(table);
 
 1034     layout->addWidget(tableDirections);
 
 1036     d->setLayout(layout);
 
 1052     QMenu *fileMenu = 
new QMenu(
"&File");
 
 1053     QMenu *editMenu = 
new QMenu(
"&Edit");
 
 1054     QMenu *optionsMenu = 
new QMenu(
"&Options");
 
 1059       save->setText(
"&Save Plot As");
 
 1060       save->setIcon(QIcon::fromTheme(
"document-save-as"));
 
 1062           "<b>Function:</b>  Save the plot as a png, jpg, or tif file.";
 
 1063       save->setWhatsThis(text);
 
 1064       connect(save, SIGNAL(triggered()), 
this, SLOT(
savePlot()));
 
 1065       fileMenu->addAction(save);
 
 1066       actions.push_back(save);
 
 1071       prt->setText(
"&Print Plot");
 
 1072       prt->setIcon(QIcon::fromTheme(
"document-print"));
 
 1074           "<b>Function:</b>  Sends the plot image to the printer";
 
 1075       prt->setWhatsThis(text);
 
 1076       connect(prt, SIGNAL(triggered()), 
this, SLOT(
printPlot()));
 
 1077       fileMenu->addAction(prt);
 
 1078       actions.push_back(prt);
 
 1083       table->setText(
"Show Table");
 
 1085           QPixmap(
FileName(
"$base/icons/plot_table.png").expanded()));
 
 1087           "<b>Function:</b>  Activates the table which displays the data of the " 
 1089       table->setWhatsThis(text);
 
 1090       connect(table, SIGNAL(triggered()), 
this, SLOT(
showTable()));
 
 1091       fileMenu->addAction(table);
 
 1092       actions.push_back(table);
 
 1095     QAction *close = 
new QAction(QIcon::fromTheme(
"document-close"), 
"&Close",
 
 1097     connect(close, SIGNAL(triggered()), 
this, SLOT(close()));
 
 1098     fileMenu->addAction(close);
 
 1102       track->setText(
"Show Mouse &Tracking");
 
 1104           QPixmap(
FileName(
"$base/icons/goto.png").expanded()));
 
 1105       track->setCheckable(
true);
 
 1107           "<b>Function:</b>  Displays the x,y coordinates as the cursor moves " 
 1108           "around on the plot.";
 
 1109       track->setWhatsThis(text);
 
 1110       connect(track, SIGNAL(triggered()), 
this, SLOT(
trackerEnabled()));
 
 1111       optionsMenu->addAction(track);
 
 1115         BackgroundSwitchMenuOption) {
 
 1117       backgrdSwitch->setText(
"White/Black &Background");
 
 1118       backgrdSwitch->setIcon(
 
 1119           QPixmap(
FileName(
"$base/icons/plot_switchBackgrd.png").expanded()));
 
 1121           "<b>Function:</b>  Switch the background color between black and " 
 1123       backgrdSwitch->setWhatsThis(text);
 
 1124       connect(backgrdSwitch, SIGNAL(triggered()),
 
 1126       optionsMenu->addAction(backgrdSwitch);
 
 1127       actions.push_back(backgrdSwitch);
 
 1134           QPixmap(
FileName(
"$base/icons/plot_grid.png").expanded()));
 
 1136           "<b>Function:</b>  Display grid lines on the plot.";
 
 1145       changeLabels->setText(
"Rename Plot &Labels");
 
 1146       changeLabels->setIcon(
 
 1147           QPixmap(
FileName(
"$base/icons/plot_renameLabels.png").expanded()));
 
 1149           "<b>Function:</b>  Edit the plot title, x and y axis labels.";
 
 1150       changeLabels->setWhatsThis(text);
 
 1151       connect(changeLabels, SIGNAL(triggered()),
 
 1153       optionsMenu->addAction(changeLabels);
 
 1154       actions.push_back(changeLabels);
 
 1158         SetDisplayRangeMenuOption) {
 
 1160       changeScale->setText(
"Set &Display Range");
 
 1161       changeScale->setIcon(
 
 1162           QPixmap(
FileName(
"$base/icons/plot_setScale.png").expanded()));
 
 1164           "<b>Function:</b>  Adjust the scale for the x and y axis on the " 
 1166       changeScale->setWhatsThis(text);
 
 1167       connect(changeScale, SIGNAL(triggered()), 
this, SLOT(
setDefaultRange()));
 
 1168       optionsMenu->addAction(changeScale);
 
 1169       actions.push_back(changeScale);
 
 1173         ShowHideCurvesMenuOption) {
 
 1177           QPixmap(
FileName(
"$base/icons/plot_showCurves.png").expanded()));
 
 1179           "<b>Function:</b>  Displays or hides all the curves currently " 
 1180                             "displayed on the plot.";
 
 1189         ShowHideMarkersMenuOption) {
 
 1193           QPixmap(
FileName(
"$base/icons/plot_markers.png").expanded()));
 
 1194       QString text = 
"<b>Function:</b>  Displays or hides a symbol for each " 
 1195                      "data point plotted on a plot.";
 
 1205       resetScaleButton->setText(
"Reset Scale");
 
 1206       resetScaleButton->setIcon(
 
 1207           QPixmap(
FileName(
"$base/icons/plot_resetscale.png").expanded()));
 
 1209           "<b>Function:</b>  Reset the plot's scale.";
 
 1210       resetScaleButton->setWhatsThis(text);
 
 1211       connect(resetScaleButton, SIGNAL(triggered()), 
this, SLOT(
resetScale()));
 
 1212       actions.push_back(resetScaleButton);
 
 1217       clear->setText(
"Clear Plot");
 
 1219           QPixmap(
FileName(
"$base/icons/plot_clear.png").expanded()));
 
 1221           "<b>Function:</b>  Removes all the curves from the plot.";
 
 1222       clear->setWhatsThis(text);
 
 1223       connect(clear, SIGNAL(triggered()), 
this, SLOT(
clearPlot()));
 
 1224       actions.push_back(clear);
 
 1229       lineFit->setText(
"Create Best Fit Line");
 
 1231           QPixmap(
FileName(
"$base/icons/linefit.png").expanded()));
 
 1232       QString text = 
"<b>Function:</b>  Calculates a best fit line from an " 
 1234       lineFit->setWhatsThis(text);
 
 1236       optionsMenu->addAction(lineFit);
 
 1237       actions.push_back(lineFit);
 
 1242       configurePlot->setText(
"Configure Plot");
 
 1243       configurePlot->setIcon( 
 
 1244           QPixmap( 
FileName(
"$base/icons/plot_configure.png").expanded() ) );
 
 1245       QString text = 
"<b>Function:</b> Change the name, color, style, and vertex symbol of the " 
 1247       configurePlot->setWhatsThis(text);
 
 1248       connect( configurePlot, SIGNAL( triggered() ),
 
 1250       optionsMenu->addAction(configurePlot);
 
 1251       actions.push_back(configurePlot);
 
 1258     m_pasteAct->setShortcut(Qt::CTRL | Qt::Key_V);
 
 1269     menu.push_back(fileMenu);
 
 1270     menu.push_back(editMenu);
 
 1272     if (optionsMenu->actions().size()) {
 
 1273       menu.push_back(optionsMenu);
 
 1304     bool userCanAdd = 
false;
 
 1307         curve->hasFormat(
"application/isis3-plot-curve")) {
 
 1310           curve->data(
"application/isis3-plot-curve"));
 
 1312       userCanAdd = 
canAdd(testCurve);
 
 1359       m_toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea);
 
 1360       addToolBar(Qt::TopToolBarArea, 
m_toolBar);
 
 1369     for (
int i = 0; i < menu.size(); i++) {
 
 1373     for (
int i = 0; i < actions.size(); i++) {
 
 1397     if (!m_scheduledFillTable) {
 
 1398       m_scheduledFillTable = 
true;
 
 1399       emit requestFillTable();
 
 1409     m_scheduledFillTable = 
false;
 
 1418                               m_plot->axisTitle(QwtPlot::xBottom).text(),
 
 1419                               m_plot->axisTitle(QwtPlot::xBottom).text());
 
 1424                                 curve->title().text(),
 
 1425                                 curve->title().text());
 
 1442     QProgressDialog progress(tr(
"Re-calculating Table"), tr(
""), 0, 1000, 
this);
 
 1443     double percentPerCurve = 0.5 * 1.0 / curves.count();
 
 1445     for (
int curveIndex = 0; curveIndex < curves.count(); curveIndex++) {
 
 1446       progress.setValue(qRound(curveIndex * percentPerCurve * 1000.0));
 
 1450       double percentPerDataIndex = (1.0 / curve->data()->size()) * percentPerCurve;
 
 1454       for (
int dataIndex = (
int)curve->data()->size() - 1;
 
 1457         double xValue = curve->data()->sample(dataIndex).x();
 
 1458         QString xValueString = 
toString(xValue);
 
 1460         int inverseDataIndex = (curve->data()->size() - 1) - dataIndex;
 
 1462             qRound( ((curveIndex * percentPerCurve) +
 
 1463                      (inverseDataIndex * percentPerDataIndex)) * 1000.0));
 
 1469             qBinaryFind(xAxisPoints.begin(), xAxisPoints.end(), xValueString);
 
 1471         if (foundPos == xAxisPoints.end()) {
 
 1472           bool inserted = 
false;
 
 1474           for (
int searchIndex = 0;
 
 1475              searchIndex < xAxisPoints.size() && !inserted;
 
 1477             if (xAxisPoints[searchIndex] > xValueString) {
 
 1479               xAxisPoints.insert(searchIndex, xValueString);
 
 1484             xAxisPoints.append(xValueString);
 
 1489     qSort(xAxisPoints.begin(), xAxisPoints.end(), &numericStringLessThan);
 
 1495     for (
int i = 0; i < curves.count(); i++) {
 
 1496       lastSuccessfulSamples.append(-1);
 
 1502       progress.setValue(500 + qRound(row * progressPerRow * 1000.0));
 
 1504       QString xValueString = xAxisPoints[row];
 
 1505       double xValue = 
toDouble(xValueString);
 
 1507       QTableWidgetItem *xAxisItem = 
new QTableWidgetItem(xValueString);
 
 1519         bool tooFar = 
false;
 
 1521         for (
int dataIndex = lastSuccessfulSamples[col - 1] + 1;
 
 1522              dataIndex < (int)curve->data()->size() && y == 
Null && !tooFar;
 
 1525           if (
toString(curve->data()->sample(dataIndex).x()) == xValueString) {
 
 1527             if (dataIndex > 0 &&
 
 1528                 curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x()) {
 
 1529               lastSuccessfulSamples[col - 1] = dataIndex;
 
 1531             y = curve->data()->sample(dataIndex).y();
 
 1534           else if (dataIndex > 0 &&
 
 1535               curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x() &&
 
 1536               curve->data()->sample(dataIndex).x() > xValue) {
 
 1541         QTableWidgetItem *item = NULL;
 
 1544           item = 
new QTableWidgetItem(QString(
"N/A"));
 
 1546           item = 
new QTableWidgetItem(
toString(y));
 
 1588     bool blockWidgetFromEvent = 
false;
 
 1590     switch (e->type()) {
 
 1591       case QEvent::MouseButtonPress:
 
 1593             childAt(((QMouseEvent *)e)->pos()) != 
plot()->canvas()) {
 
 1595           blockWidgetFromEvent = 
true;
 
 1603     bool stopHandlingEvent = 
false;
 
 1604     if (!blockWidgetFromEvent && o == 
this) {
 
 1605       stopHandlingEvent = MainWindow::eventFilter(o, e);
 
 1607       if (e->type() == QEvent::Close && !stopHandlingEvent) {
 
 1612     return stopHandlingEvent || blockWidgetFromEvent;
 
 1626     if (qobject_cast<QWidget *>(
object) &&
 
 1627         event->button() == Qt::RightButton &&
 
 1631       QAction *pasteAct = 
new QAction(QIcon::fromTheme(
"edit-paste"), 
"Paste",
 
 1633       contextMenu.addAction(pasteAct);
 
 1635       QAction *chosenAct = contextMenu.exec(
 
 1636           qobject_cast<QWidget *>(
object)->mapToGlobal(event->pos()));
 
 1638       if (chosenAct == pasteAct) {
 
 1696       QClipboard *globalClipboard = QApplication::clipboard();
 
 1697       const QMimeData *globalData = globalClipboard->mimeData();
 
 1699       if (globalData->hasFormat(
"application/isis3-plot-curve")) {
 
 1701                 globalData->data(
"application/isis3-plot-curve"));
 
 1722     bool foundDataValue = 
false;
 
 1726       for (
int dataIndex = 0; dataIndex < (int)curve->dataSize(); dataIndex++) {
 
 1727         if (axisId == QwtPlot::xBottom) {
 
 1728           if (!foundDataValue) {
 
 1729             rangeMinMax.first = curve->sample(dataIndex).x();
 
 1730             rangeMinMax.second = curve->sample(dataIndex).x();
 
 1731             foundDataValue = 
true;
 
 1734             rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).x());
 
 1735             rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).x());
 
 1738         else if (axisId == QwtPlot::yLeft) {
 
 1739           if (!foundDataValue) {
 
 1740             rangeMinMax.first = curve->sample(dataIndex).y();
 
 1741             rangeMinMax.second = curve->sample(dataIndex).y();
 
 1742             foundDataValue = 
true;
 
 1745             rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).y());
 
 1746             rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).y());
 
 1752     if (!foundDataValue) {
 
 1753       rangeMinMax.first = 1;
 
 1754       rangeMinMax.second = 10;
 
 1756     else if(rangeMinMax.first == rangeMinMax.second) {
 
 1757       rangeMinMax.first -= 0.5;
 
 1758       rangeMinMax.second += 0.5;
 
 1765   bool PlotWindow::numericStringLessThan(QString left, QString right) {
 
 1766     bool result = 
false;
 
 1771     catch (IException &) {
 
 1786       curve->
paint(vp, painter);
 
 1821     QObject *source = 
event->source();
 
 1823     if (source != 
m_legend->contentsWidget() &&
 
 1825       event->acceptProposedAction();
 
 1843         event->mimeData()->hasFormat(
"application/isis3-plot-curve")) {
 
 1844       Qt::DropActions possibleActions = 
event->possibleActions();
 
 1845       Qt::DropAction actionToTake = 
event->proposedAction();
 
 1848       boldFont.setBold(
true);
 
 1849       QMenu dropActionsMenu;
 
 1852       if (possibleActions.testFlag(Qt::CopyAction)) {
 
 1853         dropActionsMenu.addAction(copyAct);
 
 1855         if (actionToTake == Qt::CopyAction)
 
 1856           copyAct->setFont(boldFont);
 
 1860       if (possibleActions.testFlag(Qt::MoveAction)) {
 
 1861         dropActionsMenu.addAction(moveAct);
 
 1863         if (actionToTake == Qt::MoveAction)
 
 1864           moveAct->setFont(boldFont);
 
 1867       if (dropActionsMenu.actions().size() > 1) {
 
 1868         dropActionsMenu.addSeparator();
 
 1871         dropActionsMenu.addAction(cancelAct);
 
 1873         QAction *chosenAct = dropActionsMenu.exec(mapToGlobal(event->pos()));
 
 1875         if (chosenAct == copyAct) {
 
 1876           actionToTake = Qt::CopyAction;
 
 1878         else if (chosenAct == moveAct) {
 
 1879           actionToTake = Qt::MoveAction;
 
 1882           actionToTake = Qt::IgnoreAction;
 
 1886       if (actionToTake != Qt::IgnoreAction) {
 
 1888                 event->mimeData()->data(
"application/isis3-plot-curve"));
 
 1893         event->setDropAction(actionToTake);
 
Cube display widget for certain Isis MDI applications. 
 
This option allows the user to create a best fit line for any of the scatter plot data or cube plot c...
 
bool m_plotYLogScale
Tracks if the plot Y axis is using a log (true) or linear (false) scale. 
 
This option enables the ability for a user to change the background color of the plot from black to w...
 
PlotCurve::Units m_yAxisUnits
The units of the data on the y-left axis. 
 
virtual void readSettings(QSize defaultSize=QSize())
This method ensure that the settings get written even if the Main window was only hidden...
 
QTableWidget * table() const 
Returns the table. 
 
void clearPlot()
This method completely clears the plot of all plot items. 
 
const double Null
Value for an Isis Null pixel. 
 
QLineEdit * m_yMaxEdit
Set Scale Dialog's edit for the max Y-axis value. 
 
void setMarkerVisible(bool visible)
This method sets the visibility states of the markers at each value point. 
 
QColor color() const 
This method returns the color of the curve. 
 
bool canAdd(CubePlotCurve *curveToTest) const 
This method tests whethere or not a CubePlotCurve can be successfully added to this window...
 
void showHideAllCurves()
This method shows or hides all of the curves in the plotWindow. 
 
void switchBackground()
This method toggles the plot background color between black and white. 
 
void savePlot()
This method allows the user to save the plot as a png, jpg, or tif image file. 
 
bool m_plotXLogScale
Tracks if the plot X axis is using a log (true) or linear (false) scale. 
 
File name manipulation and expansion. 
 
MenuOptions
There is a menu option for everything in the plot window's menu. 
 
void attachMarkers()
After attaching this curve to a plot, due to an inheritance/implementation complication with qwt the ...
 
void createWidgets(MenuOptions optionsToProvide)
This method is called by the constructor to create the plot, legend. 
 
void showHideAllMarkers()
Shows/Hides all the markers(symbols) 
 
The data is a Cube DN value. 
 
QwtPlotZoomer * m_zoomer
Plot Zoomer. 
 
bool userCanAddCurve(const QMimeData *curve)
Ask if a user action can add this curve to this window. 
 
void pasteCurve()
When the user pastes a curve try to put it into this plot window. 
 
This option allows the user to change the curve name, color, style size, and symbol of the curve...
 
virtual void paint(MdiCubeViewport *vp, QPainter *painter)
Paint plot curve information onto the viewport. 
 
QPointer< QAction > m_showHideAllCurves
Hide all curves action. 
 
This option enables mouse tracking on the plot area (displays next to the mouse which x/y point you a...
 
QListWidget * listWidget() const 
Returns the list widget. 
 
QLineEdit * m_xMaxEdit
Set Scale Dialog's edit for the max X-axis value. 
 
This option provides the user with an alternative zoom out button. 
 
void createBestFitLine()
This method prompts the user to select the best fit line criterea. 
 
QwtPlotZoomer * zoomer()
Get this window's plot's zoomer. 
 
QLineEdit * m_xAxisText
Set Labels Dialog's edit for the x-axis label. 
 
QwtLegend * m_legend
The legend inserted in this plot. 
 
QCheckBox * m_xLogCheckBox
Set Scale Dialog's checkbox for using logarithmic scale for the x axis. 
 
virtual void dropEvent(QDropEvent *event)
This is called when a user drops data into our window. 
 
void configurePlotCurves()
This method creates a CubePlotCurveConfigureDialog object. 
 
The data is a percentage (0-100). 
 
QAction * m_pasteAct
This is the paste action in the edit menu to paste a curve into the plot window. 
 
void showHelp()
This method creates and shows the help dialog box for the plot window. 
 
void setPlotBackground(QColor c)
Sets the plot background color to the given color. 
 
void showHideGrid()
This method hides/shows the grid on the plotWindow and changes the text for the action. 
 
void updateVisibility(PlotCurve *curve)
This method sets the visibility states in the curve (and it's symbols) to match with this window's cu...
 
QString toString(bool boolToConvert)
Global function to convert a boolean to a string. 
 
QLineEdit * m_yAxisText
Set Labels Dialog's edit for the y-axis label. 
 
QString plotTitle() const 
Returns the plot title. 
 
The data is a wavelength. 
 
double toDouble(const QString &string)
Global function to convert from a string to a double. 
 
This error is for when a programmer made an API call that was illegal. 
 
QPointer< QAction > m_showHideAllMarkers
Hide all markers action. 
 
QwtPlot * m_plot
The plot in this window. 
 
void setMenus(QList< QMenu * > menus, QList< QAction * > actions)
Sets up the menus added from a parent object. 
 
void updateLegendItemWidget(QWidget *legendItem)
This creates a legend item and overrides events from it. 
 
void trackerEnabled()
Enables the plot mouse tracker. 
 
void setUserValues()
This method sets the scale for the axis according to the user specified numbers. 
 
bool m_autoscaleAxes
True if we are autoscaling the x-bottom and y-left axes. 
 
QColor plotBackgroundColor() const 
Returns the plot's background color. 
 
void fillTable()
Fills in the table with the data from the current curves in the plotWindow immediately. 
 
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...
 
TableMainWindow * m_tableWindow
Table window. 
 
void closed()
Emitted when there is a close event on this window that will be accepted. 
 
This option sends the plot to a printer. 
 
Units xUnits() const 
Get the units of the x-axis double data. 
 
virtual bool eventFilter(QObject *o, QEvent *e)
This method filters the events of the objects it is connected to. 
 
Units yUnits() const 
Get the units of the y-axis double data. 
 
QMenuBar * m_menubar
Plot window's menu bar. 
 
QwtPlotGrid * m_grid
Plot grid lines. 
 
void scheduleFillTable()
Fills in the table with the data from the current curves in the plotWindow once all current actions/a...
 
QLineEdit * m_yMinEdit
Set Scale Dialog's edit for the min Y-axis value. 
 
void plotChanged()
Emitted every time there is a change to the plot window. 
 
This is a plot curve with information relating it to a particular cube or region of a cube...
 
#define _FILEINFO_
Macro for the filename and line number. 
 
void setDefaultRange()
Resets the x/y min/max to the defaults. 
 
QToolBar * m_toolBar
Tool bar on the plot window. 
 
This option allows the user to delete all of the data inside the plot. 
 
bool IsSpecial(const double d)
Returns if the input pixel is special. 
 
void syncColumns()
This method hides and shows the columns according to which items the user has selected to be view-abl...
 
QLineEdit * m_plotTitleText
Set Labels Dialog's edit for the plot title. 
 
void setAxisLabel(int axisId, QString title)
Sets the plots given axis title to the given string. 
 
void printPlot()
Provides printing support of the plot image. 
 
void setPlotTitle(QString pt)
Sets the plot title to the given string. 
 
void resetScale()
Sets plot scale back to the defaults. 
 
QWidget * m_parent
Parent widget. 
 
This option is titled 'Hide All Curves' which makes all curves invisible. 
 
a subclass of the qisis mainwindow, tablemainwindow handles all of the table tasks. 
 
QCheckBox * m_yLogCheckBox
Set Scale Dialog's checkbox for using logarithmic scale for the y axis. 
 
This option brings up the table. 
 
void showTable()
This method is called from the showTable action on the tool bar There are some checks done to make su...
 
virtual void update(MdiCubeViewport *activeViewport)
This is provided to allow children to react to tool updates. 
 
QPair< double, double > findDataRange(int axisId) const 
This calculates the data range of the specified axis (works with xBottom and yLeft only)...
 
void mousePressEvent(QObject *object, QMouseEvent *e)
This is a helper method for the eventFilter() method. 
 
The data is an elevation (in meters). 
 
void disableAxisAutoScale()
This turns off scaling the x/y axes automatically. 
 
void autoScaleCheckboxToggled()
This is a helper method for the set scale configuration dialog. 
 
PlotCurve::Units m_xAxisUnits
The units of the data on the x-bottom axis. 
 
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
 
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...
 
This option is titled 'Hide All Symbols' which hides all markers. 
 
Adds specific functionality to C++ strings. 
 
QList< CubePlotCurve * > plotCurves()
Get a comprehensive list of the plot curves inside of this plot window, excluding plot curves that ar...
 
void setUserCanAddCurves(bool)
Allow or disallow users from manually putting curves into this plot window through either copy-and-pa...
 
QLineEdit * m_xMinEdit
Set Scale Dialog's edit for the min X-axis value. 
 
void showWindow()
Shows the plot window, and raises it to the front of any overlapping sibling widgets. 
 
This option allows the user to set the x/y axis display value ranges. 
 
QList< QwtPlotSpectrogram * > plotSpectrograms()
Get a comprehensive list of the scatter plots (spectrograms) inside of this plot window. 
 
Base class for the Qisis main windows. 
 
void setLabels()
Makes the user specified changes to the plot labels. 
 
This option enables the ability for a user to change the x/y axis labels and plot title...
 
This option enables the ability for a user to enable a grid over the plot area. 
 
void replot()
Reset the scale of the plot, replot it and emit plot changed. 
 
The data is a band number. 
 
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. 
 
QCheckBox * m_autoScaleCheckBox
Set Scale Dialog's checkbox for enabling automatic scaling on x & y. 
 
The data is in kilometers. 
 
virtual void clearPlotCurves()
This method also clears the plot of all plot items, but does not call the table delete stuff This met...
 
bool userCanAddCurves() const 
Ask if a user action can add this curve to this window in general. 
 
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot. 
 
QwtPlot * plot()
Get the plot encapsulated by this PlotWindow. 
 
bool m_allowUserToAddCurves
Is the window showing the curve markers? 
 
This option exports the plot into a standard image format. 
 
Units
These are all the possible units for the x or y data in a plot curve. 
 
QPointer< QAction > m_showHideGrid
Show plot grid lines action. 
 
void changePlotLabels()
This method creates the dialog box which allows the user to relabel the plot window. 
 
void setupDefaultMenu(MenuOptions optionsToProvide)
The user can add menu items from parent classes, but there are some menu items that are common betwee...
 
PlotCurve::Units xAxisUnits() const 
This is the data-type of the curves' x data in this plot window. 
 
PlotCurve::Units yAxisUnits() const 
This is the data-type of the curves' y data in this plot window. 
 
void paint(CubeViewport *vp, QPainter *painter)
Use information inside of the plot curve to paint onto a cube viewport. 
 
void onClipboardChanged()
This slot will be called when the system clipboard is changed.