source: trunk/dll/select.c@ 1673

Last change on this file since 1673 was 1673, checked in by Gregg Young, 13 years ago

Update to Doxygen comment style Ticket 55. Also some minor code cleanup.

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