1 /*
2     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "locationinformation.h"
8 
9 #include <KLocalizedString>
10 
11 #include <QDebug>
12 
13 using namespace KItinerary;
14 
15 LocationInformation::LocationInformation() = default;
16 LocationInformation::~LocationInformation() = default;
17 
operator ==(const LocationInformation & other) const18 bool LocationInformation::operator==(const LocationInformation& other) const
19 {
20     const auto dsEqual = m_drivingSide == other.m_drivingSide || m_drivingSide == KnowledgeDb::DrivingSide::Unknown || other.m_drivingSide == KnowledgeDb::DrivingSide::Unknown;
21     const auto ppEqual = (m_incompatPlugs == other.m_incompatPlugs && m_incompatSockets == other.m_incompatSockets)
22                         || m_powerPlugs == KnowledgeDb::Unknown || other.m_powerPlugs == KnowledgeDb::Unknown;
23 
24     return dsEqual && ppEqual && !hasRelevantTimeZoneChange(other);
25 }
26 
isoCode() const27 QString LocationInformation::isoCode() const
28 {
29     return m_isoCode;
30 }
31 
setIsoCode(const QString & isoCode)32 void LocationInformation::setIsoCode(const QString& isoCode)
33 {
34     if (m_isoCode == isoCode) {
35         return;
36     }
37     m_isoCode = isoCode;
38 
39     const auto id = KnowledgeDb::CountryId{isoCode};
40     if (!id.isValid()) {
41         setDrivingSide(KnowledgeDb::DrivingSide::Unknown);
42         setPowerPlugTypes(KnowledgeDb::Unknown);
43         return;
44     }
45     const auto countryRecord = KnowledgeDb::countryForId(id);
46     setDrivingSide(countryRecord.drivingSide);
47     setPowerPlugTypes(countryRecord.powerPlugTypes);
48 }
49 
drivingSide() const50 KnowledgeDb::DrivingSide LocationInformation::drivingSide() const
51 {
52     return m_drivingSide;
53 }
54 
setDrivingSide(KnowledgeDb::DrivingSide drivingSide)55 void LocationInformation::setDrivingSide(KnowledgeDb::DrivingSide drivingSide)
56 {
57     if (m_drivingSide == drivingSide) {
58         return;
59     }
60 
61     if (m_drivingSide != KnowledgeDb::DrivingSide::Unknown) {
62         m_drivingSideDiffers = true;
63     }
64 
65     m_drivingSide = drivingSide;
66 }
67 
drivingSideDiffers() const68 bool LocationInformation::drivingSideDiffers() const
69 {
70     return m_drivingSideDiffers;
71 }
72 
powerPlugCompatibility() const73 LocationInformation::PowerPlugCompatibility LocationInformation::powerPlugCompatibility() const
74 {
75     return m_powerPlugCompat;
76 }
77 
78 struct plugTypeName {
79     KnowledgeDb::PowerPlugType type;
80     const char *name;
81 }
82 
83 static const plug_name_table[] = {
84     { KnowledgeDb::TypeA, I18N_NOOP("Type A") },
85     { KnowledgeDb::TypeB, I18N_NOOP("Type B") },
86     { KnowledgeDb::TypeC, I18N_NOOP("Europlug") },
87     { KnowledgeDb::TypeD, I18N_NOOP("Type D") },
88     { KnowledgeDb::TypeE, I18N_NOOP("Type E") },
89     { KnowledgeDb::TypeF, I18N_NOOP("Schuko") },
90     { KnowledgeDb::TypeG, I18N_NOOP("Type G") },
91     { KnowledgeDb::TypeH, I18N_NOOP("Type H") },
92     { KnowledgeDb::TypeI, I18N_NOOP("Type I") },
93     { KnowledgeDb::TypeJ, I18N_NOOP("Type J") },
94     { KnowledgeDb::TypeK, I18N_NOOP("Type K") },
95     { KnowledgeDb::TypeL, I18N_NOOP("Type L") },
96     { KnowledgeDb::TypeM, I18N_NOOP("Type M") },
97     { KnowledgeDb::TypeN, I18N_NOOP("Type N") },
98 };
99 
plugTypesToString(KnowledgeDb::PowerPlugTypes type)100 static QString plugTypesToString(KnowledgeDb::PowerPlugTypes type)
101 {
102     QStringList l;
103     for (const auto &elem : plug_name_table) {
104         if (type & elem.type) {
105             l.push_back(i18n(elem.name));
106         }
107     }
108     return l.join(QLatin1String(", "));
109 }
110 
powerPlugTypes() const111 QString LocationInformation::powerPlugTypes() const
112 {
113     return plugTypesToString(m_incompatPlugs);
114 }
115 
powerSocketTypes() const116 QString LocationInformation::powerSocketTypes() const
117 {
118     return plugTypesToString(m_incompatSockets);
119 }
120 
setPowerPlugTypes(KItinerary::KnowledgeDb::PowerPlugTypes powerPlugs)121 void LocationInformation::setPowerPlugTypes(KItinerary::KnowledgeDb::PowerPlugTypes powerPlugs)
122 {
123     if (m_powerPlugs == powerPlugs) {
124         return;
125     }
126 
127     if (powerPlugs != KnowledgeDb::Unknown && m_powerPlugs != KnowledgeDb::Unknown) {
128         m_incompatPlugs = KnowledgeDb::incompatiblePowerPlugs(m_powerPlugs, powerPlugs);
129         m_incompatSockets = KnowledgeDb::incompatiblePowerSockets(m_powerPlugs, powerPlugs);
130 
131         if ((m_powerPlugs & powerPlugs) == 0) {
132             m_powerPlugCompat = Incompatible;
133         } else if (m_incompatPlugs != KnowledgeDb::Unknown || m_incompatSockets != KnowledgeDb::Unknown) {
134             m_powerPlugCompat = PartiallyCompatible;
135         }
136     }
137 
138     m_powerPlugs = powerPlugs;
139 }
140 
timeZone() const141 QTimeZone LocationInformation::timeZone() const
142 {
143     return m_timeZone;
144 }
145 
transitionTime() const146 QDateTime LocationInformation::transitionTime() const
147 {
148     return m_transitionTime;
149 }
150 
setTimeZone(const QTimeZone & tz,const QDateTime & transitionTime)151 void LocationInformation::setTimeZone(const QTimeZone &tz, const QDateTime &transitionTime)
152 {
153     if (m_timeZone.isValid() && tz.isValid()) {
154         m_timeZoneOffsetDelta = tz.offsetFromUtc(transitionTime) - m_timeZone.offsetFromUtc(transitionTime);
155     } else {
156         m_timeZoneOffsetDelta = 0;
157     }
158     m_timeZone = tz;
159     m_transitionTime = transitionTime;
160 }
161 
hasRelevantTimeZoneChange(const LocationInformation & other) const162 bool LocationInformation::hasRelevantTimeZoneChange(const LocationInformation &other) const
163 {
164     return m_timeZone.isValid() && other.m_timeZone.isValid()
165         && m_timeZone.offsetFromUtc(m_transitionTime) != other.m_timeZone.offsetFromUtc(m_transitionTime);
166 }
167 
timeZoneDiffers() const168 bool LocationInformation::timeZoneDiffers() const
169 {
170     return m_timeZoneOffsetDelta != 0 && m_timeZone.isValid();
171 }
172 
timeZoneName() const173 QString LocationInformation::timeZoneName() const
174 {
175     return m_timeZone.displayName(m_transitionTime, QTimeZone::LongName);
176 }
177 
timeZoneOffsetDelta() const178 int LocationInformation::timeZoneOffsetDelta() const
179 {
180     return m_timeZoneOffsetDelta;
181 }
182