source: trunk/dll/select.c @ 766

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

format cleanup

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