Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
chatitem.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 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  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #ifndef CHATITEM_H_
22 #define CHATITEM_H_
23 
24 #include <QAction>
25 #include <QObject>
26 
27 #include "chatlinemodel.h"
28 #include "chatscene.h"
29 #include "clickable.h"
30 #include "uistyle.h"
31 #include "qtui.h"
32 
33 #include <QTextLayout>
34 
35 class ChatLine;
36 class ChatView;
37 
38 /* All external positions are relative to the parent ChatLine */
39 /* Yes, that's also true for the boundingRect() and related things */
40 
41 class ChatItem
42 {
43 protected:
44  // boundingRect is relative to the parent ChatLine
45  ChatItem(const QRectF &boundingRect, ChatLine *parent);
46  virtual ~ChatItem();
47 
48 public:
49  const QAbstractItemModel *model() const;
50  ChatLine *chatLine() const;
51  ChatScene *chatScene() const;
52  ChatView *chatView() const;
53  int row() const;
54  virtual ChatLineModel::ColumnType column() const = 0;
55 
56  // The boundingRect() is relative to the parent ChatLine
57  inline QRectF boundingRect() const;
58  inline qreal width() const;
59  inline qreal height() const;
60  inline QPointF pos() const;
61  inline qreal x() const;
62  inline qreal y() const;
63 
64  QPointF mapToLine(const QPointF &) const;
65  QPointF mapFromLine(const QPointF &) const;
66  QPointF mapToScene(const QPointF &) const;
67  QPointF mapFromScene(const QPointF &) const;
68 
69  virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
70  virtual inline int type() const { return ChatScene::ChatItemType; }
71 
72  QVariant data(int role) const;
73 
74  // selection stuff, to be called by the scene
75  QString selection() const;
76  void clearSelection();
77  void setFullSelection();
78  void continueSelecting(const QPointF &pos);
79  bool hasSelection() const;
80  bool isPosOverSelection(const QPointF &pos) const;
81 
82  QList<QRectF> findWords(const QString &searchWord, Qt::CaseSensitivity caseSensitive);
83 
84  virtual void addActionsToMenu(QMenu *menu, const QPointF &itemPos);
85  virtual void handleClick(const QPointF &pos, ChatScene::ClickMode);
86 
87  void initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode, Qt::Alignment = Qt::AlignLeft) const;
88 
90 
92  virtual void clearCache();
93 
94 protected:
99  };
100 
101  virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
102  virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
103  virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
104  virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) {}
105  virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) {}
106  virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *) {}
107 
108  QTextLayout *layout() const;
109 
110  virtual void initLayout(QTextLayout *layout) const;
111  virtual void doLayout(QTextLayout *) const;
112  virtual UiStyle::FormatList formatList() const;
113 
114  void paintBackground(QPainter *);
115  QVector<QTextLayout::FormatRange> selectionFormats() const;
116  virtual QVector<QTextLayout::FormatRange> additionalFormats() const;
117  void overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const;
118 
119  inline qint16 selectionStart() const { return _selectionStart; }
120  inline void setSelectionStart(qint16 start) { _selectionStart = start; }
121  inline qint16 selectionEnd() const { return _selectionEnd; }
122  inline void setSelectionEnd(qint16 end) { _selectionEnd = end; }
123  inline SelectionMode selectionMode() const { return _selectionMode; }
124  inline void setSelectionMode(SelectionMode mode) { _selectionMode = mode; }
125  void setSelection(SelectionMode mode, qint16 selectionStart, qint16 selectionEnd);
126 
127  qint16 posToCursor(const QPointF &pos) const;
128 
129  inline void setGeometry(qreal width, qreal height) { clearCache(); _boundingRect.setSize(QSizeF(width, height)); }
130  inline void setHeight(const qreal &height) { clearCache(); _boundingRect.setHeight(height); }
131  inline void setWidth(const qreal &width) { clearCache(); _boundingRect.setWidth(width); }
132  inline void setPos(const QPointF &pos) { _boundingRect.moveTopLeft(pos); }
133 
134 private:
137 
140 
141  mutable QTextLayout *_cachedLayout;
142 
143  // internal selection stuff
144  void setSelection(int start, int length);
145 
146  friend class ChatLine;
147 };
148 
149 
150 // ************************************************************
151 // TimestampChatItem
152 // ************************************************************
153 
156 {
157 public:
158  TimestampChatItem(const QRectF &boundingRect, ChatLine *parent) : ChatItem(boundingRect, parent) {}
159  virtual inline int type() const { return ChatScene::TimestampChatItemType; }
161 };
162 
163 
164 // ************************************************************
165 // SenderChatItem
166 // ************************************************************
168 class SenderChatItem : public ChatItem
169 {
170 public:
171  SenderChatItem(const QRectF &boundingRect, ChatLine *parent) : ChatItem(boundingRect, parent) {}
173  virtual void handleClick(const QPointF &pos, ChatScene::ClickMode clickMode);
174 
175 protected:
176  virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
177  virtual inline int type() const { return ChatScene::SenderChatItemType; }
178  virtual void initLayout(QTextLayout *layout) const;
179 };
180 
181 
182 // ************************************************************
183 // ContentsChatItem
184 // ************************************************************
186 
189 {
190  Q_DECLARE_TR_FUNCTIONS(ContentsChatItem)
191 
192 public:
193  ContentsChatItem(const QPointF &pos, const qreal &width, ChatLine *parent);
195 
196  virtual inline int type() const { return ChatScene::ContentsChatItemType; }
197 
199  QFontMetricsF *fontMetrics() const;
200 
201  virtual void clearCache();
202 
203 protected:
204  virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
205  virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
206  virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
207  virtual void handleClick(const QPointF &pos, ChatScene::ClickMode clickMode);
208 
209  virtual void addActionsToMenu(QMenu *menu, const QPointF &itemPos);
210  virtual void copyLinkToClipboard();
211 
212  virtual QVector<QTextLayout::FormatRange> additionalFormats() const;
213 
214  virtual void initLayout(QTextLayout *layout) const;
215  virtual void doLayout(QTextLayout *layout) const;
216  virtual UiStyle::FormatList formatList() const;
217 
218 private:
219  class ActionProxy;
221 
224 
225  Clickable clickableAt(const QPointF &pos) const;
226 
227  void endHoverMode();
228  void showWebPreview(const Clickable &click);
229  void clearWebPreview();
230 
231  qreal setGeometryByWidth(qreal w);
232 
233  QFontMetricsF *_fontMetrics;
234 
235  // we need a receiver for Action signals
237 
238  friend class ChatLine;
239  friend struct ContentsChatItemPrivate;
240 };
241 
242 
248 
250 };
251 
253 {
254 public:
255  WrapColumnFinder(const ChatItem *parent);
257 
258  qint16 nextWrapColumn(qreal width);
259 
260 private:
261  const ChatItem *item;
262  QTextLayout layout;
263  QTextLine line;
265  qint16 wordidx;
266  qint16 lineCount;
268 };
269 
270 
272 
276 class ContentsChatItem::ActionProxy : public QObject
277 {
278  Q_OBJECT
279 
280 public slots:
282 
283 private:
285 
289  inline ContentsChatItem *item() const
290  {
291  return static_cast<ContentsChatItem *>(qobject_cast<QAction *>(sender())->data().value<void *>());
292  }
293 };
294 
295 
296 /*************************************************************************************************/
297 
298 // Inlines
299 
300 QRectF ChatItem::boundingRect() const { return _boundingRect; }
301 qreal ChatItem::width() const { return _boundingRect.width(); }
302 qreal ChatItem::height() const { return _boundingRect.height(); }
303 QPointF ChatItem::pos() const { return _boundingRect.topLeft(); }
304 qreal ChatItem::x() const { return pos().x(); }
305 qreal ChatItem::y() const { return pos().y(); }
306 
307 #endif