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

📄 editor.cxx

📁 porting scintilla to qt
💻 CXX
📖 第 1 页 / 共 2 页
字号:
	int lineDoc = cs.DocFromDisplay(visibleLine);	if (lineDoc >= pdoc->LinesTotal())		return pdoc->Length();	unsigned int posLineStart = pdoc->LineStart(lineDoc);	int retVal = posLineStart;	AutoSurface surface(this);	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));	if (surface && ll) {		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);		int lineStartSet = cs.DisplayFromDoc(lineDoc);		int subLine = visibleLine - lineStartSet;		if (subLine < ll->lines) {			int lineStart = ll->LineStart(subLine);			int lineEnd = ll->LineLastVisible(subLine);			int subLineStart = ll->positions[lineStart];			if (actualWrapVisualStartIndent != 0) {				if (lineStart != 0)	// Wrapped					pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;			}			int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);			while (i < lineEnd) {				if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {					return pdoc->MovePositionOutsideChar(i + posLineStart, 1);				}				i++;			}			return lineEnd + posLineStart;		}		retVal = ll->numCharsInLine + posLineStart;	}	return retVal;}// Like PositionFromLocation but INVALID_POSITION returned when not near any text.int Editor::PositionFromLocationClose(Point pt) {	RefreshStyleData();	PRectangle rcClient = GetTextRectangle();	if (!rcClient.Contains(pt))		return INVALID_POSITION;	if (pt.x < vs.fixedColumnWidth)		return INVALID_POSITION;	if (pt.y < 0)		return INVALID_POSITION;	pt.x = pt.x - vs.fixedColumnWidth + xOffset;	int visibleLine = pt.y / vs.lineHeight + topLine;	if (pt.y < 0) {	// Division rounds towards 0		visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;	}	int lineDoc = cs.DocFromDisplay(visibleLine);	if (lineDoc < 0)		return INVALID_POSITION;	if (lineDoc >= pdoc->LinesTotal())		return INVALID_POSITION;	AutoSurface surface(this);	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));	if (surface && ll) {		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);		unsigned int posLineStart = pdoc->LineStart(lineDoc);		int lineStartSet = cs.DisplayFromDoc(lineDoc);		int subLine = visibleLine - lineStartSet;		if (subLine < ll->lines) {			int lineStart = ll->LineStart(subLine);			int lineEnd = ll->LineLastVisible(subLine);			int subLineStart = ll->positions[lineStart];			if (actualWrapVisualStartIndent != 0) {				if (lineStart != 0)	// Wrapped					pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;			}			int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);			while (i < lineEnd) {				if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {					return pdoc->MovePositionOutsideChar(i + posLineStart, 1);				}				i++;			}			if (pt.x < (ll->positions[lineEnd] - subLineStart)) {				return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);			}		}	}	return INVALID_POSITION;}/** * Find the document position corresponding to an x coordinate on a particular document line. * Ensure is between whole characters when document is in multi-byte or UTF-8 mode. */int Editor::PositionFromLineX(int lineDoc, int x) {	RefreshStyleData();	if (lineDoc >= pdoc->LinesTotal())		return pdoc->Length();	//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);	AutoSurface surface(this);	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));	int retVal = 0;	if (surface && ll) {		unsigned int posLineStart = pdoc->LineStart(lineDoc);		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);		retVal = ll->numCharsInLine + posLineStart;		int subLine = 0;		int lineStart = ll->LineStart(subLine);		int lineEnd = ll->LineLastVisible(subLine);		int subLineStart = ll->positions[lineStart];		if (actualWrapVisualStartIndent != 0) {			if (lineStart != 0)	// Wrapped				x -= actualWrapVisualStartIndent * vs.aveCharWidth;		}		int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);		while (i < lineEnd) {			if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {				retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);				break;			}			i++;		}	}	return retVal;}/** * If painting then abandon the painting because a wider redraw is needed. * @return true if calling code should stop drawing. */bool Editor::AbandonPaint() {	if ((paintState == painting) && !paintingAllText) {		paintState = paintAbandoned;	}	return paintState == paintAbandoned;}void Editor::RedrawRect(PRectangle rc) {	//Platform::DebugPrintf("Redraw %0d,%0d - %0d,%0d\n", rc.left, rc.top, rc.right, rc.bottom);	// Clip the redraw rectangle into the client area	PRectangle rcClient = GetClientRectangle();	if (rc.top < rcClient.top)		rc.top = rcClient.top;	if (rc.bottom > rcClient.bottom)		rc.bottom = rcClient.bottom;	if (rc.left < rcClient.left)		rc.left = rcClient.left;	if (rc.right > rcClient.right)		rc.right = rcClient.right;	if ((rc.bottom > rc.top) && (rc.right > rc.left)) {		wMain.InvalidateRectangle(rc);	}}void Editor::Redraw() {	//Platform::DebugPrintf("Redraw all\n");	PRectangle rcClient = GetClientRectangle();	wMain.InvalidateRectangle(rcClient);	//wMain.InvalidateAll();}void Editor::RedrawSelMargin(int line) {	if (!AbandonPaint()) {		if (vs.maskInLine) {			Redraw();		} else {			PRectangle rcSelMargin = GetClientRectangle();			rcSelMargin.right = vs.fixedColumnWidth;			if (line != -1) {				int position = pdoc->LineStart(line);				PRectangle rcLine = RectangleFromRange(position, position);				rcSelMargin.top = rcLine.top;				rcSelMargin.bottom = rcLine.bottom;			}			wMain.InvalidateRectangle(rcSelMargin);		}	}}PRectangle Editor::RectangleFromRange(int start, int end) {	int minPos = start;	if (minPos > end)		minPos = end;	int maxPos = start;	if (maxPos < end)		maxPos = end;	int minLine = cs.DisplayFromDoc(pdoc->LineFromPosition(minPos));	int lineDocMax = pdoc->LineFromPosition(maxPos);	int maxLine = cs.DisplayFromDoc(lineDocMax) + cs.GetHeight(lineDocMax) - 1;	PRectangle rcClient = GetTextRectangle();	PRectangle rc;	rc.left = vs.fixedColumnWidth;	rc.top = (minLine - topLine) * vs.lineHeight;	if (rc.top < 0)		rc.top = 0;	rc.right = rcClient.right;	rc.bottom = (maxLine - topLine + 1) * vs.lineHeight;	// Ensure PRectangle is within 16 bit space	rc.top = Platform::Clamp(rc.top, -32000, 32000);	rc.bottom = Platform::Clamp(rc.bottom, -32000, 32000);	return rc;}void Editor::InvalidateRange(int start, int end) {	RedrawRect(RectangleFromRange(start, end));}int Editor::CurrentPosition() {	return currentPos;}bool Editor::SelectionEmpty() {	return anchor == currentPos;}int Editor::SelectionStart() {	return Platform::Minimum(currentPos, anchor);}int Editor::SelectionEnd() {	return Platform::Maximum(currentPos, anchor);}void Editor::SetRectangularRange() {	if (selType == selRectangle) {		xStartSelect = XFromPosition(anchor);		xEndSelect = XFromPosition(currentPos);	}}void Editor::InvalidateSelection(int currentPos_, int anchor_, bool invalidateWholeSelection) {	if (anchor != anchor_ || selType == selRectangle) {		invalidateWholeSelection = true;	}	int firstAffected = currentPos;	if (invalidateWholeSelection) {		if (firstAffected > anchor)			firstAffected = anchor;		if (firstAffected > anchor_)			firstAffected = anchor_;	}	if (firstAffected > currentPos_)		firstAffected = currentPos_;	int lastAffected = currentPos;	if (invalidateWholeSelection) {		if (lastAffected < anchor)			lastAffected = anchor;		if (lastAffected < anchor_)			lastAffected = anchor_;	}	if (lastAffected < (currentPos_ + 1))	// +1 ensures caret repainted		lastAffected = (currentPos_ + 1);	needUpdateUI = true;	InvalidateRange(firstAffected, lastAffected);}void Editor::SetSelection(int currentPos_, int anchor_) {	currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);	anchor_ = pdoc->ClampPositionIntoDocument(anchor_);	if ((currentPos != currentPos_) || (anchor != anchor_)) {		InvalidateSelection(currentPos_, anchor_, true);		currentPos = currentPos_;		anchor = anchor_;	}	SetRectangularRange();	ClaimSelection();}void Editor::SetSelection(int currentPos_) {	currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);	if (currentPos != currentPos_) {		InvalidateSelection(currentPos_, anchor, false);		currentPos = currentPos_;	}	SetRectangularRange();	ClaimSelection();}void Editor::SetEmptySelection(int currentPos_) {	selType = selStream;	moveExtendsSelection = false;	SetSelection(currentPos_, currentPos_);}bool Editor::RangeContainsProtected(int start, int end) const {	if (vs.ProtectionActive()) {		if (start > end) {			int t = start;			start = end;			end = t;		}		int mask = pdoc->stylingBitsMask;		for (int pos = start; pos < end; pos++) {			if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected())				return true;		}	}	return false;}bool Editor::SelectionContainsProtected() {	// DONE, but untested...: make support rectangular selection	bool scp = false;	if (selType == selStream) {		scp = RangeContainsProtected(anchor, currentPos);	} else {		SelectionLineIterator lineIterator(this);		while (lineIterator.Iterate()) {			if (RangeContainsProtected(lineIterator.startPos, lineIterator.endPos)) {				scp = true;				break;			}		}	}	return scp;}/** * Asks document to find a good position and then moves out of any invisible positions. */int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {	pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd);	if (vs.ProtectionActive()) {		int mask = pdoc->stylingBitsMask;		if (moveDir > 0) {			if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) {				while ((pos < pdoc->Length()) &&				        (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()))					pos++;			}		} else if (moveDir < 0) {			if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {				while ((pos > 0) &&				        (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))					pos--;			}		}	}	return pos;}int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {	int delta = newPos - currentPos;	newPos = pdoc->ClampPositionIntoDocument(newPos);	newPos = MovePositionOutsideChar(newPos, delta);	if (sel != noSel) {		selType = sel;	}	if (sel != noSel || moveExtendsSelection) {		SetSelection(newPos);	} else {		SetEmptySelection(newPos);	}	ShowCaretAtCurrentPosition();	if (ensureVisible) {		EnsureCaretVisible();	}	NotifyMove(newPos);	return 0;}int Editor::MovePositionSoVisible(int pos, int moveDir) {	pos = pdoc->ClampPositionIntoDocument(pos);	pos = MovePositionOutsideChar(pos, moveDir);	int lineDoc = pdoc->LineFromPosition(pos);	if (cs.GetVisible(lineDoc)) {		return pos;	} else {		int lineDisplay = cs.DisplayFromDoc(lineDoc);		if (moveDir > 0) {			// lineDisplay is already line before fold as lines in fold use display line of line after fold			lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed());			return pdoc->LineStart(cs.DocFromDisplay(lineDisplay));		} else {			lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed());			return pdoc->LineEnd(cs.DocFromDisplay(lineDisplay));		}	}}/** * Choose the x position that the caret will try to stick to * as it moves up and down. */void Editor::SetLastXChosen() {	Point pt = LocationFromPosition(currentPos);	lastXChosen = pt.x;}void Editor::ScrollTo(int line, bool moveThumb) {	int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());	if (topLineNew != topLine) {		// Try to optimise small scrolls		int linesToMove = topLine - topLineNew;		SetTopLine(topLineNew);		ShowCaretAtCurrentPosition();		// Perform redraw rather than scroll if many lines would be redrawn anyway.#ifndef UNDER_CE		if ((abs(linesToMove) <= 10) && (paintState == notPainting)) {			ScrollText(linesToMove);		} else {			Redraw();		}#else		Redraw();#endif		if (moveThumb) {			SetVerticalScrollPos();		}	}}void Editor::ScrollText(int /* linesToMove */) {	//Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove);	Redraw();}void Editor::HorizontalScrollTo(int xPos) {	//Platform::DebugPrintf("HorizontalScroll %d\n", xPos);	if (xPos < 0)		xPos = 0;	if ((wrapState == eWrapNone) && (xOffset != xPos)) {		xOffset = xPos;		SetHorizontalScrollPos();		RedrawRect(GetClientRectangle());	}}void Editor::MoveCaretInsideView(bool ensureVisible) {	PRectangle rcClient = GetTextRectangle();	Point pt = LocationFromPosition(currentPos);	if (pt.y < rcClient.top) {		MovePositionTo(PositionFromLocation(		            Point(lastXChosen, rcClient.top)),		        noSel, ensureVisible);	} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {		int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;		MovePositionTo(PositionFromLocation(		            Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),		        noSel, ensureVisible);	}}int Editor::DisplayFromPosition(int pos) {	int lineDoc = pdoc->LineFromPosition(pos);	int lineDisplay = cs.DisplayFromDoc(lineDoc);	AutoSurface surface(this);	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));	if (surface && ll) {		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);		unsigned int posLineStart = pdoc->LineStart(lineDoc);		int posInLine = pos - posLineStart;		lineDisplay--; // To make up for first increment ahead.		for (int subLine = 0; subLine < ll->lines; subLine++) {			if (posInLine >= ll->LineStart(subLine)) {				lineDisplay++;			}		}	}	return lineDisplay;}/** * Ensure the caret is reasonably visible in context. *Caret policy in SciTEIf slop is set, we can define a slop value.This value defines an unwanted zone (UZ) where the caret is... unwanted.This zone is defined as a number of pixels near the vertical margins,and as a number of lines near the horizontal margins.By keeping the caret away from the edges, it is seen within its context,so it is likely that the identifier that the caret is on can be completely seen,and that the current line is seen with some of the lines following it which areoften dependent on that line.If strict is set, the policy is enforced... strictly.The caret is centred on the display if slop is not set,and cannot go in the UZ if slop is set.If jumps is set, the display is moved more energeticallyso the caret can move in the same direction longer before the policy is applied again.'3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin.If even is not set, instead of having symmetrical UZs,the left and bottom UZs are extended up to right and top UZs respectively.This way, we favour the displaying of useful information: the begining of lines,where most code reside, and the lines after the caret, eg. the body of a function.     |        |       |      |                                            |slop | strict | jumps | even | Caret can go to the margin                 | When reaching limit

⌨️ 快捷键说明

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