field.cpp 3.24 KB
Newer Older
1
/*
2
   SPDX-FileCopyrightText: 2017-2021 Volker Krause <vkrause@kde.org>
3

4
   SPDX-License-Identifier: LGPL-2.0-or-later
5
6
7
*/

#include "field.h"
Volker Krause's avatar
Volker Krause committed
8
#include "pass.h"
9
#include "pass_p.h"
10

11
#include <QGuiApplication>
12
13
14
15
#include <QJsonObject>

using namespace KPkPass;

Laurent Montel's avatar
Laurent Montel committed
16
17
18
19
namespace KPkPass
{
class FieldPrivate
{
Volker Krause's avatar
Volker Krause committed
20
public:
Volker Krause's avatar
Volker Krause committed
21
    const Pass *pass = nullptr;
Volker Krause's avatar
Volker Krause committed
22
23
24
25
26
27
28
29
30
    QJsonObject obj;
};
}

Field::Field()
    : d(new FieldPrivate)
{
}

Laurent Montel's avatar
Laurent Montel committed
31
32
Field::Field(const Field &) = default;
Field::Field(Field &&) = default;
Volker Krause's avatar
Volker Krause committed
33
Field::~Field() = default;
Laurent Montel's avatar
Laurent Montel committed
34
Field &Field::operator=(const Field &) = default;
Volker Krause's avatar
Volker Krause committed
35

Volker Krause's avatar
Volker Krause committed
36
Field::Field(const QJsonObject &obj, const Pass *pass)
Volker Krause's avatar
Volker Krause committed
37
    : d(new FieldPrivate)
38
{
Volker Krause's avatar
Volker Krause committed
39
    d->pass = pass;
Volker Krause's avatar
Volker Krause committed
40
41
42
43
44
    d->obj = obj;
}

QString Field::key() const
{
Volker Krause's avatar
Volker Krause committed
45
    return d->obj.value(QLatin1String("key")).toString();
46
47
48
49
}

QString Field::label() const
{
Volker Krause's avatar
Volker Krause committed
50
    if (d->pass) {
51
        return d->pass->d->message(d->obj.value(QLatin1String("label")).toString());
Volker Krause's avatar
Volker Krause committed
52
53
54
55
56
57
    }
    return {};
}

QVariant Field::value() const
{
Volker Krause's avatar
Volker Krause committed
58
    if (!d->pass) {
Volker Krause's avatar
Volker Krause committed
59
60
        return {};
    }
61
    auto v = d->pass->d->message(d->obj.value(QLatin1String("attributedValue")).toString());
Volker Krause's avatar
Volker Krause committed
62
    if (v.isEmpty()) {
63
        v = d->pass->d->message(d->obj.value(QLatin1String("value")).toString());
Volker Krause's avatar
Volker Krause committed
64
    }
65
66
67
68
69
70
71

    const auto dt = QDateTime::fromString(v, Qt::ISODate);
    if (dt.isValid()) {
        return dt;
    }

    // TODO number detection
Volker Krause's avatar
Volker Krause committed
72
73
74
75
76
    return v;
}

QString Field::valueDisplayString() const
{
77
    const auto v = value();
78
79
80
    // see
    // https://developer.apple.com/library/archive/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/FieldDictionary.html#//apple_ref/doc/uid/TP40012026-CH4-SW6
    // however, real-world data doesn't strictly follow that, so we have to guess a bit here...
81
    if (v.type() == QVariant::DateTime) {
82
        const auto dt = v.toDateTime();
83
84
85
86
87
        auto fmt = QLocale::ShortFormat;
        const auto dtStyle = d->obj.value(QLatin1String("dateStyle")).toString();
        if (dtStyle == QLatin1String("PKDateStyleLong") || dtStyle == QLatin1String("PKDateStyleFull")) {
            fmt = QLocale::LongFormat;
        }
88
89
90
91
92
93
        const auto timeStyle = d->obj.value(QLatin1String("timeStyle")).toString();
        if (timeStyle == QLatin1String("PKDateStyleNone") || (timeStyle.isEmpty() && !dtStyle.isEmpty() && dt.time() == QTime(0, 0))) {
            return QLocale().toString(dt.date(), fmt);
        }

        return QLocale().toString(dt, fmt);
94
95
96
    }

    // TODO respect number formatting options
Volker Krause's avatar
Volker Krause committed
97
    return value().toString().trimmed();
98
99
}

Volker Krause's avatar
Volker Krause committed
100
QString Field::changeMessage() const
101
{
Volker Krause's avatar
Volker Krause committed
102
    if (!d->pass) {
Volker Krause's avatar
Volker Krause committed
103
104
        return {};
    }
105
    auto msg = d->pass->d->message(d->obj.value(QLatin1String("changeMessage")).toString());
106
    msg.replace(QLatin1String("%@"), valueDisplayString());
Volker Krause's avatar
Volker Krause committed
107
    return msg;
108
}
109
110
111
112
113
114
115
116
117
118
119
120
121

Qt::Alignment Field::textAlignment() const
{
    const auto alignStr = d->obj.value(QLatin1String("textAlignment")).toString();
    if (alignStr == QLatin1String("PKTextAlignmentLeft")) {
        return Qt::AlignLeft;
    } else if (alignStr == QLatin1String("PKTextAlignmentCenter")) {
        return Qt::AlignHCenter;
    } else if (alignStr == QLatin1String("PKTextAlignmentRight")) {
        return Qt::AlignRight;
    }
    return QGuiApplication::layoutDirection() == Qt::LeftToRight ? Qt::AlignLeft : Qt::AlignRight;
}
Volker Krause's avatar
Volker Krause committed
122
123

#include "moc_field.cpp"