Updated with progress work.
[reactos.git] / rosapps / winfile / treeview.c
1 /*
2 * ReactOS winfile
3 *
4 * treeview.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #ifdef _MSC_VER
24 #include "stdafx.h"
25 #else
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <memory.h>
32 #include <tchar.h>
33 #include <process.h>
34 #include <stdio.h>
35 #endif
36
37 #include <shellapi.h>
38 //#include <winspool.h>
39 #include <windowsx.h>
40 #include <shellapi.h>
41 #include <ctype.h>
42 #include <assert.h>
43 #define ASSERT assert
44
45 #include "winfile.h"
46 #include "treeview.h"
47 #include "entries.h"
48 #include "utils.h"
49
50
51 // Global Variables:
52 extern HINSTANCE hInst;
53
54
55 // Global variables and constants
56 // Image_Open, Image_Closed, and Image_Root - integer variables for
57 // indexes of the images.
58 // CX_BITMAP and CY_BITMAP - width and height of an icon.
59 // NUM_BITMAPS - number of bitmaps to add to the image list.
60 int Image_Open;
61 int Image_Closed;
62 int Image_Root;
63
64 #define CX_BITMAP 16
65 #define CY_BITMAP 16
66 #define NUM_BITMAPS 3
67
68
69 // AddItemToTree - adds items to a tree view control.
70 // Returns the handle to the newly added item.
71 // hwndTV - handle to the tree view control.
72 // lpszItem - text of the item to add.
73 // nLevel - level at which to add the item.
74
75 HTREEITEM AddItemToTree(HWND hwndTV, LPSTR lpszItem, int nLevel)
76 {
77 TVITEM tvi;
78 TVINSERTSTRUCT tvins;
79 static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
80 static HTREEITEM hPrevRootItem = NULL;
81 static HTREEITEM hPrevLev2Item = NULL;
82 HTREEITEM hti;
83
84 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
85
86 // Set the text of the item.
87 tvi.pszText = lpszItem;
88 tvi.cchTextMax = lstrlen(lpszItem);
89
90 // Assume the item is not a parent item, so give it an image.
91 tvi.iImage = Image_Root;
92 tvi.iSelectedImage = Image_Root;
93
94 tvi.cChildren = 1;
95
96
97 // Save the heading level in the item's application-defined data area.
98 tvi.lParam = (LPARAM)nLevel;
99
100 tvins.item = tvi;
101 tvins.hInsertAfter = hPrev;
102
103 // Set the parent item based on the specified level.
104 if (nLevel == 1)
105 tvins.hParent = TVI_ROOT;
106 else if (nLevel == 2)
107 tvins.hParent = hPrevRootItem;
108 else
109 tvins.hParent = hPrevLev2Item;
110
111 // Add the item to the tree view control.
112 hPrev = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
113
114 // Save the handle to the item.
115 if (nLevel == 1)
116 hPrevRootItem = hPrev;
117 else if (nLevel == 2)
118 hPrevLev2Item = hPrev;
119
120 // The new item is a child item. Give the parent item a
121 // closed folder bitmap to indicate it now has child items.
122 if (nLevel > 1) {
123 hti = TreeView_GetParent(hwndTV, hPrev);
124 tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
125 tvi.hItem = hti;
126 tvi.iImage = Image_Closed;
127 tvi.iSelectedImage = Image_Closed;
128 TreeView_SetItem(hwndTV, &tvi);
129 }
130
131 return hPrev;
132 }
133
134 // InitTreeViewItems - extracts headings from the specified file and
135 // passes them to a function that adds them to a tree view control.
136 // Returns TRUE if successful, or FALSE otherwise.
137 // hwndTV - handle to the tree view control.
138 // lpszFileName - name of file with headings.
139
140 BOOL InitTreeViewItems(HWND hwndTV, LPSTR lpszFileName)
141 {
142 HTREEITEM hItem;
143
144 hItem = AddItemToTree(hwndTV, "C:\\ - FAT32", 1);
145 AddItemToTree(hwndTV, "reactos", 2);
146 AddItemToTree(hwndTV, "bin", 3);
147 AddItemToTree(hwndTV, "media", 3);
148 // AddItemToTree(hwndTV, "fonts", 4);
149 AddItemToTree(hwndTV, "symbols", 3);
150 AddItemToTree(hwndTV, "system32", 3);
151 // AddItemToTree(hwndTV, "config", 4);
152 // AddItemToTree(hwndTV, "drivers", 4);
153
154 TreeView_Expand(hwndTV, hItem, TVE_EXPAND);
155 return TRUE;
156 }
157
158 // InitTreeViewImageLists - creates an image list, adds three bitmaps
159 // to it, and associates the image list with a tree view control.
160 // Returns TRUE if successful, or FALSE otherwise.
161 // hwndTV - handle to the tree view control.
162
163 BOOL InitTreeViewImageLists(HWND hwndTV)
164 {
165 HIMAGELIST himl; // handle to image list
166 HBITMAP hbmp; // handle to bitmap
167
168 // Create the image list.
169 if ((himl = ImageList_Create(CX_BITMAP, CY_BITMAP,
170 FALSE, NUM_BITMAPS, 0)) == NULL)
171 return FALSE;
172
173 // Add the open file, closed file, and document bitmaps.
174 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FILE));
175 Image_Open = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
176 DeleteObject(hbmp);
177
178 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FILE));
179 Image_Closed = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
180 DeleteObject(hbmp);
181
182 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ROOT));
183 Image_Root = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
184 DeleteObject(hbmp);
185
186 // Fail if not all of the images were added.
187 if (ImageList_GetImageCount(himl) < 3)
188 return FALSE;
189
190 // Associate the image list with the tree view control.
191 TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
192
193 return TRUE;
194 }
195
196 // CreateTreeView - creates a tree view control.
197 // Returns the handle to the new control if successful,
198 // or NULL otherwise.
199 // hwndParent - handle to the control's parent window.
200 // lpszFileName - name of the file to parse for tree view items.
201
202 HWND CreateTreeView(HWND hwndParent, LPSTR lpszFileName)
203 {
204 RECT rcClient; // dimensions of client area
205 HWND hwndTV; // handle to tree view control
206
207 // Get the dimensions of the parent window's client area, and create
208 // the tree view control.
209 GetClientRect(hwndParent, &rcClient);
210 hwndTV = CreateWindowEx(0, WC_TREEVIEW, "Tree View",
211 WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
212 0, 0, rcClient.right, rcClient.bottom,
213 hwndParent, (HMENU)TREE_WINDOW, hInst, NULL);
214 /*
215 hwndTV = CreateWindow(_T("ListBox"), _T(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
216 LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
217 0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0);
218 */
219 // Initialize the image list, and add items to the control.
220 if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, lpszFileName)) {
221 DestroyWindow(hwndTV);
222 return NULL;
223 }
224 return hwndTV;
225 }
226
227 ////////////////////////////////////////////////////////////////////////////////
228 static WNDPROC g_orgTreeWndProc;
229
230 LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
231 {
232 ChildWnd* child = (ChildWnd*)GetWindowLong(GetParent(hwnd), GWL_USERDATA);
233 Pane* pane = (Pane*)GetWindowLong(hwnd, GWL_USERDATA);
234 ASSERT(child);
235
236 switch(nmsg) {
237 #ifndef _NO_EXTENSIONS
238 case WM_HSCROLL:
239 set_header(pane);
240 break;
241 #endif
242
243 case WM_SETFOCUS:
244 child->focus_pane = pane==&child->right? 1: 0;
245 ListBox_SetSel(hwnd, TRUE, 1);
246 //TODO: check menu items
247 break;
248
249 case WM_KEYDOWN:
250 if (wparam == VK_TAB) {
251 //TODO: SetFocus(Globals.hDriveBar)
252 SetFocus(child->focus_pane? child->left.hwnd: child->right.hwnd);
253 }
254 }
255
256 return CallWindowProc(g_orgTreeWndProc, hwnd, nmsg, wparam, lparam);
257 }
258
259
260 static void init_output(HWND hwnd)
261 {
262 TCHAR b[16];
263 HFONT old_font;
264 HDC hdc = GetDC(hwnd);
265
266 if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, _T("1000"), 0, b, 16) > 4)
267 Globals.num_sep = b[1];
268 else
269 Globals.num_sep = _T('.');
270
271 old_font = SelectFont(hdc, Globals.hFont);
272 GetTextExtentPoint32(hdc, _T(" "), 1, &Globals.spaceSize);
273 SelectFont(hdc, old_font);
274 ReleaseDC(hwnd, hdc);
275 }
276
277
278 void create_tree_window(HWND parent, Pane* pane, int id, int id_header, LPSTR lpszFileName)
279 {
280 static int s_init = 0;
281 Entry* entry = pane->root;
282 #if 1
283 pane->hwnd = CreateTreeView(parent, lpszFileName);
284 #else
285 pane->hwnd = CreateWindow(_T("ListBox"), _T(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
286 // LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
287 LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_NOTIFY,
288 0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0);
289 #endif
290 SetWindowLong(pane->hwnd, GWL_USERDATA, (LPARAM)pane);
291 g_orgTreeWndProc = SubclassWindow(pane->hwnd, TreeWndProc);
292
293 SendMessage(pane->hwnd, WM_SETFONT, (WPARAM)Globals.hFont, FALSE);
294
295 // insert entries into listbox
296 if (entry)
297 insert_entries(pane, entry, -1);
298
299 // calculate column widths
300 if (!s_init) {
301 s_init = 1;
302 init_output(pane->hwnd);
303 }
304
305 calc_widths(pane, TRUE);
306
307 #ifndef _NO_EXTENSIONS
308 pane->hwndHeader = create_header(parent, pane, id_header);
309 #endif
310 }
311
312
313