source: trunk/dll/comp.c@ 1205

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

Ticket 187: Move datadevlarations/definitions out of fm3dll.h

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