ORE Studio 0.0.4
Loading...
Searching...
No Matches
PortfolioExplorerMdiWindow.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * Copyright (C) 2026 Marco Craveiro <marco.craveiro@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 3 of the License, or (at your option) any later
8 * version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20#ifndef ORES_QT_PORTFOLIO_EXPLORER_MDI_WINDOW_HPP
21#define ORES_QT_PORTFOLIO_EXPLORER_MDI_WINDOW_HPP
22
23#include <vector>
24#include <QLabel>
25#include <QList>
26#include <QAction>
27#include <QToolBar>
28#include <QSplitter>
29#include <QTreeView>
30#include <QWidget>
31#include <QTableView>
32#include <QDateTime>
33#include <QFutureWatcher>
34#include <QItemSelection>
35#include <QSortFilterProxyModel>
36#include <QToolButton>
37#include "ores.logging/make_logger.hpp"
38#include "ores.qt/ClientManager.hpp"
39#include "ores.qt/EntityListMdiWindow.hpp"
40#include "ores.qt/PaginationWidget.hpp"
41#include "ores.qt/PortfolioExplorerTreeModel.hpp"
42#include "ores.qt/PortfolioExplorerTradeModel.hpp"
43#include "ores.refdata.api/domain/portfolio.hpp"
44#include "ores.refdata.api/domain/book.hpp"
45
46namespace ores::qt {
47
48class BookController;
49class OreImportController;
50class PortfolioController;
51class TradeController;
52
61 Q_OBJECT
62
63private:
64 inline static std::string_view logger_name =
65 "ores.qt.portfolio_explorer_mdi_window";
66
67 [[nodiscard]] static auto& lg() {
68 using namespace ores::logging;
69 static auto instance = make_logger(logger_name);
70 return instance;
71 }
72
73 // Event names for subscription
74 static constexpr const char* book_event = "ores.refdata.book_changed";
75 static constexpr const char* portfolio_event = "ores.refdata.portfolio_changed";
76 static constexpr const char* trade_event = "ores.trading.trade_changed";
77
78public:
80 ClientManager* clientManager,
81 BookController* bookController,
82 PortfolioController* portfolioController,
83 TradeController* tradeController,
84 OreImportController* oreImportController,
85 const QString& username,
86 QWidget* parent = nullptr);
87 ~PortfolioExplorerMdiWindow() override = default;
88
89public slots:
95 void doReload() override;
96
97signals:
98 void statusChanged(const QString& msg);
99
100protected:
101 QString normalRefreshTooltip() const override {
102 return tr("Refresh portfolio/book tree");
103 }
104
105private slots:
106 void onTreeSelectionChanged(const QItemSelection& selected,
107 const QItemSelection& deselected);
108 void onNotificationReceived(const QString& eventType,
109 const QDateTime& timestamp,
110 const QStringList& entityIds,
111 const QString& tenantId);
112 void onPortfoliosLoaded();
113 void onBooksLoaded();
114 void onCounterpartiesLoaded();
115 void onAddRequested();
116 void onEditSelected();
117 void onDeleteSelected();
118 void onHistorySelected();
119 void onShowContextMenu(const QPoint& pos);
120 void onTradeDoubleClicked(const QModelIndex& index);
121 void updateActionStates();
122
123private:
124 bool eventFilter(QObject* obj, QEvent* event) override;
125 void setupUi();
126 void setupToolbar();
127 void setupTree();
128 void setupTradePanel();
129 void setupConnections();
130 void setupEventSubscriptions();
131 void rebuildTree();
132 void updateBreadcrumb(const PortfolioTreeNode* node);
133 void collectBookUuids(const QModelIndex& parent,
134 QList<boost::uuids::uuid>& uuids);
135 void onReparentRequested(const PortfolioTreeNode* node,
136 const boost::uuids::uuid& newParentId);
137
138 // Fetch result types
139 struct PortfolioFetchResult {
140 bool success;
141 std::vector<refdata::domain::portfolio> portfolios;
142 QString error_message;
143 QString error_details;
144 };
145
146 struct BookFetchResult {
147 bool success;
148 std::vector<refdata::domain::book> books;
149 QString error_message;
150 QString error_details;
151 };
152
153 struct CounterpartyFetchResult {
154 bool success;
155 std::unordered_map<std::string, CounterpartyInfo> cpty_map;
156 QString error_message;
157 QString error_details;
158 };
159
160 struct CountResult {
161 boost::uuids::uuid book_id;
162 std::uint32_t count{0};
163 bool success{false};
164 QString error_message;
165 QString error_details;
166 };
167
168 ClientManager* clientManager_;
169 QString username_;
170
171 // Controllers (not owned — lifetime guaranteed by MainWindow)
172 BookController* bookController_{nullptr};
173 OreImportController* oreImportController_{nullptr};
174 PortfolioController* portfolioController_{nullptr};
175 TradeController* tradeController_{nullptr};
176
177 // Layout
178 QToolBar* toolbar_{nullptr};
179 QAction* reloadAction_{nullptr};
180
181 // Selection-sensitive toolbar actions
182 QAction* addAction_{nullptr};
183 QAction* editAction_{nullptr};
184 QAction* deleteAction_{nullptr};
185 QAction* historyAction_{nullptr};
186 QAction* importAction_{nullptr};
187
188 QSplitter* splitter_{nullptr};
189
190 // Left: tree
191 QTreeView* treeView_{nullptr};
192 PortfolioExplorerTreeModel* treeModel_{nullptr};
193
194 // Right: trade panel
195 QWidget* breadcrumbBar_{nullptr};
196 QTableView* tradeTableView_{nullptr};
197 PortfolioExplorerTradeModel* tradeModel_{nullptr};
198 QSortFilterProxyModel* tradeProxyModel_{nullptr};
199 PaginationWidget* paginationWidget_{nullptr};
200
201 // Async watchers
202 QFutureWatcher<PortfolioFetchResult>* portfolioWatcher_{nullptr};
203 QFutureWatcher<BookFetchResult>* bookWatcher_{nullptr};
204 QFutureWatcher<CounterpartyFetchResult>* counterpartyWatcher_{nullptr};
205 QList<QFutureWatcher<CountResult>*> countWatchers_;
206
207 // Data
208 std::vector<refdata::domain::portfolio> portfolios_;
209 std::vector<refdata::domain::book> books_;
210 bool portfolios_loaded_{false};
211 bool books_loaded_{false};
212
213 // Drag state
214 QPoint dragStartPos_;
215 QModelIndex dragSourceIndex_;
216};
217
218}
219
220#endif
Implements logging infrastructure for ORE Studio.
Definition boost_severity.hpp:28
Qt-based graphical user interface for ORE Studio.
Definition AboutDialog.hpp:29
Controller for managing book windows and operations.
Definition BookController.hpp:45
Manages the lifecycle of the NATS client and login state.
Definition ClientManager.hpp:109
Base class for entity list MDI windows providing stale indicator support.
Definition EntityListMdiWindow.hpp:62
Controller that owns and launches the OreImportWizard.
Definition OreImportController.hpp:42
Controller for managing portfolio windows and operations.
Definition PortfolioController.hpp:45
MDI window showing the portfolio/book hierarchy with a filtered trade table.
Definition PortfolioExplorerMdiWindow.hpp:60
void doReload() override
Reload all data from server.
Definition PortfolioExplorerMdiWindow.cpp:302
QString normalRefreshTooltip() const override
Get the normal (non-stale) tooltip text for the refresh action.
Definition PortfolioExplorerMdiWindow.hpp:101
A single node in the portfolio/book tree.
Definition PortfolioExplorerTreeModel.hpp:42
Controller for managing trade windows and operations.
Definition TradeController.hpp:43