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
RevLine 
[123]1
2/***********************************************************************
3
4 $Id: select.c 1882 2015-10-12 19:59:34Z 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
[1874]41 27 Sep 15 GKY DosSleep times in WaitFleshWorkListEmpty set by caller
[123]42
43***********************************************************************/
44
[2]45#include <stdlib.h>
46#include <string.h>
47#include <share.h>
[317]48#include <io.h>
[158]49
[907]50#define INCL_DOS
51#define INCL_WIN
52#define INCL_LONGLONG
53
[1180]54#include "fm3dll.h"
[1226]55#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
56#include "select.h"
[1212]57#include "notebook.h" // Data declaration(s)
58#include "newview.h" // Data declarations
[907]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
[1158]64#include "valid.h" // TestCDates
[1180]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
[1039]72#include "fortify.h"
[1871]73#include "flesh.h"
[1882]74#include "treecnr.h" // fExpandAll
[1838]75#if 0
76#define __PMPRINTF__
77#include "PMPRINTF.H"
78#endif
[2]79
[362]80static PSZ pszSrcFile = __FILE__;
81
[672]82VOID UnHilite(HWND hwndCnr, BOOL all, CHAR *** list, ULONG ulItemsToUnHilite)
[317]83{
[2]84 PCNRITEM pci;
[907]85 UINT numfiles = 0, numalloc = 0;
86 UINT x = 0;
[551]87 INT attribute = CRA_CURSORED;
[2]88
[362]89 if (all && list && *list) {
[2]90 FreeList(*list);
91 *list = NULL;
92 }
[551]93 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]94 if (pci && (INT)pci != -1) {
[362]95 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]96 attribute = CRA_SELECTED;
[551]97 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
98 MPFROMSHORT(attribute));
[2]99 }
[748]100 while (pci && (INT)pci != -1) {
[551]101 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
102 MPFROM2SHORT(FALSE, CRA_SELECTED));
[362]103 if (!all)
[690]104 break;
[618]105 // Count is one extra to ensure non-zero elsewhere
[672]106 // x is 0 based index
107 if (x + 2 == ulItemsToUnHilite)
[690]108 break;
[362]109 if (list)
[730]110 AddToList(pci->pszFileName, list, &numfiles, &numalloc);
[551]111 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
112 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
[603]113 x++;
[2]114 }
115 }
116}
117
[551]118VOID SelectList(HWND hwndCnr, BOOL partial, BOOL deselect, BOOL clearfirst,
[748]119 PCNRITEM pciParent, PSZ filename, CHAR ** list)
[362]120{
[2]121
[551]122 PCNRITEM pci;
[2]123 register INT x;
[551]124 BOOL foundone = FALSE;
[766]125 ULONG errs = 0;
[2]126
[362]127 if (clearfirst && !deselect)
[672]128 UnHilite(hwndCnr, TRUE, NULL, 0);
[362]129 if (list && list[0]) {
[551]130 for (x = 0; list[x]; x++) {
[2]131 pci = FindCnrRecord(hwndCnr,
[551]132 list[x], pciParent, partial, partial, TRUE);
[362]133 if (pci) {
[551]134 WinSendMsg(hwndCnr,
135 CM_SETRECORDEMPHASIS,
136 MPFROMP(pci),
137 MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
138 CRA_SELECTED));
139 foundone = TRUE;
[2]140 }
141 }
[362]142 if (!foundone)
143 Runtime_Error(pszSrcFile, __LINE__, "select failed");
[2]144 }
[362]145 else if (filename && *filename) {
[2]146
147 FILE *fp;
[551]148 CHAR input[1024], *p;
[1544]149 CHAR *moder = "r";
[2]150
[1544]151 fp = xfsopen(filename, moder, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
[362]152 if (fp) {
153 while (!feof(fp)) {
[551]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 }
[1565]169 // Input now contains name of file to select
[551]170 pci = FindCnrRecord(hwndCnr,
171 input, pciParent, partial, partial, TRUE);
[1565]172 if (pci) // Found it?
[551]173 WinSendMsg(hwndCnr,
174 CM_SETRECORDEMPHASIS,
175 MPFROMP(pci),
176 MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
177 CRA_SELECTED));
178 else
179 errs++;
[1565]180 if (errs > 50) { // Prevent runaway on bad file
[2]181
[551]182 APIRET ret;
[2]183
[551]184 ret = saymsg(MB_YESNO,
185 hwndCnr,
186 GetPString(IDS_POSSIBLEERRORTEXT),
187 GetPString(IDS_MAYNOTBELISTTEXT), filename);
188 if (ret == MBID_NO)
189 break;
[766]190 errs = 0;
[551]191 }
[2]192 }
193 fclose(fp);
194 }
195 }
196}
197
[748]198VOID SelectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
199 PSZ text, BOOL is_arc)
[362]200{
[2]201
[551]202 PCNRITEM pci;
203 BOOL markit;
[748]204 PSZ file;
205 PSZ pszToMatch;
[551]206 MASK Mask;
[748]207 INT x;
[551]208 ULONG textlen = 0;
[2]209
[362]210 if (text)
[2]211 textlen = strlen(text);
[551]212 memset(&Mask, 0, sizeof(Mask));
[442]213 if (maskstr)
[551]214 SetMask(maskstr, &Mask);
215 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
216 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]217 while (pci && (INT)pci != -1) {
218
[2]219 markit = FALSE;
[748]220
221 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[362]222 if (!is_arc) {
[748]223 if (files && ~pci->attrFile & FILE_DIRECTORY)
[551]224 markit = TRUE;
[748]225 if (dirs && pci->attrFile & FILE_DIRECTORY)
[551]226 markit = TRUE;
[2]227 }
228 else
[551]229 markit = TRUE;
[442]230 if (maskstr && *maskstr && markit) {
[551]231 markit = FALSE;
[748]232 // Point a filename part
[730]233 file = strrchr(pci->pszFileName, '\\');
[551]234 if (!file)
[730]235 file = strrchr(pci->pszFileName, ':');
[551]236 if (file)
237 file++;
238 else
[730]239 file = pci->pszFileName;
[551]240 for (x = 0; Mask.pszMasks[x]; x++) {
241 if (*Mask.pszMasks[x]) {
[748]242 if ((strchr(Mask.pszMasks[x], '\\') ||
243 strchr(Mask.pszMasks[x], ':')))
244 pszToMatch = pci->pszFileName;
245 else
246 pszToMatch = file;
[551]247 if (*Mask.pszMasks[x] != '/') {
[1565]248 if (wildcard(pszToMatch, Mask.pszMasks[x], TRUE)) {
[551]249 markit = TRUE;
[690]250 }
[551]251 }
252 else {
[1413]253 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, TRUE)) {
[551]254 markit = FALSE;
255 break;
256 }
257 }
258 }
[690]259 } // for
[2]260 }
261 }
262
[748]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;
[1565]271 FILE *inputFile;
272 CHAR *moderb = "rb";
[2]273
[1565]274 if ((inputFile = xfsopen(pci->pszFileName, moderb, SH_DENYNO,
275 pszSrcFile, __LINE__, TRUE)) != NULL) {
[748]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
[551]288 break;
[787]289 } // while
[748]290 fclose(inputFile);
[551]291 }
[1039]292 free(input);
[766]293 DosSleep(1);
[551]294 }
[2]295 }
[748]296 else
297 markit = FALSE;
[2]298 }
[748]299
[362]300 if (markit)
[551]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
[2]306}
307
[748]308VOID DeselectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
309 PSZ text, BOOL is_arc)
[362]310{
[551]311 PCNRITEM pci;
312 BOOL unmarkit;
[748]313 PSZ file;
314 PSZ pszToMatch;
[551]315 MASK Mask;
316 register INT x;
317 ULONG textlen = 0;
[2]318
[362]319 if (text)
[2]320 textlen = strlen(text);
[551]321 memset(&Mask, 0, sizeof(Mask));
[442]322 if (maskstr && *maskstr)
[551]323 SetMask(maskstr, &Mask);
324 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
325 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]326 while (pci && (INT)pci != -1) {
[2]327 unmarkit = FALSE;
[748]328 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[362]329 if (!is_arc) {
[748]330 if (files && ~pci->attrFile & FILE_DIRECTORY)
[551]331 unmarkit = TRUE;
332 if (dirs && (pci->attrFile & FILE_DIRECTORY))
333 unmarkit = TRUE;
[2]334 }
335 else
[551]336 unmarkit = TRUE;
[442]337 if (maskstr && *maskstr && unmarkit) {
[551]338 unmarkit = FALSE;
[730]339 file = strrchr(pci->pszFileName, '\\');
[551]340 if (!file)
[730]341 file = strrchr(pci->pszFileName, ':');
[551]342 if (file)
343 file++;
344 else
[730]345 file = pci->pszFileName;
[551]346 for (x = 0; Mask.pszMasks[x]; x++) {
347 if (*Mask.pszMasks[x]) {
[748]348 if (strchr(Mask.pszMasks[x], '\\') ||
349 strchr(Mask.pszMasks[x], ':'))
350 pszToMatch = pci->pszFileName;
351 else
352 pszToMatch = file;
[551]353 if (*Mask.pszMasks[x] != '/') {
[1413]354 if (wildcard(pszToMatch, Mask.pszMasks[x], TRUE))
[551]355 unmarkit = TRUE;
356 }
357 else {
[1413]358 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, TRUE)) {
[551]359 unmarkit = FALSE;
360 break;
361 }
362 }
363 }
364 }
[2]365 }
366 }
367
[748]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;
[1565]377 CHAR *moderb = "rb";
[2]378
[1565]379 if ((inputFile = xfsopen(pci->pszFileName, moderb, SH_DENYNO,
380 pszSrcFile, __LINE__, TRUE)) != NULL) {
[748]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
[551]393 break;
[787]394 } // while
[748]395 fclose(inputFile);
[551]396 }
[1039]397 free(input);
[766]398 DosSleep(1);
[551]399 }
[2]400 }
[748]401 else
402 unmarkit = FALSE;
[2]403 }
[748]404
[362]405 if (unmarkit)
[1604]406 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
[551]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));
[2]411 }
412}
413
[551]414VOID Deselect(HWND hwndCnr)
[317]415{
[2]416 PCNRITEM pcil;
417
[551]418 pcil = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
419 MPFROMLONG(CMA_FIRST),
420 MPFROMSHORT(CRA_SELECTED));
[748]421 while (pcil && (INT)pcil != -1) {
[551]422 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pcil),
423 MPFROM2SHORT(FALSE, CRA_SELECTED));
424 pcil = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pcil),
425 MPFROMSHORT(CRA_SELECTED));
[2]426 }
427}
428
[317]429//=== HideAll() Hide all selected records ===
[2]430
[551]431VOID HideAll(HWND hwndCnr)
[317]432{
[551]433 PCNRITEM pci, pciH;
434 INT attribute = CRA_CURSORED;
435 CNRINFO cnri;
436 BOOL didone = FALSE;
[2]437
[551]438 memset(&cnri, 0, sizeof(CNRINFO));
[2]439 cnri.cb = sizeof(CNRINFO);
[551]440 WinSendMsg(hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
441 MPFROMLONG(sizeof(CNRINFO)));
442 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]443 if (pci && (INT)pci != -1) {
[362]444 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]445 attribute = CRA_SELECTED;
[551]446 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
447 MPFROMSHORT(attribute));
[2]448 }
449 }
[748]450 while (pci && (INT)pci != -1) {
[551]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));
[2]456 pci->rc.flRecordAttr |= CRA_FILTERED;
457 didone = TRUE;
[362]458 if (fSyncUpdates) {
459 if (cnri.flWindowAttr & CV_DETAIL)
[551]460 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
461 MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
[2]462 else
[551]463 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
464 MPFROM2SHORT(1, CMA_REPOSITION | CMA_ERASE));
[2]465 }
466 pci = pciH;
467 }
[362]468 if (didone && !fSyncUpdates)
[551]469 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
470 MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
[2]471}
472
[551]473VOID MarkAll(HWND hwndCnr, BOOL quitit, BOOL target, BOOL source)
[317]474{
[2]475 PCNRITEM pci;
[551]476 INT attribute = CRA_CURSORED;
[2]477
[362]478 if (quitit)
[618]479 attribute = target ? CRA_TARGET : source ? CRA_SOURCE : CRA_INUSE;
[551]480 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
481 MPFROMLONG(CMA_FIRST), MPFROMSHORT(attribute));
[748]482 if (pci && (INT)pci != -1) {
[362]483 if (attribute == CRA_CURSORED) {
484 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[551]485 attribute = CRA_SELECTED;
486 pci =
487 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
488 MPFROMSHORT(attribute));
[2]489 }
490 }
491 }
[748]492 while (pci && (INT)pci != -1) {
[551]493 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
494 MPFROM2SHORT(!quitit,
[618]495 target ? CRA_TARGET : source ? CRA_SOURCE :
496 CRA_INUSE));
[551]497 pci =
498 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
499 MPFROMSHORT(attribute));
[2]500 }
501}
502
[551]503VOID RemoveAll(HWND hwndCnr, ULONGLONG * pullTotalBytes,
504 ULONG * pulTotalFiles)
[317]505{
[2]506 PCNRITEM pci;
[551]507 INT attribute = CRA_CURSORED;
508 BOOL didone = FALSE;
[2]509
[551]510 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]511 if (pci && (INT)pci != -1) {
[362]512 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]513 attribute = CRA_SELECTED;
[551]514 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
515 MPFROMSHORT(attribute));
[2]516 }
517 }
[748]518 while (pci && (INT)pci != -1) {
519 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[2]520 didone = TRUE;
[158]521 if (pulTotalFiles)
[689]522 *pulTotalFiles -= 1;
[158]523 if (pullTotalBytes)
[551]524 *pullTotalBytes -= (pci->cbFile + pci->easize);
525 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
526 MPFROM2SHORT(0, CRA_SELECTED));
[362]527 if (fSyncUpdates)
[751]528 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE | CMA_INVALIDATE);
[2]529 else
[751]530 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE);
[362]531 if (attribute == CRA_CURSORED)
[551]532 break;
533 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
534 MPFROMSHORT(attribute));
[2]535 }
536 else
[551]537 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
538 MPFROMSHORT(attribute));
[2]539 }
[362]540 if (didone && !fSyncUpdates)
[551]541 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
542 MPFROM2SHORT(0, CMA_REPOSITION));
[2]543}
544
[442]545//== SetMask() Convert mask string to array of pointers to masks ==
546
[1565]547VOID SetMask(PSZ maskstr, MASK *mask)
[317]548{
[442]549 UINT x;
550 PSZ p;
[2]551
[1304]552 DosEnterCritSec();
[442]553 if (maskstr)
[551]554 strcpy(mask->szMask, maskstr); // Got new mask string
[442]555 // Build array of pointers
556 p = mask->szMaskCopy;
[551]557 strcpy(p, mask->szMask);
[442]558 // Allow up to 25 masks - ignore extras
559 for (x = 0; *p && x < 25; x++) {
560 mask->pszMasks[x] = p;
[362]561 while (*p && *p != ';')
[442]562 p++; // Find separator
[362]563 if (*p) {
[1565]564 *p = 0; // Replace ; will nul to terminate string
[2]565 p++;
566 }
[551]567 } // for
[442]568 mask->pszMasks[x] = NULL; // Mark end
[1565]569 if (!x)
570 mask->pszMasks[1] = NULL; // Need 1 more for multiple mask detect 2011-05-31 SHL
[1304]571 DosExitCritSec();
[2]572}
573
[1871]574BOOL ExpandAll(HWND hwndCnr, INT count, PCNRITEM pciParent)
[317]575{
[2]576 PCNRITEM pci;
[1873]577 static BOOL fExpanding = FALSE; // statics are only used by tree container
[1871]578 static INT counter = 1;
[2]579
[1871]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 }
[362]590 if (!pciParent)
[551]591 pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
592 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[362]593 if (pciParent) {
[1871]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) {
[551]598 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciParent), MPVOID);
[1871]599 if (count != 0) {
600 fExpanding = TRUE;
[1873]601 if (IsFleshWorkListEmpty())
[1882]602 DosSleep(fExpandAll ? 0 : 10); // Yield to EXPANDTREE and Flesh thread
[1871]603 if (!IsFleshWorkListEmpty()) {
[1882]604 WaitFleshWorkListEmpty(NULL, fExpandAll ? 1 : 50); // Let it expand
[1871]605 }
606 }
607 }
608 while (pci && (INT)pci != -1) {
609 ExpandAll(hwndCnr, count, pci);
[1874]610 if (count != 0 && !IsFleshWorkListEmpty())
[1882]611 WaitFleshWorkListEmpty(NULL, fExpandAll ? 1 : 50); // Wait for container to catch up
[1871]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))
[551]630 WinSendMsg(hwndCnr, CM_COLLAPSETREE, MPFROMP(pciParent), MPVOID);
[1871]631 while (pci && (INT)pci != -1) {
632 CollapseAll(hwndCnr, pci);
[551]633 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
[1871]634 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]635 }
636 }
[787]637 DosSleep(0);
[2]638}
639
[551]640VOID InvertAll(HWND hwndCnr)
[317]641{
[2]642 PCNRITEM pci;
643
[551]644 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
645 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]646 while (pci && (INT)pci != -1) {
647 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
648 if (~pci->rc.flRecordAttr & CRA_SELECTED)
[551]649 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
650 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]651 else
[551]652 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
653 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]654 }
[551]655 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
656 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]657 }
658}
659
[551]660struct SS
661{
662 PCNRITEM pci;
663 BOOL unique, all, smallest, largest, newest, oldest;
[2]664};
665
[551]666struct Cnr
667{
668 HWND hwndCnr;
669 ULONG numfiles;
[2]670 struct SS *ss;
671};
672
[551]673static int CompSSNamesB(const void *s1, const void *s2)
[317]674{
[2]675 struct SS *ss2 = (struct SS *)s2;
676
[1812]677 return stricmp((PSZ)s1, ss2->pci->pszDisplayName);
[2]678}
679
[551]680static int CompSSNames(const void *s1, const void *s2)
[317]681{
[2]682 struct SS *ss1 = (struct SS *)s1;
683 struct SS *ss2 = (struct SS *)s2;
684
[551]685 return stricmp(ss1->pci->pszFileName, ss2->pci->pszFileName);
[2]686}
687
[551]688VOID FreeCnrs(struct Cnr * Cnrs, INT numw)
[317]689{
[2]690 register INT z;
691
[551]692 for (z = 0; z < numw; z++) {
[1009]693 xfree(Cnrs[z].ss, pszSrcFile, __LINE__);
[2]694 }
[1009]695 xfree(Cnrs, pszSrcFile, __LINE__);
[2]696 DosPostEventSem(CompactSem);
697}
698
[762]699/**
700 * Do select actions for single container
701 *
702 */
703
[551]704VOID SpecialSelect2(HWND hwndParent, INT action)
[317]705{
[551]706 PCNRITEM pci;
707 HENUM henum;
708 HWND hwnd;
[897]709 INT numwindows = 0, w, x, z, cmp = 0;
[551]710 struct Cnr *Cnrs = NULL;
711 struct SS *bsres;
[2]712
[362]713 if (!hwndParent)
[2]714 return;
715
[1565]716 // Count directory containers, build array of hwnds
[2]717 henum = WinBeginEnumWindows(hwndParent);
[362]718 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE) {
[551]719 if (WinWindowFromID(WinWindowFromID(hwnd, FID_CLIENT), DIR_CNR)) {
720 Cnrs =
721 xrealloc(Cnrs, (numwindows + 1) * sizeof(struct Cnr), pszSrcFile,
722 __LINE__);
[362]723 if (!Cnrs) {
[551]724 Notify(GetPString(IDS_OUTOFMEMORY));
725 return;
[2]726 }
[551]727 memset(&Cnrs[numwindows], 0, sizeof(struct Cnr));
[2]728 Cnrs[numwindows].hwndCnr = WinWindowFromID(WinWindowFromID(hwnd,
[551]729 FID_CLIENT),
730 DIR_CNR);
[2]731 numwindows++;
732 }
733 }
734 WinEndEnumWindows(henum);
[362]735 if (numwindows < 2) {
[551]736 FreeCnrs(Cnrs, numwindows);
[362]737 Runtime_Error(pszSrcFile, __LINE__, "expected two windows");
[2]738 Notify(GetPString(IDS_COMPSEL2ORMORETEXT));
739 return;
740 }
[362]741 if (numwindows > 4) {
[2]742 WinSendMsg(Cnrs[0].
[551]743 hwndCnr,
744 UM_NOTIFY, MPFROMP(GetPString(IDS_BUILDINGLISTSTEXT)), MPVOID);
[1565]745 DosSleep(0); // Allow other windows to update
[2]746 }
747
[1565]748 // Count records, build array of pointers to records
[551]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));
[2]754 x = 0;
[748]755 while (pci && (INT)pci != -1) {
756 if (~pci->rc.flRecordAttr & CRA_FILTERED &&
757 ~pci->attrFile & FILE_DIRECTORY) {
[551]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++;
[2]769 }
[551]770 pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
771 CM_QUERYRECORD,
772 MPFROMP(pci),
773 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]774 }
[1565]775 DosSleep(0); // Allow other windows to update
[2]776 Cnrs[z].numfiles = x;
[362]777 if (Cnrs[z].numfiles)
[551]778 qsort(Cnrs[z].ss, Cnrs[z].numfiles, sizeof(struct SS), CompSSNames);
[2]779 }
780
[551]781 for (z = 0; z < numwindows; z++) {
782 for (x = 0; x < Cnrs[z].numfiles; x++) {
[2]783 Cnrs[z].ss[x].all = Cnrs[z].ss[x].unique = Cnrs[z].ss[x].newest =
[551]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) {
[1812]788 bsres = (struct SS *)bsearch(Cnrs[z].ss[x].pci->pszDisplayName,
[551]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;
[897]799 cmp = TestCDates(&bsres->pci->date, &bsres->pci->time,
[1565]800 &Cnrs[z].ss[x].pci->date, &Cnrs[z].ss[x].pci->time);
[897]801 if (cmp != 1)
[551]802 Cnrs[z].ss[x].newest = FALSE;
[897]803 if (cmp != -1)
[551]804 Cnrs[z].ss[x].oldest = FALSE;
805 cmp = 0;
806 break;
807 }
808 else
809 Cnrs[z].ss[x].all = FALSE;
810 }
[2]811 }
[362]812 if (Cnrs[z].ss[x].unique)
[551]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;
[748]815 DosSleep(1);
[2]816 }
[766]817 DosSleep(1);
[2]818 }
819
[551]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));
[2]828 }
[1565]829 DosSleep(0); // Allow other windows to update
[551]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));
[2]839 }
[1565]840 DosSleep(0); // Allow other windows to update
[551]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));
[2]850 }
[1565]851 DosSleep(0); // Allow other windows to update
[551]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));
[2]861 }
[1565]862 DosSleep(0); // Allow other windows to update
[551]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));
[2]872 }
[1565]873 DosSleep(0); // Allow other windows to update
[551]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));
[2]883 }
[1565]884 DosSleep(0); // Allow other windows to update
[551]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));
[2]894 }
[1565]895 DosSleep(0); // Allow other windows to update
[551]896 }
897 break;
[2]898
[551]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));
[2]906 }
[1565]907 DosSleep(0); // Allow other windows to update
[551]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));
[2]917 }
[1565]918 DosSleep(0); // Allow other windows to update
[551]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));
[2]928 }
[1565]929 DosSleep(0); // Allow other windows to update
[551]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));
[2]939 }
[1565]940 DosSleep(0); // Allow other windows to update
[551]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));
[2]950 }
[1565]951 DosSleep(0); // Allow other windows to update
[551]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));
[2]961 }
[1565]962 DosSleep(0); // Allow other windows to update
[551]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));
[2]972 }
[1565]973 DosSleep(0); // Allow other windows to update
[551]974 }
975 break;
[2]976 }
977
[551]978 FreeCnrs(Cnrs, numwindows);
[2]979}
[793]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.