From 1b4ffa19bf679223147e11f80050241257cbb3cc Mon Sep 17 00:00:00 2001 From: grimmd Date: Thu, 1 Mar 2001 21:01:27 +0000 Subject: [PATCH] Initial revision --- Src/editlib/asp.cpp | 951 +++++++ Src/editlib/basic.cpp | 444 +++ Src/editlib/batch.cpp | 443 +++ Src/editlib/ccrystaleditview.cpp | 2532 ++++++++++++++++++ Src/editlib/ccrystaleditview.h | 194 ++ Src/editlib/ccrystaleditview.inl | 72 + Src/editlib/ccrystaltextbuffer.cpp | 1498 +++++++++++ Src/editlib/ccrystaltextbuffer.h | 335 +++ Src/editlib/ccrystaltextbuffer.inl | 38 + Src/editlib/ccrystaltextview.cpp | 5202 ++++++++++++++++++++++++++++++++++++ Src/editlib/ccrystaltextview.h | 902 +++++++ Src/editlib/ccrystaltextview.inl | 38 + Src/editlib/ccrystaltextview2.cpp | 1215 +++++++++ Src/editlib/ceditreplacedlg.cpp | 413 +++ Src/editlib/ceditreplacedlg.h | 106 + Src/editlib/cfindtextdlg.cpp | 159 ++ Src/editlib/cfindtextdlg.h | 90 + Src/editlib/chcondlg.cpp | 126 + Src/editlib/chcondlg.h | 71 + Src/editlib/cplusplus.cpp | 489 ++++ Src/editlib/cregexp.cpp | 1159 ++++++++ Src/editlib/cregexp.h | 117 + Src/editlib/crystaleditviewex.cpp | 72 + Src/editlib/crystaleditviewex.h | 97 + Src/editlib/crystalparser.cpp | 108 + Src/editlib/crystalparser.h | 109 + Src/editlib/crystaltextblock.cpp | 66 + Src/editlib/crystaltextblock.h | 71 + Src/editlib/cs2cs.cpp | 248 ++ Src/editlib/cs2cs.h | 59 + Src/editlib/dcl.cpp | 441 +++ Src/editlib/editcmd.h | 325 +++ Src/editlib/editreg.h | 38 + Src/editlib/edtlib.cpp | 57 + Src/editlib/edtlib.h | 16 + Src/editlib/filesup.cpp | 119 + Src/editlib/filesup.h | 39 + Src/editlib/filesup.inl | 36 + Src/editlib/fortran.cpp | 449 ++++ Src/editlib/fpattern.cpp | 402 +++ Src/editlib/fpattern.h | 148 + Src/editlib/gotodlg.cpp | 80 + Src/editlib/gotodlg.h | 70 + Src/editlib/html.cpp | 701 +++++ Src/editlib/is.cpp | 741 +++++ Src/editlib/java.cpp | 378 +++ Src/editlib/lisp.cpp | 576 ++++ Src/editlib/memcombo.cpp | 276 ++ Src/editlib/memcombo.h | 81 + Src/editlib/memcombo.inl | 45 + Src/editlib/pascal.cpp | 346 +++ Src/editlib/perl.cpp | 506 ++++ Src/editlib/php.cpp | 937 +++++++ Src/editlib/python.cpp | 440 +++ Src/editlib/registry.cpp | 1463 ++++++++++ Src/editlib/registry.h | 411 +++ Src/editlib/rexx.cpp | 393 +++ Src/editlib/rsrc.cpp | 355 +++ Src/editlib/sgml.cpp | 551 ++++ Src/editlib/sh.cpp | 339 +++ Src/editlib/siod.cpp | 670 +++++ Src/editlib/splash.cpp | 116 + Src/editlib/splash.h | 55 + Src/editlib/sql.cpp | 353 +++ Src/editlib/statbar.cpp | 126 + Src/editlib/statbar.h | 53 + Src/editlib/tcl.cpp | 298 +++ Src/editlib/tex.cpp | 1133 ++++++++ Src/editlib/wispelld.h | 64 + 69 files changed, 31051 insertions(+) create mode 100644 Src/editlib/asp.cpp create mode 100644 Src/editlib/basic.cpp create mode 100644 Src/editlib/batch.cpp create mode 100644 Src/editlib/ccrystaleditview.cpp create mode 100644 Src/editlib/ccrystaleditview.h create mode 100644 Src/editlib/ccrystaleditview.inl create mode 100644 Src/editlib/ccrystaltextbuffer.cpp create mode 100644 Src/editlib/ccrystaltextbuffer.h create mode 100644 Src/editlib/ccrystaltextbuffer.inl create mode 100644 Src/editlib/ccrystaltextview.cpp create mode 100644 Src/editlib/ccrystaltextview.h create mode 100644 Src/editlib/ccrystaltextview.inl create mode 100644 Src/editlib/ccrystaltextview2.cpp create mode 100644 Src/editlib/ceditreplacedlg.cpp create mode 100644 Src/editlib/ceditreplacedlg.h create mode 100644 Src/editlib/cfindtextdlg.cpp create mode 100644 Src/editlib/cfindtextdlg.h create mode 100644 Src/editlib/chcondlg.cpp create mode 100644 Src/editlib/chcondlg.h create mode 100644 Src/editlib/cplusplus.cpp create mode 100644 Src/editlib/cregexp.cpp create mode 100644 Src/editlib/cregexp.h create mode 100644 Src/editlib/crystaleditviewex.cpp create mode 100644 Src/editlib/crystaleditviewex.h create mode 100644 Src/editlib/crystalparser.cpp create mode 100644 Src/editlib/crystalparser.h create mode 100644 Src/editlib/crystaltextblock.cpp create mode 100644 Src/editlib/crystaltextblock.h create mode 100644 Src/editlib/cs2cs.cpp create mode 100644 Src/editlib/cs2cs.h create mode 100644 Src/editlib/dcl.cpp create mode 100644 Src/editlib/editcmd.h create mode 100644 Src/editlib/editreg.h create mode 100644 Src/editlib/edtlib.cpp create mode 100644 Src/editlib/edtlib.h create mode 100644 Src/editlib/filesup.cpp create mode 100644 Src/editlib/filesup.h create mode 100644 Src/editlib/filesup.inl create mode 100644 Src/editlib/fortran.cpp create mode 100644 Src/editlib/fpattern.cpp create mode 100644 Src/editlib/fpattern.h create mode 100644 Src/editlib/gotodlg.cpp create mode 100644 Src/editlib/gotodlg.h create mode 100644 Src/editlib/html.cpp create mode 100644 Src/editlib/is.cpp create mode 100644 Src/editlib/java.cpp create mode 100644 Src/editlib/lisp.cpp create mode 100644 Src/editlib/memcombo.cpp create mode 100644 Src/editlib/memcombo.h create mode 100644 Src/editlib/memcombo.inl create mode 100644 Src/editlib/pascal.cpp create mode 100644 Src/editlib/perl.cpp create mode 100644 Src/editlib/php.cpp create mode 100644 Src/editlib/python.cpp create mode 100644 Src/editlib/registry.cpp create mode 100644 Src/editlib/registry.h create mode 100644 Src/editlib/rexx.cpp create mode 100644 Src/editlib/rsrc.cpp create mode 100644 Src/editlib/sgml.cpp create mode 100644 Src/editlib/sh.cpp create mode 100644 Src/editlib/siod.cpp create mode 100644 Src/editlib/splash.cpp create mode 100644 Src/editlib/splash.h create mode 100644 Src/editlib/sql.cpp create mode 100644 Src/editlib/statbar.cpp create mode 100644 Src/editlib/statbar.h create mode 100644 Src/editlib/tcl.cpp create mode 100644 Src/editlib/tex.cpp create mode 100644 Src/editlib/wispelld.h diff --git a/Src/editlib/asp.cpp b/Src/editlib/asp.cpp new file mode 100644 index 000000000..698513a03 --- /dev/null +++ b/Src/editlib/asp.cpp @@ -0,0 +1,951 @@ +/////////////////////////////////////////////////////////////////////////// +// File: asp.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// HTML syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszHtmlKeywordList[] = + { + // HTML section + _T ("DOCTYPE"), + _T ("PUBLIC"), + _T ("FRAME"), + _T ("FRAMESET"), + _T ("NOFRAMES"), + // HEAD section + _T ("HEAD"), + _T ("TITLE"), + _T ("ISINDEX"), + _T ("META"), + _T ("LINK"), + _T ("BASE"), + _T ("SCRIPT"), + _T ("STYLE"), + // BODY section + _T ("BODY"), + // headings + _T ("H1"), + _T ("H2"), + _T ("H3"), + _T ("H4"), + _T ("H5"), + _T ("H6"), + // lists + _T ("UL"), + _T ("OL"), + _T ("DIR"), + _T ("MENU"), + _T ("LI"), + _T ("DL"), + _T ("DT"), + _T ("DD"), + // text containers + _T ("P"), + _T ("PRE"), + _T ("BLOCKQUOTE"), + _T ("ADDRESS"), + // others + _T ("DIV"), + _T ("SPAN"), + _T ("CENTER"), + _T ("HR"), + _T ("FORM"), + _T ("TABLE"), + _T ("LEFT"), + _T ("RIGHT"), + _T ("TOP"), + // logical markup + _T ("EM"), + _T ("STRONG"), + _T ("DFN"), + _T ("CODE"), + _T ("SAMP"), + _T ("KBD"), + _T ("VAR"), + _T ("CITE"), + // physical markup + _T ("TT"), + _T ("I"), + _T ("B"), + _T ("U"), + _T ("STRIKE"), + _T ("BIG"), + _T ("SMALL"), + _T ("SUB"), + _T ("SUP"), + // special markup + _T ("A"), + _T ("BASEFONT"), + _T ("IMG"), + _T ("APPLET"), + _T ("PARAM"), + _T ("FONT"), + _T ("BR"), + _T ("MAP"), + _T ("AREA"), + // forms + _T ("INPUT"), + _T ("SELECT"), + _T ("OPTION"), + _T ("TEXTAREA"), + _T ("ONCLICK"), + // tables + _T ("CAPTION"), + _T ("TR"), + _T ("TH"), + _T ("TD"), + _T ("HTML"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("ACTION"), + _T ("ALIGN"), + _T ("ALINK"), + _T ("BACKGROUND"), + _T ("BGCOLOR"), + _T ("COLOR"), + _T ("COMPACT"), + _T ("CONTENT"), + _T ("ENCTYPE"), + _T ("FACE"), + _T ("HEIGHT"), + _T ("HREF"), + _T ("HTTP-EQUIV"), + _T ("LINK"), + _T ("METHOD"), + _T ("NAME"), + _T ("PROMPT"), + _T ("REL"), + _T ("REV"), + _T ("START"), + _T ("TEXT"), + _T ("TYPE"), + _T ("VALUE"), + _T ("VLINK"), + _T ("WIDTH"), + _T ("ADD_DATE"), + _T ("ALT"), + _T ("BORDER"), + _T ("CELLPADDING"), + _T ("CELLSPACING"), + _T ("CHECKED"), + _T ("CLEAR"), + _T ("CODE"), + _T ("CODEBASE"), + _T ("COLS"), + _T ("COLSPAN"), + _T ("COORDS"), + _T ("FOLDED"), + _T ("HSPACE"), + _T ("ISMAP"), + _T ("LAST_MODIFIED"), + _T ("LAST_VISIT"), + _T ("MAXLENGTH"), + _T ("MULTIPLE"), + _T ("NORESIZE"), + _T ("NOSHADE"), + _T ("NOWRAP"), + _T ("ROWS"), + _T ("ROWSPAN"), + _T ("SELECTED"), + _T ("SHAPE"), + _T ("SIZE"), + _T ("SRC"), + _T ("TARGET"), + _T ("USEMAP"), + _T ("VALIGN"), + _T ("VSPACE"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("nbsp"), + _T ("quot"), + _T ("amp"), + _T ("lt"), + _T ("lt"), + _T ("gt"), + _T ("copy"), + _T ("reg"), + _T ("acute"), + _T ("laquo"), + _T ("raquo"), + _T ("iexcl"), + _T ("iquest"), + _T ("Agrave"), + _T ("agrave"), + _T ("Aacute"), + _T ("aacute"), + _T ("Acirc"), + _T ("acirc"), + _T ("Atilde"), + _T ("atilde"), + _T ("Auml"), + _T ("auml"), + _T ("Aring"), + _T ("aring"), + _T ("AElig"), + _T ("aelig"), + _T ("Ccedil"), + _T ("ccedil"), + _T ("ETH"), + _T ("eth"), + _T ("Egrave"), + _T ("egrave"), + _T ("Eacute"), + _T ("eacute"), + _T ("Ecirc"), + _T ("ecirc"), + _T ("Euml"), + _T ("euml"), + _T ("Igrave"), + _T ("igrave"), + _T ("Iacute"), + _T ("iacute"), + _T ("Icirc"), + _T ("icirc"), + _T ("Iuml"), + _T ("iuml"), + _T ("Ntilde"), + _T ("ntilde"), + _T ("Ograve"), + _T ("ograve"), + _T ("Oacute"), + _T ("oacute"), + _T ("Ocirc"), + _T ("ocirc"), + _T ("Otilde"), + _T ("otilde"), + _T ("Ouml"), + _T ("ouml"), + _T ("Oslash"), + _T ("oslash"), + _T ("Ugrave"), + _T ("ugrave"), + _T ("Uacute"), + _T ("uacute"), + _T ("Ucirc"), + _T ("ucirc"), + _T ("Uuml"), + _T ("uuml"), + _T ("Yacute"), + _T ("yacute"), + _T ("yuml"), + _T ("THORN"), + _T ("thorn"), + _T ("szlig"), + _T ("sect"), + _T ("para"), + _T ("micro"), + _T ("brvbar"), + _T ("plusmn"), + _T ("middot"), + _T ("uml"), + _T ("cedil"), + _T ("ordf"), + _T ("ordm"), + _T ("not"), + _T ("shy"), + _T ("macr"), + _T ("deg"), + _T ("sup1"), + _T ("sup2"), + _T ("sup3"), + _T ("frac14"), + _T ("frac12"), + _T ("frac34"), + _T ("times"), + _T ("divide"), + _T ("cent"), + _T ("pound"), + _T ("curren"), + _T ("yen"), + NULL + }; + +static LPTSTR s_apszAspKeywordList[] = + { + _T ("If"), + _T ("Function"), + _T ("Else"), + _T ("End"), + _T ("For"), + _T ("Next"), + _T ("While"), + _T ("Wend"), + _T ("SMDoMenu"), + _T ("GetAttrType"), + _T ("GetAttrName"), + _T ("GetAttrValString"), + _T ("GetAttrValFloat"), + _T ("GetAttrValInt"), + _T ("GetAttrValBool"), + _T ("GetAttrValEnumInt"), + _T ("GetAttrValEnumString"), + _T ("GetClassId"), + _T ("GetGeoType"), + _T ("SetAttrValString"), + _T ("SetAttrValInt"), + _T ("SetAttrValFloat"), + _T ("SetAttrValBool"), + _T ("SetAttrValEnumString"), + _T ("SetAttrValEnumInt"), + _T ("CreateVerifyItem"), + _T ("VerifyCardinalities"), + _T ("As"), + _T ("Abs"), + _T ("AppActivate"), + _T ("Asc"), + _T ("Atn"), + _T ("Beep"), + _T ("Call"), + _T ("CDbl"), + _T ("ChDir"), + _T ("ChDrive"), + _T ("CheckBox"), + _T ("Chr"), + _T ("CInt"), + _T ("CLng"), + _T ("Close"), + _T ("Const"), + _T ("Cos"), + _T ("CreateObject"), + _T ("CSng"), + _T ("CStr"), + _T ("CVar"), + _T ("CurDir"), + _T ("Date"), + _T ("Declare"), + _T ("Dialog"), + _T ("Dim"), + _T ("Dir"), + _T ("DlgEnable"), + _T ("DlgText"), + _T ("DlgVisible"), + _T ("Do"), + _T ("Double"), + _T ("Loop"), + _T ("End"), + _T ("EOF"), + _T ("Erase"), + _T ("Exit"), + _T ("Exp"), + _T ("FileCopy"), + _T ("FileLen"), + _T ("Fix"), + _T ("For"), + _T ("To"), + _T ("Step"), + _T ("Next"), + _T ("Format"), + _T ("Function"), + _T ("GetObject"), + _T ("Global"), + _T ("GoSub"), + _T ("Return"), + _T ("GoTo"), + _T ("Hex"), + _T ("Hour"), + _T ("If"), + _T ("Then"), + _T ("Else"), + _T ("Input"), + _T ("InputBox"), + _T ("InStr"), + _T ("Int"), + _T ("IsDate"), + _T ("IsEmpty"), + _T ("IsNull"), + _T ("IsNumeric"), + _T ("Kill"), + _T ("LBound"), + _T ("LCase"), + _T ("LCase$"), + _T ("Left"), + _T ("Left$"), + _T ("Len"), + _T ("Let"), + _T ("Line"), + _T ("Input#"), + _T ("Log"), + _T ("Long"), + _T ("Mid"), + _T ("Minute"), + _T ("MkDir"), + _T ("Month"), + _T ("MsgBox"), + _T ("Name"), + _T ("Now"), + _T ("Oct"), + _T ("On"), + _T ("Error"), + _T ("Open"), + _T ("Option"), + _T ("Base"), + _T ("Print"), + _T ("Print"), + _T ("Rem"), + _T ("Right"), + _T ("RmDir"), + _T ("Rnd"), + _T ("Second"), + _T ("Seek"), + _T ("Seek"), + _T ("Select Case"), + _T ("SendKeys"), + _T ("Set"), + _T ("Shell"), + _T ("Sin"), + _T ("Space"), + _T ("Sqr"), + _T ("Static"), + _T ("Stop"), + _T ("Str"), + _T ("StrComp"), + _T ("String"), + _T ("StringFunction"), + _T ("Sub"), + _T ("Tan"), + _T ("Text"), + _T ("TextBox"), + _T ("Time"), + _T ("TimeSerial"), + _T ("TimeValue"), + _T ("Trim"), + _T ("LTrim"), + _T ("RTrim"), + _T ("Type"), + _T ("UBound"), + _T ("UCase"), + _T ("Val"), + _T ("VarType"), + _T ("While"), + _T ("Wend"), + _T ("With"), + _T ("Write"), + _T ("Year"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsHtmlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszHtmlKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsAspKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszAspKeywordList, pszChars, nLength); +} + +static BOOL +IsAspNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 +#define COOKIE_USER1 0x0020 +#define COOKIE_EXT_USER1 0x0040 + +DWORD CCrystalTextView:: +ParseLineAsp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_USER1); + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~(COOKIE_EXT_COMMENT|COOKIE_EXT_USER1)) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else if (dwCookie & COOKIE_EXT_USER1) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_COMMENT) + { + if (!(dwCookie & COOKIE_EXT_USER1)) + { + if (I > 1 && pszChars[I] == '>' && pszChars[I - 1] == '-' && pszChars[I - 2] == '-') + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + } + continue; + } + + if ((dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '\'') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + bRedefineBlock = TRUE; + continue; + } + } + + // Normal text + if ((dwCookie & (COOKIE_PREPROCESSOR|COOKIE_EXT_USER1)) && pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + + if ((dwCookie & (COOKIE_PREPROCESSOR|COOKIE_EXT_USER1)) && pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (!(dwCookie & COOKIE_EXT_USER1)) + { + if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + I += 3; + dwCookie |= COOKIE_EXT_COMMENT; + dwCookie &= ~COOKIE_PREPROCESSOR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsAspNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + goto next; + } + } + else if (dwCookie & COOKIE_EXT_USER1) + { + if (IsAspKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsAspNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + else + { + goto next; + } + } + } + else if (dwCookie & COOKIE_USER1) + { + if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else + { + goto next; + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; +next: + ; + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor end: > or bracket + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor start: & + if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '&') + { + dwCookie |= COOKIE_USER1; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: ; + if (dwCookie & COOKIE_USER1) + { + if (pszChars[I] == ';') + { + dwCookie &= ~COOKIE_USER1; + nIdentBegin = -1; + continue; + } + } + + } + } + + if (nIdentBegin >= 0 && (dwCookie & COOKIE_PREPROCESSOR)) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsAspNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + else if (nIdentBegin >= 0 && (dwCookie & COOKIE_EXT_USER1)) + { + if (IsAspKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsAspNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + } + } + + // Preprocessor end: > or } + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + } + } + +end: + dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_PREPROCESSOR | COOKIE_EXT_USER1); + return dwCookie; +} diff --git a/Src/editlib/basic.cpp b/Src/editlib/basic.cpp new file mode 100644 index 000000000..6b4304fe2 --- /dev/null +++ b/Src/editlib/basic.cpp @@ -0,0 +1,444 @@ +/////////////////////////////////////////////////////////////////////////// +// File: basic.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Visual Basic syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszBasicKeywordList[] = + { + _T ("If"), + _T ("Function"), + _T ("Else"), + _T ("End"), + _T ("For"), + _T ("Next"), + _T ("While"), + _T ("Wend"), + _T ("SMDoMenu"), + _T ("GetAttrType"), + _T ("GetAttrName"), + _T ("GetAttrValString"), + _T ("GetAttrValFloat"), + _T ("GetAttrValInt"), + _T ("GetAttrValBool"), + _T ("GetAttrValEnumInt"), + _T ("GetAttrValEnumString"), + _T ("GetClassId"), + _T ("GetGeoType"), + _T ("SetAttrValString"), + _T ("SetAttrValInt"), + _T ("SetAttrValFloat"), + _T ("SetAttrValBool"), + _T ("SetAttrValEnumString"), + _T ("SetAttrValEnumInt"), + _T ("CreateVerifyItem"), + _T ("VerifyCardinalities"), + _T ("As"), + _T ("Abs"), + _T ("AppActivate"), + _T ("Asc"), + _T ("Atn"), + _T ("Beep"), + _T ("Call"), + _T ("CDbl"), + _T ("ChDir"), + _T ("ChDrive"), + _T ("CheckBox"), + _T ("Chr"), + _T ("CInt"), + _T ("CLng"), + _T ("Close"), + _T ("Const"), + _T ("Cos"), + _T ("CreateObject"), + _T ("CSng"), + _T ("CStr"), + _T ("CVar"), + _T ("CurDir"), + _T ("Date"), + _T ("Declare"), + _T ("Dialog"), + _T ("Dim"), + _T ("Dir"), + _T ("DlgEnable"), + _T ("DlgText"), + _T ("DlgVisible"), + _T ("Do"), + _T ("Double"), + _T ("Loop"), + _T ("End"), + _T ("EOF"), + _T ("Erase"), + _T ("Exit"), + _T ("Exp"), + _T ("FileCopy"), + _T ("FileLen"), + _T ("Fix"), + _T ("For"), + _T ("To"), + _T ("Step"), + _T ("Next"), + _T ("Format"), + _T ("Function"), + _T ("GetObject"), + _T ("Global"), + _T ("GoSub"), + _T ("Return"), + _T ("GoTo"), + _T ("Hex"), + _T ("Hour"), + _T ("If"), + _T ("Then"), + _T ("Else"), + _T ("Input"), + _T ("InputBox"), + _T ("InStr"), + _T ("Int"), + _T ("IsDate"), + _T ("IsEmpty"), + _T ("IsNull"), + _T ("IsNumeric"), + _T ("Kill"), + _T ("LBound"), + _T ("LCase"), + _T ("LCase$"), + _T ("Left"), + _T ("Left$"), + _T ("Len"), + _T ("Let"), + _T ("Line"), + _T ("Input#"), + _T ("Log"), + _T ("Long"), + _T ("Mid"), + _T ("Minute"), + _T ("MkDir"), + _T ("Month"), + _T ("MsgBox"), + _T ("Name"), + _T ("Now"), + _T ("Oct"), + _T ("On"), + _T ("Error"), + _T ("Open"), + _T ("Option"), + _T ("Base"), + _T ("Print"), + _T ("Print"), + _T ("Rem"), + _T ("Right"), + _T ("RmDir"), + _T ("Rnd"), + _T ("Second"), + _T ("Seek"), + _T ("Seek"), + _T ("Select Case"), + _T ("SendKeys"), + _T ("Set"), + _T ("Shell"), + _T ("Sin"), + _T ("Space"), + _T ("Sqr"), + _T ("Static"), + _T ("Stop"), + _T ("Str"), + _T ("StrComp"), + _T ("String"), + _T ("StringFunction"), + _T ("Sub"), + _T ("Tan"), + _T ("Text"), + _T ("TextBox"), + _T ("Time"), + _T ("TimeSerial"), + _T ("TimeValue"), + _T ("Trim"), + _T ("LTrim"), + _T ("RTrim"), + _T ("Type"), + _T ("UBound"), + _T ("UCase"), + _T ("Val"), + _T ("VarType"), + _T ("While"), + _T ("Wend"), + _T ("With"), + _T ("Write"), + _T ("Year"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsBasicKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszBasicKeywordList, pszChars, nLength); +} + +static BOOL +IsBasicNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineBasic (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 2 && !xisalnum (pszChars[I]) && (pszChars[I - 1] == 'M' || pszChars[I - 1] == 'm') && (pszChars[I - 2] == 'E' || pszChars[I - 2] == 'e') && (pszChars[I - 3] == 'R' || pszChars[I - 3] == 'r')) + { + DEFINE_BLOCK (I - 3, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsBasicKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsBasicNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsBasicKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsBasicNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/batch.cpp b/Src/editlib/batch.cpp new file mode 100644 index 000000000..a1b05a064 --- /dev/null +++ b/Src/editlib/batch.cpp @@ -0,0 +1,443 @@ +/////////////////////////////////////////////////////////////////////////// +// File: batch.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// MS-DOS batch syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszBatKeywordList[] = + { + _T ("?"), + _T ("CALL"), + _T ("CD"), + _T ("CDD"), + _T ("CHCP"), + _T ("CLS"), + _T ("COLOR"), + _T ("COPY"), + _T ("CTTY"), + _T ("DATE"), + _T ("DEL"), + _T ("DELAY"), + _T ("DESCRIBE"), + _T ("DIR"), + _T ("DIRHISTORY"), + _T ("DIRS"), + _T ("DO"), + _T ("DRAWBOX"), + _T ("DRAWHLINE"), + _T ("DRAWVLINE"), + _T ("ECHO"), + _T ("ECHOERR"), + _T ("ECHOS"), + _T ("ECHOSERR"), + _T ("ENDLOCAL"), + _T ("ERASE"), + _T ("ESET"), + _T ("EXCEPT"), + _T ("EXIT"), + _T ("FFIND"), + _T ("FOR"), + _T ("FREE"), + _T ("GLOBAL"), + _T ("GOSUB"), + _T ("GOTO"), + _T ("HELP"), + _T ("HISTORY"), + _T ("IF"), + _T ("IFF"), + _T ("INKEY"), + _T ("INPUT"), + _T ("KEYBD"), + _T ("KEYSTACK"), + _T ("LH"), + _T ("LOADHIGH"), + _T ("LIST"), + _T ("LOADBTM"), + _T ("LOCK"), + _T ("LOG"), + _T ("MD"), + _T ("MKDIR"), + _T ("MEMORY"), + _T ("MOVE"), + _T ("ON"), + _T ("OPTION"), + _T ("PATH"), + _T ("PAUSE"), + _T ("POPD"), + _T ("PROMPT"), + _T ("PUSHD"), + _T ("QUIT"), + _T ("RD"), + _T ("REBOOT"), + _T ("REM"), + _T ("REN"), + _T ("RENAME"), + _T ("RETURN"), + _T ("SCREEN"), + _T ("SCRPUT"), + _T ("SELECT"), + _T ("SET"), + _T ("SETDOS"), + _T ("SETLOCAL"), + _T ("SHIFT"), + _T ("START"), + _T ("SWAPPING"), + _T ("SWITCH"), + _T ("TEE"), + _T ("TEXT"), + _T ("TIME"), + _T ("TIMER"), + _T ("TOUCH"), + _T ("TREE"), + _T ("TRUENAME"), + _T ("TYPE"), + _T ("UNALIAS"), + _T ("UNLOCK"), + _T ("UNSET"), + _T ("VER"), + _T ("VERIFY"), + _T ("VOL"), + _T ("VSCRPUT"), + _T ("Y"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("APPEND"), + _T ("ATTRIB"), + _T ("BUSETUP"), + _T ("CHKDSK"), + _T ("CHOICE"), + _T ("COMMAND"), + _T ("DEBUG"), + _T ("DEFRAG"), + _T ("DELOLDOS"), + _T ("DELTREE"), + _T ("DISKCOMP"), + _T ("DISKCOPY"), + _T ("DOSKEY"), + _T ("DRVSPACE"), + _T ("EDIT"), + _T ("EMM386"), + _T ("EXPAND"), + _T ("FASTHELP"), + _T ("FASTOPEN"), + _T ("FC"), + _T ("FDISK"), + _T ("FIND"), + _T ("FORMAT"), + _T ("GRAPHICS"), + _T ("HELP"), + _T ("INTERLNK"), + _T ("INTERSVR"), + _T ("KEYB"), + _T ("LABEL"), + _T ("LOADFIX"), + _T ("MEM"), + _T ("MEMMAKER"), + _T ("MODE"), + _T ("MORE"), + _T ("MOUSE"), + _T ("MOVE"), + _T ("MSAV"), + _T ("MSBACKUP"), + _T ("MSCDEX"), + _T ("MSD"), + _T ("MWAV"), + _T ("MWAVTSR"), + _T ("MWBACKUP"), + _T ("MWUNDEL"), + _T ("NLSFUNC"), + _T ("POWER"), + _T ("PRINT"), + _T ("QBASIC"), + _T ("REPLACE"), + _T ("RESTORE"), + _T ("SCANDISK"), + _T ("SETUP"), + _T ("SETVER"), + _T ("SHARE"), + _T ("SIZER"), + _T ("SMARTDRV"), + _T ("SMARTMON"), + _T ("SORT"), + _T ("SUBST"), + _T ("SYS"), + _T ("TREE"), + _T ("UNDELETE"), + _T ("UNFORMAT"), + _T ("UNINSTAL"), + _T ("VSAFE"), + _T ("XCOPY"), + NULL + }; + +static BOOL +IsBatKeyword (LPCTSTR pszChars, int nLength) +{ + for (int L = 0; s_apszBatKeywordList[L] != NULL; L++) + { + if (_tcsnicmp (s_apszBatKeywordList[L], pszChars, nLength) == 0 + && s_apszBatKeywordList[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + TCHAR buffer[13]; + + for (int L = 0; s_apszUser1KeywordList[L] != NULL; L++) + { + if (_tcsnicmp (s_apszUser1KeywordList[L], pszChars, nLength) == 0 + && s_apszUser1KeywordList[L][nLength] == 0) + return TRUE; + _tcscpy (buffer, s_apszUser1KeywordList[L]); + _tcscat (buffer, _T (".COM")); + if (_tcsnicmp (buffer, pszChars, nLength) == 0 + && buffer[nLength] == 0) + return TRUE; + _tcscpy (buffer, s_apszUser1KeywordList[L]); + _tcscat (buffer, _T (".EXE")); + if (_tcsnicmp (buffer, pszChars, nLength) == 0 + && buffer[nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsBatNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineBatch (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (pszChars[I] == ':') + { + DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + continue; + } + if (nLength >= I + 3 && !_tcsnicmp (pszChars + I, _T ("REM"), 3) && (isspace (pszChars[I + 3]) || nLength == I + 3)) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsBatKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsBatNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsBatKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsBatNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + } + + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/ccrystaleditview.cpp b/Src/editlib/ccrystaleditview.cpp new file mode 100644 index 000000000..1233ac781 --- /dev/null +++ b/Src/editlib/ccrystaleditview.cpp @@ -0,0 +1,2532 @@ +/////////////////////////////////////////////////////////////////////////// +// File: ccrystaleditview.cpp +// Version: 1.2.0.5 +// Created: 29-Dec-1998 +// +// Copyright: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalEditView class, a part of the Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 21-Feb-99 +// Paul Selormey, James R. Twine: +// + FEATURE: description for Undo/Redo actions +// + FEATURE: multiple MSVC-like bookmarks +// + FEATURE: 'Disable backspace at beginning of line' option +// + FEATURE: 'Disable drag-n-drop editing' option +// +// + FEATURE: Auto indent +// + FIX: ResetView() was overriden to provide cleanup +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: support for autoindenting brackets and parentheses +// + FEATURE: menu options, view and window +// + FEATURE: SDI+MDI versions with help +// + FEATURE: extended registry support for saving settings +// + FEATURE: some other things I've forgotten ... +// 27-Jul-99 +// + FIX: treating groups in regular expressions corrected +// + FIX: autocomplete corrected +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// ??-Aug-99 +// Sven Wiegand (search for "//BEGIN SW" to find my changes): +// + FEATURE: "Go to last change" (sets the cursor on the position where +// the user did his last edit actions +// + FEATURE: Support for incremental search in CCrystalTextView +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 24-Oct-99 +// Sven Wiegand +// + FEATURE: Supporting [Return] to exit incremental-search-mode +// (see OnChar()) +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "editcmd.h" +#include "editreg.h" +#include "ccrystaleditview.h" +#include "ccrystaltextbuffer.h" +#include "ceditreplacedlg.h" +#include "registry.h" +#include "cs2cs.h" +#include "chcondlg.h" + +#ifndef __AFXPRIV_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif +#ifndef __AFXOLE_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define DRAG_BORDER_X 5 +#define DRAG_BORDER_Y 5 + +///////////////////////////////////////////////////////////////////////////// +// CEditDropTargetImpl class declaration + +class CEditDropTargetImpl : public COleDropTarget + { +private : + CCrystalEditView * m_pOwner; +public : + CEditDropTargetImpl (CCrystalEditView * pOwner) + { + m_pOwner = pOwner; + }; + + virtual DROPEFFECT OnDragEnter (CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point); + virtual void OnDragLeave (CWnd * pWnd); + virtual DROPEFFECT OnDragOver (CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point); + virtual BOOL OnDrop (CWnd * pWnd, COleDataObject * pDataObject, DROPEFFECT dropEffect, CPoint point); + virtual DROPEFFECT OnDragScroll (CWnd * pWnd, DWORD dwKeyState, CPoint point); + }; + + +#pragma warning ( disable : 4100 ) +///////////////////////////////////////////////////////////////////////////// +// CCrystalEditView + +IMPLEMENT_DYNCREATE (CCrystalEditView, CCrystalTextView) + +CCrystalEditView::CCrystalEditView () +{ + AFX_ZERO_INIT_OBJECT (CCrystalTextView); + m_bInsertTabs = TRUE; + m_bAutoIndent = TRUE; + m_mapExpand = new CMap (10); +} + +CCrystalEditView:: ~ CCrystalEditView () +{ + delete m_mapExpand; +} + +bool CCrystalEditView:: +DoSetTextType (TextDefinition *def) +{ + m_CurSourceDef = def; + SetInsertTabs ((def->flags & SRCOPT_INSERTTABS) != FALSE); + SetAutoIndent ((def->flags & SRCOPT_AUTOINDENT) != FALSE); + SetDisableBSAtSOL ((def->flags & SRCOPT_BSATBOL) == FALSE); + m_mapExpand->RemoveAll (); + CReg reg; + CString sKey = REG_EDITPAD _T("\\"); + sKey += def->name; + sKey += _T ("\\Expand"); + if (reg.Open (HKEY_CURRENT_USER, sKey, KEY_READ)) + { + LPCTSTR pszValue; + RegVal regVal; + if (reg.FindFirstValue (pszValue, ®Val)) + { + CString sData; + do + if (RegValGetString (®Val, sData)) + m_mapExpand->SetAt (pszValue, sData); + while (reg.FindNextValue (pszValue, ®Val)); + } + reg.FindClose (); + } + return CCrystalTextView::DoSetTextType (def); +} + +BEGIN_MESSAGE_MAP (CCrystalEditView, CCrystalTextView) +//{{AFX_MSG_MAP(CCrystalEditView) +ON_COMMAND (ID_EDIT_PASTE, OnEditPaste) +ON_UPDATE_COMMAND_UI (ID_EDIT_CUT, OnUpdateEditCut) +ON_COMMAND (ID_EDIT_CUT, OnEditCut) +ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE, OnUpdateEditPaste) +ON_COMMAND (ID_EDIT_DELETE, OnEditDelete) +ON_WM_CHAR () +ON_COMMAND (ID_EDIT_DELETE_BACK, OnEditDeleteBack) +ON_COMMAND (ID_EDIT_UNTAB, OnEditUntab) +ON_COMMAND (ID_EDIT_TAB, OnEditTab) +ON_COMMAND (ID_EDIT_SWITCH_OVRMODE, OnEditSwitchOvrmode) +ON_UPDATE_COMMAND_UI (ID_EDIT_SWITCH_OVRMODE, OnUpdateEditSwitchOvrmode) +ON_WM_CREATE () +ON_WM_DESTROY () +ON_COMMAND (ID_EDIT_REPLACE, OnEditReplace) +ON_UPDATE_COMMAND_UI (ID_EDIT_UNDO, OnUpdateEditUndo) +ON_COMMAND (ID_EDIT_UNDO, OnEditUndo) +ON_UPDATE_COMMAND_UI (ID_EDIT_REDO, OnUpdateEditRedo) +ON_COMMAND (ID_EDIT_REDO, OnEditRedo) +ON_UPDATE_COMMAND_UI (ID_EDIT_AUTOCOMPLETE, OnUpdateEditAutoComplete) +ON_COMMAND (ID_EDIT_AUTOCOMPLETE, OnEditAutoComplete) +ON_UPDATE_COMMAND_UI (ID_EDIT_AUTOEXPAND, OnUpdateEditAutoExpand) +ON_COMMAND (ID_EDIT_AUTOEXPAND, OnEditAutoExpand) +ON_UPDATE_COMMAND_UI (ID_EDIT_LOWERCASE, OnUpdateEditLowerCase) +ON_COMMAND (ID_EDIT_LOWERCASE, OnEditLowerCase) +ON_UPDATE_COMMAND_UI (ID_EDIT_UPPERCASE, OnUpdateEditUpperCase) +ON_COMMAND (ID_EDIT_UPPERCASE, OnEditUpperCase) +ON_UPDATE_COMMAND_UI (ID_EDIT_SWAPCASE, OnUpdateEditSwapCase) +ON_COMMAND (ID_EDIT_SWAPCASE, OnEditSwapCase) +ON_UPDATE_COMMAND_UI (ID_EDIT_SWAPCASE, OnUpdateEditSwapCase) +ON_COMMAND (ID_EDIT_SWAPCASE, OnEditSwapCase) +ON_UPDATE_COMMAND_UI (ID_EDIT_CAPITALIZE, OnUpdateEditCapitalize) +ON_COMMAND (ID_EDIT_CAPITALIZE, OnEditCapitalize) +ON_UPDATE_COMMAND_UI (ID_EDIT_SENTENCE, OnUpdateEditSentence) +ON_COMMAND (ID_EDIT_SENTENCE, OnEditSentence) +ON_UPDATE_COMMAND_UI(ID_EDIT_GOTO_LAST_CHANGE, OnUpdateEditGotoLastChange) +ON_COMMAND(ID_EDIT_GOTO_LAST_CHANGE, OnEditGotoLastChange) +ON_COMMAND(ID_EDIT_DELETE_WORD, OnEditDeleteWord) +ON_COMMAND(ID_EDIT_DELETE_WORD_BACK, OnEditDeleteWordBack) +//}}AFX_MSG_MAP +ON_UPDATE_COMMAND_UI (ID_EDIT_INDICATOR_READ, OnUpdateIndicatorRead) +ON_UPDATE_COMMAND_UI (ID_INDICATOR_OVR, OnUpdateIndicatorOvr) +ON_UPDATE_COMMAND_UI (ID_EDIT_INDICATOR_POSITION, OnUpdateIndicatorPosition) +ON_UPDATE_COMMAND_UI (ID_TOOLS_SPELLING, OnUpdateToolsSpelling) +ON_COMMAND (ID_TOOLS_SPELLING, OnToolsSpelling) +ON_UPDATE_COMMAND_UI (ID_TOOLS_CHARCODING, OnUpdateToolsCharCoding) +ON_COMMAND (ID_TOOLS_CHARCODING, OnToolsCharCoding) +END_MESSAGE_MAP () + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalEditView message handlers + +void CCrystalEditView::ResetView () +{ + // m_bAutoIndent = TRUE; + m_bOvrMode = FALSE; + m_bLastReplace = FALSE; + CCrystalTextView::ResetView (); +} + +BOOL CCrystalEditView:: +QueryEditable () +{ + if (m_pTextBuffer == NULL) + return FALSE; + return !m_pTextBuffer->GetReadOnly (); +} + +void CCrystalEditView:: +OnEditPaste () +{ + Paste (); +} + +void CCrystalEditView:: +OnUpdateEditPaste (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (TextInClipboard ()); +} + +void CCrystalEditView:: +OnUpdateEditCut (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditCut () +{ + Cut (); +} + +BOOL CCrystalEditView:: +DeleteCurrentSelection () +{ + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + CPoint ptCursorPos = ptSelStart; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELSEL); + return TRUE; + } + return FALSE; +} + +void CCrystalEditView:: +Paste () +{ + if (!QueryEditable ()) + return; + if (m_pTextBuffer == NULL) + return; + + CString text; + if (GetFromClipboard (text)) + { + m_pTextBuffer->BeginUndoGroup (); + + CPoint ptCursorPos; + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // WINMERGE: clear the winmerge flags so the file saves correctly + for (int i=ptSelStart.y; i <= ptSelEnd.y; i++) + m_pTextBuffer->SetLineFlag(i, LF_WINMERGE_FLAGS, FALSE, FALSE, FALSE); + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_PASTE); + } + else + { + ptCursorPos = GetCursorPos (); + + // WINMERGE: clear the winmerge flags so the file saves correctly + m_pTextBuffer->SetLineFlag(ptCursorPos.y, LF_WINMERGE_FLAGS, FALSE, FALSE, FALSE); + } + ASSERT_VALIDTEXTPOS (ptCursorPos); + + int x, y; + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, text, y, x, CE_ACTION_PASTE); // [JRT] + + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +Cut () +{ + if (!QueryEditable ()) + return; + if (m_pTextBuffer == NULL) + return; + if (!IsSelection ()) + return; + + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + PutToClipboard (text); + + CPoint ptCursorPos = ptSelStart; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_CUT); // [JRT] + +} + +void CCrystalEditView:: +OnEditDelete () +{ + if (!QueryEditable () || m_pTextBuffer == NULL) + return; + + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + if (ptSelStart == ptSelEnd) + { + if (ptSelEnd.x == GetLineLength (ptSelEnd.y)) + { + if (ptSelEnd.y == GetLineCount () - 1) + return; + ptSelEnd.y++; + ptSelEnd.x = 0; + } + else + ptSelEnd.x++; + } + + CPoint ptCursorPos = ptSelStart; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); // [JRT] + +} + +void CCrystalEditView:: +OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) +{ + //BEGIN SW + // check if incremental search is active before call to CCrystalTextView::OnChar() + BOOL bIncrementalSearch = m_bIncrementalSearchForward || m_bIncrementalSearchBackward; + //END Sw + CCrystalTextView::OnChar (nChar, nRepCnt, nFlags); + //BEGIN SW + // if we are in incremental search mode ignore the character + if( m_bIncrementalSearchForward || m_bIncrementalSearchBackward ) + return; + //END SW + + // if we *were* in incremental search mode and CCrystalTextView::OnChar() + // exited it the ignore the character (VK_RETURN) + if( bIncrementalSearch && !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + return; + //END SW + + if ((::GetAsyncKeyState (VK_LBUTTON) & 0x8000) != 0 || + (::GetAsyncKeyState (VK_RBUTTON) & 0x8000) != 0) + return; + + if (nChar == VK_RETURN) + { + if (m_bOvrMode) + { + CPoint ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + if (ptCursorPos.y < GetLineCount () - 1) + { + ptCursorPos.x = 0; + ptCursorPos.y++; + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + return; + } + } + + m_pTextBuffer->BeginUndoGroup (); + + if (QueryEditable () && m_pTextBuffer != NULL) + { + CPoint ptCursorPos; + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_TYPING); + } + else + ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + const static TCHAR pszText[3] = _T ("\r\n"); + + int x, y; + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT] + + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + } + + m_pTextBuffer->FlushUndoGroup (this); + return; + } + + if (nChar > 31) + { + if (QueryEditable () && m_pTextBuffer != NULL) + { + m_pTextBuffer->BeginUndoGroup (nChar != _T (' ')); + + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CPoint ptCursorPos; + if (ptSelStart != ptSelEnd) + { + ptCursorPos = ptSelStart; + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_TYPING); + } + } + else + { + ptCursorPos = GetCursorPos (); + if (m_bOvrMode && ptCursorPos.x < GetLineLength (ptCursorPos.y)) + m_pTextBuffer->DeleteText (this, ptCursorPos.y, ptCursorPos.x, ptCursorPos.y, ptCursorPos.x + 1, CE_ACTION_TYPING); // [JRT] + + } + + ASSERT_VALIDTEXTPOS (ptCursorPos); + + TCHAR pszText[2]; + pszText[0] = (TCHAR) nChar; + pszText[1] = 0; + + int x, y; + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT] + + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } + } +} + + +// +// [JRT]: Added Support For "Disable Backspace At Start Of Line" +// +void CCrystalEditView:: +OnEditDeleteBack () +{ + //BEGIN SW + // if we are in incremental search mode ignore backspace + CCrystalTextView::OnEditDeleteBack(); + if( m_bIncrementalSearchForward || m_bIncrementalSearchBackward ) + return; + //END SW + + if (IsSelection ()) + { + OnEditDelete (); + return; + } + + if (!QueryEditable () || m_pTextBuffer == NULL) + return; + + CPoint ptCursorPos = GetCursorPos (); + CPoint ptCurrentCursorPos = ptCursorPos; + bool bDeleted = false; + + if (!(ptCursorPos.x)) // If At Start Of Line + + { + if (!m_bDisableBSAtSOL) // If DBSASOL Is Disabled + + { + if (ptCursorPos.y > 0) // If Previous Lines Available + + { + ptCursorPos.y--; // Decrement To Previous Line + + ptCursorPos.x = GetLineLength ( + ptCursorPos.y); // Set Cursor To End Of Previous Line + + bDeleted = true; // Set Deleted Flag + + } + } + } + else // If Caret Not At SOL + + { + ptCursorPos.x--; // Decrement Position + + bDeleted = true; // Set Deleted Flag + + } + /* + if (ptCursorPos.x == 0) + { + if (ptCursorPos.y == 0) + return; + ptCursorPos.y --; + ptCursorPos.x = GetLineLength(ptCursorPos.y); + } + else + ptCursorPos.x --; + */ + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + if (bDeleted) + { + m_pTextBuffer->DeleteText (this, ptCursorPos.y, ptCursorPos.x, ptCurrentCursorPos.y, ptCurrentCursorPos.x, CE_ACTION_BACKSPACE); // [JRT] + + } + return; +} + +void CCrystalEditView:: +OnEditTab () +{ + if (!QueryEditable () || m_pTextBuffer == NULL) + return; + + BOOL bTabify = FALSE; + CPoint ptSelStart, ptSelEnd; + if (IsSelection ()) + { + GetSelection (ptSelStart, ptSelEnd); + bTabify = ptSelStart.y != ptSelEnd.y; + } + + CPoint ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + + static TCHAR pszText[32]; + if (m_bInsertTabs) + { + *pszText = _T ('\t'); + pszText[1] = _T ('\0'); + } + else + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - ptCursorPos.x % nTabSize; + memset(pszText, _T(' '), nChars); + pszText[nChars] = _T ('\0'); + } + + if (bTabify) + { + m_pTextBuffer->BeginUndoGroup (); + + int nStartLine = ptSelStart.y; + int nEndLine = ptSelEnd.y; + ptSelStart.x = 0; + if (ptSelEnd.x > 0) + { + if (ptSelEnd.y == GetLineCount () - 1) + { + ptSelEnd.x = GetLineLength (ptSelEnd.y); + } + else + { + ptSelEnd.x = 0; + ptSelEnd.y++; + } + } + else + nEndLine--; + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptSelEnd); + EnsureVisible (ptSelEnd); + + // Shift selection to right + m_bHorzScrollBarLocked = TRUE; + for (int L = nStartLine; L <= nEndLine; L++) + { + int x, y; + m_pTextBuffer->InsertText (this, L, 0, pszText, y, x, CE_ACTION_INDENT); // [JRT] + + } + m_bHorzScrollBarLocked = FALSE; + RecalcHorzScrollBar (); + + m_pTextBuffer->FlushUndoGroup (this); + return; + } + + if (m_bOvrMode) + { + CPoint ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + + int nLineLength = GetLineLength (ptCursorPos.y); + LPCTSTR pszLineChars = GetLineChars (ptCursorPos.y); + if (ptCursorPos.x < nLineLength) + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - CalculateActualOffset (ptCursorPos.y, ptCursorPos.x) % nTabSize; + ASSERT (nChars > 0 && nChars <= nTabSize); + + while (nChars > 0) + { + if (ptCursorPos.x == nLineLength) + break; + if (pszLineChars[ptCursorPos.x] == _T ('\t')) + { + ptCursorPos.x++; + break; + } + ptCursorPos.x++; + nChars--; + } + ASSERT (ptCursorPos.x <= nLineLength); + ASSERT_VALIDTEXTPOS (ptCursorPos); + + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + return; + } + } + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_TYPING); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT] + + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); +} + +void CCrystalEditView:: +OnEditUntab () +{ + if (!QueryEditable () || m_pTextBuffer == NULL) + return; + + BOOL bTabify = FALSE; + CPoint ptSelStart, ptSelEnd; + if (IsSelection ()) + { + GetSelection (ptSelStart, ptSelEnd); + bTabify = ptSelStart.y != ptSelEnd.y; + } + + if (bTabify) + { + m_pTextBuffer->BeginUndoGroup (); + + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + int nStartLine = ptSelStart.y; + int nEndLine = ptSelEnd.y; + ptSelStart.x = 0; + if (ptSelEnd.x > 0) + { + if (ptSelEnd.y == GetLineCount () - 1) + { + ptSelEnd.x = GetLineLength (ptSelEnd.y); + } + else + { + ptSelEnd.x = 0; + ptSelEnd.y++; + } + } + else + nEndLine--; + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptSelEnd); + EnsureVisible (ptSelEnd); + + // Shift selection to left + m_bHorzScrollBarLocked = TRUE; + for (int L = nStartLine; L <= nEndLine; L++) + { + int nLength = GetLineLength (L); + if (nLength > 0) + { + LPCTSTR pszChars = GetLineChars (L); + int nPos = 0, nOffset = 0; + while (nPos < nLength) + { + if (pszChars[nPos] == _T (' ')) + { + nPos++; + if (++nOffset >= GetTabSize ()) + break; + } + else + { + if (pszChars[nPos] == _T ('\t')) + nPos++; + break; + } + } + + if (nPos > 0) + m_pTextBuffer->DeleteText (this, L, 0, L, nPos, CE_ACTION_INDENT); // [JRT] + + } + } + m_bHorzScrollBarLocked = FALSE; + RecalcHorzScrollBar (); + + m_pTextBuffer->FlushUndoGroup (this); + } + else + { + CPoint ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + if (ptCursorPos.x > 0) + { + int nTabSize = GetTabSize (); + int nOffset = CalculateActualOffset (ptCursorPos.y, ptCursorPos.x); + int nNewOffset = nOffset / nTabSize * nTabSize; + if (nOffset == nNewOffset && nNewOffset > 0) + nNewOffset -= nTabSize; + ASSERT (nNewOffset >= 0); + + LPCTSTR pszChars = GetLineChars (ptCursorPos.y); + int nCurrentOffset = 0; + int I = 0; + while (nCurrentOffset < nNewOffset) + { + if (pszChars[I] == _T ('\t')) + nCurrentOffset = nCurrentOffset / nTabSize * nTabSize + nTabSize; + else + nCurrentOffset++; + I++; + } + + ASSERT (nCurrentOffset == nNewOffset); + + ptCursorPos.x = I; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + } + } +} + +void CCrystalEditView:: +OnUpdateIndicatorCol (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (FALSE); +} + +void CCrystalEditView:: +OnUpdateIndicatorOvr (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_bOvrMode); +} + +void CCrystalEditView:: +OnUpdateIndicatorRead (CCmdUI * pCmdUI) +{ + if (m_pTextBuffer == NULL) + pCmdUI->Enable (FALSE); + else + pCmdUI->Enable (m_pTextBuffer->GetReadOnly ()); +} + +void CCrystalEditView:: +OnEditSwitchOvrmode () +{ + m_bOvrMode = !m_bOvrMode; +} + +void CCrystalEditView:: +OnUpdateEditSwitchOvrmode (CCmdUI * pCmdUI) +{ + pCmdUI->SetCheck (m_bOvrMode ? 1 : 0); +} + +DROPEFFECT CEditDropTargetImpl:: +OnDragEnter (CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point) +{ + if (!pDataObject->IsDataAvailable (CF_TEXT)) + { + m_pOwner->HideDropIndicator (); + return DROPEFFECT_NONE; + } + m_pOwner->ShowDropIndicator (point); + if (dwKeyState & MK_CONTROL) + return DROPEFFECT_COPY; + return DROPEFFECT_MOVE; +} + +void CEditDropTargetImpl:: +OnDragLeave (CWnd * pWnd) +{ + m_pOwner->HideDropIndicator (); +} + +DROPEFFECT CEditDropTargetImpl:: +OnDragOver (CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point) +{ + /* + if (! pDataObject->IsDataAvailable(CF_TEXT)) + { + m_pOwner->HideDropIndicator(); + return DROPEFFECT_NONE; + } + */ + // + // [JRT] + // + bool bDataSupported = false; + + if ((!m_pOwner) || // If No Owner + (!(m_pOwner->QueryEditable ())) || // Or Not Editable + (m_pOwner->GetDisableDragAndDrop ())) // Or Drag And Drop Disabled + + { + m_pOwner->HideDropIndicator (); // Hide Drop Caret + + return DROPEFFECT_NONE; // Return DE_NONE + + } + // if ((pDataObject->IsDataAvailable( CF_TEXT ) ) || // If Text Available + // ( pDataObject -> IsDataAvailable( xxx ) ) || // Or xxx Available + // ( pDataObject -> IsDataAvailable( yyy ) ) ) // Or yyy Available + if (pDataObject->IsDataAvailable (CF_TEXT)) // If Text Available + + { + bDataSupported = true; // Set Flag + + } + if (!bDataSupported) // If No Supported Formats Available + + { + m_pOwner->HideDropIndicator (); // Hide Drop Caret + + return DROPEFFECT_NONE; // Return DE_NONE + + } + m_pOwner->ShowDropIndicator (point); + if (dwKeyState & MK_CONTROL) + return DROPEFFECT_COPY; + return DROPEFFECT_MOVE; +} + +BOOL CEditDropTargetImpl:: +OnDrop (CWnd * pWnd, COleDataObject * pDataObject, DROPEFFECT dropEffect, CPoint point) +{ + // + // [JRT] ( m_pOwner -> GetDisableDragAndDrop() ) ) // Or Drag And Drop Disabled + // + bool bDataSupported = false; + + m_pOwner->HideDropIndicator (); // Hide Drop Caret + + if ((!m_pOwner) || // If No Owner + (!(m_pOwner->QueryEditable ())) || // Or Not Editable + (m_pOwner->GetDisableDragAndDrop ())) // Or Drag And Drop Disabled + + { + return DROPEFFECT_NONE; // Return DE_NONE + + } + // if( ( pDataObject -> IsDataAvailable( CF_TEXT ) ) || // If Text Available + // ( pDataObject -> IsDataAvailable( xxx ) ) || // Or xxx Available + // ( pDataObject -> IsDataAvailable( yyy ) ) ) // Or yyy Available + if (pDataObject->IsDataAvailable (CF_TEXT)) // If Text Available + + { + bDataSupported = true; // Set Flag + + } + if (!bDataSupported) // If No Supported Formats Available + + { + return DROPEFFECT_NONE; // Return DE_NONE + + } + return (m_pOwner->DoDropText (pDataObject, point)); // Return Result Of Drop + +} + +DROPEFFECT CEditDropTargetImpl:: +OnDragScroll (CWnd * pWnd, DWORD dwKeyState, CPoint point) +{ + ASSERT (m_pOwner == pWnd); + m_pOwner->DoDragScroll (point); + + if (dwKeyState & MK_CONTROL) + return DROPEFFECT_COPY; + return DROPEFFECT_MOVE; +} + +void CCrystalEditView:: +DoDragScroll (const CPoint & point) +{ + CRect rcClientRect; + GetClientRect (rcClientRect); + if (point.y < rcClientRect.top + DRAG_BORDER_Y) + { + HideDropIndicator (); + ScrollUp (); + UpdateWindow (); + ShowDropIndicator (point); + //UpdateSiblingScrollPos(FALSE); + return; + } + if (point.y >= rcClientRect.bottom - DRAG_BORDER_Y) + { + HideDropIndicator (); + ScrollDown (); + UpdateWindow (); + ShowDropIndicator (point); + //UpdateSiblingScrollPos(FALSE); + return; + } + if (point.x < rcClientRect.left + GetMarginWidth () + DRAG_BORDER_X) + { + HideDropIndicator (); + ScrollLeft (); + UpdateWindow (); + ShowDropIndicator (point); + //UpdateSiblingScrollPos(TRUE); + return; + } + if (point.x >= rcClientRect.right - DRAG_BORDER_X) + { + HideDropIndicator (); + ScrollRight (); + UpdateWindow (); + ShowDropIndicator (point); + //UpdateSiblingScrollPos(TRUE); + return; + } +} + +BOOL CCrystalEditView:: +DoDropText (COleDataObject * pDataObject, const CPoint & ptClient) +{ + HGLOBAL hData = pDataObject->GetGlobalData (CF_TEXT); + if (hData == NULL) + return FALSE; + + CPoint ptDropPos = ClientToText (ptClient); + if (IsDraggingText () && IsInsideSelection (ptDropPos)) + { + SetAnchor (ptDropPos); + SetSelection (ptDropPos, ptDropPos); + SetCursorPos (ptDropPos); + EnsureVisible (ptDropPos); + return FALSE; + } + + LPTSTR pszText = (LPTSTR)::GlobalLock (hData); + if (pszText == NULL) + return FALSE; + + int x, y; + m_pTextBuffer->InsertText (this, ptDropPos.y, ptDropPos.x, pszText, y, x, CE_ACTION_DRAGDROP); // [JRT] + + CPoint ptCurPos (x, y); + ASSERT_VALIDTEXTPOS (ptCurPos); + SetAnchor (ptDropPos); + SetSelection (ptDropPos, ptCurPos); + SetCursorPos (ptCurPos); + EnsureVisible (ptCurPos); + + ::GlobalUnlock (hData); + return TRUE; +} + +int CCrystalEditView:: +OnCreate (LPCREATESTRUCT lpCreateStruct) +{ + if (CCrystalTextView::OnCreate (lpCreateStruct) == -1) + return -1; + + ASSERT (m_pDropTarget == NULL); + m_pDropTarget = new CEditDropTargetImpl (this); + if (!m_pDropTarget->Register (this)) + { + TRACE0 ("Warning: Unable to register drop target for ccrystaleditview.\n"); + delete m_pDropTarget; + m_pDropTarget = NULL; + } + + return 0; +} + +void CCrystalEditView:: +OnDestroy () +{ + if (m_pDropTarget != NULL) + { + m_pDropTarget->Revoke (); + delete m_pDropTarget; + m_pDropTarget = NULL; + } + + CCrystalTextView::OnDestroy (); +} + +void CCrystalEditView:: +ShowDropIndicator (const CPoint & point) +{ + if (!m_bDropPosVisible) + { + HideCursor (); + m_ptSavedCaretPos = GetCursorPos (); + m_bDropPosVisible = TRUE; + ::CreateCaret (m_hWnd, (HBITMAP) 1, 2, GetLineHeight ()); + } + m_ptDropPos = ClientToText (point); + if (m_ptDropPos.x >= m_nOffsetChar) + { + SetCaretPos (TextToClient (m_ptDropPos)); + ShowCaret (); + } + else + { + HideCaret (); + } +} + +void CCrystalEditView:: +HideDropIndicator () +{ + if (m_bDropPosVisible) + { + SetCursorPos (m_ptSavedCaretPos); + ShowCursor (); + m_bDropPosVisible = FALSE; + } +} + +DROPEFFECT CCrystalEditView:: +GetDropEffect () +{ + return DROPEFFECT_COPY | DROPEFFECT_MOVE; +} + +void CCrystalEditView:: +OnDropSource (DROPEFFECT de) +{ + if (!IsDraggingText ()) + return; + + ASSERT_VALIDTEXTPOS (m_ptDraggedTextBegin); + ASSERT_VALIDTEXTPOS (m_ptDraggedTextEnd); + + if (de == DROPEFFECT_MOVE) + { + m_pTextBuffer->DeleteText (this, m_ptDraggedTextBegin.y, m_ptDraggedTextBegin.x, m_ptDraggedTextEnd.y, + m_ptDraggedTextEnd.x, CE_ACTION_DRAGDROP); // [JRT] + + } +} + +void CCrystalEditView:: +UpdateView (CCrystalTextView * pSource, CUpdateContext * pContext, DWORD dwFlags, int nLineIndex /*= -1*/ ) +{ + CCrystalTextView::UpdateView (pSource, pContext, dwFlags, nLineIndex); + + if (m_bSelectionPushed && pContext != NULL) + { + pContext->RecalcPoint (m_ptSavedSelStart); + pContext->RecalcPoint (m_ptSavedSelEnd); + ASSERT_VALIDTEXTPOS (m_ptSavedSelStart); + ASSERT_VALIDTEXTPOS (m_ptSavedSelEnd); + } +} + +void CCrystalEditView:: +OnEditReplace () +{ + if (!QueryEditable ()) + return; + + CWinApp *pApp = AfxGetApp (); + ASSERT (pApp != NULL); + + CEditReplaceDlg dlg (this); + + if (m_bLastReplace) + { + // Get the latest Replace parameters + dlg.m_bMatchCase = (m_dwLastReplaceFlags & FIND_MATCH_CASE) != 0; + dlg.m_bWholeWord = (m_dwLastReplaceFlags & FIND_WHOLE_WORD) != 0; + dlg.m_bRegExp = (m_dwLastReplaceFlags & FIND_REGEXP) != 0; + if (m_pszLastFindWhat != NULL) + dlg.m_sText = m_pszLastFindWhat; + } + else + { + DWORD dwFlags; + if (!RegLoadNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("ReplaceFlags"), &dwFlags)) + dwFlags = 0; + dlg.m_bMatchCase = (dwFlags & FIND_MATCH_CASE) != 0; + dlg.m_bWholeWord = (dwFlags & FIND_WHOLE_WORD) != 0; + dlg.m_bRegExp = (dwFlags & FIND_REGEXP) != 0; + // dlg.m_sText = pApp->GetProfileString (REG_REPLACE_SUBKEY, REG_FIND_WHAT, _T ("")); + // dlg.m_sNewText = pApp->GetProfileString (REG_REPLACE_SUBKEY, REG_REPLACE_WITH, _T ("")); + } + + if (IsSelection ()) + { + GetSelection (m_ptSavedSelStart, m_ptSavedSelEnd); + m_bSelectionPushed = TRUE; + + dlg.m_nScope = 0; // Replace in current selection + + dlg.m_ptCurrentPos = m_ptSavedSelStart; + dlg.m_bEnableScopeSelection = TRUE; + dlg.m_ptBlockBegin = m_ptSavedSelStart; + dlg.m_ptBlockEnd = m_ptSavedSelEnd; + } + else + { + dlg.m_nScope = 1; // Replace in whole text + + dlg.m_ptCurrentPos = GetCursorPos (); + dlg.m_bEnableScopeSelection = FALSE; + + CPoint ptCursorPos = GetCursorPos (), ptStart = WordToLeft (ptCursorPos), ptEnd = WordToRight (ptCursorPos); + if (IsValidTextPos (ptStart) && IsValidTextPos (ptEnd) && ptStart != ptEnd) + GetText (ptStart, ptEnd, dlg.m_sText); + } + + // Execute Replace dialog + // m_bShowInactiveSelection = TRUE; // FP: removed because I like it + dlg.DoModal (); + // m_bShowInactiveSelection = FALSE; // FP: removed because I like it + + // Save Replace parameters for 'F3' command + m_bLastReplace = TRUE; + if (m_pszLastFindWhat != NULL) + free (m_pszLastFindWhat); + m_pszLastFindWhat = _tcsdup (dlg.m_sText); + m_dwLastReplaceFlags = 0; + if (dlg.m_bMatchCase) + m_dwLastReplaceFlags |= FIND_MATCH_CASE; + if (dlg.m_bWholeWord) + m_dwLastReplaceFlags |= FIND_WHOLE_WORD; + if (dlg.m_bRegExp) + m_dwLastReplaceFlags |= FIND_REGEXP; + + // Restore selection + if (m_bSelectionPushed) + { + SetSelection (m_ptSavedSelStart, m_ptSavedSelEnd); + m_bSelectionPushed = FALSE; + } + + // Save search parameters to registry + VERIFY (RegSaveNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("ReplaceFlags"), m_dwLastReplaceFlags)); + // pApp->WriteProfileString (REG_REPLACE_SUBKEY, REG_FIND_WHAT, dlg.m_sText); + // pApp->WriteProfileString (REG_REPLACE_SUBKEY, REG_REPLACE_WITH, dlg.m_sNewText); +} + +BOOL CCrystalEditView:: +ReplaceSelection (LPCTSTR pszNewText, DWORD dwFlags) +{ + if (!pszNewText) + pszNewText = _T (""); + /*ASSERT (pszNewText != NULL); + if (!IsSelection ()) + return FALSE;*/ + + CPoint ptCursorPos; + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_REPLACE, FALSE); + } + else + ptCursorPos = GetCursorPos (); + ASSERT_VALIDTEXTPOS (ptCursorPos); + + int x, y; + if (dwFlags & FIND_REGEXP) + { + LPTSTR lpszNewStr; + if (m_pszMatched && !RxReplace(pszNewText, m_pszMatched, m_nLastFindWhatLen, m_rxmatch, &lpszNewStr, &m_nLastReplaceLen)) + { + CString text; + if (lpszNewStr && m_nLastReplaceLen > 0) + { + LPTSTR buf = text.GetBuffer (m_nLastReplaceLen + 1); + _tcsncpy (buf, lpszNewStr, m_nLastReplaceLen + 1); + buf [m_nLastReplaceLen] = _T('\0'); + text.ReleaseBuffer (); + } + else + text.Empty (); + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, text, y, x, CE_ACTION_REPLACE, FALSE); // [JRT+FRD] + if (lpszNewStr) + free(lpszNewStr); + } + } + else + { + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszNewText, y, x, CE_ACTION_REPLACE, FALSE); // [JRT] + m_nLastReplaceLen = _tcslen (pszNewText); + } + CPoint ptEndOfBlock = CPoint (x, y); + ASSERT_VALIDTEXTPOS (ptCursorPos); + ASSERT_VALIDTEXTPOS (ptEndOfBlock); + SetAnchor (ptEndOfBlock); + SetSelection (ptCursorPos, ptEndOfBlock); + SetCursorPos (ptEndOfBlock); + //EnsureVisible (ptEndOfBlock); + return TRUE; +} + +void CCrystalEditView:: +OnUpdateEditUndo (CCmdUI * pCmdUI) +{ + BOOL bCanUndo = m_pTextBuffer != NULL && m_pTextBuffer->CanUndo (); + pCmdUI->Enable (bCanUndo); + + // Since we need text only for menus... + if (pCmdUI->m_pMenu != NULL) + { + // Tune up 'resource handle' + HINSTANCE hOldResHandle = AfxGetResourceHandle (); + AfxSetResourceHandle (GetResourceHandle ()); + + CString menu; + if (bCanUndo) + { + // Format menu item text using the provided item description + CString desc; + m_pTextBuffer->GetUndoDescription (desc); + menu.Format (IDS_MENU_UNDO_FORMAT, desc); + } + else + { + // Just load default menu item text + menu.LoadString (IDS_MENU_UNDO_DEFAULT); + } + + // Restore original handle + AfxSetResourceHandle (hOldResHandle); + + // Set menu item text + pCmdUI->SetText (menu); + } +} + +void CCrystalEditView:: +OnEditUndo () +{ + if (m_pTextBuffer != NULL && m_pTextBuffer->CanUndo ()) + { + CPoint ptCursorPos; + if (m_pTextBuffer->Undo (ptCursorPos)) + { + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + } + } +} + +// [JRT] +void CCrystalEditView:: +SetDisableBSAtSOL (BOOL bDisableBSAtSOL) +{ + m_bDisableBSAtSOL = bDisableBSAtSOL; +} + +void CCrystalEditView:: +OnEditRedo () +{ + if (m_pTextBuffer != NULL && m_pTextBuffer->CanRedo ()) + { + CPoint ptCursorPos; + if (m_pTextBuffer->Redo (ptCursorPos)) + { + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + } + } +} + +void CCrystalEditView:: +OnUpdateEditRedo (CCmdUI * pCmdUI) +{ + BOOL bCanRedo = m_pTextBuffer != NULL && m_pTextBuffer->CanRedo (); + pCmdUI->Enable (bCanRedo); + + // Since we need text only for menus... + if (pCmdUI->m_pMenu != NULL) + { + // Tune up 'resource handle' + HINSTANCE hOldResHandle = AfxGetResourceHandle (); + AfxSetResourceHandle (GetResourceHandle ()); + + CString menu; + if (bCanRedo) + { + // Format menu item text using the provided item description + CString desc; + m_pTextBuffer->GetRedoDescription (desc); + menu.Format (IDS_MENU_REDO_FORMAT, desc); + } + else + { + // Just load default menu item text + menu.LoadString (IDS_MENU_REDO_DEFAULT); + } + + // Restore original handle + AfxSetResourceHandle (hOldResHandle); + + // Set menu item text + pCmdUI->SetText (menu); + } +} + +bool +isopenbrace (TCHAR c) +{ + return c == _T ('{') || c == _T ('(') || c == _T ('[') || c == _T ('<'); +} + +bool +isclosebrace (TCHAR c) +{ + return c == _T ('}') || c == _T ('}') || c == _T (']') || c == _T ('>'); +} + +bool +isopenbrace (LPCTSTR s) +{ + return s[1] == _T ('\0') && isopenbrace (*s); +} + +bool +isclosebrace (LPCTSTR s) +{ + return s[1] == _T ('\0') && isclosebrace (*s); +} + +int +bracetype (TCHAR c) +{ + static LPCTSTR braces = _T("{}()[]<>"); + LPCTSTR pos = _tcschr (braces, c); + return pos ? pos - braces + 1 : 0; +} + +int +bracetype (LPCTSTR s) +{ + if (s[1]) + return 0; + return bracetype (*s); +} + +void CCrystalEditView:: +OnEditOperation (int nAction, LPCTSTR pszText) +{ + if (m_bAutoIndent) + { + // Analyse last action... + if (nAction == CE_ACTION_TYPING && _tcscmp (pszText, _T ("\r\n")) == 0 && !m_bOvrMode) + { + // Enter stroke! + CPoint ptCursorPos = GetCursorPos (); + ASSERT (ptCursorPos.y > 0); + + // Take indentation from the previos line + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y - 1); + LPCTSTR pszLineChars = m_pTextBuffer->GetLineChars (ptCursorPos.y - 1); + int nPos = 0; + while (nPos < nLength && isspace (pszLineChars[nPos])) + nPos++; + + if (nPos > 0) + { + if ((GetFlags () & SRCOPT_BRACEGNU) && isclosebrace (pszLineChars[nLength - 1]) && ptCursorPos.y > 0 && nPos && nPos == nLength - 1) + { + if (pszLineChars[nPos - 1] == _T ('\t')) + { + nPos--; + } + else + { + int nTabSize = GetTabSize (), + nDelta = nTabSize - nPos % nTabSize; + if (!nDelta) + { + nDelta = nTabSize; + } + nPos -= nDelta; + if (nPos < 0) + { + nPos = 0; + } + } + } + // Insert part of the previos line + TCHAR *pszInsertStr; + if ((GetFlags () & (SRCOPT_BRACEGNU|SRCOPT_BRACEANSI)) && isopenbrace (pszLineChars[nLength - 1])) + { + if (m_bInsertTabs) + { + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * (nPos + 2)); + _tcsncpy (pszInsertStr, pszLineChars, nPos); + pszInsertStr[nPos++] = _T ('\t'); + } + else + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - nPos % nTabSize; + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * (nPos + nChars)); + _tcsncpy (pszInsertStr, pszLineChars, nPos); + while (nChars--) + { + pszInsertStr[nPos++] = _T (' '); + } + } + } + else + { + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * (nPos + 1)); + _tcsncpy (pszInsertStr, pszLineChars, nPos); + } + pszInsertStr[nPos] = 0; + + // m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->InsertText (NULL, ptCursorPos.y, ptCursorPos.x, + pszInsertStr, y, x, CE_ACTION_AUTOINDENT); + CPoint pt (x, y); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + // m_pTextBuffer->FlushUndoGroup (this); + } + else + { + // Insert part of the previos line + TCHAR *pszInsertStr; + if ((GetFlags () & (SRCOPT_BRACEGNU|SRCOPT_BRACEANSI)) && isopenbrace (pszLineChars[nLength - 1])) + { + if (m_bInsertTabs) + { + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * 2); + pszInsertStr[nPos++] = _T ('\t'); + } + else + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - nPos % nTabSize; + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * (nChars + 1)); + while (nChars--) + { + pszInsertStr[nPos++] = _T (' '); + } + } + pszInsertStr[nPos] = 0; + + // m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->InsertText (NULL, ptCursorPos.y, ptCursorPos.x, + pszInsertStr, y, x, CE_ACTION_AUTOINDENT); + CPoint pt (x, y); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + // m_pTextBuffer->FlushUndoGroup (this); + } + } + } + else if (nAction == CE_ACTION_TYPING && (GetFlags () & SRCOPT_FNBRACE) && bracetype (pszText) == 3) + { + // Enter stroke! + CPoint ptCursorPos = GetCursorPos (); + LPCTSTR pszChars = m_pTextBuffer->GetLineChars (ptCursorPos.y); + if (ptCursorPos.x > 1 && xisalnum (pszChars[ptCursorPos.x - 2])) + { + LPTSTR pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * 2); + *pszInsertStr = _T (' '); + pszInsertStr[1] = _T ('\0'); + // m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->InsertText (NULL, ptCursorPos.y, ptCursorPos.x - 1, + pszInsertStr, y, x, CE_ACTION_AUTOINDENT); + ptCursorPos.x = x + 1; + ptCursorPos.y = y; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + // m_pTextBuffer->FlushUndoGroup (this); + } + } + else if (nAction == CE_ACTION_TYPING && (GetFlags () & SRCOPT_BRACEGNU) && isopenbrace (pszText)) + { + // Enter stroke! + CPoint ptCursorPos = GetCursorPos (); + + // Take indentation from the previos line + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszLineChars = m_pTextBuffer->GetLineChars (ptCursorPos.y ); + int nPos = 0; + while (nPos < nLength && isspace (pszLineChars[nPos])) + nPos++; + if (nPos == nLength - 1) + { + TCHAR *pszInsertStr; + if (m_bInsertTabs) + { + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * 2); + *pszInsertStr = _T ('\t'); + nPos = 1; + } + else + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - nPos % nTabSize; + pszInsertStr = (TCHAR *) _alloca (sizeof (TCHAR) * (nChars + 1)); + nPos = 0; + while (nChars--) + { + pszInsertStr[nPos++] = _T (' '); + } + } + pszInsertStr[nPos] = 0; + + // m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->InsertText (NULL, ptCursorPos.y, ptCursorPos.x - 1, + pszInsertStr, y, x, CE_ACTION_AUTOINDENT); + CPoint pt (x + 1, y); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + // m_pTextBuffer->FlushUndoGroup (this); + } + } + else if (nAction == CE_ACTION_TYPING && (GetFlags () & (SRCOPT_BRACEGNU|SRCOPT_BRACEANSI)) && isclosebrace (pszText)) + { + // Enter stroke! + CPoint ptCursorPos = GetCursorPos (); + + // Take indentation from the previos line + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszLineChars = m_pTextBuffer->GetLineChars (ptCursorPos.y ); + int nPos = 0; + while (nPos < nLength && isspace (pszLineChars[nPos])) + nPos++; + if (ptCursorPos.y > 0 && nPos && nPos == nLength - 1) + { + if (pszLineChars[nPos - 1] == _T ('\t')) + { + nPos = 1; + } + else + { + int nTabSize = GetTabSize (); + nPos = nTabSize - (ptCursorPos.x - 1) % nTabSize; + if (!nPos) + { + nPos = nTabSize; + } + if (nPos > nLength - 1) + { + nPos = nLength - 1; + } + } + // m_pTextBuffer->BeginUndoGroup (); + m_pTextBuffer->DeleteText (NULL, ptCursorPos.y, ptCursorPos.x - nPos - 1, + ptCursorPos.y, ptCursorPos.x - 1, CE_ACTION_AUTOINDENT); + ptCursorPos.x -= nPos; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + // m_pTextBuffer->FlushUndoGroup (this); + } + } + } +} + +void CCrystalEditView:: +OnEditAutoComplete () +{ + CPoint ptCursorPos = GetCursorPos (); + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y), pszEnd = pszText + ptCursorPos.x; + if (ptCursorPos.x > 0 && ptCursorPos.y > 0 && (nLength == ptCursorPos.x || !xisalnum (*pszEnd)) && xisalnum (pszEnd[-1])) + { + LPCTSTR pszBegin = pszEnd - 1; + while (pszBegin > pszText && xisalnum (*pszBegin)) + pszBegin--; + if (!xisalnum (*pszBegin)) + pszBegin++; + nLength = pszEnd - pszBegin; + CString sText; + LPTSTR pszBuffer = sText.GetBuffer (nLength + 2); + *pszBuffer = _T('<'); + _tcsncpy (pszBuffer + 1, pszBegin, nLength); + pszBuffer[nLength + 1] = _T('\0'); + sText.ReleaseBuffer (); + CPoint ptTextPos; + ptCursorPos.x -= nLength; + BOOL bFound = FindText (sText, ptCursorPos, FIND_MATCH_CASE|FIND_REGEXP|FIND_DIRECTION_UP, TRUE, &ptTextPos); + if (!bFound) + { + ptCursorPos.x += nLength; + bFound = FindText (sText, ptCursorPos, FIND_MATCH_CASE|FIND_REGEXP, TRUE, &ptTextPos); + ptCursorPos.x -= nLength; + } + if (bFound) + { + int nFound = m_pTextBuffer->GetLineLength (ptTextPos.y); + pszText = m_pTextBuffer->GetLineChars (ptTextPos.y) + ptTextPos.x + m_nLastFindWhatLen; + nFound -= ptTextPos.x + m_nLastFindWhatLen; + pszBuffer = sText.GetBuffer (nFound + 1); + while (nFound-- && xisalnum (*pszText)) + *pszBuffer++ = *pszText++; + *pszBuffer = _T('\0'); + sText.ReleaseBuffer (); + if (!sText.IsEmpty ()) + { + m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x + nLength, sText, y, x, CE_ACTION_AUTOCOMPLETE); + ptCursorPos.x = x; + ptCursorPos.y = y; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + m_pTextBuffer->FlushUndoGroup (this); + } + } + } +} + +void CCrystalEditView:: +OnUpdateEditAutoComplete (CCmdUI * pCmdUI) +{ + CPoint ptCursorPos = GetCursorPos (); + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y) + ptCursorPos.x; + pCmdUI->Enable (ptCursorPos.x > 0 && ptCursorPos.y > 0 && (nLength == ptCursorPos.x || !xisalnum (*pszText)) && xisalnum (pszText[-1])); +} + +void CCrystalEditView:: +OnEditAutoExpand () +{ + CPoint ptCursorPos = GetCursorPos (); + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y), pszEnd = pszText + ptCursorPos.x; + if (ptCursorPos.x > 0 && ptCursorPos.y > 0 && (nLength == ptCursorPos.x || !xisalnum (*pszEnd)) && xisalnum (pszEnd[-1])) + { + LPCTSTR pszBegin = pszEnd - 1; + while (pszBegin > pszText && xisalnum (*pszBegin)) + pszBegin--; + if (!xisalnum (*pszBegin)) + pszBegin++; + nLength = pszEnd - pszBegin; + CString sText, sExpand; + LPTSTR pszBuffer = sText.GetBuffer (nLength + 1); + _tcsncpy (pszBuffer, pszBegin, nLength); + pszBuffer[nLength] = _T('\0'); + sText.ReleaseBuffer (); + CPoint ptTextPos; + ptCursorPos.x -= nLength; + BOOL bFound = m_mapExpand->Lookup (sText, sExpand); + if (bFound && !sExpand.IsEmpty ()) + { + m_pTextBuffer->BeginUndoGroup (); + int x, y; + m_pTextBuffer->DeleteText (this, ptCursorPos.y, ptCursorPos.x, ptCursorPos.y, ptCursorPos.x + nLength, CE_ACTION_AUTOEXPAND); + LPTSTR pszExpand = sExpand.GetBuffer (sExpand.GetLength () + 1); + LPTSTR pszSlash = _tcschr (pszExpand, _T ('\\')); + if (!pszSlash) + { + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszExpand, y, x, CE_ACTION_AUTOEXPAND); + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + } + else + { + *pszSlash++ = _T ('\0'); + for(;;) + { + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszExpand, y, x, CE_ACTION_AUTOEXPAND); + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + OnEditOperation (CE_ACTION_TYPING, pszExpand); + ptCursorPos = GetCursorPos (); + if (!pszSlash) + break; + switch (*pszSlash) + { + case _T ('n'): + { + const static TCHAR szText[3] = _T ("\r\n"); + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, szText, y, x, CE_ACTION_AUTOEXPAND); // [JRT] + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + OnEditOperation (CE_ACTION_TYPING, szText); + } + break; + case _T ('u'): + MoveUp (FALSE); + break; + case _T ('d'): + MoveDown (FALSE); + break; + case _T ('l'): + MoveLeft (FALSE); + break; + case _T ('r'): + MoveRight (FALSE); + break; + case _T ('h'): + MoveHome (FALSE); + break; + case _T ('f'): + MoveEnd (FALSE); + break; + case _T ('b'): + { + CPoint ptSelStart = ptCursorPos; + bool bDeleted = false; + if (!(ptCursorPos.x)) // If At Start Of Line + + { + if (!m_bDisableBSAtSOL) // If DBSASOL Is Disabled + + { + if (ptCursorPos.y > 0) // If Previous Lines Available + + { + ptCursorPos.y--; // Decrement To Previous Line + + ptCursorPos.x = GetLineLength ( + ptCursorPos.y); // Set Cursor To End Of Previous Line + + bDeleted = true; // Set Deleted Flag + + } + } + } + else // If Caret Not At SOL + + { + ptCursorPos.x--; // Decrement Position + + bDeleted = true; // Set Deleted Flag + + } + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + + if (bDeleted) + m_pTextBuffer->DeleteText (this, ptCursorPos.y, ptCursorPos.x, ptSelStart.y, ptSelStart.x, CE_ACTION_AUTOEXPAND); // [JRT] + } + break; + case _T ('e'): + { + CPoint ptSelEnd = ptCursorPos; + if (ptSelEnd.x == GetLineLength (ptSelEnd.y)) + { + if (ptSelEnd.y == GetLineCount () - 1) + break; + ptSelEnd.y++; + ptSelEnd.x = 0; + } + else + ptSelEnd.x++; + m_pTextBuffer->DeleteText (this, ptCursorPos.y, ptCursorPos.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_AUTOEXPAND); // [JRT] + } + break; + case _T ('t'): + { + static TCHAR szText[32]; + if (m_bInsertTabs) + { + *szText = _T ('\t'); + szText[1] = _T ('\0'); + } + else + { + int nTabSize = GetTabSize (); + int nChars = nTabSize - ptCursorPos.x % nTabSize; + memset(szText, _T(' '), nChars); + szText[nChars] = _T ('\0'); + } + m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, szText, y, x, CE_ACTION_AUTOEXPAND); // [JRT] + ptCursorPos.x = x; + ptCursorPos.y = y; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + SetCursorPos (ptCursorPos); + } + } + ptCursorPos = GetCursorPos (); + pszExpand = pszSlash + 1; + pszSlash = _tcschr (pszExpand, _T ('\\')); + if (pszSlash) + *pszSlash++ = _T ('\0'); + } + } + sExpand.ReleaseBuffer (); + EnsureVisible (ptCursorPos); + m_pTextBuffer->FlushUndoGroup (this); + } + } +} + +void CCrystalEditView:: +OnUpdateEditAutoExpand (CCmdUI * pCmdUI) +{ + if (m_mapExpand->IsEmpty ()) + pCmdUI->Enable (FALSE); + else + OnUpdateEditAutoComplete (pCmdUI); +} + +void CCrystalEditView:: +OnUpdateEditLowerCase (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditLowerCase () +{ + if (IsSelection ()) + { + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + text.MakeLower (); + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_LOWERCASE); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, text, y, x, CE_ACTION_LOWERCASE); + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +OnUpdateEditUpperCase (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditUpperCase () +{ + if (IsSelection ()) + { + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + text.MakeUpper (); + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_UPPERCASE); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, text, y, x, CE_ACTION_UPPERCASE); + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +OnUpdateEditSwapCase (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditSwapCase () +{ + if (IsSelection ()) + { + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + int nLen = text.GetLength (); + LPTSTR pszText = text.GetBuffer (nLen + 1); + while (*pszText) + *pszText++ = (TCHAR)(_istlower (*pszText) ? _totupper (*pszText) : _totlower (*pszText)); + text.ReleaseBuffer (); + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_SWAPCASE); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, text, y, x, CE_ACTION_SWAPCASE); + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +OnUpdateEditCapitalize (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditCapitalize () +{ + if (IsSelection ()) + { + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + int nLen = text.GetLength (); + LPTSTR pszText = text.GetBuffer (nLen + 1); + bool bCapitalize = true; + while (*pszText) + { + if (_istspace (*pszText)) + bCapitalize = true; + else if (_istalpha (*pszText)) + if (bCapitalize) + { + *pszText = (TCHAR)_totupper (*pszText); + bCapitalize = false; + } + else + *pszText = (TCHAR)_totlower (*pszText); + pszText++; + } + text.ReleaseBuffer (); + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_CAPITALIZE); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, text, y, x, CE_ACTION_CAPITALIZE); + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +OnUpdateEditSentence (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +void CCrystalEditView:: +OnEditSentence () +{ + if (IsSelection ()) + { + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString text; + GetText (ptSelStart, ptSelEnd, text); + int nLen = text.GetLength (); + LPTSTR pszText = text.GetBuffer (nLen + 1); + bool bCapitalize = true; + while (*pszText) + { + if (!_istspace (*pszText)) + if (*pszText == _T ('.')) + { + if (pszText[1] && !_istdigit (pszText[1])) + bCapitalize = true; + } + else if (_istalpha (*pszText)) + if (bCapitalize) + { + *pszText = (TCHAR)_totupper (*pszText); + bCapitalize = false; + } + else + *pszText = (TCHAR)_totlower (*pszText); + pszText++; + } + text.ReleaseBuffer (); + + m_pTextBuffer->BeginUndoGroup (); + + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + ptCursorPos = ptSelStart; + /*SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos);*/ + + // [JRT]: + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_SENTENCIZE); + } + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, text, y, x, CE_ACTION_SENTENCIZE); + + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +//BEGIN SW +void CCrystalEditView::OnUpdateEditGotoLastChange( CCmdUI *pCmdUI ) +{ + CPoint ptLastChange = m_pTextBuffer->GetLastChangePos(); + pCmdUI->Enable( ptLastChange.x > 0 && ptLastChange.y > -1 ); +} + +void CCrystalEditView::OnEditGotoLastChange() +{ + CPoint ptLastChange = m_pTextBuffer->GetLastChangePos(); + if( ptLastChange.x < 0 || ptLastChange.y < 0 ) + return; + + // goto last change + SetCursorPos( ptLastChange ); + SetSelection( ptLastChange, ptLastChange ); + EnsureVisible( ptLastChange ); +} +//END SW + +int CCrystalEditView::SpellGetLine (struct SpellData_t *pdata) +{ + int nCount; + CCrystalEditView *pView = (CCrystalEditView*) pdata->pUserData; + static TCHAR szBuffer[4096]; + + if (pdata->nRow < pView->GetLineCount ()) + { + nCount = pView->GetLineLength (pdata->nRow) + 1; + /*if (pdata->pszBuffer) + free (pdata->pszBuffer); + pdata->pszBuffer = (LPTSTR) malloc (nCount + 2);*/ + pdata->pszBuffer = szBuffer; + *pdata->pszBuffer = _T ('^'); + if (nCount > 1) + _tcscpy (pdata->pszBuffer + 1, pView->GetLineChars (pdata->nRow)); + else + pdata->pszBuffer[nCount++] = _T (' '); + pdata->pszBuffer[nCount++] = _T ('\n'); + pdata->pszBuffer[nCount] = _T ('\0'); + pdata->nRow++; + return nCount; + } + pdata->pszBuffer = szBuffer; + *pdata->pszBuffer = _T ('\0'); + return 0; +} + +int CCrystalEditView::SpellNotify (int nEvent, struct SpellData_t *pdata) +{ + CCrystalEditView *pView = (CCrystalEditView*) pdata->pUserData; + CPoint ptStartPos, ptEndPos; + int x, y; + + switch (nEvent) + { + case SN_FOUND: + ptStartPos.x = pdata->nColumn - 1; + ptStartPos.y = pdata->nRow - 1; + ptEndPos.x = pdata->nColumn - 1 + _tcslen (pdata->pszWord); + ptEndPos.y = pdata->nRow - 1; + if (!pView->IsValidTextPos (ptStartPos)) + if (ptStartPos.x > 0) + ptStartPos.x--; + else + ptStartPos.x = 0; + if (!pView->IsValidTextPos (ptEndPos)) + if (ptEndPos.x > 0) + ptEndPos.x--; + else + ptEndPos.x = 0; + pView->SetAnchor (ptStartPos); + pView->SetSelection (ptStartPos, ptEndPos); + pView->SetCursorPos (ptStartPos); + pView->EnsureVisible (ptStartPos); + break; + case SN_REPLACED: + if (pView->IsSelection ()) + { + pView->GetSelection (ptStartPos, ptEndPos); + pView->m_pTextBuffer->DeleteText (pView, ptStartPos.y, ptStartPos.x, ptEndPos.y, ptEndPos.x, CE_ACTION_SPELL); + pView->m_pTextBuffer->InsertText (pView, ptStartPos.y, ptStartPos.x, pdata->pszWord, y, x, CE_ACTION_SPELL); + ptEndPos.x = x; + ptEndPos.y = y; + pView->SetAnchor (ptEndPos); + pView->SetSelection (ptEndPos, ptEndPos); + pView->SetCursorPos (ptEndPos); + } + break; + case SN_FINISHED: + ptStartPos = pView->GetCursorPos (); + pView->SetAnchor (ptStartPos); + pView->SetSelection (ptStartPos, ptStartPos); + pView->SetCursorPos (ptStartPos); + pView->EnsureVisible (ptStartPos); + ::MessageBox (pdata->hParent, _T ("Spellchecking finished."), _T ("WIspell"), MB_OK|MB_ICONINFORMATION); + } + return 0; +} + +HMODULE CCrystalEditView::hSpellDll = NULL; +TCHAR CCrystalEditView::szWIspellPath[_MAX_PATH]; +SpellData CCrystalEditView::spellData; +int (*CCrystalEditView::SpellInit) (SpellData*); +int (*CCrystalEditView::SpellCheck) (SpellData*); +int (*CCrystalEditView::SpellConfig) (SpellData*); + +BOOL CCrystalEditView::LoadSpellDll (BOOL bAlert /*= TRUE*/) +{ + if (hSpellDll) + return TRUE; + CString sPath = szWIspellPath; + if (!sPath.IsEmpty () && sPath[sPath.GetLength () - 1] != _T('\\')) + sPath += _T ('\\'); + sPath += _T ("wispell.dll"); + hSpellDll = LoadLibrary (sPath); + if (hSpellDll) + { + SpellInit = (int (*) (SpellData*)) GetProcAddress (hSpellDll, "SpellInit"); + SpellCheck = (int (*) (SpellData*)) GetProcAddress (hSpellDll, "SpellCheck"); + SpellConfig = (int (*) (SpellData*)) GetProcAddress (hSpellDll, "SpellConfig"); + if (SpellInit) + SpellInit (&spellData); + _tcscpy (spellData.szIspell, szWIspellPath); + spellData.GetLine = SpellGetLine; + spellData.Notify = SpellNotify; + } + else + { + SpellInit = SpellCheck = SpellConfig = NULL; + if (bAlert) + ::MessageBox (AfxGetMainWnd ()->GetSafeHwnd (), _T ("Error loading \"wispell.dll\"."), _T ("Error"), MB_OK|MB_ICONEXCLAMATION); + } + return hSpellDll != NULL; +} + +void CCrystalEditView:: +OnUpdateToolsSpelling (CCmdUI * pCmdUI) +{ + CPoint ptCursorPos = GetCursorPos (); + int nLines = GetLineCount () - 1; + pCmdUI->Enable (LoadSpellDll (FALSE) && ptCursorPos.y < nLines); +} + +void CCrystalEditView:: +OnToolsSpelling () +{ + CPoint ptCursorPos = GetCursorPos (); + if (LoadSpellDll () && ptCursorPos.y < GetLineCount ()) + { + spellData.hParent = GetSafeHwnd (); + spellData.nRow = ptCursorPos.y; + spellData.pUserData = (LPVOID) (LPCVOID) this; + spellData.pszBuffer = NULL; + m_pTextBuffer->BeginUndoGroup (); + if (SpellCheck (&spellData) == IDCANCEL) + { + m_pTextBuffer->FlushUndoGroup (this); + OnEditUndo (); + } + else + m_pTextBuffer->FlushUndoGroup (this); + /*if (spellData.pszBuffer) + free (spellData.pszBuffer);*/ + } +} + +void CCrystalEditView:: +OnUpdateToolsCharCoding (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (IsSelection ()); +} + +long str_pos (LPCTSTR whole, LPCTSTR piece); + +void CCrystalEditView:: +OnToolsCharCoding () +{ + if (IsSelection ()) + { + CWaitCursor wait; + CPoint ptCursorPos = GetCursorPos (); + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + CString sText; + GetText (ptSelStart, ptSelEnd, sText); + CCharConvDlg dlg; + dlg.m_sOriginal = sText; + LPTSTR pszEnd = dlg.m_sOriginal.GetBuffer (dlg.m_sOriginal.GetLength () + 1); + for (int i = 0; i < 13; i++) + { + pszEnd = _tcschr (pszEnd, _T ('\n')); + if (pszEnd) + pszEnd++; + else + break; + } + if (pszEnd) + *pszEnd = _T ('\0'); + dlg.m_sOriginal.ReleaseBuffer (); + if (dlg.DoModal () != IDOK) + return; + LPTSTR pszNew; + if (!iconvert_new (sText, &pszNew, dlg.m_nSource, dlg.m_nDest, dlg.m_bAlpha != FALSE)) + { + ASSERT (pszNew); + m_pTextBuffer->BeginUndoGroup (); + + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_RECODE); + + int x, y; + m_pTextBuffer->InsertText (this, ptSelStart.y, ptSelStart.x, pszNew, y, x, CE_ACTION_RECODE); + + if (IsValidTextPos (ptCursorPos)) + ptCursorPos.x = 0; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptSelStart, ptSelEnd); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + + m_pTextBuffer->FlushUndoGroup (this); + } + if (pszNew) + free (pszNew); + } +} + +void CCrystalEditView:: +OnEditDeleteWord () +{ + if (!IsSelection ()) + MoveWordRight (TRUE); + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + m_pTextBuffer->BeginUndoGroup (); + + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); + + ASSERT_VALIDTEXTPOS (ptSelStart); + SetAnchor (ptSelStart); + SetSelection (ptSelStart, ptSelStart); + SetCursorPos (ptSelStart); + EnsureVisible (ptSelStart); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +void CCrystalEditView:: +OnEditDeleteWordBack () +{ + if (!IsSelection ()) + MoveWordLeft (TRUE); + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + + m_pTextBuffer->BeginUndoGroup (); + + m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); + + ASSERT_VALIDTEXTPOS (ptSelStart); + SetAnchor (ptSelStart); + SetSelection (ptSelStart, ptSelStart); + SetCursorPos (ptSelStart); + EnsureVisible (ptSelStart); + + m_pTextBuffer->FlushUndoGroup (this); + } +} + +//////////////////////////////////////////////////////////////////////////// +#pragma warning ( default : 4100 ) diff --git a/Src/editlib/ccrystaleditview.h b/Src/editlib/ccrystaleditview.h new file mode 100644 index 000000000..5a89333a8 --- /dev/null +++ b/Src/editlib/ccrystaleditview.h @@ -0,0 +1,194 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaleditview.h +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Interface of the CCrystalEditView class, a part of Crystal Edit - syntax +// coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CCRYSTALEDITVIEW_H__8F3F8B63_6F66_11D2_8C34_0080ADB86836__INCLUDED_) +#define AFX_CCRYSTALEDITVIEW_H__8F3F8B63_6F66_11D2_8C34_0080ADB86836__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "ccrystaltextview.h" +#include "wispelld.h" + +///////////////////////////////////////////////////////////////////////////// +// Forward class declarations + +class CEditDropTargetImpl; + +///////////////////////////////////////////////////////////////////////////// +// CCrystalEditView view + +class EDITPADC_CLASS CCrystalEditView : public CCrystalTextView + { + DECLARE_DYNCREATE (CCrystalEditView) + +public : + int m_nLastReplaceLen; + CMap *m_mapExpand; + + static HMODULE hSpellDll; + static TCHAR szWIspellPath[_MAX_PATH]; + static SpellData spellData; + static int (*SpellInit) (SpellData*); + static int (*SpellCheck) (SpellData*); + static int (*SpellConfig) (SpellData*); + static BOOL LoadSpellDll (BOOL bAlert = TRUE); + static int SpellGetLine (struct SpellData_t *pdata); + static int SpellNotify (int nEvent, struct SpellData_t *pdata); + +protected: + BOOL m_bLastReplace; + DWORD m_dwLastReplaceFlags; + +private : + BOOL m_bOvrMode; + BOOL m_bDropPosVisible; + CPoint m_ptSavedCaretPos; + CPoint m_ptDropPos; + BOOL m_bSelectionPushed; + CPoint m_ptSavedSelStart, m_ptSavedSelEnd; + BOOL m_bAutoIndent; + BOOL m_bInsertTabs; + + // [JRT] + BOOL m_bDisableBSAtSOL; // Disable BS At Start Of Line + + +public : + virtual void ResetView (); +protected : + CEditDropTargetImpl * m_pDropTarget; + virtual DROPEFFECT GetDropEffect (); + virtual void OnDropSource (DROPEFFECT de); + void Paste (); + void Cut (); + BOOL DeleteCurrentSelection (); + + // Attributes +public : + BOOL GetAutoIndent () const; + void SetAutoIndent (BOOL bAutoIndent); + BOOL GetInsertTabs () const; + void SetInsertTabs (BOOL bInsertTabs); + + // [JRT] + void SetDisableBSAtSOL (BOOL bDisableBSAtSOL); + BOOL GetDisableBSAtSOL () const; + + // Operations +public : + CCrystalEditView (); + ~CCrystalEditView (); + + BOOL GetOverwriteMode () const; + void SetOverwriteMode (BOOL bOvrMode = TRUE); + + void ShowDropIndicator (const CPoint & point); + void HideDropIndicator (); + + BOOL DoDropText (COleDataObject * pDataObject, const CPoint & ptClient); + void DoDragScroll (const CPoint & point); + + virtual BOOL QueryEditable (); + virtual void UpdateView (CCrystalTextView * pSource, CUpdateContext * pContext, DWORD dwFlags, int nLineIndex = -1); + + BOOL ReplaceSelection (LPCTSTR pszNewText, DWORD dwFlags); + + virtual void OnEditOperation (int nAction, LPCTSTR pszText); + + virtual bool DoSetTextType (TextDefinition *def); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCrystalEditView) + //}}AFX_VIRTUAL + + // Implementation +protected : + + // Generated message map functions +protected : + //{{AFX_MSG(CCrystalEditView) + afx_msg void OnEditPaste (); + afx_msg void OnUpdateEditCut (CCmdUI * pCmdUI); + afx_msg void OnEditCut (); + afx_msg void OnUpdateEditPaste (CCmdUI * pCmdUI); + afx_msg void OnEditDelete (); + afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnEditDeleteBack (); + afx_msg void OnEditUntab (); + afx_msg void OnEditTab (); + afx_msg void OnEditSwitchOvrmode (); + afx_msg void OnUpdateEditSwitchOvrmode (CCmdUI * pCmdUI); + afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy (); + afx_msg void OnEditReplace (); + afx_msg void OnUpdateEditUndo (CCmdUI * pCmdUI); + afx_msg void OnEditUndo (); + afx_msg void OnUpdateEditRedo (CCmdUI * pCmdUI); + afx_msg void OnEditRedo (); + afx_msg void OnUpdateEditAutoComplete (CCmdUI * pCmdUI); + afx_msg void OnEditAutoComplete (); + afx_msg void OnUpdateEditAutoExpand (CCmdUI * pCmdUI); + afx_msg void OnEditAutoExpand (); + afx_msg void OnUpdateEditLowerCase (CCmdUI * pCmdUI); + afx_msg void OnEditLowerCase (); + afx_msg void OnUpdateEditUpperCase (CCmdUI * pCmdUI); + afx_msg void OnEditUpperCase (); + afx_msg void OnUpdateEditSwapCase (CCmdUI * pCmdUI); + afx_msg void OnEditSwapCase (); + afx_msg void OnUpdateEditCapitalize (CCmdUI * pCmdUI); + afx_msg void OnEditCapitalize (); + afx_msg void OnUpdateEditSentence (CCmdUI * pCmdUI); + afx_msg void OnEditSentence (); + //}}AFX_MSG + afx_msg void OnUpdateIndicatorCol (CCmdUI * pCmdUI); + afx_msg void OnUpdateIndicatorOvr (CCmdUI * pCmdUI); + afx_msg void OnUpdateIndicatorRead (CCmdUI * pCmdUI); + //BEGIN SW + afx_msg void OnUpdateEditGotoLastChange(CCmdUI* pCmdUI); + afx_msg void OnEditGotoLastChange(); + //END SW + afx_msg void OnUpdateToolsSpelling (CCmdUI * pCmdUI); + afx_msg void OnToolsSpelling (); + afx_msg void OnUpdateToolsCharCoding (CCmdUI * pCmdUI); + afx_msg void OnToolsCharCoding (); + afx_msg void OnEditDeleteWord (); + afx_msg void OnEditDeleteWordBack (); + DECLARE_MESSAGE_MAP () + }; + +///////////////////////////////////////////////////////////////////////////// + +#if ! (defined(CE_FROM_DLL) || defined(CE_DLL_BUILD)) +#include "ccrystaleditview.inl" +#endif + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CCRYSTALEDITVIEW_H__8F3F8B63_6F66_11D2_8C34_0080ADB86836__INCLUDED_) diff --git a/Src/editlib/ccrystaleditview.inl b/Src/editlib/ccrystaleditview.inl new file mode 100644 index 000000000..f4528f265 --- /dev/null +++ b/Src/editlib/ccrystaleditview.inl @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CCrystalEditView.inl +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Inline functions of Crystal Edit classes +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#ifndef __CCrystalEditView_INL_INCLUDED +#define __CCrystalEditView_INL_INCLUDED + +#include "CCrystalEditView.h" + +inline BOOL CCrystalEditView:: +GetOverwriteMode () +const +{ + return m_bOvrMode; +} + +inline void CCrystalEditView::SetOverwriteMode (BOOL bOvrMode /*= TRUE*/ ) +{ + m_bOvrMode = bOvrMode; +} + +inline BOOL CCrystalEditView:: +GetDisableBSAtSOL () +const +{ + return m_bDisableBSAtSOL; +} + +inline BOOL CCrystalEditView::GetAutoIndent () +const +{ + return m_bAutoIndent; +} + +inline void CCrystalEditView::SetAutoIndent (BOOL bAutoIndent) +{ + m_bAutoIndent = bAutoIndent; +} + +inline BOOL CCrystalEditView::GetInsertTabs () +const +{ + return m_bInsertTabs; +} + +inline void CCrystalEditView::SetInsertTabs (BOOL bInsertTabs) +{ + m_bInsertTabs = bInsertTabs; +} + +#endif diff --git a/Src/editlib/ccrystaltextbuffer.cpp b/Src/editlib/ccrystaltextbuffer.cpp new file mode 100644 index 000000000..bd1e984c6 --- /dev/null +++ b/Src/editlib/ccrystaltextbuffer.cpp @@ -0,0 +1,1498 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaltextbuffer.cpp +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalTextBuffer class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 17-Feb-99 +// + FIX: unnecessary 'HANDLE' in CCrystalTextBuffer::SaveToFile +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 21-Feb-99 +// Paul Selormey, James R. Twine: +// + FEATURE: description for Undo/Redo actions +// + FEATURE: multiple MSVC-like bookmarks +// + FEATURE: 'Disable backspace at beginning of line' option +// + FEATURE: 'Disable drag-n-drop editing' option +// +// + FEATURE: changed layout of SUndoRecord. Now takes less memory +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: some other things I've forgotten ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// ??-Aug-99 +// Sven Wiegand (search for "//BEGIN SW" to find my changes): +// + FEATURE: Remembering the text-position of the latest change. +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 24-Oct-99 +// Sven Wiegand +// + FIX: Setting m_ptLastChange to the beginning of the selection in +// InternalDeleteText(), so that position is valid in any case. +// Editor won't crash any more i.e. by selecting whole buffer and +// deleting it and then executing ID_EDIT_GOTO_LAST_CHANGE-command. +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "editcmd.h" +#include "ccrystaltextbuffer.h" +#include "ccrystaltextview.h" +#include "filesup.h" +#include "cs2cs.h" +#include + +#ifndef __AFXPRIV_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// Line allocation granularity +#define CHAR_ALIGN 16 +#define ALIGN_BUF_SIZE(size) ((size) / CHAR_ALIGN) * CHAR_ALIGN + CHAR_ALIGN; + +#define UNDO_BUF_SIZE 1024 + +const TCHAR crlf[] = _T ("\r\n"); + +#ifdef _DEBUG +#define _ADVANCED_BUGCHECK 1 +#endif + +int CCrystalTextBuffer::m_nDefaultEncoding = -1; + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextBuffer::SUndoRecord + +void CCrystalTextBuffer::SUndoRecord:: +SetText (LPCTSTR pszText) +{ + m_pszText = NULL; + if (pszText != NULL && pszText[0] != _T ('\0')) + { + int nLength = _tcslen (pszText); + if (nLength > 1) + { + m_pszText = new TCHAR[(nLength + 1) * sizeof (TCHAR)]; + _tcscpy (m_pszText, pszText); + } + else + { + m_szText[0] = pszText[0]; + } + } +} + +void CCrystalTextBuffer::SUndoRecord:: +FreeText () +{ + if (HIWORD ((DWORD) m_pszText) != 0) + delete m_pszText; +} + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextBuffer::CUpdateContext + +void CCrystalTextBuffer::CInsertContext:: +RecalcPoint (CPoint & ptPoint) +{ + ASSERT (m_ptEnd.y > m_ptStart.y || + m_ptEnd.y == m_ptStart.y && m_ptEnd.x >= m_ptStart.x); + if (ptPoint.y < m_ptStart.y) + return; + if (ptPoint.y > m_ptStart.y) + { + ptPoint.y += (m_ptEnd.y - m_ptStart.y); + return; + } + if (ptPoint.x <= m_ptStart.x) + return; + ptPoint.y += (m_ptEnd.y - m_ptStart.y); + ptPoint.x = m_ptEnd.x + (ptPoint.x - m_ptStart.x); +} + +void CCrystalTextBuffer::CDeleteContext:: +RecalcPoint (CPoint & ptPoint) +{ + ASSERT (m_ptEnd.y > m_ptStart.y || + m_ptEnd.y == m_ptStart.y && m_ptEnd.x >= m_ptStart.x); + if (ptPoint.y < m_ptStart.y) + return; + if (ptPoint.y > m_ptEnd.y) + { + ptPoint.y -= (m_ptEnd.y - m_ptStart.y); + return; + } + if (ptPoint.y == m_ptEnd.y && ptPoint.x >= m_ptEnd.x) + { + ptPoint.y = m_ptStart.y; + ptPoint.x = m_ptStart.x + (ptPoint.x - m_ptEnd.x); + return; + } + if (ptPoint.y == m_ptStart.y) + { + if (ptPoint.x > m_ptStart.x) + ptPoint.x = m_ptStart.x; + return; + } + ptPoint = m_ptStart; +} + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextBuffer + +IMPLEMENT_DYNCREATE (CCrystalTextBuffer, CCmdTarget) + +CCrystalTextBuffer::CCrystalTextBuffer () +{ + m_bInit = FALSE; + m_bReadOnly = FALSE; + m_bModified = FALSE; + m_bCreateBackupFile = FALSE; + m_nUndoPosition = 0; + //BEGIN SW + m_ptLastChange.x = m_ptLastChange.y = -1; + //END SW + m_nSourceEncoding = m_nDefaultEncoding; +} + +CCrystalTextBuffer:: ~ CCrystalTextBuffer () +{ + ASSERT (!m_bInit); // You must call FreeAll() before deleting the object +} + + +BEGIN_MESSAGE_MAP (CCrystalTextBuffer, CCmdTarget) +//{{AFX_MSG_MAP(CCrystalTextBuffer) +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextBuffer message handlers + +void CCrystalTextBuffer::InsertLine (LPCTSTR pszLine, int nLength /*= -1*/ , int nPosition /*= -1*/ ) +{ + if (nLength == -1) + { + if (pszLine == NULL) + nLength = 0; + else + nLength = _tcslen (pszLine); + } + + SLineInfo li; + li.m_nLength = nLength; + li.m_nMax = ALIGN_BUF_SIZE (li.m_nLength); + ASSERT (li.m_nMax >= li.m_nLength); + if (li.m_nMax > 0) + li.m_pcLine = new TCHAR[li.m_nMax]; + if (li.m_nLength > 0) + memcpy (li.m_pcLine, pszLine, sizeof (TCHAR) * li.m_nLength); + + if (nPosition == -1) + m_aLines.Add (li); + else + m_aLines.InsertAt (nPosition, li); + +#ifdef _DEBUG + int nLines = m_aLines.GetSize (); + if (nLines % 5000 == 0) + TRACE1 ("%d lines loaded!\n", nLines); +#endif +} + +void CCrystalTextBuffer:: +AppendLine (int nLineIndex, LPCTSTR pszChars, int nLength /*= -1*/ ) +{ + if (nLength == -1) + { + if (pszChars == NULL) + return; + nLength = _tcslen (pszChars); + } + + if (nLength == 0) + return; + + register SLineInfo & li = m_aLines[nLineIndex]; + int nBufNeeded = li.m_nLength + nLength; + if (nBufNeeded > li.m_nMax) + { + li.m_nMax = ALIGN_BUF_SIZE (nBufNeeded); + ASSERT (li.m_nMax >= li.m_nLength + nLength); + TCHAR *pcNewBuf = new TCHAR[li.m_nMax]; + if (li.m_nLength > 0) + memcpy (pcNewBuf, li.m_pcLine, sizeof (TCHAR) * li.m_nLength); + delete li.m_pcLine; + li.m_pcLine = pcNewBuf; + } + memcpy (li.m_pcLine + li.m_nLength, pszChars, sizeof (TCHAR) * nLength); + li.m_nLength += nLength; + ASSERT (li.m_nLength <= li.m_nMax); +} + +void CCrystalTextBuffer:: +FreeAll () +{ + // Free text + int nCount = m_aLines.GetSize (); + for (int I = 0; I < nCount; I++) + { + if (m_aLines[I].m_nMax > 0) + delete m_aLines[I].m_pcLine; + } + m_aLines.RemoveAll (); + + // Free undo buffer + int nBufSize = m_aUndoBuf.GetSize (); + for (I = 0; I < nBufSize; I++) + m_aUndoBuf[I].FreeText (); + m_aUndoBuf.RemoveAll (); + + m_bInit = FALSE; + //BEGIN SW + m_ptLastChange.x = m_ptLastChange.y = -1; + //END SW +} + +BOOL CCrystalTextBuffer:: +InitNew (int nCrlfStyle /*= CRLF_STYLE_DOS*/ ) +{ + ASSERT (!m_bInit); + ASSERT (m_aLines.GetSize () == 0); + ASSERT (nCrlfStyle >= 0 && nCrlfStyle <= 2); + InsertLine (_T ("")); + m_bInit = TRUE; + m_bReadOnly = FALSE; + m_nCRLFMode = nCrlfStyle; + m_bModified = FALSE; + m_nSyncPosition = m_nUndoPosition = 0; + m_bUndoGroup = m_bUndoBeginGroup = FALSE; + m_nUndoBufSize = UNDO_BUF_SIZE; + ASSERT (m_aUndoBuf.GetSize () == 0); + UpdateViews (NULL, NULL, UPDATE_RESET); + //BEGIN SW + m_ptLastChange.x = m_ptLastChange.y = -1; + //END SW + return TRUE; +} + +BOOL CCrystalTextBuffer:: +GetReadOnly () +const +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + return m_bReadOnly; +} + +void CCrystalTextBuffer::SetReadOnly (BOOL bReadOnly /*= TRUE*/ ) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + m_bReadOnly = bReadOnly; +} + +static LPCTSTR crlfs[] = + { + _T ("\x0d\x0a"), // DOS/Windows style + _T ("\x0a"), // UNIX style + _T ("\x0a") // Macintosh style + }; + +BOOL CCrystalTextBuffer:: +LoadFromFile (LPCTSTR pszFileName, int nCrlfStyle /*= CRLF_STYLE_AUTOMATIC*/ ) +{ + ASSERT (!m_bInit); + ASSERT (m_aLines.GetSize () == 0); + + HANDLE hFile = NULL; + int nCurrentMax = 256; + LPTSTR pcLineBuf = new TCHAR[nCurrentMax]; + + BOOL bSuccess = FALSE; + + int nExt = GetExtPosition (pszFileName); + if (pszFileName[nExt] == _T ('.')) + nExt++; + CCrystalTextView::TextDefinition *def = CCrystalTextView::GetTextType (pszFileName + nExt); + if (def && def->encoding != -1) + m_nSourceEncoding = def->encoding; + + __try + { + DWORD dwFileAttributes =::GetFileAttributes (pszFileName); + if (dwFileAttributes == (DWORD) - 1) + __leave; + + hFile =::CreateFile (pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (hFile == INVALID_HANDLE_VALUE) + __leave; + + int nCurrentLength = 0; + + const DWORD dwBufSize = 32768; + LPTSTR pcBuf = (LPTSTR) _alloca (dwBufSize); + DWORD dwCurSize; + if (!::ReadFile (hFile, pcBuf, dwBufSize, &dwCurSize, NULL)) + __leave; + + if (nCrlfStyle == CRLF_STYLE_AUTOMATIC) + { + // Try to determine current CRLF mode + for (DWORD I = 0; I < dwCurSize; I++) + { + if ((pcBuf[I] == _T('\x0d')) || (pcBuf[I] == _T('\x0a'))) + break; + } + if (I == dwCurSize) + { + // By default (or in the case of empty file), set DOS style + nCrlfStyle = CRLF_STYLE_DOS; + } + else + { + // Otherwise, analyse the first occurance of line-feed character + if (pcBuf[I] == _T('\x0a')) + { + nCrlfStyle = CRLF_STYLE_UNIX; + } + else + { + if (I < dwCurSize - 1 && pcBuf[I + 1] == _T ('\x0a')) + nCrlfStyle = CRLF_STYLE_DOS; + else + nCrlfStyle = CRLF_STYLE_MAC; + } + } + } + + ASSERT (nCrlfStyle >= 0 && nCrlfStyle <= 2); + m_nCRLFMode = nCrlfStyle; + LPCTSTR crlf = crlfs[nCrlfStyle]; + + m_aLines.SetSize (0, 4096); + + DWORD dwBufPtr = 0; + int nCrlfPtr = 0; + while (dwBufPtr < dwCurSize) + { + int c = pcBuf[dwBufPtr]; + dwBufPtr++; + if (dwBufPtr == dwCurSize && dwCurSize == dwBufSize) + { + if (!::ReadFile (hFile, pcBuf, dwBufSize, &dwCurSize, NULL)) + __leave; + dwBufPtr = 0; + } + + pcLineBuf[nCurrentLength] = (TCHAR) c; + nCurrentLength++; + if (nCurrentLength == nCurrentMax) + { + // Reallocate line buffer + nCurrentMax += 256; + LPTSTR pcNewBuf = new TCHAR[nCurrentMax]; + memcpy (pcNewBuf, pcLineBuf, nCurrentLength); + delete pcLineBuf; + pcLineBuf = pcNewBuf; + } + + if ((TCHAR) c == crlf[nCrlfPtr]) + { + nCrlfPtr++; + if (crlf[nCrlfPtr] == 0) + { + pcLineBuf[nCurrentLength - nCrlfPtr] = 0; + if (m_nSourceEncoding >= 0) + iconvert (pcLineBuf, m_nSourceEncoding, 1, m_nSourceEncoding == 15); + InsertLine (pcLineBuf); + nCurrentLength = 0; + nCrlfPtr = 0; + } + } + else + nCrlfPtr = 0; + } + + pcLineBuf[nCurrentLength] = 0; + InsertLine (pcLineBuf); + + ASSERT (m_aLines.GetSize () > 0); // At least one empty line must present + + m_bInit = TRUE; + m_bReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0; + m_bModified = FALSE; + m_bUndoGroup = m_bUndoBeginGroup = FALSE; + m_nUndoBufSize = UNDO_BUF_SIZE; + m_nSyncPosition = m_nUndoPosition = 0; + ASSERT (m_aUndoBuf.GetSize () == 0); + bSuccess = TRUE; + + RetypeViews (pszFileName); + UpdateViews (NULL, NULL, UPDATE_RESET); + } + __finally + { + if (pcLineBuf != NULL) + delete pcLineBuf; + } + if (hFile != NULL && hFile != INVALID_HANDLE_VALUE) + ::CloseHandle (hFile); + //BEGIN SW + m_ptLastChange.x = m_ptLastChange.y = -1; + //END SW + return bSuccess; +} + +BOOL CCrystalTextBuffer:: +SaveToFile (LPCTSTR pszFileName, int nCrlfStyle /*= CRLF_STYLE_AUTOMATIC*/ , BOOL bClearModifiedFlag /*= TRUE*/ ) +{ + ASSERT (nCrlfStyle == CRLF_STYLE_AUTOMATIC || nCrlfStyle == CRLF_STYLE_DOS || + nCrlfStyle == CRLF_STYLE_UNIX || nCrlfStyle == CRLF_STYLE_MAC); + ASSERT (m_bInit); + HANDLE hTempFile = INVALID_HANDLE_VALUE; + HANDLE hSearch = INVALID_HANDLE_VALUE; + TCHAR szTempFileDir[_MAX_PATH + 1]; + TCHAR szTempFileName[_MAX_PATH + 1]; + TCHAR szBackupFileName[_MAX_PATH + 1]; + BOOL bSuccess = FALSE; + __try + { + TCHAR drive[_MAX_PATH], dir[_MAX_PATH], name[_MAX_PATH], ext[_MAX_PATH]; +#ifdef _UNICODE + _wsplitpath (pszFileName, drive, dir, name, ext); +#else + _splitpath (pszFileName, drive, dir, name, ext); +#endif + _tcscpy (szTempFileDir, drive); + _tcscat (szTempFileDir, dir); + _tcscpy (szBackupFileName, pszFileName); + _tcscat (szBackupFileName, _T (".bak")); + + if (::GetTempFileName (szTempFileDir, _T ("CRE"), 0, szTempFileName) == 0) + __leave; + + hTempFile =::CreateFile (szTempFileName, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hTempFile == INVALID_HANDLE_VALUE) + __leave; + + if (nCrlfStyle == CRLF_STYLE_AUTOMATIC) + nCrlfStyle = m_nCRLFMode; + + ASSERT (nCrlfStyle >= 0 && nCrlfStyle <= 2); + LPCTSTR pszCRLF = crlfs[nCrlfStyle]; + int nCRLFLength = _tcslen (pszCRLF); + + int nLineCount = m_aLines.GetSize (); + for (int nLine = 0; nLine < nLineCount; nLine++) + { + int nLength = m_aLines[nLine].m_nLength; + DWORD dwWrittenBytes; + if (nLength > 0) + { + LPCTSTR pszLine = m_aLines[nLine].m_pcLine; + if (m_nSourceEncoding >= 0) + { + LPTSTR pszBuf; + iconvert_new (m_aLines[nLine].m_pcLine, &pszBuf, 1, m_nSourceEncoding, m_nSourceEncoding == 15); + if (!::WriteFile (hTempFile, pszBuf, nLength, &dwWrittenBytes, NULL)) + { + free (pszBuf); + __leave; + } + free (pszBuf); + } + else + if (!::WriteFile (hTempFile, pszLine, nLength, &dwWrittenBytes, NULL)) + __leave; + if (nLength != (int) dwWrittenBytes) + __leave; + } + if (nLine < nLineCount - 1) // Last line must not end with CRLF + + { + if (!::WriteFile (hTempFile, pszCRLF, nCRLFLength, &dwWrittenBytes, NULL)) + __leave; + if (nCRLFLength != (int) dwWrittenBytes) + __leave; + } + } + ::CloseHandle (hTempFile); + hTempFile = INVALID_HANDLE_VALUE; + + if (m_bCreateBackupFile) + { + WIN32_FIND_DATA wfd; + hSearch =::FindFirstFile (pszFileName, &wfd); + if (hSearch != INVALID_HANDLE_VALUE) + { + // File exist - create backup file + ::DeleteFile (szBackupFileName); + if (!::MoveFile (pszFileName, szBackupFileName)) + __leave; + ::FindClose (hSearch); + hSearch = INVALID_HANDLE_VALUE; + } + } + else + { + ::DeleteFile (pszFileName); + } + + // Move temporary file to target name + if (!::MoveFile (szTempFileName, pszFileName)) + __leave; + + if (bClearModifiedFlag) + { + SetModified (FALSE); + m_nSyncPosition = m_nUndoPosition; + } + bSuccess = TRUE; + } + __finally + { + if (hSearch != INVALID_HANDLE_VALUE) + ::FindClose (hSearch); + if (hTempFile != INVALID_HANDLE_VALUE) + ::CloseHandle (hTempFile); + ::DeleteFile (szTempFileName); + } + return bSuccess; +} + +int CCrystalTextBuffer:: +GetCRLFMode () +{ + return m_nCRLFMode; +} + +void CCrystalTextBuffer:: +SetCRLFMode (int nCRLFMode) +{ + /*ASSERT (nCRLFMode == CRLF_STYLE_DOS || + nCRLFMode == CRLF_STYLE_UNIX || + nCRLFMode == CRLF_STYLE_MAC);*/ + if (nCRLFMode >= 0) + { + m_nCRLFMode = nCRLFMode; + } +} + +int CCrystalTextBuffer:: +GetLineCount () +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + return m_aLines.GetSize (); +} + +int CCrystalTextBuffer:: +GetLineLength (int nLine) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + return m_aLines[nLine].m_nLength; +} + +LPTSTR CCrystalTextBuffer:: +GetLineChars (int nLine) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + return m_aLines[nLine].m_pcLine; +} + +DWORD CCrystalTextBuffer:: +GetLineFlags (int nLine) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + return m_aLines[nLine].m_dwFlags; +} + +static int +FlagToIndex (DWORD dwFlag) +{ + int nIndex = 0; + while ((dwFlag & 1) == 0) + { + dwFlag = dwFlag >> 1; + nIndex++; + if (nIndex == 32) + return -1; + } + dwFlag = dwFlag & 0xFFFFFFFE; + if (dwFlag != 0) + return -1; + return nIndex; + +} + +int CCrystalTextBuffer:: +FindLineWithFlag (DWORD dwFlag) +{ + int nSize = m_aLines.GetSize (); + for (int L = 0; L < nSize; L++) + { + if ((m_aLines[L].m_dwFlags & dwFlag) != 0) + return L; + } + return -1; +} + +int CCrystalTextBuffer:: +GetLineWithFlag (DWORD dwFlag) +{ + int nFlagIndex =::FlagToIndex (dwFlag); + if (nFlagIndex < 0) + { + ASSERT (FALSE); // Invalid flag passed in + + return -1; + } + return FindLineWithFlag (dwFlag); +} + +void CCrystalTextBuffer:: +SetLineFlag (int nLine, DWORD dwFlag, BOOL bSet, BOOL bRemoveFromPreviousLine /*= TRUE*/ , BOOL bUpdate /*=TRUE*/) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + int nFlagIndex =::FlagToIndex (dwFlag); + if (nFlagIndex < 0 && (nLine == -1 || bRemoveFromPreviousLine)) + { + ASSERT (FALSE); // Invalid flag passed in + + return; + } + + if (nLine == -1) + { + ASSERT (!bSet); + nLine = FindLineWithFlag (dwFlag); + if (nLine == -1) + return; + bRemoveFromPreviousLine = FALSE; + } + + DWORD dwNewFlags = m_aLines[nLine].m_dwFlags; + if (bSet) + { + if (dwFlag==0) + dwNewFlags=0; + else + dwNewFlags = dwNewFlags | dwFlag; + } + else + dwNewFlags = dwNewFlags & ~dwFlag; + + if (m_aLines[nLine].m_dwFlags != dwNewFlags) + { + if (bRemoveFromPreviousLine) + { + int nPrevLine = FindLineWithFlag (dwFlag); + if (bSet) + { + if (nPrevLine >= 0) + { + ASSERT ((m_aLines[nPrevLine].m_dwFlags & dwFlag) != 0); + m_aLines[nPrevLine].m_dwFlags &= ~dwFlag; + if (bUpdate) + UpdateViews (NULL, NULL, UPDATE_SINGLELINE | UPDATE_FLAGSONLY, nPrevLine); + } + } + else + { + ASSERT (nPrevLine == nLine); + } + } + + m_aLines[nLine].m_dwFlags = dwNewFlags; + if (bUpdate) + UpdateViews (NULL, NULL, UPDATE_SINGLELINE | UPDATE_FLAGSONLY, nLine); + } +} + +void CCrystalTextBuffer:: +GetText (int nStartLine, int nStartChar, int nEndLine, int nEndChar, CString & text, LPCTSTR pszCRLF /*= NULL*/ ) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + ASSERT (nStartLine >= 0 && nStartLine < m_aLines.GetSize ()); + ASSERT (nStartChar >= 0 && nStartChar <= m_aLines[nStartLine].m_nLength); + ASSERT (nEndLine >= 0 && nEndLine < m_aLines.GetSize ()); + ASSERT (nEndChar >= 0 && nEndChar <= m_aLines[nEndLine].m_nLength); + ASSERT (nStartLine < nEndLine || nStartLine == nEndLine && nStartChar < nEndChar); + + if (pszCRLF == NULL) + pszCRLF = crlf; + int nCRLFLength = _tcslen (pszCRLF); + ASSERT (nCRLFLength > 0); + + int nBufSize = 0; + for (int L = nStartLine; L <= nEndLine; L++) + { + nBufSize += m_aLines[L].m_nLength; + nBufSize += nCRLFLength; + } + + LPTSTR pszBuf = text.GetBuffer (nBufSize); + + if (nStartLine < nEndLine) + { + int nCount = m_aLines[nStartLine].m_nLength - nStartChar; + if (nCount > 0) + { + memcpy (pszBuf, m_aLines[nStartLine].m_pcLine + nStartChar, sizeof (TCHAR) * nCount); + pszBuf += nCount; + } + memcpy (pszBuf, pszCRLF, sizeof (TCHAR) * nCRLFLength); + pszBuf += nCRLFLength; + for (int I = nStartLine + 1; I < nEndLine; I++) + { + nCount = m_aLines[I].m_nLength; + if (nCount > 0) + { + memcpy (pszBuf, m_aLines[I].m_pcLine, sizeof (TCHAR) * nCount); + pszBuf += nCount; + } + memcpy (pszBuf, pszCRLF, sizeof (TCHAR) * nCRLFLength); + pszBuf += nCRLFLength; + } + if (nEndChar > 0) + { + memcpy (pszBuf, m_aLines[nEndLine].m_pcLine, sizeof (TCHAR) * nEndChar); + pszBuf += nEndChar; + } + } + else + { + int nCount = nEndChar - nStartChar; + memcpy (pszBuf, m_aLines[nStartLine].m_pcLine + nStartChar, sizeof (TCHAR) * nCount); + pszBuf += nCount; + } + pszBuf[0] = 0; + text.ReleaseBuffer (); + text.FreeExtra (); +} + +void CCrystalTextBuffer:: +AddView (CCrystalTextView * pView) +{ + m_lpViews.AddTail (pView); +} + +void CCrystalTextBuffer:: +RemoveView (CCrystalTextView * pView) +{ + POSITION pos = m_lpViews.GetHeadPosition (); + while (pos != NULL) + { + POSITION thispos = pos; + CCrystalTextView *pvw = m_lpViews.GetNext (pos); + if (pvw == pView) + { + m_lpViews.RemoveAt (thispos); + return; + } + } + ASSERT (FALSE); +} + +CCrystalTextView::TextDefinition *CCrystalTextBuffer:: +RetypeViews (LPCTSTR lpszFileName) +{ + POSITION pos = m_lpViews.GetHeadPosition (); + CString sNew = GetExt (lpszFileName); + CCrystalTextView::TextDefinition *def = CCrystalTextView::GetTextType (sNew); + while (pos != NULL) + { + CCrystalTextView *pView = m_lpViews.GetNext (pos); + pView->SetTextType (def); + } + return def; +} + +void CCrystalTextBuffer:: +UpdateViews (CCrystalTextView * pSource, CUpdateContext * pContext, DWORD dwUpdateFlags, int nLineIndex /*= -1*/ ) +{ + POSITION pos = m_lpViews.GetHeadPosition (); + while (pos != NULL) + { + CCrystalTextView *pView = m_lpViews.GetNext (pos); + pView->UpdateView (pSource, pContext, dwUpdateFlags, nLineIndex); + } +} + +BOOL CCrystalTextBuffer:: +InternalDeleteText (CCrystalTextView * pSource, int nStartLine, int nStartChar, int nEndLine, int nEndChar) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + ASSERT (nStartLine >= 0 && nStartLine < m_aLines.GetSize ()); + ASSERT (nStartChar >= 0 && nStartChar <= m_aLines[nStartLine].m_nLength); + ASSERT (nEndLine >= 0 && nEndLine < m_aLines.GetSize ()); + ASSERT (nEndChar >= 0 && nEndChar <= m_aLines[nEndLine].m_nLength); + ASSERT (nStartLine < nEndLine || nStartLine == nEndLine && nStartChar < nEndChar); + if (m_bReadOnly) + return FALSE; + + CDeleteContext context; + context.m_ptStart.y = nStartLine; + context.m_ptStart.x = nStartChar; + context.m_ptEnd.y = nEndLine; + context.m_ptEnd.x = nEndChar; + if (nStartLine == nEndLine) + { + SLineInfo & li = m_aLines[nStartLine]; + if (nEndChar < li.m_nLength) + { + memcpy (li.m_pcLine + nStartChar, li.m_pcLine + nEndChar, + sizeof (TCHAR) * (li.m_nLength - nEndChar)); + } + li.m_nLength -= (nEndChar - nStartChar); + + if (pSource!=NULL) + UpdateViews (pSource, &context, UPDATE_SINGLELINE | UPDATE_HORZRANGE, nStartLine); + } + else + { + int nRestCount = m_aLines[nEndLine].m_nLength - nEndChar; + LPTSTR pszRestChars = NULL; + if (nRestCount > 0) + { + pszRestChars = new TCHAR[nRestCount]; + memcpy (pszRestChars, m_aLines[nEndLine].m_pcLine + nEndChar, nRestCount * sizeof (TCHAR)); + } + + int nDelCount = nEndLine - nStartLine; + for (int L = nStartLine + 1; L <= nEndLine; L++) + delete m_aLines[L].m_pcLine; + m_aLines.RemoveAt (nStartLine + 1, nDelCount); + + // nEndLine is no more valid + m_aLines[nStartLine].m_nLength = nStartChar; + if (nRestCount > 0) + { + AppendLine (nStartLine, pszRestChars, nRestCount); + delete pszRestChars; + } + + if (pSource!=NULL) + UpdateViews (pSource, &context, UPDATE_HORZRANGE | UPDATE_VERTRANGE, nStartLine); + } + + if (!m_bModified) + SetModified (TRUE); + //BEGIN SW + // remember current cursor position as last editing position + m_ptLastChange = context.m_ptStart; + //END SW + return TRUE; +} + +BOOL CCrystalTextBuffer:: +InternalInsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + + ASSERT (nLine >= 0 && nLine < m_aLines.GetSize ()); + ASSERT (nPos >= 0 && nPos <= m_aLines[nLine].m_nLength); + if (m_bReadOnly) + return FALSE; + + CInsertContext context; + context.m_ptStart.x = nPos; + context.m_ptStart.y = nLine; + + int nRestCount = m_aLines[nLine].m_nLength - nPos; + LPTSTR pszRestChars = NULL; + if (nRestCount > 0) + { + pszRestChars = new TCHAR[nRestCount]; + memcpy (pszRestChars, m_aLines[nLine].m_pcLine + nPos, nRestCount * sizeof (TCHAR)); + m_aLines[nLine].m_nLength = nPos; + } + + int nCurrentLine = nLine; + BOOL bNewLines = FALSE; + int nTextPos; + for (;;) + { + nTextPos = 0; + while (pszText[nTextPos] != 0 && pszText[nTextPos] != _T ('\r')) + nTextPos++; + + if (nCurrentLine == nLine) + { + AppendLine (nLine, pszText, nTextPos); + } + else + { + InsertLine (pszText, nTextPos, nCurrentLine); + bNewLines = TRUE; + } + + if (pszText[nTextPos] == 0) + { + nEndLine = nCurrentLine; + nEndChar = m_aLines[nCurrentLine].m_nLength; + AppendLine (nCurrentLine, pszRestChars, nRestCount); + break; + } + + nCurrentLine++; + nTextPos++; + + if (pszText[nTextPos] == _T ('\n')) + { + nTextPos++; + } + else + { + ASSERT (FALSE); // Invalid line-end format passed + + } + + pszText += nTextPos; + } + + if (pszRestChars != NULL) + delete pszRestChars; + + context.m_ptEnd.x = nEndChar; + context.m_ptEnd.y = nEndLine; + + if (pSource!=NULL) + { + if (bNewLines) + UpdateViews (pSource, &context, UPDATE_HORZRANGE | UPDATE_VERTRANGE, nLine); + else + UpdateViews (pSource, &context, UPDATE_SINGLELINE | UPDATE_HORZRANGE, nLine); + } + + if (!m_bModified) + SetModified (TRUE); + //BEGIN SW + // remember current cursor position as last editing position + m_ptLastChange = context.m_ptEnd; + //END SW + return TRUE; +} + +BOOL CCrystalTextBuffer:: +CanUndo () +{ + ASSERT (m_nUndoPosition >= 0 && m_nUndoPosition <= m_aUndoBuf.GetSize ()); + return m_nUndoPosition > 0; +} + +BOOL CCrystalTextBuffer:: +CanRedo () +{ + ASSERT (m_nUndoPosition >= 0 && m_nUndoPosition <= m_aUndoBuf.GetSize ()); + return m_nUndoPosition < m_aUndoBuf.GetSize (); +} + +POSITION CCrystalTextBuffer:: +GetUndoDescription (CString & desc, POSITION pos /*= NULL*/ ) +{ + ASSERT (CanUndo ()); // Please call CanUndo() first + + ASSERT ((m_aUndoBuf[0].m_dwFlags & UNDO_BEGINGROUP) != 0); + + int nPosition; + if (pos == NULL) + { + // Start from beginning + nPosition = m_nUndoPosition; + } + else + { + nPosition = (int) pos; + ASSERT (nPosition > 0 && nPosition < m_nUndoPosition); + ASSERT ((m_aUndoBuf[nPosition].m_dwFlags & UNDO_BEGINGROUP) != 0); + } + + // Advance to next undo group + nPosition--; + while ((m_aUndoBuf[nPosition].m_dwFlags & UNDO_BEGINGROUP) == 0) + nPosition--; + + // Read description + if (!GetActionDescription (m_aUndoBuf[nPosition].m_nAction, desc)) + desc.Empty (); // Use empty string as description + + // Now, if we stop at zero position, this will be the last action, + // since we return (POSITION) nPosition + return (POSITION) nPosition; +} + +POSITION CCrystalTextBuffer:: +GetRedoDescription (CString & desc, POSITION pos /*= NULL*/ ) +{ + ASSERT (CanRedo ()); // Please call CanRedo() before! + + ASSERT ((m_aUndoBuf[0].m_dwFlags & UNDO_BEGINGROUP) != 0); + ASSERT ((m_aUndoBuf[m_nUndoPosition].m_dwFlags & UNDO_BEGINGROUP) != 0); + + int nPosition; + if (pos == NULL) + { + // Start from beginning + nPosition = m_nUndoPosition; + } + else + { + nPosition = (int) pos; + ASSERT (nPosition > m_nUndoPosition); + ASSERT ((m_aUndoBuf[nPosition].m_dwFlags & UNDO_BEGINGROUP) != 0); + } + + // Read description + if (!GetActionDescription (m_aUndoBuf[nPosition].m_nAction, desc)) + desc.Empty (); // Use empty string as description + + // Advance to next undo group + nPosition++; + while (nPosition < m_aUndoBuf.GetSize () && + (m_aUndoBuf[nPosition].m_dwFlags & UNDO_BEGINGROUP) == 0) + nPosition--; + + if (nPosition >= m_aUndoBuf.GetSize ()) + return NULL; // No more redo actions! + + return (POSITION) nPosition; +} + +BOOL CCrystalTextBuffer:: +Undo (CPoint & ptCursorPos) +{ + ASSERT (CanUndo ()); + ASSERT ((m_aUndoBuf[0].m_dwFlags & UNDO_BEGINGROUP) != 0); + for (;;) + { + m_nUndoPosition--; + const SUndoRecord & ur = m_aUndoBuf[m_nUndoPosition]; + if (ur.m_dwFlags & UNDO_INSERT) + { +#ifdef _ADVANCED_BUGCHECK + // Try to ensure that we undoing correctly... + // Just compare the text as it was before Undo operation + CString text; + GetText (ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.m_ptEndPos.y, ur.m_ptEndPos.x, text); + ASSERT (lstrcmp (text, ur.GetText ()) == 0); +#endif + VERIFY (InternalDeleteText (NULL, ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.m_ptEndPos.y, ur.m_ptEndPos.x)); + ptCursorPos = ur.m_ptStartPos; + } + else + { + int nEndLine, nEndChar; + VERIFY (InternalInsertText (NULL, ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.GetText (), nEndLine, nEndChar)); +#ifdef _ADVANCED_BUGCHECK + ASSERT (ur.m_ptEndPos.y == nEndLine); + ASSERT (ur.m_ptEndPos.x == nEndChar); +#endif + ptCursorPos = ur.m_ptEndPos; + } + if (ur.m_dwFlags & UNDO_BEGINGROUP) + break; + } + if (m_bModified && m_nSyncPosition == m_nUndoPosition) + SetModified (FALSE); + if (!m_bModified && m_nSyncPosition != m_nUndoPosition) + SetModified (TRUE); + return TRUE; +} + +BOOL CCrystalTextBuffer:: +Redo (CPoint & ptCursorPos) +{ + ASSERT (CanRedo ()); + ASSERT ((m_aUndoBuf[0].m_dwFlags & UNDO_BEGINGROUP) != 0); + ASSERT ((m_aUndoBuf[m_nUndoPosition].m_dwFlags & UNDO_BEGINGROUP) != 0); + for (;;) + { + const SUndoRecord & ur = m_aUndoBuf[m_nUndoPosition]; + if (ur.m_dwFlags & UNDO_INSERT) + { + int nEndLine, nEndChar; + VERIFY (InternalInsertText (NULL, ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.GetText (), nEndLine, nEndChar)); +#ifdef _ADVANCED_BUGCHECK + ASSERT (ur.m_ptEndPos.y == nEndLine); + ASSERT (ur.m_ptEndPos.x == nEndChar); +#endif + ptCursorPos = ur.m_ptEndPos; + } + else + { +#ifdef _ADVANCED_BUGCHECK + CString text; + GetText (ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.m_ptEndPos.y, ur.m_ptEndPos.x, text); + ASSERT (lstrcmp (text, ur.GetText ()) == 0); +#endif + VERIFY (InternalDeleteText (NULL, ur.m_ptStartPos.y, ur.m_ptStartPos.x, ur.m_ptEndPos.y, ur.m_ptEndPos.x)); + ptCursorPos = ur.m_ptStartPos; + } + m_nUndoPosition++; + if (m_nUndoPosition == m_aUndoBuf.GetSize ()) + break; + if ((m_aUndoBuf[m_nUndoPosition].m_dwFlags & UNDO_BEGINGROUP) != 0) + break; + } + if (m_bModified && m_nSyncPosition == m_nUndoPosition) + SetModified (FALSE); + if (!m_bModified && m_nSyncPosition != m_nUndoPosition) + SetModified (TRUE); + return TRUE; +} + +// [JRT] Support For Descriptions On Undo/Redo Actions +void CCrystalTextBuffer:: +AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos, LPCTSTR pszText, int nActionType) +{ + // Forgot to call BeginUndoGroup()? + ASSERT (m_bUndoGroup); + ASSERT (m_aUndoBuf.GetSize () == 0 || (m_aUndoBuf[0].m_dwFlags & UNDO_BEGINGROUP) != 0); + + // Strip unnecessary undo records (edit after undo) + int nBufSize = m_aUndoBuf.GetSize (); + if (m_nUndoPosition < nBufSize) + { + for (int I = m_nUndoPosition; I < nBufSize; I++) + m_aUndoBuf[I].FreeText (); + m_aUndoBuf.SetSize (m_nUndoPosition); + } + + // If undo buffer size is close to critical, remove the oldest records + ASSERT (m_aUndoBuf.GetSize () <= m_nUndoBufSize); + nBufSize = m_aUndoBuf.GetSize (); + if (nBufSize >= m_nUndoBufSize) + { + int nIndex = 0; + for (;;) + { + m_aUndoBuf[nIndex].FreeText (); + nIndex++; + if (nIndex == nBufSize || (m_aUndoBuf[nIndex].m_dwFlags & UNDO_BEGINGROUP) != 0) + break; + } + m_aUndoBuf.RemoveAt (0, nIndex); + } + ASSERT (m_aUndoBuf.GetSize () < m_nUndoBufSize); + + // Add new record + SUndoRecord ur; + ur.m_dwFlags = bInsert ? UNDO_INSERT : 0; + ur.m_nAction = nActionType; + if (m_bUndoBeginGroup) + { + ur.m_dwFlags |= UNDO_BEGINGROUP; + m_bUndoBeginGroup = FALSE; + } + ur.m_ptStartPos = ptStartPos; + ur.m_ptEndPos = ptEndPos; + ur.SetText (pszText); + + m_aUndoBuf.Add (ur); + m_nUndoPosition = m_aUndoBuf.GetSize (); + + ASSERT (m_aUndoBuf.GetSize () <= m_nUndoBufSize); +} + +BOOL CCrystalTextBuffer:: +InsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, + int &nEndLine, int &nEndChar, int nAction, BOOL bUpdate /*=TRUE*/) +{ + if (!InternalInsertText (bUpdate? pSource:NULL, nLine, nPos, pszText, nEndLine, nEndChar)) + return FALSE; + + BOOL bGroupFlag = FALSE; + if (!m_bUndoGroup) + { + BeginUndoGroup (); + bGroupFlag = TRUE; + } + AddUndoRecord (TRUE, CPoint (nPos, nLine), CPoint (nEndChar, nEndLine), pszText, nAction); + if (bGroupFlag) + FlushUndoGroup (pSource); + return TRUE; +} + +BOOL CCrystalTextBuffer:: +DeleteText (CCrystalTextView * pSource, int nStartLine, int nStartChar, + int nEndLine, int nEndChar, int nAction, BOOL bUpdate /*=TRUE*/) +{ + CString sTextToDelete; + GetText (nStartLine, nStartChar, nEndLine, nEndChar, sTextToDelete); + + if (!InternalDeleteText (bUpdate? pSource:NULL, nStartLine, nStartChar, nEndLine, nEndChar)) + return FALSE; + + BOOL bGroupFlag = FALSE; + if (!m_bUndoGroup) + { + BeginUndoGroup (); + bGroupFlag = TRUE; + } + AddUndoRecord (FALSE, CPoint (nStartChar, nStartLine), CPoint (nEndChar, nEndLine), sTextToDelete, nAction); + if (bGroupFlag) + FlushUndoGroup (pSource); + return TRUE; +} + +BOOL CCrystalTextBuffer:: +GetActionDescription (int nAction, CString & desc) +{ + HINSTANCE hOldResHandle = AfxGetResourceHandle (); +#ifdef CRYSEDIT_RES_HANDLE + AfxSetResourceHandle (CRYSEDIT_RES_HANDLE); +#else + if (CCrystalTextView::s_hResourceInst != NULL) + AfxSetResourceHandle (CCrystalTextView::s_hResourceInst); +#endif + BOOL bSuccess = FALSE; + switch (nAction) + { + case CE_ACTION_PASTE: + bSuccess = desc.LoadString (IDS_EDITOP_PASTE); + break; + case CE_ACTION_DELSEL: + bSuccess = desc.LoadString (IDS_EDITOP_DELSELECTION); + break; + case CE_ACTION_CUT: + bSuccess = desc.LoadString (IDS_EDITOP_CUT); + break; + case CE_ACTION_TYPING: + bSuccess = desc.LoadString (IDS_EDITOP_TYPING); + break; + case CE_ACTION_BACKSPACE: + bSuccess = desc.LoadString (IDS_EDITOP_BACKSPACE); + break; + case CE_ACTION_INDENT: + bSuccess = desc.LoadString (IDS_EDITOP_INDENT); + break; + case CE_ACTION_DRAGDROP: + bSuccess = desc.LoadString (IDS_EDITOP_DRAGDROP); + break; + case CE_ACTION_REPLACE: + bSuccess = desc.LoadString (IDS_EDITOP_REPLACE); + break; + case CE_ACTION_DELETE: + bSuccess = desc.LoadString (IDS_EDITOP_DELETE); + break; + case CE_ACTION_AUTOINDENT: + bSuccess = desc.LoadString (IDS_EDITOP_AUTOINDENT); + break; + case CE_ACTION_AUTOCOMPLETE: + bSuccess = desc.LoadString (IDS_EDITOP_AUTOCOMPLETE); + break; + case CE_ACTION_AUTOEXPAND: + bSuccess = desc.LoadString (IDS_EDITOP_AUTOEXPAND); + break; + case CE_ACTION_LOWERCASE: + bSuccess = desc.LoadString (IDS_EDITOP_LOWERCASE); + break; + case CE_ACTION_UPPERCASE: + bSuccess = desc.LoadString (IDS_EDITOP_UPPERCASE); + break; + case CE_ACTION_SWAPCASE: + bSuccess = desc.LoadString (IDS_EDITOP_SWAPCASE); + break; + case CE_ACTION_CAPITALIZE: + bSuccess = desc.LoadString (IDS_EDITOP_CAPITALIZE); + break; + case CE_ACTION_SENTENCIZE: + bSuccess = desc.LoadString (IDS_EDITOP_SENTENCIZE); + break; + case CE_ACTION_RECODE: + bSuccess = desc.LoadString (IDS_EDITOP_RECODE); + break; + case CE_ACTION_SPELL: + bSuccess = desc.LoadString (IDS_EDITOP_SPELL); + break; + default: /* case CE_ACTION_UNKNOWN: */ + bSuccess = desc.LoadString (IDS_EDITOP_UNKNOWN); + } + AfxSetResourceHandle (hOldResHandle); + return bSuccess; +} + +void CCrystalTextBuffer:: +SetModified (BOOL bModified /*= TRUE*/ ) +{ + m_bModified = bModified; +} + +void CCrystalTextBuffer:: +BeginUndoGroup (BOOL bMergeWithPrevious /*= FALSE*/ ) +{ + ASSERT (!m_bUndoGroup); + m_bUndoGroup = TRUE; + m_bUndoBeginGroup = m_nUndoPosition == 0 || !bMergeWithPrevious; +} + +void CCrystalTextBuffer:: +FlushUndoGroup (CCrystalTextView * pSource) +{ + ASSERT (m_bUndoGroup); + if (pSource != NULL) + { + ASSERT (m_nUndoPosition == m_aUndoBuf.GetSize ()); + if (m_nUndoPosition > 0) + { + m_bUndoBeginGroup = TRUE; + pSource->OnEditOperation (m_aUndoBuf[m_nUndoPosition - 1].m_nAction, m_aUndoBuf[m_nUndoPosition - 1].GetText ()); + } + } + m_bUndoGroup = FALSE; +} + +int CCrystalTextBuffer:: +FindNextBookmarkLine (int nCurrentLine) +{ + BOOL bWrapIt = TRUE; + DWORD dwFlags = GetLineFlags (nCurrentLine); + if ((dwFlags & LF_BOOKMARKS) != 0) + nCurrentLine++; + + int nSize = m_aLines.GetSize (); + for (;;) + { + while (nCurrentLine < nSize) + { + if ((m_aLines[nCurrentLine].m_dwFlags & LF_BOOKMARKS) != 0) + return nCurrentLine; + // Keep going + nCurrentLine++; + } + // End of text reached + if (!bWrapIt) + return -1; + + // Start from the beginning of text + bWrapIt = FALSE; + nCurrentLine = 0; + } + return -1; +} + +int CCrystalTextBuffer:: +FindPrevBookmarkLine (int nCurrentLine) +{ + BOOL bWrapIt = TRUE; + DWORD dwFlags = GetLineFlags (nCurrentLine); + if ((dwFlags & LF_BOOKMARKS) != 0) + nCurrentLine--; + + int nSize = m_aLines.GetSize (); + for (;;) + { + while (nCurrentLine >= 0) + { + if ((m_aLines[nCurrentLine].m_dwFlags & LF_BOOKMARKS) != 0) + return nCurrentLine; + // Keep moving up + nCurrentLine--; + } + // Beginning of text reached + if (!bWrapIt) + return -1; + + // Start from the end of text + bWrapIt = FALSE; + nCurrentLine = nSize - 1; + } + return -1; +} + +BOOL CCrystalTextBuffer:: +IsMBSLead (int nLine, int nCol) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + +#ifdef _UNICODE + LPCTSTR string = (LPCTSTR) GetLineChars (nLine); + LPCTSTR current = string + nCol; + return FALSE; +#else // _UNICODE + const unsigned char *string = (const unsigned char *) GetLineChars (nLine); + const unsigned char *current = string + nCol; + if (_ismbslead (string, current) < 0) + return TRUE; + return FALSE; +#endif // _UNICODE +} + +BOOL CCrystalTextBuffer:: +IsMBSTrail (int nLine, int nCol) +{ + ASSERT (m_bInit); // Text buffer not yet initialized. + // You must call InitNew() or LoadFromFile() first! + +#ifdef _UNICODE + LPCTSTR string = (LPCTSTR) GetLineChars (nLine); + LPCTSTR current = string + nCol; + return FALSE; +#else // _UNICODE + const unsigned char *string = (const unsigned char *) GetLineChars (nLine); + const unsigned char *current = string + nCol; + if (_ismbstrail (string, current) < 0) + return TRUE; + return FALSE; +#endif // _UNICODE +} + +//BEGIN SW +CPoint CCrystalTextBuffer::GetLastChangePos() const +{ + return m_ptLastChange; +} +//END SW diff --git a/Src/editlib/ccrystaltextbuffer.h b/Src/editlib/ccrystaltextbuffer.h new file mode 100644 index 000000000..40efcaeb7 --- /dev/null +++ b/Src/editlib/ccrystaltextbuffer.h @@ -0,0 +1,335 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaltextbuffer.h +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Interface of the CCrystalTextBuffer class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CCRYSTALTEXTBUFFER_H__AD7F2F49_6CB3_11D2_8C32_0080ADB86836__INCLUDED_) +#define AFX_CCRYSTALTEXTBUFFER_H__AD7F2F49_6CB3_11D2_8C32_0080ADB86836__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "ccrystaltextview.h" + +#ifndef __AFXTEMPL_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif + +#define UNDO_DESCRIP_BUF 32 + +enum LINEFLAGS +{ + LF_BOOKMARK_FIRST = 0x00000001L, + LF_EXECUTION = 0x00010000L, + LF_BREAKPOINT = 0x00020000L, + LF_COMPILATION_ERROR = 0x00040000L, + LF_BOOKMARKS = 0x00080000L, + LF_INVALID_BREAKPOINT = 0x00100000L, + LF_DIFF = 0x00200000L, + LF_DELETED = 0x00400000L, + LF_LEFT_ONLY = 0x00800000L, + LF_RIGHT_ONLY = 0x01000000L +}; +#define LF_WINMERGE_FLAGS 0x01e00000 + +#define LF_BOOKMARK(id) (LF_BOOKMARK_FIRST << id) + +enum CRLFSTYLE +{ + CRLF_STYLE_AUTOMATIC = -1, + CRLF_STYLE_DOS = 0, + CRLF_STYLE_UNIX = 1, + CRLF_STYLE_MAC = 2 +}; + +enum +{ + CE_ACTION_UNKNOWN = 0, + CE_ACTION_PASTE = 1, + CE_ACTION_DELSEL = 2, + CE_ACTION_CUT = 3, + CE_ACTION_TYPING = 4, + CE_ACTION_BACKSPACE = 5, + CE_ACTION_INDENT = 6, + CE_ACTION_DRAGDROP = 7, + CE_ACTION_REPLACE = 8, + CE_ACTION_DELETE = 9, + CE_ACTION_AUTOINDENT = 10, + CE_ACTION_AUTOCOMPLETE = 11, + CE_ACTION_AUTOEXPAND = 12, + CE_ACTION_LOWERCASE = 13, + CE_ACTION_UPPERCASE = 14, + CE_ACTION_SWAPCASE = 15, + CE_ACTION_CAPITALIZE = 16, + CE_ACTION_SENTENCIZE = 17, + CE_ACTION_RECODE = 18, + CE_ACTION_SPELL = 19 + // ... + // Expandable: user actions allowed +}; + + +///////////////////////////////////////////////////////////////////////////// +// CUpdateContext class + +class EDITPADC_CLASS CUpdateContext + { +public : + virtual void RecalcPoint (CPoint & ptPoint) = 0; + }; + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextBuffer command target + +class EDITPADC_CLASS CCrystalTextBuffer : public CCmdTarget + { +public: + DECLARE_DYNCREATE (CCrystalTextBuffer) + + int m_nSourceEncoding; + static int m_nDefaultEncoding; + +protected : + BOOL m_bInit; + BOOL m_bReadOnly; + BOOL m_bModified; + int m_nCRLFMode; + BOOL m_bCreateBackupFile; + int m_nUndoBufSize; + int FindLineWithFlag (DWORD dwFlag); + +protected : +#pragma pack(push, 1) + // Nested class declarations + struct SLineInfo + { + TCHAR *m_pcLine; + int m_nLength, m_nMax; + DWORD m_dwFlags; + + SLineInfo () + { + memset (this, 0, sizeof (SLineInfo)); + }; + }; + + enum + { + UNDO_INSERT = 0x0001, + UNDO_BEGINGROUP = 0x0100 + }; + + // [JRT] Support For Descriptions On Undo/Redo Actions + struct SUndoRecord + { + DWORD m_dwFlags; + + CPoint m_ptStartPos, m_ptEndPos; // Block of text participating + + int m_nAction; // For information only: action type + +private : + // TCHAR *m_pcText; + // Since in most cases we have 1 character here, + // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*) + // + // Here we will use the following trick: on Win32 platforms high-order word + // of any pointer will be != 0. So we can store 1 character strings without + // allocating memory. + // + + union + { + TCHAR *m_pszText; // For cases when we have > 1 character strings + + TCHAR m_szText[2]; // For single-character strings + + }; + +public : + // constructor/destructor for this struct + SUndoRecord () + { + memset (this, 0, sizeof (SUndoRecord)); + }; + + void SetText (LPCTSTR pszText); + void FreeText (); + + LPCTSTR GetText () const + { + if (HIWORD ((DWORD) m_pszText) != 0) + return m_pszText; + return m_szText; + }; + }; + +#pragma pack(pop) + +class EDITPADC_CLASS CInsertContext : public CUpdateContext + { +public : + CPoint m_ptStart, m_ptEnd; + virtual void RecalcPoint (CPoint & ptPoint); + }; + +class EDITPADC_CLASS CDeleteContext : public CUpdateContext + { +public : + CPoint m_ptStart, m_ptEnd; + virtual void RecalcPoint (CPoint & ptPoint); + }; + + // Lines of text + CArray < SLineInfo, SLineInfo & >m_aLines; + + // Undo + CArray < SUndoRecord, SUndoRecord & >m_aUndoBuf; + int m_nUndoPosition; + int m_nSyncPosition; + BOOL m_bUndoGroup, m_bUndoBeginGroup; + + //BEGIN SW + /** Position where the last change was made. */ + CPoint m_ptLastChange; + //END SW + + // Connected views + CList < CCrystalTextView *, CCrystalTextView * >m_lpViews; + + // Helper methods + void InsertLine (LPCTSTR pszLine, int nLength = -1, int nPosition = -1); + void AppendLine (int nLineIndex, LPCTSTR pszChars, int nLength = -1); + + // Implementation + BOOL InternalInsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar); + BOOL InternalDeleteText (CCrystalTextView * pSource, int nStartLine, int nStartPos, int nEndLine, int nEndPos); + + // [JRT] Support For Descriptions On Undo/Redo Actions + void AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos, + LPCTSTR pszText, int nActionType = CE_ACTION_UNKNOWN); + + // Overridable: provide action description + virtual BOOL GetActionDescription (int nAction, CString & desc); + + // Operations +public : + // Construction/destruction code + CCrystalTextBuffer (); + ~CCrystalTextBuffer (); + + // Basic functions + BOOL InitNew (int nCrlfStyle = CRLF_STYLE_DOS); + BOOL LoadFromFile (LPCTSTR pszFileName, int nCrlfStyle = CRLF_STYLE_AUTOMATIC); + BOOL SaveToFile (LPCTSTR pszFileName, int nCrlfStyle = CRLF_STYLE_AUTOMATIC, BOOL bClearModifiedFlag = TRUE); + void FreeAll (); + + // 'Dirty' flag + virtual void SetModified (BOOL bModified = TRUE); + BOOL IsModified () const; + + // Connect/disconnect views + void AddView (CCrystalTextView * pView); + void RemoveView (CCrystalTextView * pView); + + // Text access functions + int GetLineCount (); + int GetLineLength (int nLine); + LPTSTR GetLineChars (int nLine); + DWORD GetLineFlags (int nLine); + int GetLineWithFlag (DWORD dwFlag); + void SetLineFlag (int nLine, DWORD dwFlag, BOOL bSet, BOOL bRemoveFromPreviousLine = TRUE, BOOL bUpdate=TRUE); + void GetText (int nStartLine, int nStartChar, int nEndLine, int nEndChar, CString & text, LPCTSTR pszCRLF = NULL); + + // Attributes + int GetCRLFMode (); + void SetCRLFMode (int nCRLFMode); + BOOL GetReadOnly () const; + void SetReadOnly (BOOL bReadOnly = TRUE); + + // Text modification functions + BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar, int nAction = CE_ACTION_UNKNOWN, BOOL bUpdate =TRUE); + BOOL DeleteText (CCrystalTextView * pSource, int nStartLine, int nStartPos, int nEndLine, int nEndPos, int nAction = CE_ACTION_UNKNOWN, BOOL bUpdate =TRUE); + + // Undo/Redo + BOOL CanUndo (); + BOOL CanRedo (); + BOOL Undo (CPoint & ptCursorPos); + BOOL Redo (CPoint & ptCursorPos); + + // Undo grouping + void BeginUndoGroup (BOOL bMergeWithPrevious = FALSE); + void FlushUndoGroup (CCrystalTextView * pSource); + + //BEGIN SW + /** + Returns the position where the last changes where made. + */ + CPoint GetLastChangePos() const; + //END SW + + // Browse undo sequence + POSITION GetUndoDescription (CString & desc, POSITION pos = NULL); + POSITION GetRedoDescription (CString & desc, POSITION pos = NULL); + + // Notify all connected views about changes in name of file + CCrystalTextView::TextDefinition *RetypeViews (LPCTSTR lpszFileName); + // Notify all connected views about changes in text + void UpdateViews (CCrystalTextView * pSource, CUpdateContext * pContext, + DWORD dwUpdateFlags, int nLineIndex = -1); + + // More bookmarks + int FindNextBookmarkLine (int nCurrentLine = 0); + int FindPrevBookmarkLine (int nCurrentLine = 0); + + BOOL IsMBSLead (int nLine, int nCol); + BOOL IsMBSTrail (int nLine, int nCol); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCrystalTextBuffer) + //}}AFX_VIRTUAL + + // Implementation +protected : + // Generated message map functions + //{{AFX_MSG(CCrystalTextBuffer) + //}}AFX_MSG + + DECLARE_MESSAGE_MAP () + }; + +#if ! (defined(CE_FROM_DLL) || defined(CE_DLL_BUILD)) +#include "ccrystaltextbuffer.inl" +#endif + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CCRYSTALTEXTBUFFER_H__AD7F2F49_6CB3_11D2_8C32_0080ADB86836__INCLUDED_) diff --git a/Src/editlib/ccrystaltextbuffer.inl b/Src/editlib/ccrystaltextbuffer.inl new file mode 100644 index 000000000..4a9212b4a --- /dev/null +++ b/Src/editlib/ccrystaltextbuffer.inl @@ -0,0 +1,38 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CCrystalTextBuffer.inl +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Inline functions of Crystal Edit classes +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#ifndef __CCrystalTextBuffer_INL_INCLUDED +#define __CCrystalTextBuffer_INL_INCLUDED + +#include "CCrystalTextBuffer.h" + +inline BOOL CCrystalTextBuffer:: +IsModified () +const +{ + return m_bModified; +} + +#endif diff --git a/Src/editlib/ccrystaltextview.cpp b/Src/editlib/ccrystaltextview.cpp new file mode 100644 index 000000000..038d682ca --- /dev/null +++ b/Src/editlib/ccrystaltextview.cpp @@ -0,0 +1,5202 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaltextview.cpp +// Version: 1.2.0.5 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalTextView class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 17-Feb-99 +// FIX: missing UpdateCaret() in CCrystalTextView::SetFont +// FIX: missing UpdateCaret() in CCrystalTextView::RecalcVertScrollBar +// FIX: mistype in CCrystalTextView::RecalcPageLayouts + instead of += +// FIX: removed condition 'm_nLineHeight < 20' in +// CCrystalTextView::CalcLineCharDim(). This caused painting defects +// when using very small fonts. +// +// FEATURE: Some experiments with smooth scrolling, controlled by +// m_bSmoothScroll member variable, by default turned off. +// See ScrollToLine function for implementation details. +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 21-Feb-99 +// Paul Selormey, James R. Twine +// + FEATURE: description for Undo/Redo actions +// + FEATURE: multiple MSVC-like bookmarks +// + FEATURE: 'Disable backspace at beginning of line' option +// + FEATURE: 'Disable drag-n-drop editing' option +// +// + FIX: ResetView() now virtual +// + FEATURE: Added OnEditOperation() virtual: base for auto-indent, +// smart indent etc. +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: regular expressions, go to line and things ... +// + FEATURE: plenty of syntax highlighting definitions +// + FEATURE: corrected bug in syntax highlighting C comments +// + FEATURE: extended registry support for saving settings +// + FEATURE: some other things I've forgotten ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 01-Jun-99 to 31-Aug-99 +// Sven Wiegand (search for "//BEGIN SW" to find my changes): +// +// + FEATURE: support for language switching on the fly with class +// CCrystalParser +// + FEATURE: word wrapping +// + FIX: Setting m_nIdealCharPos, when choosing cursor position by mouse +// + FIX: Backward search +// + FEATURE: incremental search +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 24-Oct-99 +// Sven Wiegand +// +// + FIX: Opening large files won't crash anymore and will go very fast +// (removed call to RecalcVertScrollBar() in WrapLineCached()) +// + FIX: Problems with repainting and cursor-position by resizing window +// fixed by adding call to ScrollToSubLine() in OnSize(). +// + FEATURE: Supporting [Return] to exit incremental-search-mode +// (see OnChar()) +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "editcmd.h" +#include "editreg.h" +#include "ccrystaltextview.h" +#include "ccrystaltextbuffer.h" +#include "cfindtextdlg.h" +#include "fpattern.h" +#include "filesup.h" +#include "registry.h" +#include "gotodlg.h" + +#ifndef __AFXPRIV_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define TAB_CHARACTER _T('\xBB') +#define SPACE_CHARACTER _T('\x95') +#define DEFAULT_PRINT_MARGIN 1000 // 10 millimeters + +#define SMOOTH_SCROLL_FACTOR 6 + +#pragma warning ( disable : 4100 ) +//////////////////////////////////////////////////////////////////////////// +// CCrystalTextView + +LOGFONT CCrystalTextView::m_LogFont; + +IMPLEMENT_DYNCREATE (CCrystalTextView, CView) + +HINSTANCE CCrystalTextView::s_hResourceInst = NULL; + +BEGIN_MESSAGE_MAP (CCrystalTextView, CView) +//{{AFX_MSG_MAP(CCrystalTextView) +ON_WM_DESTROY () +ON_WM_ERASEBKGND () +ON_WM_SIZE () +ON_WM_VSCROLL () +ON_WM_SETCURSOR () +ON_WM_LBUTTONDOWN () +ON_WM_SETFOCUS () +ON_WM_HSCROLL () +ON_WM_LBUTTONUP () +ON_WM_MOUSEMOVE () +ON_WM_TIMER () +ON_WM_KILLFOCUS () +ON_WM_LBUTTONDBLCLK () +ON_COMMAND (ID_EDIT_COPY, OnEditCopy) +ON_UPDATE_COMMAND_UI (ID_EDIT_COPY, OnUpdateEditCopy) +ON_COMMAND (ID_EDIT_SELECT_ALL, OnEditSelectAll) +ON_UPDATE_COMMAND_UI (ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll) +ON_WM_RBUTTONDOWN () +ON_WM_SYSCOLORCHANGE () +ON_WM_CREATE () +ON_COMMAND (ID_EDIT_FIND, OnEditFind) +ON_COMMAND (ID_EDIT_REPEAT, OnEditRepeat) +ON_UPDATE_COMMAND_UI (ID_EDIT_REPEAT, OnUpdateEditRepeat) +ON_COMMAND (ID_EDIT_FIND_PREVIOUS, OnEditFindPrevious) +ON_UPDATE_COMMAND_UI (ID_EDIT_FIND_PREVIOUS, OnUpdateEditFindPrevious) +ON_WM_MOUSEWHEEL () +//}}AFX_MSG_MAP +ON_COMMAND (ID_EDIT_CHAR_LEFT, OnCharLeft) +ON_COMMAND (ID_EDIT_EXT_CHAR_LEFT, OnExtCharLeft) +ON_COMMAND (ID_EDIT_CHAR_RIGHT, OnCharRight) +ON_COMMAND (ID_EDIT_EXT_CHAR_RIGHT, OnExtCharRight) +ON_COMMAND (ID_EDIT_WORD_LEFT, OnWordLeft) +ON_COMMAND (ID_EDIT_EXT_WORD_LEFT, OnExtWordLeft) +ON_COMMAND (ID_EDIT_WORD_RIGHT, OnWordRight) +ON_COMMAND (ID_EDIT_EXT_WORD_RIGHT, OnExtWordRight) +ON_COMMAND (ID_EDIT_LINE_UP, OnLineUp) +ON_COMMAND (ID_EDIT_EXT_LINE_UP, OnExtLineUp) +ON_COMMAND (ID_EDIT_LINE_DOWN, OnLineDown) +ON_COMMAND (ID_EDIT_EXT_LINE_DOWN, OnExtLineDown) +ON_COMMAND (ID_EDIT_SCROLL_UP, ScrollUp) +ON_COMMAND (ID_EDIT_SCROLL_DOWN, ScrollDown) +ON_COMMAND (ID_EDIT_PAGE_UP, OnPageUp) +ON_COMMAND (ID_EDIT_EXT_PAGE_UP, OnExtPageUp) +ON_COMMAND (ID_EDIT_PAGE_DOWN, OnPageDown) +ON_COMMAND (ID_EDIT_EXT_PAGE_DOWN, OnExtPageDown) +ON_COMMAND (ID_EDIT_LINE_END, OnLineEnd) +ON_COMMAND (ID_EDIT_EXT_LINE_END, OnExtLineEnd) +ON_COMMAND (ID_EDIT_HOME, OnHome) +ON_COMMAND (ID_EDIT_EXT_HOME, OnExtHome) +ON_COMMAND (ID_EDIT_TEXT_BEGIN, OnTextBegin) +ON_COMMAND (ID_EDIT_EXT_TEXT_BEGIN, OnExtTextBegin) +ON_COMMAND (ID_EDIT_TEXT_END, OnTextEnd) +ON_COMMAND (ID_EDIT_EXT_TEXT_END, OnExtTextEnd) +// Standard printing commands +ON_COMMAND (ID_FILE_PAGE_SETUP, OnFilePageSetup) +ON_COMMAND (ID_FILE_PRINT, CView::OnFilePrint) +ON_COMMAND (ID_FILE_PRINT_DIRECT, CView::OnFilePrint) +ON_COMMAND (ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) +// Status +ON_UPDATE_COMMAND_UI (ID_EDIT_INDICATOR_CRLF, OnUpdateIndicatorCRLF) +ON_UPDATE_COMMAND_UI (ID_EDIT_INDICATOR_POSITION, OnUpdateIndicatorPosition) +// Bookmarks +ON_COMMAND_RANGE (ID_EDIT_TOGGLE_BOOKMARK0, ID_EDIT_TOGGLE_BOOKMARK9, OnToggleBookmark) +ON_COMMAND_RANGE (ID_EDIT_GO_BOOKMARK0, ID_EDIT_GO_BOOKMARK9, OnGoBookmark) +ON_COMMAND (ID_EDIT_CLEAR_BOOKMARKS, OnClearBookmarks) +// More Bookmarks +ON_COMMAND (ID_EDIT_TOGGLE_BOOKMARK, OnToggleBookmark) +ON_COMMAND (ID_EDIT_GOTO_NEXT_BOOKMARK, OnNextBookmark) +ON_COMMAND (ID_EDIT_GOTO_PREV_BOOKMARK, OnPrevBookmark) +ON_COMMAND (ID_EDIT_CLEAR_ALL_BOOKMARKS, OnClearAllBookmarks) +ON_UPDATE_COMMAND_UI (ID_EDIT_GOTO_NEXT_BOOKMARK, OnUpdateNextBookmark) +ON_UPDATE_COMMAND_UI (ID_EDIT_GOTO_PREV_BOOKMARK, OnUpdatePrevBookmark) +ON_UPDATE_COMMAND_UI (ID_EDIT_CLEAR_ALL_BOOKMARKS, OnUpdateClearAllBookmarks) +// Ferdi's source type chnages +ON_COMMAND_RANGE (ID_SOURCE_PLAIN, ID_SOURCE_TEX, OnSourceType) +ON_UPDATE_COMMAND_UI_RANGE (ID_SOURCE_PLAIN, ID_SOURCE_TEX, OnUpdateSourceType) +ON_COMMAND (ID_EDIT_MATCHBRACE, OnMatchBrace) +ON_UPDATE_COMMAND_UI (ID_EDIT_MATCHBRACE, OnUpdateMatchBrace) +ON_COMMAND (ID_EDIT_GOTO, OnEditGoTo) +ON_UPDATE_COMMAND_UI (ID_VIEW_TOGGLE_SRC_HDR, OnUpdateToggleSourceHeader) +ON_COMMAND (ID_VIEW_TOGGLE_SRC_HDR, OnToggleSourceHeader) +ON_UPDATE_COMMAND_UI (ID_VIEW_SELMARGIN, OnUpdateSelMargin) +ON_COMMAND (ID_VIEW_SELMARGIN, OnSelMargin) +ON_UPDATE_COMMAND_UI (ID_VIEW_WORDWRAP, OnUpdateWordWrap) +ON_COMMAND (ID_VIEW_WORDWRAP, OnWordWrap) +ON_COMMAND (ID_FORCE_REDRAW, OnForceRedraw) + //BEGIN SW + // incremental search + ON_COMMAND(ID_EDIT_FIND_INCREMENTAL_FORWARD, OnEditFindIncrementalForward) + ON_COMMAND(ID_EDIT_FIND_INCREMENTAL_BACKWARD, OnEditFindIncrementalBackward) + ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_INCREMENTAL_FORWARD, OnUpdateEditFindIncrementalForward) + ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_INCREMENTAL_BACKWARD, OnUpdateEditFindIncrementalBackward) + //END SW +END_MESSAGE_MAP () + +#define EXPAND_PRIMITIVE(impl, func) \ +void CCrystalTextView::On##func() { impl(FALSE); } \ +void CCrystalTextView::OnExt##func() { impl(TRUE); } +EXPAND_PRIMITIVE (MoveLeft, CharLeft) +EXPAND_PRIMITIVE (MoveRight, CharRight) +EXPAND_PRIMITIVE (MoveWordLeft, WordLeft) +EXPAND_PRIMITIVE (MoveWordRight, WordRight) +EXPAND_PRIMITIVE (MoveUp, LineUp) +EXPAND_PRIMITIVE (MoveDown, LineDown) +EXPAND_PRIMITIVE (MovePgUp, PageUp) +EXPAND_PRIMITIVE (MovePgDn, PageDown) +EXPAND_PRIMITIVE (MoveHome, Home) +EXPAND_PRIMITIVE (MoveEnd, LineEnd) +EXPAND_PRIMITIVE (MoveCtrlHome, TextBegin) +EXPAND_PRIMITIVE (MoveCtrlEnd, TextEnd) +#undef EXPAND_PRIMITIVE + +CCrystalTextView::TextDefinition CCrystalTextView::m_SourceDefs[] = + { + CCrystalTextView::SRC_PLAIN, _T ("Plain"), _T ("txt,doc,diz"), CCrystalTextView::ParseLinePlain, SRCOPT_AUTOINDENT, 4, _T (""), _T (""), _T (""), (DWORD)-1, + CCrystalTextView::SRC_ASP, _T ("ASP"), _T ("asp"), CCrystalTextView::ParseLineAsp, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T (""), _T (""), _T ("'"), (DWORD)-1, + CCrystalTextView::SRC_BASIC, _T ("Basic"), _T ("bas,vb,vbs,frm,dsm"), CCrystalTextView::ParseLineBasic, SRCOPT_AUTOINDENT, 4, _T (""), _T (""), _T ("\'"), (DWORD)-1, + CCrystalTextView::SRC_BATCH, _T ("Batch"), _T ("bat,btm,cmd"), CCrystalTextView::ParseLineBatch, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT, 4, _T (""), _T (""), _T ("rem "), (DWORD)-1, + CCrystalTextView::SRC_C, _T ("C"), _T ("c,cc,cpp,cxx,h,hpp.hxx,hm,inl,rh,tlh,tli,xs"), CCrystalTextView::ParseLineC, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_DCL, _T ("DCL"), _T ("dcl,dcc"), CCrystalTextView::ParseLineDcl, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_FORTRAN, _T ("Fortran"), _T ("f,f90,f9p,fpp"), CCrystalTextView::ParseLineFortran, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT, 8, _T (""), _T (""), _T ("!"), (DWORD)-1, + CCrystalTextView::SRC_HTML, _T ("HTML"), _T ("html,htm,shtml,ihtml,ssi"), CCrystalTextView::ParseLineHtml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, 2, _T (""), _T (""), (DWORD)-1, + CCrystalTextView::SRC_INSTALLSHIELD, _T ("InstallShield"), _T ("rul"), CCrystalTextView::ParseLineIS, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_JAVA, _T ("Java"), _T ("java,jav,js"), CCrystalTextView::ParseLineJava, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_LISP, _T ("AutoLISP"), _T ("lsp"), CCrystalTextView::ParseLineLisp, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, 2, _T (";|"), _T ("|;"), _T (";"), (DWORD)-1, + CCrystalTextView::SRC_PASCAL, _T ("Pascal"), _T ("pas"), CCrystalTextView::ParseLinePascal, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("{"), _T ("}"), _T (""), (DWORD)-1, + CCrystalTextView::SRC_PERL, _T ("Perl"), _T ("pl"), CCrystalTextView::ParseLinePerl, SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, 4, _T (""), _T (""), _T ("#"), (DWORD)-1, + CCrystalTextView::SRC_PHP, _T ("PHP"), _T ("php,php3,php4"), CCrystalTextView::ParseLinePhp, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_PYTHON, _T ("Python"), _T ("py"), CCrystalTextView::ParseLinePython, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_REXX, _T ("REXX"), _T ("rex,rexx,cmd"), CCrystalTextView::ParseLineRexx, SRCOPT_AUTOINDENT, 4, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_RSRC, _T ("Resources"), _T ("rc,dlg"), CCrystalTextView::ParseLineRsrc, SRCOPT_AUTOINDENT, 4, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_SGML, _T ("Sgml"), _T ("sgml"), CCrystalTextView::ParseLineSgml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, 2, _T (""), _T (""), (DWORD)-1, + CCrystalTextView::SRC_SH, _T ("Shell"), _T ("sh,conf"), CCrystalTextView::ParseLineSh, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, 4, _T (""), _T (""), _T ("#"), (DWORD)-1, + CCrystalTextView::SRC_SIOD, _T ("SIOD"), _T ("scm"), CCrystalTextView::ParseLineSiod, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, 2, _T (";|"), _T ("|;"), _T (";"), (DWORD)-1, + CCrystalTextView::SRC_SQL, _T ("SQL"), _T ("sql"), CCrystalTextView::ParseLineSql, SRCOPT_AUTOINDENT, 4, _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1, + CCrystalTextView::SRC_TCL, _T ("TCL"), _T ("tcl"), CCrystalTextView::ParseLineTcl, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU|SRCOPT_EOLNUNIX, 2, _T (""), _T (""), _T ("#"), (DWORD)-1, + CCrystalTextView::SRC_TEX, _T ("TEX"), _T ("tex,sty,cls,clo,ltx,fd,dtx"), CCrystalTextView::ParseLineTex, SRCOPT_AUTOINDENT, 4, _T (""), _T (""), _T ("%"), (DWORD)-1 + }; + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextView construction/destruction + +BOOL +MatchType (CString pattern, LPCTSTR lpszExt) +{ + CString part; + int pos, len = pattern.GetLength (); + + while ((pos = pattern.Find (_T (','))) != -1) + { + part = pattern.Left (pos); + if (!part.IsEmpty () && fpattern_isvalid (part)) + { + if (fpattern_matchn (part, lpszExt)) + { + return TRUE; + } + } + len -= pos + 1; + pattern = pattern.Right (len); + } + if (!pattern.IsEmpty () && fpattern_isvalid (pattern)) + { + if (fpattern_matchn (pattern, lpszExt)) + { + return TRUE; + } + } + return FALSE; +} + +bool CCrystalTextView:: +DoSetTextType (TextDefinition *def) +{ + m_CurSourceDef = def; + SetFlags (def->flags); + SetWordWrapping ((def->flags & SRCOPT_WORDWRAP) != FALSE); + SetSelectionMargin ((def->flags & SRCOPT_SELMARGIN) != FALSE); + SetTabSize (def->tabsize); + SetViewTabs ((def->flags & SRCOPT_SHOWTABS) != FALSE); + int nEoln; + if (def->flags & SRCOPT_EOLNDOS) + { + nEoln = 0; + } + else if (def->flags & SRCOPT_EOLNUNIX) + { + nEoln = 1; + } + else if (def->flags & SRCOPT_EOLNMAC) + { + nEoln = 2; + } + else /* eoln auto */ + { + nEoln = -1; + } + SetCRLFMode (nEoln); + return true; +} + +CCrystalTextView::TextDefinition* CCrystalTextView:: +GetTextType (LPCTSTR pszExt) +{ + TextDefinition *def; + CString sExt = pszExt; + + def = CCrystalTextView::m_SourceDefs; + sExt.MakeLower (); + for (int i = 0; i < countof (CCrystalTextView::m_SourceDefs); i++, def++) + if (MatchType (def->exts, sExt)) + return def; + return NULL; +} + +bool CCrystalTextView:: +SetTextType (LPCTSTR pszExt) +{ + m_CurSourceDef = m_SourceDefs; + + TextDefinition *def = GetTextType (pszExt); + + return SetTextType (def); +} + +bool CCrystalTextView:: +SetTextType (CCrystalTextView::TextType enuType) +{ + TextDefinition *def; + + m_CurSourceDef = def = m_SourceDefs; + for (int i = 0; i < countof (m_SourceDefs); i++, def++) + { + if (def->type == enuType) + { + return SetTextType (def); + } + } + return false; +} + +bool CCrystalTextView:: +SetTextType (CCrystalTextView::TextDefinition *def) +{ + if (def) + if (m_CurSourceDef != def) + return DoSetTextType (def); + else + return true; + return false; +} + +void CCrystalTextView:: +LoadSettings () +{ + TextDefinition *def = m_SourceDefs; + bool bFontLoaded; + CReg reg; + if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ)) + { + reg.LoadNumber (_T ("DefaultEncoding"), (DWORD*) &CCrystalTextBuffer::m_nDefaultEncoding); + for (int i = 0; i < countof (m_SourceDefs); i++, def++) + { + CReg reg1; + if (reg1.Open (reg.hKey, def->name, KEY_READ)) + { + reg1.LoadString (_T ("Extensions"), def->exts, countof (def->exts)); + reg1.LoadNumber (_T ("Flags"), &def->flags); + reg1.LoadNumber (_T ("TabSize"), &def->tabsize); + reg1.LoadString (_T ("OpenComment"), def->opencomment, countof (def->opencomment)); + reg1.LoadString (_T ("CloseComment"), def->closecomment, countof (def->closecomment)); + reg1.LoadString (_T ("CommentLine"), def->commentline, countof (def->commentline)); + reg1.LoadNumber (_T ("DefaultEncoding"), &def->encoding); + } + } + bFontLoaded = reg.LoadBinary (_T ("LogFont"), (LPBYTE) &m_LogFont, sizeof (m_LogFont)); + } + else + bFontLoaded = false; + if (!bFontLoaded) + { + CWindowDC dc (CWnd::GetDesktopWindow ()); + NONCLIENTMETRICS info; + info.cbSize = sizeof(info); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + memcpy (&m_LogFont, &info.lfMessageFont, sizeof (LOGFONT)); + m_LogFont.lfHeight = -MulDiv (11, dc.GetDeviceCaps (LOGPIXELSY), 72); + m_LogFont.lfWeight = FW_NORMAL; + m_LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + m_LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + m_LogFont.lfQuality = DEFAULT_QUALITY; + m_LogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + _tcscpy (m_LogFont.lfFaceName, _T ("Courier New")); + } +} + +void CCrystalTextView:: +SaveSettings () +{ + TextDefinition *def = m_SourceDefs; + CReg reg; + if (reg.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE)) + { + VERIFY (reg.SaveNumber (_T ("DefaultEncoding"), (DWORD) CCrystalTextBuffer::m_nDefaultEncoding)); + for (int i = 0; i < countof (m_SourceDefs); i++, def++) + { + CReg reg1; + if (reg1.Create (reg.hKey, def->name, KEY_WRITE)) + { + VERIFY (reg1.SaveString (_T ("Extensions"), def->exts)); + VERIFY (reg1.SaveNumber (_T ("Flags"), def->flags)); + VERIFY (reg1.SaveNumber (_T ("TabSize"), def->tabsize)); + VERIFY (reg1.SaveString (_T ("OpenComment"), def->opencomment)); + VERIFY (reg1.SaveString (_T ("CloseComment"), def->closecomment)); + VERIFY (reg1.SaveString (_T ("CommentLine"), def->commentline)); + VERIFY (reg1.SaveNumber (_T ("DefaultEncoding"), def->encoding)); + } + } + VERIFY (reg.SaveBinary (_T ("LogFont"), (LPBYTE) &m_LogFont, sizeof (m_LogFont))); + } +} + +CCrystalTextView::CCrystalTextView () +{ + AFX_ZERO_INIT_OBJECT (CView); + m_rxnode = NULL; + m_pszMatched = NULL; + m_bSelMargin = TRUE; + m_bWordWrap = FALSE; + //BEGIN SW + m_panSubLines = new CArray(); + ASSERT( m_panSubLines ); + m_panSubLines->SetSize( 0, 4096 ); + + m_pstrIncrementalSearchString = new CString; + ASSERT( m_pstrIncrementalSearchString ); + m_pstrIncrementalSearchStringOld = new CString; + ASSERT( m_pstrIncrementalSearchStringOld ); + //END SW + ResetView (); + SetTextType (SRC_PLAIN); + m_bSingle = false; // needed to be set in descendat classes + m_bRememberLastPos = false; +} + +CCrystalTextView::~CCrystalTextView () +{ + ASSERT (m_hAccel == NULL); + ASSERT (m_pCacheBitmap == NULL); + ASSERT (m_pTextBuffer == NULL); // Must be correctly detached + + if (m_pszLastFindWhat != NULL) + { + free (m_pszLastFindWhat); + m_pszLastFindWhat=NULL; + } + if (m_pdwParseCookies != NULL) + { + delete m_pdwParseCookies; + m_pdwParseCookies = NULL; + } + if (m_pnActualLineLength != NULL) + { + delete m_pnActualLineLength; + m_pnActualLineLength = NULL; + } + if (m_rxnode) + { + RxFree (m_rxnode); + m_rxnode = NULL; + } + if (m_pszMatched) + { + delete m_pszMatched; + m_pszMatched = NULL; + } + //BEGIN SW + if( m_panSubLines ) + { + delete m_panSubLines; + m_panSubLines = NULL; + } + if( m_pstrIncrementalSearchString ) + { + delete m_pstrIncrementalSearchString; + m_pstrIncrementalSearchString = NULL; + } + if( m_pstrIncrementalSearchStringOld ) + { + delete m_pstrIncrementalSearchStringOld; + m_pstrIncrementalSearchStringOld = NULL; + } + //END SW +} + +BOOL CCrystalTextView:: +PreCreateWindow (CREATESTRUCT & cs) +{ + CWnd *pParentWnd = CWnd::FromHandlePermanent (cs.hwndParent); + if (pParentWnd == NULL || !pParentWnd->IsKindOf (RUNTIME_CLASS (CSplitterWnd))) + { + // View must always create its own scrollbars, + // if only it's not used within splitter + //BEGIN SW + if( m_bWordWrap ) + // we do not need a horizontal scroll bar, if we wrap the lines + cs.style|= WS_VSCROLL; + else + cs.style |= (WS_HSCROLL | WS_VSCROLL); + /*ORIGINAL + cs.style |= (WS_HSCROLL | WS_VSCROLL); + */ + //END SW + } + cs.lpszClass = AfxRegisterWndClass (CS_DBLCLKS); + return CView::PreCreateWindow (cs); +} + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextView drawing + +void CCrystalTextView:: +GetSelection (CPoint & ptStart, CPoint & ptEnd) +{ + PrepareSelBounds (); + ptStart = m_ptDrawSelStart; + ptEnd = m_ptDrawSelEnd; +} + +CCrystalTextBuffer *CCrystalTextView:: +LocateTextBuffer () +{ + return NULL; +} + +int CCrystalTextView:: +GetLineActualLength (int nLineIndex) +{ + int nLineCount = GetLineCount (); + ASSERT (nLineCount > 0); + ASSERT (nLineIndex >= 0 && nLineIndex < nLineCount); + if (m_pnActualLineLength == NULL) + { + m_pnActualLineLength = new int[nLineCount]; + memset (m_pnActualLineLength, 0xff, sizeof (int) * nLineCount); + m_nActualLengthArraySize = nLineCount; + } + + if (m_pnActualLineLength[nLineIndex] >= 0) + return m_pnActualLineLength[nLineIndex]; + + // Actual line length is not determined yet, let's calculate a little + int nActualLength = 0; + int nLength = GetLineLength (nLineIndex); + if (nLength > 0) + { + LPCTSTR pszLine = GetLineChars (nLineIndex); + LPTSTR pszChars = (LPTSTR) _alloca (sizeof (TCHAR) * (nLength + 1)); + memcpy (pszChars, pszLine, sizeof (TCHAR) * nLength); + pszChars[nLength] = 0; + LPTSTR pszCurrent = pszChars; + + int nTabSize = GetTabSize (); + for (;;) + { + LPTSTR psz = _tcschr (pszCurrent, _T('\t')); + if (psz == NULL) + { + nActualLength += (pszChars + nLength - pszCurrent); + break; + } + + nActualLength += (psz - pszCurrent); + nActualLength += (nTabSize - nActualLength % nTabSize); + pszCurrent = psz + 1; + } + } + + m_pnActualLineLength[nLineIndex] = nActualLength; + return nActualLength; +} + +void CCrystalTextView:: +ScrollToChar (int nNewOffsetChar, BOOL bNoSmoothScroll /*= FALSE*/ , BOOL bTrackScrollBar /*= TRUE*/ ) +{ + //BEGIN SW + // no horizontal scrolling, when word wrapping is enabled + if( m_bWordWrap ) + return; + //END SW + + // For now, ignoring bNoSmoothScroll and m_bSmoothScroll + if (m_nOffsetChar != nNewOffsetChar) + { + int nScrollChars = m_nOffsetChar - nNewOffsetChar; + m_nOffsetChar = nNewOffsetChar; + CRect rcScroll; + GetClientRect (&rcScroll); + rcScroll.left += GetMarginWidth (); + ScrollWindow (nScrollChars * GetCharWidth (), 0, &rcScroll, &rcScroll); + UpdateWindow (); + if (bTrackScrollBar) + RecalcHorzScrollBar (TRUE); + } +} + +//BEGIN SW +void CCrystalTextView::ScrollToSubLine( int nNewTopSubLine, + BOOL bNoSmoothScroll /*= FALSE*/, BOOL bTrackScrollBar /*= TRUE*/ ) +{ + if (m_nTopSubLine != nNewTopSubLine) + { + if (bNoSmoothScroll || ! m_bSmoothScroll) + { + int nScrollLines = m_nTopSubLine - nNewTopSubLine; + m_nTopSubLine = nNewTopSubLine; + ScrollWindow(0, nScrollLines * GetLineHeight()); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + else + { + // Do smooth scrolling + int nLineHeight = GetLineHeight(); + if (m_nTopSubLine > nNewTopSubLine) + { + int nIncrement = (m_nTopSubLine - nNewTopSubLine) / SMOOTH_SCROLL_FACTOR + 1; + while (m_nTopSubLine != nNewTopSubLine) + { + int nTopSubLine = m_nTopSubLine - nIncrement; + if (nTopSubLine < nNewTopSubLine) + nTopSubLine = nNewTopSubLine; + int nScrollLines = nTopSubLine - m_nTopSubLine; + m_nTopSubLine = nTopSubLine; + ScrollWindow(0, - nLineHeight * nScrollLines); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + } + else + { + int nIncrement = (nNewTopSubLine - m_nTopSubLine) / SMOOTH_SCROLL_FACTOR + 1; + while (m_nTopSubLine != nNewTopSubLine) + { + int nTopSubLine = m_nTopSubLine + nIncrement; + if (nTopSubLine > nNewTopSubLine) + nTopSubLine = nNewTopSubLine; + int nScrollLines = nTopSubLine - m_nTopSubLine; + m_nTopSubLine = nTopSubLine; + ScrollWindow(0, - nLineHeight * nScrollLines); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + } + } + int nDummy; + GetLineBySubLine( m_nTopSubLine, m_nTopLine, nDummy ); + InvalidateRect( NULL ); // repaint whole window + } +} + +/*void CCrystalTextView::GoToLine( int nLine ) +{ + SetCursorPos( CPoint( 0, (nLine > 0)? nLine - 1 : 0 ) ); + EnsureVisible( GetCursorPos() ); +}*/ +//END SW + +void CCrystalTextView:: +ScrollToLine (int nNewTopLine, BOOL bNoSmoothScroll /*= FALSE*/ , BOOL bTrackScrollBar /*= TRUE*/ ) +{ + //BEGIN SW + if( m_nTopLine != nNewTopLine ) + ScrollToSubLine( GetSubLineIndex( nNewTopLine ), bNoSmoothScroll, bTrackScrollBar ); + + /*ORIGINAL + if (m_nTopLine != nNewTopLine) + { + if (bNoSmoothScroll || ! m_bSmoothScroll) + { + int nScrollLines = m_nTopLine - nNewTopLine; + m_nTopLine = nNewTopLine; + ScrollWindow(0, nScrollLines * GetLineHeight()); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + else + { + // Do smooth scrolling + int nLineHeight = GetLineHeight(); + if (m_nTopLine > nNewTopLine) + { + int nIncrement = (m_nTopLine - nNewTopLine) / SMOOTH_SCROLL_FACTOR + 1; + while (m_nTopLine != nNewTopLine) + { + int nTopLine = m_nTopLine - nIncrement; + if (nTopLine < nNewTopLine) + nTopLine = nNewTopLine; + int nScrollLines = nTopLine - m_nTopLine; + m_nTopLine = nTopLine; + ScrollWindow(0, - nLineHeight * nScrollLines); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + } + else + { + int nIncrement = (nNewTopLine - m_nTopLine) / SMOOTH_SCROLL_FACTOR + 1; + while (m_nTopLine != nNewTopLine) + { + int nTopLine = m_nTopLine + nIncrement; + if (nTopLine > nNewTopLine) + nTopLine = nNewTopLine; + int nScrollLines = nTopLine - m_nTopLine; + m_nTopLine = nTopLine; + ScrollWindow(0, - nLineHeight * nScrollLines); + UpdateWindow(); + if (bTrackScrollBar) + RecalcVertScrollBar(TRUE); + } + } + } + } + *///END SW +} + +void CCrystalTextView:: +ExpandChars (LPCTSTR pszChars, int nOffset, int nCount, CString & line) +{ + if (nCount <= 0) + { + line = _T (""); + return; + } + + int nTabSize = GetTabSize (); + + int nActualOffset = 0; + for (int I = 0; I < nOffset; I++) + { + if (pszChars[I] == _T ('\t')) + nActualOffset += (nTabSize - nActualOffset % nTabSize); + else + nActualOffset++; + } + + pszChars += nOffset; + int nLength = nCount; + + int nTabCount = 0; + for (I = 0; I < nLength; I++) + { + if (pszChars[I] == _T ('\t')) + nTabCount++; + } + + LPTSTR pszBuf = line.GetBuffer (nLength + nTabCount * (nTabSize - 1) + 1); + int nCurPos = 0; + if (nTabCount > 0 || m_bViewTabs) + { + for (I = 0; I < nLength; I++) + { + if (pszChars[I] == _T ('\t')) + { + int nSpaces = nTabSize - (nActualOffset + nCurPos) % nTabSize; + if (m_bViewTabs) + { + pszBuf[nCurPos++] = TAB_CHARACTER; + nSpaces--; + } + while (nSpaces > 0) + { + pszBuf[nCurPos++] = _T (' '); + nSpaces--; + } + } + else + { + if (pszChars[I] == _T (' ') && m_bViewTabs) + pszBuf[nCurPos] = SPACE_CHARACTER; + else + pszBuf[nCurPos] = pszChars[I]; + nCurPos++; + } + } + } + else + { + memcpy (pszBuf, pszChars, sizeof (TCHAR) * nLength); + nCurPos = nLength; + } + pszBuf[nCurPos] = 0; + line.ReleaseBuffer (); +} + +void CCrystalTextView:: +DrawLineHelperImpl (CDC * pdc, CPoint & ptOrigin, const CRect & rcClip, + LPCTSTR pszChars, int nOffset, int nCount) +{ + ASSERT (nCount >= 0); + if (nCount > 0) + { + CString line; + ExpandChars (pszChars, nOffset, nCount, line); + int nWidth = rcClip.right - ptOrigin.x; + if (nWidth > 0) + { + int nCharWidth = GetCharWidth (); + int nCount = line.GetLength (); + int nCountFit = nWidth / nCharWidth + 1; + if (nCount > nCountFit) + nCount = nCountFit; +#ifdef _DEBUG + //CSize sz = pdc->GetTextExtent(line, nCount); + //ASSERT(sz.cx == m_nCharWidth * nCount); +#endif + /* + CRect rcBounds = rcClip; + rcBounds.left = ptOrigin.x; + rcBounds.right = rcBounds.left + GetCharWidth() * nCount; + pdc->ExtTextOut(rcBounds.left, rcBounds.top, ETO_OPAQUE, &rcBounds, NULL, 0, NULL); + */ + VERIFY (pdc->ExtTextOut (ptOrigin.x, ptOrigin.y, ETO_CLIPPED, &rcClip, line, nCount, NULL)); + } + ptOrigin.x += GetCharWidth () * line.GetLength (); + } +} + +void CCrystalTextView:: +DrawLineHelper (CDC * pdc, CPoint & ptOrigin, const CRect & rcClip, int nColorIndex, + LPCTSTR pszChars, int nOffset, int nCount, CPoint ptTextPos) +{ + if (nCount > 0) + { + if (m_bFocused || m_bShowInactiveSelection) + { + int nSelBegin = 0, nSelEnd = 0; + if (m_ptDrawSelStart.y > ptTextPos.y) + { + nSelBegin = nCount; + } + else if (m_ptDrawSelStart.y == ptTextPos.y) + { + nSelBegin = m_ptDrawSelStart.x - ptTextPos.x; + if (nSelBegin < 0) + nSelBegin = 0; + if (nSelBegin > nCount) + nSelBegin = nCount; + } + if (m_ptDrawSelEnd.y > ptTextPos.y) + { + nSelEnd = nCount; + } + else if (m_ptDrawSelEnd.y == ptTextPos.y) + { + nSelEnd = m_ptDrawSelEnd.x - ptTextPos.x; + if (nSelEnd < 0) + nSelEnd = 0; + if (nSelEnd > nCount) + nSelEnd = nCount; + } + + ASSERT (nSelBegin >= 0 && nSelBegin <= nCount); + ASSERT (nSelEnd >= 0 && nSelEnd <= nCount); + ASSERT (nSelBegin <= nSelEnd); + + // Draw part of the text before selection + if (nSelBegin > 0) + { + DrawLineHelperImpl (pdc, ptOrigin, rcClip, pszChars, nOffset, nSelBegin); + } + if (nSelBegin < nSelEnd) + { + COLORREF crOldBk = pdc->SetBkColor (GetColor (COLORINDEX_SELBKGND)); + COLORREF crOldText = pdc->SetTextColor (GetColor (COLORINDEX_SELTEXT)); + DrawLineHelperImpl (pdc, ptOrigin, rcClip, pszChars, nOffset + nSelBegin, nSelEnd - nSelBegin); + pdc->SetBkColor (crOldBk); + pdc->SetTextColor (crOldText); + } + if (nSelEnd < nCount) + { + DrawLineHelperImpl (pdc, ptOrigin, rcClip, pszChars, nOffset + nSelEnd, nCount - nSelEnd); + } + } + else + { + DrawLineHelperImpl (pdc, ptOrigin, rcClip, pszChars, nOffset, nCount); + } + } +} + +void CCrystalTextView:: +GetLineColors (int nLineIndex, COLORREF & crBkgnd, + COLORREF & crText, BOOL & bDrawWhitespace) +{ + DWORD dwLineFlags = GetLineFlags (nLineIndex); + bDrawWhitespace = TRUE; + crText = RGB (255, 255, 255); + if (dwLineFlags & LF_EXECUTION) + { + crBkgnd = RGB (0, 128, 0); + return; + } + if (dwLineFlags & LF_BREAKPOINT) + { + crBkgnd = RGB (255, 0, 0); + return; + } + if (dwLineFlags & LF_INVALID_BREAKPOINT) + { + crBkgnd = RGB (128, 128, 0); + return; + } + if (dwLineFlags & LF_DIFF) + { + crBkgnd = RGB(255,255,92); + return; + } + if (dwLineFlags & LF_DELETED) + { + crBkgnd = RGB(192,192,192); + return; + } + crBkgnd = CLR_NONE; + crText = CLR_NONE; + bDrawWhitespace = FALSE; +} + +DWORD CCrystalTextView:: +GetParseCookie (int nLineIndex) +{ + int nLineCount = GetLineCount (); + if (m_pdwParseCookies == NULL) + { + m_nParseArraySize = nLineCount; + m_pdwParseCookies = new DWORD[nLineCount]; + memset (m_pdwParseCookies, 0xff, nLineCount * sizeof (DWORD)); + } + + if (nLineIndex < 0) + return 0; + if (m_pdwParseCookies[nLineIndex] != (DWORD) - 1) + return m_pdwParseCookies[nLineIndex]; + + int L = nLineIndex; + while (L >= 0 && m_pdwParseCookies[L] == (DWORD) - 1) + L--; + L++; + + int nBlocks; + while (L <= nLineIndex) + { + DWORD dwCookie = 0; + if (L > 0) + dwCookie = m_pdwParseCookies[L - 1]; + ASSERT (dwCookie != (DWORD) - 1); + m_pdwParseCookies[L] = ParseLine (dwCookie, L, NULL, nBlocks); + ASSERT (m_pdwParseCookies[L] != (DWORD) - 1); + L++; + } + + return m_pdwParseCookies[nLineIndex]; +} + +//BEGIN SW +void CCrystalTextView::WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ) +{ + // There must be a parser attached to this view + if( !m_pParser ) + return; + + m_pParser->WrapLine( nLineIndex, nMaxLineWidth, anBreaks, nBreaks ); +} + + +void CCrystalTextView::WrapLineCached( + int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ) +{ + // if word wrap is not active, there is not any break in the line + if( !m_bWordWrap ) + { + nBreaks = 0; + return; + } + + // word wrap is active + if( nLineIndex < m_panSubLines->GetSize() && !anBreaks && (*m_panSubLines)[nLineIndex] > -1 ) + // return cached data + nBreaks = (*m_panSubLines)[nLineIndex] - 1; + else + { + // recompute line wrap + nBreaks = 0; + WrapLine( nLineIndex, nMaxLineWidth, anBreaks, nBreaks ); + + // cache data + ASSERT( nBreaks > -1 ); + m_panSubLines->SetAtGrow( nLineIndex, nBreaks + 1 ); + + // RecalcVertScrollBar(); + } +} + + +void CCrystalTextView::InvalidateLineCache( int nLineIndex1, int nLineIndex2 /*= -1*/ ) +{ + // invalidate cached sub line count + + if( nLineIndex2 == -1 && nLineIndex1 < m_panSubLines->GetSize() ) + for( int i = nLineIndex1; i < m_panSubLines->GetSize(); i++ ) + (*m_panSubLines)[i] = -1; + else + { + if( nLineIndex1 > nLineIndex2 ) + { + int nStorage = nLineIndex1; + nLineIndex1 = nLineIndex2; + nLineIndex2 = nStorage; + } + + if( nLineIndex1 >= m_panSubLines->GetSize() ) + return; + + if( nLineIndex2 >= m_panSubLines->GetSize() ) + nLineIndex2 = m_panSubLines->GetUpperBound(); + + for( int i = nLineIndex1; i <= nLineIndex2; i++ ) + if( i >= 0 && i < m_panSubLines->GetSize() ) + (*m_panSubLines)[i] = -1; + } +} + + +void CCrystalTextView::DrawScreenLine( CDC *pdc, CPoint &ptOrigin, const CRect &rcClip, + TEXTBLOCK *pBuf, int nBlocks, int &nActualItem, + COLORREF crText, COLORREF crBkgnd, BOOL bDrawWhitespace, + LPCTSTR pszChars, + int nOffset, int nCount, CPoint ptTextPos ) +{ + CPoint originalOrigin = ptOrigin; + CRect frect = rcClip; + int nLength = GetLineLength( ptTextPos.y ); + + frect.top = ptOrigin.y; + frect.bottom = frect.top + GetLineHeight(); + + ASSERT( nActualItem < nBlocks ); + + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(pBuf[nActualItem].m_nColorIndex)); + pdc->SelectObject( + GetFont(GetItalic(pBuf[nActualItem].m_nColorIndex), + GetBold(pBuf[nActualItem].m_nColorIndex))); + + if( nBlocks > 0 && nActualItem < nBlocks - 1 && + pBuf[nActualItem + 1].m_nCharPos >= nOffset && + pBuf[nActualItem + 1].m_nCharPos <= nOffset + nCount ) + { + ASSERT(pBuf[nActualItem].m_nCharPos >= 0 && pBuf[nActualItem].m_nCharPos <= nLength); + + /* + pdc->SelectObject(GetFont(GetItalic(COLORINDEX_NORMALTEXT), GetBold(COLORINDEX_NORMALTEXT))); + DrawLineHelper( + pdc, ptOrigin, rcClip, pBuf[nActualItem].m_nColorIndex, pszChars, + nOffset, pBuf[nActualItem].m_nCharPos, ptTextPos); + */ + for (int I = nActualItem; I < nBlocks - 1 && pBuf[I + 1].m_nCharPos <= nOffset + nCount; I ++) + { + ASSERT(pBuf[I].m_nCharPos >= 0 && pBuf[I].m_nCharPos <= nLength); + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(pBuf[I].m_nColorIndex)); + + pdc->SelectObject(GetFont(GetItalic(pBuf[I].m_nColorIndex), GetBold(pBuf[I].m_nColorIndex))); + + int nOffsetToUse = (nOffset > pBuf[I].m_nCharPos)? nOffset : pBuf[I].m_nCharPos; + DrawLineHelper(pdc, ptOrigin, rcClip, pBuf[I].m_nColorIndex, pszChars, + (nOffset > pBuf[I].m_nCharPos)? nOffset : pBuf[I].m_nCharPos, + pBuf[I + 1].m_nCharPos - nOffsetToUse, + CPoint( nOffsetToUse, ptTextPos.y )); + } + + nActualItem = I; + + ASSERT(pBuf[nActualItem].m_nCharPos >= 0 && pBuf[nActualItem].m_nCharPos <= nLength); + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(pBuf[nActualItem].m_nColorIndex)); + + pdc->SelectObject(GetFont(GetItalic(pBuf[nActualItem].m_nColorIndex), + GetBold(pBuf[nActualItem].m_nColorIndex))); + DrawLineHelper(pdc, ptOrigin, rcClip, pBuf[nActualItem].m_nColorIndex, pszChars, + pBuf[nActualItem].m_nCharPos, nOffset + nCount - pBuf[nActualItem].m_nCharPos, + CPoint(pBuf[nActualItem].m_nCharPos, ptTextPos.y)); + } + else + { + DrawLineHelper( + pdc, ptOrigin, rcClip, pBuf[nActualItem].m_nColorIndex, + pszChars, nOffset, nCount, ptTextPos); + } + + // Draw space on the right of the text + if (ptOrigin.x > frect.left) + frect.left = ptOrigin.x; + if (frect.right > frect.left) + { + if ((m_bFocused || m_bShowInactiveSelection) + && IsInsideSelBlock(CPoint(GetLineLength( ptTextPos.y ), ptTextPos.y)) + && (nOffset + nCount) == GetLineLength( ptTextPos.y ) ) + { + pdc->FillSolidRect(frect.left, frect.top, GetCharWidth(), frect.Height(), + GetColor(COLORINDEX_SELBKGND)); + frect.left += GetCharWidth(); + } + if (frect.right > frect.left) + pdc->FillSolidRect(frect, bDrawWhitespace ? crBkgnd : GetColor(COLORINDEX_WHITESPACE)); + } + + // set origin to beginning of next screen line + ptOrigin.x = originalOrigin.x; + ptOrigin.y+= GetLineHeight(); +} +//END SW + +void CCrystalTextView:: +DrawSingleLine (CDC * pdc, const CRect & rc, int nLineIndex) +{ + ASSERT (nLineIndex >= -1 && nLineIndex < GetLineCount ()); + + if (nLineIndex == -1) + { + // Draw line beyond the text + pdc->FillSolidRect (rc, GetColor (COLORINDEX_WHITESPACE)); + return; + } + + // Acquire the background color for the current line + BOOL bDrawWhitespace = FALSE; + COLORREF crBkgnd, crText; + GetLineColors (nLineIndex, crBkgnd, crText, bDrawWhitespace); + if (crBkgnd == CLR_NONE) + crBkgnd = GetColor (COLORINDEX_BKGND); + + int nLength = GetLineLength (nLineIndex); + if (nLength == 0) + { + // Draw the empty line + CRect rect = rc; + if ((m_bFocused || m_bShowInactiveSelection) && IsInsideSelBlock (CPoint (0, nLineIndex))) + { + pdc->FillSolidRect (rect.left, rect.top, GetCharWidth (), rect.Height (), GetColor (COLORINDEX_SELBKGND)); + rect.left += GetCharWidth (); + } + pdc->FillSolidRect (rect, bDrawWhitespace ? crBkgnd : GetColor (COLORINDEX_WHITESPACE)); + return; + } + + // Parse the line + LPCTSTR pszChars = GetLineChars (nLineIndex); + DWORD dwCookie = GetParseCookie (nLineIndex - 1); + TEXTBLOCK *pBuf = (TEXTBLOCK *) _alloca (sizeof (TEXTBLOCK) * nLength * 3); + int nBlocks = 0; + //BEGIN SW + // insert at least one textblock of normal color at the beginning + pBuf[0].m_nCharPos = 0; + pBuf[0].m_nColorIndex = COLORINDEX_NORMALTEXT; + nBlocks++; + //END SW + m_pdwParseCookies[nLineIndex] = ParseLine (dwCookie, nLineIndex, pBuf, nBlocks); + ASSERT (m_pdwParseCookies[nLineIndex] != (DWORD) - 1); + + //BEGIN SW + int nActualItem = 0; + + // Wrap the line + int *anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + int nBreaks = 0; + + WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks ); + //END SW + + // Draw the line text + CPoint origin (rc.left - m_nOffsetChar * GetCharWidth (), rc.top); + pdc->SetBkColor (crBkgnd); + if (crText != CLR_NONE) + pdc->SetTextColor (crText); + BOOL bColorSet = FALSE; + + //BEGIN SW + /*ORIGINAL + if (nBlocks > 0) + { + ASSERT(pBuf[0].m_nCharPos >= 0 && pBuf[0].m_nCharPos <= nLength); + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(COLORINDEX_NORMALTEXT)); + pdc->SelectObject(GetFont(GetItalic(COLORINDEX_NORMALTEXT), GetBold(COLORINDEX_NORMALTEXT))); + DrawLineHelper(pdc, origin, rc, COLORINDEX_NORMALTEXT, pszChars, 0, pBuf[0].m_nCharPos, CPoint(0, nLineIndex)); + for (int I = 0; I < nBlocks - 1; I ++) + { + ASSERT(pBuf[I].m_nCharPos >= 0 && pBuf[I].m_nCharPos <= nLength); + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(pBuf[I].m_nColorIndex)); + pdc->SelectObject(GetFont(GetItalic(pBuf[I].m_nColorIndex), GetBold(pBuf[I].m_nColorIndex))); + DrawLineHelper(pdc, origin, rc, pBuf[I].m_nColorIndex, pszChars, + pBuf[I].m_nCharPos, pBuf[I + 1].m_nCharPos - pBuf[I].m_nCharPos, + CPoint(pBuf[I].m_nCharPos, nLineIndex)); + } + ASSERT(pBuf[nBlocks - 1].m_nCharPos >= 0 && pBuf[nBlocks - 1].m_nCharPos <= nLength); + if (crText == CLR_NONE) + pdc->SetTextColor(GetColor(pBuf[nBlocks - 1].m_nColorIndex)); + pdc->SelectObject(GetFont(GetItalic(pBuf[nBlocks - 1].m_nColorIndex), + GetBold(pBuf[nBlocks - 1].m_nColorIndex))); + DrawLineHelper(pdc, origin, rc, pBuf[nBlocks - 1].m_nColorIndex, pszChars, + pBuf[nBlocks - 1].m_nCharPos, nLength - pBuf[nBlocks - 1].m_nCharPos, + CPoint(pBuf[nBlocks - 1].m_nCharPos, nLineIndex)); + } + else + */ + //END SW + + // BEGIN SW + if( nBreaks > 0 ) + { + // Draw all the screen lines of the wrapped line + ASSERT( anBreaks[0] < nLength ); + + // draw start of line to first break + DrawScreenLine( + pdc, origin, rc, + pBuf, nBlocks, nActualItem, + crText, crBkgnd, bDrawWhitespace, + pszChars, 0, anBreaks[0], CPoint( 0, nLineIndex ) ); + + // draw from first break to last break + for( int i = 0; i < nBreaks - 1; i++ ) + { + ASSERT( anBreaks[i] >= 0 && anBreaks[i] < nLength ); + DrawScreenLine( + pdc, origin, rc, + pBuf, nBlocks, nActualItem, + crText, crBkgnd, bDrawWhitespace, + pszChars, anBreaks[i], anBreaks[i + 1] - anBreaks[i], + CPoint( anBreaks[i], nLineIndex ) ); + } + + // draw from last break till end of line + DrawScreenLine( + pdc, origin, rc, + pBuf, nBlocks, nActualItem, + crText, crBkgnd, bDrawWhitespace, + pszChars, anBreaks[i], nLength - anBreaks[i], + CPoint( anBreaks[i], nLineIndex ) ); + } + else + DrawScreenLine( + pdc, origin, rc, + pBuf, nBlocks, nActualItem, + crText, crBkgnd, bDrawWhitespace, + pszChars, 0, nLength, CPoint(0, nLineIndex)); + + // Draw whitespaces to the left of the text + //BEGIN SW + // Drawing is now realized by DrawScreenLine() + /*ORIGINAL + CRect frect = rc; + if (origin.x > frect.left) + frect.left = origin.x; + if (frect.right > frect.left) + { + if ((m_bFocused || m_bShowInactiveSelection) && IsInsideSelBlock(CPoint(nLength, nLineIndex))) + { + pdc->FillSolidRect(frect.left, frect.top, GetCharWidth(), frect.Height(), + GetColor(COLORINDEX_SELBKGND)); + frect.left += GetCharWidth(); + } + if (frect.right > frect.left) + pdc->FillSolidRect(frect, bDrawWhitespace ? crBkgnd : GetColor(COLORINDEX_WHITESPACE)); + } + */ + //END SW +} + +COLORREF CCrystalTextView:: +GetColor (int nColorIndex) +{ + switch (nColorIndex) + { + case COLORINDEX_WHITESPACE : + case COLORINDEX_BKGND: + return::GetSysColor (COLOR_WINDOW); + case COLORINDEX_NORMALTEXT: + return::GetSysColor (COLOR_WINDOWTEXT); + case COLORINDEX_SELMARGIN: + return::GetSysColor (COLOR_SCROLLBAR); + case COLORINDEX_PREPROCESSOR: + return RGB (0, 128, 192); + case COLORINDEX_COMMENT: + // return RGB(128, 128, 128); + return RGB (0, 128, 0); + // [JRT]: Enabled Support For Numbers... + case COLORINDEX_NUMBER: + // return RGB(0x80, 0x00, 0x00); + return RGB (0xff, 0x00, 0x00); + // [JRT]: Support For C/C++ Operators + case COLORINDEX_OPERATOR: + // return RGB(0x00, 0x00, 0x00); + return RGB (96, 96, 96); + case COLORINDEX_KEYWORD: + return RGB (0, 0, 255); + case COLORINDEX_FUNCNAME: + return RGB (128, 0, 128); + case COLORINDEX_USER1: + return RGB (0, 0, 128); + case COLORINDEX_USER2: + return RGB (0, 128, 192); + case COLORINDEX_SELBKGND: + return RGB (0, 0, 0); + case COLORINDEX_SELTEXT: + return RGB (255, 255, 255); + } + // return RGB(255, 0, 0); + return RGB (128, 0, 0); +} + +DWORD CCrystalTextView:: +GetLineFlags (int nLineIndex) +{ + if (m_pTextBuffer == NULL) + return 0; + return m_pTextBuffer->GetLineFlags (nLineIndex); +} + +void CCrystalTextView:: +DrawMargin (CDC * pdc, const CRect & rect, int nLineIndex) +{ + if (!m_bSelMargin) + { + pdc->FillSolidRect (rect, GetColor (COLORINDEX_BKGND)); + return; + } + + pdc->FillSolidRect (rect, GetColor (COLORINDEX_SELMARGIN)); + + int nImageIndex = -1; + if (nLineIndex >= 0) + { + DWORD dwLineFlags = GetLineFlags (nLineIndex); + static const DWORD adwFlags[] = + { + LF_EXECUTION, + LF_BREAKPOINT, + LF_COMPILATION_ERROR, + LF_BOOKMARK (1), + LF_BOOKMARK (2), + LF_BOOKMARK (3), + LF_BOOKMARK (4), + LF_BOOKMARK (5), + LF_BOOKMARK (6), + LF_BOOKMARK (7), + LF_BOOKMARK (8), + LF_BOOKMARK (9), + LF_BOOKMARK (0), + LF_BOOKMARKS, + LF_INVALID_BREAKPOINT + }; + for (int I = 0; I <= sizeof (adwFlags) / sizeof (adwFlags[0]); I++) + { + if ((dwLineFlags & adwFlags[I]) != 0) + { + nImageIndex = I; + break; + } + } + } + + if (nImageIndex >= 0) + { + if (m_pIcons == NULL) + { + m_pIcons = new CImageList; + VERIFY (m_pIcons->Create (IDR_MARGIN_ICONS, 16, 16, RGB (255, 255, 255))); + } + //BEGIN SW + CPoint pt(rect.left + 2, rect.top + (GetLineHeight() - 16) / 2); + /*ORIGINAL + CPoint pt(rect.left + 2, rect.top + (rect.Height() - 16) / 2); + *///END SW + VERIFY(m_pIcons->Draw(pdc, nImageIndex, pt, ILD_TRANSPARENT)); + VERIFY (m_pIcons->Draw (pdc, nImageIndex, pt, ILD_TRANSPARENT)); + } +} + +BOOL CCrystalTextView:: +IsInsideSelBlock (CPoint ptTextPos) +{ + ASSERT_VALIDTEXTPOS (ptTextPos); + if (ptTextPos.y < m_ptDrawSelStart.y) + return FALSE; + if (ptTextPos.y > m_ptDrawSelEnd.y) + return FALSE; + if (ptTextPos.y < m_ptDrawSelEnd.y && ptTextPos.y > m_ptDrawSelStart.y) + return TRUE; + if (m_ptDrawSelStart.y < m_ptDrawSelEnd.y) + { + if (ptTextPos.y == m_ptDrawSelEnd.y) + return ptTextPos.x < m_ptDrawSelEnd.x; + ASSERT (ptTextPos.y == m_ptDrawSelStart.y); + return ptTextPos.x >= m_ptDrawSelStart.x; + } + ASSERT (m_ptDrawSelStart.y == m_ptDrawSelEnd.y); + return ptTextPos.x >= m_ptDrawSelStart.x && ptTextPos.x < m_ptDrawSelEnd.x; +} + +BOOL CCrystalTextView:: +IsInsideSelection (const CPoint & ptTextPos) +{ + PrepareSelBounds (); + return IsInsideSelBlock (ptTextPos); +} + +void CCrystalTextView:: +PrepareSelBounds () +{ + if (m_ptSelStart.y < m_ptSelEnd.y || + (m_ptSelStart.y == m_ptSelEnd.y && m_ptSelStart.x < m_ptSelEnd.x)) + { + m_ptDrawSelStart = m_ptSelStart; + m_ptDrawSelEnd = m_ptSelEnd; + } + else + { + m_ptDrawSelStart = m_ptSelEnd; + m_ptDrawSelEnd = m_ptSelStart; + } +} + +void CCrystalTextView:: +OnDraw (CDC * pdc) +{ + CRect rcClient; + GetClientRect (rcClient); + + int nLineCount = GetLineCount (); + int nLineHeight = GetLineHeight (); + PrepareSelBounds (); + + CDC cacheDC; + VERIFY (cacheDC.CreateCompatibleDC (pdc)); + if (m_pCacheBitmap == NULL) + { + m_pCacheBitmap = new CBitmap; + //BEGIN SW + VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc, rcClient.Width(), rcClient.Height())); + /*ORIGINAL + VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc, rcClient.Width(), nLineHeight)); + */ + //END SW + } + CBitmap *pOldBitmap = cacheDC.SelectObject (m_pCacheBitmap); + + CRect rcLine; + rcLine = rcClient; + rcLine.bottom = rcLine.top + nLineHeight; + CRect rcCacheMargin (0, 0, GetMarginWidth (), nLineHeight); + CRect rcCacheLine (GetMarginWidth (), 0, rcLine.Width (), nLineHeight); + //BEGIN SW + // initialize rects + int nSubLineOffset = GetSubLineIndex( m_nTopLine ) - m_nTopSubLine; + if( nSubLineOffset < 0 ) + { + rcCacheMargin.OffsetRect( 0, nSubLineOffset * nLineHeight ); + rcCacheLine.OffsetRect( 0, nSubLineOffset * nLineHeight ); + } + + int nBreaks; + int nMaxLineChars = GetScreenChars(); + //END SW + + int nCurrentLine = m_nTopLine; + while (rcLine.top < rcClient.bottom) + { + //BEGIN SW + nBreaks = 0; + if( nCurrentLine < nLineCount /*&& GetLineLength( nCurrentLine ) > nMaxLineChars*/ ) + WrapLineCached( nCurrentLine, nMaxLineChars, NULL, nBreaks ); + + rcLine.bottom = rcLine.top + (nBreaks + 1) * nLineHeight; + rcCacheLine.bottom = rcCacheLine.top + rcLine.Height(); + rcCacheMargin.bottom = rcCacheMargin.top + rcLine.Height(); + + if( rcCacheLine.top < 0 ) + rcLine.bottom+= rcCacheLine.top; + //END SW + if (nCurrentLine < nLineCount) + { + DrawMargin (&cacheDC, rcCacheMargin, nCurrentLine); + DrawSingleLine (&cacheDC, rcCacheLine, nCurrentLine); + } + else + { + DrawMargin (&cacheDC, rcCacheMargin, -1); + DrawSingleLine (&cacheDC, rcCacheLine, -1); + } + + VERIFY (pdc->BitBlt (rcLine.left, rcLine.top, rcLine.Width (), rcLine.Height (), &cacheDC, 0, 0, SRCCOPY)); + + nCurrentLine++; + //BEGIN SW + rcLine.top = rcLine.bottom; + rcCacheLine.top = 0; + rcCacheMargin.top = 0; + /*ORIGINAL + rcLine.OffsetRect(0, nLineHeight); + */ + //END SW + } + + cacheDC.SelectObject (pOldBitmap); + cacheDC.DeleteDC (); +} + +void CCrystalTextView:: +ResetView () +{ + // m_bWordWrap = FALSE; + m_nTopLine = 0; + m_nOffsetChar = 0; + m_nLineHeight = -1; + m_nCharWidth = -1; + m_nTabSize = 4; + m_nMaxLineLength = -1; + m_nScreenLines = -1; + m_nScreenChars = -1; + m_nIdealCharPos = -1; + m_ptAnchor.x = 0; + m_ptAnchor.y = 0; + if (m_pIcons != NULL) + { + delete m_pIcons; + m_pIcons = NULL; + } + for (int I = 0; I < 4; I++) + { + if (m_apFonts[I] != NULL) + { + m_apFonts[I]->DeleteObject (); + delete m_apFonts[I]; + m_apFonts[I] = NULL; + } + } + if (m_pdwParseCookies != NULL) + { + delete m_pdwParseCookies; + m_pdwParseCookies = NULL; + } + if (m_pnActualLineLength != NULL) + { + delete m_pnActualLineLength; + m_pnActualLineLength = NULL; + } + m_nParseArraySize = 0; + m_nActualLengthArraySize = 0; + m_ptCursorPos.x = 0; + m_ptCursorPos.y = 0; + m_ptSelStart = m_ptSelEnd = m_ptCursorPos; + m_bDragSelection = FALSE; + m_bVertScrollBarLocked = FALSE; + m_bHorzScrollBarLocked = FALSE; + if (::IsWindow (m_hWnd)) + UpdateCaret (); + m_bLastSearch = FALSE; + m_bShowInactiveSelection = TRUE; // FP: reverted because I like it + m_bPrintHeader = FALSE; + m_bPrintFooter = TRUE; + + m_bBookmarkExist = FALSE; // More bookmarks + + m_bMultipleSearch = FALSE; // More search + +} + +void CCrystalTextView:: +UpdateCaret () +{ + ASSERT_VALIDTEXTPOS (m_ptCursorPos); + if (m_bFocused && !m_bCursorHidden && + CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x) >= m_nOffsetChar) + { + CreateSolidCaret (2, GetLineHeight ()); + SetCaretPos (TextToClient (m_ptCursorPos)); + ShowCaret (); + } + else + { + HideCaret (); + } +} + +int CCrystalTextView:: +GetCRLFMode () +{ + if (m_pTextBuffer) + { + return m_pTextBuffer->GetCRLFMode (); + } + return -1; +} + +void CCrystalTextView:: +SetCRLFMode (int nCRLFMode) +{ + if (m_pTextBuffer) + { + m_pTextBuffer->SetCRLFMode (nCRLFMode); + } +} + +int CCrystalTextView:: +GetTabSize () +{ + ASSERT (m_nTabSize >= 0 && m_nTabSize <= 64); + return m_nTabSize; +} + +void CCrystalTextView:: +SetTabSize (int nTabSize) +{ + ASSERT (nTabSize >= 0 && nTabSize <= 64); + if (m_nTabSize != nTabSize) + { + m_nTabSize = nTabSize; + if (m_pnActualLineLength != NULL) + { + delete m_pnActualLineLength; + m_pnActualLineLength = NULL; + } + m_nActualLengthArraySize = 0; + m_nMaxLineLength = -1; + RecalcHorzScrollBar (); + Invalidate (); + UpdateCaret (); + } +} + +CFont *CCrystalTextView:: +GetFont (BOOL bItalic /*= FALSE*/ , BOOL bBold /*= FALSE*/ ) +{ + int nIndex = 0; + if (bBold) + nIndex |= 1; + if (bItalic) + nIndex |= 2; + + if (m_apFonts[nIndex] == NULL) + { + m_apFonts[nIndex] = new CFont; + if (!m_lfBaseFont.lfHeight) + { + CClientDC dc (GetDesktopWindow ()); + m_lfBaseFont.lfHeight = -MulDiv (11, dc.GetDeviceCaps (LOGPIXELSY), 72); + } + m_lfBaseFont.lfWeight = bBold && !_tcsnicmp (m_lfBaseFont.lfFaceName, _T ("Courier"), 7) ? FW_BOLD : FW_NORMAL; + m_lfBaseFont.lfItalic = (BYTE) (bItalic && !_tcsnicmp (m_lfBaseFont.lfFaceName, _T ("Courier"), 7)); + if (!m_apFonts[nIndex]->CreateFontIndirect (&m_lfBaseFont)) + { + delete m_apFonts[nIndex]; + m_apFonts[nIndex] = NULL; + return CView::GetFont (); + } + + } + return m_apFonts[nIndex]; +} + +void CCrystalTextView:: +CalcLineCharDim () +{ + CDC *pdc = GetDC (); + CFont *pOldFont = pdc->SelectObject (GetFont ()); + CSize szCharExt = pdc->GetTextExtent (_T ("X")); + m_nLineHeight = szCharExt.cy; + if (m_nLineHeight < 1) + m_nLineHeight = 1; + m_nCharWidth = szCharExt.cx; + /* + TEXTMETRIC tm; + if (pdc->GetTextMetrics(&tm)) + m_nCharWidth -= tm.tmOverhang; + */ + pdc->SelectObject (pOldFont); + ReleaseDC (pdc); +} + +int CCrystalTextView:: +GetLineHeight () +{ + if (m_nLineHeight == -1) + CalcLineCharDim (); + return m_nLineHeight; +} + +//BEGIN SW +int CCrystalTextView::GetSubLines( int nLineIndex ) +{ + /* + if( GetLineLength( nLineIndex ) <= GetScreenChars() ) + return 1; + */ + // get number of wrapped lines, this line contains of + int nBreaks = 0; + WrapLineCached( nLineIndex, GetScreenChars(), NULL, nBreaks ); + + return nBreaks + 1; +} + +int CCrystalTextView::CharPosToPoint( int nLineIndex, int nCharPos, CPoint &charPoint ) +{ + // if we do not wrap lines, y is allways 0 and x is equl to nCharPos + if( !m_bWordWrap ) + { + charPoint.x = nCharPos; + charPoint.y = 0; + } + + // calculate point out of char pos + /* + if( GetLineLength( nLineIndex ) <= GetScreenChars() ) + { + // line is not wrapped + charPoint.x = nCharPos; + charPoint.y = 0; + return 0; + } + */ + + // line is wrapped + int *anBreaks = (int*)_alloca( sizeof( int ) * GetLineLength( nLineIndex ) ); + int nBreaks = 0; + + WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks ); + + for( int i = nBreaks - 1; i >= 0 && nCharPos < anBreaks[i]; i-- ); + + charPoint.x = (i >= 0)? nCharPos - anBreaks[i] : nCharPos; + charPoint.y = i + 1; + + return (i >= 0)? anBreaks[i] : 0; +} + +int CCrystalTextView::CursorPointToCharPos( int nLineIndex, const CPoint &curPoint ) +{ + // calculate char pos out of point + int nLength = GetLineLength( nLineIndex ); + int nScreenChars = GetScreenChars(); + LPCTSTR szLine = GetLineChars( nLineIndex ); + + // wrap line + int *anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + int nBreaks = 0; + + WrapLineCached( nLineIndex, nScreenChars, anBreaks, nBreaks ); + + // find char pos that matches cursor position + int nXPos = 0; + int nYPos = 0; + int nCurPos = 0; + int nTabSize = GetTabSize(); + + for( int nIndex = 0; nIndex < nLength; nIndex++ ) + { + if( nBreaks && nIndex == anBreaks[nYPos] ) + { + nXPos = 0; + nYPos++; + } + + if (szLine[nIndex] == _T('\t')) + { + nXPos+= (nTabSize - nCurPos % nTabSize); + nCurPos+= (nTabSize - nCurPos % nTabSize); + } + else + { + nXPos++; + nCurPos++; + } + + if( nXPos > curPoint.x && nYPos == curPoint.y ) + break; + else if( nYPos > curPoint.y ) + { + nIndex--; + break; + } + } + + return nIndex; +} + +void CCrystalTextView::SubLineCursorPosToTextPos( const CPoint &subLineCurPos, CPoint &textPos ) +{ + // Get line breaks + int nSubLineOffset, nLine; + + GetLineBySubLine( subLineCurPos.y, nLine, nSubLineOffset ); + + // compute cursor-position + textPos.x = CursorPointToCharPos( nLine, CPoint( subLineCurPos.x, nSubLineOffset ) ); + textPos.y = nLine; +} + +int CCrystalTextView::SubLineEndToCharPos( int nLineIndex, int nSubLineOffset ) +{ + int nLength = GetLineLength( nLineIndex ); + + // if word wrapping is disabled, the end is equal to the length of the line -1 + if( !m_bWordWrap /*|| nLength <= GetScreenChars()*/ ) + return nLength; + + // wrap line + int *anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + int nBreaks = 0; + + WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks ); + + // if there is no break inside the line or the given subline is the last + // one in this line... + if( !nBreaks || nSubLineOffset == nBreaks ) + return nLength; + + // compute character position for end of subline + ASSERT( nSubLineOffset >= 0 && nSubLineOffset <= nBreaks ); + + return anBreaks[nSubLineOffset] - 1; +} + +int CCrystalTextView::SubLineHomeToCharPos( int nLineIndex, int nSubLineOffset ) +{ + int nLength = GetLineLength( nLineIndex ); + + // if word wrapping is disabled, the start is 0 + if( !m_bWordWrap /*|| nLength <= GetScreenChars() */|| nSubLineOffset == 0 ) + return 0; + + // wrap line + int *anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + int nBreaks = 0; + + WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks ); + + // if there is no break inside the line... + if( !nBreaks ) + return 0; + + // compute character position for end of subline + ASSERT( nSubLineOffset > 0 && nSubLineOffset <= nBreaks ); + + return anBreaks[nSubLineOffset - 1]; +} +//END SW + +int CCrystalTextView:: +GetCharWidth () +{ + if (m_nCharWidth == -1) + CalcLineCharDim (); + return m_nCharWidth; +} + +int CCrystalTextView:: +GetMaxLineLength () +{ + if (m_nMaxLineLength == -1) + { + m_nMaxLineLength = 0; + int nLineCount = GetLineCount (); + for (int I = 0; I < nLineCount; I++) + { + int nActualLength = GetLineActualLength (I); + if (m_nMaxLineLength < nActualLength) + m_nMaxLineLength = nActualLength; + } + } + return m_nMaxLineLength; +} + +CCrystalTextView *CCrystalTextView:: +GetSiblingView (int nRow, int nCol) +{ + CSplitterWnd *pSplitter = GetParentSplitter (this, FALSE); + if (pSplitter == NULL) + return NULL; + CWnd *pWnd = CWnd::FromHandlePermanent ( + ::GetDlgItem (pSplitter->m_hWnd, pSplitter->IdFromRowCol (nRow, nCol))); + if (pWnd == NULL || !pWnd->IsKindOf (RUNTIME_CLASS (CCrystalTextView))) + return NULL; + return (CCrystalTextView *) pWnd; +} + +void CCrystalTextView:: +GoToLine (int nLine, bool bRelative) +{ + int nLines = m_pTextBuffer->GetLineCount () - 1; + CPoint ptCursorPos = GetCursorPos (); + if (bRelative) + { + nLine += ptCursorPos.y; + } + if (nLine) + { + nLine--; + } + if (nLine > nLines) + { + nLine = nLines; + } + if (nLine >= 0) + { + int nChars = m_pTextBuffer->GetLineLength (nLine); + if (nChars) + { + nChars--; + } + if (ptCursorPos.x > nChars) + { + ptCursorPos.x = nChars; + } + if (ptCursorPos.x >= 0) + { + ptCursorPos.y = nLine; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetAnchor (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetCursorPos (ptCursorPos); + EnsureVisible (ptCursorPos); + } + } +} + +void CCrystalTextView:: +OnInitialUpdate () +{ + CView::OnInitialUpdate (); + CString sDoc = GetDocument ()->GetPathName (), sExt = GetExt (sDoc); + SetTextType (sExt); + AttachToBuffer (NULL); + + CSplitterWnd *pSplitter = GetParentSplitter (this, FALSE); + if (pSplitter != NULL) + { + // See CSplitterWnd::IdFromRowCol() implementation + int nRow = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) / 16; + int nCol = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) % 16; + ASSERT (nRow >= 0 && nRow < pSplitter->GetRowCount ()); + ASSERT (nCol >= 0 && nCol < pSplitter->GetColumnCount ()); + + if (nRow > 0) + { + CCrystalTextView *pSiblingView = GetSiblingView (0, nCol); + if (pSiblingView != NULL && pSiblingView != this) + { + m_nOffsetChar = pSiblingView->m_nOffsetChar; + ASSERT (m_nOffsetChar >= 0 && m_nOffsetChar <= GetMaxLineLength ()); + } + } + + if (nCol > 0) + { + CCrystalTextView *pSiblingView = GetSiblingView (nRow, 0); + if (pSiblingView != NULL && pSiblingView != this) + { + m_nTopLine = pSiblingView->m_nTopLine; + ASSERT (m_nTopLine >= 0 && m_nTopLine < GetLineCount ()); + } + } + } + SetTextType (sExt); + SetFont (m_LogFont); + if (m_bRememberLastPos && !sDoc.IsEmpty ()) + { + DWORD dwLastPos[3]; + CString sKey = REG_EDITPAD; + sKey += _T ("\\Remembered"); + CReg reg; + if (reg.Open (HKEY_CURRENT_USER, sKey, KEY_READ) && + reg.LoadBinary (sDoc, (LPBYTE) dwLastPos, sizeof (dwLastPos))) + { + CPoint ptCursorPos; + ptCursorPos.x = dwLastPos[1]; + ptCursorPos.y = dwLastPos[2]; + if (IsValidTextPosY (ptCursorPos)) + { + if (!IsValidTextPosX (ptCursorPos)) + ptCursorPos.x = 0; + ASSERT_VALIDTEXTPOS (ptCursorPos); + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + } + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextView printing + +void CCrystalTextView:: +OnPrepareDC (CDC * pDC, CPrintInfo * pInfo) +{ + CView::OnPrepareDC (pDC, pInfo); + + if (pInfo != NULL) + { + pInfo->m_bContinuePrinting = TRUE; + if (m_pnPages != NULL && (int) pInfo->m_nCurPage > m_nPrintPages) + pInfo->m_bContinuePrinting = FALSE; + } +} + +BOOL CCrystalTextView:: +OnPreparePrinting (CPrintInfo * pInfo) +{ + return DoPreparePrinting (pInfo); +} + +int CCrystalTextView:: +PrintLineHeight (CDC * pdc, int nLine) +{ + ASSERT (nLine >= 0 && nLine < GetLineCount ()); + ASSERT (m_nPrintLineHeight > 0); + int nLength = GetLineLength (nLine); + if (nLength == 0) + return m_nPrintLineHeight; + + CString line; + LPCTSTR pszChars = GetLineChars (nLine); + ExpandChars (pszChars, 0, nLength, line); + CRect rcPrintArea = m_rcPrintArea; + pdc->DrawText (line, &rcPrintArea, DT_LEFT | DT_NOPREFIX | DT_TOP | DT_WORDBREAK | DT_CALCRECT); + return rcPrintArea.Height (); +} + +void CCrystalTextView:: +GetPrintHeaderText (int nPageNum, CString & text) +{ + ASSERT (m_bPrintHeader); + text = _T (""); +} + +void CCrystalTextView:: +GetPrintFooterText (int nPageNum, CString & text) +{ + ASSERT (m_bPrintFooter); + text.Format (_T ("Page %d/%d"), nPageNum, m_nPrintPages); +} + +void CCrystalTextView:: +PrintHeader (CDC * pdc, int nPageNum) +{ + CRect rcHeader = m_rcPrintArea; + rcHeader.bottom = rcHeader.top; + rcHeader.top -= (m_nPrintLineHeight + m_nPrintLineHeight / 2); + + CString text; + GetPrintHeaderText (nPageNum, text); + if (!text.IsEmpty ()) + pdc->DrawText (text, &rcHeader, DT_CENTER | DT_NOPREFIX | DT_TOP | DT_SINGLELINE); +} + +void CCrystalTextView:: +PrintFooter (CDC * pdc, int nPageNum) +{ + CRect rcFooter = m_rcPrintArea; + rcFooter.top = rcFooter.bottom; + rcFooter.bottom += (m_nPrintLineHeight + m_nPrintLineHeight / 2); + + CString text; + GetPrintFooterText (nPageNum, text); + if (!text.IsEmpty ()) + pdc->DrawText (text, &rcFooter, DT_CENTER | DT_NOPREFIX | DT_BOTTOM | DT_SINGLELINE); +} + +void CCrystalTextView:: +RecalcPageLayouts (CDC * pdc, CPrintInfo * pInfo) +{ + m_ptPageArea = pInfo->m_rectDraw; + m_ptPageArea.NormalizeRect (); + + m_nPrintLineHeight = pdc->GetTextExtent (_T ("X")).cy; + + m_rcPrintArea = m_ptPageArea; + CSize szTopLeft, szBottomRight; + CWinApp *pApp = AfxGetApp (); + ASSERT (pApp != NULL); + szTopLeft.cx = DEFAULT_PRINT_MARGIN; + szBottomRight.cx = DEFAULT_PRINT_MARGIN; + szTopLeft.cy = DEFAULT_PRINT_MARGIN; + szBottomRight.cy = DEFAULT_PRINT_MARGIN; + CReg reg; + if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ)) + { + DWORD dwTemp; + if (reg.LoadNumber (_T ("PageLeft"), &dwTemp)) + szTopLeft.cx = dwTemp; + if (reg.LoadNumber (_T ("PageRight"), &dwTemp)) + szBottomRight.cx = dwTemp; + if (reg.LoadNumber (_T ("PageTop"), &dwTemp)) + szTopLeft.cy = dwTemp; + if (reg.LoadNumber (_T ("PageBottom"), &dwTemp)) + szBottomRight.cy = dwTemp; + } + pdc->HIMETRICtoLP (&szTopLeft); + pdc->HIMETRICtoLP (&szBottomRight); + m_rcPrintArea.left += szTopLeft.cx; + m_rcPrintArea.right -= szBottomRight.cx; + m_rcPrintArea.top += szTopLeft.cy; + m_rcPrintArea.bottom -= szBottomRight.cy; + if (m_bPrintHeader) + m_rcPrintArea.top += m_nPrintLineHeight + m_nPrintLineHeight / 2; + if (m_bPrintFooter) + m_rcPrintArea.bottom += m_nPrintLineHeight + m_nPrintLineHeight / 2; + + int nLimit = 32; + m_nPrintPages = 1; + m_pnPages = new int[nLimit]; + m_pnPages[0] = 0; + + int nLineCount = GetLineCount (); + int nLine = 1; + int y = m_rcPrintArea.top + PrintLineHeight (pdc, 0); + while (nLine < nLineCount) + { + int nHeight = PrintLineHeight (pdc, nLine); + if (y + nHeight <= m_rcPrintArea.bottom) + { + y += nHeight; + } + else + { + ASSERT (nLimit >= m_nPrintPages); + if (nLimit <= m_nPrintPages) + { + nLimit += 32; + int *pnNewPages = new int[nLimit]; + memcpy (pnNewPages, m_pnPages, sizeof (int) * m_nPrintPages); + delete m_pnPages; + m_pnPages = pnNewPages; + } + ASSERT (nLimit > m_nPrintPages); + m_pnPages[m_nPrintPages++] = nLine; + y = m_rcPrintArea.top + nHeight; + } + nLine++; + } +} + +void CCrystalTextView:: +OnBeginPrinting (CDC * pdc, CPrintInfo * pInfo) +{ + ASSERT (m_pnPages == NULL); + ASSERT (m_pPrintFont == NULL); + CFont *pDisplayFont = GetFont (); + + LOGFONT lf; + pDisplayFont->GetLogFont (&lf); + + CDC *pDisplayDC = GetDC (); + lf.lfHeight = MulDiv (lf.lfHeight, pdc->GetDeviceCaps (LOGPIXELSY), pDisplayDC->GetDeviceCaps (LOGPIXELSY) * 2); + lf.lfWidth = MulDiv (lf.lfWidth, pdc->GetDeviceCaps (LOGPIXELSX), pDisplayDC->GetDeviceCaps (LOGPIXELSX) * 2); + ReleaseDC (pDisplayDC); + + m_pPrintFont = new CFont; + if (!m_pPrintFont->CreateFontIndirect (&lf)) + { + delete m_pPrintFont; + m_pPrintFont = NULL; + return; + } + + pdc->SelectObject (m_pPrintFont); +} + +void CCrystalTextView:: +OnEndPrinting (CDC * pdc, CPrintInfo * pInfo) +{ + if (m_pPrintFont != NULL) + { + delete m_pPrintFont; + m_pPrintFont = NULL; + } + if (m_pnPages != NULL) + { + delete m_pnPages; + m_pnPages = NULL; + } + m_nPrintPages = 0; + m_nPrintLineHeight = 0; +} + +void CCrystalTextView:: +OnPrint (CDC * pdc, CPrintInfo * pInfo) +{ + if (m_pnPages == NULL) + { + RecalcPageLayouts (pdc, pInfo); + ASSERT (m_pnPages != NULL); + } + + ASSERT (pInfo->m_nCurPage >= 1 && (int) pInfo->m_nCurPage <= m_nPrintPages); + int nLine = m_pnPages[pInfo->m_nCurPage - 1]; + int nEndLine = GetLineCount (); + if ((int) pInfo->m_nCurPage < m_nPrintPages) + nEndLine = m_pnPages[pInfo->m_nCurPage]; + TRACE (_T ("Printing page %d of %d, lines %d - %d\n"), pInfo->m_nCurPage, m_nPrintPages, + nLine, nEndLine - 1); + + if (m_bPrintHeader) + PrintHeader (pdc, pInfo->m_nCurPage); + if (m_bPrintFooter) + PrintFooter (pdc, pInfo->m_nCurPage); + + int y = m_rcPrintArea.top; + for (; nLine < nEndLine; nLine++) + { + int nLineLength = GetLineLength (nLine); + if (nLineLength == 0) + { + y += m_nPrintLineHeight; + continue; + } + + CRect rcPrintRect = m_rcPrintArea; + rcPrintRect.top = y; + LPCTSTR pszChars = GetLineChars (nLine); + CString line; + ExpandChars (pszChars, 0, nLineLength, line); + y += pdc->DrawText (line, &rcPrintRect, DT_LEFT | DT_NOPREFIX | DT_TOP | DT_WORDBREAK); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextView message handlers + +int CCrystalTextView:: +GetLineCount () +{ + if (m_pTextBuffer == NULL) + return 1; // Single empty line + + int nLineCount = m_pTextBuffer->GetLineCount (); + ASSERT (nLineCount > 0); + return nLineCount; +} + +//BEGIN SW +int CCrystalTextView::GetSubLineCount() +{ + // if we do not wrap words, number of sub lines is equal to number of lines + if( !m_bWordWrap ) + return GetLineCount(); + + // calculate number of sub lines + int nLineCount = GetLineCount(); + int nSubLineCount = 0; + + for( int i = 0; i < nLineCount; i++ ) + nSubLineCount+= GetSubLines( i ); + + return nSubLineCount; +} + +int CCrystalTextView::GetSubLineIndex( int nLineIndex ) +{ + // if we do not wrap words, subline index of this line is equal to its index + if( !m_bWordWrap ) + return nLineIndex; + + // calculate subline index of the line + int nSubLineCount = 0; + + if( nLineIndex >= GetLineCount() ) + nLineIndex = GetLineCount() - 1; + + for( int i = 0; i < nLineIndex; i++ ) + nSubLineCount+= GetSubLines( i ); + + return nSubLineCount; +} + +void CCrystalTextView::GetLineBySubLine( int nSubLineIndex, int &nLine, int &nSubLine ) +{ + ASSERT( nSubLineIndex < GetSubLineCount() ); + + // if we do not wrap words, nLine is equal to nSubLineIndex and nSubLine is allways 0 + if( !m_bWordWrap ) + { + nLine = nSubLineIndex; + nSubLine = 0; + } + + // compute result + int nSubLineCount = 0; + int nLineCount = GetLineCount(); + + for( int i = 0; i < nLineCount; i++ ) + { + nSubLineCount+= GetSubLines( i ); + if( !(nSubLineCount <= nSubLineIndex) ) + break; + } + + ASSERT( i < nLineCount ); + nLine = i; + nSubLine = nSubLineIndex - (nSubLineCount - GetSubLines( i )); +} +//END SW + +int CCrystalTextView:: +GetLineLength (int nLineIndex) +{ + if (m_pTextBuffer == NULL) + return 0; + return m_pTextBuffer->GetLineLength (nLineIndex); +} + +LPCTSTR CCrystalTextView:: +GetLineChars (int nLineIndex) +{ + if (m_pTextBuffer == NULL) + return NULL; + return m_pTextBuffer->GetLineChars (nLineIndex); +} + +void CCrystalTextView:: +AttachToBuffer (CCrystalTextBuffer * pBuf /*= NULL*/ ) +{ + if (m_pTextBuffer != NULL) + m_pTextBuffer->RemoveView (this); + if (pBuf == NULL) + { + pBuf = LocateTextBuffer (); + // ... + } + m_pTextBuffer = pBuf; + if (m_pTextBuffer != NULL) + m_pTextBuffer->AddView (this); + ResetView (); + + // Init scrollbars + CScrollBar *pVertScrollBarCtrl = GetScrollBarCtrl (SB_VERT); + if (pVertScrollBarCtrl != NULL) + pVertScrollBarCtrl->EnableScrollBar (GetScreenLines () >= GetLineCount ()? + ESB_DISABLE_BOTH : ESB_ENABLE_BOTH); + CScrollBar *pHorzScrollBarCtrl = GetScrollBarCtrl (SB_HORZ); + if (pHorzScrollBarCtrl != NULL) + pHorzScrollBarCtrl->EnableScrollBar (GetScreenChars () >= GetMaxLineLength ()? + ESB_DISABLE_BOTH : ESB_ENABLE_BOTH); + + // Update scrollbars + RecalcVertScrollBar (); + RecalcHorzScrollBar (); +} + +void CCrystalTextView:: +DetachFromBuffer () +{ + if (m_pTextBuffer != NULL) + { + m_pTextBuffer->RemoveView (this); + m_pTextBuffer = NULL; + ResetView (); + } +} + +int CCrystalTextView:: +GetScreenLines () +{ + if (m_nScreenLines == -1) + { + CRect rect; + GetClientRect (&rect); + m_nScreenLines = rect.Height () / GetLineHeight (); + } + return m_nScreenLines; +} + +BOOL CCrystalTextView:: +GetItalic (int nColorIndex) +{ + return nColorIndex == COLORINDEX_COMMENT; + // return FALSE; +} + +BOOL CCrystalTextView:: +GetBold (int nColorIndex) +{ + return nColorIndex == COLORINDEX_KEYWORD; + // return FALSE; +} + +int CCrystalTextView:: +GetScreenChars () +{ + if (m_nScreenChars == -1) + { + CRect rect; + GetClientRect (&rect); + m_nScreenChars = (rect.Width () - GetMarginWidth ()) / GetCharWidth (); + } + return m_nScreenChars; +} + +void CCrystalTextView:: +OnDestroy () +{ + GetFont ()->GetLogFont (&m_lfBaseFont); + DetachFromBuffer (); + m_hAccel = NULL; + + CView::OnDestroy (); + + for (int I = 0; I < 4; I++) + { + if (m_apFonts[I] != NULL) + { + m_apFonts[I]->DeleteObject (); + delete m_apFonts[I]; + m_apFonts[I] = NULL; + } + } + if (m_pCacheBitmap != NULL) + { + delete m_pCacheBitmap; + m_pCacheBitmap = NULL; + } +} + +BOOL CCrystalTextView:: +OnEraseBkgnd (CDC * pdc) +{ + return TRUE; +} + +void CCrystalTextView:: +OnSize (UINT nType, int cx, int cy) +{ + CView::OnSize (nType, cx, cy); + + //BEGIN SW + // get char position of top left visible character with old cached word wrap + CPoint topPos; + SubLineCursorPosToTextPos( CPoint( 0, m_nTopSubLine ), topPos ); + //END SW + + if (m_pCacheBitmap != NULL) + { + m_pCacheBitmap->DeleteObject (); + delete m_pCacheBitmap; + m_pCacheBitmap = NULL; + } + m_nScreenLines = -1; + m_nScreenChars = -1; + + //BEGIN SW + // we have to recompute the line wrapping + InvalidateLineCache( 0, -1 ); + + // compute new top sub line + CPoint topSubLine; + CharPosToPoint( topPos.y, topPos.x, topSubLine ); + m_nTopSubLine = topPos.y + topSubLine.y; + + // set caret to right position + UpdateCaret(); + //END SW + + RecalcVertScrollBar (); + RecalcHorzScrollBar (); + PostMessage (WM_COMMAND, ID_FORCE_REDRAW); +} + +void CCrystalTextView:: +UpdateSiblingScrollPos (BOOL bHorz) +{ + CSplitterWnd *pSplitterWnd = GetParentSplitter (this, FALSE); + if (pSplitterWnd != NULL) + { + // See CSplitterWnd::IdFromRowCol() implementation for details + int nCurrentRow = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) / 16; + int nCurrentCol = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) % 16; + ASSERT (nCurrentRow >= 0 && nCurrentRow < pSplitterWnd->GetRowCount ()); + ASSERT (nCurrentCol >= 0 && nCurrentCol < pSplitterWnd->GetColumnCount ()); + + if (bHorz) + { + int nCols = pSplitterWnd->GetColumnCount (); + for (int nCol = 0; nCol < nCols; nCol++) + { + if (nCol != nCurrentCol) // We don't need to update ourselves + { + CCrystalTextView *pSiblingView = GetSiblingView (nCurrentRow, nCol); + if (pSiblingView != NULL) + pSiblingView->OnUpdateSibling (this, FALSE); + } + } + } + else + { + int nRows = pSplitterWnd->GetRowCount (); + for (int nRow = 0; nRow < nRows; nRow++) + { + if (nRow != nCurrentRow) // We don't need to update ourselves + { + CCrystalTextView *pSiblingView = GetSiblingView (nRow, nCurrentCol); + if (pSiblingView != NULL) + pSiblingView->OnUpdateSibling (this, FALSE); + } + } + } + + + } +} + +void CCrystalTextView:: +OnUpdateSibling (CCrystalTextView * pUpdateSource, BOOL bHorz) +{ + if (pUpdateSource != this) + { + ASSERT (pUpdateSource != NULL); + ASSERT_KINDOF (CCrystalTextView, pUpdateSource); + if (bHorz) + { + ASSERT (pUpdateSource->m_nTopLine >= 0); + ASSERT (pUpdateSource->m_nTopLine < GetLineCount ()); + if (pUpdateSource->m_nTopLine != m_nTopLine) + { + ScrollToLine (pUpdateSource->m_nTopLine, TRUE, FALSE); + UpdateCaret (); + } + } + else + { + ASSERT (pUpdateSource->m_nOffsetChar >= 0); + ASSERT (pUpdateSource->m_nOffsetChar < GetMaxLineLength ()); + if (pUpdateSource->m_nOffsetChar != m_nOffsetChar) + { + ScrollToChar (pUpdateSource->m_nOffsetChar, TRUE, FALSE); + UpdateCaret (); + } + } + } +} + +void CCrystalTextView:: +RecalcVertScrollBar (BOOL bPositionOnly /*= FALSE*/ ) +{ + SCROLLINFO si; + si.cbSize = sizeof (si); + if (bPositionOnly) + { + si.fMask = SIF_POS; + //BEGIN SW + si.nPos = m_nTopSubLine; + /*ORIGINAL + si.nPos = m_nTopLine; + */ + //END SW + } + else + { + //BEGIN SW + if( GetScreenLines() >= GetSubLineCount() && m_nTopSubLine > 0 ) + /*ORIGINAL + if (GetScreenLines() >= GetLineCount() && m_nTopLine > 0) + */ + //END SW + { + m_nTopLine = 0; + Invalidate (); + UpdateCaret (); + } + si.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE; + si.nMin = 0; + //BEGIN SW + si.nMax = GetSubLineCount() - 1; + /*ORIGINAL + si.nMax = GetLineCount() - 1; + */ + //END SW + si.nPage = GetScreenLines (); + //BEGIN SW + si.nPos = m_nTopSubLine; + /*ORIGINAL + si.nPos = m_nTopLine; + */ + //END SW + } + VERIFY (SetScrollInfo (SB_VERT, &si)); +} + +void CCrystalTextView:: +OnVScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar) +{ + CView::OnVScroll (nSBCode, nPos, pScrollBar); + + // Note we cannot use nPos because of its 16-bit nature + SCROLLINFO si; + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + VERIFY (GetScrollInfo (SB_VERT, &si)); + + //BEGIN SW + int nPageLines = GetScreenLines(); + int nSubLineCount = GetSubLineCount(); + + int nNewTopSubLine; + BOOL bDisableSmooth = TRUE; + switch (nSBCode) + { + case SB_TOP: + nNewTopSubLine = 0; + bDisableSmooth = FALSE; + break; + case SB_BOTTOM: + nNewTopSubLine = nSubLineCount - nPageLines + 1; + bDisableSmooth = FALSE; + break; + case SB_LINEUP: + nNewTopSubLine = m_nTopSubLine - 1; + break; + case SB_LINEDOWN: + nNewTopSubLine = m_nTopSubLine + 1; + break; + case SB_PAGEUP: + nNewTopSubLine = m_nTopSubLine - si.nPage + 1; + bDisableSmooth = FALSE; + break; + case SB_PAGEDOWN: + nNewTopSubLine = m_nTopSubLine + si.nPage - 1; + bDisableSmooth = FALSE; + break; + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + nNewTopSubLine = si.nTrackPos; + break; + default: + return; + } + + if (nNewTopSubLine < 0) + nNewTopSubLine = 0; + if (nNewTopSubLine >= nSubLineCount) + nNewTopSubLine = nSubLineCount - 1; + ScrollToSubLine(nNewTopSubLine, bDisableSmooth); + + /*ORIGINAL + int nPageLines = GetScreenLines(); + int nLineCount = GetLineCount(); + + int nNewTopLine; + BOOL bDisableSmooth = TRUE; + switch (nSBCode) + { + case SB_TOP: + nNewTopLine = 0; + bDisableSmooth = FALSE; + break; + case SB_BOTTOM: + nNewTopLine = nLineCount - nPageLines + 1; + bDisableSmooth = FALSE; + break; + case SB_LINEUP: + nNewTopLine = m_nTopLine - 1; + break; + case SB_LINEDOWN: + nNewTopLine = m_nTopLine + 1; + break; + case SB_PAGEUP: + nNewTopLine = m_nTopLine - si.nPage + 1; + bDisableSmooth = FALSE; + break; + case SB_PAGEDOWN: + nNewTopLine = m_nTopLine + si.nPage - 1; + bDisableSmooth = FALSE; + break; + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + nNewTopLine = si.nTrackPos; + break; + default: + return; + } + + if (nNewTopLine < 0) + nNewTopLine = 0; + if (nNewTopLine >= nLineCount) + nNewTopLine = nLineCount - 1; + ScrollToLine(nNewTopLine, bDisableSmooth); + *///END SW +} + +void CCrystalTextView:: +RecalcHorzScrollBar (BOOL bPositionOnly /*= FALSE*/ ) +{ + // Again, we cannot use nPos because it's 16-bit + SCROLLINFO si; + si.cbSize = sizeof (si); + if (bPositionOnly) + { + si.fMask = SIF_POS; + si.nPos = m_nOffsetChar; + } + else + { + if (GetScreenChars () >= GetMaxLineLength () && m_nOffsetChar > 0) + { + m_nOffsetChar = 0; + Invalidate (); + UpdateCaret (); + } + si.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE; + si.nMin = 0; + si.nMax = GetMaxLineLength () - 1; + si.nPage = GetScreenChars (); + si.nPos = m_nOffsetChar; + } + VERIFY (SetScrollInfo (SB_HORZ, &si)); +} + +void CCrystalTextView:: +OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar) +{ + CView::OnHScroll (nSBCode, nPos, pScrollBar); + + SCROLLINFO si; + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + VERIFY (GetScrollInfo (SB_HORZ, &si)); + + int nPageChars = GetScreenChars (); + int nMaxLineLength = GetMaxLineLength (); + + int nNewOffset; + switch (nSBCode) + { + case SB_LEFT: + nNewOffset = 0; + break; + case SB_BOTTOM: + nNewOffset = nMaxLineLength - nPageChars + 1; + break; + case SB_LINEUP: + nNewOffset = m_nOffsetChar - 1; + break; + case SB_LINEDOWN: + nNewOffset = m_nOffsetChar + 1; + break; + case SB_PAGEUP: + nNewOffset = m_nOffsetChar - si.nPage + 1; + break; + case SB_PAGEDOWN: + nNewOffset = m_nOffsetChar + si.nPage - 1; + break; + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + nNewOffset = si.nTrackPos; + break; + default: + return; + } + + if (nNewOffset >= nMaxLineLength) + nNewOffset = nMaxLineLength - 1; + if (nNewOffset < 0) + nNewOffset = 0; + ScrollToChar (nNewOffset, TRUE); + UpdateCaret (); +} + +BOOL CCrystalTextView:: +OnSetCursor (CWnd * pWnd, UINT nHitTest, UINT message) +{ + if (nHitTest == HTCLIENT) + { + CPoint pt; + ::GetCursorPos (&pt); + ScreenToClient (&pt); + if (pt.x < GetMarginWidth ()) + { + ::SetCursor (::LoadCursor (GetResourceHandle (), MAKEINTRESOURCE (IDR_MARGIN_CURSOR))); + } + else + { + CPoint ptText = ClientToText (pt); + PrepareSelBounds (); + if (IsInsideSelBlock (ptText)) + { + // [JRT]: Support For Disabling Drag and Drop... + if (!m_bDisableDragAndDrop) // If Drag And Drop Not Disabled + + ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE (IDC_ARROW))); // Set To Arrow Cursor + + } + else + ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE (IDC_IBEAM))); + } + return TRUE; + } + return CView::OnSetCursor (pWnd, nHitTest, message); +} + +CPoint CCrystalTextView:: +ClientToText (const CPoint & point) +{ + //BEGIN SW + int nSubLineCount = GetSubLineCount(); + int nLineCount = GetLineCount(); + + CPoint pt; + pt.y = m_nTopSubLine + point.y / GetLineHeight(); + if (pt.y >= nSubLineCount) + pt.y = nSubLineCount - 1; + if (pt.y < 0) + pt.y = 0; + + int nLine; + int nSubLineOffset; + int nOffsetChar = m_nOffsetChar; + + GetLineBySubLine( pt.y, nLine, nSubLineOffset ); + pt.y = nLine; + + LPCTSTR pszLine = NULL; + int nLength = 0; + int *anBreaks = NULL; + int nBreaks = 0; + + if (pt.y >= 0 && pt.y < nLineCount) + { + nLength = GetLineLength( pt.y ); + anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + pszLine = GetLineChars(pt.y); + WrapLineCached( pt.y, GetScreenChars(), anBreaks, nBreaks ); + + if( nSubLineOffset > 0 ) + nOffsetChar = anBreaks[nSubLineOffset - 1]; + if( nBreaks > nSubLineOffset ) + nLength = anBreaks[nSubLineOffset] - 1; + } + + int nPos = nOffsetChar + (point.x - GetMarginWidth()) / GetCharWidth(); + if (nPos < 0) + nPos = 0; + + int nIndex = 0, nCurPos = 0, n = 0, i = 0; + int nTabSize = GetTabSize(); + + /* + if( m_bWordWrap ) + nCurPos = nIndex = nOffsetChar; + */ + + while (nIndex < nLength) + { + if( nBreaks && nIndex == anBreaks[i] ) + { + n = nIndex; + i++; + } + + if (pszLine[nIndex] == _T('\t')) + { + n+= (nTabSize - nCurPos % nTabSize); + nCurPos += (nTabSize - nCurPos % nTabSize); + } + else + { + n++; + nCurPos ++; + } + + if (n > nPos && i == nSubLineOffset) + break; + + nIndex ++; + } + + ASSERT(nIndex >= 0 && nIndex <= nLength); + pt.x = nIndex; + return pt; + + /*ORIGINAL + int nLineCount = GetLineCount(); + + CPoint pt; + pt.y = m_nTopLine + point.y / GetLineHeight(); + if (pt.y >= nLineCount) + pt.y = nLineCount - 1; + if (pt.y < 0) + pt.y = 0; + + int nLength = 0; + LPCTSTR pszLine = NULL; + if (pt.y >= 0 && pt.y < nLineCount) + { + nLength = GetLineLength(pt.y); + pszLine = GetLineChars(pt.y); + } + + int nPos = m_nOffsetChar + (point.x - GetMarginWidth()) / GetCharWidth(); + if (nPos < 0) + nPos = 0; + + int nIndex = 0, nCurPos = 0; + int nTabSize = GetTabSize(); + while (nIndex < nLength) + { + if (pszLine[nIndex] == _T('\t')) + nCurPos += (nTabSize - nCurPos % nTabSize); + else + nCurPos ++; + + if (nCurPos > nPos) + break; + + nIndex ++; + } + + ASSERT(nIndex >= 0 && nIndex <= nLength); + pt.x = nIndex; + return pt; + *///END SW +} + +#ifdef _DEBUG +void CCrystalTextView:: +AssertValidTextPos (const CPoint & point) +{ + if (GetLineCount () > 0) + { + ASSERT (m_nTopLine >= 0 && m_nOffsetChar >= 0); + ASSERT (point.y >= 0 && point.y < GetLineCount ()); + ASSERT (point.x >= 0 && point.x <= GetLineLength (point.y)); + } +} +#endif + +bool CCrystalTextView:: +IsValidTextPos (const CPoint &point) +{ + return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 && + point.y >= 0 && point.y < GetLineCount () && point.x >= 0 && point.x <= GetLineLength (point.y); +} + +bool CCrystalTextView:: +IsValidTextPosX (const CPoint &point) +{ + return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 && + point.y >= 0 && point.y < GetLineCount () && point.x >= 0 && point.x <= GetLineLength (point.y); +} + +bool CCrystalTextView:: +IsValidTextPosY (const CPoint &point) +{ + return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 && + point.y >= 0 && point.y < GetLineCount (); +} + +CPoint CCrystalTextView:: +TextToClient (const CPoint & point) +{ + ASSERT_VALIDTEXTPOS (point); + LPCTSTR pszLine = GetLineChars (point.y); + + CPoint pt; + //BEGIN SW + CPoint charPoint; + int nSubLineStart = CharPosToPoint( point.y, point.x, charPoint ); + charPoint.y+= GetSubLineIndex( point.y ); + + // compute y-position + pt.y = (charPoint.y - m_nTopSubLine) * GetLineHeight(); + + // if pt.x is null, we know the result + if( charPoint.x == 0 ) + { + pt.x = GetMarginWidth(); + return pt; + } + + // we have to calculate x-position + int nPreOffset = 0; + /*ORIGINAL + pt.y = (point.y - m_nTopLine) * GetLineHeight(); + */ + //END SW + pt.x = 0; + int nTabSize = GetTabSize (); + for (int nIndex = 0; nIndex < point.x; nIndex++) + { + //BEGIN SW + if( nIndex == nSubLineStart ) + nPreOffset = pt.x; + //END SW + if (pszLine[nIndex] == _T ('\t')) + pt.x += (nTabSize - pt.x % nTabSize); + else + pt.x++; + } + //BEGIN SW + pt.x-= nPreOffset; + //END SW + + pt.x = (pt.x - m_nOffsetChar) * GetCharWidth () + GetMarginWidth (); + return pt; +} + +void CCrystalTextView:: +InvalidateLines (int nLine1, int nLine2, BOOL bInvalidateMargin /*= FALSE*/ ) +{ + bInvalidateMargin = TRUE; + if (nLine2 == -1) + { + CRect rcInvalid; + GetClientRect (&rcInvalid); + if (!bInvalidateMargin) + rcInvalid.left += GetMarginWidth (); + //BEGIN SW + rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * GetLineHeight(); + /*ORIGINAL + rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight(); + */ + //END SW + InvalidateRect (&rcInvalid, FALSE); + } + else + { + if (nLine2 < nLine1) + { + int nTemp = nLine1; + nLine1 = nLine2; + nLine2 = nTemp; + } + CRect rcInvalid; + GetClientRect (&rcInvalid); + if (!bInvalidateMargin) + rcInvalid.left += GetMarginWidth (); + //BEGIN SW + rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * GetLineHeight(); + rcInvalid.bottom = (GetSubLineIndex( nLine2 ) - m_nTopSubLine + GetSubLines( nLine2 )) * GetLineHeight(); + /*ORIGINAL + rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight(); + rcInvalid.bottom = (nLine2 - m_nTopLine + 1) * GetLineHeight(); + */ + //END SW + InvalidateRect (&rcInvalid, FALSE); + } +} + +void CCrystalTextView:: +SetSelection (const CPoint & ptStart, const CPoint & ptEnd) +{ + ASSERT_VALIDTEXTPOS (ptStart); + ASSERT_VALIDTEXTPOS (ptEnd); + if (m_ptSelStart == ptStart) + { + if (m_ptSelEnd != ptEnd) + InvalidateLines (ptEnd.y, m_ptSelEnd.y); + } + else + { + InvalidateLines (ptStart.y, ptEnd.y); + InvalidateLines (m_ptSelStart.y, m_ptSelEnd.y); + } + m_ptSelStart = ptStart; + m_ptSelEnd = ptEnd; +} + +void CCrystalTextView:: +AdjustTextPoint (CPoint & point) +{ + point.x += GetCharWidth () / 2; //todo + +} + +void CCrystalTextView:: +OnSetFocus (CWnd * pOldWnd) +{ + CView::OnSetFocus (pOldWnd); + + m_bFocused = TRUE; + if (m_ptSelStart != m_ptSelEnd) + InvalidateLines (m_ptSelStart.y, m_ptSelEnd.y); + UpdateCaret (); +} + +DWORD CCrystalTextView:: +ParseLinePlain (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + return 0; +} + +DWORD CCrystalTextView:: +ParseLine (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + return (this->*(m_CurSourceDef->ParseLineX)) (dwCookie, nLineIndex, pBuf, nActualItems); +} + +int CCrystalTextView:: +CalculateActualOffset (int nLineIndex, int nCharIndex) +{ + int nLength = GetLineLength (nLineIndex); + ASSERT (nCharIndex >= 0 && nCharIndex <= nLength); + LPCTSTR pszChars = GetLineChars (nLineIndex); + int nOffset = 0; + int nTabSize = GetTabSize (); + //BEGIN SW + int *anBreaks = (int*)_alloca( sizeof( int ) * nLength ); + int nBreaks = 0; + + /*if( nLength > GetScreenChars() )*/ + WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks ); + + int nPreOffset = 0; + int nPreBreak = 0; + + if( nBreaks ) + { + for( int J = nBreaks - 1; J >= 0 && nCharIndex < anBreaks[J]; J-- ); + nPreBreak = anBreaks[J]; + } + //END SW + for (int I = 0; I < nCharIndex; I++) + { + //BEGIN SW + if( nPreBreak == I && nBreaks ) + nPreOffset = nOffset; + //END SW + if (pszChars[I] == _T ('\t')) + nOffset += (nTabSize - nOffset % nTabSize); + else + nOffset++; + } + //BEGIN SW + if( nPreBreak == I && nBreaks ) + return 0; + else + return nOffset - nPreOffset; + /*ORIGINAL + return nOffset; + *///END SW +} + +int CCrystalTextView:: +ApproxActualOffset (int nLineIndex, int nOffset) +{ + if (nOffset == 0) + return 0; + + int nLength = GetLineLength (nLineIndex); + LPCTSTR pszChars = GetLineChars (nLineIndex); + int nCurrentOffset = 0; + int nTabSize = GetTabSize (); + for (int I = 0; I < nLength; I++) + { + if (pszChars[I] == _T ('\t')) + nCurrentOffset += (nTabSize - nCurrentOffset % nTabSize); + else + nCurrentOffset++; + if (nCurrentOffset >= nOffset) + { + if (nOffset <= nCurrentOffset - nTabSize / 2) + return I; + return I + 1; + } + } + return nLength; +} + +void CCrystalTextView:: +EnsureVisible (CPoint pt) +{ + // Scroll vertically + //BEGIN SW + int nSubLineCount = GetSubLineCount(); + int nNewTopSubLine = m_nTopSubLine; + CPoint subLinePos; + + CharPosToPoint( pt.y, pt.x, subLinePos ); + subLinePos.y+= GetSubLineIndex( pt.y ); + + if( subLinePos.y >= nNewTopSubLine + GetScreenLines() ) + nNewTopSubLine = subLinePos.y - GetScreenLines() + 1; + if( subLinePos.y < nNewTopSubLine ) + nNewTopSubLine = subLinePos.y; + + if( nNewTopSubLine < 0 ) + nNewTopSubLine = 0; + if( nNewTopSubLine >= nSubLineCount ) + nNewTopSubLine = nSubLineCount - 1; + + if( nNewTopSubLine != m_nTopSubLine ) + { + ScrollToSubLine( nNewTopSubLine ); + UpdateCaret(); + UpdateSiblingScrollPos( FALSE ); + } + /*ORIGINAL + int nLineCount = GetLineCount(); + int nNewTopLine = m_nTopLine; + if (pt.y >= nNewTopLine + GetScreenLines()) + { + nNewTopLine = pt.y - GetScreenLines() + 1; + } + if (pt.y < nNewTopLine) + { + nNewTopLine = pt.y; + } + + if (nNewTopLine < 0) + nNewTopLine = 0; + if (nNewTopLine >= nLineCount) + nNewTopLine = nLineCount - 1; + + if (m_nTopLine != nNewTopLine) + { + ScrollToLine(nNewTopLine); + UpdateSiblingScrollPos(TRUE); + } + */ + //END SW + + // Scroll horizontally + //BEGIN SW + // we do not need horizontally scrolling, if we wrap the words + if( m_bWordWrap ) + return; + //END SW + int nActualPos = CalculateActualOffset (pt.y, pt.x); + int nNewOffset = m_nOffsetChar; + if (nActualPos > nNewOffset + GetScreenChars ()) + { + nNewOffset = nActualPos - GetScreenChars (); + } + if (nActualPos < nNewOffset) + { + nNewOffset = nActualPos; + } + + if (nNewOffset >= GetMaxLineLength ()) + nNewOffset = GetMaxLineLength () - 1; + if (nNewOffset < 0) + nNewOffset = 0; + + if (m_nOffsetChar != nNewOffset) + { + ScrollToChar (nNewOffset); + UpdateCaret (); + UpdateSiblingScrollPos (TRUE); + } +} + +void CCrystalTextView:: +OnKillFocus (CWnd * pNewWnd) +{ + CView::OnKillFocus (pNewWnd); + + m_bFocused = FALSE; + UpdateCaret (); + if (m_ptSelStart != m_ptSelEnd) + InvalidateLines (m_ptSelStart.y, m_ptSelEnd.y); + if (m_bDragSelection) + { + ReleaseCapture (); + KillTimer (m_nDragSelTimer); + m_bDragSelection = FALSE; + } +} + +void CCrystalTextView:: +OnSysColorChange () +{ + CView::OnSysColorChange (); + Invalidate (); +} + +void CCrystalTextView:: +GetText (const CPoint & ptStart, const CPoint & ptEnd, CString & text) +{ + if (m_pTextBuffer != NULL) + m_pTextBuffer->GetText (ptStart.y, ptStart.x, ptEnd.y, ptEnd.x, text); + else + text = _T (""); +} + +void CCrystalTextView:: +UpdateView (CCrystalTextView * pSource, CUpdateContext * pContext, + DWORD dwFlags, int nLineIndex /*= -1*/ ) +{ + // SetTextType (GetExt (GetDocument ()->GetPathName ())); + if (dwFlags & UPDATE_RESET) + { + ResetView (); + RecalcVertScrollBar (); + RecalcHorzScrollBar (); + return; + } + + int nLineCount = GetLineCount (); + ASSERT (nLineCount > 0); + ASSERT (nLineIndex >= -1 && nLineIndex < nLineCount); + if ((dwFlags & UPDATE_SINGLELINE) != 0) + { + ASSERT (nLineIndex != -1); + // All text below this line should be reparsed + if (m_pdwParseCookies != NULL) + { + ASSERT (m_nParseArraySize == nLineCount); + memset (m_pdwParseCookies + nLineIndex, 0xff, sizeof (DWORD) * (m_nParseArraySize - nLineIndex)); + } + // This line'th actual length must be recalculated + if (m_pnActualLineLength != NULL) + { + ASSERT (m_nActualLengthArraySize == nLineCount); + m_pnActualLineLength[nLineIndex] = -1; + //BEGIN SW + InvalidateLineCache( nLineIndex, nLineIndex ); + //END SW + } + // Repaint the lines + InvalidateLines (nLineIndex, -1, TRUE); + } + else + { + if (nLineIndex == -1) + nLineIndex = 0; // Refresh all text + // All text below this line should be reparsed + + if (m_pdwParseCookies != NULL) + { + if (m_nParseArraySize != nLineCount) + { + // Reallocate cookies array + DWORD *pdwNewArray = new DWORD[nLineCount]; + if (nLineIndex > 0) + memcpy (pdwNewArray, m_pdwParseCookies, sizeof (DWORD) * nLineIndex); + delete m_pdwParseCookies; + m_nParseArraySize = nLineCount; + m_pdwParseCookies = pdwNewArray; + } + memset (m_pdwParseCookies + nLineIndex, 0xff, sizeof (DWORD) * (m_nParseArraySize - nLineIndex)); + } + // Recalculate actual length for all lines below this + if (m_pnActualLineLength != NULL) + { + if (m_nActualLengthArraySize != nLineCount) + { + // Reallocate actual length array + int *pnNewArray = new int[nLineCount]; + if (nLineIndex > 0) + memcpy (pnNewArray, m_pnActualLineLength, sizeof (int) * nLineIndex); + delete m_pnActualLineLength; + m_nActualLengthArraySize = nLineCount; + m_pnActualLineLength = pnNewArray; + } + memset (m_pnActualLineLength + nLineIndex, 0xff, sizeof (DWORD) * (m_nActualLengthArraySize - nLineIndex)); + } + //BEGIN SW + InvalidateLineCache( nLineIndex, -1 ); + //END SW + // Repaint the lines + InvalidateLines (nLineIndex, -1, TRUE); + } + + // All those points must be recalculated and validated + if (pContext != NULL) + { + pContext->RecalcPoint (m_ptCursorPos); + pContext->RecalcPoint (m_ptSelStart); + pContext->RecalcPoint (m_ptSelEnd); + pContext->RecalcPoint (m_ptAnchor); + ASSERT_VALIDTEXTPOS (m_ptCursorPos); + ASSERT_VALIDTEXTPOS (m_ptSelStart); + ASSERT_VALIDTEXTPOS (m_ptSelEnd); + ASSERT_VALIDTEXTPOS (m_ptAnchor); + if (m_bDraggingText) + { + pContext->RecalcPoint (m_ptDraggedTextBegin); + pContext->RecalcPoint (m_ptDraggedTextEnd); + ASSERT_VALIDTEXTPOS (m_ptDraggedTextBegin); + ASSERT_VALIDTEXTPOS (m_ptDraggedTextEnd); + } + CPoint ptTopLine (0, m_nTopLine); + pContext->RecalcPoint (ptTopLine); + ASSERT_VALIDTEXTPOS (ptTopLine); + m_nTopLine = ptTopLine.y; + UpdateCaret (); + } + + // Recalculate vertical scrollbar, if needed + if ((dwFlags & UPDATE_VERTRANGE) != 0) + { + if (!m_bVertScrollBarLocked) + RecalcVertScrollBar (); + } + + // Recalculate horizontal scrollbar, if needed + if ((dwFlags & UPDATE_HORZRANGE) != 0) + { + m_nMaxLineLength = -1; + if (!m_bHorzScrollBarLocked) + RecalcHorzScrollBar (); + } +} + +HINSTANCE CCrystalTextView:: +GetResourceHandle () +{ +#ifdef CRYSEDIT_RES_HANDLE + return CRYSEDIT_RES_HANDLE; +#else + if (s_hResourceInst != NULL) + return s_hResourceInst; + return AfxGetResourceHandle (); +#endif +} + +int CCrystalTextView:: +OnCreate (LPCREATESTRUCT lpCreateStruct) +{ + memset (&m_lfBaseFont, 0, sizeof (m_lfBaseFont)); + _tcscpy (m_lfBaseFont.lfFaceName, _T ("FixedSys")); + m_lfBaseFont.lfHeight = 0; + m_lfBaseFont.lfWeight = FW_NORMAL; + m_lfBaseFont.lfItalic = FALSE; + m_lfBaseFont.lfCharSet = DEFAULT_CHARSET; + m_lfBaseFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + m_lfBaseFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + m_lfBaseFont.lfQuality = DEFAULT_QUALITY; + m_lfBaseFont.lfPitchAndFamily = DEFAULT_PITCH; + + if (CView::OnCreate (lpCreateStruct) == -1) + return -1; + + /*TODO + ASSERT (m_hAccel == NULL); + // vvv GetResourceHandle () ??? + HINSTANCE hInst = AfxFindResourceHandle (MAKEINTRESOURCE(IDR_DEFAULT_ACCEL), RT_ACCELERATOR); + ASSERT (hInst); + m_hAccel =::LoadAccelerators (hInst, MAKEINTRESOURCE (IDR_DEFAULT_ACCEL)); + ASSERT (m_hAccel != NULL);*/ + return 0; +} + +void CCrystalTextView:: +SetAnchor (const CPoint & ptNewAnchor) +{ + ASSERT_VALIDTEXTPOS (ptNewAnchor); + m_ptAnchor = ptNewAnchor; +} + +void CCrystalTextView:: +OnEditOperation (int nAction, LPCTSTR pszText) +{ +} + +BOOL CCrystalTextView:: +PreTranslateMessage (MSG * pMsg) +{ + if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) + { + if (m_hAccel != NULL) + { + if (::TranslateAccelerator (m_hWnd, m_hAccel, pMsg)) + return TRUE; + } + } + + return CView::PreTranslateMessage (pMsg); +} + +CPoint CCrystalTextView:: +GetCursorPos () +{ + return m_ptCursorPos; +} + +void CCrystalTextView:: +SetCursorPos (const CPoint & ptCursorPos) +{ + ASSERT_VALIDTEXTPOS (ptCursorPos); + m_ptCursorPos = ptCursorPos; + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + UpdateCaret (); +} + +void CCrystalTextView:: +SetSelectionMargin (BOOL bSelMargin) +{ + if (m_bSelMargin != bSelMargin) + { + m_bSelMargin = bSelMargin; + if (::IsWindow (m_hWnd)) + { + m_nScreenChars = -1; + Invalidate (); + RecalcHorzScrollBar (); + } + } +} + +void CCrystalTextView:: +GetFont (LOGFONT & lf) +{ + lf = m_lfBaseFont; +} + +void CCrystalTextView:: +SetFont (const LOGFONT & lf) +{ + m_lfBaseFont = lf; + m_nScreenLines = -1; + m_nScreenChars = -1; + m_nCharWidth = -1; + m_nLineHeight = -1; + if (m_pCacheBitmap != NULL) + { + m_pCacheBitmap->DeleteObject (); + delete m_pCacheBitmap; + m_pCacheBitmap = NULL; + } + for (int I = 0; I < 4; I++) + { + if (m_apFonts[I] != NULL) + { + m_apFonts[I]->DeleteObject (); + delete m_apFonts[I]; + m_apFonts[I] = NULL; + } + } + if (::IsWindow (m_hWnd)) + { + RecalcVertScrollBar (); + RecalcHorzScrollBar (); + UpdateCaret (); + Invalidate (); + } +} + +void CCrystalTextView:: +OnUpdateIndicatorPosition (CCmdUI * pCmdUI) +{ + ASSERT_VALIDTEXTPOS (m_ptCursorPos); + CString stat; + // VVV m_ptCursorPos.x + 1 ??? + stat.Format (_T ("Ln %d, Col %d"), m_ptCursorPos.y + 1, m_nIdealCharPos + 1); + pCmdUI->SetText (stat); + //BEGIN SW + if( pCmdUI->m_pOther && pCmdUI->m_pOther->IsKindOf( RUNTIME_CLASS(CStatusBar) ) ) + OnUpdateStatusMessage( (CStatusBar*)pCmdUI->m_pOther ); + //END SW +} + +void CCrystalTextView:: +OnUpdateIndicatorCRLF (CCmdUI * pCmdUI) +{ + if (m_pTextBuffer != NULL) + { + int crlfMode = m_pTextBuffer->GetCRLFMode (); + switch (crlfMode) + { + case CRLF_STYLE_DOS: + pCmdUI->SetText (_T ("DOS")); + pCmdUI->Enable (TRUE); + break; + case CRLF_STYLE_UNIX: + pCmdUI->SetText (_T ("UNIX")); + pCmdUI->Enable (TRUE); + break; + case CRLF_STYLE_MAC: + pCmdUI->SetText (_T ("MAC")); + pCmdUI->Enable (TRUE); + break; + default: + pCmdUI->SetText (NULL); + pCmdUI->Enable (FALSE); + } + } + else + { + pCmdUI->SetText (NULL); + pCmdUI->Enable (FALSE); + } +} + +void CCrystalTextView:: +OnToggleBookmark (UINT nCmdID) +{ + int nBookmarkID = nCmdID - ID_EDIT_TOGGLE_BOOKMARK0; + ASSERT (nBookmarkID >= 0 && nBookmarkID <= 9); + if (m_pTextBuffer != NULL) + { + DWORD dwFlags = GetLineFlags (m_ptCursorPos.y); + DWORD dwMask = LF_BOOKMARK (nBookmarkID); + m_pTextBuffer->SetLineFlag (m_ptCursorPos.y, dwMask, (dwFlags & dwMask) == 0); + } +} + +void CCrystalTextView:: +OnGoBookmark (UINT nCmdID) +{ + int nBookmarkID = nCmdID - ID_EDIT_GO_BOOKMARK0; + ASSERT (nBookmarkID >= 0 && nBookmarkID <= 9); + if (m_pTextBuffer != NULL) + { + int nLine = m_pTextBuffer->GetLineWithFlag (LF_BOOKMARK (nBookmarkID)); + if (nLine >= 0) + { + CPoint pt (0, nLine); + ASSERT_VALIDTEXTPOS (pt); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + } + } +} + +void CCrystalTextView:: +OnClearBookmarks () +{ + if (m_pTextBuffer != NULL) + { + for (int nBookmarkID = 0; nBookmarkID <= 9; nBookmarkID++) + { + int nLine = m_pTextBuffer->GetLineWithFlag (LF_BOOKMARK (nBookmarkID)); + if (nLine >= 0) + { + m_pTextBuffer->SetLineFlag (nLine, LF_BOOKMARK (nBookmarkID), FALSE); + } + } + + } +} + +void CCrystalTextView:: +ShowCursor () +{ + m_bCursorHidden = FALSE; + UpdateCaret (); +} + +void CCrystalTextView:: +HideCursor () +{ + m_bCursorHidden = TRUE; + UpdateCaret (); +} + +void CCrystalTextView:: +PopCursor () +{ + if (IsValidTextPosY (m_ptCursorLast)) + { + if (!IsValidTextPosX (m_ptCursorLast)) + m_ptCursorLast.x = 0; + ASSERT_VALIDTEXTPOS (m_ptCursorLast); + CPoint ptCursorPos = m_ptCursorLast; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + } +} + +void CCrystalTextView:: +PushCursor () +{ + m_ptCursorLast = m_ptCursorPos; +} + +DROPEFFECT CCrystalTextView:: +GetDropEffect () +{ + return DROPEFFECT_COPY; +} + +void CCrystalTextView:: +OnDropSource (DROPEFFECT de) +{ + ASSERT (de == DROPEFFECT_COPY); +} + +HGLOBAL CCrystalTextView:: +PrepareDragData () +{ + PrepareSelBounds (); + if (m_ptDrawSelStart == m_ptDrawSelEnd) + return NULL; + + CString text; + GetText (m_ptDrawSelStart, m_ptDrawSelEnd, text); + HGLOBAL hData =::GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, _tcslen (text) + 1); + if (hData == NULL) + return NULL; + + LPTSTR pszData = (LPTSTR)::GlobalLock (hData); + _tcscpy (pszData, text.GetBuffer (0)); + text.ReleaseBuffer (); + ::GlobalUnlock (hData); + + m_ptDraggedTextBegin = m_ptDrawSelStart; + m_ptDraggedTextEnd = m_ptDrawSelEnd; + return hData; +} + +static int +FindStringHelper (LPCTSTR pszFindWhere, LPCTSTR pszFindWhat, DWORD dwFlags, int &nLen, RxNode *&rxnode, RxMatchRes *rxmatch) +{ + if (dwFlags & FIND_REGEXP) + { + int pos; + + if (rxnode) + RxFree (rxnode); + rxnode = RxCompile (pszFindWhat); + if (rxnode && RxExec (rxnode, pszFindWhere, _tcslen (pszFindWhere), pszFindWhere, rxmatch, (dwFlags & FIND_MATCH_CASE) != 0 ? RX_CASE : 0)) + { + pos = rxmatch->Open[0]; + nLen = rxmatch->Close[0] - rxmatch->Open[0]; + } + else + { + pos = -1; + } + return pos; + } + else + { + ASSERT (pszFindWhere != NULL); + ASSERT (pszFindWhat != NULL); + int nCur = 0; + int nLength = _tcslen (pszFindWhat); + nLen = nLength; + for (;;) + { + LPCTSTR pszPos = _tcsstr (pszFindWhere, pszFindWhat); + if (pszPos == NULL) + return -1; + if ((dwFlags & FIND_WHOLE_WORD) == 0) + return nCur + (pszPos - pszFindWhere); + if (pszPos > pszFindWhere && xisalnum (pszPos[-1])) + { + nCur += (pszPos - pszFindWhere); + pszFindWhere = pszPos + 1; + continue; + } + if (xisalnum (pszPos[nLength])) + { + nCur += (pszPos - pszFindWhere + 1); + pszFindWhere = pszPos + 1; + continue; + } + return nCur + (pszPos - pszFindWhere); + } + } + ASSERT (FALSE); // Unreachable + + return -1; +} + +BOOL CCrystalTextView:: +HighlightText (const CPoint & ptStartPos, int nLength, BOOL bReverse /*= FALSE*/) +{ + ASSERT_VALIDTEXTPOS (ptStartPos); + CPoint ptEndPos = ptStartPos; + int nCount = GetLineLength (ptEndPos.y) - ptEndPos.x; + if (nLength <= nCount) + { + ptEndPos.x += nLength; + } + else + { + while (nLength > nCount) + { + nLength -= nCount + 1; + nCount = GetLineLength (++ptEndPos.y); + } + ptEndPos.x = nLength; + } + ASSERT_VALIDTEXTPOS (m_ptCursorPos); // Probably 'nLength' is bigger than expected... + + m_ptCursorPos = bReverse ? ptStartPos : ptEndPos; + m_ptAnchor = m_ptCursorPos; + SetSelection (ptStartPos, ptEndPos); + UpdateCaret (); + EnsureVisible (m_ptCursorPos); + return TRUE; +} + +BOOL CCrystalTextView:: +FindText (LPCTSTR pszText, const CPoint & ptStartPos, DWORD dwFlags, + BOOL bWrapSearch, CPoint * pptFoundPos) +{ + int nLineCount = GetLineCount (); + return FindTextInBlock (pszText, ptStartPos, CPoint (0, 0), + CPoint (GetLineLength (nLineCount - 1), nLineCount - 1), + dwFlags, bWrapSearch, pptFoundPos); +} + +int HowManyStr (LPCTSTR s, LPCTSTR m) +{ + LPCTSTR p = s; + int n = 0, l = _tcslen (m); + while ((p = _tcsstr (p, m)) != NULL) + { + n++; + p += l; + } + return n; +} + +int HowManyStr (LPCTSTR s, TCHAR c) +{ + LPCTSTR p = s; + int n = 0; + while ((p = _tcschr (p, c)) != NULL) + { + n++; + p++; + } + return n; +} + +BOOL CCrystalTextView:: +FindTextInBlock (LPCTSTR pszText, const CPoint & ptStartPosition, + const CPoint & ptBlockBegin, const CPoint & ptBlockEnd, + DWORD dwFlags, BOOL bWrapSearch, CPoint * pptFoundPos) +{ + CPoint ptCurrentPos = ptStartPosition; + + ASSERT (pszText != NULL && _tcslen (pszText) > 0); + ASSERT_VALIDTEXTPOS (ptCurrentPos); + ASSERT_VALIDTEXTPOS (ptBlockBegin); + ASSERT_VALIDTEXTPOS (ptBlockEnd); + ASSERT (ptBlockBegin.y < ptBlockEnd.y || ptBlockBegin.y == ptBlockEnd.y && + ptBlockBegin.x <= ptBlockEnd.x); + if (ptBlockBegin == ptBlockEnd) + return FALSE; + CWaitCursor waitCursor; + if (ptCurrentPos.y < ptBlockBegin.y || ptCurrentPos.y == ptBlockBegin.y && + ptCurrentPos.x < ptBlockBegin.x) + ptCurrentPos = ptBlockBegin; + + CString what = pszText; + int nEolns; + if (dwFlags & FIND_REGEXP) + { + nEolns = HowManyStr (what, _T("\\n")); + } + else + { + nEolns = 0; + if ((dwFlags & FIND_MATCH_CASE) == 0) + what.MakeUpper (); + } + if (dwFlags & FIND_DIRECTION_UP) + { + // Let's check if we deal with whole text. + // At this point, we cannot search *up* in selection + ASSERT (ptBlockBegin.x == 0 && ptBlockBegin.y == 0); + ASSERT (ptBlockEnd.x == GetLineLength (GetLineCount () - 1) && + ptBlockEnd.y == GetLineCount () - 1); + + // Proceed as if we have whole text search. + for (;;) + { + while (ptCurrentPos.y >= 0) + { + int nLineLength; + CString line; + if (dwFlags & FIND_REGEXP) + { + for (int i = 0; i <= nEolns && ptCurrentPos.y >= i; i++) + { + CString item; + LPCTSTR pszChars = GetLineChars (ptCurrentPos.y - i); + if (i) + { + nLineLength = GetLineLength (ptCurrentPos.y - i); + ptCurrentPos.x = 0; + line = _T ('\n') + line; + } + else + { + nLineLength = ptCurrentPos.x != -1 ? ptCurrentPos.x : GetLineLength (ptCurrentPos.y - i); + } + if (nLineLength > 0) + { + LPTSTR pszBuf = item.GetBuffer (nLineLength + 1); + _tcsncpy (pszBuf, pszChars, nLineLength); + pszBuf[nLineLength] = _T ('\0'); + item.ReleaseBuffer (); + line = item + line; + } + } + nLineLength = line.GetLength (); + if (ptCurrentPos.x == -1) + ptCurrentPos.x = 0; + } + else + { + nLineLength = GetLineLength(ptCurrentPos.y); + //BEGIN SW+FP + if (ptCurrentPos.x == -1) + { + ptCurrentPos.x = nLineLength; + } + else + if( ptCurrentPos.x >= nLineLength ) + ptCurrentPos.x = nLineLength - 1; + /*ORIGINAL + if (ptCurrentPos.x == -1) + { + nLineLength = GetLineLength (ptCurrentPos.y); + ptCurrentPos.x = nLineLength; + } + else + nLineLength = ptCurrentPos.x; + if (nLineLength <= 0) + { + ptCurrentPos.x = -1; + ptCurrentPos.y--; + continue; + } + *///END SW + + LPCTSTR pszChars = GetLineChars (ptCurrentPos.y); + //BEGIN SW + _tcsncpy(line.GetBuffer(ptCurrentPos.x + 2), pszChars, ptCurrentPos.x + 1); + /*ORIGINAL + LPTSTR pszBuf = line.GetBuffer (nLineLength + 1); + _tcsncpy (pszBuf, pszChars, nLineLength); + pszBuf[nLineLength] = _T ('\0'); + *///END SW + line.ReleaseBuffer (); + if ((dwFlags & FIND_MATCH_CASE) == 0) + line.MakeUpper (); + } + + //BEGIN SW + int nFoundPos = -1; + int nMatchLen = what.GetLength(); + int nLineLen = line.GetLength(); + int nPos; + do + { + nPos = ::FindStringHelper(line, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch); + if( nPos >= 0 ) + { + nFoundPos = (nFoundPos == -1)? nPos : nFoundPos + nPos; + nFoundPos+= nMatchLen; + line = line.Right( nLineLen - (nMatchLen + nPos) ); + nLineLen = line.GetLength(); + } + } + while( nPos >= 0 ); + + if( nFoundPos >= 0 ) // Found text! + { + ptCurrentPos.x = nFoundPos - nMatchLen; + *pptFoundPos = ptCurrentPos; + return TRUE; + } + + ptCurrentPos.y--; + if( ptCurrentPos.y >= 0 ) + ptCurrentPos.x = GetLineLength( ptCurrentPos.y ); + /*ORIGINAL + int nPos =::FindStringHelper (line, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch); + if (nPos >= 0) // Found text! + { + LPTSTR pszText = line.GetBuffer (nLineLength + 1); + m_pszMatched = _tcsdup (pszText); + line.ReleaseBuffer (); + // m_sMatched = line.Mid (nPos); + if (nEolns) + { + CString item = line.Left (nPos); + ptCurrentPos.y -= nEolns - HowManyStr (item, _T('\n')); + if (ptCurrentPos.y < 0) + ptCurrentPos.y = 0; + LPCTSTR current = _tcsrchr (item, _T('\n')); + if (current) + current++; + else + current = item; + ptCurrentPos.x = nPos - (current - (LPCTSTR) item); + if (ptCurrentPos.x < 0) + ptCurrentPos.x = 0; + } + else + { + ptCurrentPos.x = nPos; + } + *pptFoundPos = ptCurrentPos; + return TRUE; + } + else + m_pszMatched = NULL; + + ptCurrentPos.x = -1; + ptCurrentPos.y--; + *///END SW + } + + // Beginning of text reached + if (!bWrapSearch) + return FALSE; + + // Start again from the end of text + bWrapSearch = FALSE; + ptCurrentPos = CPoint (0, GetLineCount () - 1); + } + } + else + { + for (;;) + { + while (ptCurrentPos.y <= ptBlockEnd.y) + { + int nLineLength, nLines; + CString line; + if (dwFlags & FIND_REGEXP) + { + nLines = m_pTextBuffer->GetLineCount (); + for (int i = 0; i <= nEolns && ptCurrentPos.y + i < nLines; i++) + { + CString item; + LPCTSTR pszChars = GetLineChars (ptCurrentPos.y + i); + nLineLength = GetLineLength (ptCurrentPos.y + i); + if (i) + { + line += _T ('\n'); + } + else + { + pszChars += ptCurrentPos.x; + nLineLength -= ptCurrentPos.x; + } + if (nLineLength > 0) + { + LPTSTR pszBuf = item.GetBuffer (nLineLength + 1); + _tcsncpy (pszBuf, pszChars, nLineLength); + pszBuf[nLineLength] = _T ('\0'); + item.ReleaseBuffer (); + line += item; + } + } + nLineLength = line.GetLength (); + } + else + { + nLineLength = GetLineLength (ptCurrentPos.y) - ptCurrentPos.x; + if (nLineLength <= 0) + { + ptCurrentPos.x = 0; + ptCurrentPos.y++; + continue; + } + + LPCTSTR pszChars = GetLineChars (ptCurrentPos.y); + pszChars += ptCurrentPos.x; + + // Prepare necessary part of line + LPTSTR pszBuf = line.GetBuffer (nLineLength + 1); + _tcsncpy (pszBuf, pszChars, nLineLength); + pszBuf[nLineLength] = _T ('\0'); + line.ReleaseBuffer (); + if ((dwFlags & FIND_MATCH_CASE) == 0) + line.MakeUpper (); + } + + // Perform search in the line + int nPos =::FindStringHelper (line, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch); + if (nPos >= 0) + { + LPTSTR pszText = line.GetBuffer (nLineLength + 1); + m_pszMatched = _tcsdup (pszText); + line.ReleaseBuffer (); + // m_sMatched = line.Mid (nPos); + if (nEolns) + { + CString item = line.Left (nPos); + LPCTSTR current = _tcsrchr (item, _T('\n')); + if (current) + current++; + else + current = item; + nEolns = HowManyStr (item, _T('\n')); + if (nEolns) + { + ptCurrentPos.y += nEolns; + ptCurrentPos.x = nPos - (current - (LPCTSTR) item); + } + else + { + ptCurrentPos.x += nPos - (current - (LPCTSTR) item); + } + if (ptCurrentPos.x < 0) + ptCurrentPos.x = 0; + } + else + { + ptCurrentPos.x += nPos; + } + // Check of the text found is outside the block. + if (ptCurrentPos.y == ptBlockEnd.y && ptCurrentPos.x >= ptBlockEnd.x) + break; + + *pptFoundPos = ptCurrentPos; + return TRUE; + } + else + m_pszMatched = NULL; + + // Go further, text was not found + ptCurrentPos.x = 0; + ptCurrentPos.y++; + } + + // End of text reached + if (!bWrapSearch) + return FALSE; + + // Start from the beginning + bWrapSearch = FALSE; + ptCurrentPos = ptBlockBegin; + } + } + + ASSERT (FALSE); // Unreachable + + return FALSE; +} + +void CCrystalTextView:: +OnEditFind () +{ + CWinApp *pApp = AfxGetApp (); + ASSERT (pApp != NULL); + + CFindTextDlg dlg (this); + if (m_bLastSearch) + { + // Get the latest search parameters + dlg.m_bMatchCase = (m_dwLastSearchFlags & FIND_MATCH_CASE) != 0; + dlg.m_bWholeWord = (m_dwLastSearchFlags & FIND_WHOLE_WORD) != 0; + dlg.m_bRegExp = (m_dwLastSearchFlags & FIND_REGEXP) != 0; + dlg.m_nDirection = (m_dwLastSearchFlags & FIND_DIRECTION_UP) != 0 ? 0 : 1; + if (m_pszLastFindWhat != NULL) + dlg.m_sText = m_pszLastFindWhat; + } + else + { + DWORD dwFlags; + if (!RegLoadNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("FindFlags"), &dwFlags)) + dwFlags = 0; + dlg.m_bMatchCase = (dwFlags & FIND_MATCH_CASE) != 0; + dlg.m_bWholeWord = (dwFlags & FIND_WHOLE_WORD) != 0; + dlg.m_bRegExp = (dwFlags & FIND_REGEXP) != 0; + dlg.m_nDirection = (dwFlags & FIND_DIRECTION_UP) == 0; + // dlg.m_sText = pApp->GetProfileString (REG_FIND_SUBKEY, REG_FIND_WHAT, _T ("")); + } + + // Take the current selection, if any + if (IsSelection ()) + { + CPoint ptSelStart, ptSelEnd; + GetSelection (ptSelStart, ptSelEnd); + if (ptSelStart.y == ptSelEnd.y) + { + LPCTSTR pszChars = GetLineChars (ptSelStart.y); + int nChars = ptSelEnd.x - ptSelStart.x; + _tcsncpy (dlg.m_sText.GetBuffer (nChars + 1), pszChars + ptSelStart.x, nChars + 1); + dlg.m_sText.ReleaseBuffer (); + } + } + else + { + CPoint ptCursorPos = GetCursorPos (), ptStart = WordToLeft (ptCursorPos), ptEnd = WordToRight (ptCursorPos); + if (IsValidTextPos (ptStart) && IsValidTextPos (ptEnd) && ptStart != ptEnd) + GetText (ptStart, ptEnd, dlg.m_sText); + } + + // Execute Find dialog + dlg.m_ptCurrentPos = m_ptCursorPos; // Search from cursor position + + // m_bShowInactiveSelection = TRUE; // FP: removed because I like it + dlg.DoModal (); + // m_bShowInactiveSelection = FALSE; // FP: removed because I like it + + // Save search parameters for 'F3' command + m_bLastSearch = TRUE; + if (m_pszLastFindWhat != NULL) + free (m_pszLastFindWhat); + m_pszLastFindWhat = _tcsdup (dlg.m_sText); + m_dwLastSearchFlags = 0; + if (dlg.m_bMatchCase) + m_dwLastSearchFlags |= FIND_MATCH_CASE; + if (dlg.m_bWholeWord) + m_dwLastSearchFlags |= FIND_WHOLE_WORD; + if (dlg.m_bRegExp) + m_dwLastSearchFlags |= FIND_REGEXP; + if (dlg.m_nDirection == 0) + m_dwLastSearchFlags |= FIND_DIRECTION_UP; + + // Save search parameters to registry + VERIFY (RegSaveNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("FindFlags"), m_dwLastSearchFlags)); + // pApp->WriteProfileString (REG_FIND_SUBKEY, REG_FIND_WHAT, dlg.m_sText); +} + +void CCrystalTextView:: +OnEditRepeat () +{ + BOOL bEnable = m_bLastSearch; + CString sText; + if (bEnable) + sText = m_pszLastFindWhat; + else + { + bEnable = CMemComboBox::groups.Lookup (_T ("FindText"), sText) && !sText.IsEmpty (); + if (bEnable) + { + int pos = sText.Find (_T('\n')); + if (pos >= 0) + sText = sText.Left (pos); + } + } + if (bEnable) + { + CPoint ptFoundPos; + //BEGIN SW + // for correct backward search we need some changes: + CPoint ptSearchPos = m_ptCursorPos; + if( m_dwLastSearchFlags & FIND_DIRECTION_UP && IsSelection() ) + { + CPoint ptDummy; + GetSelection( ptSearchPos, ptDummy ); + } + + if (! FindText(sText, ptSearchPos, m_dwLastSearchFlags, TRUE, &ptFoundPos)) + /*ORIGINAL + if (! FindText(sText, m_ptCursorPos, m_dwLastSearchFlags, TRUE, &ptFoundPos)) + *///END SW + { + CString prompt; + prompt.Format (IDS_EDIT_TEXT_NOT_FOUND, sText); + AfxMessageBox (prompt); + return; + } + HighlightText (ptFoundPos, m_nLastFindWhatLen, (m_dwLastSearchFlags & FIND_DIRECTION_UP) != 0); + m_bMultipleSearch = TRUE; // More search + + } +} + +void CCrystalTextView:: +OnUpdateEditRepeat (CCmdUI * pCmdUI) +{ + BOOL bEnable = m_bLastSearch; + if (!bEnable) + { + CString sText; + bEnable = CMemComboBox::groups.Lookup (_T ("FindText"), sText) && !sText.IsEmpty (); + } + pCmdUI->Enable (bEnable); +} + +void CCrystalTextView:: +OnEditFindPrevious () +{ + DWORD dwSaveSearchFlags = m_dwLastSearchFlags; + if ((m_dwLastSearchFlags & FIND_DIRECTION_UP) != 0) + m_dwLastSearchFlags &= ~FIND_DIRECTION_UP; + else + m_dwLastSearchFlags |= FIND_DIRECTION_UP; + OnEditRepeat (); + m_dwLastSearchFlags = dwSaveSearchFlags; +} + +void CCrystalTextView:: +OnUpdateEditFindPrevious (CCmdUI * pCmdUI) +{ + BOOL bEnable = m_bLastSearch; + if (!bEnable) + { + CString sText; + bEnable = CMemComboBox::groups.Lookup (_T ("FindText"), sText) && !sText.IsEmpty (); + } + pCmdUI->Enable (bEnable); +} + +void CCrystalTextView:: +OnFilePageSetup () +{ + CWinApp *pApp = AfxGetApp (); + ASSERT (pApp != NULL); + + CPageSetupDialog dlg; + //dlg.m_psd.Flags &= ~PSD_INTHOUSANDTHSOFINCHES; + dlg.m_psd.Flags = PSD_INHUNDREDTHSOFMILLIMETERS|PSD_MARGINS; + dlg.m_psd.rtMargin.left = DEFAULT_PRINT_MARGIN; + dlg.m_psd.rtMargin.right = DEFAULT_PRINT_MARGIN; + dlg.m_psd.rtMargin.top = DEFAULT_PRINT_MARGIN; + dlg.m_psd.rtMargin.bottom = DEFAULT_PRINT_MARGIN; + CReg reg; + if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ)) + { + DWORD dwTemp; + if (reg.LoadNumber (_T ("PageWidth"), &dwTemp)) + dlg.m_psd.ptPaperSize.x = dwTemp; + if (reg.LoadNumber (_T ("PageHeight"), &dwTemp)) + dlg.m_psd.ptPaperSize.y = dwTemp; + if (reg.LoadNumber (_T ("PageLeft"), &dwTemp)) + dlg.m_psd.rtMargin.left = dwTemp; + if (reg.LoadNumber (_T ("PageRight"), &dwTemp)) + dlg.m_psd.rtMargin.right = dwTemp; + if (reg.LoadNumber (_T ("PageTop"), &dwTemp)) + dlg.m_psd.rtMargin.top = dwTemp; + if (reg.LoadNumber (_T ("PageBottom"), &dwTemp)) + dlg.m_psd.rtMargin.bottom = dwTemp; + } + if (dlg.DoModal () == IDOK) + { + CReg reg; + if (reg.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE)) + { + VERIFY (reg.SaveNumber (_T ("PageWidth"), dlg.m_psd.ptPaperSize.x)); + VERIFY (reg.SaveNumber (_T ("PageHeight"), dlg.m_psd.ptPaperSize.y)); + VERIFY (reg.SaveNumber (_T ("PageLeft"), dlg.m_psd.rtMargin.left)); + VERIFY (reg.SaveNumber (_T ("PageRight"), dlg.m_psd.rtMargin.right)); + VERIFY (reg.SaveNumber (_T ("PageTop"), dlg.m_psd.rtMargin.top)); + VERIFY (reg.SaveNumber (_T ("PageBottom"), dlg.m_psd.rtMargin.bottom)); + } + } +} + +void CCrystalTextView:: +OnToggleBookmark () +{ + if (m_pTextBuffer != NULL) + { + DWORD dwFlags = GetLineFlags (m_ptCursorPos.y); + DWORD dwMask = LF_BOOKMARKS; + m_pTextBuffer->SetLineFlag (m_ptCursorPos.y, dwMask, (dwFlags & dwMask) == 0, FALSE); + } + int nLine = m_pTextBuffer->GetLineWithFlag (LF_BOOKMARKS); + if (nLine >= 0) + m_bBookmarkExist = TRUE; + else + m_bBookmarkExist = FALSE; +} + +void CCrystalTextView:: +OnNextBookmark () +{ + if (m_pTextBuffer != NULL) + { + int nLine = m_pTextBuffer->FindNextBookmarkLine (m_ptCursorPos.y); + if (nLine >= 0) + { + CPoint pt (0, nLine); + ASSERT_VALIDTEXTPOS (pt); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + } + } +} + +void CCrystalTextView:: +OnPrevBookmark () +{ + if (m_pTextBuffer != NULL) + { + int nLine = m_pTextBuffer->FindPrevBookmarkLine (m_ptCursorPos.y); + if (nLine >= 0) + { + CPoint pt (0, nLine); + ASSERT_VALIDTEXTPOS (pt); + SetCursorPos (pt); + SetSelection (pt, pt); + SetAnchor (pt); + EnsureVisible (pt); + } + } +} + +void CCrystalTextView:: +OnClearAllBookmarks () +{ + if (m_pTextBuffer != NULL) + { + int nLineCount = GetLineCount (); + for (int I = 0; I < nLineCount; I++) + { + if (m_pTextBuffer->GetLineFlags (I) & LF_BOOKMARKS) + m_pTextBuffer->SetLineFlag (I, LF_BOOKMARKS, FALSE); + } + m_bBookmarkExist = FALSE; + } +} + +void CCrystalTextView:: +OnUpdateNextBookmark (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_bBookmarkExist); +} + +void CCrystalTextView:: +OnUpdatePrevBookmark (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_bBookmarkExist); +} + +void CCrystalTextView:: +OnUpdateClearAllBookmarks (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_bBookmarkExist); +} + +BOOL CCrystalTextView:: +GetViewTabs () +{ + return m_bViewTabs; +} + +void CCrystalTextView:: +SetViewTabs (BOOL bViewTabs) +{ + if (bViewTabs != m_bViewTabs) + { + m_bViewTabs = bViewTabs; + if (::IsWindow (m_hWnd)) + Invalidate (); + } +} + +DWORD CCrystalTextView:: +GetFlags () +{ + return m_dwFlags; +} + +void CCrystalTextView:: +SetFlags (DWORD dwFlags) +{ + if (m_dwFlags != dwFlags) + { + m_dwFlags = dwFlags; + if (::IsWindow (m_hWnd)) + Invalidate (); + } +} + +BOOL CCrystalTextView:: +GetSelectionMargin () +{ + return m_bSelMargin; +} + +int CCrystalTextView:: +GetMarginWidth () +{ + return m_bSelMargin ? 20 : 1; +} + +BOOL CCrystalTextView:: +GetSmoothScroll () +const +{ + return m_bSmoothScroll; +} + +void CCrystalTextView::SetSmoothScroll (BOOL bSmoothScroll) +{ + m_bSmoothScroll = bSmoothScroll; +} + +// [JRT] +BOOL CCrystalTextView:: +GetDisableDragAndDrop () +const +{ + return m_bDisableDragAndDrop; +} + +// [JRT] +void CCrystalTextView::SetDisableDragAndDrop (BOOL bDDAD) +{ + m_bDisableDragAndDrop = bDDAD; +} + +// +// Mouse wheel event. zDelta is in multiples of 120. +// Divide by 40 so each click is 3 lines. I know some +// drivers let you set the ammount of scroll, but I +// don't know how to retrieve this or if they just +// adjust the zDelta you get here. +BOOL CCrystalTextView:: +OnMouseWheel (UINT nFlags, short zDelta, CPoint pt) +{ + // -> HE + int nPageLines = GetScreenLines(); + int nSubLineCount = GetSubLineCount(); + + int nNewTopSubLine= m_nTopSubLine - zDelta / 40; + + if (nNewTopSubLine < 0) + nNewTopSubLine = 0; + if (nNewTopSubLine >= nSubLineCount) + nNewTopSubLine = nSubLineCount - 1; + + ScrollToSubLine(nNewTopSubLine, TRUE); + UpdateSiblingScrollPos(FALSE); + // <- HE +/* Old + int nLineCount = GetLineCount (); + + int nNewTopLine = m_nTopLine - zDelta / 40; + + if (nNewTopLine < 0) + nNewTopLine = 0; + if (nNewTopLine >= nLineCount) + nNewTopLine = nLineCount - 1; + + if (m_nTopLine != nNewTopLine) + { + int nScrollLines = m_nTopLine - nNewTopLine; + m_nTopLine = nNewTopLine; + ScrollWindow (0, nScrollLines * GetLineHeight ()); + UpdateWindow (); + } + + RecalcVertScrollBar (TRUE); +*/ + + return CView::OnMouseWheel (nFlags, zDelta, pt); +} + +void CCrystalTextView:: +OnSourceType (UINT nId) +{ + SetTextType ((CCrystalTextView::TextType) (nId - ID_SOURCE_PLAIN)); + Invalidate (); +} + +void CCrystalTextView:: +OnUpdateSourceType (CCmdUI * pCmdUI) +{ + pCmdUI->SetRadio (m_SourceDefs + (pCmdUI->m_nID - ID_SOURCE_PLAIN) == m_CurSourceDef); +} + +int bracetype (TCHAR c); + +void CCrystalTextView:: +OnMatchBrace () +{ + CPoint ptCursorPos = GetCursorPos (); + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y), pszEnd = pszText + ptCursorPos.x; + bool bAfter; + int nType = 0; + if (ptCursorPos.x < nLength) + { + nType = bracetype (*pszEnd); + if (nType) + { + bAfter = false; + } + else if (!nType && ptCursorPos.x > 0) + { + nType = bracetype (pszEnd[-1]); + bAfter = true; + } + } + else if (ptCursorPos.x > 0) + { + nType = bracetype (pszEnd[-1]); + bAfter = true; + } + if (nType) + { + int nOther, nCount = 0, nComment = 0; + if (bAfter) + { + nOther = ((nType - 1) ^ 1) + 1; + if (nOther & 1) + pszEnd--; + } + else + { + nOther = ((nType - 1) ^ 1) + 1; + if (!(nOther & 1)) + pszEnd++; + } + LPCTSTR pszOpenComment = m_CurSourceDef->opencomment, + pszCloseComment = m_CurSourceDef->closecomment, + pszCommentLine = m_CurSourceDef->commentline, pszTest; + int nOpenComment = _tcslen (pszOpenComment), + nCloseComment = _tcslen (pszCloseComment), + nCommentLine = _tcslen (pszCommentLine); + if (nOther & 1) + { + for (;;) + { + while (--pszEnd >= pszText) + { + pszTest = pszEnd - nOpenComment + 1; + if (pszTest >= pszText && !_tcsnicmp (pszTest, pszOpenComment, nOpenComment)) + { + nComment--; + pszEnd = pszTest; + if (--pszEnd < pszText) + { + break; + } + } + pszTest = pszEnd - nCloseComment + 1; + if (pszTest >= pszText && !_tcsnicmp (pszTest, pszCloseComment, nCloseComment)) + { + nComment++; + pszEnd = pszTest; + if (--pszEnd < pszText) + { + break; + } + } + if (!nComment) + { + pszTest = pszEnd - nCommentLine + 1; + if (pszTest >= pszText && !_tcsnicmp (pszTest, pszCommentLine, nCommentLine)) + { + break; + } + if (bracetype (*pszEnd) == nType) + { + nCount++; + } + else if (bracetype (*pszEnd) == nOther) + { + if (!nCount--) + { + ptCursorPos.x = pszEnd - pszText; + if (bAfter) + ptCursorPos.x++; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + return; + } + } + } + } + if (ptCursorPos.y) + { + ptCursorPos.x = m_pTextBuffer->GetLineLength (--ptCursorPos.y); + pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y); + pszEnd = pszText + ptCursorPos.x; + } + else + break; + } + } + else + { + LPCTSTR pszBegin = pszText; + pszText = pszEnd; + pszEnd = pszBegin + nLength; + int nLines = m_pTextBuffer->GetLineCount (); + for (;;) + { + while (pszText < pszEnd) + { + pszTest = pszText + nCloseComment; + if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszCloseComment, nCloseComment)) + { + nComment--; + pszText = pszTest; + if (pszText > pszEnd) + { + break; + } + } + pszTest = pszText + nOpenComment; + if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszOpenComment, nOpenComment)) + { + nComment++; + pszText = pszTest; + if (pszText > pszEnd) + { + break; + } + } + if (!nComment) + { + pszTest = pszText + nCommentLine; + if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszCommentLine, nCommentLine)) + { + break; + } + if (bracetype (*pszText) == nType) + { + nCount++; + } + else if (bracetype (*pszText) == nOther) + { + if (!nCount--) + { + ptCursorPos.x = pszText - pszBegin; + if (bAfter) + ptCursorPos.x++; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + return; + } + } + } + pszText++; + } + if (ptCursorPos.y < nLines) + { + ptCursorPos.x = 0; + nLength = m_pTextBuffer->GetLineLength (++ptCursorPos.y); + pszBegin = pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y); + pszEnd = pszBegin + nLength; + } + else + break; + } + } + } +} + +void CCrystalTextView:: +OnUpdateMatchBrace (CCmdUI * pCmdUI) +{ + CPoint ptCursorPos = GetCursorPos (); + int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y); + LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y) + ptCursorPos.x; + pCmdUI->Enable (ptCursorPos.x < nLength && (bracetype (*pszText) || ptCursorPos.x > 0 && bracetype (pszText[-1])) || ptCursorPos.x > 0 && bracetype (pszText[-1])); +} + +void CCrystalTextView:: +OnEditGoTo () +{ + CGotoDlg dlg (this); + dlg.DoModal (); +} + +void CCrystalTextView:: +OnUpdateToggleSourceHeader (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_CurSourceDef->type == SRC_C); +} + +void CCrystalTextView:: +OnToggleSourceHeader () +{ + if (m_CurSourceDef->type == SRC_C) + { + CDocument *pDoc = GetDocument (); + ASSERT (pDoc); + CString sFilePath = pDoc->GetPathName (), sOriginalPath = sFilePath; + if (!_tcsicmp (sFilePath.Right (2), _T (".c"))) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 1) + _T ('h'); + } + else if (!_tcsicmp (sFilePath.Right (4), _T (".cpp"))) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('h'); + } + else if (!_tcsicmp (sFilePath.Right (4), _T (".inl"))) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('c'); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath + _T ("pp"); + } + } + else if (!_tcsicmp (sFilePath.Right (4), _T (".hpp"))) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ("inl"); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('c'); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath + _T ("pp"); + } + } + } + else if (!_tcsicmp (sFilePath.Right (2), _T (".h"))) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 1) + _T ("hpp"); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ("inl"); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('c'); + if (!FileExist(sFilePath)) + { + sFilePath = sFilePath + _T ("pp"); + } + } + } + } + if (FileExist(sFilePath)) + { + if (!m_bSingle || !pDoc->IsModified () || pDoc->DoSave (sOriginalPath)) + { + AfxGetApp ()->OpenDocumentFile (sFilePath); + if (m_bSingle) + { + m_ptCursorLast.x = m_ptCursorLast.y = 0; + ASSERT_VALIDTEXTPOS (m_ptCursorLast); + CPoint ptCursorPos = m_ptCursorLast; + SetCursorPos (ptCursorPos); + SetSelection (ptCursorPos, ptCursorPos); + SetAnchor (ptCursorPos); + EnsureVisible (ptCursorPos); + Invalidate (); + } + } + } + } +} + +void CCrystalTextView:: +OnUpdateSelMargin (CCmdUI * pCmdUI) +{ + pCmdUI->SetCheck (m_bSelMargin); +} + +void CCrystalTextView:: +OnSelMargin () +{ + ASSERT (m_CurSourceDef); + if (m_bSelMargin) + { + m_CurSourceDef->flags &= ~SRCOPT_SELMARGIN; + SetSelectionMargin (FALSE); + } + else + { + m_CurSourceDef->flags |= SRCOPT_SELMARGIN; + SetSelectionMargin (TRUE); + } +} + +void CCrystalTextView:: +OnUpdateWordWrap (CCmdUI * pCmdUI) +{ + pCmdUI->SetCheck (m_bWordWrap); +} + +void CCrystalTextView:: +OnWordWrap () +{ + ASSERT (m_CurSourceDef); + if (m_bWordWrap) + { + m_CurSourceDef->flags &= ~SRCOPT_WORDWRAP; + SetWordWrapping (FALSE); + } + else + { + m_CurSourceDef->flags |= SRCOPT_WORDWRAP; + SetWordWrapping (TRUE); + } +} + +void CCrystalTextView:: +OnForceRedraw () +{ + //Invalidate (); + RedrawWindow (NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ERASENOW); +} + +//BEGIN SW +BOOL CCrystalTextView::GetWordWrapping() const +{ + return m_bWordWrap; +} + +void CCrystalTextView::SetWordWrapping( BOOL bWordWrap ) +{ + m_bWordWrap = bWordWrap; + + if( IsWindow( m_hWnd ) ) + InvalidateLines( 0, -1, TRUE ); +} + +CCrystalParser *CCrystalTextView::SetParser( CCrystalParser *pParser ) +{ + CCrystalParser *pOldParser = m_pParser; + + m_pParser = pParser; + + if( pParser ) + pParser->m_pTextView = this; + + return pOldParser; +} +//END SW + + +//BEGIN SW +// incremental search imlementation +BOOL CCrystalTextView::OnCmdMsg( UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO *pHandlerInfo ) +{ + // just look for commands + if( nCode != CN_COMMAND || pExtra ) + return CView::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ); + + // handle code: + // each command that is not related to incremental search + // ends the incremental search + if( nID == ID_EDIT_FIND_INCREMENTAL_FORWARD || + nID == ID_EDIT_FIND_INCREMENTAL_BACKWARD || + nID == ID_EDIT_DELETE_BACK ) + return CView::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ); + + if( nID >= ID_EDIT_FIRST && nID <= ID_EDIT_LAST ) + m_bIncrementalSearchForward = m_bIncrementalSearchBackward = FALSE; + + return CView::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ); +} + +void CCrystalTextView::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ) +{ + CView::OnChar( nChar, nRepCnt, nFlags ); + + // we only have to handle character-input, if we are in incremental search mode + if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + return; + + // exit incremental search, wenn Escape is pressed + if( nChar == VK_ESCAPE ) + { + // if not end incremental search + m_bIncrementalSearchForward = m_bIncrementalSearchBackward = FALSE; + SetSelection( m_selStartBeforeIncrementalSearch, m_selEndBeforeIncrementalSearch ); + SetCursorPos( m_cursorPosBeforeIncrementalSearch ); + EnsureVisible( m_cursorPosBeforeIncrementalSearch ); + return; + } + + // exit incremental search without destroying selection + if( nChar == VK_RETURN ) + { + m_bIncrementalSearchForward = m_bIncrementalSearchBackward = FALSE; + return; + } + + // is the character valid for incremental search? + if( !_istgraph( nChar ) && !(nChar == _T(' ')) && !(nChar == _T('\t')) ) + { + // if not end incremental search + m_bIncrementalSearchForward = m_bIncrementalSearchBackward = FALSE; + return; + } + + // if last search was not successfull do not add a new character + if( !m_bIncrementalFound ) + { + MessageBeep( MB_OK ); + return; + } + + // add character to incremental search string and search + *m_pstrIncrementalSearchString += (TCHAR) nChar; + OnEditFindIncremental(); +} + + +void CCrystalTextView::OnEditDeleteBack() +{ + if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + return; + + // remove last character from search string + if( m_pstrIncrementalSearchString->IsEmpty() ) + return; + + *m_pstrIncrementalSearchString = m_pstrIncrementalSearchString->Left( m_pstrIncrementalSearchString->GetLength() - 1 ); + OnEditFindIncremental(); +} + + +void CCrystalTextView::OnEditFindIncremental( BOOL bFindNextOccurence /*= FALSE*/ ) +{ + // when string is empty, then goto position where the search starts + if( m_pstrIncrementalSearchString->IsEmpty() ) + { + SetSelection( m_incrementalSearchStartPos, m_incrementalSearchStartPos ); + SetCursorPos( m_incrementalSearchStartPos ); + EnsureVisible( m_incrementalSearchStartPos ); + return; + } + + // otherwise search next occurence of search string, + // starting at current cursor position + CPoint matchStart, matchEnd; + + // calculate start point for search + if( bFindNextOccurence ) + { + CPoint selStart, selEnd; + GetSelection( selStart, selEnd ); + m_incrementalSearchStartPos = (m_bIncrementalSearchBackward)? selStart : selEnd; + } + + m_bIncrementalFound = FindText( + *m_pstrIncrementalSearchString, + m_incrementalSearchStartPos, + m_bIncrementalSearchBackward? FIND_DIRECTION_UP : 0, + TRUE, + &matchStart ); + + if( !m_bIncrementalFound ) + { + MessageBeep( MB_OK ); + return; + } + + // select found text and set cursor to end of match + matchEnd = matchStart; + matchEnd.x+= m_pstrIncrementalSearchString->GetLength(); + SetSelection( matchStart, matchEnd ); + SetCursorPos( matchEnd ); + EnsureVisible( matchEnd ); +} + + + +void CCrystalTextView::OnEditFindIncrementalForward() +{ + if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + { + // initialize + if( !m_pstrIncrementalSearchString->IsEmpty() ) + *m_pstrIncrementalSearchStringOld = *m_pstrIncrementalSearchString; + m_pstrIncrementalSearchString->Empty(); + m_incrementalSearchStartPos = m_cursorPosBeforeIncrementalSearch = m_ptCursorPos; + GetSelection( m_selStartBeforeIncrementalSearch, m_selEndBeforeIncrementalSearch ); + } + else if( m_bIncrementalSearchForward ) + { + if( m_pstrIncrementalSearchString->IsEmpty() ) + { + *m_pstrIncrementalSearchString = *m_pstrIncrementalSearchStringOld; + m_pstrIncrementalSearchStringOld->Empty(); + OnEditFindIncremental(); + } + else + OnEditFindIncremental( TRUE ); + + return; + } + + m_bIncrementalSearchForward = TRUE; + m_bIncrementalSearchBackward = FALSE; + m_bIncrementalFound = TRUE; + OnEditFindIncremental(); +} + +void CCrystalTextView::OnEditFindIncrementalBackward() +{ + if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + { + // initialize + if( !m_pstrIncrementalSearchString->IsEmpty() ) + *m_pstrIncrementalSearchStringOld = *m_pstrIncrementalSearchString; + m_pstrIncrementalSearchString->Empty(); + GetSelection( m_selStartBeforeIncrementalSearch, m_selEndBeforeIncrementalSearch ); + m_incrementalSearchStartPos = m_cursorPosBeforeIncrementalSearch = m_ptCursorPos; + } + else if( m_bIncrementalSearchBackward ) + { + if( m_pstrIncrementalSearchString->IsEmpty() ) + { + *m_pstrIncrementalSearchString = *m_pstrIncrementalSearchStringOld; + m_pstrIncrementalSearchStringOld->Empty(); + OnEditFindIncremental(); + } + else + OnEditFindIncremental( TRUE ); + + return; + } + + m_bIncrementalSearchForward = FALSE; + m_bIncrementalSearchBackward = TRUE; + m_bIncrementalFound = TRUE; + OnEditFindIncremental(); +} + +void CCrystalTextView::OnUpdateEditFindIncrementalForward(CCmdUI* pCmdUI) +{ + if (m_pTextBuffer) + { + int nLines = m_pTextBuffer->GetLineCount (); + int nChars = m_pTextBuffer->GetLineLength (m_ptCursorPos.y); + pCmdUI->Enable(m_ptCursorPos.y < nLines - 1 || m_ptCursorPos.x < nChars); + return; + } + pCmdUI->Enable(FALSE); +} + +void CCrystalTextView::OnUpdateEditFindIncrementalBackward(CCmdUI* pCmdUI) +{ + if (m_pTextBuffer) + { + pCmdUI->Enable(m_ptCursorPos.y > 0 || m_ptCursorPos.x > 0); + return; + } + pCmdUI->Enable(FALSE); +} + +void CCrystalTextView::OnUpdateStatusMessage( CStatusBar *pStatusBar ) +{ + static BOOL bUpdatedAtLastCall = FALSE; + + ASSERT( pStatusBar && IsWindow( pStatusBar->m_hWnd ) ); + if( !pStatusBar || !IsWindow( pStatusBar->m_hWnd ) ) + return; + + if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward ) + { + if( bUpdatedAtLastCall ) + pStatusBar->SetPaneText( 0, CString( (LPCTSTR)AFX_IDS_IDLEMESSAGE ) ); + + bUpdatedAtLastCall = FALSE; + + return; + } + + CString strFormat; + if( !m_bIncrementalFound ) + strFormat.Format( IDS_FIND_INCREMENTAL_FAILED, *m_pstrIncrementalSearchString ); + else if( m_bIncrementalSearchForward ) + strFormat.Format( IDS_FIND_INCREMENTAL_FORWARD, *m_pstrIncrementalSearchString ); + else if( m_bIncrementalSearchBackward ) + strFormat.Format( IDS_FIND_INCREMENTAL_BACKWARD, *m_pstrIncrementalSearchString ); + + if( strFormat.IsEmpty() ) + return; + + pStatusBar->SetPaneText( 0, strFormat ); + bUpdatedAtLastCall = TRUE; +} +//END SW + +//////////////////////////////////////////////////////////////////////////// +#pragma warning ( default : 4100 ) diff --git a/Src/editlib/ccrystaltextview.h b/Src/editlib/ccrystaltextview.h new file mode 100644 index 000000000..a7ee1c8e8 --- /dev/null +++ b/Src/editlib/ccrystaltextview.h @@ -0,0 +1,902 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaltextview.h +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Interface of the CCrystalTextView class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CCRYSTALTEXTVIEW_H__AD7F2F41_6CB3_11D2_8C32_0080ADB86836__INCLUDED_) +#define AFX_CCRYSTALTEXTVIEW_H__AD7F2F41_6CB3_11D2_8C32_0080ADB86836__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "cregexp.h" +#include "crystalparser.h" + +//////////////////////////////////////////////////////////////////////////// +// Forward class declarations + +class CCrystalTextBuffer; +class CUpdateContext; + + +//////////////////////////////////////////////////////////////////////////// +// CCrystalTextView class declaration + +// CCrystalTextView::FindText() flags +enum +{ + FIND_MATCH_CASE = 0x0001, + FIND_WHOLE_WORD = 0x0002, + FIND_REGEXP = 0x0004, + FIND_DIRECTION_UP = 0x0010, + REPLACE_SELECTION = 0x0100 +}; + +// CCrystalTextView::UpdateView() flags +enum +{ + UPDATE_HORZRANGE = 0x0001, // update horz scrollbar + UPDATE_VERTRANGE = 0x0002, // update vert scrollbar + UPDATE_SINGLELINE = 0x0100, // single line has changed + UPDATE_FLAGSONLY = 0x0200, // only line-flags were changed + + UPDATE_RESET = 0x1000 // document was reloaded, update all! +}; + +class EDITPADC_CLASS CCrystalTextView : public CView + { + DECLARE_DYNCREATE (CCrystalTextView) + + //BEGIN SW + friend CCrystalParser; + //END SW + +protected: + // Search parameters + BOOL m_bLastSearch; + DWORD m_dwLastSearchFlags; + LPTSTR m_pszLastFindWhat; + BOOL m_bMultipleSearch; // More search + +private : + BOOL m_bCursorHidden; + + // Painting caching bitmap + CBitmap *m_pCacheBitmap; + + // Line/character dimensions + int m_nLineHeight, m_nCharWidth; + void CalcLineCharDim (); + + // Text attributes + int m_nTabSize; + BOOL m_bViewTabs; + BOOL m_bSelMargin; + DWORD m_dwFlags; + + // Amount of lines/characters that completely fits the client area + int m_nScreenLines, m_nScreenChars; + + //BEGIN SW + /** + Contains for each line the number of sublines. If the line is not + wrapped, the value for this line is 1. The value of a line is invalid, + if it is -1. + + Must create pointer, because contructor uses AFX_ZERO_INIT_OBJECT to + initialize the member objects. This would destroy a CArray object. + */ + CArray *m_panSubLines; + //END SW + + int m_nMaxLineLength; + int m_nIdealCharPos; + + BOOL m_bFocused; + CPoint m_ptAnchor; + LOGFONT m_lfBaseFont; + CFont *m_apFonts[4]; + + // Parsing stuff + DWORD *m_pdwParseCookies; + int m_nParseArraySize; + DWORD GetParseCookie (int nLineIndex); + + // Pre-calculated line lengths (in characters) + int m_nActualLengthArraySize; + int *m_pnActualLineLength; + + BOOL m_bPreparingToDrag; + BOOL m_bDraggingText; + BOOL m_bDragSelection, m_bWordSelection, m_bLineSelection; + UINT m_nDragSelTimer; + + CPoint m_ptDrawSelStart, m_ptDrawSelEnd; + CPoint m_ptCursorPos, m_ptCursorLast; + CPoint m_ptSelStart, m_ptSelEnd; + void PrepareSelBounds (); + + // Helper functions + void ExpandChars (LPCTSTR pszChars, int nOffset, int nCount, CString & line); + + int ApproxActualOffset (int nLineIndex, int nOffset); + void AdjustTextPoint (CPoint & point); + void DrawLineHelperImpl (CDC * pdc, CPoint & ptOrigin, const CRect & rcClip, + LPCTSTR pszChars, int nOffset, int nCount); + BOOL IsInsideSelBlock (CPoint ptTextPos); + + BOOL m_bBookmarkExist; // More bookmarks + +public : + virtual void ResetView (); + virtual int GetLineCount (); + +protected : + CPoint WordToRight (CPoint pt); + CPoint WordToLeft (CPoint pt); + + bool m_bSingle; + CImageList * m_pIcons; + CCrystalTextBuffer *m_pTextBuffer; + HACCEL m_hAccel; + BOOL m_bVertScrollBarLocked, m_bHorzScrollBarLocked; + CPoint m_ptDraggedTextBegin, m_ptDraggedTextEnd; + void UpdateCaret (); + void SetAnchor (const CPoint & ptNewAnchor); + int GetMarginWidth (); + bool IsValidTextPos (const CPoint &point); + bool IsValidTextPosX (const CPoint &point); + bool IsValidTextPosY (const CPoint &point); + + BOOL m_bShowInactiveSelection; + // [JRT] + BOOL m_bDisableDragAndDrop; + + //BEGIN SW + BOOL m_bWordWrap; + CCrystalParser *m_pParser; + //END SW + + CPoint ClientToText (const CPoint & point); + CPoint TextToClient (const CPoint & point); + void InvalidateLines (int nLine1, int nLine2, BOOL bInvalidateMargin = FALSE); + int CalculateActualOffset (int nLineIndex, int nCharIndex); + + // Printing + int m_nPrintPages; + int *m_pnPages; + CFont *m_pPrintFont; + int m_nPrintLineHeight; + BOOL m_bPrintHeader, m_bPrintFooter; + CRect m_ptPageArea, m_rcPrintArea; + int PrintLineHeight (CDC * pdc, int nLine); + void RecalcPageLayouts (CDC * pdc, CPrintInfo * pInfo); + virtual void PrintHeader (CDC * pdc, int nPageNum); + virtual void PrintFooter (CDC * pdc, int nPageNum); + virtual void GetPrintHeaderText (int nPageNum, CString & text); + virtual void GetPrintFooterText (int nPageNum, CString & text); + + // Keyboard handlers + void MoveLeft (BOOL bSelect); + void MoveRight (BOOL bSelect); + void MoveWordLeft (BOOL bSelect); + void MoveWordRight (BOOL bSelect); + void MoveUp (BOOL bSelect); + void MoveDown (BOOL bSelect); + void MoveHome (BOOL bSelect); + void MoveEnd (BOOL bSelect); + void MovePgUp (BOOL bSelect); + void MovePgDn (BOOL bSelect); + void MoveCtrlHome (BOOL bSelect); + void MoveCtrlEnd (BOOL bSelect); + + void SelectAll (); + void Copy (); + + BOOL IsSelection (); + BOOL IsInsideSelection (const CPoint & ptTextPos); + void GetSelection (CPoint & ptStart, CPoint & ptEnd); + void SetSelection (const CPoint & ptStart, const CPoint & ptEnd); + + int m_nTopLine, m_nOffsetChar; + //BEGIN SW + /** + The index of the subline that is the first visible line on the screen. + */ + int m_nTopSubLine; + //END SW + BOOL m_bSmoothScroll; + + int GetLineHeight (); + //BEGIN SW + /** + Returns the number of sublines the given line contains of. + Allway "1", if word wrapping is disabled. + + @param nLineIndex Index of the line to get the subline count of. + + @return Number of sublines the given line contains of + */ + int GetSubLines( int nLineIndex ); + + /** + Converts the given character position for the given line into a point. + + After the call the x-member of the returned point contains the + character position relative to the beginning of the subline. The y-member + contains the zero based index of the subline relative to the line, the + character position was given for. + + @param nLineIndex Zero based index of the line, nCharPos refers to. + @param nCharPos The character position, the point shoult be calculated for. + @param charPoint Reference to a point, which should receive the result. + + @return The character position of the beginning of the subline charPoint.y. + */ + int CharPosToPoint( int nLineIndex, int nCharPos, CPoint &charPoint ); + + /** + Converts the given cursor point for the given line to the character position + for the given line. + + The y-member of the cursor position specifies the subline inside the given + line, the cursor is placed on and the x-member specifies the cursor position + (in character widths) relative to the beginning of that subline. + + @param nLineIndex Zero based index of the line the cursor position refers to. + @param curPoint Position of the cursor relative to the line in sub lines and + char widths. + + @return The character position the best matches the cursor position. + */ + int CursorPointToCharPos( int nLineIndex, const CPoint &curPoint ); + + /** + Converts the given cursor position to a text position. + + The x-member of the subLinePos parameter describes the cursor position in + char widths relative to the beginning of the subline described by the + y-member. The subline is the zero based number of the subline relative to + the beginning of the text buffer. + +

+ The returned point contains a valid text position, where the y-member is + the zero based index of the textline and the x-member is the character + position inside this line. + + @param subLinePos The sublinebased cursor position + (see text above for detailed description). + @param textPos The calculated line and character position that best matches + the cursor position (see text above for detailed descritpion). + */ + void SubLineCursorPosToTextPos( const CPoint &subLinePos, CPoint &textPos ); + + /** + Returns the character position relative to the given line, that matches + the end of the given sub line. + + @param nLineIndex Zero based index of the line to work on. + @param nSubLineOffset Zero based index of the subline inside the given line. + + @return Character position that matches the end of the given subline, relative + to the given line. + */ + int SubLineEndToCharPos( int nLineIndex, int nSubLineOffset ); + + /** + Returns the character position relative to the given line, that matches + the start of the given sub line. + + @param nLineIndex Zero based index of the line to work on. + @param nSubLineOffset Zero based index of the subline inside the given line. + + @return Character position that matches the start of the given subline, relative + to the given line. + */ + int SubLineHomeToCharPos( int nLineIndex, int nSubLineOffset ); + //END SW + int GetCharWidth (); + int GetMaxLineLength (); + int GetScreenLines (); + int GetScreenChars (); + CFont *GetFont (BOOL bItalic = FALSE, BOOL bBold = FALSE); + + void RecalcVertScrollBar (BOOL bPositionOnly = FALSE); + void RecalcHorzScrollBar (BOOL bPositionOnly = FALSE); + + // Scrolling helpers + void ScrollToChar (int nNewOffsetChar, BOOL bNoSmoothScroll = FALSE, BOOL bTrackScrollBar = TRUE); + void ScrollToLine (int nNewTopLine, BOOL bNoSmoothScroll = FALSE, BOOL bTrackScrollBar = TRUE); + + //BEGIN SW + /** + Scrolls to the given sub line, so that the sub line is the first visible + line on the screen. + + @param nNewTopSubLine Index of the sub line to scroll to. + @param bNoSmoothScroll TRUE to disable smooth scrolling, else FALSE. + @param bTrackScrollBar TRUE to recalculate the scroll bar after scrolling, + else FALSE. + */ + void ScrollToSubLine( int nNewTopSubLine, BOOL bNoSmoothScroll = FALSE, BOOL bTrackScrollBar = TRUE ); + //END SW + + // Splitter support + virtual void UpdateSiblingScrollPos (BOOL bHorz); + virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, BOOL bHorz); + CCrystalTextView *GetSiblingView (int nRow, int nCol); + + //BEGIN SW + /** + Returns the number of sublines in the whole text buffer. + + The number of sublines is the sum of all sublines of all lines. + + @return Number of sublines in the whole text buffer. + */ + virtual int GetSubLineCount(); + + /** + Returns the zero-based subline index of the given line. + + @param nLineIndex Index of the line to calculate the subline index of + + @return The zero-based subline index of the given line. + */ + virtual int GetSubLineIndex( int nLineIndex ); + + /** + Splits the given subline index into line and sub line of this line. + + @param nSubLineIndex The zero based index of the subline to get info about + @param nLine Gets the line number the give subline is included in + @param nSubLine Get the subline of the given subline relative to nLine + */ + virtual void GetLineBySubLine( int nSubLineIndex, int &nLine, int &nSubLine ); + //END SW + + virtual int GetLineLength (int nLineIndex); + virtual int GetLineActualLength (int nLineIndex); + virtual LPCTSTR GetLineChars (int nLineIndex); + virtual DWORD GetLineFlags (int nLineIndex); + virtual void GetText (const CPoint & ptStart, const CPoint & ptEnd, CString & text); + + // Clipboard overridable + virtual BOOL TextInClipboard (); + virtual BOOL PutToClipboard (LPCTSTR pszText); + virtual BOOL GetFromClipboard (CString & text); + + // Drag-n-drop overrideable + virtual HGLOBAL PrepareDragData (); + virtual DROPEFFECT GetDropEffect (); + virtual void OnDropSource (DROPEFFECT de); + BOOL IsDraggingText () const; + + virtual COLORREF GetColor (int nColorIndex); + virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd, + COLORREF & crText, BOOL & bDrawWhitespace); + virtual BOOL GetItalic (int nColorIndex); + virtual BOOL GetBold (int nColorIndex); + + void DrawLineHelper (CDC * pdc, CPoint & ptOrigin, const CRect & rcClip, int nColorIndex, + LPCTSTR pszChars, int nOffset, int nCount, CPoint ptTextPos); + virtual void DrawSingleLine (CDC * pdc, const CRect & rect, int nLineIndex); + virtual void DrawMargin (CDC * pdc, const CRect & rect, int nLineIndex); + + //BEGIN SW + // word wrapping + + /** + Called to wrap the line with the given index into sublines. + + The standard implementation wraps the line at the first non-whitespace after + an whitespace that exceeds the visible line width (nMaxLineWidth). Override + this function to provide your own word wrapping. + + Attention: Never call this function directly, + call WrapLineCached() instead, which calls this method. + + @param nLineIndex The index of the line to wrap + + @param nMaxLineWidth The number of characters a subline of this line should + not exceed (except whitespaces) + + @param anBreaks An array of integers. Put the positions where to wrap the line + in that array (its allready allocated). If this pointer is NULL, the function + has only to compute the number of breaks (the parameter nBreaks). + + @param nBreaks The number of breaks this line has (number of sublines - 1). When + the function is called, this variable is 0. If the line is not wrapped, this value + should be 0 after the call. + + @see WrapLineCached() + */ + virtual void WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ); + + /** + Called to wrap the line with the given index into sublines. + + Call this method instead of WrapLine() (which is called internal by this + method). This function uses an internal cache which contains the number + of sublines for each line, so it has only to call WrapLine(), if the + cache for the given line is invalid or if the caller wants to get the + wrap postions (anBreaks != NULL). + + This functions also tests m_bWordWrap -- you can call it even if + word wrapping is disabled and you will retrieve a valid value. + + @param nLineIndex The index of the line to wrap + + @param nMaxLineWidth The number of characters a subline of this line should + not exceed (except whitespaces) + + @param anBreaks An array of integers. Put the positions where to wrap the line + in that array (its allready allocated). If this pointer is NULL, the function + has only to compute the number of breaks (the parameter nBreaks). + + @param nBreaks The number of breaks this line has (number of sublines - 1). When + the function is called, this variable is 0. If the line is not wrapped, this value + should be 0 after the call. + + @see WrapLine() + @see m_anSubLines + */ + void WrapLineCached( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ); + + /** + Invalidates the cached data for the given lines. + + Remarks: Override this method, if your derived class caches other + view specific line info, which becomes invalid, when this line changes. + Call this standard implementation in your overriding. + + @param nLineIndex1 The index of the first line to invalidate. + + @param nLineIndex2 The index of the last line to invalidate. If this value is + -1 (default) all lines from nLineIndex1 to the end are invalidated. + */ + virtual void InvalidateLineCache( int nLineIndex1, int nLineIndex2 ); + //END SW + + // Syntax coloring overrides + struct TEXTBLOCK + { + int m_nCharPos; + int m_nColorIndex; + }; + + virtual HINSTANCE GetResourceHandle (); + + //BEGIN SW + // function to draw a single screen line + // (a wrapped line can consist of many screen lines + virtual void DrawScreenLine( CDC *pdc, CPoint &ptOrigin, const CRect &rcClip, + TEXTBLOCK *pBuf, int nBlocks, int &nActualItem, + COLORREF crText, COLORREF crBkgnd, BOOL bDrawWhitespace, + LPCTSTR pszChars, + int nOffset, int nCount, CPoint ptTextPos ); + //END SW + + + //BEGIN SW + // helpers for incremental search + + /** + Called each time the position-information in the status bar + is updated. Use this to change the text of the message field + in the status bar. + + @param pStatusBar + Pointer to the status bar + */ + void OnUpdateStatusMessage( CStatusBar *pStatusBar ); + + /** + Called by OnFindIncrementalForward() and OnFindIncrementalBackward(). + + @param bFindNextOccurence + TRUE, if the method should look for the next occurence of the + search string in search direction. + + @see #OnFindIncrementalForward + @see #OnFindIncrementalBackward + */ + void OnEditFindIncremental( BOOL bFindNextOccurence = FALSE ); + + /** TRUE if incremental forward search is active, FALSE otherwise */ + BOOL m_bIncrementalSearchForward; + + /** TRUE if incremental backward search is active, FALSE otherwise */ + BOOL m_bIncrementalSearchBackward; + +private: + /** TRUE if we found the string to search for */ + BOOL m_bIncrementalFound; + + /** String we are looking for.*/ + CString *m_pstrIncrementalSearchString; + + /** String we looked for last time.*/ + CString *m_pstrIncrementalSearchStringOld; + + /** Start of selection at the time the incremental search started */ + CPoint m_selStartBeforeIncrementalSearch; + + /** Start of selection at the time the incremental search started */ + CPoint m_selEndBeforeIncrementalSearch; + + /** Cursor position at the time the incremental search started */ + CPoint m_cursorPosBeforeIncrementalSearch; + + /** position to start the incremental search at */ + CPoint m_incrementalSearchStartPos; + + //END SW + +public : + void GoToLine (int nLine, bool bRelative); + DWORD ParseLine (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLinePlain (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineAsp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineBasic (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineBatch (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineC (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineDcl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineFortran (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineHtml (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineIS (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineJava (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineLisp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLinePascal (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLinePerl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLinePhp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLinePython (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineRexx (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineRsrc (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineSgml (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineSh (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineSiod (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineSql (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineTcl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD ParseLineTex (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + + // Attributes +public : + int GetCRLFMode (); + void SetCRLFMode (int nCRLFMode); + BOOL GetViewTabs (); + void SetViewTabs (BOOL bViewTabs); + int GetTabSize (); + void SetTabSize (int nTabSize); + BOOL GetSelectionMargin (); + void SetSelectionMargin (BOOL bSelMargin); + void GetFont (LOGFONT & lf); + void SetFont (const LOGFONT & lf); + DWORD GetFlags (); + void SetFlags (DWORD dwFlags); + BOOL GetSmoothScroll () const; + void SetSmoothScroll (BOOL bSmoothScroll); + // [JRT]: + BOOL GetDisableDragAndDrop () const; + void SetDisableDragAndDrop (BOOL bDDAD); + + //BEGIN SW + BOOL GetWordWrapping() const; + void SetWordWrapping( BOOL bWordWrap ); + + /** + Sets the Parser to use to parse the file. + + @param pParser Pointer to parser to use. Set to NULL to use no parser. + + @return Pointer to parser used before or NULL, if no parser has been used before. + */ + CCrystalParser *SetParser( CCrystalParser *pParser ); + //END SW + + // Default handle to resources + static HINSTANCE s_hResourceInst; + + int m_nLastFindWhatLen; + RxNode *m_rxnode; + RxMatchRes m_rxmatch; + LPTSTR m_pszMatched; + static LOGFONT m_LogFont; + + typedef enum + { + SRC_PLAIN, + SRC_ASP, + SRC_BASIC, + SRC_BATCH, + SRC_C, + SRC_DCL, + SRC_FORTRAN, + SRC_HTML, + SRC_INSTALLSHIELD, + SRC_JAVA, + SRC_LISP, + SRC_PASCAL, + SRC_PERL, + SRC_PHP, + SRC_PYTHON, + SRC_REXX, + SRC_RSRC, + SRC_SGML, + SRC_SH, + SRC_SIOD, + SRC_SQL, + SRC_TCL, + SRC_TEX + } + TextType; + + struct TextDefinition + { + TextType type; + TCHAR name[256]; + TCHAR exts[256]; + DWORD (CCrystalTextView:: * ParseLineX) (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems); + DWORD flags; + DWORD tabsize; + TCHAR opencomment[8]; + TCHAR closecomment[8]; + TCHAR commentline[8]; + DWORD encoding; + }; + +#define SRCOPT_INSERTTABS 1 +#define SRCOPT_SHOWTABS 2 +#define SRCOPT_BSATBOL 4 +#define SRCOPT_SELMARGIN 8 +#define SRCOPT_AUTOINDENT 16 +#define SRCOPT_BRACEANSI 32 +#define SRCOPT_BRACEGNU 64 +#define SRCOPT_EOLNDOS 128 +#define SRCOPT_EOLNUNIX 256 +#define SRCOPT_EOLNMAC 512 +#define SRCOPT_FNBRACE 1024 +#define SRCOPT_WORDWRAP 2048 + + // Source type + TextDefinition *m_CurSourceDef; + static TextDefinition m_SourceDefs[]; + bool m_bRememberLastPos; + virtual bool DoSetTextType (TextDefinition *def); + static TextDefinition *GetTextType (LPCTSTR pszExt); + virtual bool SetTextType (LPCTSTR pszExt); + virtual bool SetTextType (CCrystalTextView::TextType enuType); + virtual bool SetTextType (CCrystalTextView::TextDefinition *def); + static void LoadSettings (); + static void SaveSettings (); + + enum + { + // Base colors + COLORINDEX_WHITESPACE, + COLORINDEX_BKGND, + COLORINDEX_NORMALTEXT, + COLORINDEX_SELMARGIN, + COLORINDEX_SELBKGND, + COLORINDEX_SELTEXT, + // Syntax colors + COLORINDEX_KEYWORD, + COLORINDEX_FUNCNAME, + COLORINDEX_COMMENT, + COLORINDEX_NUMBER, + COLORINDEX_OPERATOR, // [JRT]: + COLORINDEX_STRING, + COLORINDEX_PREPROCESSOR, + COLORINDEX_USER1, + COLORINDEX_USER2, + // Compiler/debugger colors + COLORINDEX_ERRORBKGND, + COLORINDEX_ERRORTEXT, + COLORINDEX_EXECUTIONBKGND, + COLORINDEX_EXECUTIONTEXT, + COLORINDEX_BREAKPOINTBKGND, + COLORINDEX_BREAKPOINTTEXT + // ... + // Expandable: custom elements are allowed. + }; + + // Operations +public : + void AttachToBuffer (CCrystalTextBuffer * pBuf = NULL); + void DetachFromBuffer (); + + // Buffer-view interaction, multiple views + virtual CCrystalTextBuffer *LocateTextBuffer (); + virtual void UpdateView (CCrystalTextView * pSource, CUpdateContext * pContext, DWORD dwFlags, int nLineIndex = -1); + + // Attributes + CPoint GetCursorPos (); + void SetCursorPos (const CPoint & ptCursorPos); + void ShowCursor (); + void HideCursor (); + void PopCursor (); + void PushCursor (); + + // Operations + void EnsureVisible (CPoint pt); + + // Text search helpers + BOOL FindText (LPCTSTR pszText, const CPoint & ptStartPos, DWORD dwFlags, BOOL bWrapSearch, CPoint * pptFoundPos); + BOOL FindTextInBlock (LPCTSTR pszText, const CPoint & ptStartPos, const CPoint & ptBlockBegin, const CPoint & ptBlockEnd, + DWORD dwFlags, BOOL bWrapSearch, CPoint * pptFoundPos); + BOOL HighlightText (const CPoint & ptStartPos, int nLength, BOOL bReverse = FALSE); + + // Overridable: an opportunity for Auto-Indent, Smart-Indent etc. + virtual void OnEditOperation (int nAction, LPCTSTR pszText); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCrystalTextView) +public : + virtual void OnDraw (CDC * pDC); // overridden to draw this view + + virtual BOOL PreCreateWindow (CREATESTRUCT & cs); + virtual BOOL PreTranslateMessage (MSG * pMsg); + virtual void OnPrepareDC (CDC * pDC, CPrintInfo * pInfo = NULL); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO *pHandlerInfo); +protected : + virtual void OnInitialUpdate (); // called first time after construct + + virtual BOOL OnPreparePrinting (CPrintInfo * pInfo); + virtual void OnBeginPrinting (CDC * pDC, CPrintInfo * pInfo); + virtual void OnEndPrinting (CDC * pDC, CPrintInfo * pInfo); + virtual void OnPrint (CDC * pDC, CPrintInfo * pInfo); + //}}AFX_VIRTUAL + + // Implementation +public : + CCrystalTextView (); + ~CCrystalTextView (); + +protected : + + // Generated message map functions +protected : +#ifdef _DEBUG + void AssertValidTextPos (const CPoint & pt); +#endif + + //{{AFX_MSG(CCrystalTextView) + afx_msg void OnDestroy (); + afx_msg BOOL OnEraseBkgnd (CDC * pDC); + afx_msg void OnSize (UINT nType, int cx, int cy); + afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar); + afx_msg BOOL OnSetCursor (CWnd * pWnd, UINT nHitTest, UINT message); + afx_msg void OnLButtonDown (UINT nFlags, CPoint point); + afx_msg void OnSetFocus (CWnd * pOldWnd); + afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar); + afx_msg void OnLButtonUp (UINT nFlags, CPoint point); + afx_msg void OnMouseMove (UINT nFlags, CPoint point); + afx_msg void OnTimer (UINT nIDEvent); + afx_msg void OnKillFocus (CWnd * pNewWnd); + afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point); + afx_msg void OnEditCopy (); + afx_msg void OnUpdateEditCopy (CCmdUI * pCmdUI); + afx_msg void OnEditSelectAll (); + afx_msg void OnUpdateEditSelectAll (CCmdUI * pCmdUI); + afx_msg void OnRButtonDown (UINT nFlags, CPoint point); + afx_msg void OnSysColorChange (); + afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); + afx_msg void OnEditFind (); + afx_msg void OnEditRepeat (); + afx_msg void OnUpdateEditRepeat (CCmdUI * pCmdUI); + afx_msg void OnEditFindPrevious (); // More search + afx_msg void OnEditDeleteBack(); + afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); + + afx_msg void OnUpdateEditFindPrevious (CCmdUI * pCmdUI); + afx_msg BOOL OnMouseWheel (UINT nFlags, short zDelta, CPoint pt); + //}}AFX_MSG + afx_msg void OnFilePageSetup (); + + afx_msg void OnCharLeft (); + afx_msg void OnExtCharLeft (); + afx_msg void OnCharRight (); + afx_msg void OnExtCharRight (); + afx_msg void OnWordLeft (); + afx_msg void OnExtWordLeft (); + afx_msg void OnWordRight (); + afx_msg void OnExtWordRight (); + afx_msg void OnLineUp (); + afx_msg void OnExtLineUp (); + afx_msg void OnLineDown (); + afx_msg void OnExtLineDown (); + afx_msg void OnPageUp (); + afx_msg void OnExtPageUp (); + afx_msg void OnPageDown (); + afx_msg void OnExtPageDown (); + afx_msg void OnLineEnd (); + afx_msg void OnExtLineEnd (); + afx_msg void OnHome (); + afx_msg void OnExtHome (); + afx_msg void OnTextBegin (); + afx_msg void OnExtTextBegin (); + afx_msg void OnTextEnd (); + afx_msg void OnExtTextEnd (); + afx_msg void OnUpdateIndicatorCRLF (CCmdUI * pCmdUI); + afx_msg void OnUpdateIndicatorPosition (CCmdUI * pCmdUI); + afx_msg void OnToggleBookmark (UINT nCmdID); + afx_msg void OnGoBookmark (UINT nCmdID); + afx_msg void OnClearBookmarks (); + + afx_msg void OnToggleBookmark (); // More bookmarks + + afx_msg void OnClearAllBookmarks (); + afx_msg void OnNextBookmark (); + afx_msg void OnPrevBookmark (); + afx_msg void OnUpdateClearAllBookmarks (CCmdUI * pCmdUI); + afx_msg void OnUpdateNextBookmark (CCmdUI * pCmdUI); + afx_msg void OnUpdatePrevBookmark (CCmdUI * pCmdUI); + + afx_msg void ScrollUp (); + afx_msg void ScrollDown (); + afx_msg void ScrollLeft (); + afx_msg void ScrollRight (); + + afx_msg void OnSourceType (UINT nId); + afx_msg void OnUpdateSourceType (CCmdUI * pCmdUI); + afx_msg void OnMatchBrace (); + afx_msg void OnUpdateMatchBrace (CCmdUI * pCmdUI); + afx_msg void OnEditGoTo (); + afx_msg void OnUpdateToggleSourceHeader (CCmdUI * pCmdUI); + afx_msg void OnToggleSourceHeader (); + afx_msg void OnUpdateSelMargin (CCmdUI * pCmdUI); + afx_msg void OnSelMargin (); + afx_msg void OnUpdateWordWrap (CCmdUI * pCmdUI); + afx_msg void OnWordWrap (); + afx_msg void OnForceRedraw (); + + //BEGIN SW + // incremental search + afx_msg void OnEditFindIncrementalForward(); + afx_msg void OnEditFindIncrementalBackward(); + afx_msg void OnUpdateEditFindIncrementalForward(CCmdUI* pCmdUI); + afx_msg void OnUpdateEditFindIncrementalBackward(CCmdUI* pCmdUI); + //END SW + + DECLARE_MESSAGE_MAP () + }; + +#ifdef _DEBUG +#define ASSERT_VALIDTEXTPOS(pt) AssertValidTextPos(pt); +#else +#define ASSERT_VALIDTEXTPOS(pt) +#endif + +#if ! (defined(CE_FROM_DLL) || defined(CE_DLL_BUILD)) +#include "ccrystaltextview.inl" +#endif + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CCRYSTALTEXTVIEW_H__AD7F2F41_6CB3_11D2_8C32_0080ADB86836__INCLUDED_) diff --git a/Src/editlib/ccrystaltextview.inl b/Src/editlib/ccrystaltextview.inl new file mode 100644 index 000000000..04d3f6b3d --- /dev/null +++ b/Src/editlib/ccrystaltextview.inl @@ -0,0 +1,38 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CCrystalTextView.inl +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Inline functions of Crystal Edit classes +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#ifndef __CCrystalTextView_INL_INCLUDED +#define __CCrystalTextView_INL_INCLUDED + +#include "CCrystalTextView.h" + +inline BOOL CCrystalTextView:: +IsDraggingText () +const +{ + return m_bDraggingText; +} + +#endif diff --git a/Src/editlib/ccrystaltextview2.cpp b/Src/editlib/ccrystaltextview2.cpp new file mode 100644 index 000000000..b2b1f3048 --- /dev/null +++ b/Src/editlib/ccrystaltextview2.cpp @@ -0,0 +1,1215 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ccrystaltextview2.cpp +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalTextView class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 21-Feb-99 +// Paul Selormey, James R. Twine: +// + FEATURE: description for Undo/Redo actions +// + FEATURE: multiple MSVC-like bookmarks +// + FEATURE: 'Disable backspace at beginning of line' option +// + FEATURE: 'Disable drag-n-drop editing' option +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: regular expressions, go to line and things ... +// + FEATURE: plenty of syntax highlighting definitions +// + FEATURE: corrected bug in syntax highlighting C comments +// + FEATURE: extended registry support for saving settings +// + FEATURE: some other things I've forgotten ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "editcmd.h" +#include "ccrystaltextview.h" +#include "ccrystaltextbuffer.h" +#include + +#ifndef __AFXPRIV_H__ +#pragma message("Include in your stdafx.h to avoid this message") +#include +#endif + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define CRYSTAL_TIMER_DRAGSEL 1001 + + +///////////////////////////////////////////////////////////////////////////// +// CCrystalTextView + +void CCrystalTextView:: +MoveLeft (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + { + m_ptCursorPos = m_ptDrawSelStart; + } + else + { + if (m_ptCursorPos.x == 0) + { + if (m_ptCursorPos.y > 0) + { + m_ptCursorPos.y--; + m_ptCursorPos.x = GetLineLength (m_ptCursorPos.y); + } + } + else + { + m_ptCursorPos.x--; + if (m_pTextBuffer->IsMBSTrail (m_ptCursorPos.y, m_ptCursorPos.x) && + // here... if its a MBSTrail, then should move one character more.... + m_ptCursorPos.x > 0) + m_ptCursorPos.x--; + } + } + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveRight (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + { + m_ptCursorPos = m_ptDrawSelEnd; + } + else + { + if (m_ptCursorPos.x == GetLineLength (m_ptCursorPos.y)) + { + if (m_ptCursorPos.y < GetLineCount () - 1) + { + m_ptCursorPos.y++; + m_ptCursorPos.x = 0; + } + } + else + { + m_ptCursorPos.x++; + if (m_pTextBuffer->IsMBSTrail (m_ptCursorPos.y, m_ptCursorPos.x) && + // here... if its a MBSTrail, then should move one character more.... + m_ptCursorPos.x < GetLineLength (m_ptCursorPos.y)) + m_ptCursorPos.x++; + } + } + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveWordLeft (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + { + MoveLeft (bSelect); + return; + } + + if (m_ptCursorPos.x == 0) + { + if (m_ptCursorPos.y == 0) + return; + m_ptCursorPos.y--; + m_ptCursorPos.x = GetLineLength (m_ptCursorPos.y); + } + + LPCTSTR pszChars = GetLineChars (m_ptCursorPos.y); + int nPos = m_ptCursorPos.x; + while (nPos > 0 && isspace (pszChars[nPos - 1])) + nPos--; + + if (nPos > 0) + { + nPos--; + if (xisalnum (pszChars[nPos])) + { + while (nPos > 0 && xisalnum (pszChars[nPos - 1])) + nPos--; + } + else + { + while (nPos > 0 && !xisalnum (pszChars[nPos - 1]) + && !isspace (pszChars[nPos - 1])) + nPos--; + } + } + + m_ptCursorPos.x = nPos; + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveWordRight (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + { + MoveRight (bSelect); + return; + } + + if (m_ptCursorPos.x == GetLineLength (m_ptCursorPos.y)) + { + if (m_ptCursorPos.y == GetLineCount () - 1) + return; + m_ptCursorPos.y++; + m_ptCursorPos.x = 0; + } + + int nLength = GetLineLength (m_ptCursorPos.y); + if (m_ptCursorPos.x == nLength) + { + MoveRight (bSelect); + return; + } + + LPCTSTR pszChars = GetLineChars (m_ptCursorPos.y); + int nPos = m_ptCursorPos.x; + if (xisalnum (pszChars[nPos])) + { + while (nPos < nLength && xisalnum (pszChars[nPos])) + nPos++; + } + else + { + while (nPos < nLength && !xisalnum (pszChars[nPos]) + && !isspace (pszChars[nPos])) + nPos++; + } + + while (nPos < nLength && isspace (pszChars[nPos])) + nPos++; + + m_ptCursorPos.x = nPos; + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveUp (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + m_ptCursorPos = m_ptDrawSelStart; + + //BEGIN SW + CPoint subLinePos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, subLinePos ); + + int nSubLine = GetSubLineIndex( m_ptCursorPos.y ) + subLinePos.y; + + if( nSubLine > 0 ) + /*ORIGINAL + if (m_ptCursorPos.y > 0) + *///END SW + { + if (m_nIdealCharPos == -1) + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + //BEGIN SW + SubLineCursorPosToTextPos( CPoint( m_nIdealCharPos, nSubLine - 1 ), m_ptCursorPos ); + /*ORIGINAL + m_ptCursorPos.y --; + m_ptCursorPos.x = ApproxActualOffset(m_ptCursorPos.y, m_nIdealCharPos); + *///END SW + if (m_ptCursorPos.x > GetLineLength (m_ptCursorPos.y)) + m_ptCursorPos.x = GetLineLength (m_ptCursorPos.y); + } + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveDown (BOOL bSelect) +{ + PrepareSelBounds (); + if (m_ptDrawSelStart != m_ptDrawSelEnd && !bSelect) + m_ptCursorPos = m_ptDrawSelEnd; + + //BEGIN SW + CPoint subLinePos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, subLinePos ); + + int nSubLine = GetSubLineIndex( m_ptCursorPos.y ) + subLinePos.y; + + if( nSubLine < GetSubLineCount() - 1 ) + /*ORIGINAL + if (m_ptCursorPos.y < GetLineCount() - 1) + */ + { + if (m_nIdealCharPos == -1) + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + //BEGIN SW + SubLineCursorPosToTextPos( CPoint( m_nIdealCharPos, nSubLine + 1 ), m_ptCursorPos ); + /*ORIGINAL + m_ptCursorPos.y ++; + m_ptCursorPos.x = ApproxActualOffset(m_ptCursorPos.y, m_nIdealCharPos); + *///END SW + if (m_ptCursorPos.x > GetLineLength (m_ptCursorPos.y)) + m_ptCursorPos.x = GetLineLength (m_ptCursorPos.y); + } + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveHome (BOOL bSelect) +{ + int nLength = GetLineLength (m_ptCursorPos.y); + LPCTSTR pszChars = GetLineChars (m_ptCursorPos.y); + //BEGIN SW + CPoint pos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, pos ); + int nHomePos = SubLineHomeToCharPos( m_ptCursorPos.y, pos.y ); + int nOriginalHomePos = nHomePos; + /*ORIGINAL + int nHomePos = 0; + *///END SW + while (nHomePos < nLength && isspace (pszChars[nHomePos])) + nHomePos++; + if (nHomePos == nLength || m_ptCursorPos.x == nHomePos) + //BEGIN SW + m_ptCursorPos.x = nOriginalHomePos; + /*ORIGINAL + m_ptCursorPos.x = 0; + *///END SW + else + m_ptCursorPos.x = nHomePos; + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveEnd (BOOL bSelect) +{ + //BEGIN SW + CPoint pos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, pos ); + m_ptCursorPos.x = SubLineEndToCharPos( m_ptCursorPos.y, pos.y ); + /*ORIGINAL + m_ptCursorPos.x = GetLineLength(m_ptCursorPos.y); + *///END SW + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MovePgUp (BOOL bSelect) +{ + //BEGIN SW + // scrolling windows + int nNewTopSubLine = m_nTopSubLine - GetScreenLines() + 1; + if (nNewTopSubLine < 0) + nNewTopSubLine = 0; + if (m_nTopSubLine != nNewTopSubLine) + { + ScrollToSubLine(nNewTopSubLine); + UpdateSiblingScrollPos(TRUE); + } + + // setting cursor + CPoint subLinePos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, subLinePos ); + + int nSubLine = GetSubLineIndex( m_ptCursorPos.y ) + subLinePos.y - GetScreenLines() + 1; + + if( nSubLine < 0 ) + nSubLine = 0; + + SubLineCursorPosToTextPos( + CPoint( m_nIdealCharPos, nSubLine ), m_ptCursorPos ); + + /*ORIGINAL + int nNewTopLine = m_nTopLine - GetScreenLines() + 1; + if (nNewTopLine < 0) + nNewTopLine = 0; + if (m_nTopLine != nNewTopLine) + { + ScrollToLine(nNewTopLine); + UpdateSiblingScrollPos(TRUE); + } + + m_ptCursorPos.y -= GetScreenLines() - 1; + if (m_ptCursorPos.y < 0) + m_ptCursorPos.y = 0; + if (m_ptCursorPos.x > GetLineLength(m_ptCursorPos.y)) + m_ptCursorPos.x = GetLineLength(m_ptCursorPos.y); + *///END SW + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); //todo: no vertical scroll + + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MovePgDn (BOOL bSelect) +{ + //BEGIN SW + // scrolling windows + int nNewTopSubLine = m_nTopSubLine + GetScreenLines() - 1; + int nSubLineCount = GetSubLineCount(); + + if (nNewTopSubLine > nSubLineCount) + nNewTopSubLine = nSubLineCount - 1; + if (m_nTopSubLine != nNewTopSubLine) + { + ScrollToSubLine(nNewTopSubLine); + UpdateSiblingScrollPos(TRUE); + } + + // setting cursor + CPoint subLinePos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, subLinePos ); + + int nSubLine = GetSubLineIndex( m_ptCursorPos.y ) + subLinePos.y + GetScreenLines() - 1; + + if( nSubLine > nSubLineCount - 1 ) + nSubLine = nSubLineCount - 1; + + SubLineCursorPosToTextPos( + CPoint( m_nIdealCharPos, nSubLine ), m_ptCursorPos ); + + /*ORIGINAL + int nNewTopLine = m_nTopLine + GetScreenLines() - 1; + if (nNewTopLine >= GetLineCount()) + nNewTopLine = GetLineCount() - 1; + if (m_nTopLine != nNewTopLine) + { + ScrollToLine(nNewTopLine); + UpdateSiblingScrollPos(TRUE); + } + + m_ptCursorPos.y += GetScreenLines() - 1; + if (m_ptCursorPos.y >= GetLineCount()) + m_ptCursorPos.y = GetLineCount() - 1; + if (m_ptCursorPos.x > GetLineLength(m_ptCursorPos.y)) + m_ptCursorPos.x = GetLineLength(m_ptCursorPos.y); + *///END SW + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); //todo: no vertical scroll + + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveCtrlHome (BOOL bSelect) +{ + m_ptCursorPos.x = 0; + m_ptCursorPos.y = 0; + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +MoveCtrlEnd (BOOL bSelect) +{ + m_ptCursorPos.y = GetLineCount () - 1; + m_ptCursorPos.x = GetLineLength (m_ptCursorPos.y); + m_nIdealCharPos = CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + if (!bSelect) + m_ptAnchor = m_ptCursorPos; + SetSelection (m_ptAnchor, m_ptCursorPos); +} + +void CCrystalTextView:: +ScrollUp () +{ + if (m_nTopLine > 0) + { + ScrollToLine (m_nTopLine - 1); + UpdateSiblingScrollPos (FALSE); + } +} + +void CCrystalTextView:: +ScrollDown () +{ + if (m_nTopLine < GetLineCount () - 1) + { + ScrollToLine (m_nTopLine + 1); + UpdateSiblingScrollPos (FALSE); + } +} + +void CCrystalTextView:: +ScrollLeft () +{ + if (m_nOffsetChar > 0) + { + ScrollToChar (m_nOffsetChar - 1); + UpdateCaret (); + UpdateSiblingScrollPos (TRUE); + } +} + +void CCrystalTextView:: +ScrollRight () +{ + if (m_nOffsetChar < GetMaxLineLength () - 1) + { + ScrollToChar (m_nOffsetChar + 1); + UpdateCaret (); + UpdateSiblingScrollPos (TRUE); + } +} + +CPoint CCrystalTextView:: +WordToRight (CPoint pt) +{ + ASSERT_VALIDTEXTPOS (pt); + int nLength = GetLineLength (pt.y); + LPCTSTR pszChars = GetLineChars (pt.y); + while (pt.x < nLength) + { + if (!xisalnum (pszChars[pt.x])) + break; + pt.x++; + } + ASSERT_VALIDTEXTPOS (pt); + return pt; +} + +CPoint CCrystalTextView:: +WordToLeft (CPoint pt) +{ + ASSERT_VALIDTEXTPOS (pt); + LPCTSTR pszChars = GetLineChars (pt.y); + while (pt.x > 0) + { + if (!xisalnum (pszChars[pt.x - 1])) + break; + pt.x--; + } + ASSERT_VALIDTEXTPOS (pt); + return pt; +} + +void CCrystalTextView:: +SelectAll () +{ + int nLineCount = GetLineCount (); + m_ptCursorPos.x = GetLineLength (nLineCount - 1); + m_ptCursorPos.y = nLineCount - 1; + SetSelection (CPoint (0, 0), m_ptCursorPos); + UpdateCaret (); +} + +void CCrystalTextView:: +OnLButtonDown (UINT nFlags, CPoint point) +{ + CView::OnLButtonDown (nFlags, point); + + BOOL bShift = GetKeyState (VK_SHIFT) & 0x8000; + BOOL bControl = GetKeyState (VK_CONTROL) & 0x8000; + + if (point.x < GetMarginWidth ()) + { + AdjustTextPoint (point); + if (bControl) + { + SelectAll (); + } + else + { + m_ptCursorPos = ClientToText (point); + //BEGIN SW + // Find char pos that is the beginning of the subline clicked on + CPoint pos; + CharPosToPoint( m_ptCursorPos.y, m_ptCursorPos.x, pos ); + m_ptCursorPos.x = SubLineHomeToCharPos( m_ptCursorPos.y, pos.y ); + /*ORIGINAL + m_ptCursorPos.x = 0; // Force beginning of the line + *///END SW + + if (!bShift) + m_ptAnchor = m_ptCursorPos; + + CPoint ptStart, ptEnd; + //BEGIN SW + CharPosToPoint( m_ptAnchor.y, m_ptAnchor.x, pos ); + ptStart.y = m_ptAnchor.y; + if( GetSubLineIndex( ptStart.y ) + pos.y == GetSubLineCount() - 1 ) + { + // select to end of subline + ptStart = SubLineEndToCharPos( ptStart.y, pos.y ); + } + else + { + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( ptStart.y ) + pos.y + 1, nLine, nSubLine ); + ptStart.y = nLine; + ptStart.x = SubLineHomeToCharPos( nLine, nSubLine ); + } + /*ORIGINAL + ptStart = m_ptAnchor; + if (ptStart.y == GetLineCount() - 1) + ptStart.x = GetLineLength(ptStart.y); + else + { + ptStart.y ++; + ptStart.x = 0; + } + *///END SW + + //BEGIN SW + ptEnd = m_ptCursorPos; + /*ORIGINAL + ptEnd = m_ptCursorPos; + ptEnd.x = 0; + *///END SW + + m_ptCursorPos = ptEnd; + UpdateCaret (); + EnsureVisible (m_ptCursorPos); + SetSelection (ptStart, ptEnd); + + SetCapture (); + m_nDragSelTimer = SetTimer (CRYSTAL_TIMER_DRAGSEL, 100, NULL); + ASSERT (m_nDragSelTimer != 0); + m_bWordSelection = FALSE; + m_bLineSelection = TRUE; + m_bDragSelection = TRUE; + } + } + else + { + CPoint ptText = ClientToText (point); + PrepareSelBounds (); + // [JRT]: Support For Disabling Drag and Drop... + if ((IsInsideSelBlock (ptText)) && // If Inside Selection Area + (!m_bDisableDragAndDrop)) // And D&D Not Disabled + + { + m_bPreparingToDrag = TRUE; + } + else + { + AdjustTextPoint (point); + m_ptCursorPos = ClientToText (point); + if (!bShift) + m_ptAnchor = m_ptCursorPos; + + CPoint ptStart, ptEnd; + if (bControl) + { + if (m_ptCursorPos.y < m_ptAnchor.y || + m_ptCursorPos.y == m_ptAnchor.y && m_ptCursorPos.x < m_ptAnchor.x) + { + ptStart = WordToLeft (m_ptCursorPos); + ptEnd = WordToRight (m_ptAnchor); + } + else + { + ptStart = WordToLeft (m_ptAnchor); + ptEnd = WordToRight (m_ptCursorPos); + } + } + else + { + ptStart = m_ptAnchor; + ptEnd = m_ptCursorPos; + } + + m_ptCursorPos = ptEnd; + UpdateCaret (); + EnsureVisible (m_ptCursorPos); + SetSelection (ptStart, ptEnd); + + SetCapture (); + m_nDragSelTimer = SetTimer (CRYSTAL_TIMER_DRAGSEL, 100, NULL); + ASSERT (m_nDragSelTimer != 0); + m_bWordSelection = bControl; + m_bLineSelection = FALSE; + m_bDragSelection = TRUE; + } + } + + ASSERT_VALIDTEXTPOS (m_ptCursorPos); + //BEGIN SW + // we must set the ideal character position here! + m_nIdealCharPos = CalculateActualOffset( m_ptCursorPos.y, m_ptCursorPos.x ); + //END SW +} + +void CCrystalTextView:: +OnMouseMove (UINT nFlags, CPoint point) +{ + CView::OnMouseMove (nFlags, point); + + if (m_bDragSelection) + { + BOOL bOnMargin = point.x < GetMarginWidth (); + + AdjustTextPoint (point); + CPoint ptNewCursorPos = ClientToText (point); + + CPoint ptStart, ptEnd; + if (m_bLineSelection) + { + if (bOnMargin) + { + if (ptNewCursorPos.y < m_ptAnchor.y || + ptNewCursorPos.y == m_ptAnchor.y && ptNewCursorPos.x < m_ptAnchor.x) + { + //BEGIN SW + CPoint pos; + ptEnd = m_ptAnchor; + CharPosToPoint( ptEnd.y, ptEnd.x, pos ); + if( GetSubLineIndex( ptEnd.y ) + pos.y == GetSubLineCount() - 1 ) + ptEnd = SubLineEndToCharPos( ptEnd.y, pos.y ); + else + { + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( ptEnd.y ) + pos.y + 1, nLine, nSubLine ); + ptEnd.y = nLine; + ptEnd.x = SubLineHomeToCharPos( nLine, nSubLine ); + } + CharPosToPoint( ptNewCursorPos.y, ptNewCursorPos.x, pos ); + ptNewCursorPos.x = SubLineHomeToCharPos( ptNewCursorPos.y, pos.y ); + /*ORIGINAL + ptEnd = m_ptAnchor; + if (ptEnd.y == GetLineCount() - 1) + { + ptEnd.x = GetLineLength(ptEnd.y); + } + else + { + ptEnd.y ++; + ptEnd.x = 0; + } + ptNewCursorPos.x = 0; + *///END SW + m_ptCursorPos = ptNewCursorPos; + } + else + { + ptEnd = m_ptAnchor; + //BEGIN SW + + CPoint pos; + CharPosToPoint( ptEnd.y, ptEnd.x, pos ); + ptEnd.x = SubLineHomeToCharPos( ptEnd.y, pos.y ); + + m_ptCursorPos = ptNewCursorPos; + CharPosToPoint( ptNewCursorPos.y, ptNewCursorPos.x, pos ); + if( GetSubLineIndex( ptNewCursorPos.y ) + pos.y == GetSubLineCount() - 1 ) + ptNewCursorPos.x = SubLineEndToCharPos( ptNewCursorPos.y, pos.y ); + else + { + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( ptNewCursorPos.y ) + pos.y + 1, nLine, nSubLine ); + ptNewCursorPos.y = nLine; + ptNewCursorPos.x = SubLineHomeToCharPos( nLine, nSubLine ); + } + + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( m_ptCursorPos.y ) + pos.y, nLine, nSubLine ); + m_ptCursorPos.y = nLine; + m_ptCursorPos.x = SubLineHomeToCharPos( nLine, nSubLine ); + /*ORIGINAL + ptEnd.x = 0; + m_ptCursorPos = ptNewCursorPos; + if (ptNewCursorPos.y == GetLineCount() - 1) + { + ptNewCursorPos.x = GetLineLength(ptNewCursorPos.y); + } + else + { + ptNewCursorPos.y ++; + ptNewCursorPos.x = 0; + } + m_ptCursorPos.x = 0; + *///END SW + } + UpdateCaret (); + SetSelection (ptNewCursorPos, ptEnd); + return; + } + + // Moving to normal selection mode + ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE (IDC_IBEAM))); + m_bLineSelection = m_bWordSelection = FALSE; + } + + if (m_bWordSelection) + { + if (ptNewCursorPos.y < m_ptAnchor.y || + ptNewCursorPos.y == m_ptAnchor.y && ptNewCursorPos.x < m_ptAnchor.x) + { + ptStart = WordToLeft (ptNewCursorPos); + ptEnd = WordToRight (m_ptAnchor); + } + else + { + ptStart = WordToLeft (m_ptAnchor); + ptEnd = WordToRight (ptNewCursorPos); + } + } + else + { + ptStart = m_ptAnchor; + ptEnd = ptNewCursorPos; + } + + m_ptCursorPos = ptEnd; + UpdateCaret (); + SetSelection (ptStart, ptEnd); + } + + if (m_bPreparingToDrag) + { + m_bPreparingToDrag = FALSE; + HGLOBAL hData = PrepareDragData (); + if (hData != NULL) + { + if (m_pTextBuffer != NULL) + m_pTextBuffer->BeginUndoGroup (); + + COleDataSource ds; + ds.CacheGlobalData (CF_TEXT, hData); + m_bDraggingText = TRUE; + DROPEFFECT de = ds.DoDragDrop (GetDropEffect ()); + if (de != DROPEFFECT_NONE) + OnDropSource (de); + m_bDraggingText = FALSE; + + if (m_pTextBuffer != NULL) + m_pTextBuffer->FlushUndoGroup (this); + } + } + + ASSERT_VALIDTEXTPOS (m_ptCursorPos); +} + +void CCrystalTextView:: +OnLButtonUp (UINT nFlags, CPoint point) +{ + CView::OnLButtonUp (nFlags, point); + + if (m_bDragSelection) + { + AdjustTextPoint (point); + CPoint ptNewCursorPos = ClientToText (point); + + CPoint ptStart, ptEnd; + if (m_bLineSelection) + { + CPoint ptEnd; + if (ptNewCursorPos.y < m_ptAnchor.y || + ptNewCursorPos.y == m_ptAnchor.y && ptNewCursorPos.x < m_ptAnchor.x) + { + //BEGIN SW + CPoint pos; + ptEnd = m_ptAnchor; + CharPosToPoint( ptEnd.y, ptEnd.x, pos ); + if( GetSubLineIndex( ptEnd.y ) + pos.y == GetSubLineCount() - 1 ) + ptEnd = SubLineEndToCharPos( ptEnd.y, pos.y ); + else + { + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( ptEnd.y ) + pos.y + 1, nLine, nSubLine ); + ptEnd.y = nLine; + ptEnd.x = SubLineHomeToCharPos( nLine, nSubLine ); + } + CharPosToPoint( ptNewCursorPos.y, ptNewCursorPos.x, pos ); + ptNewCursorPos.x = SubLineHomeToCharPos( ptNewCursorPos.y, pos.y ); + /*ORIGINAL + ptEnd = m_ptAnchor; + if (ptEnd.y == GetLineCount() - 1) + { + ptEnd.x = GetLineLength(ptEnd.y); + } + else + { + ptEnd.y ++; + ptEnd.x = 0; + } + ptNewCursorPos.x = 0; + *///END SW + m_ptCursorPos = ptNewCursorPos; + } + else + { + ptEnd = m_ptAnchor; + //BEGIN SW + + CPoint pos; + CharPosToPoint( ptEnd.y, ptEnd.x, pos ); + ptEnd.x = SubLineHomeToCharPos( ptEnd.y, pos.y ); + + m_ptCursorPos = ptNewCursorPos; + CharPosToPoint( ptNewCursorPos.y, ptNewCursorPos.x, pos ); + if( GetSubLineIndex( ptNewCursorPos.y ) + pos.y == GetSubLineCount() - 1 ) + ptNewCursorPos.x = SubLineEndToCharPos( ptNewCursorPos.y, pos.y ); + else + { + int nLine, nSubLine; + GetLineBySubLine( GetSubLineIndex( ptNewCursorPos.y ) + pos.y + 1, nLine, nSubLine ); + ptNewCursorPos.y = nLine; + ptNewCursorPos.x = SubLineHomeToCharPos( nLine, nSubLine ); + } + m_ptCursorPos = ptNewCursorPos; + /*ORIGINAL + ptEnd.x = 0; + m_ptCursorPos = ptNewCursorPos; + if (ptNewCursorPos.y == GetLineCount() - 1) + { + ptNewCursorPos.x = GetLineLength(ptNewCursorPos.y); + } + else + { + ptNewCursorPos.y ++; + ptNewCursorPos.x = 0; + } + m_ptCursorPos = ptNewCursorPos; + *///END SW + } + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + SetSelection (ptNewCursorPos, ptEnd); + } + else + { + if (m_bWordSelection) + { + if (ptNewCursorPos.y < m_ptAnchor.y || + ptNewCursorPos.y == m_ptAnchor.y && ptNewCursorPos.x < m_ptAnchor.x) + { + ptStart = WordToLeft (ptNewCursorPos); + ptEnd = WordToRight (m_ptAnchor); + } + else + { + ptStart = WordToLeft (m_ptAnchor); + ptEnd = WordToRight (ptNewCursorPos); + } + } + else + { + ptStart = m_ptAnchor; + ptEnd = m_ptCursorPos; + } + + m_ptCursorPos = ptEnd; + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + SetSelection (ptStart, ptEnd); + } + + ReleaseCapture (); + KillTimer (m_nDragSelTimer); + m_bDragSelection = FALSE; + } + + if (m_bPreparingToDrag) + { + m_bPreparingToDrag = FALSE; + + AdjustTextPoint (point); + m_ptCursorPos = ClientToText (point); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + SetSelection (m_ptCursorPos, m_ptCursorPos); + } + + ASSERT_VALIDTEXTPOS (m_ptCursorPos); +} + +void CCrystalTextView:: +OnTimer (UINT nIDEvent) +{ + CView::OnTimer (nIDEvent); + + if (nIDEvent == CRYSTAL_TIMER_DRAGSEL) + { + ASSERT (m_bDragSelection); + CPoint pt; + ::GetCursorPos (&pt); + ScreenToClient (&pt); + CRect rcClient; + GetClientRect (&rcClient); + + BOOL bChanged = FALSE; + + // Scroll vertically, if necessary + int nNewTopLine = m_nTopLine; + int nLineCount = GetLineCount (); + if (pt.y < rcClient.top) + { + nNewTopLine--; + if (pt.y < rcClient.top - GetLineHeight ()) + nNewTopLine -= 2; + } + else if (pt.y >= rcClient.bottom) + { + nNewTopLine++; + if (pt.y >= rcClient.bottom + GetLineHeight ()) + nNewTopLine += 2; + } + + if (nNewTopLine < 0) + nNewTopLine = 0; + if (nNewTopLine >= nLineCount) + nNewTopLine = nLineCount - 1; + + if (m_nTopLine != nNewTopLine) + { + ScrollToLine (nNewTopLine); + UpdateSiblingScrollPos (FALSE); + bChanged = TRUE; + } + + // Scroll horizontally, if necessary + int nNewOffsetChar = m_nOffsetChar; + int nMaxLineLength = GetMaxLineLength (); + if (pt.x < rcClient.left) + nNewOffsetChar--; + else if (pt.x >= rcClient.right) + nNewOffsetChar++; + + if (nNewOffsetChar >= nMaxLineLength) + nNewOffsetChar = nMaxLineLength - 1; + if (nNewOffsetChar < 0) + nNewOffsetChar = 0; + + if (m_nOffsetChar != nNewOffsetChar) + { + ScrollToChar (nNewOffsetChar); + UpdateCaret (); + UpdateSiblingScrollPos (TRUE); + bChanged = TRUE; + } + + // Fix changes + if (bChanged) + { + AdjustTextPoint (pt); + CPoint ptNewCursorPos = ClientToText (pt); + if (ptNewCursorPos != m_ptCursorPos) + { + m_ptCursorPos = ptNewCursorPos; + UpdateCaret (); + } + SetSelection (m_ptAnchor, m_ptCursorPos); + } + } +} + +void CCrystalTextView:: +OnLButtonDblClk (UINT nFlags, CPoint point) +{ + CView::OnLButtonDblClk (nFlags, point); + + if (!m_bDragSelection) + { + AdjustTextPoint (point); + + m_ptCursorPos = ClientToText (point); + m_ptAnchor = m_ptCursorPos; + + CPoint ptStart, ptEnd; + if (m_ptCursorPos.y < m_ptAnchor.y || + m_ptCursorPos.y == m_ptAnchor.y && m_ptCursorPos.x < m_ptAnchor.x) + { + ptStart = WordToLeft (m_ptCursorPos); + ptEnd = WordToRight (m_ptAnchor); + } + else + { + ptStart = WordToLeft (m_ptAnchor); + ptEnd = WordToRight (m_ptCursorPos); + } + + m_ptCursorPos = ptEnd; + UpdateCaret (); + EnsureVisible (m_ptCursorPos); + SetSelection (ptStart, ptEnd); + + SetCapture (); + m_nDragSelTimer = SetTimer (CRYSTAL_TIMER_DRAGSEL, 100, NULL); + ASSERT (m_nDragSelTimer != 0); + m_bWordSelection = TRUE; + m_bLineSelection = FALSE; + m_bDragSelection = TRUE; + } +} + +void CCrystalTextView:: +OnEditCopy () +{ + Copy (); +} + +void CCrystalTextView:: +OnUpdateEditCopy (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (m_ptSelStart != m_ptSelEnd); +} + +void CCrystalTextView:: +OnEditSelectAll () +{ + SelectAll (); +} + +void CCrystalTextView:: +OnUpdateEditSelectAll (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (TRUE); +} + +void CCrystalTextView:: +OnRButtonDown (UINT nFlags, CPoint point) +{ + CPoint pt = point; + AdjustTextPoint (pt); + pt = ClientToText (pt); + if (!IsInsideSelBlock (pt)) + { + m_ptAnchor = m_ptCursorPos = pt; + SetSelection (m_ptCursorPos, m_ptCursorPos); + EnsureVisible (m_ptCursorPos); + UpdateCaret (); + } + + CView::OnRButtonDown (nFlags, point); +} + +BOOL CCrystalTextView:: +IsSelection () +{ + return m_ptSelStart != m_ptSelEnd; +} + +void CCrystalTextView:: +Copy () +{ + if (m_ptSelStart == m_ptSelEnd) + return; + + PrepareSelBounds (); + CString text; + GetText (m_ptDrawSelStart, m_ptDrawSelEnd, text); + PutToClipboard (text); +} + +BOOL CCrystalTextView:: +TextInClipboard () +{ + return IsClipboardFormatAvailable (CF_TEXT); +} + +BOOL CCrystalTextView:: +PutToClipboard (LPCTSTR pszText) +{ + if (pszText == NULL || _tcslen (pszText) == 0) + return FALSE; + + CWaitCursor wc; + BOOL bOK = FALSE; + if (OpenClipboard ()) + { + EmptyClipboard (); + HGLOBAL hData = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, _tcslen (pszText) + 1); + if (hData != NULL) + { + LPTSTR pszData = (LPTSTR)::GlobalLock (hData); + _tcscpy (pszData, (LPTSTR) pszText); + GlobalUnlock (hData); + bOK = SetClipboardData (CF_TEXT, hData) != NULL; + } + CloseClipboard (); + } + return bOK; +} + +BOOL CCrystalTextView:: +GetFromClipboard (CString & text) +{ + BOOL bSuccess = FALSE; + if (OpenClipboard ()) + { + HGLOBAL hData = GetClipboardData (CF_TEXT); + if (hData != NULL) + { + LPTSTR pszData = (LPTSTR) GlobalLock (hData); + if (pszData != NULL) + { + text = pszData; + GlobalUnlock (hData); + bSuccess = TRUE; + } + } + CloseClipboard (); + } + return bSuccess; +} diff --git a/Src/editlib/ceditreplacedlg.cpp b/Src/editlib/ceditreplacedlg.cpp new file mode 100644 index 000000000..d5257e007 --- /dev/null +++ b/Src/editlib/ceditreplacedlg.cpp @@ -0,0 +1,413 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ceditreplacedlg.cpp +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CEditReplaceDlg dialog, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: regular expressions, go to line and things ... +// + FEATURE: some other things I've forgotten ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ceditreplacedlg.h" +#include "ccrystaleditview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CEditReplaceDlg dialog + + +CEditReplaceDlg::CEditReplaceDlg (CCrystalEditView * pBuddy):CDialog (CEditReplaceDlg::IDD, NULL) +{ + ASSERT (pBuddy != NULL); + m_pBuddy = pBuddy; + //{{AFX_DATA_INIT(CEditReplaceDlg) + m_bMatchCase = FALSE; + m_bWholeWord = FALSE; + m_bRegExp = FALSE; + m_sText = _T (""); + m_sNewText = _T (""); + m_nScope = -1; + //}}AFX_DATA_INIT + m_bEnableScopeSelection = TRUE; +} + +void CEditReplaceDlg:: +UpdateRegExp () +{ + if (m_bRegExp) + { + m_ctlWholeWord.EnableWindow (FALSE); + m_bWholeWord = FALSE; + } + else + { + m_ctlWholeWord.EnableWindow (TRUE); + } +} + +void CEditReplaceDlg:: +DoDataExchange (CDataExchange * pDX) +{ + CDialog::DoDataExchange (pDX); + //{{AFX_DATA_MAP(CEditReplaceDlg) + DDX_Control (pDX, IDC_EDIT_TEXT, m_ctlFindText); + DDX_Control (pDX, IDC_EDIT_REPLACE_WITH, m_ctlReplText); + DDX_Control (pDX, IDC_EDIT_WHOLE_WORD, m_ctlWholeWord); + DDX_Check (pDX, IDC_EDIT_MATCH_CASE, m_bMatchCase); + DDX_Check (pDX, IDC_EDIT_WHOLE_WORD, m_bWholeWord); + DDX_Check (pDX, IDC_EDIT_REGEXP, m_bRegExp); + DDX_CBString (pDX, IDC_EDIT_TEXT, m_sText); + DDX_CBString (pDX, IDC_EDIT_REPLACE_WITH, m_sNewText); + DDX_Radio (pDX, IDC_EDIT_SCOPE_SELECTION, m_nScope); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP (CEditReplaceDlg, CDialog) +//{{AFX_MSG_MAP(CEditReplaceDlg) +ON_CBN_EDITCHANGE (IDC_EDIT_TEXT, OnChangeEditText) +ON_CBN_SELCHANGE (IDC_EDIT_TEXT, OnChangeEditText) +ON_BN_CLICKED (IDC_EDIT_REPLACE, OnEditReplace) +ON_BN_CLICKED (IDC_EDIT_REPLACE_ALL, OnEditReplaceAll) +ON_BN_CLICKED (IDC_EDIT_SKIP, OnEditSkip) +ON_BN_CLICKED (IDC_EDIT_REGEXP, OnRegExp) +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + +BOOL CEditReplaceDlg::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) + { + CButton *pSkip = (CButton*) GetDlgItem (IDC_EDIT_SKIP); + if (pSkip->GetButtonStyle () & BS_DEFPUSHBUTTON) + { + OnEditSkip (); + } + else + { + OnEditReplace (); + } + return TRUE; + } + return CDialog::PreTranslateMessage(pMsg); +} + +///////////////////////////////////////////////////////////////////////////// +// CEditReplaceDlg message handlers + +void CEditReplaceDlg::OnChangeEditText () +{ + UpdateData(); + GetDlgItem (IDC_EDIT_SKIP)->EnableWindow (!m_sText.IsEmpty ()); +} + +void CEditReplaceDlg:: +OnCancel () +{ + VERIFY (UpdateData ()); + CDialog::OnCancel (); +} + +BOOL CEditReplaceDlg:: +OnInitDialog () +{ + CDialog::OnInitDialog (); + + m_ctlReplText.m_sGroup = _T ("ReplaceText"); + m_ctlReplText.OnSetfocus (); + GetDlgItem (IDC_EDIT_REPLACE_WITH)->GetWindowText (m_sNewText); + UpdateData (FALSE); + m_ctlFindText.m_sGroup = _T ("FindText"); + m_ctlFindText.OnSetfocus (); + GetDlgItem (IDC_EDIT_SKIP)->EnableWindow (!m_sText.IsEmpty ()); + GetDlgItem (IDC_EDIT_SCOPE_SELECTION)->EnableWindow (m_bEnableScopeSelection); + m_bFound = FALSE; + UpdateRegExp (); + + return TRUE; +} + +BOOL CEditReplaceDlg:: +DoHighlightText () +{ + ASSERT (m_pBuddy != NULL); + DWORD dwSearchFlags = 0; + if (m_bMatchCase) + dwSearchFlags |= FIND_MATCH_CASE; + if (m_bWholeWord) + dwSearchFlags |= FIND_WHOLE_WORD; + if (m_bRegExp) + dwSearchFlags |= FIND_REGEXP; + + BOOL bFound; + if (m_nScope == 0) + { + // Searching selection only + bFound = m_pBuddy->FindTextInBlock (m_sText, m_ptFoundAt, m_ptBlockBegin, m_ptBlockEnd, + dwSearchFlags, FALSE, &m_ptFoundAt); + } + else + { + // Searching whole text + bFound = m_pBuddy->FindText (m_sText, m_ptFoundAt, dwSearchFlags, FALSE, &m_ptFoundAt); + } + + if (!bFound) + { + CString prompt; + prompt.Format (IDS_EDIT_TEXT_NOT_FOUND, m_sText); + AfxMessageBox (prompt); + m_ptCurrentPos = m_nScope == 0 ? m_ptBlockBegin : CPoint (0, 0); + return FALSE; + } + + m_pBuddy->HighlightText (m_ptFoundAt, m_pBuddy->m_nLastFindWhatLen); + return TRUE; +} + +BOOL CEditReplaceDlg:: +DoReplaceText (LPCTSTR /*pszNewText*/, DWORD dwSearchFlags) +{ + ASSERT (m_pBuddy != NULL); + // m_pBuddy->m_nLastFindWhatLen + + BOOL bFound; + if (m_nScope == 0) + { + // Searching selection only + bFound = m_pBuddy->FindTextInBlock (m_sText, m_ptFoundAt, m_ptBlockBegin, m_ptBlockEnd, + dwSearchFlags, FALSE, &m_ptFoundAt); + } + else + { + // Searching whole text + bFound = m_pBuddy->FindText (m_sText, m_ptFoundAt, dwSearchFlags, FALSE, &m_ptFoundAt); + } + + if (!bFound) + { + CString prompt; + prompt.Format (IDS_EDIT_TEXT_NOT_FOUND, m_sText); + AfxMessageBox (prompt); + m_ptCurrentPos = m_nScope == 0 ? m_ptBlockBegin : CPoint (0, 0); + return FALSE; + } + + m_pBuddy->HighlightText (m_ptFoundAt, m_pBuddy->m_nLastFindWhatLen); + return TRUE; +} + +void CEditReplaceDlg:: +OnEditSkip () +{ + if (!UpdateData ()) + return; + CButton *pSkip = (CButton*) GetDlgItem (IDC_EDIT_SKIP); + CButton *pRepl = (CButton*) GetDlgItem (IDC_EDIT_REPLACE); + + if (!m_bFound) + { + m_ptFoundAt = m_ptCurrentPos; + m_bFound = DoHighlightText (); + if (m_bFound) + { + pSkip->SetButtonStyle (pSkip->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pRepl->SetButtonStyle (pRepl->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pRepl->SetFocus (); + } + else + { + pRepl->SetButtonStyle (pRepl->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pSkip->SetButtonStyle (pSkip->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pSkip->SetFocus (); + } + return; + } + + if (!m_pBuddy->m_nLastFindWhatLen) + if (m_ptFoundAt.y + 1 < m_pBuddy->GetLineCount ()) + { + m_ptFoundAt.x = 0; + m_ptFoundAt.y++; + } + else + { + m_bFound = FALSE; + return; + } + else + m_ptFoundAt.x += 1; + m_bFound = DoHighlightText (); + if (m_bFound) + { + pSkip->SetButtonStyle (pSkip->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pRepl->SetButtonStyle (pRepl->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pRepl->SetFocus (); + } + else + { + pRepl->SetButtonStyle (pRepl->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pSkip->SetButtonStyle (pSkip->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pSkip->SetFocus (); + } +} + +void CEditReplaceDlg:: +OnEditReplace () +{ + if (!UpdateData ()) + return; + + if (!m_bFound) + { + m_ptFoundAt = m_ptCurrentPos; + m_bFound = DoHighlightText (); + CButton *pSkip = (CButton*) GetDlgItem (IDC_EDIT_SKIP); + CButton *pRepl = (CButton*) GetDlgItem (IDC_EDIT_REPLACE); + if (m_bFound) + { + pSkip->SetButtonStyle (pSkip->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pRepl->SetButtonStyle (pRepl->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pRepl->SetFocus (); + } + else + { + pRepl->SetButtonStyle (pRepl->GetButtonStyle () & ~BS_DEFPUSHBUTTON); + pSkip->SetButtonStyle (pSkip->GetButtonStyle () | BS_DEFPUSHBUTTON); + // pSkip->SetFocus (); + } + return; + } + DWORD dwSearchFlags = 0; + if (m_bMatchCase) + dwSearchFlags |= FIND_MATCH_CASE; + if (m_bWholeWord) + dwSearchFlags |= FIND_WHOLE_WORD; + if (m_bRegExp) + dwSearchFlags |= FIND_REGEXP; + + // We have highlighted text + VERIFY (m_pBuddy->ReplaceSelection (m_sNewText, dwSearchFlags)); + + // Manually recalculate points + if (m_bEnableScopeSelection) + { + if (m_ptBlockBegin.y == m_ptFoundAt.y && m_ptBlockBegin.x > m_ptFoundAt.x) + { + m_ptBlockBegin.x -= m_pBuddy->m_nLastFindWhatLen; + m_ptBlockBegin.x += m_pBuddy->m_nLastReplaceLen; + } + if (m_ptBlockEnd.y == m_ptFoundAt.y && m_ptBlockEnd.x > m_ptFoundAt.x) + { + m_ptBlockEnd.x -= m_pBuddy->m_nLastFindWhatLen; + m_ptBlockEnd.x += m_pBuddy->m_nLastReplaceLen; + } + } + if (!m_pBuddy->m_nLastFindWhatLen) + if (m_ptFoundAt.y + 1 < m_pBuddy->GetLineCount ()) + { + m_ptFoundAt.x = 0; + m_ptFoundAt.y++; + } + else + { + m_bFound = FALSE; + return; + } + else + { + m_ptFoundAt.x += m_pBuddy->m_nLastReplaceLen; + m_ptFoundAt = m_pBuddy->GetCursorPos (); + } + m_bFound = DoHighlightText (); +} + +void CEditReplaceDlg:: +OnEditReplaceAll () +{ + if (!UpdateData ()) + return; + + CWaitCursor waitCursor; + if (!m_bFound) + { + m_ptFoundAt = m_ptCurrentPos; + m_bFound = DoHighlightText (); + } + + while (m_bFound) + { + DWORD dwSearchFlags = 0; + if (m_bMatchCase) + dwSearchFlags |= FIND_MATCH_CASE; + if (m_bWholeWord) + dwSearchFlags |= FIND_WHOLE_WORD; + if (m_bRegExp) + dwSearchFlags |= FIND_REGEXP; + + // We have highlighted text + VERIFY (m_pBuddy->ReplaceSelection (m_sNewText, dwSearchFlags)); + + // Manually recalculate points + if (m_bEnableScopeSelection) + { + if (m_ptBlockBegin.y == m_ptFoundAt.y && m_ptBlockBegin.x > m_ptFoundAt.x) + { + m_ptBlockBegin.x -= m_pBuddy->m_nLastFindWhatLen; + m_ptBlockBegin.x += m_pBuddy->m_nLastReplaceLen; + } + if (m_ptBlockEnd.y == m_ptFoundAt.y && m_ptBlockEnd.x > m_ptFoundAt.x) + { + m_ptBlockEnd.x -= m_pBuddy->m_nLastFindWhatLen; + m_ptBlockEnd.x += m_pBuddy->m_nLastReplaceLen; + } + } + if (!m_pBuddy->m_nLastFindWhatLen) + if (m_ptFoundAt.y + 1 < m_pBuddy->GetLineCount ()) + { + m_ptFoundAt.x = 0; + m_ptFoundAt.y++; + } + else + { + m_bFound = FALSE; + break; + } + else + { + m_ptFoundAt.x += m_pBuddy->m_nLastReplaceLen; + m_ptFoundAt = m_pBuddy->GetCursorPos (); + } + m_bFound = DoHighlightText (); + } +} + +void CEditReplaceDlg:: +OnRegExp () +{ + UpdateData (TRUE); + UpdateRegExp (); + UpdateData (FALSE); +} diff --git a/Src/editlib/ceditreplacedlg.h b/Src/editlib/ceditreplacedlg.h new file mode 100644 index 000000000..8ea9ed168 --- /dev/null +++ b/Src/editlib/ceditreplacedlg.h @@ -0,0 +1,106 @@ +//////////////////////////////////////////////////////////////////////////// +// File: ceditreplacedlg.h +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Declaration of the CEditReplaceDlg dialog, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CEDITREPLACEDLG_H__759417E3_7B18_11D2_8C50_0080ADB86836__INCLUDED_) +#define AFX_CEDITREPLACEDLG_H__759417E3_7B18_11D2_8C50_0080ADB86836__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// ceditreplacedlg.h : header file +// + +#include "editcmd.h" +#include "memcombo.h" + +class CCrystalEditView; + +///////////////////////////////////////////////////////////////////////////// +// CEditReplaceDlg dialog + +class EDITPADC_CLASS CEditReplaceDlg : public CDialog + { +private : + CCrystalEditView * m_pBuddy; + BOOL m_bFound; + CPoint m_ptFoundAt; + BOOL DoHighlightText (); + BOOL DoReplaceText (LPCTSTR pszNewText, DWORD dwSearchFlags); + + // Construction +public : + CEditReplaceDlg (CCrystalEditView * pBuddy); + + BOOL m_bEnableScopeSelection; + CPoint m_ptCurrentPos; + CPoint m_ptBlockBegin, m_ptBlockEnd; + + // Dialog Data + //{{AFX_DATA(CEditReplaceDlg) + enum { IDD = IDD_EDIT_REPLACE }; + CMemComboBox m_ctlFindText; + CMemComboBox m_ctlReplText; + CButton m_ctlWholeWord; + BOOL m_bMatchCase; + BOOL m_bWholeWord; + BOOL m_bRegExp; + CString m_sText; + CString m_sNewText; + int m_nScope; + //}}AFX_DATA + + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEditReplaceDlg) + public: + virtual BOOL PreTranslateMessage(MSG* pMsg); + protected: + virtual void DoDataExchange (CDataExchange * pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + // Implementation +protected : + + void UpdateRegExp (); + + // Generated message map functions + //{{AFX_MSG(CEditReplaceDlg) + afx_msg void OnChangeEditText (); + virtual void OnCancel (); + virtual BOOL OnInitDialog (); + afx_msg void OnEditReplace (); + afx_msg void OnEditReplaceAll (); + afx_msg void OnEditSkip (); + afx_msg void OnRegExp (); + //}}AFX_MSG + DECLARE_MESSAGE_MAP () + }; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CEDITREPLACEDLG_H__759417E3_7B18_11D2_8C50_0080ADB86836__INCLUDED_) diff --git a/Src/editlib/cfindtextdlg.cpp b/Src/editlib/cfindtextdlg.cpp new file mode 100644 index 000000000..b7c8ac30a --- /dev/null +++ b/Src/editlib/cfindtextdlg.cpp @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////// +// File: cfindtextdlg.cpp +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CFindTextDlg dialog, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: regular expressions, go to line and things ... +// + FEATURE: some other things I've forgotten ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "cfindtextdlg.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFindTextDlg dialog + +CFindTextDlg::CFindTextDlg (CCrystalTextView * pBuddy):CDialog (CFindTextDlg::IDD, NULL) +{ + m_pBuddy = pBuddy; + //{{AFX_DATA_INIT(CFindTextDlg) + m_nDirection = 1; + m_bMatchCase = FALSE; + m_bWholeWord = FALSE; + m_bRegExp = FALSE; + m_sText = _T (""); + //}}AFX_DATA_INIT + m_ptCurrentPos = CPoint (0, 0); +} + +void CFindTextDlg:: +DoDataExchange (CDataExchange * pDX) +{ + CDialog::DoDataExchange (pDX); + //{{AFX_DATA_MAP(CFindTextDlg) + DDX_Control (pDX, IDC_EDIT_TEXT, m_ctlFindText); + DDX_Control (pDX, IDC_EDIT_WHOLE_WORD, m_ctlWholeWord); + DDX_Radio (pDX, IDC_EDIT_DIRECTION_UP, m_nDirection); + DDX_Check (pDX, IDC_EDIT_MATCH_CASE, m_bMatchCase); + DDX_CBString (pDX, IDC_EDIT_TEXT, m_sText); + DDX_Check (pDX, IDC_EDIT_WHOLE_WORD, m_bWholeWord); + DDX_Check (pDX, IDC_EDIT_REGEXP, m_bRegExp); + //}}AFX_DATA_MAP +} + +void CFindTextDlg:: +UpdateRegExp () +{ + if (m_bRegExp) + { + m_ctlWholeWord.EnableWindow (FALSE); + m_bWholeWord = FALSE; + } + else + { + m_ctlWholeWord.EnableWindow (TRUE); + } +} + +BEGIN_MESSAGE_MAP (CFindTextDlg, CDialog) +//{{AFX_MSG_MAP(CFindTextDlg) +ON_CBN_EDITCHANGE (IDC_EDIT_TEXT, OnChangeEditText) +ON_CBN_SELCHANGE (IDC_EDIT_TEXT, OnChangeEditText) +ON_BN_CLICKED (IDC_EDIT_REGEXP, OnRegExp) +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + +///////////////////////////////////////////////////////////////////////////// +// CFindTextDlg message handlers + +void CFindTextDlg::OnOK () +{ + if (UpdateData ()) + { + ASSERT (m_pBuddy != NULL); + DWORD dwSearchFlags = 0; + if (m_bMatchCase) + dwSearchFlags |= FIND_MATCH_CASE; + if (m_bWholeWord) + dwSearchFlags |= FIND_WHOLE_WORD; + if (m_bRegExp) + dwSearchFlags |= FIND_REGEXP; + if (m_nDirection == 0) + dwSearchFlags |= FIND_DIRECTION_UP; + + CPoint ptTextPos; + if (!m_pBuddy->FindText (m_sText, m_ptCurrentPos, dwSearchFlags, TRUE, &ptTextPos)) + { + CString prompt; + prompt.Format (IDS_EDIT_TEXT_NOT_FOUND, m_sText); + AfxMessageBox (prompt); + m_ptCurrentPos = CPoint (0, 0); + return; + } + + m_pBuddy->HighlightText (ptTextPos, m_pBuddy->m_nLastFindWhatLen, (dwSearchFlags & FIND_DIRECTION_UP) != 0); + + CDialog::OnOK (); + } +} + +void CFindTextDlg:: +OnChangeEditText () +{ + UpdateData(); + GetDlgItem (IDOK)->EnableWindow (!m_sText.IsEmpty ()); +} + +BOOL CFindTextDlg:: +OnInitDialog () +{ + CDialog::OnInitDialog (); + + UpdateData (FALSE); + m_ctlFindText.m_sGroup = _T ("FindText"); + m_ctlFindText.OnSetfocus (); + GetDlgItem (IDOK)->EnableWindow (!m_sText.IsEmpty ()); + UpdateRegExp (); + + return TRUE; +} + +void CFindTextDlg:: +OnCancel () +{ + VERIFY (UpdateData ()); + CDialog::OnCancel (); +} + +void CFindTextDlg:: +OnRegExp () +{ + UpdateData (TRUE); + UpdateRegExp (); + UpdateData (FALSE); +} diff --git a/Src/editlib/cfindtextdlg.h b/Src/editlib/cfindtextdlg.h new file mode 100644 index 000000000..189bebe65 --- /dev/null +++ b/Src/editlib/cfindtextdlg.h @@ -0,0 +1,90 @@ + //////////////////////////////////////////////////////////////////////////// +// File: cfindtextdlg.h +// Version: 1.0.0.0 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Declaration of the CFindTextDlg dialog, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 19-Jul-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CFINDTEXTDLG_H__F59009E3_7B01_11D2_8C4F_0080ADB86836__INCLUDED_) +#define AFX_CFINDTEXTDLG_H__F59009E3_7B01_11D2_8C4F_0080ADB86836__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "editcmd.h" +#include "memcombo.h" + +class CCrystalTextView; + +///////////////////////////////////////////////////////////////////////////// +// CFindTextDlg dialog + +class EDITPADC_CLASS CFindTextDlg : public CDialog + { +private : + CCrystalTextView * m_pBuddy; + + // Construction +public : + CFindTextDlg (CCrystalTextView * pBuddy); + + CPoint m_ptCurrentPos; + // Dialog Data + //{{AFX_DATA(CFindTextDlg) + enum { IDD = IDD_EDIT_FIND }; + CMemComboBox m_ctlFindText; + CButton m_ctlWholeWord; + int m_nDirection; + BOOL m_bMatchCase; + CString m_sText; + BOOL m_bWholeWord; + BOOL m_bRegExp; + //}}AFX_DATA + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CFindTextDlg) +protected : + virtual void DoDataExchange (CDataExchange * pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + // Implementation +protected : + + void UpdateRegExp (); + + // Generated message map functions + //{{AFX_MSG(CFindTextDlg) + virtual void OnOK (); + afx_msg void OnChangeEditText (); + virtual BOOL OnInitDialog (); + virtual void OnCancel (); + afx_msg void OnRegExp (); + //}}AFX_MSG + DECLARE_MESSAGE_MAP () + }; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CFINDTEXTDLG_H__F59009E3_7B01_11D2_8C4F_0080ADB86836__INCLUDED_) diff --git a/Src/editlib/chcondlg.cpp b/Src/editlib/chcondlg.cpp new file mode 100644 index 000000000..ba4a25793 --- /dev/null +++ b/Src/editlib/chcondlg.cpp @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////// +// File: chcondlg.cpp +// Version: 1.6.0.9 +// Updated: 17-Oct-1999 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Character encoding dialog +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "chcondlg.h" +#include "ccrystaltextview.h" +#include "cs2cs.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +EDITPADC_CLASS LPCTSTR pszCodeNames[] = + { + _T ("ASCII (without accents)"), + _T ("MS-Windows CP 1250"), + _T ("MS-Windows CP 1252"), + _T ("PC Latin I (CP 850)"), + _T ("PC Latin II (CP 852)"), + _T ("IBM Latin II (IBM 852)"), + _T ("ISO-8859-1"), + _T ("ISO-8859-2"), + _T ("Brothers Kamenicky"), + _T ("KOI8-CS"), + _T ("Apple Macintosh"), + _T ("Apple Macintosh for Central Europe"), + _T ("Corky"), + NULL + }; + +EDITPADC_CLASS int nCodeNames = countof (pszCodeNames) - 1; + +EDITPADC_CLASS void FillComboBox (CComboBox &Control, LPCTSTR *pszItems) +{ + Control.ResetContent(); + ASSERT (pszItems); + while (*pszItems) + Control.AddString(*pszItems++); +} + +///////////////////////////////////////////////////////////////////////////// +// CCharConvDlg dialog + +CCharConvDlg::CCharConvDlg () : CDialog (CCharConvDlg::IDD, NULL) +{ + //{{AFX_DATA_INIT(CCharConvDlg) + m_nSource = 1; + m_nDest = 1; + m_bAlpha = FALSE; + m_sPreview = _T(""); + //}}AFX_DATA_INIT +} + +void CCharConvDlg:: +DoDataExchange (CDataExchange * pDX) +{ + CDialog::DoDataExchange (pDX); + //{{AFX_DATA_MAP(CCharConvDlg) + DDX_Control(pDX, IDC_SRC, m_ctlSource); + DDX_Control(pDX, IDC_DEST, m_ctlDest); + DDX_CBIndex(pDX, IDC_SRC, m_nSource); + DDX_CBIndex(pDX, IDC_DEST, m_nDest); + DDX_Check(pDX, IDC_ALPHA_ONLY, m_bAlpha); + DDX_Text(pDX, IDC_PREVIEW, m_sPreview); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP (CCharConvDlg, CDialog) +//{{AFX_MSG_MAP(CCharConvDlg) + ON_BN_CLICKED(IDPREVIEW, OnPreview) + //}}AFX_MSG_MAP +END_MESSAGE_MAP () + +///////////////////////////////////////////////////////////////////////////// +// CCharConvDlg message handlers + +static int nSource = 1; +static int nDest = 1; + +BOOL CCharConvDlg:: +OnInitDialog () +{ + CDialog::OnInitDialog (); + FillComboBox (m_ctlSource, pszCodeNames); + FillComboBox (m_ctlDest, pszCodeNames); + m_nSource = nSource; + m_nDest = nSource; + m_sPreview = m_sOriginal; + UpdateData (FALSE); + return TRUE; +} + +void CCharConvDlg::OnOK () +{ + CDialog::OnOK (); + nSource = m_nSource; + nDest = m_nSource; +} + +void CCharConvDlg::OnPreview() +{ + UpdateData (); + LPTSTR pszNew; + if (!iconvert_new (m_sOriginal, &pszNew, m_nSource, m_nDest, m_bAlpha != FALSE)) + { + m_sPreview = pszNew; + UpdateData (FALSE); + } + if (pszNew) + free (pszNew); +} diff --git a/Src/editlib/chcondlg.h b/Src/editlib/chcondlg.h new file mode 100644 index 000000000..fd1dd7300 --- /dev/null +++ b/Src/editlib/chcondlg.h @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////// +// File: chcondlg.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Character encoding dialog +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __CHCONDLG_H__INCLUDED__ +#define __CHCONDLG_H__INCLUDED__ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "editcmd.h" + +class CCrystalTextView; + +///////////////////////////////////////////////////////////////////////////// +// CCharConvDlg dialog + +class EDITPADC_CLASS CCharConvDlg : public CDialog + { + // Construction +public : + CCharConvDlg (); + + // Dialog Data + //{{AFX_DATA(CCharConvDlg) + enum { IDD = IDD_EDIT_CHARCONV }; + CComboBox m_ctlSource; + CComboBox m_ctlDest; + int m_nSource; + int m_nDest; + BOOL m_bAlpha; + CString m_sPreview; + //}}AFX_DATA + CString m_sOriginal; + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CCharConvDlg) +protected : + virtual void DoDataExchange (CDataExchange * pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + // Implementation +protected : + + // Generated message map functions + //{{AFX_MSG(CCharConvDlg) + virtual void OnOK (); + virtual BOOL OnInitDialog (); + afx_msg void OnPreview(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP () + }; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // __CHCONDLG_H__INCLUDED__ diff --git a/Src/editlib/cplusplus.cpp b/Src/editlib/cplusplus.cpp new file mode 100644 index 000000000..6a1b9e1cd --- /dev/null +++ b/Src/editlib/cplusplus.cpp @@ -0,0 +1,489 @@ +/////////////////////////////////////////////////////////////////////////// +// File: cplusplus.cpp +// Version: 1.2.0.5 +// Created: 29-Dec-1998 +// +// Copyright: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalEditView class, a part of the Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 16-Aug-99 +// Ferdinand Prantl: +// + FEATURE: corrected bug in syntax highlighting C comments +// + FEATURE: extended levels 1- 4 of keywords in some languages +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszCppKeywordList[] = + { + _T ("_asm"), + _T ("__asm"), + _T ("_far16"), + _T ("__far16"), + _T ("enum"), + _T ("__multiple_inheritance"), + _T ("template"), + _T ("auto"), + _T ("__except"), + _T ("__single_inheritance"), + _T ("this"), + _T ("__based"), + _T ("explicit"), + _T ("__virtual_inheritance"), + _T ("thread"), + _T ("bool"), + _T ("extern"), + _T ("mutable"), + _T ("throw"), + _T ("break"), + _T ("false"), + _T ("naked"), + _T ("true"), + _T ("case"), + _T ("_fastcall"), + _T ("__fastcall"), + _T ("namespace"), + _T ("try"), + _T ("catch"), + _T ("__finally"), + _T ("new"), + _T ("__try"), + _T ("__cdecl"), + _T ("__pascal"), + _T ("_cdecl"), + _T ("_pascal"), + _T ("float"), + _T ("operator"), + _T ("typedef"), + _T ("char"), + _T ("for"), + _T ("private"), + _T ("typeid"), + _T ("class"), + _T ("friend"), + _T ("protected"), + _T ("typename"), + _T ("const"), + _T ("goto"), + _T ("public"), + _T ("union"), + _T ("const_cast"), + _T ("if"), + _T ("register"), + _T ("unsigned"), + _T ("continue"), + _T ("inline"), + _T ("reinterpret_cast"), + _T ("using"), + _T ("__declspec"), + _T ("__inline"), + _T ("return"), + _T ("uuid"), + _T ("default"), + _T ("int"), + _T ("short"), + _T ("__uuidof"), + _T ("delete"), + _T ("__int8"), + _T ("signed"), + _T ("virtual"), + _T ("_export"), + _T ("__export"), + _T ("dllexport"), + _T ("__int16"), + _T ("sizeof"), + _T ("void"), + _T ("dllimport"), + _T ("__int32"), + _T ("static"), + _T ("volatile"), + _T ("do"), + _T ("__int64"), + _T ("static_cast"), + _T ("wmain"), + _T ("double"), + _T ("__leave"), + _T ("_stdcall"), + _T ("__stdcall"), + _T ("_syscall"), + _T ("__syscall"), + _T ("while"), + _T ("dynamic_cast"), + _T ("long"), + _T ("struct"), + _T ("xalloc"), + _T ("else"), + _T ("main"), + _T ("switch"), + _T ("interface"), + // Added by a.s. + _T ("persistent"), + _T ("_persistent"), + _T ("transient"), + _T ("depend"), + _T ("ondemand"), + _T ("transient"), + _T ("cset"), + _T ("useindex"), + _T ("indexdef"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("LPTSTR"), + _T ("LPCTSTR"), + _T ("LPWSTR"), + _T ("LPCWSTR"), + _T ("LPTSTR"), + _T ("LPCTSTR"), + _T ("CHAR"), + _T ("WCHAR"), + _T ("TCHAR"), + _T ("BYTE"), + _T ("BOOL"), + _T ("TRUE"), + _T ("FALSE"), + _T ("INT"), + _T ("UINT"), + _T ("WORD"), + _T ("DWORD"), + _T ("WPARAM"), + _T ("LPARAM"), + _T ("LRESULT"), + _T ("CString"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsCppKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszCppKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsCppNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineC (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Preprocessor directive #.... + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + continue; + } + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsCppKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsCppNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsCppKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsCppNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/cregexp.cpp b/Src/editlib/cregexp.cpp new file mode 100644 index 000000000..18dccf806 --- /dev/null +++ b/Src/editlib/cregexp.cpp @@ -0,0 +1,1159 @@ +/////////////////////////////////////////////////////////////////////////// +// File: regexp.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Marko Macek +// E-mail: Marko.Macek@gmx.net or mark@hermes.si +// +// Some handy stuff to deal with regular expressions +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include +#include +#include "cregexp.h" + +//#define DEBUG + +static int RegCount = 0; + +#ifdef DEBUG +static void RxDump(int N, RxNode *n); +#endif + +static RxNode *NewNode(int aWhat) { + RxNode *N = (RxNode *) malloc(sizeof(RxNode)); + + if (N) { + memset(N, 0, sizeof(RxNode)); + N->fWhat = (short)aWhat; + } + return N; +} + +static RxNode *NewChar(TCHAR Ch) { + RxNode *A = NewNode(RE_CHAR); + + if (A) { + A->fChar = (LPTSTR) malloc(1); + A->fLen = 1; + A->fChar[0] = Ch; + } + return A; +} + +static RxNode *NewEscape(LPCTSTR *const Regexp) { + TCHAR Ch = **Regexp; + ++*Regexp; + switch (Ch) { + case 0: return 0; + case _T('a'): Ch = _T('\a'); break; + case _T('b'): Ch = _T('\b'); break; + case _T('f'): Ch = _T('\f'); break; + case _T('n'): Ch = _T('\n'); break; + case _T('r'): Ch = _T('\r'); break; + case _T('t'): Ch = _T('\t'); break; + case _T('v'): Ch = _T('\v'); break; + case _T('e'): Ch = 27; break; + case _T('s'): return NewNode(RE_WSPACE); + case _T('S'): return NewNode(RE_NWSPACE); + case _T('U'): return NewNode(RE_UPPER); + case _T('L'): return NewNode(RE_LOWER); + case _T('w'): return NewNode(RE_WORD); + case _T('W'): return NewNode(RE_NWORD); + case _T('d'): return NewNode(RE_DIGIT); + case _T('D'): return NewNode(RE_NDIGIT); + case _T('C'): return NewNode(RE_CASE); + case _T('c'): return NewNode(RE_NCASE); + case _T('N'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = N * 100; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = A + N * 10; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = A + N; + Ch = (TCHAR) A; + } + break; + case _T('o'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = N * 64; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = A + N * 8; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = A + N; + Ch = (TCHAR) A; + } + break; + case _T('x'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + (*Regexp)++; + A = N << 4; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + (*Regexp)++; + A = A + N; + Ch = (TCHAR) A; + } + break; + } + return NewChar(Ch); +} + + +#define NNN 32 // 8 * 32 = 256 (match set) + +#ifdef _UNICODE +#define SETOP(set,n) \ + do { \ + set[(TCHAR)(n) >> 3] |= (TCHAR)(1 << ((TCHAR)(n) & 7)); \ + } while (0) +#else // _UNICODE +#define SETOP(set,n) \ + do { \ + set[(unsigned char)(n) >> 3] |= (unsigned char)(1 << ((unsigned char)(n) & 7)); \ + } while (0) +#endif // _UNICODE + +static RxNode *NewSet(LPCTSTR * const Regexp) { +#ifdef _UNICODE + TCHAR set[NNN]; +#else // _UNICODE + unsigned char set[NNN]; +#endif // _UNICODE + int s = 0; + int c = 0; + unsigned int i, xx; +#ifdef _UNICODE + TCHAR Ch, C1 = 0, C2 = 0; +#else // _UNICODE + unsigned char Ch, C1 = 0, C2 = 0; +#endif // _UNICODE + int doset = 0; + + memset(set, 0, sizeof(set)); + s = 1; + if (**Regexp == _T('^')) { + s = 0; + ++*Regexp; + } + c = 0; + + while (**Regexp) { + switch (Ch = *((*Regexp)++)) { + case _T(']'): + if (doset == 1) return 0; + { + RxNode *N = NewNode(s?RE_INSET:RE_NOTINSET); + N->fChar = (LPTSTR) malloc(sizeof(set)); + N->fLen = sizeof(set); + if (N->fChar == 0) return 0; + memcpy(N->fChar, (LPTSTR) set, sizeof(set)); + return N; + } + case _T('\\'): + switch (Ch = *((*Regexp)++)) { + case 0: return 0; + case _T('a'): Ch = _T('\a'); break; + case _T('b'): Ch = _T('\b'); break; + case _T('f'): Ch = _T('\f'); break; + case _T('n'): Ch = _T('\n'); break; + case _T('r'): Ch = _T('\r'); break; + case _T('t'): Ch = _T('\t'); break; + case _T('v'): Ch = _T('\v'); break; + case _T('e'): Ch = 27; break; + case _T('N'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = N * 100; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = A + N * 10; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) return 0; + (*Regexp)++; + A = A + N; +#ifdef _UNICODE + Ch = (TCHAR)A; +#else // _UNICODE + Ch = (unsigned char)A; +#endif // _UNICODE + } + break; + case _T('o'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = N * 64; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = A + N * 8; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 7) return 0; + (*Regexp)++; + A = A + N; +#ifdef _UNICODE + Ch = (TCHAR)A; +#else // _UNICODE + Ch = (unsigned char)A; +#endif // _UNICODE + } + break; + case _T('x'): + { + unsigned int N = 0; + unsigned int A = 0; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + (*Regexp)++; + A = N << 4; + if (**Regexp == 0) return 0; + N = _totupper(**Regexp) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + (*Regexp)++; + A = A + N; +#ifdef _UNICODE + Ch = (TCHAR)A; +#else // _UNICODE + Ch = (unsigned char)A; +#endif // _UNICODE + } + break; + case _T('s'): + c += 4; + SETOP(set, _T('\n')); + SETOP(set, _T('\t')); + SETOP(set, _T(' ')); + SETOP(set, _T('\r')); + continue; + case _T('S'): + for (xx = 0; xx <= 255; xx++) { + if (xx != _T(' ') && xx != _T('\t') && xx != _T('\n') && xx != _T('\r')) { + c++; + SETOP(set, xx); + } + } + continue; + case _T('w'): + for (xx = 0; xx <= 255; xx++) { + if (_istalnum(xx)) { + c++; + SETOP(set, xx); + } + } + break; + case _T('W'): + for (xx = 0; xx <= 255; xx++) { + if (!isalnum(xx)) { + c++; + SETOP(set, xx); + } + } + break; + case _T('d'): + for (xx = 0; xx <= 255; xx++) { + if (_istdigit(xx)) { + c++; + SETOP(set, xx); + } + } + break; + case _T('D'): + for (xx = 0; xx <= 255; xx++) { + if (!_istdigit(xx)) { + c++; + SETOP(set, xx); + } + } + break; + case _T('U'): + for (xx = _T('A'); xx <= _T('Z'); xx++) { + c++; + SETOP(set, xx); + } + continue; + case _T('L'): + for (xx = _T('a'); xx <= _T('z'); xx++) { + c++; + SETOP(set, xx); + } + continue; + } + break; + } + if (doset == 0 && ((**Regexp) == _T('-'))) { + doset = 1; + C1 = Ch; + ++*Regexp; + continue; + } else if (doset == 1) { + C2 = Ch; + if (C2 < C1) return 0; + for(i = C1; i <= C2; i++) SETOP(set, i); + doset = 0; + continue; + } + c++; + SETOP(set, Ch); + } + return 0; +} + +static int AddNode(RxNode **F, RxNode **N, RxNode *A) { + if (A) { + if (*F) { + (*N)->fNext = A; + A->fPrev = (*N); + *N = A; + } else { + (*N) = (*F) = A; + A->fPrev = A->fNext = 0; + } + return 1; + } + return 0; +} + +static int CountWidth(RxNode *N) { + int w = 0; + + while (N) { + if (N->fWhat < 32) w += 0; + else if (N->fWhat >= 32 && N->fWhat < 64) + w += 1; + N = N->fNext; + } + return w; +} + +static int MakeSub(RxNode **F, RxNode **N, TCHAR What) { + //_tprintf(_T("MakeSub: %c\n", What)); + if (*N) { + RxNode *No; + RxNode *New; + RxNode *Jump, *Skip; + RxNode *Last = (*N); + + if (Last->fWhat & RE_GROUP) { + RxNode *P = Last->fPrev; + int C = 1; + + while ((C > 0) && P) { + //puts(_T("backtracking...-----")); + //RxDump(0, P); + if (P->fWhat & RE_GROUP) { + if (P->fWhat & RE_CLOSE) C++; + else C--; + } + Last = P; + if (C == 0) break; + P = P->fPrev; + } + //_tprintf(_T("P = %s, c = %d", P ? "ok":"null", C)); + if (C != 0) return 0; + } + assert(Last); + if (What != _T('?') && What != _T('|')) + if (CountWidth(Last) == 0) { + // puts(_T("FAILED count")); + return 0; + } + switch (What) { + case _T('?'): /* BRANCH x NOTHING */ + New = NewNode(RE_BRANCH | RE_GREEDY | What); + No = NewNode(RE_NOTHING); + if (!New || !No) return 0; + No->fPrev = *N; + if (*N) + (*N)->fNext = No; + New->fNext = Last; + New->fPrev = Last->fPrev; + Last->fPrev = New; + if (New->fPrev) { + New->fPrev->fNext = New; + } else { + *F = New; + } + New->fPtr = No; + No->fPtr = New; + *N = No; + //puts(_T("BRANCH ?")); + break; + + case _T('*'): + case _T('@'): + New = NewNode(RE_BRANCH | What | ((What == _T('*')) ? RE_GREEDY : 0)); + Jump = NewNode(RE_JUMP); + No = NewNode(RE_NOTHING); + + if (!New || !No || !Jump) return 0; + No->fPrev = Jump; + Jump->fNext = No; + Jump->fPrev = *N; + if (*N) + (*N)->fNext = Jump; + New->fNext = Last; + New->fPrev = Last->fPrev; + Last->fPrev = New; + if (New->fPrev) { + New->fPrev->fNext = New; + } else { + *F = New; + } + New->fPtr = No; + No->fPtr = New; + Jump->fPtr = New; + *N = No; + //puts(_T("BRANCH *")); + break; + + case _T('#'): + case _T('+'): + New = NewNode(RE_BRANCH | What | ((What == _T('+')) ? RE_GREEDY : 0)); + Skip = NewNode(RE_JUMP); + Jump = NewNode(RE_JUMP); + No = NewNode(RE_NOTHING); + + if (!New || !No || !Jump) return 0; + No->fPrev = Jump; + Jump->fPrev = *N; + Jump->fNext = No; + + Skip->fNext = New; + New->fPrev = Skip; + if (*N) + (*N)->fNext = Jump; + New->fNext = Last; + Skip->fPrev = Last->fPrev; + Last->fPrev = New; + if (Skip->fPrev) { + Skip->fPrev->fNext = Skip; + } else { + *F = Skip; + } + New->fPtr = No; + No->fPtr = New; + Jump->fPtr = New; + Skip->fPtr = Last; + *N = No; + //puts(_T("BRANCH +")); + break; + case _T('|'): + New = NewNode(RE_BRANCH | RE_GREEDY | What); + Jump = NewNode(RE_BREAK); + No = NewNode(RE_NOTHING); + + if (!New || !No || !Jump) return 0; + No->fPrev = Jump; + Jump->fNext = No; + Jump->fPrev = *N; + if (*N) + (*N)->fNext = Jump; + New->fNext = Last; + New->fPrev = Last->fPrev; + Last->fPrev = New; + if (New->fPrev) { + New->fPrev->fNext = New; + } else { + *F = New; + } + New->fPtr = No; + No->fPtr = New; + Jump->fPtr = New; + *N = No; + //puts(_T("BRANCH |")); + break; + } + return 1; + } + return 0; +} + +#define CHECK(n) do { if ((n) == 0) { return 0;} } while (0) + +static RxNode *RxComp(LPCTSTR *Regexp) { + RxNode *F = 0; + RxNode *N = 0; + int C; + TCHAR Ch; + + while (**Regexp) { + // puts(*Regexp); + switch (Ch = (*(*Regexp)++)) { + case _T('?'): + case _T('*'): + case _T('+'): + case _T('@'): + case _T('#'): + case _T('|'): + CHECK(MakeSub(&F, &N, Ch)); + break; + case _T('}'): + case _T(')'): + return F; + case _T('{'): + CHECK(AddNode(&F, &N, NewNode(RE_GROUP | RE_OPEN))); + CHECK(AddNode(&F, &N, RxComp(Regexp))); + while (N->fNext) N = N->fNext; + CHECK(AddNode(&F, &N, NewNode(RE_GROUP | RE_CLOSE))); + break; + case _T('('): + C = ++RegCount; + CHECK(AddNode(&F, &N, NewNode(RE_GROUP | RE_OPEN | RE_MEM | C))); + CHECK(AddNode(&F, &N, RxComp(Regexp))); + while (N->fNext) N = N->fNext; + CHECK(AddNode(&F, &N, NewNode(RE_GROUP | RE_CLOSE | RE_MEM | C))); + break; + case _T('\\'):CHECK(AddNode(&F, &N, NewEscape(Regexp))); break; + case _T('['): CHECK(AddNode(&F, &N, NewSet(Regexp))); break; + case _T('^'): CHECK(AddNode(&F, &N, NewNode(RE_ATBOL))); break; + case _T('$'): CHECK(AddNode(&F, &N, NewNode(RE_ATEOL))); break; + case _T('.'): CHECK(AddNode(&F, &N, NewNode(RE_ANY))); break; + case _T('<'): CHECK(AddNode(&F, &N, NewNode(RE_ATBOW))); break; + case _T('>'): CHECK(AddNode(&F, &N, NewNode(RE_ATEOW))); break; + default: + --*Regexp; + CHECK(AddNode(&F, &N, NewChar(**Regexp))); + ++*Regexp; + break; + } + } + return F; +} + +RxNode *RxOptimize(RxNode *rx) { + return rx; +} + +RxNode *RxCompile(LPCTSTR Regexp) { + RxNode *n = 0, *x; + if (Regexp == 0) return 0; + RegCount = 0; + n = RxComp(&Regexp); + if (n == 0) return 0; + n = RxOptimize(n); + x = n; + while (x->fNext) x = x->fNext; + x->fNext = NewNode(RE_END); + return n; +} + +void RxFree(RxNode *n) { + RxNode *p; + + while (n) { + p = n; + n = n->fNext; + switch (p->fWhat) { + case RE_INSET: + case RE_NOTINSET: + case RE_CHAR: + free(p->fChar); + break; + default: + break; + } + free(p); + } +} + +#define ChClass(x) (((((x) >= _T('A')) && ((x) <= _T('Z'))) || (((x) >= _T('a')) && ((x) <= _T('z'))) || (((x) >= _T('0')) && ((x) <= _T('9'))))?1:0) + +static RxMatchRes *match; +static LPCTSTR bop; +static LPCTSTR eop; +static int flags = RX_CASE; +static LPCTSTR rex; + +int RxMatch(RxNode *rx) { + RxNode *n = rx; + + //_tprintf(_T(">>")); + while (n) { + //_tprintf(_T("%-50.50s\n", rex)); + //RxDump(1, n); + switch (n->fWhat) { + case RE_NOTHING: + break; + case RE_CASE: + flags |= RX_CASE; + break; + case RE_NCASE: + flags &= ~RX_CASE; + break; + case RE_ATBOL: + if (rex != bop) return 0; + break; + case RE_ATEOL: + if (rex != eop) return 0; + break; + case RE_ANY: + if (rex == eop) return 0; + rex++; + break; + case RE_WSPACE: + if (rex == eop) return 0; + if (*rex != _T(' ') && *rex != _T('\n') && *rex != _T('\r') && *rex != _T('\t')) return 0; + rex++; + break; + case RE_NWSPACE: + if (rex == eop) return 0; + if (*rex == _T(' ') || *rex == _T('\n') || *rex == _T('\r') || *rex == _T('\t')) return 0; + rex++; + break; + case RE_WORD: + if (rex == eop) return 0; + if (!_istalnum(*rex)) return 0; + rex++; + break; + case RE_NWORD: + if (rex == eop) return 0; + if (_istalnum(*rex)) return 0; + rex++; + break; + case RE_DIGIT: + if (rex == eop) return 0; + if (!_istdigit(*rex)) return 0; + rex++; + break; + case RE_NDIGIT: + if (rex == eop) return 0; + if (_istdigit(*rex)) return 0; + rex++; + break; + case RE_UPPER: + if (rex == eop) return 0; + if (!_istupper(*rex)) return 0; + rex++; + break; + case RE_LOWER: + if (rex == eop) return 0; + if (!_istlower(*rex)) return 0; + rex++; + break; + case RE_ATBOW: + if (rex >= eop) return 0; + if (rex > bop) { + if ((ChClass(*rex) != 1) || (ChClass(*(rex-1)) != 0)) return 0; + } + break; + case RE_ATEOW: + if (rex <= bop) return 0; + if (rex < eop) { + if ((ChClass(*rex) != 0) || (ChClass(*(rex-1)) != 1)) return 0; + } + break; + case RE_CHAR: + if (rex == eop) return 0; + if (flags & RX_CASE) { + if (*n->fChar != *rex) return 0; + if (memcmp(rex, n->fChar, n->fLen) != 0) return 0; + } else { + for (int i = 0; i < n->fLen; i++) + if (_totupper(rex[i]) != _totupper(n->fChar[i])) + return 0; + } + rex += n->fLen; + break; + case RE_INSET: + if (rex == eop) return 0; +#ifdef _UNICODE + if ((n->fChar[(TCHAR)(*rex) >> 3] & (1 << ((TCHAR)(*rex) & 7))) == 0) return 0; +#else // _UNICODE + if ((n->fChar[(unsigned char)(*rex) >> 3] & (1 << ((unsigned char)(*rex) & 7))) == 0) return 0; +#endif // _UNICODE + rex++; + break; + case RE_NOTINSET: + if (rex == eop) return 0; +#ifdef _UNICODE + if (n->fChar[(TCHAR)(*rex) >> 3] & (1 << ((TCHAR)(*rex) & 7))) return 0; +#else // _UNICODE + if (n->fChar[(unsigned char)(*rex) >> 3] & (1 << ((unsigned char)(*rex) & 7))) return 0; +#endif // _UNICODE + rex++; + break; + case RE_JUMP: + n = n->fPtr; + continue; + case RE_END: + return 1; + case RE_BREAK: + n = n->fNext; + if (n->fNext == 0) break; + n = n->fNext; + if (n->fWhat & RE_BRANCH) { + while ((n->fWhat & RE_BRANCH) && n->fPtr && ((n->fWhat & 0xFF) == _T('|'))) + n = n->fPtr->fNext; + } + if (n->fWhat & RE_GROUP) { + int C = 1; + n = n->fNext; + while ((C > 0) && n) { + if (n->fWhat & RE_GROUP) { + if (n->fWhat & RE_OPEN) C++; + else C--; + } + if (C == 0) break; + n = n->fNext; + } + } + break; + default: + if (n->fWhat & RE_GROUP) { + if (n->fWhat & RE_MEM) { + LPCTSTR save = rex; + int b = n->fWhat & 0xFF; + int fl = flags; + + if (RxMatch(n->fNext) == 0) { + flags = fl; + if (n->fWhat & RE_OPEN) + match->Open[b] = -1; + else + match->Close[b] = -1; + return 0; + } + + if (n->fWhat & RE_OPEN) { + // if (match->Open[b] == -1) + match->Open[b] = (int) (save - bop); + } else { + // if (match->Close[b] == -1) + match->Close[b] = (int) (save - bop); + } + return 1; + } + } else if (n->fWhat & RE_BRANCH) { + LPCTSTR save = rex; + int fl = flags; + + if ((n->fWhat & RE_GREEDY) == 0) { + if (RxMatch(n->fPtr) == 1) return 1; + flags = fl; + rex = save; + } else { + if (RxMatch(n->fNext) == 1) return 1; + flags = fl; + rex = save; + n = n->fPtr; + continue; + } + } + break; + } + n = n->fNext; + } + /* NOTREACHED */ + assert(1 == 0 /* internal regexp error */); + return 0; +} + +int RxTry(RxNode *rx, LPCTSTR s) { + int fl = flags; + rex = s; + for (int i = 0; i < NSEXPS; i++) + match->Open[i] = match->Close[i] = -1; + if (RxMatch(rx)) { + match->Open[0] = (int) (s - bop); + match->Close[0] = (int) (rex - bop); + return 1; + } + flags = fl; + return 0; +} + +int RxExec(RxNode *Regexp, LPCTSTR Data, int Len, LPCTSTR Start, RxMatchRes *Match, unsigned int RxOpt) { + TCHAR Ch; + if (Regexp == 0) return 0; + + match = Match; + bop = Data; + eop = Data + Len; + + flags = RxOpt; + + for (int i = 0; i < NSEXPS; i++) Match->Open[i] = Match->Close[i] = -1; + + switch (Regexp->fWhat) { // this should be more clever + case RE_ATBOL: // match is anchored + return RxTry(Regexp, Start); + case RE_CHAR: // search for a character to match + Ch = Regexp->fChar[0]; + if (Start == eop) + break; + if (flags & RX_CASE) { + while (1) { + while (Start < eop && *Start != Ch) + Start++; + if (Start == eop) + break; + if (RxTry(Regexp, Start)) + return 1; + if (++Start == eop) + break; + } + } else { + Ch = (TCHAR)_totupper(Ch); + while (1) { + while (Start < eop && (TCHAR) _totupper(*Start) != Ch) + Start++; + if (Start == eop) + break; + if (RxTry(Regexp, Start)) + return 1; + if (++Start == eop) + break; + } + } + break; + default: // (slow) + do { + if (RxTry(Regexp, Start)) return 1; + } while (Start++ < eop); + break; + } + return 0; +} + +#define FLAG_UP_CASE 1 +#define FLAG_DOWN_CASE 2 +#define FLAG_UP_NEXT 4 +#define FLAG_DOWN_NEXT 8 + +static int add(int *len, LPTSTR *s, LPCTSTR a, int alen, int &flag) { + int NewLen = *len + alen; + int i; + + NewLen = NewLen * 2; + + if (alen == 0) + return 0; + + if (*s) { + *s = (LPTSTR) realloc(*s, NewLen); + assert(*s); + memcpy(*s + *len, a, alen); + } else { + *s = (LPTSTR) malloc(NewLen); + assert(*s); + memcpy(*s, a, alen); + *len = 0; + } + if (flag & FLAG_UP_CASE) { + LPTSTR p = *s + *len; + + for (i = 0; i < alen; i++) { + *p = (TCHAR)_totupper(*p); + p++; + } + } else if (flag & FLAG_DOWN_CASE) { + LPTSTR p = *s + *len; + + for (i = 0; i < alen; i++) { + *p = (TCHAR)_totlower(*p); + p++; + } + } + if (flag & FLAG_UP_NEXT) { + LPTSTR p = *s + *len; + + *p = (TCHAR)_totupper(*p); + flag &= ~FLAG_UP_NEXT; + } else if (flag & FLAG_DOWN_NEXT) { + LPTSTR p = *s + *len; + + *p = (TCHAR)_totlower(*p); + flag &= ~FLAG_DOWN_NEXT; + } + *len += alen; + return 0; +} + +int RxReplace(LPCTSTR rep, LPCTSTR Src, int /*len*/, RxMatchRes match, LPTSTR *Dest, int *Dlen) { + int dlen = 0; + LPTSTR dest = 0; + TCHAR Ch; + int n; + int flag = 0; + + *Dest = 0; + *Dlen = 0; + // add(&dlen, &dest, Src, match.Open[0]); + while (*rep) { + switch (Ch = *rep++) { + // case _T('&'): + // add(&dlen, &dest, Src + match.Open[0], match.Close[0] - match.Open[0], flag); + // break; + case _T('\\'): + switch (Ch = *rep++) { + case _T('0'): + case _T('1'): case _T('2'): case _T('3'): + case _T('4'): case _T('5'): case _T('6'): + case _T('7'): case _T('8'): case _T('9'): + n = Ch - 48; + + if (match.Open[n] != -1 && match.Close[n] != -1) { + add(&dlen, &dest, Src + match.Open[n], match.Close[n] - match.Open[n], flag); + } else return -1; + break; + case 0: + if (dest) free(dest); + return -1; // error + case _T('r'): Ch = _T('\r'); add(&dlen, &dest, &Ch, 1, flag); break; + case _T('n'): Ch = _T('\n'); add(&dlen, &dest, &Ch, 1, flag); break; + case _T('b'): Ch = _T('\b'); add(&dlen, &dest, &Ch, 1, flag); break; + case _T('a'): Ch = _T('\a'); add(&dlen, &dest, &Ch, 1, flag); break; + case _T('t'): Ch = _T('\t'); add(&dlen, &dest, &Ch, 1, flag); break; + case _T('U'): flag |= FLAG_UP_CASE; break; + case _T('u'): flag |= FLAG_UP_NEXT; break; + case _T('L'): flag |= FLAG_DOWN_CASE; break; + case _T('l'): flag |= FLAG_DOWN_NEXT; break; + case _T('E'): + case _T('e'): flag &= ~(FLAG_UP_CASE | FLAG_DOWN_CASE); break; + case _T('x'): + { + int N = 0; + int A = 0; + + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + rep++; + A = N << 4; + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 9) N = N + 48 - 65 + 10; if (N > 15) return 0; + rep++; + A = A + N; + Ch = (TCHAR)A; + } + add(&dlen, &dest, &Ch, 1, flag); + break; + case _T('d'): + { + int N = 0; + int A = 0; + + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 9) return 0; + rep++; + A = N * 100; + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 9) return 0; + rep++; + A = N * 10; + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 9) return 0; + rep++; + A = A + N; + Ch = (TCHAR)A; + } + add(&dlen, &dest, &Ch, 1, flag); + break; + case _T('o'): + { + int N = 0; + int A = 0; + + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 7) return 0; + rep++; + A = N * 64; + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 7) return 0; + rep++; + A = N * 8; + if (*rep == 0) return 0; + N = _totupper(*rep) - 48; if (N > 7) return 0; + rep++; + A = A + N; + Ch = (TCHAR)A; + } + add(&dlen, &dest, &Ch, 1, flag); + break; + default: + add(&dlen, &dest, &Ch, 1, flag); + break; + } + break; + default: + add(&dlen, &dest, &Ch, 1, flag); + break; + } + } + // add(&dlen, &dest, Src + match.Close[0], len - match.Close[0]); + *Dlen = dlen; + *Dest = dest; + return 0; +} + +#if 0 + +static void RxDump(int N, RxNode *n) { + while (n) { + for (int i = 0; i < N; i++) _tprintf(_T(" ")); + switch (n->fWhat) { + case RE_NOTHING: _tprintf(_T("NOTHING\n")); break; + case RE_CHAR: _tprintf(_T("CHAR '%.1s'\n"), n->fChar); break; + case RE_ATBOL: _tprintf(_T("^\n")); break; + case RE_ATEOL: _tprintf(_T("$\n")); break; + case RE_ANY: _tprintf(_T(".\n")); break; + case RE_INSET: _tprintf(_T("[\n")/*, n->fChar*/); break; + case RE_NOTINSET: _tprintf(_T("[^\n")/*, n->fChar*/); break; + case RE_ATBOW: _tprintf(_T("<\n")); break; + case RE_ATEOW: _tprintf(_T(">\n")); break; + case RE_WSPACE: _tprintf(_T("WSPACE\n")); break; + case RE_NWSPACE: _tprintf(_T("NWSPACE\n")); break; + case RE_UPPER: _tprintf(_T("UPPER\n")); break; + case RE_LOWER: _tprintf(_T("LOWER\n")); break; + case RE_JUMP: _tprintf(_T("JUMP\n")); break; + case RE_BREAK: _tprintf(_T("BREAK\n")); break; + case RE_END: _tprintf(_T("END\n")); break; + default: + if (n->fWhat & RE_GROUP) { + if (n->fWhat & RE_MEM) { + if (n->fWhat & RE_OPEN) _tprintf(_T("( %d\n"), n->fWhat & 0xFF); + if (n->fWhat & RE_CLOSE) _tprintf(_T(") %d\n"), n->fWhat & 0xFF); + } else { + if (n->fWhat & RE_OPEN) _tprintf(_T("{\n")); + if (n->fWhat & RE_CLOSE) _tprintf(_T("}\n")); + } + } else if (n->fWhat & RE_BRANCH) { + if (n->fWhat & RE_GREEDY) { + _tprintf(_T("%c\n"), n->fWhat & 0xFF); + } else { + _tprintf(_T("%c\n"), n->fWhat & 0xFF); + } + } else { + _tprintf(_T("???????????????\n")); + } + break; + } + n = n->fNext; + } +} + +#define TEST(rc,rx,st) \ + _tcscpy(line,st); \ + assert((a = RxCompile(rx)) != 0); \ + puts(_T("\n--- " rx " -- " st " -- ")); \ + RxDump(0,a);\ + assert(rc == RxExec(a, line, _tcslen(line), line, &b)); \ + RxFree(a); + +int main() { + RxNode *a; + RxMatchRes b; + TCHAR line[1024]; + + TEST(1, _T("a"), _T("a")); + TEST(0, _T("b"), _T("a")); + TEST(1, _T("aaaa"), _T("aaaa")); + TEST(0, _T("bbbb"), _T("aaaa")); + TEST(1, _T("."), _T("a")); + TEST(0, _T("."), _T("")); + TEST(1, _T("a.."), _T("axx")); + TEST(0, _T("a.."), _T("b..")); + TEST(1, _T("a?b"), _T("ab")); + TEST(1, _T("a?b"), _T("xb")); + TEST(0, _T("a?C"), _T("xb")); + TEST(1, _T("{aa}?b"), _T("aab")); + TEST(1, _T("{aa}?b"), _T("xab")); + TEST(0, _T("{aa}?C"), _T("xxb")); + TEST(1, _T("^aa"), _T("aa")); + TEST(0, _T("^aa"), _T("baa")); + TEST(1, _T("^aa$"),_T("aa")); + TEST(0, _T("^aa$"), _T("baab")); + TEST(1, _T("a*b"), _T("aaab")); + TEST(0, _T("a*b"), _T("aaaa")); + TEST(1, _T("{aa}*b"), _T("aaab")); + TEST(0, _T("{aa}*b"), _T("aaaa")); + TEST(1, _T("b+"), _T("bb")); + TEST(1, _T("b+"), _T("b")); + TEST(0, _T("b+"), _T("a")); + TEST(1, _T("^b+$"), _T("b")); + TEST(0, _T("^b+$"), _T("aba")); + TEST(1, _T("a|b"), _T(" a")); + TEST(1, _T("a|b"), _T(" b")); + TEST(0, _T("a|b"), _T(" c")); + TEST(1, _T("a|b|c|d|e"), _T(" a ")); + TEST(1, _T("a|b|c|d|e"), _T(" c ")); + TEST(1, _T("a|b|c|d|e"), _T(" e ")); + TEST(0, _T("a|b|c|d|e"), _T(" x ")); + TEST(1, _T("{a}|{b}|{c}|{d}|{e}"), _T(" a ")); + TEST(1, _T("{a}|{b}|{c}|{d}|{e}"), _T(" c ")); + TEST(1, _T("{a}|{b}|{c}|{d}|{e}"), _T(" e ")); + TEST(0, _T("{a}|{b}|{c}|{d}|{e}"), _T(" x ")); + TEST(1, _T("^xx{alpha}|{beta}xx$"), _T("xxalphaxx")); + TEST(1, _T("^xx{alpha}|{beta}xx$"), _T("xxbetaxx")); + TEST(1, _T("[a-z]"), _T("aaa")); + TEST(1, _T("^{Error}|{Warning}"), _T("Warning search.cpp 35: Conversion may lose significant digits in function AskReplace()")); + TEST(1, _T("^{Error}|{Warning} (.+)"), _T("Warning search.cpp 35: Conversion may lose significant digits in function AskReplace()")); + TEST(1, _T("^{Error}|{Warning} ([a-z.]#) ([0-9]#)"), _T("Warning search.cpp 35: Conversion may lose significant digits in function AskReplace()")); + TEST(1, _T("^{Error}|{Warning} (.+) ([0-9]+): (.*)$"), _T("Warning search.cpp 35: Conversion may lose significant digits in function AskReplace()")); + TEST(1, _T("^{Error}|{Warning} (.+) ([0-9]+): (.*)$"), _T("Error search.cpp 35: Conversion may lose significant digits in function AskReplace()")); + TEST(1, _T("^([a-z]+ +)*\\("), _T("blabla bla bla bla (")); + TEST(1, _T("^([a-z]+\\s+)+\\("), _T("blabla bla bla bla (")); + TEST(1, _T("^([a-z]+\\s*)+\\("), _T("blabla bla bla bla(")); + TEST(1, _T("^([a-z]+\\s+)+\\("), _T("blabla bla bla bla (")); + TEST(1, _T("^([a-z]+\\s*)+\\("), _T("blabla bla bla bla(")); + TEST(1, _T("^([a-z]# #)*\\("), _T("blabla bla bla bla (")); + TEST(1, _T("^([a-z]+ @)@\\("), _T("blabla bla bla bla (")); + TEST(1, _T("^[\\x20-\\xFF]+$"), _T("blabla")); + TEST(1, _T("{a{a{a{a|a}|{a|a}a}a}a|a}"), _T("aaaaaaaaaaaaaaaaa")); + + while (1) { + _tprintf(_T ("Regexp: ")); fflush(stdout); gets(line); + if (!*line) break; + a = RxCompile(line); RxDump(0, a); + _tprintf(_T ("String: ")); fflush(stdout); gets(line); + _tprintf(_T ("rc = %d\n"), RxExec(a, line, _tcslen(line), line, &b)); + for (int i = 0; i < NSEXPS; i++) { + if (b.Open[i] != -1) { + _tprintf(_T ("%d: %d %d\n"), i, b.Open[i], b.Close[i]); + } + } + RxFree(a); + } + return 0; +} + +#endif diff --git a/Src/editlib/cregexp.h b/Src/editlib/cregexp.h new file mode 100644 index 000000000..1d7f9e57e --- /dev/null +++ b/Src/editlib/cregexp.h @@ -0,0 +1,117 @@ +/////////////////////////////////////////////////////////////////////////// +// File: regexp.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Marko Macek +// E-mail: Marko.Macek@gmx.net or mark@hermes.si +// +// Some handy stuff to deal with regular expressions +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __REGEX_H +#define __REGEX_H + +/* + * Operator: + * + * ^ Match the beginning of line + * $ Match the end of line + * . Match any character + * [ ] Match characters in set + * [^ ] Match characters not in set + * ? Match previous pattern 0 or 1 times (greedy) + * | Match previous or next pattern + * @ Match previous pattern 0 or more times (non-greedy) + * # Match previous pattern 1 or more times (non-greedy) + * * Match previous pattern 0 or more times (greedy) + * + Match previous pattern 1 or more times (greedy) + * { } Group characters to form one pattern + * ( ) Group and remember + * \ Quote next character (only of not a-z) + * < Match beginning of a word + * > Match end of a word + * \x## Match character with ASCII code ## (hex) + * \N### Match ascii code ### (dec) + * \o### Match ascii code + * \a Match \a \r Match 0x13 (cr) + * \b Match \b \t Match 0x09 (tab) + * \f Match \f \v Match \v + * \n Match 0x10 (lf) \e Match escape (^E) + * \s Match whitespace (cr/lf/tab/space) + * \S Match nonwhitespace (!\S) + * \w Match word character + * \W Match non-word character + * \d Match digit character + * \D Match non-digit character + * \U Match uppercase + * \L Match lowercase + * \C Match case sensitively from here on + * \c Match case ingnore from here on + */ + +#define RE_NOTHING 0 // nothing +#define RE_JUMP 1 // jump to +#define RE_BREAK 2 // break | +#define RE_ATBOL 3 // match at beginning of line +#define RE_ATEOL 4 // match at end of line +#define RE_ATBOW 5 // match beginning of word +#define RE_ATEOW 6 // match end of word +#define RE_CASE 7 // match case sensitively from here +#define RE_NCASE 8 // ignore case from here. +#define RE_END 31 // end of regexp + +#define RE_ANY (32 + 1) // match any character +#define RE_INSET (32 + 2) // match if in set +#define RE_NOTINSET (32 + 3) // match if not in set +#define RE_CHAR (32 + 4) // match character string +#define RE_WSPACE (32 + 5) // match whitespace +#define RE_NWSPACE (32 + 6) // match whitespace +#define RE_UPPER (32 + 7) // match uppercase +#define RE_LOWER (32 + 8) // match lowercase +#define RE_DIGIT (32 + 9) // match digit +#define RE_NDIGIT (32 + 10) // match non-digit +#define RE_WORD (32 + 11) // match word +#define RE_NWORD (32 + 12) // match non-word + +#define RE_GROUP 256 // grouping +#define RE_OPEN 512 // open ( +#define RE_CLOSE 1024 // close ) +#define RE_MEM 2048 // store () match + +#define RE_BRANCH 4096 +#define RE_GREEDY 2048 // do a greedy match (as much as possible) + +#define NSEXPS 64 // for replace only 0-9 + +#define RX_CASE 1 // matchcase + +typedef struct _RxNode RxNode; + +struct _RxNode { + short fWhat; + short fLen; + RxNode *fPrev; + RxNode *fNext; + union { + LPTSTR fChar; + RxNode *fPtr; + }; +}; + +typedef struct { + int Open[NSEXPS]; // -1 = not matched + int Close[NSEXPS]; +} RxMatchRes; + +RxNode EDITPADC_CLASS *RxCompile(LPCTSTR Regexp); +int EDITPADC_CLASS RxExec(RxNode *Regexp, LPCTSTR Data, int Len, LPCTSTR Start, RxMatchRes *Match, unsigned int RxOpt = RX_CASE); +int EDITPADC_CLASS RxReplace(LPCTSTR rep, LPCTSTR Src, int len, RxMatchRes match, LPTSTR *Dest, int *Dlen); +void EDITPADC_CLASS RxFree(RxNode *Node); + +#endif diff --git a/Src/editlib/crystaleditviewex.cpp b/Src/editlib/crystaleditviewex.cpp new file mode 100644 index 000000000..0e430719c --- /dev/null +++ b/Src/editlib/crystaleditviewex.cpp @@ -0,0 +1,72 @@ +// CrystalEditViewEx.cpp: Implementierung der Klasse CCrystalEditViewEx. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "CrystalParser.h" +#include "CrystalEditViewEx.h" + + +////////////////////////////////////////////////////////////////////// +// Konstruktion/Destruktion +////////////////////////////////////////////////////////////////////// +IMPLEMENT_DYNCREATE(CCrystalEditViewEx,CCrystalEditView) + + +CCrystalEditViewEx::CCrystalEditViewEx() +: CCrystalEditView() +{ + m_pSyntaxParser = NULL; +} + + +HINSTANCE CCrystalEditViewEx::GetResourceHandle() +{ +#ifdef CE_DLL_BUILD + return g_hDllInstance; +#else + // -> HE + // call inherited + return CCrystalEditView::GetResourceHandle(); + // <- HE + // OLD + //return AfxGetInstanceHandle(); +#endif +} + + +DWORD CCrystalEditViewEx::ParseLine( DWORD dwCookie, int nLineIndex, + TEXTBLOCK *pBuf, int &nActualItems ) +{ + if( m_pSyntaxParser ) + { + CCrystalTextBlock *pTextBlock = + pBuf? new CCrystalTextBlock( (CCrystalTextBlock::TEXTBLOCK*)pBuf, nActualItems ) : NULL; + dwCookie = m_pSyntaxParser->ParseLine( dwCookie, nLineIndex, pTextBlock ); + + if( pTextBlock ) + delete pTextBlock; + + return dwCookie; + } + else + return 0; +} + + +CCrystalParser *CCrystalEditViewEx::SetSyntaxParser( CCrystalParser *pParser ) +{ + CCrystalParser *pOldParser = m_pSyntaxParser; + + m_pSyntaxParser = pParser; + + if( pParser ) + //BEGIN FP + pParser->m_pTextView = this; + /*ORIGINAL + pParser->m_pEditViewEx = this; + */ + //END FP + + return pOldParser; +} diff --git a/Src/editlib/crystaleditviewex.h b/Src/editlib/crystaleditviewex.h new file mode 100644 index 000000000..ed23e92e2 --- /dev/null +++ b/Src/editlib/crystaleditviewex.h @@ -0,0 +1,97 @@ +// CrystalEditViewEx.h: Schnittstelle für die Klasse CCrystalEditViewEx. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CRYSTALEDITVIEWEX_H__5353A214_1059_11D3_929E_CEFE4CA77E5E__INCLUDED_) +#define AFX_CRYSTALEDITVIEWEX_H__5353A214_1059_11D3_929E_CEFE4CA77E5E__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ccrystaleditview.h" + +#ifndef __CRYSTALSYNTAXPARSER_H__ +#include "CrystalParser.h" +#endif + + +class EDITPADC_CLASS CCrystalEditViewEx : public CCrystalEditView +{ + DECLARE_DYNCREATE(CCrystalEditViewEx) + +protected: + friend class CCrystalParser; + +/** @construction/destruction */ +public: + CCrystalEditViewEx(); + +/** @operations */ +public: + /** + Attaches a syntax parser to this view. + + @param pParser + The syntax parser to attach to this view. The Parser must be derived + from CCrystalParser. + + @return + The syntax parser that was used until the call to this function or + NULL if no one was attached to this view. + */ + CCrystalParser *SetSyntaxParser( CCrystalParser *pParser ); + +/** @overridables */ +protected: + /** + @description + Returns a handle to the instance (DLL or EXE) + + @return + Handle to the Instance (DLL or EXE) + + @remark + Equivalent to AfxGetInstanceHandle() + */ + virtual HINSTANCE GetResourceHandle(); + + + /** + @description + Is called by tht view, when there is a Line to parse. + + @param dwCookie + The result of parsing the previous line. This parameter contains flags, + you set while parsing the previous line. Normaly this will be flags that + indicate a region that was still open at the end of the last line. You + set those flags for a line by returning them ored (|). + @param nLineIndex + The zero-based index of the line to parse. + @param pBuf + You have to split the lines in to parts which are specified by there + beginning (zero-based index of the character in this line) and there text + color. You have to specifie each one of this blocks in this Buffer. + You can define a new Block with the macro DEFINE_BLOCK( pos, colorindex ). + + When the function ist called with this parameter set zu NULL, you only + have to calculate the cookies. + @param nActualItems + Used by the macro DEFINE_BLOCK. + + @return + The calculated flags for this line (see dwCookie). + */ + virtual DWORD ParseLine( DWORD dwCookie, int nLineIndex, + TEXTBLOCK *pBuf, int &nActualItems ); + +/** @attributes */ +protected: + /** + @description + The parser used to parse the Text or NULL if no parser is used. + */ + CCrystalParser *m_pSyntaxParser; +}; + +#endif // !defined(AFX_CRYSTALEDITVIEWEX_H__5353A214_1059_11D3_929E_CEFE4CA77E5E__INCLUDED_) diff --git a/Src/editlib/crystalparser.cpp b/Src/editlib/crystalparser.cpp new file mode 100644 index 000000000..ae4c1f3f6 --- /dev/null +++ b/Src/editlib/crystalparser.cpp @@ -0,0 +1,108 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CrystalParser.cpp +// +// Author: Sven Wiegand +// E-mail: sven.wiegand@gmx.de +// +// Implementation of the CCrystalParser class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "CrystalParser.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +IMPLEMENT_DYNAMIC( CCrystalParser, CObject ) + +CCrystalParser::CCrystalParser() +{ + m_pTextView = NULL; +} + + +CCrystalParser::~CCrystalParser() +{ +} + + +DWORD CCrystalParser::ParseLine(DWORD /*dwCookie*/, + int /*nLineIndex*/, + CCrystalTextBlock * /*pBlock*/ ) +{ + return 0; +} + + +void CCrystalParser::WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ) +{ + // The parser must be attached to a view! + ASSERT( m_pTextView ); + + int nLineLength = m_pTextView->GetLineLength( nLineIndex ); + int nTabWidth = m_pTextView->GetTabSize(); + int nLineCharCount = 0; + int nCharCount = 0; + LPCTSTR szLine = m_pTextView->GetLineChars( nLineIndex ); + int nLastBreakPos = 0; + int nLastCharBreakPos = 0; + BOOL bWhitespace = FALSE; + + for( int i = 0; i < nLineLength; i++ ) + { + // remember position of whitespace for wrap + if( bWhitespace ) + { + nLastBreakPos = i; + nLastCharBreakPos = nCharCount; + bWhitespace = FALSE; + } + + // increment char counter (evtl. expand tab) + if( szLine[i] == _T('\t') ) + { + nLineCharCount+= (nTabWidth - nCharCount % nTabWidth); + nCharCount+= (nTabWidth - nCharCount % nTabWidth); + } + else + { + nLineCharCount++; + nCharCount++; + } + + // remember whitespace + if( szLine[i] == _T('\t') || szLine[i] == _T(' ') ) + bWhitespace = TRUE; + + // wrap line + if( nLineCharCount >= nMaxLineWidth ) + { + if( anBreaks ) + { + // if no wrap position found, but line is to wide, + // wrap at current position + if( (nBreaks && nLastBreakPos == anBreaks[nBreaks - 1]) || (!nBreaks && !nLastBreakPos) ) + { + nLastBreakPos = i; + nLastCharBreakPos = nCharCount; + } + + anBreaks[nBreaks++] = nLastBreakPos; + } + else + nBreaks++; + + nLineCharCount = nCharCount - nLastCharBreakPos; + } + } +} diff --git a/Src/editlib/crystalparser.h b/Src/editlib/crystalparser.h new file mode 100644 index 000000000..b6780d440 --- /dev/null +++ b/Src/editlib/crystalparser.h @@ -0,0 +1,109 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CrystalParser.h +// +// Author: Sven Wiegand +// E-mail: sven.wiegand@gmx.de +// +// Interface of the CCrystalParser class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CRYSTALPARSER_H__17435DA0_1F72_11D3_929E_FD90DABF8479__INCLUDED_) +#define AFX_CRYSTALPARSER_H__17435DA0_1F72_11D3_929E_FD90DABF8479__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "CrystalTextBlock.h" + +/** +Objects of this class are used to describe language properties. At this time +language properties are: +

    +
  • Syntax highlighting (method ParseLine()) +
  • Word wrapping (method WrapLine()) +
+ +Derive your own class from CCrystalParser and override the method ParseLine() +to modify syntax highlighting and/or WrapLine() to modify line wrapping. + +Use the CCrystalTextView::SetParser() function to attach a parser to a text +view. + +@author Sven Wiegand +*/ +class EDITPADC_CLASS CCrystalParser : public CObject +{ + DECLARE_DYNAMIC(CCrystalParser) + friend class CCrystalTextView; + friend class CCrystalEditViewEx; + +// construction/destruction +public: + CCrystalParser(); + virtual ~CCrystalParser(); + +// overridables +public: + /** + Is called by tht view, when there is a Line to parse. + + @param dwCookie The result of parsing the previous line. This parameter contains flags, + you set while parsing the previous line. Normaly this will be flags that + indicate a region that was still open at the end of the last line. You + set those flags for a line by returning them ored (|). + @param nLineIndex The zero-based index of the line to parse. + @param pBlock You have to split the lines in to parts which are specified by there + beginning (zero-based index of the character in this line) and there text + color. You have to specifie each one of this blocks by adding them to + this block array, using CTextBlock::Add(). You do not have to care about + the sort to add the elements. + + When the function ist called with this parameter set zu NULL, you only + have to calculate the cookies which can be (hoply) done much more faster. + + @return The calculated flags for this line (see dwCookie). + */ + virtual DWORD ParseLine( DWORD dwCookie, int nLineIndex, CCrystalTextBlock *pBlock ); + + /** + Called by CCrystalTextView-object to wrap the line with the given index into sublines. + + The standard implementation wraps the line behind the first whitespace in front + of the word that exceeds the visible line width (nMaxLineWidth). Override + this function to provide your own word wrapping. + + Attention: Never call this function directly in other parts of the code + call WrapLineCached() instead, which will work much faster in most cases. + + @param nLineIndex The index of the line to wrap + + @param nMaxLineWidth The number of characters a subline of this line should + not exceed + + @param anBreaks An array of integers. Put the positions where to wrap the line + in that array (its allready allocated). If this pointer is NULL, the function + has only to compute the number of breaks (the parameter nBreaks). + + @param nBreaks The number of breaks this line has (number of sublines - 1). When + the function is called, this variable is 0. If the line is not wrapped, this value + should be 0 after the call. + + @see WrapLineCached() + */ + virtual void WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks ); + +// attributes +protected: + /** The text view this parser is attached to. */ + CCrystalTextView *m_pTextView; + +}; + +#endif // !defined(AFX_CRYSTALPARSER_H__17435DA0_1F72_11D3_929E_FD90DABF8479__INCLUDED_) diff --git a/Src/editlib/crystaltextblock.cpp b/Src/editlib/crystaltextblock.cpp new file mode 100644 index 000000000..0a237e0d8 --- /dev/null +++ b/Src/editlib/crystaltextblock.cpp @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CrystalTextBlock.cpp +// +// Author: Sven Wiegand +// E-mail: sven.wiegand@gmx.de +// +// Implementation of the CCrystalTextBufferEx class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "CrystalTextBlock.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +CCrystalTextBlock::CCrystalTextBlock( TEXTBLOCK *pTextBlock, int &rnActualItems ) +: m_rnActualItems( rnActualItems ) +{ + ASSERT( pTextBlock ); + m_pTextBlock = pTextBlock; +} + + +BOOL CCrystalTextBlock::Add( int nCharPos, int nColorIndex ) +{ + // insert new text block sorted by character position + for( int i = 0; i < m_rnActualItems && m_pTextBlock[i].m_nCharPos < nCharPos; i++ ); + + // insert text block + if( i < m_rnActualItems ) + { + // if new character position allready exists, the replace old one + if( m_pTextBlock[i].m_nCharPos == nCharPos ) + { + m_pTextBlock[i].m_nCharPos = nCharPos; + m_pTextBlock[i].m_nColorIndex = nColorIndex; + } + else + { + for( int j = ++m_rnActualItems - 1; j > i; j-- ) + { + m_pTextBlock[j].m_nCharPos = m_pTextBlock[j - 1].m_nCharPos; + m_pTextBlock[j].m_nColorIndex = m_pTextBlock[j - 1].m_nColorIndex; + } + m_pTextBlock[i].m_nCharPos = nCharPos; + m_pTextBlock[i].m_nColorIndex = nColorIndex; + } + } + else + { + // add text block to end of array + m_pTextBlock[m_rnActualItems].m_nCharPos = nCharPos; + m_pTextBlock[m_rnActualItems++].m_nColorIndex = nColorIndex; + } + + return TRUE; +} diff --git a/Src/editlib/crystaltextblock.h b/Src/editlib/crystaltextblock.h new file mode 100644 index 000000000..f1fa3cc12 --- /dev/null +++ b/Src/editlib/crystaltextblock.h @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////// +// File: CrystalTextBlock.h +// +// Author: Sven Wiegand +// E-mail: sven.wiegand@gmx.de +// +// Interface of the CCrystalTextBlock class, a part of Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CRYSTALTEXTBLOCK_H__37ECF0C1_145F_11D3_929E_444553540000__INCLUDED_) +#define AFX_CRYSTALTEXTBLOCK_H__37ECF0C1_145F_11D3_929E_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +/** +Objects of this class are passed to CCrystalParser::ParseLine() to get the +positions of color changes in a text line. + +You can simply add a color change using the Add()-Method. You do add the +color changes sorted by position -- the Add()-Method will do this for you. + +@author Sven Wiegand +*/ +class EDITPADC_CLASS CCrystalTextBlock +{ + friend class CCrystalTextView; + friend class CCrystalEditViewEx; + +protected: + struct TEXTBLOCK + { + int m_nCharPos; + int m_nColorIndex; + }; + +// construction/destruction +protected: + CCrystalTextBlock( TEXTBLOCK *pTextBlock, int &rnActualItems ); + +// operations +public: + /** + Adds a text block to the array. + + You do not need to add the text blocks in the order of character position. + + @param nCharPos + Character position of the line, where the text block starts. + @param nColorIndex + Index of the color to use to colorize the text block. + */ + BOOL Add( int nCharPos, int nColorIndex ); + +// attributes +protected: + /** text block to work on */ + TEXTBLOCK *m_pTextBlock; + + /** Index */ + int &m_rnActualItems; +}; + +#endif // !defined(AFX_CRYSTALTEXTBLOCK_H__37ECF0C1_145F_11D3_929E_444553540000__INCLUDED_) diff --git a/Src/editlib/cs2cs.cpp b/Src/editlib/cs2cs.cpp new file mode 100644 index 000000000..98431bb87 --- /dev/null +++ b/Src/editlib/cs2cs.cpp @@ -0,0 +1,248 @@ +/* Ferda Prantl - character coding conversion engine */ + +#include "stdafx.h" +#include "cs2cs.h" +#include +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define FD_ENCODING_LBRACKET _T ("") + +#define codes_count 13 +#define chars_all_count 66 +#define chars_alphabet_count 44 + +type_codes source_codes[] = +{ + {_T ("ASCII"), _T ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x26\x5c\x22\x3c\x3e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")}, + {_T ("CP1250"), _T ("\xc1\xc8\xcf\xc9\xcc\xcd\xd2\xd3\xd8\x8a\x8d\xda\xd9\xdd\x8e\xbc\xc0\xc5\xd4\xd6\xdc\xc4\xe1\xe8\xef\xe9\xec\xed\xf2\xf3\xf8\x9a\x9d\xfa\xf9\xfd\x9e\xbe\xe0\xe5\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x74\xa0\x7c\x63\x52\xb0\x2b\xb6\x7\0\0\0\xd7\0\xf7\0")}, + {_T ("CP1252"), _T ("\xc1\0\0\xc9\0\xcd\0\xd3\0\x8a\0\xda\0\xdd\0\0\0\0\xd4\xd6\xdc\xc4\xe1\0\0\xe9\0\xed\0\xf3\0\x9a\0\xfa\0\xfd\0\0\0\0\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x74\xa0\x7c\x63\x52\xb0\x2b\xb6\x7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("CP850"), _T ("\xb5\0\0\x90\0\xd6\0\xe0\0\0\0\xe9\0\xed\0\0\0\0\xe2\x99\x9a\x8e\xa0\0\0\x82\0\xa1\0\xa2\0\0\0\xa3\0\xec\0\0\0\0\x93\x94\x81\x84\xe1\0\x26\x5c\x22\x3c\x3e\0\0\0\0\0\xf8\xf1\xf5\xfa\xac\xab\0\x9e\0\xf6\xed")}, + {_T ("CP852"), _T ("\xb5\xac\xd2\x90\xb7\xd6\xd5\xe0\xfc\xe6\x9b\xe9\xde\xed\xa6\x95\xe8\x91\xe2\x99\x9a\x8e\xa0\x9f\xd4\x82\xd8\xa1\xe5\xa2\xfd\xe7\x9c\xa3\x85\xec\xa7\x96\xea\x92\x93\x94\x81\x84\xe1\xf5\x26\x5c\x22\x3c\x3e\0\0\0\0\0\xf8\0\xf5\0\0\0\0\x9e\0\xf6\0")}, + {_T ("IBM852"), _T ("\xb5\xab\xd2\x90\xb7\xd6\xd5\xe0\xfd\xe6\x9b\xe9\xde\xed\xa5\x95\xe8\x91\xe2\x99\x9a\x8e\xa0\x9f\xd4\x82\xd8\xa1\xe5\xa2\xfe\xe7\x9c\xa3\x85\xec\xa6\x96\xea\x92\x93\x94\x81\x84\xe1\xf5\x26\x5c\x22\x3c\x3e\0\0\0\0\0\xf8\0\xf5\0\0\0\0\x9e\0\xf6\0")}, + {_T ("ISO-8859-1"), _T ("\xc1\0\0\xc9\0\xcd\0\xd3\0\0\0\xda\0\xdd\0\0\0\0\xd4\xd6\xdc\xc4\xe1\0\0\xe9\0\xed\0\xf3\0\0\0\xfa\0\xfd\0\0\0\0\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\0\xa0\x7c\x63\x52\xb0\x2b\xb6\x7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("ISO-8859-2"), _T ("\xc1\xc8\xcf\xc9\xcc\xcd\xd2\xd3\xd8\xa9\xab\xda\xd9\xdd\xae\xa5\xc0\xc5\xd4\xd6\xdc\xc4\xe1\xe8\xef\xe9\xec\xed\xf2\xf3\xf8\xb9\xbb\xfa\xf9\xfd\xbe\xb5\xe0\xe5\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\0\xa0\x7c\x63\x52\xb0\x2b\xb6\x7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("KEYBCS2"), _T ("\x8f\x80\x85\x90\x89\x8b\xa5\x95\x9e\x9b\x86\x97\xa6\x9d\x92\x9c\xab\x8a\xa7\x99\x9a\x8e\xa0\x87\x83\x82\x88\xa1\xa4\xa2\xa9\xa8\x9f\xa3\x96\x98\x91\x8c\xaa\x8d\x93\x94\x81\x84\xe1\xad\x26\x5c\x22\x3c\x3e\0\0\0\0\0\xf8\xf1\xf5\xfa\xac\0\0\x9e\0\xf6\0")}, + {_T ("KOI8-CS"), _T ("\xe1\xe3\xe4\xf7\xe5\xe9\xee\xef\xf2\xf3\xf4\xf5\xea\xf9\xfa\xec\xe6\xeb\xf0\xed\xe8\xf1\xc1\xc3\xc4\xd7\xc5\xc9\xce\xcf\xd2\xd3\xd4\xd5\xca\xd9\xda\xcc\xc6\xcb\xd0\xcd\xc8\xd1\0\0\x26\x5c\x22\x3c\x3e\0\0\0\0\0\xfe\0\0\0\0\0\0\0\0\0\0")}, + {_T ("MAC"), _T ("\xe7\0\0\x83\0\xea\0\xee\0\0\0\xf2\0\0\0\0\0\0\xef\x85\x86\x80\x87\0\0\x8e\0\x92\0\x97\0\0\0\x9c\0\0\0\0\0\0\x99\x9a\x9f\x8a\xa7\xa4\x26\x5c\x22\x3c\x3e\xaa\xca\0\x63\xa8\xa1\x2b\x7c\0\0\0\0\0\xaf\xd6\xbf")}, + {_T ("MACCE"), _T ("\xe7\x89\x91\x83\x9d\xea\xc5\xee\xdb\xe1\xe8\xf2\xf1\xf8\xeb\xbb\xd9\xbd\xef\x85\x86\x80\x87\x8b\x93\x8e\x9e\x92\xcb\x97\xde\xe4\xe9\x9c\xf3\xf9\xec\xbc\xda\xbe\x99\x9a\x9f\x8a\xa7\xa4\x26\x5c\x22\x3c\x3e\xaa\xca\0\x63\xa8\xa1\x2b\x7c\0\0\0\0\0\xaf\xd6\xbf")}, + {_T ("CORK"), _T ("\xc1\x83\x84\xc9\x85\xcd\x8c\xd3\x90\x92\x94\xda\x97\xdd\x9a\x89\x8f\x88\xd4\xd6\xdc\xc4\xe1\xa3\xa4\xe9\xa5\xed\xac\xf3\xb0\xb2\xb4\xfa\xb7\xfd\xba\xa9\xaf\xa8\xf4\xf6\xfc\xe4\0\0\x26\x5c\x22\x3c\x3e\0\0\0\0\0\0\0\0\0\0\0\0\0\xd8\0\xf8")} +}, destination_codes[] = +{ + {_T ("ASCII"), _T ("\x41\x43\x44\x45\x45\x49\x4e\x4f\x52\x53\x54\x55\x55\x59\x5a\x4c\x52\x4c\x4f\x4f\x55\x41\x61\x63\x64\x65\x65\x69\x6e\x6f\x72\x73\x74\x75\x75\x79\x7a\x6c\x72\x6c\x6f\x6f\x75\x61\x73\x53\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20")}, + {_T ("CP1250"), _T ("\xc1\xc8\xcf\xc9\xcc\xcd\xd2\xd3\xd8\x8a\x8d\xda\xd9\xdd\x8e\xbc\xc0\xc5\xd4\xd6\xdc\xc4\xe1\xe8\xef\xe9\xec\xed\xf2\xf3\xf8\x9a\x9d\xfa\xf9\xfd\x9e\xbe\xe0\xe5\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x99\xa0\xa6\xa9\xae\xb0\xb1\xb6\xb7\x20\x20\x20\xd7\x20\xf7\x20")}, + {_T ("CP1252"), _T ("\xc1\x43\x44\xc9\x45\xcd\x4e\xd3\x52\x8a\x54\xda\x55\xdd\x5a\x4c\x52\x4c\xd4\xd6\xdc\xc4\xe1\x63\x64\xe9\x65\xed\x6e\xf3\x72\x9a\x74\xfa\x75\xfd\x7a\x6c\x72\x6c\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x99\xa0\xa6\xa9\xae\xb0\xb1\xb6\xb7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("CP850"), _T ("\xb5\x43\x44\x90\x45\xd6\x4e\xe0\x52\x53\x54\xe9\x55\xed\x5a\x4c\x52\x4c\xe2\x99\x9a\x8e\xa0\x63\x64\x82\x65\xa1\x6e\xa2\x72\x73\x74\xa3\x75\xec\x7a\x6c\x72\x6c\x93\x94\x81\x84\xe1\xf5\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\xf8\xf1\xf5\xfa\xac\xab\x20\x9e\x20\xf6\xed")}, + {_T ("CP852"), _T ("\xb5\xac\xd2\x90\xb7\xd6\xd5\xe0\xfc\xe6\x9b\xe9\xde\xed\xa6\x95\xe8\x91\xe2\x99\x9a\x8e\xa0\x9f\xd4\x82\xd8\xa1\xe5\xa2\xfd\xe7\x9c\xa3\x85\xec\xa7\x96\xea\x92\x93\x94\x81\x84\xe1\xf5\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\xf8\x20\xf5\x20\x20\x20\x20\x9e\x20\xf6\x20")}, + {_T ("IBM852"), _T ("\xb5\xab\xd2\x90\xb7\xd6\xd5\xe0\xfd\xe6\x9b\xe9\xde\xed\xa5\x95\xe8\x91\xe2\x99\x9a\x8e\xa0\x9f\xd4\x82\xd8\xa1\xe5\xa2\xfe\xe7\x9c\xa3\x85\xec\xa6\x96\xea\x92\x93\x94\x81\x84\xe1\xf5\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\xf8\x20\xf5\x20\x20\x20\x20\x9e\x20\xf6\x20")}, + {_T ("ISO-8859-1"), _T ("\xc1\x43\x44\xc9\x45\xcd\x4e\xd3\x52\x53\x54\xda\x55\xdd\x5a\x4c\x52\x4c\xd4\xd6\xdc\xc4\xe1\x63\x64\xe9\x65\xed\x6e\xf3\x72\x73\x74\xfa\x75\xfd\x7a\x6c\x72\x6c\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x20\xa0\xa6\xa9\xae\xb0\xb1\xb6\xb7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("ISO-8859-2"), _T ("\xc1\xc8\xcf\xc9\xcc\xcd\xd2\xd3\xd8\xa9\xab\xda\xd9\xdd\xae\xa5\xc0\xc5\xd4\xd6\xdc\xc4\xe1\xe8\xef\xe9\xec\xed\xf2\xf3\xf8\xb9\xbb\xfa\xf9\xfd\xbe\xb5\xe0\xe5\xf4\xf6\xfc\xe4\xdf\xa7\x26\x5c\x22\x3c\x3e\x20\xa0\xa6\xa9\xae\xb0\xb1\xb6\xb7\xbc\xbd\xbe\xd7\xd8\xf7\xf8")}, + {_T ("KEYBCS2"), _T ("\x8f\x80\x85\x90\x89\x8b\xa5\x95\x9e\x9b\x86\x97\xa6\x9d\x92\x9c\xab\x8a\xa7\x99\x9a\x8e\xa0\x87\x83\x82\x88\xa1\xa4\xa2\xa9\xa8\x9f\xa3\x96\x98\x91\x8c\xaa\x8d\x93\x94\x81\x84\xe1\xad\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\xf8\xf1\xf5\xfa\xac\x20\x20\x9e\x20\xf6\x20")}, + {_T ("KOI8-CS"), _T ("\xe1\xe3\xe4\xf7\xe5\xe9\xee\xef\xf2\xf3\xf4\xf5\xea\xf9\xfa\xec\xe6\xeb\xf0\xed\xe8\xf1\xc1\xc3\xc4\xd7\xc5\xc9\xce\xcf\xd2\xd3\xd4\xd5\xca\xd9\xda\xcc\xc6\xcb\xd0\xcd\xc8\xd1\x73\x53\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\xfe\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20")}, + {_T ("MAC"), _T ("\xe7\x43\x44\x83\x45\xea\x4e\xee\x52\x53\x54\xf2\x55\x59\x5a\x4c\x52\x4c\xef\x85\x86\x80\x87\x63\x64\x8e\x65\x92\x6e\x97\x72\x73\x74\x9c\x75\x79\x7a\x6c\x72\x6c\x99\x9a\x9f\x8a\xa7\xa4\x26\x5c\x22\x3c\x3e\xaa\xca\x20\xa9\xa8\xa1\xb1\xa6\x20\x20\x20\x20\x20\xaf\xd6\xbf")}, + {_T ("MACCE"), _T ("\xe7\x89\x91\x83\x9d\xea\xc5\xee\xdb\xe1\xe8\xf2\xf1\xf8\xeb\xbb\xd9\xbd\xef\x85\x86\x80\x87\x8b\x93\x8e\x9e\x92\xcb\x97\xde\xe4\xe9\x9c\xf3\xf9\xec\xbc\xda\xbe\x99\x9a\x9f\x8a\xa7\xa4\x26\x5c\x22\x3c\x3e\xaa\xca\x20\xa9\xa8\xa1\xb1\xa6\x20\x20\x20\x20\x20\xaf\xd6\xbf")}, + {_T ("CORK"), _T ("\xc1\x83\x84\xc9\x85\xcd\x8c\xd3\x90\x92\x94\xda\x97\xdd\x9a\x89\x8f\x88\xd4\xd6\xdc\xc4\xe1\xa3\xa4\xe9\xa5\xed\xac\xf3\xb0\xb2\xb4\xfa\xb7\xfd\xba\xa9\xaf\xa8\xf4\xf6\xfc\xe4\x73\x53\x26\x5c\x22\x3c\x3e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xd8\x20\xf8")} +}; + +bool alphabet_only; +int chars_count; + +void +str_fill (LPTSTR s, TCHAR ch, long count) +{ + while (count--) + *s++ = ch; + *s = _T ('\0'); +} + +long +str_pos (LPCTSTR whole, LPCTSTR piece) +{ + LPCTSTR s = whole; + long l = _tcslen (piece); + + while (*s) + if (!_tcsnicmp (s++, piece, l)) + return s - whole - 1; + return -2; +} + +bool +str_same (LPCTSTR str1, LPCTSTR str2, long count) +{ + if (!count) + return false; + while (count--) + if (*str1++ != *str2++) + return false; + return true; +} + +LPCTSTR +skip_spaces (LPCTSTR s) +{ + while (*s) + if (*s == _T (' ') || *s == _T ('\t') || *s == _T ('\r') || *s == _T ('\n')) + s++; + else + break; + return s; +} + +LPCTSTR +skip_word (LPCTSTR s) +{ + s = skip_spaces (s); + while (*s) + if (*s != _T (' ') && *s != _T ('\t') && *s != _T ('\r') && *s != _T ('\n') && *s != _T ('=')) + s++; + else + break; + return skip_spaces (s); +} + +long +get_coding (LPCTSTR name, type_codes *codes, int *coding) +{ + long i, pos; + + for (i = 0; i < codes_count; i++) + if ((pos = str_pos (name, codes[i].name)) >= 0) + { + *coding = i; + return pos; + } + *coding = -2; + return -2; +} + +long +fget_coding (LPCTSTR text, int *coding) +{ + long posit, i; + LPCTSTR s, s1; + + while ((i = str_pos (text, FD_ENCODING_LBRACKET)) >= 0) + { + s = text + i; + + if ((i = str_pos (s, FD_ENCODING_LBRACKET FD_ENCODING_MARK)) >= 0) + posit += (s += _tcslen (FD_ENCODING_LBRACKET)) - text; + else if (*(s = skip_word (s1 = s)) != _T ('\0')) + posit += s - text; + if ((i = str_pos (s, FD_ENCODING_MARK)) >= 0) + { + if (*(s = skip_word ((s1 = s) + i)) != _T ('\0')) + posit += s - s1; + if (*s == _T ('=')) + { + if (*(s = skip_spaces ((s1 = s) + 1)) != _T ('\0')) + posit += s - s1; + i = get_coding (s, source_codes, coding); + if (i >= 0) + return posit + i; + } + } + } + *coding = -2; + return -2; +} + +TCHAR iconvert_char (TCHAR ch, int source_coding, int destination_coding, bool alphabet_only) + { + long i; + LPCTSTR source_chars, destination_chars; + + if (source_coding < 0) + return ch; + if (destination_coding < 0) + return ch; + + chars_count = alphabet_only ? chars_alphabet_count : chars_all_count; + source_chars = source_codes[source_coding].codes; + destination_chars = destination_codes[destination_coding].codes; + i = chars_count; + if ((unsigned) ch > 127) + for (i = 0; i < chars_count; i++) + if (ch == source_chars[i]) + break; + return i < chars_count ? destination_chars[i] : ch; + } + +int +iconvert (LPTSTR string, int source_coding, int destination_coding, bool alphabet_only) + { + long posit = -2, i, j; + LPCTSTR source_chars, destination_chars, cod_pos = NULL; + TCHAR ch; + LPTSTR s = string; + + if (source_coding < 0) + { + posit = fget_coding (string, &source_coding); + if (posit) + cod_pos = string + posit; + } + if (source_coding < 0) + return -1; + if (destination_coding < 0) + return -2; + + chars_count = alphabet_only ? chars_alphabet_count : chars_all_count; + source_chars = source_codes[source_coding].codes; + destination_chars = destination_codes[destination_coding].codes; + for (;;) + if (cod_pos == s) + { + i = _tcslen (source_codes[source_coding].name); + j = _tcslen (destination_codes[destination_coding].name); + if (i != j) + memmove (s + j, s + i, _tcslen (s + i) + 1); + memcpy (s, destination_codes[destination_coding].name, j); + s += j; + } + else + { + ch = *s; + if (!ch) + break; + i = chars_count; + if ((unsigned) ch > 127) + for (i = 0; i < chars_count; i++) + if (ch == source_chars[i]) + break; + if (i < chars_count) + { + ch = destination_chars[i]; + *s = ch; + } + s++; + } + return 0; + } + +int +iconvert_new (LPCTSTR source, LPTSTR *destination, int source_coding, int destination_coding, bool alphabet_only) + { + LPTSTR dest = (LPTSTR) malloc (_tcslen (source) + 1 + 10); /* reserved for MYCHARSET= replacement */ + int result = -3; + if (dest) + { + _tcscpy (dest, source); + result = iconvert (dest, source_coding, destination_coding, alphabet_only); + if (!result) + { + *destination = dest; + return 0; + } + free (dest); + } + return result; + } diff --git a/Src/editlib/cs2cs.h b/Src/editlib/cs2cs.h new file mode 100644 index 000000000..ec94afb55 --- /dev/null +++ b/Src/editlib/cs2cs.h @@ -0,0 +1,59 @@ +/* Ferda Prantl - character coding conversion engine */ + +#ifndef __CS2CS_H__INCLUDED__ +#define __CS2CS_H__INCLUDED__ + +#define FD_CODE_ASCII 0 +#define FD_CODE_CP1250 1 +#define FD_CODE_CP1252 2 +#define FD_CODE_CP850 3 +#define FD_CODE_CP852 4 +#define FD_CODE_IBM852 5 +#define FD_CODE_ISO_8859_1 6 +#define FD_CODE_ISO_8859_2 7 +#define FD_CODE_KEYBCS2 8 +#define FD_CODE_KOI8_CS 9 +#define FD_CODE_MAC 10 +#define FD_CODE_MACCE 11 +#define FD_CODE_CORK 12 +#define FD_CODE_TEX1 13 +#define FD_CODE_TEX2 14 +#define FD_CODE_HTML1 15 +#define FD_CODE_HTML2 16 +#define FD_CODE_RTF1 17 +#define FD_CODE_RTF2 18 + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +#ifndef _T +typedef char TCHAR; +typedef const char *LPCTSTR; +typedef char *LPTSTR; +#define _T(x) x +#define _tcscpy strcpy +#define _tcslen strlen +#define _tcsnicmp strnicmp +#endif /* _T */ + +#ifndef __cplusplus +#define false 0 +#define true 1 +typedef int bool; +#endif /* __cplusplus */ + +typedef struct type_codes_t + { + LPCTSTR name, codes; + } +type_codes; + +extern type_codes source_codes[]; +extern type_codes destination_codes[]; + +TCHAR EDITPADC_CLASS iconvert_char (TCHAR ch, int source_coding, int destination_coding, bool alphabet_only); +int EDITPADC_CLASS iconvert (LPTSTR string, int source_coding, int destination_coding, bool alphabet_only); +int EDITPADC_CLASS iconvert_new (LPCTSTR source, LPTSTR *destination, int source_coding, int destination_coding, bool alphabet_only); + +#endif // __CS2CS_H__INCLUDED__ diff --git a/Src/editlib/dcl.cpp b/Src/editlib/dcl.cpp new file mode 100644 index 000000000..3e728b5ae --- /dev/null +++ b/Src/editlib/dcl.cpp @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////////////////////////// +// File: dcl.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// AutoCAD DCL syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszDclKeywordList[] = + { + _T ("boxed_column"), + _T ("boxed_radio_column"), + _T ("boxed_radio_row"), + _T ("boxed_row"), + _T ("button"), + _T ("column"), + _T ("concatenation"), + _T ("dialog"), + _T ("edit_box"), + _T ("image"), + _T ("list_box"), + _T ("paragraph"), + _T ("popup_list"), + _T ("radio_button"), + _T ("row"), + _T ("slider"), + _T ("spacer"), + _T ("text_part"), + _T ("text"), + _T ("toggle"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("spacer_0"), + _T ("spacer_1"), + _T ("default_button"), + _T ("retirement_button"), + _T ("ok_cancel_help_errtile"), + _T ("ok_cancel_help_info"), + _T ("ok_cancel"), + _T ("ok_cancel_err"), + _T ("ok_cancel_help"), + _T ("ok_only"), + _T ("ok_button"), + _T ("cancel_button"), + _T ("help_button"), + _T ("info_button"), + _T ("errtile"), + _T ("image_button"), + _T ("radio_column"), + _T ("radio_row"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("action"), + _T ("alignment"), + _T ("allow_accept"), + _T ("aspect_ratio"), + _T ("big_increment"), + _T ("children_alignment"), + _T ("children_fixed_height"), + _T ("children_fixed_width"), + _T ("edit_limit"), + _T ("edit_width"), + _T ("fixed_height"), + _T ("fixed_width"), + _T ("height"), + _T ("initial_focus"), + _T ("is_bold"), + _T ("is_cancel"), + _T ("is_default"), + _T ("is_enabled"), + _T ("is_tab_stop"), + _T ("key"), + _T ("label"), + _T ("layout"), + _T ("list"), + _T ("max_value"), + _T ("min_value"), + _T ("mnemonic"), + _T ("multiple_select"), + _T ("small_increment"), + _T ("tabs"), + _T ("value"), + _T ("width"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsDclKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszDclKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsDclNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineDcl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsDclKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsDclNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '{' || pszChars[j] == ':') + { + bFunction = TRUE; + } + break; + } + } + if (!bFunction) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == ':') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsDclKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsDclNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '{' || pszChars[j] == ':') + { + bFunction = TRUE; + } + break; + } + } + if (!bFunction) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == ':') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/editcmd.h b/Src/editlib/editcmd.h new file mode 100644 index 000000000..8875a065d --- /dev/null +++ b/Src/editlib/editcmd.h @@ -0,0 +1,325 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by editres.rc +// +#define IDPREVIEW 3 +#define IDD_ABOUTBOX 100 +#define IDD_EDFILEOPEN 101 +#define IDD_EDITOR_PAGE 102 +#define IDB_LIGHTBULB 102 +#define IDM_POPUP_HLINK 103 +#define IDD_TIP 103 +#define IDD_HLINK_PROPERTIES 105 +#define IDS_HLINK_PROPERTIES 105 +#define IDS_RICHED_LOAD_FAIL 108 +#define IDI_EDITPAD 128 +#define IDI_EDITPADTYPE 129 +#define IDC_HLINK 130 +#define IDI_EDITPADRICHTYPE 130 +#define IDI_EDITPADBINTYPE 131 +#define IDC_HLINK_BAD 131 +#define IDI_HLINK_URL 132 +#define IDD_SPLASH 157 +#define IDC_STATIC1 158 +#define IDB_BITMAP48 162 +#define IDS_TIP_DIDYOUKNOW 301 +#define IDS_TIP_FILE_ABSENT 302 +#define IDS_TIP_FILE_CORRUPT 303 +#define IDB_LIGHTBULB2 344 +#define IDC_ME 1000 +#define IDC_BULB 1000 +#define IDC_ANDREI 1001 +#define IDC_STARTUP 1001 +#define IDR_POPUP_HEX_EDIT 1001 +#define IDC_SVEN 1002 +#define IDC_INSERT_TABS 1002 +#define IDC_NEXTTIP 1002 +#define IDC_IMAGE 1002 +#define IDC_STAS 1003 +#define IDC_INSERT_SPACES 1003 +#define IDC_DESC 1003 +#define IDC_MARKO 1004 +#define IDC_TAB_SIZE 1004 +#define IDC_TIPSTRING 1004 +#define IDC_ADOLF 1005 +#define IDC_NAME 1005 +#define IDC_SHOW_TABS 1005 +#define IDC_NUMBER 1005 +#define IDC_FRANKY 1006 +#define IDC_URL_PROMPT 1006 +#define IDC_AUTOINDENT 1006 +#define IDC_TEXT 1006 +#define IDC_URL 1007 +#define IDC_BACKSP_AT_BOL 1007 +#define IDC_ENCODING 1007 +#define IDC_SELOM 1008 +#define IDC_SEL_MARGIN 1008 +#define IDC_FORMAT 1008 +#define IDC_NONE 1009 +#define IDC_ASP 1010 +#define IDC_HANS 1010 +#define IDC_BASIC 1011 +#define IDC_MICHAEL 1011 +#define IDC_BATCH 1012 +#define IDC_ROBERTO 1012 +#define IDC_C 1013 +#define IDC_AUTODCL 1014 +#define IDC_ROBERTO2 1013 +#define IDC_JOSH 1013 +#define IDC_FORTRAN 1015 +#define IDC_EXTENSIONS 1014 +#define IDC_JAN 1014 +#define IDC_HTML 1016 +#define IDC_PAUL 1015 +#define IDC_INSTALLSHIELD 1017 +#define IDC_CRISTI 1017 +#define IDC_JAVA 1018 +#define IDC_AUTOLISP 1019 +#define IDC_WITOLD 1018 +#define IDC_MFCCODEGURU 1019 +#define IDC_PASCAL 1020 +#define IDC_PERL 1021 +#define IDC_PHP 1022 +#define IDC_PYTHON 1023 +#define IDC_RSRC 1024 +#define IDC_REXX 1025 +#define IDC_BIGICON 1023 +#define IDC_SGML 1026 +#define IDC_SH 1027 +#define IDC_SIOD 1028 +#define IDC_SQL 1029 +#define IDC_TCL 1030 +#define IDC_TEX 1031 +#define IDC_SELECT_ALL 1032 +#define IDC_UNSELECT_ALL 1033 +#define IDC_BRACES_NO 1032 +#define IDC_BRACES_ANSI 1033 +#define IDC_BRACES_GNU 1034 +#define IDC_EOLN_AUTO 1035 +#define IDC_EOLN_DOS 1036 +#define IDC_EOLN_UNIX 1037 +#define IDC_EOLN_MAC 1038 +#define IDC_FNBRACE 1039 +#define IDC_WORDWRAP 1040 +#define IDC_MORE 1041 +#define IDC_EDITPAGE1 1042 +#define IDC_SRC 1043 +#define IDC_ALPHA_ONLY 1044 +#define IDC_PREVIEW 1045 +#define IDC_RECODE 1046 +#define stc32 0x045f +#define IDD_EDIT_FIND 8601 +#define IDD_EDIT_REPLACE 8602 +#define IDC_EDIT_WHOLE_WORD 8603 +#define IDD_EDIT_GOTO 8603 +#define IDC_EDIT_MATCH_CASE 8604 +#define IDD_EDIT_CHARCONV 8604 +#define IDC_EDIT_TEXT 8605 +#define IDD_EDITOR_PAGE1 8605 +#define IDC_EDIT_REGEXP 8606 +#define IDS_EDIT_TEXT_NOT_FOUND 8606 +#define IDD_EDITOR_PAGE2 8606 +#define IDC_DEST 8606 +#define IDC_EDIT_REPLACE 8607 +#define IDD_EDFILEADD 8607 +#define IDC_EDIT_REPLACE_ALL 8608 +#define IDD_EDITOR_PAGE3 8608 +#define IDC_EDIT_REPLACE_WITH 8609 +#define IDC_EDIT_SKIP 8610 +#define IDC_EDIT_DIRECTION_UP 8611 +#define IDC_EDIT_DIRECTION_DOWN 8612 +#define IDC_EDIT_SCOPE_SELECTION 8613 +#define IDC_EDIT_SCOPE_WHOLE_FILE 8614 +#define IDS_MENU_UNDO_FORMAT 8615 +#define IDS_MENU_REDO_FORMAT 8616 +#define IDS_MENU_UNDO_DEFAULT 8617 +#define IDS_MENU_REDO_DEFAULT 8618 +#define IDS_EDITOP_UNKNOWN 8619 +#define IDS_EDITOP_PASTE 8620 +#define IDS_EDITOP_DELSELECTION 8621 +#define IDS_EDITOP_CUT 8622 +#define IDS_EDITOP_DELETE 8623 +#define IDS_EDITOP_TYPING 8624 +#define IDS_EDITOP_BACKSPACE 8625 +#define IDS_EDITOP_INDENT 8626 +#define IDS_EDITOP_DRAGDROP 8627 +#define IDS_EDITOP_REPLACE 8628 +#define IDS_EDITOP_AUTOINDENT 8629 +#define IDS_EDITOP_AUTOCOMPLETE 8630 +#define IDS_EDITOP_AUTOEXPAND 8631 +#define IDS_EDITOP_LOWERCASE 8632 +#define IDS_EDITOP_UPPERCASE 8633 +#define IDS_EDITOP_SWAPCASE 8634 +#define IDS_EDITOP_CAPITALIZE 8635 +#define IDS_EDITOP_SENTENCIZE 8636 +#define IDS_EDITOP_RECODE 8637 +#define IDS_EDITOP_SPELL 8638 +#define IDS_FIND_INCREMENTAL_FORWARD 8640 +#define IDS_FIND_INCREMENTAL_BACKWARD 8641 +#define IDS_FIND_INCREMENTAL_FAILED 8642 +#define IDS_SHEET_OPTIONS 8700 +#define IDR_MARGIN_CURSOR 22900 +#define IDR_DEFAULT_ACCEL 22901 +#define IDR_MARGIN_ICONS 22902 +#define IDR_RTF_ACCEL 22903 +#define ID_EDIT_DELETE_WORD 32771 +#define ID_POPUP_EDIT 32774 +#define ID_POPUP_PRINT 32775 +#define ID_POPUP_OPEN 32780 +#define ID_POPUP_COPYSHORTCUT 32781 +#define ID_POPUP_ADDTOFAVORITES 32782 +#define ID_POPUP_ADDTODESKTOP 32783 +#define ID_POPUP_PROPERTIES 32784 +#define ID_VIEW_FULL_SCREEN 32791 +#define ID_CHAR_BOLD 32799 +#define ID_TOOLS_SPELLING 32800 +#define ID_TOOLS_SPELLING_SET 32801 +#define ID_CHAR_ITALIC 32802 +#define ID_TOOLS_CHARCODING 32803 +#define ID_CHAR_UNDERLINE 32804 +#define ID_PARA_LEFT 32805 +#define ID_PARA_CENTER 32806 +#define ID_PARA_RIGHT 32807 +#define ID_FILE_RELOAD 36999 +#define ID_EDIT_FIRST 37000 +#define ID_EDIT_DELETE 37000 +#define ID_EDIT_DELETE_BACK 37001 +#define ID_EDIT_DELETE_WORD_BACK 37002 +#define ID_EDIT_TAB 37003 +#define ID_EDIT_UNTAB 37004 +#define ID_EDIT_SWITCH_OVRMODE 37005 +#define ID_EDIT_CHAR_LEFT 37100 +#define ID_EDIT_EXT_CHAR_LEFT 37101 +#define ID_EDIT_CHAR_RIGHT 37102 +#define ID_EDIT_EXT_CHAR_RIGHT 37103 +#define ID_EDIT_WORD_LEFT 37104 +#define ID_EDIT_EXT_WORD_LEFT 37105 +#define ID_EDIT_WORD_RIGHT 37106 +#define ID_EDIT_EXT_WORD_RIGHT 37107 +#define ID_EDIT_LINE_UP 37108 +#define ID_EDIT_EXT_LINE_UP 37109 +#define ID_EDIT_LINE_DOWN 37110 +#define ID_EDIT_EXT_LINE_DOWN 37111 +#define ID_EDIT_SCROLL_UP 37112 +#define ID_EDIT_SCROLL_DOWN 37113 +#define ID_EDIT_PAGE_UP 37114 +#define ID_EDIT_EXT_PAGE_UP 37115 +#define ID_EDIT_PAGE_DOWN 37116 +#define ID_EDIT_EXT_PAGE_DOWN 37117 +#define ID_EDIT_LINE_END 37118 +#define ID_EDIT_EXT_LINE_END 37119 +#define ID_EDIT_HOME 37120 +#define ID_EDIT_EXT_HOME 37121 +#define ID_EDIT_TEXT_BEGIN 37122 +#define ID_EDIT_EXT_TEXT_BEGIN 37123 +#define ID_EDIT_TEXT_END 37124 +#define ID_EDIT_EXT_TEXT_END 37125 +#define ID_EDIT_FIND_PREVIOUS 37126 +#define ID_EDIT_TOGGLE_BOOKMARK0 37200 +#define ID_EDIT_TOGGLE_BOOKMARK1 37201 +#define ID_EDIT_TOGGLE_BOOKMARK2 37202 +#define ID_EDIT_TOGGLE_BOOKMARK3 37203 +#define ID_EDIT_TOGGLE_BOOKMARK4 37204 +#define ID_EDIT_TOGGLE_BOOKMARK5 37205 +#define ID_EDIT_TOGGLE_BOOKMARK6 37206 +#define ID_EDIT_TOGGLE_BOOKMARK7 37207 +#define ID_EDIT_TOGGLE_BOOKMARK8 37208 +#define ID_EDIT_TOGGLE_BOOKMARK9 37209 +#define ID_EDIT_GO_BOOKMARK0 37210 +#define ID_EDIT_GO_BOOKMARK1 37211 +#define ID_EDIT_GO_BOOKMARK2 37212 +#define ID_EDIT_GO_BOOKMARK3 37213 +#define ID_EDIT_GO_BOOKMARK4 37214 +#define ID_EDIT_GO_BOOKMARK5 37215 +#define ID_EDIT_GO_BOOKMARK6 37216 +#define ID_EDIT_GO_BOOKMARK7 37217 +#define ID_EDIT_GO_BOOKMARK8 37218 +#define ID_EDIT_GO_BOOKMARK9 37219 +#define ID_EDIT_CLEAR_BOOKMARKS 37220 +#define ID_EDIT_SET_BREAKPOINT 37221 +#define ID_EDIT_ENABLE_BREAKPOINT 37222 +#define ID_EDIT_TOGGLE_BOOKMARK 37223 +#define ID_EDIT_GOTO_NEXT_BOOKMARK 37224 +#define ID_EDIT_GOTO_PREV_BOOKMARK 37225 +#define ID_EDIT_CLEAR_ALL_BOOKMARKS 37226 +#define ID_EDIT_GOTO_LAST_CHANGE 37227 +#define ID_EDIT_FIND_INCREMENTAL_FORWARD 37228 +#define ID_EDIT_FIND_INCREMENTAL_BACKWARD 37229 +#define ID_EDIT_AUTOCOMPLETE 37300 +#define ID_EDIT_AUTOEXPAND 37301 +#define ID_EDIT_MATCHBRACE 37302 +#define ID_EDIT_LOWERCASE 37303 +#define ID_EDIT_UPPERCASE 37304 +#define ID_EDIT_CAPITALIZE 37305 +#define ID_EDIT_SENTENCE 37306 +#define ID_EDIT_SWAPCASE 37307 +#define ID_EDIT_GOTO 37308 +#define ID_VIEW_OPTIONS 37400 +#define ID_VIEW_TOGGLE_SRC_HDR 37401 +#define ID_VIEW_SELMARGIN 37402 +#define ID_DATE_TIME 37403 +#define ID_VIEW_WORDWRAP 37404 +#define ID_READ_ONLY 37405 +#define ID_SOURCE_PLAIN 37500 +#define ID_SOURCE_ASP 37501 +#define ID_SOURCE_BASIC 37502 +#define ID_SOURCE_BATCH 37503 +#define ID_SOURCE_C 37504 +#define ID_SOURCE_AUTODCL 37505 +#define ID_SOURCE_FORTRAN 37506 +#define ID_SOURCE_HTML 37507 +#define ID_SOURCE_INSTALLSHIELD 37508 +#define ID_SOURCE_JAVA 37509 +#define ID_SOURCE_AUTOLISP 37510 +#define ID_SOURCE_PASCAL 37511 +#define ID_SOURCE_PERL 37512 +#define ID_SOURCE_PHP 37513 +#define ID_SOURCE_PYTHON 37514 +#define ID_SOURCE_REXX 37515 +#define ID_SOURCE_RSRC 37516 +#define ID_SOURCE_SGML 37517 +#define ID_SOURCE_SH 37518 +#define ID_SOURCE_SIOD 37519 +#define ID_SOURCE_SQL 37520 +#define ID_SOURCE_TCL 37521 +#define ID_SOURCE_TEX 37522 +#define ID_EDIT_INDICATOR_READ 37901 +#define ID_EDIT_INDICATOR_CRLF 37902 +#define ID_EDIT_INDICATOR_POSITION 37903 +#define ID_INDICATOR_TIME 37904 +#define ID_FORCE_REDRAW 37999 +#define ID_EDIT_LAST 37999 +#define ID_HELP_TIPOFTHEDAY 39000 +#define ID_FORMAT_SHOW_ADDRESS 40001 +#define ID_FORMAT_SHOW_HEX 40002 +#define ID_FORMAT_SHOW_ASCII 40003 +#define ID_FORMAT_WIDE_ADDRESS 40004 +#define ID_FORMAT_BPR_FIRST 40011 +#define ID_FORMAT_BPR_1 40011 +#define ID_FORMAT_BPR_2 40012 +#define ID_FORMAT_BPR_3 40013 +#define ID_FORMAT_BPR_4 40014 +#define ID_FORMAT_BPR_5 40015 +#define ID_FORMAT_BPR_6 40016 +#define ID_FORMAT_BPR_7 40017 +#define ID_FORMAT_BPR_8 40018 +#define ID_FORMAT_BPR_9 40019 +#define ID_FORMAT_BPR_10 40020 +#define ID_FORMAT_BPR_11 40021 +#define ID_FORMAT_BPR_12 40022 +#define ID_FORMAT_BPR_13 40023 +#define ID_FORMAT_BPR_14 40024 +#define ID_FORMAT_BPR_15 40025 +#define ID_FORMAT_BPR_16 40026 +#define ID_FORMAT_BPR_LAST 40026 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 1002 +#define _APS_NEXT_COMMAND_VALUE 32772 +#define _APS_NEXT_CONTROL_VALUE 1049 +#define _APS_NEXT_SYMED_VALUE 1000 +#endif +#endif diff --git a/Src/editlib/editreg.h b/Src/editlib/editreg.h new file mode 100644 index 000000000..95e85dbc3 --- /dev/null +++ b/Src/editlib/editreg.h @@ -0,0 +1,38 @@ +//////////////////////////////////////////////////////////////////////////// +// File: editcmd.h +// Version: 1.2.0.5 +// Created: 29-Dec-1998 +// +// Author: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Registry keys and values for Crystal Edit - syntax colorig text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 16-Aug-99 +// Ferdinand Prantl: +// + FEATURE: see cpps ... +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#ifndef __EDITREG_H__INCLUDED__ +#define __EDITREG_H__INCLUDED__ + +// Registry keys & values +#define REG_EDITPAD _T ("Software\\EditPad") +#define REG_EDITPAD_MULTI _T ("Software\\EditPad\\Multi") +#define REG_EDITPAD_SINGLE _T ("Software\\EditPad\\Single") +#define REG_EDITPAD_IDE _T ("Software\\EditPad\\IDE") +#define REG_EDITPAD_VERSION 0x0108000d +#define MAX_REMEMBERED 100 +#define REMEMBERED_TO_REMOVE 10 + +#endif // __EDITREG_H__INCLUDED__ diff --git a/Src/editlib/edtlib.cpp b/Src/editlib/edtlib.cpp new file mode 100644 index 000000000..196a3b788 --- /dev/null +++ b/Src/editlib/edtlib.cpp @@ -0,0 +1,57 @@ +// edtlib.cpp : Defines the initialization routines for the DLL. +// + +#include "stdafx.h" +#include "ccrystaltextview.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +HINSTANCE g_hDllInstance; + +static AFX_EXTENSION_MODULE EditpadcDLL = { NULL, NULL }; + +extern "C" int APIENTRY +DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + // Remove this if you use lpReserved + UNREFERENCED_PARAMETER(lpReserved); + + CCrystalTextView::s_hResourceInst = hInstance; + + if (dwReason == DLL_PROCESS_ATTACH) + { + TRACE0("EDITPADC.DLL Initializing!\n"); + + g_hDllInstance = hInstance; + + // Extension DLL one-time initialization + if (!AfxInitExtensionModule(EditpadcDLL, hInstance)) + return 0; + + // Insert this DLL into the resource chain + // NOTE: If this Extension DLL is being implicitly linked to by + // an MFC Regular DLL (such as an ActiveX Control) + // instead of an MFC application, then you will want to + // remove this line from DllMain and put it in a separate + // function exported from this Extension DLL. The Regular DLL + // that uses this Extension DLL should then explicitly call that + // function to initialize this Extension DLL. Otherwise, + // the CDynLinkLibrary object will not be attached to the + // Regular DLL's resource chain, and serious problems will + // result. + + new CDynLinkLibrary(EditpadcDLL); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + TRACE0("EDITPADC.DLL Terminating!\n"); + // Terminate the library before destructors are called + AfxTermExtensionModule(EditpadcDLL); + } + return 1; // ok +} diff --git a/Src/editlib/edtlib.h b/Src/editlib/edtlib.h new file mode 100644 index 000000000..d1b1aa4b8 --- /dev/null +++ b/Src/editlib/edtlib.h @@ -0,0 +1,16 @@ +#ifndef __EDTLIB_H +#define __EDTLIB_H + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + + + +#include "crystalparser.h" +#include "ccrystaltextbuffer.h" +#include "ccrystaltextview.h" +#include "ccrystaleditview.h" +#include "crystaleditviewex.h" + +#endif // __EDTLIB_H diff --git a/Src/editlib/filesup.cpp b/Src/editlib/filesup.cpp new file mode 100644 index 000000000..1c1603896 --- /dev/null +++ b/Src/editlib/filesup.cpp @@ -0,0 +1,119 @@ +/////////////////////////////////////////////////////////////////////////// +// File: filesup.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Some handy stuff to deal with files and their names +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "filesup.h" + +#ifdef _DEBUG +#include "filesup.inl" +#endif // _DEBUG + +#ifdef INLINE +#undef INLINE +#endif +#define INLINE + +//////////////////////////////////////////////////////////////////////////////// + +bool FileExist(LPCTSTR lpszPath) +{ + CFileStatus status; + return CFile::GetStatus(lpszPath, status) != 0; +} + +INLINE int +GetExtPosition (LPCTSTR pszString) +{ + if (!pszString || !*pszString) + return 0; + const CString sString = pszString; + int len = sString.GetLength (), posit = len; + TCHAR test; + do + if ((test = sString.GetAt (--posit)) == _T ('.')) + return posit; + while (posit && test != _T ('\\') && test != _T (':')); + return len; +} + +INLINE CString +GetExt (CString sString) +{ + if (!sString.IsEmpty ()) + { + sString = sString.Mid (GetExtPosition (sString)); + if (!sString.IsEmpty () && sString[0] == _T ('.')) + { + sString = sString.Mid (1); + } + } + return sString; +} + +INLINE CString +GetName (const CString & sString) +{ + int nPosition = GetNamePosition (sString), nPosition2 = GetExtPosition (sString); + + return sString.IsEmpty ()? sString : (nPosition2 == sString.GetLength ()? sString.Mid (nPosition) : sString.Mid (nPosition, nPosition2 - nPosition)); +} + +INLINE CString +GetNameExt (const CString & sString) +{ + return sString.IsEmpty ()? sString : sString.Mid (GetNamePosition (sString)); +} + +INLINE int +GetNamePosition (LPCTSTR pszString) +{ + if (!pszString || !*pszString) + return 0; + const CString sString = pszString; + int posit = sString.GetLength (); + TCHAR test; + do + if ((test = sString.GetAt (--posit)) == _T ('\\') || test == _T (':')) + return posit + 1; + while (posit); + return posit; +} + +INLINE CString +GetPath (const CString & sString, BOOL bClose /*= FALSE*/ ) +{ + if (sString.IsEmpty ()) + return sString; + int posit = GetNamePosition (sString); + if (posit == 0) + return bClose ? _T (".\\") : _T ("."); + + TCHAR test = sString.GetAt (posit - 1); + + if (test == _T (':') || test == _T ('\\') && (posit == 1 || posit != 1 && sString.GetAt (posit - 2) == _T (':'))) + return sString.Left (posit); + return sString.Left (bClose ? posit : test == _T (':') ? posit : posit - 1); +} + +INLINE CString +GetPathName (const CString & sString) +{ + int nPosition = GetExtPosition (sString); + + return sString.IsEmpty ()? sString : (nPosition == sString.GetLength ()? sString : sString.Left (nPosition)); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/Src/editlib/filesup.h b/Src/editlib/filesup.h new file mode 100644 index 000000000..6f562937e --- /dev/null +++ b/Src/editlib/filesup.h @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////// +// File: filesup.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Some handy stuff to deal with files and their names +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __FILESUP_H__INCLUDED__ +#define __FILESUP_H__INCLUDED__ + +///////////////////////////////////////////////////////////////////////////// + +bool EDITPADC_CLASS FileExist(LPCTSTR lpszPath); +int EDITPADC_CLASS GetExtPosition (LPCTSTR pszString); +CString EDITPADC_CLASS GetExt (CString sString); +CString EDITPADC_CLASS GetName (const CString & sString); +CString EDITPADC_CLASS GetNameExt (const CString & sString); +int EDITPADC_CLASS GetNamePosition (LPCTSTR pszString); +CString EDITPADC_CLASS GetPath (const CString & sString, BOOL bClose = FALSE); +CString EDITPADC_CLASS GetPathName (const CString & sString); + +///////////////////////////////////////////////////////////////////////////// + +#ifndef _DEBUG +#include "filesup.inl" +#endif // _DEBUG + +///////////////////////////////////////////////////////////////////////////// + +#endif // __FILESUP_H__INCLUDED__ diff --git a/Src/editlib/filesup.inl b/Src/editlib/filesup.inl new file mode 100644 index 000000000..203319363 --- /dev/null +++ b/Src/editlib/filesup.inl @@ -0,0 +1,36 @@ +/////////////////////////////////////////////////////////////////////////// +// File: filesup.inl +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Some handy stuff to deal with files and their names +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __FILESUP_INL__INCLUDED__ +#define __FILESUP_INL__INCLUDED__ + +//////////////////////////////////////////////////////////////////////////////// + +#ifdef INLINE +#undef INLINE +#endif + +#ifndef _DEBUG +#define INLINE inline +#else +#define INLINE +#endif // _DEBUG + +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// + +#endif // __FILESUP_INL__INCLUDED__ diff --git a/Src/editlib/fortran.cpp b/Src/editlib/fortran.cpp new file mode 100644 index 000000000..58aac67c1 --- /dev/null +++ b/Src/editlib/fortran.cpp @@ -0,0 +1,449 @@ +/////////////////////////////////////////////////////////////////////////// +// File: fortran.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// FORTRAN syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszFortranKeywordList[] = + { + _T ("abs"), + _T ("achar"), + _T ("acos"), + _T ("adjustl"), + _T ("adjustr"), + _T ("aimag"), + _T ("aint"), + _T ("all"), + _T ("allocatable"), + _T ("allocate"), + _T ("allocated"), + _T (".and."), + _T ("anint"), + _T ("any"), + _T ("asin"), + _T ("assignment"), + _T ("associated"), + _T ("atan"), + _T ("atan2"), + _T ("backspace"), + _T ("bit_size"), + _T ("block"), + _T ("blockdata"), + _T ("btest"), + _T ("call"), + _T ("random_number"), + _T ("random_seed"), + _T ("system_clock"), + _T ("call"), + _T ("case"), + _T ("ceiling"), + _T ("char"), + _T ("character"), + _T ("close"), + _T ("cmplx"), + _T ("common"), + _T ("complex"), + _T ("conjg"), + _T ("contains"), + _T ("continue"), + _T ("cos"), + _T ("cosh"), + _T ("count"), + _T ("cshift"), + _T ("cycle"), + _T ("data"), + _T ("date_and_time"), + _T ("dble"), + _T ("deallocate"), + _T ("default"), + _T ("digits"), + _T ("dim"), + _T ("dimension"), + _T ("do"), + _T ("dot_product"), + _T ("double"), + _T ("doubleprecision"), + _T ("dprod"), + _T ("else"), + _T ("elseif"), + _T ("elsewhere"), + _T ("end"), + _T ("endblock"), + _T ("endblockdata"), + _T ("enddo"), + _T ("endfile"), + _T ("endif"), + _T ("endinterface"), + _T ("endselect"), + _T ("endtype"), + _T ("endwhere"), + _T ("entry"), + _T ("eoshift"), + _T ("epsilon"), + _T ("equivalence"), + _T ("exit"), + _T ("exp"), + _T ("exponent"), + _T ("external"), + _T ("file"), + _T ("floor"), + _T ("format."), + _T ("fraction"), + _T ("function"), + _T ("go"), + _T ("goto"), + _T ("huge"), + _T ("iachar"), + _T ("iand"), + _T ("ibclr"), + _T ("ibits"), + _T ("ibset"), + _T ("ichar"), + _T ("ieor"), + _T ("if"), + _T ("implicit"), + _T ("in"), + _T ("index"), + _T ("inout"), + _T ("inquire"), + _T ("int"), + _T ("integer"), + _T ("intent"), + _T ("interface"), + _T ("intrinsic"), + _T ("iolength"), + _T ("ior"), + _T ("ishftc"), + _T ("ishift"), + _T ("kind"), + _T ("lbound"), + _T ("len"), + _T ("len_trim"), + _T ("lge"), + _T ("lgt"), + _T ("lle"), + _T ("llt"), + _T ("log"), + _T ("log10"), + _T ("logical"), + _T ("matmul"), + _T ("max"), + _T ("maxexponent"), + _T ("maxloc"), + _T ("maxval"), + _T ("merge"), + _T ("min"), + _T ("minexponent"), + _T ("minloc"), + _T ("minval"), + _T ("mod"), + _T ("module"), + _T ("modulo"), + _T ("mvbits"), + _T ("namelist"), + _T ("nearest"), + _T ("nint"), + _T ("none"), + _T (".not."), + _T ("nullify"), + _T ("only"), + _T ("open"), + _T ("operator"), + _T ("optional"), + _T (".or."), + _T ("out"), + _T ("pack"), + _T ("parameter"), + _T ("pointer"), + _T ("precision"), + _T ("present"), + _T ("print"), + _T ("private"), + _T ("procedure"), + _T ("product"), + _T ("program"), + _T ("public"), + _T ("radix"), + _T ("rangereal"), + _T ("read"), + _T ("real"), + _T ("recursive"), + _T ("repeat"), + _T ("reshape"), + _T ("result"), + _T ("return"), + _T ("rewrind"), + _T ("rrspacing"), + _T ("save"), + _T ("scale"), + _T ("scan"), + _T ("select"), + _T ("selectcase"), + _T ("selected_int_kind"), + _T ("selected_real_kind"), + _T ("sequence"), + _T ("set_exponent"), + _T ("shape"), + _T ("sign"), + _T ("sin"), + _T ("sinh"), + _T ("size"), + _T ("spacing"), + _T ("spread"), + _T ("sqrt"), + _T ("stop"), + _T ("subroutine"), + _T ("sum"), + _T ("tan"), + _T ("tanh"), + _T ("target"), + _T ("then"), + _T ("tiny"), + _T ("to"), + _T ("transfer"), + _T ("transpose"), + _T ("trim"), + _T ("type"), + _T ("unbound"), + _T ("unpack"), + _T ("use"), + _T ("verify"), + _T ("where"), + _T ("while"), + _T ("write"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsFortranKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszFortranKeywordList, pszChars, nLength); +} + +static BOOL +IsFortranNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineFortran (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '!' || !I && (pszChars[I] == 'C' || pszChars[I] == 'c')) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsFortranNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsFortranNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/fpattern.cpp b/Src/editlib/fpattern.cpp new file mode 100644 index 000000000..a9f99572a --- /dev/null +++ b/Src/editlib/fpattern.cpp @@ -0,0 +1,402 @@ +/////////////////////////////////////////////////////////////////////////// +// File: fpattern.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl (I'm sorry, author unknown ...) +// E-mail: prantl@ff.cuni.cz +// +// File-like string pattern matching routines +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "fpattern.h" + +#if TEST +#define SUB _T('~') +#else +#define SUB FPAT_CLOSP +#endif + +#ifndef DELIM +#define DELIM 0 +#endif + +#define DEL FPAT_DEL + +#ifdef __UNIX__ +#define DEL2 FPAT_DEL +#define QUOTE FPAT_QUOTE +#define lowercase( c ) ( c ) +#else +#define DEL2 FPAT_DEL2 +#define QUOTE FPAT_QUOTE2 +#define lowercase( c ) _totlower( c ) +#endif + +/*----------------------------------------------------------------------------- + * fpattern_isvalid() + * Checks that filename pattern 'pat' is a well-formed pattern. + * + * Returns + * 1 ( true ) if 'pat' is a valid filename pattern, otherwise 0 ( false ). + * + * Caveats + * If 'pat' is null, 0 ( false ) is returned. + * + * If 'pat' is empty ( "" ), 1 ( true ) is returned, and it is considered a + * valid ( but degenerate ) pattern ( the only filename it matches is the + * empty ( "" ) string ). + */ + +int +fpattern_isvalid (LPCTSTR pat) +{ + int len; + + /* Check args */ + if (pat == NULL) + return (FALSE); + + /* Verify that the pattern is valid */ + for (len = 0; pat[len] != _T('\0'); len++) + { + switch (pat[len]) + { + case FPAT_SET_L: + /* Char set */ + len++; + if (pat[len] == FPAT_SET_NOT) + len++; /* Set negation */ + + while (pat[len] != FPAT_SET_R) + { + if (pat[len] == QUOTE) + len++; /* Quoted char */ + if (pat[len] == _T('\0')) + return (FALSE); /* Missing closing bracket */ + len++; + + if (pat[len] == FPAT_SET_THRU) + { + /* Char range */ + len++; + if (pat[len] == QUOTE) + len++; /* Quoted char */ + if (pat[len] == _T('\0')) + return (FALSE); /* Missing closing bracket */ + len++; + } + + if (pat[len] == _T('\0')) + return (FALSE); /* Missing closing bracket */ + } + break; + + case QUOTE: + /* Quoted char */ + len++; + if (pat[len] == _T('\0')) + return (FALSE); /* Missing quoted char */ + break; + + case FPAT_NOT: + /* Negated pattern */ + len++; + if (pat[len] == _T('\0')) + return (FALSE); /* Missing subpattern */ + break; + + default: + /* Valid character */ + break; + } + } + + return (TRUE); +} + + +/*----------------------------------------------------------------------------- + * fpattern_submatch() + * Attempts to match subpattern 'pat' to subfilename 'fname'. + * + * Returns + * 1 ( true ) if the subfilename matches, otherwise 0 ( false ). + * + * Caveats + * This does not assume that 'pat' is well-formed. + * + * If 'pat' is empty ( "" ), the only filename it matches is the empty ( "" ) + * string. + * + * Some non-empty patterns ( e.g., "" ) will match an empty filename ( "" ). + */ + +static int +fpattern_submatch (LPCTSTR pat, LPCTSTR fname) +{ + int fch; + int pch; + int i; + int yes, match; + int lo, hi; + + /* Attempt to match subpattern against subfilename */ + while (*pat != _T('\0')) + { + fch = *fname; + pch = *pat; + pat++; + + switch (pch) + { + case FPAT_ANY: + /* Match a single char */ +#if DELIM + if (fch == DEL || fch == DEL2 || fch == _T('\0')) + return (FALSE); +#else + if (fch == _T('\0')) + return (FALSE); +#endif + fname++; + break; + + case FPAT_CLOS: + /* Match zero or more chars */ + i = 0; +#if DELIM + while (fname[i] != _T('\0') && + fname[i] != DEL && fname[i] != DEL2) + i++; +#else + while (fname[i] != _T('\0')) + i++; +#endif + while (i >= 0) + { + if (fpattern_submatch (pat, fname + i)) + return (TRUE); + i--; + } + return (FALSE); + + case SUB: + /* Match zero or more chars */ + i = 0; + while (fname[i] != _T('\0') && +#if DELIM + fname[i] != DEL && fname[i] != DEL2 && +#endif + fname[i] != _T('.')) + i++; + while (i >= 0) + { + if (fpattern_submatch (pat, fname + i)) + return (TRUE); + i--; + } + return (FALSE); + + case QUOTE: + /* Match a quoted char */ + pch = *pat; + if (lowercase (fch) != lowercase (pch) || pch == _T('\0')) + return (FALSE); + fname++; + pat++; + break; + + case FPAT_SET_L: + /* Match char set/range */ + yes = TRUE; + if (*pat == FPAT_SET_NOT) + { + pat++; + yes = FALSE; /* Set negation */ + } + + /* Look for [ s ], [ - ], [ abc ], [ a-c ] */ + match = !yes; + while (*pat != FPAT_SET_R && *pat != _T('\0')) + { + if (*pat == QUOTE) + pat++; /* Quoted char */ + + if (*pat == _T('\0')) + break; + lo = *pat++; + hi = lo; + + if (*pat == FPAT_SET_THRU) + { + /* Range */ + pat++; + + if (*pat == QUOTE) + pat++; /* Quoted char */ + + if (*pat == _T('\0')) + break; + hi = *pat++; + } + + if (*pat == _T('\0')) + break; + + /* Compare character to set range */ + if (lowercase (fch) >= lowercase (lo) && + lowercase (fch) <= lowercase (hi)) + match = yes; + } + + if (!match) + return (FALSE); + + if (*pat == _T('\0')) + return (FALSE); /* Missing closing bracket */ + + fname++; + pat++; + break; + + case FPAT_NOT: + /* Match only if rest of pattern does not match */ + if (*pat == _T('\0')) + return (FALSE); /* Missing subpattern */ + i = fpattern_submatch (pat, fname); + return !i; + +#if DELIM + case DEL: +#if DEL2 != DEL + case DEL2: +#endif + /* Match path delimiter char */ + if (fch != DEL && fch != DEL2) + return (FALSE); + fname++; + break; +#endif + + default: + /* Match a ( non-null ) char exactly */ + if (lowercase (fch) != lowercase (pch)) + return (FALSE); + fname++; + break; + } + } + + /* Check for complete match */ + if (*fname != _T('\0')) + return (FALSE); + + /* Successful match */ + return (TRUE); +} + + +/*----------------------------------------------------------------------------- + * fpattern_match() + * Attempts to match pattern 'pat' to filename 'fname'. + * + * Returns + * 1 ( true ) if the filename matches, otherwise 0 ( false ). + * + * Caveats + * If 'fname' is null, zero ( false ) is returned. + * + * If 'pat' is null, zero ( false ) is returned. + * + * If 'pat' is empty ( "" ), the only filename it matches is the empty + * string ( "" ). + * + * If 'fname' is empty, the only pattern that will match it is the empty + * string ( "" ). + * + * If 'pat' is not a well-formed pattern, zero ( false ) is returned. + * + * Upper and lower case letters are treated the same ; alphabetic + * characters are converted to lower case before matching occurs. + * Conversion to lower case is dependent upon the current locale setting. + */ + +int +fpattern_match (LPCTSTR pat, LPCTSTR fname) +{ + int rc; + + /* Check args */ + if (fname == NULL) + return (FALSE); + + if (pat == NULL) + return (FALSE); + + /* Verify that the pattern is valid, and get its length */ + if (!fpattern_isvalid (pat)) + return (FALSE); + + /* Attempt to match pattern against filename */ + if (fname[0] == _T('\0')) + return (pat[0] == _T('\0')); /* Special case */ + rc = fpattern_submatch (pat, fname); + + return (rc); +} + + +/*----------------------------------------------------------------------------- + * fpattern_matchn() + * Attempts to match pattern 'pat' to filename 'fname'. + * This operates like fpattern_match() except that it does not verify that + * pattern 'pat' is well-formed, assuming that it has been checked by a + * prior call to fpattern_isvalid(). + * + * Returns + * 1 ( true ) if the filename matches, otherwise 0 ( false ). + * + * Caveats + * If 'fname' is null, zero ( false ) is returned. + * + * If 'pat' is null, zero ( false ) is returned. + * + * If 'pat' is empty ( "" ), the only filename it matches is the empty ( "" ) + * string. + * + * If 'pat' is not a well-formed pattern, unpredictable results may occur. + * + * Upper and lower case letters are treated the same ; alphabetic + * characters are converted to lower case before matching occurs. + * Conversion to lower case is dependent upon the current locale setting. + * + * See also + * fpattern_match(). + */ + +int +fpattern_matchn (LPCTSTR pat, LPCTSTR fname) +{ + int rc; + + /* Check args */ + if (fname == NULL) + return (FALSE); + + if (pat == NULL) + return (FALSE); + + /* Assume that pattern is well-formed */ + + /* Attempt to match pattern against filename */ + rc = fpattern_submatch (pat, fname); + + return (rc); +} diff --git a/Src/editlib/fpattern.h b/Src/editlib/fpattern.h new file mode 100644 index 000000000..310426da5 --- /dev/null +++ b/Src/editlib/fpattern.h @@ -0,0 +1,148 @@ +/////////////////////////////////////////////////////////////////////////// +// File: fpattern.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl (I'm sorry, author unknown ...) +// E-mail: prantl@ff.cuni.cz +// +// File-like string pattern matching routines +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __FPATTERN_H__INCLUDED__ +#define __FPATTERN_H__INCLUDED__ + +/****************************************************************************** + * fpattern.h + * Functions for matching filename patterns to filenames. + * + * Usage + * Filename patterns are composed of regular (printable) characters which + * may comprise a filename as well as special pattern matching characters: + * + * . Matches a period (.). + * Note that a period in a filename is not treated any + * differently than any other character. + * + * ? Any. + * Matches any single character except '/' or '\'. + * + * * Closure. + * Matches zero or more occurences of any characters other + * than '/' or '\'. + * Leading '*' characters are allowed. + * + * SUB Substitute (^Z). + * Similar to '*', this matches zero or more occurences of + * any characters other than '/', '\', or '.'. + * Leading '^Z' characters are allowed. + * + * [ab] Set. + * Matches the single character 'a' or 'b'. + * If the dash '-' character is to be included, it must + * immediately follow the opening bracket '['. + * If the closing bracket ']' character is to be included, + * it must be preceded by a quote '`'. + * + * [a-z] Range. + * Matches a single character in the range 'a' to 'z'. + * Ranges and sets may be combined within the same set of + * brackets. + * + * [!R] Exclusive range. + * Matches a single character not in the range 'R'. + * If range 'R' includes the dash '-' character, the dash + * must immediately follow the caret '!'. + * + * ! Not. + * Makes the following pattern (up to the next '/') match + * any filename except those what it would normally match. + * + * / Path separator (UNIX and DOS). + * Matches a '/' or '\' pathname (directory) separator. + * Multiple separators are treated like a single + * separator. + * A leading separator indicates an absolute pathname. + * + * \ Path separator (DOS). + * Same as the '/' character. + * Note that this character must be escaped if used within + * string constants ("\\"). + * + * \ Quote (UNIX). + * Makes the next character a regular (nonspecial) + * character. + * Note that to match the quote character itself, it must + * be quoted. + * Note that this character must be escaped if used within + * string constants ("\\"). + * + * ` Quote (DOS). + * Makes the next character a regular (nonspecial) + * character. + * Note that to match the quote character itself, it must + * be quoted. + * + * Upper and lower case alphabetic characters are considered identical, + * i.e., 'a' and 'A' match each other. + * (What constitutes a lowercase letter depends on the current locale + * settings.) + * + * Spaces and control characters are treated as normal characters. + * + * Examples + * The following patterns in the left column will match the filenames in + * the middle column and will not match filenames in the right column: + * + * Pattern Will Match Will Not Match + * ------- ---------- -------------- + * a a (only) (anything else) + * a. a. (only) (anything else) + * a?c abc, acc, arc, a.c a, ac, abbc + * a*c ac, abc, abbc, acc, a.c a, ab, acb, bac + * a* a, ab, abb, a., a.b b, ba + * * a, ab, abb, a., .foo, a.foo (nothing) + * *. a., ab., abb., a.foo. a, ab, a.foo, .foo + * *.* a., a.b, ah.bc.foo a + * ^Z a, ab, abb a., .foo, a.foo + * ^Z. a., ab., abb. a, .foo, a.foo + * ^Z.* a, a., .foo, a.foo ab, abb + * *2.c 2.c, 12.c, foo2.c, foo.12.c 2x.c + * a[b-z]c abc, acc, azc (only) (anything else) + * [ab0-9]x ax, bx, 0x, 9x zx + * a[-.]b a-b, a.b (only) (anything else) + * a[!a-z]b a0b, a.b, a@b aab, azb, aa0b + * a[!-b]x a0x, a+x, acx a-x, abx, axxx + * a[-!b]x a-x, a!x, abx (only) (anything else) + * a[`]]x a]x (only) (anything else) + * a``x a`x (only) (anything else) + * oh`! oh! (only) (anything else) + * is`?it is?it (only) (anything else) + * !a?c a, ac, ab, abb, acb, a.foo abc, a.c, azc + * + */ + +#define FPAT_QUOTE _T('\\') /* Quotes a special char */ +#define FPAT_QUOTE2 _T('`') /* Quotes a special char */ +#define FPAT_DEL _T('/') /* Path delimiter */ +#define FPAT_DEL2 _T('\\') /* Path delimiter */ +#define FPAT_DOT _T('.') /* Dot char */ +#define FPAT_NOT _T('!') /* Exclusion */ +#define FPAT_ANY _T('?') /* Any one char */ +#define FPAT_CLOS _T('*') /* Zero or more chars */ +#define FPAT_CLOSP _T('\x1A') /* Zero or more nondelimiters */ +#define FPAT_SET_L _T('[') /* Set/range open bracket */ +#define FPAT_SET_R _T(']') /* Set/range close bracket */ +#define FPAT_SET_NOT _T('!') /* Set exclusion */ +#define FPAT_SET_THRU _T('-') /* Set range of chars */ + +int EDITPADC_CLASS fpattern_isvalid (LPCTSTR pat); +int EDITPADC_CLASS fpattern_match (LPCTSTR pat, LPCTSTR fname); +int EDITPADC_CLASS fpattern_matchn (LPCTSTR pat, LPCTSTR fname); + +#endif // __FPATTERN_H__INCLUDED__ diff --git a/Src/editlib/gotodlg.cpp b/Src/editlib/gotodlg.cpp new file mode 100644 index 000000000..b14cb133c --- /dev/null +++ b/Src/editlib/gotodlg.cpp @@ -0,0 +1,80 @@ +/////////////////////////////////////////////////////////////////////////// +// File: gotodlg.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Go to line dialog +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "gotodlg.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CGotoDlg dialog + +CGotoDlg::CGotoDlg (CCrystalTextView * pBuddy):CDialog (CGotoDlg::IDD, NULL) +{ + m_pBuddy = pBuddy; + //{{AFX_DATA_INIT(CGotoDlg) + m_sNumber = _T (""); + //}}AFX_DATA_INIT +} + +void CGotoDlg:: +DoDataExchange (CDataExchange * pDX) +{ + CDialog::DoDataExchange (pDX); + //{{AFX_DATA_MAP(CGotoDlg) + DDX_Control (pDX, IDC_NUMBER, m_ctlNumber); + DDX_Text (pDX, IDC_NUMBER, m_sNumber); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP (CGotoDlg, CDialog) +//{{AFX_MSG_MAP(CGotoDlg) +ON_EN_CHANGE (IDC_NUMBER, OnChangeNumber) +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + +///////////////////////////////////////////////////////////////////////////// +// CGotoDlg message handlers + +void CGotoDlg::OnOK () +{ + CDialog::OnOK (); + ASSERT (m_pBuddy != NULL); + m_pBuddy->GoToLine (_ttoi (m_sNumber), _tcschr (_T ("+-"), *(LPCTSTR)m_sNumber) != NULL); +} + +void CGotoDlg:: +OnChangeNumber () +{ + CString text; + GetDlgItem (IDC_NUMBER)->GetWindowText (text); + GetDlgItem (IDOK)->EnableWindow (!text.IsEmpty ()); +} + +BOOL CGotoDlg:: +OnInitDialog () +{ + CDialog::OnInitDialog (); + + GetDlgItem (IDOK)->EnableWindow (!m_sNumber.IsEmpty ()); + + return TRUE; +} diff --git a/Src/editlib/gotodlg.h b/Src/editlib/gotodlg.h new file mode 100644 index 000000000..303a995ea --- /dev/null +++ b/Src/editlib/gotodlg.h @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////// +// File: gotodlg.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Go to line dialog +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __GOTODLG_H__INCLUDED__ +#define __GOTODLG_H__INCLUDED__ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "editcmd.h" + +class CCrystalTextView; + +///////////////////////////////////////////////////////////////////////////// +// CGotoDlg dialog + +class EDITPADC_CLASS CGotoDlg : public CDialog + { +private : + CCrystalTextView * m_pBuddy; + + // Construction +public : + CGotoDlg (CCrystalTextView * pBuddy); + + CPoint m_ptCurrentPos; + // Dialog Data + //{{AFX_DATA(CGotoDlg) + enum { IDD = IDD_EDIT_GOTO }; + CEdit m_ctlNumber; + CString m_sNumber; + //}}AFX_DATA + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CGotoDlg) +protected : + virtual void DoDataExchange (CDataExchange * pDX); // DDX/DDV support + //}}AFX_VIRTUAL + + // Implementation +protected : + + // Generated message map functions + //{{AFX_MSG(CGotoDlg) + virtual void OnOK (); + afx_msg void OnChangeNumber (); + virtual BOOL OnInitDialog (); + //}}AFX_MSG + DECLARE_MESSAGE_MAP () + }; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // __GOTODLG_H__INCLUDED__ diff --git a/Src/editlib/html.cpp b/Src/editlib/html.cpp new file mode 100644 index 000000000..e560c0439 --- /dev/null +++ b/Src/editlib/html.cpp @@ -0,0 +1,701 @@ +/////////////////////////////////////////////////////////////////////////// +// File: html.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// HTML syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszHtmlKeywordList[] = + { + // HTML section + _T ("DOCTYPE"), + _T ("PUBLIC"), + _T ("FRAME"), + _T ("FRAMESET"), + _T ("NOFRAMES"), + // HEAD section + _T ("HEAD"), + _T ("TITLE"), + _T ("ISINDEX"), + _T ("META"), + _T ("LINK"), + _T ("BASE"), + _T ("SCRIPT"), + _T ("STYLE"), + // BODY section + _T ("BODY"), + // headings + _T ("H1"), + _T ("H2"), + _T ("H3"), + _T ("H4"), + _T ("H5"), + _T ("H6"), + // lists + _T ("UL"), + _T ("OL"), + _T ("DIR"), + _T ("MENU"), + _T ("LI"), + _T ("DL"), + _T ("DT"), + _T ("DD"), + // text containers + _T ("P"), + _T ("PRE"), + _T ("BLOCKQUOTE"), + _T ("ADDRESS"), + // others + _T ("DIV"), + _T ("SPAN"), + _T ("CENTER"), + _T ("HR"), + _T ("FORM"), + _T ("TABLE"), + _T ("LEFT"), + _T ("RIGHT"), + _T ("TOP"), + // logical markup + _T ("EM"), + _T ("STRONG"), + _T ("DFN"), + _T ("CODE"), + _T ("SAMP"), + _T ("KBD"), + _T ("VAR"), + _T ("CITE"), + // physical markup + _T ("TT"), + _T ("I"), + _T ("B"), + _T ("U"), + _T ("STRIKE"), + _T ("BIG"), + _T ("SMALL"), + _T ("SUB"), + _T ("SUP"), + // special markup + _T ("A"), + _T ("BASEFONT"), + _T ("IMG"), + _T ("APPLET"), + _T ("PARAM"), + _T ("FONT"), + _T ("BR"), + _T ("MAP"), + _T ("AREA"), + // forms + _T ("INPUT"), + _T ("SELECT"), + _T ("OPTION"), + _T ("TEXTAREA"), + _T ("ONCLICK"), + // tables + _T ("CAPTION"), + _T ("TR"), + _T ("TH"), + _T ("TD"), + _T ("HTML"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("ACTION"), + _T ("ALIGN"), + _T ("ALINK"), + _T ("BACKGROUND"), + _T ("BGCOLOR"), + _T ("COLOR"), + _T ("COMPACT"), + _T ("CONTENT"), + _T ("ENCTYPE"), + _T ("FACE"), + _T ("HEIGHT"), + _T ("HREF"), + _T ("HTTP-EQUIV"), + _T ("LINK"), + _T ("METHOD"), + _T ("NAME"), + _T ("PROMPT"), + _T ("REL"), + _T ("REV"), + _T ("START"), + _T ("TEXT"), + _T ("TYPE"), + _T ("VALUE"), + _T ("VLINK"), + _T ("WIDTH"), + _T ("ADD_DATE"), + _T ("ALT"), + _T ("BORDER"), + _T ("CELLPADDING"), + _T ("CELLSPACING"), + _T ("CHECKED"), + _T ("CLEAR"), + _T ("CODE"), + _T ("CODEBASE"), + _T ("COLS"), + _T ("COLSPAN"), + _T ("COORDS"), + _T ("FOLDED"), + _T ("HSPACE"), + _T ("ISMAP"), + _T ("LAST_MODIFIED"), + _T ("LAST_VISIT"), + _T ("MAXLENGTH"), + _T ("MULTIPLE"), + _T ("NORESIZE"), + _T ("NOSHADE"), + _T ("NOWRAP"), + _T ("ROWS"), + _T ("ROWSPAN"), + _T ("SELECTED"), + _T ("SHAPE"), + _T ("SIZE"), + _T ("SRC"), + _T ("TARGET"), + _T ("USEMAP"), + _T ("VALIGN"), + _T ("VSPACE"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("nbsp"), + _T ("quot"), + _T ("amp"), + _T ("lt"), + _T ("lt"), + _T ("gt"), + _T ("copy"), + _T ("reg"), + _T ("acute"), + _T ("laquo"), + _T ("raquo"), + _T ("iexcl"), + _T ("iquest"), + _T ("Agrave"), + _T ("agrave"), + _T ("Aacute"), + _T ("aacute"), + _T ("Acirc"), + _T ("acirc"), + _T ("Atilde"), + _T ("atilde"), + _T ("Auml"), + _T ("auml"), + _T ("Aring"), + _T ("aring"), + _T ("AElig"), + _T ("aelig"), + _T ("Ccedil"), + _T ("ccedil"), + _T ("ETH"), + _T ("eth"), + _T ("Egrave"), + _T ("egrave"), + _T ("Eacute"), + _T ("eacute"), + _T ("Ecirc"), + _T ("ecirc"), + _T ("Euml"), + _T ("euml"), + _T ("Igrave"), + _T ("igrave"), + _T ("Iacute"), + _T ("iacute"), + _T ("Icirc"), + _T ("icirc"), + _T ("Iuml"), + _T ("iuml"), + _T ("Ntilde"), + _T ("ntilde"), + _T ("Ograve"), + _T ("ograve"), + _T ("Oacute"), + _T ("oacute"), + _T ("Ocirc"), + _T ("ocirc"), + _T ("Otilde"), + _T ("otilde"), + _T ("Ouml"), + _T ("ouml"), + _T ("Oslash"), + _T ("oslash"), + _T ("Ugrave"), + _T ("ugrave"), + _T ("Uacute"), + _T ("uacute"), + _T ("Ucirc"), + _T ("ucirc"), + _T ("Uuml"), + _T ("uuml"), + _T ("Yacute"), + _T ("yacute"), + _T ("yuml"), + _T ("THORN"), + _T ("thorn"), + _T ("szlig"), + _T ("sect"), + _T ("para"), + _T ("micro"), + _T ("brvbar"), + _T ("plusmn"), + _T ("middot"), + _T ("uml"), + _T ("cedil"), + _T ("ordf"), + _T ("ordm"), + _T ("not"), + _T ("shy"), + _T ("macr"), + _T ("deg"), + _T ("sup1"), + _T ("sup2"), + _T ("sup3"), + _T ("frac14"), + _T ("frac12"), + _T ("frac34"), + _T ("times"), + _T ("divide"), + _T ("cent"), + _T ("pound"), + _T ("curren"), + _T ("yen"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsHtmlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszHtmlKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsHtmlNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 +#define COOKIE_USER1 0x0020 +#define COOKIE_EXT_USER1 0x0040 + +DWORD CCrystalTextView:: +ParseLineHtml (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_USER1); + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~(COOKIE_EXT_COMMENT|COOKIE_EXT_USER1)) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else if (dwCookie & COOKIE_EXT_USER1) + { + DEFINE_BLOCK (nPos, COLORINDEX_FUNCNAME); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_COMMENT) + { + if (I > 1 && pszChars[I] == '>' && pszChars[I - 1] == '-' && pszChars[I - 2] == '-') + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + bRedefineBlock = TRUE; + } + continue; + } + + // Normal text + if ((dwCookie & COOKIE_PREPROCESSOR) && pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + + if ((dwCookie & COOKIE_PREPROCESSOR) && pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + I += 3; + dwCookie |= COOKIE_EXT_COMMENT; + dwCookie &= ~COOKIE_PREPROCESSOR; + continue; + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsHtmlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + goto next; + } + } + else if (dwCookie & COOKIE_USER1) + { + if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else + { + goto next; + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; +next: + ; + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor end: > or bracket + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>'/* || pszChars[I] == '}'*/) + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor start: & + if (pszChars[I] == '&') + { + dwCookie |= COOKIE_USER1; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: ; + if (dwCookie & COOKIE_USER1) + { + if (pszChars[I] == ';') + { + dwCookie &= ~COOKIE_USER1; + nIdentBegin = -1; + continue; + } + } + } + } + + if (nIdentBegin >= 0 && (dwCookie & COOKIE_PREPROCESSOR)) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsHtmlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + } + } + + // Preprocessor end: > or } + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>'/* || pszChars[I] == '}'*/) + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + } + } + +end: + dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_PREPROCESSOR | COOKIE_EXT_USER1); + return dwCookie; +} diff --git a/Src/editlib/is.cpp b/Src/editlib/is.cpp new file mode 100644 index 000000000..e532c17ab --- /dev/null +++ b/Src/editlib/is.cpp @@ -0,0 +1,741 @@ +/////////////////////////////////////////////////////////////////////////// +// File: is.cpp +// Version: 1.2.0.5 +// Created: 29-Dec-1998 +// +// Copyright: Stcherbatchenko Andrei +// E-mail: windfall@gmx.de +// +// Implementation of the CCrystalEditView class, a part of the Crystal Edit - +// syntax coloring text editor. +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 16-Aug-99 +// Ferdinand Prantl: +// + FEATURE: corrected bug in syntax highlighting C comments +// + FEATURE: extended levels 1- 4 of keywords in some languages +// +// ... it's being edited very rapidly so sorry for non-commented +// and maybe "ugly" code ... +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// InstallShield keywords (IS3.0) +static LPTSTR s_apszISKeywordList[] = + { + _T ("begin"), + _T ("call"), + _T ("case"), + _T ("declare"), + _T ("default"), + _T ("downto"), + _T ("else"), + _T ("elseif"), + _T ("end"), + _T ("endif"), + _T ("endswitch"), + _T ("endwhile"), + _T ("external"), + _T ("for"), + _T ("function"), + _T ("goto"), + _T ("if"), + _T ("program"), + _T ("prototype"), + _T ("repeat"), + _T ("return"), + _T ("step"), + _T ("switch"), + _T ("then"), + _T ("to"), + _T ("typedef"), + _T ("until"), + _T ("void"), + _T ("while"), + _T ("BOOL"), + _T ("BYREF"), + _T ("CHAR"), + _T ("HIWORD"), + _T ("HWND"), + _T ("INT"), + _T ("LIST"), + _T ("LONG"), + _T ("LOWORD"), + _T ("NUMBER"), + _T ("POINTER"), + _T ("QUAD"), + _T ("RGB"), + _T ("SHORT"), + _T ("STRING"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("AFTER"), + _T ("APPEND"), + _T ("BACK"), + _T ("BEFORE"), + _T ("CANCEL"), + _T ("COMMAND"), + _T ("COMMANDEX"), + _T ("CONTINUE"), + _T ("DISABLE"), + _T ("DLG_ERR"), + _T ("ENABLE"), + _T ("EXCLUSIVE"), + _T ("EXISTS"), + _T ("FAILIFEXISTS"), + _T ("FALSE"), + _T ("FULL"), + _T ("NEXT"), + _T ("NO"), + _T ("NONEXCLUSIVE"), + _T ("NOSET"), + _T ("OFF"), + _T ("ON"), + _T ("PARTIAL"), + _T ("REPLACE"), + _T ("REPLACE_ITEM"), + _T ("RESET"), + _T ("RESTART"), + _T ("SET"), + _T ("TRUE"), + _T ("YES"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("CMDLINE"), + _T ("ERRORFILENAME"), + _T ("INFOFILENAME"), + _T ("ISRES"), + _T ("ISUSER"), + _T ("ISVERSION"), + _T ("SRCDIR"), + _T ("SRCDISK"), + _T ("SUPPORTDIR"), + _T ("TARGETDIR"), + _T ("TARGETDISK"), + _T ("WINDIR"), + _T ("WINDISK"), + _T ("WINSYSDIR"), + _T ("WINSYSDISK"), + NULL + }; + +/* built-in functions + _T ("AddFolderIcon"), + _T ("AddProfString"), + _T ("AddressNumber"), + _T ("AddressString"), + _T ("AddressStruct"), + _T ("AppCommandControls"), + _T ("AskDestPath"), + _T ("AskOptionsCreates"), + _T ("AskPath"), + _T ("AskText"), + _T ("AskYesNoCreates"), + _T ("BatchAddAdds"), + _T ("BatchDeleteEx"), + _T ("BatchFileLoad"), + _T ("BatchFileSave"), + _T ("BatchFind"), + _T ("BatchGetFileNameRetrieves"), + _T ("BatchMoveEx"), + _T ("BatchSetFileNameDetermines"), + _T ("CallDLLFx"), + _T ("ChangeDirectory"), + _T ("CloseFile"), + _T ("CmdGetHwndDlg"), + _T ("CommitSharedFiles"), + _T ("ComponentAddItemAdds"), + _T ("ComponentDialog"), + _T ("ComponentGetItemInfoRetrieves"), + _T ("ComponentGetItemSizeQueries"), + _T ("ComponentIsItemSelected"), + _T ("ComponentListItemsCreates"), + _T ("ComponentSelectItem"), + _T ("ComponentSetItemInfoSets"), + _T ("ComponentTotalSizeCalculates"), + _T ("CompressAdd"), + _T ("CompressDel"), + _T ("CompressEnumEnumerates"), + _T ("CompressGet"), + _T ("CompressInfoRetrieves"), + _T ("ConfigAdd"), + _T ("ConfigDeleteDeletes"), + _T ("ConfigFileLoadLoads"), + _T ("ConfigFileSaveSaves"), + _T ("ConfigFindSearches"), + _T ("ConfigGetFileName"), + _T ("ConfigGetIntRetrieves"), + _T ("ConfigMoveMoves"), + _T ("ConfigSetFileName"), + _T ("ConfigSetIntSets"), + _T ("CopyBytes"), + _T ("CopyFileCopies"), + _T ("CreateDir"), + _T ("CreateFileCreates"), + _T ("CreateProgramFolder"), + _T ("CtrlClear"), + _T ("CtrlDir"), + _T ("CtrlGetCurSel"), + _T ("CtrlGetMLETextRetrieves"), + _T ("CtrlGetMultCurSel"), + _T ("CtrlGetStateRetrieves"), + _T ("CtrlGetSubCommand"), + _T ("CtrlGetText"), + _T ("CtrlPGroups"), + _T ("CtrlSelectTextSelects"), + _T ("CtrlSetCurSel"), + _T ("CtrlSetFont"), + _T ("CtrlSetList"), + _T ("CtrlSetMLETextSets"), + _T ("CtrlSetMultCurSel"), + _T ("CtrlSetStateSets"), + _T ("CtrlSetText"), + _T ("DefineDialogRegisters"), + _T ("DeinstallStartStarts"), + _T ("Delay"), + _T ("DeleteDir"), + _T ("DeleteFileDeletes"), + _T ("DeleteFolderIconRemoves"), + _T ("DeleteProgramFolder"), + _T ("Disable"), + _T ("DoInitiates"), + _T ("DoInstall"), + _T ("EnableEnables"), + _T ("EndDialog"), + _T ("EnterDisk"), + _T ("ExistsDir"), + _T ("ExistsDiskChecks"), + _T ("ExitProgMan"), + _T ("EzBatchAddPathAdds"), + _T ("EzBatchAddStringAdds"), + _T ("EzBatchReplaceReplaces"), + _T ("EzConfigAddDriver"), + _T ("EzConfigAddString"), + _T ("EzConfigGetValueRetrieves"), + _T ("EzConfigSetValueRetrieves"), + _T ("EzDefineDialogRegisters"), + _T ("FileCompare"), + _T ("FileDeleteLineDeletes"), + _T ("FileGrepSearches"), + _T ("FileInsertLineInserts"), + _T ("FileSetBeginDefineStarts"), + _T ("FileSetEndDefineEnds"), + _T ("FileSetEndPerform"), + _T ("FileSetPerformPerforms"), + _T ("FileSetPerformEzExecutes"), + _T ("FileSetResetResets"), + _T ("FileSetRoot"), + _T ("FindAllDirs"), + _T ("FindAllFilesSearches"), + _T ("FindFileSearches"), + _T ("FindWindowRetrieves"), + _T ("GetByte"), + _T ("GetDirRetrieves"), + _T ("GetDisk"), + _T ("GetDiskSpaceReturns"), + _T ("GetEnvVar"), + _T ("GetExtentsRetrieves"), + _T ("GetFileInfo"), + _T ("GetFont"), + _T ("GetGroupNameListRetrieves"), + _T ("GetItemNameList"), + _T ("GetLine"), + _T ("GetMemFreeReturns"), + _T ("GetMode"), + _T ("GetProfIntReturns"), + _T ("GetProfString"), + _T ("GetSystemInfo"), + _T ("GetValidDrivesListReturns"), + _T ("GetWindowHandle"), + _T ("Handler"), + _T ("HIWORDRetrieves"), + _T ("InstallationInfoAllows"), + _T ("IsRetrieves"), + _T ("LaunchApp"), + _T ("LaunchAppAndWaitLaunches"), + _T ("ListAddItem"), + _T ("ListAddString"), + _T ("ListCount"), + _T ("ListCreateCreates"), + _T ("ListCurrentItem"), + _T ("ListCurrentString"), + _T ("ListDeleteItemDeletes"), + _T ("ListDeleteStringDeletes"), + _T ("ListDestroy"), + _T ("ListFindItemAttempts"), + _T ("ListFindStringAttempts"), + _T ("ListGetFirstItemAcquires"), + _T ("ListGetFirstStringRetrieves"), + _T ("ListGetNextItem"), + _T ("ListGetNextString"), + _T ("ListReadFromFileReads"), + _T ("ListSetCurrentItemSets"), + _T ("ListSetCurrentStringSets"), + _T ("ListSetIndexSets"), + _T ("ListWriteToFile"), + _T ("LongPathFromShortPath"), + _T ("LongPathToQuote"), + _T ("LongPathToShortPath"), + _T ("LOWORDRetrieves"), + _T ("MessageBeep"), + _T ("MessageBoxCreates"), + _T ("NumToStrConverts"), + _T ("OpenFileOpens"), + _T ("OpenFileModeSets"), + _T ("ParsePath"), + _T ("PathAdd"), + _T ("PathDeleteDeletes"), + _T ("PathFindFinds"), + _T ("PathGet"), + _T ("PathMoveRearranges"), + _T ("PathSet"), + _T ("PlaceBitmap"), + _T ("PlaceWindow"), + _T ("QueryProgGroupQueries"), + _T ("QueryProgItem"), + _T ("QueryShellMgr"), + _T ("ReadBytes"), + _T ("RebootDialogCreates"), + _T ("RegDBCreateKeyExAllows"), + _T ("RegDBDeleteKeyDeletes"), + _T ("RegDBGetAppInfo"), + _T ("RegDBGetItemGets"), + _T ("RegDBGetKeyValueExRetrieves"), + _T ("RegDBKeyExist"), + _T ("RegDBQueryKey"), + _T ("RegDBSetAppInfo"), + _T ("RegDBSetDefaultRoot"), + _T ("RegDBSetItemSets"), + _T ("RegDBSetKeyValueExSets"), + _T ("ReleaseDialog"), + _T ("ReloadProgGroup"), + _T ("RenameFileRenames"), + _T ("ReplaceFolderIcon"), + _T ("ReplaceProfString"), + _T ("SdAskDestPath"), + _T ("SdAskOptionsCreates"), + _T ("SdAskOptionsListCreates"), + _T ("SdBitmapDisplays"), + _T ("SdComponentDialog"), + _T ("SdComponentDialog2Displays"), + _T ("SdComponentDialogAdvDisplays"), + _T ("SdComponentMult"), + _T ("SdConfirmNewDir"), + _T ("SdConfirmRegistration"), + _T ("SdDisplayTopics"), + _T ("SdFinishDisplays"), + _T ("SdFinishRebootDisplays"), + _T ("SdLicense"), + _T ("SdOptionsButtonsDisplays"), + _T ("SdProductName"), + _T ("SdRegisterUserDisplays"), + _T ("SdRegisterUserExDisplays"), + _T ("SdSelectFolderCreates"), + _T ("SdSetupType"), + _T ("SdShowAnyDialog"), + _T ("SdShowDlgEdit1Displays"), + _T ("SdShowDlgEdit2Displays"), + _T ("SdShowDlgEdit3Displays"), + _T ("SdShowFileModsDisplays"), + _T ("SdShowInfoListDisplays"), + _T ("SdShowMsg"), + _T ("SdStartCopy"), + _T ("SdWelcome"), + _T ("SeekBytes"), + _T ("SelectDir"), + _T ("SelectFolderCreates"), + _T ("SendMessage"), + _T ("SetByte"), + _T ("SetColorSets"), + _T ("SetDialogTitleChanges"), + _T ("SetErrorMsg"), + _T ("SetErrorTitle"), + _T ("SetFileInfo"), + _T ("SetFont"), + _T ("SetStatusWindow"), + _T ("SetTitleDisplays"), + _T ("SetupType"), + _T ("ShowGroup"), + _T ("ShowProgramFolder"), + _T ("SizeWindowSpecifies"), + _T ("Split"), + _T ("Sprintf"), + _T ("SprintfBoxAllows"), + _T ("StatusGetSize"), + _T ("StatusUpdateUpdates"), + _T ("StrCompareCompares"), + _T ("StrFind"), + _T ("StrGetTokensRetrieves"), + _T ("StrLength"), + _T ("StrRemoveLastSlashRemoves"), + _T ("StrSubExtracts"), + _T ("StrToLowerConverts"), + _T ("StrToNumConverts"), + _T ("StrToUpperConverts"), + _T ("StructGet"), + _T ("StructGetPPoints"), + _T ("StructPut"), + _T ("StructPutPPlaces"), + _T ("SystemTerminates"), + _T ("UnUseDLLUnloads"), + _T ("UseDLLOpens"), + _T ("VarRestoreRestores"), + _T ("VarSave"), + _T ("VerCompareCompares"), + _T ("VerFindFileVersionRetrieves"), + _T ("VerGetFileVersion"), + _T ("VerSearchAndUpdateFileSearches"), + _T ("VerUpdateFile"), + _T ("WaitOnDialogDisplays"), + _T ("Welcome"), + _T ("WriteBytesWrites"), + _T ("WriteLine"), + _T ("WriteProfString"), + _T ("XCopyFile"), +*/ + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsISKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszISKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsISNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineIS (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Preprocessor directive #.... + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + continue; + } + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsISKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsISNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsISKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsISNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/java.cpp b/Src/editlib/java.cpp new file mode 100644 index 000000000..173a8083f --- /dev/null +++ b/Src/editlib/java.cpp @@ -0,0 +1,378 @@ +/////////////////////////////////////////////////////////////////////////// +// File: java.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Java syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszJavaKeywordList[] = + { + _T ("abstract"), + _T ("default"), + _T ("goto"), + _T ("null"), + _T ("synchronized"), + _T ("boolean"), + _T ("do"), + _T ("if"), + _T ("package"), + _T ("this"), + _T ("break"), + _T ("double"), + _T ("implements"), + _T ("private"), + _T ("threadsafe"), + _T ("byte"), + _T ("else"), + _T ("import"), + _T ("protected"), + _T ("throw"), + _T ("byvalue"), + _T ("extends"), + _T ("instanceof"), + _T ("public"), + _T ("transient"), + _T ("case"), + _T ("false"), + _T ("int"), + _T ("return"), + _T ("true"), + _T ("catch"), + _T ("final"), + _T ("interface"), + _T ("short"), + _T ("try"), + _T ("char"), + _T ("finally"), + _T ("long"), + _T ("static"), + _T ("void"), + _T ("class"), + _T ("float"), + _T ("native"), + _T ("super"), + _T ("while"), + _T ("const"), + _T ("for"), + _T ("new"), + _T ("switch"), + _T ("continue"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsJavaKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszJavaKeywordList, pszChars, nLength); +} + +static BOOL +IsJavaNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineJava (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Preprocessor directive #.... + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + continue; + } + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsJavaKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsJavaNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsJavaKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsJavaNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/lisp.cpp b/Src/editlib/lisp.cpp new file mode 100644 index 000000000..0ae1e28f7 --- /dev/null +++ b/Src/editlib/lisp.cpp @@ -0,0 +1,576 @@ +/////////////////////////////////////////////////////////////////////////// +// File: lisp.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// LISP (particularly AutoLISP) syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszLispKeywordList[] = + { + _T ("abs"), + _T ("acad_colordlg"), + _T ("acad_helpdlg"), + _T ("acad_strlsort"), + _T ("action_tile"), + _T ("add_list"), + _T ("ads"), + _T ("alert"), + _T ("alloc"), + _T ("and"), + _T ("angle"), + _T ("angtof"), + _T ("angtos"), + _T ("append"), + _T ("apply"), + _T ("arxload"), + _T ("arxunload"), + _T ("arx"), + _T ("ascii"), + _T ("assoc"), + _T ("atan"), + _T ("atof"), + _T ("atoi"), + _T ("atoms-family"), + _T ("atom"), + _T ("autoarxload"), + _T ("autoload"), + _T ("autoxload"), + _T ("boole"), + _T ("boundp"), + _T ("caaaar"), + _T ("caaadr"), + _T ("caaar"), + _T ("caadar"), + _T ("caaddr"), + _T ("caadr"), + _T ("caar"), + _T ("cadaar"), + _T ("cadadr"), + _T ("cadar"), + _T ("caddar"), + _T ("cadddr"), + _T ("caddr"), + _T ("cadr"), + _T ("car"), + _T ("cdaaar"), + _T ("cdaadr"), + _T ("cdaar"), + _T ("cdadar"), + _T ("cdaddr"), + _T ("cdadr"), + _T ("cdar"), + _T ("cddaar"), + _T ("cddadr"), + _T ("cddar"), + _T ("cdddar"), + _T ("cddddr"), + _T ("cdddr"), + _T ("cddr"), + _T ("cdr"), + _T ("chr"), + _T ("client_data_tile"), + _T ("close"), + _T ("command"), + _T ("cond"), + _T ("cons"), + _T ("cos"), + _T ("cvunit"), + _T ("defun"), + _T ("dictnext"), + _T ("dictsearch"), + _T ("dimx_tile"), + _T ("dimy_tile"), + _T ("distance"), + _T ("distof"), + _T ("done_dialog"), + _T ("end_image"), + _T ("end_list"), + _T ("entdel"), + _T ("entget"), + _T ("entlast"), + _T ("entmake"), + _T ("entmod"), + _T ("entnext"), + _T ("entsel"), + _T ("entupd"), + _T ("equal"), + _T ("eq"), + _T ("eval"), + _T ("exit"), + _T ("expand"), + _T ("expt"), + _T ("exp"), + _T ("fill_image"), + _T ("findfile"), + _T ("fix"), + _T ("float"), + _T ("foreach"), + _T ("gcd"), + _T ("gc"), + _T ("get_attr"), + _T ("get_tile"), + _T ("getangle"), + _T ("getcfg"), + _T ("getcorner"), + _T ("getdist"), + _T ("getenv"), + _T ("getfield"), + _T ("getint"), + _T ("getkword"), + _T ("getorient"), + _T ("getpoint"), + _T ("getreal"), + _T ("getstring"), + _T ("getvar"), + _T ("graphscr"), + _T ("grclear"), + _T ("grdraw"), + _T ("grread"), + _T ("grtext"), + _T ("grvecs"), + _T ("handent"), + _T ("if"), + _T ("help"), + _T ("initget"), + _T ("inters"), + _T ("itoa"), + _T ("lambda"), + _T ("last"), + _T ("length"), + _T ("listp"), + _T ("list"), + _T ("load_dialog"), + _T ("load"), + _T ("logand"), + _T ("logior"), + _T ("log"), + _T ("lsh"), + _T ("mapcar"), + _T ("max"), + _T ("member"), + _T ("mem"), + _T ("menucmd"), + _T ("minusp"), + _T ("min"), + _T ("mode_tile"), + _T ("namedobjdict"), + _T ("nentsel"), + _T ("nentselp"), + _T ("new_dialog"), + _T ("not"), + _T ("nth"), + _T ("null"), + _T ("numberp"), + _T ("open"), + _T ("or"), + _T ("osnap"), + _T ("polar"), + _T ("prin1"), + _T ("princ"), + _T ("print"), + _T ("progn"), + _T ("prompt"), + _T ("quit"), + _T ("quote"), + _T ("read-char"), + _T ("read-line"), + _T ("read"), + _T ("redraw"), + _T ("regapp"), + _T ("rem"), + _T ("repeat"), + _T ("reverse"), + _T ("rtos"), + _T ("setcfg"), + _T ("setfunhelp"), + _T ("setq"), + _T ("setvar"), + _T ("set_tile"), + _T ("set"), + _T ("sin"), + _T ("slide_image"), + _T ("snvalid"), + _T ("sqrt"), + _T ("ssadd"), + _T ("ssdel"), + _T ("ssget"), + _T ("sslength"), + _T ("ssmemb"), + _T ("ssname"), + _T ("startapp"), + _T ("start_dialog"), + _T ("start_image"), + _T ("start_list"), + _T ("strcase"), + _T ("strcat"), + _T ("strlen"), + _T ("substr"), + _T ("subst"), + _T ("tablet"), + _T ("tblnext"), + _T ("tblobjname"), + _T ("tblsearch"), + _T ("term_dialog"), + _T ("terpri"), + _T ("textbox"), + _T ("textpage"), + _T ("textscr"), + _T ("trace"), + _T ("trans"), + _T ("type"), + _T ("unload_dialog"), + _T ("untrace"), + _T ("vector_image"), + _T ("ver"), + _T ("vmon"), + _T ("vports"), + _T ("wcmatch"), + _T ("while"), + _T ("write-char"), + _T ("write-line"), + _T ("xdroom"), + _T ("xdsize"), + _T ("xload"), + _T ("xunload"), + _T ("zerop"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsLispKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszLispKeywordList, pszChars, nLength); +} + +static BOOL +IsLispNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineLisp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + BOOL bDefun = FALSE; + + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == ';' && pszChars[I - 1] == '|') + if ((I > 1 && pszChars[I] == ';' && pszChars[I - 1] == '|' /*&& pszChars[I - 2] != ';'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == ';' && pszChars[I - 1] == '|')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] != '|' && pszChars[I - 1] == ';') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '|' && pszChars[I - 1] == ';') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsLispKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5)) + { + bDefun = TRUE; + } + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsLispNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bDefun) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsLispKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5)) + { + bDefun = TRUE; + } + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsLispNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bDefun) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/memcombo.cpp b/Src/editlib/memcombo.cpp new file mode 100644 index 000000000..e0d396329 --- /dev/null +++ b/Src/editlib/memcombo.cpp @@ -0,0 +1,276 @@ +/////////////////////////////////////////////////////////////////////////// +// File: memcombo.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Combo-box saving last typed expressions +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "resource.h" +#include "memcombo.h" +#include "registry.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#define REMEMBER_COUNT 64 + +#ifdef _DEBUG +#include "memcombo.inl" +#endif // _DEBUG + +#ifdef INLINE +#undef INLINE +#endif +#define INLINE + +///////////////////////////////////////////////////////////////////////////// +// CMemComboBox + +BEGIN_MESSAGE_MAP (CMemComboBox, CComboBox) +//{{AFX_MSG_MAP(CMemComboBox) +ON_WM_KILLFOCUS () +ON_CONTROL_REFLECT (CBN_SETFOCUS, OnSetfocus) +ON_WM_DESTROY () +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + +///////////////////////////////////////////////////////////////////////////// +// CMemComboBox message handlers + +CMap < CString, LPCTSTR, CString, LPCTSTR > CMemComboBox::groups; + +void SetComboBoxHeight(CComboBox &Control) +{ + int nHeight = Control.GetCount(), nMax = ::GetSystemMetrics(SM_CYSCREEN) - 48; + CRect rc; + + Control.GetClientRect(rc); + Control.ClientToScreen(rc); + nHeight = rc.Height() * nHeight + 16; + if(rc.top + nHeight > nMax) + nHeight = nMax - rc.top; + Control.SetWindowPos(NULL, 0, 0, rc.Width(), nHeight, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); +} + +void SetComboBoxWidth(CComboBox &Control, LPCTSTR lpszText = NULL) +{ + int cnt = Control.GetCount(); + + if(!cnt) + return; + CClientDC dc(&Control); + NONCLIENTMETRICS info; + CFont oFont, *oldFont; + int width = 0, nMax = ::GetSystemMetrics(SM_CXSCREEN) - 48; + CRect rc; + CSize size; + + memset(&info.lfMenuFont, 0, sizeof(LOGFONT)); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + info.lfMenuFont.lfHeight = -MulDiv(9, dc.GetDeviceCaps(LOGPIXELSY), 72); + info.lfMenuFont.lfWidth = 0; + info.lfMenuFont.lfWeight = FW_THIN; + info.lfMenuFont.lfItalic = FALSE; + info.lfMenuFont.lfUnderline = FALSE; + info.lfMenuFont.lfCharSet = DEFAULT_CHARSET; + info.lfMenuFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + info.lfMenuFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + info.lfMenuFont.lfQuality = DEFAULT_QUALITY; + info.lfMenuFont.lfPitchAndFamily = FF_SWISS; + _tcscpy(info.lfMenuFont.lfFaceName, _T("MS Sans Serif")); + oFont.CreateFontIndirect(&info.lfMenuFont); + oldFont = dc.SelectObject(&oFont); + if(lpszText && *lpszText) { + size = dc.GetTextExtent(lpszText); + width = size.cx; + } else { + CString item; + + for(int i = 0; i < cnt; i++) { + Control.GetLBText(i, item); + size = dc.GetTextExtent(item); + if(size.cx > width) + width = size.cx; + } + } + Control.GetClientRect(rc); + Control.ClientToScreen(rc); + if(rc.left + width > nMax) + width = nMax - rc.left; + Control.SetDroppedWidth(width); + dc.SelectObject(oldFont); +} + +/*void FillComboBox(CComboBox &Control, const CList &Items, LPCTSTR lpszItem, BOOL bMustContains) +{ + POSITION pos = Items.GetHeadPosition(); + CString item, maxitem; + int maxlen = 0, len; + + Control.ResetContent(); + while(pos) { + item = Items.GetNext(pos); + len = item.GetLength(); + if(maxlen < len) { + maxlen = len; + maxitem = item; + } + Control.AddString(item); + } + if(Items.Find(lpszItem)) + Control.SelectString(-1, lpszItem); + else if(!bMustContains) + Control.SetWindowText(lpszItem); + SetComboBoxHeight(Control); + SetComboBoxWidth(Control, maxitem); +}*/ + +/*int ListToString (CString &sResult, CList listSource) +{ + POSITION pos = listSource.GetHeadPosition (); + CString item; + while (pos) + { + item = listSource.GetNext (pos); + sResult += item + _T ('\n'); + } + return listSource.GetCount (); +}*/ + +/*int StringToList (CList listResult, CString sSource) +{ + int pos; + while ((pos = sSource.Find (_T ('\n'))) != -1) + { + listResult.AddTail (sSource.Left (pos)); + sSource = sSource.Mid (pos + 1); + } + if (*(LPCTSTR) sSource) + { + listResult.AddTail (sSource); + } + return listResult.GetCount (); +}*/ + +void CMemComboBox::FillCurrent () +{ + CString strText; + GetWindowText (strText); + Fill (strText); +} + +void CMemComboBox:: +Fill (LPCTSTR text) +{ + if (text && *text) + { + int nPos = FindStringExact (-1, text); + if (nPos != CB_ERR) + DeleteString (nPos); + InsertString (0, text); + int l = GetCount (); + if (l > REMEMBER_COUNT) + DeleteString (--l); + SetComboBoxHeight (*this); + SetComboBoxWidth (*this); + SetCurSel (0); + if (!m_sGroup.IsEmpty ()) + { + CString item, items; + for (int i = 0; i < l; i++) + { + GetLBText (i, item); + items += item + _T ('\n'); + } + groups.SetAt (m_sGroup, items); + } + } +} + +void CMemComboBox:: +LoadSettings () +{ + CReg reg; + if (reg.Open (HKEY_CURRENT_USER, _T ("SOFTWARE\\EditPad"), KEY_READ)) + { + POSITION pos = groups.GetStartPosition (); + static LPCTSTR name[] = { _T("FindText"), _T("ReplaceText") }; + CString value; + + for (int i = 0; i < countof (name); i++) + { + if (reg.LoadString (name[i], value)) + { + groups.SetAt (name[i], value); + } + } + } +} + +void CMemComboBox:: +SaveSettings () +{ + CReg reg; + if (reg.Create (HKEY_CURRENT_USER, _T ("SOFTWARE\\EditPad"), KEY_WRITE)) + { + POSITION pos = groups.GetStartPosition (); + CString name, value; + + while (pos) + { + groups.GetNextAssoc (pos, name, value); + VERIFY (reg.SaveString (name, value)); + } + } +} + +void CMemComboBox:: +OnKillFocus (CWnd * /*pNewWnd*/) +{ + FillCurrent (); +} + +void CMemComboBox:: +OnSetfocus () +{ + if (m_bFirstFocus && !m_sGroup.IsEmpty ()) + { + m_bFirstFocus = FALSE; + CString items, strText; + GetWindowText (strText); + if (groups.Lookup (m_sGroup, items)) + { + int p; + while ((p = items.Find (_T ('\n'))) != -1) + { + AddString (items.Left (p)); + items = items.Mid (p + 1); + } + SetComboBoxHeight (*this); + SetComboBoxWidth (*this); + SetCurSel (0); + if (!strText.IsEmpty ()) + SetWindowText (strText); + } + } +} + +void CMemComboBox:: +OnDestroy () +{ + FillCurrent (); + CComboBox::OnDestroy (); +} diff --git a/Src/editlib/memcombo.h b/Src/editlib/memcombo.h new file mode 100644 index 000000000..422c93ae7 --- /dev/null +++ b/Src/editlib/memcombo.h @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////// +// File: memcombo.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Combo-box saving last typed expressions +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __MEMCOMBO_H__INCLUDED__ +#define __MEMCOMBO_H__INCLUDED__ + +//////////////////////////////////////////////////////////////////////////////// +// Includes + +//////////////////////////////////////////////////////////////////////////////// +// All Classes and Class Templates + +class CMemComboBox; + +//////////////////////////////////////////////////////////////////////////////// +// Includes + +///////////////////////////////////////////////////////////////////////////// +// CMemComboBox Class Declaration + +class EDITPADC_CLASS CMemComboBox : public CComboBox + { + // Construction +public : + CMemComboBox (); + + // Attributes +public : + static CMap < CString, LPCTSTR, CString, LPCTSTR > groups; + BOOL m_bFirstFocus; + CString m_sGroup; + + // Operations +public : + void FillCurrent (); + void Fill (LPCTSTR text); + static void LoadSettings (); + static void SaveSettings (); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMemComboBox) + //}}AFX_VIRTUAL + + // Implementation +public : + virtual ~CMemComboBox (); + + // Generated message map functions +public : + //{{AFX_MSG(CMemComboBox) + afx_msg void OnKillFocus (CWnd * pNewWnd); + afx_msg void OnSetfocus (); + afx_msg void OnDestroy (); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP () + }; + +///////////////////////////////////////////////////////////////////////////// + +#ifndef _DEBUG +#include "memcombo.inl" +#endif // _DEBUG + +///////////////////////////////////////////////////////////////////////////// + +#endif // __MEMCOMBO_H__INCLUDED__ diff --git a/Src/editlib/memcombo.inl b/Src/editlib/memcombo.inl new file mode 100644 index 000000000..91620bc2d --- /dev/null +++ b/Src/editlib/memcombo.inl @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////// +// File: memcombo.inl +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Combo-box saving last typed expressions +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __MEMCOMBO_INL__INCLUDED__ +#define __MEMCOMBO_INL__INCLUDED__ + +#ifdef INLINE +#undef INLINE +#endif + +#ifndef _DEBUG +#define INLINE inline +#else +#define INLINE +#endif // _DEBUG + +//////////////////////////////////////////////////////////////////////////////// +// Methods + +INLINE +CMemComboBox::CMemComboBox () : m_bFirstFocus (TRUE) +{ +} + +INLINE +CMemComboBox::~CMemComboBox () +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +#endif // __MEMCOMBO_INL__INCLUDED__ diff --git a/Src/editlib/pascal.cpp b/Src/editlib/pascal.cpp new file mode 100644 index 000000000..24f69dd5f --- /dev/null +++ b/Src/editlib/pascal.cpp @@ -0,0 +1,346 @@ +/////////////////////////////////////////////////////////////////////////// +// File: pascal.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Pascal syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszPascalKeywordList[] = + { + _T ("program"), + _T ("const"), + _T ("type"), + _T ("var"), + _T ("begin"), + _T ("end"), + _T ("array"), + _T ("set"), + _T ("record"), + _T ("string"), + _T ("if"), + _T ("then"), + _T ("else"), + _T ("while"), + _T ("for"), + _T ("to"), + _T ("downto"), + _T ("do"), + _T ("with"), + _T ("repeat"), + _T ("until"), + _T ("case"), + _T ("of"), + _T ("goto"), + _T ("exit"), + _T ("label"), + _T ("procedure"), + _T ("function"), + _T ("nil"), + _T ("file"), + _T ("and"), + _T ("or"), + _T ("not"), + _T ("xor"), + _T ("div"), + _T ("mod"), + _T ("unit"), + _T ("uses"), + _T ("implementation"), + _T ("interface"), + _T ("external"), + _T ("asm"), + _T ("inline"), + _T ("object"), + _T ("constructor"), + _T ("destructor"), + _T ("virtual"), + _T ("far"), + _T ("assembler"), + _T ("near"), + _T ("inherited"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsPascalKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPascalKeywordList, pszChars, nLength); +} + +static BOOL +IsPascalNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLinePascal (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == ')' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == ')' && pszChars[I - 1] == '*' && pszChars[I - 2] != '(') || (I == 1 && pszChars[I] == ')' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '(') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + continue; + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsPascalKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPascalNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsPascalKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPascalNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/perl.cpp b/Src/editlib/perl.cpp new file mode 100644 index 000000000..bc20703fd --- /dev/null +++ b/Src/editlib/perl.cpp @@ -0,0 +1,506 @@ +/////////////////////////////////////////////////////////////////////////// +// File: perl.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// PERL syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszPerlKeywordList[] = + { + _T ("q"), + _T ("qq"), + _T ("qw"), + _T ("qx"), + _T ("m"), + _T ("s"), + _T ("y"), + _T ("tr"), + _T ("if"), + _T ("sub"), + _T ("return"), + _T ("while"), + _T ("for"), + _T ("elsif"), + _T ("foreach"), + _T ("else"), + _T ("unless"), + _T ("eq"), + _T ("not"), + _T ("and"), + _T ("or"), + _T ("ne"), + _T ("until"), + _T ("abs"), + _T ("accept"), + _T ("alarm"), + _T ("atan2"), + _T ("bind"), + _T ("binmode"), + _T ("bless"), + _T ("caller"), + _T ("chdir"), + _T ("chmod"), + _T ("chomp"), + _T ("chop"), + _T ("chown"), + _T ("chr"), + _T ("chroot"), + _T ("close"), + _T ("closedir"), + _T ("connect"), + _T ("cos"), + _T ("crypt"), + _T ("dbmclose"), + _T ("dbmopen"), + _T ("defined"), + _T ("delete"), + _T ("die"), + _T ("do"), + _T ("dump"), + _T ("each"), + _T ("eof"), + _T ("eval"), + _T ("exec"), + _T ("exists"), + _T ("exit"), + _T ("exp"), + _T ("fcntl"), + _T ("fileno"), + _T ("flock"), + _T ("fork"), + _T ("formline"), + _T ("getc"), + _T ("getlogin"), + _T ("getpeername"), + _T ("getpgrp"), + _T ("getppid"), + _T ("getpriority"), + _T ("getpwnam"), + _T ("getgrname"), + _T ("gethostbyname"), + _T ("getnetbyname"), + _T ("getprotobyname"), + _T ("getpwuid"), + _T ("getgrgid"), + _T ("getservbyname"), + _T ("gethostbyaddr"), + _T ("getnetbyaddr"), + _T ("getprotobynumber"), + _T ("getservbyport"), + _T ("getpwent"), + _T ("getgrent"), + _T ("gethostent"), + _T ("getnetent"), + _T ("getprotoent"), + _T ("getservent"), + _T ("setpwent"), + _T ("setgrent"), + _T ("sethostent"), + _T ("setnetent"), + _T ("setprotoent"), + _T ("setservent"), + _T ("endpwent"), + _T ("endgrent"), + _T ("endhostent"), + _T ("endnetent"), + _T ("endprotoent"), + _T ("endservent"), + _T ("getsockname"), + _T ("getsockopt"), + _T ("glob"), + _T ("gmtime"), + _T ("goto"), + _T ("grep"), + _T ("hex"), + _T ("import"), + _T ("index"), + _T ("int"), + _T ("ioctl"), + _T ("join"), + _T ("keys"), + _T ("kill"), + _T ("last"), + _T ("lc"), + _T ("lcfirst"), + _T ("length"), + _T ("link"), + _T ("listen"), + _T ("local"), + _T ("localtime"), + _T ("log"), + _T ("lstat"), + _T ("map"), + _T ("mkdir"), + _T ("msgctl"), + _T ("msgget"), + _T ("msgsnd"), + _T ("msgrcv"), + _T ("my"), + _T ("next"), + _T ("no"), + _T ("oct"), + _T ("open"), + _T ("opendir"), + _T ("ord"), + _T ("pack"), + _T ("pipe"), + _T ("pop"), + _T ("pos"), + _T ("print"), + _T ("printf"), + _T ("push"), + _T ("quotemeta"), + _T ("rand"), + _T ("read"), + _T ("readdir"), + _T ("readlink"), + _T ("recv"), + _T ("redo"), + _T ("ref"), + _T ("rename"), + _T ("require"), + _T ("reset"), + _T ("return"), + _T ("reverse"), + _T ("rewinddir"), + _T ("rindex"), + _T ("rmdir"), + _T ("scalar"), + _T ("seek"), + _T ("seekdir"), + _T ("select"), + _T ("semctl"), + _T ("semget"), + _T ("semop"), + _T ("send"), + _T ("setpgrp"), + _T ("setpriority"), + _T ("setsockopt"), + _T ("shift"), + _T ("shmctl"), + _T ("sgmget"), + _T ("shmread"), + _T ("shmwrite"), + _T ("shutdown"), + _T ("sin"), + _T ("sleep"), + _T ("socket"), + _T ("socketpair"), + _T ("sort"), + _T ("splice"), + _T ("split"), + _T ("sprintf"), + _T ("sqrt"), + _T ("srand"), + _T ("stat"), + _T ("study"), + _T ("substr"), + _T ("symlink"), + _T ("syscall"), + _T ("sysread"), + _T ("system"), + _T ("syswrite"), + _T ("tell"), + _T ("telldir"), + _T ("tie"), + _T ("time"), + _T ("times"), + _T ("truncate"), + _T ("uc"), + _T ("ucfirst"), + _T ("umask"), + _T ("undef"), + _T ("unlink"), + _T ("unpack"), + _T ("untie"), + _T ("unshift"), + _T ("use"), + _T ("utime"), + _T ("values"), + _T ("vec"), + _T ("wait"), + _T ("waitpid"), + _T ("wantarray"), + _T ("warn"), + _T ("write"), + _T ("x"), + _T ("continue"), + _T ("package"), + _T ("bootstrap"), + _T ("getgrnam"), + _T ("tan"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsPerlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPerlKeywordList, pszChars, nLength); +} + +static BOOL +IsPerlNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLinePerl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsPerlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPerlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsPerlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPerlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/php.cpp b/Src/editlib/php.cpp new file mode 100644 index 000000000..bbca7687e --- /dev/null +++ b/Src/editlib/php.cpp @@ -0,0 +1,937 @@ +/////////////////////////////////////////////////////////////////////////// +// File: php.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// HTML syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszHtmlKeywordList[] = + { + // HTML section + _T ("DOCTYPE"), + _T ("PUBLIC"), + _T ("FRAME"), + _T ("FRAMESET"), + _T ("NOFRAMES"), + // HEAD section + _T ("HEAD"), + _T ("TITLE"), + _T ("ISINDEX"), + _T ("META"), + _T ("LINK"), + _T ("BASE"), + _T ("SCRIPT"), + _T ("STYLE"), + // BODY section + _T ("BODY"), + // headings + _T ("H1"), + _T ("H2"), + _T ("H3"), + _T ("H4"), + _T ("H5"), + _T ("H6"), + // lists + _T ("UL"), + _T ("OL"), + _T ("DIR"), + _T ("MENU"), + _T ("LI"), + _T ("DL"), + _T ("DT"), + _T ("DD"), + // text containers + _T ("P"), + _T ("PRE"), + _T ("BLOCKQUOTE"), + _T ("ADDRESS"), + // others + _T ("DIV"), + _T ("SPAN"), + _T ("CENTER"), + _T ("HR"), + _T ("FORM"), + _T ("TABLE"), + _T ("LEFT"), + _T ("RIGHT"), + _T ("TOP"), + // logical markup + _T ("EM"), + _T ("STRONG"), + _T ("DFN"), + _T ("CODE"), + _T ("SAMP"), + _T ("KBD"), + _T ("VAR"), + _T ("CITE"), + // physical markup + _T ("TT"), + _T ("I"), + _T ("B"), + _T ("U"), + _T ("STRIKE"), + _T ("BIG"), + _T ("SMALL"), + _T ("SUB"), + _T ("SUP"), + // special markup + _T ("A"), + _T ("BASEFONT"), + _T ("IMG"), + _T ("APPLET"), + _T ("PARAM"), + _T ("FONT"), + _T ("BR"), + _T ("MAP"), + _T ("AREA"), + // forms + _T ("INPUT"), + _T ("SELECT"), + _T ("OPTION"), + _T ("TEXTAREA"), + _T ("ONCLICK"), + // tables + _T ("CAPTION"), + _T ("TR"), + _T ("TH"), + _T ("TD"), + _T ("HTML"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("ACTION"), + _T ("ALIGN"), + _T ("ALINK"), + _T ("BACKGROUND"), + _T ("BGCOLOR"), + _T ("COLOR"), + _T ("COMPACT"), + _T ("CONTENT"), + _T ("ENCTYPE"), + _T ("FACE"), + _T ("HEIGHT"), + _T ("HREF"), + _T ("HTTP-EQUIV"), + _T ("LINK"), + _T ("METHOD"), + _T ("NAME"), + _T ("PROMPT"), + _T ("REL"), + _T ("REV"), + _T ("START"), + _T ("TEXT"), + _T ("TYPE"), + _T ("VALUE"), + _T ("VLINK"), + _T ("WIDTH"), + _T ("ADD_DATE"), + _T ("ALT"), + _T ("BORDER"), + _T ("CELLPADDING"), + _T ("CELLSPACING"), + _T ("CHECKED"), + _T ("CLEAR"), + _T ("CODE"), + _T ("CODEBASE"), + _T ("COLS"), + _T ("COLSPAN"), + _T ("COORDS"), + _T ("FOLDED"), + _T ("HSPACE"), + _T ("ISMAP"), + _T ("LAST_MODIFIED"), + _T ("LAST_VISIT"), + _T ("MAXLENGTH"), + _T ("MULTIPLE"), + _T ("NORESIZE"), + _T ("NOSHADE"), + _T ("NOWRAP"), + _T ("ROWS"), + _T ("ROWSPAN"), + _T ("SELECTED"), + _T ("SHAPE"), + _T ("SIZE"), + _T ("SRC"), + _T ("TARGET"), + _T ("USEMAP"), + _T ("VALIGN"), + _T ("VSPACE"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("nbsp"), + _T ("quot"), + _T ("amp"), + _T ("lt"), + _T ("lt"), + _T ("gt"), + _T ("copy"), + _T ("reg"), + _T ("acute"), + _T ("laquo"), + _T ("raquo"), + _T ("iexcl"), + _T ("iquest"), + _T ("Agrave"), + _T ("agrave"), + _T ("Aacute"), + _T ("aacute"), + _T ("Acirc"), + _T ("acirc"), + _T ("Atilde"), + _T ("atilde"), + _T ("Auml"), + _T ("auml"), + _T ("Aring"), + _T ("aring"), + _T ("AElig"), + _T ("aelig"), + _T ("Ccedil"), + _T ("ccedil"), + _T ("ETH"), + _T ("eth"), + _T ("Egrave"), + _T ("egrave"), + _T ("Eacute"), + _T ("eacute"), + _T ("Ecirc"), + _T ("ecirc"), + _T ("Euml"), + _T ("euml"), + _T ("Igrave"), + _T ("igrave"), + _T ("Iacute"), + _T ("iacute"), + _T ("Icirc"), + _T ("icirc"), + _T ("Iuml"), + _T ("iuml"), + _T ("Ntilde"), + _T ("ntilde"), + _T ("Ograve"), + _T ("ograve"), + _T ("Oacute"), + _T ("oacute"), + _T ("Ocirc"), + _T ("ocirc"), + _T ("Otilde"), + _T ("otilde"), + _T ("Ouml"), + _T ("ouml"), + _T ("Oslash"), + _T ("oslash"), + _T ("Ugrave"), + _T ("ugrave"), + _T ("Uacute"), + _T ("uacute"), + _T ("Ucirc"), + _T ("ucirc"), + _T ("Uuml"), + _T ("uuml"), + _T ("Yacute"), + _T ("yacute"), + _T ("yuml"), + _T ("THORN"), + _T ("thorn"), + _T ("szlig"), + _T ("sect"), + _T ("para"), + _T ("micro"), + _T ("brvbar"), + _T ("plusmn"), + _T ("middot"), + _T ("uml"), + _T ("cedil"), + _T ("ordf"), + _T ("ordm"), + _T ("not"), + _T ("shy"), + _T ("macr"), + _T ("deg"), + _T ("sup1"), + _T ("sup2"), + _T ("sup3"), + _T ("frac14"), + _T ("frac12"), + _T ("frac34"), + _T ("times"), + _T ("divide"), + _T ("cent"), + _T ("pound"), + _T ("curren"), + _T ("yen"), + NULL + }; + +static LPTSTR s_apszPhpKeywordList[] = + { + _T ("exit"), + _T ("die"), + _T ("old_function"), + _T ("function"), + _T ("cfunction"), + _T ("const"), + _T ("return"), + _T ("if"), + _T ("elseif"), + _T ("endif"), + _T ("else"), + _T ("while"), + _T ("endwhile"), + _T ("do"), + _T ("for"), + _T ("endfor"), + _T ("foreach"), + _T ("endforeach"), + _T ("as"), + _T ("switch"), + _T ("endswitch"), + _T ("case"), + _T ("default"), + _T ("break"), + _T ("continue"), + _T ("echo"), + _T ("print"), + _T ("class"), + _T ("extends"), + _T ("new"), + _T ("var"), + _T ("int"), + _T ("integer"), + _T ("real"), + _T ("double"), + _T ("float"), + _T ("string"), + _T ("array"), + _T ("object"), + _T ("bool"), + _T ("boolean"), + _T ("eval"), + _T ("include"), + _T ("require"), + _T ("global"), + _T ("isset"), + _T ("empty"), + _T ("static"), + _T ("unset"), + _T ("list"), + _T ("array"), + NULL + }; + +static LPTSTR s_apszPhp1KeywordList[] = + { + _T ("OR"), + _T ("AND"), + _T ("XOR"), + NULL + }; + +static LPTSTR s_apszPhp2KeywordList[] = + { + _T ("__LINE__"), + _T ("__FILE__"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsHtmlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszHtmlKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsPhpKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPhpKeywordList, pszChars, nLength); +} + +static BOOL +IsPhp1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPhp1KeywordList, pszChars, nLength); +} + +static BOOL +IsPhp2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPhp2KeywordList, pszChars, nLength); +} + +static BOOL +IsPhpNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 +#define COOKIE_USER1 0x0020 +#define COOKIE_USER2 0x0040 +#define COOKIE_EXT_USER1 0x0080 + +DWORD CCrystalTextView:: +ParseLinePhp (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & (COOKIE_EXT_COMMENT|COOKIE_EXT_USER1); + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~(COOKIE_EXT_COMMENT|COOKIE_EXT_USER1)) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else if (dwCookie & COOKIE_EXT_USER1) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_COMMENT) + { + if (dwCookie & COOKIE_EXT_USER1) + { + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + } + else + { + if (I > 1 && pszChars[I] == '>' && pszChars[I - 1] == '-' && pszChars[I - 2] == '-') + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + } + continue; + } + + if ((dwCookie & COOKIE_EXT_USER1) && I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + if ((dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + bRedefineBlock = TRUE; + continue; + } + } + + // Normal text + if ((dwCookie & (COOKIE_PREPROCESSOR|COOKIE_EXT_USER1)) && pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + + if ((dwCookie & (COOKIE_PREPROCESSOR|COOKIE_EXT_USER1)) && pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + bWasCommentStart = FALSE; + } + else + { + if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + I += 3; + dwCookie |= COOKIE_EXT_COMMENT; + dwCookie &= ~COOKIE_PREPROCESSOR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsPhpNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + goto next; + } + } + else if (dwCookie & COOKIE_EXT_USER1) + { + if (dwCookie & COOKIE_USER2) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + if (IsPhpKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPhp1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_OPERATOR); + } + else if (IsPhp2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsPhpNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + else + { + goto next; + } + } + } + else if (dwCookie & COOKIE_USER1) + { + if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else + { + goto next; + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; +next: + ; + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor end: > or bracket + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + + // Preprocessor start: & + if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '&') + { + dwCookie |= COOKIE_USER1; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: ; + if (dwCookie & COOKIE_USER1) + { + if (pszChars[I] == ';') + { + dwCookie &= ~COOKIE_USER1; + nIdentBegin = -1; + continue; + } + } + + // Preprocessor start: $ + if ((dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '$') + { + dwCookie |= COOKIE_USER2; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: ... + if (dwCookie & COOKIE_USER2) + { + if (!xisalnum (pszChars[I])) + { + dwCookie &= ~COOKIE_USER2; + nIdentBegin = -1; + continue; + } + } + } + } + + if (nIdentBegin >= 0 && (dwCookie & COOKIE_PREPROCESSOR)) + { + if (IsHtmlKeyword (pszChars + nIdentBegin, I - nIdentBegin) && (pszChars[nIdentBegin - 1] == _T ('<') || pszChars[nIdentBegin - 1] == _T ('/'))) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsPhpNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + else if (nIdentBegin >= 0 && (dwCookie & COOKIE_EXT_USER1)) + { + if (IsPhpKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsPhp1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_OPERATOR); + } + else if (IsPhp2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsPhpNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + // User1 start: + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && (pszChars[I - 1] == '?' || pszChars[I - 1] == '%')) + { + dwCookie &= ~COOKIE_EXT_USER1; + nIdentBegin = -1; + } + } + + // Preprocessor end: > or } + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + } + } + +end: + dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_PREPROCESSOR | COOKIE_EXT_USER1); + return dwCookie; +} diff --git a/Src/editlib/python.cpp b/Src/editlib/python.cpp new file mode 100644 index 000000000..4e5f3ffa6 --- /dev/null +++ b/Src/editlib/python.cpp @@ -0,0 +1,440 @@ +/////////////////////////////////////////////////////////////////////////// +// File: python.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Python syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszPythonKeywordList[] = + { + _T ("access"), + _T ("and"), + _T ("break"), + _T ("class"), + _T ("continue"), + _T ("def"), + _T ("del"), + _T ("elif"), + _T ("else"), + _T ("except"), + _T ("exec"), + _T ("finally"), + _T ("for"), + _T ("from"), + _T ("global"), + _T ("if"), + _T ("import"), + _T ("in"), + _T ("is"), + _T ("lambda"), + _T ("not"), + _T ("or"), + _T ("pass"), + _T ("print"), + _T ("raise"), + _T ("return"), + _T ("try"), + _T ("while"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("argv"), + _T ("builtin_module_names"), + _T ("exc_type"), + _T ("exc_value"), + _T ("exc_traceback"), + _T ("exit"), + _T ("exitfunc"), + _T ("last_type"), + _T ("last_value"), + _T ("last_traceback"), + _T ("modules"), + _T ("path"), + _T ("ps1"), + _T ("ps2"), + _T ("settrace"), + _T ("setprofile"), + _T ("stdin"), + _T ("stdout"), + _T ("stderr"), + _T ("tracebacklimit"), + _T ("AttributeError"), + _T ("EOFError"), + _T ("IOError"), + _T ("ImportError"), + _T ("IndexError"), + _T ("KeyError"), + _T ("KeyboardInterrupt"), + _T ("MemoryError"), + _T ("NameError"), + _T ("OverflowError"), + _T ("RuntimeError"), + _T ("SyntaxError"), + _T ("SystemError"), + _T ("SystemExit"), + _T ("TypeError"), + _T ("ValueError"), + _T ("ZeroDivisionError"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("id"), + _T ("__init__"), + _T ("__del__"), + _T ("__repr__"), + _T ("__str__"), + _T ("__cmp__"), + _T ("__hash__"), + _T ("__dict__"), + _T ("__methods__"), + _T ("__members__"), + _T ("__class__"), + _T ("__bases__"), + _T ("__add__"), + _T ("__mul__"), + _T ("__mod__"), + _T ("__sub__"), + _T ("__div__"), + _T ("divmod"), + _T ("__divmod__"), + _T ("pow"), + _T ("__pow__"), + _T ("__and__"), + _T ("__xor__"), + _T ("__or__"), + _T ("__lshift__"), + _T ("__rshift__"), + _T ("nonzero"), + _T ("__nonzero__"), + _T ("coerce"), + _T ("__coerce__"), + _T ("__neg__"), + _T ("__pos__"), + _T ("abs"), + _T ("__abs__"), + _T ("__invert__"), + _T ("int"), + _T ("__int__"), + _T ("float"), + _T ("__float__"), + _T ("long"), + _T ("__long__"), + _T ("float"), + _T ("__float__"), + _T ("oct"), + _T ("__oct__"), + _T ("hex"), + _T ("__hex__"), + _T ("range"), + _T ("round"), + _T ("xrange"), + _T ("len"), + _T ("__len__"), + _T ("__getitem__"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsPythonKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszPythonKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsPythonNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLinePython (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsPythonKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsPythonNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsPythonKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsPythonNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/registry.cpp b/Src/editlib/registry.cpp new file mode 100644 index 000000000..0f7be81e2 --- /dev/null +++ b/Src/editlib/registry.cpp @@ -0,0 +1,1463 @@ +/////////////////////////////////////////////////////////////////////////// +// File: registry.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Some handy stuff to deal with Windows registry +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// 14-Sep-99 +// + FIX: closing null handle (Michael A. Barnhart) +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "registry.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning ( disable : 4711 ) +/*////////////////////////////////////////////////////////////////////////////*/ + +/* initializes registry value data */ +void +RegValInit (RegVal *pValData) +{ + ASSERT (pValData); + pValData->dwType = REG_NONE; +} + +/* frees registry value data */ +void +RegValFree (RegVal *pValData) +{ + ASSERT (pValData); + if (pValData->dwType == REG_SZ || pValData->dwType == REG_EXPAND_SZ + || pValData->dwType == REG_LINK || pValData->dwType == REG_MULTI_SZ + || pValData->dwType == REG_BINARY) + { + free (pValData->pbyteData); + pValData->dwType = REG_NONE; + } +} + +/* get a number */ +bool +RegValGetNumber (const RegVal *pValData, DWORD *pdwNumber) +{ + ASSERT (pValData &&pdwNumber); + if (pValData->dwType == REG_DWORD) + { + *pdwNumber = pValData->dwNumber; + return true; + } + return false; +} + +/* get binary data */ +bool +RegValGetBinary (const RegVal *pValData, LPBYTE pbyteData, DWORD dwSize) +{ + ASSERT (pValData &&pbyteData); + if (pValData->dwType == REG_BINARY &&dwSize >= pValData->dwSize) + { + memcpy (pbyteData, pValData->pbyteData, pValData->dwSize); + return true; + } + return false; +} + +/* get new binary data */ +bool +RegValGetNewBinary (const RegVal *pValData, LPBYTE *pbyteData, DWORD *pdwSize) +{ + ASSERT (pValData &&pbyteData); + if (pValData->dwType == REG_BINARY) + { + LPBYTE pbyteNewData = (LPBYTE) malloc (pValData->dwSize); + if (pbyteNewData) + { + *pbyteData = pbyteNewData; + *pdwSize = pValData->dwSize; + memcpy (pbyteNewData, pValData->pbyteData, pValData->dwSize); + return true; + } + } + return false; +} + +/* get a new string */ +bool +RegValGetNewString (const RegVal *pValData, LPTSTR *pszString, DWORD *pdwLength) +{ + ASSERT (pValData &&pszString); + if (pValData->dwType == REG_SZ || pValData->dwType == REG_EXPAND_SZ + || pValData->dwType == REG_LINK || pValData->dwType == REG_MULTI_SZ) + { + LPTSTR pszNewString = (LPTSTR) malloc (pValData->dwLength + 1); + if (pszNewString) + { + *pszString = pszNewString; + if (pdwLength) + { + *pdwLength = pValData->dwLength; + } + memcpy (pszNewString, pValData->pszString, pValData->dwLength); + pszNewString [pValData->dwLength] = _T ('\0'); + return true; + } + } + return false; +} + +/* get a string */ +bool +RegValGetString (const RegVal *pValData, LPTSTR pszString, DWORD dwLength) +{ + ASSERT (pValData &&pszString); + if ((pValData->dwType == REG_SZ || pValData->dwType == REG_EXPAND_SZ + || pValData->dwType == REG_LINK || pValData->dwType == REG_MULTI_SZ) + && dwLength >= pValData->dwLength) + { + memcpy (pszString, pValData->pszString, pValData->dwLength); + pszString [pValData->dwLength] = _T ('\0'); + return true; + } + return false; +} + +/* get an array of strings */ +bool +RegValGetStringArr (const RegVal *pValData, LPTSTR pszStrings[], DWORD dwCount) +{ + ASSERT (pValData); + if (pValData->dwType == REG_MULTI_SZ) + { + LPCTSTR pszString; + DWORD dwRealCount = 0, dwLength; + for (pszString = pValData->pszString; *pszString; pszString += dwLength) + { + dwLength = _tcslen (pszString) + 1; + dwRealCount++; + } + if (dwCount >= dwRealCount) + { + LPTSTR *pszDstString = pszStrings; + for (LPCTSTR pszString = pValData->pszString; *pszString; pszString += dwLength, pszDstString++) + { + dwLength = _tcslen (pszString) + 1; + LPTSTR pszNewString = (LPTSTR) malloc (dwLength); + *pszDstString = pszNewString; + if (pszNewString) + { + while ((*pszNewString = (BYTE) *pszString) != _T ('\0')) + { + pszNewString++; + pszString++; + } + } + else + { + while (*pszString) + { + pszString++; + } + } + } + return true; + } + } + return false; +} + +/* get a new array of strings */ +bool +RegValGetNewStringArr (const RegVal *pValData, LPTSTR **pszStrings, DWORD *pdwCount) +{ + ASSERT (pValData); + if (pValData->dwType == REG_MULTI_SZ) + { + LPTSTR pszString; + DWORD dwRealCount = 0, dwLength; + for (pszString = pValData->pszString; *pszString; pszString += dwLength) + { + dwLength = _tcslen (pszString) + 1; + dwRealCount++; + } + LPTSTR *pszNewStrings = (LPTSTR *) malloc (dwRealCount *sizeof (LPTSTR)); + if (pszNewStrings) + { + *pszStrings = pszNewStrings; + *pdwCount = dwRealCount; + for (pszString = pValData->pszString; *pszString; pszString += dwLength, pszNewStrings++) + { + dwLength = _tcslen (pszString) + 1; + LPTSTR pszNewString = (LPTSTR) malloc (dwLength); + *pszNewStrings = pszNewString; + if (pszNewString) + { + while ((*pszNewString = (BYTE) *pszString) != _T ('\0')) + { + pszNewString++; + pszString++; + } + } + else + { + while (*pszString) + { + pszString++; + } + } + } + return true; + } + } + return false; +} + +#ifdef REG_WITH_MFC + +/* get a string */ +bool +RegValGetString (const RegVal *pValData, CString &sString) +{ + ASSERT (pValData); + if (pValData->dwType == REG_SZ || pValData->dwType == REG_EXPAND_SZ + || pValData->dwType == REG_LINK || pValData->dwType == REG_MULTI_SZ) + { + LPTSTR pszString = sString.GetBuffer (pValData->dwLength + 1); + memcpy (pszString, pValData->pszString, pValData->dwLength); + pszString [pValData->dwLength] = _T ('\0'); + sString.ReleaseBuffer (); + return true; + } + return false; +} + +/* get an array of strings */ +bool +RegValGetStringArr (const RegVal *pValData, CStringArray &arrString) +{ + ASSERT (pValData); + if (pValData->dwType == REG_MULTI_SZ) + { + arrString.RemoveAll (); + for (LPCTSTR pszString = pValData->pszString; *pszString; pszString += _tcslen (pszString) + 1) + { + arrString.Add (pszString); + } + return true; + } + return false; +} + +#endif /* REG_WITH_MFC */ + +/* set a number */ +void +RegValSetNumber (RegVal *pValData, DWORD dwNumber) +{ + ASSERT (pValData); + pValData->dwType = REG_DWORD; + pValData->dwNumber = dwNumber; +} + +/* set binary data */ +bool +RegValSetBinary (RegVal *pValData, const LPBYTE pbyteData, DWORD dwSize) +{ + ASSERT (pValData &&pbyteData); + pValData->pbyteData = (LPBYTE) malloc (dwSize); + if (pValData->pbyteData) + { + pValData->dwSize = dwSize; + pValData->dwType = REG_BINARY; + memcpy (pValData->pbyteData, pbyteData, dwSize); + return true; + } + pValData->dwType = REG_NONE; + return false; +} + +/* set a string */ +bool +RegValSetString (RegVal *pValData, LPCTSTR pszString) +{ + ASSERT (pValData &&pszString); + DWORD dwLength = _tcslen (pszString) + 1; + pValData->pszString = (LPTSTR) malloc (dwLength); + if (pValData->pszString) + { + pValData->dwLength = dwLength; + pValData->dwType = REG_SZ; + memcpy (pValData->pbyteData, pszString, dwLength); + return true; + } + pValData->dwType = REG_NONE; + return false; +} + +bool +RegValSetStringArr (RegVal *pValData, const LPCTSTR pszStrings[], DWORD dwCount) +{ + ASSERT (pValData &&pszStrings); + DWORD i, dwSize = 1; + if (dwCount) + { + for (i = 0; i < dwCount; i++) + { + dwSize += _tcslen (pszStrings[i]) + 1; + } + } + else + { + dwSize++; + } + pValData->pbyteData = (LPBYTE) malloc (dwSize); + if (pValData->pbyteData) + { + pValData->dwSize = dwSize; + pValData->dwType = REG_MULTI_SZ; + LPBYTE pbyteData = pValData->pbyteData; + if (dwCount) + { + for (i = 0; i < dwCount; i++) + { + LPCTSTR pszString = pszStrings[i]; + while ((*pbyteData++ = (BYTE) *pszString) != _T ('\0')) + { + pszString++; + } + } + } + else + { + *pbyteData++ = _T ('\0'); + } + *pbyteData = _T ('\0'); + return true; + } + pValData->dwType = REG_NONE; + return false; +} + +#ifdef REG_WITH_MFC + +/* set an array of strings */ +bool +RegValSetStringArr (RegVal *pValData, const CStringArray &arrString) +{ + ASSERT (pValData); + DWORD i, dwSize = 1, dwCount = arrString.GetSize (); + if (dwCount) + { + for (i = 0; i < dwCount; i++) + { + dwSize += arrString[i].GetLength () + 1; + } + } + else + { + dwSize++; + } + pValData->pbyteData = (LPBYTE) malloc (dwSize); + if (pValData->pbyteData) + { + pValData->dwSize = dwSize; + pValData->dwType = REG_MULTI_SZ; + LPBYTE pbyteData = pValData->pbyteData; + if (dwCount) + { + for (i = 0; i < dwCount; i++) + { + LPCTSTR pszString = arrString[i]; + while ((*pbyteData++ = (BYTE) *pszString) != _T ('\0')) + { + pszString++; + } + } + } + else + { + *pbyteData++ = _T ('\0'); + } + *pbyteData = _T ('\0'); + return true; + } + pValData->dwType = REG_NONE; + return false; +} + +#endif /* REG_WITH_MFC */ + +/* connect to remote computer registry */ +HKEY +RegConnect (HKEY hKey, LPCTSTR pszRemote) +{ + HKEY hSubKey; + if (RegConnectRegistry (pszRemote, hKey, &hSubKey) == ERROR_SUCCESS) + { + return hSubKey; + } + return NULL; +} + +/* open computer registry */ +HKEY +RegOpen (HKEY hKey, LPCTSTR pszSubKey, DWORD dwRights) +{ + HKEY hSubKey; + if (RegOpenKeyEx (hKey, pszSubKey, 0, dwRights, &hSubKey) == ERROR_SUCCESS) + { + return hSubKey; + } + return NULL; +} + +/* create computer registry */ +HKEY +RegCreate (HKEY hKey, LPCTSTR pszSubKey, DWORD dwRights) +{ + HKEY hSubKey; + DWORD dwDisposition; + if (RegCreateKeyEx (hKey, pszSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, dwRights, + NULL, &hSubKey, &dwDisposition) == ERROR_SUCCESS) + { + return hSubKey; + } + return NULL; +} + +/* close computer registry */ +void +RegClose (HKEY hKey) +{ + if (hKey) + RegCloseKey (hKey); +} + +/* load data of any type */ +bool +RegLoadVal (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, RegVal *pValData) +{ + ASSERT (pValData); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwSize; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_DWORD) + { + ASSERT (dwSize == sizeof (DWORD)); + DWORD dwNumber; + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) &dwNumber, &dwSize) == ERROR_SUCCESS) + { + ASSERT (dwSize == sizeof (DWORD)); + RegValFree (pValData); + pValData->dwType = dwType; + pValData->dwNumber = dwNumber; + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + } + else if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK + || dwType == REG_MULTI_SZ || dwType == REG_BINARY) + { + LPBYTE pbyteData = (LPBYTE) malloc (dwSize); + if (pbyteData) + { + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, pbyteData, &dwSize) == ERROR_SUCCESS) + { + RegValFree (pValData); + pValData->dwType = dwType; + pValData->pbyteData = pbyteData; + pValData->dwLength = dwSize; + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + free (pbyteData); + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load a number */ +bool +RegLoadNumber (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD *pdwNumber) +{ + ASSERT (pdwNumber); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwSize; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_DWORD) + { + ASSERT (dwSize == sizeof (DWORD)); + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pdwNumber, &dwSize) == ERROR_SUCCESS) + { + ASSERT (dwSize == sizeof (DWORD)); + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load binary data */ +bool +RegLoadBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize) +{ + ASSERT (pbyteData); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwRealSize; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealSize) == ERROR_SUCCESS) + { + if (dwType == REG_BINARY &&dwSize >= dwRealSize) + { + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, pbyteData, &dwRealSize) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load new binary data */ +bool +RegLoadNewBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize) +{ + ASSERT (pbyteData); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwRealSize; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealSize) == ERROR_SUCCESS) + { + if (dwType == REG_BINARY) + { + LPBYTE pbyteNewData = (LPBYTE) malloc (dwRealSize); + if (pbyteNewData) + { + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, pbyteNewData, &dwRealSize) == ERROR_SUCCESS) + { + *pbyteData = pbyteNewData; + *pdwSize = dwRealSize; + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + free (pbyteNewData); + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load a string */ +bool +RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength) +{ + ASSERT (pszString); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwRealLength; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealLength) == ERROR_SUCCESS) + { + if ((dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK + || dwType == REG_MULTI_SZ) &&dwLength >= dwRealLength) + { + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pszString, &dwRealLength) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load a new string */ +bool +RegLoadNewString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength) +{ + ASSERT (pszString); + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwRealLength; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealLength) == ERROR_SUCCESS) + { + if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK + || dwType == REG_MULTI_SZ) + { + LPTSTR pszNewString = (LPTSTR) malloc (dwRealLength); + if (pszNewString) + { + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pszNewString, &dwRealLength) == ERROR_SUCCESS) + { + *pszString = pszNewString; + if (pdwLength) + { + *pdwLength = dwRealLength; + } + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + free (pszNewString); + } + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load an array of strings */ +bool +RegLoadStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount) +{ + RegVal Value; + if (RegLoadVal (hKey, pszSubKey, pszValName, &Value)) + { + if (RegValGetStringArr (&Value, pszStrings, dwCount)) + { + RegValFree (&Value); + return true; + } + RegValFree (&Value); + } + return false; +} + +/* load a new array of strings */ +bool +RegLoadNewStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount) +{ + RegVal Value; + if (RegLoadVal (hKey, pszSubKey, pszValName, &Value)) + { + if (RegValGetNewStringArr (&Value, pszStrings, pdwCount)) + { + RegValFree (&Value); + return true; + } + RegValFree (&Value); + } + return false; +} + +#ifdef REG_WITH_MFC + +/* load a string */ +bool +RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, CString &sString) +{ + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + DWORD dwType, dwRealLength; + if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealLength) == ERROR_SUCCESS) + { + if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK + || dwType == REG_MULTI_SZ) + { + LPTSTR pszString = sString.GetBuffer (dwRealLength); + if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pszString, &dwRealLength) == ERROR_SUCCESS) + { + sString.ReleaseBuffer (dwRealLength); + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + sString.ReleaseBuffer (0); + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* load an array of strings */ +bool +RegLoadStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, CStringArray &arrString) +{ + RegVal Value; + if (RegLoadVal (hKey, pszSubKey, pszValName, &Value)) + { + if (RegValGetStringArr (&Value, arrString)) + { + RegValFree (&Value); + return true; + } + RegValFree (&Value); + } + return false; +} + +#endif /* REG_WITH_MFC */ + +/* store data of any type */ +bool +RegSaveVal (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const RegVal *pValData) +{ + ASSERT (pValData); + HKEY hSubKey = pszSubKey ? RegCreate (hKey, pszSubKey, KEY_WRITE) : hKey; + if (hSubKey) + { + LONG lResult; + if (pValData->dwType == REG_DWORD) + { + lResult = RegSetValueEx (hSubKey, pszValName, 0, pValData->dwType, (LPBYTE) &pValData->dwNumber, sizeof (DWORD)); + } + else if (pValData->dwType == REG_SZ || pValData->dwType == REG_EXPAND_SZ + || pValData->dwType == REG_LINK || pValData->dwType == REG_MULTI_SZ + || pValData->dwType == REG_BINARY) + { + lResult = RegSetValueEx (hSubKey, pszValName, 0, pValData->dwType, pValData->pbyteData, pValData->dwSize); + } + else + { + lResult = ERROR_BAD_FORMAT; + } + if (lResult == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* store a number */ +bool +RegSaveNumber (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD dwNumber) +{ + HKEY hSubKey = pszSubKey ? RegCreate (hKey, pszSubKey, KEY_WRITE) : hKey; + if (hSubKey) + { + if (RegSetValueEx (hSubKey, pszValName, 0, REG_DWORD, (LPBYTE) &dwNumber, sizeof (DWORD)) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* store binary data */ +bool +RegSaveBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize) +{ + HKEY hSubKey = pszSubKey ? RegCreate (hKey, pszSubKey, KEY_WRITE) : hKey; + if (hSubKey) + { + if (RegSetValueEx (hSubKey, pszValName, 0, REG_BINARY, pbyteData, dwSize) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* store a string */ +bool +RegSaveString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPCTSTR pszString) +{ + HKEY hSubKey = pszSubKey ? RegCreate (hKey, pszSubKey, KEY_WRITE) : hKey; + if (hSubKey) + { + if (RegSetValueEx (hSubKey, pszValName, 0, REG_SZ, (LPBYTE) pszString, _tcslen (pszString) + 1) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* store an array of strings */ +bool +RegSaveStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount) +{ + RegVal Value; + if (RegValSetStringArr (&Value, pszStrings, dwCount)) + { + if (RegSaveVal (hKey, pszSubKey, pszValName, &Value)) + { + RegValFree (&Value); + return true; + } + RegValFree (&Value); + } + return false; +} + +#ifdef REG_WITH_MFC + +/* store an array of strings */ +bool +RegSaveStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const CStringArray &arrString) +{ + RegVal Value; + if (RegValSetStringArr (&Value, arrString)) + { + if (RegSaveVal (hKey, pszSubKey, pszValName, &Value)) + { + RegValFree (&Value); + return true; + } + RegValFree (&Value); + } + return false; +} + +#endif /* REG_WITH_MFC */ + +/* delete all subkeys in the given key */ +bool +RegDeleteSubKeys (HKEY hKey) +{ + DWORD dwSubKeyCnt, dwMaxSubKey; + if (RegQueryInfoKey (hKey, NULL, NULL, 0, &dwSubKeyCnt, &dwMaxSubKey, + NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if (dwSubKeyCnt) + { + LPTSTR pszKeyName = (LPTSTR) malloc (dwMaxSubKey += 1); + if (pszKeyName) + { + do + { + if (RegEnumKey (hKey, --dwSubKeyCnt, pszKeyName, dwMaxSubKey) == ERROR_SUCCESS) + { + HKEY hSubKey = RegOpen (hKey, pszKeyName, KEY_READ | KEY_WRITE); + if (hSubKey) + { + if (RegDeleteSubKeys (hSubKey)) + { + RegClose (hSubKey); + if (RegDeleteKey (hKey, pszKeyName) != ERROR_SUCCESS) + { + free (pszKeyName); + return false; + } + } + else + { + RegClose (hSubKey); + free (pszKeyName); + return false; + } + } + else + { + free (pszKeyName); + return false; + } + } + else + { + free (pszKeyName); + return false; + } + } + while (dwSubKeyCnt); + free (pszKeyName); + } + else + { + return false; + } + } + return true; + } + return false; +} + +/* delete the given value or key in the registry with all of its subkeys */ +bool +RegDeleteKey (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName) +{ + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ | KEY_WRITE) : hKey; + if (hSubKey) + { + if (pszValName) + { + if (RegDeleteValue (hSubKey, pszValName) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + } + else + { + if (RegDeleteSubKeys (hSubKey)) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return RegDeleteKey (hKey, pszSubKey) == ERROR_SUCCESS; + } + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + return false; +} + +/* check wether the given key has other subkeys and/or values */ +bool +RegHasEntries (HKEY hKey, LPCTSTR pszSubKey, DWORD *pdwSubKeyCount, DWORD *pdwValueCount) +{ + HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; + if (hSubKey) + { + if (RegQueryInfoKey (hSubKey, NULL, NULL, 0, pdwSubKeyCount, NULL, NULL, pdwValueCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if (hSubKey != hKey) + RegClose (hSubKey); + return true; + } + if (hSubKey != hKey) + RegClose (hSubKey); + } + *pdwSubKeyCount = *pdwValueCount = 0; + return false; +} + +static LPTSTR g_pszValue = NULL; +static DWORD g_dwValueCnt, g_dwValue, g_dwValueMax; + +bool RegFindFirstValue (HKEY hKey, LPCTSTR *ppszValue, RegVal *pValData); + +/* walks to the first value */ +bool +RegFindFirstValue (HKEY hKey, LPCTSTR *ppszValue, RegVal *pValData) +{ + if (RegQueryInfoKey (hKey, NULL, NULL, 0, NULL, NULL, NULL, + &g_dwValueCnt, &g_dwValueMax, NULL, NULL, NULL) == ERROR_SUCCESS) + { + if (g_dwValueCnt) + { + if (g_pszValue) + { + free (g_pszValue); + g_pszValue = NULL; + } + g_pszValue = (LPTSTR) malloc (g_dwValueMax += 1); + if (g_pszValue) + { + DWORD dwMaxValue = g_dwValueMax; + g_dwValue = 0; + if (RegEnumValue (hKey, g_dwValue++, g_pszValue, &dwMaxValue, 0, NULL, NULL, NULL) == ERROR_SUCCESS) + { + *ppszValue = g_pszValue; + return RegLoadVal (hKey, NULL, g_pszValue, pValData); + } + } + } + } + return false; +} + +/* walks to the next value */ +bool RegFindNextValue (HKEY hKey, LPCTSTR *ppszValue, RegVal *pValData) +{ + DWORD dwMaxValue = g_dwValueMax; + if (g_dwValue < g_dwValueCnt && RegEnumValue (hKey, g_dwValue++, g_pszValue, &dwMaxValue, 0, NULL, NULL, NULL) == ERROR_SUCCESS) + { + *ppszValue = g_pszValue; + return RegLoadVal (hKey, NULL, g_pszValue, pValData); + } + return false; +} + +/* closes registry walking */ +void RegFindClose () +{ + if (g_pszValue) + { + free (g_pszValue); + g_pszValue = NULL; + } +} + +/*////////////////////////////////////////////////////////////////////////////*/ + +#ifdef __cplusplus + +/* constructor - automatically initializes registry value data */ +CRegVal::CRegVal () +{ + Init (); +} + +/* destructor - automatically frees registry value data */ +CRegVal::~CRegVal () +{ + Free (); +} + +/* initializes registry value data */ +void CRegVal::Init () +{ + RegValInit (this); +} + +/* frees registry value data */ +void CRegVal::Free () +{ + RegValFree (this); +} + +/* get a number */ +bool CRegVal::GetNumber (DWORD *pdwNumber) const +{ + return RegValGetNumber (this, pdwNumber); +} + +/* get binary data */ +bool CRegVal::GetBinary (LPBYTE pbyteData, DWORD dwSize) const +{ + return RegValGetBinary (this, pbyteData, dwSize); +} + +/* get new binary data */ +bool CRegVal::GetNewBinary (LPBYTE *pbyteData, DWORD *pdwSize) const +{ + return RegValGetNewBinary (this, pbyteData, pdwSize); +} + +/* get a string */ +bool CRegVal::GetString (LPTSTR pszString, DWORD dwLength) const +{ + return RegValGetString (this, pszString, dwLength); +} + +/* get a new string */ +bool CRegVal::GetNewString (LPTSTR *pszString, DWORD *pdwLength) const +{ + return RegValGetNewString (this, pszString, pdwLength); +} + +/* get an array of strings */ +bool CRegVal::GetStringArr (LPTSTR pszStrings[], DWORD dwCount) const +{ + return RegValGetStringArr (this, pszStrings, dwCount); +} + +/* get a new array of strings */ +bool CRegVal::GetNewStringArr (LPTSTR **pszStrings, DWORD *pdwCount) const +{ + return RegValGetNewStringArr (this, pszStrings, pdwCount); +} + +#ifdef REG_WITH_MFC + +/* get a string */ +bool CRegVal::GetString (CString &sString) const +{ + return RegValGetString (this, sString); +} + +/* get an array of strings */ +bool CRegVal::GetStringArr (CStringArray &arrString) const +{ + return RegValGetStringArr (this, arrString); +} + +#endif /* REG_WITH_MFC */ + +/* set a number */ +void CRegVal::SetNumber (DWORD dwNumber) +{ + RegValSetNumber (this, dwNumber); +} + +/* set binary data */ +bool CRegVal::SetBinary (const LPBYTE pbyteData, DWORD dwSize) +{ + return RegValSetBinary (this, pbyteData, dwSize); +} + +/* set a string */ +bool CRegVal::SetString (LPCTSTR pszString) +{ + return RegValSetString (this, pszString); +} + +/* set an array of strings */ +bool CRegVal::SetStringArr (const LPCTSTR pszStrings[], DWORD dwCount) +{ + return RegValSetStringArr (this, pszStrings, dwCount); +} + +#ifdef REG_WITH_MFC + +/* set an array of strings */ +bool CRegVal::SetStringArr (const CStringArray &arrString) +{ + return RegValSetStringArr (this, arrString); +} + +#endif /* REG_WITH_MFC */ + +/* constructor - automatically initializes registry data */ +CReg::CReg () +{ + Open (); +} + +/* destructor - automatically frees registry data */ +CReg::~CReg () +{ + Close (); +} + +/* connect to remote computer registry */ +HKEY CReg::Connect (HKEY hNewKey, LPCTSTR pszRemote) +{ + return hKey = RegConnect (hNewKey, pszRemote); +} + +/* connect to registry key */ +HKEY CReg::Open (HKEY hNewKey /*= NULL*/) +{ + return hKey = hNewKey; +} + +/* open computer registry */ +HKEY CReg::Open (HKEY hNewKey, LPCTSTR pszSubKey, DWORD dwRights) +{ + return hKey = RegOpen (hNewKey, pszSubKey, dwRights); +} + +/* close computer registry */ +void CReg::Close () +{ + if (hKey != NULL) // MAB 8 Nov 1999 - added NULL test + { + RegClose (hKey); + //*** MIPO 07-12-1999 - After Closing the Key, hKey must by NULL **** + // RegClose - dont do that - it must be done manualy + hKey = NULL; + } +} + +/* create computer registry */ +HKEY CReg::Create (HKEY hNewKey, LPCTSTR pszSubKey, DWORD dwRights) +{ + return hKey = RegCreate (hNewKey, pszSubKey, dwRights); +} + +/* load data of any type */ +bool CReg::LoadVal (LPCTSTR pszValName, RegVal *pValData) +{ + return RegLoadVal (hKey, NULL, pszValName, pValData); +} + +/* load data of any type from subkey */ +bool CReg::LoadVal (LPCTSTR pszSubKey, LPCTSTR pszValName, RegVal *pValData) +{ + return RegLoadVal (hKey, pszSubKey, pszValName, pValData); +} + +/* load a number */ +bool CReg::LoadNumber (LPCTSTR pszValName, DWORD *pdwNumber) +{ + return RegLoadNumber (hKey, NULL, pszValName, pdwNumber); +} + +/* load a number from subkey */ +bool CReg::LoadNumber (LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD *pdwNumber) +{ + return RegLoadNumber (hKey, pszSubKey, pszValName, pdwNumber); +} + +/* load binary data */ +bool CReg::LoadBinary (LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize) +{ + return RegLoadBinary (hKey, NULL, pszValName, pbyteData, dwSize); +} + +/* load binary data from subkey */ +bool CReg::LoadBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize) +{ + return RegLoadBinary (hKey, pszSubKey, pszValName, pbyteData, dwSize); +} + +/* load new binary data */ +bool CReg::LoadNewBinary (LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize) +{ + return RegLoadNewBinary (hKey, NULL, pszValName, pbyteData, pdwSize); +} + +/* load new binary data from subkey */ +bool CReg::LoadNewBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize) +{ + return RegLoadNewBinary (hKey, pszSubKey, pszValName, pbyteData, pdwSize); +} + +/* load a string */ +bool CReg::LoadString (LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength) +{ + return RegLoadString (hKey, NULL, pszValName, pszString, dwLength); +} + +/* load a string from subkey */ +bool CReg::LoadString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength) +{ + return RegLoadString (hKey, pszSubKey, pszValName, pszString, dwLength); +} + +/* load a new string */ +bool CReg::LoadNewString (LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength) +{ + return RegLoadNewString (hKey, NULL, pszValName, pszString, pdwLength); +} + +/* load a new string from subkey */ +bool CReg::LoadNewString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength) +{ + return RegLoadNewString (hKey, pszSubKey, pszValName, pszString, pdwLength); +} + +/* load an array of strings */ +bool CReg::LoadStringArr (LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount) +{ + return RegLoadStringArr (hKey, NULL, pszValName, pszStrings, dwCount); +} + +/* load an array of strings from subkey */ +bool CReg::LoadStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount) +{ + return RegLoadStringArr (hKey, pszSubKey, pszValName, pszStrings, dwCount); +} + +/* load a new array of strings */ +bool CReg::LoadNewStringArr (LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount) +{ + return RegLoadNewStringArr (hKey, NULL, pszValName, pszStrings, pdwCount); +} + +/* load a new array of strings from subkey */ +bool CReg::LoadNewStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount) +{ + return RegLoadNewStringArr (hKey, pszSubKey, pszValName, pszStrings, pdwCount); +} + +#ifdef REG_WITH_MFC + +/* load a string */ +bool CReg::LoadString (LPCTSTR pszValName, CString &sString) +{ + return RegLoadString (hKey, NULL, pszValName, sString); +} + +/* load a string from subkey */ +bool CReg::LoadString (LPCTSTR pszSubKey, LPCTSTR pszValName, CString &sString) +{ + return RegLoadString (hKey, pszSubKey, pszValName, sString); +} + +/* load an array of strings */ +bool CReg::LoadStringArr (LPCTSTR pszValName, CStringArray &arrString) +{ + return RegLoadStringArr (hKey, NULL, pszValName, arrString); +} + +/* load an array of strings from subkey */ +bool CReg::LoadStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, CStringArray &arrString) +{ + return RegLoadStringArr (hKey, pszSubKey, pszValName, arrString); +} + +#endif /* REG_WITH_MFC */ + +/* store data of any type */ +bool CReg::SaveVal (LPCTSTR pszValName, const RegVal *pValData) +{ + return RegSaveVal (hKey, NULL, pszValName, pValData); +} + +/* store data of any type to subkey */ +bool CReg::SaveVal (LPCTSTR pszSubKey, LPCTSTR pszValName, const RegVal *pValData) +{ + return RegSaveVal (hKey, pszSubKey, pszValName, pValData); +} + +/* store a number */ +bool CReg::SaveNumber (LPCTSTR pszValName, DWORD dwNumber) +{ + return RegSaveNumber (hKey, NULL, pszValName, dwNumber); +} + +/* store a number to subkey */ +bool CReg::SaveNumber (LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD dwNumber) +{ + return RegSaveNumber (hKey, pszSubKey, pszValName, dwNumber); +} + +/* store binary data */ +bool CReg::SaveBinary (LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize) +{ + return RegSaveBinary (hKey, NULL, pszValName, pbyteData, dwSize); +} + +/* store binary data to subkey */ +bool CReg::SaveBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize) +{ + return RegSaveBinary (hKey, pszSubKey, pszValName, pbyteData, dwSize); +} + +/* store a string */ +bool CReg::SaveString (LPCTSTR pszValName, LPCTSTR pszString) +{ + return RegSaveString (hKey, NULL, pszValName, pszString); +} + +/* store a string to subkey */ +bool CReg::SaveString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPCTSTR pszString) +{ + return RegSaveString (hKey, pszSubKey, pszValName, pszString); +} + +/* store an array of strings */ +bool CReg::SaveStringArr (LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount) +{ + return RegSaveStringArr (hKey, NULL, pszValName, pszStrings, dwCount); +} + +/* store an array of strings to subkey */ +bool CReg::SaveStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount) +{ + return RegSaveStringArr (hKey, pszSubKey, pszValName, pszStrings, dwCount); +} + +#ifdef REG_WITH_MFC + +/* store an array of strings */ +bool CReg::SaveStringArr (LPCTSTR pszValName, const CStringArray &arrString) +{ + return RegSaveStringArr (hKey, NULL, pszValName, arrString); +} + +/* store an array of strings to subkey */ +bool CReg::SaveStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, const CStringArray &arrString) +{ + return RegSaveStringArr (hKey, pszSubKey, pszValName, arrString); +} + +#endif /* REG_WITH_MFC */ + +/* delete the given value or key in the registry with all of its subkeys */ +bool CReg::DeleteKey (LPCTSTR pszValName) +{ + return RegDeleteKey (hKey, NULL, pszValName); +} + +/* delete the given value or key in the registry with all of its subkeys in subkey */ +bool CReg::DeleteKey (LPCTSTR pszSubKey, LPCTSTR pszValName) +{ + return RegDeleteKey (hKey, pszSubKey, pszValName); +} + +/* delete all of subkeys in the key */ +bool CReg::DeleteSubKeys () +{ + return RegDeleteSubKeys (hKey); +} + +/* check wether the given key has other subkeys and/or values */ +bool CReg::HasEntries (DWORD *pdwSubKeyCount, DWORD *pdwValueCount) +{ + return RegHasEntries (hKey, NULL, pdwSubKeyCount, pdwValueCount); +} + +/* check wether the given key has other subkeys and/or values in subkey */ +bool CReg::HasEntries (LPCTSTR pszSubKey, DWORD *pdwSubKeyCount, DWORD *pdwValueCount) +{ + return RegHasEntries (hKey, pszSubKey, pdwSubKeyCount, pdwValueCount); +} + +/* walks to the first value */ +bool CReg::FindFirstValue (LPCTSTR &ppszValue, RegVal *pValData) +{ + return RegFindFirstValue (hKey, &ppszValue, pValData); +} + +/* walks to the next value */ +bool CReg::FindNextValue (LPCTSTR &ppszValue, RegVal *pValData) +{ + return RegFindNextValue (hKey, &ppszValue, pValData); +} + +/* closes registry walking */ +void CReg::FindClose () +{ + RegFindClose (); +} + +#endif /* cplusplus */ + +/*////////////////////////////////////////////////////////////////////////////*/ +#pragma warning ( default : 4711 ) diff --git a/Src/editlib/registry.h b/Src/editlib/registry.h new file mode 100644 index 000000000..e023dcdbf --- /dev/null +++ b/Src/editlib/registry.h @@ -0,0 +1,411 @@ +/////////////////////////////////////////////////////////////////////////// +// File: registry.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl +// E-mail: prantl@ff.cuni.cz +// +// Some handy stuff to deal with Windows registry +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __REGISTRY_H__INCLUDED__ +#define __REGISTRY_H__INCLUDED__ + +/*////////////////////////////////////////////////////////////////////////////*/ + +#if (defined (__AFXWIN_H__) || defined (ARX_WITH_MFC)) && !defined (REG_WITH_MFC) +#define REG_WITH_MFC +#endif + +struct RegVal + { + DWORD dwType; + + union + { + DWORD dwNumber; + LPBYTE pbyteData; + LPTSTR pszString; + }; + union + { + DWORD dwSize; + DWORD dwLength; + }; + }; + +/* initializes registry value data */ +void EDITPADC_CLASS RegValInit (RegVal *pValData); + +/* frees registry value data */ +void EDITPADC_CLASS RegValFree (RegVal *pValData); + +/* get a number */ +bool EDITPADC_CLASS RegValGetNumber (const RegVal *pValData, DWORD *pdwNumber); + +/* get binary data */ +bool EDITPADC_CLASS RegValGetBinary (const RegVal *pValData, LPBYTE pbyteData, DWORD dwSize); + +/* get new binary data */ +bool EDITPADC_CLASS RegValGetNewBinary (const RegVal *pValData, LPBYTE *pbyteData, DWORD *pdwSize); + +/* get a string */ +bool EDITPADC_CLASS RegValGetString (const RegVal *pValData, LPTSTR pszString, DWORD dwLength); + +/* get a new string */ +bool EDITPADC_CLASS RegValGetNewString (const RegVal *pValData, LPTSTR *pszString, DWORD *pdwLength); + +/* get an array of strings */ +bool EDITPADC_CLASS RegValGetStringArr (const RegVal *pValData, LPTSTR pszStrings[], DWORD dwCount); + +/* get a new array of strings */ +bool EDITPADC_CLASS RegValGetNewStringArr (const RegVal *pValData, LPTSTR **pszStrings, DWORD *pdwCount); + +#ifdef REG_WITH_MFC + +/* get a string */ +bool EDITPADC_CLASS RegValGetString (const RegVal *pValData, CString &sString); + +/* get an array of strings */ +bool EDITPADC_CLASS RegValGetStringArr (const RegVal *pValData, CStringArray &arrString); + +#endif /* REG_WITH_MFC */ + +/* set a number */ +void EDITPADC_CLASS RegValSetNumber (RegVal *pValData, DWORD dwNumber); + +/* set binary data */ +bool EDITPADC_CLASS RegValSetBinary (RegVal *pValData, const LPBYTE pbyteData, DWORD dwSize); + +/* set a string */ +bool EDITPADC_CLASS RegValSetString (RegVal *pValData, LPCTSTR pszString); + +/* set an array of strings */ +bool EDITPADC_CLASS RegValSetStringArr (RegVal *pValData, const LPCTSTR pszStrings[], DWORD dwCount); + +#ifdef REG_WITH_MFC + +/* set an array of strings */ +bool EDITPADC_CLASS RegValSetStringArr (RegVal *pValData, const CStringArray &arrString); + +#endif /* REG_WITH_MFC */ + +/* connect to remote computer registry */ +HKEY EDITPADC_CLASS RegConnect (HKEY hKey, LPCTSTR pszRemote); + +/* open computer registry */ +HKEY EDITPADC_CLASS RegOpen (HKEY hKey, LPCTSTR pszSubKey, DWORD dwRights); + +/* close computer registry */ +void EDITPADC_CLASS RegClose (HKEY hKey); + +/* create computer registry */ +HKEY EDITPADC_CLASS RegCreate (HKEY hKey, LPCTSTR pszSubKey, DWORD dwRights); + +/* load data of any type */ +bool EDITPADC_CLASS RegLoadVal (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, RegVal *pValData); + +/* load a number */ +bool EDITPADC_CLASS RegLoadNumber (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD *pdwNumber); + +/* load binary data */ +bool EDITPADC_CLASS RegLoadBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize); + +/* load new binary data */ +bool EDITPADC_CLASS RegLoadNewBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize); + +/* load a string */ +bool EDITPADC_CLASS RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength); + +/* load a new string */ +bool EDITPADC_CLASS RegLoadNewString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength); + +/* load an array of strings */ +bool EDITPADC_CLASS RegLoadStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount); + +/* load a new array of strings */ +bool EDITPADC_CLASS RegLoadNewStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount); + +#ifdef REG_WITH_MFC + +/* load a string */ +bool EDITPADC_CLASS RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, CString &sString); + +/* load an array of strings */ +bool EDITPADC_CLASS RegLoadStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, CStringArray &arrString); + +#endif /* REG_WITH_MFC */ + +/* store data of any type */ +bool EDITPADC_CLASS RegSaveVal (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const RegVal *pValData); + +/* store a number */ +bool EDITPADC_CLASS RegSaveNumber (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD dwNumber); + +/* store binary data */ +bool EDITPADC_CLASS RegSaveBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize); + +/* store a string */ +bool EDITPADC_CLASS RegSaveString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPCTSTR pszString); + +/* store an array of strings */ +bool EDITPADC_CLASS RegSaveStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount); + +#ifdef REG_WITH_MFC + +/* store an array of strings */ +bool EDITPADC_CLASS RegSaveStringArr (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, const CStringArray &arrString); + +#endif /* REG_WITH_MFC */ + +/* delete the given value or key in the registry with all of its subkeys */ +bool EDITPADC_CLASS RegDeleteKey (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName); + +/* check wether the given key has other subkeys and/or values */ +bool EDITPADC_CLASS RegHasEntries (HKEY hKey, LPCTSTR pszSubKey, DWORD *pdwSubKeyCount, DWORD *pdwValueCount); + +/* walks to the first value */ +bool RegFindFirstValue (HKEY hKey, LPCTSTR *ppszValue, RegVal *pValData); + +/* walks to the next value */ +bool RegFindNextValue (HKEY hKey, LPCTSTR *ppszValue, RegVal *pValData); + +/* closes registry walking */ +void RegFindClose (); + +/*////////////////////////////////////////////////////////////////////////////*/ + +#ifdef __cplusplus + +struct EDITPADC_CLASS CRegVal : public RegVal + { + /* constructor - automatically initializes registry value data */ + CRegVal (); + + /* destructor - automatically frees registry value data */ + ~CRegVal (); + + /* initializes registry value data */ + void Init (); + + /* frees registry value data */ + void Free (); + + /* get a number */ + bool GetNumber (DWORD *pdwNumber) const; + + /* get binary data */ + bool GetBinary (LPBYTE pbyteData, DWORD dwSize) const; + + /* get new binary data */ + bool GetNewBinary (LPBYTE *pbyteData, DWORD *pdwSize) const; + + /* get a string */ + bool GetString (LPTSTR pszString, DWORD dwLength) const; + + /* get a new string */ + bool GetNewString (LPTSTR *pszString, DWORD *pdwLength) const; + + /* get an array of strings */ + bool GetStringArr (LPTSTR pszStrings[], DWORD dwCount) const; + + /* get a new array of strings */ + bool GetNewStringArr (LPTSTR **pszStrings, DWORD *pdwCount) const; + + #ifdef REG_WITH_MFC + + /* get a string */ + bool GetString (CString &sString) const; + + /* get an array of strings */ + bool GetStringArr (CStringArray &arrString) const; + + #endif /* REG_WITH_MFC */ + + /* set a number */ + void SetNumber (DWORD dwNumber); + + /* set binary data */ + bool SetBinary (const LPBYTE pbyteData, DWORD dwSize); + + /* set a string */ + bool SetString (LPCTSTR pszString); + + /* set an array of strings */ + bool SetStringArr (const LPCTSTR pszStrings[], DWORD dwCount); + + #ifdef REG_WITH_MFC + + /* set an array of strings */ + bool SetStringArr (const CStringArray &arrString); + + #endif /* REG_WITH_MFC */ + }; + +struct EDITPADC_CLASS CReg + { + HKEY hKey; + + /* constructor - automatically initializes registry data */ + CReg (); + + /* destructor - automatically frees registry data */ + ~CReg (); + + /* connect to remote computer registry */ + HKEY Connect (HKEY hNewKey, LPCTSTR pszRemote); + + /* connect to registry key */ + HKEY Open (HKEY hNewKey = NULL); + + /* open computer registry */ + HKEY Open (HKEY hNewKey, LPCTSTR pszSubKey, DWORD dwRights); + + /* close computer registry */ + void Close (); + + /* create computer registry */ + HKEY Create (HKEY hNewKey, LPCTSTR pszSubKey, DWORD dwRights); + + /* load data of any type */ + bool LoadVal (LPCTSTR pszValName, RegVal *pValData); + + /* load data of any type from subkey */ + bool LoadVal (LPCTSTR pszSubKey, LPCTSTR pszValName, RegVal *pValData); + + /* load a number */ + bool LoadNumber (LPCTSTR pszValName, DWORD *pdwNumber); + + /* load a number from subkey */ + bool LoadNumber (LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD *pdwNumber); + + /* load binary data */ + bool LoadBinary (LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize); + + /* load binary data from subkey */ + bool LoadBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize); + + /* load new binary data */ + bool LoadNewBinary (LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize); + + /* load new binary data from subkey */ + bool LoadNewBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize); + + /* load a string */ + bool LoadString (LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength); + + /* load a string from subkey */ + bool LoadString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength); + + /* load a new string */ + bool LoadNewString (LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength); + + /* load a new string from subkey */ + bool LoadNewString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength); + + /* load an array of strings */ + bool LoadStringArr (LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount); + + /* load an array of strings from subkey */ + bool LoadStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszStrings[], DWORD dwCount); + + /* load a new array of strings */ + bool LoadNewStringArr (LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount); + + /* load a new array of strings from subkey */ + bool LoadNewStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR **pszStrings, DWORD *pdwCount); + + #ifdef REG_WITH_MFC + + /* load a string */ + bool LoadString (LPCTSTR pszValName, CString &sString); + + /* load a string from subkey */ + bool LoadString (LPCTSTR pszSubKey, LPCTSTR pszValName, CString &sString); + + /* load an array of strings */ + bool LoadStringArr (LPCTSTR pszValName, CStringArray &arrString); + + /* load an array of strings from subkey */ + bool LoadStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, CStringArray &arrString); + + #endif /* REG_WITH_MFC */ + + /* store data of any type */ + bool SaveVal (LPCTSTR pszValName, const RegVal *pValData); + + /* store data of any type to subkey */ + bool SaveVal (LPCTSTR pszSubKey, LPCTSTR pszValName, const RegVal *pValData); + + /* store a number */ + bool SaveNumber (LPCTSTR pszValName, DWORD dwNumber); + + /* store a number to subkey */ + bool SaveNumber (LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD dwNumber); + + /* store binary data */ + bool SaveBinary (LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize); + + /* store binary data to subkey */ + bool SaveBinary (LPCTSTR pszSubKey, LPCTSTR pszValName, const LPBYTE pbyteData, DWORD dwSize); + + /* store a string */ + bool SaveString (LPCTSTR pszValName, LPCTSTR pszString); + + /* store a string to subkey */ + bool SaveString (LPCTSTR pszSubKey, LPCTSTR pszValName, LPCTSTR pszString); + + /* store an array of strings */ + bool SaveStringArr (LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount); + + /* store an array of strings to subkey */ + bool SaveStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, const LPCTSTR pszStrings[], DWORD dwCount); + + #ifdef REG_WITH_MFC + + /* store an array of strings */ + bool SaveStringArr (LPCTSTR pszValName, const CStringArray &arrString); + + /* store an array of strings to subkey */ + bool SaveStringArr (LPCTSTR pszSubKey, LPCTSTR pszValName, const CStringArray &arrString); + + #endif /* REG_WITH_MFC */ + + /* delete the given value or key in the registry with all of its subkeys */ + bool DeleteKey (LPCTSTR pszValName); + + /* delete the given value or key in the registry with all of its subkeys in subkey */ + bool DeleteKey (LPCTSTR pszSubKey, LPCTSTR pszValName); + + /* delete all of subkeys in the key */ + bool DeleteSubKeys (); + + /* check wether the given key has other subkeys and/or values */ + bool HasEntries (DWORD *pdwSubKeyCount, DWORD *pdwValueCount); + + /* check wether the given key has other subkeys and/or values in subkey */ + bool HasEntries (LPCTSTR pszSubKey, DWORD *pdwSubKeyCount, DWORD *pdwValueCount); + + /* walks to the first value */ + bool FindFirstValue (LPCTSTR &ppszValue, RegVal *pValData); + + /* walks to the next value */ + bool FindNextValue (LPCTSTR &ppszValue, RegVal *pValData); + + /* closes registry walking */ + void FindClose (); + }; + +#endif /* cplusplus */ + +bool EDITPADC_CLASS RegDeleteSubKeys (HKEY hKey); + +/*////////////////////////////////////////////////////////////////////////////*/ + +#endif /* __REGISTRY_H__INCLUDED__ */ diff --git a/Src/editlib/rexx.cpp b/Src/editlib/rexx.cpp new file mode 100644 index 000000000..9df41c572 --- /dev/null +++ b/Src/editlib/rexx.cpp @@ -0,0 +1,393 @@ +/////////////////////////////////////////////////////////////////////////// +// File: rexx.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// REXX syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszRexxKeywordList[] = + { + _T ("ADDRESS"), + _T ("ARG"), + _T ("CALL"), + _T ("DO"), + _T ("DROP"), + _T ("EXIT"), + _T ("IF"), + _T ("INTERPRET"), + _T ("ITERATE"), + _T ("LEAVE"), + _T ("NOP"), + _T ("NUMERIC"), + _T ("OPTIONS"), + _T ("PARSE"), + _T ("PROCEDURE"), + _T ("PULL"), + _T ("PUSH"), + _T ("QUEUE"), + _T ("RETURN"), + _T ("SAY"), + _T ("SELECT"), + _T ("OTHERWISE"), + _T ("SIGNAL"), + _T ("TRACE"), + _T ("END"), + _T ("WHEN"), + _T ("ELSE"), + _T ("WITH"), + _T ("TO"), + _T ("BY"), + _T ("ON"), + _T ("END"), + _T ("FOR"), + _T ("OFF"), + _T ("VAR"), + _T ("THEN"), + _T ("HALT"), + _T ("NAME"), + _T ("FORM"), + _T ("FUZZ"), + _T ("VALUE"), + _T ("WHILE"), + _T ("UNTIL"), + _T ("ERROR"), + _T ("UPPER"), + _T ("WITH"), + _T ("EXPOSE"), + _T ("DIGITS"), + _T ("FOREVER"), + _T ("FAILURE"), + _T ("VERSION"), + _T ("NOVALUE"), + _T ("SOURCE"), + _T ("SYNTAX"), + _T ("NOTREADY"), + _T ("SCIENTIFIC"), + _T ("ENGINEERING"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("METHOD"), + _T ("CLASS"), + _T ("NULL"), + _T ("LOOP"), + _T ("CATCH"), + _T ("RETURNS"), + _T ("EXTENDS"), + _T ("IMPLEMENTS"), + _T ("CHAR"), + _T ("BOOLEAN"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsRexxKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszRexxKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsRexxNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineRexx (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsRexxKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsRexxNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsRexxKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsRexxNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/rsrc.cpp b/Src/editlib/rsrc.cpp new file mode 100644 index 000000000..ae7e6c775 --- /dev/null +++ b/Src/editlib/rsrc.cpp @@ -0,0 +1,355 @@ +/////////////////////////////////////////////////////////////////////////// +// File: rsrc.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Windows resources syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszRsrcKeywordList[] = + { + _T ("MENU"), + _T ("POPUP"), + _T ("MENUITEM"), + _T ("SEPARATOR"), + _T ("BEGIN"), + _T ("END"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("VK_F1"), + _T ("VK_F2"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsRsrcKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszRsrcKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsRsrcNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineRsrc (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || pszChars[I - 1] != '\\')) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Preprocessor directive #.... + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + continue; + } + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsRsrcKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsRsrcNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsRsrcKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsRsrcNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/sgml.cpp b/Src/editlib/sgml.cpp new file mode 100644 index 000000000..e46a39f3a --- /dev/null +++ b/Src/editlib/sgml.cpp @@ -0,0 +1,551 @@ +/////////////////////////////////////////////////////////////////////////// +// File: sgml.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// SGML syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszSgmlKeywordList[] = + { + _T ("ABSTRACT"), + _T ("ARTICLE"), + _T ("AUTHOR"), + _T ("BF"), + _T ("BOOK"), + _T ("CHAPT"), + _T ("CODE"), + _T ("COPYRIGHT"), + _T ("DATE"), + _T ("DEBIANDOC"), + _T ("DESCRIP"), + _T ("DOCTYPE"), + _T ("EM"), + _T ("EMAIL"), + _T ("ENUM"), + _T ("ENUMLIST"), + _T ("EXAMPLE"), + _T ("FOOTNOTE"), + _T ("FTPSITE"), + _T ("FTPPATH"), + _T ("HEADING"), + _T ("HTMLURL"), + _T ("HTTPSITE"), + _T ("HTTPPATH"), + _T ("IT"), + _T ("ITEM"), + _T ("ITEMIZE"), + _T ("LABEL"), + _T ("LIST"), + _T ("MANREF"), + _T ("NAME"), + _T ("P"), + _T ("PRGN"), + _T ("PUBLIC"), + _T ("QREF"), + _T ("QUOTE"), + _T ("REF"), + _T ("SECT"), + _T ("SECT1"), + _T ("SECT2"), + _T ("SECT3"), + _T ("SECT4"), + _T ("STRONG"), + _T ("SYSTEM"), + _T ("TAG"), + _T ("TAGLIST"), + _T ("TITLE"), + _T ("TITLEPAG"), + _T ("TOC"), + _T ("TSCREEN"), + _T ("TT"), + _T ("URL"), + _T ("VAR"), + _T ("VERB"), + _T ("VERSION"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("COMPACT"), + _T ("ID"), + _T ("NAME"), + _T ("SECTION"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T ("nbsp"), + _T ("quot"), + _T ("amp"), + _T ("lt"), + _T ("lt"), + _T ("gt"), + _T ("copy"), + _T ("reg"), + _T ("acute"), + _T ("laquo"), + _T ("raquo"), + _T ("iexcl"), + _T ("iquest"), + _T ("Agrave"), + _T ("agrave"), + _T ("Aacute"), + _T ("aacute"), + _T ("Acirc"), + _T ("acirc"), + _T ("Atilde"), + _T ("atilde"), + _T ("Auml"), + _T ("auml"), + _T ("Aring"), + _T ("aring"), + _T ("AElig"), + _T ("aelig"), + _T ("Ccedil"), + _T ("ccedil"), + _T ("ETH"), + _T ("eth"), + _T ("Egrave"), + _T ("egrave"), + _T ("Eacute"), + _T ("eacute"), + _T ("Ecirc"), + _T ("ecirc"), + _T ("Euml"), + _T ("euml"), + _T ("Igrave"), + _T ("igrave"), + _T ("Iacute"), + _T ("iacute"), + _T ("Icirc"), + _T ("icirc"), + _T ("Iuml"), + _T ("iuml"), + _T ("Ntilde"), + _T ("ntilde"), + _T ("Ograve"), + _T ("ograve"), + _T ("Oacute"), + _T ("oacute"), + _T ("Ocirc"), + _T ("ocirc"), + _T ("Otilde"), + _T ("otilde"), + _T ("Ouml"), + _T ("ouml"), + _T ("Oslash"), + _T ("oslash"), + _T ("Ugrave"), + _T ("ugrave"), + _T ("Uacute"), + _T ("uacute"), + _T ("Ucirc"), + _T ("ucirc"), + _T ("Uuml"), + _T ("uuml"), + _T ("Yacute"), + _T ("yacute"), + _T ("yuml"), + _T ("THORN"), + _T ("thorn"), + _T ("szlig"), + _T ("sect"), + _T ("para"), + _T ("micro"), + _T ("brvbar"), + _T ("plusmn"), + _T ("middot"), + _T ("uml"), + _T ("cedil"), + _T ("ordf"), + _T ("ordm"), + _T ("not"), + _T ("shy"), + _T ("macr"), + _T ("deg"), + _T ("sup1"), + _T ("sup2"), + _T ("sup3"), + _T ("frac14"), + _T ("frac12"), + _T ("frac34"), + _T ("times"), + _T ("divide"), + _T ("cent"), + _T ("pound"), + _T ("curren"), + _T ("yen"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsSgmlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszSgmlKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsSgmlNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 +#define COOKIE_USER1 0x0020 +#define COOKIE_EXT_USER1 0x0040 + +DWORD CCrystalTextView:: +ParseLineSgml (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else if (dwCookie & COOKIE_PREPROCESSOR) + { + DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_COMMENT) + { + if (I > 1 && pszChars[I] == '>' && pszChars[I - 1] == '-' && pszChars[I - 2] == '-') + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment + if (dwCookie & COOKIE_EXT_USER1) + { + if (I > 0 && pszChars[I] == '>' && pszChars[I - 1] == '?') + { + dwCookie &= ~COOKIE_EXT_USER1; + bRedefineBlock = TRUE; + } + continue; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + I += 3; + dwCookie |= COOKIE_EXT_COMMENT; + dwCookie &= ~COOKIE_PREPROCESSOR; + continue; + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (IsSgmlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsSgmlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + goto next; + } + } + else if (dwCookie & COOKIE_USER1) + { + if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else + { + goto next; + } + } + else if (IsSgmlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + goto next; + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; +next: + ; + } + // Preprocessor start: < or bracket + if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') || pszChars[I] == '{') + { + DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: > or bracket + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>' || pszChars[I] == '}') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + bRedefineBlock = TRUE; + bDecIndex = TRUE; + continue; + } + } + // Preprocessor start: & + if (pszChars[I] == '&') + { + dwCookie |= COOKIE_USER1; + nIdentBegin = -1; + continue; + } + + // Preprocessor end: ; + if (dwCookie & COOKIE_USER1) + { + if (pszChars[I] == ';') + { + dwCookie &= ~COOKIE_USER1; + nIdentBegin = -1; + continue; + } + } + } + } + + if (nIdentBegin >= 0 && (dwCookie & COOKIE_PREPROCESSOR)) + { + if (IsSgmlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsSgmlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + } + // Preprocessor start: < or { + if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') || pszChars[I] == '{') + { + DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR); + dwCookie |= COOKIE_PREPROCESSOR; + nIdentBegin = -1; + goto end; + } + + // Preprocessor end: > or } + if (dwCookie & COOKIE_PREPROCESSOR) + { + if (pszChars[I] == '>' || pszChars[I] == '}') + { + dwCookie &= ~COOKIE_PREPROCESSOR; + nIdentBegin = -1; + } + } +end: + dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_PREPROCESSOR | COOKIE_EXT_USER1); + return dwCookie; +} diff --git a/Src/editlib/sh.cpp b/Src/editlib/sh.cpp new file mode 100644 index 000000000..85435cb5d --- /dev/null +++ b/Src/editlib/sh.cpp @@ -0,0 +1,339 @@ +/////////////////////////////////////////////////////////////////////////// +// File: sh.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// UNIX shell script syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszShKeywordList[] = + { + _T ("case"), + _T ("do"), + _T ("done"), + _T ("elif"), + _T ("else"), + _T ("esac"), + _T ("fi"), + _T ("for"), + _T ("function"), + _T ("if"), + _T ("in"), + _T ("then"), + _T ("until"), + _T ("while"), + _T ("exec"), + _T ("export"), + _T ("set"), + _T ("echo"), + _T ("exit"), + _T ("select"), + _T ("source"), + _T ("unset"), + _T ("alias"), + _T ("unalias"), + _T ("shift"), + _T ("break"), + _T ("read"), + _T ("return"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("ls"), + _T ("pwd"), + _T ("chown"), + _T ("chmod"), + _T ("logout"), + _T ("ssh"), + _T ("telnet"), + _T ("who"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsShKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszShKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsShNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineSh (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsShKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsShNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsShKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsShNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/siod.cpp b/Src/editlib/siod.cpp new file mode 100644 index 000000000..c23a0b4b5 --- /dev/null +++ b/Src/editlib/siod.cpp @@ -0,0 +1,670 @@ +/////////////////////////////////////////////////////////////////////////// +// File: siod.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// SIOD syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszSiodKeywordList[] = + { + _T("abs"), + _T("alarm"), + _T("and"), + _T("append"), + _T("apply"), + _T("ass"), + _T("assoc"), + _T("assq"), + _T("assv"), + _T("base64decode"), + _T("base64encode"), + _T("begin"), + _T("caaar"), + _T("caadr"), + _T("caar"), + _T("cadar"), + _T("caddr"), + _T("cadr"), + _T("car"), + _T("cdaar"), + _T("cdadr"), + _T("cdar"), + _T("cddar"), + _T("cdddr"), + _T("cddr"), + _T("cdr"), + _T("cond"), + _T("cons-array"), + _T("define"), + _T("eq?"), + _T("equal?"), + _T("eqv?"), + _T("eval"), + _T("exec"), + _T("exit"), + _T("fclose"), + _T("fopen"), + _T("if"), + _T("lambda"), + _T("length"), + _T("let"), + _T("let*"), + _T("letrec"), + _T("list"), + _T("load"), + _T("max"), + _T("min"), + _T("member"), + _T("memq"), + _T("memv"), + _T("nil"), + _T("not"), + _T("null?"), + _T("number?"), + _T("number->string"), + _T("or"), + _T("pair?"), + _T("quit"), + _T("quote"), + _T("set!"), + _T("set-car!"), + _T("set-cdr!"), + _T("string->number"), + _T("string-length"), + _T("string?"), + _T("string-append"), + _T("substring"), + _T("symbol?"), + _T("read"), + _T("reverse"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T("acos"), + _T("asin"), + _T("atan"), + _T("cos"), + _T("exp"), + _T("log"), + _T("sin"), + _T("tan"), + _T("sqrt"), + NULL + }; + +static LPTSTR s_apszUser2KeywordList[] = + { + _T("%%%memref"), + _T("%%closure"), + _T("%%closure-code"), + _T("%%closure-env"), + _T("%%stack-limit"), + _T("*after-gc*"), + _T("*args*"), + _T("*catch"), + _T("*env*"), + _T("*eval-history-ptr*"), + _T("*pi*"), + _T("*plists*"), + _T("*throw"), + _T("*traced*"), + _T("F_GETLK"), + _T("F_SETLK"), + _T("F_SETLKW"), + _T("access-problem?"), + _T("allocate-heap"), + _T("apropos"), + _T("aref"), + _T("array->hexstr"), + _T("aset"), + _T("ash"), + _T("atan2"), + _T("benchmark-eval"), + _T("benchmark-funcall1"), + _T("benchmark-funcall2"), + _T("bit-and"), + _T("bit-not"), + _T("bit-or"), + _T("bit-xor"), + _T("butlast"), + _T("bytes-append"), + _T("chdir"), + _T("chmod"), + _T("chown"), + _T("closedir"), + _T("copy-list"), + _T("cpu-usage-limits"), + _T("crypt"), + _T("current-resource-usage"), + _T("datlength"), + _T("datref"), + _T("decode-file-mode"), + _T("delete-file"), + _T("delq"), + _T("encode-file-mode"), + _T("encode-open-flags"), + _T("endpwent"), + _T("env-lookup"), + _T("eof-val"), + _T("errobj"), + _T("error"), + _T("fast-load"), + _T("fast-print"), + _T("fast-read"), + _T("fast-save"), + _T("fchmod"), + _T("fflush"), + _T("file-times"), + _T("first"), + _T("fmod"), + _T("fnmatch"), + _T("fork"), + _T("fread"), + _T("fseek"), + _T("fstat"), + _T("ftell"), + _T("fwrite"), + _T("gc"), + _T("gc-info"), + _T("gc-status"), + _T("get"), + _T("getc"), + _T("getcwd"), + _T("getenv"), + _T("getgid"), + _T("getgrgid"), + _T("getpass"), + _T("getpgrp"), + _T("getpid"), + _T("getppid"), + _T("getpwent"), + _T("getpwnam"), + _T("getpwuid"), + _T("gets"), + _T("getuid"), + _T("gmtime"), + _T("hexstr->bytes"), + _T("href"), + _T("hset"), + _T("html-encode"), + _T("intern"), + _T("kill"), + _T("larg-default"), + _T("last"), + _T("last-c-error"), + _T("lchown"), + _T("link"), + _T("lkey-default"), + _T("load-so"), + _T("localtime"), + _T("lref-default"), + _T("lstat"), + _T("make-list"), + _T("mapcar"), + _T("md5-final"), + _T("md5-init"), + _T("md5-update"), + _T("mkdatref"), + _T("mkdir"), + _T("mktime"), + _T("nconc"), + _T("nice"), + _T("nreverse"), + _T("nth"), + _T("opendir"), + _T("os-classification"), + _T("parse-number"), + _T("pclose"), + _T("popen"), + _T("pow"), + _T("prin1"), + _T("print"), + _T("print-to-string"), + _T("prog1"), + _T("putc"), + _T("putenv"), + _T("putprop"), + _T("puts"), + _T("qsort"), + _T("rand"), + _T("random"), + _T("read-from-string"), + _T("readdir"), + _T("readline"), + _T("readlink"), + _T("realtime"), + _T("rename"), + _T("require"), + _T("require-so"), + _T("rest"), + _T("rld-pathnames"), + _T("rmdir"), + _T("runtime"), + _T("save-forms"), + _T("sdatref"), + _T("set-eval-history"), + _T("set-symbol-value!"), + _T("setprop"), + _T("setpwent"), + _T("setuid"), + _T("siod-lib"), + _T("sleep"), + _T("so-ext"), + _T("srand"), + _T("srandom"), + _T("stat"), + _T("strbreakup"), + _T("strcat"), + _T("strcmp"), + _T("strcpy"), + _T("strcspn"), + _T("strftime"), + _T("string-dimension"), + _T("string-downcase"), + _T("string-lessp"), + _T("string-search"), + _T("string-trim"), + _T("string-trim-left"), + _T("string-trim-right"), + _T("string-upcase"), + _T("strptime"), + _T("strspn"), + _T("subset"), + _T("substring-equal?"), + _T("swrite"), + _T("sxhash"), + _T("symbol-bound?"), + _T("symbol-value"), + _T("symbolconc"), + _T("symlink"), + _T("system"), + _T("t"), + _T("the-environment"), + _T("trace"), + _T("trunc"), + _T("typeof"), + _T("unbreakupstr"), + _T("ungetc"), + _T("unix-ctime"), + _T("unix-time"), + _T("unix-time->strtime"), + _T("unlink"), + _T("untrace"), + _T("url-decode"), + _T("url-encode"), + _T("utime"), + _T("verbose"), + _T("wait"), + _T("while"), + _T("writes"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsSiodKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszSiodKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsUser2Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser2KeywordList, pszChars, nLength); +} + +static BOOL +IsSiodNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineSiod (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + BOOL bDefun = FALSE; + + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == ';' && pszChars[I - 1] == '|') + if ((I > 1 && pszChars[I] == ';' && pszChars[I - 1] == '|' /*&& pszChars[I - 2] != ';'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == ';' && pszChars[I - 1] == '|')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] != '|' && pszChars[I - 1] == ';') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '|' && pszChars[I - 1] == ';') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsSiodKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5)) + { + bDefun = TRUE; + } + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsSiodNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bDefun) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsSiodKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5)) + { + bDefun = TRUE; + } + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2); + } + else if (IsSiodNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bDefun) + { + for (int j = nIdentBegin; --j >= 0;) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/splash.cpp b/Src/editlib/splash.cpp new file mode 100644 index 000000000..173a52746 --- /dev/null +++ b/Src/editlib/splash.cpp @@ -0,0 +1,116 @@ +#include "stdafx.h" +#include "editcmd.h" +#include "splash.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char BASED_CODE THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSplashWnd dialog + +BOOL CSplashWnd::Create(CWnd* pParent) +{ + //{{AFX_DATA_INIT(CSplashWnd) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + + if (!CDialog::Create(CSplashWnd::IDD, pParent)) + { + TRACE0("Warning: creation of CSplashWnd dialog failed\n"); + return FALSE; + } + + return TRUE; +} + +BOOL CSplashWnd::OnInitDialog() +{ + CDialog::OnInitDialog(); + CenterWindow(); + + // initialize the big icon control + m_icon.SubclassDlgItem(IDC_BIGICON, this); + m_icon.SizeToContent(); + + return TRUE; // return TRUE unless you set the focus to a control +} + +///////////////////////////////////////////////////////////////////////////// +// CSplashWnd message handlers + +///////////////////////////////////////////////////////////////////////////// +// CBigIcon + +BEGIN_MESSAGE_MAP(CBigIcon, CButton) + //{{AFX_MSG_MAP(CBigIcon) + ON_WM_DRAWITEM() + ON_WM_ERASEBKGND() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CBigIcon message handlers + +#define CY_SHADOW 4 +#define CX_SHADOW 4 + +void CBigIcon::SizeToContent() +{ + m_bitmap.LoadBitmap(IDB_BITMAP48); + BITMAP bm; + m_bitmap.GetObject(sizeof(bm), &bm); + m_sizeBitmap = CSize(bm.bmWidth, bm.bmHeight); + // get system icon size + + // a big icon should be twice the size of an icon + shadows + SetWindowPos(NULL, 0, 0, bm.bmWidth + CX_SHADOW + 4, bm.bmHeight + CY_SHADOW + 4, + SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); +} + +void CBigIcon::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); + ASSERT(pDC != NULL); + + CRect rect; + GetClientRect(rect); + int cxClient = rect.Width(); + int cyClient = rect.Height(); + + // draw border around icon + CPen pen; + pen.CreateStockObject(BLACK_PEN); + CPen* pPenOld = pDC->SelectObject(&pen); + pDC->Rectangle(0, 0, cxClient-CX_SHADOW, cyClient-CY_SHADOW); + if (pPenOld) + pDC->SelectObject(pPenOld); + + // draw shadows around icon + CBrush br; + br.CreateStockObject(DKGRAY_BRUSH); + rect.SetRect(cxClient-CX_SHADOW, CY_SHADOW, cxClient, cyClient); + pDC->FillRect(rect, &br); + rect.SetRect(CX_SHADOW, cyClient-CY_SHADOW, cxClient, cyClient); + pDC->FillRect(rect, &br); + + // draw the bitmap contents + CDC dcMem; + if (!dcMem.CreateCompatibleDC(pDC)) + return; + CBitmap* pBitmapOld = dcMem.SelectObject(&m_bitmap); + if (pBitmapOld == NULL) + return; + + pDC->BitBlt(2, 2, m_sizeBitmap.cx, m_sizeBitmap.cy, &dcMem, 0, 0, SRCCOPY); + + dcMem.SelectObject(pBitmapOld); +} + +BOOL CBigIcon::OnEraseBkgnd(CDC*) +{ + return TRUE; // we don't do any erasing... +} + +///////////////////////////////////////////////////////////////////////////// diff --git a/Src/editlib/splash.h b/Src/editlib/splash.h new file mode 100644 index 000000000..a85b214d7 --- /dev/null +++ b/Src/editlib/splash.h @@ -0,0 +1,55 @@ +#ifndef __SPLASH_H__INCLUDED__ +#define __SPLASH_H__INCLUDED__ + +///////////////////////////////////////////////////////////////////////////// +// CBigIcon window + +class EDITPADC_CLASS CBigIcon : public CButton +{ +// Attributes +public: + CBitmap m_bitmap; + CSize m_sizeBitmap; + +// Operations +public: + void SizeToContent(); + +// Implementation +protected: + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + + //{{AFX_MSG(CBigIcon) + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// CSplash dialog + +class EDITPADC_CLASS CSplashWnd : public CDialog +{ +// Construction +public: + BOOL Create(CWnd* pParent); + +// Dialog Data + //{{AFX_DATA(CSplashWnd) + enum { IDD = IDD_SPLASH }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + +// Implementation +protected: + CBigIcon m_icon; // self-draw button + + // Generated message map functions + //{{AFX_MSG(CSplashWnd) + virtual BOOL OnInitDialog(); + //}}AFX_MSG +}; + +///////////////////////////////////////////////////////////////////////////// + +#endif // __SPLASH_H__INCLUDED__ diff --git a/Src/editlib/sql.cpp b/Src/editlib/sql.cpp new file mode 100644 index 000000000..13793e03b --- /dev/null +++ b/Src/editlib/sql.cpp @@ -0,0 +1,353 @@ +/////////////////////////////////////////////////////////////////////////// +// File: sql.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// SQL syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszSqlKeywordList[] = + { + _T ("select"), + _T ("where"), + _T ("insert"), + _T ("into"), + _T ("update"), + _T ("from"), + _T ("in"), + _T ("order"), + _T ("by"), + _T ("and"), + _T ("or"), + _T ("not"), + _T ("union"), + _T ("distinct"), + _T ("join"), + _T ("all"), + _T ("group"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("CHAR"), + _T ("VARCHAR"), + _T ("INTEGER"), + _T ("REAL"), + _T ("DOUBLE"), + _T ("MEMO"), + _T ("BYTE"), + _T ("WORD"), + _T ("DATE"), + _T ("TIME"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsSqlKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszSqlKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsSqlNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineSql (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bWasCommentStart = FALSE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + // Extended comment /*....*/ + if (dwCookie & COOKIE_EXT_COMMENT) + { + // if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*') + if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*')) + { + dwCookie &= ~COOKIE_EXT_COMMENT; + bRedefineBlock = TRUE; + } + bWasCommentStart = FALSE; + continue; + } + + if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/') + { + DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT); + dwCookie |= COOKIE_EXT_COMMENT; + bWasCommentStart = TRUE; + continue; + } + + bWasCommentStart = FALSE; + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsSqlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsSqlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsSqlKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsSqlNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/statbar.cpp b/Src/editlib/statbar.cpp new file mode 100644 index 000000000..9c2572395 --- /dev/null +++ b/Src/editlib/statbar.cpp @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////// +// File: statbar.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Status bar extension +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "editcmd.h" +#include "statbar.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +CEditStatusBar::CEditStatusBar () + :CStatusBar (), m_strClockFormat (_T("%d.%m. %H:%M:%S")) +{ +} + +CEditStatusBar:: ~ CEditStatusBar () +{ +} + +BOOL CEditStatusBar:: +Create (CWnd * pParentWnd, DWORD dwStyle, UINT nID) +{ + BOOL bCreatedOK = CStatusBar::Create (pParentWnd, dwStyle, nID); + return bCreatedOK; +} + +BOOL CEditStatusBar:: +SetPaneFormattedText (int nIndex, BOOL bUpdate, LPCTSTR lpszFmt,...) +{ + TCHAR buffer[256]; + va_list argptr; + va_start (argptr, lpszFmt); + _vstprintf (buffer, lpszFmt, argptr); + va_end (argptr); + BOOL bResult = SetPaneText (nIndex, buffer, bUpdate); + UpdateWindow (); + return bResult; +} + +BOOL CEditStatusBar:: +SetPaneFormattedText (int nIndex, BOOL bUpdate, UINT nId,...) +{ + CString str; + if (str.LoadString (nId)) + { + va_list argptr; + va_start (argptr, nId); + BOOL bResult = SetPaneFormattedText (nIndex, bUpdate, str, argptr); + va_end (argptr); + return bResult; + } + SetPaneText (nIndex, _T (""), bUpdate); + return FALSE; +} + +BOOL CEditStatusBar:: +SetPaneText (int nIndex, LPCTSTR lpszNewText, BOOL bUpdate /*= TRUE*/ ) +{ + return CStatusBar::SetPaneText (nIndex, lpszNewText, bUpdate); +} + +BOOL CEditStatusBar:: +SetPaneText (int nIndex, UINT nId, BOOL bUpdate /*= TRUE*/ ) +{ + CString str; + if (str.LoadString (nId)) + return SetPaneText (nIndex, str, bUpdate); + SetPaneText (nIndex, _T (""), bUpdate); + return FALSE; +} + +void CEditStatusBar:: +SetClockFormat (LPCTSTR strClockFormat) +{ + m_strClockFormat = strClockFormat; +} + +IMPLEMENT_DYNCREATE (CEditStatusBar, CStatusBar) + +BEGIN_MESSAGE_MAP (CEditStatusBar, CStatusBar) +//{{AFX_MSG_MAP(CEditStatusBar) +ON_WM_CREATE () +ON_WM_DESTROY () +ON_UPDATE_COMMAND_UI (ID_INDICATOR_TIME, OnUpdateIndicatorTime) +//}}AFX_MSG_MAP +END_MESSAGE_MAP () + +int CEditStatusBar::OnCreate (LPCREATESTRUCT lpCreateStruct) +{ + // make sure time gets updated every second, even when idle + if (CStatusBar::OnCreate (lpCreateStruct) == -1) + return -1; + SetFont (CFont::FromHandle ((HFONT) GetStockObject (DEFAULT_GUI_FONT))); + SetTimer (ID_INDICATOR_TIME, 1000, NULL); + return 0; +} + +void CEditStatusBar:: +OnUpdateIndicatorTime (CCmdUI * pCmdUI) +{ + pCmdUI->Enable (true); + pCmdUI->SetText (CTime::GetCurrentTime ().Format (m_strClockFormat)); +} + +void CEditStatusBar:: +OnDestroy () +{ + KillTimer (ID_INDICATOR_TIME); + CStatusBar::OnDestroy (); +} diff --git a/Src/editlib/statbar.h b/Src/editlib/statbar.h new file mode 100644 index 000000000..4410163e1 --- /dev/null +++ b/Src/editlib/statbar.h @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////// +// File: statbar.h +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// Status bar extension +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#ifndef __STATBAR_H__INCLUDED__ +#define __STATBAR_H__INCLUDED__ + +class EDITPADC_CLASS CEditStatusBar : public CStatusBar + { + DECLARE_DYNCREATE (CEditStatusBar) +public : + CEditStatusBar (); + ~CEditStatusBar (); + virtual BOOL Create (CWnd * pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR); + +protected : + CString m_strClockFormat; + +public : + BOOL SetPaneFormattedText (int nIndex, BOOL bUpdate, LPCTSTR lpszFmt,...); + BOOL SetPaneFormattedText (int nIndex, BOOL bUpdate, UINT nId,...); + BOOL SetPaneText (int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE); + BOOL SetPaneText (int nIndex, UINT nId, BOOL bUpdate = TRUE); + void SetClockFormat (LPCTSTR strClockFormat); + + // Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEditStatusBar) + //}}AFX_VIRTUAL + + // Generated message map functions + //{{AFX_MSG(CEditStatusBar) + afx_msg void OnDestroy (); + afx_msg void OnUpdateIndicatorTime (CCmdUI * pCmdUI); + afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP () + }; + +#endif // __STATBAR_H__INCLUDED__ diff --git a/Src/editlib/tcl.cpp b/Src/editlib/tcl.cpp new file mode 100644 index 000000000..30547037c --- /dev/null +++ b/Src/editlib/tcl.cpp @@ -0,0 +1,298 @@ +/////////////////////////////////////////////////////////////////////////// +// File: tcl.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// TCL syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszTclKeywordList[] = + { + _T ("case"), + _T ("do"), + _T ("done"), + _T ("elif"), + _T ("else"), + _T ("esac"), + _T ("fi"), + _T ("for"), + _T ("function"), + _T ("if"), + _T ("in"), + _T ("then"), + _T ("until"), + _T ("while"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsTclKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszTclKeywordList, pszChars, nLength); +} + +static BOOL +IsTclNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineTcl (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1]))) + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '#') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1]))) + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsTclKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsTclNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsTclKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsTclNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + for (int j = I; j < nLength; j++) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '(') + { + bFunction = TRUE; + } + break; + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + if (pszChars[nLength - 1] != '\\') + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/tex.cpp b/Src/editlib/tex.cpp new file mode 100644 index 000000000..6dc079f5c --- /dev/null +++ b/Src/editlib/tex.cpp @@ -0,0 +1,1133 @@ +/////////////////////////////////////////////////////////////////////////// +// File: tex.cpp +// Version: 1.1.0.4 +// Updated: 19-Jul-1998 +// +// Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei +// E-mail: prantl@ff.cuni.cz +// +// TEX syntax highlighing definition +// +// You are free to use or modify this code to the following restrictions: +// - Acknowledge me somewhere in your about box, simple "Parts of code by.." +// will be enough. If you can't (or don't want to), contact me personally. +// - LEAVE THIS HEADER INTACT +//////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ccrystaltextview.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// C++ keywords (MSVC5.0 + POET5.0) +static LPTSTR s_apszTexKeywordList[] = + { + _T ("documentstyle"), + _T ("document"), + _T ("documentclass"), + _T ("pagestyle"), + _T ("pagenumbering"), + _T ("thispagestyle"), + _T ("title"), + _T ("author"), + _T ("date"), + _T ("maketitle"), + _T ("begin"), + _T ("end"), + _T ("part"), + _T ("chapter"), + _T ("section"), + _T ("subsection"), + _T ("subsubsection"), + _T ("paragraph"), + _T ("subparagraph"), + _T ("appendix"), + _T ("tableofcontents"), + _T ("listoffigures"), + _T ("listoftables"), + _T ("rm"), + _T ("em"), + _T ("bf"), + _T ("sc"), + _T ("it"), + _T ("sl"), + _T ("sf"), + _T ("tt"), + _T ("tiny"), + _T ("scriptsize"), + _T ("footnotesize"), + _T ("small"), + _T ("normalsize"), + _T ("large"), + _T ("Large"), + _T ("LARGE"), + _T ("huge"), + _T ("HUGE"), + _T ("bibitem"), + _T ("cite"), + _T ("label"), + _T ("ref"), + _T ("pageref"), + _T ("footnote"), + _T ("item"), + _T ("caption"), + _T ("kill"), + _T ("hline"), + _T ("cline"), + _T ("multicolumn"), + _T ("def"), + _T ("hspace"), + _T ("vspace"), + _T ("linebreak"), + _T ("nolinebreak"), + _T ("newpage"), + _T ("clearpage"), + _T ("pagebreak"), + _T ("nopagebreak"), + _T ("samepage"), + _T ("newcommand"), + _T ("renewcommand"), + _T ("newenvironment"), + _T ("newtheorem"), + _T ("newcounter"), + _T ("setcounter"), + _T ("addtocounter"), + _T ("value"), + _T ("stepcounter"), + + _T ("newlength"), + _T ("setlength"), + _T ("addtolength"), + _T ("settowidth"), + _T ("textheight"), + _T ("textwidth"), + _T ("topmargin"), + _T ("hoffset"), + _T ("voffset"), + _T ("oddsidemargin"), + _T ("evensidemargin"), + _T ("mbox"), + _T ("makebox"), + _T ("fbos"), + _T ("framebox"), + _T ("newsavebox"), + _T ("sbox"), + _T ("savebox"), + _T ("usebox"), + _T ("raisebox"), + _T ("put"), + _T ("framebox"), + _T ("dashbox"), + _T ("line"), + _T ("vector"), + _T ("circle"), + _T ("oval"), + _T ("frame"), + _T ("shortstack"), + _T ("multiput"), + _T ("thinlines"), + _T ("thicklines"), + _T ("linethickness"), + _T ("font"), + _T ("magnification"), + _T ("magstephalf"), + _T ("magstep"), + _T ("hsize"), + _T ("vsize"), + _T ("voffset"), + _T ("hoffset"), + _T ("topskip"), + _T ("leftskip"), + _T ("rightskip"), + _T ("eject"), + _T ("vfill"), + _T ("eject"), + _T ("goodbreak"), + _T ("nobreak"), + _T ("nopagenumbers"), + _T ("headline"), + _T ("headheight"), + _T ("headsep"), + _T ("footnote"), + _T ("pageno"), + _T ("folio"), + _T ("par"), + _T ("parindent"), + _T ("noindent"), + _T ("break"), + _T ("hfill"), + _T ("break"), + _T ("line"), + _T ("rightline"), + _T ("centerline"), + + _T ("includegraphics"), + + _T ("enskip"), + _T ("hskip"), + _T ("hfil"), + _T ("hfill"), + _T ("hss"), + _T ("smallskip"), + _T ("vskip"), + _T ("vglue"), + _T ("vfil"), + _T ("vfill"), + _T ("vss"), + _T ("baselineskip"), + _T ("parskip"), + _T ("topinsert"), + _T ("midinsert"), + _T ("handindent"), + _T ("footnote"), + _T ("hrule"), + _T ("vrule"), + _T ("leaders"), + _T ("hrulefill"), + _T ("settabs"), + _T ("haling"), + _T ("hbox"), + _T ("vbox"), + _T ("newbox"), + _T ("setbox"), + + _T ("arccos"), + _T ("cos"), + _T ("csc"), + _T ("exp"), + _T ("ker"), + _T ("limsup"), + _T ("min"), + _T ("sinh"), + _T ("arcsin"), + _T ("cosh"), + _T ("deg"), + _T ("gcd"), + _T ("lg"), + _T ("ln"), + _T ("Pr"), + _T ("sup"), + _T ("arctan"), + _T ("cot"), + _T ("det"), + _T ("hom"), + _T ("lim"), + _T ("log"), + _T ("sec"), + _T ("tan"), + _T ("arg"), + _T ("coth"), + _T ("dim"), + _T ("inf"), + _T ("liminfo"), + _T ("max"), + _T ("sin"), + _T ("tanh"), + + _T ("displaystyle"), + _T ("textstyle"), + _T ("alpha"), + _T ("beta"), + _T ("gamma"), + _T ("delta"), + _T ("epsilon"), + _T ("varepsilon"), + _T ("zeta"), + _T ("eta"), + _T ("theta"), + _T ("vartheta"), + _T ("iota"), + _T ("kappa"), + _T ("lambda"), + _T ("mu"), + _T ("nu"), + _T ("xi"), + _T ("o"), + _T ("pi"), + _T ("varpi"), + _T ("rho"), + _T ("varrho"), + _T ("sigma"), + _T ("varsigma"), + _T ("tau"), + _T ("upsilon"), + _T ("phi"), + _T ("varphi"), + _T ("chi"), + _T ("psi"), + _T ("omega"), + _T ("Gamma"), + _T ("Delta"), + _T ("Theta"), + _T ("Lambda"), + _T ("Xi"), + _T ("Pi"), + _T ("Sigma"), + _T ("Upsilon"), + _T ("Phi"), + _T ("Psi"), + _T ("Omega"), + + _T ("aleph"), + _T ("hbar"), + _T ("imath"), + _T ("jmath"), + _T ("ell"), + _T ("wp"), + _T ("Re"), + _T ("Im"), + _T ("partial"), + _T ("infty"), + _T ("backslash"), + _T ("prime"), + _T ("emptyset"), + _T ("nabla"), + _T ("surd"), + _T ("triangle"), + _T ("angle"), + _T ("bot"), + _T ("top"), + _T ("forall"), + _T ("exists"), + _T ("neg"), + _T ("lnot"), + _T ("flat"), + _T ("natural"), + _T ("sharp"), + _T ("clubsuit"), + _T ("diamondsuit"), + _T ("heartsuit"), + _T ("spadesuit"), + + _T ("pm"), + _T ("mp"), + _T ("setminus"), + _T ("cdot"), + _T ("times"), + _T ("ast"), + _T ("star"), + _T ("diamond"), + _T ("circ"), + _T ("bullet"), + _T ("triangleleft"), + _T ("cap"), + _T ("cup"), + _T ("uplus"), + _T ("sqcap"), + _T ("sqcup"), + _T ("amalg"), + _T ("div"), + _T ("wr"), + _T ("bigcirc"), + _T ("vee"), + _T ("lor"), + _T ("wedge"), + _T ("land"), + _T ("oplus"), + _T ("ominus"), + _T ("otimes"), + _T ("oslash"), + _T ("odot"), + _T ("dagger"), + _T ("ddagger"), + _T ("bigtriangleleft"), + _T ("bigtriangledown"), + _T ("sum"), + _T ("prod"), + _T ("coprod"), + _T ("int"), + _T ("oint"), + _T ("bigcap"), + _T ("bigcup"), + _T ("bigsqcup"), + _T ("bigvee"), + _T ("bigwedge"), + _T ("bigodot"), + _T ("bigotimes"), + _T ("bigoplus"), + _T ("biguplus"), + _T ("hat"), + _T ("acute"), + _T ("ddot"), + _T ("vec"), + _T ("check"), + _T ("grave"), + _T ("breve"), + _T ("tilde"), + _T ("dot"), + _T ("bar"), + _T ("widehat"), + _T ("widetilde"), + + _T ("ldots"), + _T ("vdots"), + _T ("cdots"), + _T ("ddots"), + _T ("leq"), + _T ("le"), + _T ("prec"), + _T ("preceq"), + _T ("ll"), + _T ("subset"), + _T ("subsetqe"), + _T ("supsetqe"), + _T ("in"), + _T ("vdash"), + _T ("smile"), + _T ("frown"), + _T ("geq"), + _T ("ge"), + _T ("succ"), + _T ("succeq"), + _T ("gg"), + _T ("supset"), + _T ("sqsubseteq"), + _T ("sqsupsetqe"), + _T ("ni"), + _T ("owns"), + _T ("dashv"), + _T ("mid"), + _T ("parallel"), + _T ("equiv"), + _T ("sim"), + _T ("simeq"), + _T ("asymp"), + _T ("approx"), + _T ("cong"), + _T ("bowtie"), + _T ("propto"), + _T ("models"), + _T ("doteq"), + _T ("perp"), + _T ("not"), + + _T ("leftarrow"), + _T ("Leftarrow"), + _T ("gets"), + _T ("longleftarrow"), + _T ("Longleftarrow"), + _T ("rightarrow"), + _T ("Rightarrow"), + _T ("to"), + _T ("longrightarrow"), + _T ("Longrightarrow"), + _T ("leftrightarrow"), + _T ("Leftrightarrow"), + _T ("longleftrightarrow"), + _T ("Longleftrightarrow"), + _T ("mapsto"), + _T ("longmapsto"), + _T ("hookleftarrow"), + _T ("hookrightarrow"), + _T ("leftharpoonup"), + _T ("rightharpoonup"), + _T ("leftharpoondown"), + _T ("rightharpoondown"), + _T ("uparrow"), + _T ("Uparrow"), + _T ("downarrow"), + _T ("Downarrow"), + _T ("updownarrow"), + _T ("Updownarrow"), + _T ("nearrow"), + _T ("searrow"), + _T ("swarrow"), + _T ("nwarrow"), + _T ("lbrack"), + _T ("lfloor"), + _T ("rbrack"), + _T ("rfloor"), + _T ("lceil"), + _T ("lbrace"), + _T ("langle"), + _T ("rceil"), + _T ("rbrace"), + _T ("rangle"), + _T ("quad"), + _T ("qquad"), + + _T ("Biggl"), + _T ("biggl"), + _T ("Bigl"), + _T ("bigl"), + _T ("bigr"), + _T ("Bigr"), + _T ("biggr"), + _T ("Biggr"), + _T ("lgroup"), + _T ("rgroup"), + _T ("langle"), + _T ("rangle"), + _T ("vert"), + _T ("Vert"), + _T ("uparrow"), + _T ("left"), + _T ("right"), + _T ("overline"), + _T ("overrightarrow"), + _T ("overleftarrow"), + _T ("overbrace"), + _T ("underbrace"), + _T ("atop"), + _T ("choose"), + _T ("brack"), + _T ("above"), + _T ("brace"), + _T ("pmatrix"), + _T ("matrix"), + _T ("bordermatrix"), + _T ("eqalign"), + _T ("eqno"), + _T ("eqalignno"), + _T ("quad"), + + _T ("def"), + _T ("gdef"), + _T ("edef"), + _T ("newcount"), + _T ("advance"), + _T ("multiply"), + _T ("divide"), + _T ("number"), + _T ("romannumeral"), + _T ("newdimen"), + _T ("newread"), + _T ("openin"), + _T ("closein"), + _T ("input"), + _T ("endinput"), + _T ("newwrite"), + _T ("openouput"), + _T ("closeout"), + _T ("write"), + _T ("jobname"), + _T ("if"), + _T ("else"), + _T ("fi"), + _T ("ifx"), + _T ("ifeof"), + _T ("ifhmode"), + _T ("ifvmode"), + _T ("ifmmode"), + _T ("ifcat"), + _T ("ifnum"), + _T ("ifdim"), + _T ("ifodd"), + _T ("ifcase"), + _T ("or"), + _T ("loop"), + _T ("repeat"), + + _T ("beginpicture"), + _T ("setcoordinatesystem"), + _T ("endpicture"), + _T ("plotheading"), + _T ("lines"), + _T ("putrule"), + _T ("linethickness"), + _T ("setlinear"), + _T ("setquadratic"), + _T ("sethistograms"), + _T ("setsolid"), + _T ("setdashes"), + _T ("setdots"), + _T ("setdashpattern"), + _T ("setplotsymbol"), + _T ("plot"), + _T ("arrow"), + _T ("put"), + _T ("multiput"), + _T ("circulararc"), + _T ("ellipticarc"), + _T ("startrotation"), + _T ("stoprotation"), + _T ("setshadegrid"), + _T ("setshadesymbol"), + _T ("shaderectangleson"), + _T ("sharerectanglesoff"), + _T ("vshade"), + _T ("setquadratic"), + _T ("hshade"), + _T ("setplotarea"), + _T ("inboundscheckon"), + _T ("inboundscheckoff"), + _T ("axis"), + _T ("setbox"), + _T ("endpicturesave"), + _T ("newdimen"), + NULL + }; + +static LPTSTR s_apszUser1KeywordList[] = + { + _T ("Alph"), + _T ("AtBeginDocument"), + _T ("AtBeginDvi"), + _T ("AtEndDocument"), + _T ("AtEndOfPackage"), + _T ("Big"), + _T ("Bigg"), + _T ("Box"), + _T ("CheckCommand"), + _T ("ClassError"), + _T ("ClassInfo"), + _T ("ClassWarning"), + _T ("ClassWarningNoLine"), + _T ("DeclareErrorFont"), + _T ("DeclareFixedFont"), + _T ("DeclareFontEncoding"), + _T ("DeclareFontEncodingDefaults"), + _T ("DeclareFontFamily"), + _T ("DeclareFontShape"), + _T ("DeclareFontSubstitution"), + _T ("DeclareMathAccent"), + _T ("DeclareMathAlphabet"), + _T ("DeclareMathDelimiter"), + _T ("DeclareMathRadical"), + _T ("DeclareMathSizes"), + _T ("DeclareMathSymbol"), + _T ("DeclareMathVersion"), + _T ("DeclareOldFontCommand"), + _T ("DeclareOption"), + _T ("DeclarePreloadSizes"), + _T ("DeclareRobustCommand"), + _T ("DeclareSizeFunction"), + _T ("DeclareSymbolFont"), + _T ("DeclareSymbolFontAlphabet"), + _T ("DeclareTextAccent"), + _T ("DeclareTextAccentDefault"), + _T ("DeclareTextCommand"), + _T ("DeclareTextCommandDefault"), + _T ("DeclareTextComposite"), + _T ("DeclareTextCompositeCommand"), + _T ("DeclareTextFontCommand"), + _T ("DeclareTextSymbol"), + _T ("DeclareTextSymbolDefault"), + _T ("ExecuteOptions"), + _T ("IfFileExists"), + _T ("InputIfFileExists"), + _T ("Join"), + _T ("LoadClass"), + _T ("LoadClassWithOptions"), + _T ("MessageBreak"), + _T ("NeedsTeXFormat"), + _T ("OptionNotUsed"), + _T ("PackageError"), + _T ("PackageInfo"), + _T ("PackageWarning"), + _T ("PackageWarningNoLine"), + _T ("PassOptionsToClass"), + _T ("PassOptionsToPackage"), + _T ("ProcessOptions"), + _T ("ProvideTextCommand"), + _T ("ProvideTextCommandDefault"), + _T ("ProvidesFile"), + _T ("ProvidesPackage"), + _T ("RequirePackage"), + _T ("RequirePackageWithOptions"), + _T ("Roman"), + _T ("SetMathAlphabet"), + _T ("SetSymbolFont"), + _T ("TeX"), + _T ("TextSymbolUnavailable"), + _T ("UseTextAccent"), + _T ("UseTextSymbol"), + _T ("addcontentsline"), + _T ("addpenalty"), + _T ("addtocontents"), + _T ("addtoversion"), + _T ("addvspace"), + _T ("afterassignment"), + _T ("allocationnumber"), + _T ("allowbreak"), + _T ("alph"), + _T ("arrayrulewidth"), + _T ("arraystretch"), + _T ("baselinestretch"), + _T ("bezier"), + _T ("bfdefault"), + _T ("bfseries"), + _T ("bibcite"), + _T ("bibliography"), + _T ("bibliographystyle"), + _T ("big"), + _T ("bigbreak"), + _T ("bigg"), + _T ("bigskip"), + _T ("bigskipamount"), + _T ("bigskipamount"), + _T ("bmod"), + _T ("boldmath"), + _T ("buildrel"), + _T ("cases"), + _T ("catcode"), + _T ("center"), + _T ("centering"), + _T ("chardef"), + _T ("cleardoublepage"), + _T ("contentsline"), + _T ("countdef"), + _T ("cr"), + _T ("csname"), + _T ("depth"), + _T ("discretionary"), + _T ("displaymath"), + _T ("dospecials"), + _T ("dotfill"), + _T ("encodingdefault"), + _T ("endcsname"), + _T ("everycr"), + _T ("expandafter"), + _T ("expandafter"), + _T ("extracolsep"), + _T ("familydefault"), + _T ("familydefault"), + _T ("fbox"), + _T ("filbreak"), + _T ("flushleft"), + _T ("flushright"), + _T ("fmtname"), + _T ("fmtversion"), + _T ("fontencoding"), + _T ("fontfamily"), + _T ("fontseries"), + _T ("fontshape"), + _T ("footnotemark"), + _T ("footnoterule"), + _T ("footnotetext"), + _T ("frac"), + _T ("frenchspacing"), + _T ("fussy"), + _T ("futurelet"), + _T ("global"), + _T ("glossary"), + _T ("halign"), + _T ("height"), + _T ("hphantom"), + _T ("ifinner"), + _T ("immediate"), + _T ("include"), + _T ("includeonly"), + _T ("itdefault"), + _T ("iterate"), + _T ("kern"), + _T ("lastskip"), + _T ("leadsto"), + _T ("leavevmode"), + _T ("lefteqn"), + _T ("leftline"), + _T ("leftmark"), + _T ("let"), + _T ("lhd"), + _T ("liminf"), + _T ("lineskip"), + _T ("lower"), + _T ("lowercase"), + _T ("makeatletter"), + _T ("makeatother"), + _T ("makeglossary"), + _T ("makeindex"), + _T ("marginpar"), + _T ("markboth"), + _T ("markright"), + _T ("mathclose"), + _T ("mathop"), + _T ("mathopen"), + _T ("mathrel"), + _T ("mathstrut"), + _T ("mddefault"), + _T ("medbreak"), + _T ("medmuskip"), + _T ("medskip"), + _T ("mho"), + _T ("minipage"), + _T ("mskip"), + _T ("multispan"), + _T ("narrower"), + _T ("negthinspace"), + _T ("newfont"), + _T ("newhelp"), + _T ("newif"), + _T ("newinsert"), + _T ("newlabel"), + _T ("newlanguage"), + _T ("newline"), + _T ("newmathalphabet"), + _T ("newmuskip"), + _T ("newskip"), + _T ("newtoks"), + _T ("nocite"), + _T ("nocorrlist"), + _T ("noexpand"), + _T ("nointerlineskip"), + _T ("nolimits"), + _T ("nonfrenchspacing"), + _T ("nonumber"), + _T ("normalbaselines"), + _T ("normallineskip"), + _T ("normalmarginpar"), + _T ("null"), + _T ("numberline"), + _T ("obeylines"), + _T ("obeyspaces"), + _T ("offinterlineskip"), + _T ("onecolumn"), + _T ("openup"), + _T ("pagenumberin"), + _T ("parbox"), + _T ("penalty"), + _T ("phantom"), + _T ("pmod"), + _T ("protect"), + _T ("providecommand"), + _T ("raggedbottom"), + _T ("raggedleft"), + _T ("raggedright"), + _T ("refstepcounter"), + _T ("relax"), + _T ("removelastskip"), + _T ("renewenvironment"), + _T ("reversemarginpar"), + _T ("rhd"), + _T ("rightmark"), + _T ("rlap"), + _T ("rmdefault"), + _T ("roman"), + _T ("root"), + _T ("rq"), + _T ("rule"), + _T ("scdefault"), + _T ("secdef"), + _T ("selectfont"), + _T ("seriesdefault"), + _T ("settodepth"), + _T ("settoheight"), + _T ("sfdefault"), + _T ("shapedefault"), + _T ("showhyphens"), + _T ("showoutput"), + _T ("showoverfull"), + _T ("sldefault"), + _T ("sloppy"), + _T ("sloppypar"), + _T ("smallbreak"), + _T ("space"), + _T ("spacefactor"), + _T ("sqsubset"), + _T ("stackrel"), + _T ("stretch"), + _T ("strut"), + _T ("suppressfloats"), + _T ("symbol"), + _T ("tabskip"), + _T ("thanks"), + _T ("thefootnote"), + _T ("thickmuskip"), + _T ("thinmuskip"), + _T ("thinspace"), + _T ("today"), + _T ("tracingfonts"), + _T ("tracingoutput"), + _T ("trivlist"), + _T ("ttdefault"), + _T ("twocolumn"), + _T ("typein"), + _T ("typeout"), + _T ("unboldmath"), + _T ("undefinedpagestyle"), + _T ("underbar"), + _T ("underline"), + _T ("unlhd"), + _T ("unrhd"), + _T ("updefault"), + _T ("usecounter"), + _T ("usefont"), + _T ("usepackage"), + _T ("vcenter"), + _T ("verb"), + _T ("verbatim"), + _T ("vline"), + _T ("vphantom"), + _T ("width"), + _T ("wlog"), + _T ("xdef"), + NULL + }; + +static BOOL +IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength) +{ + for (int L = 0; apszKeywords[L] != NULL; L++) + { + if (_tcsnicmp (apszKeywords[L], pszChars, nLength) == 0 + && apszKeywords[L][nLength] == 0) + return TRUE; + } + return FALSE; +} + +static BOOL +IsTexKeyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszTexKeywordList, pszChars, nLength); +} + +static BOOL +IsUser1Keyword (LPCTSTR pszChars, int nLength) +{ + return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength); +} + +static BOOL +IsTexNumber (LPCTSTR pszChars, int nLength) +{ + if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x') + { + for (int I = 2; I < nLength; I++) + { + if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') || + (pszChars[I] >= 'a' && pszChars[I] <= 'f')) + continue; + return FALSE; + } + return TRUE; + } + if (!_istdigit (pszChars[0])) + return FALSE; + for (int I = 1; I < nLength; I++) + { + if (!_istdigit (pszChars[I]) && pszChars[I] != '+' && + pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' && + pszChars[I] != 'E') + return FALSE; + } + return TRUE; +} + +#define DEFINE_BLOCK(pos, colorindex) \ +ASSERT((pos) >= 0 && (pos) <= nLength);\ +if (pBuf != NULL)\ + {\ + if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\ + pBuf[nActualItems].m_nCharPos = (pos);\ + pBuf[nActualItems].m_nColorIndex = (colorindex);\ + nActualItems ++;}\ + } + +#define COOKIE_COMMENT 0x0001 +#define COOKIE_PREPROCESSOR 0x0002 +#define COOKIE_EXT_COMMENT 0x0004 +#define COOKIE_STRING 0x0008 +#define COOKIE_CHAR 0x0010 + +DWORD CCrystalTextView:: +ParseLineTex (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems) +{ + int nLength = GetLineLength (nLineIndex); + if (nLength <= 1) + return dwCookie & COOKIE_EXT_COMMENT; + + LPCTSTR pszChars = GetLineChars (nLineIndex); + BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0; + BOOL bRedefineBlock = TRUE; + BOOL bDecIndex = FALSE; + int nIdentBegin = -1; + + for (int I = 0;; I++) + { + if (bRedefineBlock) + { + int nPos = I; + if (bDecIndex) + nPos--; + if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT)) + { + DEFINE_BLOCK (nPos, COLORINDEX_COMMENT); + } + else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING)) + { + DEFINE_BLOCK (nPos, COLORINDEX_STRING); + } + else + { + if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.') + { + DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT); + } + else + { + DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR); + bRedefineBlock = TRUE; + bDecIndex = TRUE; + goto out; + } + } + bRedefineBlock = FALSE; + bDecIndex = FALSE; + } +out: + + if (I == nLength) + break; + + if (dwCookie & COOKIE_COMMENT) + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // String constant "...." + if (dwCookie & COOKIE_STRING) + { + if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_STRING; + bRedefineBlock = TRUE; + } + continue; + } + + // Char constant '..' + if (dwCookie & COOKIE_CHAR) + { + if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\'))) + { + dwCookie &= ~COOKIE_CHAR; + bRedefineBlock = TRUE; + } + continue; + } + + if (pszChars[I] == '%') + { + DEFINE_BLOCK (I, COLORINDEX_COMMENT); + dwCookie |= COOKIE_COMMENT; + break; + } + + // Normal text + if (pszChars[I] == '"') + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_STRING; + continue; + } + if (pszChars[I] == '\'') + { + // if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'') + if (!I || !xisalnum (pszChars[I - 1])) + { + DEFINE_BLOCK (I, COLORINDEX_STRING); + dwCookie |= COOKIE_CHAR; + continue; + } + } + + if (bFirstChar) + { + if (!isspace (pszChars[I])) + bFirstChar = FALSE; + } + + if (pBuf == NULL) + continue; // We don't need to extract keywords, + // for faster parsing skip the rest of loop + + if (xisalnum (pszChars[I]) || pszChars[I] == '.') + { + if (nIdentBegin == -1) + nIdentBegin = I; + } + else + { + if (nIdentBegin >= 0) + { + if (IsTexKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsTexNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '$') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + bRedefineBlock = TRUE; + bDecIndex = TRUE; + nIdentBegin = -1; + } + } + } + + if (nIdentBegin >= 0) + { + if (IsTexKeyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD); + } + else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1); + } + else if (IsTexNumber (pszChars + nIdentBegin, I - nIdentBegin)) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER); + } + else + { + bool bFunction = FALSE; + + if (!bFunction) + { + for (int j = I; j >= 0; j--) + { + if (!isspace (pszChars[j])) + { + if (pszChars[j] == '$') + { + bFunction = TRUE; + } + break; + } + } + } + if (bFunction) + { + DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME); + } + } + } + + dwCookie &= COOKIE_EXT_COMMENT; + return dwCookie; +} diff --git a/Src/editlib/wispelld.h b/Src/editlib/wispelld.h new file mode 100644 index 000000000..968e362eb --- /dev/null +++ b/Src/editlib/wispelld.h @@ -0,0 +1,64 @@ +/* + * The following ifdef block is the standard way of creating macros which make exporting + * from a DLL simpler. All files within this DLL are compiled with the WISPELL_EXPORTS + * symbol defined on the command line. this symbol should not be defined on any project + * that uses this DLL. This way any other project whose source files include this file see + * WISPELL_API functions as being imported from a DLL, wheras this DLL sees symbols + * defined with this macro as being exported. + */ + +#ifndef __WISPELLD_H__ +#define __WISPELLD_H__ + +/*#ifdef WISPELL_EXPORTS +#define WISPELL_API __declspec (dllexport) +#else +#define WISPELL_API __declspec (dllimport) +#endif*/ + +#define SN_FOUND 1 /* possibly incorrect word was found */ +#define SN_REPLACED 2 /* possibly incorrect word was commanded to be replaced */ +#define SN_FINISHED 3 /* spell checking finished */ +#define SN_HELP_SPELL 4 /* help button of the checking dialog was pressed */ +#define SN_HELP_CONFIG 5 /* help button of the configuration dialog was pressed */ + +#define SF_TEX 0x00001 /* -t/-n */ /* TeX mode on */ +#define SF_HTML 0x00002 /* -h */ /* HTML mode on */ +#define SF_RUNTOGETHER 0x00004 /* -C/-B */ /* run-together words to be legal compounds */ +#define SF_EXTRAAFFIX 0x00008 /* -m/-P */ /* generate extra root/affix combinations */ +#define SF_SORTPROBLY 0x00010 /* -S */ /* sort the list of suggested words by probable correctness */ +#define SF_HELP 0x10000 /* to enable the Help button in checking and configuration dialogs */ +#define SF_ISPELLPATH 0x20000 /* to enable setting of the directory where ispell resides */ + +#define SF_TOSET (SF_TEX|SF_HTML|SF_RUNTOGETHER|SF_EXTRAAFFIX|SF_SORTPROBLY) + +#define BUFSIZE 4096 +#define INPUTWORDLEN 100 +#define WAITTIME 50 + +typedef struct SpellData_t + { + DWORD dwFlags; /* combination of SF_ flags */ + TCHAR szIspell[MAX_PATH], /* the directory where ispell resides */ + szUserDict[MAX_PATH], /* path to the user dictionary */ + szMainDict[INPUTWORDLEN], /* name of the file with the main dictionary */ + szWordChars[INPUTWORDLEN], /* extra characters to be allowed to build the word */ + szFormatter[INPUTWORDLEN]; /* alternate form for the character set */ + HWND hParent; /* parent window for the calling of the current routine */ + LPCTSTR pszWord; /* currently processed word - found or to be replaced */ + LPTSTR pszBuffer, /* buffer from which the engine reads the input line */ + pszCurrent; /* current position in the buffer - for internal use only */ + int nColumn, /* character position in currently processed line */ + nRow, /* currently processed line */ + nDelta, /* gap between original column and another one modified by replacing - for internal use only */ + nLegalLen; /* maximal length of the word considered to be always correct */ + LPVOID pUserData; /* for external use only */ + int (*GetLine) (struct SpellData_t*); /* pointer to routine which has to fill in the input buffer */ + int (*Notify) (int, struct SpellData_t*); /* pointer to routine which receives SN_ notifications */ + } SpellData; + +/* WISPELL_API int SpellInit (SpellData*); */ /* initializes the control structure */ +/* WISPELL_API int SpellCheck (SpellData*); */ /* performs spell checking (the dialog may appear) */ +/* WISPELL_API int SpellConfig (SpellData*); */ /* performs spell checking configuration (the dialog appears) */ + +#endif /* __WISPELLD_H__ */ -- 2.11.0