diff options
Diffstat (limited to 'desktop-widgets')
-rw-r--r-- | desktop-widgets/command_divelist.cpp | 271 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.h | 86 | ||||
-rw-r--r-- | desktop-widgets/divelistview.cpp | 49 | ||||
-rw-r--r-- | desktop-widgets/divelistview.h | 1 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 8 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/maintab.cpp | 4 |
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(); |