You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
7.1 KiB
179 lines
7.1 KiB
/* |
|
* Copyright 2011 Marco Martin <notmart@gmail.com> |
|
* Copyright 2014, 2019 Kai Uwe Broulik <kde@privat.broulik.de> |
|
* |
|
* This program is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU General Public License as |
|
* published by the Free Software Foundation; either version 2 of |
|
* the License or (at your option) version 3 or any later version |
|
* accepted by the membership of KDE e.V. (or its successor approved |
|
* by the membership of KDE e.V.), which shall act as a proxy |
|
* defined in Section 14 of version 3 of the license. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|
*/ |
|
|
|
import QtQuick 2.8 |
|
import QtQuick.Window 2.2 |
|
import QtQuick.Layouts 1.1 |
|
|
|
import org.kde.plasma.core 2.0 as PlasmaCore |
|
import org.kde.plasma.components 2.0 as PlasmaComponents |
|
import org.kde.plasma.extras 2.0 as PlasmaExtras |
|
import org.kde.kirigami 2.11 as Kirigami |
|
|
|
// NOTE This wrapper item is needed for QQC ScrollView to work |
|
// In NotificationItem we just do SelectableLabel {} and then it gets confused |
|
// as to which is the "contentItem" |
|
Item { |
|
id: bodyTextContainer |
|
|
|
property alias text: bodyText.text |
|
property alias font: bodyText.font |
|
|
|
property int cursorShape |
|
|
|
property QtObject contextMenu: null |
|
|
|
signal clicked(var mouse) |
|
signal linkActivated(string link) |
|
|
|
implicitWidth: bodyText.paintedWidth |
|
implicitHeight: bodyText.paintedHeight |
|
|
|
|
|
PlasmaExtras.ScrollArea { |
|
id: bodyTextScrollArea |
|
|
|
anchors.fill: parent |
|
|
|
flickableItem.boundsBehavior: Flickable.StopAtBounds |
|
flickableItem.flickableDirection: Flickable.VerticalFlick |
|
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff |
|
|
|
TextEdit { |
|
id: bodyText |
|
width: bodyTextScrollArea.width |
|
// TODO check that this doesn't causes infinite loops when it starts adding and removing the scrollbar |
|
//width: bodyTextScrollArea.viewport.width |
|
enabled: !Kirigami.Settings.isMobile |
|
|
|
color: PlasmaCore.ColorScope.textColor |
|
selectedTextColor: theme.viewBackgroundColor |
|
selectionColor: theme.viewFocusColor |
|
font.capitalization: theme.defaultFont.capitalization |
|
font.family: theme.defaultFont.family |
|
font.italic: theme.defaultFont.italic |
|
font.letterSpacing: theme.defaultFont.letterSpacing |
|
font.pointSize: theme.defaultFont.pointSize |
|
font.strikeout: theme.defaultFont.strikeout |
|
font.underline: theme.defaultFont.underline |
|
font.weight: theme.defaultFont.weight |
|
font.wordSpacing: theme.defaultFont.wordSpacing |
|
// Work around Qt bug where NativeRendering breaks for non-integer scale factors |
|
// https://bugreports.qt.io/browse/QTBUG-67007 |
|
renderType: Screen.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering |
|
// Selectable only when we are in desktop mode |
|
selectByMouse: !Kirigami.Settings.tabletMode |
|
|
|
readOnly: true |
|
wrapMode: Text.Wrap |
|
textFormat: TextEdit.RichText |
|
|
|
onLinkActivated: bodyTextContainer.linkActivated(link) |
|
|
|
// ensure selecting text scrolls the view as needed... |
|
onCursorRectangleChanged: { |
|
var flick = bodyTextScrollArea.flickableItem |
|
if (flick.contentY >= cursorRectangle.y) { |
|
flick.contentY = cursorRectangle.y |
|
} else if (flick.contentY + flick.height <= cursorRectangle.y + cursorRectangle.height) { |
|
flick.contentY = cursorRectangle.y + cursorRectangle.height - flick.height |
|
} |
|
} |
|
MouseArea { |
|
property int selectionStart |
|
property point mouseDownPos: Qt.point(-999, -999); |
|
|
|
anchors.fill: parent |
|
acceptedButtons: Qt.RightButton | Qt.LeftButton |
|
cursorShape: { |
|
if (bodyText.hoveredLink) { |
|
return Qt.PointingHandCursor; |
|
} else if (bodyText.selectionStart !== bodyText.selectionEnd) { |
|
return Qt.IBeamCursor; |
|
} else { |
|
return bodyTextContainer.cursorShape || Qt.IBeamCursor; |
|
} |
|
} |
|
preventStealing: true // don't let us accidentally drag the Flickable |
|
|
|
onPressed: { |
|
if (mouse.button === Qt.RightButton) { |
|
contextMenu = contextMenuComponent.createObject(bodyText); |
|
contextMenu.link = bodyText.linkAt(mouse.x, mouse.y); |
|
|
|
contextMenu.closed.connect(function() { |
|
contextMenu.destroy(); |
|
contextMenu = null; |
|
}); |
|
contextMenu.open(mouse.x, mouse.y); |
|
return; |
|
} |
|
|
|
mouseDownPos = Qt.point(mouse.x, mouse.y); |
|
selectionStart = bodyText.positionAt(mouse.x, mouse.y); |
|
var pos = bodyText.positionAt(mouse.x, mouse.y); |
|
// deselect() would scroll to the end which we don't want |
|
bodyText.select(pos, pos); |
|
} |
|
|
|
onReleased: { |
|
// emulate "onClicked" |
|
var manhattanLength = Math.abs(mouseDownPos.x - mouse.x) + Math.abs(mouseDownPos.y - mouse.y); |
|
if (manhattanLength <= Qt.styleHints.startDragDistance) { |
|
var link = bodyText.linkAt(mouse.x, mouse.y); |
|
if (link) { |
|
Qt.openUrlExternally(link); |
|
} else { |
|
bodyTextContainer.clicked(mouse); |
|
} |
|
} |
|
|
|
// emulate selection clipboard |
|
if (bodyText.selectedText) { |
|
plasmoid.nativeInterface.setSelectionClipboardText(bodyText.selectedText); |
|
} |
|
|
|
mouseDownPos = Qt.point(-999, -999); |
|
} |
|
|
|
// HACK to be able to select text whilst still getting all mouse events to the MouseArea |
|
onPositionChanged: { |
|
if (pressed) { |
|
var pos = bodyText.positionAt(mouseX, mouseY); |
|
if (selectionStart < pos) { |
|
bodyText.select(selectionStart, pos); |
|
} else { |
|
bodyText.select(pos, selectionStart); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
Component { |
|
id: contextMenuComponent |
|
|
|
EditContextMenu { |
|
target: bodyText |
|
} |
|
} |
|
}
|
|
|