Isis 3 Programmer Reference
TargetBodyList.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "TargetBodyList.h"
10
11//#include <QAction>
12#include <QDebug>
13#include <QDir>
14#include <QFile>
15#include <QFuture>
16#include <QInputDialog>
17#include <QLabel>
18#include <QProgressDialog>
19#include <QtConcurrentMap>
20#include <QXmlStreamWriter>
21
22#include "FileName.h"
23#include "IException.h"
24#include "IString.h"
25#include "Project.h"
26#include "TargetBody.h"
27#include "XmlStackedHandlerReader.h"
28
29namespace Isis {
38 TargetBodyList::TargetBodyList(QString name, QString path, QObject *parent) : QObject(parent) {
39 m_name = name;
40 m_path = path;
41 }
42
43
51
52
59 TargetBodyList::TargetBodyList(QList<TargetBodyQsp> targetBodys, QObject *parent) : QObject(parent) {
60 append(targetBodys);
61 }
62
63
72 QObject *parent) : QObject(parent) {
73 xmlReader->pushContentHandler(new XmlHandler(this, project));
74 }
75
76
83 QList<TargetBodyQsp>(other) {
84 m_name = other.m_name;
85 m_path = other.m_path;
86 }
87
88
93// TargetBodyList::TargetBodyList(QStringList &fileNames) {
94// foreach (QString fileName, fileNames) {
95// try {
96// TargetBodyQsp targetBody = TargetBodyQsp(new TargetBody(fileName);
97// append(targetBody);
98// }
99// catch (IException &) {
100// }
101// }
102// }
103
104
110
111
121 emit countChanged(count());
122 }
123
124
132 void TargetBodyList::append(const QList<TargetBodyQsp> &value) {
134 emit countChanged(count());
135 }
136
137
144 bool countChanging = count();
146 if (countChanging) {
147 emit countChanged(count());
148 }
149 }
150
151
160 iterator result = QList<TargetBodyQsp>::erase(pos);
161 emit countChanged(count());
162 return result;
163 }
164
165
179 iterator result = QList<TargetBodyQsp>::erase(begin, end);
180 emit countChanged(count());
181 return result;
182 }
183
184
193 void TargetBodyList::insert(int i, TargetBodyQsp const &value) {
195
196 emit countChanged(count());
197 }
198
199
212 iterator result = QList<TargetBodyQsp>::insert(before, value);
213 emit countChanged(count());
214 return result;
215 }
216
217
227 emit countChanged(count());
228 }
229
230
240 emit countChanged(count());
241 }
242
243
253 emit countChanged(count());
254 }
255
256
267 int result = QList<TargetBodyQsp>::removeAll(value);
268
269 if (result != 0) {
270 emit countChanged(count());
271 }
272
273 return result;
274 }
275
276
286 emit countChanged(count());
287 }
288
289
297 emit countChanged(count());
298 }
299
300
308 emit countChanged(count());
309 }
310
311
322 bool result = QList<TargetBodyQsp>::removeOne(value);
323
324 if (result) {
325 emit countChanged(count());
326 }
327
328 return result;
329 }
330
331
339 void TargetBodyList::swap(QList<TargetBodyQsp> &other) {
341
342 if (count() != other.count()) {
343 emit countChanged(count());
344 }
345 }
346
347
359 emit countChanged(count());
360 return result;
361 }
362
363
373 emit countChanged(count());
374 return result;
375 }
376
377
387 emit countChanged(count());
388 return result;
389 }
390
391
401 TargetBodyList &TargetBodyList::operator+=(const QList<TargetBodyQsp> &other) {
403
404 if (other.count()) {
405 emit countChanged(count());
406 }
407
408 return *this;
409 }
410
411
423 emit countChanged(count());
424 return *this;
425 }
426
427
437 TargetBodyList &TargetBodyList::operator<<(const QList<TargetBodyQsp> &other) {
439
440 if (other.count()) {
441 emit countChanged(count());
442 }
443
444 return *this;
445 }
446
447
459 emit countChanged(count());
460 return *this;
461 }
462
463
473 TargetBodyList &TargetBodyList::operator=(const QList<TargetBodyQsp> &rhs) {
474 bool countChanging = (rhs.count() != count());
476
477 if (countChanging) {
478 emit countChanged(count());
479 }
480
481 return *this;
482 }
483
484
493 bool countChanging = (rhs.count() != count());
495
496 m_name = rhs.m_name;
497 m_path = rhs.m_path;
498
499 if (countChanging) {
500 emit countChanged(count());
501 }
502
503 return *this;
504 }
505
506
511// QList<QAction *> TargetBodyList::supportedActions(Project *project) {
512// QList<QAction *> actions;
513
514// // It turns out connect() statements cannot be templated, hence they aren't inside of
515// // createWorkOrder().
516// if (allSupport(ImageDisplayProperties::Color)) {
517// QAction *alphaAction = createWorkOrder(project, TargetBodyListActionWorkOrder::ChangeTransparency);
518// if (!project) {
519// connect(alphaAction, SIGNAL(triggered()),
520// this, SLOT(askAndUpdateAlpha()));
521// }
522// actions.append(alphaAction);
523
524// QAction *colorAction = createWorkOrder(project, TargetBodyListActionWorkOrder::ChangeColor);
525// if (!project) {
526// connect(colorAction, SIGNAL(triggered()),
527// this, SLOT(askAndUpdateColor()));
528// }
529// actions.append(colorAction);
530
531
532// QAction *ranColorAction = createWorkOrder(project, TargetBodyListActionWorkOrder::RandomizeColor);
533// if (!project) {
534// connect(ranColorAction, SIGNAL(triggered()),
535// this, SLOT(showRandomColor()));
536// }
537// actions.append(ranColorAction);
538// }
539
540
541// if (allSupport(ImageDisplayProperties::ShowLabel)) {
542// QAction *labelVisibleAction = createWorkOrder(project,
543// TargetBodyListActionWorkOrder::ToggleShowLabel);
544// if (!project) {
545// connect(labelVisibleAction, SIGNAL(triggered()),
546// this, SLOT(saveAndToggleShowLabel()));
547// }
548// actions.append(labelVisibleAction);
549// }
550
551
552// if (allSupport(ImageDisplayProperties::ShowFill)) {
553// QAction *fillAction = createWorkOrder(project, TargetBodyListActionWorkOrder::ToggleShowFilled);
554// if (!project) {
555// connect(fillAction, SIGNAL(triggered()),
556// this, SLOT(saveAndToggleShowFill()));
557// }
558// actions.append(fillAction);
559// }
560
561
562// if (allSupport(ImageDisplayProperties::ShowDNs)) {
563// QAction *cubeDataAction = createWorkOrder(project,
564// TargetBodyListActionWorkOrder::ToggleShowCubeData);
565// if (!project) {
566// connect(cubeDataAction, SIGNAL(triggered()),
567// this, SLOT(saveAndToggleShowDNs()));
568// }
569// actions.append(cubeDataAction);
570// }
571
572
573// if (allSupport(ImageDisplayProperties::ShowOutline)) {
574// QAction *outlineAction = createWorkOrder(project,
575// TargetBodyListActionWorkOrder::ToggleShowOutline);
576// if (!project) {
577// connect(outlineAction, SIGNAL(triggered()),
578// this, SLOT(saveAndToggleShowOutline()));
579// }
580// actions.append(outlineAction);
581// }
582
583// actions.append(NULL);
584
585// if (!project) {
586// if (allSupport(ImageDisplayProperties::ZOrdering)) {
587// QAction *moveToTopAct = new QAction(tr("Bring to Front"), this);
588// QAction *moveUpAct = new QAction(tr("Bring Forward"), this);
589// QAction *moveToBottomAct = new QAction(tr("Send to Back"), this);
590// QAction *moveDownAct = new QAction(tr("Send Backward"), this);
591
592// foreach (Image *image, *this) {
593// connect(moveToTopAct, SIGNAL(triggered()),
594// image->displayProperties(), SIGNAL(moveToTop()));
595
596// connect(moveUpAct, SIGNAL(triggered()),
597// image->displayProperties(), SIGNAL(moveUpOne()));
598
599// connect(moveToBottomAct, SIGNAL(triggered()),
600// image->displayProperties(), SIGNAL(moveToBottom()));
601
602// connect(moveDownAct, SIGNAL(triggered()),
603// image->displayProperties(), SIGNAL(moveDownOne()));
604// }
605// actions.append(moveToTopAct);
606// actions.append(moveUpAct);
607// actions.append(moveToBottomAct);
608// actions.append(moveDownAct);
609// }
610
611// actions.append(NULL);
612
613// if (size() == 1 && allSupport(ImageDisplayProperties::Zooming)) {
614// QAction *zoomFit = new QAction(tr("Zoom Fit"), this);
615// connect(zoomFit, SIGNAL(triggered()),
616// first()->displayProperties(), SIGNAL(zoomFit()));
617// actions.append(zoomFit);
618// }
619// }
620
621// return actions;
622// }
623
624
631// bool TargetBodyList::allSupport(ImageDisplayProperties::Property prop) {
632// if (isEmpty())
633// return false;
634
635// foreach (Image *image, *this) {
636// if (!image->displayProperties()->supports(prop))
637// return false;
638// }
639
640// return true;
641// }
642
643
650 void TargetBodyList::setName(QString newName) {
651 m_name = newName;
652 }
653
654
661 void TargetBodyList::setPath(QString newPath) {
662 m_path = newPath;
663 }
664
665
671 QString TargetBodyList::name() const {
672 return m_name;
673 }
674
675
683 QString TargetBodyList::path() const {
684 return m_path;
685 }
686
687
691// void TargetBodyList::deleteFromDisk(Project *project) {
692// foreach (TargetBodyQsp targetBody, *this) {
693// targetBody->deleteFromDisk();
694// }
695
696// if (!m_path.isEmpty()) {
697// QFile::remove(project->imageDataRoot() + "/" + m_path + "/targets.xml");
698
699// QDir dir;
700// dir.rmdir(project->imageDataRoot() + "/" + m_path);
701// }
702// }
703
704
726 void TargetBodyList::save(QXmlStreamWriter &stream, const Project *project,
727 FileName newProjectRoot) const {
728// stream.writeStartElement("TargetBodyList");
729// stream.writeAttribute("name", m_name);
730// stream.writeAttribute("path", m_path);
731
732// FileName settingsFileName(
733// Project::targetBodyRoot(newProjectRoot.toString()) + "/" + m_path + "/targets.xml");
734
735// if (!settingsFileName.dir().mkpath(settingsFileName.path())) {
736// throw IException(IException::Io,
737// QString("Failed to create directory [%1]")
738// .arg(settingsFileName.path()),
739// _FILEINFO_);
740// }
741
742// QFile TargetBodyListContentsFile(settingsFileName.toString());
743
744// if (!TargetBodyListContentsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
745// throw IException(IException::Io,
746// QString("Unable to save target body information for [%1] because [%2] could not be opened"
747// " for writing")
748// .arg(m_name).arg(settingsFileName.original()),
749// _FILEINFO_);
750// }
751
752// QXmlStreamWriter targetBodyDetailsWriter(&TargetBodyListContentsFile);
753// targetBodyDetailsWriter.setAutoFormatting(true);
754// targetBodyDetailsWriter.writeStartDocument();
755
756// int countWidth = QString("%1L").arg(count()).size() - 1;
757// QChar paddingChar('0');
758
759// QLabel *progressLabel = new QLabel;
760
761// QProgressDialog progressDialog;
762// progressDialog.setLabel(progressLabel);
763// progressDialog.setRange(-1, count());
764// progressDialog.setValue(-1);
765
766// targetBodyDetailsWriter.writeStartElement("targets");
767// // Mapped is way faster than hundreds/thousands of run() calls... so use mapped for performance
768// QFuture<void *> future = QtConcurrent::mapped(*this,
769// CopyTargetBodyDataFunctor(project, newProjectRoot));
770
771// for (int i = 0; i < count(); i++) {
772// int newProgressValue = progressDialog.value() + 1;
773// progressLabel->setText(
774// tr("Saving Target Body Information for [%1] - %L2/%L3 done")
775// .arg(m_name)
776// .arg(newProgressValue, countWidth, 10, paddingChar)
777// .arg(count()));
778// progressDialog.setValue(newProgressValue);
779// future.resultAt(i);
780// }
781
782// progressLabel->setText(tr("Finalizing..."));
783// progressDialog.setRange(0, 0);
784// progressDialog.setValue(0);
785
786// foreach (TargetBodyQsp targetBody, *this) {
787// targetBody->save(targetBodyDetailsWriter, project, newProjectRoot);
788// }
789
790// targetBodyDetailsWriter.writeEndElement();
791
792// targetBodyDetailsWriter.writeEndDocument();
793
794// stream.writeEndElement();
795 }
796
797
798// TargetBodyList::CopyTargetBodyDataFunctor::CopyTargetBodyDataFunctor(const Project *project,
799// FileName newProjectRoot) {
800// m_project = project;
801// m_newProjectRoot = newProjectRoot;
802// }
803
804
805// TargetBodyList::CopyTargetBodyDataFunctor::CopyTargetBodyDataFunctor(
806// const CopyTargetBodyDataFunctor &other) {
807// m_project = other.m_project;
808// m_newProjectRoot = other.m_newProjectRoot;
809// }
810
811
812// TargetBodyList::CopyTargetBodyDataFunctor::~CopyTargetBodyDataFunctor() {
813// }
814
815
816// void *TargetBodyList::CopyTargetBodyDataFunctor::operator()(TargetBodyQsp const &targetToCopy) {
817// targetToCopy->copyToNewProjectRoot(m_project, m_newProjectRoot);
818// return NULL;
819// }
820
821
822// TargetBodyList::CopyTargetBodyDataFunctor &TargetBodyList::CopyTargetBodyDataFunctor::operator=(
823// const CopyTargetBodyDataFunctor &rhs) {
824// m_project = rhs.m_project;
825// m_newProjectRoot = rhs.m_newProjectRoot;
826// return *this;
827// }
828
829
834// QStringList TargetBodyList::saveAndToggleShowLabel() {
835// QStringList results;
836
837// if (!isEmpty()) {
838// ImageDisplayProperties *firstDisplayProps = first()->displayProperties();
839// bool newValue = !firstDisplayProps->getValue(ImageDisplayProperties::ShowLabel).toBool();
840
841// foreach (Image *image, *this) {
842// ImageDisplayProperties *displayProps = image->displayProperties();
843
844// bool value = displayProps->getValue(ImageDisplayProperties::ShowLabel).toBool();
845// results.append(value? "shown" : "hidden");
846
847// image->displayProperties()->setShowLabel(newValue);
848// }
849// }
850
851// return results;
852// }
853
854
866
867
879 bool TargetBodyList::XmlHandler::startElement(const QString &namespaceURI,
880 const QString &localName,
881 const QString &qName,
882 const QXmlAttributes &atts) {
883 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
884 if (localName == "TargetBodyList") {
885 QString name = atts.value("name");
886 QString path = atts.value("path");
887
888 if (!name.isEmpty()) {
889 m_TargetBodyList->setName(name);
890 }
891
892 if (!path.isEmpty()) {
893 m_TargetBodyList->setPath(path);
894 }
895 }
896 else if (localName == "target") {
897// m_TargetBodyList->append(TargetBodyQsp(new TargetBody(m_project->targetBodyRoot()
898// + "/" + m_TargetBodyList->path(),
899// reader())));
900 }
901 }
902
903 return true;
904 }
905
906
920 bool TargetBodyList::XmlHandler::endElement(const QString &namespaceURI,
921 const QString &localName,
922 const QString &qName) {
923 if (localName == "TargetBodyList") {
924 XmlHandler handler(m_TargetBodyList, m_project);
925
927 reader.pushContentHandler(&handler);
928 reader.setErrorHandler(&handler);
929
930 QString TargetBodyListXmlPath = m_project->targetBodyRoot() + "/" +
931 m_TargetBodyList->path() + "/targets.xml";
932 QFile file(TargetBodyListXmlPath);
933
934 if (!file.open(QFile::ReadOnly)) {
936 QString("Unable to open [%1] with read access")
937 .arg(TargetBodyListXmlPath),
938 _FILEINFO_);
939 }
940
941 QXmlInputSource xmlInputSource(&file);
942 if (!reader.parse(xmlInputSource))
944 tr("Failed to open target body list XML [%1]").arg(TargetBodyListXmlPath),
945 _FILEINFO_);
946 }
947
948 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
949 }
950}
File name manipulation and expansion.
Definition FileName.h:100
Isis exception class.
Definition IException.h:91
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
The main project for ipce.
Definition Project.h:289
XmlReader for working with TargetBody XML files.
Project * m_project
The project that contains the TargetBodies.
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Handle an XML start element.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Handle an XML end element.
TargetBodyList * m_TargetBodyList
The TargetBodyList to read into/save from.
XmlHandler(TargetBodyList *TargetBodyList, Project *project)
Change the visibility of the display name.
List for holding TargetBodies.
TargetBodyList & operator<<(const QList< TargetBodyQsp > &other)
Appends another TargetBodyList to the list.
QString m_name
This functor is used for copying the TargetBody objects between two projects quickly.
TargetBodyList & operator=(const QList< TargetBodyQsp > &rhs)
Assignment operator for a QList of TargetBodyQsp.
void setPath(QString newPath)
Set the relative path (from the project root) to this target body list's folder.
void removeLast()
Removes the last TargetBody from the list.
void save(QXmlStreamWriter &stream, const Project *project, FileName newProjectRoot) const
Delete all of the contained TargetBody objects from disk (see TargetBody::deleteFromDisk())
iterator erase(iterator pos)
Erases the TargetBody associated with an iterator.
QString path() const
Get the path to these target body objects in the list (relative to project root).
void swap(QList< TargetBodyQsp > &other)
Swaps the list with another TargetBodyList.
TargetBodyQsp takeLast()
Removes and returns the last TargetBody in the list.
void insert(int i, TargetBodyQsp const &value)
Inserts a TargetBody at a specific index.
void append(TargetBodyQsp const &value)
Appends a TargetBody to the list.
bool removeOne(TargetBodyQsp const &value)
Removes the first occurrence of a TargetBody from the list.
void push_front(TargetBodyQsp const &value)
Insertes a TargetBody at the front of the list.
TargetBodyList & operator+=(const QList< TargetBodyQsp > &other)
Appends another TargetBodyList to the list.
TargetBodyList(QString name, QString path, QObject *parent=NULL)
Create an target body list from an target body list name and path (does not read TargetBody objects).
QString name() const
Get the human-readable name of this target body list.
void removeFirst()
Removes the first TargetBody from the list.
int removeAll(TargetBodyQsp const &value)
Removes all occurrences of a TargetBody and returns the number removed.
void prepend(TargetBodyQsp const &value)
Inserts a TargetBody at the front of the list.
void push_back(TargetBodyQsp const &value)
Appends a TargetBody to the end of the list.
TargetBodyQsp takeFirst()
Removes and returns the first TargetBody in the list.
QString m_path
This stores the directory name that contains the TargetBody objects in this list.
~TargetBodyList()
Create an target body list from a list of target body file names.
void setName(QString newName)
Gets a list of pre-connected actions that have to do with display, such as color, alpha,...
void removeAt(int i)
Removes the TargetBody at a specific index.
void clear()
clears the list.
TargetBodyQsp takeAt(int i)
Removes and returns the TargetBody at a specific index.
Manage a stack of content handlers for reading XML files.
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16