|
Isis 3.0 Developer's Reference (API) |
Home |
00001 #ifndef CubeAttribute_h 00002 #define CubeAttribute_h 00003 00026 #include <typeinfo> 00027 00028 #include <QDebug> 00029 #include <QStringList> 00030 00031 #include "Cube.h" 00032 #include "Endian.h" 00033 #include "FileName.h" 00034 #include "IException.h" 00035 #include "PixelType.h" 00036 00037 00038 namespace Isis { 00047 enum LabelAttachment { 00048 AttachedLabel, 00049 DetachedLabel, 00050 00056 ExternalLabel 00057 }; 00058 00059 00068 inline QString LabelAttachmentName(LabelAttachment labelType) { 00069 if(labelType == AttachedLabel) return "Attached"; 00070 if(labelType == DetachedLabel) return "Detached"; 00071 if(labelType == ExternalLabel) return "External"; 00072 00073 QString msg = "Invalid label attachment type [" + QString(labelType) + "]"; 00074 throw IException(IException::Programmer, msg, _FILEINFO_); 00075 } 00076 00077 00086 inline LabelAttachment LabelAttachmentEnumeration(const QString &labelType) { 00087 QString temp = labelType.toUpper(); 00088 if(temp == "ATTACHED") return AttachedLabel; 00089 if(temp == "DETACHED") return DetachedLabel; 00090 if(temp == "External") return ExternalLabel; 00091 00092 QString msg = "Invalid label attachment type string [" + labelType + "]"; 00093 throw IException(IException::Unknown, msg, _FILEINFO_); 00094 } 00095 00096 00097 00133 template<typename ChildClass> class CubeAttribute { 00134 public: 00135 00137 CubeAttribute(QList< bool (ChildClass::*)(QString) const > testers) { 00138 m_attributeTypeTesters = testers; 00139 } 00140 00141 00153 CubeAttribute(QList< bool (ChildClass::*)(QString) const > testers, 00154 const FileName &fileName) { 00155 m_attributeTypeTesters = testers; 00156 setAttributes(fileName); 00157 } 00158 00159 00161 virtual ~CubeAttribute() { 00162 } 00163 00164 00173 QString toString() const { 00174 QString result; 00175 00176 if (!m_attributes.isEmpty()) 00177 result = "+" + m_attributes.join("+"); 00178 00179 return result; 00180 } 00181 00182 00193 void addAttribute(QString attribute) { 00194 QString upcaseAtt = attribute.toUpper(); 00195 00196 if (attribute.contains("+")) { 00197 throw IException(IException::Unknown, 00198 "Individual attributes (for example, BSQ) cannot contain the '+' " 00199 "character because that is used to denote the separation of individual " 00200 "attributes", 00201 _FILEINFO_); 00202 } 00203 00204 // Verify this attribute is legal 00205 bool legal = false; 00206 bool (ChildClass::*tester)(QString) const; 00207 foreach (tester, m_attributeTypeTesters) { 00208 if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) { 00209 if (legal) { 00210 throw IException(IException::Unknown, 00211 QObject::tr("Attribute [%1] is ambiguous").arg(attribute), 00212 _FILEINFO_); 00213 } 00214 00215 legal = true; 00216 } 00217 } 00218 00219 if (!legal) { 00220 throw IException(IException::Unknown, 00221 QObject::tr("Attribute [%1] is not recognized").arg(attribute), 00222 _FILEINFO_); 00223 } 00224 00225 m_attributes.append(attribute); 00226 } 00227 00228 00237 void addAttributes(const FileName &fileNameWithAtts) { 00238 addAttributes(fileNameWithAtts.attributes()); 00239 } 00240 00241 00250 void addAttributes(const char *attributesString) { 00251 addAttributes(QString(attributesString)); 00252 } 00253 00254 00263 void addAttributes(const QString &attributesString) { 00264 setAttributes(toString() + "+" + attributesString); 00265 } 00266 00267 00277 void setAttributes(const FileName &fileName) { 00278 QStringList attributes = fileName.attributes().split("+", QString::SkipEmptyParts); 00279 00280 m_attributes.clear(); 00281 foreach (QString attribute, attributes) 00282 addAttribute(attribute); 00283 } 00284 00285 00286 protected: 00295 QStringList attributeList(bool (ChildClass::*tester)(QString) const) const { 00296 QStringList relevantAttributes; 00297 00298 foreach (QString attribute, m_attributes) { 00299 QString upcaseAtt = attribute.toUpper(); 00300 if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) { 00301 relevantAttributes.append(upcaseAtt); 00302 } 00303 } 00304 00305 return relevantAttributes; 00306 } 00307 00308 00320 void setAttribute(QString newValue, bool (ChildClass::*tester)(QString) const) { 00321 QMutableListIterator<QString> it(m_attributes); 00322 00323 bool found = false; 00324 while (it.hasNext()) { 00325 QString &attribute = it.next(); 00326 00327 QString upcaseAtt = attribute.toUpper(); 00328 if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) { 00329 if (found || newValue == "") { 00330 // already found one (remove the duplicate) or just deleting it 00331 it.remove(); 00332 } 00333 else { 00334 // modify existing attribute value 00335 attribute = newValue; 00336 } 00337 00338 found = true; 00339 } 00340 } 00341 00342 // Attribute doesn't exist, add it 00343 if (!found && newValue != "") { 00344 m_attributes.append(newValue); 00345 } 00346 } 00347 00348 private: 00354 QStringList m_attributes; 00355 00363 QList< bool (ChildClass::*)(QString) const > m_attributeTypeTesters; 00364 }; 00365 00366 00394 class CubeAttributeInput : public CubeAttribute<CubeAttributeInput> { 00395 00396 public: 00397 00399 CubeAttributeInput(); 00400 00401 00411 CubeAttributeInput(const FileName &fileName); 00412 00413 00415 ~CubeAttributeInput(); 00416 00417 00419 std::vector<QString> bands() const; 00420 00432 QString bandsString() const; 00433 00435 void setBands(const std::vector<QString> &bands); 00436 00437 using CubeAttribute<CubeAttributeInput>::toString; 00438 00439 private: 00440 bool isBandRange(QString attribute) const; 00441 00442 static QString toString(const std::vector<QString> &bands); 00443 static QList<bool (CubeAttributeInput::*)(QString) const> testers(); 00444 00445 private: 00446 std::vector<QString> m_bands; 00447 }; 00448 00449 00484 class CubeAttributeOutput : public CubeAttribute<CubeAttributeOutput> { 00485 00486 public: 00487 00489 CubeAttributeOutput(); 00490 00503 CubeAttributeOutput(const FileName &fileName); 00504 00505 00507 ~CubeAttributeOutput(); 00508 00509 00511 bool propagatePixelType() const; 00512 00514 bool propagateMinimumMaximum() const; 00515 00517 Cube::Format fileFormat() const; 00518 00520 QString fileFormatString() const; 00521 00523 void setFileFormat(Cube::Format fmt); 00524 00526 ByteOrder byteOrder() const; 00527 00529 QString byteOrderString() const; 00530 00532 void setByteOrder(ByteOrder order); 00533 00535 double minimum() const; 00536 00538 double maximum() const; 00539 00541 void setMinimum(double min); 00542 00544 void setMaximum(double max); 00545 00547 PixelType pixelType() const; 00548 00550 void setPixelType(PixelType type); 00551 00553 void setLabelAttachment(LabelAttachment attachment); 00554 00555 LabelAttachment labelAttachment() const; 00556 00557 using CubeAttribute<CubeAttributeOutput>::toString; 00558 00559 00560 private: 00561 bool isByteOrder(QString attribute) const; 00562 bool isFileFormat(QString attribute) const; 00563 bool isLabelAttachment(QString attribute) const; 00564 bool isPixelType(QString attribute) const; 00565 bool isRange(QString attribute) const; 00566 00567 static QString toString(Cube::Format); 00568 00575 enum RangeType { 00576 PropagateRange, 00577 RangeSet, 00578 }; 00579 00580 static QList<bool (CubeAttributeOutput::*)(QString) const> testers(); 00581 }; 00582 }; 00583 00584 #endif