qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
chatline.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2014-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "chatline.h"
21 #include "chatlinecontent.h"
22 
23 #include <QDebug>
24 #include <QGraphicsScene>
25 
27 {
28 }
29 
31 {
32  for (ChatLineContent* c : content) {
33  if (c->scene())
34  c->scene()->removeItem(c);
35 
36  delete c;
37  }
38 }
39 
40 void ChatLine::visibilityChanged(bool visible)
41 {
42  if (isVisible != visible) {
43  for (ChatLineContent* c : content)
44  c->visibilityChanged(visible);
45  }
46 
47  isVisible = visible;
48 }
49 
51 {
52  if (col < static_cast<int>(content.size()) && col >= 0)
53  return content[col];
54 
55  return nullptr;
56 }
57 
58 ChatLineContent* ChatLine::getContent(QPointF scenePos) const
59 {
60  for (ChatLineContent* c : content) {
61  if (c->sceneBoundingRect().contains(scenePos))
62  return c;
63  }
64 
65  return nullptr;
66 }
67 
69 {
70  for (ChatLineContent* c : content) {
71  if (c->scene())
72  c->scene()->removeItem(c);
73  }
74 }
75 
76 void ChatLine::addToScene(QGraphicsScene* scene)
77 {
78  if (!scene)
79  return;
80 
81  for (ChatLineContent* c : content)
82  scene->addItem(c);
83 }
84 
85 void ChatLine::setVisible(bool visible)
86 {
87  for (ChatLineContent* c : content)
88  c->setVisible(visible);
89 }
90 
92 {
93  for (ChatLineContent* c : content)
94  c->selectionCleared();
95 }
96 
98 {
99  for (ChatLineContent* c : content)
100  c->selectionFocusChanged(focusIn);
101 }
102 
103 void ChatLine::fontChanged(const QFont& font)
104 {
105  for (ChatLineContent* c : content)
106  c->fontChanged(font);
107 }
108 
110 {
111  for (ChatLineContent* c : content) {
112  c->reloadTheme();
113  }
114 }
115 
117 {
118  return content.size();
119 }
120 
122 {
123  bbox.setHeight(0);
124  bbox.setWidth(width);
125 
126  for (ChatLineContent* c : content)
127  bbox.setHeight(qMax(c->sceneBoundingRect().top() - bbox.top() + c->sceneBoundingRect().height(),
128  bbox.height()));
129 }
130 
132 {
133  return bbox;
134 }
135 
137 {
138  if (!item)
139  return;
140 
141  format.push_back(fmt);
142  content.push_back(item);
143  item->setIndex(0, content.size() -1 );
144 }
145 
146 void ChatLine::replaceContent(int col, ChatLineContent* lineContent)
147 {
148  if (col >= 0 && col < static_cast<int>(content.size()) && lineContent) {
149  QGraphicsScene* scene = content[col]->scene();
150  delete content[col];
151 
152  content[col] = lineContent;
153  lineContent->setIndex(row, col);
154 
155  if (scene)
156  scene->addItem(content[col]);
157 
158  layout(width, bbox.topLeft());
159  content[col]->visibilityChanged(isVisible);
160  content[col]->update();
161  }
162 }
163 
164 void ChatLine::layout(qreal w, QPointF scenePos)
165 {
166  if (!content.size())
167  return;
168 
169  width = w;
170  bbox.setTopLeft(scenePos);
171 
172  qreal fixedWidth = (content.size() - 1) * columnSpacing;
173  qreal varWidth = 0.0; // used for normalisation
174 
175  for (int i = 0; i < format.size(); ++i) {
176  if (format[i].policy == ColumnFormat::FixedSize)
177  fixedWidth += format[i].size;
178  else
179  varWidth += format[i].size;
180  }
181 
182  if (varWidth == 0.0)
183  varWidth = 1.0;
184 
185  qreal leftover = qMax(0.0, width - fixedWidth);
186 
187  qreal maxVOffset = 0.0;
188  qreal xOffset = 0.0;
189  QVector<qreal> xPos(content.size());
190 
191  for (int i = 0; i < content.size(); ++i) {
192  // calculate the effective width of the current column
193  qreal width;
194  if (format[i].policy == ColumnFormat::FixedSize)
195  width = format[i].size;
196  else
197  width = format[i].size / varWidth * leftover;
198 
199  // set the width of the current column
200  content[i]->setWidth(width);
201 
202  // calculate horizontal alignment
203  qreal xAlign = 0.0;
204 
205  switch (format[i].hAlign) {
206  case ColumnFormat::Left:
207  break;
208  case ColumnFormat::Right:
209  xAlign = width - content[i]->boundingRect().width();
210  break;
212  xAlign = (width - content[i]->boundingRect().width()) / 2.0;
213  break;
214  }
215 
216  // reposition
217  xPos[i] = scenePos.x() + xOffset + xAlign;
218 
219  xOffset += width + columnSpacing;
220  maxVOffset = qMax(maxVOffset, content[i]->getAscent());
221  }
222 
223  for (int i = 0; i < content.size(); ++i) {
224  // calculate vertical alignment
225  // vertical alignment may depend on width, so we do it in a second pass
226  qreal yOffset = maxVOffset - content[i]->getAscent();
227 
228  // reposition
229  content[i]->setPos(xPos[i], scenePos.y() + yOffset);
230  }
231 
232  updateBBox();
233 }
234 
235 void ChatLine::moveBy(qreal deltaY)
236 {
237  // reposition only
238  for (ChatLineContent* c : content)
239  c->moveBy(0, deltaY);
240 
241  bbox.moveTop(bbox.top() + deltaY);
242 }
243 
244 bool ChatLine::lessThanBSRectTop(const ChatLine::Ptr& lhs, const qreal& rhs)
245 {
246  return lhs->sceneBoundingRect().top() < rhs;
247 }
248 
249 bool ChatLine::lessThanBSRectBottom(const ChatLine::Ptr& lhs, const qreal& rhs)
250 {
251  return lhs->sceneBoundingRect().bottom() < rhs;
252 }
ColumnFormat::Right
@ Right
Definition: chatline.h:45
ChatLine::removeFromScene
void removeFromScene()
Definition: chatline.cpp:68
ChatLine::setVisible
void setVisible(bool visible)
Definition: chatline.cpp:85
ColumnFormat::Center
@ Center
Definition: chatline.h:44
ColumnFormat
Definition: chatline.h:33
ChatLine::width
qreal width
Definition: chatline.h:110
ChatLine::lessThanBSRectBottom
static bool lessThanBSRectBottom(const ChatLine::Ptr &lhs, const qreal &rhs)
Definition: chatline.cpp:249
ChatLine::~ChatLine
virtual ~ChatLine()
Definition: chatline.cpp:30
ChatLine::row
int row
Definition: chatline.h:107
ChatLine::replaceContent
void replaceContent(int col, ChatLineContent *lineContent)
Definition: chatline.cpp:146
ChatLine::fontChanged
void fontChanged(const QFont &font)
Definition: chatline.cpp:103
ChatLine::getContent
ChatLineContent * getContent(int col) const
Definition: chatline.cpp:50
ColumnFormat::Left
@ Left
Definition: chatline.h:43
ChatLine::format
QVector< ColumnFormat > format
Definition: chatline.h:109
ChatLine::moveBy
void moveBy(qreal deltaY)
Definition: chatline.cpp:235
chatline.h
chatlinecontent.h
ChatLine::ChatLine
ChatLine()
Definition: chatline.cpp:26
ColumnFormat::FixedSize
@ FixedSize
Definition: chatline.h:37
ChatLine::bbox
QRectF bbox
Definition: chatline.h:112
ChatLine::addToScene
void addToScene(QGraphicsScene *scene)
Definition: chatline.cpp:76
ChatLine::sceneBoundingRect
QRectF sceneBoundingRect() const
Definition: chatline.cpp:131
ChatLineContent
Definition: chatlinecontent.h:26
ChatLine::lessThanBSRectTop
static bool lessThanBSRectTop(const ChatLine::Ptr &lhs, const qreal &rhs)
Definition: chatline.cpp:244
ChatLine::isVisible
bool isVisible
Definition: chatline.h:113
ChatLine::content
QVector< ChatLineContent * > content
Definition: chatline.h:108
ChatLine::layout
void layout(qreal width, QPointF scenePos)
Definition: chatline.cpp:164
ChatLineContent::setIndex
void setIndex(int row, int col)
Definition: chatlinecontent.cpp:22
ChatLine::getColumnCount
int getColumnCount()
Definition: chatline.cpp:116
ChatLine::selectionCleared
void selectionCleared()
Definition: chatline.cpp:91
ChatLine::visibilityChanged
void visibilityChanged(bool visible)
Definition: chatline.cpp:40
ChatLine::columnSpacing
qreal columnSpacing
Definition: chatline.h:111
ChatLine::addColumn
void addColumn(ChatLineContent *item, ColumnFormat fmt)
Definition: chatline.cpp:136
ChatLine::selectionFocusChanged
void selectionFocusChanged(bool focusIn)
Definition: chatline.cpp:97
ChatLine::Ptr
std::shared_ptr< ChatLine > Ptr
Definition: chatline.h:68
ChatLine::reloadTheme
void reloadTheme()
Definition: chatline.cpp:109
ChatLine::updateBBox
void updateBBox()
Definition: chatline.cpp:121