source: trunk/dll/select.c@ 1838

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

Serialize local hard drive scanning to reduce drive thrashing continue to scan all other drive types in separate threads. Ticket [561] Remove unneed SubbyScan code and improve suppression of blank lines and duplicate subdirectory name caused by running Stubby in worker threads.

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