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