diff --git a/sources/ElementsCollection/elementcollectionitem.cpp b/sources/ElementsCollection/elementcollectionitem.cpp index 2e7cadb12..9f0bfbd22 100644 --- a/sources/ElementsCollection/elementcollectionitem.cpp +++ b/sources/ElementsCollection/elementcollectionitem.cpp @@ -1,116 +1,39 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ + #include "elementcollectionitem.h" -#include -#include /** * @brief ElementCollectionItem::ElementCollectionItem * Constructor - * @param parent : the parent item of this item */ -ElementCollectionItem::ElementCollectionItem(ElementCollectionItem *parent) : - QObject(parent), - m_parent_item (parent) +ElementCollectionItem::ElementCollectionItem() {} /** - * @brief ElementCollectionItem::~ElementCollectionItem - * Destructor + * @brief ElementCollectionItem::clearData + * Reset the data */ -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::removeChild - * Remove and delete count childs starting at position row - * @param row - * @return true if childs was successfully removed - */ -bool ElementCollectionItem::removeChild(int row, int count) +void ElementCollectionItem::clearData() { - if (!(1 <= row+count && row+count <= m_child_items.size())) return false; - - int last_ = row + (count-1); - if (last_ < row) return false; - - emit beginRemoveRows(this, row, last_); - - for (int i=0 ; icollectionName() == name) return eci; - - return nullptr; + setText(QString()); + setToolTip(QString()); + setIcon(QIcon()); } /** @@ -118,10 +41,10 @@ ElementCollectionItem *ElementCollectionItem::childWithCollectionName(QString na * Return the last existing item in this ElementCollectionItem hierarchy according to the given path. * Next_item is the first non existing item in this hierarchy according to the given path. * @param path : The path to find last item. The path must be in form : path/otherPath/.../.../myElement.elmt. - * @param newt_item : The first item that not exist in this hierarchy + * @param no_found_path : The first item that not exist in this hierarchy * @return : The last item that exist in this hierarchy, or nullptr can't find (an error was occurred, or path already exist) */ -ElementCollectionItem *ElementCollectionItem::lastItemForPath(const QString &path, QString &newt_item) +ElementCollectionItem *ElementCollectionItem::lastItemForPath(const QString &path, QString &no_found_path) { QStringList str_list = path.split("/"); if (str_list.isEmpty()) return nullptr; @@ -132,7 +55,7 @@ ElementCollectionItem *ElementCollectionItem::lastItemForPath(const QString &pat ElementCollectionItem *eci = return_eci->childWithCollectionName(str); if (!eci) { - newt_item = str; + no_found_path = str; return return_eci; } else @@ -143,27 +66,36 @@ ElementCollectionItem *ElementCollectionItem::lastItemForPath(const QString &pat } /** - * @brief ElementCollectionItem::itemAtPath - * @param path - * @return the item at path or nullptr if doesn't exist + * @brief ElementCollectionItem::childWithCollectionName + * Return the child with the collection name @name, else return nullptr + * @param name + * @return */ -ElementCollectionItem *ElementCollectionItem::itemAtPath(const QString &path) +ElementCollectionItem *ElementCollectionItem::childWithCollectionName(QString name) const { - QStringList str_list = path.split("/"); - if (str_list.isEmpty()) return nullptr; - - ElementCollectionItem *match_eci = this; - foreach (QString str, str_list) { - ElementCollectionItem *eci = match_eci->childWithCollectionName(str); - if (!eci) { - return nullptr; - } - else { - match_eci = eci; - } + rowCount(); + foreach (QStandardItem *qsi, directChilds()) { + ElementCollectionItem *eci = static_cast(qsi); + if (eci->name() == name) + return eci; } - return match_eci; + return nullptr; +} + +/** + * @brief ElementCollectionItem::directChilds + * Return the direct child of this item + * @return + */ +QList ElementCollectionItem::directChilds() const +{ + QList item_list; + + for (int i=0 ; i child; //The item to insert is an element we search from element child - if (collection_name.endsWith(".elmt")) + if (name.endsWith(".elmt")) { - child = elementsChild(); + child = elementsDirectChild(); //There isn't element, we insert at last position if (child.isEmpty()) - return childCount(); + return rowCount(); } //The item is a directory, we search from directory child else { - child = directoriesChild(); + child = directoriesDirectChild(); //There isn't directory, we insert at first position if(child.isEmpty()) return 0; } foreach (ElementCollectionItem *eci, child) - if (eci->collectionName() > collection_name) - return indexOfChild(eci); + if (eci->name() > name) + return model()->indexFromItem(eci).row(); - return (indexOfChild(child.last())+1); + return (model()->indexFromItem(child.last()).row() + 1); } /** - * @brief ElementCollectionItem::insertNewItem - * By defualt do nothing, implement this method in subclass - * to handle the insertion of a new item with name collection_name + * @brief ElementCollectionItem::itemAtPath + * @param path + * @return the item at path or nullptr if doesn't exist */ -void ElementCollectionItem::insertNewItem(const QString &collection_name) {Q_UNUSED (collection_name);} - -/** - * @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) +ElementCollectionItem *ElementCollectionItem::itemAtPath(const QString &path) { - Q_UNUSED(column); + QStringList str_list = path.split("/"); + if (str_list.isEmpty()) + return nullptr; - switch (role) - { - case Qt::BackgroundRole: - { - if(m_show_bg_color) - return QBrush(m_bg_color); - else - return QVariant(); - } - case Qt::StatusTipRole: - { - if (isElement()) - return tr("Glissez-déposez cet élément « %1 » sur un folio pour l'y insérer, double-cliquez dessus pour l'éditer").arg(name()); - else - return tr("Double-cliquez pour réduire ou développer cette catégorie d'éléments"); - } - default: - return QVariant(); + ElementCollectionItem *match_eci = this; + foreach (QString str, str_list) { + ElementCollectionItem *eci = match_eci->childWithCollectionName(str); + if (!eci) + return nullptr; + else + match_eci = eci; } - return QVariant(); + return match_eci; } /** - * @brief ElementCollectionItem::clearData - * Reset the curent name + * @brief ElementCollectionItem::elementsDirectChild + * @return The direct element child of this item */ -void ElementCollectionItem::clearData() +QList ElementCollectionItem::elementsDirectChild() const { - m_name = QString(); + QList element_child; + + foreach (QStandardItem *qsi, directChilds()) { + ElementCollectionItem *eci = static_cast(qsi); + if (eci->isElement()) + element_child.append(eci); + } + + return element_child; } /** - * @brief ElementCollectionItem::mimeData - * @return The mime data of this item + * @brief ElementCollectionItem::directoriesDirectChild + * @return the direct directory child of this item */ -QMimeData *ElementCollectionItem::mimeData() { - return new QMimeData(); -} - -bool ElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const +QList ElementCollectionItem::directoriesDirectChild() const { - Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - return false; -} + QList dir_child; -bool ElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) -{ - Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - return false; -} + foreach (QStandardItem *qsi, directChilds()) { + ElementCollectionItem *eci = static_cast(qsi); + if (eci->isDir()) + dir_child.append(eci); + } -/** - * @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::collectionName - * @return The collection name of this item - */ -QString ElementCollectionItem::collectionName() const { - return QString(); -} - -/** - * @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; + return dir_child; } /** * @brief ElementCollectionItem::items - * @return all child and subchild subsubchild... contained by this item - * This item isn't stored in the list + * @return every childs of this item (direct and indirect childs) */ QList ElementCollectionItem::items() const { - QList list; - list.append(m_child_items); - foreach(ElementCollectionItem *eci, m_child_items) + QList list; + + for (int i=0 ; i(child(i)); + list.append(eci); list.append(eci->items()); - return list; -} - -/** - * @brief ElementCollectionItem::elementsChild - * @return All elements child of this item - */ -QList ElementCollectionItem::elementsChild() const -{ - QList list; - foreach (ElementCollectionItem *eci, m_child_items) - if (eci->isElement()) - list.append(eci); + } return list; } - -/** - * @brief ElementCollectionItem::directoriesChild - * @return All directories child of this item - */ -QList ElementCollectionItem::directoriesChild() const -{ - QList list; - foreach (ElementCollectionItem *eci, m_child_items) - if (eci->isDir()) - list.append(eci); - - return list; -} - -/** - * @brief ElementCollectionItem::indexOfChild - * @param child - * @return the index of child or -1 if not found - */ -int ElementCollectionItem::indexOfChild(ElementCollectionItem *child) const { - return m_child_items.indexOf(child); -} - -/** - * @brief ElementCollectionItem::setBackgroundColor - * Set the background color for this item to @color - * if @show is true, use the background color, else let's Qt use the appropriate color - * @param color - * @param show - */ -void ElementCollectionItem::setBackgroundColor(Qt::GlobalColor color, bool show) -{ - m_bg_color = color; - m_show_bg_color = show; -} diff --git a/sources/ElementsCollection/elementcollectionitem.h b/sources/ElementsCollection/elementcollectionitem.h index 813d3b4da..2726acb60 100644 --- a/sources/ElementsCollection/elementcollectionitem.h +++ b/sources/ElementsCollection/elementcollectionitem.h @@ -1,28 +1,24 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ -#ifndef ELEMENTCOLLECTIONITEM_H -#define ELEMENTCOLLECTIONITEM_H +#ifndef ELEMENTCOLLECTIONITEM2_H +#define ELEMENTCOLLECTIONITEM2_H -#include - -class QMimeData; -class ElementCollectionItem; -class QList; +#include /** * @brief The ElementCollectionItem class @@ -30,61 +26,34 @@ class QList; * This class must be herited for specialisation. * This item is used by ElementsCollectionModel for manage the elements collection */ -class ElementCollectionItem : public QObject +class ElementCollectionItem : public QStandardItem { - Q_OBJECT + public: + ElementCollectionItem(); - public: - ElementCollectionItem(ElementCollectionItem *parent = nullptr); - virtual ~ElementCollectionItem(); + enum {Type = UserType+1}; + virtual int type() const { return Type; } - enum {Type = 1 , UserType = 100}; - virtual int type() const {return Type;} - - void appendChild (ElementCollectionItem *item); - bool removeChild (int row, int count); - bool insertChild (int row, ElementCollectionItem *item); - ElementCollectionItem *child(int row) const; - ElementCollectionItem *childWithCollectionName(QString name) const; - ElementCollectionItem *lastItemForPath(const QString &path, QString &newt_item); - ElementCollectionItem *itemAtPath(const QString &path); - int rowForInsertItem(const QString &collection_name); - virtual void insertNewItem(const QString &collection_name); - int childCount() const; - int columnCount() const; - virtual QVariant data(int column, int role); + virtual bool isDir() const = 0; + virtual bool isElement() const = 0; + virtual QString localName() = 0; + virtual QString name() const = 0; + virtual QString collectionPath() const = 0; + virtual bool isCollectionRoot() const = 0; + virtual void addChildAtPath(const QString &collection_name) = 0; + virtual void setUpData() = 0; + virtual void setUpIcon() = 0; virtual void clearData(); - virtual QMimeData *mimeData(); - virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column); - virtual Qt::ItemFlags flags(); - ElementCollectionItem *parent(); - int row() const; - virtual QString name(); - virtual QString collectionName() const; - virtual QString collectionPath() const {return QString();} - virtual bool isDir() const; - virtual bool isElement() const; - virtual bool isValid() const; - virtual QList items() const; - QList elementsChild() const; - QList directoriesChild() const; - int indexOfChild(ElementCollectionItem *child) const; - void setBackgroundColor(Qt::GlobalColor color, bool show); + ElementCollectionItem *lastItemForPath(const QString &path, QString &no_found_path); + ElementCollectionItem *childWithCollectionName(QString name) const; + QList directChilds() const; + int rowForInsertItem(const QString &name); + ElementCollectionItem *itemAtPath(const QString &path); - signals: - void beginInsertRows(ElementCollectionItem *parent, int first, int last); - void endInsertRows(); - void beginRemoveRows(ElementCollectionItem *parent, int first, int last); - void endRemoveRows(); - - protected: - ElementCollectionItem *m_parent_item; - QList m_child_items; - QString m_name; - Qt::GlobalColor m_bg_color; - bool m_show_bg_color = false; + QList elementsDirectChild() const; + QList directoriesDirectChild() const; + QList items() const; }; -#endif // ELEMENTCOLLECTIONITEM_H +#endif // ELEMENTCOLLECTIONITEM2_H diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp index 6f96eab6a..0aa1bdcdb 100644 --- a/sources/ElementsCollection/elementscollectionmodel.cpp +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -17,251 +17,76 @@ */ #include "elementscollectionmodel.h" #include "elementcollectionitem.h" -#include "qetapp.h" #include "fileelementcollectionitem.h" #include "xmlprojectelementcollectionitem.h" -#include "qetproject.h" +#include "qetapp.h" #include "xmlelementcollection.h" +#include "qetproject.h" +#include "elementcollectionhandler.h" /** * @brief ElementsCollectionModel::ElementsCollectionModel - * Defaut constructor - * @param parent : parent QObject + * Constructor + * @param parent */ ElementsCollectionModel::ElementsCollectionModel(QObject *parent) : - QAbstractItemModel (parent) + QStandardItemModel(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()) { - if (m_hide_element) { - if (child_item->isDir()) { - return createIndex(row, column, child_item); - } - else { - return QModelIndex(); - } - } - else { - 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()); - - if (m_hide_element) { - int count_ = 0; - - for (int i = 0 ; ichildCount() ; i++) - { - if (parent_item->child(i)->isDir()) { - count_ ++; - } - } - - return count_; - } - else { - 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 + * Reimplemented from QStandardItemModel * @param index * @param role - * @return the data of index for the given role or a default QVariant if no data. + * @return */ QVariant ElementsCollectionModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (role == Qt::DecorationRole) { + QStandardItem *item = itemFromIndex(index); - ElementCollectionItem *item = static_cast(index.internalPointer()); - return item->data(index.column(), role); -} + if (item->type() == FileElementCollectionItem::Type) + static_cast(item)->setUpIcon(); + else if (item->type() == XmlProjectElementCollectionItem::Type) + static_cast(item)->setUpIcon(); + } -/** - * @brief ElementsCollectionModel::removeRows - * Reimplemented from QAbstractItemModel - * @param row - * @param count - * @param parent - * @return true if rows was successfully removed - */ -bool ElementsCollectionModel::removeRows(int row, int count, const QModelIndex &parent) -{ - ElementCollectionItem *eci = nullptr; - if (!parent.isValid()) - eci = m_root_item; - else - eci = static_cast(parent.internalPointer()); - - if (!(1 <= row+count && row+count <= eci->childCount())) return false; - - beginRemoveRows(parent, row, (row + count -1)); - bool r = eci->removeChild(row, count); - endRemoveRows(); - - return r; + return QStandardItemModel::data(index, role); } /** * @brief ElementsCollectionModel::mimeData + * Reimplemented from QStandardItemModel * @param indexes - * @return the mime data of the items at @indexes + * @return */ QMimeData *ElementsCollectionModel::mimeData(const QModelIndexList &indexes) const { QModelIndex index = indexes.first(); if (index.isValid()) { - ElementCollectionItem *item = static_cast(index.internalPointer()); - return item->mimeData(); + ElementCollectionItem *item = static_cast(itemFromIndex(index)); + + QMimeData *mime_data = new QMimeData(); + mime_data->setText(item->collectionPath()); + + if (item->isElement()) + mime_data->setData("application/x-qet-element-uri", item->collectionPath().toLatin1()); + else + mime_data->setData("application/x-qet-category-uri", item->collectionPath().toLatin1()); + + return mime_data; } else return new QMimeData(); } /** - * @brief ElementsCollectionModel::flags - * @param index - * @return the flags of the item at @index + * @brief ElementsCollectionModel::mimeTypes + * Reimplemented from QStandardItemModel + * @return */ -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 (!(QAbstractItemModel::canDropMimeData(data, action, row, column, parent) && parent.isValid())) return false; - - ElementCollectionItem *eci = static_cast (parent.internalPointer()); - if (!eci) return false; - - return eci->canDropMimeData(data, action, row, column); -} - -bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if (!parent.isValid()) return false; - - ElementCollectionItem *eci = static_cast (parent.internalPointer()); - if (!eci || eci->isElement()) return false; - - m_parent_at_drop = parent; - - //We temporarily disconnect for avoid double insertion of item - foreach (QETProject *project, m_project_list) - disconnect(project->embeddedElementCollection(), &XmlElementCollection::elementAdded, this, &ElementsCollectionModel::elementIntegratedToCollection); - - - connect(eci, &ElementCollectionItem::beginInsertRows, this, &ElementsCollectionModel::bir); - connect(eci, &ElementCollectionItem::endInsertRows, this, &ElementsCollectionModel::endInsertRows); - connect(eci, &ElementCollectionItem::beginRemoveRows, this, &ElementsCollectionModel::brr); - connect(eci, &ElementCollectionItem::endRemoveRows, this, &ElementsCollectionModel::endRemoveRows); - - bool rb = eci->dropMimeData(data, action, row, column); - - disconnect(eci, &ElementCollectionItem::beginInsertRows, this, &ElementsCollectionModel::bir); - disconnect(eci, &ElementCollectionItem::endInsertRows, this, &ElementsCollectionModel::endInsertRows); - disconnect(eci, &ElementCollectionItem::beginRemoveRows, this, &ElementsCollectionModel::brr); - disconnect(eci, &ElementCollectionItem::endRemoveRows, this, &ElementsCollectionModel::endRemoveRows); - - foreach(QETProject *project, m_project_list) - connect(project->embeddedElementCollection(), &XmlElementCollection::elementAdded, this, &ElementsCollectionModel::elementIntegratedToCollection); - - m_parent_at_drop = QModelIndex(); - - return rb; -} - QStringList ElementsCollectionModel::mimeTypes() const { QStringList mime_list = QAbstractItemModel::mimeTypes(); @@ -270,25 +95,132 @@ QStringList ElementsCollectionModel::mimeTypes() const } /** - * @brief ElementsCollectionModel::items - * @return All items handled by this model. The root item isn't stored in the list + * @brief ElementsCollectionModel::canDropMimeData + * Reimplemented from QStandardItemModel + * @param data + * @param action + * @param row + * @param column + * @param parent + * @return */ -QList ElementsCollectionModel::items() const +bool ElementsCollectionModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { - QList list; - list.append(m_root_item->items()); - return list; + if (!(QStandardItemModel::canDropMimeData(data, action, row, column, parent) && parent.isValid())) + return false; + + QStandardItem *qsi = itemFromIndex(parent.child(row, column)); + if (!qsi) + qsi = itemFromIndex(parent); + + //Drop in the common collection is forbiden + if (qsi->type() == FileElementCollectionItem::Type) + if (static_cast(qsi)->isCommonCollection()) + return false; + + ElementCollectionItem *eci = static_cast(qsi); + + if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri")) { + return true; + //Return false if user try to drop a item from a folder to the same folder + ElementsLocation drop_location(data->text()); + for (int i=0 ; irowCount() ; i++) + if (static_cast(eci->child(i))->collectionPath() == drop_location.collectionPath()) + return false; + + return true; + } + else + return false; +} + +/** + * @brief ElementsCollectionModel::dropMimeData + * Reimplemented from QStandardItemModel + * @param data + * @param action + * @param row + * @param column + * @param parent + * @return + */ +bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + Q_UNUSED(action); + + QStandardItem *qsi = itemFromIndex(parent.child(row, column)); + if (!qsi) + qsi = itemFromIndex(parent); + + if (qsi->type() == FileElementCollectionItem::Type) { + FileElementCollectionItem *feci = static_cast(qsi); + + if (feci->isCommonCollection()) + return false; + + if (feci->isElement() && feci->parent() && feci->parent()->type() == FileElementCollectionItem::Type) + feci = static_cast(feci->parent()); + + ElementCollectionHandler ech; + + ElementsLocation source(data->text()); + ElementsLocation destination(feci->fileSystemPath()); + ElementsLocation location = ech.copy(source, destination); + + if (location.exist()) + { + //If feci have a child with the same path of location, + //we remove the existing child befor insert new child + for (int i=0 ; irowCount() ; i++) { + if (static_cast(feci->child(i))->collectionPath() == location.collectionPath()) + feci->removeRow(i); + } + feci->addChildAtPath(location.fileName()); + return true; + } + + return false; + } + else if (qsi->type() == XmlProjectElementCollectionItem::Type) { + XmlProjectElementCollectionItem *xpeci = static_cast(qsi); + + if (xpeci->isElement() && xpeci->parent() && xpeci->parent()->type() == XmlProjectElementCollectionItem::Type) + xpeci = static_cast(xpeci->parent()); + + //before do the copy, we get all collection path of xpeci child, + //for remove it if the copied item have the same path of an existing child. + //We can't do this after the copy, because at the copy if the xml collection have a DomElement with the same path, + //he was removed before the new xml DomElement is inserted + //So the existing child of this will return a null QString when call collectionPath(), because the item + //doesn't exist anymore in the xml collection. + QList child_path_list; + for (int i=0 ; irowCount() ; i++) + child_path_list.append(static_cast(xpeci->child(i, 0))->collectionPath()); + + ElementCollectionHandler ech; + + ElementsLocation source(data->text()); + ElementsLocation destination(xpeci->collectionPath()); + ElementsLocation location = ech.copy(source, destination); + + return location.exist(); + } + + return false; } /** * @brief ElementsCollectionModel::addCommonCollection * Add the common elements collection to this model */ -void ElementsCollectionModel::addCommonCollection() +void ElementsCollectionModel::addCommonCollection(bool set_data) { - FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item); - if (feci->setRootPath(QETApp::commonElementsDirN())) - m_root_item->appendChild(feci); + FileElementCollectionItem *feci = new FileElementCollectionItem(); + if (feci->setRootPath(QETApp::commonElementsDirN(), set_data, m_hide_element)) { + invisibleRootItem()->appendRow(feci); + if (set_data) + feci->setUpData(); + } else delete feci; } @@ -297,92 +229,124 @@ void ElementsCollectionModel::addCommonCollection() * @brief ElementsCollectionModel::addCustomCollection * Add the custom elements collection to this model */ -void ElementsCollectionModel::addCustomCollection() +void ElementsCollectionModel::addCustomCollection(bool set_data) { - FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item); - if (feci->setRootPath(QETApp::customElementsDirN())) - m_root_item->appendChild(feci); + FileElementCollectionItem *feci = new FileElementCollectionItem(); + if (feci->setRootPath(QETApp::customElementsDirN(), set_data, m_hide_element)) { + invisibleRootItem()->appendRow(feci); + if (set_data) + feci->setUpData(); + } else delete feci; } /** * @brief ElementsCollectionModel::addProject - * Add @project to the displayed collection - * @param project - * @return true if project was successfully added. If project is already - * handled, return false. + * Add project to this model + * @param project : project to add. + * @param set_data : if true, setUpData is called for every ElementCollectionItem of project */ -bool ElementsCollectionModel::addProject(QETProject *project) +void ElementsCollectionModel::addProject(QETProject *project, bool set_data) { - if (m_project_list.contains(project)) return false; + if (m_project_list.contains(project)) + return; m_project_list.append(project); int row = m_project_list.indexOf(project); - beginInsertRows(QModelIndex(), row, row); - XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(project, m_root_item); - bool r = m_root_item->insertChild(row, xpeci); - endInsertRows(); + XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(); + m_project_hash.insert(project, xpeci); + + xpeci->setProject(project); + insertRow(row, xpeci); + if (set_data) + xpeci->setUpData(); connect(project->embeddedElementCollection(), &XmlElementCollection::elementAdded, this, &ElementsCollectionModel::elementIntegratedToCollection); connect(project->embeddedElementCollection(), &XmlElementCollection::elementChanged, this, &ElementsCollectionModel::updateItem); - - return r; } /** * @brief ElementsCollectionModel::removeProject - * Remove @project from this model + * Remove project from this model * @param project - * @return true if the project was successfully removed, false if not (or project doesn't managed) */ -bool ElementsCollectionModel::removeProject(QETProject *project) +void ElementsCollectionModel::removeProject(QETProject *project) { - if (!m_project_list.contains(project)) return false; + if (!m_project_list.contains(project)) + return; int row = m_project_list.indexOf(project); if (removeRows(row, 1, QModelIndex())) { m_project_list.removeOne(project); + m_project_hash.remove(project); disconnect(project->embeddedElementCollection(), &XmlElementCollection::elementAdded, this, &ElementsCollectionModel::elementIntegratedToCollection); - connect(project->embeddedElementCollection(), &XmlElementCollection::elementChanged, this, &ElementsCollectionModel::updateItem); - return true; + disconnect(project->embeddedElementCollection(), &XmlElementCollection::elementChanged, this, &ElementsCollectionModel::updateItem); } - else - return false; } /** * @brief ElementsCollectionModel::project - * @return A list of project handled by this model + * @return every project added to this model */ -QList ElementsCollectionModel::project() const { +QList ElementsCollectionModel::project() const +{ return m_project_list; } /** - * @brief ElementsCollectionModel::index - * @param location - * @return Return the index of the item represented by location. - * index can be no valid + * @brief ElementsCollectionModel::items + * @return every ElementCollectionItem owned by this model */ -QModelIndex ElementsCollectionModel::index(const ElementsLocation &location) const +QList ElementsCollectionModel::items() const { - if (!location.exist()) { - return QModelIndex(); + QList list; + + for (int i=0 ; i(item(i)); + list.append(eci); + list.append(eci->items()); } + return list; +} + +/** + * @brief ElementsCollectionModel::hideElement + * Hide element in this model, only directory is managed + */ +void ElementsCollectionModel::hideElement() +{ + m_hide_element = true; + foreach(ElementCollectionItem *eci, items()) { + if (eci->isElement()) { + removeRow(eci->row(), indexFromItem(eci).parent()); + } + } +} + +/** + * @brief ElementsCollectionModel::indexFromLocation + * Return the index who represent @location. + * Index can be non valid + * @param location + * @return + */ +QModelIndex ElementsCollectionModel::indexFromLocation(const ElementsLocation &location) +{ + if (!location.exist()) + return QModelIndex(); + QList child_list; - for (int i=0 ; ichildCount() ; i++) { - child_list.append(m_root_item->child(i)); - } + for (int i=0 ; i(item(i))); foreach(ElementCollectionItem *eci, child_list) { ElementCollectionItem *match_eci = nullptr; if (eci->type() == FileElementCollectionItem::Type) { - FileElementCollectionItem *feci = static_cast(eci); - if (feci) { + if (FileElementCollectionItem *feci = static_cast(eci)) { if ( (location.isCommonCollection() && feci->isCommonCollection()) || (location.isCustomCollection() && !feci->isCommonCollection()) ) { match_eci = feci->itemAtPath(location.collectionPath(false)); @@ -390,59 +354,30 @@ QModelIndex ElementsCollectionModel::index(const ElementsLocation &location) con } } else if (eci->type() == XmlProjectElementCollectionItem::Type) { - XmlProjectElementCollectionItem *xpeci = static_cast(eci); - if (xpeci) { + if (XmlProjectElementCollectionItem *xpeci = static_cast(eci)) { match_eci = xpeci->itemAtPath(location.collectionPath(false)); } } - if (match_eci) { - return createIndex(match_eci->row(), 0, match_eci); - } + if (match_eci) + return indexFromItem(match_eci); } return QModelIndex(); } /** - * @brief ElementsCollectionModel::hideElement - * Hide element. - * Only directory is provided by the model - */ -void ElementsCollectionModel::hideElement() -{ - m_hide_element = true; -} - -/** - * @brief ElementsCollectionModel::itemForProject - * @param project - * @return the root item of project @project, or nullptr if not found. - */ -XmlProjectElementCollectionItem *ElementsCollectionModel::itemForProject(QETProject *project) -{ - if (!m_project_list.contains(project)) return nullptr; - QModelIndex index_ = index(m_project_list.indexOf(project), 0); - if (!index_.isValid()) return nullptr; - - XmlProjectElementCollectionItem *xpeci = static_cast(index_.internalPointer()); - if (xpeci) - return xpeci; - else - return nullptr; -} - -/** - * @brief ElementsCollectionModel::elementAddedToEmbeddedCollection + * @brief ElementsCollectionModel::elementIntegratedToCollection * When an element is added to embedded collection of a project, * this method create and display the new element * @param path -The path of the new element in the embedded collection of a project */ -void ElementsCollectionModel::elementIntegratedToCollection (QString path) +void ElementsCollectionModel::elementIntegratedToCollection(QString path) { QObject *object = sender(); XmlElementCollection *collection = static_cast (object); - if (!collection) return; + if (!collection) + return; QETProject *project = nullptr; @@ -454,19 +389,14 @@ void ElementsCollectionModel::elementIntegratedToCollection (QString path) } if (project) { - XmlProjectElementCollectionItem *xpeci = itemForProject(project); - if (!xpeci) return; + XmlProjectElementCollectionItem *xpeci = m_project_hash.value(project); QString collection_name; ElementCollectionItem *eci = xpeci->lastItemForPath(path, collection_name); - if (!eci) return; + if (!eci) + return; - int new_row = eci->rowForInsertItem(collection_name); - if (new_row <= -1) return; - QModelIndex parent_index = createIndex(eci->row(), 0, eci); - beginInsertRows(parent_index, new_row, new_row); - eci->insertNewItem(collection_name); - endInsertRows(); + eci->addChildAtPath(collection_name); } } @@ -479,7 +409,8 @@ void ElementsCollectionModel::updateItem(QString path) { QObject *object = sender(); XmlElementCollection *collection = static_cast (object); - if (!collection) return; + if (!collection) + return; QETProject *project = nullptr; @@ -491,30 +422,11 @@ void ElementsCollectionModel::updateItem(QString path) } if (project) { - XmlProjectElementCollectionItem *xpeci = itemForProject(project); - if (!xpeci) { + ElementCollectionItem *eci = m_project_hash.value(project)->itemAtPath(path); + if (!eci) return; - } - - ElementCollectionItem *eci = xpeci->itemAtPath(path); - if (!eci) { - return; - } eci->clearData(); + eci->setUpData(); } } - -void ElementsCollectionModel::bir(ElementCollectionItem *eci, int first, int last) -{ - Q_UNUSED(eci); - if (!m_parent_at_drop.isValid()) return; - beginInsertRows(m_parent_at_drop, first, last); -} - -void ElementsCollectionModel::brr(ElementCollectionItem *eci, int first, int last) -{ - Q_UNUSED(eci); - if (!m_parent_at_drop.isValid()) return; - beginRemoveRows(m_parent_at_drop, first, last); -} diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h index bde496463..19a0c183f 100644 --- a/sources/ElementsCollection/elementscollectionmodel.h +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -15,66 +15,51 @@ You should have received a copy of the GNU General Public License along with QElectroTech. If not, see . */ -#ifndef ELEMENTSCOLLECTIONMODEL_H -#define ELEMENTSCOLLECTIONMODEL_H +#ifndef ELEMENTSCOLLECTIONMODEL2_H +#define ELEMENTSCOLLECTIONMODEL2_H -#include +#include #include "elementslocation.h" -class ElementCollectionItem; -class QETProject; class QList; class XmlProjectElementCollectionItem; +class QHash; +class ElementCollectionItem; +class QList; -/** - * @brief The ElementsCollectionModel class - * Provide a data model for co;llection of elements. - */ -class ElementsCollectionModel : public QAbstractItemModel +class ElementsCollectionModel : public QStandardItemModel { - Q_OBJECT + 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 bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + ElementsCollectionModel(QObject *parent = Q_NULLPTR); + virtual QVariant data(const QModelIndex &index, int role) const; virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QStringList mimeTypes() 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; - QList items() const; - void addCommonCollection(); - void addCustomCollection(); - bool addProject(QETProject *project); - bool removeProject(QETProject *project); + void addCommonCollection(bool set_data = true); + void addCustomCollection(bool set_data = true); + + void addProject(QETProject *project, bool set_data = true); + void removeProject(QETProject *project); QList project() const; - QModelIndex index(const ElementsLocation &location) const; + + QList items() const; void hideElement(); + bool isHideElement() {return m_hide_element;} + QModelIndex indexFromLocation(const ElementsLocation &location); private: - XmlProjectElementCollectionItem *itemForProject(QETProject *project); void elementIntegratedToCollection (QString path); void updateItem (QString path); - //Use as slot in method drop mime data - void bir(ElementCollectionItem *eci, int first, int last); - void brr(ElementCollectionItem *eci, int first, int last); private: - ElementCollectionItem *m_root_item; QList m_project_list; - QModelIndex m_parent_at_drop; + QHash m_project_hash; bool m_hide_element = false; }; -#endif // ELEMENTSCOLLECTIONMODEL_H +#endif // ELEMENTSCOLLECTIONMODEL2_H diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index 1d5700b44..147d7ed8c 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -34,6 +34,7 @@ #include #include #include +#include /** * @brief ElementsCollectionWidget::ElementsCollectionWidget @@ -47,8 +48,6 @@ ElementsCollectionWidget::ElementsCollectionWidget(QWidget *parent): setUpWidget(); setUpAction(); setUpConnection(); - - reload(); } /** @@ -57,18 +56,13 @@ ElementsCollectionWidget::ElementsCollectionWidget(QWidget *parent): */ void ElementsCollectionWidget::expandFirstItems() { + if (!m_model) + return; + 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; -} - /** * @brief ElementsCollectionWidget::addProject * Add @project to be displayed @@ -82,6 +76,16 @@ void ElementsCollectionWidget::removeProject(QETProject *project) { m_model->removeProject(project); } +bool ElementsCollectionWidget::event(QEvent *event) +{ + if (m_first_show && event->type() == QEvent::WindowActivate) { + m_first_show = false; + QTimer::singleShot(250, this, &ElementsCollectionWidget::reload); + } + + return QWidget::event(event); +} + void ElementsCollectionWidget::setUpAction() { m_open_dir = new QAction(QET::Icons::DocumentOpen, tr("Ouvrir le dossier correspondant"), this); @@ -249,7 +253,7 @@ void ElementsCollectionWidget::editElement() foreach (QETElementEditor *element_editor, app->elementEditors()) { if (element_editor->isEditing(location)) - connect(element_editor, &QETElementEditor::destroyed, eci, &ElementCollectionItem::clearData); + connect(element_editor, &QETElementEditor::destroyed, [eci](){ eci->clearData(); eci->setUpData();}); } } @@ -393,7 +397,7 @@ void ElementsCollectionWidget::showThisDir() { ElementCollectionItem *eci = elementCollectionItemForIndex(m_showed_index); if (eci) - eci->setBackgroundColor(Qt::yellow, false); + eci->setBackground(QBrush()); } m_showed_index = m_index_at_context_menu; @@ -403,7 +407,7 @@ void ElementsCollectionWidget::showThisDir() showAndExpandItem(m_showed_index, true, true); ElementCollectionItem *eci = elementCollectionItemForIndex(m_showed_index); if (eci) - eci->setBackgroundColor(Qt::yellow, true); + eci->setBackground(QBrush(Qt::yellow)); search(m_search_field->text()); } else @@ -421,7 +425,7 @@ void ElementsCollectionWidget::resetShowThisDir() { ElementCollectionItem *eci = elementCollectionItemForIndex(m_showed_index); if (eci) - eci->setBackgroundColor(Qt::yellow, false); + eci->setBackground(QBrush()); } m_showed_index = QModelIndex(); @@ -435,19 +439,19 @@ void ElementsCollectionWidget::reload() { m_progress_bar->show(); ElementsCollectionModel *new_model = new ElementsCollectionModel(m_tree_view); - new_model->addCommonCollection(); - new_model->addCustomCollection(); + new_model->addCommonCollection(false); + new_model->addCustomCollection(false); if (m_model) foreach (QETProject *project, m_model->project()) - new_model->addProject(project); + new_model->addProject(project, false); QList list = new_model->items(); m_progress_bar->setMaximum(list.size()); m_progress_bar->setValue(0); foreach (ElementCollectionItem *item, new_model->items()) { - item->name(); + item->setUpData(); m_progress_bar->setValue(m_progress_bar->value() + 1); } @@ -493,7 +497,6 @@ void ElementsCollectionWidget::search(const QString &text) } hideCollection(true); - QStringList text_list = text.split("+", QString::SkipEmptyParts); QModelIndexList match_index; foreach (QString txt, text_list) { @@ -543,11 +546,13 @@ void ElementsCollectionWidget::hideItem(bool hide, const QModelIndex &index, boo */ void ElementsCollectionWidget::showAndExpandItem(const QModelIndex &index, bool parent, bool child) { - if (parent && index.isValid()) - showAndExpandItem(index.parent(), parent); + if (index.isValid()) { + if (parent) + showAndExpandItem(index.parent(), parent); - hideItem(false, index, child); - m_tree_view->expand(index); + hideItem(false, index, child); + m_tree_view->expand(index); + } } /** @@ -556,5 +561,5 @@ void ElementsCollectionWidget::showAndExpandItem(const QModelIndex &index, bool * @return The internal pointer of index casted to ElementCollectionItem; */ ElementCollectionItem *ElementsCollectionWidget::elementCollectionItemForIndex(const QModelIndex &index) { - return static_cast(index.internalPointer()); + return static_cast(m_model->itemFromIndex(index)); } diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index 9f5697bee..80c1f5fca 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -44,11 +44,13 @@ class ElementsCollectionWidget : public QWidget ElementsCollectionWidget(QWidget *parent = nullptr); void expandFirstItems(); - ElementsCollectionModel *model() const; void addProject (QETProject *project); void removeProject (QETProject *project); + protected: + virtual bool event(QEvent *event); + private: void setUpAction(); void setUpWidget(); @@ -70,11 +72,11 @@ class ElementsCollectionWidget : public QWidget void showAndExpandItem (const QModelIndex &index, bool parent = true, bool child = false); ElementCollectionItem *elementCollectionItemForIndex (const QModelIndex &index); - private: - ElementsCollectionModel *m_model; + private: + ElementsCollectionModel *m_model; QLineEdit *m_search_field; ElementsTreeView *m_tree_view; - QVBoxLayout *m_main_vlayout; + QVBoxLayout *m_main_vlayout; QMenu *m_context_menu; QModelIndex m_index_at_context_menu; QModelIndex m_showed_index; @@ -90,6 +92,8 @@ class ElementsCollectionWidget : public QWidget *m_new_element, *m_show_this_dir, *m_show_all_dir; + + bool m_first_show = true; }; #endif // ELEMENTSCOLLECTIONWIDGET_H diff --git a/sources/ElementsCollection/elementstreeview.cpp b/sources/ElementsCollection/elementstreeview.cpp index 467aac4bf..65a03d316 100644 --- a/sources/ElementsCollection/elementstreeview.cpp +++ b/sources/ElementsCollection/elementstreeview.cpp @@ -23,6 +23,7 @@ #include "element.h" #include +#include static int MAX_DND_PIXMAP_WIDTH = 500; static int MAX_DND_PIXMAP_HEIGHT = 375; @@ -49,18 +50,16 @@ void ElementsTreeView::startDrag(Qt::DropActions supportedActions) return; } - ElementCollectionItem *eci = static_cast(index.internalPointer()); - - if (!eci) { - QTreeView::startDrag(supportedActions); - return; + if (QStandardItemModel *qsim = static_cast(model())) { + if (ElementCollectionItem *eci = static_cast(qsim->itemFromIndex(index))) { + ElementsLocation loc (eci->collectionPath()); + if (loc.exist()) { + startElementDrag(loc); + return; + } + } } - - ElementsLocation loc (eci->collectionPath()); - if (loc.exist()) - startElementDrag(loc); - else - QTreeView::startDrag(supportedActions); + QTreeView::startDrag(supportedActions); } /** diff --git a/sources/ElementsCollection/fileelementcollectionitem.cpp b/sources/ElementsCollection/fileelementcollectionitem.cpp index 0e042c5a8..5bba95029 100644 --- a/sources/ElementsCollection/fileelementcollectionitem.cpp +++ b/sources/ElementsCollection/fileelementcollectionitem.cpp @@ -1,41 +1,33 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ + #include "fileelementcollectionitem.h" -#include "qetapp.h" #include "elementslocation.h" -#include "nameslist.h" +#include "qetapp.h" #include "qeticons.h" -#include "elementcollectionhandler.h" + +#include /** * @brief FileElementCollectionItem::FileElementCollectionItem - * Default constructor - * @param parent : parent item of this item + * Constructor */ -FileElementCollectionItem::FileElementCollectionItem(ElementCollectionItem *parent) : - ElementCollectionItem(parent) -{} - -/** - * @brief FileElementCollectionItem::~FileElementCollectionItem - * Destructor - */ -FileElementCollectionItem::~FileElementCollectionItem() +FileElementCollectionItem::FileElementCollectionItem() {} /** @@ -45,16 +37,15 @@ FileElementCollectionItem::~FileElementCollectionItem() * @param path * @return true if path exist. */ -bool FileElementCollectionItem::setRootPath(QString path) +bool FileElementCollectionItem::setRootPath(QString path, bool set_data, bool hide_element) { - QDir dir(path); - - if (dir.exists()) - { + QDir dir(path); + if (dir.exists()) { m_path = path; - populate(); + populate(set_data, hide_element); return true; } + return false; } @@ -64,226 +55,29 @@ bool FileElementCollectionItem::setRootPath(QString path) */ QString FileElementCollectionItem::fileSystemPath() const { - //Parent must be a file element collection item - if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type) + if (isCollectionRoot()) return m_path; - FileElementCollectionItem *parent = static_cast(m_parent_item); - - //Get the path of the parent. -// if (parent->isCollectionRoot()) -// return parent->fileSystemPath() + m_path; -// else -// return parent->fileSystemPath() + "/" + m_path; - return parent->fileSystemPath() + "/" + 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::commonElementsDirN()) - 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; - } + FileElementCollectionItem *feci = static_cast (parent()); + if (feci) + return feci->fileSystemPath() + "/" + m_path; else return QString(); } /** - * @brief FileElementCollectionItem::collectionName - * @return The collection name of this item + * @brief FileElementCollectionItem::dirPath + * @return the dir path of this item (if this item is a dir return the path, + * if item is an element return the path of the parent directory) */ -QString FileElementCollectionItem::collectionName() const -{ - if (isCollectionRoot()) return QString(); - else return m_path; -} - -/** - * @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 > 0) - return QVariant(); - - switch (role) - { - case Qt::DisplayRole: { - 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::commonElementsDirN()) - 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()) - { - ElementsLocation loc(collectionPath()); - m_icon = loc.icon(); - } - return m_icon; - } - } - case Qt::ToolTipRole: - return collectionPath(); - break; - default: - return ElementCollectionItem::data(column, role); - break; - } -} - -/** - * @brief FileElementCollectionItem::clearData - * Reset the current icon - */ -void FileElementCollectionItem::clearData() -{ - m_icon = QIcon(); - ElementCollectionItem::clearData(); -} - -/** - * @brief FileElementCollectionItem::mimeData - * @return the mime data of this item - */ -QMimeData *FileElementCollectionItem::mimeData() -{ - QMimeData *mime_data = new QMimeData(); - mime_data->setText(collectionPath()); - - if (isElement()) - mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1()); - else - mime_data->setData("application/x-qet-category-uri", collectionPath().toLatin1()); - - return mime_data; -} - -/** - * @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 row, int column) const -{ - Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - if (isCommonCollection()) return false; - - if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri")) - { - //Return false if user try to drop a item from a folder to the same folder - ElementsLocation drop_location(data->text()); - for (int i=0 ; i(child(i))->collectionPath() == drop_location.collectionPath()) - return false; - } - - 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 row, int column) -{ - Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - if (isCommonCollection()) return false; - - FileElementCollectionItem *feci = this; - if (isElement() && parent() && parent()->type() == FileElementCollectionItem::Type) - feci = static_cast(parent()); - - ElementCollectionHandler ech; - - ElementsLocation source(data->text()); - ElementsLocation destination(feci->fileSystemPath()); - ElementsLocation location = ech.copy(source, destination); - - if (location.exist()) - { - //If this item have a child with the same path of location, - //we remove the existing child befor insert new child - for (int i=0 ; i(child(i))->collectionPath() == location.collectionPath()) - removeChild(i, 1); - - insertNewItem(location.fileName()); - return true; - } - - return false; -} - -/** - * @brief FileElementCollectionItem::flags - * @return the flags of this item - */ -Qt::ItemFlags FileElementCollectionItem::flags() +QString FileElementCollectionItem::dirPath() const { if (isDir()) - return (Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + return fileSystemPath(); + else if (parent() && parent()->type() == FileElementCollectionItem::Type) + return static_cast(parent())->fileSystemPath(); else - return (Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); + return QString(); } /** @@ -296,16 +90,98 @@ bool FileElementCollectionItem::isDir() const return false; else return true; + } /** * @brief FileElementCollectionItem::isElement * @return true if this item represent an element */ -bool FileElementCollectionItem::isElement() const { +bool FileElementCollectionItem::isElement() const +{ return (!isDir()); } +/** + * @brief FileElementCollectionItem::localName + * @return the located name of this item + */ +QString FileElementCollectionItem::localName() +{ + if (!text().isNull()) + return text(); + + else if (isDir()) { + if (isCollectionRoot()) { + if (m_path == QETApp::commonElementsDirN()) + setText(QObject::tr("Collection QET")); + else if (m_path == QETApp::customElementsDirN()) + setText(QObject::tr("Collection utilisateur")); + else + setText(QObject::tr("Collection inconnue")); + } + else { + //Open the qet_directory file, to get the traductions name of this dir + QFile dir_conf(fileSystemPath() + "/qet_directory"); + + if (dir_conf.exists() && dir_conf.open(QIODevice::ReadOnly | QIODevice::Text)) { + + //Get the content of the file + QDomDocument document; + if (document.setContent(&dir_conf)) { + QDomElement root = document.documentElement(); + if (root.tagName() == "qet-directory") { + NamesList nl; + nl.fromXml(root); + setText(nl.name()); + } + } + } + } + } + else if (isElement()) { + ElementsLocation loc(collectionPath()); + setText(loc.name()); + } + + return text(); +} + +/** + * @brief FileElementCollectionItem::name + * @return The collection name of this item + */ +QString FileElementCollectionItem::name() const +{ + if (isCollectionRoot()) + return QString(); + else + return m_path; +} + +/** + * @brief FileElementCollectionItem::collectionPath + * @return The path of this item relative to the collection. + */ +QString FileElementCollectionItem::collectionPath() const +{ + if (isCollectionRoot()) { + if (m_path == QETApp::commonElementsDirN()) + return "common://"; + else + return "custom://"; + } + else if (parent() && parent()->type() == FileElementCollectionItem::Type) { + ElementCollectionItem *eci = static_cast(parent()); + if (eci->isCollectionRoot()) + return eci->collectionPath() + m_path; + else + return eci->collectionPath() + "/" + m_path; + } + else + return QString(); +} + /** * @brief FileElementCollectionItem::isCollectionRoot * @return true if this item represent the root of collection @@ -320,84 +196,70 @@ bool FileElementCollectionItem::isCollectionRoot() const /** * @brief FileElementCollectionItem::isCommonCollection - * @return True if this item is part of the common element collection item + * @return True if this item represent the common collection */ -bool FileElementCollectionItem::isCommonCollection() const { +bool FileElementCollectionItem::isCommonCollection() const +{ return fileSystemPath().startsWith(QETApp::commonElementsDirN()); } /** - * @brief FileElementCollectionItem::isValid - * @return + * @brief FileElementCollectionItem::addChildAtPath + * Ask to this item item to add a child with collection name @collection_name + * @param collection_name */ -bool FileElementCollectionItem::isValid() const +void FileElementCollectionItem::addChildAtPath(const QString &collection_name) { - return true; - if (m_path.isEmpty()) - return false; - else - return true; + if (collection_name.isEmpty()) + return; + + FileElementCollectionItem *feci = new FileElementCollectionItem(); + insertRow(rowForInsertItem(collection_name), feci); + feci->setPathName(collection_name); + feci->setUpData(); } /** - * @brief FileElementCollectionItem::name - * @return the located name of this item + * @brief FileElementCollectionItem::setUpData + * SetUp the data of this item */ -QString FileElementCollectionItem::name() +void FileElementCollectionItem::setUpData() { - if (!m_name.isNull()) return m_name; + //Setup the displayed name + localName(); - else if (isDir()) - { - if (isCollectionRoot()) - { - if (m_path == QETApp::commonElementsDirN()) - m_name = QObject::tr("Collection QET"); - else if (m_path == QETApp::customElementsDirN()) - m_name = QObject::tr("Collection utilisateur"); - else - m_name = QObject::tr("Collection inconnue"); - } - else - { - //Open the qet_directory file, to get the traductions name of this dir - QFile dir_conf(fileSystemPath() + "/qet_directory"); - if (!dir_conf.exists()) - m_name = QString(""); + if (isDir()) + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + else + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); - 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()) - { - ElementsLocation loc(collectionPath()); - m_name = loc.name(); - } - return m_name; + setToolTip(collectionPath()); } -void FileElementCollectionItem::insertNewItem(const QString &collection_name) +/** + * @brief FileElementCollectionItem::setUpIcon + * SetUp the icon of this item. + * Because icon use several memory, we use this method for setup icon instead setUpData. + */ +void FileElementCollectionItem::setUpIcon() { - if (collection_name.isEmpty()) return; + if (!icon().isNull()) + return; - FileElementCollectionItem *feci = new FileElementCollectionItem(this); - feci->setPathName(collection_name); - insertChild(rowForInsertItem(collection_name), feci); + if (isCollectionRoot()) { + if (m_path == QETApp::commonElementsDirN()) + setIcon(QIcon(":/ico/16x16/qet.png")); + else + setIcon(QIcon(":/ico/16x16/go-home.png")); + } + else { + if (isDir()) + setIcon(QET::Icons::Folder); + else { + ElementsLocation loc(collectionPath()); + setIcon(loc.icon()); + } + } } /** @@ -407,39 +269,45 @@ void FileElementCollectionItem::insertNewItem(const QString &collection_name) * For create a new file collection see setRootPath. * @param path_name */ -void FileElementCollectionItem::setPathName(QString path_name) +void FileElementCollectionItem::setPathName(QString path_name, bool set_data, bool hide_element) { - if (!m_parent_item) return; - m_path = path_name; //This isn't an element, we create the childs if (!path_name.endsWith(".elmt")) - populate(); + populate(set_data, hide_element); } /** * @brief FileElementCollectionItem::populate - * Item populate itself with childs found in the system path. + * Create the childs of this item + * @param set_data : if true, call setUpData for every child of this item */ -void FileElementCollectionItem::populate() +void FileElementCollectionItem::populate(bool set_data, bool hide_element) { 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); + FileElementCollectionItem *feci = new FileElementCollectionItem(); + appendRow(feci); + feci->setPathName(str, set_data, hide_element); + if (set_data) + feci->setUpData(); } + if (hide_element) + return; + //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); + FileElementCollectionItem *feci = new FileElementCollectionItem(); + appendRow(feci); + feci->setPathName(str, set_data); + if (set_data) + feci->setUpData(); } } diff --git a/sources/ElementsCollection/fileelementcollectionitem.h b/sources/ElementsCollection/fileelementcollectionitem.h index b6b67d7aa..d54f80055 100644 --- a/sources/ElementsCollection/fileelementcollectionitem.h +++ b/sources/ElementsCollection/fileelementcollectionitem.h @@ -1,27 +1,24 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ -#ifndef FILEELEMENTCOLLECTIONITEM_H -#define FILEELEMENTCOLLECTIONITEM_H +#ifndef FILEELEMENTCOLLECTIONITEM2_H +#define FILEELEMENTCOLLECTIONITEM2_H #include "elementcollectionitem.h" -#include -#include -#include /** * @brief The FileElementCollectionItem class @@ -30,45 +27,37 @@ */ class FileElementCollectionItem : public ElementCollectionItem { - Q_OBJECT + public: + FileElementCollectionItem(); - public: - FileElementCollectionItem(ElementCollectionItem *parent = nullptr); - ~FileElementCollectionItem(); + enum { Type = UserType+2 }; + virtual int type() const { return Type;} - enum {Type = UserType + 1}; - virtual int type() const {return Type;} - - bool setRootPath(QString path); + bool setRootPath(QString path, bool set_data = true, bool hide_element = false); QString fileSystemPath() const; QString dirPath() const; - QString collectionPath() const; - QString collectionName() const; - - virtual QVariant data(int column, int role); - virtual void clearData(); - virtual QMimeData *mimeData(); - virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column); - virtual Qt::ItemFlags flags(); - virtual bool isDir() const; virtual bool isElement() const; + virtual QString localName(); + virtual QString name() const; + virtual QString collectionPath() const; virtual bool isCollectionRoot() const; bool isCommonCollection() const; - virtual bool isValid() const; - virtual QString name(); + virtual void addChildAtPath(const QString &collection_name); - virtual void insertNewItem(const QString &collection_name); + void setUpData(); + void setUpIcon(); - private: - void setPathName(QString path_name); - void populate(); + void hire(); - private: + + private: + void setPathName(QString path_name, bool set_data = true, bool hide_element = false); + void populate(bool set_data = true, bool hide_element = false); + + private: QString m_path; - QIcon m_icon; }; -#endif // FILEELEMENTCOLLECTIONITEM_H +#endif // FILEELEMENTCOLLECTIONITEM2_H diff --git a/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp b/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp index 7b5dda0fa..3e9b107ba 100644 --- a/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp +++ b/sources/ElementsCollection/xmlprojectelementcollectionitem.cpp @@ -1,266 +1,32 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ -#include "xmlprojectelementcollectionitem.h" #include "qetproject.h" -#include "qeticons.h" #include "xmlelementcollection.h" -#include "nameslist.h" -#include "qetapp.h" -#include "elementcollectionhandler.h" -#include +#include "qeticons.h" +#include "xmlprojectelementcollectionitem.h" /** * @brief XmlProjectElementCollectionItem::XmlProjectElementCollectionItem - * Default constructor. - * @param project -project for this item - * @param parent -paretn item + * Constructor */ -XmlProjectElementCollectionItem::XmlProjectElementCollectionItem(QETProject *project, ElementCollectionItem *parent) : - ElementCollectionItem(parent), - m_project(project) -{ - m_dom_element = project->embeddedElementCollection()->root(); - populate(); -} - -/** - * @brief XmlProjectElementCollectionItem::XmlProjectElementCollectionItem - * Private constructor - * @param project -project for this item - * @param dom_element: the dom_element must represent this item - * @param parent - */ -XmlProjectElementCollectionItem::XmlProjectElementCollectionItem(QETProject *project, const QDomElement &dom_element, ElementCollectionItem *parent) : - ElementCollectionItem(parent), - m_project(project), - m_dom_element(dom_element) -{ - populate(); -} - -/** - * @brief XmlProjectElementCollectionItem::~XmlProjectElementCollectionItem - */ -XmlProjectElementCollectionItem::~XmlProjectElementCollectionItem() +XmlProjectElementCollectionItem::XmlProjectElementCollectionItem() {} -/** - * @brief XmlProjectElementCollectionItem::data - * The data used by the view who display this item through the model - * @param column - * @param role - * @return - */ -QVariant XmlProjectElementCollectionItem::data(int column, int role) -{ - if (column > 0) - return QVariant(); - - switch (role) - { - case Qt::DisplayRole: - return name(); - break; - case Qt::DecorationRole: - if (isCollectionRoot()) - return QIcon(QET::Icons::ProjectFileGP); - else if (isDir()) - return QET::Icons::Folder; - else - { - if (m_icon.isNull()) - { - ElementsLocation loc(embeddedPath(), m_project); - m_icon = loc.icon(); - } - return m_icon; - } - break; - case Qt::ToolTipRole: - if (isCollectionRoot()) - return m_project->filePath(); - else - return collectionPath(); - break; - default: - return ElementCollectionItem::data(column, role); - } -} - -void XmlProjectElementCollectionItem::clearData() -{ - m_icon = QIcon(); - ElementCollectionItem::clearData(); -} - -/** - * @brief XmlProjectElementCollectionItem::mimeData - * @return The mimedata of this item - */ -QMimeData *XmlProjectElementCollectionItem::mimeData() -{ - QMimeData *mime_data = new QMimeData(); - mime_data->setText(collectionPath()); - - if (isElement()) - mime_data->setData("application/x-qet-element-uri", collectionPath().toLatin1()); - else - mime_data->setData("application/x-qet-category-uri", collectionPath().toLatin1()); - - return mime_data; -} - -/** - * @brief XmlProjectElementCollectionItem::canDropMimeData - * @param data - * @param action - * @param row - * @param column - * @return True if the data can be dropped - */ -bool XmlProjectElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const -{ - Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - - if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri")) - { - //Return false if user try to drop a item from a folder to the same folder - ElementsLocation drop_location(data->text()); - for (int i=0 ; i(child(i))->collectionPath() == drop_location.collectionPath()) - return false; - } - - return true; - } - else - return false; -} - -/** - * @brief XmlProjectElementCollectionItem::dropMimeData - * @param data - * @param action - * @param row - * @param column - * @return handle a drop of a mime data - */ -bool XmlProjectElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) -{ - Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column); - - XmlProjectElementCollectionItem *xpeci = this; - if (isElement() && parent() && parent()->type() == XmlProjectElementCollectionItem::Type) - xpeci = static_cast(parent()); - - //before do the copy, we get all collection path of child, - //for remove it if the copied item have the same path of an existing child. - //We can't do this after the copy, because at the copy if the xml collection have a DomElement with the same path, - //he was removed before the new xml DomElement is inserted - //So the existing child of this will return a null QString when call collectionPath(), because the item - //doesn't exist anymore in the xml collection. - QList child_path_list; - for (int i=0 ; i(child(i))->collectionPath()); - - ElementCollectionHandler ech; - - ElementsLocation source(data->text()); - ElementsLocation destination(xpeci->collectionPath()); - ElementsLocation location = ech.copy(source, destination); - - if (location.exist()) - { - //If this item have a child with the same path of location, we remove the existing child before insert new child - for (int i=0 ; itype() != XmlProjectElementCollectionItem::Type) return true; - else return false; -} - -/** - * @brief XmlProjectElementCollectionItem::name - * @return The name of this item, name is notably use for Qt::DisplayRole data - */ -QString XmlProjectElementCollectionItem::name() -{ - if (!m_name.isNull()) return m_name; - - if (isCollectionRoot()) - { - if (m_project->title().isEmpty()) - return QString("Projet sans titre"); - else - return m_project->title(); - } - else - { - ElementsLocation location (embeddedPath(), m_project); - m_name = location.name(); - return m_name; - } -} - -/** - * @brief XmlProjectElementCollectionItem::isValid - * @return Always true - */ -bool XmlProjectElementCollectionItem::isValid() const { - return true; -} - -/** - * @brief XmlProjectElementCollectionItem::project - * @return The project for this collection item - */ -QETProject *XmlProjectElementCollectionItem::project() const { - return m_project; -} - /** * @brief XmlProjectElementCollectionItem::isDir * @return true if this item represent a directory @@ -281,15 +47,49 @@ bool XmlProjectElementCollectionItem::isElement() const else return false; } +/** + * @brief XmlProjectElementCollectionItem::localName + * @return the located name of this item + */ +QString XmlProjectElementCollectionItem::localName() +{ + if (!text().isNull()) + return text(); + + if (isCollectionRoot()) { + if (m_project->title().isEmpty()) + setText(QObject::tr("Projet sans titre")); + else + setText(m_project->title()); + } + else { + ElementsLocation location (embeddedPath(), m_project); + setText(location.name()); + } + + return text(); +} + +/** + * @brief XmlProjectElementCollectionItem::name + * @return The collection name of this item + */ +QString XmlProjectElementCollectionItem::name() const +{ + return m_dom_element.attribute("name"); +} + /** * @brief XmlProjectElementCollectionItem::collectionPath - * @return The collection path of this item. - * The path is in form : project0+embed://dir/subdir/myElement.elmt + * @return The path of this item relative to the collection. */ QString XmlProjectElementCollectionItem::collectionPath() const { ElementsLocation loc (embeddedPath(), m_project); - return loc.projectCollectionPath(); + QString p = loc.projectCollectionPath(); + if (p.isEmpty()) + p = QObject::tr("Collection"); + return p; } /** @@ -300,37 +100,42 @@ QString XmlProjectElementCollectionItem::collectionPath() const QString XmlProjectElementCollectionItem::embeddedPath() const { if (isCollectionRoot()) - { return "embed://"; + else if (parent()){ + XmlProjectElementCollectionItem *xpeci = static_cast(parent()); + + if (xpeci->isCollectionRoot()) + return xpeci->embeddedPath() + name(); + else + return xpeci->embeddedPath() + "/" + name(); } else - { - XmlProjectElementCollectionItem *parent = static_cast(m_parent_item); - - if (parent->isCollectionRoot()) - return parent->embeddedPath() + collectionName(); - else - return parent->embeddedPath() + "/" + collectionName(); - } + return QString(); } /** - * @brief XmlProjectElementCollectionItem::collectionName - * @return The collection name of this item + * @brief XmlProjectElementCollectionItem::isCollectionRoot + * @return true if this item represent the root of collection */ -QString XmlProjectElementCollectionItem::collectionName() const { - return m_dom_element.attribute("name"); -} - -/** - * @brief XmlProjectElementCollectionItem::insertNewItem - * When this XmlProjectElementCollectionItem is already created, we must to use this method for insert a new item. - * Befor use this, see rowForInsertItem and lastItemForPath - * @param collection_name : the collection name to search in the child of QDomElement. - */ -void XmlProjectElementCollectionItem::insertNewItem(const QString &collection_name) +bool XmlProjectElementCollectionItem::isCollectionRoot() const { - if (collection_name.isEmpty()) return; + if (!parent()) + return true; + else if (parent()->type() != XmlProjectElementCollectionItem::Type) + return true; + else + return false; +} + +/** + * @brief XmlProjectElementCollectionItem::addChildAtPath + * Ask to this item item to add a child with collection name @collection_name + * @param collection_name + */ +void XmlProjectElementCollectionItem::addChildAtPath(const QString &collection_name) +{ + if (collection_name.isEmpty()) + return; QDomNodeList node_list; if (collection_name.endsWith(".elmt")) @@ -349,31 +154,120 @@ void XmlProjectElementCollectionItem::insertNewItem(const QString &collection_na } } - XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(m_project, child_element, this); - insertChild(rowForInsertItem(collection_name), xpeci); + XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem (); + insertRow(rowForInsertItem(collection_name), xpeci); + xpeci->setXmlElement(child_element, m_project); + xpeci->setUpData(); +} + +/** + * @brief XmlProjectElementCollectionItem::project + * @return the paretn project of the managed collection + */ +QETProject *XmlProjectElementCollectionItem::project() const +{ + return m_project; +} + +/** + * @brief XmlProjectElementCollectionItem::setProject + * Set the project for this item. + * Use this method for set this item the root of the collection + * @param project : project to manage the collection + * @param set_data : if true, call setUpData for every child of this item + */ +void XmlProjectElementCollectionItem::setProject(QETProject *project, bool set_data, bool hide_element) +{ + if (m_project) + return; + + m_project = project; + m_dom_element = project->embeddedElementCollection()->root(); + populate(set_data, hide_element); +} + +/** + * @brief XmlProjectElementCollectionItem::setUpData + * SetUp the data of this item + */ +void XmlProjectElementCollectionItem::setUpData() +{ + //Setup the displayed name + localName(); + + if (isDir()) + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + else + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); + + setToolTip(collectionPath()); +} + +/** + * @brief XmlProjectElementCollectionItem::setUpIcon + * SetUp the icon of this item. + * Because icon use several memory, we use this method for setup icon instead setUpData. + */ +void XmlProjectElementCollectionItem::setUpIcon() +{ + if (!icon().isNull()) + return; + + if (isCollectionRoot()) + setIcon(QET::Icons::ProjectFileGP); + else if (isDir()) + setIcon(QET::Icons::Folder); + else { + ElementsLocation loc(embeddedPath(), m_project); + setIcon(loc.icon()); + } } /** * @brief XmlProjectElementCollectionItem::populate - * Populate this item + * Create the childs of this item + * @param set_data : if true, call setUpData for every child of this item */ -void XmlProjectElementCollectionItem::populate() +void XmlProjectElementCollectionItem::populate(bool set_data, bool hide_element) { QList dom_category = m_project->embeddedElementCollection()->directories(m_dom_element); std::sort(dom_category.begin(), dom_category.end(), [](QDomElement a, QDomElement b){return (a.attribute("name") < b.attribute("name"));}); foreach (QDomElement element, dom_category) { - XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(m_project, element, this); - this->appendChild(xpeci); + XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(); + appendRow(xpeci); + xpeci->setXmlElement(element, m_project, set_data, hide_element); + if (set_data) + xpeci->setUpData(); } + if (hide_element) + return; + QList dom_elements = m_project->embeddedElementCollection()->elements(m_dom_element); std::sort(dom_elements.begin(), dom_elements.end(), [](QDomElement a, QDomElement b){return (a.attribute("name") < b.attribute("name"));}); foreach (QDomElement element, dom_elements) { - XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(m_project, element, this); - this->appendChild(xpeci); + XmlProjectElementCollectionItem *xpeci = new XmlProjectElementCollectionItem(); + appendRow(xpeci); + xpeci->setXmlElement(element, m_project, set_data); + if (set_data) + xpeci->setUpData(); } } + +/** + * @brief XmlProjectElementCollectionItem::setXmlElement + * Set the managed content of this item + * @param element : the dom element (directory or element), to be managed by this item + * @param project : the parent project of managed collection + * @param set_data : if true, call setUpData for every child of this item + */ +void XmlProjectElementCollectionItem::setXmlElement(QDomElement element, QETProject *project, bool set_data, bool hide_element) +{ + m_dom_element = element; + m_project = project; + populate(set_data, hide_element); +} diff --git a/sources/ElementsCollection/xmlprojectelementcollectionitem.h b/sources/ElementsCollection/xmlprojectelementcollectionitem.h index 217719fcf..cb1ab2824 100644 --- a/sources/ElementsCollection/xmlprojectelementcollectionitem.h +++ b/sources/ElementsCollection/xmlprojectelementcollectionitem.h @@ -1,27 +1,25 @@ /* - Copyright 2006-2016 The QElectroTech Team - This file is part of QElectroTech. + Copyright 2006-2016 The QElectroTech Team + This file is part of QElectroTech. - QElectroTech is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - QElectroTech is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with QElectroTech. If not, see . + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . */ -#ifndef XMLPROJECTELEMENTCOLLECTIONITEM_H -#define XMLPROJECTELEMENTCOLLECTIONITEM_H +#ifndef XMLPROJECTELEMENTCOLLECTIONITEM2_H +#define XMLPROJECTELEMENTCOLLECTIONITEM2_H #include "elementcollectionitem.h" - #include -#include class QETProject; @@ -31,43 +29,33 @@ class QETProject; */ class XmlProjectElementCollectionItem : public ElementCollectionItem { - Q_OBJECT - - public: - XmlProjectElementCollectionItem(QETProject *project, ElementCollectionItem *parent = nullptr); - private: - XmlProjectElementCollectionItem (QETProject *project, const QDomElement &dom_element, ElementCollectionItem *parent = nullptr); public: - ~XmlProjectElementCollectionItem(); + XmlProjectElementCollectionItem(); - enum {Type = UserType + 2}; - virtual int type() const {return Type;} + enum {Type = UserType+3}; + virtual int type() const { return Type; } - virtual QVariant data(int column, int role); - virtual void clearData(); - virtual QMimeData *mimeData(); - virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column); - virtual Qt::ItemFlags flags(); - - virtual bool isCollectionRoot() const; - virtual QString name(); - virtual bool isValid() const; - QETProject *project() const; virtual bool isDir() const; virtual bool isElement() const; - QString collectionPath() const; - QString embeddedPath() const; - virtual QString collectionName() const; - void insertNewItem(const QString &collection_name); + virtual QString localName(); + virtual QString name() const; + virtual QString collectionPath() const; + virtual QString embeddedPath() const; + virtual bool isCollectionRoot() const; + virtual void addChildAtPath(const QString &collection_name); + QETProject * project() const; + + void setProject (QETProject *project, bool set_data = true, bool hide_element = false); + void setUpData(); + void setUpIcon(); private: - void populate(); + void populate(bool set_data = true, bool hide_element = false); + void setXmlElement(QDomElement element, QETProject *project, bool set_data = true, bool hide_element = false); private: - QETProject *m_project; + QETProject *m_project = nullptr; QDomElement m_dom_element; - QIcon m_icon; }; -#endif // XMLPROJECTELEMENTCOLLECTIONITEM_H +#endif // XMLPROJECTELEMENTCOLLECTIONITEM2_H diff --git a/sources/elementdialog.cpp b/sources/elementdialog.cpp index 8f5da2974..50f1222a9 100644 --- a/sources/elementdialog.cpp +++ b/sources/elementdialog.cpp @@ -85,14 +85,14 @@ void ElementDialog::setUpWidget() m_tree_view = new QTreeView(this); - ElementsCollectionModel *model = new ElementsCollectionModel(m_tree_view); - if (m_mode == OpenElement) {model->addCommonCollection();} - model->addCustomCollection(); + m_model = new ElementsCollectionModel(m_tree_view); + if (m_mode == OpenElement) {m_model->addCommonCollection();} + m_model->addCustomCollection(); foreach (QETProject *project, QETApp::registeredProjects()) { - model->addProject(project); + m_model->addProject(project); } - m_tree_view->setModel(model); + m_tree_view->setModel(m_model); m_tree_view->setHeaderHidden(true); layout->addWidget(m_tree_view); @@ -138,7 +138,7 @@ void ElementDialog::setUpConnection() */ void ElementDialog::indexClicked(const QModelIndex &index) { - ElementCollectionItem *eci = static_cast (index.internalPointer()); + ElementCollectionItem *eci = static_cast (m_model->itemFromIndex(index)); m_location = ElementsLocation(eci->collectionPath()); checkCurrentLocation(); } diff --git a/sources/elementdialog.h b/sources/elementdialog.h index 3a100e5d0..595d517c4 100644 --- a/sources/elementdialog.h +++ b/sources/elementdialog.h @@ -24,6 +24,8 @@ class QDialogButtonBox; class QFileNameEdit; class QTreeView; +class ElementsCollectionModel; + /** This class provides several dialogs to select an element or a category (e.g. new or existing, for opening or for saving...). @@ -66,6 +68,7 @@ class ElementDialog : public QDialog QDialogButtonBox *m_buttons_box = nullptr; QFileNameEdit *m_text_field = nullptr; QTreeView *m_tree_view = nullptr; + ElementsCollectionModel *m_model= nullptr; public: static ElementsLocation getOpenElementLocation(QWidget *parent = nullptr); diff --git a/sources/newelementwizard.cpp b/sources/newelementwizard.cpp index 8cc15aeae..19248615c 100644 --- a/sources/newelementwizard.cpp +++ b/sources/newelementwizard.cpp @@ -61,7 +61,7 @@ NewElementWizard::~NewElementWizard() { */ void NewElementWizard::preselectedLocation(const ElementsLocation &location) { - QModelIndex index = m_model->index(location); + QModelIndex index = m_model->indexFromLocation(location); if (index.isValid()) { m_tree_view->scrollTo(index); m_tree_view->setCurrentIndex(index); @@ -170,7 +170,7 @@ bool NewElementWizard::validStep1() QModelIndex index = m_tree_view->currentIndex(); if (index.isValid()) { - ElementCollectionItem *eci = static_cast(index.internalPointer()); + ElementCollectionItem *eci = static_cast(m_model->itemFromIndex(index)); if (eci && eci->isDir()) { ElementsLocation loc(eci->collectionPath()); if (loc.exist()) {