mit unitType

This commit is contained in:
2025-08-09 11:56:11 +02:00
parent c89cdfef71
commit 63f139de8c
10 changed files with 147 additions and 64 deletions

View File

@@ -35,23 +35,57 @@ XQChildModel::XQChildModel( QObject *parent )
void XQChildModel::initModel(const QString& modelName) void XQChildModel::initModel(const QString& modelName)
{ {
auto extendItemType = [=](const XQNodePtr& entry)
{
const QString& typeName = entry->attribute("ItemType");
XQItemType* itemType = _itemFactory.findItemTypeTemplate( typeName); // throws
// über alle attribute
for (const auto& attr : entry->attributes())
{
// prüfen, ob der itemType des attribute schon hat
int role = itemType->hasAttribute( attr.first);
// wenn ja, überschreiben
if( role != XQItem::NoRole )
{
QVariant newValue = _itemFactory.makeVariant(role,attr.second);
itemType->replaceAttribute( newValue, role );
}
}
};
// #0: Wir suchen die Model-Beschreibung // #0: Wir suchen die Model-Beschreibung
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
// #1: Wie erzeugen die Model-Struktur: Jedes Kind beschreibt einen // #1: Wir erzeugen die Model-Struktur: Jedes Kind beschreibt einen
// XML-Datentyp, z.B. <Panel atr1="..." />, <Battery .../> // XML-Datentyp, z.B. <Panel atr1="..." />, <Battery .../>
// Jeder XML-Knoten entspricht einer Zeile im späteren Model, jedes // Jeder XML-Knoten entspricht einer Zeile im späteren Model, jedes
// Attribut wird einem eigenen Feld (XQItem) abgebildet. // Attribut wird einem eigenen Feld (XQItem) abgebildet.
for( auto& sheetNode : modelSheet->children() ) for( const auto& sheetNode : modelSheet->children() )
{ {
XQItemList list = _itemFactory.makeHeaderRow( sheetNode ); XQItemList list = _itemFactory.makeHeaderRow( sheetNode );
// für jeden XML-Knotentyp in der Modelbeschreibung erzeugen wir eine section // für jeden XML-Knotentyp in der Modelbeschreibung erzeugen wir eine section
addSection(list, sheetNode ); addSection(list, sheetNode );
// jedes kind kann enthält einen itemType und einen headerItemType. Für
// diese sind eventuell weitere attribute vorhanden, die die im type
// enthaltenen defualt-werte überschreiben.
for( const auto& sheetChild : sheetNode->children() )
{
//qDebug() << "---- kloppo: " << sheetChild->tag_name() << ": " << sheetChild->to_string();
extendItemType( sheetChild );
}
/* /*
// empty row // empty row:
XQNodePtr contentNode = XQNode::make_node( sheetNode->tag_name() ); XQNodePtr contentNode = XQNode::make_node( sheetNode->tag_name() );
XQItemList emptyRow = _itemFactory.makeEmptyRow( contentNode, sheetNode ); XQItemList emptyRow = _itemFactory.makeEmptyRow( contentNode, sheetNode );
appendRow( emptyRow ); appendRow( emptyRow );

View File

@@ -451,6 +451,7 @@ QVariant XQItem::data(int role ) const
case IconRole: // aka Qt::DecorationRole, case IconRole: // aka Qt::DecorationRole,
case RenderStyleRole: case RenderStyleRole:
case EditorTypeRole: case EditorTypeRole:
case UnitTypeRole:
case ContentFormatRole: case ContentFormatRole:
case FixedChoicesRole: case FixedChoicesRole:
{ {
@@ -504,12 +505,11 @@ QVariant XQItem::data(int role ) const
return firstItem.data( XQItem::ContentNodeRole ); return firstItem.data( XQItem::ContentNodeRole );
} }
case UnitTypeRole:
case Qt::StatusTipRole: case Qt::StatusTipRole:
case Qt::WhatsThisRole: case Qt::WhatsThisRole:
case Qt::SizeHintRole: case Qt::SizeHintRole:
case Qt::FontRole: case Qt::FontRole:
case Qt::TextAlignmentRole: case Qt::TextAlignmentRole:
case Qt::BackgroundRole: case Qt::BackgroundRole:
@@ -554,13 +554,18 @@ void XQItem::setData(const QVariant& value, int role )
case RenderStyleRole : case RenderStyleRole :
case EditorTypeRole : case EditorTypeRole :
case UnitTypeRole:
case ContentFormatRole: case ContentFormatRole:
case FlagsRole: // Stimmt das? case FlagsRole: // Stimmt das?
case IconRole: case IconRole:
case FixedChoicesRole: case FixedChoicesRole:
{ {
//qDebug() << " ---call type set Data: " << role << ": " << XQItem::fetchItemDataRoleName(role) << ":" << value.toString(); //qDebug() << " ---call type set Data: " << role << ": " << XQItem::fetchItemDataRoleName(role) << ":" << value.toString();
itemType().replaceAttribute( this, value, role ); XQItemType* oldType = &itemType();
XQItemType* newType = oldType->replaceAttribute(value, role );
if( oldType != newType )
setItemType( newType );
emitDataChanged(); emitDataChanged();
// no break, return! // no break, return!
return; return;
@@ -593,8 +598,6 @@ void XQItem::setData(const QVariant& value, int role )
} }
// alles andere wie gehabt // alles andere wie gehabt
case UnitTypeRole:
case ContentNodeRole: case ContentNodeRole:
case SheetNodeRole: case SheetNodeRole:

View File

@@ -28,7 +28,7 @@ void XQItemFactory::initItemFactory( const QString& modelSheetFileName )
// über alle attribute // über alle attribute
for( const auto& [key,value] : sheetNode->attributes() ) for( const auto& [key,value] : sheetNode->attributes() )
{ {
qDebug() << " --- conf: " << key << " : " << value; qDebug() << " --- conf item Type: " << key << " : " << value;
setItemDataFromString( *itemType, key, value ); setItemDataFromString( *itemType, key, value );
} }
}; };
@@ -45,7 +45,7 @@ void XQItemFactory::initItemFactory( const QString& modelSheetFileName )
_typesSheet = _modelSheet->find_child_by_tag_name( "ItemTypes" ); _typesSheet = _modelSheet->find_child_by_tag_name( "ItemTypes" );
// ... und testen // ... und testen
if( !_typesSheet ) if( !_typesSheet )
throw XQException( "initItemFactory typeSheetRoot is null" ); throw XQException( "initItemFactory <ItemTypes> is null" );
// alle itemtype vorlagen erzeugen // alle itemtype vorlagen erzeugen
for( const XQNodePtr& typeSheetNode : _typesSheet->children()) for( const XQNodePtr& typeSheetNode : _typesSheet->children())
@@ -56,8 +56,9 @@ void XQItemFactory::initItemFactory( const QString& modelSheetFileName )
configureItemType(itemType, typeSheetNode); configureItemType(itemType, typeSheetNode);
itemType->setText( typeName); itemType->setText( typeName);
s_ItemTypeCache[typeName] = itemType; s_ItemTypeTemplates[typeName] = itemType;
} }
} }
@@ -67,11 +68,32 @@ bool XQItemFactory::isValid()
} }
XQItemType* XQItemFactory::findItemType(const QString& key ) const //! es reicht nicht, einen itemType aus den itemType-templates zu
//! holen: möglicherweise muss der noch mit zusätzlichen attributen
//! ergänzt werden, (hier 'UnitType' ). Al
//!
//! \param sheetEntry
//! \return
//!
XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
{ {
if( !key.isEmpty() && s_ItemTypeCache.contains(key)) QString typeKey = sheetEntry->attribute("ItemType");
return s_ItemTypeCache[key]; XQItemType* itemType = findItemTypeTemplate(typeKey);
throw XQException( "itemfactory: findItemType: not found:", key );
// wir prüfen, ob im sheetEntry noch zusätzliche attribute vorhanden
// sind, die wir in dem itemType müssen
return itemType;
}
XQItemType* XQItemFactory::findItemTypeTemplate(const QString& key ) const
{
if( !key.isEmpty() && s_ItemTypeTemplates.contains(key))
return s_ItemTypeTemplates[key];
throw XQException( "itemfactory: findItemTypeTemplate: not found:", key );
} }
@@ -85,11 +107,13 @@ XQNodePtr XQItemFactory::findModelSheet( const QString& modelName ) const
} }
XQItem* XQItemFactory::makeContentItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry ) const XQItem* XQItemFactory::makeContentItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry )
{ {
// den itemtype des neuen items rausfinden // den itemtype des neuen items rausfinden
QString typeKey = sheetEntry->attribute("ItemType"); QString typeKey = sheetEntry->attribute("ItemType");
XQItemType* itemType = findItemType(typeKey); // throws //XQItemType* itemType = findItemTypeTemplate(typeKey); // throws
XQItemType* itemType = makeItemType(sheetEntry); // throws
const QString* contentPtr = contentNode->attribute_ptr( sheetEntry->tag_name() ); const QString* contentPtr = contentNode->attribute_ptr( sheetEntry->tag_name() );
XQItem* newItem = new XQItem( itemType, contentPtr ); XQItem* newItem = new XQItem( itemType, contentPtr );
@@ -98,7 +122,7 @@ XQItem* XQItemFactory::makeContentItem( const XQNodePtr& contentNode, const XQNo
} }
XQItem* XQItemFactory::makeHeaderItem( const XQNodePtr& sheetEntry ) const XQItem* XQItemFactory::makeHeaderItem( const XQNodePtr& sheetEntry )
{ {
// header items are all non-data items: // header items are all non-data items:
// - section header row items // - section header row items
@@ -108,7 +132,7 @@ XQItem* XQItemFactory::makeHeaderItem( const XQNodePtr& sheetEntry ) const
// den itemtype des neuen items rausfinden // den itemtype des neuen items rausfinden
QString typeKey = sheetEntry->attribute("HeaderItemType"); QString typeKey = sheetEntry->attribute("HeaderItemType");
XQItemType* itemType = findItemType(typeKey); // throws XQItemType* itemType = findItemTypeTemplate(typeKey); // throws
// das ist Unterschied zum normalen Item: Der Titel kommt aus der Modelbeschreibung // das ist Unterschied zum normalen Item: Der Titel kommt aus der Modelbeschreibung
const QString* contentPtr = sheetEntry->attribute_ptr("HeaderCaption"); const QString* contentPtr = sheetEntry->attribute_ptr("HeaderCaption");
@@ -148,7 +172,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
case XQItem::ItemTypeRole: case XQItem::ItemTypeRole:
{ {
// itemType() -> XQItemType* // itemType() -> XQItemType*
XQItemType* itemType = findItemType( source ); XQItemType* itemType = findItemTypeTemplate( source );
value = QVariant::fromValue(itemType); value = QVariant::fromValue(itemType);
break; break;
} }

View File

@@ -32,9 +32,8 @@ public:
XQNodePtr findModelSheet( const QString& modelName ) const; XQNodePtr findModelSheet( const QString& modelName ) const;
XQItem* makeHeaderItem(const XQNodePtr& typeSheetNode );
XQItem* makeHeaderItem(const XQNodePtr& typeSheetNode ) const; XQItem* makeContentItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry );
XQItem* makeContentItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry ) const;
virtual XQItemList makeHeaderRow( const XQNodePtr& sheetNode ); virtual XQItemList makeHeaderRow( const XQNodePtr& sheetNode );
virtual XQItemList makeContentRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode ); virtual XQItemList makeContentRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
@@ -44,8 +43,8 @@ public:
void setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const; void setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const;
// __fix! unsinn! XQItemType* makeItemType(const XQNodePtr& sheetEntry );
XQItemType* findItemType(const QString& key ) const; XQItemType* findItemTypeTemplate(const QString& key ) const;
QVariant makeVariant(int dataRole, const QString &value ) const; QVariant makeVariant(int dataRole, const QString &value ) const;
protected: protected:
@@ -56,7 +55,7 @@ protected:
using ItemConfigFunc = std::function<void( XQItem* item, const QString& attrValue, XQNodePtr contentNode, XQNodePtr sheetNode )>; using ItemConfigFunc = std::function<void( XQItem* item, const QString& attrValue, XQNodePtr contentNode, XQNodePtr sheetNode )>;
using ItemConfigMap = QMap<QString,ItemConfigFunc>; using ItemConfigMap = QMap<QString,ItemConfigFunc>;
XQItemTypeMap s_ItemTypeCache; XQItemTypeMap s_ItemTypeTemplates;
// Beschreibung des XQModels // Beschreibung des XQModels
XQNodePtr _modelSheet{}; XQNodePtr _modelSheet{};

View File

@@ -69,16 +69,36 @@ void XQItemType::setData(const QVariant& value, int role )
return QStandardItem::setData(value,role); return QStandardItem::setData(value,role);
} }
//! tested, ob ein attribute (z.B. unitType) hier vorhanden ist
int XQItemType::hasAttribute( const QString& attrKey )
{
int role = XQItem::fetchItemDataRole(attrKey);
// gibbed überhaupt eine rolle für unser attribut?
if( role == XQItem::NoRole)
return XQItem::NoRole;
// wenn ja, ist die role hier besetzt?
QVariant value = data(role);
if( !value.isValid() || value.isNull() )
return XQItem::NoRole;
return role;
}
//! setzt einen attributwert neu. Ggf. wird ein neuer ItemType erzeugt. //! setzt einen attributwert neu. Ggf. wird ein neuer ItemType erzeugt.
void XQItemType::replaceAttribute( XQItem* item, const QVariant& newValue, int role ) XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
{ {
// hat sich überhaupt was geändert? // hat sich überhaupt was geändert?
QVariant oldValue = data(role); QVariant oldValue = data(role);
// ja, es hat
if( oldValue != newValue ) // nein, es hat nicht
{ if( oldValue == newValue )
return this;
// kopie von mir
XQItemType* myClone = new XQItemType(*this); XQItemType* myClone = new XQItemType(*this);
// Änderungen übernehmen // Änderungen übernehmen
myClone->setData( newValue, role ); myClone->setData( newValue, role );
@@ -87,20 +107,22 @@ void XQItemType::replaceAttribute( XQItem* item, const QVariant& newValue, int r
// jawoll // jawoll
if( s_ItemTypeMap.contains( newKey ) ) if( s_ItemTypeMap.contains( newKey ) )
{ {
// nur abräumen, sonst nix // abräumen ...
delete myClone; delete myClone;
// und die alte version zurückgegen
return s_ItemTypeMap[newKey];
} }
else
{
// speichern // speichern
s_ItemTypeMap.insert( newKey, myClone ); s_ItemTypeMap.insert( newKey, myClone );
// und ins item übernehmen // und ins item übernehmen
item->setItemType( myClone ); //item.setItemType( myClone );
/// Obacht! Der alte, geänderte itemType bleibt erhalten /// Obacht! Der alte, geänderte itemType bleibt erhalten
/// und verrottet ggf. ohne Daseinszweck /// und verrottet ggf. ohne Daseinszweck
}
} return myClone;
} }
QVariant XQItemType::formatText( const XQItem& item ) const QVariant XQItemType::formatText( const XQItem& item ) const

View File

@@ -45,7 +45,8 @@ public:
QString formatToSI(const QString& rawText, XQItem::UnitType unitType ) const; QString formatToSI(const QString& rawText, XQItem::UnitType unitType ) const;
QString unFormatFromSI(const QString& valueText ) const; QString unFormatFromSI(const QString& valueText ) const;
void replaceAttribute( XQItem* item, const QVariant& newValue, int role ); int hasAttribute( const QString& attrKey );
XQItemType* replaceAttribute(const QVariant& newValue, int role );
QString makeItemTypeKey(); QString makeItemTypeKey();

View File

@@ -430,14 +430,14 @@ void XQViewModel::cmdToggleSection( const QModelIndex& index )
} }
//! firz //! git die treetable zurück
XQTreeTable* XQViewModel::treeTable() XQTreeTable* XQViewModel::treeTable()
{ {
return _treeTable; return _treeTable;
} }
//! firz //! setzt die treetable als member.
void XQViewModel::setTreeTable(XQTreeTable* mainView ) void XQViewModel::setTreeTable(XQTreeTable* mainView )
{ {

View File

@@ -232,13 +232,13 @@ namespace znode
if( !_attributes.empty() ) if( !_attributes.empty() )
{ {
result += " ["; result += " [";
bool first = true; bool beg = true;
for (const auto& entry : _attributes) for (const auto& entry : _attributes)
{ {
if(first) if(beg)
{ {
result += entry.first + "=" + entry.second; result += entry.first + "=" + entry.second;
first = false; beg = false;
continue; continue;
} }
result += ", " + entry.first + "=" + entry.second; result += ", " + entry.first + "=" + entry.second;

View File

@@ -11,7 +11,7 @@
<StaticType RenderStyle="PlainStyle"/> <StaticType RenderStyle="PlainStyle"/>
<TreeChildType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsDragEnabled|IsSelectable|IsDropEnabled"/> <TreeChildType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsDragEnabled|IsSelectable|IsDropEnabled"/>
<PlainType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/> <PlainType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/>
<ValueType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/> <ValueType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="###"/>
<PercentageType RenderStyle="ProgressBarStyle" ItemFlags="IsEnabled|IsSelectable"/> <PercentageType RenderStyle="ProgressBarStyle" ItemFlags="IsEnabled|IsSelectable"/>
<ChoiceType RenderStyle="ComboBoxStyle" ItemFlags="IsEnabled|IsSelectable|IsEditable" FixedChoices="la|le|lo|lu"/> <ChoiceType RenderStyle="ComboBoxStyle" ItemFlags="IsEnabled|IsSelectable|IsEditable" FixedChoices="la|le|lo|lu"/>
<IntValueType RenderStyle="SpinBoxStyle" ItemFlags="IsEnabled|IsSelectable"/> <IntValueType RenderStyle="SpinBoxStyle" ItemFlags="IsEnabled|IsSelectable"/>