/*
Copyright 2006-2016 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 "qetproject.h"
#include "qeticons.h"
#include "xmlelementcollection.h"
#include "nameslist.h"
#include "qetapp.h"
#include "elementcollectionhandler.h"
#include
/**
* @brief XmlProjectElementCollectionItem::XmlProjectElementCollectionItem
* Default constructor.
* @param project -project for this item
* @param parent -paretn item
*/
XmlProjectElementCollectionItem::XmlProjectElementCollectionItem(QETProject *project, ElementCollectionItem *parent) :
ElementCollectionItem(parent),
m_project(project)
{
m_dom_element = project->embeddedElementCollection()->root();
populate();
}
/**
* @brief XmlProjectElementCollectionItem::XmlProjectElementCollectionItem
* Private constructor
* @param project -project for this item
* @param dom_element: the dom_element must represent this item
* @param parent
*/
XmlProjectElementCollectionItem::XmlProjectElementCollectionItem(QETProject *project, const QDomElement &dom_element, ElementCollectionItem *parent) :
ElementCollectionItem(parent),
m_project(project),
m_dom_element(dom_element)
{
populate();
}
/**
* @brief XmlProjectElementCollectionItem::~XmlProjectElementCollectionItem
*/
XmlProjectElementCollectionItem::~XmlProjectElementCollectionItem()
{}
/**
* @brief XmlProjectElementCollectionItem::data
* The data used by the view who display this item through the model
* @param column
* @param role
* @return
*/
QVariant XmlProjectElementCollectionItem::data(int column, int role)
{
if (column > 0)
return QVariant();
switch (role)
{
case Qt::DisplayRole:
return name();
break;
case Qt::DecorationRole:
if (isCollectionRoot())
return QIcon(QET::Icons::ProjectFileGP);
else if (isDir())
return QET::Icons::Folder;
else
{
if (m_icon.isNull())
{
ElementsLocation loc(embeddedPath(), m_project);
m_icon = loc.icon();
}
return m_icon;
}
break;
case Qt::ToolTipRole:
if (isCollectionRoot())
return m_project->filePath();
else
return collectionPath();
break;
default:
return ElementCollectionItem::data(column, role);
}
}
void XmlProjectElementCollectionItem::clearData()
{
m_icon = QIcon();
ElementCollectionItem::clearData();
}
/**
* @brief XmlProjectElementCollectionItem::mimeData
* @return The mimedata of this item
*/
QMimeData *XmlProjectElementCollectionItem::mimeData()
{
QMimeData *mime_data = new QMimeData();
mime_data->setText(collectionPath());
if (isElement())
mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1());
else
mime_data->setData("application/x-qet-category-uri", collectionPath().toLatin1());
return mime_data;
}
/**
* @brief XmlProjectElementCollectionItem::canDropMimeData
* @param data
* @param action
* @param row
* @param column
* @return True if the data can be dropped
*/
bool XmlProjectElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const
{
Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column);
if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri"))
{
//Return false if user try to drop a item from a folder to the same folder
ElementsLocation drop_location(data->text());
for (int i=0 ; i(child(i))->collectionPath() == drop_location.collectionPath())
return false;
}
return true;
}
else
return false;
}
/**
* @brief XmlProjectElementCollectionItem::dropMimeData
* @param data
* @param action
* @param row
* @param column
* @return handle a drop of a mime data
*/
bool XmlProjectElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column)
{
Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column);
XmlProjectElementCollectionItem *xpeci = this;
if (isElement() && parent() && parent()->type() == XmlProjectElementCollectionItem::Type)
xpeci = static_cast(parent());
//before do the copy, we get all collection path of child,
//for remove it if the copied item have the same path of an existing child.
//We can't do this after the copy, because at the copy if the xml collection have a DomElement with the same path,
//he was removed before the new xml DomElement is inserted
//So the existing child of this will return a null QString when call collectionPath(), because the item
//doesn't exist anymore in the xml collection.
QList child_path_list;
for (int i=0 ; i(child(i))->collectionPath());
ElementCollectionHandler ech;
ElementsLocation source(data->text());
ElementsLocation destination(xpeci->collectionPath());
ElementsLocation location = ech.copy(source, destination);
if (location.exist())
{
//If this item have a child with the same path of location, we remove the existing child before insert new child
for (int i=0 ; itype() != XmlProjectElementCollectionItem::Type) return true;
else return false;
}
/**
* @brief XmlProjectElementCollectionItem::name
* @return The name of this item, name is notably use for Qt::DisplayRole data
*/
QString XmlProjectElementCollectionItem::name()
{
if (!m_name.isNull()) return m_name;
if (isCollectionRoot())
{
if (m_project->title().isEmpty())
return QString("Projet sans titre");
else
return m_project->title();
}
else
{
ElementsLocation location (embeddedPath(), m_project);
m_name = location.name();
return m_name;
}
}
/**
* @brief XmlProjectElementCollectionItem::isValid
* @return Always true
*/
bool XmlProjectElementCollectionItem::isValid() const {
return true;
}
/**
* @brief XmlProjectElementCollectionItem::project
* @return The project for this collection item
*/
QETProject *XmlProjectElementCollectionItem::project() const {
return m_project;
}
/**
* @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::collectionPath
* @return The collection path of this item.
* The path is in form : project0+embed://dir/subdir/myElement.elmt
*/
QString XmlProjectElementCollectionItem::collectionPath() const
{
ElementsLocation loc (embeddedPath(), m_project);
return loc.projectCollectionPath();
}
/**
* @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
{
XmlProjectElementCollectionItem *parent = static_cast(m_parent_item);
if (parent->isCollectionRoot())
return parent->embeddedPath() + collectionName();
else
return parent->embeddedPath() + "/" + collectionName();
}
}
/**
* @brief XmlProjectElementCollectionItem::collectionName
* @return The collection name of this item
*/
QString XmlProjectElementCollectionItem::collectionName() const {
return m_dom_element.attribute("name");
}
/**
* @brief XmlProjectElementCollectionItem::insertNewItem
* When this XmlProjectElementCollectionItem is already created, we must to use this method for insert a new item.
* Befor use this, see rowForInsertItem and lastItemForPath
* @param collection_name : the collection name to search in the child of QDomElement.
*/
void XmlProjectElementCollectionItem::insertNewItem(const QString &collection_name)
{
if (collection_name.isEmpty()) return;
QDomNodeList node_list;
if (collection_name.endsWith(".elmt"))
node_list = m_dom_element.elementsByTagName("element");
else
node_list = m_dom_element.elementsByTagName("category");
QDomElement child_element;
for(int i=0 ; i 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(m_project, element, this);
this->appendChild(xpeci);
}
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(m_project, element, this);
this->appendChild(xpeci);
}
}