USGS

Isis 3.0 Object Programmers' Reference

Home

FileTool.cpp
1 #include "FileTool.h"
2 
3 #include <QApplication>
4 #include <QFileDialog>
5 #include <QImage>
6 #include <QMenu>
7 #include <QMessageBox>
8 #include <QPainter>
9 #include <QPixmap>
10 #include <QPrinter>
11 #include <QPrintDialog>
12 
13 #include <cmath>
14 
15 #include "Brick.h"
16 #include "BrowseDialog.h"
17 #include "CubeAttribute.h"
18 #include "Enlarge.h"
19 #include "FileDialog.h"
20 #include "Interpolator.h"
21 #include "MainWindow.h"
22 #include "MdiCubeViewport.h"
23 #include "OriginalLabel.h"
24 #include "Portal.h"
25 #include "ProcessRubberSheet.h"
26 #include "ProcessByLine.h"
27 #include "Pvl.h"
28 #include "Reduce.h"
29 #include "SaveAsDialog.h"
30 #include "SubArea.h"
31 #include "Workspace.h"
32 
33 namespace Isis {
42  FileTool::FileTool(QWidget *parent) : Tool(parent) {
43  p_parent = parent;
44  p_dir = "/thisDirDoesNotExist!";
45  p_open = new QAction(parent);
46  p_open->setShortcut(Qt::CTRL + Qt::Key_O);
47  p_open->setText("&Open...");
48  p_open->setIcon(QPixmap(toolIconDir() + "/fileopen.png"));
49  p_open->setToolTip("Open cube");
50  QString whatsThis =
51  "<b>Function:</b> Open an <i>Isis cube</i> in new viewport \
52  <p><b>Shortcut:</b> Ctrl+O\n</p> \
53  <p><b>Hint:</b> Use Ctrl or Shift in file dialog to open \
54  multiple cubes</p>";
55  p_open->setWhatsThis(whatsThis);
56  connect(p_open, SIGNAL(activated()), this, SLOT(open()));
57 
58  p_browse = new QAction(parent);
59  p_browse->setShortcut(Qt::CTRL + Qt::Key_B);
60  p_browse->setText("&Browse...");
61  p_browse->setToolTip("Browse cubes");
62  whatsThis =
63  "<b>Function:</b> Browse a <i>Isis cubes</i> in new viewport \
64  <p><b>Shortcut:</b> Ctrl+B\n</p>";
65  p_browse->setWhatsThis(whatsThis);
66  connect(p_browse, SIGNAL(activated()), this, SLOT(browse()));
67 
68  p_save = new QAction(parent);
69  p_save->setShortcut(Qt::CTRL + Qt::Key_S);
70  p_save->setText("&Save");
71  p_save->setIcon(QPixmap(toolIconDir() + "/filesave.png"));
72  p_save->setToolTip("Save");
73  whatsThis =
74  "<b>Function:</b> Save changes to the current Cube \
75  <p><b>Shortcut:</b> Ctrl+S</p>";
76  p_save->setWhatsThis(whatsThis);
77  connect(p_save, SIGNAL(activated()), this, SLOT(save()));
78  p_save->setEnabled(false);
79 
80  p_saveAs = new QAction(parent);
81  p_saveAs->setText("Save &As...");
82  p_saveAs->setIcon(QPixmap(toolIconDir() + "/filesaveas.png"));
83  p_saveAs->setToolTip("Save As");
84  whatsThis =
85  "<b>Function:</b> Save the current Cube to the specified location";
86  p_saveAs->setWhatsThis(whatsThis);
87  connect(p_saveAs, SIGNAL(activated()), this, SLOT(saveAs()));
88  p_saveAs->setEnabled(false);
89 
90  p_saveInfo = new QAction(parent);
91  p_saveInfo->setText("Save &Info...");
92  p_saveInfo->setIcon(QPixmap(toolIconDir() + "/filesaveas.png"));
93  p_saveInfo->setToolTip("Save Info");
94  whatsThis =
95  "<b>Function:</b> Save the current Cube's Whatsthis Info to the specified location";
96  p_saveInfo->setWhatsThis(whatsThis);
97  connect(p_saveInfo, SIGNAL(activated()), this, SLOT(saveInfo()));
98  p_saveInfo->setEnabled(false);
99 
100  p_exportView = new QAction(parent);
101  p_exportView->setText("Export View");
102  p_exportView->setIcon(QPixmap(toolIconDir() + "/fileexport.png"));
103  p_exportView->setToolTip("Export View");
104  whatsThis =
105  "<b>Function:</b> Save visible contents of the active \
106  viewport as a png, jpg, tiff \
107  <p><b>Hint:</b> Your local installation of Qt may not support \
108  all formats. Reinstall Qt if necessary</p>";
109  p_exportView->setWhatsThis(whatsThis);
110  connect(p_exportView, SIGNAL(activated()), this, SLOT(exportView()));
111  p_exportView->setEnabled(false);
112 
113  p_print = new QAction(parent);
114  p_print->setText("&Print...");
115  p_print->setShortcut(Qt::CTRL + Qt::Key_P);
116  p_print->setIcon(QPixmap(toolIconDir() + "/fileprint.png"));
117  p_print->setToolTip("Print");
118  whatsThis =
119  "<b>Function:</b> Print visible contents of the active viewport \
120  <p><b>Shortcut:</b> Ctrl+P</b>";
121  p_print->setWhatsThis(whatsThis);
122  connect(p_print, SIGNAL(activated()), this, SLOT(print()));
123  p_print->setEnabled(false);
124 
125  p_closeAll = new QAction(parent);
126  p_closeAll->setText("&Close All...");
127  p_closeAll->setToolTip("Close All");
128  whatsThis =
129  "<b>Function:</b> Close all cube viewports.";
130  p_closeAll->setWhatsThis(whatsThis);
131 
132  p_exit = new QAction(this);
133  p_exit->setShortcut(Qt::CTRL + Qt::Key_Q);
134  p_exit->setText("E&xit");
135  p_exit->setIcon(QPixmap(toolIconDir() + "/fileclose.png"));
136  whatsThis =
137  "<b>Function:</b> Quit qview \
138  <p><b>Shortcut:</b> Ctrl+Q</p>";
139  p_exit->setWhatsThis(whatsThis);
140  connect(p_exit, SIGNAL(activated()), this, SLOT(exit()));
141 
142  p_lastViewport = NULL;
143 
144  p_saveAsDialog = NULL;
145  activate(true);
146  }
147 
153  void FileTool::addTo(QMenu *menu) {
154  menu->addAction(p_open);
155  menu->addAction(p_browse);
156  menu->addAction(p_save);
157  menu->addAction(p_saveAs);
158  menu->addAction(p_saveInfo);
159  menu->addAction(p_exportView);
160  menu->addAction(p_print);
161  menu->addAction(p_closeAll);
162  menu->addAction(p_exit);
163  }
164 
171  p_workSpace = ws;
172  Tool::addTo(ws);
173  connect(this, SIGNAL(fileSelected(QString)),
174  ws, SLOT(addCubeViewport(QString)));
175 
176  connect(p_closeAll, SIGNAL(activated()), ws->mdiArea(), SLOT(closeAllSubWindows()));
177  }
178 
185  perm->addAction(p_open);
186  perm->addAction(p_exportView);
187  perm->addAction(p_print);
188  perm->addAction(p_exit);
189  }
190 
195  void FileTool::open() {
196  //Set up the list of filters that are default with this dialog.
197  if (!p_filterList.contains("Isis cubes (*.cub)")) {
198  p_filterList.append("Isis cubes (*.cub)");
199  p_filterList.append("All files (*)");
200  }
201  if (!p_dir.exists()) {
202  p_dir = QDir::current();
203  }
204 
205  FileDialog *fileDialog = new FileDialog("Open", p_filterList, p_dir, (QWidget *)parent());
206  fileDialog->show();
207  connect(fileDialog, SIGNAL(fileSelected(QString)),
208  p_workSpace, SLOT(addCubeViewport(QString)));
209  }
210 
216  //Set up the list of filters that are default with this dialog.
217  if (!p_filterList.contains("Isis cubes (*.cub)")) {
218  p_filterList.append("Isis cubes (*.cub)");
219  p_filterList.append("All files (*)");
220  }
221  if (!p_dir.exists()) {
222  p_dir = QDir::current();
223  }
224  BrowseDialog *browser = new BrowseDialog("Browse", p_filterList, p_dir, (QWidget *)parent());
225  browser->show();
226  connect(browser, SIGNAL(fileSelected(QString)),
227  p_workSpace, SLOT(addBrowseView(QString)));
228  }
229 
236  void FileTool::save() {
237  //If the current viewport is null (safety check), return from this method
238  if (cubeViewport() == NULL) {
239  QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save");
240  return;
241  }
242 
243  emit saveChanges(cubeViewport());
244  p_save->setEnabled(false);
245 
246  cubeViewport()->cube()->reopen("rw");
247  }
248 
262  //If the current viewport is null (safety check), return from this method
263  if (cubeViewport() == NULL) {
264  QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save");
265  return;
266  }
267  //Set up the list of filters that are default with this dialog.
268  if (!p_filterList.contains("Isis cubes (*.cub)")) {
269  p_filterList.append("Isis cubes (*.cub)");
270  }
271  if (!p_dir.exists()) {
272  p_dir = QDir(p_lastDir);
273  }
274  if (p_saveAsDialog) {
275  delete p_saveAsDialog;
276  p_saveAsDialog = NULL;
277  }
278 
279  p_saveAsDialog = new SaveAsDialog("Save As", p_filterList, p_dir, (QWidget *)parent());
280  connect(p_saveAsDialog, SIGNAL(fileSelected(QString)), this, SLOT(saveAsCubeByOption(QString)));
281 
282  p_saveAsDialog->show();
283  }
284 
293  void FileTool::saveAsCubeByOption(QString psOutFile) {
294  //If the current viewport is null (safety check), return from this method
295  if (cubeViewport() == NULL) {
296  QMessageBox::information((QWidget *)parent(), "Error",
297  "No active cube to save");
298  return;
299  }
300 
301  //If the filename is empty, return
302  if (psOutFile.isEmpty() || (p_saveAsDialog==NULL)){
303  QMessageBox::information((QWidget *)parent(), "Error",
304  "No output file selected");
305  return;
306  }
307 
308  //Check if the output file is already opened
309  QVector< MdiCubeViewport *> *vwportList = p_workSpace->cubeViewportList();
311  for (it = vwportList->begin(); it != vwportList->end(); ++it){
312  if (QString((*it)->cube()->fileName()) == psOutFile) {
313  QMessageBox::information((QWidget *)parent(), "Error",
314  "Output File is already open\n\""+ psOutFile + "\"");
315  return;
316  }
317  }
318 
319  //If the filename is the same as the current cube's filename, just save it
320  if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::FullImage &&
321  psOutFile == cubeViewport()->cube()->fileName()) {
322  save();
323  return;
324  }
325 
326  //Save the current cube's changes by reopening it, and open an input cube
327  //from the current cube's location
328  Cube *icube = new Cube();
329  icube->open(cubeViewport()->cube()->fileName(), "rw");
330  Cube *ocube = NULL;
331 
332  // The output cube needs to be created if the scale is 1 since saveAs_FullResolution will be
333  // called, which expects a cube.
334  // NOTE: This really should be cleaned up and the cube should be created in 1 place.
335  if (p_saveAsDialog->getSaveAsType() != SaveAsDialog::ExportAsIs ||
336  p_lastViewport->scale() == 1) {
337  //Create the output cube
338  ocube = new Cube;
339  }
340 
341  if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::FullImage) {
342  copyCubeDetails(psOutFile, icube, ocube, icube->sampleCount(),
343  icube->lineCount(), icube->bandCount());
344  saveAsFullImage(icube, ocube);
345  ocube->close();
346  }
347  else {
348  // start and end Samples and Lines
349  double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
350  p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
351 
352  if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::ExportFullRes ||
353  p_lastViewport->scale() == 1) {
354 // int numSamples = (int)ceil(dEndSample-dStartSample);
355 // int numLines = (int)ceil(dEndLine-dStartLine);
356  int numSamples = (int)((dEndSample - dStartSample + 1) + 0.5);
357  int numLines = (int)((dEndLine - dStartLine + 1) + 0.5);
358  copyCubeDetails(psOutFile, icube, ocube, numSamples, numLines, icube->bandCount());
359  saveAs_FullResolution(icube, ocube, numSamples, numLines);
360  ocube->close();
361  }
362  else if (p_saveAsDialog->getSaveAsType() == SaveAsDialog::ExportAsIs ) {
363  saveAs_AsIs(icube, psOutFile);
364  }
365  }
366 
367  emit(fileSelected(psOutFile));
368 
369  //Disable the save action
370  p_save->setEnabled(false);
371 
372  p_lastDir = psOutFile;
373  }
374 
385  void FileTool::saveAsEnlargedCube(Cube *icube, const QString & psOutFile) {
386  double dScale = p_lastViewport->scale();
387 
388  // start and end Samples and Lines
389  double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
390  p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
391 
392  double ins = dEndSample - dStartSample + 1;
393  double inl = dEndLine - dStartLine + 1;
394 
395  double ons = (int)(ins * dScale + 0.5);
396  double onl = (int)(inl * dScale + 0.5);
397 
398  try {
400  p.SetInputCube (icube);
401  Cube *ocube = p.SetOutputCube(psOutFile, CubeAttributeOutput(" "),
402  ons, onl, icube->bandCount());
403 
404  Interpolator *interp = new Interpolator(Interpolator::NearestNeighborType);
405 
406  Enlarge *imgEnlarge = new Enlarge(icube, dScale, dScale);
407  imgEnlarge->SetInputArea((int)dStartSample, (int)dEndSample, (int)dStartLine, (int)dEndLine);
408 
409  p.StartProcess(*imgEnlarge, *interp);
410  imgEnlarge->UpdateOutputLabel(ocube);
411  p.EndProcess();
412 
413  delete imgEnlarge;
414  delete interp;
415 
416  } catch(IException &) {
417  QMessageBox::critical((QWidget *)parent(),
418  "Error", "Cannot open file, please check permissions");
419  }
420  }
421 
431  void FileTool::saveAsReducedCube(Cube *icube, const QString & psOutFile) {
432 
433  double dScale = p_lastViewport->scale();
434  // start and end Samples and Lines
435  double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
436  p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
437 
438  double ins = dEndSample - dStartSample + 1;
439  double inl = dEndLine - dStartLine + 1;
440 
441  double ons = (int)(ins * dScale + 0.5);
442  double onl = (int)(inl * dScale + 0.5);
443 
444  CubeAttributeInput cai(icube->fileName());
445  std::vector<QString> bands = cai.bands();
446  int inb = bands.size();
447 
448  if (inb == 0) {
449  inb = cubeViewport()->cube()->bandCount();
450  for(int i = 1; i <= inb; i++) {
451  bands.push_back(toString(i));
452  }
453  }
454 
455  ProcessByLine p;
456  p.SetInputCube (icube);
457  Cube *ocube = NULL;
458  try {
459  ocube = p.SetOutputCube(psOutFile, CubeAttributeOutput(""), ons, onl, inb);
460  // Our processing routine only needs 1
461  // the original set was for info about the cube only
462  p.ClearInputCubes();
463  }
464  catch(IException &) {
465  // If there is a problem, catch it and close the cube so it isn't open next time around
466  icube->close();
467  throw;
468  }
469 
470  Cube *tempcube=new Cube;
471  tempcube->open(cubeViewport()->cube()->fileName(), "r");
472  Nearest *near = new Nearest(tempcube, ins/ons, inl/onl);
473  near->setInputBoundary((int)dStartSample, (int)dEndSample, (int)dStartLine, (int)dEndLine);
474 
475  p.ProcessCubeInPlace(*near, false);
476  near->UpdateOutputLabel(ocube);
477  p.EndProcess();
478 
479  delete near;
480  near=NULL;
481  }
482 
491  void FileTool::saveAs_AsIs(Cube *icube, const QString & psOutFile) {
492  double dScale = p_lastViewport->scale();
493  // Enlarge the cube area
494  if (dScale > 1) {
495  saveAsEnlargedCube(icube, psOutFile);
496  }
497  // Reduce the cube area
498  else {
499  saveAsReducedCube(icube, psOutFile);
500  }
501  }
502 
517  void FileTool::copyCubeDetails(const QString & psOutFile, Cube *icube,
518  Cube *ocube, int piNumSamples, int piNumLines, int piNumBands) {
519  //Create the default output attribute with the output filename
520  CubeAttributeOutput outAtt(psOutFile);
521 
522  //Propagate all labels, tables, blobs, etc from the input to output cube
523  try {
524  ocube->setDimensions(piNumSamples, piNumLines, piNumBands);
525  ocube->setByteOrder(outAtt.byteOrder());
526  ocube->setFormat(outAtt.fileFormat());
527  ocube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);
528 
529  if (outAtt.propagatePixelType()) {
530  ocube->setPixelType(icube->pixelType());
531  }
532  else {
533  ocube->setPixelType(outAtt.pixelType());
534  }
535 
536  if (outAtt.propagateMinimumMaximum()) {
537  if (ocube->pixelType() == Real) {
538  ocube->setBaseMultiplier(0.0, 1.0);
539  }
540  else if (ocube->pixelType() >= icube->pixelType()) {
541  double base = icube->base();
542  double mult = icube->multiplier();
543  ocube->setBaseMultiplier(base, mult);
544  }
545  else if ((ocube->pixelType() != Real) &&
546  (ocube->pixelType() != UnsignedByte) &&
547  (ocube->pixelType() != SignedWord)) {
548  QString msg = "Looks like your refactoring to add different pixel types";
549  msg += " you'll need to make changes here";
551  }
552  else {
553  QString msg = "You've chosen to reduce your output PixelType for [" +
554  psOutFile + "] you must specify the output pixel range too";
556  }
557  }
558  else {
559  // Not propagating so either the user entered or the programmer did
560  ocube->setMinMax(outAtt.minimum(), outAtt.maximum());
561  }
562 
563  int needLabBytes = icube->labelSize(true) + (1024 * 6);
564  if (needLabBytes > ocube->labelSize()) {
565  ocube->setLabelSize(needLabBytes);
566  }
567 
568  // Allocate the cube
569  ocube->create(psOutFile);
570 
571  // Transfer labels from the first input cube
572  PvlObject &incube = icube->label()->findObject("IsisCube");
573  PvlObject &outcube = ocube->label()->findObject("IsisCube");
574  for(int i = 0; i < incube.groups(); i++) {
575  outcube.addGroup(incube.group(i));
576  }
577 
578  // Transfer tables from the first input cube
579  Pvl &inlab = *icube->label();
580  for(int i = 0; i < inlab.objects(); i++) {
581  if (inlab.object(i).isNamed("Table")) {
582  Blob t((QString)inlab.object(i)["Name"], inlab.object(i).name());
583  icube->read(t);
584  ocube->write(t);
585  }
586  }
587 
588  // Transfer blobs from the first input cube
589  inlab = *icube->label();
590  for(int i = 0; i < inlab.objects(); i++) {
591  if (inlab.object(i).isNamed("Polygon")) {
592  Blob t((QString)inlab.object(i)["Name"], inlab.object(i).name());
593  icube->read(t);
594  ocube->write(t);
595  }
596  }
597 
598  // Transfer tables from the first input cube
599  inlab = *icube->label();
600  for(int i = 0; i < inlab.objects(); i++) {
601  if (inlab.object(i).isNamed("OriginalLabel")) {
602  OriginalLabel ol;
603  icube->read(ol);
604  ocube->write(ol);
605  }
606  }
607  }
608  catch(IException &) {
609  delete ocube;
610  throw;
611  }
612  }
613 
624  void FileTool::saveAsFullImage(Cube *icube, Cube *ocube) {
625  //Start the copy process line by line
626  Brick ibrick(*icube, icube->sampleCount(), 1, 1);
627  Brick obrick(*ocube, ocube->sampleCount(), 1, 1);
628 
629  int numBricks;
630  if (ibrick.Bricks() > obrick.Bricks()) {
631  numBricks = ibrick.Bricks();
632  }
633  else {
634  numBricks = obrick.Bricks();
635  }
636 
637  // Loop and let the app programmer work with the bricks
638  ibrick.begin();
639  obrick.begin();
640  for(int i = 0; i < numBricks; i++) {
641  icube->read(ibrick);
642  //Copy the contents to the output cube
643  copy(ibrick, obrick);
644  ocube->write(obrick);
645  ibrick++;
646  obrick++;
647  }
648  }
649 
662  Cube *pOutCube, int pNumSamples, int pNumLines) {
663  // start and end Samples and Lines
664  double dStartSample=0, dEndSample=0, dStartLine=0, dEndLine=0;
665  p_lastViewport->getCubeArea(dStartSample, dEndSample, dStartLine, dEndLine);
666  int iNumBands = pInCube->bandCount();
667 
668  PvlGroup results("Results");
669  results += PvlKeyword("InputLines", toString(pInCube->lineCount()));
670  results += PvlKeyword("InputSamples", toString(pInCube->sampleCount()));
671  results += PvlKeyword("StartingLine", toString(dStartLine));
672  results += PvlKeyword("StartingSample", toString(dStartSample));
673  results += PvlKeyword("EndingLine", toString(dEndLine));
674  results += PvlKeyword("EndingSample", toString(dEndSample));
675  results += PvlKeyword("LineIncrement", toString(1));
676  results += PvlKeyword("SampleIncrement", toString(1));
677  results += PvlKeyword("OutputLines", toString(pNumLines));
678  results += PvlKeyword("OutputSamples", toString(pNumSamples));
679  SubArea subArea;
680  subArea.SetSubArea(pInCube->lineCount(), pInCube->sampleCount(), dStartLine, dStartSample,
681  dEndLine, dEndSample, 1.0, 1.0);
682  subArea.UpdateLabel(pInCube, pOutCube, results);
683 
684  Portal iPortal (pNumSamples, 1, pInCube->pixelType());
685  Portal oPortal (pNumSamples, 1, pOutCube->pixelType());
686 
687  for(int iBand=1; iBand<=iNumBands; iBand++) {
688  int ol=1;
689  for(int iLine=(int)dStartLine; iLine<=(int)dEndLine; iLine++) {
690  iPortal.SetPosition(dStartSample, iLine, iBand);
691  pInCube->read(iPortal);
692 
693  oPortal.SetPosition(1, ol++, iBand);
694  pOutCube->read(oPortal);
695 
696  oPortal.Copy(iPortal);
697  pOutCube->write(oPortal);
698  }
699  }
700  }
701 
709  {
710  if (cubeViewport() == NULL) {
711  QMessageBox::information((QWidget *)parent(), "Error", "No active cube to save info");
712  return;
713  }
714 
715  //Get the new cube's filename
716  QString output =
717  QFileDialog::getSaveFileName((QWidget *)parent(),
718  "Choose output file",
719  p_lastDir,
720  QString("PVL Files (*.pvl)"));
721 
722  //If the filename is empty, return
723  if (output.isEmpty()) {
724  return;
725  }
726  else if (!output.endsWith(".pvl")) {
727  output += ".pvl";
728  }
729 
730  Pvl whatsThisPvl;
731  cubeViewport()->getAllWhatsThisInfo(whatsThisPvl);
732  whatsThisPvl.write(output);
733  }
734 
741  void FileTool::copy(Buffer &in, Buffer &out) {
742  out.Copy(in);
743  }
744 
752  }
753 
759  if (cubeViewport() == NULL) {
760  QMessageBox::information((QWidget *)parent(), "Error", "No active cube to export");
761  return;
762  }
763 
764  QString output =
765  QFileDialog::getSaveFileName((QWidget *)parent(),
766  QString("Choose output file"),
767  p_lastDir,
768  QString("PNG (*.png);;JPG (*.jpg);;TIF (*.tif)"));
769  if (output.isEmpty()) return;
770 
771  p_lastDir = output;
772 
773  QString format = QFileInfo(output).suffix();
774 
775  if (format.isEmpty()) {
776  if (output.endsWith('.')) {
777  output.append(QString("png"));
778  }
779  else {
780  output.append(QString(".png"));
781  }
782  }
783  else if (format.compare("png", Qt::CaseInsensitive) &&
784  format.compare("jpg", Qt::CaseInsensitive) &&
785  format.compare("tif", Qt::CaseInsensitive)) {
786 
787  QMessageBox::information((QWidget *)parent(), "Error", format + " is an invalid extension.");
788  return;
789  }
790 
791  QPixmap pm = QPixmap::grabWidget(cubeViewport()->viewport());
792 
793  //if (!cubeViewport()->pixmap().save(output,format)) {
794 
795  if (!pm.save(output)) {
796  QMessageBox::information((QWidget *)parent(), "Error", "Unable to save " + output);
797  return;
798  }
799  }
800 
806  // Is there anything to print
807  if (cubeViewport() == NULL) {
808  QMessageBox::information((QWidget *)parent(), "Error", "No active cube to print");
809  return;
810  }
811 
812  // Initialize a printer
813  static QPrinter *printer = NULL;
814  if (printer == NULL) printer = new QPrinter;
815  printer->setPageSize(QPrinter::Letter);
816  printer->setColorMode(QPrinter::GrayScale);
817  if (cubeViewport()->isColor()) printer->setColorMode(QPrinter::Color);
818 
819  QPrintDialog printDialog(printer, (QWidget *)parent());
820  if (printDialog.exec() == QDialog::Accepted) {
821  // Get display widget as a pixmap and convert to an image
822  QPixmap pixmap = QPixmap::grabWidget(cubeViewport()->viewport());
823  QImage img = pixmap.toImage();
824 
825  // C++ Gui Programmign with Qt, page 201
826  QPainter painter(printer);
827  QRect rect = painter.viewport();
828  QSize size = img.size();
829  size.scale(rect.size(), Qt::KeepAspectRatio);
830  painter.setViewport(rect.x(), rect.y(),
831  size.width(), size.height());
832  painter.setWindow(img.rect());
833  painter.drawImage(0, 0, img);
834  }
835  }
836 
841  // Close all cubes
842  // We must create a temporary list. If not the actual
843  // list size gets modified when a close occurs and not all
844  // windows were being closed.
845  MdiCubeViewport *d;
847  for(int i = 0; i < (int)tempList.size(); i++) {
848  d = tempList.at(i);
849  //Set the current viewport to the one being closed
850  setCubeViewport(d);
851 
852  if (!d->parentWidget()->close()) {
853  return false;
854  }
855  }
856  return true;
857  }
858 
867  void FileTool::exit() {
868  QWidget *mainWindow = qobject_cast<QWidget *>(p_parent);
869 
870  if (mainWindow)
871  mainWindow->close();
872  }
873 
879  void FileTool::enableSave(bool enable) {
880  p_save->setEnabled(enable);
881  }
882 
888  if (cubeViewport() == NULL) {
889  if (p_lastViewport != NULL) {
890  p_lastViewport = NULL;
891  }
892  p_print->setEnabled(false);
893  p_save->setEnabled(false);
894  p_exportView->setEnabled(false);
895  p_saveAs->setEnabled(false);
896  p_saveInfo->setEnabled(false);
897  }
898  else {
899  if (p_lastViewport == NULL) {
900  //Set the last viewport to the current viewport and connect signals to save and discard
902  connect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
903  }
904  else {
905  if (p_lastViewport != cubeViewport()) {
906  //If the viewport has changes made to it enable the save action
907  if (cubeViewport()->parentWidget()->windowTitle().endsWith("*")) {
908  p_save->setEnabled(true);
909  }
910  //Else disable it
911  else {
912  p_save->setEnabled(false);
913  }
914  //disconnect signals from the old viewport and connect them to the new viewport
915  disconnect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
916  disconnect(p_lastViewport, SIGNAL(discardChanges(CubeViewport *)), this, SLOT(discard()));
918  connect(p_lastViewport, SIGNAL(saveChanges(CubeViewport *)), this, SLOT(save()));
919  connect(p_lastViewport, SIGNAL(discardChanges(CubeViewport *)), this, SLOT(discard()));
920  }
921  }
922  p_print->setEnabled(true);
923  p_exportView->setEnabled(true);
924  p_saveAs->setEnabled(true);
925  p_saveInfo->setEnabled(true);
926  }
927  }
928 }