mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Dive site: introduce proxy model DiveSiteSortedModel
The LocationInformationModel used to sort its entries and was completely rebuilt after every change. This makes it rather complex to support incremental changes. Instead, keep LocationInformationModel sorted by UUID so that indexes are consistent with indices in the core dive site table. Implement sorting by other columns than name and enable sorting in the dive site view. Finally, don't cache the list of dive site names for the mobile app, since that would also need some rather convoluted methods of keeping the list up to date. Calculate it on the fly. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
59f1191d0c
commit
e99c4c9059
6 changed files with 71 additions and 19 deletions
|
@ -8,7 +8,10 @@ TabDiveSite::TabDiveSite(QWidget *parent) : TabBase(parent)
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
ui.diveSites->setTitle(tr("Dive sites"));
|
ui.diveSites->setTitle(tr("Dive sites"));
|
||||||
ui.diveSites->setModel(LocationInformationModel::instance());
|
ui.diveSites->setModel(&model);
|
||||||
|
// Default: sort by name
|
||||||
|
ui.diveSites->view()->sortByColumn(LocationInformationModel::NAME, Qt::AscendingOrder);
|
||||||
|
ui.diveSites->view()->setSortingEnabled(true);
|
||||||
|
|
||||||
// Show only the first few columns
|
// Show only the first few columns
|
||||||
for (int i = LocationInformationModel::COORDS; i < LocationInformationModel::COLUMNS; ++i)
|
for (int i = LocationInformationModel::COORDS; i < LocationInformationModel::COLUMNS; ++i)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "TabBase.h"
|
#include "TabBase.h"
|
||||||
#include "ui_TabDiveSite.h"
|
#include "ui_TabDiveSite.h"
|
||||||
|
#include "qt-models/divelocationmodel.h"
|
||||||
|
|
||||||
class TabDiveSite : public TabBase {
|
class TabDiveSite : public TabBase {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -13,6 +14,7 @@ public:
|
||||||
void clear() override;
|
void clear() override;
|
||||||
private:
|
private:
|
||||||
Ui::TabDiveSite ui;
|
Ui::TabDiveSite ui;
|
||||||
|
DiveSiteSortedModel model;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -223,6 +223,9 @@ QMLManager::QMLManager() : m_locationServiceEnabled(false),
|
||||||
set_git_update_cb(&gitProgressCB);
|
set_git_update_cb(&gitProgressCB);
|
||||||
LOG_STP("qmlmgr git update");
|
LOG_STP("qmlmgr git update");
|
||||||
|
|
||||||
|
// present dive site lists sorted by name
|
||||||
|
locationModel.sort(LocationInformationModel::NAME);
|
||||||
|
|
||||||
// make sure we know if the current cloud repo has been successfully synced
|
// make sure we know if the current cloud repo has been successfully synced
|
||||||
syncLoadFromCloud();
|
syncLoadFromCloud();
|
||||||
LOG_STP("qmlmgr sync load cloud");
|
LOG_STP("qmlmgr sync load cloud");
|
||||||
|
@ -334,7 +337,8 @@ void QMLManager::updateAllGlobalLists()
|
||||||
buddyModel.updateModel(); emit buddyListChanged();
|
buddyModel.updateModel(); emit buddyListChanged();
|
||||||
suitModel.updateModel(); emit suitListChanged();
|
suitModel.updateModel(); emit suitListChanged();
|
||||||
divemasterModel.updateModel(); emit divemasterListChanged();
|
divemasterModel.updateModel(); emit divemasterListChanged();
|
||||||
locationModel.update(); emit locationListChanged();
|
// TODO: Probably not needed anymore, as the dive site list is generated on the fly!
|
||||||
|
LocationInformationModel::instance()->update(); emit locationListChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMLManager::mergeLocalRepo()
|
void QMLManager::mergeLocalRepo()
|
||||||
|
|
|
@ -209,7 +209,7 @@ private:
|
||||||
BuddyCompletionModel buddyModel;
|
BuddyCompletionModel buddyModel;
|
||||||
SuitCompletionModel suitModel;
|
SuitCompletionModel suitModel;
|
||||||
DiveMasterCompletionModel divemasterModel;
|
DiveMasterCompletionModel divemasterModel;
|
||||||
LocationInformationModel locationModel;
|
DiveSiteSortedModel locationModel;
|
||||||
QString m_startPageText;
|
QString m_startPageText;
|
||||||
QString m_logText;
|
QString m_logText;
|
||||||
QString m_lastError;
|
QString m_lastError;
|
||||||
|
|
|
@ -11,11 +11,6 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <core/gettextfromc.h>
|
#include <core/gettextfromc.h>
|
||||||
|
|
||||||
static bool dive_site_less_than(dive_site *a, dive_site *b)
|
|
||||||
{
|
|
||||||
return QString(a->name) < QString(b->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocationInformationModel *LocationInformationModel::instance()
|
LocationInformationModel *LocationInformationModel::instance()
|
||||||
{
|
{
|
||||||
static LocationInformationModel *self = new LocationInformationModel();
|
static LocationInformationModel *self = new LocationInformationModel();
|
||||||
|
@ -133,18 +128,9 @@ QVariant LocationInformationModel::data(const QModelIndex &index, int role) cons
|
||||||
void LocationInformationModel::update()
|
void LocationInformationModel::update()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
std::sort(dive_site_table.dive_sites, dive_site_table.dive_sites + dive_site_table.nr, dive_site_less_than);
|
|
||||||
locationNames.clear();
|
|
||||||
for (int i = 0; i < dive_site_table.nr; i++)
|
|
||||||
locationNames << QString(dive_site_table.dive_sites[i]->name);
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList LocationInformationModel::allSiteNames() const
|
|
||||||
{
|
|
||||||
return locationNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LocationInformationModel::removeRows(int row, int, const QModelIndex&)
|
bool LocationInformationModel::removeRows(int row, int, const QModelIndex&)
|
||||||
{
|
{
|
||||||
if(row >= rowCount())
|
if(row >= rowCount())
|
||||||
|
@ -183,6 +169,56 @@ void LocationInformationModel::diveSiteDeleted(struct dive_site *, int idx)
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DiveSiteSortedModel::filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const
|
||||||
|
{
|
||||||
|
// TODO: filtering
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiveSiteSortedModel::lessThan(const QModelIndex &i1, const QModelIndex &i2) const
|
||||||
|
{
|
||||||
|
// The source indices correspond to indices in the global dive site table.
|
||||||
|
// Let's access them directly without going via the source model.
|
||||||
|
// Kind of dirty, but less effort.
|
||||||
|
struct dive_site *ds1 = get_dive_site(i1.row(), &dive_site_table);
|
||||||
|
struct dive_site *ds2 = get_dive_site(i2.row(), &dive_site_table);
|
||||||
|
if (!ds1 || !ds2) // Invalid dive sites compare as different
|
||||||
|
return false;
|
||||||
|
switch (i1.column()) {
|
||||||
|
case LocationInformationModel::NAME:
|
||||||
|
default:
|
||||||
|
return QString::localeAwareCompare(QString(ds1->name), QString(ds2->name)) < 0; // TODO: avoid copy
|
||||||
|
case LocationInformationModel::DESCRIPTION: {
|
||||||
|
int cmp = QString::localeAwareCompare(QString(ds1->description), QString(ds2->description)); // TODO: avoid copy
|
||||||
|
return cmp != 0 ? cmp < 0 :
|
||||||
|
QString::localeAwareCompare(QString(ds1->name), QString(ds2->name)) < 0; // TODO: avoid copy
|
||||||
|
}
|
||||||
|
case LocationInformationModel::NUM_DIVES: {
|
||||||
|
int cmp = ds1->dives.nr - ds2->dives.nr;
|
||||||
|
// Since by default nr dives is descending, invert sort direction of names, such that
|
||||||
|
// the names are listed as ascending.
|
||||||
|
return cmp != 0 ? cmp < 0 :
|
||||||
|
QString::localeAwareCompare(QString(ds1->name), QString(ds2->name)) < 0; // TODO: avoid copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiveSiteSortedModel::DiveSiteSortedModel()
|
||||||
|
{
|
||||||
|
setSourceModel(LocationInformationModel::instance());
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DiveSiteSortedModel::allSiteNames() const
|
||||||
|
{
|
||||||
|
QStringList locationNames;
|
||||||
|
int num = rowCount();
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
int idx = mapToSource(index(i, 0)).row();
|
||||||
|
locationNames << QString(dive_site_table.dive_sites[idx]->name);
|
||||||
|
}
|
||||||
|
return locationNames;
|
||||||
|
}
|
||||||
|
|
||||||
GeoReferencingOptionsModel *GeoReferencingOptionsModel::instance()
|
GeoReferencingOptionsModel *GeoReferencingOptionsModel::instance()
|
||||||
{
|
{
|
||||||
static GeoReferencingOptionsModel *self = new GeoReferencingOptionsModel();
|
static GeoReferencingOptionsModel *self = new GeoReferencingOptionsModel();
|
||||||
|
|
|
@ -32,12 +32,19 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void update();
|
void update();
|
||||||
QStringList allSiteNames() const;
|
|
||||||
void diveSiteDiveCountChanged(struct dive_site *ds);
|
void diveSiteDiveCountChanged(struct dive_site *ds);
|
||||||
void diveSiteAdded(struct dive_site *ds, int idx);
|
void diveSiteAdded(struct dive_site *ds, int idx);
|
||||||
void diveSiteDeleted(struct dive_site *ds, int idx);
|
void diveSiteDeleted(struct dive_site *ds, int idx);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiveSiteSortedModel : public QSortFilterProxyModel {
|
||||||
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QStringList locationNames;
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override;
|
||||||
|
bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override;
|
||||||
|
public:
|
||||||
|
DiveSiteSortedModel();
|
||||||
|
QStringList allSiteNames() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// To access only divesites at the given GPS coordinates with the exception of a given dive site
|
// To access only divesites at the given GPS coordinates with the exception of a given dive site
|
||||||
|
|
Loading…
Add table
Reference in a new issue