source: trunk/dll/select.c@ 1874

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

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

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