[libcalamares] Make ZonesModel more QML-friendly

- expose TZ lookup (as a QObject*, which QML needs)
- C++ code should use find(), which is safer
This commit is contained in:
Adriaan de Groot 2020-08-06 10:47:47 +02:00
parent ab69e7c83a
commit 9e274aac07
2 changed files with 54 additions and 21 deletions

View File

@ -35,6 +35,9 @@ namespace CalamaresUtils
{ {
namespace Locale namespace Locale
{ {
class RegionData;
using RegionVector = QVector< RegionData* >;
using ZoneVector = QVector< TimeZoneData* >;
/** @brief Turns a string longitude or latitude notation into a double /** @brief Turns a string longitude or latitude notation into a double
* *
@ -81,6 +84,7 @@ TimeZoneData::TimeZoneData( const QString& region,
, m_latitude( latitude ) , m_latitude( latitude )
, m_longitude( longitude ) , m_longitude( longitude )
{ {
setObjectName( region + '/' + zone );
} }
QString QString
@ -105,9 +109,6 @@ RegionData::tr() const
return QObject::tr( m_human, "tz_regions" ); return QObject::tr( m_human, "tz_regions" );
} }
using RegionVector = QVector< RegionData* >;
using ZoneVector = QVector< TimeZoneData* >;
static void static void
loadTZData( RegionVector& regions, ZoneVector& zones ) loadTZData( RegionVector& regions, ZoneVector& zones )
{ {
@ -188,8 +189,10 @@ loadTZData( RegionVector& regions, ZoneVector& zones )
} }
struct Private class Private : public QObject
{ {
Q_OBJECT
public:
RegionVector m_regions; RegionVector m_regions;
ZoneVector m_zones; ZoneVector m_zones;
@ -210,6 +213,11 @@ struct Private
} }
return lhs->region() < rhs->region(); return lhs->region() < rhs->region();
} ); } );
for ( auto* z : m_zones )
{
z->setParent( this );
}
} }
}; };
@ -322,6 +330,22 @@ ZonesModel::find( double latitude, double longitude ) const
return nullptr; return nullptr;
} }
QObject*
ZonesModel::lookup( double latitude, double longitude ) const
{
const auto* p = find( latitude, longitude );
if ( !p )
{
p = find( "America", "New_York" );
}
if ( !p )
{
cWarning() << "No zone (not even New York) found, expect crashes.";
}
return const_cast< QObject* >( reinterpret_cast< const QObject* >( p ) );
}
ZonesModel::Iterator::operator bool() const ZonesModel::Iterator::operator bool() const
{ {
return 0 <= m_index && m_index < m_p->m_zones.count(); return 0 <= m_index && m_index < m_p->m_zones.count();
@ -376,3 +400,7 @@ RegionalZonesModel::filterAcceptsRow( int sourceRow, const QModelIndex& ) const
} // namespace Locale } // namespace Locale
} // namespace CalamaresUtils } // namespace CalamaresUtils
#include "utils/moc-warnings.h"
#include "TimeZone.moc"

View File

@ -35,7 +35,7 @@ namespace CalamaresUtils
{ {
namespace Locale namespace Locale
{ {
struct Private; class Private;
class RegionalZonesModel; class RegionalZonesModel;
class ZonesModel; class ZonesModel;
@ -122,22 +122,7 @@ public:
QHash< int, QByteArray > roleNames() const override; QHash< int, QByteArray > roleNames() const override;
/** @brief Look up TZ data based on its name. /** @brief Iterator for the underlying list of zones
*
* Returns @c nullptr if not found.
*/
const TimeZoneData* find( const QString& region, const QString& zone ) const;
/** @brief Look up TZ data based on the location.
*
* Returns the nearest zone to the given lat and lon.
*/
const TimeZoneData* find( double latitude, double longitude ) const;
/** @brief Iterator for testing purposes
*
* This is primarily for testing, but who knows, it might be useful
* elsewhere, and it's convenient when it can access Private.
* *
* Iterates over all the zones in the model. Operator * may return * Iterates over all the zones in the model. Operator * may return
* a @c nullptr when the iterator is not valid. Typical usage: * a @c nullptr when the iterator is not valid. Typical usage:
@ -171,6 +156,26 @@ public:
Iterator begin() const { return Iterator( m_private ); } Iterator begin() const { return Iterator( m_private ); }
public Q_SLOTS:
/** @brief Look up TZ data based on its name.
*
* Returns @c nullptr if not found.
*/
const TimeZoneData* find( const QString& region, const QString& zone ) const;
/** @brief Look up TZ data based on the location.
*
* Returns the nearest zone to the given lat and lon.
*/
const TimeZoneData* find( double latitude, double longitude ) const;
/** @brief Look up TZ data based on the location.
*
* Returns the nearest zone, or New York. This is non-const for QML
* purposes, but the object should be considered const anyway.
*/
QObject* lookup( double latitude, double longitude ) const;
private: private:
Private* m_private; Private* m_private;
}; };