4e105a313e1f26ff62a9e4cf9f309d206bdb75f8
[reactos.git] / rosapps / winfile / entries.c
1 /*
2 * ReactOS winfile
3 *
4 * entries.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 <windowsx.h>
38
39 #include "main.h"
40 #include "entries.h"
41 #include "utils.h"
42
43
44
45 Entry* find_entry_win(Entry* parent, LPCTSTR name)
46 {
47 Entry* entry;
48
49 for(entry=parent->down; entry; entry=entry->next) {
50 LPCTSTR p = name;
51 LPCTSTR q = entry->data.cFileName;
52
53 do {
54 if (!*p || *p==_T('\\') || *p==_T('/'))
55 return entry;
56 } while(tolower(*p++) == tolower(*q++));
57
58 p = name;
59 q = entry->data.cAlternateFileName;
60
61 do {
62 if (!*p || *p==_T('\\') || *p==_T('/'))
63 return entry;
64 } while(tolower(*p++) == tolower(*q++));
65 }
66
67 return 0;
68 }
69
70
71 Entry* read_tree_win(Root* root, LPCTSTR path, int sortOrder)
72 {
73 TCHAR buffer[MAX_PATH];
74 Entry* entry = &root->entry;
75 LPCTSTR s = path;
76 PTSTR d = buffer;
77
78 #ifndef _NO_EXTENSIONS
79 entry->unix_dir = FALSE;
80 #endif
81
82 while(entry) {
83 while(*s && *s!=_T('\\') && *s!=_T('/'))
84 *d++ = *s++;
85
86 while(*s==_T('\\') || *s==_T('/'))
87 s++;
88
89 *d++ = _T('\\');
90 *d = _T('\0');
91
92 read_directory(entry, buffer, sortOrder);
93
94 if (entry->down)
95 entry->expanded = TRUE;
96
97 if (!*s)
98 break;
99
100 entry = find_entry_win(entry, s);
101 }
102
103 return entry;
104 }
105
106
107 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
108
109 static Entry* find_entry_unix(Entry* parent, LPCTSTR name)
110 {
111 Entry* entry;
112
113 for(entry=parent->down; entry; entry=entry->next) {
114 LPCTSTR p = name;
115 LPCTSTR q = entry->data.cFileName;
116
117 do {
118 if (!*p || *p==_T('/'))
119 return entry;
120 } while(*p++ == *q++);
121 }
122
123 return 0;
124 }
125
126 static Entry* read_tree_unix(Root* root, LPCTSTR path, int sortOrder)
127 {
128 TCHAR buffer[MAX_PATH];
129 Entry* entry = &root->entry;
130 LPCTSTR s = path;
131 PTSTR d = buffer;
132
133 entry->unix_dir = TRUE;
134
135 while(entry) {
136 while(*s && *s!=_T('/'))
137 *d++ = *s++;
138
139 while(*s == _T('/'))
140 s++;
141
142 *d++ = _T('/');
143 *d = _T('\0');
144
145 read_directory(entry, buffer, sortOrder);
146
147 if (entry->down)
148 entry->expanded = TRUE;
149
150 if (!*s)
151 break;
152
153 entry = find_entry_unix(entry, s);
154 }
155
156 return entry;
157 }
158
159 #endif
160
161
162 // recursively free all child entries
163 void free_entries(Entry* parent)
164 {
165 Entry *entry, *next=parent->down;
166
167 if (next) {
168 parent->down = 0;
169 do {
170 entry = next;
171 next = entry->next;
172 free_entries(entry);
173 free(entry);
174 } while(next);
175 }
176 }
177
178 // insert listbox entries after index idx
179 void insert_entries(Pane* pane, Entry* parent, int idx)
180 {
181 /*
182 Entry* entry = parent;
183
184 if (!entry)
185 return;
186 ShowWindow(pane->hWnd, SW_HIDE);
187 for(; entry; entry=entry->next) {
188 #ifndef _LEFT_FILES
189 if (pane->treePane && !(entry->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
190 continue;
191 #endif
192 // don't display entries "." and ".." in the left pane
193 if (pane->treePane && (entry->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
194 && entry->data.cFileName[0]==_T('.'))
195 if (
196 #ifndef _NO_EXTENSIONS
197 entry->data.cFileName[1]==_T('\0') ||
198 #endif
199 (entry->data.cFileName[1]==_T('.') && entry->data.cFileName[2]==_T('\0')))
200 continue;
201 if (idx != -1)
202 idx++;
203 ListBox_InsertItemData(pane->hWnd, idx, entry);
204 if (pane->treePane && entry->expanded)
205 insert_entries(pane, entry->down, idx);
206 }
207 ShowWindow(pane->hWnd, SW_SHOW);
208 */
209 }
210
211
212 void scan_entry(ChildWnd* child, Entry* entry)
213 {
214 TCHAR path[MAX_PATH];
215 /*
216 int idx = ListBox_GetCurSel(child->left.hWnd);
217 HCURSOR crsrOld = SetCursor(LoadCursor(0, IDC_WAIT));
218
219 // delete sub entries in left pane
220 for(;;) {
221 LRESULT res = ListBox_GetItemData(child->left.hWnd, idx+1);
222 Entry* sub = (Entry*) res;
223
224 if (res==LB_ERR || !sub || sub->level<=entry->level)
225 break;
226
227 ListBox_DeleteString(child->left.hWnd, idx+1);
228 }
229
230 // empty right pane
231 ListBox_ResetContent(child->right.hWnd);
232 */
233 // release memory
234 free_entries(entry);
235
236 // read contents from disk
237 get_path(entry, path);
238 read_directory(entry, path, child->sortOrder);
239 /*
240 // insert found entries in right pane
241 insert_entries(&child->right, entry->down, -1);
242 calc_widths(&child->right, FALSE);
243 #ifndef _NO_EXTENSIONS
244 set_header(&child->right);
245 #endif
246
247 child->header_wdths_ok = FALSE;
248
249 SetCursor(crsrOld);
250 */
251 }
252
253
254 // expand a directory entry
255 BOOL expand_entry(ChildWnd* child, Entry* dir)
256 {
257 int idx;
258 Entry* p;
259
260 if (!dir || dir->expanded || !dir->down)
261 return FALSE;
262
263 p = dir->down;
264
265 if (p->data.cFileName[0]=='.' && p->data.cFileName[1]=='\0' && p->next) {
266 p = p->next;
267
268 if (p->data.cFileName[0]=='.' && p->data.cFileName[1]=='.' &&
269 p->data.cFileName[2]=='\0' && p->next)
270 p = p->next;
271 }
272
273 // no subdirectories ?
274 if (!(p->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
275 return FALSE;
276 /*
277 idx = ListBox_FindItemData(child->left.hWnd, 0, dir);
278 */
279 dir->expanded = TRUE;
280
281 // insert entries in left pane
282 insert_entries(&child->left, p, idx);
283 /*
284 if (!child->header_wdths_ok) {
285 if (calc_widths(&child->left, FALSE)) {
286 #ifndef _NO_EXTENSIONS
287 set_header(&child->left);
288 #endif
289
290 child->header_wdths_ok = TRUE;
291 }
292 }
293 */
294 return TRUE;
295 }
296
297
298 void collapse_entry(Pane* pane, Entry* dir)
299 {
300 int idx = ListBox_FindItemData(pane->hWnd, 0, dir);
301
302 ShowWindow(pane->hWnd, SW_HIDE);
303
304 // hide sub entries
305 for(;;) {
306 LRESULT res = ListBox_GetItemData(pane->hWnd, idx+1);
307 Entry* sub = (Entry*) res;
308
309 if (res==LB_ERR || !sub || sub->level<=dir->level)
310 break;
311
312 ListBox_DeleteString(pane->hWnd, idx+1);
313 }
314
315 dir->expanded = FALSE;
316
317 ShowWindow(pane->hWnd, SW_SHOW);
318 }
319
320
321 void activate_entry(ChildWnd* child, Pane* pane)
322 {
323 Entry* entry = pane->cur;
324
325 if (!entry)
326 return;
327
328 if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
329 int scanned_old = entry->scanned;
330
331 if (!scanned_old)
332 scan_entry(child, entry);
333
334 #ifndef _NO_EXTENSIONS
335 if (entry->data.cFileName[0]=='.' && entry->data.cFileName[1]=='\0')
336 return;
337 #endif
338
339 if (entry->data.cFileName[0]=='.' && entry->data.cFileName[1]=='.' && entry->data.cFileName[2]=='\0') {
340 entry = child->left.cur->up;
341 collapse_entry(&child->left, entry);
342 goto focus_entry;
343 } else if (entry->expanded)
344 collapse_entry(pane, child->left.cur);
345 else {
346 expand_entry(child, child->left.cur);
347
348 if (!pane->treePane) focus_entry: {
349 int idx = ListBox_FindItemData(child->left.hWnd, ListBox_GetCurSel(child->left.hWnd), entry);
350 ListBox_SetCurSel(child->left.hWnd, idx);
351 set_curdir(child, entry);
352 }
353 }
354
355 if (!scanned_old) {
356 calc_widths(pane, FALSE);
357
358 #ifndef _NO_EXTENSIONS
359 set_header(pane);
360 #endif
361 }
362 } else {
363
364 //TODO: start program, open document...
365
366 }
367 }