modified qrc

This commit is contained in:
pimin 2025-10-31 23:15:23 +08:00
commit 0fb6395f06
18 changed files with 634 additions and 151 deletions

View File

@ -32,6 +32,12 @@
<file>res/default/menu_window_setting.png</file> <file>res/default/menu_window_setting.png</file>
<file>res/default/Command.png</file> <file>res/default/Command.png</file>
<file>res/default/polar.png</file> <file>res/default/polar.png</file>
<file>res/models/aircraft_carrier.png</file>
<file>res/models/chaff_interference.png</file>
<file>res/models/missile.png</file>
<file>res/models/radar_jamming_station.png</file>
<file>res/models/satellite.png</file>
<file>res/models/warships.png</file>
</qresource> </qresource>
<qresource prefix="/qss"/> <qresource prefix="/qss"/>
<qresource prefix="/fonts"> <qresource prefix="/fonts">

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

BIN
src/res/models/missile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

BIN
src/res/models/warships.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

View File

@ -601,57 +601,57 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="27"/> <location filename="../ui/Layout/AddParamSetting.ui" line="32"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="32"/> <location filename="../ui/Layout/AddParamSetting.ui" line="37"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="37"/> <location filename="../ui/Layout/AddParamSetting.ui" line="42"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="42"/> <location filename="../ui/Layout/AddParamSetting.ui" line="47"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="47"/> <location filename="../ui/Layout/AddParamSetting.ui" line="52"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="52"/> <location filename="../ui/Layout/AddParamSetting.ui" line="57"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="57"/> <location filename="../ui/Layout/AddParamSetting.ui" line="62"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="62"/> <location filename="../ui/Layout/AddParamSetting.ui" line="67"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="91"/> <location filename="../ui/Layout/AddParamSetting.ui" line="96"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="104"/> <location filename="../ui/Layout/AddParamSetting.ui" line="109"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Layout/AddParamSetting.ui" line="117"/> <location filename="../ui/Layout/AddParamSetting.ui" line="122"/>
<source></source> <source></source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1599,12 +1599,12 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/MainWindow.cpp" line="77"/> <location filename="../ui/MainWindow.cpp" line="78"/>
<source>attribte</source> <source>attribte</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/MainWindow.cpp" line="92"/> <location filename="../ui/MainWindow.cpp" line="93"/>
<source>Main View</source> <source>Main View</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1701,7 +1701,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="20"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="26"/>
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="55"/> <location filename="../ui/Menu/PlayManagerMenu.cpp" line="55"/>
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="150"/> <location filename="../ui/Menu/PlayManagerMenu.cpp" line="150"/>
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="157"/> <location filename="../ui/Menu/PlayManagerMenu.cpp" line="157"/>
@ -1709,32 +1709,32 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="27"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="39"/>
<source>stop</source> <source>stop</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="55"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="67"/>
<source>000.000</source> <source>000.000</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="77"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="89"/>
<source>00000</source> <source>00000</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="95"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="107"/>
<source>x1</source> <source>x1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="105"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="123"/>
<source>up</source> <source>up</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/PlayManagerMenu.ui" line="112"/> <location filename="../ui/Menu/PlayManagerMenu.ui" line="136"/>
<source>down</source> <source>down</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1777,22 +1777,32 @@
<context> <context>
<name>PresetModelPanel</name> <name>PresetModelPanel</name>
<message> <message>
<location filename="../ui/PresetModelPanel.cpp" line="57"/> <location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="14"/>
<source>Preset Models</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="35"/>
<source>PresetModelToolBox</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="50"/>
<source>Ships</source> <source>Ships</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/PresetModelPanel.cpp" line="58"/> <location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="75"/>
<source>Satellites</source> <source>Satellites</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/PresetModelPanel.cpp" line="59"/> <location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="100"/>
<source>Missiles</source> <source>Missiles</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/PresetModelPanel.cpp" line="60"/> <location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="125"/>
<source>Jammers</source> <source>Jammers</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2763,22 +2773,22 @@
<context> <context>
<name>SimuRunMenu</name> <name>SimuRunMenu</name>
<message> <message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="52"/> <location filename="../ui/Menu/SimuRunMenu.cpp" line="54"/>
<source>no workspace</source> <source>no workspace</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="66"/> <location filename="../ui/Menu/SimuRunMenu.cpp" line="68"/>
<source>no commands</source> <source>no commands</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="76"/> <location filename="../ui/Menu/SimuRunMenu.cpp" line="78"/>
<source>Commands</source> <source>Commands</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="95"/> <location filename="../ui/Menu/SimuRunMenu.cpp" line="97"/>
<source>unnamed</source> <source>unnamed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View File

@ -5,7 +5,7 @@
#include "PropertyBrowser.h" #include "PropertyBrowser.h"
#include "ModelBrowser.h" #include "ModelBrowser.h"
#include "PresetModelPanel.h" #include "ModelBrowser/PresetModelPanel.h"
#include "DockWidget.h" #include "DockWidget.h"
#include "viewer/QtOsgViewWidget.h" #include "viewer/QtOsgViewWidget.h"

View File

@ -0,0 +1,191 @@
#include "PresetModelConfigParser.h"
#include "../../xml/tinyxml2.h"
#include "../../common/SpdLogger.h"
#include <QDir>
#include <QFileInfo>
PresetModelConfigParser::PresetModelConfigParser()
{
}
PresetModelConfigParser::~PresetModelConfigParser()
{
}
bool PresetModelConfigParser::LoadAllConfigs(const QString& configDir)
{
Clear();
QDir dir(configDir);
if (!dir.exists()) {
SetError(QString("Config directory does not exist: %1").arg(configDir));
LOG_WARN("Preset config directory does not exist: {}", configDir.toStdString());
return false;
}
// Get all XML files
QStringList filters;
filters << "*.xml";
QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);
if (fileList.isEmpty()) {
SetError(QString("No XML files found in config directory: %1").arg(configDir));
LOG_WARN("No XML files found in preset config directory: {}", configDir.toStdString());
return false;
}
bool hasSuccess = false;
for (const QFileInfo& fileInfo : fileList) {
if (LoadConfig(fileInfo.absoluteFilePath())) {
hasSuccess = true;
LOG_INFO("Successfully loaded preset config: {}", fileInfo.fileName().toStdString());
} else {
LOG_WARN("Failed to load preset config: {}", fileInfo.fileName().toStdString());
}
}
return hasSuccess;
}
bool PresetModelConfigParser::LoadConfig(const QString& filePath)
{
if (!QFileInfo::exists(filePath)) {
SetError(QString("Config file does not exist: %1").arg(filePath));
return false;
}
return ParseXmlFile(filePath);
}
bool PresetModelConfigParser::ParseXmlFile(const QString& filePath)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(filePath.toLocal8Bit().constData());
if (error != tinyxml2::XML_SUCCESS) {
SetError(QString("Failed to parse XML file: %1, error code: %2").arg(filePath).arg(static_cast<int>(error)));
return false;
}
const tinyxml2::XMLElement* root = doc.RootElement();
if (!root) {
SetError(QString("XML file has no root element: %1").arg(filePath));
return false;
}
if (strcmp(root->Name(), "modelCategory") != 0) {
SetError(QString("XML file root element is not modelCategory: %1").arg(filePath));
return false;
}
ModelCategory category;
const char* name = root->Attribute("name");
const char* displayName = root->Attribute("displayName");
const char* icon = root->Attribute("icon");
if (!name) {
SetError(QString("modelCategory missing name attribute: %1").arg(filePath));
return false;
}
category.name = QString::fromUtf8(name);
category.displayName = displayName ? QString::fromUtf8(displayName) : category.name;
category.icon = icon ? QString::fromUtf8(icon) : "";
// Read model list
const tinyxml2::XMLElement* modelElement = root->FirstChildElement("model");
while (modelElement) {
ModelInfo model;
const char* modelName = modelElement->Attribute("name");
const char* modelDisplayName = modelElement->Attribute("displayName");
const char* description = modelElement->Attribute("description");
const char* meshFile = modelElement->Attribute("meshFile");
const char* enabled = modelElement->Attribute("enabled");
if (!modelName) {
LOG_WARN("Model element missing name attribute in file: {}", filePath.toStdString());
modelElement = modelElement->NextSiblingElement("model");
continue;
}
model.name = QString::fromUtf8(modelName);
model.displayName = modelDisplayName ? QString::fromUtf8(modelDisplayName) : model.name;
model.description = description ? QString::fromUtf8(description) : "";
model.meshFile = meshFile ? QString::fromUtf8(meshFile) : "";
model.enabled = enabled ? (strcmp(enabled, "true") == 0) : true;
category.models.append(model);
modelElement = modelElement->NextSiblingElement("model");
}
// Store category data
m_categories[category.name] = category;
return true;
}
QStringList PresetModelConfigParser::GetModelNames(const QString& categoryName) const
{
QStringList names;
if (m_categories.contains(categoryName)) {
const ModelCategory& category = m_categories[categoryName];
for (const ModelInfo& model : category.models) {
if (model.enabled) {
names.append(model.name);
}
}
}
return names;
}
QStringList PresetModelConfigParser::GetCategoryNames() const
{
return m_categories.keys();
}
ModelCategory PresetModelConfigParser::GetCategory(const QString& categoryName) const
{
if (m_categories.contains(categoryName)) {
return m_categories[categoryName];
}
return ModelCategory();
}
ModelInfo PresetModelConfigParser::GetModelInfo(const QString& categoryName, const QString& modelName) const
{
if (m_categories.contains(categoryName)) {
const ModelCategory& category = m_categories[categoryName];
for (const ModelInfo& model : category.models) {
if (model.name == modelName) {
return model;
}
}
}
return ModelInfo();
}
bool PresetModelConfigParser::HasData() const
{
return !m_categories.isEmpty();
}
void PresetModelConfigParser::Clear()
{
m_categories.clear();
m_lastError.clear();
}
QString PresetModelConfigParser::GetLastError() const
{
return m_lastError;
}
void PresetModelConfigParser::SetError(const QString& error)
{
m_lastError = error;
}

View File

@ -0,0 +1,67 @@
#pragma once
#include <QString>
#include <QStringList>
#include <QMap>
#include <QVector>
struct ModelInfo {
QString name;
QString displayName;
QString description;
QString meshFile;
bool enabled;
ModelInfo() : enabled(true) {}
};
struct ModelCategory {
QString name;
QString displayName;
QString icon;
QVector<ModelInfo> models;
};
class PresetModelConfigParser
{
public:
PresetModelConfigParser();
~PresetModelConfigParser();
// Load all preset model configurations
bool LoadAllConfigs(const QString& configDir = "workspace/presets");
// Load single configuration file
bool LoadConfig(const QString& filePath);
// Get model names for specified category
QStringList GetModelNames(const QString& categoryName) const;
// Get all category names
QStringList GetCategoryNames() const;
// Get category information
ModelCategory GetCategory(const QString& categoryName) const;
// Get model information
ModelInfo GetModelInfo(const QString& categoryName, const QString& modelName) const;
// Check if configuration data exists
bool HasData() const;
// Clear all data
void Clear();
// Get last error message
QString GetLastError() const;
private:
QMap<QString, ModelCategory> m_categories;
QString m_lastError;
// Parse single XML file
bool ParseXmlFile(const QString& filePath);
// Set error message
void SetError(const QString& error);
};

View File

@ -1,6 +1,4 @@
#include "PresetModelPanel.h" #include "ui/ModelBrowser/PresetModelPanel.h"
#include "DockTitleBar.h"
#include "DockWidget.h"
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
@ -15,20 +13,24 @@
#include <QIcon> #include <QIcon>
#include <QMouseEvent> #include <QMouseEvent>
#include "common/SpdLogger.h"
#include "ui/DockTitleBar.h"
#include "ui/DockWidget.h"
#include "ui_PresetModelPanel.h"
PresetModelPanel::PresetModelPanel(QWidget *parent) PresetModelPanel::PresetModelPanel(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, toolBox_(nullptr) , ui(new Ui::PresetModelPanel)
, mainLayout_(nullptr)
, shipList_(nullptr)
, satelliteList_(nullptr)
, missileList_(nullptr)
, jammerList_(nullptr)
{ {
ui->setupUi(this);
InitUI(); InitUI();
} }
PresetModelPanel::~PresetModelPanel() PresetModelPanel::~PresetModelPanel()
{ {
delete ui;
} }
void PresetModelPanel::AttachDock(DockWidget* dockWidget) void PresetModelPanel::AttachDock(DockWidget* dockWidget)
@ -47,101 +49,87 @@ void PresetModelPanel::AttachDock(DockWidget* dockWidget)
void PresetModelPanel::InitUI() void PresetModelPanel::InitUI()
{ {
mainLayout_ = new QVBoxLayout(this); // Try to load model data from configuration files
mainLayout_->setContentsMargins(0, 0, 0, 0); if (m_configParser.LoadAllConfigs("workspace/presets")) {
mainLayout_->setSpacing(5); // Successfully loaded from configuration files
LoadModelsFromConfig();
toolBox_ = new QToolBox(this); } else {
toolBox_->setObjectName("PresetModelToolBox"); // Failed to load configuration files, use hardcoded defaults as fallback
LOG_WARN("Failed to load preset models from config files, using hardcoded defaults. Error: {}",
toolBox_->addItem(CreateShipPage(), QIcon(), tr("Ships")); m_configParser.GetLastError().toStdString());
toolBox_->addItem(CreateSatellitePage(), QIcon(), tr("Satellites")); LoadDefaultModels();
toolBox_->addItem(CreateMissilePage(), QIcon(), tr("Missiles")); }
toolBox_->addItem(CreateJammerPage(), QIcon(), tr("Jammers"));
mainLayout_->addWidget(toolBox_);
setLayout(mainLayout_);
} }
QWidget* PresetModelPanel::CreateShipPage() void PresetModelPanel::LoadModelsFromConfig()
{ {
QWidget* page = new QWidget; // Load ship models
QVBoxLayout* layout = new QVBoxLayout(page); QStringList shipModels = m_configParser.GetModelNames("Ship");
if (!shipModels.isEmpty()) {
PopulateModelList(ui->shipList, "Ship", shipModels);
}
// Load satellite models
QStringList satelliteModels = m_configParser.GetModelNames("Satellite");
if (!satelliteModels.isEmpty()) {
PopulateModelList(ui->satelliteList, "Satellite", satelliteModels);
}
// Load missile models
QStringList missileModels = m_configParser.GetModelNames("Missile");
if (!missileModels.isEmpty()) {
PopulateModelList(ui->missileList, "Missile", missileModels);
}
// Load jammer models
QStringList jammerModels = m_configParser.GetModelNames("Jammer");
if (!jammerModels.isEmpty()) {
PopulateModelList(ui->jammerList, "Jammer", jammerModels);
}
}
void PresetModelPanel::LoadDefaultModels()
{
// Use hardcoded default models as fallback mechanism
QStringList shipModels = { QStringList shipModels = {
tr("Destroyer"), "Destroyer",
tr("Aircraft Carrier"), "Aircraft Carrier",
tr("Frigate"), "Frigate",
tr("Submarine") "Submarine"
}; };
PopulateModelList(ui->shipList, "Ship", shipModels);
shipList_ = CreateModelList(page, "Ship", shipModels);
layout->addWidget(shipList_);
return page;
}
QWidget* PresetModelPanel::CreateSatellitePage()
{
QWidget* page = new QWidget;
QVBoxLayout* layout = new QVBoxLayout(page);
QStringList satelliteModels = { QStringList satelliteModels = {
tr("Geostationary Satellite"), "Communication Satellite",
tr("Communication Satellite"), "Weather Satellite",
tr("Weather Satellite"), "GPS Satellite",
tr("Navigation Satellite") "Spy Satellite"
}; };
PopulateModelList(ui->satelliteList, "Satellite", satelliteModels);
satelliteList_ = CreateModelList(page, "Satellite", satelliteModels);
layout->addWidget(satelliteList_);
return page;
}
QWidget* PresetModelPanel::CreateMissilePage()
{
QWidget* page = new QWidget;
QVBoxLayout* layout = new QVBoxLayout(page);
QStringList missileModels = { QStringList missileModels = {
tr("Hypersonic Missile"), "Cruise Missile",
tr("Cruise Missile"), "Ballistic Missile",
tr("Ballistic Missile"), "Anti-Ship Missile",
tr("Anti-Ship Missile") "Surface-to-Air Missile"
}; };
PopulateModelList(ui->missileList, "Missile", missileModels);
missileList_ = CreateModelList(page, "Missile", missileModels);
layout->addWidget(missileList_);
return page;
}
QWidget* PresetModelPanel::CreateJammerPage()
{
QWidget* page = new QWidget;
QVBoxLayout* layout = new QVBoxLayout(page);
QStringList jammerModels = { QStringList jammerModels = {
tr("Passive Jammer"), "Electronic Jammer",
tr("Active Jammer"), "Communication Jammer",
tr("Electronic Warfare Pod"), "Radar Jammer",
tr("Decoy System") "GPS Jammer"
}; };
PopulateModelList(ui->jammerList, "Jammer", jammerModels);
jammerList_ = CreateModelList(page, "Jammer", jammerModels);
layout->addWidget(jammerList_);
return page;
} }
QListWidget* PresetModelPanel::CreateModelList(QWidget* parent, const QString& modelType, const QStringList& models) void PresetModelPanel::PopulateModelList(QListWidget* listWidget, const QString& modelType, const QStringList& models)
{ {
DraggableListWidget* listWidget = new DraggableListWidget(modelType, parent); if (!listWidget) return;
listWidget->setDragDropMode(QAbstractItemView::DragOnly); // Set the model type as a property for later use
listWidget->setDefaultDropAction(Qt::CopyAction); listWidget->setProperty("modelType", modelType);
for (const QString& model : models) { for (const QString& model : models) {
QListWidgetItem* item = new QListWidgetItem(model); QListWidgetItem* item = new QListWidgetItem(model);
@ -161,8 +149,6 @@ QListWidget* PresetModelPanel::CreateModelList(QWidget* parent, const QString& m
} }
connect(listWidget, &QListWidget::itemDoubleClicked, this, &PresetModelPanel::OnModelItemDoubleClicked); connect(listWidget, &QListWidget::itemDoubleClicked, this, &PresetModelPanel::OnModelItemDoubleClicked);
return listWidget;
} }
void PresetModelPanel::SetupDragAndDrop(QListWidget* listWidget) void PresetModelPanel::SetupDragAndDrop(QListWidget* listWidget)

View File

@ -10,6 +10,11 @@
#include <QMimeData> #include <QMimeData>
#include <QDrag> #include <QDrag>
#include <QMouseEvent> #include <QMouseEvent>
#include "PresetModelConfigParser.h"
QT_BEGIN_NAMESPACE
namespace Ui { class PresetModelPanel; }
QT_END_NAMESPACE
class DockWidget; class DockWidget;
@ -58,37 +63,12 @@ private:
void InitUI(); void InitUI();
/** /**
* @brief Create ship category page * @brief Populate model list with items
* @return Ship page widget * @param listWidget List widget to populate
*/
QWidget* CreateShipPage();
/**
* @brief Create satellite category page
* @return Satellite page widget
*/
QWidget* CreateSatellitePage();
/**
* @brief Create missile category page
* @return Missile page widget
*/
QWidget* CreateMissilePage();
/**
* @brief Create jammer category page
* @return Jammer page widget
*/
QWidget* CreateJammerPage();
/**
* @brief Create model list items
* @param parent Parent widget
* @param modelType Model type * @param modelType Model type
* @param models Model name list * @param models Model name list
* @return Configured QListWidget
*/ */
QListWidget* CreateModelList(QWidget* parent, const QString& modelType, const QStringList& models); void PopulateModelList(QListWidget* listWidget, const QString& modelType, const QStringList& models);
/** /**
* @brief Setup drag and drop functionality * @brief Setup drag and drop functionality
@ -96,14 +76,19 @@ private:
*/ */
void SetupDragAndDrop(QListWidget* listWidget); void SetupDragAndDrop(QListWidget* listWidget);
private: /**
QToolBox* toolBox_; * @brief Load models from configuration file
QVBoxLayout* mainLayout_; */
void LoadModelsFromConfig();
QListWidget* shipList_; /**
QListWidget* satelliteList_; * @brief Load default models when config is unavailable
QListWidget* missileList_; */
QListWidget* jammerList_; void LoadDefaultModels();
private:
Ui::PresetModelPanel *ui;
PresetModelConfigParser m_configParser;
}; };
/** /**

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PresetModelPanel</class>
<widget class="QWidget" name="PresetModelPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Preset Models</string>
</property>
<layout class="QVBoxLayout" name="mainLayout">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<property name="spacing">
<number>5</number>
</property>
<item>
<widget class="QToolBox" name="toolBox">
<property name="objectName">
<string>PresetModelToolBox</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="shipPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>540</height>
</rect>
</property>
<attribute name="label">
<string>Ships</string>
</attribute>
<layout class="QVBoxLayout" name="shipLayout">
<item>
<widget class="QListWidget" name="shipList">
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="satellitePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>540</height>
</rect>
</property>
<attribute name="label">
<string>Satellites</string>
</attribute>
<layout class="QVBoxLayout" name="satelliteLayout">
<item>
<widget class="QListWidget" name="satelliteList">
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="missilePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>540</height>
</rect>
</property>
<attribute name="label">
<string>Missiles</string>
</attribute>
<layout class="QVBoxLayout" name="missileLayout">
<item>
<widget class="QListWidget" name="missileList">
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="jammerPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>540</height>
</rect>
</property>
<attribute name="label">
<string>Jammers</string>
</attribute>
<layout class="QVBoxLayout" name="jammerLayout">
<item>
<widget class="QListWidget" name="jammerList">
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<modelCategory name="Jammer" displayName="Jammers" icon="jammer_icon.png">
<model name="Electronic Jammer" displayName="Electronic Jammer"
description="Comprehensive electronic warfare jamming equipment"
meshFile="models/electronic_jammer.ive"
enabled="true" />
<model name="Communication Jammer" displayName="Communication Jammer"
description="Specialized communication signal jamming equipment"
meshFile="models/comm_jammer.ive"
enabled="true" />
<model name="Radar Jammer" displayName="Radar Jammer"
description="Radar signal jamming and deception equipment"
meshFile="models/radar_jammer.ive"
enabled="true" />
<model name="GPS Jammer" displayName="GPS Jammer"
description="Satellite navigation signal jamming equipment"
meshFile="models/gps_jammer.ive"
enabled="true" />
<model name="Signal Jammer" displayName="Signal Jammer"
description="Multi-frequency signal jamming equipment"
meshFile="models/signal_jammer.ive"
enabled="true" />
</modelCategory>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<modelCategory name="Missile" displayName="Missiles" icon="missile_icon.png">
<model name="Cruise Missile" displayName="Cruise Missile"
description="Long-range precision strike cruise missile"
meshFile="models/cruise_missile.ive"
enabled="true" />
<model name="Ballistic Missile" displayName="Ballistic Missile"
description="Long-range ballistic missile system"
meshFile="models/ballistic_missile.ive"
enabled="true" />
<model name="Anti-Ship Missile" displayName="Anti-Ship Missile"
description="Specialized anti-ship attack missile"
meshFile="models/antiship_missile.ive"
enabled="true" />
<model name="Surface-to-Air Missile" displayName="Surface-to-Air Missile"
description="Surface-to-air defense missile system"
meshFile="models/sam_missile.ive"
enabled="true" />
<model name="Anti-Tank Missile" displayName="Anti-Tank Missile"
description="Anti-armor precision guided missile"
meshFile="models/antitank_missile.ive"
enabled="true" />
</modelCategory>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<modelCategory name="Satellite" displayName="Satellites" icon="satellite_icon.png">
<model name="Communication Satellite" displayName="Communication Satellite"
description="Satellite platform providing global communication services"
meshFile="models/comm_satellite.ive"
enabled="true" />
<model name="Weather Satellite" displayName="Weather Satellite"
description="Observation satellite monitoring weather and climate changes"
meshFile="models/weather_satellite.ive"
enabled="true" />
<model name="GPS Satellite" displayName="GPS Satellite"
description="Global Positioning System satellite"
meshFile="models/gps_satellite.ive"
enabled="true" />
<model name="Spy Satellite" displayName="Spy Satellite"
description="Military reconnaissance and surveillance satellite"
meshFile="models/spy_satellite.ive"
enabled="true" />
<model name="Scientific Satellite" displayName="Scientific Satellite"
description="Dedicated satellite for scientific research"
meshFile="models/science_satellite.ive"
enabled="true" />
</modelCategory>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<modelCategory name="Ship" displayName="Ships" icon="ship_icon.png">
<model name="Destroyer" displayName="Destroyer"
description="High-speed combat vessel with powerful anti-submarine and air defense capabilities"
meshFile="models/destroyer.ive"
enabled="true" />
<model name="Aircraft Carrier" displayName="Aircraft Carrier"
description="Large aircraft carrier, mobile airfield and command center at sea"
meshFile="models/carrier.ive"
enabled="true" />
<model name="Frigate" displayName="Frigate"
description="Medium-sized escort vessel, multi-purpose combat platform"
meshFile="models/frigate.ive"
enabled="true" />
<model name="Submarine" displayName="Submarine"
description="Underwater combat platform with strong stealth capabilities"
meshFile="models/submarine.ive"
enabled="true" />
<model name="Cruiser" displayName="Cruiser"
description="Heavy combat vessel with powerful firepower"
meshFile="models/cruiser.ive"
enabled="true" />
</modelCategory>