ACAV f0ba4b7c9529
Abstract Syntax Tree (AST) visualization tool for C, C++, and Objective-C
Loading...
Searching...
No Matches
OpenProjectDialog.cpp
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
26
27#include <QDialogButtonBox>
28#include <QDir>
29#include <QFileDialog>
30#include <QFileInfo>
31#include <QFormLayout>
32#include <QHBoxLayout>
33#include <QMessageBox>
34#include <QVBoxLayout>
35
36namespace acav {
37
38namespace {
39
40QString expandUserPath(const QString &path) {
41 if (path.startsWith("~")) {
42 return QDir::homePath() + path.mid(1); // Handles both "~" and "~/"
43 }
44 return path;
45}
46
47} // namespace
48
49OpenProjectDialog::OpenProjectDialog(QWidget *parent) : QDialog(parent) {
50 setWindowTitle(tr("Open Project"));
51 setMinimumWidth(400);
52 resize(700, 120); // Larger initial size, user can resize as needed
53
54 auto *layout = new QVBoxLayout(this);
55
56 // Form layout for inputs
57 auto *formLayout = new QFormLayout();
58
59 // Compilation database row
60 auto *dbRow = new QHBoxLayout();
61 dbPathEdit_ = new QLineEdit(this);
62 // Don't need placeholder
63 // dbPathEdit_->setPlaceholderText(tr("/path/to/compile_commands.json"));
64 dbPathEdit_->setClearButtonEnabled(true);
65 dbBrowseButton_ = new QPushButton(tr("Browse..."), this);
66 dbRow->addWidget(dbPathEdit_);
67 dbRow->addWidget(dbBrowseButton_);
68 formLayout->addRow(tr("Compilation Database:"), dbRow);
69
70 // Project root row (optional)
71 auto *projectRow = new QHBoxLayout();
72 projectRootEdit_ = new QLineEdit(this);
73 projectRootEdit_->setClearButtonEnabled(true);
74 projectRootBrowseButton_ = new QPushButton(tr("Browse..."), this);
75 projectRow->addWidget(projectRootEdit_);
76 projectRow->addWidget(projectRootBrowseButton_);
77 formLayout->addRow(tr("Project Root (optional):"), projectRow);
78
79 layout->addLayout(formLayout);
80
81 // Dialog buttons
82 auto *buttonBox =
83 new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
84 layout->addWidget(buttonBox);
85
86 // Connections
87 connect(dbBrowseButton_, &QPushButton::clicked, this,
88 &OpenProjectDialog::browseCompilationDatabase);
89 connect(projectRootBrowseButton_, &QPushButton::clicked, this,
90 &OpenProjectDialog::browseProjectRoot);
91 connect(buttonBox, &QDialogButtonBox::accepted, this,
92 &OpenProjectDialog::validateAndAccept);
93 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
94
95 dbPathEdit_->setFocus();
96}
97
99 return dbPathEdit_->text();
100}
101
103 return projectRootEdit_->text();
104}
105
106void OpenProjectDialog::browseCompilationDatabase() {
107 QString initialDir;
108 QString current = dbPathEdit_->text().trimmed();
109 if (!current.isEmpty()) {
110 QFileInfo info(current);
111 initialDir = info.absolutePath();
112 }
113 QString fileName = QFileDialog::getOpenFileName(
114 this, tr("Select Compilation Database"), initialDir,
115 tr("Compilation Database (*.json);;All Files (*)"));
116 if (!fileName.isEmpty()) {
117 dbPathEdit_->setText(fileName);
118 }
119}
120
121void OpenProjectDialog::browseProjectRoot() {
122 QString dir = QFileDialog::getExistingDirectory(
123 this, tr("Select Project Root Directory"),
124 projectRootEdit_->text().trimmed(), QFileDialog::ShowDirsOnly);
125 if (!dir.isEmpty()) {
126 projectRootEdit_->setText(dir);
127 }
128}
129
130void OpenProjectDialog::validateAndAccept() {
131 const QString rawDbPath = dbPathEdit_->text().trimmed();
132 if (rawDbPath.isEmpty()) {
133 QMessageBox::warning(this, tr("Validation Error"),
134 tr("Please enter a compilation database path."));
135 return;
136 }
137
138 const QString expandedDbPath = expandUserPath(rawDbPath);
139 QFileInfo dbInfo(expandedDbPath);
140 if (!dbInfo.exists() || !dbInfo.isFile()) {
141 QMessageBox::warning(
142 this, tr("Validation Error"),
143 tr("Compilation database not found:\n%1").arg(expandedDbPath));
144 return;
145 }
146
147 dbPathEdit_->setText(dbInfo.absoluteFilePath());
148
149 const QString rawProjectRoot = projectRootEdit_->text().trimmed();
150 if (!rawProjectRoot.isEmpty()) {
151 const QString expandedProjectRoot = expandUserPath(rawProjectRoot);
152 QFileInfo rootInfo(expandedProjectRoot);
153 if (!rootInfo.exists() || !rootInfo.isDir()) {
154 QMessageBox::warning(
155 this, tr("Validation Error"),
156 tr("Project root directory not found:\n%1").arg(expandedProjectRoot));
157 return;
158 }
159 projectRootEdit_->setText(rootInfo.absoluteFilePath());
160 } else {
161 projectRootEdit_->clear();
162 }
163
164 accept();
165}
166
167} // namespace acav
Dialog for opening a project with compilation database and optional project root.
QString projectRootPath() const
Get the selected project root path.
QString compilationDatabasePath() const
Get the selected compilation database path.