• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

The MinGW.org Installation Manager Tool


Commit MetaInfo

Révision3d007dfb258a624b5cf1942c4da35993f976c90b (tree)
l'heure2008-10-10 03:43:44
AuteurJohn E. <tdragon@user...>
CommiterJohn E.

Message de Log

Some restructuring and additions

Change Summary

Modification

--- a/TODO.txt
+++ b/TODO.txt
@@ -1,2 +1,5 @@
11
22 * Use GUI during installation
3+ * Get manifest with http://mingw.cvs.sourceforge.net/*checkout*/mingw/mingw-get/blah.mft
4+ * Toolbar icons
5+ * Default directory %SystemDrive%\MinGW
--- a/download.cpp
+++ b/download.cpp
@@ -19,10 +19,10 @@ extern "C" int DLCallback
1919 CallbackInfo* cbi = reinterpret_cast< CallbackInfo* >(clientp);
2020 if (!cbi->total_sent)
2121 {
22- cbi->next_callback(dltotal);
22+ cbi->next_callback((size_t)dltotal);
2323 cbi->total_sent = 1;
2424 }
25- cbi->next_callback(dlnow);
25+ cbi->next_callback((size_t)dlnow);
2626 return 0;
2727 }
2828
@@ -68,5 +68,5 @@ size_t DownloadFile
6868
6969 double dltotal = 0.0;
7070 curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dltotal);
71- return dltotal;
71+ return (size_t)dltotal;
7272 }
--- /dev/null
+++ b/getbindir.cpp
@@ -0,0 +1,26 @@
1+/** \file getbindir.cpp
2+ *
3+ * Created: JohnE, 2008-10-09
4+ */
5+
6+
7+#define WIN32_LEAN_AND_MEAN
8+#include <windows.h>
9+#include <string>
10+
11+
12+std::string GetBinDir()
13+{
14+ char path[1024];
15+ GetModuleFileName(0, path, 1024);
16+ for (int i = strlen(path) - 1; i >= 0; --i)
17+ {
18+ if (path[i] == '/' || path[i] == '\\')
19+ {
20+ path[i] = '\0';
21+ break;
22+ }
23+ path[i] = '\0';
24+ }
25+ return path;
26+}
--- a/inst_manager.cpp
+++ b/inst_manager.cpp
@@ -10,18 +10,6 @@
1010
1111 char InstManager::sm_lasterror[2048] = {0};
1212 std::string InstManager::sm_inst_loc;
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-}
2513
2614
2715 const char* InstManager::GetError()
@@ -59,6 +47,7 @@ size_t DownloadFile
5947 (const char*,
6048 const char*,
6149 void (*)(size_t) = 0);
50+std::string GetBinDir();
6251
6352 bool InstManager::Load(const std::string& inst_loc, bool create)
6453 {
@@ -67,8 +56,6 @@ bool InstManager::Load(const std::string& inst_loc, bool create)
6756 || sm_inst_loc[sm_inst_loc.length() - 1] == '/')
6857 sm_inst_loc.erase(sm_inst_loc.length() - 1);
6958
70- ClearPackages();
71-
7259 ChangeSet::Ref changes(new ChangeSet);
7360 do
7461 {
@@ -83,25 +70,20 @@ bool InstManager::Load(const std::string& inst_loc, bool create)
8370 }
8471 changes->Push(DirCreated(sm_inst_loc));
8572
73+#if 0
8674 if (DownloadFile("http://localhost:1330/mingwinst/mingw_avail.mft",
87- (sm_inst_loc + "\\mingw_inst.mft").c_str(), 0) <= 0)
75+ (GetBinDir() + "\\mingw_avail.mft").c_str(), 0) <= 0)
8876 {
8977 SetError("Couldn't download the following file:\r\n%s",
9078 "http://localhost:1330/mingwinst/mingw_avail.mft");
9179 break;
9280 }
93- changes->Push(FileCreated(sm_inst_loc + "\\mingw_inst.mft"));
94-
95- UI::ResetLists();
96- if (!LoadManifest(sm_inst_loc + "\\mingw_inst.mft"))
97- break;
81+#endif
9882
9983 return true;
10084 }
10185 else
10286 {
103- if (!LoadManifest((sm_inst_loc + "\\mingw_inst.mft").c_str()))
104- return false;
10587 return true;
10688 }
10789 } while (0);
@@ -117,39 +99,6 @@ void InstManager::Save()
11799 }
118100
119101
120-int InstManager::NumCategories()
121-{
122- return sm_index_categories.size();
123-}
124-
125-
126-const char* InstManager::GetCategory(int cat)
127-{
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;
138-}
139-
140-
141-InstManager::PackageIter InstManager::Packages_Begin()
142-{
143- return sm_id_packages.begin();
144-}
145-
146-
147-InstManager::PackageIter InstManager::Packages_End()
148-{
149- return sm_id_packages.end();
150-}
151-
152-
153102 void InstManager::SetError(const char* fmt, ...)
154103 {
155104 va_list ap;
@@ -157,69 +106,3 @@ void InstManager::SetError(const char* fmt, ...)
157106 vsnprintf(sm_lasterror, 2048, fmt, ap);
158107 va_end(ap);
159108 }
160-
161-
162-static const char* NonEmptyAttribute(const TiXmlElement* el, const char* name)
163-{
164- const char* attr = el->Attribute(name);
165- if (attr && attr[0])
166- return attr;
167- return 0;
168-}
169-
170-bool InstManager::LoadManifest(const std::string& mfile)
171-{
172- TiXmlDocument doc(mfile.c_str());
173- if (!doc.LoadFile())
174- {
175- SetError("Couldn't load '%s' as XML", mfile.c_str());
176- return false;
177- }
178- for (TiXmlElement* cat_el =
179- TiXmlHandle(doc.RootElement()->FirstChildElement("package-categories")).
180- FirstChildElement("category").ToElement();
181- cat_el;
182- cat_el = cat_el->NextSiblingElement("category"))
183- {
184- const char* id = NonEmptyAttribute(cat_el, "id");
185- if (!id)
186- continue;
187- const char* name = NonEmptyAttribute(cat_el, "name");
188- if (!name)
189- continue;
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);
209- }
210- return true;
211-}
212-
213-
214-void InstManager::ClearPackages()
215-{
216- sm_index_categories.clear();
217- sm_id_categories.clear();
218- sm_id_packages.clear();
219-}
220-
221-
222-void InstManager::InsertPackage(Package::Ref ins)
223-{
224- sm_id_packages.insert(std::make_pair(ins->m_id, ins));
225-}
--- a/inst_manager.hpp
+++ b/inst_manager.hpp
@@ -24,28 +24,11 @@ public:
2424 bool create = false);
2525 static void Save();
2626
27- static int NumCategories();
28- static const char* GetCategory(int cat);
29- static int CategoryIndex(const char* cat_id);
30-
31- typedef std::map< std::string, RefType< Package >::Ref >::const_iterator
32- PackageIter;
33- static PackageIter Packages_Begin();
34- static PackageIter Packages_End();
35-
3627 private:
3728 static void SetError(const char* fmt, ...);
38- static bool LoadManifest(const std::string& mfile);
39- static void ClearPackages();
40- static void InsertPackage(RefType< Package >::Ref ins);
4129
4230 static char sm_lasterror[];
4331 static std::string sm_inst_loc;
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;
4932 };
5033
5134
--- a/instselect.cpp
+++ b/instselect.cpp
@@ -35,7 +35,7 @@ static void ValidateInstPath(HWND hdlg, const std::string& path)
3535 if (path.length() > 0)
3636 {
3737 size_t i = path.find_last_of("/\\", path.length() - 2);
38- if (i != std::string::npos)
38+ if (path[1] == ':' && i != std::string::npos)
3939 {
4040 std::string pdir = (i >= 4) ? path.substr(0, i) : path.substr(0, i + 1);
4141 struct _stat st;
@@ -135,6 +135,17 @@ extern "C" void PrevInstCallback(const char* path)
135135 prev_insts[path] = index;
136136 }
137137
138+static int CALLBACK InstBrowseProc
139+ (HWND hwnd,
140+ UINT uMsg,
141+ LPARAM lParam,
142+ LPARAM lpData)
143+{
144+ if (uMsg == BFFM_INITIALIZED)
145+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
146+ return 0;
147+}
148+
138149 static BOOL CALLBACK InstSelProc
139150 (HWND hwndDlg,
140151 UINT uMsg,
@@ -147,7 +158,7 @@ static BOOL CALLBACK InstSelProc
147158 {
148159 g_hdlg = hwndDlg;
149160 if (!g_inst_loc[0])
150- strcpy(g_inst_loc, "C:\\MinGW");
161+ strcpy(g_inst_loc, "C:\\mingwgettest");
151162 if (GetPrevInstalls(PrevInstCallback) > 0)
152163 {
153164 SendMessage(GetDlgItem(hwndDlg, IDC_PREVINSTLIST), LB_SETCURSEL,
@@ -187,13 +198,19 @@ static BOOL CALLBACK InstSelProc
187198 return TRUE;
188199 case IDC_BROWSENEWINST:
189200 {
201+ char path[MAX_PATH];
202+ path[0] = 0;
203+ Edit_GetText(GetDlgItem(hwndDlg, IDC_INSTPATH), path, MAX_PATH);
204+ if (!path[0])
205+ strcpy(path, "C:\\");
190206 BROWSEINFO bi;
191207 bi.hwndOwner = hwndDlg;
192208 bi.pidlRoot = 0;
193209 bi.pszDisplayName = 0;
194210 bi.lpszTitle = "Select a Folder";
195211 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
196- bi.lpfn = 0;
212+ bi.lpfn = InstBrowseProc;
213+ bi.lParam = reinterpret_cast< LPARAM >(path);
197214 bi.iImage = 0;
198215 LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
199216 if (pidl)
--- a/mainwnd.c
+++ b/mainwnd.c
@@ -6,10 +6,7 @@
66 #include <malloc.h>
77 #include <ole2.h>
88 #include "resource.h"
9-
10-
11-#define ID_SHOW_STABLE 10001
12-#define ID_SHOW_UNSTABLE 10002
9+#include "pkg_const.h"
1310
1411
1512 static int g_vert_grip_x = 150;
@@ -18,6 +15,47 @@ static HACCEL g_haccel;
1815 static HINSTANCE g_instance = 0;
1916
2017
18+void TransToClient(HWND hwnd, RECT* rc)
19+{
20+ POINT p;
21+ p.x = rc->left;
22+ p.y = rc->top;
23+ ScreenToClient(hwnd, &p);
24+ rc->left = p.x;
25+ rc->top = p.y;
26+ p.x = rc->right;
27+ p.y = rc->bottom;
28+ ScreenToClient(hwnd, &p);
29+ rc->right = p.x;
30+ rc->bottom = p.y;
31+}
32+
33+
34+void NewVertSashPos(int pos, HWND mainwnd)
35+{
36+ g_vert_grip_x = pos;
37+ RECT rc;
38+ GetClientRect(mainwnd, &rc);
39+ SendMessage(mainwnd, WM_SIZE, SIZE_RESTORED,
40+ MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
41+}
42+
43+
44+void NewHorzSashPos(int pos, HWND mainwnd)
45+{
46+ RECT tbrc, statrc, rc;
47+ GetWindowRect(GetDlgItem(mainwnd, IDC_MAINTOOLBAR), &tbrc);
48+ TransToClient(mainwnd, &tbrc);
49+ GetWindowRect(GetDlgItem(mainwnd, IDC_STATBAR), &statrc);
50+ TransToClient(mainwnd, &statrc);
51+ GetClientRect(mainwnd, &rc);
52+ g_horz_grip_prop = (float)(pos - (tbrc.bottom - tbrc.top) - 6) /
53+ ((rc.bottom - rc.top) - (tbrc.bottom - tbrc.top) - (statrc.bottom - statrc.top) - 6);
54+ SendMessage(mainwnd, WM_SIZE, SIZE_RESTORED,
55+ MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
56+}
57+
58+
2159 static void InsertColumn
2260 (HWND hlv,
2361 const char* txt,
@@ -50,31 +88,17 @@ static void InsertColumn
5088 }
5189
5290
53-static void TransToClient(HWND hwnd, RECT* rc)
54-{
55- POINT p;
56- p.x = rc->left;
57- p.y = rc->top;
58- ScreenToClient(hwnd, &p);
59- rc->left = p.x;
60- rc->top = p.y;
61- p.x = rc->right;
62- p.y = rc->bottom;
63- ScreenToClient(hwnd, &p);
64- rc->right = p.x;
65- rc->bottom = p.y;
66-}
67-
68-
6991 void SelectInst(HINSTANCE, HWND);
7092 const char* Pkg_GetSubItemText(LPARAM, int);
7193 void UI_NotifyCategoryChange(int);
7294 void UI_SortListView(int);
7395 void UI_OnListViewSelect(int);
7496 void DescWnd_SetHWND(HWND);
75-int Pkg_UnstableShown(LPARAM);
76-void Pkg_SetUnstableShown(LPARAM, int);
77-void InstMgr_SetAllPkgsShowUnstable(int);
97+void UI_OnStateCycle(int);
98+const char* Pkg_GetInstalledVersion(LPARAM);
99+int Pkg_GetSelectedAction(LPARAM);
100+void Pkg_SelectAction(LPARAM, int);
101+int Pkg_GetStateImage(LPARAM);
78102
79103 static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
80104 {
@@ -90,17 +114,19 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
90114 old_cli_height = rc.bottom;
91115
92116 HWND htb = GetDlgItem(hwndDlg, IDC_MAINTOOLBAR);
93- HIMAGELIST hImageList = ImageList_Create(16, 16,
94- ILC_COLOR16 | ILC_MASK, 3, 0);
95- SendMessage(htb, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
96- SendMessage(htb, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR,
97- (LPARAM)HINST_COMMCTRL);
117+ HIMAGELIST il =
118+ ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, 6, 0);
119+ HBITMAP tbbuttons =
120+ LoadBitmap(g_instance, MAKEINTRESOURCE(IDB_TBBUTTONS));
121+ ImageList_AddMasked(il, tbbuttons, RGB(255, 0, 255));
122+ DeleteObject(tbbuttons);
123+ SendMessage(htb, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)il);
98124 TBBUTTON tbButtons[3] = {
99- { MAKELONG(STD_FILENEW, 0), -1, TBSTATE_ENABLED,
125+ { 0, -1, TBSTATE_ENABLED,
100126 TBSTYLE_BUTTON|TBSTYLE_AUTOSIZE, {0}, 0, (INT_PTR)"Update Lists" },
101- { MAKELONG(STD_FILEOPEN, 0), -1, TBSTATE_ENABLED,
127+ { 1, -1, TBSTATE_ENABLED,
102128 TBSTYLE_BUTTON|TBSTYLE_AUTOSIZE, {0}, 0, (INT_PTR)"Mark All Upgrades"},
103- { MAKELONG(STD_FILESAVE, 0), -1, 0,
129+ { 2, -1, 0,
104130 TBSTYLE_BUTTON|TBSTYLE_AUTOSIZE, {0}, 0, (INT_PTR)"Apply"}
105131 };
106132 SendMessage(htb, TB_BUTTONSTRUCTSIZE,
@@ -113,6 +139,7 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
113139 HWND hcb = GetDlgItem(hwndDlg, IDC_CATTYPE);
114140 SendMessage(hcb, CB_ADDSTRING, 0, (LPARAM)"Category");
115141 SendMessage(hcb, CB_ADDSTRING, 0, (LPARAM)"State");
142+ SendMessage(hcb, CB_ADDSTRING, 0, (LPARAM)"Release Status");
116143 SendMessage(hcb, CB_SETCURSEL, 0, 0);
117144
118145 HWND hcl = GetDlgItem(hwndDlg, IDC_CATLIST);
@@ -122,8 +149,7 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
122149 HWND hlv = GetDlgItem(hwndDlg, IDC_COMPLIST);
123150 ListView_SetExtendedListViewStyle(hlv,
124151 LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);
125- HIMAGELIST il =
126- ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 10, 0);
152+ il = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 10, 0);
127153 HBITMAP buttonsbmp =
128154 LoadBitmap(g_instance, MAKEINTRESOURCE(IDB_STATES));
129155 ImageList_AddMasked(il, buttonsbmp, RGB(255, 0, 255));
@@ -134,12 +160,22 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
134160 HDC lvdc = GetDC(hlv);
135161 GetTextExtentPoint32(lvdc, "sample string", 13, &sz);
136162 ReleaseDC(hlv, lvdc);
137- InsertColumn(hlv, "S", 0, LVCFMT_LEFT, 0);
163+ InsertColumn(hlv, "", 0, LVCFMT_LEFT, 25);
138164 InsertColumn(hlv, "Package", 1, LVCFMT_LEFT, sz.cx);
139165 InsertColumn(hlv, "Installed Version", 2, LVCFMT_LEFT, 0);
140166 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);
167+ InsertColumn(hlv, "Size", 4, LVCFMT_RIGHT, 0);
168+ InsertColumn(hlv, "Description", 5, LVCFMT_LEFT, sz.cx * 1.8);
169+
170+ HFONT hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
171+ LOGFONT lf = {0};
172+ GetObject(hFont, sizeof(LOGFONT), &lf);
173+ lf.lfWeight |= FW_BOLD;
174+ lf.lfHeight += 2;
175+ HFONT hFontTitle = CreateFontIndirect(&lf);
176+ SendMessage(GetDlgItem(hwndDlg, IDC_DESCTITLE), WM_SETFONT,
177+ (WPARAM)hFontTitle, MAKELPARAM(FALSE, 0));
178+ DeleteObject(hFontTitle);
143179 }
144180 return TRUE;
145181
@@ -158,24 +194,6 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
158194 case IDM_FILE_CHANGEINST:
159195 SelectInst(g_instance, hwndDlg);
160196 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;
179197 case IDC_CATLIST:
180198 if (HIWORD(wParam) == LBN_SELCHANGE)
181199 {
@@ -187,32 +205,6 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
187205 break;
188206
189207 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- }
216208 switch (((LPNMHDR)lParam)->idFrom)
217209 {
218210 case IDC_COMPLIST:
@@ -233,6 +225,21 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
233225 && (((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED))
234226 UI_OnListViewSelect(((LPNMLISTVIEW)lParam)->iItem);
235227 return 0;
228+ case NM_CLICK:
229+ {
230+ DWORD dwpos = GetMessagePos();
231+ LVHITTESTINFO lvhti;
232+ memset(&lvhti, 0, sizeof(lvhti));
233+ lvhti.pt.x = GET_X_LPARAM(dwpos);
234+ lvhti.pt.y = GET_Y_LPARAM(dwpos);
235+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &lvhti.pt);
236+ ListView_HitTest(((LPNMHDR)lParam)->hwndFrom, &lvhti);
237+ if ((lvhti.flags & LVHT_ONITEMICON)
238+ && !(lvhti.flags & LVHT_ONITEMLABEL)
239+ && lvhti.iItem >= 0)
240+ UI_OnStateCycle(lvhti.iItem);
241+ }
242+ return 0;
236243 case NM_RCLICK:
237244 {
238245 DWORD dwpos = GetMessagePos();
@@ -247,80 +254,51 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
247254 HMENU menu = CreatePopupMenu();
248255 LVITEM lvitem;
249256 lvitem.iItem = hit;
257+ lvitem.iSubItem = 0;
250258 lvitem.mask = LVIF_PARAM;
251259 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- }
260+ const char* instv =
261+ Pkg_GetInstalledVersion(lvitem.lParam);
262+ if (instv)
263+ AppendMenu(menu, MF_SEPARATOR, -1, 0);
257264 else
258265 {
259- AppendMenu(menu, MF_STRING, ID_SHOW_UNSTABLE,
260- "Show &unstable version");
266+ int act = Pkg_GetSelectedAction(lvitem.lParam);
267+ if (act != ACT_NO_CHANGE)
268+ {
269+ AppendMenu(menu, MF_STRING,
270+ 10000 + ACT_NO_CHANGE,
271+ "&Deselect this package");
272+ }
273+ if (act != ACT_INSTALL_VERSION)
274+ {
275+ AppendMenu(menu, MF_STRING,
276+ 10000 + ACT_INSTALL_VERSION,
277+ "&Select this package");
278+ }
261279 }
262280 int ret = TrackPopupMenuEx(menu,
263281 TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY |
264282 TPM_RETURNCMD | TPM_RIGHTBUTTON,
265283 GET_X_LPARAM(dwpos), GET_Y_LPARAM(dwpos),
266284 ((LPNMHDR)lParam)->hwndFrom, 0);
285+ DestroyMenu(menu);
267286 switch (ret)
268287 {
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);
288+ case 10000 + ACT_INSTALL_VERSION:
289+ Pkg_SelectAction(lvitem.lParam,
290+ ACT_INSTALL_VERSION);
274291 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);
292+ case 10000 + ACT_NO_CHANGE:
293+ Pkg_SelectAction(lvitem.lParam, ACT_NO_CHANGE);
280294 break;
281295 }
282- DestroyMenu(menu);
296+ lvitem.mask = LVIF_IMAGE;
297+ lvitem.iImage = Pkg_GetStateImage(lvitem.lParam);
298+ ListView_SetItem(((LPNMHDR)lParam)->hwndFrom, &lvitem);
283299 }
284300 }
285301 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- }
324302 }
325303 break;
326304 }
@@ -331,23 +309,19 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
331309 int cli_width = LOWORD(lParam);
332310 int cli_height = HIWORD(lParam);
333311
334- RECT tbrc, statrc, ctyperc, rc;
312+ RECT tbrc, statrc, ctyperc, instvrc, vtirc, rc;
335313
336314 GetWindowRect(GetDlgItem(hwndDlg, IDC_MAINTOOLBAR), &tbrc);
337315 TransToClient(hwndDlg, &tbrc);
338- MoveWindow(GetDlgItem(hwndDlg, IDC_MAINTOOLBAR),
339- tbrc.left, tbrc.top, cli_width - tbrc.left * 2,
340- tbrc.bottom - tbrc.top, TRUE);
341316
342317 GetWindowRect(GetDlgItem(hwndDlg, IDC_STATBAR), &statrc);
343318 TransToClient(hwndDlg, &statrc);
344- MoveWindow(GetDlgItem(hwndDlg, IDC_STATBAR),
345- statrc.left, cli_height - (statrc.bottom - statrc.top),
346- cli_width - statrc.left * 2,
347- statrc.bottom - statrc.top, TRUE);
348319
349320 int t = tbrc.bottom + 6;
350321
322+ MoveWindow(GetDlgItem(hwndDlg, IDC_VERTSASH), g_vert_grip_x, t,
323+ 8, cli_height - (statrc.bottom - statrc.top) - t, TRUE);
324+
351325 GetWindowRect(GetDlgItem(hwndDlg, IDC_CATTYPE), &ctyperc);
352326 TransToClient(hwndDlg, &ctyperc);
353327 MoveWindow(GetDlgItem(hwndDlg, IDC_CATTYPE),
@@ -360,17 +334,63 @@ static BOOL CALLBACK MainWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
360334 rc.left, t + (ctyperc.bottom - ctyperc.top) + 2,
361335 g_vert_grip_x,
362336 cli_height - t - (ctyperc.bottom - ctyperc.top) -
363- (statrc.bottom - statrc.top) - 4, TRUE);
337+ (statrc.bottom - statrc.top) - 2, TRUE);
364338
365339 int h = (cli_height - t - (statrc.bottom - statrc.top)) *
366340 g_horz_grip_prop;
367341
368342 MoveWindow(GetDlgItem(hwndDlg, IDC_COMPLIST),
369- g_vert_grip_x + 8, t, cli_width - g_vert_grip_x - 10, h, TRUE);
343+ g_vert_grip_x + 8, t, cli_width - g_vert_grip_x - 8, h, TRUE);
344+ InvalidateRect(GetDlgItem(hwndDlg, IDC_COMPLIST), 0, TRUE);
345+ UpdateWindow(GetDlgItem(hwndDlg, IDC_COMPLIST));
346+
347+ MoveWindow(GetDlgItem(hwndDlg, IDC_HORZSASH), g_vert_grip_x + 8,
348+ t + h, cli_width - g_vert_grip_x - 8, 8, TRUE);
349+
350+ GetWindowRect(GetDlgItem(hwndDlg, IDC_INSTVERSION), &instvrc);
351+ TransToClient(hwndDlg, &instvrc);
352+ MoveWindow(GetDlgItem(hwndDlg, IDC_INSTVERSION),
353+ cli_width - (instvrc.right - instvrc.left), t + h + 10,
354+ (instvrc.right - instvrc.left), instvrc.bottom - instvrc.top,
355+ TRUE);
356+ InvalidateRect(GetDlgItem(hwndDlg, IDC_INSTVERSION), 0, TRUE);
357+ UpdateWindow(GetDlgItem(hwndDlg, IDC_INSTVERSION));
358+
359+ GetWindowRect(GetDlgItem(hwndDlg, IDC_VTITEXT), &vtirc);
360+ TransToClient(hwndDlg, &vtirc);
361+ MoveWindow(GetDlgItem(hwndDlg, IDC_VTITEXT),
362+ cli_width - (instvrc.right - instvrc.left) - (vtirc.right - vtirc.left) - 2,
363+ t + h + 14, vtirc.right - vtirc.left, vtirc.bottom - vtirc.top,
364+ TRUE);
365+ InvalidateRect(GetDlgItem(hwndDlg, IDC_VTITEXT), 0, TRUE);
366+ UpdateWindow(GetDlgItem(hwndDlg, IDC_VTITEXT));
367+
368+ GetWindowRect(GetDlgItem(hwndDlg, IDC_DESCTITLE), &rc);
369+ TransToClient(hwndDlg, &rc);
370+ MoveWindow(GetDlgItem(hwndDlg, IDC_DESCTITLE), g_vert_grip_x + 10,
371+ t + h + 8 + (instvrc.bottom - instvrc.top) - (rc.bottom - rc.top),
372+ cli_width - g_vert_grip_x - (instvrc.right - instvrc.left) - (vtirc.right - vtirc.left) - 14,
373+ rc.bottom - rc.top, TRUE);
374+ InvalidateRect(GetDlgItem(hwndDlg, IDC_DESCTITLE), 0, TRUE);
375+ UpdateWindow(GetDlgItem(hwndDlg, IDC_DESCTITLE));
376+
377+ MoveWindow(GetDlgItem(hwndDlg, IDC_FULLDESC), g_vert_grip_x + 8,
378+ t + h + (instvrc.bottom - instvrc.top) + 10,
379+ cli_width - g_vert_grip_x - 8,
380+ cli_height - t - h - (instvrc.bottom - instvrc.top) - (statrc.bottom - statrc.top) - 10,
381+ TRUE);
370382
371- MoveWindow(GetDlgItem(hwndDlg, IDC_FULLDESC),
372- g_vert_grip_x + 8, t + h + 8, cli_width - g_vert_grip_x - 10,
373- cli_height - t - h - (statrc.bottom - statrc.top) - 10, TRUE);
383+ MoveWindow(GetDlgItem(hwndDlg, IDC_MAINTOOLBAR),
384+ tbrc.left, tbrc.top, cli_width - tbrc.left * 2,
385+ tbrc.bottom - tbrc.top, TRUE);
386+ InvalidateRect(GetDlgItem(hwndDlg, IDC_MAINTOOLBAR), 0, TRUE);
387+ UpdateWindow(GetDlgItem(hwndDlg, IDC_MAINTOOLBAR));
388+ MoveWindow(GetDlgItem(hwndDlg, IDC_STATBAR),
389+ statrc.left, cli_height - (statrc.bottom - statrc.top),
390+ cli_width - statrc.left * 2,
391+ statrc.bottom - statrc.top, TRUE);
392+ InvalidateRect(GetDlgItem(hwndDlg, IDC_STATBAR), 0, TRUE);
393+ UpdateWindow(GetDlgItem(hwndDlg, IDC_STATBAR));
374394 }
375395 return 0;
376396 }
@@ -402,7 +422,7 @@ static int ProcessQueuedMessages(HWND wnd)
402422 }
403423
404424
405-int DescWnd_RegisterClass(HINSTANCE);
425+int SashWnd_RegisterClasses(HINSTANCE);
406426
407427 HWND CreateMainWnd(HINSTANCE hInstance)
408428 {
@@ -411,6 +431,9 @@ HWND CreateMainWnd(HINSTANCE hInstance)
411431 InitCommonControls();
412432 OleInitialize(0);
413433
434+ if (!SashWnd_RegisterClasses(hInstance))
435+ return 0;
436+
414437 g_haccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_MAINACCEL));
415438
416439 HWND wnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), 0,
--- a/mingw-get.cbp
+++ b/mingw-get.cbp
@@ -58,6 +58,7 @@
5858 <Unit filename="download.cpp">
5959 <Option compilerVar="CC" />
6060 </Unit>
61+ <Unit filename="getbindir.cpp" />
6162 <Unit filename="inst_manager.cpp" />
6263 <Unit filename="inst_manager.hpp" />
6364 <Unit filename="instselect.cpp">
@@ -76,6 +77,9 @@
7677 <Unit filename="multiuser.h" />
7778 <Unit filename="package.cpp" />
7879 <Unit filename="package.hpp" />
80+ <Unit filename="pkg_const.h" />
81+ <Unit filename="pkg_index.cpp" />
82+ <Unit filename="pkg_index.hpp" />
7983 <Unit filename="previnstalls.c">
8084 <Option compilerVar="CC" />
8185 </Unit>
@@ -84,6 +88,9 @@
8488 <Unit filename="resource.rc">
8589 <Option compilerVar="WINDRES" />
8690 </Unit>
91+ <Unit filename="sash_wnd.c">
92+ <Option compilerVar="CC" />
93+ </Unit>
8794 <Unit filename="tinyxml\MODIFIED_TINYXML.txt" />
8895 <Unit filename="tinyxml\tinystr.cpp" />
8996 <Unit filename="tinyxml\tinystr.h" />
@@ -101,6 +108,7 @@
101108 <Extensions>
102109 <code_completion />
103110 <debugger />
111+ <envvars />
104112 </Extensions>
105113 </Project>
106114 </CodeBlocks_project_file>
--- a/mingw-get.manifest
+++ b/mingw-get.manifest
@@ -3,10 +3,10 @@
33 <assemblyIdentity
44 version="1.0.0.0"
55 processorArchitecture="X86"
6- name="MinGW.mingwpack.mingwpack"
6+ name="MinGW.mingwget.mingwget"
77 type="win32"
88 />
9-<description>MinGWPack: MinGW Package Manager</description>
9+<description>mingw-get: MinGW Package Manager</description>
1010 <dependency>
1111 <dependentAssembly>
1212 <assemblyIdentity
--- a/package.cpp
+++ b/package.cpp
@@ -1,11 +1,16 @@
11
22 #include "package.hpp"
33
4-#include "inst_manager.hpp"
4+#define WIN32_LEAN_AND_MEAN
5+#include <windows.h>
6+#include "pkg_index.hpp"
7+#include "pkg_const.h"
58
69
710 extern "C" const char* Pkg_GetSubItemText(LPARAM lv_lparam, int index)
811 {
12+ static std::string vstr;
13+
914 Package* pkg = reinterpret_cast< Package* >(lv_lparam);
1015 switch (index)
1116 {
@@ -14,9 +19,11 @@ extern "C" const char* Pkg_GetSubItemText(LPARAM lv_lparam, int index)
1419 case 2:
1520 return pkg->m_installed_version.c_str();
1621 case 3:
17- return pkg->m_stable_version.c_str();
22+ if (pkg->m_versions.size() > 0)
23+ return pkg->m_versions.front()->m_version.c_str();
24+ break;
1825 case 5:
19- return pkg->m_description.c_str();
26+ return pkg->m_title.c_str();
2027 default:
2128 break;
2229 }
@@ -24,30 +31,57 @@ extern "C" const char* Pkg_GetSubItemText(LPARAM lv_lparam, int index)
2431 }
2532
2633
27-extern "C" int Pkg_UnstableShown(LPARAM lv_lparam)
34+extern "C" const char* Pkg_GetInstalledVersion(LPARAM lv_lparam)
35+{
36+ Package* pkg = reinterpret_cast< Package* >(lv_lparam);
37+ if (pkg->m_installed_version.length() > 0)
38+ return pkg->m_installed_version.c_str();
39+ return 0;
40+}
41+
42+
43+extern "C" int Pkg_GetStateImage(LPARAM lv_lparam)
44+{
45+ return reinterpret_cast< Package* >(lv_lparam)->GetStateImage();
46+}
47+
48+
49+extern "C" int Pkg_GetSelectedAction(LPARAM lv_lparam)
50+{
51+ return reinterpret_cast< Package* >(lv_lparam)->m_selected_action;
52+}
53+
54+
55+extern "C" void Pkg_SelectAction(LPARAM lv_lparam, int action)
2856 {
29- return (reinterpret_cast< Package* >(lv_lparam)->m_show_unstable) ? 1 : 0;
57+ reinterpret_cast< Package* >(lv_lparam)->m_selected_action = action;
3058 }
3159
3260
33-extern "C" void Pkg_SetUnstableShown(LPARAM lv_lparam, int shown)
61+PkgVersion::PkgVersion(const char* ver, int status)
62+ : m_version(ver),
63+ m_status(status)
3464 {
35- reinterpret_cast< Package* >(lv_lparam)->m_show_unstable = shown;
65+}
66+
67+
68+extern "C" int VersionCompare(const char*, const char*);
69+
70+static bool PkgVersionOrder
71+ (const PkgVersion::Ref& p1,
72+ const PkgVersion::Ref& p2)
73+{
74+ if (p1->m_status != p2->m_status)
75+ return (p1->m_status > p2->m_status);
76+ return (VersionCompare(p1->m_version.c_str(), p2->m_version.c_str()) > 0);
3677 }
3778
3879
3980 Package::Package(const char* id, const TiXmlElement* pack_el)
4081 : m_id(id),
41- m_show_unstable(false)
82+ m_selected_action(ACT_NO_CHANGE),
83+ m_selected_version(-1)
4284 {
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- }
5185 for (const TiXmlElement* aff_el = pack_el->FirstChildElement("affiliate");
5286 aff_el;
5387 aff_el = aff_el->NextSiblingElement("affiliate"))
@@ -55,16 +89,17 @@ Package::Package(const char* id, const TiXmlElement* pack_el)
5589 const char* aff_id = aff_el->Attribute("id");
5690 if (aff_id && aff_id[0])
5791 {
58- int cat = InstManager::CategoryIndex(aff_id);
92+ int cat = PkgIndex::CategoryIndex(aff_id);
5993 if (cat >= 0)
60- {
6194 m_categories.insert(cat);
62- }
6395 }
6496 }
6597 const TiXmlElement* desc_el = pack_el->FirstChildElement("description");
6698 if (desc_el)
6799 {
100+ const char* title = desc_el->Attribute("title");
101+ if (title && title[0])
102+ m_title = title;
68103 for (const TiXmlNode* node = desc_el->FirstChild();
69104 node;
70105 node = node->NextSibling())
@@ -75,4 +110,51 @@ Package::Package(const char* id, const TiXmlElement* pack_el)
75110 m_description += "\r\n\r\n";
76111 }
77112 }
113+ for (const TiXmlElement* rel_el = pack_el->FirstChildElement("release");
114+ rel_el;
115+ rel_el = rel_el->NextSiblingElement("release"))
116+ {
117+ const char* ver = rel_el->Attribute("version");
118+ if (ver && ver[0])
119+ {
120+ int status = PSTATUS_STABLE;
121+ const char* stat = rel_el->Attribute("status");
122+ if (stat)
123+ {
124+ if (strcmp(stat, "alpha") == 0)
125+ status = PSTATUS_ALPHA;
126+ }
127+ m_versions.push_back(PkgVersion::Ref(new PkgVersion(ver, status)));
128+ }
129+ }
130+ if (m_versions.size() > 0)
131+ std::sort(m_versions.begin(), m_versions.end(), PkgVersionOrder);
132+}
133+
134+
135+int Package::GetStateImage() const
136+{
137+ const char* sel_ver = "";
138+ if (m_selected_version >= 0)
139+ sel_ver = m_versions[m_selected_version]->m_version.c_str();
140+ if (m_installed_version.length() <= 0)
141+ {
142+ if (m_selected_action == ACT_NO_CHANGE)
143+ return 1;
144+ else if (m_selected_action == ACT_INSTALL_VERSION)
145+ return 5;
146+ }
147+ else
148+ {
149+ if (m_selected_action == ACT_NO_CHANGE)
150+ return 2;
151+ else if (m_selected_action == ACT_INSTALL_VERSION)
152+ return (VersionCompare(m_installed_version.c_str(), sel_ver) < 0)
153+ ? 7 : 8;
154+ else if (m_selected_action == ACT_REMOVE)
155+ return 9;
156+ else if (m_selected_action == ACT_REINSTALL)
157+ return 6;
158+ }
159+ return 0;
78160 }
--- a/package.hpp
+++ b/package.hpp
@@ -4,10 +4,22 @@
44
55 #include <string>
66 #include <set>
7+#include <vector>
78 #include "ref.hpp"
89 #include "tinyxml/tinyxml.h"
910
1011
12+struct PkgVersion
13+{
14+ typedef RefType< PkgVersion >::Ref Ref;
15+
16+ std::string m_version;
17+ int m_status;
18+
19+ PkgVersion(const char* ver, int status);
20+};
21+
22+
1123 struct Package
1224 {
1325 typedef RefType< Package >::Ref Ref;
@@ -15,12 +27,15 @@ struct Package
1527 std::string m_id;
1628 std::set< int > m_categories;
1729 std::string m_installed_version;
18- std::string m_stable_version;
19- std::string m_unstable_version;
30+ std::string m_title;
2031 std::string m_description;
21- bool m_show_unstable;
32+ int m_selected_action;
33+ std::vector< PkgVersion::Ref > m_versions;
34+ int m_selected_version;
2235
2336 Package(const char* id, const TiXmlElement* pack_el);
37+
38+ int GetStateImage() const;
2439 };
2540
2641
--- /dev/null
+++ b/pkg_const.h
@@ -0,0 +1,14 @@
1+#ifndef ACTION_H_INC
2+#define ACTION_H_INC
3+
4+
5+#define ACT_NO_CHANGE 0
6+#define ACT_INSTALL_VERSION 1
7+#define ACT_REMOVE 2
8+#define ACT_REINSTALL 3
9+
10+#define PSTATUS_STABLE 0
11+#define PSTATUS_ALPHA 1
12+
13+
14+#endif // ACTION_H_INC
--- /dev/null
+++ b/pkg_index.cpp
@@ -0,0 +1,129 @@
1+/** \file pkg_index.cpp
2+ *
3+ * Created: JohnE, 2008-10-09
4+ */
5+
6+
7+#include "pkg_index.hpp"
8+
9+#include <string>
10+#include <cstdarg>
11+#include "tinyxml/tinyxml.h"
12+#include "ui.hpp"
13+#include "package.hpp"
14+
15+
16+char PkgIndex::sm_lasterror[2048] = {0};
17+std::vector< std::string > PkgIndex::sm_index_categories;
18+PkgIndex::StringIntMap PkgIndex::sm_id_categories;
19+std::list< Package::Ref >PkgIndex::sm_packages;
20+PkgIndex::StringPackageMap PkgIndex::sm_id_packages;
21+
22+
23+static const char* NonEmptyAttribute(const TiXmlElement* el, const char* name)
24+{
25+ const char* attr = el->Attribute(name);
26+ if (attr && attr[0])
27+ return attr;
28+ return 0;
29+}
30+
31+
32+int PkgIndex::NumCategories()
33+{
34+ return sm_index_categories.size();
35+}
36+
37+
38+const char* PkgIndex::GetCategory(int cat)
39+{
40+ return sm_index_categories[cat].c_str();
41+}
42+
43+
44+int PkgIndex::CategoryIndex(const char* cat_id)
45+{
46+ StringIntMap::iterator found = sm_id_categories.find(cat_id);
47+ if (found == sm_id_categories.end())
48+ return -1;
49+ return found->second;
50+}
51+
52+
53+PkgIndex::PackageIter PkgIndex::Packages_Begin()
54+{
55+ return sm_packages.begin();
56+}
57+
58+
59+PkgIndex::PackageIter PkgIndex::Packages_End()
60+{
61+ return sm_packages.end();
62+}
63+
64+
65+bool PkgIndex::LoadManifest(const std::string& mfile)
66+{
67+ TiXmlDocument doc(mfile.c_str());
68+ if (!doc.LoadFile())
69+ {
70+ SetError("Couldn't load '%s' as XML", mfile.c_str());
71+ return false;
72+ }
73+ for (TiXmlElement* cat_el =
74+ TiXmlHandle(doc.RootElement()->FirstChildElement("package-categories")).
75+ FirstChildElement("category").ToElement();
76+ cat_el;
77+ cat_el = cat_el->NextSiblingElement("category"))
78+ {
79+ const char* id = NonEmptyAttribute(cat_el, "id");
80+ if (!id)
81+ continue;
82+ const char* name = NonEmptyAttribute(cat_el, "name");
83+ if (!name)
84+ continue;
85+ sm_id_categories[id] = sm_index_categories.size();
86+ sm_index_categories.push_back(name);
87+ UI::NotifyNewCategory(name);
88+ }
89+ for (TiXmlElement* package_el =
90+ TiXmlHandle(doc.RootElement()->FirstChildElement("package-collection")).
91+ FirstChildElement("package").ToElement();
92+ package_el;
93+ package_el = package_el->NextSiblingElement("package"))
94+ {
95+ const char* id = NonEmptyAttribute(package_el, "id");
96+ if (!id)
97+ continue;
98+ StringPackageMap::iterator found = sm_id_packages.find(id);
99+ if (found != sm_id_packages.end())
100+ continue;
101+ Package::Ref newpkg(new Package(id, package_el));
102+ InsertPackage(newpkg);
103+ UI::NotifyNewPackage(*newpkg);
104+ }
105+ return true;
106+}
107+
108+
109+void PkgIndex::ClearAll()
110+{
111+ sm_index_categories.clear();
112+ sm_id_categories.clear();
113+ sm_id_packages.clear();
114+}
115+
116+
117+void PkgIndex::InsertPackage(Package::Ref ins)
118+{
119+ sm_id_packages.insert(std::make_pair(ins->m_id, ins));
120+}
121+
122+
123+void PkgIndex::SetError(const char* fmt, ...)
124+{
125+ va_list ap;
126+ va_start(ap, fmt);
127+ vsnprintf(sm_lasterror, 2048, fmt, ap);
128+ va_end(ap);
129+}
--- /dev/null
+++ b/pkg_index.hpp
@@ -0,0 +1,47 @@
1+/** \file pkg_index.hpp
2+ *
3+ * Created: JohnE, 2008-10-09
4+ */
5+#ifndef PKG_INDEX_HPP_INC
6+#define PKG_INDEX_HPP_INC
7+
8+
9+#include <list>
10+#include <map>
11+#include <vector>
12+#include "ref.hpp"
13+
14+
15+struct Package;
16+
17+
18+class PkgIndex
19+{
20+public:
21+ static void ClearAll();
22+ static bool LoadManifest(const std::string& mfile);
23+
24+ static int NumCategories();
25+ static const char* GetCategory(int cat);
26+ static int CategoryIndex(const char* cat_id);
27+
28+ typedef std::list< RefType< Package >::Ref >::const_iterator
29+ PackageIter;
30+ static PackageIter Packages_Begin();
31+ static PackageIter Packages_End();
32+
33+private:
34+ static void SetError(const char* fmt, ...);
35+ static void InsertPackage(RefType< Package >::Ref ins);
36+
37+ static char sm_lasterror[];
38+ static std::vector< std::string > sm_index_categories;
39+ typedef std::map< std::string, int > StringIntMap;
40+ static StringIntMap sm_id_categories;
41+ static std::list< RefType< Package >::Ref > sm_packages;
42+ typedef std::map< std::string, RefType< Package >::Ref > StringPackageMap;
43+ static StringPackageMap sm_id_packages;
44+};
45+
46+
47+#endif // PKG_INDEX_HPP_INC
Binary files /dev/null and b/reload16.png differ
Binary files /dev/null and b/reload22.png differ
--- a/resource.h
+++ b/resource.h
@@ -4,6 +4,10 @@
44 #endif
55
66
7+#define SASHWND_VERT_CLASSNAME "wcMGSashWndVert"
8+#define SASHWND_HORZ_CLASSNAME "wcMGSashWndHorz"
9+
10+
711 #define IDD_MAINDLG 101
812 #define IDD_INSTSEL 102
913
@@ -18,15 +22,20 @@
1822 #define IDC_BROWSENEWINST 209
1923 #define IDC_PREVINSTLIST 210
2024 #define IDC_VALTEXT 211
25+#define IDC_DESCTITLE 212
26+#define IDC_INSTVERSION 213
27+#define IDC_VTITEXT 214
28+#define IDC_VERTSASH 215
29+#define IDC_HORZSASH 216
2130
2231 #define IDA_MAINACCEL 301
2332
24-#define IDB_STATES 401
33+#define IDB_TBBUTTONS 401
34+#define IDB_STATES 402
2535
2636 #define IDM_MAINMENU 1101
2737
2838 #define IDM_FILE_EXIT 1201
2939 #define IDM_FILE_CHANGEINST 1202
30-#define IDM_VIEW_SHOWSTABLE 1203
31-#define IDM_VIEW_SHOWUNSTABLE 1204
32-#define IDM_SOURCES_MIRRORS 1205
40+#define IDM_EDIT_PREFERENCES 1203
41+#define IDM_SOURCES_MIRRORS 1204
--- a/resource.rc
+++ b/resource.rc
@@ -11,14 +11,14 @@
1111 CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mingw-get.manifest"
1212
1313
14+IDB_TBBUTTONS BITMAP "tbbuttons.bmp"
1415 IDB_STATES BITMAP "buttons.bmp"
1516
1617
1718 IDA_MAINACCEL ACCELERATORS
1819 BEGIN
1920 "I", IDM_FILE_CHANGEINST, CONTROL, ALT, VIRTKEY
20- "S", IDM_VIEW_SHOWSTABLE, CONTROL, SHIFT, VIRTKEY
21- "U", IDM_VIEW_SHOWUNSTABLE, CONTROL, SHIFT, VIRTKEY
21+ "P", IDM_EDIT_PREFERENCES, CONTROL, VIRTKEY
2222 "M", IDM_SOURCES_MIRRORS, CONTROL, VIRTKEY
2323 END
2424
@@ -30,10 +30,9 @@ BEGIN
3030 MENUITEM "Select &Installation...\tCtrl+Alt+I", IDM_FILE_CHANGEINST
3131 MENUITEM "E&xit\tAlt+F4", IDM_FILE_EXIT
3232 END
33- POPUP "&View"
33+ POPUP "&Edit"
3434 BEGIN
35- MENUITEM "Show only &stable versions\tCtrl+Shift+S", IDM_VIEW_SHOWSTABLE
36- MENUITEM "Show &unstable versions\tCtrl+Shift+U", IDM_VIEW_SHOWUNSTABLE
35+ MENUITEM "&Preferences...\tCtrl+P", IDM_EDIT_PREFERENCES
3736 END
3837 POPUP "Sour&ces"
3938 BEGIN
@@ -49,10 +48,15 @@ MENU IDM_MAINMENU
4948 STYLE DS_CENTER|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
5049 BEGIN
5150 CONTROL "", IDC_MAINTOOLBAR, TOOLBARCLASSNAME, TBSTYLE_WRAPABLE, 0, 0, 0, 0
52- COMBOBOX IDC_CATTYPE, 1, 28, 100, 271, CBS_DROPDOWNLIST|WS_TABSTOP
53- LISTBOX IDC_CATLIST, 1, 43, 100, 241, WS_BORDER|WS_VSCROLL|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_TABSTOP
51+ COMBOBOX IDC_CATTYPE, 0, 28, 100, 271, CBS_DROPDOWNLIST|WS_TABSTOP
52+ LISTBOX IDC_CATLIST, 0, 43, 100, 241, WS_BORDER|WS_VSCROLL|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_TABSTOP
53+ CONTROL "", IDC_VERTSASH, SASHWND_VERT_CLASSNAME, WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE, 101, 0, 4, 300
5454 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
55+ CONTROL "", IDC_HORZSASH, SASHWND_HORZ_CLASSNAME, WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE, 105, 156, 395, 8
56+ LTEXT "", IDC_DESCTITLE, 105, 157, 169, 10
57+ LTEXT "Version to install:", IDC_VTITEXT, 276, 105, 55, 8
58+ COMBOBOX IDC_INSTVERSION, 378, 157, 120, 100, CBS_DROPDOWNLIST|WS_TABSTOP|WS_DISABLED
59+ EDITTEXT IDC_FULLDESC, 105, 169, 391, 116, ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY|WS_BORDER|WS_TABSTOP
5660 CONTROL "", IDC_STATBAR, STATUSCLASSNAME, SBT_TOOLTIPS, 0, 0, 0, 0
5761 END
5862
--- /dev/null
+++ b/sash_wnd.c
@@ -0,0 +1,140 @@
1+
2+#define WIN32_LEAN_AND_MEAN
3+#include <windows.h>
4+#include "resource.h"
5+
6+
7+void NewVertSashPos(int, HWND);
8+void NewHorzSashPos(int, HWND);
9+void TransToClient(HWND, RECT*);
10+
11+static LRESULT CALLBACK SashWndProc
12+ (HWND hwnd,
13+ UINT uMsg,
14+ WPARAM wParam,
15+ LPARAM lParam)
16+{
17+ static PAINTSTRUCT ps;
18+ static HDC hdc;
19+ static HPEN pen, oldpen;
20+ static RECT tbrc, statrc, rc;
21+ static POINT tl, br;
22+ static int drag_offset;
23+
24+ switch (uMsg)
25+ {
26+ case WM_LBUTTONDOWN:
27+ GetWindowRect(hwnd, &rc);
28+ tl.x = rc.left; tl.y = rc.top; ScreenToClient(hwnd, &tl);
29+ br.x = rc.right; br.y = rc.bottom; ScreenToClient(hwnd, &br);
30+ if (br.x - tl.x < br.y - tl.y)
31+ drag_offset = LOWORD(lParam) - tl.x;
32+ else
33+ drag_offset = HIWORD(lParam) - tl.y;
34+
35+ SetCapture(hwnd);
36+
37+ GetClientRect(GetParent(hwnd), &rc);
38+ GetWindowRect(GetDlgItem(GetParent(hwnd), IDC_MAINTOOLBAR), &tbrc);
39+ TransToClient(GetParent(hwnd), &tbrc);
40+ GetWindowRect(GetDlgItem(GetParent(hwnd), IDC_STATBAR), &statrc);
41+ TransToClient(GetParent(hwnd), &statrc);
42+ if (br.x - tl.x < br.y - tl.y)
43+ {
44+ tl.x = rc.left + drag_offset;
45+ tl.y = rc.top + (tbrc.bottom - tbrc.top) + 6;
46+ br.x = rc.right + 1 + drag_offset - 8;
47+ br.y = rc.bottom + 1 - (statrc.bottom - statrc.top);
48+ }
49+ else
50+ {
51+ tl.x = rc.left;
52+ tl.y = rc.top + drag_offset + (tbrc.bottom - tbrc.top) + 6;
53+ br.x = rc.right + 1;
54+ br.y = rc.bottom + 1 - (statrc.bottom - statrc.top) + drag_offset - 8;
55+ }
56+ ClientToScreen(GetParent(hwnd), &tl);
57+ ClientToScreen(GetParent(hwnd), &br);
58+ SetRect(&rc, tl.x, tl.y, br.x, br.y);
59+ ClipCursor(&rc);
60+
61+ return 0;
62+
63+ case WM_MOUSEMOVE:
64+ if (wParam & MK_LBUTTON)
65+ {
66+ GetWindowRect(hwnd, &rc);
67+ tl.x = rc.left; tl.y = rc.top; ScreenToClient(GetParent(hwnd), &tl);
68+ br.x = rc.right; br.y = rc.bottom; ScreenToClient(GetParent(hwnd), &br);
69+ DWORD dwpos = GetMessagePos();
70+ POINT mpt; mpt.x = LOWORD(dwpos); mpt.y = HIWORD(dwpos);
71+ ScreenToClient(GetParent(hwnd), &mpt);
72+ if (br.x - tl.x < br.y - tl.y)
73+ NewVertSashPos(mpt.x - drag_offset, GetParent(hwnd));
74+ else
75+ NewHorzSashPos(mpt.y - drag_offset, GetParent(hwnd));
76+ }
77+ break;
78+
79+ case WM_LBUTTONUP:
80+ ClipCursor(0);
81+ ReleaseCapture();
82+ return 0;
83+
84+ case WM_PAINT:
85+ {
86+ GetWindowRect(hwnd, &rc);
87+ tl.x = rc.left; tl.y = rc.top; ScreenToClient(hwnd, &tl);
88+ br.x = rc.right; br.y = rc.bottom; ScreenToClient(hwnd, &br);
89+
90+ hdc = BeginPaint(hwnd, &ps);
91+
92+ pen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));
93+ oldpen = SelectObject(hdc, pen);
94+ MoveToEx(hdc, tl.x, tl.y, 0);
95+ if (br.x - tl.x < br.y - tl.y)
96+ LineTo(hdc, tl.x, br.y);
97+ else
98+ LineTo(hdc, br.x, tl.y);
99+ SelectObject(hdc, oldpen);
100+ DeleteObject(pen);
101+
102+ pen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));
103+ oldpen = SelectObject(hdc, pen);
104+ MoveToEx(hdc, br.x - 1, br.y - 1, 0);
105+ if (br.x - tl.x < br.y - tl.y)
106+ LineTo(hdc, br.x - 1, tl.y - 1);
107+ else
108+ LineTo(hdc, tl.x - 1, br.y - 1);
109+ SelectObject(hdc, oldpen);
110+ DeleteObject(pen);
111+
112+ EndPaint(hwnd, &ps);
113+ }
114+ return 0;
115+ }
116+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
117+}
118+
119+
120+int SashWnd_RegisterClasses(HINSTANCE hinstance)
121+{
122+ WNDCLASS wc;
123+ wc.style = 0;
124+ wc.lpfnWndProc = SashWndProc;
125+ wc.cbClsExtra = 0;
126+ wc.cbWndExtra = 0;
127+ wc.hInstance = hinstance;
128+ wc.hIcon = 0;
129+ wc.hCursor = LoadCursor(0, IDC_SIZEWE);
130+ wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
131+ wc.lpszMenuName = 0;
132+ wc.lpszClassName = SASHWND_VERT_CLASSNAME;
133+ if (!RegisterClass(&wc))
134+ return 0;
135+ wc.hCursor = LoadCursor(0, IDC_SIZENS);
136+ wc.lpszClassName = SASHWND_HORZ_CLASSNAME;
137+ if (!RegisterClass(&wc))
138+ return 0;
139+ return 1;
140+}
Binary files /dev/null and b/synaptic.ico differ
Binary files /dev/null and b/tbbuttons.bmp differ
--- a/ui_windowed.cpp
+++ b/ui_windowed.cpp
@@ -9,7 +9,8 @@
99 #include <list>
1010 #include "resource.h"
1111 #include "package.hpp"
12-#include "inst_manager.hpp"
12+#include "pkg_index.hpp"
13+#include "pkg_const.h"
1314
1415
1516 static HWND g_hmainwnd = 0;
@@ -18,6 +19,7 @@ static HWND g_hmainwnd = 0;
1819 extern "C" HWND CreateMainWnd(HINSTANCE);
1920 extern "C" int MainMessageLoop(HWND);
2021 extern "C" void SelectInst(HINSTANCE, HWND);
22+std::string GetBinDir();
2123
2224 extern "C" int UI_Windowed(HINSTANCE hinstance)
2325 {
@@ -25,6 +27,8 @@ extern "C" int UI_Windowed(HINSTANCE hinstance)
2527 if (!g_hmainwnd)
2628 return 1;
2729
30+ PkgIndex::LoadManifest(GetBinDir() + "\\mingw_avail.mft");
31+
2832 SelectInst(hinstance, g_hmainwnd);
2933
3034 return MainMessageLoop(g_hmainwnd);
@@ -40,9 +44,10 @@ static void LVAddPackage(const Package& pkg)
4044 lvi.iSubItem = 0;
4145 char emptystr = 0;
4246 lvi.pszText = &emptystr;
43- lvi.iImage = 1;
47+ lvi.iImage = pkg.GetStateImage();
4448 lvi.lParam = reinterpret_cast< LPARAM >(&pkg);
4549 lvi.iItem = ListView_InsertItem(hlist, &lvi);
50+ lvi.mask = LVIF_TEXT;
4651 lvi.pszText = LPSTR_TEXTCALLBACK;
4752 for (int i = 1; i <= 5; ++i)
4853 {
@@ -63,23 +68,23 @@ extern "C" void UI_NotifyCategoryChange(int sel)
6368 bool have_item = false;
6469 if (sel == 0)
6570 {
66- for (InstManager::PackageIter it = InstManager::Packages_Begin();
67- it != InstManager::Packages_End();
71+ for (PkgIndex::PackageIter it = PkgIndex::Packages_Begin();
72+ it != PkgIndex::Packages_End();
6873 ++it)
6974 {
70- LVAddPackage(*(it->second));
75+ LVAddPackage(**it);
7176 have_item = true;
7277 }
7378 }
7479 else
7580 {
76- for (InstManager::PackageIter it = InstManager::Packages_Begin();
77- it != InstManager::Packages_End();
81+ for (PkgIndex::PackageIter it = PkgIndex::Packages_Begin();
82+ it != PkgIndex::Packages_End();
7883 ++it)
7984 {
80- if (it->second->m_categories.count(sel - 1) > 0)
85+ if ((*it)->m_categories.count(sel - 1) > 0)
8186 {
82- LVAddPackage(*(it->second));
87+ LVAddPackage(**it);
8388 have_item = true;
8489 }
8590 }
@@ -90,7 +95,12 @@ extern "C" void UI_NotifyCategoryChange(int sel)
9095 LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
9196 }
9297 else
98+ {
99+ Static_SetText(GetDlgItem(g_hmainwnd, IDC_DESCTITLE), "");
93100 Edit_SetText(GetDlgItem(g_hmainwnd, IDC_FULLDESC), "");
101+ ComboBox_ResetContent(GetDlgItem(g_hmainwnd, IDC_INSTVERSION));
102+ EnableWindow(GetDlgItem(g_hmainwnd, IDC_INSTVERSION), FALSE);
103+ }
94104 }
95105
96106
@@ -100,10 +110,69 @@ extern "C" void UI_OnListViewSelect(int sel)
100110 {
101111 LVITEM lvitem;
102112 lvitem.iItem = sel;
113+ lvitem.iSubItem = 0;
103114 lvitem.mask = LVIF_PARAM;
104115 ListView_GetItem(GetDlgItem(g_hmainwnd, IDC_COMPLIST), &lvitem);
116+ Package* pkg = reinterpret_cast< Package* >(lvitem.lParam);
105117 Edit_SetText(GetDlgItem(g_hmainwnd, IDC_FULLDESC),
106- reinterpret_cast< Package* >(lvitem.lParam)->m_description.c_str());
118+ pkg->m_description.c_str());
119+ Static_SetText(GetDlgItem(g_hmainwnd, IDC_DESCTITLE),
120+ pkg->m_title.c_str());
121+ ComboBox_ResetContent(GetDlgItem(g_hmainwnd, IDC_INSTVERSION));
122+ if (pkg->m_versions.size() > 0)
123+ {
124+ EnableWindow(GetDlgItem(g_hmainwnd, IDC_INSTVERSION), TRUE);
125+ std::string vstr;
126+ for (std::vector< PkgVersion::Ref >::const_iterator it = pkg->m_versions.begin();
127+ it != pkg->m_versions.end();
128+ ++it)
129+ {
130+ if ((*it)->m_status == PSTATUS_ALPHA)
131+ vstr = "Alpha: ";
132+ else
133+ vstr = "Stable: ";
134+ vstr += (*it)->m_version;
135+ ComboBox_AddString(GetDlgItem(g_hmainwnd, IDC_INSTVERSION),
136+ vstr.c_str());
137+ }
138+ pkg->m_selected_version = 0;
139+ ComboBox_SetCurSel(GetDlgItem(g_hmainwnd, IDC_INSTVERSION), 0);
140+ }
141+ else
142+ {
143+ pkg->m_selected_version = -1;
144+ EnableWindow(GetDlgItem(g_hmainwnd, IDC_INSTVERSION), FALSE);
145+ }
146+}
147+
148+
149+extern "C" int VersionCompare(const char*, const char*);
150+
151+extern "C" void UI_OnStateCycle(int sel)
152+{
153+ LVITEM lvitem;
154+ lvitem.iItem = sel;
155+ lvitem.iSubItem = 0;
156+ lvitem.mask = LVIF_PARAM;
157+ ListView_GetItem(GetDlgItem(g_hmainwnd, IDC_COMPLIST), &lvitem);
158+ Package* pkg = reinterpret_cast< Package* >(lvitem.lParam);
159+ if (pkg->m_installed_version.length() > 0)
160+ {
161+ if (pkg->m_selected_action == ACT_INSTALL_VERSION)
162+ pkg->m_selected_action = ACT_NO_CHANGE;
163+ else
164+ pkg->m_selected_action = ACT_INSTALL_VERSION;
165+ }
166+ else
167+ {
168+ if (pkg->m_selected_action == ACT_INSTALL_VERSION)
169+ pkg->m_selected_action = ACT_NO_CHANGE;
170+ else
171+ pkg->m_selected_action = ACT_INSTALL_VERSION;
172+ }
173+ lvitem.mask = LVIF_IMAGE;
174+ lvitem.iImage = pkg->GetStateImage();
175+ ListView_SetItem(GetDlgItem(g_hmainwnd, IDC_COMPLIST), &lvitem);
107176 }
108177
109178
@@ -138,10 +207,19 @@ int CALLBACK LVSortCompare(LPARAM lp1, LPARAM lp2, LPARAM lpsort)
138207 );
139208 break;
140209 case 3:
141- ret = VersionCompare(
142- reinterpret_cast< Package* >(lp1)->m_stable_version.c_str(),
143- reinterpret_cast< Package* >(lp2)->m_stable_version.c_str()
144- );
210+ {
211+ const Package& p1 = *(reinterpret_cast< Package* >(lp1));
212+ const Package& p2 = *(reinterpret_cast< Package* >(lp2));
213+ const char* p1v = (p1.m_versions.size() > 0)
214+ ? p1.m_versions.front()->m_version.c_str() : "";
215+ const char* p2v = (p2.m_versions.size() > 0)
216+ ? p2.m_versions.front()->m_version.c_str() : "";
217+ ret = VersionCompare(p1v, p2v);
218+ }
219+ break;
220+ case 5:
221+ ret = stricmp(reinterpret_cast< Package* >(lp1)->m_title.c_str(),
222+ reinterpret_cast< Package* >(lp2)->m_title.c_str());
145223 break;
146224 };
147225 return ret * st->m_reverse;
@@ -165,6 +243,7 @@ extern "C" void UI_SortListView(int column)
165243
166244 void UI::ResetLists()
167245 {
246+ ListBox_SetCurSel(GetDlgItem(g_hmainwnd, IDC_CATLIST), 0);
168247 int ct = ListBox_GetCount(GetDlgItem(g_hmainwnd, IDC_CATLIST));
169248 for (; ct > 1; --ct)
170249 ListBox_DeleteString(GetDlgItem(g_hmainwnd, IDC_CATLIST), ct - 1);