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"
30 #include "../utility/shellclasses.h"
31 #include "../globals.h" // for _prescan_nodes
36 // allocate and initialise a directory entry
37 Entry::Entry(ENTRY_TYPE etype)
50 Entry::Entry(Entry* parent)
51 : _etype(parent->_etype),
63 // free a directory entry
66 if (_hIcon && _hIcon!=(HICON)-1)
71 // read directory tree and expand to the given location
72 Entry* Entry::read_tree(const void* path, SORT_ORDER sortOrder)
74 HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
77 Entry* next_entry = entry;
79 for(const void*p=path; p&&next_entry; p=entry->get_next_path_component(p)) {
82 entry->read_directory(sortOrder);
85 entry->_expanded = true;
87 next_entry = entry->find_entry(p);
90 SetCursor(old_cursor);
96 void Entry::read_directory(SORT_ORDER sortOrder)
101 if (g_Globals._prescan_nodes) {
102 for(Entry*entry=_down; entry; entry=entry->_next)
103 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
104 entry->read_directory();
105 entry->sort_directory(sortOrder);
109 sort_directory(sortOrder);
115 memset(this, 0, sizeof(Root));
121 _entry->free_subentries();
125 // directories first...
126 static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
128 int dir1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
129 int dir2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
131 return dir2==dir1? 0: dir2<dir1? -1: 1;
135 static int compareName(const void* arg1, const void* arg2)
137 const WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data;
138 const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data;
140 int cmp = compareType(fd1, fd2);
144 return lstrcmpi(fd1->cFileName, fd2->cFileName);
147 static int compareExt(const void* arg1, const void* arg2)
149 const WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data;
150 const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data;
151 const TCHAR *name1, *name2, *ext1, *ext2;
153 int cmp = compareType(fd1, fd2);
157 name1 = fd1->cFileName;
158 name2 = fd2->cFileName;
160 ext1 = _tcsrchr(name1, TEXT('.'));
161 ext2 = _tcsrchr(name2, TEXT('.'));
173 cmp = lstrcmpi(ext1, ext2);
177 return lstrcmpi(name1, name2);
180 static int compareSize(const void* arg1, const void* arg2)
182 WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data;
183 WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data;
185 int cmp = compareType(fd1, fd2);
189 cmp = fd2->nFileSizeHigh - fd1->nFileSizeHigh;
196 cmp = fd2->nFileSizeLow - fd1->nFileSizeLow;
198 return cmp<0? -1: cmp>0? 1: 0;
201 static int compareDate(const void* arg1, const void* arg2)
203 WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data;
204 WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data;
206 int cmp = compareType(fd1, fd2);
210 return CompareFileTime(&fd2->ftLastWriteTime, &fd1->ftLastWriteTime);
214 static int (*sortFunctions[])(const void* arg1, const void* arg2) = {
215 compareName, // SORT_NAME
216 compareExt, // SORT_EXT
217 compareSize, // SORT_SIZE
218 compareDate // SORT_DATE
222 void Entry::sort_directory(SORT_ORDER sortOrder)
224 Entry* entry = _down;
229 for(entry=_down; entry; entry=entry->_next)
233 array = (Entry**) alloca(len*sizeof(Entry*));
236 for(entry=_down; entry; entry=entry->_next)
239 // call qsort with the appropriate compare function
240 qsort(array, len, sizeof(array[0]), sortFunctions[sortOrder]);
244 for(p=array; --len; p++)
252 void Entry::smart_scan()
256 read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order
261 BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
267 // start program, open document...
268 return launch_file(hwnd, cmd, nCmdShow);
272 // recursively free all child entries
273 void Entry::free_subentries()
275 Entry *entry, *next=_down;
284 entry->free_subentries();