2 * Copyright (c) 2002 Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <robertc@hotmail.com>
18 #include "PickPackageLine.h"
19 #include "PickCategoryLine.h"
20 #include "package_db.h"
21 #include "package_version.h"
26 static PickView::Header pkg_headers
[] = {
31 {"Category", 8, 0, 0},
36 static PickView::Header cat_headers
[] = {
37 {"Category", 8, 0, 0},
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);
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.
59 DoInsertItem (HWND hwndHeader
, int iInsertAfter
, int nWidth
, LPSTR lpsz
)
64 hdi
.mask
= HDI_TEXT
| HDI_FORMAT
| HDI_WIDTH
;
67 hdi
.cchTextMax
= lstrlen (hdi
.pszText
);
68 hdi
.fmt
= HDF_LEFT
| HDF_STRING
;
70 index
= SendMessage (hwndHeader
, HDM_INSERTITEM
,
71 (WPARAM
) iInsertAfter
, (LPARAM
) & hdi
);
79 PickView::set_headers ()
81 if (view_mode
== views::Unknown
)
83 if (view_mode
== views::PackageFull
||
84 view_mode
== views::Package
)
86 headers
= pkg_headers
;
89 bintick_col
= new_col
+ 1;
90 srctick_col
= bintick_col
+ 1;
91 cat_col
= srctick_col
+ 1;
92 pkg_col
= cat_col
+ 1;
95 else if (view_mode
== views::Category
)
97 headers
= cat_headers
;
99 new_col
= current_col
+ 1;
100 bintick_col
= new_col
+ 1;
101 srctick_col
= bintick_col
+ 1;
103 pkg_col
= srctick_col
+ 1;
108 while (int n
= SendMessage (listheader
, HDM_GETITEMCOUNT
, 0, 0))
110 SendMessage (listheader
, HDM_DELETEITEM
, n
- 1, 0);
113 for (i
= 0; i
<= last_col
; i
++)
114 DoInsertItem (listheader
, i
, headers
[i
].width
, (char *) headers
[i
].text
);
118 PickView::note_width (PickView::Header
*hdrs
, HDC dc
, String
const &string
, int addend
,
123 if (hdrs
[column
].width
< addend
)
124 hdrs
[column
].width
= addend
;
128 GetTextExtentPoint32 (dc
, string
.cstr_oneuse(), string
.size(), &s
);
129 if (hdrs
[column
].width
< s
.cx
+ addend
)
130 hdrs
[column
].width
= s
.cx
+ addend
;
134 PickView::set_view_mode (PickView::views _mode
)
141 PickView::mode_caption ()
143 return view_mode
.caption ();
147 PickView::views::caption ()
163 PickView::insert_pkg (packagemeta
& pkg
)
165 if (view_mode
!= views::Category
)
167 PickLine
& line
= *new PickPackageLine (*this, pkg
);
168 contents
.insert (line
);
172 for (size_t x
= 1; x
<= pkg
.Categories
.number (); x
++)
174 Category
& cat
= pkg
.Categories
[x
]->key
;
175 // Special case - yuck
176 if (cat
== Category ("All"))
178 PickCategoryLine
& catline
= *new PickCategoryLine (*this, cat
, 1);
179 PickLine
& line
= *new PickPackageLine(*this, pkg
);
180 catline
.insert (line
);
181 contents
.insert (catline
);
187 PickView::insert_category (Category
* cat
, bool collapsed
)
189 if (*cat
== Category ("All"))
191 PickCategoryLine
& catline
= *new PickCategoryLine (*this, *cat
, 1, collapsed
);
192 for (CategoryPackage
* catpkg
= cat
->packages
; catpkg
;
193 catpkg
= catpkg
->next
)
196 PickLine
& line
= *new PickPackageLine (*this, *catpkg
->pkg
);
197 catline
.insert (line
);
199 contents
.insert (catline
);
203 PickView::clear_view (void)
206 if (view_mode
== views::Unknown
)
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 ();
216 PickView::views::operator++ ()
219 if (_value
> Category
._value
)
225 PickView::click (int row
, int x
)
227 return contents
.click (0, row
, x
);
232 PickView::scroll (HWND hwnd
, int which
, int *var
, int code
)
235 si
.cbSize
= sizeof (si
);
237 GetScrollInfo (hwnd
, which
, &si
);
242 si
.nPos
= si
.nTrackPos
;
244 case SB_THUMBPOSITION
:
253 si
.nPos
+= row_height
;
256 si
.nPos
-= row_height
;
259 si
.nPos
+= si
.nPage
* 9 / 10;
262 si
.nPos
-= si
.nPage
* 9 / 10;
266 if ((int) si
.nPos
< 0)
268 if (si
.nPos
+ si
.nPage
> (unsigned int) si
.nMax
)
269 si
.nPos
= si
.nMax
- si
.nPage
;
272 SetScrollInfo (hwnd
, which
, &si
, TRUE
);
274 int ox
= scroll_ulc_x
;
275 int oy
= scroll_ulc_y
;
279 GetClientRect (hwnd
, &cr
);
281 sr
.top
+= header_height
;
283 ScrollWindow (hwnd
, ox
- scroll_ulc_x
, oy
- scroll_ulc_y
, &sr
, &sr
);
287 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
289 if (ox
- scroll_ulc_x
)
291 GetClientRect (listheader
, &cr
);
293 // UpdateWindow (htmp);
294 MoveWindow (listheader
, -scroll_ulc_x
, 0,
295 headers
[last_col
].x
+
296 headers
[last_col
].width
, header_height
, TRUE
);
302 PickView::init_headers (HDC dc
)
306 for (i
= 0; headers
[i
].text
; i
++)
308 headers
[i
].width
= 0;
312 for (i
= 0; headers
[i
].text
; i
++)
313 note_width (headers
, dc
, headers
[i
].text
, HMARGIN
, i
);
315 note_width (headers
, dc
, 0, HMARGIN
+ 11, bintick_col
);
316 note_width (headers
, dc
, 0, HMARGIN
+ 11, srctick_col
);
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
++)
322 packagemeta
& pkg
= *db
.packages
[n
];
324 note_width (headers
, dc
, pkg
.installed
.Canonical_version (),
325 HMARGIN
, current_col
);
326 for (set
<packageversion
>::iterator i
=pkg
.versions
.begin();
327 i
!= pkg
.versions
.end(); ++i
)
328 if (*i
!= pkg
.installed
)
329 note_width (headers
, dc
,
330 i
->Canonical_version (),
331 NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
333 if (pkg
.SDesc ().size())
334 s
+= String (": ") + pkg
.SDesc ();
335 note_width (headers
, dc
, s
, HMARGIN
, pkg_col
);
337 note_width (headers
, dc
, "keep", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
338 note_width (headers
, dc
, "uninstall", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
341 for (i
= 1; i
<= last_col
; i
++)
342 headers
[i
].x
= headers
[i
- 1].x
+ headers
[i
- 1].width
;
346 PickView::PickView (views _mode
, HWND lv
, Category
&cat
) : deftrust (TRUST_UNKNOWN
),
347 contents (*this, cat
, 0, false, true), listview (lv
)
350 HDC dc
= GetDC (listview
);
351 sysfont
= GetStockObject (DEFAULT_GUI_FONT
);
352 SelectObject (dc
, sysfont
);
353 GetTextMetrics (dc
, &tm
);
355 bitmap_dc
= CreateCompatibleDC (dc
);
356 bm_spin
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_SPIN
), IMAGE_BITMAP
, 0, 0, 0);
357 bm_rtarrow
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_RTARROW
), IMAGE_BITMAP
,
360 bm_checkyes
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_YES
), IMAGE_BITMAP
,
362 bm_checkno
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_NO
), IMAGE_BITMAP
,
364 bm_checkna
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_NA
), IMAGE_BITMAP
,
367 row_height
= (tm
.tmHeight
+ tm
.tmExternalLeading
+ ROW_MARGIN
);
376 if (row_height
< irh
)
383 // Ensure that the common control DLL is loaded, and then create
384 // the header control.
385 INITCOMMONCONTROLSEX controlinfo
=
387 sizeof (INITCOMMONCONTROLSEX
), ICC_LISTVIEW_CLASSES
};
388 InitCommonControlsEx (&controlinfo
);
390 if ((listheader
= CreateWindowEx (0, WC_HEADER
, (LPCTSTR
) NULL
,
391 WS_CHILD
| WS_BORDER
| CCS_NORESIZE
|
393 HDS_HORZ
, 0, 0, 0, 0, listview
,
394 (HMENU
) IDC_CHOOSE_LISTHEADER
, hinstance
,
395 (LPVOID
) NULL
)) == NULL
)
396 // FIXME: throw an exception
399 // Retrieve the bounding rectangle of the parent window's
400 // client area, and then request size and position values
401 // from the header control.
402 GetClientRect (listview
, &rcParent
);
406 if (!SendMessage (listheader
, HDM_LAYOUT
, 0, (LPARAM
) & hdl
))
407 // FIXME: throw an exception
411 // Set the size, position, and visibility of the header control.
412 SetWindowPos (listheader
, wp
.hwndInsertAfter
, wp
.x
, wp
.y
,
413 wp
.cx
, wp
.cy
, wp
.flags
| SWP_SHOWWINDOW
);
415 header_height
= wp
.cy
;
417 view_mode
= PickView::views::Package
;
420 view_mode
= PickView::views::Category
;
430 PickView::~PickView()