X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=subsys%2Fsystem%2Fexplorer%2Fshell%2Ffilechild.cpp;fp=subsys%2Fsystem%2Fexplorer%2Fshell%2Ffilechild.cpp;h=189e6bdea4a4c5194bb7e8953e2ac57be279fddf;hp=0000000000000000000000000000000000000000;hb=ee8b63255465d8c28be3e7bd11628015708fc1ab;hpb=c99688ef1ab339c8746ecc385bde679623084c71 diff --git a/subsys/system/explorer/shell/filechild.cpp b/subsys/system/explorer/shell/filechild.cpp new file mode 100644 index 0000000..189e6bd --- /dev/null +++ b/subsys/system/explorer/shell/filechild.cpp @@ -0,0 +1,508 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // filechild.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" + +#include "../explorer.h" +#include "../globals.h" + +#include "../explorer_intres.h" + + +FileChildWndInfo::FileChildWndInfo(LPCTSTR path) +{ +#ifdef __linux__ + if (*path == '/') + _etype = ET_UNIX; + else +#endif + _etype = ET_WINDOWS; + + _path = path; + + _pos.length = sizeof(WINDOWPLACEMENT); + _pos.flags = 0; + _pos.showCmd = SW_SHOWNORMAL; + _pos.rcNormalPosition.left = CW_USEDEFAULT; + _pos.rcNormalPosition.top = CW_USEDEFAULT; + _pos.rcNormalPosition.right = CW_USEDEFAULT; + _pos.rcNormalPosition.bottom = CW_USEDEFAULT; + + _mode_explore = true; +} + + +ShellChildWndInfo::ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_path) + : FileChildWndInfo(path), + _shell_path(path), + _root_shell_path(root_shell_path) +{ + _etype = ET_SHELL; + _path = path; +} + + +FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) + : ChildWindow(hwnd) +{ + TCHAR drv[_MAX_DRIVE+1]; + Entry* entry; + + if (info._etype == ET_SHELL) //@@ evtl. Aufteilung von FileChildWindow in ShellChildWindow, WinChildWindow, UnixChildWindow + { + _root._drive_type = DRIVE_UNKNOWN; + lstrcpy(drv, TEXT("\\")); + lstrcpy(_root._volname, TEXT("Desktop")); + _root._fs_flags = 0; + lstrcpy(_root._fs, TEXT("Shell")); + + const ShellChildWndInfo& shell_info = static_cast(info); + _root._entry = new ShellDirectory(Desktop(), DesktopFolder(), hwnd); + entry = _root._entry->read_tree((LPCTSTR)&*shell_info._shell_path, SORT_NAME/*_sortOrder*/); + } + else +#ifdef __linux__ + if (info._etype == ET_UNIX) + { + _root._drive_type = GetDriveType(info._path); + + _tsplitpath(info._path, drv, NULL, NULL, NULL); + lstrcat(drv, TEXT("/")); + lstrcpy(_root._volname, TEXT("root fs")); + _root._fs_flags = 0; + lstrcpy(_root._fs, TEXT("unixfs")); + lstrcpy(_root._path, TEXT("/")); + _root._entry = new UnixDirectory(_root._path); + entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/); + } + else +#endif + {// if (info._etype == ET_WINDOWS) + _root._drive_type = GetDriveType(info._path); + + _tsplitpath(info._path, drv, NULL, NULL, NULL); + lstrcat(drv, TEXT("\\")); + GetVolumeInformation(drv, _root._volname, _MAX_FNAME, 0, 0, &_root._fs_flags, _root._fs, _MAX_DIR); + lstrcpy(_root._path, drv); + _root._entry = new WinDirectory(_root._path); + entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/); + } + + if (info._etype != ET_SHELL) + wsprintf(_root._entry->_data.cFileName, TEXT("%s - %s"), drv, _root._fs); +/*@@else + lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop"));*/ + + _root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + + + if (info._mode_explore) //TODO: Is not-explore-mode for FileChildWindow completely implemented? + _left_hwnd = *(_left=new Pane(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT, _root._entry, true, 0)); + + _right_hwnd = *(_right=new Pane(_hwnd, IDW_TREE_RIGHT, IDW_HEADER_RIGHT, NULL, false, COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS)); + + _sortOrder = SORT_NAME; + _header_wdths_ok = false; + + set_curdir(entry, hwnd); + + if (_left_hwnd) { + int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), _left->_cur); + ListBox_SetCurSel(_left_hwnd, idx); + } + + //TODO: scroll to visibility + +} + +FileChildWindow::~FileChildWindow() +{ +} + + +void FileChildWindow::set_curdir(Entry* entry, HWND hwnd) +{ + _path[0] = TEXT('\0'); + + _left->_cur = entry; + _right->_root = entry&&entry->_down? entry->_down: entry; + _right->_cur = entry; + + if (entry) { + if (!entry->_scanned) + scan_entry(entry, hwnd); + else { + ListBox_ResetContent(_right_hwnd); + _right->insert_entries(entry->_down, -1); + _right->calc_widths(false); + _right->set_header(); + } + + entry->get_path(_path); + } + + if (hwnd) // only change window title, if the window already exists + SetWindowText(hwnd, _path); + + if (_path[0]) + if (!SetCurrentDirectory(_path)) + _path[0] = TEXT('\0'); +} + + + // expand a directory entry + +bool FileChildWindow::expand_entry(Entry* dir) +{ + int idx; + Entry* p; + + if (!dir || dir->_expanded || !dir->_down) + return false; + + p = dir->_down; + + if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='\0' && p->_next) { + p = p->_next; + + if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='.' && + p->_data.cFileName[2]=='\0' && p->_next) + p = p->_next; + } + + // no subdirectories ? + if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return FALSE; + + idx = ListBox_FindItemData(_left_hwnd, 0, dir); + + dir->_expanded = true; + + // insert entries in left pane + _left->insert_entries(p, idx); + + if (!_header_wdths_ok) { + if (_left->calc_widths(false)) { + _left->set_header(); + + _header_wdths_ok = true; + } + } + + return true; +} + + +void FileChildWindow::collapse_entry(Pane* pane, Entry* dir) +{ + int idx = ListBox_FindItemData(*pane, 0, dir); + + SendMessage(*pane, WM_SETREDRAW, FALSE, 0); //ShowWindow(*pane, SW_HIDE); + + // hide sub entries + for(;;) { + LRESULT res = ListBox_GetItemData(*pane, idx+1); + Entry* sub = (Entry*) res; + + if (res==LB_ERR || !sub || sub->_level<=dir->_level) + break; + + ListBox_DeleteString(*pane, idx+1); + } + + dir->_expanded = false; + + SendMessage(*pane, WM_SETREDRAW, TRUE, 0); //ShowWindow(*pane, SW_SHOW); +} + + +FileChildWindow* FileChildWindow::create(HWND hmdiclient, const FileChildWndInfo& info) +{ + MDICREATESTRUCT mcs; + + mcs.szClass = CLASSNAME_WINEFILETREE; + mcs.szTitle = (LPTSTR)info._path; + mcs.hOwner = g_Globals._hInstance; + mcs.x = info._pos.rcNormalPosition.left; + mcs.y = info._pos.rcNormalPosition.top; + mcs.cx = info._pos.rcNormalPosition.right - info._pos.rcNormalPosition.left; + mcs.cy = info._pos.rcNormalPosition.bottom - info._pos.rcNormalPosition.top; + mcs.style = 0; + mcs.lParam = 0; + + FileChildWindow* child = static_cast( + create_mdi_child(hmdiclient, mcs, WINDOW_CREATOR_INFO(FileChildWindow,FileChildWndInfo), &info)); + + return child; +} + + +void FileChildWindow::resize_children(int cx, int cy) +{ + HDWP hdwp = BeginDeferWindowPos(4); + RECT rt; + + rt.left = 0; + rt.top = 0; + rt.right = cx; + rt.bottom = cy; + + cx = _split_pos + SPLIT_WIDTH/2; + + { + WINDOWPOS wp; + HD_LAYOUT hdl; + + hdl.prc = &rt; + hdl.pwpos = ℘ + + Header_Layout(_left->_hwndHeader, &hdl); + + hdwp = DeferWindowPos(hdwp, _left->_hwndHeader, wp.hwndInsertAfter, + wp.x-1, wp.y, _split_pos-SPLIT_WIDTH/2+1, wp.cy, wp.flags); + + hdwp = DeferWindowPos(hdwp, _right->_hwndHeader, wp.hwndInsertAfter, + rt.left+cx+1, wp.y, wp.cx-cx+2, wp.cy, wp.flags); + } + + if (_left_hwnd) + 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); + + hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); + + EndDeferWindowPos(hdwp); +} + + +LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_DRAWITEM: { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lparam; + Entry* entry = (Entry*) dis->itemData; + + if (dis->CtlID == IDW_TREE_LEFT) + _left->draw_item(dis, entry); + else + _right->draw_item(dis, entry); + + return TRUE;} + + case WM_SIZE: + if (wparam != SIZE_MINIMIZED) + resize_children(LOWORD(lparam), HIWORD(lparam)); + return DefMDIChildProc(_hwnd, nmsg, wparam, lparam); + + case PM_GET_FILEWND_PTR: + return (LRESULT)this; + + case WM_SETFOCUS: { + TCHAR path[MAX_PATH]; + + if (_left->_cur) { + _left->_cur->get_path(path); + SetCurrentDirectory(path); + } + + SetFocus(_focus_pane? _right_hwnd: _left_hwnd); + goto def;} + + case PM_DISPATCH_COMMAND: { + Pane* pane = GetFocus()==_left_hwnd? _left: _right; + + switch(LOWORD(wparam)) { + case ID_WINDOW_NEW: + if (_root._entry->_etype == ET_SHELL) + FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, ShellChildWndInfo(_path,DesktopFolder())); + else + FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, FileChildWndInfo(_path)); + break; + + case ID_REFRESH: { + bool expanded = _left->_cur->_expanded; + + scan_entry(_left->_cur, _hwnd); + + if (expanded) + expand_entry(_left->_cur); + break;} + + case ID_ACTIVATE: + activate_entry(pane, _hwnd); + break; + + default: + return pane->command(LOWORD(wparam)); + } + + return TRUE;} + + default: def: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; +} + + +int FileChildWindow::Command(int id, int code) +{ + Pane* pane = GetFocus()==_left_hwnd? _left: _right; + + switch(code) { + case LBN_SELCHANGE: { + int idx = ListBox_GetCurSel(*pane); + Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx); + + if (pane == _left) + set_curdir(entry, _hwnd); + else + pane->_cur = entry; + break;} + + case LBN_DBLCLK: + activate_entry(pane, _hwnd); + break; + } + + return 0; +} + + +void FileChildWindow::activate_entry(Pane* pane, HWND hwnd) +{ + Entry* entry = pane->_cur; + + if (!entry) + return; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + int scanned_old = entry->_scanned; + + if (!scanned_old) + scan_entry(entry, hwnd); + + if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='\0') + return; + + if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='.' && entry->_data.cFileName[2]=='\0') { + entry = _left->_cur->_up; + collapse_entry(_left, entry); + goto focus_entry; + } else if (entry->_expanded) + collapse_entry(pane, _left->_cur); + else { + expand_entry(_left->_cur); + + if (!pane->_treePane) focus_entry: { + int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), entry); + ListBox_SetCurSel(_left_hwnd, idx); + set_curdir(entry, _hwnd); + } + } + + if (!scanned_old) { + pane->calc_widths(FALSE); + + pane->set_header(); + } + } else { + entry->launch_entry(_hwnd); + } +} + + +void FileChildWindow::scan_entry(Entry* entry, HWND hwnd) +{ + int idx = ListBox_GetCurSel(_left_hwnd); + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + + // delete sub entries in left pane + for(;;) { + LRESULT res = ListBox_GetItemData(_left_hwnd, idx+1); + Entry* sub = (Entry*) res; + + if (res==LB_ERR || !sub || sub->_level<=entry->_level) + break; + + ListBox_DeleteString(_left_hwnd, idx+1); + } + + // empty right pane + ListBox_ResetContent(_right_hwnd); + + // release memory + entry->free_subentries(); + entry->_expanded = false; + + // read contents from disk + entry->read_directory(_sortOrder); + + // insert found entries in right pane + _right->insert_entries(entry->_down, -1); + + _right->calc_widths(false); + _right->set_header(); + + _header_wdths_ok = FALSE; + + SetCursor(old_cursor); +} + + +int FileChildWindow::Notify(int id, NMHDR* pnmh) +{ + return (pnmh->idFrom==IDW_HEADER_LEFT? _left: _right)->Notify(id, pnmh); +} + + +BOOL CALLBACK ExecuteDialog::WndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + static struct ExecuteDialog* dlg; + + switch(nmsg) { + case WM_INITDIALOG: + dlg = (struct ExecuteDialog*) lparam; + return 1; + + case WM_COMMAND: { + int id = (int)wparam; + + if (id == IDOK) { + GetWindowText(GetDlgItem(hwnd, 201), dlg->cmd, MAX_PATH); + dlg->cmdshow = Button_GetState(GetDlgItem(hwnd,214))&BST_CHECKED? + SW_SHOWMINIMIZED: SW_SHOWNORMAL; + EndDialog(hwnd, id); + } else if (id == IDCANCEL) + EndDialog(hwnd, id); + + return 1;} + } + + return 0; +}