1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#pragma once
#include <QString>
#include <QMetaType>
// DTO for storing the actual and total number of tracks for an album.
// Both numbers are 1-based and 0 indicates an undefined value.
class TrackNumbers final {
public:
static constexpr int kValueUndefined = 0;
static constexpr int kValueMin = 1; // lower bound (inclusive)
// Separates the total number of tracks from the actual
// track number in the textual format.
static const QString kSeparator;
static bool isUndefinedValue(int value) {
return kValueUndefined == value;
}
static bool isValidValue(int value) {
return isUndefinedValue(value) || (kValueMin <= value);
}
// Parses a value from a string. Returns true if the value
// has been parsed successfully and (optionally) stores the
// result in pValue. The caller is still responsible to check
// if the resulting value is valid!
static bool parseValueFromString(
const QString& str,
int* pValue = nullptr);
explicit TrackNumbers(int actualValue = kValueUndefined, int totalValue = kValueUndefined)
: m_actualValue(actualValue),
m_totalValue(totalValue) {
}
bool hasActual() const {
return !isUndefinedValue(m_actualValue);
}
bool isActualValid() const {
return isValidValue(m_actualValue);
}
int getActual() const {
return m_actualValue;
}
void setActual(int actualValue) {
m_actualValue = actualValue;
}
bool hasTotal() const {
return !isUndefinedValue(m_totalValue);
}
bool isTotalValid() const {
return isValidValue(m_totalValue);
}
int getTotal() const {
return m_totalValue;
}
void setTotal(int totalValue) {
m_totalValue = totalValue;
}
bool isValid() const {
return isActualValid() && isTotalValid();
}
enum class ParseResult {
EMPTY,
VALID,
INVALID
};
// Creates a new instance from string(s).
// If the caller is only interested in the ParseResult
// a nullptr can be passed for the corresponding output
// parameter pParsed.
static ParseResult parseFromStrings(
const QString& actualText,
const QString& totalText,
TrackNumbers* pParsed = nullptr);
static ParseResult parseFromString(
const QString& str,
TrackNumbers* pParsed = nullptr);
// Formats this instance as string(s).
// Both output parameters pActualText and pTotalText
// are optional and the caller might pass a nullptr.
void toStrings(
QString* pActualText,
QString* pTotalText) const;
QString toString() const;
// Splits a string into actual and total part. Both
// output parameters pActualText and pTotalText are
// optional and the caller might pass a nullptr.
static void splitString(
const QString& str,
QString* pActualText = nullptr,
QString* pTotalText = nullptr);
// Joins the actual and total strings
static QString joinAsString(
const QString& actualText,
const QString& totalText);
private:
int m_actualValue;
int m_totalValue;
};
inline
bool operator==(const TrackNumbers& lhs, const TrackNumbers& rhs) {
return (lhs.getActual() == rhs.getActual()) &&
(lhs.getTotal() == rhs.getTotal());
}
inline
bool operator!=(const TrackNumbers& lhs, const TrackNumbers& rhs) {
return !(lhs == rhs);
}
Q_DECLARE_TYPEINFO(TrackNumbers, Q_MOVABLE_TYPE);
Q_DECLARE_METATYPE(TrackNumbers)
|