1 /*
2 * Copyright 2003, 2004, 2005 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19
20 //
21 // Explorer clone
22 //
23 // filechild.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27
28
29 #include <precomp.h>
30
31 #include "ntobjfs.h"
32 #include "regfs.h"
33 #include "fatfs.h"
34
FileChildWndInfo(HWND hmdiclient,LPCTSTR path,ENTRY_TYPE etype)35 FileChildWndInfo::FileChildWndInfo(HWND hmdiclient, LPCTSTR path, ENTRY_TYPE etype)
36 : super(hmdiclient),
37 _etype(etype)
38 {
39 #ifndef _NO_WIN_FS
40 if (etype == ET_UNKNOWN)
41 #ifdef __WINE__
42 if (*path == '/')
43 _etype = ET_UNIX;
44 else
45 #endif
46 _etype = ET_WINDOWS;
47 #endif
48
49 _path = path;
50
51 _pos.length = sizeof(WINDOWPLACEMENT);
52 _pos.flags = 0;
53 _pos.showCmd = SW_SHOWNORMAL;
54 _pos.rcNormalPosition.left = CW_USEDEFAULT;
55 _pos.rcNormalPosition.top = CW_USEDEFAULT;
56 _pos.rcNormalPosition.right = CW_USEDEFAULT;
57 _pos.rcNormalPosition.bottom = CW_USEDEFAULT;
58
59 _open_mode = OWM_EXPLORE|OWM_DETAILS;
60 }
61
62
ShellChildWndInfo(HWND hmdiclient,LPCTSTR path,const ShellPath & root_shell_path)63 ShellChildWndInfo::ShellChildWndInfo(HWND hmdiclient, LPCTSTR path, const ShellPath& root_shell_path)
64 : FileChildWndInfo(hmdiclient, path, ET_SHELL),
65 _shell_path(path&&*path? path: root_shell_path),
66 _root_shell_path(root_shell_path)
67 {
68 }
69
70
NtObjChildWndInfo(HWND hmdiclient,LPCTSTR path)71 NtObjChildWndInfo::NtObjChildWndInfo(HWND hmdiclient, LPCTSTR path)
72 : FileChildWndInfo(hmdiclient, path, ET_NTOBJS)
73 {
74 }
75
76
RegistryChildWndInfo(HWND hmdiclient,LPCTSTR path)77 RegistryChildWndInfo::RegistryChildWndInfo(HWND hmdiclient, LPCTSTR path)
78 : FileChildWndInfo(hmdiclient, path, ET_REGISTRY)
79 {
80 }
81
82
FATChildWndInfo(HWND hmdiclient,LPCTSTR path)83 FATChildWndInfo::FATChildWndInfo(HWND hmdiclient, LPCTSTR path)
84 : FileChildWndInfo(hmdiclient, path, ET_FAT)
85 {
86 }
87
88
WebChildWndInfo(HWND hmdiclient,LPCTSTR url)89 WebChildWndInfo::WebChildWndInfo(HWND hmdiclient, LPCTSTR url)
90 : FileChildWndInfo(hmdiclient, url, ET_WEB)
91 {
92 }
93
94
WndProc(HWND hwnd,UINT nmsg,WPARAM wparam,LPARAM lparam)95 INT_PTR CALLBACK ExecuteDialog::WndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
96 {
97 static struct ExecuteDialog* dlg;
98
99 switch(nmsg) {
100 case WM_INITDIALOG:
101 dlg = (struct ExecuteDialog*) lparam;
102 return 1;
103
104 case WM_COMMAND: {
105 int id = (int)wparam;
106
107 if (id == IDOK) {
108 GetWindowText(GetDlgItem(hwnd, 201), dlg->cmd, COUNTOF(dlg->cmd));
109 dlg->cmdshow = Button_GetState(GetDlgItem(hwnd,214))&BST_CHECKED?
110 SW_SHOWMINIMIZED: SW_SHOWNORMAL;
111 EndDialog(hwnd, id);
112 } else if (id == IDCANCEL)
113 EndDialog(hwnd, id);
114
115 return 1;}
116 }
117
118 return 0;
119 }
120
121
122 // FileChildWindow
123
FileChildWindow(HWND hwnd,const FileChildWndInfo & info)124 FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
125 : super(hwnd, info)
126 {
127 CONTEXT("FileChildWindow::FileChildWindow()");
128
129 TCHAR drv[_MAX_DRIVE+1];
130 Entry* entry = NULL;
131
132 _left = NULL;
133 _right = NULL;
134
135 switch(info._etype) {
136 #ifdef __WINE__
137 case ET_UNIX:
138 _root._drive_type = GetDriveType(info._path);
139 _root._sort_order = SORT_NAME;
140
141 _tsplitpath(info._path, drv, NULL, NULL, NULL);
142 lstrcat(drv, TEXT("/"));
143 lstrcpy(_root._volname, TEXT("root fs"));
144 _root._fs_flags = 0;
145 lstrcpy(_root._fs, TEXT("unixfs"));
146 lstrcpy(_root._path, TEXT("/"));
147 _root._entry = new UnixDirectory(_root._path);
148 entry = _root.read_tree(info._path+_tcslen(_root._path));
149 break;
150 #endif
151
152 case ET_NTOBJS:
153 _root._drive_type = DRIVE_UNKNOWN;
154 _root._sort_order = SORT_NAME;
155
156 _tsplitpath_s(info._path, drv, COUNTOF(drv), NULL, 0, NULL, 0, NULL, 0);
157 lstrcat(drv, TEXT("\\"));
158 lstrcpy(_root._volname, TEXT("NT Object Namespace"));
159 lstrcpy(_root._fs, TEXT("NTOBJ"));
160 lstrcpy(_root._path, drv);
161 _root._entry = new NtObjDirectory(_root._path);
162 entry = _root.read_tree(info._path+_tcslen(_root._path));
163 break;
164
165 case ET_REGISTRY:
166 _root._drive_type = DRIVE_UNKNOWN;
167 _root._sort_order = SORT_NONE;
168
169 _tsplitpath_s(info._path, drv, COUNTOF(drv), NULL, 0, NULL, 0, NULL, 0);
170 lstrcat(drv, TEXT("\\"));
171 lstrcpy(_root._volname, TEXT("Registry"));
172 lstrcpy(_root._fs, TEXT("Registry"));
173 lstrcpy(_root._path, drv);
174 _root._entry = new RegistryRoot();
175 entry = _root.read_tree(info._path+_tcslen(_root._path));
176 break;
177 #ifdef _DEBUG
178 case ET_FAT: {
179 _root._drive_type = DRIVE_UNKNOWN;
180 _root._sort_order = SORT_NONE;
181
182 _tsplitpath_s(info._path, drv, COUNTOF(drv), NULL, 0, NULL, 0, NULL, 0);
183 lstrcat(drv, TEXT("\\"));
184 lstrcpy(_root._volname, TEXT("FAT XXX")); //@@
185 lstrcpy(_root._fs, TEXT("FAT"));
186 lstrcpy(_root._path, drv);
187 FATDrive* drive = new FATDrive(TEXT("c:/reactos-emu/c.img")); //TEXT("\\\\.\\F:")); //@@
188
189 if (drive->_hDrive != INVALID_HANDLE_VALUE) {
190 _root._entry = drive;
191 entry = _root.read_tree(info._path+_tcslen(_root._path));
192 }
193 break;}
194 #endif
195 #ifndef _NO_WIN_FS
196 default: // ET_WINDOWS
197 _root._drive_type = GetDriveType(info._path);
198 _root._sort_order = SORT_NAME;
199
200 _tsplitpath_s(info._path, drv, COUNTOF(drv), NULL, 0, NULL, 0, NULL, 0);
201 lstrcat(drv, TEXT("\\"));
202 GetVolumeInformation(drv, _root._volname, _MAX_FNAME, 0, 0, &_root._fs_flags, _root._fs, COUNTOF(_root._fs));
203 lstrcpy(_root._path, drv);
204 _root._entry = new WinDirectory(_root._path);
205 entry = _root.read_tree(info._path+_tcslen(_root._path));
206 break;
207 #else
208 default:
209 #endif
210
211 case ET_SHELL: { //@@ separate FileChildWindow into ShellChildWindow, WinChildWindow, UnixChildWindow ?
212 _root._drive_type = DRIVE_UNKNOWN;
213 _root._sort_order = SORT_NAME;
214
215 lstrcpy(drv, TEXT("\\"));
216 lstrcpy(_root._volname, TEXT("Desktop"));
217 _root._fs_flags = 0;
218 lstrcpy(_root._fs, TEXT("Shell"));
219
220 _root._entry = new ShellDirectory(GetDesktopFolder(), DesktopFolderPath(), hwnd);
221 const ShellChildWndInfo& shell_info = static_cast<const ShellChildWndInfo&>(info);
222 entry = _root.read_tree(&*shell_info._shell_path);
223 break;}
224 }
225
226 if (_root._entry) {
227 if (info._etype != ET_SHELL)
228 wsprintf(_root._entry->_data.cFileName, TEXT("%s - %s"), drv, _root._fs);
229 /*@@else
230 lstrcpy(_root._entry->_data.cFileName, TEXT("GetDesktopFolder"));*/
231
232 _root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
233
234
235 ///@todo use OWM_ROOTED flag
236
237 if (info._open_mode & OWM_EXPLORE) ///@todo Is not-explore-mode for FileChildWindow completely implemented?
238 _left_hwnd = *(_left=new Pane(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT, _root._entry, true, COL_CONTENT));
239
240 _right_hwnd = *(_right=new Pane(_hwnd, IDW_TREE_RIGHT, IDW_HEADER_RIGHT, NULL, false,
241 COL_TYPE|COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS|COL_CONTENT));
242 }
243
244 _header_wdths_ok = false;
245
246 if (!_left_hwnd && !_right_hwnd)
247 return;
248
249 if (entry)
250 set_curdir(entry);
251 else if (_root._entry)
252 set_curdir(_root._entry);
253
254 if (_left_hwnd) {
255 int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), _left->_cur);
256 ListBox_SetCurSel(_left_hwnd, idx);
257 //SetFocus(_left_hwnd);
258 }
259
260 // store path into history
261 if (info._path && *info._path)
262 _url_history.push(info._path);
263 }
264
265
set_curdir(Entry * entry)266 void FileChildWindow::set_curdir(Entry* entry)
267 {
268 CONTEXT("FileChildWindow::set_curdir()");
269
270 _path[0] = TEXT('\0');
271
272 _left->_cur = entry;
273 _right->_root = entry&&entry->_down? entry->_down: entry;
274 _right->_cur = entry;
275
276 if (entry) {
277 WaitCursor wait;
278
279 if (!entry->_scanned)
280 scan_entry(entry);
281 else {
282 HiddenWindow hide(_right_hwnd);
283
284 ListBox_ResetContent(_right_hwnd);
285 _right->insert_entries(entry->_down);
286
287 _right->calc_widths(false); ///@todo make configurable (This call takes really _very_ long compared to all other processing!)
288
289 _right->set_header();
290 }
291
292 entry->get_path(_path, COUNTOF(_path));
293 }
294
295 if (_hwnd) // only change window title if the window already exists
296 SetWindowText(_hwnd, _path);
297
298 if (_path[0])
299 {
300 if (SetCurrentDirectory(_path))
301 set_url(_path); //set_url(FmtString(TEXT("file://%s"), _path));
302 else
303 _path[0] = TEXT('\0');
304 }
305 }
306
307
308 // expand a directory entry
309
expand_entry(Entry * dir)310 bool FileChildWindow::expand_entry(Entry* dir)
311 {
312 int idx;
313 Entry* p;
314
315 if (!dir || dir->_expanded || !dir->_down)
316 return false;
317
318 p = dir->_down;
319
320 if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='\0' && p->_next) {
321 p = p->_next;
322
323 if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='.' &&
324 p->_data.cFileName[2]=='\0' && p->_next)
325 p = p->_next;
326 }
327
328 // no subdirectories ?
329 if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // not a directory?
330 !p->_down) // not a file with NTFS sub-streams?
331 return FALSE;
332
333 idx = ListBox_FindItemData(_left_hwnd, 0, dir);
334
335 dir->_expanded = true;
336
337 // insert entries in left pane
338 HiddenWindow hide(_left_hwnd);
339
340 _left->insert_entries(p, idx);
341
342 if (!_header_wdths_ok) {
343 if (_left->calc_widths(false)) {
344 _left->set_header();
345
346 _header_wdths_ok = true;
347 }
348 }
349
350 return true;
351 }
352
353
collapse_entry(Pane * pane,Entry * dir)354 void FileChildWindow::collapse_entry(Pane* pane, Entry* dir)
355 {
356 int idx = ListBox_FindItemData(*pane, 0, dir);
357
358 SendMessage(*pane, WM_SETREDRAW, FALSE, 0); //ShowWindow(*pane, SW_HIDE);
359
360 // hide sub entries
361 for(;;) {
362 LRESULT res = ListBox_GetItemData(*pane, idx+1);
363 Entry* sub = (Entry*) res;
364
365 if (res==LB_ERR || !sub || sub->_level<=dir->_level)
366 break;
367
368 ListBox_DeleteString(*pane, idx+1);
369 }
370
371 dir->_expanded = false;
372
373 SendMessage(*pane, WM_SETREDRAW, TRUE, 0); //ShowWindow(*pane, SW_SHOW);
374 }
375
376
create(const FileChildWndInfo & info)377 FileChildWindow* FileChildWindow::create(const FileChildWndInfo& info)
378 {
379 CONTEXT("FileChildWindow::create()");
380
381 MDICREATESTRUCT mcs;
382
383 mcs.szClass = CLASSNAME_WINEFILETREE;
384 mcs.szTitle = (LPTSTR)info._path;
385 mcs.hOwner = g_Globals._hInstance;
386 mcs.x = info._pos.rcNormalPosition.left;
387 mcs.y = info._pos.rcNormalPosition.top;
388 mcs.cx = info._pos.rcNormalPosition.right - info._pos.rcNormalPosition.left;
389 mcs.cy = info._pos.rcNormalPosition.bottom - info._pos.rcNormalPosition.top;
390 mcs.style = 0;
391 mcs.lParam = 0;
392
393 FileChildWindow* child = static_cast<FileChildWindow*>(
394 create_mdi_child(info, mcs, WINDOW_CREATOR_INFO(FileChildWindow,FileChildWndInfo)));
395
396 if (!child->_left_hwnd && !child->_right_hwnd) {
397 SendMessage(info._hmdiclient, WM_MDIDESTROY, (WPARAM)child->_hwnd, 0);
398 MessageBox(info._hmdiclient, TEXT("Error opening child window"), TEXT("ROS Explorer"), MB_OK);
399 }
400
401 return child;
402 }
403
404
resize_children(int cx,int cy)405 void FileChildWindow::resize_children(int cx, int cy)
406 {
407 HDWP hdwp = BeginDeferWindowPos(4);
408 RECT rt;
409
410 rt.left = 0;
411 rt.top = 0;
412 rt.right = cx;
413 rt.bottom = cy;
414
415 cx = _split_pos + SPLIT_WIDTH/2;
416
417 if (_left && _right) {
418 WINDOWPOS wp;
419 HD_LAYOUT hdl;
420
421 hdl.prc = &rt;
422 hdl.pwpos = ℘
423
424 Header_Layout(_left->_hwndHeader, &hdl);
425
426 hdwp = DeferWindowPos(hdwp, _left->_hwndHeader, wp.hwndInsertAfter,
427 wp.x-1, wp.y, _split_pos-SPLIT_WIDTH/2+1, wp.cy, wp.flags);
428
429 hdwp = DeferWindowPos(hdwp, _right->_hwndHeader, wp.hwndInsertAfter,
430 rt.left+cx+1, wp.y, wp.cx-cx+2, wp.cy, wp.flags);
431 }
432
433 if (_left_hwnd)
434 hdwp = DeferWindowPos(hdwp, _left_hwnd, 0, rt.left, rt.top, _split_pos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
435
436 if (_right_hwnd)
437 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
438
439 EndDeferWindowPos(hdwp);
440 }
441
442
WndProc(UINT nmsg,WPARAM wparam,LPARAM lparam)443 LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
444 {
445 switch(nmsg) {
446 case WM_DRAWITEM: {
447 LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lparam;
448 Entry* entry = (Entry*) dis->itemData;
449
450 if (dis->CtlID == IDW_TREE_LEFT) {
451 _left->draw_item(dis, entry);
452 return TRUE;
453 } else if (dis->CtlID == IDW_TREE_RIGHT) {
454 _right->draw_item(dis, entry);
455 return TRUE;
456 }
457
458 goto def;}
459
460 case WM_SIZE:
461 if (wparam != SIZE_MINIMIZED)
462 resize_children(LOWORD(lparam), HIWORD(lparam));
463 return DefMDIChildProc(_hwnd, nmsg, wparam, lparam);
464
465 case PM_GET_FILEWND_PTR:
466 return (LRESULT)this;
467
468 case WM_SETFOCUS: {
469 TCHAR path[MAX_PATH];
470
471 if (_left && _left->_cur) {
472 _left->_cur->get_path(path, COUNTOF(path));
473 SetCurrentDirectory(path);
474 }
475
476 SetFocus(_focus_pane? _right_hwnd: _left_hwnd);
477 goto def;}
478
479 case PM_DISPATCH_COMMAND: {
480 Pane* pane = GetFocus()==_left_hwnd? _left: _right;
481
482 switch(LOWORD(wparam)) {
483 case ID_WINDOW_NEW: {CONTEXT("FileChildWindow PM_DISPATCH_COMMAND ID_WINDOW_NEW");
484 if (_root._entry->_etype == ET_SHELL)
485 FileChildWindow::create(ShellChildWndInfo(GetParent(_hwnd)/*_hmdiclient*/, _path, DesktopFolderPath()));
486 else
487 FileChildWindow::create(FileChildWndInfo(GetParent(_hwnd)/*_hmdiclient*/, _path));
488 break;}
489
490 case ID_REFRESH: {CONTEXT("ID_REFRESH");
491 refresh();
492 break;}
493
494 case ID_ACTIVATE: {CONTEXT("ID_ACTIVATE");
495 activate_entry(pane);
496 break;}
497
498 default:
499 if (pane->command(LOWORD(wparam)))
500 return TRUE;
501 else
502 return super::WndProc(nmsg, wparam, lparam);
503 }
504
505 return TRUE;}
506
507 case WM_CONTEXTMENU: {
508 // first select the current item in the listbox
509 HWND hpanel = (HWND) wparam;
510 POINT pt;
511 pt.x = LOWORD(lparam);
512 pt.y = HIWORD(lparam);
513 POINT pt_screen = pt;
514 ScreenToClient(hpanel, &pt);
515 SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y));
516 SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt.x, pt.y));
517
518 // now create the popup menu using shell namespace and IContextMenu
519 Pane* pane = GetFocus()==_left_hwnd? _left: _right;
520 int idx = ListBox_GetCurSel(*pane);
521 if (idx != -1) {
522 Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
523
524 HRESULT hr = entry->do_context_menu(_hwnd, pt_screen, _cm_ifs);
525
526 if (SUCCEEDED(hr))
527 refresh();
528 else
529 CHECKERROR(hr);
530 }
531 break;}
532
533 default: def:
534 return super::WndProc(nmsg, wparam, lparam);
535 }
536
537 return 0;
538 }
539
540
refresh()541 void FileChildWindow::refresh()
542 {
543 WaitCursor wait;
544 bool expanded = _left->_cur->_expanded;
545
546 scan_entry(_left->_cur);
547
548 if (expanded)
549 expand_entry(_left->_cur);
550 }
551
552
Command(int id,int code)553 int FileChildWindow::Command(int id, int code)
554 {
555 Pane* pane = GetFocus()==_left_hwnd? _left: _right;
556
557 switch(code) {
558 case LBN_SELCHANGE: {
559 int idx = ListBox_GetCurSel(*pane);
560 Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
561
562 if (pane == _left)
563 set_curdir(entry);
564 else
565 pane->_cur = entry;
566 break;}
567
568 case LBN_DBLCLK:
569 activate_entry(pane);
570 break;
571 }
572
573 return 0;
574 }
575
576
activate_entry(Pane * pane)577 void FileChildWindow::activate_entry(Pane* pane) ///@todo enable using RETURN key accelerator
578 {
579 Entry* entry = pane->_cur;
580
581 if (!entry)
582 return;
583
584 WaitCursor wait;
585
586 if ((entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || // a directory?
587 entry->_down) // a file with NTFS sub-streams?
588 {
589 int scanned_old = entry->_scanned;
590
591 if (!scanned_old)
592 scan_entry(entry);
593
594 if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('\0'))
595 return;
596
597 if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0')) {
598 entry = _left->_cur->_up;
599 collapse_entry(_left, entry);
600 goto focus_entry;
601 } else if (entry->_expanded)
602 collapse_entry(pane, _left->_cur);
603 else {
604 expand_entry(_left->_cur);
605
606 if (!pane->_treePane) focus_entry: {
607 int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), entry);
608 ListBox_SetCurSel(_left_hwnd, idx);
609
610 set_curdir(entry);
611 }
612 }
613
614 if (!scanned_old) {
615 pane->calc_widths(false);
616
617 pane->set_header();
618 }
619 } else {
620 entry->launch_entry(_hwnd);
621 }
622 }
623
624
scan_entry(Entry * entry)625 void FileChildWindow::scan_entry(Entry* entry)
626 {
627 CONTEXT("FileChildWindow::scan_entry()");
628
629 int idx = ListBox_GetCurSel(_left_hwnd);
630
631 // delete sub entries in left pane
632 for(;;) {
633 LRESULT res = ListBox_GetItemData(_left_hwnd, idx+1);
634 Entry* sub = (Entry*) res;
635
636 if (res==LB_ERR || !sub || sub->_level<=entry->_level)
637 break;
638
639 ListBox_DeleteString(_left_hwnd, idx+1);
640 }
641
642 // empty right pane
643 ListBox_ResetContent(_right_hwnd);
644
645 // release memory
646 entry->free_subentries();
647 entry->_expanded = false;
648
649 // read contents from disk
650 entry->read_directory_base(_root._sort_order); ///@todo use modifyable sort order instead of fixed file system default
651
652 // insert found entries in right pane
653 HiddenWindow hide(_right_hwnd);
654 _right->insert_entries(entry->_down);
655
656 _right->calc_widths(false);
657 _right->set_header();
658
659 _header_wdths_ok = false;
660 }
661
662
Notify(int id,NMHDR * pnmh)663 int FileChildWindow::Notify(int id, NMHDR* pnmh)
664 {
665 return (pnmh->idFrom==IDW_HEADER_LEFT? _left: _right)->Notify(id, pnmh);
666 }
667
668
jump_to_int(LPCTSTR url)669 String FileChildWindow::jump_to_int(LPCTSTR url)
670 {
671 String dir, fname;
672
673 if (SplitFileSysURL(url, dir, fname)) {
674 Entry* entry = NULL;
675
676 // call read_tree() to iterate through the hierarchy and open all folders to reach dir
677 if (_root._entry)
678 switch(_root._entry->_etype) {
679 case ET_SHELL: { //@@ separate into FileChildWindow in ShellChildWindow, WinChildWindow, UnixChildWindow ?
680 ShellPath shell_path(dir);
681 entry = _root.read_tree(&*shell_path);
682 break;}
683
684 #ifdef __WINE__
685 case ET_UNIX: {
686 LPCTSTR path = dir;
687
688 if (!_tcsicmp(path, _root._path, _tcslen(_root._path)))
689 path += _tcslen(_root._path);
690
691 entry = _root.read_tree(path);
692 break;}
693 #endif
694
695 default: { // ET_NTOBJS, ET_REGISTRY, ET_FAT, ET_WINDOWS
696 LPCTSTR path = dir;
697
698 if (!_tcsnicmp(path, _root._path, _tcslen(_root._path)))
699 path += _tcslen(_root._path);
700
701 entry = _root.read_tree(path);
702 break;}
703 }
704
705 if (entry) {
706 // refresh left pane entries
707 HiddenWindow hide(_left_hwnd);
708
709 ListBox_ResetContent(_left_hwnd);
710
711 _left->insert_entries(_root._entry);
712
713 if (!_header_wdths_ok) {
714 if (_left->calc_widths(false)) {
715 _left->set_header();
716
717 _header_wdths_ok = true;
718 }
719 }
720
721 set_curdir(entry);
722
723 if (_left_hwnd) {
724 int idx = ListBox_FindItemData(_left_hwnd, -1, entry);
725
726 if (idx != -1) { // The item should always be found.
727 ListBox_SetCurSel(_left_hwnd, idx);
728 SetFocus(_left_hwnd);
729 }
730 }
731
732 ///@todo use fname
733
734 return dir; //FmtString(TEXT("file://%s"), (LPCTSTR)dir);
735 }
736 }
737
738 return String();
739 }
740