delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2001/06/29/20:51:17

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-developers-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-developers-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com
Message-ID: <032001c100fe$d62310c0$806410ac@local>
From: "Robert Collins" <robert DOT collins AT itdomain DOT com DOT au>
To: <cygwin-developers AT cygwin DOT com>, <cygwin-patches AT cygwin DOT com>
References: <04e801c0faa2$f9008260$0200a8c0 AT lifelesswks> <20010621222615 DOT C13746 AT redhat DOT com> <3B3324A7 DOT 49FFC98A AT yahoo DOT com> <054c01c0fbef$5f600e20$0200a8c0 AT lifelesswks> <06a001c0fc51$7a87e210$0200a8c0 AT lifelesswks> <20010629114004 DOT A6990 AT redhat DOT com> <VA DOT 00000842 DOT 01fd0b44 AT thesoftwaresource DOT com> <20010629172912 DOT A8991 AT redhat DOT com>
Subject: Re: hierarchy in setup (category stuff)
Date: Sat, 30 Jun 2001 10:51:44 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4522.1200
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200
X-OriginalArrivalTime: 30 Jun 2001 00:39:21.0654 (UTC) FILETIME=[1AA08D60:01C100FD]

This is a multi-part message in MIME format.

------=_NextPart_000_031D_01C10152.A6F4ED60
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

This is what I've got right now.

>Known bugs:
>1) The partial view when you enter the package list has a scroll bar one
>line too many long.

Not addressed. May not be present with the default view now categories.

>2) The category view always shows _all_ packages. There's no
>category-partial view. Do we need one?

not addressed.

3) I haven't added the lex rule for multi category parsing yet (but the
suporting c code is there.

I've changed the default view to categories. (It's the view constructor
call).

> >> I just played with this and I like what I see.
> >>
> >> I had a hard time getting all of the changes into the current CVS,
though,
> >> and the view was sort of screwed up.

clean patch attached.

> Either way, there would still be problems.  I think that they are mainly
because
> of Michael's white space fixes.
>
> I sometimes wish that we had a C/C++ aware version of patch.

My .2c: update your CVS server. I have much much less problems with merges
with the sourceforge CVS server.

> >> Robert, if you are still interested, then I think that this is
definitely the
> >> way to go.  If you have something worth checking in, then please do so.

I'll draw up change log stuff and send something to cygwin-patches... or did
you want me to hit CVS directly?

> I've included a new patch below.  I took another stab at this and found
that I'd
> wiped out a huge chunk of a function.  setup.exe seems to work much better
now.
>
> I've also included a setup.ini with categories.  I haven't added
dependencies yet.
>
> I'm thinking that we should just nuke the "latest" and "contrib"
directories and
> create directories based on the name of the categories.

I don't think we even need separate directories - they don't do much once
the package system manages the view :].

Rob

------=_NextPart_000_031D_01C10152.A6F4ED60
Content-Type: application/octet-stream;
	name="choose.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="choose.h"

/*=0A=
 * Copyright (c) 2000, Red Hat, Inc.=0A=
 *=0A=
 *     This program is free software; you can redistribute it and/or =
modify=0A=
 *     it under the terms of the GNU General Public License as published =
by=0A=
 *     the Free Software Foundation; either version 2 of the License, or=0A=
 *     (at your option) any later version.=0A=
 *=0A=
 *     A copy of the GNU General Public License can be found at=0A=
 *     http://www.gnu.org/=0A=
 *=0A=
 * Written by Robert Collins <rbtcollins AT hotmail DOT com>=0A=
 *=0A=
 */=0A=
=0A=
#ifndef _CHOOSE_H_=0A=
#define _CHOOSE_H_=0A=
=0A=
#include "ini.h"=0A=
=0A=
#define CATEGORY_EXPANDED  0=0A=
#define CATEGORY_COLLAPSED 1=0A=
=0A=
=0A=
struct _header=0A=
{=0A=
  char *text;=0A=
  int slen;=0A=
  int width;=0A=
  int x;=0A=
};=0A=
=0A=
typedef class _view view;=0A=
=0A=
class pick_line=0A=
{=0A=
  public:=0A=
    void set_line (Package *_pkg);=0A=
    void set_line (Category *_cat);=0A=
    void paint (HDC hdc, int x, int y, int row, int show_cat);=0A=
    Package *get_pkg (void) { return pkg; };=0A=
    Category *get_category (void) { return cat; };=0A=
    int click (int x);=0A=
  private:=0A=
    Package *pkg;=0A=
    Category *cat;=0A=
};=0A=
=0A=
class _view=0A=
{=0A=
  public:=0A=
    int num_columns;=0A=
    views get_view_mode () { return view_mode; };=0A=
    void set_view_mode(views _mode);=0A=
    struct _header *headers;=0A=
    _view (views mode, HDC dc);=0A=
    char *mode_caption ();=0A=
    void insert_pkg (Package *);=0A=
    void insert_category (Category *, int);=0A=
    void clear_view (void);=0A=
    int click (int row, int x);=0A=
    int current_col;=0A=
    int new_col;=0A=
    int src_col;=0A=
    int cat_col;=0A=
    int pkg_col;=0A=
    int last_col;=0A=
    pick_line * lines;=0A=
    int nlines;=0A=
=0A=
  private:=0A=
    views view_mode;=0A=
    void set_headers (void);=0A=
    void init_headers (HDC dc);=0A=
    void insert_at (int, pick_line);=0A=
    void insert_under (int linen, pick_line line); =0A=
=0A=
};=0A=
=0A=
#endif /* _CHOOSE_H_ */=0A=

------=_NextPart_000_031D_01C10152.A6F4ED60
Content-Type: application/octet-stream;
	name="currentsetup.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="currentsetup.patch"

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

------=_NextPart_000_031D_01C10152.A6F4ED60--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019