изменено: CMakeLists.txt
новый файл: appimage-build.nix новый файл: assets/icons/erlu.ico изменено: default.nix новый файл: packaging/windows/erlu.rc изменено: src/MainWindow.cpp изменено: src/MainWindow.h изменено: src/items/BlockItem.cpp изменено: src/items/HeaderFooterItem.cpp изменено: src/main.cpp изменено: src/plugins/color/ColorsPlugin.cpp изменено: src/plugins/color/translations/colors_en.ts изменено: src/plugins/color/translations/colors_fr.ts изменено: src/plugins/color/translations/colors_ru.ts
This commit is contained in:
parent
17f793f334
commit
58198c6ecd
14 changed files with 428 additions and 139 deletions
|
|
@ -54,6 +54,14 @@ static const char* kDiagramFileFilter = QT_TR_NOOP("IDEF0 Diagram (*.idef0);;JSO
|
|||
static const char* kPdfFileFilter = QT_TR_NOOP("PDF (*.pdf)");
|
||||
static const char* kMarkdownFileFilter = QT_TR_NOOP("Markdown (*.md)");
|
||||
|
||||
static QFileDialog::Options themedFileDialogOptions() {
|
||||
QFileDialog::Options options;
|
||||
#if defined(Q_OS_WIN)
|
||||
options |= QFileDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
return options;
|
||||
}
|
||||
|
||||
static QPageSize::PageSizeId pageSizeFromMeta(const QVariantMap& meta) {
|
||||
const QString size = meta.value("pageSize", "A4").toString();
|
||||
if (size == "A1") return QPageSize::A1;
|
||||
|
|
@ -95,7 +103,7 @@ static QVariantMap mergeWithDiagramState(QVariantMap globalMeta, const QVariantM
|
|||
return globalMeta;
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(const QString& startupPath, QWidget* parent)
|
||||
MainWindow::MainWindow(const QString& startupPath, QWidget* parent, bool skipStartupPrompt)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setupUi();
|
||||
|
|
@ -106,7 +114,7 @@ MainWindow::MainWindow(const QString& startupPath, QWidget* parent)
|
|||
QTimer::singleShot(0, this, &QWidget::close);
|
||||
return;
|
||||
}
|
||||
} else if (!promptStartup()) {
|
||||
} else if (!skipStartupPrompt && !promptStartup()) {
|
||||
QTimer::singleShot(0, this, &QWidget::close);
|
||||
return;
|
||||
}
|
||||
|
|
@ -262,7 +270,8 @@ void MainWindow::setupActions() {
|
|||
|
||||
connect(actNew, &QAction::triggered, this, [this]{ newDiagram(); });
|
||||
connect(actOpen, &QAction::triggered, this, [this]{
|
||||
const QString path = QFileDialog::getOpenFileName(this, tr("Open diagram"), QString(), tr(kDiagramFileFilter));
|
||||
const QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Open diagram"), QString(), tr(kDiagramFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (!path.isEmpty()) {
|
||||
loadDiagramFromPath(path);
|
||||
}
|
||||
|
|
@ -293,14 +302,16 @@ void MainWindow::setupActions() {
|
|||
|
||||
connect(actSave, &QAction::triggered, this, [this, saveTo]{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
const QString path = QFileDialog::getSaveFileName(this, tr("Save diagram"), QString(), tr(kDiagramFileFilter));
|
||||
const QString path = QFileDialog::getSaveFileName(
|
||||
this, tr("Save diagram"), QString(), tr(kDiagramFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (!path.isEmpty()) saveTo(path);
|
||||
} else {
|
||||
saveTo(m_currentFile);
|
||||
}
|
||||
});
|
||||
connect(actSaveAs, &QAction::triggered, this, [this, saveTo]{
|
||||
const QString path = QFileDialog::getSaveFileName(this, tr("Save diagram as"), QString(), tr(kDiagramFileFilter));
|
||||
const QString path = QFileDialog::getSaveFileName(
|
||||
this, tr("Save diagram as"), QString(), tr(kDiagramFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (!path.isEmpty()) saveTo(path);
|
||||
});
|
||||
connect(actExportPdf, &QAction::triggered, this, [this]{
|
||||
|
|
@ -411,9 +422,77 @@ static QString symbolPlacementDefault(const QLocale& loc, const QString& sym) {
|
|||
return "?1";
|
||||
}
|
||||
|
||||
static void applyWindowsMenuPaletteFix(QMainWindow* window) {
|
||||
#if defined(Q_OS_WIN)
|
||||
if (!window || !window->menuBar()) return;
|
||||
const QPalette pal = qApp->palette();
|
||||
const QString menuBg = pal.color(QPalette::Window).name(QColor::HexRgb);
|
||||
const QString popupBg = pal.color(QPalette::Base).name(QColor::HexRgb);
|
||||
const QString text = pal.color(QPalette::Active, QPalette::WindowText).name(QColor::HexRgb);
|
||||
const QString selectedBg = pal.color(QPalette::Highlight).name(QColor::HexRgb);
|
||||
const QString selectedText = pal.color(QPalette::HighlightedText).name(QColor::HexRgb);
|
||||
const QString disabledText = pal.color(QPalette::Disabled, QPalette::WindowText).name(QColor::HexRgb);
|
||||
|
||||
window->menuBar()->setStyleSheet(QStringLiteral(
|
||||
"QMenuBar { background-color: %1; color: %2; }"
|
||||
"QMenuBar::item { background: transparent; color: %2; padding: 4px 8px; }"
|
||||
"QMenuBar::item:selected { background-color: %3; color: %4; }"
|
||||
"QMenuBar::item:disabled { color: %5; }"
|
||||
"QMenu { background-color: %6; color: %2; border: 1px solid %1; }"
|
||||
"QMenu::item { color: %2; }"
|
||||
"QMenu::item:selected { background-color: %3; color: %4; }"
|
||||
"QMenu::item:disabled { color: %5; }")
|
||||
.arg(menuBg, text, selectedBg, selectedText, disabledText, popupBg));
|
||||
#else
|
||||
Q_UNUSED(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void applyWindowsDialogPaletteFix(bool darkMode) {
|
||||
#if defined(Q_OS_WIN)
|
||||
if (!darkMode) {
|
||||
qApp->setStyleSheet(QString());
|
||||
return;
|
||||
}
|
||||
const QPalette pal = qApp->palette();
|
||||
const QString window = pal.color(QPalette::Window).name(QColor::HexRgb);
|
||||
const QString base = pal.color(QPalette::Base).name(QColor::HexRgb);
|
||||
const QString text = pal.color(QPalette::Active, QPalette::WindowText).name(QColor::HexRgb);
|
||||
const QString border = pal.color(QPalette::Mid).name(QColor::HexRgb);
|
||||
const QString btn = pal.color(QPalette::Button).name(QColor::HexRgb);
|
||||
const QString btnText = pal.color(QPalette::Active, QPalette::ButtonText).name(QColor::HexRgb);
|
||||
const QString disabled = pal.color(QPalette::Disabled, QPalette::WindowText).name(QColor::HexRgb);
|
||||
const QString highlight = pal.color(QPalette::Highlight).name(QColor::HexRgb);
|
||||
const QString highlightedText = pal.color(QPalette::HighlightedText).name(QColor::HexRgb);
|
||||
|
||||
qApp->setStyleSheet(QStringLiteral(
|
||||
"QDialog, QMessageBox, QInputDialog, QFileDialog, QColorDialog { background-color: %1; color: %2; }"
|
||||
"QTabWidget::pane { background-color: %1; border: 1px solid %5; }"
|
||||
"QTabBar::tab { background-color: %3; color: %4; border: 1px solid %5; padding: 4px 10px; }"
|
||||
"QTabBar::tab:selected { background-color: %1; color: %2; }"
|
||||
"QTabBar::tab:disabled { color: %6; }"
|
||||
"QTabWidget QWidget { background-color: %1; color: %2; }"
|
||||
"QLabel, QCheckBox, QRadioButton, QGroupBox { color: %2; }"
|
||||
"QPushButton { background-color: %3; color: %4; border: 1px solid %5; padding: 4px 10px; }"
|
||||
"QPushButton:disabled { color: %6; }"
|
||||
"QLineEdit, QPlainTextEdit, QTextEdit, QAbstractSpinBox, QComboBox {"
|
||||
" background-color: %7; color: %2; border: 1px solid %5; selection-background-color: %8; selection-color: %9; }"
|
||||
"QAbstractItemView, QListView, QTreeView, QTableView {"
|
||||
" background-color: %7; color: %2; border: 1px solid %5; selection-background-color: %8; selection-color: %9; }"
|
||||
"QDialogButtonBox QPushButton { min-width: 80px; }")
|
||||
.arg(window, text, btn, btnText, border, disabled, base, highlight, highlightedText));
|
||||
#else
|
||||
Q_UNUSED(darkMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MainWindow::showWelcome() {
|
||||
auto* dlg = new QDialog(this);
|
||||
dlg->setWindowTitle(tr("Welcome"));
|
||||
dlg->setPalette(qApp->palette());
|
||||
#if defined(Q_OS_WIN)
|
||||
dlg->setStyleSheet(qApp->styleSheet());
|
||||
#endif
|
||||
auto* tabs = new QTabWidget(dlg);
|
||||
|
||||
// General tab
|
||||
|
|
@ -445,20 +524,6 @@ bool MainWindow::showWelcome() {
|
|||
general->setLayout(genForm);
|
||||
tabs->addTab(general, tr("General"));
|
||||
|
||||
// Numbering tab (placeholder)
|
||||
auto* numbering = new QWidget(dlg);
|
||||
auto* numLayout = new QVBoxLayout(numbering);
|
||||
numLayout->addStretch();
|
||||
numbering->setLayout(numLayout);
|
||||
tabs->addTab(numbering, tr("Numbering"));
|
||||
|
||||
// Display tab (placeholder)
|
||||
auto* display = new QWidget(dlg);
|
||||
auto* disLayout = new QVBoxLayout(display);
|
||||
disLayout->addStretch();
|
||||
display->setLayout(disLayout);
|
||||
tabs->addTab(display, tr("Display"));
|
||||
|
||||
// ABC Units tab
|
||||
auto* units = new QWidget(dlg);
|
||||
auto* unitsForm = new QFormLayout(units);
|
||||
|
|
@ -577,17 +642,31 @@ void MainWindow::resetScene() {
|
|||
|
||||
void MainWindow::newDiagram() {
|
||||
if (!showWelcome()) return;
|
||||
resetScene();
|
||||
const QRectF bounds = m_scene->contentRect().isNull() ? m_scene->sceneRect() : m_scene->contentRect();
|
||||
m_scene->createBlockAt(bounds.center());
|
||||
m_currentFile.clear();
|
||||
markDirty(false);
|
||||
// Keep main window visible and focused after closing modal creation dialogs.
|
||||
QTimer::singleShot(0, this, [this]{
|
||||
setWindowState(windowState() & ~Qt::WindowMinimized);
|
||||
showNormal();
|
||||
raise();
|
||||
activateWindow();
|
||||
auto* win = new MainWindow(QString(), nullptr, true);
|
||||
win->m_welcomeState = m_welcomeState;
|
||||
|
||||
if (win->m_actDarkMode && win->m_actFollowSystemTheme) {
|
||||
const QSignalBlocker b2(win->m_actDarkMode);
|
||||
const QSignalBlocker b3(win->m_actFollowSystemTheme);
|
||||
win->m_actDarkMode->setChecked(win->m_welcomeState.value("darkMode", false).toBool());
|
||||
win->m_actFollowSystemTheme->setChecked(win->m_welcomeState.value("followSystemTheme", false).toBool());
|
||||
win->m_actDarkMode->setEnabled(!win->m_actFollowSystemTheme->isChecked());
|
||||
}
|
||||
|
||||
win->m_welcomeState["resolvedDarkMode"] = win->effectiveDarkMode();
|
||||
win->applyAppPalette(win->m_welcomeState.value("resolvedDarkMode").toBool());
|
||||
win->resetScene();
|
||||
const QRectF bounds = win->m_scene->contentRect().isNull() ? win->m_scene->sceneRect() : win->m_scene->contentRect();
|
||||
win->m_scene->createBlockAt(bounds.center());
|
||||
win->m_currentFile.clear();
|
||||
win->markDirty(false);
|
||||
win->resize(size());
|
||||
win->show();
|
||||
QTimer::singleShot(0, win, [win]{
|
||||
win->setWindowState(win->windowState() & ~Qt::WindowMinimized);
|
||||
win->showNormal();
|
||||
win->raise();
|
||||
win->activateWindow();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -601,7 +680,8 @@ bool MainWindow::promptStartup() {
|
|||
box.exec();
|
||||
if (box.clickedButton() == cancelBtn) return false;
|
||||
if (box.clickedButton() == openBtn) {
|
||||
const QString path = QFileDialog::getOpenFileName(this, tr("Open diagram"), QString(), tr(kDiagramFileFilter));
|
||||
const QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Open diagram"), QString(), tr(kDiagramFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (path.isEmpty()) return false;
|
||||
return loadDiagramFromPath(path);
|
||||
}
|
||||
|
|
@ -659,7 +739,8 @@ bool MainWindow::loadDiagramFromPath(const QString& path) {
|
|||
}
|
||||
|
||||
bool MainWindow::exportPdf(bool allDiagrams, bool numberPages, bool forceLightTheme) {
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("Export to PDF"), QString(), tr(kPdfFileFilter));
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
this, tr("Export to PDF"), QString(), tr(kPdfFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (path.isEmpty()) return false;
|
||||
if (QFileInfo(path).suffix().isEmpty()) path += ".pdf";
|
||||
|
||||
|
|
@ -765,7 +846,8 @@ bool MainWindow::exportPdf(bool allDiagrams, bool numberPages, bool forceLightTh
|
|||
|
||||
bool MainWindow::exportMarkdownExplanation() {
|
||||
if (!m_scene) return false;
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("Export to Markdown"), QString(), tr(kMarkdownFileFilter));
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
this, tr("Export to Markdown"), QString(), tr(kMarkdownFileFilter), nullptr, themedFileDialogOptions());
|
||||
if (path.isEmpty()) return false;
|
||||
if (QFileInfo(path).suffix().isEmpty()) path += ".md";
|
||||
|
||||
|
|
@ -909,6 +991,8 @@ void MainWindow::applyAppPalette(bool darkMode) {
|
|||
static const QPalette defaultPalette = qApp->palette();
|
||||
if (!darkMode) {
|
||||
qApp->setPalette(defaultPalette);
|
||||
applyWindowsDialogPaletteFix(false);
|
||||
applyWindowsMenuPaletteFix(this);
|
||||
return;
|
||||
}
|
||||
QPalette p;
|
||||
|
|
@ -925,6 +1009,8 @@ void MainWindow::applyAppPalette(bool darkMode) {
|
|||
p.setColor(QPalette::Highlight, QColor(75, 110, 180));
|
||||
p.setColor(QPalette::HighlightedText, QColor(255, 255, 255));
|
||||
qApp->setPalette(p);
|
||||
applyWindowsDialogPaletteFix(true);
|
||||
applyWindowsMenuPaletteFix(this);
|
||||
}
|
||||
|
||||
bool MainWindow::openDiagramPath(const QString& path) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class PluginManager;
|
|||
class MainWindow final : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(const QString& startupPath = QString(), QWidget* parent = nullptr);
|
||||
explicit MainWindow(const QString& startupPath = QString(), QWidget* parent = nullptr, bool skipStartupPrompt = false);
|
||||
bool openDiagramPath(const QString& path);
|
||||
DiagramScene* scene() const { return m_scene; }
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <QCheckBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLocale>
|
||||
#include <QApplication>
|
||||
|
||||
#include "DiagramScene.h"
|
||||
|
||||
|
|
@ -281,7 +282,7 @@ QString BlockItem::formattedPrice() const {
|
|||
}
|
||||
|
||||
void BlockItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* e) {
|
||||
auto* dlg = new QDialog();
|
||||
auto* dlg = new QDialog(QApplication::activeWindow());
|
||||
dlg->setWindowTitle(tr("Edit block"));
|
||||
|
||||
auto* layout = new QVBoxLayout(dlg);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <QButtonGroup>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QApplication>
|
||||
|
||||
HeaderFooterItem::HeaderFooterItem(DiagramScene* scene)
|
||||
: QGraphicsObject(nullptr)
|
||||
|
|
@ -221,7 +222,7 @@ void HeaderFooterItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* e) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto* dlg = new QDialog();
|
||||
auto* dlg = new QDialog(QApplication::activeWindow());
|
||||
dlg->setWindowTitle(tr("Edit header/footer"));
|
||||
auto* layout = new QVBoxLayout(dlg);
|
||||
auto* form = new QFormLayout();
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ int main(int argc, char** argv) {
|
|||
|
||||
const QStringList searchPaths = {
|
||||
QDir::currentPath() + "/translations",
|
||||
QCoreApplication::applicationDirPath() + "/translations",
|
||||
QCoreApplication::applicationDirPath() + "/../translations",
|
||||
QCoreApplication::applicationDirPath() + "/../Resources/translations",
|
||||
QCoreApplication::applicationDirPath() + "/../share/idef0/translations",
|
||||
":/i18n"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,94 +1,98 @@
|
|||
#include "plugins/color/ColorsPlugin.h"
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QObject>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
static void ensureTranslator(Idef0Host* host) {
|
||||
static bool loaded = false;
|
||||
static QTranslator* translator = nullptr;
|
||||
if (loaded || !host || !host->plugin_dir) return;
|
||||
const char* dirC = host->plugin_dir(host->opaque);
|
||||
if (!dirC) return;
|
||||
const QString dir = QString::fromUtf8(dirC);
|
||||
const QString baseLocale = QLocale().name().replace('-', '_');
|
||||
const QString shortLocale = baseLocale.section('_', 0, 0);
|
||||
|
||||
QStringList candidates;
|
||||
auto addCandidate = [&](const QString& c) {
|
||||
if (c.isEmpty()) return;
|
||||
if (c == QStringLiteral("C") || c == QStringLiteral("POSIX")) return;
|
||||
candidates << c;
|
||||
};
|
||||
addCandidate(baseLocale);
|
||||
addCandidate(shortLocale);
|
||||
const QString sysName = QLocale::system().name().replace('-', '_');
|
||||
addCandidate(sysName);
|
||||
addCandidate(sysName.section('_', 0, 0));
|
||||
for (const QString& lang : QLocale::system().uiLanguages()) {
|
||||
const QString norm = QString(lang).replace('-', '_');
|
||||
addCandidate(norm);
|
||||
addCandidate(norm.section('_', 0, 0));
|
||||
}
|
||||
const QString envLang = QString::fromLocal8Bit(qgetenv("LANG")).section('.', 0, 0).replace('-', '_');
|
||||
addCandidate(envLang);
|
||||
addCandidate(envLang.section('_', 0, 0));
|
||||
|
||||
candidates.removeDuplicates();
|
||||
if (candidates.isEmpty()) candidates << QStringLiteral("en");
|
||||
|
||||
translator = new QTranslator(qApp);
|
||||
qInfo() << "[colors plugin] translator search in" << dir << "candidates" << candidates;
|
||||
for (const QString& loc : candidates) {
|
||||
if (loc.isEmpty()) continue;
|
||||
const QString baseName = QStringLiteral("colors_%1").arg(loc);
|
||||
if (translator->load(baseName, dir + "/translations")) {
|
||||
qApp->installTranslator(translator);
|
||||
qInfo() << "[colors plugin] translator loaded" << baseName;
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
qWarning() << "[colors plugin] translator not found, falling back to default language";
|
||||
delete translator;
|
||||
translator = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void onSetColor(void*, Idef0Host* host) {
|
||||
if (!host || !host->selected_items || !host->set_item_color) return;
|
||||
ensureTranslator(host);
|
||||
#include "plugins/color/ColorsPlugin.h"
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QObject>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
static void ensureTranslator(Idef0Host* host) {
|
||||
static bool loaded = false;
|
||||
static QTranslator* translator = nullptr;
|
||||
if (loaded || !host || !host->plugin_dir) return;
|
||||
const char* dirC = host->plugin_dir(host->opaque);
|
||||
if (!dirC) return;
|
||||
const QString dir = QString::fromUtf8(dirC);
|
||||
const QString baseLocale = QLocale().name().replace('-', '_');
|
||||
const QString shortLocale = baseLocale.section('_', 0, 0);
|
||||
|
||||
QStringList candidates;
|
||||
auto addCandidate = [&](const QString& c) {
|
||||
if (c.isEmpty()) return;
|
||||
if (c == QStringLiteral("C") || c == QStringLiteral("POSIX")) return;
|
||||
candidates << c;
|
||||
};
|
||||
addCandidate(baseLocale);
|
||||
addCandidate(shortLocale);
|
||||
const QString sysName = QLocale::system().name().replace('-', '_');
|
||||
addCandidate(sysName);
|
||||
addCandidate(sysName.section('_', 0, 0));
|
||||
for (const QString& lang : QLocale::system().uiLanguages()) {
|
||||
const QString norm = QString(lang).replace('-', '_');
|
||||
addCandidate(norm);
|
||||
addCandidate(norm.section('_', 0, 0));
|
||||
}
|
||||
const QString envLang = QString::fromLocal8Bit(qgetenv("LANG")).section('.', 0, 0).replace('-', '_');
|
||||
addCandidate(envLang);
|
||||
addCandidate(envLang.section('_', 0, 0));
|
||||
|
||||
candidates.removeDuplicates();
|
||||
if (candidates.isEmpty()) candidates << QStringLiteral("en");
|
||||
|
||||
translator = new QTranslator(qApp);
|
||||
qInfo() << "[colors plugin] translator search in" << dir << "candidates" << candidates;
|
||||
for (const QString& loc : candidates) {
|
||||
if (loc.isEmpty()) continue;
|
||||
const QString baseName = QStringLiteral("colors_%1").arg(loc);
|
||||
if (translator->load(baseName, dir + "/translations")) {
|
||||
qApp->installTranslator(translator);
|
||||
qInfo() << "[colors plugin] translator loaded" << baseName;
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
qWarning() << "[colors plugin] translator not found, falling back to default language";
|
||||
delete translator;
|
||||
translator = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void onSetColor(void*, Idef0Host* host) {
|
||||
if (!host || !host->selected_items || !host->set_item_color) return;
|
||||
ensureTranslator(host);
|
||||
Idef0SelectedItem items[64];
|
||||
const size_t count = host->selected_items(host->opaque, items, 64);
|
||||
if (count == 0) return;
|
||||
QColor initial("#2b6ee6");
|
||||
const QColor chosen = QColorDialog::getColor(initial, nullptr, QObject::tr("Select item color"));
|
||||
QColorDialog::ColorDialogOptions options;
|
||||
#if defined(Q_OS_WIN)
|
||||
options |= QColorDialog::DontUseNativeDialog;
|
||||
#endif
|
||||
const QColor chosen = QColorDialog::getColor(initial, nullptr, QObject::tr("Select item color"), options);
|
||||
if (!chosen.isValid()) return;
|
||||
const QByteArray hex = chosen.name(QColor::HexRgb).toUtf8();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
host->set_item_color(host->opaque, items[i].kind, items[i].id, hex.constData());
|
||||
}
|
||||
}
|
||||
|
||||
static void onClearColor(void*, Idef0Host* host) {
|
||||
if (!host || !host->selected_items || !host->clear_item_color) return;
|
||||
ensureTranslator(host);
|
||||
Idef0SelectedItem items[64];
|
||||
const size_t count = host->selected_items(host->opaque, items, 64);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
host->clear_item_color(host->opaque, items[i].kind, items[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" bool idef0_plugin_init_v1(Idef0Host* host) {
|
||||
if (!host || !host->add_menu_action) return false;
|
||||
ensureTranslator(host);
|
||||
qInfo() << "[colors plugin] init, plugin dir:" << (host->plugin_dir ? host->plugin_dir(host->opaque) : "(none)");
|
||||
host->add_menu_action(host->opaque, QObject::tr("Set item color…").toUtf8().constData(), &onSetColor, nullptr);
|
||||
host->add_menu_action(host->opaque, QObject::tr("Clear item colors").toUtf8().constData(), &onClearColor, nullptr);
|
||||
return true;
|
||||
}
|
||||
const QByteArray hex = chosen.name(QColor::HexRgb).toUtf8();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
host->set_item_color(host->opaque, items[i].kind, items[i].id, hex.constData());
|
||||
}
|
||||
}
|
||||
|
||||
static void onClearColor(void*, Idef0Host* host) {
|
||||
if (!host || !host->selected_items || !host->clear_item_color) return;
|
||||
ensureTranslator(host);
|
||||
Idef0SelectedItem items[64];
|
||||
const size_t count = host->selected_items(host->opaque, items, 64);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
host->clear_item_color(host->opaque, items[i].kind, items[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" bool idef0_plugin_init_v1(Idef0Host* host) {
|
||||
if (!host || !host->add_menu_action) return false;
|
||||
ensureTranslator(host);
|
||||
qInfo() << "[colors plugin] init, plugin dir:" << (host->plugin_dir ? host->plugin_dir(host->opaque) : "(none)");
|
||||
host->add_menu_action(host->opaque, QObject::tr("Set item color...").toUtf8().constData(), &onSetColor, nullptr);
|
||||
host->add_menu_action(host->opaque, QObject::tr("Clear item colors").toUtf8().constData(), &onClearColor, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
<translation>Select item color</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set item color…</source>
|
||||
<translation>Set item color…</translation>
|
||||
<source>Set item color...</source>
|
||||
<translation>Set item color...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear item colors</source>
|
||||
|
|
@ -17,3 +17,6 @@
|
|||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="fr_FR">
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>Select item color</source>
|
||||
<translation>Choisir la couleur de l'élément</translation>
|
||||
<translation>Choisir la couleur de l'Г©lГ©ment</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set item color…</source>
|
||||
<translation>Définir la couleur de l'élément…</translation>
|
||||
<source>Set item color...</source>
|
||||
<translation>Définir la couleur de l'élément...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear item colors</source>
|
||||
<translation>Réinitialiser les couleurs des éléments</translation>
|
||||
<translation>RГ©initialiser les couleurs des Г©lГ©ments</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>Select item color</source>
|
||||
<translation>Выберите цвет элемента</translation>
|
||||
<translation>Задать цвет элемента</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set item color…</source>
|
||||
<translation>Задать цвет элемента…</translation>
|
||||
<source>Set item color...</source>
|
||||
<translation>Задать цвет элемента...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear item colors</source>
|
||||
<translation>Сбросить цвета элементов</translation>
|
||||
<translation>Очистить цвета элементов</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue