source: trunk/dll/select.c@ 1890

Last change on this file since 1890 was 1890, checked in by Steven Levine, 6 years ago

Add PMPRINTF enable support to makefiles.
Correct PMPRINTF debug macro enables in sources.

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