/***************************************************************************
- * Copyright (C) 2005-2013 by the Quassel Project *
+ * Copyright (C) 2005-2018 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
#include <QDesktopServices>
#include <QFontMetrics>
#include <QGraphicsSceneMouseEvent>
+#include <QIcon>
#include <QPainter>
#include <QPalette>
#include <QTextLayout>
#include "chatlinemodel.h"
#include "chatview.h"
#include "contextmenuactionprovider.h"
-#include "iconloader.h"
#include "mainwin.h"
#include "qtui.h"
#include "qtuistyle.h"
layout->setTextOption(option);
QList<QTextLayout::FormatRange> formatRanges
- = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt());
+ = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).value<UiStyle::MessageLabel>());
layout->setAdditionalFormats(formatRanges);
}
// }
// 2) draw MsgId over the time column
// if(column() == 0) {
-// QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value<MsgId>().toInt());
+// QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value<MsgId>().toLongLong());
// QPointF bottomPoint = boundingRect().bottomLeft();
// bottomPoint.ry() -= 2;
// painter->drawText(bottomPoint, msgIdString);
}
-void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const
+void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, quint16 start, quint16 end, UiStyle::FormatType overlayFmt) const
{
- for (int i = 0; i < fmtList.count(); i++) {
+ for (size_t i = 0; i < fmtList.size(); i++) {
int fmtStart = fmtList.at(i).first;
- int fmtEnd = (i < fmtList.count()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length());
+ int fmtEnd = (i < fmtList.size()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length());
if (fmtEnd <= start)
continue;
// split the format if necessary
if (fmtStart < start) {
- fmtList.insert(i, fmtList.at(i));
+ fmtList.insert(fmtList.begin() + i, fmtList.at(i));
fmtList[++i].first = start;
}
if (end < fmtEnd) {
- fmtList.insert(i, fmtList.at(i));
+ fmtList.insert(fmtList.begin() + i, fmtList.at(i));
fmtList[i+1].first = end;
}
- fmtList[i].second |= overlayFmt;
+ fmtList[i].second.type |= overlayFmt;
}
}
if (!hasSelection())
return QVector<QTextLayout::FormatRange>();
- int start, end;
+ quint16 start, end;
if (_selectionMode == FullSelection) {
start = 0;
end = data(MessageModel::DisplayRole).toString().length();
UiStyle::FormatList fmtList = formatList();
- while (fmtList.count() > 1 && fmtList.at(1).first <= start)
- fmtList.removeFirst();
+ while (fmtList.size() > 1 && fmtList.at(1).first <= start)
+ fmtList.erase(fmtList.begin());
- fmtList.first().first = start;
+ fmtList.front().first = start;
- while (fmtList.count() > 1 && fmtList.last().first >= end)
- fmtList.removeLast();
+ while (fmtList.size() > 1 && fmtList.back().first >= end)
+ fmtList.pop_back();
- return QtUi::style()->toTextLayoutList(fmtList, end, UiStyle::Selected|data(ChatLineModel::MsgLabelRole).toUInt()).toVector();
+ return QtUi::style()->toTextLayoutList(fmtList, end, data(ChatLineModel::MsgLabelRole).value<UiStyle::MessageLabel>()|UiStyle::MessageLabel::Selected).toVector();
}
if (layoutWidth > width()) {
// Draw a nice gradient for longer items
- // Qt's text drawing with a gradient brush sucks, so we use an alpha-channeled pixmap instead
+ // Qt's text drawing with a gradient brush sucks, so we use compositing instead
QPixmap pixmap(layout()->boundingRect().toRect().size());
pixmap.fill(Qt::transparent);
+
QPainter pixPainter(&pixmap);
layout()->draw(&pixPainter, QPointF(qMax(offset, (qreal)0), 0), additionalFormats());
- pixPainter.end();
// Create alpha channel mask
- QPixmap mask(pixmap.size());
- QPainter maskPainter(&mask);
QLinearGradient gradient;
if (offset < 0) {
gradient.setStart(0, 0);
gradient.setFinalStop(12, 0);
- gradient.setColorAt(0, Qt::black);
+ gradient.setColorAt(0, Qt::transparent);
gradient.setColorAt(1, Qt::white);
}
else {
gradient.setStart(width()-10, 0);
gradient.setFinalStop(width(), 0);
gradient.setColorAt(0, Qt::white);
- gradient.setColorAt(1, Qt::black);
+ gradient.setColorAt(1, Qt::transparent);
}
- maskPainter.fillRect(0, 0, pixmap.width(), pixmap.height(), gradient);
- pixmap.setAlphaChannel(mask);
+ pixPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); // gradient's alpha gets applied to the pixmap
+ pixPainter.fillRect(pixmap.rect(), gradient);
painter->drawPixmap(pos(), pixmap);
}
else {
QFontMetricsF *ContentsChatItem::fontMetrics() const
{
- return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value<UiStyle::FormatList>().at(0).second, 0);
+ return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value<UiStyle::FormatList>().at(0).second.type, UiStyle::MessageLabel::None);
}
for (int i = 0; i < privateData()->clickables.count(); i++) {
Clickable click = privateData()->clickables.at(i);
if (click.type() == Clickable::Url) {
- overlayFormat(fmtList, click.start(), click.start() + click.length(), UiStyle::Url);
+ overlayFormat(fmtList, click.start(), click.start() + click.length(), UiStyle::FormatType::Url);
}
}
return fmtList;
switch (click.type()) {
case Clickable::Url:
privateData()->activeClickable = click;
- menu->addAction(SmallIcon("edit-copy"), tr("Copy Link Address"),
+ menu->addAction(QIcon::fromTheme("edit-copy"), tr("Copy Link Address"),
&_actionProxy, SLOT(copyLinkToClipboard()))->setData(QVariant::fromValue<void *>(this));
break;
case Clickable::Channel:
{
- // Hide existing menu actions, they confuse us when right-clicking on a clickable
- foreach(QAction *action, menu->actions())
- action->setVisible(false);
+ // Remove existing menu actions, they confuse us when right-clicking on a clickable
+ menu->clear();
QString name = data(ChatLineModel::DisplayRole).toString().mid(click.start(), click.length());
GraphicalUi::contextMenuActionProvider()->addActions(menu, chatScene()->filter(), data(MessageModel::BufferIdRole).value<BufferId>(), name);
break;
void ContentsChatItem::showWebPreview(const Clickable &click)
{
-#ifndef HAVE_WEBKIT
+#if !defined HAVE_WEBKIT && !defined HAVE_WEBENGINE
Q_UNUSED(click);
#else
QTextLine line = layout()->lineForTextPosition(click.start());
void ContentsChatItem::clearWebPreview()
{
-#ifdef HAVE_WEBKIT
+#if defined HAVE_WEBKIT || defined HAVE_WEBENGINE
chatScene()->clearWebPreview(this);
#endif
}