| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  |  * Copyright (c) 2013 Maximilian Güntner <maximilian.guentner@gmail.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is subject to the terms and conditions of version 2 of | 
					
						
							|  |  |  |  * the GNU General Public License.  See the file gpl-2.0.txt in the main | 
					
						
							|  |  |  |  * directory of this archive for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Original License: | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  |  * This file is part of the Nepomuk widgets collection | 
					
						
							|  |  |  |  * Copyright (c) 2013 Denis Steckelmacher <steckdenis@yahoo.fr> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Library General Public | 
					
						
							|  |  |  |  * License version 2.1 as published by the Free Software Foundation, | 
					
						
							|  |  |  |  * or any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Library General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Library General Public License | 
					
						
							|  |  |  |  * along with this library; see the file COPYING.LIB.  If not, write to | 
					
						
							|  |  |  |  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 
					
						
							|  |  |  |  * Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "groupedlineedit.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-22 09:44:28 -08:00
										 |  |  | #include <QStyleOptionFrameV3>
 | 
					
						
							|  |  |  | #include <QFontMetrics>
 | 
					
						
							|  |  |  | #include <QApplication>
 | 
					
						
							|  |  |  | #include <QScrollBar>
 | 
					
						
							|  |  |  | #include <QTextDocument>
 | 
					
						
							|  |  |  | #include <QTextBlock>
 | 
					
						
							|  |  |  | #include <QTextLayout>
 | 
					
						
							|  |  |  | #include <QTextLine>
 | 
					
						
							|  |  |  | #include <QPainter>
 | 
					
						
							|  |  |  | #include <QPainterPath>
 | 
					
						
							|  |  |  | #include <QBrush>
 | 
					
						
							|  |  |  | #include <QColor>
 | 
					
						
							|  |  |  | #include <QPalette>
 | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | struct GroupedLineEdit::Private { | 
					
						
							|  |  |  | 	struct Block { | 
					
						
							|  |  |  | 		int start; | 
					
						
							|  |  |  | 		int end; | 
					
						
							|  |  |  | 		QString text; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	QVector<Block> blocks; | 
					
						
							|  |  |  | 	QVector<QColor> colors; | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | GroupedLineEdit::GroupedLineEdit(QWidget *parent) : QPlainTextEdit(parent), | 
					
						
							|  |  |  | 	d(new Private) | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	setWordWrapMode(QTextOption::NoWrap); | 
					
						
							|  |  |  | 	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | 
					
						
							|  |  |  | 	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	document()->setMaximumBlockCount(1); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GroupedLineEdit::~GroupedLineEdit() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	delete d; | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString GroupedLineEdit::text() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	// Remove the block crosses from the text
 | 
					
						
							|  |  |  | 	return toPlainText(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int GroupedLineEdit::cursorPosition() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	return textCursor().positionInBlock(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::addBlock(int start, int end) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	Private::Block block; | 
					
						
							|  |  |  | 	block.start = start; | 
					
						
							|  |  |  | 	block.end = end; | 
					
						
							| 
									
										
										
										
											2014-07-10 09:24:57 -07:00
										 |  |  | 	block.text = text().mid(start, end - start + 1).remove(',').trimmed(); | 
					
						
							| 
									
										
										
										
											2014-07-10 13:19:07 -03:00
										 |  |  | 	if (block.text.isEmpty()) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	d->blocks.append(block); | 
					
						
							|  |  |  | 	viewport()->update(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::addColor(QColor color) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	d->colors.append(color); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::removeAllColors() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	d->colors.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QStringList GroupedLineEdit::getBlockStringList() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QStringList retList; | 
					
						
							| 
									
										
										
										
											2014-07-29 13:06:30 -03:00
										 |  |  | 	foreach (const Private::Block &block, d->blocks) | 
					
						
							| 
									
										
										
										
											2014-03-03 13:25:55 -08:00
										 |  |  | 		retList.append(block.text); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | 	return retList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::setCursorPosition(int position) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QTextCursor c = textCursor(); | 
					
						
							|  |  |  | 	c.setPosition(position, QTextCursor::MoveAnchor); | 
					
						
							|  |  |  | 	setTextCursor(c); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::setText(const QString &text) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	setPlainText(text); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::clear() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QPlainTextEdit::clear(); | 
					
						
							|  |  |  | 	removeAllBlocks(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::selectAll() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QTextCursor c = textCursor(); | 
					
						
							|  |  |  | 	c.select(QTextCursor::LineUnderCursor); | 
					
						
							|  |  |  | 	setTextCursor(c); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::removeAllBlocks() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	d->blocks.clear(); | 
					
						
							|  |  |  | 	viewport()->update(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QSize GroupedLineEdit::sizeHint() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QSize rs( | 
					
						
							| 
									
										
										
										
											2014-05-22 11:40:22 -07:00
										 |  |  | 		40, | 
					
						
							|  |  |  | 		document()->findBlock(0).layout()->lineAt(0).height() + | 
					
						
							|  |  |  | 			document()->documentMargin() * 2 + | 
					
						
							|  |  |  | 			frameWidth() * 2); | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	return rs; | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QSize GroupedLineEdit::minimumSizeHint() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	return sizeHint(); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::keyPressEvent(QKeyEvent *e) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	switch (e->key()) { | 
					
						
							|  |  |  | 	case Qt::Key_Return: | 
					
						
							|  |  |  | 	case Qt::Key_Enter: | 
					
						
							|  |  |  | 		emit editingFinished(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	QPlainTextEdit::keyPressEvent(e); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GroupedLineEdit::paintEvent(QPaintEvent *e) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-22 09:44:28 -08:00
										 |  |  | #if !defined __APPLE__
 | 
					
						
							|  |  |  | 	// for reasons we don't understand, yet, touching the painter
 | 
					
						
							|  |  |  | 	// here (even drawing the fill rect) causes the QPlainTextEdit
 | 
					
						
							|  |  |  | 	// paintEvent to not draw the text on MacOS.
 | 
					
						
							|  |  |  | 	// So as a workaround until this is better understood we need
 | 
					
						
							|  |  |  | 	// to disable the eye candy
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QTextLine line = document()->findBlock(0).layout()->lineAt(0); | 
					
						
							|  |  |  | 	QPainter painter(viewport()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	painter.setRenderHint(QPainter::Antialiasing, true); | 
					
						
							|  |  |  | 	painter.fillRect(0, 0, viewport()->width(), viewport()->height(), palette().base()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QVectorIterator<QColor> i(d->colors); | 
					
						
							|  |  |  | 	i.toFront(); | 
					
						
							| 
									
										
										
										
											2014-05-22 11:40:22 -07:00
										 |  |  | 	foreach (const Private::Block &block, d->blocks) { | 
					
						
							| 
									
										
										
										
											2014-05-27 20:06:24 -03:00
										 |  |  | 		qreal start_x = line.cursorToX(block.start, QTextLine::Leading); | 
					
						
							|  |  |  | #if QT_VERSION >= 0x050000
 | 
					
						
							|  |  |  | 		qreal end_x = line.cursorToX(block.end-1, QTextLine::Trailing); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		qreal end_x = line.cursorToX(block.end, QTextLine::Trailing); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 		QPainterPath path; | 
					
						
							|  |  |  | 		QRectF rectangle( | 
					
						
							| 
									
										
										
										
											2014-05-22 11:40:22 -07:00
										 |  |  | 			start_x - 1.0 - double(horizontalScrollBar()->value()), | 
					
						
							|  |  |  | 			1.0, | 
					
						
							|  |  |  | 			end_x - start_x + 2.0, | 
					
						
							|  |  |  | 			double(viewport()->height() - 2)); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 		if (!i.hasNext()) | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 			i.toFront(); | 
					
						
							|  |  |  | 		path.addRoundedRect(rectangle, 5.0, 5.0); | 
					
						
							|  |  |  | 		painter.setPen(i.peekNext()); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 		if (palette().color(QPalette::Text).lightnessF() <= 0.3) | 
					
						
							| 
									
										
										
										
											2013-12-19 17:16:57 -02:00
										 |  |  | 			painter.setBrush(i.next().lighter()); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 		else if (palette().color(QPalette::Text).lightnessF() <= 0.6) | 
					
						
							| 
									
										
										
										
											2013-12-19 17:16:57 -02:00
										 |  |  | 			painter.setBrush(i.next()); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			painter.setBrush(i.next().darker()); | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 		painter.drawPath(path); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-22 09:44:28 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-11-02 15:23:53 +01:00
										 |  |  | 	QPlainTextEdit::paintEvent(e); | 
					
						
							| 
									
										
										
										
											2013-11-02 02:20:02 +01:00
										 |  |  | } |