⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 document.cxx

📁 porting scintilla to qt
💻 CXX
📖 第 1 页 / 共 3 页
字号:
	return newPos;}int Document::Redo() {	int newPos = -1;	CheckReadOnly();	if (enteredModification == 0) {		enteredModification++;		if (!cb.IsReadOnly()) {			bool startSavePoint = cb.IsSavePoint();			bool multiLine = false;			int steps = cb.StartRedo();			for (int step = 0; step < steps; step++) {				const int prevLinesTotal = LinesTotal();				const Action &action = cb.GetRedoStep();				if (action.at == insertAction) {					NotifyModified(DocModification(									SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));				} else {					NotifyModified(DocModification(									SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));				}				cb.PerformRedoStep();				ModifiedAt(action.position);				newPos = action.position;				int modFlags = SC_PERFORMED_REDO;				if (action.at == insertAction) {					newPos += action.lenData;					modFlags |= SC_MOD_INSERTTEXT;				} else {					modFlags |= SC_MOD_DELETETEXT;				}				if (steps > 1)					modFlags |= SC_MULTISTEPUNDOREDO;				const int linesAdded = LinesTotal() - prevLinesTotal;				if (linesAdded != 0)					multiLine = true;				if (step == steps - 1) {					modFlags |= SC_LASTSTEPINUNDOREDO;					if (multiLine)						modFlags |= SC_MULTILINEUNDOREDO;				}				NotifyModified(					DocModification(modFlags, action.position, action.lenData,									linesAdded, action.data));			}			bool endSavePoint = cb.IsSavePoint();			if (startSavePoint != endSavePoint)				NotifySavePoint(endSavePoint);		}		enteredModification--;	}	return newPos;}/** * Insert a single character. */bool Document::InsertChar(int pos, char ch) {	char chs[1];	chs[0] = ch;	return InsertString(pos, chs, 1);}/** * Insert a null terminated string. */bool Document::InsertCString(int position, const char *s) {	return InsertString(position, s, strlen(s));}void Document::ChangeChar(int pos, char ch) {	DeleteChars(pos, 1);	InsertChar(pos, ch);}void Document::DelChar(int pos) {	DeleteChars(pos, LenChar(pos));}void Document::DelCharBack(int pos) {	if (pos <= 0) {		return;	} else if (IsCrLf(pos - 2)) {		DeleteChars(pos - 2, 2);	} else if (dbcsCodePage) {		int startChar = MovePositionOutsideChar(pos - 1, -1, false);		DeleteChars(startChar, pos - startChar);	} else {		DeleteChars(pos - 1, 1);	}}static bool isindentchar(char ch) {	return (ch == ' ') || (ch == '\t');}static int NextTab(int pos, int tabSize) {	return ((pos / tabSize) + 1) * tabSize;}static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {	length--;	// ensure space for \0	if (!insertSpaces) {		while ((indent >= tabSize) && (length > 0)) {			*linebuf++ = '\t';			indent -= tabSize;			length--;		}	}	while ((indent > 0) && (length > 0)) {		*linebuf++ = ' ';		indent--;		length--;	}	*linebuf = '\0';}int Document::GetLineIndentation(int line) {	int indent = 0;	if ((line >= 0) && (line < LinesTotal())) {		int lineStart = LineStart(line);		int length = Length();		for (int i = lineStart;i < length;i++) {			char ch = cb.CharAt(i);			if (ch == ' ')				indent++;			else if (ch == '\t')				indent = NextTab(indent, tabInChars);			else				return indent;		}	}	return indent;}void Document::SetLineIndentation(int line, int indent) {	int indentOfLine = GetLineIndentation(line);	if (indent < 0)		indent = 0;	if (indent != indentOfLine) {		char linebuf[1000];		CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);		int thisLineStart = LineStart(line);		int indentPos = GetLineIndentPosition(line);		BeginUndoAction();		DeleteChars(thisLineStart, indentPos - thisLineStart);		InsertCString(thisLineStart, linebuf);		EndUndoAction();	}}int Document::GetLineIndentPosition(int line) const {	if (line < 0)		return 0;	int pos = LineStart(line);	int length = Length();	while ((pos < length) && isindentchar(cb.CharAt(pos))) {		pos++;	}	return pos;}int Document::GetColumn(int pos) {	int column = 0;	int line = LineFromPosition(pos);	if ((line >= 0) && (line < LinesTotal())) {		for (int i = LineStart(line);i < pos;) {			char ch = cb.CharAt(i);			if (ch == '\t') {				column = NextTab(column, tabInChars);				i++;			} else if (ch == '\r') {				return column;			} else if (ch == '\n') {				return column;			} else if (i >= Length()) {				return column;			} else {				column++;				i = MovePositionOutsideChar(i + 1, 1, false);			}		}	}	return column;}int Document::FindColumn(int line, int column) {	int position = LineStart(line);	int columnCurrent = 0;	if ((line >= 0) && (line < LinesTotal())) {		while ((columnCurrent < column) && (position < Length())) {			char ch = cb.CharAt(position);			if (ch == '\t') {				columnCurrent = NextTab(columnCurrent, tabInChars);				position++;			} else if (ch == '\r') {				return position;			} else if (ch == '\n') {				return position;			} else {				columnCurrent++;				position = MovePositionOutsideChar(position + 1, 1, false);			}		}	}	return position;}void Document::Indent(bool forwards, int lineBottom, int lineTop) {	// Dedent - suck white space off the front of the line to dedent by equivalent of a tab	for (int line = lineBottom; line >= lineTop; line--) {		int indentOfLine = GetLineIndentation(line);		if (forwards) {			if (LineStart(line) < LineEnd(line)) {				SetLineIndentation(line, indentOfLine + IndentSize());			}		} else {			SetLineIndentation(line, indentOfLine - IndentSize());		}	}}// Convert line endings for a piece of text to a particular mode.// Stop at len or when a NUL is found.// Caller must delete the returned pointer.char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) {	char *dest = new char[2 * len + 1];	const char *sptr = s;	char *dptr = dest;	for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) {		if (*sptr == '\n' || *sptr == '\r') {			if (eolMode == SC_EOL_CR) {				*dptr++ = '\r';			} else if (eolMode == SC_EOL_LF) {				*dptr++ = '\n';			} else { // eolMode == SC_EOL_CRLF				*dptr++ = '\r';				*dptr++ = '\n';			}			if ((*sptr == '\r') && (i+1 < len) && (*(sptr+1) == '\n')) {				i++;				sptr++;			}			sptr++;		} else {			*dptr++ = *sptr++;		}	}	*dptr++ = '\0';	*pLenOut = (dptr - dest) - 1;	return dest;}void Document::ConvertLineEnds(int eolModeSet) {	BeginUndoAction();	for (int pos = 0; pos < Length(); pos++) {		if (cb.CharAt(pos) == '\r') {			if (cb.CharAt(pos + 1) == '\n') {				// CRLF				if (eolModeSet == SC_EOL_CR) {					DeleteChars(pos + 1, 1); // Delete the LF				} else if (eolModeSet == SC_EOL_LF) {					DeleteChars(pos, 1); // Delete the CR				} else {					pos++;				}			} else {				// CR				if (eolModeSet == SC_EOL_CRLF) {					InsertString(pos + 1, "\n", 1); // Insert LF					pos++;				} else if (eolModeSet == SC_EOL_LF) {					InsertString(pos, "\n", 1); // Insert LF					DeleteChars(pos + 1, 1); // Delete CR				}			}		} else if (cb.CharAt(pos) == '\n') {			// LF			if (eolModeSet == SC_EOL_CRLF) {				InsertString(pos, "\r", 1); // Insert CR				pos++;			} else if (eolModeSet == SC_EOL_CR) {				InsertString(pos, "\r", 1); // Insert CR				DeleteChars(pos + 1, 1); // Delete LF			}		}	}	EndUndoAction();}bool Document::IsWhiteLine(int line) const {	int currentChar = LineStart(line);	int endLine = LineEnd(line);	while (currentChar < endLine) {		if (cb.CharAt(currentChar) != ' ' && cb.CharAt(currentChar) != '\t') {			return false;		}		++currentChar;	}	return true;}int Document::ParaUp(int pos) {	int line = LineFromPosition(pos);	line--;	while (line >= 0 && IsWhiteLine(line)) { // skip empty lines		line--;	}	while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines		line--;	}	line++;	return LineStart(line);}int Document::ParaDown(int pos) {	int line = LineFromPosition(pos);	while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines		line++;	}	while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines		line++;	}	if (line < LinesTotal())		return LineStart(line);	else // end of a document		return LineEnd(line-1);}CharClassify::cc Document::WordCharClass(unsigned char ch) {	if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))		return CharClassify::ccWord;	return charClass.GetClass(ch);}/** * Used by commmands that want to select whole words. * Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0. */int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {	CharClassify::cc ccStart = CharClassify::ccWord;	if (delta < 0) {		if (!onlyWordCharacters)			ccStart = WordCharClass(cb.CharAt(pos-1));		while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccStart))			pos--;	} else {		if (!onlyWordCharacters && pos < Length())			ccStart = WordCharClass(cb.CharAt(pos));		while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))			pos++;	}	return MovePositionOutsideChar(pos, delta);}/** * Find the start of the next word in either a forward (delta >= 0) or backwards direction * (delta < 0). * This is looking for a transition between character classes although there is also some * additional movement to transit white space. * Used by cursor movement by word commands. */int Document::NextWordStart(int pos, int delta) {	if (delta < 0) {		while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace))			pos--;		if (pos > 0) {			CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1));			while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccStart)) {				pos--;			}		}	} else {		CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos));		while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))			pos++;		while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace))			pos++;	}	return pos;}/** * Find the end of the next word in either a forward (delta >= 0) or backwards direction * (delta < 0). * This is looking for a transition between character classes although there is also some * additional movement to transit white space. * Used by cursor movement by word commands. */int Document::NextWordEnd(int pos, int delta) {	if (delta < 0) {		if (pos > 0) {			CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1));			if (ccStart != CharClassify::ccSpace) {				while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == ccStart) {					pos--;				}			}			while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace) {				pos--;			}		}	} else {		while (pos < Length() && WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace) {			pos++;		}		if (pos < Length()) {			CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos));			while (pos < Length() && WordCharClass(cb.CharAt(pos)) == ccStart) {				pos++;			}		}	}	return pos;}/** * Check that the character at the given position is a word or punctuation character and that * the previous character is of a different character class. */bool Document::IsWordStartAt(int pos) {	if (pos > 0) {		CharClassify::cc ccPos = WordCharClass(CharAt(pos));		return (ccPos == CharClassify::ccWord || ccPos == CharClassify::ccPunctuation) &&			(ccPos != WordCharClass(CharAt(pos - 1)));	}	return true;}/** * Check that the character at the given position is a word or punctuation character and that * the next character is of a different character class. */bool Document::IsWordEndAt(int pos) {	if (pos < Length()) {		CharClassify::cc ccPrev = WordCharClass(CharAt(pos-1));		return (ccPrev == CharClassify::ccWord || ccPrev == CharClassify::ccPunctuation) &&			(ccPrev != WordCharClass(CharAt(pos)));	}	return true;}/** * Check that the given range is has transitions between character classes at both * ends and where the characters on the inside are word or punctuation characters. */bool Document::IsWordAt(int start, int end) {	return IsWordStartAt(start) && IsWordEndAt(end);}// The comparison and case changing functions here assume ASCII// or extended ASCII such as the normal Windows code page.static inline char MakeUpperCase(char ch) {	if (ch < 'a' || ch > 'z')		return ch;	else		return static_cast<char>(ch - 'a' + 'A');}static inline char MakeLowerCase(char ch) {	if (ch < 'A' || ch > 'Z')		return ch;	else		return static_cast<char>(ch - 'A' + 'a');}// Define a way for the Regular Expression code to access the documentclass DocumentIndexer : public CharacterIndexer {	Document *pdoc;	int end;public:	DocumentIndexer(Document *pdoc_, int end_) :		pdoc(pdoc_), end(end_) {	}	virtual ~DocumentIndexer() {	}	virtual char CharAt(int index) {		if (index < 0 || index >= end)			return 0;		else			return pdoc->CharAt(index);	}};/** * Find text in document, supporting both forward and backward * searches (just pass minPos > maxPos to do a backward search) * Has not been tested with backwards DBCS searches yet. */long Document::FindText(int minPos, int maxPos, const char *s,                        bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix,                        int *length) {	if (regExp) {		if (!pre)			pre = new RESearch(&charClass);		if (!pre)			return -1;		int increment = (minPos <= maxPos) ? 1 : -1;		int startPos = minPos;		int endPos = maxPos;		// Range endpoints should not be inside DBCS characters, but just in case, move them.		startPos = MovePositionOutsideChar(startPos, 1, false);		endPos = MovePositionOutsideChar(endPos, 1, false);		const char *errmsg = pre->Compile(s, *length, caseSensitive, posix);		if (errmsg) {			return -1;		}		// Find a variable in a property file: \$(\([A-Za-z0-9_.]+\))		// Replace first '.' with '-' in each property file variable reference:		//     Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\))		//     Replace: $(\1-\2)		int lineRangeStart = LineFromPosition(startPos);		int lineRangeEnd = LineFromPosition(endPos);		if ((increment == 1) &&			(startPos >= LineEnd(lineRangeStart)) &&			(lineRangeStart < lineRangeEnd)) {			// the start position is at end of line or between line end characters.			lineRangeStart++;			startPos = LineStart(lineRangeStart);		}		int pos = -1;		int lenRet = 0;		char searchEnd = s[*length - 1];		int lineRangeBreak = lineRangeEnd + increment;		for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {			int startOfLine = LineStart(line);			int endOfLine = LineEnd(line);			if (increment == 1) {				if (line == lineRangeStart) {					if ((startPos != startOfLine) && (s[0] == '^'))						continue;	// Can't match start of line if start position after start of line					startOfLine = startPos;				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -