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>
34#include "CubePlotCurve.h"
35#include "CubePlotCurveConfigureDialog.h"
36#include "CubeViewport.h"
38#include "Interpolator.h"
39#include "MainWindow.h"
40#include "MdiCubeViewport.h"
41#include "PlotWindowBestFitDialog.h"
44#include "PvlKeyword.h"
45#include "QHistogram.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);
104 QMap<PlotCurve::Units, QString> unitLabels;
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();
329 QList<CubePlotCurve *> foundCurves;
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);
355 QList<const CubePlotCurve *> foundCurves;
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);
382 QList<QwtPlotSpectrogram *> foundSpectrograms;
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;
410 QList<const QwtPlotSpectrogram *> 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 *)),
480 pc->updateLegendItemWidget(legendWidget);
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 QPageSize pageSize(QPageSize::Letter);
579 printer->setPageSize(pageSize);
580 printer->setColorMode(QPrinter::Color);
582 QPrintDialog printDialog(printer, (
QWidget *)parent());
584 if (printDialog.exec() == QDialog::Accepted) {
587 QImage img = pixmap.toImage();
589 QPainter painter(printer);
590 QRect rect = painter.viewport();
591 QSize size = img.size();
592 size.scale(rect.size(), Qt::KeepAspectRatio);
593 painter.setViewport(rect.x(), rect.y(),
594 size.width(), size.height());
595 painter.setWindow(img.rect());
596 painter.drawImage(0, 0, img);
609 QFileDialog::getSaveFileName((
QWidget *)parent(),
610 "Choose output file",
612 QString(
"Images (*.png *.jpg *.tif)"));
613 if (output.isEmpty())
return;
615 if (!output.isEmpty()) {
616 if (!output.endsWith(
".png") && !output.endsWith(
".jpg") && !output.endsWith(
".tif")) {
617 output = output +
".png";
621 QString format = QFileInfo(output).suffix();
624 std::string formatString = format.toStdString();
625 if (!pixmap.save(output, formatString.c_str())) {
626 QMessageBox::information((
QWidget *)parent(),
"Error",
"Unable to save " + output);
637 QPen *pen =
new QPen(Qt::white);
639 if (
m_plot->canvasBackground() == Qt::white) {
640 m_plot->setCanvasBackground(Qt::black);
641 m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
644 m_plot->setCanvasBackground(Qt::white);
645 pen->setColor(Qt::black);
646 m_grid->setMajorPen(QPen(Qt::black, 1, Qt::DotLine));
666 m_plot->setAxisAutoScale(QwtPlot::xBottom);
671 m_plot->setAxisScale(QwtPlot::xBottom, calculatedXRange.first,
672 calculatedXRange.second);
676 m_plot->setAxisAutoScale(QwtPlot::yLeft);
681 m_plot->setAxisScale(QwtPlot::yLeft, calculatedYRange.first,
682 calculatedYRange.second);
697 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLogScaleEngine);
701 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine);
706 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLogScaleEngine);
710 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine);
723 m_plot->setAxisScale(QwtPlot::xBottom, xMin, xMax);
731 m_plot->setAxisScale(QwtPlot::yLeft, yMin, yMax);
746 dialog->setWindowTitle(
"Set Display Range");
748 QGridLayout *dialogLayout =
new QGridLayout;
752 QLabel *autoLabel =
new QLabel(
"Auto-Scale: ");
753 dialogLayout->addWidget(autoLabel, row, 0);
762 QLabel *xLabel =
new QLabel(
"<h3>X-Axis</h3>");
763 dialogLayout->addWidget(xLabel, row, 0, 1, 2);
766 QLabel *xMinLabel =
new QLabel(
"Minimum: ");
767 dialogLayout->addWidget(xMinLabel, row, 0);
769 double xMin =
plot()->axisScaleDiv(QwtPlot::xBottom).lowerBound();
770 m_xMinEdit =
new QLineEdit(QString::number(xMin));
774 QLabel *xMaxLabel =
new QLabel(
"Maximum: ");
775 dialogLayout->addWidget(xMaxLabel, row, 0);
777 double xMax =
plot()->axisScaleDiv(QwtPlot::xBottom).upperBound();
778 m_xMaxEdit =
new QLineEdit(QString::number(xMax));
782 QLabel *xLogLabel =
new QLabel(
"Logarithmic Scale");
783 dialogLayout->addWidget(xLogLabel, row, 0);
793 QLabel *yLabel =
new QLabel(
"<h3>Y-Axis</h3>");
794 dialogLayout->addWidget(yLabel, row, 0, 1, 2);
797 QLabel *yMinLabel =
new QLabel(
"Minimum: ");
798 dialogLayout->addWidget(yMinLabel, row, 0);
800 double yMin =
plot()->axisScaleDiv(QwtPlot::yLeft).lowerBound();
801 m_yMinEdit =
new QLineEdit(QString::number(yMin));
805 QLabel *yMaxLabel =
new QLabel(
"Maximum: ");
806 dialogLayout->addWidget(yMaxLabel, row, 0);
808 double yMax =
plot()->axisScaleDiv(QwtPlot::yLeft).upperBound();
809 m_yMaxEdit =
new QLineEdit(QString::number(yMax));
813 QLabel *yLogLabel =
new QLabel(
"Logarithmic Scale");
814 dialogLayout->addWidget(yLogLabel, row, 0);
824 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
825 buttonsLayout->addStretch();
827 QPushButton *okButton =
new QPushButton(
"&Ok");
828 okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
829 connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
830 connect(dialog, SIGNAL(accepted()),
this, SLOT(
setUserValues()));
831 okButton->setShortcut(Qt::Key_Enter);
832 buttonsLayout->addWidget(okButton);
834 QPushButton *cancelButton =
new QPushButton(
"&Cancel");
835 cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
836 connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
837 buttonsLayout->addWidget(cancelButton);
840 buttonsWrapper->setLayout(buttonsLayout);
841 dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
846 dialog->setLayout(dialogLayout);
857 dialog->setWindowTitle(
"Name Plot Labels");
859 QGridLayout *dialogLayout =
new QGridLayout;
862 QLabel *plotLabel =
new QLabel(
"Plot Title: ");
863 dialogLayout->addWidget(plotLabel, row, 0);
869 QLabel *xAxisLabel =
new QLabel(
"X-Axis Label: ");
870 dialogLayout->addWidget(xAxisLabel, row, 0);
876 QLabel *yAxisLabel =
new QLabel(
"Y-Axis Label: ");
877 dialogLayout->addWidget(yAxisLabel, row, 0);
883 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
884 buttonsLayout->addStretch();
886 QPushButton *okButton =
new QPushButton(
"&Ok");
887 okButton->setIcon(QIcon::fromTheme(
"dialog-ok"));
888 connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept()));
889 connect(dialog, SIGNAL(accepted()),
this, SLOT(
setLabels()));
890 okButton->setShortcut(Qt::Key_Enter);
891 buttonsLayout->addWidget(okButton);
893 QPushButton *cancelButton =
new QPushButton(
"&Cancel");
894 cancelButton->setIcon(QIcon::fromTheme(
"dialog-cancel"));
895 connect(cancelButton, SIGNAL(clicked()), dialog, SLOT(reject()));
896 buttonsLayout->addWidget(cancelButton);
899 buttonsWrapper->setLayout(buttonsLayout);
900 dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
903 dialog->setLayout(dialogLayout);
927 if (
m_grid->isVisible()) {
943 method = &QwtPlotItem::hide;
949 method = &QwtPlotItem::show;
954 for (
int i = 0; i <
m_plot->itemList().size(); i ++) {
956 if (plotItem->rtti() == QwtPlotItem::Rtti_PlotMarker)
957 (plotItem->*method)();
971 method = &QwtPlotItem::hide;
975 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
979 method = &QwtPlotItem::show;
983 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_hideCurves.png").expanded()));
986 for (
int i = 0; i <
m_plot->itemList().size(); i ++) {
988 if (plotItem->rtti() == QwtPlotItem::Rtti_PlotCurve)
989 (plotItem->*method)();
1002 d->setWindowTitle(
"Basic Help");
1004 QLabel *zoomLabel =
new QLabel(
"<U>Zoom Options:</U>");
1005 QLabel *zoomIn =
new
1006 QLabel(
" <b>Left click</b> on the mouse, drag, and release to select an area to zoom in on");
1007 QLabel *zoomOut =
new
1008 QLabel(
" <b>Middle click</b> on the mouse to zoom out one level");
1009 QLabel *zoomReset =
new
1010 QLabel(
" <b>Right click</b> on the mouse and select <I>Reset Scale</I> to clear the zoom and return to the original plot");
1012 QLabel *curveConfigLabel =
new QLabel(
"<br><U>Curve Configuration:</U>");
1013 QLabel *configDirections =
new
1014 QLabel(
" <b>To configure the curve properties</b> Right click on the legend and select <I>Configure</I> from <br> the menu"
1015 " or click on the configure icon in the tool bar.");
1016 QLabel *config =
new QLabel();
1017 config->setPixmap(QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_configure.png").expanded()));
1019 QLabel *tableLabel =
new QLabel(
"<br><U>Table Options:</U>");
1020 QLabel *tableDirections =
new
1021 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.");
1022 QLabel *table =
new QLabel();
1023 table->setPixmap(QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_table.png").expanded()));
1025 QVBoxLayout *layout =
new QVBoxLayout();
1026 layout->addWidget(zoomLabel);
1027 layout->addWidget(zoomIn);
1028 layout->addWidget(zoomOut);
1029 layout->addWidget(zoomReset);
1030 layout->addWidget(curveConfigLabel);
1031 layout->addWidget(config);
1032 layout->addWidget(configDirections);
1033 layout->addWidget(tableLabel);
1034 layout->addWidget(table);
1035 layout->addWidget(tableDirections);
1037 d->setLayout(layout);
1050 QList<QMenu *> menu;
1051 QList<QAction *> actions;
1060 save->setText(
"&Save Plot As");
1061 save->setIcon(QIcon::fromTheme(
"document-save-as"));
1063 "<b>Function:</b> Save the plot as a png, jpg, or tif file.";
1064 save->setWhatsThis(text);
1065 connect(save, SIGNAL(triggered()),
this, SLOT(
savePlot()));
1066 fileMenu->addAction(save);
1067 actions.push_back(save);
1072 prt->setText(
"&Print Plot");
1073 prt->setIcon(QIcon::fromTheme(
"document-print"));
1075 "<b>Function:</b> Sends the plot image to the printer";
1076 prt->setWhatsThis(text);
1077 connect(prt, SIGNAL(triggered()),
this, SLOT(
printPlot()));
1078 fileMenu->addAction(prt);
1079 actions.push_back(prt);
1084 table->setText(
"Show Table");
1086 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_table.png").expanded()));
1088 "<b>Function:</b> Activates the table which displays the data of the "
1090 table->setWhatsThis(text);
1091 connect(table, SIGNAL(triggered()),
this, SLOT(
showTable()));
1092 fileMenu->addAction(table);
1093 actions.push_back(table);
1096 QAction *close =
new QAction(QIcon::fromTheme(
"document-close"),
"&Close",
1098 connect(close, SIGNAL(triggered()),
this, SLOT(close()));
1099 fileMenu->addAction(close);
1103 track->setText(
"Show Mouse &Tracking");
1105 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/goto.png").expanded()));
1106 track->setCheckable(
true);
1108 "<b>Function:</b> Displays the x,y coordinates as the cursor moves "
1109 "around on the plot.";
1110 track->setWhatsThis(text);
1111 connect(track, SIGNAL(triggered()),
this, SLOT(
trackerEnabled()));
1112 optionsMenu->addAction(track);
1118 backgrdSwitch->setText(
"White/Black &Background");
1119 backgrdSwitch->setIcon(
1120 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_switchBackgrd.png").expanded()));
1122 "<b>Function:</b> Switch the background color between black and "
1124 backgrdSwitch->setWhatsThis(text);
1125 connect(backgrdSwitch, SIGNAL(triggered()),
1127 optionsMenu->addAction(backgrdSwitch);
1128 actions.push_back(backgrdSwitch);
1135 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_grid.png").expanded()));
1137 "<b>Function:</b> Display grid lines on the plot.";
1146 changeLabels->setText(
"Rename Plot &Labels");
1147 changeLabels->setIcon(
1148 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_renameLabels.png").expanded()));
1150 "<b>Function:</b> Edit the plot title, x and y axis labels.";
1151 changeLabels->setWhatsThis(text);
1152 connect(changeLabels, SIGNAL(triggered()),
1154 optionsMenu->addAction(changeLabels);
1155 actions.push_back(changeLabels);
1161 changeScale->setText(
"Set &Display Range");
1162 changeScale->setIcon(
1163 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_setScale.png").expanded()));
1165 "<b>Function:</b> Adjust the scale for the x and y axis on the "
1167 changeScale->setWhatsThis(text);
1168 connect(changeScale, SIGNAL(triggered()),
this, SLOT(
setDefaultRange()));
1169 optionsMenu->addAction(changeScale);
1170 actions.push_back(changeScale);
1178 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
1180 "<b>Function:</b> Displays or hides all the curves currently "
1181 "displayed on the plot.";
1194 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_markers.png").expanded()));
1195 QString text =
"<b>Function:</b> Displays or hides a symbol for each "
1196 "data point plotted on a plot.";
1206 resetScaleButton->setText(
"Reset Scale");
1207 resetScaleButton->setIcon(
1208 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_resetscale.png").expanded()));
1210 "<b>Function:</b> Reset the plot's scale.";
1211 resetScaleButton->setWhatsThis(text);
1212 connect(resetScaleButton, SIGNAL(triggered()),
this, SLOT(
resetScale()));
1213 actions.push_back(resetScaleButton);
1218 clear->setText(
"Clear Plot");
1220 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_clear.png").expanded()));
1222 "<b>Function:</b> Removes all the curves from the plot.";
1223 clear->setWhatsThis(text);
1224 connect(clear, SIGNAL(triggered()),
this, SLOT(
clearPlot()));
1225 actions.push_back(clear);
1230 lineFit->setText(
"Create Best Fit Line");
1232 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/linefit.png").expanded()));
1233 QString text =
"<b>Function:</b> Calculates a best fit line from an "
1235 lineFit->setWhatsThis(text);
1237 optionsMenu->addAction(lineFit);
1238 actions.push_back(lineFit);
1243 configurePlot->setText(
"Configure Plot");
1244 configurePlot->setIcon(
1245 QPixmap(
FileName(
"$ISISROOT/appdata/images/icons/plot_configure.png").expanded() ) );
1246 QString text =
"<b>Function:</b> Change the name, color, style, and vertex symbol of the "
1248 configurePlot->setWhatsThis(text);
1249 connect( configurePlot, SIGNAL( triggered() ),
1251 optionsMenu->addAction(configurePlot);
1252 actions.push_back(configurePlot);
1256 basicHelp->setText(
"Basic Help");
1257 QString text =
"<b>Function:</b> Provides a basic overview on using components "
1258 "of the qview plot window";
1259 basicHelp->setWhatsThis(text);
1260 connect( basicHelp, SIGNAL( triggered() ),
1262 helpMenu->addAction(basicHelp);
1268 m_pasteAct->setShortcut(Qt::CTRL | Qt::Key_V);
1273 menu.push_back(fileMenu);
1274 menu.push_back(editMenu);
1276 if (optionsMenu->actions().size()) {
1277 menu.push_back(optionsMenu);
1284 if (helpMenu->actions().size()) {
1285 menu.push_back(helpMenu);
1308 bool userCanAdd =
false;
1311 curve->hasFormat(
"application/isis3-plot-curve")) {
1314 curve->data(
"application/isis3-plot-curve"));
1316 userCanAdd =
canAdd(testCurve);
1341 curve->setMarkerVisible(
true);
1344 curve->setMarkerVisible(
false);
1363 m_toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea);
1364 addToolBar(Qt::TopToolBarArea,
m_toolBar);
1373 for (
int i = 0; i < menu.size(); i++) {
1377 for (
int i = 0; i < actions.size(); i++) {
1401 if (!m_scheduledFillTable) {
1402 m_scheduledFillTable =
true;
1403 emit requestFillTable();
1413 m_scheduledFillTable =
false;
1422 m_plot->axisTitle(QwtPlot::xBottom).text(),
1423 m_plot->axisTitle(QwtPlot::xBottom).text());
1425 QList<CubePlotCurve *> curves =
plotCurves();
1428 curve->title().text(),
1429 curve->title().text());
1444 QList<QString> xAxisPoints;
1446 QProgressDialog progress(tr(
"Re-calculating Table"), tr(
""), 0, 1000,
this);
1447 double percentPerCurve = 0.5 * 1.0 / curves.count();
1449 for (
int curveIndex = 0; curveIndex < curves.count(); curveIndex++) {
1450 progress.setValue(qRound(curveIndex * percentPerCurve * 1000.0));
1454 double percentPerDataIndex = (1.0 / curve->data()->size()) * percentPerCurve;
1458 for (
int dataIndex = (
int)curve->data()->size() - 1;
1461 double xValue = curve->data()->sample(dataIndex).x();
1462 QString xValueString =
toString(xValue);
1464 int inverseDataIndex = (curve->data()->size() - 1) - dataIndex;
1466 qRound( ((curveIndex * percentPerCurve) +
1467 (inverseDataIndex * percentPerDataIndex)) * 1000.0));
1471 std::lower_bound(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 sort(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.