7#include "osmelementinformationmodel.h"
8#include "osmelementinformationmodel_data.cpp"
10#include "localization.h"
11#include "osmaddress.h"
13#include <KLocalizedString>
19static QString formatDistance(
int meter)
22 return i18n(
"%1m", meter);
25 return i18n(
"%1km", ((
int)meter/100)/10.0);
27 return i18n(
"%1km", (
int)qRound(meter/1000.0));
30bool OSMElementInformationModel::Info::operator<(OSMElementInformationModel::Info other)
const
32 if (category == other.category) {
33 return key < other.key;
35 return category < other.category;
38bool OSMElementInformationModel::Info::operator==(OSMElementInformationModel::Info other)
const
40 return category == other.category && key == other.key;
44OSMElementInformationModel::OSMElementInformationModel(
QObject *
parent)
46 , m_langs(
OSM::Languages::fromQLocale(
QLocale()))
50OSMElementInformationModel::~OSMElementInformationModel() =
default;
52OSMElement OSMElementInformationModel::element()
const
57void OSMElementInformationModel::setElement(
const OSMElement &element)
59 if (m_element == element.element()) {
64 m_element = element.element();
66 if (m_element.type() != OSM::Type::Null) {
73void OSMElementInformationModel::clear()
75 if (m_element.type() == OSM::Type::Null) {
85QString OSMElementInformationModel::name()
const
87 return valueForKey(Info{m_nameKey, Header}).
toString();
90QString OSMElementInformationModel::category()
const
92 return valueForKey(Info{m_categoryKey, Header}).
toString();
95int OSMElementInformationModel::rowCount(
const QModelIndex &parent)
const
97 if (
parent.isValid() || m_element.type() == OSM::Type::Null) {
100 return m_infos.size();
109 const auto info = m_infos[
index.
row()];
117 case OperatorWikipedia:
121 return PostalAddress;
123 return OpeningHoursType;
130 if (info.key == DebugKey) {
133 return keyName(info.key);
136 case DebugKey:
return debugTagValue(
index.
row());
137 case Wikipedia:
return i18n(
"Wikipedia");
138 default:
return valueForKey(info);
141 return urlify(valueForKey(info), info.key);
143 return info.category;
144 case CategoryLabelRole:
145 return categoryLabel(info.category);
154 r.insert(KeyRole,
"key");
155 r.insert(KeyLabelRole,
"keyLabel");
156 r.insert(ValueRole,
"value");
157 r.insert(ValueUrlRole,
"url");
158 r.insert(CategoryRole,
"category");
159 r.insert(CategoryLabelRole,
"categoryLabel");
160 r.insert(TypeRole,
"type");
164#define M(name, key, category) { name, OSMElementInformationModel::key, OSMElementInformationModel::category }
165struct KeyCategoryMapEntry {
167 OSMElementInformationModel::Key m_key;
168 OSMElementInformationModel::KeyCategory m_category;
170 constexpr inline OSMElementInformationModel::Key key()
const {
return m_key; }
171 constexpr inline OSMElementInformationModel::KeyCategory
category()
const {
return m_category; }
174static constexpr const KeyCategoryMapEntry simple_key_map[] = {
175 M(
"addr:city", Address, Contact),
176 M(
"addr:street", Address, Contact),
177 M(
"amenity", Category, Header),
178 M(
"bicycle_parking", BicycleParking, Parking),
179 M(
"brand", Name, Header),
180 M(
"brand:wikipedia", Wikipedia, UnresolvedCategory),
181 M(
"building", Category, Header),
182 M(
"bus_lines", Routes, Main),
183 M(
"bus_routes", Routes, Main),
184 M(
"buses", Routes, Main),
185 M(
"capacity", Capacity, UnresolvedCategory),
186 M(
"capacity:charging", CapacityCharing, Parking),
187 M(
"capacity:disabled", CapacityDisabled, Parking),
188 M(
"capacity:parent", CapacityParent, Parking),
189 M(
"capacity:women", CapacityWomen, Parking),
190 M(
"centralkey", CentralKey, Accessibility),
191 M(
"changing_table", DiaperChangingTable, UnresolvedCategory),
192 M(
"charge", Fee, UnresolvedCategory),
193 M(
"contact:city", Address, Contact),
194 M(
"contact:email", Email, Contact),
195 M(
"contact:phone", Phone, Contact),
196 M(
"contact:street", Address, Contact),
197 M(
"contact:website", Website, Contact),
198 M(
"cuisine", Cuisine, Main),
199 M(
"description", Description, Main),
200 M(
"diaper", DiaperChangingTable, UnresolvedCategory),
201 M(
"diplomatic", Category, Header),
202 M(
"email", Email, Contact),
203 M(
"fee", Fee, UnresolvedCategory),
204 M(
"genus", Name, Header),
205 M(
"historic", Category, Header),
206 M(
"int_name", Name, Header),
207 M(
"leisure", Category, Header),
208 M(
"maxstay", MaxStay, Parking),
209 M(
"mx:realtime_available", AvailableVehicles, Main),
210 M(
"mx:remaining_range", RemainingRange, Main),
211 M(
"mx:vehicle", Category, Header),
212 M(
"network", Network, Operator),
213 M(
"network:wikipedia", OperatorWikipedia, Operator),
214 M(
"office", Category, Header),
215 M(
"old_name", OldName, UnresolvedCategory),
216 M(
"opening_hours", OpeningHours, OpeningHoursCategory),
217 M(
"operator", OperatorName, Operator),
218 M(
"operator:email", Email, Contact),
219 M(
"operator:phone", Phone, Contact),
220 M(
"operator:website", Website, Contact),
221 M(
"operator:wikipedia", OperatorWikipedia, Operator),
222 M(
"parking:fee", Fee, Parking),
223 M(
"payment:cash", PaymentCash, Payment),
224 M(
"payment:coins", PaymentCash, Payment),
225 M(
"payment:notes", PaymentCash, Payment),
226 M(
"phone", Phone, Contact),
227 M(
"room", Category, Header),
228 M(
"route_ref", Routes, Main),
229 M(
"shop", Category, Header),
230 M(
"tactile_writing", TactileWriting, Accessibility),
231 M(
"takeaway", Takeaway, Main),
232 M(
"toilets:fee", Fee, Toilets),
233 M(
"toilets:wheelchair", Wheelchair, Toilets),
234 M(
"tourism", Category, Header),
235 M(
"url", Website, Contact),
236 M(
"website", Website, Contact),
237 M(
"wheelchair", Wheelchair, Accessibility),
238 M(
"wheelchair:lift", WheelchairLift, Accessibility),
240static_assert(isSortedLookupTable(simple_key_map),
"key map is not sorted!");
242static constexpr const KeyCategoryMapEntry localized_key_map[] = {
243 M(
"name", Name, Header),
244 M(
"loc_name", Name, Header),
245 M(
"species", Name, Header),
246 M(
"species:wikipedia", Wikipedia, UnresolvedCategory),
247 M(
"speech_output", SpeechOutput, Accessibility),
248 M(
"wikipedia", Wikipedia, UnresolvedCategory),
252template <
typename KeyMapEntry, std::
size_t N>
253void OSMElementInformationModel::addEntryForKey(
const char *keyName,
const KeyMapEntry(&map)[N])
255 const auto it = std::lower_bound(std::begin(map), std::end(map), keyName, [](
const auto &lhs,
auto rhs) {
256 return std::strcmp(lhs.keyName, rhs) < 0;
258 if (it != std::end(map) && std::strcmp((*it).keyName, keyName) == 0) {
259 m_infos.push_back(Info{(*it).key(), (*it).category()});
263template <
typename KeyMapEntry, std::
size_t N>
264void OSMElementInformationModel::addEntryForLocalizedKey(
const char *keyName,
const KeyMapEntry(&map)[N])
266 for (
const auto &entry :
map) {
267 const auto mapKeyLen = std::strlen(entry.keyName);
268 if (std::strncmp(keyName, entry.keyName, mapKeyLen) != 0) {
271 const auto keyNameLen = std::strlen(keyName);
272 if (keyNameLen == mapKeyLen || (keyNameLen == mapKeyLen + 3 && keyName[mapKeyLen] ==
':')) {
273 m_infos.push_back(Info{entry.key(), entry.category()});
279void OSMElementInformationModel::reload()
282 m_categoryKey = NoKey;
284 const bool isRoom = m_element.tagValue(
"indoor") ==
"room";
285 for (
auto it = m_element.tagsBegin(); it != m_element.tagsEnd(); ++it) {
286 addEntryForLocalizedKey((*it).key.name(), localized_key_map);
287 addEntryForKey((*it).key.name(), simple_key_map);
288 addEntryForKey((*it).key.name(), payment_generic_type_map);
289 addEntryForKey((*it).key.name(), payment_type_map);
290 addEntryForKey((*it).key.name(), diet_type_map);
291 addEntryForKey((*it).key.name(), socket_type_map);
292 addEntryForKey((*it).key.name(), authentication_type_map);
293 addEntryForKey((*it).key.name(), gender_type_map);
294 addEntryForLocalizedKey((*it).key.name(), tactile_writing_map);
296 if (isRoom && std::strcmp((*it).key.name(),
"ref") == 0) {
297 m_infos.push_back(Info{Name, Header});
301 std::sort(m_infos.begin(), m_infos.end());
302 m_infos.erase(std::unique(m_infos.begin(), m_infos.end()), m_infos.end());
307 for (
auto cat : {Parking, Toilets}) {
308 if (promoteMainCategory(cat)) {
314 for (
auto &info : m_infos) {
315 if (info.category == UnresolvedCategory) {
316 info.category = Main;
319 std::sort(m_infos.begin(), m_infos.end());
320 m_infos.erase(std::unique(m_infos.begin(), m_infos.end()), m_infos.end());
323 m_infos.push_back(Info{ DebugLink, DebugCategory });
324 const auto count = std::distance(m_element.tagsBegin(), m_element.tagsEnd());
325 std::fill_n(std::back_inserter(m_infos), count, Info{ DebugKey, DebugCategory });
329void OSMElementInformationModel::resolveCategories()
331 if (m_infos.empty() || m_infos[0].category != UnresolvedCategory) {
334 for (
auto &info : m_infos) {
335 if (info.category != UnresolvedCategory) {
340 if (m_element.tagValue(
"parking:fee").
isEmpty() && (!m_element.tagValue(
"parking").
isEmpty()
341 || m_element.tagValue(
"amenity") ==
"parking" || m_element.tagValue(
"amenity") ==
"bicycle_parking"))
343 info.category = Parking;
344 }
else if (m_element.tagValue(
"toilets:fee").
isEmpty() && (m_element.tagValue(
"toilets") ==
"yes" || m_element.tagValue(
"amenity") ==
"toilets")) {
345 info.category = Toilets;
347 info.category = Main;
351 if (m_element.tagValue(
"amenity").
endsWith(
"rental")) {
352 info.category = Main;
354 info.category = Parking;
360 const auto amenity = m_element.tagValue(
"amenity");
361 if ((amenity !=
"parking" && amenity !=
"toilets")
362 || !m_element.tagValue(
"office").
isEmpty()
363 || (!m_element.tagValue(
"room").
isEmpty() && m_element.tagValue(
"room") !=
"toilets")
364 || !m_element.tagValue(
"shop").
isEmpty()
365 || !m_element.tagValue(
"tourism").
isEmpty()) {
366 info.category = Main;
372 std::sort(m_infos.begin(), m_infos.end());
375void OSMElementInformationModel::resolveHeaders()
377 for (
auto key : { Name, Network, OperatorName, Category }) {
378 if (m_nameKey != NoKey) {
382 const auto it = std::find_if(m_infos.begin(), m_infos.end(), [key](Info info) {
383 return info.key == key;
385 if (it == m_infos.end()) {
389 m_nameKey = (*it).key;
395 const auto it = std::find_if(m_infos.begin(), m_infos.end(), [](Info info) {
396 return info.key == Category;
398 if (it == m_infos.end() || m_nameKey == Category) {
403 m_categoryKey = Category;
406bool OSMElementInformationModel::promoteMainCategory(OSMElementInformationModel::KeyCategory cat)
408 const auto hasMain = std::any_of(m_infos.begin(), m_infos.end(), [](
const auto &info) {
409 return info.category == Main;
416 bool didPromote =
false;
417 for (
auto &info : m_infos) {
418 if (info.category == cat) {
419 info.category = (info.key == Wheelchair ? Accessibility : Main);
425 std::sort(m_infos.begin(), m_infos.end());
430QString OSMElementInformationModel::categoryLabel(OSMElementInformationModel::KeyCategory cat)
const
433 case UnresolvedCategory:
435 case Main:
return {};
436 case OpeningHoursCategory:
return i18n(
"Opening Hours");
437 case Contact:
return i18n(
"Contact");
438 case Payment:
return i18n(
"Payment");
439 case Toilets:
return i18n(
"Toilets");
440 case Accessibility:
return i18n(
"Accessibility");
441 case Parking:
return i18n(
"Parking");
442 case Operator:
return i18n(
"Operator");
443 case DebugCategory:
return QStringLiteral(
"Debug");
448QString OSMElementInformationModel::debugTagKey(
int row)
const
450 const auto tagCount = std::distance(m_element.tagsBegin(), m_element.tagsEnd());
451 const auto tagIdx = row - (rowCount() - tagCount);
455QString OSMElementInformationModel::debugTagValue(
int row)
const
457 const auto tagCount = std::distance(m_element.tagsBegin(), m_element.tagsEnd());
458 const auto tagIdx = row - (rowCount() - tagCount);
462QString OSMElementInformationModel::keyName(OSMElementInformationModel::Key key)
const
467 case Category:
return {};
468 case OldName:
return i18n(
"Formerly");
469 case Description:
return i18n(
"Description");
470 case Routes:
return i18n(
"Routes");
471 case Cuisine:
return i18n(
"Cuisine");
472 case Diet:
return i18n(
"Diet");
473 case Takeaway:
return i18n(
"Takeaway");
474 case Socket:
return i18nc(
"electrical power socket",
"Socket");
475 case OpeningHours:
return {};
476 case AvailableVehicles:
return i18n(
"Available vehicles");
477 case Fee:
return i18n(
"Fee");
478 case Authentication:
return i18n(
"Authentication");
479 case BicycleParking:
return i18n(
"Bicycle parking");
480 case Capacity:
return i18n(
"Capacity");
481 case CapacityDisabled:
return i18n(
"Disabled parking spaces");
482 case CapacityWomen:
return i18n(
"Women parking spaces");
483 case CapacityParent:
return i18n(
"Parent parking spaces");
484 case CapacityCharing:
return i18n(
"Parking spaces for charging");
485 case MaxStay:
return i18n(
"Maximum stay");
486 case DiaperChangingTable:
return i18n(
"Diaper changing table");
487 case Gender:
return i18n(
"Gender");
488 case Wikipedia:
return {};
489 case Address:
return i18n(
"Address");
490 case Phone:
return i18n(
"Phone");
491 case Email:
return i18n(
"Email");
492 case Website:
return i18n(
"Website");
493 case PaymentCash:
return i18n(
"Cash");
494 case PaymentDigital:
return i18n(
"Digital");
495 case PaymentDebitCard:
return i18n(
"Debit cards");
496 case PaymentCreditCard:
return i18n(
"Credit cards");
497 case PaymentStoredValueCard:
return i18n(
"Stored value cards");
498 case Wheelchair:
return i18n(
"Wheelchair access");
499 case WheelchairLift:
return i18n(
"Wheelchair lift");
500 case CentralKey:
return i18n(
"Central key");
501 case SpeechOutput:
return i18n(
"Speech output");
502 case TactileWriting:
return i18n(
"Tactile writing");
503 case OperatorName:
return {};
504 case Network:
return i18nc(
"transport network",
"Network");
505 case OperatorWikipedia:
return {};
506 case RemainingRange:
return i18nc(
"remaining travel range of a battery powered vehicle",
"Remaining range");
507 case DebugLink:
return QStringLiteral(
"OSM");
508 case DebugKey:
return {};
519 for (
const auto &s : split) {
536}
static constexpr const script_map[] = {
543 return std::find_if(std::begin(script_map), std::end(script_map), [ls, cs](
const auto &m) {
return m.localeScript == ls && m.charScript == cs; }) != std::end(script_map);
546QVariant OSMElementInformationModel::valueForKey(Info info)
const
549 case NoKey:
return {};
551 const auto n =
QString::fromUtf8(m_element.tagValue(m_langs,
"name",
"loc_name",
"int_name",
"brand",
"ref",
"species",
"genus"));
552 const auto script = scriptForString(n);
554 const auto transliterated =
QString::fromUtf8(m_element.tagValue(m_langs,
"int_name"));
555 if (transliterated.isEmpty() || transliterated == n) {
558 return i18nc(
"local name (transliterated name)",
"%1 (%2)", n, transliterated);
565 appendNonEmpty(m_element.tagValue(
"amenity"), l);
566 appendNonEmpty(m_element.tagValue(
"shop"), l);
567 appendNonEmpty(m_element.tagValue(
"tourism"), l);
568 appendNonEmpty(m_element.tagValue(
"vending"), l);
569 const auto diplomatic = m_element.tagValue(
"diplomatic");
570 appendNonEmpty(diplomatic, l);
571 if (diplomatic.isEmpty()) {
572 appendNonEmpty(m_element.tagValue(
"office"), l);
574 appendNonEmpty(m_element.tagValue(
"leisure"), l);
575 appendNonEmpty(m_element.tagValue(
"historic"), l);
576 appendNonEmpty(m_element.tagValue(
"mx:vehicle"), l);
578 appendNonEmpty(m_element.tagValue(
"room"), l);
586 for (
auto it = l.
begin(); it != l.
end();++it) {
587 if ((*it).isEmpty() || (*it) ==
"yes" || (*it) ==
"no" || (*it) ==
"vending_machine" || (*it) ==
"building") {
594 appendNonEmpty(m_element.tagValue(
"building"), l);
595 for (
const auto &key : l) {
613 return m_element.tagValue(m_langs,
"description");
626 for (
const auto &d : diet_type_map) {
627 const auto v = m_element.tagValue(d.keyName);
628 const auto label = d.label.
toString();
631 }
else if (v ==
"only") {
633 }
else if (v ==
"no") {
639 case Takeaway:
return translatedBoolValue(m_element.tagValue(
"takeaway"));
643 for (
const auto &socket : socket_type_map) {
644 const auto value = m_element.tagValue(socket.keyName);
645 if (value.isEmpty() || value ==
"no") {
649 auto s = socket.label.toString();
652 if (value !=
"yes") {
656 const auto current = m_element.tagValue(
QByteArray(socket.keyName +
QByteArray(
":current")).constData());
657 if (!current.isEmpty()) {
658 if (std::all_of(current.begin(), current.end(), [](
unsigned char c) { return std::isdigit(c); })) {
664 const auto output = m_element.tagValue(
QByteArray(socket.keyName +
QByteArray(
":output")).constData());
665 if (!output.isEmpty()) {
666 if (std::all_of(output.begin(), output.end(), [](
unsigned char c) { return std::isdigit(c); })) {
673 if (!details.
empty()) {
680 case OpeningHours:
return QString::fromUtf8(m_element.tagValue(
"opening_hours"));
681 case AvailableVehicles:
683 const auto total = m_element.tagValue(
"mx:realtime_available").
toInt();
685 for (
const auto &v : available_vehicles_map) {
686 const auto b = m_element.tagValue(v.keyName);
690 types.
push_back(v.label.subs(b.toInt()).toString());
695 }
else if (types.
size() == 1) {
698 return i18n(
"%1 (%2)", total,
QLocale().createSeparatedList(types));
704 switch (info.category) {
705 case Parking: fee = m_element.tagValue(
"parking:fee",
"fee");
break;
706 case Toilets: fee = m_element.tagValue(
"toilets:fee",
"fee");
break;
707 default: fee = m_element.tagValue(
"fee");
714 if (!charge.isEmpty()) {
722 for (
const auto &auth : authentication_type_map) {
723 const auto v = m_element.tagValue(auth.keyName);
724 if (v.isEmpty() || v ==
"no") {
731 case BicycleParking:
return translateValues(m_element.tagValue(
"bicycle_parking"), bicycle_parking_map);
733 case CapacityDisabled:
return capacitryValue(
"capacity:disabled");
734 case CapacityWomen:
return capacitryValue(
"capacity:women");
735 case CapacityParent:
return capacitryValue(
"capacity:parent");
736 case CapacityCharing:
return capacitryValue(
"capacity:charging");
738 case DiaperChangingTable:
740 return translatedBoolValue(m_element.tagValue(
"changing_table",
"diaper"));
744 for (
const auto &gender : gender_type_map) {
745 const auto v = m_element.tagValue(gender.keyName);
746 if (v.isEmpty() || v ==
"no") {
753 case Wikipedia:
return wikipediaUrl(m_element.tagValue(m_langs,
"wikipedia",
"brand:wikipedia",
"species:wikipedia"));
755 case Phone:
return QString::fromUtf8(m_element.tagValue(
"contact:phone",
"phone",
"telephone",
"operator:phone"));
756 case Email:
return QString::fromUtf8(m_element.tagValue(
"contact:email",
"email",
"operator:email"));
757 case Website:
return QString::fromUtf8(m_element.tagValue(
"website",
"contact:website",
"url",
"operator:website"));
760 const auto coins = m_element.tagValue(
"payment:coins");
761 const auto notes = m_element.tagValue(
"payment:notes");
762 if (coins.isEmpty() && notes.isEmpty()) {
763 return translatedBoolValue(m_element.tagValue(
"payment:cash"));
765 if (coins ==
"yes" && notes ==
"yes") {
768 if (coins ==
"yes") {
769 return i18nc(
"payment option",
"coins only");
771 if (notes ==
"yes") {
772 return i18nc(
"payment option",
"notes only");
777 case PaymentDebitCard:
778 case PaymentCreditCard:
779 case PaymentStoredValueCard:
780 return paymentMethodValue(info.key);
784 if (info.category == Toilets) {
785 wheelchair = m_element.tagValue(
"toilets:wheelchair",
"wheelchair");
787 wheelchair = m_element.tagValue(
"wheelchair");
789 const auto a = translateValue(wheelchair.
constData(), wheelchair_map);
790 const auto d =
QString::fromUtf8(m_element.tagValue(m_langs,
"wheelchair:description"));
797 return translatedBoolValue(m_element.tagValue(
"wheelchair:lift"));
803 return translatedBoolValue(m_element.tagValue(m_langs,
"speech_output"));
808 bool explicitNo =
false;
809 for (
const auto &writing : tactile_writing_map) {
810 const auto v = m_element.tagValue(m_langs, writing.keyName);
823 const auto v = m_element.tagValue(m_langs,
"tactile_writing");
824 if (explicitNo && v.isEmpty()) {
827 return translatedBoolValue(v);
831 case OperatorWikipedia:
return wikipediaUrl(m_element.tagValue(m_langs,
"operator:wikipedia",
"network:wikipedia"));
834 const auto range = m_element.tagValue(
"mx:remaining_range").
toInt();
835 return formatDistance(range);
837 case DebugLink:
return m_element.url();
838 case DebugKey:
return {};
843QVariant OSMElementInformationModel::urlify(
const QVariant& v, OSMElementInformationModel::Key key)
const
878QString OSMElementInformationModel::paymentMethodList(OSMElementInformationModel::Key key)
const
881 for (
const auto &payment : payment_type_map) {
882 if (payment.key() != key) {
885 if (m_element.tagValue(payment.keyName) ==
"yes") {
893QString OSMElementInformationModel::paymentMethodValue(OSMElementInformationModel::Key key)
const
895 const auto s = paymentMethodList(key);
900 for (
const auto &payment : payment_generic_type_map) {
901 if (payment.key() != key) {
904 const auto s = m_element.tagValue(payment.keyName);
912QUrl OSMElementInformationModel::wikipediaUrl(
const QByteArray &wp)
const
931QString OSMElementInformationModel::capacitryValue(
const char *prop)
const
933 const auto v = m_element.tagValue(prop);
934 return translatedBoolValue(v);
937QString OSMElementInformationModel::translatedBoolValue(
const QByteArray &value)
const
939 if (value ==
"yes") {
948#include "moc_osmelementinformationmodel.cpp"
Postal address from OSM data.
QML wrapper around an OSM element.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
QString cuisineTypes(const QByteArray &value, Localization::TranslationOption opt=Localization::ReturnUnknownKey)
Translated values of the cuisine tag (does list splitting).
QString amenityType(const char *value, Localization::TranslationOption opt=Localization::ReturnUnknownKey)
Translated name for an amenity tag value (after list splitting).
OSM-based multi-floor indoor maps for buildings.
Category category(StandardShortcut id)
Low-level types and functions to work with raw OSM data as efficiently as possible.
QByteArray tagValue(const Elem &elem, TagKey key)
Returns the tag value for key of elem.
virtual QHash< int, QByteArray > roleNames() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
const char * constData() const const
bool endsWith(QByteArrayView bv) const const
bool isEmpty() const const
QList< QByteArray > split(char sep) const const
int toInt(bool *ok, int base) const const
const_reference at(qsizetype i) const const
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
void push_back(parameter_type value)
void reserve(qsizetype size)
qsizetype size() const const
QString createSeparatedList(const QStringList &list) const const
QString toString(QDate date, FormatType format) const const
bool isValid() const const
QObject * parent() const const
QString fromUtf8(QByteArrayView str)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
const_iterator begin() const const
const_iterator end() const const
QTextStream & left(QTextStream &stream)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
void setHost(const QString &host, ParsingMode mode)
void setPath(const QString &path, ParsingMode mode)
void setScheme(const QString &scheme)
QVariant fromValue(T &&value)
QString toString() const const
int userType() const const