source: trunk/dll/select.c@ 1873

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

Adjustments to ShowTreeRec to eliminate failures and reduce retries and container noise on tree switches. Remove fInitialDriveScan code. Changes to speed up ExpandAll. WaitFleshWorkListEmpty now gives error message and returns if semaphore request fails more than 5 consecutive times.

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