From 9f57a10bb8e99f45aaffda8ac421b32d12f6934a Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Sat, 29 Jul 2017 17:22:17 +0200 Subject: [PATCH] Make the project translatable Jeeeesh that's alot --- colorpicker/colorpickerscene.cpp | 2 +- colorpicker/colorpickerscene.hpp | 1 + cropeditor/cropeditor.cpp | 2 +- cropeditor/cropscene.cpp | 28 +++---- cropeditor/drawing/textitem.cpp | 2 +- cropeditor/drawing/textitem.hpp | 2 + cropeditor/settings/brushpenselection.cpp | 6 +- formats.cpp | 14 ---- hotkeying.cpp | 5 +- hotkeyinputdialog.cpp | 4 +- main.cpp | 17 ++++ mainwindow.cpp | 40 +++++++--- mainwindow.hpp | 4 +- recording/encoders/encodersettingsdialog.cpp | 2 +- recording/recordingformats.cpp | 6 +- recording/recordingformats.hpp | 2 + recording/recordingpreview.cpp | 8 +- screenareaselector/screenareaselector.cpp | 4 +- settings.cpp | 2 +- settingsdialog.cpp | 16 ++-- uploaders/customuploader.cpp | 83 +++++++++++--------- uploaders/customuploader.hpp | 4 + uploaders/default/clipboarduploader.cpp | 2 +- uploaders/default/clipboarduploader.hpp | 2 + uploaders/default/imgplusuploader.cpp | 7 +- uploaders/default/imgplusuploader.hpp | 2 + uploaders/default/imgursettingsdialog.cpp | 2 +- uploaders/default/imguruploader.cpp | 8 +- uploaders/default/imguruploader.hpp | 2 + uploaders/uploadersingleton.cpp | 17 ++-- uploaders/uploadersingleton.hpp | 2 +- 31 files changed, 170 insertions(+), 128 deletions(-) diff --git a/colorpicker/colorpickerscene.cpp b/colorpicker/colorpickerscene.cpp index 773d16a..ad02c24 100644 --- a/colorpicker/colorpickerscene.cpp +++ b/colorpicker/colorpickerscene.cpp @@ -16,7 +16,7 @@ ColorPickerScene::ColorPickerScene(QPixmap pixmap, QWidget *parentWidget) setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); setCursor(QCursor(Qt::CrossCursor)); setMouseTracking(true); - setWindowTitle("KShare Color Picker"); + setWindowTitle(tr("KShare Color Picker")); setAttribute(Qt::WA_DeleteOnClose); pItem = addPixmap(pixmap); diff --git a/colorpicker/colorpickerscene.hpp b/colorpicker/colorpickerscene.hpp index e2e9c55..76aebd8 100644 --- a/colorpicker/colorpickerscene.hpp +++ b/colorpicker/colorpickerscene.hpp @@ -11,6 +11,7 @@ #include class ColorPickerScene : public QGraphicsScene, public QGraphicsView { + Q_OBJECT public: ColorPickerScene(QPixmap pixmap, QWidget *parentWidget); void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index 4f0605c..511cd49 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -24,7 +24,7 @@ CropEditor::CropEditor(QPixmap image, QObject *parent) : QObject(parent) { QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); view->move(p.x(), p.y()); - view->setWindowTitle("KShare Crop Editor"); + view->setWindowTitle(tr("KShare Crop Editor")); view->activateWindow(); connect(scene, &CropScene::closedWithRect, this, &CropEditor::crop); diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 24a8743..2a76ddd 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -35,18 +35,18 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) static_cast(settings::settings().value("brushStyle", static_cast(Qt::SolidPattern)).toInt())); menu = new QMenuBar; - addDrawingAction(menu, "Free draw", ":/icons/pencil.png", [] { return new PathItem; }); - addDrawingAction(menu, "Blur", ":/icons/blur.png", [] { return new BlurItem; }); - addDrawingAction(menu, "Straight line", ":/icons/line.png", [] { return new LineItem; }); - addDrawingAction(menu, "Text", ":/icons/text.png", [] { return new TextItem; }); - addDrawingAction(menu, "Rectangle", ":/icons/rectangle.png", [] { return new RectItem; }); - addDrawingAction(menu, "Ellipse", ":/icons/circle.png", [] { return new EllipseItem; }); - addDrawingAction(menu, "Arrow", ":/icons/arrow.png", [] { return new ArrowItem; }); + addDrawingAction(menu, tr("Free draw"), ":/icons/pencil.png", [] { return new PathItem; }); + addDrawingAction(menu, tr("Blur"), ":/icons/blur.png", [] { return new BlurItem; }); + addDrawingAction(menu, tr("Straight line"), ":/icons/line.png", [] { return new LineItem; }); + addDrawingAction(menu, tr("Text"), ":/icons/text.png", [] { return new TextItem; }); + addDrawingAction(menu, tr("Rectangle"), ":/icons/rectangle.png", [] { return new RectItem; }); + addDrawingAction(menu, tr("Ellipse"), ":/icons/circle.png", [] { return new EllipseItem; }); + addDrawingAction(menu, tr("Arrow"), ":/icons/arrow.png", [] { return new ArrowItem; }); menu->addSeparator(); - addDrawingAction(menu, "Eraser", ":/icons/erase.png", [] { return new EraserItem; }); + addDrawingAction(menu, tr("Eraser"), ":/icons/erase.png", [] { return new EraserItem; }); QAction *clear = menu->addAction(""); - clear->setToolTip("Clear all drawing"); + clear->setToolTip(tr("Clear all drawing")); clear->setIcon(QIcon(":/icons/delete.png")); connect(clear, &QAction::triggered, [&] { auto its = items(); @@ -60,11 +60,11 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) } }); - addDrawingAction(menu, "Crop", ":/icons/crop.png", [] { return nullptr; }); + addDrawingAction(menu, tr("Crop"), ":/icons/crop.png", [] { return nullptr; }); menu->addSeparator(); QAction *settings = menu->addAction(""); - settings->setToolTip("Settings"); + settings->setToolTip(tr("Settings")); settings->setIcon(QIcon(":/icons/settings.png")); connect(settings, &QAction::triggered, [&] { hide(); @@ -82,13 +82,13 @@ CropScene::CropScene(QObject *parent, QPixmap pixmap) menu->addAction(fonts); menu->addSeparator(); QAction *confirm = menu->addAction(""); - confirm->setToolTip("Confirm"); + confirm->setToolTip(tr("Confirm")); confirm->setIcon(QIcon(":/icons/accept.png")); connect(confirm, &QAction::triggered, [this] { done(true); }); menu->addAction(confirm); QAction *cancel = menu->addAction(""); - cancel->setToolTip("Cancel"); + cancel->setToolTip(tr("Cancel")); cancel->setIcon(QIcon(":/icons/cancel.png")); connect(cancel, &QAction::triggered, [this] { done(false); }); menu->addAction(cancel); @@ -207,7 +207,7 @@ void CropScene::setVisible(bool visible) { QPoint p = screenshotutil::smallestScreenCoordinate() + QPoint(settings::settings().value("cropx", 0).toInt(), settings::settings().value("cropy", 0).toInt()); view->move(p.x(), p.y()); - view->setWindowTitle("KShare Crop Editor"); + view->setWindowTitle(tr("KShare Crop Editor")); view->activateWindow(); } } diff --git a/cropeditor/drawing/textitem.cpp b/cropeditor/drawing/textitem.cpp index 8ed86f5..294b45d 100644 --- a/cropeditor/drawing/textitem.cpp +++ b/cropeditor/drawing/textitem.cpp @@ -5,7 +5,7 @@ bool TextItem::init(CropScene *s) { bool ok; s->hide(); - text = QInputDialog::getText(nullptr, "Text to add", "Input", QLineEdit::Normal, QString(), &ok); + text = QInputDialog::getText(nullptr, tr("Text to add"), tr("Input"), QLineEdit::Normal, QString(), &ok); s->show(); return ok; } diff --git a/cropeditor/drawing/textitem.hpp b/cropeditor/drawing/textitem.hpp index d60fb54..9c49bf1 100644 --- a/cropeditor/drawing/textitem.hpp +++ b/cropeditor/drawing/textitem.hpp @@ -2,9 +2,11 @@ #define TEXTITEM_HPP #include "drawitem.hpp" +#include #include class TextItem : public DrawItem { + Q_DECLARE_TR_FUNCTIONS(TextItem) public: QString name() override; bool init(CropScene *s) override; diff --git a/cropeditor/settings/brushpenselection.cpp b/cropeditor/settings/brushpenselection.cpp index f2301ed..b26a681 100644 --- a/cropeditor/settings/brushpenselection.cpp +++ b/cropeditor/settings/brushpenselection.cpp @@ -37,7 +37,7 @@ BrushPenSelection::BrushPenSelection(CropScene *scene) : QDialog(), ui(new Ui::B ui->alphaSlider->setValue(brush.alpha()); ui->alphaSpin->setValue(brush.alpha()); - setWindowTitle("Crop editor settings"); + setWindowTitle(tr("Crop editor settings")); this->scene = scene; } @@ -46,12 +46,12 @@ BrushPenSelection::~BrushPenSelection() { } void BrushPenSelection::on_penColor_clicked(bool) { - pen = QColorDialog::getColor(pen, this, "Pen Color"); + pen = QColorDialog::getColor(pen, this, tr("Pen Color")); pen.setAlpha(ui->penAlphaSpin->value()); } void BrushPenSelection::on_brushColor_clicked(bool) { - brush = QColorDialog::getColor(brush, this, "Brush Color"); + brush = QColorDialog::getColor(brush, this, tr("Brush Color")); brush.setAlpha(ui->alphaSpin->value()); } diff --git a/formats.cpp b/formats.cpp index 21a8089..5e08ad3 100644 --- a/formats.cpp +++ b/formats.cpp @@ -4,13 +4,10 @@ QString formats::normalFormatName(formats::Normal format) { switch (format) { case Normal::JPG: return "JPG"; - break; case Normal::PNG: return "PNG"; - break; default: return QString(); - break; } } @@ -25,13 +22,10 @@ QString formats::normalFormatMIME(formats::Normal format) { switch (format) { case Normal::JPG: return "image/jpeg"; - break; case Normal::PNG: return "image/png"; - break; default: return QString(); - break; } } @@ -39,16 +33,12 @@ QString formats::recordingFormatName(formats::Recording format) { switch (format) { case Recording::GIF: return "GIF"; - break; case Recording::WebM: return "WEBM"; - break; case Recording::MP4: return "MP4"; - break; default: return QString(); - break; } } @@ -63,15 +53,11 @@ QString formats::recordingFormatMIME(formats::Recording format) { switch (format) { case Recording::GIF: return "image/gif"; - break; case Recording::WebM: return "video/webm"; - break; case Recording::MP4: return "video/mp4"; - break; default: return QString(); - break; } } diff --git a/hotkeying.cpp b/hotkeying.cpp index 98aeeb1..4940bb8 100644 --- a/hotkeying.cpp +++ b/hotkeying.cpp @@ -19,7 +19,7 @@ void hotkeying::hotkey(QString seqName, QKeySequence seq, std::function settings::settings().setValue(seqName.prepend("hotkey_"), seq.toString()); if (!hotkey->isRegistered() && !seq.toString().isEmpty()) qWarning().noquote().nospace() - << "Could not bind the hotkey " << seqName << "! Is the keybind already registered?"; + << QObject::tr("Could not bind the hotkey %1! Is the keybind already registered?").arg(seqName); } // forces the hotkey from settings @@ -37,7 +37,8 @@ void hotkeying::load(QString seqName, std::function func, QString def) { hotkeys.insert(seqName, h); if (!h->isRegistered() && !h->shortcut().toString().isEmpty()) qWarning().noquote().nospace() - << "Could not bind the hotkey " << seqName << "! Is the keybind already registered?"; + << QObject::tr("Could not bind the hotkey %1! Is the keybind already registered?").arg(seqName); + ; } bool hotkeying::valid(QString seq) { diff --git a/hotkeyinputdialog.cpp b/hotkeyinputdialog.cpp index 250ae13..980ec7c 100644 --- a/hotkeyinputdialog.cpp +++ b/hotkeyinputdialog.cpp @@ -28,11 +28,11 @@ void HotkeyInputDialog::keyPressEvent(QKeyEvent *e) { QKeySequence seq(e->modifiers() + e->key()); ui->keySeq->setText(seq.toString()); recording = false; - ui->recordButton->setText("Record"); + ui->recordButton->setText(tr("Record")); } } void HotkeyInputDialog::on_recordButton_clicked() { recording = !recording; - ui->recordButton->setText(recording ? "Stop recording" : "Record"); + ui->recordButton->setText(recording ? tr("Stop recording") : tr("Record")); } diff --git a/main.cpp b/main.cpp index 3c3a892..acb0275 100644 --- a/main.cpp +++ b/main.cpp @@ -13,6 +13,7 @@ extern "C" { #include } #include +#include #include #include #include @@ -59,6 +60,19 @@ void handler(QtMsgType type, const QMessageLogContext &, const QString &msg) { } } +void loadTranslation(QString locale) { + QFile resource(":/langs/kshare_" + locale + ".qm"); + if (!resource.exists()) return; + resource.open(QIODevice::ReadOnly); + + QTranslator *translator = new QTranslator; + QByteArray file = resource.readAll(); + QByteArray *permFile = new QByteArray; + permFile->swap(file); + translator->load((const unsigned char *)permFile->constData(), permFile->size()); + QApplication::installTranslator(translator); +} + int main(int argc, char *argv[]) { av_register_all(); qInstallMessageHandler(handler); @@ -68,6 +82,9 @@ int main(int argc, char *argv[]) { a.setOrganizationName("ArsenArsen"); a.setApplicationVersion("4.1"); + QString locale = QLocale::system().name(); + if (locale != "en_US") loadTranslation(locale); + QCommandLineParser parser; parser.addHelpOption(); diff --git a/mainwindow.cpp b/mainwindow.cpp index a2522bb..a23cef8 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -19,10 +19,10 @@ MainWindow *MainWindow::instance; void MainWindow::rec() { if (controller->isRunning()) return; - auto f - = static_cast(settings::settings().value("recording/format", (int)formats::Recording::None).toInt()); + auto f = static_cast( + settings::settings().value("recording/format", static_cast(formats::Recording::None)).toInt()); if (f >= formats::Recording::None) { - qWarning() << "Recording format not set in settings. Aborting."; + qWarning() << tr("Recording format not set in settings. Aborting."); return; } RecordingContext *ctx = new RecordingContext; @@ -36,6 +36,22 @@ void MainWindow::rec() { controller->start(ctx); } +#define ACTION(english, menu) \ + [&]() -> QAction * { \ + QAction *a = menu->addAction(tr(english)); \ + acts.insert(a, english); \ + return a; \ + }() + +void MainWindow::changeEvent(QEvent *e) { + if (e->type() == QEvent::LocaleChange) { + ui->retranslateUi(this); + for (auto key : acts.keys()) { + key->setText(tr(acts.value(key))); + } + } +} + void addHotkey(QString name, std::function action) { hotkeying::load(name, action); } @@ -48,19 +64,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi tray->setToolTip("KShare"); tray->setVisible(true); QMenu *menu = new QMenu(this); - QAction *quit = new QAction("Quit", this); - QAction *shtoggle = new QAction("Show/Hide", this); - QAction *fullscreen = new QAction("Take fullscreen shot", this); - QAction *area = new QAction("Take area shot", this); + QAction *quit = ACTION("Quit", menu); + QAction *shtoggle = ACTION("Show/Hide", menu); + QAction *fullscreen = ACTION("Take fullscreen shot", menu); + QAction *area = ACTION("Take area shot", menu); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - QAction *active = new QAction("Screenshot active window", this); + QAction *active = ACTION("Screenshot active window", menu); connect(active, &QAction::triggered, this, [] { screenshotter::activeDelayed(); }); #endif - QAction *picker = new QAction("Show color picker", this); - QAction *rec = new QAction("Record screen", this); - QAction *recoff = new QAction("Stop recording", this); - QAction *recabort = new QAction("Abort recording", this); + QAction *picker = ACTION("Show color picker", menu); + QAction *rec = ACTION("Record screen", menu); + QAction *recoff = ACTION("Stop recording", menu); + QAction *recabort = ACTION("Abort recording", menu); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); menu->addActions({ fullscreen, area }); diff --git a/mainwindow.hpp b/mainwindow.hpp index a5a87c4..88a3d36 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -45,10 +45,12 @@ public slots: private: bool val = false; + QMap acts; static MainWindow *instance; protected: - void closeEvent(QCloseEvent *event); + void changeEvent(QEvent *e) override; + void closeEvent(QCloseEvent *event) override; }; #endif // MAINWINDOW_HPP diff --git a/recording/encoders/encodersettingsdialog.cpp b/recording/encoders/encodersettingsdialog.cpp index e182f8c..d70ba73 100644 --- a/recording/encoders/encodersettingsdialog.cpp +++ b/recording/encoders/encodersettingsdialog.cpp @@ -8,7 +8,7 @@ EncoderSettingsDialog::EncoderSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::EncoderSettingsDialog) { ui->setupUi(this); - setWindowTitle("KShare Encoder Settings"); + setWindowTitle(tr("KShare Encoder Settings")); connect(ui->buttonBox, &QDialogButtonBox::accepted, [&] { EncoderSettings::inst().setbitrate(ui->bitrate->value()); EncoderSettings::inst().seth264Crf(ui->crf->value()); diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index a16abfb..b6840f7 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -19,7 +19,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { if (!tmpDir.isValid()) { validator = [](QSize) { return false; }; - qCritical().noquote() << "Could not create temporary directory. Error: " + tmpDir.errorString(); + qCritical().noquote() << tr("Could not create temporary directory. Error: ") + tmpDir.errorString(); return; } iFormat = QImage::Format_RGB888; @@ -39,7 +39,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { return false; } } catch (std::runtime_error &e) { - qCritical() << "Encoder error: " << e.what(); + qCritical() << tr("Encoder error: ") << e.what(); interrupt = true; delete enc; return false; @@ -52,7 +52,7 @@ RecordingFormats::RecordingFormats(formats::Recording f) { frameAdded = true; enc->addFrame(img); } catch (std::runtime_error &e) { - qCritical() << "Encoder error: " << e.what(); + qCritical() << tr("Encoder error: ") << e.what(); interrupt = true; } }; diff --git a/recording/recordingformats.hpp b/recording/recordingformats.hpp index 09fb505..1a75438 100644 --- a/recording/recordingformats.hpp +++ b/recording/recordingformats.hpp @@ -1,6 +1,7 @@ #ifndef RECORDINGFORMATS_HPP #define RECORDINGFORMATS_HPP +#include #include #include #include @@ -12,6 +13,7 @@ #include class RecordingFormats { + Q_DECLARE_TR_FUNCTIONS(RecordingFormats) public: RecordingFormats(formats::Recording f); std::function getConsumer(); diff --git a/recording/recordingpreview.cpp b/recording/recordingpreview.cpp index cab4563..1b079e6 100644 --- a/recording/recordingpreview.cpp +++ b/recording/recordingpreview.cpp @@ -7,7 +7,7 @@ #include #include -QSize max(300, 300); +static QSize max(300, 300); inline bool sizeGreater(QSize one, QSize two) { return one.height() > two.height() || one.width() > two.width(); @@ -44,7 +44,7 @@ RecordingPreview::RecordingPreview(QRect area, QWidget *parent) : QWidget(parent label->setPixmap(empty); layout()->addWidget(hintLabel); layout()->addWidget(label); - hintLabel->setText(QString("Time: 00:00\nFrame: 0\nStop key: ") + hotkeying::sequence("recordingstop")); + hintLabel->setText(QString(tr("Time: 00:00\nFrame: 0\nStop key: ")) + hotkeying::sequence("recordingstop")); } RecordingPreview::~RecordingPreview() { @@ -58,6 +58,6 @@ void RecordingPreview::setPixmap(QPixmap map) { } void RecordingPreview::setTime(QString time, int frame) { if (isVisible()) - hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame) - + "\nStop key: " + hotkeying::sequence("recordingstop")); + hintLabel->setText( + tr("Time: %1\nFrame: %2\nStop key: %3").arg(time).arg(frame).arg(hotkeying::sequence("recordingstop"))); } diff --git a/screenareaselector/screenareaselector.cpp b/screenareaselector/screenareaselector.cpp index e5f35b6..e04aa02 100644 --- a/screenareaselector/screenareaselector.cpp +++ b/screenareaselector/screenareaselector.cpp @@ -6,14 +6,14 @@ #include #include -static QString hintPattern("Set the recording region by resizing this.\n%1x%2"); +static QString hintPattern(ScreenAreaSelector::tr("Set the recording region by resizing this.\n%1x%2")); ScreenAreaSelector::ScreenAreaSelector() { setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); setStyleSheet("background-color: rgba(0, 0, 0, 0.5);"); - setWindowTitle("KShare: Select Area (By resizing this window)"); + setWindowTitle(tr("KShare: Select Area (By resizing this window)")); setAutoFillBackground(true); QTimer::singleShot(0, [&] { QVariant val = settings::settings().value("screenareaselector/rect"); diff --git a/settings.cpp b/settings.cpp index f76c081..bb5ac9e 100644 --- a/settings.cpp +++ b/settings.cpp @@ -13,7 +13,7 @@ QDir settings::dir() { if (configDir.dirName() != "KShare") { if (!configDir.cd("KShare")) { if (!configDir.mkdir("KShare")) { - qFatal("Could not make config directory"); + qFatal("%s", QObject::tr("Could not make config directory").toLocal8Bit().constData()); } else { configDir.cd("KShare"); } diff --git a/settingsdialog.cpp b/settingsdialog.cpp index 3a39548..18949ed 100644 --- a/settingsdialog.cpp +++ b/settingsdialog.cpp @@ -20,7 +20,7 @@ #include #include -QMap> fncs; +static QMap> fncs; void addHotkeyItem(QListWidget *hotkeys, QString text, QString name, std::function func, QString def = QString()) { QListWidgetItem *item = new QListWidgetItem(text, hotkeys); @@ -52,14 +52,14 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se ui->hotkeys->setSelectionMode(QListWidget::SingleSelection); - addHotkeyItem(ui->hotkeys, "Fullscreen image", "fullscreen", [] { screenshotter::fullscreen(); }); - addHotkeyItem(ui->hotkeys, "Area image", "area", [] { screenshotter::area(); }); + addHotkeyItem(ui->hotkeys, tr("Fullscreen image"), "fullscreen", [] { screenshotter::fullscreen(); }); + addHotkeyItem(ui->hotkeys, tr("Area image"), "area", [] { screenshotter::area(); }); #ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW - addHotkeyItem(ui->hotkeys, "Active window", "active", [&] { screenshotter::active(); }); + addHotkeyItem(ui->hotkeys, tr("Active window"), "active", [&] { screenshotter::active(); }); #endif - addHotkeyItem(ui->hotkeys, "Color picker", "picker", [] { ColorPickerScene::showPicker(); }); - addHotkeyItem(ui->hotkeys, "Stop Recording", "recordingstop", [&] { MainWindow::inst()->controller->end(); }); - addHotkeyItem(ui->hotkeys, "Start Recording", "recordingstart", [&] { MainWindow::inst()->rec(); }); + addHotkeyItem(ui->hotkeys, tr("Color picker"), "picker", [] { ColorPickerScene::showPicker(); }); + addHotkeyItem(ui->hotkeys, tr("Stop Recording"), "recordingstop", [&] { MainWindow::inst()->controller->end(); }); + addHotkeyItem(ui->hotkeys, tr("Start Recording"), "recordingstart", [&] { MainWindow::inst()->rec(); }); ui->quickMode->setChecked(settings::settings().value("quickMode", false).toBool()); ui->hideToTray->setChecked(settings::settings().value("hideOnClose", true).toBool()); @@ -81,7 +81,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se ui->nameScheme->setValidator(new FilenameValidator(ui->nameScheme)); #ifndef PLATFORM_CAPABILITY_CURSOR ui->captureCursor->setEnabled(false); - ui->captureCursor->setText("Capture cursor (disabled: implementation missing)"); + ui->captureCursor->setText(tr("Capture cursor (disabled: implementation missing)")); #endif } diff --git a/uploaders/customuploader.cpp b/uploaders/customuploader.cpp index bf8ff6c..93020d1 100644 --- a/uploaders/customuploader.cpp +++ b/uploaders/customuploader.cpp @@ -18,8 +18,8 @@ using formats::recordingFormatFromName; using formats::recordingFormatMIME; using std::runtime_error; -void error(QString absFilePath, QString err) { - throw runtime_error((QString("Invalid file: ").append(absFilePath) + ": " + err).toStdString()); +[[noreturn]] void error(QString absFilePath, QString err) { + throw runtime_error((QObject::tr("Invalid file: ").append(absFilePath) + ": " + err).toStdString()); } CustomUploader::CustomUploader(QString absFilePath) { @@ -28,16 +28,16 @@ CustomUploader::CustomUploader(QString absFilePath) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString()); QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if (!doc.isObject()) { - error(absFilePath, "Root not an object"); + error(absFilePath, tr("Root not an object")); } QJsonObject obj = doc.object(); if (!obj["name"].isString()) - error(absFilePath, "name is not a string"); + error(absFilePath, tr("name is not a string")); else uName = obj["name"].toString(); if (obj.contains("desc")) { if (!obj["desc"].isString()) - /*t*/ error(absFilePath, "desc not a string"); + /*t*/ error(absFilePath, tr("desc not a string")); else desc = obj["desc"].toString(); @@ -45,19 +45,19 @@ CustomUploader::CustomUploader(QString absFilePath) { desc = absFilePath; QJsonValue m = obj["method"]; if (!m.isUndefined() && !m.isNull()) { - if (!m.isString()) error(absFilePath, "method not a string"); + if (!m.isString()) error(absFilePath, tr("method not a string")); QString toCheck = m.toString().toLower(); if (toCheck == "post") method = HttpMethod::POST; else - error(absFilePath, "method invalid"); + error(absFilePath, tr("method invalid")); } QJsonValue url = obj["target"]; if (!url.isString()) { - error(absFilePath, "target missing"); + error(absFilePath, tr("target missing")); } QUrl target(url.toString()); - if (!target.isValid()) error(absFilePath, "target not URL"); + if (!target.isValid()) error(absFilePath, tr("target not URL")); this->target = target; QJsonValue formatValue = obj["format"]; if (!formatValue.isUndefined() && !formatValue.isNull()) { @@ -72,45 +72,47 @@ CustomUploader::CustomUploader(QString absFilePath) { else if (formatString == "multipart-form-data") rFormat = RequestFormat::MULTIPART_FORM_DATA; else - error(absFilePath, "format invalid"); + error(absFilePath, tr("format invalid")); } } else - error(absFilePath, "format provided but not string"); + error(absFilePath, tr("format provided but not string")); QJsonValue bodyValue = obj["body"]; if (rFormat != RequestFormat::PLAIN) { - if (bodyValue.isUndefined()) error(absFilePath, "body not set"); + if (bodyValue.isUndefined()) error(absFilePath, tr("body not set")); if (rFormat == RequestFormat::MULTIPART_FORM_DATA) { if (bodyValue.isArray()) { for (QJsonValue val : bodyValue.toArray()) { - if (!val.isObject()) error(absFilePath, "all elements of body must be objects"); + if (!val.isObject()) error(absFilePath, tr("all elements of body must be objects")); if (!val.toObject()["body"].isObject() && !val.toObject().value("body").isString()) - error(absFilePath, "all parts must have a body which is object or string!"); + error(absFilePath, tr("all parts must have a body which is object or string!")); QJsonObject vo = val.toObject(); for (auto v : vo["body"].toObject()) if (!v.isObject() && !v.isString()) - error(absFilePath, "all parts of body must be string or object"); + error(absFilePath, tr("all parts of body must be string or object")); for (auto v : vo.keys()) if (v.startsWith("__") && !vo[v].isString()) - error(absFilePath, "all __headers must be strings"); + //: __ + error(absFilePath, tr("all __headers must be strings")); } body = bodyValue; } else - error(absFilePath, "body not array (needed for multipart)"); + error(absFilePath, tr("body not array (needed for multipart)")); } else { if (bodyValue.isObject()) body = bodyValue; else - error(absFilePath, "body not object"); + error(absFilePath, tr("body not object")); } } else { if (bodyValue.isString()) { body = bodyValue; } else - error(absFilePath, "body not string (reason: format: PLAIN)"); + //: `format: PLAIN` should stay the same + error(absFilePath, tr("body not string (reason: format: PLAIN)")); } QJsonValue headerVal = obj["headers"]; if (!(headerVal.isUndefined() || headerVal.isNull())) { - if (!headerVal.isObject()) error(absFilePath, "headers must be object"); + if (!headerVal.isObject()) error(absFilePath, tr("headers must be object")); headers = headerVal.toObject(); } else headers = QJsonObject(); @@ -118,17 +120,18 @@ CustomUploader::CustomUploader(QString absFilePath) { if (returnPsVal.isString()) { returnPathspec = returnPsVal.toString(); } else - error(absFilePath, "return invalid"); + error(absFilePath, tr("return invalid")); QJsonValue fileLimit = obj["fileLimit"]; if (!fileLimit.isNull() && !fileLimit.isUndefined()) { - if (!fileLimit.isDouble()) error(absFilePath, "fileLimit not double"); + //: fileLimit stays English + if (!fileLimit.isDouble()) error(absFilePath, tr("fileLimit not decimal")); limit = fileLimit.toDouble(); } QJsonValue bool64 = obj["base64"]; if (!bool64.isNull() && !bool64.isUndefined()) { - if (!bool64.isBool()) error(absFilePath, "base64 must be boolean"); + if (!bool64.isBool()) error(absFilePath, tr("base64 must be boolean")); base64 = bool64.toBool(); - if (rFormat == RequestFormat::JSON && !base64) error(absFilePath, "base64 required with json"); + if (rFormat == RequestFormat::JSON && !base64) error(absFilePath, tr("base64 required with json")); } urlPrepend = obj["return_prepend"].toString(); urlAppend = obj["return_append"].toString(); @@ -204,19 +207,19 @@ QString parsePathspec(QJsonDocument &response, QString &pathspec) { return ""; } -void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name, QString urlPrepend, QString urlAppend) { +void CustomUploader::parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name) { if (result.isObject()) { QString url = urlPrepend + parsePathspec(result, returnPathspec) + urlAppend; if (!url.isEmpty()) { QApplication::clipboard()->setText(url); - notifications::notify("KShare Custom Uploader " + name, "Copied upload link to clipboard!"); + notifications::notify(tr("KShare Custom Uploader ") + name, tr("Copied upload link to clipboard!")); } else { - notifications::notify("KShare Custom Uploader " + name, "Upload done, but result empty!"); + notifications::notify(tr("KShare Custom Uploader ") + name, tr("Upload done, but result empty!")); QApplication::clipboard()->setText(data); } } else { - notifications::notify("KShare Custom Uploader " + name, - "Upload done, but result is not JSON Object! Result in clipboard."); + notifications::notify(tr("KShare Custom Uploader ") + name, + tr("Upload done, but result is not JSON Object! Result in clipboard.")); QApplication::clipboard()->setText(data); } } @@ -328,18 +331,20 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { switch (method) { case HttpMethod::POST: if (returnPathspec == "|") { - ioutils::postMultipartData(target, h, multipart, [&, buffersToDelete, arraysToDelete](QByteArray result, QNetworkReply *) { - QApplication::clipboard()->setText(QString::fromUtf8(result)); - for (auto buffer : buffersToDelete) buffer->deleteLater(); - for (auto arr : arraysToDelete) delete arr; - notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!"); - }); + ioutils::postMultipartData(target, h, multipart, + [&, buffersToDelete, arraysToDelete](QByteArray result, QNetworkReply *) { + QApplication::clipboard()->setText(QString::fromUtf8(result)); + for (auto buffer : buffersToDelete) buffer->deleteLater(); + for (auto arr : arraysToDelete) delete arr; + notifications::notify(tr("KShare Custom Uploader ") + name(), + tr("Copied upload result to clipboard!")); + }); } else { ioutils::postMultipart(target, h, multipart, [&, buffersToDelete, arraysToDelete](QJsonDocument result, QByteArray data, QNetworkReply *) { for (auto buffer : buffersToDelete) buffer->deleteLater(); for (auto arr : arraysToDelete) delete arr; - parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); + parseResult(result, data, returnPathspec, name()); }); } break; @@ -348,7 +353,7 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { } } if (limit > 0 && data.size() > limit) { - notifications::notify("KShare Custom Uploader " + name(), "File limit exceeded!"); + notifications::notify(tr("KShare Custom Uploader ") + name(), tr("File limit exceeded!")); return; } switch (method) { @@ -356,11 +361,11 @@ void CustomUploader::doUpload(QByteArray imgData, QString format) { if (returnPathspec == "|") { ioutils::postData(target, h, data, [&](QByteArray result, QNetworkReply *) { QApplication::clipboard()->setText(QString::fromUtf8(result)); - notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!"); + notifications::notify(tr("KShare Custom Uploader ") + name(), tr("Copied upload result to clipboard!")); }); } else { ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray data, QNetworkReply *) { - parseResult(result, data, returnPathspec, name(), urlPrepend, urlAppend); + parseResult(result, data, returnPathspec, name()); }); } break; diff --git a/uploaders/customuploader.hpp b/uploaders/customuploader.hpp index 22deaef..35b54bf 100644 --- a/uploaders/customuploader.hpp +++ b/uploaders/customuploader.hpp @@ -2,6 +2,7 @@ #define CUSTOMUPLOADER_HPP #include "uploader.hpp" +#include #include #include #include @@ -11,6 +12,8 @@ enum class HttpMethod { POST }; enum class RequestFormat { X_WWW_FORM_URLENCODED, JSON, MULTIPART_FORM_DATA, PLAIN }; class CustomUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(CustomUploader) + public: CustomUploader(QString absFilePath); QString name(); @@ -29,6 +32,7 @@ private: bool base64 = false; QString returnPathspec; QString urlPrepend, urlAppend; + void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name); }; #endif // CUSTOMUPLOADER_HPP diff --git a/uploaders/default/clipboarduploader.cpp b/uploaders/default/clipboarduploader.cpp index 57aa7a2..5955d29 100644 --- a/uploaders/default/clipboarduploader.cpp +++ b/uploaders/default/clipboarduploader.cpp @@ -14,5 +14,5 @@ void ClipboardUploader::doUpload(QByteArray imgData, QString format) { QApplication::clipboard()->setMimeData(data); } else QApplication::clipboard()->setImage(QImage::fromData(imgData, format.toLocal8Bit().constData())); - notifications::notify("KShare", "Copied to clipboard!"); + notifications::notify(tr("KShare"), tr("Copied to clipboard!")); } diff --git a/uploaders/default/clipboarduploader.hpp b/uploaders/default/clipboarduploader.hpp index 5794386..07e78f0 100644 --- a/uploaders/default/clipboarduploader.hpp +++ b/uploaders/default/clipboarduploader.hpp @@ -1,10 +1,12 @@ #ifndef CLIPBOARDUPLOADER_HPP #define CLIPBOARDUPLOADER_HPP +#include #include #include class ClipboardUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ClipboardUploader) public: QString name() { return "clipboard"; diff --git a/uploaders/default/imgplusuploader.cpp b/uploaders/default/imgplusuploader.cpp index dcb1ce0..5cbdb6a 100644 --- a/uploaders/default/imgplusuploader.cpp +++ b/uploaders/default/imgplusuploader.cpp @@ -36,14 +36,15 @@ void ImgplusUploader::doUpload(QByteArray byteArray, QString format) { [](QByteArray link, QNetworkReply *) { QApplication::clipboard()->setText(QString::fromUtf8(link)); if (!link.startsWith("http")) - qCritical() << "Failed to upload! Copied the response to clipboard"; + qCritical() << QObject::tr("Failed to upload! Copied the response to clipboard"); else - notifications::notify("KShare imgur Uploader ", "Uploaded to ImagePlus!"); + notifications::notify(QObject::tr("KShare imgplus Uploader"), + QObject::tr("Uploaded to ImagePlus!")); }); } void ImgplusUploader::showSettings() { - QString text = QInputDialog::getText(0, "imgplus API key", "Enter the imgpl.us API key (Found in Settings)", + QString text = QInputDialog::getText(0, tr("imgplus API key"), tr("Enter the imgpl.us API key (Found in Settings)"), QLineEdit::Normal, settings::settings().value("imgplus/apikey").toString()); if (!text.isNull()) settings::settings().setValue("imgplus/apikey", text); } diff --git a/uploaders/default/imgplusuploader.hpp b/uploaders/default/imgplusuploader.hpp index a7050c6..7ef3836 100644 --- a/uploaders/default/imgplusuploader.hpp +++ b/uploaders/default/imgplusuploader.hpp @@ -1,9 +1,11 @@ #ifndef IMGPLUSUPLOADER_HPP #define IMGPLUSUPLOADER_HPP +#include #include class ImgplusUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ImgplusUploader) public: QString name() override { return "ImagePlus"; diff --git a/uploaders/default/imgursettingsdialog.cpp b/uploaders/default/imgursettingsdialog.cpp index f69aba6..fbaa65e 100644 --- a/uploaders/default/imgursettingsdialog.cpp +++ b/uploaders/default/imgursettingsdialog.cpp @@ -60,7 +60,7 @@ void ImgurSettingsDialog::on_authorize_clicked() { QDateTime::currentDateTimeUtc().addSecs(res["expires_in"].toInt())); settings::settings().setValue("imgur/refresh", res["refresh_token"].toString()); settings::settings().setValue("imgur/access", res["refresh_token"].toString()); - ui->status->setText("It works!"); + ui->status->setText(tr("It works!")); ui->status->setStyleSheet("* { color: green; }"); ui->authorize->setEnabled(false); diff --git a/uploaders/default/imguruploader.cpp b/uploaders/default/imguruploader.cpp index ec051a9..fa6457b 100644 --- a/uploaders/default/imguruploader.cpp +++ b/uploaders/default/imguruploader.cpp @@ -53,7 +53,7 @@ private: void ImgurUploader::doUpload(QByteArray byteArray, QString format) { if (byteArray.size() > 1e+7) { - notifications::notify("KShare imgur Uploader ", "Failed upload! Image too big"); + notifications::notify(tr("KShare imgur Uploader"), tr("Failed upload! Image too big")); return; } QString mime; @@ -89,10 +89,10 @@ void ImgurUploader::handleSend(QString auth, QString mime, QByteArray byteArray) } if (!result.isEmpty()) { screenshotutil::toClipboard(result); - notifications::notify("KShare imgur Uploader ", "Uploaded to imgur!"); + notifications::notify(tr("KShare imgur Uploader"), tr("Uploaded to imgur!")); } else { - notifications::notify("KShare imgur Uploader ", - QString("Failed upload! imgur said: HTTP %1: %2") + notifications::notify(tr("KShare imgur Uploader "), + QString(tr("Failed upload! imgur said: HTTP %1: %2")) .arg(r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()) .arg(r->errorString())); } diff --git a/uploaders/default/imguruploader.hpp b/uploaders/default/imguruploader.hpp index 5419f31..78c38af 100644 --- a/uploaders/default/imguruploader.hpp +++ b/uploaders/default/imguruploader.hpp @@ -2,8 +2,10 @@ #define IMGURUPLOADER_HPP #include "../uploader.hpp" +#include class ImgurUploader : public Uploader { + Q_DECLARE_TR_FUNCTIONS(ImgurUploader) friend struct SegfaultWorkaround; public: diff --git a/uploaders/uploadersingleton.cpp b/uploaders/uploadersingleton.cpp index 3f21481..4bac1fa 100644 --- a/uploaders/uploadersingleton.cpp +++ b/uploaders/uploadersingleton.cpp @@ -18,18 +18,17 @@ UploaderSingleton::UploaderSingleton() : QObject() { case 0: saveDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if (QStandardPaths::writableLocation(QStandardPaths::PicturesLocation).isEmpty()) { - qFatal("Cannot determine location for pictures"); + qFatal("%s", tr("Cannot determine location for pictures").toLocal8Bit().constData()); } break; case 1: if (QStandardPaths::writableLocation(QStandardPaths::HomeLocation).isEmpty()) { - qFatal("Cannot determine location of your home directory"); + qFatal("%s", tr("Cannot determine location of your home directory").toLocal8Bit().constData()); } saveDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/Screenshots"; break; default: - qFatal("Invalid config [saveLocation not int or is not in range]"); - break; + qFatal("%s", tr("Invalid config [saveLocation not int or is not in range]").toLocal8Bit().constData()); } if (!saveDir.exists()) { @@ -68,7 +67,7 @@ UploaderSingleton::UploaderSingleton() : QObject() { void UploaderSingleton::registerUploader(Uploader *uploader) { if (uploaders.contains(uploader->name())) - throw std::runtime_error(("Ambigious uploader " + uploader->name()).toStdString()); + throw std::runtime_error((tr("Ambigious uploader ") + uploader->name()).toStdString()); uploaders.insert(uploader->name(), uploader); emit newUploader(uploader); } @@ -78,7 +77,7 @@ void UploaderSingleton::upload(QPixmap pixmap) { if (!u->validate()) { u = uploaders.value("imgur"); set("imgur"); - qWarning() << "Currently selected uploader is not set up properly! Falling back to imgur"; + qWarning() << tr("Currently selected uploader is not set up properly! Falling back to imgur"); } QString format = settings::settings().value("captureformat", "PNG").toString(); QFile file(saveDir.absoluteFilePath( @@ -90,7 +89,7 @@ void UploaderSingleton::upload(QPixmap pixmap) { file.seek(0); u->doUpload(file.readAll(), format); } else - notifications::notify("KShare - Failed to save picture", file.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), file.errorString(), QSystemTrayIcon::Warning); } void UploaderSingleton::upload(QByteArray img, QString format) { @@ -113,9 +112,9 @@ void UploaderSingleton::upload(QFile &img, QString format) { if (img.open(QFile::ReadWrite)) uploaders.value(uploader)->doUpload(img.readAll(), format); else - notifications::notify("KShare - Failed to save picture", img.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), img.errorString(), QSystemTrayIcon::Warning); } else - notifications::notify("KShare - Failed to save picture", img.errorString(), QSystemTrayIcon::Warning); + notifications::notify(tr("KShare - Failed to save picture"), img.errorString(), QSystemTrayIcon::Warning); } void UploaderSingleton::showSettings() { diff --git a/uploaders/uploadersingleton.hpp b/uploaders/uploadersingleton.hpp index fc1fb2a..50f5f99 100644 --- a/uploaders/uploadersingleton.hpp +++ b/uploaders/uploadersingleton.hpp @@ -30,10 +30,10 @@ signals: private: QDir saveDir; - UploaderSingleton(); QMap uploaders; QString uploader = "imgur"; QList errs; + UploaderSingleton(); }; #endif // UPLOADERSINGLETON_HPP