mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
Remove unused classes
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4533 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -1,503 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementdefinition.h"
|
||||
#include "elementscollection.h"
|
||||
#include "moveelementshandler.h"
|
||||
#include "moveelementsdescription.h"
|
||||
|
||||
/**
|
||||
@return true si l'element est rattache a une collection d'elements
|
||||
Un element appartenant a une collection a forcement un chemin virtuel.
|
||||
*/
|
||||
bool ElementDefinition::hasParentCategory() {
|
||||
return(parent_category_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementDefinition::uuid
|
||||
* @return The uuid of this element definition.
|
||||
* If uuid can't be found, return a null QUuid.
|
||||
*/
|
||||
QUuid ElementDefinition::uuid()
|
||||
{
|
||||
if (!m_uuid.isNull()) return m_uuid;
|
||||
|
||||
//Get the uuid of element
|
||||
QList<QDomElement> list_ = QET::findInDomElement(xml(), "uuid");
|
||||
|
||||
if (!list_.isEmpty())
|
||||
m_uuid = QUuid(list_.first().attribute("uuid"));
|
||||
else
|
||||
qDebug() << "The element : " << filePath() << "haven't got an uuid, please edit and save this element with element editor to create an uuid";
|
||||
|
||||
return m_uuid;
|
||||
|
||||
}
|
||||
|
||||
ElementsCategory *ElementDefinition::parentCategory() {
|
||||
return(parent_category_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la liste des categories parentes de cet item.
|
||||
*/
|
||||
QList<ElementsCategory *> ElementDefinition::parentCategories() {
|
||||
QList<ElementsCategory *> cat_list;
|
||||
if (ElementsCategory *par_cat = parentCategory()) {
|
||||
cat_list << par_cat -> parentCategories() << par_cat;
|
||||
}
|
||||
return(cat_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si l'element est rattache a une collection d'elements
|
||||
Un element appartenant a une collection a forcement un chemin virtuel.
|
||||
*/
|
||||
bool ElementDefinition::hasParentCollection() {
|
||||
return(parent_collection_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param other_item Autre item
|
||||
@return true si other_item est parent (direct ou indirect) de cet item, false sinon
|
||||
*/
|
||||
bool ElementDefinition::isChildOf(ElementsCollectionItem *other_item) {
|
||||
// soit l'autre item est le parent direct de cet element
|
||||
if (ElementsCategory *other_item_cat = other_item -> toCategory()) {
|
||||
if (other_item_cat == parentCategory()) {
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
// soit il est un parent indirect, auquel cas, on peut demander a la categorie parente de repondre a la question
|
||||
if (ElementsCategory *parent_cat = parentCategory()) {
|
||||
return(parent_cat -> isChildOf(other_item));
|
||||
}
|
||||
|
||||
// arrive ici, l'autre item n'est pas parent de cet item
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la collection d'element a laquelle appartient cet element
|
||||
*/
|
||||
ElementsCollection *ElementDefinition::parentCollection() {
|
||||
return(parent_collection_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le projet auquel appartient cette categorie, si celle-ci
|
||||
appartient a une collection.
|
||||
*/
|
||||
QETProject *ElementDefinition::project() {
|
||||
if (hasParentCollection()) {
|
||||
return(parentCollection() -> project());
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Ne fait rien ; le projet doit etre defini au niveau d'une collection
|
||||
*/
|
||||
void ElementDefinition::setProject(QETProject *) {
|
||||
}
|
||||
|
||||
/**
|
||||
@return le protocole utilise par la collection a laquelle appartient cet element
|
||||
*/
|
||||
QString ElementDefinition::protocol() {
|
||||
// il n'est pas possible d'avoir un protocole sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
|
||||
return(parentCollection() -> protocol());
|
||||
}
|
||||
|
||||
/**
|
||||
Ne fait rien
|
||||
*/
|
||||
void ElementDefinition::setProtocol(const QString &) {
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin virtuel complet de cet element (protocole + chemin)
|
||||
*/
|
||||
QString ElementDefinition::fullVirtualPath() {
|
||||
// il n'est pas possible d'avoir un chemin virtuel sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
|
||||
return(protocol() + "://" + virtualPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@return l'emplacement de l'element
|
||||
*/
|
||||
ElementsLocation ElementDefinition::location() {
|
||||
return(ElementsLocation(fullVirtualPath(), project()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return une liste vide - un element ne possede pas de categorie
|
||||
*/
|
||||
QList<ElementsCategory *> ElementDefinition::categories() {
|
||||
return(QList<ElementsCategory *>());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - un element ne possede pas de categorie
|
||||
*/
|
||||
ElementsCategory *ElementDefinition::category(const QString &) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - un element ne possede pas de categorie
|
||||
*/
|
||||
ElementsCategory *ElementDefinition::createCategory(const QString &) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return une liste contenant seulement cet element
|
||||
*/
|
||||
QList<ElementDefinition *> ElementDefinition::elements() {
|
||||
return(QList<ElementDefinition *>() << this);
|
||||
}
|
||||
|
||||
/**
|
||||
@return cet element si path est vide, 0 sinon
|
||||
*/
|
||||
ElementDefinition *ElementDefinition::element(const QString &path) {
|
||||
if (path.isEmpty()) return(this);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - un element n'en cree pas d'autre
|
||||
*/
|
||||
ElementDefinition *ElementDefinition::createElement(const QString &) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return always true - an element contains nothing but itself
|
||||
*/
|
||||
bool ElementDefinition::isEmpty() {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return always 1
|
||||
*/
|
||||
int ElementDefinition::count() {
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - un element n'est pas une collection
|
||||
*/
|
||||
ElementsCollection *ElementDefinition::toCollection() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la categorie parente de cet element
|
||||
*/
|
||||
ElementsCategory *ElementDefinition::toCategory() {
|
||||
return(parentCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - un element n'est pas une categorie
|
||||
*/
|
||||
ElementsCategory *ElementDefinition::toPureCategory() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return un pointeur ElementDefinition * sur cet element
|
||||
*/
|
||||
ElementDefinition *ElementDefinition::toElement() {
|
||||
return(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementDefinition::equals
|
||||
* @param other : ElementDefinition to compare with this
|
||||
* @return true if this element definition and other element definition is the same, else false
|
||||
*/
|
||||
bool ElementDefinition::equals(ElementDefinition &other)
|
||||
{
|
||||
//Compare the uuid of the elements
|
||||
QList <QDomElement> this_uuid_dom = QET::findInDomElement(xml(), "uuid");
|
||||
QList <QDomElement> other_uuid_dom = QET::findInDomElement(other.xml(), "uuid");
|
||||
if ((this_uuid_dom.size() == 1) && (other_uuid_dom.size() == 1))
|
||||
return this_uuid_dom.first().attribute("uuid") == other_uuid_dom.first().attribute("uuid") ? true : false;
|
||||
|
||||
//********
|
||||
//The code below is used to keep compatibility with previous version of qet
|
||||
//The uuid store in .elmt file, to compare two elements was created at version svn 4032
|
||||
///@TODO remove this code at version 0.6 or 0.7 (all users should already used the version with uuid)
|
||||
//********
|
||||
//Compare the xml definition transformed in QString. This method can return a false positive (notably with Qt5,
|
||||
//because the attributes of the xml isn't at the same order,with two instance of qet, for the same element)
|
||||
QDomDocument this_xml_document;
|
||||
this_xml_document.appendChild(this_xml_document.importNode(xml(), true));
|
||||
QString this_text = this_xml_document.toString(0);
|
||||
|
||||
QDomDocument other_xml_document;
|
||||
other_xml_document.appendChild(other_xml_document.importNode(other.xml(), true));
|
||||
QString other_text = other_xml_document.toString(0);
|
||||
|
||||
return(other_text == this_text);
|
||||
}
|
||||
|
||||
/**
|
||||
@param target_category Categorie cible pour la copie ; elle doit exister
|
||||
@param handler Gestionnaire d'erreurs a utiliser pour effectuer la copie
|
||||
@param deep_copy Argument ignore - une copie "recursive" n'a pas de sens pour un element
|
||||
@return La copie de l'element ou 0 si le processus a echoue
|
||||
*/
|
||||
ElementsCollectionItem *ElementDefinition::copy(ElementsCategory *target_category, MoveElementsHandler *handler, bool deep_copy) {
|
||||
Q_UNUSED(deep_copy);
|
||||
if (!target_category) return(0);
|
||||
|
||||
// echec si le path name de cet element est vide
|
||||
QString elmt_name(pathName());
|
||||
if (elmt_name.isEmpty()) return(0);
|
||||
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription mvt_desc;
|
||||
mvt_desc.setDestinationParentCategory(target_category);
|
||||
// on tente une copie avec le meme nom interne
|
||||
mvt_desc.setOriginalDestinationInternalName(pathName());
|
||||
mvt_desc.setFinalDestinationInternalName(pathName());
|
||||
mvt_desc.setHandler(handler);
|
||||
|
||||
copy(&mvt_desc);
|
||||
return(mvt_desc.createdItem());
|
||||
}
|
||||
|
||||
/**
|
||||
Methode privee effectuant une copie de cet element a partir d'une
|
||||
description du mouvement.
|
||||
@param mvt_desc Description du mouvement
|
||||
*/
|
||||
void ElementDefinition::copy(MoveElementsDescription *mvt_desc) {
|
||||
// quelques pointeurs pour simplifier l'ecriture de la methode
|
||||
MoveElementsHandler *handler = mvt_desc -> handler();
|
||||
ElementsCategory *target_category = mvt_desc -> destinationParentCategory();
|
||||
|
||||
ElementDefinition *element_copy = 0;
|
||||
|
||||
// verifie que la categorie parente cible est accessible en lecture
|
||||
if (!target_category -> isReadable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
QET::Action todo = handler -> categoryIsNotReadable(target_category);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!target_category -> isReadable());
|
||||
}
|
||||
}
|
||||
|
||||
// verifie que la categorie parente cible est accessible en ecriture
|
||||
if (!target_category -> isWritable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
QET::Action todo = handler -> categoryIsNotWritable(target_category);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!target_category -> isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
// verifie que la cible n'existe pas deja
|
||||
if ((element_copy = target_category -> element(mvt_desc -> finalDestinationInternalName()))) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
// la cible existe deja : on demande au Handler ce qu'on doit faire
|
||||
QET::Action todo = handler -> elementAlreadyExists(this, element_copy);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Erase) {
|
||||
break;
|
||||
} else if (todo == QET::Rename) {
|
||||
mvt_desc -> setFinalDestinationInternalName(handler -> nameForRenamingOperation());
|
||||
}
|
||||
} while ((element_copy = target_category -> element(mvt_desc -> finalDestinationInternalName())));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A ce stade, on peut creer l'element cible : soit il n'existe pas, soit
|
||||
on a l'autorisation de l'ecraser
|
||||
*/
|
||||
|
||||
// si la cible existe deja, verifie qu'elle est accessible en ecriture
|
||||
element_copy = target_category -> element(mvt_desc -> finalDestinationInternalName());
|
||||
if (element_copy && !element_copy -> isWritable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
// la cible n'est pas accessible en ecriture : on demande au Handler ce qu'on doit faire
|
||||
QET::Action todo = handler -> elementIsNotWritable(element_copy);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!element_copy -> isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
// cree l'element cible
|
||||
element_copy = target_category -> createElement(mvt_desc -> finalDestinationInternalName());
|
||||
if (!element_copy) {
|
||||
if (handler) {
|
||||
handler -> errorWithAnElement(this, tr("L'élément cible n'a pu être créé."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// recopie la definition de l'element
|
||||
element_copy -> setXml(xml());
|
||||
element_copy -> write();
|
||||
mvt_desc -> setCreatedItem(element_copy);
|
||||
}
|
||||
|
||||
/**
|
||||
@param target_category Categorie cible pour le deplacement ; elle doit exister
|
||||
@param handler Gestionnaire d'erreurs a utiliser pour effectuer le deplacement
|
||||
@return L'element apres deplacement ou 0 si le processus a echoue
|
||||
|
||||
*/
|
||||
ElementsCollectionItem *ElementDefinition::move(ElementsCategory *target_category, MoveElementsHandler *handler) {
|
||||
if (!target_category) return(0);
|
||||
|
||||
// echec si le path name de cet element est vide
|
||||
QString elmt_name(pathName());
|
||||
if (elmt_name.isEmpty()) return(0);
|
||||
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription mvt_desc;
|
||||
mvt_desc.setDestinationParentCategory(target_category);
|
||||
// on tente un deplacement avec le meme nom interne
|
||||
mvt_desc.setOriginalDestinationInternalName(pathName());
|
||||
mvt_desc.setFinalDestinationInternalName(pathName());
|
||||
mvt_desc.setHandler(handler);
|
||||
|
||||
move(&mvt_desc);
|
||||
return(mvt_desc.createdItem());
|
||||
}
|
||||
|
||||
/**
|
||||
Methode privee effectuant un delacement de cet element a partir d'une
|
||||
description du mouvement.
|
||||
Pour etre plus exact, cette methode effectue d'abord une copie de l'element,
|
||||
puis, si celle-ci a reussi, il supprime l'element d'origine.
|
||||
@param mvt_desc Description du mouvement
|
||||
*/
|
||||
void ElementDefinition::move(MoveElementsDescription *mvt_desc) {
|
||||
// effectue une copie de l'element
|
||||
copy(mvt_desc);
|
||||
ElementsCollectionItem *item_copy = mvt_desc -> createdItem();
|
||||
if (!item_copy) return;
|
||||
ElementDefinition *element_copy = item_copy -> toElement();
|
||||
if (!element_copy) return;
|
||||
|
||||
// supprime cet element
|
||||
MoveElementsHandler *handler = mvt_desc -> handler();
|
||||
|
||||
// cet element doit etre accessible en ecriture pour etre supprime
|
||||
if (!isWritable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
// on demande au Handler ce qu'on doit faire
|
||||
QET::Action todo = handler -> elementIsNotWritable(this);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
// supprime cet element (sinon il ne s'agirait que d'une copie, pas d'un deplacement)
|
||||
bool element_deletion = remove();
|
||||
mvt_desc -> setSourceItemDeleted(element_deletion);
|
||||
if (!element_deletion && handler) {
|
||||
handler -> errorWithAnElement(this, tr("La suppression de cet élément a échoué."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cette methode n'a aucun effet
|
||||
@return toujours true
|
||||
*/
|
||||
bool ElementDefinition::removeContent() {
|
||||
return(true);
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ELEMENT_DEFINITION_H
|
||||
#define ELEMENT_DEFINITION_H
|
||||
#include <QtXml>
|
||||
#include "elementscategory.h"
|
||||
class ElementsCollection;
|
||||
class MoveElementsHandler;
|
||||
/**
|
||||
This abstract class represents a way to access the XML definition of an
|
||||
element, be it from a .elmt file or from a QET project file.
|
||||
*/
|
||||
class ElementDefinition : public ElementsCollectionItem {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
Constructor
|
||||
*/
|
||||
ElementDefinition(ElementsCategory *category = 0, ElementsCollection *collection = 0) :
|
||||
ElementsCollectionItem(category),
|
||||
parent_category_(category),
|
||||
parent_collection_(collection)
|
||||
{};
|
||||
|
||||
virtual ~ElementDefinition() {};
|
||||
|
||||
/**
|
||||
@return the XML definition of a particular element
|
||||
*/
|
||||
virtual QDomElement xml() = 0;
|
||||
virtual QUuid uuid();
|
||||
|
||||
/**
|
||||
Specify the XML definition of a particular element
|
||||
@param xml_element New XML definition
|
||||
@return true if everything went well, false otherwise
|
||||
*/
|
||||
virtual bool setXml(const QDomElement &xml_element) = 0;
|
||||
|
||||
/**
|
||||
@return true if the definition is not available
|
||||
*/
|
||||
virtual bool isNull() const = 0;
|
||||
|
||||
virtual ElementsCategory *parentCategory();
|
||||
virtual QList<ElementsCategory *> parentCategories();
|
||||
virtual bool hasParentCategory();
|
||||
|
||||
/**
|
||||
@return whether the element is attached to an elements collection
|
||||
An elemet which belongs to a collection always has a virtual path.
|
||||
*/
|
||||
virtual bool hasParentCollection();
|
||||
virtual bool isChildOf(ElementsCollectionItem *);
|
||||
|
||||
/**
|
||||
@return the elements collections this element belongs to
|
||||
*/
|
||||
virtual ElementsCollection *parentCollection();
|
||||
|
||||
virtual QETProject *project();
|
||||
virtual void setProject(QETProject *);
|
||||
/**
|
||||
@return the "protocol" used by the parent collection
|
||||
*/
|
||||
virtual QString protocol();
|
||||
/**
|
||||
Has no effect.
|
||||
*/
|
||||
virtual void setProtocol(const QString &);
|
||||
|
||||
/**
|
||||
@return the full virtual path for this element (i.e. "protocol" + path)
|
||||
*/
|
||||
virtual QString fullVirtualPath();
|
||||
|
||||
/**
|
||||
@return the location of this element, as an ElementsLocation object.
|
||||
@see ElementsLocation
|
||||
*/
|
||||
virtual ElementsLocation location();
|
||||
|
||||
virtual QList<ElementsCategory *> categories();
|
||||
virtual ElementsCategory *category(const QString &);
|
||||
virtual ElementsCategory *createCategory(const QString &);
|
||||
|
||||
virtual QList<ElementDefinition *> elements();
|
||||
virtual ElementDefinition *element(const QString &);
|
||||
virtual ElementDefinition *createElement(const QString &);
|
||||
virtual bool isEmpty();
|
||||
virtual int count();
|
||||
virtual ElementsCollectionItem *copy(ElementsCategory *, MoveElementsHandler *, bool = true);
|
||||
virtual ElementsCollectionItem *move(ElementsCategory *, MoveElementsHandler *);
|
||||
|
||||
virtual bool isCollection() const { return(false); } ///< @return always false
|
||||
virtual bool isRootCategory() const { return(false); } ///< @return always false
|
||||
virtual bool isCategory() const { return(false); } ///< @return always false
|
||||
virtual bool isElement() const { return(true ); } ///< @return always true
|
||||
virtual ElementsCollection *toCollection();
|
||||
virtual ElementsCategory *toCategory();
|
||||
virtual ElementsCategory *toPureCategory();
|
||||
virtual ElementDefinition *toElement();
|
||||
virtual bool equals(ElementDefinition &);
|
||||
virtual bool removeContent();
|
||||
virtual QDateTime modificationTime() const = 0;
|
||||
void copy(MoveElementsDescription *);
|
||||
void move(MoveElementsDescription *);
|
||||
|
||||
// attributes
|
||||
private:
|
||||
ElementsCategory *parent_category_;
|
||||
ElementsCollection *parent_collection_;
|
||||
QUuid m_uuid;
|
||||
};
|
||||
#endif
|
||||
@@ -1,618 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementscategory.h"
|
||||
#include "elementscollection.h"
|
||||
#include "elementdefinition.h"
|
||||
#include "moveelementshandler.h"
|
||||
#include "moveelementsdescription.h"
|
||||
#include "qet.h"
|
||||
#include "qetproject.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
*/
|
||||
ElementsCategory::ElementsCategory(ElementsCategory *parent, ElementsCollection *collection) :
|
||||
ElementsCollectionItem(parent),
|
||||
parent_collection_(collection),
|
||||
parent_category_(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
ElementsCategory::~ElementsCategory() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return le projet auquel appartient cette categorie, si celle-ci
|
||||
appartient a une collection.
|
||||
*/
|
||||
QETProject *ElementsCategory::project() {
|
||||
if (parent_collection_) {
|
||||
return(parent_collection_ -> project());
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Ne fait rien ; le projet doit etre defini au niveau d'une collection
|
||||
*/
|
||||
void ElementsCategory::setProject(QETProject *) {
|
||||
}
|
||||
|
||||
/**
|
||||
@return le protocole utilise pour designer la collection a laquelle
|
||||
appartient cette categorie
|
||||
*/
|
||||
QString ElementsCategory::protocol() {
|
||||
// il n'est pas possible d'avoir un protocole sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
|
||||
return(parentCollection() -> protocol());
|
||||
}
|
||||
|
||||
/**
|
||||
Ne fait rien
|
||||
*/
|
||||
void ElementsCategory::setProtocol(const QString &) {
|
||||
}
|
||||
|
||||
/**
|
||||
@return la categorie parente de cette categorie, ou 0 si celle-ci n'en possede
|
||||
*/
|
||||
ElementsCategory *ElementsCategory::parentCategory() {
|
||||
return(parent_category_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la liste des categories parentes de cet item.
|
||||
Cette liste peut etre vide s'il s'agit d'une categorie racine
|
||||
*/
|
||||
QList<ElementsCategory *> ElementsCategory::parentCategories() {
|
||||
QList<ElementsCategory *> cat_list;
|
||||
if (ElementsCategory *par_cat = parentCategory()) {
|
||||
cat_list << par_cat -> parentCategories() << par_cat;
|
||||
}
|
||||
return(cat_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette categorie possede une categorie parente
|
||||
*/
|
||||
bool ElementsCategory::hasParentCategory() {
|
||||
return(parent_category_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la collection a laquelle appartient la categorie
|
||||
*/
|
||||
ElementsCollection *ElementsCategory::parentCollection() {
|
||||
return(parent_collection_);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la categorie appartient a une collection
|
||||
*/
|
||||
bool ElementsCategory::hasParentCollection() {
|
||||
return(parent_collection_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param other_item Un autre item
|
||||
@return true si other_item est parent (direct ou indirect) de cet item, false sinon
|
||||
*/
|
||||
bool ElementsCategory::isChildOf(ElementsCollectionItem *other_item) {
|
||||
// verifie si l'autre item n'est pas la collection a laquelle cette categorie appartient
|
||||
if (ElementsCollection *other_item_coll = other_item -> toCollection()) {
|
||||
if (other_item_coll == parentCollection()) {
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
// remonte les categories parentes pour voir si l'une d'entre elles correspond a cet autre item
|
||||
ElementsCategory *parent_cat = this;
|
||||
while ((parent_cat = parent_cat -> parentCategory())) {
|
||||
if (parent_cat == other_item) {
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
// arrive ici, l'autre item n'est pas parent de cet item
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin virtuel de la categorie, avec le protocole
|
||||
*/
|
||||
QString ElementsCategory::fullVirtualPath() {
|
||||
// il n'est pas possible d'avoir un chemin virtuel sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
|
||||
return(protocol() + "://" + virtualPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@return l'emplacement de la categorie
|
||||
*/
|
||||
ElementsLocation ElementsCategory::location() {
|
||||
return(ElementsLocation(fullVirtualPath(), project()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette categorie est la categorie racine de la collection
|
||||
a laquelle elle appartient, false sinon
|
||||
*/
|
||||
bool ElementsCategory::isRootCategory() const {
|
||||
// il faut appartenir a une collection pour etre categorie racine
|
||||
if (!parent_collection_) return(false);
|
||||
|
||||
return(this == parent_collection_ -> rootCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false
|
||||
*/
|
||||
bool ElementsCategory::isCollection() const {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours true
|
||||
*/
|
||||
bool ElementsCategory::isCategory() const {
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false
|
||||
*/
|
||||
bool ElementsCategory::isElement() const {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une categorie n'est pas une collection
|
||||
*/
|
||||
ElementsCollection *ElementsCategory::toCollection() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return un pointeur ElementsCategory * sur cette categorie
|
||||
*/
|
||||
ElementsCategory *ElementsCategory::toCategory() {
|
||||
return(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@return un pointeur ElementsCategory * sur cette categorie
|
||||
*/
|
||||
ElementsCategory *ElementsCategory::toPureCategory() {
|
||||
return(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une categorie n'est pas un element
|
||||
*/
|
||||
ElementDefinition *ElementsCategory::toElement() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@param target_category Categorie cible pour la copie ; cette categorie
|
||||
sera copiee en tant que sous-categorie de la categorie cible
|
||||
@param handler Gestionnaire d'erreurs a utiliser pour effectuer la copie
|
||||
Si handler vaut 0, les erreurs, problemes et questions sont purement et
|
||||
simplement ignores.
|
||||
@param deep_copy true pour copier recursivement le contenu (elements et
|
||||
sous-categories) de cette categorie, false sinon
|
||||
@return La copie de la categorie, ou 0 si le processus a echoue.
|
||||
*/
|
||||
ElementsCollectionItem *ElementsCategory::copy(ElementsCategory *target_category, MoveElementsHandler *handler, bool deep_copy) {
|
||||
if (!target_category) return(0);
|
||||
|
||||
// echec si le path name de cette categorie est vide
|
||||
QString cat_name(pathName());
|
||||
if (cat_name.isEmpty()) return(0);
|
||||
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription mvt_desc;
|
||||
mvt_desc.setDestinationParentCategory(target_category);
|
||||
// on tente une copie avec le meme nom interne
|
||||
mvt_desc.setOriginalDestinationInternalName(cat_name);
|
||||
mvt_desc.setFinalDestinationInternalName(cat_name);
|
||||
mvt_desc.setHandler(handler);
|
||||
mvt_desc.setRecursive(deep_copy);
|
||||
|
||||
// effectue le mouvement
|
||||
copy(&mvt_desc);
|
||||
return(mvt_desc.createdItem());
|
||||
}
|
||||
|
||||
/**
|
||||
Methode privee effectuant une copie de cette categorie a partir d'une
|
||||
description du mouvement
|
||||
*/
|
||||
void ElementsCategory::copy(MoveElementsDescription *mvt_desc) {
|
||||
// quelques pointeurs pour simplifier l'ecriture de la methode
|
||||
MoveElementsHandler *handler = mvt_desc -> handler();
|
||||
ElementsCategory *target_category = mvt_desc -> destinationParentCategory();
|
||||
|
||||
// verifie que la categorie parente cible est accessible en lecture
|
||||
if (!target_category -> isReadable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
QET::Action todo = handler -> categoryIsNotReadable(target_category);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!target_category -> isReadable());
|
||||
}
|
||||
}
|
||||
|
||||
// verifie que la source et la destination ne sont pas identiques
|
||||
if (target_category == this || target_category -> isChildOf(this)) {
|
||||
if (handler) {
|
||||
handler -> errorWithACategory(this, tr("La copie d'une catégorie vers elle-même ou vers l'une de ses sous-catégories n\'est pas gérée."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// verifie que la categorie parente cible est accessible en ecriture
|
||||
if (!target_category -> isWritable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
QET::Action todo = handler -> categoryIsNotWritable(target_category);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!target_category -> isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
ElementsCategory *category_copy = 0;
|
||||
|
||||
// verifie que la cible n'existe pas deja
|
||||
if ((category_copy = target_category -> category(mvt_desc -> finalDestinationInternalName()))) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
// la cible existe deja : on demande au Handler ce qu'on doit faire
|
||||
QET::Action todo = handler -> categoryAlreadyExists(this, category_copy);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Erase) {
|
||||
break;
|
||||
} else if (todo == QET::Rename) {
|
||||
mvt_desc -> setFinalDestinationInternalName(handler -> nameForRenamingOperation());
|
||||
}
|
||||
} while ((category_copy = target_category -> category(mvt_desc -> finalDestinationInternalName())));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A ce stade, on peut creer la categorie cible : soit elle n'existe pas,
|
||||
soit on a l'autorisation de l'ecraser
|
||||
*/
|
||||
|
||||
// si la cible existe deja, verifie qu'elle est accessible en ecriture
|
||||
category_copy = target_category -> category(mvt_desc -> finalDestinationInternalName());
|
||||
if (category_copy && !category_copy -> isWritable()) {
|
||||
if (!handler) {
|
||||
return;
|
||||
} else {
|
||||
do {
|
||||
// la cible n'est pas accessible en ecriture : on demande au Handler ce qu'on doit faire
|
||||
QET::Action todo = handler -> categoryIsNotWritable(category_copy);
|
||||
|
||||
// on agit en fonction de la reponse du handler
|
||||
if (todo == QET::Abort) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
} else if (todo == QET::Ignore || todo == QET::Managed) {
|
||||
return;
|
||||
} else if (todo == QET::Retry || todo == QET::Erase) {
|
||||
// reessayer = repasser dans la boucle
|
||||
} else if (todo == QET::Rename) {
|
||||
// cas non gere
|
||||
}
|
||||
} while (!category_copy -> isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
// memorise la liste des sous-categories et elements directs
|
||||
QList<ElementsCategory *> categories_list = categories();
|
||||
QList<ElementDefinition *> elements_list = elements();
|
||||
|
||||
// cree la categorie cible
|
||||
category_copy = target_category -> createCategory(mvt_desc -> finalDestinationInternalName());
|
||||
if (!category_copy) {
|
||||
/// @todo la creation a echoue : gerer ce cas
|
||||
return;
|
||||
}
|
||||
|
||||
// recopie les noms de la categorie
|
||||
category_copy -> category_names = category_names;
|
||||
category_copy -> write();
|
||||
mvt_desc -> setCreatedItem(category_copy);
|
||||
|
||||
// copie recursive
|
||||
if (mvt_desc -> isRecursive()) {
|
||||
// copie les sous-categories
|
||||
foreach(ElementsCategory *sub_category, categories_list) {
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription sub_category_mvt_desc;
|
||||
sub_category_mvt_desc.setDestinationParentCategory(category_copy);
|
||||
// on tente une copie avec le meme nom interne
|
||||
sub_category_mvt_desc.setOriginalDestinationInternalName(sub_category -> pathName());
|
||||
sub_category_mvt_desc.setFinalDestinationInternalName(sub_category -> pathName());
|
||||
sub_category_mvt_desc.setHandler(handler);
|
||||
sub_category_mvt_desc.setRecursive(true);
|
||||
|
||||
// effectue la copie
|
||||
sub_category -> copy(&sub_category_mvt_desc);
|
||||
|
||||
// abort si besoin
|
||||
if (sub_category_mvt_desc.mustAbort()) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// copie les elements
|
||||
foreach(ElementDefinition *element, elements_list) {
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription element_mvt_desc;
|
||||
element_mvt_desc.setDestinationParentCategory(category_copy);
|
||||
// on tente une copie avec le meme nom interne
|
||||
element_mvt_desc.setOriginalDestinationInternalName(element -> pathName());
|
||||
element_mvt_desc.setFinalDestinationInternalName(element -> pathName());
|
||||
element_mvt_desc.setHandler(handler);
|
||||
|
||||
element -> copy(&element_mvt_desc);
|
||||
|
||||
// abort si besoin
|
||||
if (element_mvt_desc.mustAbort()) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cette methode copie la categorie recursivement puis la supprime, ce qui
|
||||
equivaut a un deplacement. Elle cree donc un nouvel objet representant la
|
||||
categorie, qu'elle retourne ensuite.
|
||||
@param target_category Categorie cible pour le deplacement ; cette categorie
|
||||
sera deplacee de faon a devenir une sous-categorie de la categorie cible
|
||||
@param handler Gestionnaire d'erreurs a utiliser pour effectuer le
|
||||
deplacement. Si handler vaut 0, les erreurs, problemes et questions sont
|
||||
purement et simplement ignores.
|
||||
@return Un pointeur vers la categorie apres le deplacement, ou 0 si le
|
||||
processus a echoue.
|
||||
*/
|
||||
ElementsCollectionItem *ElementsCategory::move(ElementsCategory *target_category, MoveElementsHandler *handler) {
|
||||
if (!target_category) return(0);
|
||||
|
||||
// echec si le path name de cette categorie est vide
|
||||
QString cat_name(pathName());
|
||||
if (cat_name.isEmpty()) return(0);
|
||||
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription mvt_desc;
|
||||
mvt_desc.setDestinationParentCategory(target_category);
|
||||
// on tente une copie avec le meme nom interne
|
||||
mvt_desc.setOriginalDestinationInternalName(cat_name);
|
||||
mvt_desc.setFinalDestinationInternalName(cat_name);
|
||||
mvt_desc.setHandler(handler);
|
||||
mvt_desc.setRecursive(true); // un deplacement est forcement recursif
|
||||
|
||||
// effectue le mouvement
|
||||
move(&mvt_desc);
|
||||
return(mvt_desc.createdItem());
|
||||
}
|
||||
|
||||
/**
|
||||
Methode privee effectuant le deplacement de cette categorie a partir d'une
|
||||
description du mouvement
|
||||
@param mvt_desc Description du mouvement
|
||||
*/
|
||||
void ElementsCategory::move(MoveElementsDescription *mvt_desc) {
|
||||
// quelques pointeurs pour simplifier l'ecriture de la methode
|
||||
MoveElementsHandler *handler = mvt_desc -> handler();
|
||||
ElementsCategory *target_category = mvt_desc -> destinationParentCategory();
|
||||
|
||||
// empeche le deplacement s'il s'agit d'une categorie racine
|
||||
if (isRootCategory()) {
|
||||
if (handler) handler -> errorWithACategory(this, tr("Il n'est pas possible de déplacer une collection."));
|
||||
return;
|
||||
}
|
||||
|
||||
// empeche le deplacement de la categorie dans une sous-categorie
|
||||
if (target_category == this || target_category -> isChildOf(this)) {
|
||||
if (handler) handler -> errorWithACategory(this, tr("Le déplacement d'une catégorie dans une de ses sous-catégories n'est pas possible."));
|
||||
return;
|
||||
}
|
||||
|
||||
// effectue une copie non recursive de cette categorie
|
||||
ElementsCollectionItem *item_copy = copy(target_category, handler, false);
|
||||
if (!item_copy) return;
|
||||
ElementsCategory *category_copy = item_copy -> toCategory();
|
||||
if (!category_copy) return;
|
||||
|
||||
// memorise la liste des sous-categories et elements directs
|
||||
QList<ElementsCategory *> categories_list = categories();
|
||||
QList<ElementDefinition *> elements_list = elements();
|
||||
|
||||
// booleen indiquant si on pourra tenter de supprimer la categorie apres la copie
|
||||
bool remove_category = true;
|
||||
|
||||
// tente de deplacer les sous-categories
|
||||
foreach(ElementsCategory *sub_category, categories_list) {
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription sub_category_mvt_desc;
|
||||
sub_category_mvt_desc.setDestinationParentCategory(category_copy);
|
||||
// on tente un deplacement avec le meme nom interne
|
||||
sub_category_mvt_desc.setOriginalDestinationInternalName(sub_category -> pathName());
|
||||
sub_category_mvt_desc.setFinalDestinationInternalName(sub_category -> pathName());
|
||||
sub_category_mvt_desc.setHandler(handler);
|
||||
sub_category_mvt_desc.setRecursive(true);
|
||||
|
||||
// effectue le deplacement
|
||||
sub_category -> move(&sub_category_mvt_desc);
|
||||
|
||||
// abort si besoin
|
||||
if (sub_category_mvt_desc.mustAbort()) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// si la sous-categorie n'a pas ete supprimee, on ne supprimera pas cette categorie
|
||||
if (remove_category) remove_category = sub_category_mvt_desc.sourceItemWasDeleted();
|
||||
|
||||
// si la sous-categorie n'a pas ete supprimee, ...
|
||||
if (!sub_category_mvt_desc.sourceItemWasDeleted()) {
|
||||
// on ne supprimera pas cette categorie
|
||||
if (remove_category) remove_category = false;
|
||||
}
|
||||
}
|
||||
|
||||
// tente de deplacer les elements
|
||||
foreach(ElementDefinition *element, elements_list) {
|
||||
// cree une description du mouvement a effectuer
|
||||
MoveElementsDescription element_mvt_desc;
|
||||
element_mvt_desc.setDestinationParentCategory(category_copy);
|
||||
// on tente une copie avec le meme nom interne
|
||||
element_mvt_desc.setOriginalDestinationInternalName(element -> pathName());
|
||||
element_mvt_desc.setFinalDestinationInternalName(element -> pathName());
|
||||
element_mvt_desc.setHandler(handler);
|
||||
|
||||
element -> move(&element_mvt_desc);
|
||||
|
||||
// abort si besoin
|
||||
if (element_mvt_desc.mustAbort()) {
|
||||
mvt_desc -> abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// si l'element n'a pas ete supprime, ...
|
||||
if (!element_mvt_desc.sourceItemWasDeleted()) {
|
||||
// on ne supprimera pas cette categorie
|
||||
if (remove_category) remove_category = false;
|
||||
}
|
||||
}
|
||||
|
||||
// supprime cette categorie (sinon il ne s'agirait que d'une copie, pas d'un deplacement)
|
||||
if (remove_category) {
|
||||
reload();
|
||||
bool category_deletion = remove();
|
||||
mvt_desc -> setSourceItemDeleted(category_deletion);
|
||||
if (!category_deletion && handler) {
|
||||
handler -> errorWithACategory(this, tr("La suppression de cette catégorie a échoué."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette collection est vide (pas de sous-categorie, pas
|
||||
d'element), false sinon.
|
||||
*/
|
||||
bool ElementsCategory::isEmpty() {
|
||||
return(categories().count() || elements().count());
|
||||
}
|
||||
|
||||
/**
|
||||
@return the count of categories and elements within this collection
|
||||
*/
|
||||
int ElementsCategory::count() {
|
||||
int items_count = elements().count();
|
||||
foreach(ElementsCategory *category, categories()) {
|
||||
items_count += category -> count();
|
||||
}
|
||||
return(items_count);
|
||||
}
|
||||
|
||||
/**
|
||||
Methode permettant d'obtenir le nom affichable de cette categorie.
|
||||
@return Le nom affichable de la categorie
|
||||
*/
|
||||
QString ElementsCategory::name() const {
|
||||
return(category_names.name(pathName()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return La liste des differents noms possibles pour la categorie
|
||||
*/
|
||||
NamesList ElementsCategory::categoryNames() const {
|
||||
return(category_names);
|
||||
}
|
||||
|
||||
/**
|
||||
Vide la liste des noms de la categorie
|
||||
*/
|
||||
void ElementsCategory::clearNames() {
|
||||
category_names.clearNames();
|
||||
}
|
||||
|
||||
/**
|
||||
Ajoute un nom a la categorie.
|
||||
Si la langue existe deja, le nom pour cette langue est remplace.
|
||||
@param lang La langue pour laquelle le nom est utilisable
|
||||
@param value Le nom
|
||||
*/
|
||||
void ElementsCategory::addName(const QString &lang, const QString &value) {
|
||||
category_names.addName(lang, value);
|
||||
}
|
||||
|
||||
/**
|
||||
Specifie les noms de la categorie.
|
||||
Tous les noms precedemment connus sont perdus
|
||||
*/
|
||||
void ElementsCategory::setNames(const NamesList &names_list) {
|
||||
category_names = names_list;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ELEMENTS_CATEGORY_H
|
||||
#define ELEMENTS_CATEGORY_H
|
||||
#include "elementscollectionitem.h"
|
||||
#include "nameslist.h"
|
||||
#include "elementslocation.h"
|
||||
class ElementDefinition;
|
||||
class ElementsCollection;
|
||||
class MoveElementsHandler;
|
||||
class MoveElementsDescription;
|
||||
/**
|
||||
This abstract class represents an elements category, i.e. a kind of
|
||||
subfolder within elements collections.
|
||||
*/
|
||||
class ElementsCategory : public ElementsCollectionItem {
|
||||
Q_OBJECT
|
||||
|
||||
// constructors, destructor
|
||||
public:
|
||||
ElementsCategory(ElementsCategory * = 0, ElementsCollection * = 0);
|
||||
virtual ~ElementsCategory();
|
||||
|
||||
private:
|
||||
ElementsCategory(const ElementsCategory &);
|
||||
|
||||
// Implementations of pure virtual methods from parent classes
|
||||
public:
|
||||
virtual QETProject *project();
|
||||
virtual void setProject(QETProject *);
|
||||
virtual QString protocol();
|
||||
virtual void setProtocol(const QString &);
|
||||
virtual ElementsCategory *parentCategory();
|
||||
virtual QList<ElementsCategory *> parentCategories();
|
||||
virtual bool hasParentCategory();
|
||||
virtual ElementsCollection *parentCollection();
|
||||
virtual bool hasParentCollection();
|
||||
virtual bool isChildOf(ElementsCollectionItem *);
|
||||
virtual QString fullVirtualPath();
|
||||
virtual ElementsLocation location();
|
||||
virtual bool isRootCategory() const;
|
||||
virtual bool isCollection() const;
|
||||
virtual bool isCategory() const;
|
||||
virtual bool isElement() const;
|
||||
virtual ElementsCollection *toCollection();
|
||||
virtual ElementsCategory *toCategory();
|
||||
virtual ElementsCategory *toPureCategory();
|
||||
virtual ElementDefinition *toElement();
|
||||
virtual ElementsCollectionItem *copy(ElementsCategory *, MoveElementsHandler *, bool = true);
|
||||
virtual ElementsCollectionItem *move(ElementsCategory *, MoveElementsHandler *);
|
||||
virtual bool isEmpty();
|
||||
virtual int count();
|
||||
|
||||
// Methods specific to the ElementsCategory class
|
||||
public:
|
||||
virtual QString name() const;
|
||||
virtual NamesList categoryNames() const;
|
||||
virtual void clearNames();
|
||||
virtual void addName(const QString &, const QString &);
|
||||
virtual void setNames(const NamesList &);
|
||||
void copy(MoveElementsDescription *);
|
||||
void move(MoveElementsDescription *);
|
||||
|
||||
// attributes
|
||||
protected:
|
||||
/// parent collection
|
||||
ElementsCollection *parent_collection_;
|
||||
/// parent category
|
||||
ElementsCategory *parent_category_;
|
||||
/// names list for this category
|
||||
NamesList category_names;
|
||||
};
|
||||
#endif
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementscollection.h"
|
||||
#include "elementscategory.h"
|
||||
#include "elementdefinition.h"
|
||||
#include "moveelementshandler.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param parent Item parent
|
||||
*/
|
||||
ElementsCollection::ElementsCollection(ElementsCollectionItem *parent) :
|
||||
ElementsCollectionItem(parent),
|
||||
cache_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
ElementsCollection::~ElementsCollection() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return the title for this collection
|
||||
*/
|
||||
QString ElementsCollection::title() const {
|
||||
return(title_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param title New title for this collection
|
||||
*/
|
||||
void ElementsCollection::setTitle(const QString &title) {
|
||||
if (title_ == title) return;
|
||||
title_ = title;
|
||||
emit(elementsCollectionChanged(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@return the icon for this collection
|
||||
*/
|
||||
QIcon ElementsCollection::icon() const {
|
||||
return(icon_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param icon the icon for this collection
|
||||
*/
|
||||
void ElementsCollection::setIcon(const QIcon &icon) {
|
||||
if (icon_.cacheKey() == icon.cacheKey()) return;
|
||||
icon_ = icon;
|
||||
emit(elementsCollectionChanged(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours true
|
||||
*/
|
||||
bool ElementsCollection::isCollection() const {
|
||||
return(true );
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false
|
||||
*/
|
||||
bool ElementsCollection::isRootCategory() const {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false
|
||||
*/
|
||||
bool ElementsCollection::isCategory() const {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false
|
||||
*/
|
||||
bool ElementsCollection::isElement() const {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return un pointeur ElementsCollection * sur cette collection
|
||||
*/
|
||||
ElementsCollection *ElementsCollection::toCollection() {
|
||||
return(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@return un pointeur vers la categorie racine de cette collection
|
||||
*/
|
||||
ElementsCategory *ElementsCollection::toCategory() {
|
||||
return(rootCategory());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une collection n'est pas a proprement parler une
|
||||
categorie
|
||||
*/
|
||||
ElementsCategory *ElementsCollection::toPureCategory() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une collection n'est pas un element
|
||||
*/
|
||||
ElementDefinition *ElementsCollection::toElement() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@param target_category Categorie cible pour la copie ; la categorie racine
|
||||
de cette collection sera copiee en tant que sous-categorie de la categorie
|
||||
cible
|
||||
@param handler Gestionnaire d'erreurs a utiliser pour effectuer la copie
|
||||
@param deep_copy true pour copier recursivement le contenu (elements et
|
||||
sous-categories) de la categorie racine, false sinon
|
||||
@return La copie de la categorie, ou 0 si le processus a echoue.
|
||||
*/
|
||||
ElementsCollectionItem *ElementsCollection::copy(ElementsCategory *target_category, MoveElementsHandler *handler, bool deep_copy) {
|
||||
if (ElementsCategory *root = rootCategory()) {
|
||||
return(root -> copy(target_category, handler, deep_copy));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Il n'est pas possible de deplacer une collection. Cette methode demande
|
||||
simplement au gestionnaire d'erreur handler d'afficher un message.
|
||||
*/
|
||||
ElementsCollectionItem *ElementsCollection::move(ElementsCategory *, MoveElementsHandler *handler) {
|
||||
if (ElementsCategory *root = rootCategory()) {
|
||||
if (handler) {
|
||||
handler -> errorWithACategory(root, tr("Il n'est pas possible de déplacer une collection."));
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Vide la collection de son contenu sans la supprimer
|
||||
@return true si l'operation a reussi, false sinon
|
||||
*/
|
||||
bool ElementsCollection::removeContent() {
|
||||
if (!rootCategory()) return(true);
|
||||
|
||||
// demande a la categorie racine de supprimer son contenu
|
||||
return(rootCategory() -> removeContent());
|
||||
}
|
||||
|
||||
/**
|
||||
Vide la collection de son contenu sans la supprimer
|
||||
@return true si l'operation a reussi, false sinon
|
||||
*/
|
||||
bool ElementsCollection::remove() {
|
||||
return(removeContent());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le projet auquel est rattachee cette collection ou 0 si
|
||||
celle-ci n'est pas liee a un projet.
|
||||
*/
|
||||
QETProject *ElementsCollection::project() {
|
||||
return(project_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param project le nouveau projet auquel est rattachee cette collection
|
||||
Indiquer 0 pour que cette collection ne soit plus liee a un projet.
|
||||
*/
|
||||
void ElementsCollection::setProject(QETProject *project) {
|
||||
project_ = project;
|
||||
}
|
||||
|
||||
/**
|
||||
@return le protocole utilise par cette collection ; exemples :
|
||||
"common" pour la collection commune qui utilise des URLs en common://
|
||||
"custom" pour la collection perso qui utilise des URLs en custom://
|
||||
"embed" pour une collection embarquee qui utilise des URLs en embed://
|
||||
*/
|
||||
QString ElementsCollection::protocol() {
|
||||
return(protocol_);
|
||||
}
|
||||
|
||||
/**
|
||||
Definit le protocole de cette collection
|
||||
@param p Nouveau protocole de cette collection
|
||||
*/
|
||||
void ElementsCollection::setProtocol(const QString &p) {
|
||||
if (!p.isEmpty()) protocol_ = p;
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une collection n'a pas de categorie parente. En
|
||||
revanche, elle peut posseder un projet parent.
|
||||
@see project()
|
||||
*/
|
||||
ElementsCategory *ElementsCollection::parentCategory() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours une liste vide - une collection n'a pas de categorie
|
||||
parente. En revanche, elle peut posseder un projet parent.
|
||||
@see project()
|
||||
*/
|
||||
QList<ElementsCategory *> ElementsCollection::parentCategories() {
|
||||
return(QList<ElementsCategory *>());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false0 - une collection n'a pas de categorie parente. En
|
||||
revanche, elle peut posseder un projet parent.
|
||||
@see project()
|
||||
*/
|
||||
bool ElementsCollection::hasParentCategory() {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours 0 - une collection n'a pas de collection parente. En
|
||||
revanche, elle peut posseder un projet parent.
|
||||
@see project()
|
||||
*/
|
||||
ElementsCollection *ElementsCollection::parentCollection() {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false - une collection n'a pas de collection parente. En
|
||||
revanche, elle peut posseder un projet parent.
|
||||
@see project()
|
||||
*/
|
||||
bool ElementsCollection::hasParentCollection() {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours false - une collection ne peut etre l'enfant de quoi que ce
|
||||
soit.
|
||||
*/
|
||||
bool ElementsCollection::isChildOf(ElementsCollectionItem *) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours une chaine vide
|
||||
*/
|
||||
QString ElementsCollection::pathName() const {
|
||||
return(QString());
|
||||
}
|
||||
|
||||
/**
|
||||
@return toujours une chaine vide
|
||||
*/
|
||||
QString ElementsCollection::virtualPath() {
|
||||
return(QString());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le protocole suivi de :// ou une chaine vide si cette collection
|
||||
n'a pas de protocole defini.
|
||||
*/
|
||||
QString ElementsCollection::fullVirtualPath() {
|
||||
if (protocol().isEmpty()) return(QString());
|
||||
return(protocol() + "://");
|
||||
}
|
||||
|
||||
/**
|
||||
@return l'emplacement de cette collection
|
||||
*/
|
||||
ElementsLocation ElementsCollection::location() {
|
||||
return(ElementsLocation(fullVirtualPath(), project()));
|
||||
}
|
||||
|
||||
/**
|
||||
@return une liste ne contenant que la categorie racine de la collection
|
||||
*/
|
||||
QList<ElementsCategory *> ElementsCollection::categories() {
|
||||
QList<ElementsCategory *> result;
|
||||
if (ElementsCategory *root = rootCategory()) {
|
||||
result << root;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@param cat_path chemin d'une categorie sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3
|
||||
@return la categorie demandee, ou 0 si celle-ci n'a pas ete trouvee
|
||||
*/
|
||||
ElementsCategory *ElementsCollection::category(const QString &cat_path) {
|
||||
ElementsCategory *root = rootCategory();
|
||||
// on doit avoir une categorie racine
|
||||
if (!root) return(0);
|
||||
|
||||
// le protocole de l'adresse virtuelle doit correspondre
|
||||
if (!cat_path.startsWith(protocol_ + "://", Qt::CaseInsensitive)) return(0);
|
||||
|
||||
// on enleve le protocole
|
||||
QString cat_path_(cat_path);
|
||||
cat_path_.remove(QRegExp("^" + protocol_ + ":\\/\\/", Qt::CaseInsensitive));
|
||||
|
||||
// on fait appel a la categorie racine pour le reste du traitement
|
||||
return(root -> category(cat_path_));
|
||||
}
|
||||
|
||||
/**
|
||||
Cree une categorie. La categorie parente doit exister.
|
||||
@param path chemin d'une categorie a creer sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3
|
||||
@return la nouvelle categorie demandee, ou 0 en cas d'echec
|
||||
*/
|
||||
ElementsCategory *ElementsCollection::createCategory(const QString &path) {
|
||||
ElementsCategory *root = rootCategory();
|
||||
// on doit avoir une categorie racine
|
||||
if (!root) return(0);
|
||||
|
||||
// on ne doit pas etre en lecture seule
|
||||
if (!isWritable()) return(0);
|
||||
|
||||
// le protocole de l'adresse virtuelle doit correspondre
|
||||
if (!path.startsWith(protocol_ + "://", Qt::CaseInsensitive)) return(0);
|
||||
|
||||
// on enleve le protocole
|
||||
QString path_(path);
|
||||
path_.remove(QRegExp("^" + protocol_ + ":\\/\\/", Qt::CaseInsensitive));
|
||||
|
||||
// on fait appel a la categorie racine pour le reste du traitement
|
||||
return(root -> createCategory(path_));
|
||||
}
|
||||
|
||||
/**
|
||||
@return une liste vide
|
||||
*/
|
||||
QList<ElementDefinition *> ElementsCollection::elements() {
|
||||
return(QList<ElementDefinition *>());
|
||||
}
|
||||
|
||||
/**
|
||||
@param elmt_path chemin d'un element sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3/dog.elmt
|
||||
@return l'element demande, ou 0 si celui-ci n'a pas ete trouve
|
||||
*/
|
||||
ElementDefinition *ElementsCollection::element(const QString &elmt_path) {
|
||||
ElementsCategory *root = rootCategory();
|
||||
// on doit avoir une categorie racine
|
||||
if (!root) return(0);
|
||||
|
||||
// le protocole de l'adresse virtuelle doit correspondre
|
||||
if (!elmt_path.startsWith(protocol_ + "://", Qt::CaseInsensitive)) return(0);
|
||||
|
||||
// on enleve le protocole
|
||||
QString elmt_path_(elmt_path);
|
||||
elmt_path_.remove(QRegExp("^" + protocol_ + ":\\/\\/", Qt::CaseInsensitive));
|
||||
|
||||
// on fait appel a la categorie racine pour le reste du traitement
|
||||
return(root -> element(elmt_path_));
|
||||
}
|
||||
|
||||
/**
|
||||
Cree un element. La categorie parente doit exister.
|
||||
@param path chemin d'un element a creer sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3/dog.elmt
|
||||
@return le nouvel element demande, ou 0 en cas d'echec
|
||||
*/
|
||||
ElementDefinition *ElementsCollection::createElement(const QString &path) {
|
||||
ElementsCategory *root = rootCategory();
|
||||
// on doit avoir une categorie racine
|
||||
if (!rootCategory()) return(0);
|
||||
|
||||
// on ne doit pas etre en lecture seule
|
||||
if (!isWritable()) return(0);
|
||||
|
||||
// le protocole de l'adresse virtuelle doit correspondre
|
||||
if (!path.startsWith(protocol_ + "://", Qt::CaseInsensitive)) return(0);
|
||||
|
||||
// on enleve le protocole
|
||||
QString path_(path);
|
||||
path_.remove(QRegExp("^" + protocol_ + ":\\/\\/", Qt::CaseInsensitive));
|
||||
|
||||
// on fait appel a la categorie racine pour le reste du traitement
|
||||
return(root -> createElement(path_));
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette collection est vide (pas de sous-categorie, pas
|
||||
d'element), false sinon.
|
||||
*/
|
||||
bool ElementsCollection::isEmpty() {
|
||||
ElementsCategory *root_category = rootCategory();
|
||||
if (!root_category) return(true);
|
||||
return(root_category -> isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@return the count of categories and elements within this collection
|
||||
*/
|
||||
int ElementsCollection::count() {
|
||||
ElementsCategory *root_category = rootCategory();
|
||||
if (!root_category) return(0);
|
||||
return(root_category -> count());
|
||||
}
|
||||
|
||||
/**
|
||||
@param item_path chemin d'un item sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3
|
||||
@param prefer_collections true pour renvoyer la collection lorsque le
|
||||
chemin correspond aussi bien a une collection qu'a sa categorie racine
|
||||
@return l'item demande, ou 0 si celui-ci n'a pas ete trouve
|
||||
*/
|
||||
ElementsCollectionItem *ElementsCollection::item(const QString &item_path, bool prefer_collections) {
|
||||
ElementsCollectionItem *result = 0;
|
||||
|
||||
// essaye de trouver l'item en tant que categorie
|
||||
result = category(item_path);
|
||||
// si la categorie est trouvee, ...
|
||||
if (result) {
|
||||
// ... qu'il s'agit d'une categorie racine et que l'utilisateur prefere les collections
|
||||
if (prefer_collections && result -> isRootCategory()) {
|
||||
// ... alors on renvoie la collection et non la categorie
|
||||
result = this;
|
||||
}
|
||||
}
|
||||
|
||||
// sinon essaye de trouver l'item en tant qu'element
|
||||
if (!result) result = element(item_path);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@return The cache used by this collection, or 0 if this collection does not have any
|
||||
*/
|
||||
ElementsCollectionCache *ElementsCollection::cache() const {
|
||||
return(cache_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param cache The cache to be used by this collection
|
||||
*/
|
||||
void ElementsCollection::setCache(ElementsCollectionCache *cache) {
|
||||
cache_ = cache;
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ELEMENTS_COLLECTION_H
|
||||
#define ELEMENTS_COLLECTION_H
|
||||
#include <QtCore>
|
||||
#include <QIcon>
|
||||
#include "elementscollectionitem.h"
|
||||
class QETProject;
|
||||
class ElementsCategory;
|
||||
class ElementsCollectionCache;
|
||||
class ElementDefinition;
|
||||
class MoveElementsHandler;
|
||||
/**
|
||||
This abstract class represents an elements collection. For instance, it may
|
||||
represent the collection provided along with QElectroTech, users custom
|
||||
collections or collections embedded within QET project files.
|
||||
*/
|
||||
class ElementsCollection : public ElementsCollectionItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// constructors, destructor
|
||||
ElementsCollection(ElementsCollectionItem * = 0);
|
||||
virtual ~ElementsCollection();
|
||||
|
||||
private:
|
||||
ElementsCollection(const ElementsCollection &);
|
||||
|
||||
// Implementations of pure virtual methodes from parent classes
|
||||
public:
|
||||
virtual QString title() const;
|
||||
virtual void setTitle(const QString &);
|
||||
virtual QIcon icon() const;
|
||||
virtual void setIcon(const QIcon &);
|
||||
virtual bool isCollection() const;
|
||||
virtual bool isRootCategory() const;
|
||||
virtual bool isCategory() const;
|
||||
virtual bool isElement() const;
|
||||
virtual ElementsCollection *toCollection();
|
||||
virtual ElementsCategory *toCategory();
|
||||
virtual ElementsCategory *toPureCategory();
|
||||
virtual ElementDefinition *toElement();
|
||||
virtual ElementsCollectionItem *copy(ElementsCategory *, MoveElementsHandler *, bool = true);
|
||||
virtual ElementsCollectionItem *move(ElementsCategory *, MoveElementsHandler *);
|
||||
virtual bool removeContent();
|
||||
virtual bool remove();
|
||||
virtual QETProject *project();
|
||||
virtual void setProject(QETProject *);
|
||||
virtual QString protocol();
|
||||
virtual void setProtocol(const QString &);
|
||||
virtual ElementsCategory *parentCategory();
|
||||
virtual QList<ElementsCategory *> parentCategories();
|
||||
virtual bool hasParentCategory();
|
||||
virtual ElementsCollection *parentCollection();
|
||||
virtual bool hasParentCollection();
|
||||
virtual bool isChildOf(ElementsCollectionItem *);
|
||||
virtual QString pathName() const;
|
||||
virtual QString virtualPath();
|
||||
virtual QString fullVirtualPath();
|
||||
virtual ElementsLocation location();
|
||||
virtual QList<ElementsCategory *> categories();
|
||||
virtual ElementsCategory *category(const QString &);
|
||||
virtual ElementsCategory *createCategory(const QString &);
|
||||
virtual QList<ElementDefinition *> elements();
|
||||
virtual ElementDefinition *element(const QString &);
|
||||
virtual ElementDefinition *createElement(const QString &);
|
||||
virtual bool isEmpty();
|
||||
virtual int count();
|
||||
|
||||
// Methods specific to the ElementsCollection class
|
||||
public:
|
||||
/**
|
||||
@return the root category of this collection
|
||||
*/
|
||||
virtual ElementsCategory *rootCategory() = 0;
|
||||
virtual ElementsCollectionItem *item(const QString &, bool = true);
|
||||
virtual bool isCacheable() const = 0;
|
||||
virtual ElementsCollectionCache *cache() const;
|
||||
virtual void setCache(ElementsCollectionCache *);
|
||||
|
||||
signals:
|
||||
void elementsCollectionChanged(ElementsCollection *);
|
||||
|
||||
// attributes
|
||||
protected:
|
||||
/// Title to be used when referring to this collection
|
||||
QString title_;
|
||||
/// Icon to be displayed when representing this collection
|
||||
QIcon icon_;
|
||||
/// "Protocol" used to access this collection
|
||||
QString protocol_;
|
||||
/// Project this collection belongs to, if any
|
||||
QETProject *project_;
|
||||
/// Optional cache used to improve performance
|
||||
ElementsCollectionCache *cache_;
|
||||
};
|
||||
#endif
|
||||
@@ -16,9 +16,6 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementscollectioncache.h"
|
||||
#include "elementscollection.h"
|
||||
#include "elementscategory.h"
|
||||
#include "elementdefinition.h"
|
||||
#include "factory/elementfactory.h"
|
||||
#include "element.h"
|
||||
#include "qet.h"
|
||||
@@ -151,73 +148,6 @@ QString ElementsCollectionCache::pixmapStorageFormat() const {
|
||||
return(pixmap_storage_format_);
|
||||
}
|
||||
|
||||
/**
|
||||
Indicate the cache a new collection is about to be browsed. This is mainly
|
||||
used to delimit database transactions.
|
||||
@param collection The elements collection about to be browsed.
|
||||
*/
|
||||
void ElementsCollectionCache::beginCollection(ElementsCollection *collection) {
|
||||
bool use_cache = cache_db_.isOpen() && collection -> isCacheable();
|
||||
if (use_cache) {
|
||||
bool transaction_started = cache_db_.transaction();
|
||||
qDebug() << (transaction_started ? "transaction began for " : "transaction not started for ") << collection -> protocol();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Indicate the cache the currently browsed collection end has been reached. This
|
||||
is mainly used to delimit database transactions.
|
||||
@param collection The elements collection being browsed.
|
||||
*/
|
||||
void ElementsCollectionCache::endCollection(ElementsCollection *collection) {
|
||||
bool use_cache = cache_db_.isOpen() && collection -> isCacheable();
|
||||
if (use_cache) {
|
||||
bool transaction_commited = cache_db_.commit();
|
||||
if (transaction_commited) {
|
||||
qDebug() << "transaction commited for " << collection -> protocol();
|
||||
} else {
|
||||
qDebug() << "transaction not commited for " << collection -> protocol() << ":" << cache_db_.lastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the data for a given element, using the cache if available,
|
||||
filling it otherwise. Data are then available through pixmap() and name()
|
||||
methods.
|
||||
@param element The definition of an element.
|
||||
@see pixmap()
|
||||
@see name()
|
||||
@return True if the retrieval succeeded, false otherwise.
|
||||
*/
|
||||
bool ElementsCollectionCache::fetchElement(ElementDefinition *element)
|
||||
{
|
||||
// can we use the cache with this element?
|
||||
bool use_cache = cache_db_.isOpen() && element -> parentCollection() -> isCacheable();
|
||||
|
||||
// attempt to fetch the element name from the cache database
|
||||
if (!use_cache)
|
||||
{
|
||||
return(fetchData(element -> location()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString element_path = element -> location().toString();
|
||||
bool got_name = fetchNameFromCache(element_path, element->uuid());
|
||||
bool got_pixmap = fetchPixmapFromCache(element_path, element->uuid());
|
||||
if (got_name && got_pixmap)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (fetchData(element -> location()))
|
||||
{
|
||||
cacheName(element_path, element->uuid());
|
||||
cachePixmap(element_path, element->uuid());
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementsCollectionCache::fetchElement
|
||||
* Retrieve the data for a given element, using the cache if available,
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
#include <QSqlDatabase>
|
||||
#include "elementslocation.h"
|
||||
|
||||
class ElementsCollection;
|
||||
class ElementsCategory;
|
||||
class ElementDefinition;
|
||||
/**
|
||||
This class implements a SQLite cache for data related to elements
|
||||
collections, mainly names and pixmaps. This avoids the cost of parsing XML
|
||||
@@ -43,9 +40,6 @@ class ElementsCollectionCache : public QObject
|
||||
QString locale() const;
|
||||
bool setPixmapStorageFormat(const QString &);
|
||||
QString pixmapStorageFormat() const;
|
||||
void beginCollection(ElementsCollection *);
|
||||
void endCollection(ElementsCollection *);
|
||||
bool fetchElement(ElementDefinition *);
|
||||
bool fetchElement(ElementsLocation &location);
|
||||
QString name() const;
|
||||
QPixmap pixmap() const;
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ELEMENTS_COLLECTION_ITEM_H
|
||||
#define ELEMENTS_COLLECTION_ITEM_H
|
||||
#include <QtCore>
|
||||
#include "elementslocation.h"
|
||||
class ElementsCollection;
|
||||
class ElementsCategory;
|
||||
class ElementDefinition;
|
||||
class MoveElementsHandler;
|
||||
/**
|
||||
This interface is the base class for all classes representing a part of an
|
||||
elements collection.
|
||||
*/
|
||||
class ElementsCollectionItem : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
// constructors, destructor
|
||||
public:
|
||||
ElementsCollectionItem(ElementsCollectionItem *parent = 0) : QObject(parent) {};
|
||||
virtual ~ElementsCollectionItem() {};
|
||||
|
||||
private:
|
||||
ElementsCollectionItem(const ElementsCollectionItem &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
/// @return whether the item is an elements collection
|
||||
virtual bool isCollection() const = 0;
|
||||
/// @return whether the item is an elements category
|
||||
virtual bool isCategory() const = 0;
|
||||
/// @return whether the item is the root category of a collection
|
||||
virtual bool isRootCategory() const = 0;
|
||||
/// @return whether the item is an element
|
||||
virtual bool isElement() const = 0;
|
||||
|
||||
/**
|
||||
@return a pointer to this item as a collection object, or 0 if this item is not a collection.
|
||||
*/
|
||||
virtual ElementsCollection *toCollection() = 0;
|
||||
/**
|
||||
@return a pointer to this item as a category object.
|
||||
If this item is a collection, return a valid pointer to its root category.
|
||||
If this item is a category, return a valid pointer.
|
||||
If this item is an element, return a valid pointer to its parent category.
|
||||
*/
|
||||
virtual ElementsCategory *toCategory() = 0;
|
||||
/**
|
||||
@return a pointer to this item as a category if and only if this object is a non-root elements category.
|
||||
If this item is a collection, return 0.
|
||||
If this item is a category, return a valid pointer.
|
||||
If this item is an element, return 0.
|
||||
*/
|
||||
virtual ElementsCategory *toPureCategory() = 0;
|
||||
/**
|
||||
@return a pointer to this item as an element object.
|
||||
*/
|
||||
virtual ElementDefinition *toElement() = 0;
|
||||
|
||||
/**
|
||||
Copy this item to the specified target, using a specific strategy to handle
|
||||
corner cases (errors, conflicts, confirmations, ...), recursively or not.
|
||||
*/
|
||||
virtual ElementsCollectionItem *copy(ElementsCategory *, MoveElementsHandler *, bool = true) = 0;
|
||||
|
||||
/**
|
||||
Move this item to the specified destination, using a specific strategy to
|
||||
handle corner cases (errors, conflicts, confirmations, ...).
|
||||
*/
|
||||
virtual ElementsCollectionItem *move(ElementsCategory *, MoveElementsHandler *) = 0;
|
||||
|
||||
/// Reload this item
|
||||
virtual void reload() = 0;
|
||||
/// @return whether the item really exists
|
||||
virtual bool exists() = 0;
|
||||
/// @return whether the item is readable
|
||||
virtual bool isReadable() = 0;
|
||||
/// @return whether the item is writable
|
||||
virtual bool isWritable() = 0;
|
||||
/**
|
||||
Delete the item content (elements and subcategories) without deleting the item itself.
|
||||
@return true if the operation succeeded, false otherwise
|
||||
*/
|
||||
virtual bool removeContent() = 0;
|
||||
/**
|
||||
Delete the item content (elements and categories) before deleting the item itself.
|
||||
@return true if the operation succeeded, false otherwise
|
||||
*/
|
||||
virtual bool remove() = 0;
|
||||
/**
|
||||
Save the item.
|
||||
@return true if the operation succeeded, false otherwise
|
||||
*/
|
||||
virtual bool write() = 0;
|
||||
/**
|
||||
@return the project this item belongs to
|
||||
*/
|
||||
virtual QETProject *project() = 0;
|
||||
/**
|
||||
Set the project this item belongs to.
|
||||
*/
|
||||
virtual void setProject(QETProject *) = 0;
|
||||
/**
|
||||
@return the protocol used to access the collection this item belongs to.
|
||||
*/
|
||||
virtual QString protocol() = 0;
|
||||
/**
|
||||
Set the protocol used to access the collection this item belongs to.
|
||||
*/
|
||||
virtual void setProtocol(const QString &) = 0;
|
||||
/**
|
||||
@return the parent category of this item, or 0 if it does not have any
|
||||
*/
|
||||
virtual ElementsCategory *parentCategory() = 0;
|
||||
/**
|
||||
@return the list of parent categories of this item
|
||||
*/
|
||||
virtual QList<ElementsCategory *> parentCategories() = 0;
|
||||
/**
|
||||
@return whether this item has a parent category
|
||||
*/
|
||||
virtual bool hasParentCategory() = 0;
|
||||
/**
|
||||
@return the parent collection of this item, or 0 if it does not have any
|
||||
*/
|
||||
virtual ElementsCollection *parentCollection() = 0;
|
||||
/**
|
||||
@return whether this item belongs to an elements collection
|
||||
*/
|
||||
virtual bool hasParentCollection() = 0;
|
||||
/**
|
||||
@param other_item other item
|
||||
@return whether \a other_item is a direct or indirect parent of this item.
|
||||
*/
|
||||
virtual bool isChildOf(ElementsCollectionItem *other_item) = 0;
|
||||
/**
|
||||
@return the name of this item within the elements tree.
|
||||
*/
|
||||
virtual QString pathName() const = 0;
|
||||
/**
|
||||
@return the virtual path to this item within the elements tree, protocol excluded.
|
||||
*/
|
||||
virtual QString virtualPath() = 0;
|
||||
/**
|
||||
@return the virtual path to this item within the elements tree, protocol included.
|
||||
*/
|
||||
virtual QString fullVirtualPath() = 0;
|
||||
/**
|
||||
@return the location of this item
|
||||
*/
|
||||
virtual ElementsLocation location() = 0;
|
||||
/**
|
||||
@return whether this item is stored somewhere on the filesystem.
|
||||
*/
|
||||
virtual bool hasFilePath() = 0;
|
||||
/**
|
||||
@return the path of this item within the filesystem
|
||||
*/
|
||||
virtual QString filePath() = 0;
|
||||
/**
|
||||
Set the path to this item within the filesystem.
|
||||
*/
|
||||
virtual void setFilePath(const QString &) = 0;
|
||||
/**
|
||||
@return the list of direct child elements category within this item
|
||||
*/
|
||||
virtual QList<ElementsCategory *> categories() = 0;
|
||||
/**
|
||||
@return the specified category, provided its virtual path
|
||||
*/
|
||||
virtual ElementsCategory *category(const QString &) = 0;
|
||||
/**
|
||||
@return a new category, created from the spcified virtual path
|
||||
*/
|
||||
virtual ElementsCategory *createCategory(const QString &) = 0;
|
||||
/**
|
||||
@return the list of child elements within this item
|
||||
*/
|
||||
virtual QList<ElementDefinition *> elements() = 0;
|
||||
/**
|
||||
@return an element, provided its virtual path
|
||||
*/
|
||||
virtual ElementDefinition *element(const QString &) = 0;
|
||||
/**
|
||||
@return a new element, created from the specified virtual path
|
||||
*/
|
||||
virtual ElementDefinition *createElement(const QString &) = 0;
|
||||
/**
|
||||
@return whether the item is empty
|
||||
*/
|
||||
virtual bool isEmpty() = 0;
|
||||
/**
|
||||
@return the count of categories and elements within this item
|
||||
*/
|
||||
virtual int count() = 0;
|
||||
};
|
||||
#endif
|
||||
@@ -16,7 +16,6 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementspanelwidget.h"
|
||||
#include "elementscollectionitem.h"
|
||||
#include "qetelementeditor.h"
|
||||
#include "elementscategoryeditor.h"
|
||||
#include "qetapp.h"
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "elementscollectioncache.h"
|
||||
#include "fileelementdefinition.h"
|
||||
#include "fileelementscategory.h"
|
||||
#include "fileelementscollection.h"
|
||||
#include "qetapp.h"
|
||||
#include "qet.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param uri Chemin du fichier contenant la definition de l'element
|
||||
@param category Categorie parente
|
||||
@param collection collection parente
|
||||
*/
|
||||
FileElementDefinition::FileElementDefinition(const QString &uri, FileElementsCategory *category, FileElementsCollection *collection) :
|
||||
ElementDefinition(category, collection),
|
||||
is_null(true),
|
||||
file_path(uri)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
FileElementDefinition::~FileElementDefinition() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return la definition XML de l'element
|
||||
*/
|
||||
QDomElement FileElementDefinition::xml() {
|
||||
// ouvre le fichier
|
||||
QFile file(file_path);
|
||||
|
||||
// charge le contenu du fichier en s'attendant a du XML
|
||||
is_null = !xml_element_.setContent(&file);
|
||||
if (is_null) {
|
||||
return(QDomElement());
|
||||
} else {
|
||||
// l'ouverture de la definition a reussi
|
||||
return(xml_element_.documentElement());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Change la definition XML de l'element
|
||||
@param xml_element Nouvelle definition XML de l'element
|
||||
@return true si l'operation s'est bien passee, false sinon
|
||||
*/
|
||||
bool FileElementDefinition::setXml(const QDomElement &xml_element) {
|
||||
xml_element_.clear();
|
||||
xml_element_.appendChild(xml_element_.importNode(xml_element, true));
|
||||
is_null = false;
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Enregistre la definition de l'element.
|
||||
@return true si l'operation a reussi, false sinon
|
||||
*/
|
||||
bool FileElementDefinition::write() {
|
||||
return(QET::writeXmlFile(xml_element_, file_path));
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la definition n'est pas disponible
|
||||
*/
|
||||
bool FileElementDefinition::isNull() const {
|
||||
return(is_null);
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le nom de cet element dans l'arborescence
|
||||
*/
|
||||
QString FileElementDefinition::pathName() const {
|
||||
return(QFileInfo(file_path).fileName());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin virtuel de cet element
|
||||
*/
|
||||
QString FileElementDefinition::virtualPath() {
|
||||
// il n'est pas possible d'avoir un chemin virtuel sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
// recupere le chemin absolu de la racine de la collection
|
||||
QString root_abs_path(parentCollection() -> filePath());
|
||||
|
||||
if (!file_path.startsWith(root_abs_path)) return(QString());
|
||||
QString virtual_path(file_path);
|
||||
virtual_path.remove(root_abs_path);
|
||||
virtual_path.remove(QRegExp("^/"));
|
||||
return(virtual_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileElementDefinition::reload
|
||||
* Reload this file element definition
|
||||
*/
|
||||
void FileElementDefinition::reload()
|
||||
{
|
||||
if (file_path.isEmpty())
|
||||
{
|
||||
is_null = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// recupere le chemin du fichier *.elmt correspondant
|
||||
QFileInfo file_info(file_path);
|
||||
if (!file_info.exists() || !file_info.isReadable())
|
||||
{
|
||||
is_null = true;
|
||||
return;
|
||||
}
|
||||
file_path = file_info.canonicalFilePath();
|
||||
|
||||
if (parentCollection())
|
||||
{
|
||||
ElementsCollectionCache *cache = parentCollection() -> cache();
|
||||
if (cache && cache -> fetchNameFromCache(location().toString(), uuid()))
|
||||
{
|
||||
// the element file has not been modified since the last time
|
||||
// we put its name in cache: we do not need to load it.
|
||||
is_null = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// we need to ensure this is a valid XML document
|
||||
QFile file(file_path);
|
||||
QDomDocument xml_document;
|
||||
is_null = !xml_document.setContent(&file);
|
||||
xml_document.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le fichier existe, false sinon
|
||||
*/
|
||||
bool FileElementDefinition::exists() {
|
||||
if (isNull()) return(false);
|
||||
return(QFileInfo(file_path).exists());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le fichier representant l'element est accessible en
|
||||
lecture.
|
||||
*/
|
||||
bool FileElementDefinition::isReadable() {
|
||||
if (isNull()) return(false);
|
||||
return(QFileInfo(file_path).isReadable());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le fichier representant l'element est accessible en
|
||||
ecriture.
|
||||
*/
|
||||
bool FileElementDefinition::isWritable() {
|
||||
if (isNull()) return(false);
|
||||
return(QFileInfo(file_path).isWritable());
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime le fichier representant l'element
|
||||
@return true si l'operation s'est bien passee, false sinon
|
||||
*/
|
||||
bool FileElementDefinition::remove() {
|
||||
QFile elmt_file(file_path);
|
||||
if (!elmt_file.exists()) return(true);
|
||||
return(elmt_file.remove());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cet element est represente quelque part sur le systeme de
|
||||
fichiers
|
||||
*/
|
||||
bool FileElementDefinition::hasFilePath() {
|
||||
return(!file_path.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le fichier representant cet element sur le systeme de fichiers
|
||||
*/
|
||||
QString FileElementDefinition::filePath() {
|
||||
return(file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
Definit le nouveau chemin de cet element dans le systeme de fichiers
|
||||
*/
|
||||
void FileElementDefinition::setFilePath(const QString &path) {
|
||||
// recupere le chemin du fichier *.elmt correspondant
|
||||
QFileInfo file_info(path);
|
||||
if (!file_info.exists() || !file_info.isReadable()) {
|
||||
return;
|
||||
}
|
||||
file_path = file_info.canonicalFilePath();
|
||||
}
|
||||
|
||||
/**
|
||||
@return the time of the last modification (mtime) for this element file
|
||||
*/
|
||||
QDateTime FileElementDefinition::modificationTime() const {
|
||||
QFileInfo file_info(file_path);
|
||||
if (!file_info.exists() || !file_info.isReadable()) {
|
||||
return QDateTime();
|
||||
}
|
||||
return(file_info.lastModified());
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef FILE_ELEMENT_DEFINITION
|
||||
#define FILE_ELEMENT_DEFINITION
|
||||
#include <QtCore>
|
||||
#include "elementdefinition.h"
|
||||
class FileElementsCategory;
|
||||
class FileElementsCollection;
|
||||
/**
|
||||
This class represents an element definition stored into a file.
|
||||
*/
|
||||
class FileElementDefinition : public ElementDefinition {
|
||||
public:
|
||||
FileElementDefinition(const QString &, FileElementsCategory * = 0, FileElementsCollection * = 0);
|
||||
virtual ~FileElementDefinition();
|
||||
|
||||
private:
|
||||
FileElementDefinition(const FileElementDefinition &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
virtual QDomElement xml();
|
||||
virtual bool setXml(const QDomElement &);
|
||||
virtual bool write();
|
||||
virtual bool isNull() const;
|
||||
virtual QString pathName() const;
|
||||
virtual QString virtualPath();
|
||||
virtual void reload();
|
||||
virtual bool exists();
|
||||
virtual bool isReadable();
|
||||
virtual bool isWritable();
|
||||
virtual bool remove();
|
||||
virtual bool hasFilePath();
|
||||
virtual QString filePath();
|
||||
virtual void setFilePath(const QString &);
|
||||
virtual QDateTime modificationTime() const;
|
||||
|
||||
// attributes
|
||||
private:
|
||||
bool is_null;
|
||||
QString file_path;
|
||||
QDomDocument xml_element_;
|
||||
};
|
||||
#endif
|
||||
@@ -1,484 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "fileelementscategory.h"
|
||||
#include "fileelementscollection.h"
|
||||
#include "fileelementdefinition.h"
|
||||
#include "qet.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param path Chemin du dossier de la categorie
|
||||
@param parent Categorie parente
|
||||
@param coll Collection parente
|
||||
*/
|
||||
FileElementsCategory::FileElementsCategory(const QString &path, FileElementsCategory *parent, FileElementsCollection *coll) :
|
||||
ElementsCategory(parent, coll),
|
||||
file_parent_collection_(coll),
|
||||
file_parent_category_(parent),
|
||||
cat_dir(path)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
FileElementsCategory::~FileElementsCategory() {
|
||||
deleteContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@return le nom de la categorie utilisable dans un chemin (virtuel ou reel)
|
||||
*/
|
||||
QString FileElementsCategory::pathName() const {
|
||||
return(cat_dir.dirName());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin virtuel de la categorie, sans le protocole
|
||||
*/
|
||||
QString FileElementsCategory::virtualPath() {
|
||||
|
||||
// il n'est pas possible d'avoir un chemin virtuel sans appartenir a une collection
|
||||
if (!hasParentCollection()) return(QString());
|
||||
|
||||
// recupere le chemin absolu de la racine de la collection
|
||||
QString root_abs_path(parentCollection() -> filePath());
|
||||
if (!filePath().startsWith(root_abs_path)) return(QString());
|
||||
|
||||
QString virtual_path(filePath());
|
||||
virtual_path.remove(root_abs_path);
|
||||
virtual_path.remove(QRegExp("^/"));
|
||||
return(virtual_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la categorie possede un chemin sur un systeme de fichiers
|
||||
*/
|
||||
bool FileElementsCategory::hasFilePath() {
|
||||
return(!filePath().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin sur le systeme de fichiers de la categorie
|
||||
*/
|
||||
QString FileElementsCategory::filePath() {
|
||||
return(cat_dir.path());
|
||||
}
|
||||
|
||||
/**
|
||||
Definit le chemin du dossier representant la categorie
|
||||
@param p nouveau chemin du dossier representant la categorie
|
||||
*/
|
||||
void FileElementsCategory::setFilePath(const QString &p) {
|
||||
cat_dir.setPath(p);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la liste des sous-categories de la categorie
|
||||
*/
|
||||
QList<ElementsCategory *> FileElementsCategory::categories() {
|
||||
QList<ElementsCategory *> result;
|
||||
|
||||
QList<QString> keys(categories_.keys());
|
||||
qSort(keys.begin(), keys.end());
|
||||
foreach(QString key, keys) result << categories_[key];
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@return la categorie correspondant au chemin virtuel cat_path, ou 0 en cas d'echec
|
||||
@param cat_path Chemin virtuel de la categorie voulue
|
||||
*/
|
||||
ElementsCategory *FileElementsCategory::category(const QString &cat_path) {
|
||||
// recupere les differentes parties du chemin
|
||||
QString cat_path_(cat_path);
|
||||
QStringList path_parts = cat_path_.split(QChar('/'), QString::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
|
||||
if (!path_parts.count()) {
|
||||
return(this);
|
||||
} else {
|
||||
// a-t-on la premiere sous-categorie ?
|
||||
if (!categories_.contains(path_parts.first())) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
// on a la premiere sous-categorie
|
||||
ElementsCategory *first_sub_cat = categories_.value(path_parts.first());
|
||||
|
||||
if (path_parts.count() == 1) return(first_sub_cat);
|
||||
|
||||
// on demande a la premiere sous-categorie de fournir la categorie finale
|
||||
path_parts.removeFirst();
|
||||
return(first_sub_cat -> category(path_parts.join("/")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cree une categorie. La categorie parente doit exister.
|
||||
@param path chemin d'une categorie a creer sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3
|
||||
@return la nouvelle categorie demandee, ou 0 en cas d'echec
|
||||
*/
|
||||
ElementsCategory *FileElementsCategory::createCategory(const QString &path) {
|
||||
// on ne doit pas etre en lecture seule
|
||||
if (!isWritable()) return(0);
|
||||
|
||||
// recupere les differentes parties du chemin
|
||||
QString cat_path_(path);
|
||||
QStringList path_parts = cat_path_.split(QChar('/'), QString::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
|
||||
if (!path_parts.count()) {
|
||||
// le chemin est vide, on renvoie 0
|
||||
return(0);
|
||||
} else if (path_parts.count() == 1) {
|
||||
// il n'y a plus qu'une categorie dans le chemin : il faut la creer ici
|
||||
|
||||
// on verifie si la categorie n'existe pas deja
|
||||
if (categories_.contains(path_parts[0])) {
|
||||
return(categories_.value(path_parts[0]));
|
||||
}
|
||||
|
||||
// on cree un objet
|
||||
FileElementsCategory *new_category = new FileElementsCategory(
|
||||
cat_dir.absolutePath() + "/" + path_parts[0],
|
||||
this,
|
||||
file_parent_collection_
|
||||
);
|
||||
|
||||
// on l'integre dans la liste des sous-categories connues
|
||||
categories_.insert(path_parts[0], new_category);
|
||||
|
||||
// on le renvoie
|
||||
return(new_category);
|
||||
} else {
|
||||
// il y a plusieurs categories dans le chemin :
|
||||
// on delegue le travail a la premiere sous-categorie
|
||||
|
||||
// a-t-on la premiere sous-categorie ?
|
||||
if (!categories_.contains(path_parts.first())) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
// on a la premiere sous-categorie
|
||||
ElementsCategory *first_sub_cat = categories_.value(path_parts.first());
|
||||
|
||||
// on demande a la premiere sous-categorie de fournir la categorie finale
|
||||
path_parts.removeFirst();
|
||||
return(first_sub_cat -> category(path_parts.join("/")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return la liste des elements de la categorie
|
||||
*/
|
||||
QList<ElementDefinition *> FileElementsCategory::elements() {
|
||||
QList<ElementDefinition *> result;
|
||||
|
||||
QList<QString> keys(elements_.keys());
|
||||
qSort(keys.begin(), keys.end());
|
||||
foreach(QString key, keys) result << elements_[key];
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@return l'element correspondant au chemin virtuel elmt_path, ou 0 en cas d'echec
|
||||
@param elmt_path Chemin virtuel de l'element voulu
|
||||
*/
|
||||
ElementDefinition *FileElementsCategory::element(const QString &elmt_path) {
|
||||
// recupere les differentes parties du chemin
|
||||
QString elmt_path_(elmt_path);
|
||||
QStringList path_parts = elmt_path_.split(QChar('/'), QString::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
|
||||
if (!path_parts.count()) {
|
||||
// chemin vide
|
||||
return(0);
|
||||
} else if (path_parts.count() == 1) {
|
||||
// seulement le nom de fichier
|
||||
QString element_filename = path_parts.takeLast();
|
||||
if (!elements_.contains(element_filename)) {
|
||||
return(0);
|
||||
} else {
|
||||
return(elements_.value(element_filename));
|
||||
}
|
||||
} else {
|
||||
// separe le nom de fichier du chemin de la categorie et recupere celle-ci
|
||||
QString element_filename = path_parts.takeLast();
|
||||
ElementsCategory *elmt_cat = category(path_parts.join("/"));
|
||||
if (!elmt_cat) {
|
||||
return(0);
|
||||
} else {
|
||||
return(elmt_cat -> element(element_filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cree un element. La categorie parente doit exister.
|
||||
@param path chemin d'un element a creer sous la forme d'une adresse
|
||||
virtuelle comme common://cat1/cat2/cat3/dog.elmt
|
||||
@return le nouvel element demande, ou 0 en cas d'echec
|
||||
*/
|
||||
ElementDefinition *FileElementsCategory::createElement(const QString &path) {
|
||||
// on ne doit pas etre en lecture seule
|
||||
if (!isWritable()) return(0);
|
||||
|
||||
// recupere les differentes parties du chemin
|
||||
QString cat_path_(path);
|
||||
QStringList path_parts = cat_path_.split(QChar('/'), QString::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
|
||||
if (!path_parts.count()) {
|
||||
// le chemin est vide, on renvoie 0
|
||||
return(0);
|
||||
} else if (path_parts.count() == 1) {
|
||||
// il n'y a plus que l'element dans le chemin : il faut le creer ici
|
||||
|
||||
// on verifie si l'element n'existe pas deja
|
||||
if (elements_.contains(path_parts[0])) {
|
||||
return(elements_.value(path_parts[0]));
|
||||
}
|
||||
|
||||
// on cree un objet
|
||||
FileElementDefinition *new_element = new FileElementDefinition(
|
||||
cat_dir.absolutePath() + "/" + path_parts[0],
|
||||
this,
|
||||
file_parent_collection_
|
||||
);
|
||||
|
||||
// on l'integre dans la liste des elements connus
|
||||
elements_.insert(path_parts[0], new_element);
|
||||
|
||||
// on le renvoie
|
||||
return(new_element);
|
||||
} else {
|
||||
// il y a plusieurs categories dans le chemin :
|
||||
// on delegue le travail a la premiere sous-categorie
|
||||
|
||||
// a-t-on la premiere sous-categorie ?
|
||||
if (!categories_.contains(path_parts.first())) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
// on a la premiere sous-categorie
|
||||
ElementsCategory *first_sub_cat = categories_.value(path_parts.first());
|
||||
|
||||
// on demande a la premiere sous-categorie de fournir la categorie finale
|
||||
path_parts.removeFirst();
|
||||
return(first_sub_cat -> createElement(path_parts.join("/")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le dossier representant la categorie existe
|
||||
*/
|
||||
bool FileElementsCategory::exists() {
|
||||
return(cat_dir.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la categorie est accessible en lecture
|
||||
Cett methode retourne true a partir du moment ou le dossier representant
|
||||
cette categorie est accessible en lecture. Il se peut que les elements ou
|
||||
le fichier qet_directory a l'interieur ne soient pas accessibles en
|
||||
ecriture.
|
||||
*/
|
||||
bool FileElementsCategory::isReadable() {
|
||||
return(QFileInfo(cat_dir.absolutePath()).isReadable());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il est possible d'ecrire le fichier qet_directory dans la
|
||||
categorie
|
||||
*/
|
||||
bool FileElementsCategory::isWritable() {
|
||||
// informations sur le dossier de la categorie
|
||||
QFileInfo category(cat_dir.absolutePath());
|
||||
QFileInfo qet_directory(cat_dir.absolutePath() + "/qet_directory");
|
||||
/*
|
||||
soit qet_directory n'existe pas et le dossier est accessible en ecriture,
|
||||
soit qet_directory existe et est accessible en ecriture
|
||||
*/
|
||||
return(
|
||||
category.isWritable() && // le dossier lui-meme est accessible en ecriture
|
||||
(
|
||||
!qet_directory.exists() ||
|
||||
(qet_directory.exists() && qet_directory.isWritable())
|
||||
) // le fichier qet_directory est accessible en ecriture
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Recharge le contenu et les noms de la categorie
|
||||
*/
|
||||
void FileElementsCategory::reload() {
|
||||
// supprime l'ancien contenu
|
||||
deleteContent();
|
||||
category_names.clearNames();
|
||||
|
||||
// la categorie doit exister
|
||||
if (!cat_dir.exists()) return;
|
||||
|
||||
// charge les noms de la categorie
|
||||
loadNames();
|
||||
|
||||
// charge les sous-categories
|
||||
QStringList dirs = cat_dir.entryList(QStringList(), QDir::AllDirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDir::Name);
|
||||
foreach(QString dir, dirs) {
|
||||
categories_.insert(dir, new FileElementsCategory(cat_dir.absoluteFilePath(dir), this, file_parent_collection_));
|
||||
}
|
||||
|
||||
// charge les elements
|
||||
QStringList elmts = cat_dir.entryList(QStringList("*.elmt"), QDir::Files, QDir::Name);
|
||||
foreach(QString elmt, elmts) {
|
||||
elements_.insert(elmt, new FileElementDefinition(cat_dir.absoluteFilePath(elmt), this, file_parent_collection_));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime le contenu de la categorie puis la categorie elle-meme
|
||||
@return true si l'operation s'est bien passee, false sinon
|
||||
*/
|
||||
bool FileElementsCategory::remove() {
|
||||
// suppression du contenu de la categorie
|
||||
if (!removeContent()) return(false);
|
||||
|
||||
// une categorie racine ne se supprime pas elle-meme
|
||||
if (isRootCategory()) return(true);
|
||||
|
||||
// suppression du fichier de description de la categorie
|
||||
if (cat_dir.exists("qet_directory")) {
|
||||
if (!cat_dir.remove("qet_directory")) return(false);
|
||||
}
|
||||
|
||||
// suppression de la categorie elle-meme
|
||||
return(cat_dir.rmdir(cat_dir.absolutePath()));
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime le contenu de la categorie sans supprimer la categorie elle-meme.
|
||||
@return true si l'operation s'est bien passee, false sinon
|
||||
*/
|
||||
bool FileElementsCategory::removeContent() {
|
||||
// suppression des sous-categories
|
||||
foreach(QString cat_name, categories_.keys()) {
|
||||
ElementsCategory *cat = categories_.value(cat_name);
|
||||
if (cat -> remove()) {
|
||||
categories_.take(cat_name);
|
||||
delete cat;
|
||||
} else {
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
// suppression des elements
|
||||
foreach(QString elmt_name, elements_.keys()) {
|
||||
ElementDefinition *elmt = elements_.value(elmt_name);
|
||||
if (elmt -> remove()) {
|
||||
elements_.take(elmt_name);
|
||||
delete elmt;
|
||||
} else {
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Cree la categorie
|
||||
@return true si la creation a reussi, false sinon
|
||||
*/
|
||||
bool FileElementsCategory::write() {
|
||||
// cree le dossier de la categorie
|
||||
if (!cat_dir.mkpath(cat_dir.path())) return(false);
|
||||
|
||||
// prepare la structure XML
|
||||
QDomDocument document;
|
||||
QDomElement root = document.createElement("qet-directory");
|
||||
document.appendChild(root);
|
||||
root.appendChild(category_names.toXml(document));
|
||||
|
||||
QString filepath = cat_dir.absolutePath() + "/qet_directory";
|
||||
return(QET::writeXmlFile(document, filepath));
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime un repertoire recursivement.
|
||||
@return true si la suppression a reussie, false sinon
|
||||
*/
|
||||
bool FileElementsCategory::rmdir(const QString &path) const {
|
||||
QDir directory(path);
|
||||
|
||||
// supprime les dossiers, recursivement
|
||||
foreach (QString file, directory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) {
|
||||
if (!rmdir(directory.absolutePath() + "/" + file)) return(false);
|
||||
}
|
||||
|
||||
// supprime les fichiers
|
||||
foreach (QString file, directory.entryList(QDir::Files | QDir::NoDotAndDotDot)) {
|
||||
if (!directory.remove(file)) return(false);
|
||||
}
|
||||
|
||||
// supprime le dossier lui-meme
|
||||
return(directory.rmdir(path));
|
||||
}
|
||||
|
||||
/**
|
||||
Charge la liste des noms possibles pour la categorie
|
||||
*/
|
||||
void FileElementsCategory::loadNames() {
|
||||
// repere le chemin du fichier de configuration de la categorie
|
||||
QFile directory_conf(cat_dir.absolutePath() + "/qet_directory");
|
||||
|
||||
// verifie l'existence du fichier
|
||||
if (!directory_conf.exists()) return;
|
||||
|
||||
// ouvre le fichier
|
||||
if (!directory_conf.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||
|
||||
// lit le contenu du fichier dans un QDomDocument XML
|
||||
QDomDocument document;
|
||||
if (!document.setContent(&directory_conf)) return;
|
||||
|
||||
// verifie la racine
|
||||
QDomElement root = document.documentElement();
|
||||
if (root.tagName() != "qet-directory") return;
|
||||
|
||||
category_names.fromXml(root);
|
||||
|
||||
// ferme le fichier
|
||||
directory_conf.close();
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime le contenu de la categorie en memoire
|
||||
*/
|
||||
void FileElementsCategory::deleteContent() {
|
||||
// suppression des elements
|
||||
foreach(QString elmt_name, elements_.keys()) {
|
||||
FileElementDefinition *elmt = elements_.take(elmt_name);
|
||||
delete elmt;
|
||||
}
|
||||
|
||||
// suppression des categories
|
||||
foreach(QString cat_name, categories_.keys()) {
|
||||
FileElementsCategory *cat = categories_.take(cat_name);
|
||||
delete cat;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef FILE_ELEMENTS_CATEGORY_H
|
||||
#define FILE_ELEMENTS_CATEGORY_H
|
||||
#include <QtCore>
|
||||
#include "elementscategory.h"
|
||||
class FileElementsCollection;
|
||||
class FileElementDefinition;
|
||||
/**
|
||||
This class represents an elements category stored on a filesystem.
|
||||
*/
|
||||
class FileElementsCategory : public ElementsCategory {
|
||||
Q_OBJECT
|
||||
|
||||
// constructors, destructor
|
||||
public:
|
||||
FileElementsCategory(const QString & = QString(), FileElementsCategory * = 0, FileElementsCollection * = 0);
|
||||
virtual ~FileElementsCategory();
|
||||
|
||||
private:
|
||||
FileElementsCategory(const FileElementsCategory &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
virtual QString pathName() const;
|
||||
virtual QString virtualPath();
|
||||
|
||||
virtual QString filePath();
|
||||
virtual bool hasFilePath();
|
||||
virtual void setFilePath(const QString &);
|
||||
|
||||
virtual QList<ElementsCategory *> categories();
|
||||
virtual ElementsCategory *category(const QString &);
|
||||
virtual ElementsCategory *createCategory(const QString &);
|
||||
|
||||
virtual QList<ElementDefinition *> elements();
|
||||
virtual ElementDefinition *element(const QString &);
|
||||
virtual ElementDefinition *createElement(const QString &);
|
||||
|
||||
virtual bool exists();
|
||||
virtual bool isReadable();
|
||||
virtual bool isWritable();
|
||||
|
||||
virtual void reload();
|
||||
virtual bool remove();
|
||||
virtual bool removeContent();
|
||||
virtual bool write();
|
||||
|
||||
private:
|
||||
bool rmdir(const QString &) const;
|
||||
void loadNames();
|
||||
void deleteContent();
|
||||
|
||||
// attributes
|
||||
protected:
|
||||
/// Parent collection, stored on filesystem too
|
||||
FileElementsCollection *file_parent_collection_;
|
||||
/// Paremt Collection, stored on filesystem too
|
||||
FileElementsCategory *file_parent_category_;
|
||||
/// Child sub-categories
|
||||
QHash<QString, FileElementsCategory *> categories_;
|
||||
/// Child elements
|
||||
QHash<QString, FileElementDefinition *> elements_;
|
||||
/// Directory matching this category on filesystem
|
||||
QDir cat_dir;
|
||||
};
|
||||
#endif
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "fileelementscollection.h"
|
||||
#include "fileelementscategory.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param path Chemin du dossier racine de la collection
|
||||
@param parent QObject parent de la collection
|
||||
*/
|
||||
FileElementsCollection::FileElementsCollection(const QString &path, ElementsCollectionItem *parent) :
|
||||
ElementsCollection(parent),
|
||||
coll_path(path)
|
||||
{
|
||||
protocol_ = "unknown";
|
||||
project_ = 0;
|
||||
root = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
FileElementsCollection::~FileElementsCollection() {
|
||||
deleteContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@return la categorie racine de la collection
|
||||
*/
|
||||
ElementsCategory *FileElementsCollection::rootCategory() {
|
||||
return(root);
|
||||
}
|
||||
|
||||
/**
|
||||
Recharge l'arborescence des categories et elements.
|
||||
*/
|
||||
void FileElementsCollection::reload() {
|
||||
QMutexLocker reload_lock(&reload_mutex_);
|
||||
// oublie l'arborescence precedente
|
||||
deleteContent();
|
||||
|
||||
// le dossier doit exister et etre lisible
|
||||
QDir coll_dir(coll_path);
|
||||
if (!coll_dir.exists() || !coll_dir.isReadable()) return;
|
||||
coll_path = coll_dir.canonicalPath();
|
||||
|
||||
root = new FileElementsCategory(coll_path, 0, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si cette collection est representee quelque part sur le
|
||||
systeme de fichiers.
|
||||
*/
|
||||
bool FileElementsCollection::hasFilePath() {
|
||||
return(!coll_path.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@return le chemin du repertoire representant cette collection
|
||||
*/
|
||||
QString FileElementsCollection::filePath() {
|
||||
return(coll_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@param path Nouveau chemin de la collection
|
||||
Cette methode ne recharge pas la collection
|
||||
*/
|
||||
void FileElementsCollection::setFilePath(const QString &path) {
|
||||
coll_path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
Supprime le contenu en memoire de cette collection
|
||||
*/
|
||||
void FileElementsCollection::deleteContent() {
|
||||
delete root;
|
||||
root = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@return ttrue si la categorie racine de la collection existe
|
||||
*/
|
||||
bool FileElementsCollection::exists() {
|
||||
return(root && root -> exists());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la collection est accessible en lecture
|
||||
*/
|
||||
bool FileElementsCollection::isReadable() {
|
||||
// une collection est accessible en lecture si sa categorie racine l'est
|
||||
return(root && root -> isReadable());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si la collection est accessible en ecriture
|
||||
*/
|
||||
bool FileElementsCollection::isWritable() {
|
||||
// une collection est accessible en ecriture si sa categorie racine l'est
|
||||
return(root && root -> isWritable());
|
||||
}
|
||||
|
||||
/**
|
||||
Ne fait rien
|
||||
@return toujours true
|
||||
*/
|
||||
bool FileElementsCollection::write() {
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@return always true, since a file-based elements collection can always be
|
||||
cached.
|
||||
*/
|
||||
bool FileElementsCollection::isCacheable() const {
|
||||
return(true);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef FILE_ELEMENTS_COLLECTION_H
|
||||
#define FILE_ELEMENTS_COLLECTION_H
|
||||
#include <QtCore>
|
||||
#include "elementscollection.h"
|
||||
class FileElementsCategory;
|
||||
/**
|
||||
This class represents an elements collection stored on filesystem, like the
|
||||
collection provided along with QET or users custom collection.
|
||||
*/
|
||||
class FileElementsCollection : public ElementsCollection {
|
||||
Q_OBJECT
|
||||
|
||||
// constructors, destructor
|
||||
public:
|
||||
FileElementsCollection(const QString &, ElementsCollectionItem *parent = 0);
|
||||
virtual ~FileElementsCollection();
|
||||
|
||||
private:
|
||||
FileElementsCollection(const FileElementsCollection &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
virtual void reload();
|
||||
virtual ElementsCategory *rootCategory();
|
||||
|
||||
virtual bool hasFilePath();
|
||||
virtual QString filePath();
|
||||
virtual void setFilePath(const QString &);
|
||||
virtual bool exists();
|
||||
virtual bool isReadable();
|
||||
virtual bool isWritable();
|
||||
virtual bool write();
|
||||
virtual bool isCacheable() const;
|
||||
|
||||
private:
|
||||
void deleteContent();
|
||||
|
||||
// attributes
|
||||
private:
|
||||
QString coll_path;
|
||||
FileElementsCategory *root;
|
||||
QMutex reload_mutex_; ///< Mutex used to avoid loading a collection twice at the same time
|
||||
};
|
||||
#endif
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "moveelementsdescription.h"
|
||||
|
||||
/**
|
||||
Constructeur - construit une description ne comprenant aucun nom internem,
|
||||
aucune destination, aucun handler. Par defaut, la recursivite est activee.
|
||||
@param parent QObject parent
|
||||
*/
|
||||
MoveElementsDescription::MoveElementsDescription(QObject *parent) :
|
||||
QObject(parent),
|
||||
recursive_(true),
|
||||
handler_(0),
|
||||
destination_(0),
|
||||
dest_internal_name_orig_(""),
|
||||
dest_internal_name_final_(""),
|
||||
created_item_(0),
|
||||
src_deleted_(false),
|
||||
abort_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
MoveElementsDescription::~MoveElementsDescription() {
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le mouvement decrit est recursif (c'est-a-dire que la copie
|
||||
d'une categorie entrainera la copie de ses sous-categories et de ses
|
||||
elements)
|
||||
*/
|
||||
bool MoveElementsDescription::isRecursive() const {
|
||||
return(recursive_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param r true pour activer la recursivite, false sinon
|
||||
@see isRecursive()
|
||||
*/
|
||||
void MoveElementsDescription::setRecursive(bool r) {
|
||||
recursive_ = r;
|
||||
}
|
||||
|
||||
/**
|
||||
@return le MoveElementsHandler utilise pour gerer les erreurs lors de la
|
||||
realisation de ce mouvement. Si aucun handler n'est specifie, cette methode
|
||||
retourne 0.
|
||||
@see MoveElementsHandler
|
||||
*/
|
||||
MoveElementsHandler *MoveElementsDescription::handler() const {
|
||||
return(handler_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param handler Le MoveElementHandler a utiliser pour gerer les erreurs lors
|
||||
de la realisation de ce mouvement. Indiquer 0 pour enlever le
|
||||
MoveElementsHandler.
|
||||
*/
|
||||
void MoveElementsDescription::setHandler(MoveElementsHandler *handler) {
|
||||
handler_ = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
@return la categorie de destination qui accueillera l'element cree par le
|
||||
mouvement.
|
||||
*/
|
||||
ElementsCategory *MoveElementsDescription::destinationParentCategory() const {
|
||||
return(destination_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param destination la categorie de destination qui accueillera l'element
|
||||
cree par le mouvement
|
||||
*/
|
||||
void MoveElementsDescription::setDestinationParentCategory(ElementsCategory *destination) {
|
||||
destination_ = destination;
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le nom interne souhaite pour l'item a creer.
|
||||
Typiquement, il s'agit du meme nom que l'item d'origine. Il faut toutefois
|
||||
le specifier explicitement.
|
||||
*/
|
||||
QString MoveElementsDescription::originalDestinationInternalName() const {
|
||||
return(dest_internal_name_orig_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param name Le nom interne souhaite pour l'item a creer.
|
||||
Typiquement, il s'agit du meme nom que l'item d'origine. Il faut toutefois
|
||||
le specifier explicitement.
|
||||
*/
|
||||
void MoveElementsDescription::setOriginalDestinationInternalName(const QString &name) {
|
||||
dest_internal_name_orig_ = name;
|
||||
}
|
||||
|
||||
/**
|
||||
@return Le nom interne finalement retenu pour creer l'item.
|
||||
Si le nom interne est deja pris dans la categorie de destination, il est
|
||||
courant de changer le nom interne de destination (cette decision revient
|
||||
typiquement au MoveElementsHandler).
|
||||
*/
|
||||
QString MoveElementsDescription::finalDestinationInternalName() const {
|
||||
return(dest_internal_name_final_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param name Le nom interne finalement retenu pour creer l'item.
|
||||
Si le nom interne est deja pris dans la categorie de destination, il est
|
||||
courant de changer le nom interne de destination (cette decision revient
|
||||
typiquement au MoveElementsHandler).
|
||||
*/
|
||||
void MoveElementsDescription::setFinalDestinationInternalName(const QString &name) {
|
||||
dest_internal_name_final_ = name;
|
||||
}
|
||||
|
||||
/**
|
||||
@return l'item cree par le mouvement, ou 0 si celui-ci n'as pas encore ete
|
||||
cree ou ne sera pas cree.
|
||||
*/
|
||||
ElementsCollectionItem *MoveElementsDescription::createdItem() const {
|
||||
return(created_item_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param item l'item cree par le mouvement. Indiquer 0 si celui-ci n'as pas
|
||||
encore ete cree ou ne sera pas cree.
|
||||
*/
|
||||
void MoveElementsDescription::setCreatedItem(ElementsCollectionItem *item) {
|
||||
created_item_ = item;
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si, dans le cadre normal du mouvement, l'item source a ete
|
||||
supprime (exemple : deplacement) avec succes.
|
||||
*/
|
||||
bool MoveElementsDescription::sourceItemWasDeleted() const {
|
||||
return(src_deleted_);
|
||||
}
|
||||
|
||||
/**
|
||||
@param deleted Definit si oui ou non l'item source a ete supprime avec
|
||||
succes, et ce dans le cadre normal du mouvement (exemple : deplacement).
|
||||
*/
|
||||
void MoveElementsDescription::setSourceItemDeleted(bool deleted) {
|
||||
src_deleted_ = deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
@return true si le mouvement, ainsi que les mouvements qui suivent, doivent
|
||||
etre annules.
|
||||
*/
|
||||
bool MoveElementsDescription::mustAbort() const {
|
||||
return(abort_);
|
||||
}
|
||||
|
||||
/**
|
||||
Definit ce mouvement ainsi que les mouvements qui suivent comme etant a
|
||||
annuler.
|
||||
*/
|
||||
void MoveElementsDescription::abort() {
|
||||
abort_ = true;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MOVE_ELEMENTS_DESCRIPTION_H
|
||||
#define MOVE_ELEMENTS_DESCRIPTION_H
|
||||
#include <QObject>
|
||||
class ElementsCollectionItem;
|
||||
class ElementsCategory;
|
||||
class MoveElementsHandler;
|
||||
/**
|
||||
This class describes the evolution of an elements item move (actually
|
||||
either move or copy), i.e. whether the source was deleted, whether the
|
||||
target changed and to what path, etc.
|
||||
*/
|
||||
class MoveElementsDescription : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
// constructors, destructor
|
||||
public:
|
||||
MoveElementsDescription(QObject * = 0);
|
||||
virtual ~MoveElementsDescription();
|
||||
private:
|
||||
MoveElementsDescription(const MoveElementsDescription &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
bool isRecursive() const;
|
||||
void setRecursive(bool);
|
||||
|
||||
MoveElementsHandler *handler() const;
|
||||
void setHandler(MoveElementsHandler *);
|
||||
|
||||
ElementsCategory *destinationParentCategory() const;
|
||||
void setDestinationParentCategory(ElementsCategory *);
|
||||
|
||||
QString originalDestinationInternalName() const;
|
||||
void setOriginalDestinationInternalName(const QString &);
|
||||
|
||||
QString finalDestinationInternalName() const;
|
||||
void setFinalDestinationInternalName(const QString &);
|
||||
|
||||
ElementsCollectionItem *createdItem() const;
|
||||
void setCreatedItem(ElementsCollectionItem *);
|
||||
|
||||
bool sourceItemWasDeleted() const;
|
||||
void setSourceItemDeleted(bool);
|
||||
|
||||
bool mustAbort() const;
|
||||
void abort();
|
||||
|
||||
// attributes
|
||||
private:
|
||||
bool recursive_;
|
||||
MoveElementsHandler *handler_;
|
||||
ElementsCategory *destination_;
|
||||
QString dest_internal_name_orig_;
|
||||
QString dest_internal_name_final_;
|
||||
ElementsCollectionItem *created_item_;
|
||||
bool src_deleted_;
|
||||
bool abort_;
|
||||
};
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MOVE_ELEMENTS_HANDLER_H
|
||||
#define MOVE_ELEMENTS_HANDLER_H
|
||||
#include <QObject>
|
||||
#include "qet.h"
|
||||
class ElementDefinition;
|
||||
class ElementsCategory;
|
||||
/**
|
||||
This class defines the minimum interface required to implement an object able
|
||||
to handle a move/copy operation among elements collections. This kind of
|
||||
objects is typically useful in the move() and copy() method of the
|
||||
ElementDefinition and ElementsCategory classes. These methods simply rely on
|
||||
answers provided by an instance of this class as soon as they encounter
|
||||
typical move/copy problems, such as conflicts or permission issues.
|
||||
|
||||
For instance, when copying a particular element to a given category, that
|
||||
element may already exist in the target category. It is then possible either
|
||||
to erase the target element, change the target name or cancel the operation.
|
||||
There is no systematic or calculable answer to this kind of questions, hence
|
||||
the rational to delegate the decision process to a dedicated "Strategy" object.
|
||||
|
||||
All we know from this object is the fact it implements the interface defined
|
||||
below. It is then free to create complicated dialogs to ask a user what to do
|
||||
or even to pick a random decision.
|
||||
|
||||
@see ElementsCategory
|
||||
@see ElementDefinition
|
||||
*/
|
||||
class MoveElementsHandler : public QObject {
|
||||
Q_OBJECT
|
||||
// constructors, destructor
|
||||
public:
|
||||
MoveElementsHandler(QObject * = 0) {};
|
||||
virtual ~MoveElementsHandler() {};
|
||||
private:
|
||||
MoveElementsHandler(const MoveElementsHandler &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
/**
|
||||
@return what to do if the target category already exists
|
||||
*/
|
||||
virtual QET::Action categoryAlreadyExists(ElementsCategory *src, ElementsCategory *dst) = 0;
|
||||
/**
|
||||
@return what to do if the target element already exists
|
||||
*/
|
||||
virtual QET::Action elementAlreadyExists(ElementDefinition *src, ElementDefinition *dst) = 0;
|
||||
|
||||
/**
|
||||
@return what to do if a category is not readable
|
||||
*/
|
||||
virtual QET::Action categoryIsNotReadable(ElementsCategory *) = 0;
|
||||
/**
|
||||
@return what to do if an element is not readable
|
||||
*/
|
||||
virtual QET::Action elementIsNotReadable(ElementDefinition *) = 0;
|
||||
|
||||
/**
|
||||
@return what to do if the target category is not writable
|
||||
*/
|
||||
virtual QET::Action categoryIsNotWritable(ElementsCategory *) = 0;
|
||||
/**
|
||||
@return what to do if the target element is not writable
|
||||
*/
|
||||
virtual QET::Action elementIsNotWritable(ElementDefinition *) = 0;
|
||||
|
||||
/**
|
||||
@return what to do when an error, described by the provided QString, occurs in relation with the given elements category.
|
||||
*/
|
||||
virtual QET::Action errorWithACategory(ElementsCategory *, const QString &) = 0;
|
||||
/**
|
||||
@return what to do when an error, described by the provided QString, occurs in relation with the given element.
|
||||
*/
|
||||
virtual QET::Action errorWithAnElement(ElementDefinition *, const QString &) = 0;
|
||||
|
||||
/**
|
||||
@return the name to be used along with the latest QET::Rename answer
|
||||
*/
|
||||
virtual QString nameForRenamingOperation() = 0;
|
||||
};
|
||||
#endif
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "diagram.h"
|
||||
#include "qetapp.h"
|
||||
#include "partline.h"
|
||||
#include "elementdefinition.h"
|
||||
#include <iostream>
|
||||
#include "terminal.h"
|
||||
#include "diagramposition.h"
|
||||
|
||||
Reference in New Issue
Block a user