source: trunk/dll/select.c@ 766

Last change on this file since 766 was 766, checked in by Gregg Young, 18 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
RevLine 
[123]1
2/***********************************************************************
3
4 $Id: select.c 766 2007-08-05 20:21:20Z gyoung $
5
[362]6 Container item selection support routines
7
[123]8 Copyright (c) 1993-98 M. Kimes
[672]9 Copyright (c) 2004, 2007 Steven H. Levine
[123]10
[158]11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 25 May 05 SHL Rework for ULONGLONG
[204]13 06 Jun 05 SHL Drop unused code
[317]14 06 Jul 06 SHL Support compare content (IDM_SELECTSAMECONTENT)
[362]15 13 Jul 06 SHL Use Runtime_Error
[406]16 29 Jul 06 SHL Use xfgets_bstripcr
[442]17 15 Aug 06 SHL Rework SetMask args and logic
[603]18 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
[618]19 19 Apr 07 SHL Sync with NumItemsToUnhilite mods
[672]20 12 May 07 SHL Use dcd->ulItemsToUnHilite
[690]21 14 Jun 07 SHL SelectAll: make odd expression go away
[751]22 02 Aug 07 SHL Sync with CNRITEM mods
[762]23 04 Aug 07 SHL Use Runtime_Error
[123]24
25***********************************************************************/
26
[2]27#define INCL_DOS
28#define INCL_WIN
[158]29#define INCL_LONGLONG
30#include <os2.h>
[2]31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <share.h>
[317]36#include <io.h>
[158]37
[2]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
[362]45static PSZ pszSrcFile = __FILE__;
46
[672]47VOID UnHilite(HWND hwndCnr, BOOL all, CHAR *** list, ULONG ulItemsToUnHilite)
[317]48{
[2]49 PCNRITEM pci;
[603]50 INT numfiles = 0, numalloc = 0, x = 0;
[551]51 INT attribute = CRA_CURSORED;
[2]52
[362]53 if (all && list && *list) {
[2]54 FreeList(*list);
55 *list = NULL;
56 }
[551]57 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]58 if (pci && (INT)pci != -1) {
[362]59 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]60 attribute = CRA_SELECTED;
[551]61 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
62 MPFROMSHORT(attribute));
[2]63 }
[748]64 while (pci && (INT)pci != -1) {
[551]65 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
66 MPFROM2SHORT(FALSE, CRA_SELECTED));
[362]67 if (!all)
[690]68 break;
[618]69 // Count is one extra to ensure non-zero elsewhere
[672]70 // x is 0 based index
71 if (x + 2 == ulItemsToUnHilite)
[690]72 break;
[362]73 if (list)
[730]74 AddToList(pci->pszFileName, list, &numfiles, &numalloc);
[551]75 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
76 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
[603]77 x++;
[2]78 }
79 }
80}
81
[551]82VOID SelectList(HWND hwndCnr, BOOL partial, BOOL deselect, BOOL clearfirst,
[748]83 PCNRITEM pciParent, PSZ filename, CHAR ** list)
[362]84{
[2]85
[551]86 PCNRITEM pci;
[2]87 register INT x;
[551]88 BOOL foundone = FALSE;
[766]89 ULONG errs = 0;
[2]90
[362]91 if (clearfirst && !deselect)
[672]92 UnHilite(hwndCnr, TRUE, NULL, 0);
[362]93 if (list && list[0]) {
[551]94 for (x = 0; list[x]; x++) {
[2]95 pci = FindCnrRecord(hwndCnr,
[551]96 list[x], pciParent, partial, partial, TRUE);
[362]97 if (pci) {
[551]98 WinSendMsg(hwndCnr,
99 CM_SETRECORDEMPHASIS,
100 MPFROMP(pci),
101 MPFROM2SHORT((SHORT) ((deselect) ? FALSE : TRUE),
102 CRA_SELECTED));
103 foundone = TRUE;
[2]104 }
105 }
[362]106 if (!foundone)
107 Runtime_Error(pszSrcFile, __LINE__, "select failed");
[2]108 }
[362]109 else if (filename && *filename) {
[2]110
111 FILE *fp;
[551]112 CHAR input[1024], *p;
[2]113
[551]114 fp = _fsopen(filename, "r", SH_DENYNO);
[362]115 if (fp) {
116 while (!feof(fp)) {
[551]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++;
[766]143 if (errs > 50) { /* prevent runaway on bad file */
[2]144
[551]145 APIRET ret;
[2]146
[551]147 ret = saymsg(MB_YESNO,
148 hwndCnr,
149 GetPString(IDS_POSSIBLEERRORTEXT),
150 GetPString(IDS_MAYNOTBELISTTEXT), filename);
151 if (ret == MBID_NO)
152 break;
[766]153 errs = 0;
[551]154 }
[2]155 }
156 fclose(fp);
157 }
158 }
159}
160
[748]161VOID SelectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
162 PSZ text, BOOL is_arc)
[362]163{
[2]164
[551]165 PCNRITEM pci;
166 BOOL markit;
[748]167 PSZ file;
168 PSZ pszToMatch;
[551]169 MASK Mask;
[748]170 INT x;
[551]171 ULONG textlen = 0;
[2]172
[362]173 if (text)
[2]174 textlen = strlen(text);
[551]175 memset(&Mask, 0, sizeof(Mask));
[442]176 if (maskstr)
[551]177 SetMask(maskstr, &Mask);
178 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
179 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]180 while (pci && (INT)pci != -1) {
181
[2]182 markit = FALSE;
[748]183
184 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[362]185 if (!is_arc) {
[748]186 if (files && ~pci->attrFile & FILE_DIRECTORY)
[551]187 markit = TRUE;
[748]188 if (dirs && pci->attrFile & FILE_DIRECTORY)
[551]189 markit = TRUE;
[2]190 }
191 else
[551]192 markit = TRUE;
[442]193 if (maskstr && *maskstr && markit) {
[551]194 markit = FALSE;
[748]195 // Point a filename part
[730]196 file = strrchr(pci->pszFileName, '\\');
[551]197 if (!file)
[730]198 file = strrchr(pci->pszFileName, ':');
[551]199 if (file)
200 file++;
201 else
[730]202 file = pci->pszFileName;
[551]203 for (x = 0; Mask.pszMasks[x]; x++) {
204 if (*Mask.pszMasks[x]) {
[748]205 if ((strchr(Mask.pszMasks[x], '\\') ||
206 strchr(Mask.pszMasks[x], ':')))
207 pszToMatch = pci->pszFileName;
208 else
209 pszToMatch = file;
[551]210 if (*Mask.pszMasks[x] != '/') {
[748]211 if (wildcard(pszToMatch, Mask.pszMasks[x], FALSE)) {
[551]212 markit = TRUE;
[690]213 }
[551]214 }
215 else {
[748]216 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, FALSE)) {
[551]217 markit = FALSE;
218 break;
219 }
220 }
221 }
[690]222 } // for
[2]223 }
224 }
225
[748]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;
[2]235
[748]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
[551]249 break;
250 }
[748]251 fclose(inputFile);
[551]252 }
[748]253 free(input);
[766]254 DosSleep(1);
[551]255 }
[2]256 }
[748]257 else
258 markit = FALSE;
[2]259 }
[748]260
[362]261 if (markit)
[551]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
[2]267}
268
[748]269VOID DeselectAll(HWND hwndCnr, BOOL files, BOOL dirs, PSZ maskstr,
270 PSZ text, BOOL is_arc)
[362]271{
[551]272 PCNRITEM pci;
273 BOOL unmarkit;
[748]274 PSZ file;
275 PSZ pszToMatch;
[551]276 MASK Mask;
277 register INT x;
278 ULONG textlen = 0;
[2]279
[362]280 if (text)
[2]281 textlen = strlen(text);
[551]282 memset(&Mask, 0, sizeof(Mask));
[442]283 if (maskstr && *maskstr)
[551]284 SetMask(maskstr, &Mask);
285 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
286 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]287 while (pci && (INT)pci != -1) {
[2]288 unmarkit = FALSE;
[748]289 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[362]290 if (!is_arc) {
[748]291 if (files && ~pci->attrFile & FILE_DIRECTORY)
[551]292 unmarkit = TRUE;
293 if (dirs && (pci->attrFile & FILE_DIRECTORY))
294 unmarkit = TRUE;
[2]295 }
296 else
[551]297 unmarkit = TRUE;
[442]298 if (maskstr && *maskstr && unmarkit) {
[551]299 unmarkit = FALSE;
[730]300 file = strrchr(pci->pszFileName, '\\');
[551]301 if (!file)
[730]302 file = strrchr(pci->pszFileName, ':');
[551]303 if (file)
304 file++;
305 else
[730]306 file = pci->pszFileName;
[551]307 for (x = 0; Mask.pszMasks[x]; x++) {
308 if (*Mask.pszMasks[x]) {
[748]309 if (strchr(Mask.pszMasks[x], '\\') ||
310 strchr(Mask.pszMasks[x], ':'))
311 pszToMatch = pci->pszFileName;
312 else
313 pszToMatch = file;
[551]314 if (*Mask.pszMasks[x] != '/') {
[748]315 if (wildcard(pszToMatch, Mask.pszMasks[x], FALSE))
[551]316 unmarkit = TRUE;
317 }
318 else {
[748]319 if (wildcard(pszToMatch, Mask.pszMasks[x] + 1, FALSE)) {
[551]320 unmarkit = FALSE;
321 break;
322 }
323 }
324 }
325 }
[2]326 }
327 }
328
[748]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;
[2]338
[748]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
[551]352 break;
353 }
[748]354 fclose(inputFile);
[551]355 }
[748]356 free(input);
[766]357 DosSleep(1);
[551]358 }
[2]359 }
[748]360 else
361 unmarkit = FALSE;
[2]362 }
[748]363
[362]364 if (unmarkit)
[551]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));
[2]370 }
371}
372
[551]373VOID Deselect(HWND hwndCnr)
[317]374{
[2]375 PCNRITEM pcil;
376
[551]377 pcil = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
378 MPFROMLONG(CMA_FIRST),
379 MPFROMSHORT(CRA_SELECTED));
[748]380 while (pcil && (INT)pcil != -1) {
[551]381 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pcil),
382 MPFROM2SHORT(FALSE, CRA_SELECTED));
383 pcil = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pcil),
384 MPFROMSHORT(CRA_SELECTED));
[2]385 }
386}
387
[317]388//=== HideAll() Hide all selected records ===
[2]389
[551]390VOID HideAll(HWND hwndCnr)
[317]391{
[551]392 PCNRITEM pci, pciH;
393 INT attribute = CRA_CURSORED;
394 CNRINFO cnri;
395 BOOL didone = FALSE;
[2]396
[551]397 memset(&cnri, 0, sizeof(CNRINFO));
[2]398 cnri.cb = sizeof(CNRINFO);
[551]399 WinSendMsg(hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
400 MPFROMLONG(sizeof(CNRINFO)));
401 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]402 if (pci && (INT)pci != -1) {
[362]403 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]404 attribute = CRA_SELECTED;
[551]405 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
406 MPFROMSHORT(attribute));
[2]407 }
408 }
[748]409 while (pci && (INT)pci != -1) {
[551]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));
[2]415 pci->rc.flRecordAttr |= CRA_FILTERED;
416 didone = TRUE;
[362]417 if (fSyncUpdates) {
418 if (cnri.flWindowAttr & CV_DETAIL)
[551]419 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
420 MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
[2]421 else
[551]422 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
423 MPFROM2SHORT(1, CMA_REPOSITION | CMA_ERASE));
[2]424 }
425 pci = pciH;
426 }
[362]427 if (didone && !fSyncUpdates)
[551]428 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
429 MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
[2]430}
431
[551]432VOID MarkAll(HWND hwndCnr, BOOL quitit, BOOL target, BOOL source)
[317]433{
[2]434 PCNRITEM pci;
[551]435 INT attribute = CRA_CURSORED;
[2]436
[362]437 if (quitit)
[618]438 attribute = target ? CRA_TARGET : source ? CRA_SOURCE : CRA_INUSE;
[551]439 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
440 MPFROMLONG(CMA_FIRST), MPFROMSHORT(attribute));
[748]441 if (pci && (INT)pci != -1) {
[362]442 if (attribute == CRA_CURSORED) {
443 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[551]444 attribute = CRA_SELECTED;
445 pci =
446 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
447 MPFROMSHORT(attribute));
[2]448 }
449 }
450 }
[748]451 while (pci && (INT)pci != -1) {
[551]452 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
453 MPFROM2SHORT(!quitit,
[618]454 target ? CRA_TARGET : source ? CRA_SOURCE :
455 CRA_INUSE));
[551]456 pci =
457 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
458 MPFROMSHORT(attribute));
[2]459 }
460}
461
[551]462VOID RemoveAll(HWND hwndCnr, ULONGLONG * pullTotalBytes,
463 ULONG * pulTotalFiles)
[317]464{
[2]465 PCNRITEM pci;
[551]466 INT attribute = CRA_CURSORED;
467 BOOL didone = FALSE;
[2]468
[551]469 pci = (PCNRITEM) CurrentRecord(hwndCnr);
[748]470 if (pci && (INT)pci != -1) {
[362]471 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]472 attribute = CRA_SELECTED;
[551]473 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
474 MPFROMSHORT(attribute));
[2]475 }
476 }
[748]477 while (pci && (INT)pci != -1) {
478 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
[2]479 didone = TRUE;
[158]480 if (pulTotalFiles)
[689]481 *pulTotalFiles -= 1;
[158]482 if (pullTotalBytes)
[551]483 *pullTotalBytes -= (pci->cbFile + pci->easize);
484 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
485 MPFROM2SHORT(0, CRA_SELECTED));
[362]486 if (fSyncUpdates)
[751]487 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE | CMA_INVALIDATE);
[2]488 else
[751]489 RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE);
[362]490 if (attribute == CRA_CURSORED)
[551]491 break;
492 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
493 MPFROMSHORT(attribute));
[2]494 }
495 else
[551]496 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
497 MPFROMSHORT(attribute));
[2]498 }
[362]499 if (didone && !fSyncUpdates)
[551]500 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
501 MPFROM2SHORT(0, CMA_REPOSITION));
[2]502}
503
[442]504//== SetMask() Convert mask string to array of pointers to masks ==
505
[551]506VOID SetMask(PSZ maskstr, MASK * mask)
[317]507{
[442]508 UINT x;
509 PSZ p;
[2]510
[442]511 if (maskstr)
[551]512 strcpy(mask->szMask, maskstr); // Got new mask string
[442]513 // Build array of pointers
514 p = mask->szMaskCopy;
[551]515 strcpy(p, mask->szMask);
[442]516 // Allow up to 25 masks - ignore extras
517 for (x = 0; *p && x < 25; x++) {
518 mask->pszMasks[x] = p;
[362]519 while (*p && *p != ';')
[442]520 p++; // Find separator
[362]521 if (*p) {
[442]522 *p = 0; // Replace ;
[2]523 p++;
524 }
[551]525 } // for
[442]526 mask->pszMasks[x] = NULL; // Mark end
[2]527}
528
[551]529VOID ExpandAll(HWND hwndCnr, BOOL expand, PCNRITEM pciParent)
[317]530{
[2]531 PCNRITEM pci;
532
[362]533 if (!pciParent)
[551]534 pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
535 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[362]536 if (pciParent) {
[748]537 if (expand && ~pciParent->rc.flRecordAttr & CRA_EXPANDED)
[551]538 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciParent), MPVOID);
[362]539 else if (!expand && (pciParent->rc.flRecordAttr & CRA_EXPANDED))
[551]540 WinSendMsg(hwndCnr, CM_COLLAPSETREE, MPFROMP(pciParent), MPVOID);
541 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
542 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[362]543 if (pci)
[766]544 DosSleep(1);
[748]545 while (pci && (INT)pci != -1) {
[551]546 ExpandAll(hwndCnr, expand, pci);
547 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
548 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]549 }
550 }
[748]551 DosSleep(1);
[2]552}
553
[551]554VOID InvertAll(HWND hwndCnr)
[317]555{
[2]556 PCNRITEM pci;
557
[551]558 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPVOID,
559 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]560 while (pci && (INT)pci != -1) {
561 if (~pci->rc.flRecordAttr & CRA_FILTERED) {
562 if (~pci->rc.flRecordAttr & CRA_SELECTED)
[551]563 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
564 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]565 else
[551]566 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
567 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]568 }
[551]569 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
570 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]571 }
572}
573
[204]574#pragma alloc_text (SELECT3,SpecialSelect)
[2]575#pragma alloc_text(SELECT4,FreeCnrs,SpecialSelect2,CompSSNames,CompSSNamesB)
576
[762]577/**
578 * Do select actions for compare directories containers
579 *
580 */
581
[551]582VOID SpecialSelect(HWND hwndCnrS, HWND hwndCnrD, INT action, BOOL reset)
[317]583{
[551]584 PCNRITEM pciS, pciD, *pciSa = NULL, *pciDa = NULL;
585 CNRINFO cnri;
586 BOOL slow = FALSE;
587 register INT x, numD, numS;
[2]588
[606]589
[762]590 if (!hwndCnrS || !hwndCnrD) {
591 Runtime_Error(pszSrcFile, __LINE__, "hwndCnrS %p hwndCnrD %p", hwndCnrS, hwndCnrD);
[2]592 return;
[762]593 }
[2]594
[551]595 memset(&cnri, 0, sizeof(CNRINFO));
[2]596 cnri.cb = sizeof(CNRINFO);
[551]597 WinSendMsg(hwndCnrD, CM_QUERYCNRINFO, MPFROMP(&cnri),
598 MPFROMLONG(sizeof(CNRINFO)));
599 numD = (INT) cnri.cRecords;
600 memset(&cnri, 0, sizeof(CNRINFO));
[2]601 cnri.cb = sizeof(CNRINFO);
[551]602 WinSendMsg(hwndCnrS, CM_QUERYCNRINFO, MPFROMP(&cnri),
603 MPFROMLONG(sizeof(CNRINFO)));
604 numS = (INT) cnri.cRecords;
[362]605 if (!numD || numS != numD) {
[762]606 Runtime_Error(pszSrcFile, __LINE__, "numD %u != numS %u", numD, numS);
[2]607 return;
608 }
[551]609 pciDa = xmalloc(sizeof(PCNRITEM) * numD, pszSrcFile, __LINE__);
[362]610 if (!pciDa)
[2]611 return;
612
[551]613 pciSa = xmalloc(sizeof(PCNRITEM) * numS, pszSrcFile, __LINE__);
[362]614 if (!pciSa) {
615 free(pciDa);
[2]616 return;
617 }
618
619Restart:
620
[551]621 memset(pciDa, 0, sizeof(PCNRITEM) * numD);
622 memset(pciSa, 0, sizeof(PCNRITEM) * numS);
[2]623
[551]624 pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
625 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[2]626 x = 0;
[748]627 while (pciD && (INT)pciD != -1 && x < numD) {
[362]628 if (reset)
[2]629 pciD->flags = 0;
630 pciDa[x] = pciD;
631 x++;
[362]632 if (!slow)
[551]633 pciD = (PCNRITEM) pciD->rc.preccNextRecord;
[2]634 else
[551]635 pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
636 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[362]637 if (!(x % 500))
[762]638 DosSleep(1);
[362]639 else if (!(x % 50))
[748]640 DosSleep(1);
[762]641 } // while
642
[362]643 if (numD != x) {
644 if (!slow) {
[2]645 slow = TRUE;
646 goto Restart;
647 }
648 free(pciDa);
649 free(pciSa);
[762]650 Runtime_Error(pszSrcFile, __LINE__, "numD %u != x %lu", numD, x);
[2]651 return;
652 }
653
[551]654 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
655 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[2]656 x = 0;
[748]657 while (pciS && (INT)pciS != -1 && x < numS) {
[362]658 if (reset)
[2]659 pciS->flags = 0;
660 pciSa[x] = pciS;
661 x++;
[362]662 if (!slow)
[551]663 pciS = (PCNRITEM) pciS->rc.preccNextRecord;
[2]664 else
[551]665 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
666 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[362]667 if (!(x % 500))
[762]668 DosSleep(1);
[362]669 else if (!(x % 50))
[748]670 DosSleep(1);
[762]671 } // while
672
[362]673 if (numS != x) {
674 if (!slow) {
[2]675 slow = TRUE;
676 goto Restart;
677 }
678 free(pciSa);
679 free(pciDa);
[551]680 Runtime_Error(pszSrcFile, __LINE__, "numS (%lu) != x (%lu)", numS, x);
[2]681 return;
682 }
683
[362]684 if (reset) {
[551]685 for (x = 0; x < numS; x++) {
[748]686
[730]687 if (!*pciSa[x]->pszFileName || !*pciDa[x]->pszFileName)
[551]688 continue;
[748]689
[2]690 pciSa[x]->flags |= CNRITEM_EXISTS;
691 pciDa[x]->flags |= CNRITEM_EXISTS;
[362]692 if (pciSa[x]->cbFile + pciSa[x]->easize >
[551]693 pciDa[x]->cbFile + pciDa[x]->easize) {
694 pciSa[x]->flags |= CNRITEM_LARGER;
695 pciDa[x]->flags |= CNRITEM_SMALLER;
[2]696 }
[362]697 else if (pciSa[x]->cbFile + pciSa[x]->easize <
[551]698 pciDa[x]->cbFile + pciDa[x]->easize) {
699 pciSa[x]->flags |= CNRITEM_SMALLER;
700 pciDa[x]->flags |= CNRITEM_LARGER;
[2]701 }
[362]702 if ((pciSa[x]->date.year > pciDa[x]->date.year) ? TRUE :
[551]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;
[2]716 }
[362]717 else if ((pciSa[x]->date.year < pciDa[x]->date.year) ? TRUE :
[551]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;
[2]732 }
[362]733 if (!(x % 500))
[762]734 DosSleep(1);
[362]735 else if (!(x % 50))
[748]736 DosSleep(1);
[2]737 }
738 }
739
[551]740 switch (action) {
741 case IDM_SELECTIDENTICAL:
742 for (x = 0; x < numS; x++) {
[748]743 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
[730]744 if (*pciSa[x]->pszFileName &&
[748]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)
[551]751 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
752 MPFROM2SHORT(TRUE, CRA_SELECTED));
[748]753 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]754 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
755 MPFROM2SHORT(TRUE, CRA_SELECTED));
756 }
757 if (!(x % 500))
[766]758 DosSleep(1);
[551]759 else if (!(x % 50))
[748]760 DosSleep(1);
[2]761 }
[551]762 }
763 break;
[2]764
[551]765 case IDM_SELECTSAME:
766 for (x = 0; x < numS; x++) {
[748]767 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
[730]768 *pciSa[x]->pszFileName &&
[748]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)
[551]773 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
774 MPFROM2SHORT(TRUE, CRA_SELECTED));
[748]775 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]776 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
777 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]778 }
[551]779 if (!(x % 500))
[766]780 DosSleep(1);
[551]781 else if (!(x % 50))
[748]782 DosSleep(1);
[551]783 }
784 break;
[2]785
[551]786 case IDM_SELECTSAMECONTENT:
[690]787 // fixme why?
[551]788 for (x = 0; x < numS; x++) {
789 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
[730]790 *pciSa[x]->pszFileName &&
791 *pciDa[x]->pszFileName &&
[551]792 pciSa[x]->flags & CNRITEM_EXISTS &&
[748]793 pciDa[x]->flags & CNRITEM_EXISTS)
794 {
[551]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);
[317]803
[730]804 fp1 = _fsopen(pciSa[x]->pszFileName, "rb", SH_DENYNO);
[551]805 if (!fp1) {
806 errLineNo = __LINE__;
807 compErrno = errno;
808 }
809 else {
[730]810 fp2 = _fsopen(pciDa[x]->pszFileName, "rb", SH_DENYNO);
[551]811 if (!fp2) {
[362]812 errLineNo = __LINE__;
813 compErrno = errno;
[317]814 }
815 else {
[551]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;
[317]830 }
[551]831 else if (feof(fp1) && feof(fp2))
832 gotMatch = TRUE;
833 break;
834 }
835 else if (memcmp(buf1, buf2, numread1))
836 break;
[690]837 } // while
838 } // same len
[551]839 }
840 }
[317]841
[551]842 if (fp1)
843 fclose(fp1);
[317]844
[551]845 if (fp2)
846 fclose(fp2);
[317]847
[551]848 if (errLineNo) {
849 Runtime_Error(pszSrcFile, errLineNo,
850 "error %d while comparing", compErrno);
851 }
852 if (gotMatch) {
[748]853 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]854 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
855 MPFROM2SHORT(TRUE, CRA_SELECTED));
[748]856 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]857 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
858 MPFROM2SHORT(TRUE, CRA_SELECTED));
859 }
860 }
861 if (!(x % 500))
[766]862 DosSleep(1);
[551]863 else if (!(x % 50))
[748]864 DosSleep(1);
[551]865 } // for records
866 break;
[317]867
[551]868 case IDM_SELECTBOTH:
869 for (x = 0; x < numS; x++) {
[748]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)
[551]874 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
875 MPFROM2SHORT(TRUE, CRA_SELECTED));
[748]876 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]877 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
878 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]879 }
[551]880 if (!(x % 500))
[766]881 DosSleep(1);
[551]882 else if (!(x % 50))
[748]883 DosSleep(1);
[551]884 }
885 break;
[2]886
[551]887 case IDM_SELECTONE:
888 for (x = 0; x < numS; x++) {
[748]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)
[551]894 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
895 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]896 }
[748]897 else if (*pciDa[x]->pszFileName &&
898 ~pciDa[x]->flags & CNRITEM_EXISTS) {
899 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]900 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
901 MPFROM2SHORT(TRUE, CRA_SELECTED));
902 }
903 if (!(x % 500))
[766]904 DosSleep(1);
[551]905 else if (!(x % 50))
[748]906 DosSleep(1);
[551]907 }
908 break;
[2]909
[551]910 case IDM_SELECTBIGGER:
911 for (x = 0; x < numS; x++) {
[748]912 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
913 pciSa[x]->flags & CNRITEM_LARGER) {
914 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
[551]915 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
916 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]917 }
[748]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)
[551]922 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
923 MPFROM2SHORT(TRUE, CRA_SELECTED));
924 }
925 if (!(x % 500))
[766]926 DosSleep(1);
[551]927 else if (!(x % 50))
[748]928 DosSleep(1);
[551]929 }
930 break;
[2]931
[551]932 case IDM_SELECTSMALLER:
933 for (x = 0; x < numS; x++) {
[748]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)
[551]938 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
939 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]940 }
[748]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)
[551]945 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
946 MPFROM2SHORT(TRUE, CRA_SELECTED));
947 }
948 if (!(x % 500))
[766]949 DosSleep(1);
[551]950 else if (!(x % 50))
[748]951 DosSleep(1);
[551]952 }
953 break;
[2]954
[551]955 case IDM_SELECTNEWER:
956 for (x = 0; x < numS; x++) {
[748]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)
[551]961 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
962 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]963 }
[748]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)
[551]968 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
969 MPFROM2SHORT(TRUE, CRA_SELECTED));
970 }
971 if (!(x % 500))
[766]972 DosSleep(1);
[551]973 else if (!(x % 50))
[748]974 DosSleep(1);
[551]975 }
976 break;
[2]977
[551]978 case IDM_SELECTOLDER:
979 for (x = 0; x < numS; x++) {
[748]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)
[551]984 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
985 MPFROM2SHORT(TRUE, CRA_SELECTED));
[2]986 }
[748]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)
[551]991 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
992 MPFROM2SHORT(TRUE, CRA_SELECTED));
993 }
994 if (!(x % 500))
[766]995 DosSleep(1);
[551]996 else if (!(x % 50))
[748]997 DosSleep(1);
[551]998 }
999 break;
[2]1000
[551]1001 case IDM_DESELECTBOTH:
1002 for (x = 0; x < numS; x++) {
[748]1003 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1004 *pciSa[x]->pszFileName &&
1005 pciSa[x]->flags & CNRITEM_EXISTS) {
[551]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));
[2]1012 }
[551]1013 if (!(x % 500))
[766]1014 DosSleep(1);
[551]1015 else if (!(x % 50))
[748]1016 DosSleep(1);
[551]1017 }
1018 break;
[2]1019
[551]1020 case IDM_DESELECTONE:
1021 for (x = 0; x < numS; x++) {
[748]1022 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1023 *pciSa[x]->pszFileName &&
1024 ~pciSa[x]->flags & CNRITEM_EXISTS) {
[551]1025 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1026 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1027 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]1028 }
[748]1029 else if (*pciDa[x]->pszFileName &&
1030 ~pciDa[x]->flags & CNRITEM_EXISTS) {
[551]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))
[766]1036 DosSleep(1);
[551]1037 else if (!(x % 50))
[748]1038 DosSleep(1);
[551]1039 }
1040 break;
[2]1041
[551]1042 case IDM_DESELECTBIGGER:
1043 for (x = 0; x < numS; x++) {
[748]1044 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1045 *pciSa[x]->pszFileName &&
1046 pciSa[x]->flags & CNRITEM_LARGER) {
[551]1047 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1048 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1049 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]1050 }
[748]1051 else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1052 *pciDa[x]->pszFileName &&
1053 pciDa[x]->flags & CNRITEM_LARGER) {
[551]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))
[766]1059 DosSleep(1);
[551]1060 else if (!(x % 50))
[748]1061 DosSleep(1);
[551]1062 }
1063 break;
[2]1064
[551]1065 case IDM_DESELECTSMALLER:
1066 for (x = 0; x < numS; x++) {
[748]1067 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1068 *pciSa[x]->pszFileName &&
1069 pciSa[x]->flags & CNRITEM_SMALLER) {
[551]1070 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1071 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1072 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]1073 }
[748]1074 else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1075 *pciDa[x]->pszFileName &&
1076 pciDa[x]->flags & CNRITEM_SMALLER) {
[551]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))
[766]1082 DosSleep(1);
[551]1083 else if (!(x % 50))
[748]1084 DosSleep(1);
[551]1085 }
1086 break;
[2]1087
[551]1088 case IDM_DESELECTNEWER:
1089 for (x = 0; x < numS; x++) {
[748]1090 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1091 *pciSa[x]->pszFileName &&
1092 pciSa[x]->flags & CNRITEM_NEWER) {
[551]1093 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1094 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1095 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]1096 }
[748]1097 else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1098 *pciDa[x]->pszFileName &&
1099 pciDa[x]->flags & CNRITEM_NEWER) {
[551]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))
[766]1105 DosSleep(1);
[551]1106 else if (!(x % 50))
[748]1107 DosSleep(1);
[551]1108 }
1109 break;
[2]1110
[551]1111 case IDM_DESELECTOLDER:
1112 for (x = 0; x < numS; x++) {
[748]1113 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1114 *pciSa[x]->pszFileName &&
1115 pciSa[x]->flags & CNRITEM_OLDER) {
[551]1116 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1117 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1118 MPFROM2SHORT(FALSE, CRA_SELECTED));
[2]1119 }
[748]1120 else if (~pciDa[x]->rc.flRecordAttr & CRA_FILTERED &&
1121 *pciDa[x]->pszFileName &&
1122 pciDa[x]->flags & CNRITEM_OLDER) {
[551]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))
[766]1128 DosSleep(1);
[551]1129 else if (!(x % 50))
[748]1130 DosSleep(1);
[551]1131 }
1132 break;
[2]1133
[551]1134 default:
1135 break;
[2]1136 }
1137
[362]1138 if (reset) {
1139 while (numS) {
[551]1140 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD,
1141 MPFROMP(pciSa), MPFROM2SHORT((min(numS, 65535)), 0));
[748]1142 DosSleep(1);
[551]1143 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD,
1144 MPFROMP(pciDa), MPFROM2SHORT((min(numD, 65535)), 0));
1145 numS -= min(numS, 65535);
[362]1146 if (numS)
[748]1147 DosSleep(1);
[2]1148 }
1149 }
1150
1151 free(pciSa);
1152 free(pciDa);
1153 DosPostEventSem(CompactSem);
1154}
1155
[551]1156struct SS
1157{
1158 PCNRITEM pci;
1159 BOOL unique, all, smallest, largest, newest, oldest;
[2]1160};
1161
[551]1162struct Cnr
1163{
1164 HWND hwndCnr;
1165 ULONG numfiles;
[2]1166 struct SS *ss;
1167};
1168
[551]1169static int CompSSNamesB(const void *s1, const void *s2)
[317]1170{
[2]1171 struct SS *ss2 = (struct SS *)s2;
1172
[748]1173 return stricmp((PSZ)s1, ss2->pci->pszFileName);
[2]1174}
1175
[551]1176static int CompSSNames(const void *s1, const void *s2)
[317]1177{
[2]1178 struct SS *ss1 = (struct SS *)s1;
1179 struct SS *ss2 = (struct SS *)s2;
1180
[551]1181 return stricmp(ss1->pci->pszFileName, ss2->pci->pszFileName);
[2]1182}
1183
[551]1184VOID FreeCnrs(struct Cnr * Cnrs, INT numw)
[317]1185{
[2]1186 register INT z;
1187
[551]1188 for (z = 0; z < numw; z++) {
[362]1189 if (Cnrs[z].ss)
[2]1190 free(Cnrs[z].ss);
1191 }
1192 free(Cnrs);
1193 DosPostEventSem(CompactSem);
1194}
1195
[762]1196/**
1197 * Do select actions for single container
1198 *
1199 */
1200
[551]1201VOID SpecialSelect2(HWND hwndParent, INT action)
[317]1202{
[551]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;
[2]1209
[362]1210 if (!hwndParent)
[2]1211 return;
1212
1213 /* count directory containers, build array of hwnds */
1214 henum = WinBeginEnumWindows(hwndParent);
[362]1215 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE) {
[551]1216 if (WinWindowFromID(WinWindowFromID(hwnd, FID_CLIENT), DIR_CNR)) {
1217 Cnrs =
1218 xrealloc(Cnrs, (numwindows + 1) * sizeof(struct Cnr), pszSrcFile,
1219 __LINE__);
[362]1220 if (!Cnrs) {
[551]1221 Notify(GetPString(IDS_OUTOFMEMORY));
1222 return;
[2]1223 }
[551]1224 memset(&Cnrs[numwindows], 0, sizeof(struct Cnr));
[2]1225 Cnrs[numwindows].hwndCnr = WinWindowFromID(WinWindowFromID(hwnd,
[551]1226 FID_CLIENT),
1227 DIR_CNR);
[2]1228 numwindows++;
1229 }
1230 }
1231 WinEndEnumWindows(henum);
[362]1232 if (numwindows < 2) {
[551]1233 FreeCnrs(Cnrs, numwindows);
[362]1234 Runtime_Error(pszSrcFile, __LINE__, "expected two windows");
[2]1235 Notify(GetPString(IDS_COMPSEL2ORMORETEXT));
1236 return;
1237 }
[362]1238 if (numwindows > 4) {
[2]1239 WinSendMsg(Cnrs[0].
[551]1240 hwndCnr,
1241 UM_NOTIFY, MPFROMP(GetPString(IDS_BUILDINGLISTSTEXT)), MPVOID);
[748]1242 DosSleep(1);
[2]1243 }
1244
1245 /* count records, build array of pointers to records */
[551]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));
[2]1251 x = 0;
[748]1252 while (pci && (INT)pci != -1) {
1253 if (~pci->rc.flRecordAttr & CRA_FILTERED &&
1254 ~pci->attrFile & FILE_DIRECTORY) {
[551]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++;
[2]1266 }
[551]1267 pci = (PCNRITEM) WinSendMsg(Cnrs[z].hwndCnr,
1268 CM_QUERYRECORD,
1269 MPFROMP(pci),
1270 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]1271 }
[748]1272 DosSleep(1);
[2]1273 Cnrs[z].numfiles = x;
[362]1274 if (Cnrs[z].numfiles)
[551]1275 qsort(Cnrs[z].ss, Cnrs[z].numfiles, sizeof(struct SS), CompSSNames);
[2]1276 }
1277
[551]1278 for (z = 0; z < numwindows; z++) {
1279 for (x = 0; x < Cnrs[z].numfiles; x++) {
[2]1280 Cnrs[z].ss[x].all = Cnrs[z].ss[x].unique = Cnrs[z].ss[x].newest =
[551]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 }
[2]1376 }
[362]1377 if (Cnrs[z].ss[x].unique)
[551]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;
[748]1380 DosSleep(1);
[2]1381 }
[766]1382 DosSleep(1);
[2]1383 }
1384
[551]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));
[2]1393 }
[748]1394 DosSleep(1);
[551]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));
[2]1404 }
[748]1405 DosSleep(1);
[551]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));
[2]1415 }
[748]1416 DosSleep(1);
[551]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));
[2]1426 }
[748]1427 DosSleep(1);
[551]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));
[2]1437 }
[748]1438 DosSleep(1);
[551]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));
[2]1448 }
[748]1449 DosSleep(1);
[551]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));
[2]1459 }
[748]1460 DosSleep(1);
[551]1461 }
1462 break;
[2]1463
[551]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));
[2]1471 }
[748]1472 DosSleep(1);
[551]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));
[2]1482 }
[748]1483 DosSleep(1);
[551]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));
[2]1493 }
[748]1494 DosSleep(1);
[551]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));
[2]1504 }
[748]1505 DosSleep(1);
[551]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));
[2]1515 }
[748]1516 DosSleep(1);
[551]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));
[2]1526 }
[748]1527 DosSleep(1);
[551]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));
[2]1537 }
[748]1538 DosSleep(1);
[551]1539 }
1540 break;
[2]1541 }
1542
[551]1543 FreeCnrs(Cnrs, numwindows);
[2]1544}
Note: See TracBrowser for help on using the repository browser.