/*********************************************************************** $Id: mle.c 1009 2008-05-10 07:51:58Z stevenhl $ MLE text editor/viewer Copyright (c) 1993-97 M. Kimes Copyright (c) 2004, 2007 Steven H.Levine 01 Aug 04 SHL Rework lstrip/rstrip usage 16 Apr 06 SHL MLEexportfile: rework to avoid wrap problems 14 Jul 06 SHL Use Runtime_Error 03 Nov 06 SHL Count thread usage 22 Mar 07 GKY Use QWL_USER 06 Aug 07 GKY Reduce DosSleep times (ticket 148) 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat 26 Aug 07 GKY DosSleep(1) in loops changed to (0) 17 Dec 07 GKY Make WPURLDEFAULTSETTINGS the fall back for ftp/httprun 29 Feb 08 GKY Refactor global command line variables to notebook.h 29 Feb 08 GKY Use xfree where appropriate ***********************************************************************/ #include #include #include #include #include // _beginthread #define INCL_DOS #define INCL_WIN #define INCL_LONGLONG #include "fm3dlg.h" #include "mle.h" #include "fm3str.h" #include "errutil.h" // Dos_Error... #include "strutil.h" // GetPString #include "notebook.h" // httprun etc #include "fm3dll.h" static PSZ pszSrcFile = __FILE__; #define FAKEROT 1 #define DOROT13(c) (!isalpha((c)))?(c):((((c) >= (char) 'A') && \ ((c) <= (char) 'M')) || (((c) >= (char) 'a') && ((c) <= (char) 'm')))?((c) + (char) 0xd)\ :((((c) >= (char) 'N') && ((c) <= (char) 'Z')) || (((c) >= (char) 'n') && ((c) <= (char) 'z')))?\ ((c) - (char) 0xd):(c) /*((FAKEROT==0)?(c):(FAKEROT==1)?(!isalpha((c)))?(c):((((c) >= (char) 'A') && \ ((c) <= (char) 'M')) || (((c) >= (char) 'a') && ((c) <= (char) 'm')))?((c) + (char) 0xd)\ :((((c) >= (char) 'N') && ((c) <= (char) 'Z')) || (((c) >= (char) 'n') && ((c) <= (char) 'z')))?\ ((c) - (char) 0xd):(c):((c) >= (char) '!') ? ((((c) + (char) 47) > (char) '~') ? ((c) - (char) 47) :\ ((c) + (char) 47)) : (c))*/ LONG MLEgetlinetext(HWND h, LONG l, CHAR * buf, INT maxlen) { /* get text of line l from MLE */ IPT s, e; s = MLEstartofline(h, l); e = MLElinelenleft(h, s); return MLEtextatpos(h, s, buf, min((INT) e, maxlen)); } LONG MLEdeleteline(HWND h, LONG l) { /* delete line l from MLE */ IPT s, e; s = MLEstartofline(h, l); e = MLElinelenleft(h, s); return MLEdelete(h, s, e); } LONG MLEdeletecurline(HWND h) { /* delete current line from MLE */ LONG l; l = MLEcurline(h); return MLEdeleteline(h, l); } LONG MLEdeletetoeol(HWND h) { /* delete from cursor pos to end of line */ IPT s, e; s = MLEcurpos(h); e = MLEcurlenleft(h); return MLEdelete(h, s, e); } VOID MLEclearall(HWND h) { /* remove all text from MLE */ LONG len; len = MLEgetlen(h); if (len) MLEdelete(h, 0, len); } LONG MLEtextatcursor(HWND h, CHAR * buffer, INT buflen) { /* place up to buflen chars of text from cursor pos into buffer * return # of chars imported */ IPT i; i = MLEcurpos(h); return MLEtextatpos(h, i, buffer, buflen); } LONG MLEtextatpos(HWND h, IPT i, CHAR * buffer, INT buflen) { /* place up to buflen chars of text from pos i in buffer * return # of chars imported */ WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(buffer), MPFROMLONG((LONG) buflen)); return (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&i), MPFROMLONG((PLONG) & buflen)); } LONG MLEsizeofsel(HWND h) { /* return length of selected text */ IPT cursor, anchor, test; cursor = MLEcurpos(h); anchor = MLEancpos(h); test = min(cursor, anchor); /* MLE fakes us out; get real length in bytes */ return (LONG) WinSendMsg(h, MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(test), MPFROMLONG((LONG) ((cursor < anchor) ? (anchor - cursor) : (cursor - anchor)))); } VOID MLEinternet(HWND h, BOOL ftp) { CHAR *temp = NULL; IPT ancpos, curpos, here; LONG len, oldlen; APIRET rc; ULONG size; len = MLEsizeofsel(h); len = min(2048, len); oldlen = len; if (len) { len++; rc = DosAllocMem((PVOID) & temp, 4096, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if (rc || !temp) Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY)); else { ancpos = MLEancpos(h); curpos = MLEcurpos(h); here = min(curpos, ancpos); WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(len)); len = (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&here), MPFROMP(&len)); if (len <= 1) Runtime_Error(pszSrcFile, __LINE__, "len <= 1"); else { if (len > oldlen) len--; temp[len] = 0; bstripcr(temp); if (*temp) { if (ftp) { if (fFtpRunWPSDefault) { CHAR WPSDefaultFtpRun[CCHMAXPATH], WPSDefaultFtpRunDir[CCHMAXPATH]; size = sizeof(WPSDefaultFtpRun); PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", "DefaultBrowserExe", WPSDefaultFtpRun, &size); size = sizeof(WPSDefaultFtpRunDir); PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", "DefaultWorkingDir", WPSDefaultFtpRunDir, &size); runemf2(SEPARATE | WINDOWED, h, pszSrcFile, __LINE__, WPSDefaultFtpRunDir, fLibPathStrictFtpRun ? "SET LIBPATHSTRICT=TRUE" : NULL, "%s %s", WPSDefaultFtpRun, temp); } else runemf2(SEPARATE | WINDOWED, h, pszSrcFile, __LINE__, ftprundir, NULL, "%s %s", ftprun, temp); } else if (fHttpRunWPSDefault) { CHAR WPSDefaultHttpRun[CCHMAXPATH], WPSDefaultHttpRunDir[CCHMAXPATH]; size = sizeof(WPSDefaultHttpRun); PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", "DefaultBrowserExe", WPSDefaultHttpRun, &size); size = sizeof(WPSDefaultHttpRunDir); PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", "DefaultWorkingDir", WPSDefaultHttpRunDir, &size); runemf2(SEPARATE | WINDOWED, h, pszSrcFile, __LINE__, WPSDefaultHttpRunDir, fLibPathStrictHttpRun ? "SET LIBPATHSTRICT=TRUE" : NULL, "%s %s", WPSDefaultHttpRun, temp); } else runemf2(SEPARATE | WINDOWED, h, pszSrcFile, __LINE__, httprundir, NULL, "%s %s", httprun, temp); } } DosFreeMem(temp); } } } BOOL MLEdoblock(HWND h, INT action, CHAR * filename) { /* perform action on text in selection */ register CHAR *p; CHAR *sel, *temp = NULL; IPT ancpos, curpos, here; LONG sellen, oldlen; APIRET rc; oldlen = MLEsizeofsel(h); if (!oldlen) return TRUE; sel = xmallocz((size_t) (oldlen + 2), pszSrcFile, __LINE__); if (!sel) return FALSE; rc = DosAllocMem((PVOID) & temp, 32768L, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if (rc || !temp) { Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY)); xfree(sel, pszSrcFile, __LINE__); DosPostEventSem(CompactSem); return FALSE; } ancpos = MLEancpos(h); curpos = MLEcurpos(h); here = min(curpos, ancpos); p = sel; MLEdisable(h); while (oldlen > 0) { sellen = min(oldlen + 1, 32701); WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(sellen)); sellen = (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&here), MPFROMP(&sellen)); if (sellen < 1) { Runtime_Error(pszSrcFile, __LINE__, "len < 1"); xfree(sel, pszSrcFile, __LINE__); DosPostEventSem(CompactSem); return FALSE; } if (sellen > min(oldlen, 32700)) sellen--; memcpy(p, temp, sellen); p += sellen; oldlen -= sellen; } switch (action) { case APPENDCLIP: SaveToClip(h, sel, TRUE); DosFreeMem(temp); xfree(sel, pszSrcFile, __LINE__); MLEenable(h); DosPostEventSem(CompactSem); return TRUE; case WRITE: { FILE *fp; fp = fopen(filename, "a+"); if (!fp) fp = xfopen(filename, "w", pszSrcFile, __LINE__); if (fp) { fseek(fp, 0L, SEEK_END); fwrite(sel, 1, strlen(sel), fp); fclose(fp); } #ifdef __DEBUG_ALLOC__ _heap_check(); #endif DosFreeMem(temp); xfree(sel, pszSrcFile, __LINE__); MLEenable(h); DosPostEventSem(CompactSem); return TRUE; } case UPPERCASE: p = sel; while (*p) { if (isalpha(*p)) *p = toupper(*p); p++; } break; case LOWERCASE: p = sel; while (*p) { if (isalpha(*p)) *p = tolower(*p); p++; } break; case TOGGLECASE: p = sel; while (*p) { if (isalpha(*p)) { if (islower(*p)) *p = toupper(*p); else *p = tolower(*p); } p++; } break; case ROT13: p = sel; while (*p) { *p = DOROT13(*p); // fixme condition both true and false? p++; } break; case XOR: p = sel; while (*p) { *p = (~*p); p++; } break; case FORMAT: p = sel; while (*p) { if (*p == '\r') { memmove(p, p + 1, strlen(p)); continue; } if (*p == '\n') { *p = ' '; continue; } p++; } break; default: /* unknown action */ #ifdef __DEBUG_ALLOC__ _heap_check(); #endif DosFreeMem(temp); xfree(sel, pszSrcFile, __LINE__); DosPostEventSem(CompactSem); MLEenable(h); return FALSE; } /* replace selection with altered text */ p = sel; here = min(curpos, ancpos); MLEclear(h); /* delete current selection */ sellen = oldlen = strlen(sel); /* actual number of bytes */ while (oldlen > 0) { sellen = min(oldlen, 32700); memcpy(temp, p, sellen); WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(sellen)); sellen = (LONG) WinSendMsg(h, MLM_IMPORT, MPFROMP(&here), MPFROMLONG(sellen)); if (!sellen) { Runtime_Error(pszSrcFile, __LINE__, "sellen 0"); break; } p += sellen; oldlen -= sellen; if (oldlen && *p == '\n' /* && *(p - 1) == '\r' */ ) p--; } // while WinSendMsg(h, MLM_SETSEL, MPFROMLONG(ancpos), MPFROMLONG(curpos)); MLEenable(h); #ifdef __DEBUG_ALLOC__ _heap_check(); #endif DosFreeMem(temp); xfree(sel, pszSrcFile, __LINE__); DosPostEventSem(CompactSem); return TRUE; } BOOL MLEquotepara(HWND h, CHAR * initials, BOOL fQuoteOld) { LONG num; CHAR lineend[2], line[8], *p; if (!initials || !*initials) initials = " > "; num = MLEcurline(h); while (MLElinelen(h, num) < 3L && MLEnumlines(h) >= num) num++; while (MLElinelen(h, num) > 2L && MLEnumlines(h) >= num) { memset(line, 0, 8); MLEgetlinetext(h, num, line, 7L); line[7] = 0; if ((p = strchr(line, '>')) == NULL) { MLEsetcurpos(h, MLEstartofline(h, num)); MLEinsert(h, initials); MLEsetcurpos(h, (MLEstartofline(h, num) + MLElinelen(h, num)) - 1L); MLEtextatcursor(h, lineend, 2L); if (*lineend != '\r' && *lineend != '\n') MLEinsert(h, "\n"); } else if (fQuoteOld) { while (isspace(line[strlen(line) - 1])) line[strlen(line) - 1] = 0; MLEsetcurpos(h, MLEstartofline(h, num) + (p - line)); MLEinsert(h, ">"); } num++; } MLEsetcurpos(h, MLEstartofline(h, num)); return TRUE; } BOOL MLEAutoLoad(HWND h, CHAR * filename) { XMLEWNDPTR *vw; vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER); if (vw && vw->size != sizeof(XMLEWNDPTR)) vw = NULL; if (TestBinary(filename)) { if (vw) vw->hex = 1; return MLEHexLoad(h, filename); } if (vw) vw->hex = 2; return MLEloadfile(h, filename); } BOOL MLEHexLoad(HWND h, CHAR * filename) { /* insert a file into the current position in the MLE */ HAB hab; CHAR *buffer = NULL, *hexbuff = NULL; IPT iptOffset = -1; ULONG numread, howmuch, numimport, action, len, left = 0; BOOL ret = TRUE, first = TRUE; CHAR titletext[512]; HWND grandpa; XMLEWNDPTR *vw; HFILE handle; APIRET rc; *titletext = 0; hab = WinQueryAnchorBlock(h); vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER); if (vw && vw->size != sizeof(XMLEWNDPTR)) vw = NULL; grandpa = GrandparentOf(h); *titletext = 0; WinQueryWindowText(grandpa, 512, titletext); rc = DosOpen(filename, &handle, &action, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0); if (rc) { ret = FALSE; } else { DosChgFilePtr(handle, 0, FILE_END, &len); DosChgFilePtr(handle, 0, FILE_BEGIN, &action); if (len) { rc = DosAllocMem((PVOID) & hexbuff, 50001, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if (rc || !hexbuff) { Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY)); ret = FALSE; } else { buffer = xmalloc(10000, pszSrcFile, __LINE__); if (!buffer) ret = FALSE; else { MLEclearall(h); WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(hexbuff), MPFROMLONG(50000L)); if (!DosRead(handle, buffer, min(10000, len), &numread) && numread) { CHAR s[81]; MLEsetwrap(h, FALSE); WinSetSysValue(HWND_DESKTOP, SV_INSERTMODE, FALSE); *hexbuff = 0; numimport = CreateHexDump(buffer, numread, hexbuff, 50000, left, TRUE); while (len && numimport) { /* import entire file */ left += numread; len -= numread; if (!WinIsWindow(hab, h) || (vw && vw->killme)) break; howmuch = (INT) WinSendMsg(h, MLM_IMPORT, MPFROMP(&iptOffset), MPFROMLONG(numimport)); if (first && len) { MLEdisable(h); WinEnableWindowUpdate(h, FALSE); first = FALSE; } // fprintf(stderr,"%d bytes of %d imported\n",howmuch,numimport); if (howmuch < 1) { numimport = 0; break; } while (howmuch < numimport) { numimport -= howmuch; memmove(hexbuff, hexbuff + howmuch, numimport); DosSleep(0); //26 Aug 07 GKY 1 if (!WinIsWindow(hab, h) || (vw && vw->killme)) break; howmuch = (INT) WinSendMsg(h, MLM_IMPORT, MPFROMP(&iptOffset), MPFROMLONG((LONG) numimport)); if (howmuch < 1) break; } if (DosRead(handle, buffer, min(10000, len), &numread) || !numread) { numimport = 0; break; } *hexbuff = 0; numimport = CreateHexDump(buffer, numread, hexbuff, 50000, left, TRUE); if (numimport < 1 || !WinIsWindow(hab, h) || (vw && vw->killme)) { numimport = 0; break; } sprintf(s, GetPString(IDS_LOADINGMLETEXT), len); WinSetWindowText(grandpa, s); } DosSleep(1); } else ret = FALSE; xfree(buffer, pszSrcFile, __LINE__); } DosFreeMem(hexbuff); } } if (WinIsWindow(hab, h)) WinSetWindowText(grandpa, titletext); DosClose(handle); } if (!first) { WinEnableWindowUpdate(h, TRUE); MLEenable(h); } MLEsetchanged(h, FALSE); return ret; } //== MLEinsertfile() insert a file into the current position in the MLE == BOOL MLEinsertfile(HWND h, CHAR * filename) { HAB hab; FILE *fp; CHAR *buffer = NULL; INT len; IPT iptOffset = -1L; INT numread, howmuch, tempnum, x; BOOL ret = TRUE, first = TRUE, once = FALSE, dont = FALSE; CHAR titletext[512]; HWND grandpa; XMLEWNDPTR *vw; APIRET rc; *titletext = 0; hab = WinQueryAnchorBlock(h); vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER); if (vw && vw->size != sizeof(XMLEWNDPTR)) vw = NULL; grandpa = GrandparentOf(h); *titletext = 0; WinQueryWindowText(grandpa, 512, titletext); fp = _fsopen(filename, "r", SH_DENYNO); if (!fp) ret = FALSE; else { setvbuf(fp, NULL, _IONBF, 0); fseek(fp, 0L, SEEK_END); len = (INT) ftell(fp); fseek(fp, 0L, SEEK_SET); if (len && len != -1) { rc = DosAllocMem((PVOID) & buffer, 50000L, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if (rc || !buffer) { Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY)); ret = FALSE; } else { WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(buffer), MPFROMLONG(50000L)); numread = fread(buffer, 1, min(50000, len), fp); if (numread < 1) ret = FALSE; while (len && numread > 0) { /* here we go... */ CHAR s[81]; while (numread > 0) { /* import entire file */ if (!WinIsWindow(hab, h) || (vw && vw->killme)) break; if (strlen(buffer) < numread) { if (!once && !dont) rc = saymsg(MB_YESNOCANCEL, HWND_DESKTOP, GetPString(IDS_WARNINGTEXT), GetPString(IDS_TEXTNULSTEXT)); else if (once) rc = MBID_YES; else if (dont) rc = MBID_NO; if (rc == MBID_YES) { once = FALSE; for (x = 0; x < numread; x++) { if (!buffer[x]) buffer[x] = ' '; } } else if (rc == MBID_CANCEL) { len = 0; numread = 0; saymsg(MB_ENTER, HWND_DESKTOP, GetPString(IDS_OBEYTEXT), GetPString(IDS_LOADCANCELLEDTEXT)); break; } else if (rc == MBID_NO) dont = TRUE; } howmuch = (INT) WinSendMsg(h, MLM_IMPORT, MPFROMP(&iptOffset), MPFROMLONG((LONG) numread)); if (first && !feof(fp)) { MLEdisable(h); WinEnableWindowUpdate(h, FALSE); first = FALSE; } // fprintf(stderr,"%d bytes of %d imported\n",howmuch,numread); if (howmuch < 1) { numread = 0; break; } len -= howmuch; if (howmuch < numread) { numread -= howmuch; memmove(buffer, buffer + howmuch, numread); if (numread && len) { tempnum = numread; numread = fread(buffer + tempnum, 1, min(50000 - tempnum, len), fp); if (numread > 1) numread += tempnum; else numread = tempnum; } DosSleep(0); //26 Aug 07 GKY 1 } else numread = fread(buffer, 1, min(50000, len), fp); if (numread < 1 || !WinIsWindow(hab, h) || (vw && vw->killme)) { numread = 0; break; } sprintf(s, GetPString(IDS_LOADINGMLETEXT), len); WinSetWindowText(grandpa, s); } DosSleep(0); //26 Aug 07 GKY 1 } DosFreeMem(buffer); } } if (WinIsWindow(hab, h)) WinSetWindowText(grandpa, titletext); fclose(fp); } if (!first) { WinEnableWindowUpdate(h, TRUE); MLEenable(h); } return ret; } typedef struct { USHORT size; USHORT hex; HWND h; CHAR filename[CCHMAXPATH]; HWND hwndReport; HWND msg; } BKGLOAD; VOID LoadThread(VOID * arg) { BKGLOAD *bkg; BOOL fSuccess; HAB thab; HMQ thmq; DosError(FERR_DISABLEHARDERR); bkg = (BKGLOAD *) arg; if (bkg) { thab = WinInitialize(0); if (thab) { thmq = WinCreateMsgQueue(thab, 0); if (thmq) { WinCancelShutdown(thmq, TRUE); IncrThreadUsage(); priority_normal(); if (bkg->hex == 1) fSuccess = MLEHexLoad(bkg->h, bkg->filename); else if (bkg->hex == 2) fSuccess = MLEloadfile(bkg->h, bkg->filename); else fSuccess = MLEAutoLoad(bkg->h, bkg->filename); priority_bumped(); if (bkg->hwndReport && WinIsWindow(thab, bkg->hwndReport)) PostMsg(bkg->hwndReport, bkg->msg, MPFROMLONG(fSuccess), MPFROMP(bkg->filename)); #ifdef __DEBUG_ALLOC__ _heap_check(); #endif xfree(bkg, pszSrcFile, __LINE__); WinDestroyMsgQueue(thmq); } DecrThreadUsage(); WinTerminate(thab); _endthread(); } // fixme to be gone? PostMsg(bkg->hwndReport, bkg->msg, MPVOID, MPVOID); } } INT MLEbackgroundload(HWND hwndReport, ULONG msg, HWND h, CHAR * filename, INT hex) { /* load a file into the MLE in the background (via a separate thread) * return _beginthread status */ BKGLOAD *bkg; INT rc; bkg = xmallocz(sizeof(BKGLOAD), pszSrcFile, __LINE__); if (!bkg) return -1; bkg->size = sizeof(BKGLOAD); bkg->hex = (USHORT) hex; bkg->hwndReport = hwndReport; bkg->msg = msg; bkg->h = h; strcpy(bkg->filename, filename); rc = _beginthread(LoadThread, NULL, 65536, bkg); if (rc == -1) Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_COULDNTSTARTTHREADTEXT)); return rc; } BOOL MLEloadfile(HWND h, CHAR * filename) { /* load a file into the MLE, getting rid of whatever was already * there. Note this returns without erasing existing text if the * file to load does not exist */ FILESTATUS3 fsa; BOOL ret; if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsa, sizeof(fsa)) && ~fsa.attrFile & FILE_DIRECTORY) { MLEclearall(h); ret = MLEinsertfile(h, filename); MLEsetchanged(h, FALSE); return ret; } return FALSE; } BOOL MLEexportfile(HWND h, CHAR * filename, INT tabspaces, BOOL striptraillines, BOOL striptrailspaces) { /* save the MLE contents as a file. Format the output so that * the file is CR/LF terminated as presented in the MLE. */ FILE *fp = NULL; CHAR *buffer = NULL; CHAR *p; BOOL ok = TRUE; INT blanklines = 0; BOOL fWrap = MLEgetwrap(h); APIRET rc; // saymsg(MB_ENTER,h,DEBUG_STRING,"len = %ld",MLEgetlen(h)); if (!MLEgetlen(h)) /* nothing to save; forget it */ return TRUE; MLEsetwrap(h, FALSE); // Need wrap off to export MLFIE_NOTRANS if (striptraillines) { register LONG x; LONG numlines; numlines = MLEnumlines(h); for (x = numlines; x; x--) { if (MLElinelen(h, x - 1L) < 2) MLEdeleteline(h, x - 1L); else break; } if (!MLEgetlen(h)) { /* nothing to save; forget it */ MLEsetwrap(h, fWrap); // Restore return TRUE; } } rc = DosAllocMem((PVOID) & buffer, 4096L, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if (rc || !buffer) { Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY)); ok = FALSE; } else { fp = fopen(filename, "a+"); if (!fp) fp = xfopen(filename, "w", pszSrcFile, __LINE__); if (!fp) ok = FALSE; else { LONG numlines, ret, len, wl, temp; IPT s; fseek(fp, 0L, SEEK_END); numlines = MLEnumlines(h); WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(buffer), MPFROMLONG(4095L)); for (temp = 0; temp < numlines; temp++) { s = MLEstartofline(h, temp); wl = len = (LONG) MLElinelenleft(h, s); ret = (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&s), MPFROMP(&len)); if (ret < 0) break; wl = min(wl, ret); buffer[wl] = 0; if (*buffer) { p = buffer + strlen(buffer) - 1; while (p >= buffer && (*p == '\n' || *p == '\r')) { *p = 0; p--; } } if (tabspaces) { p = buffer; while (*p) { if (*p == '\t') { *p = ' '; memmove((p + tabspaces) - 1, p, strlen(p) + 1); memset(p, ' ', tabspaces); } p++; } } if (striptrailspaces && *buffer) { p = buffer + strlen(buffer) - 1; while (p >= buffer && (*p == ' ' || *p == '\t')) { *p = 0; p--; } } if (striptraillines) { if (!*buffer) { blanklines++; continue; } else { while (blanklines) { fwrite("\n", 1, 1, fp); blanklines--; } } } strcat(buffer, "\n"); // buffer = translate_out(buffer,4095,h,filename); if (fwrite(buffer, 1, strlen(buffer), fp) < 1) { saymsg(MB_ENTER, h, GetPString(IDS_ARGHTEXT), GetPString(IDS_WRITEERRORTEXT)); break; } } // for lines } } MLEsetwrap(h, fWrap); // Restore if (fp) fclose(fp); if (buffer) DosFreeMem(buffer); return ok; } MRESULT EXPENTRY SandRDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { /* initiate search(/replace)s in edit mode */ SRCHPTR *vw; if (msg != WM_INITDLG) vw = (SRCHPTR *) WinQueryWindowPtr(hwnd, QWL_USER); else vw = NULL; switch (msg) { case WM_INITDLG: vw = (SRCHPTR *) mp2; if (!vw) { WinDismissDlg(hwnd, 0); break; } WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2); WinSendDlgItemMsg(hwnd, SRCH_SEARCH, EM_SETTEXTLIMIT, MPFROM2SHORT(256, 0), MPVOID); WinSendDlgItemMsg(hwnd, SRCH_REPLACE, EM_SETTEXTLIMIT, MPFROM2SHORT(256, 0), MPVOID); if (*vw->search) WinSetDlgItemText(hwnd, SRCH_SEARCH, vw->search); if (!MLEgetreadonly(vw->hwndmle)) { if (*vw->replace) WinSetDlgItemText(hwnd, SRCH_REPLACE, vw->replace); WinSendDlgItemMsg(hwnd, SRCH_SANDR, BM_SETCHECK, MPFROM2SHORT(vw->sandr, 0), MPVOID); WinSendDlgItemMsg(hwnd, SRCH_RALL, BM_SETCHECK, MPFROM2SHORT(vw->rall, 0), MPVOID); } else { WinEnableWindow(WinWindowFromID(hwnd, SRCH_SANDR), FALSE); WinEnableWindow(WinWindowFromID(hwnd, SRCH_RALL), FALSE); WinEnableWindow(WinWindowFromID(hwnd, SRCH_REPLACE), FALSE); WinShowWindow(WinWindowFromID(hwnd, SRCH_REPLACE), FALSE); *vw->replace = 0; vw->sandr = FALSE; vw->rall = FALSE; } memset(&vw->se, 0, sizeof(MLE_SEARCHDATA)); vw->se.cb = sizeof(MLE_SEARCHDATA); vw->se.pchFind = (PCHAR) vw->search; vw->se.cchFind = (SHORT) strlen(vw->search); vw->se.pchReplace = (PCHAR) vw->replace; vw->se.cchReplace = (SHORT) strlen(vw->replace); vw->se.iptStart = MLEcurpos(vw->hwndmle); vw->se.iptStop = -1L; vw->se.cchFound = 0; PosOverOkay(hwnd); break; case WM_CONTROL: return 0; case WM_COMMAND: switch (SHORT1FROMMP(mp1)) { case IDM_HELP: saymsg(MB_ENTER | MB_ICONASTERISK, hwnd, NullStr, GetPString(IDS_ENTERSEARCHSTRINGTEXT), (MLEgetreadonly(vw->hwndmle)) ? "." : GetPString(IDS_REPLACESTRINGTEXT)); break; case DID_CANCEL: WinDismissDlg(hwnd, 0); break; case DID_OK: WinShowWindow(hwnd, FALSE); { CHAR temp[257]; APIRET ret; if ((USHORT) WinSendDlgItemMsg(hwnd, SRCH_SANDR, BM_QUERYCHECK, MPVOID, MPVOID)) vw->sandr = TRUE; else vw->sandr = FALSE; if ((USHORT) WinSendDlgItemMsg(hwnd, SRCH_RALL, BM_QUERYCHECK, MPVOID, MPVOID)) vw->rall = TRUE; else vw->rall = FALSE; *vw->replace = 0; WinQueryDlgItemText(hwnd, SRCH_REPLACE, 256, vw->replace); vw->se.cchReplace = (SHORT) strlen(vw->replace); WinQueryDlgItemText(hwnd, SRCH_SEARCH, 256, temp); if (*temp) { strcpy(vw->search, temp); vw->se.cchFind = (SHORT) strlen(vw->search); if (!WinSendMsg(vw->hwndmle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | (MLFSEARCH_CASESENSITIVE * (vw->fInsensitive == FALSE)) | (MLFSEARCH_CHANGEALL * (vw->rall != 0))), MPFROMP(&vw->se))) { saymsg(MB_ENTER | MB_ICONASTERISK, hwnd, NullStr, GetPString(IDS_STRINGNOTFOUNDTEXT), vw->search); WinDismissDlg(hwnd, 0); break; } else if (vw->sandr && !vw->rall) { ret = saymsg(MB_YESNOCANCEL, hwnd, NullStr, GetPString(IDS_CONFIRMREPLACETEXT), vw->replace); if (ret == MBID_YES) MLEinsert(vw->hwndmle, vw->replace); else if (ret == MBID_CANCEL) { WinDismissDlg(hwnd, 0); break; } WinDismissDlg(hwnd, 1); break; } } WinDismissDlg(hwnd, 0); } break; } return 0; case WM_CLOSE: break; } return WinDefDlgProc(hwnd, msg, mp1, mp2); } BOOL MLEfindfirst(HWND hwnd, SRCHPTR * vw) { if (MLEsizeofsel(vw->hwndmle) < 256L) { MLEgetseltext(vw->hwndmle, vw->search); vw->search[255] = 0; } if (WinDlgBox(HWND_DESKTOP, hwnd, SandRDlgProc, FM3ModHandle, SRCH_FRAME, MPFROMP(vw)) && *vw->search) return TRUE; return FALSE; } INT MLEfindnext(HWND hwnd, SRCHPTR * vw) { if (!*vw->search) return -1; else { vw->se.iptStart++; if (!WinSendMsg(vw->hwndmle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | (MLFSEARCH_CASESENSITIVE * (vw->fInsensitive == FALSE)) | (MLFSEARCH_CHANGEALL * (vw->rall))), MPFROMP(&vw->se))) saymsg(MB_ENTER | MB_ICONASTERISK, hwnd, NullStr, GetPString(IDS_STRINGNOTFOUNDTEXT), vw->search); else if (vw->sandr && !vw->rall) { APIRET ret; ret = saymsg(MB_YESNOCANCEL, hwnd, NullStr, GetPString(IDS_CONFIRMREPLACETEXT), vw->replace); if (ret == MBID_YES) MLEinsert(vw->hwndmle, vw->replace); if (ret != MBID_CANCEL) return 1; } } return 0; } #pragma alloc_text(FMMLE,MLEgetlinetext,MLEdeleteline,MLEdeletecurline,MLEdeletetoeol) #pragma alloc_text(FMMLE,MLEclearall,MLEtextatcursor,MLEtextatpos,MLEsizeofsel) #pragma alloc_text(FMMLE3,MLEdoblock,MLEquotepara,MLEinternet) #pragma alloc_text(FMMLE4,MLEAutoLoad,MLEHexLoad,MLEinsertfile,LoadThread,MLEbackgroundload) #pragma alloc_text(FMMLE5,MLEloadfile,MLEexportfile) #pragma alloc_text(FMMLE3,MLEfindfirst,MLEfindnext,SandRDlgProc)