From 146aab0a44c12ace8ac131e55f3a791cc9bb6086 Mon Sep 17 00:00:00 2001 From: Sergey Svistunov Date: Fri, 10 May 2024 18:22:40 +0300 Subject: [PATCH] Add 'Open system connection settings' button to Upload Settings 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 --- Lang/imageuploader.pot | 14 +++-- Lang/locale/ru/LC_MESSAGES/imageuploader.po | 18 +++--- Source/Core/DefaultProxyProvider.cpp | 19 +----- Source/Func/WinUtils.cpp | 17 ++++-- Source/Func/WinUtils.h | 2 +- Source/Gui/Dialogs/UploadSettingsPage.cpp | 64 ++++++++++++++++---- Source/Gui/Dialogs/UploadSettingsPage.h | 14 ++++- Source/Image Uploader.rc | 5 +- Source/res/Src/icons8-external-link-160.png | Bin 0 -> 1271 bytes Source/res/icon-external-link.ico | Bin 0 -> 17542 bytes Source/resource.h | 4 +- TODO.txt | 1 - 12 files changed, 107 insertions(+), 51 deletions(-) create mode 100644 Source/res/Src/icons8-external-link-160.png create mode 100644 Source/res/icon-external-link.ico diff --git a/Lang/imageuploader.pot b/Lang/imageuploader.pot index 278242a7..fc1ea26b 100644 --- a/Lang/imageuploader.pot +++ b/Lang/imageuploader.pot @@ -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 \n" "Language-Team: LANGUAGE \n" @@ -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 @@ -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." @@ -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 "" @@ -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 "" diff --git a/Lang/locale/ru/LC_MESSAGES/imageuploader.po b/Lang/locale/ru/LC_MESSAGES/imageuploader.po index 07b436d2..51da34fd 100644 --- a/Lang/locale/ru/LC_MESSAGES/imageuploader.po +++ b/Lang/locale/ru/LC_MESSAGES/imageuploader.po @@ -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" @@ -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 @@ -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." @@ -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 не существует" @@ -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 "Открыть с помощью..." @@ -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" diff --git a/Source/Core/DefaultProxyProvider.cpp b/Source/Core/DefaultProxyProvider.cpp index dee4d926..c0c6fe46 100644 --- a/Source/Core/DefaultProxyProvider.cpp +++ b/Source/Core/DefaultProxyProvider.cpp @@ -214,20 +214,5 @@ bool DefaultProxyProvider::obtainProxyConfig() { } CString DefaultProxyProvider::proxyForUrlErrorToString(DWORD errorCode) const { - std::map 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); -} \ No newline at end of file + return WinUtils::ErrorCodeToString(errorCode, GetModuleHandle(_T("winhttp.dll"))); +} diff --git a/Source/Func/WinUtils.cpp b/Source/Func/WinUtils.cpp index 62839222..fc0bb8ed 100644 --- a/Source/Func/WinUtils.cpp +++ b/Source/Func/WinUtils.cpp @@ -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(&lpMsgBuf), 0, NULL); - CString res = reinterpret_cast(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(&lpMsgBuf), 0, NULL)) { + LOG(WARNING) << _T("Failed to format message! Error code %d\n") << GetLastError(); + } + + CString res = static_cast(lpMsgBuf); // Free the buffer. LocalFree(lpMsgBuf); return res; diff --git a/Source/Func/WinUtils.h b/Source/Func/WinUtils.h index 8201e44f..57025cd4 100644 --- a/Source/Func/WinUtils.h +++ b/Source/Func/WinUtils.h @@ -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); diff --git a/Source/Gui/Dialogs/UploadSettingsPage.cpp b/Source/Gui/Dialogs/UploadSettingsPage.cpp index 313f3264..01495eae 100644 --- a/Source/Gui/Dialogs/UploadSettingsPage.cpp +++ b/Source/Gui/Dialogs/UploadSettingsPage.cpp @@ -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(tipText.GetString())); + toolTip_.AddTool(tip); + SetDlgItemText(IDC_PROXYLOGINEDIT, U2W(Settings.ConnectionSettings.ProxyUser)); - SetDlgItemText(IDC_PROXYPASSWORDEDIT, (CString)Settings.ConnectionSettings.ProxyPassword); + SetDlgItemText(IDC_PROXYPASSWORDEDIT, static_cast(Settings.ConnectionSettings.ProxyPassword)); SetDlgItemInt(IDC_UPLOADBUFFERSIZEEDIT,Settings.UploadBufferSize/1024); if(Settings.ConnectionSettings.ProxyPort) SetDlgItemInt(IDC_PORTEDIT, Settings.ConnectionSettings.ProxyPort); @@ -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); @@ -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(fieldName), minValue, maxValue); throw ValidationException(message, GetDlgItem(controlId)); } -} \ No newline at end of file +} + +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(hinst) <= 32) { + LOG(ERROR) << "ShellExecute failed. Error code=" << reinterpret_cast(hinst); + } + return 0; +} diff --git a/Source/Gui/Dialogs/UploadSettingsPage.h b/Source/Gui/Dialogs/UploadSettingsPage.h index 28219035..96a300f2 100644 --- a/Source/Gui/Dialogs/UploadSettingsPage.h +++ b/Source/Gui/Dialogs/UploadSettingsPage.h @@ -30,8 +30,9 @@ // CUploadSettingsPage class CUploadSettingsPage : - public CDialogImpl, public CSettingsPage, - public CWinDataExchange + public CDialogImpl, + public CSettingsPage, + public CWinDataExchange { public: CUploadSettingsPage(); @@ -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); @@ -65,6 +70,7 @@ 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*/); @@ -72,6 +78,10 @@ virtual ~CUploadSettingsPage(); 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> proxyTypes = { { _T("HTTP"), 0 }, diff --git a/Source/Image Uploader.rc b/Source/Image Uploader.rc index dd7e2904..396466a4 100644 --- a/Source/Image Uploader.rc +++ b/Source/Image Uploader.rc @@ -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 @@ -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" + ///////////////////////////////////////////////////////////////////////////// // diff --git a/Source/res/Src/icons8-external-link-160.png b/Source/res/Src/icons8-external-link-160.png new file mode 100644 index 0000000000000000000000000000000000000000..da94c51277bccae70d24f5bd448d1b6e9058641f GIT binary patch literal 1271 zcmeAS@N?(olHy`uVBq!ia0vp^3qY8I4M=vMPuB%foCO|{#S9GG!XV7ZFl&wk0|U!S zPZ!6KiaBrZp3Rc>WH?f|_kqNubj=8%h|<2Meea!rh(&Ckz4~Nu%bh*#w(q3BBsD8a zNS>TEarN%k@d575Gk;Z@NYz$sS8fq-;!tdfF+Kg^`TCnWi?~mXNF7LUP;L8`)9#b!0%8H`@8?O z0fXJShROdFW!Mg~AK=@d@_2O&^RI(Iis8#*&tu_?FWM*ftY^B=uPzzSx6ONJR#h-jqQF^3&WF}dC}eZyiN>7tC!|B zzTcVucajf7(fswft?xJH|6LZwP&9cbkS+NjT7YRnxW%ooA9bu1dQJ?VK1JQ;y6@fa zT!BSl{o8G8Kgcpya49l0-;da^zqaDn-ff4zOC3;eng4E|jI|mA&(UzRnj5z453*^Z%YK4-V2JVUeKG`=8GgBYtYdf~ueg(mG(n~f%|PwvC^LjYHw*^t<_@O}1sEI``1LWSAK-KIc-PmS n@So%4T|rQ>BCsiX`hUhBDR1K5vpmiKmShZ`u6{1-oD!M<8ATTi literal 0 HcmV?d00001 diff --git a/Source/res/icon-external-link.ico b/Source/res/icon-external-link.ico new file mode 100644 index 0000000000000000000000000000000000000000..a04659717f7b665b5d5e78b3cfa7c18f5f362b86 GIT binary patch literal 17542 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 Gh4_CHEQ3w} literal 0 HcmV?d00001 diff --git a/Source/resource.h b/Source/resource.h index 621e7a97..6c47ce79 100644 --- a/Source/resource.h +++ b/Source/resource.h @@ -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 @@ -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 @@ -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 diff --git a/TODO.txt b/TODO.txt index 12abebb9..65a4eb8a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,6 @@ - Synchronize performed actions in DefaultUploadEngine () - 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.)