Добавлена реализация базовых профилей (Имя, путь до java)
This commit is contained in:
@@ -16,7 +16,7 @@ qt_add_executable(minecraft-launcher
|
||||
settingsdialog.h settingsdialog.cpp
|
||||
settingsdialog.ui
|
||||
mainwindow.ui
|
||||
|
||||
profiledialog.h profiledialog.cpp profiledialog.ui
|
||||
|
||||
|
||||
)
|
||||
|
||||
146
mainwindow.cpp
146
mainwindow.cpp
@@ -1,6 +1,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h" // Подключаем сгенерированный заголовочный файл
|
||||
#include "settingsdialog.h"
|
||||
#include "profiledialog.h" // Подключаем новый диалог
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
@@ -12,6 +13,8 @@
|
||||
#include <QJsonObject> // Для работы с JSON
|
||||
#include <QJsonArray> // Для работы с JSON
|
||||
#include <QJsonValue> // Для работы с JSON
|
||||
#include <QUuid> // Для генерации ID профиля
|
||||
#include <QStandardPaths> // Для поиска папки с данными
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
@@ -32,6 +35,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(process, &QProcess::readyReadStandardError, this, &MainWindow::readProcessOutput);
|
||||
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onProcessFinished(int, QProcess::ExitStatus)));
|
||||
connect(process, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(onProcessError(QProcess::ProcessError)));
|
||||
// Загружаем профили при старте
|
||||
profilesPath = "/launcher_profiles.json";
|
||||
loadProfiles();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -86,8 +92,146 @@ bool checkRules(const QJsonObject &item) {
|
||||
return isAllowed;
|
||||
}
|
||||
|
||||
void MainWindow::loadProfiles()
|
||||
{
|
||||
QFile profilesFile(profilesPath);
|
||||
if (profilesFile.exists() && profilesFile.open(QIODevice::ReadOnly)) {
|
||||
QJsonDocument doc = QJsonDocument::fromJson(profilesFile.readAll());
|
||||
profilesData = doc.object();
|
||||
profilesFile.close();
|
||||
} else {
|
||||
// Создаем базовую структуру, если файла нет
|
||||
profilesData = QJsonObject({{"profiles", QJsonObject()}});
|
||||
}
|
||||
|
||||
QJsonObject profiles = profilesData["profiles"].toObject();
|
||||
ui->profileComboBox->clear();
|
||||
|
||||
if (profiles.isEmpty()) {
|
||||
// Если профилей нет, принудительно открываем диалог создания
|
||||
QMessageBox::information(this, "Настройка", "Не найдено ни одного профиля. Давайте создадим новый.");
|
||||
createNewProfile();
|
||||
return; // createNewProfile вызовет loadProfiles() повторно
|
||||
}
|
||||
|
||||
// Заполняем ComboBox
|
||||
for (const QString &key : profiles.keys()) {
|
||||
QJsonObject profile = profiles[key].toObject();
|
||||
ui->profileComboBox->addItem(profile["name"].toString(), key); // Имя и UUID
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveProfiles()
|
||||
{
|
||||
QFile profilesFile(profilesPath);
|
||||
if (profilesFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QJsonDocument doc(profilesData);
|
||||
profilesFile.write(doc.toJson(QJsonDocument::Indented));
|
||||
profilesFile.close();
|
||||
} else {
|
||||
QMessageBox::critical(this, "Ошибка", "Не удалось сохранить файл профилей: " + profilesFile.errorString());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_editProfileButton_clicked()
|
||||
{
|
||||
// 1. Проверяем, выбран ли профиль
|
||||
QString currentProfileId = ui->profileComboBox->currentData().toString();
|
||||
if (currentProfileId.isEmpty()) {
|
||||
QMessageBox::warning(this, "Нет профиля", "Пожалуйста, выберите профиль для редактирования.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Получаем данные текущего профиля
|
||||
QJsonObject profiles = profilesData["profiles"].toObject();
|
||||
QJsonObject currentProfile = profiles[currentProfileId].toObject();
|
||||
|
||||
// 3. Создаем диалог и заполняем его данными
|
||||
ProfileDialog dialog(this);
|
||||
dialog.setWindowTitle("Редактирование профиля");
|
||||
dialog.setProfileName(currentProfile["name"].toString());
|
||||
dialog.setJavaPath(currentProfile["javaDir"].toString());
|
||||
|
||||
// 4. Показываем диалог и обрабатываем результат
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
if (dialog.profileName().isEmpty() || dialog.javaPath().isEmpty()) {
|
||||
QMessageBox::warning(this, "Ошибка", "Имя профиля и путь к Java не могут быть пустыми.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Обновляем данные в нашем JSON объекте
|
||||
currentProfile["name"] = dialog.profileName();
|
||||
currentProfile["javaDir"] = dialog.javaPath();
|
||||
|
||||
// 6. Записываем обновленный профиль обратно
|
||||
profiles[currentProfileId] = currentProfile;
|
||||
profilesData["profiles"] = profiles;
|
||||
|
||||
// 7. Сохраняем и перезагружаем список
|
||||
saveProfiles();
|
||||
|
||||
// Сохраняем ID, чтобы восстановить выбор после перезагрузки
|
||||
QString previouslySelectedId = currentProfileId;
|
||||
loadProfiles();
|
||||
int indexToSelect = ui->profileComboBox->findData(previouslySelectedId);
|
||||
if (indexToSelect != -1) {
|
||||
ui->profileComboBox->setCurrentIndex(indexToSelect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::createNewProfile()
|
||||
{
|
||||
ProfileDialog dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
if (dialog.profileName().isEmpty() || dialog.javaPath().isEmpty()) {
|
||||
QMessageBox::warning(this, "Ошибка", "Имя профиля и путь к Java не могут быть пустыми.");
|
||||
return;
|
||||
}
|
||||
|
||||
QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
QJsonObject newProfile;
|
||||
newProfile["name"] = dialog.profileName();
|
||||
newProfile["javaDir"] = dialog.javaPath();
|
||||
newProfile["lastVersionId"] = "";
|
||||
newProfile["created"] = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
newProfile["lastUsed"] = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
newProfile["icon"] = "Bedrock";
|
||||
newProfile["type"] = "custom";
|
||||
|
||||
QJsonObject profiles = profilesData["profiles"].toObject();
|
||||
profiles[uuid] = newProfile;
|
||||
profilesData["profiles"] = profiles;
|
||||
|
||||
saveProfiles();
|
||||
loadProfiles(); // Перезагружаем список профилей
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_addProfileButton_clicked()
|
||||
{
|
||||
createNewProfile();
|
||||
}
|
||||
|
||||
void MainWindow::on_profileComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
// Пока ничего не делаем, но слот полезен для будущего
|
||||
Q_UNUSED(index);
|
||||
}
|
||||
|
||||
void MainWindow::on_launchButton_clicked()
|
||||
{
|
||||
QString currentProfileId = ui->profileComboBox->currentData().toString();
|
||||
if (currentProfileId.isEmpty()) {
|
||||
QMessageBox::critical(this, "Ошибка", "Не выбран профиль для запуска!");
|
||||
return;
|
||||
}
|
||||
QJsonObject profile = profilesData["profiles"].toObject()[currentProfileId].toObject();
|
||||
QString javaPath = profile["javaDir"].toString();
|
||||
if (!QFileInfo::exists(javaPath)) {
|
||||
QMessageBox::critical(this, "Ошибка", "Не найден исполняемый файл Java, указанный в профиле:\n" + javaPath);
|
||||
return;
|
||||
}
|
||||
// --- 1. Выбор версии (остается без изменений) ---
|
||||
QString minecraftPath = getMinecraftPath();
|
||||
if (minecraftPath.isEmpty()) {
|
||||
@@ -229,7 +373,7 @@ void MainWindow::on_launchButton_clicked()
|
||||
|
||||
// --- 6. Финальная сборка и запуск ---
|
||||
QString mainClass = rootObj["mainClass"].toString();
|
||||
QString javaPath = "java";
|
||||
//QString javaPath = "java";
|
||||
|
||||
QStringList finalArguments;
|
||||
finalArguments << jvmArgs << mainClass << gameArgs;
|
||||
|
||||
11
mainwindow.h
11
mainwindow.h
@@ -4,6 +4,7 @@
|
||||
#include <QMainWindow>
|
||||
#include <QProcess>
|
||||
#include <QSettings>
|
||||
#include <QJsonObject> // Важно: добавить для хранения данных профилей
|
||||
|
||||
// Предварительное объявление класса, сгенерированного из mainwindow.ui
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -24,6 +25,9 @@ private slots:
|
||||
void on_modsFolderButton_clicked();
|
||||
void on_updateModsButton_clicked();
|
||||
void on_settingsButton_clicked();
|
||||
void on_addProfileButton_clicked(); // Слот для кнопки "Новый..."
|
||||
void on_editProfileButton_clicked(); // <-- ДОБАВЬТЕ ЭТОТ СЛОТ
|
||||
void on_profileComboBox_currentIndexChanged(int index); // Слот для смены профиля
|
||||
|
||||
// Слоты для QProcess (подключаются вручную)
|
||||
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
@@ -33,6 +37,13 @@ private slots:
|
||||
private:
|
||||
QString getMinecraftPath();
|
||||
|
||||
// Новые методы для работы с профилями
|
||||
void loadProfiles();
|
||||
void saveProfiles();
|
||||
void createNewProfile();
|
||||
QString profilesPath; // Путь к launcher_profiles.json
|
||||
QJsonObject profilesData; // JSON данные из файла
|
||||
|
||||
Ui::MainWindow *ui; // Указатель на объект интерфейса
|
||||
QProcess *process;
|
||||
QSettings *settings;
|
||||
|
||||
@@ -15,6 +15,34 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Профиль:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="profileComboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addProfileButton">
|
||||
<property name="text">
|
||||
<string>Новый...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="editProfileButton">
|
||||
<property name="text">
|
||||
<string>Редактировать...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="launchButton">
|
||||
<property name="text">
|
||||
@@ -65,4 +93,4 @@
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
</ui>
|
||||
|
||||
48
profiledialog.cpp
Normal file
48
profiledialog.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "profiledialog.h"
|
||||
#include "ui_profiledialog.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
ProfileDialog::ProfileDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ProfileDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ProfileDialog::~ProfileDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString ProfileDialog::profileName() const
|
||||
{
|
||||
return ui->profileNameEdit->text();
|
||||
}
|
||||
|
||||
QString ProfileDialog::javaPath() const
|
||||
{
|
||||
return ui->javaPathEdit->text();
|
||||
}
|
||||
// === РЕАЛИЗАЦИЯ НОВЫХ ФУНКЦИЙ ===
|
||||
void ProfileDialog::setProfileName(const QString &name)
|
||||
{
|
||||
ui->profileNameEdit->setText(name);
|
||||
}
|
||||
|
||||
void ProfileDialog::setJavaPath(const QString &path)
|
||||
{
|
||||
ui->javaPathEdit->setText(path);
|
||||
}
|
||||
// ===============================
|
||||
|
||||
void ProfileDialog::on_browseButton_clicked()
|
||||
{
|
||||
QString filter = "Исполняемый файл (java.exe)";
|
||||
#if !defined(Q_OS_WIN)
|
||||
filter = "Все файлы (*)";
|
||||
#endif
|
||||
QString path = QFileDialog::getOpenFileName(this, "Выберите java.exe", QDir::homePath(), filter);
|
||||
if (!path.isEmpty()) {
|
||||
ui->javaPathEdit->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
}
|
||||
32
profiledialog.h
Normal file
32
profiledialog.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef PROFILEDIALOG_H
|
||||
#define PROFILEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class ProfileDialog;
|
||||
}
|
||||
|
||||
class ProfileDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProfileDialog(QWidget *parent = nullptr);
|
||||
~ProfileDialog();
|
||||
|
||||
QString profileName() const;
|
||||
QString javaPath() const;
|
||||
// === НОВЫЕ ФУНКЦИИ ===
|
||||
void setProfileName(const QString &name);
|
||||
void setJavaPath(const QString &path);
|
||||
|
||||
|
||||
private slots:
|
||||
void on_browseButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::ProfileDialog *ui;
|
||||
};
|
||||
|
||||
#endif // PROFILEDIALOG_H
|
||||
99
profiledialog.ui
Normal file
99
profiledialog.ui
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProfileDialog</class>
|
||||
<widget class="QDialog" name="ProfileDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>450</width>
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Настройка профиля</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Имя профиля:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="profileNameEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Путь к Java:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="javaPathEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="browseButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ProfileDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ProfileDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user