2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru>
13 * based on work and suggestions of DJ Delorie
17 /* The purpose of this file is to ask the user where they want the
18 * locally downloaded package files to be cached
23 #include "LogSingleton.h"
26 #include "filemanip.h"
39 #include "io_stream.h"
42 #include "UserSettings.h"
44 #include "getopt++/StringOption.h"
47 extern ThreeBarProgressPage Progress
;
49 static StringOption
LocalDirOption ("", 'l', "local-package-dir", IDS_HELPTEXT_LOCAL_PACKAGE_DIR
, false);
51 static 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
},
58 LocalDirSetting::LocalDirSetting ()
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
);
68 LocalDirSetting::save ()
70 UserSettings::instance().set ("last-cache", local_dir
);
71 if (source
== IDC_SOURCE_DOWNLOAD
|| !get_root_dir ().size())
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);
80 Logger ().clearFiles();
81 mkdir_p (1, cygpath ("/var/log").c_str (), 01777);
82 Logger ().setFile (LOG_BABBLE
, cygpath ("/var/log/setup.log.full"),
84 Logger ().setFile (0, cygpath ("/var/log/setup.log"), true);
89 check_if_enable_next (HWND h
)
91 EnableWindow (GetDlgItem (h
, IDOK
), local_dir
.size() != 0);
97 if (source
!= IDC_SOURCE_LOCALDIR
)
99 ShowWindow (GetDlgItem(h
, IDC_LOCAL_DIR_DOWNLOAD_DESC
), SW_SHOW
);
100 ShowWindow (GetDlgItem(h
, IDC_LOCAL_DIR_INSTALL_DESC
), SW_HIDE
);
104 ShowWindow (GetDlgItem(h
, IDC_LOCAL_DIR_DOWNLOAD_DESC
), SW_HIDE
);
105 ShowWindow (GetDlgItem(h
, IDC_LOCAL_DIR_INSTALL_DESC
), SW_SHOW
);
107 eset (h
, IDC_LOCAL_DIR
, local_dir
);
108 check_if_enable_next (h
);
114 local_dir
= egetString (h
, IDC_LOCAL_DIR
);
117 // returns non-zero if refused or error, 0 if accepted and created ok.
119 offer_to_create (HWND h
, const char *dirname
)
121 if (!dirname
|| !*dirname
)
124 if (!unattended_mode
)
127 ret
= mbox (h
, IDS_MAYBE_MKDIR
, MB_ICONSTOP
| MB_YESNO
, dirname
);
132 int rv
= mkdir_p (true, dirname
, 0);
135 note (h
, IDS_CANT_MKDIR
, dirname
);
141 browse_cb (HWND h
, UINT msg
, LPARAM lp
, LPARAM data
)
143 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
144 static CHAR dirname
[MAX_PATH
];
147 case BFFM_INITIALIZED
:
148 if (local_dir
.size())
149 SendMessage (h
, BFFM_SETSELECTION
, TRUE
, (LPARAM
) local_dir
.c_str());
151 case BFFM_SELCHANGED
:
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
);
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
))
166 SendMessage (h
, BFFM_SETSELECTION
, TRUE
, reinterpret_cast<LPARAM
>(tempname
));
169 // Reset to original directory instead.
170 SendMessage (h
, BFFM_SETSELECTION
, TRUE
, reinterpret_cast<LPARAM
>(dirname
));
179 std::wstring title
= LoadStringW((source
!= IDC_SOURCE_LOCALDIR
) ?
180 IDS_LOCALDIR_BROWSE_DOWNLOAD_TITLE
:
181 IDS_LOCALDIR_BROWSE_PACKAGE_TITLE
);
183 wchar_t wname
[MAX_PATH
];
185 memset (&bi
, 0, sizeof (bi
));
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
)
194 /* SHGetPathFromIDList doesn't handle path length > MAX_PATH. */
196 pidl
= SHBrowseForFolderW (&bi
);
200 if (SHGetPathFromIDList (pidl
, name
))
201 eset (h
, IDC_LOCAL_DIR
, name
);
206 dialog_cmd (HWND h
, int id
, HWND hwndctl
, UINT code
)
213 check_if_enable_next (h
);
216 case IDC_LOCAL_DIR_BROWSE
:
223 LocalDirPage::LocalDirPage ()
225 sizeProcessor
.AddControlInfo (LocaldirControlsInfo
);
229 LocalDirPage::Create ()
231 return PropertyPage::Create (NULL
, dialog_cmd
, IDD_LOCAL_DIR
);
235 LocalDirPage::OnActivate ()
237 load_dialog (GetHWND ());
241 LocalDirPage::OnNext ()
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
;
251 bool tryLocalDir
= true;
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
260 size_t len
= local_dir
.size () + 7;
262 mklongpath (wlocal
, local_dir
.c_str (), len
);
263 DWORD attr
= GetFileAttributesW (wlocal
);
264 if (attr
!= INVALID_FILE_ATTRIBUTES
&& (attr
& FILE_ATTRIBUTE_DIRECTORY
))
266 if (source
== IDC_SOURCE_LOCALDIR
)
268 do_from_local_dir (GetInstance (), GetHWND (), local_dir
);
269 Progress
.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD
);
273 else if (attr
== INVALID_FILE_ATTRIBUTES
274 && (GetLastError () == ERROR_FILE_NOT_FOUND
275 || GetLastError () == ERROR_PATH_NOT_FOUND
))
277 if (source
== IDC_SOURCE_LOCALDIR
)
279 if (!unattended_mode
)
281 // Check the user really wants only to uninstall.
282 int ret
= mbox(h
, IDS_NO_LOCALDIR
,
283 MB_ICONEXCLAMATION
| MB_OKCANCEL
,
288 Progress
.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD
);
291 else if (offer_to_create (GetHWND (), local_dir
.c_str ()))
297 DWORD err
= GetLastError ();
300 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
301 0, err
, LANG_NEUTRAL
, (LPSTR
)&buf
, 0, 0) != 0)
303 snprintf (msg
, sizeof (msg
), "%s", buf
);
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
);
314 tryLocalDir
= (ret
== IDRETRY
);
318 if (source
== IDC_SOURCE_LOCALDIR
)
325 LocalDirPage::OnBack ()
327 save_dialog (GetHWND ());