+ if(!haveLayout()) updateLayout();
+ painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work
+ //if(_selectionMode == FullSelection) {
+ //painter->save();
+ //painter->fillRect(boundingRect(), QApplication::palette().brush(QPalette::Highlight));
+ //painter->restore();
+ //}
+ QVector<QTextLayout::FormatRange> formats;
+ if(_selectionMode != NoSelection) {
+ QTextLayout::FormatRange selectFmt;
+ selectFmt.format.setForeground(QApplication::palette().brush(QPalette::HighlightedText));
+ selectFmt.format.setBackground(QApplication::palette().brush(QPalette::Highlight));
+ if(_selectionMode == PartialSelection) {
+ selectFmt.start = qMin(_selectionStart, _selectionEnd);
+ selectFmt.length = qAbs(_selectionStart - _selectionEnd);
+ } else { // FullSelection
+ selectFmt.start = 0;
+ selectFmt.length = data(MessageModel::DisplayRole).toString().length();
+ }
+ formats.append(selectFmt);
+ }
+ _layout->draw(painter, QPointF(0,0), formats, boundingRect());
+}
+
+qint16 ChatItem::posToCursor(const QPointF &pos) {
+ if(pos.y() > height()) return data(MessageModel::DisplayRole).toString().length();
+ if(pos.y() < 0) return 0;
+ if(!haveLayout()) updateLayout();
+ for(int l = _layout->lineCount() - 1; l >= 0; l--) {
+ QTextLine line = _layout->lineAt(l);
+ if(pos.y() >= line.y()) {
+ return line.xToCursor(pos.x(), QTextLine::CursorOnCharacter);
+ }
+ }
+ return 0;
+}
+
+void ChatItem::setFullSelection() {
+ if(_selectionMode != FullSelection) {
+ _selectionMode = FullSelection;
+ update();
+ }
+}
+
+void ChatItem::clearSelection() {
+ if(_selectionMode != NoSelection) {
+ _selectionMode = NoSelection;
+ update();
+ }
+}
+
+void ChatItem::continueSelecting(const QPointF &pos) {
+ _selectionMode = PartialSelection;
+ _selectionEnd = posToCursor(pos);
+ update();
+}
+
+void ChatItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
+ if(event->buttons() == Qt::LeftButton) {
+ if(_selectionMode == NoSelection) {
+ chatScene()->setSelectingItem(this); // removes earlier selection if exists
+ _selectionStart = _selectionEnd = posToCursor(event->pos());
+ _selectionMode = PartialSelection;
+ } else {
+ chatScene()->setSelectingItem(0);
+ _selectionMode = NoSelection;
+ update();
+ }
+ event->accept();
+ } else {
+ event->ignore();
+ }
+}