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
)
52 _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();