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.