Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/core/config/LocalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ bool LocalSettings::Load()

if (j.contains("AddExtraHeaders"))
m_bAddExtraHeaders = j["AddExtraHeaders"];

if (j.contains("Language"))
m_language = j["Language"];
return true;
}

Expand Down Expand Up @@ -203,6 +206,7 @@ bool LocalSettings::Save()
j["Use12HourTime"] = m_bUse12HourTime;
j["ShowBlockedMessages"] = m_bShowBlockedMessages;
j["UseDoubleBuffering"] = m_bUseDoubleBuffering;
j["Language"] = m_language;

if (m_bSaveWindowSize) {
j["WindowWidth"] = m_width;
Expand Down
3 changes: 3 additions & 0 deletions src/core/config/LocalSettings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ class LocalSettings
void SetUseDoubleBuffering(bool b) {
m_bUseDoubleBuffering = b;
}
int GetLanguage() const { return m_language; }
void SetLanguage(int lang) { m_language = lang; }

private:
std::string m_token;
Expand Down Expand Up @@ -262,6 +264,7 @@ class LocalSettings
int m_width = 1000;
int m_height = 700;
int m_userScale = 1000;
int m_language = 0;
};

LocalSettings* GetLocalSettings();
12 changes: 12 additions & 0 deletions src/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
#define IDD_DIALOG_UPLOADING_ND 426
#define IDD_DIALOG_GUILD_CHOOSER_ND 427
#define IDD_DIALOG_PREFERENCES_ND 428
#define IDD_DIALOG_LANGUAGE_ND 429
#define IDR_MAINMENU 501
#define IDR_MESSAGE_CONTEXT 502
#define IDR_GUILD_CONTEXT 503
Expand Down Expand Up @@ -337,6 +338,11 @@
#define IDS_CANT_LAUNCH_URL_UNS 775
#define IDS_CONFIRM_UNPIN 776
#define IDS_CONFIRM_UNPIN_TITLE 777
#define IDS_LANGUAGE 778
#define IDS_APPLY_LANG 779
#define IDS_RESTART_REQUIRED 780
#define IDS_LANG_DEFAULTS 781
#define IDS_SYSTEM_LANGUAGE 782
#define IDC_OPTIONS_TABS 801
#define IDC_MY_ACCOUNT_BOX 802
#define IDC_MY_ACCOUNT_NAME 803
Expand Down Expand Up @@ -443,6 +449,12 @@
#define IDC_MINIMIZE_TO_NOTIF 904
#define IDC_HOW_GET_TOKEN 905
#define IDC_DOUBLE_BUFFERING 917
#define IDC_LANGUAGE_LIST 918
#define IDC_LANGUAGE_SYSTEM 919
#define IDC_LANGUAGE_APPLY 920
#define IDC_LANGUAGE_DEFAULTS 921
#define IDC_PENDING_RESTART 922
#define IDC_PENDING_RESTART_TEXT 923
#define ID_FILE_PREFERENCES 1001
#define ID_FILE_STOPALLSPEECH 1002
#define ID_FILE_EXIT 1003
Expand Down
31 changes: 30 additions & 1 deletion src/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ BEGIN
END



/////////////////////////////////////////////////////////////////////////////
//
// Icon
Expand Down Expand Up @@ -913,6 +914,23 @@ BEGIN
END


IDD_DIALOG_LANGUAGE_ND DIALOG 0, 0, 264, 240
STYLE WS_CHILD | DS_CONTROL
FONT 8, "MS Shell Dlg"
BEGIN
GROUPBOX "Language Options", IDC_MDISPLAY_BOX, 6, 7, 248, 132
LTEXT "Choose the language you want Discord Messenger to display", IDC_STATIC, 12, 18, 236, 8
LISTBOX IDC_LANGUAGE_LIST, 12, 30, 236, 60, LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
AUTOCHECKBOX "Detect and use my systems language by default", IDC_LANGUAGE_SYSTEM, 12, 93, 170, 10
LTEXT "System Language: ", IDS_SYSTEM_LANGUAGE, 12, 106, 236, 8
PUSHBUTTON "Apply Language", IDC_LANGUAGE_APPLY, 180, 120, 70, 14
PUSHBUTTON "Revert to Defaults", IDC_LANGUAGE_DEFAULTS, 12, 120, 70, 14

ICON IDI_WARNING_IC,IDC_PENDING_RESTART,12,225,136,20,SS_REALSIZEIMAGE
LTEXT "Pending Restart. Some changes will not take effect until after a restart.", IDC_PENDING_RESTART_TEXT, 28, 226, 236, 8

END

/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
Expand Down Expand Up @@ -1718,11 +1736,19 @@ BEGIN
IDS_CONFIRM_UNPIN_TITLE "Discord Messenger - Unpin Message"
END

STRINGTABLE
BEGIN
IDS_APPLY_LANG "In order to apply the language, you need to restart Discord Messenger.\nDo you wish to restart now?"
IDS_RESTART_REQUIRED "Restart Required - Discord Messenger"
IDS_LANG_DEFAULTS "Default Settings have been loaded. They will take affect after a restart."
IDS_LANGUAGE "Language"
IDS_SYSTEM_LANGUAGE "System Language: %s"
END

#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
Expand All @@ -1733,3 +1759,6 @@ END
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED




1 change: 1 addition & 0 deletions src/windows/InstanceMutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ class InstanceMutex
public:
HRESULT Init();
~InstanceMutex();
void Release() { Close(); }
};
40 changes: 40 additions & 0 deletions src/windows/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ IChannelView* g_pChannelView;
MessageEditor* g_pMessageEditor;
LoadingMessage* g_pLoadingMessage;

pSetThreadUILanguage g_fnSetThreadUILanguage = nullptr;

bool g_bBlockDoubleBufferingForThisInstance = false;

constexpr int MIN_MEMORY_TO_BLOCK_DOUBLE_BUFFERING = 128 * 1024 * 1024;
Expand Down Expand Up @@ -1921,6 +1923,31 @@ static bool ForceSingleInstance(LPCTSTR pClassName)
return false;
}

// Restarts the instance - for languages to apply
void RestartInstance()
{
g_instanceMutex.Release(); // Close();

TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH);

STARTUPINFO si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };

if (!CreateProcess(szPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {

g_instanceMutex.Init();
return;
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

ExitProcess(0);

}

// Blackwingcat's Extended Kernel workaround: Apparently, the custom user32.dll it uses tries
// to write to the class name, which previously was part of .rodata, which is of course read-only.
TCHAR g_className[64];
Expand Down Expand Up @@ -1966,6 +1993,19 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLin
// Load the settings, and fix up some settings that are
// actually bad to leave on on NT 3.x or NT 4
pSettings->Load();

// compatibility checking
HMODULE h = GetModuleHandle(TEXT("kernel32.dll"));
pSetThreadUILanguage fnSetUILanguage = (pSetThreadUILanguage)GetProcAddress(h, "SetThreadUILanguage");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not your fault, but if I merge the PR, I'll move this to MWAS

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i understand that, i looked and saw simillar things like that. No worries


LANGID langid = pSettings->GetLanguage();

if (fnSetUILanguage) {
fnSetUILanguage(langid);
}
else {
SetThreadLocale(MAKELCID(langid, SORT_DEFAULT));
}

if (LOBYTE(version) < 5 && pSettings->GetMessageStyle() == MS_GRADIENT)
{
Expand Down
3 changes: 3 additions & 0 deletions src/windows/Main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ struct SendMessageAuxParams
Snowflake m_snowflake;
};

typedef LANGID(WINAPI* pSetThreadUILanguage)(LANGID);

std::string FormatDiscrim(int discrim);
std::string GetStringFromHResult(HRESULT hr);
std::string GetDiscordToken();
Expand All @@ -155,3 +157,4 @@ void SetHeartbeatInterval(int timeMs);
int GetProfilePictureSize();
HBITMAP GetDefaultBitmap();
bool ShouldBlockDoubleBuffering();
void RestartInstance();
111 changes: 111 additions & 0 deletions src/windows/OptionsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#endif
#include <commdlg.h>

static bool g_bPendingRestart = false;

const eMessageStyle g_indexToMessageStyle[] = {
MS_3DFACE,
MS_GRADIENT,
Expand Down Expand Up @@ -39,6 +41,7 @@ enum ePage
PG_CHAT,
PG_WINDOW,
PG_CONNECTION,
PG_LANGUAGE,
PG_PAGE_COUNT,
PG_FIRST = PG_ACCOUNT_AND_PRIVACY
};
Expand Down Expand Up @@ -288,6 +291,45 @@ void OptionsInitPage(HWND hwndDlg, int pageNum)
free(tstrAPI);
free(tstrCDN);

break;
}
case PG_LANGUAGE:
{
if (g_bPendingRestart) {
ShowWindow(GetDlgItem(hwndDlg, IDC_PENDING_RESTART), SW_SHOW);
ShowWindow(GetDlgItem(hwndDlg, IDC_PENDING_RESTART_TEXT), SW_SHOW);
}
else {
ShowWindow(GetDlgItem(hwndDlg, IDC_PENDING_RESTART), SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_PENDING_RESTART_TEXT), SW_HIDE);
}

// TODO: Make a function that reads off available languages
// off resource file and adds them as listbox options
HWND hList = GetDlgItem(hwndDlg, IDC_LANGUAGE_LIST);

// NOTE: must be in order!!
ListBox_AddString(hList, TEXT("English (US)"));
ListBox_AddString(hList, TEXT("Deutsch"));
ListBox_AddString(hList, TEXT("Espa\xf1ol"));
ListBox_AddString(hList, TEXT("Polski"));

TCHAR szSysLang[128];
TCHAR szResText[256];

// Check if currently loaded language is the name as the system.
LocalSettings* pSettings = GetLocalSettings();

if (GetSystemDefaultLangID() == pSettings->GetLanguage()) {
SendMessage(GetDlgItem(hwndDlg, IDC_LANGUAGE_SYSTEM), BM_SETCHECK, BST_CHECKED, 0);
}

// Get Systems Language and display that
GetLocaleInfo(MAKELCID(GetSystemDefaultLangID(), SORT_DEFAULT), LOCALE_SLANGUAGE, szSysLang, 128);

_stprintf(szResText, (LPCTSTR)TmGetTString(IDS_SYSTEM_LANGUAGE), szSysLang);
SetDlgItemText(hwndDlg, IDS_SYSTEM_LANGUAGE, szResText);

break;
}
}
Expand Down Expand Up @@ -316,6 +358,7 @@ void WINAPI OnChildDialogInit(HWND hwndDlg)

INT_PTR OptionsHandleCommand(HWND hwndParent, HWND hWnd, int pageNum, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

if (LOWORD(wParam) == IDOK)
return EndDialog(hWnd, IDOK);

Expand Down Expand Up @@ -648,6 +691,71 @@ INT_PTR OptionsHandleCommand(HWND hwndParent, HWND hWnd, int pageNum, UINT uMsg,
}
break;
}
case PG_LANGUAGE:
{

switch (LOWORD(wParam)) {

case IDC_LANGUAGE_APPLY:
{
// NOTE: this must be in order as the ListBox
// temporary, once i'll figure out other ways

LANGID langIds[] = {
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
};

int sel = ListBox_GetCurSel(GetDlgItem(hWnd, IDC_LANGUAGE_LIST));

GetLocalSettings()->SetLanguage(langIds[sel]);
GetLocalSettings()->Save();

if (MessageBox(hWnd, TmGetTString(IDS_APPLY_LANG), TmGetTString(IDS_RESTART_REQUIRED), MB_YESNO | MB_ICONEXCLAMATION) == IDYES) {
RestartInstance();
}
else {
g_bPendingRestart = true;

ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART), SW_SHOW);
ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART_TEXT), SW_SHOW);
}
break;
}

case IDC_LANGUAGE_DEFAULTS:
{
MessageBox(hWnd, TmGetTString(IDS_LANG_DEFAULTS), TmGetTString(IDS_RESTART_REQUIRED), MB_OK);
g_bPendingRestart = true;

ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART), SW_SHOW);
ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART_TEXT), SW_SHOW);

// the default langID for English US
GetLocalSettings()->SetLanguage(1033);
GetLocalSettings()->Save();

break;
}

case IDC_LANGUAGE_SYSTEM:
{
GetLocalSettings()->SetLanguage(GetSystemDefaultLangID());
GetLocalSettings()->Save();

if (MessageBox(hWnd, TmGetTString(IDS_APPLY_LANG), TmGetTString(IDS_RESTART_REQUIRED), MB_YESNO | MB_ICONEXCLAMATION) == IDYES) {
RestartInstance();
}
else {
g_bPendingRestart = true;

ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART), SW_SHOW);
ShowWindow(GetDlgItem(hWnd, IDC_PENDING_RESTART_TEXT), SW_SHOW);
}

break;
}
}
}
}

return 0;
Expand Down Expand Up @@ -743,6 +851,7 @@ HRESULT OnPreferenceDialogInit(HWND hWnd)
AddTab(hwndTab, tie, PG_CHAT, (LPTSTR)TmGetTString(IDS_CHAT));
AddTab(hwndTab, tie, PG_WINDOW, (LPTSTR)TmGetTString(IDS_WINDOW));
AddTab(hwndTab, tie, PG_CONNECTION, (LPTSTR)TmGetTString(IDS_CONNECTION));
AddTab(hwndTab, tie, PG_LANGUAGE, (LPTSTR)TmGetTString(IDS_LANGUAGE));

// Lock the resources for the child dialog boxes.
pHeader->apRes[PG_ACCOUNT_AND_PRIVACY] = LockDialogResource(MAKEINTRESOURCE(IDD_DIALOG_MY_ACCOUNT));
Expand All @@ -751,6 +860,8 @@ HRESULT OnPreferenceDialogInit(HWND hWnd)
pHeader->apRes[ PG_CHAT ] = LockDialogResource(MAKEINTRESOURCE(IDD_DIALOG_CHATSETTINGS));
pHeader->apRes[ PG_WINDOW ] = LockDialogResource(MAKEINTRESOURCE(IDD_DIALOG_WINDOWSETTINGS));
pHeader->apRes[ PG_CONNECTION ] = LockDialogResource(MAKEINTRESOURCE(IDD_DIALOG_CONNECTION));
pHeader->apRes[ PG_LANGUAGE ] = LockDialogResource(MAKEINTRESOURCE(IDD_DIALOG_LANGUAGE_ND));


RECT rcTab;
SetRectEmpty(&rcTab);
Expand Down