1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-26 13:47:46 +00:00

armoury: Support localization

This commit is contained in:
Joshua Goins 2024-02-04 15:13:46 -05:00
parent 1c0712bdbf
commit 98036249fb
8 changed files with 60 additions and 51 deletions

View file

@ -2,11 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include "cmpeditor.h" #include "cmpeditor.h"
#include <KLocalizedString>
CmpEditor::CmpEditor(GameData *data, QWidget *parent) CmpEditor::CmpEditor(GameData *data, QWidget *parent)
: CmpPart(data, parent) : CmpPart(data, parent)
{ {
setWindowTitle(QStringLiteral("CMP Editor")); setWindowTitle(i18nc("@title:window CMP is an abbreviation", "CMP Editor"));
load(physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp")); load(physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp"));
} }

View file

@ -5,6 +5,7 @@
#include "boneeditor.h" #include "boneeditor.h"
#include "magic_enum.hpp" #include "magic_enum.hpp"
#include <KLocalizedString>
#include <QCloseEvent> #include <QCloseEvent>
#include <QFileDialog> #include <QFileDialog>
#include <QFormLayout> #include <QFormLayout>
@ -17,7 +18,7 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
: QMainWindow(parent) : QMainWindow(parent)
, data(data) , data(data)
{ {
setWindowTitle(QStringLiteral("Full Model Viewer")); setWindowTitle(i18nc("@title:window", "Full Model Viewer"));
setMinimumWidth(1280); setMinimumWidth(1280);
setMinimumHeight(720); setMinimumHeight(720);
setAttribute(Qt::WA_DeleteOnClose, false); setAttribute(Qt::WA_DeleteOnClose, false);
@ -28,13 +29,15 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
auto layout = new QVBoxLayout(); auto layout = new QVBoxLayout();
dummyWidget->setLayout(layout); dummyWidget->setLayout(layout);
auto fileMenu = menuBar()->addMenu(QStringLiteral("File")); auto fileMenu = menuBar()->addMenu(i18nc("@title:menu", "File"));
auto datOpenAction = fileMenu->addAction(QStringLiteral("Load character DAT...")); auto datOpenAction = fileMenu->addAction(i18nc("@action:inmenu DAT is an abbreviation", "Load Character DAT..."));
datOpenAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); datOpenAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
connect(datOpenAction, &QAction::triggered, [this] { connect(datOpenAction, &QAction::triggered, [this] {
auto fileName = auto fileName = QFileDialog::getOpenFileName(nullptr,
QFileDialog::getOpenFileName(nullptr, QStringLiteral("Open DAT File"), QStringLiteral("~"), QStringLiteral("FFXIV Character DAT File (*.dat)")); i18nc("@title:window DAT is an abbreviation", "Open DAT File"),
QStringLiteral("~"),
i18nc("DAT is an abbreviation", "FFXIV Character DAT File (*.dat)"));
auto buffer = physis_read_file(fileName.toStdString().c_str()); auto buffer = physis_read_file(fileName.toStdString().c_str());
@ -72,7 +75,7 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
const float scale = (float)position / 100.0f; const float scale = (float)position / 100.0f;
updateHeightScaling(scale); updateHeightScaling(scale);
}); });
characterEditorLayout->addRow(QStringLiteral("Height"), characterHeight); characterEditorLayout->addRow(i18nc("@label:slider Character height", "Height"), characterHeight);
auto bustSize = new QSlider(); auto bustSize = new QSlider();
bustSize->setOrientation(Qt::Horizontal); bustSize->setOrientation(Qt::Horizontal);
@ -81,7 +84,7 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
const float scale = (float)position / 100.0f; const float scale = (float)position / 100.0f;
updateBustScaling(scale); updateBustScaling(scale);
}); });
characterEditorLayout->addRow(QStringLiteral("Bust Size"), bustSize); characterEditorLayout->addRow(i18nc("@label:slider Character breast size", "Bust Size"), bustSize);
characterEditorLayout->addWidget(addFaceGroup()); characterEditorLayout->addWidget(addFaceGroup());
characterEditorLayout->addWidget(addHairGroup()); characterEditorLayout->addWidget(addHairGroup());
@ -89,8 +92,8 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
characterEditorLayout->addWidget(addTailGroup()); characterEditorLayout->addWidget(addTailGroup());
auto tabWidget = new QTabWidget(); auto tabWidget = new QTabWidget();
tabWidget->addTab(new BoneEditor(gearView), QStringLiteral("Bone Editor")); tabWidget->addTab(new BoneEditor(gearView), i18nc("@title:tab", "Bone Editor"));
tabWidget->addTab(characterEditorWidget, QStringLiteral("Character Editor")); tabWidget->addTab(characterEditorWidget, i18nc("@title:tab", "Character Editor"));
viewportLayout->addWidget(tabWidget); viewportLayout->addWidget(tabWidget);
auto controlLayout = new QHBoxLayout(); auto controlLayout = new QHBoxLayout();
@ -291,23 +294,23 @@ void FullModelViewer::updateSupportedSubraces()
QGroupBox *FullModelViewer::addFaceGroup() QGroupBox *FullModelViewer::addFaceGroup()
{ {
auto faceGroup = new QGroupBox(QStringLiteral("Face")); auto faceGroup = new QGroupBox(i18nc("@title:group", "Face"));
auto faceGroupLayout = new QVBoxLayout(); auto faceGroupLayout = new QVBoxLayout();
faceGroup->setLayout(faceGroupLayout); faceGroup->setLayout(faceGroupLayout);
auto faceRadio1 = new QRadioButton(QStringLiteral("Face 1")); auto faceRadio1 = new QRadioButton(i18nc("@option:radio", "Face 1"));
connect(faceRadio1, &QRadioButton::clicked, this, [this] { connect(faceRadio1, &QRadioButton::clicked, this, [this] {
gearView->setFace(1); gearView->setFace(1);
}); });
faceGroupLayout->addWidget(faceRadio1); faceGroupLayout->addWidget(faceRadio1);
auto faceRadio2 = new QRadioButton(QStringLiteral("Face 2")); auto faceRadio2 = new QRadioButton(i18nc("@option:radio", "Face 2"));
connect(faceRadio2, &QRadioButton::clicked, this, [this] { connect(faceRadio2, &QRadioButton::clicked, this, [this] {
gearView->setFace(2); gearView->setFace(2);
}); });
faceGroupLayout->addWidget(faceRadio2); faceGroupLayout->addWidget(faceRadio2);
auto faceRadio3 = new QRadioButton(QStringLiteral("Face 3")); auto faceRadio3 = new QRadioButton(i18nc("@option:radio", "Face 3"));
connect(faceRadio3, &QRadioButton::clicked, this, [this] { connect(faceRadio3, &QRadioButton::clicked, this, [this] {
gearView->setFace(3); gearView->setFace(3);
}); });
@ -318,23 +321,23 @@ QGroupBox *FullModelViewer::addFaceGroup()
QGroupBox *FullModelViewer::addHairGroup() QGroupBox *FullModelViewer::addHairGroup()
{ {
auto hairGroup = new QGroupBox(QStringLiteral("Hair")); auto hairGroup = new QGroupBox(i18nc("@title:group", "Hair"));
auto hairGroupLayout = new QVBoxLayout(); auto hairGroupLayout = new QVBoxLayout();
hairGroup->setLayout(hairGroupLayout); hairGroup->setLayout(hairGroupLayout);
auto hairRadio1 = new QRadioButton(QStringLiteral("Hair 1")); auto hairRadio1 = new QRadioButton(i18nc("@option:radio", "Hair 1"));
connect(hairRadio1, &QRadioButton::clicked, this, [this] { connect(hairRadio1, &QRadioButton::clicked, this, [this] {
gearView->setHair(1); gearView->setHair(1);
}); });
hairGroupLayout->addWidget(hairRadio1); hairGroupLayout->addWidget(hairRadio1);
auto hairRadio2 = new QRadioButton(QStringLiteral("Hair 2")); auto hairRadio2 = new QRadioButton(i18nc("@option:radio", "Hair 2"));
connect(hairRadio2, &QRadioButton::clicked, this, [this] { connect(hairRadio2, &QRadioButton::clicked, this, [this] {
gearView->setHair(2); gearView->setHair(2);
}); });
hairGroupLayout->addWidget(hairRadio2); hairGroupLayout->addWidget(hairRadio2);
auto hairRadio3 = new QRadioButton(QStringLiteral("Hair 3")); auto hairRadio3 = new QRadioButton(i18nc("@option:radio", "Hair 3"));
connect(hairRadio3, &QRadioButton::clicked, this, [this] { connect(hairRadio3, &QRadioButton::clicked, this, [this] {
gearView->setHair(3); gearView->setHair(3);
}); });
@ -345,23 +348,23 @@ QGroupBox *FullModelViewer::addHairGroup()
QGroupBox *FullModelViewer::addEarGroup() QGroupBox *FullModelViewer::addEarGroup()
{ {
auto earGroup = new QGroupBox(QStringLiteral("Ears")); auto earGroup = new QGroupBox(i18nc("@title:group", "Ears"));
auto earGroupLayout = new QVBoxLayout(); auto earGroupLayout = new QVBoxLayout();
earGroup->setLayout(earGroupLayout); earGroup->setLayout(earGroupLayout);
auto earRadio1 = new QRadioButton(QStringLiteral("Ears 1")); auto earRadio1 = new QRadioButton(i18nc("@option:radio", "Ears 1"));
connect(earRadio1, &QRadioButton::clicked, this, [this] { connect(earRadio1, &QRadioButton::clicked, this, [this] {
gearView->setEar(1); gearView->setEar(1);
}); });
earGroupLayout->addWidget(earRadio1); earGroupLayout->addWidget(earRadio1);
auto earRadio2 = new QRadioButton(QStringLiteral("Ears 2")); auto earRadio2 = new QRadioButton(i18nc("@option:radio", "Ears 2"));
connect(earRadio2, &QRadioButton::clicked, this, [this] { connect(earRadio2, &QRadioButton::clicked, this, [this] {
gearView->setEar(2); gearView->setEar(2);
}); });
earGroupLayout->addWidget(earRadio2); earGroupLayout->addWidget(earRadio2);
auto earRadio3 = new QRadioButton(QStringLiteral("Ears 3")); auto earRadio3 = new QRadioButton(i18nc("@option:radio", "Ears 3"));
connect(earRadio3, &QRadioButton::clicked, this, [this] { connect(earRadio3, &QRadioButton::clicked, this, [this] {
gearView->setEar(3); gearView->setEar(3);
}); });
@ -372,23 +375,23 @@ QGroupBox *FullModelViewer::addEarGroup()
QGroupBox *FullModelViewer::addTailGroup() QGroupBox *FullModelViewer::addTailGroup()
{ {
auto tailGroup = new QGroupBox(QStringLiteral("Tail")); auto tailGroup = new QGroupBox(i18nc("@title:group", "Tail"));
auto tailGroupLayout = new QVBoxLayout(); auto tailGroupLayout = new QVBoxLayout();
tailGroup->setLayout(tailGroupLayout); tailGroup->setLayout(tailGroupLayout);
auto tailRadio1 = new QRadioButton(QStringLiteral("Tail 1")); auto tailRadio1 = new QRadioButton(i18nc("@option:radio", "Tail 1"));
connect(tailRadio1, &QRadioButton::clicked, this, [this] { connect(tailRadio1, &QRadioButton::clicked, this, [this] {
gearView->setTail(1); gearView->setTail(1);
}); });
tailGroupLayout->addWidget(tailRadio1); tailGroupLayout->addWidget(tailRadio1);
auto tailRadio2 = new QRadioButton(QStringLiteral("Tail 2")); auto tailRadio2 = new QRadioButton(i18nc("@option:radio", "Tail 2"));
connect(tailRadio2, &QRadioButton::clicked, this, [this] { connect(tailRadio2, &QRadioButton::clicked, this, [this] {
gearView->setTail(2); gearView->setTail(2);
}); });
tailGroupLayout->addWidget(tailRadio2); tailGroupLayout->addWidget(tailRadio2);
auto tailRadio3 = new QRadioButton(QStringLiteral("Tail 3")); auto tailRadio3 = new QRadioButton(i18nc("@option:radio", "Tail 3"));
connect(tailRadio3, &QRadioButton::clicked, this, [this] { connect(tailRadio3, &QRadioButton::clicked, this, [this] {
gearView->setTail(3); gearView->setTail(3);
}); });

View file

@ -3,6 +3,7 @@
#include "gearlistmodel.h" #include "gearlistmodel.h"
#include <KLocalizedString>
#include <QtConcurrent> #include <QtConcurrent>
#include <magic_enum.hpp> #include <magic_enum.hpp>
@ -128,7 +129,7 @@ QVariant GearListModel::headerData(int section, Qt::Orientation orientation, int
{ {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
if (section == 0) { if (section == 0) {
return QStringLiteral("Name"); return i18nc("@title:column Item name", "Name");
} }
} }

View file

@ -3,6 +3,7 @@
#include "gearlistwidget.h" #include "gearlistwidget.h"
#include <KLocalizedString>
#include <QLineEdit> #include <QLineEdit>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -24,7 +25,7 @@ GearListWidget::GearListWidget(GameData *data, QWidget *parent)
searchModel->setFilterCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); searchModel->setFilterCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
auto searchEdit = new QLineEdit(); auto searchEdit = new QLineEdit();
searchEdit->setPlaceholderText(QStringLiteral("Search...")); searchEdit->setPlaceholderText(i18nc("@info:placeholder Search through items", "Search…"));
searchEdit->setClearButtonEnabled(true); searchEdit->setClearButtonEnabled(true);
searchEdit->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::BottomEdge})); searchEdit->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::BottomEdge}));
connect(searchEdit, &QLineEdit::textChanged, this, [=](const QString &text) { connect(searchEdit, &QLineEdit::textChanged, this, [=](const QString &text) {

View file

@ -34,6 +34,7 @@ GearView::GearView(GameData *data, FileCache &cache, QWidget *parent)
ImGui::SetWindowPos(ImVec2(0, 0)); ImGui::SetWindowPos(ImVec2(0, 0));
ImGui::SetWindowSize(io.DisplaySize); ImGui::SetWindowSize(io.DisplaySize);
// TODO: localize
const char *loadingLabel{"Loading gear..."}; const char *loadingLabel{"Loading gear..."};
ImGui::SetCursorPosX((io.DisplaySize.x - ImGui::CalcTextSize(loadingLabel).x) * 0.5f); ImGui::SetCursorPosX((io.DisplaySize.x - ImGui::CalcTextSize(loadingLabel).x) * 0.5f);
ImGui::SetCursorPosY((io.DisplaySize.y - ImGui::CalcTextSize(loadingLabel).y) * 0.5f); ImGui::SetCursorPosY((io.DisplaySize.y - ImGui::CalcTextSize(loadingLabel).y) * 0.5f);

View file

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <KLocalizedString>
#include <QApplication> #include <QApplication>
#include <physis.hpp> #include <physis.hpp>
@ -13,10 +14,7 @@ int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
customizeAboutData(QStringLiteral("armoury"), customizeAboutData(QStringLiteral("armoury"), QStringLiteral("zone.xiv.armoury"), QStringLiteral("Gear Editor"), i18n("Program to view FFXIV gear."));
QStringLiteral("zone.xiv.armoury"),
QStringLiteral("Gear Editor"),
QStringLiteral("Program to view FFXIV gear."));
// Default to a sensible message pattern // Default to a sensible message pattern
if (qEnvironmentVariableIsEmpty("QT_MESSAGE_PATTERN")) { if (qEnvironmentVariableIsEmpty("QT_MESSAGE_PATTERN")) {

View file

@ -8,6 +8,7 @@
#include <QTableWidget> #include <QTableWidget>
#include <QTimer> #include <QTimer>
#include <KLocalizedString>
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
#include <QDesktopServices> #include <QDesktopServices>
@ -53,9 +54,9 @@ MainWindow::MainWindow(GameData *in_data)
metadataView = new MetadataView(&data); metadataView = new MetadataView(&data);
auto tabWidget = new QTabWidget(); auto tabWidget = new QTabWidget();
tabWidget->addTab(gearView, QStringLiteral("Models")); tabWidget->addTab(gearView, i18nc("@title:tab", "Models"));
tabWidget->addTab(materialView, QStringLiteral("Materials")); tabWidget->addTab(materialView, i18nc("@title:tab", "Materials"));
tabWidget->addTab(metadataView, QStringLiteral("Metadata")); tabWidget->addTab(metadataView, i18nc("@title:tab", "Metadata"));
tabWidget->setDocumentMode(true); // Don't draw the borders tabWidget->setDocumentMode(true); // Don't draw the borders
tabWidget->tabBar()->setExpanding(true); tabWidget->tabBar()->setExpanding(true);
dummyWidget->addWidget(tabWidget); dummyWidget->addWidget(tabWidget);
@ -68,18 +69,18 @@ MainWindow::MainWindow(GameData *in_data)
void MainWindow::setupAdditionalMenus(QMenuBar *menuBar) void MainWindow::setupAdditionalMenus(QMenuBar *menuBar)
{ {
auto toolsMenu = menuBar->addMenu(QStringLiteral("Tools")); auto toolsMenu = menuBar->addMenu(i18nc("@title:menu", "Tools"));
auto cmpEditorMenu = toolsMenu->addAction(QStringLiteral("CMP Editor")); auto cmpEditorMenu = toolsMenu->addAction(i18nc("@action:inmenu CMP is an abbreviation", "CMP Editor"));
cmpEditorMenu->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); cmpEditorMenu->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
connect(cmpEditorMenu, &QAction::triggered, [this] { connect(cmpEditorMenu, &QAction::triggered, [this] {
auto cmpEditor = new CmpEditor(&data); auto cmpEditor = new CmpEditor(&data);
cmpEditor->show(); cmpEditor->show();
}); });
auto windowMenu = menuBar->addMenu(QStringLiteral("Window")); auto windowMenu = menuBar->addMenu(i18nc("@title:menu", "Window"));
auto fmvMenu = windowMenu->addAction(QStringLiteral("Full Model viewer")); auto fmvMenu = windowMenu->addAction(i18nc("@action:inmenu", "Full Model Viewer"));
fmvMenu->setCheckable(true); fmvMenu->setCheckable(true);
fmvMenu->setIcon(QIcon::fromTheme(QStringLiteral("user-symbolic"))); fmvMenu->setIcon(QIcon::fromTheme(QStringLiteral("user-symbolic")));
connect(fmvMenu, &QAction::toggled, [this](bool toggled) { connect(fmvMenu, &QAction::toggled, [this](bool toggled) {
@ -93,9 +94,9 @@ void MainWindow::setupAdditionalMenus(QMenuBar *menuBar)
fmvMenu->setChecked(fullModelViewer->isVisible()); fmvMenu->setChecked(fullModelViewer->isVisible());
}); });
auto settingsMenu = menuBar->addMenu(QStringLiteral("Settings")); auto settingsMenu = menuBar->addMenu(i18nc("@title:menu", "Settings"));
auto settingsAction = settingsMenu->addAction(QStringLiteral("Configure Armoury...")); auto settingsAction = settingsMenu->addAction(i18nc("@action:inmenu", "Configure Armoury…"));
settingsAction->setIcon(QIcon::fromTheme(QStringLiteral("configure-symbolic"))); settingsAction->setIcon(QIcon::fromTheme(QStringLiteral("configure-symbolic")));
connect(settingsAction, &QAction::triggered, [this] { connect(settingsAction, &QAction::triggered, [this] {
auto settingsWindow = new SettingsWindow(); auto settingsWindow = new SettingsWindow();

View file

@ -5,6 +5,7 @@
#include <KConfig> #include <KConfig>
#include <KConfigGroup> #include <KConfigGroup>
#include <KLocalizedString>
#include <QDebug> #include <QDebug>
#include <QFileDialog> #include <QFileDialog>
#include <QLineEdit> #include <QLineEdit>
@ -83,7 +84,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
}); });
controlLayout->addWidget(lodCombo); controlLayout->addWidget(lodCombo);
addToFMVButton = new QPushButton(QStringLiteral("Add to FMV")); addToFMVButton = new QPushButton(i18nc("@action:button FMV is an abbreviation for Full Model Viewer", "Add to FMV"));
addToFMVButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add-user"))); addToFMVButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add-user")));
connect(addToFMVButton, &QPushButton::clicked, this, [this](bool) { connect(addToFMVButton, &QPushButton::clicked, this, [this](bool) {
if (currentGear.has_value()) { if (currentGear.has_value()) {
@ -91,7 +92,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
} }
}); });
editButton = new QPushButton(QStringLiteral("Edit")); editButton = new QPushButton(i18nc("@action:button", "Edit"));
editButton->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); editButton->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
connect(editButton, &QPushButton::clicked, this, [this](bool) { connect(editButton, &QPushButton::clicked, this, [this](bool) {
// Export in default location // Export in default location
@ -134,7 +135,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
}); });
topControlLayout->addWidget(editButton); topControlLayout->addWidget(editButton);
importButton = new QPushButton(QStringLiteral("Import...")); importButton = new QPushButton(i18nc("@action:button", "Import…"));
importButton->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); importButton->setIcon(QIcon::fromTheme(QStringLiteral("document-import")));
connect(importButton, &QPushButton::clicked, this, [this](bool) { connect(importButton, &QPushButton::clicked, this, [this](bool) {
if (currentGear.has_value()) { if (currentGear.has_value()) {
@ -157,7 +158,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
if (!QDir().exists(path)) if (!QDir().exists(path))
QDir().mkpath(path); QDir().mkpath(path);
const QString fileName = QFileDialog::getOpenFileName(this, tr("Import Model"), path, tr("glTF Binary File (*.glb)")); const QString fileName = QFileDialog::getOpenFileName(this, i18nc("@title:window", "Import Model"), path, i18n("glTF Binary File (*.glb)"));
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
importModel(fileName); importModel(fileName);
} }
@ -166,7 +167,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
topControlLayout->addWidget(importButton); topControlLayout->addWidget(importButton);
auto testMenu = new QMenu(); auto testMenu = new QMenu();
auto gltfAction = testMenu->addAction(QStringLiteral("glTF")); auto gltfAction = testMenu->addAction(i18nc("@action:inmenu", "glTF"));
connect(gltfAction, &QAction::triggered, this, [this](bool) { connect(gltfAction, &QAction::triggered, this, [this](bool) {
if (currentGear.has_value()) { if (currentGear.has_value()) {
// TODO: deduplicate // TODO: deduplicate
@ -194,7 +195,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
gearView->exportModel(fileName); gearView->exportModel(fileName);
} }
}); });
auto mdlAction = testMenu->addAction(QStringLiteral("MDL")); auto mdlAction = testMenu->addAction(i18nc("@action:inmenu", "MDL"));
connect(mdlAction, &QAction::triggered, this, [this, data](bool) { connect(mdlAction, &QAction::triggered, this, [this, data](bool) {
if (currentGear.has_value()) { if (currentGear.has_value()) {
// TODO: deduplicate // TODO: deduplicate
@ -202,8 +203,10 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
return QString(mdlPath).section(QLatin1Char('/'), -1); return QString(mdlPath).section(QLatin1Char('/'), -1);
}; };
const QString fileName = const QString fileName = QFileDialog::getSaveFileName(this,
QFileDialog::getSaveFileName(this, tr("Export Model"), sanitizeMdlPath(gearView->getLoadedGearPath()), tr("MDL File (*.mdl)")); i18nc("@title:window", "Export Model"),
sanitizeMdlPath(gearView->getLoadedGearPath()),
i18n("MDL File (*.mdl)"));
auto buffer = physis_gamedata_extract_file(data, gearView->getLoadedGearPath().toStdString().c_str()); auto buffer = physis_gamedata_extract_file(data, gearView->getLoadedGearPath().toStdString().c_str());
@ -214,7 +217,7 @@ SingleGearView::SingleGearView(GameData *data, FileCache &cache, QWidget *parent
} }
}); });
exportButton = new QPushButton(QStringLiteral("Export")); exportButton = new QPushButton(i18nc("@action:button", "Export"));
exportButton->setMenu(testMenu); exportButton->setMenu(testMenu);
exportButton->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); exportButton->setIcon(QIcon::fromTheme(QStringLiteral("document-export")));
@ -386,7 +389,7 @@ void SingleGearView::reloadGear()
lodCombo->clear(); lodCombo->clear();
for (int i = 0; i < gearView->lodCount(); i++) { for (int i = 0; i < gearView->lodCount(); i++) {
lodCombo->addItem(QStringLiteral("LOD %1").arg(i), i); lodCombo->addItem(i18nc("@action:inmenu LOD stands for Level of Detail", "LOD %1").arg(i), i);
} }
if (oldLod < gearView->lodCount()) { if (oldLod < gearView->lodCount()) {
lodCombo->setCurrentIndex(oldLod); lodCombo->setCurrentIndex(oldLod);