source: trunk/dll/select.c@ 1871

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

Create CollapseAll and modify ExpandAll to reduce code overhead both to try and speed drive expansion. Change ExpandAll to allow it to loop in UM_EXPAND until until drive is completely expanded. Changes were need to work with Flesh, Stubby and UnFlesh being moved to a thread. Add code for Flesh to skip the directory entry added by Stubby (eliminate use of NULL/Nullstr pszFileNames by Stubby). Add code in Stubby to insert a complete container item. Add a flag to indicate when a directory needed to be Fleshed. Get expand and switch code to work with Flesh, UnFlesh and Stubby running on a thread. Loop and idle ExpandAll; Move tree expand to a thread; Have ShowTreeRec wait for the Flesh thread. Add a correction factor so directories don't get placed above the top of the tree container when a large drive has been expanded. Debug is mostly still in but all turned off.

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