mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
Element collection : improve drag and drop behavior
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4325 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -63,6 +63,13 @@ bool ElementCollectionItem::removeChild(int row, int count)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementCollectionItem::insertChild
|
||||
* Insert item at position row in the child item list
|
||||
* @param row
|
||||
* @param item
|
||||
* @return true if item was inserted, if item is already a chil of this item, return false
|
||||
*/
|
||||
bool ElementCollectionItem::insertChild(int row, ElementCollectionItem *item)
|
||||
{
|
||||
if (m_child_items.contains(item)) return false;
|
||||
@@ -95,6 +102,78 @@ ElementCollectionItem *ElementCollectionItem::childWithCollectionName(QString na
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementCollectionItem::lastItemForPath
|
||||
* 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
|
||||
* @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)
|
||||
{
|
||||
QStringList str_list = path.split("/");
|
||||
if (str_list.isEmpty()) return nullptr;
|
||||
|
||||
ElementCollectionItem *return_eci = this;
|
||||
foreach (QString str, str_list)
|
||||
{
|
||||
ElementCollectionItem *eci = return_eci->childWithCollectionName(str);
|
||||
if (!eci)
|
||||
{
|
||||
newt_item = str;
|
||||
return return_eci;
|
||||
}
|
||||
else
|
||||
return_eci = eci;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementCollectionItem::rowForInsertItem
|
||||
* Return the row for insert a new child item to this item with name @collection_name.
|
||||
* If row can't be found (collection_name is null, or already exist) return -1;
|
||||
* @param collection_name
|
||||
* @return
|
||||
*/
|
||||
int ElementCollectionItem::rowForInsertItem(const QString &collection_name)
|
||||
{
|
||||
if (collection_name.isEmpty()) return -1;
|
||||
|
||||
QList <ElementCollectionItem *> child;
|
||||
//The item to insert is an element we search from element child
|
||||
if (collection_name.endsWith(".elmt"))
|
||||
{
|
||||
child = elementsChild();
|
||||
//There isn't element, we insert at last position
|
||||
if (child.isEmpty())
|
||||
return childCount();
|
||||
}
|
||||
//The item is a directory, we search from directory child
|
||||
else
|
||||
{
|
||||
child = directoriesChild();
|
||||
//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);
|
||||
|
||||
return childCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementCollectionItem::insertNewItem
|
||||
* By defualt do nothing, implement this method in subclass
|
||||
* to handle the insertion of a new item with name collection_name
|
||||
*/
|
||||
void ElementCollectionItem::insertNewItem(const QString &collection_name) {Q_UNUSED (collection_name);}
|
||||
|
||||
/**
|
||||
* @brief ElementCollectionItem::childCount
|
||||
* @return the number of childs of this item
|
||||
@@ -131,15 +210,15 @@ QMimeData *ElementCollectionItem::mimeData() {
|
||||
return new QMimeData();
|
||||
}
|
||||
|
||||
bool ElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const
|
||||
bool ElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const
|
||||
{
|
||||
Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column);
|
||||
Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int column)
|
||||
bool ElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column)
|
||||
{
|
||||
Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(column);
|
||||
Q_UNUSED(data); Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define ELEMENTCOLLECTIONITEM_H
|
||||
|
||||
#include <QVariant>
|
||||
#include "elementlocation.h"
|
||||
|
||||
class QMimeData;
|
||||
class ElementCollectionItem;
|
||||
@@ -44,12 +45,15 @@ class ElementCollectionItem
|
||||
bool insertChild (int row, ElementCollectionItem *item);
|
||||
ElementCollectionItem *child(int row);
|
||||
ElementCollectionItem *childWithCollectionName(QString name) const;
|
||||
ElementCollectionItem *lastItemForPath(const QString &path, QString &newt_item);
|
||||
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 QMimeData *mimeData();
|
||||
virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int column);
|
||||
virtual 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;
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
* @brief ElementLocation::ElementLocation
|
||||
* @param path : path of item in file system
|
||||
*/
|
||||
ElementLocation::ElementLocation(QString path):
|
||||
m_project(nullptr)
|
||||
ElementLocation::ElementLocation(QString path)
|
||||
{
|
||||
if (!path.isEmpty())
|
||||
setPath(path);
|
||||
@@ -47,6 +46,19 @@ ElementLocation::ElementLocation(QString path, QETProject *project) :
|
||||
setPath(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementLocation::ElementLocation
|
||||
* Constructor, build an ElementLocation from a QMimeData, the mime data format
|
||||
* must be "application/x-qet-element-uri" or "application/x-qet-category-uri".
|
||||
* This location can be null even if format is valid.
|
||||
* @param data
|
||||
*/
|
||||
ElementLocation::ElementLocation(const QMimeData *data)
|
||||
{
|
||||
if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri"))
|
||||
setPath(data->text());
|
||||
}
|
||||
|
||||
ElementLocation::~ElementLocation()
|
||||
{}
|
||||
|
||||
@@ -194,9 +206,10 @@ bool ElementLocation::setPath(QString path)
|
||||
*/
|
||||
bool ElementLocation::isNull() const
|
||||
{
|
||||
if (!m_file_system_path.isEmpty()) return false;
|
||||
else if (!m_collection_path.isEmpty()) return false;
|
||||
else return true;
|
||||
if (isFileSystem() || isProject())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,6 +236,29 @@ bool ElementLocation::isDirectory() const {
|
||||
return !isElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementLocation::isFileSystem
|
||||
* @return True if this location represent a file system item.
|
||||
*/
|
||||
bool ElementLocation::isFileSystem() const
|
||||
{
|
||||
if (m_project) return false;
|
||||
if (m_file_system_path.isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementLocation::isProject
|
||||
* @return True if this location represent an item from a project.
|
||||
*/
|
||||
bool ElementLocation::isProject() const
|
||||
{
|
||||
if (m_project && !m_collection_path.isEmpty())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementLocation::collectionPath
|
||||
* @return the colletion relative to the collection
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <QIcon>
|
||||
|
||||
class QETProject;
|
||||
class QMimeData;
|
||||
|
||||
/**
|
||||
* @brief The ElementLocation class
|
||||
@@ -36,6 +37,7 @@ class ElementLocation
|
||||
public:
|
||||
ElementLocation(QString path = QString());
|
||||
ElementLocation(QString path, QETProject *project);
|
||||
ElementLocation(const QMimeData *data);
|
||||
~ElementLocation();
|
||||
|
||||
bool setPath(QString path);
|
||||
@@ -44,6 +46,7 @@ class ElementLocation
|
||||
bool isElement() const;
|
||||
bool isDirectory() const;
|
||||
bool isFileSystem() const;
|
||||
bool isProject() const;
|
||||
|
||||
QString collectionPath(bool protocol = true) const;
|
||||
QString fileSystemPath() const;
|
||||
@@ -59,7 +62,7 @@ class ElementLocation
|
||||
private:
|
||||
QString m_collection_path;
|
||||
QString m_file_system_path;
|
||||
QETProject *m_project;
|
||||
QETProject *m_project = nullptr;
|
||||
QDomElement m_xml;
|
||||
QUuid m_uuid;
|
||||
QIcon m_icon;
|
||||
|
||||
@@ -193,32 +193,32 @@ Qt::ItemFlags ElementsCollectionModel::flags(const QModelIndex &index) const
|
||||
|
||||
bool ElementsCollectionModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return false;
|
||||
if (!(QAbstractItemModel::canDropMimeData(data, action, row, column, parent) && parent.isValid())) return false;
|
||||
|
||||
if (!hasIndex(row, column, parent)) return false;
|
||||
|
||||
QModelIndex item = index(row, column, parent);
|
||||
|
||||
if (item.isValid())
|
||||
return static_cast<ElementCollectionItem*>(item.internalPointer())->canDropMimeData(data, action, column);
|
||||
else
|
||||
return false;
|
||||
ElementCollectionItem *eci = static_cast <ElementCollectionItem *>(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;
|
||||
|
||||
if (!hasIndex(row, column, parent)) return false;
|
||||
ElementLocation location(data);
|
||||
if (location.isNull()) return false;
|
||||
|
||||
QModelIndex item = index(row, column, parent);
|
||||
ElementCollectionItem *eci = static_cast<ElementCollectionItem*> (parent.internalPointer());
|
||||
if (!eci) return false;
|
||||
if (eci->isElement()) eci = eci->parent();
|
||||
|
||||
if (item.isValid())
|
||||
return static_cast<ElementCollectionItem*>(item.internalPointer())->dropMimeData(data, action, column);
|
||||
else
|
||||
return false;
|
||||
int i = eci->rowForInsertItem(location.fileName());
|
||||
if (i < 0) return false;
|
||||
|
||||
beginInsertRows(parent, i, i);
|
||||
bool rb = eci->dropMimeData(data, action, row, column);
|
||||
endInsertRows();
|
||||
return rb;
|
||||
}
|
||||
|
||||
QStringList ElementsCollectionModel::mimeTypes() const
|
||||
@@ -342,14 +342,13 @@ void ElementsCollectionModel::elementIntegratedToCollection(QETProject *project,
|
||||
if (!xpeci) return;
|
||||
|
||||
QString collection_name;
|
||||
XmlProjectElementCollectionItem *parent_xpeci = xpeci->lastItemForPath(path, collection_name);
|
||||
if (parent_xpeci)
|
||||
{
|
||||
int new_row = parent_xpeci->rowForInsertItem(collection_name);
|
||||
if (new_row <= -1) return;
|
||||
QModelIndex parent_index = createIndex(parent_xpeci->row(), 0, parent_xpeci);
|
||||
beginInsertRows(parent_index, new_row, new_row);
|
||||
parent_xpeci->insertNewItem(collection_name);
|
||||
endInsertRows();
|
||||
}
|
||||
ElementCollectionItem *eci = xpeci->lastItemForPath(path, collection_name);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -115,6 +115,9 @@ void ElementsCollectionWidget::setUpWidget()
|
||||
m_tree_view->setIconSize(QSize(50, 50));
|
||||
m_tree_view->setDragDropMode(QAbstractItemView::DragDrop);
|
||||
m_tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_tree_view->setAutoExpandDelay(500);
|
||||
m_tree_view->setAnimated(true);
|
||||
m_tree_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
m_main_vlayout->addWidget(m_tree_view);
|
||||
|
||||
//Setup the progress bar
|
||||
|
||||
@@ -121,6 +121,16 @@ QString FileElementCollectionItem::collectionPath() const
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileElementCollectionItem::collectionName
|
||||
* @return The collection name of this item
|
||||
*/
|
||||
QString FileElementCollectionItem::collectionName() const
|
||||
{
|
||||
if (isCollectionRoot()) return QString();
|
||||
else return m_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileElementCollectionItem::data
|
||||
* @param column
|
||||
@@ -195,9 +205,9 @@ QMimeData *FileElementCollectionItem::mimeData()
|
||||
* @param column
|
||||
* @return True if the data can be dropped
|
||||
*/
|
||||
bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const
|
||||
bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column) const
|
||||
{
|
||||
Q_UNUSED(action); Q_UNUSED(column);
|
||||
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"))
|
||||
@@ -213,9 +223,9 @@ bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropA
|
||||
* @param column
|
||||
* @return Handle the drop of a data
|
||||
*/
|
||||
bool FileElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int column)
|
||||
bool FileElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column)
|
||||
{
|
||||
Q_UNUSED(action); Q_UNUSED(column);
|
||||
Q_UNUSED(action); Q_UNUSED(row); Q_UNUSED(column);
|
||||
if (isCommonCollection()) return false;
|
||||
|
||||
FileElementCollectionItem *feci = this;
|
||||
@@ -381,6 +391,15 @@ bool FileElementCollectionItem::removeContent()
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileElementCollectionItem::insertNewItem(const QString &collection_name)
|
||||
{
|
||||
if (collection_name.isEmpty()) return;
|
||||
|
||||
FileElementCollectionItem *feci = new FileElementCollectionItem(this);
|
||||
feci->setPathName(collection_name);
|
||||
insertChild(rowForInsertItem(collection_name), feci);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileElementCollectionItem::setPathName
|
||||
* Set the name of this item in the file system path.
|
||||
@@ -434,7 +453,9 @@ void FileElementCollectionItem::populate()
|
||||
bool FileElementCollectionItem::handleElementDrop(const QMimeData *data)
|
||||
{
|
||||
ElementLocation location(data->text());
|
||||
return QFile::copy(location.fileSystemPath(), fileSystemPath() + "/" + location.fileSystemPath().split("/").last());
|
||||
bool rb = QFile::copy(location.fileSystemPath(), fileSystemPath() + "/" + location.fileSystemPath().split("/").last());
|
||||
if (rb) insertNewItem(location.fileName());
|
||||
return rb;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,7 +470,11 @@ bool FileElementCollectionItem::handleDirectoryDrop(const QMimeData *data)
|
||||
QDir origin_dir(location.fileSystemPath());
|
||||
|
||||
if (origin_dir.exists())
|
||||
return createSubDir(origin_dir, QDir(fileSystemPath()));
|
||||
{
|
||||
bool rb = createSubDir(origin_dir, QDir(fileSystemPath()));
|
||||
if(rb) insertNewItem(location.fileName());
|
||||
return rb;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -42,11 +42,12 @@ class FileElementCollectionItem : public ElementCollectionItem
|
||||
QString dirPath() const;
|
||||
|
||||
QString collectionPath() const;
|
||||
QString collectionName() const;
|
||||
|
||||
virtual QVariant data(int column, int role);
|
||||
virtual QMimeData *mimeData();
|
||||
virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int column) const;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int column);
|
||||
virtual 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;
|
||||
@@ -58,6 +59,7 @@ class FileElementCollectionItem : public ElementCollectionItem
|
||||
|
||||
virtual bool canRemoveContent();
|
||||
virtual bool removeContent();
|
||||
virtual void insertNewItem(const QString &collection_name);
|
||||
|
||||
private:
|
||||
void setPathName(QString path_name);
|
||||
|
||||
@@ -253,71 +253,6 @@ QString XmlProjectElementCollectionItem::collectionName() const {
|
||||
return m_dom_element.attribute("name");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XmlProjectElementCollectionItem::lastItemForPath
|
||||
* Return the last existing item in this XmlProjectElementCollectionItem 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 next_item : 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)
|
||||
*/
|
||||
XmlProjectElementCollectionItem *XmlProjectElementCollectionItem::lastItemForPath(const QString &path, QString &next_item)
|
||||
{
|
||||
QStringList str_list = path.split("/");
|
||||
if (str_list.isEmpty()) return nullptr;
|
||||
|
||||
XmlProjectElementCollectionItem *xpeci = this;
|
||||
foreach (QString str, str_list)
|
||||
{
|
||||
ElementCollectionItem *eci = xpeci->childWithCollectionName(str);
|
||||
if (!eci)
|
||||
{
|
||||
next_item = str;
|
||||
return xpeci;
|
||||
}
|
||||
else
|
||||
xpeci = static_cast<XmlProjectElementCollectionItem *>(eci);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XmlProjectElementCollectionItem::rowForInsertItem
|
||||
* Return the row for insert a new child item to this item with name @collection_name.
|
||||
* If row can't be found (collection_name is null, or already exist) return -1;
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
int XmlProjectElementCollectionItem::rowForInsertItem(const QString &collection_name)
|
||||
{
|
||||
if (collection_name.isEmpty()) return -1;
|
||||
|
||||
QList <ElementCollectionItem *> child;
|
||||
//The item to insert is an element we search from element child
|
||||
if (collection_name.endsWith(".elmt"))
|
||||
{
|
||||
child = elementsChild();
|
||||
//There isn't element, we insert at last position
|
||||
if (child.isEmpty())
|
||||
return childCount();
|
||||
}
|
||||
//The item is a directory, we search from directory child
|
||||
else
|
||||
{
|
||||
child = directoriesChild();
|
||||
//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);
|
||||
|
||||
return childCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XmlProjectElementCollectionItem::insertNewItem
|
||||
* When this XmlProjectElementCollectionItem is already created, we must to use this method for insert a new item.
|
||||
|
||||
@@ -54,12 +54,8 @@ class XmlProjectElementCollectionItem : public ElementCollectionItem
|
||||
QString collectionPath() const;
|
||||
QString embeddedPath() const;
|
||||
virtual QString collectionName() const;
|
||||
|
||||
XmlProjectElementCollectionItem *lastItemForPath(const QString &path, QString &next_item);
|
||||
int rowForInsertItem(const QString &collection_name);
|
||||
void insertNewItem(const QString &collection_name);
|
||||
|
||||
|
||||
private:
|
||||
void populate();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user