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         {
128             NewSettingsInfo = SettingsInfo;
129             InitSettingsControls(hDlg, &SettingsInfo);
130         }
131         break;
132 
133         case WM_COMMAND:
134         {
135             switch (LOWORD(wParam))
136             {
137                 case IDC_CHOOSE:
138                     ChooseFolder(hDlg);
139                     break;
140 
141                 case IDC_SAVE_WINDOW_POS:
142                     NewSettingsInfo.bSaveWndPos = IsCheckedDlgItem(hDlg, IDC_SAVE_WINDOW_POS);
143                     break;
144 
145                 case IDC_UPDATE_AVLIST:
146                     NewSettingsInfo.bUpdateAtStart = IsCheckedDlgItem(hDlg, IDC_UPDATE_AVLIST);
147                     break;
148 
149                 case IDC_LOG_ENABLED:
150                     NewSettingsInfo.bLogEnabled = IsCheckedDlgItem(hDlg, IDC_LOG_ENABLED);
151                     break;
152 
153                 case IDC_DEL_AFTER_INSTALL:
154                     NewSettingsInfo.bDelInstaller = IsCheckedDlgItem(hDlg, IDC_DEL_AFTER_INSTALL);
155                     break;
156 
157                 case IDC_SOURCE_DEFAULT:
158                     NewSettingsInfo.bUseSource = FALSE;
159                     EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
160                     break;
161 
162                 case IDC_USE_SOURCE:
163                     NewSettingsInfo.bUseSource = TRUE;
164                     EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
165                     break;
166 
167                 case IDC_PROXY_DEFAULT:
168                     NewSettingsInfo.Proxy = 0;
169                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
170                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
171                     break;
172 
173                 case IDC_NO_PROXY:
174                     NewSettingsInfo.Proxy = 1;
175                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
176                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
177                     break;
178 
179                 case IDC_USE_PROXY:
180                     NewSettingsInfo.Proxy = 2;
181                     EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), TRUE);
182                     EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), TRUE);
183                     break;
184 
185                 case IDC_DEFAULT_SETTINGS:
186                     FillDefaultSettings(&NewSettingsInfo);
187                     InitSettingsControls(hDlg, &NewSettingsInfo);
188                     break;
189 
190                 case IDOK:
191                 {
192                     CStringW szDir;
193                     CStringW szSource;
194                     CStringW szProxy;
195                     CStringW szNoProxy;
196                     DWORD dwAttr;
197 
198                     GetWindowTextW(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT), szDir.GetBuffer(MAX_PATH), MAX_PATH);
199                     szDir.ReleaseBuffer();
200 
201                     GetWindowTextW(
202                         GetDlgItem(hDlg, IDC_SOURCE_URL), szSource.GetBuffer(INTERNET_MAX_URL_LENGTH),
203                         INTERNET_MAX_URL_LENGTH);
204                     szSource.ReleaseBuffer();
205 
206                     GetWindowTextW(GetDlgItem(hDlg, IDC_PROXY_SERVER), szProxy.GetBuffer(MAX_PATH), MAX_PATH);
207                     szProxy.ReleaseBuffer();
208                     CStringW::CopyChars(
209                         NewSettingsInfo.szProxyServer, _countof(NewSettingsInfo.szProxyServer), szProxy,
210                         szProxy.GetLength() + 1);
211 
212                     GetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), szNoProxy.GetBuffer(MAX_PATH), MAX_PATH);
213                     szNoProxy.ReleaseBuffer();
214                     CStringW::CopyChars(
215                         NewSettingsInfo.szNoProxyFor, _countof(NewSettingsInfo.szNoProxyFor), szNoProxy,
216                         szNoProxy.GetLength() + 1);
217 
218                     dwAttr = GetFileAttributesW(szDir);
219                     if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
220                     {
221                         CStringW::CopyChars(
222                             NewSettingsInfo.szDownloadDir, _countof(NewSettingsInfo.szDownloadDir), szDir,
223                             szDir.GetLength() + 1);
224                     }
225                     else
226                     {
227                         CStringW szMsgText;
228                         szMsgText.LoadStringW(IDS_CHOOSE_FOLDER_ERROR);
229 
230                         if (MessageBoxW(hDlg, szMsgText, NULL, MB_YESNO) == IDYES)
231                         {
232                             if (CreateDirectoryW(szDir, NULL))
233                             {
234                                 EndDialog(hDlg, LOWORD(wParam));
235                             }
236                         }
237                         else
238                         {
239                             SetFocus(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT));
240                             break;
241                         }
242                     }
243 
244                     if (NewSettingsInfo.bUseSource && !IsUrlValid(szSource))
245                     {
246                         CStringW szMsgText;
247                         szMsgText.LoadStringW(IDS_URL_INVALID);
248 
249                         MessageBoxW(hDlg, szMsgText, NULL, 0);
250                         SetFocus(GetDlgItem(hDlg, IDC_SOURCE_URL));
251                         break;
252                     }
253                     else
254                     {
255                         CStringW::CopyChars(
256                             NewSettingsInfo.szSourceURL, _countof(NewSettingsInfo.szSourceURL), szSource,
257                             szSource.GetLength() + 1);
258                     }
259 
260                     SettingsInfo = NewSettingsInfo;
261                     SaveSettings(GetParent(hDlg), &SettingsInfo);
262                     EndDialog(hDlg, LOWORD(wParam));
263                 }
264                 break;
265 
266                 case IDCANCEL:
267                     EndDialog(hDlg, LOWORD(wParam));
268                     break;
269             }
270         }
271         break;
272     }
273 
274     return FALSE;
275 }
276 } // namespace
277 
278 VOID
279 CreateSettingsDlg(HWND hwnd)
280 {
281     DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_SETTINGS_DIALOG), hwnd, SettingsDlgProc);
282 }
283