//----------------------------------------------------------------------------- // $Id: Sim/Ornament.cpp 2013/10/26 23:10:54 philw $ // Workspace Text/Image Ornament -- created for RiverWare 6.5 [10-2013] //----------------------------------------------------------------------------- #include "Ornament.hpp" #include "OrnamentMgr.hpp" #include "CanvasDefs.hpp" #include "RwFileDialog.hpp" #include "cwFormat.hpp" #include "libSimMsgs.hpp" #include #include #include #include #include //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // static const char* Ornament::imageTypeStr (Ornament::ImageType typ, bool forSerial) { if (forSerial) { switch (typ) { case ImageTypeNone: return ("ImageTypeNone"); case ImageTypeUser: return ("ImageTypeUser"); case ImageTypeDingbat: return ("ImageTypeDingbat"); // TENTATIVE } return ("ImageTypeErr"); } switch (typ) { case ImageTypeNone: return ("No Image"); case ImageTypeUser: return ("User Image"); case ImageTypeDingbat: return ("Dingbat"); } return ("Image Type Error"); } // static Ornament::ImageType Ornament::imageTypeFromStr (const QString& str) { if (str == imageTypeStr (ImageTypeNone, true)) return ImageTypeNone; if (str == imageTypeStr (ImageTypeUser, true)) return ImageTypeUser; if (str == imageTypeStr (ImageTypeDingbat, true)) return ImageTypeDingbat; if (str == imageTypeStr (ImageTypeNone, false)) return ImageTypeNone; if (str == imageTypeStr (ImageTypeUser, false)) return ImageTypeUser; if (str == imageTypeStr (ImageTypeDingbat, false)) return ImageTypeDingbat; return ImageTypeNone; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- Ornament::Ornament() : Root() { init(); } Ornament::~Ornament() { sendCallback (ORNAMENT_DELETED); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ***************** // *** Setters *** // ***************** void Ornament::setImage (ImageType typ, int imageId) { _imageType = typ; _imageId = imageId; sendCallback (ORNAMENT_CHANGED); } void Ornament::setHasFrame (bool has) { _hasFrame = has; sendCallback (ORNAMENT_CHANGED); } void Ornament::setDisplayText (const QString& text) { _displayText = text; sendCallback (ORNAMENT_CHANGED); } void Ornament::setTooltipText (const QString& text) { _tooltipText = text; sendCallback (ORNAMENT_CHANGED); } void Ornament::setCanvasId (CanvasDefs::CanvasID id) { _canvasID = id; } void Ornament::setSimXY (double x, double y) { _simX = x; _simY = y; sendCallback (ORNAMENT_MOVED_SIM); } void Ornament::setAccXY (double x, double y) { _accX = x; _accY = y; sendCallback (ORNAMENT_MOVED_ACC); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool Ornament::operator== (const Ornament& rhs) const { if (_imageType != rhs._imageType) return (false); if (_imageId != rhs._imageId) return (false); if (_displayText != rhs._displayText) return (false); if (_tooltipText != rhs._tooltipText) return (false); if (_hasFrame != rhs._hasFrame) return (false); if (_simX != rhs._simX) return (false); if (_simY != rhs._simY) return (false); if (_accX != rhs._accX) return (false); if (_accY != rhs._accY) return (false); return (true); // all fields are equal } bool Ornament::equalWithImageData (const Ornament& rhsOrn, const UserImageData& rhsImgDat) const { // (1) Text and General Fields (excluding Image data) if (_displayText != rhsOrn._displayText) return (false); if (_tooltipText != rhsOrn._tooltipText) return (false); if (_hasFrame != rhsOrn._hasFrame) return (false); if (_simX != rhsOrn._simX) return (false); if (_simY != rhsOrn._simY) return (false); if (_accX != rhsOrn._accX) return (false); if (_accY != rhsOrn._accY) return (false); // (2) Image Data const OrnamentMgr* mgr = OrnamentMgr::instance(); const UserImageData imgDat = mgr->userImageData (this); const bool imgDatEqual = imgDat.dataEqual (rhsImgDat); return (imgDatEqual); } // private void Ornament::init() { _imageType = ImageTypeNone; _imageId = 0; _displayText = QString(); _tooltipText = QString(); _hasFrame = false; _simX = 0.0; _simY = 0.0; _accX = 0.0; _accY = 0.0; } // private void Ornament::sendCallback (CallbackType cbType) { callCallbacks (cbType, (CallbackData*) this); OrnamentMgr* mgr = OrnamentMgr::instance(); mgr->handleAndForwardCallback (cbType, this); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ********************************************** // *** Ornament / XML Serialization: Output *** // ********************************************** static const QString XML_ELEM_ORNAMENT ("Ornament"); static const QString XML_ELEM_IMAGE_REF ("ImageRef"); static const QString XML_ELEM_CANVAS ("Canvas"); static const QString XML_ELEM_FRAME ("Frame"); static const QString XML_ELEM_DISP_TEXT ("DisplayText"); static const QString XML_ELEM_TOOL_TEXT ("TooltipText"); static const QString XML_ATTRIB_TYPE ("type"); static const QString XML_ATTRIB_ID ("id"); static const QString XML_ATTRIB_SHOW ("show"); static const QString XML_ATTRIB_X ("x"); static const QString XML_ATTRIB_Y ("y"); QDomElement Ornament::asXmlDomElement (QDomDocument& doc) const { QDomElement elem = doc.createElement (XML_ELEM_ORNAMENT); QDomElement imageElem = doc.createElement (XML_ELEM_IMAGE_REF); imageElem.setAttribute (XML_ATTRIB_TYPE, imageTypeStr (_imageType, true)); imageElem.setAttribute (XML_ATTRIB_ID, _imageId); QDomElement simElem = doc.createElement (XML_ELEM_CANVAS); const CanvasDefs::CanvasID simId = CanvasDefs::CanvasID_SIMULATION; const QString simCanvStr = CanvasDefs::canvasIDStr (simId); simElem.setAttribute (XML_ATTRIB_ID, simCanvStr); simElem.setAttribute (XML_ATTRIB_SHOW, (_canvasID == simId)); simElem.setAttribute (XML_ATTRIB_X, _simX); simElem.setAttribute (XML_ATTRIB_Y, _simY); QDomElement acctElem = doc.createElement (XML_ELEM_CANVAS); const CanvasDefs::CanvasID acctId = CanvasDefs::CanvasID_ACCOUNTING; const QString acctCanvStr = CanvasDefs::canvasIDStr (acctId); acctElem.setAttribute (XML_ATTRIB_ID, acctCanvStr); acctElem.setAttribute (XML_ATTRIB_SHOW, (_canvasID == acctId)); acctElem.setAttribute (XML_ATTRIB_X, _accX); acctElem.setAttribute (XML_ATTRIB_Y, _accY); QDomElement frameElem = doc.createElement (XML_ELEM_FRAME); frameElem.setAttribute (XML_ATTRIB_SHOW, _hasFrame); QDomElement dispElem = doc.createElement (XML_ELEM_DISP_TEXT); QDomCDATASection dispData = doc.createCDATASection (_displayText); dispElem.appendChild (dispData); QDomElement toolElem = doc.createElement (XML_ELEM_TOOL_TEXT); QDomCDATASection toolData = doc.createCDATASection (_tooltipText); toolElem.appendChild (toolData); elem.appendChild (imageElem); elem.appendChild (simElem); elem.appendChild (acctElem); elem.appendChild (frameElem); elem.appendChild (dispElem); elem.appendChild (toolElem); return elem; } QString Ornament::toXml() const { QDomDocument ornamentDoc; const QDomElement docElem = asXmlDomElement (ornamentDoc); ornamentDoc.appendChild (docElem); const QString docStr = ornamentDoc.toString(); return (docStr.trimmed()); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ********************************************* // *** Ornament / XML Serialization: Input *** // ********************************************* okstat Ornament::loadFromDomElement (const QDomElement& ornamentElem, const QString& srcDesc) { srcDesc; // (avoid compilation warning) // **************************************** // *** Workspace Ornament: Attributes *** // **************************************** // No attributes are currently supported. //-- const QDomNamedNodeMap ornamentAttbs = ornamentElem.attributes(); //-- const int attbCnt = ornamentAttbs.count(); //-- for (int attbInx = 0; attbInx < attbCnt; ++attbInx) //-- { //-- const QDomAttr attb = ornamentAttbs .item (attbInx) .toAttr(); //-- if (!attb.isNull()) //-- { //-- const QString attbName = attb.name(); //-- const QString attbStrVal = attb.value(); //-- } //-- } // ******************************************** // *** Workspace Ornament: Child Elements *** // ******************************************** const QDomNodeList ornamentChildNodes = ornamentElem.childNodes(); const int chCnt = ornamentChildNodes.count(); for (int chInx = 0; chInx < chCnt; ++chInx) { const QDomElement chElem = ornamentChildNodes.at (chInx).toElement(); const QString chTag = chElem.tagName(); if (chTag == XML_ELEM_IMAGE_REF) { if (chElem.hasAttribute (XML_ATTRIB_TYPE)) { const QString typeStr = chElem.attribute (XML_ATTRIB_TYPE); const QString idStr = chElem.attribute (XML_ATTRIB_ID, "-1"); const ImageType imgTyp = imageTypeFromStr (typeStr); bool idOk (false); const int idNum = idStr.toInt (&idOk); setImage (imgTyp, idOk ? idNum : (-1)); } } if (chTag == XML_ELEM_FRAME) { const QString showStr = chElem.attribute (XML_ATTRIB_SHOW); const bool doShow = !showStr.isEmpty() && (showStr != "0"); setHasFrame (doShow); } else if (chTag == XML_ELEM_DISP_TEXT) { const QString dispStr = chElem.text(); setDisplayText (dispStr); } else if (chTag == XML_ELEM_TOOL_TEXT) { const QString toolStr = chElem.text(); setTooltipText (toolStr); } else if (chTag == XML_ELEM_CANVAS) // more than one of these { const QString idStr = chElem.attribute (XML_ATTRIB_ID); if (!idStr.isEmpty()) { const CanvasDefs::CanvasID canvId = CanvasDefs::canvasID_fromString (idStr.toLatin1()); const QString showStr = chElem.attribute (XML_ATTRIB_SHOW); const bool doShow = !showStr.isEmpty() && (showStr != "0"); if (doShow) { setCanvasId (canvId); } const QString xStr = chElem.attribute (XML_ATTRIB_X, "-1"); const QString yStr = chElem.attribute (XML_ATTRIB_Y, "-1"); bool xOk (false); bool yOk (false); const double xVal = xStr.toDouble (&xOk); const double yVal = yStr.toDouble (&yOk); if (xOk && yOk) { switch (canvId) { case CanvasDefs::CanvasID_SIMULATION: setSimXY (xVal, yVal); break; case CanvasDefs::CanvasID_ACCOUNTING: setAccXY (xVal, yVal); break; } } } } } return okstat (true); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- okstat Ornament::loadFromXml (const QString& xmlStr, const QString& srcDesc) { okstat loadOk (true); // ************************************************ // *** Read XML Document from Provided String *** // ************************************************ QDomDocument ornamentDoc; QString errMsg (""); int errLine (-1); int errCol (-1); const bool setContentOk = ornamentDoc.setContent (xmlStr, &errMsg, &errLine, &errCol); if (!setContentOk) { QString msg (""); cwFormatMsg (msg, MSG_XML_LN_PARSE_ERR, "Workspace Ornament Data", qPrintable (srcDesc), errLine, errCol, qPrintable (errMsg)); loadOk = okstat (msg); } else // (setContentOk) { // ****************************************************** // *** Load this Ornament from the XML DOM Document *** // ****************************************************** loadOk = loadFromDomElement (ornamentDoc.documentElement(), srcDesc); } return (loadOk); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void Ornament::testSerial() { static const char* mname ("Ornament::testSerial"); Ornament outOrn; outOrn.setImage (Ornament::ImageTypeUser, 7); outOrn.setDisplayText ("Something happens here (Text)"); outOrn.setTooltipText ("Something happens here (Tooltip)"); outOrn.setCanvasId (CanvasDefs::CanvasID_SIMULATION); outOrn.setSimXY (422, 755); const QString xmlStr = outOrn.toXml(); const QString testPath = RwFileDialog::getSaveFileName (RwFile::For_Output, NULL, "Test Ornament XML Output"); if (testPath.isEmpty()) return; //--------------------------->> QFile testOutFile (testPath); testOutFile.open (QIODevice::WriteOnly | QIODevice::Text); testOutFile.write (xmlStr.toLatin1()); testOutFile.close(); QFile testInFile (testPath); testInFile.open (QIODevice::ReadOnly | QIODevice::Text); const QByteArray inBytes = testInFile.readAll(); testInFile.close(); const QString inStr (inBytes); Ornament inOrn; okstat loadOk = inOrn.loadFromXml (inStr, mname); const bool equal = (outOrn == inOrn); std::cout << mname << " " << (equal ? "SUCCESS" : "FAILURE") << "\n .. " << qPrintable (loadOk.msg()) << std::endl; } //--- (end Ornament.cpp) ---