source: trunk/dll/select.c@ 1604

Last change on this file since 1604 was 1604, checked in by Gregg Young, 14 years ago

Cleanup of INI load code; added error checking to save directory load; improve code format.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: select.c 1604 2011-08-07 17:23:33Z 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 /*(Cnrs[z].ss[x].pci->date.year >
746 bsres->pci->date.year) ? TRUE : (Cnrs[z].ss[x].pci->date.year <
747 bsres->pci->date.
748 year) ? FALSE : (Cnrs[z].
749 ss[x].pci->
750 date.month >
751 bsres->pci->
752 date.
753 month) ? TRUE
754 : (Cnrs[z].ss[x].pci->date.month <
755 bsres->pci->date.month) ? FALSE : (Cnrs[z].ss[x].pci->date.
756 day >
757 bsres->pci->date.
758 day) ? TRUE : (Cnrs[z].
759 ss[x].pci->
760 date.day <
761 bsres->
762 pci->date.
763 day) ?
764 FALSE : (Cnrs[z].ss[x].pci->time.hours >
765 bsres->pci->time.hours) ? TRUE : (Cnrs[z].ss[x].pci->
766 time.hours <
767 bsres->pci->time.
768 hours) ? FALSE
769 : (Cnrs[z].ss[x].pci->time.minutes >
770 bsres->pci->time.minutes) ? TRUE : (Cnrs[z].ss[x].pci->time.
771 minutes <
772 bsres->pci->time.
773 minutes) ? FALSE
774 : (Cnrs[z].ss[x].pci->time.seconds >
775 bsres->pci->time.seconds) ? TRUE : (Cnrs[z].ss[x].pci->time.
776 seconds <
777 bsres->pci->time.
778 seconds) ? FALSE : FALSE;*/
779 if (cmp != 1)
780 Cnrs[z].ss[x].newest = FALSE;
781 /*cmp =
782 (Cnrs[z].ss[x].pci->date.year <
783 bsres->pci->date.year) ? TRUE : (Cnrs[z].ss[x].pci->date.year >
784 bsres->pci->date.
785 year) ? FALSE : (Cnrs[z].
786 ss[x].pci->
787 date.month <
788 bsres->pci->
789 date.
790 month) ? TRUE
791 : (Cnrs[z].ss[x].pci->date.month >
792 bsres->pci->date.month) ? FALSE : (Cnrs[z].ss[x].pci->date.
793 day <
794 bsres->pci->date.
795 day) ? TRUE : (Cnrs[z].
796 ss[x].pci->
797 date.day >
798 bsres->
799 pci->date.
800 day) ?
801 FALSE : (Cnrs[z].ss[x].pci->time.hours <
802 bsres->pci->time.hours) ? TRUE : (Cnrs[z].ss[x].pci->
803 time.hours >
804 bsres->pci->time.
805 hours) ? FALSE
806 : (Cnrs[z].ss[x].pci->time.minutes <
807 bsres->pci->time.minutes) ? TRUE : (Cnrs[z].ss[x].pci->time.
808 minutes >
809 bsres->pci->time.
810 minutes) ? FALSE
811 : (Cnrs[z].ss[x].pci->time.seconds <
812 bsres->pci->time.seconds) ? TRUE : (Cnrs[z].ss[x].pci->time.
813 seconds >
814 bsres->pci->time.
815 seconds) ? FALSE : FALSE;*/
816 if (cmp != -1)
817 Cnrs[z].ss[x].oldest = FALSE;
818 cmp = 0;
819 break;
820 }
821 else
822 Cnrs[z].ss[x].all = FALSE;
823 }
824 }
825 if (Cnrs[z].ss[x].unique)
826 Cnrs[z].ss[x].oldest = Cnrs[z].ss[x].newest = Cnrs[z].ss[x].all =
827 Cnrs[z].ss[x].largest = Cnrs[z].ss[x].smallest = FALSE;
828 DosSleep(1);
829 }
830 DosSleep(1);
831 }
832
833 switch (action) {
834 case IDM_SELECTBOTH:
835 for (z = 0; z < numwindows; z++) {
836 for (x = 0; x < Cnrs[z].numfiles; x++) {
837 if (Cnrs[z].ss[x].all)
838 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
839 MPFROMP(Cnrs[z].ss[x].pci),
840 MPFROM2SHORT(TRUE, CRA_SELECTED));
841 }
842 DosSleep(0); // Allow other windows to update
843 }
844 break;
845 case IDM_SELECTMORE:
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));
852 }
853 DosSleep(0); // Allow other windows to update
854 }
855 break;
856 case IDM_SELECTONE:
857 for (z = 0; z < numwindows; z++) {
858 for (x = 0; x < Cnrs[z].numfiles; x++) {
859 if (Cnrs[z].ss[x].unique)
860 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
861 MPFROMP(Cnrs[z].ss[x].pci),
862 MPFROM2SHORT(TRUE, CRA_SELECTED));
863 }
864 DosSleep(0); // Allow other windows to update
865 }
866 break;
867 case IDM_SELECTNEWER:
868 for (z = 0; z < numwindows; z++) {
869 for (x = 0; x < Cnrs[z].numfiles; x++) {
870 if (Cnrs[z].ss[x].newest)
871 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
872 MPFROMP(Cnrs[z].ss[x].pci),
873 MPFROM2SHORT(TRUE, CRA_SELECTED));
874 }
875 DosSleep(0); // Allow other windows to update
876 }
877 break;
878 case IDM_SELECTOLDER:
879 for (z = 0; z < numwindows; z++) {
880 for (x = 0; x < Cnrs[z].numfiles; x++) {
881 if (Cnrs[z].ss[x].oldest)
882 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
883 MPFROMP(Cnrs[z].ss[x].pci),
884 MPFROM2SHORT(TRUE, CRA_SELECTED));
885 }
886 DosSleep(0); // Allow other windows to update
887 }
888 break;
889 case IDM_SELECTBIGGER:
890 for (z = 0; z < numwindows; z++) {
891 for (x = 0; x < Cnrs[z].numfiles; x++) {
892 if (Cnrs[z].ss[x].largest)
893 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
894 MPFROMP(Cnrs[z].ss[x].pci),
895 MPFROM2SHORT(TRUE, CRA_SELECTED));
896 }
897 DosSleep(0); // Allow other windows to update
898 }
899 break;
900 case IDM_SELECTSMALLER:
901 for (z = 0; z < numwindows; z++) {
902 for (x = 0; x < Cnrs[z].numfiles; x++) {
903 if (Cnrs[z].ss[x].smallest)
904 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
905 MPFROMP(Cnrs[z].ss[x].pci),
906 MPFROM2SHORT(TRUE, CRA_SELECTED));
907 }
908 DosSleep(0); // Allow other windows to update
909 }
910 break;
911
912 case IDM_DESELECTBOTH:
913 for (z = 0; z < numwindows; z++) {
914 for (x = 0; x < Cnrs[z].numfiles; x++) {
915 if (Cnrs[z].ss[x].all)
916 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
917 MPFROMP(Cnrs[z].ss[x].pci),
918 MPFROM2SHORT(FALSE, CRA_SELECTED));
919 }
920 DosSleep(0); // Allow other windows to update
921 }
922 break;
923 case IDM_DESELECTMORE:
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));
930 }
931 DosSleep(0); // Allow other windows to update
932 }
933 break;
934 case IDM_DESELECTONE:
935 for (z = 0; z < numwindows; z++) {
936 for (x = 0; x < Cnrs[z].numfiles; x++) {
937 if (Cnrs[z].ss[x].unique)
938 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
939 MPFROMP(Cnrs[z].ss[x].pci),
940 MPFROM2SHORT(FALSE, CRA_SELECTED));
941 }
942 DosSleep(0); // Allow other windows to update
943 }
944 break;
945 case IDM_DESELECTNEWER:
946 for (z = 0; z < numwindows; z++) {
947 for (x = 0; x < Cnrs[z].numfiles; x++) {
948 if (Cnrs[z].ss[x].newest)
949 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
950 MPFROMP(Cnrs[z].ss[x].pci),
951 MPFROM2SHORT(FALSE, CRA_SELECTED));
952 }
953 DosSleep(0); // Allow other windows to update
954 }
955 break;
956 case IDM_DESELECTOLDER:
957 for (z = 0; z < numwindows; z++) {
958 for (x = 0; x < Cnrs[z].numfiles; x++) {
959 if (Cnrs[z].ss[x].oldest)
960 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
961 MPFROMP(Cnrs[z].ss[x].pci),
962 MPFROM2SHORT(FALSE, CRA_SELECTED));
963 }
964 DosSleep(0); // Allow other windows to update
965 }
966 break;
967 case IDM_DESELECTBIGGER:
968 for (z = 0; z < numwindows; z++) {
969 for (x = 0; x < Cnrs[z].numfiles; x++) {
970 if (Cnrs[z].ss[x].largest)
971 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
972 MPFROMP(Cnrs[z].ss[x].pci),
973 MPFROM2SHORT(FALSE, CRA_SELECTED));
974 }
975 DosSleep(0); // Allow other windows to update
976 }
977 break;
978 case IDM_DESELECTSMALLER:
979 for (z = 0; z < numwindows; z++) {
980 for (x = 0; x < Cnrs[z].numfiles; x++) {
981 if (Cnrs[z].ss[x].smallest)
982 WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
983 MPFROMP(Cnrs[z].ss[x].pci),
984 MPFROM2SHORT(FALSE, CRA_SELECTED));
985 }
986 DosSleep(0); // Allow other windows to update
987 }
988 break;
989 }
990
991 FreeCnrs(Cnrs, numwindows);
992}
993
994#pragma alloc_text(SELECT,UnHilite,SelectAll,DeselectAll,MarkAll,SetMask)
995#pragma alloc_text(SELECT,SelectList)
996#pragma alloc_text(SELECT1,Deselect,HideAll,RemoveAll,ExpandAll,InvertAll)
997#pragma alloc_text(SELECT4,FreeCnrs,SpecialSelect2,CompSSNames,CompSSNamesB)
Note: See TracBrowser for help on using the repository browser.