/*!

*/
bool QFoldPanel::paint(QPainter *p, QEditor *e)
{
	QDocument *doc = editor()->document();
	QLanguageDefinition *def = e->languageDefinition();

	if ( !def || !doc )
	{
		return true;
	}

	m_rects.clear();
	m_lines.clear();

	bool bVisible = false; //,
	//	inCursorBlock = false;

	int endHighlightLineNr = -1;

	int pos,
		max = doc->lines(),
		ls = doc->getLineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();

	int xMid = 6,
		iconSize = 9,
		yIconOffset = (ls - iconSize) / 2;
	
	pos = - contentsY;

	//qDebug("beg pos : %i", pos);

	p->save();
	QPen linePen(QColor(128,0,128));
	linePen.setWidth(3);
	linePen.setCapStyle(Qt::FlatCap);
	p->setPen(linePen);

	QFoldedLineIterator fli = def->foldedLineIterator(doc);

	for (; fli.lineNr<max; ++fli) {
		if ( pos > pageBottom )
			break;

		const QDocumentLine &line=fli.line;

		if ( fli.lineFlagsInvalid() ){
			//correct folding when the folding of the current line is invalid
			//problems: slow (but O(n) like the paint method is anyways), doesn't work if panel is hidden
			//pro: simple, doesn't correct invalid, but invisible folding (e.g. like folding that is only temporary invalid, until the user writes a closing bracket; otherwise writing $$ would expand every folded $-block)
			doc->correctFolding(fli.lineNr, doc->lines()); //this will again call paint
			break;
		}

		if ( line.isHidden() ) {
			continue;
		}

		int len = ls * line.lineSpan();

		bVisible = ((pos + len) >= 0);

		if (bVisible) {

			if ( fli.open ) {
				if ( line.hasFlag(QDocumentLine::CollapsedBlockStart) ) {

					 // line above icon
					int topLineEnd = yIconOffset-1;
					if (topLineEnd > 0 && fli.lineNr <= endHighlightLineNr)
						p->drawLine(xMid, pos, xMid, pos + topLineEnd);

					// draw icon
					m_lines << fli.lineNr;
					m_rects << drawIcon(p, e, 2, pos + yIconOffset, true, fli.lineNr == m_lastMouseLine);

					 // line below icon
					int bottomLineStart = yIconOffset + iconSize + 1;
					if (bottomLineStart < len && fli.lineNr < endHighlightLineNr)
						p->drawLine(xMid, pos + bottomLineStart, xMid, pos + len);
				} else {
					// line above icon
					int topLineEnd = yIconOffset;
					if (topLineEnd > 0 && fli.lineNr <= endHighlightLineNr)
						p->drawLine(xMid, pos, xMid, pos + topLineEnd);

					// draw icon
					m_lines << fli.lineNr;
					m_rects << drawIcon(p, e, 2, pos + yIconOffset, false, fli.lineNr == m_lastMouseLine);
					if (fli.lineNr == m_lastMouseLine) {
						QFoldedLineIterator findEnd = fli;
						findEnd.incrementUntilBlockEnd();
						endHighlightLineNr = findEnd.lineNr;
					}

					// line below icon
					int bottomLineStart = yIconOffset + iconSize;
					if ( bottomLineStart < len && fli.lineNr < endHighlightLineNr)
						p->drawLine(xMid, pos + bottomLineStart, xMid, pos + len);
				}
			} else if (fli.lineNr <= endHighlightLineNr) {
				if ( fli.lineNr == endHighlightLineNr ) {
					int mid = pos + len - ls / 6;
					p->drawLine(xMid, pos, xMid, mid); // line ending here
				} else {
					p->drawLine(xMid, pos, xMid, pos + len); // line continues
				}
			}
		}
		pos += len;
	}

	p->restore();
	return true;
}
Beispiel #2
0
/*!

*/
bool QFoldPanel::paint(QPainter *p, QEditor *e)
{
	QDocument *doc = editor()->document();
	QLanguageDefinition *def = e->languageDefinition();

	if ( !def || !doc )
	{
		return true;
	}

	m_rects.clear();
	m_lines.clear();

	bool bVisible = false; //,
	//	inCursorBlock = false;

	int pos,
		max = doc->lines(),
		ls = doc->getLineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();
	
	pos = - contentsY;

	//qDebug("beg pos : %i", pos);

	QFoldedLineIterator fli = def->foldedLineIterator(doc);

	bool oldFolding=false;

	for (; fli.lineNr<max; ++fli)
	{
		if ( pos > pageBottom )
			break;

		const QDocumentLine &line=fli.line;

		if ( fli.lineFlagsInvalid() ){
			//correct folding when the folding of the current line is invalid
			//problems: slow (but O(n) like the paint method is anyways), doesn't work if panel is hidden
			//pro: simple, doesn't correct invalid, but invisible folding (e.g. like folding that is only temporary invalid, until the user writes a closing bracket; otherwise writing $$ would expand every folded $-block)
			doc->correctFolding(fli.lineNr, doc->lines()); //this will again call paint
			return true;
		}

		if ( line.isHidden() )
		{
			continue;
		}

		int len = ls * line.lineSpan();

//		bool oldFolding = !fli.openParentheses.empty() && fli.openParentheses.first().line!=fli.lineNr;

		bVisible = ((pos + len) >= 0);

		if ( fli.open )
		{
			if ( line.hasFlag(QDocumentLine::CollapsedBlockStart) )
			{
				// outermost block folded : none of the opening is actually opened
				int bound = (ls - 8) / 2;
				int mid = pos + len - ls / 6;

				if ( bVisible )
				{
					// draw icon

					if ( bound > 0 && oldFolding )
					{
						p->drawLine(7, pos, 7, pos + bound);
					}

					if ( fli.close )
					{
						p->drawLine(7, pos + 8 + bound, 7, mid);
						p->drawLine(7, mid, 12, mid);
					}

					m_lines << fli.lineNr;
					m_rects << drawIcon(p, e, 3, pos + bound, true);
				}

				int firstParenthesisPos = fli.openParentheses.size() - fli.open;
				const FoldedParenthesis firstParenthesis = fli.openParentheses[firstParenthesisPos];

				while (fli.lineNr<doc->lines() &&
				       firstParenthesisPos<fli.openParentheses.size() &&
				       fli.openParentheses[firstParenthesisPos] == firstParenthesis){
					if (fli.lineNr < doc->lines()-1 && !doc->line(fli.lineNr+1).isHidden()) {
						if ( bVisible )
							p->drawLine(7, pos + 8 + bound, 7, pos + len);
						break;
					}
					++fli;
				}

				if ( bVisible && !fli.openParentheses.empty() )
				{
					if ( fli.close )
						p->drawLine(7, mid, 7, pos + len);
					else
						p->drawLine(7, pos + 8 + bound, 7, pos + len);
				}
			} else {
				if ( bVisible )
				{
					int bound = (ls - 8) / 2;

					if ( oldFolding && bound > 0 )
						p->drawLine(7, pos, 7, pos + bound);

					m_lines << fli.lineNr;
					m_rects << drawIcon(p, e, 3, pos + bound, false);

					int mid = pos + len - ls / 6;

					if ( fli.close )
						p->drawLine(7, mid, 12, mid);

					if ( bound > 0 )
						p->drawLine(7, pos + 8 + bound, 7, pos + len);
				}
			}
		} else if ( (oldFolding) && bVisible ) {
			if ( fli.close )
			{
				int mid = pos + len - ls / 6;

				p->drawLine(7, pos, 7, mid);
				p->drawLine(7, mid, 12, mid);

				if ( !fli.openParentheses.empty() )
					p->drawLine(7, pos, 7, pos + len);
			} else  {
				p->drawLine(7, pos, 7, pos + len);
			}
		}

		pos += len;
		oldFolding=!fli.openParentheses.empty();
	}
	
	return true;
}