diff --git a/sources/ElementsCollection/elementcollectionhandler.cpp b/sources/ElementsCollection/elementcollectionhandler.cpp index 719bdcf84..b1248a038 100644 --- a/sources/ElementsCollection/elementcollectionhandler.cpp +++ b/sources/ElementsCollection/elementcollectionhandler.cpp @@ -125,22 +125,13 @@ ElementLocation ECHSFileToFile::copyElement(ElementLocation &source, ElementLoca /******************************************************/ -/** - * @brief ECHSFileToXml::ECHSFileToXml - * @param source - * @param destination - */ -ECHSFileToXml::ECHSFileToXml(ElementLocation &source, ElementLocation &destination) : +ECHSToXml::ECHSToXml(ElementLocation &source, ElementLocation &destination) : ECHStrategy(source, destination) {} -/** - * @brief ECHSFileToXml::copy - * @return - */ -ElementLocation ECHSFileToXml::copy() +ElementLocation ECHSToXml::copy() { - if (!(m_source.isFileSystem() && m_destination.isDirectory() && m_destination.isProject())) return ElementLocation(); + if (!(m_source.exist() && 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()); @@ -186,7 +177,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); + else if (destination.isProject()) m_strategy = new ECHSToXml(source, destination); if (m_strategy) return m_strategy->copy(); diff --git a/sources/ElementsCollection/elementcollectionhandler.h b/sources/ElementsCollection/elementcollectionhandler.h index b4be91482..2f2c50ec0 100644 --- a/sources/ElementsCollection/elementcollectionhandler.h +++ b/sources/ElementsCollection/elementcollectionhandler.h @@ -22,6 +22,10 @@ class QWidget; +/** + * @brief The ECHStrategy class + * Abstract class for manage copy of directory or element from a collection to another + */ class ECHStrategy { public: @@ -32,6 +36,11 @@ class ECHStrategy ElementLocation m_source, m_destination; }; +/** + * @brief The ECHSFileToFile class + * Manage the copy of directory or element from a file system collection to another file system collection + * (Work only if the source is the common collection and the destination is the custom collection) + */ class ECHSFileToFile : public ECHStrategy { public: @@ -43,10 +52,15 @@ class ECHSFileToFile : public ECHStrategy ElementLocation copyElement(ElementLocation &source, ElementLocation &destination, QString rename = QString()); }; -class ECHSFileToXml : public ECHStrategy +/** + * @brief The ECHSToXml class + * Manage the copy of a directory or element from a collection (no matter if the source is a file system collection or an xml collection) + * to an xml collection + */ +class ECHSToXml : public ECHStrategy { public: - ECHSFileToXml (ElementLocation &source, ElementLocation &destination); + ECHSToXml (ElementLocation &source, ElementLocation &destination); ElementLocation copy(); }; diff --git a/sources/ElementsCollection/elementlocation.cpp b/sources/ElementsCollection/elementlocation.cpp index ef9bbf06c..4327dd2c6 100644 --- a/sources/ElementsCollection/elementlocation.cpp +++ b/sources/ElementsCollection/elementlocation.cpp @@ -233,8 +233,9 @@ bool ElementLocation::isElement() const { * @brief ElementLocation::isDirectory * @return true if this location represent a directory */ -bool ElementLocation::isDirectory() const { - return !isElement(); +bool ElementLocation::isDirectory() const +{ + return (!isElement() && !m_collection_path.isEmpty()); } /** @@ -270,15 +271,17 @@ bool ElementLocation::exist() const return m_project->embeddedElementCollection()->exist(collectionPath(false)); else { + if (fileSystemPath().isEmpty()) return false; + if (isDirectory()) { QDir dir(fileSystemPath()); return dir.exists(); } - else - { + else if (isElement()) return QFile::exists(fileSystemPath()); - } + else + return false; } } diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp index 62a808a52..49a226db9 100644 --- a/sources/ElementsCollection/elementscollectionmodel.cpp +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -208,13 +208,22 @@ bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction ElementCollectionItem *eci = static_cast (parent.internalPointer()); if (!eci || eci->isElement()) return false; - connect(eci, &ElementCollectionItem::beginInsertRows, [this, &parent](ElementCollectionItem *eci, int first, int last){ Q_UNUSED(eci); this->beginInsertRows(parent, first, last); }); - connect(eci, &ElementCollectionItem::endInsertRows, [this, &parent](){ this->endInsertRows(); }); - connect(eci, &ElementCollectionItem::beginRemoveRows, [this, &parent](ElementCollectionItem *eci, int first, int last){ Q_UNUSED(eci); this->beginRemoveRows(parent, first, last); }); - connect(eci, &ElementCollectionItem::endRemoveRows, [this, &parent](){ this->endRemoveRows(); }); + m_parent_at_drop = parent; + + connect(eci, &ElementCollectionItem::beginInsertRows, this, &ElementsCollectionModel::bir); + connect(eci, &ElementCollectionItem::endInsertRows, this, &ElementsCollectionModel::endInsertRows); + connect(eci, &ElementCollectionItem::beginRemoveRows, this, &ElementsCollectionModel::brr); + connect(eci, &ElementCollectionItem::endRemoveRows, this, &ElementsCollectionModel::endRemoveRows); bool rb = eci->dropMimeData(data, action, row, column); + disconnect(eci, &ElementCollectionItem::beginInsertRows, this, &ElementsCollectionModel::bir); + disconnect(eci, &ElementCollectionItem::endInsertRows, this, &ElementsCollectionModel::endInsertRows); + disconnect(eci, &ElementCollectionItem::beginRemoveRows, this, &ElementsCollectionModel::brr); + disconnect(eci, &ElementCollectionItem::endRemoveRows, this, &ElementsCollectionModel::endRemoveRows); + + m_parent_at_drop = QModelIndex(); + return rb; } @@ -349,3 +358,17 @@ void ElementsCollectionModel::elementIntegratedToCollection(QETProject *project, eci->insertNewItem(collection_name); endInsertRows(); } + +void ElementsCollectionModel::bir(ElementCollectionItem *eci, int first, int last) +{ + Q_UNUSED(eci); + if (!m_parent_at_drop.isValid()) return; + beginInsertRows(m_parent_at_drop, first, last); +} + +void ElementsCollectionModel::brr(ElementCollectionItem *eci, int first, int last) +{ + Q_UNUSED(eci); + if (!m_parent_at_drop.isValid()) return; + beginRemoveRows(m_parent_at_drop, first, last); +} diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h index 3d8410ed0..2e2610e95 100644 --- a/sources/ElementsCollection/elementscollectionmodel.h +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -62,10 +62,14 @@ class ElementsCollectionModel : public QAbstractItemModel private: XmlProjectElementCollectionItem *itemForProject(QETProject *project); void elementIntegratedToCollection (QETProject *project, QString path); + //Use as slot in method drop mime data + void bir(ElementCollectionItem *eci, int first, int last); + void brr(ElementCollectionItem *eci, int first, int last); private: ElementCollectionItem *m_root_item; QList m_project_list; + QModelIndex m_parent_at_drop; }; #endif // ELEMENTSCOLLECTIONMODEL_H diff --git a/sources/ElementsCollection/xmlelementcollection.cpp b/sources/ElementsCollection/xmlelementcollection.cpp index 72fa5ca3a..3dc38aa9f 100644 --- a/sources/ElementsCollection/xmlelementcollection.cpp +++ b/sources/ElementsCollection/xmlelementcollection.cpp @@ -360,7 +360,7 @@ QString XmlElementCollection::addElement(const QString &path) */ ElementLocation XmlElementCollection::copy(ElementLocation &source, ElementLocation &destination, QString rename, bool deep_copy) { - if (!(source.isFileSystem() && destination.isDirectory() && destination.isProject() && destination.projectCollection() == this)) + if (!(source.exist() && destination.isDirectory() && destination.isProject() && destination.projectCollection() == this)) return ElementLocation(); if (source.isElement()) @@ -401,10 +401,6 @@ bool XmlElementCollection::exist(const QString &path) * @brief XmlElementCollection::copyDirectory * Copy the directory represented by source to destination. * if destination have a directory with the same name as source, then this directory is removed - * - * WARNING - * for now, only work if source is from files system - * * @param source : directory to copy * @param destination : destination of the copy * @param rename : rename the copy with @rename else use the name of source @@ -413,54 +409,75 @@ bool XmlElementCollection::exist(const QString &path) */ ElementLocation XmlElementCollection::copyDirectory(ElementLocation &source, ElementLocation &destination, QString rename, bool deep_copy) { - QDir source_dir(source.fileSystemPath()); - if (!source_dir.exists()) return ElementLocation(); + QString new_dir_name = rename.isEmpty() ? source.fileName() : rename; - QString new_dir_name = rename.isEmpty() ? source_dir.dirName() : rename; + //Get the xml directory where the new directory must be added + QDomElement parent_dir_dom = directory(destination.collectionPath(false)); + if (parent_dir_dom.isNull()) return ElementLocation(); //Remove the previous directory with the same path QDomElement element = child(destination.collectionPath(false) + "/" + new_dir_name); if (!element.isNull()) element.parentNode().removeChild(element); - QDir dir(source.fileSystemPath()); - QDomElement elmt_dom = QETXML::fileSystemDirToXmlCollectionDir(m_dom_document, dir, new_dir_name); - if (elmt_dom.isNull()) return ElementLocation(); - //Get the xml directory where the new directory must be added - QDomElement parent_dir_dom = directory(destination.collectionPath(false)); - if (parent_dir_dom.isNull()) return ElementLocation(); - parent_dir_dom.appendChild(elmt_dom); - ElementLocation created_location(destination.projectCollectionPath() + "/" + new_dir_name); + ElementLocation created_location; - if (deep_copy) + //Copy with a file system collection source + if (source.isFileSystem()) { - //Append all directories of source to the new created directory - foreach(QString str, source_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name)) - { - ElementLocation sub_source(source.fileSystemPath() + "/" + str); - copyDirectory(sub_source, created_location); - } + QDir source_dir(source.fileSystemPath()); + if (!source_dir.exists()) return ElementLocation(); - //Append all elements of source to the new created directory - source_dir.setNameFilters(QStringList() << "*.elmt"); - foreach(QString str, source_dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name)) + + QDir dir(source.fileSystemPath()); + QDomElement elmt_dom = QETXML::fileSystemDirToXmlCollectionDir(m_dom_document, dir, new_dir_name); + if (elmt_dom.isNull()) return ElementLocation(); + + parent_dir_dom.appendChild(elmt_dom); + + created_location.setPath(destination.projectCollectionPath() + "/" + new_dir_name); + + if (deep_copy) { - ElementLocation sub_source(source.fileSystemPath() + "/" + str); - copyElement(sub_source, created_location); + //Append all directories of source to the new created directory + foreach(QString str, source_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name)) + { + ElementLocation sub_source(source.fileSystemPath() + "/" + str); + copyDirectory(sub_source, created_location); + } + + //Append all elements of source to the new created directory + source_dir.setNameFilters(QStringList() << "*.elmt"); + foreach(QString str, source_dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name)) + { + ElementLocation sub_source(source.fileSystemPath() + "/" + str); + copyElement(sub_source, created_location); + } } } + //Copy with a xml collection source + else + { + if (!source.projectCollection()) return ElementLocation(); + + QDomNode other_collection_node = source.projectCollection()->child(source.collectionPath(false)).cloneNode(true); + if (other_collection_node.isNull()) return ElementLocation(); + + QDomElement other_collection_dom_dir = other_collection_node.toElement(); + other_collection_dom_dir.setAttribute("name", new_dir_name); + parent_dir_dom.appendChild(other_collection_dom_dir); + + created_location.setPath(destination.projectCollectionPath() + "/" + new_dir_name); + } + return created_location; } /** * @brief XmlElementCollection::copyElement - * - * WARNING - * for now, only work if source is from files system - * * @param source : element to copy * @param destination : destination of the copy * @param rename : rename the copy with @rename else use the name of source @@ -470,9 +487,24 @@ ElementLocation XmlElementCollection::copyElement(ElementLocation &source, Eleme { QString new_elmt_name = rename.isEmpty() ? source.fileName() : rename; - QFile file(source.fileSystemPath()); - QDomElement elmt_dom = QETXML::fileSystemElementToXmlCollectionElement(m_dom_document, file, new_elmt_name); - if (elmt_dom.isNull()) return ElementLocation(); + QDomElement elmt_dom; + + //Copy with a file system collection source + if (source.isFileSystem()) + { + QFile file(source.fileSystemPath()); + elmt_dom = QETXML::fileSystemElementToXmlCollectionElement(m_dom_document, file, new_elmt_name); + if (elmt_dom.isNull()) return ElementLocation(); + } + //Copy with a xml collection source + else + { + QDomElement other_collection = source.xml(); + elmt_dom = m_dom_document.createElement("element"); + elmt_dom.setAttribute("name", new_elmt_name); + elmt_dom.appendChild(other_collection.cloneNode()); + } + //Remove the previous element with the same path QDomElement element = child(destination.collectionPath(false) + "/" + new_elmt_name);