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