Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
chatscene.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 CHATSCENE_H_
22 #define CHATSCENE_H_
23 
24 #include <QAbstractItemModel>
25 #include <QClipboard>
26 #include <QGraphicsItem>
27 #include <QGraphicsScene>
28 #include <QSet>
29 #include <QTimer>
30 #include <QUrl>
31 
32 #include "chatlinemodel.h"
33 #include "messagefilter.h"
34 
35 class AbstractUiMsg;
36 class ChatItem;
37 class ChatLine;
38 class ChatView;
39 class ColumnHandleItem;
40 class MarkerLineItem;
41 class WebPreviewItem;
42 
43 class QGraphicsSceneMouseEvent;
44 
45 class ChatScene : public QGraphicsScene
46 {
47  Q_OBJECT
48 
49 public:
50  enum CutoffMode {
53  };
54 
55  enum ItemType {
56  ChatLineType = QGraphicsItem::UserType + 1,
65  };
66 
67  enum ClickMode {
73  };
74 
75  ChatScene(QAbstractItemModel *model, const QString &idString, qreal width, ChatView *parent);
76  virtual ~ChatScene();
77 
78  inline QAbstractItemModel *model() const { return _model; }
79  inline MessageFilter *filter() const { return qobject_cast<MessageFilter *>(_model); }
80  inline QString idString() const { return _idString; }
81 
82  int rowByScenePos(qreal y) const;
83  inline int rowByScenePos(const QPointF &pos) const { return rowByScenePos(pos.y()); }
85  inline ChatLineModel::ColumnType columnByScenePos(const QPointF &pos) const { return columnByScenePos(pos.x()); }
86 
87  ChatView *chatView() const;
88  ChatItem *chatItemAt(const QPointF &pos) const;
89  inline ChatLine *chatLine(int row) const { return (row < _lines.count()) ? _lines.value(row) : 0; }
90  inline ChatLine *chatLine(const QModelIndex &index) const { return _lines.value(index.row()); }
91 
93 
103  ChatLine *chatLine(MsgId msgId, bool matchExact = true, bool ignoreDayChange = true) const;
104 
105  inline ChatLine *lastLine() const { return _lines.count() ? _lines.last() : 0; }
106 
107  inline MarkerLineItem *markerLine() const { return _markerLine; }
108 
109  inline bool isSingleBufferScene() const { return _singleBufferId.isValid(); }
110  inline BufferId singleBufferId() const { return _singleBufferId; }
111  bool containsBuffer(const BufferId &id) const;
112 
115 
116  inline CutoffMode senderCutoffMode() const { return _cutoffMode; }
117  inline void setSenderCutoffMode(CutoffMode mode) { _cutoffMode = mode; }
118 
119  QString selection() const;
120  bool hasSelection() const;
121  bool hasGlobalSelection() const;
122  bool isPosOverSelection(const QPointF &) const;
123  bool isGloballySelecting() const;
124  void initiateDrag(QWidget *source);
125 
126  bool isScrollingAllowed() const;
127 
128 public slots:
129  void updateForViewport(qreal width, qreal height);
130  void setWidth(qreal width);
131  void layout(int start, int end, qreal width);
132 
133  void resetColumnWidths();
134 
135  void setMarkerLineVisible(bool visible = true);
136  void setMarkerLine(MsgId msgId = MsgId());
137  void jumpToMarkerLine(bool requestBacklog);
138 
139  // these are used by the chatitems to notify the scene and manage selections
140  void setSelectingItem(ChatItem *item);
141  ChatItem *selectingItem() const { return _selectingItem; }
142  void startGlobalSelection(ChatItem *item, const QPointF &itemPos);
143  void clearGlobalSelection();
144  void clearSelection();
145  void selectionToClipboard(QClipboard::Mode = QClipboard::Clipboard);
146  void stringToClipboard(const QString &str, QClipboard::Mode = QClipboard::Clipboard);
147 
148  void webSearchOnSelection();
149 
150  void requestBacklog();
151 
152 #ifdef HAVE_WEBKIT
153  void loadWebPreview(ChatItem *parentItem, const QUrl &url, const QRectF &urlRect);
154  void clearWebPreview(ChatItem *parentItem = 0);
155 #endif
156 
157 signals:
158  void lastLineChanged(QGraphicsItem *item, qreal offset);
159  void layoutChanged(); // indicates changes to the scenerect due to resizing of the contentsitems
160  void mouseMoveWhileSelecting(const QPointF &scenePos);
161 
162 protected:
163  virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent);
164  virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
165  virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
166  virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
167  virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent);
168  virtual void handleClick(Qt::MouseButton button, const QPointF &scenePos);
169 
170 protected slots:
171  void rowsInserted(const QModelIndex &, int, int);
172  void rowsAboutToBeRemoved(const QModelIndex &, int, int);
173  void dataChanged(const QModelIndex &, const QModelIndex &);
174 
175 private slots:
176  void firstHandlePositionChanged(qreal xpos);
177  void secondHandlePositionChanged(qreal xpos);
178 #ifdef HAVE_WEBKIT
179  void webPreviewNextStep();
180 #endif
181  void showWebPreviewChanged();
182 
183  void rowsRemoved();
184 
185  void clickTimeout();
186 
187 private:
188  void setHandleXLimits();
189  void updateSelection(const QPointF &pos);
190 
192  QString _idString;
193  QAbstractItemModel *_model;
194  QList<ChatLine *> _lines;
196 
197  // calls to QChatScene::sceneRect() are very expensive. As we manage the scenerect ourselves
198  // we store the size in a member variable.
199  QRectF _sceneRect;
200  int _firstLineRow; // the first row to display (aka: not a daychange msg)
201  void updateSceneRect(qreal width);
202  inline void updateSceneRect() { updateSceneRect(_sceneRect.width()); }
203  void updateSceneRect(const QRectF &rect);
205 
208 
213 
220 
221  QTimer _clickTimer;
223  QPointF _clickPos;
226 
228 
229  static const int _webSearchSelectionTextMaxVisible = 24;
230 
231 #ifdef HAVE_WEBKIT
232  struct WebPreview {
233  enum PreviewState {
234  NoPreview,
235  NewPreview,
236  DelayPreview,
237  ShowPreview,
238  HidePreview
239  };
240  ChatItem *parentItem;
241  QGraphicsItem *previewItem;
242  QUrl url;
243  QRectF urlRect;
244  PreviewState previewState;
245  QTimer timer;
246  WebPreview() : parentItem(0), previewItem(0), previewState(NoPreview) {}
247  };
248  WebPreview webPreview;
249 #endif // HAVE_WEBKIT
250 };
251 
252 
253 #endif