]> cygwin.com Git - cygwin-apps/setup.git/blame - PickView.cc
2004-12-25 Max Bowsher <maxb@ukf.net>
[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>
693916f8
RC
25/* For 'source' */
26#include "state.h"
27#include "LogSingleton.h"
97647369 28
6625e635 29using namespace std;
97647369
RC
30
31static PickView::Header pkg_headers[] = {
32 {"Current", 7, 0, 0},
33 {"New", 3, 0, 0},
2fa7c5a4 34 {"Bin?", 4, 0, 0},
97647369 35 {"Src?", 4, 0, 0},
bfdf6ac2 36 {"Categories", 10, 0, 0},
97647369
RC
37 {"Package", 7, 0, 0},
38 {0, 0, 0, 0}
39};
40
41static PickView::Header cat_headers[] = {
42 {"Category", 8, 0, 0},
43 {"Current", 7, 0, 0},
44 {"New", 3, 0, 0},
2fa7c5a4 45 {"Bin?", 4, 0, 0},
97647369
RC
46 {"Src?", 4, 0, 0},
47 {"Package", 7, 0, 0},
48 {0, 0, 0, 0}
49};
50
51// PickView:: views
52const PickView::views PickView::views::Unknown (0);
53const PickView::views PickView::views::PackageFull (1);
e0aec95e
MB
54const PickView::views PickView::views::Package (2);
55const PickView::views PickView::views::PackageKeeps (3);
56const PickView::views PickView::views::PackageSkips = PickView::views (4);
57const PickView::views PickView::views::Category (5);
97647369 58
693916f8
RC
59ATOM PickView::WindowClassAtom = 0;
60
97647369
RC
61// DoInsertItem - inserts an item into a header control.
62// Returns the index of the new item.
63// hwndHeader - handle to the header control.
64// iInsertAfter - index of the previous item.
65// nWidth - width of the new item.
66// lpsz - address of the item string.
67static int
68DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz)
69{
70 HDITEM hdi;
71 int index;
72
73 hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
74 hdi.pszText = lpsz;
75 hdi.cxy = nWidth;
76 hdi.cchTextMax = lstrlen (hdi.pszText);
77 hdi.fmt = HDF_LEFT | HDF_STRING;
78
79 index = SendMessage (hwndHeader, HDM_INSERTITEM,
80 (WPARAM) iInsertAfter, (LPARAM) & hdi);
81
82 return index;
83}
84
85
86
87void
88PickView::set_headers ()
89{
90 if (view_mode == views::Unknown)
91 return;
92 if (view_mode == views::PackageFull ||
e0aec95e
MB
93 view_mode == views::Package ||
94 view_mode == views::PackageKeeps ||
95 view_mode == views::PackageSkips)
97647369
RC
96 {
97 headers = pkg_headers;
98 current_col = 0;
99 new_col = 1;
2fa7c5a4
RC
100 bintick_col = new_col + 1;
101 srctick_col = bintick_col + 1;
102 cat_col = srctick_col + 1;
103 pkg_col = cat_col + 1;
931f2755 104 last_col = pkg_col;
97647369
RC
105 }
106 else if (view_mode == views::Category)
107 {
108 headers = cat_headers;
109 current_col = 1;
2fa7c5a4
RC
110 new_col = current_col + 1;
111 bintick_col = new_col + 1;
112 srctick_col = bintick_col + 1;
97647369 113 cat_col = 0;
2fa7c5a4
RC
114 pkg_col = srctick_col + 1;
115 last_col = pkg_col;
97647369
RC
116 }
117 else
118 return;
119 while (int n = SendMessage (listheader, HDM_GETITEMCOUNT, 0, 0))
120 {
121 SendMessage (listheader, HDM_DELETEITEM, n - 1, 0);
122 }
123 int i;
124 for (i = 0; i <= last_col; i++)
125 DoInsertItem (listheader, i, headers[i].width, (char *) headers[i].text);
126}
127
128void
3c054baf 129PickView::note_width (PickView::Header *hdrs, HDC dc, String const &string, int addend,
97647369
RC
130 int column)
131{
3c054baf 132 if (!string.size())
97647369
RC
133 {
134 if (hdrs[column].width < addend)
135 hdrs[column].width = addend;
136 return;
137 }
138 SIZE s;
3c054baf 139 GetTextExtentPoint32 (dc, string.cstr_oneuse(), string.size(), &s);
97647369
RC
140 if (hdrs[column].width < s.cx + addend)
141 hdrs[column].width = s.cx + addend;
142}
143
144void
145PickView::set_view_mode (PickView::views _mode)
146{
147 view_mode = _mode;
148 set_headers ();
149}
150
525531ca
RC
151void
152PickView::setViewMode (PickView::views mode)
153{
154 set_view_mode (mode);
155
156 clear_view ();
157 packagedb db;
158 if (get_view_mode () == PickView::views::Package)
159 {
160 for (vector <packagemeta *>::iterator i = db.packages.begin ();
161 i != db.packages.end (); ++i)
162 {
163 packagemeta & pkg = **i;
164 if ((!pkg.desired && pkg.installed)
165 || (pkg.desired && (pkg.desired.picked ()
166 || pkg.desired.sourcePackage().picked())))
167 insert_pkg (pkg);
168 }
169 }
170 else if (get_view_mode () == PickView::views::PackageKeeps)
171 {
172 for (vector <packagemeta *>::iterator i = db.packages.begin ();
173 i != db.packages.end (); ++i)
174 {
175 packagemeta & pkg = **i;
176 if (pkg.installed && pkg.desired && !pkg.desired.picked()
177 && !pkg.desired.sourcePackage().picked())
178 insert_pkg (pkg);
179 }
180 }
181 else if (get_view_mode () == PickView::views::PackageSkips)
182 {
183 for (vector <packagemeta *>::iterator i = db.packages.begin ();
184 i != db.packages.end (); ++i)
185 {
186 packagemeta & pkg = **i;
187 if (!pkg.desired && !pkg.installed)
188 insert_pkg (pkg);
189 }
190 }
191 else if (get_view_mode () == PickView::views::PackageFull)
192 {
193 for (vector <packagemeta *>::iterator i = db.packages.begin ();
194 i != db.packages.end (); ++i)
195 insert_pkg (**i);
196 }
197 else if (get_view_mode () == PickView::views::Category)
198 {
199 /* start collapsed. TODO: make this a chooser flag */
200 for (packagedb::categoriesType::iterator n
201 = packagedb::categories.begin();
202 n != packagedb::categories.end(); ++n)
203 insert_category (&*n, CATEGORY_COLLAPSED);
204 }
205
bb8e2353 206 RECT r = GetClientRect ();
525531ca
RC
207 SCROLLINFO si;
208 memset (&si, 0, sizeof (si));
209 si.cbSize = sizeof (si);
210 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
211 si.nMin = 0;
212 si.nMax = headers[last_col].x + headers[last_col].width; // + HMARGIN;
213 si.nPage = r.right;
214 SetScrollInfo (GetHWND(), SB_HORZ, &si, TRUE);
215
216 si.nMax = contents.itemcount () * row_height;
217 si.nPage = r.bottom - header_height;
218 SetScrollInfo (GetHWND(), SB_VERT, &si, TRUE);
219
220 scroll_ulc_x = scroll_ulc_y = 0;
221
222 InvalidateRect (GetHWND(), &r, TRUE);
223}
224
97647369
RC
225const char *
226PickView::mode_caption ()
227{
228 return view_mode.caption ();
229}
230
231const char *
232PickView::views::caption ()
233{
234 switch (_value)
235 {
236 case 1:
237 return "Full";
238 case 2:
239 return "Partial";
240 case 3:
e0aec95e
MB
241 return "Up To Date";
242 case 4:
243 return "Not Installed";
244 case 5:
97647369
RC
245 return "Category";
246 default:
247 return "";
248 }
249}
250
251void
252PickView::insert_pkg (packagemeta & pkg)
253{
254 if (view_mode != views::Category)
255 {
49cf3899 256 PickLine & line = *new PickPackageLine (*this, pkg);
97647369
RC
257 contents.insert (line);
258 }
259 else
260 {
405d7186
RC
261 for (set <String, String::caseless>::const_iterator x
262 = pkg.categories.begin (); x != pkg.categories.end (); ++x)
97647369 263 {
405d7186
RC
264 packagedb db;
265 // Special case - yuck
266 if (x->casecompare ("All") == 0)
267 continue;
268
269 PickCategoryLine & catline =
0cf68afd 270 *new PickCategoryLine (*this,* db.categories.find (*x), 1);
405d7186
RC
271 PickLine & line = *new PickPackageLine(*this, pkg);
272 catline.insert (line);
273 contents.insert (catline);
97647369
RC
274 }
275 }
276}
277
278void
279PickView::insert_category (Category * cat, bool collapsed)
280{
0cf68afd
RC
281 // Urk, special case
282 if (cat->first.casecompare ("All") == 0)
97647369
RC
283 return;
284 PickCategoryLine & catline = *new PickCategoryLine (*this, *cat, 1, collapsed);
0cf68afd
RC
285 for (vector <packagemeta *>::iterator i = cat->second.begin ();
286 i != cat->second.end () ; ++i)
97647369 287 {
405d7186 288 PickLine & line = *new PickPackageLine (*this, **i);
97647369
RC
289 catline.insert (line);
290 }
291 contents.insert (catline);
292}
293
294void
295PickView::clear_view (void)
296{
297 contents.empty ();
298 if (view_mode == views::Unknown)
299 return;
300 if (view_mode == views::PackageFull ||
e0aec95e
MB
301 view_mode == views::Package ||
302 view_mode == views::PackageKeeps ||
303 view_mode == views::PackageSkips)
97647369
RC
304 contents.ShowLabel (false);
305 else if (view_mode == views::Category)
306 contents.ShowLabel ();
307}
308
309PickView::views&
310PickView::views::operator++ ()
311{
312 ++_value;
313 if (_value > Category._value)
314 _value = 1;
315 return *this;
316}
317
318int
319PickView::click (int row, int x)
320{
321 return contents.click (0, row, x);
322}
323
324
325void
326PickView::scroll (HWND hwnd, int which, int *var, int code)
327{
328 SCROLLINFO si;
329 si.cbSize = sizeof (si);
e0aec95e 330 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
97647369
RC
331 GetScrollInfo (hwnd, which, &si);
332
333 switch (code)
334 {
335 case SB_THUMBTRACK:
336 si.nPos = si.nTrackPos;
337 break;
338 case SB_THUMBPOSITION:
339 break;
340 case SB_BOTTOM:
341 si.nPos = si.nMax;
342 break;
343 case SB_TOP:
344 si.nPos = 0;
345 break;
346 case SB_LINEDOWN:
347 si.nPos += row_height;
348 break;
349 case SB_LINEUP:
350 si.nPos -= row_height;
351 break;
352 case SB_PAGEDOWN:
353 si.nPos += si.nPage * 9 / 10;
354 break;
355 case SB_PAGEUP:
356 si.nPos -= si.nPage * 9 / 10;
357 break;
358 }
359
360 if ((int) si.nPos < 0)
361 si.nPos = 0;
362 if (si.nPos + si.nPage > (unsigned int) si.nMax)
363 si.nPos = si.nMax - si.nPage;
364
365 si.fMask = SIF_POS;
366 SetScrollInfo (hwnd, which, &si, TRUE);
367
368 int ox = scroll_ulc_x;
369 int oy = scroll_ulc_y;
370 *var = si.nPos;
371
372 RECT cr, sr;
693916f8 373 ::GetClientRect (hwnd, &cr);
97647369
RC
374 sr = cr;
375 sr.top += header_height;
376 UpdateWindow (hwnd);
377 ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
378 /*
379 sr.bottom = sr.top;
380 sr.top = cr.top;
381 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
382 */
383 if (ox - scroll_ulc_x)
384 {
693916f8 385 ::GetClientRect (listheader, &cr);
97647369
RC
386 sr = cr;
387// UpdateWindow (htmp);
693916f8 388 ::MoveWindow (listheader, -scroll_ulc_x, 0,
97647369
RC
389 headers[last_col].x +
390 headers[last_col].width, header_height, TRUE);
391 }
392 UpdateWindow (hwnd);
393}
394
395void
396PickView::init_headers (HDC dc)
397{
398 int i;
399
400 for (i = 0; headers[i].text; i++)
401 {
402 headers[i].width = 0;
403 headers[i].x = 0;
404 }
405
406 for (i = 0; headers[i].text; i++)
407 note_width (headers, dc, headers[i].text, HMARGIN, i);
408 /* src checkbox */
2fa7c5a4
RC
409 note_width (headers, dc, 0, HMARGIN + 11, bintick_col);
410 note_width (headers, dc, 0, HMARGIN + 11, srctick_col);
97647369 411 packagedb db;
0cf68afd
RC
412 for (packagedb::categoriesType::iterator n = packagedb::categories.begin();
413 n != packagedb::categories.end(); ++n)
414 note_width (headers, dc, String ("+ ")+n->first, HMARGIN, cat_col);
cfae3b8d
RC
415 for (vector <packagemeta *>::iterator n = db.packages.begin ();
416 n != db.packages.end (); ++n)
97647369 417 {
cfae3b8d 418 packagemeta & pkg = **n;
97647369 419 if (pkg.installed)
3c196821 420 note_width (headers, dc, pkg.installed.Canonical_version (),
97647369 421 HMARGIN, current_col);
3c196821
RC
422 for (set<packageversion>::iterator i=pkg.versions.begin();
423 i != pkg.versions.end(); ++i)
424 if (*i != pkg.installed)
97647369 425 note_width (headers, dc,
3c196821 426 i->Canonical_version (),
97647369 427 NEW_COL_SIZE_SLOP + HMARGIN, new_col);
3c054baf
RC
428 String s = pkg.name;
429 if (pkg.SDesc ().size())
430 s += String (": ") + pkg.SDesc ();
431 note_width (headers, dc, s, HMARGIN, pkg_col);
97647369
RC
432 }
433 note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
434 note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
435
436 headers[0].x = 0;
437 for (i = 1; i <= last_col; i++)
438 headers[i].x = headers[i - 1].x + headers[i - 1].width;
439}
440
441
693916f8 442PickView::PickView (Category &cat) : deftrust (TRUST_UNKNOWN),
ee91d9be 443contents (*this, cat, 0, false, true), hasClientRect (false)
97647369 444{
693916f8 445}
97647369 446
693916f8
RC
447void
448PickView::init(views _mode)
449{
450 HDC dc = GetDC (GetHWND());
97647369
RC
451 sysfont = GetStockObject (DEFAULT_GUI_FONT);
452 SelectObject (dc, sysfont);
453 GetTextMetrics (dc, &tm);
454
455 bitmap_dc = CreateCompatibleDC (dc);
456 bm_spin = LoadImage (hinstance, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0);
457 bm_rtarrow = LoadImage (hinstance, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP,
458 0, 0, 0);
459
460 bm_checkyes = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP,
461 0, 0, 0);
462 bm_checkno = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP,
463 0, 0, 0);
464 bm_checkna = LoadImage (hinstance, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP,
465 0, 0, 0);
466
467 row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN);
468 int
469 irh =
470 tm.
471 tmExternalLeading +
472 tm.
473 tmDescent +
474 11 +
475 ROW_MARGIN;
476 if (row_height < irh)
477 row_height = irh;
478
97647369
RC
479 HDLAYOUT hdl;
480 WINDOWPOS wp;
481
482 // Ensure that the common control DLL is loaded, and then create
483 // the header control.
484 INITCOMMONCONTROLSEX controlinfo =
485 {
486 sizeof (INITCOMMONCONTROLSEX), ICC_LISTVIEW_CLASSES};
487 InitCommonControlsEx (&controlinfo);
488
489 if ((listheader = CreateWindowEx (0, WC_HEADER, (LPCTSTR) NULL,
490 WS_CHILD | WS_BORDER | CCS_NORESIZE |
491 // | HDS_BUTTONS
693916f8 492 HDS_HORZ, 0, 0, 0, 0, GetHWND(),
97647369
RC
493 (HMENU) IDC_CHOOSE_LISTHEADER, hinstance,
494 (LPVOID) NULL)) == NULL)
495 // FIXME: throw an exception
496 exit (10);
497
498 // Retrieve the bounding rectangle of the parent window's
499 // client area, and then request size and position values
500 // from the header control.
bb8e2353 501 RECT rcParent = GetClientRect ();
97647369
RC
502
503 hdl.prc = &rcParent;
504 hdl.pwpos = &wp;
505 if (!SendMessage (listheader, HDM_LAYOUT, 0, (LPARAM) & hdl))
506 // FIXME: throw an exception
507 exit (11);
508
09130e58
RC
509 // Set the font of the listheader, but don't redraw, because its not shown
510 // yet.This message does not return a value, so we are not checking it as we
511 // do above.
512 SendMessage (listheader, WM_SETFONT, (WPARAM) sysfont, FALSE);
97647369
RC
513
514 // Set the size, position, and visibility of the header control.
515 SetWindowPos (listheader, wp.hwndInsertAfter, wp.x, wp.y,
516 wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW);
517
518 header_height = wp.cy;
519
520 view_mode = PickView::views::Package;
521 set_headers ();
522 init_headers (dc);
523 view_mode = PickView::views::Category;
524 set_headers ();
525 init_headers (dc);
526
527 view_mode = _mode;
528 set_headers ();
529
9c9cfce7 530 ReleaseDC (GetHWND(), dc);
97647369 531}
49cf3899
RC
532
533PickView::~PickView()
534{
535}
693916f8
RC
536
537bool PickView::registerWindowClass ()
538{
539 if (WindowClassAtom != 0)
540 return true;
541
542 // We're not registered yet
543 WNDCLASSEX wc;
544
545 wc.cbSize = sizeof (wc);
546 // Some sensible style defaults
547 wc.style = CS_HREDRAW | CS_VREDRAW;
548 // Our default window procedure. This replaces itself
549 // on the first call with the simpler Window::WindowProcReflector().
550 wc.lpfnWndProc = Window::FirstWindowProcReflector;
551 // No class bytes
552 wc.cbClsExtra = 0;
553 // One pointer to REFLECTION_INFO in the extra window instance bytes
554 wc.cbWndExtra = 4;
555 // The app instance
556 wc.hInstance = hinstance; //GetInstance ();
557 // Use a bunch of system defaults for the GUI elements
558 wc.hIcon = LoadIcon (0, IDI_APPLICATION);
559 wc.hIconSm = NULL;
560 wc.hCursor = LoadCursor (0, IDC_ARROW);
561 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
562 // No menu
563 wc.lpszMenuName = NULL;
564 // We'll get a little crazy here with the class name
565 wc.lpszClassName = "listview";
566
567 // All set, try to register
568 WindowClassAtom = RegisterClassEx (&wc);
569 if (WindowClassAtom == 0)
570 log (LOG_BABBLE) << "Failed to register listview " << GetLastError () << endLog;
571 return WindowClassAtom != 0;
572}
573
574LRESULT CALLBACK
575PickView::list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos)
576{
d2be933d 577 scroll (hwnd, SB_VERT, &scroll_ulc_y, code);
693916f8
RC
578 return 0;
579}
580
581LRESULT CALLBACK
582PickView::list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos)
583{
d2be933d 584 scroll (hwnd, SB_HORZ, &scroll_ulc_x, code);
693916f8
RC
585 return 0;
586}
587
588LRESULT CALLBACK
589PickView::list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode)
590{
591 int row, refresh;
592
d2be933d 593 if (contents.itemcount () == 0)
693916f8
RC
594 return 0;
595
d2be933d 596 if (y < header_height)
693916f8 597 return 0;
d2be933d
RC
598 x += scroll_ulc_x;
599 y += scroll_ulc_y - header_height;
693916f8 600
d2be933d 601 row = (y + ROW_MARGIN / 2) / row_height;
693916f8 602
d2be933d 603 if (row < 0 || row >= contents.itemcount ())
693916f8
RC
604 return 0;
605
d2be933d 606 refresh = click (row, x);
693916f8
RC
607
608 // XXX we need a method to queryt he database to see if more
609 // than just one package has changed! Until then...
610#if 0
611 if (refresh)
612 {
613#endif
bb8e2353 614 RECT r = GetClientRect ();
693916f8
RC
615 SCROLLINFO si;
616 memset (&si, 0, sizeof (si));
617 si.cbSize = sizeof (si);
618 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; /* SIF_RANGE was giving strange behaviour */
619 si.nMin = 0;
620
d2be933d
RC
621 si.nMax = contents.itemcount () * row_height;
622 si.nPage = r.bottom - header_height;
693916f8
RC
623
624 /* if we are under the minimum display count ,
625 * set the offset to 0
626 */
627 if ((unsigned int) si.nMax <= si.nPage)
d2be933d
RC
628 scroll_ulc_y = 0;
629 si.nPos = scroll_ulc_y;
693916f8 630
9c9cfce7 631 SetScrollInfo (GetHWND(), SB_VERT, &si, TRUE);
693916f8 632
9c9cfce7 633 InvalidateRect (GetHWND(), &r, TRUE);
693916f8
RC
634#if 0
635 }
636 else
637 {
638 RECT rect;
639 rect.left =
d2be933d 640 headers[new_col].x - scroll_ulc_x;
693916f8 641 rect.right =
d2be933d 642 headers[src_col + 1].x - scroll_ulc_x;
693916f8 643 rect.top =
d2be933d
RC
644 header_height + row * row_height -
645 scroll_ulc_y;
646 rect.bottom = rect.top + row_height;
693916f8
RC
647 InvalidateRect (hwnd, &rect, TRUE);
648 }
649#endif
650 return 0;
651}
652
653/*
654 * LRESULT CALLBACK
655 * PickView::listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
656 */
657LRESULT
658PickView::WindowProc (UINT message, WPARAM wParam, LPARAM lParam)
659{
660 switch (message)
661 {
662 case WM_HSCROLL:
663 return HANDLE_WM_HSCROLL (GetHWND(), wParam, lParam, list_hscroll);
664 case WM_VSCROLL:
665 return HANDLE_WM_VSCROLL (GetHWND(), wParam, lParam, list_vscroll);
666 case WM_LBUTTONDOWN:
667 return HANDLE_WM_LBUTTONDOWN (GetHWND(), wParam, lParam, list_click);
668 case WM_PAINT:
669 paint (GetHWND());
670 return 0;
671 case WM_NOTIFY:
672 {
673 // pnmh = (LPNMHDR) lParam
674 LPNMHEADER phdr = (LPNMHEADER) lParam;
675 switch (phdr->hdr.code)
676 {
677 case HDN_ITEMCHANGED:
d2be933d 678 if (phdr->hdr.hwndFrom == ListHeader ())
693916f8
RC
679 {
680 if (phdr->pitem && phdr->pitem->mask & HDI_WIDTH)
d2be933d
RC
681 headers[phdr->iItem].width = phdr->pitem->cxy;
682 for (int i = 1; i <= last_col; i++)
683 headers[i].x =
684 headers[i - 1].x + headers[i - 1].width;
bb8e2353 685 RECT r = GetClientRect ();
693916f8
RC
686 SCROLLINFO si;
687 si.cbSize = sizeof (si);
688 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
689 GetScrollInfo (GetHWND(), SB_HORZ, &si);
690 int oldMax = si.nMax;
691 si.nMax =
d2be933d
RC
692 headers[last_col].x +
693 headers[last_col].width;
693916f8
RC
694 if (si.nTrackPos && oldMax > si.nMax)
695 si.nTrackPos += si.nMax - oldMax;
696 si.nPage = r.right;
697 SetScrollInfo (GetHWND(), SB_HORZ, &si, TRUE);
698 InvalidateRect (GetHWND(), &r, TRUE);
699 if (si.nTrackPos && oldMax > si.nMax)
d2be933d 700 scroll (GetHWND(), SB_HORZ, &scroll_ulc_x,
693916f8
RC
701 SB_THUMBTRACK);
702 }
703 break;
704 default:
705 break;
706 }
707 }
ee91d9be
RC
708 case WM_SIZE:
709 {
710 // Note: WM_SIZE msgs only appear when 'just' scrolling the window
711 RECT clientRect = GetWindowRect ();
712 if (hasClientRect)
713 {
714 int dx = clientRect.right - clientRect.left - lastClientRect.width();
715 if (dx != 0)
716 {
717 headers[last_col].width += dx;
718
719 set_headers ();
720
721 ::MoveWindow (listheader, -scroll_ulc_x, 0,
722 headers[last_col].x +
723 headers[last_col].width, header_height, TRUE);
724 }
725 }
726 else
727 hasClientRect = true;
728 lastClientRect = clientRect;
729 return 0;
730 }
731
693916f8
RC
732 default:
733 return DefWindowProc (GetHWND(), message, wParam, lParam);
734 }
735}
736
693916f8
RC
737void
738PickView::paint (HWND hwnd)
739{
740 HDC hdc;
741 PAINTSTRUCT ps;
742 int x, y;
743
744 hdc = BeginPaint (hwnd, &ps);
745
d2be933d 746 SelectObject (hdc, sysfont);
693916f8
RC
747 SetBkColor (hdc, GetSysColor (COLOR_WINDOW));
748 SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
749
750 RECT cr;
751 ::GetClientRect (hwnd, &cr);
752
d2be933d
RC
753 x = cr.left - scroll_ulc_x;
754 y = cr.top - scroll_ulc_y + header_height;
693916f8 755
d2be933d 756 IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right,
693916f8
RC
757 cr.bottom);
758
d2be933d 759 contents.paint (hdc, x, y, 0, (get_view_mode () ==
693916f8
RC
760 PickView::views::Category) ? 0 : 1);
761
d2be933d 762 if (contents.itemcount () == 0)
693916f8
RC
763 {
764 static const char *msg = "Nothing to Install/Update";
765 if (source == IDC_SOURCE_DOWNLOAD)
766 msg = "Nothing to Download";
ee91d9be 767 TextOut (hdc, x + HMARGIN, y, msg, strlen (msg));
693916f8
RC
768 }
769
770 EndPaint (hwnd, &ps);
771}
772
773
774bool
775PickView::Create (Window * parent, DWORD Style, RECT *r)
776{
777
778 // First register the window class, if we haven't already
779 if (!registerWindowClass ())
780 {
781 // Registration failed
782 return false;
783 }
784
785 // Save our parent, we'll probably need it eventually.
786 setParent(parent);
787
788 // Create the window instance
789 CreateWindowEx (
790 // Extended Style
791 WS_EX_CLIENTEDGE,
792 "listview", //MAKEINTATOM(WindowClassAtom), // window class atom (name)
793 "listviewwindow", // no title-bar string yet
794 // Style bits
795 Style,
796 r ? r->left : CW_USEDEFAULT, r ? r->top : CW_USEDEFAULT,
797 r? r->right - r->left + 1 : CW_USEDEFAULT,
798 r? r->bottom - r->top + 1 :CW_USEDEFAULT,
799 // Parent Window
800 parent == NULL ? (HWND) NULL : parent->GetHWND (),
801 // use class menu
802 (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST),
803 // The application instance
804 GetInstance (),
805 // The this ptr, which we'll use to set up the WindowProc reflection.
806 reinterpret_cast<void *>((Window *)this));
693916f8
RC
807 if (GetHWND() == NULL)
808 {
809 log (LOG_BABBLE) << "Failed to create PickView " << GetLastError () << endLog;
810 return false;
811 }
812
813 return true;
814}
22120c90
RC
815
816void
817PickView::defaultTrust (trusts trust)
818{
819 this->deftrust = trust;
820 packagedb db;
821 for (vector <packagemeta *>::iterator i = db.packages.begin ();
822 i != db.packages.end (); ++i)
823 {
824 packagemeta & pkg = **i;
825 if (pkg.installed
826 || pkg.categories.find ("Base") != pkg.categories.end ()
827 || pkg.categories.find ("Misc") != pkg.categories.end ())
828 {
829 pkg.desired = pkg.trustp (trust);
830 if (pkg.desired)
831 pkg.desired.pick (pkg.desired.accessible()
832 && pkg.desired != pkg.installed);
833 }
834 else
835 pkg.desired = packageversion ();
836 }
bb8e2353 837 RECT r = GetClientRect ();
22120c90
RC
838 InvalidateRect (this->GetHWND(), &r, TRUE);
839 // and then do the same for categories with no packages.
840 for (packagedb::categoriesType::iterator n = packagedb::categories.begin();
841 n != packagedb::categories.end(); ++n)
842 if (!n->second.size())
843 {
844 log (LOG_BABBLE) << "Removing empty category " << n->first << endLog;
845 packagedb::categories.erase (n++);
846 }
847}
ec2dbbf0
RC
848
849void
850PickView::refresh()
851{
852 setViewMode (get_view_mode ());
853}
This page took 0.116404 seconds and 5 git commands to generate.