root/branches/2.10/src/choose.cc

Revision 608, 19.7 kB (checked in by kose, 4 years ago)

* version.c: 2.10.5.
* res-ja.rc (IDS_MIRROR_LST): set URL.
* res.rc (IDS_MIRROR_LST): Ditto.
* reginfo.h (XEMACS_SETUP_DIR): set dir packages/setup.
* postinstall.cc (do_postinstall): set dir $MEADOW/packages/pkginfo.

  • Property svn:executable set to
Line 
1 /*
2  * Copyright (c) 2000, Red Hat, Inc.
3  *
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  *
9  *     A copy of the GNU General Public License can be found at
10  *     http://www.gnu.org/
11  *
12  * Written by DJ Delorie <dj@cygnus.com>
13  *
14  */
15
16 /* The purpose of this file is to let the user choose which packages
17    to install, and which versions of the package when more than one
18    version is provided.  The "trust" level serves as an indication as
19    to which version should be the default choice.  At the moment, all
20    we do is compare with previously installed packages to skip any
21    that are already installed (by setting the action to ACTION_SAME).
22    While the "trust" stuff is supported, it's not really implemented
23    yet.  We always prefer the "current" option.  In the future, this
24    file might have a user dialog added to let the user choose to not
25    install packages, or to install packages that aren't installed by
26    default. */
27
28 #include "win32.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32
33 #include "dialog.h"
34 #include "resource.h"
35 #include "state.h"
36 #include "ini.h"
37 #include "concat.h"
38 #include "msg.h"
39 #include "log.h"
40 #include "find.h"
41 #include "reginfo.h"
42
43 #define HMARGIN         10
44 #define ROW_MARGIN      5
45 #define ICON_MARGIN     4
46
47 #define CHECK_SIZE      11
48
49 #define TRUST_KEEP      101
50 #define TRUST_UNINSTALL 102
51 #define TRUST_NONE      103
52
53 static int initialized = 0;
54
55 static int full_list = 0;
56
57 static int scroll_ulc_x, scroll_ulc_y;
58
59 static HWND lv, nextbutton;
60 static TEXTMETRIC tm;
61 static int header_height;
62 static HANDLE sysfont;
63 static int row_height;
64 static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna;
65 static HDC bitmap_dc;
66
67 static struct {
68   char *text;
69   int slen;
70   int width;
71   int x;
72 } headers[] = {
73   { "Current", 7, 0, 0 },
74 #define CURRENT_COL 0
75   { "New", 3, 0, 0 },
76 #define NEW_COL 1
77   { "Src?", 4, 0, 0 },
78 #define SRC_COL 2
79   { "Package", 7, 0, 0 },
80 #define PACKAGE_COL 3
81   { 0, 0, 0, 0 }
82 };
83 #define NUM_COLUMNS (sizeof(headers)/(sizeof(headers[0]))-1)
84
85 int *package_indexes, nindexes;
86
87 struct ExtraPackageInfo {
88   char *installed_file; /* filename of previous "install" file */
89   char *installed_ver;  /* version part */
90   int   installed_size; /* ditto, size. */
91
92   int in_partial_list;
93   int pick;
94   int npick;
95   int which_is_installed; /* == TRUST* or -1 */
96
97   struct {
98     int src_avail;
99     int trust;          /* may be keep or uninstall */
100     char *caption;      /* ==0 at EOL */
101   } chooser[NTRUST+3];  /* one extra for NULL above */
102 };
103
104 static ExtraPackageInfo *extra;
105
106 static void
107 paint (HWND hwnd)
108 {
109   HDC hdc;
110   PAINTSTRUCT ps;
111   int x, y, i, ii;
112
113   hdc = BeginPaint (hwnd, &ps);
114
115   SelectObject (hdc, sysfont);
116
117   RECT cr;
118   GetClientRect (hwnd, &cr);
119
120   POINT p;
121
122   x = cr.left - scroll_ulc_x;
123   y = cr.top - scroll_ulc_y + header_height;
124
125
126   for (i=0; headers[i].text; i++)
127     {
128       TextOut (hdc, x+headers[i].x, 3, headers[i].text, headers[i].slen);
129       MoveToEx (hdc, x+headers[i].x, header_height-3, &p);
130       LineTo (hdc, x+headers[i].x+headers[i].width, header_height-3);
131     }
132
133   IntersectClipRect (hdc, cr.left, cr.top+header_height, cr.right, cr.bottom);
134
135   for (ii=0; ii<nindexes; ii++)
136     {
137       i = package_indexes[ii];
138       int r = y + ii * row_height;
139       int by = r + tm.tmHeight - 11;
140       if (extra[i].installed_ver && extra[i].installed_ver[0])
141         {
142           TextOut (hdc, x+headers[CURRENT_COL].x, r,
143                    extra[i].installed_ver, strlen (extra[i].installed_ver));
144           SelectObject (bitmap_dc, bm_rtarrow);
145           BitBlt (hdc, x+headers[CURRENT_COL].x+headers[0].width+ICON_MARGIN/2+HMARGIN/2, by,
146                   11, 11, bitmap_dc, 0, 0, SRCCOPY);
147         }
148
149       char *s = extra[i].chooser[extra[i].pick].caption;
150       if (s)
151         {
152           TextOut (hdc, x+headers[NEW_COL].x + 11 + ICON_MARGIN, r,
153                    s, strlen (s));
154           if (extra[i].npick > 1)
155             {
156               SelectObject (bitmap_dc, bm_spin);
157               BitBlt (hdc, x+headers[NEW_COL].x, by, 11, 11,
158                       bitmap_dc, 0, 0, SRCCOPY);
159             }
160         }
161
162       HANDLE check_bm = bm_checkna;
163       if (extra[i].chooser[extra[i].pick].src_avail)
164         {
165           if (package[i].srcaction == SRCACTION_NO)
166             check_bm = bm_checkno;
167           else if (package[i].srcaction == SRCACTION_YES)
168             check_bm = bm_checkyes;
169         }
170       SelectObject (bitmap_dc, check_bm);
171       BitBlt (hdc, x+headers[SRC_COL].x, by, 11, 11,
172               bitmap_dc, 0, 0, SRCCOPY);
173
174       if (package[i].name)
175         TextOut (hdc, x+headers[PACKAGE_COL].x, r, package[i].name, strlen(package[i].name));
176     }
177
178   if (nindexes == 0)
179     {
180       static char *m = "Nothing to Install/Update";
181       TextOut (hdc, HMARGIN, header_height, m, strlen (m));
182     }
183  
184   EndPaint (hwnd, &ps);
185 }
186
187 static void
188 scroll_common (HWND hwnd, int which, int *var, int code)
189 {
190   SCROLLINFO si;
191   si.cbSize = sizeof (si);
192   si.fMask = SIF_ALL;
193   GetScrollInfo (hwnd, which, &si);
194
195   switch (code)
196     {
197     case SB_THUMBTRACK:
198       si.nPos = si.nTrackPos;
199       break;
200     case SB_THUMBPOSITION:
201       break;
202     case SB_BOTTOM:
203       si.nPos = si.nMax;
204       break;
205     case SB_TOP:
206       si.nPos = 0;
207       break;
208     case SB_LINEDOWN:
209       si.nPos += row_height;
210       break;
211     case SB_LINEUP:
212       si.nPos -= row_height;
213       break;
214     case SB_PAGEDOWN:
215       si.nPos += si.nPage * 9/10;
216       break;
217     case SB_PAGEUP:
218       si.nPos -= si.nPage * 9/10;
219       break;
220     }
221
222   if ((int)si.nPos < 0)
223     si.nPos = 0;
224   if ((int)(si.nPos + si.nPage) > si.nMax)
225     si.nPos = si.nMax - si.nPage;
226
227   si.fMask = SIF_POS;
228   SetScrollInfo (hwnd, which, &si, TRUE);
229
230   int ox = scroll_ulc_x;
231   int oy = scroll_ulc_y;
232   *var = si.nPos;
233
234   RECT cr, sr;
235   GetClientRect (hwnd, &cr);
236   sr = cr;
237   sr.top += header_height;
238   ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
239   sr.bottom = sr.top;
240   sr.top = cr.top;
241   ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
242 }
243
244 static LRESULT CALLBACK
245 list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos)
246 {
247   scroll_common (hwnd, SB_VERT, &scroll_ulc_y, code);
248   return FALSE;
249 }
250
251 static LRESULT CALLBACK
252 list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos)
253 {
254   scroll_common (hwnd, SB_HORZ, &scroll_ulc_x, code);
255   return FALSE;
256 }
257
258 static LRESULT CALLBACK
259 list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode)
260 {
261   int r;
262
263   if (nindexes == 0)
264     return 0;
265
266   if (y < header_height)
267     return 0;
268   x += scroll_ulc_x;
269   y += scroll_ulc_y - header_height;
270
271   r = (y + ROW_MARGIN/2) / row_height;
272
273   if (r < 0 || r >= npackages)
274     return 0;
275
276   int p = package_indexes[r];
277
278   if (x >= headers[NEW_COL].x - HMARGIN/2 && x <= headers[NEW_COL+1].x - HMARGIN/2)
279     {
280       extra[p].pick ++;
281       if (extra[p].chooser[extra[p].pick].caption == 0)
282         extra[p].pick = 0;
283     }
284
285   if (x >= headers[SRC_COL].x - HMARGIN/2 && x <= headers[SRC_COL+1].x - HMARGIN/2)
286     {
287       if (extra[p].chooser[extra[p].pick].src_avail)
288         package[p].srcaction ^= (SRCACTION_NO^SRCACTION_YES);
289     }
290
291   RECT rect;
292   rect.left = headers[NEW_COL].x - scroll_ulc_x;
293   rect.right = headers[SRC_COL+1].x - scroll_ulc_x;
294   rect.top = header_height + r * row_height - scroll_ulc_y;
295   rect.bottom = rect.top + row_height;
296   InvalidateRect (hwnd, &rect, TRUE);
297   return FALSE;
298 }
299
300 static LRESULT CALLBACK
301 listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
302 {
303   switch (message) {
304   case WM_HSCROLL:
305     return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll);
306   case WM_VSCROLL:
307     return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll);
308   case WM_LBUTTONDOWN:
309     return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click);
310   case WM_PAINT:
311     paint (hwnd);
312     return 0;
313   default:
314     return DefWindowProc (hwnd, message, wParam, lParam);
315   }
316 }
317
318 static void
319 register_windows (HINSTANCE hinst)
320 {
321   WNDCLASSEX wcex;
322   static int done = 0;
323
324   if (done)
325     return;
326   done = 1;
327
328   memset (&wcex, 0, sizeof (wcex));
329   wcex.cbSize = sizeof (WNDCLASSEX);
330   wcex.style = CS_HREDRAW | CS_VREDRAW;
331   wcex.lpfnWndProc = listview_proc;
332   wcex.hInstance = hinst;
333   wcex.hIcon = LoadIcon (0, IDI_APPLICATION);
334   wcex.hCursor = LoadCursor (0, IDC_ARROW);
335   wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
336   wcex.lpszClassName = "listview";
337
338   RegisterClassEx (&wcex);
339 }
340
341 static void
342 note_width (HDC dc, char *string, int addend, int column)
343 {
344   if (!string)
345     return;
346   SIZE s;
347   GetTextExtentPoint32 (dc, string, strlen (string), &s);
348   if (headers[column].width < s.cx + addend)
349     headers[column].width = s.cx + addend;
350 }
351
352 static int
353 best_trust (int p, int trust)
354 {
355   int t;
356   for (t=trust; t>=0; t--)
357     if (package[p].info[t].install)
358       return t;
359   for (t=trust+1; t<=NTRUST; t++)
360     if (package[p].info[t].install)
361       return t;
362   if (extra[p].installed_file)
363     return TRUST_KEEP;
364   return TRUST_NONE;
365 }
366
367 static void
368 default_trust (HWND h, int trust)
369 {
370   int i, t, c;
371
372   for (i=0; i<npackages; i++)
373     {
374       t = best_trust (i, trust);
375       extra[i].pick = 1;
376       for (c=0; c<extra[i].npick; c++)
377         if (t == extra[i].chooser[c].trust)
378           extra[i].pick = c;
379       if (install_type == IDC_INSTALL_NATIVE
380           && package[i].type == TY_CYGWIN
381           ||
382           install_type == IDC_INSTALL_CYGWIN
383           && package[i].type == TY_NATIVE)
384         extra[i].pick = extra[i].npick -1;
385       if (!extra[i].installed_file
386           && strncmp(package[i].name, "Meadow", 6)
387           && strncmp(package[i].name, "imagemagick", 12)
388           && strncmp(package[i].name, "misc", 4))
389         extra[i].pick = extra[i].npick -1;
390     }
391   RECT r;
392   GetClientRect (h, &r);
393   InvalidateRect (h, &r, TRUE);
394   if (nextbutton)
395     SetFocus (nextbutton);
396 }
397
398 static void
399 set_full_list (HWND h, int isfull)
400 {
401   int i, j;
402   full_list = isfull;
403   if (package_indexes == 0)
404     package_indexes = (int *) malloc (npackages * sizeof (int));
405   for (i=j=0; i<npackages; i++)
406     {
407       if (isfull || extra[i].in_partial_list)
408         package_indexes[j++] = i;
409     }
410   nindexes = j;
411
412   RECT r;
413   GetClientRect (h, &r);
414   SCROLLINFO si;
415   memset (&si, 0, sizeof (si));
416   si.cbSize = sizeof (si);
417   si.fMask = SIF_ALL;
418   si.nMin = 0;
419   si.nMax = headers[2].x + headers[2].width + HMARGIN;
420   si.nPage = r.right;
421   SetScrollInfo (h, SB_HORZ, &si, TRUE);
422
423   si.nMax = nindexes * row_height;
424   si.nPage = r.bottom - header_height;
425   SetScrollInfo (h, SB_VERT, &si, TRUE);
426
427   scroll_ulc_x = scroll_ulc_y = 0;
428
429   InvalidateRect (h, &r, TRUE);
430
431   if (nextbutton)
432     SetFocus (nextbutton);
433 }
434
435 static void
436 build_labels ()
437 {
438   int i;
439   for (i=0; i<npackages; i++)
440     {
441       int c = 0, t;
442
443 #define C extra[i].chooser[c]
444       if (extra[i].installed_ver)
445         {
446           C.caption = "Uninstall";
447           C.trust = TRUST_UNINSTALL;
448           c++;
449           C.caption = "Keep";
450           C.trust = TRUST_KEEP;
451           c++;
452         }
453
454       for (t=TRUST_PREV; t<NTRUST; t++)
455         if (package[i].info[t].install)
456           if (t != extra[i].which_is_installed)
457             {
458               C.caption = package[i].info[t].version;
459               if (C.caption == 0 || C.caption[0] == 0)
460                 C.caption = "0.0";
461               C.trust = t;
462               if (package[i].info[t].source)
463                 C.src_avail = 1;
464               c++;
465               /* we intentionally skip TRUST_PREV */
466               if (t != TRUST_PREV || !extra[i].installed_ver)
467                 extra[i].in_partial_list = 1;
468
469             }
470
471       if (c == 0)
472         {
473           C.caption = "N/A";
474           C.trust = TRUST_NONE;
475           c++;
476         }
477
478       if (! extra[i].installed_file)
479         {
480           C.caption = "Skip";
481           C.trust = TRUST_NONE;
482           c++;
483         }
484
485       C.caption = 0;
486