The MinGW.org Installation Manager Tool
Révision | 2ab493b0d7460d58b51e227b8c27c9bc94fbe2c3 (tree) |
---|---|
l'heure | 2008-08-20 12:41:44 |
Auteur | John E. <tdragon@user...> |
Commiter | John E. |
Lots more UI additions
@@ -10,8 +10,18 @@ | ||
10 | 10 | |
11 | 11 | char InstManager::sm_lasterror[2048] = {0}; |
12 | 12 | std::string InstManager::sm_inst_loc; |
13 | -std::vector< std::string > InstManager::sm_categories; | |
14 | -InstManager::IDPackageMap InstManager::sm_id_packages; | |
13 | +std::vector< std::string > InstManager::sm_index_categories; | |
14 | +InstManager::StringIntMap InstManager::sm_id_categories; | |
15 | +InstManager::StringPackageMap InstManager::sm_id_packages; | |
16 | + | |
17 | + | |
18 | +extern "C" void InstMgr_SetAllPkgsShowUnstable(int show) | |
19 | +{ | |
20 | + for (InstManager::PackageIter it = InstManager::Packages_Begin(); | |
21 | + it != InstManager::Packages_End(); | |
22 | + ++it) | |
23 | + it->second->m_show_unstable = show; | |
24 | +} | |
15 | 25 | |
16 | 26 | |
17 | 27 | const char* InstManager::GetError() |
@@ -82,6 +92,7 @@ bool InstManager::Load(const std::string& inst_loc, bool create) | ||
82 | 92 | } |
83 | 93 | changes->Push(FileCreated(sm_inst_loc + "\\mingw_inst.mft")); |
84 | 94 | |
95 | + UI::ResetLists(); | |
85 | 96 | if (!LoadManifest(sm_inst_loc + "\\mingw_inst.mft")) |
86 | 97 | break; |
87 | 98 |
@@ -108,13 +119,22 @@ void InstManager::Save() | ||
108 | 119 | |
109 | 120 | int InstManager::NumCategories() |
110 | 121 | { |
111 | - return sm_categories.size(); | |
122 | + return sm_index_categories.size(); | |
112 | 123 | } |
113 | 124 | |
114 | 125 | |
115 | 126 | const char* InstManager::GetCategory(int cat) |
116 | 127 | { |
117 | - return sm_categories[cat].c_str(); | |
128 | + return sm_index_categories[cat].c_str(); | |
129 | +} | |
130 | + | |
131 | + | |
132 | +int InstManager::CategoryIndex(const char* cat_id) | |
133 | +{ | |
134 | + StringIntMap::iterator found = sm_id_categories.find(cat_id); | |
135 | + if (found == sm_id_categories.end()) | |
136 | + return -1; | |
137 | + return found->second; | |
118 | 138 | } |
119 | 139 | |
120 | 140 |
@@ -155,43 +175,46 @@ bool InstManager::LoadManifest(const std::string& mfile) | ||
155 | 175 | SetError("Couldn't load '%s' as XML", mfile.c_str()); |
156 | 176 | return false; |
157 | 177 | } |
158 | - int newpkgct = 0; | |
159 | 178 | for (TiXmlElement* cat_el = |
160 | - doc.RootElement()->FirstChildElement("Category"); | |
179 | + TiXmlHandle(doc.RootElement()->FirstChildElement("package-categories")). | |
180 | + FirstChildElement("category").ToElement(); | |
161 | 181 | cat_el; |
162 | - cat_el = cat_el->NextSiblingElement("Category")) | |
182 | + cat_el = cat_el->NextSiblingElement("category")) | |
163 | 183 | { |
184 | + const char* id = NonEmptyAttribute(cat_el, "id"); | |
185 | + if (!id) | |
186 | + continue; | |
164 | 187 | const char* name = NonEmptyAttribute(cat_el, "name"); |
165 | 188 | if (!name) |
166 | 189 | continue; |
167 | - sm_categories.push_back(name); | |
168 | - for (TiXmlElement* package_el = | |
169 | - cat_el->FirstChildElement("Package"); | |
170 | - package_el; | |
171 | - package_el = package_el->NextSiblingElement("Package")) | |
172 | - { | |
173 | - const char* id = NonEmptyAttribute(package_el, "id"); | |
174 | - if (!id) | |
175 | - continue; | |
176 | - IDPackageMap::iterator found = sm_id_packages.find(id); | |
177 | - if (found != sm_id_packages.end()) | |
178 | - continue; | |
179 | - ++newpkgct; | |
180 | - Package::Ref newpkg( | |
181 | - new Package(id, sm_categories.size() - 1, package_el) | |
182 | - ); | |
183 | - InsertPackage(newpkg); | |
184 | - } | |
190 | + sm_id_categories[id] = sm_index_categories.size(); | |
191 | + sm_index_categories.push_back(name); | |
192 | + UI::NotifyNewCategory(name); | |
193 | + } | |
194 | + for (TiXmlElement* package_el = | |
195 | + TiXmlHandle(doc.RootElement()->FirstChildElement("package-collection")). | |
196 | + FirstChildElement("package").ToElement(); | |
197 | + package_el; | |
198 | + package_el = package_el->NextSiblingElement("package")) | |
199 | + { | |
200 | + const char* id = NonEmptyAttribute(package_el, "id"); | |
201 | + if (!id) | |
202 | + continue; | |
203 | + StringPackageMap::iterator found = sm_id_packages.find(id); | |
204 | + if (found != sm_id_packages.end()) | |
205 | + continue; | |
206 | + Package::Ref newpkg(new Package(id, package_el)); | |
207 | + InsertPackage(newpkg); | |
208 | + UI::NotifyNewPackage(*newpkg); | |
185 | 209 | } |
186 | - if (newpkgct > 0) | |
187 | - UI::NotifyNewPackages(); | |
188 | 210 | return true; |
189 | 211 | } |
190 | 212 | |
191 | 213 | |
192 | 214 | void InstManager::ClearPackages() |
193 | 215 | { |
194 | - sm_categories.clear(); | |
216 | + sm_index_categories.clear(); | |
217 | + sm_id_categories.clear(); | |
195 | 218 | sm_id_packages.clear(); |
196 | 219 | } |
197 | 220 |
@@ -26,6 +26,7 @@ public: | ||
26 | 26 | |
27 | 27 | static int NumCategories(); |
28 | 28 | static const char* GetCategory(int cat); |
29 | + static int CategoryIndex(const char* cat_id); | |
29 | 30 | |
30 | 31 | typedef std::map< std::string, RefType< Package >::Ref >::const_iterator |
31 | 32 | PackageIter; |
@@ -40,9 +41,11 @@ private: | ||
40 | 41 | |
41 | 42 | static char sm_lasterror[]; |
42 | 43 | static std::string sm_inst_loc; |
43 | - static std::vector< std::string > sm_categories; | |
44 | - typedef std::map< std::string, RefType< Package >::Ref > IDPackageMap; | |
45 | - static IDPackageMap sm_id_packages; | |
44 | + static std::vector< std::string > sm_index_categories; | |
45 | + typedef std::map< std::string, int > StringIntMap; | |
46 | + static StringIntMap sm_id_categories; | |
47 | + typedef std::map< std::string, RefType< Package >::Ref > StringPackageMap; | |
48 | + static StringPackageMap sm_id_packages; | |
46 | 49 | }; |
47 | 50 | |
48 | 51 |
@@ -8,26 +8,41 @@ | ||
8 | 8 | #include "resource.h" |
9 | 9 | |
10 | 10 | |
11 | +#define ID_SHOW_STABLE 10001 | |
12 | +#define ID_SHOW_UNSTABLE 10002 | |
13 | + | |
14 | + | |
11 | 15 | static int g_vert_grip_x = 150; |
12 | 16 | static float g_horz_grip_prop = 0.5f; |
13 | 17 | static HACCEL g_haccel; |
14 | 18 | static HINSTANCE g_instance = 0; |
15 | 19 | |
16 | 20 | |
17 | -static void InsertColumn(HWND hlv, const char* txt, int index, int fmt) | |
21 | +static void InsertColumn | |
22 | + (HWND hlv, | |
23 | + const char* txt, | |
24 | + int index, | |
25 | + int fmt, | |
26 | + int width) | |
18 | 27 | { |
19 | 28 | int tlen = strlen(txt); |
20 | 29 | if (tlen >= 200) |
21 | 30 | return; |
22 | 31 | char* tcopy = malloc(tlen + 1); |
23 | 32 | strcpy(tcopy, txt); |
24 | - SIZE sz; | |
25 | - if (!GetTextExtentPoint32(GetDC(hlv), tcopy, tlen, &sz)) | |
26 | - return; | |
27 | 33 | LVCOLUMN lvc; |
28 | 34 | lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; |
29 | 35 | lvc.fmt = fmt; |
30 | - lvc.cx = sz.cx + 15; | |
36 | + if (width > 0) | |
37 | + lvc.cx = width; | |
38 | + else | |
39 | + { | |
40 | + SIZE sz; | |
41 | + if (GetTextExtentPoint32(GetDC(hlv), tcopy, tlen, &sz)) | |
42 | + lvc.cx = sz.cx + 15; | |
43 | + else | |
44 | + lvc.cx = 100; | |
45 | + } | |
31 | 46 | lvc.pszText = tcopy; |
32 | 47 | lvc.cchTextMax = tlen; |
33 | 48 | ListView_InsertColumn(hlv, index, &lvc); |
@@ -52,9 +67,14 @@ static void TransToClient(HWND hwnd, RECT* rc) | ||
52 | 67 | |
53 | 68 | |
54 | 69 | void SelectInst(HINSTANCE, HWND); |
55 | -const char* PackageGetSubItemText(LPARAM, int); | |
70 | +const char* Pkg_GetSubItemText(LPARAM, int); | |
56 | 71 | void UI_NotifyCategoryChange(int); |
57 | 72 | void UI_SortListView(int); |
73 | +void UI_OnListViewSelect(int); | |
74 | +void DescWnd_SetHWND(HWND); | |
75 | +int Pkg_UnstableShown(LPARAM); | |
76 | +void Pkg_SetUnstableShown(LPARAM, int); | |
77 | +void InstMgr_SetAllPkgsShowUnstable(int); | |
58 | 78 | |
59 | 79 | static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) |
60 | 80 | { |
@@ -102,12 +122,24 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM | ||
102 | 122 | HWND hlv = GetDlgItem(hwndDlg, IDC_COMPLIST); |
103 | 123 | ListView_SetExtendedListViewStyle(hlv, |
104 | 124 | LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP); |
105 | - InsertColumn(hlv, "S", 0, LVCFMT_LEFT); | |
106 | - InsertColumn(hlv, "Package", 1, LVCFMT_LEFT); | |
107 | - InsertColumn(hlv, "Installed Version", 2, LVCFMT_LEFT); | |
108 | - InsertColumn(hlv, "Latest Version", 3, LVCFMT_LEFT); | |
109 | - InsertColumn(hlv, "Size", 4, LVCFMT_RIGHT); | |
110 | - InsertColumn(hlv, "Description", 5, LVCFMT_LEFT); | |
125 | + HIMAGELIST il = | |
126 | + ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 10, 0); | |
127 | + HBITMAP buttonsbmp = | |
128 | + LoadBitmap(g_instance, MAKEINTRESOURCE(IDB_STATES)); | |
129 | + ImageList_AddMasked(il, buttonsbmp, RGB(255, 0, 255)); | |
130 | + DeleteObject(buttonsbmp); | |
131 | + (void)ListView_SetImageList(hlv, il, LVSIL_SMALL); | |
132 | + SIZE sz; | |
133 | + sz.cx = 100; | |
134 | + HDC lvdc = GetDC(hlv); | |
135 | + GetTextExtentPoint32(lvdc, "sample string", 13, &sz); | |
136 | + ReleaseDC(hlv, lvdc); | |
137 | + InsertColumn(hlv, "S", 0, LVCFMT_LEFT, 0); | |
138 | + InsertColumn(hlv, "Package", 1, LVCFMT_LEFT, sz.cx); | |
139 | + InsertColumn(hlv, "Installed Version", 2, LVCFMT_LEFT, 0); | |
140 | + InsertColumn(hlv, "Latest Version", 3, LVCFMT_LEFT, 0); | |
141 | + InsertColumn(hlv, "Size (DL)", 4, LVCFMT_RIGHT, 0); | |
142 | + InsertColumn(hlv, "Description", 5, LVCFMT_LEFT, sz.cx); | |
111 | 143 | } |
112 | 144 | return TRUE; |
113 | 145 |
@@ -119,13 +151,31 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM | ||
119 | 151 | case WM_COMMAND: |
120 | 152 | switch(LOWORD(wParam)) |
121 | 153 | { |
122 | - case IDI_FILE_EXIT: | |
154 | + case IDM_FILE_EXIT: | |
123 | 155 | DestroyWindow(hwndDlg); |
124 | 156 | PostQuitMessage(0); |
125 | 157 | return TRUE; |
126 | - case IDI_FILE_CHANGEINST: | |
158 | + case IDM_FILE_CHANGEINST: | |
127 | 159 | SelectInst(g_instance, hwndDlg); |
128 | 160 | return TRUE; |
161 | + case IDM_VIEW_SHOWSTABLE: | |
162 | + InstMgr_SetAllPkgsShowUnstable(0); | |
163 | + if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_COMPLIST)) > 0) | |
164 | + { | |
165 | + ListView_RedrawItems(GetDlgItem(hwndDlg, IDC_COMPLIST), 0, | |
166 | + ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_COMPLIST)) - 1); | |
167 | + UpdateWindow(GetDlgItem(hwndDlg, IDC_COMPLIST)); | |
168 | + } | |
169 | + return TRUE; | |
170 | + case IDM_VIEW_SHOWUNSTABLE: | |
171 | + InstMgr_SetAllPkgsShowUnstable(1); | |
172 | + if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_COMPLIST)) > 0) | |
173 | + { | |
174 | + ListView_RedrawItems(GetDlgItem(hwndDlg, IDC_COMPLIST), 0, | |
175 | + ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_COMPLIST)) - 1); | |
176 | + UpdateWindow(GetDlgItem(hwndDlg, IDC_COMPLIST)); | |
177 | + } | |
178 | + return TRUE; | |
129 | 179 | case IDC_CATLIST: |
130 | 180 | if (HIWORD(wParam) == LBN_SELCHANGE) |
131 | 181 | { |
@@ -137,6 +187,32 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM | ||
137 | 187 | break; |
138 | 188 | |
139 | 189 | case WM_NOTIFY: |
190 | + if (((LPNMHDR)lParam)->code == NM_RCLICK && | |
191 | + ((LPNMHDR)lParam)->hwndFrom == | |
192 | + ListView_GetHeader(GetDlgItem(hwndDlg, IDC_COMPLIST))) | |
193 | + { | |
194 | + DWORD dwpos = GetMessagePos(); | |
195 | + HD_HITTESTINFO hdhti; | |
196 | + hdhti.pt.x = GET_X_LPARAM(dwpos); | |
197 | + hdhti.pt.y = GET_Y_LPARAM(dwpos); | |
198 | + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hdhti.pt); | |
199 | + int hit = SendMessage(((LPNMHDR)lParam)->hwndFrom, HDM_HITTEST, 0, | |
200 | + (LPARAM)&hdhti); | |
201 | + if ((hdhti.flags & HHT_ONHEADER) && hit == 3) | |
202 | + { | |
203 | + HMENU menu = CreatePopupMenu(); | |
204 | + AppendMenu(menu, MF_STRING, IDM_VIEW_SHOWSTABLE, | |
205 | + "Show only &stable versions\tCtrl+Shift+S"); | |
206 | + AppendMenu(menu, MF_STRING, IDM_VIEW_SHOWUNSTABLE, | |
207 | + "Show &unstable versions\tCtrl+Shift+U"); | |
208 | + TrackPopupMenuEx(menu, | |
209 | + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, | |
210 | + GET_X_LPARAM(dwpos), GET_Y_LPARAM(dwpos), hwndDlg, 0); | |
211 | + DestroyMenu(menu); | |
212 | + return 0; | |
213 | + } | |
214 | + break; | |
215 | + } | |
140 | 216 | switch (((LPNMHDR)lParam)->idFrom) |
141 | 217 | { |
142 | 218 | case IDC_COMPLIST: |
@@ -145,13 +221,106 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM | ||
145 | 221 | case LVN_GETDISPINFO: |
146 | 222 | { |
147 | 223 | ((NMLVDISPINFO*)lParam)->item.pszText = |
148 | - (char*)PackageGetSubItemText(((NMLVDISPINFO*)lParam)->item.lParam, | |
224 | + (char*)Pkg_GetSubItemText(((NMLVDISPINFO*)lParam)->item.lParam, | |
149 | 225 | ((NMLVDISPINFO*)lParam)->item.iSubItem); |
150 | 226 | } |
151 | 227 | return 0; |
152 | 228 | case LVN_COLUMNCLICK: |
153 | 229 | UI_SortListView(((LPNMLISTVIEW)lParam)->iSubItem); |
154 | 230 | return 0; |
231 | + case LVN_ITEMCHANGED: | |
232 | + if ((((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE) | |
233 | + && (((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED)) | |
234 | + UI_OnListViewSelect(((LPNMLISTVIEW)lParam)->iItem); | |
235 | + return 0; | |
236 | + case NM_RCLICK: | |
237 | + { | |
238 | + DWORD dwpos = GetMessagePos(); | |
239 | + LVHITTESTINFO lvhti; | |
240 | + lvhti.pt.x = GET_X_LPARAM(dwpos); | |
241 | + lvhti.pt.y = GET_Y_LPARAM(dwpos); | |
242 | + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &lvhti.pt); | |
243 | + int hit = ListView_HitTest(((LPNMHDR)lParam)->hwndFrom, | |
244 | + &lvhti); | |
245 | + if (hit >= 0) | |
246 | + { | |
247 | + HMENU menu = CreatePopupMenu(); | |
248 | + LVITEM lvitem; | |
249 | + lvitem.iItem = hit; | |
250 | + lvitem.mask = LVIF_PARAM; | |
251 | + ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &lvitem); | |
252 | + if (Pkg_UnstableShown(lvitem.lParam)) | |
253 | + { | |
254 | + AppendMenu(menu, MF_STRING, ID_SHOW_STABLE, | |
255 | + "Show &stable version"); | |
256 | + } | |
257 | + else | |
258 | + { | |
259 | + AppendMenu(menu, MF_STRING, ID_SHOW_UNSTABLE, | |
260 | + "Show &unstable version"); | |
261 | + } | |
262 | + int ret = TrackPopupMenuEx(menu, | |
263 | + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | | |
264 | + TPM_RETURNCMD | TPM_RIGHTBUTTON, | |
265 | + GET_X_LPARAM(dwpos), GET_Y_LPARAM(dwpos), | |
266 | + ((LPNMHDR)lParam)->hwndFrom, 0); | |
267 | + switch (ret) | |
268 | + { | |
269 | + case ID_SHOW_STABLE: | |
270 | + Pkg_SetUnstableShown(lvitem.lParam, 0); | |
271 | + ListView_RedrawItems(((LPNMHDR)lParam)->hwndFrom, | |
272 | + hit, hit); | |
273 | + UpdateWindow(((LPNMHDR)lParam)->hwndFrom); | |
274 | + break; | |
275 | + case ID_SHOW_UNSTABLE: | |
276 | + Pkg_SetUnstableShown(lvitem.lParam, 1); | |
277 | + ListView_RedrawItems(((LPNMHDR)lParam)->hwndFrom, | |
278 | + hit, hit); | |
279 | + UpdateWindow(((LPNMHDR)lParam)->hwndFrom); | |
280 | + break; | |
281 | + } | |
282 | + DestroyMenu(menu); | |
283 | + } | |
284 | + } | |
285 | + return 0; | |
286 | + case NM_CUSTOMDRAW: | |
287 | + { | |
288 | + static COLORREF old_color; | |
289 | + LRESULT ret = CDRF_DODEFAULT; | |
290 | + switch (((LPNMCUSTOMDRAW)lParam)->dwDrawStage) | |
291 | + { | |
292 | + case CDDS_PREPAINT: | |
293 | + ret = CDRF_NOTIFYITEMDRAW; | |
294 | + break; | |
295 | + case CDDS_ITEMPREPAINT: | |
296 | + if (Pkg_UnstableShown( | |
297 | + ((LPNMCUSTOMDRAW)lParam)->lItemlParam | |
298 | + )) | |
299 | + { | |
300 | + old_color = ((LPNMLVCUSTOMDRAW)lParam)->clrText; | |
301 | + ((LPNMLVCUSTOMDRAW)lParam)->clrText = | |
302 | + RGB(255, 128, 0); | |
303 | + HFONT hFont = | |
304 | + (HFONT)SendMessage(((LPNMHDR)lParam)->hwndFrom, | |
305 | + WM_GETFONT, 0, 0); | |
306 | + LOGFONT lf = {0}; | |
307 | + GetObject(hFont, sizeof(LOGFONT), &lf); | |
308 | + lf.lfWeight |= FW_BOLD; | |
309 | + HFONT hFontBold = CreateFontIndirect(&lf); | |
310 | + SelectObject(((LPNMCUSTOMDRAW)lParam)->hdc, | |
311 | + hFontBold); | |
312 | + ret = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT; | |
313 | + } | |
314 | + else | |
315 | + ret = CDRF_DODEFAULT; | |
316 | + break; | |
317 | + case CDDS_ITEMPOSTPAINT: | |
318 | + ((LPNMLVCUSTOMDRAW)lParam)->clrText = old_color; | |
319 | + ret = CDRF_DODEFAULT; | |
320 | + } | |
321 | + SetWindowLong(hwndDlg, DWL_MSGRESULT, ret); | |
322 | + return TRUE; | |
323 | + } | |
155 | 324 | } |
156 | 325 | break; |
157 | 326 | } |
@@ -210,16 +379,6 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM | ||
210 | 379 | } |
211 | 380 | |
212 | 381 | |
213 | -static LRESULT CALLBACK DescWndProc | |
214 | - (HWND hwnd, | |
215 | - UINT uMsg, | |
216 | - WPARAM wParam, | |
217 | - LPARAM lParam) | |
218 | -{ | |
219 | - return DefWindowProc(hwnd, uMsg, wParam, lParam); | |
220 | -} | |
221 | - | |
222 | - | |
223 | 382 | static int ProcessQueuedMessages(HWND wnd) |
224 | 383 | { |
225 | 384 | MSG msg; |
@@ -243,6 +402,8 @@ static int ProcessQueuedMessages(HWND wnd) | ||
243 | 402 | } |
244 | 403 | |
245 | 404 | |
405 | +int DescWnd_RegisterClass(HINSTANCE); | |
406 | + | |
246 | 407 | HWND CreateMainWnd(HINSTANCE hInstance) |
247 | 408 | { |
248 | 409 | g_instance = hInstance; |
@@ -250,20 +411,6 @@ HWND CreateMainWnd(HINSTANCE hInstance) | ||
250 | 411 | InitCommonControls(); |
251 | 412 | OleInitialize(0); |
252 | 413 | |
253 | - WNDCLASS wc; | |
254 | - wc.style = CS_OWNDC; | |
255 | - wc.lpfnWndProc = DescWndProc; | |
256 | - wc.cbClsExtra = 0; | |
257 | - wc.cbWndExtra = 0; | |
258 | - wc.hInstance = hInstance; | |
259 | - wc.hIcon = 0; | |
260 | - wc.hCursor = 0; | |
261 | - wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; | |
262 | - wc.lpszMenuName = 0; | |
263 | - wc.lpszClassName = FULLDESCCLASSNAME; | |
264 | - if (!RegisterClass(&wc)) | |
265 | - return 0; | |
266 | - | |
267 | 414 | g_haccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_MAINACCEL)); |
268 | 415 | |
269 | 416 | HWND wnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), 0, |
@@ -11,6 +11,7 @@ | ||
11 | 11 | <Option object_output="obj\Debug\" /> |
12 | 12 | <Option type="1" /> |
13 | 13 | <Option compiler="gcc" /> |
14 | + <Option use_console_runner="0" /> | |
14 | 15 | <Compiler> |
15 | 16 | <Add option="-g" /> |
16 | 17 | </Compiler> |
@@ -1,19 +1,22 @@ | ||
1 | 1 | |
2 | 2 | #include "package.hpp" |
3 | 3 | |
4 | -#define WIN32_LEAN_AND_MEAN | |
5 | -#include <windows.h> | |
4 | +#include "inst_manager.hpp" | |
6 | 5 | |
7 | 6 | |
8 | -extern "C" const char* PackageGetSubItemText(LPARAM lv_lparam, int index) | |
7 | +extern "C" const char* Pkg_GetSubItemText(LPARAM lv_lparam, int index) | |
9 | 8 | { |
10 | 9 | Package* pkg = reinterpret_cast< Package* >(lv_lparam); |
11 | 10 | switch (index) |
12 | 11 | { |
13 | 12 | case 1: |
14 | 13 | return pkg->m_id.c_str(); |
14 | + case 2: | |
15 | + return pkg->m_installed_version.c_str(); | |
15 | 16 | case 3: |
16 | - return pkg->m_latest_version.c_str(); | |
17 | + return pkg->m_stable_version.c_str(); | |
18 | + case 5: | |
19 | + return pkg->m_description.c_str(); | |
17 | 20 | default: |
18 | 21 | break; |
19 | 22 | } |
@@ -21,16 +24,55 @@ extern "C" const char* PackageGetSubItemText(LPARAM lv_lparam, int index) | ||
21 | 24 | } |
22 | 25 | |
23 | 26 | |
24 | -Package::Package(const char* id, int cat, const TiXmlElement* pack_el) | |
27 | +extern "C" int Pkg_UnstableShown(LPARAM lv_lparam) | |
28 | +{ | |
29 | + return (reinterpret_cast< Package* >(lv_lparam)->m_show_unstable) ? 1 : 0; | |
30 | +} | |
31 | + | |
32 | + | |
33 | +extern "C" void Pkg_SetUnstableShown(LPARAM lv_lparam, int shown) | |
34 | +{ | |
35 | + reinterpret_cast< Package* >(lv_lparam)->m_show_unstable = shown; | |
36 | +} | |
37 | + | |
38 | + | |
39 | +Package::Package(const char* id, const TiXmlElement* pack_el) | |
25 | 40 | : m_id(id), |
26 | - m_category(cat) | |
41 | + m_show_unstable(false) | |
27 | 42 | { |
28 | - const TiXmlElement* latest_ver_el = | |
29 | - pack_el->FirstChildElement("LatestVersion"); | |
30 | - if (latest_ver_el) | |
43 | + const TiXmlElement* release_el = | |
44 | + pack_el->FirstChildElement("stable-release"); | |
45 | + if (release_el) | |
46 | + { | |
47 | + const char* rel_ver = release_el->Attribute("version"); | |
48 | + if (rel_ver && rel_ver[0]) | |
49 | + m_stable_version = rel_ver; | |
50 | + } | |
51 | + for (const TiXmlElement* aff_el = pack_el->FirstChildElement("affiliate"); | |
52 | + aff_el; | |
53 | + aff_el = aff_el->NextSiblingElement("affiliate")) | |
54 | + { | |
55 | + const char* aff_id = aff_el->Attribute("id"); | |
56 | + if (aff_id && aff_id[0]) | |
57 | + { | |
58 | + int cat = InstManager::CategoryIndex(aff_id); | |
59 | + if (cat >= 0) | |
60 | + { | |
61 | + m_categories.insert(cat); | |
62 | + } | |
63 | + } | |
64 | + } | |
65 | + const TiXmlElement* desc_el = pack_el->FirstChildElement("description"); | |
66 | + if (desc_el) | |
31 | 67 | { |
32 | - const char* latest_ver = latest_ver_el->Attribute("id"); | |
33 | - if (latest_ver && latest_ver[0]) | |
34 | - m_latest_version = latest_ver; | |
68 | + for (const TiXmlNode* node = desc_el->FirstChild(); | |
69 | + node; | |
70 | + node = node->NextSibling()) | |
71 | + { | |
72 | + if (node->ToText()) | |
73 | + m_description += node->Value(); | |
74 | + else if (node->ToElement() && strcmp(node->Value(), "p") == 0) | |
75 | + m_description += "\r\n\r\n"; | |
76 | + } | |
35 | 77 | } |
36 | 78 | } |
@@ -3,6 +3,7 @@ | ||
3 | 3 | |
4 | 4 | |
5 | 5 | #include <string> |
6 | +#include <set> | |
6 | 7 | #include "ref.hpp" |
7 | 8 | #include "tinyxml/tinyxml.h" |
8 | 9 |
@@ -12,10 +13,14 @@ struct Package | ||
12 | 13 | typedef RefType< Package >::Ref Ref; |
13 | 14 | |
14 | 15 | std::string m_id; |
15 | - int m_category; | |
16 | - std::string m_latest_version; | |
17 | - | |
18 | - Package(const char* id, int cat, const TiXmlElement* pack_el); | |
16 | + std::set< int > m_categories; | |
17 | + std::string m_installed_version; | |
18 | + std::string m_stable_version; | |
19 | + std::string m_unstable_version; | |
20 | + std::string m_description; | |
21 | + bool m_show_unstable; | |
22 | + | |
23 | + Package(const char* id, const TiXmlElement* pack_el); | |
19 | 24 | }; |
20 | 25 | |
21 | 26 |
@@ -4,9 +4,6 @@ | ||
4 | 4 | #endif |
5 | 5 | |
6 | 6 | |
7 | -#define FULLDESCCLASSNAME "mpFullDescription" | |
8 | - | |
9 | - | |
10 | 7 | #define IDD_MAINDLG 101 |
11 | 8 | #define IDD_INSTSEL 102 |
12 | 9 |
@@ -24,8 +21,12 @@ | ||
24 | 21 | |
25 | 22 | #define IDA_MAINACCEL 301 |
26 | 23 | |
24 | +#define IDB_STATES 401 | |
25 | + | |
27 | 26 | #define IDM_MAINMENU 1101 |
28 | 27 | |
29 | -#define IDI_FILE_EXIT 1201 | |
30 | -#define IDI_FILE_CHANGEINST 1202 | |
31 | -#define IDI_SOURCES_MIRRORS 1203 | |
28 | +#define IDM_FILE_EXIT 1201 | |
29 | +#define IDM_FILE_CHANGEINST 1202 | |
30 | +#define IDM_VIEW_SHOWSTABLE 1203 | |
31 | +#define IDM_VIEW_SHOWUNSTABLE 1204 | |
32 | +#define IDM_SOURCES_MIRRORS 1205 |
@@ -11,24 +11,36 @@ | ||
11 | 11 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mingw-get.manifest" |
12 | 12 | |
13 | 13 | |
14 | +IDB_STATES BITMAP "buttons.bmp" | |
15 | + | |
16 | + | |
17 | +IDA_MAINACCEL ACCELERATORS | |
18 | +BEGIN | |
19 | + "I", IDM_FILE_CHANGEINST, CONTROL, ALT, VIRTKEY | |
20 | + "S", IDM_VIEW_SHOWSTABLE, CONTROL, SHIFT, VIRTKEY | |
21 | + "U", IDM_VIEW_SHOWUNSTABLE, CONTROL, SHIFT, VIRTKEY | |
22 | + "M", IDM_SOURCES_MIRRORS, CONTROL, VIRTKEY | |
23 | +END | |
24 | + | |
25 | + | |
14 | 26 | IDM_MAINMENU MENU |
15 | 27 | BEGIN |
16 | 28 | POPUP "&File" |
17 | 29 | BEGIN |
18 | - MENUITEM "Select &Installation\tCtrl+Alt+I", IDI_FILE_CHANGEINST | |
19 | - MENUITEM "E&xit\tAlt+F4", IDI_FILE_EXIT | |
30 | + MENUITEM "Select &Installation...\tCtrl+Alt+I", IDM_FILE_CHANGEINST | |
31 | + MENUITEM "E&xit\tAlt+F4", IDM_FILE_EXIT | |
32 | + END | |
33 | + POPUP "&View" | |
34 | + BEGIN | |
35 | + MENUITEM "Show only &stable versions\tCtrl+Shift+S", IDM_VIEW_SHOWSTABLE | |
36 | + MENUITEM "Show &unstable versions\tCtrl+Shift+U", IDM_VIEW_SHOWUNSTABLE | |
20 | 37 | END |
21 | - POPUP "&Sources" | |
38 | + POPUP "Sour&ces" | |
22 | 39 | BEGIN |
23 | - MENUITEM "&Mirrors\tCtrl+M", IDI_SOURCES_MIRRORS | |
40 | + MENUITEM "&Mirrors...\tCtrl+M", IDM_SOURCES_MIRRORS | |
24 | 41 | END |
25 | 42 | END |
26 | 43 | |
27 | -IDA_MAINACCEL ACCELERATORS | |
28 | -BEGIN | |
29 | - "I", IDI_FILE_CHANGEINST, CONTROL, ALT, VIRTKEY | |
30 | - "M", IDI_SOURCES_MIRRORS, CONTROL, VIRTKEY | |
31 | -END | |
32 | 44 | |
33 | 45 | IDD_MAINDLG DIALOGEX 0, 0, 500, 300 |
34 | 46 | CAPTION "mingw-get" |
@@ -39,8 +51,8 @@ BEGIN | ||
39 | 51 | CONTROL "", IDC_MAINTOOLBAR, TOOLBARCLASSNAME, TBSTYLE_WRAPABLE, 0, 0, 0, 0 |
40 | 52 | COMBOBOX IDC_CATTYPE, 1, 28, 100, 271, CBS_DROPDOWNLIST|WS_TABSTOP |
41 | 53 | LISTBOX IDC_CATLIST, 1, 43, 100, 241, WS_BORDER|WS_VSCROLL|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_TABSTOP |
42 | - CONTROL "", IDC_COMPLIST, WC_LISTVIEW, WS_BORDER|/*LVS_LIST*/LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL|WS_TABSTOP, 105, 28, 393, 128 | |
43 | - CONTROL "", IDC_FULLDESC, FULLDESCCLASSNAME, WS_CHILD|WS_BORDER, 105, 157, 393, 128 | |
54 | + CONTROL "", IDC_COMPLIST, WC_LISTVIEW, WS_BORDER|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL|WS_TABSTOP, 105, 28, 393, 128 | |
55 | + EDITTEXT IDC_FULLDESC, 105, 157, 393, 128, ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY|WS_BORDER|WS_TABSTOP | |
44 | 56 | CONTROL "", IDC_STATBAR, STATUSCLASSNAME, SBT_TOOLTIPS, 0, 0, 0, 0 |
45 | 57 | END |
46 | 58 |
@@ -11,7 +11,9 @@ class Package; | ||
11 | 11 | class UI |
12 | 12 | { |
13 | 13 | public: |
14 | - static void NotifyNewPackages(); | |
14 | + static void ResetLists(); | |
15 | + static void NotifyNewCategory(const char* name); | |
16 | + static void NotifyNewPackage(const Package& pkg); | |
15 | 17 | }; |
16 | 18 | |
17 | 19 |
@@ -35,11 +35,12 @@ static void LVAddPackage(const Package& pkg) | ||
35 | 35 | { |
36 | 36 | HWND hlist = GetDlgItem(g_hmainwnd, IDC_COMPLIST); |
37 | 37 | LVITEM lvi; |
38 | - lvi.mask = LVIF_TEXT | LVIF_PARAM; | |
38 | + lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; | |
39 | 39 | lvi.iItem = INT_MAX; |
40 | 40 | lvi.iSubItem = 0; |
41 | 41 | char emptystr = 0; |
42 | 42 | lvi.pszText = &emptystr; |
43 | + lvi.iImage = 1; | |
43 | 44 | lvi.lParam = reinterpret_cast< LPARAM >(&pkg); |
44 | 45 | lvi.iItem = ListView_InsertItem(hlist, &lvi); |
45 | 46 | lvi.pszText = LPSTR_TEXTCALLBACK; |
@@ -48,18 +49,27 @@ static void LVAddPackage(const Package& pkg) | ||
48 | 49 | lvi.iSubItem = i; |
49 | 50 | ListView_SetItem(hlist, &lvi); |
50 | 51 | } |
52 | + if (lvi.iItem == 0) | |
53 | + { | |
54 | + ListView_SetItemState(GetDlgItem(g_hmainwnd, IDC_COMPLIST), 0, | |
55 | + LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); | |
56 | + } | |
51 | 57 | } |
52 | 58 | |
53 | 59 | |
54 | 60 | extern "C" void UI_NotifyCategoryChange(int sel) |
55 | 61 | { |
56 | 62 | ListView_DeleteAllItems(GetDlgItem(g_hmainwnd, IDC_COMPLIST)); |
63 | + bool have_item = false; | |
57 | 64 | if (sel == 0) |
58 | 65 | { |
59 | 66 | for (InstManager::PackageIter it = InstManager::Packages_Begin(); |
60 | 67 | it != InstManager::Packages_End(); |
61 | 68 | ++it) |
69 | + { | |
62 | 70 | LVAddPackage(*(it->second)); |
71 | + have_item = true; | |
72 | + } | |
63 | 73 | } |
64 | 74 | else |
65 | 75 | { |
@@ -67,10 +77,33 @@ extern "C" void UI_NotifyCategoryChange(int sel) | ||
67 | 77 | it != InstManager::Packages_End(); |
68 | 78 | ++it) |
69 | 79 | { |
70 | - if (it->second->m_category == sel - 1) | |
80 | + if (it->second->m_categories.count(sel - 1) > 0) | |
81 | + { | |
71 | 82 | LVAddPackage(*(it->second)); |
83 | + have_item = true; | |
84 | + } | |
72 | 85 | } |
73 | 86 | } |
87 | + if (have_item) | |
88 | + { | |
89 | + ListView_SetItemState(GetDlgItem(g_hmainwnd, IDC_COMPLIST), 0, | |
90 | + LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); | |
91 | + } | |
92 | + else | |
93 | + Edit_SetText(GetDlgItem(g_hmainwnd, IDC_FULLDESC), ""); | |
94 | +} | |
95 | + | |
96 | + | |
97 | +void DescWnd_SetDescription(const std::string&); | |
98 | + | |
99 | +extern "C" void UI_OnListViewSelect(int sel) | |
100 | +{ | |
101 | + LVITEM lvitem; | |
102 | + lvitem.iItem = sel; | |
103 | + lvitem.mask = LVIF_PARAM; | |
104 | + ListView_GetItem(GetDlgItem(g_hmainwnd, IDC_COMPLIST), &lvitem); | |
105 | + Edit_SetText(GetDlgItem(g_hmainwnd, IDC_FULLDESC), | |
106 | + reinterpret_cast< Package* >(lvitem.lParam)->m_description.c_str()); | |
74 | 107 | } |
75 | 108 | |
76 | 109 |
@@ -98,16 +131,19 @@ int CALLBACK LVSortCompare(LPARAM lp1, LPARAM lp2, LPARAM lpsort) | ||
98 | 131 | ret = strcmp(reinterpret_cast< Package* >(lp1)->m_id.c_str(), |
99 | 132 | reinterpret_cast< Package* >(lp2)->m_id.c_str()); |
100 | 133 | break; |
134 | + case 2: | |
135 | + ret = VersionCompare( | |
136 | + reinterpret_cast< Package* >(lp1)->m_installed_version.c_str(), | |
137 | + reinterpret_cast< Package* >(lp2)->m_installed_version.c_str() | |
138 | + ); | |
139 | + break; | |
101 | 140 | case 3: |
102 | 141 | ret = VersionCompare( |
103 | - reinterpret_cast< Package* >(lp1)->m_latest_version.c_str(), | |
104 | - reinterpret_cast< Package* >(lp2)->m_latest_version.c_str() | |
142 | + reinterpret_cast< Package* >(lp1)->m_stable_version.c_str(), | |
143 | + reinterpret_cast< Package* >(lp2)->m_stable_version.c_str() | |
105 | 144 | ); |
106 | 145 | break; |
107 | 146 | }; |
108 | - //Ensure an exact reverse sort | |
109 | - if (ret == 0 && st->m_reverse == -1) | |
110 | - return 1; | |
111 | 147 | return ret * st->m_reverse; |
112 | 148 | }; |
113 | 149 |
@@ -127,21 +163,24 @@ extern "C" void UI_SortListView(int column) | ||
127 | 163 | } |
128 | 164 | |
129 | 165 | |
130 | -void UI::NotifyNewPackages() | |
166 | +void UI::ResetLists() | |
131 | 167 | { |
132 | 168 | int ct = ListBox_GetCount(GetDlgItem(g_hmainwnd, IDC_CATLIST)); |
133 | 169 | for (; ct > 1; --ct) |
134 | 170 | ListBox_DeleteString(GetDlgItem(g_hmainwnd, IDC_CATLIST), ct - 1); |
135 | 171 | ListView_DeleteAllItems(GetDlgItem(g_hmainwnd, IDC_COMPLIST)); |
172 | +} | |
173 | + | |
174 | + | |
175 | +void UI::NotifyNewCategory(const char* name) | |
176 | +{ | |
177 | + ListBox_AddString(GetDlgItem(g_hmainwnd, IDC_CATLIST), name); | |
178 | +} | |
136 | 179 | |
137 | - for (ct = 0; ct < InstManager::NumCategories(); ++ct) | |
138 | - { | |
139 | - ListBox_AddString(GetDlgItem(g_hmainwnd, IDC_CATLIST), | |
140 | - InstManager::GetCategory(ct)); | |
141 | - } | |
142 | 180 | |
143 | - for (InstManager::PackageIter it = InstManager::Packages_Begin(); | |
144 | - it != InstManager::Packages_End(); | |
145 | - ++it) | |
146 | - LVAddPackage(*(it->second)); | |
181 | +void UI::NotifyNewPackage(const Package& pkg) | |
182 | +{ | |
183 | + int sel = ListBox_GetCurSel(GetDlgItem(g_hmainwnd, IDC_CATLIST)); | |
184 | + if (sel <= 0 || pkg.m_categories.count(sel - 1) > 0) | |
185 | + LVAddPackage(pkg); | |
147 | 186 | } |