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