modified qrc
This commit is contained in:
commit
0fb6395f06
@ -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">
|
||||||
|
|||||||
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>
|
<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>
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
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 "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)
|
||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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