From 7787bfbf9e39595d98c459e4af121f3174762c7d Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 24 Nov 2019 13:26:29 +0100 Subject: Selection: move commands/command_private.* to core/selection.* The file command_private.cpp had functions concerning selections only. To make these functions accessible from outside the undo machinery, turn it into a part of the core-library. Currently, only C++ functions are exported. We might think about also exporting a C interface. Signed-off-by: Berthold Stoeger --- commands/CMakeLists.txt | 2 - commands/command_divelist.cpp | 2 +- commands/command_divesite.cpp | 1 - commands/command_edit.cpp | 2 +- commands/command_edit_trip.cpp | 2 +- commands/command_private.cpp | 108 ----------------------------------------- commands/command_private.h | 25 ---------- core/CMakeLists.txt | 2 + core/selection.cpp | 106 ++++++++++++++++++++++++++++++++++++++++ core/selection.h | 24 +++++++++ 10 files changed, 135 insertions(+), 139 deletions(-) delete mode 100644 commands/command_private.cpp delete mode 100644 commands/command_private.h create mode 100644 core/selection.cpp create mode 100644 core/selection.h diff --git a/commands/CMakeLists.txt b/commands/CMakeLists.txt index 76ad42603..dcf7f3892 100644 --- a/commands/CMakeLists.txt +++ b/commands/CMakeLists.txt @@ -14,8 +14,6 @@ set(SUBSURFACE_GENERIC_COMMANDS_SRCS command_edit.h command_edit_trip.cpp command_edit_trip.h - command_private.cpp - command_private.h ) if (SUBSURFACE_TARGET_EXECUTABLE MATCHES "DesktopExecutable") add_library(subsurface_commands_desktop STATIC ${SUBSURFACE_GENERIC_COMMANDS_SRCS}) diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp index 4fabac9fc..12e1c9309 100644 --- a/commands/command_divelist.cpp +++ b/commands/command_divelist.cpp @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 #include "command_divelist.h" -#include "command_private.h" #include "core/divelist.h" #include "core/display.h" // for amount_selected #include "core/qthelper.h" +#include "core/selection.h" #include "core/subsurface-qt/DiveListNotifier.h" #include "qt-models/filtermodels.h" #include "../profile-widget/profilewidget2.h" diff --git a/commands/command_divesite.cpp b/commands/command_divesite.cpp index b5fb46f91..45d0abcaf 100644 --- a/commands/command_divesite.cpp +++ b/commands/command_divesite.cpp @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "command_divesite.h" -#include "command_private.h" #include "core/divesite.h" #include "core/subsurface-qt/DiveListNotifier.h" #include "core/qthelper.h" diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 7f4726a6b..5e02ed80e 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include "command_edit.h" -#include "command_private.h" #include "core/divelist.h" #include "core/qthelper.h" // for copy_qstring +#include "core/selection.h" #include "core/subsurface-string.h" #include "core/tag.h" diff --git a/commands/command_edit_trip.cpp b/commands/command_edit_trip.cpp index b25e3fcc5..c0f512907 100644 --- a/commands/command_edit_trip.cpp +++ b/commands/command_edit_trip.cpp @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 #include "command_edit_trip.h" -#include "command_private.h" #include "core/qthelper.h" +#include "core/selection.h" namespace Command { diff --git a/commands/command_private.cpp b/commands/command_private.cpp deleted file mode 100644 index 714ffd9b6..000000000 --- a/commands/command_private.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Helper functions for the undo-commands - -#include "command_private.h" -#include "core/divelist.h" -#include "core/display.h" // for amount_selected -#include "core/subsurface-qt/DiveListNotifier.h" - -namespace Command { - -// 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 &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); -} - -// 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. -void setSelection(const std::vector &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. - QVector divesToSelect; - divesToSelect.reserve(selection.size()); - - // 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(); - - if (newState) { - ++amount_selected; - divesToSelect.push_back(d); - } - // 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. - d->selected = newState; - } - - // We cannot simply change the current dive to the given dive. - // It might be hidden by a filter and thus not be selected. - current_dive = currentDive; - if (current_dive && !currentDive->selected) { - // Current not visible -> find a different dive. - setClosestCurrentDive(currentDive->when, selection); - } - - // Send the new selection - emit diveListNotifier.divesSelected(divesToSelect, current_dive); -} - -// Turn current selection into a vector. -// TODO: This could be made much more efficient if we kept a sorted list of selected dives! -std::vector getDiveSelection() -{ - std::vector res; - res.reserve(amount_selected); - - int i; - dive *d; - for_each_dive(i, d) { - if (d->selected) - res.push_back(d); - } - return res; -} - -} // namespace Command diff --git a/commands/command_private.h b/commands/command_private.h deleted file mode 100644 index 280654a93..000000000 --- a/commands/command_private.h +++ /dev/null @@ -1,25 +0,0 @@ -// 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 { - -// 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. -void setSelection(const std::vector &selection, dive *currentDive); - -// Get currently selectd dives -std::vector getDiveSelection(); - -} // namespace Command - -#endif // COMMAND_PRIVATE_H diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 0c8f88141..0622a859a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -139,6 +139,8 @@ set(SUBSURFACE_CORE_LIB_SRCS save-html.h save-profiledata.c save-xml.c + selection.cpp + selection.h sha1.c sha1.h ssrf.h diff --git a/core/selection.cpp b/core/selection.cpp new file mode 100644 index 000000000..ce0b0aa42 --- /dev/null +++ b/core/selection.cpp @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +// Helper functions for the undo-commands + +#include "selection.h" +#include "divelist.h" +#include "display.h" // for amount_selected +#include "subsurface-qt/DiveListNotifier.h" + +#include + +// 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 &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); +} + +// 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. +void setSelection(const std::vector &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. + QVector divesToSelect; + divesToSelect.reserve(selection.size()); + + // 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(); + + if (newState) { + ++amount_selected; + divesToSelect.push_back(d); + } + // 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. + d->selected = newState; + } + + // We cannot simply change the current dive to the given dive. + // It might be hidden by a filter and thus not be selected. + current_dive = currentDive; + if (current_dive && !currentDive->selected) { + // Current not visible -> find a different dive. + setClosestCurrentDive(currentDive->when, selection); + } + + // Send the new selection + emit diveListNotifier.divesSelected(divesToSelect, current_dive); +} + +// Turn current selection into a vector. +// TODO: This could be made much more efficient if we kept a sorted list of selected dives! +std::vector getDiveSelection() +{ + std::vector res; + res.reserve(amount_selected); + + int i; + dive *d; + for_each_dive(i, d) { + if (d->selected) + res.push_back(d); + } + return res; +} diff --git a/core/selection.h b/core/selection.h new file mode 100644 index 000000000..0fb226949 --- /dev/null +++ b/core/selection.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +// Selection related functions + +#ifndef SELECTION_H +#define SELECTION_H + +/*** C++-only functions ***/ + +#ifdef __cplusplus +#include + +struct dive; + +// 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). +void setSelection(const std::vector &selection, dive *currentDive); + +// Get currently selectd dives +std::vector getDiveSelection(); + +#endif // __cplusplus + +#endif // SELECTION_H -- cgit v1.2.3-70-g09d2