eb06779f06967a329384a6c0cb6c696a99814444
[reactos.git] / rosapps / packmgr / gui / main.cpp
1 ////////////////////////////////////////////////////////
2 //
3 // main.cpp
4 //
5 // Implementation of the Package Manager GUI
6 //
7 //
8 // Maarten Bosma, 09.01.2004
9 // maarten.paul@bosma.de
10 //
11 ////////////////////////////////////////////////////////////////////
12
13 #include "main.h"
14
15
16 // Application's Entry Point
17 int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
18 {
19 HWND hwnd;
20 MSG msg;
21 WNDCLASSEX wc = {0};
22
23 // Window creation
24 wc.cbSize = sizeof(WNDCLASSEX);
25 wc.lpszClassName = L"pgkmgr";
26 wc.style = CS_HREDRAW | CS_VREDRAW;
27 wc.lpfnWndProc = (WNDPROC)WndProc;
28 wc.hInstance = hinst;
29 wc.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));
30 wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR);
31
32 RegisterClassEx(&wc);
33
34 hwnd = CreateWindow(L"pgkmgr",
35 L"ReactOS - Package Manager v0.3",
36 WS_OVERLAPPEDWINDOW,
37 CW_USEDEFAULT,
38 CW_USEDEFAULT,
39 500, 600,
40 NULL, NULL,
41 hinst,
42 NULL);
43
44
45 // Toolbar creation
46 InitCommonControls();
47
48 hTBar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, 0, 8, hinst, IDB_TOOLBAR,
49 Buttons, sizeof(Buttons)/sizeof(TBBUTTON), TBSIZE, TBSIZE, TBSIZE, TBSIZE, sizeof(TBBUTTON));
50
51 // Show the windows
52 ShowWindow(hwnd, SW_SHOW);
53 UpdateWindow(hwnd);
54
55 // Load the tree
56 int error = PML_LoadTree(&tree, "tree.xml", AddItem);
57
58 if(error)
59 {
60 MessageBox(0,PML_TransError(error),0,0);
61 return 0;
62 }
63
64 // Read the help
65 Help();
66
67 // Start getting messages
68 while(GetMessage(&msg,NULL,0,0))
69 {
70 TranslateMessage(&msg);
71 DispatchMessage(&msg);
72 }
73
74 // Close our handle
75 PML_CloseTree (tree);
76
77 return 0;
78 }
79
80 // Add a item to our tree
81 int AddItem (int id, const char* name, int parent, int icon)
82 {
83 TV_INSERTSTRUCT tvins;
84
85 tvins.item.lParam = (UINT)id;
86 tvins.item.mask = TVIF_TEXT|TVIF_PARAM;
87 tvins.item.pszText = (WCHAR*)name; //that is ok
88 tvins.item.cchTextMax = strlen(name);
89 tvins.hInsertAfter = TVI_LAST;
90
91 if(icon)
92 {
93 tvins.item.iImage = icon;
94 tvins.item.iSelectedImage = icon;
95 tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
96 }
97
98 if (parent==0)
99 tvins.hParent = TVI_ROOT;
100 else
101 tvins.hParent = nodes[parent];
102
103 nodes[id] = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMA, 0, (LPARAM)&tvins);
104
105 return 0;
106 }
107
108 // Load the Help from file and display it
109 void Help (void)
110 {
111 string source;
112
113 ifstream file("help.txt", ios_base::in);
114 getline(file, source, '\0');
115
116 SetText(source.c_str());
117 }
118
119 // Create our Controls
120 void InitControls (HWND hwnd)
121 {
122
123 HINSTANCE hinst = GetModuleHandle(NULL);
124
125 // Create the controls
126 hTree = CreateWindowEx(0, WC_TREEVIEW, L"TreeView", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS,
127 0, 0, 0, 0, hwnd, NULL, hinst, NULL);
128
129 hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"edit", PML_TransError(IDS_LOAD), WS_CHILD|WS_VISIBLE|ES_MULTILINE,
130 0, 0, 100, 100, hwnd, NULL, hinst, NULL);
131
132 hPopup = LoadMenu(hinst, MAKEINTRESOURCE(IDR_POPUP));
133
134 // Create Tree Icons
135 HIMAGELIST hIcon = ImageList_Create(16,16,ILC_COLOR32,1,1);
136 SendMessage(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hIcon);
137
138 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(1)));
139 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(11)));
140 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(12)));
141 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(13)));
142 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(14)));
143
144 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(2)));
145 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(3)));
146 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(4)));
147 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(5)));
148 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(6)));
149 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(7)));
150 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(8)));
151 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(9)));
152 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(10)));
153
154 // Setup Hotkeys
155 RegisterHotKey(hwnd, 1, MOD_CONTROL, VK_1);
156 RegisterHotKey(hwnd, 2, MOD_CONTROL, VK_2);
157 RegisterHotKey(hwnd, 3, MOD_CONTROL, VK_3);
158 RegisterHotKey(hwnd, 4, MOD_CONTROL, VK_4);
159 RegisterHotKey(hwnd, 0, MOD_CONTROL, VK_0);
160 }
161
162 // Set the Icons
163 int SetIcon (int id, int icon)
164 {
165 TVITEMEX item;
166
167 item.hItem = nodes[id];
168 item.iImage = icon;
169 item.iSelectedImage = icon;
170 item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
171
172 TreeView_SetItem(hTree, &item);
173
174 return 1;
175 }
176
177 // Set the Icons
178 int Ask (const WCHAR* message)
179 {
180 int ans = MessageBox (0,message,0,MB_YESNO);
181
182 if(ans == IDYES)
183 return 1;
184
185 return 0;
186 }
187
188 // En- or Disable a Button inside of the toolbar and the Context Menu
189 int SetButton (DWORD id, BOOL state)
190 {
191 // Change the Toorbar Button
192 TBBUTTONINFO ti;
193
194 ti.cbSize = sizeof (ti);
195 ti.dwMask = TBIF_STATE;
196 /*
197 if(state&&id==1)
198 MessageBox(0,L"on",0,0);
199 else if(!state&&id==1)
200 MessageBox(0,L"off",0,0);
201 */
202 if(state)
203 ti.fsState = TBSTATE_ENABLED;
204 else
205 ti.fsState = TBSTATE_INDETERMINATE;
206
207 SendMessage (hTBar, TB_SETBUTTONINFO, id, (LPARAM)&ti);
208
209 // Change the Context Menu item
210 MENUITEMINFO mi;
211
212 mi.cbSize = sizeof (mi);
213 mi.fMask = MIIM_STATE;
214
215 if(state)
216 mi.fState = MFS_ENABLED;
217
218 else
219 mi.fState = MFS_GRAYED;
220
221 SetMenuItemInfo(hPopup, id, FALSE, &mi);
222
223 return 0;
224 }
225
226 // Set the text of the text box
227 int SetText (const char* text)
228 {
229 if(!text)
230 return 1;
231
232 int i = 0;
233 string source = text;
234
235 // the windows does not need "\n"
236 // for new lines but "\r\n"
237 for(i=0; source[i]; i++)
238 if(source[i]=='\n' && source[i]!='\r')
239 source.insert (i++, "\r");
240
241 SetWindowTextA(hEdit, source.c_str());
242
243 return 0;
244 }
245
246 // Windows Message Callback (this is where most things happen)
247 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
248 {
249 switch (message)
250 {
251 // at the very beginning ...
252 case WM_CREATE:
253 {
254 InitControls(hwnd);
255 }
256 break;
257
258 // calculate the size of the controls
259 case WM_SIZE:
260 {
261 RECT rcl;
262 SendMessage(hTBar, TB_AUTOSIZE, 0L, 0L);
263 GetWindowRect(hTBar, &rcl);
264
265 int win_top = rcl.bottom - rcl.top;
266 int win_hight = HIWORD(lParam) - win_top;
267
268 MoveWindow(hTree, 0, win_top, LOWORD(lParam), splitter_pos*win_hight/100, TRUE);
269 MoveWindow(hEdit, 0, (splitter_pos*win_hight/100)+win_top, LOWORD(lParam), win_hight, TRUE);
270 }
271 break;
272
273 // for the treeview
274 case WM_NOTIFY:
275 {
276 if(((LPNMHDR)lParam)->code == TVN_SELCHANGED)
277 {
278 selected = ((LPNMTREEVIEW)lParam)->itemNew.lParam;
279 PML_LoadPackage (tree, selected, SetButton);
280 SetText(PML_GetDescription (tree, selected));
281 }
282
283 else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= ahhh LISP
284 {
285 // which item has been click on
286 HTREEITEM item = TreeView_GetDropHilight(hTree);
287
288 if(item != NULL)
289 {
290 // mark the one as seleacted
291 SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item);
292 TreeView_EnsureVisible (hTree, item);
293 }
294
295 // create the context menu
296 if(selected != 0)
297 {
298 POINT pt;
299 GetCursorPos (&pt);
300 TrackPopupMenu (GetSubMenu(hPopup, 0), 0, (UINT)pt.x, (UINT)pt.y, 0, hwnd, NULL);
301 }
302 }
303 }
304 break;
305
306 // for the toolbar
307 case WM_COMMAND:
308 {
309 // All Actions
310 if(LOWORD(wParam) <= 5 && LOWORD(wParam) >= 1)
311 {
312 if(selected)
313 if(PML_SetAction(tree, selected, LOWORD(wParam)-1, SetIcon, Ask) == ERR_OK)
314 break;
315
316 MessageBeep(MB_ICONHAND);
317 }
318
319 // DoIt
320 else if(LOWORD(wParam)==6)
321 {
322 if(PML_DoIt(tree, SetStatus, Ask) == ERR_OK)
323 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DOIT), hwnd, StatusProc);
324 else
325 MessageBeep(MB_ICONHAND);
326 }
327
328 // Help
329 else if(LOWORD(wParam)==7)
330 Help();
331
332 // Options
333 else if(LOWORD(wParam)==8)
334 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsProc);
335
336 else
337 MessageBox(0,0,0,0);
338 }
339 break;
340
341 // prozess hotkeys
342 case WM_HOTKEY:
343 {
344 if(PML_SetAction(tree, selected, wParam, SetIcon, Ask) != ERR_OK)
345 MessageBeep(MB_ICONHAND);
346 }
347 break;
348
349 // ... at the very end
350 case WM_DESTROY:
351 {
352 PostQuitMessage(0);
353 return 0;
354 }
355 }
356
357 return DefWindowProc (hwnd, message, wParam, lParam);
358 }
359
360 // Warning: This function is called from another thread
361 int SetStatus (int status1, int status2, WCHAR* text)
362 {
363 // Set the Rage to 1000
364 SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETRANGE32, 0, 1000);
365 SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETRANGE32, 0, 1000);
366
367 // The prozessbars and the text filds
368 if(text)
369 SetDlgItemText(hStatus, IDC_TSTATUS, text);
370
371 if(status1!=-1)
372 SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETPOS, status1, 0);
373
374 if(status2!=-1)
375 SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETPOS, status2, 0);
376
377 // If the Status is 1000 very thing is done
378 if(status1==1000)
379 {
380 EndDialog(hStatus, TRUE);
381 MessageBox(0,PML_TransError(status2),0,0);
382 }
383
384 return 0;
385 }
386
387 // Callback for the Status Dialog
388 INT_PTR CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
389 {
390 switch (msg)
391 {
392 case WM_INITDIALOG:
393 {
394 hStatus = hwnd;
395
396 } break;
397
398 case WM_COMMAND: // can only be the about button
399 case WM_CLOSE: // the close-window-[x]
400 {
401 PML_Abort();
402 EndDialog(hwnd, TRUE);
403 return 0;
404 }
405 }
406
407 return 0;
408 }
409
410 // Callback for the Options Dialog
411 INT_PTR CALLBACK OptionsProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
412 {
413 switch (msg)
414 {
415 case WM_CLOSE:
416 EndDialog(hwnd, TRUE);
417 return 0;
418 }
419
420 return 0;
421 }