]> cygwin.com Git - cygwin-apps/setup.git/blame - localdir.cc
Added dpiAwareness element to manifest
[cygwin-apps/setup.git] / localdir.cc
CommitLineData
c92e1307
DD
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
b24c88b3
RC
18 * locally downloaded package files to be cached
19 */
c92e1307 20
a77b6167
MB
21#include "localdir.h"
22
23#include "LogSingleton.h"
24#include "LogFile.h"
c92e1307 25#include "win32.h"
7cc4d95e 26#include "filemanip.h"
a77b6167 27
c92e1307
DD
28#include <shlobj.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <ctype.h>
32
458d5797 33#include "ini.h"
c92e1307
DD
34#include "dialog.h"
35#include "resource.h"
36#include "state.h"
37#include "msg.h"
38#include "mount.h"
b24c88b3 39#include "io_stream.h"
e0a4fb63 40#include "mkdir.h"
45c2d7d3 41
f0fd8856 42#include "UserSettings.h"
ab57ceaa 43
c9feb168
RC
44#include "getopt++/StringOption.h"
45
ab57ceaa
RC
46#include "threebar.h"
47extern ThreeBarProgressPage Progress;
dea6cc21 48
20f237b4 49static StringOption LocalDirOption ("", 'l', "local-package-dir", IDS_HELPTEXT_LOCAL_PACKAGE_DIR, false);
c9feb168 50
daab12c7
BD
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
f26f525f
CF
58LocalDirSetting::LocalDirSetting ()
59{
f26f525f 60 const char *fg_ret;
2b94fe1e
DK
61 if (std::string (LocalDirOption).size ())
62 local_dir = std::string (LocalDirOption);
63 else if ((fg_ret = UserSettings::instance().get ("last-cache")))
7c863922 64 local_dir = std::string (fg_ret);
dbdc1d9d 65}
dea6cc21 66
f26f525f
CF
67void
68LocalDirSetting::save ()
45c2d7d3 69{
f26f525f 70 UserSettings::instance().set ("last-cache", local_dir);
9f4a0c62
RC
71 if (source == IDC_SOURCE_DOWNLOAD || !get_root_dir ().size())
72 {
4d10ec8c 73 const char *sep = isdirsep (local_dir[local_dir.size () - 1]) ? "" : "\\";
5fa64c3c
CV
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);
9f4a0c62
RC
77 }
78 else
79 {
5fa64c3c 80 Logger ().clearFiles();
c459d893 81 mkdir_p (1, cygpath ("/var/log").c_str (), 01777);
5fa64c3c
CV
82 Logger ().setFile (LOG_BABBLE, cygpath ("/var/log/setup.log.full"),
83 false);
84 Logger ().setFile (0, cygpath ("/var/log/setup.log"), true);
9f4a0c62 85 }
45c2d7d3
RC
86}
87
c92e1307
DD
88static void
89check_if_enable_next (HWND h)
90{
3c054baf 91 EnableWindow (GetDlgItem (h, IDOK), local_dir.size() != 0);
c92e1307
DD
92}
93
94static void
95load_dialog (HWND h)
96{
7cc4d95e 97 if (source != IDC_SOURCE_LOCALDIR)
e0fd9bd3 98 {
15befbf1
JT
99 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_DOWNLOAD_DESC), SW_SHOW);
100 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_INSTALL_DESC), SW_HIDE);
e0fd9bd3
CF
101 }
102 else
103 {
15befbf1
JT
104 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_DOWNLOAD_DESC), SW_HIDE);
105 ShowWindow (GetDlgItem(h, IDC_LOCAL_DIR_INSTALL_DESC), SW_SHOW);
e0fd9bd3 106 }
c92e1307
DD
107 eset (h, IDC_LOCAL_DIR, local_dir);
108 check_if_enable_next (h);
109}
110
111static void
112save_dialog (HWND h)
113{
3c054baf 114 local_dir = egetString (h, IDC_LOCAL_DIR);
c92e1307
DD
115}
116
cc7a5bf5
DK
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 {
cc7a5bf5 126 DWORD ret;
17d64747 127 ret = mbox (h, IDS_MAYBE_MKDIR, MB_ICONSTOP | MB_YESNO, dirname);
cc7a5bf5
DK
128 if (ret == IDNO)
129 return -1;
130 }
131
d2a5fdfb 132 int rv = mkdir_p (true, dirname, 0);
cc7a5bf5
DK
133
134 if (rv)
135 note (h, IDS_CANT_MKDIR, dirname);
136
137 return rv;
138}
c92e1307
DD
139
140static int CALLBACK
141browse_cb (HWND h, UINT msg, LPARAM lp, LPARAM data)
142{
7cc4d95e 143 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
cc7a5bf5 144 static CHAR dirname[MAX_PATH];
c92e1307
DD
145 switch (msg)
146 {
147 case BFFM_INITIALIZED:
3c054baf 148 if (local_dir.size())
d2a3615c 149 SendMessage (h, BFFM_SETSELECTION, TRUE, (LPARAM) local_dir.c_str());
c92e1307 150 break;
cc7a5bf5 151 case BFFM_SELCHANGED:
10b2d051
YS
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 }
cc7a5bf5
DK
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;
c92e1307
DD
172 }
173 return 0;
174}
175
176static void
177browse (HWND h)
178{
7409282c
JT
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;
c92e1307
DD
185 memset (&bi, 0, sizeof (bi));
186 bi.hwndOwner = h;
7409282c
JT
187 bi.pszDisplayName = wname;
188 bi.lpszTitle = title.c_str();
cc7a5bf5 189 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE
7cc4d95e
CV
190 | ((source != IDC_SOURCE_LOCALDIR) ? (BIF_EDITBOX | BIF_VALIDATE)
191 : 0);
c92e1307 192 bi.lpfn = browse_cb;
7409282c
JT
193
194 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
195 LPITEMIDLIST pidl;
196 pidl = SHBrowseForFolderW (&bi);
c92e1307
DD
197 if (pidl)
198 {
7409282c 199 CHAR name[MAX_PATH];
c92e1307
DD
200 if (SHGetPathFromIDList (pidl, name))
201 eset (h, IDC_LOCAL_DIR, name);
202 }
203}
204
c92e1307
DD
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;
c92e1307 219 }
b24c88b3 220 return 0;
c92e1307
DD
221}
222
daab12c7
BD
223LocalDirPage::LocalDirPage ()
224{
225 sizeProcessor.AddControlInfo (LocaldirControlsInfo);
226}
227
ab57ceaa
RC
228bool
229LocalDirPage::Create ()
c92e1307 230{
ab57ceaa 231 return PropertyPage::Create (NULL, dialog_cmd, IDD_LOCAL_DIR);
c92e1307
DD
232}
233
ab57ceaa
RC
234void
235LocalDirPage::OnActivate ()
236{
237 load_dialog (GetHWND ());
238}
239
240long
241LocalDirPage::OnNext ()
242{
243 HWND h = GetHWND ();
c92e1307 244
ab57ceaa 245 save_dialog (h);
7c907c13
CF
246 while (local_dir[local_dir.size() - 1] == '\\' || local_dir[local_dir.size() - 1] == '/')
247 local_dir.erase (local_dir.size() - 1, 1);
f26f525f 248 LocalDirSetting::save ();
157dc2b8 249 Log (LOG_PLAIN) << "Selected local directory: " << local_dir << endLog;
081bf320 250
7cc4d95e
CV
251 bool tryLocalDir = true;
252 while (tryLocalDir)
ab57ceaa 253 {
7cc4d95e
CV
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))
ab57ceaa 265 {
7cc4d95e 266 if (source == IDC_SOURCE_LOCALDIR)
ab57ceaa 267 {
c80470f6
JT
268 do_from_local_dir (GetInstance (), GetHWND (), local_dir);
269 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
270 return IDD_INSTATUS;
ab57ceaa 271 }
081bf320 272 }
7cc4d95e
CV
273 else if (attr == INVALID_FILE_ATTRIBUTES
274 && (GetLastError () == ERROR_FILE_NOT_FOUND
275 || GetLastError () == ERROR_PATH_NOT_FOUND))
cc7a5bf5 276 {
c80470f6
JT
277 if (source == IDC_SOURCE_LOCALDIR)
278 {
279 if (!unattended_mode)
cc7a5bf5
DK
280 {
281 // Check the user really wants only to uninstall.
17d64747
JT
282 int ret = mbox(h, IDS_NO_LOCALDIR,
283 MB_ICONEXCLAMATION | MB_OKCANCEL,
284 local_dir.c_str ());
c80470f6
JT
285 if (ret == IDCANCEL)
286 return -1;
cc7a5bf5 287 }
c80470f6
JT
288 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
289 return IDD_INSTATUS;
290 }
cc7a5bf5
DK
291 else if (offer_to_create (GetHWND (), local_dir.c_str ()))
292 return -1;
7cc4d95e 293 tryLocalDir = true;
cc7a5bf5 294 }
081bf320
RC
295 else
296 {
297 DWORD err = GetLastError ();
17d64747
JT
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)
081bf320 302 {
17d64747 303 snprintf (msg, sizeof (msg), "%s", buf);
cc7a5bf5 304 LocalFree (buf);
17d64747
JT
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);
7a2a6788 311 if (ret == IDABORT)
081bf320
RC
312 return -1;
313 else
7cc4d95e 314 tryLocalDir = (ret == IDRETRY);
ab57ceaa
RC
315 }
316 }
ab57ceaa 317
7a2a6788
JT
318 if (source == IDC_SOURCE_LOCALDIR)
319 return IDD_INSTATUS;
320
c80470f6 321 return 0; // IDD_NET
ab57ceaa
RC
322}
323
324long
325LocalDirPage::OnBack ()
326{
327 save_dialog (GetHWND ());
ab57ceaa 328 return 0;
c92e1307 329}
This page took 0.192148 seconds and 6 git commands to generate.