Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
PlotWindow.cpp
1#include "PlotWindow.h"
2
3#include <algorithm>
4#include <iostream>
5
6#include <qwt_legend.h>
7#include <qwt_plot_grid.h>
8#include <qwt_plot_spectrogram.h>
9#include <qwt_symbol.h>
10#include <qwt_scale_engine.h>
11#include <qwt_text.h>
12
13#include <QAction>
14#include <QApplication>
15#include <QCheckBox>
16#include <QFileDialog>
17#include <QGridLayout>
18#include <QIcon>
19#include <QLabel>
20#include <QLineEdit>
21#include <QMap>
22#include <QMenuBar>
23#include <QMessageBox>
24#include <QPrinter>
25#include <QPrintDialog>
26#include <QProgressDialog>
27#include <QPushButton>
28#include <QSet>
29#include <QTableWidget>
30#include <QToolBar>
31#include <QPageSize>
32
33#include "Cube.h"
34#include "CubePlotCurve.h"
35#include "CubePlotCurveConfigureDialog.h" //
36#include "CubeViewport.h"
37#include "FileName.h"
38#include "Interpolator.h"
39#include "MainWindow.h"
40#include "MdiCubeViewport.h"
41#include "PlotWindowBestFitDialog.h"
42#include "Pvl.h"
43#include "PvlGroup.h"
44#include "PvlKeyword.h"
45#include "QHistogram.h"
46#include "Stretch.h"
47#include "TableMainWindow.h"
48
49
50using namespace std;
51
52namespace Isis {
68 MenuOptions optionsToProvide) :
69 MainWindow(title, parent) {
70
71 m_toolBar = NULL;
72 m_menubar = NULL;
73 m_tableWindow = NULL;
74 m_pasteAct = NULL;
76 m_autoscaleAxes = true;
77
78 setObjectName("Plot Window: " + title);
79
80 m_parent = parent;
83
84 if (!m_parent) {
85 IString msg = "PlotWindow cannot be instantiated with a NULL parent";
86 throw IException(IException::Programmer, msg, _FILEINFO_);
87 }
88
89 installEventFilter(this);
90 setAcceptDrops(true);
91
92 createWidgets(optionsToProvide);
93 setWindowTitle(title);
94
95 setPlotBackground(Qt::black);
96
97 connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)),
98 this, SLOT(onClipboardChanged()));
99 connect(this, SIGNAL(plotChanged()),
100 this, SLOT(scheduleFillTable()));
101 connect(this, SIGNAL(requestFillTable()),
102 this, SLOT(fillTable()), Qt::QueuedConnection);
103
105 unitLabels.insert(PlotCurve::Band, "Band");
106 unitLabels.insert(PlotCurve::Percentage, "Percentage");
107 unitLabels.insert(PlotCurve::PixelNumber, "Pixel Number");
108 unitLabels.insert(PlotCurve::CubeDN, "Pixel Value");
109 unitLabels.insert(PlotCurve::Elevation, "Elevation");
110 unitLabels.insert(PlotCurve::Meters, "Meters");
111 unitLabels.insert(PlotCurve::Kilometers, "Kilometers");
112 unitLabels.insert(PlotCurve::Wavelength, "Wavelength");
113
114 plot()->setAxisTitle(QwtPlot::xBottom, unitLabels[xAxisUnits]);
115 plot()->setAxisTitle(QwtPlot::yLeft, unitLabels[yAxisUnits]);
116 setPlotTitle(title);
117
119
120 readSettings();
121
122#ifdef __APPLE__
123 setWindowFlags(Qt::Tool);
124#else
125 setWindowFlags(Qt::Dialog);
126#endif
127 }
128
129
130
131 PlotWindow::~PlotWindow() {
132 foreach (QwtPlotCurve *curve, plotCurves()) {
133 delete curve;
134 }
135 }
136
137
145 void PlotWindow::createWidgets(MenuOptions optionsToProvide) {
146 /*Create plot*/
147 m_plot = new QwtPlot();
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);
154
155 /*Plot Legend*/
156 m_legend = new QwtLegend();
157 m_legend->setDefaultItemMode(QwtLegendData::Clickable);
158 m_legend->setWhatsThis("Right Click on a legend item to display the context "
159 "menu.");
160 m_plot->insertLegend(m_legend, QwtPlot::RightLegend, 1.0);
161 m_legend->installEventFilter(this);
162
163 /*Plot Grid*/
164 m_grid = new QwtPlotGrid;
165 m_grid->enableXMin(true);
166 m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
167 m_grid->setMinorPen(QPen(Qt::gray, 1, Qt::DotLine));
168 m_grid->attach(m_plot);
169 m_grid->setVisible(false);
170
171 /*Plot Zoomer*/
172 m_zoomer = new QwtPlotZoomer(m_plot->canvas());
173 m_zoomer->setRubberBandPen(QPen(Qt::lightGray));
174 m_zoomer->setTrackerPen(QPen(Qt::lightGray));
175
176 setCentralWidget(m_plot);
177 setupDefaultMenu(optionsToProvide);
178 }
179
180
186 raise();
187 show();
188 }
189
190
197 void PlotWindow::update(MdiCubeViewport *activeViewport) {
198 }
199
200
208 void PlotWindow::setAxisLabel(int axisId, QString title) {
209 m_plot->setAxisTitle(axisId, title);
210 }
211
212
219 void PlotWindow::setPlotTitle(QString pt) {
220 m_plot->setTitle(pt);
221 }
222
223
231 void PlotWindow::setUserCanAddCurves(bool userHasControl) {
232 m_allowUserToAddCurves = userHasControl;
233 }
234
241 QString PlotWindow::plotTitle() const {
242 return m_plot->title().text();
243 }
244
245
256 }
257
258
269
270
281
282
290 m_plot->setCanvasBackground(c);
291 }
292
293
305 bool PlotWindow::canAdd(CubePlotCurve *curveToTest) const {
306 return (curveToTest->xUnits() == m_xAxisUnits &&
307 curveToTest->yUnits() == m_yAxisUnits);
308 }
309
310
318 return m_plot->canvasBackground().color();
319 }
320
321
329 QList<CubePlotCurve *> foundCurves;
330
331 const QwtPlotItemList &plotItems = m_plot->itemList();
332
333 for (int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
334 QwtPlotItem *item = plotItems[itemIndex];
335
336 if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
337 CubePlotCurve *curve = dynamic_cast<CubePlotCurve *>(item);
338
339 if (curve && curve->color().alpha() != 0)
340 foundCurves.append(curve);
341 }
342 }
343
344 return foundCurves;
345 }
346
347
356
357 const QwtPlotItemList &plotItems = m_plot->itemList();
358
359 for (int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
360 const QwtPlotItem *item = plotItems[itemIndex];
361
362 if (item->rtti() == QwtPlotItem::Rtti_PlotCurve) {
363 const CubePlotCurve *curve = dynamic_cast<const CubePlotCurve *>(item);
364
365 if (curve)
366 foundCurves.append(curve);
367 }
368 }
369
370 return foundCurves;
371 }
372
373
382 QList<QwtPlotSpectrogram *> foundSpectrograms;
383
384 const QwtPlotItemList &plotItems = m_plot->itemList();
385
386 for (int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
387 QwtPlotItem *item = plotItems[itemIndex];
388
389 if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
390 QwtPlotSpectrogram *spectrogram =
391 dynamic_cast<QwtPlotSpectrogram *>(item);
392
393 if (spectrogram)
394 foundSpectrograms.append(spectrogram);
395 }
396 }
397
398 return foundSpectrograms;
399 }
400
401
410 QList<const QwtPlotSpectrogram *> foundSpectrograms;
411
412 const QwtPlotItemList &plotItems = m_plot->itemList();
413
414 for (int itemIndex = 0; itemIndex < plotItems.size(); itemIndex++) {
415 const QwtPlotItem *item = plotItems[itemIndex];
416
417 if (item->rtti() == QwtPlotItem::Rtti_PlotSpectrogram) {
418 const QwtPlotSpectrogram *spectrogram =
419 dynamic_cast<const QwtPlotSpectrogram *>(item);
420
421 if (spectrogram)
422 foundSpectrograms.append(spectrogram);
423 }
424 }
425
426 return foundSpectrograms;
427 }
428
429
437 if (!canAdd(pc)) {
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 "
440 "x/y units");
441 }
442 else {
443 QString curveTitle = pc->title().text();
444
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) + ")";
451 }
452
453 titleTryCount++;
454 titleAccepted = true;
455
456 const QwtPlotItemList &plotItems = m_plot->itemList();
457
458 for (int itemIndex = 0; itemIndex < plotItems.size(); itemIndex ++) {
459 QwtPlotItem *item = plotItems[itemIndex];
460
461 if (item->title().text() == curveTitle)
462 titleAccepted = false;
463 }
464 }
465
466 pc->setTitle(curveTitle);
467 pc->attach(m_plot);
468 pc->attachMarkers();
469 fillTable();
470
472
473 connect(pc, SIGNAL(needsRepaint()),
474 this, SIGNAL(plotChanged()));
475 connect(pc, SIGNAL(destroyed(QObject *)),
476 this, SLOT(resetScale()));
477
478 // Get the legend widget for the recently attached plotcurve and give to the plotcurve
479 QWidget *legendWidget = m_legend->legendWidget( plot()->itemToInfo(pc) );
480 pc->updateLegendItemWidget(legendWidget);
481
482 replot();
483 }
484 }
485
486
494
495 /*Table Stuff if table is open*/
496 if (m_tableWindow != NULL && m_tableWindow->isVisible()) {
497 m_tableWindow->table()->setColumnCount(1);
498 m_tableWindow->table()->setRowCount(0);
499// deleteFromTable();
500 }
501 }
502
503
509 // make sure that there are CubePlotCurves to configure
511 // can't configure 0 curves - menu item is deactivated
512 if (curves.size() < 1) {
513 return;
514 }
515 CubePlotCurve *curve = curves.first();
516 CubePlotCurveConfigureDialog *configDialog = new CubePlotCurveConfigureDialog(curve, this);
517 configDialog->exec();
518
519 emit plotChanged();
520 }
521
522
531 dialog->show();
532 }
533
534
541 const QwtPlotItemList &plotItems = m_plot->itemList();
542
543 for (int itemIndex = plotItems.size()- 1; itemIndex >= 0; itemIndex --) {
544 QwtPlotItem *item = plotItems[itemIndex];
545
546 if (item->rtti() == QwtPlotItem::Rtti_PlotCurve ||
547 item->rtti() == QwtPlotItem::Rtti_PlotHistogram) {
548 delete item;
549 }
550 }
551
552 replot();
553 }
554
555
561 if (m_zoomer->trackerMode() == QwtPicker::ActiveOnly) {
562 m_zoomer->setTrackerMode(QwtPicker::AlwaysOn);
563 }
564 else {
565 m_zoomer->setTrackerMode(QwtPicker::ActiveOnly);
566 }
567 }
568
569
574 QPixmap pixmap;
575 /* Initialize a printer*/
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);
581
582 QPrintDialog printDialog(printer, (QWidget *)parent());
583
584 if (printDialog.exec() == QDialog::Accepted) {
585 /* Get display widget as a pixmap and convert to an image*/
586 pixmap = m_plot->grab();
587 QImage img = pixmap.toImage();
588 /* C++ Gui Programming with Qt, page 201*/
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);
597 }
598
599 }
600
601
607 QPixmap pixmap;
608 QString output =
609 QFileDialog::getSaveFileName((QWidget *)parent(),
610 "Choose output file",
611 "./",
612 QString("Images (*.png *.jpg *.tif)"));
613 if (output.isEmpty()) return;
614 //Make sure the filename is valid
615 if (!output.isEmpty()) {
616 if (!output.endsWith(".png") && !output.endsWith(".jpg") && !output.endsWith(".tif")) {
617 output = output + ".png";
618 }
619 }
620
621 QString format = QFileInfo(output).suffix();
622 pixmap = m_plot->grab();
623
624 std::string formatString = format.toStdString();
625 if (!pixmap.save(output, formatString.c_str())) {
626 QMessageBox::information((QWidget *)parent(), "Error", "Unable to save " + output);
627 return;
628 }
629 }
630
631
637 QPen *pen = new QPen(Qt::white);
638
639 if (m_plot->canvasBackground() == Qt::white) {
640 m_plot->setCanvasBackground(Qt::black);
641 m_grid->setMajorPen(QPen(Qt::white, 1, Qt::DotLine));
642 }
643 else {
644 m_plot->setCanvasBackground(Qt::white);
645 pen->setColor(Qt::black);
646 m_grid->setMajorPen(QPen(Qt::black, 1, Qt::DotLine));
647 }
648
649 m_zoomer->setRubberBandPen(*pen);
650 m_zoomer->setTrackerPen(*pen);
651 pen->setWidth(2);
652 /*Replot with the new background and pen colors*/
653 m_plot->replot();
654 }
655
656
662 m_zoomer->zoom(0);
663
664 if (m_autoscaleAxes) {
666 m_plot->setAxisAutoScale(QwtPlot::xBottom);
667 }
668 else {
669 QPair<double, double> calculatedXRange = findDataRange(
670 QwtPlot::xBottom);
671 m_plot->setAxisScale(QwtPlot::xBottom, calculatedXRange.first,
672 calculatedXRange.second);
673 }
674
676 m_plot->setAxisAutoScale(QwtPlot::yLeft);
677 }
678 else {
679 QPair<double, double> calculatedYRange = findDataRange(
680 QwtPlot::yLeft);
681 m_plot->setAxisScale(QwtPlot::yLeft, calculatedYRange.first,
682 calculatedYRange.second);
683 }
684 }
685
686 m_zoomer->setZoomBase();
687 m_plot->replot();
688 }
689
690
696 if (m_xLogCheckBox->isChecked()) {
697 m_plot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLogScaleEngine);
698 m_plotXLogScale = true;
699 }
700 else {
701 m_plot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
702 m_plotXLogScale = false;
703 }
704
705 if (m_yLogCheckBox->isChecked()) {
706 m_plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine);
707 m_plotYLogScale = true;
708 }
709 else {
710 m_plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
711 m_plotYLogScale = false;
712 }
713
715
716 if (!m_autoscaleAxes) {
717 double xMin = m_xMinEdit->text().toDouble();
718 double xMax = m_xMaxEdit->text().toDouble();
719 // QwtScaleDiv xAxisScale =
720 // m_plot->axisScaleEngine(QwtPlot::xBottom)->divideScale(xMin, xMax,
721 // 25, 100);
722 // m_plot->setAxisScaleDiv(QwtPlot::xBottom, xAxisScale);
723 m_plot->setAxisScale(QwtPlot::xBottom, xMin, xMax);
724
725 double yMin = m_yMinEdit->text().toDouble();
726 double yMax = m_yMaxEdit->text().toDouble();
727 // QwtScaleDiv yAxisScale =
728 // m_plot->axisScaleEngine(QwtPlot::yLeft)->divideScale(yMin, yMax,
729 // 25, 100);
730 // m_plot->setAxisScaleDiv(QwtPlot::yLeft, yAxisScale);
731 m_plot->setAxisScale(QwtPlot::yLeft, yMin, yMax);
732
733 m_zoomer->setZoomBase();
734 }
735
736 replot();
737 }
738
739
745 QDialog *dialog = new QDialog(this);
746 dialog->setWindowTitle("Set Display Range");
747
748 QGridLayout *dialogLayout = new QGridLayout;
749
750 int row = 0;
751
752 QLabel *autoLabel = new QLabel("Auto-Scale: ");
753 dialogLayout->addWidget(autoLabel, row, 0);
754
755 m_autoScaleCheckBox = new QCheckBox("Scale X/Y Axes Automatically");
757 connect(m_autoScaleCheckBox, SIGNAL(stateChanged(int)),
758 this, SLOT(autoScaleCheckboxToggled()));
759 dialogLayout->addWidget(m_autoScaleCheckBox, row, 1);
760 row++;
761
762 QLabel *xLabel = new QLabel("<h3>X-Axis</h3>");
763 dialogLayout->addWidget(xLabel, row, 0, 1, 2);
764 row++;
765
766 QLabel *xMinLabel = new QLabel("Minimum: ");
767 dialogLayout->addWidget(xMinLabel, row, 0);
768
769 double xMin = plot()->axisScaleDiv(QwtPlot::xBottom).lowerBound();
770 m_xMinEdit = new QLineEdit(QString::number(xMin));
771 dialogLayout->addWidget(m_xMinEdit, row, 1);
772 row++;
773
774 QLabel *xMaxLabel = new QLabel("Maximum: ");
775 dialogLayout->addWidget(xMaxLabel, row, 0);
776
777 double xMax = plot()->axisScaleDiv(QwtPlot::xBottom).upperBound();
778 m_xMaxEdit = new QLineEdit(QString::number(xMax));
779 dialogLayout->addWidget(m_xMaxEdit, row, 1);
780 row++;
781
782 QLabel *xLogLabel = new QLabel("Logarithmic Scale");
783 dialogLayout->addWidget(xLogLabel, row, 0);
784
785 m_xLogCheckBox = new QCheckBox;
786 m_xLogCheckBox->setChecked(m_plotXLogScale);
787// m_xLogCheckBox->setChecked(
788// m_plot->axisScaleEngine(QwtPlot::xBottom)->transformation()->type() ==
789// QwtScaleTransformation::Log10);
790 dialogLayout->addWidget(m_xLogCheckBox, row, 1);
791 row++;
792
793 QLabel *yLabel = new QLabel("<h3>Y-Axis</h3>");
794 dialogLayout->addWidget(yLabel, row, 0, 1, 2);
795 row++;
796
797 QLabel *yMinLabel = new QLabel("Minimum: ");
798 dialogLayout->addWidget(yMinLabel, row, 0);
799
800 double yMin = plot()->axisScaleDiv(QwtPlot::yLeft).lowerBound();
801 m_yMinEdit = new QLineEdit(QString::number(yMin));
802 dialogLayout->addWidget(m_yMinEdit, row, 1);
803 row++;
804
805 QLabel *yMaxLabel = new QLabel("Maximum: ");
806 dialogLayout->addWidget(yMaxLabel, row, 0);
807
808 double yMax = plot()->axisScaleDiv(QwtPlot::yLeft).upperBound();
809 m_yMaxEdit = new QLineEdit(QString::number(yMax));
810 dialogLayout->addWidget(m_yMaxEdit, row, 1);
811 row++;
812
813 QLabel *yLogLabel = new QLabel("Logarithmic Scale");
814 dialogLayout->addWidget(yLogLabel, row, 0);
815
816 m_yLogCheckBox = new QCheckBox;
817 m_yLogCheckBox->setChecked(m_plotYLogScale);
818// m_yLogCheckBox->setChecked(
819// m_plot->axisScaleEngine(QwtPlot::yLeft)->transformation()->type() ==
820// QwtScaleTransformation::Log10);
821 dialogLayout->addWidget(m_yLogCheckBox, row, 1);
822 row++;
823
824 QHBoxLayout *buttonsLayout = new QHBoxLayout;
825 buttonsLayout->addStretch();
826
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);
833
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);
838
839 QWidget *buttonsWrapper = new QWidget;
840 buttonsWrapper->setLayout(buttonsLayout);
841 dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
842 row++;
843
845
846 dialog->setLayout(dialogLayout);
847 dialog->show();
848 }
849
850
856 QDialog *dialog = new QDialog(this);
857 dialog->setWindowTitle("Name Plot Labels");
858
859 QGridLayout *dialogLayout = new QGridLayout;
860
861 int row = 0;
862 QLabel *plotLabel = new QLabel("Plot Title: ");
863 dialogLayout->addWidget(plotLabel, row, 0);
864
865 m_plotTitleText = new QLineEdit(plot()->title().text());
866 dialogLayout->addWidget(m_plotTitleText, row, 1);
867 row++;
868
869 QLabel *xAxisLabel = new QLabel("X-Axis Label: ");
870 dialogLayout->addWidget(xAxisLabel, row, 0);
871
872 m_xAxisText = new QLineEdit(m_plot->axisTitle(QwtPlot::xBottom).text());
873 dialogLayout->addWidget(m_xAxisText, row, 1);
874 row++;
875
876 QLabel *yAxisLabel = new QLabel("Y-Axis Label: ");
877 dialogLayout->addWidget(yAxisLabel, row, 0);
878
879 m_yAxisText = new QLineEdit(m_plot->axisTitle(QwtPlot::yLeft).text());
880 dialogLayout->addWidget(m_yAxisText, row, 1);
881 row++;
882
883 QHBoxLayout *buttonsLayout = new QHBoxLayout;
884 buttonsLayout->addStretch();
885
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);
892
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);
897
898 QWidget *buttonsWrapper = new QWidget;
899 buttonsWrapper->setLayout(buttonsLayout);
900 dialogLayout->addWidget(buttonsWrapper, row, 0, 1, 2);
901 row++;
902
903 dialog->setLayout(dialogLayout);
904 dialog->show();
905 }
906
907
912 m_plot->setTitle(m_plotTitleText->text());
913 m_plot->setAxisTitle(QwtPlot::xBottom, m_xAxisText->text());
914 m_plot->setAxisTitle(QwtPlot::yLeft, m_yAxisText->text());
915 /*Replot with new labels.*/
916 m_plot->replot();
917 }
918
919
925 m_grid->setVisible(!m_grid->isVisible());
926
927 if (m_grid->isVisible()) {
928 m_showHideGrid->setText("Hide Grid");
929 }
930 else {
931 m_showHideGrid->setText("Show Grid");
932 }
933 m_plot->replot();
934 }
935
936
941 void (QwtPlotItem::*method)();
942 if (m_showHideAllMarkers->text() == "Hide All Symbols") {
943 method = &QwtPlotItem::hide;
944
945 m_showHideAllMarkers->setText("Show All Symbols");
946
947 }
948 else {
949 method = &QwtPlotItem::show;
950
951 m_showHideAllMarkers->setText("Hide All Symbols");
952 }
953
954 for (int i = 0; i < m_plot->itemList().size(); i ++) {
955 QwtPlotItem *plotItem = m_plot->itemList()[i];
956 if (plotItem->rtti() == QwtPlotItem::Rtti_PlotMarker)
957 (plotItem->*method)();
958 }
959 /*Replot with all symbols hidden*/
960 m_plot->replot();
961 }
962
963
969 void (QwtPlotItem::*method)();
970 if (m_showHideAllCurves->text() == "Hide All Curves") {
971 method = &QwtPlotItem::hide;
972
973 m_showHideAllCurves->setText("Show All Curves");
974 m_showHideAllCurves->setIcon(
975 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
976
977 }
978 else {
979 method = &QwtPlotItem::show;
980
981 m_showHideAllCurves->setText("Hide All Curves");
982 m_showHideAllCurves->setIcon(
983 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_hideCurves.png").expanded()));
984 }
985
986 for (int i = 0; i < m_plot->itemList().size(); i ++) {
987 QwtPlotItem *plotItem = m_plot->itemList()[i];
988 if (plotItem->rtti() == QwtPlotItem::Rtti_PlotCurve)
989 (plotItem->*method)();
990 }
991 /*Replot with all curves hidden*/
992 m_plot->replot();
993 }
994
995
1001 QDialog *d = new QDialog(m_plot);
1002 d->setWindowTitle("Basic Help");
1003
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");
1011
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()));
1018
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()));
1024
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);
1036
1037 d->setLayout(layout);
1038 d->show();
1039 }
1040
1041
1050 QList<QMenu *> menu;
1051 QList<QAction *> actions;
1052
1053 QMenu *fileMenu = new QMenu("&File");
1054 QMenu *editMenu = new QMenu("&Edit");
1055 QMenu *optionsMenu = new QMenu("&Options");
1056 QMenu *helpMenu = new QMenu("&Help");
1057
1058 if ((optionsToProvide & SaveMenuOption) == SaveMenuOption) {
1059 QAction *save = new QAction(m_plot);
1060 save->setText("&Save Plot As");
1061 save->setIcon(QIcon::fromTheme("document-save-as"));
1062 QString text =
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);
1068 }
1069
1070 if ((optionsToProvide & PrintMenuOption) == PrintMenuOption) {
1071 QAction *prt = new QAction(m_plot);
1072 prt->setText("&Print Plot");
1073 prt->setIcon(QIcon::fromTheme("document-print"));
1074 QString text =
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);
1080 }
1081
1082 if ((optionsToProvide & ShowTableMenuOption) == ShowTableMenuOption) {
1083 QAction *table = new QAction(m_plot);
1084 table->setText("Show Table");
1085 table->setIcon(
1086 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_table.png").expanded()));
1087 QString text =
1088 "<b>Function:</b> Activates the table which displays the data of the "
1089 "current plot";
1090 table->setWhatsThis(text);
1091 connect(table, SIGNAL(triggered()), this, SLOT(showTable()));
1092 fileMenu->addAction(table);
1093 actions.push_back(table);
1094 }
1095
1096 QAction *close = new QAction(QIcon::fromTheme("document-close"), "&Close",
1097 m_plot);
1098 connect(close, SIGNAL(triggered()), this, SLOT(close()));
1099 fileMenu->addAction(close);
1100
1101 if ((optionsToProvide & TrackMenuOption) == TrackMenuOption) {
1102 QAction *track = new QAction(m_plot);
1103 track->setText("Show Mouse &Tracking");
1104 track->setIcon(
1105 QPixmap(FileName("$ISISROOT/appdata/images/icons/goto.png").expanded()));
1106 track->setCheckable(true);
1107 QString text =
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);
1113 }
1114
1115 if ((optionsToProvide & BackgroundSwitchMenuOption) ==
1117 QAction *backgrdSwitch = new QAction(m_plot);
1118 backgrdSwitch->setText("White/Black &Background");
1119 backgrdSwitch->setIcon(
1120 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_switchBackgrd.png").expanded()));
1121 QString text =
1122 "<b>Function:</b> Switch the background color between black and "
1123 "white.";
1124 backgrdSwitch->setWhatsThis(text);
1125 connect(backgrdSwitch, SIGNAL(triggered()),
1126 this, SLOT(switchBackground()));
1127 optionsMenu->addAction(backgrdSwitch);
1128 actions.push_back(backgrdSwitch);
1129 }
1130
1131 if ((optionsToProvide & ShowHideGridMenuOption) == ShowHideGridMenuOption) {
1133 m_showHideGrid->setText("Show Grid");
1134 m_showHideGrid->setIcon(
1135 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_grid.png").expanded()));
1136 QString text =
1137 "<b>Function:</b> Display grid lines on the plot.";
1138 m_showHideGrid->setWhatsThis(text);
1139 connect(m_showHideGrid, SIGNAL(triggered()), this, SLOT(showHideGrid()));
1140 optionsMenu->addAction(m_showHideGrid);
1141 actions.push_back(m_showHideGrid);
1142 }
1143
1144 if ((optionsToProvide & RenameLabelsMenuOption) == RenameLabelsMenuOption) {
1145 QAction *changeLabels = new QAction(m_plot);
1146 changeLabels->setText("Rename Plot &Labels");
1147 changeLabels->setIcon(
1148 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_renameLabels.png").expanded()));
1149 QString text =
1150 "<b>Function:</b> Edit the plot title, x and y axis labels.";
1151 changeLabels->setWhatsThis(text);
1152 connect(changeLabels, SIGNAL(triggered()),
1153 this, SLOT(changePlotLabels()));
1154 optionsMenu->addAction(changeLabels);
1155 actions.push_back(changeLabels);
1156 }
1157
1158 if ((optionsToProvide & SetDisplayRangeMenuOption) ==
1160 QAction *changeScale = new QAction(m_plot);
1161 changeScale->setText("Set &Display Range");
1162 changeScale->setIcon(
1163 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_setScale.png").expanded()));
1164 QString text =
1165 "<b>Function:</b> Adjust the scale for the x and y axis on the "
1166 "plot.";
1167 changeScale->setWhatsThis(text);
1168 connect(changeScale, SIGNAL(triggered()), this, SLOT(setDefaultRange()));
1169 optionsMenu->addAction(changeScale);
1170 actions.push_back(changeScale);
1171 }
1172
1173 if ((optionsToProvide & ShowHideCurvesMenuOption) ==
1176 m_showHideAllCurves->setText("Hide All Curves");
1177 m_showHideAllCurves->setIcon(
1178 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_showCurves.png").expanded()));
1179 QString text =
1180 "<b>Function:</b> Displays or hides all the curves currently "
1181 "displayed on the plot.";
1182 m_showHideAllCurves->setWhatsThis(text);
1183 connect(m_showHideAllCurves, SIGNAL(triggered()),
1184 this, SLOT(showHideAllCurves()));
1185 optionsMenu->addAction(m_showHideAllCurves);
1186 actions.push_back(m_showHideAllCurves);
1187 }
1188
1189 if ((optionsToProvide & ShowHideMarkersMenuOption) ==
1192 m_showHideAllMarkers->setText("Hide All Symbols");
1193 m_showHideAllMarkers->setIcon(
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.";
1197 m_showHideAllMarkers->setWhatsThis(text);
1198 connect(m_showHideAllMarkers, SIGNAL(triggered()),
1199 this, SLOT(showHideAllMarkers()));
1200 optionsMenu->addAction(m_showHideAllMarkers);
1201 actions.push_back(m_showHideAllMarkers);
1202 }
1203
1204 if ((optionsToProvide & ResetScaleMenuOption) == ResetScaleMenuOption) {
1205 QAction *resetScaleButton = new QAction(m_plot);
1206 resetScaleButton->setText("Reset Scale");
1207 resetScaleButton->setIcon(
1208 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_resetscale.png").expanded()));
1209 QString text =
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);
1214 }
1215
1216 if ((optionsToProvide & ClearPlotMenuOption) == ClearPlotMenuOption) {
1217 QAction *clear = new QAction(m_plot);
1218 clear->setText("Clear Plot");
1219 clear->setIcon(
1220 QPixmap(FileName("$ISISROOT/appdata/images/icons/plot_clear.png").expanded()));
1221 QString text =
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);
1226 }
1227
1228 if ((optionsToProvide & LineFitMenuOption) == LineFitMenuOption) {
1229 QAction *lineFit = new QAction(m_plot);
1230 lineFit->setText("Create Best Fit Line");
1231 lineFit->setIcon(
1232 QPixmap(FileName("$ISISROOT/appdata/images/icons/linefit.png").expanded()));
1233 QString text = "<b>Function:</b> Calculates a best fit line from an "
1234 "existing curve.";
1235 lineFit->setWhatsThis(text);
1236 connect(lineFit, SIGNAL(triggered()), this, SLOT( createBestFitLine() ) );
1237 optionsMenu->addAction(lineFit);
1238 actions.push_back(lineFit);
1239 }
1240
1241 if ((optionsToProvide & ConfigurePlotMenuOption) == ConfigurePlotMenuOption) {
1242 QAction *configurePlot = new QAction(m_plot);
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 "
1247 "curves.";
1248 configurePlot->setWhatsThis(text);
1249 connect( configurePlot, SIGNAL( triggered() ),
1250 this, SLOT( configurePlotCurves() ) );
1251 optionsMenu->addAction(configurePlot);
1252 actions.push_back(configurePlot);
1253 }
1254
1255 QAction *basicHelp = new QAction(m_plot);
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() ),
1261 this, SLOT( showHelp() ) );
1262 helpMenu->addAction(basicHelp);
1263
1264 /*setup menus*/
1265 m_pasteAct = new QAction(QIcon::fromTheme("edit-paste"),
1266 "&Paste Curve", m_plot);
1267 m_pasteAct->setEnabled(false);
1268 m_pasteAct->setShortcut(Qt::CTRL | Qt::Key_V);
1269 connect(m_pasteAct, SIGNAL(triggered()),
1270 this, SLOT(pasteCurve()));
1271 editMenu->addAction(m_pasteAct);
1272
1273 menu.push_back(fileMenu);
1274 menu.push_back(editMenu);
1275
1276 if (optionsMenu->actions().size()) {
1277 menu.push_back(optionsMenu);
1278 }
1279 else {
1280 delete optionsMenu;
1281 optionsMenu = NULL;
1282 }
1283
1284 if (helpMenu->actions().size()) {
1285 menu.push_back(helpMenu);
1286 }
1287 else {
1288 delete helpMenu;
1289 helpMenu = NULL;
1290 }
1291
1292 setMenus(menu, actions);
1293 }
1294
1295
1307 bool PlotWindow::userCanAddCurve(const QMimeData *curve) {
1308 bool userCanAdd = false;
1309
1311 curve->hasFormat("application/isis3-plot-curve")) {
1312
1313 CubePlotCurve * testCurve = new CubePlotCurve(
1314 curve->data("application/isis3-plot-curve"));
1315
1316 userCanAdd = canAdd(testCurve);
1317 }
1318
1319 return userCanAdd;
1320 }
1321
1322
1332 if (m_showHideAllCurves) {
1333 if (m_showHideAllCurves->text() == "Hide All Curves") {
1334 curve->show();
1335 }
1336 else {
1337 curve->hide();
1338 }
1339
1340 if (m_showHideAllMarkers->text() == "Hide All Symbols") {
1341 curve->setMarkerVisible(true);
1342 }
1343 else {
1344 curve->setMarkerVisible(false);
1345 }
1346 }
1347
1348 emit plotChanged();
1349 }
1350
1351
1360 if (m_toolBar == NULL) {
1361 m_toolBar = new QToolBar(this);
1362 m_toolBar->setObjectName("PlotWindow");
1363 m_toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea);
1364 addToolBar(Qt::TopToolBarArea, m_toolBar);
1365 }
1366 else {
1367 m_toolBar->clear();
1368 }
1369
1370 m_menubar = menuBar();
1371 m_menubar->clear();
1372
1373 for (int i = 0; i < menu.size(); i++) {
1374 m_menubar->addMenu(menu[i]);
1375 }
1376
1377 for (int i = 0; i < actions.size(); i++) {
1378 m_toolBar->addAction(actions[i]);
1379 }
1380
1381 }
1382
1383
1389 QwtPlotZoomer *PlotWindow::zoomer() {
1390 return m_zoomer;
1391 }
1392
1393
1401 if (!m_scheduledFillTable) {
1402 m_scheduledFillTable = true;
1403 emit requestFillTable();
1404 }
1405 }
1406
1407
1413 m_scheduledFillTable = false;
1414
1415 if (m_tableWindow == NULL) return;
1416 m_tableWindow->listWidget()->clear();
1417 m_tableWindow->table()->clear();
1418 m_tableWindow->table()->setRowCount(0);
1419 m_tableWindow->table()->setColumnCount(0);
1420
1421 m_tableWindow->addToTable(true,
1422 m_plot->axisTitle(QwtPlot::xBottom).text(),
1423 m_plot->axisTitle(QwtPlot::xBottom).text());
1424
1426 foreach (CubePlotCurve *curve, curves) {
1427 m_tableWindow->addToTable(true,
1428 curve->title().text(),
1429 curve->title().text());
1430 }
1431
1432 // We really need all of the x-values associated with the curves,
1433 // but qwt doesn't seem to want to give this to us. It'll give us the
1434 // axis scale, but that isn't quite what we want (especially when zooming)
1435 // So let's find the list of x-points ourselves.
1436 //
1437 // This is what I tried and it did NOT work:
1438 // QwtScaleDiv *xAxisScaleDiv = m_plot->axisScaleDiv(QwtPlot::xBottom);
1439 // QList<double> xAxisPoints = xAxisScaleDiv->ticks(QwtScaleDiv::MajorTick);
1440 //
1441 // We're going to keep xAxisPoints in standard text sort order until we're done populating it,
1442 // then we'll re-sort numerically. That enables us to effectively use binary searches and
1443 // insertion sort-like capabilities for speed.
1444 QList<QString> xAxisPoints;
1445
1446 QProgressDialog progress(tr("Re-calculating Table"), tr(""), 0, 1000, this);
1447 double percentPerCurve = 0.5 * 1.0 / curves.count();
1448
1449 for (int curveIndex = 0; curveIndex < curves.count(); curveIndex++) {
1450 progress.setValue(qRound(curveIndex * percentPerCurve * 1000.0));
1451
1452 CubePlotCurve *curve = curves[curveIndex];
1453
1454 double percentPerDataIndex = (1.0 / curve->data()->size()) * percentPerCurve;
1455
1456 // Loop backwards because our insertion sort will have a much better
1457 // chance of success on it's first try this way.
1458 for (int dataIndex = (int)curve->data()->size() - 1;
1459 dataIndex >= 0;
1460 dataIndex--) {
1461 double xValue = curve->data()->sample(dataIndex).x();
1462 QString xValueString = toString(xValue);
1463
1464 int inverseDataIndex = (curve->data()->size() - 1) - dataIndex;
1465 progress.setValue(
1466 qRound( ((curveIndex * percentPerCurve) +
1467 (inverseDataIndex * percentPerDataIndex)) * 1000.0));
1468
1469
1470 bool foundPos = std::binary_search(xAxisPoints.begin(), xAxisPoints.end(), xValueString);
1471
1472 if (!foundPos) {
1473 bool inserted = false;
1474
1475 for (int searchIndex = 0;
1476 searchIndex < xAxisPoints.size() && !inserted;
1477 searchIndex++) {
1478 if (xAxisPoints[searchIndex] > xValueString) {
1479 inserted = true;
1480 xAxisPoints.insert(searchIndex, xValueString);
1481 }
1482 }
1483
1484 if (!inserted)
1485 xAxisPoints.append(xValueString);
1486 }
1487 }
1488 }
1489
1490 sort(xAxisPoints.begin(), xAxisPoints.end(), &numericStringLessThan);
1491
1492 m_tableWindow->table()->setRowCount(xAxisPoints.size());
1493
1494 QList<int> lastSuccessfulSamples;
1495
1496 for (int i = 0; i < curves.count(); i++) {
1497 lastSuccessfulSamples.append(-1);
1498 }
1499
1500 double progressPerRow = 0.5 * 1.0 / m_tableWindow->table()->rowCount();
1501
1502 for (int row = 0; row < m_tableWindow->table()->rowCount(); row++) {
1503 progress.setValue(500 + qRound(row * progressPerRow * 1000.0));
1504
1505 QString xValueString = xAxisPoints[row];
1506 double xValue = toDouble(xValueString);
1507
1508 QTableWidgetItem *xAxisItem = new QTableWidgetItem(xValueString);
1509 m_tableWindow->table()->setItem(row, 0, xAxisItem);
1510
1511 if (row == m_tableWindow->table()->rowCount() - 1) {
1512 m_tableWindow->table()->resizeColumnToContents(0);
1513 }
1514
1515 // Now search for the x-axis points in the curves to fill in data
1516 for (int col = 1; col < m_tableWindow->table()->columnCount(); col++) {
1517 CubePlotCurve *curve = curves[col - 1];
1518
1519 double y = Null;
1520 bool tooFar = false;
1521
1522 for (int dataIndex = lastSuccessfulSamples[col - 1] + 1;
1523 dataIndex < (int)curve->data()->size() && y == Null && !tooFar;
1524 dataIndex++) {
1525
1526 if (toString(curve->data()->sample(dataIndex).x()) == xValueString) {
1527 // Try to compensate for decreasing x values by not performing this optimization
1528 if (dataIndex > 0 &&
1529 curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x()) {
1530 lastSuccessfulSamples[col - 1] = dataIndex;
1531 }
1532 y = curve->data()->sample(dataIndex).y();
1533 }
1534 // Try to compensate for decreasing X values in the too far computation
1535 else if (dataIndex > 0 &&
1536 curve->data()->sample(dataIndex - 1).x() < curve->data()->sample(dataIndex).x() &&
1537 curve->data()->sample(dataIndex).x() > xValue) {
1538 tooFar = true;
1539 }
1540 }
1541
1542 QTableWidgetItem *item = NULL;
1543
1544 if (IsSpecial(y))
1545 item = new QTableWidgetItem(QString("N/A"));
1546 else
1547 item = new QTableWidgetItem(toString(y));
1548
1549 m_tableWindow->table()->setItem(row, col, item);
1550
1551 if (row == m_tableWindow->table()->rowCount() - 1) {
1552 m_tableWindow->table()->resizeColumnToContents(col);
1553 }
1554 }
1555 }
1556 }
1557
1558
1565 if (plotCurves().size()) {
1566 if (m_tableWindow == NULL) {
1567 //m_tableWindow = new TableMainWindow("Plot Table", this);
1568 m_tableWindow = new TableMainWindow("Plot Table", m_parent);
1569 m_tableWindow->setTrackListItems(false);
1570 }
1571
1572 fillTable();
1573 m_tableWindow->show();
1574 m_tableWindow->syncColumns();
1575 }
1576 }
1577
1578
1588 bool PlotWindow::eventFilter(QObject *o, QEvent *e) {
1589 bool blockWidgetFromEvent = false;
1590
1591 switch (e->type()) {
1592 case QEvent::MouseButtonPress:
1593 if (o == this &&
1594 childAt(((QMouseEvent *)e)->pos()) != plot()->canvas()) {
1595 mousePressEvent(o, (QMouseEvent *)e);
1596 blockWidgetFromEvent = true;
1597 }
1598 break;
1599
1600 default:
1601 break;
1602 }
1603
1604 bool stopHandlingEvent = false;
1605 if (!blockWidgetFromEvent && o == this) {
1606 stopHandlingEvent = MainWindow::eventFilter(o, e);
1607
1608 if (e->type() == QEvent::Close && !stopHandlingEvent) {
1609 emit closed();
1610 }
1611 }
1612
1613 return stopHandlingEvent || blockWidgetFromEvent;
1614 }
1615
1616
1626 void PlotWindow::mousePressEvent(QObject *object, QMouseEvent *event) {
1627 if (qobject_cast<QWidget *>(object) &&
1628 event->button() == Qt::RightButton &&
1629 userCanAddCurve(QApplication::clipboard()->mimeData())) {
1630 QMenu contextMenu;
1631
1632 QAction *pasteAct = new QAction(QIcon::fromTheme("edit-paste"), "Paste",
1633 this);
1634 contextMenu.addAction(pasteAct);
1635
1636 QAction *chosenAct = contextMenu.exec(
1637 qobject_cast<QWidget *>(object)->mapToGlobal(event->pos()));
1638
1639 if (chosenAct == pasteAct) {
1640 pasteCurve();
1641 }
1642 }
1643 }
1644
1645
1652 return m_plot;
1653 }
1654
1655
1665
1666
1674 m_xMinEdit->setEnabled(!m_autoScaleCheckBox->isChecked());
1675 m_xMaxEdit->setEnabled(!m_autoScaleCheckBox->isChecked());
1676 m_yMinEdit->setEnabled(!m_autoScaleCheckBox->isChecked());
1677 m_yMaxEdit->setEnabled(!m_autoScaleCheckBox->isChecked());
1678 }
1679
1680
1685 m_pasteAct->setEnabled(
1686 userCanAddCurve(QApplication::clipboard()->mimeData()));
1687 }
1688
1689
1697 QClipboard *globalClipboard = QApplication::clipboard();
1698 const QMimeData *globalData = globalClipboard->mimeData();
1699
1700 if (globalData->hasFormat("application/isis3-plot-curve")) {
1701 CubePlotCurve * newCurve = new CubePlotCurve(
1702 globalData->data("application/isis3-plot-curve"));
1703 // add curve to plot
1704 add(newCurve);
1705 emit plotChanged();
1706 }
1707 }
1708 }
1709
1710
1720 QPair<double, double> PlotWindow::findDataRange(int axisId) const {
1722
1723 bool foundDataValue = false;
1724 QPair<double, double> rangeMinMax;
1725
1726 foreach(const CubePlotCurve *curve, curves) {
1727 for (int dataIndex = 0; dataIndex < (int)curve->dataSize(); dataIndex++) {
1728 if (axisId == QwtPlot::xBottom) {
1729 if (!foundDataValue) {
1730 rangeMinMax.first = curve->sample(dataIndex).x();
1731 rangeMinMax.second = curve->sample(dataIndex).x();
1732 foundDataValue = true;
1733 }
1734 else {
1735 rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).x());
1736 rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).x());
1737 }
1738 }
1739 else if (axisId == QwtPlot::yLeft) {
1740 if (!foundDataValue) {
1741 rangeMinMax.first = curve->sample(dataIndex).y();
1742 rangeMinMax.second = curve->sample(dataIndex).y();
1743 foundDataValue = true;
1744 }
1745 else {
1746 rangeMinMax.first = qMin(rangeMinMax.first, curve->sample(dataIndex).y());
1747 rangeMinMax.second = qMax(rangeMinMax.second, curve->sample(dataIndex).y());
1748 }
1749 }
1750 }
1751 }
1752
1753 if (!foundDataValue) {
1754 rangeMinMax.first = 1;
1755 rangeMinMax.second = 10;
1756 }
1757 else if(rangeMinMax.first == rangeMinMax.second) {
1758 rangeMinMax.first -= 0.5;
1759 rangeMinMax.second += 0.5;
1760 }
1761
1762 return rangeMinMax;
1763 }
1764
1765
1766 bool PlotWindow::numericStringLessThan(QString left, QString right) {
1767 bool result = false;
1768
1769 try {
1770 result = toDouble(left) < toDouble(right);
1771 }
1772 catch (IException &) {
1773 }
1774
1775 return result;
1776 }
1777
1778
1785 void PlotWindow::paint(MdiCubeViewport *vp, QPainter *painter) {
1786 foreach (CubePlotCurve *curve, plotCurves()) {
1787 curve->paint(vp, painter);
1788 }
1789 }
1790
1791
1796 resetScale();
1797 emit plotChanged();
1798 }
1799
1800
1809 return "Plot";
1810 }
1811
1812
1821 void PlotWindow::dragEnterEvent(QDragEnterEvent *event) {
1822 QObject *source = event->source();
1823
1824 if (source != m_legend->contentsWidget() &&
1825 userCanAddCurve(event->mimeData())) {
1826 event->acceptProposedAction();
1827 }
1828 }
1829
1830
1842 void PlotWindow::dropEvent(QDropEvent *event) {
1844 event->mimeData()->hasFormat("application/isis3-plot-curve")) {
1845 Qt::DropActions possibleActions = event->possibleActions();
1846 Qt::DropAction actionToTake = event->proposedAction();
1847
1848 QFont boldFont;
1849 boldFont.setBold(true);
1850 QMenu dropActionsMenu;
1851
1852 QAction *copyAct = new QAction("&Copy Here", this);
1853 if (possibleActions.testFlag(Qt::CopyAction)) {
1854 dropActionsMenu.addAction(copyAct);
1855
1856 if (actionToTake == Qt::CopyAction)
1857 copyAct->setFont(boldFont);
1858 }
1859
1860 QAction *moveAct = new QAction("&Move Here", this);
1861 if (possibleActions.testFlag(Qt::MoveAction)) {
1862 dropActionsMenu.addAction(moveAct);
1863
1864 if (actionToTake == Qt::MoveAction)
1865 moveAct->setFont(boldFont);
1866 }
1867
1868 if (dropActionsMenu.actions().size() > 1) {
1869 dropActionsMenu.addSeparator();
1870
1871 QAction *cancelAct = new QAction("&Cancel", this);
1872 dropActionsMenu.addAction(cancelAct);
1873
1874 QAction *chosenAct = dropActionsMenu.exec(mapToGlobal(event->pos()));
1875
1876 if (chosenAct == copyAct) {
1877 actionToTake = Qt::CopyAction;
1878 }
1879 else if (chosenAct == moveAct) {
1880 actionToTake = Qt::MoveAction;
1881 }
1882 else {
1883 actionToTake = Qt::IgnoreAction;
1884 }
1885 }
1886
1887 if (actionToTake != Qt::IgnoreAction) {
1888 CubePlotCurve * newCurve = new CubePlotCurve(
1889 event->mimeData()->data("application/isis3-plot-curve"));
1890 // add curve to plot
1891 add(newCurve);
1892 emit plotChanged();
1893
1894 event->setDropAction(actionToTake);
1895 event->accept();
1896 }
1897 }
1898 }
1899
1900}
This should be an inner class for CubePlotCurve, but Qt doesn't support having a QObject as an inner ...
This is a plot curve with information relating it to a particular cube or region of a cube.
void paint(CubeViewport *vp, QPainter *painter)
Use information inside of the plot curve to paint onto a cube viewport.
void updateLegendItemWidget(QWidget *legendItem)
This creates a legend item and overrides events from it.
MainWindow(QString title, QWidget *parent=0, Qt::WindowFlags flags=Qt::WindowFlags())
Mainwindow constructor.
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.
QColor color() const
This method returns the color of the curve.
Definition PlotCurve.cpp:55
Units yUnits() const
Get the units of the y-axis double data.
Definition PlotCurve.cpp:85
Units xUnits() const
Get the units of the x-axis double data.
Definition PlotCurve.cpp:75
void attachMarkers()
After attaching this curve to a plot, due to an inheritance/implementation complication with qwt the ...
Definition PlotCurve.cpp:45
Units
These are all the possible units for the x or y data in a plot curve.
Definition PlotCurve.h:54
@ Elevation
The data is an elevation (in meters).
Definition PlotCurve.h:71
@ Band
The data is a band number.
Definition PlotCurve.h:63
@ CubeDN
The data is a Cube DN value.
Definition PlotCurve.h:67
@ Wavelength
The data is a wavelength.
Definition PlotCurve.h:92
@ Kilometers
The data is in kilometers.
Definition PlotCurve.h:87
@ PixelNumber
The data is a pixel #.
Definition PlotCurve.h:79
@ Meters
The data is in meters.
Definition PlotCurve.h:83
@ Percentage
The data is a percentage (0-100).
Definition PlotCurve.h:75
void setMarkerVisible(bool visible)
This method sets the visibility states of the markers at each value point.
QLineEdit * m_plotTitleText
Set Labels Dialog's edit for the plot title.
Definition PlotWindow.h:297
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.
Definition PlotWindow.h:312
QwtPlot * m_plot
The plot in this window.
Definition PlotWindow.h:328
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.
Definition PlotWindow.h:285
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.
Definition PlotWindow.h:330
void plotChanged()
Emitted every time there is a change to the plot window.
QMenuBar * m_menubar
Plot window's menu bar.
Definition PlotWindow.h:300
QLineEdit * m_xMaxEdit
Set Scale Dialog's edit for the max X-axis value.
Definition PlotWindow.h:287
QLineEdit * m_yMinEdit
Set Scale Dialog's edit for the min Y-axis value.
Definition PlotWindow.h:289
bool m_allowUserToAddCurves
Is the window showing the curve markers?
Definition PlotWindow.h:324
QString plotTitle() const
Returns the plot title.
QLineEdit * m_xAxisText
Set Labels Dialog's edit for the x-axis label.
Definition PlotWindow.h:293
void showHideAllCurves()
This method shows or hides all of the curves in the plotWindow.
QPointer< QAction > m_showHideGrid
Show plot grid lines action.
Definition PlotWindow.h:316
void printPlot()
Provides printing support of the plot image.
QwtPlotZoomer * m_zoomer
Plot Zoomer.
Definition PlotWindow.h:275
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.
Definition PlotWindow.h:94
@ LineFitMenuOption
This option allows the user to create a best fit line for any of the scatter plot data or cube plot c...
Definition PlotWindow.h:161
@ PrintMenuOption
This option sends the plot to a printer.
Definition PlotWindow.h:116
@ ResetScaleMenuOption
This option provides the user with an alternative zoom out button.
Definition PlotWindow.h:145
@ ShowHideMarkersMenuOption
This option is titled 'Hide All Symbols' which hides all markers.
Definition PlotWindow.h:96
@ ConfigurePlotMenuOption
This option allows the user to change the curve name, color, style size, and symbol of the curve.
Definition PlotWindow.h:167
@ SaveMenuOption
This option exports the plot into a standard image format.
Definition PlotWindow.h:112
@ ShowHideGridMenuOption
This option enables the ability for a user to enable a grid over the plot area.
Definition PlotWindow.h:132
@ ShowTableMenuOption
This option brings up the table.
Definition PlotWindow.h:106
@ ClearPlotMenuOption
This option allows the user to delete all of the data inside the plot.
Definition PlotWindow.h:151
@ RenameLabelsMenuOption
This option enables the ability for a user to change the x/y axis labels and plot title.
Definition PlotWindow.h:137
@ TrackMenuOption
This option enables mouse tracking on the plot area (displays next to the mouse which x/y point you a...
Definition PlotWindow.h:122
@ ShowHideCurvesMenuOption
This option is titled 'Hide All Curves' which makes all curves invisible.
Definition PlotWindow.h:101
@ BackgroundSwitchMenuOption
This option enables the ability for a user to change the background color of the plot from black to w...
Definition PlotWindow.h:127
@ SetDisplayRangeMenuOption
This option allows the user to set the x/y axis display value ranges.
Definition PlotWindow.h:141
QLineEdit * m_yMaxEdit
Set Scale Dialog's edit for the max Y-axis value.
Definition PlotWindow.h:291
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.
Definition PlotWindow.h:283
void resetScale()
Sets plot scale back to the defaults.
QPointer< QAction > m_showHideAllMarkers
Hide all markers action.
Definition PlotWindow.h:314
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.
Definition PlotWindow.h:307
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.
Definition PlotWindow.h:295
TableMainWindow * m_tableWindow
Table window.
Definition PlotWindow.h:332
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.
Definition PlotWindow.h:329
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.
Definition PlotWindow.h:326
void changePlotLabels()
This method creates the dialog box which allows the user to relabel the plot window.
QWidget * m_parent
Parent widget.
Definition PlotWindow.h:273
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.
Definition PlotWindow.h:319
QCheckBox * m_autoScaleCheckBox
Set Scale Dialog's checkbox for enabling automatic scaling on x & y.
Definition PlotWindow.h:279
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.
Definition PlotWindow.h:333
QwtPlotGrid * m_grid
Plot grid lines.
Definition PlotWindow.h:277
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.
Definition PlotWindow.h:321
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.
Definition PlotWindow.h:281
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.
Definition PlotWindow.h:331
a subclass of the qisis mainwindow, tablemainwindow handles all of the table tasks.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.
Namespace for the standard library.