source: trunk/dll/select.c@ 1883

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

Comments for CS [1882]

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