source: trunk/dll/comp.c@ 1065

Last change on this file since 1065 was 1065, checked in by John Small, 17 years ago

Ticket 230: Simplified code and eliminated some local variables by incorporating
all the details view settings (both the global variables and those in the
DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 99.8 KB
RevLine 
[76]1
2/***********************************************************************
3
4 $Id: comp.c 1065 2008-07-11 16:50:19Z jbs $
5
6 Compare directories
7
8 Copyright (c) 1993-02 M. Kimes
[907]9 Copyright (c) 2003, 2008 Steven H. Levine
[76]10
[145]11 16 Oct 02 MK Baseline
12 04 Nov 03 SHL Force window refresh after subdir toggle
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 24 May 05 SHL Rework Win_Error usage
[157]15 24 May 05 SHL Rework for CNRITEM.szSubject
16 25 May 05 SHL Rework with ULONGLONG
[199]17 06 Jun 05 SHL Drop unused
[362]18 12 Jul 06 SHL Renames and comments
19 13 Jul 06 SHL Use Runtime_Error
[366]20 26 Jul 06 SHL Drop unreachable CN_... code
[406]21 29 Jul 06 SHL Use xfgets_bstripcr
[448]22 15 Aug 06 SHL Turn off hide not selected on dir change
[517]23 19 Oct 06 SHL Correct . and .. detect
[535]24 03 Nov 06 SHL Count thread usage
[574]25 22 Mar 07 GKY Use QWL_USER
[742]26 29 Jul 07 SHL Use Win_Error to report container errors
[748]27 01 Aug 07 SHL Rework to sync with CNRITEM mods
28 01 Aug 07 SHL Rework to remove vast amount of duplicate code
[756]29 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[773]30 06 Aug 07 SHL Move BldFullPathName here to be near primary caller
31 07 Aug 07 SHL COMP_COLLECT: Avoid collecting empty entries when nothing selected
[775]32 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]33 13 Aug 07 SHL Sync code with other FilesToGet usage
34 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
[790]35 20 Aug 07 SHL Correct remaining pcil/pcir typos (we hope)
36 20 Aug 07 SHL Revert to DosSleep(0)
37 20 Aug 07 SHL Use GetMSecTimer for timing
[846]38 20 Aug 07 SHL A few more speed up tweaks. Some experimental timing code
[814]39 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
[846]40 27 Sep 07 SHL Correct ULONGLONG size formatting
[897]41 30 Dec 07 GKY Use TestCDates for compare by file date/time
[907]42 04 Jan 08 SHL Avoid traps if CM_ALLOCRECORD returns less that requested
43 05 Jan 08 SHL Use WM_TIMER for progress messaging
44 05 Jan 08 SHL Use ITIMER_DESC for hogging control
[919]45 12 Jan 08 SHL Correct select count display regression
[924]46 12 Jan 08 SHL Localize SpecialSelect here and rename
47 12 Jan 08 SHL Use SleepIfNeeded
48 12 Jan 08 SHL Reduce/eliminate more DosSleep calls
[929]49 16 Jan 08 SHL Update total/select counts with WM_TIMER only
50 17 Jan 08 SHL Change hide not selected button to 3 state
51 18 Jan 08 SHL Honor filters in actions
[938]52 20 Jan 08 GKY Compare dialog now saves and restores size and position
[985]53 29 Feb 08 GKY Use xfree where appropriate
54 29 Feb 08 GKY Refactor global command line variables to notebook.h
[1000]55 16 Mar 08 GKY Prevent trap caused by files that exceed maxpath length
[1065]56 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
57 all the details view settings (both the global variables and those in the
58 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
[76]59
60***********************************************************************/
61
[907]62#include <stdlib.h>
63#include <string.h>
64#include <share.h>
65#include <io.h>
66#include <process.h> // _beginthread
67
[2]68#define INCL_DOS
69#define INCL_WIN
[783]70#define INCL_DOSERRORS
[2]71#define INCL_GPI
[157]72#define INCL_LONGLONG
[2]73
74#include "fm3dlg.h"
75#include "fm3str.h"
[907]76#include "pathutil.h" // BldFullPathName
77#include "filldir.h" // EmptyCnr...
78#include "makelist.h" // AddToFileList...
79#include "errutil.h" // Dos_Error...
80#include "strutil.h" // GetPString
81#include "tmrsvcs.h" // IsITimerExpired
82#include "comp.h"
83#include "fm3dll.h"
[985]84#include "notebook.h" // External compare/dircompare
[2]85
[1009]86#include "fortify.h" // 06 May 08 SHL
87
[551]88typedef struct
89{
90 CHAR filename[CCHMAXPATH];
91 CHAR dirname[CCHMAXPATH];
92 BOOL recurse;
93}
94SNAPSTUFF;
[2]95
[362]96static PSZ pszSrcFile = __FILE__;
97
[316]98//=== SnapShot() Write directory tree to file and recurse if requested ===
[2]99
[783]100static VOID SnapShot(char *path, FILE *fp, BOOL recurse)
[157]101{
[841]102 PFILEFINDBUF4L pffb;
[551]103 char *mask, *enddir;
104 HDIR hdir = HDIR_CREATE;
[783]105 ULONG ulFindCnt;
[2]106
[783]107 // 13 Aug 07 SHL fimxe to use FileToGet
[841]108 pffb = xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
[783]109 if (pffb) {
[551]110 mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
111 if (mask) {
[783]112 BldFullPathName(mask, path, "*");
[551]113 enddir = strrchr(mask, '\\');
[2]114 enddir++;
[783]115 ulFindCnt = 1;
116 // 13 Aug 07 SHL fixme to report errors
[838]117 if (!xDosFindFirst(mask,
[907]118 &hdir,
[838]119 FILE_NORMAL | FILE_DIRECTORY |
120 FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN |
121 FILE_SYSTEM,
[841]122 pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL)) {
[551]123 do {
[783]124 strcpy(enddir, pffb->achName);
125 if (!(pffb->attrFile & FILE_DIRECTORY))
[846]126 // 27 Sep 07 SHL fixme to use CommaFmtULL
[551]127 fprintf(fp,
[846]128 "\"%s\",%u,%llu,%04u/%02u/%02u,%02u:%02u:%02u,%lu,%lu,N\n",
[551]129 mask,
130 enddir - mask,
[783]131 pffb->cbFile,
132 (pffb->fdateLastWrite.year + 1980),
133 pffb->fdateLastWrite.month,
134 pffb->fdateLastWrite.day,
135 pffb->ftimeLastWrite.hours,
136 pffb->ftimeLastWrite.minutes,
137 pffb->ftimeLastWrite.twosecs,
[846]138 pffb->attrFile,
139 pffb->cbList > 4 ? pffb->cbList / 2 : 0);
[517]140 // Skip . and ..
[551]141 else if (recurse &&
[783]142 (pffb->achName[0] != '.' ||
143 (pffb->achName[1] &&
144 (pffb->achName[1] != '.' || pffb->achName[2])))) {
[551]145 SnapShot(mask, fp, recurse);
146 }
[783]147 ulFindCnt = 1;
[850]148 } while (!xDosFindNext(hdir, pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL));
[551]149 DosFindClose(hdir);
[2]150 }
[1039]151 free(mask);
[2]152 }
[1039]153 free(pffb);
[2]154 }
155}
156
[316]157//=== StartSnap() Write directory tree to snapshot file ===
[2]158
[919]159static VOID StartSnap(VOID *pargs)
[316]160{
[919]161 SNAPSTUFF *sf = (SNAPSTUFF *)pargs;
[551]162 FILE *fp;
163 CHAR *p;
[2]164
[551]165 if (sf) {
166 if (*sf->dirname && *sf->filename) {
[2]167 priority_normal();
168 p = sf->dirname;
[551]169 while (*p) {
170 if (*p == '/')
171 *p = '\\';
172 p++;
[2]173 }
[551]174 if (*(p - 1) != '\\') {
175 *p = '\\';
176 p++;
[2]177 }
[551]178 fp = xfopen(sf->filename, "w", pszSrcFile, __LINE__);
[362]179 if (fp) {
[551]180 fprintf(fp, "\"%s\"\n", sf->dirname);
181 SnapShot(sf->dirname, fp, sf->recurse);
182 fclose(fp);
[2]183 }
184 }
[1039]185 free(sf);
[2]186 }
187}
188
[316]189//=== CompareFilesThread() Compare files and update container select flags ===
[2]190
[919]191static VOID CompareFilesThread(VOID *args)
[316]192{
[2]193 FCOMPARE fc;
[551]194 HAB hab2;
195 HMQ hmq2;
196 FILE *fp1, *fp2;
[847]197 ULONG len1, len2;
[841]198 ULONG offset = 0;
[551]199 LONG numread1, numread2;
200 CHAR s[1024], ss[1024], *p1, *p2;
[2]201
[551]202 if (args) {
[919]203 fc = *(FCOMPARE *)args;
[2]204 hab2 = WinInitialize(0);
[551]205 if (hab2) {
[1063]206# ifdef FORTIFY
207 Fortify_EnterScope();
208# endif
[1038]209 hmq2 = WinCreateMsgQueue(hab2, 0);
210 if (hmq2) {
[551]211 WinCancelShutdown(hmq2, TRUE);
[535]212 IncrThreadUsage();
[551]213 if (!IsFile(fc.file1) || IsRoot(fc.file1)) {
214 p1 = strrchr(fc.file2, '\\');
215 if (p1) {
216 if (fc.file1[strlen(fc.file1) - 1] == '\\')
217 p1++;
218 strcat(fc.file1, p1);
219 }
[362]220 }
[551]221 else if (!IsFile(fc.file2) || IsRoot(fc.file2)) {
222 p1 = strrchr(fc.file1, '\\');
223 if (p1) {
224 if (fc.file2[strlen(fc.file2) - 1] == '\\')
225 p1++;
226 strcat(fc.file2, p1);
227 }
228 }
229 sprintf(s, GetPString(IDS_COMPCOMPARETEXT), fc.file1);
230 AddToListboxBottom(fc.hwndList, s);
231 sprintf(s, GetPString(IDS_COMPTOTEXT), fc.file2);
232 AddToListboxBottom(fc.hwndList, s);
233 fp1 = _fsopen(fc.file1, "rb", SH_DENYNO);
234 if (!fp1) {
235 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file1);
236 AddToListboxBottom(fc.hwndList, s);
237 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
238 }
[362]239 else {
[551]240 fp2 = _fsopen(fc.file2, "rb", SH_DENYNO);
241 if (!fp2) {
242 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file2);
243 AddToListboxBottom(fc.hwndList, s);
244 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
[362]245 }
246 else {
[847]247 len1 = filelength(fileno(fp1));
248 len2 = filelength(fileno(fp2));
[551]249 if (len1 != len2) {
250 strcpy(s, GetPString(IDS_COMPDIFSIZESTEXT));
251 AddToListboxBottom(fc.hwndList, s);
252 sprintf(s, GetPString(IDS_COMPVSBYTESTEXT), len1, len2);
253 AddToListboxBottom(fc.hwndList, s);
254 WinSetWindowText(fc.hwndHelp,
255 GetPString(IDS_COMPDONTMATCHTEXT));
256 }
257 else {
258 WinSetWindowText(fc.hwndHelp,
259 GetPString(IDS_COMPCOMPARINGTEXT));
260 while (WinIsWindow(hab2, fc.hwndList)) {
261 numread1 = fread(s, 1, 1024, fp1);
262 numread2 = fread(ss, 1, 1024, fp2);
263 if (numread1 != numread2 || feof(fp1) != feof(fp2)) {
264 sprintf(s, GetPString(IDS_COMPREADERRORTEXT),
265 offset, offset);
266 AddToListboxBottom(fc.hwndList, s);
267 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
268 break;
269 }
270 else if (!numread1 && feof(fp1) && feof(fp2)) {
271 AddToListboxBottom(fc.hwndList,
272 GetPString(IDS_COMPFILESMATCHTEXT));
273 if (!stricmp(fc.file1, fc.file2))
274 AddToListboxBottom(fc.hwndList,
275 GetPString(IDS_COMPWONDERWHYTEXT));
276 WinSetWindowText(fc.hwndHelp,
277 GetPString(IDS_COMPCOMPLETETEXT));
278 break;
279 }
280 else if (numread1 <= 0 || numread2 <= 0) {
281 if (offset == len1)
282 break;
283 else {
284 sprintf(s, GetPString(IDS_COMPMATCHREADERRORTEXT),
285 offset, offset);
286 WinSetWindowText(fc.hwndHelp,
287 GetPString(IDS_COMPODDERRORTEXT));
288 AddToListboxBottom(fc.hwndList, s);
289 break;
290 }
291 }
292 else if (memcmp(s, ss, numread1)) {
293 p1 = s;
294 p2 = ss;
295 while (p1 < s + numread1) {
296 if (*p1 != *p2) {
297 sprintf(s, GetPString(IDS_COMPMISMATCHERRORTEXT),
298 offset + (p1 - s), offset + (p1 - s));
299 AddToListboxBottom(fc.hwndList, s);
300 WinSetWindowText(fc.hwndHelp,
301 GetPString(IDS_COMPDONTMATCHTEXT));
302 break;
303 }
304 p1++;
305 p2++;
306 }
307 break;
308 }
309 offset += numread1;
310 }
311 }
312 fclose(fp2);
313 }
314 fclose(fp1);
315 }
[535]316 DecrThreadUsage();
[551]317 WinDestroyMsgQueue(hmq2);
[2]318 }
319 WinTerminate(hab2);
[1063]320# ifdef FORTIFY
[1038]321 Fortify_LeaveScope();
[1063]322# endif
[2]323 }
324 }
325}
326
[316]327//=== CFileDlgProc() Select directories to compare dialog procedure ===
[2]328
[551]329MRESULT EXPENTRY CFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[316]330{
[2]331 FCOMPARE *fc;
332
[551]333 switch (msg) {
334 case WM_INITDLG:
335 if (!mp2)
336 WinDismissDlg(hwnd, 0);
337 else {
[574]338 WinSetWindowPtr(hwnd, QWL_USER, mp2);
[919]339 fc = (FCOMPARE *)mp2;
[551]340 fc->hwndReport = hwnd;
341 fc->hwndList = WinWindowFromID(hwnd, FCMP_LISTBOX);
342 fc->hwndHelp = WinWindowFromID(hwnd, FCMP_HELP);
343 if (!*fc->file1 || !fc->file2) {
344 WinDismissDlg(hwnd, 0);
345 break;
[2]346 }
[551]347 MakeFullName(fc->file1);
348 MakeFullName(fc->file2);
349 if (!stricmp(fc->file1, fc->file2)) {
350 saymsg(MB_CANCEL, hwnd,
351 GetPString(IDS_COMPSILLYALERTTEXT),
352 GetPString(IDS_COMPTOITSELFTEXT));
353 WinDismissDlg(hwnd, 0);
354 break;
355 }
[919]356 if (_beginthread(CompareFilesThread, NULL, 65536, (PVOID)fc) == -1) {
[551]357 Runtime_Error(pszSrcFile, __LINE__,
358 GetPString(IDS_COULDNTSTARTTHREADTEXT));
359 WinDismissDlg(hwnd, 0);
360 }
361 }
362 break;
[2]363
[551]364 case WM_ADJUSTWINDOWPOS:
365 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
366 break;
[2]367
[551]368 case UM_SETDIR:
369 PaintRecessedWindow(WinWindowFromID(hwnd, FCMP_HELP),
[919]370 (HPS)0, FALSE, TRUE);
[551]371 return 0;
[2]372
[551]373 case WM_COMMAND:
374 switch (SHORT1FROMMP(mp1)) {
375 case DID_OK:
376 WinDismissDlg(hwnd, 0);
377 break;
378 case DID_CANCEL:
379 WinDismissDlg(hwnd, 1);
380 break;
381 }
382 return 0;
[2]383
[551]384 case WM_DESTROY:
[924]385 DosSleep(50); // Let others die first
[551]386 break;
[2]387 }
[551]388 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]389}
390
[316]391//=== ActionCnrThread() Do requested action on container contents ===
[2]392
[731]393static VOID ActionCnrThread(VOID *args)
[316]394{
[731]395 COMPARE *cmp = (COMPARE *)args;
[551]396 HAB hab;
397 HMQ hmq;
398 HWND hwndCnrS, hwndCnrD;
[924]399 PCNRITEM pciS, pciD, pciNextS, pciNextD;
[769]400 CHAR szNewName[CCHMAXPATH], szDirName[CCHMAXPATH], *p;
[551]401 APIRET rc;
[924]402 ITIMER_DESC itdSleep = { 0 };
[2]403
[748]404 if (!cmp) {
[773]405 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
[2]406 return;
[748]407 }
[2]408
409 DosError(FERR_DISABLEHARDERR);
410
411 hab = WinInitialize(0);
[551]412 if (hab) {
[1063]413# ifdef FORTIFY
414 Fortify_EnterScope();
415# endif
[1038]416 hmq = WinCreateMsgQueue(hab, 0);
417 if (hmq) {
[551]418 WinCancelShutdown(hmq, TRUE);
[535]419 IncrThreadUsage();
[2]420 priority_normal();
[551]421 switch (cmp->action) {
422 case COMP_DELETELEFT:
423 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
424 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
425 cmp->action = IDM_DELETE;
426 break;
427 case COMP_DELETERIGHT:
428 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
429 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
430 cmp->action = IDM_DELETE;
431 break;
432 case COMP_MOVELEFT:
433 cmp->action = IDM_MOVE;
434 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
435 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
436 break;
437 case COMP_MOVERIGHT:
438 cmp->action = IDM_MOVE;
439 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
440 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
441 break;
442 case COMP_COPYLEFT:
443 cmp->action = IDM_COPY;
444 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
445 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
446 break;
447 case COMP_COPYRIGHT:
448 cmp->action = IDM_COPY;
449 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
450 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
451 break;
452 default:
453 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", cmp->action);
454 goto Abort;
[2]455 }
456
[924]457 pciS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
[551]458 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]459 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
[551]460 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[316]461
[924]462 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
[907]463
[924]464 while (pciS && (INT)pciS != -1 && pciD && (INT)pciD != -1) {
[748]465
[924]466 pciNextS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
[551]467 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]468 pciNextD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
[551]469 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]470
[929]471 // Process file if selected and not filtered
472 if (*pciS->pszFileName &&
473 pciS->rc.flRecordAttr & CRA_SELECTED &&
474 ~pciS->rc.flRecordAttr & CRA_FILTERED)
475 {
[748]476 // Source name not blank
[551]477 switch (cmp->action) {
478 case IDM_DELETE:
[924]479 if (!unlinkf("%s", pciS->pszFileName)) {
480 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
[551]481 MPFROM2SHORT(FALSE, CRA_SELECTED));
[748]482
483 if (!*pciD->pszFileName) {
[751]484 // Other side is blank - remove from both sides
[924]485 RemoveCnrItems(hwndCnrS, pciS, 1, CMA_FREE | CMA_INVALIDATE);
[748]486 if (pciD->rc.flRecordAttr & CRA_SELECTED)
487 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
[551]488 MPFROM2SHORT(FALSE, CRA_SELECTED));
[751]489 RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
[551]490 }
[742]491 else {
[751]492 // Other side is not blank - update just this side
[924]493 FreeCnrItemData(pciS);
494 pciS->pszDisplayName = pciS->pszFileName;
495 pciS->rc.pszIcon = pciS->pszFileName;
496 pciS->flags = 0; // Just on one side
497 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
[551]498 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[924]499 pciD->flags = 0; // Just on one side
[929]500 if (pciD->pszSubject != NullStr) {
[1009]501 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
[924]502 pciD->pszSubject = NullStr;
[929]503 }
[551]504 }
505 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
506 cmp->cmp->totalleft--;
507 else
508 cmp->cmp->totalright--;
509 }
510 break;
[2]511
[551]512 case IDM_MOVE:
513 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
[924]514 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
[769]515 else
[924]516 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
[748]517 // Make directory if required
[769]518 strcpy(szDirName, szNewName);
519 p = strrchr(szDirName, '\\');
[551]520 if (p) {
[769]521 if (p > szDirName + 2)
[551]522 p++;
523 *p = 0;
[769]524 if (IsFile(szDirName) == -1)
525 MassMkdir(hwndMain, szDirName);
[551]526 }
[924]527 rc = docopyf(MOVE, pciS->pszFileName, "%s", szNewName);
528 if (!rc && stricmp(pciS->pszFileName, szNewName)) {
529 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
[551]530 MPFROM2SHORT(FALSE, CRA_SELECTED));
[748]531 if (pciD->rc.flRecordAttr & CRA_SELECTED)
532 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
[551]533 MPFROM2SHORT(FALSE, CRA_SELECTED));
[748]534 FreeCnrItemData(pciD);
[769]535 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
[551]536 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
[748]537 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
[551]538 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
[751]539 pciD->pszDisplayName++;
[551]540 }
541 else {
[748]542 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
[551]543 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
[751]544 pciD->pszDisplayName++;
[742]545 }
[769]546 // 02 Aug 07 SHL fixme to know if LongName transfer is correct?
[924]547 pciD->pszLongName = pciS->pszLongName;
[751]548 if (pciD->pszSubject != NullStr) {
[1009]549 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
[751]550 pciD->pszSubject = NullStr;
551 }
[924]552 pciD->attrFile = pciS->attrFile;
553 pciD->pszDispAttr = pciS->pszDispAttr;
[769]554 pciD->flags = 0; // Just on one side
[924]555 pciD->date = pciS->date;
556 pciD->time = pciS->time;
557 pciD->ladate = pciS->ladate;
558 pciD->latime = pciS->latime;
559 pciD->crdate = pciS->crdate;
560 pciD->crtime = pciS->crtime;
561 pciD->cbFile = pciS->cbFile;
562 pciD->easize = pciS->easize;
[751]563
[924]564 if (pciS->pszFileName != NullStr) {
[1009]565 xfree(pciS->pszFileName, pszSrcFile, __LINE__);
[924]566 pciS->pszFileName = NullStr;
567 pciS->pszDisplayName = pciS->pszFileName;
568 pciS->rc.pszIcon = pciS->pszFileName;
[751]569 }
[924]570 if (pciS->pszSubject != NullStr) {
[1009]571 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
[924]572 pciS->pszSubject = NullStr;
[751]573 }
[924]574 pciS->flags = 0; // Just on one side
[751]575
[924]576 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
[551]577 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[924]578
[748]579 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
[551]580 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[924]581
582 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
583 cmp->cmp->totalleft--;
584 else
585 cmp->cmp->totalright--;
[551]586 }
587 else if (rc) {
588 rc = Dos_Error(MB_ENTERCANCEL,
589 rc,
590 HWND_DESKTOP,
591 pszSrcFile,
592 __LINE__,
593 GetPString(IDS_COMPMOVEFAILEDTEXT),
[924]594 pciS->pszFileName, szNewName);
[748]595 if (rc == MBID_CANCEL) // Cause loop to break
596 pciNextS = NULL;
[551]597 }
598 break;
[2]599
[551]600 case IDM_COPY:
[769]601 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
[924]602 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
[769]603 else
[924]604 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
[748]605 // Make directory if required
[769]606 strcpy(szDirName, szNewName);
607 p = strrchr(szDirName, '\\');
[551]608 if (p) {
[769]609 if (p > szDirName + 2)
[551]610 p++;
611 *p = 0;
[769]612 if (IsFile(szDirName) == -1)
613 MassMkdir(hwndMain, szDirName);
[551]614 }
[924]615 rc = docopyf(COPY, pciS->pszFileName, "%s", szNewName);
[551]616 if (rc) {
617 rc = Dos_Error(MB_ENTERCANCEL,
618 rc,
619 HWND_DESKTOP,
620 pszSrcFile,
621 __LINE__,
622 GetPString(IDS_COMPCOPYFAILEDTEXT),
[924]623 pciS->pszFileName, szNewName);
[551]624 if (rc == MBID_CANCEL)
[748]625 pciNextS = NULL; // Cause loop to break
[551]626 }
627 else {
[924]628 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
[551]629 MPFROM2SHORT(FALSE, CRA_SELECTED));
[748]630 if (pciD->rc.flRecordAttr & CRA_SELECTED)
631 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
[551]632 MPFROM2SHORT(FALSE, CRA_SELECTED));
[924]633 // 12 Jan 08 SHL
634 if (pciD->pszFileName == NullStr) {
635 if (hwndCnrD == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
636 cmp->totalleft++;
637 else
638 cmp->totalright++;
639 }
[748]640 FreeCnrItemData(pciD);
[769]641 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
[551]642 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
[748]643 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
[551]644 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
[751]645 pciD->pszDisplayName++;
[362]646 }
647 else {
[748]648 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
[551]649 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
[751]650 pciD->pszDisplayName++;
[742]651 }
[924]652 pciD->attrFile = pciS->attrFile;
653 pciD->pszDispAttr = pciS->pszDispAttr;
[769]654 pciD->flags = CNRITEM_EXISTS; // Now on both sides
[924]655 pciD->date = pciS->date;
656 pciD->time = pciS->time;
657 pciD->ladate = pciS->ladate;
658 pciD->latime = pciS->latime;
659 pciD->crdate = pciS->crdate;
660 pciD->crtime = pciS->crtime;
661 pciD->cbFile = pciS->cbFile;
662 pciD->easize = pciS->easize;
[751]663
[769]664 // Forget status until we regenerate it
[924]665 if (pciS->pszSubject != NullStr) {
[1009]666 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
[924]667 pciS->pszSubject = NullStr;
[751]668 }
[924]669 pciS->flags = CNRITEM_EXISTS; // Now on both sides
[751]670
[924]671 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
[551]672 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[748]673 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
[551]674 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
675 }
676 break;
[2]677
[551]678 default:
679 break;
[748]680 } // switch
681
682 } // if have name
683
[924]684 pciS = pciNextS;
[748]685 pciD = pciNextD;
686
[924]687 SleepIfNeeded(&itdSleep, 0);
[748]688 } // while
[929]689 WinPostMsg(cmp->hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
[551]690 Abort:
[2]691 WinDestroyMsgQueue(hmq);
692 }
[929]693 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1), MPVOID);
694 // PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID); // 18 Jan 08 SHL we can count now
[535]695 DecrThreadUsage();
[1039]696 free(cmp);
[2]697 WinTerminate(hab);
[1063]698# ifdef FORTIFY
[1038]699 Fortify_LeaveScope();
[1063]700# endif
[2]701 }
[1032]702 else
703 xfree(cmp, pszSrcFile, __LINE__);
[2]704}
705
[929]706VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, BOOL reset);
[924]707
[316]708//=== SelectCnrsThread() Update container selection flags thread ===
[2]709
[919]710static VOID SelectCnrsThread(VOID *args)
[316]711{
[919]712 COMPARE *cmp = (COMPARE *)args;
[551]713 HAB hab;
714 HMQ hmq;
[2]715
[783]716 if (!cmp) {
717 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]718 return;
[783]719 }
[2]720
721 DosError(FERR_DISABLEHARDERR);
722
723 hab = WinInitialize(0);
[551]724 if (hab) {
[1063]725# ifdef FORTIFY
726 Fortify_EnterScope();
727# endif
[1038]728 hmq = WinCreateMsgQueue(hab, 0);
729 if (hmq) {
[551]730 WinCancelShutdown(hmq, TRUE);
[535]731 IncrThreadUsage();
[2]732 priority_normal();
[551]733 switch (cmp->action) {
734 case IDM_INVERT:
735 InvertAll(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
736 InvertAll(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
737 break;
[2]738
[551]739 case IDM_DESELECTALL:
740 Deselect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
741 Deselect(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
742 break;
[2]743
[551]744 default:
[924]745 // 13 Jan 08 SHL fixme to decide if cmp->reset can ever get set
746 // if not lots of code can disappear
747 if (cmp->reset)
748 DbgMsg(pszSrcFile, __LINE__, "cmp->reset is TRUE");
749 CompSelect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR),
750 WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR),
[929]751 cmp->hwnd,
752 cmp->action,
753 cmp->reset);
[551]754 break;
[2]755 }
[551]756 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID))
757 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
[2]758 WinDestroyMsgQueue(hmq);
759 }
[535]760 DecrThreadUsage();
[1039]761 free(cmp);
[2]762 WinTerminate(hab);
[1063]763# ifdef FORTIFY
[1038]764 Fortify_LeaveScope();
[1063]765# endif
[2]766 }
[1032]767 else
[1039]768 free(cmp);
[2]769}
770
[748]771/**
[924]772 * Do select actions for compare directories containers
773 * @param action is select mode
774 * @param reset requests flags by regenerated
775 */
776
[929]777VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, BOOL reset)
[924]778{
779 PCNRITEM pciS, pciD, *pciSa = NULL, *pciDa = NULL;
780 CNRINFO cnri;
781 BOOL slow = FALSE;
782 UINT x, numD, numS;
783 INT ret = 0;
784 ITIMER_DESC itdSleep = { 0 };
[929]785 BOOL fUpdateHideButton = FALSE;
[924]786
787 if (!hwndCnrS || !hwndCnrD) {
788 Runtime_Error(pszSrcFile, __LINE__, "hwndCnrS %p hwndCnrD %p", hwndCnrS, hwndCnrD);
789 return;
790 }
791
792 memset(&cnri, 0, sizeof(CNRINFO));
793 cnri.cb = sizeof(CNRINFO);
794 WinSendMsg(hwndCnrD, CM_QUERYCNRINFO, MPFROMP(&cnri),
795 MPFROMLONG(sizeof(CNRINFO)));
796 numD = cnri.cRecords;
797 memset(&cnri, 0, sizeof(CNRINFO));
798 cnri.cb = sizeof(CNRINFO);
799 WinSendMsg(hwndCnrS, CM_QUERYCNRINFO, MPFROMP(&cnri),
800 MPFROMLONG(sizeof(CNRINFO)));
801 numS = cnri.cRecords;
802 if (!numD || numS != numD) {
803 Runtime_Error(pszSrcFile, __LINE__, "numD %u != numS %u", numD, numS);
804 return;
805 }
806
807 pciDa = xmalloc(sizeof(PCNRITEM) * numD, pszSrcFile, __LINE__);
808 if (!pciDa)
809 return;
810
811 pciSa = xmalloc(sizeof(PCNRITEM) * numS, pszSrcFile, __LINE__);
812 if (!pciSa) {
[1039]813 free(pciDa);
[924]814 return;
815 }
816
817 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
818
819Restart:
820
821 memset(pciDa, 0, sizeof(PCNRITEM) * numD);
822 memset(pciSa, 0, sizeof(PCNRITEM) * numS);
823
824 pciD = (PCNRITEM)WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
825 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
826 x = 0;
827 while (pciD && (INT)pciD != -1 && x < numD) {
828 if (reset)
829 pciD->flags = 0;
830 pciDa[x] = pciD;
831 x++;
832 if (!slow)
833 pciD = (PCNRITEM) pciD->rc.preccNextRecord;
834 else
835 pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
836 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
837 SleepIfNeeded(&itdSleep, 0);
838 } // while
839
840 if (numD != x) {
841 // Something out of sync - fixme to document why
842 if (!slow) {
843 slow = TRUE;
844 goto Restart;
845 }
[1039]846 free(pciDa);
847 free(pciSa);
[924]848 Runtime_Error(pszSrcFile, __LINE__, "numD %u != x %lu", numD, x);
849 return;
850 }
851
852 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
853 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
854 x = 0;
855 while (pciS && (INT)pciS != -1 && x < numS) {
856 if (reset)
857 pciS->flags = 0;
858 pciSa[x] = pciS;
859 x++;
860 if (!slow)
861 pciS = (PCNRITEM) pciS->rc.preccNextRecord;
862 else
863 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
864 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
865 SleepIfNeeded(&itdSleep, 0);
866 } // while
867
868 if (numS != x) {
869 if (!slow) {
870 slow = TRUE;
871 goto Restart;
872 }
[1039]873 free(pciSa);
874 free(pciDa);
[924]875 Runtime_Error(pszSrcFile, __LINE__, "numS (%lu) != x (%lu)", numS, x);
876 return;
877 }
878
879 if (reset) {
880 // Update flags for files that exist on both sides
881 for (x = 0; x < numS; x++) {
882
883 if (!*pciSa[x]->pszFileName || !*pciDa[x]->pszFileName) {
884 // 12 Jan 08 SHL clear flags
885 pciSa[x]->flags = 0; // File exists on one side only
886 pciDa[x]->flags = 0;
887 continue;
888 }
889
890 pciSa[x]->flags |= CNRITEM_EXISTS; // File exists on both sides
891 pciDa[x]->flags |= CNRITEM_EXISTS;
892 if (pciSa[x]->cbFile + pciSa[x]->easize >
893 pciDa[x]->cbFile + pciDa[x]->easize) {
894 pciSa[x]->flags |= CNRITEM_LARGER;
895 pciDa[x]->flags |= CNRITEM_SMALLER;
896 }
897 else if (pciSa[x]->cbFile + pciSa[x]->easize <
898 pciDa[x]->cbFile + pciDa[x]->easize) {
899 pciSa[x]->flags |= CNRITEM_SMALLER;
900 pciDa[x]->flags |= CNRITEM_LARGER;
901 }
902 ret = TestCDates(&pciDa[x]->date, &pciDa[x]->time,
903 &pciSa[x]->date, &pciSa[x]->time);
904 if (ret == 1)
905 /* 13 Jan 08 SHL fixme to be gone?
906 ((pciSa[x]->date.year > pciDa[x]->date.year) ? TRUE :
907 (pciSa[x]->date.year < pciDa[x]->date.year) ? FALSE :
908 (pciSa[x]->date.month > pciDa[x]->date.month) ? TRUE :
909 (pciSa[x]->date.month < pciDa[x]->date.month) ? FALSE :
910 (pciSa[x]->date.day > pciDa[x]->date.day) ? TRUE :
911 (pciSa[x]->date.day < pciDa[x]->date.day) ? FALSE :
912 (pciSa[x]->time.hours > pciDa[x]->time.hours) ? TRUE :
913 (pciSa[x]->time.hours < pciDa[x]->time.hours) ? FALSE :
914 (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? TRUE :
915 (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? FALSE :
916 (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? TRUE :
917 (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? FALSE : FALSE)
918 */
919 {
920 pciSa[x]->flags |= CNRITEM_NEWER;
921 pciDa[x]->flags |= CNRITEM_OLDER;
922 }
923 else if (ret == -1)
924 /* 13 Jan 08 SHL fixme to be gone?
925 ((pciSa[x]->date.year < pciDa[x]->date.year) ? TRUE :
926 (pciSa[x]->date.year > pciDa[x]->date.year) ? FALSE :
927 (pciSa[x]->date.month < pciDa[x]->date.month) ? TRUE :
928 (pciSa[x]->date.month > pciDa[x]->date.month) ? FALSE :
929 (pciSa[x]->date.day < pciDa[x]->date.day) ? TRUE :
930 (pciSa[x]->date.day > pciDa[x]->date.day) ? FALSE :
931 (pciSa[x]->time.hours < pciDa[x]->time.hours) ? TRUE :
932 (pciSa[x]->time.hours > pciDa[x]->time.hours) ? FALSE :
933 (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? TRUE :
934 (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? FALSE :
935 (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? TRUE :
936 (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? FALSE :
937 FALSE)
938 */
939 {
940 pciSa[x]->flags |= CNRITEM_OLDER;
941 pciDa[x]->flags |= CNRITEM_NEWER;
942 }
943 SleepIfNeeded(&itdSleep, 0);
944 } // for
945 } // if reset
946
947 switch (action) {
948 case IDM_SELECTIDENTICAL:
949 for (x = 0; x < numS; x++) {
950 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
951 pciSa[x]->flags & CNRITEM_EXISTS &&
952 ~pciSa[x]->flags & CNRITEM_SMALLER &&
953 ~pciSa[x]->flags & CNRITEM_LARGER &&
954 ~pciSa[x]->flags & CNRITEM_NEWER &&
955 ~pciSa[x]->flags & CNRITEM_OLDER) {
956 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
957 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
958 MPFROM2SHORT(TRUE, CRA_SELECTED));
959 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
960 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
961 MPFROM2SHORT(TRUE, CRA_SELECTED));
962 }
963 SleepIfNeeded(&itdSleep, 0);
964 } // for
965 break;
966
967 case IDM_SELECTSAME:
968 for (x = 0; x < numS; x++) {
969 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
970 pciSa[x]->flags & CNRITEM_EXISTS &&
971 ~pciSa[x]->flags & CNRITEM_SMALLER &&
972 ~pciSa[x]->flags & CNRITEM_LARGER) {
973 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
974 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
975 MPFROM2SHORT(TRUE, CRA_SELECTED));
976 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
977 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
978 MPFROM2SHORT(TRUE, CRA_SELECTED));
979 }
980 SleepIfNeeded(&itdSleep, 0);
981 } // for
982 break;
983
984 case IDM_SELECTSAMECONTENT:
985 for (x = 0; x < numS; x++) {
986 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
987 pciSa[x]->flags & CNRITEM_EXISTS)
988 {
989 FILE *fp1 = NULL;
990 FILE *fp2 = NULL;
991 BOOL gotMatch = FALSE;
992 UINT errLineNo = 0;
993 UINT compErrno = 0;
994 CHAR buf1[1024];
995 CHAR buf2[1024];
996 HAB hab = WinQueryAnchorBlock(hwndCnrS);
997
998 if (!*pciSa[x]->pszFileName ||
999 !*pciDa[x]->pszFileName) {
1000 Runtime_Error(pszSrcFile, __LINE__,
1001 "CNRITEM_EXISTS set with null file name for index %u", x);
1002 break;
1003 }
1004
1005 fp1 = _fsopen(pciSa[x]->pszFileName, "rb", SH_DENYNO);
1006 if (!fp1) {
1007 errLineNo = __LINE__;
1008 compErrno = errno;
1009 }
1010 else {
1011 fp2 = _fsopen(pciDa[x]->pszFileName, "rb", SH_DENYNO);
1012 if (!fp2) {
1013 errLineNo = __LINE__;
1014 compErrno = errno;
1015 }
1016 else {
1017 size_t len1 = filelength(fileno(fp1));
1018 size_t len2 = filelength(fileno(fp2));
1019
1020 if (len1 == len2) {
1021 setbuf(fp1, NULL);
1022 setbuf(fp2, NULL);
1023 while (WinIsWindow(hab, hwndCnrS)) {
1024 size_t numread1 = fread(buf1, 1, 1024, fp1);
1025 size_t numread2 = fread(buf2, 1, 1024, fp2);
1026
1027 if (!numread1 || !numread2 || numread1 != numread2) {
1028 if (ferror(fp1) || ferror(fp2)) {
1029 errLineNo = __LINE__;
1030 compErrno = errno;
1031 }
1032 else if (feof(fp1) && feof(fp2))
1033 gotMatch = TRUE;
1034 break;
1035 }
1036 else if (memcmp(buf1, buf2, numread1))
1037 break;
1038 } // while
1039 } // same len
1040 }
1041 }
1042
1043 if (fp1)
1044 fclose(fp1);
1045
1046 if (fp2)
1047 fclose(fp2);
1048
1049 if (errLineNo) {
1050 Runtime_Error(pszSrcFile, errLineNo,
1051 "error %d while comparing", compErrno);
1052 }
1053
1054 if (gotMatch) {
1055 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1056 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1057 MPFROM2SHORT(TRUE, CRA_SELECTED));
1058 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1059 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1060 MPFROM2SHORT(TRUE, CRA_SELECTED));
1061 }
1062 }
1063 SleepIfNeeded(&itdSleep, 0);
1064 } // for
1065 break;
1066
1067 case IDM_SELECTBOTH:
1068 for (x = 0; x < numS; x++) {
1069 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1070 pciSa[x]->flags & CNRITEM_EXISTS) {
1071 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1072 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1073 MPFROM2SHORT(TRUE, CRA_SELECTED));
1074 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1075 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1076 MPFROM2SHORT(TRUE, CRA_SELECTED));
1077 }
1078 SleepIfNeeded(&itdSleep, 0);
1079 } // for
1080 break;
1081
1082 case IDM_SELECTONE:
1083 for (x = 0; x < numS; x++) {
1084 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1085 ~pciSa[x]->flags & CNRITEM_EXISTS) {
1086 if (*pciSa[x]->pszFileName) {
1087 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1088 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1089 MPFROM2SHORT(TRUE, CRA_SELECTED));
1090 }
1091 }
1092 else if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1093 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1094 MPFROM2SHORT(TRUE, CRA_SELECTED));
1095 }
1096 }
1097 SleepIfNeeded(&itdSleep, 0);
1098 } // for
1099 break;
1100
1101 case IDM_SELECTBIGGER:
1102 for (x = 0; x < numS; x++) {
1103 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1104 if (pciSa[x]->flags & CNRITEM_LARGER) {
1105 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1106 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1107 MPFROM2SHORT(TRUE, CRA_SELECTED));
1108 }
1109 else if (pciDa[x]->flags & CNRITEM_LARGER) {
1110 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1111 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1112 MPFROM2SHORT(TRUE, CRA_SELECTED));
1113 }
1114 }
1115 SleepIfNeeded(&itdSleep, 0);
1116 } // for
1117 break;
1118
1119 case IDM_SELECTSMALLER:
1120 for (x = 0; x < numS; x++) {
1121 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1122 if (pciSa[x]->flags & CNRITEM_SMALLER) {
1123 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1124 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1125 MPFROM2SHORT(TRUE, CRA_SELECTED));
1126 }
1127 else if (pciDa[x]->flags & CNRITEM_SMALLER) {
1128 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1129 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1130 MPFROM2SHORT(TRUE, CRA_SELECTED));
1131 }
1132 }
1133 SleepIfNeeded(&itdSleep, 0);
1134 } // for
1135 break;
1136
1137 case IDM_SELECTNEWER:
1138 for (x = 0; x < numS; x++) {
1139 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1140 if (pciSa[x]->flags & CNRITEM_NEWER) {
1141 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1142 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1143 MPFROM2SHORT(TRUE, CRA_SELECTED));
1144 }
1145 else if (pciDa[x]->flags & CNRITEM_NEWER) {
1146 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1147 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1148 MPFROM2SHORT(TRUE, CRA_SELECTED));
1149 }
1150 }
1151 SleepIfNeeded(&itdSleep, 0);
1152 } // for
1153 break;
1154
1155 case IDM_SELECTOLDER:
1156 for (x = 0; x < numS; x++) {
1157 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1158 if (pciSa[x]->flags & CNRITEM_OLDER) {
1159 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1160 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1161 MPFROM2SHORT(TRUE, CRA_SELECTED));
1162 }
1163 else if (pciDa[x]->flags & CNRITEM_OLDER) {
1164 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1165 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1166 MPFROM2SHORT(TRUE, CRA_SELECTED));
1167 }
1168 }
1169 SleepIfNeeded(&itdSleep, 0);
1170 } // for
1171 break;
1172
1173 case IDM_DESELECTBOTH:
1174 for (x = 0; x < numS; x++) {
1175 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1176 pciSa[x]->flags & CNRITEM_EXISTS) {
[929]1177 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1178 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1179 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1180 fUpdateHideButton = TRUE;
1181 }
1182 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1183 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1184 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1185 fUpdateHideButton = TRUE;
1186 }
[924]1187 }
1188 SleepIfNeeded(&itdSleep, 0);
1189 } // for
1190 break;
1191
1192 case IDM_DESELECTONE:
1193 for (x = 0; x < numS; x++) {
1194 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1195 if (~pciSa[x]->flags & CNRITEM_EXISTS) {
[929]1196 if (*pciSa[x]->pszFileName) {
1197 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1198 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1199 MPFROM2SHORT(FALSE, CRA_SELECTED));
1200 fUpdateHideButton = TRUE;
1201 }
1202 }
1203 else if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1204 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1205 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1206 fUpdateHideButton = TRUE;
1207 }
[924]1208 }
1209 }
1210 SleepIfNeeded(&itdSleep, 0);
1211 } // for
1212 break;
1213
1214 case IDM_DESELECTBIGGER:
1215 for (x = 0; x < numS; x++) {
1216 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1217 if (pciSa[x]->flags & CNRITEM_LARGER) {
[929]1218 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1219 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1220 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1221 fUpdateHideButton = TRUE;
1222 }
[924]1223 }
1224 else if (pciDa[x]->flags & CNRITEM_LARGER) {
[929]1225 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1226 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1227 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1228 fUpdateHideButton = TRUE;
1229 }
[924]1230 }
1231 }
1232 SleepIfNeeded(&itdSleep, 0);
1233 } // for
1234 break;
1235
1236 case IDM_DESELECTSMALLER:
1237 for (x = 0; x < numS; x++) {
1238 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1239 if (pciSa[x]->flags & CNRITEM_SMALLER) {
[929]1240 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1241 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1242 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1243 fUpdateHideButton = TRUE;
1244 }
[924]1245 }
1246 else if (pciDa[x]->flags & CNRITEM_SMALLER) {
[929]1247 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1248 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1249 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1250 fUpdateHideButton = TRUE;
1251 }
[924]1252 }
1253 }
1254 SleepIfNeeded(&itdSleep, 0);
1255 } // for
1256 break;
1257
1258 case IDM_DESELECTNEWER:
1259 for (x = 0; x < numS; x++) {
1260 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1261 if (pciSa[x]->flags & CNRITEM_NEWER) {
[929]1262 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1263 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1264 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1265 fUpdateHideButton = TRUE;
1266 }
[924]1267 }
1268 else if (pciDa[x]->flags & CNRITEM_NEWER) {
[929]1269 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1270 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1271 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1272 fUpdateHideButton = TRUE;
1273 }
[924]1274 }
1275 }
1276 SleepIfNeeded(&itdSleep, 0);
1277 } // for
1278 break;
1279
1280 case IDM_DESELECTOLDER:
1281 for (x = 0; x < numS; x++) {
1282 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1283 if (pciSa[x]->flags & CNRITEM_OLDER) {
[929]1284 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1285 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1286 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1287 fUpdateHideButton = TRUE;
1288 }
[924]1289 }
1290 else if (pciDa[x]->flags & CNRITEM_OLDER) {
[929]1291 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
[924]1292 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1293 MPFROM2SHORT(FALSE, CRA_SELECTED));
[929]1294 fUpdateHideButton = TRUE;
1295 }
[924]1296 }
1297 }
1298 SleepIfNeeded(&itdSleep, 0);
1299 } // for
1300 break;
1301
1302 default:
1303 break;
[929]1304 } // switch
[924]1305
1306 if (reset) {
1307 while (numS) {
1308 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD,
1309 MPFROMP(pciSa), MPFROM2SHORT((min(numS, 65535)), 0));
1310 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD,
1311 MPFROMP(pciDa), MPFROM2SHORT((min(numD, 65535)), 0));
1312 numS -= min(numS, 65535);
1313 SleepIfNeeded(&itdSleep, 0); // 12 Jan 08 SHL
1314 } // while
1315 }
1316
[1039]1317 free(pciSa);
1318 free(pciDa);
[929]1319
1320 if (fUpdateHideButton) {
1321 if (WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED) == 1)
1322 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
1323 }
1324
1325 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
[924]1326 DosPostEventSem(CompactSem);
1327}
1328
1329/**
[748]1330 * Build FILELIST given pathname
1331 */
1332
[907]1333static VOID FillDirList(CHAR *str, UINT skiplen, BOOL recurse,
1334 FILELIST ***list, UINT *pnumfiles, UINT *pnumalloc)
[551]1335{
[748]1336 CHAR *enddir;
1337 ULONG x;
[551]1338 CHAR *maskstr;
[841]1339 PFILEFINDBUF4L pffbArray;
1340 PFILEFINDBUF4L pffbFile;
[551]1341 HDIR hDir;
[783]1342 ULONG ulFindCnt;
[841]1343 ULONG ulBufBytes = sizeof(FILEFINDBUF4L) * FilesToGet;
[551]1344 APIRET rc;
[1000]1345 static BOOL fDone;
[2]1346
[748]1347 if (!str || !*str) {
[773]1348 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
[2]1349 return;
[748]1350 }
1351
[846]1352 // DbgMsg(pszSrcFile, __LINE__, "FillDirList start %s", str);
1353
[1000]1354 maskstr = xmalloc(CCHMAXPATH + 100, pszSrcFile, __LINE__);
[551]1355 if (!maskstr)
[2]1356 return;
[783]1357 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
1358 if (!pffbArray) {
[1039]1359 free(maskstr);
[2]1360 return;
1361 }
1362 x = strlen(str);
[551]1363 memcpy(maskstr, str, x + 1);
[2]1364 enddir = maskstr + x;
[551]1365 if (*(enddir - 1) != '\\') {
[2]1366 *enddir = '\\';
1367 enddir++;
1368 *enddir = 0;
1369 }
1370 *enddir = '*';
1371 *(enddir + 1) = 0;
1372 hDir = HDIR_CREATE;
1373 DosError(FERR_DISABLEHARDERR);
[783]1374 ulFindCnt = FilesToGet;
[838]1375 rc = xDosFindFirst(maskstr, &hDir,
[907]1376 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
[838]1377 FILE_SYSTEM | FILE_HIDDEN |
1378 (recurse ? FILE_DIRECTORY : 0),
[841]1379 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[551]1380 if (!rc) {
[783]1381 do {
1382 pffbFile = pffbArray;
1383 for (x = 0; x < ulFindCnt; x++) {
1384 if (pffbFile->attrFile & FILE_DIRECTORY) {
[517]1385 // Skip . and ..
[551]1386 if (recurse &&
[783]1387 (pffbFile->achName[0] != '.' ||
1388 (pffbFile->achName[1] &&
1389 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
[551]1390 if (fForceUpper)
[783]1391 strupr(pffbFile->achName);
[551]1392 else if (fForceLower)
[783]1393 strlwr(pffbFile->achName);
1394 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
[907]1395 FillDirList(maskstr, skiplen, recurse, list, pnumfiles, pnumalloc);
[551]1396 }
1397 }
1398 else {
1399 if (fForceUpper)
[783]1400 strupr(pffbFile->achName);
[551]1401 else if (fForceLower)
[783]1402 strlwr(pffbFile->achName);
[1000]1403 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
1404 if (strlen(maskstr) > CCHMAXPATH) {
1405 // Complain if pathnames exceeds max
1406 DosFindClose(hDir);
[1039]1407 free(pffbArray);
1408 free(maskstr);
[1000]1409 if (!fDone) {
1410 fDone = TRUE;
1411 saymsg(MB_OK | MB_ICONASTERISK,
1412 HWND_DESKTOP,
1413 GetPString(IDS_WARNINGTEXT),
1414 "One or more of your files has a full path name that exceeds the OS/2 maximum");
1415 }
1416 return;
1417 }
[783]1418 if (AddToFileList(maskstr + skiplen,
[907]1419 pffbFile, list, pnumfiles, pnumalloc)) {
[551]1420 goto Abort;
[783]1421 }
[551]1422 }
[841]1423 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]1424 } // for
[2]1425 DosError(FERR_DISABLEHARDERR);
[783]1426 ulFindCnt = FilesToGet;
[850]1427 rc = xDosFindNext(hDir, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[783]1428 } while (!rc);
1429
1430Abort:
1431
[2]1432 DosFindClose(hDir);
[846]1433 DosSleep(0);
[2]1434 }
[783]1435
1436 if (rc && rc != ERROR_NO_MORE_FILES) {
1437 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1438 GetPString(IDS_CANTFINDDIRTEXT), maskstr);
1439 }
1440
[1009]1441 xfree(maskstr, pszSrcFile, __LINE__);
1442 xfree(pffbArray, pszSrcFile, __LINE__);
[846]1443
1444 // DbgMsg(pszSrcFile, __LINE__, "FillDirList finish %s", str);
[2]1445}
1446
[924]1447/**
1448 * Compare names for qsort
1449 */
[2]1450
[551]1451static int CompNames(const void *n1, const void *n2)
[316]1452{
[919]1453 FILELIST *fl1 = *(FILELIST **)n1;
1454 FILELIST *fl2 = *(FILELIST **)n2;
[2]1455
[551]1456 return stricmp(fl1->fname, fl2->fname);
[2]1457}
1458
[316]1459//=== FillCnrsThread() Fill left and right containers ===
[2]1460
[751]1461static VOID FillCnrsThread(VOID *args)
[316]1462{
[919]1463 COMPARE *cmp = (COMPARE *)args;
[551]1464 HAB hab;
1465 HMQ hmq;
1466 BOOL notified = FALSE;
[907]1467 ITIMER_DESC itdSleep = { 0 };
[751]1468
[551]1469 HWND hwndLeft, hwndRight;
[748]1470 CHAR szBuf[CCHMAXPATH];
1471 CNRINFO cnri;
[2]1472
[1009]1473# ifdef FORTIFY
1474 // 10 May 08 SHL fixme to suppress W111
1475 Fortify_EnterScope();
[1063]1476# endif
[1009]1477
[748]1478 if (!cmp) {
[773]1479 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
[1063]1480# ifdef FORTIFY
[1009]1481 // 10 May 08 SHL fixme to suppress W111
1482 Fortify_LeaveScope();
[1063]1483# endif
[2]1484 _endthread();
[748]1485 }
[2]1486
[846]1487 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread enter");
1488
[2]1489 DosError(FERR_DISABLEHARDERR);
1490
[907]1491 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
1492
[2]1493 hab = WinInitialize(0);
[551]1494 if (!hab)
1495 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__, "WinInitialize");
[362]1496 else {
[551]1497 hmq = WinCreateMsgQueue(hab, 0);
1498 if (!hmq)
1499 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__,
1500 "WinCreateMsgQueue");
[362]1501 else {
[551]1502 INT x;
[907]1503 UINT l;
1504 UINT r;
[919]1505 // UINT cntr;
[551]1506 FILELIST **filesl = NULL;
1507 FILELIST **filesr = NULL;
[907]1508 UINT numallocl = 0;
1509 UINT numallocr = 0;
[897]1510 INT ret = 0;
[769]1511 UINT lenl; // Directory prefix length
1512 UINT lenr;
[748]1513 UINT recsNeeded;
[907]1514 UINT recsGotten;
[551]1515 PCNRITEM pcilFirst;
1516 PCNRITEM pcirFirst;
[907]1517 PCNRITEM pcilLast;
1518 PCNRITEM pcirLast;
[551]1519 PCNRITEM pcil;
1520 PCNRITEM pcir;
1521 RECORDINSERT ri;
1522 CHAR *pch;
[2]1523
[551]1524 WinCancelShutdown(hmq, TRUE);
[535]1525 IncrThreadUsage();
[907]1526
[551]1527 hwndLeft = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
1528 hwndRight = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
[2]1529 lenl = strlen(cmp->leftdir);
[551]1530 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
1531 lenl++;
[2]1532 lenr = strlen(cmp->rightdir);
[551]1533 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
1534 lenr++;
[2]1535 priority_normal();
[748]1536 // Clear containers
[751]1537 RemoveCnrItems(hwndRight, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1538 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
[917]1539 cmp->cmp->totalleft = 0;
1540 cmp->cmp->totalright = 0;
[2]1541
[748]1542 // Build list of all files in left directory
[551]1543 if (fForceLower)
1544 strlwr(cmp->leftdir);
1545 else if (fForceUpper)
1546 strupr(cmp->leftdir);
1547 FillDirList(cmp->leftdir, lenl, cmp->includesubdirs,
[907]1548 &filesl, &cmp->cmp->totalleft, &numallocl);
[2]1549
[551]1550 if (filesl)
[917]1551 qsort(filesl, cmp->cmp->totalleft, sizeof(CHAR *), CompNames);
[748]1552
[846]1553 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread sorted filesl");
1554
[748]1555 // Build list of all files in right directory
[551]1556 if (!*cmp->rightlist) {
1557 if (fForceLower)
1558 strlwr(cmp->rightdir);
1559 else if (fForceUpper)
1560 strupr(cmp->rightdir);
1561 FillDirList(cmp->rightdir, lenr, cmp->includesubdirs,
[907]1562 &filesr, &cmp->cmp->totalright, &numallocr);
[2]1563 }
[551]1564 else {
[748]1565 // Use snapshot file
[551]1566 FILE *fp;
[841]1567 FILEFINDBUF4L fb4;
[551]1568 CHAR str[CCHMAXPATH * 2], *p;
[2]1569
[551]1570 memset(&fb4, 0, sizeof(fb4));
1571 fp = fopen(cmp->rightlist, "r");
1572 if (!fp)
1573 Runtime_Error(pszSrcFile, __LINE__, "can not open %s (%d)",
1574 cmp->rightlist, errno);
[362]1575 else {
[551]1576 while (!feof(fp)) {
[748]1577 // First get name of directory
[551]1578 if (!xfgets_bstripcr(str, sizeof(str), fp, pszSrcFile, __LINE__))
1579 break; // EOF
1580 p = str;
1581 if (*p == '\"') {
[748]1582 // Quoted
[551]1583 p++;
1584 if (*p && *p != '\"') {
1585 p = strchr(p, '\"');
1586 if (p) {
1587 *p = 0;
1588 if (*(str + 1)) {
1589 strcpy(cmp->rightdir, str + 1);
1590 if (fForceUpper)
1591 strupr(cmp->rightdir);
1592 else if (fForceLower)
1593 strlwr(cmp->rightdir);
1594 p = cmp->rightdir + (strlen(cmp->rightdir) - 1);
1595 if (p - cmp->rightdir > 3 && *p == '\\')
1596 *p = 0; // Chop trailing slash
1597 break;
1598 }
1599 }
1600 }
1601 }
[748]1602 } // while !EOF
[2]1603
[748]1604 memset(&cnri, 0, sizeof(cnri));
1605 cnri.cb = sizeof(cnri);
1606 cnri.pszCnrTitle = cmp->rightdir;
1607 if (!WinSendMsg(hwndRight, CM_SETCNRINFO,
1608 MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE))) {
1609 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_SETCNRINFO");
[551]1610 }
[748]1611
[551]1612 if (*cmp->rightdir) {
[769]1613 lenr = strlen(cmp->rightdir);
1614 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
1615 lenr++;
[551]1616 while (!feof(fp)) {
1617 if (!xfgets_bstripcr
1618 (str, sizeof(str), fp, pszSrcFile, __LINE__))
1619 break;
1620 p = str;
1621 if (*p == '\"') {
1622 p++;
1623 if (*p && *p != '\"') {
1624 p = strchr(p, '\"');
1625 if (p) {
1626 *p = 0;
1627 p++;
1628 if (*p == ',') {
1629 p++;
1630 if (!cmp->includesubdirs && atol(p) > lenr)
1631 continue;
1632 p = strchr(p, ',');
1633 if (p) {
1634 p++;
[846]1635 // 27 Sep 07 SHL fixme to do ULONGLONG conversion
[551]1636 fb4.cbFile = atol(p);
1637 p = strchr(p, ',');
1638 if (p) {
1639 p++;
1640 fb4.fdateLastWrite.year = atol(p) - 1980;
1641 p = strchr(p, '/');
1642 if (p) {
1643 p++;
1644 fb4.fdateLastWrite.month = atol(p);
1645 p = strchr(p, '/');
1646 if (p) {
1647 p++;
1648 fb4.fdateLastWrite.day = atol(p);
1649 p = strchr(p, ',');
1650 if (p) {
1651 p++;
1652 fb4.ftimeLastWrite.hours = atol(p);
1653 p = strchr(p, ':');
1654 if (p) {
1655 p++;
1656 fb4.ftimeLastWrite.minutes = atol(p);
1657 p = strchr(p, ':');
1658 if (p) {
1659 p++;
1660 fb4.ftimeLastWrite.twosecs = atol(p);
1661 p = strchr(p, ',');
1662 if (p) {
1663 p++;
1664 fb4.attrFile = atol(p);
1665 p = strchr(p, ',');
1666 if (p) {
1667 p++;
1668 fb4.cbList = atol(p) * 2;
1669 if (fForceUpper)
1670 strupr(str + 1);
1671 else if (fForceLower)
1672 strlwr(str + 1);
1673 if (AddToFileList((str + 1) + lenr,
1674 &fb4,
1675 &filesr,
[917]1676 &cmp->cmp->totalright,
[551]1677 &numallocr))
1678 break;
1679 }
1680 }
1681 }
1682 }
1683 }
1684 }
1685 }
1686 }
1687 }
1688 }
1689 }
1690 }
1691 }
[748]1692 } // while
1693 } // if have rightdir
[551]1694 fclose(fp);
1695 }
[748]1696 } // if snapshot file
[316]1697
[551]1698 if (filesr)
[917]1699 qsort(filesr, cmp->cmp->totalright, sizeof(CHAR *), CompNames);
[2]1700
[846]1701 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread sorted filesr");
1702
[748]1703 // We now have two lists of files, both sorted.
1704 // Count total number of container entries required on each side
[2]1705 l = r = 0;
[316]1706 recsNeeded = 0;
[551]1707 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
[748]1708
1709 if (filesl && filesl[l]) {
1710 if (filesr && filesr[r])
1711 x = stricmp(filesl[l]->fname, filesr[r]->fname);
[551]1712 else
[748]1713 x = -1; // Left side list longer
[551]1714 }
[748]1715 else
1716 x = +1; // Right side list longer
1717
1718 if (x <= 0)
1719 l++; // On left side
1720 if (x >= 0)
1721 r++; // On right side
1722
1723 recsNeeded++; // Keep count of how many entries req'd
1724
1725 } // while
1726
[907]1727 // Say building list - fixme to post?
[551]1728 WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
[748]1729
1730 // Now insert records into the containers
[551]1731 if (recsNeeded) {
1732 pcilFirst = WinSendMsg(hwndLeft,
1733 CM_ALLOCRECORD,
[751]1734 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]1735 MPFROMLONG(recsNeeded));
1736 if (!pcilFirst) {
[742]1737 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1738 recsNeeded);
[551]1739 recsNeeded = 0;
1740 }
[316]1741 }
[362]1742 if (recsNeeded) {
[551]1743 pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
[751]1744 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]1745 MPFROMLONG(recsNeeded));
1746 if (!pcirFirst) {
[742]1747 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1748 recsNeeded);
[551]1749 recsNeeded = 0;
[751]1750 FreeCnrItemList(hwndLeft, pcilFirst);
[551]1751 }
[2]1752 }
[748]1753
[362]1754 if (recsNeeded) {
[748]1755
[846]1756 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread filling");
1757
[919]1758 l = 0;
1759 r = 0;
[551]1760 pcil = pcilFirst;
1761 pcir = pcirFirst;
[919]1762 pcilLast = NULL;
1763 pcirLast = NULL;
[907]1764
1765 recsGotten = 0;
[919]1766 cmp->cmp->totalleft = 0;
1767 cmp->cmp->totalright = 0;
[907]1768
[551]1769 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
[907]1770
[919]1771 // 12 Jan 08 SHL fixme to have message in string table
[907]1772 if (!pcil) {
[919]1773 Runtime_Error(pszSrcFile, __LINE__, "Insufficient memory or %u items (%u)",
1774 recsNeeded, recsGotten);
[907]1775 break;
1776 }
1777
[919]1778 // 12 Jan 08 SHL fixme to have message in string table
[907]1779 if (!pcir) {
[919]1780 Runtime_Error(pszSrcFile, __LINE__, "Insufficient memory or %u items (%u)",
1781 recsNeeded, recsGotten);
[907]1782 break;
1783 }
1784 recsGotten++;
[551]1785 pcir->hwndCnr = hwndRight;
[919]1786 pcir->rc.hptrIcon = (HPOINTER)0;
[551]1787 pcil->hwndCnr = hwndLeft;
[919]1788 pcil->rc.hptrIcon = (HPOINTER)0;
[748]1789
1790 if (filesl && filesl[l]) {
1791 if (filesr && filesr[r])
1792 x = stricmp(filesl[l]->fname, filesr[r]->fname);
1793 else
1794 x = -1; // Left side list longer
1795 }
1796 else
1797 x = +1; // Right side list longer
1798
1799 if (x <= 0) {
[769]1800 // File appears on left side
[919]1801 cmp->cmp->totalleft++;
[769]1802 BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname);
1803 pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]1804 pcil->pszDisplayName = pcil->pszFileName + lenl;
1805 pcil->attrFile = filesl[l]->attrFile;
[751]1806 pcil->pszDispAttr = FileAttrToString(pcil->attrFile);
[748]1807 pcil->cbFile = filesl[l]->cbFile;
[919]1808 // 12 Jan 08 SHL fixme to used cached size here too
1809 CommaFmtULL(szBuf, sizeof(szBuf), pcil->cbFile, ' ');
1810 pcil->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]1811 pcil->easize = filesl[l]->easize;
1812 pcil->date.day = filesl[l]->date.day;
1813 pcil->date.month = filesl[l]->date.month;
1814 pcil->date.year = filesl[l]->date.year + 1980;
1815 pcil->time.seconds = filesl[l]->time.twosecs * 2;
1816 pcil->time.minutes = filesl[l]->time.minutes;
1817 pcil->time.hours = filesl[l]->time.hours;
1818 pcil->ladate.day = filesl[l]->ladate.day;
1819 pcil->ladate.month = filesl[l]->ladate.month;
1820 pcil->ladate.year = filesl[l]->ladate.year + 1980;
1821 pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1822 pcil->latime.minutes = filesl[l]->latime.minutes;
1823 pcil->latime.hours = filesl[l]->latime.hours;
1824 pcil->crdate.day = filesl[l]->crdate.day;
1825 pcil->crdate.month = filesl[l]->crdate.month;
1826 pcil->crdate.year = filesl[l]->crdate.year + 1980;
1827 pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1828 pcil->crtime.minutes = filesl[l]->crtime.minutes;
1829 pcil->crtime.hours = filesl[l]->crtime.hours;
1830 if (*cmp->dcd.mask.szMask) {
[919]1831 if (!Filter((PMINIRECORDCORE)pcil, (PVOID)&cmp->dcd.mask)) {
[748]1832 pcil->rc.flRecordAttr |= CRA_FILTERED;
1833 pcir->rc.flRecordAttr |= CRA_FILTERED;
1834 }
1835 }
1836 } // if on left
1837
1838 if (x >= 0) {
[769]1839 // File appears on right side
[919]1840 cmp->cmp->totalright++;
[773]1841 BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname);
[769]1842 pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__); // 31 Jul 07 SHL
[748]1843 pcir->pszDisplayName = pcir->pszFileName + lenr;
1844 pcir->attrFile = filesr[r]->attrFile;
1845 // pcir->rc.hptrIcon = hptrFile;
[751]1846 pcir->pszDispAttr = FileAttrToString(pcir->attrFile);
[748]1847 pcir->cbFile = filesr[r]->cbFile;
[919]1848 // 12 Jan 08 SHL fixme to used cached size here too
1849 CommaFmtULL(szBuf, sizeof(szBuf), pcir->cbFile, ' ');
1850 pcir->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]1851 pcir->easize = filesr[r]->easize;
1852 pcir->date.day = filesr[r]->date.day;
1853 pcir->date.month = filesr[r]->date.month;
1854 pcir->date.year = filesr[r]->date.year + 1980;
1855 pcir->time.seconds = filesr[r]->time.twosecs * 2;
1856 pcir->time.minutes = filesr[r]->time.minutes;
1857 pcir->time.hours = filesr[r]->time.hours;
1858 pcir->ladate.day = filesr[r]->ladate.day;
1859 pcir->ladate.month = filesr[r]->ladate.month;
1860 pcir->ladate.year = filesr[r]->ladate.year + 1980;
1861 pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1862 pcir->latime.minutes = filesr[r]->latime.minutes;
1863 pcir->latime.hours = filesr[r]->latime.hours;
1864 pcir->crdate.day = filesr[r]->crdate.day;
1865 pcir->crdate.month = filesr[r]->crdate.month;
1866 pcir->crdate.year = filesr[r]->crdate.year + 1980;
1867 pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1868 pcir->crtime.minutes = filesr[r]->crtime.minutes;
1869 pcir->crtime.hours = filesr[r]->crtime.hours;
[790]1870 // Bypass check if already filtered on left side
1871 if (~pcir->rc.flRecordAttr & CRA_FILTERED &&
[748]1872 *cmp->dcd.mask.szMask) {
1873 if (!Filter((PMINIRECORDCORE)pcir, (PVOID)&cmp->dcd.mask)) {
1874 pcil->rc.flRecordAttr |= CRA_FILTERED;
1875 pcir->rc.flRecordAttr |= CRA_FILTERED;
1876 }
1877 }
1878 } // if on right
1879
1880 if (x == 0) {
1881 // File appears on both sides
[769]1882 pcil->flags |= CNRITEM_EXISTS;
1883 pcir->flags |= CNRITEM_EXISTS;
1884 pch = szBuf;
[748]1885 // Subject field holds status messages
1886 *pch = 0;
1887 if (pcil->cbFile + pcil->easize > pcir->cbFile + pcir->easize) {
1888 pcil->flags |= CNRITEM_LARGER;
1889 pcir->flags |= CNRITEM_SMALLER;
1890 strcpy(pch, GetPString(IDS_LARGERTEXT));
1891 pch += 6;
1892 }
1893 else if (pcil->cbFile + pcil->easize <
1894 pcir->cbFile + pcir->easize) {
1895 pcil->flags |= CNRITEM_SMALLER;
1896 pcir->flags |= CNRITEM_LARGER;
1897 strcpy(pch, GetPString(IDS_SMALLERTEXT));
1898 pch += 7;
[907]1899 }
1900 ret = TestCDates(&pcir->date, &pcir->time,
1901 &pcil->date, &pcil->time);
1902 if (ret == 1)
[924]1903 /* 13 Jan 08 SHL fixme to be gone
1904 ((pcil->date.year > pcir->date.year) ? TRUE :
[748]1905 (pcil->date.year < pcir->date.year) ? FALSE :
1906 (pcil->date.month > pcir->date.month) ? TRUE :
1907 (pcil->date.month < pcir->date.month) ? FALSE :
1908 (pcil->date.day > pcir->date.day) ? TRUE :
1909 (pcil->date.day < pcir->date.day) ? FALSE :
1910 (pcil->time.hours > pcir->time.hours) ? TRUE :
1911 (pcil->time.hours < pcir->time.hours) ? FALSE :
1912 (pcil->time.minutes > pcir->time.minutes) ? TRUE :
1913 (pcil->time.minutes < pcir->time.minutes) ? FALSE :
1914 (pcil->time.seconds > pcir->time.seconds) ? TRUE :
[924]1915 (pcil->time.seconds < pcir->time.seconds) ? FALSE : FALSE)
1916 */
1917 {
[748]1918 pcil->flags |= CNRITEM_NEWER;
1919 pcir->flags |= CNRITEM_OLDER;
[769]1920 if (pch != szBuf) {
[748]1921 strcpy(pch, ", ");
1922 pch += 2;
1923 }
1924 strcpy(pch, GetPString(IDS_NEWERTEXT));
1925 pch += 5;
1926 }
[907]1927 else if (ret == -1)
[924]1928 /* 13 Jan 08 SHL fixme to be gone
1929 ((pcil->date.year < pcir->date.year) ? TRUE :
1930 (pcil->date.year > pcir->date.year) ? FALSE :
1931 (pcil->date.month < pcir->date.month) ? TRUE :
1932 (pcil->date.month > pcir->date.month) ? FALSE :
1933 (pcil->date.day < pcir->date.day) ? TRUE :
1934 (pcil->date.day > pcir->date.day) ? FALSE :
1935 (pcil->time.hours < pcir->time.hours) ? TRUE :
1936 (pcil->time.hours > pcir->time.hours) ? FALSE :
1937 (pcil->time.minutes < pcir->time.minutes) ? TRUE :
1938 (pcil->time.minutes > pcir->time.minutes) ? FALSE :
1939 (pcil->time.seconds < pcir->time.seconds) ? TRUE :
1940 (pcil->time.seconds > pcir->time.seconds) ? FALSE :
1941 FALSE)
1942 */
1943 {
[748]1944 pcil->flags |= CNRITEM_OLDER;
1945 pcir->flags |= CNRITEM_NEWER;
[769]1946 if (pch != szBuf) {
[748]1947 strcpy(pch, ", ");
1948 pch += 2;
1949 }
1950 strcpy(pch, GetPString(IDS_OLDERTEXT));
1951 pch += 5;
1952 }
[769]1953 pcil->pszSubject = *szBuf ?
1954 xstrdup(szBuf, pszSrcFile, __LINE__) :
[751]1955 NullStr;
[748]1956
1957 } // if on both sides
1958
[1032]1959 if (x <= 0) {
[919]1960 free(filesl[l++]); // Done with item on left
[1032]1961 }
1962 if (x >= 0) {
1963 free(filesr[r++]); // Done with item on right
1964 }
[748]1965 // Ensure empty buffers point somewhere
1966 if (!pcil->pszFileName) {
1967 pcil->pszFileName = NullStr;
1968 pcil->pszDisplayName = pcil->pszFileName;
1969 }
1970
1971 if (!pcir->pszFileName) {
1972 pcir->pszFileName = NullStr;
1973 pcir->pszDisplayName = pcir->pszFileName;
1974 }
1975
[751]1976 pcil->rc.pszIcon = pcil->pszDisplayName;
1977 pcir->rc.pszIcon = pcir->pszDisplayName;
[748]1978
[762]1979 pcil->pszLongName = NullStr;
1980 pcir->pszLongName = NullStr;
[751]1981
[748]1982 if (!pcil->pszSubject)
1983 if (!pcir->pszSubject)
[790]1984 pcir->pszSubject = NullStr;
[748]1985
[751]1986 if (!pcil->pszDispAttr)
1987 pcil->pszDispAttr = NullStr;
1988 if (!pcir->pszDispAttr)
[790]1989 pcir->pszDispAttr = NullStr;
[751]1990
[907]1991 // Avoid hogging systems
1992 SleepIfNeeded(&itdSleep, 0);
[748]1993
[907]1994 pcilLast = pcil;
1995 pcirLast = pcir;
[919]1996 pcil = (PCNRITEM)pcil->rc.preccNextRecord;
1997 pcir = (PCNRITEM)pcir->rc.preccNextRecord;
[748]1998
1999 } // while filling left or right
2000
[907]2001 // If stopped early CM_ALLOCATERECORD partially failed
2002 // Free up container records we did not use on other side
[919]2003 // Free up items we did not insert in container
[907]2004 if (recsGotten < recsNeeded) {
2005 if (pcil) {
[919]2006 if (pcilLast)
2007 pcilLast->rc.preccNextRecord = NULL;
2008 else
2009 pcilFirst = NULL;
[907]2010 FreeCnrItemList(hwndLeft, pcil);
2011 }
2012 if (filesl) {
[1032]2013 for(; filesl[l]; l++) {
2014 free(filesl[l]);
2015 }
[907]2016 }
2017 if (pcir) {
[919]2018 if (pcirLast)
2019 pcirLast->rc.preccNextRecord = NULL;
2020 else
2021 pcirFirst = NULL;
[907]2022 FreeCnrItemList(hwndRight, pcir);
2023 }
2024 if (filesr) {
[1032]2025 for (; filesr[r]; r++) {
2026 free(filesr[r]);
2027 }
[907]2028 }
[917]2029 // Reduce count to match what is in containers
[907]2030 recsNeeded = recsGotten;
2031 } // if insufficient resources
2032
[1009]2033 xfree(filesl, pszSrcFile, __LINE__); // Free header - have already freed elements
[551]2034 filesl = NULL;
[1009]2035 xfree(filesr, pszSrcFile, __LINE__);
[551]2036 filesr = NULL;
[907]2037
2038 // Say inserting
[551]2039 WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
[748]2040
[907]2041 // Insert left side
[551]2042 memset(&ri, 0, sizeof(RECORDINSERT));
2043 ri.cb = sizeof(RECORDINSERT);
[919]2044 ri.pRecordOrder = (PRECORDCORE)CMA_END;
2045 ri.pRecordParent = (PRECORDCORE)NULL;
2046 ri.zOrder = (ULONG)CMA_TOP;
[551]2047 ri.cRecordsInsert = recsNeeded;
2048 ri.fInvalidateRecord = FALSE;
[919]2049
[551]2050 if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
2051 MPFROMP(pcilFirst), MPFROMP(&ri))) {
[742]2052 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
[751]2053 FreeCnrItemList(hwndLeft, pcilFirst);
[917]2054 cmp->cmp->totalleft = 0;
[551]2055 }
[748]2056
[907]2057 // Insert right side
[551]2058 memset(&ri, 0, sizeof(RECORDINSERT));
2059 ri.cb = sizeof(RECORDINSERT);
[919]2060 ri.pRecordOrder = (PRECORDCORE)CMA_END;
2061 ri.pRecordParent = (PRECORDCORE)NULL;
2062 ri.zOrder = (ULONG)CMA_TOP;
[551]2063 ri.cRecordsInsert = recsNeeded;
2064 ri.fInvalidateRecord = FALSE;
[751]2065
[551]2066 if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
2067 MPFROMP(pcirFirst), MPFROMP(&ri))) {
[751]2068 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
2069 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
2070 FreeCnrItemList(hwndRight, pcirFirst);
[917]2071 cmp->cmp->totalright = 0;
[551]2072 }
[748]2073
[846]2074 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread filled");
2075
[748]2076 } // if recsNeeded
2077
[2]2078 Deselect(hwndLeft);
2079 Deselect(hwndRight);
[748]2080
[846]2081 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread deselected");
2082
[907]2083 // Request window update
[551]2084 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID))
2085 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]2086 notified = TRUE;
[748]2087
[846]2088 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread FILLED posted");
2089
[362]2090 if (filesl)
[748]2091 FreeList((CHAR **)filesl); // Must have failed to create container
[362]2092 if (filesr)
[748]2093 FreeList((CHAR **)filesr);
2094
[2]2095 WinDestroyMsgQueue(hmq);
[907]2096 } // if have queue
2097 if (!notified)
2098 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[535]2099 DecrThreadUsage();
[2]2100 WinTerminate(hab);
2101 }
[1039]2102 free(cmp);
[2]2103 DosPostEventSem(CompactSem);
[846]2104
[1009]2105# ifdef FORTIFY
[1038]2106 Fortify_LeaveScope();
[1063]2107# endif
[1009]2108
[846]2109 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread exit");
[2]2110}
2111
[929]2112// fixme to be gone - use variable?
[773]2113#define hwndLeft (WinWindowFromID(hwnd,COMP_LEFTDIR))
2114#define hwndRight (WinWindowFromID(hwnd,COMP_RIGHTDIR))
[2]2115
[316]2116//=== CompareDlgProc() Compare directories dialog procedure ===
[2]2117
[551]2118MRESULT EXPENTRY CompareDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[316]2119{
[551]2120 COMPARE *cmp;
[773]2121 BOOL temp;
[907]2122 CHAR s[81];
[362]2123
[773]2124 static HPOINTER hptr;
[2]2125
[551]2126 switch (msg) {
2127 case WM_INITDLG:
[919]2128 cmp = (COMPARE *)mp2;
[551]2129 if (!cmp) {
2130 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2131 WinDismissDlg(hwnd, 0);
2132 }
2133 else {
2134 if (!hptr)
2135 hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, COMPARE_ICON);
2136 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptr), MPVOID);
2137 cmp->hwnd = hwnd;
[919]2138 WinSetWindowPtr(hwnd, QWL_USER, (PVOID)cmp);
[938]2139 {
2140 SWP swp;
2141 ULONG size = sizeof(SWP);
2142
2143 PrfQueryProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp, &size);
2144 WinSetWindowPos(hwnd,
2145 HWND_TOP,
2146 swp.x,
2147 swp.y,
2148 swp.cx,
2149 swp.cy,
2150 swp.fl);
2151 }
[551]2152 SetCnrCols(hwndLeft, TRUE);
2153 SetCnrCols(hwndRight, TRUE);
2154 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2155 WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2156 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2157 {
2158 USHORT ids[] = { COMP_LEFTDIR, COMP_RIGHTDIR, COMP_TOTALLEFT,
[751]2159 COMP_TOTALRIGHT, COMP_SELLEFT, COMP_SELRIGHT,
2160 0
2161 };
[919]2162 UINT x;
[924]2163 for (x = 0; ids[x]; x++) {
[551]2164 SetPresParams(WinWindowFromID(hwnd, ids[x]),
2165 &RGBGREY,
2166 &RGBBLACK, &RGBBLACK, GetPString(IDS_8HELVTEXT));
[924]2167 }
[2]2168 }
[929]2169 WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER, 500);
[551]2170 }
2171 break;
[2]2172
[551]2173 case UM_STRETCH:
2174 {
2175 SWP swp, swpC;
2176 LONG titl, szbx, szby, sz;
2177 HWND hwndActive;
[2]2178
[551]2179 WinQueryWindowPos(hwnd, &swp);
2180 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
2181 hwndActive = WinQueryFocus(HWND_DESKTOP);
2182 szbx = SysVal(SV_CXSIZEBORDER);
2183 szby = SysVal(SV_CYSIZEBORDER);
2184 titl = SysVal(SV_CYTITLEBAR);
2185 titl += 26;
2186 swp.cx -= (szbx * 2);
2187 sz = (swp.cx / 8);
2188 WinQueryWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), &swpC);
2189 WinSetWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), HWND_TOP,
2190 szbx + 6,
2191 swpC.y,
2192 (swp.cx / 2) - (szbx + 6),
2193 ((swp.cy - swpC.y) - titl) - szby,
2194 SWP_MOVE | SWP_SIZE);
2195 WinSetWindowPos(WinWindowFromID(hwnd, COMP_RIGHTDIR), HWND_TOP,
2196 (swp.cx / 2) + (szbx + 6),
2197 swpC.y,
2198 (swp.cx / 2) - (szbx + 6),
2199 ((swp.cy - swpC.y) - titl) - szby,
2200 SWP_MOVE | SWP_SIZE);
2201 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFTHDR), HWND_TOP,
2202 szbx + 6,
2203 ((swp.cy - titl) - szby) + 4,
2204 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2205 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFT), HWND_TOP,
2206 sz + (szbx + 6),
2207 ((swp.cy - titl) - szby) + 4,
2208 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2209 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFTHDR), HWND_TOP,
2210 (sz * 2) + (szbx + 6),
2211 ((swp.cy - titl) - szby) + 4,
2212 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2213 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFT), HWND_TOP,
2214 (sz * 3) + (szbx + 6),
2215 ((swp.cy - titl) - szby) + 4,
2216 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2217 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHTHDR), HWND_TOP,
2218 (sz * 4) + (szbx + 6),
2219 ((swp.cy - titl) - szby) + 4,
2220 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2221 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHT), HWND_TOP,
2222 (sz * 5) + (szbx + 6),
2223 ((swp.cy - titl) - szby) + 4,
2224 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2225 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHTHDR), HWND_TOP,
2226 (sz * 6) + (szbx + 6),
2227 ((swp.cy - titl) - szby) + 4,
2228 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2229 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHT), HWND_TOP,
2230 (sz * 7) + (szbx + 6),
2231 ((swp.cy - titl) - szby) + 4,
2232 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2233 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALLEFT),
[919]2234 (HPS)0, FALSE, FALSE);
[551]2235 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELLEFT),
[919]2236 (HPS)0, FALSE, FALSE);
[551]2237 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALRIGHT),
[919]2238 (HPS)0, FALSE, FALSE);
[551]2239 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELRIGHT),
[919]2240 (HPS)0, FALSE, FALSE);
2241 PaintRecessedWindow(hwndLeft, (HPS)0,
[551]2242 (hwndActive == hwndLeft), TRUE);
[919]2243 PaintRecessedWindow(hwndRight, (HPS)0,
[551]2244 (hwndActive == hwndRight), TRUE);
[2]2245 }
[551]2246 }
2247 return 0;
[2]2248
[551]2249 case WM_ADJUSTWINDOWPOS:
2250 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2251 break;
[2]2252
[551]2253 case UM_SETUP:
2254 {
2255 CNRINFO cnri;
2256 BOOL tempsubj;
[2]2257
[551]2258 cmp = INSTDATA(hwnd);
[919]2259 if (!cmp)
2260 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2261 else {
[551]2262 cmp->dcd.size = sizeof(DIRCNRDATA);
2263 cmp->dcd.type = DIR_FRAME;
2264 cmp->dcd.hwndFrame = hwnd;
2265 cmp->dcd.hwndClient = hwnd;
2266 cmp->dcd.mask.attrFile = (FILE_DIRECTORY | FILE_ARCHIVED |
2267 FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN);
[1065]2268 LoadDetailsSwitches("DirCmp", &cmp->dcd.ds);
2269 cmp->dcd.ds.detailslongname = FALSE;
2270 cmp->dcd.ds.detailsicon = FALSE; // TRUE;
[2]2271 }
[551]2272 memset(&cnri, 0, sizeof(CNRINFO));
2273 cnri.cb = sizeof(CNRINFO);
2274 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_QUERYCNRINFO,
2275 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2276 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2277 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 68;
2278 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2279 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
2280 memset(&cnri, 0, sizeof(CNRINFO));
2281 cnri.cb = sizeof(CNRINFO);
2282 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_QUERYCNRINFO,
2283 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2284 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2285 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 54;
2286 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2287 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
2288 AdjustCnrColRO(hwndLeft, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2289 AdjustCnrColRO(hwndLeft, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
2290 AdjustCnrColRO(hwndRight, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2291 AdjustCnrColRO(hwndRight, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
[1065]2292 AdjustCnrColsForPref(hwndLeft, cmp->leftdir, &cmp->dcd.ds, TRUE);
2293 tempsubj = cmp->dcd.ds.detailssubject;
2294 cmp->dcd.ds.detailssubject = FALSE;
2295 AdjustCnrColsForPref(hwndRight, cmp->rightdir, &cmp->dcd.ds, TRUE);
[551]2296 if (*cmp->rightlist) {
2297 AdjustCnrColVis(hwndRight, GetPString(IDS_LADATECOLTEXT), FALSE,
2298 FALSE);
2299 AdjustCnrColVis(hwndRight, GetPString(IDS_LATIMECOLTEXT), FALSE,
2300 FALSE);
2301 AdjustCnrColVis(hwndRight, GetPString(IDS_CRDATECOLTEXT), FALSE,
2302 FALSE);
2303 AdjustCnrColVis(hwndRight, GetPString(IDS_CRTIMECOLTEXT), FALSE,
2304 FALSE);
2305 }
[1065]2306 cmp->dcd.ds.detailssubject = tempsubj;
[551]2307 }
2308 return 0;
[2]2309
[551]2310 case WM_DRAWITEM:
2311 if (mp2) {
[748]2312 POWNERITEM pown = (POWNERITEM)mp2;
[551]2313 PCNRDRAWITEMINFO pcown;
2314 PCNRITEM pci;
[2]2315
[748]2316 pcown = (PCNRDRAWITEMINFO)pown->hItem;
[551]2317 if (pcown) {
[919]2318 pci = (PCNRITEM)pcown->pRecord;
[748]2319 // 01 Aug 07 SHL if field null or blank, we draw
[929]2320 // fixme to document why - probably to optimize and bypass draw?
[748]2321 if (pci && (INT)pci != -1 && !*pci->pszFileName)
[551]2322 return MRFROMLONG(TRUE);
[2]2323 }
[551]2324 }
2325 return 0;
[2]2326
[551]2327 case UM_CONTAINERHWND:
[907]2328 // Building list
[551]2329 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDBLDLISTTEXT));
2330 return 0;
[2]2331
[551]2332 case UM_CONTAINERDIR:
[907]2333 // Filling container
[551]2334 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDFILLCNRTEXT));
2335 return 0;
[2]2336
[907]2337 case WM_TIMER:
2338 // Show current totals
2339 cmp = INSTDATA(hwnd);
2340 if (!cmp) {
2341 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2342 WinDismissDlg(hwnd, 0);
2343 }
2344 else {
[929]2345 if (cmp->uOldTotalLeft != cmp->totalleft) {
2346 cmp->uOldTotalLeft = cmp->totalleft;
2347 sprintf(s, " %d", cmp->totalleft);
2348 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s);
2349 }
2350 if (cmp->uOldTotalRight != cmp->totalright) {
2351 cmp->uOldTotalRight = cmp->totalright;
2352 sprintf(s, " %d", cmp->totalright);
2353 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s);
2354 }
2355 if (cmp->uOldSelLeft != cmp->selleft) {
2356 cmp->uOldSelLeft = cmp->selleft;
2357 sprintf(s, " %d", cmp->selleft);
2358 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
2359 }
2360 if (cmp->uOldSelRight != cmp->selright) {
2361 cmp->uOldSelRight = cmp->selright;
2362 sprintf(s, " %d", cmp->selright);
2363 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
2364 }
[907]2365 }
2366 break;
2367
[551]2368 case UM_CONTAINER_FILLED:
2369 cmp = INSTDATA(hwnd);
2370 if (!cmp) {
2371 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2372 WinDismissDlg(hwnd, 0);
2373 }
2374 else {
2375 cmp->filling = FALSE;
2376 WinEnableWindow(hwndLeft, TRUE);
2377 WinEnableWindow(hwndRight, TRUE);
2378 WinEnableWindowUpdate(hwndLeft, TRUE);
2379 WinEnableWindowUpdate(hwndRight, TRUE);
[929]2380 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
2381 // 12 Jan 08 SHL fixme to have SetButtonEnables(COMPARE* pcmp, BOOL fEnable)
[919]2382 // to replace duplicated code here and elsewhere
[551]2383 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
2384 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
2385 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), TRUE);
2386 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), TRUE);
2387 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), TRUE);
2388 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), TRUE);
2389 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), TRUE);
2390 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), TRUE);
2391 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), TRUE);
2392 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), TRUE);
2393 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), TRUE);
2394 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), TRUE);
2395 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), TRUE);
2396 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), TRUE);
2397 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), TRUE);
2398 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), TRUE);
2399 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), TRUE);
2400 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), TRUE);
2401 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), TRUE);
2402 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), TRUE);
2403 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), TRUE);
2404 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), TRUE);
2405 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), TRUE);
2406 if (!*cmp->rightlist) {
2407 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), TRUE);
2408 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), TRUE);
2409 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), TRUE);
2410 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), TRUE);
2411 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), TRUE);
[362]2412 }
[551]2413 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), TRUE);
[919]2414 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), TRUE);
2415 if (*cmp->dcd.mask.szMask) {
2416 sprintf(s,
2417 GetPString(IDS_COMPREADYFILTEREDTEXT),
2418 cmp->dcd.mask.szMask);
2419 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2420 }
[551]2421 else
2422 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2423 }
2424 break;
2425
2426 case WM_INITMENU:
2427 cmp = INSTDATA(hwnd);
2428 if (cmp) {
2429 switch (SHORT1FROMMP(mp1)) {
2430 case IDM_COMMANDSMENU:
2431 SetupCommandMenu(cmp->dcd.hwndLastMenu, hwnd);
2432 break;
[2]2433 }
[551]2434 }
2435 break;
[2]2436
[551]2437 case WM_MENUEND:
2438 cmp = INSTDATA(hwnd);
2439 if (cmp) {
[919]2440 if ((HWND)mp2 == cmp->dcd.hwndLastMenu) {
[551]2441 MarkAll(hwndLeft, TRUE, FALSE, TRUE);
2442 MarkAll(hwndRight, TRUE, FALSE, TRUE);
2443 WinDestroyWindow(cmp->dcd.hwndLastMenu);
[919]2444 cmp->dcd.hwndLastMenu = (HWND)0;
[2]2445 }
[551]2446 }
2447 break;
[2]2448
[551]2449 case WM_CONTROL:
2450 switch (SHORT1FROMMP(mp1)) {
2451 case COMP_INCLUDESUBDIRS:
2452 switch (SHORT2FROMMP(mp1)) {
2453 case BN_CLICKED:
2454 cmp = INSTDATA(hwnd);
2455 if (cmp)
2456 *cmp->rightlist = 0;
2457 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2458 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2459 break;
[2]2460 }
2461 break;
[551]2462 case COMP_HIDENOTSELECTED:
2463 switch (SHORT2FROMMP(mp1)) {
2464 case BN_CLICKED:
2465 WinSendMsg(hwnd, UM_HIDENOTSELECTED, MPVOID, MPVOID);
2466 break;
2467 }
2468 break;
[2]2469
[551]2470 case COMP_LEFTDIR:
2471 case COMP_RIGHTDIR:
2472 switch (SHORT2FROMMP(mp1)) {
2473 case CN_KILLFOCUS:
2474 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2475 (HPS)0, FALSE, TRUE);
[551]2476 break;
[2]2477
[551]2478 case CN_SETFOCUS:
2479 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2480 (HPS)0, TRUE, TRUE);
[551]2481 break;
[2]2482
[551]2483 case CN_ENTER:
2484 if (mp2) {
[2]2485
[919]2486 PCNRITEM pci = (PCNRITEM)((PNOTIFYRECORDENTER)mp2)->pRecord;
[551]2487 HWND hwndCnr = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
[2]2488
[551]2489 SetShiftState();
2490 if (pci) {
[748]2491 if (pci->rc.flRecordAttr & CRA_INUSE || !pci || !*pci->pszFileName)
[551]2492 break;
2493 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2494 MPFROM2SHORT(TRUE, CRA_INUSE));
2495 if (pci->attrFile & FILE_DIRECTORY) {
2496 if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT))
[730]2497 OpenObject(pci->pszFileName, Settings, hwnd);
[551]2498 else
[730]2499 OpenObject(pci->pszFileName, Default, hwnd);
[551]2500 }
2501 else
2502 DefaultViewKeys(hwnd, hwnd, HWND_DESKTOP, NULL,
[730]2503 pci->pszFileName);
[551]2504 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS,
2505 MPFROMP(pci),
[919]2506 MPFROM2SHORT(FALSE,
2507 CRA_INUSE | (fUnHilite ? CRA_SELECTED : 0)));
[551]2508 }
2509 }
2510 break;
[2]2511
[551]2512 case CN_CONTEXTMENU:
2513 cmp = INSTDATA(hwnd);
2514 if (cmp) {
[919]2515 PCNRITEM pci = (PCNRITEM)mp2;
[551]2516 USHORT id = COMP_CNRMENU;
[2]2517
[551]2518 if (cmp->dcd.hwndLastMenu)
2519 WinDestroyWindow(cmp->dcd.hwndLastMenu);
[919]2520 cmp->dcd.hwndLastMenu = (HWND)0;
[551]2521 cmp->hwndCalling = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2522 if (pci) {
[748]2523 if (!pci || !*pci->pszFileName || *cmp->rightlist)
[551]2524 break;
2525 id = COMP_MENU;
2526 WinSendMsg(cmp->hwndCalling, CM_SETRECORDEMPHASIS,
2527 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2528 }
2529 cmp->dcd.hwndLastMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
2530 if (cmp->dcd.hwndLastMenu) {
2531 if (id == COMP_CNRMENU) {
2532 if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2533 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2534 MPFROM2SHORT(IDM_SHOWSUBJECT, FALSE), MPVOID);
[1065]2535 SetDetailsSwitches(cmp->dcd.hwndLastMenu, &cmp->dcd.ds);
[551]2536 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
2537 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2538 MPFROM2SHORT(IDM_LOADLISTFILE, 0), MPVOID);
2539 else if (*cmp->rightlist)
2540 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2541 MPFROM2SHORT(IDM_SAVELISTFILE, 0), MPVOID);
2542 }
2543 PopupMenu(hwnd, hwnd, cmp->dcd.hwndLastMenu);
2544 }
2545 }
2546 break;
[2]2547
[551]2548 case CN_INITDRAG:
2549 cmp = INSTDATA(hwnd);
2550 if (*cmp->rightlist && SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2551 break;
2552 DoFileDrag(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2553 (HWND)0, mp2, NULL, NULL, TRUE);
[551]2554 break;
[2]2555
[551]2556 case CN_BEGINEDIT:
2557 case CN_REALLOCPSZ:
[929]2558 // fixme to be gone - field edits not allowed?
[551]2559 Runtime_Error(pszSrcFile, __LINE__,
2560 "CN_BEGINEDIT/CN_REALLOCPSZ unexpected");
2561 break;
[2]2562
[551]2563 case CN_EMPHASIS:
2564 {
[919]2565 PNOTIFYRECORDEMPHASIS pnre = mp2;
[929]2566 BOOL fSelected;
[919]2567 if (pnre->fEmphasisMask & CRA_SELECTED) {
[929]2568 // Select toggled
[919]2569 PCNRITEM pci = (PCNRITEM)pnre->pRecord;
[551]2570 if (pci) {
[919]2571 if (!*pci->pszFileName) {
[929]2572 // Slot empty
2573 // 17 Jan 08 SHL fixme to know how can get here
[919]2574 // 12 Jan 08 SHL fixme to know if select counts need update?
[551]2575 if (pci->rc.flRecordAttr & CRA_SELECTED)
2576 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
2577 CM_SETRECORDEMPHASIS,
2578 MPFROMP(pci),
2579 MPFROM2SHORT(FALSE, CRA_SELECTED));
2580 }
2581 else {
[929]2582 BOOL fUpdateHideButton = FALSE;
[551]2583 cmp = INSTDATA(hwnd);
[919]2584 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
[929]2585 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2586 cmp->selleft += fSelected ? 1 : -1;
2587 if (!fSelected)
2588 fUpdateHideButton = TRUE;
[551]2589 }
[919]2590 else if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR) {
[929]2591 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2592 cmp->selright += fSelected ? 1 : -1;
2593 if (!fSelected)
2594 fUpdateHideButton = TRUE;
[551]2595 }
[919]2596 else {
2597 Runtime_Error(pszSrcFile, __LINE__,
2598 "mp1 %u unexpected", SHORT1FROMMP(mp1));
2599 }
[929]2600 if (fUpdateHideButton) {
[1029]2601 ULONG state = WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED);
[929]2602 if (state == 1) {
2603 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
2604 }
2605 }
[551]2606 }
2607 }
2608 }
2609 }
2610 break;
[2]2611
[551]2612 case CN_SCROLL:
2613 cmp = INSTDATA(hwnd);
2614 if (!cmp->forcescroll) {
[2]2615
[551]2616 PNOTIFYSCROLL pns = mp2;
[2]2617
[551]2618 if (pns->fScroll & CMA_VERTICAL) {
2619 cmp->forcescroll = TRUE;
[919]2620 // Scroll other window to match
2621 WinSendDlgItemMsg(hwnd,
2622 SHORT1FROMMP(mp1) == COMP_LEFTDIR ?
2623 COMP_RIGHTDIR : COMP_LEFTDIR,
2624 CM_SCROLLWINDOW,
2625 MPFROMSHORT(CMA_VERTICAL),
[551]2626 MPFROMLONG(pns->lScrollInc));
2627 cmp->forcescroll = FALSE;
2628 }
2629 }
2630 break;
[919]2631 } // switch COMP_LEFTDIR mp1
2632 break; // COMP_LEFTDIR / COMP_RIGHTDIR
2633 } // switch WM_CONTROL mp1
[551]2634 return 0; // WM_CONTROL
[2]2635
[551]2636 case UM_SETDIR:
2637 cmp = INSTDATA(hwnd);
2638 if (cmp) {
2639 COMPARE *forthread;
2640 CNRINFO cnri;
2641 cmp->includesubdirs = WinQueryButtonCheckstate(hwnd,
2642 COMP_INCLUDESUBDIRS);
2643 memset(&cnri, 0, sizeof(CNRINFO));
2644 cnri.cb = sizeof(CNRINFO);
2645 cnri.pszCnrTitle = cmp->leftdir;
2646 cnri.flWindowAttr = CV_DETAIL | CV_MINI |
[751]2647 CA_CONTAINERTITLE | CA_TITLESEPARATOR |
2648 CA_DETAILSVIEWTITLES | CA_OWNERDRAW;
[551]2649 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2650 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2651 cnri.pszCnrTitle = cmp->rightdir;
2652 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2653 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2654 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 0);
2655 cmp->filling = TRUE;
[1063]2656# ifdef FORTIFY
2657 Fortify_EnterScope();
2658# endif
[551]2659 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2660 if (!forthread)
2661 WinDismissDlg(hwnd, 0);
2662 else {
2663 *forthread = *cmp;
2664 forthread->cmp = cmp;
[919]2665 if (_beginthread(FillCnrsThread, NULL, 122880, (PVOID)forthread) ==
[551]2666 -1) {
2667 Runtime_Error(pszSrcFile, __LINE__,
2668 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2669 WinDismissDlg(hwnd, 0);
[1039]2670 free(forthread);
[1063]2671# ifdef FORTIFY
2672 Fortify_LeaveScope();
2673# endif
[551]2674 }
[362]2675 else {
[551]2676 WinEnableWindowUpdate(hwndLeft, FALSE);
2677 WinEnableWindowUpdate(hwndRight, FALSE);
2678 cmp->selleft = cmp->selright = 0;
2679 WinSetDlgItemText(hwnd, COMP_NOTE,
2680 GetPString(IDS_COMPHOLDREADDISKTEXT));
2681 WinEnableWindow(hwndRight, FALSE);
2682 WinEnableWindow(hwndLeft, FALSE);
2683 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2684 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2685 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2686 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2687 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2688 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2689 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2690 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2691 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2692 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2693 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2694 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2695 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2696 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2697 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
2698 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2699 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2700 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2701 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2702 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2703 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2704 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2705 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
[919]2706 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
[551]2707 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
2708 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2709 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2710 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
[919]2711 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
2712 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
[551]2713 }
[2]2714 }
[551]2715 }
2716 return 0;
[2]2717
[551]2718 case UM_FILTER:
2719 cmp = INSTDATA(hwnd);
2720 if (cmp) {
2721 if (mp1) {
2722 DosEnterCritSec();
[919]2723 SetMask((CHAR *)mp1, &cmp->dcd.mask);
[551]2724 DosExitCritSec();
[2]2725 }
[919]2726 WinSetDlgItemText(hwnd, COMP_NOTE,
2727 GetPString(IDS_COMPHOLDFILTERINGTEXT));
2728 // cmp->dcd.suspendview = 1; // 12 Jan 08 SHL appears not to be used here
2729 priority_idle(); // Don't hog resources
[551]2730 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2731 MPFROMP(&cmp->dcd.mask));
2732 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2733 MPFROMP(&cmp->dcd.mask));
[919]2734 priority_normal();
2735 // cmp->dcd.suspendview = 0; // 12 Jan 08 SHL appears not to be used here
2736 if (*cmp->dcd.mask.szMask) {
2737 sprintf(s,
2738 GetPString(IDS_COMPREADYFILTEREDTEXT),
2739 cmp->dcd.mask.szMask);
2740 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2741 }
[551]2742 else
2743 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2744 }
2745 return 0;
[2]2746
[551]2747 case UM_HIDENOTSELECTED:
2748 cmp = INSTDATA(hwnd);
2749 if (cmp) {
[1029]2750 ULONG wasHidden = WinQueryButtonCheckstate(hwnd,
[929]2751 COMP_HIDENOTSELECTED);
[316]2752
[919]2753 // cmp->dcd.suspendview = 1; // 12 Jan 08 SHL appears not to be used here
[929]2754 if (wasHidden != 1) {
2755 // Hide if not selected on both sides
[551]2756 BOOL needRefresh = FALSE;
2757 HWND hwndl = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
2758 HWND hwndr = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
2759 PCNRITEM pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPVOID,
2760 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2761 PCNRITEM pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPVOID,
2762 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2763
[919]2764 while (pcil && (INT)pcil != -1 && pcir && (INT)pcir != -1) {
[551]2765 if (~pcil->rc.flRecordAttr & CRA_SELECTED &&
2766 ~pcir->rc.flRecordAttr & CRA_SELECTED) {
[929]2767 // 17 Jan 08 SHL fixme to optimize refresh
[551]2768 pcil->rc.flRecordAttr |= CRA_FILTERED;
2769 pcir->rc.flRecordAttr |= CRA_FILTERED;
2770 needRefresh = TRUE;
[316]2771 }
[551]2772 pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPFROMP(pcil),
2773 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2774 pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPFROMP(pcir),
2775 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]2776 } // while
[551]2777 if (needRefresh) {
2778 WinSendMsg(hwndl, CM_INVALIDATERECORD,
2779 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2780 WinSendMsg(hwndr, CM_INVALIDATERECORD,
2781 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
[316]2782 }
2783 }
[551]2784 else {
[929]2785 // Unhide
[551]2786 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2787 MPFROMP(&cmp->dcd.mask));
2788 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2789 MPFROMP(&cmp->dcd.mask));
2790 }
[919]2791 // cmp->dcd.suspendview = 0; // 12 Jan 08 SHL appears not to be used here
2792 if (*cmp->dcd.mask.szMask) {
2793 sprintf(s,
2794 GetPString(IDS_COMPREADYFILTEREDTEXT),
2795 cmp->dcd.mask.szMask);
2796 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2797 }
[551]2798 else
2799 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
[929]2800 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, wasHidden != 1 ? 1 : 0);
[551]2801 }
2802 return 0;
[316]2803
[551]2804 case WM_COMMAND:
2805 switch (SHORT1FROMMP(mp1)) {
2806 case IDM_COMPARE:
2807 cmp = INSTDATA(hwnd);
2808 if (cmp) {
2809 PCNRITEM pci;
2810 CHAR ofile[CCHMAXPATH];
[2]2811
[919]2812 pci = (PCNRITEM)WinSendMsg(cmp->hwndCalling,
2813 CM_QUERYRECORDEMPHASIS,
2814 MPFROMLONG(CMA_FIRST),
2815 MPFROMSHORT(CRA_CURSORED));
[748]2816 // 01 Aug 07 SHL
2817 if (pci && *pci->pszFileName) {
[551]2818 if (cmp->hwndCalling == hwndLeft)
2819 strcpy(ofile, cmp->rightdir);
2820 else
2821 strcpy(ofile, cmp->leftdir);
2822 if (ofile[strlen(ofile) - 1] != '\\')
2823 strcat(ofile, "\\");
[751]2824 strcat(ofile, pci->pszDisplayName);
[551]2825 if (*compare) {
2826 CHAR *fakelist[3];
[730]2827 fakelist[0] = pci->pszFileName;
[551]2828 fakelist[1] = ofile;
2829 fakelist[2] = NULL;
2830 ExecOnList(hwnd, compare,
[907]2831 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL,
2832 pszSrcFile, __LINE__);
[551]2833 }
2834 else {
2835 FCOMPARE fc;
2836 memset(&fc, 0, sizeof(fc));
2837 fc.size = sizeof(fc);
2838 fc.hwndParent = hwnd;
[730]2839 strcpy(fc.file1, pci->pszFileName);
[551]2840 strcpy(fc.file2, ofile);
2841 WinDlgBox(HWND_DESKTOP, hwnd,
[919]2842 CFileDlgProc, FM3ModHandle, FCMP_FRAME, (PVOID)&fc);
[551]2843 }
2844 }
2845 }
2846 break;
[2]2847
[551]2848 case COMP_FILTER:
2849 case IDM_FILTER:
2850 cmp = INSTDATA(hwnd);
2851 if (cmp) {
2852 BOOL empty = FALSE;
2853 PCNRITEM pci;
2854 CHAR *p;
2855 BOOL temp;
[2]2856
[551]2857 if (!*cmp->dcd.mask.szMask) {
2858 empty = TRUE;
2859 temp = fSelectedAlways;
2860 fSelectedAlways = TRUE;
[748]2861 pci = (PCNRITEM)CurrentRecord(hwnd);
[551]2862 fSelectedAlways = temp;
[748]2863 // 01 Aug 07 SHL
2864 if (pci && ~pci->attrFile & FILE_DIRECTORY) {
[730]2865 p = strrchr(pci->pszFileName, '\\');
[551]2866 if (p) {
2867 p++;
2868 strcpy(cmp->dcd.mask.szMask, p);
2869 }
2870 }
2871 }
2872 cmp->dcd.mask.fNoAttribs = TRUE;
2873 cmp->dcd.mask.attrFile = ALLATTRS;
2874 cmp->dcd.mask.antiattr = 0;
2875 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2876 FM3ModHandle, MSK_FRAME, MPFROMP(&cmp->dcd.mask))) {
2877 cmp->dcd.mask.attrFile = ALLATTRS;
2878 cmp->dcd.mask.antiattr = 0;
2879 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2880 }
2881 else if (empty) {
2882 *cmp->dcd.mask.szMask = 0;
2883 cmp->dcd.mask.attrFile = ALLATTRS;
2884 cmp->dcd.mask.antiattr = 0;
2885 }
2886 }
2887 break;
[2]2888
[551]2889 case IDM_SHOWSUBJECT:
2890 case IDM_SHOWEAS:
2891 case IDM_SHOWSIZE:
2892 case IDM_SHOWLWDATE:
2893 case IDM_SHOWLWTIME:
2894 case IDM_SHOWLADATE:
2895 case IDM_SHOWLATIME:
2896 case IDM_SHOWCRDATE:
2897 case IDM_SHOWCRTIME:
2898 case IDM_SHOWATTR:
2899 cmp = INSTDATA(hwnd);
2900 if (cmp) {
2901 DIRCNRDATA dcd1;
2902 BOOL tempsubj;
[2]2903
[551]2904 dcd1 = cmp->dcd;
2905 AdjustDetailsSwitches(hwndLeft,
[919]2906 (HWND)0, SHORT1FROMMP(mp1),
[1065]2907 cmp->leftdir, "DirCmp", &cmp->dcd.ds, TRUE);
2908 tempsubj = cmp->dcd.ds.detailssubject;
[551]2909 cmp->dcd = dcd1;
[1065]2910 cmp->dcd.ds.detailssubject = FALSE;
[551]2911 AdjustDetailsSwitches(hwndRight,
2912 cmp->dcd.hwndLastMenu, SHORT1FROMMP(mp1),
[1065]2913 cmp->rightdir, "DirCmp", &cmp->dcd.ds, TRUE);
2914 cmp->dcd.ds.detailssubject = tempsubj;
[551]2915 }
2916 break;
[2]2917
[551]2918 case IDM_LOADLISTFILE:
2919 cmp = INSTDATA(hwnd);
2920 if (cmp) {
2921 CHAR fullname[CCHMAXPATH];
[2]2922
[551]2923 strcpy(fullname, "*.PMD");
2924 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
2925 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?')) {
2926 strcpy(cmp->rightlist, fullname);
2927 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2928 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2929 }
2930 }
2931 break;
[2]2932
[551]2933 case IDM_SAVELISTFILE:
2934 cmp = INSTDATA(hwnd);
2935 if (cmp) {
2936 SNAPSTUFF *sf;
2937 CHAR fullname[CCHMAXPATH];
[2]2938
[551]2939 strcpy(fullname, "*.PMD");
2940 if (export_filename(HWND_DESKTOP, fullname, 1) && *fullname &&
2941 !strchr(fullname, '*') && !strchr(fullname, '?')) {
2942 sf = xmallocz(sizeof(SNAPSTUFF), pszSrcFile, __LINE__);
2943 if (sf) {
2944 strcpy(sf->filename, fullname);
2945 if (hwndLeft == cmp->hwndCalling)
2946 strcpy(sf->dirname, cmp->leftdir);
2947 else
2948 strcpy(sf->dirname, cmp->rightdir);
2949 sf->recurse = cmp->includesubdirs;
[919]2950 if (_beginthread(StartSnap, NULL, 65536, (PVOID)sf) == -1) {
[551]2951 Runtime_Error(pszSrcFile, __LINE__,
2952 GetPString(IDS_COULDNTSTARTTHREADTEXT));
[1039]2953 free(sf);
[551]2954 }
2955 }
2956 }
2957 }
2958 break;
[2]2959
[551]2960 case COMP_SETDIRS:
2961 cmp = INSTDATA(hwnd);
2962 if (cmp) {
2963 WALK2 wa;
2964 memset(&wa, 0, sizeof(wa));
2965 wa.size = sizeof(wa);
2966 strcpy(wa.szCurrentPath1, cmp->leftdir);
2967 strcpy(wa.szCurrentPath2, cmp->rightdir);
[919]2968 if (WinDlgBox(HWND_DESKTOP,
2969 hwnd,
2970 WalkTwoCmpDlgProc,
2971 FM3ModHandle,
2972 WALK2_FRAME,
[551]2973 MPFROMP(&wa)) &&
[769]2974 !IsFile(wa.szCurrentPath1) &&
2975 !IsFile(wa.szCurrentPath2)) {
[551]2976 strcpy(cmp->leftdir, wa.szCurrentPath1);
2977 strcpy(cmp->rightdir, wa.szCurrentPath2);
2978 *cmp->rightlist = 0;
2979 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2980 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2981 }
2982 }
2983 break;
[2]2984
[551]2985 case COMP_COPYLEFT:
2986 case COMP_MOVELEFT:
2987 case COMP_COPYRIGHT:
2988 case COMP_MOVERIGHT:
2989 case COMP_DELETELEFT:
2990 case COMP_DELETERIGHT:
2991 cmp = INSTDATA(hwnd);
2992 if (cmp) {
2993 COMPARE *forthread;
[2]2994
[551]2995 cmp->filling = TRUE;
2996 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2997 if (forthread) {
2998 *forthread = *cmp;
2999 forthread->cmp = cmp;
3000 forthread->action = SHORT1FROMMP(mp1);
[919]3001 if (_beginthread(ActionCnrThread, NULL, 122880, (PVOID)forthread)
[551]3002 == -1) {
3003 Runtime_Error(pszSrcFile, __LINE__,
3004 GetPString(IDS_COULDNTSTARTTHREADTEXT));
[1039]3005 free(forthread);
[551]3006 }
3007 else {
3008 WinEnableWindowUpdate(hwndLeft, FALSE);
3009 WinEnableWindowUpdate(hwndRight, FALSE);
3010 switch (SHORT1FROMMP(mp1)) {
3011 case COMP_DELETELEFT:
3012 case COMP_DELETERIGHT:
3013 WinSetDlgItemText(hwnd, COMP_NOTE,
3014 GetPString(IDS_COMPHOLDDELETINGTEXT));
3015 break;
3016 case COMP_MOVELEFT:
3017 case COMP_MOVERIGHT:
3018 WinSetDlgItemText(hwnd, COMP_NOTE,
3019 GetPString(IDS_COMPHOLDMOVINGTEXT));
3020 break;
3021 case COMP_COPYLEFT:
3022 case COMP_COPYRIGHT:
3023 WinSetDlgItemText(hwnd, COMP_NOTE,
3024 GetPString(IDS_COMPHOLDCOPYINGTEXT));
3025 break;
3026 default:
[919]3027 Runtime_Error(pszSrcFile, __LINE__, "mp1 %u unexpected", SHORT1FROMMP(mp1));
[551]3028 }
3029 WinEnableWindow(hwndRight, FALSE);
3030 WinEnableWindow(hwndLeft, FALSE);
3031 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
3032 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
3033 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
3034 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
3035 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
3036 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
3037 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
3038 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
3039 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
3040 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
3041 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
3042 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
3043 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
3044 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
[919]3045 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
[551]3046 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
3047 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
3048 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
3049 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
3050 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
3051 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
3052 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
3053 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
[919]3054 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
3055 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
[551]3056 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
3057 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
3058 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
[919]3059 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
3060 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
[551]3061 }
3062 }
3063 }
3064 break;
[2]3065
[551]3066 case DID_OK:
[938]3067 {
3068 SWP swp;
3069 ULONG size = sizeof(SWP);
3070
3071 WinQueryWindowPos(hwnd, &swp);
3072 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
3073 size);
3074 }
[551]3075 WinDismissDlg(hwnd, 0);
3076 break;
3077 case DID_CANCEL:
[938]3078 {
3079 SWP swp;
3080 ULONG size = sizeof(SWP);
3081
3082 WinQueryWindowPos(hwnd, &swp);
3083 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
3084 size);
3085 }
[551]3086 WinDismissDlg(hwnd, 1);
3087 break;
[2]3088
[551]3089 case IDM_HELP:
3090 if (hwndHelp)
3091 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
3092 MPFROM2SHORT(HELP_COMPARE, 0), MPFROMSHORT(HM_RESOURCEID));
3093 break;
[2]3094
[551]3095 case IDM_DESELECTALL:
3096 case IDM_SELECTNEWER:
3097 case IDM_SELECTOLDER:
3098 case IDM_SELECTBIGGER:
3099 case IDM_SELECTSMALLER:
3100 case IDM_DESELECTNEWER:
3101 case IDM_DESELECTOLDER:
3102 case IDM_DESELECTBIGGER:
3103 case IDM_DESELECTSMALLER:
3104 case IDM_DESELECTONE:
3105 case IDM_DESELECTBOTH:
3106 case IDM_SELECTBOTH:
3107 case IDM_SELECTONE:
3108 case IDM_SELECTSAMECONTENT:
[748]3109 case IDM_SELECTIDENTICAL: // Name, size and time
3110 case IDM_SELECTSAME: // Name and size
[551]3111 case IDM_INVERT:
3112 cmp = INSTDATA(hwnd);
3113 if (!cmp)
3114 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
3115 else {
3116 COMPARE *forthread;
3117
3118 cmp->filling = TRUE;
3119 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
3120 if (forthread) {
3121 *forthread = *cmp;
3122 forthread->cmp = cmp;
3123 forthread->action = SHORT1FROMMP(mp1);
[919]3124 if (_beginthread(SelectCnrsThread, NULL, 65536, (PVOID)forthread)
[551]3125 == -1) {
3126 Runtime_Error(pszSrcFile, __LINE__,
3127 GetPString(IDS_COULDNTSTARTTHREADTEXT));
[1039]3128 free(forthread);
[551]3129 }
[362]3130 else {
[551]3131 WinEnableWindowUpdate(hwndLeft, FALSE);
3132 WinEnableWindowUpdate(hwndRight, FALSE);
3133 switch (SHORT1FROMMP(mp1)) {
3134 case IDM_DESELECTALL:
3135 case IDM_DESELECTNEWER:
3136 case IDM_DESELECTOLDER:
3137 case IDM_DESELECTBIGGER:
3138 case IDM_DESELECTSMALLER:
3139 case IDM_DESELECTONE:
3140 case IDM_DESELECTBOTH:
3141 WinSetDlgItemText(hwnd, COMP_NOTE,
3142 GetPString(IDS_COMPHOLDDESELTEXT));
3143 break;
3144 case IDM_INVERT:
3145 WinSetDlgItemText(hwnd, COMP_NOTE,
3146 GetPString(IDS_COMPHOLDINVERTTEXT));
3147 break;
3148 default:
3149 WinSetDlgItemText(hwnd, COMP_NOTE,
3150 GetPString(IDS_COMPHOLDSELTEXT));
3151 break;
3152 }
3153 WinEnableWindow(hwndRight, FALSE);
3154 WinEnableWindow(hwndLeft, FALSE);
3155 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
3156 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
3157 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
3158 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
3159 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
3160 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
3161 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
3162 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
3163 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
3164 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
3165 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
3166 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
3167 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
3168 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
[919]3169 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
[551]3170 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
[919]3171 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
3172 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
[551]3173 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
3174 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
3175 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
3176 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
3177 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
3178 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
3179 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
[919]3180 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
3181 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
[551]3182 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
3183 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
3184 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
3185 }
3186 }
3187 }
3188 break;
[2]3189
[551]3190 case COMP_COLLECT:
3191 cmp = INSTDATA(hwnd);
[773]3192 if (!cmp)
3193 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
3194 else {
3195 CHAR **listl;
3196 CHAR **listr = NULL;
[551]3197 if (!Collector) {
3198 SWP swp;
3199 HWND hwndC;
[773]3200 if (!fAutoTile &&
3201 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3202 !fExternalCollector &&
3203 !strcmp(realappname, FM3Str)) {
[551]3204 GetNextWindowPos(cmp->hwndParent, &swp, NULL, NULL);
[773]3205 }
3206 hwndC = StartCollector(fExternalCollector ||
3207 strcmp(realappname, FM3Str) ?
3208 HWND_DESKTOP :
3209 cmp->hwndParent,
3210 4);
[551]3211 if (hwndC) {
[773]3212 if (!fAutoTile &&
3213 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3214 !fExternalCollector &&
3215 !strcmp(realappname, FM3Str)) {
3216 WinSetWindowPos(hwndC, HWND_TOP,
3217 swp.x, swp.y, swp.cx, swp.cy,
3218 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
3219 }
3220 else if (!ParentIsDesktop(hwnd, cmp->hwndParent) &&
3221 fAutoTile &&
3222 !strcmp(realappname, FM3Str)) {
[551]3223 TileChildren(cmp->hwndParent, TRUE);
[773]3224 }
[924]3225 DosSleep(1); // 12 Jan 08 SHL Let screen update
[551]3226 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(COMP_COLLECT, 0), MPVOID);
3227 break;
3228 }
3229 }
3230 else
3231 StartCollector(cmp->hwndParent, 4);
[2]3232
[773]3233 temp = fSelectedAlways;
3234 fSelectedAlways = TRUE;
3235 listl = BuildList(hwndLeft);
3236 if (!*cmp->rightlist)
3237 listr = BuildList(hwndRight);
3238 fSelectedAlways = temp;
3239
[551]3240 if (listl || listr) {
3241 if (Collector) {
[773]3242 // 07 Aug 07 SHL Avoid collected from empty list
3243 if (listl && listl[0] && *listl[0]) {
3244 if (PostMsg(Collector, WM_COMMAND,
3245 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listl)))
3246 listl = NULL; // Collector will free
[551]3247 }
[773]3248 if (listr && listr[0] && *listr[0]) {
3249 if (PostMsg(Collector, WM_COMMAND,
3250 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listr)))
3251 listr = NULL; // Collector will free
[551]3252 }
3253 WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
3254 QW_PARENT),
[773]3255 QW_PARENT),
3256 HWND_TOP, 0, 0, 0, 0,
[551]3257 SWP_ACTIVATE);
3258 }
[773]3259 FreeList(listl);
3260 FreeList(listr);
[551]3261 }
[2]3262 }
[551]3263 break;
3264 }
3265 return 0;
[2]3266
[551]3267 case WM_CLOSE:
[929]3268 // 18 Jan 08 SHL fixme to hold off if thread busy?
[551]3269 WinDismissDlg(hwnd, 0);
3270 return 0;
[2]3271
[551]3272 case WM_DESTROY:
3273 cmp = INSTDATA(hwnd);
3274 if (cmp) {
[929]3275 // 17 Jan 08 SHL fixme to know if stop really needed?
3276 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER);
[551]3277 if (cmp->dcd.hwndLastMenu)
3278 WinDestroyWindow(cmp->dcd.hwndLastMenu);
3279 if (cmp->dcd.hwndObject) {
[919]3280 WinSetWindowPtr(cmp->dcd.hwndObject, QWL_USER, (PVOID)NULL);
[551]3281 if (!PostMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID))
3282 WinSendMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID);
[2]3283 }
[1039]3284 free(cmp);
[551]3285 }
3286 EmptyCnr(hwndLeft);
3287 EmptyCnr(hwndRight);
3288 DosPostEventSem(CompactSem);
3289 break;
[2]3290 }
[551]3291 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]3292}
[783]3293
3294#pragma alloc_text(COMPAREDIR,FillCnrsThread,FillDirList,CompNames,BldFullPathName)
3295#pragma alloc_text(COMPAREDIR1,CompareDlgProc)
3296#pragma alloc_text(COMPAREDIR2,SelectCnrsThread,ActionCnrThread)
3297#pragma alloc_text(COMPAREFILE,CFileDlgProc,CompareFilesThread)
3298#pragma alloc_text(SNAPSHOT,SnapShot,StartSnap)
[924]3299#pragma alloc_text(COMPSELECT,CompSelect)
[783]3300
Note: See TracBrowser for help on using the repository browser.