From 82306ac25c04c5d7223522ff482420e451d6c7ef Mon Sep 17 00:00:00 2001 From: Brian Dessent Date: Sat, 21 May 2005 23:04:03 +0000 Subject: [PATCH] 2005-05-21 Brian Dessent * prereq.cc: New file. * prereq.h: Ditto. * tree-minus.bmp: Ditto. * tree-plus.bmp: Ditto. * Makefile.am: Add prereq.cc and prereq.h to build. * PickCategoryLine.cc (PickCategoryLine::paint): Add new parameter and refactor. Use bitmap for '+' and '-' indicators. Draw package lines column-wise for better drawing efficiency. (PickCategoryLine::click): Use previously calculated x value. * PickCategoryLine.h (PickCategoryLine::paint): Update prototype. Add 'spin_x' member. * PickLine.h (PickLine:paint): Update prototype. * PickPackageLine.cc (PickPackageLine::DrawCheck): Remove. (PickPackageLine::DrawIcon): New function. (PickPackageLine::paint): Add parameter. Refactor completely for more efficient painting. * PickPackageLine.h (PickPackageLine::DrawIcon): Add prototype. (PickPackageLine::paint): Update prototype. (PickPackageLine::DrawCheck): Remove. * PickView.cc (pkg_headers): Remove unused 'slen' field, add new 'needs_clip' field to signify if clipping is necessary for this column. (PickView::note_width): Fold long line. Refactor slightly for simplicity. (PickView::set_view_mode): Remove. (PickView::cycleViewMode): New function. (PickView::setViewMode): Refactor completely. Incorporate functionality of clear_view() here instead. Simplify package selection into a single 'for' loop rather than repeating code for each type. (isObsolete): New function, with second overloaded version. (PickView::setObsolete): New function. (PickView::insert_pkg): Do not show obsolete packages. Move declaration of 'db' lower. Fix whitespace. (PickView::insert_category): Do not show obsolete packages. (PickView::clear_view): Remove. Moved logic into 'setViewMode'. (PickView::scroll): Add additional parameter 'howmany' with default value of 1. Scroll by 'howmany' lines for SB_LINEDOWN and SB_LINEUP. (NUM_CATEGORY_COL_WIDTH): Define. (PickView::init_headers): Fix whitespace. Add comments. Ignore obsolete packages in width calculations. Add functionality to size 'Category' column so that at least NUM_CATEGORY_COL_WIDTH categories are displayed for every package. Ensure that 'new_col' takes into account all possible labels. (PickView::PickView): Initialize showObsolete to false. (PickView::init): Remove unused bitmap bm_rtarrow. Add new bitmaps bm_treeplus and bm_treeminus. Use a macro for better readability. Fix whitespace formatting. Remove header computation from here, call refresh() instead. (PickView::registerWindowClass): Remove unnecessary background brush. (PickView::WindowProc): Add support for WM_MOUSEWHEEL message processing. Fix indentation. Reformat for readability. (PickView::paint): Get the update region before calling BeginPaint. Fill the update region with the default colors. Do not do clipping here. Pass update region to the PickLine paint function instead. Free the update region when finished. (PickView::Create): Fix indentation. (PickView::defaultTrust): Ditto. (PickView::refresh): Add column recalculation logic here. * PickView.h: Fix indentation. (RTARROW_WIDTH): Remove unused define. (NEW_COL_SIZE_SLOP): Ditto. (TREE_INDENT): Define. (PickView::get_view_mode): Remove. (PickView::set_view_mode): Rename to setViewMode for consistency. (PickView::cycleViewMode): Add new function. (PickView::setObsolete): Ditto. (PickView::clear_view): Remove. (PickView::bm_treeplus): Define new member. (PickView::bm_treeminus): Ditto. (PickView::scroll): Add parameter. (PickView::Header::slen): Remove unused member. (PickView::Header::needs_clip): Define new member. (PickView::showObsolete): Ditto. (isObsolete): Add prototype, and for overloaded version as well. * choose.cc: Add include. (ChooserControlsInfo): Allow new checkbox to be resized. (ChooserPage::OnInit): Start dialog with 'Hide obsolete' checked. (ChooserPage::OnNext): Call the dependency checker, act accordingly. (ChooserPage::changeTrust): Notify dependency checker of current trust level when it changes. (ChooserPage::OnMessageCmd): Just call cycleViewMode instead when changing the view. Update the chooser when the user toggles the 'hide obsolete' checkbox. (ChooserPage::OnMouseWheel): New function. Pass mouse wheel message on to chooser. * choose.h (OnMouseWheel): Add prototype. * main.cc: Add include. (main): Define and initialize the PrereqPage object. Add it into the property sheet list. * PropPage.cc (PropertyPage::DialogProc): Add support for WM_MOUSEWHEEL message processing in derived classes. (PropertyPage::OnMouseWheel): New function. * PropPage.h (PropertyPage::OnMouseWheel): Add prototype. * res.rc (IDD_LOCAL_DIR): Shorten edit box so that pushbutton is not crowded. (IDD_SITE): Provide static text with an ID so that it can be resized properly. Move pushbutton slightly to right so that it doesn't crowd edit box. (IDD_SPLASH): Change copyright displayed on spash screen to be generic since the actual list of contributors is long. (IDD_CHOOSE): Add checkbox. Resize other controls to accomodate. (IDD_PREREQ): New dialog. (SPIN): Delete duplicated bitmap resource. (IDB_RTARROW): Remove unused bitmap resource. (IDB_TREE_PLUS): Add. (IDB_TREE_MINUS): Ditto. (IDS_TRUSTPREV_TOOLTIP): Revise wording to be more concise. (IDS_TRUSTCURR_TOOLTIP): Ditto. (IDS_TRUSTEXP_TOOLTIP): Ditto. (IDS_VIEWBUTTON_TOOLTIP): Ditto. * resource.h (IDD_PREREQ): Define. (IDB_RTARROW): Remove. (IDB_TREE_PLUS): Add, and renumber. (IDB_TREE_MINUS): Ditto. (IDC_SITE_USERURL): Define. (IDC_CHOOSE_HIDE): Ditto. (IDC_PREREQ_TEXT): Ditto. (IDC_PREREQ_EDIT): Ditto. (IDC_PREREQ_CHECK): Ditto. * site.cc (SiteControlsInfo): Ensure that 'User URL' static text is properly resized. --- ChangeLog | 123 ++++++++++ Makefile.am | 2 + PickCategoryLine.cc | 84 +++++-- PickCategoryLine.h | 3 +- PickLine.h | 2 +- PickPackageLine.cc | 185 +++++---------- PickPackageLine.h | 5 +- PickView.cc | 562 +++++++++++++++++++++++++------------------- PickView.h | 27 +-- choose.cc | 38 ++- choose.h | 2 + main.cc | 4 + prereq.cc | 249 ++++++++++++++++++++ prereq.h | 55 +++++ proppage.cc | 14 ++ proppage.h | 2 + res.rc | 73 +++--- resource.h | 15 +- site.cc | 1 + tree-minus.bmp | Bin 0 -> 106 bytes tree-plus.bmp | Bin 0 -> 106 bytes 21 files changed, 1002 insertions(+), 444 deletions(-) create mode 100644 prereq.cc create mode 100644 prereq.h create mode 100755 tree-minus.bmp create mode 100755 tree-plus.bmp diff --git a/ChangeLog b/ChangeLog index 114660ca..8b86d87c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,126 @@ +2005-05-21 Brian Dessent + + * prereq.cc: New file. + * prereq.h: Ditto. + * tree-minus.bmp: Ditto. + * tree-plus.bmp: Ditto. + * Makefile.am: Add prereq.cc and prereq.h to build. + * PickCategoryLine.cc (PickCategoryLine::paint): Add new parameter and + refactor. Use bitmap for '+' and '-' indicators. Draw package lines + column-wise for better drawing efficiency. + (PickCategoryLine::click): Use previously calculated x value. + * PickCategoryLine.h (PickCategoryLine::paint): Update prototype. Add + 'spin_x' member. + * PickLine.h (PickLine:paint): Update prototype. + * PickPackageLine.cc (PickPackageLine::DrawCheck): Remove. + (PickPackageLine::DrawIcon): New function. + (PickPackageLine::paint): Add parameter. Refactor completely for more + efficient painting. + * PickPackageLine.h (PickPackageLine::DrawIcon): Add prototype. + (PickPackageLine::paint): Update prototype. + (PickPackageLine::DrawCheck): Remove. + * PickView.cc (pkg_headers): Remove unused 'slen' field, add new + 'needs_clip' field to signify if clipping is necessary for this column. + (PickView::note_width): Fold long line. Refactor slightly for + simplicity. + (PickView::set_view_mode): Remove. + (PickView::cycleViewMode): New function. + (PickView::setViewMode): Refactor completely. Incorporate functionality + of clear_view() here instead. Simplify package selection into a single + 'for' loop rather than repeating code for each type. + (isObsolete): New function, with second overloaded version. + (PickView::setObsolete): New function. + (PickView::insert_pkg): Do not show obsolete packages. Move + declaration of 'db' lower. Fix whitespace. + (PickView::insert_category): Do not show obsolete packages. + (PickView::clear_view): Remove. Moved logic into 'setViewMode'. + (PickView::scroll): Add additional parameter 'howmany' with default + value of 1. Scroll by 'howmany' lines for SB_LINEDOWN and SB_LINEUP. + (NUM_CATEGORY_COL_WIDTH): Define. + (PickView::init_headers): Fix whitespace. Add comments. Ignore + obsolete packages in width calculations. Add functionality to size + 'Category' column so that at least NUM_CATEGORY_COL_WIDTH categories + are displayed for every package. Ensure that 'new_col' takes into + account all possible labels. + (PickView::PickView): Initialize showObsolete to false. + (PickView::init): Remove unused bitmap bm_rtarrow. Add new bitmaps + bm_treeplus and bm_treeminus. Use a macro for better readability. + Fix whitespace formatting. Remove header computation from here, call + refresh() instead. + (PickView::registerWindowClass): Remove unnecessary background brush. + (PickView::WindowProc): Add support for WM_MOUSEWHEEL message + processing. Fix indentation. Reformat for readability. + (PickView::paint): Get the update region before calling BeginPaint. + Fill the update region with the default colors. Do not do clipping + here. Pass update region to the PickLine paint function instead. + Free the update region when finished. + (PickView::Create): Fix indentation. + (PickView::defaultTrust): Ditto. + (PickView::refresh): Add column recalculation logic here. + * PickView.h: Fix indentation. + (RTARROW_WIDTH): Remove unused define. + (NEW_COL_SIZE_SLOP): Ditto. + (TREE_INDENT): Define. + (PickView::get_view_mode): Remove. + (PickView::set_view_mode): Rename to setViewMode for consistency. + (PickView::cycleViewMode): Add new function. + (PickView::setObsolete): Ditto. + (PickView::clear_view): Remove. + (PickView::bm_treeplus): Define new member. + (PickView::bm_treeminus): Ditto. + (PickView::scroll): Add parameter. + (PickView::Header::slen): Remove unused member. + (PickView::Header::needs_clip): Define new member. + (PickView::showObsolete): Ditto. + (isObsolete): Add prototype, and for overloaded version as well. + * choose.cc: Add include. + (ChooserControlsInfo): Allow new checkbox to be resized. + (ChooserPage::OnInit): Start dialog with 'Hide obsolete' checked. + (ChooserPage::OnNext): Call the dependency checker, act accordingly. + (ChooserPage::changeTrust): Notify dependency checker of current trust + level when it changes. + (ChooserPage::OnMessageCmd): Just call cycleViewMode instead when + changing the view. Update the chooser when the user toggles the + 'hide obsolete' checkbox. + (ChooserPage::OnMouseWheel): New function. Pass mouse wheel message + on to chooser. + * choose.h (OnMouseWheel): Add prototype. + * main.cc: Add include. + (main): Define and initialize the PrereqPage object. Add it into + the property sheet list. + * PropPage.cc (PropertyPage::DialogProc): Add support for WM_MOUSEWHEEL + message processing in derived classes. + (PropertyPage::OnMouseWheel): New function. + * PropPage.h (PropertyPage::OnMouseWheel): Add prototype. + * res.rc (IDD_LOCAL_DIR): Shorten edit box so that pushbutton is not + crowded. + (IDD_SITE): Provide static text with an ID so that it can be resized + properly. Move pushbutton slightly to right so that it doesn't crowd + edit box. + (IDD_SPLASH): Change copyright displayed on spash screen to be generic + since the actual list of contributors is long. + (IDD_CHOOSE): Add checkbox. Resize other controls to accomodate. + (IDD_PREREQ): New dialog. + (SPIN): Delete duplicated bitmap resource. + (IDB_RTARROW): Remove unused bitmap resource. + (IDB_TREE_PLUS): Add. + (IDB_TREE_MINUS): Ditto. + (IDS_TRUSTPREV_TOOLTIP): Revise wording to be more concise. + (IDS_TRUSTCURR_TOOLTIP): Ditto. + (IDS_TRUSTEXP_TOOLTIP): Ditto. + (IDS_VIEWBUTTON_TOOLTIP): Ditto. + * resource.h (IDD_PREREQ): Define. + (IDB_RTARROW): Remove. + (IDB_TREE_PLUS): Add, and renumber. + (IDB_TREE_MINUS): Ditto. + (IDC_SITE_USERURL): Define. + (IDC_CHOOSE_HIDE): Ditto. + (IDC_PREREQ_TEXT): Ditto. + (IDC_PREREQ_EDIT): Ditto. + (IDC_PREREQ_CHECK): Ditto. + * site.cc (SiteControlsInfo): Ensure that 'User URL' static text is + properly resized. + 2005-05-14 Max Bowsher "Type" field of packageversions was not even being filled in. Fix. diff --git a/Makefile.am b/Makefile.am index 293956b5..5fcffe3f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -232,6 +232,8 @@ setup_SOURCES = \ PickView.cc \ PickView.h \ postinstall.cc \ + prereq.cc \ + prereq.h \ proppage.cc \ proppage.h \ propsheet.cc \ diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc index 4a3bacc7..b5472f73 100644 --- a/PickCategoryLine.cc +++ b/PickCategoryLine.cc @@ -29,41 +29,80 @@ PickCategoryLine::empty (void) } void -PickCategoryLine::paint (HDC hdc, int x, int y, int row, int show_cat) +PickCategoryLine::paint (HDC hdc, HRGN hUpdRgn, int x, int y, int row, int show_cat) { int r = y + row * theView.row_height; if (show_label) { - int by = r + theView.tm.tmHeight - 11; - String temp=(String("+ ") +cat.first); - TextOut (hdc, - x + theView.headers[theView.cat_col].x + HMARGIN / 2 + - depth * 8, r, temp.c_str(), temp.size()); + int x2 = x + theView.headers[theView.cat_col].x + HMARGIN / 2 + depth * TREE_INDENT; + int by = r + (theView.tm.tmHeight / 2) - 5; + + // draw the '+' or '-' box + SelectObject (theView.bitmap_dc, + (collapsed ? theView.bm_treeplus : theView.bm_treeminus)); + BitBlt (hdc, x2, by, 11, 11, theView.bitmap_dc, 0, 0, SRCCOPY); + + // draw the category name + TextOut (hdc, x2 + 11 + ICON_MARGIN, r, cat.first.c_str(), cat.first.size()); if (!labellength) { SIZE s; - GetTextExtentPoint32 (hdc, temp.c_str(), temp.size(), &s); + GetTextExtentPoint32 (hdc, cat.first.c_str(), cat.first.size(), &s); labellength = s.cx; } + + // draw the 'spin' glyph SelectObject (theView.bitmap_dc, theView.bm_spin); - BitBlt (hdc, - x + theView.headers[theView.cat_col].x + - labellength + depth * 8 + - ICON_MARGIN + - HMARGIN / 2, by, 11, 11, theView.bitmap_dc, 0, 0, SRCCOPY); - TextOut (hdc, - x + theView.headers[theView.cat_col].x + - labellength + depth * 8 + - ICON_MARGIN + SPIN_WIDTH + - HMARGIN, r, current_default.caption (), strlen (current_default.caption ())); + spin_x = x2 + 11 + ICON_MARGIN + labellength + ICON_MARGIN; + BitBlt (hdc, spin_x, by, 11, 11, theView.bitmap_dc, 0, 0, SRCCOPY); + + // draw the caption ('Default', 'Install', etc) + TextOut (hdc, spin_x + SPIN_WIDTH + ICON_MARGIN, r, + current_default.caption (), strlen (current_default.caption ())); + row++; } if (collapsed) return; - int accum_row = row + (show_label ? 1 : 0); - for (size_t n = 0; n < bucket.size (); ++n) + + // are the siblings containers? + if (bucket.size () && bucket[0]->IsContainer ()) + { + for (size_t n = 0; n < bucket.size (); n++) + { + bucket[n]->paint (hdc, hUpdRgn, x, y, row, show_cat); + row += bucket[n]->itemcount (); + } + } + else { - bucket[n]->paint (hdc, x, y, accum_row, show_cat); - accum_row += bucket[n]->itemcount (); + // calculate the maximum y value we expect for this group of lines + int max_y = y + (row + bucket.size ()) * theView.row_height; + + // paint all contained rows, columnwise + for (int i = 0; theView.headers[i].text; i++) + { + RECT r; + r.left = x + theView.headers[i].x; + r.right = r.left + theView.headers[i].width; + + // set up a clipping mask if necessary + if (theView.headers[i].needs_clip) + IntersectClipRect (hdc, r.left, y, r.right, max_y); + + // draw each row in this column + for (unsigned int n = 0; n < bucket.size (); n++) + { + // test for visibility + r.top = y + ((row + n) * theView.row_height); + r.bottom = r.top + theView.row_height; + if (RectVisible (hdc, &r) != 0) + bucket[n]->paint (hdc, hUpdRgn, (int)r.left, (int)r.top, i, show_cat); + } + + // restore original clipping area + if (theView.headers[i].needs_clip) + SelectClipRgn (hdc, hUpdRgn); + } } } @@ -72,8 +111,7 @@ PickCategoryLine::click (int const myrow, int const ClickedRow, int const x) { if (myrow == ClickedRow && show_label) { - if ((size_t) x >= theView.headers[theView.cat_col].x + - labellength + depth * 8 + ICON_MARGIN + HMARGIN / 2) + if ((size_t) x >= spin_x) { ++current_default; diff --git a/PickCategoryLine.h b/PickCategoryLine.h index d72481dc..dcffbac4 100644 --- a/PickCategoryLine.h +++ b/PickCategoryLine.h @@ -52,7 +52,7 @@ public: if (!show_label) collapsed = false; } - virtual void paint (HDC hdc, int x, int y, int row, int show_cat); + virtual void paint (HDC hdc, HRGN hUpdRgn, int x, int y, int row, int show_cat); virtual int click (int const myrow, int const ClickedRow, int const x); virtual int itemcount () const { @@ -80,6 +80,7 @@ private: bool collapsed; bool show_label; size_t labellength; + size_t spin_x; // x-coord where the spin button starts size_t depth; PickCategoryLine (PickCategoryLine const &); PickCategoryLine & operator= (PickCategoryLine const &); diff --git a/PickLine.h b/PickLine.h index db2f1087..f4df2ca5 100644 --- a/PickLine.h +++ b/PickLine.h @@ -22,7 +22,7 @@ class PickLine { public: - virtual void paint (HDC hdc, int x, int y, int row, int show_cat) = 0; + virtual void paint (HDC hdc, HRGN hUpdRgn, int x, int y, int col_num, int show_cat) = 0; virtual int click (int const myrow, int const ClickedRow, int const x) = 0; virtual int set_action (packagemeta::_actions) = 0; virtual int itemcount () const = 0; diff --git a/PickPackageLine.cc b/PickPackageLine.cc index 08dd24a3..48066c91 100644 --- a/PickPackageLine.cc +++ b/PickPackageLine.cc @@ -19,145 +19,82 @@ #include "package_version.h" void -PickPackageLine::DrawCheck (int const checked, HDC hdc, int const column, HRGN const clip, int const x, int const by) +PickPackageLine::DrawIcon (HDC hdc, int x, int y, HANDLE hIcon) { - HANDLE check_bm; - if (checked == 0) - check_bm = theView.bm_checkna; - else if (checked == 1) - check_bm = theView.bm_checkyes; - else if (checked == 2) - check_bm = theView.bm_checkno; - else - return; - - SelectObject (theView.bitmap_dc, check_bm); - IntersectClipRect (hdc, x + theView.headers[column].x, by, - x + theView.headers[column].x + - theView.headers[column].width, by + 11); - BitBlt (hdc, x + theView.headers[column].x + HMARGIN / 2, by, 11, - 11, theView.bitmap_dc, 0, 0, SRCCOPY); - SelectClipRgn (hdc, clip); + SelectObject (theView.bitmap_dc, hIcon); + BitBlt (hdc, x, y, 11, 11, theView.bitmap_dc, 0, 0, SRCCOPY); } void -PickPackageLine::paint (HDC hdc, int x, int y, int row, int show_cat) +PickPackageLine::paint (HDC hdc, HRGN unused, int x, int y, int col_num, int show_cat) { - int r = y + row * theView.row_height; - int rb = r + theView.tm.tmHeight; + int rb = y + theView.tm.tmHeight; int by = rb - 11; // top of box images - int oldDC = SaveDC (hdc); - if (!oldDC) - return; - HRGN oldClip = CreateRectRgn (0, 0, 0, 0); - if (GetRandomRgn (hdc, oldClip, SYSRGN) == -1) + String s; + + if (col_num == theView.current_col && pkg.installed) { - RestoreDC (hdc, oldDC); - return; + TextOut (hdc, x + HMARGIN/2, y, pkg.installed.Canonical_version ().c_str(), + pkg.installed.Canonical_version ().size()); + } + else if (col_num == theView.new_col) + { + // TextOut (hdc, x + HMARGIN/2 + NEW_COL_SIZE_SLOP, y, s.c_str(), s.size()); + // DrawIcon (hdc, x + HMARGIN/2 + ICON_MARGIN/2 + RTARROW_WIDTH, by, theView.bm_spin); + TextOut (hdc, x + HMARGIN/2 + ICON_MARGIN/2 + SPIN_WIDTH , y, + pkg.action_caption ().c_str(), pkg.action_caption ().size()); + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_spin); } - HRGN oldClip2; - if (IsWindowsNT()) { - - unsigned int regionsize = GetRegionData (oldClip, 0, 0); - LPRGNDATA oldClipData = (LPRGNDATA) malloc (regionsize); - if (GetRegionData (oldClip, regionsize, oldClipData) > regionsize) + else if (col_num == theView.bintick_col) { - RestoreDC (hdc, oldDC); - DeleteObject (oldClip); - return; + if (/* uninstall or skip */ !pkg.desired || + /* current version */ pkg.desired == pkg.installed || + /* no source */ !pkg.desired.accessible()) + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna); + else if (pkg.desired.picked()) + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes); + else + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno); } - for (unsigned int n = 0; n < oldClipData->rdh.nCount; n++) - for (unsigned int t = 0; t < 2; t++) - ScreenToClient (WindowFromDC (hdc), - &((POINT *) oldClipData->Buffer)[t + n * 2]); + else if (col_num == theView.srctick_col) + { + if ( /* uninstall */ !pkg.desired || - oldClip2 = ExtCreateRegion (NULL, regionsize, oldClipData); - } - else - oldClip2 = oldClip; - - SelectClipRgn (hdc, oldClip2); - if (pkg.installed) +#if 0 + /* note: I'm not sure what the logic here is. With this following + check enabled, clicking on the "source" box for a package that + is already installed results it in showing "n/a", instead of a + cross-box. That seems very unintuitive, it should show a cross- + box to indicate that the source is going to be downloaded and + unpacked. Disabling this, but leaving the code as reference + in case there is some reason I'm missing for having it. --b.d. */ + /* source only */ (!pkg.desired.picked() + && pkg.desired.sourcePackage().picked() && pkg.desired == pkg.installed) || +#endif + /* when no source mirror available */ + !pkg.desired.sourcePackage().accessible()) + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna); + else if (pkg.desired.sourcePackage().picked()) + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes); + else + DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno); + } + else if (col_num == theView.cat_col) { - IntersectClipRect (hdc, x + theView.headers[theView.current_col].x, - r, - x + theView.headers[theView.current_col].x + - theView.headers[theView.current_col].width, rb); - TextOut (hdc, - x + theView.headers[theView.current_col].x + HMARGIN / 2, r, - pkg.installed.Canonical_version ().c_str(), - pkg.installed.Canonical_version ().size()); - SelectObject (theView.bitmap_dc, theView.bm_rtarrow); - BitBlt (hdc, x + theView.headers[theView.new_col].x + HMARGIN / 2, - by, 11, 11, theView.bitmap_dc, 0, 0, SRCCOPY); - SelectClipRgn (hdc, oldClip2); + /* shows "first" category - do we want to show any? */ + if (pkg.categories.size () && show_cat) + { + s = pkg.getReadableCategoryList(); + TextOut (hdc, x + HMARGIN / 2, y, s.c_str(), s.size()); + } } - - String s = pkg.action_caption (); - IntersectClipRect (hdc, x + theView.headers[theView.new_col].x, - r, - x + theView.headers[theView.new_col].x + - theView.headers[theView.new_col].width, rb); - TextOut (hdc, - x + theView.headers[theView.new_col].x + HMARGIN / 2 + - NEW_COL_SIZE_SLOP, r, s.c_str(), s.size()); - SelectObject (theView.bitmap_dc, theView.bm_spin); - BitBlt (hdc, - x + theView.headers[theView.new_col].x + ICON_MARGIN / 2 + - RTARROW_WIDTH + HMARGIN / 2, by, 11, 11, theView.bitmap_dc, 0, 0, - SRCCOPY); - SelectClipRgn (hdc, oldClip2); - - int checked; - - if (/* uninstall or skip */ !pkg.desired || - /* current version */ pkg.desired == pkg.installed || - /* no source */ !pkg.desired.accessible()) - checked = 0; - else if (pkg.desired.picked()) - checked = 1; - else - checked = 2; - - DrawCheck (checked, hdc, theView.bintick_col, oldClip2, x, by); - - if ( /* uninstall */ !pkg.desired || - /* source only */ (!pkg.desired.picked() - && pkg.desired.sourcePackage().picked() && pkg.desired == pkg.installed) || - /* when no source mirror available */ - !pkg.desired.sourcePackage().accessible()) - checked = 0; - else if (pkg.desired.sourcePackage().picked()) - checked = 1; - else - checked = 2; - - DrawCheck (checked, hdc, theView.srctick_col, oldClip2, x, by); - - /* shows "first" category - do we want to show any? */ - if (pkg.categories.size () && show_cat) + else if (col_num == theView.pkg_col) { - String catName = pkg.getReadableCategoryList(); - IntersectClipRect (hdc, x + theView.headers[theView.cat_col].x, r, - x + theView.headers[theView.cat_col].x + - theView.headers[theView.cat_col].width - HMARGIN / 2, rb); - TextOut (hdc, x + theView.headers[theView.cat_col].x + HMARGIN / 2, r, - catName.c_str(), - catName.size()); - SelectClipRgn (hdc, oldClip2); + s = pkg.name; + if (pkg.SDesc ().size()) + s += String(": ") + pkg.SDesc (); + TextOut (hdc, x + HMARGIN / 2, y, s.c_str(), s.size()); } - - s = pkg.name; - if (pkg.SDesc ().size()) - s += String(": ") + pkg.SDesc (); - IntersectClipRect (hdc, x + theView.headers[theView.pkg_col].x, r, - x + theView.headers[theView.pkg_col].x + - theView.headers[theView.pkg_col].width, rb); - TextOut (hdc, x + theView.headers[theView.pkg_col].x + HMARGIN / 2, r, s.c_str(), - s.size()); - DeleteObject (oldClip); - DeleteObject (oldClip2); - RestoreDC (hdc, oldDC); } int diff --git a/PickPackageLine.h b/PickPackageLine.h index f8537c8c..b1571e84 100644 --- a/PickPackageLine.h +++ b/PickPackageLine.h @@ -26,7 +26,8 @@ public: PickPackageLine (PickView &aView, packagemeta & apkg):PickLine (apkg.key), pkg (apkg), theView (aView) { }; - virtual void paint (HDC hdc, int x, int y, int row, int show_cat); + void DrawIcon (HDC hdc, int x, int y, HANDLE hIcon); + virtual void paint (HDC hdc, HRGN unused, int x, int y, int col_num, int show_cat); virtual int click (int const myrow, int const ClickedRow, int const x); virtual int itemcount () const { @@ -43,8 +44,6 @@ public: private: packagemeta & pkg; PickView & theView; - // XXX make checked an enum or tri-valued class of its own - void DrawCheck (int const checked, HDC hdc, int const column, HRGN const clip, int const x, int const by); }; #endif /* SETUP_PICKPACKAGELINE_H */ diff --git a/PickView.cc b/PickView.cc index d1dfdd85..6441e622 100644 --- a/PickView.cc +++ b/PickView.cc @@ -29,23 +29,23 @@ using namespace std; static PickView::Header pkg_headers[] = { - {"Current", 7, 0, 0}, - {"New", 3, 0, 0}, - {"Bin?", 4, 0, 0}, - {"Src?", 4, 0, 0}, - {"Categories", 10, 0, 0}, - {"Package", 7, 0, 0}, - {0, 0, 0, 0} + {"Current", 0, 0, true}, + {"New", 0, 0, true}, + {"Bin?", 0, 0, false}, + {"Src?", 0, 0, false}, + {"Categories", 0, 0, true}, + {"Package", 0, 0, true}, + {0, 0, 0, false} }; static PickView::Header cat_headers[] = { - {"Category", 8, 0, 0}, - {"Current", 7, 0, 0}, - {"New", 3, 0, 0}, - {"Bin?", 4, 0, 0}, - {"Src?", 4, 0, 0}, - {"Package", 7, 0, 0}, - {0, 0, 0, 0} + {"Category", 0, 0, true}, + {"Current", 0, 0, true}, + {"New", 0, 0, true}, + {"Bin?", 0, 0, false}, + {"Src?", 0, 0, false}, + {"Package", 0, 0, true}, + {0, 0, 0, false} }; // PickView:: views @@ -82,8 +82,6 @@ DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz) return index; } - - void PickView::set_headers () { @@ -126,81 +124,70 @@ PickView::set_headers () } void -PickView::note_width (PickView::Header *hdrs, HDC dc, String const &string, int addend, - int column) +PickView::note_width (PickView::Header *hdrs, HDC dc, String const &string, + int addend, int column) { - if (!string.size()) - { - if (hdrs[column].width < addend) - hdrs[column].width = addend; - return; - } - SIZE s; - GetTextExtentPoint32 (dc, string.c_str(), string.size(), &s); + SIZE s = { 0, 0 }; + + if (string.size()) + GetTextExtentPoint32 (dc, string.c_str(), string.size(), &s); if (hdrs[column].width < s.cx + addend) hdrs[column].width = s.cx + addend; } void -PickView::set_view_mode (PickView::views _mode) +PickView::cycleViewMode () { - view_mode = _mode; - set_headers (); + setViewMode (++view_mode); } void -PickView::setViewMode (PickView::views mode) +PickView::setViewMode (views mode) { - set_view_mode (mode); - - clear_view (); + view_mode = mode; + set_headers (); packagedb db; - if (get_view_mode () == PickView::views::Package) - { - for (vector ::iterator i = db.packages.begin (); - i != db.packages.end (); ++i) - { - packagemeta & pkg = **i; - if ((!pkg.desired && pkg.installed) - || (pkg.desired && (pkg.desired.picked () - || pkg.desired.sourcePackage().picked()))) - insert_pkg (pkg); - } - } - else if (get_view_mode () == PickView::views::PackageKeeps) - { - for (vector ::iterator i = db.packages.begin (); - i != db.packages.end (); ++i) - { - packagemeta & pkg = **i; - if (pkg.installed && pkg.desired && !pkg.desired.picked() - && !pkg.desired.sourcePackage().picked()) - insert_pkg (pkg); - } - } - else if (get_view_mode () == PickView::views::PackageSkips) + + contents.empty (); + if (view_mode == PickView::views::Category) { - for (vector ::iterator i = db.packages.begin (); - i != db.packages.end (); ++i) - { - packagemeta & pkg = **i; - if (!pkg.desired && !pkg.installed) - insert_pkg (pkg); - } + contents.ShowLabel (true); + /* start collapsed. TODO: make this a chooser flag */ + for (packagedb::categoriesType::iterator n = + packagedb::categories.begin(); n != packagedb::categories.end(); + ++n) + insert_category (&*n, CATEGORY_COLLAPSED); } - else if (get_view_mode () == PickView::views::PackageFull) + else { + contents.ShowLabel (false); + // iterate through every package for (vector ::iterator i = db.packages.begin (); - i != db.packages.end (); ++i) - insert_pkg (**i); - } - else if (get_view_mode () == PickView::views::Category) - { - /* start collapsed. TODO: make this a chooser flag */ - for (packagedb::categoriesType::iterator n - = packagedb::categories.begin(); - n != packagedb::categories.end(); ++n) - insert_category (&*n, CATEGORY_COLLAPSED); + i != db.packages.end (); ++i) + { + packagemeta & pkg = **i; + + if ( // "Full" : everything + (view_mode == PickView::views::PackageFull) + + // "Partial" : packages that are being added/removed/upgraded + || (view_mode == PickView::views::Package && + ((!pkg.desired && pkg.installed) || // uninstall + (pkg.desired && + (pkg.desired.picked () || // install bin + pkg.desired.sourcePackage ().picked ())))) // src + + // "Up to date" : installed packages that will not be changed + || (view_mode == PickView::views::PackageKeeps && + (pkg.installed && pkg.desired && !pkg.desired.picked () + && !pkg.desired.sourcePackage ().picked ())) + + // "Not installed" + || (view_mode == PickView::views::PackageSkips && + (!pkg.desired && !pkg.installed))) + + insert_pkg (pkg); + } } RECT r = GetClientRect (); @@ -248,9 +235,42 @@ PickView::views::caption () } } +/* meant to be called on packagemeta::categories */ +bool +isObsolete (set &categories) +{ + set ::const_iterator i; + + for (i = categories.begin (); i != categories.end (); ++i) + if (isObsolete (*i)) + return true; + return false; +} + +bool +isObsolete (const String &catname) +{ + if (catname.casecompare ("ZZZRemovedPackages") == 0 + || catname.casecompare ("_", 1) == 0) + return true; + return false; +} + +/* Sets the mode for showing/hiding obsolete junk packages. */ +void +PickView::setObsolete (bool doit) +{ + showObsolete = doit; + refresh (); +} + + void PickView::insert_pkg (packagemeta & pkg) { + if (!showObsolete && isObsolete (pkg.categories)) + return; + if (view_mode != views::Category) { PickLine & line = *new PickPackageLine (*this, pkg); @@ -261,13 +281,13 @@ PickView::insert_pkg (packagemeta & pkg) for (set ::const_iterator x = pkg.categories.begin (); x != pkg.categories.end (); ++x) { - packagedb db; // Special case - yuck if (x->casecompare ("All") == 0) continue; + packagedb db; PickCategoryLine & catline = - *new PickCategoryLine (*this,* db.categories.find (*x), 1); + *new PickCategoryLine (*this, *db.categories.find (*x), 1); PickLine & line = *new PickPackageLine(*this, pkg); catline.insert (line); contents.insert (catline); @@ -276,10 +296,11 @@ PickView::insert_pkg (packagemeta & pkg) } void -PickView::insert_category (Category * cat, bool collapsed) +PickView::insert_category (Category *cat, bool collapsed) { // Urk, special case - if (cat->first.casecompare ("All") == 0) + if (cat->first.casecompare ("All") == 0 || + (!showObsolete && isObsolete (cat->first))) return; PickCategoryLine & catline = *new PickCategoryLine (*this, *cat, 1, collapsed); for (vector ::iterator i = cat->second.begin (); @@ -291,21 +312,6 @@ PickView::insert_category (Category * cat, bool collapsed) contents.insert (catline); } -void -PickView::clear_view (void) -{ - contents.empty (); - if (view_mode == views::Unknown) - return; - if (view_mode == views::PackageFull || - view_mode == views::Package || - view_mode == views::PackageKeeps || - view_mode == views::PackageSkips) - contents.ShowLabel (false); - else if (view_mode == views::Category) - contents.ShowLabel (); -} - PickView::views& PickView::views::operator++ () { @@ -323,7 +329,7 @@ PickView::click (int row, int x) void -PickView::scroll (HWND hwnd, int which, int *var, int code) +PickView::scroll (HWND hwnd, int which, int *var, int code, int howmany = 1) { SCROLLINFO si; si.cbSize = sizeof (si); @@ -344,10 +350,10 @@ PickView::scroll (HWND hwnd, int which, int *var, int code) si.nPos = 0; break; case SB_LINEDOWN: - si.nPos += row_height; + si.nPos += (row_height * howmany); break; case SB_LINEUP: - si.nPos -= row_height; + si.nPos -= (row_height * howmany); break; case SB_PAGEDOWN: si.nPos += si.nPage * 9 / 10; @@ -392,6 +398,10 @@ PickView::scroll (HWND hwnd, int which, int *var, int code) UpdateWindow (hwnd); } +/* this means to make the 'category' column wide enough to fit the first 'n' + categories for each package. */ +#define NUM_CATEGORY_COL_WIDTH 2 + void PickView::init_headers (HDC dc) { @@ -403,36 +413,72 @@ PickView::init_headers (HDC dc) headers[i].x = 0; } - for (i = 0; headers[i].text; i++) - note_width (headers, dc, headers[i].text, HMARGIN, i); - /* src checkbox */ + // accomodate widths of the 'bin' and 'src' checkbox columns note_width (headers, dc, 0, HMARGIN + 11, bintick_col); note_width (headers, dc, 0, HMARGIN + 11, srctick_col); + + // accomodate the width of each category name packagedb db; for (packagedb::categoriesType::iterator n = packagedb::categories.begin(); n != packagedb::categories.end(); ++n) - note_width (headers, dc, String ("+ ")+n->first, HMARGIN, cat_col); + { + if (!showObsolete && isObsolete (n->first)) + continue; + note_width (headers, dc, n->first, HMARGIN, cat_col); + } + + /* For each package, accomodate the width of the installed version in the + current_col, the widths of all other versions in the new_col, and the + width of the sdesc for the pkg_col. Also, if this is not a Category + view, adjust the 'category' column so that the first NUM_CATEGORY_COL_WIDTH + categories from each package fits. */ for (vector ::iterator n = db.packages.begin (); n != db.packages.end (); ++n) { packagemeta & pkg = **n; + if (!showObsolete && isObsolete (pkg.categories)) + continue; if (pkg.installed) note_width (headers, dc, pkg.installed.Canonical_version (), HMARGIN, current_col); - for (set::iterator i=pkg.versions.begin(); - i != pkg.versions.end(); ++i) + for (set::iterator i = pkg.versions.begin (); + i != pkg.versions.end (); ++i) if (*i != pkg.installed) - note_width (headers, dc, - i->Canonical_version (), - NEW_COL_SIZE_SLOP + HMARGIN, new_col); + note_width (headers, dc, i->Canonical_version (), + HMARGIN + SPIN_WIDTH, new_col); String s = pkg.name; if (pkg.SDesc ().size()) s += String (": ") + pkg.SDesc (); note_width (headers, dc, s, HMARGIN, pkg_col); + + if (view_mode != PickView::views::Category && pkg.categories.size () > 2) + { + String compound_cat(""); + std::set::const_iterator cat; + size_t cnt; + + for (cnt = 0, cat = pkg.categories.begin (); + cnt < NUM_CATEGORY_COL_WIDTH && cat != pkg.categories.end (); + ++cat) + { + if (cat->casecompare ("All") == 0) + continue; + if (compound_cat.size ()) + compound_cat += ", "; + compound_cat += *cat; + cnt++; + } + note_width (headers, dc, compound_cat, HMARGIN, cat_col); + } } - note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP + HMARGIN, new_col); - note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP + HMARGIN, new_col); - + + // ensure that the new_col is wide enough for all the labels + const char *captions[] = { "Uninstall", "Skip", "Reinstall", "Retrieve", + "Source", "Keep", NULL }; + for (int i = 0; captions[i]; i++) + note_width (headers, dc, captions[i], HMARGIN + SPIN_WIDTH, new_col); + + // finally, compute the actual x values based on widths headers[0].x = 0; for (i = 1; i <= last_col; i++) headers[i].x = headers[i - 1].x + headers[i - 1].width; @@ -440,7 +486,8 @@ PickView::init_headers (HDC dc) PickView::PickView (Category &cat) : deftrust (TRUST_UNKNOWN), -contents (*this, cat, 0, false, true), hasClientRect (false) +contents (*this, cat, 0, false, true), showObsolete (false), +hasClientRect (false) { } @@ -453,26 +500,17 @@ PickView::init(views _mode) GetTextMetrics (dc, &tm); bitmap_dc = CreateCompatibleDC (dc); - bm_spin = LoadImage (hinstance, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0); - bm_rtarrow = LoadImage (hinstance, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP, - 0, 0, 0); - - bm_checkyes = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP, - 0, 0, 0); - bm_checkno = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP, - 0, 0, 0); - bm_checkna = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP, - 0, 0, 0); +#define LI(x) LoadImage (hinstance, MAKEINTRESOURCE (x), IMAGE_BITMAP, 0, 0, 0); + bm_spin = LI (IDB_SPIN); + bm_checkyes = LI (IDB_CHECK_YES); + bm_checkno = LI (IDB_CHECK_NO); + bm_checkna = LI (IDB_CHECK_NA); + bm_treeplus = LI (IDB_TREE_PLUS); + bm_treeminus = LI (IDB_TREE_MINUS); +#undef LI row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN); - int - irh = - tm. - tmExternalLeading + - tm. - tmDescent + - 11 + - ROW_MARGIN; + int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN; if (row_height < irh) row_height = irh; @@ -481,9 +519,8 @@ PickView::init(views _mode) // Ensure that the common control DLL is loaded, and then create // the header control. - INITCOMMONCONTROLSEX controlinfo = - { - sizeof (INITCOMMONCONTROLSEX), ICC_LISTVIEW_CLASSES}; + INITCOMMONCONTROLSEX controlinfo = { sizeof (INITCOMMONCONTROLSEX), + ICC_LISTVIEW_CLASSES }; InitCommonControlsEx (&controlinfo); if ((listheader = CreateWindowEx (0, WC_HEADER, (LPCTSTR) NULL, @@ -516,18 +553,10 @@ PickView::init(views _mode) wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW); header_height = wp.cy; - - view_mode = PickView::views::Package; - set_headers (); - init_headers (dc); - view_mode = PickView::views::Category; - set_headers (); - init_headers (dc); + ReleaseDC (GetHWND (), dc); view_mode = _mode; - set_headers (); - - ReleaseDC (GetHWND(), dc); + refresh (); } PickView::~PickView() @@ -558,7 +587,7 @@ bool PickView::registerWindowClass () wc.hIcon = LoadIcon (0, IDI_APPLICATION); wc.hIconSm = NULL; wc.hCursor = LoadCursor (0, IDC_ARROW); - wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); + wc.hbrBackground = NULL; // No menu wc.lpszMenuName = NULL; // We'll get a little crazy here with the class name @@ -657,6 +686,9 @@ PickView::list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) LRESULT PickView::WindowProc (UINT message, WPARAM wParam, LPARAM lParam) { + int wheel_notches; + UINT wheel_lines; + switch (message) { case WM_HSCROLL: @@ -665,6 +697,22 @@ PickView::WindowProc (UINT message, WPARAM wParam, LPARAM lParam) case WM_VSCROLL: list_vscroll (GetHWND(), (HWND)lParam, LOWORD(wParam), HIWORD(wParam)); return 0; + case WM_MOUSEWHEEL: + // this is how many 'notches' the wheel scrolled, forward/up = positive + wheel_notches = GET_WHEEL_DELTA_WPARAM(wParam) / 120; + + // determine how many lines the user has configred for a mouse scroll + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheel_lines, 0); + + if (wheel_lines == 0) // do no scrolling + return 0; + else if (wheel_lines == WHEEL_PAGESCROLL) + scroll (GetHWND (), SB_VERT, &scroll_ulc_y, (wheel_notches > 0) ? + SB_PAGEUP : SB_PAGEDOWN); + else + scroll (GetHWND (), SB_VERT, &scroll_ulc_y, (wheel_notches > 0) ? + SB_LINEUP : SB_LINEDOWN, wheel_lines * abs (wheel_notches)); + return 0; // handled case WM_LBUTTONDOWN: list_click (GetHWND(), FALSE, LOWORD(lParam), HIWORD(lParam), wParam); return 0; @@ -673,103 +721,112 @@ PickView::WindowProc (UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_NOTIFY: { - // pnmh = (LPNMHDR) lParam - LPNMHEADER phdr = (LPNMHEADER) lParam; - switch (phdr->hdr.code) - { - case HDN_ITEMCHANGED: - if (phdr->hdr.hwndFrom == ListHeader ()) - { - if (phdr->pitem && phdr->pitem->mask & HDI_WIDTH) - headers[phdr->iItem].width = phdr->pitem->cxy; - for (int i = 1; i <= last_col; i++) - headers[i].x = - headers[i - 1].x + headers[i - 1].width; - RECT r = GetClientRect (); - SCROLLINFO si; - si.cbSize = sizeof (si); - si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; - GetScrollInfo (GetHWND(), SB_HORZ, &si); - int oldMax = si.nMax; - si.nMax = - headers[last_col].x + - headers[last_col].width; - if (si.nTrackPos && oldMax > si.nMax) - si.nTrackPos += si.nMax - oldMax; - si.nPage = r.right; - SetScrollInfo (GetHWND(), SB_HORZ, &si, TRUE); - InvalidateRect (GetHWND(), &r, TRUE); - if (si.nTrackPos && oldMax > si.nMax) - scroll (GetHWND(), SB_HORZ, &scroll_ulc_x, - SB_THUMBTRACK); - } - break; - default: - break; - } - } + // pnmh = (LPNMHDR) lParam + LPNMHEADER phdr = (LPNMHEADER) lParam; + switch (phdr->hdr.code) + { + case HDN_ITEMCHANGED: + if (phdr->hdr.hwndFrom == ListHeader ()) + { + if (phdr->pitem && phdr->pitem->mask & HDI_WIDTH) + headers[phdr->iItem].width = phdr->pitem->cxy; + + for (int i = 1; i <= last_col; i++) + headers[i].x = headers[i - 1].x + headers[i - 1].width; + + RECT r = GetClientRect (); + SCROLLINFO si; + si.cbSize = sizeof (si); + si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; + GetScrollInfo (GetHWND(), SB_HORZ, &si); + + int oldMax = si.nMax; + si.nMax = headers[last_col].x + headers[last_col].width; + if (si.nTrackPos && oldMax > si.nMax) + si.nTrackPos += si.nMax - oldMax; + + si.nPage = r.right; + SetScrollInfo (GetHWND(), SB_HORZ, &si, TRUE); + InvalidateRect (GetHWND(), &r, TRUE); + if (si.nTrackPos && oldMax > si.nMax) + scroll (GetHWND(), SB_HORZ, &scroll_ulc_x, SB_THUMBTRACK); + } + break; + } + } + break; case WM_SIZE: { // Note: WM_SIZE msgs only appear when 'just' scrolling the window - RECT clientRect = GetWindowRect (); - if (hasClientRect) - { - int dx = clientRect.right - clientRect.left - lastClientRect.width(); - if (dx != 0) - { - headers[last_col].width += dx; - - set_headers (); - - ::MoveWindow (listheader, -scroll_ulc_x, 0, - headers[last_col].x + - headers[last_col].width, header_height, TRUE); - } - } - else - hasClientRect = true; - lastClientRect = clientRect; - return 0; + RECT clientRect = GetWindowRect (); + if (hasClientRect) + { + int dx; + if ((dx = clientRect.right - clientRect.left - + lastClientRect.width ()) != 0) + { + headers[last_col].width += dx; + set_headers (); + ::MoveWindow (listheader, -scroll_ulc_x, 0, + headers[last_col].x + + headers[last_col].width, header_height, TRUE); + } + } + else + hasClientRect = true; + + lastClientRect = clientRect; + return 0; } - - default: - return DefWindowProc (GetHWND(), message, wParam, lParam); } + + // default: can't handle this message + return DefWindowProc (GetHWND(), message, wParam, lParam); } void PickView::paint (HWND hwnd) { - HDC hdc; - PAINTSTRUCT ps; - int x, y; + // we want to retrieve the update region before calling BeginPaint, + // because after we do that the update region is validated and we can + // no longer retrieve it + HRGN hUpdRgn = CreateRectRgn (0, 0, 0, 0); - hdc = BeginPaint (hwnd, &ps); + if (GetUpdateRgn (hwnd, hUpdRgn, FALSE) == 0) + { + // error? + return; + } + // tell the system that we're going to begin painting our window + // it will prevent further WM_PAINT messages from arriving until we're + // done, and if any part of our window was invalidated while we are + // painting, it will retrigger us so that we can fix it + PAINTSTRUCT ps; + HDC hdc = BeginPaint (hwnd, &ps); + SelectObject (hdc, sysfont); - SetBkColor (hdc, GetSysColor (COLOR_WINDOW)); SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)); + FillRgn (hdc, hUpdRgn, GetSysColorBrush(COLOR_WINDOW)); RECT cr; ::GetClientRect (hwnd, &cr); - x = cr.left - scroll_ulc_x; - y = cr.top - scroll_ulc_y + header_height; - - IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right, - cr.bottom); + int x = cr.left - scroll_ulc_x; + int y = cr.top - scroll_ulc_y + header_height; - contents.paint (hdc, x, y, 0, (get_view_mode () == - PickView::views::Category) ? 0 : 1); + contents.paint (hdc, hUpdRgn, x, y, 0, (view_mode == + PickView::views::Category) ? 0 : 1); if (contents.itemcount () == 0) { static const char *msg = "Nothing to Install/Update"; if (source == IDC_SOURCE_DOWNLOAD) - msg = "Nothing to Download"; + msg = "Nothing to Download"; TextOut (hdc, x + HMARGIN, y, msg, strlen (msg)); } + DeleteObject (hUpdRgn); EndPaint (hwnd, &ps); } @@ -785,27 +842,29 @@ PickView::Create (Window * parent, DWORD Style, RECT *r) return false; } - // Save our parent, we'll probably need it eventually. + // Save our parent, we'll probably need it eventually. setParent(parent); // Create the window instance - CreateWindowEx ( - // Extended Style - WS_EX_CLIENTEDGE, - "listview", //MAKEINTATOM(WindowClassAtom), // window class atom (name) - "listviewwindow", // no title-bar string yet - // Style bits + CreateWindowEx (// Extended Style + WS_EX_CLIENTEDGE, + // window class atom (name) + "listview", //MAKEINTATOM(WindowClassAtom), + "listviewwindow", // no title-bar string yet + // Style bits Style, - r ? r->left : CW_USEDEFAULT, r ? r->top : CW_USEDEFAULT, - r? r->right - r->left + 1 : CW_USEDEFAULT, - r? r->bottom - r->top + 1 :CW_USEDEFAULT, - // Parent Window - parent == NULL ? (HWND) NULL : parent->GetHWND (), - // use class menu - (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST), - // The application instance - GetInstance (), - // The this ptr, which we'll use to set up the WindowProc reflection. + r ? r->left : CW_USEDEFAULT, + r ? r->top : CW_USEDEFAULT, + r ? r->right - r->left + 1 : CW_USEDEFAULT, + r ? r->bottom - r->top + 1 : CW_USEDEFAULT, + // Parent Window + parent == NULL ? (HWND)NULL : parent->GetHWND (), + // use class menu + (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST), + // The application instance + GetInstance (), + // The this ptr, which we'll use to set up + // the WindowProc reflection. reinterpret_cast((Window *)this)); if (GetHWND() == NULL) { @@ -826,16 +885,16 @@ PickView::defaultTrust (trusts trust) { packagemeta & pkg = **i; if (pkg.installed - || pkg.categories.find ("Base") != pkg.categories.end () - || pkg.categories.find ("Misc") != pkg.categories.end ()) - { - pkg.desired = pkg.trustp (trust); - if (pkg.desired) - pkg.desired.pick (pkg.desired.accessible() - && pkg.desired != pkg.installed); - } + || pkg.categories.find ("Base") != pkg.categories.end () + || pkg.categories.find ("Misc") != pkg.categories.end ()) + { + pkg.desired = pkg.trustp (trust); + if (pkg.desired) + pkg.desired.pick (pkg.desired.accessible() && + pkg.desired != pkg.installed); + } else - pkg.desired = packageversion (); + pkg.desired = packageversion (); } RECT r = GetClientRect (); InvalidateRect (this->GetHWND(), &r, TRUE); @@ -844,13 +903,36 @@ PickView::defaultTrust (trusts trust) n != packagedb::categories.end(); ++n) if (!n->second.size()) { - log (LOG_BABBLE) << "Removing empty category " << n->first << endLog; + log (LOG_BABBLE) << "Removing empty category " << n->first << endLog; packagedb::categories.erase (n++); } } +/* This recalculates all column widths and resets the view */ void PickView::refresh() { - setViewMode (get_view_mode ()); + HDC dc = GetDC (GetHWND ()); + + // we must set the font of the DC here, otherwise the width calculations + // will be off because the system will use the wrong font metrics + sysfont = GetStockObject (DEFAULT_GUI_FONT); + SelectObject (dc, sysfont); + + // init headers for the current mode + set_headers (); + init_headers (dc); + + // save the current mode + views cur_view_mode = view_mode; + + // switch to the other type and do those headers + view_mode = (view_mode == PickView::views::Category) ? + PickView::views::PackageFull : PickView::views::Category; + set_headers (); + init_headers (dc); + ReleaseDC (GetHWND (), dc); + + view_mode = cur_view_mode; + setViewMode (view_mode); } diff --git a/PickView.h b/PickView.h index 0e8a42d5..80093508 100644 --- a/PickView.h +++ b/PickView.h @@ -21,13 +21,12 @@ #include "window.h" #include "RECTWrapper.h" -#define HMARGIN 10 +#define HMARGIN 10 #define ROW_MARGIN 5 #define ICON_MARGIN 4 -#define RTARROW_WIDTH 11 -#define SPIN_WIDTH 11 -#define NEW_COL_SIZE_SLOP (ICON_MARGIN + SPIN_WIDTH + RTARROW_WIDTH) +#define SPIN_WIDTH 11 #define CHECK_SIZE 11 +#define TREE_INDENT 12 #define CATEGORY_EXPANDED 0 #define CATEGORY_COLLAPSED 1 @@ -44,13 +43,9 @@ public: class views; class Header; int num_columns; - views get_view_mode () - { - return view_mode; - }; void defaultTrust (trusts trust); - void set_view_mode (views _mode); - void setViewMode (PickView::views mode); + void cycleViewMode (); + void setViewMode (views mode); void paint (HWND hwnd); LRESULT CALLBACK list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode); LRESULT CALLBACK list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos); @@ -61,9 +56,9 @@ public: void init(views _mode); ~PickView(); const char *mode_caption (); + void setObsolete (bool doit); void insert_pkg (packagemeta &); void insert_category (Category *, bool); - void clear_view (void); int click (int row, int x); void refresh(); int current_col; @@ -76,13 +71,13 @@ public: int row_height; TEXTMETRIC tm; HDC bitmap_dc; - HANDLE bm_spin,bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna; + HANDLE bm_spin, bm_checkyes, bm_checkno, bm_checkna, bm_treeplus, bm_treeminus; trusts deftrust; HANDLE sysfont; int scroll_ulc_x, scroll_ulc_y; int header_height; PickCategoryLine contents; - void scroll (HWND hwnd, int which, int *var, int code); + void scroll (HWND hwnd, int which, int *var, int code, int howmany); HWND ListHeader (void) const { return listheader; @@ -126,15 +121,16 @@ public: { public: const char *text; - int slen; int width; int x; + bool needs_clip; }; private: static ATOM WindowClassAtom; HWND listheader; views view_mode; + bool showObsolete; // Stuff needed to handle resizing bool hasClientRect; @@ -146,4 +142,7 @@ private: int column); }; +bool isObsolete (std::set &categories); +bool isObsolete (const String &catname); + #endif /* SETUP_PICKVIEW_H */ diff --git a/choose.cc b/choose.cc index a3740ce0..1b5ec444 100644 --- a/choose.cc +++ b/choose.cc @@ -56,6 +56,7 @@ static const char *cvsid = #include "threebar.h" #include "Generic.h" #include "ControlAdjuster.h" +#include "prereq.h" using namespace std; @@ -73,6 +74,7 @@ static ControlAdjuster::ControlInfo ChooserControlsInfo[] = { {IDC_LISTVIEW_POS, CP_RIGHT, CP_TOP}, {IDC_CHOOSE_VIEWCAPTION, CP_RIGHT, CP_TOP}, {IDC_CHOOSE_LIST, CP_STRETCH, CP_STRETCH}, + {IDC_CHOOSE_HIDE, CP_LEFT, CP_BOTTOM}, {0, CP_LEFT, CP_TOP} }; @@ -147,6 +149,8 @@ ChooserPage::getDefaultListViewSize() void ChooserPage::OnInit () { + CheckDlgButton (GetHWND (), IDC_CHOOSE_HIDE, BST_CHECKED); + if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD) packagemeta::ScanDownloadedFiles (); @@ -188,17 +192,26 @@ ChooserPage::OnNext () logResults(); #endif - if (source == IDC_SOURCE_CWD) + PrereqChecker p; + if (p.isMet ()) { - // Next, install - Progress.SetActivateTask (WM_APP_START_INSTALL); + if (source == IDC_SOURCE_CWD) + { + // Next, install + Progress.SetActivateTask (WM_APP_START_INSTALL); + } + else + { + // Next, start download from internet + Progress.SetActivateTask (WM_APP_START_DOWNLOAD); + } + return IDD_INSTATUS; } else { - // Next, start download from internet - Progress.SetActivateTask (WM_APP_START_DOWNLOAD); + // rut-roh, some required things are not selected + return IDD_PREREQ; } - return IDD_INSTATUS; } long @@ -232,6 +245,8 @@ ChooserPage::changeTrust(trusts aTrust) for_each (db.packages.begin (), db.packages.end (), bind2nd (mem_fun (&packagemeta::set_requirements), aTrust)); chooser->refresh(); + PrereqChecker p; + p.setTrust (aTrust); } bool @@ -266,13 +281,16 @@ ChooserPage::OnMessageCmd (int id, HWND hwndctl, UINT code) break; case IDC_CHOOSE_VIEW: - chooser->setViewMode (++chooser->get_view_mode ()); + chooser->cycleViewMode (); if (!SetDlgItemText (GetHWND (), IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) log (LOG_BABBLE) << "Failed to set View button caption " << GetLastError () << endLog; break; + case IDC_CHOOSE_HIDE: + chooser->setObsolete (!IsButtonChecked (id)); + break; default: // Wasn't recognized or handled. return false; @@ -281,3 +299,9 @@ ChooserPage::OnMessageCmd (int id, HWND hwndctl, UINT code) // Was handled since we never got to default above. return true; } + +BOOL CALLBACK +ChooserPage::OnMouseWheel (UINT message, WPARAM wParam, LPARAM lParam) +{ + return chooser->WindowProc (message, wParam, lParam); +} diff --git a/choose.h b/choose.h index d9b26e0e..644a7a68 100644 --- a/choose.h +++ b/choose.h @@ -31,6 +31,8 @@ public: }; virtual bool OnMessageCmd (int id, HWND hwndctl, UINT code); + virtual BOOL CALLBACK OnMouseWheel (UINT message, WPARAM wParam, + LPARAM lParam); bool Create (); virtual void OnInit (); diff --git a/main.cc b/main.cc index 669dd619..68937d5b 100644 --- a/main.cc +++ b/main.cc @@ -57,6 +57,7 @@ static const char *cvsid = #include "net.h" #include "site.h" #include "choose.h" +#include "prereq.h" #include "threebar.h" #include "desktop.h" @@ -461,6 +462,7 @@ main (int argc, char **argv) NetPage Net; SitePage Site; ChooserPage Chooser; + PrereqPage Prereq; DesktopSetupPage Desktop; PropSheet MainWindow; @@ -494,6 +496,7 @@ main (int argc, char **argv) Net.Create (); Site.Create (); Chooser.Create (); + Prereq.Create (); Progress.Create (); Desktop.Create (); @@ -506,6 +509,7 @@ main (int argc, char **argv) MainWindow.AddPage (&Net); MainWindow.AddPage (&Site); MainWindow.AddPage (&Chooser); + MainWindow.AddPage (&Prereq); MainWindow.AddPage (&Progress); MainWindow.AddPage (&Desktop); diff --git a/prereq.cc b/prereq.cc new file mode 100644 index 00000000..8404d461 --- /dev/null +++ b/prereq.cc @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2005 Brian Dessent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Brian Dessent + * + */ + +#if 0 +static const char *cvsid = + "\n%%% $Id$\n"; +#endif + +#include "win32.h" +#include +#include +#include +#include +#include + +#include "prereq.h" +#include "dialog.h" +#include "resource.h" +#include "state.h" +#include "propsheet.h" +#include "threebar.h" +#include "Generic.h" +#include "LogSingleton.h" +#include "ControlAdjuster.h" +#include "package_db.h" +#include "package_meta.h" +#include "msg.h" + +// Sizing information. +static ControlAdjuster::ControlInfo PrereqControlsInfo[] = { + {IDC_PREREQ_CHECK, CP_LEFT, CP_BOTTOM}, + {IDC_PREREQ_EDIT, CP_STRETCH, CP_STRETCH}, + {0, CP_LEFT, CP_TOP} +}; + +extern ThreeBarProgressPage Progress; + +// --------------------------------------------------------------------------- +// implements class PrereqPage +// --------------------------------------------------------------------------- + +PrereqPage::PrereqPage () +{ + sizeProcessor.AddControlInfo (PrereqControlsInfo); +} + +bool +PrereqPage::Create () +{ + return PropertyPage::Create (IDD_PREREQ); +} + +void +PrereqPage::OnInit () +{ + // start with the checkbox set + CheckDlgButton (GetHWND (), IDC_PREREQ_CHECK, BST_CHECKED); + + // set the edit-area to a larger font + SetDlgItemFont(IDC_PREREQ_EDIT, "MS Shell Dlg", 10); +} + +void +PrereqPage::OnActivate() +{ + // if we have gotten this far, then PrereqChecker has already run isMet + // and found that there were missing packages; so we can just call + // getUnmetString to format the results and display it + + String s; + PrereqChecker p; + p.getUnmetString (s); + SetDlgItemText (GetHWND (), IDC_PREREQ_EDIT, s.c_str ()); + + SetFocus (GetDlgItem (IDC_PREREQ_CHECK)); +} + +long +PrereqPage::OnNext () +{ + HWND h = GetHWND (); + + if (!IsDlgButtonChecked (h, IDC_PREREQ_CHECK)) + { + // breakage imminent! danger, danger + int res = MessageBox (h, + "If you continue without correcting the listed conflicts, your " + "Cygwin installation will not function properly.\r\n" + "We strongly recommend that you let Setup install the listed packages.\r\n\r\n" + "Are you sure you want to proceed?", + "WARNING - Required Packages Not Selected", + MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2); + if (res == IDNO) + return -1; + else + log (LOG_PLAIN) << + "NOTE! User refused suggested missing dependencies! " + "Expect some packages to give errors or not function at all." << endLog; + } + else + { + // add the missing requirements + PrereqChecker p; + p.selectMissing (); + } + if (source == IDC_SOURCE_CWD) + { + // Next, install + Progress.SetActivateTask (WM_APP_START_INSTALL); + } + else + { + // Next, start download from internet + Progress.SetActivateTask (WM_APP_START_DOWNLOAD); + } + return IDD_INSTATUS; +} + +long +PrereqPage::OnBack () +{ + return IDD_CHOOSE; +} + + +// --------------------------------------------------------------------------- +// implements class PrereqChecker +// --------------------------------------------------------------------------- + +// instantiate the static members +map , packagemeta_ltcomp> PrereqChecker::unmet; +trusts PrereqChecker::theTrust = TRUST_CURR; + +/* This function builds a list of unmet dependencies to present to the user on + the PrereqPage propsheet. The data is stored as an associative map of + unmet[missing-package] = vector of packages that depend on missing-package */ +bool +PrereqChecker::isMet () +{ + packagedb db; + bool foundUnmet = false; + + // unmet is static - clear it each time this is called + unmet.clear (); + + // loop through each package + for (vector ::iterator n = db.packages.begin (); + n != db.packages.end (); ++n) + { + // if the package is installed or selected to be installed... + if ((*n)->desired) + { + // loop through each dependency + for (vector *>::iterator i = + (*n)->desired.depends ()->begin (); + i != (*n)->desired.depends ()->end (); ++i) + { + // XXX: the following assumes that there is only a single + // node in each OR clause, which is currently the case. + // if setup is ever pushed to use AND/OR in "depends:" + // lines this will have to be updated + PackageSpecification *spec = (*i)->at(0); + + packagemeta *pack = db.findBinary (*spec); + if (!pack) + continue; // asking for a package that doesn't exist - error? + + if (pack->desired && spec->satisfies (pack->desired)) + { + // dependency met + } + else + { + foundUnmet = true; + unmet[pack].push_back (*n); + } + } + } + } + + return !foundUnmet; +} + +/* Formats 'unmet' as a string for display to the user. */ +void +PrereqChecker::getUnmetString (String &s) +{ + s = ""; + + map , packagemeta_ltcomp>::iterator i; + for (i = unmet.begin(); i != unmet.end(); i++) + { + s = s + "Package: " + i->first->name + "\r\n\tRequired by: "; + for (unsigned int j = 0; j < i->second.size(); j++) + { + s += i->second[j]->name; + if (j != i->second.size() - 1) + s += ", "; + } + s += "\r\n\r\n"; + } +} + +/* Takes the keys of 'unmet' and selects them, using the current trust. */ +void +PrereqChecker::selectMissing () +{ + packagedb db; + + // provide a default, even though this should have been set for us + if (!theTrust) + theTrust = TRUST_CURR; + + // get each of the keys of 'unmet' + map , packagemeta_ltcomp>::iterator i; + for (i = unmet.begin(); i != unmet.end(); i++) + { + packageversion vers = i->first->trustp (theTrust); + i->first->desired = vers; + vers.sourcePackage ().pick (false); + + if (vers == i->first->installed) + { + vers.pick (false); + log (LOG_PLAIN) << "Adding required dependency " << i->first->name << + ": Selecting already-installed version " << + i->first->installed.Canonical_version () << "." << endLog; + } + else + { + vers.pick (vers.accessible ()); + log (LOG_PLAIN) << "Adding required dependency " << i->first->name << + ": Selecting version " << vers.Canonical_version () << + " for installation." << endLog; + } + } +} diff --git a/prereq.h b/prereq.h new file mode 100644 index 00000000..cd3f3444 --- /dev/null +++ b/prereq.h @@ -0,0 +1,55 @@ +#ifndef SETUP_PREREQ_H +#define SETUP_PREREQ_H + +#include +#include "proppage.h" +#include "PackageTrust.h" +#include "package_meta.h" + +using namespace std; + +// keeps the map sorted by name +struct packagemeta_ltcomp +{ + bool operator() ( const packagemeta *m1, const packagemeta *m2 ) + { return m1->name.casecompare (m2->name) < 0; } +}; + + +class PrereqPage:public PropertyPage +{ +public: + PrereqPage (); + virtual ~PrereqPage () { }; + bool Create (); + virtual void OnInit (); + virtual void OnActivate (); + virtual long OnNext (); + virtual long OnBack (); + virtual long OnUnattended () { return 0; }; +}; + +class PrereqChecker +{ +public: + // checks all dependecies, populates 'unmet' + // returns true if unsatisfied dependencies exist + bool isMet (); + + // formats 'unmet' as a string for display + void getUnmetString (String &s); + + // selects/picks the needed packages that were missing + void selectMissing (); + + // notes the current trust (for use in selectMissing) + void setTrust (trusts t) { theTrust = t; }; + +private: + + // this is the actual hash_map that does all the work + static map , packagemeta_ltcomp> unmet; + static trusts theTrust; +}; + +#endif /* SETUP_PREREQ_H */ diff --git a/proppage.cc b/proppage.cc index cd87b67d..4663538c 100644 --- a/proppage.cc +++ b/proppage.cc @@ -340,6 +340,14 @@ PropertyPage::DialogProc (UINT message, WPARAM wParam, LPARAM lParam) // cast this brush as a BOOL and return it (?!) return (BOOL)theURL->second.brush; } + case WM_MOUSEWHEEL: + // we do this so that derived classes that wish to process this message + // do not need to reimplement the entire WinProc, they can just + // provice an OnMouseWheel. (Note that mousewheel events are delivered + // to the parent of the window that received the scroll, so it would + // not work to just process this message there.) + return OnMouseWheel (message, wParam, lParam); + break; default: break; } @@ -356,6 +364,12 @@ PropertyPage::DialogProc (UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } +BOOL CALLBACK +PropertyPage::OnMouseWheel (UINT message, WPARAM wParam, LPARAM lParam) +{ + return 1; // not handled; define in a derived class to support this +} + void PropertyPage::setTitleFont () { diff --git a/proppage.h b/proppage.h index 49515d2f..302edf03 100644 --- a/proppage.h +++ b/proppage.h @@ -81,6 +81,8 @@ protected: virtual BOOL CALLBACK DialogProc (UINT message, WPARAM wParam, LPARAM lParam); + virtual BOOL CALLBACK OnMouseWheel (UINT message, WPARAM wParam, + LPARAM lParam); public: PropertyPage (); diff --git a/res.rc b/res.rc index 8e9c5758..050090a7 100644 --- a/res.rc +++ b/res.rc @@ -80,7 +80,7 @@ BEGIN 317,1 GROUPBOX "Local Package Directory",IDC_LOCALDIR_GRP,53,67,210,45 - EDITTEXT IDC_LOCAL_DIR,58,83,165,15,ES_AUTOHSCROLL | WS_GROUP + EDITTEXT IDC_LOCAL_DIR,58,83,161,15,ES_AUTOHSCROLL | WS_GROUP PUSHBUTTON "B&rowse...",IDC_LOCAL_DIR_BROWSE,223,83,34,14 END @@ -150,8 +150,8 @@ BEGIN 8,NOT WS_GROUP EDITTEXT IDC_EDIT_USER_URL,65,160,185,14,ES_AUTOHSCROLL | WS_GROUP - LTEXT "User URL:",IDC_STATIC,15,162,45,8,NOT WS_GROUP - PUSHBUTTON "Add",IDC_BUTTON_ADD_URL,250,160,50,14 + LTEXT "User URL:",IDC_SITE_USERURL,15,162,45,8,NOT WS_GROUP + PUSHBUTTON "Add",IDC_BUTTON_ADD_URL,255,160,50,14 END IDD_NET DIALOG DISCARDABLE 0, 0, 317, 179 @@ -265,8 +265,7 @@ BEGIN "necessary.",IDC_SPLASH_TEXT,115,25,195,90 ICON IDI_CYGWIN,IDC_SPLASH_ICON,114,114,21,20,WS_GROUP LTEXT "Version (unknown)",IDC_VERSION,115,137,195,10 - LTEXT "Copyright 2000-2005 Red Hat Inc.",IDC_SPLASH_COPYR, - 115,150,195,8 + LTEXT "Copyright 2000-2005",IDC_SPLASH_COPYR,115,150,195,8 LTEXT "http://www.cygwin.com/",IDC_SPLASH_URL,115,162,90,8 END @@ -324,7 +323,9 @@ BEGIN CONTROL "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN,0,28, 317,1 CONTROL "",IDC_LISTVIEW_POS,"Static",SS_BLACKFRAME | NOT - WS_VISIBLE,7,45,303,134 + WS_VISIBLE,7,45,303,122 + CONTROL "&Hide obsolete packages",IDC_CHOOSE_HIDE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,167,100,14 ICON IDI_CYGWIN,IDC_HEADICON,290,0,21,20 LTEXT "Select the packages you want setup to install.", IDC_CHOOSE_INST_TEXT,21,9,239,16,NOT WS_GROUP @@ -333,6 +334,28 @@ BEGIN LTEXT "",IDC_CHOOSE_VIEWCAPTION,270,33,40,10 END +IDD_PREREQ DIALOG DISCARDABLE 0, 0, 317, 179 +STYLE DS_MODALFRAME | DS_3DLOOK | WS_CHILD | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CAPTION "Cygwin Setup - Resolve Dependencies" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN, + 0,28,317,1 + ICON IDI_CYGWIN,IDC_HEADICON,290,0,21,20 + LTEXT "Warning! Unmet Dependencies Found",IDC_STATIC_HEADER_TITLE + ,7,0,258,8,NOT WS_GROUP + LTEXT "The following packages are required but have not been " + "selected.",IDC_STATIC,21,9,239,16,NOT WS_GROUP + CONTROL "&Install these packages to meet dependencies (RECOMMENDED)" + ,IDC_PREREQ_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 7,167,225,14 + EDITTEXT IDC_PREREQ_EDIT,7,41,303,124,WS_VSCROLL | WS_HSCROLL | + ES_LEFT | ES_MULTILINE | ES_READONLY | ES_AUTOHSCROLL | + ES_AUTOVSCROLL + +END + ///////////////////////////////////////////////////////////////////////////// // // Manifest @@ -361,12 +384,12 @@ CYGWIN.ICON FILE DISCARDABLE "cygwin.ico" // Bitmap // -SPIN BITMAP DISCARDABLE "choose-spin.bmp" IDB_SPIN BITMAP DISCARDABLE "choose-spin.bmp" -IDB_RTARROW BITMAP DISCARDABLE "choose-rtarrow.bmp" IDB_CHECK_YES BITMAP DISCARDABLE "check-yes.bmp" IDB_CHECK_NO BITMAP DISCARDABLE "check-no.bmp" IDB_CHECK_NA BITMAP DISCARDABLE "check-na.bmp" +IDB_TREE_PLUS BITMAP DISCARDABLE "tree-plus.bmp" +IDB_TREE_MINUS BITMAP DISCARDABLE "tree-minus.bmp" ///////////////////////////////////////////////////////////////////////////// // @@ -403,31 +426,27 @@ BEGIN IDS_TRUSTKEEP_TOOLTIP "Sets all packages to their currently installed " "version. This is equivalent to telling setup not to make any " "changes to any package." - IDS_TRUSTPREV_TOOLTIP "Tells setup to try to select the version " - "marked as 'Prev' for every package. 'Prev' generally means the " - "package that was last considered stable prior to the current stable " - "version." - IDS_TRUSTCURR_TOOLTIP "Tells setup to try to select the version for " - "each package that is currently considered the most stable. " - "(RECOMMENDED)" - IDS_TRUSTEXP_TOOLTIP "Tells setup to try to select the most recent " - "version for every package, even if that version is marked as " - "Experimental or for test use by its maintainer." + IDS_TRUSTPREV_TOOLTIP "Globally select the version marked as 'Prev', " + "which generally means the version that was last considered stable " + "prior to the current stable version." + IDS_TRUSTCURR_TOOLTIP "Globally select the version that is currently " + "considered the most stable. (RECOMMENDED)" + IDS_TRUSTEXP_TOOLTIP "Globally select the most recent version, even if " + "that version is considered Experimental or for test use by the maintainer." IDS_VIEWBUTTON_TOOLTIP "Cycles the package view. This determines " "which packages are shown in the chooser below.\r\n" "\r\n" - "Category: Shows packages by heirarchy. Click on '+' to expand a " - "category.\r\n" + "Category: Group by package category. Click on '+' to expand.\r\n" "\r\n" - "Full: Shows all packages.\r\n" + "Full: Show all packages.\r\n" "\r\n" - "Partial: Shows only packages that are about to be installed, " - "removed, or upgraded. This essentially tells you everything that " - "setup is about to change when you press 'Next'.\r\n" + "Partial: Show only packages that are about to be installed, removed, " + "or upgraded. This tells you everything that setup is about to change " + "when you press 'Next'.\r\n" "\r\n" - "Up To Date: Shows installed packages that need no action because " - "they are at the desired version already.\r\n" + "Up To Date: Show installed packages that need no action because they " + "are at the desired version already.\r\n" "\r\n" - "Not installed: Shows packages that are are not currently installed " + "Not installed: Show packages that are are not currently installed " "and haven't been selected for installation." END diff --git a/resource.h b/resource.h index 3e0dabf6..c0668694 100644 --- a/resource.h +++ b/resource.h @@ -53,14 +53,16 @@ #define IDD_S_POSTINSTALL 217 #define IDD_VIRUS 218 #define IDD_DESKTOP 219 +#define IDD_PREREQ 220 // Bitmaps #define IDB_SPIN 300 -#define IDB_RTARROW 301 -#define IDB_CHECK_YES 302 -#define IDB_CHECK_NO 303 -#define IDB_CHECK_NA 304 +#define IDB_CHECK_YES 301 +#define IDB_CHECK_NO 302 +#define IDB_CHECK_NA 303 +#define IDB_TREE_PLUS 304 +#define IDB_TREE_MINUS 305 // icons @@ -144,3 +146,8 @@ #define IDC_SPLASH_TEXT 571 #define IDC_SPLASH_ICON 572 #define IDC_SPLASH_COPYR 573 +#define IDC_SITE_USERURL 574 +#define IDC_CHOOSE_HIDE 575 +#define IDC_PREREQ_TEXT 576 +#define IDC_PREREQ_EDIT 577 +#define IDC_PREREQ_CHECK 578 diff --git a/site.cc b/site.cc index 88f76c26..00264ffd 100644 --- a/site.cc +++ b/site.cc @@ -53,6 +53,7 @@ static ControlAdjuster::ControlInfo SiteControlsInfo[] = { {IDC_URL_LIST, CP_STRETCH, CP_STRETCH}, {IDC_EDIT_USER_URL, CP_STRETCH, CP_BOTTOM}, {IDC_BUTTON_ADD_URL, CP_RIGHT, CP_BOTTOM}, + {IDC_SITE_USERURL, CP_LEFT, CP_BOTTOM}, {0, CP_LEFT, CP_TOP} }; diff --git a/tree-minus.bmp b/tree-minus.bmp new file mode 100755 index 0000000000000000000000000000000000000000..35b2221b89542e9c1b37b10969107f3fc0f72362 GIT binary patch literal 106 zcmZ?r&0>H6J0PV2#N1HK$iN7e&;gT}#Q*>Q8U8H6J0PV2#N1HK$iN7e&;gT}#Q*>Q8U8