mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
Change the way how an element or directory is copied, this isn't the role of the new panel to manage the copy.
We must to use elementcollectionhandler instead git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4343 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -79,7 +79,8 @@ INCLUDEPATH += sources \
|
|||||||
sources/editor/graphicspart \
|
sources/editor/graphicspart \
|
||||||
sources/undocommand \
|
sources/undocommand \
|
||||||
sources/diagramevent \
|
sources/diagramevent \
|
||||||
sources/ElementsCollection
|
sources/ElementsCollection \
|
||||||
|
sources/ElementsCollection/ui
|
||||||
|
|
||||||
|
|
||||||
# Fichiers sources
|
# Fichiers sources
|
||||||
@@ -91,7 +92,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) $$files(sources/editor/*
|
|||||||
$$files(sources/dvevent/*.h) \
|
$$files(sources/dvevent/*.h) \
|
||||||
$$files(sources/undocommand/*.h) \
|
$$files(sources/undocommand/*.h) \
|
||||||
$$files(sources/diagramevent/*.h) \
|
$$files(sources/diagramevent/*.h) \
|
||||||
$$files(sources/ElementsCollection/*.h)
|
$$files(sources/ElementsCollection/*.h) \
|
||||||
|
$$files(sources/ElementsCollection/ui/*.h)
|
||||||
|
|
||||||
SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/titleblock/*.cpp) $$files(sources/richtext/*.cpp) $$files(sources/ui/*.cpp) $$files(sources/qetgraphicsitem/*.cpp) $$files(sources/factory/*.cpp) \
|
SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/titleblock/*.cpp) $$files(sources/richtext/*.cpp) $$files(sources/ui/*.cpp) $$files(sources/qetgraphicsitem/*.cpp) $$files(sources/factory/*.cpp) \
|
||||||
$$files(sources/properties/*.cpp) \
|
$$files(sources/properties/*.cpp) \
|
||||||
@@ -101,7 +103,8 @@ SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/
|
|||||||
$$files(sources/dvevent/*.cpp) \
|
$$files(sources/dvevent/*.cpp) \
|
||||||
$$files(sources/undocommand/*.cpp) \
|
$$files(sources/undocommand/*.cpp) \
|
||||||
$$files(sources/diagramevent/*.cpp) \
|
$$files(sources/diagramevent/*.cpp) \
|
||||||
$$files(sources/ElementsCollection/*.cpp)
|
$$files(sources/ElementsCollection/*.cpp) \
|
||||||
|
$$files(sources/ElementsCollection/ui/*.cpp)
|
||||||
|
|
||||||
# Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
|
# Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
|
||||||
RESOURCES += qelectrotech.qrc
|
RESOURCES += qelectrotech.qrc
|
||||||
@@ -118,7 +121,8 @@ QT += xml svg network sql widgets printsupport
|
|||||||
# UI DESIGNER FILES AND GENERATION SOURCES FILES
|
# UI DESIGNER FILES AND GENERATION SOURCES FILES
|
||||||
FORMS += $$files(sources/richtext/*.ui) \
|
FORMS += $$files(sources/richtext/*.ui) \
|
||||||
$$files(sources/ui/*.ui) \
|
$$files(sources/ui/*.ui) \
|
||||||
$$files(sources/editor/ui/*.ui)
|
$$files(sources/editor/ui/*.ui) \
|
||||||
|
$$files(sources/ElementsCollection/ui/*.ui)
|
||||||
|
|
||||||
UI_SOURCES_DIR = sources/ui/
|
UI_SOURCES_DIR = sources/ui/
|
||||||
UI_HEADERS_DIR = sources/ui/
|
UI_HEADERS_DIR = sources/ui/
|
||||||
|
|||||||
156
sources/ElementsCollection/elementcollectionhandler.cpp
Normal file
156
sources/ElementsCollection/elementcollectionhandler.cpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2015 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "elementcollectionhandler.h"
|
||||||
|
#include "renamedialog.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
ECHStrategy::ECHStrategy(ElementLocation &source, ElementLocation &destination) :
|
||||||
|
m_source(source),
|
||||||
|
m_destination (destination)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ECHStrategy::~ECHStrategy() {}
|
||||||
|
|
||||||
|
/******************************************************/
|
||||||
|
|
||||||
|
ECHSFileToFile::ECHSFileToFile(ElementLocation &source, ElementLocation &destination) :
|
||||||
|
ECHStrategy(source, destination)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ElementLocation ECHSFileToFile::copy()
|
||||||
|
{
|
||||||
|
//Check if the destination already have an item with the same name of the item to copy
|
||||||
|
ElementLocation location(m_destination.fileSystemPath() + "/" + m_source.fileName());
|
||||||
|
QString rename;
|
||||||
|
if (location.exist())
|
||||||
|
{
|
||||||
|
RenameDialog rd(location.fileSystemPath());
|
||||||
|
if (rd.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
if (rd.selectedAction() == QET::Erase)
|
||||||
|
{
|
||||||
|
if (location.isDirectory())
|
||||||
|
{
|
||||||
|
QDir dir(location.fileSystemPath());
|
||||||
|
dir.removeRecursively();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QFile file(location.fileSystemPath());
|
||||||
|
file.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rd.selectedAction() == QET::Rename)
|
||||||
|
{
|
||||||
|
rename = rd.newName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ElementLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_source.isElement())
|
||||||
|
return copyElement(m_source, m_destination, rename);
|
||||||
|
else
|
||||||
|
return copyDirectory(m_source, m_destination, rename);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementLocation ECHSFileToFile::copyDirectory(ElementLocation &source, ElementLocation &destination, QString rename)
|
||||||
|
{
|
||||||
|
QDir source_dir(source.fileSystemPath());
|
||||||
|
QDir destination_dir(destination.fileSystemPath());
|
||||||
|
|
||||||
|
if (!source_dir.exists() || !destination_dir.exists()) return ElementLocation();
|
||||||
|
|
||||||
|
QString new_dir_name = rename.isEmpty() ? source_dir.dirName() : rename;
|
||||||
|
|
||||||
|
//Create a new dir
|
||||||
|
if (destination_dir.mkdir(new_dir_name))
|
||||||
|
{
|
||||||
|
//The new created directory
|
||||||
|
QDir created_dir(destination_dir.canonicalPath() + "/" + new_dir_name);
|
||||||
|
|
||||||
|
//Copy the qet_directory file
|
||||||
|
QFile::copy(source_dir.canonicalPath() + "/qet_directory", created_dir.canonicalPath() + "/qet_directory");
|
||||||
|
|
||||||
|
//Copy all dirs found in source_dir to destination_dir
|
||||||
|
ElementLocation created_location(created_dir.canonicalPath());
|
||||||
|
foreach(QString str, source_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name))
|
||||||
|
{
|
||||||
|
ElementLocation sub_source(source.fileSystemPath() + "/" + str);
|
||||||
|
copyDirectory(sub_source, created_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy all elements found in source_dir to destination_dir
|
||||||
|
source_dir.setNameFilters(QStringList() << "*.elmt");
|
||||||
|
foreach(QString str, source_dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
|
||||||
|
{
|
||||||
|
ElementLocation sub_source(source.fileSystemPath() + "/" + str);
|
||||||
|
copyElement(sub_source, created_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
return created_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ElementLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementLocation ECHSFileToFile::copyElement(ElementLocation &source, ElementLocation &destination, QString rename)
|
||||||
|
{
|
||||||
|
QString new_elmt_name = rename.isEmpty() ? source.fileName() : rename;
|
||||||
|
bool rb = QFile::copy(source.fileSystemPath(), destination.fileSystemPath() + "/" + new_elmt_name);
|
||||||
|
if (rb)
|
||||||
|
return ElementLocation (destination.fileSystemPath() + "/" + new_elmt_name);
|
||||||
|
else
|
||||||
|
return ElementLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementCollectionHandler::ElementCollectionHandler
|
||||||
|
* @param widget
|
||||||
|
*/
|
||||||
|
ElementCollectionHandler::ElementCollectionHandler() {}
|
||||||
|
|
||||||
|
ElementCollectionHandler::~ElementCollectionHandler()
|
||||||
|
{
|
||||||
|
if (m_strategy) delete m_strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ElementCollectionHandler::copy
|
||||||
|
* Copy the content of collection represented by source to the collection represented by destination.
|
||||||
|
* Destination must be a directory, else the copy do nothing and return a null ElementLocation
|
||||||
|
* if destination have an item with the same name of source, a dialog ask to user what to do.
|
||||||
|
* @param source
|
||||||
|
* @param destination
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ElementLocation ElementCollectionHandler::copy(ElementLocation &source, ElementLocation &destination)
|
||||||
|
{
|
||||||
|
if (!source.exist() || !destination.exist() || destination.isElement()) return ElementLocation();
|
||||||
|
|
||||||
|
if (source.isFileSystem() && destination.isFileSystem()) m_strategy = new ECHSFileToFile(source, destination);
|
||||||
|
|
||||||
|
if (m_strategy)
|
||||||
|
return m_strategy->copy();
|
||||||
|
else
|
||||||
|
return ElementLocation();
|
||||||
|
}
|
||||||
64
sources/ElementsCollection/elementcollectionhandler.h
Normal file
64
sources/ElementsCollection/elementcollectionhandler.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2015 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef ELEMENTCOLLECTIONHANDLER_H
|
||||||
|
#define ELEMENTCOLLECTIONHANDLER_H
|
||||||
|
|
||||||
|
#include "elementlocation.h"
|
||||||
|
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
class ECHStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ECHStrategy(ElementLocation &source, ElementLocation &destination);
|
||||||
|
virtual ~ECHStrategy();
|
||||||
|
virtual ElementLocation copy() =0;
|
||||||
|
|
||||||
|
ElementLocation m_source, m_destination;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ECHSFileToFile : public ECHStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ECHSFileToFile (ElementLocation &source, ElementLocation &destination);
|
||||||
|
|
||||||
|
ElementLocation copy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ElementLocation copyDirectory(ElementLocation &source, ElementLocation &destination, QString rename = QString());
|
||||||
|
ElementLocation copyElement(ElementLocation &source, ElementLocation &destination, QString rename = QString());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The ElementCollectionHandler class
|
||||||
|
* Provide several method to copy element or directory from a collection
|
||||||
|
* to another collection.
|
||||||
|
*/
|
||||||
|
class ElementCollectionHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ElementCollectionHandler();
|
||||||
|
~ElementCollectionHandler();
|
||||||
|
|
||||||
|
ElementLocation copy(ElementLocation &source, ElementLocation &destination);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ECHStrategy *m_strategy = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ELEMENTCOLLECTIONHANDLER_H
|
||||||
@@ -84,7 +84,7 @@ bool ElementCollectionItem::insertChild(int row, ElementCollectionItem *item)
|
|||||||
* @return The child at @row of this item.
|
* @return The child at @row of this item.
|
||||||
* If there isn't child at @row, return default ElementCollectionItem
|
* If there isn't child at @row, return default ElementCollectionItem
|
||||||
*/
|
*/
|
||||||
ElementCollectionItem *ElementCollectionItem::child(int row) {
|
ElementCollectionItem *ElementCollectionItem::child(int row) const {
|
||||||
return m_child_items.value(row);
|
return m_child_items.value(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class ElementCollectionItem
|
|||||||
void appendChild (ElementCollectionItem *item);
|
void appendChild (ElementCollectionItem *item);
|
||||||
bool removeChild (int row, int count);
|
bool removeChild (int row, int count);
|
||||||
bool insertChild (int row, ElementCollectionItem *item);
|
bool insertChild (int row, ElementCollectionItem *item);
|
||||||
ElementCollectionItem *child(int row);
|
ElementCollectionItem *child(int row) const;
|
||||||
ElementCollectionItem *childWithCollectionName(QString name) const;
|
ElementCollectionItem *childWithCollectionName(QString name) const;
|
||||||
ElementCollectionItem *lastItemForPath(const QString &path, QString &newt_item);
|
ElementCollectionItem *lastItemForPath(const QString &path, QString &newt_item);
|
||||||
int rowForInsertItem(const QString &collection_name);
|
int rowForInsertItem(const QString &collection_name);
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ ElementLocation::ElementLocation(const QMimeData *data)
|
|||||||
setPath(data->text());
|
setPath(data->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElementLocation &ElementLocation::operator=(const ElementLocation &other)
|
||||||
|
{
|
||||||
|
m_collection_path = other.m_collection_path;
|
||||||
|
m_file_system_path = other.m_file_system_path;
|
||||||
|
m_project = other.m_project;
|
||||||
|
m_xml = other.m_xml;
|
||||||
|
m_uuid = other.m_uuid;
|
||||||
|
m_icon = other.m_icon;
|
||||||
|
return(*this);
|
||||||
|
}
|
||||||
|
|
||||||
ElementLocation::~ElementLocation()
|
ElementLocation::~ElementLocation()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -115,12 +126,12 @@ bool ElementLocation::setPath(QString path)
|
|||||||
if (path.startsWith("common://"))
|
if (path.startsWith("common://"))
|
||||||
{
|
{
|
||||||
tmp_path.remove("common://");
|
tmp_path.remove("common://");
|
||||||
p = QETApp::commonElementsDir() + tmp_path;
|
p = QETApp::commonElementsDirN() + "/" + tmp_path;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp_path.remove("custom://");
|
tmp_path.remove("custom://");
|
||||||
p = QETApp::customElementsDir() + tmp_path;
|
p = QETApp::customElementsDirN() + "/" + tmp_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is an element
|
//This is an element
|
||||||
@@ -152,49 +163,39 @@ bool ElementLocation::setPath(QString path)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(path.endsWith(".elmt"))
|
if(path.endsWith(".elmt"))
|
||||||
{
|
|
||||||
QFile file(path);
|
|
||||||
if (file.exists())
|
|
||||||
{
|
{
|
||||||
m_file_system_path = path;
|
m_file_system_path = path;
|
||||||
if (path.startsWith(QETApp::commonElementsDir()))
|
if (path.startsWith(QETApp::commonElementsDirN()))
|
||||||
{
|
{
|
||||||
path.remove(QETApp::commonElementsDir());
|
path.remove(QETApp::commonElementsDirN() + "/");
|
||||||
path.prepend("common://");
|
path.prepend("common://");
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
}
|
}
|
||||||
else if (path.startsWith(QETApp::customElementsDir()))
|
else if (path.startsWith(QETApp::customElementsDirN()))
|
||||||
{
|
{
|
||||||
path.remove(QETApp::customElementsDir());
|
path.remove(QETApp::customElementsDirN() + "/");
|
||||||
path.prepend("custom://");
|
path.prepend("custom://");
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
QDir dir(path);
|
|
||||||
if (dir.exists())
|
|
||||||
{
|
{
|
||||||
m_file_system_path = path;
|
m_file_system_path = path;
|
||||||
if (path.startsWith(QETApp::commonElementsDir()))
|
if (path.startsWith(QETApp::commonElementsDirN()))
|
||||||
{
|
{
|
||||||
path.remove(QETApp::commonElementsDir());
|
path.remove(QETApp::commonElementsDirN() + "/");
|
||||||
path.prepend("common://");
|
path.prepend("common://");
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
}
|
}
|
||||||
else if (path.startsWith(QETApp::customElementsDir()))
|
else if (path.startsWith(QETApp::customElementsDirN()))
|
||||||
{
|
{
|
||||||
path.remove(QETApp::customElementsDir());
|
path.remove(QETApp::customElementsDirN()) + "/";
|
||||||
path.prepend("custom://");
|
path.prepend("custom://");
|
||||||
m_collection_path = path;
|
m_collection_path = path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -260,9 +261,27 @@ bool ElementLocation::isProject() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ElementLocation::collectionPath
|
* @brief ElementLocation::exist
|
||||||
* @return the colletion relative to the collection
|
* @return True if this location represent an existing directory or element.
|
||||||
*/
|
*/
|
||||||
|
bool ElementLocation::exist() const
|
||||||
|
{
|
||||||
|
if (isProject())
|
||||||
|
return m_project->embeddedElementCollection()->exist(collectionPath(false));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isDirectory())
|
||||||
|
{
|
||||||
|
QDir dir(fileSystemPath());
|
||||||
|
return dir.exists();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QFile::exists(fileSystemPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ElementLocation::collectionPath
|
* @brief ElementLocation::collectionPath
|
||||||
* Return the path of the represented element relative to collection
|
* Return the path of the represented element relative to collection
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class ElementLocation
|
|||||||
ElementLocation(QString path = QString());
|
ElementLocation(QString path = QString());
|
||||||
ElementLocation(QString path, QETProject *project);
|
ElementLocation(QString path, QETProject *project);
|
||||||
ElementLocation(const QMimeData *data);
|
ElementLocation(const QMimeData *data);
|
||||||
|
ElementLocation &operator=(const ElementLocation &other);
|
||||||
~ElementLocation();
|
~ElementLocation();
|
||||||
|
|
||||||
bool setPath(QString path);
|
bool setPath(QString path);
|
||||||
@@ -47,6 +48,7 @@ class ElementLocation
|
|||||||
bool isDirectory() const;
|
bool isDirectory() const;
|
||||||
bool isFileSystem() const;
|
bool isFileSystem() const;
|
||||||
bool isProject() const;
|
bool isProject() const;
|
||||||
|
bool exist() const;
|
||||||
|
|
||||||
QString collectionPath(bool protocol = true) const;
|
QString collectionPath(bool protocol = true) const;
|
||||||
QString fileSystemPath() const;
|
QString fileSystemPath() const;
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ QList<ElementCollectionItem *> ElementsCollectionModel::items() const
|
|||||||
void ElementsCollectionModel::addCommonCollection()
|
void ElementsCollectionModel::addCommonCollection()
|
||||||
{
|
{
|
||||||
FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item);
|
FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item);
|
||||||
if (feci->setRootPath(QETApp::commonElementsDir()))
|
if (feci->setRootPath(QETApp::commonElementsDirN()))
|
||||||
m_root_item->appendChild(feci);
|
m_root_item->appendChild(feci);
|
||||||
else
|
else
|
||||||
delete feci;
|
delete feci;
|
||||||
@@ -259,7 +259,7 @@ void ElementsCollectionModel::addCommonCollection()
|
|||||||
void ElementsCollectionModel::addCustomCollection()
|
void ElementsCollectionModel::addCustomCollection()
|
||||||
{
|
{
|
||||||
FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item);
|
FileElementCollectionItem *feci = new FileElementCollectionItem(m_root_item);
|
||||||
if (feci->setRootPath(QETApp::customElementsDir()))
|
if (feci->setRootPath(QETApp::customElementsDirN()))
|
||||||
m_root_item->appendChild(feci);
|
m_root_item->appendChild(feci);
|
||||||
else
|
else
|
||||||
delete feci;
|
delete feci;
|
||||||
|
|||||||
@@ -16,11 +16,11 @@
|
|||||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "fileelementcollectionitem.h"
|
#include "fileelementcollectionitem.h"
|
||||||
#include "QDir"
|
|
||||||
#include "qetapp.h"
|
#include "qetapp.h"
|
||||||
#include "elementslocation.h"
|
#include "elementslocation.h"
|
||||||
#include "nameslist.h"
|
#include "nameslist.h"
|
||||||
#include "qeticons.h"
|
#include "qeticons.h"
|
||||||
|
#include "elementcollectionhandler.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief FileElementCollectionItem::FileElementCollectionItem
|
* @brief FileElementCollectionItem::FileElementCollectionItem
|
||||||
@@ -71,9 +71,10 @@ QString FileElementCollectionItem::fileSystemPath() const
|
|||||||
FileElementCollectionItem *parent = static_cast<FileElementCollectionItem*>(m_parent_item);
|
FileElementCollectionItem *parent = static_cast<FileElementCollectionItem*>(m_parent_item);
|
||||||
|
|
||||||
//Get the path of the parent.
|
//Get the path of the parent.
|
||||||
if (parent->isCollectionRoot())
|
// if (parent->isCollectionRoot())
|
||||||
return parent->fileSystemPath() + m_path;
|
// return parent->fileSystemPath() + m_path;
|
||||||
else
|
// else
|
||||||
|
// return parent->fileSystemPath() + "/" + m_path;
|
||||||
return parent->fileSystemPath() + "/" + m_path;
|
return parent->fileSystemPath() + "/" + m_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ QString FileElementCollectionItem::collectionPath() const
|
|||||||
//else this item is the root of collection path.
|
//else this item is the root of collection path.
|
||||||
if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type)
|
if (!m_parent_item || m_parent_item->type() != FileElementCollectionItem::Type)
|
||||||
{
|
{
|
||||||
if (m_path == QETApp::commonElementsDir())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
return "common://";
|
return "common://";
|
||||||
else
|
else
|
||||||
return "custom://";
|
return "custom://";
|
||||||
@@ -154,7 +155,7 @@ QVariant FileElementCollectionItem::data(int column, int role)
|
|||||||
//This item have no parent or parent isn't a file element, so it is the root of a collection
|
//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_parent_item || m_parent_item->type() != FileElementCollectionItem::Type)
|
||||||
{
|
{
|
||||||
if (m_path == QETApp::commonElementsDir())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
return QIcon(":/ico/16x16/qet.png");
|
return QIcon(":/ico/16x16/qet.png");
|
||||||
else
|
else
|
||||||
return QIcon(":/ico/16x16/go-home.png");
|
return QIcon(":/ico/16x16/go-home.png");
|
||||||
@@ -211,7 +212,17 @@ bool FileElementCollectionItem::canDropMimeData(const QMimeData *data, Qt::DropA
|
|||||||
if (isCommonCollection()) return false;
|
if (isCommonCollection()) return false;
|
||||||
|
|
||||||
if (data->hasFormat("application/x-qet-element-uri") || data->hasFormat("application/x-qet-category-uri"))
|
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
|
||||||
|
ElementLocation drop_location(data->text());
|
||||||
|
for (int i=0 ; i<childCount() ; i++)
|
||||||
|
{
|
||||||
|
if (static_cast<FileElementCollectionItem *>(child(i))->collectionPath() == drop_location.collectionPath())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -232,10 +243,23 @@ bool FileElementCollectionItem::dropMimeData(const QMimeData *data, Qt::DropActi
|
|||||||
if (isElement() && parent() && parent()->type() == FileElementCollectionItem::Type)
|
if (isElement() && parent() && parent()->type() == FileElementCollectionItem::Type)
|
||||||
feci = static_cast<FileElementCollectionItem *>(parent());
|
feci = static_cast<FileElementCollectionItem *>(parent());
|
||||||
|
|
||||||
if (data->hasFormat("application/x-qet-element-uri"))
|
ElementCollectionHandler ech;
|
||||||
return feci->handleElementDrop(data);
|
|
||||||
else if (data->hasFormat("application/x-qet-category-uri"))
|
ElementLocation source(data->text());
|
||||||
return feci->handleDirectoryDrop(data);
|
ElementLocation destination(feci->fileSystemPath());
|
||||||
|
ElementLocation 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<childCount() ; i++)
|
||||||
|
if (static_cast<FileElementCollectionItem *>(child(i))->collectionPath() == location.collectionPath())
|
||||||
|
removeChild(i, 1);
|
||||||
|
|
||||||
|
insertNewItem(location.fileName());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -278,7 +302,7 @@ bool FileElementCollectionItem::isElement() const {
|
|||||||
*/
|
*/
|
||||||
bool FileElementCollectionItem::isCollectionRoot() const
|
bool FileElementCollectionItem::isCollectionRoot() const
|
||||||
{
|
{
|
||||||
if (m_path == QETApp::commonElementsDir() || m_path == QETApp::customElementsDir())
|
if (m_path == QETApp::commonElementsDirN() || m_path == QETApp::customElementsDirN())
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@@ -289,7 +313,7 @@ bool FileElementCollectionItem::isCollectionRoot() const
|
|||||||
* @return True if this item is part of the common element collection item
|
* @return True if this item is part of the common element collection item
|
||||||
*/
|
*/
|
||||||
bool FileElementCollectionItem::isCommonCollection() const {
|
bool FileElementCollectionItem::isCommonCollection() const {
|
||||||
return fileSystemPath().startsWith(QETApp::commonElementsDir());
|
return fileSystemPath().startsWith(QETApp::commonElementsDirN());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -317,9 +341,9 @@ QString FileElementCollectionItem::name()
|
|||||||
{
|
{
|
||||||
if (isCollectionRoot())
|
if (isCollectionRoot())
|
||||||
{
|
{
|
||||||
if (m_path == QETApp::commonElementsDir())
|
if (m_path == QETApp::commonElementsDirN())
|
||||||
m_name = QObject::tr("Collection QET");
|
m_name = QObject::tr("Collection QET");
|
||||||
else if (m_path == QETApp::customElementsDir())
|
else if (m_path == QETApp::customElementsDirN())
|
||||||
m_name = QObject::tr("Collection utilisateur");
|
m_name = QObject::tr("Collection utilisateur");
|
||||||
else
|
else
|
||||||
m_name = QObject::tr("Collection inconnue");
|
m_name = QObject::tr("Collection inconnue");
|
||||||
@@ -443,70 +467,3 @@ void FileElementCollectionItem::populate()
|
|||||||
appendChild(feci);
|
appendChild(feci);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FileElementCollectionItem::handleElementDrop
|
|
||||||
* Handle a drop data that represente an element.
|
|
||||||
* @param data
|
|
||||||
* @return true if the data is successfully dropped
|
|
||||||
*/
|
|
||||||
bool FileElementCollectionItem::handleElementDrop(const QMimeData *data)
|
|
||||||
{
|
|
||||||
ElementLocation location(data->text());
|
|
||||||
bool rb = QFile::copy(location.fileSystemPath(), fileSystemPath() + "/" + location.fileSystemPath().split("/").last());
|
|
||||||
if (rb) insertNewItem(location.fileName());
|
|
||||||
return rb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FileElementCollectionItem::handleDirectoryDrop
|
|
||||||
* Handle a drop data that represent a directory
|
|
||||||
* @param data
|
|
||||||
* @return true if the data is successfully dropped
|
|
||||||
*/
|
|
||||||
bool FileElementCollectionItem::handleDirectoryDrop(const QMimeData *data)
|
|
||||||
{
|
|
||||||
ElementLocation location(data->text());
|
|
||||||
QDir origin_dir(location.fileSystemPath());
|
|
||||||
|
|
||||||
if (origin_dir.exists())
|
|
||||||
{
|
|
||||||
bool rb = createSubDir(origin_dir, QDir(fileSystemPath()));
|
|
||||||
if(rb) insertNewItem(location.fileName());
|
|
||||||
return rb;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FileElementCollectionItem::createSubDir
|
|
||||||
* Copy the directory @ dir_to_copy and the qet_directory file to destination.
|
|
||||||
* Also copy all directorys and elements find in @dir_to_copy recursively
|
|
||||||
* @param dir_to_copy
|
|
||||||
* @param destination
|
|
||||||
* @return true if the copy of @dir_to_copy to destination is successfull.
|
|
||||||
*/
|
|
||||||
bool FileElementCollectionItem::createSubDir(QDir dir_to_copy, QDir destination)
|
|
||||||
{
|
|
||||||
if (destination.mkdir(dir_to_copy.dirName()))
|
|
||||||
{
|
|
||||||
QDir created_dir(destination.canonicalPath() + "/" + dir_to_copy.dirName());
|
|
||||||
|
|
||||||
//Copy the qet_directory file
|
|
||||||
QFile::copy(dir_to_copy.canonicalPath() + "/qet_directory", created_dir.canonicalPath() +"/qet_directory");
|
|
||||||
|
|
||||||
//Copy all dirs found in dir_to_copy to destination
|
|
||||||
foreach(QString str, dir_to_copy.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name))
|
|
||||||
createSubDir(QDir(dir_to_copy.canonicalPath() + "/" + str), created_dir);
|
|
||||||
|
|
||||||
//Copy all elements found in dir_to_copy to destination
|
|
||||||
dir_to_copy.setNameFilters(QStringList() << "*.elmt");
|
|
||||||
foreach(QString str, dir_to_copy.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
|
|
||||||
QFile::copy(dir_to_copy.canonicalPath() + "/" + str, created_dir.canonicalPath() + "/" + str);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ class FileElementCollectionItem : public ElementCollectionItem
|
|||||||
private:
|
private:
|
||||||
void setPathName(QString path_name);
|
void setPathName(QString path_name);
|
||||||
void populate();
|
void populate();
|
||||||
bool handleElementDrop (const QMimeData *data);
|
// bool handleElementDrop (const QMimeData *data);
|
||||||
bool handleDirectoryDrop (const QMimeData *data);
|
// bool handleDirectoryDrop (const QMimeData *data);
|
||||||
bool createSubDir (QDir dir_to_copy, QDir destination);
|
// bool createSubDir (QDir dir_to_copy, QDir destination);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_path;
|
QString m_path;
|
||||||
|
|||||||
64
sources/ElementsCollection/ui/renamedialog.cpp
Normal file
64
sources/ElementsCollection/ui/renamedialog.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2015 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "renamedialog.h"
|
||||||
|
#include "ui_renamedialog.h"
|
||||||
|
|
||||||
|
RenameDialog::RenameDialog(QString path, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::RenameDialog),
|
||||||
|
m_path(path)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
m_name = m_path.split("/").last();
|
||||||
|
if (m_name.endsWith(".elmt")) m_name.remove(".elmt");
|
||||||
|
ui->m_label->setText(tr("L'élément « %1 » existe déjà. Que souhaitez-vous faire ?").arg(m_path));
|
||||||
|
ui->lineEdit->setText(m_name + QDate::currentDate().toString("dd-MM-yy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
RenameDialog::~RenameDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenameDialog::on_lineEdit_textEdited(const QString &arg1)
|
||||||
|
{
|
||||||
|
if (arg1.isEmpty() || (arg1 == m_name))
|
||||||
|
ui->m_rename_pb->setDisabled(true);
|
||||||
|
else
|
||||||
|
ui->m_rename_pb->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenameDialog::on_m_erase_pb_clicked()
|
||||||
|
{
|
||||||
|
m_action = QET::Erase;
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenameDialog::on_m_rename_pb_clicked()
|
||||||
|
{
|
||||||
|
m_action = QET::Rename;
|
||||||
|
m_new_name = ui->lineEdit->text();
|
||||||
|
if (m_path.endsWith(".elmt")) m_new_name.append(".elmt");
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenameDialog::on_m_cancel_pb_clicked()
|
||||||
|
{
|
||||||
|
m_action = QET::Abort;
|
||||||
|
reject();
|
||||||
|
}
|
||||||
53
sources/ElementsCollection/ui/renamedialog.h
Normal file
53
sources/ElementsCollection/ui/renamedialog.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2015 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef RENAMEDIALOG_H
|
||||||
|
#define RENAMEDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "qet.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RenameDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenameDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RenameDialog(QString path, QWidget *parent = 0);
|
||||||
|
~RenameDialog();
|
||||||
|
|
||||||
|
QString newName() const {return m_new_name;}
|
||||||
|
QET::Action selectedAction() const {return m_action;}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_lineEdit_textEdited(const QString &arg1);
|
||||||
|
void on_m_erase_pb_clicked();
|
||||||
|
void on_m_rename_pb_clicked();
|
||||||
|
void on_m_cancel_pb_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::RenameDialog *ui;
|
||||||
|
QString m_path;
|
||||||
|
QString m_name;
|
||||||
|
QString m_new_name;
|
||||||
|
QET::Action m_action;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RENAMEDIALOG_H
|
||||||
62
sources/ElementsCollection/ui/renamedialog.ui
Normal file
62
sources/ElementsCollection/ui/renamedialog.ui
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RenameDialog</class>
|
||||||
|
<widget class="QDialog" name="RenameDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>284</width>
|
||||||
|
<height>88</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Nouveau nom :</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="m_erase_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>Écraser</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QPushButton" name="m_rename_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>Renommer</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QPushButton" name="m_cancel_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>Annuler</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="m_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -495,6 +495,30 @@ QString QETApp::customElementsDir() {
|
|||||||
return(configDir() + "elements/");
|
return(configDir() + "elements/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETApp::commonElementsDirN
|
||||||
|
* like QString QETApp::commonElementsDir but without "/" at the end
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
QString QETApp::commonElementsDirN()
|
||||||
|
{
|
||||||
|
QString path = commonElementsDir();
|
||||||
|
if (path.endsWith("/")) path.remove(path.length()-1, 1);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETApp::customElementsDirN
|
||||||
|
* like QString QETApp::customElementsDir but without "/" at the end
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
QString QETApp::customElementsDirN()
|
||||||
|
{
|
||||||
|
QString path = customElementsDir();
|
||||||
|
if (path.endsWith("/")) path.remove(path.length()-1, 1);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return the path of the directory containing the common title block
|
@return the path of the directory containing the common title block
|
||||||
templates collection.
|
templates collection.
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ class QETApp : public QETSingleApplication {
|
|||||||
static QString userName();
|
static QString userName();
|
||||||
static QString commonElementsDir();
|
static QString commonElementsDir();
|
||||||
static QString customElementsDir();
|
static QString customElementsDir();
|
||||||
|
static QString commonElementsDirN();
|
||||||
|
static QString customElementsDirN();
|
||||||
static QString commonTitleBlockTemplatesDir();
|
static QString commonTitleBlockTemplatesDir();
|
||||||
static QString customTitleBlockTemplatesDir();
|
static QString customTitleBlockTemplatesDir();
|
||||||
static bool registerProject(QETProject *);
|
static bool registerProject(QETProject *);
|
||||||
|
|||||||
Reference in New Issue
Block a user