mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
filter: implement importing of filter presets
When importing a divelog, import filter presets. If there are equal names, import only if the presets differ. In that case, disambiguate the name. This made things a bit more complicated, as comparison of filter presets had to be implemented. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
631be569fe
commit
f9721fce4b
14 changed files with 81 additions and 13 deletions
|
@ -17,9 +17,10 @@ void addDive(dive *d, bool autogroup, bool newNumber)
|
||||||
execute(new AddDive(d, autogroup, newNumber));
|
execute(new AddDive(d, autogroup, newNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
void importDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source)
|
void importDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites,
|
||||||
|
filter_preset_table_t *presets, int flags, const QString &source)
|
||||||
{
|
{
|
||||||
execute(new ImportDives(dives, trips, sites, flags, source));
|
execute(new ImportDives(dives, trips, sites, presets, flags, source));
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteDive(const QVector<struct dive*> &divesToDelete)
|
void deleteDive(const QVector<struct dive*> &divesToDelete)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#define COMMAND_H
|
#define COMMAND_H
|
||||||
|
|
||||||
#include "core/dive.h"
|
#include "core/dive.h"
|
||||||
|
#include "core/filterpreset.h"
|
||||||
#include "core/pictureobj.h"
|
#include "core/pictureobj.h"
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
@ -32,7 +33,8 @@ QString changesMade(); // return a string with the texts from all commands on
|
||||||
// insertion position.
|
// insertion position.
|
||||||
void addDive(dive *d, bool autogroup, bool newNumber);
|
void addDive(dive *d, bool autogroup, bool newNumber);
|
||||||
void importDives(struct dive_table *dives, struct trip_table *trips,
|
void importDives(struct dive_table *dives, struct trip_table *trips,
|
||||||
struct dive_site_table *sites, int flags, const QString &source); // The tables are consumed!
|
struct dive_site_table *sites, filter_preset_table_t *filter_presets,
|
||||||
|
int flags, const QString &source); // The tables are consumed!
|
||||||
void deleteDive(const QVector<struct dive*> &divesToDelete);
|
void deleteDive(const QVector<struct dive*> &divesToDelete);
|
||||||
void shiftTime(const std::vector<dive *> &changedDives, int amount);
|
void shiftTime(const std::vector<dive *> &changedDives, int amount);
|
||||||
void renumberDives(const QVector<QPair<dive *, int>> &divesToRenumber);
|
void renumberDives(const QVector<QPair<dive *, int>> &divesToRenumber);
|
||||||
|
|
|
@ -469,7 +469,8 @@ void AddDive::undoit()
|
||||||
setSelection(selection, currentDive);
|
setSelection(selection, currentDive);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source)
|
ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites,
|
||||||
|
filter_preset_table_t *filter_presets, int flags, const QString &source)
|
||||||
{
|
{
|
||||||
setText(Command::Base::tr("import %n dive(s) from %1", "", dives->nr).arg(source));
|
setText(Command::Base::tr("import %n dive(s) from %1", "", dives->nr).arg(source));
|
||||||
|
|
||||||
|
@ -509,6 +510,22 @@ ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, str
|
||||||
divesAndSitesToRemove.dives.reserve(dives_to_remove.nr);
|
divesAndSitesToRemove.dives.reserve(dives_to_remove.nr);
|
||||||
for (int i = 0; i < dives_to_remove.nr; ++i)
|
for (int i = 0; i < dives_to_remove.nr; ++i)
|
||||||
divesAndSitesToRemove.dives.push_back(dives_to_remove.dives[i]);
|
divesAndSitesToRemove.dives.push_back(dives_to_remove.dives[i]);
|
||||||
|
|
||||||
|
// When encountering filter presets with equal names, check whether they are
|
||||||
|
// the same. If they are, ignore them.
|
||||||
|
if (filter_presets) {
|
||||||
|
for (const filter_preset &preset: *filter_presets) {
|
||||||
|
QString name = preset.name;
|
||||||
|
auto it = std::find_if(filter_preset_table.begin(), filter_preset_table.end(),
|
||||||
|
[&name](const filter_preset &preset) { return preset.name == name; });
|
||||||
|
if (it != filter_preset_table.end() && it->data == preset.data)
|
||||||
|
continue;
|
||||||
|
filterPresetsToAdd.emplace_back(preset.name, preset.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume the table for analogy with the other tables.
|
||||||
|
filter_presets->clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportDives::workToBeDone()
|
bool ImportDives::workToBeDone()
|
||||||
|
@ -532,6 +549,13 @@ void ImportDives::redoit()
|
||||||
|
|
||||||
// Remember dives and sites to remove
|
// Remember dives and sites to remove
|
||||||
divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew);
|
divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew);
|
||||||
|
|
||||||
|
// Add new filter presets
|
||||||
|
for (auto &it: filterPresetsToAdd) {
|
||||||
|
filterPresetsToRemove.push_back(filter_preset_add(it.first, it.second));
|
||||||
|
emit diveListNotifier.filterPresetAdded(filterPresetsToRemove.back());
|
||||||
|
}
|
||||||
|
filterPresetsToAdd.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportDives::undoit()
|
void ImportDives::undoit()
|
||||||
|
@ -547,6 +571,18 @@ void ImportDives::undoit()
|
||||||
|
|
||||||
// ...and restore the selection
|
// ...and restore the selection
|
||||||
setSelection(selection, currentDive);
|
setSelection(selection, currentDive);
|
||||||
|
|
||||||
|
// Remove filter presets. Do this in reverse order.
|
||||||
|
for (auto it = filterPresetsToRemove.rbegin(); it != filterPresetsToRemove.rend(); ++it) {
|
||||||
|
int index = *it;
|
||||||
|
QString oldName = filter_preset_name_qstring(index);
|
||||||
|
FilterData oldData = filter_preset_get(index);
|
||||||
|
filter_preset_delete(index);
|
||||||
|
emit diveListNotifier.filterPresetRemoved(index);
|
||||||
|
filterPresetsToAdd.emplace_back(oldName, oldData);
|
||||||
|
}
|
||||||
|
filterPresetsToRemove.clear();
|
||||||
|
std::reverse(filterPresetsToAdd.begin(), filterPresetsToAdd.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteDive::DeleteDive(const QVector<struct dive*> &divesToDeleteIn)
|
DeleteDive::DeleteDive(const QVector<struct dive*> &divesToDeleteIn)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#define COMMAND_DIVELIST_H
|
#define COMMAND_DIVELIST_H
|
||||||
|
|
||||||
#include "command_base.h"
|
#include "command_base.h"
|
||||||
|
#include "core/filterpreset.h"
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
|
@ -97,7 +98,8 @@ private:
|
||||||
class ImportDives : public DiveListBase {
|
class ImportDives : public DiveListBase {
|
||||||
public:
|
public:
|
||||||
// Note: dives and trips are consumed - after the call they will be empty.
|
// Note: dives and trips are consumed - after the call they will be empty.
|
||||||
ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source);
|
ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites,
|
||||||
|
filter_preset_table_t *filter_presets, int flags, const QString &source);
|
||||||
private:
|
private:
|
||||||
void undoit() override;
|
void undoit() override;
|
||||||
void redoit() override;
|
void redoit() override;
|
||||||
|
@ -109,11 +111,14 @@ private:
|
||||||
|
|
||||||
// For redo
|
// For redo
|
||||||
std::vector<OwningDiveSitePtr> sitesToAdd;
|
std::vector<OwningDiveSitePtr> sitesToAdd;
|
||||||
|
std::vector<std::pair<QString,FilterData>>
|
||||||
|
filterPresetsToAdd;
|
||||||
|
|
||||||
// For undo
|
// For undo
|
||||||
std::vector<dive_site *> sitesToRemove;
|
std::vector<dive_site *> sitesToRemove;
|
||||||
std::vector<dive *> selection;
|
std::vector<dive *> selection;
|
||||||
dive *currentDive;
|
dive *currentDive;
|
||||||
|
std::vector<int> filterPresetsToRemove;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeleteDive : public DiveListBase {
|
class DeleteDive : public DiveListBase {
|
||||||
|
|
|
@ -22,6 +22,12 @@ static void updateDiveStatus(dive *d, bool newStatus, ShownChange &change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FilterData::operator==(const FilterData &f2) const
|
||||||
|
{
|
||||||
|
return fullText.originalQuery == f2.fullText.originalQuery &&
|
||||||
|
fulltextStringMode == f2.fulltextStringMode &&
|
||||||
|
constraints == f2.constraints;
|
||||||
|
}
|
||||||
|
|
||||||
bool FilterData::validFilter() const
|
bool FilterData::validFilter() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct FilterData {
|
||||||
StringFilterMode fulltextStringMode = StringFilterMode::STARTSWITH;
|
StringFilterMode fulltextStringMode = StringFilterMode::STARTSWITH;
|
||||||
std::vector<filter_constraint> constraints;
|
std::vector<filter_constraint> constraints;
|
||||||
bool validFilter() const;
|
bool validFilter() const;
|
||||||
|
bool operator==(const FilterData &) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiveFilter {
|
class DiveFilter {
|
||||||
|
|
|
@ -602,6 +602,22 @@ filter_constraint &filter_constraint::operator=(const filter_constraint &c)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool filter_constraint::operator==(const filter_constraint &f2) const
|
||||||
|
{
|
||||||
|
if (type != f2.type || string_mode != f2.string_mode || range_mode != f2.range_mode || negate != f2.negate)
|
||||||
|
return false;
|
||||||
|
if (filter_constraint_is_timestamp(type))
|
||||||
|
return data.timestamp_range.from == f2.data.timestamp_range.from &&
|
||||||
|
data.timestamp_range.to == f2.data.timestamp_range.to;
|
||||||
|
else if (filter_constraint_is_string(type))
|
||||||
|
return *data.string_list == *(f2.data.string_list);
|
||||||
|
else if (filter_constraint_is_multiple_choice(type))
|
||||||
|
return data.multiple_choice == f2.data.multiple_choice;
|
||||||
|
else
|
||||||
|
return data.numerical_range.from == f2.data.numerical_range.from &&
|
||||||
|
data.numerical_range.to == f2.data.numerical_range.to;
|
||||||
|
}
|
||||||
|
|
||||||
filter_constraint::~filter_constraint()
|
filter_constraint::~filter_constraint()
|
||||||
{
|
{
|
||||||
if (filter_constraint_is_string(type))
|
if (filter_constraint_is_string(type))
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct filter_constraint {
|
||||||
filter_constraint(const filter_constraint &);
|
filter_constraint(const filter_constraint &);
|
||||||
filter_constraint &operator=(const filter_constraint &);
|
filter_constraint &operator=(const filter_constraint &);
|
||||||
~filter_constraint();
|
~filter_constraint();
|
||||||
|
bool operator==(const filter_constraint &f2) const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,9 @@ FilterData filter_preset_get(int preset)
|
||||||
return filter_preset_table[preset].data;
|
return filter_preset_table[preset].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int filter_preset_add(const QString &name, const FilterData &d)
|
int filter_preset_add(const QString &nameIn, const FilterData &d)
|
||||||
{
|
{
|
||||||
|
QString name = get_unique_preset_name(nameIn, filter_preset_table);
|
||||||
return filter_preset_add_to_table(name, d, filter_preset_table);
|
return filter_preset_add_to_table(name, d, filter_preset_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ struct full_text_cache {
|
||||||
class FullText {
|
class FullText {
|
||||||
std::map<QString, std::vector<dive *>> words; // Dives that belong to each word
|
std::map<QString, std::vector<dive *>> words; // Dives that belong to each word
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void populate(); // Rebuild from current dive_table
|
void populate(); // Rebuild from current dive_table
|
||||||
void registerDive(struct dive *d); // Note: can be called repeatedly
|
void registerDive(struct dive *d); // Note: can be called repeatedly
|
||||||
void unregisterDive(struct dive *d); // Note: can be called repeatedly
|
void unregisterDive(struct dive *d); // Note: can be called repeatedly
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ void DiveLogImportDialog::on_buttonBox_accepted()
|
||||||
}
|
}
|
||||||
|
|
||||||
QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files");
|
QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files");
|
||||||
Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, source);
|
Command::importDives(&table, &trips, &sites, nullptr, IMPORT_MERGE_ALL_TRIPS, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
TagDragDelegate::TagDragDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
TagDragDelegate::TagDragDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
||||||
|
|
|
@ -1556,7 +1556,7 @@ void MainWindow::importFiles(const QStringList fileNames)
|
||||||
parse_file(fileNamePtr.data(), &table, &trips, &sites, &filter_presets);
|
parse_file(fileNamePtr.data(), &table, &trips, &sites, &filter_presets);
|
||||||
}
|
}
|
||||||
QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files");
|
QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files");
|
||||||
Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, source);
|
Command::importDives(&table, &trips, &sites, &filter_presets, IMPORT_MERGE_ALL_TRIPS, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::loadFiles(const QStringList fileNames)
|
void MainWindow::loadFiles(const QStringList fileNames)
|
||||||
|
|
|
@ -458,7 +458,7 @@ void DivelogsDeWebServices::buttonClicked(QAbstractButton *button)
|
||||||
struct dive_site_table sites = empty_dive_site_table;
|
struct dive_site_table sites = empty_dive_site_table;
|
||||||
filter_preset_table_t filter_presets;
|
filter_preset_table_t filter_presets;
|
||||||
parse_file(QFile::encodeName(zipFile.fileName()), &table, &trips, &sites, &filter_presets);
|
parse_file(QFile::encodeName(zipFile.fileName()), &table, &trips, &sites, &filter_presets);
|
||||||
Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, QStringLiteral("divelogs.de"));
|
Command::importDives(&table, &trips, &sites, nullptr, IMPORT_MERGE_ALL_TRIPS, QStringLiteral("divelogs.de"));
|
||||||
|
|
||||||
/* store last entered user/pass in config */
|
/* store last entered user/pass in config */
|
||||||
qPrefCloudStorage::set_divelogde_user(ui.userID->text());
|
qPrefCloudStorage::set_divelogde_user(ui.userID->text());
|
||||||
|
|
|
@ -194,7 +194,7 @@ void DiveImportedModel::recordDives(int flags)
|
||||||
std::pair<struct dive_table, struct dive_site_table> tables = consumeTables();
|
std::pair<struct dive_table, struct dive_site_table> tables = consumeTables();
|
||||||
if (tables.first.nr > 0) {
|
if (tables.first.nr > 0) {
|
||||||
auto data = thread.data();
|
auto data = thread.data();
|
||||||
Command::importDives(&tables.first, nullptr, &tables.second, flags, data->devName());
|
Command::importDives(&tables.first, nullptr, &tables.second, nullptr, flags, data->devName());
|
||||||
} else {
|
} else {
|
||||||
clear_dive_site_table(&tables.second);
|
clear_dive_site_table(&tables.second);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue