diff --git a/src/dbg/debugger_commands.cpp b/src/dbg/debugger_commands.cpp index 18bc80b1..6a225671 100644 --- a/src/dbg/debugger_commands.cpp +++ b/src/dbg/debugger_commands.cpp @@ -1278,7 +1278,7 @@ CMDRESULT cbDebugStepOver(int argc, char* argv[]) { StepOver((void*)cbStep); // History - HistoryAdd(); + HistoryClear(); dbgsetstepping(true); return cbDebugRun(argc, argv); } diff --git a/src/gui/Src/Gui/MainWindow.cpp b/src/gui/Src/Gui/MainWindow.cpp index b9b2aaa2..0d5dd28c 100644 --- a/src/gui/Src/Gui/MainWindow.cpp +++ b/src/gui/Src/Gui/MainWindow.cpp @@ -15,6 +15,7 @@ #include "StringUtil.h" #include "MiscUtil.h" #include "FavouriteTools.h" +#include "main.h" QString MainWindow::windowTitle = ""; @@ -307,6 +308,9 @@ MainWindow::MainWindow(QWidget* parent) // Setup favourite tools menu updateFavouriteTools(); + // Setup language menu + setupLanguagesMenu(); + // Set default setttings (when not set) SettingsDialog defaultSettings; lastException = 0; @@ -355,6 +359,53 @@ void MainWindow::setupStatusBar() mTimeWastedCounter = new TimeWastedCounter(this, timeWastedLabel); } +void MainWindow::setupLanguagesMenu() +{ + QDir translationsDir(QString("%1/../translations/").arg(QCoreApplication::applicationDirPath())); + QMenu* languageMenu; + if(tr("Languages") == QString("Languages")) + languageMenu = new QMenu(QString("Languages")); + else + languageMenu = new QMenu(tr("Languages") + QString(" Languages"), this); + QLocale enUS(QLocale::English, QLocale::UnitedStates); + QString wCurrentLocale(currentLocale); + QAction* action_enUS = new QAction(QString("[%1]%2 - %3").arg(enUS.name()).arg(enUS.nativeLanguageName()).arg(enUS.nativeCountryName()), languageMenu); + connect(action_enUS, SIGNAL(triggered()), this, SLOT(chooseLanguage())); + action_enUS->setCheckable(true); + action_enUS->setChecked(false); + languageMenu->addAction(action_enUS); + if(!translationsDir.exists()) + { + // translations dir do not exist + action_enUS->setChecked(true); + ui->menuOptions->addMenu(languageMenu); + return; + } + if(wCurrentLocale == QString("en_US")) + action_enUS->setChecked(true); + QStringList filter; + filter << "x64dbg_*.qm"; + QFileInfoList fileList = translationsDir.entryInfoList(filter, QDir::Readable | QDir::Files, QDir::Size); + auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry); + for(auto i : fileList) + { + QString localeName = i.baseName().mid(7); + for(auto j : allLocales) + { + if(j.name().startsWith(localeName)) + { + QAction* actionLanguage = new QAction(QString("[%1]%2 - %3").arg(localeName).arg(j.nativeLanguageName()).arg(j.nativeCountryName()), languageMenu); + connect(actionLanguage, SIGNAL(triggered()), this, SLOT(chooseLanguage())); + actionLanguage->setCheckable(true); + actionLanguage->setChecked(localeName == wCurrentLocale); + languageMenu->addAction(actionLanguage); + break; + } + } + } + ui->menuOptions->addMenu(languageMenu); +} + void MainWindow::closeEvent(QCloseEvent* event) { mCloseDialog->show(); @@ -1565,6 +1616,52 @@ void MainWindow::clickFavouriteTool() } } +void MainWindow::chooseLanguage() +{ + QAction* action = qobject_cast(sender()); + QString localeName = action->text(); + localeName = localeName.mid(1, localeName.indexOf(QChar(']')) - 1); + action->setChecked(localeName == QString(currentLocale)); + if(localeName != "en_US") + { + QDir translationsDir(QString("%1/../translations/").arg(QCoreApplication::applicationDirPath())); + QFile file(translationsDir.absoluteFilePath(QString("x64dbg_%1.qm").arg(localeName))); + if(file.size() < 512) + { + QMessageBox msg(this); + msg.setIcon(QMessageBox::Information); + if(tr("Languages") == QString("Languages")) + { + msg.setWindowTitle(QString("Languages")); + msg.setText(QString("The translation is nearly empty. Do you still want to use this language?")); + } + else + { + msg.setWindowTitle(tr("Languages") + QString(" Languages")); + msg.setText(tr("The translation is nearly empty. Do you still want to use this language?") + QString("\r\nThe translation is nearly empty. Do you still want to use this language?")); + } + msg.addButton(QMessageBox::Yes); + msg.addButton(QMessageBox::No); + if(msg.exec() == QMessageBox::No) + return; + } + } + BridgeSettingSet("Engine", "Language", localeName.toUtf8().constData()); + QMessageBox msg(this); + msg.setIcon(QMessageBox::Information); + if(tr("Languages") == QString("Languages")) + { + msg.setWindowTitle(QString("Languages")); + msg.setText(QString("New language setting will take effect upon restart.")); + } + else + { + msg.setWindowTitle(tr("Languages") + QString(" Languages")); + msg.setText(tr("New language setting will take effect upon restart.") + QString("\r\nNew language setting will take effect upon restart.")); + } + msg.exec(); +} + void MainWindow::on_actionStepIntoSource_triggered() { DbgCmdExec("TraceIntoConditional src.line(cip) && !src.disp(cip)"); diff --git a/src/gui/Src/Gui/MainWindow.h b/src/gui/Src/Gui/MainWindow.h index 2ff60b17..cf73bc15 100644 --- a/src/gui/Src/Gui/MainWindow.h +++ b/src/gui/Src/Gui/MainWindow.h @@ -147,6 +147,7 @@ public slots: void manageFavourites(); void updateFavouriteTools(); void clickFavouriteTool(); + void chooseLanguage(); private: Ui::MainWindow* ui; @@ -191,6 +192,7 @@ private: void removeMRUEntry(QString entry); void updateMRUMenu(); QString getMRUEntry(int index); + void setupLanguagesMenu(); //menu api struct MenuEntryInfo diff --git a/src/gui/Src/main.cpp b/src/gui/Src/main.cpp index 72203e6e..51df5ec4 100644 --- a/src/gui/Src/main.cpp +++ b/src/gui/Src/main.cpp @@ -45,6 +45,7 @@ bool MyApplication::notify(QObject* receiver, QEvent* event) } static Configuration* mConfiguration; +char currentLocale[MAX_SETTING_SIZE] = ""; static bool isValidLocale(const QString & locale) { @@ -75,24 +76,23 @@ int main(int argc, char* argv[]) #endif // Get the hidden language setting (for testers) - char locale[MAX_SETTING_SIZE] = ""; - if(!BridgeSettingGet("Engine", "Language", locale) || !isValidLocale(locale)) + if(!BridgeSettingGet("Engine", "Language", currentLocale) || !isValidLocale(currentLocale)) { QStringList uiLanguages = QLocale::system().uiLanguages(); QString sysLocale = uiLanguages.size() ? QLocale(uiLanguages[0]).name() : QLocale::system().name(); - strcpy_s(locale, sysLocale.toUtf8().constData()); - BridgeSettingSet("Engine", "Language", locale); + strcpy_s(currentLocale, sysLocale.toUtf8().constData()); + BridgeSettingSet("Engine", "Language", currentLocale); } // Load translations for Qt QTranslator qtTranslator; - if(qtTranslator.load(QString("qt_%1").arg(locale), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + if(qtTranslator.load(QString("qt_%1").arg(currentLocale), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) application.installTranslator(&qtTranslator); //x64dbg and x32dbg can share the same translation QTranslator x64dbgTranslator; auto path = QString("%1/../translations").arg(QCoreApplication::applicationDirPath()); - if(x64dbgTranslator.load(QString("x64dbg_%1").arg(locale), path)) + if(x64dbgTranslator.load(QString("x64dbg_%1").arg(currentLocale), path)) application.installTranslator(&x64dbgTranslator); // initialize capstone diff --git a/src/gui/Src/main.h b/src/gui/Src/main.h index a40393be..69182d5b 100644 --- a/src/gui/Src/main.h +++ b/src/gui/Src/main.h @@ -23,6 +23,7 @@ public: }; int main(int argc, char* argv[]); +extern char currentLocale[MAX_SETTING_SIZE]; #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) class x64GlobalFilter : public QAbstractNativeEventFilter