ea84b1e0cf5c2314bb4a53fce58e53e82fddba85
[quassel.git] / src / qtui / topiclabel.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005/06 by the Quassel Project                          *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
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.                                           *
9  *                                                                         *
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.                          *
14  *                                                                         *
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  ***************************************************************************/
20
21 #include "topiclabel.h"
22
23
24 #include <QDebug>
25
26 #include <QApplication>
27 #include <QDesktopServices>
28 #include <QPainter>
29 // #include <QHBoxLayout>
30 #include <QFont>
31 #include <QFontMetrics>
32
33 #include "qtui.h"
34 #include "message.h"
35
36 TopicLabel::TopicLabel(QWidget *parent)
37   : QFrame(parent),
38     offset(0),
39     dragStartX(0),
40     dragMode(false)
41 {
42 }
43
44 void TopicLabel::paintEvent(QPaintEvent *event) {
45   Q_UNUSED(event);
46
47   textPartOffset.clear();
48   
49   QPainter painter(this);
50   painter.setBackgroundMode(Qt::OpaqueMode);
51
52   // FIXME re-enable topic painting
53 #ifndef SPUTDEV
54   QRect drawRect = rect().adjusted(offset, 0, 0, 0);
55   QRect brect;
56   QString textPart;
57   foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
58     textPart = styledContents.plainText.mid(fr.start, fr.length);
59     textPartOffset << drawRect.left();
60     painter.setFont(fr.format.font());
61     painter.setPen(QPen(fr.format.foreground(), 0));
62     painter.setBackground(fr.format.background());
63     painter.drawText(drawRect, Qt::AlignLeft|Qt::AlignVCenter, textPart, &brect);
64     drawRect.setLeft(brect.right());
65   }
66 #endif
67 }
68
69 void TopicLabel::setText(const QString &text) {
70   if(_text == text)
71     return;
72
73   _text = text;
74   offset = 0;
75   update();
76
77 #ifndef SPUTDEV
78   styledContents = QtUi::style()->styleString(Message::mircToInternal(text));
79   int height = 1;
80   foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
81     height = qMax(height, QFontMetrics(fr.format.font()).height());
82   }
83
84   // ensure the label is editable (height != 1) if there is no text to show
85   if(text.isEmpty())
86     height = QFontMetrics(qApp->font()).height();
87   
88   // setFixedHeight(height);
89 #endif  
90   // show topic in tooltip
91   setToolTip(_text);
92 }
93
94
95 void TopicLabel::mouseMoveEvent(QMouseEvent *event) {
96   if(!dragMode)
97     return;
98
99   event->accept();
100   offset = event->pos().x() - dragStartX;
101   update();
102 }
103
104 void TopicLabel::mousePressEvent(QMouseEvent *event) {
105   event->accept();
106   dragMode = true;
107   dragStartX = event->pos().x() - offset;
108 }
109
110 void TopicLabel::mouseReleaseEvent(QMouseEvent *event) {
111   event->accept();
112   dragMode = false;
113   if(qAbs(offset) < 30) {
114     offset = 0;
115     update();
116   }
117 }
118
119 void TopicLabel::mouseDoubleClickEvent(QMouseEvent *event) {
120 #ifndef SPUTDEV
121   event->accept();
122   int textPart = 0;
123   int textOffset = 0;
124
125   if(textPartOffset.isEmpty())
126     return;
127
128   // find the text part that contains the url. We don't expect color codes in urls so we expect only full parts (yet?)
129   int x = event->pos().x();
130   while(textPart + 1 < textPartOffset.count()) {
131     if(textPartOffset[textPart + 1] < x) {
132       textPart++;
133       textOffset = textPartOffset[textPart];
134     } else {
135       break;
136     }
137   }
138
139   // we've Identified the needed text part \o/
140   QString text = styledContents.plainText.mid(styledContents.formatList[textPart].start, styledContents.formatList[textPart].length);
141
142   // now we have to find the the left and right word delimiters of the clicked word
143   QFontMetrics fontMetric(styledContents.formatList[textPart].format.font());
144   
145   int start = 0;
146   int spacePos = text.indexOf(" ");
147   while(spacePos != -1) {
148     if(fontMetric.width(text.left(spacePos + 1)) + textOffset < x) {
149       start = spacePos + 1;
150       spacePos = text.indexOf(" ", start + 1);
151     } else {
152       break;
153     }
154   }
155
156   int end = text.indexOf(" ", start);
157   int len = -1;
158   if(end != -1) {
159     len = end - start;
160   }
161   QString word = text.mid(start, len);
162   qDebug() << word;
163   QRegExp regex("^(h|f)t{1,2}ps?:\\/\\/");
164   if(regex.indexIn(word) != -1) {
165     QDesktopServices::openUrl(QUrl(word));
166   }
167 #endif
168   
169 }