ACAV f0ba4b7c9529
Abstract Syntax Tree (AST) visualization tool for C, C++, and Objective-C
Loading...
Searching...
No Matches
MainWindow.h
Go to the documentation of this file.
1/*$!{
2* Aurora Clang AST Viewer (ACAV)
3*
4* Copyright (c) 2026 Min Liu
5* Copyright (c) 2026 Michael David Adams
6*
7* SPDX-License-Identifier: GPL-2.0-or-later
8*
9* This program is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation; either version 2 of the License, or
12* (at your option) any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License along
20* with this program; if not, see <https://www.gnu.org/licenses/>.
21}$!*/
22
25#pragma once
26
27#include "common/FileManager.h"
29#include "core/MakeAstRunner.h"
32#include "ui/AstModel.h"
33#include "ui/DeclContextView.h"
34#include "ui/DockTitleBar.h"
35#include "ui/LogDock.h"
36#include "ui/NodeCycleWidget.h"
37#include "ui/SourceCodeView.h"
39#include <QAction>
40#include <QByteArray>
41#include <QCheckBox>
42#include <QCompleter>
43#include <QDockWidget>
44#include <QDialog>
45#include <QLabel>
46#include <QLineEdit>
47#include <QMainWindow>
48#include <QMenu>
49#include <QPoint>
50#include <QSet>
51#include <QSpinBox>
52#include <QStringList>
53#include <QStringListModel>
54#include <QThread>
55#include <QTimer>
56#include <QToolBar>
57#include <QToolButton>
58#include <QTreeView>
59#include <memory>
60#include <vector>
61
62namespace acav {
63
64class AstContext; // Forward declaration
65class MainWindowTestAccess;
66
75class MainWindow : public QMainWindow {
76 Q_OBJECT
77
78public:
79 explicit MainWindow(QWidget *parent = nullptr);
80 ~MainWindow() override;
81
86 void loadCompilationDatabase(const QString &compilationDatabasePath,
87 const QString &projectRoot = QString());
88
89private slots:
90 // Menu actions
91 void onOpenCompilationDatabase();
92 void onExit();
93
94 // View interactions
95 void onTranslationUnitSelected(const QModelIndex &index);
96 void onTranslationUnitClicked(const QModelIndex &index);
97
98 // Query-dependencies integration
99 void onDependenciesReady(const QJsonObject &dependencies);
100 void onDependenciesReadyWithErrors(const QJsonObject &dependencies,
101 const QStringList &errorMessages);
102 void onDependenciesError(const QString &errorMessage);
103 void onDependenciesProgress(const QString &message);
104
105 // AST extraction
106 void onAstReady(const QString &astFilePath);
107 void onAstExtracted(AstViewNode *root);
108 void onAstError(const QString &errorMessage);
109 void onMakeAstLogMessage(const LogEntry &entry);
110 void onAstProgress(const QString &message);
111 void onAstStatsUpdated(const AstExtractionStats &stats);
112 void onTimingMessage(const QString &message);
113 void onAstContextMenuRequested(const QPoint &pos);
114 void onViewNodeDetails(AstViewNode *node);
115 void onExportAst(AstViewNode *node);
116 void onExpandAllAstChildren();
117 void onCollapseAllAstChildren();
118 void onGoToMacroDefinition();
119
120 // Source Files tree context menu
121 void onTuContextMenuRequested(const QPoint &pos);
122 void onExpandAllTuChildren();
123 void onCollapseAllTuChildren();
124
125 // Navigation
126 void onAstNodeSelected(const QModelIndex &index);
127 void onSourcePositionClicked(FileID fileId, unsigned line, unsigned column);
128 void onSourceRangeSelected(FileID fileId, unsigned startLine,
129 unsigned startColumn, unsigned endLine,
130 unsigned endColumn);
131 void onCycleNodeSelected(AstViewNode *node);
132 void onCycleWidgetClosed();
133 void onSourceSearchTextChanged(const QString &text);
134 void onSourceSearchDebounced();
135 void onSourceSearchFindNext();
136 void onSourceSearchFindPrevious();
137 void onAstSearchTextChanged(const QString &text);
138 void onAstSearchDebounced();
139 void onAstSearchFindNext();
140 void onAstSearchFindPrevious();
141 void onShowAbout();
142 void onResetLayout();
143 void onFocusChanged(QWidget *old, QWidget *now);
144
145protected:
146 void resizeEvent(QResizeEvent *event) override;
147 void moveEvent(QMoveEvent *event) override;
148 bool eventFilter(QObject *watched, QEvent *event) override;
149
150private:
151 friend class MainWindowTestAccess;
152
153 // UI setup
154 void setupUI();
155 void setupMenuBar();
156 void setupDockWidgets();
157 void setupModels();
158 void setupTuSearch();
159 void setupSourceSearchPanel(QWidget *container);
160 void setupAstSearchPanel(QWidget *container);
161 void setupSettingsAction();
162 void applyUnifiedSelectionPalette();
163 void setupViewMenuDockActions();
164 void applyFontSize(int size);
165 void adjustFontSize(int delta);
166 void expandFileExplorerTopLevel();
167 void connectSignals();
168
169 // Status bar helper
170 void logStatus(LogLevel level, const QString &message,
171 const QString &source = QString());
172
173 // AST helper methods
174 void extractAst(const QString &astFilePath, const QString &sourceFilePath);
175 QStringList getFileListForSource(const QString &sourceFilePath) const;
176 bool isSourceFile(const QString &filePath) const;
177 bool deleteCachedAst(const QString &astFilePath);
178 QString astCacheStatusFilePath(const QString &astFilePath) const;
179 void persistAstCompilationErrorState(const QString &astFilePath,
180 bool hasCompilationErrors);
181 bool loadAstCompilationErrorState(const QString &astFilePath) const;
182
183 // Navigation history
184 struct NavEntry {
185 FileID fileId;
186 unsigned line;
187 unsigned column;
188 AstViewNode *node;
189 std::size_t astVersion;
190 };
191
192 void recordHistory(FileID fileId, unsigned line, unsigned column,
193 AstViewNode *node);
194 void clearHistory();
195 void navigateHistory(int delta);
196 void applyEntry(const NavEntry &entry);
197 void updateNavActions();
198 void onOpenConfigFile();
199 void onReloadConfig();
200 QString buildDefaultExportFileName(AstViewNode *node) const;
201 void triggerSourceSearch(bool forward);
202 void triggerAstSearch(bool forward);
203 void collectAstSearchMatches(const QString &expression);
204 void navigateToAstMatch(int index);
205 void clearAstSearchState();
206 void setAstSearchStatus(const QString &text, bool isError);
207 void showAstSearchPopup(bool selectAll = false);
208 void syncAstSearchPopupGeometry();
209 void rememberAstSearchQuery(const QString &query);
210 void setAstCompilationWarningVisible(bool visible);
211 void expandAllChildren(QTreeView *view);
212 void expandSubtree(QTreeView *view);
213 void collapseAllChildren(QTreeView *view);
214 void collapseTuDirectories(QTreeView *view);
215 void collapseRecursively(const QModelIndex &index, QTreeView *view);
216 void highlightTuFile(FileID fileId);
217 bool navigateToRange(const SourceRange &range, AstViewNode *node,
218 bool skipCursorMove);
219 bool getMacroSpellingRange(const AstViewNode *node,
220 SourceRange *outRange) const;
221
224 bool validateSourceLookup(FileID fileId);
225
227 void logNoNodeFound(FileID fileId, const QString &fallbackMessage);
228
230 void updateSourceSubtitle(const QString &filePath);
231
233 void updateAstSubtitle(const QString &mainSourcePath);
234
235 // Menu bar
236 ::QMenu *fileMenu_;
237 ::QMenu *viewMenu_;
238 QAction *openAction_;
239 QAction *exitAction_;
240 QAction *settingsAction_;
241 QAction *reloadConfigAction_;
242 QAction *navBackAction_;
243 QAction *navForwardAction_;
244 QAction *goToMacroDefinitionAction_;
245 QAction *zoomInAction_;
246 QAction *zoomOutAction_;
247 QAction *zoomResetAction_;
248 QToolBar *navToolBar_;
249 QAction *resetLayoutAction_;
250 QLineEdit *tuSearch_;
251 QLineEdit *sourceSearchInput_;
252 QToolButton *sourceSearchPrevButton_;
253 QToolButton *sourceSearchNextButton_;
254 QLabel *sourceSearchStatus_;
255 ::QTimer *sourceSearchDebounce_;
256
257 // AST search
258 QDialog *astSearchPopup_ = nullptr;
259 QLineEdit *astSearchQuickInput_ = nullptr;
260 QLineEdit *astSearchInput_ = nullptr;
261 QToolButton *astSearchPrevButton_ = nullptr;
262 QToolButton *astSearchNextButton_ = nullptr;
263 QLabel *astSearchStatus_ = nullptr;
264 QLabel *astCompilationWarningLabel_ = nullptr;
265 QCheckBox *astSearchProjectFilter_ = nullptr;
266 QCompleter *astSearchCompleter_ = nullptr;
267 QStringListModel *astSearchHistoryModel_ = nullptr;
268 QStringList astSearchHistory_;
269 std::vector<AstViewNode *> astSearchMatches_;
270 int astSearchCurrentIndex_ = -1;
271
272 // Dock widgets
273 QDockWidget *tuDock_;
274 QDockWidget *sourceDock_;
275 QDockWidget *astDock_;
276 QDockWidget *declContextDock_;
277 LogDock *logDock_;
278
279 // Views
280 QTreeView *tuView_;
281 SourceCodeView *sourceView_;
282 QTreeView *astView_;
283 DeclContextView *declContextView_;
284
285 // Models
286 TranslationUnitModel *tuModel_;
287 AstModel *astModel_;
288
289 // Core components
290 QueryDependenciesRunner *queryRunner_;
291 QueryDependenciesParallelRunner *parallelQueryRunner_;
292 MakeAstRunner *makeAstRunner_;
293 AstExtractorRunner *astExtractorRunner_;
294 QThread *astWorkerThread_;
295 QThread *astExportThread_ = nullptr;
296 FileManager fileManager_;
297 std::unique_ptr<AstContext> astContext_; // One context per TU
298
299 // Configuration
300 static constexpr int kParallelThreshold = 10; // Use parallel if >= 10 files
301 static constexpr int kMinFontSize = 8;
302 static constexpr int kMaxFontSize = 32;
303
304 // Current state
305 QString compilationDatabasePath_;
306 QString projectRoot_; // User-specified or auto-detected project root
307 QString currentSourceFilePath_; // Track which file AST is being generated for
308 QString lastAstFilePath_; // Track last AST cache path used for extraction
309 bool isAstExtractionInProgress_; // Track if AST extraction is ongoing
310 bool isAstExportInProgress_ = false; // Track if AST export is ongoing
311 QString pendingSourceFilePath_; // File path that is being processed
312 bool astHasCompilationErrors_ = false;
313 std::size_t astVersion_ = 0;
314 int currentFontSize_ = 11;
315 QString currentFontFamily_;
316
317 // Per-subwindow font sizes
318 int tuFontSize_ = 11;
319 int sourceFontSize_ = 11;
320 int astFontSize_ = 11;
321 int declContextFontSize_ = 11;
322 int logFontSize_ = 11;
323
324 QByteArray defaultDockState_;
325
326 // Navigation
327 NodeCycleWidget *nodeCycleWidget_;
328 std::vector<NavEntry> history_;
329 std::size_t historyCursor_ = 0;
330 bool suppressHistory_ = false;
331 bool suppressSourceCursorMove_ = false;
332 bool suppressSourceHighlight_ = false;
333 bool isNavigatingFromDeclContext_ = false;
334
335 // Focus tracking with custom title bars (fast, no setStyleSheet)
336 QDockWidget *focusedDock_ = nullptr;
337 DockTitleBar *tuTitleBar_ = nullptr;
338 DockTitleBar *sourceTitleBar_ = nullptr;
339 DockTitleBar *astTitleBar_ = nullptr;
340 DockTitleBar *declContextTitleBar_ = nullptr;
341 DockTitleBar *logTitleBar_ = nullptr;
342};
343
344} // namespace acav
Qt runner for AST extraction pipeline.
Qt model for AST tree view display.
Declaration context hierarchy display panel.
Custom dock widget title bar with fast focus indication.
Centralized file registry with path-to-FileID mapping.
std::size_t FileID
Type-safe identifier for registered files. 0 is reserved for invalid.
Definition FileManager.h:38
Dock widget for displaying logs and diagnostics.
Qt runner for make-ast tool execution.
Popup widget for cycling through overlapping AST nodes.
Parallel runner specifically for query-dependencies tool.
Qt runner for query-dependencies tool.
Source code display widget with line numbers.
Qt model for translation unit tree view.
Memory manager for AST nodes in a translation unit.
Definition AstNode.h:66
Qt runner that loads AST from cache and builds ACAV tree.
Qt model for displaying AST hierarchy.
Definition AstModel.h:41
Represents node in AST tree hierarchy.
Definition AstNode.h:195
Panel displaying declaration context hierarchy for selected AST node.
Custom title bar for QDockWidget with fast focus indication.
Centralized file registry providing path-to-FileID mapping.
Definition FileManager.h:45
void loadCompilationDatabase(const QString &compilationDatabasePath, const QString &projectRoot=QString())
Load compilation database and populate translation units.
Runs the make-ast tool to generate AST cache files.
Popup widget for cycling through multiple matching nodes.
Parallel runner specifically for query-dependencies tool.
Runs the query-dependencies tool and parses its output.
Source code viewer with line numbers and lightweight syntax highlighting.
Represents a span of source code (begin to end).
Model for displaying translation units in a tree view.
Statistics collected during AST extraction.