forked from qt-creator/qt-creator
RemoteLinux: Use Argument and Working directory aspects in run config
Also some cosmetics in the run config widget setup. Change-Id: I02503d808b5ee7f81f46520f9e6d1750c2cd5de9 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
#include <utils/fancylineedit.h>
|
#include <utils/fancylineedit.h>
|
||||||
#include <utils/pathchooser.h>
|
#include <utils/pathchooser.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
@@ -264,7 +265,12 @@ void ArgumentsAspect::setArguments(const QString &arguments)
|
|||||||
|
|
||||||
void ArgumentsAspect::fromMap(const QVariantMap &map)
|
void ArgumentsAspect::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
m_arguments = map.value(settingsKey()).toString();
|
QVariant args = map.value(settingsKey());
|
||||||
|
// Until 3.7 a QStringList was stored for Remote Linux
|
||||||
|
if (args.type() == QVariant::StringList)
|
||||||
|
m_arguments = QtcProcess::joinArgs(args.toStringList(), OsTypeLinux);
|
||||||
|
else
|
||||||
|
m_arguments = args.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArgumentsAspect::toMap(QVariantMap &map) const
|
void ArgumentsAspect::toMap(QVariantMap &map) const
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <projectexplorer/deploymentdata.h>
|
#include <projectexplorer/deploymentdata.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/runconfigurationaspects.h>
|
||||||
#include <projectexplorer/runnables.h>
|
#include <projectexplorer/runnables.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <qtsupport/qtoutputformatter.h>
|
#include <qtsupport/qtoutputformatter.h>
|
||||||
@@ -55,10 +56,8 @@ class RemoteLinuxRunConfigurationPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString targetName;
|
QString targetName;
|
||||||
QString arguments;
|
|
||||||
bool useAlternateRemoteExecutable = false;
|
bool useAlternateRemoteExecutable = false;
|
||||||
QString alternateRemoteExecutable;
|
QString alternateRemoteExecutable;
|
||||||
QString workingDirectory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -75,6 +74,9 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::I
|
|||||||
{
|
{
|
||||||
addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
|
addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
|
||||||
|
|
||||||
|
addExtraAspect(new ArgumentsAspect(this, ArgumentsKey));
|
||||||
|
addExtraAspect(new WorkingDirectoryAspect(this, WorkingDirectoryKey));
|
||||||
|
|
||||||
connect(target, &Target::deploymentDataChanged,
|
connect(target, &Target::deploymentDataChanged,
|
||||||
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
|
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
|
||||||
connect(target, &Target::applicationTargetsChanged,
|
connect(target, &Target::applicationTargetsChanged,
|
||||||
@@ -109,19 +111,17 @@ Runnable RemoteLinuxRunConfiguration::runnable() const
|
|||||||
StandardRunnable r;
|
StandardRunnable r;
|
||||||
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
|
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
|
||||||
r.executable = remoteExecutableFilePath();
|
r.executable = remoteExecutableFilePath();
|
||||||
r.commandLineArguments = arguments();
|
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
|
||||||
r.workingDirectory = workingDirectory();
|
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap RemoteLinuxRunConfiguration::toMap() const
|
QVariantMap RemoteLinuxRunConfiguration::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap map = RunConfiguration::toMap();
|
QVariantMap map = RunConfiguration::toMap();
|
||||||
map.insert(QLatin1String(ArgumentsKey), d->arguments);
|
|
||||||
map.insert(QLatin1String(TargetNameKey), d->targetName);
|
map.insert(QLatin1String(TargetNameKey), d->targetName);
|
||||||
map.insert(QLatin1String(UseAlternateExeKey), d->useAlternateRemoteExecutable);
|
map.insert(QLatin1String(UseAlternateExeKey), d->useAlternateRemoteExecutable);
|
||||||
map.insert(QLatin1String(AlternateExeKey), d->alternateRemoteExecutable);
|
map.insert(QLatin1String(AlternateExeKey), d->alternateRemoteExecutable);
|
||||||
map.insert(QLatin1String(WorkingDirectoryKey), d->workingDirectory);
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,15 +135,9 @@ bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
if (!RunConfiguration::fromMap(map))
|
if (!RunConfiguration::fromMap(map))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QVariant args = map.value(QLatin1String(ArgumentsKey));
|
|
||||||
if (args.type() == QVariant::StringList) // Until 3.7 a QStringList was stored.
|
|
||||||
d->arguments = QtcProcess::joinArgs(args.toStringList(), OsTypeLinux);
|
|
||||||
else
|
|
||||||
d->arguments = args.toString();
|
|
||||||
d->targetName = map.value(QLatin1String(TargetNameKey)).toString();
|
d->targetName = map.value(QLatin1String(TargetNameKey)).toString();
|
||||||
d->useAlternateRemoteExecutable = map.value(QLatin1String(UseAlternateExeKey), false).toBool();
|
d->useAlternateRemoteExecutable = map.value(QLatin1String(UseAlternateExeKey), false).toBool();
|
||||||
d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString();
|
d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString();
|
||||||
d->workingDirectory = map.value(QLatin1String(WorkingDirectoryKey)).toString();
|
|
||||||
|
|
||||||
// Hack for old-style mangled ids. FIXME: Remove.
|
// Hack for old-style mangled ids. FIXME: Remove.
|
||||||
if (d->targetName.isEmpty()) {
|
if (d->targetName.isEmpty()) {
|
||||||
@@ -160,11 +154,6 @@ QString RemoteLinuxRunConfiguration::defaultDisplayName() const
|
|||||||
return RunConfigurationFactory::decoratedTargetName(d->targetName, target());
|
return RunConfigurationFactory::decoratedTargetName(d->targetName, target());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RemoteLinuxRunConfiguration::arguments() const
|
|
||||||
{
|
|
||||||
return d->arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RemoteLinuxRunConfiguration::localExecutableFilePath() const
|
QString RemoteLinuxRunConfiguration::localExecutableFilePath() const
|
||||||
{
|
{
|
||||||
return target()->applicationTargets().targetFilePath(d->targetName).toString();
|
return target()->applicationTargets().targetFilePath(d->targetName).toString();
|
||||||
@@ -182,21 +171,6 @@ QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const
|
|||||||
? alternateRemoteExecutable() : defaultRemoteExecutableFilePath();
|
? alternateRemoteExecutable() : defaultRemoteExecutableFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxRunConfiguration::setArguments(const QString &args)
|
|
||||||
{
|
|
||||||
d->arguments = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RemoteLinuxRunConfiguration::workingDirectory() const
|
|
||||||
{
|
|
||||||
return d->workingDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxRunConfiguration::setWorkingDirectory(const QString &wd)
|
|
||||||
{
|
|
||||||
d->workingDirectory = wd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxRunConfiguration::setUseAlternateExecutable(bool useAlternate)
|
void RemoteLinuxRunConfiguration::setUseAlternateExecutable(bool useAlternate)
|
||||||
{
|
{
|
||||||
d->useAlternateRemoteExecutable = useAlternate;
|
d->useAlternateRemoteExecutable = useAlternate;
|
||||||
|
@@ -53,10 +53,6 @@ public:
|
|||||||
QString localExecutableFilePath() const;
|
QString localExecutableFilePath() const;
|
||||||
QString defaultRemoteExecutableFilePath() const;
|
QString defaultRemoteExecutableFilePath() const;
|
||||||
QString remoteExecutableFilePath() const;
|
QString remoteExecutableFilePath() const;
|
||||||
QString arguments() const;
|
|
||||||
void setArguments(const QString &args);
|
|
||||||
QString workingDirectory() const;
|
|
||||||
void setWorkingDirectory(const QString &wd);
|
|
||||||
void setAlternateRemoteExecutable(const QString &exe);
|
void setAlternateRemoteExecutable(const QString &exe);
|
||||||
QString alternateRemoteExecutable() const;
|
QString alternateRemoteExecutable() const;
|
||||||
void setUseAlternateExecutable(bool useAlternate);
|
void setUseAlternateExecutable(bool useAlternate);
|
||||||
|
@@ -27,19 +27,19 @@
|
|||||||
|
|
||||||
#include "remotelinuxrunconfiguration.h"
|
#include "remotelinuxrunconfiguration.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfigurationaspects.h>
|
||||||
|
|
||||||
#include <utils/detailswidget.h>
|
#include <utils/detailswidget.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QComboBox>
|
#include <QDir>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPushButton>
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -48,7 +48,7 @@ class RemoteLinuxRunConfigurationWidgetPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RemoteLinuxRunConfigurationWidgetPrivate(RemoteLinuxRunConfiguration *runConfig)
|
RemoteLinuxRunConfigurationWidgetPrivate(RemoteLinuxRunConfiguration *runConfig)
|
||||||
: runConfiguration(runConfig), ignoreChange(false)
|
: runConfiguration(runConfig)
|
||||||
{
|
{
|
||||||
const auto selectable = Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse;
|
const auto selectable = Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse;
|
||||||
localExecutableLabel.setTextInteractionFlags(selectable);
|
localExecutableLabel.setTextInteractionFlags(selectable);
|
||||||
@@ -56,10 +56,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoteLinuxRunConfiguration * const runConfiguration;
|
RemoteLinuxRunConfiguration * const runConfiguration;
|
||||||
bool ignoreChange;
|
bool ignoreChange = false;
|
||||||
|
|
||||||
QLineEdit argsLineEdit;
|
|
||||||
QLineEdit workingDirLineEdit;
|
|
||||||
QLabel localExecutableLabel;
|
QLabel localExecutableLabel;
|
||||||
QLabel remoteExecutableLabel;
|
QLabel remoteExecutableLabel;
|
||||||
QCheckBox useAlternateCommandBox;
|
QCheckBox useAlternateCommandBox;
|
||||||
@@ -72,31 +70,16 @@ public:
|
|||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
RemoteLinuxRunConfigurationWidget::RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration,
|
RemoteLinuxRunConfigurationWidget::RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration)
|
||||||
QWidget *parent)
|
: d(new RemoteLinuxRunConfigurationWidgetPrivate(runConfiguration))
|
||||||
: QWidget(parent), d(new RemoteLinuxRunConfigurationWidgetPrivate(runConfiguration))
|
|
||||||
{
|
{
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
auto mainLayout = new QVBoxLayout(this);
|
||||||
mainLayout->setMargin(0);
|
mainLayout->setMargin(0);
|
||||||
addGenericWidgets(mainLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteLinuxRunConfigurationWidget::~RemoteLinuxRunConfigurationWidget()
|
auto detailsContainer = new Utils::DetailsWidget(this);
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxRunConfigurationWidget::addFormLayoutRow(QWidget *label, QWidget *field)
|
|
||||||
{
|
|
||||||
d->genericWidgetsLayout.addRow(label, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout)
|
|
||||||
{
|
|
||||||
Utils::DetailsWidget *detailsContainer = new Utils::DetailsWidget(this);
|
|
||||||
detailsContainer->setState(Utils::DetailsWidget::NoSummary);
|
detailsContainer->setState(Utils::DetailsWidget::NoSummary);
|
||||||
|
|
||||||
QWidget *details = new QWidget(this);
|
auto details = new QWidget(this);
|
||||||
details->setLayout(&d->genericWidgetsLayout);
|
details->setLayout(&d->genericWidgetsLayout);
|
||||||
detailsContainer->setWidget(details);
|
detailsContainer->setWidget(details);
|
||||||
|
|
||||||
@@ -107,8 +90,8 @@ void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayou
|
|||||||
d->localExecutableLabel.setText(d->runConfiguration->localExecutableFilePath());
|
d->localExecutableLabel.setText(d->runConfiguration->localExecutableFilePath());
|
||||||
d->genericWidgetsLayout.addRow(tr("Executable on host:"), &d->localExecutableLabel);
|
d->genericWidgetsLayout.addRow(tr("Executable on host:"), &d->localExecutableLabel);
|
||||||
d->genericWidgetsLayout.addRow(tr("Executable on device:"), &d->remoteExecutableLabel);
|
d->genericWidgetsLayout.addRow(tr("Executable on device:"), &d->remoteExecutableLabel);
|
||||||
QWidget * const altRemoteExeWidget = new QWidget;
|
auto altRemoteExeWidget = new QWidget;
|
||||||
QHBoxLayout * const altRemoteExeLayout = new QHBoxLayout(altRemoteExeWidget);
|
auto altRemoteExeLayout = new QHBoxLayout(altRemoteExeWidget);
|
||||||
altRemoteExeLayout->setContentsMargins(0, 0, 0, 0);
|
altRemoteExeLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
d->alternateCommand.setText(d->runConfiguration->alternateRemoteExecutable());
|
d->alternateCommand.setText(d->runConfiguration->alternateRemoteExecutable());
|
||||||
altRemoteExeLayout->addWidget(&d->alternateCommand);
|
altRemoteExeLayout->addWidget(&d->alternateCommand);
|
||||||
@@ -117,15 +100,11 @@ void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayou
|
|||||||
altRemoteExeLayout->addWidget(&d->useAlternateCommandBox);
|
altRemoteExeLayout->addWidget(&d->useAlternateCommandBox);
|
||||||
d->genericWidgetsLayout.addRow(tr("Alternate executable on device:"), altRemoteExeWidget);
|
d->genericWidgetsLayout.addRow(tr("Alternate executable on device:"), altRemoteExeWidget);
|
||||||
|
|
||||||
d->argsLineEdit.setText(d->runConfiguration->arguments());
|
d->runConfiguration->extraAspect<ArgumentsAspect>()
|
||||||
d->genericWidgetsLayout.addRow(tr("Arguments:"), &d->argsLineEdit);
|
->addToMainConfigurationWidget(this, &d->genericWidgetsLayout);
|
||||||
|
d->runConfiguration->extraAspect<WorkingDirectoryAspect>()
|
||||||
|
->addToMainConfigurationWidget(this, &d->genericWidgetsLayout);
|
||||||
|
|
||||||
d->workingDirLineEdit.setPlaceholderText(tr("<default>"));
|
|
||||||
d->workingDirLineEdit.setText(d->runConfiguration->workingDirectory());
|
|
||||||
d->genericWidgetsLayout.addRow(tr("Working directory:"), &d->workingDirLineEdit);
|
|
||||||
|
|
||||||
connect(&d->argsLineEdit, &QLineEdit::textEdited,
|
|
||||||
this, &RemoteLinuxRunConfigurationWidget::argumentsEdited);
|
|
||||||
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::targetInformationChanged,
|
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::targetInformationChanged,
|
||||||
this, &RemoteLinuxRunConfigurationWidget::updateTargetInformation);
|
this, &RemoteLinuxRunConfigurationWidget::updateTargetInformation);
|
||||||
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::deploySpecsChanged,
|
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::deploySpecsChanged,
|
||||||
@@ -134,15 +113,19 @@ void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayou
|
|||||||
this, &RemoteLinuxRunConfigurationWidget::handleUseAlternateCommandChanged);
|
this, &RemoteLinuxRunConfigurationWidget::handleUseAlternateCommandChanged);
|
||||||
connect(&d->alternateCommand, &QLineEdit::textEdited,
|
connect(&d->alternateCommand, &QLineEdit::textEdited,
|
||||||
this, &RemoteLinuxRunConfigurationWidget::handleAlternateCommandChanged);
|
this, &RemoteLinuxRunConfigurationWidget::handleAlternateCommandChanged);
|
||||||
connect(&d->workingDirLineEdit, &QLineEdit::textEdited,
|
|
||||||
this, &RemoteLinuxRunConfigurationWidget::handleWorkingDirectoryChanged);
|
|
||||||
handleDeploySpecsChanged();
|
handleDeploySpecsChanged();
|
||||||
handleUseAlternateCommandChanged();
|
handleUseAlternateCommandChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxRunConfigurationWidget::argumentsEdited(const QString &text)
|
RemoteLinuxRunConfigurationWidget::~RemoteLinuxRunConfigurationWidget()
|
||||||
{
|
{
|
||||||
d->runConfiguration->setArguments(text);
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunConfigurationWidget::addFormLayoutRow(QWidget *label, QWidget *field)
|
||||||
|
{
|
||||||
|
d->genericWidgetsLayout.addRow(label, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxRunConfigurationWidget::updateTargetInformation()
|
void RemoteLinuxRunConfigurationWidget::updateTargetInformation()
|
||||||
@@ -179,9 +162,4 @@ void RemoteLinuxRunConfigurationWidget::handleAlternateCommandChanged()
|
|||||||
d->runConfiguration->setAlternateRemoteExecutable(d->alternateCommand.text().trimmed());
|
d->runConfiguration->setAlternateRemoteExecutable(d->alternateCommand.text().trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxRunConfigurationWidget::handleWorkingDirectoryChanged()
|
|
||||||
{
|
|
||||||
d->runConfiguration->setWorkingDirectory(d->workingDirLineEdit.text().trimmed());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -43,21 +43,17 @@ class REMOTELINUX_EXPORT RemoteLinuxRunConfigurationWidget : public QWidget
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration,
|
explicit RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration);
|
||||||
QWidget *parent = 0);
|
|
||||||
~RemoteLinuxRunConfigurationWidget();
|
~RemoteLinuxRunConfigurationWidget();
|
||||||
|
|
||||||
void addFormLayoutRow(QWidget *label, QWidget *field);
|
void addFormLayoutRow(QWidget *label, QWidget *field);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void argumentsEdited(const QString &args);
|
|
||||||
void updateTargetInformation();
|
void updateTargetInformation();
|
||||||
void handleDeploySpecsChanged();
|
void handleDeploySpecsChanged();
|
||||||
void handleUseAlternateCommandChanged();
|
void handleUseAlternateCommandChanged();
|
||||||
void handleAlternateCommandChanged();
|
void handleAlternateCommandChanged();
|
||||||
void handleWorkingDirectoryChanged();
|
|
||||||
|
|
||||||
void addGenericWidgets(QVBoxLayout *mainLayout);
|
|
||||||
void setLabelText(QLabel &label, const QString ®ularText, const QString &errorText);
|
void setLabelText(QLabel &label, const QString ®ularText, const QString &errorText);
|
||||||
|
|
||||||
Internal::RemoteLinuxRunConfigurationWidgetPrivate * const d;
|
Internal::RemoteLinuxRunConfigurationWidgetPrivate * const d;
|
||||||
|
Reference in New Issue
Block a user