Isis 3 Programmer Reference
ShapeReader.cpp
1 #include "ShapeReader.h"
2 
3 #include <QAction>
4 #include <QApplication>
5 #include <QDebug>
6 #include <QFuture>
7 #include <QFutureWatcher>
8 #include <QInputDialog>
9 #include <QList>
10 #include <QProgressBar>
11 #include <QSettings>
12 #include <QString>
13 #include <QtConcurrentMap>
14 #include <QVariant>
15 
16 #include "IException.h"
17 #include "Shape.h"
18 #include "ShapeDisplayProperties.h"
19 #include "IString.h"
20 #include "FileName.h"
21 #include "ProgressBar.h"
22 #include "PvlObject.h"
23 
24 namespace Isis {
25 
35  ShapeReader::ShapeReader(QMutex *cameraMutex, bool requireFootprints, QObject *parent) :
36  QObject(parent) {
37  m_watcher = NULL;
38 
39  m_cameraMutex = cameraMutex;
40  m_requireFootprints = requireFootprints;
41 
42  m_progress = new ProgressBar("Reading Shapes");
43  m_watcher = new QFutureWatcher<Shape *>;
44 
45  initProgress();
46 
47  connect(m_watcher, SIGNAL(resultReadyAt(int)),
48  this, SLOT(shapesReady(int)));
49  connect(m_watcher, SIGNAL(finished()),
50  this, SLOT(mappedFinished()));
51 
52  m_safeFileOpen = false;
53  m_openFilled = true;
54  m_defaultAlpha = 60;
55 
56  m_mappedRunning = false;
57 
58  readSettings();
59  }
60 
61 
66  writeSettings();
67 
68  if (m_watcher) {
69  m_watcher->cancel();
70  m_watcher->waitForFinished();
71  }
72 
73  delete m_watcher;
74  m_watcher = NULL;
75 
76  m_backlog.clear();
77 
78  m_cameraMutex = NULL;
79 
80  delete m_progress;
81  }
82 
83 
84  QList<QAction *> ShapeReader::actions(ShapeDisplayProperties::Property relevantDispProperties) {
85  QList<QAction *> results;
86 
87  if (!m_safeFileOpenAct) {
88  m_safeFileOpenAct = new QAction(tr("&Safe File Open"), this);
89  m_safeFileOpenAct->setCheckable(true);
90  m_safeFileOpenAct->setChecked(m_safeFileOpen);
91  m_safeFileOpenAct->setWhatsThis(tr("This lowers the number of "
92  "simulataneously open files drastically in order to stay under the "
93  "operating system limit. Only use this if you are having trouble "
94  "loading large numbers of shapes."));
95  connect(m_safeFileOpenAct, SIGNAL(toggled(bool)),
96  this, SLOT(setSafeFileOpen(bool)));
97  }
98 
99  results.append(m_safeFileOpenAct);
100 
101  return results;
102  }
103 
104 
105  QProgressBar *ShapeReader::progress() {
106  return m_progress;
107  }
108 
109 
110  void ShapeReader::read(PvlObject shapesObject) {
111  read(shapesObject.beginObject(), shapesObject.endObject());
112  }
113 
114 
118  void ShapeReader::read(QStringList cubeNames) {
119  read(cubeNames.begin(), cubeNames.end());
120  }
121 
122 
123  void ShapeReader::setSafeFileOpen(bool safeFileOpen) {
124  m_safeFileOpen = safeFileOpen;
125  if (m_safeFileOpen) {
126  m_safeFileOpenAct->setChecked(m_safeFileOpen);
127  }
128  }
129 
130 
131  void ShapeReader::initProgress() {
132  m_progress->setVisible(false);
133  m_progress->setRange(0, 0);
134  m_progress->setValue(0);
135  }
136 
137 
138  void ShapeReader::start() {
139  if (!m_backlog.isEmpty() && !m_mappedRunning) {
140  m_progress->setVisible(true);
141 
142  int maxOpenShapes = m_safeFileOpen? 20 : 400;
143  QList<QVariant> culledBacklog = m_backlog.mid(0, maxOpenShapes);
144  m_backlog = m_backlog.mid(maxOpenShapes);
145 
146  QFuture< Shape * > shapes = QtConcurrent::mapped(
147  culledBacklog,
148  VariantToShapeFunctor(m_cameraMutex, m_requireFootprints, QThread::currentThread(),
149  m_openFilled, m_defaultAlpha));
150 
151  m_watcher->setFuture(shapes);
152  m_mappedRunning = true;
153  }
154  }
155 
156 
157  void ShapeReader::readSettings() {
158  QSettings settings(
159  FileName("$HOME/.Isis/" + QApplication::applicationName() + "/Shape Reader.config")
160  .expanded(),
161  QSettings::NativeFormat);
162 
163  m_safeFileOpen = settings.value("safeFileOpen", m_safeFileOpen).toBool();
164  }
165 
166 
167  void ShapeReader::writeSettings() {
168  QSettings settings(
169  FileName("$HOME/.Isis/" + QApplication::applicationName() + "/Shape Reader.config")
170  .expanded(),
171  QSettings::NativeFormat);
172 
173  settings.setValue("safeFileOpen", m_safeFileOpen);
174  }
175 
176 
177  void ShapeReader::shapesReady(int index) {
178  m_progress->setValue(m_progress->value() + 1);
179  }
180 
181 
182  void ShapeReader::mappedFinished() {
183  ShapeList shapes(m_watcher->future().results());
184 
185  // Tracie Sucharski: Go through list & get rid of NULLs. This is a temporary fix to get rid
186  // of seg faulting when something goes wrong. This is not a good solution & needs to be
187  // properly fixed
188  foreach (Shape *shape, shapes) {
189  if (!shape) {
190  shapes.removeAll(shape);
191  }
192  }
193 
194  emit shapesReady(shapes);
195 
196  m_mappedRunning = false;
197  if (!m_backlog.isEmpty()) {
198  start();
199  }
200  else {
201  initProgress();
202  }
203  }
204 
205 
212  QMutex *cameraMutex, bool requireFootprints, QThread *targetThread, bool openFilled,
213  int defaultAlpha) {
214  m_mutex = cameraMutex;
215  m_targetThread = targetThread;
216  m_openFilled = openFilled;
217  m_defaultAlpha = defaultAlpha;
218  m_requireFootprints = requireFootprints;
219  }
220 
221 
230  const QVariant &shapeData) {
231  Shape *result = NULL;
232 
233  try {
234  QString fileName;
235  if (shapeData.canConvert<QString>()) {
236  fileName = shapeData.value<QString>();
237 
238  result = new Shape(FileName(fileName).expanded());
239  }
240  else if (shapeData.canConvert<PvlObject>()) {
241  PvlObject shapeObj = shapeData.value<PvlObject>();
242  fileName = ((IString)shapeObj["FileName"][0]).ToQt();
243  result = new Shape(FileName(fileName).expanded());
244  result->fromPvl(shapeObj);
245  }
246 
247  if (m_requireFootprints) {
248  try {
249  result->initFootprint(m_mutex);
250  }
251  catch (IException &) {
252  throw;
253  }
254  }
255 
256  result->moveToThread(m_targetThread);
257  }
258  catch(IException &e) {
259  e.print();
260  result = NULL;
261  }
262 
263  return result;
264  }
265 }
ShapeReader(QMutex *cameraMutex, bool requireFootprints=false, QObject *parent=NULL)
MosaicWidget constructor.
Definition: ShapeReader.cpp:35
virtual ~ShapeReader()
Free the allocated memory by this object.
Definition: ShapeReader.cpp:65
File name manipulation and expansion.
Definition: FileName.h:116
bool initFootprint(QMutex *cameraMutex)
Calculate a footprint for this shape.
Definition: Shape.cpp:422
void fromPvl(const PvlObject &pvl)
Read the shape settings from a Pvl.
Definition: Shape.cpp:236
void print() const
Prints a string representation of this exception to stderr.
Definition: IException.cpp:461
This represents a shape in a project-based GUI interface.
Definition: Shape.h:78
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Property
This is a list of properties and actions that are possible.
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
VariantToShapeFunctor(QMutex *cameraMutex, bool requireFootprints, QThread *targetThread, bool openFilled, int defaultAlpha)
Create a functor for converting from QVariant to an Shape *.
Shape * operator()(const QVariant &)
Read the QString filename and make an Shape from it.