Skip to content

Commit

Permalink
Add 'Open system connection settings' button to Upload Settings
Browse files Browse the repository at this point in the history
Add 'Open system connection settings' to the UploadSettingsPage in the Settings dialog
Fixed WinHttp error messages in the DefaultProxyProvider
Disable the proxy server if the proxy server address is empty on the UploadSettingsPage
  • Loading branch information
zenden2k committed May 10, 2024
1 parent 7da13b0 commit 146aab0
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 51 deletions.
14 changes: 9 additions & 5 deletions Lang/imageuploader.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: imageuploader\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-05-05 15:13+0300\n"
"POT-Creation-Date: 2024-05-10 17:56+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -275,7 +275,7 @@ msgstr ""
#: ../Source/Gui/Dialogs/GeneralSettings.cpp:86
#: ../Source/Gui/Dialogs/LogoSettings.cpp:166
#: ../Source/Gui/Dialogs/MainDlg.cpp:674
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:227
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:253
#: ../Source/Gui/Dialogs/VideoGrabberPage.cpp:384
#: ../Source/Gui/Dialogs/WizardDlg.cpp:1634
#: ../Source/Gui/Dialogs/WizardDlg.cpp:1853
Expand Down Expand Up @@ -1165,12 +1165,12 @@ msgstr ""
msgid "Error control"
msgstr ""

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:214
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:240
#, c-format
msgid "Error in the field '%s':\n"
msgstr ""

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:267
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:293
#: ../Source/Gui/Dialogs/VideoGrabberParams.cpp:146
#, c-format
msgid "Error in the field '%s': value should be between %d and %d."
Expand Down Expand Up @@ -1272,7 +1272,7 @@ msgstr ""
msgid "File \"%s\" not found!"
msgstr ""

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:215
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:241
#, c-format
msgid "File %s doesn't exist"
msgstr ""
Expand Down Expand Up @@ -1976,6 +1976,10 @@ msgstr ""
msgid "Open screenshots folder"
msgstr ""

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:120
msgid "Open system connection settings"
msgstr ""

#: ../Source/Gui/Dialogs/MainDlg.cpp:188
msgid "Open with..."
msgstr ""
Expand Down
18 changes: 11 additions & 7 deletions Lang/locale/ru/LC_MESSAGES/imageuploader.po
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: imageuploader\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-05-05 15:13+0300\n"
"PO-Revision-Date: 2024-05-05 15:14+0300\n"
"POT-Creation-Date: 2024-05-10 17:56+0300\n"
"PO-Revision-Date: 2024-05-10 17:57+0300\n"
"Last-Translator: \n"
"Language-Team: zenden2k@gmail.com\n"
"Language: ru\n"
Expand Down Expand Up @@ -286,7 +286,7 @@ msgstr "Только для Aero (Windows Vista и новее)"
#: ../Source/Gui/Dialogs/GeneralSettings.cpp:86
#: ../Source/Gui/Dialogs/LogoSettings.cpp:166
#: ../Source/Gui/Dialogs/MainDlg.cpp:674
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:227
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:253
#: ../Source/Gui/Dialogs/VideoGrabberPage.cpp:384
#: ../Source/Gui/Dialogs/WizardDlg.cpp:1634
#: ../Source/Gui/Dialogs/WizardDlg.cpp:1853
Expand Down Expand Up @@ -1196,12 +1196,12 @@ msgstr "Ошибка"
msgid "Error control"
msgstr "Контроль ошибок"

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:214
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:240
#, c-format
msgid "Error in the field '%s':\n"
msgstr "Ошибка в поле '%s':\n"

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:267
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:293
#: ../Source/Gui/Dialogs/VideoGrabberParams.cpp:146
#, c-format
msgid "Error in the field '%s': value should be between %d and %d."
Expand Down Expand Up @@ -1303,7 +1303,7 @@ msgstr "Идет загрузка \"%s\" на сервер %s."
msgid "File \"%s\" not found!"
msgstr "Файл \"%s\" не найден!"

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:215
#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:241
#, c-format
msgid "File %s doesn't exist"
msgstr "Файл %s не существует"
Expand Down Expand Up @@ -2022,6 +2022,10 @@ msgstr "Открыть скриншот в редакторе"
msgid "Open screenshots folder"
msgstr "Открыть папку со снимками"

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:120
msgid "Open system connection settings"
msgstr "Открыть системные настройки подключений"

#: ../Source/Gui/Dialogs/MainDlg.cpp:188
msgid "Open with..."
msgstr "Открыть с помощью..."
Expand Down Expand Up @@ -3026,7 +3030,7 @@ msgstr "Использовать серверные миниатюры"

#: ../Source/Gui/Dialogs/UploadSettingsPage.cpp:44
msgid "Use system proxy settings"
msgstr "Автоматическое определение прокси"
msgstr "Использовать системные настройки прокси"

#: ../Source/Gui/Dialogs/ResultsPanel.cpp:914
msgid "Use template"
Expand Down
19 changes: 2 additions & 17 deletions Source/Core/DefaultProxyProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,20 +214,5 @@ bool DefaultProxyProvider::obtainProxyConfig() {
}

CString DefaultProxyProvider::proxyForUrlErrorToString(DWORD errorCode) const {
std::map<DWORD, const wchar_t*> errorMap = {
{ ERROR_IO_PENDING, L"ERROR_IO_PENDING"},
{ ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR, L"ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR" },
{ ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT, L"ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT" },
{ ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, L"ERROR_WINHTTP_INCORRECT_HANDLE_TYPE" },
{ ERROR_WINHTTP_INVALID_URL, L"ERROR_WINHTTP_INVALID_URL" },
{ ERROR_WINHTTP_OPERATION_CANCELLED, L"ERROR_WINHTTP_OPERATION_CANCELLED" },
{ ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, L"ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT" },
{ ERROR_WINHTTP_UNRECOGNIZED_SCHEME, L"ERROR_WINHTTP_UNRECOGNIZED_SCHEME" },
{ ERROR_NOT_ENOUGH_MEMORY, L"ERROR_NOT_ENOUGH_MEMORY" }
};
auto it = errorMap.find(errorCode);
if (it != errorMap.end()) {
return it->second;
}
return WinUtils::ErrorCodeToString(errorCode);
}
return WinUtils::ErrorCodeToString(errorCode, GetModuleHandle(_T("winhttp.dll")));
}
17 changes: 13 additions & 4 deletions Source/Func/WinUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,12 +1304,21 @@ std::string chcp(const std::string &str, UINT codePageSrc, UINT codePageDst)
return wstostr(strtows(str, codePageSrc), codePageDst);
}

CString ErrorCodeToString(DWORD idCode)
CString ErrorCodeToString(DWORD idCode, HMODULE mod)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
idCode, 0, reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, NULL);
CString res = reinterpret_cast<LPCTSTR>(lpMsgBuf);
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS;
if (mod != NULL) {
flags |= FORMAT_MESSAGE_FROM_HMODULE;
} else {
flags |= FORMAT_MESSAGE_FROM_SYSTEM;
}

if (!FormatMessage(flags, mod, idCode, 0, reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, NULL)) {
LOG(WARNING) << _T("Failed to format message! Error code %d\n") << GetLastError();
}

CString res = static_cast<LPCTSTR>(lpMsgBuf);
// Free the buffer.
LocalFree(lpMsgBuf);
return res;
Expand Down
2 changes: 1 addition & 1 deletion Source/Func/WinUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ namespace WinUtils {
std::string AnsiToUtf8(const std::string &str, int codepage);
std::string Utf8ToAnsi(const std::string &str, int codepage);
CString GetProcessName(DWORD pid);
CString ErrorCodeToString(DWORD idCode);
CString ErrorCodeToString(DWORD idCode, HMODULE mod = NULL);
CString ExpandEnvironmentStrings(const CString& s);
void ArgvQuote(const std::wstring& Argument, std::wstring& CommandLine, bool Force);
bool GetProxyInfo(CString& proxy_address, CString& proxy_bypass);
Expand Down
64 changes: 52 additions & 12 deletions Source/Gui/Dialogs/UploadSettingsPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,52 @@ LRESULT CUploadSettingsPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lPara
serverTypeCombo_.SetItemData(index, item.second);

}
/*serverTypeCombo_.AddString(_T("HTTP"));
serverTypeCombo_.AddString(_T("SOCKS4"));
serverTypeCombo_.AddString(_T("SOCKS4A"));
serverTypeCombo_.AddString(_T("SOCKS5"));
serverTypeCombo_.AddString(_T("SOCKS5(DNS)"));
serverTypeCombo_.AddString(_T("HTTPS"));*/


// ---- connection settings -----
SetDlgItemText(IDC_ADDRESSEDIT, U2W(Settings.ConnectionSettings.ServerAddress));
SendDlgItemMessage(IDC_NEEDSAUTH, BM_SETCHECK, (WPARAM) Settings.ConnectionSettings.NeedsAuth);
SendDlgItemMessage(IDC_AUTOCOPYTOCLIPBOARD, BM_SETCHECK, (WPARAM) Settings.AutoCopyToClipboard);


SendDlgItemMessage(IDC_USEPROXYSERVER, BM_SETCHECK, (WPARAM)(Settings.ConnectionSettings.UseProxy == ConnectionSettingsStruct::kUserProxy)?TRUE:FALSE);
SendDlgItemMessage(IDC_USESYSTEMPROXY, BM_SETCHECK, (WPARAM)(Settings.ConnectionSettings.UseProxy == ConnectionSettingsStruct::kSystemProxy)?TRUE:FALSE);
SendDlgItemMessage(IDC_NOPROXY, BM_SETCHECK, (WPARAM)(Settings.ConnectionSettings.UseProxy == ConnectionSettingsStruct::kNoProxy)?TRUE:FALSE);

int iconWidth = GetSystemMetrics(SM_CXSMICON);
int iconHeight = GetSystemMetrics(SM_CYSMICON);

SIZE radioButtonSize_{};

// Auto-size useSystemProxy_ radio button, then move openSystemConnectionSettingsButton_
// to the right of the radio button and center openSystemConnectionSettingsButton_ vertically
if (useSystemProxy_.GetIdealSize(&radioButtonSize_)) {
useSystemProxy_.SetWindowPos(0, 0, 0, radioButtonSize_.cx, radioButtonSize_.cy, SWP_NOZORDER | SWP_NOMOVE);
CRect useSystemProxyRect;
if (useSystemProxy_.GetWindowRect(&useSystemProxyRect) && ScreenToClient(useSystemProxyRect)) {
WORD unitX = LOWORD(GetDialogBaseUnits());
// Horizontal margin of the button is equal to 3 base dialog units
int offsetX = MulDiv(3, unitX, 4);
CRect buttonRect;
if (openSystemConnectionSettingsButton_.GetWindowRect(buttonRect) && ScreenToClient(buttonRect)) {
openSystemConnectionSettingsButton_.SetWindowPos(0, useSystemProxyRect.right + offsetX,
buttonRect.top + (buttonRect.Height() - useSystemProxyRect.Height()) / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE
);
}
}
}

externalLink_.LoadIconWithScaleDown(MAKEINTRESOURCE(IDI_ICONEXTERNALLINK), iconWidth, iconHeight);
openSystemConnectionSettingsButton_.SetIcon(externalLink_);

// Creating tooltip control. We will use subclassing of controls to intercept their messages
// The variant with usage of RelayEvent method is not available because we don't have access to message loop
// that is running in DialogBox method of CSettingsDlg.
toolTip_.Create(m_hWnd);
CString tipText = TR("Open system connection settings");
CToolInfo tip(TTF_SUBCLASS, openSystemConnectionSettingsButton_, 0, 0, const_cast<LPWSTR>(tipText.GetString()));
toolTip_.AddTool(tip);

SetDlgItemText(IDC_PROXYLOGINEDIT, U2W(Settings.ConnectionSettings.ProxyUser));
SetDlgItemText(IDC_PROXYPASSWORDEDIT, (CString)Settings.ConnectionSettings.ProxyPassword);
SetDlgItemText(IDC_PROXYPASSWORDEDIT, static_cast<CString>(Settings.ConnectionSettings.ProxyPassword));
SetDlgItemInt(IDC_UPLOADBUFFERSIZEEDIT,Settings.UploadBufferSize/1024);
if(Settings.ConnectionSettings.ProxyPort)
SetDlgItemInt(IDC_PORTEDIT, Settings.ConnectionSettings.ProxyPort);
Expand Down Expand Up @@ -177,11 +203,17 @@ bool CUploadSettingsPage::Apply()

Settings.ConnectionSettings.NeedsAuth = SendDlgItemMessage(IDC_NEEDSAUTH, BM_GETCHECK)!=0;
Settings.AutoCopyToClipboard = SendDlgItemMessage(IDC_AUTOCOPYTOCLIPBOARD, BM_GETCHECK)!=0;

CString proxyAddress;
TCHAR Buffer[128];
addressEdit_.GetWindowText(proxyAddress);

GetDlgItemText(IDC_ADDRESSEDIT,Buffer, 128);
Settings.ConnectionSettings.ServerAddress = W2U(Buffer);
Settings.ConnectionSettings.ServerAddress = W2U(proxyAddress);
Settings.ConnectionSettings.ProxyPort = GetDlgItemInt(IDC_PORTEDIT);

if (proxyAddress.IsEmpty() /* || Settings.ConnectionSettings.ProxyPort == 0*/) {
Settings.ConnectionSettings.UseProxy = ConnectionSettingsStruct::kNoProxy;
}

GetDlgItemText(IDC_PROXYLOGINEDIT, Buffer, 128);
Settings.ConnectionSettings.ProxyUser = W2U(Buffer);
Expand Down Expand Up @@ -267,4 +299,12 @@ void CUploadSettingsPage::CheckBounds(int controlId, int minValue, int maxValue,
message.Format(TR("Error in the field '%s': value should be between %d and %d."), static_cast<LPCTSTR>(fieldName), minValue, maxValue);
throw ValidationException(message, GetDlgItem(controlId));
}
}
}

LRESULT CUploadSettingsPage::OnOpenSystemConnectionSettingsClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
HINSTANCE hinst = ShellExecute(0, _T("open"), _T("rundll32.exe"), _T("inetcpl.cpl,LaunchConnectionDialog"), NULL, SW_SHOWNORMAL);
if (reinterpret_cast<int>(hinst) <= 32) {
LOG(ERROR) << "ShellExecute failed. Error code=" << reinterpret_cast<int>(hinst);
}
return 0;
}
14 changes: 12 additions & 2 deletions Source/Gui/Dialogs/UploadSettingsPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
// CUploadSettingsPage

class CUploadSettingsPage :
public CDialogImpl<CUploadSettingsPage>, public CSettingsPage,
public CWinDataExchange <CUploadSettingsPage >
public CDialogImpl<CUploadSettingsPage>,
public CSettingsPage,
public CWinDataExchange<CUploadSettingsPage>
{
public:
CUploadSettingsPage();
Expand All @@ -48,10 +49,14 @@ virtual ~CUploadSettingsPage();
COMMAND_HANDLER(IDC_NOPROXY, BN_CLICKED, OnClickedNoProxy)
COMMAND_HANDLER(IDC_USESYSTEMPROXY, BN_CLICKED, OnClickedUseSystemProxy)
COMMAND_HANDLER(IDC_EXECUTESCRIPTCHECKBOX, BN_CLICKED, OnExecuteScriptCheckboxClicked)
COMMAND_HANDLER(IDC_OPENSYSTEMCONNECTION, BN_CLICKED, OnOpenSystemConnectionSettingsClicked)
END_MSG_MAP()

BEGIN_DDX_MAP(CScreenshotDlg)
DDX_CONTROL_HANDLE(IDC_SERVERTYPECOMBO, serverTypeCombo_)
DDX_CONTROL_HANDLE(IDC_OPENSYSTEMCONNECTION, openSystemConnectionSettingsButton_)
DDX_CONTROL_HANDLE(IDC_USESYSTEMPROXY, useSystemProxy_)
DDX_CONTROL_HANDLE(IDC_ADDRESSEDIT, addressEdit_)
END_DDX_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
Expand All @@ -65,13 +70,18 @@ virtual ~CUploadSettingsPage();
LRESULT OnClickedNoProxy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnClickedUseSystemProxy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnExecuteScriptCheckboxClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnOpenSystemConnectionSettingsClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
bool Apply() override;
void TranslateUI();
LRESULT OnBnClickedBrowseScriptButton(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
void proxyRadioChanged();
void executeScriptCheckboxChanged();
protected:
CComboBox serverTypeCombo_;
CButton openSystemConnectionSettingsButton_, useSystemProxy_;
CIcon externalLink_;
CToolTipCtrl toolTip_;
CEdit addressEdit_;
void CheckBounds(int controlId, int minValue, int maxValue, int labelId = -1) const;
std::vector<std::pair<CString, int>> proxyTypes = {
{ _T("HTTP"), 0 },
Expand Down
5 changes: 4 additions & 1 deletion Source/Image Uploader.rc
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ BEGIN
CONTROL "#",IDC_AUTOCOPYTOCLIPBOARD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,11,233,10
GROUPBOX "#",IDC_CONNECTIONSETTINGS,8,26,250,125
CONTROL "#No proxy",IDC_NOPROXY,"Button",BS_AUTORADIOBUTTON,21,39,226,10
CONTROL "#Use system proxy",IDC_USESYSTEMPROXY,"Button",BS_AUTORADIOBUTTON,21,51,222,10
CONTROL "#Use system proxy",IDC_USESYSTEMPROXY,"Button",BS_AUTORADIOBUTTON,21,51,212,10
PUSHBUTTON "",IDC_OPENSYSTEMCONNECTION,240,47,18,14,BS_ICON | BS_NOTIFY
CONTROL "#Use provided proxy:",IDC_USEPROXYSERVER,"Button",BS_AUTORADIOBUTTON,21,63,217,10
LTEXT "�����:",IDC_ADDRESSLABEL,28,80,38,8
EDITTEXT IDC_ADDRESSEDIT,67,78,81,13,ES_AUTOHSCROLL
Expand Down Expand Up @@ -1542,6 +1543,8 @@ IDI_ICONSEPARATOR ICON "res\\icon_separator.ico"

IDI_ICONCONTROLS ICON "res\\icon-controls.ico"

IDI_ICONEXTERNALLINK ICON "res\\icon-external-link.ico"


/////////////////////////////////////////////////////////////////////////////
//
Expand Down
Binary file added Source/res/Src/icons8-external-link-160.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Source/res/icon-external-link.ico
Binary file not shown.
4 changes: 3 additions & 1 deletion Source/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
#define IDI_ICONSEPARATOR 332
#define IDI_ICON15 334
#define IDI_ICONCONTROLS 334
#define IDI_ICONEXTERNALLINK 336
#define IDC_ADDIMAGES 1000
#define IDC_TOOLSERVERLIST 1000
#define IDC_ADDVIDEO 1001
Expand Down Expand Up @@ -399,6 +400,7 @@
#define IDC_SHOWLOG 1080
#define IDC_LOGOUT 1080
#define IDC_BROWSEPRIVATEKEYBUTTON 1080
#define IDC_OPENSYSTEMCONNECTION 1080
#define IDC_ABOUT 1081
#define IDC_HELPBUTTON 1082
#define IDC_SPIN1 1083
Expand Down Expand Up @@ -790,7 +792,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 336
#define _APS_NEXT_RESOURCE_VALUE 337
#define _APS_NEXT_COMMAND_VALUE 32821
#define _APS_NEXT_CONTROL_VALUE 1341
#define _APS_NEXT_SYMED_VALUE 128
Expand Down
1 change: 0 additions & 1 deletion TODO.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
- Synchronize performed actions in DefaultUploadEngine (<Action OnlyOnce="1">)
- Reload server list after update
- [HIGH] Preserve photo order for some servers (like Picasa)
- Convert korean.lng and farsi.lng ?
- Proxy provided by DefaultProxyProvider not being changed on redirects
- Fix log window buttons moving when RTL is on
- Fix function names in docs (CSelection etc.)
Expand Down

0 comments on commit 146aab0

Please sign in to comment.