/*!

*/
void QFoldPanel::mousePressEvent(QMouseEvent *e)
{
	if ( !editor() || !editor()->languageDefinition() || (e->button() != Qt::LeftButton) )
	{
		QPanel::mousePressEvent(e);
		return;
	}


	QDocument *doc = editor()->document();
	QLanguageDefinition *def = editor()->languageDefinition();

	int ln = mapRectPosToLine(e->pos());
	if ( ln != -1 ){
		QDocumentLine b = doc->line(ln);

		if ( b.hasFlag(QDocumentLine::CollapsedBlockStart) )
			def->expand(doc, ln);
		else //if ( def->blockFlags(doc, ln, 0) & QLanguageDefinition::Collapsible ) collapse checks if it can collapse the line
			def->collapse(doc, ln);
		editor()->setFocus();
	} else
		QPanel::mousePressEvent(e);

}
Beispiel #2
0
/*!

*/
void QFoldPanel::mousePressEvent(QMouseEvent *e)
{
	if ( !editor() || !editor()->languageDefinition() || (e->button() != Qt::LeftButton) )
	{
		QPanel::mousePressEvent(e);
		return;
	}
	
	bool act = false;
	QDocument *doc = editor()->document();
	QLanguageDefinition *def = editor()->languageDefinition();
	
	for ( int i = 0; i < m_rects.count(); ++i )
	{
		if ( !m_rects.at(i).contains(e->pos()) )
			continue;
		
		int ln = m_lines.at(i);
		
		QDocumentLine b = doc->line(ln);
		
		if ( b.hasFlag(QDocumentLine::CollapsedBlockStart) )
			def->expand(doc, ln);
		else if ( def->blockFlags(doc, ln, 0) & QLanguageDefinition::Collapsible )
			def->collapse(doc, ln);
		
		act = true;
	}
	
	if ( act )
		editor()->setFocus();
	else
		QPanel::mousePressEvent(e);
	
}
Beispiel #3
0
bool QFoldPanel::event(QEvent *e) {
	if (e->type() == QEvent::ToolTip) {		
		QDocument *doc = editor()->document();
		QLanguageDefinition *def = doc->languageDefinition();

		QHelpEvent* helpEvent = static_cast<QHelpEvent*>(e);
		int line = mapRectPosToLine(helpEvent->pos());
		if ( def && doc && line != -1 && doc->line(line).hasFlag(QDocumentLine::CollapsedBlockStart) ){
			QFoldedLineIterator it = def->foldedLineIterator(doc, line);
			it.incrementUntilBlockEnd();
			QString tooltip;
			if (it.lineNr - line < 16)
				tooltip = doc->exportAsHtml(doc->cursor(line,0,it.lineNr),true,true);
			else {
				tooltip = doc->exportAsHtml(doc->cursor(line,0,line+7),true,true);
				tooltip.replace("</body></html>","");
				tooltip += "<br>...<br>";
				tooltip += doc->exportAsHtml(doc->cursor(it.lineNr-7,0,it.lineNr),false);
				tooltip +=  "</body></html>";
			}
			if (tooltip.isEmpty()) QToolTip::hideText();
			else QToolTip::showText(helpEvent->globalPos(), tooltip);
			e->setAccepted(true);
		}
	}
	return QWidget::event(e);
}
/*!
	\internal
*/
void QLineChangePanel::paint(QPainter *p, QEditor *e)
{
	if ( !e || !e->document() )
		return;

	const QFontMetrics fm( e->document()->font() );

	int n, posY,
//		maxCount = 0,
		as = fm.ascent(),
		ls = fm.lineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();

	QString txt;

	QDocument *d = e->document();
	n = d->lineNumber(contentsY);
	posY = 2 + d->y(n) - contentsY;

	for ( ; ; ++n )
	{
		//qDebug("n = %i; pos = %i", n, posY);
		QDocumentLine line = d->line(n);

		if ( line.isNull() || ((posY - as) > pageBottom) )
			break;

		if ( line.isHidden() )
			continue;

		int span = line.lineSpan();

		if ( d->isLineModified(line) )
		{
			p->fillRect(1, posY, 2, ls * span, Qt::yellow);
		} else if ( d->hasLineEverBeenModified(line) ) {
			p->fillRect(1, posY, 2, ls * span, Qt::green);
		}

		posY += ls * span;
	}
}
/*!
	\brief Set a search option
	\param opt option to set
	\param on whether to enable the option
*/
void QDocumentSearch::setOption(Option opt, bool on)
{
	if ( on )
		m_option |= opt;
	else
		m_option &= ~opt;
	
	if ( (opt & QDocumentSearch::HighlightAll) && m_highlight.count() )
	{
		QDocument *d = m_editor->document();
		
		if ( m_group != -1 && !on )
		{
			d->clearMatches(m_group);
			d->flushMatches(m_group);
			m_group = -1;
		} else if ( m_group == -1 && on ) {
			m_group = d->getNextGroupId();
			
			QFormatScheme *f = d->formatScheme();
			
			if ( !f )
				f = QDocument::formatFactory();
			
			if ( !f )
			{
				qWarning("No format scheme set to the document and no global default one available.\n"
						"-> highlighting of search matches disabled.");
				return;
			}
			
			int sid = f->id("search");
			
			foreach ( const QDocumentCursor& c, m_highlight )
			{
				//QFormatRange r(c.anchorColumnNumber(), c.columnNumber() - c.anchorColumnNumber(), sid);
				
				d->addMatch(m_group,
							c.lineNumber(),
							c.anchorColumnNumber(),
							c.columnNumber() - c.anchorColumnNumber(),
							sid);
			}
Beispiel #6
0
/*!
	\internal
*/
bool QLineChangePanel::paint(QPainter *p, QEditor *e)
{
	if ( !e || !e->document() )
		return true;

	int n, posY,
		as = QFontMetrics(e->document()->font()).ascent(),
		ls = e->document()->getLineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();

	QString txt;

	QDocument *d = e->document();
	n = d->lineNumber(contentsY);
	posY = 2 + d->y(n) - contentsY;

	for ( ; ; ++n )
	{
		//qDebug("n = %i; pos = %i", n, posY);
		QDocumentLine line = d->line(n);

		if ( line.isNull() || ((posY - as) > pageBottom) )
			break;

		if ( line.isHidden() )
			continue;

		int span = line.lineSpan();

		if ( d->isLineModified(line) )
		{
			p->fillRect(1, posY, 2, ls * span, QColor(255, 216, 0)); // yellow
		} else if ( d->hasLineEverBeenModified(line) ) {
			p->fillRect(1, posY, 2, ls * span, QColor(70, 191, 0)); // green
		}

		posY += ls * span;
	}
	
	return true;
}
Beispiel #7
0
/*!

*/
void QFoldPanel::paint(QPainter *p, QEditor *e)
{
	QDocument *doc = editor()->document();
	QLanguageDefinition *def = e->languageDefinition();
	
	if ( !def || !doc )
	{
		return;
	}
	
	m_rects.clear();
	m_lines.clear();
	
	bool bVisible = false; //,
	//	inCursorBlock = false;
	
	QDocumentLine block;
	const QFontMetrics fm(doc->font());
	
	int n,
		pos,
		depth = 0,
		max = doc->lines(),
		h = fm.height(),
		ls = fm.lineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();
	
	pos = - contentsY;
	
	//qDebug("beg pos : %i", pos);
	
	for ( n = 0; n < max; ++n )
	{
		if ( pos > pageBottom )
			break;
		
		block = doc->line(n);
		
		if ( block.isHidden() )
		{
			continue;
		}
		
		int len = ls * block.lineSpan();
		int flags = def->blockFlags(doc, n, depth);
		short open = QCE_FOLD_OPEN_COUNT(flags);
		short close = QCE_FOLD_CLOSE_COUNT(flags);
		
		bVisible = ((pos + len) >= 0);
		
		int oldDepth = depth;
		
		depth -= close;
		
		if ( depth < 0 )
			depth = 0;
		
		depth += open;
		
		if ( open )
		{
			if ( flags & QLanguageDefinition::Collapsed )
			{
				int bound = (ls - 8) / 2;
				int mid = pos + len - ls / 6;
				
				// outermost block folded : none of the opening is actually opened
				depth -= open;
				
				if ( bVisible )
				{
					// draw icon
					
					if ( bound > 0 && oldDepth > 0 )
					{
						p->drawLine(7, pos, 7, pos + bound);
					}
					
					if ( close )
					{
						p->drawLine(7, pos + 8 + bound, 7, mid);
						p->drawLine(7, mid, 12, mid);
					}
					
					m_lines << n;
					m_rects << drawIcon(p, e, 3, pos + bound, true);
				}
				
				int sub = open;
				
				//qDebug("%i : +%i", n, open);
				
				while ( sub > 0 && ((n + 1) < max) )
				{
					++n;
					block = doc->line(n);
					
					if ( !block.isHidden() )
					{
						if ( bVisible )
							p->drawLine(7, pos + 8 + bound, 7, pos + len);
						
						--n;
						break;
					}
					
					int sflags = def->blockFlags(doc, n, depth + 1);
					short sopen = QCE_FOLD_OPEN_COUNT(sflags);
					short sclose = QCE_FOLD_CLOSE_COUNT(sflags);
					
					sub -= sclose;
					
					if ( sub <= 0 )
						break;
					
					sub += sopen;
				}
				
				depth += sub;
				
				if ( bVisible && depth > 0 )
				{
					if ( 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 ( oldDepth > 0 && bound > 0 )
						p->drawLine(7, pos, 7, pos + bound);
					
					m_lines << n;
					m_rects << drawIcon(p, e, 3, pos + bound, false);
					
					int mid = pos + len - ls / 6;
					
					if ( close )
						p->drawLine(7, mid, 12, mid);
					
					if ( bound > 0 )
						p->drawLine(7, pos + 8 + bound, 7, pos + len);
				}
			}
		} else if ( (oldDepth > 0) && bVisible ) {
			if ( close )
			{
				int mid = pos + len - ls / 6;
				
				p->drawLine(7, pos, 7, mid);
				p->drawLine(7, mid, 12, mid);
				
				if ( depth > 0 )
					p->drawLine(7, pos, 7, pos + len);
			} else  {
				p->drawLine(7, pos, 7, pos + len);
			}
		}
		
		pos += len;
	}
}
/*!
	\internal
*/
void QLineMarkPanel::paint(QPainter *p, QEditor *e)
{
	if ( !e || !e->document() )
		return;
	
	m_rects.clear();
	m_lines.clear();
	QDocument *d = e->document();
	
	int maxMarksPerLine = d->maxMarksPerLine();
	
	setFixedWidth(maxMarksPerLine ? maxMarksPerLine * 16 + 2 : 18);
	
	const QFontMetrics fm( d->font() );
	
	int n, posY,
		maxCount = 0,
		as = fm.ascent(),
		ls = fm.lineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();
	
	QString txt;
	const QFontMetrics sfm(fontMetrics());
	QLineMarksInfoCenter *mic = QLineMarksInfoCenter::instance();
	
	n = d->lineNumber(contentsY);
	posY = 2 + d->y(n) - contentsY;
	
	//qDebug("first = %i; last = %i", first, last);
	//qDebug("beg pos : %i", posY);
	//qDebug("<session>");
	for ( ; ; ++n )
	{
		//qDebug("n = %i; pos = %i", n, posY);
		QDocumentLine line = d->line(n);
		
		if ( line.isNull() || ((posY - as) > pageBottom) )
			break;
		
		if ( line.isHidden() )
			continue;
		
		m_lines << n;
		m_rects << QRect(0, posY, width(), ls);
		
		if ( maxMarksPerLine )
		{
			int count = 1;
			QList<int> lm = line.marks();
			
			foreach ( int id, lm )
			{
				QPixmap pix = mic->markType(id).icon;
				
				if ( pix.isNull() )
					continue;
				
				int h = qMin(pix.height(), ls),
					w = qMin(pix.width(), 16),
					x = count,
					y = posY + ( (ls - h) >> 1 );
				
				p->drawPixmap(x, y, w, h, pix);
				
				count += 16;
			}
		}

		posY += ls * line.lineSpan();
	}
/*!

*/
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 #10
0
/*!

*/
bool QLineNumberPanel::paint(QPainter *p, QEditor *e)
{
	/*
		possible Unicode caracter for wrapping arrow :
			0x21B3
			0x2937
	*/
	
	QFont f(font());
	f.setWeight(QFont::Bold);
	const QFontMetrics sfm(f);
	
	#ifndef WIN32
	static const QChar wrappingArrow(0x2937);
	const QFontMetrics specialSfm(sfm);
	#else
	// 0xC4 gives a decent wrapping arrow in Wingdings fonts, availables on all windows systems
	// this is a hackish fallback to workaround Windows issues with Unicode...
	static const QChar wrappingArrow(0xC4);
	QFont specialFont(font());
	specialFont.setRawName("Wingdings");
	const QFontMetrics specialSfm(specialFont);
	#endif
	
	const int max = e->document()->lines();
	const int panelWidth = sfm.width(QString::number(max)) + 5;
	setFixedWidth(panelWidth);
	
	const QFontMetrics fm( e->document()->font() );
	
	int n, posY,
		as = fm.ascent(),
		ls = fm.lineSpacing(),
		pageBottom = e->viewport()->height(),
		contentsY = e->verticalOffset();
	
	QString txt;
	QDocument *d = e->document();
	const int cursorLine = e->cursor().lineNumber();
	
	n = d->lineNumber(contentsY);
	posY = as + 2 + d->y(n) - contentsY;
	
	//qDebug("first = %i; last = %i", first, last);
	//qDebug("beg pos : %i", posY);
	
	for ( ; ; ++n )
	{
		//qDebug("n = %i; pos = %i", n, posY);
		QDocumentLine line = d->line(n);
		
		if ( line.isNull() || ((posY - as) > pageBottom) )
			break;
		
		if ( line.isHidden() )
			continue;
		
		bool draw = true;
		
		if ( !m_verbose )
		{
			draw = !((n + 1) % 10) || !n || line.marks().count();
		}
		
		txt = QString::number(n + 1);
		
		if ( n == cursorLine )
		{
			draw = true;
			
			p->save();
			QFont f = p->font();
			f.setWeight(QFont::Bold);
			
			p->setFont(f);
		}
		
		if ( draw )
		{
			p->drawText(width() - 2 - sfm.width(txt),
						posY,
						txt);
			
		} else {
			int yOff = posY - (as + 1) + ls / 2;
			
			if ( (n + 1) % 5 )
				p->drawPoint(width() - 5, yOff);
			else
				p->drawLine(width() - 7, yOff, width() - 2, yOff);
		}
		
		if ( line.lineSpan() > 1 )
		{
			#ifdef Q_OS_WIN32
			p->save();
			specialFont.setBold(n == cursorLine); //todo: only get bold on the current wrapped line
			p->setFont(specialFont);
			#endif

			for ( int i = 1; i < line.lineSpan(); ++i )
			{
				// draw line wrapping indicators
				//p->drawText(width() - 2 - sfm.width(wrappingArrow), posY + i * ls, wrappingArrow);
				p->drawText(width() - 1 - specialSfm.width(wrappingArrow), posY + i * ls, wrappingArrow);
			}
			
			#ifdef Q_OS_WIN32
			p->restore();
			#endif
		}
		
		if ( n == cursorLine )
		{
			p->restore();
		}
		
		posY += ls * line.lineSpan();
	}
	
	//p->setPen(Qt::DotLine);
	//p->drawLine(width()-1, 0, width()-1, pageBottom);
	
	//setFixedWidth(sfm.width(txt) + 5);
	return true;
}
Beispiel #11
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;
}