? cgf ? collins ? res.aps ? stripit ? choose.h ? GNUmakefile Index: choose.cc =================================================================== RCS file: /cvs/uberbaum/winsup/cinstall/choose.cc,v retrieving revision 2.35 diff -p -r2.35 choose.cc *** choose.cc 2001/06/25 05:55:22 2.35 --- choose.cc 2001/06/29 21:24:28 *************** static char *cvsid = "\n%%% $Id: choose. *** 43,48 **** --- 43,49 ---- #include "find.h" #include "filemanip.h" #include "mount.h" + #include "choose.h" #include "port.h" *************** static char *cvsid = "\n%%% $Id: choose. *** 55,62 **** static int initialized = 0; - static int full_list = 0; - static int scroll_ulc_x, scroll_ulc_y; static HWND lv, nextbutton, choose_inst_text; --- 56,61 ---- *************** static HANDLE sysfont; *** 66,94 **** static int row_height; static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna; static HDC bitmap_dc; ! static struct ! { ! char *text; ! int slen; ! int width; ! int x; ! } ! headers[] = { { "Current", 7, 0, 0 }, - #define CURRENT_COL 0 { "New", 3, 0, 0 }, - #define NEW_COL 1 { "Src?", 4, 0, 0 }, - #define SRC_COL 2 { "Package", 7, 0, 0 }, - #define PACKAGE_COL 3 { 0, 0, 0, 0 } }; - #define NUM_COLUMNS (sizeof (headers) / (sizeof (headers[0])) - 1) ! int *package_indexes, nindexes; static bool isinstalled (Package *pkg, int trust) { --- 65,94 ---- static int row_height; static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna; static HDC bitmap_dc; + static view *chooser = NULL; ! static struct _header pkg_headers[] = { ! { "Current", 7, 0, 0 }, ! { "New", 3, 0, 0 }, ! { "Src?", 4, 0, 0 }, ! { "Category", 8, 0, 0 }, ! { "Package", 7, 0, 0 }, ! { 0, 0, 0, 0 } ! }; ! ! static struct _header cat_headers[] = { ! { "Category", 8, 0, 0 }, { "Current", 7, 0, 0 }, { "New", 3, 0, 0 }, { "Src?", 4, 0, 0 }, { "Package", 7, 0, 0 }, { 0, 0, 0, 0 } }; ! static int add_required(Package *pkg); ! static void set_view_mode (HWND h, views mode); + static bool isinstalled (Package *pkg, int trust) { *************** set_action (Package *pkg, bool preinc) *** 174,179 **** --- 174,242 ---- } } + static int + add_required (Package *pkg) + { + Dependency *dp; + Package *required; + int c; + int changed = 0; + dp = pkg->required; + switch (pkg->action) + { + case ACTION_UNINSTALL: + case ACTION_ERROR: + case ACTION_UNKNOWN: + case ACTION_SRC_ONLY: + case ACTION_SKIP: + return 0; + default: + break; + } + while (dp) + { + if ((required = getpkgbyname(dp->package)) == NULL) + { + dp=dp->next; + continue; + } + switch (required->action) + { + case ACTION_PREV: + case ACTION_CURR: + case ACTION_TEST: + case ACTION_LAST: + case ACTION_SAME_CURR: + case ACTION_SAME_TEST: + case ACTION_SAME_PREV: + case ACTION_REDO: + case ACTION_SAME_LAST: + /* we are installing a user selected version */ + break; + + case ACTION_UNINSTALL: + /* it's already installed - leave it */ + required->action = ACTION_SKIP; + break; + case ACTION_ERROR: + case ACTION_UNKNOWN: + case ACTION_SRC_ONLY: + case ACTION_SKIP: + /* the current install will fail */ + required->action = ACTION_PREV; /* this find prev, then curr, then test. */ + set_action(required, 0); /* we need a find_best that gets installed, */ + changed++; /* then current, then prev, then test */ + chooser->insert_pkg (required); + break; + default: + log (0, "should never get here %d\n", required->action); + } + changed += add_required (required); + dp=dp->next; + } + return changed; + } + /* Return an appropriate caption given the current action. */ const char * choose_caption (Package *pkg) *************** paint (HWND hwnd) *** 224,281 **** x = cr.left - scroll_ulc_x; y = cr.top - scroll_ulc_y + header_height; - ! for (i = 0; headers[i].text; i++) { ! TextOut (hdc, x + headers[i].x, 3, headers[i].text, headers[i].slen); ! MoveToEx (hdc, x + headers[i].x, header_height-3, &p); ! LineTo (hdc, x + headers[i].x + headers[i].width, header_height-3); } IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right, cr.bottom); - - for (ii = 0; ii < nindexes; ii++) - { - i = package_indexes[ii]; - Package *pkg = package + i; - int r = y + ii * row_height; - int by = r + tm.tmHeight - 11; - if (pkg->installed) - { - TextOut (hdc, x + headers[CURRENT_COL].x, r, - pkg->installed->version, strlen (pkg->installed->version)); - SelectObject (bitmap_dc, bm_rtarrow); - BitBlt (hdc, x + headers[CURRENT_COL].x + headers[0].width + - ICON_MARGIN/2 + HMARGIN/2, by, - 11, 11, bitmap_dc, 0, 0, SRCCOPY); - } - - const char *s = choose_caption (pkg); - TextOut (hdc, x + headers[NEW_COL].x + NEW_COL_SIZE_SLOP, r, - s, strlen (s)); - SelectObject (bitmap_dc, bm_spin); - BitBlt (hdc, x + headers[NEW_COL].x, by, 11, 11, - bitmap_dc, 0, 0, SRCCOPY); ! HANDLE check_bm; ! if (pkg->srcpicked) ! check_bm = bm_checkyes; ! else ! check_bm = bm_checkno; ! SelectObject (bitmap_dc, check_bm); ! BitBlt (hdc, x + headers[SRC_COL].x, by, 11, 11, ! bitmap_dc, 0, 0, SRCCOPY); ! ! if (package[i].sdesc) ! s = package[i].sdesc; ! else ! s = package[i].name; ! TextOut (hdc, x + headers[PACKAGE_COL].x, r, s, strlen (s)); ! } ! ! if (nindexes == 0) { static char *msg = "Nothing to Install/Update"; if (source == IDC_SOURCE_DOWNLOAD) --- 287,306 ---- x = cr.left - scroll_ulc_x; y = cr.top - scroll_ulc_y + header_height; ! for (i = 0; i <= chooser->last_col ; i++) { ! TextOut (hdc, x + chooser->headers[i].x, 3, chooser->headers[i].text, chooser->headers[i].slen); ! MoveToEx (hdc, x + chooser->headers[i].x, header_height-3, &p); ! LineTo (hdc, x + chooser->headers[i].x + chooser->headers[i].width, header_height-3); } IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right, cr.bottom); ! for (ii = 0; ii < chooser->nlines; ii++) ! chooser->lines[ii].paint (hdc, x, y, ii, (chooser->get_view_mode () == VIEW_CATEGORY) ? 0 : 1); ! if (chooser->nlines == 0) { static char *msg = "Nothing to Install/Update"; if (source == IDC_SOURCE_DOWNLOAD) *************** list_hscroll (HWND hwnd, HWND hctl, UINT *** 360,368 **** static LRESULT CALLBACK list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) { ! int r; ! if (nindexes == 0) return 0; if (y < header_height) --- 385,393 ---- static LRESULT CALLBACK list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) { ! int r,refresh; ! if (chooser->nlines == 0) return 0; if (y < header_height) *************** list_click (HWND hwnd, BOOL dblclk, int *** 372,397 **** r = (y + ROW_MARGIN/2) / row_height; ! if (r < 0 || r >= nindexes) return 0; ! Package *pkg = package + package_indexes[r]; ! if (x >= headers[NEW_COL].x - (HMARGIN / 2) ! && x <= headers[NEW_COL + 1].x - (HMARGIN / 2)) ! set_action (pkg, 1); ! ! if (pkg->info[pkg->trust].source_exists ! && x >= headers[SRC_COL].x - HMARGIN / 2 ! && x <= headers[SRC_COL + 1].x - (HMARGIN / 2)) ! pkg->srcpicked ^= 1; ! ! RECT rect; ! rect.left = headers[NEW_COL].x - scroll_ulc_x; ! rect.right = headers[SRC_COL + 1].x - scroll_ulc_x; ! rect.top = header_height + r * row_height - scroll_ulc_y; ! rect.bottom = rect.top + row_height; ! InvalidateRect (hwnd, &rect, TRUE); } static LRESULT CALLBACK --- 397,434 ---- r = (y + ROW_MARGIN/2) / row_height; ! if (r < 0 || r >= chooser->nlines) return 0; ! refresh = chooser->click (r, x); ! if (refresh) ! { ! RECT r; ! GetClientRect (lv, &r); ! SCROLLINFO si; ! memset (&si, 0, sizeof (si)); ! si.cbSize = sizeof (si); ! si.fMask = SIF_ALL; /* SIF_RANGE was giving strange behaviour */ ! si.nMin = 0; ! ! si.nMax = chooser->nlines * row_height; ! si.nPage = r.bottom - header_height; ! si.nPos = scroll_ulc_y; ! SetScrollInfo (lv, SB_VERT, &si, TRUE); ! ! InvalidateRect (lv, &r, TRUE); ! ! } ! else ! { ! RECT rect; ! rect.left = chooser->headers[chooser->new_col].x - scroll_ulc_x; ! rect.right = chooser->headers[chooser->src_col + 1].x - scroll_ulc_x; ! rect.top = header_height + r * row_height - scroll_ulc_y; ! rect.bottom = rect.top + row_height; ! InvalidateRect (hwnd, &rect, TRUE); ! } } static LRESULT CALLBACK *************** register_windows (HINSTANCE hinst) *** 437,450 **** } static void ! note_width (HDC dc, char *string, int addend, int column) { if (!string) return; SIZE s; GetTextExtentPoint32 (dc, string, strlen (string), &s); ! if (headers[column].width < s.cx + addend) ! headers[column].width = s.cx + addend; } static int --- 474,487 ---- } static void ! note_width (struct _header *hdrs, HDC dc, char *string, int addend, int column) { if (!string) return; SIZE s; GetTextExtentPoint32 (dc, string, strlen (string), &s); ! if (hdrs[column].width < s.cx + addend) ! hdrs[column].width = s.cx + addend; } static int *************** set_existence () *** 487,492 **** --- 524,537 ---- } static void + fill_missing_category () + { + for (Package *pkg = package; pkg->name; pkg++) + if (!pkg->category) + add_category (pkg, register_category ("Misc")); + } + + static void default_trust (HWND h, trusts trust) { int i, t, c; *************** default_trust (HWND h, trusts trust) *** 494,499 **** --- 539,547 ---- for (Package *pkg = package; pkg->name; pkg++) { pkg->action = (actions) trust; + if (pkg->category && !(getpackagecategorybyname (pkg, "Required") || + getpackagecategorybyname (pkg, "Misc"))) + pkg->action = ACTION_SKIP; set_action (pkg, 0); } RECT r; *************** default_trust (HWND h, trusts trust) *** 503,526 **** SetFocus (nextbutton); } ! static void ! set_full_list (HWND h, int isfull) { ! int i; ! full_list = isfull; ! if (package_indexes == 0) ! package_indexes = (int *) malloc (npackages * sizeof (int)); ! nindexes = 0; ! for (Package *pkg = package; pkg->name; pkg++) ! if (!pkg->exclude) { ! set_action (pkg, 0); ! if (isfull || !is_full_action (pkg)) ! package_indexes[nindexes++] = pkg - package; } RECT r; GetClientRect (h, &r); SCROLLINFO si; --- 551,999 ---- SetFocus (nextbutton); } ! void ! pick_line::set_line (Package *_pkg) { ! pkg = _pkg; ! cat = NULL; ! } ! void ! pick_line::set_line (Category *_cat) ! { ! cat = _cat; ! pkg = NULL; ! } ! void ! pick_line::paint (HDC hdc, int x, int y, int row, int show_cat) ! { ! int r = y + row * row_height; ! int by = r + tm.tmHeight - 11; ! if (pkg) ! { ! if (pkg->installed) ! { ! TextOut (hdc, x + chooser->headers[chooser->current_col].x, r, ! pkg->installed->version, strlen (pkg->installed->version)); ! SelectObject (bitmap_dc, bm_rtarrow); ! BitBlt (hdc, x + chooser->headers[chooser->current_col].x + chooser->headers[0].width + ICON_MARGIN/2 + HMARGIN/2, by, ! 11, 11, bitmap_dc, 0, 0, SRCCOPY); ! } ! ! const char *s = choose_caption (pkg); ! TextOut (hdc, x + chooser->headers[chooser->new_col].x + NEW_COL_SIZE_SLOP, r, ! s, strlen (s)); ! SelectObject (bitmap_dc, bm_spin); ! BitBlt (hdc, x + chooser->headers[chooser->new_col].x, by, 11, 11, ! bitmap_dc, 0, 0, SRCCOPY); ! ! HANDLE check_bm; ! if (pkg->srcpicked) ! check_bm = bm_checkyes; ! else ! check_bm = bm_checkno; ! ! SelectObject (bitmap_dc, check_bm); ! BitBlt (hdc, x + chooser->headers[chooser->src_col].x, by, 11, 11, ! bitmap_dc, 0, 0, SRCCOPY); ! ! /* shows "first" category - do we want to show any? */ ! if (pkg->category && show_cat) ! TextOut (hdc, x + chooser->headers[chooser->cat_col].x, r, pkg->category->name, strlen (pkg->category->name)); ! ! if (pkg->sdesc) ! s = pkg->sdesc; ! else ! s = pkg->name; ! TextOut (hdc, x + chooser->headers[chooser->pkg_col].x, r, s, strlen (s)); ! } ! else if (cat) ! { ! TextOut (hdc, x + chooser->headers[chooser->cat_col].x, r, cat->name, strlen (cat->name)); ! } ! } ! ! int ! pick_line::click (int x) ! { ! if (pkg) ! { ! if (x >= chooser->headers[chooser->src_col].x - HMARGIN/2 && x <= chooser->headers[chooser->src_col + 1].x - HMARGIN/2) ! pkg->srcpicked ^= 1; ! ! if (x >= chooser->headers[chooser->new_col].x - (HMARGIN / 2) && x <= chooser->headers[chooser->new_col + 1].x - HMARGIN/2) { ! set_action (pkg, 1); ! /* Add any packages that are needed by this package */ ! return add_required (pkg); } + } + else if (cat) + { + /* handle the catalog being clicked ... does this belong up a level.. ? */ + } + + return 0; + } + + _view::_view (views _mode, HDC dc) + { + lines = NULL; + nlines = 0; + view_mode = VIEW_PACKAGE; + set_headers (); + init_headers (dc); + view_mode = VIEW_CATEGORY; + set_headers (); + init_headers (dc); + + view_mode = _mode; + set_headers (); + } + + void + _view::set_view_mode (views _mode) + { + if (_mode == NVIEW) + view_mode = VIEW_PACKAGE_FULL; + else + view_mode = _mode; + set_headers (); + } + + char * + _view::mode_caption () + { + switch (view_mode) + { + case VIEW_UNKNOWN: return ""; + case VIEW_PACKAGE_FULL: return "Full"; + case VIEW_PACKAGE: return "Partial"; + case VIEW_CATEGORY: return "Category"; + default: return ""; + } + } + + void + _view::set_headers (void) + { + switch (view_mode) + { + case VIEW_UNKNOWN: + return; + case VIEW_PACKAGE_FULL: + case VIEW_PACKAGE: + headers = pkg_headers; + current_col = 0; + new_col = 1; + src_col = 2; + cat_col = 3; + pkg_col = 4; + last_col = 4; + break; + case VIEW_CATEGORY: + headers = cat_headers; + current_col = 1; + new_col = 2; + src_col = 3; + cat_col = 0; + pkg_col = 4; + last_col = 4; + default: + return; + } + } + + void + _view::init_headers (HDC dc) + { + int i; + + for (i = 0; headers[i].text; i++) + headers[i].width = 0; + + for (i = 0; headers[i].text; i++) + note_width (headers, dc, headers[i].text, 0, i); + for (Package *pkg = package; pkg->name; pkg++) + { + if (pkg->installed) + { + note_width (headers, dc, pkg->installed->version, 0, current_col); + note_width (headers, dc, pkg->installed->version, NEW_COL_SIZE_SLOP, new_col); + } + for (Info *inf = pkg->infoscan; inf < pkg->infoend; inf++) + note_width (headers, dc, inf->version, NEW_COL_SIZE_SLOP, new_col); + for (Category *cat = pkg->category; cat ; cat = cat->next) + note_width (headers, dc, cat->name, 0, cat_col); + note_width (headers, dc, pkg->name, 0, pkg_col); + note_width (headers, dc, pkg->sdesc, 0, pkg_col); + } + note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP, new_col); + note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP, new_col); + + headers[0].x = HMARGIN/2; + for (i = 1; i <= last_col ; i++) + headers[i].x = headers[i-1].x + headers[i-1].width + ((i == new_col) ? NEW_COL_SIZE_SLOP : 0) + HMARGIN; + ; + } + + void + _view::insert_pkg (Package *pkg) + { + pick_line line; + line.set_line (pkg); + if (view_mode != VIEW_CATEGORY) + { + if (lines == NULL) + { + lines = (pick_line *) malloc ((npackages + ncategories) * sizeof (pick_line)); + memset (lines, '\0', (npackages + ncategories) * sizeof (pick_line) ); + nlines = 0; + insert_at (0, line); + } + else + insert_under (0, line); + } + else + { + // assert (lines); /* protect against a coding change in future */ + for (Category *cat = pkg->category; cat; cat = cat->next) + { + /* insert the package under this category in the list. If this category is not + visible, add it */ + int n=0; + while (n < nlines) + { + /* this should be a generic call to list_sort_cmp */ + if (lines[n].get_category () + && cat->name == lines[n].get_category ()->name) + insert_under (n, line); + n++; + } + if (n == nlines) + { + /* the category wasn't visible - insert at the end */ + insert_category (cat, CATEGORY_COLLAPSED); + insert_pkg (pkg); + } + } + } + } + + void + _view::insert_category (Category *cat, int collapsed) + { + pick_line line; + line.set_line (cat); + if (lines == NULL) + { + lines = (pick_line *) malloc ((npackages + ncategories) * sizeof (pick_line)); + memset (lines, '\0', (npackages + ncategories) * sizeof (pick_line) ); + nlines = 0; + insert_at (0, line); + if (!collapsed) + for (CategoryPackage *catpkg = cat->packages; catpkg; catpkg = catpkg->next) + insert_pkg (getpkgbyname (catpkg->pkg)); + } + else + { + int n=0; + while (n < nlines) + { + /* this should be a generic call to list_sort_cmp */ + if (lines[n].get_category () + && strcasecmp (cat->name, lines[n].get_category ()->name) < 0) + { + insert_at (n, line); + if (!collapsed) + for (CategoryPackage *catpkg = cat->packages; catpkg; catpkg = catpkg->next) + insert_pkg (getpkgbyname (catpkg->pkg)); + n = nlines; + } + else if (lines[n].get_category () == cat) + n = nlines; + n++; + } + if (n == nlines) + { + /* insert at the end */ + insert_at (n, line); + if (!collapsed) + for (CategoryPackage *catpkg = cat->packages; catpkg; catpkg = catpkg->next) + insert_pkg (getpkgbyname (catpkg->pkg)); + } + } + } + + /* insert a new line at line n */ + void + _view::insert_at (int n, pick_line line) + { + if (n < 0 || n > nlines) + return; + memmove (&lines[n + 1], &lines[n], (nlines - n) * sizeof (pick_line)); + lines[n] = line; + nlines++; + } + + /* insert a new line in the chooser, at the next depth in from linen */ + void + _view::insert_under (int linen, pick_line line) + { + int n; + /* special case - empty view */ + if (nlines == 0) + { + insert_at (0, line); + return; + } + /* part 1 - find the appropriate bucket beginning */ + if (lines[linen].get_category ()) + { + n = linen + 1; + } + else if (lines[linen].get_pkg ()) + { + n = linen; + /* walk up to the beginning of the bucket */ + while (n > 0 && lines[n - 1].get_pkg ()) + n--; + } + /* part 2 - insert in sorted order in the bucket */ + while (n < nlines) + { + if (lines[n].get_category () || (lines[n].get_pkg () + && strcasecmp (line.get_pkg ()->name, lines[n].get_pkg ()->name) < 0)) + { + insert_at (n, line); + n = nlines; + } + else if (lines[n].get_pkg () == line.get_pkg ()) + { + n = nlines; + } + n++; + } + if (n == nlines) + { + /* insert at the end of this bucket */ + insert_at (n, line); + } + } + + void + _view::clear_view (void) + { + nlines = 0; + } + + static views + viewsplusplus(views theview) + { + switch (theview) + { + case VIEW_UNKNOWN: return VIEW_PACKAGE_FULL; + case VIEW_PACKAGE_FULL: return VIEW_PACKAGE; + case VIEW_PACKAGE: return VIEW_CATEGORY; + case VIEW_CATEGORY: return NVIEW; + default: return VIEW_UNKNOWN; + } + } + + int + _view::click (int row, int x) + { + if (row > nlines) + return 0; + if (lines[row].get_pkg ()) + return lines[row].click (x); + else + { + /* if we are the last line or the next line is a category too, expand */ + if (row == (nlines -1) || lines[row + 1].get_category ()) + { + int count = nlines; + for (CategoryPackage *catpkg = lines[row].get_category ()->packages; catpkg; catpkg = catpkg->next) + { + Package * pkg = getpkgbyname (catpkg->pkg); + int n = row + 1; + pick_line line; + line.set_line (pkg); + /* this is a nasty hack. It will go away when the hierarchy is coded */ + while (n < nlines) + { + if (lines[n].get_category () || (lines[n].get_pkg () + && strcasecmp (pkg->name, lines[n].get_pkg ()->name) < 0)) + { + insert_at (n, line); + n = nlines; + } + else if (lines[n].get_pkg () == pkg) + { + n = nlines; + } + n++; + } + if (n == nlines) + { + /* insert at the end of this category */ + insert_at (n, line); + n=nlines + 1; + } + } + return nlines - count; + } + else + /* contract */ + { + int count = 0, n = row + 1; + while (n < nlines &! lines[n].get_category ()) + { + memmove (&lines[n], &lines[n + 1], (nlines - n) * sizeof (pick_line)); + nlines--; + count++; + } + return count; + } + } + } + + static void + set_view_mode (HWND h, views mode) + { + int i; + chooser->set_view_mode (mode); + + chooser->clear_view (); + for (Package *pkg = package; pkg->name; pkg++) + if (!pkg->exclude) + { + set_action (pkg, 0); + } + + switch (chooser->get_view_mode ()) + { + case VIEW_PACKAGE: + for (Package *pkg = package; pkg->name; pkg++) + if (!pkg->exclude && is_download_action (pkg)) + chooser->insert_pkg (pkg); + break; + case VIEW_PACKAGE_FULL: + for (Package *pkg = package; pkg->name; pkg++) + if (!pkg->exclude) + chooser->insert_pkg (pkg); + break; + case VIEW_CATEGORY: + /* start collapsed. TODO: make this a chooser flag */ + for (Category *cat = category; cat; cat = cat->next) + chooser->insert_category (cat, CATEGORY_COLLAPSED); + break; + default: + break; + } + RECT r; GetClientRect (h, &r); SCROLLINFO si; *************** set_full_list (HWND h, int isfull) *** 528,538 **** si.cbSize = sizeof (si); si.fMask = SIF_ALL; si.nMin = 0; ! si.nMax = headers[2].x + headers[2].width + HMARGIN; si.nPage = r.right; SetScrollInfo (h, SB_HORZ, &si, TRUE); ! si.nMax = nindexes * row_height; si.nPage = r.bottom - header_height; SetScrollInfo (h, SB_VERT, &si, TRUE); --- 1001,1011 ---- si.cbSize = sizeof (si); si.fMask = SIF_ALL; si.nMin = 0; ! si.nMax = chooser->headers[chooser->last_col].x + chooser->headers[chooser->last_col].width + HMARGIN; si.nPage = r.right; SetScrollInfo (h, SB_HORZ, &si, TRUE); ! si.nMax = chooser->nlines * row_height; si.nPage = r.bottom - header_height; SetScrollInfo (h, SB_VERT, &si, TRUE); *************** create_listview (HWND dlg, RECT *r) *** 559,568 **** hinstance, 0); ShowWindow (lv, SW_SHOW); - - for (i = 0; headers[i].text; i++) - headers[i].width = 0; - HDC dc = GetDC (lv); sysfont = GetStockObject (DEFAULT_GUI_FONT); SelectObject (dc, sysfont); --- 1032,1037 ---- *************** create_listview (HWND dlg, RECT *r) *** 575,607 **** int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN; if (row_height < irh) row_height = irh; - - for (i = 0; headers[i].text; i++) - note_width (dc, headers[i].text, 0, i); - for (Package *pkg = package; pkg->name; pkg++) - { - if (pkg->installed) - { - note_width (dc, pkg->installed->version, 0, CURRENT_COL); - note_width (dc, pkg->installed->version, NEW_COL_SIZE_SLOP, NEW_COL); - } - for (Info *inf = pkg->infoscan; inf < pkg->infoend; inf++) - note_width (dc, inf->version, NEW_COL_SIZE_SLOP, NEW_COL); - note_width (dc, pkg->name, 0, PACKAGE_COL); - note_width (dc, pkg->sdesc, 0, PACKAGE_COL); - } - note_width (dc, "keep", NEW_COL_SIZE_SLOP, NEW_COL); - note_width (dc, "uninstall", NEW_COL_SIZE_SLOP, NEW_COL); - - headers[CURRENT_COL].x = HMARGIN/2; - headers[NEW_COL].x = headers[CURRENT_COL].x + headers[CURRENT_COL].width + - NEW_COL_SIZE_SLOP + HMARGIN; - headers[SRC_COL].x = headers[NEW_COL].x + headers[NEW_COL].width + HMARGIN; - headers[PACKAGE_COL].x = headers[SRC_COL].x + headers[SRC_COL].width + - HMARGIN; default_trust (lv, TRUST_CURR); ! set_full_list (lv, full_list); static int ta[] = { IDC_CHOOSE_CURR, 0 }; rbset (dlg, ta, IDC_CHOOSE_CURR); --- 1044,1058 ---- int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN; if (row_height < irh) row_height = irh; + chooser = new (view) (VIEW_PACKAGE, dc); + default_trust (lv, TRUST_CURR); ! set_view_mode (lv, VIEW_PACKAGE); ! if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption())) ! log (LOG_BABBLE, "Failed to set View button caption %d", GetLastError() ); ! for (Package *foo = package; foo->name; foo++) ! add_required(foo); static int ta[] = { IDC_CHOOSE_CURR, 0 }; rbset (dlg, ta, IDC_CHOOSE_CURR); *************** dialog_cmd (HWND h, int id, HWND hwndctl *** 615,632 **** { case IDC_CHOOSE_PREV: default_trust (lv, TRUST_PREV); ! set_full_list (lv, full_list); break; case IDC_CHOOSE_CURR: default_trust (lv, TRUST_CURR); ! set_full_list (lv, full_list); break; case IDC_CHOOSE_EXP: default_trust (lv, TRUST_TEST); ! set_full_list (lv, full_list); break; ! case IDC_CHOOSE_FULLPART: ! set_full_list (lv, !full_list); break; case IDOK: --- 1066,1091 ---- { case IDC_CHOOSE_PREV: default_trust (lv, TRUST_PREV); ! for (Package *foo = package; foo->name; foo++) ! add_required(foo); ! set_view_mode (lv, chooser->get_view_mode ()); break; case IDC_CHOOSE_CURR: default_trust (lv, TRUST_CURR); ! for (Package *foo = package; foo->name; foo++) ! add_required(foo); ! set_view_mode (lv, chooser->get_view_mode ()); break; case IDC_CHOOSE_EXP: default_trust (lv, TRUST_TEST); ! for (Package *foo = package; foo->name; foo++) ! add_required(foo); ! set_view_mode (lv, chooser->get_view_mode ()); break; ! case IDC_CHOOSE_VIEW: ! set_view_mode (lv, viewsplusplus (chooser->get_view_mode ())); ! if (!SetDlgItemText (h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption())) ! log (LOG_BABBLE, "Failed to set View button caption %d", GetLastError() ); break; case IDOK: *************** getpkgbyname (const char *pkgname) *** 804,809 **** --- 1263,1290 ---- return NULL; } + /* Return a pointer to a category given the name. */ + Category * + getcategorybyname (const char *categoryname) + { + for (Category *cat = category; cat; cat=cat->next) + if (strcasecmp (cat->name, categoryname) == 0) + return cat; + + return NULL; + } + + /* Return a pointer to a category of a given package given the name. */ + Category * + getpackagecategorybyname (Package *pkg, const char *categoryname) + { + for (Category *cat = pkg->category; cat; cat = cat->next) + if (strcasecmp (cat->name, categoryname) == 0) + return cat; + + return NULL; + } + static void scan2 (char *path, unsigned int size) { *************** package_sort (const void *va, const void *** 936,942 **** { Package *a = (Package *)va; Package *b = (Package *)vb; ! return strcmp (a->name, b->name); } void --- 1417,1423 ---- { Package *a = (Package *)va; Package *b = (Package *)vb; ! return strcasecmp (a->name, b->name); } void *************** do_choose (HINSTANCE h) *** 963,968 **** --- 1444,1450 ---- read_installed_db (); set_existence (); + fill_missing_category (); qsort (package, npackages, sizeof (package[0]), package_sort); *************** do_choose (HINSTANCE h) *** 986,995 **** : "unknown"); const char *excluded = (pkg->exclude ? "yes" : "no"); ! log (LOG_BABBLE, ! "[%s] action=%s trust=%s installed=%s excluded=%s src?=%s", ! pkg->name, action, trust, installed, ! excluded, pkg->srcpicked ? "yes" : "no"); for (int t = 1; t < NTRUST; t++) { if (pkg->info[t].install) --- 1468,1476 ---- : "unknown"); const char *excluded = (pkg->exclude ? "yes" : "no"); ! log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s excluded=%s src?=%s" ! "category=%s", pkg->name, action, trust, installed, ! excluded, pkg->srcpicked ? "yes" : "no", pkg->category); for (int t = 1; t < NTRUST; t++) { if (pkg->info[t].install) Index: ini.h =================================================================== RCS file: /cvs/uberbaum/winsup/cinstall/ini.h,v retrieving revision 2.13 diff -p -r2.13 ini.h *** ini.h 2001/06/25 05:48:38 2.13 --- ini.h 2001/06/29 21:24:28 *************** *** 13,18 **** --- 13,21 ---- * */ + #ifndef _INI_H_ + #define _INI_H_ + /* When setup.ini is parsed, the information is stored according to the declarations here. ini.cc (via inilex and iniparse) initializes these structures. choose.cc sets the action and trust *************** typedef enum *** 62,67 **** --- 65,79 ---- EXCLUDE_NOT_FOUND } excludes; + typedef enum + { + VIEW_UNKNOWN, + VIEW_PACKAGE_FULL, + VIEW_PACKAGE, + VIEW_CATEGORY, + NVIEW + } views; + #define is_download_action(pkg) \ ((pkg)->action == ACTION_PREV || \ (pkg)->action == ACTION_CURR || \ *************** typedef struct _Info *** 101,106 **** --- 113,131 ---- #endif } Info; /* +1 for TRUST_UNKNOWN */ + typedef struct _CategoryPackage + { + struct _CategoryPackage *next; /* The next package pointer in the list */ + char *pkg; /* This should be Package *, but the packages can move*/ + } CategoryPackage; + + typedef struct _Category + { + struct _Category *next; /* the next category in the list */ + char *name; /* the category */ + CategoryPackage *packages; /* the packages in this category */ + } Category; + typedef struct _Dependency { struct _Dependency *next; /* the next package in this dependency list */ *************** typedef struct *** 112,118 **** char *name; /* package name, like "cygwin" */ char *sdesc; /* short description (replaces "name" if provided) */ char *ldesc; /* long description (multi-line) */ ! char *category; /* the category the package belongs to, like "required" or "XFree86" */ Dependency *required; /* the packages required for this package to work */ actions action; /* A range of states applicable to this package */ trusts trust; /* Selects among info[] below, a subset of action */ --- 137,143 ---- char *name; /* package name, like "cygwin" */ char *sdesc; /* short description (replaces "name" if provided) */ char *ldesc; /* long description (multi-line) */ ! Category *category; /* the categories the package belongs to */ Dependency *required; /* the packages required for this package to work */ actions action; /* A range of states applicable to this package */ trusts trust; /* Selects among info[] below, a subset of action */ *************** typedef struct *** 133,138 **** --- 158,165 ---- extern Package *package; extern int npackages; + extern Category *category; + extern int ncategories; #ifdef __cplusplus extern "C" { *************** Package *new_package (char *name); *** 142,148 **** --- 169,181 ---- void ini_init (char *string); Package *getpkgbyname (const char *pkgname); void new_requirement (Package *package, char *dependson); + Category *getcategorybyname (const char *categoryname); + Category *getpackagecategorybyname (Package *pkg, const char *categoryname); + Category *register_category (char *name); + void add_category (Package *package, Category *cat); #ifdef __cplusplus } #endif + + #endif /* _INI_H_ */ Index: iniparse.y =================================================================== RCS file: /cvs/uberbaum/winsup/cinstall/iniparse.y,v retrieving revision 2.9 diff -p -r2.9 iniparse.y *** iniparse.y 2001/06/15 04:05:31 2.9 --- iniparse.y 2001/06/29 21:24:28 *************** simple_line *** 86,92 **** : VERSION STRING { cpt->version = $2; } | SDESC STRING { cp->sdesc = $2; } | LDESC STRING { cp->ldesc = $2; } ! | CATEGORY STRING { cp->category = $2; } | REQUIRES requires | INSTALL STRING STRING { cpt->install = $2; cpt->install_size = atoi($3); --- 86,93 ---- : VERSION STRING { cpt->version = $2; } | SDESC STRING { cp->sdesc = $2; } | LDESC STRING { cp->ldesc = $2; } ! | CATEGORY STRING { add_category (cp, register_category ($2)); ! } | REQUIRES requires | INSTALL STRING STRING { cpt->install = $2; cpt->install_size = atoi($3); *************** requires *** 121,131 **** Package *package = NULL; int npackages = 0; static int maxpackages = 0; Package * new_package (char *name) { ! if (package == 0) maxpackages = npackages = 0; if (npackages >= maxpackages) { --- 122,134 ---- Package *package = NULL; int npackages = 0; static int maxpackages = 0; + Category *category = NULL; + int ncategories = 0; Package * new_package (char *name) { ! if (package == NULL) maxpackages = npackages = 0; if (npackages >= maxpackages) { *************** new_package (char *name) *** 149,155 **** } void ! new_requirement(Package *package, char *dependson) { Dependency *dp; if (!dependson) --- 152,158 ---- } void ! new_requirement (Package *package, char *dependson) { Dependency *dp; if (!dependson) *************** new_requirement(Package *package, char * *** 158,161 **** --- 161,218 ---- dp->next = cp->required; dp->package = dependson; cp->required = dp; + } + + Category * + register_category (char *name) + { + Category *tempcat; + if (category == NULL) + ncategories = 0; + tempcat = getcategorybyname (name); + if (!tempcat) + { + Category *sortcat = category; + tempcat = new (Category); + memset (tempcat, '\0', sizeof (Category)); + tempcat->name = strdup (name); + if (!sortcat || strcasecmp(sortcat->name, name) > 0) + { + tempcat->next = category; + category = tempcat; + } + else + { + while (sortcat->next && + strcasecmp(sortcat->next->name, tempcat->name) < 0) + { + tempcat->next = sortcat->next; + sortcat->next = tempcat; + } + } + ncategories++; + } + return tempcat; + } + + void + add_category (Package *package, Category *cat) + { + /* add a new record for the package list */ + /* TODO: alpabetical inserts ? */ + Category *tempcat; + CategoryPackage *templink; + tempcat = new (Category); + memset (tempcat, '\0', sizeof (Category)); + tempcat->next = package->category; + tempcat->name = cat->name; + package->category = tempcat; + + templink = new (CategoryPackage); + templink->next = cat->packages; + templink->pkg = package->name; + cat->packages = templink; + + /* hack to ensure we allocate enough space */ + ncategories++; } Index: res.rc =================================================================== RCS file: /cvs/uberbaum/winsup/cinstall/res.rc,v retrieving revision 2.20 diff -p -r2.20 res.rc *** res.rc 2001/05/28 08:31:02 2.20 --- res.rc 2001/06/29 21:24:28 *************** BEGIN *** 240,246 **** CONTROL "SPIN",IDC_STATIC,"Static",SS_BITMAP,55,170,15,13 LTEXT "= click to choose action, (p) = previous version, (x) = experimental", IDC_STATIC,65,170,220,8 ! PUSHBUTTON "Full/Part",IDC_CHOOSE_FULLPART,283,5,35,10 CONTROL "E&xp",IDC_CHOOSE_EXP,"Button",BS_AUTORADIOBUTTON | WS_GROUP,248,5,25,10 CONTROL "&Curr",IDC_CHOOSE_CURR,"Button",BS_AUTORADIOBUTTON,222, --- 240,247 ---- CONTROL "SPIN",IDC_STATIC,"Static",SS_BITMAP,55,170,15,13 LTEXT "= click to choose action, (p) = previous version, (x) = experimental", IDC_STATIC,65,170,220,8 ! PUSHBUTTON "View",IDC_CHOOSE_VIEW,278,5,20,10 ! LTEXT "", IDC_CHOOSE_VIEWCAPTION, 300,5,30,10 CONTROL "E&xp",IDC_CHOOSE_EXP,"Button",BS_AUTORADIOBUTTON | WS_GROUP,248,5,25,10 CONTROL "&Curr",IDC_CHOOSE_CURR,"Button",BS_AUTORADIOBUTTON,222, Index: resource.h =================================================================== RCS file: /cvs/uberbaum/winsup/cinstall/resource.h,v retrieving revision 2.11 diff -p -r2.11 resource.h *** resource.h 2001/05/28 08:31:02 2.11 --- resource.h 2001/06/29 21:24:28 *************** *** 84,90 **** #define IDC_NET_PASSWD 1031 #define IDC_VERSION 1033 #define IDC_LISTVIEW_POS 1034 ! #define IDC_CHOOSE_FULLPART 1035 #define IDC_CHOOSE_EXP 1036 #define IDC_CHOOSE_CURR 1037 #define IDC_CHOOSE_PREV 1038 --- 84,90 ---- #define IDC_NET_PASSWD 1031 #define IDC_VERSION 1033 #define IDC_LISTVIEW_POS 1034 ! #define IDC_CHOOSE_VIEW 1035 #define IDC_CHOOSE_EXP 1036 #define IDC_CHOOSE_CURR 1037 #define IDC_CHOOSE_PREV 1038 *************** *** 100,105 **** --- 100,106 ---- #define IDC_DLS_PPROGRESS_TEXT 1048 #define IDC_DLS_IPROGRESS_TEXT 1049 #define IDC_CHOOSE_INST_TEXT 1050 + #define IDC_CHOOSE_VIEWCAPTION 1051 #define IDC_STATIC -1 // Next default values for new objects *************** *** 110,116 **** #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 127 #define _APS_NEXT_COMMAND_VALUE 40003 ! #define _APS_NEXT_CONTROL_VALUE 1051 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif --- 111,117 ---- #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 127 #define _APS_NEXT_COMMAND_VALUE 40003 ! #define _APS_NEXT_CONTROL_VALUE 1052 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif