mirror of https://github.com/procxx/kepka.git
Add [first|middle|last]_name_native support.
This commit is contained in:
parent
b935d54fe7
commit
6558a32794
|
@ -151,6 +151,13 @@ void CollectToRequestedRow(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyDataChanges(ValueData &data, ValueMap &&changes) {
|
||||||
|
data.parsedInEdit = data.parsed;
|
||||||
|
for (auto &[key, value] : changes.fields) {
|
||||||
|
data.parsedInEdit.fields[key] = std::move(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RequestedRow CollectRequestedRow(const MTPSecureRequiredType &data) {
|
RequestedRow CollectRequestedRow(const MTPSecureRequiredType &data) {
|
||||||
auto result = RequestedRow();
|
auto result = RequestedRow();
|
||||||
CollectToRequestedRow(result, data);
|
CollectToRequestedRow(result, data);
|
||||||
|
@ -220,6 +227,39 @@ QString ValidateUrl(const QString &url) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
bool ValueChanged(not_null<const Value*> value, const ValueMap &data) {
|
||||||
|
const auto FileChanged = [](const EditFile &file) {
|
||||||
|
if (file.uploadData) {
|
||||||
|
return !file.deleted;
|
||||||
|
}
|
||||||
|
return file.deleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto filesCount = 0;
|
||||||
|
for (const auto &scan : value->scansInEdit) {
|
||||||
|
if (FileChanged(scan)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &[type, scan] : value->specialScansInEdit) {
|
||||||
|
if (FileChanged(scan)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto &existing = value->data.parsed.fields;
|
||||||
|
for (const auto &[key, value] : data.fields) {
|
||||||
|
const auto i = existing.find(key);
|
||||||
|
if (i != existing.end()) {
|
||||||
|
if (i->second.text != value.text) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (!value.text.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
FormRequest::FormRequest(
|
FormRequest::FormRequest(
|
||||||
UserId botId,
|
UserId botId,
|
||||||
const QString &scope,
|
const QString &scope,
|
||||||
|
@ -1576,42 +1616,6 @@ bool FormController::isEncryptedValue(Value::Type type) const {
|
||||||
return (type != Value::Type::Phone && type != Value::Type::Email);
|
return (type != Value::Type::Phone && type != Value::Type::Email);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FormController::editFileChanged(const EditFile &file) const {
|
|
||||||
if (file.uploadData) {
|
|
||||||
return !file.deleted;
|
|
||||||
}
|
|
||||||
return file.deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormController::editValueChanged(
|
|
||||||
not_null<const Value*> value,
|
|
||||||
const ValueMap &data) const {
|
|
||||||
auto filesCount = 0;
|
|
||||||
for (const auto &scan : value->scansInEdit) {
|
|
||||||
if (editFileChanged(scan)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &[type, scan] : value->specialScansInEdit) {
|
|
||||||
if (editFileChanged(scan)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto existing = value->data.parsed.fields;
|
|
||||||
for (const auto &[key, value] : data.fields) {
|
|
||||||
const auto i = existing.find(key);
|
|
||||||
if (i != existing.end()) {
|
|
||||||
if (i->second.text != value.text) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
existing.erase(i);
|
|
||||||
} else if (!value.text.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !existing.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormController::saveValueEdit(
|
void FormController::saveValueEdit(
|
||||||
not_null<const Value*> value,
|
not_null<const Value*> value,
|
||||||
ValueMap &&data) {
|
ValueMap &&data) {
|
||||||
|
@ -1623,7 +1627,7 @@ void FormController::saveValueEdit(
|
||||||
// and we don't reset value->error/[scan|translation]MissingError.
|
// and we don't reset value->error/[scan|translation]MissingError.
|
||||||
// Otherwise we reset them after save by re-parsing the value.
|
// Otherwise we reset them after save by re-parsing the value.
|
||||||
const auto nonconst = findValue(value);
|
const auto nonconst = findValue(value);
|
||||||
if (!editValueChanged(nonconst, data)) {
|
if (!ValueChanged(nonconst, data)) {
|
||||||
nonconst->saveRequestId = -1;
|
nonconst->saveRequestId = -1;
|
||||||
crl::on_main(this, [=] {
|
crl::on_main(this, [=] {
|
||||||
base::take(nonconst->scansInEdit);
|
base::take(nonconst->scansInEdit);
|
||||||
|
@ -1636,7 +1640,7 @@ void FormController::saveValueEdit(
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nonconst->data.parsedInEdit = std::move(data);
|
ApplyDataChanges(nonconst->data, std::move(data));
|
||||||
|
|
||||||
if (isEncryptedValue(nonconst->type)) {
|
if (isEncryptedValue(nonconst->type)) {
|
||||||
saveEncryptedValue(nonconst);
|
saveEncryptedValue(nonconst);
|
||||||
|
|
|
@ -201,6 +201,8 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool ValueChanged(not_null<const Value*> value, const ValueMap &data);
|
||||||
|
|
||||||
struct RequestedValue {
|
struct RequestedValue {
|
||||||
explicit RequestedValue(Value::Type type);
|
explicit RequestedValue(Value::Type type);
|
||||||
|
|
||||||
|
@ -327,9 +329,6 @@ public:
|
||||||
void startValueEdit(not_null<const Value*> value);
|
void startValueEdit(not_null<const Value*> value);
|
||||||
void cancelValueEdit(not_null<const Value*> value);
|
void cancelValueEdit(not_null<const Value*> value);
|
||||||
void cancelValueVerification(not_null<const Value*> value);
|
void cancelValueVerification(not_null<const Value*> value);
|
||||||
bool editValueChanged(
|
|
||||||
not_null<const Value*> value,
|
|
||||||
const ValueMap &data) const;
|
|
||||||
void saveValueEdit(not_null<const Value*> value, ValueMap &&data);
|
void saveValueEdit(not_null<const Value*> value, ValueMap &&data);
|
||||||
void deleteValueEdit(not_null<const Value*> value);
|
void deleteValueEdit(not_null<const Value*> value);
|
||||||
bool savingValue(not_null<const Value*> value) const;
|
bool savingValue(not_null<const Value*> value) const;
|
||||||
|
@ -454,7 +453,6 @@ private:
|
||||||
void valueEditFailed(not_null<Value*> value);
|
void valueEditFailed(not_null<Value*> value);
|
||||||
void clearValueEdit(not_null<Value*> value);
|
void clearValueEdit(not_null<Value*> value);
|
||||||
void clearValueVerification(not_null<Value*> value);
|
void clearValueVerification(not_null<Value*> value);
|
||||||
bool editFileChanged(const EditFile &file) const;
|
|
||||||
|
|
||||||
bool isEncryptedValue(Value::Type type) const;
|
bool isEncryptedValue(Value::Type type) const;
|
||||||
void saveEncryptedValue(not_null<Value*> value);
|
void saveEncryptedValue(not_null<Value*> value);
|
||||||
|
|
|
@ -278,7 +278,10 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}();
|
}();
|
||||||
if (document && scope.documents.size() > 1) {
|
if ((document && scope.documents.size() > 1)
|
||||||
|
|| (!scope.details
|
||||||
|
&& (ScopeTypeForValueType(document->type)
|
||||||
|
== Scope::Type::Address))) {
|
||||||
pushListValue("_type", [&] {
|
pushListValue("_type", [&] {
|
||||||
using Type = Value::Type;
|
using Type = Value::Type;
|
||||||
switch (document->type) {
|
switch (document->type) {
|
||||||
|
@ -307,7 +310,10 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
|
||||||
if (!scope.documents.empty() && !document) {
|
if (!scope.documents.empty() && !document) {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
const auto scheme = GetDocumentScheme(scope.type);
|
const auto scheme = GetDocumentScheme(
|
||||||
|
scope.type,
|
||||||
|
document ? base::make_optional(document->type) : base::none,
|
||||||
|
scope.details ? scope.details->nativeNames : false);
|
||||||
for (const auto &row : scheme.rows) {
|
for (const auto &row : scheme.rows) {
|
||||||
const auto format = row.format;
|
const auto format = row.format;
|
||||||
if (row.valueClass == EditDocumentScheme::ValueClass::Fields) {
|
if (row.valueClass == EditDocumentScheme::ValueClass::Fields) {
|
||||||
|
@ -357,9 +363,10 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeRow ComputeScopeRow(const Scope &scope) {
|
ScopeRow ComputeScopeRow(const Scope &scope) {
|
||||||
const auto addReadyError = [&](ScopeRow &&row) {
|
const auto addReadyError = [&](
|
||||||
const auto ready = ComputeScopeRowReadyString(scope);
|
ScopeRow &&row,
|
||||||
row.ready = ready;
|
QString titleFallback = QString()) {
|
||||||
|
row.ready = ComputeScopeRowReadyString(scope);
|
||||||
auto errors = QStringList();
|
auto errors = QStringList();
|
||||||
const auto addValueErrors = [&](not_null<const Value*> value) {
|
const auto addValueErrors = [&](not_null<const Value*> value) {
|
||||||
if (!value->error.isEmpty()) {
|
if (!value->error.isEmpty()) {
|
||||||
|
@ -408,7 +415,10 @@ ScopeRow ComputeScopeRow(const Scope &scope) {
|
||||||
}
|
}
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
row.error = errors[0];// errors.join('\n');
|
row.error = errors[0];// errors.join('\n');
|
||||||
|
} else if (row.title == row.ready && !titleFallback.isEmpty()) {
|
||||||
|
row.title = titleFallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #TODO passport half-full value
|
// #TODO passport half-full value
|
||||||
//if (row.error.isEmpty()
|
//if (row.error.isEmpty()
|
||||||
// && row.ready.isEmpty()
|
// && row.ready.isEmpty()
|
||||||
|
@ -473,27 +483,27 @@ ScopeRow ComputeScopeRow(const Scope &scope) {
|
||||||
return addReadyError({
|
return addReadyError({
|
||||||
lang(lng_passport_address_statement),
|
lang(lng_passport_address_statement),
|
||||||
lang(lng_passport_address_statement_upload),
|
lang(lng_passport_address_statement_upload),
|
||||||
});
|
}, lang(lng_passport_address_title));
|
||||||
case Value::Type::UtilityBill:
|
case Value::Type::UtilityBill:
|
||||||
return addReadyError({
|
return addReadyError({
|
||||||
lang(lng_passport_address_bill),
|
lang(lng_passport_address_bill),
|
||||||
lang(lng_passport_address_bill_upload),
|
lang(lng_passport_address_bill_upload),
|
||||||
});
|
}, lang(lng_passport_address_title));
|
||||||
case Value::Type::RentalAgreement:
|
case Value::Type::RentalAgreement:
|
||||||
return addReadyError({
|
return addReadyError({
|
||||||
lang(lng_passport_address_agreement),
|
lang(lng_passport_address_agreement),
|
||||||
lang(lng_passport_address_agreement_upload),
|
lang(lng_passport_address_agreement_upload),
|
||||||
});
|
}, lang(lng_passport_address_title));
|
||||||
case Value::Type::PassportRegistration:
|
case Value::Type::PassportRegistration:
|
||||||
return addReadyError({
|
return addReadyError({
|
||||||
lang(lng_passport_address_registration),
|
lang(lng_passport_address_registration),
|
||||||
lang(lng_passport_address_registration_upload),
|
lang(lng_passport_address_registration_upload),
|
||||||
});
|
}, lang(lng_passport_address_title));
|
||||||
case Value::Type::TemporaryRegistration:
|
case Value::Type::TemporaryRegistration:
|
||||||
return addReadyError({
|
return addReadyError({
|
||||||
lang(lng_passport_address_temporary),
|
lang(lng_passport_address_temporary),
|
||||||
lang(lng_passport_address_temporary_upload),
|
lang(lng_passport_address_temporary_upload),
|
||||||
});
|
}, lang(lng_passport_address_title));
|
||||||
default: Unexpected("Address type in ComputeScopeRow.");
|
default: Unexpected("Address type in ComputeScopeRow.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ constexpr auto kMaxPostcodeSize = 10;
|
||||||
|
|
||||||
EditDocumentScheme GetDocumentScheme(
|
EditDocumentScheme GetDocumentScheme(
|
||||||
Scope::Type type,
|
Scope::Type type,
|
||||||
base::optional<Value::Type> scansType) {
|
base::optional<Value::Type> scansType,
|
||||||
|
bool nativeNames) {
|
||||||
using Scheme = EditDocumentScheme;
|
using Scheme = EditDocumentScheme;
|
||||||
using ValueClass = Scheme::ValueClass;
|
using ValueClass = Scheme::ValueClass;
|
||||||
const auto DontFormat = nullptr;
|
const auto DontFormat = nullptr;
|
||||||
|
@ -74,7 +75,8 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
}
|
}
|
||||||
return base::none;
|
return base::none;
|
||||||
};
|
};
|
||||||
|
const auto NativeNameValidate = LimitedValidate(kMaxNameSize);
|
||||||
|
const auto NativeNameOrEmptyValidate = LimitedValidate(kMaxNameSize, 0);
|
||||||
const auto DocumentValidate = LimitedValidate(kMaxDocumentSize);
|
const auto DocumentValidate = LimitedValidate(kMaxDocumentSize);
|
||||||
const auto StreetValidate = LimitedValidate(kMaxStreetSize);
|
const auto StreetValidate = LimitedValidate(kMaxStreetSize);
|
||||||
const auto CityValidate = LimitedValidate(kMaxCitySize, kMinCitySize);
|
const auto CityValidate = LimitedValidate(kMaxCitySize, kMinCitySize);
|
||||||
|
@ -129,35 +131,40 @@ EditDocumentScheme GetDocumentScheme(
|
||||||
Unexpected("scansType in GetDocumentScheme:Identity.");
|
Unexpected("scansType in GetDocumentScheme:Identity.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
using Validator = EditDocumentScheme::Row::Validator;
|
||||||
result.rows = {
|
result.rows = {
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
qsl("first_name"),
|
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
||||||
lang(lng_passport_first_name),
|
lang(lng_passport_first_name),
|
||||||
NameValidate,
|
nativeNames ? Validator(NativeNameValidate) : NameValidate,
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
qsl("middle_name"),
|
(nativeNames
|
||||||
|
? qsl("middle_name_native")
|
||||||
|
: qsl("middle_name")),
|
||||||
lang(lng_passport_middle_name),
|
lang(lng_passport_middle_name),
|
||||||
NameOrEmptyValidate,
|
(nativeNames
|
||||||
|
? Validator(NativeNameOrEmptyValidate)
|
||||||
|
: NameOrEmptyValidate),
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
qsl("first_name")
|
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
PanelDetailsType::Text,
|
PanelDetailsType::Text,
|
||||||
qsl("last_name"),
|
nativeNames ? qsl("last_name_native") : qsl("last_name"),
|
||||||
lang(lng_passport_last_name),
|
lang(lng_passport_last_name),
|
||||||
NameValidate,
|
nativeNames ? Validator(NativeNameValidate) : NameValidate,
|
||||||
DontFormat,
|
DontFormat,
|
||||||
kMaxNameSize,
|
kMaxNameSize,
|
||||||
qsl("first_name")
|
nativeNames ? qsl("first_name_native") : qsl("first_name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueClass::Fields,
|
ValueClass::Fields,
|
||||||
|
@ -360,6 +367,15 @@ const std::map<QString, QString> &NativeToLatinMap() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AdjustKeyName(not_null<const Value*> value, const QString &key) {
|
||||||
|
if (!value->nativeNames) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
const auto &map = LatinToNativeMap();
|
||||||
|
const auto i = map.find(key);
|
||||||
|
return (i == end(map)) ? key : i->second;
|
||||||
|
}
|
||||||
|
|
||||||
bool SkipFieldCheck(not_null<const Value*> value, const QString &key) {
|
bool SkipFieldCheck(not_null<const Value*> value, const QString &key) {
|
||||||
if (value->type != Value::Type::PersonalDetails) {
|
if (value->type != Value::Type::PersonalDetails) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1058,7 +1074,8 @@ void PanelController::startScopeEdit(int index, int documentIndex) {
|
||||||
this,
|
this,
|
||||||
GetDocumentScheme(
|
GetDocumentScheme(
|
||||||
_editScope->type,
|
_editScope->type,
|
||||||
_editDocument->type),
|
_editDocument->type,
|
||||||
|
_editValue->nativeNames),
|
||||||
_editValue->error,
|
_editValue->error,
|
||||||
_editValue->data.parsedInEdit,
|
_editValue->data.parsedInEdit,
|
||||||
_editDocument->error,
|
_editDocument->error,
|
||||||
|
@ -1071,7 +1088,8 @@ void PanelController::startScopeEdit(int index, int documentIndex) {
|
||||||
this,
|
this,
|
||||||
GetDocumentScheme(
|
GetDocumentScheme(
|
||||||
_editScope->type,
|
_editScope->type,
|
||||||
_editDocument->type),
|
_editDocument->type,
|
||||||
|
false),
|
||||||
_editDocument->error,
|
_editDocument->error,
|
||||||
_editDocument->data.parsedInEdit,
|
_editDocument->data.parsedInEdit,
|
||||||
_editDocument->scanMissingError,
|
_editDocument->scanMissingError,
|
||||||
|
@ -1089,7 +1107,10 @@ void PanelController::startScopeEdit(int index, int documentIndex) {
|
||||||
auto result = object_ptr<PanelEditDocument>(
|
auto result = object_ptr<PanelEditDocument>(
|
||||||
_panel->widget(),
|
_panel->widget(),
|
||||||
this,
|
this,
|
||||||
GetDocumentScheme(_editScope->type),
|
GetDocumentScheme(
|
||||||
|
_editScope->type,
|
||||||
|
base::none,
|
||||||
|
_editValue->nativeNames),
|
||||||
_editValue->error,
|
_editValue->error,
|
||||||
_editValue->data.parsedInEdit);
|
_editValue->data.parsedInEdit);
|
||||||
const auto weak = make_weak(result.data());
|
const auto weak = make_weak(result.data());
|
||||||
|
@ -1288,6 +1309,8 @@ void PanelController::saveScope(ValueMap &&data, ValueMap &&filesData) {
|
||||||
|
|
||||||
if (_editValue) {
|
if (_editValue) {
|
||||||
_form->saveValueEdit(_editValue, std::move(data));
|
_form->saveValueEdit(_editValue, std::move(data));
|
||||||
|
} else {
|
||||||
|
Assert(data.fields.empty());
|
||||||
}
|
}
|
||||||
if (_editDocument) {
|
if (_editDocument) {
|
||||||
_form->saveValueEdit(_editDocument, std::move(filesData));
|
_form->saveValueEdit(_editDocument, std::move(filesData));
|
||||||
|
@ -1299,10 +1322,9 @@ void PanelController::saveScope(ValueMap &&data, ValueMap &&filesData) {
|
||||||
bool PanelController::editScopeChanged(
|
bool PanelController::editScopeChanged(
|
||||||
const ValueMap &data,
|
const ValueMap &data,
|
||||||
const ValueMap &filesData) const {
|
const ValueMap &filesData) const {
|
||||||
if (_editValue && _form->editValueChanged(_editValue, data)) {
|
if (_editValue && ValueChanged(_editValue, data)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (_editDocument
|
} else if (_editDocument && ValueChanged(_editDocument, filesData)) {
|
||||||
&& _form->editValueChanged(_editDocument, filesData)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -22,11 +22,13 @@ enum class ReadScanError;
|
||||||
|
|
||||||
EditDocumentScheme GetDocumentScheme(
|
EditDocumentScheme GetDocumentScheme(
|
||||||
Scope::Type type,
|
Scope::Type type,
|
||||||
base::optional<Value::Type> scansType = base::none);
|
base::optional<Value::Type> scansType,
|
||||||
|
bool nativeNames);
|
||||||
EditContactScheme GetContactScheme(Scope::Type type);
|
EditContactScheme GetContactScheme(Scope::Type type);
|
||||||
|
|
||||||
const std::map<QString, QString> &LatinToNativeMap();
|
const std::map<QString, QString> &LatinToNativeMap();
|
||||||
const std::map<QString, QString> &NativeToLatinMap();
|
const std::map<QString, QString> &NativeToLatinMap();
|
||||||
|
QString AdjustKeyName(not_null<const Value*> value, const QString &key);
|
||||||
bool SkipFieldCheck(not_null<const Value*> value, const QString &key);
|
bool SkipFieldCheck(not_null<const Value*> value, const QString &key);
|
||||||
|
|
||||||
struct ScanInfo {
|
struct ScanInfo {
|
||||||
|
|
|
@ -42,14 +42,16 @@ struct EditDocumentScheme {
|
||||||
Scans,
|
Scans,
|
||||||
};
|
};
|
||||||
struct Row {
|
struct Row {
|
||||||
|
using Validator = Fn<base::optional<QString>(const QString &value)>;
|
||||||
|
using Formatter = Fn<QString(const QString &value)>;
|
||||||
ValueClass valueClass = ValueClass::Fields;
|
ValueClass valueClass = ValueClass::Fields;
|
||||||
PanelDetailsType inputType = PanelDetailsType();
|
PanelDetailsType inputType = PanelDetailsType();
|
||||||
QString key;
|
QString key;
|
||||||
QString label;
|
QString label;
|
||||||
Fn<base::optional<QString>(const QString &value)> error;
|
Validator error;
|
||||||
Fn<QString(const QString &value)> format;
|
Formatter format;
|
||||||
int lengthLimit = 0;
|
int lengthLimit = 0;
|
||||||
QString keyForAttachmentTo; // attach last_name to first_name
|
QString keyForAttachmentTo; // attach [last|middle]_name to first_*
|
||||||
};
|
};
|
||||||
std::vector<Row> rows;
|
std::vector<Row> rows;
|
||||||
QString fieldsHeader;
|
QString fieldsHeader;
|
||||||
|
|
Loading…
Reference in New Issue