// $Id: SctSumFuncAssignSpec.cpp,v 1.8 2011/05/12 02:11:56 philw Exp $ // // Data definition for the SCT Slot Aggregation Summary Function "set" // operation and default specification (used when Slots are added to an // SCT). // // class SctSumFuncAssignSpec // class SctSumFuncAssignSpec::Item // // Sample Data Illustration. One SctSumFuncAssignSpec instance represents // this information. This example shows five Items (rows): // // "Specify summary functions for SCT slot items based on Unit // Type or Slot Name. The first row matching a particular slot is // used for that slot." // // ====================== ================== ================ // Unit Type Slot Name * Summary Function // ====================== ================== ================ // ( ) Any (o) Pool Elevation Max // ( ) Any (o) Spill Max // (o) Flow ( ) Sum // (o) Volume ( ) Ave // (o) PercentUncertainty ( ) Max // All Other Slots: Last // ====================== ================== ================ // // "* Slot Name matches are based on the slot's name CONTAINING // the specified string". // //-- #ifndef SctSumFuncAssignSpecINCLUDED #include "SctSumFuncAssignSpec.hpp" #endif // ********************************* // *** Configuration Constants *** // ********************************* // The intial default case, applied to Slots not matching any of the Unit // Type or Slot Name (Part) filters in the sequence of filter rows. // static const SctSumFunc DEFAULT_SUMFUNC (SCT_SUMFUNC_LAST); // Serialization static const QString ItemSerialKey ("SCT_SFAS"); static const QString NBSP (" "); static const QString QUOT ("""); // --------------------------------- #ifndef RwQtSettingsINCLUDED #include "RwQtSettings.hpp" #endif #ifndef SystemINCLUDED #include "System.hpp" #endif #ifndef SimWSINCLUDED #include "SimWS.hpp" #endif #ifndef SlotGUIUtilsINCLUDED #include "SlotGUIUtils.hpp" #endif #include #include //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************ // *** class SctSumFuncAssignSpec *** // ************************************ SctSumFuncAssignSpec::SctSumFuncAssignSpec() : _itemList() { } SctSumFuncAssignSpec::~SctSumFuncAssignSpec() { } bool SctSumFuncAssignSpec::operator== (const SctSumFuncAssignSpec& rhs) const { const bool eq = (_itemList == rhs._itemList); return (eq); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // static const SctSumFuncAssignSpec& SctSumFuncAssignSpec::factoryValueRef() { // Returns a const reference to a static SctSumFuncAssignSpec // instance having the "Factory" default settings. static SctSumFuncAssignSpec factVal; static bool staticInstanceDefined (false); if (!staticInstanceDefined) { staticInstanceDefined = true; Item lastItem (true); // last item lastItem.setSumFuncSpec (SctSumFuncSpec (DEFAULT_SUMFUNC)); QList itemList; itemList << Item (FLOW, SCT_SUMFUNC_SUM) // 1 << Item (VOLUME, SCT_SUMFUNC_AVE) // 2 << lastItem; // 3 factVal.setItemList (itemList); factVal.clearTemporaryChangeCnt(); } return (factVal); } void SctSumFuncAssignSpec::setFactoryValue() { _itemList.clear(); *this = factoryValueRef(); } bool SctSumFuncAssignSpec::isFactoryValue() const { const SctSumFuncAssignSpec& factoryVal = factoryValueRef(); const bool isFactoryVal = (factoryVal == *this); return (isFactoryVal); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void SctSumFuncAssignSpec::setItemList ( const QList& newItemList) { if (_itemList != newItemList) { _itemList.clear(); _itemList = newItemList; // Update 'isLastItem' flag among items. const int cnt = _itemList.count(); for (int inx = 0; inx < cnt; ++inx) { _itemList [inx].setIsLastItem (inx == (cnt-1)); } ++_temporaryChangeCnt; } } SctSumFuncSpec SctSumFuncAssignSpec::defaultSumFuncSpec() const { const int itemCnt = _itemList.count(); SctSumFuncSpec defaultSpec (DEFAULT_SUMFUNC); if (itemCnt > 0) { // The last item (if there are any items), is the default. defaultSpec = _itemList [itemCnt-1] .sumFuncSpec(); } return defaultSpec; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // *********************** // *** Serialization *** // *********************** QString SctSumFuncAssignSpec::serialize (int indentSpaces) const { // -- (example) ------------------------------------ // SCT_SFAS "START" // SCT_SFAS "Unit_on Volume Slot_off   FUNC Sum" // SCT_SFAS "Unit_off NONE Slot_on Release FUNC Ave" // SCT_SFAS "END" // ------------------------------------------------- QString indSp (""); indSp.fill (QChar (' '), indentSpaces); QStringList serialStrList; serialStrList << QString ("%1%2 \"START\"") .arg (indSp) .arg (ItemSerialKey); const int itemCnt = _itemList.count(); for (int inx = 0; inx < itemCnt; ++inx) { const QString recStr = indSp + _itemList [inx] .saveAsString(); serialStrList << recStr; } serialStrList << QString ("%1%2 \"END\"") .arg (indSp) .arg (ItemSerialKey); const QString serialStr = serialStrList .join ("\n"); return (serialStr); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- okstat SctSumFuncAssignSpec::loadSerialCmd (const QString& cmd) { static const char* mname ("SctSumFuncAssignSpec::loadSerialCmd"); static const QString SEP (" "); // Seperator: one space // -- (example) ------------------------------------- // SCT_SFAS START // SCT_SFAS "Unit_on Volume Slot_off   FUNC Sum" // SCT_SFAS "Unit_off NONE Slot_on Release FUNC Ave" // SCT_SFAS END // -------------------------------------------------- QStringList cmdList = cmd.split (SEP); const int cmdCnt = cmdList.count(); const int itemCnt = _itemList.count(); if (cmdCnt < 2) { return okstat ("Invalid SctSumFuncAssignSpec loadSerialCmd"); } const QString keyword = cmdList [1] .toUpper(); if (keyword == "START") { _itemList.clear(); return okstat (true); //----------------->> } if (keyword == "END") { for (int inx = 0; inx < itemCnt; ++inx) { _itemList [inx].setIsLastItem (inx == (itemCnt-1)); } return okstat (true); //----------------->> } Item newItem; // default constructed const okstat recOk = newItem.loadFromString (cmd); if (recOk) { _itemList.append (newItem); } return okstat (recOk); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ********************* // *** Assess Slot *** // ********************* SctSumFuncSpec SctSumFuncAssignSpec::functionForSlot ( const SlotColRef& scRef) const { SctSumFuncSpec retFuncSpec = defaultSumFuncSpec(); if (scRef.valid()) { const int cnt = _itemList.count(); for (int inx = 0; inx < cnt; ++inx) { const Item& itemRef = _itemList [inx]; const bool itemMatches = itemRef.matchesSlot (scRef); if (itemMatches) { retFuncSpec = itemRef.sumFuncSpec(); break; } } } return (retFuncSpec); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ****************************************** // *** class SctSumFuncAssignSpec::Item *** // ****************************************** // constructor 1 of 2 SctSumFuncAssignSpec::Item::Item (bool isLast /*=false*/) : _unitTypeFilterEnabled (false), _slotNameFilterEnabled (false), _unitType (NOUNITS), _slotNamePart (""), _sumFuncSpec (SctSumFuncSpec (DEFAULT_SUMFUNC)), _isLastItem (isLast), // Non-persistent field _slotCount (0) // Non-persistent field { static const char* mname ("SctSumFuncAssignSpec::Item ctor1"); } // constructor 2 of 2 SctSumFuncAssignSpec::Item::Item (unit_type utyp, SctSumFuncSpec func, bool isLast /*=false*/) : _unitTypeFilterEnabled (utyp != NOUNITS), _slotNameFilterEnabled (false), _unitType (utyp), _slotNamePart (""), _sumFuncSpec (func), _isLastItem (isLast), // Non-persistent field _slotCount (0) // Non-persistent field { static const char* mname ("SctSumFuncAssignSpec::Item ctor2"); } SctSumFuncAssignSpec::Item::~Item() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void SctSumFuncAssignSpec::Item::setUnitTypeFilterEnabled (bool newOn) { _unitTypeFilterEnabled = newOn; if (FiltersExclusive && newOn) { _slotNameFilterEnabled = false; } } void SctSumFuncAssignSpec::Item::setSlotNameFilterEnabled (bool newOn) { _slotNameFilterEnabled = newOn; if (FiltersExclusive && newOn) { _unitTypeFilterEnabled = false; } } void SctSumFuncAssignSpec::Item::setUnitType (unit_type utyp, bool setEnabled /*=false*/) { _unitType = utyp; if (setEnabled) { // enable this filter setUnitTypeFilterEnabled (true); } } void SctSumFuncAssignSpec::Item::setSlotNamePart (const QString& slotNamePart, bool setEnabled /*=false*/) { _slotNamePart = slotNamePart; if (setEnabled) { // enable this filter setSlotNameFilterEnabled (true); } } void SctSumFuncAssignSpec::Item::setSumFuncSpec (SctSumFuncSpec func) { _sumFuncSpec = func; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool SctSumFuncAssignSpec::Item::matchesSlot (const SlotColRef& scRef) const { if (!scRef.valid()) return (false); //------------------------------->> // The last item matches all Slots if (_isLastItem) return (true); //--------------------------->> const Slot* slotPtr = scRef.slot(); const int col = scRef.col(); if (_unitTypeFilterEnabled) { const unit_type utyp = SlotGUIUtils::getUnitType (slotPtr, col); if (utyp == _unitType) { return (true); //---------->> } } if (_slotNameFilterEnabled && !_slotNamePart.isEmpty()) { if (slotPtr != NULL) { const QString sname = slotPtr->getName(); const bool nameMatch = sname.contains (_slotNamePart, Qt::CaseInsensitive); if (nameMatch) { return (true); //---------->> } } } return (false); } bool SctSumFuncAssignSpec::Item::countSlotMatch (const SlotColRef& scRef) { const bool matches = matchesSlot (scRef); if (matches) { ++_slotCount; } return (matches); } void SctSumFuncAssignSpec::Item::setIsLastItem (bool isLast) { _isLastItem = isLast; } // ignores non-persist fields bool SctSumFuncAssignSpec::Item::equals (const Item& rhs) const { if (_unitTypeFilterEnabled != rhs._unitTypeFilterEnabled) return (false); if (_slotNameFilterEnabled != rhs._slotNameFilterEnabled) return (false); if (activeUnitType() != rhs.activeUnitType()) return (false); if (activeSlotNamePart() != rhs.activeSlotNamePart()) return (false); if (_sumFuncSpec != rhs._sumFuncSpec) return (false); return (true); // equal } bool SctSumFuncAssignSpec::Item::operator== (const Item& rhs) const { return (equals (rhs)); } bool SctSumFuncAssignSpec::Item::operator!= (const Item& rhs) const { return (!equals (rhs)); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // *********************** // *** Serialization *** // *********************** // Serialization: Save QString SctSumFuncAssignSpec::Item::saveAsString() const { // -- (examples) ----------------------------------- // SCT_SFAS "Unit_on Volume Slot_off   FUNC Sum" // SCT_SFAS "Unit_off NONE Slot_on Release FUNC Ave" // ------------------------------------------------- QString utypStr = unitMgr->getUnitType (_unitType); QString slotStr = _slotNamePart; QString funcStr = _sumFuncSpec.getFuncString(); if (utypStr.isEmpty()) utypStr = "NOUNITS"; else { utypStr.replace (QChar (' '), NBSP, Qt::CaseSensitive); utypStr.replace (QChar ('"'), QUOT, Qt::CaseSensitive); } if (slotStr.isEmpty()) slotStr = NBSP; else { slotStr.replace (QChar (' '), NBSP, Qt::CaseSensitive); slotStr.replace (QChar ('"'), QUOT, Qt::CaseSensitive); } if (funcStr.isEmpty()) funcStr = "UND"; else { funcStr.replace (QChar (' '), NBSP, Qt::CaseSensitive); funcStr.replace (QChar ('"'), QUOT, Qt::CaseSensitive); } QStringList encStrList; encStrList << QString ("Unit_%1") .arg (_unitTypeFilterEnabled ? "on" : "off") << utypStr << QString ("Slot_%1") .arg (_slotNameFilterEnabled ? "on" : "off") << slotStr << QString ("FUNC") << funcStr; const QString encStr = QString ("%1 \"%2\"") .arg (ItemSerialKey) .arg (encStrList.join (QString (" "))); return (encStr); } // Serialization: Load okstat SctSumFuncAssignSpec::Item::loadFromString (const QString& encStr) { static const char* mname ("SctSumFuncAssignSpec::Item::loadFromString"); // -- (examples) ------------------------------------ // SCT_SFAS "Unit_on Volume Slot_off   FUNC Sum" // SCT_SFAS "Unit_off NONE Slot_on Release FUNC Ave" // -------------------------------------------------- static const QString SEP (" "); // Seperator: one space QString errMsg (""); QStringList encStrList = encStr.split (SEP); const int encStrListCnt = encStrList.count(); if ((encStrListCnt != 7) || (encStrList [0] != ItemSerialKey)) { errMsg = QString (QObject::tr ( "SctSumFuncAssignSpec string (\"%1\") has %2 fields. " "It should have 7 fields and start with \"%3\".")) .arg (encStr) .arg (encStrListCnt) .arg (ItemSerialKey); return okstat (errMsg); //------------------->> } // Decode spaces. for (int inx = 1; inx < encStrListCnt; ++inx) { static const QString SP (' '); static const QString QU ('"'); encStrList [inx] .replace (NBSP, SP, Qt::CaseInsensitive); encStrList [inx] .replace (QUOT, QU, Qt::CaseInsensitive); } const QString unitOnOff = encStrList [1]; const QString unitTypStr = encStrList [2]; const QString slotOnOff = encStrList [3]; const QString slotStr = encStrList [4]; const QString funcKword = encStrList [5]; funcKword; // not used const QString funcStr = encStrList [6]; _unitTypeFilterEnabled = (unitOnOff.toUpper() == "UNIT_ON"); _slotNameFilterEnabled = (slotOnOff.toUpper() == "SLOT_ON"); _unitType = unitMgr->getUnitType (unitTypStr); _slotNamePart = slotStr; _sumFuncSpec = SctSumFuncSpec (funcStr); _isLastItem = false; // this needs to be set later. return okstat (true); } //--- (end SctSumFuncAssignSpec.cpp) ---