Move PrereqChecker.isMet() call out of ChooserPage::OnNext() to a separate stage, so we can put the package chooser page away and indicate progress via the threebar status page.
2010-11-19 Jon TURNEY <[email protected]> * choose.cc (OnNext): Remove PrereqChecker call, instead use new WM_APP_PREREQ_CHECK state of Progress dialog. * threebar.h (WM_APP_PREREQ_CHECK) (WM_APP_PREREQ_CHECK_THREAD_COMPLETE): Add new messages. * threebar.cc (OnActivate, OnMessageApp): Use single bar mode for WM_APP_PREREQ_CHECK state. Handle new messages. * dialog.h (do_prereq_check_thread): Add prototype. * prereq.cc (isMet, do_prereq_check_thread) (do_prereq_check_reflector, do_prereq_check): Add progress reporting during isMet, and thread containing moved PrereqChecker code. Signed-off-by: Jon TURNEY <[email protected]> --- choose.cc | 19 ++------------- dialog.h | 1 + prereq.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ threebar.cc | 12 +++++++++ threebar.h | 2 + 5 files changed, 90 insertions(+), 16 deletions(-) diff --git a/choose.cc b/choose.cc index f0c6f64..59654a8 100644 --- a/choose.cc +++ b/choose.cc @@ -291,23 +291,10 @@ ChooserPage::OnNext () logResults(); #endif - PrereqChecker p; - long retval; - if (p.isMet ()) - { - if (source == IDC_SOURCE_CWD) - Progress.SetActivateTask (WM_APP_START_INSTALL); // install - else - Progress.SetActivateTask (WM_APP_START_DOWNLOAD); // start download - retval = IDD_INSTATUS; - } - else - { - // rut-roh, some required things are not selected - retval = IDD_PREREQ; - } PlaceDialog (false); - return retval; + Progress.SetActivateTask (WM_APP_PREREQ_CHECK); + + return IDD_INSTATUS; } long diff --git a/dialog.h b/dialog.h index 8883a6d..0c94238 100644 --- a/dialog.h +++ b/dialog.h @@ -38,6 +38,7 @@ bool do_fromcwd(HINSTANCE _h, HWND owner); D (do_ini); D (do_install); D (do_postinstall); +D (do_prereq_check); #undef D diff --git a/prereq.cc b/prereq.cc index f7302d9..a049630 100644 --- a/prereq.cc +++ b/prereq.cc @@ -38,6 +38,7 @@ static const char *cvsid = #include "package_db.h" #include "package_meta.h" #include "msg.h" +#include "Exception.h" // Sizing information. static ControlAdjuster::ControlInfo PrereqControlsInfo[] = { @@ -152,6 +153,10 @@ PrereqChecker::isMet () { packagedb db; + Progress.SetText1 ("Checking prerequisites..."); + Progress.SetText2 (""); + Progress.SetText3 (""); + // unmet is static - clear it each time this is called unmet.clear (); @@ -166,6 +171,9 @@ PrereqChecker::isMet () todo.push (*p); } + int max = todo.size(); + int pos = 0; + // churn through the work list while (!todo.empty ()) { @@ -173,6 +181,13 @@ PrereqChecker::isMet () packagemeta *pack = todo.front (); todo.pop (); + pos++; + Progress.SetText2 (pack->name.c_str()); + static char buf[100]; + sprintf(buf, "%d %% (%d/%d)", pos * 100 / max, pos, max); + Progress.SetText3(buf); + Progress.SetBar1(pos, max); + // Fetch the dependencies of the package. This assumes that the // dependencies of the prev, curr, and exp versions are all the same. vector <vector <PackageSpecification *> *> *deps = pack->curr.depends (); @@ -261,3 +276,60 @@ PrereqChecker::selectMissing () } } } + +// --------------------------------------------------------------------------- +// progress page glue +// --------------------------------------------------------------------------- + +static int +do_prereq_check_thread(HINSTANCE h, HWND owner) +{ + PrereqChecker p; + int retval; + + if (p.isMet ()) + { + if (source == IDC_SOURCE_CWD) + Progress.SetActivateTask (WM_APP_START_INSTALL); // install + else + Progress.SetActivateTask (WM_APP_START_DOWNLOAD); // start download + retval = IDD_INSTATUS; + } + else + { + // rut-roh, some required things are not selected + retval = IDD_PREREQ; + } + + return retval; +} + +static DWORD WINAPI +do_prereq_check_reflector (void *p) +{ + HANDLE *context; + context = (HANDLE *) p; + + try + { + int next_dialog = do_prereq_check_thread ((HINSTANCE) context[0], (HWND) context[1]); + + // Tell the progress page that we're done prereq checking + Progress.PostMessage (WM_APP_PREREQ_CHECK_THREAD_COMPLETE, 0, next_dialog); + } + TOPLEVEL_CATCH("prereq_check"); + + ExitThread(0); +} + +static HANDLE context[2]; + +void +do_prereq_check (HINSTANCE h, HWND owner) +{ + context[0] = h; + context[1] = owner; + + DWORD threadID; + CreateThread (NULL, 0, do_prereq_check_reflector, context, 0, &threadID); +} diff --git a/threebar.cc b/threebar.cc index cbc8c08..10d2f18 100644 --- a/threebar.cc +++ b/threebar.cc @@ -147,6 +147,7 @@ ThreeBarProgressPage::OnActivate () { case WM_APP_START_SITE_INFO_DOWNLOAD: case WM_APP_START_SETUP_INI_DOWNLOAD: + case WM_APP_PREREQ_CHECK: // For these tasks, show only a single progress bar. EnableSingleBar (); break; @@ -164,6 +165,17 @@ ThreeBarProgressPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { + case WM_APP_PREREQ_CHECK: + { + // Start the prereq-check thread + do_prereq_check (GetInstance (), GetHWND ()); + break; + } + case WM_APP_PREREQ_CHECK_THREAD_COMPLETE: + { + GetOwner ()->SetActivePageByID (lParam); + break; + } case WM_APP_START_DOWNLOAD: { // Start the package download thread. diff --git a/threebar.h b/threebar.h index 3b73b71..225703a 100644 --- a/threebar.h +++ b/threebar.h @@ -34,6 +34,8 @@ // desktop.h: WM_APP_UNATTENDED_FINISH WM_APP+8 #define WM_APP_START_POSTINSTALL WM_APP+9 #define WM_APP_POSTINSTALL_THREAD_COMPLETE WM_APP+10 +#define WM_APP_PREREQ_CHECK WM_APP+11 +#define WM_APP_PREREQ_CHECK_THREAD_COMPLETE WM_APP+12 class ThreeBarProgressPage:public PropertyPage { -- 1.7.2.3
