1 /*
2  * PROJECT:     ReactOS Applications Manager
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Settings Dialog
5  * COPYRIGHT:   Copyright 2009 Dmitry Chapyshev (dmitry@reactos.org)
6  *              Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
7  */
8 #include "rapps.h"
9 
10 SETTINGS_INFO NewSettingsInfo;
11 
12 BOOL
13 ChooseFolder(HWND hwnd)
14 {
15     BOOL bRet = FALSE;
16     BROWSEINFOW bi;
17     CStringW szChooseFolderText;
18 
19     szChooseFolderText.LoadStringW(IDS_CHOOSE_FOLDER_TEXT);
20 
21     ZeroMemory(&bi, sizeof(bi));
22     bi.hwndOwner = hwnd;
23     bi.pidlRoot = NULL;
24     bi.lpszTitle = szChooseFolderText;
25     bi.ulFlags =
26         BIF_USENEWUI | BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | /* BIF_BROWSEFILEJUNCTIONS | */ BIF_VALIDATE;
27 
28     if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
29     {
30         CStringW szBuf;
31 
32         LPITEMIDLIST lpItemList = SHBrowseForFolderW(&bi);
33         if (lpItemList && SHGetPathFromIDListW(lpItemList, szBuf.GetBuffer(MAX_PATH)))
34         {
35             szBuf.ReleaseBuffer();
36             if (!szBuf.IsEmpty())
37             {
38                 SetDlgItemTextW(hwnd, IDC_DOWNLOAD_DIR_EDIT, szBuf);
39                 bRet = TRUE;
40             }
41         }
42         else
43         {
44             szBuf.ReleaseBuffer();
45         }
46 
47         CoTaskMemFree(lpItemList);
48         CoUninitialize();
49     }
50 
51     return bRet;
52 }
53 
54 BOOL
55 IsUrlValid(const WCHAR *Url)
56 {
57     URL_COMPONENTSW UrlComponmentInfo = {0};
58     UrlComponmentInfo.dwStructSize = sizeof(UrlComponmentInfo);
59     UrlComponmentInfo.dwSchemeLength = 1;
60 
61     BOOL bSuccess = InternetCrackUrlW(Url, wcslen(Url), 0, &UrlComponmentInfo);
62     if (!bSuccess)
63     {
64         return FALSE;
65     }
66 
67     switch (UrlComponmentInfo.nScheme)
68     {
69         case INTERNET_SCHEME_HTTP:
70         case INTERNET_SCHEME_HTTPS:
71         case INTERNET_SCHEME_FTP:
72         case INTERNET_SCHEME_FILE:
73             // supported
74             return TRUE;
75 
76         default:
77             return FALSE;
78     }
79 }
80 
81 namespace
82 {
83 inline BOOL
84 IsCheckedDlgItem(HWND hDlg, INT nIDDlgItem)
85 {
86     return (SendDlgItemMessageW(hDlg, nIDDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? TRUE : FALSE;
87 }
88 
89 VOID
90 InitSettingsControls(HWND hDlg, PSETTINGS_INFO Info)
91 {
92     SendDlgItemMessageW(hDlg, IDC_SAVE_WINDOW_POS, BM_SETCHECK, Info->bSaveWndPos, 0);
93     SendDlgItemMessageW(hDlg, IDC_UPDATE_AVLIST, BM_SETCHECK, Info->bUpdateAtStart, 0);
94     SendDlgItemMessageW(hDlg, IDC_LOG_ENABLED, BM_SETCHECK, Info->bLogEnabled, 0);
95     SendDlgItemMessageW(hDlg, IDC_DEL_AFTER_INSTALL, BM_SETCHECK, Info->bDelInstaller, 0);
96 
97     SetWindowTextW(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT), Info->szDownloadDir);
98 
99     CheckRadioButton(hDlg, IDC_PROXY_DEFAULT, IDC_USE_PROXY, IDC_PROXY_DEFAULT + Info->Proxy);
100 
101     if (Info->Proxy == 2)
102     {
103         EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), TRUE);
104         EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), TRUE);
105     }
106     else
107     {
108         EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
109         EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
110     }
111 
112     CheckRadioButton(hDlg, IDC_SOURCE_DEFAULT, IDC_USE_SOURCE, Info->bUseSource ? IDC_USE_SOURCE : IDC_SOURCE_DEFAULT);
113 
114     EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), Info->bUseSource);
115 
116     SetWindowTextW(GetDlgItem(hDlg, IDC_SOURCE_URL), Info->szSourceURL);
117     SetWindowTextW(GetDlgItem(hDlg, IDC_PROXY_SERVER), Info->szProxyServer);
118     SetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), Info->szNoProxyFor);
119 }
120 
121 INT_PTR CALLBACK
122 SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
123 {
124     switch (Msg)
125     {
126         case WM_INITDIALOG:
127             NewSettingsInfo = SettingsInfo;
128             InitSettingsControls(hDlg, &SettingsInfo);
129             return TRUE;
130 
131         case WM_COMMAND:
132         {
133             switch (LOWORD(wParam))
134             {
135                 case IDC_CHOOSE:
136                     ChooseFolder(hDlg);
137                     break;
138 
139                 case IDC_SAVE_WINDOW_POS:
140                     NewSettingsInfo.bSaveWndPos = IsCheckedDlgItem(hDlg, IDC_SAVE_WINDOW_POS);
141                     break;
142 
143                 case IDC_UPDATE_AVLIST:
144                     NewSettingsInfo.bUpdateAtStart = IsCheckedDlgItem(hDlg, IDC_UPDATE_AVLIST);
145                     break;
146 
147                 case IDC_LOG_ENABLED:
148                     NewSettingsInfo.bLogEnabled = IsCheckedDlgItem(hDlg, IDC_LOG_ENABLED);
149                     break;
150 
151                 case IDC_DEL_AFTER_INSTALL:
152                     NewSettingsInfo.bDelInstaller = IsCheckedDlgItem(hDlg, IDC_DEL_AFTER_INSTALL);
153                     break;
154 
155                 case IDC_SOURCE_DEFAULT:
156                     NewSettingsInfo.bUseSource = FALSE;
157                     EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
158                     break;
159 
160                 case IDC_USE_SOURCE:
161                     NewSettingsInfo.bUseSource = TRUE;
162                     EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
163                     break;
164 
165                 case IDC_PROXY_DEFAULT:
166                     NewSettingsInfo.Proxy = 0;
167                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
168                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
169                     break;
170 
171                 case IDC_NO_PROXY:
172                     NewSettingsInfo.Proxy = 1;
173                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
174                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
175                     break;
176 
177                 case IDC_USE_PROXY:
178                     NewSettingsInfo.Proxy = 2;
179                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), TRUE);
180                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), TRUE);
181                     break;
182 
183                 case IDC_DEFAULT_SETTINGS:
184                     FillDefaultSettings(&NewSettingsInfo);
185                     InitSettingsControls(hDlg, &NewSettingsInfo);
186                     break;
187 
188                 case IDOK:
189                 {
190                     CStringW szDir;
191                     CStringW szSource;
192                     CStringW szProxy;
193                     CStringW szNoProxy;
194                     DWORD dwAttr;
195 
196                     GetWindowTextW(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT), szDir.GetBuffer(MAX_PATH), MAX_PATH);
197                     szDir.ReleaseBuffer();
198 
199                     GetWindowTextW(
200                         GetDlgItem(hDlg, IDC_SOURCE_URL), szSource.GetBuffer(INTERNET_MAX_URL_LENGTH),
201                         INTERNET_MAX_URL_LENGTH);
202                     szSource.ReleaseBuffer();
203 
204                     GetWindowTextW(GetDlgItem(hDlg, IDC_PROXY_SERVER), szProxy.GetBuffer(MAX_PATH), MAX_PATH);
205                     szProxy.ReleaseBuffer();
206                     CStringW::CopyChars(
207                         NewSettingsInfo.szProxyServer, _countof(NewSettingsInfo.szProxyServer), szProxy,
208                         szProxy.GetLength() + 1);
209 
210                     GetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), szNoProxy.GetBuffer(MAX_PATH), MAX_PATH);
211                     szNoProxy.ReleaseBuffer();
212                     CStringW::CopyChars(
213                         NewSettingsInfo.szNoProxyFor, _countof(NewSettingsInfo.szNoProxyFor), szNoProxy,
214                         szNoProxy.GetLength() + 1);
215 
216                     dwAttr = GetFileAttributesW(szDir);
217                     if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
218                     {
219                         CStringW::CopyChars(
220                             NewSettingsInfo.szDownloadDir, _countof(NewSettingsInfo.szDownloadDir), szDir,
221                             szDir.GetLength() + 1);
222                     }
223                     else
224                     {
225                         CStringW szMsgText;
226                         szMsgText.LoadStringW(IDS_CHOOSE_FOLDER_ERROR);
227 
228                         if (MessageBoxW(hDlg, szMsgText, NULL, MB_YESNO) == IDYES)
229                         {
230                             if (CreateDirectoryW(szDir, NULL))
231                             {
232                                 EndDialog(hDlg, LOWORD(wParam));
233                             }
234                         }
235                         else
236                         {
237                             SetFocus(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT));
238                             break;
239                         }
240                     }
241 
242                     if (NewSettingsInfo.bUseSource && !IsUrlValid(szSource))
243                     {
244                         CStringW szMsgText;
245                         szMsgText.LoadStringW(IDS_URL_INVALID);
246 
247                         MessageBoxW(hDlg, szMsgText, NULL, MB_OK);
248                         SetFocus(GetDlgItem(hDlg, IDC_SOURCE_URL));
249                         break;
250                     }
251                     else
252                     {
253                         CStringW::CopyChars(
254                             NewSettingsInfo.szSourceURL, _countof(NewSettingsInfo.szSourceURL), szSource,
255                             szSource.GetLength() + 1);
256                     }
257 
258                     SettingsInfo = NewSettingsInfo;
259                     SaveSettings(GetParent(hDlg), &SettingsInfo);
260                     EndDialog(hDlg, LOWORD(wParam));
261                 }
262                 break;
263 
264                 case IDCANCEL:
265                     EndDialog(hDlg, LOWORD(wParam));
266                     break;
267             }
268         }
269         break;
270     }
271 
272     return FALSE;
273 }
274 } // namespace
275 
276 VOID
277 CreateSettingsDlg(HWND hwnd)
278 {
279     DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_SETTINGS_DIALOG), hwnd, SettingsDlgProc);
280 }
281