2 * Copyright 2003 Martin Fuchs
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.
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.
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
25 // Martin Fuchs, 23.07.2003
29 #include "../utility/utility.h"
31 #include "../explorer.h"
32 #include "../globals.h"
34 #include "../explorer_intres.h"
37 FileChildWndInfo::FileChildWndInfo(LPCTSTR path)
48 _pos.length = sizeof(WINDOWPLACEMENT);
50 _pos.showCmd = SW_SHOWNORMAL;
51 _pos.rcNormalPosition.left = CW_USEDEFAULT;
52 _pos.rcNormalPosition.top = CW_USEDEFAULT;
53 _pos.rcNormalPosition.right = CW_USEDEFAULT;
54 _pos.rcNormalPosition.bottom = CW_USEDEFAULT;
60 ShellChildWndInfo::ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_path)
61 : FileChildWndInfo(path),
63 _root_shell_path(root_shell_path)
70 FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
73 TCHAR drv[_MAX_DRIVE+1];
76 if (info._etype == ET_SHELL) //@@ evtl. Aufteilung von FileChildWindow in ShellChildWindow, WinChildWindow, UnixChildWindow
78 _root._drive_type = DRIVE_UNKNOWN;
79 lstrcpy(drv, TEXT("\\"));
80 lstrcpy(_root._volname, TEXT("Desktop"));
82 lstrcpy(_root._fs, TEXT("Shell"));
84 const ShellChildWndInfo& shell_info = static_cast<const ShellChildWndInfo&>(info);
85 _root._entry = new ShellDirectory(Desktop(), DesktopFolder(), hwnd);
86 entry = _root._entry->read_tree((LPCTSTR)&*shell_info._shell_path, SORT_NAME/*_sortOrder*/);
90 if (info._etype == ET_UNIX)
92 _root._drive_type = GetDriveType(info._path);
94 _tsplitpath(info._path, drv, NULL, NULL, NULL);
95 lstrcat(drv, TEXT("/"));
96 lstrcpy(_root._volname, TEXT("root fs"));
98 lstrcpy(_root._fs, TEXT("unixfs"));
99 lstrcpy(_root._path, TEXT("/"));
100 _root._entry = new UnixDirectory(_root._path);
101 entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/);
105 {// if (info._etype == ET_WINDOWS)
106 _root._drive_type = GetDriveType(info._path);
108 _tsplitpath(info._path, drv, NULL, NULL, NULL);
109 lstrcat(drv, TEXT("\\"));
110 GetVolumeInformation(drv, _root._volname, _MAX_FNAME, 0, 0, &_root._fs_flags, _root._fs, _MAX_DIR);
111 lstrcpy(_root._path, drv);
112 _root._entry = new WinDirectory(_root._path);
113 entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/);
116 if (info._etype != ET_SHELL)
117 wsprintf(_root._entry->_data.cFileName, TEXT("%s - %s"), drv, _root._fs);
119 lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop"));*/
121 _root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
124 if (info._mode_explore) //TODO: Is not-explore-mode for FileChildWindow completely implemented?
125 _left_hwnd = *(_left=new Pane(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT, _root._entry, true, 0));
127 _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));
129 _sortOrder = SORT_NAME;
130 _header_wdths_ok = false;
132 set_curdir(entry, hwnd);
135 int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), _left->_cur);
136 ListBox_SetCurSel(_left_hwnd, idx);
139 //TODO: scroll to visibility
143 FileChildWindow::~FileChildWindow()
148 void FileChildWindow::set_curdir(Entry* entry, HWND hwnd)
150 _path[0] = TEXT('\0');
153 _right->_root = entry&&entry->_down? entry->_down: entry;
154 _right->_cur = entry;
157 if (!entry->_scanned)
158 scan_entry(entry, hwnd);
160 ListBox_ResetContent(_right_hwnd);
161 _right->insert_entries(entry->_down, -1);
162 _right->calc_widths(false);
163 _right->set_header();
166 entry->get_path(_path);
169 if (hwnd) // only change window title, if the window already exists
170 SetWindowText(hwnd, _path);
173 if (!SetCurrentDirectory(_path))
174 _path[0] = TEXT('\0');
178 // expand a directory entry
180 bool FileChildWindow::expand_entry(Entry* dir)
185 if (!dir || dir->_expanded || !dir->_down)
190 if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='\0' && p->_next) {
193 if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='.' &&
194 p->_data.cFileName[2]=='\0' && p->_next)
198 // no subdirectories ?
199 if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
202 idx = ListBox_FindItemData(_left_hwnd, 0, dir);
204 dir->_expanded = true;
206 // insert entries in left pane
207 _left->insert_entries(p, idx);
209 if (!_header_wdths_ok) {
210 if (_left->calc_widths(false)) {
213 _header_wdths_ok = true;
221 void FileChildWindow::collapse_entry(Pane* pane, Entry* dir)
223 int idx = ListBox_FindItemData(*pane, 0, dir);
225 SendMessage(*pane, WM_SETREDRAW, FALSE, 0); //ShowWindow(*pane, SW_HIDE);
229 LRESULT res = ListBox_GetItemData(*pane, idx+1);
230 Entry* sub = (Entry*) res;
232 if (res==LB_ERR || !sub || sub->_level<=dir->_level)
235 ListBox_DeleteString(*pane, idx+1);
238 dir->_expanded = false;
240 SendMessage(*pane, WM_SETREDRAW, TRUE, 0); //ShowWindow(*pane, SW_SHOW);
244 FileChildWindow* FileChildWindow::create(HWND hmdiclient, const FileChildWndInfo& info)
248 mcs.szClass = CLASSNAME_WINEFILETREE;
249 mcs.szTitle = (LPTSTR)info._path;
250 mcs.hOwner = g_Globals._hInstance;
251 mcs.x = info._pos.rcNormalPosition.left;
252 mcs.y = info._pos.rcNormalPosition.top;
253 mcs.cx = info._pos.rcNormalPosition.right - info._pos.rcNormalPosition.left;
254 mcs.cy = info._pos.rcNormalPosition.bottom - info._pos.rcNormalPosition.top;
258 FileChildWindow* child = static_cast<FileChildWindow*>(
259 create_mdi_child(hmdiclient, mcs, WINDOW_CREATOR_INFO(FileChildWindow,FileChildWndInfo), &info));
265 void FileChildWindow::resize_children(int cx, int cy)
267 HDWP hdwp = BeginDeferWindowPos(4);
275 cx = _split_pos + SPLIT_WIDTH/2;
284 Header_Layout(_left->_hwndHeader, &hdl);
286 hdwp = DeferWindowPos(hdwp, _left->_hwndHeader, wp.hwndInsertAfter,
287 wp.x-1, wp.y, _split_pos-SPLIT_WIDTH/2+1, wp.cy, wp.flags);
289 hdwp = DeferWindowPos(hdwp, _right->_hwndHeader, wp.hwndInsertAfter,
290 rt.left+cx+1, wp.y, wp.cx-cx+2, wp.cy, wp.flags);
294 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);
296 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
298 EndDeferWindowPos(hdwp);
302 LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
306 LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lparam;
307 Entry* entry = (Entry*) dis->itemData;
309 if (dis->CtlID == IDW_TREE_LEFT)
310 _left->draw_item(dis, entry);
312 _right->draw_item(dis, entry);
317 if (wparam != SIZE_MINIMIZED)
318 resize_children(LOWORD(lparam), HIWORD(lparam));
319 return DefMDIChildProc(_hwnd, nmsg, wparam, lparam);
321 case PM_GET_FILEWND_PTR:
322 return (LRESULT)this;
325 TCHAR path[MAX_PATH];
328 _left->_cur->get_path(path);
329 SetCurrentDirectory(path);
332 SetFocus(_focus_pane? _right_hwnd: _left_hwnd);
335 case PM_DISPATCH_COMMAND: {
336 Pane* pane = GetFocus()==_left_hwnd? _left: _right;
338 switch(LOWORD(wparam)) {
340 if (_root._entry->_etype == ET_SHELL)
341 FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, ShellChildWndInfo(_path,DesktopFolder()));
343 FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, FileChildWndInfo(_path));
347 bool expanded = _left->_cur->_expanded;
349 scan_entry(_left->_cur, _hwnd);
352 expand_entry(_left->_cur);
356 activate_entry(pane, _hwnd);
360 return pane->command(LOWORD(wparam));
366 return super::WndProc(nmsg, wparam, lparam);
373 int FileChildWindow::Command(int id, int code)
375 Pane* pane = GetFocus()==_left_hwnd? _left: _right;
378 case LBN_SELCHANGE: {
379 int idx = ListBox_GetCurSel(*pane);
380 Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
383 set_curdir(entry, _hwnd);
389 activate_entry(pane, _hwnd);
397 void FileChildWindow::activate_entry(Pane* pane, HWND hwnd)
399 Entry* entry = pane->_cur;
404 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
405 int scanned_old = entry->_scanned;
408 scan_entry(entry, hwnd);
410 if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='\0')
413 if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='.' && entry->_data.cFileName[2]=='\0') {
414 entry = _left->_cur->_up;
415 collapse_entry(_left, entry);
417 } else if (entry->_expanded)
418 collapse_entry(pane, _left->_cur);
420 expand_entry(_left->_cur);
422 if (!pane->_treePane) focus_entry: {
423 int idx = ListBox_FindItemData(_left_hwnd, ListBox_GetCurSel(_left_hwnd), entry);
424 ListBox_SetCurSel(_left_hwnd, idx);
425 set_curdir(entry, _hwnd);
430 pane->calc_widths(FALSE);
435 entry->launch_entry(_hwnd);
440 void FileChildWindow::scan_entry(Entry* entry, HWND hwnd)
442 int idx = ListBox_GetCurSel(_left_hwnd);
443 HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
445 // delete sub entries in left pane
447 LRESULT res = ListBox_GetItemData(_left_hwnd, idx+1);
448 Entry* sub = (Entry*) res;
450 if (res==LB_ERR || !sub || sub->_level<=entry->_level)
453 ListBox_DeleteString(_left_hwnd, idx+1);
457 ListBox_ResetContent(_right_hwnd);
460 entry->free_subentries();
461 entry->_expanded = false;
463 // read contents from disk
464 entry->read_directory(_sortOrder);
466 // insert found entries in right pane
467 _right->insert_entries(entry->_down, -1);
469 _right->calc_widths(false);
470 _right->set_header();
472 _header_wdths_ok = FALSE;
474 SetCursor(old_cursor);
478 int FileChildWindow::Notify(int id, NMHDR* pnmh)
480 return (pnmh->idFrom==IDW_HEADER_LEFT? _left: _right)->Notify(id, pnmh);
484 BOOL CALLBACK ExecuteDialog::WndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
486 static struct ExecuteDialog* dlg;
490 dlg = (struct ExecuteDialog*) lparam;
494 int id = (int)wparam;
497 GetWindowText(GetDlgItem(hwnd, 201), dlg->cmd, MAX_PATH);
498 dlg->cmdshow = Button_GetState(GetDlgItem(hwnd,214))&BST_CHECKED?
499 SW_SHOWMINIMIZED: SW_SHOWNORMAL;
501 } else if (id == IDCANCEL)