//
-#include "../utility/utility.h"
-#include "../utility/shellclasses.h"
-#include "../globals.h" // for _prescan_nodes
+#include "precomp.h"
-#include "entries.h"
+//#include "entries.h"
// allocate and initialise a directory entry
// read directory tree and expand to the given location
-Entry* Entry::read_tree(const void* path, SORT_ORDER sortOrder)
+Entry* Entry::read_tree(const void* path, SORT_ORDER sortOrder, int scan_flags)
{
CONTEXT("Entry::read_tree()");
- HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
+ WaitCursor wait;
Entry* entry = this;
- Entry* next_entry = entry;
- for(const void*p=path; p&&next_entry; p=entry->get_next_path_component(p)) {
- entry = next_entry;
-
- entry->read_directory(sortOrder);
+ for(const void*p=path; p && entry; ) {
+ entry->smart_scan(sortOrder, scan_flags);
if (entry->_down)
entry->_expanded = true;
- next_entry = entry->find_entry(p);
- }
+ Entry* found = entry->find_entry(p);
+ p = entry->get_next_path_component(p);
- SetCursor(old_cursor);
+ entry = found;
+ }
return entry;
}
-void Entry::read_directory(SORT_ORDER sortOrder, int scan_flags)
+void Entry::read_directory_base(SORT_ORDER sortOrder, int scan_flags)
{
- CONTEXT("Entry::read_directory(SORT_ORDER)");
+ CONTEXT("Entry::read_directory_base()");
// call into subclass
read_directory(scan_flags);
+#ifndef ROSSHELL
if (g_Globals._prescan_nodes) { //@todo _prescan_nodes should not be used for reading the start menu.
for(Entry*entry=_down; entry; entry=entry->_next)
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
entry->sort_directory(sortOrder);
}
}
+#endif
sort_directory(sortOrder);
}
// directories first...
static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
{
- int dir1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- int dir2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ int order1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ int order2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- return dir2==dir1? 0: dir2<dir1? -1: 1;
+ /* Handle "." and ".." as special case and move them at the very first beginning. */
+ if (order1 && order2) {
+ order1 = fd1->cFileName[0]!='.'? 1: fd1->cFileName[1]=='.'? 2: fd1->cFileName[1]=='\0'? 3: 1;
+ order2 = fd2->cFileName[0]!='.'? 1: fd2->cFileName[1]=='.'? 2: fd2->cFileName[1]=='\0'? 3: 1;
+ }
+
+ return order2==order1? 0: order2<order1? -1: 1;
}
}
-void Entry::smart_scan(int scan_flags)
+void Entry::smart_scan(SORT_ORDER sortOrder, int scan_flags)
{
CONTEXT("Entry::smart_scan()");
if (!_scanned) {
free_subentries();
- read_directory(SORT_NAME, scan_flags); // we could use IShellFolder2::GetDefaultColumn to determine sort order
+ read_directory_base(sortOrder, scan_flags); ///@todo We could use IShellFolder2::GetDefaultColumn to determine sort order.
}
}
ICON_ID icon_id = ICID_NONE;
- if (get_path(path))
+ if (get_path(path) && _tcsncmp(path,TEXT("::{"),3))
icon_id = g_Globals._icon_cache.extract(path);
if (icon_id == ICID_NONE) {
}
+HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs)
+{
+ ShellPath shell_path = create_absolute_pidl();
+ LPCITEMIDLIST pidl_abs = shell_path;
+
+ if (!pidl_abs)
+ return S_FALSE; // no action for registry entries, etc.
+
+ static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent");
+
+ if (SHBindToParent) {
+ IShellFolder* parentFolder;
+ LPCITEMIDLIST pidlLast;
+
+ // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ...
+ HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
+
+ if (SUCCEEDED(hr)) {
+ hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs);
+
+ parentFolder->Release();
+ }
+
+ return hr;
+ } else {
+ /**@todo use parent folder instead of desktop folder
+ Entry* dir = _up;
+
+ ShellPath parent_path;
+
+ if (dir)
+ parent_path = dir->create_absolute_pidl();
+ else
+ parent_path = DesktopFolderPath();
+
+ ShellPath shell_path = create_relative_pidl(parent_path);
+ LPCITEMIDLIST pidl = shell_path;
+
+ ShellFolder parent_folder = parent_path;
+ return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
+ */
+ return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y, cm_ifs);
+ }
+}
+
+
HRESULT Entry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{
TCHAR path[MAX_PATH];
}
-const void* Directory::get_next_path_component(const void* p)
+Entry* Root::read_tree(LPCTSTR path, int scan_flags)
{
- LPCTSTR s = (LPCTSTR) p;
+ Entry* entry;
- while(*s && *s!=TEXT('\\') && *s!=TEXT('/'))
- ++s;
+ if (path && *path)
+ entry = _entry->read_tree(path, _sort_order);
+ else {
+ entry = _entry->read_tree(NULL, _sort_order);
- while(*s==TEXT('\\') || *s==TEXT('/'))
- ++s;
+ _entry->smart_scan();
- if (!*s)
- return NULL;
+ if (_entry->_down)
+ _entry->_expanded = true;
+ }
- return s;
+ return entry;
+}
+
+
+Entry* Root::read_tree(LPCITEMIDLIST pidl, int scan_flags)
+{
+ return _entry->read_tree(pidl, _sort_order);
}