From 2ea81633f99bfecde5cf7c0e49b7cea960c6c82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=BE=E5=93=A5?= Date: Tue, 28 Apr 2026 19:14:54 +0800 Subject: [PATCH] =?UTF-8?q?v1.2:=20.VSC=20=E6=96=87=E4=BB=B6=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=20&=20=E8=B7=A8=E5=B9=B3=E5=8F=B0=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【文件格式】 - 工程文件扩展名从 .json 改为 .VSC(内容仍为 JSON) - 文件对话框过滤、保存/打开全部适配 .VSC - 双击 .VSC 文件可直接打开工程(命令行传参) 【安装程序】 - Windows: NSIS 安装脚本 (installer/voiletcstudio.nsi) 支持注册 .VSC 文件关联、开始菜单/桌面快捷方式、卸载 - Linux: install.sh/uninstall.sh 一键安装/卸载 自动注册 MIME 类型、.desktop 文件、命令行软链接 - 内置 --register/--unregister 命令行参数用于文件关联 【代码清理】 - 移除所有拖拽功能(dragEnter/Move/DropEvent) - 新增 MainWindow::openProjectFile() 用于命令行打开 - main.cpp 完整重写,加入命令行解析器 【其他】 - .gitignore 排除 NSIS 输出 (.exe) --- .gitignore | 5 + installer/install.sh | 92 +++++++++++++++++ installer/uninstall.sh | 25 +++++ installer/voiletcstudio.nsi | 85 ++++++++++++++++ resources/voiletcstudio.desktop | 3 +- src/main.cpp | 156 ++++++++++++++++++++++++++++- src/mainwindow.cpp | 172 ++++++++++---------------------- src/mainwindow.h | 8 +- 8 files changed, 419 insertions(+), 127 deletions(-) create mode 100644 installer/install.sh create mode 100644 installer/uninstall.sh create mode 100644 installer/voiletcstudio.nsi diff --git a/.gitignore b/.gitignore index 6750d3f..063baec 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ VoiletCStudio .idea/ *.user *.pro.user + +# Installer output +*.exe +VoiletCStudio-Setup-*.exe +installer/build/ diff --git a/installer/install.sh b/installer/install.sh new file mode 100644 index 0000000..e626e5b --- /dev/null +++ b/installer/install.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# ===================================================== +# VoiletCStudio Linux 安装脚本 +# 用法: sudo bash installer/install.sh +# ===================================================== + +set -e + +APP_NAME="VoiletCStudio" +VERSION="1.2" +INSTALL_DIR="/opt/${APP_NAME}" +BIN_DIR="/usr/local/bin" +DESKTOP_DIR="/usr/share/applications" +MIME_DIR="/usr/share/mime/packages" +ICON_DIR="/usr/share/icons/hicolor/256x256/apps" + +echo "=========================================" +echo " VoiletCStudio v${VERSION} - Linux 安装程序" +echo "=========================================" + +# 检查 root +if [ "$EUID" -ne 0 ]; then + echo "请使用 sudo 运行: sudo bash installer/install.sh" + exit 1 +fi + +echo "" +echo "[1/5] 编译程序..." +mkdir -p build && cd build +qmake ../VoiletCStudio.pro && make -j$(nproc) +cd .. + +echo "" +echo "[2/5] 安装到 ${INSTALL_DIR}..." +mkdir -p "${INSTALL_DIR}" +cp build/VoiletCStudio "${INSTALL_DIR}/" +chmod +x "${INSTALL_DIR}/VoiletCStudio" + +# 创建命令行软链接 +ln -sf "${INSTALL_DIR}/VoiletCStudio" "${BIN_DIR}/voiletcstudio" + +echo "" +echo "[3/5] 安装图标..." +mkdir -p "${ICON_DIR}" +cp resources/voiletcstudio.png "${ICON_DIR}/voiletcstudio.png" + +echo "" +echo "[4/5] 注册 MIME 类型和 .desktop..." +mkdir -p "${MIME_DIR}" +cat > "${MIME_DIR}/voiletcstudio.xml" << 'MIMEXML' + + + + VoiletCStudio Project + VoiletCStudio 工程文件 + + + + +MIMEXML + +mkdir -p "${DESKTOP_DIR}" +cat > "${DESKTOP_DIR}/voiletcstudio.desktop" << DESKTOPEOF +[Desktop Entry] +Type=Application +Name=VoiletCStudio +Name[zh_CN]=紫罗兰 C 工程配置器 +Comment=C Project Configurator with CMake +Comment[zh_CN]=C 语言工程配置器,自动生成 CMakeLists.txt +Exec=${INSTALL_DIR}/VoiletCStudio %f +Icon=voiletcstudio +MimeType=application/x-voiletcstudio; +Categories=Development;IDE; +Terminal=false +DESKTOPEOF + +echo "" +echo "[5/5] 更新系统数据库..." +update-mime-database /usr/share/mime +update-desktop-database +gtk-update-icon-cache /usr/share/icons/hicolor 2>/dev/null || true + +echo "" +echo "=========================================" +echo " ✅ VoiletCStudio 安装完成!" +echo "=========================================" +echo "" +echo " 命令行: voiletcstudio" +echo " 或双击 .VSC 工程文件自动打开" +echo "" +echo " 卸载: sudo bash installer/uninstall.sh" +echo "" diff --git a/installer/uninstall.sh b/installer/uninstall.sh new file mode 100644 index 0000000..438342e --- /dev/null +++ b/installer/uninstall.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# ===================================================== +# VoiletCStudio Linux 卸载脚本 +# ===================================================== +set -e + +if [ "$EUID" -ne 0 ]; then + echo "请使用 sudo 运行" + exit 1 +fi + +APP_NAME="VoiletCStudio" + +echo "正在卸载 ${APP_NAME}..." + +rm -rf "/opt/${APP_NAME}" +rm -f "/usr/local/bin/voiletcstudio" +rm -f "/usr/share/applications/voiletcstudio.desktop" +rm -f "/usr/share/mime/packages/voiletcstudio.xml" +rm -f "/usr/share/icons/hicolor/256x256/apps/voiletcstudio.png" + +update-mime-database /usr/share/mime 2>/dev/null || true +update-desktop-database 2>/dev/null || true + +echo "✅ ${APP_NAME} 已卸载" diff --git a/installer/voiletcstudio.nsi b/installer/voiletcstudio.nsi new file mode 100644 index 0000000..922ecf6 --- /dev/null +++ b/installer/voiletcstudio.nsi @@ -0,0 +1,85 @@ +; ===================================================== +; VoiletCStudio Windows 安装脚本 (NSIS) +; 用法: makensis installer/voiletcstudio.nsi +; ===================================================== + +!define PRODUCT_NAME "VoiletCStudio" +!define PRODUCT_VERSION "1.2" +!define PRODUCT_PUBLISHER "LinuxAcme" +!define PRODUCT_EXE "VoiletCStudio.exe" + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "VoiletCStudio-Setup-${PRODUCT_VERSION}.exe" +InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" +RequestExecutionLevel admin + +; ----- 安装页面 ----- +Page directory +Page instfiles + +; ----- 默认安装路径 ----- +Section "Install" + SetOutPath "$INSTDIR" + + ; 复制主程序 + File "VoiletCStudio.exe" + + ; 复制 Qt 运行时 DLL(需要提前准备好) + ; File /r "Qt5Core.dll" + ; File /r "Qt5Gui.dll" + ; File /r "Qt5Widgets.dll" + + ; 复制 MinGW 运行时 + ; File /r "libgcc_s_seh-1.dll" + ; File /r "libstdc++-6.dll" + ; File /r "libwinpthread-1.dll" + + ; 创建卸载程序 + WriteUninstaller "$INSTDIR\uninstall.exe" + + ; 注册 .VSC 文件关联 + WriteRegStr HKCR ".VSC" "" "VoiletCStudio.VSC" + WriteRegStr HKCR "VoiletCStudio.VSC" "" "VoiletCStudio 工程文件" + WriteRegStr HKCR "VoiletCStudio.VSC\DefaultIcon" "" "$INSTDIR\${PRODUCT_EXE},0" + WriteRegStr HKCR "VoiletCStudio.VSC\shell\open\command" "" '"$INSTDIR\${PRODUCT_EXE}" "%1"' + + ; 注册表卸载信息 + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\uninstall.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "${PRODUCT_PUBLISHER}" + + ; 开始菜单快捷方式 + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\VoiletCStudio.lnk" "$INSTDIR\${PRODUCT_EXE}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\卸载.lnk" "$INSTDIR\uninstall.exe" + + ; 桌面快捷方式 + CreateShortCut "$DESKTOP\VoiletCStudio.lnk" "$INSTDIR\${PRODUCT_EXE}" + + ; 通知系统刷新文件关联 + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' +SectionEnd + +; ----- 卸载 ----- +Section "Uninstall" + ; 删除程序 + Delete "$INSTDIR\${PRODUCT_EXE}" + Delete "$INSTDIR\uninstall.exe" + RMDir "$INSTDIR" + + ; 删除文件关联 + DeleteRegKey HKCR ".VSC" + DeleteRegKey HKCR "VoiletCStudio.VSC" + + ; 删除注册表 + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + + ; 删除快捷方式 + Delete "$SMPROGRAMS\${PRODUCT_NAME}\VoiletCStudio.lnk" + Delete "$SMPROGRAMS\${PRODUCT_NAME}\卸载.lnk" + RMDir "$SMPROGRAMS\${PRODUCT_NAME}" + Delete "$DESKTOP\VoiletCStudio.lnk" + + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' +SectionEnd diff --git a/resources/voiletcstudio.desktop b/resources/voiletcstudio.desktop index f8e37df..f0e987a 100644 --- a/resources/voiletcstudio.desktop +++ b/resources/voiletcstudio.desktop @@ -4,7 +4,8 @@ Name=VoiletCStudio Name[zh_CN]=紫罗兰 C 工程配置器 Comment=C Project Configurator with CMake Comment[zh_CN]=C 语言工程配置器,自动生成 CMakeLists.txt -Exec=VoiletCStudio +Exec=VoiletCStudio %f Icon=voiletcstudio +MimeType=application/x-voiletcstudio; Categories=Development;IDE; Terminal=false diff --git a/src/main.cpp b/src/main.cpp index 022aa5d..bd99db9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,125 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "mainwindow.h" +#ifdef Q_OS_WIN32 +#include +#include +#endif + +// ===== 文件关联注册 ===== +static void registerFileAssociation() +{ +#ifdef Q_OS_WIN32 + QString appPath = QCoreApplication::applicationFilePath(); + appPath.replace("/", "\\"); + + // 注册 .VSC 扩展名 + QSettings settings("HKEY_CLASSES_ROOT\\.VSC", QSettings::NativeFormat); + settings.setValue("Default", "VoiletCStudio.VSC"); + settings.sync(); + + // 注册文件类型描述 + QSettings typeSettings("HKEY_CLASSES_ROOT\\VoiletCStudio.VSC", QSettings::NativeFormat); + typeSettings.setValue("Default", "VoiletCStudio 工程文件"); + typeSettings.sync(); + + // 注册图标 + QSettings iconSettings("HKEY_CLASSES_ROOT\\VoiletCStudio.VSC\\DefaultIcon", QSettings::NativeFormat); + iconSettings.setValue("Default", appPath + ",0"); + iconSettings.sync(); + + // 注册打开命令 + QSettings cmdSettings("HKEY_CLASSES_ROOT\\VoiletCStudio.VSC\\shell\\open\\command", QSettings::NativeFormat); + cmdSettings.setValue("Default", "\"" + appPath + "\" \"%1\""); + cmdSettings.sync(); + + // 通知系统刷新 + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); + + qDebug() << "[OK] .VSC file association registered on Windows"; +#else + // Linux: 写入 MIME 类型定义 + 更新 desktop 数据库 + QString mimeDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/mime/packages"; + QDir().mkpath(mimeDir); + + QString mimeFile = mimeDir + "/voiletcstudio.xml"; + QFile f(mimeFile); + if (f.open(QIODevice::WriteOnly)) { + f.write(R"( + + + VoiletCStudio Project + VoiletCStudio 工程文件 + + + + +)"); + f.close(); + } + + // 写入 .desktop 文件 + QString appsDir = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); + QDir().mkpath(appsDir); + + QString desktopFile = appsDir + "/voiletcstudio.desktop"; + QFile df(desktopFile); + if (df.open(QIODevice::WriteOnly)) { + df.write(R"([Desktop Entry] +Type=Application +Name=VoiletCStudio +Name[zh_CN]=紫罗兰 C 工程配置器 +Comment=C Project Configurator +Comment[zh_CN]=C 语言工程配置器 +Exec=)" + QCoreApplication::applicationFilePath().toUtf8() + R"( %f +Icon=voiletcstudio +MimeType=application/x-voiletcstudio; +Categories=Development;IDE; +Terminal=false +)"); + df.close(); + } + + // 更新 MIME 数据库 + QProcess::execute("update-mime-database", QStringList() << + QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/mime"); + QProcess::execute("update-desktop-database", QStringList()); + + qDebug() << "[OK] .VSC file association registered on Linux"; +#endif +} + +static void unregisterFileAssociation() +{ +#ifdef Q_OS_WIN32 + QSettings settings("HKEY_CLASSES_ROOT\\.VSC", QSettings::NativeFormat); + settings.remove("Default"); + settings.sync(); + + QSettings("HKEY_CLASSES_ROOT\\VoiletCStudio.VSC", QSettings::NativeFormat).remove(""); + SHDeleteKey(HKEY_CLASSES_ROOT, L"VoiletCStudio.VSC"); + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); + + qDebug() << "[OK] .VSC file association removed"; +#else + QString mimeFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/mime/packages/voiletcstudio.xml"; + QFile::remove(mimeFile); + QProcess::execute("update-mime-database", QStringList() << + QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/mime"); + qDebug() << "[OK] .VSC file association removed"; +#endif +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -12,14 +129,49 @@ int main(int argc, char *argv[]) // 设置应用程序信息 app.setApplicationName("VoiletCStudio"); - app.setApplicationVersion("1.1"); + app.setApplicationVersion("1.2"); app.setOrganizationName("LinuxAcme"); - // 设置样式(使用系统原生样式) + // 命令行参数解析 + QCommandLineParser parser; + parser.setApplicationDescription("紫罗兰 C 工程配置器 - 自动生成 CMakeLists.txt"); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption registerOpt("register", "注册 .VSC 文件关联到系统"); + QCommandLineOption unregisterOpt("unregister", "取消 .VSC 文件关联"); + parser.addOption(registerOpt); + parser.addOption(unregisterOpt); + + // 接受 .VSC 文件作为位置参数(双击打开) + parser.addPositionalArgument("file", "要打开的 .VSC 工程文件"); + + parser.process(app); + + // 处理注册/取消注册 + if (parser.isSet(registerOpt)) { + registerFileAssociation(); + return 0; + } + if (parser.isSet(unregisterOpt)) { + unregisterFileAssociation(); + return 0; + } + + // 设置样式 app.setStyle(QStyleFactory::create("Fusion")); MainWindow window; window.show(); + // 通过命令行传入的文件自动打开 + QStringList posArgs = parser.positionalArguments(); + if (!posArgs.isEmpty()) { + QString filePath = posArgs.first(); + if (filePath.endsWith(".VSC", Qt::CaseInsensitive) || filePath.endsWith(".json", Qt::CaseInsensitive)) { + window.openProjectFile(filePath); + } + } + return app.exec(); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index feb52dc..11dd2f9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include +#include #include #include #include @@ -18,9 +19,6 @@ #include #include #include -#include -#include -#include #include MainWindow::MainWindow(QWidget *parent) @@ -31,9 +29,6 @@ MainWindow::MainWindow(QWidget *parent) config = new ProjectConfig(this); cmakeGenerator = new CMakeGenerator(this); - // ★ 启用拖拽 - setAcceptDrops(true); - setupUI(); setupConnections(); updateWindowTitle(); @@ -109,7 +104,7 @@ void MainWindow::setupUI() basicLayout->addWidget(projectNameEdit); basicLayout->addStretch(); - basicLayout->addWidget(new QLabel("📂 工程路径:同 JSON 配置文件所在目录")); + basicLayout->addWidget(new QLabel("📂 工程路径:同 VSC 工程文件所在目录")); mainLayout->addWidget(basicGroup); @@ -280,22 +275,6 @@ void MainWindow::setupUI() // 状态栏 statusBar()->showMessage("就绪"); - - // ★ 禁用子控件的拖拽,让所有拖拽事件由 MainWindow 统一处理 - sourceTree->setAcceptDrops(false); - sourceTree->viewport()->setAcceptDrops(false); - includeDirList->setAcceptDrops(false); - includeDirList->viewport()->setAcceptDrops(false); - libraryList->setAcceptDrops(false); - libraryList->viewport()->setAcceptDrops(false); - defineList->setAcceptDrops(false); - defineList->viewport()->setAcceptDrops(false); - optionList->setAcceptDrops(false); - optionList->viewport()->setAcceptDrops(false); - projectNameEdit->setAcceptDrops(false); - compilerPathEdit->setAcceptDrops(false); - assemblerPathEdit->setAcceptDrops(false); - linkerPathEdit->setAcceptDrops(false); } void MainWindow::setupConnections() @@ -361,99 +340,6 @@ bool MainWindow::maybeSave() return true; } -void MainWindow::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasUrls()) { - QList urls = event->mimeData()->urls(); - if (!urls.isEmpty()) { - QString file = urls.first().toLocalFile(); - if (file.endsWith(".json", Qt::CaseInsensitive)) { - event->acceptProposedAction(); - statusBar()->showMessage("📂 释放鼠标打开工程:" + file, 3000); - return; - } - } - } - event->ignore(); -} - -void MainWindow::dragMoveEvent(QDragMoveEvent *event) -{ - // 拖拽移动时也要接受,否则 Qt 不会触发 dropEvent - if (event->mimeData()->hasUrls()) { - QList urls = event->mimeData()->urls(); - if (!urls.isEmpty()) { - QString file = urls.first().toLocalFile(); - if (file.endsWith(".json", Qt::CaseInsensitive)) { - event->acceptProposedAction(); - return; - } - } - } - event->ignore(); -} - -void MainWindow::dropEvent(QDropEvent *event) -{ - if (event->mimeData()->hasUrls()) { - QList urls = event->mimeData()->urls(); - if (!urls.isEmpty()) { - QString file = urls.first().toLocalFile(); - if (file.endsWith(".json", Qt::CaseInsensitive)) { - if (!maybeSave()) { - return; - } - - if (config->loadConfig(file)) { - currentFilePath = file; - modified = false; - - // 更新 UI - projectNameEdit->setText(config->getProjectName()); - compilerPathEdit->setText(config->getCompilerPath()); - assemblerPathEdit->setText(config->getAssemblerPath()); - linkerPathEdit->setText(config->getLinkerPath()); - - // 更新虚拟目录树 - sourceTree->clear(); - QMap dirs = config->getVirtualDirs(); - for (auto it = dirs.begin(); it != dirs.end(); ++it) { - QTreeWidgetItem *dirItem = new QTreeWidgetItem(sourceTree); - dirItem->setText(0, "📁 " + it.key()); - for (const QString &f : it->files) { - QTreeWidgetItem *fileItem = new QTreeWidgetItem(dirItem); - fileItem->setText(0, "📄 " + QFileInfo(f).fileName()); - fileItem->setToolTip(0, f); - } - } - sourceTree->expandAll(); - - // 更新包含目录 - includeDirList->clear(); - includeDirList->addItems(config->getIncludeDirs()); - - // 更新库文件 - libraryList->clear(); - libraryList->addItems(config->getLibraries()); - - // 更新编译宏 - defineList->clear(); - defineList->addItems(config->getDefines()); - - // 更新编译选项 - optionList->clear(); - optionList->addItems(config->getCompilerOptions()); - - updateWindowTitle(); - statusBar()->showMessage("✅ 工程已加载:" + file, 5000); - } else { - QMessageBox::critical(this, "错误", "无法加载工程文件:" + file); - } - } - } - } -} - void MainWindow::newProject() { if (!maybeSave()) { @@ -485,7 +371,7 @@ void MainWindow::openProject() } QString filePath = QFileDialog::getOpenFileName(this, "打开工程", "", - "JSON 配置文件 (*.json);;所有文件 (*)"); + "VSC 工程文件 (*.VSC);;所有文件 (*)"); if (filePath.isEmpty()) { return; @@ -530,6 +416,54 @@ void MainWindow::openProject() } } +void MainWindow::openProjectFile(const QString &filePath) +{ + // 直接打开指定文件(用于命令行和双击打开),跳过 maybeSave + if (!QFile::exists(filePath)) { + QMessageBox::critical(this, "错误", "文件不存在:" + filePath); + return; + } + + if (config->loadConfig(filePath)) { + currentFilePath = filePath; + modified = false; + + projectNameEdit->setText(config->getProjectName()); + compilerPathEdit->setText(config->getCompilerPath()); + assemblerPathEdit->setText(config->getAssemblerPath()); + linkerPathEdit->setText(config->getLinkerPath()); + + sourceTree->clear(); + QMap dirs = config->getVirtualDirs(); + for (auto it = dirs.begin(); it != dirs.end(); ++it) { + QTreeWidgetItem *dirItem = new QTreeWidgetItem(sourceTree); + dirItem->setText(0, it.key()); + for (const QString &file : it->files) { + QTreeWidgetItem *fileItem = new QTreeWidgetItem(dirItem); + fileItem->setText(0, file); + } + } + sourceTree->expandAll(); + + includeDirList->clear(); + includeDirList->addItems(config->getIncludeDirs()); + + libraryList->clear(); + libraryList->addItems(config->getLibraries()); + + defineList->clear(); + defineList->addItems(config->getDefines()); + + optionList->clear(); + optionList->addItems(config->getCompilerOptions()); + + updateWindowTitle(); + statusBar()->showMessage("✅ 工程已加载:" + filePath, 5000); + } else { + QMessageBox::critical(this, "错误", "无法加载工程文件:" + filePath); + } +} + bool MainWindow::saveProject() { if (currentFilePath.isEmpty()) { @@ -555,7 +489,7 @@ bool MainWindow::saveProject() bool MainWindow::saveProjectAs() { QString filePath = QFileDialog::getSaveFileName(this, "保存工程", "", - "JSON 配置文件 (*.json);;所有文件 (*)"); + "VSC 工程文件 (*.VSC);;所有文件 (*)"); if (filePath.isEmpty()) { return false; @@ -572,7 +506,7 @@ void MainWindow::generateCMake() return; } - // 获取工程目录(JSON 配置文件所在目录) + // 获取工程目录(VSC 工程文件所在目录) QString projectDir = QFileInfo(currentFilePath).absolutePath(); QString buildDir = projectDir + "/build"; QString cmakePath = projectDir + "/CMakeLists.txt"; diff --git a/src/mainwindow.h b/src/mainwindow.h index fc4b8cd..016c4c4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -19,6 +19,9 @@ class MainWindow : public QMainWindow public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); + + // 通过命令行/双击打开工程文件 + void openProjectFile(const QString &filePath); private slots: // 文件操作 @@ -67,11 +70,6 @@ private slots: void browseAssemblerPath(); void browseLinkerPath(); -protected: - void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dropEvent(QDropEvent *event) override; - private: void setupUI(); void setupConnections();