1 /***************************************************************************
2 * Copyright (C) 2005-09 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
22 #include <QTextDocument>
23 #include <QTextLayout>
25 #include "graphicalui.h"
26 #include "styledlabel.h"
29 StyledLabel::StyledLabel(QWidget *parent)
31 _wrapMode(QTextOption::NoWrap),
32 _alignment(Qt::AlignVCenter|Qt::AlignLeft),
35 setMouseTracking(true);
37 QTextOption opt = _layout.textOption();
38 opt.setWrapMode(_wrapMode);
39 opt.setAlignment(_alignment);
40 _layout.setTextOption(opt);
43 void StyledLabel::setWrapMode(QTextOption::WrapMode mode) {
48 QTextOption opt = _layout.textOption();
49 opt.setWrapMode(mode);
50 _layout.setTextOption(opt);
55 void StyledLabel::setAlignment(Qt::Alignment alignment) {
56 if(_alignment == alignment)
59 _alignment = alignment;
60 QTextOption opt = _layout.textOption();
61 opt.setAlignment(alignment);
62 _layout.setTextOption(opt);
67 void StyledLabel::resizeEvent(QResizeEvent *event) {
68 QFrame::resizeEvent(event);
73 QSize StyledLabel::sizeHint() const {
77 void StyledLabel::updateSizeHint() {
79 int padding = frameWidth() * 2;
80 sh = _layout.boundingRect().size().toSize() + QSize(padding, padding);
88 void StyledLabel::setText(const QString &text) {
89 UiStyle *style = GraphicalUi::uiStyle();
91 UiStyle::StyledString sstr = style->styleString(style->mircToInternal(text), UiStyle::PlainMsg);
92 QList<QTextLayout::FormatRange> layoutList = style->toTextLayoutList(sstr.formatList, sstr.plainText.length(), 0);
94 // Use default font rather than the style's
95 QTextLayout::FormatRange fmtRange;
96 fmtRange.format.setFont(font());
98 fmtRange.length = sstr.plainText.length();
99 layoutList << fmtRange;
102 _clickables = ClickableList::fromString(sstr.plainText);
103 foreach(Clickable click, _clickables) {
104 if(click.type() == Clickable::Url) {
105 QTextLayout::FormatRange range;
106 range.start = click.start();
107 range.length = click.length();
108 range.format.setForeground(palette().link());
113 _layout.setText(sstr.plainText);
114 _layout.setAdditionalFormats(layoutList);
121 void StyledLabel::updateToolTip() {
122 if(frameRect().width() - 2*frameWidth() < _layout.minimumWidth())
123 setToolTip(QString("<qt>%1</qt>").arg(Qt::escape(_layout.text()))); // only rich text gets wordwrapped!
125 setToolTip(QString());
128 void StyledLabel::layout() {
130 qreal w = frameRect().width() - 2*frameWidth();
132 _layout.beginLayout();
134 QTextLine line = _layout.createLine();
137 line.setLineWidth(w);
138 line.setPosition(QPointF(0, h));
148 void StyledLabel::paintEvent(QPaintEvent *) {
149 QPainter painter(this);
151 qreal y = (frameRect().height() - _layout.boundingRect().height()) / 2;
152 _layout.draw(&painter, QPointF(0, y), _extraLayoutList);
155 int StyledLabel::posToCursor(const QPointF &pos) {
156 if(pos.y() < 0 || pos.y() > height())
159 for(int l = _layout.lineCount() - 1; l >= 0; l--) {
160 QTextLine line = _layout.lineAt(l);
161 if(pos.y() >= line.y()) {
162 return line.xToCursor(pos.x(), QTextLine::CursorOnCharacter);
168 void StyledLabel::mouseMoveEvent(QMouseEvent *event) {
169 if(event->buttons() == Qt::NoButton) {
170 Clickable click = _clickables.atCursorPos(posToCursor(event->posF()));
172 setHoverMode(click.start(), click.length());
178 void StyledLabel::leaveEvent(QEvent *) {
182 void StyledLabel::mousePressEvent(QMouseEvent *event) {
183 if(event->button() == Qt::LeftButton) {
184 Clickable click = _clickables.atCursorPos(posToCursor(event->posF()));
186 emit clickableActivated(click);
190 void StyledLabel::setHoverMode(int start, int length) {
191 if(_extraLayoutList.count() >= 1 && _extraLayoutList.first().start == start && _extraLayoutList.first().length == length)
194 QTextLayout::FormatRange range;
196 range.length = length;
197 range.format.setFontUnderline(true);
198 _extraLayoutList.clear();
199 _extraLayoutList << range;
201 setCursor(Qt::PointingHandCursor);
205 void StyledLabel::endHoverMode() {
206 _extraLayoutList.clear();
207 setCursor(Qt::ArrowCursor);