8e138e09dadc0846c11128e1a3bc63eb8ee90e41
[reactos.git] / reactos / subsys / system / explorer / shell / shellbrowser.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 // shellbrowser.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27
28
29 #include <precomp.h>
30
31 #include "../resource.h"
32
33
34 // work around GCC's wide string constant bug
35 #ifdef __GNUC__
36 const LPCTSTR C_DRIVE = C_DRIVE_STR;
37 #endif
38
39
40 ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
41 BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
42 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
43 : super(IID_IShellFolderViewCB),
44 #else
45 :
46 #endif
47 _hwnd(hwnd),
48 _left_hwnd(left_hwnd),
49 _right_hwnd(right_hwnd),
50 _create_info(create_info),
51 _callback(cb),
52 _cm_ifs(cm_ifs)
53 {
54 _pShellView = NULL;
55 _pDropTarget = NULL;
56 _last_sel = 0;
57
58 _cur_dir = NULL;
59
60 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
61 ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
62 }
63
64 ShellBrowser::~ShellBrowser()
65 {
66 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
67 ImageList_Destroy(_himl);
68
69 if (_pShellView)
70 _pShellView->Release();
71
72 if (_pDropTarget) {
73 _pDropTarget->Release();
74 _pDropTarget = NULL;
75 }
76
77 if (_right_hwnd) {
78 DestroyWindow(_right_hwnd);
79 _right_hwnd = 0;
80 }
81 }
82
83
84 LRESULT ShellBrowser::Init(HWND hWndFrame)
85 {
86 CONTEXT("ShellBrowser::Init()");
87
88 _hWndFrame = hWndFrame;
89
90 const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR);
91
92 _root._drive_type = DRIVE_UNKNOWN;
93 lstrcpy(_root._volname, root_name);
94 _root._fs_flags = 0;
95 lstrcpy(_root._fs, TEXT("Desktop"));
96
97 _root._entry = new ShellDirectory(GetDesktopFolder(), _create_info._root_shell_path, _hwnd);
98
99 jump_to(_create_info._shell_path);
100
101 // -> set_curdir()
102 _root._entry->read_directory();
103
104 /* already filled by ShellDirectory constructor
105 lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); */
106
107 return 0;
108 }
109
110 void ShellBrowser::jump_to(LPCITEMIDLIST pidl)
111 {
112 Entry* entry = NULL;
113
114 //@@
115 if (!_cur_dir)
116 _cur_dir = static_cast<ShellDirectory*>(_root._entry);
117
118 //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl)));
119
120 // We could call read_tree() here to iterate through the hierarchy and open all folders
121 // from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl).
122 // To make it easier we just use ILFindChild() instead.
123 if (_cur_dir) {
124 static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24);
125
126 if (ILFindChild) {
127 for(;;) {
128 LPCITEMIDLIST child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl);
129 if (!child_pidl || !child_pidl->mkid.cb)
130 break;
131
132 _cur_dir->smart_scan();
133
134 entry = _cur_dir->find_entry(child_pidl);
135 if (!entry)
136 break;
137
138 _cur_dir = static_cast<ShellDirectory*>(entry);
139 _callback->entry_selected(entry);
140 }
141 } else {
142 _cur_dir->smart_scan();
143
144 entry = _cur_dir->find_entry(pidl); // This is not correct in the common case, but works on the desktop level.
145
146 if (entry) {
147 _cur_dir = static_cast<ShellDirectory*>(entry);
148 _callback->entry_selected(entry);
149 }
150 }
151 }
152
153 // If not already called, now directly call UpdateFolderView() using pidl
154 if (!entry)
155 UpdateFolderView(ShellFolder(pidl));
156 }
157
158
159 void ShellBrowser::InitializeTree()
160 {
161 CONTEXT("ShellBrowserChild::InitializeTree()");
162
163 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
164 TreeView_SetScrollTime(_left_hwnd, 100);
165
166 TV_INSERTSTRUCT tvInsert;
167 TV_ITEM& tvItem = tvInsert.item;
168
169 tvInsert.hParent = 0;
170 tvInsert.hInsertAfter = TVI_LAST;
171
172 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
173 tvItem.lParam = (LPARAM)_root._entry;
174 tvItem.pszText = _root._volname; //LPSTR_TEXTCALLBACK;
175 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
176 tvItem.cChildren = 1;
177
178 HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert);
179 TreeView_SelectItem(_left_hwnd, hItem);
180 TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND);
181 }
182
183 bool ShellBrowser::InitDragDrop()
184 {
185 CONTEXT("ShellBrowser::InitDragDrop()");
186
187 _pDropTarget = new TreeDropTarget(_left_hwnd);
188
189 if (!_pDropTarget)
190 return false;
191
192 _pDropTarget->AddRef();
193
194 if (FAILED(RegisterDragDrop(_left_hwnd, _pDropTarget))) {//calls addref
195 _pDropTarget->Release(); // free TreeDropTarget
196 _pDropTarget = NULL;
197 return false;
198 } else
199 _pDropTarget->Release();
200
201 FORMATETC ftetc;
202
203 ftetc.dwAspect = DVASPECT_CONTENT;
204 ftetc.lindex = -1;
205 ftetc.tymed = TYMED_HGLOBAL;
206 ftetc.cfFormat = CF_HDROP;
207
208 _pDropTarget->AddSuportedFormat(ftetc);
209
210 return true;
211 }
212
213
214 void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
215 {
216 CONTEXT("ShellBrowser::OnTreeItemRClick()");
217
218 TVHITTESTINFO tvhti;
219
220 GetCursorPos(&tvhti.pt);
221 ScreenToClient(_left_hwnd, &tvhti.pt);
222
223 tvhti.flags = LVHT_NOWHERE;
224 (void)TreeView_HitTest(_left_hwnd, &tvhti);
225
226 if (TVHT_ONITEM & tvhti.flags) {
227 LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem);
228
229 if (itemData) {
230 Entry* entry = (Entry*)itemData;
231 ClientToScreen(_left_hwnd, &tvhti.pt);
232
233 CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs));
234 }
235 }
236 }
237
238 void ShellBrowser::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh)
239 {
240 CONTEXT("ShellBrowser::OnTreeGetDispInfo()");
241
242 LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh;
243 ShellEntry* entry = (ShellEntry*)lpdi->item.lParam;
244
245 if (entry) {
246 if (lpdi->item.mask & TVIF_TEXT)
247 lpdi->item.pszText = entry->_display_name;
248
249 if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
250 if (lpdi->item.mask & TVIF_IMAGE)
251 lpdi->item.iImage = get_image_idx(
252 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS)));
253
254 if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
255 lpdi->item.iSelectedImage = get_image_idx(
256 entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN)));
257 }
258 }
259 }
260
261 int ShellBrowser::get_image_idx(int icon_id)
262 {
263 if (icon_id != ICID_NONE) {
264 map<int,int>::const_iterator found = _image_map.find(icon_id);
265
266 if (found != _image_map.end())
267 return found->second;
268
269 int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon());
270
271 _image_map[icon_id] = idx;
272
273 return idx;
274 } else
275 return -1;
276 }
277
278 void ShellBrowser::invalidate_cache()
279 {
280 (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
281 ImageList_Destroy(_himl);
282
283 _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
284 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
285
286 for(map<int,int>::const_iterator it=_image_map.begin(); it!=_image_map.end(); ++it)
287 g_Globals._icon_cache.free_icon(it->first);
288
289 _image_map.clear();
290 }
291
292 void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
293 {
294 CONTEXT("ShellBrowser::OnTreeItemExpanding()");
295
296 if (pnmtv->action == TVE_COLLAPSE)
297 TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET);
298 else if (pnmtv->action == TVE_EXPAND) {
299 ShellDirectory* entry = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem);
300
301 if (entry)
302 if (!InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder)) {
303 entry->_shell_attribs &= ~SFGAO_HASSUBFOLDER;
304
305 // remove subitem "+"
306 TV_ITEM tvItem;
307
308 tvItem.mask = TVIF_CHILDREN;
309 tvItem.hItem = pnmtv->itemNew.hItem;
310 tvItem.cChildren = 0;
311
312 TreeView_SetItem(_left_hwnd, &tvItem);
313 }
314 }
315 }
316
317 int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder)
318 {
319 CONTEXT("ShellBrowser::InsertSubitems()");
320
321 WaitCursor wait;
322
323 int cnt = 0;
324
325 SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0);
326
327 try {
328 entry->smart_scan();
329 } catch(COMException& e) {
330 HandleException(e, g_Globals._hMainWnd);
331 }
332
333 // remove old children items
334 for(HTREEITEM hchild,hnext=TreeView_GetChild(_left_hwnd, hParentItem); hchild=hnext; ) {
335 hnext = TreeView_GetNextSibling(_left_hwnd, hchild);
336 TreeView_DeleteItem(_left_hwnd, hchild);
337 }
338
339 TV_ITEM tvItem;
340 TV_INSERTSTRUCT tvInsert;
341
342 for(entry=entry->_down; entry; entry=entry->_next) {
343 #ifndef _LEFT_FILES
344 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
345 #endif
346 {
347 ZeroMemory(&tvItem, sizeof(tvItem));
348
349 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
350 tvItem.pszText = LPSTR_TEXTCALLBACK;
351 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
352 tvItem.lParam = (LPARAM)entry;
353 tvItem.cChildren = entry->_shell_attribs & SFGAO_HASSUBFOLDER? 1: 0;
354
355 if (entry->_shell_attribs & SFGAO_SHARE) {
356 tvItem.mask |= TVIF_STATE;
357 tvItem.stateMask |= TVIS_OVERLAYMASK;
358 tvItem.state |= INDEXTOOVERLAYMASK(1);
359 }
360
361 tvInsert.item = tvItem;
362 tvInsert.hInsertAfter = TVI_LAST;
363 tvInsert.hParent = hParentItem;
364
365 (void)TreeView_InsertItem(_left_hwnd, &tvInsert);
366 }
367
368 ++cnt;
369 }
370
371 SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0);
372
373 return cnt;
374 }
375
376 void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
377 {
378 CONTEXT("ShellBrowser::OnTreeItemSelected()");
379
380 ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam;
381
382 _last_sel = pnmtv->itemNew.hItem;
383
384 if (entry)
385 _callback->entry_selected(entry);
386 }
387
388 void ShellBrowser::UpdateFolderView(IShellFolder* folder)
389 {
390 CONTEXT("ShellBrowser::UpdateFolderView()");
391
392 FOLDERSETTINGS fs;
393 IShellView* pLastShellView = _pShellView;
394
395 _folder = folder;
396
397 if (pLastShellView)
398 pLastShellView->GetCurrentInfo(&fs);
399 else {
400 fs.ViewMode = _create_info._open_mode&OWM_DETAILS? FVM_DETAILS: FVM_ICON;
401 fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW;
402 }
403
404 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
405 SFV_CREATE sfv_create;
406
407 sfv_create.cbSize = sizeof(SFV_CREATE);
408 sfv_create.pshf = folder;
409 sfv_create.psvOuter = NULL;
410 sfv_create.psfvcb = this;
411
412 HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView);
413 #else
414 HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView);
415 #endif
416
417 if (FAILED(hr)) {
418 _pShellView = NULL;
419 return;
420 }
421
422 RECT rect = {CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT};
423 hr = _pShellView->CreateViewWindow(pLastShellView, &fs, static_cast<IShellBrowser*>(this), &rect, &_right_hwnd/*&m_hWndListView*/);
424
425 if (pLastShellView) {
426 pLastShellView->GetCurrentInfo(&fs);
427 pLastShellView->UIActivate(SVUIA_DEACTIVATE);
428 pLastShellView->DestroyViewWindow();
429 pLastShellView->Release();
430 }
431
432 _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS);
433 }
434
435
436 #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
437
438 /// shell view callback
439 HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
440 {
441 if (uMsg == SFVM_INITMENUPOPUP) {
442 //@todo never reached
443 InsertMenu((HMENU)lParam, 0, MF_BYPOSITION, 12345, TEXT("TEST ENTRY"));
444 return S_OK;
445 }
446
447 return E_NOTIMPL;
448 }
449
450 #endif
451
452
453 HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida)
454 {
455 CONTEXT("ShellBrowser::OnDefaultCommand()");
456
457 if (pida->cidl >= 1) {
458 if (_left_hwnd) { // explorer mode
459 if (_last_sel) {
460 ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel);
461
462 if (parent) {
463 try {
464 parent->smart_scan();
465 } catch(COMException& e) {
466 return e.Error();
467 }
468
469 UINT firstOffset = pida->aoffset[1];
470 LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset);
471
472 Entry* entry = parent->find_entry(pidl);
473
474 if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
475 if (entry->_etype == ET_SHELL)
476 if (_last_sel && select_entry(_last_sel, entry))
477 return S_OK;
478 }
479 }
480 } else { // no tree control
481 if (MainFrameBase::OpenShellFolders(pida, _hWndFrame))
482 return S_OK;
483
484 /* create new Frame Window
485 if (MainFrame::OpenShellFolders(pida, 0))
486 return S_OK;
487 */
488 }
489 }
490
491 return E_NOTIMPL;
492 }
493
494
495 HTREEITEM ShellBrowser::select_entry(HTREEITEM hitem, Entry* entry, bool expand)
496 {
497 CONTEXT("ShellBrowser::select_entry()");
498
499 if (expand && !TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
500 return 0;
501
502 for(hitem=TreeView_GetChild(_left_hwnd,hitem); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) {
503 if ((Entry*)TreeView_GetItemData(_left_hwnd,hitem) == entry) {
504 if (TreeView_SelectItem(_left_hwnd, hitem)) {
505 if (expand)
506 TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND);
507
508 return hitem;
509 }
510
511 break;
512 }
513 }
514
515 return 0;
516 }
517
518
519 bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl)
520 {
521 if (!_root._entry)
522 return false;
523
524 // iterate through the hierarchy and open all folders to reach pidl
525 WaitCursor wait;
526
527 HTREEITEM hitem = TreeView_GetRoot(_left_hwnd);
528 Entry* entry = _root._entry;
529
530 for(const void*p=pidl;;) {
531 if (!p)
532 return true;
533
534 if (!entry || !hitem)
535 break;
536
537 entry->smart_scan(SORT_NAME);
538
539 Entry* found = entry->find_entry(p);
540 p = entry->get_next_path_component(p);
541
542 if (found)
543 hitem = select_entry(hitem, found);
544
545 entry = found;
546 }
547
548 return false;
549 }
550
551
552 #ifndef _NO_MDI
553
554 MDIShellBrowserChild::MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info)
555 : super(hwnd, info),
556 _create_info(info),
557 _shellpath_info(info) //@@ copies info -> no referenz to _create_info !
558 {
559 /**todo Conversion of shell path into path string -> store into URL history
560 const String& path = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORADDRESSBAR);
561 const String& parsingpath = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORPARSING);
562
563 // store path into history
564 if (info._path && *info._path)
565 _url_history.push(info._path);
566 */
567 }
568
569
570 MDIShellBrowserChild* MDIShellBrowserChild::create(const ShellChildWndInfo& info)
571 {
572 ChildWindow* child = ChildWindow::create(info, info._pos.rcNormalPosition,
573 WINDOW_CREATOR_INFO(MDIShellBrowserChild,ShellChildWndInfo), CLASSNAME_CHILDWND, NULL, info._pos.showCmd==SW_SHOWMAXIMIZED? WS_MAXIMIZE: 0);
574
575 return static_cast<MDIShellBrowserChild*>(child);
576 }
577
578
579 LRESULT MDIShellBrowserChild::Init(LPCREATESTRUCT pcs)
580 {
581 CONTEXT("MDIShellBrowserChild::Init()");
582
583 if (super::Init(pcs))
584 return 1;
585
586 update_shell_browser();
587
588 if (_shellBrowser.get())
589 if (_left_hwnd)
590 _shellBrowser->Init();
591 else
592 _shellBrowser->UpdateFolderView(_create_info._shell_path.get_folder());
593
594 return 0;
595 }
596
597
598 LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
599 {
600 switch(nmsg) {
601 case PM_DISPATCH_COMMAND: {
602 switch(LOWORD(wparam)) {
603 case ID_WINDOW_NEW: {CONTEXT("MDIShellBrowserChild PM_DISPATCH_COMMAND ID_WINDOW_NEW");
604 MDIShellBrowserChild::create(_create_info);
605 break;}
606
607 case ID_REFRESH:
608 //@todo refresh shell child
609 _shellBrowser->invalidate_cache();
610 break;
611
612 case ID_VIEW_SDI:
613 MainFrameBase::Create(ExplorerCmd(_url, false));
614 break;
615
616 default:
617 return super::WndProc(nmsg, wparam, lparam);
618 }
619 return TRUE;}
620
621 default:
622 return super::WndProc(nmsg, wparam, lparam);
623 }
624
625 return 0;
626 }
627
628 void MDIShellBrowserChild::update_shell_browser()
629 {
630 int split_pos = DEFAULT_SPLIT_POS;
631
632 if (_shellBrowser.get()) {
633 split_pos = _split_pos;
634 delete _shellBrowser.release();
635 }
636
637 // create explorer treeview
638 if (_create_info._open_mode & OWM_EXPLORE) {
639 if (!_left_hwnd) {
640 ClientRect rect(_hwnd);
641
642 _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL,
643 WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,//|TVS_NOTOOLTIPS
644 0, rect.top, split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top,
645 _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0);
646 }
647 } else {
648 if (_left_hwnd) {
649 DestroyWindow(_left_hwnd);
650 _left_hwnd = 0;
651 }
652 }
653
654 _shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
655 _shellpath_info, this, _cm_ifs));
656
657 _shellBrowser->Init(_hwndFrame);
658 }
659
660
661 String MDIShellBrowserChild::jump_to_int(LPCTSTR url)
662 {
663 String dir, fname;
664
665 if (!_tcsnicmp(url, TEXT("shell://"), 8)) {
666 if (_shellBrowser->jump_to_pidl(ShellPath(url+8)))
667 return url;
668 }
669
670 if (SplitFileSysURL(url, dir, fname)) {
671
672 ///@todo use fname
673
674 if (_shellBrowser->jump_to_pidl(ShellPath(dir)))
675 return FmtString(TEXT("file://%s"), (LPCTSTR)dir);
676 }
677
678 return String();
679 }
680
681
682 void MDIShellBrowserChild::entry_selected(Entry* entry)
683 {
684 if (entry->_etype == ET_SHELL) {
685 ShellEntry* shell_entry = static_cast<ShellEntry*>(entry);
686 IShellFolder* folder;
687
688 if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
689 folder = static_cast<ShellDirectory*>(shell_entry)->_folder;
690 else
691 folder = shell_entry->get_parent_folder();
692
693 if (!folder) {
694 assert(folder);
695 return;
696 }
697
698 TCHAR path[MAX_PATH];
699
700 if (shell_entry->get_path(path, COUNTOF(path))) {
701 String url;
702
703 if (path[0] == ':')
704 url.printf(TEXT("shell://%s"), path);
705 else
706 url.printf(TEXT("file://%s"), path);
707
708 set_url(url);
709 }
710
711 _shellBrowser->UpdateFolderView(folder);
712
713 // set size of new created shell view windows
714 ClientRect rt(_hwnd);
715 resize_children(rt.right, rt.bottom);
716 }
717 }
718
719 #endif