source: trunk/dll/select.c @ 672

Last change on this file since 672 was 672, checked in by Steven Levine, 14 years ago

Use dcd->ulItemsToUnHilite
Sync UnHilite? calls with arg mods

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