]> cygwin.com Git - cygwin-apps/setup.git/blame - PickView.cc
2003-07-27 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / PickView.cc
CommitLineData
97647369
RC
1/*
2 * Copyright (c) 2002 Robert Collins.
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 Robert Collins <robertc@hotmail.com>
13 *
14 */
15
16#include "PickView.h"
17#include <commctrl.h>
18#include "PickPackageLine.h"
19#include "PickCategoryLine.h"
20#include "package_db.h"
21#include "package_version.h"
22#include "dialog.h"
23#include "resource.h"
0cf68afd 24#include <algorithm>
97647369 25
6625e635 26using namespace std;
97647369
RC
27
28static PickView::Header pkg_headers[] = {
29 {"Current", 7, 0, 0},
30 {"New", 3, 0, 0},
2fa7c5a4 31 {"Bin?", 4, 0, 0},
97647369 32 {"Src?", 4, 0, 0},
bfdf6ac2 33 {"Categories", 10, 0, 0},
97647369
RC
34 {"Package", 7, 0, 0},
35 {0, 0, 0, 0}
36};
37
38static PickView::Header cat_headers[] = {
39 {"Category", 8, 0, 0},
40 {"Current", 7, 0, 0},
41 {"New", 3, 0, 0},
2fa7c5a4 42 {"Bin?", 4, 0, 0},
97647369
RC
43 {"Src?", 4, 0, 0},
44 {"Package", 7, 0, 0},
45 {0, 0, 0, 0}
46};
47
48// PickView:: views
49const PickView::views PickView::views::Unknown (0);
50const PickView::views PickView::views::PackageFull (1);
e0aec95e
MB
51const PickView::views PickView::views::Package (2);
52const PickView::views PickView::views::PackageKeeps (3);
53const PickView::views PickView::views::PackageSkips = PickView::views (4);
54const PickView::views PickView::views::Category (5);
97647369
RC
55
56// DoInsertItem - inserts an item into a header control.
57// Returns the index of the new item.
58// hwndHeader - handle to the header control.
59// iInsertAfter - index of the previous item.
60// nWidth - width of the new item.
61// lpsz - address of the item string.
62static int
63DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz)
64{
65 HDITEM hdi;
66 int index;
67
68 hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
69 hdi.pszText = lpsz;
70 hdi.cxy = nWidth;
71 hdi.cchTextMax = lstrlen (hdi.pszText);
72 hdi.fmt = HDF_LEFT | HDF_STRING;
73
74 index = SendMessage (hwndHeader, HDM_INSERTITEM,
75 (WPARAM) iInsertAfter, (LPARAM) & hdi);
76
77 return index;
78}
79
80
81
82void
83PickView::set_headers ()
84{
85 if (view_mode == views::Unknown)
86 return;
87 if (view_mode == views::PackageFull ||
e0aec95e
MB
88 view_mode == views::Package ||
89 view_mode == views::PackageKeeps ||
90 view_mode == views::PackageSkips)
97647369
RC
91 {
92 headers = pkg_headers;
93 current_col = 0;
94 new_col = 1;
2fa7c5a4
RC
95 bintick_col = new_col + 1;
96 srctick_col = bintick_col + 1;
97 cat_col = srctick_col + 1;
98 pkg_col = cat_col + 1;
931f2755 99 last_col = pkg_col;
97647369
RC
100 }
101 else if (view_mode == views::Category)
102 {
103 headers = cat_headers;
104 current_col = 1;
2fa7c5a4
RC
105 new_col = current_col + 1;
106 bintick_col = new_col + 1;
107 srctick_col = bintick_col + 1;
97647369 108 cat_col = 0;
2fa7c5a4
RC
109 pkg_col = srctick_col + 1;
110 last_col = pkg_col;
97647369
RC
111 }
112 else
113 return;
114 while (int n = SendMessage (listheader, HDM_GETITEMCOUNT, 0, 0))
115 {
116 SendMessage (listheader, HDM_DELETEITEM, n - 1, 0);
117 }
118 int i;
119 for (i = 0; i <= last_col; i++)
120 DoInsertItem (listheader, i, headers[i].width, (char *) headers[i].text);
121}
122
123void
3c054baf 124PickView::note_width (PickView::Header *hdrs, HDC dc, String const &string, int addend,
97647369
RC
125 int column)
126{
3c054baf 127 if (!string.size())
97647369
RC
128 {
129 if (hdrs[column].width < addend)
130 hdrs[column].width = addend;
131 return;
132 }
133 SIZE s;
3c054baf 134 GetTextExtentPoint32 (dc, string.cstr_oneuse(), string.size(), &s);
97647369
RC
135 if (hdrs[column].width < s.cx + addend)
136 hdrs[column].width = s.cx + addend;
137}
138
139void
140PickView::set_view_mode (PickView::views _mode)
141{
142 view_mode = _mode;
143 set_headers ();
144}
145
146const char *
147PickView::mode_caption ()
148{
149 return view_mode.caption ();
150}
151
152const char *
153PickView::views::caption ()
154{
155 switch (_value)
156 {
157 case 1:
158 return "Full";
159 case 2:
160 return "Partial";
161 case 3:
e0aec95e
MB
162 return "Up To Date";
163 case 4:
164 return "Not Installed";
165 case 5:
97647369
RC
166 return "Category";
167 default:
168 return "";
169 }
170}
171
172void
173PickView::insert_pkg (packagemeta & pkg)
174{
175 if (view_mode != views::Category)
176 {
49cf3899 177 PickLine & line = *new PickPackageLine (*this, pkg);
97647369
RC
178 contents.insert (line);
179 }
180 else
181 {
405d7186
RC
182 for (set <String, String::caseless>::const_iterator x
183 = pkg.categories.begin (); x != pkg.categories.end (); ++x)
97647369 184 {
405d7186
RC
185 packagedb db;
186 // Special case - yuck
187 if (x->casecompare ("All") == 0)
188 continue;
189
190 PickCategoryLine & catline =
0cf68afd 191 *new PickCategoryLine (*this,* db.categories.find (*x), 1);
405d7186
RC
192 PickLine & line = *new PickPackageLine(*this, pkg);
193 catline.insert (line);
194 contents.insert (catline);
97647369
RC
195 }
196 }
197}
198
199void
200PickView::insert_category (Category * cat, bool collapsed)
201{
0cf68afd
RC
202 // Urk, special case
203 if (cat->first.casecompare ("All") == 0)
97647369
RC
204 return;
205 PickCategoryLine & catline = *new PickCategoryLine (*this, *cat, 1, collapsed);
0cf68afd
RC
206 for (vector <packagemeta *>::iterator i = cat->second.begin ();
207 i != cat->second.end () ; ++i)
97647369 208 {
405d7186 209 PickLine & line = *new PickPackageLine (*this, **i);
97647369
RC
210 catline.insert (line);
211 }
212 contents.insert (catline);
213}
214
215void
216PickView::clear_view (void)
217{
218 contents.empty ();
219 if (view_mode == views::Unknown)
220 return;
221 if (view_mode == views::PackageFull ||
e0aec95e
MB
222 view_mode == views::Package ||
223 view_mode == views::PackageKeeps ||
224 view_mode == views::PackageSkips)
97647369
RC
225 contents.ShowLabel (false);
226 else if (view_mode == views::Category)
227 contents.ShowLabel ();
228}
229
230PickView::views&
231PickView::views::operator++ ()
232{
233 ++_value;
234 if (_value > Category._value)
235 _value = 1;
236 return *this;
237}
238
239int
240PickView::click (int row, int x)
241{
242 return contents.click (0, row, x);
243}
244
245
246void
247PickView::scroll (HWND hwnd, int which, int *var, int code)
248{
249 SCROLLINFO si;
250 si.cbSize = sizeof (si);
e0aec95e 251 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
97647369
RC
252 GetScrollInfo (hwnd, which, &si);
253
254 switch (code)
255 {
256 case SB_THUMBTRACK:
257 si.nPos = si.nTrackPos;
258 break;
259 case SB_THUMBPOSITION:
260 break;
261 case SB_BOTTOM:
262 si.nPos = si.nMax;
263 break;
264 case SB_TOP:
265 si.nPos = 0;
266 break;
267 case SB_LINEDOWN:
268 si.nPos += row_height;
269 break;
270 case SB_LINEUP:
271 si.nPos -= row_height;
272 break;
273 case SB_PAGEDOWN:
274 si.nPos += si.nPage * 9 / 10;
275 break;
276 case SB_PAGEUP:
277 si.nPos -= si.nPage * 9 / 10;
278 break;
279 }
280
281 if ((int) si.nPos < 0)
282 si.nPos = 0;
283 if (si.nPos + si.nPage > (unsigned int) si.nMax)
284 si.nPos = si.nMax - si.nPage;
285
286 si.fMask = SIF_POS;
287 SetScrollInfo (hwnd, which, &si, TRUE);
288
289 int ox = scroll_ulc_x;
290 int oy = scroll_ulc_y;
291 *var = si.nPos;
292
293 RECT cr, sr;
294 GetClientRect (hwnd, &cr);
295 sr = cr;
296 sr.top += header_height;
297 UpdateWindow (hwnd);
298 ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
299 /*
300 sr.bottom = sr.top;
301 sr.top = cr.top;
302 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
303 */
304 if (ox - scroll_ulc_x)
305 {
306 GetClientRect (listheader, &cr);
307 sr = cr;
308// UpdateWindow (htmp);
309 MoveWindow (listheader, -scroll_ulc_x, 0,
310 headers[last_col].x +
311 headers[last_col].width, header_height, TRUE);
312 }
313 UpdateWindow (hwnd);
314}
315
316void
317PickView::init_headers (HDC dc)
318{
319 int i;
320
321 for (i = 0; headers[i].text; i++)
322 {
323 headers[i].width = 0;
324 headers[i].x = 0;
325 }
326
327 for (i = 0; headers[i].text; i++)
328 note_width (headers, dc, headers[i].text, HMARGIN, i);
329 /* src checkbox */
2fa7c5a4
RC
330 note_width (headers, dc, 0, HMARGIN + 11, bintick_col);
331 note_width (headers, dc, 0, HMARGIN + 11, srctick_col);
97647369 332 packagedb db;
0cf68afd
RC
333 for (packagedb::categoriesType::iterator n = packagedb::categories.begin();
334 n != packagedb::categories.end(); ++n)
335 note_width (headers, dc, String ("+ ")+n->first, HMARGIN, cat_col);
cfae3b8d
RC
336 for (vector <packagemeta *>::iterator n = db.packages.begin ();
337 n != db.packages.end (); ++n)
97647369 338 {
cfae3b8d 339 packagemeta & pkg = **n;
97647369 340 if (pkg.installed)
3c196821 341 note_width (headers, dc, pkg.installed.Canonical_version (),
97647369 342 HMARGIN, current_col);
3c196821
RC
343 for (set<packageversion>::iterator i=pkg.versions.begin();
344 i != pkg.versions.end(); ++i)
345 if (*i != pkg.installed)
97647369 346 note_width (headers, dc,
3c196821 347 i->Canonical_version (),
97647369 348 NEW_COL_SIZE_SLOP + HMARGIN, new_col);
3c054baf
RC
349 String s = pkg.name;
350 if (pkg.SDesc ().size())
351 s += String (": ") + pkg.SDesc ();
352 note_width (headers, dc, s, HMARGIN, pkg_col);
97647369
RC
353 }
354 note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
355 note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
356
357 headers[0].x = 0;
358 for (i = 1; i <= last_col; i++)
359 headers[i].x = headers[i - 1].x + headers[i - 1].width;
360}
361
362
363PickView::PickView (views _mode, HWND lv, Category &cat) : deftrust (TRUST_UNKNOWN),
364contents (*this, cat, 0, false, true), listview (lv)
365{
366
367 HDC dc = GetDC (listview);
368 sysfont = GetStockObject (DEFAULT_GUI_FONT);
369 SelectObject (dc, sysfont);
370 GetTextMetrics (dc, &tm);
371
372 bitmap_dc = CreateCompatibleDC (dc);
373 bm_spin = LoadImage (hinstance, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0);
374 bm_rtarrow = LoadImage (hinstance, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP,
375 0, 0, 0);
376
377 bm_checkyes = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP,
378 0, 0, 0);
379 bm_checkno = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP,
380 0, 0, 0);
381 bm_checkna = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP,
382 0, 0, 0);
383
384 row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN);
385 int
386 irh =
387 tm.
388 tmExternalLeading +
389 tm.
390 tmDescent +
391 11 +
392 ROW_MARGIN;
393 if (row_height < irh)
394 row_height = irh;
395
396 RECT rcParent;
397 HDLAYOUT hdl;
398 WINDOWPOS wp;
399
400 // Ensure that the common control DLL is loaded, and then create
401 // the header control.
402 INITCOMMONCONTROLSEX controlinfo =
403 {
404 sizeof (INITCOMMONCONTROLSEX), ICC_LISTVIEW_CLASSES};
405 InitCommonControlsEx (&controlinfo);
406
407 if ((listheader = CreateWindowEx (0, WC_HEADER, (LPCTSTR) NULL,
408 WS_CHILD | WS_BORDER | CCS_NORESIZE |
409 // | HDS_BUTTONS
410 HDS_HORZ, 0, 0, 0, 0, listview,
411 (HMENU) IDC_CHOOSE_LISTHEADER, hinstance,
412 (LPVOID) NULL)) == NULL)
413 // FIXME: throw an exception
414 exit (10);
415
416 // Retrieve the bounding rectangle of the parent window's
417 // client area, and then request size and position values
418 // from the header control.
419 GetClientRect (listview, &rcParent);
420
421 hdl.prc = &rcParent;
422 hdl.pwpos = &wp;
423 if (!SendMessage (listheader, HDM_LAYOUT, 0, (LPARAM) & hdl))
424 // FIXME: throw an exception
425 exit (11);
426
09130e58
RC
427 // Set the font of the listheader, but don't redraw, because its not shown
428 // yet.This message does not return a value, so we are not checking it as we
429 // do above.
430 SendMessage (listheader, WM_SETFONT, (WPARAM) sysfont, FALSE);
97647369
RC
431
432 // Set the size, position, and visibility of the header control.
433 SetWindowPos (listheader, wp.hwndInsertAfter, wp.x, wp.y,
434 wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW);
435
436 header_height = wp.cy;
437
438 view_mode = PickView::views::Package;
439 set_headers ();
440 init_headers (dc);
441 view_mode = PickView::views::Category;
442 set_headers ();
443 init_headers (dc);
444
445 view_mode = _mode;
446 set_headers ();
447
448 ReleaseDC (lv, dc);
449}
49cf3899
RC
450
451PickView::~PickView()
452{
453}
This page took 0.07108 seconds and 5 git commands to generate.