[qet] [4283] Add new element panel

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 4283
Author:   blacksun
Date:     2015-12-08 17:52:10 +0100 (Tue, 08 Dec 2015)
Log Message:
-----------
Add new element panel

Modified Paths:
--------------
    trunk/qelectrotech.pro
    trunk/sources/elementscollectioncache.cpp
    trunk/sources/elementscollectioncache.h
    trunk/sources/factory/elementfactory.h
    trunk/sources/qetdiagrameditor.cpp
    trunk/sources/qetdiagrameditor.h

Added Paths:
-----------
    trunk/sources/ElementsCollection/
    trunk/sources/ElementsCollection/elementcollectionitem.cpp
    trunk/sources/ElementsCollection/elementcollectionitem.h
    trunk/sources/ElementsCollection/elementlocation.cpp
    trunk/sources/ElementsCollection/elementlocation.h
    trunk/sources/ElementsCollection/elementscollectionmodel.cpp
    trunk/sources/ElementsCollection/elementscollectionmodel.h
    trunk/sources/ElementsCollection/elementscollectionwidget.cpp
    trunk/sources/ElementsCollection/elementscollectionwidget.h
    trunk/sources/ElementsCollection/fileelementcollectionitem.cpp
    trunk/sources/ElementsCollection/fileelementcollectionitem.h

Modified: trunk/qelectrotech.pro
===================================================================
--- trunk/qelectrotech.pro	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/qelectrotech.pro	2015-12-08 16:52:10 UTC (rev 4283)
@@ -78,7 +78,8 @@
                sources/editor/esevent \
                sources/editor/graphicspart \
                sources/undocommand \
-               sources/diagramevent
+               sources/diagramevent \
+               sources/ElementsCollection
 
 
 # Fichiers sources
@@ -89,7 +90,8 @@
            $$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 @@
            $$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 @@
 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

Added: trunk/sources/ElementsCollection/elementcollectionitem.cpp
===================================================================
--- trunk/sources/ElementsCollection/elementcollectionitem.cpp	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementcollectionitem.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#include "elementcollectionitem.h"
+#include <QMimeData>
+
+/**
+ * @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<ElementCollectionItem *>(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;
+}

Added: trunk/sources/ElementsCollection/elementcollectionitem.h
===================================================================
--- trunk/sources/ElementsCollection/elementcollectionitem.h	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementcollectionitem.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef ELEMENTCOLLECTIONITEM_H
+#define ELEMENTCOLLECTIONITEM_H
+
+#include <QVariant>
+
+class QMimeData;
+class ElementCollectionItem;
+class QList<ElementCollectionItem>;
+
+/**
+ * @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 <ElementCollectionItem *> m_child_items;
+		QString m_name;
+};
+
+#endif // ELEMENTCOLLECTIONITEM_H

Added: trunk/sources/ElementsCollection/elementlocation.cpp
===================================================================
--- trunk/sources/ElementsCollection/elementlocation.cpp	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementlocation.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#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<QDomElement>  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();
+}

Added: trunk/sources/ElementsCollection/elementlocation.h
===================================================================
--- trunk/sources/ElementsCollection/elementlocation.h	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementlocation.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef ELEMENTLOCATION_H
+#define ELEMENTLOCATION_H
+
+#include <QString>
+#include <QDomElement>
+#include <QUuid>
+#include <QIcon>
+
+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

Added: trunk/sources/ElementsCollection/elementscollectionmodel.cpp
===================================================================
--- trunk/sources/ElementsCollection/elementscollectionmodel.cpp	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementscollectionmodel.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#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<ElementCollectionItem*>(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<ElementCollectionItem*> (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<ElementCollectionItem*> (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<ElementCollectionItem*>(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<ElementCollectionItem*>(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<ElementCollectionItem*>(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<ElementCollectionItem*>(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<ElementCollectionItem*>(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<ElementCollectionItem*>(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;
+}

Added: trunk/sources/ElementsCollection/elementscollectionmodel.h
===================================================================
--- trunk/sources/ElementsCollection/elementscollectionmodel.h	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementscollectionmodel.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef ELEMENTSCOLLECTIONMODEL_H
+#define ELEMENTSCOLLECTIONMODEL_H
+
+#include <QAbstractItemModel>
+
+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

Added: trunk/sources/ElementsCollection/elementscollectionwidget.cpp
===================================================================
--- trunk/sources/ElementsCollection/elementscollectionwidget.cpp	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementscollectionwidget.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#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 <QVBoxLayout>
+#include <QTreeView>
+#include <QMenu>
+#include <QDesktopServices>
+#include <QUrl>
+
+/**
+ * @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<ElementCollectionItem*>(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<ElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(eci)->collectionPath());
+	QETApp::instance()->openElementLocations(QList<ElementsLocation>() << 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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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 <m_model->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 ; i<m_model->rowCount(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);
+}

Added: trunk/sources/ElementsCollection/elementscollectionwidget.h
===================================================================
--- trunk/sources/ElementsCollection/elementscollectionwidget.h	                        (rev 0)
+++ trunk/sources/ElementsCollection/elementscollectionwidget.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef ELEMENTSCOLLECTIONWIDGET_H
+#define ELEMENTSCOLLECTIONWIDGET_H
+
+#include <QWidget>
+#include <QModelIndex>
+
+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

Added: trunk/sources/ElementsCollection/fileelementcollectionitem.cpp
===================================================================
--- trunk/sources/ElementsCollection/fileelementcollectionitem.cpp	                        (rev 0)
+++ trunk/sources/ElementsCollection/fileelementcollectionitem.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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<FileElementCollectionItem*>(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);
+	}
+}

Added: trunk/sources/ElementsCollection/fileelementcollectionitem.h
===================================================================
--- trunk/sources/ElementsCollection/fileelementcollectionitem.h	                        (rev 0)
+++ trunk/sources/ElementsCollection/fileelementcollectionitem.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef FILEELEMENTCOLLECTIONITEM_H
+#define FILEELEMENTCOLLECTIONITEM_H
+
+#include "elementcollectionitem.h"
+#include "elementlocation.h"
+#include <QString>
+
+/**
+ * @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

Modified: trunk/sources/elementscollectioncache.cpp
===================================================================
--- trunk/sources/elementscollectioncache.cpp	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/sources/elementscollectioncache.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -215,6 +215,20 @@
 	}
 }
 
+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().
 */

Modified: trunk/sources/elementscollectioncache.h
===================================================================
--- trunk/sources/elementscollectioncache.h	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/sources/elementscollectioncache.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -20,6 +20,7 @@
 #include <QtCore>
 #include <QtSql>
 #include "elementslocation.h"
+#include "elementlocation.h"
 class ElementsCollection;
 class ElementsCategory;
 class ElementDefinition;
@@ -45,6 +46,7 @@
 	void beginCollection(ElementsCollection *);
 	void endCollection(ElementsCollection *);
 	bool fetchElement(ElementDefinition *);
+	bool fetchElement(ElementLocation location);
 	QString name() const;
 	QPixmap pixmap() const;
 	bool fetchData(const ElementsLocation &);

Modified: trunk/sources/factory/elementfactory.h
===================================================================
--- trunk/sources/factory/elementfactory.h	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/sources/factory/elementfactory.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -19,6 +19,7 @@
 #define ELEMENTFACTORY_H
 
 #include <QMutex>
+#include "elementlocation.h"
 class Element;
 class ElementsLocation;
 class QGraphicsItem;

Modified: trunk/sources/qetdiagrameditor.cpp
===================================================================
--- trunk/sources/qetdiagrameditor.cpp	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/sources/qetdiagrameditor.cpp	2015-12-08 16:52:10 UTC (rev 4283)
@@ -40,13 +40,16 @@
 #include "diagrameventaddshape.h"
 #include "diagrameventaddimage.h"
 #include "diagrameventaddtext.h"
+#include "elementscollectionwidget.h"
 
 #include "ui/dialogautonum.h"
 
 #include <QMessageBox>
 #include <QStandardPaths>
 
+#include "elementscollectionmodel.h"
 
+
 /**
  * @brief QETDiagramEditor::QETDiagramEditor
  * Constructor
@@ -79,8 +82,10 @@
 	statusBar() -> showMessage(tr("QElectroTech", "status bar message"));
 	
 	setUpElementsPanel();
+	setUpElementsCollectionWidget();
 	setUpUndoStack();
 	setUpSelectionPropertiesEditor();
+
 	setUpActions();
 	setUpToolBar();
 	setUpMenu();
@@ -149,6 +154,24 @@
 }
 
 /**
+ * @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
  */

Modified: trunk/sources/qetdiagrameditor.h
===================================================================
--- trunk/sources/qetdiagrameditor.h	2015-12-01 18:39:16 UTC (rev 4282)
+++ trunk/sources/qetdiagrameditor.h	2015-12-08 16:52:10 UTC (rev 4283)
@@ -31,6 +31,8 @@
 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 @@
 
 	private:
 		void setUpElementsPanel ();
+		void setUpElementsCollectionWidget();
 		void setUpUndoStack     ();
 		void setUpSelectionPropertiesEditor();
 		void setUpActions       ();
@@ -208,6 +211,8 @@
 		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;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/