New undo command MoveSPoint.
--HG-- branch : feature
This commit is contained in:
parent
7e3dc203dc
commit
0783cc24e1
|
@ -93,10 +93,11 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
pattern = new VContainer();
|
pattern = new VContainer();
|
||||||
|
|
||||||
doc = new VPattern(pattern, &mode, sceneDraw, sceneDetails);
|
doc = new VPattern(pattern, &mode, sceneDraw, sceneDetails);
|
||||||
connect(doc, &VPattern::patternChanged, this, &MainWindow::PatternWasModified);
|
|
||||||
connect(doc, &VPattern::ClearMainWindow, this, &MainWindow::Clear);
|
connect(doc, &VPattern::ClearMainWindow, this, &MainWindow::Clear);
|
||||||
connect(doc, &VPattern::UndoCommand, this, &MainWindow::FullParseFile);
|
connect(doc, &VPattern::UndoCommand, this, &MainWindow::FullParseFile);
|
||||||
|
|
||||||
|
connect(qApp->getUndoStack(), &QUndoStack::cleanChanged, this, &MainWindow::PatternWasModified);
|
||||||
|
|
||||||
InitAutoSave();
|
InitAutoSave();
|
||||||
|
|
||||||
ui->toolBox->setCurrentIndex(0);
|
ui->toolBox->setCurrentIndex(0);
|
||||||
|
@ -1319,7 +1320,6 @@ void MainWindow::Clear()
|
||||||
setCurrentFile("");
|
setCurrentFile("");
|
||||||
pattern->Clear();
|
pattern->Clear();
|
||||||
doc->clear();
|
doc->clear();
|
||||||
doc->setPatternModified(false);
|
|
||||||
sceneDraw->clear();
|
sceneDraw->clear();
|
||||||
sceneDetails->clear();
|
sceneDetails->clear();
|
||||||
CancelTool();
|
CancelTool();
|
||||||
|
@ -1429,7 +1429,7 @@ void MainWindow::FullParseFile()
|
||||||
*/
|
*/
|
||||||
void MainWindow::NewPattern()
|
void MainWindow::NewPattern()
|
||||||
{
|
{
|
||||||
if (doc->isPatternModified() || curFile.isEmpty() == false)
|
if (this->isWindowModified() || curFile.isEmpty() == false)
|
||||||
{
|
{
|
||||||
QProcess *v = new QProcess(this);
|
QProcess *v = new QProcess(this);
|
||||||
v->startDetached(QCoreApplication::applicationFilePath ());
|
v->startDetached(QCoreApplication::applicationFilePath ());
|
||||||
|
@ -1441,10 +1441,10 @@ void MainWindow::NewPattern()
|
||||||
/**
|
/**
|
||||||
* @brief haveChange enable action save if we have unsaved change.
|
* @brief haveChange enable action save if we have unsaved change.
|
||||||
*/
|
*/
|
||||||
void MainWindow::PatternWasModified()
|
void MainWindow::PatternWasModified(bool saved)
|
||||||
{
|
{
|
||||||
setWindowModified(doc->isPatternModified());
|
setWindowModified(!saved);
|
||||||
ui->actionSave->setEnabled(true);
|
ui->actionSave->setEnabled(!saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1657,7 +1657,7 @@ bool MainWindow::SavePattern(const QString &fileName)
|
||||||
*/
|
*/
|
||||||
void MainWindow::AutoSavePattern()
|
void MainWindow::AutoSavePattern()
|
||||||
{
|
{
|
||||||
if (curFile.isEmpty() == false && doc->isPatternModified() == true)
|
if (curFile.isEmpty() == false && this->isWindowModified() == true)
|
||||||
{
|
{
|
||||||
QString autofile = curFile +".autosave";
|
QString autofile = curFile +".autosave";
|
||||||
if (SavePattern(autofile) == false)
|
if (SavePattern(autofile) == false)
|
||||||
|
@ -1676,7 +1676,6 @@ void MainWindow::AutoSavePattern()
|
||||||
void MainWindow::setCurrentFile(const QString &fileName)
|
void MainWindow::setCurrentFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
curFile = fileName;
|
curFile = fileName;
|
||||||
doc->setPatternModified(false);
|
|
||||||
setWindowModified(false);
|
setWindowModified(false);
|
||||||
|
|
||||||
QString shownName = strippedName(curFile);
|
QString shownName = strippedName(curFile);
|
||||||
|
@ -1761,7 +1760,7 @@ void MainWindow::WriteSettings()
|
||||||
*/
|
*/
|
||||||
bool MainWindow::MaybeSave()
|
bool MainWindow::MaybeSave()
|
||||||
{
|
{
|
||||||
if (doc->isPatternModified())
|
if (this->isWindowModified())
|
||||||
{
|
{
|
||||||
QMessageBox::StandardButton ret;
|
QMessageBox::StandardButton ret;
|
||||||
ret = QMessageBox::warning(this, tr("Unsaved change"), tr("The pattern has been modified.\n"
|
ret = QMessageBox::warning(this, tr("Unsaved change"), tr("The pattern has been modified.\n"
|
||||||
|
@ -1994,13 +1993,12 @@ void MainWindow::LoadPattern(const QString &fileName)
|
||||||
|
|
||||||
FullParseFile();
|
FullParseFile();
|
||||||
|
|
||||||
bool patternModified = doc->isPatternModified();
|
bool patternModified = this->isWindowModified();
|
||||||
setCurrentFile(fileName);
|
setCurrentFile(fileName);
|
||||||
if (patternModified)
|
if (patternModified)
|
||||||
{
|
{
|
||||||
//For situation where was fixed wrong formula need return for document status was modified.
|
//For situation where was fixed wrong formula need return for document status was modified.
|
||||||
doc->setPatternModified(patternModified);
|
PatternWasModified(patternModified);
|
||||||
PatternWasModified();
|
|
||||||
}
|
}
|
||||||
helpLabel->setText(tr("File loaded"));
|
helpLabel->setText(tr("File loaded"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public slots:
|
||||||
void ChangedSize(const QString &text);
|
void ChangedSize(const QString &text);
|
||||||
void ChangedHeight(const QString & text);
|
void ChangedHeight(const QString & text);
|
||||||
|
|
||||||
void PatternWasModified();
|
void PatternWasModified(bool saved);
|
||||||
|
|
||||||
void ToolEndLine(bool checked);
|
void ToolEndLine(bool checked);
|
||||||
void ToolLine(bool checked);
|
void ToolLine(bool checked);
|
||||||
|
|
|
@ -191,7 +191,6 @@ qreal VDrawTool::CheckFormula(QString &formula, VContainer *data)
|
||||||
void VDrawTool::AddToCalculation(const QDomElement &domElement)
|
void VDrawTool::AddToCalculation(const QDomElement &domElement)
|
||||||
{
|
{
|
||||||
AddToCal *addToCal = new AddToCal(domElement, doc);
|
AddToCal *addToCal = new AddToCal(domElement, doc);
|
||||||
connect(addToCal, &AddToCal::UnsavedChange, doc, &VPattern::haveLiteChange);
|
|
||||||
connect(addToCal, &AddToCal::NeedFullParsing, doc, &VPattern::NeedFullParsing);
|
connect(addToCal, &AddToCal::NeedFullParsing, doc, &VPattern::NeedFullParsing);
|
||||||
qApp->getUndoStack()->push(addToCal);
|
qApp->getUndoStack()->push(addToCal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ void VToolPoint::RefreshPointGeometry(const VPointF &point)
|
||||||
rec.translate(-rec.center().x(), -rec.center().y());
|
rec.translate(-rec.center().x(), -rec.center().y());
|
||||||
this->setRect(rec);
|
this->setRect(rec);
|
||||||
this->setPos(point.toQPointF());
|
this->setPos(point.toQPointF());
|
||||||
|
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||||
disconnect(namePoint, &VGraphicsSimpleTextItem::NameChangePosition, this, &VToolPoint::NameChangePosition);
|
disconnect(namePoint, &VGraphicsSimpleTextItem::NameChangePosition, this, &VToolPoint::NameChangePosition);
|
||||||
QFont font = namePoint->font();
|
QFont font = namePoint->font();
|
||||||
font.setPointSize(static_cast<qint32>(namePoint->FontSize()/factor));
|
font.setPointSize(static_cast<qint32>(namePoint->FontSize()/factor));
|
||||||
|
|
|
@ -134,21 +134,27 @@ QVariant VToolSinglePoint::itemChange(QGraphicsItem::GraphicsItemChange change,
|
||||||
}
|
}
|
||||||
if (change == ItemPositionHasChanged && scene())
|
if (change == ItemPositionHasChanged && scene())
|
||||||
{
|
{
|
||||||
|
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
|
||||||
// value - this is new position.
|
// value - this is new position.
|
||||||
QPointF newPos = value.toPointF();
|
QPointF newPos = value.toPointF();
|
||||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
|
||||||
if (domElement.isElement())
|
|
||||||
{
|
|
||||||
doc->SetAttribute(domElement, AttrX, QString().setNum(qApp->fromPixel(newPos.x())));
|
|
||||||
doc->SetAttribute(domElement, AttrY, QString().setNum(qApp->fromPixel(newPos.y())));
|
|
||||||
|
|
||||||
QList<QGraphicsView*> list = this->scene()->views();
|
MoveSPoint *moveSP = new MoveSPoint(doc, newPos.x(), newPos.y(), id, this->scene());
|
||||||
VAbstractTool::NewSceneRect(this->scene(), list[0]);
|
connect(moveSP, &MoveSPoint::NeedLiteParsing, doc, &VPattern::LiteParseTree);
|
||||||
|
qApp->getUndoStack()->push(moveSP);
|
||||||
|
|
||||||
//I don't now why but signal does not work.
|
// QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||||
doc->LiteParseTree();
|
// if (domElement.isElement())
|
||||||
emit toolhaveChange();
|
// {
|
||||||
}
|
// doc->SetAttribute(domElement, AttrX, QString().setNum(qApp->fromPixel(newPos.x())));
|
||||||
|
// doc->SetAttribute(domElement, AttrY, QString().setNum(qApp->fromPixel(newPos.y())));
|
||||||
|
|
||||||
|
// QList<QGraphicsView*> list = this->scene()->views();
|
||||||
|
// VAbstractTool::NewSceneRect(this->scene(), list[0]);
|
||||||
|
|
||||||
|
// //I don't now why but signal does not work.
|
||||||
|
// doc->LiteParseTree();
|
||||||
|
// emit toolhaveChange();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
return QGraphicsItem::itemChange(change, value);
|
return QGraphicsItem::itemChange(change, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,8 @@ const QString VPattern::IncrementDescription = QStringLiteral("description");
|
||||||
VPattern::VPattern(VContainer *data, Valentina::Draws *mode, VMainGraphicsScene *sceneDraw,
|
VPattern::VPattern(VContainer *data, Valentina::Draws *mode, VMainGraphicsScene *sceneDraw,
|
||||||
VMainGraphicsScene *sceneDetail, QObject *parent)
|
VMainGraphicsScene *sceneDetail, QObject *parent)
|
||||||
: QObject(parent), VDomDocument(data), nameActivDraw(QString()), tools(QHash<quint32, VDataTool*>()),
|
: QObject(parent), VDomDocument(data), nameActivDraw(QString()), tools(QHash<quint32, VDataTool*>()),
|
||||||
history(QVector<VToolRecord>()), cursor(0), patternPieces(QStringList()), mode(mode), patternModified(false),
|
history(QVector<VToolRecord>()), cursor(0), patternPieces(QStringList()), mode(mode), sceneDraw(sceneDraw),
|
||||||
sceneDraw(sceneDraw), sceneDetail(sceneDetail)
|
sceneDetail(sceneDetail)
|
||||||
{
|
{
|
||||||
SCASSERT(sceneDraw != nullptr);
|
SCASSERT(sceneDraw != nullptr);
|
||||||
SCASSERT(sceneDetail != nullptr);
|
SCASSERT(sceneDetail != nullptr);
|
||||||
|
@ -724,7 +724,6 @@ void VPattern::LiteParseTree()
|
||||||
*/
|
*/
|
||||||
void VPattern::haveLiteChange()
|
void VPattern::haveLiteChange()
|
||||||
{
|
{
|
||||||
patternModified = true;
|
|
||||||
emit patternChanged();
|
emit patternChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,9 +177,6 @@ private:
|
||||||
/** @brief mode current draw mode. */
|
/** @brief mode current draw mode. */
|
||||||
Valentina::Draws *mode;
|
Valentina::Draws *mode;
|
||||||
|
|
||||||
/** @brief fileModified true if exist change in file. */
|
|
||||||
bool patternModified;
|
|
||||||
|
|
||||||
VMainGraphicsScene *sceneDraw;
|
VMainGraphicsScene *sceneDraw;
|
||||||
VMainGraphicsScene *sceneDetail;
|
VMainGraphicsScene *sceneDetail;
|
||||||
|
|
||||||
|
@ -250,18 +247,6 @@ inline quint32 VPattern::getCursor() const
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
inline bool VPattern::isPatternModified() const
|
|
||||||
{
|
|
||||||
return patternModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
inline void VPattern::setPatternModified(bool value)
|
|
||||||
{
|
|
||||||
patternModified = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
inline QStringList VPattern::getPatternPieces() const
|
inline QStringList VPattern::getPatternPieces() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "vundocommands.h"
|
#include "vundocommands.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "../widgets/vapplication.h"
|
||||||
|
#include "../tools/vabstracttool.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
AddToCal::AddToCal(const QDomElement &xml, VPattern *doc, QUndoCommand *parent)
|
AddToCal::AddToCal(const QDomElement &xml, VPattern *doc, QUndoCommand *parent)
|
||||||
|
@ -94,11 +96,7 @@ void AddToCal::redo()
|
||||||
{
|
{
|
||||||
qDebug()<<"Can't find tag Calculation"<< Q_FUNC_INFO;
|
qDebug()<<"Can't find tag Calculation"<< Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
if (redoFlag == false)
|
if (redoFlag)
|
||||||
{
|
|
||||||
emit UnsavedChange();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
emit NeedFullParsing();
|
emit NeedFullParsing();
|
||||||
}
|
}
|
||||||
|
@ -157,3 +155,84 @@ void AddPatternPiece::redo()
|
||||||
}
|
}
|
||||||
redoFlag = true;
|
redoFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------MoveSPoint---------------------------------------------------------------
|
||||||
|
MoveSPoint::MoveSPoint(VPattern *doc, const double &x, const double &y, const quint32 &id, QGraphicsScene *scene,
|
||||||
|
QUndoCommand *parent)
|
||||||
|
: QObject(), QUndoCommand(parent), doc(doc), oldX(10.0), oldY(10.0), newX(x), newY(y), sPointId(id), scene(scene)
|
||||||
|
{
|
||||||
|
setText(tr("Move single point"));
|
||||||
|
|
||||||
|
SCASSERT(scene != nullptr);
|
||||||
|
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||||
|
if (domElement.isElement())
|
||||||
|
{
|
||||||
|
oldX = qApp->toPixel(doc->GetParametrDouble(domElement, VAbstractTool::AttrX, "10.0"));
|
||||||
|
oldY = qApp->toPixel(doc->GetParametrDouble(domElement, VAbstractTool::AttrY, "10.0"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug()<<"Can't find spoint with id ="<< sPointId << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
MoveSPoint::~MoveSPoint()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void MoveSPoint::undo()
|
||||||
|
{
|
||||||
|
QDomElement domElement = doc->elementById(QString().setNum(sPointId));
|
||||||
|
if (domElement.isElement())
|
||||||
|
{
|
||||||
|
doc->SetAttribute(domElement, VAbstractTool::AttrX, QString().setNum(qApp->fromPixel(oldX)));
|
||||||
|
doc->SetAttribute(domElement, VAbstractTool::AttrY, QString().setNum(qApp->fromPixel(oldY)));
|
||||||
|
|
||||||
|
emit NeedLiteParsing();
|
||||||
|
|
||||||
|
QList<QGraphicsView*> list = scene->views();
|
||||||
|
VAbstractTool::NewSceneRect(scene, list[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug()<<"Can't find spoint with id ="<< sPointId << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void MoveSPoint::redo()
|
||||||
|
{
|
||||||
|
QDomElement domElement = doc->elementById(QString().setNum(sPointId));
|
||||||
|
if (domElement.isElement())
|
||||||
|
{
|
||||||
|
doc->SetAttribute(domElement, VAbstractTool::AttrX, QString().setNum(qApp->fromPixel(newX)));
|
||||||
|
doc->SetAttribute(domElement, VAbstractTool::AttrY, QString().setNum(qApp->fromPixel(newY)));
|
||||||
|
|
||||||
|
emit NeedLiteParsing();
|
||||||
|
|
||||||
|
QList<QGraphicsView*> list = scene->views();
|
||||||
|
VAbstractTool::NewSceneRect(scene, list[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug()<<"Can't find spoint with id ="<< sPointId << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool MoveSPoint::mergeWith(const QUndoCommand *command)
|
||||||
|
{
|
||||||
|
const MoveSPoint *moveCommand = static_cast<const MoveSPoint *>(command);
|
||||||
|
SCASSERT(moveCommand != nullptr);
|
||||||
|
const quint32 id = moveCommand->getSPointId();
|
||||||
|
|
||||||
|
if (id != sPointId)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
newX = moveCommand->getNewX();
|
||||||
|
newY = moveCommand->getNewY();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "vpattern.h"
|
#include "vpattern.h"
|
||||||
|
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
|
#include <QGraphicsScene>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
|
||||||
class AddToCal : public QObject, public QUndoCommand
|
class AddToCal : public QObject, public QUndoCommand
|
||||||
|
@ -43,7 +44,6 @@ public:
|
||||||
virtual void undo();
|
virtual void undo();
|
||||||
virtual void redo();
|
virtual void redo();
|
||||||
signals:
|
signals:
|
||||||
void UnsavedChange();
|
|
||||||
void NeedFullParsing();
|
void NeedFullParsing();
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(AddToCal)
|
Q_DISABLE_COPY(AddToCal)
|
||||||
|
@ -54,6 +54,7 @@ private:
|
||||||
bool redoFlag;
|
bool redoFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------AddPatternPiece-----------------------------------------------------------
|
||||||
class AddPatternPiece : public QObject, public QUndoCommand
|
class AddPatternPiece : public QObject, public QUndoCommand
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -76,4 +77,57 @@ private:
|
||||||
QString mPath;
|
QString mPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------MoveSPoint--------------------------------------------------------------
|
||||||
|
class MoveSPoint : public QObject, public QUndoCommand
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MoveSPoint(VPattern *doc, const double &x, const double &y, const quint32 &id, QGraphicsScene *scene,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~MoveSPoint();
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
virtual bool mergeWith(const QUndoCommand *command);
|
||||||
|
virtual int id() const;
|
||||||
|
quint32 getSPointId() const;
|
||||||
|
double getNewX() const;
|
||||||
|
double getNewY() const;
|
||||||
|
signals:
|
||||||
|
void NeedLiteParsing();
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(MoveSPoint)
|
||||||
|
enum { Id = 0 };
|
||||||
|
VPattern *doc;
|
||||||
|
double oldX;
|
||||||
|
double oldY;
|
||||||
|
double newX;
|
||||||
|
double newY;
|
||||||
|
quint32 sPointId;
|
||||||
|
QGraphicsScene *scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
inline int MoveSPoint::id() const
|
||||||
|
{
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
inline quint32 MoveSPoint::getSPointId() const
|
||||||
|
{
|
||||||
|
return sPointId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
inline double MoveSPoint::getNewX() const
|
||||||
|
{
|
||||||
|
return newX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
inline double MoveSPoint::getNewY() const
|
||||||
|
{
|
||||||
|
return newY;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VUNDOCOMMANDS_H
|
#endif // VUNDOCOMMANDS_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user