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"
27 static PickView::Header pkg_headers
[] = {
32 {"Category", 8, 0, 0},
37 static PickView::Header cat_headers
[] = {
38 {"Category", 8, 0, 0},
48 const PickView::views
PickView::views::Unknown (0);
49 const PickView::views
PickView::views::PackageFull (1);
50 const PickView::views
PickView::views::Package
= PickView::views (2);
51 const PickView::views
PickView::views::Category (3);
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.
60 DoInsertItem (HWND hwndHeader
, int iInsertAfter
, int nWidth
, LPSTR lpsz
)
65 hdi
.mask
= HDI_TEXT
| HDI_FORMAT
| HDI_WIDTH
;
68 hdi
.cchTextMax
= lstrlen (hdi
.pszText
);
69 hdi
.fmt
= HDF_LEFT
| HDF_STRING
;
71 index
= SendMessage (hwndHeader
, HDM_INSERTITEM
,
72 (WPARAM
) iInsertAfter
, (LPARAM
) & hdi
);
80 PickView::set_headers ()
82 if (view_mode
== views::Unknown
)
84 if (view_mode
== views::PackageFull
||
85 view_mode
== views::Package
)
87 headers
= pkg_headers
;
90 bintick_col
= new_col
+ 1;
91 srctick_col
= bintick_col
+ 1;
92 cat_col
= srctick_col
+ 1;
93 pkg_col
= cat_col
+ 1;
96 else if (view_mode
== views::Category
)
98 headers
= cat_headers
;
100 new_col
= current_col
+ 1;
101 bintick_col
= new_col
+ 1;
102 srctick_col
= bintick_col
+ 1;
104 pkg_col
= srctick_col
+ 1;
109 while (int n
= SendMessage (listheader
, HDM_GETITEMCOUNT
, 0, 0))
111 SendMessage (listheader
, HDM_DELETEITEM
, n
- 1, 0);
114 for (i
= 0; i
<= last_col
; i
++)
115 DoInsertItem (listheader
, i
, headers
[i
].width
, (char *) headers
[i
].text
);
119 PickView::note_width (PickView::Header
*hdrs
, HDC dc
, String
const &string
, int addend
,
124 if (hdrs
[column
].width
< addend
)
125 hdrs
[column
].width
= addend
;
129 GetTextExtentPoint32 (dc
, string
.cstr_oneuse(), string
.size(), &s
);
130 if (hdrs
[column
].width
< s
.cx
+ addend
)
131 hdrs
[column
].width
= s
.cx
+ addend
;
135 PickView::set_view_mode (PickView::views _mode
)
142 PickView::mode_caption ()
144 return view_mode
.caption ();
148 PickView::views::caption ()
164 PickView::insert_pkg (packagemeta
& pkg
)
166 if (view_mode
!= views::Category
)
168 PickLine
& line
= *new PickPackageLine (*this, pkg
);
169 contents
.insert (line
);
173 for (set
<String
, String::caseless
>::const_iterator x
174 = pkg
.categories
.begin (); x
!= pkg
.categories
.end (); ++x
)
177 // Special case - yuck
178 if (x
->casecompare ("All") == 0)
181 PickCategoryLine
& catline
=
182 *new PickCategoryLine (*this,* db
.categories
.find (*x
), 1);
183 PickLine
& line
= *new PickPackageLine(*this, pkg
);
184 catline
.insert (line
);
185 contents
.insert (catline
);
191 PickView::insert_category (Category
* cat
, bool collapsed
)
194 if (cat
->first
.casecompare ("All") == 0)
196 PickCategoryLine
& catline
= *new PickCategoryLine (*this, *cat
, 1, collapsed
);
197 for (vector
<packagemeta
*>::iterator i
= cat
->second
.begin ();
198 i
!= cat
->second
.end () ; ++i
)
200 PickLine
& line
= *new PickPackageLine (*this, **i
);
201 catline
.insert (line
);
203 contents
.insert (catline
);
207 PickView::clear_view (void)
210 if (view_mode
== views::Unknown
)
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 ();
220 PickView::views::operator++ ()
223 if (_value
> Category
._value
)
229 PickView::click (int row
, int x
)
231 return contents
.click (0, row
, x
);
236 PickView::scroll (HWND hwnd
, int which
, int *var
, int code
)
239 si
.cbSize
= sizeof (si
);
241 GetScrollInfo (hwnd
, which
, &si
);
246 si
.nPos
= si
.nTrackPos
;
248 case SB_THUMBPOSITION
:
257 si
.nPos
+= row_height
;
260 si
.nPos
-= row_height
;
263 si
.nPos
+= si
.nPage
* 9 / 10;
266 si
.nPos
-= si
.nPage
* 9 / 10;
270 if ((int) si
.nPos
< 0)
272 if (si
.nPos
+ si
.nPage
> (unsigned int) si
.nMax
)
273 si
.nPos
= si
.nMax
- si
.nPage
;
276 SetScrollInfo (hwnd
, which
, &si
, TRUE
);
278 int ox
= scroll_ulc_x
;
279 int oy
= scroll_ulc_y
;
283 GetClientRect (hwnd
, &cr
);
285 sr
.top
+= header_height
;
287 ScrollWindow (hwnd
, ox
- scroll_ulc_x
, oy
- scroll_ulc_y
, &sr
, &sr
);
291 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
293 if (ox
- scroll_ulc_x
)
295 GetClientRect (listheader
, &cr
);
297 // UpdateWindow (htmp);
298 MoveWindow (listheader
, -scroll_ulc_x
, 0,
299 headers
[last_col
].x
+
300 headers
[last_col
].width
, header_height
, TRUE
);
306 PickView::init_headers (HDC dc
)
310 for (i
= 0; headers
[i
].text
; i
++)
312 headers
[i
].width
= 0;
316 for (i
= 0; headers
[i
].text
; i
++)
317 note_width (headers
, dc
, headers
[i
].text
, HMARGIN
, i
);
319 note_width (headers
, dc
, 0, HMARGIN
+ 11, bintick_col
);
320 note_width (headers
, dc
, 0, HMARGIN
+ 11, srctick_col
);
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
);
325 for (size_t n
= 1; n
<= db
.packages
.number (); n
++)
327 packagemeta
& pkg
= *db
.packages
[n
];
329 note_width (headers
, dc
, pkg
.installed
.Canonical_version (),
330 HMARGIN
, current_col
);
331 for (set
<packageversion
>::iterator i
=pkg
.versions
.begin();
332 i
!= pkg
.versions
.end(); ++i
)
333 if (*i
!= pkg
.installed
)
334 note_width (headers
, dc
,
335 i
->Canonical_version (),
336 NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
338 if (pkg
.SDesc ().size())
339 s
+= String (": ") + pkg
.SDesc ();
340 note_width (headers
, dc
, s
, HMARGIN
, pkg_col
);
342 note_width (headers
, dc
, "keep", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
343 note_width (headers
, dc
, "uninstall", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
346 for (i
= 1; i
<= last_col
; i
++)
347 headers
[i
].x
= headers
[i
- 1].x
+ headers
[i
- 1].width
;
351 PickView::PickView (views _mode
, HWND lv
, Category
&cat
) : deftrust (TRUST_UNKNOWN
),
352 contents (*this, cat
, 0, false, true), listview (lv
)
355 HDC dc
= GetDC (listview
);
356 sysfont
= GetStockObject (DEFAULT_GUI_FONT
);
357 SelectObject (dc
, sysfont
);
358 GetTextMetrics (dc
, &tm
);
360 bitmap_dc
= CreateCompatibleDC (dc
);
361 bm_spin
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_SPIN
), IMAGE_BITMAP
, 0, 0, 0);
362 bm_rtarrow
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_RTARROW
), IMAGE_BITMAP
,
365 bm_checkyes
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_YES
), IMAGE_BITMAP
,
367 bm_checkno
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_NO
), IMAGE_BITMAP
,
369 bm_checkna
= LoadImage (hinstance
, MAKEINTRESOURCE (IDB_CHECK_NA
), IMAGE_BITMAP
,
372 row_height
= (tm
.tmHeight
+ tm
.tmExternalLeading
+ ROW_MARGIN
);
381 if (row_height
< irh
)
388 // Ensure that the common control DLL is loaded, and then create
389 // the header control.
390 INITCOMMONCONTROLSEX controlinfo
=
392 sizeof (INITCOMMONCONTROLSEX
), ICC_LISTVIEW_CLASSES
};
393 InitCommonControlsEx (&controlinfo
);
395 if ((listheader
= CreateWindowEx (0, WC_HEADER
, (LPCTSTR
) NULL
,
396 WS_CHILD
| WS_BORDER
| CCS_NORESIZE
|
398 HDS_HORZ
, 0, 0, 0, 0, listview
,
399 (HMENU
) IDC_CHOOSE_LISTHEADER
, hinstance
,
400 (LPVOID
) NULL
)) == NULL
)
401 // FIXME: throw an exception
404 // Retrieve the bounding rectangle of the parent window's
405 // client area, and then request size and position values
406 // from the header control.
407 GetClientRect (listview
, &rcParent
);
411 if (!SendMessage (listheader
, HDM_LAYOUT
, 0, (LPARAM
) & hdl
))
412 // FIXME: throw an exception
416 // Set the size, position, and visibility of the header control.
417 SetWindowPos (listheader
, wp
.hwndInsertAfter
, wp
.x
, wp
.y
,
418 wp
.cx
, wp
.cy
, wp
.flags
| SWP_SHOWWINDOW
);
420 header_height
= wp
.cy
;
422 view_mode
= PickView::views::Package
;
425 view_mode
= PickView::views::Category
;
435 PickView::~PickView()