kateoutputview.cpp 4.4 KB
Newer Older
1
2
3
4
5
6
7
/*
    SPDX-FileCopyrightText: 2021 Christoph Cullmann <cullmann@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "kateoutputview.h"
8
#include "katemainwindow.h"
9

10
11
#include <KLocalizedString>

Christoph Cullmann's avatar
Christoph Cullmann committed
12
13
#include <QPainter>
#include <QTextDocument>
14
15
16
#include <QTreeView>
#include <QVBoxLayout>

Christoph Cullmann's avatar
Christoph Cullmann committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * setup text document from data
 */
static void setupText(QTextDocument &doc, const QModelIndex &index)
{
    /**
     * fill in right variant of text
     * we always trim spaces away, to avoid ugly empty line at the start/end
     */
    const auto message = index.data(KateOutputMessageStyledDelegate::MessageRole).toMap();
    if (message.contains(QStringLiteral("plainText"))) {
        doc.setPlainText(message.value(QStringLiteral("plainText")).toString().trimmed());
    } else if (message.contains(QStringLiteral("markDown"))) {
        doc.setMarkdown(message.value(QStringLiteral("markDown")).toString().trimmed());
    } else if (message.contains(QStringLiteral("html"))) {
        doc.setHtml(message.value(QStringLiteral("html")).toString().trimmed());
    }
}

void KateOutputMessageStyledDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Christoph Cullmann's avatar
Christoph Cullmann committed
38
39
40
    // ensure we recover state
    painter->save();

Christoph Cullmann's avatar
Christoph Cullmann committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    QStyleOptionViewItem options = option;
    initStyleOption(&options, index);

    // paint background
    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());
    } else {
        painter->fillRect(option.rect, option.palette.base());
    }

    options.text = QString();
    options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);

    painter->translate(option.rect.x(), option.rect.y());

    QTextDocument doc;
    setupText(doc, index);
    doc.drawContents(painter);
Christoph Cullmann's avatar
Christoph Cullmann committed
59
60
61

    // ensure we recover state
    painter->restore();
Christoph Cullmann's avatar
Christoph Cullmann committed
62
63
64
65
66
67
68
69
70
}

QSize KateOutputMessageStyledDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &index) const
{
    QTextDocument doc;
    setupText(doc, index);
    return doc.size().toSize();
}

71
72
73
74
KateOutputView::KateOutputView(KateMainWindow *mainWindow, QWidget *parent)
    : QWidget(parent)
    , m_mainWindow(mainWindow)
{
75
76
77
78
    // simple vbox layout with just the tree view ATM
    // TODO: e.g. filter and such!
    QVBoxLayout *layout = new QVBoxLayout(this);
    m_messagesTreeView = new QTreeView(this);
79
80
81
    m_messagesTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_messagesTreeView->setHeaderHidden(true);
    m_messagesTreeView->setRootIsDecorated(false);
82
83
    m_messagesTreeView->setModel(&m_messagesModel);
    layout->addWidget(m_messagesTreeView);
84
85
86
87

    // we want a special delegate to render the message body, as that might be plain text
    // mark down or HTML
    m_messagesTreeView->setItemDelegateForColumn(1, &m_messageBodyDelegate);
88
89
90
91
}

void KateOutputView::slotMessage(const QVariantMap &message)
{
92
93
94
    /**
     * type column: shows the type, icons for some types only
     */
95
    bool shouldShowOutputToolView = false;
96
97
98
    auto typeColumn = new QStandardItem();
    const auto typeString = message.value(QStringLiteral("type")).toString();
    if (typeString == QLatin1String("Error")) {
99
        shouldShowOutputToolView = true;
100
101
102
        typeColumn->setText(i18nc("@info", "Error"));
        typeColumn->setIcon(QIcon::fromTheme(QStringLiteral("data-error")));
    } else if (typeString == QLatin1String("Warning")) {
103
        shouldShowOutputToolView = true;
104
105
106
107
108
109
110
        typeColumn->setText(i18nc("@info", "Warning"));
        typeColumn->setIcon(QIcon::fromTheme(QStringLiteral("data-warning")));
    } else if (typeString == QLatin1String("Info")) {
        typeColumn->setText(i18nc("@info", "Info"));
        typeColumn->setIcon(QIcon::fromTheme(QStringLiteral("data-information")));
    } else {
        typeColumn->setText(i18nc("@info", "Log"));
111
    }
112
113
114
115

    /**
     * body column, formatted text
     * we just set the full message as attribute
Christoph Cullmann's avatar
Christoph Cullmann committed
116
     * we have our KateOutputMessageStyledDelegate to render this!
117
118
     */
    auto bodyColumn = new QStandardItem();
Christoph Cullmann's avatar
Christoph Cullmann committed
119
    bodyColumn->setData(QVariant::fromValue(message), KateOutputMessageStyledDelegate::MessageRole);
120
121
122
123
124

    /**
     * add new message to model as one row
     */
    m_messagesModel.appendRow({typeColumn, bodyColumn});
125
126
127
128
129
130
131

    /**
     * if message requires it => show the tool view if hidden
     */
    if (shouldShowOutputToolView) {
        m_mainWindow->showToolView(parentWidget());
    }
132
}