source: trunk/dll/comp.c@ 1400

Last change on this file since 1400 was 1400, checked in by Gregg Young, 16 years ago

Remainder of changes to rename commafmt.h/c (Ticket 28, 82); Additional strings moved to PCSZs in init.c (Ticket 6); Added WriteDetailsSwitches used it and LoadDetailsSwitches to consolidate inline code (Ticket 343, 344)

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