diff --git a/sources/ElementsCollection/elementcollectionhandler.cpp b/sources/ElementsCollection/elementcollectionhandler.cpp index a2c67f3ff..719bdcf84 100644 --- a/sources/ElementsCollection/elementcollectionhandler.cpp +++ b/sources/ElementsCollection/elementcollectionhandler.cpp @@ -17,6 +17,8 @@ */ #include "elementcollectionhandler.h" #include "renamedialog.h" +#include "xmlelementcollection.h" +#include "qetxml.h" #include #include @@ -123,6 +125,42 @@ ElementLocation ECHSFileToFile::copyElement(ElementLocation &source, ElementLoca /******************************************************/ +/** + * @brief ECHSFileToXml::ECHSFileToXml + * @param source + * @param destination + */ +ECHSFileToXml::ECHSFileToXml(ElementLocation &source, ElementLocation &destination) : + ECHStrategy(source, destination) +{} + +/** + * @brief ECHSFileToXml::copy + * @return + */ +ElementLocation ECHSFileToXml::copy() +{ + if (!(m_source.isFileSystem() && m_destination.isDirectory() && m_destination.isProject())) return ElementLocation(); + + //Check if the destination already have an item with the same name of the item to copy + ElementLocation location(m_destination.projectCollectionPath() + "/" + m_source.fileName()); + + QString rename; + if (location.exist()) + { + RenameDialog rd(location.collectionPath()); + if(rd.exec() == QDialog::Accepted) + { + if (rd.selectedAction() == QET::Rename) + rename = rd.newName(); + } + else + return ElementLocation(); + } + + return m_destination.projectCollection()->copy(m_source, m_destination, rename); +} + /** * @brief ElementCollectionHandler::ElementCollectionHandler * @param widget @@ -148,6 +186,7 @@ ElementLocation ElementCollectionHandler::copy(ElementLocation &source, ElementL if (!source.exist() || !destination.exist() || destination.isElement()) return ElementLocation(); if (source.isFileSystem() && destination.isFileSystem()) m_strategy = new ECHSFileToFile(source, destination); + else if (source.isFileSystem() && destination.isProject()) m_strategy = new ECHSFileToXml(source, destination); if (m_strategy) return m_strategy->copy(); diff --git a/sources/ElementsCollection/elementcollectionhandler.h b/sources/ElementsCollection/elementcollectionhandler.h index e3cc75046..b4be91482 100644 --- a/sources/ElementsCollection/elementcollectionhandler.h +++ b/sources/ElementsCollection/elementcollectionhandler.h @@ -36,7 +36,6 @@ class ECHSFileToFile : public ECHStrategy { public: ECHSFileToFile (ElementLocation &source, ElementLocation &destination); - ElementLocation copy(); private: @@ -44,6 +43,13 @@ class ECHSFileToFile : public ECHStrategy ElementLocation copyElement(ElementLocation &source, ElementLocation &destination, QString rename = QString()); }; +class ECHSFileToXml : public ECHStrategy +{ + public: + ECHSFileToXml (ElementLocation &source, ElementLocation &destination); + ElementLocation copy(); +}; + /** * @brief The ElementCollectionHandler class * Provide several method to copy element or directory from a collection diff --git a/sources/ElementsCollection/elementlocation.cpp b/sources/ElementsCollection/elementlocation.cpp index 711e38590..ef9bbf06c 100644 --- a/sources/ElementsCollection/elementlocation.cpp +++ b/sources/ElementsCollection/elementlocation.cpp @@ -266,7 +266,7 @@ bool ElementLocation::isProject() const */ bool ElementLocation::exist() const { - if (isProject()) + if (m_project) return m_project->embeddedElementCollection()->exist(collectionPath(false)); else { @@ -282,6 +282,56 @@ bool ElementLocation::exist() const } } +/** + * @brief ElementLocation::projectCollection + * @return If this location represente a item in an embedded project collection, return this collection + * else return nullptr. + */ +XmlElementCollection *ElementLocation::projectCollection() const +{ + if (m_project) + return m_project->embeddedElementCollection(); + else + return nullptr; +} + +/** + * @brief ElementLocation::nameList + * @return the namelist of the represented element or directory. + * If namelist can't be set, return a empty namelist + */ +NamesList ElementLocation::nameList() +{ + NamesList nl; + + if (isElement()) + nl.fromXml(xml()); + + if (isDirectory()) + { + if (m_project) + nl.fromXml(m_project->embeddedElementCollection()->directory(collectionPath(false))); + else + { + //Open the qet_directory file, to get the traductions name of this dir + QFile dir_conf(fileSystemPath() + "/qet_directory"); + if (dir_conf.exists() && dir_conf.open(QIODevice::ReadOnly | QIODevice::Text)) + { + //Get the content of the file + QDomDocument document; + if (document.setContent(&dir_conf)) + { + QDomElement root = document.documentElement(); + if (root.tagName() == "qet-directory") + nl.fromXml(root); + } + } + } + } + + return nl; +} + /** * @brief ElementLocation::collectionPath * Return the path of the represented element relative to collection @@ -301,6 +351,19 @@ QString ElementLocation::collectionPath(bool protocol) const } } +/** + * @brief ElementLocation::projectCollectionPath + * @return The path is in form : project0+embed://dir/subdir/myElement.elmt + * If this item represent a file system thing, return a null QString; + */ +QString ElementLocation::projectCollectionPath() const +{ + if (isFileSystem()) + return QString(); + else + return QString("project" + QString::number(QETApp::projectId(m_project)) + "+" + collectionPath()); +} + /** * @brief ElementLocation::fileSystemPath * @return The file system path of this element, (the separator is always '/' see QDir::toNativeSeparators()) diff --git a/sources/ElementsCollection/elementlocation.h b/sources/ElementsCollection/elementlocation.h index c321ac64d..1babe7a05 100644 --- a/sources/ElementsCollection/elementlocation.h +++ b/sources/ElementsCollection/elementlocation.h @@ -18,6 +18,7 @@ #ifndef ELEMENTLOCATION_H #define ELEMENTLOCATION_H +#include "nameslist.h" #include #include #include @@ -25,6 +26,7 @@ class QETProject; class QMimeData; +class XmlElementCollection; /** * @brief The ElementLocation class @@ -49,8 +51,11 @@ class ElementLocation bool isFileSystem() const; bool isProject() const; bool exist() const; + XmlElementCollection *projectCollection() const; + NamesList nameList(); QString collectionPath(bool protocol = true) const; + QString projectCollectionPath() const; QString fileSystemPath() const; QETProject *project() const; diff --git a/sources/ElementsCollection/xmlelementcollection.cpp b/sources/ElementsCollection/xmlelementcollection.cpp index 809e3c491..72fa5ca3a 100644 --- a/sources/ElementsCollection/xmlelementcollection.cpp +++ b/sources/ElementsCollection/xmlelementcollection.cpp @@ -119,23 +119,43 @@ QDomElement XmlElementCollection::child(const QDomElement &parent_element, const if (parent_element.ownerDocument() != m_dom_document && parent_element.tagName() != "category") return QDomElement(); //Get all childs element of parent_element - QDomNodeList node_list; - if (child_name.endsWith(".elmt")) - node_list = parent_element.elementsByTagName("element"); - else - node_list = parent_element.elementsByTagName("category"); - - if (node_list.isEmpty()) return QDomElement(); - - for (int i=0 ; i found_dom_element; + for (int i=0 ; i #include @@ -38,13 +39,19 @@ class XmlElementCollection : public QObject QDomElement importCategory() const; QDomNodeList childs(const QDomElement &parent_element) const; QDomElement child(const QDomElement &parent_element, const QString &child_name) const; + QDomElement child(const QString &path) const; QList directories(const QDomElement &parent_element); QList elements(const QDomElement &parent_element); QDomElement element(const QString &path); QDomElement directory(const QString &path); QString addElement (const QString &path); + ElementLocation copy (ElementLocation &source, ElementLocation &destination, QString rename = QString(), bool deep_copy = true); bool exist (const QString &path); + private: + ElementLocation copyDirectory(ElementLocation &source, ElementLocation &destination, QString rename = QString(), bool deep_copy = true); + ElementLocation copyElement(ElementLocation &source, ElementLocation &destination, QString rename = QString()); + signals: /** * @brief elementAdded diff --git a/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp b/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp index ad8c5530f..a0bb89411 100644 --- a/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp +++ b/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp @@ -22,6 +22,7 @@ #include "nameslist.h" #include "qetapp.h" #include "elementlocation.h" +#include "elementcollectionhandler.h" #include /** @@ -119,6 +120,80 @@ QMimeData *XmlProjectElementCollectionItem::mimeData() return mime_data; } +/** + * @brief XmlProjectElementCollectionItem::canDropMimeData + * @param data + * @param action + * @param row + * @param column + * @return True if the data can be dropped + */ +bool XmlProjectElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const +{ + Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); + + if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri")) + { + //Return false if user try to drop a item from a folder to the same folder + ElementLocation drop_location(data->text()); + for (int i=0 ; i(child(i))->collectionPath() == drop_location.collectionPath()) + return false; + } + + return true; + } + else + return false; +} + +/** + * @brief XmlProjectElementCollectionItem::dropMimeData + * @param data + * @param action + * @param row + * @param column + * @return handle a drop of a mime data + */ +bool XmlProjectElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) +{ + Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); + + XmlProjectElementCollectionItem *xpeci = this; + if (isElement() && parent() && parent()->type() == XmlProjectElementCollectionItem::Type) + xpeci = static_cast(parent()); + + //before do the copy, we get all collection path of child, + //for remove it if the copied item have the same path of an existing child. + //We can't do this after the copy, because at the copy if the xml collection have a DomElement with the same path, + //he was removed before the new xml DomElement is inserted + //So the existing child of this will return a null QString when call collectionPath(), because the item + //doesn't exist anymore in the xml collection. + QList child_path_list; + for (int i=0 ; i(child(i))->collectionPath()); + + ElementCollectionHandler ech; + + ElementLocation source(data->text()); + ElementLocation destination(xpeci->collectionPath()); + ElementLocation location = ech.copy(source, destination); + + if (location.exist()) + { + //If this item have a child with the same path of location, we remove the existing child before insert new child + for (int i=0 ; i(m_parent_item); - if (parent->isCollectionRoot()) - return parent->collectionPath() + m_dom_element.attribute("name"); - else - return parent->collectionPath() + "/" + m_dom_element.attribute("name"); - } + ElementLocation loc (embeddedPath(), m_project); + return loc.projectCollectionPath(); } /** diff --git a/sources/ElementsCollection/xmlprojectelementcollectionitem.h b/sources/ElementsCollection/xmlprojectelementcollectionitem.h index f30e766c8..d6675fde7 100644 --- a/sources/ElementsCollection/xmlprojectelementcollectionitem.h +++ b/sources/ElementsCollection/xmlprojectelementcollectionitem.h @@ -43,6 +43,8 @@ class XmlProjectElementCollectionItem : public ElementCollectionItem virtual QVariant data(int column, int role); virtual QMimeData *mimeData(); + virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column); virtual Qt::ItemFlags flags(); virtual bool isCollectionRoot() const; diff --git a/sources/qetxml.cpp b/sources/qetxml.cpp index 246c223e7..e82258fd3 100644 --- a/sources/qetxml.cpp +++ b/sources/qetxml.cpp @@ -154,15 +154,17 @@ QBrush QETXML::brushFromXml(const QDomElement &element) * @brief QETXML::fileSystemDirToXmlCollectionDir * @param document : owner document of returned QDomElement, use to create the QDomElement. * @param dir : file system direcory to convert to QDomElement directory + * @param rename : by default the attribute "name" of the returned QDomElement is the same name of @dir + * but we can override itwith @rename * @return A file system directory converted to a QDomElement directory ready to be inserted into a XmlElementCollection. * If the QDomElement can't be created, return a null QDomElement. */ -QDomElement QETXML::fileSystemDirToXmlCollectionDir(QDomDocument &document, const QDir &dir) +QDomElement QETXML::fileSystemDirToXmlCollectionDir(QDomDocument &document, const QDir &dir, QString rename) { if (!dir.exists()) return QDomElement(); QDomElement dir_element = document.createElement("category"); - dir_element.setAttribute("name", dir.dirName()); + dir_element.setAttribute("name", rename.isNull()? dir.dirName() : rename); //Get the traduction of this directory QFile qet_dir(dir.filePath("qet_directory")); @@ -190,10 +192,12 @@ QDomElement QETXML::fileSystemDirToXmlCollectionDir(QDomDocument &document, cons * @brief QETXML::fileSystemElementToXmlCollectionElement * @param document : owner document of returned QDomElement, use to create the QDomElement. * @param file : file system element file to convert to QDomElement; + * @param rename : by default the attribute "name" of the returned QDomElement is the same name of @file + * but we can override itwith @rename * @return A file system element converted to a QDomElement ready to be inserted into a XmlElementCollection * If the QDomElement can't be created, return a null QDomElement */ -QDomElement QETXML::fileSystemElementToXmlCollectionElement(QDomDocument &document, QFile &file) +QDomElement QETXML::fileSystemElementToXmlCollectionElement(QDomDocument &document, QFile &file, QString rename) { if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -202,7 +206,7 @@ QDomElement QETXML::fileSystemElementToXmlCollectionElement(QDomDocument &docume { QFileInfo fi(file); QDomElement dom_element = document.createElement("element"); - dom_element.setAttribute("name", fi.fileName()); + dom_element.setAttribute("name", rename.isEmpty()? fi.fileName() : rename); dom_element.appendChild(docu.documentElement()); file.close(); return dom_element; diff --git a/sources/qetxml.h b/sources/qetxml.h index c609ac442..06cf38a92 100644 --- a/sources/qetxml.h +++ b/sources/qetxml.h @@ -36,8 +36,8 @@ namespace QETXML QDomElement brushToXml (QDomDocument &parent_document, QBrush brush); QBrush brushFromXml (const QDomElement &element); - QDomElement fileSystemDirToXmlCollectionDir (QDomDocument &document, const QDir &dir); - QDomElement fileSystemElementToXmlCollectionElement (QDomDocument &document, QFile &file); + QDomElement fileSystemDirToXmlCollectionDir (QDomDocument &document, const QDir &dir, QString rename = QString()); + QDomElement fileSystemElementToXmlCollectionElement (QDomDocument &document, QFile &file, QString rename = QString()); }