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