source: trunk/dll/select.c@ 1874

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

DosSleep times in WaitFleshWorkListEmpty set by caller; TOPDIR code calls WaitFleshWorkListEmpty before ShowCnrRecord and now actually exists for directory containers in tree view. These calls are made from the object windows.

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