/*
Copyright 2006-2025 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see .
*/
#include "xmlprojectelementcollectionitem.h"
#include "../qeticons.h"
#include "../qetproject.h"
#include "xmlelementcollection.h"
/**
@brief XmlProjectElementCollectionItem::XmlProjectElementCollectionItem
Constructor
*/
XmlProjectElementCollectionItem::XmlProjectElementCollectionItem()
{}
/**
@brief XmlProjectElementCollectionItem::isDir
@return true if this item represent a directory
*/
bool XmlProjectElementCollectionItem::isDir() const
{
if (m_dom_element.tagName() == "category") return true;
else return false;
}
/**
@brief XmlProjectElementCollectionItem::isElement
@return true if this item represent an element
*/
bool XmlProjectElementCollectionItem::isElement() const
{
if (m_dom_element.tagName() == "element") return true;
else return false;
}
/**
@brief XmlProjectElementCollectionItem::localName
@return the located name of this item
*/
QString XmlProjectElementCollectionItem::localName()
{
if (!text().isNull())
return text();
if (isCollectionRoot()) {
if (m_project->title().isEmpty())
setText(QObject::tr("Projet sans titre"));
else
setText(m_project->title());
}
else {
ElementsLocation location (embeddedPath(), m_project);
setText(location.name());
}
return text();
}
/**
@brief XmlProjectElementCollectionItem::name
@return The collection name of this item
*/
QString XmlProjectElementCollectionItem::name() const
{
return m_dom_element.attribute("name");
}
/**
@brief XmlProjectElementCollectionItem::collectionPath
@return The path of this item relative to the collection.
*/
QString XmlProjectElementCollectionItem::collectionPath() const
{
ElementsLocation loc (embeddedPath(), m_project);
QString p = loc.projectCollectionPath();
if (p.isEmpty())
p = QObject::tr("Collection");
return p;
}
/**
@brief XmlProjectElementCollectionItem::embeddedPath
@return The embedde path of this item
The path is in form : embed://dir/subdir/myElement.elmt
*/
QString XmlProjectElementCollectionItem::embeddedPath() const
{
if (isCollectionRoot())
return "embed://";
else if (parent()){
XmlProjectElementCollectionItem *xpeci = static_cast(parent());
if (xpeci->isCollectionRoot())
return xpeci->embeddedPath() + name();
else
return xpeci->embeddedPath() + "/" + name();
}
else
return QString();
}
/**
@brief XmlProjectElementCollectionItem::isCollectionRoot
@return true if this item represent the root of collection
*/
bool XmlProjectElementCollectionItem::isCollectionRoot() const
{
if (!parent())
return true;
else if (parent()->type() != XmlProjectElementCollectionItem::Type)
return true;
else
return false;
}
/**
@brief XmlProjectElementCollectionItem::addChildAtPath
Ask to this item item to add a new child with collection name collection_name
(the child must exist in the xml element collection)
@param collection_name : name of the child item to add.
*/
void XmlProjectElementCollectionItem::addChildAtPath(
const QString &collection_name)
{
if (collection_name.isEmpty())
return;
QString str (collection_name.endsWith(".elmt")? "element" : "category");
QDomElement child_element = m_dom_element.firstChildElement(str);
while (!child_element.isNull()) {
if (child_element.attribute("name") == collection_name) {
XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem ();
insertRow(rowForInsertItem(collection_name), xpeci);
xpeci->setXmlElement(child_element, m_project);
xpeci->setUpData();
return;
}
else
child_element = child_element.nextSiblingElement(str);
}
}
/**
@brief XmlProjectElementCollectionItem::project
@return the paretn project of the managed collection
*/
QETProject *XmlProjectElementCollectionItem::project() const
{
return m_project;
}
/**
@brief XmlProjectElementCollectionItem::setProject
Set the project for this item.
Use this method for set this item the root of the collection
@param project : project to manage the collection
@param set_data : if true, call setUpData for every child of this item
@param hide_element : bool
*/
void XmlProjectElementCollectionItem::setProject(QETProject *project,
bool set_data,
bool hide_element)
{
if (m_project)
return;
m_project = project;
m_dom_element = project->embeddedElementCollection()->root();
populate(set_data, hide_element);
}
/**
@brief XmlProjectElementCollectionItem::setUpData
SetUp the data of this item
*/
void XmlProjectElementCollectionItem::setUpData()
{
//Setup the displayed name
localName();
if (isDir()) {
setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled);
}
else
{
setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
//Set the local name and all informations of the element
//in the data Qt::UserRole+1, these data will be use for search.
ElementsLocation location(embeddedPath(), m_project);
DiagramContext context = location.elementInformations();
QStringList search_list;
for (QString key : context.keys()) {
search_list.append(context.value(key).toString());
}
search_list.append(localName());
setData(search_list.join(" "));
}
setToolTip(collectionPath());
}
/**
@brief XmlProjectElementCollectionItem::setUpIcon
SetUp the icon of this item.
Because icon use several memory, we use this method for setup icon instead setUpData.
*/
void XmlProjectElementCollectionItem::setUpIcon()
{
if (!icon().isNull())
return;
if (isCollectionRoot())
setIcon(QET::Icons::ProjectFileGP);
else if (isDir())
setIcon(QET::Icons::Folder);
else {
ElementsLocation loc(embeddedPath(), m_project);
setIcon(loc.icon());
}
}
/**
@brief XmlProjectElementCollectionItem::populate
Create the childs of this item
@param set_data : if true, call setUpData for every child of this item
@param hide_element : bool
*/
void XmlProjectElementCollectionItem::populate(bool set_data, bool hide_element)
{
QList dom_category = m_project->embeddedElementCollection()->directories(m_dom_element);
std::sort(dom_category.begin(), dom_category.end(), [](QDomElement a, QDomElement b){return (a.attribute("name") < b.attribute("name"));});
foreach (QDomElement element, dom_category)
{
XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem();
appendRow(xpeci);
xpeci->setXmlElement(element, m_project, set_data, hide_element);
if (set_data)
xpeci->setUpData();
}
if (hide_element)
return;
QList dom_elements = m_project->embeddedElementCollection()->elements(m_dom_element);
std::sort(dom_elements.begin(), dom_elements.end(), [](QDomElement a, QDomElement b){return (a.attribute("name") < b.attribute("name"));});
foreach (QDomElement element, dom_elements)
{
XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem();
appendRow(xpeci);
xpeci->setXmlElement(element, m_project, set_data);
if (set_data)
xpeci->setUpData();
}
}
/**
@brief XmlProjectElementCollectionItem::setXmlElement
Set the managed content of this item
@param element :
the dom element (directory or element), to be managed by this item
@param project : the parent project of managed collection
@param set_data : if true, call setUpData for every child of this item
@param hide_element : bool
*/
void XmlProjectElementCollectionItem::setXmlElement(const QDomElement& element,
QETProject *project,
bool set_data,
bool hide_element)
{
m_dom_element = element;
m_project = project;
populate(set_data, hide_element);
}