source: trunk/dll/comp.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 17 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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