]> cygwin.com Git - cygwin-apps/setup.git/blame_incremental - localdir.cc
Added dpiAwareness element to manifest
[cygwin-apps/setup.git] / localdir.cc
... / ...
CommitLineData
1/*
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru>
13 * based on work and suggestions of DJ Delorie
14 *
15 */
16
17/* The purpose of this file is to ask the user where they want the
18 * locally downloaded package files to be cached
19 */
20
21#include "localdir.h"
22
23#include "LogSingleton.h"
24#include "LogFile.h"
25#include "win32.h"
26#include "filemanip.h"
27
28#include <shlobj.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <ctype.h>
32
33#include "ini.h"
34#include "dialog.h"
35#include "resource.h"
36#include "state.h"
37#include "msg.h"
38#include "mount.h"
39#include "io_stream.h"
40#include "mkdir.h"
41
42#include "UserSettings.h"
43
44#include "getopt++/StringOption.h"
45
46#include "threebar.h"
47extern ThreeBarProgressPage Progress;
48
49static StringOption LocalDirOption ("", 'l', "local-package-dir", IDS_HELPTEXT_LOCAL_PACKAGE_DIR, false);
50
51static ControlAdjuster::ControlInfo LocaldirControlsInfo[] = {
52 { IDC_LOCALDIR_GRP, CP_STRETCH, CP_TOP },
53 { IDC_LOCAL_DIR, CP_STRETCH, CP_TOP },
54 { IDC_LOCAL_DIR_BROWSE, CP_RIGHT, CP_TOP },
55 {0, CP_LEFT, CP_TOP}
56};
57
58LocalDirSetting::LocalDirSetting ()
59{
60 const char *fg_ret;
61 if (std::string (LocalDirOption).size ())
62 local_dir = std::string (LocalDirOption);
63 else if ((fg_ret = UserSettings::instance().get ("last-cache")))
64 local_dir = std::string (fg_ret);
65}
66
67void
68LocalDirSetting::save ()
69{
70 UserSettings::instance().set ("last-cache", local_dir);
71 if (source == IDC_SOURCE_DOWNLOAD || !get_root_dir ().size())
72 {
73 const char *sep = isdirsep (local_dir[local_dir.size () - 1]) ? "" : "\\";
74 Logger ().clearFiles();
75 Logger ().setFile (LOG_BABBLE, local_dir + sep + "setup.log.full", false);
76 Logger ().setFile (0, local_dir + sep + "setup.log", true);
77 }
78 else
79 {
80 Logger ().clearFiles();
81 mkdir_p (1, cygpath ("/var/log").c_str (), 01777);
82 Logger ().setFile (LOG_BABBLE, cygpath ("/var/log/setup.log.full"),
83 false);
84 Logger ().setFile (0, cygpath ("/var/log/setup.log"), true);
85 }
86}
87
88static void
89check_if_enable_next (HWND h)
90{
91 EnableWindow (GetDlgItem (h, IDOK), local_dir.size() != 0);
92}
93
94static void
95load_dialog (HWND h)
96{
97 if (source != IDC_SOURCE_LOCALDIR)
98 {
99 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_DOWNLOAD_DESC), SW_SHOW);
100 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_INSTALL_DESC), SW_HIDE);
101 }
102 else
103 {
104 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_DOWNLOAD_DESC), SW_HIDE);
105 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_INSTALL_DESC), SW_SHOW);
106 }
107 eset (h, IDC_LOCAL_DIR, local_dir);
108 check_if_enable_next (h);
109}
110
111static void
112save_dialog (HWND h)
113{
114 local_dir = egetString (h, IDC_LOCAL_DIR);
115}
116
117// returns non-zero if refused or error, 0 if accepted and created ok.
118static int
119offer_to_create (HWND h, const char *dirname)
120{
121 if (!dirname || !*dirname)
122 return -1;
123
124 if (!unattended_mode)
125 {
126 DWORD ret;
127 ret = mbox (h, IDS_MAYBE_MKDIR, MB_ICONSTOP | MB_YESNO, dirname);
128 if (ret == IDNO)
129 return -1;
130 }
131
132 int rv = mkdir_p (true, dirname, 0);
133
134 if (rv)
135 note (h, IDS_CANT_MKDIR, dirname);
136
137 return rv;
138}
139
140static int CALLBACK
141browse_cb (HWND h, UINT msg, LPARAM lp, LPARAM data)
142{
143 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
144 static CHAR dirname[MAX_PATH];
145 switch (msg)
146 {
147 case BFFM_INITIALIZED:
148 if (local_dir.size())
149 SendMessage (h, BFFM_SETSELECTION, TRUE, (LPARAM) local_dir.c_str());
150 break;
151 case BFFM_SELCHANGED:
152 {
153 // Make a note of each new dir we successfully select, so that
154 // we know where to create the new directory if an invalid name
155 // is entered in the text box.
156 LPITEMIDLIST pidl = reinterpret_cast<LPITEMIDLIST>(lp);
157 SHGetPathFromIDList (pidl, dirname);
158 break;
159 }
160 case BFFM_VALIDATEFAILED:
161 // See if user wants to create a dir in the last successfully-selected.
162 CHAR tempname[MAX_PATH];
163 snprintf (tempname, sizeof tempname, "%s\\%s", dirname, reinterpret_cast<LPTSTR>(lp));
164 if (!offer_to_create (h, tempname))
165 {
166 SendMessage (h, BFFM_SETSELECTION, TRUE, reinterpret_cast<LPARAM>(tempname));
167 return -1;
168 }
169 // Reset to original directory instead.
170 SendMessage (h, BFFM_SETSELECTION, TRUE, reinterpret_cast<LPARAM>(dirname));
171 return -1;
172 }
173 return 0;
174}
175
176static void
177browse (HWND h)
178{
179 std::wstring title = LoadStringW((source != IDC_SOURCE_LOCALDIR) ?
180 IDS_LOCALDIR_BROWSE_DOWNLOAD_TITLE :
181 IDS_LOCALDIR_BROWSE_PACKAGE_TITLE);
182
183 wchar_t wname[MAX_PATH];
184 BROWSEINFOW bi;
185 memset (&bi, 0, sizeof (bi));
186 bi.hwndOwner = h;
187 bi.pszDisplayName = wname;
188 bi.lpszTitle = title.c_str();
189 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE
190 | ((source != IDC_SOURCE_LOCALDIR) ? (BIF_EDITBOX | BIF_VALIDATE)
191 : 0);
192 bi.lpfn = browse_cb;
193
194 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
195 LPITEMIDLIST pidl;
196 pidl = SHBrowseForFolderW (&bi);
197 if (pidl)
198 {
199 CHAR name[MAX_PATH];
200 if (SHGetPathFromIDList (pidl, name))
201 eset (h, IDC_LOCAL_DIR, name);
202 }
203}
204
205static BOOL
206dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
207{
208 switch (id)
209 {
210
211 case IDC_LOCAL_DIR:
212 save_dialog (h);
213 check_if_enable_next (h);
214 break;
215
216 case IDC_LOCAL_DIR_BROWSE:
217 browse (h);
218 break;
219 }
220 return 0;
221}
222
223LocalDirPage::LocalDirPage ()
224{
225 sizeProcessor.AddControlInfo (LocaldirControlsInfo);
226}
227
228bool
229LocalDirPage::Create ()
230{
231 return PropertyPage::Create (NULL, dialog_cmd, IDD_LOCAL_DIR);
232}
233
234void
235LocalDirPage::OnActivate ()
236{
237 load_dialog (GetHWND ());
238}
239
240long
241LocalDirPage::OnNext ()
242{
243 HWND h = GetHWND ();
244
245 save_dialog (h);
246 while (local_dir[local_dir.size() - 1] == '\\' || local_dir[local_dir.size() - 1] == '/')
247 local_dir.erase (local_dir.size() - 1, 1);
248 LocalDirSetting::save ();
249 Log (LOG_PLAIN) << "Selected local directory: " << local_dir << endLog;
250
251 bool tryLocalDir = true;
252 while (tryLocalDir)
253 {
254 tryLocalDir = false;
255 /* FIXME: As for almost any other string, we should store local_dir
256 as UNICODE string to avoid the whole conversion mess.
257 We call GetFileAttributesW because our own version implies
258 FILE_OPEN_FOR_BACKUP_INTENT. We don't try to change CWD for
259 the same reason. */
260 size_t len = local_dir.size () + 7;
261 WCHAR wlocal[len];
262 mklongpath (wlocal, local_dir.c_str (), len);
263 DWORD attr = GetFileAttributesW (wlocal);
264 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
265 {
266 if (source == IDC_SOURCE_LOCALDIR)
267 {
268 do_from_local_dir (GetInstance (), GetHWND (), local_dir);
269 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
270 return IDD_INSTATUS;
271 }
272 }
273 else if (attr == INVALID_FILE_ATTRIBUTES
274 && (GetLastError () == ERROR_FILE_NOT_FOUND
275 || GetLastError () == ERROR_PATH_NOT_FOUND))
276 {
277 if (source == IDC_SOURCE_LOCALDIR)
278 {
279 if (!unattended_mode)
280 {
281 // Check the user really wants only to uninstall.
282 int ret = mbox(h, IDS_NO_LOCALDIR,
283 MB_ICONEXCLAMATION | MB_OKCANCEL,
284 local_dir.c_str ());
285 if (ret == IDCANCEL)
286 return -1;
287 }
288 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
289 return IDD_INSTATUS;
290 }
291 else if (offer_to_create (GetHWND (), local_dir.c_str ()))
292 return -1;
293 tryLocalDir = true;
294 }
295 else
296 {
297 DWORD err = GetLastError ();
298 char* buf;
299 char msg[1000];
300 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
301 0, err, LANG_NEUTRAL, (LPSTR)&buf, 0, 0) != 0)
302 {
303 snprintf (msg, sizeof (msg), "%s", buf);
304 LocalFree (buf);
305 }
306 else
307 snprintf (msg, sizeof (msg), "%s", "(unknown error)");
308 int ret = mbox (h, IDS_ERR_CHDIR,
309 MB_ICONEXCLAMATION | MB_ABORTRETRYIGNORE,
310 local_dir.c_str(), msg, err);
311 if (ret == IDABORT)
312 return -1;
313 else
314 tryLocalDir = (ret == IDRETRY);
315 }
316 }
317
318 if (source == IDC_SOURCE_LOCALDIR)
319 return IDD_INSTATUS;
320
321 return 0; // IDD_NET
322}
323
324long
325LocalDirPage::OnBack ()
326{
327 save_dialog (GetHWND ());
328 return 0;
329}
This page took 0.028823 seconds and 6 git commands to generate.