20 #include "IsisDebug.h"
25 #include <QApplication>
26 #include <QCloseEvent>
33 #include <QMessageBox>
34 #include <QMouseEvent>
42 #include "CubeDataThread.h"
74 "Can not view NULL cube pointer",
79 "Can not view unopened cube",
110 setAttribute(Qt::WA_DeleteOnClose);
111 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
112 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
113 viewport()->setObjectName(
"viewport");
114 viewport()->setCursor(QCursor(Qt::CrossCursor));
115 viewport()->installEventFilter(
this);
116 viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
118 setAttribute(Qt::WA_NoSystemBackground);
119 setFrameShadow(QFrame::Plain);
120 setFrameShape(QFrame::NoFrame);
121 setAutoFillBackground(
false);
178 p_whatsThisText = QString(
"<b>Function: </b>Viewport to ") + cubeFileName;
181 "<p><b>Cube Dimensions:</b> \
182 <blockQuote>Samples = " +
185 QString::number(cube->
lineCount()) +
"<br>" +
187 QString::number(cube->
bandCount()) +
"</blockquote></p>";
196 p_grayBuffer->enable(
false);
197 p_grayBuffer->setBand(1);
206 p_progressTimer->setInterval(250);
213 p_globalStretches->push_back(NULL);
216 connect(p_progressTimer, SIGNAL(timeout()),
this, SLOT(
onProgressTimer()));
223 p_image =
new QImage(viewport()->size(), QImage::Format_RGB32);
250 QAbstractScrollArea::show();
263 double progress = 0.0;
264 bool completed =
false;
286 int realProgress = (int)(progress * 100.0);
293 else if(realProgress == 100) {
380 delete(*p_pixmapPaintRects)[rect];
390 delete(*p_knownStretches)[stretch];
391 (*p_knownStretches)[stretch] = NULL;
404 delete(*p_globalStretches)[stretch];
405 (*p_globalStretches)[stretch] = NULL;
454 double ss, sl, es, el;
465 if(es >
cube()->sampleCount() + 0.5){
468 if(el >
cube()->lineCount() + 0.5){
482 if(ex > viewport()->width()){
483 ex = viewport()->width();
485 if(ey > viewport()->height()){
486 ey = viewport()->height();
488 QRect vpRect(sx, sy, ex - sx + 1, ey - sy + 1);
521 bool canClose =
true;
524 switch(QMessageBox::information(
this, tr(
"Confirm Save"),
525 tr(
"The cube [<font color='red'>%1</font>] contains unsaved changes. "
526 "Do you want to save the changes before exiting?").arg(
cube()->fileName()),
527 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)) {
529 case QMessageBox::Save:
534 case QMessageBox::Discard:
539 case QMessageBox::Cancel:
589 if (viewport()->width() && viewport()->height()) {
591 double maxScale = max(viewport()->width(),viewport()->height());
592 if (scale > maxScale) {
597 if (scale < minScale) {
604 contentsToCube(horizontalScrollBar()->value(), verticalScrollBar()->value(),
638 viewport()->repaint();
667 viewport()->setUpdatesEnabled(
false);
669 bool wasEnabled =
false;
713 viewport()->setUpdatesEnabled(
true);
714 viewport()->update();
747 int panX = horizontalScrollBar()->value() - x;
748 int panY = verticalScrollBar()->value() - y;
799 double &sample,
double &line)
const {
816 double &sample,
double &line)
const {
817 x += horizontalScrollBar()->value();
818 x -= viewport()->width() / 2;
819 y += verticalScrollBar()->value();
820 y -= viewport()->height() / 2;
836 int &x,
int &y)
const {
837 x = (int)(sample *
p_scale + 0.5);
838 y = (int)(line *
p_scale + 0.5);
853 int &x,
int &y)
const {
855 x -= horizontalScrollBar()->value();
856 x += viewport()->width() / 2;
857 y -= verticalScrollBar()->value();
858 y += viewport()->height() / 2;
871 int x = horizontalScrollBar()->value() + dx;
873 dx = 1 - horizontalScrollBar()->value();
875 else if(x >= horizontalScrollBar()->maximum()) {
876 dx = horizontalScrollBar()->maximum() - horizontalScrollBar()->value();
880 int y = verticalScrollBar()->value() + dy;
882 dy = 1 - verticalScrollBar()->value();
884 else if(y >= verticalScrollBar()->maximum()) {
885 dy = verticalScrollBar()->maximum() - verticalScrollBar()->value();
889 if((dx == 0) && (dy == 0)){
895 verticalScrollBar()->value() + dy);
912 if(viewport()->signalsBlocked()) {
924 bool panQueued =
false;
963 viewport()->update();
987 QString str = QFileInfo(cubeFileName).fileName();
988 str += QString(
" @ ");
989 str += QString::number(
p_scale * 100.0);
990 str += QString(
"% ");
993 str += QString(
"(RGB = ");
994 str += QString::number(
p_red.band);
996 str += QString::number(
p_green.band);
998 str += QString::number(
p_blue.band);
1002 str += QString(
"(Gray = ");
1003 str += QString::number(
p_gray.band);
1004 str += QString(
")");
1012 parentWidget()->setWindowTitle(str);
1054 p_image =
new QImage(viewport()->size(), QImage::Format_RGB32);
1055 p_pixmap = QPixmap(viewport()->size());
1061 verticalScrollBar()->value());
1064 "<p><b>Viewport Dimensions:</b> \
1065 <blockQuote>Samples = " +
1066 QString::number(viewport()->width()) +
"<br>" +
1068 QString::number(viewport()->height()) +
"</blockquote></p>";
1074 viewport()->update();
1125 viewport()->repaint(rect);
1168 for(
int y = dataArea.top();
1169 !dataArea.isNull() && y <= dataArea.bottom();
1171 const vector< double > & line =
1174 if(line.size() == 0) {
1182 QRgb *rgb = (QRgb *)
p_image->scanLine(y);
1184 for(
int x = dataArea.left(); x <= dataArea.right(); x++) {
1186 int bufferX = x - bufferLeft;
1188 if(bufferX >= (
int)line.size()){
1200 double bufferVal = line.at(bufferX);
1204 int redPix = (int)(
p_red.getStretch().
Map(bufferVal) + 0.5);
1205 int greenPix = (int)(
p_green.getStretch().
Map(bufferVal) + 0.5);
1206 int bluePix = (int)(
p_blue.getStretch().
Map(bufferVal) + 0.5);
1207 rgb[x] = qRgb(redPix, greenPix, bluePix);
1224 "Buffer rects mismatched",
1233 "Buffer rects mismatched",
1239 for(
int y = dataArea.top();
1240 !dataArea.isNull() && y <= dataArea.bottom();
1248 if((
int)redLine.size() < dataArea.width() ||
1249 (int)greenLine.size() < dataArea.width() ||
1250 (int)blueLine.size() < dataArea.width()) {
1252 "Empty buffer line",
1256 QRgb *rgb = (QRgb *)
p_image->scanLine(y);
1258 for(
int x = dataArea.left(); x <= dataArea.right(); x++) {
1263 rgb[x] = qRgb(redPix, greenPix, bluePix);
1269 if(!dataArea.isNull()){
1270 p.drawImage(dataArea.topLeft(), *
p_image, dataArea);
1290 int drawStartX = dx;
1291 int pixmapStartX = 0;
1292 if(drawStartX < 0) {
1297 int drawStartY = dy;
1298 int pixmapStartY = 0;
1305 int pixmapDrawWidth =
p_pixmap.width() - pixmapStartX + 1;
1306 int pixmapDrawHeight =
p_pixmap.height() - pixmapStartY + 1;
1309 QPixmap pixmapCopy =
p_pixmap.copy();
1312 painter.fillRect(rect, QBrush(
p_bgColor));
1313 painter.drawPixmap(drawStartX, drawStartY,
1315 pixmapStartX, pixmapStartY,
1316 pixmapDrawWidth, pixmapDrawHeight);
1324 xFillRect = QRect(QPoint(0, 0),
1329 xFillRect = QRect(QPoint(
p_pixmap.width() + dx, 0),
1336 yFillRect = QRect(QPoint(0, 0),
1341 yFillRect = QRect(QPoint(0,
p_pixmap.height() + dy),
1354 viewport()->update();
1370 PvlGroup cubeGrp(
"CubeDimensions");
1374 whatsThisObj += cubeGrp;
1377 PvlGroup viewportGrp(
"ViewportDimensions");
1380 whatsThisObj += viewportGrp;
1388 int iFilterSize = filterName.
size();
1392 PvlKeyword virtualKey(
"Virtual"), physicalKey(
"Physical"), filterNameKey;
1400 virtualKey +=
toString(iGreenBand);
1402 bandGrp += virtualKey;
1407 bandGrp += physicalKey;
1410 if(iRedBand <= iFilterSize) {
1411 filterNameKey += filterName[iRedBand-1];
1414 filterNameKey +=
"None";
1417 if(iGreenBand <= iFilterSize) {
1418 filterNameKey += filterName[iGreenBand-1];
1421 filterNameKey +=
"None";
1424 if(iBlueBand <= iFilterSize) {
1425 filterNameKey += filterName[iBlueBand-1];
1428 filterNameKey +=
"None";
1430 bandGrp += filterNameKey;
1441 if(iFilterSize && iGrayBand <= iFilterSize) {
1442 bandGrp +=
PvlKeyword(
"FilterName", filterName[iGrayBand-1]);
1447 double sl, ss, es, el;
1453 cubeAreaPvl += bandGrp;
1454 whatsThisObj += cubeAreaPvl;
1455 pWhatsThisPvl += whatsThisObj;
1474 pFilterNameKey =bandBinGrp.
findKeyword(
"FilterName") ;
1488 double & pdStartLine,
double & pdEndLine)
1491 if(pdStartSample < 1.0){
1492 pdStartSample = 1.0;
1494 if(pdStartLine < 1.0){
1499 viewportToCube(viewport()->width() - 1, viewport()->height() - 1, pdEndSample, pdEndLine);
1514 double sl, ss, es, el;
1520 int iFilterSize = filterNameKey.
size();
1528 sBandInfo =
"Bands(RGB) Virtual = " +
1529 QString::number(iRedBand) +
", ";
1530 sBandInfo += QString::number(iGreenBand) +
", ";
1531 sBandInfo += QString::number(iBlueBand) +
" ";
1533 sBandInfo +=
"Physical = " +
1539 sBandInfo +=
"<br>FilterName = ";
1540 if(iRedBand <= iFilterSize) {
1541 sBandInfo += QString(filterNameKey[iRedBand-1]);
1544 sBandInfo +=
"None";
1548 if(iGreenBand <= iFilterSize) {
1549 sBandInfo += QString(filterNameKey[iGreenBand-1]);
1552 sBandInfo +=
"None";
1556 if(iBlueBand <= iFilterSize) {
1557 sBandInfo += QString(filterNameKey[iBlueBand-1]);
1560 sBandInfo +=
"None";
1567 sBandInfo =
"Band(Gray) Virtual = " + QString::number(iGrayBand) +
" ";
1571 if(iFilterSize && iGrayBand <= iFilterSize) {
1572 sBandInfo +=
"<br>FilterName = " + QString(filterNameKey[iGrayBand-1]);
1577 "<p><b>Visible Cube Area:</b><blockQuote> \
1578 Samples = " + QString::number(
int(ss + 0.5)) +
"-" +
1579 QString::number(
int(es + 0.5)) +
"<br> \
1580 Lines = " + QString::number(
int(sl + 0.5)) +
"-" +
1581 QString::number(
int(el + 0.5)) +
"<br> " +
1582 sBandInfo +
"</blockQuote></p>";
1585 setWhatsThis(fullWhatsThis);
1586 viewport()->setWhatsThis(fullWhatsThis);
1655 return p_gray.getStretch();
1661 return p_red.getStretch();
1673 return p_blue.getStretch();
1688 if(o == viewport()) {
1690 case QEvent::Enter: {
1691 viewport()->setMouseTracking(
true);
1696 case QEvent::MouseMove: {
1697 QMouseEvent *m = (QMouseEvent *) e;
1699 emit
mouseMove(m->pos(), (Qt::MouseButton)(m->button() +
1704 case QEvent::Leave: {
1705 viewport()->setMouseTracking(
false);
1710 case QEvent::MouseButtonPress: {
1711 QMouseEvent *m = (QMouseEvent *) e;
1713 (Qt::MouseButton)(m->button() + m->modifiers()));
1717 case QEvent::MouseButtonRelease: {
1718 QMouseEvent *m = (QMouseEvent *) e;
1720 (Qt::MouseButton)(m->button() + m->modifiers()));
1724 case QEvent::MouseButtonDblClick: {
1725 QMouseEvent *m = (QMouseEvent *) e;
1736 return QAbstractScrollArea::eventFilter(o, e);
1748 if(e->key() == Qt::Key_Plus) {
1753 else if(e->key() == Qt::Key_Minus) {
1758 else if(e->key() == Qt::Key_Up) {
1762 else if(e->key() == Qt::Key_Down) {
1766 else if(e->key() == Qt::Key_Left) {
1770 else if(e->key() == Qt::Key_Right) {
1775 QAbstractScrollArea::keyPressEvent(e);
1787 QPoint g = QCursor::pos();
1788 QPoint v = viewport()->mapFromGlobal(g);
1795 if(v.x() >= viewport()->width()){
1798 if(v.y() >= viewport()->height()){
1812 QPoint g = QCursor::pos();
1813 return viewport()->mapFromGlobal(g);
1825 QPoint g = QCursor::pos();
1827 QPoint v = viewport()->mapFromGlobal(g);
1834 if(v.x() >= viewport()->width()){
1837 if(v.y() >= viewport()->height()){
1853 QPoint v = viewport()->mapToGlobal(g);
1866 viewport()->blockSignals(
true);
1868 verticalScrollBar()->setValue(1);
1869 verticalScrollBar()->setMinimum(1);
1871 verticalScrollBar()->setPageStep(viewport()->height() / 2);
1873 horizontalScrollBar()->setValue(1);
1874 horizontalScrollBar()->setMinimum(1);
1876 horizontalScrollBar()->setPageStep(viewport()->width() / 2);
1878 if(horizontalScrollBar()->value() != x || verticalScrollBar()->value() != y) {
1879 horizontalScrollBar()->setValue(x);
1880 verticalScrollBar()->setValue(y);
1884 QApplication::sendPostedEvents(viewport(), 0);
1885 viewport()->blockSignals(
false);
1925 delete(*p_knownStretches)[oldBand - 1];
1928 (*p_knownStretches)[oldBand - 1] =
new Stretch(
p_gray.getStretch());
1947 viewport()->repaint();
1953 delete(*p_knownStretches)[stretch];
1954 (*p_knownStretches)[stretch] = NULL;
1963 delete(*p_knownStretches)[index];
1966 (*p_knownStretches)[index] =
new Stretch(stretch);
2004 delete(*p_knownStretches)[oldBand - 1];
2007 (*p_knownStretches)[oldBand - 1] =
new Stretch(
p_red.getStretch());
2027 delete(*p_knownStretches)[oldBand - 1];
2030 (*p_knownStretches)[oldBand - 1] =
new Stretch(
p_green.getStretch());
2050 delete(*p_knownStretches)[oldBand - 1];
2053 (*p_knownStretches)[oldBand - 1] =
new Stretch(
p_blue.getStretch());
2086 stretch.
Parse(
string);
2098 stretch.
Parse(
string);
2110 stretch.
Parse(
string);
2122 stretch.
Parse(
string);
2167 p_gray.setStretch(stretch);
2171 p_red.setStretch(newRed);
2179 p_blue.setStretch(newBlue);
2182 viewport()->update();
2192 p_red.setStretch(stretch);
2200 viewport()->update();
2218 viewport()->update();
2228 p_blue.setStretch(stretch);
2236 viewport()->update();
2248 double sampScale = (double) viewport()->width() / (double)
cubeSamples();
2249 double lineScale = (double) viewport()->height() / (double)
cubeLines();
2250 double scale = sampScale < lineScale ? sampScale : lineScale;
2276 double scale = (double) viewport()->height() / (double)
cubeLines();
2291 double ss, sl, es, el;
2292 ss = (double)(cubeRect.left()) - 1.;
2293 sl = (double)(cubeRect.top()) - 1.;
2294 es = (double)(cubeRect.right()) + 1.;
2295 el = (double)(cubeRect.bottom()) + 1.;
2305 if(el >
cube()->lineCount()){
2320 if(ex > viewport()->width()){
2321 ex = viewport()->width();
2323 if(ey > viewport()->height()){
2324 ey = viewport()->height();
2326 QRect vpRect(sx, sy, ex - sx + 1, ey - sy + 1);
2354 viewport()->setCursor(cursor);
2358 CubeViewport::BandInfo::BandInfo() : band(1), stretch(NULL) {
2361 stretch->SetLis(0.0);
2362 stretch->SetLrs(0.0);
2363 stretch->SetHis(255.0);
2364 stretch->SetHrs(255.0);
2365 stretch->SetMinimum(0.0);
2366 stretch->SetMaximum(255.0);
2370 CubeViewport::BandInfo::BandInfo(
const CubeViewport::BandInfo &other) :
2373 stretch =
new Stretch(*other.stretch);
2377 CubeViewport::BandInfo::~BandInfo() {
2385 Stretch CubeViewport::BandInfo::getStretch()
const {
2386 ASSERT_PTR(stretch);
2392 void CubeViewport::BandInfo::setStretch(
const Stretch &newStretch) {
2393 *stretch = newStretch;
2397 const CubeViewport::BandInfo &CubeViewport::BandInfo::operator=(
2398 CubeViewport::BandInfo other) {
2399 ASSERT_PTR(other.stretch);
2402 stretch =
new Stretch;
2403 *stretch = *other.stretch;