mirror of
https://github.com/altlinux/admc.git
synced 2025-03-22 02:50:30 +03:00
setup attribute display strings and translation
setup gpgui translation add XmlAttribute::hidden() remove XmlAttribute::property()
This commit is contained in:
parent
451ae5394e
commit
2296b8104e
src/gpgui
translations
@ -38,6 +38,8 @@ add_executable(gpgui
|
||||
gui/xml/xml_attribute.cpp
|
||||
gui/xml/xml_edit.cpp
|
||||
gui/xml/xml_string_edit.cpp
|
||||
|
||||
${PROJECT_SOURCE_DIR}/translations/translations.qrc
|
||||
)
|
||||
|
||||
if(SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
|
@ -19,6 +19,9 @@
|
||||
|
||||
#include "xml_attribute.h"
|
||||
|
||||
#include <QSet>
|
||||
#include <QHash>
|
||||
|
||||
XmlAttribute::XmlAttribute(const QDomNode &node) {
|
||||
// NOTE: there are two "attributes", attributes of the object and xml attributes
|
||||
const QDomNamedNodeMap attributes = node.attributes();
|
||||
@ -31,37 +34,6 @@ XmlAttribute::XmlAttribute(const QDomNode &node) {
|
||||
|
||||
const QDomNode attribute_use = attributes.namedItem("use");
|
||||
m_required = (attribute_use.nodeValue() == "required");
|
||||
|
||||
// Recurse through all ancestors of node and check if any of them have an attribute "name" set to "Properties"
|
||||
// TODO: might actually not be useful? Delete if not
|
||||
auto get_is_property =
|
||||
[node]() -> bool {
|
||||
QDomNode current = node.parentNode();
|
||||
|
||||
while (!current.isNull()) {
|
||||
const QDomNamedNodeMap current_attributes = current.attributes();
|
||||
const QDomNode name_node = current_attributes.namedItem("name");
|
||||
if (!name_node.isNull()) {
|
||||
const QString this_name = name_node.nodeValue();
|
||||
|
||||
if (this_name == "Properties") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const QDomNode new_current = current.parentNode();
|
||||
|
||||
if (new_current == current) {
|
||||
// Reached top node
|
||||
return false;
|
||||
} else {
|
||||
current = new_current;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
m_is_property = get_is_property();
|
||||
}
|
||||
|
||||
void XmlAttribute::print() const {
|
||||
@ -69,7 +41,6 @@ void XmlAttribute::print() const {
|
||||
printf(" name=%s\n", qPrintable(m_name));
|
||||
printf(" type=%s\n", qPrintable(attribute_type_to_string(m_type)));
|
||||
printf(" required=%d\n", m_required);
|
||||
printf(" properties=%d\n", m_is_property);
|
||||
}
|
||||
|
||||
|
||||
@ -85,8 +56,17 @@ bool XmlAttribute::required() const {
|
||||
return m_required;
|
||||
}
|
||||
|
||||
bool XmlAttribute::is_property() const {
|
||||
return m_is_property;
|
||||
bool XmlAttribute::hidden() const {
|
||||
// TODO: there's gotta be some external resource that says which attributes are hidden
|
||||
static const QSet<QString> hidden_attributes = {
|
||||
"clsid",
|
||||
"disabled",
|
||||
"changed",
|
||||
"uid",
|
||||
};
|
||||
const bool is_hidden = hidden_attributes.contains(name());
|
||||
|
||||
return is_hidden;
|
||||
}
|
||||
|
||||
const QHash<XmlAttributeType, QString> attribute_type_to_string_map = {
|
||||
@ -123,3 +103,34 @@ XmlAttributeType string_to_attribute_type(const QString string_raw) {
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
#define DISPLAY_STRING_MACRO(attribute) {attribute, QObject::tr(attribute)},
|
||||
#define DISPLAY_STRING_MACRO_2(attribute) attribute "_test"
|
||||
|
||||
QString XmlAttribute::display_string() const {
|
||||
static const QHash<QString, QString> display_strings = {
|
||||
{"pidl", QObject::tr("pidl DISPLAY_STRING")},
|
||||
{"name", QObject::tr("name DISPLAY_STRING")},
|
||||
{"image", QObject::tr("image DISPLAY_STRING")},
|
||||
{"targetType", QObject::tr("targetType DISPLAY_STRING")},
|
||||
{"action", QObject::tr("action DISPLAY_STRING")},
|
||||
{"comment", QObject::tr("comment DISPLAY_STRING")},
|
||||
{"shortcutKey", QObject::tr("shortcutKey DISPLAY_STRING")},
|
||||
{"startIn", QObject::tr("startIn DISPLAY_STRING")},
|
||||
{"arguments", QObject::tr("arguments DISPLAY_STRING")},
|
||||
{"iconIndex", QObject::tr("iconIndex DISPLAY_STRING")},
|
||||
{"targetPath", QObject::tr("targetPath DISPLAY_STRING")},
|
||||
{"iconPath", QObject::tr("iconPath DISPLAY_STRING")},
|
||||
{"window", QObject::tr("window DISPLAY_STRING")},
|
||||
{"shortcutPath", QObject::tr("shortcutPath DISPLAY_STRING")},
|
||||
{"desc", QObject::tr("desc DISPLAY_STRING")},
|
||||
{"bypassErrors", QObject::tr("bypassErrors DISPLAY_STRING")},
|
||||
{"userContext", QObject::tr("userContext DISPLAY_STRING")},
|
||||
{"removePolicy", QObject::tr("removePolicy DISPLAY_STRING")},
|
||||
};
|
||||
static const QString default_value = QObject::tr("UNKNOWN XML ATTRIBUTE NAME");
|
||||
|
||||
const QString display_string = display_strings.value(name(), default_value);
|
||||
|
||||
return display_string;
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ public:
|
||||
QString name() const;
|
||||
XmlAttributeType type() const;
|
||||
bool required() const;
|
||||
bool is_property() const;
|
||||
bool hidden() const;
|
||||
QString display_string() const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
XmlAttributeType m_type;
|
||||
bool m_required;
|
||||
bool m_is_property;
|
||||
};
|
||||
|
||||
QString attribute_type_to_string(const XmlAttributeType type);
|
||||
|
@ -102,6 +102,10 @@ XmlEditor::XmlEditor(const QString &path_arg)
|
||||
auto edits_layout = new QGridLayout();
|
||||
|
||||
for (auto attribute : schema_attributes) {
|
||||
if (attribute.hidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto edit = new XmlStringEdit(attribute);
|
||||
edit->add_to_layout(edits_layout);
|
||||
edit->load(doc);
|
||||
|
@ -48,7 +48,7 @@ void XmlStringEdit::load(const QDomDocument &doc) {
|
||||
}
|
||||
|
||||
void XmlStringEdit::add_to_layout(QGridLayout *layout) {
|
||||
const QString label_text = attribute.name() + ":";
|
||||
const QString label_text = attribute.display_string() + ":";
|
||||
const auto label = new QLabel(label_text);
|
||||
|
||||
// TODO: connect_changed_marker(this, label);
|
||||
@ -69,16 +69,16 @@ bool XmlStringEdit::changed() const {
|
||||
}
|
||||
|
||||
bool XmlStringEdit::apply(QDomDocument *doc) {
|
||||
printf("apply %s\n", qPrintable(attribute.name()));
|
||||
if (!changed()) {
|
||||
printf(" not applying\n");
|
||||
return true;
|
||||
}
|
||||
printf("!!!!!!!applying\n");
|
||||
|
||||
QDomNode attribute_node = find_attribute_node(*doc, attribute.name());
|
||||
const QString new_value = edit->text();
|
||||
attribute_node.setNodeValue(new_value);
|
||||
|
||||
printf("apply %s: [%s]=>[%s]\n", qPrintable(attribute.name()), qPrintable(original_value), qPrintable(new_value));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ int main(int argc, char **argv) {
|
||||
app.setOrganizationName(GPGUI_ORGANIZATION);
|
||||
app.setOrganizationDomain(GPGUI_ORGANIZATION_DOMAIN);
|
||||
|
||||
QTranslator translator;
|
||||
translator.load(QLocale(), QString(), QString(), ":/translations");
|
||||
app.installTranslator(&translator);
|
||||
|
||||
QCommandLineParser cli_parser;
|
||||
cli_parser.setApplicationDescription(QCoreApplication::applicationName());
|
||||
cli_parser.addHelpOption();
|
||||
|
@ -546,37 +546,41 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="87"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="88"/>
|
||||
<source>File</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="89"/>
|
||||
<source>File untranslated</source>
|
||||
<translation type="obsolete">File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="90"/>
|
||||
<source>Open</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="94"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="95"/>
|
||||
<source>Exit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="113"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="116"/>
|
||||
<source>About GPGUI</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="113"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="116"/>
|
||||
<source>GPGUI about</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="177"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="180"/>
|
||||
<source>Loaded PReg file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="218"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="221"/>
|
||||
<source>Open Directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -967,6 +971,101 @@
|
||||
<source>Attribute "%1" cannot be empty!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="112"/>
|
||||
<source>pidl DISPLAY_STRING</source>
|
||||
<translation>PIDL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="113"/>
|
||||
<source>name DISPLAY_STRING</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="114"/>
|
||||
<source>image DISPLAY_STRING</source>
|
||||
<translation>Image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="115"/>
|
||||
<source>targetType DISPLAY_STRING</source>
|
||||
<translation>Target type</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="116"/>
|
||||
<source>action DISPLAY_STRING</source>
|
||||
<translation>Action</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="117"/>
|
||||
<source>comment DISPLAY_STRING</source>
|
||||
<translation>Comment</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="118"/>
|
||||
<source>shortcutKey DISPLAY_STRING</source>
|
||||
<translation>Shortcut key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="119"/>
|
||||
<source>startIn DISPLAY_STRING</source>
|
||||
<translation>Start in</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="120"/>
|
||||
<source>arguments DISPLAY_STRING</source>
|
||||
<translation>Arguments</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="121"/>
|
||||
<source>iconIndex DISPLAY_STRING</source>
|
||||
<translation>Icon index</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="122"/>
|
||||
<source>targetPath DISPLAY_STRING</source>
|
||||
<translation>Target path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="123"/>
|
||||
<source>iconPath DISPLAY_STRING</source>
|
||||
<translation>Icon path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="124"/>
|
||||
<source>window DISPLAY_STRING</source>
|
||||
<translation>Window</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="125"/>
|
||||
<source>shortcutPath DISPLAY_STRING</source>
|
||||
<translation>Shortcut path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="126"/>
|
||||
<source>desc DISPLAY_STRING</source>
|
||||
<translation>Description</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="127"/>
|
||||
<source>bypassErrors DISPLAY_STRING</source>
|
||||
<translation>Bypass errors</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="128"/>
|
||||
<source>userContext DISPLAY_STRING</source>
|
||||
<translation>Apply in security context of user</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="129"/>
|
||||
<source>removePolicy DISPLAY_STRING</source>
|
||||
<translation>Remove policy when it stops being applied</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="131"/>
|
||||
<source>UNKNOWN XML ATTRIBUTE NAME</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RenameDialog</name>
|
||||
@ -1063,7 +1162,7 @@
|
||||
<context>
|
||||
<name>XmlEditor</name>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml_editor.cpp" line="34"/>
|
||||
<location filename="../src/gpgui/gui/xml/xml_editor.cpp" line="78"/>
|
||||
<source>Editing xml file:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -566,37 +566,37 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="87"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="88"/>
|
||||
<source>File</source>
|
||||
<translation type="unfinished">Файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="89"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="90"/>
|
||||
<source>Open</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="94"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="95"/>
|
||||
<source>Exit</source>
|
||||
<translation type="unfinished">Выход</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="113"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="116"/>
|
||||
<source>About GPGUI</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="113"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="116"/>
|
||||
<source>GPGUI about</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="177"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="180"/>
|
||||
<source>Loaded PReg file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="218"/>
|
||||
<location filename="../src/gpgui/gui/MainWindow.cpp" line="221"/>
|
||||
<source>Open Directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1058,6 +1058,101 @@
|
||||
<source>Attribute "%1" cannot be empty!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="112"/>
|
||||
<source>pidl DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="113"/>
|
||||
<source>name DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="114"/>
|
||||
<source>image DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="115"/>
|
||||
<source>targetType DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="116"/>
|
||||
<source>action DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="117"/>
|
||||
<source>comment DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="118"/>
|
||||
<source>shortcutKey DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="119"/>
|
||||
<source>startIn DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="120"/>
|
||||
<source>arguments DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="121"/>
|
||||
<source>iconIndex DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="122"/>
|
||||
<source>targetPath DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="123"/>
|
||||
<source>iconPath DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="124"/>
|
||||
<source>window DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="125"/>
|
||||
<source>shortcutPath DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="126"/>
|
||||
<source>desc DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="127"/>
|
||||
<source>bypassErrors DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="128"/>
|
||||
<source>userContext DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="129"/>
|
||||
<source>removePolicy DISPLAY_STRING</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml/xml_attribute.cpp" line="131"/>
|
||||
<source>UNKNOWN XML ATTRIBUTE NAME</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RenameDialog</name>
|
||||
@ -1197,7 +1292,7 @@
|
||||
<context>
|
||||
<name>XmlEditor</name>
|
||||
<message>
|
||||
<location filename="../src/gpgui/gui/xml_editor.cpp" line="34"/>
|
||||
<location filename="../src/gpgui/gui/xml/xml_editor.cpp" line="78"/>
|
||||
<source>Editing xml file:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
Loading…
x
Reference in New Issue
Block a user