// SPDX-License-Identifier: GPL-2.0 // Private definitions for the command-objects #ifndef COMMAND_PRIVATE_H #define COMMAND_PRIVATE_H #include "core/dive.h" #include #include #include namespace Command { // Generally, signals are sent in batches per trip. To avoid writing the same loop // again and again, this template takes a vector of trip / dive pairs, sorts it // by trip and then calls a function-object with trip and a QVector of dives in that trip. // The dives are sorted by the dive_less_than() function defined in the core. // Input parameters: // - dives: a vector of trip,dive pairs, which will be sorted and processed in batches by trip. // - action: a function object, taking a trip-pointer and a QVector of dives, which will be called for each batch. template void processByTrip(std::vector> &dives, Function action) { // Use std::tie for lexicographical sorting of trip, then start-time std::sort(dives.begin(), dives.end(), [](const std::pair &e1, const std::pair &e2) { return e1.first == e2.first ? dive_less_than(e1.second, e2.second) : e1.first < e2.first; }); // Then, process the dives in batches by trip size_t i, j; // Begin and end of batch for (i = 0; i < dives.size(); i = j) { dive_trip *trip = dives[i].first; for (j = i + 1; j < dives.size() && dives[j].first == trip; ++j) ; // pass // Copy dives into a QVector. Some sort of "range_view" would be ideal, but Qt doesn't work this way. QVector divesInTrip(j - i); for (size_t k = i; k < j; ++k) divesInTrip[k - i] = dives[k].second; // Finally, emit the signal action(trip, divesInTrip); } } // The processByTrip() function above takes a vector if (trip, dive) pairs. // This overload takes a vector of dives. template void processByTrip(Vector &divesIn, Function action) { std::vector> dives; dives.reserve(divesIn.size()); for (dive *d: divesIn) dives.push_back({ d->divetrip, d }); processByTrip(dives, action); } // Reset 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). Return true if the selection or current dive changed. bool setSelection(const std::vector &selection, dive *currentDive); // Get currently selectd dives std::vector getDiveSelection(); } // namespace Command #endif // COMMAND_PRIVATE_H