From 531b6876f94a2e6284279efd4ce10c88f2bd92e3 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Wed, 5 Jan 2022 20:45:33 +0000 Subject: [PATCH] feat(departure): Combine pending prenotes and releases into one list (#386) * Create new list from releases list * Add type column * Add toggle * Bootstrap new toggles * Start prenotes mixin * Display Prenotes Properly * Fix bugs * Test updates * Docs * Remove old code * Style * Fix test * Fix another test * One last test fix * Fix created at time on release --- docs/UserGuide/Features/DepartureReleases.md | 4 +- docs/UserGuide/Features/PrenoteMessages.md | 4 +- src/plugin/CMakeLists.txt | 16 +- src/plugin/bootstrap/PersistenceContainer.h | 4 + .../departure/DepartureCoordinationList.cpp | 282 ++++++++++++++ .../DepartureCoordinationList.h} | 59 ++- src/plugin/departure/DepartureModule.cpp | 48 +++ src/plugin/departure/DepartureModule.h | 22 ++ .../ToggleDepartureCoordinationList.cpp | 27 ++ .../ToggleDepartureCoordinationList.h | 31 ++ src/plugin/prenote/PendingPrenoteList.cpp | 233 ----------- src/plugin/prenote/PendingPrenoteList.h | 122 ------ src/plugin/prenote/PrenoteMessage.cpp | 7 +- src/plugin/prenote/PrenoteMessage.h | 4 + src/plugin/prenote/PrenoteModule.cpp | 62 +-- src/plugin/prenote/PrenoteModule.h | 8 +- .../prenote/TogglePendingPrenoteList.cpp | 26 -- src/plugin/prenote/TogglePendingPrenoteList.h | 25 -- src/plugin/radarscreen/RadarScreenFactory.cpp | 6 +- .../releases/DepartureReleaseDecisionList.cpp | 209 ---------- .../releases/DepartureReleaseRequest.cpp | 267 ++++++------- src/plugin/releases/DepartureReleaseRequest.h | 163 ++++---- src/plugin/releases/ReleaseModule.cpp | 36 +- src/plugin/releases/ReleaseModule.h | 7 +- .../ToggleDepartureReleaseDecisionList.cpp | 33 -- .../ToggleDepartureReleaseDecisionList.h | 34 -- test/plugin/CMakeLists.txt | 16 +- .../DepartureCoordinationListTest.cpp | 216 ++++++++++ test/plugin/departure/DepartureModuleTest.cpp | 67 ++++ .../ToggleDepartureCoordinationListTest.cpp | 92 +++++ .../plugin/prenote/PendingPrenoteListTest.cpp | 204 ---------- test/plugin/prenote/PrenoteMessageTest.cpp | 5 + test/plugin/prenote/PrenoteModuleTest.cpp | 28 +- .../prenote/TogglePendingPrenoteListTest.cpp | 68 ---- .../DepartureReleaseDecisionListTest.cpp | 249 ------------ .../releases/DepartureReleaseRequestTest.cpp | 368 +++++++++--------- test/plugin/releases/ReleaseModuleTest.cpp | 22 +- ...ToggleDepartureReleaseDecisionListTest.cpp | 95 ----- 38 files changed, 1304 insertions(+), 1865 deletions(-) create mode 100644 src/plugin/departure/DepartureCoordinationList.cpp rename src/plugin/{releases/DepartureReleaseDecisionList.h => departure/DepartureCoordinationList.h} (61%) create mode 100644 src/plugin/departure/DepartureModule.cpp create mode 100644 src/plugin/departure/DepartureModule.h create mode 100644 src/plugin/departure/ToggleDepartureCoordinationList.cpp create mode 100644 src/plugin/departure/ToggleDepartureCoordinationList.h delete mode 100644 src/plugin/prenote/PendingPrenoteList.cpp delete mode 100644 src/plugin/prenote/PendingPrenoteList.h delete mode 100644 src/plugin/prenote/TogglePendingPrenoteList.cpp delete mode 100644 src/plugin/prenote/TogglePendingPrenoteList.h delete mode 100644 src/plugin/releases/DepartureReleaseDecisionList.cpp delete mode 100644 src/plugin/releases/ToggleDepartureReleaseDecisionList.cpp delete mode 100644 src/plugin/releases/ToggleDepartureReleaseDecisionList.h create mode 100644 test/plugin/departure/DepartureCoordinationListTest.cpp create mode 100644 test/plugin/departure/DepartureModuleTest.cpp create mode 100644 test/plugin/departure/ToggleDepartureCoordinationListTest.cpp delete mode 100644 test/plugin/prenote/PendingPrenoteListTest.cpp delete mode 100644 test/plugin/prenote/TogglePendingPrenoteListTest.cpp delete mode 100644 test/plugin/releases/DepartureReleaseDecisionListTest.cpp delete mode 100644 test/plugin/releases/ToggleDepartureReleaseDecisionListTest.cpp diff --git a/docs/UserGuide/Features/DepartureReleases.md b/docs/UserGuide/Features/DepartureReleases.md index 5b0e38171..43f7c00ca 100644 --- a/docs/UserGuide/Features/DepartureReleases.md +++ b/docs/UserGuide/Features/DepartureReleases.md @@ -53,8 +53,8 @@ In addition, there are two audible cues for when a release is accepted or reject ## How Do I Respond To A Release Request? -If you are the target of a release request, you can use the `Departure Release Decision List` to make decisions on individual -releases. This may be toggled on a per-ASR basis using the `OP` menu. +If you are the target of a release request, you can use the `Departure Coordination List` to make decisions on individual +releases. This may be toggled on a per-ASR basis using the `OP` menu. A release request will have `Rls` in the "Type" column. If there is a pending release request for you, the header bar of the list will flash *_Red_*. You will also receive an audible ping to let you know that something has come in. diff --git a/docs/UserGuide/Features/PrenoteMessages.md b/docs/UserGuide/Features/PrenoteMessages.md index 7306ae1d7..756526dcf 100644 --- a/docs/UserGuide/Features/PrenoteMessages.md +++ b/docs/UserGuide/Features/PrenoteMessages.md @@ -44,8 +44,8 @@ The controller callsign indicates the status of the prenote: There are two ways to respond to a prenote, if you are the target controller. -Firstly, you can use the `Pending Prenote List` to acknowledge the message. -This may be toggled on a per-ASR basis using the `OP` menu. +Firstly, you can use the `Departure Coordination List` to acknowledge the message. +This may be toggled on a per-ASR basis using the `OP` menu. A prenote will have `Pre` in the "Type" column. If there is a pending prenote for you, the header bar of the list will flash *_Red_*. You will also receive an audible ping to let you know that something has come in. diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt index a6554a9ed..6b89641b0 100644 --- a/src/plugin/CMakeLists.txt +++ b/src/plugin/CMakeLists.txt @@ -126,6 +126,10 @@ set(src__datablock ) source_group("src\\datablock" FILES ${src__datablock}) +set(src__departure + departure/DepartureCoordinationList.cpp departure/DepartureCoordinationList.h departure/ToggleDepartureCoordinationList.cpp departure/ToggleDepartureCoordinationList.h departure/DepartureModule.cpp departure/DepartureModule.h) +source_group("src\\departure" FILES ${src__departure}) + set(src__dependency "dependency/DependencyLoader.cpp" "dependency/DependencyLoader.h" @@ -636,8 +640,6 @@ set(src__prenote prenote/PrenoteMessageStatusView.cpp prenote/PrenoteMessageStatusView.h prenote/TriggerPrenoteMessageStatusView.cpp prenote/TriggerPrenoteMessageStatusView.h prenote/AcknowledgePrenoteMessage.cpp prenote/AcknowledgePrenoteMessage.h - prenote/PendingPrenoteList.cpp prenote/PendingPrenoteList.h - prenote/TogglePendingPrenoteList.cpp prenote/TogglePendingPrenoteList.h prenote/PublishedPrenote.h prenote/PublishedPrenote.cpp prenote/PublishedPrenoteCollection.cpp prenote/PublishedPrenoteCollection.h prenote/PublishedPrenoteCollectionFactory.cpp prenote/PublishedPrenoteCollectionFactory.h @@ -719,8 +721,6 @@ set(src__releases "releases/DepartureReleaseColours.h" "releases/DepartureReleaseCountdownColours.cpp" "releases/DepartureReleaseCountdownColours.h" - "releases/DepartureReleaseDecisionList.cpp" - "releases/DepartureReleaseDecisionList.h" "releases/DepartureReleaseEventHandler.cpp" "releases/DepartureReleaseEventHandler.h" "releases/DepartureReleaseRequest.cpp" @@ -737,9 +737,10 @@ set(src__releases "releases/ReleaseModule.h" "releases/RequestDepartureReleaseDialog.cpp" "releases/RequestDepartureReleaseDialog.h" - "releases/ToggleDepartureReleaseDecisionList.cpp" - "releases/ToggleDepartureReleaseDecisionList.h" - releases/EnrouteRelease.cpp releases/EnrouteReleaseType.cpp releases/RejectDepartureReleaseDialog.cpp releases/RejectDepartureReleaseDialog.h releases/ReleaseApprovalRemarksUserMessage.cpp releases/ReleaseApprovalRemarksUserMessage.h releases/ReleaseRejectionRemarksUserMessage.cpp releases/ReleaseRejectionRemarksUserMessage.h) + releases/EnrouteRelease.cpp releases/EnrouteReleaseType.cpp + releases/RejectDepartureReleaseDialog.cpp releases/RejectDepartureReleaseDialog.h + releases/ReleaseApprovalRemarksUserMessage.cpp releases/ReleaseApprovalRemarksUserMessage.h + releases/ReleaseRejectionRemarksUserMessage.cpp releases/ReleaseRejectionRemarksUserMessage.h) source_group("src\\releases" FILES ${src__releases}) set(src__sectorfile @@ -870,6 +871,7 @@ set(ALL_FILES ${src__controller} ${src__countdown} ${src__datablock} + ${src__departure} ${src__dependency} ${src__euroscope} ${src__flightinformationservice} diff --git a/src/plugin/bootstrap/PersistenceContainer.h b/src/plugin/bootstrap/PersistenceContainer.h index 13216b630..0fc3ccfd7 100644 --- a/src/plugin/bootstrap/PersistenceContainer.h +++ b/src/plugin/bootstrap/PersistenceContainer.h @@ -88,6 +88,9 @@ namespace UKControllerPlugin { namespace Plugin { class FunctionCallEventHandler; } // namespace Plugin + namespace Prenote { + class PrenoteMessageCollection; + } // namespace Prenote namespace Push { class PushEventProcessorCollection; } // namespace Push @@ -161,6 +164,7 @@ namespace UKControllerPlugin::Bootstrap { std::unique_ptr dialogManager; std::unique_ptr settingsRepository; std::shared_ptr timeFormatting; + std::shared_ptr prenotes; // Collections of event handlers std::unique_ptr flightplanHandler; diff --git a/src/plugin/departure/DepartureCoordinationList.cpp b/src/plugin/departure/DepartureCoordinationList.cpp new file mode 100644 index 000000000..b47686e7a --- /dev/null +++ b/src/plugin/departure/DepartureCoordinationList.cpp @@ -0,0 +1,282 @@ +#include "DepartureCoordinationList.h" +#include "components/BrushSwitcher.h" +#include "components/Button.h" +#include "components/ClickableArea.h" +#include "components/StandardButtons.h" +#include "components/TitleBar.h" +#include "controller/ActiveCallsignCollection.h" +#include "controller/ControllerPosition.h" +#include "controller/ControllerPositionCollection.h" +#include "euroscope/EuroScopeCFlightPlanInterface.h" +#include "euroscope/EuroscopePluginLoopbackInterface.h" +#include "euroscope/EuroscopeRadarLoopbackInterface.h" +#include "euroscope/UserSetting.h" +#include "graphics/GdiGraphicsInterface.h" +#include "helper/HelperFunctions.h" +#include "prenote/PrenoteMessage.h" +#include "prenote/PrenoteMessageCollection.h" +#include "releases/DepartureReleaseEventHandler.h" +#include "releases/DepartureReleaseRequest.h" +#include "tag/TagData.h" + +namespace UKControllerPlugin::Departure { + + DepartureCoordinationList::DepartureCoordinationList( + Releases::DepartureReleaseEventHandler& handler, + Prenote::PrenoteMessageCollection& prenotes, + Euroscope::EuroscopePluginLoopbackInterface& plugin, + const Controller::ControllerPositionCollection& controllers, + const Controller::ActiveCallsignCollection& activeCallsigns, + const int screenObjectId) + : controllers(controllers), handler(handler), prenotes(prenotes), plugin(plugin), + activeCallsigns(activeCallsigns), textBrush(OFF_WHITE_COLOUR), screenObjectId(screenObjectId), visible(false), + contentCollapsed(false) + { + this->brushSwitcher = Components::BrushSwitcher::Create( + std::make_shared(TITLE_BAR_BASE_COLOUR), std::chrono::seconds(2)) + ->AdditionalBrush(std::make_shared(TITLE_BAR_FLASH_COLOUR)); + + this->titleBar = Components::TitleBar::Create( + L"Departure Coordination Requests", {0, 0, this->titleBarWidth, this->titleBarHeight}) + ->WithDrag(this->screenObjectId) + ->WithBorder(std::make_shared(OFF_WHITE_COLOUR)) + ->WithBackgroundBrush(std::make_shared(TITLE_BAR_BASE_COLOUR)) + ->WithTextBrush(std::make_shared(OFF_WHITE_COLOUR)); + + this->closeButton = Components::Button::Create( + closeButtonOffset, this->screenObjectId, "closeButton", Components::CloseButton()); + + this->collapseButton = Components::Button::Create( + collapseButtonOffset, this->screenObjectId, "collapseButton", Components::CollapseButton([this]() -> bool { + return this->contentCollapsed; + })); + } + + void DepartureCoordinationList::LeftClick( + Euroscope::EuroscopeRadarLoopbackInterface& radarScreen, + int objectId, + const std::string& objectDescription, + POINT mousePos, + RECT itemArea) + { + if (objectDescription == "collapseButton") { + this->contentCollapsed = !this->contentCollapsed; + return; + } + + if (objectDescription == "closeButton") { + this->visible = false; + return; + } + + const std::string callsign = objectDescription.substr(4); + objectDescription.substr(0, 3) == "Rls" + ? radarScreen.TogglePluginTagFunction( + callsign, DEPARTURE_RELEASE_DECISION_TAG_FUNCTION_ID, mousePos, itemArea) + : radarScreen.TogglePluginTagFunction(callsign, ACKNOWLEDGE_PRENOTE_TAG_FUNCTION_ID, mousePos, itemArea); + } + + auto DepartureCoordinationList::IsVisible() const -> bool + { + return this->visible; + } + + void DepartureCoordinationList::Move(RECT position, std::string objectDescription) + { + this->position = {static_cast(position.left), static_cast(position.top)}; + } + + void DepartureCoordinationList::Render( + Windows::GdiGraphicsInterface& graphics, Euroscope::EuroscopeRadarLoopbackInterface& radarScreen) + { + auto decisions = this->handler.GetReleasesRequiringUsersDecision(); + auto userControllerId = this->activeCallsigns.UserHasCallsign() + ? this->activeCallsigns.GetUserCallsign().GetNormalisedPosition().GetId() + : -1; + + std::vector> prenoteMessages; + if (userControllerId != -1) { + this->prenotes.Iterate( + [&prenoteMessages, &userControllerId](const std::shared_ptr& message) { + if (message->GetTargetControllerId() == userControllerId && !message->IsAcknowledged()) { + prenoteMessages.push_back(message); + } + }); + } + + if (decisions.empty() && prenoteMessages.empty()) { + this->titleBar->WithBackgroundBrush(this->brushSwitcher->Base()); + } else { + this->titleBar->WithBackgroundBrush(this->brushSwitcher->Next()); + } + + // Translate to content position + graphics.Translated( + this->position.X, + this->position.Y + static_cast(this->titleBarHeight), + [this, &graphics, &radarScreen, &decisions, &prenoteMessages] { + if (this->contentCollapsed) { + return; + } + + // Draw column headers + graphics.DrawString(L"Type", this->typeColumnHeader, this->textBrush); + graphics.DrawString(L"Callsign", this->callsignColumnHeader, this->textBrush); + graphics.DrawString(L"Controller", this->controllerColumnHeader, this->textBrush); + graphics.DrawString(L"Dept", this->airportColumnHeader, this->textBrush); + graphics.DrawString(L"SID", this->sidColumnHeader, this->textBrush); + graphics.DrawString(L"Dest", this->destColumnHeader, this->textBrush); + + // Draw each aircraft that we care about + Gdiplus::Rect typeColumn = this->typeColumnHeader; + Gdiplus::Rect callsignColumn = this->callsignColumnHeader; + Gdiplus::Rect controllerColumn = this->controllerColumnHeader; + Gdiplus::Rect airportColumn = this->airportColumnHeader; + Gdiplus::Rect sidColumn = this->sidColumnHeader; + Gdiplus::Rect destColumn = this->destColumnHeader; + + auto nextRelease = decisions.cbegin(); + auto nextPrenote = prenoteMessages.cbegin(); + std::variant< + std::shared_ptr, + std::shared_ptr> + listItem; + + do { + // Out of things to draw + if (nextRelease == decisions.cend() && nextPrenote == prenoteMessages.cend()) { + break; + } + + // Chose the next item in the list - this is, broadly, ordered by created at time + if (nextRelease == decisions.cend()) { + listItem = std::variant< + std::shared_ptr, + std::shared_ptr>(*nextPrenote++); + } else if (nextPrenote == prenoteMessages.cend()) { + listItem = std::variant< + std::shared_ptr, + std::shared_ptr>(*nextRelease++); + } else if ((*nextPrenote)->GetCreatedAt() < (*nextRelease)->CreatedAt()) { + listItem = std::variant< + std::shared_ptr, + std::shared_ptr>(*nextPrenote++); + } else { + listItem = std::variant< + std::shared_ptr, + std::shared_ptr>(*nextRelease++); + } + + // Shift the cols + typeColumn.Y += lineHeight; + callsignColumn.Y += lineHeight; + controllerColumn.Y += lineHeight; + airportColumn.Y += lineHeight; + sidColumn.Y += lineHeight; + destColumn.Y += lineHeight; + + // Type column + const std::string itemType = listItem.index() == 0 ? "Rls" : "Pre"; + graphics.DrawString(HelperFunctions::ConvertToWideString(itemType), typeColumn, this->textBrush); + + // Callsign column + const std::string callsign = + listItem.index() == 0 + ? std::get>(listItem)->Callsign() + : std::get>(listItem)->GetCallsign(); + graphics.DrawString( + HelperFunctions::ConvertToWideString(callsign), callsignColumn, this->textBrush); + std::shared_ptr callsignClickspot = Components::ClickableArea::Create( + callsignColumn, this->screenObjectId, itemType + "." + callsign, false); + callsignClickspot->Apply(graphics, radarScreen); + + // Controller column + const int controllerId = + listItem.index() == 0 + ? std::get>(listItem) + ->RequestingController() + : std::get>(listItem)->GetSendingControllerId(); + const std::wstring controller = HelperFunctions::ConvertToWideString( + this->controllers.FetchPositionById(controllerId)->GetCallsign()); + graphics.DrawString(controller, controllerColumn, this->textBrush); + + auto fp = this->plugin.GetFlightplanForCallsign(callsign); + if (!fp) { + continue; + } + + // Remaining FP-driven columns + graphics.DrawString( + HelperFunctions::ConvertToWideString(fp->GetOrigin()), airportColumn, this->textBrush); + + graphics.DrawString( + HelperFunctions::ConvertToWideString(fp->GetSidName()), sidColumn, this->textBrush); + + graphics.DrawString( + HelperFunctions::ConvertToWideString(fp->GetDestination()), destColumn, this->textBrush); + } while (nextRelease != decisions.cend() || nextPrenote != prenoteMessages.cend()); + }); + + // Translate to window position + graphics.Translated(this->position.X, this->position.Y, [this, &graphics, &radarScreen] { + this->titleBar->Draw(graphics, radarScreen); + this->closeButton->Draw(graphics, radarScreen); + this->collapseButton->Draw(graphics, radarScreen); + }); + } + + void DepartureCoordinationList::ResetPosition() + { + this->Move(defaultRect, ""); + } + + void DepartureCoordinationList::AsrLoadedEvent(Euroscope::UserSetting& userSetting) + { + this->visible = userSetting.GetBooleanEntry(GetAsrKey("Visible"), false); + + this->contentCollapsed = userSetting.GetBooleanEntry(GetAsrKey("ContentCollapsed"), false); + + this->Move( + {userSetting.GetIntegerEntry(GetAsrKey("XPosition"), defaultPosition), + userSetting.GetIntegerEntry(GetAsrKey("YPosition"), defaultPosition), + 0, + 0}, + ""); + } + + void DepartureCoordinationList::AsrClosingEvent(Euroscope::UserSetting& userSetting) + { + userSetting.Save(GetAsrKey("Visible"), GetAsrDescription("Visible"), this->visible); + + userSetting.Save(GetAsrKey("ContentCollapsed"), GetAsrDescription("Content Collapsed"), this->contentCollapsed); + + userSetting.Save(GetAsrKey("XPosition"), GetAsrDescription("X Position"), static_cast(this->position.X)); + + userSetting.Save(GetAsrKey("YPosition"), GetAsrDescription("Y Position"), static_cast(this->position.Y)); + } + + void DepartureCoordinationList::ToggleVisible() + { + this->visible = !this->visible; + } + + auto DepartureCoordinationList::ContentCollapsed() const -> bool + { + return this->contentCollapsed; + } + + auto DepartureCoordinationList::Position() const -> Gdiplus::PointF + { + return this->position; + } + + auto DepartureCoordinationList::GetAsrKey(const std::string& item) -> std::string + { + return "departureCoordinationList" + item; + } + + auto DepartureCoordinationList::GetAsrDescription(const std::string& description) -> std::string + { + return "Departure Coordination List " + description; + } +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/releases/DepartureReleaseDecisionList.h b/src/plugin/departure/DepartureCoordinationList.h similarity index 61% rename from src/plugin/releases/DepartureReleaseDecisionList.h rename to src/plugin/departure/DepartureCoordinationList.h index 079514571..c8d8587b1 100644 --- a/src/plugin/releases/DepartureReleaseDecisionList.h +++ b/src/plugin/departure/DepartureCoordinationList.h @@ -4,36 +4,43 @@ namespace UKControllerPlugin { namespace Controller { + class ActiveCallsignCollection; class ControllerPositionCollection; } // namespace Controller - namespace Components { class BrushSwitcher; class TitleBar; class Button; } // namespace Components - namespace Euroscope { class EuroscopePluginLoopbackInterface; } // namespace Euroscope + namespace Prenote { + class PrenoteMessage; + class PrenoteMessageCollection; + } // namespace Prenote + namespace Releases { + class DepartureReleaseRequest; + class DepartureReleaseEventHandler; + } // namespace Releases } // namespace UKControllerPlugin -namespace UKControllerPlugin::Releases { - class DepartureReleaseRequest; - class DepartureReleaseEventHandler; +namespace UKControllerPlugin::Departure { /* - * Renders a list of departure releases requiring the users - * decision. + * Renders a list of departure releases and prenotes requiring the users + * attention. */ - class DepartureReleaseDecisionList : public RadarScreen::RadarRenderableInterface, - public Euroscope::AsrEventHandlerInterface + class DepartureCoordinationList : public RadarScreen::RadarRenderableInterface, + public Euroscope::AsrEventHandlerInterface { public: - DepartureReleaseDecisionList( - DepartureReleaseEventHandler& handler, + DepartureCoordinationList( + Releases::DepartureReleaseEventHandler& handler, + Prenote::PrenoteMessageCollection& prenotes, Euroscope::EuroscopePluginLoopbackInterface& plugin, const Controller::ControllerPositionCollection& controllers, + const Controller::ActiveCallsignCollection& activeCallsigns, int screenObjectId); void LeftClick( Euroscope::EuroscopeRadarLoopbackInterface& radarScreen, @@ -60,16 +67,24 @@ namespace UKControllerPlugin::Releases { const Controller::ControllerPositionCollection& controllers; // Handles events for departure releases - DepartureReleaseEventHandler& handler; + Releases::DepartureReleaseEventHandler& handler; + + // Contains all the prenote messages + Prenote::PrenoteMessageCollection& prenotes; // Provides interface with the plugin Euroscope::EuroscopePluginLoopbackInterface& plugin; + + // Who's actively online + const Controller::ActiveCallsignCollection& activeCallsigns; // Drawing RECTs - const Gdiplus::Rect callsignColumnHeader{5, 5, 100, 25}; - const Gdiplus::Rect controllerColumnHeader{115, 5, 100, 25}; - const Gdiplus::Rect airportColumnHeader{225, 5, 40, 25}; - const Gdiplus::Rect sidColumnHeader{275, 5, 65, 25}; + const Gdiplus::Rect typeColumnHeader{5, 5, 40, 25}; + const Gdiplus::Rect callsignColumnHeader{50, 5, 100, 25}; + const Gdiplus::Rect controllerColumnHeader{160, 5, 100, 25}; + const Gdiplus::Rect airportColumnHeader{270, 5, 40, 25}; + const Gdiplus::Rect sidColumnHeader{320, 5, 65, 25}; + const Gdiplus::Rect destColumnHeader{395, 5, 40, 25}; // Some colours const Gdiplus::Color OFF_WHITE_COLOUR = Gdiplus::Color(255, 255, 255); @@ -92,15 +107,15 @@ namespace UKControllerPlugin::Releases { const int titleBarHeight = 20; // Width of title bar - const int titleBarWidth = 340; + const int titleBarWidth = 435; // Default X/Y of window static const int defaultPosition = 100; // Default RECT on reset position inline static const RECT defaultRect = {100, 100, 200, 200}; - const Gdiplus::Rect closeButtonOffset = {325, 5, 10, 10}; - const Gdiplus::Rect collapseButtonOffset = {310, 5, 10, 10}; + const Gdiplus::Rect closeButtonOffset = {415, 5, 10, 10}; + const Gdiplus::Rect collapseButtonOffset = {400, 5, 10, 10}; // How high each line is static const int lineHeight = 25; @@ -113,5 +128,9 @@ namespace UKControllerPlugin::Releases { std::shared_ptr closeButton; std::shared_ptr collapseButton; std::shared_ptr brushSwitcher; + + // Some TAG function ids + inline static const int DEPARTURE_RELEASE_DECISION_TAG_FUNCTION_ID = 9013; + inline static const int ACKNOWLEDGE_PRENOTE_TAG_FUNCTION_ID = 9019; }; -} // namespace UKControllerPlugin::Releases +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/departure/DepartureModule.cpp b/src/plugin/departure/DepartureModule.cpp new file mode 100644 index 000000000..18af5e4e2 --- /dev/null +++ b/src/plugin/departure/DepartureModule.cpp @@ -0,0 +1,48 @@ +#include "DepartureModule.h" +#include "DepartureCoordinationList.h" +#include "ToggleDepartureCoordinationList.h" +#include "bootstrap/PersistenceContainer.h" +#include "euroscope/AsrEventHandlerCollection.h" +#include "euroscope/CallbackFunction.h" +#include "plugin/FunctionCallEventHandler.h" +#include "plugin/UKPlugin.h" +#include "radarscreen/ConfigurableDisplayCollection.h" +#include "radarscreen/RadarRenderableCollection.h" + +using UKControllerPlugin::Euroscope::CallbackFunction; + +namespace UKControllerPlugin::Departure { + void BootstrapRadarScreen( + const Bootstrap::PersistenceContainer& container, + RadarScreen::RadarRenderableCollection& renderables, + RadarScreen::ConfigurableDisplayCollection& configurables, + Euroscope::AsrEventHandlerCollection& asrHandlers) + { + // Coordination list + const int coordinationListRendererId = renderables.ReserveRendererIdentifier(); + auto coordinationList = std::make_shared( + *container.departureReleaseHandler, + *container.prenotes, + *container.plugin, + *container.controllerPositions, + *container.activeCallsigns, + renderables.ReserveScreenObjectIdentifier(coordinationListRendererId)); + + renderables.RegisterRenderer(coordinationListRendererId, coordinationList, renderables.afterLists); + asrHandlers.RegisterHandler(coordinationList); + + // Create the configuration list item + const int requestListShowCallbackId = container.pluginFunctionHandlers->ReserveNextDynamicFunctionId(); + auto listItem = std::make_shared(coordinationList, requestListShowCallbackId); + + CallbackFunction showReleaseRequestListCallback( + requestListShowCallbackId, + "Toggle Departure Coordination List", + [listItem](int functionId, std::string subject, RECT screenObjectArea) { + listItem->Configure(functionId, std::move(subject), screenObjectArea); + }); + + container.pluginFunctionHandlers->RegisterFunctionCall(showReleaseRequestListCallback); + configurables.RegisterDisplay(listItem); + } +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/departure/DepartureModule.h b/src/plugin/departure/DepartureModule.h new file mode 100644 index 000000000..b08f82be3 --- /dev/null +++ b/src/plugin/departure/DepartureModule.h @@ -0,0 +1,22 @@ +#pragma once + +namespace UKControllerPlugin { + namespace Bootstrap { + struct PersistenceContainer; + } // namespace Bootstrap + namespace Euroscope { + class AsrEventHandlerCollection; + } // namespace Euroscope + namespace RadarScreen { + class ConfigurableDisplayCollection; + class RadarRenderableCollection; + } // namespace RadarScreen +} // namespace UKControllerPlugin + +namespace UKControllerPlugin::Departure { + void BootstrapRadarScreen( + const Bootstrap::PersistenceContainer& container, + RadarScreen::RadarRenderableCollection& renderables, + RadarScreen::ConfigurableDisplayCollection& configurables, + Euroscope::AsrEventHandlerCollection& asrHandlers); +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/departure/ToggleDepartureCoordinationList.cpp b/src/plugin/departure/ToggleDepartureCoordinationList.cpp new file mode 100644 index 000000000..8002840c1 --- /dev/null +++ b/src/plugin/departure/ToggleDepartureCoordinationList.cpp @@ -0,0 +1,27 @@ +#include "DepartureCoordinationList.h" +#include "ToggleDepartureCoordinationList.h" + +namespace UKControllerPlugin::Departure { + + ToggleDepartureCoordinationList::ToggleDepartureCoordinationList( + std::shared_ptr list, int callbackId) + : list(list), callbackId(callbackId) + { + } + + void ToggleDepartureCoordinationList::Configure(int functionId, std::string subject, RECT screenObjectArea) + { + this->list->ToggleVisible(); + } + + auto ToggleDepartureCoordinationList::GetConfigurationMenuItem() const -> Plugin::PopupMenuItem + { + return { + "Toggle Departure Coordination List", + "", + this->callbackId, + this->list->IsVisible() ? EuroScopePlugIn::POPUP_ELEMENT_CHECKED : EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, + false, + false}; + } +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/departure/ToggleDepartureCoordinationList.h b/src/plugin/departure/ToggleDepartureCoordinationList.h new file mode 100644 index 000000000..e3dc893a4 --- /dev/null +++ b/src/plugin/departure/ToggleDepartureCoordinationList.h @@ -0,0 +1,31 @@ +#pragma once +#include "radarscreen/ConfigurableDisplayInterface.h" + +namespace UKControllerPlugin { + namespace Euroscope { + class EuroscopeFlightplanListInterface; + } // namespace Euroscope +} // namespace UKControllerPlugin + +namespace UKControllerPlugin::Departure { + class DepartureCoordinationList; + + /* + * A class for the configuration menu that toggles + * the departure coordination request list. + */ + class ToggleDepartureCoordinationList : public RadarScreen::ConfigurableDisplayInterface + { + public: + ToggleDepartureCoordinationList(std::shared_ptr list, int callbackId); + void Configure(int functionId, std::string subject, RECT screenObjectArea) override; + Plugin::PopupMenuItem GetConfigurationMenuItem() const override; + + private: + // The list + std::shared_ptr list; + + // Callback for the list + const int callbackId; + }; +} // namespace UKControllerPlugin::Departure diff --git a/src/plugin/prenote/PendingPrenoteList.cpp b/src/plugin/prenote/PendingPrenoteList.cpp deleted file mode 100644 index be1d42c4d..000000000 --- a/src/plugin/prenote/PendingPrenoteList.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "AcknowledgePrenoteMessage.h" -#include "ComparePrenoteMessages.h" -#include "PendingPrenoteList.h" -#include "PrenoteMessage.h" -#include "PrenoteMessageCollection.h" -#include "euroscope/EuroScopeCFlightPlanInterface.h" -#include "euroscope/EuroscopePluginLoopbackInterface.h" -#include "euroscope/EuroscopeRadarLoopbackInterface.h" -#include "euroscope/UserSetting.h" -#include "graphics/GdiGraphicsInterface.h" -#include "helper/HelperFunctions.h" -#include "components/TitleBar.h" -#include "components/Button.h" -#include "components/StandardButtons.h" -#include "components/ClickableArea.h" -#include "components/BrushSwitcher.h" -#include "controller/ControllerPosition.h" -#include "controller/ControllerPositionCollection.h" -#include "controller/ActiveCallsignCollection.h" - -namespace UKControllerPlugin::Prenote { - - PendingPrenoteList::PendingPrenoteList( - std::shared_ptr messages, - std::shared_ptr acknowledger, - Euroscope::EuroscopePluginLoopbackInterface& plugin, - const Controller::ControllerPositionCollection& controllers, - const Controller::ActiveCallsignCollection& activeCallsigns, - const int screenObjectId) - : controllers(controllers), messages(std::move(messages)), acknowledger(std::move(acknowledger)), - plugin(plugin), activeCallsigns(activeCallsigns), textBrush(OFF_WHITE_COLOUR), screenObjectId(screenObjectId), - visible(false), contentCollapsed(false) - { - this->brushSwitcher = Components::BrushSwitcher::Create( - std::make_shared(TITLE_BAR_BASE_COLOUR), std::chrono::seconds(2)) - ->AdditionalBrush(std::make_shared(TITLE_BAR_FLASH_COLOUR)); - - this->titleBar = - Components::TitleBar::Create(L"Pending Prenotes", {0, 0, this->titleBarWidth, this->titleBarHeight}) - ->WithDrag(this->screenObjectId) - ->WithBorder(std::make_shared(OFF_WHITE_COLOUR)) - ->WithBackgroundBrush(std::make_shared(TITLE_BAR_BASE_COLOUR)) - ->WithTextBrush(std::make_shared(OFF_WHITE_COLOUR)); - - this->closeButton = Components::Button::Create( - CLOSE_BUTTON_OFFSET, this->screenObjectId, "closeButton", Components::CloseButton()); - - this->collapseButton = Components::Button::Create( - COLLAPSE_BUTTON_OFFSET, - this->screenObjectId, - "collapseButton", - Components::CollapseButton([this]() -> bool { return this->contentCollapsed; })); - } - - void PendingPrenoteList::LeftClick( - Euroscope::EuroscopeRadarLoopbackInterface& radarScreen, - int objectId, - const std::string& objectDescription, - POINT mousePos, - RECT itemArea) - { - if (objectDescription == "collapseButton") { - this->contentCollapsed = !this->contentCollapsed; - return; - } - - if (objectDescription == "closeButton") { - this->visible = false; - return; - } - - auto fp = this->plugin.GetFlightplanForCallsign(objectDescription); - if (!fp) { - return; - } - - this->acknowledger->Acknowledge(*fp); - } - - auto PendingPrenoteList::IsVisible() const -> bool - { - return this->visible; - } - - void PendingPrenoteList::Move(RECT position, std::string objectDescription) - { - this->position = {static_cast(position.left), static_cast(position.top)}; - } - - void PendingPrenoteList::Render( - Windows::GdiGraphicsInterface& graphics, Euroscope::EuroscopeRadarLoopbackInterface& radarScreen) - { - auto userControllerId = this->activeCallsigns.UserHasCallsign() - ? this->activeCallsigns.GetUserCallsign().GetNormalisedPosition().GetId() - : -1; - - std::set, ComparePrenoteMessages> prenotes; - if (userControllerId != -1) { - this->messages->Iterate([&prenotes, &userControllerId](const std::shared_ptr& message) { - if (message->GetTargetControllerId() == userControllerId && !message->IsAcknowledged()) { - prenotes.insert(message); - } - }); - } - - if (prenotes.empty()) { - this->titleBar->WithBackgroundBrush(this->brushSwitcher->Base()); - } else { - this->titleBar->WithBackgroundBrush(this->brushSwitcher->Next()); - } - - // Translate to content position - graphics.Translated( - this->position.X, - this->position.Y + static_cast(this->titleBarHeight), - [this, &graphics, &radarScreen, &prenotes] { - if (this->contentCollapsed) { - return; - } - - // Draw column headers - graphics.DrawString(L"Callsign", this->callsignColumnHeader, this->textBrush); - graphics.DrawString(L"Controller", this->controllerColumnHeader, this->textBrush); - graphics.DrawString(L"Dept", this->airportColumnHeader, this->textBrush); - graphics.DrawString(L"SID", this->sidColumnHeader, this->textBrush); - graphics.DrawString(L"Dest", this->destColumnHeader, this->textBrush); - - // Draw each aircraft that we care about - Gdiplus::Rect callsignColumn = this->callsignColumnHeader; - Gdiplus::Rect controllerColumn = this->controllerColumnHeader; - Gdiplus::Rect airportColumn = this->airportColumnHeader; - Gdiplus::Rect sidColumn = this->sidColumnHeader; - Gdiplus::Rect destColumn = this->destColumnHeader; - - // Draw each decision - for (const auto& prenote : prenotes) { - // Shift the cols - callsignColumn.Y += LINE_HEIGHT; - controllerColumn.Y += LINE_HEIGHT; - airportColumn.Y += LINE_HEIGHT; - sidColumn.Y += LINE_HEIGHT; - destColumn.Y += LINE_HEIGHT; - - graphics.DrawString( - HelperFunctions::ConvertToWideString(prenote->GetCallsign()), callsignColumn, this->textBrush); - - std::shared_ptr callsignClickspot = Components::ClickableArea::Create( - callsignColumn, this->screenObjectId, prenote->GetCallsign(), false); - callsignClickspot->Apply(graphics, radarScreen); - - const std::wstring controller = HelperFunctions::ConvertToWideString( - this->controllers.FetchPositionById(prenote->GetSendingControllerId())->GetCallsign()); - graphics.DrawString(controller, controllerColumn, this->textBrush); - - auto fp = this->plugin.GetFlightplanForCallsign(prenote->GetCallsign()); - if (!fp) { - continue; - } - - graphics.DrawString( - HelperFunctions::ConvertToWideString(fp->GetOrigin()), airportColumn, this->textBrush); - - graphics.DrawString( - HelperFunctions::ConvertToWideString(fp->GetSidName()), sidColumn, this->textBrush); - - graphics.DrawString( - HelperFunctions::ConvertToWideString(fp->GetDestination()), destColumn, this->textBrush); - } - }); - - // Translate to window position - graphics.Translated(this->position.X, this->position.Y, [this, &graphics, &radarScreen] { - this->titleBar->Draw(graphics, radarScreen); - this->closeButton->Draw(graphics, radarScreen); - this->collapseButton->Draw(graphics, radarScreen); - }); - } - - void PendingPrenoteList::ResetPosition() - { - this->Move(DEFAULT_POSITION, ""); - } - - void PendingPrenoteList::AsrLoadedEvent(Euroscope::UserSetting& userSetting) - { - this->visible = userSetting.GetBooleanEntry(GetAsrKey("Visible"), false); - - this->contentCollapsed = userSetting.GetBooleanEntry(GetAsrKey("ContentCollapsed"), false); - - this->Move( - {userSetting.GetIntegerEntry(GetAsrKey("XPosition"), DEFAULT_POSITION.left), - userSetting.GetIntegerEntry(GetAsrKey("YPosition"), DEFAULT_POSITION.top), - 0, - 0}, - ""); - } - - void PendingPrenoteList::AsrClosingEvent(Euroscope::UserSetting& userSetting) - { - userSetting.Save(GetAsrKey("Visible"), GetAsrDescription("Visible"), this->visible); - - userSetting.Save(GetAsrKey("ContentCollapsed"), GetAsrDescription("Content Collapsed"), this->contentCollapsed); - - userSetting.Save(GetAsrKey("XPosition"), GetAsrDescription("X Position"), static_cast(this->position.X)); - - userSetting.Save(GetAsrKey("YPosition"), GetAsrDescription("Y Position"), static_cast(this->position.Y)); - } - - void PendingPrenoteList::ToggleVisible() - { - this->visible = !this->visible; - } - - auto PendingPrenoteList::ContentCollapsed() const -> bool - { - return this->contentCollapsed; - } - - auto PendingPrenoteList::Position() const -> Gdiplus::PointF - { - return this->position; - } - - auto PendingPrenoteList::GetAsrKey(const std::string& item) -> std::string - { - return "pendingPrenoteMessageList" + item; - } - - auto PendingPrenoteList::GetAsrDescription(const std::string& description) -> std::string - { - return "Pending Prenote List " + description; - } -} // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PendingPrenoteList.h b/src/plugin/prenote/PendingPrenoteList.h deleted file mode 100644 index 9b84d72c8..000000000 --- a/src/plugin/prenote/PendingPrenoteList.h +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once -#include "euroscope/AsrEventHandlerInterface.h" -#include "radarscreen/RadarRenderableInterface.h" - -namespace UKControllerPlugin { - namespace Controller { - class ActiveCallsignCollection; - class ControllerPositionCollection; - } // namespace Controller - - namespace Components { - class BrushSwitcher; - class TitleBar; - class Button; - } // namespace Components - - namespace Euroscope { - class EuroscopePluginLoopbackInterface; - } // namespace Euroscope -} // namespace UKControllerPlugin - -namespace UKControllerPlugin::Prenote { - class AcknowledgePrenoteMessage; - class PrenoteMessageCollection; - class PrenoteMessage; - - /* - * Renders a list of departure releases requiring the users - * decision. - */ - class PendingPrenoteList : public RadarScreen::RadarRenderableInterface, public Euroscope::AsrEventHandlerInterface - { - public: - PendingPrenoteList( - std::shared_ptr messages, - std::shared_ptr acknowledger, - Euroscope::EuroscopePluginLoopbackInterface& plugin, - const Controller::ControllerPositionCollection& controllers, - const Controller::ActiveCallsignCollection& activeCallsigns, - int screenObjectId); - void LeftClick( - Euroscope::EuroscopeRadarLoopbackInterface& radarScreen, - int objectId, - const std::string& objectDescription, - POINT mousePos, - RECT itemArea) override; - auto IsVisible() const -> bool override; - void Move(RECT position, std::string objectDescription) override; - void Render( - Windows::GdiGraphicsInterface& graphics, Euroscope::EuroscopeRadarLoopbackInterface& radarScreen) override; - void ResetPosition() override; - void AsrLoadedEvent(Euroscope::UserSetting& userSetting) override; - void AsrClosingEvent(Euroscope::UserSetting& userSetting) override; - void ToggleVisible(); - auto ContentCollapsed() const -> bool; - auto Position() const -> Gdiplus::PointF; - - private: - [[nodiscard]] static auto GetAsrKey(const std::string& item) -> std::string; - [[nodiscard]] static auto GetAsrDescription(const std::string& description) -> std::string; - - // The controllers - const Controller::ControllerPositionCollection& controllers; - - // All the prenote messages - const std::shared_ptr messages; - - // Lets us acknowledge messages - std::shared_ptr acknowledger; - - // Provides interface with the plugin - Euroscope::EuroscopePluginLoopbackInterface& plugin; - - // Active controllers - const Controller::ActiveCallsignCollection& activeCallsigns; - - // Drawing RECTs - const Gdiplus::Rect callsignColumnHeader{5, 5, 100, 25}; - const Gdiplus::Rect controllerColumnHeader{115, 5, 100, 25}; - const Gdiplus::Rect airportColumnHeader{225, 5, 40, 25}; - const Gdiplus::Rect sidColumnHeader{275, 5, 65, 25}; - const Gdiplus::Rect destColumnHeader{350, 5, 40, 25}; - - const Gdiplus::Color OFF_WHITE_COLOUR = Gdiplus::Color(255, 255, 255); - const Gdiplus::Color TITLE_BAR_BASE_COLOUR = Gdiplus::Color(130, 50, 154); - const Gdiplus::Color TITLE_BAR_FLASH_COLOUR = Gdiplus::Color(179, 3, 0); - - // Brushes - const Gdiplus::SolidBrush textBrush; - - // Clickspot identifier - const int screenObjectId; - - // Is the window visible - bool visible; - - // Is the content collapsed - bool contentCollapsed; - - // Height of title bar - const int titleBarHeight = 20; - - // Width of title bar - const int titleBarWidth = 390; - - // Height of each line - const int LINE_HEIGHT = 25; - - // Our window position - Gdiplus::PointF position = {0, 0}; - - inline static const RECT DEFAULT_POSITION = {100, 100, 200, 200}; - const Gdiplus::Rect CLOSE_BUTTON_OFFSET = {375, 5, 10, 10}; - const Gdiplus::Rect COLLAPSE_BUTTON_OFFSET = {360, 5, 10, 10}; - - // Standard window components - std::shared_ptr titleBar; - std::shared_ptr closeButton; - std::shared_ptr collapseButton; - std::shared_ptr brushSwitcher; - }; -} // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteMessage.cpp b/src/plugin/prenote/PrenoteMessage.cpp index 1291abb0c..97af7a884 100644 --- a/src/plugin/prenote/PrenoteMessage.cpp +++ b/src/plugin/prenote/PrenoteMessage.cpp @@ -16,7 +16,7 @@ namespace UKControllerPlugin::Prenote { : id(id), callsign(std::move(callsign)), departureAirfield(std::move(departureAirfield)), sid(std::move(sid)), destinationAirfield(std::move(destinationAirfield)), sendingControllerId(sendingControllerId), targetControllerId(targetControllerId), expiresAt(expiresAt), - acknowledgedAt((std::chrono::system_clock::time_point::max)()) + acknowledgedAt((std::chrono::system_clock::time_point::max)()), createdAt(Time::TimeNow()) { } @@ -74,4 +74,9 @@ namespace UKControllerPlugin::Prenote { { return this->acknowledgedAt; } + + auto PrenoteMessage::GetCreatedAt() const -> const std::chrono::system_clock::time_point& + { + return this->createdAt; + } } // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteMessage.h b/src/plugin/prenote/PrenoteMessage.h index c4e7d1220..40b15d746 100644 --- a/src/plugin/prenote/PrenoteMessage.h +++ b/src/plugin/prenote/PrenoteMessage.h @@ -26,6 +26,7 @@ namespace UKControllerPlugin::Prenote { [[nodiscard]] auto GetExpiresAt() const -> const std::chrono::system_clock::time_point&; [[nodiscard]] auto IsAcknowledged() const -> bool; [[nodiscard]] auto GetAcknowledgedAt() const -> const std::chrono::system_clock::time_point&; + [[nodiscard]] auto GetCreatedAt() const -> const std::chrono::system_clock::time_point&; void Acknowledge(); private: @@ -55,5 +56,8 @@ namespace UKControllerPlugin::Prenote { // What time the prenote expires std::chrono::system_clock::time_point acknowledgedAt; + + // When was it created + std::chrono::system_clock::time_point createdAt; }; } // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/PrenoteModule.cpp b/src/plugin/prenote/PrenoteModule.cpp index 4364d16b6..373ae2948 100644 --- a/src/plugin/prenote/PrenoteModule.cpp +++ b/src/plugin/prenote/PrenoteModule.cpp @@ -1,7 +1,6 @@ #include "AcknowledgePrenoteMessage.h" #include "CancelPrenoteMessageMenu.h" #include "NewPrenotePushEventHandler.h" -#include "PendingPrenoteList.h" #include "PrenoteAcknowledgedPushEventHandler.h" #include "PrenoteDeletedPushEventHandler.h" #include "PrenoteEventHandler.h" @@ -15,7 +14,6 @@ #include "PublishedPrenoteCollectionFactory.h" #include "PublishedPrenoteMapper.h" #include "SendPrenoteMenu.h" -#include "TogglePendingPrenoteList.h" #include "TriggerPrenoteMessageStatusView.h" #include "bootstrap/BootstrapWarningMessage.h" #include "bootstrap/PersistenceContainer.h" @@ -23,14 +21,12 @@ #include "controller/ControllerPositionHierarchy.h" #include "controller/ControllerPositionHierarchyFactory.h" #include "dependency/DependencyLoaderInterface.h" -#include "euroscope/AsrEventHandlerCollection.h" #include "euroscope/CallbackFunction.h" #include "flightplan/FlightPlanEventHandlerCollection.h" #include "message/UserMessager.h" #include "plugin/FunctionCallEventHandler.h" #include "plugin/UKPlugin.h" #include "push/PushEventProcessorCollection.h" -#include "radarscreen/ConfigurableDisplayCollection.h" #include "tag/TagItemCollection.h" #include "timedevent/TimedEventCollection.h" @@ -58,7 +54,6 @@ namespace UKControllerPlugin::Prenote { const int MESSAGE_TIMEOUT_CHECK_INTERVAL = 10; - std::shared_ptr messages; // NOLINT std::shared_ptr acknowledge; // NOLINT std::unique_ptr prenotes; // NOLINT std::unique_ptr mapper; // NOLINT @@ -81,24 +76,30 @@ namespace UKControllerPlugin::Prenote { *persistence.pluginUserSettingHandler)); // Electronic prenote messages - messages = std::make_shared(); + persistence.prenotes = std::make_shared(); // Push event processors persistence.pushEventProcessors->AddProcessor(std::make_shared( - messages, *persistence.controllerPositions, *persistence.activeCallsigns, *persistence.windows)); - persistence.pushEventProcessors->AddProcessor(std::make_shared(messages)); - persistence.pushEventProcessors->AddProcessor(std::make_shared(messages)); + persistence.prenotes, + *persistence.controllerPositions, + *persistence.activeCallsigns, + *persistence.windows)); + persistence.pushEventProcessors->AddProcessor( + std::make_shared(persistence.prenotes)); + persistence.pushEventProcessors->AddProcessor( + std::make_shared(persistence.prenotes)); persistence.timedHandler->RegisterEvent( - std::make_shared(messages), MESSAGE_TIMEOUT_CHECK_INTERVAL); + std::make_shared(persistence.prenotes), MESSAGE_TIMEOUT_CHECK_INTERVAL); // Status indicator tag item persistence.tagHandler->RegisterTagItem( - MESSAGE_STATUS_INDICATOR_TAG_ITEM_ID, std::make_shared(messages)); + MESSAGE_STATUS_INDICATOR_TAG_ITEM_ID, + std::make_shared(persistence.prenotes)); // Cancelling prenote messages menu auto cancelCallback = persistence.pluginFunctionHandlers->ReserveNextDynamicFunctionId(); auto cancelMenu = std::make_shared( - messages, + persistence.prenotes, *persistence.controllerPositions, *persistence.activeCallsigns, *persistence.plugin, @@ -125,7 +126,7 @@ namespace UKControllerPlugin::Prenote { // Send prenote messages menu auto sendCallback = persistence.pluginFunctionHandlers->ReserveNextDynamicFunctionId(); auto sendMenu = std::make_shared( - messages, + persistence.prenotes, *persistence.controllerPositions, *persistence.activeCallsigns, *persistence.plugin, @@ -151,7 +152,7 @@ namespace UKControllerPlugin::Prenote { // Acknowledge message acknowledge = std::make_shared( - messages, *persistence.activeCallsigns, *persistence.taskRunner, *persistence.api); + persistence.prenotes, *persistence.activeCallsigns, *persistence.taskRunner, *persistence.api); auto acknowledgeForTagFunction = acknowledge; TagFunction acknowledgePrenoteMessage( @@ -179,42 +180,13 @@ namespace UKControllerPlugin::Prenote { } void PrenoteModule::BootstrapRadarScreen( - const PersistenceContainer& persistence, - RadarRenderableCollection& radarRenderables, - RadarScreen::ConfigurableDisplayCollection& configurables, - Euroscope::AsrEventHandlerCollection& asrHandlers) + const PersistenceContainer& persistence, RadarRenderableCollection& radarRenderables) { // Status view renderer radarRenderables.RegisterRenderer( radarRenderables.ReserveRendererIdentifier(), - std::make_shared(messages, *persistence.controllerPositions), + std::make_shared(persistence.prenotes, *persistence.controllerPositions), RadarRenderableCollection::afterLists); - - // Pending list renderer - auto listRendererId = radarRenderables.ReserveRendererIdentifier(); - auto listRenderer = std::make_shared( - messages, - acknowledge, - *persistence.plugin, - *persistence.controllerPositions, - *persistence.activeCallsigns, - radarRenderables.ReserveScreenObjectIdentifier(listRendererId)); - - radarRenderables.RegisterRenderer(listRendererId, listRenderer, RadarRenderableCollection::afterLists); - asrHandlers.RegisterHandler(listRenderer); - - // Configuration menu toggle for pending list - auto toggleListCallbackId = persistence.pluginFunctionHandlers->ReserveNextDynamicFunctionId(); - auto listToggle = std::make_shared(listRenderer, toggleListCallbackId); - configurables.RegisterDisplay(listToggle); - - CallbackFunction showReleaseRequestListCallback( - toggleListCallbackId, - "Toggle Pending Prenote List", - [listToggle](int functionId, std::string subject, RECT screenObjectArea) { - listToggle->Configure(functionId, std::move(subject), screenObjectArea); - }); - persistence.pluginFunctionHandlers->RegisterFunctionCall(showReleaseRequestListCallback); } auto PrenoteModule::GetDependencyKey() -> std::string diff --git a/src/plugin/prenote/PrenoteModule.h b/src/plugin/prenote/PrenoteModule.h index 2fb4e8da3..be9d8d29b 100644 --- a/src/plugin/prenote/PrenoteModule.h +++ b/src/plugin/prenote/PrenoteModule.h @@ -15,12 +15,8 @@ namespace UKControllerPlugin { class ControllerPositionCollection; } // namespace Controller namespace RadarScreen { - class ConfigurableDisplayCollection; class RadarRenderableCollection; } // namespace RadarScreen - namespace Euroscope { - class AsrEventHandlerCollection; - } // namespace Euroscope } // namespace UKControllerPlugin namespace UKControllerPlugin::Prenote { @@ -37,9 +33,7 @@ namespace UKControllerPlugin::Prenote { static void BootstrapRadarScreen( const Bootstrap::PersistenceContainer& persistence, - RadarScreen::RadarRenderableCollection& radarRenderables, - RadarScreen::ConfigurableDisplayCollection& configurables, - Euroscope::AsrEventHandlerCollection& asrHandlers); + RadarScreen::RadarRenderableCollection& radarRenderables); [[nodiscard]] static auto GetDependencyKey() -> std::string; }; diff --git a/src/plugin/prenote/TogglePendingPrenoteList.cpp b/src/plugin/prenote/TogglePendingPrenoteList.cpp deleted file mode 100644 index c11a0c1ba..000000000 --- a/src/plugin/prenote/TogglePendingPrenoteList.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "PendingPrenoteList.h" -#include "TogglePendingPrenoteList.h" - -namespace UKControllerPlugin::Prenote { - - TogglePendingPrenoteList::TogglePendingPrenoteList(std::shared_ptr list, int callbackId) - : list(std::move(list)), callbackId(callbackId) - { - } - - void TogglePendingPrenoteList::Configure(int functionId, std::string subject, RECT screenObjectArea) - { - this->list->ToggleVisible(); - } - - auto TogglePendingPrenoteList::GetConfigurationMenuItem() const -> Plugin::PopupMenuItem - { - return { - "Toggle Pending Prenote List", - "", - this->callbackId, - this->list->IsVisible() ? EuroScopePlugIn::POPUP_ELEMENT_CHECKED : EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, - false, - false}; - } -} // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/prenote/TogglePendingPrenoteList.h b/src/plugin/prenote/TogglePendingPrenoteList.h deleted file mode 100644 index cf54ebbd4..000000000 --- a/src/plugin/prenote/TogglePendingPrenoteList.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "radarscreen/ConfigurableDisplayInterface.h" - -namespace UKControllerPlugin::Prenote { - class PendingPrenoteList; - - /* - * A class for the configuration menu that toggles - * the pending prenotes list. - */ - class TogglePendingPrenoteList : public RadarScreen::ConfigurableDisplayInterface - { - public: - TogglePendingPrenoteList(std::shared_ptr list, int callbackId); - void Configure(int functionId, std::string subject, RECT screenObjectArea) override; - [[nodiscard]] auto GetConfigurationMenuItem() const -> Plugin::PopupMenuItem override; - - private: - // The list - std::shared_ptr list; - - // Callback for the list - const int callbackId; - }; -} // namespace UKControllerPlugin::Prenote diff --git a/src/plugin/radarscreen/RadarScreenFactory.cpp b/src/plugin/radarscreen/RadarScreenFactory.cpp index 22f928214..aa8d0a190 100644 --- a/src/plugin/radarscreen/RadarScreenFactory.cpp +++ b/src/plugin/radarscreen/RadarScreenFactory.cpp @@ -6,6 +6,7 @@ #include "bootstrap/HelperBootstrap.h" #include "bootstrap/PersistenceContainer.h" #include "countdown/CountdownModule.h" +#include "departure/DepartureModule.h" #include "euroscope/GeneralSettingsConfigurationBootstrap.h" #include "graphics/GdiGraphicsWrapper.h" #include "historytrail/HistoryTrailModule.h" @@ -102,8 +103,9 @@ namespace UKControllerPlugin::RadarScreen { Srd::BootstrapRadarScreen(configurableDisplays); Notifications::BootstrapRadarScreen(this->persistence, configurableDisplays); - Releases::BootstrapRadarScreen(this->persistence, renderers, configurableDisplays, userSettingHandlers); - PrenoteModule::BootstrapRadarScreen(this->persistence, renderers, configurableDisplays, userSettingHandlers); + Releases::BootstrapRadarScreen(this->persistence, renderers); + PrenoteModule::BootstrapRadarScreen(this->persistence, renderers); + Departure::BootstrapRadarScreen(this->persistence, renderers, configurableDisplays, userSettingHandlers); MissedApproach::BootstrapRadarScreen(this->persistence, renderers, configurableDisplays, userSettingHandlers); // Register command for position resets diff --git a/src/plugin/releases/DepartureReleaseDecisionList.cpp b/src/plugin/releases/DepartureReleaseDecisionList.cpp deleted file mode 100644 index 356ef93c3..000000000 --- a/src/plugin/releases/DepartureReleaseDecisionList.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "DepartureReleaseDecisionList.h" -#include "DepartureReleaseEventHandler.h" -#include "DepartureReleaseRequest.h" -#include "components/BrushSwitcher.h" -#include "components/Button.h" -#include "components/ClickableArea.h" -#include "components/StandardButtons.h" -#include "components/TitleBar.h" -#include "controller/ControllerPosition.h" -#include "controller/ControllerPositionCollection.h" -#include "euroscope/EuroScopeCFlightPlanInterface.h" -#include "euroscope/EuroscopePluginLoopbackInterface.h" -#include "euroscope/EuroscopeRadarLoopbackInterface.h" -#include "euroscope/UserSetting.h" -#include "graphics/GdiGraphicsInterface.h" -#include "helper/HelperFunctions.h" -#include "tag/TagData.h" - -namespace UKControllerPlugin::Releases { - - DepartureReleaseDecisionList::DepartureReleaseDecisionList( - DepartureReleaseEventHandler& handler, - Euroscope::EuroscopePluginLoopbackInterface& plugin, - const Controller::ControllerPositionCollection& controllers, - const int screenObjectId) - : controllers(controllers), handler(handler), plugin(plugin), textBrush(OFF_WHITE_COLOUR), - screenObjectId(screenObjectId), visible(false), contentCollapsed(false) - { - this->brushSwitcher = Components::BrushSwitcher::Create( - std::make_shared(TITLE_BAR_BASE_COLOUR), std::chrono::seconds(2)) - ->AdditionalBrush(std::make_shared(TITLE_BAR_FLASH_COLOUR)); - - this->titleBar = Components::TitleBar::Create( - L"Departure Release Requests", {0, 0, this->titleBarWidth, this->titleBarHeight}) - ->WithDrag(this->screenObjectId) - ->WithBorder(std::make_shared(OFF_WHITE_COLOUR)) - ->WithBackgroundBrush(std::make_shared(TITLE_BAR_BASE_COLOUR)) - ->WithTextBrush(std::make_shared(OFF_WHITE_COLOUR)); - - this->closeButton = Components::Button::Create( - closeButtonOffset, this->screenObjectId, "closeButton", Components::CloseButton()); - - this->collapseButton = Components::Button::Create( - collapseButtonOffset, this->screenObjectId, "collapseButton", Components::CollapseButton([this]() -> bool { - return this->contentCollapsed; - })); - } - - void DepartureReleaseDecisionList::LeftClick( - Euroscope::EuroscopeRadarLoopbackInterface& radarScreen, - int objectId, - const std::string& objectDescription, - POINT mousePos, - RECT itemArea) - { - if (objectDescription == "collapseButton") { - this->contentCollapsed = !this->contentCollapsed; - return; - } - - if (objectDescription == "closeButton") { - this->visible = false; - return; - } - - auto fp = this->plugin.GetFlightplanForCallsign(objectDescription); - auto rt = this->plugin.GetRadarTargetForCallsign(objectDescription); - if (!fp || !rt) { - return; - } - - this->handler.OpenDecisionMenu(*fp, *rt, "", mousePos); - } - - auto DepartureReleaseDecisionList::IsVisible() const -> bool - { - return this->visible; - } - - void DepartureReleaseDecisionList::Move(RECT position, std::string objectDescription) - { - this->position = {static_cast(position.left), static_cast(position.top)}; - } - - void DepartureReleaseDecisionList::Render( - Windows::GdiGraphicsInterface& graphics, Euroscope::EuroscopeRadarLoopbackInterface& radarScreen) - { - auto decisions = this->handler.GetReleasesRequiringUsersDecision(); - if (decisions.empty()) { - this->titleBar->WithBackgroundBrush(this->brushSwitcher->Base()); - } else { - this->titleBar->WithBackgroundBrush(this->brushSwitcher->Next()); - } - - // Translate to content position - graphics.Translated( - this->position.X, - this->position.Y + static_cast(this->titleBarHeight), - [this, &graphics, &radarScreen, &decisions] { - if (this->contentCollapsed) { - return; - } - - // Draw column headers - graphics.DrawString(L"Callsign", this->callsignColumnHeader, this->textBrush); - graphics.DrawString(L"Controller", this->controllerColumnHeader, this->textBrush); - graphics.DrawString(L"Dept", this->airportColumnHeader, this->textBrush); - graphics.DrawString(L"SID", this->sidColumnHeader, this->textBrush); - - // Draw each aircraft that we care about - Gdiplus::Rect callsignColumn = this->callsignColumnHeader; - Gdiplus::Rect controllerColumn = this->controllerColumnHeader; - Gdiplus::Rect airportColumn = this->airportColumnHeader; - Gdiplus::Rect sidColumn = this->sidColumnHeader; - - // Draw each decision - for (const auto& decision : decisions) { - // Shift the cols - callsignColumn.Y += lineHeight; - controllerColumn.Y += lineHeight; - airportColumn.Y += lineHeight; - sidColumn.Y += lineHeight; - - graphics.DrawString( - HelperFunctions::ConvertToWideString(decision->Callsign()), callsignColumn, this->textBrush); - std::shared_ptr callsignClickspot = Components::ClickableArea::Create( - callsignColumn, this->screenObjectId, decision->Callsign(), false); - callsignClickspot->Apply(graphics, radarScreen); - - const std::wstring controller = HelperFunctions::ConvertToWideString( - this->controllers.FetchPositionById(decision->RequestingController())->GetCallsign()); - graphics.DrawString(controller, controllerColumn, this->textBrush); - - auto fp = this->plugin.GetFlightplanForCallsign(decision->Callsign()); - if (!fp) { - continue; - } - - graphics.DrawString( - HelperFunctions::ConvertToWideString(fp->GetOrigin()), airportColumn, this->textBrush); - - graphics.DrawString( - HelperFunctions::ConvertToWideString(fp->GetSidName()), sidColumn, this->textBrush); - } - }); - - // Translate to window position - graphics.Translated(this->position.X, this->position.Y, [this, &graphics, &radarScreen] { - this->titleBar->Draw(graphics, radarScreen); - this->closeButton->Draw(graphics, radarScreen); - this->collapseButton->Draw(graphics, radarScreen); - }); - } - - void DepartureReleaseDecisionList::ResetPosition() - { - this->Move(defaultRect, ""); - } - - void DepartureReleaseDecisionList::AsrLoadedEvent(Euroscope::UserSetting& userSetting) - { - this->visible = userSetting.GetBooleanEntry(GetAsrKey("Visible"), false); - - this->contentCollapsed = userSetting.GetBooleanEntry(GetAsrKey("ContentCollapsed"), false); - - this->Move( - {userSetting.GetIntegerEntry(GetAsrKey("XPosition"), defaultPosition), - userSetting.GetIntegerEntry(GetAsrKey("YPosition"), defaultPosition), - 0, - 0}, - ""); - } - - void DepartureReleaseDecisionList::AsrClosingEvent(Euroscope::UserSetting& userSetting) - { - userSetting.Save(GetAsrKey("Visible"), GetAsrDescription("Visible"), this->visible); - - userSetting.Save(GetAsrKey("ContentCollapsed"), GetAsrDescription("Content Collapsed"), this->contentCollapsed); - - userSetting.Save(GetAsrKey("XPosition"), GetAsrDescription("X Position"), static_cast(this->position.X)); - - userSetting.Save(GetAsrKey("YPosition"), GetAsrDescription("Y Position"), static_cast(this->position.Y)); - } - - void DepartureReleaseDecisionList::ToggleVisible() - { - this->visible = !this->visible; - } - - auto DepartureReleaseDecisionList::ContentCollapsed() const -> bool - { - return this->contentCollapsed; - } - - auto DepartureReleaseDecisionList::Position() const -> Gdiplus::PointF - { - return this->position; - } - - auto DepartureReleaseDecisionList::GetAsrKey(const std::string& item) -> std::string - { - return "departureReleaseRequestList" + item; - } - - auto DepartureReleaseDecisionList::GetAsrDescription(const std::string& description) -> std::string - { - return "Departure Release Request List " + description; - } -} // namespace UKControllerPlugin::Releases diff --git a/src/plugin/releases/DepartureReleaseRequest.cpp b/src/plugin/releases/DepartureReleaseRequest.cpp index 3023bbd4e..7a12da115 100644 --- a/src/plugin/releases/DepartureReleaseRequest.cpp +++ b/src/plugin/releases/DepartureReleaseRequest.cpp @@ -1,135 +1,138 @@ #include "DepartureReleaseRequest.h" #include "time/SystemClock.h" -namespace UKControllerPlugin { - namespace Releases { - - DepartureReleaseRequest::DepartureReleaseRequest( - int id, - std::string callsign, - int requestingController, - int targetController, - std::chrono::system_clock::time_point requestExpiresAt) - : id(id), callsign(std::move(callsign)), requestingController(requestingController), - targetController(targetController), requestExpiresAt(requestExpiresAt) - { - } - - void DepartureReleaseRequest::Acknowledge() - { - this->acknowledgedAtTime = Time::TimeNow(); - } - - void DepartureReleaseRequest::Reject(std::string remarks) - { - this->rejectedAtTime = Time::TimeNow(); - this->remarks = remarks; - } - - void DepartureReleaseRequest::Approve( - std::chrono::system_clock::time_point releasedAtTime, - std::chrono::system_clock::time_point releaseExpiresAt, - std::string remarks) - { - this->releasedAtTime = releasedAtTime; - this->releaseExpiresAt = releaseExpiresAt; - this->remarks = remarks; - } - - void DepartureReleaseRequest::Approve(std::chrono::system_clock::time_point releasedAtTime, std::string remarks) - { - this->releasedAtTime = releasedAtTime; - this->remarks = remarks; - } - - int DepartureReleaseRequest::Id() const - { - return this->id; - } - - bool DepartureReleaseRequest::RequiresDecision() const - { - return !this->Rejected() && !this->RequestExpired() && !this->Approved(); - } - - std::string DepartureReleaseRequest::Callsign() const - { - return this->callsign; - } - - int DepartureReleaseRequest::RequestingController() const - { - return this->requestingController; - } - - int DepartureReleaseRequest::TargetController() const - { - return this->targetController; - } - - bool DepartureReleaseRequest::Acknowledged() const - { - return this->acknowledgedAtTime != this->noTime; - } - - bool DepartureReleaseRequest::Rejected() const - { - return this->rejectedAtTime != this->noTime; - } - - bool DepartureReleaseRequest::Approved() const - { - return this->releasedAtTime != this->noTime; - } - - bool DepartureReleaseRequest::RequestExpired() const - { - return this->requestExpiresAt < Time::TimeNow(); - } - - bool DepartureReleaseRequest::ApprovalExpired() const - { - return this->releaseExpiresAt < Time::TimeNow(); - } - - bool DepartureReleaseRequest::AwaitingReleasedTime() const - { - return this->releasedAtTime > Time::TimeNow(); - } - - bool DepartureReleaseRequest::ApprovedWithNoExpiry() const - { - return this->Approved() && this->releaseExpiresAt == this->noTimeMax; - } - - std::chrono::system_clock::time_point DepartureReleaseRequest::RequestExpiryTime() const - { - return this->requestExpiresAt; - } - - std::chrono::system_clock::time_point DepartureReleaseRequest::ReleaseExpiryTime() const - { - return this->releaseExpiresAt; - } - - std::chrono::system_clock::time_point DepartureReleaseRequest::ReleasedAtTime() const - { - return this->releasedAtTime; - } - - std::chrono::system_clock::time_point DepartureReleaseRequest::RejectedAtTime() const - { - return this->rejectedAtTime; - } - - std::chrono::system_clock::time_point DepartureReleaseRequest::AcknowledgedAtTime() const - { - return this->acknowledgedAtTime; - } - - auto DepartureReleaseRequest::Remarks() const -> const std::string& - { - return this->remarks; - } - } // namespace Releases -} // namespace UKControllerPlugin +namespace UKControllerPlugin::Releases { + + DepartureReleaseRequest::DepartureReleaseRequest( + int id, + std::string callsign, + int requestingController, + int targetController, + std::chrono::system_clock::time_point requestExpiresAt) + : id(id), callsign(std::move(callsign)), requestingController(requestingController), + targetController(targetController), requestExpiresAt(requestExpiresAt), createdAt(Time::TimeNow()) + { + } + + void DepartureReleaseRequest::Acknowledge() + { + this->acknowledgedAtTime = Time::TimeNow(); + } + + void DepartureReleaseRequest::Reject(std::string remarks) + { + this->rejectedAtTime = Time::TimeNow(); + this->remarks = remarks; + } + + void DepartureReleaseRequest::Approve( + std::chrono::system_clock::time_point releasedAtTime, + std::chrono::system_clock::time_point releaseExpiresAt, + std::string remarks) + { + this->releasedAtTime = releasedAtTime; + this->releaseExpiresAt = releaseExpiresAt; + this->remarks = remarks; + } + + void DepartureReleaseRequest::Approve(std::chrono::system_clock::time_point releasedAtTime, std::string remarks) + { + this->releasedAtTime = releasedAtTime; + this->remarks = remarks; + } + + auto DepartureReleaseRequest::Id() const -> int + { + return this->id; + } + + bool DepartureReleaseRequest::RequiresDecision() const + { + return !this->Rejected() && !this->RequestExpired() && !this->Approved(); + } + + auto DepartureReleaseRequest::Callsign() const -> std::string + { + return this->callsign; + } + + auto DepartureReleaseRequest::RequestingController() const -> int + { + return this->requestingController; + } + + auto DepartureReleaseRequest::TargetController() const -> int + { + return this->targetController; + } + + bool DepartureReleaseRequest::Acknowledged() const + { + return this->acknowledgedAtTime != this->noTime; + } + + auto DepartureReleaseRequest::Rejected() const -> bool + { + return this->rejectedAtTime != this->noTime; + } + + auto DepartureReleaseRequest::Approved() const -> bool + { + return this->releasedAtTime != this->noTime; + } + + auto DepartureReleaseRequest::RequestExpired() const -> bool + { + return this->requestExpiresAt < Time::TimeNow(); + } + + auto DepartureReleaseRequest::ApprovalExpired() const -> bool + { + return this->releaseExpiresAt < Time::TimeNow(); + } + + auto DepartureReleaseRequest::AwaitingReleasedTime() const -> bool + { + return this->releasedAtTime > Time::TimeNow(); + } + + auto DepartureReleaseRequest::ApprovedWithNoExpiry() const -> bool + { + return this->Approved() && this->releaseExpiresAt == this->noTimeMax; + } + + auto DepartureReleaseRequest::RequestExpiryTime() const -> std::chrono::system_clock::time_point + { + return this->requestExpiresAt; + } + + auto DepartureReleaseRequest::ReleaseExpiryTime() const -> std::chrono::system_clock::time_point + { + return this->releaseExpiresAt; + } + + auto DepartureReleaseRequest::ReleasedAtTime() const -> std::chrono::system_clock::time_point + { + return this->releasedAtTime; + } + + auto DepartureReleaseRequest::RejectedAtTime() const -> std::chrono::system_clock::time_point + { + return this->rejectedAtTime; + } + + auto DepartureReleaseRequest::AcknowledgedAtTime() const -> std::chrono::system_clock::time_point + { + return this->acknowledgedAtTime; + } + + auto DepartureReleaseRequest::CreatedAt() const -> std::chrono::system_clock::time_point + { + return this->createdAt; + } + + auto DepartureReleaseRequest::Remarks() const -> const std::string& + { + return this->remarks; + } +} // namespace UKControllerPlugin::Releases diff --git a/src/plugin/releases/DepartureReleaseRequest.h b/src/plugin/releases/DepartureReleaseRequest.h index fb8cdf6ca..1b14cac58 100644 --- a/src/plugin/releases/DepartureReleaseRequest.h +++ b/src/plugin/releases/DepartureReleaseRequest.h @@ -1,81 +1,84 @@ #pragma once -namespace UKControllerPlugin { - namespace Releases { - - class DepartureReleaseRequest - { - public: - DepartureReleaseRequest( - int id, - std::string callsign, - int requestingController, - int targetController, - std::chrono::system_clock::time_point requestExpiresAt); - - void Acknowledge(); - void Reject(std::string remarks); - void Approve( - std::chrono::system_clock::time_point releasedAtTime, - std::chrono::system_clock::time_point releaseExpiresAt, - std::string remarks); - - void Approve(std::chrono::system_clock::time_point releasedAtTime, std::string remarks); - - int Id() const; - bool RequiresDecision() const; - std::string Callsign() const; - int RequestingController() const; - int TargetController() const; - bool Acknowledged() const; - bool Rejected() const; - bool Approved() const; - bool RequestExpired() const; - bool ApprovalExpired() const; - bool AwaitingReleasedTime() const; - bool ApprovedWithNoExpiry() const; - [[nodiscard]] auto Remarks() const -> const std::string&; - std::chrono::system_clock::time_point RequestExpiryTime() const; - std::chrono::system_clock::time_point ReleaseExpiryTime() const; - std::chrono::system_clock::time_point ReleasedAtTime() const; - std::chrono::system_clock::time_point RejectedAtTime() const; - std::chrono::system_clock::time_point AcknowledgedAtTime() const; - - private: - static inline const std::chrono::system_clock::time_point noTime = - (std::chrono::system_clock::time_point::min)(); - - static inline const std::chrono::system_clock::time_point noTimeMax = - (std::chrono::system_clock::time_point::max)() - std::chrono::hours(500); - - // The id of the request - int id; - - // The callsign for the request - std::string callsign; - - // Who's requesting the release - int requestingController; - - // Who's the target of the release request - int targetController; - - // When the the request expires - std::chrono::system_clock::time_point requestExpiresAt; - - // What time the release was acknowledged - std::chrono::system_clock::time_point acknowledgedAtTime = noTime; - - // What time the release was rejected - std::chrono::system_clock::time_point rejectedAtTime = noTime; - - // The time the aircraft has been approved for release - std::chrono::system_clock::time_point releasedAtTime = noTime; - - // The time that the release expires - std::chrono::system_clock::time_point releaseExpiresAt = noTimeMax; - - // Remarks relating to the release being approved or rejected - std::string remarks; - }; - } // namespace Releases -} // namespace UKControllerPlugin + +namespace UKControllerPlugin::Releases { + + class DepartureReleaseRequest + { + public: + DepartureReleaseRequest( + int id, + std::string callsign, + int requestingController, + int targetController, + std::chrono::system_clock::time_point requestExpiresAt); + + void Acknowledge(); + void Reject(std::string remarks); + void Approve( + std::chrono::system_clock::time_point releasedAtTime, + std::chrono::system_clock::time_point releaseExpiresAt, + std::string remarks); + + void Approve(std::chrono::system_clock::time_point releasedAtTime, std::string remarks); + + int Id() const; + bool RequiresDecision() const; + std::string Callsign() const; + int RequestingController() const; + int TargetController() const; + bool Acknowledged() const; + bool Rejected() const; + bool Approved() const; + bool RequestExpired() const; + bool ApprovalExpired() const; + bool AwaitingReleasedTime() const; + bool ApprovedWithNoExpiry() const; + [[nodiscard]] auto Remarks() const -> const std::string&; + std::chrono::system_clock::time_point RequestExpiryTime() const; + std::chrono::system_clock::time_point ReleaseExpiryTime() const; + std::chrono::system_clock::time_point ReleasedAtTime() const; + std::chrono::system_clock::time_point RejectedAtTime() const; + std::chrono::system_clock::time_point AcknowledgedAtTime() const; + auto CreatedAt() const -> std::chrono::system_clock::time_point; + + private: + static inline const std::chrono::system_clock::time_point noTime = + (std::chrono::system_clock::time_point::min)(); + + static inline const std::chrono::system_clock::time_point noTimeMax = + (std::chrono::system_clock::time_point::max)() - std::chrono::hours(500); + + // The id of the request + int id; + + // The callsign for the request + std::string callsign; + + // Who's requesting the release + int requestingController; + + // Who's the target of the release request + int targetController; + + // When the the request expires + std::chrono::system_clock::time_point requestExpiresAt; + + // What time the release was acknowledged + std::chrono::system_clock::time_point acknowledgedAtTime = noTime; + + // What time the release was rejected + std::chrono::system_clock::time_point rejectedAtTime = noTime; + + // The time the aircraft has been approved for release + std::chrono::system_clock::time_point releasedAtTime = noTime; + + // The time that the release expires + std::chrono::system_clock::time_point releaseExpiresAt = noTimeMax; + + // When the request was created + std::chrono::system_clock::time_point createdAt; + + // Remarks relating to the release being approved or rejected + std::string remarks; + }; +} // namespace UKControllerPlugin::Releases diff --git a/src/plugin/releases/ReleaseModule.cpp b/src/plugin/releases/ReleaseModule.cpp index 31977c3c7..a15082841 100644 --- a/src/plugin/releases/ReleaseModule.cpp +++ b/src/plugin/releases/ReleaseModule.cpp @@ -1,6 +1,5 @@ #include "ApproveDepartureReleaseDialog.h" #include "CompareEnrouteReleaseTypes.h" -#include "DepartureReleaseDecisionList.h" #include "DepartureReleaseEventHandler.h" #include "DepartureReleaseRequestView.h" #include "EnrouteReleaseEventHandler.h" @@ -8,18 +7,15 @@ #include "RejectDepartureReleaseDialog.h" #include "ReleaseModule.h" #include "RequestDepartureReleaseDialog.h" -#include "ToggleDepartureReleaseDecisionList.h" #include "bootstrap/PersistenceContainer.h" #include "controller/HandoffEventHandlerCollection.h" #include "dependency/DependencyLoaderInterface.h" #include "dialog/DialogManager.h" -#include "euroscope/AsrEventHandlerCollection.h" #include "euroscope/CallbackFunction.h" #include "euroscope/EuroscopePluginLoopbackInterface.h" #include "plugin/FunctionCallEventHandler.h" #include "plugin/UKPlugin.h" #include "push/PushEventProcessorCollection.h" -#include "radarscreen/ConfigurableDisplayCollection.h" #include "tag/TagItemCollection.h" #include "timedevent/TimedEventCollection.h" @@ -32,7 +28,6 @@ using UKControllerPlugin::Releases::ApproveDepartureReleaseDialog; using UKControllerPlugin::Releases::DepartureReleaseEventHandler; using UKControllerPlugin::Releases::DepartureReleaseRequestView; using UKControllerPlugin::Releases::RequestDepartureReleaseDialog; -using UKControllerPlugin::Releases::ToggleDepartureReleaseDecisionList; using UKControllerPlugin::Tag::TagFunction; namespace UKControllerPlugin::Releases { @@ -233,41 +228,14 @@ namespace UKControllerPlugin::Releases { container.timedHandler->RegisterEvent(departureHandler, departureReleaseEventFrequency); } - void BootstrapRadarScreen( - const PersistenceContainer& container, - RadarScreen::RadarRenderableCollection& renderables, - RadarScreen::ConfigurableDisplayCollection& configurables, - Euroscope::AsrEventHandlerCollection& asrHandlers) + void + BootstrapRadarScreen(const PersistenceContainer& container, RadarScreen::RadarRenderableCollection& renderables) { // Create the request view renderer auto releaseRequestView = std::make_shared( *container.departureReleaseHandler, *container.controllerPositions); renderables.RegisterRenderer( renderables.ReserveRendererIdentifier(), releaseRequestView, renderables.afterLists); - - // Create the decision menu - const int decisionListRenderedId = renderables.ReserveRendererIdentifier(); - const auto decisionList = std::make_shared( - *container.departureReleaseHandler, - *container.plugin, - *container.controllerPositions, - renderables.ReserveScreenObjectIdentifier(decisionListRenderedId)); - renderables.RegisterRenderer(decisionListRenderedId, decisionList, renderables.afterLists); - asrHandlers.RegisterHandler(decisionList); - - // Create the configuration list item - const int requestListShowCallbackId = container.pluginFunctionHandlers->ReserveNextDynamicFunctionId(); - auto listItem = std::make_shared(decisionList, requestListShowCallbackId); - - CallbackFunction showReleaseRequestListCallback( - requestListShowCallbackId, - "Toggle Departure Release Request List", - [listItem](int functionId, std::string subject, RECT screenObjectArea) { - listItem->Configure(functionId, std::move(subject), screenObjectArea); - }); - - container.pluginFunctionHandlers->RegisterFunctionCall(showReleaseRequestListCallback); - configurables.RegisterDisplay(listItem); } auto GetReleaseTypesDependencyKey() -> std::string diff --git a/src/plugin/releases/ReleaseModule.h b/src/plugin/releases/ReleaseModule.h index 1e217cbae..6b0ac5122 100644 --- a/src/plugin/releases/ReleaseModule.h +++ b/src/plugin/releases/ReleaseModule.h @@ -3,11 +3,9 @@ namespace UKControllerPlugin { namespace RadarScreen { class RadarRenderableCollection; - class ConfigurableDisplayCollection; } // namespace RadarScreen namespace Euroscope { class EuroscopePluginLoopbackInterface; - class AsrEventHandlerCollection; } // namespace Euroscope namespace Dependency { class DependencyLoaderInterface; @@ -24,10 +22,7 @@ namespace UKControllerPlugin { Dependency::DependencyLoaderInterface& dependencies); void BootstrapRadarScreen( - const Bootstrap::PersistenceContainer& container, - RadarScreen::RadarRenderableCollection& renderables, - RadarScreen::ConfigurableDisplayCollection& configurables, - Euroscope::AsrEventHandlerCollection& asrHandlers); + const Bootstrap::PersistenceContainer& container, RadarScreen::RadarRenderableCollection& renderables); [[nodiscard]] auto GetReleaseTypesDependencyKey() -> std::string; } // namespace Releases diff --git a/src/plugin/releases/ToggleDepartureReleaseDecisionList.cpp b/src/plugin/releases/ToggleDepartureReleaseDecisionList.cpp deleted file mode 100644 index 31fe3fdc4..000000000 --- a/src/plugin/releases/ToggleDepartureReleaseDecisionList.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "pch/pch.h" -#include "releases/ToggleDepartureReleaseDecisionList.h" -#include "DepartureReleaseDecisionList.h" - -namespace UKControllerPlugin { - namespace Releases { - - ToggleDepartureReleaseDecisionList::ToggleDepartureReleaseDecisionList( - std::shared_ptr list, - int callbackId - ): list(list), callbackId(callbackId) - {} - - void ToggleDepartureReleaseDecisionList::Configure(int functionId, std::string subject, RECT screenObjectArea) - { - this->list->ToggleVisible(); - } - - Plugin::PopupMenuItem ToggleDepartureReleaseDecisionList::GetConfigurationMenuItem() const - { - return { - "Toggle Departure Release Decision List", - "", - this->callbackId, - this->list->IsVisible() - ? EuroScopePlugIn::POPUP_ELEMENT_CHECKED - : EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, - false, - false - }; - } - } // namespace Releases -} // namespace UKControllerPlugin diff --git a/src/plugin/releases/ToggleDepartureReleaseDecisionList.h b/src/plugin/releases/ToggleDepartureReleaseDecisionList.h deleted file mode 100644 index 402c50b28..000000000 --- a/src/plugin/releases/ToggleDepartureReleaseDecisionList.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "radarscreen/ConfigurableDisplayInterface.h" - -namespace UKControllerPlugin { - namespace Euroscope { - class EuroscopeFlightplanListInterface; - } // namespace Euroscope - - namespace Releases { - class DepartureReleaseDecisionList; - - /* - * A class for the configuration menu that toggles - * the departure release request list. - */ - class ToggleDepartureReleaseDecisionList : public RadarScreen::ConfigurableDisplayInterface - { - public: - ToggleDepartureReleaseDecisionList( - std::shared_ptr list, - int callbackId - ); - void Configure(int functionId, std::string subject, RECT screenObjectArea) override; - Plugin::PopupMenuItem GetConfigurationMenuItem() const override; - - private: - // The list - std::shared_ptr list; - - // Callback for the list - const int callbackId; - }; - } // namespace Releases -} // namespace UKControllerPlugin diff --git a/test/plugin/CMakeLists.txt b/test/plugin/CMakeLists.txt index 7a959219c..00d49831b 100644 --- a/test/plugin/CMakeLists.txt +++ b/test/plugin/CMakeLists.txt @@ -71,6 +71,11 @@ set(test__datablock ) source_group("test\\datablock" FILES ${test__datablock}) +set(test__departure + + departure/DepartureCoordinationListTest.cpp departure/ToggleDepartureCoordinationListTest.cpp departure/DepartureModuleTest.cpp) +source_group("test\\departure" FILES ${test__departure}) + set(test__dependency "dependency/DependencyLoaderTest.cpp" "dependency/UpdateDependenciesTest.cpp" @@ -389,8 +394,9 @@ set(test__prenote "prenote/SendPrenoteMenuTest.cpp" "prenote/TriggerPrenoteMessageStatusViewTest.cpp" "prenote/AcknowledgePrenoteMessageTest.cpp" - "prenote/TogglePendingPrenoteListTest.cpp" - "prenote/PendingPrenoteListTest.cpp" prenote/PublishedPrenoteCollectionTest.cpp prenote/PublishedPrenoteCollectionFactoryTest.cpp prenote/PublishedPrenoteMapperTest.cpp) + prenote/PublishedPrenoteCollectionTest.cpp + prenote/PublishedPrenoteCollectionFactoryTest.cpp + prenote/PublishedPrenoteMapperTest.cpp) source_group("test\\prenote" FILES ${test__prenote}) set(test__push @@ -426,14 +432,13 @@ set(test__releases "releases/CompareDepartureReleasesTest.cpp" "releases/CompareEnrouteReleaseTypesTest.cpp" "releases/DepartureReleaseCountdownColoursTest.cpp" - "releases/DepartureReleaseDecisionListTest.cpp" "releases/DepartureReleaseEventHandlerTest.cpp" "releases/DepartureReleaseRequestTest.cpp" "releases/EnrouteReleaseEventHandlerTest.cpp" "releases/EnrouteReleaseTypesSerializerTest.cpp" "releases/ReleaseModuleTest.cpp" - "releases/ToggleDepartureReleaseDecisionListTest.cpp" - releases/ReleaseApprovalRemarksUserMessageTest.cpp releases/ReleaseRejectionRemarksUserMessageTest.cpp) + releases/ReleaseApprovalRemarksUserMessageTest.cpp + releases/ReleaseRejectionRemarksUserMessageTest.cpp) source_group("test\\releases" FILES ${test__releases}) set(test__sectorfile @@ -524,6 +529,7 @@ set(ALL_FILES ${test__controller} ${test__countdown} ${test__datablock} + ${test__departure} ${test__dependency} ${test__euroscope} ${test__flightinformationservice} diff --git a/test/plugin/departure/DepartureCoordinationListTest.cpp b/test/plugin/departure/DepartureCoordinationListTest.cpp new file mode 100644 index 000000000..c98885ab3 --- /dev/null +++ b/test/plugin/departure/DepartureCoordinationListTest.cpp @@ -0,0 +1,216 @@ +#include "controller/ActiveCallsignCollection.h" +#include "controller/ControllerPosition.h" +#include "controller/ControllerPositionCollection.h" +#include "departure/DepartureCoordinationList.h" +#include "dialog/DialogManager.h" +#include "euroscope/UserSetting.h" +#include "message/UserMessager.h" +#include "prenote/PrenoteMessageCollection.h" +#include "releases/DepartureReleaseEventHandler.h" +#include "releases/DepartureReleaseRequest.h" + +using testing::Test; +using UKControllerPlugin::Departure::DepartureCoordinationList; +using UKControllerPlugin::Message::UserMessager; +using UKControllerPlugin::Prenote::PrenoteMessageCollection; + +namespace UKControllerPluginTest::Departure { + + class DepartureCoordinationListTest : public Test + { + public: + DepartureCoordinationListTest() + : userSettings(mockAsrProvider), messager(mockPlugin), + list(std::make_shared( + handler, prenotes, mockPlugin, controllers, activeCallsigns, 3)), + handler( + mockApi, + taskRunner, + mockPlugin, + controllers, + activeCallsigns, + dialogManager, + windows, + messager, + 103, + 104), + dialogManager(dialogProvider) + { + // Add positions and releases + auto request = std::make_shared( + 1, "BAW123", 3, 2, std::chrono::system_clock::now() + std::chrono::minutes(5)); + handler.AddReleaseRequest(request); + auto position = std::make_shared( + 2, "EGFF_APP", 125.850, std::vector{"EGGD", "EGFF"}, true, true); + controllers.AddPosition(position); + auto controllerCallsign = + std::make_shared("EGFF_APP", "Test 1", *position, true); + this->activeCallsigns.AddUserCallsign(*controllerCallsign); + } + + testing::NiceMock mockPlugin; + testing::NiceMock mockRadarScreen; + testing::NiceMock mockApi; + PrenoteMessageCollection prenotes; + testing::NiceMock mockAsrProvider; + UKControllerPlugin::Euroscope::UserSetting userSettings; + UserMessager messager; + std::shared_ptr list; + UKControllerPlugin::Releases::DepartureReleaseEventHandler handler; + UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; + testing::NiceMock dialogProvider; + testing::NiceMock api; + testing::NiceMock windows; + UKControllerPlugin::Dialog::DialogManager dialogManager; + UKControllerPlugin::Controller::ControllerPositionCollection controllers; + TaskManager::MockTaskRunnerInterface taskRunner; + }; + + TEST_F(DepartureCoordinationListTest, LeftClickCollapseButtonTogglesCollapsedContent) + { + this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); + EXPECT_TRUE(this->list->ContentCollapsed()); + this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); + EXPECT_FALSE(this->list->ContentCollapsed()); + this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); + EXPECT_TRUE(this->list->ContentCollapsed()); + } + + TEST_F(DepartureCoordinationListTest, LeftClickCloseButtonClosesWindow) + { + EXPECT_FALSE(this->list->IsVisible()); + this->list->ToggleVisible(); + EXPECT_TRUE(this->list->IsVisible()); + this->list->LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); + EXPECT_FALSE(this->list->IsVisible()); + this->list->LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); + EXPECT_FALSE(this->list->IsVisible()); + } + + TEST_F(DepartureCoordinationListTest, LeftClickAReleaseTogglesDecisionMenuTagFunction) + { + EXPECT_CALL( + mockRadarScreen, TogglePluginTagFunction("BAW123", 9013, PointEq(POINT{1, 2}), RectEq(RECT{3, 4, 5, 6}))) + .Times(1); + + this->list->LeftClick(mockRadarScreen, 1, "Rls.BAW123", {1, 2}, {3, 4, 5, 6}); + } + + TEST_F(DepartureCoordinationListTest, LeftClickAPrenoteTogglesAcknowledgeTagFunction) + { + EXPECT_CALL( + mockRadarScreen, TogglePluginTagFunction("BAW123", 9019, PointEq(POINT{1, 2}), RectEq(RECT{3, 4, 5, 6}))) + .Times(1); + + this->list->LeftClick(mockRadarScreen, 1, "Pre.BAW123", {1, 2}, {3, 4, 5, 6}); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsDefaultVisiblityFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListVisible")).Times(1).WillOnce(testing::Return("")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_FALSE(this->list->IsVisible()); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsVisibilityFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListVisible")) + .Times(1) + .WillOnce(testing::Return("1")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_TRUE(this->list->IsVisible()); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsDefaultContentCollapseFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListContentCollapsed")) + .Times(1) + .WillOnce(testing::Return("")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_FALSE(this->list->ContentCollapsed()); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsContentCollapsedFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListContentCollapsed")) + .Times(1) + .WillOnce(testing::Return("1")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_TRUE(this->list->ContentCollapsed()); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsDefaultPositionFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListXPosition")) + .Times(1) + .WillOnce(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListYPosition")) + .Times(1) + .WillOnce(testing::Return("")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_TRUE(this->list->Position().Equals(Gdiplus::PointF{100.0f, 100.0f})); + } + + TEST_F(DepartureCoordinationListTest, ItLoadsPositionFromAsr) + { + EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListXPosition")) + .Times(1) + .WillOnce(testing::Return("250")); + + EXPECT_CALL(mockAsrProvider, GetKey("departureCoordinationListYPosition")) + .Times(1) + .WillOnce(testing::Return("150")); + + this->list->AsrLoadedEvent(userSettings); + + EXPECT_TRUE(this->list->Position().Equals(Gdiplus::PointF{250.0f, 150.0f})); + } + + TEST_F(DepartureCoordinationListTest, ItSavesEverythingToAsrOnClose) + { + this->list->Move({100, 200, 300, 400}, ""); + EXPECT_CALL( + mockAsrProvider, SetKey("departureCoordinationListVisible", "Departure Coordination List Visible", "0")) + .Times(1); + + EXPECT_CALL( + mockAsrProvider, + SetKey("departureCoordinationListContentCollapsed", "Departure Coordination List Content Collapsed", "0")) + .Times(1); + + EXPECT_CALL( + mockAsrProvider, + SetKey("departureCoordinationListXPosition", "Departure Coordination List X Position", "100")) + .Times(1); + + EXPECT_CALL( + mockAsrProvider, + SetKey("departureCoordinationListYPosition", "Departure Coordination List Y Position", "200")) + .Times(1); + + this->list->AsrClosingEvent(userSettings); + } +} // namespace UKControllerPluginTest::Departure diff --git a/test/plugin/departure/DepartureModuleTest.cpp b/test/plugin/departure/DepartureModuleTest.cpp new file mode 100644 index 000000000..5429feed4 --- /dev/null +++ b/test/plugin/departure/DepartureModuleTest.cpp @@ -0,0 +1,67 @@ +#include "departure/DepartureModule.h" +#include "bootstrap/PersistenceContainer.h" +#include "push/PushEventProcessorCollection.h" +#include "tag/TagItemCollection.h" +#include "timedevent/TimedEventCollection.h" +#include "plugin/FunctionCallEventHandler.h" +#include "controller/HandoffEventHandlerCollection.h" +#include "dialog/DialogManager.h" +#include "euroscope/AsrEventHandlerCollection.h" +#include "radarscreen/RadarRenderableCollection.h" +#include "radarscreen/ConfigurableDisplayCollection.h" + +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::Test; +using UKControllerPlugin::Bootstrap::PersistenceContainer; +using UKControllerPlugin::Controller::HandoffEventHandlerCollection; +using UKControllerPlugin::Departure::BootstrapRadarScreen; +using UKControllerPlugin::Dialog::DialogManager; +using UKControllerPlugin::Plugin::FunctionCallEventHandler; +using UKControllerPlugin::Push::PushEventProcessorCollection; +using UKControllerPlugin::RadarScreen::ConfigurableDisplayCollection; +using UKControllerPlugin::RadarScreen::RadarRenderableCollection; +using UKControllerPlugin::Tag::TagItemCollection; +using UKControllerPlugin::TimedEvent::TimedEventCollection; +using UKControllerPluginTest::Dependency::MockDependencyLoader; +using UKControllerPluginTest::Dialog::MockDialogProvider; +using UKControllerPluginTest::Euroscope::MockEuroscopePluginLoopbackInterface; + +namespace UKControllerPluginTest::Departure { + + class DepartureModuleTest : public Test + { + public: + DepartureModuleTest() + { + container.tagHandler = std::make_unique(); + container.pluginFunctionHandlers = std::make_unique(); + } + + PersistenceContainer container; + RadarRenderableCollection renderables; + ConfigurableDisplayCollection configurables; + UKControllerPlugin::Euroscope::AsrEventHandlerCollection asr; + }; + + TEST_F(DepartureModuleTest, RadarScreenAddsRenderable) + { + BootstrapRadarScreen(this->container, renderables, configurables, asr); + EXPECT_EQ(1, renderables.CountRenderers()); + } + + TEST_F(DepartureModuleTest, RadarScreenAddsToAsr) + { + BootstrapRadarScreen(this->container, renderables, configurables, asr); + EXPECT_EQ(1, asr.CountHandlers()); + } + + TEST_F(DepartureModuleTest, RadarScreenAddsReleaseRequestShowOption) + { + BootstrapRadarScreen(this->container, renderables, configurables, asr); + EXPECT_EQ(1, configurables.CountDisplays()); + EXPECT_EQ(1, this->container.pluginFunctionHandlers->CountCallbacks()); + EXPECT_TRUE( + this->container.pluginFunctionHandlers->HasCallbackByDescription("Toggle Departure Coordination List")); + } +} // namespace UKControllerPluginTest::Departure diff --git a/test/plugin/departure/ToggleDepartureCoordinationListTest.cpp b/test/plugin/departure/ToggleDepartureCoordinationListTest.cpp new file mode 100644 index 000000000..cecb985ff --- /dev/null +++ b/test/plugin/departure/ToggleDepartureCoordinationListTest.cpp @@ -0,0 +1,92 @@ +#include "controller/ActiveCallsignCollection.h" +#include "controller/ControllerPositionCollection.h" +#include "departure/DepartureCoordinationList.h" +#include "departure/ToggleDepartureCoordinationList.h" +#include "dialog/DialogManager.h" +#include "message/UserMessager.h" +#include "prenote/PrenoteMessageCollection.h" +#include "releases/DepartureReleaseEventHandler.h" + +using testing::Test; +using UKControllerPlugin::Departure::DepartureCoordinationList; +using UKControllerPlugin::Departure::ToggleDepartureCoordinationList; +using UKControllerPlugin::Message::UserMessager; +using UKControllerPlugin::Prenote::PrenoteMessageCollection; + +namespace UKControllerPluginTest::Departure { + + class ToggleDepartureCoordinationListTest : public Test + { + public: + ToggleDepartureCoordinationListTest() + : messager(mockPlugin), handler( + mockApi, + taskRunner, + mockPlugin, + controllers, + activeCallsigns, + dialogManager, + windows, + messager, + 103, + 104), + list(std::make_shared( + handler, prenotes, mockPlugin, controllers, activeCallsigns, 3)), + dialogManager(dialogProvider) + { + } + + ToggleDepartureCoordinationList GetList(bool alreadyToggled) + { + if (alreadyToggled) { + list->ToggleVisible(); + } + + return ToggleDepartureCoordinationList(list, 2); + } + + testing::NiceMock mockPlugin; + testing::NiceMock mockApi; + testing::NiceMock windows; + UserMessager messager; + PrenoteMessageCollection prenotes; + UKControllerPlugin::Releases::DepartureReleaseEventHandler handler; + std::shared_ptr list; + UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; + testing::NiceMock dialogProvider; + testing::NiceMock api; + UKControllerPlugin::Dialog::DialogManager dialogManager; + UKControllerPlugin::Controller::ControllerPositionCollection controllers; + TaskManager::MockTaskRunnerInterface taskRunner; + }; + + TEST_F(ToggleDepartureCoordinationListTest, ItReturnsAConfigurationItemNotToggled) + { + const ToggleDepartureCoordinationList list = GetList(true); + + UKControllerPlugin::Plugin::PopupMenuItem expected{ + "Toggle Departure Coordination List", "", 2, EuroScopePlugIn::POPUP_ELEMENT_CHECKED, false, false}; + + EXPECT_EQ(expected, list.GetConfigurationMenuItem()); + } + + TEST_F(ToggleDepartureCoordinationListTest, ItReturnsAConfigurationItemToggled) + { + const ToggleDepartureCoordinationList list = GetList(false); + + UKControllerPlugin::Plugin::PopupMenuItem expected{ + "Toggle Departure Coordination List", "", 2, EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, false, false}; + + EXPECT_EQ(expected, list.GetConfigurationMenuItem()); + } + + TEST_F(ToggleDepartureCoordinationListTest, ClickingTheItemTogglesTheList) + { + ToggleDepartureCoordinationList toggleList = GetList(true); + EXPECT_TRUE(list->IsVisible()); + toggleList.Configure(1, "", {}); + EXPECT_FALSE(list->IsVisible()); + toggleList.Configure(1, "", {}); + EXPECT_TRUE(list->IsVisible()); + } +} // namespace UKControllerPluginTest::Departure diff --git a/test/plugin/prenote/PendingPrenoteListTest.cpp b/test/plugin/prenote/PendingPrenoteListTest.cpp deleted file mode 100644 index 08917a9f6..000000000 --- a/test/plugin/prenote/PendingPrenoteListTest.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include "controller/ActiveCallsignCollection.h" -#include "controller/ControllerPosition.h" -#include "controller/ControllerPositionCollection.h" -#include "euroscope/UserSetting.h" -#include "prenote/AcknowledgePrenoteMessage.h" -#include "prenote/PendingPrenoteList.h" -#include "prenote/PrenoteMessage.h" -#include "prenote/PrenoteMessageCollection.h" -#include "time/SystemClock.h" - -using testing::Test; -using UKControllerPlugin::Prenote::AcknowledgePrenoteMessage; -using UKControllerPlugin::Prenote::PendingPrenoteList; -using UKControllerPlugin::Prenote::PrenoteMessage; -using UKControllerPlugin::Prenote::PrenoteMessageCollection; -using UKControllerPlugin::Time::TimeNow; - -namespace UKControllerPluginTest::Prenote { - - class PendingPrenoteListTest : public Test - { - public: - PendingPrenoteListTest() - : messages(std::make_shared()), - acknowledge(std::make_shared(messages, activeCallsigns, mockTaskRunner, api)), - userSettings(mockAsrProvider), list(messages, acknowledge, mockPlugin, controllers, activeCallsigns, 1) - { - this->pluginReturnedFlightplan = - std::make_shared>(); - - ON_CALL(*this->pluginReturnedFlightplan, GetCallsign).WillByDefault(testing::Return("BAW123")); - - // Add positions and releases - auto message = std::make_shared(1, "BAW123", "EGGD", "BADIM1X", "EGLL", 3, 2, TimeNow()); - messages->Add(message); - auto position = std::make_shared( - 2, "EGFF_APP", 125.850, std::vector{"EGGD", "EGFF"}, true, true); - controllers.AddPosition(position); - auto controllerCallsign = - std::make_shared("EGFF_APP", "Test 1", *position, true); - this->activeCallsigns.AddUserCallsign(*controllerCallsign); - } - - testing::NiceMock api; - testing::NiceMock mockTaskRunner; - std::shared_ptr messages; - UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; - std::shared_ptr message; - std::shared_ptr acknowledge; - testing::NiceMock mockAsrProvider; - UKControllerPlugin::Euroscope::UserSetting userSettings; - std::shared_ptr> pluginReturnedFlightplan; - UKControllerPlugin::Controller::ControllerPositionCollection controllers; - testing::NiceMock mockPlugin; - testing::NiceMock mockRadarScreen; - PendingPrenoteList list; - }; - - TEST_F(PendingPrenoteListTest, LeftClickCollapseButtonTogglesCollapsedContent) - { - this->list.LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_TRUE(this->list.ContentCollapsed()); - this->list.LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_FALSE(this->list.ContentCollapsed()); - this->list.LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_TRUE(this->list.ContentCollapsed()); - } - - TEST_F(PendingPrenoteListTest, LeftClickCloseButtonClosesWindow) - { - EXPECT_FALSE(this->list.IsVisible()); - this->list.ToggleVisible(); - EXPECT_TRUE(this->list.IsVisible()); - this->list.LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); - EXPECT_FALSE(this->list.IsVisible()); - this->list.LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); - EXPECT_FALSE(this->list.IsVisible()); - } - - TEST_F(PendingPrenoteListTest, LeftClickACallsignAcknowledgesTheMessage) - { - ON_CALL(this->mockPlugin, GetFlightplanForCallsign("BAW123")) - .WillByDefault(Return(this->pluginReturnedFlightplan)); - - EXPECT_CALL(api, AcknowledgePrenoteMessage(1, 2)).Times(1); - - this->list.LeftClick(mockRadarScreen, 1, "BAW123", {}, {}); - } - - TEST_F(PendingPrenoteListTest, LeftClickACallsignDoesntToggleMenuIfNoFlightplan) - { - ON_CALL(this->mockPlugin, GetFlightplanForCallsign("BAW123")).WillByDefault(testing::Return(nullptr)); - - EXPECT_CALL(api, AcknowledgePrenoteMessage(testing::_, testing::_)).Times(0); - - this->list.LeftClick(mockRadarScreen, 1, "BAW123", {}, {}); - } - - TEST_F(PendingPrenoteListTest, ItLoadsDefaultVisiblityFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListVisible")).Times(1).WillOnce(testing::Return("")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_FALSE(this->list.IsVisible()); - } - - TEST_F(PendingPrenoteListTest, ItLoadsVisibilityFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListVisible")) - .Times(1) - .WillOnce(testing::Return("1")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list.IsVisible()); - } - - TEST_F(PendingPrenoteListTest, ItLoadsDefaultContentCollapseFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListContentCollapsed")) - .Times(1) - .WillOnce(testing::Return("")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_FALSE(this->list.ContentCollapsed()); - } - - TEST_F(PendingPrenoteListTest, ItLoadsContentCollapsedFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListContentCollapsed")) - .Times(1) - .WillOnce(testing::Return("1")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list.ContentCollapsed()); - } - - TEST_F(PendingPrenoteListTest, ItLoadsDefaultPositionFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListXPosition")) - .Times(1) - .WillOnce(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListYPosition")) - .Times(1) - .WillOnce(testing::Return("")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list.Position().Equals(Gdiplus::PointF{100.0F, 100.0F})); - } - - TEST_F(PendingPrenoteListTest, ItLoadsPositionFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListXPosition")) - .Times(1) - .WillOnce(testing::Return("250")); - - EXPECT_CALL(mockAsrProvider, GetKey("pendingPrenoteMessageListYPosition")) - .Times(1) - .WillOnce(testing::Return("150")); - - this->list.AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list.Position().Equals(Gdiplus::PointF{250.0F, 150.0F})); - } - - TEST_F(PendingPrenoteListTest, ItSavesEverythingToAsrOnClose) - { - this->list.Move({100, 200, 300, 400}, ""); - EXPECT_CALL(mockAsrProvider, SetKey("pendingPrenoteMessageListVisible", "Pending Prenote List Visible", "0")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, - SetKey("pendingPrenoteMessageListContentCollapsed", "Pending Prenote List Content Collapsed", "0")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, SetKey("pendingPrenoteMessageListXPosition", "Pending Prenote List X Position", "100")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, SetKey("pendingPrenoteMessageListYPosition", "Pending Prenote List Y Position", "200")) - .Times(1); - - this->list.AsrClosingEvent(userSettings); - } -} // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/PrenoteMessageTest.cpp b/test/plugin/prenote/PrenoteMessageTest.cpp index 0552963d2..b4576632c 100644 --- a/test/plugin/prenote/PrenoteMessageTest.cpp +++ b/test/plugin/prenote/PrenoteMessageTest.cpp @@ -75,4 +75,9 @@ namespace UKControllerPluginTest::Prenote { message->Acknowledge(); EXPECT_EQ(TimeNow(), message->GetAcknowledgedAt()); } + + TEST_F(PrenoteMessageTest, AcknowledgingSetsTheCreatedTime) + { + EXPECT_EQ(TimeNow(), message->GetCreatedAt()); + } } // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/PrenoteModuleTest.cpp b/test/plugin/prenote/PrenoteModuleTest.cpp index ebdba5810..299fdf1b8 100644 --- a/test/plugin/prenote/PrenoteModuleTest.cpp +++ b/test/plugin/prenote/PrenoteModuleTest.cpp @@ -5,6 +5,7 @@ #include "flightplan/FlightPlanEventHandlerCollection.h" #include "message/UserMessager.h" #include "plugin/FunctionCallEventHandler.h" +#include "prenote/PrenoteMessageCollection.h" #include "prenote/PrenoteModule.h" #include "push/PushEventProcessorCollection.h" #include "radarscreen/ConfigurableDisplayCollection.h" @@ -135,29 +136,16 @@ namespace UKControllerPluginTest::Prenote { EXPECT_TRUE(container.pluginFunctionHandlers->HasTagFunction(9019)); } - TEST_F(PrenoteModuleTest, ItRegistersRenderables) + TEST_F(PrenoteModuleTest, ItRegistersPrenoteCollectionWithContainer) { - PrenoteModule::BootstrapRadarScreen(container, radarRenderables, configurableDisplays, asrHandlers); - EXPECT_EQ(2, radarRenderables.CountRenderers()); - EXPECT_EQ(2, radarRenderables.CountRenderersInPhase(radarRenderables.afterLists)); - } - - TEST_F(PrenoteModuleTest, ItRegistersRenderedScreenObjects) - { - PrenoteModule::BootstrapRadarScreen(container, radarRenderables, configurableDisplays, asrHandlers); - EXPECT_EQ(1, radarRenderables.CountScreenObjects()); - } - - TEST_F(PrenoteModuleTest, ItRegistersTogglePendingList) - { - PrenoteModule::BootstrapRadarScreen(container, radarRenderables, configurableDisplays, asrHandlers); - EXPECT_EQ(1, configurableDisplays.CountDisplays()); - EXPECT_TRUE(container.pluginFunctionHandlers->HasCallbackByDescription("Toggle Pending Prenote List")); + PrenoteModule::BootstrapPlugin(container, dependency); + EXPECT_EQ(0, container.prenotes->Count()); } - TEST_F(PrenoteModuleTest, ItRegistersPendingListForAsrEvents) + TEST_F(PrenoteModuleTest, ItRegistersRenderables) { - PrenoteModule::BootstrapRadarScreen(container, radarRenderables, configurableDisplays, asrHandlers); - EXPECT_EQ(1, asrHandlers.CountHandlers()); + PrenoteModule::BootstrapRadarScreen(container, radarRenderables); + EXPECT_EQ(1, radarRenderables.CountRenderers()); + EXPECT_EQ(1, radarRenderables.CountRenderersInPhase(radarRenderables.afterLists)); } } // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/prenote/TogglePendingPrenoteListTest.cpp b/test/plugin/prenote/TogglePendingPrenoteListTest.cpp deleted file mode 100644 index 95e4c68ae..000000000 --- a/test/plugin/prenote/TogglePendingPrenoteListTest.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "controller/ActiveCallsignCollection.h" -#include "controller/ControllerPositionCollection.h" -#include "prenote/PendingPrenoteList.h" -#include "prenote/PrenoteMessageCollection.h" -#include "prenote/TogglePendingPrenoteList.h" - -using testing::Test; -using UKControllerPlugin::Prenote::PendingPrenoteList; -using UKControllerPlugin::Prenote::PrenoteMessageCollection; -using UKControllerPlugin::Prenote::TogglePendingPrenoteList; - -namespace UKControllerPluginTest::Prenote { - - class TogglePendingPrenoteListTest : public Test - { - public: - TogglePendingPrenoteListTest() - : messages(std::make_shared()), - list(std::make_shared(nullptr, nullptr, mockPlugin, controllers, activeCallsigns, 1)) - { - } - - TogglePendingPrenoteList GetList(bool alreadyToggled) const - { - if (alreadyToggled) { - list->ToggleVisible(); - } - - return {list, 55}; - } - - std::shared_ptr messages; - UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; - UKControllerPlugin::Controller::ControllerPositionCollection controllers; - testing::NiceMock mockPlugin; - std::shared_ptr list; - }; - - TEST_F(TogglePendingPrenoteListTest, ItReturnsAConfigurationItemNotToggled) - { - auto toggle = GetList(true); - - UKControllerPlugin::Plugin::PopupMenuItem expected{ - "Toggle Pending Prenote List", "", 55, EuroScopePlugIn::POPUP_ELEMENT_CHECKED, false, false}; - - EXPECT_EQ(expected, toggle.GetConfigurationMenuItem()); - } - - TEST_F(TogglePendingPrenoteListTest, ItReturnsAConfigurationItemToggled) - { - auto toggle = GetList(false); - - UKControllerPlugin::Plugin::PopupMenuItem expected{ - "Toggle Pending Prenote List", "", 55, EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, false, false}; - - EXPECT_EQ(expected, toggle.GetConfigurationMenuItem()); - } - - TEST_F(TogglePendingPrenoteListTest, ClickingTheItemTogglesTheList) - { - auto toggle = GetList(true); - EXPECT_TRUE(list->IsVisible()); - toggle.Configure(1, "", {}); - EXPECT_FALSE(list->IsVisible()); - toggle.Configure(1, "", {}); - EXPECT_TRUE(list->IsVisible()); - } -} // namespace UKControllerPluginTest::Prenote diff --git a/test/plugin/releases/DepartureReleaseDecisionListTest.cpp b/test/plugin/releases/DepartureReleaseDecisionListTest.cpp deleted file mode 100644 index 81c20e6a3..000000000 --- a/test/plugin/releases/DepartureReleaseDecisionListTest.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "controller/ActiveCallsignCollection.h" -#include "controller/ControllerPosition.h" -#include "controller/ControllerPositionCollection.h" -#include "dialog/DialogManager.h" -#include "euroscope/UserSetting.h" -#include "message/UserMessager.h" -#include "releases/DepartureReleaseDecisionList.h" -#include "releases/DepartureReleaseEventHandler.h" -#include "releases/DepartureReleaseRequest.h" - -using testing::Test; -using UKControllerPlugin::Message::UserMessager; - -namespace UKControllerPluginTest { - namespace Releases { - - class DepartureReleaseDecisionListTest : public Test - { - public: - DepartureReleaseDecisionListTest() - : messager(mockPlugin), userSettings(mockAsrProvider), - list(new UKControllerPlugin::Releases::DepartureReleaseDecisionList( - handler, mockPlugin, controllers, 3)), - handler( - mockApi, - taskRunner, - mockPlugin, - controllers, - activeCallsigns, - dialogManager, - windows, - messager, - 103, - 104), - dialogManager(dialogProvider) - { - this->pluginReturnedFlightplan = - std::make_shared>(); - - ON_CALL(*this->pluginReturnedFlightplan, GetCallsign).WillByDefault(testing::Return("BAW123")); - - this->pluginReturnedRadarTarget = - std::make_shared>(); - - // Add positions and releases - auto request = std::make_shared( - 1, "BAW123", 3, 2, std::chrono::system_clock::now() + std::chrono::minutes(5)); - handler.AddReleaseRequest(request); - auto position = std::make_shared( - 2, "EGFF_APP", 125.850, std::vector{"EGGD", "EGFF"}, true, true); - controllers.AddPosition(position); - auto controllerCallsign = std::make_shared( - "EGFF_APP", "Test 1", *position, true); - this->activeCallsigns.AddUserCallsign(*controllerCallsign); - } - - UserMessager messager; - testing::NiceMock mockAsrProvider; - UKControllerPlugin::Euroscope::UserSetting userSettings; - std::shared_ptr> pluginReturnedFlightplan; - std::shared_ptr> pluginReturnedRadarTarget; - std::shared_ptr list; - UKControllerPlugin::Releases::DepartureReleaseEventHandler handler; - UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; - testing::NiceMock dialogProvider; - testing::NiceMock api; - testing::NiceMock windows; - UKControllerPlugin::Dialog::DialogManager dialogManager; - UKControllerPlugin::Controller::ControllerPositionCollection controllers; - testing::NiceMock mockPlugin; - testing::NiceMock mockRadarScreen; - testing::NiceMock mockApi; - TaskManager::MockTaskRunnerInterface taskRunner; - }; - - TEST_F(DepartureReleaseDecisionListTest, LeftClickCollapseButtonTogglesCollapsedContent) - { - this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_TRUE(this->list->ContentCollapsed()); - this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_FALSE(this->list->ContentCollapsed()); - this->list->LeftClick(mockRadarScreen, 1, "collapseButton", {}, {}); - EXPECT_TRUE(this->list->ContentCollapsed()); - } - - TEST_F(DepartureReleaseDecisionListTest, LeftClickCloseButtonClosesWindow) - { - EXPECT_FALSE(this->list->IsVisible()); - this->list->ToggleVisible(); - EXPECT_TRUE(this->list->IsVisible()); - this->list->LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); - EXPECT_FALSE(this->list->IsVisible()); - this->list->LeftClick(mockRadarScreen, 1, "closeButton", {}, {}); - EXPECT_FALSE(this->list->IsVisible()); - } - - TEST_F(DepartureReleaseDecisionListTest, LeftClickACallsignTogglesDecisionMenu) - { - ON_CALL(this->mockPlugin, GetFlightplanForCallsign("BAW123")) - .WillByDefault(Return(this->pluginReturnedFlightplan)); - - ON_CALL(this->mockPlugin, GetRadarTargetForCallsign("BAW123")) - .WillByDefault(Return(this->pluginReturnedRadarTarget)); - - EXPECT_CALL(this->mockPlugin, TriggerPopupList(testing::_, "Departure Release Decision", 1)).Times(1); - - this->list->LeftClick(mockRadarScreen, 1, "BAW123", {}, {}); - } - - TEST_F(DepartureReleaseDecisionListTest, LeftClickACallsignDoesntToggleMenuIfNoFlightplan) - { - ON_CALL(this->mockPlugin, GetFlightplanForCallsign("BAW123")).WillByDefault(testing::Return(nullptr)); - - ON_CALL(this->mockPlugin, GetRadarTargetForCallsign("BAW123")) - .WillByDefault(Return(this->pluginReturnedRadarTarget)); - - EXPECT_CALL(this->mockPlugin, TriggerPopupList(testing::_, "Departure Release Decision", 1)).Times(0); - - this->list->LeftClick(mockRadarScreen, 1, "BAW123", {}, {}); - } - - TEST_F(DepartureReleaseDecisionListTest, LeftClickACallsignDoesntToggleMenuIfNoRadarTarget) - { - ON_CALL(this->mockPlugin, GetFlightplanForCallsign("BAW123")) - .WillByDefault(Return(this->pluginReturnedFlightplan)); - - ON_CALL(this->mockPlugin, GetRadarTargetForCallsign("BAW123")).WillByDefault(testing::Return(nullptr)); - - EXPECT_CALL(this->mockPlugin, TriggerPopupList(testing::_, "Departure Release Decision", 1)).Times(0); - - this->list->LeftClick(mockRadarScreen, 1, "BAW123", {}, {}); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsDefaultVisiblityFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListVisible")) - .Times(1) - .WillOnce(testing::Return("")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_FALSE(this->list->IsVisible()); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsVisibilityFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListVisible")) - .Times(1) - .WillOnce(testing::Return("1")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list->IsVisible()); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsDefaultContentCollapseFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListContentCollapsed")) - .Times(1) - .WillOnce(testing::Return("")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_FALSE(this->list->ContentCollapsed()); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsContentCollapsedFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListContentCollapsed")) - .Times(1) - .WillOnce(testing::Return("1")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list->ContentCollapsed()); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsDefaultPositionFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListXPosition")) - .Times(1) - .WillOnce(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListYPosition")) - .Times(1) - .WillOnce(testing::Return("")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list->Position().Equals(Gdiplus::PointF{100.0f, 100.0f})); - } - - TEST_F(DepartureReleaseDecisionListTest, ItLoadsPositionFromAsr) - { - EXPECT_CALL(mockAsrProvider, GetKey(testing::_)).WillRepeatedly(testing::Return("")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListXPosition")) - .Times(1) - .WillOnce(testing::Return("250")); - - EXPECT_CALL(mockAsrProvider, GetKey("departureReleaseRequestListYPosition")) - .Times(1) - .WillOnce(testing::Return("150")); - - this->list->AsrLoadedEvent(userSettings); - - EXPECT_TRUE(this->list->Position().Equals(Gdiplus::PointF{250.0f, 150.0f})); - } - - TEST_F(DepartureReleaseDecisionListTest, ItSavesEverythingToAsrOnClose) - { - this->list->Move({100, 200, 300, 400}, ""); - EXPECT_CALL( - mockAsrProvider, - SetKey("departureReleaseRequestListVisible", "Departure Release Request List Visible", "0")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, - SetKey( - "departureReleaseRequestListContentCollapsed", - "Departure Release Request List Content Collapsed", - "0")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, - SetKey("departureReleaseRequestListXPosition", "Departure Release Request List X Position", "100")) - .Times(1); - - EXPECT_CALL( - mockAsrProvider, - SetKey("departureReleaseRequestListYPosition", "Departure Release Request List Y Position", "200")) - .Times(1); - - this->list->AsrClosingEvent(userSettings); - } - } // namespace Releases -} // namespace UKControllerPluginTest diff --git a/test/plugin/releases/DepartureReleaseRequestTest.cpp b/test/plugin/releases/DepartureReleaseRequestTest.cpp index d830171d7..3c700a011 100644 --- a/test/plugin/releases/DepartureReleaseRequestTest.cpp +++ b/test/plugin/releases/DepartureReleaseRequestTest.cpp @@ -3,187 +3,187 @@ using testing::Test; using UKControllerPlugin::Releases::DepartureReleaseRequest; - -namespace UKControllerPluginTest { - namespace Releases { - - class DepartureReleaseRequestTest : public Test - { - public: - DepartureReleaseRequestTest() - : requestExpiresAt(std::chrono::system_clock::now() + std::chrono::minutes(3)), - request(1, "BAW123", 2, 3, requestExpiresAt) - { - UKControllerPlugin::Time::SetTestNow(std::chrono::system_clock::now()); - } - - std::chrono::system_clock::time_point requestExpiresAt; - DepartureReleaseRequest request; - }; - - TEST_F(DepartureReleaseRequestTest, ItHasAnId) - { - EXPECT_EQ(1, request.Id()); - } - - TEST_F(DepartureReleaseRequestTest, ItHasACallsign) - { - EXPECT_EQ("BAW123", request.Callsign()); - } - - TEST_F(DepartureReleaseRequestTest, ItHasARequestingController) - { - EXPECT_EQ(2, request.RequestingController()); - } - - TEST_F(DepartureReleaseRequestTest, ItHasATargetController) - { - EXPECT_EQ(3, request.TargetController()); - } - - TEST_F(DepartureReleaseRequestTest, ItHasARequestExpiryTime) - { - EXPECT_EQ(requestExpiresAt, request.RequestExpiryTime()); - } - - TEST_F(DepartureReleaseRequestTest, ItStartsNotAcknowledged) - { - EXPECT_FALSE(request.Acknowledged()); - } - - TEST_F(DepartureReleaseRequestTest, ItStartsNotApproved) - { - EXPECT_FALSE(request.Approved()); - } - - TEST_F(DepartureReleaseRequestTest, ItStartsNotRejected) - { - EXPECT_FALSE(request.Rejected()); - } - - TEST_F(DepartureReleaseRequestTest, ItStarsWithNoRemarks) - { - EXPECT_TRUE(request.Remarks().empty()); - } - - TEST_F(DepartureReleaseRequestTest, ItCanBeAcknowledged) - { - request.Acknowledge(); - EXPECT_TRUE(request.Acknowledged()); - } - - TEST_F(DepartureReleaseRequestTest, AcknowledgingTheRequestSetsAcknowledgeTime) - { - request.Acknowledge(); - EXPECT_TRUE(std::chrono::system_clock::now() - request.AcknowledgedAtTime() < std::chrono::seconds(5)); - } - - TEST_F(DepartureReleaseRequestTest, ItCanBeRejected) - { - request.Reject("Remarks"); - EXPECT_TRUE(request.Rejected()); - } - - TEST_F(DepartureReleaseRequestTest, RejectingTheRequestSetsRejectTime) - { - request.Reject("Remarks"); - EXPECT_TRUE(std::chrono::system_clock::now() - request.RejectedAtTime() < std::chrono::seconds(5)); - } - - TEST_F(DepartureReleaseRequestTest, RejectingTheRequestSetsRemarks) - { - request.Reject("Remarks"); - EXPECT_EQ("Remarks", request.Remarks()); - } - - TEST_F(DepartureReleaseRequestTest, ItCanBeApproved) - { - request.Approve(std::chrono::system_clock::now(), std::chrono::system_clock::now(), "remarks"); - EXPECT_TRUE(request.Approved()); - EXPECT_FALSE(request.ApprovedWithNoExpiry()); - EXPECT_EQ("remarks", request.Remarks()); - } - - TEST_F(DepartureReleaseRequestTest, ItCanBeApprovedWithNoExpiryTime) - { - request.Approve(std::chrono::system_clock::now(), "remarks"); - EXPECT_TRUE(request.Approved()); - EXPECT_TRUE(request.ApprovedWithNoExpiry()); - EXPECT_EQ("remarks", request.Remarks()); - } - - TEST_F(DepartureReleaseRequestTest, ApprovingTheRequestSetsReleasedAtTime) - { - std::chrono::system_clock::time_point releasedAt = - std::chrono::system_clock::now() + std::chrono::minutes(1); - std::chrono::system_clock::time_point releaseExpiresAt = - std::chrono::system_clock::now() + std::chrono::minutes(2); - request.Approve(releasedAt, releaseExpiresAt, "remarks"); - EXPECT_EQ(releasedAt, request.ReleasedAtTime()); - } - - TEST_F(DepartureReleaseRequestTest, ApprovingTheRequestSetsReleaseExpiryTime) - { - std::chrono::system_clock::time_point releasedAt = - std::chrono::system_clock::now() + std::chrono::minutes(1); - std::chrono::system_clock::time_point releaseExpiresAt = - std::chrono::system_clock::now() + std::chrono::minutes(2); - request.Approve(releasedAt, releaseExpiresAt, "remarks"); - EXPECT_EQ(releaseExpiresAt, request.ReleaseExpiryTime()); - } - - TEST_F(DepartureReleaseRequestTest, RequestNotExpiredIfTimeHasNotPassed) - { - EXPECT_FALSE(this->request.RequestExpired()); - } - - TEST_F(DepartureReleaseRequestTest, RequestExpiredIfTimePassed) - { - UKControllerPlugin::Time::SetTestNow(std::chrono::system_clock::now() + std::chrono::minutes(4)); - EXPECT_TRUE(this->request.RequestExpired()); - } - - TEST_F(DepartureReleaseRequestTest, RequestRequiresDecision) - { - EXPECT_TRUE(this->request.RequiresDecision()); - } - - TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfExpired) - { - UKControllerPlugin::Time::SetTestNow(std::chrono::system_clock::now() + std::chrono::minutes(4)); - EXPECT_FALSE(this->request.RequiresDecision()); - } - - TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfAlreadyApproved) - { - request.Approve(std::chrono::system_clock::now(), std::chrono::system_clock::now(), ""); - EXPECT_FALSE(this->request.RequiresDecision()); - } - - TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfAlreadyRejected) - { - request.Reject("Remarks"); - EXPECT_FALSE(this->request.RequiresDecision()); - } - - TEST_F(DepartureReleaseRequestTest, RequestsCanBePendingReleasedAtTime) - { - std::chrono::system_clock::time_point releasedAt = - std::chrono::system_clock::now() + std::chrono::minutes(1); - std::chrono::system_clock::time_point releaseExpiresAt = - std::chrono::system_clock::now() + std::chrono::minutes(2); - request.Approve(releasedAt, releaseExpiresAt, ""); - EXPECT_TRUE(this->request.AwaitingReleasedTime()); - } - - TEST_F(DepartureReleaseRequestTest, RequestsCanBeReadyToGo) - { - std::chrono::system_clock::time_point releasedAt = - std::chrono::system_clock::now() - std::chrono::minutes(1); - std::chrono::system_clock::time_point releaseExpiresAt = - std::chrono::system_clock::now() + std::chrono::minutes(2); - request.Approve(releasedAt, releaseExpiresAt, ""); - EXPECT_FALSE(this->request.AwaitingReleasedTime()); - } - } // namespace Releases -} // namespace UKControllerPluginTest +using UKControllerPlugin::Time::SetTestNow; +using UKControllerPlugin::Time::TimeNow; + +namespace UKControllerPluginTes::Releases { + + class DepartureReleaseRequestTest : public Test + { + public: + DepartureReleaseRequestTest() : requestExpiresAt(std::chrono::system_clock::now() + std::chrono::minutes(3)) + { + SetTestNow(std::chrono::system_clock::now()); + request = std::make_unique(1, "BAW123", 2, 3, requestExpiresAt); + } + + std::chrono::system_clock::time_point requestExpiresAt; + std::unique_ptr request; + }; + + TEST_F(DepartureReleaseRequestTest, ItHasAnId) + { + EXPECT_EQ(1, request->Id()); + } + + TEST_F(DepartureReleaseRequestTest, ItHasACallsign) + { + EXPECT_EQ("BAW123", request->Callsign()); + } + + TEST_F(DepartureReleaseRequestTest, ItHasARequestingController) + { + EXPECT_EQ(2, request->RequestingController()); + } + + TEST_F(DepartureReleaseRequestTest, ItHasATargetController) + { + EXPECT_EQ(3, request->TargetController()); + } + + TEST_F(DepartureReleaseRequestTest, ItHasARequestExpiryTime) + { + EXPECT_EQ(requestExpiresAt, request->RequestExpiryTime()); + } + + TEST_F(DepartureReleaseRequestTest, ItStartsNotAcknowledged) + { + EXPECT_FALSE(request->Acknowledged()); + } + + TEST_F(DepartureReleaseRequestTest, ItStartsNotApproved) + { + EXPECT_FALSE(request->Approved()); + } + + TEST_F(DepartureReleaseRequestTest, ItStartsNotRejected) + { + EXPECT_FALSE(request->Rejected()); + } + + TEST_F(DepartureReleaseRequestTest, ItStarsWithNoRemarks) + { + EXPECT_TRUE(request->Remarks().empty()); + } + + TEST_F(DepartureReleaseRequestTest, ItCanBeAcknowledged) + { + request->Acknowledge(); + EXPECT_TRUE(request->Acknowledged()); + } + + TEST_F(DepartureReleaseRequestTest, AcknowledgingTheRequestSetsAcknowledgeTime) + { + request->Acknowledge(); + EXPECT_TRUE(std::chrono::system_clock::now() - request->AcknowledgedAtTime() < std::chrono::seconds(5)); + } + + TEST_F(DepartureReleaseRequestTest, ItCanBeRejected) + { + request->Reject("Remarks"); + EXPECT_TRUE(request->Rejected()); + } + + TEST_F(DepartureReleaseRequestTest, RejectingTheRequestSetsRejectTime) + { + request->Reject("Remarks"); + EXPECT_TRUE(std::chrono::system_clock::now() - request->RejectedAtTime() < std::chrono::seconds(5)); + } + + TEST_F(DepartureReleaseRequestTest, RejectingTheRequestSetsRemarks) + { + request->Reject("Remarks"); + EXPECT_EQ("Remarks", request->Remarks()); + } + + TEST_F(DepartureReleaseRequestTest, ItCanBeApproved) + { + request->Approve(std::chrono::system_clock::now(), std::chrono::system_clock::now(), "remarks"); + EXPECT_TRUE(request->Approved()); + EXPECT_FALSE(request->ApprovedWithNoExpiry()); + EXPECT_EQ("remarks", request->Remarks()); + } + + TEST_F(DepartureReleaseRequestTest, ItCanBeApprovedWithNoExpiryTime) + { + request->Approve(std::chrono::system_clock::now(), "remarks"); + EXPECT_TRUE(request->Approved()); + EXPECT_TRUE(request->ApprovedWithNoExpiry()); + EXPECT_EQ("remarks", request->Remarks()); + } + + TEST_F(DepartureReleaseRequestTest, ApprovingTheRequestSetsReleasedAtTime) + { + std::chrono::system_clock::time_point releasedAt = std::chrono::system_clock::now() + std::chrono::minutes(1); + std::chrono::system_clock::time_point releaseExpiresAt = + std::chrono::system_clock::now() + std::chrono::minutes(2); + request->Approve(releasedAt, releaseExpiresAt, "remarks"); + EXPECT_EQ(releasedAt, request->ReleasedAtTime()); + } + + TEST_F(DepartureReleaseRequestTest, ApprovingTheRequestSetsReleaseExpiryTime) + { + std::chrono::system_clock::time_point releasedAt = std::chrono::system_clock::now() + std::chrono::minutes(1); + std::chrono::system_clock::time_point releaseExpiresAt = + std::chrono::system_clock::now() + std::chrono::minutes(2); + request->Approve(releasedAt, releaseExpiresAt, "remarks"); + EXPECT_EQ(releaseExpiresAt, request->ReleaseExpiryTime()); + } + + TEST_F(DepartureReleaseRequestTest, RequestNotExpiredIfTimeHasNotPassed) + { + EXPECT_FALSE(this->request->RequestExpired()); + } + + TEST_F(DepartureReleaseRequestTest, RequestExpiredIfTimePassed) + { + UKControllerPlugin::Time::SetTestNow(std::chrono::system_clock::now() + std::chrono::minutes(4)); + EXPECT_TRUE(this->request->RequestExpired()); + } + + TEST_F(DepartureReleaseRequestTest, RequestRequiresDecision) + { + EXPECT_TRUE(this->request->RequiresDecision()); + } + + TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfExpired) + { + UKControllerPlugin::Time::SetTestNow(std::chrono::system_clock::now() + std::chrono::minutes(4)); + EXPECT_FALSE(this->request->RequiresDecision()); + } + + TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfAlreadyApproved) + { + request->Approve(std::chrono::system_clock::now(), std::chrono::system_clock::now(), ""); + EXPECT_FALSE(this->request->RequiresDecision()); + } + + TEST_F(DepartureReleaseRequestTest, RequestDoesNotRequireDecisionIfAlreadyRejected) + { + request->Reject("Remarks"); + EXPECT_FALSE(this->request->RequiresDecision()); + } + + TEST_F(DepartureReleaseRequestTest, RequestsCanBePendingReleasedAtTime) + { + std::chrono::system_clock::time_point releasedAt = std::chrono::system_clock::now() + std::chrono::minutes(1); + std::chrono::system_clock::time_point releaseExpiresAt = + std::chrono::system_clock::now() + std::chrono::minutes(2); + request->Approve(releasedAt, releaseExpiresAt, ""); + EXPECT_TRUE(this->request->AwaitingReleasedTime()); + } + + TEST_F(DepartureReleaseRequestTest, RequestsCanBeReadyToGo) + { + std::chrono::system_clock::time_point releasedAt = std::chrono::system_clock::now() - std::chrono::minutes(1); + std::chrono::system_clock::time_point releaseExpiresAt = + std::chrono::system_clock::now() + std::chrono::minutes(2); + request->Approve(releasedAt, releaseExpiresAt, ""); + EXPECT_FALSE(this->request->AwaitingReleasedTime()); + } + + TEST_F(DepartureReleaseRequestTest, ItHasACreatedAtTime) + { + EXPECT_EQ(TimeNow(), request->CreatedAt()); + } +} // namespace UKControllerPluginTes::Releases diff --git a/test/plugin/releases/ReleaseModuleTest.cpp b/test/plugin/releases/ReleaseModuleTest.cpp index 4c300eb39..e29812ab6 100644 --- a/test/plugin/releases/ReleaseModuleTest.cpp +++ b/test/plugin/releases/ReleaseModuleTest.cpp @@ -6,9 +6,7 @@ #include "plugin/FunctionCallEventHandler.h" #include "controller/HandoffEventHandlerCollection.h" #include "dialog/DialogManager.h" -#include "euroscope/AsrEventHandlerCollection.h" #include "radarscreen/RadarRenderableCollection.h" -#include "radarscreen/ConfigurableDisplayCollection.h" using ::testing::NiceMock; using ::testing::Return; @@ -18,7 +16,6 @@ using UKControllerPlugin::Controller::HandoffEventHandlerCollection; using UKControllerPlugin::Dialog::DialogManager; using UKControllerPlugin::Plugin::FunctionCallEventHandler; using UKControllerPlugin::Push::PushEventProcessorCollection; -using UKControllerPlugin::RadarScreen::ConfigurableDisplayCollection; using UKControllerPlugin::RadarScreen::RadarRenderableCollection; using UKControllerPlugin::Releases::BootstrapPlugin; using UKControllerPlugin::Releases::BootstrapRadarScreen; @@ -57,8 +54,6 @@ namespace UKControllerPluginTest { NiceMock dependencyLoader; PersistenceContainer container; RadarRenderableCollection renderables; - ConfigurableDisplayCollection configurables; - UKControllerPlugin::Euroscope::AsrEventHandlerCollection asr; }; TEST_F(ReleaseModuleTest, ItRegistersForEnroutePushEvents) @@ -167,21 +162,8 @@ namespace UKControllerPluginTest { TEST_F(ReleaseModuleTest, RadarScreenAddsRenderable) { - BootstrapRadarScreen(this->container, renderables, configurables, asr); - EXPECT_EQ(2, renderables.CountRenderers()); - } - - TEST_F(ReleaseModuleTest, RadarScreenAddsToAsr) - { - BootstrapRadarScreen(this->container, renderables, configurables, asr); - EXPECT_EQ(1, asr.CountHandlers()); - } - - TEST_F(ReleaseModuleTest, RadarScreenAddsReleaseRequestShowOption) - { - BootstrapRadarScreen(this->container, renderables, configurables, asr); - EXPECT_EQ(1, configurables.CountDisplays()); - EXPECT_EQ(1, this->container.pluginFunctionHandlers->CountCallbacks()); + BootstrapRadarScreen(this->container, renderables); + EXPECT_EQ(1, renderables.CountRenderers()); } TEST_F(ReleaseModuleTest, ItRegistersTheCancelRequestFunctions) diff --git a/test/plugin/releases/ToggleDepartureReleaseDecisionListTest.cpp b/test/plugin/releases/ToggleDepartureReleaseDecisionListTest.cpp deleted file mode 100644 index f79688cea..000000000 --- a/test/plugin/releases/ToggleDepartureReleaseDecisionListTest.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "controller/ActiveCallsignCollection.h" -#include "controller/ControllerPositionCollection.h" -#include "dialog/DialogManager.h" -#include "message/UserMessager.h" -#include "releases/ToggleDepartureReleaseDecisionList.h" -#include "releases/DepartureReleaseDecisionList.h" -#include "releases/DepartureReleaseEventHandler.h" - -using testing::Test; -using UKControllerPlugin::Message::UserMessager; -using UKControllerPlugin::Releases::ToggleDepartureReleaseDecisionList; - -namespace UKControllerPluginTest { - namespace Releases { - - class ToggleDepartureReleaseDecisionListTest : public Test - { - public: - ToggleDepartureReleaseDecisionListTest() - : messager(mockPlugin), handler( - mockApi, - taskRunner, - mockPlugin, - controllers, - activeCallsigns, - dialogManager, - windows, - messager, - 103, - 104), - list(new UKControllerPlugin::Releases::DepartureReleaseDecisionList( - handler, mockPlugin, controllers, 3)), - dialogManager(dialogProvider) - { - } - - ToggleDepartureReleaseDecisionList GetList(bool alreadyToggled) - { - if (alreadyToggled) { - list->ToggleVisible(); - } - - return ToggleDepartureReleaseDecisionList(list, 2); - } - - UserMessager messager; - UKControllerPlugin::Releases::DepartureReleaseEventHandler handler; - std::shared_ptr list; - UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns; - testing::NiceMock dialogProvider; - testing::NiceMock api; - UKControllerPlugin::Dialog::DialogManager dialogManager; - UKControllerPlugin::Controller::ControllerPositionCollection controllers; - testing::NiceMock mockPlugin; - testing::NiceMock mockApi; - testing::NiceMock windows; - TaskManager::MockTaskRunnerInterface taskRunner; - }; - - TEST_F(ToggleDepartureReleaseDecisionListTest, ItReturnsAConfigurationItemNotToggled) - { - const ToggleDepartureReleaseDecisionList list = GetList(true); - - UKControllerPlugin::Plugin::PopupMenuItem expected{ - "Toggle Departure Release Decision List", "", 2, EuroScopePlugIn::POPUP_ELEMENT_CHECKED, false, false}; - - EXPECT_EQ(expected, list.GetConfigurationMenuItem()); - } - - TEST_F(ToggleDepartureReleaseDecisionListTest, ItReturnsAConfigurationItemToggled) - { - const ToggleDepartureReleaseDecisionList list = GetList(false); - - UKControllerPlugin::Plugin::PopupMenuItem expected{ - "Toggle Departure Release Decision List", - "", - 2, - EuroScopePlugIn::POPUP_ELEMENT_UNCHECKED, - false, - false}; - - EXPECT_EQ(expected, list.GetConfigurationMenuItem()); - } - - TEST_F(ToggleDepartureReleaseDecisionListTest, ClickingTheItemTogglesTheList) - { - ToggleDepartureReleaseDecisionList toggleList = GetList(true); - EXPECT_TRUE(list->IsVisible()); - toggleList.Configure(1, "", {}); - EXPECT_FALSE(list->IsVisible()); - toggleList.Configure(1, "", {}); - EXPECT_TRUE(list->IsVisible()); - } - } // namespace Releases -} // namespace UKControllerPluginTest