Commit 54303b62 authored by Volker Krause's avatar Volker Krause

Add visited countries to the statistics page

Besides being interesting, it's information occasionally asked for in e.g.
visa applications or some medical forms.
parent 85adf935
......@@ -13,6 +13,8 @@ set(itinerary_srcs
favoritelocationmodel.cpp
json.cpp
livedatamanager.cpp
localizer.cpp
locationhelper.cpp
locationinformation.cpp
navigationcontroller.cpp
pkpassmanager.cpp
......@@ -45,6 +47,7 @@ target_link_libraries(itinerary PUBLIC
KPim::Itinerary
KPim::PkPass
KF5::I18n
KF5::Contacts
KF5::CoreAddons
Qt5::Network
Qt5::Quick
......@@ -63,7 +66,6 @@ set(itinerary_app_srcs
main.cpp
countrymodel.cpp
documentsmodel.cpp
localizer.cpp
settings.cpp
tickettokenmodel.cpp
weatherforecastmodel.cpp
......@@ -74,7 +76,6 @@ add_executable(itinerary-app ${itinerary_app_srcs})
target_include_directories(itinerary-app PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(itinerary-app PRIVATE
itinerary
KF5::Contacts
Qt5::QuickControls2
)
if (ANDROID)
......
......@@ -27,6 +27,7 @@ RowLayout {
property var statItem
Kirigami.FormData.label: root.statItem.label
Layout.fillWidth: true
Kirigami.Icon {
source: root.statItem.trend == StatisticsItem.TrendUp ? "go-up-symbolic" : root.statItem.trend == StatisticsItem.TrendDown ? "go-down-symbolic" : "go-next-symbolic"
......@@ -37,6 +38,8 @@ RowLayout {
}
QQC2.Label {
Layout.fillWidth: true
text: root.statItem.value
wrapMode: Text.Wrap
}
}
......@@ -38,6 +38,7 @@ Kirigami.ScrollablePage {
}
Kirigami.FormLayout {
width: parent.width
QQC2.ComboBox {
Kirigami.FormData.isSection: true
......@@ -57,6 +58,7 @@ Kirigami.ScrollablePage {
StatisticsDelegate { statItem: model.totalDistance }
StatisticsDelegate { statItem: model.totalNights }
StatisticsDelegate { statItem: model.totalCO2 }
StatisticsDelegate { statItem: model.visitedCountries }
Kirigami.Separator {
Kirigami.FormData.isSection: true
......
/*
Copyright (C) 2020 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "locationhelper.h"
#include <KItinerary/LocationUtil>
#include <KItinerary/Place>
#include <QVariant>
using namespace KItinerary;
QString LocationHelper::departureCountry(const QVariant &res)
{
if (LocationUtil::isLocationChange(res)) {
return LocationUtil::address(LocationUtil::arrivalLocation(res)).addressCountry();
}
return LocationUtil::address(LocationUtil::location(res)).addressCountry();
}
QString LocationHelper::destinationCountry(const QVariant &res)
{
if (LocationUtil::isLocationChange(res)) {
return LocationUtil::address(LocationUtil::arrivalLocation(res)).addressCountry();
}
return LocationUtil::address(LocationUtil::location(res)).addressCountry();
}
/*
Copyright (C) 2020 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LOCATIONHELPER_H
#define LOCATIONHELPER_H
class QString;
class QVariant;
namespace LocationHelper
{
/** Departing country for location changes, location country otherwise. */
QString departureCountry(const QVariant &res);
/** Arrival country for location changes, location country otherwise. */
QString destinationCountry(const QVariant &res);
}
#endif // LOCATIONHELPER_H
......@@ -16,6 +16,8 @@
*/
#include "statisticsmodel.h"
#include "locationhelper.h"
#include "localizer.h"
#include "reservationmanager.h"
#include "tripgroupmanager.h"
......@@ -120,6 +122,16 @@ StatisticsItem StatisticsModel::totalCO2() const
return StatisticsItem(i18n("CO₂"), formatCo2(m_statData[Total][CO2]), trend(Total, CO2));
}
StatisticsItem StatisticsModel::visitedCountries() const
{
QStringList l;
l.reserve(m_countries.size());
std::transform(m_countries.begin(), m_countries.end(), std::back_inserter(l), [](const auto &iso) {
return Localizer().countryFlag(iso);
});
return StatisticsItem(i18n("Visited countries"), l.join(QLatin1Char(' ')), StatisticsItem::TrendUnknown);
}
StatisticsItem StatisticsModel::flightCount() const
{
return StatisticsItem(i18n("Flights"), QString::number(m_statData[Flight][TripCount]), trend(Flight, TripCount));
......@@ -242,6 +254,7 @@ void StatisticsModel::recompute()
memset(m_prevStatData, 0, AGGREGATE_TYPE_COUNT * STAT_TYPE_COUNT * sizeof(int));
m_hotelCount = 0;
m_prevHotelCount = 0;
m_countries.clear();
if (!m_resMgr || !m_tripGroupMgr) {
return;
......@@ -290,6 +303,13 @@ void StatisticsModel::recompute()
if (!tgId.isEmpty()) {
isPrev ? prevTripGroups.insert(tgId) : tripGroups.insert(tgId);
}
if (!isPrev) {
auto c = LocationHelper::departureCountry(res);
if (!c.isEmpty()) m_countries.insert(c);
c = LocationHelper::destinationCountry(res);
if (!c.isEmpty()) m_countries.insert(c);
}
}
m_tripGroupCount = tripGroups.size();
......
......@@ -21,6 +21,8 @@
#include <QDate>
#include <QObject>
#include <set>
class ReservationManager;
class TripGroupManager;
......@@ -60,6 +62,7 @@ class StatisticsModel : public QObject
Q_PROPERTY(StatisticsItem totalDistance READ totalDistance NOTIFY changed)
Q_PROPERTY(StatisticsItem totalNights READ totalNights NOTIFY changed)
Q_PROPERTY(StatisticsItem totalCO2 READ totalCO2 NOTIFY changed)
Q_PROPERTY(StatisticsItem visitedCountries READ visitedCountries NOTIFY changed)
Q_PROPERTY(StatisticsItem flightCount READ flightCount NOTIFY changed)
Q_PROPERTY(StatisticsItem flightDistance READ flightDistance NOTIFY changed)
......@@ -95,6 +98,7 @@ public:
StatisticsItem totalDistance() const;
StatisticsItem totalNights() const;
StatisticsItem totalCO2() const;
StatisticsItem visitedCountries() const;
StatisticsItem flightCount() const;
StatisticsItem flightDistance() const;
......@@ -134,13 +138,14 @@ private:
StatisticsItem::Trend trend(int current, int prev) const;
StatisticsItem::Trend trend(AggregateType type, StatType stat) const;
std::set<QString> m_countries;
int m_statData[AGGREGATE_TYPE_COUNT][STAT_TYPE_COUNT];
int m_prevStatData[AGGREGATE_TYPE_COUNT][STAT_TYPE_COUNT];
int m_hotelCount = 0;
int m_prevHotelCount = 0;
int m_tripGroupCount = 0;
int m_prevTripGroupCount = 0;
};
#endif // STATISTICSMODEL_H
......@@ -16,6 +16,7 @@
*/
#include "timelinemodel.h"
#include "locationhelper.h"
#include "locationinformation.h"
#include "pkpassmanager.h"
#include "reservationmanager.h"
......@@ -63,14 +64,6 @@ static bool needsSplitting(const QVariant &res)
|| JsonLd::isA<RentalCarReservation>(res);
}
static QString destinationCountry(const QVariant &res)
{
if (LocationUtil::isLocationChange(res)) {
return LocationUtil::address(LocationUtil::arrivalLocation(res)).addressCountry();
}
return LocationUtil::address(LocationUtil::location(res)).addressCountry();
}
static QTimeZone destinationTimeZone(const QVariant &res)
{
const auto dt = SortUtil::endDateTime(res);
......@@ -487,7 +480,7 @@ void TimelineModel::updateInformationElements()
}
auto newCountry = homeCountry;
newCountry.setIsoCode(destinationCountry(res));
newCountry.setIsoCode(LocationHelper::destinationCountry(res));
newCountry.setTimeZone(previousCountry.timeZone(), (*it).dt);
newCountry.setTimeZone(destinationTimeZone(res), (*it).dt);
if (newCountry == previousCountry) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment