Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions client/chatroomwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ ChatRoomWidget::ChatRoomWidget(QWidget* parent)
m_chatEdit->setAcceptRichText(false);
m_chatEdit->setMaximumHeight(maximumChatEditHeight());
connect( m_chatEdit, &KChatEdit::returnPressed, this, &ChatRoomWidget::sendInput );
connect(m_chatEdit, &KChatEdit::copyRequested, this, [=] {
QApplication::clipboard()->setText(
m_chatEdit->textCursor().hasSelection() ? m_chatEdit->textCursor().selectedText() : selectedText
);
});
connect(m_chatEdit, &ChatEdit::proposedCompletion, this,
[=](const QStringList& matches, int pos)
{
Expand Down Expand Up @@ -725,6 +730,14 @@ void ChatRoomWidget::showMenu(int index, const QString& hoveredLink,
menu.exec(QCursor::pos());
}

void ChatRoomWidget::setGlobalSelectionBuffer(QString text)
{
if (QApplication::clipboard()->supportsSelection())
QApplication::clipboard()->setText(text, QClipboard::Selection);

selectedText = text;
}

void ChatRoomWidget::reStartShownTimer()
{
if (!readMarkerOnScreen || indicesOnScreen.empty() ||
Expand Down Expand Up @@ -798,3 +811,22 @@ bool ChatRoomWidget::pendingMarkRead() const
const auto rm = m_currentRoom->readMarker();
return rm != m_currentRoom->timelineEdge() && rm->index() < indexToMaybeRead;
}

void ChatRoomWidget::fileDrop(const QString& url)
{
attachedFileName = QUrl(url).path();
m_attachAction->setChecked(true);
m_chatEdit->setPlaceholderText(
tr("Add a message to the file or just push Enter"));
emit showStatusMessage(tr("Attaching %1").arg(attachedFileName));
}

void ChatRoomWidget::textDrop(const QString& text)
{
m_chatEdit->setText(text);
}

Qt::KeyboardModifiers ChatRoomWidget::getModifierKeys()
{
return QGuiApplication::keyboardModifiers();
}
5 changes: 5 additions & 0 deletions client/chatroomwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class ChatRoomWidget: public QWidget
void saveFileAs(QString eventId);
void quote(const QString& htmlText);
void showMenu(int index, const QString& hoveredLink, bool showingDetails);
void fileDrop(const QString& url);
void textDrop(const QString& text);
void setGlobalSelectionBuffer(QString text);
Qt::KeyboardModifiers getModifierKeys();

private slots:
void sendInput();
Expand Down Expand Up @@ -108,6 +112,7 @@ class ChatRoomWidget: public QWidget
bool readMarkerOnScreen;
QMap<QuaternionRoom*, QVector<QTextDocument*>> roomHistories;
QString attachedFileName;
QString selectedText;

void reStartShownTimer();
QString doSendInput();
Expand Down
5 changes: 5 additions & 0 deletions client/kchatedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ QSize KChatEdit::sizeHint() const

void KChatEdit::keyPressEvent(QKeyEvent *event)
{
if (event->matches(QKeySequence::Copy)) {
emit copyRequested();
return;
}

switch (event->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
Expand Down
5 changes: 5 additions & 0 deletions client/kchatedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ class KChatEdit : public QTextEdit
*/
void returnPressed();

/**
* Emitted when the user presses Ctrl+C.
*/
void copyRequested();

protected:
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;

Expand Down
2 changes: 1 addition & 1 deletion client/qml/ActiveLabel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Label {

font.italic: true
textFormat: Text.PlainText
MouseArea
TimelineMouseArea
{
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
Expand Down
4 changes: 2 additions & 2 deletions client/qml/FileContent.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Attachment {
textFormat: TextEdit.PlainText
wrapMode: Text.Wrap;

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
Expand All @@ -37,7 +37,7 @@ Attachment {
? room.fileSource(eventId) : "")
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
cursorShape: Qt.IBeamCursor
Expand Down
4 changes: 2 additions & 2 deletions client/qml/ImageContent.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Attachment {
// easing.type: Easing.OutQuad
// }}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
hoverEnabled: true
Expand All @@ -36,7 +36,7 @@ Attachment {
onClicked: openExternally()
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
cursorShape: Qt.PointingHandCursor
Expand Down
38 changes: 38 additions & 0 deletions client/qml/Timeline.qml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,27 @@ Rectangle {
? Qt.ScrollBarAlwaysOff : Qt.ScrollBarAlwaysOn
style: ScrollViewStyle { transientScrollBars: true }

DropArea {
anchors.fill: parent
onEntered: if (!room) { drag.accepted = false }
onDropped: {
if (drop.hasUrls) {
controller.fileDrop(drop.urls)
drop.acceptProposedAction()
} else if (drop.hasText) {
controller.textDrop(drop.text)
drop.acceptProposedAction()
}
}
}

// This covers the area above a short chatView.
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onReleased: controller.focusInput()
}

ListView {
id: chatView

Expand Down Expand Up @@ -220,6 +241,8 @@ Rectangle {
contentHeight > 0 && count > 0 ? count / contentHeight : 0.03
// 0.03 is just an arbitrary reasonable number

property var textEditWithSelection

function ensurePreviousContent() {
if (noNeedMoreContent)
return
Expand Down Expand Up @@ -262,6 +285,21 @@ Rectangle {
contentY = Math.min(originY + contentHeight - height,
contentY + height)
}
function onWheel(wheel) {
if (wheel.angleDelta.x == 0) {
var yDelta = wheel.angleDelta.y / 120 * 100

if (yDelta > 0) {
contentY = Math.max(originY, contentY - yDelta)
} else {
contentY = Math.min(contentY + (originY + contentHeight) - (contentY + height),
contentY + Math.abs(yDelta))
}
wheel.accepted = true
} else {
wheel.accepted = false
}
}
Connections {
target: controller
onPageUpPressed: chatView.pageUp()
Expand Down
36 changes: 30 additions & 6 deletions client/qml/TimelineItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,19 @@ Item {

Rectangle {
width: parent.width
height: childrenRect.height + 2
height: sectionLabel.height + 2
visible: sectionVisible
color: defaultPalette.window
Label {
id: sectionLabel
font.bold: true
renderType: settings.render_type
text: section
}
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}
}
Loader {
id: detailsAreaLoader
Expand All @@ -138,13 +143,23 @@ Item {
width: parent.width

sourceComponent: detailsArea

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}
}

Item {
id: message
width: parent.width
height: childrenRect.height

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}

// There are several layout styles (av - author avatar,
// al - author label, ts - timestamp, c - content
// default (when "timeline_style" is not "xchat"):
Expand Down Expand Up @@ -191,7 +206,7 @@ Item {

text: (actionEvent ? "* " : "") + authorName
}
MouseArea {
TimelineMouseArea {
anchors.left: authorAvatar.left
anchors.right: authorLabel.right
anchors.top: authorLabel.top
Expand Down Expand Up @@ -316,8 +331,11 @@ Item {
else
Qt.openUrlExternally(link)
}

TimelineTextEditSelector {}
}
MouseArea {

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.MiddleButton

Expand All @@ -328,14 +346,14 @@ Item {
}
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: controller.showMenu(index,
textFieldImpl.hoveredLink, showingDetails)
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
cursorShape: textFieldImpl.hoveredLink
? Qt.PointingHandCursor : Qt.IBeamCursor
Expand Down Expand Up @@ -480,6 +498,8 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 3
z: 1

TimelineTextEditSelector {}
}
TextEdit {
text: "<a href=\"" + evtLink + "\">"+ eventId
Expand All @@ -495,7 +515,9 @@ Item {

onLinkActivated: Qt.openUrlExternally(link)

MouseArea {
TimelineTextEditSelector {}

TimelineMouseArea {
anchors.fill: parent
cursorShape: parent.hoveredLink ?
Qt.PointingHandCursor :
Expand Down Expand Up @@ -524,6 +546,8 @@ Item {

width: parent.width
anchors.top: detailsHeader.bottom

TimelineTextEditSelector {}
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions client/qml/TimelineMouseArea.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import QtQuick 2.2

MouseArea {
onWheel: chatView.onWheel(wheel)
onReleased: controller.focusInput()
}
50 changes: 50 additions & 0 deletions client/qml/TimelineTextEditSelector.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import QtQuick 2.2

/*
* Unfortunately, TextEdit captures LeftButton events for text selection in a way which
* is not compatible with our focus-cancelling mechanism, so we took over the task here.
*/
MouseArea {
property var textEdit: parent
property var selectionMode: TextEdit.SelectCharacters

anchors.fill: parent
acceptedButtons: Qt.LeftButton

onPressed: {
var x = mouse.x
var y = mouse.y
if (textEdit.flickableItem) {
x += textEdit.flickableItem.contentX
y += textEdit.flickableItem.contentY
}
var hasSelection = textEdit.selectionEnd > textEdit.selectionStart
if (hasSelection && controller.getModifierKeys() & Qt.ShiftModifier) {
textEdit.moveCursorSelection(textEdit.positionAt(x, y), selectionMode)
} else {
textEdit.cursorPosition = textEdit.positionAt(x, y)
if (chatView.textEditWithSelection)
chatView.textEditWithSelection.deselect()
}
}
onDoubleClicked: {
selectionMode = TextEdit.SelectWords
textEdit.selectWord()
}
onReleased: {
selectionMode = TextEdit.SelectCharacters
controller.setGlobalSelectionBuffer(textEdit.selectedText)
chatView.textEditWithSelection = textEdit

controller.focusInput()
}
onPositionChanged: {
var x = mouse.x
var y = mouse.y
if (textEdit.flickableItem) {
x += textEdit.flickableItem.contentX
y += textEdit.flickableItem.contentY
}
textEdit.moveCursorSelection(textEdit.positionAt(x, y), selectionMode)
}
}
2 changes: 2 additions & 0 deletions client/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@
<file>qml/FileContent.qml</file>
<file>qml/TimelineItem.qml</file>
<file>qml/ActiveLabel.qml</file>
<file>qml/TimelineMouseArea.qml</file>
<file>qml/TimelineTextEditSelector.qml</file>
</qresource>
</RCC>