source: trunk/dll/select.c@ 1882

Last change on this file since 1882 was 1882, checked in by Gregg Young, 10 years ago

ExpandAll on a CDROM drive caused directory not found errors. Changed waits so they are longer on removable drives errors are gone performance on hard drives is unchanged.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: select.c 1882 2015-10-12 19:59:34Z gyoung $
5
6 Container item selection support routines
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2004, 2015 Steven H. Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 25 May 05 SHL Rework for ULONGLONG
13 06 Jun 05 SHL Drop unused code
14 06 Jul 06 SHL Support compare content (IDM_SELECTSAMECONTENT)
15 13 Jul 06 SHL Use Runtime_Error
16 29 Jul 06 SHL Use xfgets_bstripcr
17 15 Aug 06 SHL Rework SetMask args and logic
18 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
19 19 Apr 07 SHL Sync with NumItemsToUnhilite mods
20 12 May 07 SHL Use dcd->ulItemsToUnHilite
21 14 Jun 07 SHL SelectAll: make odd expression go away
22 02 Aug 07 SHL Sync with CNRITEM mods
23 04 Aug 07 SHL Use Runtime_Error
24 05 Aug 07 SHL Rework SpecialSelect to use CNRITEM_EXISTS and
25 not use pszFileName since CNRITEM_EXISTS set implies
26 pszFileName not null
27 14 Aug 07 SHL Revert ExpandAll DosSleep to 0
28 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
29 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
30 12 Jan 08 SHL Localize SpecialSelect in comp.c
31 29 Feb 08 GKY Use xfree where appropriate
32 31 May 11 SHL Ensure mask->pszMasks[1] initialize to NULL if not used
33 13 Jun 15 GKY Fixed compare selection replaced pszFileNames with pszDisplayNames
34 02 Aug 15 GKY Remove unneed SubbyScan code and improve suppression of blank lines and
35 duplicate subdirectory name caused by running Stubby in worker threads.
36 20 Sep 15 GKY Create CollapseAll and modify ExpandAll to reduce code overhead
37 both to try and speed drive expansion. Change ExpandAll to allow it to loop
38 in UM_EXPAND until until drive is completely expanded. Changes were need to
39 work with Flesh, Stubby and UnFlesh being moved to a thread
40 26 Sep 15 GKY Changes to speed up ExpandAll
41 27 Sep 15 GKY DosSleep times in WaitFleshWorkListEmpty set by caller
42
43***********************************************************************/
44
45#include <stdlib.h>
46#include <string.h>
47#include <share.h>
48#include <io.h>
49
50#define INCL_DOS
51#define INCL_WIN
52#define INCL_LONGLONG
53
54#include "fm3dll.h"
55#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
56#include "select.h"
57#include "notebook.h" // Data declaration(s)
58#include "newview.h" // Data declarations
59#include "fm3str.h"
60#include "filldir.h" // RemoveCnrItems
61#include "makelist.h" // AddToList
62#include "errutil.h" // Dos_Error...
63#include "strutil.h" // GetPString
64#include "valid.h" // TestCDates
65#include "misc.h" // CurrentRecord
66#include "findrec.h" // FindCnrRecord
67#include "notify.h" // Notify
68#include "literal.h" // wildcard
69#include "wrappers.h" // xrealloc
70#include "strips.h" // bstrip
71#include "stristr.h" // findstring
72#include "fortify.h"
73#include "flesh.h"
74#include "treecnr.h" // fExpandAll
75#if 0
76#define __PMPRINTF__
77#include "PMPRINTF.H"
78#endif
79
80static PSZ pszSrcFile = __FILE__;
81
82VOID UnHilite(HWND hwndCnr, BOOL all, CHAR *** list, ULONG ulItemsToUnHilite)
83{
84 PCNRITEM pci;
85 UINT numfiles = 0, numalloc = 0;
86 UINT x = 0;
87 INT attribute = CRA_CURSORED;
88
89 if (all && list && *list) {
90 FreeList(*list);
91 *list = NULL;
92 }
93 pci = (PCNRITEM) CurrentRecord(hwndCnr);
94 if (pci && (INT)pci != -1) {
95 if (pci->rc.flRecordAttr & CRA_SELECTED) {
96 attribute = CRA_SELECTED;
97 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
98 MPFROMSHORT(attribute));
99 }
100 while (pci && (INT)pci != -1) {
101 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
102 MPFROM2SHORT(FALSE, CRA_SELECTED));
103 if (!all)
104 break;
105 // Count is one extra to ensure non-zero elsewhere
106 // x is 0 based index
107 if (x + 2 == ulItemsToUnHilite)
108 break;
109 if (list)
110 AddToList(pci->pszFileName, list, &numfiles, &numalloc);
111 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
112 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
113 x++;
114 }
115 }
116}
117
118VOID SelectList(HWND hwndCnr, BOOL partial, BOOL deselect, BOOL clearfirst,
119 PCNRITEM pciParent, PSZ filename, CHAR ** list)
120{
121
122 PCNRITEM pci;
123 register INT x;
124 BOOL foundone = FALSE;
125 ULONG errs = 0;
126
127 if (clearfirst && !deselect)
128 UnHilite(hwndCnr, TRUE, NULL, 0);
129 if (list && list[0]) {
130 for (x = 0; list[x]; x++) {
131 pci = FindCnrRecord(hwndCnr,
132 list[x], pciParent, partial, partial, TRUE);
133 if (pci) {
134 WinSendMsg(hwndCnr,
135 CM_SETRECORDEMPHASIS,
136 MPFROMP(pci),
137 MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
138 CRA_SELECTED));
139 foundone = TRUE;
140 }
141 }
142 if (!foundone)
143 Runtime_Error(pszSrcFile, __LINE__, "select failed");
144 }
145 else if (filename && *filename) {
146
147 FILE *fp;
148 CHAR input[1024], *p;
149 CHAR *moder = "r";
150
151 fp = xfsopen(filename, moder, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
152 if (fp) {
153 while (!feof(fp)) {
154 if (!xfgets_bstripcr(input, sizeof(input), fp, pszSrcFile, __LINE__))
155 break;
156 if (*input == '\"') {
157 memmove(input, input + 1, strlen(input) + 1);
158 lstrip(input);
159 p = strchr(input, '\"');
160 if (p)
161 *p = 0;
162 rstrip(input);
163 }
164 else {
165 p = strchr(input, ' ');
166 if (p)
167 *p = 0;
168 }
169 // Input now contains name of file to select
170 pci = FindCnrRecord(hwndCnr,
171 input, pciParent, partial, partial, TRUE);
172 if (pci) // Found it?
173 WinSendMsg(hwndCnr,
174 CM_SETRECORDEMPHASIS,
175 MPFROMP(pci),
176 MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
177 CRA_SELECTED));
178 else
179 errs++;
180 if (errs > 50) { // Prevent runaway on bad file
181
182 APIRET ret;
183
184 ret = saymsg(MB_YESNO,
185 hwndCnr,
186 GetPString(IDS_POSSIBLEERRORTEXT),
187 GetPString(IDS_MAYNOTBELISTTEXT), filename);
188 if (ret == MBID_NO)
189 break;
190 errs = 0;
191 }
192 }
193 fclose(fp);
194 }
195 }
196}
197
198VOID SelectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
199 PSZ text, BOOL is_arc)
200{
201
202 PCNRITEM pci;
203 BOOL markit;
204 PSZ file;
205 PSZ pszToMatch;
206 MASK Mask;
207 INT x;
208 ULONG textlen = 0;
209
210 if (text)
211 textlen = strlen(text);
212 memset(&Mask, 0, sizeof(Mask));
213 if (maskstr)
214 SetMask(maskstr, &Mask);
215 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
216 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
217 while (pci && (INT)pci != -1) {
218
219 markit = FALSE;
220
221 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
222 if (!is_arc) {
223 if (files && ~pci->attrFile & FILE_DIRECTORY)
224 markit = TRUE;
225 if (dirs && pci->attrFile & FILE_DIRECTORY)
226 markit = TRUE;
227 }
228 else
229 markit = TRUE;
230 if (maskstr && *maskstr && markit) {
231 markit = FALSE;
232 // Point a filename part
233 file = strrchr(pci->pszFileName, '\\');
234 if (!file)
235 file = strrchr(pci->pszFileName, ':');
236 if (file)
237 file++;
238 else
239 file = pci->pszFileName;
240 for (x = 0; Mask.pszMasks[x]; x++) {
241 if (*Mask.pszMasks[x]) {
242 if ((strchr(Mask.pszMasks[x], '\\') ||
243 strchr(Mask.pszMasks[x], ':')))
244 pszToMatch = pci->pszFileName;
245 else
246 pszToMatch = file;
247 if (*Mask.pszMasks[x] != '/') {
248 if (wildcard(pszToMatch, Mask.pszMasks[x], TRUE)) {
249 markit = TRUE;
250 }
251 }
252 else {
253 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, TRUE)) {
254 markit = FALSE;
255 break;
256 }
257 }
258 }
259 } // for
260 }
261 }
262
263 if (markit && text && *text) {
264 if (~pci->attrFile & FILE_DIRECTORY) {
265 PSZ input;
266 markit = FALSE;
267 input = xmalloc(65537, pszSrcFile, __LINE__);
268 if (input) {
269 ULONG pos;
270 LONG len;
271 FILE *inputFile;
272 CHAR *moderb = "rb";
273
274 if ((inputFile = xfsopen(pci->pszFileName, moderb, SH_DENYNO,
275 pszSrcFile, __LINE__, TRUE)) != NULL) {
276 pos = ftell(inputFile);
277 while (!feof(inputFile)) {
278 if (pos)
279 fseek(inputFile, pos - 256, SEEK_SET);
280 len = fread(input, 1, 65536, inputFile);
281 if (len >= 0) {
282 if (findstring(text, textlen, input, len, FALSE)) {
283 markit = TRUE;
284 break;
285 }
286 }
287 else
288 break;
289 } // while
290 fclose(inputFile);
291 }
292 free(input);
293 DosSleep(1);
294 }
295 }
296 else
297 markit = FALSE;
298 }
299
300 if (markit)
301 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
302 MPFROM2SHORT(TRUE, CRA_SELECTED));
303 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
304 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
305 } // while
306}
307
308VOID DeselectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
309 PSZ text, BOOL is_arc)
310{
311 PCNRITEM pci;
312 BOOL unmarkit;
313 PSZ file;
314 PSZ pszToMatch;
315 MASK Mask;
316 register INT x;
317 ULONG textlen = 0;
318
319 if (text)
320 textlen = strlen(text);
321 memset(&Mask, 0, sizeof(Mask));
322 if (maskstr && *maskstr)
323 SetMask(maskstr, &Mask);
324 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
325 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
326 while (pci && (INT)pci != -1) {
327 unmarkit = FALSE;
328 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
329 if (!is_arc) {
330 if (files && ~pci->attrFile & FILE_DIRECTORY)
331 unmarkit = TRUE;
332 if (dirs && (pci->attrFile & FILE_DIRECTORY))
333 unmarkit = TRUE;
334 }
335 else
336 unmarkit = TRUE;
337 if (maskstr && *maskstr && unmarkit) {
338 unmarkit = FALSE;
339 file = strrchr(pci->pszFileName, '\\');
340 if (!file)
341 file = strrchr(pci->pszFileName, ':');
342 if (file)
343 file++;
344 else
345 file = pci->pszFileName;
346 for (x = 0; Mask.pszMasks[x]; x++) {
347 if (*Mask.pszMasks[x]) {
348 if (strchr(Mask.pszMasks[x], '\\') ||
349 strchr(Mask.pszMasks[x], ':'))
350 pszToMatch = pci->pszFileName;
351 else
352 pszToMatch = file;
353 if (*Mask.pszMasks[x] != '/') {
354 if (wildcard(pszToMatch, Mask.pszMasks[x], TRUE))
355 unmarkit = TRUE;
356 }
357 else {
358 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, TRUE)) {
359 unmarkit = FALSE;
360 break;
361 }
362 }
363 }
364 }
365 }
366 }
367
368 if (unmarkit && text && *text) {
369 if (~pci->attrFile & FILE_DIRECTORY) {
370 PSZ input;
371 unmarkit = FALSE;
372 input = xmalloc(65537, pszSrcFile, __LINE__);
373 if (input) {
374 ULONG pos;
375 LONG len;
376 FILE *inputFile;
377 CHAR *moderb = "rb";
378
379 if ((inputFile = xfsopen(pci->pszFileName, moderb, SH_DENYNO,
380 pszSrcFile, __LINE__, TRUE)) != NULL) {
381 pos = ftell(inputFile);
382 while (!feof(inputFile)) {
383 if (pos)
384 fseek(inputFile, pos - 256, SEEK_SET);
385 len = fread(input, 1, 65536, inputFile);
386 if (len >= 0) {
387 if (findstring(text, textlen, input, len, FALSE)) {
388 unmarkit = TRUE;
389 break;
390 }
391 }
392 else
393 break;
394 } // while
395 fclose(inputFile);
396 }
397 free(input);
398 DosSleep(1);
399 }
400 }
401 else
402 unmarkit = FALSE;
403 }
404
405 if (unmarkit)
406 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
407 MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED |
408 CRA_INUSE | CRA_SOURCE));
409 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
410 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
411 }
412}
413
414VOID Deselect(HWND hwndCnr)
415{
416 PCNRITEM pcil;
417
418 pcil = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
419 MPFROMLONG(CMA_FIRST),
420 MPFROMSHORT(CRA_SELECTED));
421 while (pcil && (INT)pcil != -1) {
422 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pcil),
423 MPFROM2SHORT(FALSE, CRA_SELECTED));
424 pcil = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pcil),
425 MPFROMSHORT(CRA_SELECTED));
426 }
427}
428
429//=== HideAll() Hide all selected records ===
430
431VOID HideAll(HWND hwndCnr)
432{
433 PCNRITEM pci, pciH;
434 INT attribute = CRA_CURSORED;
435 CNRINFO cnri;
436 BOOL didone = FALSE;
437
438 memset(&cnri, 0, sizeof(CNRINFO));
439 cnri.cb = sizeof(CNRINFO);
440 WinSendMsg(hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
441 MPFROMLONG(sizeof(CNRINFO)));
442 pci = (PCNRITEM) CurrentRecord(hwndCnr);
443 if (pci && (INT)pci != -1) {
444 if (pci->rc.flRecordAttr & CRA_SELECTED) {
445 attribute = CRA_SELECTED;
446 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
447 MPFROMSHORT(attribute));
448 }
449 }
450 while (pci && (INT)pci != -1) {
451 pciH = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
452 MPFROMSHORT(attribute));
453 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
454 MPFROM2SHORT(FALSE, CRA_CURSORED | CRA_SELECTED |
455 CRA_INUSE | CRA_SOURCE));
456 pci->rc.flRecordAttr |= CRA_FILTERED;
457 didone = TRUE;
458 if (fSyncUpdates) {
459 if (cnri.flWindowAttr & CV_DETAIL)
460 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
461 MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
462 else
463 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
464 MPFROM2SHORT(1, CMA_REPOSITION | CMA_ERASE));
465 }
466 pci = pciH;
467 }
468 if (didone && !fSyncUpdates)
469 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
470 MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
471}
472
473VOID MarkAll(HWND hwndCnr, BOOL quitit, BOOL target, BOOL source)
474{
475 PCNRITEM pci;
476 INT attribute = CRA_CURSORED;
477
478 if (quitit)
479 attribute = target ? CRA_TARGET : source ? CRA_SOURCE : CRA_INUSE;
480 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
481 MPFROMLONG(CMA_FIRST), MPFROMSHORT(attribute));
482 if (pci && (INT)pci != -1) {
483 if (attribute == CRA_CURSORED) {
484 if (pci->rc.flRecordAttr & CRA_SELECTED) {
485 attribute = CRA_SELECTED;
486 pci =
487 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
488 MPFROMSHORT(attribute));
489 }
490 }
491 }
492 while (pci && (INT)pci != -1) {
493 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
494 MPFROM2SHORT(!quitit,
495 target ? CRA_TARGET : source ? CRA_SOURCE :
496 CRA_INUSE));
497 pci =
498 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
499 MPFROMSHORT(attribute));
500 }
501}
502
503VOID RemoveAll(HWND hwndCnr, ULONGLONG * pullTotalBytes,
504 ULONG * pulTotalFiles)
505{
506 PCNRITEM pci;
507 INT attribute = CRA_CURSORED;
508 BOOL didone = FALSE;
509
510 pci = (PCNRITEM) CurrentRecord(hwndCnr);
511 if (pci && (INT)pci != -1) {
512 if (pci->rc.flRecordAttr & CRA_SELECTED) {
513 attribute = CRA_SELECTED;
514 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
515 MPFROMSHORT(attribute));
516 }
517 }
518 while (pci && (INT)pci != -1) {
519 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
520 didone = TRUE;
521 if (pulTotalFiles)
522 *pulTotalFiles -= 1;
523 if (pullTotalBytes)
524 *pullTotalBytes -= (pci->cbFile + pci->easize);
525 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
526 MPFROM2SHORT(0, CRA_SELECTED));
527 if (fSyncUpdates)
528 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE | CMA_INVALIDATE);
529 else
530 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE);
531 if (attribute == CRA_CURSORED)
532 break;
533 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
534 MPFROMSHORT(attribute));
535 }
536 else
537 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
538 MPFROMSHORT(attribute));
539 }
540 if (didone && !fSyncUpdates)
541 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
542 MPFROM2SHORT(0, CMA_REPOSITION));
543}
544
545//== SetMask() Convert mask string to array of pointers to masks ==
546
547VOID SetMask(PSZ maskstr, MASK *mask)
548{
549 UINT x;
550 PSZ p;
551
552 DosEnterCritSec();
553 if (maskstr)
554 strcpy(mask->szMask, maskstr); // Got new mask string
555 // Build array of pointers
556 p = mask->szMaskCopy;
557 strcpy(p, mask->szMask);
558 // Allow up to 25 masks - ignore extras
559 for (x = 0; *p && x < 25; x++) {
560 mask->pszMasks[x] = p;
561 while (*p && *p != ';')
562 p++; // Find separator
563 if (*p) {
564 *p = 0; // Replace ; will nul to terminate string
565 p++;
566 }
567 } // for
568 mask->pszMasks[x] = NULL; // Mark end
569 if (!x)
570 mask->pszMasks[1] = NULL; // Need 1 more for multiple mask detect 2011-05-31 SHL
571 DosExitCritSec();
572}
573
574BOOL ExpandAll(HWND hwndCnr, INT count, PCNRITEM pciParent)
575{
576 PCNRITEM pci;
577 static BOOL fExpanding = FALSE; // statics are only used by tree container
578 static INT counter = 1;
579
580 if (count != counter && count != 0) {
581 if (count > counter) {
582 fExpanding = FALSE;
583 counter++;
584 }
585 else if (count < counter) {
586 fExpanding = FALSE;
587 counter = 1;
588 }
589 }
590 if (!pciParent)
591 pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
592 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
593 if (pciParent) {
594 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
595 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
596 // Only expand items that have childern
597 if (pci && ~pciParent->rc.flRecordAttr & CRA_EXPANDED) {
598 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciParent), MPVOID);
599 if (count != 0) {
600 fExpanding = TRUE;
601 if (IsFleshWorkListEmpty())
602 DosSleep(fExpandAll ? 0 : 10); // Yield to EXPANDTREE and Flesh thread
603 if (!IsFleshWorkListEmpty()) {
604 WaitFleshWorkListEmpty(NULL, fExpandAll ? 1 : 50); // Let it expand
605 }
606 }
607 }
608 while (pci && (INT)pci != -1) {
609 ExpandAll(hwndCnr, count, pci);
610 if (count != 0 && !IsFleshWorkListEmpty())
611 WaitFleshWorkListEmpty(NULL, fExpandAll ? 1 : 50); // Wait for container to catch up
612 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
613 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
614 }
615 }
616 return fExpanding;
617}
618
619VOID CollapseAll(HWND hwndCnr, PCNRITEM pciParent)
620{
621 PCNRITEM pci;
622
623 if (!pciParent)
624 pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
625 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
626 if (pciParent) {
627 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
628 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
629 if ((pciParent->rc.flRecordAttr & CRA_EXPANDED))
630 WinSendMsg(hwndCnr, CM_COLLAPSETREE, MPFROMP(pciParent), MPVOID);
631 while (pci && (INT)pci != -1) {
632 CollapseAll(hwndCnr, pci);
633 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
634 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
635 }
636 }
637 DosSleep(0);
638}
639
640VOID InvertAll(HWND hwndCnr)
641{
642 PCNRITEM pci;
643
644 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
645 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
646 while (pci && (INT)pci != -1) {
647 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
648 if (~pci->rc.flRecordAttr & CRA_SELECTED)
649 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
650 MPFROM2SHORT(TRUE, CRA_SELECTED));
651 else
652 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
653 MPFROM2SHORT(FALSE, CRA_SELECTED));
654 }
655 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
656 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
657 }
658}
659
660struct SS
661{
662 PCNRITEM pci;
663 BOOL unique, all, smallest, largest, newest, oldest;
664};
665
666struct Cnr
667{
668 HWND hwndCnr;
669 ULONG numfiles;
670 struct SS *ss;
671};
672
673static int CompSSNamesB(const void *s1, const void *s2)
674{
675 struct SS *ss2 = (struct SS *)s2;
676
677 return stricmp((PSZ)s1, ss2->pci->pszDisplayName);
678}
679
680static int CompSSNames(const void *s1, const void *s2)
681{
682 struct SS *ss1 = (struct SS *)s1;
683 struct SS *ss2 = (struct SS *)s2;
684
685 return stricmp(ss1->pci->pszFileName, ss2->pci->pszFileName);
686}
687
688VOID FreeCnrs(struct Cnr * Cnrs, INT numw)
689{
690 register INT z;
691
692 for (z = 0; z < numw; z++) {
693 xfree(Cnrs[z].ss, pszSrcFile, __LINE__);
694 }
695 xfree(Cnrs, pszSrcFile, __LINE__);
696 DosPostEventSem(CompactSem);
697}
698
699/**
700 * Do select actions for single container
701 *
702 */
703
704VOID SpecialSelect2(HWND hwndParent, INT action)
705{
706 PCNRITEM pci;
707 HENUM henum;
708 HWND hwnd;
709 INT numwindows = 0, w, x, z, cmp = 0;
710 struct Cnr *Cnrs = NULL;
711 struct SS *bsres;
712
713 if (!hwndParent)
714 return;
715
716 // Count directory containers, build array of hwnds
717 henum = WinBeginEnumWindows(hwndParent);
718 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE) {
719 if (WinWindowFromID(WinWindowFromID(hwnd, FID_CLIENT), DIR_CNR)) {
720 Cnrs =
721 xrealloc(Cnrs, (numwindows + 1) * sizeof(struct Cnr), pszSrcFile,
722 __LINE__);
723 if (!Cnrs) {
724 Notify(GetPString(IDS_OUTOFMEMORY));
725 return;
726 }
727 memset(&Cnrs[numwindows], 0, sizeof(struct Cnr));
728 Cnrs[numwindows].hwndCnr = WinWindowFromID(WinWindowFromID(hwnd,
729 FID_CLIENT),
730 DIR_CNR);
731 numwindows++;
732 }
733 }
734 WinEndEnumWindows(henum);
735 if (numwindows < 2) {
736 FreeCnrs(Cnrs, numwindows);
737 Runtime_Error(pszSrcFile, __LINE__, "expected two windows");
738 Notify(GetPString(IDS_COMPSEL2ORMORETEXT));
739 return;
740 }
741 if (numwindows > 4) {
742 WinSendMsg(Cnrs[0].
743 hwndCnr,
744 UM_NOTIFY, MPFROMP(GetPString(IDS_BUILDINGLISTSTEXT)), MPVOID);
745 DosSleep(0); // Allow other windows to update
746 }
747
748 // Count records, build array of pointers to records
749 for (z = 0; z < numwindows; z++) {
750 pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
751 CM_QUERYRECORD,
752 MPVOID,
753 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
754 x = 0;
755 while (pci && (INT)pci != -1) {
756 if (~pci->rc.flRecordAttr & CRA_FILTERED &&
757 ~pci->attrFile & FILE_DIRECTORY) {
758 Cnrs[z].ss =
759 xrealloc(Cnrs[z].ss, (x + 1) * sizeof(struct SS), pszSrcFile,
760 __LINE__);
761 if (!Cnrs[z].ss) {
762 FreeCnrs(Cnrs, numwindows);
763 Notify(GetPString(IDS_OUTOFMEMORY));
764 return;
765 }
766 memset(&Cnrs[z].ss[x], 0, sizeof(struct SS));
767 Cnrs[z].ss[x].pci = pci;
768 x++;
769 }
770 pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
771 CM_QUERYRECORD,
772 MPFROMP(pci),
773 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
774 }
775 DosSleep(0); // Allow other windows to update
776 Cnrs[z].numfiles = x;
777 if (Cnrs[z].numfiles)
778 qsort(Cnrs[z].ss, Cnrs[z].numfiles, sizeof(struct SS), CompSSNames);
779 }
780
781 for (z = 0; z < numwindows; z++) {
782 for (x = 0; x < Cnrs[z].numfiles; x++) {
783 Cnrs[z].ss[x].all = Cnrs[z].ss[x].unique = Cnrs[z].ss[x].newest =
784 Cnrs[z].ss[x].oldest = Cnrs[z].ss[x].smallest =
785 Cnrs[z].ss[x].largest = TRUE;
786 for (w = 0; w < numwindows; w++) {
787 if (w != z && Cnrs[w].numfiles) {
788 bsres = (struct SS *)bsearch(Cnrs[z].ss[x].pci->pszDisplayName,
789 Cnrs[w].ss, Cnrs[w].numfiles,
790 sizeof(struct SS), CompSSNamesB);
791 if (bsres) {
792 Cnrs[z].ss[x].unique = FALSE;
793 if (Cnrs[z].ss[x].pci->cbFile + Cnrs[z].ss[x].pci->easize >
794 bsres->pci->cbFile + bsres->pci->easize)
795 Cnrs[z].ss[x].smallest = FALSE;
796 if (Cnrs[z].ss[x].pci->cbFile + Cnrs[z].ss[x].pci->easize <
797 bsres->pci->cbFile + bsres->pci->easize)
798 Cnrs[z].ss[x].largest = FALSE;
799 cmp = TestCDates(&bsres->pci->date, &bsres->pci->time,
800 &Cnrs[z].ss[x].pci->date, &Cnrs[z].ss[x].pci->time);
801 if (cmp != 1)
802 Cnrs[z].ss[x].newest = FALSE;
803 if (cmp != -1)
804 Cnrs[z].ss[x].oldest = FALSE;
805 cmp = 0;
806 break;
807 }
808 else
809 Cnrs[z].ss[x].all = FALSE;
810 }
811 }
812 if (Cnrs[z].ss[x].unique)
813 Cnrs[z].ss[x].oldest = Cnrs[z].ss[x].newest = Cnrs[z].ss[x].all =
814 Cnrs[z].ss[x].largest = Cnrs[z].ss[x].smallest = FALSE;
815 DosSleep(1);
816 }
817 DosSleep(1);
818 }
819
820 switch (action) {
821 case IDM_SELECTBOTH:
822 for (z = 0; z < numwindows; z++) {
823 for (x = 0; x < Cnrs[z].numfiles; x++) {
824 if (Cnrs[z].ss[x].all)
825 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
826 MPFROMP(Cnrs[z].ss[x].pci),
827 MPFROM2SHORT(TRUE, CRA_SELECTED));
828 }
829 DosSleep(0); // Allow other windows to update
830 }
831 break;
832 case IDM_SELECTMORE:
833 for (z = 0; z < numwindows; z++) {
834 for (x = 0; x < Cnrs[z].numfiles; x++) {
835 if (!Cnrs[z].ss[x].unique)
836 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
837 MPFROMP(Cnrs[z].ss[x].pci),
838 MPFROM2SHORT(TRUE, CRA_SELECTED));
839 }
840 DosSleep(0); // Allow other windows to update
841 }
842 break;
843 case IDM_SELECTONE:
844 for (z = 0; z < numwindows; z++) {
845 for (x = 0; x < Cnrs[z].numfiles; x++) {
846 if (Cnrs[z].ss[x].unique)
847 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
848 MPFROMP(Cnrs[z].ss[x].pci),
849 MPFROM2SHORT(TRUE, CRA_SELECTED));
850 }
851 DosSleep(0); // Allow other windows to update
852 }
853 break;
854 case IDM_SELECTNEWER:
855 for (z = 0; z < numwindows; z++) {
856 for (x = 0; x < Cnrs[z].numfiles; x++) {
857 if (Cnrs[z].ss[x].newest)
858 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
859 MPFROMP(Cnrs[z].ss[x].pci),
860 MPFROM2SHORT(TRUE, CRA_SELECTED));
861 }
862 DosSleep(0); // Allow other windows to update
863 }
864 break;
865 case IDM_SELECTOLDER:
866 for (z = 0; z < numwindows; z++) {
867 for (x = 0; x < Cnrs[z].numfiles; x++) {
868 if (Cnrs[z].ss[x].oldest)
869 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
870 MPFROMP(Cnrs[z].ss[x].pci),
871 MPFROM2SHORT(TRUE, CRA_SELECTED));
872 }
873 DosSleep(0); // Allow other windows to update
874 }
875 break;
876 case IDM_SELECTBIGGER:
877 for (z = 0; z < numwindows; z++) {
878 for (x = 0; x < Cnrs[z].numfiles; x++) {
879 if (Cnrs[z].ss[x].largest)
880 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
881 MPFROMP(Cnrs[z].ss[x].pci),
882 MPFROM2SHORT(TRUE, CRA_SELECTED));
883 }
884 DosSleep(0); // Allow other windows to update
885 }
886 break;
887 case IDM_SELECTSMALLER:
888 for (z = 0; z < numwindows; z++) {
889 for (x = 0; x < Cnrs[z].numfiles; x++) {
890 if (Cnrs[z].ss[x].smallest)
891 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
892 MPFROMP(Cnrs[z].ss[x].pci),
893 MPFROM2SHORT(TRUE, CRA_SELECTED));
894 }
895 DosSleep(0); // Allow other windows to update
896 }
897 break;
898
899 case IDM_DESELECTBOTH:
900 for (z = 0; z < numwindows; z++) {
901 for (x = 0; x < Cnrs[z].numfiles; x++) {
902 if (Cnrs[z].ss[x].all)
903 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
904 MPFROMP(Cnrs[z].ss[x].pci),
905 MPFROM2SHORT(FALSE, CRA_SELECTED));
906 }
907 DosSleep(0); // Allow other windows to update
908 }
909 break;
910 case IDM_DESELECTMORE:
911 for (z = 0; z < numwindows; z++) {
912 for (x = 0; x < Cnrs[z].numfiles; x++) {
913 if (!Cnrs[z].ss[x].unique)
914 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
915 MPFROMP(Cnrs[z].ss[x].pci),
916 MPFROM2SHORT(FALSE, CRA_SELECTED));
917 }
918 DosSleep(0); // Allow other windows to update
919 }
920 break;
921 case IDM_DESELECTONE:
922 for (z = 0; z < numwindows; z++) {
923 for (x = 0; x < Cnrs[z].numfiles; x++) {
924 if (Cnrs[z].ss[x].unique)
925 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
926 MPFROMP(Cnrs[z].ss[x].pci),
927 MPFROM2SHORT(FALSE, CRA_SELECTED));
928 }
929 DosSleep(0); // Allow other windows to update
930 }
931 break;
932 case IDM_DESELECTNEWER:
933 for (z = 0; z < numwindows; z++) {
934 for (x = 0; x < Cnrs[z].numfiles; x++) {
935 if (Cnrs[z].ss[x].newest)
936 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
937 MPFROMP(Cnrs[z].ss[x].pci),
938 MPFROM2SHORT(FALSE, CRA_SELECTED));
939 }
940 DosSleep(0); // Allow other windows to update
941 }
942 break;
943 case IDM_DESELECTOLDER:
944 for (z = 0; z < numwindows; z++) {
945 for (x = 0; x < Cnrs[z].numfiles; x++) {
946 if (Cnrs[z].ss[x].oldest)
947 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
948 MPFROMP(Cnrs[z].ss[x].pci),
949 MPFROM2SHORT(FALSE, CRA_SELECTED));
950 }
951 DosSleep(0); // Allow other windows to update
952 }
953 break;
954 case IDM_DESELECTBIGGER:
955 for (z = 0; z < numwindows; z++) {
956 for (x = 0; x < Cnrs[z].numfiles; x++) {
957 if (Cnrs[z].ss[x].largest)
958 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
959 MPFROMP(Cnrs[z].ss[x].pci),
960 MPFROM2SHORT(FALSE, CRA_SELECTED));
961 }
962 DosSleep(0); // Allow other windows to update
963 }
964 break;
965 case IDM_DESELECTSMALLER:
966 for (z = 0; z < numwindows; z++) {
967 for (x = 0; x < Cnrs[z].numfiles; x++) {
968 if (Cnrs[z].ss[x].smallest)
969 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
970 MPFROMP(Cnrs[z].ss[x].pci),
971 MPFROM2SHORT(FALSE, CRA_SELECTED));
972 }
973 DosSleep(0); // Allow other windows to update
974 }
975 break;
976 }
977
978 FreeCnrs(Cnrs, numwindows);
979}
980
981#pragma alloc_text(SELECT,UnHilite,SelectAll,DeselectAll,MarkAll,SetMask)
982#pragma alloc_text(SELECT,SelectList)
983#pragma alloc_text(SELECT1,Deselect,HideAll,RemoveAll,ExpandAll,InvertAll)
984#pragma alloc_text(SELECT4,FreeCnrs,SpecialSelect2,CompSSNames,CompSSNamesB)
Note: See TracBrowser for help on using the repository browser.