// Created on: 2020-01-25 // Created by: Natalia ERMOLAEVA // Copyright (c) 2020 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(TreeModel_ItemProperties, Standard_Transient) // ======================================================================= // function : Init // purpose : // ======================================================================= void TreeModel_ItemProperties::Init() { myRowValues.Clear(); InitByStream(Item()->Stream()); } // ======================================================================= // function : InitByStream // purpose : // ======================================================================= void TreeModel_ItemProperties::InitByStream(const Standard_SStream& aStream) { NCollection_IndexedDataMap aValues; TCollection_AsciiString aStreamText = Standard_Dump::Text(aStream); Standard_Dump::SplitJson(aStreamText, aValues); TreeModel_ItemStreamPtr aStreamParent = itemDynamicCast(Item()); TCollection_AsciiString aKey; Standard_DumpValue aKeyValue; if (!aStreamParent) { if (!Item() || Item()->Object().IsNull()) { aKey = "Dump"; } else { const Handle(Standard_Transient)& anItemObject = Item()->Object(); aKey = anItemObject.IsNull() ? "Dump" : anItemObject->DynamicType()->Name(); } aKeyValue = Standard_DumpValue(aStreamText, 1); myKey = aKey; myStreamValue = aKeyValue; } else { TCollection_AsciiString aValue; if (Item()->Parent()) { const Handle(TreeModel_ItemProperties)& aParentProperties = Item()->Parent()->Properties(); if (aParentProperties) aParentProperties->ChildStream(Item()->Row(), aKey, aKeyValue); } myKey = aKey; myStreamValue = aKeyValue; aValues.Clear(); Standard_Dump::SplitJson(myStreamValue.myValue, aValues); } for (Standard_Integer anIndex = 1; anIndex <= aValues.Size(); anIndex++) { Standard_DumpValue aValue = aValues.FindFromIndex(anIndex); if (Standard_Dump::HasChildKey(aValue.myValue)) myChildren.Add(aValues.FindKey(anIndex), aValue); else { TreeModel_RowValue aRowValue(aValue.myStartPosition, aValues.FindKey(anIndex).ToCString(), aValue.myValue.ToCString()); myRowValues.Add(myRowValues.Size() + 1, aRowValue); } } if (myRowValues.Size() == 1) { Quantity_Color aColor; if (Convert_Tools::ConvertStreamToColor(aStream, aColor)) { Standard_Real aRed, aGreen, aBlue; aColor.Values(aRed, aGreen, aBlue, Quantity_TOC_sRGB); int aDelta = 255; myRowValues.ChangeFromIndex(1).CustomValues.insert( (int)Qt::BackgroundRole, QColor((int)(aRed * aDelta), (int)(aGreen * aDelta), (int)(aBlue * aDelta))); } } // in case if the stream alert has empty key avalue, use as the key the first row value if ((myKey.IsEmpty() || myKey.IsEqual("Dump")) && myRowValues.Size() > 0) { myKey = myRowValues.FindFromIndex(1).Value.toString().toStdString().c_str(); } } // ======================================================================= // function : Reset // purpose : // ======================================================================= void TreeModel_ItemProperties::Reset() { myKey = ""; myStreamValue = Standard_DumpValue(); myChildren.Clear(); myRowValues.Clear(); } // ======================================================================= // function : RowCount // purpose : // ======================================================================= int TreeModel_ItemProperties::RowCount() const { return RowValues().Size(); } // ======================================================================= // function : Data // purpose : // ======================================================================= QVariant TreeModel_ItemProperties::Data(const int theRow, const int theColumn, int theRole) const { if (theColumn == 1 && theRole == Qt::BackgroundRole) { const QMap& aCachedValues = RowValues().FindFromIndex(theRow + 1).CustomValues; if (aCachedValues.contains((int)theRole)) return aCachedValues[(int)theRole]; } if (theRole == Qt::FontRole) // method name is in italic { if (Data(theRow, 0, Qt::DisplayRole).toString().contains("className")) { QFont aFont = qApp->font(); aFont.setItalic(true); return aFont; } } if (theRole == Qt::ForegroundRole) { if (Data(theRow, 0, Qt::DisplayRole).toString().contains("className")) return QColor(Qt::darkGray).darker(150); } if (theRole == Qt::DisplayRole || theRole == Qt::ToolTipRole) { if (theColumn == 0) return RowValues().FindFromIndex(theRow + 1).Key; else if (theColumn == 1) return RowValues().FindFromIndex(theRow + 1).Value; } return QVariant(); } // ======================================================================= // function : EditType // purpose : // ======================================================================= ViewControl_EditType TreeModel_ItemProperties::EditType(const int, const int theColumn) const { if (theColumn == 0) return ViewControl_EditType_None; Quantity_Color aColor; if (Convert_Tools::ConvertStreamToColor(Item()->Stream(), aColor)) { return ViewControl_EditType_Color; } return ViewControl_EditType_Line; } // ======================================================================= // function : ReplaceValue // purpose : // ======================================================================= Standard_Boolean ReplaceValue(const TCollection_AsciiString& theFromValue, const TCollection_AsciiString& theToValue, Standard_DumpValue& theStreamValue) { TCollection_AsciiString aStreamValue = theStreamValue.myValue; int aPosition = aStreamValue.FirstLocationInSet(theFromValue, 1, aStreamValue.Length()); if (aPosition < 1) return Standard_False; aPosition += 2; // due to 'FirstLocationInSet' returns position taking into account '"\' as 1 position TCollection_AsciiString aPartStart = aStreamValue.SubString(1, aPosition - 1); TCollection_AsciiString aPartFinal = aStreamValue.SubString(aPosition + theFromValue.Length(), aStreamValue.Length()); theStreamValue.myValue = aPartStart + theToValue + aPartFinal; return Standard_True; } // ======================================================================= // function : SetData // purpose : // ======================================================================= bool TreeModel_ItemProperties::SetData(const int theRow, const int theColumn, const QVariant& theValue, int theRole) { if (theColumn == 0) return false; if (theRole != Qt::DisplayRole && theRole != Qt::EditRole) return false; if (myRowValues.Size() == 1 && theColumn == 1) { TCollection_AsciiString aStreamValue(theValue.toString().toStdString().c_str()); NCollection_IndexedDataMap aKeyToValues; if (Standard_Dump::SplitJson(aStreamValue, aKeyToValues)) { Standard_SStream aStream; aStream << aStreamValue.ToCString(); int aStartPos = 1; Quantity_ColorRGBA aColor; if (aColor.InitFromJson(aStream, aStartPos)) { Standard_Real aRed, aGreen, aBlue; aColor.GetRGB().Values(aRed, aGreen, aBlue, Quantity_TOC_sRGB); int aDelta = 255; myRowValues.ChangeFromIndex(1).CustomValues.insert( (int)Qt::BackgroundRole, QColor((int)(aRed * aDelta), (int)(aGreen * aDelta), (int)(aBlue * aDelta))); } Standard_DumpValue aValue = aKeyToValues.FindFromIndex(1); myStreamValue.myValue = aValue.myValue.ToCString(); myRowValues.ChangeFromIndex(1).Value = aValue.myValue.ToCString(); Item()->StoreItemProperties(theRow, theColumn, theValue); return true; } TCollection_AsciiString aFromValue = myRowValues.ChangeFromIndex(1).Value.toString().toStdString().c_str(); if (ReplaceValue(aFromValue, aStreamValue, myStreamValue)) { aStreamValue = myStreamValue.myValue; if (Standard_Dump::SplitJson(aStreamValue, aKeyToValues)) { Standard_DumpValue aValue = aKeyToValues.FindFromIndex(1); myRowValues.ChangeFromIndex(1).Value = aValue.myValue.ToCString(); Item()->StoreItemProperties(theRow, theColumn, aStreamValue.ToCString()); return true; } } } myRowValues.ChangeFromIndex(theRow + 1).Value = theValue; Item()->StoreItemProperties(theRow, theColumn, theValue); return true; } // ======================================================================= // function : Presentations // purpose : // ======================================================================= void TreeModel_ItemProperties::Presentations( NCollection_List& thePresentations) { if (!Item()) { return; } const Standard_SStream& aStream = Item()->Stream(); Convert_Tools::ConvertStreamToPresentations(aStream, 1, -1, thePresentations); } // ======================================================================= // function : TableFlags // purpose : // ======================================================================= Qt::ItemFlags TreeModel_ItemProperties::TableFlags(const int, const int theColumn) const { Qt::ItemFlags aFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if (theColumn == 1) aFlags = aFlags | Qt::ItemIsEditable; return aFlags; } // ======================================================================= // function : ChildStream // purpose : // ======================================================================= void TreeModel_ItemProperties::ChildStream(const int theRowId, TCollection_AsciiString& theKey, Standard_DumpValue& theValue) const { if (myChildren.Size() <= theRowId) return; theKey = myChildren.FindKey(theRowId + 1); theValue = myChildren.FindFromIndex(theRowId + 1); } // ======================================================================= // function : initItem // purpose : // ======================================================================= void TreeModel_ItemProperties::initItem() const { if (!Item()) return; if (Item()->IsInitialized()) return; Item()->Init(); }