USGS

Isis 3.0 Object Programmers' Reference

Home

FileTool.cpp

00001 #include "FileTool.h"
00002 
00003 #include <QApplication>
00004 #include <QFileDialog>
00005 #include <QImage>
00006 #include <QMenu>
00007 #include <QMessageBox>
00008 #include <QPainter>
00009 #include <QPixmap>
00010 #include <QPrinter>
00011 #include <QPrintDialog>
00012 
00013 #include <cmath>
00014 
00015 #include "Brick.h"
00016 #include "BrowseDialog.h"
00017 #include "CubeAttribute.h"
00018 #include "Enlarge.h"
00019 #include "FileDialog.h"
00020 #include "Interpolator.h"
00021 #include "MainWindow.h"
00022 #include "MdiCubeViewport.h"
00023 #include "OriginalLabel.h"
00024 #include "Portal.h"
00025 #include "ProcessRubberSheet.h"
00026 #include "ProcessByLine.h"
00027 #include "Pvl.h"
00028 #include "Reduce.h"
00029 #include "SaveAsDialog.h"
00030 #include "SubArea.h"
00031 #include "Workspace.h"
00032 
00033 namespace Isis {
00042   FileTool::FileTool(QWidget *parent) : Tool(parent) {
00043     p_parent = parent;
00044     p_dir = "/thisDirDoesNotExist!";
00045     p_open = new QAction(parent);
00046     p_open->setShortcut(Qt::CTRL + Qt::Key_O);
00047     p_open->setText("&Open...");
00048     p_open->setIcon(QPixmap(toolIconDir() + "/fileopen.png"));
00049     p_open->setToolTip("Open cube");
00050     QString whatsThis =
00051       "<b>Function:</b> Open an <i>Isis cube</i> in new viewport \
00052        <p><b>Shortcut:</b>  Ctrl+O\n</p> \
00053        <p><b>Hint:</b> Use Ctrl or Shift in file dialog to open \
00054        multiple cubes</p>";
00055     p_open->setWhatsThis(whatsThis);
00056     connect(p_open, SIGNAL(activated()), this, SLOT(open()));
00057 
00058     p_browse = new QAction(parent);
00059     p_browse->setShortcut(Qt::CTRL + Qt::Key_B);
00060     p_browse->setText("&Browse...");
00061     p_browse->setToolTip("Browse cubes");
00062     whatsThis =
00063       "<b>Function:</b> Browse a <i>Isis cubes</i> in new viewport \
00064        <p><b>Shortcut:</b>  Ctrl+B\n</p>";
00065     p_browse->setWhatsThis(whatsThis);
00066     connect(p_browse, SIGNAL(activated()), this, SLOT(browse()));
00067 
00068     p_save = new QAction(parent);
00069     p_save->setShortcut(Qt::CTRL + Qt::Key_S);
00070     p_save->setText("&Save");
00071     p_save->setIcon(QPixmap(toolIconDir() + "/filesave.png"));
00072     p_save->setToolTip("Save");
00073     whatsThis =
00074       "<b>Function:</b> Save changes to the current Cube \
00075        <p><b>Shortcut:</b> Ctrl+S</p>";
00076     p_save->setWhatsThis(whatsThis);
00077     connect(p_save, SIGNAL(activated()), this, SLOT(save()));
00078     p_save->setEnabled(false);
00079 
00080     p_saveAs = new QAction(parent);
00081     p_saveAs->setText("Save &As...");
00082     p_saveAs->setIcon(QPixmap(toolIconDir() + "/filesaveas.png"));
00083     p_saveAs->setToolTip("Save As");
00084     whatsThis =
00085       "<b>Function:</b> Save the current Cube to the specified location";
00086     p_saveAs->setWhatsThis(whatsThis);
00087     connect(p_saveAs, SIGNAL(activated()), this, SLOT(saveAs()));
00088     p_saveAs->setEnabled(false);
00089 
00090     p_saveInfo = new QAction(parent);
00091     p_saveInfo->setText("Save &Info...");
00092     p_saveInfo->setIcon(QPixmap(toolIconDir() + "/filesaveas.png"));
00093     p_saveInfo->setToolTip("Save Info");
00094     whatsThis =
00095       "<b>Function:</b> Save the current Cube's Whatsthis Info to the specified location";
00096     p_saveInfo->setWhatsThis(whatsThis);
00097     connect(p_saveInfo, SIGNAL(activated()), this, SLOT(saveInfo()));
00098     p_saveInfo->setEnabled(false);
00099 
00100     p_exportView = new QAction(parent);
00101     p_exportView->setText("Export View");
00102     p_exportView->setIcon(QPixmap(toolIconDir() + "/fileexport.png"));
00103     p_exportView->setToolTip("Export View");
00104     whatsThis =
00105       "<b>Function:</b> Save visible contents of the active \
00106        viewport as a png, jpg, tiff \
00107        <p><b>Hint:</b>  Your local installation of Qt may not support \
00108        all formats.  Reinstall Qt if necessary</p>";
00109     p_exportView->setWhatsThis(whatsThis);
00110     connect(p_exportView, SIGNAL(activated()), this, SLOT(exportView()));
00111     p_exportView->setEnabled(false);
00112 
00113     p_print = new QAction(parent);
00114     p_print->setText("&Print...");
00115     p_print->setShortcut(Qt::CTRL + Qt::Key_P);
00116     p_print->setIcon(QPixmap(toolIconDir() + "/fileprint.png"));
00117     p_print->setToolTip("Print");
00118     whatsThis =
00119       "<b>Function:</b> Print visible contents of the active viewport \
00120       <p><b>Shortcut:</b> Ctrl+P</b>";
00121     p_print->setWhatsThis(whatsThis);
00122     connect(p_print, SIGNAL(activated()), this, SLOT(print()));
00123     p_print->setEnabled(false);
00124 
00125     p_closeAll = new QAction(parent);
00126     p_closeAll->setText("&Close All...");
00127     p_closeAll->setToolTip("Close All");
00128     whatsThis =
00129       "<b>Function:</b> Close all cube viewports.";
00130     p_closeAll->setWhatsThis(whatsThis);
00131 
00132     p_exit = new QAction(parent);
00133     p_exit->setShortcut(Qt::CTRL + Qt::Key_Q);
00134     p_exit->setText("E&xit");
00135     p_exit->setIcon(QPixmap(toolIconDir() + "/fileclose.png"));
00136     whatsThis =
00137       "<b>Function:</b>  Quit qview \
00138       <p><b>Shortcut:</b> Ctrl+Q</p>";
00139     p_exit->setWhatsThis(whatsThis);
00140     connect(p_exit, SIGNAL(activated()), this, SLOT(exit()));
00141 
00142     p_lastDir.clear();
00143     p_lastViewport = NULL;
00144 
00145     p_saveAsDialog = NULL;
00146     activate(true);
00147   }
00148 
00154   void FileTool::addTo(QMenu *menu) {
00155     menu->addAction(p_open);
00156     menu->addAction(p_browse);
00157     menu->addAction(p_save);
00158     menu->addAction(p_saveAs);
00159     menu->addAction(p_saveInfo);
00160     menu->addAction(p_exportView);
00161     menu->addAction(p_print);
00162     menu->addAction(p_closeAll);
00163     menu->addAction(p_exit);
00164   }
00165 
00171   void FileTool::addTo(Workspace *ws) {
00172     p_workSpace = ws;
00173     Tool::addTo(ws);
00174     connect(this, SIGNAL(fileSelected(QString)),
00175             ws, SLOT(addCubeViewport(QString)));
00176 
00177     connect(p_closeAll, SIGNAL(activated()), ws, SLOT(closeAllSubWindows()));
00178   }
00179 
00185   void FileTool::addToPermanent(QToolBar *perm) {
00186     perm->addAction(p_open);
00187     perm->addAction(p_exportView);
00188     perm->addAction(p_print);
00189     perm->addAction(p_exit);
00190   }
00191 
00196   void FileTool::open() {
00197     //Set up the list of filters that are default with this dialog.
00198     if (!p_filterList.contains("Isis cubes (*.cub)")) {
00199       p_filterList.append("Isis cubes (*.cub)");
00200       p_filterList.append("All files (*)");
00201     }
00202     if (!p_dir.exists()) {
00203       p_dir = QDir::current();
00204     }
00205 
00206     FileDialog *fileDialog = new FileDialog("Open", p_filterList, p_dir, (QWidget *)parent());
00207     fileDialog->show();
00208     connect(fileDialog, SIGNAL(fileSelected(QString)),
00209             p_workSpace, SLOT(addCubeViewport(QString)));
00210   }
00211 
00216   void FileTool::browse() {
00217     //Set up the list of filters that are default with this dialog.
00218     if (!p_filterList.contains("Isis cubes (*.cub)")) {
00219       p_filterList.append("Isis cubes (*.cub)");
00220       p_filterList.append("All files (*)");
00221     }
00222     if (!p_dir.exists()) {
00223       p_dir = QDir::current();
00224     }
00225     BrowseDialog *browser = new BrowseDialog("Browse", p_filterList, p_dir, (QWidget *)parent());
00226     browser->show();
00227     connect(browser, SIGNAL(fileSelected(QString)),
00228             p_workSpace, SLOT(addBrowseView(QString)));
00229   }
00230 
00237   void FileTool::save() {
00238     //If the current viewport is null (safety check), return from this method
00239     if (cubeViewport() == NULL) {
00240       QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save");
00241       return;
00242     }
00243 
00244     emit saveChanges(cubeViewport());
00245     p_save->setEnabled(false);
00246 
00247     cubeViewport()->cube()->reopen("rw");
00248   }
00249 
00262   void FileTool::saveAs() {
00263     //If the current viewport is null (safety check), return from this method
00264     if (cubeViewport() == NULL) {
00265       QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save");
00266       return;
00267     }
00268     //Set up the list of filters that are default with this dialog.
00269     if (!p_filterList.contains("Isis cubes (*.cub)")) {
00270       p_filterList.append("Isis cubes (*.cub)");
00271     }
00272     if (!p_dir.exists()) {
00273       p_dir = QDir(p_lastDir);
00274     }
00275     if (p_saveAsDialog) {
00276       delete p_saveAsDialog;
00277       p_saveAsDialog = NULL;
00278     }
00279 
00280     p_saveAsDialog = new SaveAsDialog("Save As", p_filterList, p_dir, (QWidget *)parent());
00281     connect(p_saveAsDialog, SIGNAL(fileSelected(QString)), this, SLOT(saveAsCubeByOption(QString)));
00282 
00283     p_saveAsDialog->show();
00284   }
00285 
00294   void FileTool::saveAsCubeByOption(QString psOutFile) {
00295     //If the current viewport is null (safety check), return from this method
00296     if (cubeViewport() == NULL) {
00297       QMessageBox::information((QWidget *)parent(), "Error",
00298                                "No active cube to save");
00299       return;
00300     }
00301 
00302     //If the filename is empty, return
00303     if (psOutFile.isEmpty() || (p_saveAsDialog==NULL)){
00304       QMessageBox::information((QWidget *)parent(), "Error",
00305                                "No output file selected");
00306       return;
00307     }
00308 
00309     //Check if the output file is already opened
00310     QVector< MdiCubeViewport *> *vwportList = p_workSpace->cubeViewportList();
00311     QVector<MdiCubeViewport *>::iterator it;
00312     for (it = vwportList->begin(); it != vwportList->end(); ++it){
00313       if (QString((*it)->cube()->fileName()) ==  psOutFile) {
00314         QMessageBox::information((QWidget *)parent(), "Error",
00315             "Output File is already open\n\""+ psOutFile + "\"");
00316         return;
00317       }
00318     }
00319 
00320     //If the filename is the same as the current cube's filename, just save it
00321     if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::FullImage &&
00322        psOutFile == cubeViewport()->cube()->fileName()) {
00323       save();
00324       return;
00325     }
00326 
00327     //Save the current cube's changes by reopening it, and open an input cube
00328     //from the current cube's location
00329     Cube *icube = new Cube();
00330     icube->open(cubeViewport()->cube()->fileName(), "rw");
00331     Cube *ocube = NULL;
00332 
00333     // The output cube needs to be created if the scale is 1 since saveAs_FullResolution will be
00334     //  called, which expects a cube.  
00335     //  NOTE:  This really should be cleaned up and the cube should be created in 1 place.
00336     if (p_saveAsDialog->getSaveAsType() != SaveAsDialog::ExportAsIs ||
00337        p_lastViewport->scale() == 1) {
00338       //Create the output cube
00339       ocube = new Cube;
00340     }
00341 
00342     if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::FullImage) {
00343       copyCubeDetails(psOutFile, icube, ocube, icube->sampleCount(),
00344                       icube->lineCount(), icube->bandCount());
00345       saveAsFullImage(icube, ocube);
00346       ocube->close();
00347     }
00348     else {
00349       // start and end Samples and Lines
00350       double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
00351       p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
00352    
00353       if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::ExportFullRes ||
00354          p_lastViewport->scale() == 1) {
00355 //      int numSamples = (int)ceil(dEndSample-dStartSample);
00356 //      int numLines = (int)ceil(dEndLine-dStartLine);
00357         int numSamples = (int)((dEndSample - dStartSample + 1) + 0.5);
00358         int numLines = (int)((dEndLine - dStartLine + 1) + 0.5);
00359         copyCubeDetails(psOutFile, icube, ocube, numSamples, numLines, icube->bandCount());
00360         saveAs_FullResolution(icube, ocube, numSamples, numLines);
00361         ocube->close();
00362       }
00363       else if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::ExportAsIs ) {
00364         saveAs_AsIs(icube, psOutFile);
00365       }
00366     }
00367 
00368     emit(fileSelected(psOutFile));
00369 
00370     //Disable the save action
00371     p_save->setEnabled(false);
00372 
00373     p_lastDir = psOutFile;
00374   }
00375 
00386   void FileTool::saveAsEnlargedCube(Cube *icube, const QString & psOutFile) {
00387     double dScale = p_lastViewport->scale();
00388 
00389     // start and end Samples and Lines
00390     double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
00391     p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
00392 
00393     double ins = dEndSample - dStartSample + 1;
00394     double inl = dEndLine - dStartLine + 1;
00395 
00396     double ons = (int)(ins * dScale + 0.5);
00397     double onl = (int)(inl * dScale + 0.5);
00398 
00399     try {
00400       ProcessRubberSheet p;
00401       p.SetInputCube (icube);
00402       Cube *ocube = p.SetOutputCube(psOutFile, CubeAttributeOutput(" "),
00403                                     ons, onl, icube->bandCount());
00404 
00405       Interpolator *interp = new Interpolator(Interpolator::NearestNeighborType);
00406 
00407       Enlarge *imgEnlarge  = new Enlarge(icube, dScale, dScale);
00408       imgEnlarge->SetInputArea((int)dStartSample, (int)dEndSample, (int)dStartLine, (int)dEndLine);
00409 
00410       p.StartProcess(*imgEnlarge, *interp);
00411       imgEnlarge->UpdateOutputLabel(ocube);
00412       p.EndProcess();
00413 
00414       delete imgEnlarge;
00415       delete interp;
00416 
00417     } catch(IException &) {
00418       QMessageBox::critical((QWidget *)parent(),
00419                             "Error", "Cannot open file, please check permissions");
00420     }
00421   }
00422 
00432   void FileTool::saveAsReducedCube(Cube *icube, const QString & psOutFile) {
00433 
00434     double dScale = p_lastViewport->scale();
00435     // start and end Samples and Lines
00436     double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
00437     p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
00438 
00439     double ins = dEndSample - dStartSample + 1;
00440     double inl = dEndLine - dStartLine + 1;
00441 
00442     double ons = (int)(ins * dScale + 0.5);
00443     double onl = (int)(inl * dScale + 0.5);
00444 
00445     CubeAttributeInput cai(icube->fileName());
00446     std::vector<QString> bands = cai.bands();
00447     int inb = bands.size();
00448 
00449     if (inb == 0) {
00450       inb = cubeViewport()->cube()->bandCount();
00451       for(int i = 1; i <= inb; i++) {
00452         bands.push_back(toString(i));
00453       }
00454     }
00455 
00456     ProcessByLine p;
00457     p.SetInputCube (icube);
00458     Cube *ocube = NULL;
00459     try {
00460       ocube = p.SetOutputCube(psOutFile, CubeAttributeOutput(""), ons, onl, inb);
00461       // Our processing routine only needs 1
00462       // the original set was for info about the cube only
00463       p.ClearInputCubes();
00464     }
00465     catch(IException &) {
00466       // If there is a problem, catch it and close the cube so it isn't open next time around
00467       icube->close();
00468       throw;
00469     }
00470 
00471     Cube *tempcube=new Cube;
00472     tempcube->open(cubeViewport()->cube()->fileName(), "r");
00473     Nearest *near = new Nearest(tempcube, ins/ons, inl/onl);
00474     near->setInputBoundary((int)dStartSample, (int)dEndSample, (int)dStartLine, (int)dEndLine);
00475 
00476     p.ProcessCubeInPlace(*near, false);
00477     near->UpdateOutputLabel(ocube);
00478     p.EndProcess();
00479 
00480     delete near;
00481     near=NULL;
00482   }
00483 
00492   void FileTool::saveAs_AsIs(Cube *icube, const QString & psOutFile) {
00493     double dScale = p_lastViewport->scale();
00494     // Enlarge the cube area
00495     if (dScale > 1) {
00496       saveAsEnlargedCube(icube, psOutFile);
00497     }
00498     // Reduce the cube area
00499     else {
00500       saveAsReducedCube(icube, psOutFile);
00501     }
00502   }
00503 
00518   void FileTool::copyCubeDetails(const QString & psOutFile, Cube *icube,
00519       Cube *ocube, int piNumSamples, int piNumLines, int piNumBands) {
00520     //Create the default output attribute with the output filename
00521     CubeAttributeOutput outAtt(psOutFile);
00522 
00523     //Propagate all labels, tables, blobs, etc from the input to output cube
00524     try {
00525       ocube->setDimensions(piNumSamples, piNumLines, piNumBands);
00526       ocube->setByteOrder(outAtt.byteOrder());
00527       ocube->setFormat(outAtt.fileFormat());
00528       ocube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);
00529 
00530       if (outAtt.propagatePixelType()) {
00531         ocube->setPixelType(icube->pixelType());
00532       }
00533       else {
00534         ocube->setPixelType(outAtt.pixelType());
00535       }
00536 
00537       if (outAtt.propagateMinimumMaximum()) {
00538         if (ocube->pixelType() == Real) {
00539           ocube->setBaseMultiplier(0.0, 1.0);
00540         }
00541         else if (ocube->pixelType() >= icube->pixelType()) {
00542           double base = icube->base();
00543           double mult = icube->multiplier();
00544           ocube->setBaseMultiplier(base, mult);
00545         }
00546         else if ((ocube->pixelType() != Real) &&
00547                 (ocube->pixelType() != UnsignedByte) &&
00548                 (ocube->pixelType() != SignedWord)) {
00549           QString msg = "Looks like your refactoring to add different pixel types";
00550           msg += " you'll need to make changes here";
00551           throw IException(IException::Programmer, msg, _FILEINFO_);
00552         }
00553         else {
00554           QString msg = "You've chosen to reduce your output PixelType for [" +
00555                             psOutFile + "] you must specify the output pixel range too";
00556           throw IException(IException::User, msg, _FILEINFO_);
00557         }
00558       }
00559       else {
00560         // Not propagating so either the user entered or the programmer did
00561         ocube->setMinMax(outAtt.minimum(), outAtt.maximum());
00562       }
00563 
00564       int needLabBytes = icube->labelSize(true) + (1024 * 6);
00565       if (needLabBytes > ocube->labelSize()) {
00566         ocube->setLabelSize(needLabBytes);
00567       }
00568 
00569       // Allocate the cube
00570       ocube->create(psOutFile);
00571 
00572       // Transfer labels from the first input cube
00573       PvlObject &incube = icube->label()->FindObject("IsisCube");
00574       PvlObject &outcube = ocube->label()->FindObject("IsisCube");
00575       for(int i = 0; i < incube.Groups(); i++) {
00576         outcube.AddGroup(incube.Group(i));
00577       }
00578 
00579       // Transfer tables from the first input cube
00580       Pvl &inlab = *icube->label();
00581       for(int i = 0; i < inlab.Objects(); i++) {
00582         if (inlab.Object(i).IsNamed("Table")) {
00583           Blob t((QString)inlab.Object(i)["Name"], inlab.Object(i).Name());
00584           icube->read(t);
00585           ocube->write(t);
00586         }
00587       }
00588 
00589       // Transfer blobs from the first input cube
00590       inlab = *icube->label();
00591       for(int i = 0; i < inlab.Objects(); i++) {
00592         if (inlab.Object(i).IsNamed("Polygon")) {
00593           Blob t((QString)inlab.Object(i)["Name"], inlab.Object(i).Name());
00594           icube->read(t);
00595           ocube->write(t);
00596         }
00597       }
00598 
00599       // Transfer tables from the first input cube
00600       inlab = *icube->label();
00601       for(int i = 0; i < inlab.Objects(); i++) {
00602         if (inlab.Object(i).IsNamed("OriginalLabel")) {
00603           OriginalLabel ol;
00604           icube->read(ol);
00605           ocube->write(ol);
00606         }
00607       }
00608     }
00609     catch(IException &) {
00610       delete ocube;
00611       throw;
00612     }
00613   }
00614 
00625   void FileTool::saveAsFullImage(Cube *icube, Cube *ocube) {
00626     //Start the copy process line by line
00627     Brick ibrick(*icube, icube->sampleCount(), 1, 1);
00628     Brick obrick(*ocube, ocube->sampleCount(), 1, 1);
00629 
00630     int numBricks;
00631     if (ibrick.Bricks() > obrick.Bricks()) {
00632       numBricks = ibrick.Bricks();
00633     }
00634     else {
00635       numBricks = obrick.Bricks();
00636     }
00637 
00638     // Loop and let the app programmer work with the bricks
00639     ibrick.begin();
00640     obrick.begin();
00641     for(int i = 0; i < numBricks; i++) {
00642       icube->read(ibrick);
00643       //Copy the contents to the output cube
00644       copy(ibrick, obrick);
00645       ocube->write(obrick);
00646       ibrick++;
00647       obrick++;
00648     }
00649   }
00650 
00662   void FileTool::saveAs_FullResolution(Cube *pInCube,
00663       Cube *pOutCube, int pNumSamples, int pNumLines) {
00664     // start and end Samples and Lines
00665     double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
00666     p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
00667     int iNumBands   = pInCube->bandCount();
00668 
00669     PvlGroup results("Results");
00670     results += PvlKeyword("InputLines",      toString(pInCube->lineCount()));
00671     results += PvlKeyword("InputSamples",    toString(pInCube->sampleCount()));
00672     results += PvlKeyword("StartingLine",    toString(dStartLine));
00673     results += PvlKeyword("StartingSample",  toString(dStartSample));
00674     results += PvlKeyword("EndingLine",      toString(dEndLine));
00675     results += PvlKeyword("EndingSample",    toString(dEndSample));
00676     results += PvlKeyword("LineIncrement",   toString(1));
00677     results += PvlKeyword("SampleIncrement", toString(1));
00678     results += PvlKeyword("OutputLines",     toString(pNumLines));
00679     results += PvlKeyword("OutputSamples",   toString(pNumSamples));
00680     SubArea subArea;
00681     subArea.SetSubArea(pInCube->lineCount(), pInCube->sampleCount(), dStartLine, dStartSample,
00682                        dEndLine, dEndSample, 1.0, 1.0);
00683     subArea.UpdateLabel(pInCube, pOutCube, results);
00684 
00685     Portal iPortal (pNumSamples, 1, pInCube->pixelType());
00686     Portal oPortal (pNumSamples, 1, pOutCube->pixelType());
00687 
00688     for(int iBand=1; iBand<=iNumBands; iBand++) {
00689       int ol=1;
00690       for(int iLine=(int)dStartLine; iLine<=(int)dEndLine; iLine++) {
00691         iPortal.SetPosition(dStartSample, iLine, iBand);
00692         pInCube->read(iPortal);
00693 
00694         oPortal.SetPosition(1, ol++, iBand);
00695         pOutCube->read(oPortal);
00696 
00697         oPortal.Copy(iPortal);
00698         pOutCube->write(oPortal);
00699       }
00700     }
00701   }
00702 
00709   void FileTool::saveInfo(void)
00710   {
00711     if (cubeViewport() == NULL) {
00712       QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save info");
00713       return;
00714     }
00715 
00716     //Get the new cube's filename
00717     QString output =
00718       QFileDialog::getSaveFileName((QWidget *)parent(),
00719                                    "Choose output file",
00720                                    p_lastDir,
00721                                    QString("PVL Files (*.pvl)"));
00722 
00723     //If the filename is empty, return
00724     if (output.isEmpty()) {
00725       return;
00726     }
00727     else if (!output.endsWith(".pvl")) {
00728       output += ".pvl";
00729     }
00730 
00731     Pvl whatsThisPvl;
00732     cubeViewport()->getAllWhatsThisInfo(whatsThisPvl);
00733     whatsThisPvl.Write(output);
00734   }
00735 
00742   void FileTool::copy(Buffer &in, Buffer &out) {
00743     out.Copy(in);
00744   }
00745 
00751   void FileTool::discard() {
00752     emit discardChanges(cubeViewport());
00753   }
00754 
00759   void FileTool::exportView() {
00760     if (cubeViewport() == NULL) {
00761       QMessageBox::information((QWidget *)parent(), "Error", "No active cube to export");
00762       return;
00763     }
00764 
00765     QString output =
00766       QFileDialog::getSaveFileName((QWidget *)parent(),
00767                                    QString("Choose output file"),
00768                                    p_lastDir,
00769                                    QString("PNG (*.png);;JPG (*.jpg);;TIF (*.tif)"));
00770     if (output.isEmpty()) return;
00771 
00772     p_lastDir = output;
00773 
00774     QString format = QFileInfo(output).suffix();
00775 
00776     if (format.isEmpty()) {
00777       if (output.endsWith('.')) {
00778         output.append(QString("png"));
00779       }
00780       else {
00781         output.append(QString(".png"));
00782       }
00783     }
00784     else if (format.compare("png", Qt::CaseInsensitive) &&
00785             format.compare("jpg", Qt::CaseInsensitive) &&
00786             format.compare("tif", Qt::CaseInsensitive)) {
00787 
00788       QMessageBox::information((QWidget *)parent(), "Error", format + " is an invalid extension.");
00789       return;
00790     }
00791 
00792     QPixmap pm = QPixmap::grabWidget(cubeViewport()->viewport());
00793 
00794     //if (!cubeViewport()->pixmap().save(output,format)) {
00795 
00796     if (!pm.save(output)) {
00797       QMessageBox::information((QWidget *)parent(), "Error", "Unable to save " + output);
00798       return;
00799     }
00800   }
00801 
00806   void FileTool::print() {
00807     // Is there anything to print
00808     if (cubeViewport() == NULL) {
00809       QMessageBox::information((QWidget *)parent(), "Error", "No active cube to print");
00810       return;
00811     }
00812 
00813     // Initialize a printer
00814     static QPrinter *printer = NULL;
00815     if (printer == NULL) printer = new QPrinter;
00816     printer->setPageSize(QPrinter::Letter);
00817     printer->setColorMode(QPrinter::GrayScale);
00818     if (cubeViewport()->isColor()) printer->setColorMode(QPrinter::Color);
00819 
00820     QPrintDialog printDialog(printer, (QWidget *)parent());
00821     if (printDialog.exec() == QDialog::Accepted) {
00822       // Get display widget as a pixmap and convert to an image
00823       QPixmap pixmap = QPixmap::grabWidget(cubeViewport()->viewport());
00824       QImage img = pixmap.toImage();
00825 
00826       // C++ Gui Programmign with Qt, page 201
00827       QPainter painter(printer);
00828       QRect rect = painter.viewport();
00829       QSize size = img.size();
00830       size.scale(rect.size(), Qt::KeepAspectRatio);
00831       painter.setViewport(rect.x(), rect.y(),
00832                           size.width(), size.height());
00833       painter.setWindow(img.rect());
00834       painter.drawImage(0, 0, img);
00835     }
00836   }
00837 
00841   bool FileTool::closeAll() {
00842     //  Close all cubes
00843     // We must create a temporary list.  If not the actual
00844     // list size gets modified when a close occurs and not all
00845     // windows were being closed.
00846     MdiCubeViewport *d;
00847     QVector< MdiCubeViewport * > tempList(*cubeViewportList());
00848     for(int i = 0; i < (int)tempList.size(); i++) {
00849       d = tempList.at(i);
00850       //Set the current viewport to the one being closed
00851       setCubeViewport(d);
00852 
00853       if (!d->parentWidget()->close()) {
00854         return false;
00855       }
00856     }
00857     return true;
00858   }
00859 
00868   void FileTool::exit() {
00869     QWidget *mainWindow = qobject_cast<QWidget *>(p_parent);
00870 
00871     if (mainWindow)
00872       mainWindow->close();
00873   }
00874 
00880   void FileTool::enableSave(bool enable) {
00881     p_save->setEnabled(enable);
00882   }
00883 
00888   void FileTool::updateTool() {
00889     if (cubeViewport() == NULL) {
00890       if (p_lastViewport != NULL) {
00891         p_lastViewport = NULL;
00892       }
00893       p_print->setEnabled(false);
00894       p_save->setEnabled(false);
00895       p_exportView->setEnabled(false);
00896       p_saveAs->setEnabled(false);
00897       p_saveInfo->setEnabled(false);
00898     }
00899     else {
00900       if (p_lastViewport == NULL) {
00901         //Set the last viewport to the current viewport and connect signals to save and discard
00902         p_lastViewport = cubeViewport();
00903         connect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
00904       }
00905       else {
00906         if (p_lastViewport != cubeViewport()) {
00907           //If the viewport has changes made to it enable the save action
00908           if (cubeViewport()->parentWidget()->windowTitle().endsWith("*")) {
00909             p_save->setEnabled(true);
00910           }
00911           //Else disable it
00912           else {
00913             p_save->setEnabled(false);
00914           }
00915           //disconnect signals from the old viewport and connect them to the new viewport
00916           disconnect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
00917           disconnect(p_lastViewport, SIGNAL(discardChanges(CubeViewport *)), this, SLOT(discard()));
00918           p_lastViewport = cubeViewport();
00919           connect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
00920           connect(p_lastViewport, SIGNAL(discardChanges(CubeViewport *)), this, SLOT(discard()));
00921         }
00922       }
00923       p_print->setEnabled(true);
00924       p_exportView->setEnabled(true);
00925       p_saveAs->setEnabled(true);
00926       p_saveInfo->setEnabled(true);
00927     }
00928   }
00929 }