source: trunk/dll/objcnr.c @ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 13 years ago

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1
2/***********************************************************************
3
4  $Id: objcnr.c 751 2007-08-02 23:05:48Z stevenhl $
5
6  Object containers
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2005, 2007 Steven H. Levine
10
11  24 May 05 SHL Rework for CNRITEM.szSubject
12  13 Jul 06 SHL Use Runtime_Error
13  01 Sep 06 SHL Do not complain for normal cancel
14  19 Oct 06 SHL Correct . and .. detect
15  03 Nov 06 SHL Renames
16  22 Mar 07 GKY Use QWL_USER
17  01 Aug 07 SHL Rework to sync with CNRITEM mods
18
19***********************************************************************/
20
21#define INCL_DOS
22#define INCL_WIN
23#include <os2.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include <process.h>                    // _beginthread
30
31#include "fm3dll.h"
32#include "fm3dlg.h"
33#include "fm3str.h"
34
35typedef struct
36{
37  CHAR *filename;
38  HWND hwndCnr;
39  CHAR *stopflag;
40}
41DIRSIZE;
42
43typedef struct
44{
45  CHAR *dirname;
46  CHAR stopflag;
47  BOOL dying;
48  BOOL working;
49}
50TEMP;
51
52#pragma data_seg(DATA1)
53
54static PSZ pszSrcFile = __FILE__;
55
56static HWND objcnrwnd;
57
58#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
59
60static VOID ProcessDir(HWND hwndCnr, CHAR * filename, PCNRITEM pciParent,
61                       CHAR * stopflag)
62{
63  CHAR maskstr[CCHMAXPATH], *endpath, *p;
64  ULONG nm, ulM;
65  HDIR hdir;
66  FILEFINDBUF3 *ffb, *fft;
67  APIRET rc;
68  RECORDINSERT ri;
69  PCNRITEM pciP;
70
71  ffb = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
72  if (!ffb)
73    return;
74  strcpy(maskstr, filename);
75  if (maskstr[strlen(maskstr) - 1] != '\\')
76    strcat(maskstr, "\\");
77  endpath = &maskstr[strlen(maskstr)];
78  strcat(maskstr, "*");
79  hdir = HDIR_CREATE;
80  nm = 1L;
81  rc = DosFindFirst(filename, &hdir,
82                    FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
83                    FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
84                    ffb, sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
85  if (!rc)
86    DosFindClose(hdir);
87
88  if (rc) {                             /* work around furshluginer FAT bug... */
89    if (IsRoot(filename))
90      rc = 0;
91  }
92
93  if ((!rc && (ffb->attrFile & FILE_DIRECTORY))) {
94    pciP = WinSendMsg(hwndCnr,
95                      CM_ALLOCRECORD,
96                      MPFROMLONG(EXTRA_RECORD_BYTES),
97                      MPFROMLONG(1L));
98    if (!pciP) {
99      free(ffb);
100      return;
101    }
102    pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
103    pciP->pszDispAttr = NullStr;
104    pciP->pszSubject = NullStr;
105    pciP->pszLongname = NullStr;
106    if (strlen(filename) < 4)
107      pciP->pszDisplayName = pciP->pszFileName;
108    else {
109      p = strrchr(pciP->pszFileName, '\\');
110      if (!p)
111        pciP->pszFileName = pciP->pszFileName;
112      else if (*(p + 1))
113        p++;
114      pciP->pszDisplayName = p;
115    }
116    pciP->rc.pszIcon = pciP->pszDisplayName;
117    if (fForceUpper)
118      strupr(pciP->pszFileName);
119    else if (fForceLower)
120      strlwr(pciP->pszFileName);
121    pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
122  }
123  else {
124    free(ffb);
125    Dos_Error(MB_ENTER,
126              rc,
127              HWND_DESKTOP,
128              pszSrcFile,
129              __LINE__, GetPString(IDS_CANTFINDDIRTEXT), filename);
130    return;
131  }
132  {
133    HPOINTER hptr;
134
135    hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
136    if (hptr)
137      pciP->rc.hptrIcon = hptr;
138  }
139  if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile)      /* OS/2 bug bug bug bug */
140    pciP->rc.hptrIcon = hptrDir;
141  memset(&ri, 0, sizeof(RECORDINSERT));
142  ri.cb = sizeof(RECORDINSERT);
143  ri.pRecordOrder = (PRECORDCORE) CMA_END;
144  ri.pRecordParent = (PRECORDCORE) pciParent;
145  ri.zOrder = (USHORT) CMA_TOP;
146  ri.cRecordsInsert = 1L;
147  ri.fInvalidateRecord = TRUE;
148  if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
149    free(ffb);
150    return;
151  }
152  hdir = HDIR_CREATE;
153  if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
154      ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
155    ulM = 1L;
156  else
157    ulM = min(FilesToGet, 225);
158  if (ulM > 1L) {
159    fft = xrealloc(ffb, sizeof(FILEFINDBUF3) * ulM, pszSrcFile, __LINE__);
160    if (!fft)
161      ulM = 1L;
162    else
163      ffb = fft;
164  }
165  nm = ulM;
166  rc = DosFindFirst(maskstr, &hdir,
167                    FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
168                    FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY, ffb,
169                    sizeof(FILEFINDBUF3) * ulM, &nm, FIL_STANDARD);
170  if (!rc) {
171
172    register PBYTE fb = (PBYTE) ffb;
173    FILEFINDBUF3 *pffbFile;
174    ULONG x;
175
176    while (!rc) {
177      for (x = 0L; x < nm; x++) {
178        pffbFile = (FILEFINDBUF3 *) fb;
179        if (*stopflag)
180          break;
181        if ((pffbFile->attrFile & FILE_DIRECTORY) &&
182            // Skip . and ..
183            (pffbFile->achName[0] != '.' ||
184             (pffbFile->achName[1] &&
185              (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
186          strcpy(endpath, pffbFile->achName);
187          ProcessDir(hwndCnr, maskstr, pciP, stopflag);
188        }
189        if (!pffbFile->oNextEntryOffset)
190          break;
191        fb += pffbFile->oNextEntryOffset;
192      }
193      DosSleep(0L);
194      if (*stopflag)
195        break;
196      nm = ulM;
197      rc = DosFindNext(hdir, ffb, sizeof(FILEFINDBUF3) * ulM, &nm);
198    }
199    DosFindClose(hdir);
200  }
201  free(ffb);
202  WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
203             MPFROM2SHORT(1, 0));
204}
205
206static VOID FillCnrsThread(VOID * args)
207{
208  HAB hab;
209  HMQ hmq;
210  DIRSIZE *dirsize = (DIRSIZE *) args;
211
212  if (!dirsize)
213    return;
214
215  DosError(FERR_DISABLEHARDERR);
216
217  hab = WinInitialize(0);
218  if (hab) {
219    hmq = WinCreateMsgQueue(hab, 0);
220    if (hmq) {
221      WinCancelShutdown(hmq, TRUE);
222      ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
223                 dirsize->stopflag);
224      DosPostEventSem(CompactSem);
225      WinDestroyMsgQueue(hmq);
226    }
227    WinTerminate(hab);
228  }
229  PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
230          MPVOID, MPVOID);
231  free(dirsize);
232}
233
234MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
235{
236  TEMP *data;
237
238  switch (msg) {
239  case WM_INITDLG:
240    if (objcnrwnd) {
241      Runtime_Error(pszSrcFile, __LINE__, "objcnrwnd set");
242      WinSetWindowPos(objcnrwnd, HWND_TOP, 0, 0, 0, 0,
243                      SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
244      WinDismissDlg(hwnd, 0);
245      break;
246    }
247    if (!mp2) {
248      Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
249      WinDismissDlg(hwnd, 0);
250      break;
251    }
252    objcnrwnd = hwnd;
253    data = xmallocz(sizeof(TEMP), pszSrcFile, __LINE__);
254    if (!data) {
255      WinDismissDlg(hwnd, 0);
256      break;
257    }
258    data->dirname = (CHAR *) mp2;
259    WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
260    if (*data->dirname)
261      WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
262    {
263      DIRSIZE *dirsize;
264
265      dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
266      if (!dirsize) {
267        WinDismissDlg(hwnd, 0);
268        break;
269      }
270      dirsize->stopflag = (CHAR *) & data->stopflag;
271      dirsize->filename = data->dirname;
272      dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
273      if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
274          -1) {
275        Runtime_Error(pszSrcFile, __LINE__,
276                      GetPString(IDS_COULDNTSTARTTHREADTEXT));
277        free(dirsize);
278        WinDismissDlg(hwnd, 0);
279        break;
280      }
281      else
282        data->working = TRUE;
283    }
284    PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
285    break;
286
287  case UM_SETUP:
288    // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
289    {
290      CNRINFO cnri;
291
292      memset(&cnri, 0, sizeof(CNRINFO));
293      cnri.cb = sizeof(CNRINFO);
294      WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
295                        MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
296      cnri.cyLineSpacing = 0;
297      cnri.cxTreeIndent = 12L;
298      cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
299      cnri.flWindowAttr = CV_TREE | CV_FLOW |
300        CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
301      if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
302        cnri.flWindowAttr |= CV_MINI;
303      WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
304                        MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
305                                   CMA_CXTREEINDENT));
306    }
307    return 0;
308
309  case UM_CONTAINER_FILLED:
310    WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
311//      WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
312    WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
313                      MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
314    data = INSTDATA(hwnd);
315    if (data) {
316      data->working = FALSE;
317      if (data->dying)
318        WinDismissDlg(hwnd, 0);
319      {
320        PCNRITEM pci;
321        USHORT id;
322
323        id = WinQueryWindowUShort(hwnd, QWS_ID);
324        pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
325                                           CM_QUERYRECORD,
326                                           MPVOID,
327                                           MPFROM2SHORT(CMA_FIRST,
328                                                        CMA_ITEMORDER));
329        if (pci && (INT) pci != -1) {
330          ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), TRUE, pci);
331          if (id == QTREE_FRAME)
332            pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
333                                               CM_QUERYRECORD,
334                                               MPFROMP(pci),
335                                               MPFROM2SHORT(CMA_FIRSTCHILD,
336                                                            CMA_ITEMORDER));
337        }
338        if ((!pci || (INT) pci == -1) && id == QTREE_FRAME) {
339          Notify(GetPString(IDS_NODIRSUNDERTEXT));
340          WinDismissDlg(hwnd, 0);
341          break;
342        }
343      }
344    }
345    return 0;
346
347  case WM_CONTROL:
348    switch (SHORT1FROMMP(mp1)) {
349    case OBJCNR_CNR:
350      if (SHORT2FROMMP(mp1) == CN_ENTER) {
351
352        PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
353
354        if (pci && (INT) pci != -1)
355          WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
356      }
357      break;
358    }
359    return 0;
360
361  case WM_COMMAND:
362    switch (SHORT1FROMMP(mp1)) {
363    case IDM_HELP:
364      if (hwndHelp) {
365
366        USHORT id;
367
368        id = WinQueryWindowUShort(hwnd, QWS_ID);
369
370        if (id == QTREE_FRAME)
371          WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
372                     MPFROM2SHORT(HELP_QUICKTREE, 0),
373                     MPFROMSHORT(HM_RESOURCEID));
374        else
375          WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
376                     MPFROM2SHORT(HELP_OBJECTPATH, 0),
377                     MPFROMSHORT(HM_RESOURCEID));
378      }
379      break;
380
381    case OBJCNR_DESKTOP:
382    case DID_OK:
383      data = INSTDATA(hwnd);
384      if (data) {
385
386        PCNRITEM pci;
387
388        if (data->working) {
389          Runtime_Error(pszSrcFile, __LINE__, "working unexpected");
390          break;
391        }
392        if (SHORT1FROMMP(mp1) == OBJCNR_DESKTOP) {
393          WinDismissDlg(hwnd, 2);
394          break;
395        }
396        pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
397                                           CM_QUERYRECORDEMPHASIS,
398                                           MPFROMLONG(CMA_FIRST),
399                                           MPFROMSHORT(CRA_CURSORED));
400        if (pci && (INT) pci != -1)
401          strcpy(data->dirname, pci->pszFileName);
402        WinDismissDlg(hwnd, 1);
403      }
404      break;
405
406    case DID_CANCEL:
407      data = INSTDATA(hwnd);
408      if (data) {
409        if (data->working) {
410          data->dying = (CHAR)TRUE;
411          data->stopflag = (CHAR)0xff;
412          break;
413        }
414        WinDismissDlg(hwnd, 0);
415      }
416      break;
417    }
418    return 0;
419
420  case WM_DESTROY:
421    objcnrwnd = (HWND) 0;
422    data = INSTDATA(hwnd);
423    if (data)
424      free(data);
425    break;
426  }
427  return WinDefDlgProc(hwnd, msg, mp1, mp2);
428}
Note: See TracBrowser for help on using the repository browser.