diff --git a/qelectrotech.pro b/qelectrotech.pro index 6293215fb..f08b04886 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -78,7 +78,8 @@ INCLUDEPATH += sources \ sources/editor/esevent \ sources/editor/graphicspart \ sources/undocommand \ - sources/diagramevent + sources/diagramevent \ + sources/ElementsCollection # Fichiers sources @@ -89,7 +90,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) $$files(sources/editor/* $$files(sources/editor/graphicspart/*.h) \ $$files(sources/dvevent/*.h) \ $$files(sources/undocommand/*.h) \ - $$files(sources/diagramevent/*.h) + $$files(sources/diagramevent/*.h) \ + $$files(sources/ElementsCollection/*.h) SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/titleblock/*.cpp) $$files(sources/richtext/*.cpp) $$files(sources/ui/*.cpp) $$files(sources/qetgraphicsitem/*.cpp) $$files(sources/factory/*.cpp) \ $$files(sources/properties/*.cpp) \ @@ -98,7 +100,8 @@ SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/ $$files(sources/editor/graphicspart/*.cpp) \ $$files(sources/dvevent/*.cpp) \ $$files(sources/undocommand/*.cpp) \ - $$files(sources/diagramevent/*.cpp) + $$files(sources/diagramevent/*.cpp) \ + $$files(sources/ElementsCollection/*.cpp) # Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt RESOURCES += qelectrotech.qrc @@ -130,10 +133,6 @@ TARGET = qelectrotech unix:QMAKE_LIBS_THREAD -= -lpthread # Enable C++11 -macx { - LIBS += -stdlib=libc++ - QMAKE_CXXFLAGS += -stdlib=libc++ -} QMAKE_CXXFLAGS += -std=c++11 # Description de l'installation diff --git a/sources/ElementsCollection/elementcollectionitem.cpp b/sources/ElementsCollection/elementcollectionitem.cpp new file mode 100644 index 000000000..8f23f8082 --- /dev/null +++ b/sources/ElementsCollection/elementcollectionitem.cpp @@ -0,0 +1,165 @@ +/* + 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 distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "elementcollectionitem.h" +#include + +/** + * @brief ElementCollectionItem::ElementCollectionItem + * Constructor + * @param parent : the parent item of this item + */ +ElementCollectionItem::ElementCollectionItem(ElementCollectionItem *parent) : + m_parent_item (parent) +{} + +/** + * @brief ElementCollectionItem::~ElementCollectionItem + * Destructor + */ +ElementCollectionItem::~ElementCollectionItem() { + qDeleteAll(m_child_items); +} + +/** + * @brief ElementCollectionItem::appendChild + * Add @item to the child of this item + * @param item + */ +void ElementCollectionItem::appendChild(ElementCollectionItem *item) { + m_child_items << item; +} + +/** + * @brief ElementCollectionItem::child + * @param row + * @return The child at @row of this item. + * If there isn't child at @row, return default ElementCollectionItem + */ +ElementCollectionItem *ElementCollectionItem::child(int row) { + return m_child_items.value(row); +} + +/** + * @brief ElementCollectionItem::childCount + * @return the number of childs of this item + */ +int ElementCollectionItem::childCount() const { + return m_child_items.size(); +} + +/** + * @brief ElementCollectionItem::columnCount + * @return the number of columns (always 1) + */ +int ElementCollectionItem::columnCount() const { + return 1; +} + +/** + * @brief ElementCollectionItem::data + * @param column + * @param role + * @return the data at @column and @role. + */ +QVariant ElementCollectionItem::data(int column, int role) { + Q_UNUSED(column); + Q_UNUSED(role); + return QVariant(); +} + +/** + * @brief ElementCollectionItem::mimeData + * @return The mime data of this item + */ +QMimeData *ElementCollectionItem::mimeData() { + return new QMimeData(); +} + +bool ElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const +{ + Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column); + return false; +} + +bool ElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int column) +{ + Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column); + return false; +} + +/** + * @brief ElementCollectionItem::flags + * @return the flag of this item + */ +Qt::ItemFlags ElementCollectionItem::flags() { + return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); +} + +/** + * @brief ElementCollectionItem::parent + * @return parent item of this item. + * return nullptr if item haven't got parent + */ +ElementCollectionItem *ElementCollectionItem::parent() { + return m_parent_item; +} + +/** + * @brief ElementCollectionItem::row + * @return the index of this item, from his parent. + * If item haven't got parent return 0 + */ +int ElementCollectionItem::row() const +{ + if (m_parent_item) + return m_parent_item->m_child_items.indexOf(const_cast(this)); + else + return 0; +} + +/** + * @brief ElementCollectionItem::name + * @return the located name of this item + */ +QString ElementCollectionItem::name() { + return m_name; +} + +/** + * @brief ElementCollectionItem::isDir + * @return true if this item represent a directory + */ +bool ElementCollectionItem::isDir() const { + return false; +} + +/** + * @brief ElementCollectionItem::isElement + * @return true if this item represent a directory + */ +bool ElementCollectionItem::isElement() const { + return false; +} + +/** + * @brief ElementCollectionItem::isValid + * @return true if this item refer to an dir or an element. + */ +bool ElementCollectionItem::isValid() const { + return false; +} diff --git a/sources/ElementsCollection/elementcollectionitem.h b/sources/ElementsCollection/elementcollectionitem.h new file mode 100644 index 000000000..066ee5731 --- /dev/null +++ b/sources/ElementsCollection/elementcollectionitem.h @@ -0,0 +1,65 @@ +/* + 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 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 . +*/ +#ifndef ELEMENTCOLLECTIONITEM_H +#define ELEMENTCOLLECTIONITEM_H + +#include + +class QMimeData; +class ElementCollectionItem; +class QList; + +/** + * @brief The ElementCollectionItem class + * This class represent a item (a directory or an element) in a element collection. + * This class must be herited for specialisation. + * This item is used by ElementsCollectionModel for manage the elements collection + */ +class ElementCollectionItem +{ + public: + ElementCollectionItem(ElementCollectionItem *parent = nullptr); + virtual ~ElementCollectionItem(); + + enum {Type = 1 , UserType = 100}; + virtual int type() const {return Type;} + + void appendChild (ElementCollectionItem *item); + ElementCollectionItem *child(int row); + int childCount() const; + int columnCount() const; + virtual QVariant data(int column, int role); + virtual QMimeData *mimeData(); + virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int column); + virtual Qt::ItemFlags flags(); + ElementCollectionItem *parent(); + int row() const; + virtual QString name(); + + virtual bool isDir() const; + virtual bool isElement() const; + virtual bool isValid() const; + + protected: + ElementCollectionItem *m_parent_item; + QList m_child_items; + QString m_name; +}; + +#endif // ELEMENTCOLLECTIONITEM_H diff --git a/sources/ElementsCollection/elementlocation.cpp b/sources/ElementsCollection/elementlocation.cpp new file mode 100644 index 000000000..6628020a3 --- /dev/null +++ b/sources/ElementsCollection/elementlocation.cpp @@ -0,0 +1,231 @@ +/* + 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 distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "elementlocation.h" +#include "qetapp.h" +#include "qetproject.h" +#include "elementscollectioncache.h" + +/** + * @brief ElementLocation::ElementLocation + * @param path : path of item in file system + */ +ElementLocation::ElementLocation(QString path): + m_project(nullptr) +{ + if (!path.isEmpty()) + setPath(path); +} + +/** + * @brief ElementLocation::ElementLocation + * @param path : path of item embedded in @project + * @param project : project + */ +ElementLocation::ElementLocation(QString path, QETProject *project) : + m_project(project) +{ + if (!path.isEmpty()) + setPath(path); +} + +ElementLocation::~ElementLocation() +{} + +/** + * @brief ElementLocation::setPath + * Set the path of this item. + * If the path is for a file collection, the path can be in file system or relative to the beginning + * of the colection, in this case the path must start with (common:// or custom://). + * @param path + * @return true if the element pointed by path exist, else false + */ +bool ElementLocation::setPath(QString path) +{ + if (!path.endsWith(".elmt")) return false; + + QString tmp_path = 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; + } + } + + return false; +} + +bool ElementLocation::isNull() const +{ + if (m_file_system_path.isEmpty()) + return true; + else + return false; +} + +/** + * @brief ElementLocation::setProject + * @param project : set the project of this location to @project. + */ +void ElementLocation::setProject(QETProject *project) +{ + m_project = project; +} + +/** + * @brief ElementLocation::collectionPath + * @return the colletion relative to the collection + */ +QString ElementLocation::collectionPath() const +{ + return m_collection_path; +} + +/** + * @brief ElementLocation::fileSystemPath + * @return The file system path of this element, + * 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(); +} + +/** + * @brief ElementLocation::project + * @return the project of this location if he was set. + */ +QETProject *ElementLocation::project() const +{ + return m_project; +} + +/** + * @brief ElementLocation::xml + * @return The definition of this element. + * The definition can be null. + */ +QDomElement ElementLocation::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(); + } + + return m_xml; +} + +/** + * @brief ElementLocation::uuid + * @return The uuid of the pointed element + */ +QUuid ElementLocation::uuid() +{ + if (!m_uuid.isNull()) return m_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"; + + return m_uuid; +} + +QIcon ElementLocation::icon() +{ + if (!m_icon.isNull()) return m_icon; + + ElementsCollectionCache *cache = QETApp::collectionCache(); + if (cache->fetchElement(*this)) + m_icon = QIcon(cache->pixmap()); + + return m_icon; +} + +QString ElementLocation::name() +{ + ElementsCollectionCache *cache = QETApp::collectionCache(); + if (cache->fetchElement(*this)) + return cache->name(); + else + return QString(); +} diff --git a/sources/ElementsCollection/elementlocation.h b/sources/ElementsCollection/elementlocation.h new file mode 100644 index 000000000..2d5e8fad6 --- /dev/null +++ b/sources/ElementsCollection/elementlocation.h @@ -0,0 +1,64 @@ +/* + 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 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 . +*/ +#ifndef ELEMENTLOCATION_H +#define ELEMENTLOCATION_H + +#include +#include +#include +#include + +class QETProject; + +/** + * @brief The ElementLocation class + * This class represent the location of an element in the file system + * or an embedded collection of a project. + * They also provide common things about an element, like the icon, uuid etc... + */ +class ElementLocation +{ + public: + ElementLocation(QString path = QString()); + ElementLocation(QString path, QETProject *project); + ~ElementLocation(); + + bool setPath(QString path); + bool isNull() const; + void setProject(QETProject *project); + + QString collectionPath() const; + QString fileSystemPath() const; + + QETProject *project() const; + + QDomElement xml(); + QUuid uuid(); + QIcon icon(); + QString name(); + + private: + QString m_collection_path; + QString m_file_system_path; + QETProject *m_project; + QDomElement m_xml; + QUuid m_uuid; + QIcon m_icon; +}; + +#endif // ELEMENTLOCATION_H diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp new file mode 100644 index 000000000..bc94166cb --- /dev/null +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -0,0 +1,228 @@ +/* + 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 distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "elementscollectionmodel.h" +#include "elementcollectionitem.h" +#include "qetapp.h" +#include "fileelementcollectionitem.h" + +/** + * @brief ElementsCollectionModel::ElementsCollectionModel + * Defaut constructor + * @param parent : parent QObject + */ +ElementsCollectionModel::ElementsCollectionModel(QObject *parent) : + QAbstractItemModel (parent) +{ + m_root_item = new ElementCollectionItem(); +} + +ElementsCollectionModel::~ElementsCollectionModel() +{ + delete m_root_item; +} + +/** + * @brief ElementsCollectionModel::index + * Create a index for child of parent at row @row and column @column. + * If there isn't child return default QModelIndex + * @param row : the wanted row + * @param column : the wanted column + * @param parent : the parent index + * @return the wanted index or a unvalid index. + */ +QModelIndex ElementsCollectionModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + ElementCollectionItem *parent_item = nullptr; + + if (!parent.isValid()) + parent_item = m_root_item; + else + parent_item = static_cast(parent.internalPointer()); + + ElementCollectionItem *child_item = parent_item->child(row); + if (child_item->isValid()) + return createIndex(row, column, child_item); + else + return QModelIndex(); +} + +/** + * @brief ElementsCollectionModel::parent + * @param child : + * @return the parent index of child if have parent. + * If child haven't got parent or parent is the root_item, return default index + */ +QModelIndex ElementsCollectionModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) + return QModelIndex(); + + ElementCollectionItem *child_item = static_cast (child.internalPointer()); + ElementCollectionItem *parent_item = child_item->parent(); + + if (parent_item == m_root_item) + return QModelIndex(); + + return createIndex(parent_item->row(), 0, parent_item); +} + +/** + * @brief ElementsCollectionModel::rowCount + * @param parent + * @return the number of row for @parent. + * If @parent is unvalid, return the number of row of the root_item + */ +int ElementsCollectionModel::rowCount(const QModelIndex &parent) const +{ + ElementCollectionItem *parent_item = nullptr; + + if (!parent.isValid()) + parent_item = m_root_item; + else + parent_item = static_cast (parent.internalPointer()); + + return parent_item->childCount(); +} + +/** + * @brief ElementsCollectionModel::columnCount + * @param parent + * @return the number of column for @parent. + * If @parent is unvalid, return the number of column of the root_item + */ +int ElementsCollectionModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return m_root_item->columnCount(); +} + +/** + * @brief ElementsCollectionModel::data + * @param index + * @param role + * @return the data of index for the given role or a default QVariant if no data. + */ +QVariant ElementsCollectionModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + ElementCollectionItem *item = static_cast(index.internalPointer()); + return item->data(index.column(), role); +} + +/** + * @brief ElementsCollectionModel::mimeData + * @param indexes + * @return the mime data of the items at @indexes + */ +QMimeData *ElementsCollectionModel::mimeData(const QModelIndexList &indexes) const +{ + QModelIndex index = indexes.first(); + if (index.isValid()) + { + ElementCollectionItem *item = static_cast(index.internalPointer()); + return item->mimeData(); + } + else + return new QMimeData(); +} + +/** + * @brief ElementsCollectionModel::flags + * @param index + * @return the flags of the item at @index + */ +Qt::ItemFlags ElementsCollectionModel::flags(const QModelIndex &index) const +{ + if (index.isValid()) + { + ElementCollectionItem *eci = static_cast(index.internalPointer()); + return eci->flags(); + } + else + return Qt::NoItemFlags; +} + +bool ElementsCollectionModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const +{ + if (!parent.isValid()) + return false; + + if (!hasIndex(row, column, parent)) return false; + + QModelIndex item = index(row, column, parent); + + if (item.isValid()) + return static_cast(item.internalPointer())->canDropMimeData(data, action, column); + else + return false; + +} + +bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (!parent.isValid()) return false; + + if (!hasIndex(row, column, parent)) return false; + + QModelIndex item = index(row, column, parent); + + if (item.isValid()) + return static_cast(item.internalPointer())->dropMimeData(data, action, column); + else + return false; +} + +QStringList ElementsCollectionModel::mimeTypes() const +{ + QStringList mime_list = QAbstractItemModel::mimeTypes(); + mime_list << "application/x-qet-element-uri"; + return mime_list; +} + +/** + * @brief ElementsCollectionModel::addCommonCollection + * Add the common elements collection to this model + */ +void ElementsCollectionModel::addCommonCollection() +{ + FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item); + if (feci->setRootPath(QETApp::commonElementsDir())) + m_root_item->appendChild(feci); + else + delete feci; +} + +/** + * @brief ElementsCollectionModel::addCustomCollection + * Add the custom elements collection to this model + */ +void ElementsCollectionModel::addCustomCollection() +{ + FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item); + if (feci->setRootPath(QETApp::customElementsDir())) + m_root_item->appendChild(feci); + else + delete feci; +} diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h new file mode 100644 index 000000000..3ce3fad57 --- /dev/null +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -0,0 +1,57 @@ +/* + 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 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 . +*/ +#ifndef ELEMENTSCOLLECTIONMODEL_H +#define ELEMENTSCOLLECTIONMODEL_H + +#include + +class ElementCollectionItem; + +/** + * @brief The ElementsCollectionModel class + * Provide a data model for collection of elements. + */ +class ElementsCollectionModel : public QAbstractItemModel +{ + Q_OBJECT + + public: + ElementsCollectionModel(QObject *parent = nullptr); + ~ElementsCollectionModel(); + + virtual QModelIndex index (int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent (const QModelIndex &child) const; + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + virtual QMimeData *mimeData(const QModelIndexList &indexes) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + 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; + + void addCommonCollection(); + void addCustomCollection(); + + private: + ElementCollectionItem *m_root_item; +}; + +#endif // ELEMENTSCOLLECTIONMODEL_H diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp new file mode 100644 index 000000000..c078a45a3 --- /dev/null +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -0,0 +1,429 @@ +/* + 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 distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "elementscollectionwidget.h" +#include "elementscollectionmodel.h" +#include "elementcollectionitem.h" +#include "qeticons.h" +#include "fileelementcollectionitem.h" +#include "elementslocation.h" +#include "qetapp.h" +#include "qetmessagebox.h" +#include "elementscategoryeditor.h" +#include "newelementwizard.h" +#include "elementscategory.h" + +#include +#include +#include +#include +#include + +/** + * @brief ElementsCollectionWidget::ElementsCollectionWidget + * Default constructor. + * @param parent : parent widget of this widget. + */ +ElementsCollectionWidget::ElementsCollectionWidget(QWidget *parent): + QWidget(parent), + m_item_at_context_menu(nullptr) +{ + setUpWidget(); + setUpAction(); + setUpConnection(); +} + +/** + * @brief ElementsCollectionWidget::expandFirstItems + * Expand each first item in the tree view + */ +void ElementsCollectionWidget::expandFirstItems() +{ + for (int i=0; i < m_model->rowCount() ; i++) + showAndExpandItem(m_model->index(i, 0), false); +} + +/** + * @brief ElementsCollectionWidget::model + * @return The ElementsCollectionModel used by the tree view + */ +ElementsCollectionModel *ElementsCollectionWidget::model() const { + return m_model; +} + +void ElementsCollectionWidget::setUpAction() +{ + m_open_dir = new QAction(QET::Icons::DocumentOpen, tr("Ouvrir le dossier correspondant"), this); + m_edit_element = new QAction(QET::Icons::ElementEdit, tr("Éditer l'élément"), this); + m_delete_element = new QAction(QET::Icons::ElementDelete, tr("Supprimer l'élément"), this); + m_delete_dir = new QAction(QET::Icons::FolderDelete, tr("Supprimer le dossier"), this); + m_reload = new QAction(QET::Icons::ViewRefresh, tr("Recharger les collections"), this); + m_edit_dir = new QAction(QET::Icons::FolderEdit, tr("Éditer le dossier"), this); + m_new_directory = new QAction(QET::Icons::FolderNew, tr("Nouveau dossier"), this); + m_new_element = new QAction(QET::Icons::ElementNew, tr("Nouvel élément"), this); +} + +/** + * @brief ElementsCollectionWidget::setUpWidget + * Setup this widget + */ +void ElementsCollectionWidget::setUpWidget() +{ + //Setup the main layout + m_main_vlayout = new QVBoxLayout(this); + this->setLayout(m_main_vlayout); + + m_search_field = new QLineEdit(this); + m_search_field->setPlaceholderText(tr("Rechercher")); + m_search_field->setClearButtonEnabled(true); + m_main_vlayout->addWidget(m_search_field); + + //Setup the tree view + m_tree_view = new QTreeView(this); + m_tree_view->setHeaderHidden(true); + m_tree_view->setIconSize(QSize(50, 50)); + m_tree_view->setDragDropMode(QAbstractItemView::DragDrop); + 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); + + m_context_menu = new QMenu(this); +} + +/** + * @brief ElementsCollectionWidget::setUpConnection + * Setup the connection used in this widget + */ +void ElementsCollectionWidget::setUpConnection() +{ + connect(m_tree_view, &QTreeView::customContextMenuRequested, this, &ElementsCollectionWidget::customContextMenu); + connect(m_search_field, &QLineEdit::textEdited, this, &ElementsCollectionWidget::search); + connect(m_open_dir, &QAction::triggered, this, &ElementsCollectionWidget::openDir); + connect(m_edit_element, &QAction::triggered, this, &ElementsCollectionWidget::editElement); + connect(m_delete_element, &QAction::triggered, this, &ElementsCollectionWidget::deleteElement); + connect(m_delete_dir, &QAction::triggered, this, &ElementsCollectionWidget::deleteDirectory); + connect(m_reload, &QAction::triggered, this, &ElementsCollectionWidget::reload); + connect(m_edit_dir, &QAction::triggered, this, &ElementsCollectionWidget::editDirectory); + connect(m_new_directory, &QAction::triggered, this, &ElementsCollectionWidget::newDirectory); + connect(m_new_element, &QAction::triggered, this, &ElementsCollectionWidget::newElement); + + connect(m_tree_view, &QTreeView::doubleClicked, [this](const QModelIndex &index) { + this->m_item_at_context_menu = static_cast(index.internalPointer()); + this->editElement();}); +} + +/** + * @brief ElementsCollectionWidget::customContextMenu + * Display the context menu of this widget at @point + * @param point + */ +void ElementsCollectionWidget::customContextMenu(const QPoint &point) +{ + QModelIndex index = m_tree_view->indexAt(point); + if (!index.isValid()) return; + + m_context_menu->clear(); + ElementCollectionItem *eci = static_cast(index.internalPointer()); + m_item_at_context_menu = eci; + + if (eci->isElement()) + m_context_menu->addAction(m_edit_element); + + if (eci->type() == FileElementCollectionItem::Type) + { + FileElementCollectionItem *feci = static_cast(eci); + if (!feci->isCommonCollection()) + { + if (feci->isDir()) + { + m_context_menu->addAction(m_new_element); + m_context_menu->addAction(m_new_directory); + if (!feci->isCollectionRoot()) + { + m_context_menu->addAction(m_edit_dir); + m_context_menu->addAction(m_delete_dir); + } + } + else + m_context_menu->addAction(m_delete_element); + } + } + + m_context_menu->addSeparator(); + m_context_menu->addAction(m_open_dir); + m_context_menu->addAction(m_reload); + + m_context_menu->popup(mapToGlobal(m_tree_view->mapToParent(point))); +} + +/** + * @brief ElementsCollectionWidget::openDir + * Open the directory represented by the current selected item + */ +void ElementsCollectionWidget::openDir() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (!eci || (eci->type() != FileElementCollectionItem::Type)) return; + + QDesktopServices::openUrl(static_cast(eci)->dirPath()); +} + +/** + * @brief ElementsCollectionWidget::editElement + * Edit the element represented by the current selected item + */ +void ElementsCollectionWidget::editElement() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (!eci || + !eci->isElement() || + (eci->type() != FileElementCollectionItem::Type)) return; + + ElementsLocation location(static_cast(eci)->collectionPath()); + QETApp::instance()->openElementLocations(QList() << location); +} + +/** + * @brief ElementsCollectionWidget::deleteElement + * Delete the element represented by the current selected item. + */ +void ElementsCollectionWidget::deleteElement() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (!eci || + !eci->isElement() || + (eci->type() != FileElementCollectionItem::Type)) return; + + + FileElementCollectionItem *feci = static_cast(eci); + //We can't remove an element in the common collection + if (feci->isCommonCollection()) return; + + if (QET::QetMessageBox::question(this, + tr("Supprimer l'élément ?", "message box title"), + tr("Êtes-vous sûr de vouloir supprimer cet élément ?\n", "message box content"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + { + QFile file(feci->fileSystemPath()); + if (!file.remove()) + { + QET::QetMessageBox::warning(this, + tr("Suppression de l'élément", "message box title"), + tr("La suppression de l'élément a échoué.", "message box content")); + } + else + reload(); + } +} + +/** + * @brief ElementsCollectionWidget::deleteDirectory + * Delete directory represented by the current selected item + */ +void ElementsCollectionWidget::deleteDirectory() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (!eci || + !eci->isDir() || + (eci->type() != FileElementCollectionItem::Type)) return; + + FileElementCollectionItem *feci = static_cast(eci); + //We can't remove directory int the common collection or remove the elements directory + if (feci->isCommonCollection() || feci->isCollectionRoot()) return; + + if (QET::QetMessageBox::question(this, + tr("Supprimer le dossier?", "message box title"), + tr("Êtes-vous sûr de vouloir supprimer le dossier ?\n" + "Tout les éléments et les dossier contenus dans ce dossier seront supprimés.", + "message box content"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + { + QDir dir(feci->fileSystemPath()); + if (!dir.removeRecursively()) + { + QET::QetMessageBox::warning(this, + tr("Suppression du dossier", "message box title"), + tr("La suppression du dossier a échoué.", "message box content")); + } + else + reload(); + } +} + +/** + * @brief ElementsCollectionWidget::editDirectory + * Edit the directory represented by the current selected item + */ +void ElementsCollectionWidget::editDirectory() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (eci->type() != FileElementCollectionItem::Type) return; + + FileElementCollectionItem *feci = static_cast(eci); + if(feci->isCommonCollection()) return; + + ElementsLocation location(feci->collectionPath()); + ElementsCategoryEditor ece(location, true, this); + if (ece.exec() == QDialog::Accepted) + reload(); +} + +/** + * @brief ElementsCollectionWidget::newDirectory + * Create a new directory + */ +void ElementsCollectionWidget::newDirectory() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (eci->type() != FileElementCollectionItem::Type) return; + + FileElementCollectionItem *feci = static_cast(eci); + if(feci->isCommonCollection()) return; + + ElementsLocation location(feci->collectionPath()); + ElementsCategoryEditor new_dir_editor(location, false, this); + if (new_dir_editor.exec() == QDialog::Accepted) + reload();; +} + +/** + * @brief ElementsCollectionWidget::newElement + * Create a new element. + */ +void ElementsCollectionWidget::newElement() +{ + ElementCollectionItem *eci = m_item_at_context_menu; + m_item_at_context_menu = nullptr; + + if (eci->type() != FileElementCollectionItem::Type) return; + + FileElementCollectionItem *feci = static_cast(eci); + if(feci->isCommonCollection()) return; + + ElementsCollectionItem *category = QETApp::collectionItem(ElementsLocation(feci->collectionPath()), false); + ElementsCategory *selected_category = category -> toCategory(); + if (!selected_category) return; + + NewElementWizard elmt_wizard(this); + elmt_wizard.preselectCategory(selected_category); + elmt_wizard.exec(); +} + +/** + * @brief ElementsCollectionWidget::reload, the displayed collections. + */ +void ElementsCollectionWidget::reload() +{ + ElementsCollectionModel *new_model = new ElementsCollectionModel(m_tree_view); + new_model->addCommonCollection(); + new_model->addCustomCollection(); + m_tree_view->setModel(new_model); + delete m_model; + m_model = new_model; + expandFirstItems(); +} + +/** + * @brief ElementsCollectionWidget::search + * Search every item (directory or element) that match the string @text + * and display it, other item who does not match @text is hidden + * @param text + */ +void ElementsCollectionWidget::search(const QString &text) +{ + //Reset the tree + if (text.isEmpty()) + { + QModelIndex current_index = m_tree_view->currentIndex(); + m_tree_view->reset(); + expandFirstItems(); + + //Expand the tree and scroll to the last selected index + if (current_index.isValid()) + { + showAndExpandItem(current_index); + m_tree_view->setCurrentIndex(current_index); + m_tree_view->scrollTo(current_index); + } + return; + } + + hideCollection(true); + QModelIndexList match_index = m_model->match(m_model->index(0,0), Qt::DisplayRole, QVariant(text), -1, Qt::MatchContains | Qt::MatchRecursive); + foreach(QModelIndex index, match_index) + showAndExpandItem(index); +} + +/** + * @brief ElementsCollectionWidget::hideCollection + * Hide all collection displayed in this tree + * @param hide- true = hide , false = visible + */ +void ElementsCollectionWidget::hideCollection(bool hide) +{ + for (int i=0 ; i rowCount() ; i++) + hideItem(hide, m_model->index(i, 0), true); +} + +/** + * @brief ElementsCollectionWidget::hideItem + * Hide the item @index. If @recursive is true, hide all subchilds of @index + * @param hide- true = hide , false = visible + * @param index- index to hide + * @param recursive- true = apply to child , false = only for @index + */ +void ElementsCollectionWidget::hideItem(bool hide, const QModelIndex &index, bool recursive) +{ + m_tree_view->setRowHidden(index.row(), index.parent(), hide); + + if (recursive) + for (int i=0 ; irowCount(index) ; i++) + hideItem(hide, m_model->index(i, 0, index), recursive); +} + +/** + * @brief ElementsCollectionWidget::showAndExpandItem + * Show the item @index and expand it. + * If recursive is true, ensure parents of @index is show and expanded + * @param index- index to show + * @param recursive- Apply to parent + */ +void ElementsCollectionWidget::showAndExpandItem(const QModelIndex &index, bool recursive) +{ + if (recursive && index.isValid()) + showAndExpandItem(index.parent(), recursive); + + m_tree_view->setRowHidden(index.row(), index.parent(), false); + m_tree_view->expand(index); +} diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h new file mode 100644 index 000000000..2c92aac8e --- /dev/null +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -0,0 +1,83 @@ +/* + 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 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 . +*/ +#ifndef ELEMENTSCOLLECTIONWIDGET_H +#define ELEMENTSCOLLECTIONWIDGET_H + +#include +#include + +class ElementsCollectionModel; +class QTreeView; +class QVBoxLayout; +class QMenu; +class QLineEdit; +class ElementCollectionItem; + +/** + * @brief The ElementsCollectionWidget class + * This widget embedd a tree view that display the element collection (common, custom, embedded) + * and all action needed to use this widget. + * This is the element collection widget used in the diagram editor. + */ +class ElementsCollectionWidget : public QWidget +{ + Q_OBJECT + + public: + ElementsCollectionWidget(QWidget *parent = nullptr); + + void expandFirstItems(); + ElementsCollectionModel *model() const; + + private: + void setUpAction(); + void setUpWidget(); + void setUpConnection(); + void customContextMenu(const QPoint &point); + void openDir(); + void editElement(); + void deleteElement(); + void deleteDirectory(); + void editDirectory(); + void newDirectory(); + void newElement(); + void reload(); + void search(const QString &text); + void hideCollection(bool hide = true); + void hideItem(bool hide, const QModelIndex &index = QModelIndex(), bool recursive = true); + void showAndExpandItem (const QModelIndex &index, bool recursive = true); + + private: + ElementsCollectionModel *m_model; + QLineEdit *m_search_field; + QTreeView *m_tree_view; + QVBoxLayout *m_main_vlayout; + QMenu *m_context_menu; + ElementCollectionItem *m_item_at_context_menu; + + QAction *m_open_dir, + *m_edit_element, + *m_delete_element, + *m_delete_dir, + *m_reload, + *m_edit_dir, + *m_new_directory, + *m_new_element; +}; + +#endif // ELEMENTSCOLLECTIONWIDGET_H diff --git a/sources/ElementsCollection/fileelementcollectionitem.cpp b/sources/ElementsCollection/fileelementcollectionitem.cpp new file mode 100644 index 000000000..241c186ce --- /dev/null +++ b/sources/ElementsCollection/fileelementcollectionitem.cpp @@ -0,0 +1,379 @@ +/* + 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 distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "fileelementcollectionitem.h" +#include "QDir" +#include "qetapp.h" +#include "elementslocation.h" +#include "nameslist.h" +#include "qeticons.h" + +/** + * @brief FileElementCollectionItem::FileElementCollectionItem + * Default constructor + * @param parent : parent item of this item + */ +FileElementCollectionItem::FileElementCollectionItem(ElementCollectionItem *parent) : + ElementCollectionItem(parent) +{} + +/** + * @brief FileElementCollectionItem::~FileElementCollectionItem + * Destructor + */ +FileElementCollectionItem::~FileElementCollectionItem() +{} + +/** + * @brief FileElementCollectionItem::setRootPath + * Set path has root path for this file item. + * Use this function only to set the beginning of a file collection. + * @param path + * @return true if path exist. + */ +bool FileElementCollectionItem::setRootPath(QString path) +{ + QDir dir(path); + + if (dir.exists()) + { + m_path = path; + populate(); + name(); + return true; + } + + return false; +} + +/** + * @brief FileElementCollectionItem::fileSystemPath + * @return the file system path of this item + */ +QString FileElementCollectionItem::fileSystemPath() const +{ + //Parent must be a file element collection item + if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type) + return m_path; + + FileElementCollectionItem *parent = static_cast(m_parent_item); + + //Get the path of the parent. + QString path = parent->fileSystemPath(); + return path + "/" + m_path; +} + +/** + * @brief FileElementCollectionItem::dirPath + * @return the dir path of this item + */ +QString FileElementCollectionItem::dirPath() const +{ + if (isDir()) + return fileSystemPath(); + + //Parent must be a file element collection item + if (m_parent_item->type() != FileElementCollectionItem::Type) return QString(); + + FileElementCollectionItem *parent = static_cast(m_parent_item); + //Get the path of the parent. + return parent->fileSystemPath(); +} + +/** + * @brief FileElementCollectionItem::collectionPath + * @return The path of this item relative to the collection. + */ +QString FileElementCollectionItem::collectionPath() const +{ + //Parent must be a file element collection item + //else this item is the root of collection path. + if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type) + { + if (m_path == QETApp::commonElementsDir()) + return "common://"; + else + return "custom://"; + } + else if (m_parent_item->type() == FileElementCollectionItem::Type) + { + FileElementCollectionItem *feci = static_cast(m_parent_item); + if (feci->isCollectionRoot()) + return feci->collectionPath() + m_path; + else + return feci->collectionPath() + "/" + m_path; + } + else + return QString(); +} + +/** + * @brief FileElementCollectionItem::data + * @param column + * @param role + * @return the item data at column and role + */ +QVariant FileElementCollectionItem::data(int column, int role) +{ + //element collection have only one column + if (column > 1) + return QVariant(); + + 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"); + } + + return name(); + } + break; + case Qt::DecorationRole: + { + //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 QIcon(":/ico/16x16/qet.png"); + else + return QIcon(":/ico/16x16/go-home.png"); + } + + if (isDir()) + return QET::Icons::Folder; + else if (isElement()) + { + if (m_icon.isNull()) + { + ElementLocation loc(collectionPath()); + m_icon = loc.icon(); + } + return m_icon; + } + } + case Qt::ToolTipRole: + return collectionPath(); + break; + default: + return QVariant(); + break; + } + + return QVariant(); +} + +/** + * @brief FileElementCollectionItem::mimeData + * @return the mime data of this item + */ +QMimeData *FileElementCollectionItem::mimeData() +{ + QMimeData *mime_data = new QMimeData(); + mime_data->setText(collectionPath()); + mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1()); + return mime_data; +} + +/** + * @brief FileElementCollectionItem::canDropMimeData + * @param data + * @param action + * @param column + * @return True if the data can be dropped + */ +bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const +{ + Q_UNUSED(action); Q_UNUSED(column); + + if (data->hasFormat("application/x-qet-element-uri") && + fileSystemPath().startsWith(QETApp::customElementsDir())) + return true; + else + return false; +} + +/** + * @brief FileElementCollectionItem::dropMimeData + * @param data + * @param action + * @param column + * @return Handle the drop of a data + */ +bool FileElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int column) +{ + Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column); + return false; +} + +/** + * @brief FileElementCollectionItem::flags + * @return the flags of this item + */ +Qt::ItemFlags FileElementCollectionItem::flags() +{ + if (isDir()) + return (Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + else + return (Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); +} + +/** + * @brief FileElementCollectionItem::isDir + * @return true if this item represent a directory + */ +bool FileElementCollectionItem::isDir() const +{ + if (m_path.endsWith(".elmt")) + return false; + else + return true; +} + +/** + * @brief FileElementCollectionItem::isElement + * @return true if this item represent an element + */ +bool FileElementCollectionItem::isElement() const { + return (!isDir()); +} + +/** + * @brief FileElementCollectionItem::isCollectionRoot + * @return true if this item represent the root of collection + */ +bool FileElementCollectionItem::isCollectionRoot() const +{ + if (m_path == QETApp::commonElementsDir() || m_path == QETApp::customElementsDir()) + return true; + else + return false; +} + +/** + * @brief FileElementCollectionItem::isCommonCollection + * @return True if this item is part of the common element collection item + */ +bool FileElementCollectionItem::isCommonCollection() const { + return fileSystemPath().startsWith(QETApp::commonElementsDir()); +} + +/** + * @brief FileElementCollectionItem::isValid + * @return + */ +bool FileElementCollectionItem::isValid() const +{ + return true; + if (m_path.isEmpty()) + return false; + else + return true; +} + +/** + * @brief FileElementCollectionItem::name + * @return the located name of this item + */ +QString FileElementCollectionItem::name() +{ + if (!m_name.isNull()) return m_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 (!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(""); + + 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(); + } + else if (isElement()) + { + ElementLocation loc(collectionPath()); + m_name = loc.name(); + } + return m_name; +} + +/** + * @brief FileElementCollectionItem::setPathName + * Set the name of this item in the file system path. + * This item must have a parent, because they should be a child item of another. + * For create a new file collection see setRootPath. + * @param path_name + */ +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")) + populate(); +} + +/** + * @brief FileElementCollectionItem::populate + * Item populate itself with childs found in the system path. + */ +void FileElementCollectionItem::populate() +{ + QDir dir (fileSystemPath()); + + //Get all directory in this directory. + foreach(QString str, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name)) + { + FileElementCollectionItem *feci = new FileElementCollectionItem(this); + feci->setPathName(str); + appendChild(feci); + } + + //Get all elmt file in this directory + dir.setNameFilters(QStringList() << "*.elmt"); + foreach(QString str, dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name)) + { + FileElementCollectionItem *feci = new FileElementCollectionItem(this); + feci->setPathName(str); + appendChild(feci); + } +} diff --git a/sources/ElementsCollection/fileelementcollectionitem.h b/sources/ElementsCollection/fileelementcollectionitem.h new file mode 100644 index 000000000..26704cfe6 --- /dev/null +++ b/sources/ElementsCollection/fileelementcollectionitem.h @@ -0,0 +1,68 @@ +/* + 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 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 . +*/ +#ifndef FILEELEMENTCOLLECTIONITEM_H +#define FILEELEMENTCOLLECTIONITEM_H + +#include "elementcollectionitem.h" +#include "elementlocation.h" +#include + +/** + * @brief The FileElementCollectionItem class + * This class specialise ElementCollectionItem for manage a collection in + * a file system. They represente a directory or an element. + */ +class FileElementCollectionItem : public ElementCollectionItem +{ + public: + FileElementCollectionItem(ElementCollectionItem *parent = nullptr); + ~FileElementCollectionItem(); + + enum {Type = UserType + 1}; + virtual int type() const {return Type;} + + bool setRootPath(QString path); + QString fileSystemPath() const; + QString dirPath() const; + + QString collectionPath() const; + + virtual QVariant data(int column, int role); + virtual QMimeData *mimeData(); + virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int column); + virtual Qt::ItemFlags flags(); + + virtual bool isDir() const; + virtual bool isElement() const; + virtual bool isCollectionRoot() const; + bool isCommonCollection() const; + virtual bool isValid() const; + virtual QString name(); + + private: + void setPathName(QString path_name); + void populate(); + + private: + QString m_path; + ElementLocation m_location; + QIcon m_icon; +}; + +#endif // FILEELEMENTCOLLECTIONITEM_H diff --git a/sources/elementscollectioncache.cpp b/sources/elementscollectioncache.cpp index b6095d281..afc56c719 100644 --- a/sources/elementscollectioncache.cpp +++ b/sources/elementscollectioncache.cpp @@ -215,6 +215,20 @@ bool ElementsCollectionCache::fetchElement(ElementDefinition *element) } } +bool ElementsCollectionCache::fetchElement(ElementLocation location) +{ + if (fetchNameFromCache(location.collectionPath(), location.uuid()) && + fetchPixmapFromCache(location.collectionPath(), location.uuid())) + return true; + else if (fetchData(ElementsLocation(location.collectionPath()))) + { + cacheName(location.collectionPath(), location.uuid()); + cachePixmap(location.collectionPath(), location.uuid()); + return true; + } + return false; +} + /** @return The last name fetched through fetchElement(). */ diff --git a/sources/elementscollectioncache.h b/sources/elementscollectioncache.h index 03dfd4efb..4e4bb6121 100644 --- a/sources/elementscollectioncache.h +++ b/sources/elementscollectioncache.h @@ -20,6 +20,7 @@ #include #include #include "elementslocation.h" +#include "elementlocation.h" class ElementsCollection; class ElementsCategory; class ElementDefinition; @@ -45,6 +46,7 @@ class ElementsCollectionCache : public QObject void beginCollection(ElementsCollection *); void endCollection(ElementsCollection *); bool fetchElement(ElementDefinition *); + bool fetchElement(ElementLocation location); QString name() const; QPixmap pixmap() const; bool fetchData(const ElementsLocation &); diff --git a/sources/factory/elementfactory.h b/sources/factory/elementfactory.h index a38eaddba..fe3b3d241 100644 --- a/sources/factory/elementfactory.h +++ b/sources/factory/elementfactory.h @@ -19,6 +19,7 @@ #define ELEMENTFACTORY_H #include +#include "elementlocation.h" class Element; class ElementsLocation; class QGraphicsItem; diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 9b6c53364..0a0712938 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -40,12 +40,15 @@ #include "diagrameventaddshape.h" #include "diagrameventaddimage.h" #include "diagrameventaddtext.h" +#include "elementscollectionwidget.h" #include "ui/dialogautonum.h" #include #include +#include "elementscollectionmodel.h" + /** * @brief QETDiagramEditor::QETDiagramEditor @@ -79,8 +82,10 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) : statusBar() -> showMessage(tr("QElectroTech", "status bar message")); setUpElementsPanel(); + setUpElementsCollectionWidget(); setUpUndoStack(); setUpSelectionPropertiesEditor(); + setUpActions(); setUpToolBar(); setUpMenu(); @@ -148,6 +153,24 @@ void QETDiagramEditor::setUpElementsPanel() { connect(pa, SIGNAL(requestForDiagramMoveDownx10 (Diagram *)), this, SLOT(moveDiagramDownx10(Diagram *))); } +/** + * @brief QETDiagramEditor::setUpElementsCollectionWidget + * Set up the dock widget of element collection + */ +void QETDiagramEditor::setUpElementsCollectionWidget() +{ + m_qdw_elmt_collection = new QDockWidget(tr("Collection d'éléments"), this); + m_qdw_elmt_collection->setObjectName("elements_collection_widget"); + m_qdw_elmt_collection->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + m_qdw_elmt_collection->setFeatures(QDockWidget::AllDockWidgetFeatures); + + m_element_collection_widget = new ElementsCollectionWidget(m_qdw_elmt_collection); + m_qdw_elmt_collection->setWidget(m_element_collection_widget); + m_element_collection_widget->expandFirstItems(); + + addDockWidget(Qt::RightDockWidgetArea, m_qdw_elmt_collection); +} + /** * @brief QETDiagramEditor::setUpUndoStack * Setup the undostack and undo stack widget diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index e0de2491e..778c0bcdf 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -31,6 +31,8 @@ class ElementsPanelWidget; class ElementsLocation; class RecentFiles; class DiagramPropertiesEditorDockWidget; +class ElementsCollectionWidget; + /** This class represents the main window of the QElectroTech diagram editor and, ipso facto, the most important part of the QElectroTech user interface. @@ -48,6 +50,7 @@ class QETDiagramEditor : public QETMainWindow { private: void setUpElementsPanel (); + void setUpElementsCollectionWidget(); void setUpUndoStack (); void setUpSelectionPropertiesEditor(); void setUpActions (); @@ -208,6 +211,8 @@ class QETDiagramEditor : public QETMainWindow { QDir open_dialog_dir; /// Dock for the elements panel QDockWidget *qdw_pa; + QDockWidget *m_qdw_elmt_collection; + ElementsCollectionWidget *m_element_collection_widget; /// Dock for the undo list QDockWidget *qdw_undo; DiagramPropertiesEditorDockWidget *m_selection_properties_editor;