diff --git a/sources/ElementsCollection/elementcollectionitem.cpp b/sources/ElementsCollection/elementcollectionitem.cpp index 8f23f8082..db63306c4 100644 --- a/sources/ElementsCollection/elementcollectionitem.cpp +++ b/sources/ElementsCollection/elementcollectionitem.cpp @@ -163,3 +163,17 @@ bool ElementCollectionItem::isElement() const { bool ElementCollectionItem::isValid() const { return false; } + +/** + * @brief ElementCollectionItem::items + * @return all child and subchild subsubchild... contained by this item + * This item isn't stored in the list + */ +QList ElementCollectionItem::items() const +{ + QList list; + list.append(m_child_items); + foreach(ElementCollectionItem *eci, m_child_items) + list.append(eci->items()); + return list; +} diff --git a/sources/ElementsCollection/elementcollectionitem.h b/sources/ElementsCollection/elementcollectionitem.h index 066ee5731..de83410e1 100644 --- a/sources/ElementsCollection/elementcollectionitem.h +++ b/sources/ElementsCollection/elementcollectionitem.h @@ -55,6 +55,7 @@ class ElementCollectionItem virtual bool isDir() const; virtual bool isElement() const; virtual bool isValid() const; + virtual QList items() const; protected: ElementCollectionItem *m_parent_item; diff --git a/sources/ElementsCollection/elementlocation.cpp b/sources/ElementsCollection/elementlocation.cpp index 6628020a3..b38c1cf0a 100644 --- a/sources/ElementsCollection/elementlocation.cpp +++ b/sources/ElementsCollection/elementlocation.cpp @@ -1,19 +1,19 @@ /* - Copyright 2006-2015 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2015 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ #include "elementlocation.h" #include "qetapp.h" @@ -25,10 +25,10 @@ * @param path : path of item in file system */ ElementLocation::ElementLocation(QString path): - m_project(nullptr) + m_project(nullptr) { - if (!path.isEmpty()) - setPath(path); + if (!path.isEmpty()) + setPath(path); } /** @@ -37,10 +37,10 @@ ElementLocation::ElementLocation(QString path): * @param project : project */ ElementLocation::ElementLocation(QString path, QETProject *project) : - m_project(project) + m_project(project) { - if (!path.isEmpty()) - setPath(path); + if (!path.isEmpty()) + setPath(path); } ElementLocation::~ElementLocation() @@ -56,68 +56,100 @@ ElementLocation::~ElementLocation() */ bool ElementLocation::setPath(QString path) { - if (!path.endsWith(".elmt")) return false; + QString tmp_path = path; - QString tmp_path = path; + //The path is in file system + if (!m_project) + { + //The given path is relative to common or custom collection + if (path.startsWith("common://") || path.startsWith("custom://")) + { + QString p; + if (path.startsWith("common://")) + { + tmp_path.remove("common://"); + p = QETApp::commonElementsDir() + tmp_path; + } + else + { + tmp_path.remove("custom://"); + p = QETApp::customElementsDir() + tmp_path; + } - //The path is in file system - if (!m_project) - { - //Common collection - if (path.startsWith("common://")) - { - tmp_path.remove("common://"); - QString p = QETApp::commonElementsDir() + tmp_path; - QFile file(p); - if (file.exists()) - { - m_file_system_path = p; - m_collection_path = path; - return true; - } - - return false; - } - - //Custom collection - if (path.startsWith("custom://")) - { - tmp_path.remove("custom://"); - QString p = QETApp::customElementsDir() + tmp_path; - QFile file(p); - if (file.exists()) - { - m_file_system_path = p; - m_collection_path = path; - return true; - } - - return false; - } - //In this case, the path is supposed to be relative to the file system. - else - { - QFile file(path); - if (file.exists()) - { - m_file_system_path = path; - if (path.startsWith(QETApp::commonElementsDir())) - { - path.remove(QETApp::commonElementsDir()); - path.prepend("common://"); - m_collection_path = path; - } - else if (path.startsWith(QETApp::customElementsDir())) - { - path.remove(QETApp::customElementsDir()); - path.prepend("common://"); - m_collection_path = path; - } - return true; - } - return false; - } - } + //This is an element + if (path.endsWith(".elmt")) + { + QFile file(p); + if (file.exists()) + { + m_file_system_path = p; + m_collection_path = path; + return true; + } + return false; + } + //They must be a directory + else + { + QDir dir(p); + if(dir.exists()) + { + m_file_system_path = p; + m_collection_path = path; + return true; + } + return false; + } + } + //In this case, the path is supposed to be relative to the file system. + else + { + if(path.endsWith(".elmt")) + { + QFile file(path); + if (file.exists()) + { + m_file_system_path = path; + if (path.startsWith(QETApp::commonElementsDir())) + { + path.remove(QETApp::commonElementsDir()); + path.prepend("common://"); + m_collection_path = path; + } + else if (path.startsWith(QETApp::customElementsDir())) + { + path.remove(QETApp::customElementsDir()); + path.prepend("custom://"); + m_collection_path = path; + } + return true; + } + return false; + } + else + { + QDir dir(path); + if (dir.exists()) + { + m_file_system_path = path; + if (path.startsWith(QETApp::commonElementsDir())) + { + path.remove(QETApp::commonElementsDir()); + path.prepend("common://"); + m_collection_path = path; + } + else if (path.startsWith(QETApp::customElementsDir())) + { + path.remove(QETApp::customElementsDir()); + path.prepend("custom://"); + m_collection_path = path; + } + return true; + } + return false; + } + } + } return false; } @@ -136,38 +168,52 @@ bool ElementLocation::isNull() const */ void ElementLocation::setProject(QETProject *project) { - m_project = project; + m_project = project; +} + +/** + * @brief ElementLocation::isElement + * @return true if this location represent an element + */ +bool ElementLocation::isElement() const { + return m_collection_path.endsWith(".elmt"); +} + +/** + * @brief ElementLocation::isDirectory + * @return true if this location represent a directory + */ +bool ElementLocation::isDirectory() const { + return !isElement(); } /** * @brief ElementLocation::collectionPath * @return the colletion relative to the collection */ -QString ElementLocation::collectionPath() const -{ - return m_collection_path; +QString ElementLocation::collectionPath() const { + return m_collection_path; } /** * @brief ElementLocation::fileSystemPath - * @return The file system path of this element, + * @return The file system path of this element, (the separator is always '/' see QDir::toNativeSeparators()) * If this element is embedded in a project return an empty string; */ QString ElementLocation::fileSystemPath() const { - if (!m_project) - return QDir::fromNativeSeparators(m_file_system_path); - else - return QString(); + if (!m_project) + return m_file_system_path; + else + return QString(); } /** * @brief ElementLocation::project * @return the project of this location if he was set. */ -QETProject *ElementLocation::project() const -{ - return m_project; +QETProject *ElementLocation::project() const { + return m_project; } /** @@ -177,18 +223,18 @@ QETProject *ElementLocation::project() const */ QDomElement ElementLocation::xml() { - if (!m_xml.isNull()) - return m_xml; + if (!m_xml.isNull()) + return m_xml; - if (!m_project) - { - QFile file (m_file_system_path); - QDomDocument docu; - if (docu.setContent(&file)) - m_xml = docu.documentElement().cloneNode().toElement(); - } + if (!m_project) + { + QFile file (m_file_system_path); + QDomDocument docu; + if (docu.setContent(&file)) + m_xml = docu.documentElement().cloneNode().toElement(); + } - return m_xml; + return m_xml; } /** @@ -197,15 +243,13 @@ QDomElement ElementLocation::xml() */ QUuid ElementLocation::uuid() { - if (!m_uuid.isNull()) return m_uuid; + if (!m_uuid.isNull()) return m_uuid; - //Get the uuid of element - QList list_ = QET::findInDomElement(xml(), "uuid"); + //Get the uuid of element + QList list_ = QET::findInDomElement(xml(), "uuid"); - if (!list_.isEmpty()) - m_uuid = QUuid(list_.first().attribute("uuid")); -// else -// qDebug() << "The element : " << m_file_system_path << "haven't got an uuid, please edit and save this element with element editor to create an uuid"; + if (!list_.isEmpty()) + m_uuid = QUuid(list_.first().attribute("uuid")); return m_uuid; } diff --git a/sources/ElementsCollection/elementlocation.h b/sources/ElementsCollection/elementlocation.h index 2d5e8fad6..dbb72ea9f 100644 --- a/sources/ElementsCollection/elementlocation.h +++ b/sources/ElementsCollection/elementlocation.h @@ -27,7 +27,7 @@ class QETProject; /** * @brief The ElementLocation class - * This class represent the location of an element in the file system + * This class represent the location of an element or a directory in the file system * or an embedded collection of a project. * They also provide common things about an element, like the icon, uuid etc... */ @@ -41,6 +41,8 @@ class ElementLocation bool setPath(QString path); bool isNull() const; void setProject(QETProject *project); + bool isElement() const; + bool isDirectory() const; QString collectionPath() const; QString fileSystemPath() const; diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp index bc94166cb..f0282f8f7 100644 --- a/sources/ElementsCollection/elementscollectionmodel.cpp +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -197,10 +197,21 @@ bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction QStringList ElementsCollectionModel::mimeTypes() const { QStringList mime_list = QAbstractItemModel::mimeTypes(); - mime_list << "application/x-qet-element-uri"; + mime_list << "application/x-qet-element-uri" << "application/x-qet-category-uri"; return mime_list; } +/** + * @brief ElementsCollectionModel::items + * @return All items handled by this model. The root item isn't stored in the list + */ +QList ElementsCollectionModel::items() const +{ + QList list; + list.append(m_root_item->items()); + return list; +} + /** * @brief ElementsCollectionModel::addCommonCollection * Add the common elements collection to this model diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h index 3ce3fad57..305bd6701 100644 --- a/sources/ElementsCollection/elementscollectionmodel.h +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -46,6 +46,7 @@ class ElementsCollectionModel : public QAbstractItemModel virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); QStringList mimeTypes() const; + QList items() const; void addCommonCollection(); void addCustomCollection(); diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index c078a45a3..14011e388 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -40,11 +40,14 @@ */ ElementsCollectionWidget::ElementsCollectionWidget(QWidget *parent): QWidget(parent), + m_model(nullptr), m_item_at_context_menu(nullptr) { setUpWidget(); setUpAction(); setUpConnection(); + + reload(); } /** @@ -100,11 +103,11 @@ void ElementsCollectionWidget::setUpWidget() m_tree_view->setContextMenuPolicy(Qt::CustomContextMenu); m_main_vlayout->addWidget(m_tree_view); - //Setup the element collection model - m_model = new ElementsCollectionModel(m_tree_view); - m_model->addCommonCollection(); - m_model->addCustomCollection(); - m_tree_view->setModel(m_model); + //Setup the progress bar + m_progress_bar = new QProgressBar(this); + m_progress_bar->setFormat(tr("Chargement") + " %p%"); + m_main_vlayout->addWidget(m_progress_bar); + m_progress_bar->hide(); m_context_menu = new QMenu(this); } @@ -345,13 +348,25 @@ void ElementsCollectionWidget::newElement() */ void ElementsCollectionWidget::reload() { + m_progress_bar->show(); ElementsCollectionModel *new_model = new ElementsCollectionModel(m_tree_view); new_model->addCommonCollection(); new_model->addCustomCollection(); + + QList list = new_model->items(); + m_progress_bar->setMaximum(list.size()); + m_progress_bar->setValue(0); + foreach (ElementCollectionItem *item, new_model->items()) + { + item->name(); + m_progress_bar->setValue(m_progress_bar->value() + 1); + } + m_tree_view->setModel(new_model); - delete m_model; + if (m_model) delete m_model; m_model = new_model; expandFirstItems(); + m_progress_bar->hide(); } /** diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index 2c92aac8e..62ec66fd1 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -27,6 +27,7 @@ class QVBoxLayout; class QMenu; class QLineEdit; class ElementCollectionItem; +class QProgressBar; /** * @brief The ElementsCollectionWidget class @@ -69,6 +70,7 @@ class ElementsCollectionWidget : public QWidget QVBoxLayout *m_main_vlayout; QMenu *m_context_menu; ElementCollectionItem *m_item_at_context_menu; + QProgressBar *m_progress_bar; QAction *m_open_dir, *m_edit_element, diff --git a/sources/ElementsCollection/fileelementcollectionitem.cpp b/sources/ElementsCollection/fileelementcollectionitem.cpp index 241c186ce..9aa939e2c 100644 --- a/sources/ElementsCollection/fileelementcollectionitem.cpp +++ b/sources/ElementsCollection/fileelementcollectionitem.cpp @@ -53,10 +53,8 @@ bool FileElementCollectionItem::setRootPath(QString path) { m_path = path; populate(); - name(); return true; } - return false; } @@ -73,8 +71,10 @@ QString FileElementCollectionItem::fileSystemPath() const FileElementCollectionItem *parent = static_cast(m_parent_item); //Get the path of the parent. - QString path = parent->fileSystemPath(); - return path + "/" + m_path; + if (parent->isCollectionRoot()) + return parent->fileSystemPath() + m_path; + else + return parent->fileSystemPath() + "/" + m_path; } /** @@ -135,19 +135,7 @@ QVariant FileElementCollectionItem::data(int column, int role) switch (role) { - case Qt::DisplayRole: - { - //This item have no parent or parent isn't a file element, so it is the root of a collection - if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type) - { - if (m_path == QETApp::commonElementsDir()) - return QObject::tr("Collection QET"); - else if (m_path == QETApp::customElementsDir()) - return QObject::tr("Collection utilisateur"); - else - return QObject::tr("Collection inconnue"); - } - + case Qt::DisplayRole: { return name(); } break; @@ -193,7 +181,12 @@ QMimeData *FileElementCollectionItem::mimeData() { QMimeData *mime_data = new QMimeData(); mime_data->setText(collectionPath()); - mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1()); + + if (isElement()) + mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1()); + else + mime_data->setData("application/x-qet-category-uri", collectionPath().toLatin1()); + return mime_data; } @@ -207,9 +200,9 @@ QMimeData *FileElementCollectionItem::mimeData() bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const { Q_UNUSED(action); Q_UNUSED(column); + if (isCommonCollection()) return false; - if (data->hasFormat("application/x-qet-element-uri") && - fileSystemPath().startsWith(QETApp::customElementsDir())) + if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri")) return true; else return false; @@ -224,7 +217,18 @@ bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropA */ bool FileElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int column) { - Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column); + Q_UNUSED(action); Q_UNUSED(column); + if (isCommonCollection()) return false; + + FileElementCollectionItem *feci = this; + if (isElement() && parent() && parent()->type() == FileElementCollectionItem::Type) + feci = static_cast(parent()); + + if (data->hasFormat("application/x-qet-element-uri")) + return feci->handleElementDrop(data); + else if (data->hasFormat("application/x-qet-category-uri")) + return feci->handleDirectoryDrop(data); + return false; } @@ -303,27 +307,39 @@ QString FileElementCollectionItem::name() else if (isDir()) { - //Open the qet_directory file, to get the traductions name of this dir - QFile dir_conf(fileSystemPath() + "/qet_directory"); - if (!dir_conf.exists()) - m_name = QString(""); + if (isCollectionRoot()) + { + if (m_path == QETApp::commonElementsDir()) + m_name = QObject::tr("Collection QET"); + else if (m_path == QETApp::customElementsDir()) + m_name = QObject::tr("Collection utilisateur"); + else + m_name = QObject::tr("Collection inconnue"); + } + else + { + //Open the qet_directory file, to get the traductions name of this dir + QFile dir_conf(fileSystemPath() + "/qet_directory"); + if (!dir_conf.exists()) + m_name = QString(""); - if (!dir_conf.open(QIODevice::ReadOnly | QIODevice::Text)) - m_name = QString(""); + if (!dir_conf.open(QIODevice::ReadOnly | QIODevice::Text)) + m_name = QString(""); - //Get the content of the file - QDomDocument document; - if (!document.setContent(&dir_conf)) - m_name = QString(""); + //Get the content of the file + QDomDocument document; + if (!document.setContent(&dir_conf)) + m_name = QString(""); - QDomElement root = document.documentElement(); - if (root.tagName() != "qet-directory") - m_name = QString(""); + QDomElement root = document.documentElement(); + if (root.tagName() != "qet-directory") + m_name = QString(""); - //Return the name for the current langage. - NamesList nl; - nl.fromXml(root); - m_name = nl.name(); + //Return the name for the current langage. + NamesList nl; + nl.fromXml(root); + m_name = nl.name(); + } } else if (isElement()) { @@ -345,7 +361,6 @@ void FileElementCollectionItem::setPathName(QString path_name) if (!m_parent_item) return; m_path = path_name; - name(); //This isn't an element, we create the childs if (!path_name.endsWith(".elmt")) @@ -377,3 +392,64 @@ void FileElementCollectionItem::populate() appendChild(feci); } } + +/** + * @brief FileElementCollectionItem::handleElementDrop + * Handle a drop data that represente an element. + * @param data + * @return true if the data is successfully dropped + */ +bool FileElementCollectionItem::handleElementDrop(const QMimeData *data) +{ + ElementLocation location(data->text()); + return QFile::copy(location.fileSystemPath(), fileSystemPath() + "/" + location.fileSystemPath().split("/").last()); +} + +/** + * @brief FileElementCollectionItem::handleDirectoryDrop + * Handle a drop data that represent a directory + * @param data + * @return true if the data is successfully dropped + */ +bool FileElementCollectionItem::handleDirectoryDrop(const QMimeData *data) +{ + ElementLocation location(data->text()); + QDir origin_dir(location.fileSystemPath()); + + if (origin_dir.exists()) + return createSubDir(origin_dir, QDir(fileSystemPath())); + else + return false; +} + +/** + * @brief FileElementCollectionItem::createSubDir + * Copy the directory @ dir_to_copy and the qet_directory file to destination. + * Also copy all directorys and elements find in @dir_to_copy recursively + * @param dir_to_copy + * @param destination + * @return true if the copy of @dir_to_copy to destination is successfull. + */ +bool FileElementCollectionItem::createSubDir(QDir dir_to_copy, QDir destination) +{ + if (destination.mkdir(dir_to_copy.dirName())) + { + QDir created_dir(destination.canonicalPath() + "/" + dir_to_copy.dirName()); + + //Copy the qet_directory file + QFile::copy(dir_to_copy.canonicalPath() + "/qet_directory", created_dir.canonicalPath() +"/qet_directory"); + + //Copy all dirs found in dir_to_copy to destination + foreach(QString str, dir_to_copy.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name)) + createSubDir(QDir(dir_to_copy.canonicalPath() + "/" + str), created_dir); + + //Copy all elements found in dir_to_copy to destination + dir_to_copy.setNameFilters(QStringList() << "*.elmt"); + foreach(QString str, dir_to_copy.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name)) + QFile::copy(dir_to_copy.canonicalPath() + "/" + str, created_dir.canonicalPath() + "/" + str); + + return true; + } + else + return false; +} diff --git a/sources/ElementsCollection/fileelementcollectionitem.h b/sources/ElementsCollection/fileelementcollectionitem.h index 26704cfe6..c9f16b592 100644 --- a/sources/ElementsCollection/fileelementcollectionitem.h +++ b/sources/ElementsCollection/fileelementcollectionitem.h @@ -21,6 +21,7 @@ #include "elementcollectionitem.h" #include "elementlocation.h" #include +#include /** * @brief The FileElementCollectionItem class @@ -58,6 +59,9 @@ class FileElementCollectionItem : public ElementCollectionItem private: void setPathName(QString path_name); void populate(); + bool handleElementDrop (const QMimeData *data); + bool handleDirectoryDrop (const QMimeData *data); + bool createSubDir (QDir dir_to_copy, QDir destination); private: QString m_path;