add PresetModelPanel
This commit is contained in:
parent
96e1eb328f
commit
885212c7d2
@ -30,7 +30,12 @@
|
||||
<file>res/default/menu_uisetting.png</file>
|
||||
<file>res/default/menu_window_manager.png</file>
|
||||
<file>res/default/menu_window_setting.png</file>
|
||||
<file>res/default/Command.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 prefix="/qss"/>
|
||||
<qresource prefix="/fonts">
|
||||
|
||||
BIN
src/res/models/aircraft_carrier.png
Normal file
BIN
src/res/models/aircraft_carrier.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 669 B |
BIN
src/res/models/chaff_interference.png
Normal file
BIN
src/res/models/chaff_interference.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 934 B |
BIN
src/res/models/missile.png
Normal file
BIN
src/res/models/missile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 555 B |
BIN
src/res/models/radar_jamming_station.png
Normal file
BIN
src/res/models/radar_jamming_station.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 582 B |
BIN
src/res/models/satellite.png
Normal file
BIN
src/res/models/satellite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1023 B |
BIN
src/res/models/warships.png
Normal file
BIN
src/res/models/warships.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 662 B |
@ -601,57 +601,57 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="27"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="32"/>
|
||||
<source>参数名称</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="32"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="37"/>
|
||||
<source>描述</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="37"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="42"/>
|
||||
<source>数据类型</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="42"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="47"/>
|
||||
<source>最大值</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="47"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="52"/>
|
||||
<source>最小值</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="52"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="57"/>
|
||||
<source>小数点有效位</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="57"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="62"/>
|
||||
<source>初始值</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="62"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="67"/>
|
||||
<source>数据输入示例</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="91"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="96"/>
|
||||
<source>添加</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="104"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="109"/>
|
||||
<source>删除</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="117"/>
|
||||
<location filename="../ui/Layout/AddParamSetting.ui" line="122"/>
|
||||
<source>应用</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1599,12 +1599,12 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="77"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="78"/>
|
||||
<source>attribte</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="92"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="93"/>
|
||||
<source>Main View</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1701,7 +1701,7 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</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="150"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="157"/>
|
||||
@ -1709,32 +1709,32 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="27"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="39"/>
|
||||
<source>stop</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="55"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="67"/>
|
||||
<source>000.000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="77"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="89"/>
|
||||
<source>00000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="95"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="107"/>
|
||||
<source>x1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="105"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="123"/>
|
||||
<source>up</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="112"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="136"/>
|
||||
<source>down</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1777,22 +1777,32 @@
|
||||
<context>
|
||||
<name>PresetModelPanel</name>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PresetModelPanel.cpp" line="58"/>
|
||||
<location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="75"/>
|
||||
<source>Satellites</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PresetModelPanel.cpp" line="59"/>
|
||||
<location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="100"/>
|
||||
<source>Missiles</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PresetModelPanel.cpp" line="60"/>
|
||||
<location filename="../ui/ModelBrowser/PresetModelPanel.ui" line="125"/>
|
||||
<source>Jammers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2763,22 +2773,22 @@
|
||||
<context>
|
||||
<name>SimuRunMenu</name>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="52"/>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="54"/>
|
||||
<source>no workspace</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="66"/>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="68"/>
|
||||
<source>no commands</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="76"/>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="78"/>
|
||||
<source>Commands</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="95"/>
|
||||
<location filename="../ui/Menu/SimuRunMenu.cpp" line="97"/>
|
||||
<source>unnamed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#include "PropertyBrowser.h"
|
||||
#include "ModelBrowser.h"
|
||||
#include "PresetModelPanel.h"
|
||||
#include "ModelBrowser/PresetModelPanel.h"
|
||||
#include "DockWidget.h"
|
||||
|
||||
#include "viewer/QtOsgViewWidget.h"
|
||||
|
||||
191
src/ui/ModelBrowser/PresetModelConfigParser.cpp
Normal file
191
src/ui/ModelBrowser/PresetModelConfigParser.cpp
Normal 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;
|
||||
}
|
||||
67
src/ui/ModelBrowser/PresetModelConfigParser.h
Normal file
67
src/ui/ModelBrowser/PresetModelConfigParser.h
Normal 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);
|
||||
};
|
||||
@ -1,6 +1,4 @@
|
||||
#include "PresetModelPanel.h"
|
||||
#include "DockTitleBar.h"
|
||||
#include "DockWidget.h"
|
||||
#include "ui/ModelBrowser/PresetModelPanel.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
@ -15,20 +13,24 @@
|
||||
#include <QIcon>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
#include "ui/DockTitleBar.h"
|
||||
#include "ui/DockWidget.h"
|
||||
|
||||
#include "ui_PresetModelPanel.h"
|
||||
|
||||
|
||||
PresetModelPanel::PresetModelPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, toolBox_(nullptr)
|
||||
, mainLayout_(nullptr)
|
||||
, shipList_(nullptr)
|
||||
, satelliteList_(nullptr)
|
||||
, missileList_(nullptr)
|
||||
, jammerList_(nullptr)
|
||||
, ui(new Ui::PresetModelPanel)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
InitUI();
|
||||
}
|
||||
|
||||
PresetModelPanel::~PresetModelPanel()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void PresetModelPanel::AttachDock(DockWidget* dockWidget)
|
||||
@ -47,101 +49,87 @@ void PresetModelPanel::AttachDock(DockWidget* dockWidget)
|
||||
|
||||
void PresetModelPanel::InitUI()
|
||||
{
|
||||
mainLayout_ = new QVBoxLayout(this);
|
||||
mainLayout_->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout_->setSpacing(5);
|
||||
|
||||
toolBox_ = new QToolBox(this);
|
||||
toolBox_->setObjectName("PresetModelToolBox");
|
||||
|
||||
toolBox_->addItem(CreateShipPage(), QIcon(), tr("Ships"));
|
||||
toolBox_->addItem(CreateSatellitePage(), QIcon(), tr("Satellites"));
|
||||
toolBox_->addItem(CreateMissilePage(), QIcon(), tr("Missiles"));
|
||||
toolBox_->addItem(CreateJammerPage(), QIcon(), tr("Jammers"));
|
||||
|
||||
mainLayout_->addWidget(toolBox_);
|
||||
|
||||
setLayout(mainLayout_);
|
||||
// Try to load model data from configuration files
|
||||
if (m_configParser.LoadAllConfigs("workspace/presets")) {
|
||||
// Successfully loaded from configuration files
|
||||
LoadModelsFromConfig();
|
||||
} else {
|
||||
// Failed to load configuration files, use hardcoded defaults as fallback
|
||||
LOG_WARN("Failed to load preset models from config files, using hardcoded defaults. Error: {}",
|
||||
m_configParser.GetLastError().toStdString());
|
||||
LoadDefaultModels();
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* PresetModelPanel::CreateShipPage()
|
||||
void PresetModelPanel::LoadModelsFromConfig()
|
||||
{
|
||||
QWidget* page = new QWidget;
|
||||
QVBoxLayout* layout = new QVBoxLayout(page);
|
||||
// Load ship models
|
||||
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 = {
|
||||
tr("Destroyer"),
|
||||
tr("Aircraft Carrier"),
|
||||
tr("Frigate"),
|
||||
tr("Submarine")
|
||||
"Destroyer",
|
||||
"Aircraft Carrier",
|
||||
"Frigate",
|
||||
"Submarine"
|
||||
};
|
||||
|
||||
shipList_ = CreateModelList(page, "Ship", shipModels);
|
||||
layout->addWidget(shipList_);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
QWidget* PresetModelPanel::CreateSatellitePage()
|
||||
{
|
||||
QWidget* page = new QWidget;
|
||||
QVBoxLayout* layout = new QVBoxLayout(page);
|
||||
PopulateModelList(ui->shipList, "Ship", shipModels);
|
||||
|
||||
QStringList satelliteModels = {
|
||||
tr("Geostationary Satellite"),
|
||||
tr("Communication Satellite"),
|
||||
tr("Weather Satellite"),
|
||||
tr("Navigation Satellite")
|
||||
"Communication Satellite",
|
||||
"Weather Satellite",
|
||||
"GPS Satellite",
|
||||
"Spy Satellite"
|
||||
};
|
||||
|
||||
satelliteList_ = CreateModelList(page, "Satellite", satelliteModels);
|
||||
layout->addWidget(satelliteList_);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
QWidget* PresetModelPanel::CreateMissilePage()
|
||||
{
|
||||
QWidget* page = new QWidget;
|
||||
QVBoxLayout* layout = new QVBoxLayout(page);
|
||||
PopulateModelList(ui->satelliteList, "Satellite", satelliteModels);
|
||||
|
||||
QStringList missileModels = {
|
||||
tr("Hypersonic Missile"),
|
||||
tr("Cruise Missile"),
|
||||
tr("Ballistic Missile"),
|
||||
tr("Anti-Ship Missile")
|
||||
"Cruise Missile",
|
||||
"Ballistic Missile",
|
||||
"Anti-Ship Missile",
|
||||
"Surface-to-Air Missile"
|
||||
};
|
||||
|
||||
missileList_ = CreateModelList(page, "Missile", missileModels);
|
||||
layout->addWidget(missileList_);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
QWidget* PresetModelPanel::CreateJammerPage()
|
||||
{
|
||||
QWidget* page = new QWidget;
|
||||
QVBoxLayout* layout = new QVBoxLayout(page);
|
||||
PopulateModelList(ui->missileList, "Missile", missileModels);
|
||||
|
||||
QStringList jammerModels = {
|
||||
tr("Passive Jammer"),
|
||||
tr("Active Jammer"),
|
||||
tr("Electronic Warfare Pod"),
|
||||
tr("Decoy System")
|
||||
"Electronic Jammer",
|
||||
"Communication Jammer",
|
||||
"Radar Jammer",
|
||||
"GPS Jammer"
|
||||
};
|
||||
|
||||
jammerList_ = CreateModelList(page, "Jammer", jammerModels);
|
||||
layout->addWidget(jammerList_);
|
||||
|
||||
return page;
|
||||
PopulateModelList(ui->jammerList, "Jammer", jammerModels);
|
||||
}
|
||||
|
||||
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);
|
||||
listWidget->setDefaultDropAction(Qt::CopyAction);
|
||||
// Set the model type as a property for later use
|
||||
listWidget->setProperty("modelType", modelType);
|
||||
|
||||
for (const QString& model : models) {
|
||||
QListWidgetItem* item = new QListWidgetItem(model);
|
||||
@ -161,8 +149,6 @@ QListWidget* PresetModelPanel::CreateModelList(QWidget* parent, const QString& m
|
||||
}
|
||||
|
||||
connect(listWidget, &QListWidget::itemDoubleClicked, this, &PresetModelPanel::OnModelItemDoubleClicked);
|
||||
|
||||
return listWidget;
|
||||
}
|
||||
|
||||
void PresetModelPanel::SetupDragAndDrop(QListWidget* listWidget)
|
||||
@ -10,6 +10,11 @@
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <QMouseEvent>
|
||||
#include "PresetModelConfigParser.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class PresetModelPanel; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class DockWidget;
|
||||
|
||||
@ -58,37 +63,12 @@ private:
|
||||
void InitUI();
|
||||
|
||||
/**
|
||||
* @brief Create ship category page
|
||||
* @return Ship page widget
|
||||
*/
|
||||
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
|
||||
* @brief Populate model list with items
|
||||
* @param listWidget List widget to populate
|
||||
* @param modelType Model type
|
||||
* @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
|
||||
@ -96,14 +76,19 @@ private:
|
||||
*/
|
||||
void SetupDragAndDrop(QListWidget* listWidget);
|
||||
|
||||
private:
|
||||
QToolBox* toolBox_;
|
||||
QVBoxLayout* mainLayout_;
|
||||
/**
|
||||
* @brief Load models from configuration file
|
||||
*/
|
||||
void LoadModelsFromConfig();
|
||||
|
||||
QListWidget* shipList_;
|
||||
QListWidget* satelliteList_;
|
||||
QListWidget* missileList_;
|
||||
QListWidget* jammerList_;
|
||||
/**
|
||||
* @brief Load default models when config is unavailable
|
||||
*/
|
||||
void LoadDefaultModels();
|
||||
|
||||
private:
|
||||
Ui::PresetModelPanel *ui;
|
||||
PresetModelConfigParser m_configParser;
|
||||
};
|
||||
|
||||
/**
|
||||
146
src/ui/ModelBrowser/PresetModelPanel.ui
Normal file
146
src/ui/ModelBrowser/PresetModelPanel.ui
Normal 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>
|
||||
23
workspace/presets/jammers.xml
Normal file
23
workspace/presets/jammers.xml
Normal 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>
|
||||
23
workspace/presets/missiles.xml
Normal file
23
workspace/presets/missiles.xml
Normal 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>
|
||||
23
workspace/presets/satellites.xml
Normal file
23
workspace/presets/satellites.xml
Normal 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>
|
||||
23
workspace/presets/ships.xml
Normal file
23
workspace/presets/ships.xml
Normal 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>
|
||||
Loading…
Reference in New Issue
Block a user