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