]> cygwin.com Git - cygwin-apps/setup.git/blame - prereq.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / prereq.cc
CommitLineData
82306ac2
BD
1/*
2 * Copyright (c) 2005 Brian Dessent
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 Brian Dessent <brian@dessent.net>
13 *
14 */
15
82306ac2
BD
16#include "win32.h"
17#include <commctrl.h>
18#include <stdio.h>
19#include <io.h>
20#include <ctype.h>
21#include <process.h>
c7c6e034 22#include <queue>
82306ac2
BD
23
24#include "prereq.h"
25#include "dialog.h"
26#include "resource.h"
27#include "state.h"
28#include "propsheet.h"
29#include "threebar.h"
30#include "Generic.h"
31#include "LogSingleton.h"
32#include "ControlAdjuster.h"
33#include "package_db.h"
34#include "package_meta.h"
35#include "msg.h"
ad20ac46 36#include "Exception.h"
1d553f34 37#include "getopt++/BoolOption.h"
82306ac2
BD
38
39// Sizing information.
40static ControlAdjuster::ControlInfo PrereqControlsInfo[] = {
41 {IDC_PREREQ_CHECK, CP_LEFT, CP_BOTTOM},
42 {IDC_PREREQ_EDIT, CP_STRETCH, CP_STRETCH},
43 {0, CP_LEFT, CP_TOP}
44};
45
46extern ThreeBarProgressPage Progress;
1d553f34 47BoolOption IncludeSource (false, 'I', "include-source", "Automatically install source for every package installed");
82306ac2
BD
48
49// ---------------------------------------------------------------------------
50// implements class PrereqPage
51// ---------------------------------------------------------------------------
52
53PrereqPage::PrereqPage ()
54{
55 sizeProcessor.AddControlInfo (PrereqControlsInfo);
157dc2b8 56}
82306ac2
BD
57
58bool
59PrereqPage::Create ()
60{
61 return PropertyPage::Create (IDD_PREREQ);
62}
63
64void
65PrereqPage::OnInit ()
66{
67 // start with the checkbox set
68 CheckDlgButton (GetHWND (), IDC_PREREQ_CHECK, BST_CHECKED);
157dc2b8 69
82306ac2
BD
70 // set the edit-area to a larger font
71 SetDlgItemFont(IDC_PREREQ_EDIT, "MS Shell Dlg", 10);
72}
73
74void
75PrereqPage::OnActivate()
76{
77 // if we have gotten this far, then PrereqChecker has already run isMet
1d553f34 78 // and found that there were problems; so we can just call
82306ac2 79 // getUnmetString to format the results and display it
157dc2b8 80
08678720 81 std::string s;
82306ac2
BD
82 PrereqChecker p;
83 p.getUnmetString (s);
84 SetDlgItemText (GetHWND (), IDC_PREREQ_EDIT, s.c_str ());
85
86 SetFocus (GetDlgItem (IDC_PREREQ_CHECK));
87}
88
89long
90PrereqPage::OnNext ()
91{
92 HWND h = GetHWND ();
93
94 if (!IsDlgButtonChecked (h, IDC_PREREQ_CHECK))
95 {
1d553f34 96 return -1;
82306ac2 97 }
19cd8e05
JT
98
99 return whatNext();
100}
101
102long
103PrereqPage::whatNext ()
104{
7cc4d95e 105 if (source == IDC_SOURCE_LOCALDIR)
82306ac2
BD
106 {
107 // Next, install
108 Progress.SetActivateTask (WM_APP_START_INSTALL);
109 }
110 else
111 {
112 // Next, start download from internet
113 Progress.SetActivateTask (WM_APP_START_DOWNLOAD);
114 }
115 return IDD_INSTATUS;
116}
117
118long
119PrereqPage::OnBack ()
120{
121 return IDD_CHOOSE;
122}
123
19cd8e05
JT
124long
125PrereqPage::OnUnattended ()
126{
127 // in chooser-only mode, show this page so the user can choose to fix dependency problems or not
128 if (unattended_mode == chooseronly)
129 return -1;
130
19cd8e05
JT
131 return whatNext();
132}
82306ac2 133
1d553f34
JT
134bool
135PrereqPage::OnMessageCmd (int id, HWND hwndctl, UINT code)
136{
137 if ((code == BN_CLICKED) && (id == IDC_PREREQ_CHECK))
138 {
139 GetOwner ()->SetButtons (PSWIZB_BACK | (IsButtonChecked (id) ? PSWIZB_NEXT : 0));
140 return true;
141 }
142
143 return false;
144}
145
82306ac2
BD
146// ---------------------------------------------------------------------------
147// implements class PrereqChecker
148// ---------------------------------------------------------------------------
149
150// instantiate the static members
1d553f34
JT
151bool PrereqChecker::upgrade;
152bool PrereqChecker::use_test_packages;
d7dcbc6f 153
82306ac2
BD
154bool
155PrereqChecker::isMet ()
156{
157 packagedb db;
82306ac2 158
1d553f34 159 Progress.SetText1 ("Solving dependencies...");
ad20ac46
JT
160 Progress.SetText2 ("");
161 Progress.SetText3 ("");
162
1d553f34
JT
163 // go through all packages, adding changed ones to the solver task list
164 SolverTasks q;
c7c6e034 165
263157cb 166 for (packagedb::packagecollection::iterator p = db.packages.begin ();
c7c6e034
AK
167 p != db.packages.end (); ++p)
168 {
1d553f34 169 packagemeta *pkg = p->second;
c7c6e034 170
1d553f34
JT
171 // decode UI state to action
172 // skip and keep don't change dependency solution
173 if (pkg->installed != pkg->desired)
82306ac2 174 {
1d553f34
JT
175 if (pkg->desired)
176 q.add(pkg->desired, SolverTasks::taskInstall); // install/upgrade
d7dcbc6f 177 else
1d553f34 178 q.add(pkg->installed, SolverTasks::taskUninstall); // uninstall
82306ac2 179 }
1d553f34
JT
180 else
181 if (pkg->picked())
182 q.add(pkg->installed, SolverTasks::taskReinstall); // reinstall
82306ac2 183
1d553f34
JT
184 // only install action makes sense for source packages
185 if (pkg->srcpicked())
82306ac2 186 {
1d553f34
JT
187 if (pkg->desired)
188 q.add(pkg->desired.sourcePackage(), SolverTasks::taskInstall);
189 else
190 q.add(pkg->installed.sourcePackage(), SolverTasks::taskInstall);
82306ac2 191 }
82306ac2 192 }
1d553f34
JT
193
194 // apply solver to those tasks and the chooser global state (keep, curr, test)
195 return db.solution.update(q, upgrade, use_test_packages, IncludeSource);
82306ac2
BD
196}
197
1d553f34 198/* Formats problems and solutions as a string for display to the user. */
82306ac2 199void
1d553f34 200PrereqChecker::getUnmetString (std::string &s)
82306ac2
BD
201{
202 packagedb db;
1d553f34 203 s = db.solution.report();
82306ac2 204
1d553f34
JT
205 //
206 size_t pos = 0;
207 while ((pos = s.find("\n", pos)) != std::string::npos)
82306ac2 208 {
1d553f34
JT
209 s.replace(pos, 1, "\r\n");
210 pos += 2;
82306ac2
BD
211 }
212}
ad20ac46
JT
213
214// ---------------------------------------------------------------------------
215// progress page glue
216// ---------------------------------------------------------------------------
217
218static int
219do_prereq_check_thread(HINSTANCE h, HWND owner)
220{
221 PrereqChecker p;
222 int retval;
223
224 if (p.isMet ())
225 {
7cc4d95e 226 if (source == IDC_SOURCE_LOCALDIR)
ad20ac46
JT
227 Progress.SetActivateTask (WM_APP_START_INSTALL); // install
228 else
229 Progress.SetActivateTask (WM_APP_START_DOWNLOAD); // start download
230 retval = IDD_INSTATUS;
231 }
232 else
233 {
234 // rut-roh, some required things are not selected
235 retval = IDD_PREREQ;
236 }
237
238 return retval;
239}
240
241static DWORD WINAPI
242do_prereq_check_reflector (void *p)
243{
244 HANDLE *context;
245 context = (HANDLE *) p;
246
247 try
248 {
249 int next_dialog = do_prereq_check_thread ((HINSTANCE) context[0], (HWND) context[1]);
250
251 // Tell the progress page that we're done prereq checking
252 Progress.PostMessageNow (WM_APP_PREREQ_CHECK_THREAD_COMPLETE, 0, next_dialog);
253 }
703f1a44 254 TOPLEVEL_CATCH((HWND) context[1], "prereq_check");
ad20ac46
JT
255
256 ExitThread(0);
257}
258
259static HANDLE context[2];
260
261void
262do_prereq_check (HINSTANCE h, HWND owner)
263{
264 context[0] = h;
265 context[1] = owner;
266
267 DWORD threadID;
268 CreateThread (NULL, 0, do_prereq_check_reflector, context, 0, &threadID);
269}
This page took 0.089164 seconds and 5 git commands to generate.