forked from qt-creator/qt-creator
ProjectExplorer: Use the fromMap(toMap()) pattern to clone devices
Change-Id: Ie6e73f5ef1019907dd311aac116d71f08b5a5202 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -90,11 +90,6 @@ Utils::OsType AndroidDevice::osType() const
|
|||||||
return Utils::OsTypeOtherUnix;
|
return Utils::OsTypeOtherUnix;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr AndroidDevice::clone() const
|
|
||||||
{
|
|
||||||
return IDevice::Ptr(new AndroidDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
|
QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
|
||||||
{
|
{
|
||||||
QUrl url;
|
QUrl url;
|
||||||
|
@@ -47,7 +47,6 @@ private:
|
|||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
||||||
Utils::OsType osType() const override;
|
Utils::OsType osType() const override;
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -130,11 +130,6 @@ QVariantMap BareMetalDevice::toMap() const
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
BareMetalDevice::IDevice::Ptr BareMetalDevice::clone() const
|
|
||||||
{
|
|
||||||
return Ptr(new BareMetalDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceProcessSignalOperation::Ptr BareMetalDevice::signalOperation() const
|
DeviceProcessSignalOperation::Ptr BareMetalDevice::signalOperation() const
|
||||||
{
|
{
|
||||||
return DeviceProcessSignalOperation::Ptr();
|
return DeviceProcessSignalOperation::Ptr();
|
||||||
@@ -160,13 +155,7 @@ DeviceProcess *BareMetalDevice::createProcess(QObject *parent) const
|
|||||||
return new GdbServerProviderProcess(sharedFromThis(), parent);
|
return new GdbServerProviderProcess(sharedFromThis(), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
BareMetalDevice::BareMetalDevice(const BareMetalDevice &other)
|
// Factory
|
||||||
: IDevice(other)
|
|
||||||
{
|
|
||||||
setGdbServerProviderId(other.gdbServerProviderId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// BareMetalDeviceFactory
|
|
||||||
|
|
||||||
BareMetalDeviceFactory::BareMetalDeviceFactory()
|
BareMetalDeviceFactory::BareMetalDeviceFactory()
|
||||||
: IDeviceFactory(Constants::BareMetalOsType)
|
: IDeviceFactory(Constants::BareMetalOsType)
|
||||||
|
@@ -48,7 +48,6 @@ public:
|
|||||||
QString displayType() const final;
|
QString displayType() const final;
|
||||||
ProjectExplorer::IDeviceWidget *createWidget() final;
|
ProjectExplorer::IDeviceWidget *createWidget() final;
|
||||||
Utils::OsType osType() const final;
|
Utils::OsType osType() const final;
|
||||||
ProjectExplorer::IDevice::Ptr clone() const final;
|
|
||||||
|
|
||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const final;
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const final;
|
||||||
|
|
||||||
@@ -65,10 +64,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
explicit BareMetalDevice() = default;
|
explicit BareMetalDevice() = default;
|
||||||
explicit BareMetalDevice(const BareMetalDevice &other);
|
|
||||||
|
|
||||||
void setChannelByServerProvider(GdbServerProvider *provider);
|
void setChannelByServerProvider(GdbServerProvider *provider);
|
||||||
BareMetalDevice &operator=(const BareMetalDevice &);
|
|
||||||
QString m_gdbServerProviderId;
|
QString m_gdbServerProviderId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -92,8 +92,6 @@ IosDevice::IosDevice()
|
|||||||
setFreePorts(ports);
|
setFreePorts(ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
IosDevice::IosDevice(const IosDevice &other) = default;
|
|
||||||
|
|
||||||
IosDevice::IosDevice(const QString &uid)
|
IosDevice::IosDevice(const QString &uid)
|
||||||
: m_lastPort(Constants::IOS_DEVICE_PORT_START)
|
: m_lastPort(Constants::IOS_DEVICE_PORT_START)
|
||||||
{
|
{
|
||||||
@@ -133,11 +131,6 @@ DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const
|
|||||||
return DeviceProcessSignalOperation::Ptr();
|
return DeviceProcessSignalOperation::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr IosDevice::clone() const
|
|
||||||
{
|
|
||||||
return IDevice::Ptr(new IosDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void IosDevice::fromMap(const QVariantMap &map)
|
void IosDevice::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
IDevice::fromMap(map);
|
IDevice::fromMap(map);
|
||||||
@@ -236,8 +229,8 @@ void IosDeviceManager::deviceConnected(const QString &uid, const QString &name)
|
|||||||
qCDebug(detectLog) << "updating ios device " << uid;
|
qCDebug(detectLog) << "updating ios device " << uid;
|
||||||
IosDevice *newDev = nullptr;
|
IosDevice *newDev = nullptr;
|
||||||
if (dev->type() == devType) {
|
if (dev->type() == devType) {
|
||||||
auto iosDev = static_cast<const IosDevice *>(dev.data());
|
newDev = new IosDevice();
|
||||||
newDev = new IosDevice(*iosDev);
|
newDev->fromMap(dev->toMap());
|
||||||
} else {
|
} else {
|
||||||
newDev = new IosDevice(uid);
|
newDev = new IosDevice(uid);
|
||||||
}
|
}
|
||||||
@@ -294,7 +287,8 @@ void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid,
|
|||||||
skipUpdate = true;
|
skipUpdate = true;
|
||||||
newDev = const_cast<IosDevice *>(iosDev);
|
newDev = const_cast<IosDevice *>(iosDev);
|
||||||
} else {
|
} else {
|
||||||
newDev = new IosDevice(*iosDev);
|
newDev = new IosDevice();
|
||||||
|
newDev->fromMap(iosDev->toMap());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newDev = new IosDevice(uid);
|
newDev = new IosDevice(uid);
|
||||||
|
@@ -54,7 +54,6 @@ public:
|
|||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
||||||
QString displayType() const override;
|
QString displayType() const override;
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
void fromMap(const QVariantMap &map) override;
|
void fromMap(const QVariantMap &map) override;
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
QString uniqueDeviceID() const;
|
QString uniqueDeviceID() const;
|
||||||
@@ -69,7 +68,6 @@ protected:
|
|||||||
friend class IosDeviceFactory;
|
friend class IosDeviceFactory;
|
||||||
friend class Ios::Internal::IosDeviceManager;
|
friend class Ios::Internal::IosDeviceManager;
|
||||||
IosDevice();
|
IosDevice();
|
||||||
IosDevice(const IosDevice &other);
|
|
||||||
IosDevice(const QString &uid);
|
IosDevice(const QString &uid);
|
||||||
|
|
||||||
Dict m_extraInfo;
|
Dict m_extraInfo;
|
||||||
|
@@ -64,14 +64,6 @@ IosSimulator::IosSimulator()
|
|||||||
setDeviceState(DeviceReadyToUse);
|
setDeviceState(DeviceReadyToUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
IosSimulator::IosSimulator(const IosSimulator &other)
|
|
||||||
: IDevice(other), m_lastPort(other.m_lastPort)
|
|
||||||
{
|
|
||||||
setDisplayName(QCoreApplication::translate("Ios::Internal::IosSimulator", "iOS Simulator"));
|
|
||||||
setDeviceState(DeviceReadyToUse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IDevice::DeviceInfo IosSimulator::deviceInformation() const
|
IDevice::DeviceInfo IosSimulator::deviceInformation() const
|
||||||
{
|
{
|
||||||
return IDevice::DeviceInfo();
|
return IDevice::DeviceInfo();
|
||||||
@@ -92,11 +84,6 @@ DeviceProcessSignalOperation::Ptr IosSimulator::signalOperation() const
|
|||||||
return DeviceProcessSignalOperation::Ptr();
|
return DeviceProcessSignalOperation::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr IosSimulator::clone() const
|
|
||||||
{
|
|
||||||
return IDevice::Ptr(new IosSimulator(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::Port IosSimulator::nextPort() const
|
Utils::Port IosSimulator::nextPort() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 100; ++i) {
|
for (int i = 0; i < 100; ++i) {
|
||||||
|
@@ -76,13 +76,12 @@ public:
|
|||||||
bool canAutoDetectPorts() const override;
|
bool canAutoDetectPorts() const override;
|
||||||
Utils::OsType osType() const override;
|
Utils::OsType osType() const override;
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
protected:
|
protected:
|
||||||
friend class IosSimulatorFactory;
|
friend class IosSimulatorFactory;
|
||||||
friend class IosConfigurations;
|
friend class IosConfigurations;
|
||||||
IosSimulator();
|
IosSimulator();
|
||||||
IosSimulator(Core::Id id);
|
IosSimulator(Core::Id id);
|
||||||
IosSimulator(const IosSimulator &other);
|
|
||||||
private:
|
private:
|
||||||
mutable quint16 m_lastPort;
|
mutable quint16 m_lastPort;
|
||||||
};
|
};
|
||||||
|
@@ -60,8 +60,6 @@ DesktopDevice::DesktopDevice()
|
|||||||
setFreePorts(Utils::PortList::fromString(portRange));
|
setFreePorts(Utils::PortList::fromString(portRange));
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopDevice::DesktopDevice(const DesktopDevice &other) = default;
|
|
||||||
|
|
||||||
IDevice::DeviceInfo DesktopDevice::deviceInformation() const
|
IDevice::DeviceInfo DesktopDevice::deviceInformation() const
|
||||||
{
|
{
|
||||||
return DeviceInfo();
|
return DeviceInfo();
|
||||||
@@ -177,9 +175,4 @@ Utils::OsType DesktopDevice::osType() const
|
|||||||
return Utils::HostOsInfo::hostOs();
|
return Utils::HostOsInfo::hostOs();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr DesktopDevice::clone() const
|
|
||||||
{
|
|
||||||
return Ptr(new DesktopDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -53,11 +53,8 @@ public:
|
|||||||
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
||||||
Utils::OsType osType() const override;
|
Utils::OsType osType() const override;
|
||||||
|
|
||||||
IDevice::Ptr clone() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DesktopDevice();
|
DesktopDevice();
|
||||||
DesktopDevice(const DesktopDevice &other);
|
|
||||||
|
|
||||||
friend class ProjectExplorerPlugin;
|
friend class ProjectExplorerPlugin;
|
||||||
friend class Internal::DesktopDeviceFactory;
|
friend class Internal::DesktopDeviceFactory;
|
||||||
|
@@ -414,10 +414,8 @@ public:
|
|||||||
|
|
||||||
static Core::Id testTypeId() { return "TestType"; }
|
static Core::Id testTypeId() { return "TestType"; }
|
||||||
private:
|
private:
|
||||||
TestDevice(const TestDevice &other) = default;
|
|
||||||
QString displayType() const override { return QLatin1String("blubb"); }
|
QString displayType() const override { return QLatin1String("blubb"); }
|
||||||
IDeviceWidget *createWidget() override { return nullptr; }
|
IDeviceWidget *createWidget() override { return nullptr; }
|
||||||
Ptr clone() const override { return Ptr(new TestDevice(*this)); }
|
|
||||||
DeviceProcessSignalOperation::Ptr signalOperation() const override
|
DeviceProcessSignalOperation::Ptr signalOperation() const override
|
||||||
{
|
{
|
||||||
return DeviceProcessSignalOperation::Ptr();
|
return DeviceProcessSignalOperation::Ptr();
|
||||||
@@ -425,8 +423,19 @@ private:
|
|||||||
Utils::OsType osType() const override { return Utils::HostOsInfo::hostOs(); }
|
Utils::OsType osType() const override { return Utils::HostOsInfo::hostOs(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TestDeviceFactory : public IDeviceFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestDeviceFactory() : IDeviceFactory(TestDevice::testTypeId())
|
||||||
|
{
|
||||||
|
setConstructionFunction([] { return IDevice::Ptr(new TestDevice); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void ProjectExplorerPlugin::testDeviceManager()
|
void ProjectExplorerPlugin::testDeviceManager()
|
||||||
{
|
{
|
||||||
|
TestDeviceFactory factory;
|
||||||
|
|
||||||
TestDevice::Ptr dev = IDevice::Ptr(new TestDevice);
|
TestDevice::Ptr dev = IDevice::Ptr(new TestDevice);
|
||||||
dev->setDisplayName(QLatin1String("blubbdiblubbfurz!"));
|
dev->setDisplayName(QLatin1String("blubbdiblubbfurz!"));
|
||||||
QVERIFY(dev->isAutoDetected());
|
QVERIFY(dev->isAutoDetected());
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "devicemanager.h"
|
#include "devicemanager.h"
|
||||||
#include "deviceprocesslist.h"
|
#include "deviceprocesslist.h"
|
||||||
|
#include "idevicefactory.h"
|
||||||
|
|
||||||
#include "../kit.h"
|
#include "../kit.h"
|
||||||
#include "../kitinformation.h"
|
#include "../kitinformation.h"
|
||||||
@@ -168,13 +169,6 @@ void IDevice::setupId(Origin origin, Core::Id id)
|
|||||||
d->id = id.isValid() ? id : newId();
|
d->id = id.isValid() ? id : newId();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::IDevice(const IDevice &other)
|
|
||||||
: QEnableSharedFromThis<IDevice>(other)
|
|
||||||
, d(std::make_unique<Internal::IDevicePrivate>())
|
|
||||||
{
|
|
||||||
*d = *other.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDevice::~IDevice() = default;
|
IDevice::~IDevice() = default;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -395,6 +389,16 @@ QVariantMap IDevice::toMap() const
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDevice::Ptr IDevice::clone() const
|
||||||
|
{
|
||||||
|
IDeviceFactory *factory = IDeviceFactory::find(d->type);
|
||||||
|
QTC_ASSERT(factory, return {});
|
||||||
|
IDevice::Ptr device = factory->construct();
|
||||||
|
QTC_ASSERT(device, return {});
|
||||||
|
device->fromMap(toMap());
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
QString IDevice::deviceStateToString() const
|
QString IDevice::deviceStateToString() const
|
||||||
{
|
{
|
||||||
const char context[] = "ProjectExplorer::IDevice";
|
const char context[] = "ProjectExplorer::IDevice";
|
||||||
|
@@ -127,9 +127,10 @@ public:
|
|||||||
enum Origin { ManuallyAdded, AutoDetected };
|
enum Origin { ManuallyAdded, AutoDetected };
|
||||||
enum MachineType { Hardware, Emulator };
|
enum MachineType { Hardware, Emulator };
|
||||||
|
|
||||||
IDevice &operator=(const IDevice &) = delete;
|
|
||||||
virtual ~IDevice();
|
virtual ~IDevice();
|
||||||
|
|
||||||
|
Ptr clone() const;
|
||||||
|
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
void setDisplayName(const QString &name);
|
void setDisplayName(const QString &name);
|
||||||
|
|
||||||
@@ -187,7 +188,6 @@ public:
|
|||||||
|
|
||||||
virtual void fromMap(const QVariantMap &map);
|
virtual void fromMap(const QVariantMap &map);
|
||||||
virtual QVariantMap toMap() const;
|
virtual QVariantMap toMap() const;
|
||||||
virtual Ptr clone() const = 0;
|
|
||||||
|
|
||||||
static Core::Id typeFromMap(const QVariantMap &map);
|
static Core::Id typeFromMap(const QVariantMap &map);
|
||||||
static Core::Id idFromMap(const QVariantMap &map);
|
static Core::Id idFromMap(const QVariantMap &map);
|
||||||
@@ -220,9 +220,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
IDevice();
|
IDevice();
|
||||||
IDevice(const IDevice &other);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
IDevice(const IDevice &) = delete;
|
||||||
|
IDevice &operator=(const IDevice &) = delete;
|
||||||
|
|
||||||
int version() const;
|
int version() const;
|
||||||
|
|
||||||
const std::unique_ptr<Internal::IDevicePrivate> d;
|
const std::unique_ptr<Internal::IDevicePrivate> d;
|
||||||
|
@@ -151,11 +151,6 @@ QVariantMap QnxDevice::toMap() const
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr QnxDevice::clone() const
|
|
||||||
{
|
|
||||||
return Ptr(new QnxDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
PortsGatheringMethod::Ptr QnxDevice::portsGatheringMethod() const
|
PortsGatheringMethod::Ptr QnxDevice::portsGatheringMethod() const
|
||||||
{
|
{
|
||||||
return PortsGatheringMethod::Ptr(new QnxPortsGatheringMethod);
|
return PortsGatheringMethod::Ptr(new QnxPortsGatheringMethod);
|
||||||
|
@@ -41,7 +41,6 @@ public:
|
|||||||
using ConstPtr = QSharedPointer<const QnxDevice>;
|
using ConstPtr = QSharedPointer<const QnxDevice>;
|
||||||
|
|
||||||
static Ptr create() { return Ptr(new QnxDevice); }
|
static Ptr create() { return Ptr(new QnxDevice); }
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
|
|
||||||
ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const override;
|
ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const override;
|
||||||
ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override;
|
ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override;
|
||||||
|
@@ -219,11 +219,6 @@ LinuxDevice::LinuxDevice()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr LinuxDevice::clone() const
|
|
||||||
{
|
|
||||||
return Ptr(new LinuxDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceProcess *LinuxDevice::createProcess(QObject *parent) const
|
DeviceProcess *LinuxDevice::createProcess(QObject *parent) const
|
||||||
{
|
{
|
||||||
return new LinuxDeviceProcess(sharedFromThis(), parent);
|
return new LinuxDeviceProcess(sharedFromThis(), parent);
|
||||||
|
@@ -47,7 +47,6 @@ public:
|
|||||||
QString displayType() const override;
|
QString displayType() const override;
|
||||||
ProjectExplorer::IDeviceWidget *createWidget() override;
|
ProjectExplorer::IDeviceWidget *createWidget() override;
|
||||||
Utils::OsType osType() const override;
|
Utils::OsType osType() const override;
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
|
|
||||||
bool canCreateProcess() const override { return true; }
|
bool canCreateProcess() const override { return true; }
|
||||||
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
|
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
|
||||||
|
@@ -106,11 +106,6 @@ Utils::OsType WinRtDevice::osType() const
|
|||||||
return Utils::OsTypeWindows;
|
return Utils::OsTypeWindows;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr WinRtDevice::clone() const
|
|
||||||
{
|
|
||||||
return IDevice::Ptr(new WinRtDevice(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString WinRtDevice::displayNameForType(Core::Id type)
|
QString WinRtDevice::displayNameForType(Core::Id type)
|
||||||
{
|
{
|
||||||
if (type == Constants::WINRT_DEVICE_TYPE_LOCAL)
|
if (type == Constants::WINRT_DEVICE_TYPE_LOCAL)
|
||||||
|
@@ -47,7 +47,6 @@ public:
|
|||||||
void fromMap(const QVariantMap &map) override;
|
void fromMap(const QVariantMap &map) override;
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
Utils::OsType osType() const override;
|
Utils::OsType osType() const override;
|
||||||
ProjectExplorer::IDevice::Ptr clone() const override;
|
|
||||||
|
|
||||||
static QString displayNameForType(Core::Id type);
|
static QString displayNameForType(Core::Id type);
|
||||||
int deviceId() const { return m_deviceId; }
|
int deviceId() const { return m_deviceId; }
|
||||||
|
Reference in New Issue
Block a user