Isis 3 Programmer Reference
ShapeList.cpp
Go to the documentation of this file.
1 
23 #include "ShapeList.h"
24 
25 #include <QDebug>
26 #include <QDir>
27 #include <QFile>
28 #include <QFuture>
29 #include <QInputDialog>
30 #include <QLabel>
31 #include <QProgressDialog>
32 #include <QtConcurrentMap>
33 #include <QXmlStreamWriter>
34 
35 #include "FileName.h"
36 #include "IException.h"
37 #include "IString.h"
38 #include "Project.h"
39 #include "XmlStackedHandlerReader.h"
40 
41 namespace Isis {
49  ShapeList::ShapeList(QString name, QString path, QObject *parent) : QObject(parent) {
50  m_name = name;
51  m_path = path;
52  }
53 
54 
60  ShapeList::ShapeList(QObject *parent) : QObject(parent) {
61  }
62 
63 
70  ShapeList::ShapeList(QList<Shape *> shapes, QObject *parent) : QObject(parent) {
71  append(shapes);
72  }
73 
74 
83  QObject(parent) {
84  xmlReader->pushContentHandler(new XmlHandler(this, project));
85  }
86 
87 
94  QList<Shape *>(other) {
95  m_name = other.m_name;
96  m_path = other.m_path;
97  }
98 
99 
106  foreach (QString fileName, fileNames) {
107  try {
108  Shape *shape = new Shape(fileName);
109  append(shape);
110  }
111  catch (IException &) {
112  }
113  }
114  }
115 
116 
121  }
122 
123 
130 
131  SerialNumberList result;
132 
133  for (int i = 0; i < count(); i++) {
134  result.add((*this)[i]->fileName());
135  }
136  return result;
137  }
138 
139 
147  void ShapeList::append(Shape * const &value) {
148  QList<Shape *>::append(value);
149  emit countChanged(count());
150  }
151 
152 
160  void ShapeList::append(const QList<Shape *> &value) {
161  QList<Shape *>::append(value);
162  emit countChanged(count());
163  }
164 
165 
172  bool countChanging = count();
174  if (countChanging) {
175  emit countChanged(count());
176  }
177  }
178 
179 
190  iterator result = QList<Shape *>::erase(pos);
191  emit countChanged(count());
192  return result;
193  }
194 
195 
208  QList<Shape *>::iterator ShapeList::erase(iterator begin, iterator end) {
209  iterator result = QList<Shape *>::erase(begin, end);
210  emit countChanged(count());
211  return result;
212  }
213 
214 
223  void ShapeList::insert(int i, Shape * const &value) {
224  QList<Shape *>::insert(i, value);
225 
226  emit countChanged(count());
227  }
228 
229 
240  QList<Shape *>::iterator ShapeList::insert(iterator before, Shape * const &value) {
241  iterator result = QList<Shape *>::insert(before, value);
242  emit countChanged(count());
243  return result;
244  }
245 
246 
254  void ShapeList::prepend(Shape * const &value) {
256  emit countChanged(count());
257  }
258 
259 
268  void ShapeList::push_back(Shape * const &value) {
270  emit countChanged(count());
271  }
272 
273 
282  void ShapeList::push_front(Shape * const &value) {
284  emit countChanged(count());
285  }
286 
287 
297  int ShapeList::removeAll(Shape * const &value) {
298  int result = QList<Shape *>::removeAll(value);
299 
300  if (result != 0) {
301  emit countChanged(count());
302  }
303 
304  return result;
305  }
306 
307 
315  void ShapeList::removeAt(int i) {
317  emit countChanged(count());
318  }
319 
320 
328  emit countChanged(count());
329  }
330 
331 
339  emit countChanged(count());
340  }
341 
342 
352  bool ShapeList::removeOne(Shape * const &value) {
353  bool result = QList<Shape *>::removeOne(value);
354 
355  if (result) {
356  emit countChanged(count());
357  }
358 
359  return result;
360  }
361 
362 
371  QList<Shape *>::swap(other);
372 
373  if (count() != other.count()) {
374  emit countChanged(count());
375  }
376  }
377 
378 
389  Shape * result = QList<Shape *>::takeAt(i);
390  emit countChanged(count());
391  return result;
392  }
393 
394 
403  Shape *result = QList<Shape *>::takeFirst();
404  emit countChanged(count());
405  return result;
406  }
407 
408 
417  Shape *result = QList<Shape *>::takeLast();
418  emit countChanged(count());
419  return result;
420  }
421 
422 
435 
436  if (other.count()) {
437  emit countChanged(count());
438  }
439 
440  return *this;
441  }
442 
443 
456  emit countChanged(count());
457  return *this;
458  }
459 
460 
471  ShapeList &ShapeList::operator<<(const QList<Shape *> &other) {
473 
474  if (other.count()) {
475  emit countChanged(count());
476  }
477 
478  return *this;
479  }
480 
481 
494  emit countChanged(count());
495  return *this;
496  }
497 
498 
509  bool countChanging = (rhs.count() != count());
511 
512  if (countChanging) {
513  emit countChanged(count());
514  }
515 
516  return *this;
517  }
518 
519 
528  bool countChanging = (rhs.count() != count());
530 
531  m_name = rhs.m_name;
532  m_path = rhs.m_path;
533 
534  if (countChanging) {
535  emit countChanged(count());
536  }
537 
538  return *this;
539  }
540 
541 
548  void ShapeList::setName(QString newName) {
549  m_name = newName;
550  }
551 
552 
559  void ShapeList::setPath(QString newPath) {
560  m_path = newPath;
561  }
562 
563 
569  QString ShapeList::name() const {
570  return m_name;
571  }
572 
573 
580  QString ShapeList::path() const {
581  return m_path;
582  }
583 
584 
593  foreach (Shape *shape, *this) {
594  shape->deleteFromDisk();
595  }
596 
597  if (!m_path.isEmpty()) {
598  QFile::remove(project->shapeDataRoot() + "/" + m_path + "/shapes.xml");
599 
600  QDir dir;
601  dir.rmdir(project->shapeDataRoot() + "/" + m_path);
602  }
603  }
604 
605 
629  void ShapeList::save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot)
630  const {
631  stream.writeStartElement("shapeList");
632  stream.writeAttribute("name", m_name);
633  stream.writeAttribute("path", m_path);
634 
635  FileName settingsFileName(
636  Project::shapeDataRoot(newProjectRoot.toString()) + "/" + m_path + "/shapes.xml");
637 
638  if (!settingsFileName.dir().mkpath(settingsFileName.path())) {
640  QString("Failed to create directory [%1]")
641  .arg(settingsFileName.path()),
642  _FILEINFO_);
643  }
644 
645  QFile shapeListContentsFile(settingsFileName.toString());
646 
647  if (!shapeListContentsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
649  QString("Unable to save shape information for [%1] because [%2] could not be opened for "
650  "writing")
651  .arg(m_name).arg(settingsFileName.original()),
652  _FILEINFO_);
653  }
654 
655  QXmlStreamWriter shapeDetailsWriter(&shapeListContentsFile);
656  shapeDetailsWriter.setAutoFormatting(true);
657  shapeDetailsWriter.writeStartDocument();
658 
659  int countWidth = QString("%1L").arg(count()).size() - 1;
660  QChar paddingChar('0');
661 
662  QLabel *progressLabel = new QLabel;
663 
664  QProgressDialog progressDialog;
665  progressDialog.setLabel(progressLabel);
666  progressDialog.setRange(-1, count());
667  progressDialog.setValue(-1);
668 
669  shapeDetailsWriter.writeStartElement("shapes");
670  // Mapped is way faster than hundreds/thousands of run() calls... so use mapped for performance
671  QFuture<void *> future = QtConcurrent::mapped(*this,
672  CopyShapeDataFunctor(project, newProjectRoot));
673 
674  for (int i = 0; i < count(); i++) {
675  int newProgressValue = progressDialog.value() + 1;
676  progressLabel->setText(
677  tr("Saving Shape Information for [%1] - %L2/%L3 done")
678  .arg(m_name)
679  .arg(newProgressValue, countWidth, 10, paddingChar)
680  .arg(count()));
681  progressDialog.setValue(newProgressValue);
682  future.resultAt(i);
683  }
684 
685  progressLabel->setText(tr("Finalizing..."));
686  progressDialog.setRange(0, 0);
687  progressDialog.setValue(0);
688 
689  foreach (Shape *shape, *this) {
690  shape->save(shapeDetailsWriter, project, newProjectRoot);
691  }
692 
693  shapeDetailsWriter.writeEndElement();
694 
695  shapeDetailsWriter.writeEndDocument();
696 
697  stream.writeEndElement();
698  }
699 
700 
708  FileName newProjectRoot) {
709  m_project = project;
710  m_newProjectRoot = newProjectRoot;
711  }
712 
713 
720  m_project = other.m_project;
721  m_newProjectRoot = other.m_newProjectRoot;
722  }
723 
724 
729  }
730 
731 
741  shapeToCopy->copyToNewProjectRoot(m_project, m_newProjectRoot);
742  return NULL;
743  }
744 
745 
754  const CopyShapeDataFunctor &rhs) {
755  m_project = rhs.m_project;
756  m_newProjectRoot = rhs.m_newProjectRoot;
757  return *this;
758  }
759 
760 
770  m_shapeList = shapeList;
771  m_project = project;
772  }
773 
774 
781  bool ShapeList::XmlHandler::startElement(const QString &namespaceURI, const QString &localName,
782  const QString &qName, const QXmlAttributes &atts) {
783  if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
784  if (localName == "shapeList") {
785  QString name = atts.value("name");
786  QString path = atts.value("path");
787 
788  if (!name.isEmpty()) {
789  m_shapeList->setName(name);
790  }
791 
792  if (!path.isEmpty()) {
793  m_shapeList->setPath(path);
794  }
795  }
796  else if (localName == "shape") {
797  m_shapeList->append(new Shape(m_project->shapeDataRoot() + "/" + m_shapeList->path(),
798  reader()));
799  }
800  }
801 
802  return true;
803  }
804 
805 
815  bool ShapeList::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
816  const QString &qName) {
817  if (localName == "shapeList") {
818  XmlHandler handler(m_shapeList, m_project);
819 
821  reader.pushContentHandler(&handler);
822  reader.setErrorHandler(&handler);
823 
824  QString shapeListXmlPath = m_project->shapeDataRoot() + "/" + m_shapeList->path() +
825  "/shapes.xml";
826  QFile file(shapeListXmlPath);
827 
828  if (!file.open(QFile::ReadOnly)) {
830  QString("Unable to open [%1] with read access")
831  .arg(shapeListXmlPath),
832  _FILEINFO_);
833  }
834 
835  QXmlInputSource xmlInputSource(&file);
836  if (!reader.parse(xmlInputSource))
838  tr("Failed to open shape list XML [%1]").arg(shapeListXmlPath),
839  _FILEINFO_);
840  }
841 
842  return XmlStackedHandler::endElement(namespaceURI, localName, qName);
843  }
844 }
ShapeList & operator+=(const QList< Shape *> &other)
Appends a list of shapes to the end of the shape list.
Definition: ShapeList.cpp:433
Internalizes a list of shapes and allows for operations on the entire list.
Definition: ShapeList.h:33
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:119
QString path() const
Get the path to the shapes in the shape list (relative to project root).
Definition: ShapeList.cpp:580
The main project for ipce.
Definition: Project.h:289
ShapeList & operator<<(const QList< Shape *> &other)
Appends a list of shapes to the end of the shape list.
Definition: ShapeList.cpp:471
File name manipulation and expansion.
Definition: FileName.h:116
void prepend(Shape *const &value)
Inserts an shape at the beginning of the shape list.
Definition: ShapeList.cpp:254
void deleteFromDisk(Project *project)
Delete all of the contained Shapes from disk.
Definition: ShapeList.cpp:592
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name &#39;shapes&#39; to the project .
Definition: Project.cpp:2087
~ShapeList()
Destructor.
Definition: ShapeList.cpp:120
void setPath(QString newPath)
Set the relative path (from the project root) to this shape list&#39;s folder.
Definition: ShapeList.cpp:559
void copyToNewProjectRoot(const Project *project, FileName newProjectRoot)
Copy the cub/ecub files associated with this shape into the new project.
Definition: Shape.cpp:556
CopyShapeDataFunctor(const Project *project, FileName newProjectRoot)
Constructor for CopyShapeDataFunctor.
Definition: ShapeList.cpp:707
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Convert this shape list into XML format for saving/restoring capabilities.
Definition: ShapeList.cpp:629
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
This functor is used for copying the shapes between two projects quickly.
Definition: ShapeList.h:137
const Project * m_project
This stores the name of the project that is going to be copied to.
Definition: ShapeList.h:151
This class is used to read an shapes.xml file into an shape list.
Definition: ShapeList.h:105
void setName(QString newName)
Set the human-readable name of this shape list.
Definition: ShapeList.cpp:548
void clear()
Clears the shape list.
Definition: ShapeList.cpp:171
FileName m_newProjectRoot
This stores the path to the root of the project that is going to be copied to.
Definition: ShapeList.h:155
QDebug operator<<(QDebug dbg, const Isis::Angle &angleToPrint)
Display an Angle for a debugging statement.
Definition: Angle.cpp:383
void removeLast()
Removes the shape at the end of the shape list.
Definition: ShapeList.cpp:337
void removeFirst()
Removes the shape at the front of the shape list.
Definition: ShapeList.cpp:326
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Output format:
Definition: Shape.cpp:846
ShapeList & operator=(const QList< Shape *> &rhs)
Assigns another list of shapes to the shape list.
Definition: ShapeList.cpp:508
void swap(QList< Shape *> &other)
Swaps the shape list with another list of shapes.
Definition: ShapeList.cpp:370
void removeAt(int i)
Removes the shape at an index.
Definition: ShapeList.cpp:315
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition: Project.cpp:2097
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
void append(Shape *const &value)
Appends an shape to the shape list.
Definition: ShapeList.cpp:147
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
SerialNumberList serialNumberList()
Creates a SerialNumberList from the shape list.
Definition: ShapeList.cpp:129
QString original() const
Returns the full file name including the file path.
Definition: FileName.cpp:228
XmlHandler(ShapeList *shapeList, Project *project)
Create an XML Handler (reader) that can populate the Shape list class data.
Definition: ShapeList.cpp:769
QDir dir() const
Returns the path of the file&#39;s parent directory as a QDir object.
Definition: FileName.cpp:481
ShapeList(QString name, QString path, QObject *parent=NULL)
Creates an shape list from an shape list name and path (does not read Shapes).
Definition: ShapeList.cpp:49
QString m_path
This stores the directory name that contains the shapes in this shape list.
Definition: ShapeList.h:176
void push_back(Shape *const &value)
Appends an shape to the end of the shape list.
Definition: ShapeList.cpp:268
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:531
void deleteFromDisk()
Delete the shape data from disk.
Definition: Shape.cpp:592
bool removeOne(Shape *const &value)
Removes the first occurance of an shape.
Definition: ShapeList.cpp:352
This represents a shape in a project-based GUI interface.
Definition: Shape.h:78
Shape * takeFirst()
Removes and returns the first shape.
Definition: ShapeList.cpp:402
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
Definition: ShapeList.cpp:781
Isis exception class.
Definition: IException.h:107
Shape * takeLast()
Removes and returns the last shape.
Definition: ShapeList.cpp:416
~CopyShapeDataFunctor()
Destructor for CopyShapeDataFunctor.
Definition: ShapeList.cpp:728
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QString name() const
Get the human-readable name of this shape list.
Definition: ShapeList.cpp:569
void * operator()(Shape *const &shapeToCopy)
Copies the cub/ecub files for an shape into m_project.
Definition: ShapeList.cpp:740
Serial Number list generator.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Handle an XML end element.
Definition: ShapeList.cpp:815
Manage a stack of content handlers for reading XML files.
void insert(int i, Shape *const &value)
Inserts an shape into the shape list at an index.
Definition: ShapeList.cpp:223
int removeAll(Shape *const &value)
Removes all occurances of an shape.
Definition: ShapeList.cpp:297
Shape * takeAt(int i)
Removes the shape at an index and returns it.
Definition: ShapeList.cpp:388
QString m_name
This stores the shape list&#39;s name.
Definition: ShapeList.h:164
void push_front(Shape *const &value)
Prepends an shape to the beginning of the shape list.
Definition: ShapeList.cpp:282
CopyShapeDataFunctor & operator=(const CopyShapeDataFunctor &rhs)
Assignment operator for CopyShapeDataFunctor.
Definition: ShapeList.cpp:753
iterator erase(iterator pos)
Erases a single shape from the shape list.
Definition: ShapeList.cpp:189