source: trunk/dll/select.c @ 748

Last change on this file since 748 was 748, checked in by Steven Levine, 13 years ago

Rework comp.c to to sync with CNRITEM mods
Rework comp.c to remove vast amount of duplicate code
Clean up select.c while auditing for CNRITEM sync
Sync fm3dll.h with comp.c mods

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.2 KB
Line 
1
2/***********************************************************************
3
4  $Id: select.c 748 2007-08-02 05:09:27Z stevenhl $
5
6  Container item selection support routines
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2004, 2007 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  01 Aug 07 SHL Clean up while auditing for CNRITEM sync
23
24***********************************************************************/
25
26#define INCL_DOS
27#define INCL_WIN
28#define INCL_LONGLONG
29#include <os2.h>
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <share.h>
35#include <io.h>
36
37#include "fm3dll.h"
38#include "fm3str.h"
39
40#pragma alloc_text(SELECT,UnHilite,SelectAll,DeselectAll,MarkAll,SetMask)
41#pragma alloc_text(SELECT,SelectList)
42#pragma alloc_text(SELECT1,Deselect,HideAll,RemoveAll,ExpandAll,InvertAll)
43
44static PSZ pszSrcFile = __FILE__;
45
46VOID UnHilite(HWND hwndCnr, BOOL all, CHAR *** list, ULONG ulItemsToUnHilite)
47{
48  PCNRITEM pci;
49  INT numfiles = 0, numalloc = 0, x = 0;
50  INT attribute = CRA_CURSORED;
51
52  if (all && list && *list) {
53    FreeList(*list);
54    *list = NULL;
55  }
56  pci = (PCNRITEM) CurrentRecord(hwndCnr);
57  if (pci && (INT)pci != -1) {
58    if (pci->rc.flRecordAttr & CRA_SELECTED) {
59      attribute = CRA_SELECTED;
60      pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
61                       MPFROMSHORT(attribute));
62    }
63    while (pci && (INT)pci != -1) {
64      WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
65                 MPFROM2SHORT(FALSE, CRA_SELECTED));
66      if (!all)
67          break;
68      // Count is one extra to ensure non-zero elsewhere
69      // x is 0 based index
70      if (x + 2 == ulItemsToUnHilite)
71        break;
72      if (list)
73        AddToList(pci->pszFileName, list, &numfiles, &numalloc);
74      pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
75                                  MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
76      x++;
77    }
78  }
79}
80
81VOID SelectList(HWND hwndCnr, BOOL partial, BOOL deselect, BOOL clearfirst,
82                PCNRITEM pciParent, PSZ filename, CHAR ** list)
83{
84
85  PCNRITEM pci;
86  register INT x;
87  BOOL foundone = FALSE;
88  ULONG errs = 0L;
89
90  if (clearfirst && !deselect)
91    UnHilite(hwndCnr, TRUE, NULL, 0);
92  if (list && list[0]) {
93    for (x = 0; list[x]; x++) {
94      pci = FindCnrRecord(hwndCnr,
95                          list[x], pciParent, partial, partial, TRUE);
96      if (pci) {
97        WinSendMsg(hwndCnr,
98                   CM_SETRECORDEMPHASIS,
99                   MPFROMP(pci),
100                   MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
101                                CRA_SELECTED));
102        foundone = TRUE;
103      }
104    }
105    if (!foundone)
106      Runtime_Error(pszSrcFile, __LINE__, "select failed");
107  }
108  else if (filename && *filename) {
109
110    FILE *fp;
111    CHAR input[1024], *p;
112
113    fp = _fsopen(filename, "r", SH_DENYNO);
114    if (fp) {
115      while (!feof(fp)) {
116        if (!xfgets_bstripcr(input, sizeof(input), fp, pszSrcFile, __LINE__))
117          break;
118        if (*input == '\"') {
119          memmove(input, input + 1, strlen(input) + 1);
120          lstrip(input);
121          p = strchr(input, '\"');
122          if (p)
123            *p = 0;
124          rstrip(input);
125        }
126        else {
127          p = strchr(input, ' ');
128          if (p)
129            *p = 0;
130        }
131        /* input now contains name of file to select */
132        pci = FindCnrRecord(hwndCnr,
133                            input, pciParent, partial, partial, TRUE);
134        if (pci)                        /* found it? */
135          WinSendMsg(hwndCnr,
136                     CM_SETRECORDEMPHASIS,
137                     MPFROMP(pci),
138                     MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
139                                  CRA_SELECTED));
140        else
141          errs++;
142        if (errs > 50L) {               /* prevent runaway on bad file */
143
144          APIRET ret;
145
146          ret = saymsg(MB_YESNO,
147                       hwndCnr,
148                       GetPString(IDS_POSSIBLEERRORTEXT),
149                       GetPString(IDS_MAYNOTBELISTTEXT), filename);
150          if (ret == MBID_NO)
151            break;
152          errs = 0L;
153        }
154      }
155      fclose(fp);
156    }
157  }
158}
159
160VOID SelectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
161               PSZ text, BOOL is_arc)
162{
163
164  PCNRITEM pci;
165  BOOL markit;
166  PSZ file;
167  PSZ pszToMatch;
168  MASK Mask;
169  INT x;
170  ULONG textlen = 0;
171
172  if (text)
173    textlen = strlen(text);
174  memset(&Mask, 0, sizeof(Mask));
175  if (maskstr)
176    SetMask(maskstr, &Mask);
177  pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
178                              MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
179  while (pci && (INT)pci != -1) {
180
181    markit = FALSE;
182
183    if (~pci->rc.flRecordAttr & CRA_FILTERED) {
184      if (!is_arc) {
185        if (files && ~pci->attrFile & FILE_DIRECTORY)
186          markit = TRUE;
187        if (dirs && pci->attrFile & FILE_DIRECTORY)
188          markit = TRUE;
189      }
190      else
191        markit = TRUE;
192      if (maskstr && *maskstr && markit) {
193        markit = FALSE;
194        // Point a filename part
195        file = strrchr(pci->pszFileName, '\\');
196        if (!file)
197          file = strrchr(pci->pszFileName, ':');
198        if (file)
199          file++;
200        else
201          file = pci->pszFileName;
202        for (x = 0; Mask.pszMasks[x]; x++) {
203          if (*Mask.pszMasks[x]) {
204            if ((strchr(Mask.pszMasks[x], '\\') ||
205                strchr(Mask.pszMasks[x], ':')))
206              pszToMatch = pci->pszFileName;
207            else
208              pszToMatch = file;
209            if (*Mask.pszMasks[x] != '/') {
210              if (wildcard(pszToMatch, Mask.pszMasks[x], FALSE)) {
211                markit = TRUE;
212              }
213            }
214            else {
215              if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, FALSE)) {
216                markit = FALSE;
217                break;
218              }
219            }
220          }
221        } // for
222      }
223    }
224
225    if (markit && text && *text) {
226      if (~pci->attrFile & FILE_DIRECTORY) {
227        PSZ input;
228        markit = FALSE;
229        input = xmalloc(65537, pszSrcFile, __LINE__);
230        if (input) {
231          ULONG pos;
232          LONG len;
233          FILE *inputFile;
234
235          if ((inputFile = _fsopen(pci->pszFileName, "rb", SH_DENYNO)) != NULL) {
236            pos = ftell(inputFile);
237            while (!feof(inputFile)) {
238              if (pos)
239                fseek(inputFile, pos - 256, SEEK_SET);
240              len = fread(input, 1, 65536, inputFile);
241              if (len >= 0) {
242                if (findstring(text, textlen, input, len, FALSE)) {
243                  markit = TRUE;
244                  break;
245                }
246              }
247              else
248                break;
249            }
250            fclose(inputFile);
251          }
252          free(input);
253          DosSleep(1L);
254        }
255      }
256      else
257        markit = FALSE;
258    }
259
260    if (markit)
261      WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
262                 MPFROM2SHORT(TRUE, CRA_SELECTED));
263    pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
264                                MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
265  }                                     // while
266}
267
268VOID DeselectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
269                 PSZ text, BOOL is_arc)
270{
271  PCNRITEM pci;
272  BOOL unmarkit;
273  PSZ file;
274  PSZ pszToMatch;
275  MASK Mask;
276  register INT x;
277  ULONG textlen = 0;
278
279  if (text)
280    textlen = strlen(text);
281  memset(&Mask, 0, sizeof(Mask));
282  if (maskstr && *maskstr)
283    SetMask(maskstr, &Mask);
284  pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
285                              MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
286  while (pci && (INT)pci != -1) {
287    unmarkit = FALSE;
288    if (~pci->rc.flRecordAttr & CRA_FILTERED) {
289      if (!is_arc) {
290        if (files && ~pci->attrFile & FILE_DIRECTORY)
291          unmarkit = TRUE;
292        if (dirs && (pci->attrFile & FILE_DIRECTORY))
293          unmarkit = TRUE;
294      }
295      else
296        unmarkit = TRUE;
297      if (maskstr && *maskstr && unmarkit) {
298        unmarkit = FALSE;
299        file = strrchr(pci->pszFileName, '\\');
300        if (!file)
301          file = strrchr(pci->pszFileName, ':');
302        if (file)
303          file++;
304        else
305          file = pci->pszFileName;
306        for (x = 0; Mask.pszMasks[x]; x++) {
307          if (*Mask.pszMasks[x]) {
308            if (strchr(Mask.pszMasks[x], '\\') ||
309                strchr(Mask.pszMasks[x], ':'))
310              pszToMatch = pci->pszFileName;
311            else
312              pszToMatch = file;
313            if (*Mask.pszMasks[x] != '/') {
314              if (wildcard(pszToMatch, Mask.pszMasks[x], FALSE))
315                unmarkit = TRUE;
316            }
317            else {
318              if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, FALSE)) {
319                unmarkit = FALSE;
320                break;
321              }
322            }
323          }
324        }
325      }
326    }
327
328    if (unmarkit && text && *text) {
329      if (~pci->attrFile & FILE_DIRECTORY) {
330        PSZ input;
331        unmarkit = FALSE;
332        input = xmalloc(65537, pszSrcFile, __LINE__);
333        if (input) {
334          ULONG pos;
335          LONG len;
336          FILE *inputFile;
337
338          if ((inputFile = _fsopen(pci->pszFileName, "rb", SH_DENYNO)) != NULL) {
339            pos = ftell(inputFile);
340            while (!feof(inputFile)) {
341              if (pos)
342                fseek(inputFile, pos - 256, SEEK_SET);
343              len = fread(input, 1, 65536, inputFile);
344              if (len >= 0) {
345                if (findstring(text, textlen, input, len, FALSE)) {
346                  unmarkit = TRUE;
347                  break;
348                }
349              }
350              else
351                break;
352            }
353            fclose(inputFile);
354          }
355          free(input);
356          DosSleep(1L);
357        }
358      }
359      else
360        unmarkit = FALSE;
361    }
362
363    if (unmarkit)
364      WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, pci,
365                 MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED |
366                              CRA_INUSE | CRA_SOURCE));
367    pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
368                                MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
369  }
370}
371
372VOID Deselect(HWND hwndCnr)
373{
374  PCNRITEM pcil;
375
376  pcil = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
377                               MPFROMLONG(CMA_FIRST),
378                               MPFROMSHORT(CRA_SELECTED));
379  while (pcil && (INT)pcil != -1) {
380    WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pcil),
381               MPFROM2SHORT(FALSE, CRA_SELECTED));
382    pcil = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pcil),
383                      MPFROMSHORT(CRA_SELECTED));
384  }
385}
386
387//=== HideAll() Hide all selected records ===
388
389VOID HideAll(HWND hwndCnr)
390{
391  PCNRITEM pci, pciH;
392  INT attribute = CRA_CURSORED;
393  CNRINFO cnri;
394  BOOL didone = FALSE;
395
396  memset(&cnri, 0, sizeof(CNRINFO));
397  cnri.cb = sizeof(CNRINFO);
398  WinSendMsg(hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
399             MPFROMLONG(sizeof(CNRINFO)));
400  pci = (PCNRITEM) CurrentRecord(hwndCnr);
401  if (pci && (INT)pci != -1) {
402    if (pci->rc.flRecordAttr & CRA_SELECTED) {
403      attribute = CRA_SELECTED;
404      pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
405                       MPFROMSHORT(attribute));
406    }
407  }
408  while (pci && (INT)pci != -1) {
409    pciH = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
410                      MPFROMSHORT(attribute));
411    WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
412               MPFROM2SHORT(FALSE, CRA_CURSORED | CRA_SELECTED |
413                            CRA_INUSE | CRA_SOURCE));
414    pci->rc.flRecordAttr |= CRA_FILTERED;
415    didone = TRUE;
416    if (fSyncUpdates) {
417      if (cnri.flWindowAttr & CV_DETAIL)
418        WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
419                   MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
420      else
421        WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
422                   MPFROM2SHORT(1, CMA_REPOSITION | CMA_ERASE));
423    }
424    pci = pciH;
425  }
426  if (didone && !fSyncUpdates)
427    WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
428               MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
429}
430
431VOID MarkAll(HWND hwndCnr, BOOL quitit, BOOL target, BOOL source)
432{
433  PCNRITEM pci;
434  INT attribute = CRA_CURSORED;
435
436  if (quitit)
437    attribute = target ? CRA_TARGET : source ? CRA_SOURCE : CRA_INUSE;
438  pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
439                              MPFROMLONG(CMA_FIRST), MPFROMSHORT(attribute));
440  if (pci && (INT)pci != -1) {
441    if (attribute == CRA_CURSORED) {
442      if (pci->rc.flRecordAttr & CRA_SELECTED) {
443        attribute = CRA_SELECTED;
444        pci =
445          WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
446                     MPFROMSHORT(attribute));
447      }
448    }
449  }
450  while (pci && (INT)pci != -1) {
451    WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
452               MPFROM2SHORT(!quitit,
453                            target ? CRA_TARGET : source ? CRA_SOURCE :
454                             CRA_INUSE));
455    pci =
456      WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
457                 MPFROMSHORT(attribute));
458  }
459}
460
461VOID RemoveAll(HWND hwndCnr, ULONGLONG * pullTotalBytes,
462               ULONG * pulTotalFiles)
463{
464  PCNRITEM pci;
465  INT attribute = CRA_CURSORED;
466  BOOL didone = FALSE;
467
468  pci = (PCNRITEM) CurrentRecord(hwndCnr);
469  if (pci && (INT)pci != -1) {
470    if (pci->rc.flRecordAttr & CRA_SELECTED) {
471      attribute = CRA_SELECTED;
472      pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
473                       MPFROMSHORT(attribute));
474    }
475  }
476  while (pci && (INT)pci != -1) {
477    if (~pci->rc.flRecordAttr & CRA_FILTERED) {
478      didone = TRUE;
479      if (pulTotalFiles)
480        *pulTotalFiles -= 1;
481      if (pullTotalBytes)
482        *pullTotalBytes -= (pci->cbFile + pci->easize);
483      WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
484                 MPFROM2SHORT(0, CRA_SELECTED));
485      if (fSyncUpdates)
486        WinSendMsg(hwndCnr, CM_REMOVERECORD, MPFROMP(&pci),
487                   MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
488      else
489        WinSendMsg(hwndCnr, CM_REMOVERECORD, MPFROMP(&pci),
490                   MPFROM2SHORT(1, CMA_FREE));
491      if (attribute == CRA_CURSORED)
492        break;
493      pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
494                       MPFROMSHORT(attribute));
495    }
496    else
497      pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
498                       MPFROMSHORT(attribute));
499  }
500  if (didone && !fSyncUpdates)
501    WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
502               MPFROM2SHORT(0, CMA_REPOSITION));
503}
504
505//== SetMask() Convert mask string to array of pointers to masks ==
506
507VOID SetMask(PSZ maskstr, MASK * mask)
508{
509  UINT x;
510  PSZ p;
511
512  if (maskstr)
513    strcpy(mask->szMask, maskstr);      // Got new mask string
514  // Build array of pointers
515  p = mask->szMaskCopy;
516  strcpy(p, mask->szMask);
517  // Allow up to 25 masks - ignore extras
518  for (x = 0; *p && x < 25; x++) {
519    mask->pszMasks[x] = p;
520    while (*p && *p != ';')
521      p++;                              // Find separator
522    if (*p) {
523      *p = 0;                           // Replace ;
524      p++;
525    }
526  }                                     // for
527  mask->pszMasks[x] = NULL;             // Mark end
528}
529
530VOID ExpandAll(HWND hwndCnr, BOOL expand, PCNRITEM pciParent)
531{
532  PCNRITEM pci;
533
534  if (!pciParent)
535    pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
536                           MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
537  if (pciParent) {
538    if (expand && ~pciParent->rc.flRecordAttr & CRA_EXPANDED)
539      WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciParent), MPVOID);
540    else if (!expand && (pciParent->rc.flRecordAttr & CRA_EXPANDED))
541      WinSendMsg(hwndCnr, CM_COLLAPSETREE, MPFROMP(pciParent), MPVOID);
542    pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
543                                MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
544    if (pci)
545      DosSleep(1L);
546    while (pci && (INT)pci != -1) {
547      ExpandAll(hwndCnr, expand, pci);
548      pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
549                                  MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
550    }
551  }
552  DosSleep(1);
553}
554
555VOID InvertAll(HWND hwndCnr)
556{
557  PCNRITEM pci;
558
559  pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
560                              MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
561  while (pci && (INT)pci != -1) {
562    if (~pci->rc.flRecordAttr & CRA_FILTERED) {
563      if (~pci->rc.flRecordAttr & CRA_SELECTED)
564        WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
565                   MPFROM2SHORT(TRUE, CRA_SELECTED));
566      else
567        WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
568                   MPFROM2SHORT(FALSE, CRA_SELECTED));
569    }
570    pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
571                                MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
572  }
573}
574
575#pragma alloc_text (SELECT3,SpecialSelect)
576#pragma alloc_text(SELECT4,FreeCnrs,SpecialSelect2,CompSSNames,CompSSNamesB)
577
578VOID SpecialSelect(HWND hwndCnrS, HWND hwndCnrD, INT action, BOOL reset)
579{
580  PCNRITEM pciS, pciD, *pciSa = NULL, *pciDa = NULL;
581  CNRINFO cnri;
582  BOOL slow = FALSE;
583  register INT x, numD, numS;
584
585
586  if (!hwndCnrS || !hwndCnrD)
587    return;
588
589  memset(&cnri, 0, sizeof(CNRINFO));
590  cnri.cb = sizeof(CNRINFO);
591  WinSendMsg(hwndCnrD, CM_QUERYCNRINFO, MPFROMP(&cnri),
592             MPFROMLONG(sizeof(CNRINFO)));
593  numD = (INT) cnri.cRecords;
594  memset(&cnri, 0, sizeof(CNRINFO));
595  cnri.cb = sizeof(CNRINFO);
596  WinSendMsg(hwndCnrS, CM_QUERYCNRINFO, MPFROMP(&cnri),
597             MPFROMLONG(sizeof(CNRINFO)));
598  numS = (INT) cnri.cRecords;
599  if (!numD || numS != numD) {
600    saymsg(MB_ENTER,
601           HWND_DESKTOP,
602           DEBUG_STRING, "numD (%lu) != numS (%lu)", numD, numS);
603    return;
604  }
605  pciDa = xmalloc(sizeof(PCNRITEM) * numD, pszSrcFile, __LINE__);
606  if (!pciDa)
607    return;
608
609  pciSa = xmalloc(sizeof(PCNRITEM) * numS, pszSrcFile, __LINE__);
610  if (!pciSa) {
611    free(pciDa);
612    return;
613  }
614
615Restart:
616
617  memset(pciDa, 0, sizeof(PCNRITEM) * numD);
618  memset(pciSa, 0, sizeof(PCNRITEM) * numS);
619
620  pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
621                               MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
622  x = 0;
623  while (pciD && (INT)pciD != -1 && x < numD) {
624    if (reset)
625      pciD->flags = 0;
626    pciDa[x] = pciD;
627    x++;
628    if (!slow)
629      pciD = (PCNRITEM) pciD->rc.preccNextRecord;
630    else
631      pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
632                                   MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
633    if (!(x % 500))
634      DosSleep(1L);
635    else if (!(x % 50))
636      DosSleep(1);
637  }
638  if (numD != x) {
639    if (!slow) {
640      slow = TRUE;
641      goto Restart;
642    }
643    free(pciDa);
644    free(pciSa);
645    saymsg(MB_ENTER,
646           HWND_DESKTOP, DEBUG_STRING, "numD (%lu) != x (%lu)", numD, x);
647    return;
648  }
649
650  pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
651                               MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
652  x = 0;
653  while (pciS && (INT)pciS != -1 && x < numS) {
654    if (reset)
655      pciS->flags = 0;
656    pciSa[x] = pciS;
657    x++;
658    if (!slow)
659      pciS = (PCNRITEM) pciS->rc.preccNextRecord;
660    else
661      pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
662                                   MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
663    if (!(x % 500))
664      DosSleep(1L);
665    else if (!(x % 50))
666      DosSleep(1);
667  }
668  if (numS != x) {
669    if (!slow) {
670      slow = TRUE;
671      goto Restart;
672    }
673    free(pciSa);
674    free(pciDa);
675    Runtime_Error(pszSrcFile, __LINE__, "numS (%lu) != x (%lu)", numS, x);
676    return;
677  }
678
679  if (reset) {
680    for (x = 0; x < numS; x++) {
681
682      if (!*pciSa[x]->pszFileName || !*pciDa[x]->pszFileName)
683        continue;
684
685      pciSa[x]->flags |= CNRITEM_EXISTS;
686      pciDa[x]->flags |= CNRITEM_EXISTS;
687      if (pciSa[x]->cbFile + pciSa[x]->easize >
688          pciDa[x]->cbFile + pciDa[x]->easize) {
689        pciSa[x]->flags |= CNRITEM_LARGER;
690        pciDa[x]->flags |= CNRITEM_SMALLER;
691      }
692      else if (pciSa[x]->cbFile + pciSa[x]->easize <
693               pciDa[x]->cbFile + pciDa[x]->easize) {
694        pciSa[x]->flags |= CNRITEM_SMALLER;
695        pciDa[x]->flags |= CNRITEM_LARGER;
696      }
697      if ((pciSa[x]->date.year > pciDa[x]->date.year) ? TRUE :
698          (pciSa[x]->date.year < pciDa[x]->date.year) ? FALSE :
699          (pciSa[x]->date.month > pciDa[x]->date.month) ? TRUE :
700          (pciSa[x]->date.month < pciDa[x]->date.month) ? FALSE :
701          (pciSa[x]->date.day > pciDa[x]->date.day) ? TRUE :
702          (pciSa[x]->date.day < pciDa[x]->date.day) ? FALSE :
703          (pciSa[x]->time.hours > pciDa[x]->time.hours) ? TRUE :
704          (pciSa[x]->time.hours < pciDa[x]->time.hours) ? FALSE :
705          (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? TRUE :
706          (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? FALSE :
707          (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? TRUE :
708          (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? FALSE : FALSE) {
709        pciSa[x]->flags |= CNRITEM_NEWER;
710        pciDa[x]->flags |= CNRITEM_OLDER;
711      }
712      else if ((pciSa[x]->date.year < pciDa[x]->date.year) ? TRUE :
713               (pciSa[x]->date.year > pciDa[x]->date.year) ? FALSE :
714               (pciSa[x]->date.month < pciDa[x]->date.month) ? TRUE :
715               (pciSa[x]->date.month > pciDa[x]->date.month) ? FALSE :
716               (pciSa[x]->date.day < pciDa[x]->date.day) ? TRUE :
717               (pciSa[x]->date.day > pciDa[x]->date.day) ? FALSE :
718               (pciSa[x]->time.hours < pciDa[x]->time.hours) ? TRUE :
719               (pciSa[x]->time.hours > pciDa[x]->time.hours) ? FALSE :
720               (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? TRUE :
721               (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? FALSE :
722               (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? TRUE :
723               (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? FALSE :
724               FALSE) {
725        pciSa[x]->flags |= CNRITEM_OLDER;
726        pciDa[x]->flags |= CNRITEM_NEWER;
727      }
728      if (!(x % 500))
729        DosSleep(1L);
730      else if (!(x % 50))
731        DosSleep(1);
732    }
733  }
734
735  switch (action) {
736  case IDM_SELECTIDENTICAL:
737    for (x = 0; x < numS; x++) {
738      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
739        if (*pciSa[x]->pszFileName &&
740            pciSa[x]->flags & CNRITEM_EXISTS &&
741            ~pciSa[x]->flags & CNRITEM_SMALLER &&
742            ~pciSa[x]->flags & CNRITEM_LARGER &&
743            ~pciSa[x]->flags & CNRITEM_NEWER &&
744            ~pciSa[x]->flags & CNRITEM_OLDER) {
745          if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
746            WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
747                       MPFROM2SHORT(TRUE, CRA_SELECTED));
748          if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
749            WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
750                       MPFROM2SHORT(TRUE, CRA_SELECTED));
751        }
752        if (!(x % 500))
753          DosSleep(1L);
754        else if (!(x % 50))
755          DosSleep(1);
756      }
757    }
758    break;
759
760  case IDM_SELECTSAME:
761    for (x = 0; x < numS; x++) {
762      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
763          *pciSa[x]->pszFileName &&
764          pciSa[x]->flags & CNRITEM_EXISTS &&
765          ~pciSa[x]->flags & CNRITEM_SMALLER &&
766          ~pciSa[x]->flags & CNRITEM_LARGER) {
767        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
768          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
769                     MPFROM2SHORT(TRUE, CRA_SELECTED));
770        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
771          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
772                     MPFROM2SHORT(TRUE, CRA_SELECTED));
773      }
774      if (!(x % 500))
775        DosSleep(1L);
776      else if (!(x % 50))
777        DosSleep(1);
778    }
779    break;
780
781  case IDM_SELECTSAMECONTENT:
782    // fixme why?
783    for (x = 0; x < numS; x++) {
784      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
785          *pciSa[x]->pszFileName &&
786          *pciDa[x]->pszFileName &&
787          pciSa[x]->flags & CNRITEM_EXISTS &&
788          pciDa[x]->flags & CNRITEM_EXISTS)
789      {
790        FILE *fp1 = NULL;
791        FILE *fp2 = NULL;
792        BOOL gotMatch = FALSE;
793        UINT errLineNo = 0;
794        UINT compErrno = 0;
795        CHAR buf1[1024];
796        CHAR buf2[1024];
797        HAB hab = WinQueryAnchorBlock(hwndCnrS);
798
799        fp1 = _fsopen(pciSa[x]->pszFileName, "rb", SH_DENYNO);
800        if (!fp1) {
801          errLineNo = __LINE__;
802          compErrno = errno;
803        }
804        else {
805          fp2 = _fsopen(pciDa[x]->pszFileName, "rb", SH_DENYNO);
806          if (!fp2) {
807            errLineNo = __LINE__;
808            compErrno = errno;
809          }
810          else {
811            size_t len1 = filelength(fileno(fp1));
812            size_t len2 = filelength(fileno(fp2));
813
814            if (len1 == len2) {
815              setbuf(fp1, NULL);
816              setbuf(fp2, NULL);
817              while (WinIsWindow(hab, hwndCnrS)) {
818                size_t numread1 = fread(buf1, 1, 1024, fp1);
819                size_t numread2 = fread(buf2, 1, 1024, fp2);
820
821                if (!numread1 || !numread2 || numread1 != numread2) {
822                  if (ferror(fp1) || ferror(fp2)) {
823                    errLineNo = __LINE__;
824                    compErrno = errno;
825                  }
826                  else if (feof(fp1) && feof(fp2))
827                    gotMatch = TRUE;
828                  break;
829                }
830                else if (memcmp(buf1, buf2, numread1))
831                  break;
832              } // while
833            } // same len
834          }
835        }
836
837        if (fp1)
838          fclose(fp1);
839
840        if (fp2)
841          fclose(fp2);
842
843        if (errLineNo) {
844          Runtime_Error(pszSrcFile, errLineNo,
845                        "error %d while comparing", compErrno);
846        }
847        if (gotMatch) {
848          if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
849            WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
850                       MPFROM2SHORT(TRUE, CRA_SELECTED));
851          if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
852            WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
853                       MPFROM2SHORT(TRUE, CRA_SELECTED));
854        }
855      }
856      if (!(x % 500))
857        DosSleep(1L);
858      else if (!(x % 50))
859        DosSleep(1);
860    }                                   // for records
861    break;
862
863  case IDM_SELECTBOTH:
864    for (x = 0; x < numS; x++) {
865      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
866          *pciSa[x]->pszFileName &&
867          pciSa[x]->flags & CNRITEM_EXISTS) {
868        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
869          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
870                     MPFROM2SHORT(TRUE, CRA_SELECTED));
871        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
872          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
873                     MPFROM2SHORT(TRUE, CRA_SELECTED));
874      }
875      if (!(x % 500))
876        DosSleep(1L);
877      else if (!(x % 50))
878        DosSleep(1);
879    }
880    break;
881
882  case IDM_SELECTONE:
883    for (x = 0; x < numS; x++) {
884      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
885          *pciSa[x]->pszFileName &&
886          ~pciSa[x]->flags & CNRITEM_EXISTS)
887      {
888        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
889          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
890                     MPFROM2SHORT(TRUE, CRA_SELECTED));
891      }
892      else if (*pciDa[x]->pszFileName &&
893               ~pciDa[x]->flags & CNRITEM_EXISTS) {
894        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
895          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
896                     MPFROM2SHORT(TRUE, CRA_SELECTED));
897      }
898      if (!(x % 500))
899        DosSleep(1L);
900      else if (!(x % 50))
901        DosSleep(1);
902    }
903    break;
904
905  case IDM_SELECTBIGGER:
906    for (x = 0; x < numS; x++) {
907      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
908          pciSa[x]->flags & CNRITEM_LARGER) {
909        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
910          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
911                     MPFROM2SHORT(TRUE, CRA_SELECTED));
912      }
913      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
914               *pciDa[x]->pszFileName &&
915               pciDa[x]->flags & CNRITEM_LARGER) {
916        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
917          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
918                     MPFROM2SHORT(TRUE, CRA_SELECTED));
919      }
920      if (!(x % 500))
921        DosSleep(1L);
922      else if (!(x % 50))
923        DosSleep(1);
924    }
925    break;
926
927  case IDM_SELECTSMALLER:
928    for (x = 0; x < numS; x++) {
929      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
930          *pciSa[x]->pszFileName &&
931          pciSa[x]->flags & CNRITEM_SMALLER) {
932        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
933          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
934                     MPFROM2SHORT(TRUE, CRA_SELECTED));
935      }
936      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
937               *pciDa[x]->pszFileName &&
938               pciDa[x]->flags & CNRITEM_SMALLER) {
939        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
940          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
941                     MPFROM2SHORT(TRUE, CRA_SELECTED));
942      }
943      if (!(x % 500))
944        DosSleep(1L);
945      else if (!(x % 50))
946        DosSleep(1);
947    }
948    break;
949
950  case IDM_SELECTNEWER:
951    for (x = 0; x < numS; x++) {
952      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
953          *pciSa[x]->pszFileName &&
954          pciSa[x]->flags & CNRITEM_NEWER) {
955        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
956          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
957                     MPFROM2SHORT(TRUE, CRA_SELECTED));
958      }
959      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
960               *pciDa[x]->pszFileName &&
961               pciDa[x]->flags & CNRITEM_NEWER) {
962        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
963          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
964                     MPFROM2SHORT(TRUE, CRA_SELECTED));
965      }
966      if (!(x % 500))
967        DosSleep(1L);
968      else if (!(x % 50))
969        DosSleep(1);
970    }
971    break;
972
973  case IDM_SELECTOLDER:
974    for (x = 0; x < numS; x++) {
975      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
976          *pciSa[x]->pszFileName &&
977          pciSa[x]->flags & CNRITEM_OLDER) {
978        if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
979          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
980                     MPFROM2SHORT(TRUE, CRA_SELECTED));
981      }
982      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
983               *pciDa[x]->pszFileName &&
984               pciDa[x]->flags & CNRITEM_OLDER) {
985        if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
986          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
987                     MPFROM2SHORT(TRUE, CRA_SELECTED));
988      }
989      if (!(x % 500))
990        DosSleep(1L);
991      else if (!(x % 50))
992        DosSleep(1);
993    }
994    break;
995
996  case IDM_DESELECTBOTH:
997    for (x = 0; x < numS; x++) {
998      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
999          *pciSa[x]->pszFileName &&
1000          pciSa[x]->flags & CNRITEM_EXISTS) {
1001        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1002          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1003                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1004        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1005          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1006                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1007      }
1008      if (!(x % 500))
1009        DosSleep(1L);
1010      else if (!(x % 50))
1011        DosSleep(1);
1012    }
1013    break;
1014
1015  case IDM_DESELECTONE:
1016    for (x = 0; x < numS; x++) {
1017      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1018          *pciSa[x]->pszFileName &&
1019          ~pciSa[x]->flags & CNRITEM_EXISTS) {
1020        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1021          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1022                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1023      }
1024      else if (*pciDa[x]->pszFileName &&
1025               ~pciDa[x]->flags & CNRITEM_EXISTS) {
1026        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1027          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1028                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1029      }
1030      if (!(x % 500))
1031        DosSleep(1L);
1032      else if (!(x % 50))
1033        DosSleep(1);
1034    }
1035    break;
1036
1037  case IDM_DESELECTBIGGER:
1038    for (x = 0; x < numS; x++) {
1039      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1040          *pciSa[x]->pszFileName &&
1041          pciSa[x]->flags & CNRITEM_LARGER) {
1042        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1043          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1044                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1045      }
1046      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1047               *pciDa[x]->pszFileName &&
1048               pciDa[x]->flags & CNRITEM_LARGER) {
1049        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1050          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1051                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1052      }
1053      if (!(x % 500))
1054        DosSleep(1L);
1055      else if (!(x % 50))
1056        DosSleep(1);
1057    }
1058    break;
1059
1060  case IDM_DESELECTSMALLER:
1061    for (x = 0; x < numS; x++) {
1062      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1063          *pciSa[x]->pszFileName &&
1064          pciSa[x]->flags & CNRITEM_SMALLER) {
1065        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1066          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1067                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1068      }
1069      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1070               *pciDa[x]->pszFileName &&
1071               pciDa[x]->flags & CNRITEM_SMALLER) {
1072        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1073          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1074                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1075      }
1076      if (!(x % 500))
1077        DosSleep(1L);
1078      else if (!(x % 50))
1079        DosSleep(1);
1080    }
1081    break;
1082
1083  case IDM_DESELECTNEWER:
1084    for (x = 0; x < numS; x++) {
1085      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1086          *pciSa[x]->pszFileName &&
1087          pciSa[x]->flags & CNRITEM_NEWER) {
1088        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1089          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1090                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1091      }
1092      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1093               *pciDa[x]->pszFileName &&
1094               pciDa[x]->flags & CNRITEM_NEWER) {
1095        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1096          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1097                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1098      }
1099      if (!(x % 500))
1100        DosSleep(1L);
1101      else if (!(x % 50))
1102        DosSleep(1);
1103    }
1104    break;
1105
1106  case IDM_DESELECTOLDER:
1107    for (x = 0; x < numS; x++) {
1108      if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1109          *pciSa[x]->pszFileName &&
1110          pciSa[x]->flags & CNRITEM_OLDER) {
1111        if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1112          WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1113                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1114      }
1115      else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1116               *pciDa[x]->pszFileName &&
1117               pciDa[x]->flags & CNRITEM_OLDER) {
1118        if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1119          WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1120                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1121      }
1122      if (!(x % 500))
1123        DosSleep(1L);
1124      else if (!(x % 50))
1125        DosSleep(1);
1126    }
1127    break;
1128
1129  default:
1130    break;
1131  }
1132
1133  if (reset) {
1134    while (numS) {
1135      WinSendMsg(hwndCnrS, CM_INVALIDATERECORD,
1136                 MPFROMP(pciSa), MPFROM2SHORT((min(numS, 65535)), 0));
1137      DosSleep(1);
1138      WinSendMsg(hwndCnrD, CM_INVALIDATERECORD,
1139                 MPFROMP(pciDa), MPFROM2SHORT((min(numD, 65535)), 0));
1140      numS -= min(numS, 65535);
1141      if (numS)
1142        DosSleep(1);
1143    }
1144  }
1145
1146  free(pciSa);
1147  free(pciDa);
1148  DosPostEventSem(CompactSem);
1149}
1150
1151struct SS
1152{
1153  PCNRITEM pci;
1154  BOOL unique, all, smallest, largest, newest, oldest;
1155};
1156
1157struct Cnr
1158{
1159  HWND hwndCnr;
1160  ULONG numfiles;
1161  struct SS *ss;
1162};
1163
1164static int CompSSNamesB(const void *s1, const void *s2)
1165{
1166  struct SS *ss2 = (struct SS *)s2;
1167
1168  return stricmp((PSZ)s1, ss2->pci->pszFileName);
1169}
1170
1171static int CompSSNames(const void *s1, const void *s2)
1172{
1173  struct SS *ss1 = (struct SS *)s1;
1174  struct SS *ss2 = (struct SS *)s2;
1175
1176  return stricmp(ss1->pci->pszFileName, ss2->pci->pszFileName);
1177}
1178
1179VOID FreeCnrs(struct Cnr * Cnrs, INT numw)
1180{
1181  register INT z;
1182
1183  for (z = 0; z < numw; z++) {
1184    if (Cnrs[z].ss)
1185      free(Cnrs[z].ss);
1186  }
1187  free(Cnrs);
1188  DosPostEventSem(CompactSem);
1189}
1190
1191VOID SpecialSelect2(HWND hwndParent, INT action)
1192{
1193  PCNRITEM pci;
1194  HENUM henum;
1195  HWND hwnd;
1196  register INT numwindows = 0, w, x, z, cmp;
1197  struct Cnr *Cnrs = NULL;
1198  struct SS *bsres;
1199
1200  if (!hwndParent)
1201    return;
1202
1203  /* count directory containers, build array of hwnds */
1204  henum = WinBeginEnumWindows(hwndParent);
1205  while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE) {
1206    if (WinWindowFromID(WinWindowFromID(hwnd, FID_CLIENT), DIR_CNR)) {
1207      Cnrs =
1208        xrealloc(Cnrs, (numwindows + 1) * sizeof(struct Cnr), pszSrcFile,
1209                 __LINE__);
1210      if (!Cnrs) {
1211        Notify(GetPString(IDS_OUTOFMEMORY));
1212        return;
1213      }
1214      memset(&Cnrs[numwindows], 0, sizeof(struct Cnr));
1215      Cnrs[numwindows].hwndCnr = WinWindowFromID(WinWindowFromID(hwnd,
1216                                                                 FID_CLIENT),
1217                                                 DIR_CNR);
1218      numwindows++;
1219    }
1220  }
1221  WinEndEnumWindows(henum);
1222  if (numwindows < 2) {
1223    FreeCnrs(Cnrs, numwindows);
1224    Runtime_Error(pszSrcFile, __LINE__, "expected two windows");
1225    Notify(GetPString(IDS_COMPSEL2ORMORETEXT));
1226    return;
1227  }
1228  if (numwindows > 4) {
1229    WinSendMsg(Cnrs[0].
1230               hwndCnr,
1231               UM_NOTIFY, MPFROMP(GetPString(IDS_BUILDINGLISTSTEXT)), MPVOID);
1232    DosSleep(1);
1233  }
1234
1235  /* count records, build array of pointers to records */
1236  for (z = 0; z < numwindows; z++) {
1237    pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
1238                                CM_QUERYRECORD,
1239                                MPVOID,
1240                                MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1241    x = 0;
1242    while (pci && (INT)pci != -1) {
1243      if (~pci->rc.flRecordAttr & CRA_FILTERED &&
1244          ~pci->attrFile & FILE_DIRECTORY) {
1245        Cnrs[z].ss =
1246          xrealloc(Cnrs[z].ss, (x + 1) * sizeof(struct SS), pszSrcFile,
1247                   __LINE__);
1248        if (!Cnrs[z].ss) {
1249          FreeCnrs(Cnrs, numwindows);
1250          Notify(GetPString(IDS_OUTOFMEMORY));
1251          return;
1252        }
1253        memset(&Cnrs[z].ss[x], 0, sizeof(struct SS));
1254        Cnrs[z].ss[x].pci = pci;
1255        x++;
1256      }
1257      pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
1258                                  CM_QUERYRECORD,
1259                                  MPFROMP(pci),
1260                                  MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1261    }
1262    DosSleep(1);
1263    Cnrs[z].numfiles = x;
1264    if (Cnrs[z].numfiles)
1265      qsort(Cnrs[z].ss, Cnrs[z].numfiles, sizeof(struct SS), CompSSNames);
1266  }
1267
1268  for (z = 0; z < numwindows; z++) {
1269    for (x = 0; x < Cnrs[z].numfiles; x++) {
1270      Cnrs[z].ss[x].all = Cnrs[z].ss[x].unique = Cnrs[z].ss[x].newest =
1271        Cnrs[z].ss[x].oldest = Cnrs[z].ss[x].smallest =
1272        Cnrs[z].ss[x].largest = TRUE;
1273      for (w = 0; w < numwindows; w++) {
1274        if (w != z && Cnrs[w].numfiles) {
1275          bsres = (struct SS *)bsearch(Cnrs[z].ss[x].pci->pszFileName,
1276                                       Cnrs[w].ss, Cnrs[w].numfiles,
1277                                       sizeof(struct SS), CompSSNamesB);
1278          if (bsres) {
1279            Cnrs[z].ss[x].unique = FALSE;
1280            if (Cnrs[z].ss[x].pci->cbFile + Cnrs[z].ss[x].pci->easize >
1281                bsres->pci->cbFile + bsres->pci->easize)
1282              Cnrs[z].ss[x].smallest = FALSE;
1283            if (Cnrs[z].ss[x].pci->cbFile + Cnrs[z].ss[x].pci->easize <
1284                bsres->pci->cbFile + bsres->pci->easize)
1285              Cnrs[z].ss[x].largest = FALSE;
1286            cmp =
1287              (Cnrs[z].ss[x].pci->date.year >
1288               bsres->pci->date.year) ? TRUE : (Cnrs[z].ss[x].pci->date.year <
1289                                                bsres->pci->date.
1290                                                year) ? FALSE : (Cnrs[z].
1291                                                                 ss[x].pci->
1292                                                                 date.month >
1293                                                                 bsres->pci->
1294                                                                 date.
1295                                                                 month) ? TRUE
1296              : (Cnrs[z].ss[x].pci->date.month <
1297                 bsres->pci->date.month) ? FALSE : (Cnrs[z].ss[x].pci->date.
1298                                                    day >
1299                                                    bsres->pci->date.
1300                                                    day) ? TRUE : (Cnrs[z].
1301                                                                   ss[x].pci->
1302                                                                   date.day <
1303                                                                   bsres->
1304                                                                   pci->date.
1305                                                                   day) ?
1306              FALSE : (Cnrs[z].ss[x].pci->time.hours >
1307                       bsres->pci->time.hours) ? TRUE : (Cnrs[z].ss[x].pci->
1308                                                         time.hours <
1309                                                         bsres->pci->time.
1310                                                         hours) ? FALSE
1311              : (Cnrs[z].ss[x].pci->time.minutes >
1312                 bsres->pci->time.minutes) ? TRUE : (Cnrs[z].ss[x].pci->time.
1313                                                     minutes <
1314                                                     bsres->pci->time.
1315                                                     minutes) ? FALSE
1316              : (Cnrs[z].ss[x].pci->time.seconds >
1317                 bsres->pci->time.seconds) ? TRUE : (Cnrs[z].ss[x].pci->time.
1318                                                     seconds <
1319                                                     bsres->pci->time.
1320                                                     seconds) ? FALSE : FALSE;
1321            if (!cmp)
1322              Cnrs[z].ss[x].newest = FALSE;
1323            cmp =
1324              (Cnrs[z].ss[x].pci->date.year <
1325               bsres->pci->date.year) ? TRUE : (Cnrs[z].ss[x].pci->date.year >
1326                                                bsres->pci->date.
1327                                                year) ? FALSE : (Cnrs[z].
1328                                                                 ss[x].pci->
1329                                                                 date.month <
1330                                                                 bsres->pci->
1331                                                                 date.
1332                                                                 month) ? TRUE
1333              : (Cnrs[z].ss[x].pci->date.month >
1334                 bsres->pci->date.month) ? FALSE : (Cnrs[z].ss[x].pci->date.
1335                                                    day <
1336                                                    bsres->pci->date.
1337                                                    day) ? TRUE : (Cnrs[z].
1338                                                                   ss[x].pci->
1339                                                                   date.day >
1340                                                                   bsres->
1341                                                                   pci->date.
1342                                                                   day) ?
1343              FALSE : (Cnrs[z].ss[x].pci->time.hours <
1344                       bsres->pci->time.hours) ? TRUE : (Cnrs[z].ss[x].pci->
1345                                                         time.hours >
1346                                                         bsres->pci->time.
1347                                                         hours) ? FALSE
1348              : (Cnrs[z].ss[x].pci->time.minutes <
1349                 bsres->pci->time.minutes) ? TRUE : (Cnrs[z].ss[x].pci->time.
1350                                                     minutes >
1351                                                     bsres->pci->time.
1352                                                     minutes) ? FALSE
1353              : (Cnrs[z].ss[x].pci->time.seconds <
1354                 bsres->pci->time.seconds) ? TRUE : (Cnrs[z].ss[x].pci->time.
1355                                                     seconds >
1356                                                     bsres->pci->time.
1357                                                     seconds) ? FALSE : FALSE;
1358            if (!cmp)
1359              Cnrs[z].ss[x].oldest = FALSE;
1360            cmp = 0;
1361            break;
1362          }
1363          else
1364            Cnrs[z].ss[x].all = FALSE;
1365        }
1366      }
1367      if (Cnrs[z].ss[x].unique)
1368        Cnrs[z].ss[x].oldest = Cnrs[z].ss[x].newest = Cnrs[z].ss[x].all =
1369          Cnrs[z].ss[x].largest = Cnrs[z].ss[x].smallest = FALSE;
1370      DosSleep(1);
1371    }
1372    DosSleep(1L);
1373  }
1374
1375  switch (action) {
1376  case IDM_SELECTBOTH:
1377    for (z = 0; z < numwindows; z++) {
1378      for (x = 0; x < Cnrs[z].numfiles; x++) {
1379        if (Cnrs[z].ss[x].all)
1380          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1381                     MPFROMP(Cnrs[z].ss[x].pci),
1382                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1383      }
1384      DosSleep(1);
1385    }
1386    break;
1387  case IDM_SELECTMORE:
1388    for (z = 0; z < numwindows; z++) {
1389      for (x = 0; x < Cnrs[z].numfiles; x++) {
1390        if (!Cnrs[z].ss[x].unique)
1391          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1392                     MPFROMP(Cnrs[z].ss[x].pci),
1393                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1394      }
1395      DosSleep(1);
1396    }
1397    break;
1398  case IDM_SELECTONE:
1399    for (z = 0; z < numwindows; z++) {
1400      for (x = 0; x < Cnrs[z].numfiles; x++) {
1401        if (Cnrs[z].ss[x].unique)
1402          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1403                     MPFROMP(Cnrs[z].ss[x].pci),
1404                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1405      }
1406      DosSleep(1);
1407    }
1408    break;
1409  case IDM_SELECTNEWER:
1410    for (z = 0; z < numwindows; z++) {
1411      for (x = 0; x < Cnrs[z].numfiles; x++) {
1412        if (Cnrs[z].ss[x].newest)
1413          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1414                     MPFROMP(Cnrs[z].ss[x].pci),
1415                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1416      }
1417      DosSleep(1);
1418    }
1419    break;
1420  case IDM_SELECTOLDER:
1421    for (z = 0; z < numwindows; z++) {
1422      for (x = 0; x < Cnrs[z].numfiles; x++) {
1423        if (Cnrs[z].ss[x].oldest)
1424          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1425                     MPFROMP(Cnrs[z].ss[x].pci),
1426                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1427      }
1428      DosSleep(1);
1429    }
1430    break;
1431  case IDM_SELECTBIGGER:
1432    for (z = 0; z < numwindows; z++) {
1433      for (x = 0; x < Cnrs[z].numfiles; x++) {
1434        if (Cnrs[z].ss[x].largest)
1435          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1436                     MPFROMP(Cnrs[z].ss[x].pci),
1437                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1438      }
1439      DosSleep(1);
1440    }
1441    break;
1442  case IDM_SELECTSMALLER:
1443    for (z = 0; z < numwindows; z++) {
1444      for (x = 0; x < Cnrs[z].numfiles; x++) {
1445        if (Cnrs[z].ss[x].smallest)
1446          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1447                     MPFROMP(Cnrs[z].ss[x].pci),
1448                     MPFROM2SHORT(TRUE, CRA_SELECTED));
1449      }
1450      DosSleep(1);
1451    }
1452    break;
1453
1454  case IDM_DESELECTBOTH:
1455    for (z = 0; z < numwindows; z++) {
1456      for (x = 0; x < Cnrs[z].numfiles; x++) {
1457        if (Cnrs[z].ss[x].all)
1458          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1459                     MPFROMP(Cnrs[z].ss[x].pci),
1460                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1461      }
1462      DosSleep(1);
1463    }
1464    break;
1465  case IDM_DESELECTMORE:
1466    for (z = 0; z < numwindows; z++) {
1467      for (x = 0; x < Cnrs[z].numfiles; x++) {
1468        if (!Cnrs[z].ss[x].unique)
1469          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1470                     MPFROMP(Cnrs[z].ss[x].pci),
1471                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1472      }
1473      DosSleep(1);
1474    }
1475    break;
1476  case IDM_DESELECTONE:
1477    for (z = 0; z < numwindows; z++) {
1478      for (x = 0; x < Cnrs[z].numfiles; x++) {
1479        if (Cnrs[z].ss[x].unique)
1480          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1481                     MPFROMP(Cnrs[z].ss[x].pci),
1482                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1483      }
1484      DosSleep(1);
1485    }
1486    break;
1487  case IDM_DESELECTNEWER:
1488    for (z = 0; z < numwindows; z++) {
1489      for (x = 0; x < Cnrs[z].numfiles; x++) {
1490        if (Cnrs[z].ss[x].newest)
1491          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1492                     MPFROMP(Cnrs[z].ss[x].pci),
1493                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1494      }
1495      DosSleep(1);
1496    }
1497    break;
1498  case IDM_DESELECTOLDER:
1499    for (z = 0; z < numwindows; z++) {
1500      for (x = 0; x < Cnrs[z].numfiles; x++) {
1501        if (Cnrs[z].ss[x].oldest)
1502          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1503                     MPFROMP(Cnrs[z].ss[x].pci),
1504                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1505      }
1506      DosSleep(1);
1507    }
1508    break;
1509  case IDM_DESELECTBIGGER:
1510    for (z = 0; z < numwindows; z++) {
1511      for (x = 0; x < Cnrs[z].numfiles; x++) {
1512        if (Cnrs[z].ss[x].largest)
1513          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1514                     MPFROMP(Cnrs[z].ss[x].pci),
1515                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1516      }
1517      DosSleep(1);
1518    }
1519    break;
1520  case IDM_DESELECTSMALLER:
1521    for (z = 0; z < numwindows; z++) {
1522      for (x = 0; x < Cnrs[z].numfiles; x++) {
1523        if (Cnrs[z].ss[x].smallest)
1524          WinSendMsg(Cnrs[z].hwndCnr, CM_SETRECORDEMPHASIS,
1525                     MPFROMP(Cnrs[z].ss[x].pci),
1526                     MPFROM2SHORT(FALSE, CRA_SELECTED));
1527      }
1528      DosSleep(1);
1529    }
1530    break;
1531  }
1532
1533  FreeCnrs(Cnrs, numwindows);
1534}
Note: See TracBrowser for help on using the repository browser.