1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #include "sourcecodeview.h" |
5 | |
6 | #include <QtCore/QFile> |
7 | #include <QtCore/QFileInfo> |
8 | #include <QtCore/QTextStream> |
9 | |
10 | #include <QtGui/QTextCharFormat> |
11 | #include <QtGui/QTextBlock> |
12 | #include <QtGui/QTextCursor> |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | SourceCodeView::SourceCodeView(QWidget *parent) |
17 | : QPlainTextEdit(parent), |
18 | m_isActive(true), |
19 | m_lineNumToLoad(0) |
20 | { |
21 | setReadOnly(true); |
22 | } |
23 | |
24 | void SourceCodeView::setSourceContext(const QString &fileName, const int lineNum) |
25 | { |
26 | m_fileToLoad.clear(); |
27 | setToolTip(fileName); |
28 | |
29 | if (fileName.isEmpty()) { |
30 | clear(); |
31 | m_currentFileName.clear(); |
32 | appendHtml(html: tr(s: "<i>Source code not available</i>" )); |
33 | return; |
34 | } |
35 | |
36 | if (m_isActive) { |
37 | showSourceCode(fileName, lineNum); |
38 | } else { |
39 | m_fileToLoad = fileName; |
40 | m_lineNumToLoad = lineNum; |
41 | } |
42 | } |
43 | |
44 | void SourceCodeView::setActivated(bool activated) |
45 | { |
46 | m_isActive = activated; |
47 | if (activated && !m_fileToLoad.isEmpty()) { |
48 | showSourceCode(fileName: m_fileToLoad, lineNum: m_lineNumToLoad); |
49 | m_fileToLoad.clear(); |
50 | } |
51 | } |
52 | |
53 | void SourceCodeView::showSourceCode(const QString &absFileName, const int lineNum) |
54 | { |
55 | QString fileText = fileHash.value(key: absFileName); |
56 | |
57 | if (fileText.isNull()) { // File not in hash |
58 | m_currentFileName.clear(); |
59 | |
60 | // Assume fileName is relative to directory |
61 | QFile file(absFileName); |
62 | |
63 | if (!file.exists()) { |
64 | clear(); |
65 | appendHtml(html: tr(s: "<i>File %1 not available</i>" ).arg(a: absFileName)); |
66 | return; |
67 | } |
68 | if (!file.open(flags: QIODevice::ReadOnly | QIODevice::Text)) { |
69 | clear(); |
70 | appendHtml(html: tr(s: "<i>File %1 not readable</i>" ).arg(a: absFileName)); |
71 | return; |
72 | } |
73 | fileText = QString::fromUtf8(ba: file.readAll()); |
74 | fileHash.insert(key: absFileName, value: fileText); |
75 | } |
76 | |
77 | |
78 | if (m_currentFileName != absFileName) { |
79 | setPlainText(fileText); |
80 | m_currentFileName = absFileName; |
81 | } |
82 | |
83 | QTextCursor cursor = textCursor(); |
84 | cursor.setPosition(pos: document()->findBlockByNumber(blockNumber: lineNum - 1).position()); |
85 | setTextCursor(cursor); |
86 | centerCursor(); |
87 | cursor.movePosition(op: QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); |
88 | cursor.movePosition(op: QTextCursor::Right, QTextCursor::KeepAnchor); |
89 | |
90 | QTextEdit::ExtraSelection selectedLine; |
91 | selectedLine.cursor = cursor; |
92 | |
93 | // Define custom color for line selection |
94 | const QColor fg = palette().color(cr: QPalette::Highlight); |
95 | const QColor bg = palette().color(cr: QPalette::Base); |
96 | QColor col; |
97 | const qreal ratio = 0.25; |
98 | col.setRedF(fg.redF() * ratio + bg.redF() * (1 - ratio)); |
99 | col.setGreenF(fg.greenF() * ratio + bg.greenF() * (1 - ratio)); |
100 | col.setBlueF(fg.blueF() * ratio + bg.blueF() * (1 - ratio)); |
101 | |
102 | selectedLine.format.setBackground(col); |
103 | selectedLine.format.setProperty(propertyId: QTextFormat::FullWidthSelection, value: true); |
104 | setExtraSelections(QList<QTextEdit::ExtraSelection>() << selectedLine); |
105 | } |
106 | |
107 | QT_END_NAMESPACE |
108 | |