Gui: Prepare for clang-format (#16051)
* Gui: Prepare for clang-format * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -53,47 +53,49 @@
|
||||
using namespace Gui::Dialog;
|
||||
|
||||
|
||||
EditTableView::EditTableView(QWidget *parent)
|
||||
EditTableView::EditTableView(QWidget* parent)
|
||||
: QTableView(parent)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void EditTableView::keyPressEvent(QKeyEvent *event)
|
||||
void EditTableView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if ((event->matches(QKeySequence::Delete)
|
||||
|| event->matches(QKeySequence::Backspace))
|
||||
if ((event->matches(QKeySequence::Delete) || event->matches(QKeySequence::Backspace))
|
||||
&& model()) {
|
||||
removeOne();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
QAbstractItemView::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void EditTableView::removeOne()
|
||||
{
|
||||
if (!model() || !selectionModel())
|
||||
if (!model() || !selectionModel()) {
|
||||
return;
|
||||
}
|
||||
int row = currentIndex().row();
|
||||
model()->removeRow(row, rootIndex());
|
||||
QModelIndex idx = model()->index(row, 0, rootIndex());
|
||||
if (!idx.isValid())
|
||||
if (!idx.isValid()) {
|
||||
idx = model()->index(row - 1, 0, rootIndex());
|
||||
}
|
||||
selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
void EditTableView::removeAll()
|
||||
{
|
||||
if (model())
|
||||
if (model()) {
|
||||
model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
}
|
||||
SqueezeLabel::SqueezeLabel(QWidget* parent)
|
||||
: QLabel(parent)
|
||||
{}
|
||||
|
||||
void SqueezeLabel::paintEvent(QPaintEvent *event)
|
||||
void SqueezeLabel::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QFontMetrics fm = fontMetrics();
|
||||
if (Gui::QtTools::horizontalAdvance(fm, text()) > contentsRect().width()) {
|
||||
@@ -102,52 +104,59 @@ void SqueezeLabel::paintEvent(QPaintEvent *event)
|
||||
setText(elided);
|
||||
QLabel::paintEvent(event);
|
||||
setText(oldText);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
QLabel::paintEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define AUTOSAVE_IN 1000 * 3 // seconds
|
||||
#define MAXWAIT 1000 * 15 // seconds
|
||||
#define AUTOSAVE_IN 1000 * 3 // seconds
|
||||
#define MAXWAIT 1000 * 15 // seconds
|
||||
|
||||
AutoSaver::AutoSaver(QObject *parent) : QObject(parent)
|
||||
AutoSaver::AutoSaver(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
Q_ASSERT(parent);
|
||||
}
|
||||
|
||||
AutoSaver::~AutoSaver()
|
||||
{
|
||||
if (m_timer.isActive())
|
||||
if (m_timer.isActive()) {
|
||||
qWarning() << "AutoSaver: still active when destroyed, changes not saved.";
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::changeOccurred()
|
||||
{
|
||||
if (!m_firstChange.isValid())
|
||||
if (!m_firstChange.isValid()) {
|
||||
m_firstChange.start();
|
||||
}
|
||||
|
||||
if (m_firstChange.elapsed() > MAXWAIT) {
|
||||
saveIfNecessary();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m_timer.start(AUTOSAVE_IN, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::timerEvent(QTimerEvent *event)
|
||||
void AutoSaver::timerEvent(QTimerEvent* event)
|
||||
{
|
||||
if (event->timerId() == m_timer.timerId()) {
|
||||
saveIfNecessary();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
QObject::timerEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoSaver::saveIfNecessary()
|
||||
{
|
||||
if (!m_timer.isActive())
|
||||
if (!m_timer.isActive()) {
|
||||
return;
|
||||
}
|
||||
m_timer.stop();
|
||||
m_firstChange = QElapsedTimer();
|
||||
if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) {
|
||||
@@ -157,13 +166,17 @@ void AutoSaver::saveIfNecessary()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
NetworkAccessManager::NetworkAccessManager(QObject *parent)
|
||||
NetworkAccessManager::NetworkAccessManager(QObject* parent)
|
||||
: QNetworkAccessManager(parent)
|
||||
{
|
||||
connect(this, &QNetworkAccessManager::authenticationRequired,
|
||||
this, &NetworkAccessManager::authenticationRequired);
|
||||
connect(this, &QNetworkAccessManager::proxyAuthenticationRequired,
|
||||
this, &NetworkAccessManager::proxyAuthenticationRequired);
|
||||
connect(this,
|
||||
&QNetworkAccessManager::authenticationRequired,
|
||||
this,
|
||||
&NetworkAccessManager::authenticationRequired);
|
||||
connect(this,
|
||||
&QNetworkAccessManager::proxyAuthenticationRequired,
|
||||
this,
|
||||
&NetworkAccessManager::proxyAuthenticationRequired);
|
||||
|
||||
auto diskCache = new QNetworkDiskCache(this);
|
||||
QString location = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
@@ -171,9 +184,9 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent)
|
||||
setCache(diskCache);
|
||||
}
|
||||
|
||||
void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
|
||||
void NetworkAccessManager::authenticationRequired(QNetworkReply* reply, QAuthenticator* auth)
|
||||
{
|
||||
QWidget *mainWindow = Gui::getMainWindow();
|
||||
QWidget* mainWindow = Gui::getMainWindow();
|
||||
|
||||
QDialog dialog(mainWindow);
|
||||
dialog.setWindowFlags(Qt::Sheet);
|
||||
@@ -183,7 +196,8 @@ void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthent
|
||||
dialog.adjustSize();
|
||||
|
||||
QString introMessage = tr("<qt>Enter username and password for \"%1\" at %2</qt>");
|
||||
introMessage = introMessage.arg(QString(reply->url().toString()).toHtmlEscaped(), QString(reply->url().toString()).toHtmlEscaped());
|
||||
introMessage = introMessage.arg(QString(reply->url().toString()).toHtmlEscaped(),
|
||||
QString(reply->url().toString()).toHtmlEscaped());
|
||||
passwordDialog.siteDescription->setText(introMessage);
|
||||
passwordDialog.siteDescription->setWordWrap(true);
|
||||
|
||||
@@ -193,9 +207,10 @@ void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthent
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth)
|
||||
void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy& proxy,
|
||||
QAuthenticator* auth)
|
||||
{
|
||||
QWidget *mainWindow = Gui::getMainWindow();
|
||||
QWidget* mainWindow = Gui::getMainWindow();
|
||||
|
||||
QDialog dialog(mainWindow);
|
||||
dialog.setWindowFlags(Qt::Sheet);
|
||||
@@ -217,7 +232,7 @@ void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &prox
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
DownloadItem::DownloadItem(QNetworkReply *reply, bool requestFileName, QWidget *parent)
|
||||
DownloadItem::DownloadItem(QNetworkReply* reply, bool requestFileName, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_reply(reply)
|
||||
, m_requestFileName(requestFileName)
|
||||
@@ -238,6 +253,7 @@ DownloadItem::DownloadItem(QNetworkReply *reply, bool requestFileName, QWidget *
|
||||
|
||||
void DownloadItem::init()
|
||||
{
|
||||
// clang-format off
|
||||
if (!m_reply)
|
||||
return;
|
||||
|
||||
@@ -266,6 +282,7 @@ void DownloadItem::init()
|
||||
error(m_reply->error());
|
||||
finished();
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
QString DownloadItem::getDownloadDirectory() const
|
||||
@@ -273,8 +290,11 @@ QString DownloadItem::getDownloadDirectory() const
|
||||
QString exe = QString::fromStdString(App::Application::getExecutableName());
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
QString dirPath = QDir(path).filePath(exe);
|
||||
Base::Reference<ParameterGrp> hPath = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")->GetGroup("General");
|
||||
Base::Reference<ParameterGrp> hPath = App::GetApplication()
|
||||
.GetUserParameter()
|
||||
.GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")
|
||||
->GetGroup("General");
|
||||
std::string dir = hPath->GetASCII("DownloadPath", "");
|
||||
if (!dir.empty()) {
|
||||
dirPath = QString::fromUtf8(dir.c_str());
|
||||
@@ -292,11 +312,14 @@ void DownloadItem::getFileName()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.beginGroup(QLatin1String("downloadmanager"));
|
||||
//QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
|
||||
// QString defaultLocation =
|
||||
// QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
|
||||
QString defaultLocation = getDownloadDirectory();
|
||||
QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString();
|
||||
if (!downloadDirectory.isEmpty())
|
||||
QString downloadDirectory =
|
||||
settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString();
|
||||
if (!downloadDirectory.isEmpty()) {
|
||||
downloadDirectory += QLatin1Char('/');
|
||||
}
|
||||
|
||||
QString defaultFileName = saveFileName(downloadDirectory);
|
||||
QString fileName = defaultFileName;
|
||||
@@ -304,23 +327,26 @@ void DownloadItem::getFileName()
|
||||
fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);
|
||||
if (fileName.isEmpty()) {
|
||||
m_reply->close();
|
||||
fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName()));
|
||||
fileNameLabel->setText(
|
||||
tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_output.setFileName(fileName);
|
||||
fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName());
|
||||
fileNameLabel->setToolTip(m_output.fileName());
|
||||
if (m_requestFileName)
|
||||
if (m_requestFileName) {
|
||||
downloadReadyRead();
|
||||
}
|
||||
}
|
||||
|
||||
QString DownloadItem::saveFileName(const QString &directory) const
|
||||
QString DownloadItem::saveFileName(const QString& directory) const
|
||||
{
|
||||
// Move this function into QNetworkReply to also get file name sent from the server
|
||||
QString path = m_url.path();
|
||||
if (!m_fileName.isEmpty())
|
||||
if (!m_fileName.isEmpty()) {
|
||||
path = m_fileName;
|
||||
}
|
||||
QFileInfo info(path);
|
||||
QString baseName = info.completeBaseName();
|
||||
QString endName = info.suffix();
|
||||
@@ -334,7 +360,8 @@ QString DownloadItem::saveFileName(const QString &directory) const
|
||||
// already exists, don't overwrite
|
||||
int i = 1;
|
||||
do {
|
||||
name = directory + baseName + QLatin1Char('-') + QString::number(i++) + QLatin1Char('.') + endName;
|
||||
name = directory + baseName + QLatin1Char('-') + QString::number(i++) + QLatin1Char('.')
|
||||
+ endName;
|
||||
} while (QFile::exists(name));
|
||||
}
|
||||
return name;
|
||||
@@ -366,7 +393,8 @@ void DownloadItem::open()
|
||||
if (doc) {
|
||||
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
|
||||
Gui::Application::Instance->importFrom(it.key().toUtf8(),
|
||||
doc->getDocument()->getName(), it.value().toLatin1());
|
||||
doc->getDocument()->getName(),
|
||||
it.value().toLatin1());
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -390,8 +418,9 @@ void DownloadItem::openFolder()
|
||||
|
||||
void DownloadItem::tryAgain()
|
||||
{
|
||||
if (!tryAgainButton->isEnabled())
|
||||
if (!tryAgainButton->isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
tryAgainButton->setEnabled(false);
|
||||
tryAgainButton->setVisible(false);
|
||||
@@ -399,17 +428,20 @@ void DownloadItem::tryAgain()
|
||||
stopButton->setVisible(true);
|
||||
progressBar->setVisible(true);
|
||||
|
||||
QNetworkReply *r = DownloadManager::getInstance()->networkAccessManager()->get(QNetworkRequest(m_url));
|
||||
if (m_reply)
|
||||
QNetworkReply* r =
|
||||
DownloadManager::getInstance()->networkAccessManager()->get(QNetworkRequest(m_url));
|
||||
if (m_reply) {
|
||||
m_reply->deleteLater();
|
||||
if (m_output.exists())
|
||||
}
|
||||
if (m_output.exists()) {
|
||||
m_output.remove();
|
||||
}
|
||||
m_reply = r;
|
||||
init();
|
||||
Q_EMIT statusChanged();
|
||||
}
|
||||
|
||||
void DownloadItem::contextMenuEvent (QContextMenuEvent * e)
|
||||
void DownloadItem::contextMenuEvent(QContextMenuEvent* e)
|
||||
{
|
||||
QMenu menu;
|
||||
QAction* a = menu.addAction(tr("Open containing folder"), this, &DownloadItem::openFolder);
|
||||
@@ -419,15 +451,17 @@ void DownloadItem::contextMenuEvent (QContextMenuEvent * e)
|
||||
|
||||
void DownloadItem::downloadReadyRead()
|
||||
{
|
||||
if (m_requestFileName && m_output.fileName().isEmpty())
|
||||
if (m_requestFileName && m_output.fileName().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!m_output.isOpen()) {
|
||||
// in case someone else has already put a file there
|
||||
if (!m_requestFileName)
|
||||
if (!m_requestFileName) {
|
||||
getFileName();
|
||||
}
|
||||
if (!m_output.open(QIODevice::WriteOnly)) {
|
||||
downloadInfoLabel->setText(tr("Error opening saved file: %1")
|
||||
.arg(m_output.errorString()));
|
||||
downloadInfoLabel->setText(
|
||||
tr("Error opening saved file: %1").arg(m_output.errorString()));
|
||||
stopButton->click();
|
||||
Q_EMIT statusChanged();
|
||||
return;
|
||||
@@ -436,8 +470,7 @@ void DownloadItem::downloadReadyRead()
|
||||
Q_EMIT statusChanged();
|
||||
}
|
||||
if (-1 == m_output.write(m_reply->readAll())) {
|
||||
downloadInfoLabel->setText(tr("Error saving: %1")
|
||||
.arg(m_output.errorString()));
|
||||
downloadInfoLabel->setText(tr("Error saving: %1").arg(m_output.errorString()));
|
||||
stopButton->click();
|
||||
}
|
||||
}
|
||||
@@ -457,26 +490,32 @@ void DownloadItem::metaDataChanged()
|
||||
QByteArray header = m_reply->rawHeader(QByteArray("Content-Disposition"));
|
||||
int index = header.indexOf("filename=");
|
||||
if (index >= 0) {
|
||||
header = header.mid(index+9);
|
||||
if (header.startsWith("\"") || header.startsWith("'"))
|
||||
header = header.mid(index + 9);
|
||||
if (header.startsWith("\"") || header.startsWith("'")) {
|
||||
header = header.mid(1);
|
||||
if ((index = header.lastIndexOf("\"")) > 0)
|
||||
}
|
||||
if ((index = header.lastIndexOf("\"")) > 0) {
|
||||
header = header.left(index);
|
||||
else if ((index = header.lastIndexOf("'")) > 0)
|
||||
}
|
||||
else if ((index = header.lastIndexOf("'")) > 0) {
|
||||
header = header.left(index);
|
||||
}
|
||||
m_fileName = QUrl::fromPercentEncoding(header);
|
||||
}
|
||||
// Sometimes "filename=" and "filename*=UTF-8''" is set.
|
||||
// So, search for this too.
|
||||
index = header.indexOf("filename*=UTF-8''");
|
||||
if (index >= 0) {
|
||||
header = header.mid(index+17);
|
||||
if (header.startsWith("\"") || header.startsWith("'"))
|
||||
header = header.mid(index + 17);
|
||||
if (header.startsWith("\"") || header.startsWith("'")) {
|
||||
header = header.mid(1);
|
||||
if ((index = header.lastIndexOf("\"")) > 0)
|
||||
}
|
||||
if ((index = header.lastIndexOf("\"")) > 0) {
|
||||
header = header.left(index);
|
||||
else if ((index = header.lastIndexOf("'")) > 0)
|
||||
}
|
||||
else if ((index = header.lastIndexOf("'")) > 0) {
|
||||
header = header.left(index);
|
||||
}
|
||||
m_fileName = QUrl::fromPercentEncoding(header);
|
||||
}
|
||||
}
|
||||
@@ -497,18 +536,28 @@ void DownloadItem::metaDataChanged()
|
||||
url = redirectUrl;
|
||||
|
||||
disconnect(m_reply, &QNetworkReply::readyRead, this, &DownloadItem::downloadReadyRead);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
|
||||
disconnect(m_reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::error), this, &DownloadItem::error);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
disconnect(m_reply,
|
||||
qOverload<QNetworkReply::NetworkError>(&QNetworkReply::error),
|
||||
this,
|
||||
&DownloadItem::error);
|
||||
#else
|
||||
disconnect(m_reply, &QNetworkReply::errorOccurred, this, &DownloadItem::error);
|
||||
#endif
|
||||
disconnect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadItem::downloadProgress);
|
||||
disconnect(m_reply, &QNetworkReply::metaDataChanged, this, &DownloadItem::metaDataChanged);
|
||||
disconnect(m_reply,
|
||||
&QNetworkReply::downloadProgress,
|
||||
this,
|
||||
&DownloadItem::downloadProgress);
|
||||
disconnect(m_reply,
|
||||
&QNetworkReply::metaDataChanged,
|
||||
this,
|
||||
&DownloadItem::metaDataChanged);
|
||||
disconnect(m_reply, &QNetworkReply::finished, this, &DownloadItem::finished);
|
||||
m_reply->close();
|
||||
m_reply->deleteLater();
|
||||
|
||||
m_reply = DownloadManager::getInstance()->networkAccessManager()->get(QNetworkRequest(url));
|
||||
m_reply =
|
||||
DownloadManager::getInstance()->networkAccessManager()->get(QNetworkRequest(url));
|
||||
init();
|
||||
}
|
||||
}
|
||||
@@ -520,7 +569,8 @@ void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||
if (bytesTotal == -1) {
|
||||
progressBar->setValue(0);
|
||||
progressBar->setMaximum(0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
progressBar->setValue(bytesReceived);
|
||||
progressBar->setMaximum(bytesTotal);
|
||||
}
|
||||
@@ -543,28 +593,30 @@ void DownloadItem::updateInfoLabel()
|
||||
timeRemaining = floor(timeRemaining);
|
||||
|
||||
// When downloading the eta should never be 0
|
||||
if (timeRemaining == 0)
|
||||
if (timeRemaining == 0) {
|
||||
timeRemaining = 1;
|
||||
}
|
||||
|
||||
QString info;
|
||||
if (running) {
|
||||
QString remaining;
|
||||
if (bytesTotal != 0)
|
||||
remaining = tr("- %4 %5 remaining")
|
||||
.arg(timeRemaining)
|
||||
.arg(timeRemainingString);
|
||||
if (bytesTotal != 0) {
|
||||
remaining = tr("- %4 %5 remaining").arg(timeRemaining).arg(timeRemainingString);
|
||||
}
|
||||
info = QString(tr("%1 of %2 (%3/sec) %4"))
|
||||
.arg(dataString(m_bytesReceived),
|
||||
bytesTotal == 0 ? tr("?") : dataString(bytesTotal),
|
||||
dataString((int)speed),
|
||||
remaining);
|
||||
} else {
|
||||
if (m_bytesReceived == bytesTotal)
|
||||
.arg(dataString(m_bytesReceived),
|
||||
bytesTotal == 0 ? tr("?") : dataString(bytesTotal),
|
||||
dataString((int)speed),
|
||||
remaining);
|
||||
}
|
||||
else {
|
||||
if (m_bytesReceived == bytesTotal) {
|
||||
info = dataString(m_output.size());
|
||||
else
|
||||
info = tr("%1 of %2 - Stopped")
|
||||
.arg(dataString(m_bytesReceived),
|
||||
dataString(bytesTotal));
|
||||
}
|
||||
else {
|
||||
info =
|
||||
tr("%1 of %2 - Stopped").arg(dataString(m_bytesReceived), dataString(bytesTotal));
|
||||
}
|
||||
}
|
||||
downloadInfoLabel->setText(info);
|
||||
}
|
||||
@@ -574,11 +626,13 @@ QString DownloadItem::dataString(int size) const
|
||||
QString unit;
|
||||
if (size < 1024) {
|
||||
unit = tr("bytes");
|
||||
} else if (size < 1024*1024) {
|
||||
}
|
||||
else if (size < 1024 * 1024) {
|
||||
size /= 1024;
|
||||
unit = tr("kB");
|
||||
} else {
|
||||
size /= 1024*1024;
|
||||
}
|
||||
else {
|
||||
size /= 1024 * 1024;
|
||||
unit = tr("MB");
|
||||
}
|
||||
return QString(QLatin1String("%1 %2")).arg(size).arg(unit);
|
||||
|
||||
Reference in New Issue
Block a user