uistyle: Support extended mIRC colors
[quassel.git] / src / qtui / chatitem.cpp
index 5726513..3dd3b2a 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2013 by the Quassel Project                        *
+ *   Copyright (C) 2005-2016 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -23,6 +23,7 @@
 #include <QDesktopServices>
 #include <QFontMetrics>
 #include <QGraphicsSceneMouseEvent>
+#include <QIcon>
 #include <QPainter>
 #include <QPalette>
 #include <QTextLayout>
@@ -35,7 +36,6 @@
 #include "chatlinemodel.h"
 #include "chatview.h"
 #include "contextmenuactionprovider.h"
-#include "iconloader.h"
 #include "mainwin.h"
 #include "qtui.h"
 #include "qtuistyle.h"
@@ -153,7 +153,7 @@ void ChatItem::initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode wrapM
     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);
 }
 
@@ -257,11 +257,11 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
 }
 
 
-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;
@@ -270,15 +270,15 @@ void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, q
 
         // 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;
     }
 }
 
@@ -294,7 +294,7 @@ QVector<QTextLayout::FormatRange> ChatItem::selectionFormats() const
     if (!hasSelection())
         return QVector<QTextLayout::FormatRange>();
 
-    int start, end;
+    quint16 start, end;
     if (_selectionMode == FullSelection) {
         start = 0;
         end = data(MessageModel::DisplayRole).toString().length();
@@ -306,15 +306,15 @@ QVector<QTextLayout::FormatRange> ChatItem::selectionFormats() const
 
     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();
 }
 
 
@@ -504,31 +504,29 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
 
     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 {
@@ -569,7 +567,7 @@ ContentsChatItem::ContentsChatItem(const QPointF &pos, const qreal &width, ChatL
 
 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);
 }
 
 
@@ -676,7 +674,7 @@ UiStyle::FormatList ContentsChatItem::formatList() const
     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;
@@ -800,7 +798,7 @@ void ContentsChatItem::addActionsToMenu(QMenu *menu, const QPointF &pos)
         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:
@@ -838,7 +836,7 @@ void ContentsChatItem::copyLinkToClipboard()
 
 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());
@@ -861,7 +859,7 @@ void ContentsChatItem::showWebPreview(const Clickable &click)
 
 void ContentsChatItem::clearWebPreview()
 {
-#ifdef HAVE_WEBKIT
+#if defined HAVE_WEBKIT || defined HAVE_WEBENGINE
     chatScene()->clearWebPreview(this);
 #endif
 }