--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_NORMALTEXT);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // Preprocessor start: < or bracket
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-'))
+ {
+ DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
+ dwCookie |= COOKIE_PREPROCESSOR;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // User1 end: ?>
+ 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_NORMALTEXT);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ goto end;
+ }
+
+ // Preprocessor start: < or {
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && (pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-')))
+ {
+ DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
+ dwCookie |= COOKIE_PREPROCESSOR;
+ nIdentBegin = -1;
+ goto end;
+ }
+
+ // User1 end: ?>
+ 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 <afxpriv.h> in your stdafx.h to avoid this message")
+#include <afxpriv.h>
+#endif
+#ifndef __AFXOLE_H__
+#pragma message("Include <afxole.h> in your stdafx.h to avoid this message")
+#include <afxole.h>
+#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<CString, LPCTSTR, CString, LPCTSTR> (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 )
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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<CString, LPCTSTR, CString, LPCTSTR> *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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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 <malloc.h>
+#include "editcmd.h"
+#include "ccrystaltextbuffer.h"
+#include "ccrystaltextview.h"
+#include "filesup.h"
+#include "cs2cs.h"
+#include <mbctype.h>
+
+#ifndef __AFXPRIV_H__
+#pragma message("Include <afxpriv.h> in your stdafx.h to avoid this message")
+#include <afxpriv.h>
+#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
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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 <afxtempl.h> in your stdafx.h to avoid this message")
+#include <afxtempl.h>
+#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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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 <malloc.h>
+#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 <afxpriv.h> in your stdafx.h to avoid this message")
+#include <afxpriv.h>
+#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 ("-->"), _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 ("-->"), _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<int, int>();
+ 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 )
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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<int, int> *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.
+
+ <p>
+ 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.
+
+ <b>Attention:</b> 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.
+
+ <b>Remarks:</b> 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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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 <malloc.h>
+
+#ifndef __AFXPRIV_H__
+#pragma message("Include <afxpriv.h> in your stdafx.h to avoid this message")
+#include <afxpriv.h>
+#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;
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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);
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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);
+}
--- /dev/null
+ ////////////////////////////////////////////////////////////////////////////
+// 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_)
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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);
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#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
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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;
+ }
+ }
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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:
+<ul>
+ <li> Syntax highlighting (method ParseLine())
+ <li> Word wrapping (method WrapLine())
+</ul>
+
+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.
+
+ <b>Attention:</b> 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_)
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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_)
--- /dev/null
+/* Ferda Prantl - character coding conversion engine */
+
+#include "stdafx.h"
+#include "cs2cs.h"
+#include <string.h>
+#include <malloc.h>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define FD_ENCODING_LBRACKET _T ("<!--")
+#define FD_ENCODING_MARK _T ("MYCHARSET")
+#define FD_ENCODING_RBRACKET _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;
+ }
--- /dev/null
+/* 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+//{{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
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+// edtlib.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "stdafx.h"
+#include "ccrystaltextview.h"
+#include <afxdllx.h>
+
+#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
+}
--- /dev/null
+#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
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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));
+}
+
+////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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);
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_FUNCNAME);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // Preprocessor start: < or bracket
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && (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;
+ }
+
+ // User1 end: ?>
+ 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_FUNCNAME);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ goto end;
+ }
+
+ // Preprocessor start: < or {
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && (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;
+ }
+
+ // User1 end: ?>
+ 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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<CString, LPCTSTR> &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<CString, LPCTSTR> listSource)
+{
+ POSITION pos = listSource.GetHeadPosition ();
+ CString item;
+ while (pos)
+ {
+ item = listSource.GetNext (pos);
+ sResult += item + _T ('\n');
+ }
+ return listSource.GetCount ();
+}*/
+
+/*int StringToList (CList<CString, LPCTSTR> 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 ();
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_NORMALTEXT);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // Preprocessor start: < or bracket
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-'))
+ {
+ DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
+ dwCookie |= COOKIE_PREPROCESSOR;
+ nIdentBegin = -1;
+ continue;
+ }
+
+ // User1 end: ?>
+ 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 (I < nLength && pszChars[I] == '<' && I < nLength - 1 && (pszChars[I + 1] == '?' || pszChars[I + 1] == '%'))
+ {
+ DEFINE_BLOCK (I, COLORINDEX_NORMALTEXT);
+ dwCookie |= COOKIE_EXT_USER1;
+ nIdentBegin = -1;
+ goto end;
+ }
+
+ // Preprocessor start: < or {
+ if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-'))
+ {
+ DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
+ dwCookie |= COOKIE_PREPROCESSOR;
+ nIdentBegin = -1;
+ goto end;
+ }
+
+ // User1 end: ?>
+ 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 )
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__ */
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+#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...
+}
+
+/////////////////////////////////////////////////////////////////////////////
--- /dev/null
+#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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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 ();
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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__
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+// 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;
+}
--- /dev/null
+/*
+ * 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__ */