summaryrefslogtreecommitdiffstats
path: root/desktop-widgets
diff options
context:
space:
mode:
Diffstat (limited to 'desktop-widgets')
-rw-r--r--desktop-widgets/command_divelist.cpp271
-rw-r--r--desktop-widgets/command_divelist.h86
-rw-r--r--desktop-widgets/divelistview.cpp49
-rw-r--r--desktop-widgets/divelistview.h1
-rw-r--r--desktop-widgets/mainwindow.cpp8
-rw-r--r--desktop-widgets/tab-widgets/maintab.cpp4
6 files changed, 332 insertions, 87 deletions
diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp
index a75004bea..9cf61eff9 100644
--- a/desktop-widgets/command_divelist.cpp
+++ b/desktop-widgets/command_divelist.cpp
@@ -4,6 +4,7 @@
#include "desktop-widgets/mainwindow.h"
#include "desktop-widgets/divelistview.h"
#include "core/divelist.h"
+#include "core/display.h" // for amount_selected
#include "core/subsurface-qt/DiveListNotifier.h"
namespace Command {
@@ -42,8 +43,20 @@ void processByTrip(std::vector<std::pair<dive_trip *, dive *>> &dives, Function
// This helper function removes a dive, takes ownership of the dive and adds it to a DiveToAdd structure.
// It is crucial that dives are added in reverse order of deletion, so the the indices are correctly
// set and that the trips are added before they are used!
-static DiveToAdd removeDive(struct dive *d)
-{
+DiveToAdd DiveListBase::removeDive(struct dive *d)
+{
+ // If the dive to be removed is selected, we will inform the frontend
+ // later via a signal that the dive changed.
+ if (d->selected)
+ selectionChanged = true;
+
+ // If the dive was the current dive, reset the current dive. The calling
+ // command is responsible of finding a new dive.
+ if (d == current_dive) {
+ selectionChanged = true; // Should have been set above, as current dive is always selected.
+ current_dive = nullptr;
+ }
+
DiveToAdd res;
res.idx = get_divenr(d);
if (res.idx < 0)
@@ -65,7 +78,7 @@ static DiveToAdd removeDive(struct dive *d)
// This helper function adds a dive and returns ownership to the backend. It may also add a dive trip.
// It is crucial that dives are added in reverse order of deletion (see comment above)!
// Returns pointer to added dive (which is owned by the backend!)
-static dive *addDive(DiveToAdd &d)
+dive *DiveListBase::addDive(DiveToAdd &d)
{
if (d.tripToAdd)
insert_trip_dont_merge(d.tripToAdd.release()); // Return ownership to backend
@@ -74,13 +87,18 @@ static dive *addDive(DiveToAdd &d)
dive *res = d.dive.release(); // Give up ownership of dive
add_single_dive(d.idx, res); // Return ownership to backend
+ // If the dive to be removed is selected, we will inform the frontend
+ // later via a signal that the dive changed.
+ if (res->selected)
+ selectionChanged = true;
+
return res;
}
// This helper function calls removeDive() on a list of dives to be removed and
// returns a vector of corresponding DiveToAdd objects, which can later be readded.
// The passed in vector is cleared.
-static std::vector<DiveToAdd> removeDives(std::vector<dive *> &divesToDelete)
+std::vector<DiveToAdd> DiveListBase::removeDives(std::vector<dive *> &divesToDelete)
{
std::vector<DiveToAdd> res;
res.reserve(divesToDelete.size());
@@ -90,7 +108,7 @@ static std::vector<DiveToAdd> removeDives(std::vector<dive *> &divesToDelete)
divesToDelete.clear();
// We send one dives-deleted signal per trip (see comments in DiveListNotifier.h).
- // Therefore, collect all dives in a array and sort by trip.
+ // Therefore, collect all dives in an array and sort by trip.
std::vector<std::pair<dive_trip *, dive *>> dives;
dives.reserve(res.size());
for (const DiveToAdd &entry: res)
@@ -112,7 +130,7 @@ static std::vector<DiveToAdd> removeDives(std::vector<dive *> &divesToDelete)
// of dives to be (re)added and returns a vector of the added dives. It does this in reverse
// order, so that trips are created appropriately and indexing is correct.
// The passed in vector is cleared.
-static std::vector<dive *> addDives(std::vector<DiveToAdd> &divesToAdd)
+std::vector<dive *> DiveListBase::addDives(std::vector<DiveToAdd> &divesToAdd)
{
std::vector<dive *> res;
res.reserve(divesToAdd.size());
@@ -289,6 +307,154 @@ static void moveDivesBetweenTrips(DivesToTrip &dives)
std::reverse(dives.divesToMove.begin(), dives.divesToMove.end());
}
+// When we initialize the command we don't have to roll-back any selection change
+DiveListBase::DiveListBase() : firstExecution(true)
+{
+}
+
+// Turn current selection into a vector.
+// TODO: This could be made much more efficient if we kept a sorted list of selected dives!
+static std::vector<dive *> getDiveSelection()
+{
+ std::vector<dive *> res;
+ res.reserve(amount_selected);
+
+ int i;
+ dive *d;
+ for_each_dive(i, d) {
+ if (d->selected)
+ res.push_back(d);
+ }
+ return res;
+}
+
+void DiveListBase::initWork()
+{
+ selectionChanged = false;
+}
+
+void DiveListBase::finishWork()
+{
+ if (selectionChanged) // If the selection changed -> tell the frontend
+ emit diveListNotifier.selectionChanged();
+}
+
+// Set the current dive either from a list of selected dives,
+// or a newly selected dive. In both cases, try to select the
+// dive that is newer that is newer than the given date.
+// This mimics the old behavior when the current dive changed.
+static void setClosestCurrentDive(timestamp_t when, const std::vector<dive *> &selection)
+{
+ // Start from back until we get the first dive that is before
+ // the supposed-to-be selected dive. (Note: this mimics the
+ // old behavior when the current dive changed).
+ for (auto it = selection.rbegin(); it < selection.rend(); ++it) {
+ if ((*it)->when > when && !(*it)->hidden_by_filter) {
+ current_dive = *it;
+ return;
+ }
+ }
+
+ // We didn't find a more recent selected dive -> try to
+ // find *any* visible selected dive.
+ for (dive *d: selection) {
+ if (!d->hidden_by_filter) {
+ current_dive = d;
+ return;
+ }
+ }
+
+ // No selected dive is visible! Take the closest dive. Note, this might
+ // return null, but that just means unsetting the current dive (as no
+ // dive is visible anyway).
+ current_dive = find_next_visible_dive(when);
+}
+
+// Rese the selection to the dives of the "selection" vector and send the appropriate signals.
+// Set the current dive to "currentDive". "currentDive" must be an element of "selection" (or
+// null if "seletion" is empty).
+void DiveListBase::restoreSelection(const std::vector<dive *> &selection, dive *currentDive)
+{
+ // To do so, generate vectors of dives to be selected and deselected.
+ // We send signals batched by trip, so keep track of trip/dive pairs.
+ std::vector<std::pair<dive_trip *, dive *>> divesToSelect;
+ std::vector<std::pair<dive_trip *, dive *>> divesToDeselect;
+
+ // TODO: We might want to keep track of selected dives in a more efficient way!
+ int i;
+ dive *d;
+ amount_selected = 0; // We recalculate amount_selected
+ for_each_dive(i, d) {
+ // We only modify dives that are currently visible.
+ if (d->hidden_by_filter) {
+ d->selected = false; // Note, not necessary, just to be sure
+ // that we get amount_selected right
+ continue;
+ }
+
+ // Search the dive in the list of selected dives.
+ // TODO: By sorting the list in the same way as the backend, this could be made more efficient.
+ bool newState = std::find(selection.begin(), selection.end(), d) != selection.end();
+
+ // TODO: Instead of using select_dive() and deselect_dive(), we set selected directly.
+ // The reason is that deselect() automatically sets a new current dive, which we
+ // don't want, as we set it later anyway.
+ // There is other parts of the C++ code that touches the innards directly, but
+ // ultimately this should be pushed down to C.
+ if (newState && !d->selected) {
+ d->selected = true;
+ ++amount_selected;
+ divesToSelect.push_back({ d->divetrip, d });
+ } else if (!newState && d->selected) {
+ d->selected = false;
+ divesToDeselect.push_back({ d->divetrip, d });
+ }
+ }
+
+ // Send the select and deselect signals
+ processByTrip(divesToSelect, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) {
+ emit diveListNotifier.divesSelected(trip, divesInTrip);
+ });
+ processByTrip(divesToDeselect, [&](dive_trip *trip, const QVector<dive *> &divesInTrip) {
+ emit diveListNotifier.divesDeselected(trip, divesInTrip);
+ });
+
+ bool currentDiveChanged = false;
+ if (current_dive != currentDive) {
+ currentDiveChanged = true;
+
+ // We cannot simply change the currentd dive to the given dive.
+ // It might be hidden by a filter and thus not be selected.
+ if (currentDive->selected)
+ // Current dive is visible and selected. Excellent.
+ current_dive = currentDive;
+ else
+ // Current not visible -> find a different dive.
+ setClosestCurrentDive(currentDive->when, selection);
+ emit diveListNotifier.currentDiveChanged();
+ }
+
+ // If anything changed (selection or current dive), send a final signal.
+ if (!divesToSelect.empty() || !divesToDeselect.empty() || currentDiveChanged)
+ selectionChanged = true;
+}
+
+void DiveListBase::undo()
+{
+ auto marker = diveListNotifier.enterCommand();
+ initWork();
+ undoit();
+ finishWork();
+}
+
+void DiveListBase::redo()
+{
+ auto marker = diveListNotifier.enterCommand();
+ initWork();
+ redoit();
+ finishWork();
+}
+
AddDive::AddDive(dive *d, bool autogroup)
{
setText(tr("add dive"));
@@ -321,30 +487,31 @@ bool AddDive::workToBeDone()
return true;
}
-void AddDive::redo()
+void AddDive::redoit()
{
- auto marker = diveListNotifier.enterCommand();
+ // Remember selection so that we can undo it
+ selection = getDiveSelection();
+ currentDive = current_dive;
- int idx = divesToAdd[0].idx;
divesToRemove = addDives(divesToAdd);
mark_divelist_changed(true);
- // Finally, do the UI stuff:
- MainWindow::instance()->dive_list()->unselectDives();
- MainWindow::instance()->dive_list()->selectDive(idx, true);
+ // Select the newly added dive
+ restoreSelection(divesToRemove, divesToRemove[0]);
// Exit from edit mode, but don't recalculate dive list
// TODO: Remove edit mode
MainWindow::instance()->refreshDisplay(false);
}
-void AddDive::undo()
+void AddDive::undoit()
{
- auto marker = diveListNotifier.enterCommand();
-
- // Simply remove the dive that was previously added
+ // Simply remove the dive that was previously added...
divesToAdd = removeDives(divesToRemove);
+ // ...and restore the selection
+ restoreSelection(selection, currentDive);
+
// Exit from edit mode, but don't recalculate dive list
// TODO: Remove edit mode
MainWindow::instance()->refreshDisplay(false);
@@ -360,18 +527,31 @@ bool DeleteDive::workToBeDone()
return !divesToDelete.empty();
}
-void DeleteDive::undo()
+void DeleteDive::undoit()
{
- auto marker = diveListNotifier.enterCommand();
divesToDelete = addDives(divesToAdd);
mark_divelist_changed(true);
+
+ // Select all re-added dives and make the first one current
+ dive *currentDive = !divesToDelete.empty() ? divesToDelete[0] : nullptr;
+ restoreSelection(divesToDelete, currentDive);
}
-void DeleteDive::redo()
+void DeleteDive::redoit()
{
- auto marker = diveListNotifier.enterCommand();
divesToAdd = removeDives(divesToDelete);
mark_divelist_changed(true);
+
+ // Deselect all dives and select dive that was close to the first deleted dive
+ dive *newCurrent = nullptr;
+ if (!divesToAdd.empty()) {
+ timestamp_t when = divesToAdd[0].dive->when;
+ newCurrent = find_next_visible_dive(when);
+ }
+ if (newCurrent)
+ restoreSelection(std::vector<dive *>{ newCurrent }, newCurrent);
+ else
+ restoreSelection(std::vector<dive *>(), nullptr);
}
@@ -381,9 +561,8 @@ ShiftTime::ShiftTime(const QVector<dive *> &changedDives, int amount)
setText(tr("shift time of %n dives", "", changedDives.count()));
}
-void ShiftTime::redo()
+void ShiftTime::redoit()
{
- auto marker = diveListNotifier.enterCommand();
for (dive *d: diveList)
d->when -= timeChanged;
@@ -413,10 +592,10 @@ bool ShiftTime::workToBeDone()
return !diveList.isEmpty();
}
-void ShiftTime::undo()
+void ShiftTime::undoit()
{
- // Same as redo(), since after redo() we reversed the timeOffset
- redo();
+ // Same as redoit(), since after redoit() we reversed the timeOffset
+ redoit();
}
@@ -425,9 +604,8 @@ RenumberDives::RenumberDives(const QVector<QPair<dive *, int>> &divesToRenumberI
setText(tr("renumber %n dive(s)", "", divesToRenumber.count()));
}
-void RenumberDives::undo()
+void RenumberDives::undoit()
{
- auto marker = diveListNotifier.enterCommand();
renumberDives(divesToRenumber);
mark_divelist_changed(true);
}
@@ -437,10 +615,10 @@ bool RenumberDives::workToBeDone()
return !divesToRenumber.isEmpty();
}
-void RenumberDives::redo()
+void RenumberDives::redoit()
{
// Redo and undo do the same thing!
- undo();
+ undoit();
}
bool TripBase::workToBeDone()
@@ -448,18 +626,17 @@ bool TripBase::workToBeDone()
return !divesToMove.divesToMove.empty();
}
-void TripBase::redo()
+void TripBase::redoit()
{
- auto marker = diveListNotifier.enterCommand();
moveDivesBetweenTrips(divesToMove);
mark_divelist_changed(true);
}
-void TripBase::undo()
+void TripBase::undoit()
{
// Redo and undo do the same thing!
- redo();
+ redoit();
}
RemoveDivesFromTrip::RemoveDivesFromTrip(const QVector<dive *> &divesToRemove)
@@ -540,7 +717,7 @@ SplitDives::SplitDives(dive *d, duration_t time)
split_dive_dont_insert(d, &new1, &new2) :
split_dive_at_time_dont_insert(d, time, &new1, &new2);
- // If this didn't work, reset pointers so that redo() and undo() do nothing
+ // If this didn't work, reset pointers as a mark that nothing is to be done.
if (idx < 0) {
diveToSplit = nullptr;
divesToUnsplit[0] = divesToUnsplit[1];
@@ -561,23 +738,27 @@ bool SplitDives::workToBeDone()
return !!diveToSplit;
}
-void SplitDives::redo()
+void SplitDives::redoit()
{
- auto marker = diveListNotifier.enterCommand();
divesToUnsplit[0] = addDive(splitDives[0]);
divesToUnsplit[1] = addDive(splitDives[1]);
unsplitDive = removeDive(diveToSplit);
mark_divelist_changed(true);
+
+ // Select split dives and make first dive current
+ restoreSelection(std::vector<dive *>{ divesToUnsplit[0], divesToUnsplit[1] }, divesToUnsplit[0]);
}
-void SplitDives::undo()
+void SplitDives::undoit()
{
- // Note: reverse order with respect to redo()
- auto marker = diveListNotifier.enterCommand();
+ // Note: reverse order with respect to redoit()
diveToSplit = addDive(unsplitDive);
splitDives[1] = removeDive(divesToUnsplit[1]);
splitDives[0] = removeDive(divesToUnsplit[0]);
mark_divelist_changed(true);
+
+ // Select unsplit dive and make it current
+ restoreSelection(std::vector<dive *>{ diveToSplit }, diveToSplit);
}
MergeDives::MergeDives(const QVector <dive *> &dives)
@@ -664,20 +845,24 @@ bool MergeDives::workToBeDone()
return !!mergedDive.dive;
}
-void MergeDives::redo()
+void MergeDives::redoit()
{
- auto marker = diveListNotifier.enterCommand();
renumberDives(divesToRenumber);
diveToUnmerge = addDive(mergedDive);
unmergedDives = removeDives(divesToMerge);
+
+ // Select merged dive and make it current
+ restoreSelection(std::vector<dive *>{ diveToUnmerge }, diveToUnmerge);
}
-void MergeDives::undo()
+void MergeDives::undoit()
{
- auto marker = diveListNotifier.enterCommand();
divesToMerge = addDives(unmergedDives);
mergedDive = removeDive(diveToUnmerge);
renumberDives(divesToRenumber);
+
+ // Select unmerged dives and make first one current
+ restoreSelection(divesToMerge, divesToMerge[0]);
}
} // namespace Command
diff --git a/desktop-widgets/command_divelist.h b/desktop-widgets/command_divelist.h
index e679369af..01dd4db77 100644
--- a/desktop-widgets/command_divelist.h
+++ b/desktop-widgets/command_divelist.h
@@ -38,12 +38,54 @@ struct DivesToTrip
std::vector<OwningTripPtr> tripsToAdd;
};
-class AddDive : public Base {
-public:
- AddDive(dive *dive, bool autogroup);
+// All divelist commands derive from a common base class, which has a flag
+// for when then selection changed. In such a case, in the redo() and undo()
+// methods a signal will be sent. The base-class implements redo() and undo(),
+// which resets the flag and sends a signal. Derived classes implement the
+// virtual methods redoit() and undoit() [Yes, the names could be more expressive].
+// Moreover, the class implements helper methods, which set the selectionChanged
+// flag accordingly.
+class DiveListBase : public Base {
+protected:
+ DiveListBase();
+
+ // These are helper functions to add / remove dive from the C-core structures,
+ // which set the selectionChanged flag if the added / removed dive was selected.
+ DiveToAdd removeDive(struct dive *d);
+ dive *addDive(DiveToAdd &d);
+ std::vector<DiveToAdd> removeDives(std::vector<dive *> &divesToDelete);
+ std::vector<dive *> addDives(std::vector<DiveToAdd> &divesToAdd);
+
+ // Set the selection to a given state. Set the selectionChanged flag if anything changed.
+ void restoreSelection(const std::vector<dive *> &selection, dive *currentDive);
+
+ // On first execution, the selections before and after execution will
+ // be remembered. On all further executions, the selection will be reset to
+ // the remembered values.
+ // Note: Therefore, commands should manipulate the selection and send the
+ // corresponding signals only on first execution!
+ bool firstExecution;
+
+ // Commands set this flag if the selection changed on first execution.
+ // Only then, a new the divelist will be scanned again after the command.
+ // If this flag is set on first execution, a selectionChanged signal will
+ // be sent.
+ bool selectionChanged;
private:
+ void initWork(); // reset selectionChanged flag
+ void finishWork(); // emit signal if selection changed
void undo() override;
void redo() override;
+ virtual void redoit() = 0;
+ virtual void undoit() = 0;
+};
+
+class AddDive : public DiveListBase {
+public:
+ AddDive(dive *dive, bool autogroup);
+private:
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo
@@ -53,14 +95,16 @@ private:
// For undo
std::vector<dive *> divesToRemove;
+ std::vector<dive *> selection;
+ dive * currentDive;
};
-class DeleteDive : public Base {
+class DeleteDive : public DiveListBase {
public:
DeleteDive(const QVector<dive *> &divesToDelete);
private:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo
@@ -70,12 +114,12 @@ private:
std::vector<DiveToAdd> divesToAdd;
};
-class ShiftTime : public Base {
+class ShiftTime : public DiveListBase {
public:
ShiftTime(const QVector<dive *> &changedDives, int amount);
private:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo and undo
@@ -83,12 +127,12 @@ private:
int timeChanged;
};
-class RenumberDives : public Base {
+class RenumberDives : public DiveListBase {
public:
RenumberDives(const QVector<QPair<dive *, int>> &divesToRenumber);
private:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo and undo: pairs of dive-id / new number
@@ -99,10 +143,10 @@ private:
// and MergeTrips all do the same thing, just the intialization differs.
// Therefore, define a base class with the proper data-structures, redo()
// and undo() functions and derive to specialize the initialization.
-class TripBase : public Base {
+class TripBase : public DiveListBase {
protected:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo and undo
@@ -127,13 +171,13 @@ struct MergeTrips : public TripBase {
MergeTrips(dive_trip *trip1, dive_trip *trip2);
};
-class SplitDives : public Base {
+class SplitDives : public DiveListBase {
public:
// If time is < 0, split at first surface interval
SplitDives(dive *d, duration_t time);
private:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo
@@ -147,12 +191,12 @@ private:
dive *divesToUnsplit[2];
};
-class MergeDives : public Base {
+class MergeDives : public DiveListBase {
public:
MergeDives(const QVector<dive *> &dives);
private:
- void undo() override;
- void redo() override;
+ void undoit() override;
+ void redoit() override;
bool workToBeDone() override;
// For redo
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp
index 2a0d7028c..8ed07b4db 100644
--- a/desktop-widgets/divelistview.cpp
+++ b/desktop-widgets/divelistview.cpp
@@ -44,6 +44,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
setContextMenuPolicy(Qt::DefaultContextMenu);
setSelectionMode(ExtendedSelection);
header()->setContextMenuPolicy(Qt::ActionsContextMenu);
+ connect(DiveTripModel::instance(), &DiveTripModel::selectionChanged, this, &DiveListView::diveSelectionChanged);
header()->setStretchLastSection(true);
@@ -176,23 +177,37 @@ void DiveListView::reset()
}
}
+// If items were selected, inform the selection model
+void DiveListView::diveSelectionChanged(const QVector<QModelIndex> &indexes, bool select)
+{
+ MultiFilterSortModel *m = MultiFilterSortModel::instance();
+ QItemSelectionModel *s = selectionModel();
+ auto flags = select ?
+ QItemSelectionModel::Rows | QItemSelectionModel::Select :
+ QItemSelectionModel::Rows | QItemSelectionModel::Deselect;
+ for (const QModelIndex &index: indexes) {
+ // We have to transform the indices into local indices, since
+ // there might be sorting or filtering in effect.
+ QModelIndex localIndex = m->mapFromSource(index);
+
+ // It might be possible that the item is not shown (filter is
+ // in effect). Then we get an invalid index and should ignore
+ // this selection.
+ if (!localIndex.isValid())
+ continue;
+
+ s->select(localIndex, flags);
+ }
+}
+
// If rows are added, check which of these rows is a trip and expand the first column
void DiveListView::rowsInserted(const QModelIndex &parent, int start, int end)
{
// First, let the QTreeView do its thing.
QTreeView::rowsInserted(parent, start, end);
+ // Check for each inserted row whether this is a trip and expand the first column
QAbstractItemModel *m = model();
- QItemSelectionModel *s = selectionModel();
-
- // Check whether any of the items is selected
- for (int i = start; i <= end; ++i) {
- QModelIndex index = m->index(i, 0, parent);
- if (m->data(index, DiveTripModel::SELECTED_ROLE).toBool())
- s->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- }
-
- // Now check for each inserted row whether this is a trip and expand the first column
if (parent.isValid()) // Trips don't have a parent
return;
for (int i = start; i <= end; ++i) {
@@ -284,7 +299,7 @@ void DiveListView::clearTripSelection()
void DiveListView::unselectDives()
{
// make sure we don't try to redraw the dives during the selection change
- selected_dive = -1;
+ current_dive = nullptr;
amount_selected = 0;
// clear the Qt selection
selectionModel()->clearSelection();
@@ -353,7 +368,7 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection)
while (!sortedSelection.isEmpty())
selectDive(sortedSelection.takeLast());
- while (selected_dive == -1) {
+ while (!current_dive) {
// that can happen if we restored a selection after edit
// and the only selected dive is no longer visible because of a filter
newSelection--;
@@ -365,7 +380,7 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection)
selectDive(newSelection);
}
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
- QModelIndexList idxList = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, selected_dive, 2, Qt::MatchRecursive);
+ QModelIndexList idxList = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, get_divenr(current_dive), 2, Qt::MatchRecursive);
if (!idxList.isEmpty()) {
QModelIndex idx = idxList.first();
if (idx.parent().isValid())
@@ -441,7 +456,7 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
sortByColumn(sortColumn, currentOrder);
if (amount_selected && current_dive != NULL) {
- selectDive(selected_dive, true);
+ selectDive(get_divenr(current_dive), true);
} else {
QModelIndex firstDiveOrTrip = m->index(0, 0);
if (firstDiveOrTrip.isValid()) {
@@ -567,7 +582,7 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS
if (!dive) // it's a trip!
deselect_dives_in_trip((dive_trip_t *)model->data(index, DiveTripModel::TRIP_ROLE).value<void *>());
else
- deselect_dive(get_divenr(dive));
+ deselect_dive(dive);
}
Q_FOREACH (const QModelIndex &index, newSelected.indexes()) {
if (index.column() != 0)
@@ -586,7 +601,7 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS
expand(index);
}
} else {
- select_dive(get_divenr(dive));
+ select_dive(dive);
}
}
if (!dontEmitDiveChangedSignal)
@@ -889,7 +904,7 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
QAction *actionTaken = popup.exec(event->globalPos());
if (actionTaken == collapseAction && collapseAction) {
this->setAnimated(false);
- selectDive(selected_dive, true);
+ selectDive(get_divenr(current_dive), true);
scrollTo(selectedIndexes().first());
this->setAnimated(true);
}
diff --git a/desktop-widgets/divelistview.h b/desktop-widgets/divelistview.h
index 9e6857312..effde2ece 100644
--- a/desktop-widgets/divelistview.h
+++ b/desktop-widgets/divelistview.h
@@ -58,6 +58,7 @@ slots:
void shiftTimes();
void loadImages();
void loadWebImages();
+ void diveSelectionChanged(const QVector<QModelIndex> &indexes, bool select);
private:
bool mouseClickSelection;
QList<int> expandedRows;
diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp
index 5ec086195..72b4e4720 100644
--- a/desktop-widgets/mainwindow.cpp
+++ b/desktop-widgets/mainwindow.cpp
@@ -504,7 +504,7 @@ void MainWindow::recreateDiveList()
}
void MainWindow::configureToolbar() {
- if (selected_dive > 0) {
+ if (current_dive) {
bool freeDiveMode = current_dive->dc.divemode == FREEDIVE;
ui.profCalcCeiling->setDisabled(freeDiveMode);
ui.profCalcCeiling->setDisabled(freeDiveMode);
@@ -870,7 +870,7 @@ void MainWindow::refreshProfile()
{
showProfile();
configureToolbar();
- graphics()->replot(get_dive(selected_dive));
+ graphics()->replot(current_dive);
DivePictureModel::instance()->updateDivePictures();
}
@@ -889,8 +889,8 @@ void MainWindow::planCreated()
if (displayed_dive.id == 0) {
// we might have added a new dive (so displayed_dive was cleared out by clone_dive()
dive_list()->unselectDives();
- select_dive(dive_table.nr - 1);
- dive_list()->selectDive(selected_dive);
+ select_dive(get_dive(dive_table.nr - 1));
+ dive_list()->selectDive(get_divenr(current_dive)); // TODO: don't convert dive->idx and back
set_dive_nr_for_current_dive();
}
// make sure our UI is in a consistent state
diff --git a/desktop-widgets/tab-widgets/maintab.cpp b/desktop-widgets/tab-widgets/maintab.cpp
index 5f740b969..92e55784f 100644
--- a/desktop-widgets/tab-widgets/maintab.cpp
+++ b/desktop-widgets/tab-widgets/maintab.cpp
@@ -1058,11 +1058,11 @@ void MainTab::rejectChanges()
MainWindow::instance()->dive_list()->restoreSelection();
// now make sure that the correct dive is displayed
- if (selected_dive >= 0)
+ if (current_dive)
copy_dive(current_dive, &displayed_dive);
else
clear_dive(&displayed_dive);
- updateDiveInfo(selected_dive < 0);
+ updateDiveInfo(!current_dive);
for (auto widget : extraWidgets) {
widget->updateData();