diff --git a/applets/notes/package/contents/ui/ShortcutMenuItem.qml b/applets/notes/package/contents/ui/ShortcutMenuItem.qml new file mode 100644 --- /dev/null +++ b/applets/notes/package/contents/ui/ShortcutMenuItem.qml @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Luca Carlon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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 Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.12 + +MenuItem { + property alias _sequence: shortcutElement.sequence + property alias _text: actionElement.text + property alias _enabled: actionElement.enabled + property alias _iconName: actionElement.icon.name + + Shortcut { + id: shortcutElement + enabled: false + } + + action: Action { + id: actionElement + shortcut: shortcutElement.nativeText + } +} \ No newline at end of file diff --git a/applets/notes/package/contents/ui/main.qml b/applets/notes/package/contents/ui/main.qml --- a/applets/notes/package/contents/ui/main.qml +++ b/applets/notes/package/contents/ui/main.qml @@ -17,14 +17,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -import QtQuick 2.1 +import QtQuick 2.6 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.1 import org.kde.draganddrop 2.0 as DragDrop import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.components 3.0 as PlasmaComponents3 import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.plasmoid 2.0 @@ -144,61 +145,163 @@ bottomMargin: verticalMargins } - PlasmaComponents.TextArea { - id: mainTextArea + QQC2.ScrollView { anchors { top: parent.top left: parent.left right: parent.right bottom: fontButtons.top bottomMargin: Math.round(units.largeSpacing / 2) } - backgroundVisible: false - frameVisible: false - textFormat: TextEdit.RichText + clip: true - onLinkActivated: Qt.openUrlExternally(link) + PlasmaComponents3.TextArea { + id: mainTextArea - Keys.onPressed: { - if(event.key === Qt.Key_Escape) { - plasmoid.expanded = false; - event.accepted = true; - } else if(event.modifiers === Qt.ControlModifier) { - if(event.key === Qt.Key_B) { - documentHandler.bold = !documentHandler.bold; - event.accepted = true; - } else if(event.key === Qt.Key_I) { - documentHandler.italic = !documentHandler.italic; - event.accepted = true; - } else if(event.key === Qt.Key_U) { - documentHandler.underline = !documentHandler.underline; + textFormat: TextEdit.RichText + onLinkActivated: Qt.openUrlExternally(link) + background: Rectangle { color: "transparent" } + color: textIconColor + persistentSelection: true + wrapMode: TextEdit.Wrap + + Keys.onPressed: { + if(event.key === Qt.Key_Escape) { + plasmoid.expanded = false; event.accepted = true; - } else if(event.key === Qt.Key_S) { - documentHandler.strikeOut = !documentHandler.strikeOut; + } else if(event.modifiers === Qt.ControlModifier) { + if(event.key === Qt.Key_B) { + documentHandler.bold = !documentHandler.bold; + event.accepted = true; + } else if(event.key === Qt.Key_I) { + documentHandler.italic = !documentHandler.italic; + event.accepted = true; + } else if(event.key === Qt.Key_U) { + documentHandler.underline = !documentHandler.underline; + event.accepted = true; + } else if(event.key === Qt.Key_S) { + documentHandler.strikeOut = !documentHandler.strikeOut; + event.accepted = true; + } else if(event.matches(StandardKey.Paste)) { + documentHandler.pasteWithoutFormatting(); + documentHandler.reset(); + event.accepted = true; + } else if(event.matches(StandardKey.Cut)) { + mainTextArea.cut(); + documentHandler.reset(); + event.accepted = true; + } + } + } + + // update the note if the source changes, but only if the user isn't editing it currently + Binding { + target: mainTextArea + property: "text" + value: note.noteText + when: !mainTextArea.activeFocus + } + + onActiveFocusChanged: { + if (activeFocus) { + plasmoid.status = PlasmaCore.Types.AcceptingInputStatus + } else { + plasmoid.status = PlasmaCore.Types.ActiveStatus + note.save(mainTextArea.text); + } + } + + onPressed: { + if (event.button === Qt.RightButton) { event.accepted = true; + contextMenu.popup(); + mainTextArea.forceActiveFocus(); } } - } - style: PlasmaStyle.TextAreaStyle { - textColor: textIconColor - } + QQC2.Menu { + id: contextMenu - // update the note if the source changes, but only if the user isn't editing it currently - Binding { - target: mainTextArea - property: "text" - value: note.noteText - when: !mainTextArea.activeFocus - } + ShortcutMenuItem { + _sequence: StandardKey.Undo + _enabled: mainTextArea.canUndo + _iconName: "edit-undo" + _text: i18n("Undo") + onTriggered: contextMenu.retFocus(() => mainTextArea.undo()) + } - onActiveFocusChanged: { - if (activeFocus) { - plasmoid.status = PlasmaCore.Types.AcceptingInputStatus - } else { - plasmoid.status = PlasmaCore.Types.ActiveStatus - note.save(mainTextArea.text); + ShortcutMenuItem { + _sequence: StandardKey.Redo + _enabled: mainTextArea.canRedo + _iconName: "edit-redo" + _text: i18n("Redo") + onTriggered: contextMenu.retFocus(() => mainTextArea.redo()) + } + + QQC2.MenuSeparator {} + + ShortcutMenuItem { + _sequence: StandardKey.Cut + _enabled: mainTextArea.selectedText.length > 0 + _iconName: "edit-cut" + _text: i18n("Cut") + onTriggered: contextMenu.retFocus(() => mainTextArea.cut()) + } + + ShortcutMenuItem { + _sequence: StandardKey.Copy + _enabled: mainTextArea.selectedText.length > 0 + _iconName: "edit-copy" + _text: i18n("Copy") + onTriggered: contextMenu.retFocus(() => mainTextArea.copy()) + } + + ShortcutMenuItem { + _sequence: StandardKey.Paste + _enabled: mainTextArea.canPaste + _iconName: "edit-paste" + _text: i18n("Paste Without Formatting") + onTriggered: contextMenu.retFocus(() => documentHandler.pasteWithoutFormatting()) + } + + ShortcutMenuItem { + _enabled: mainTextArea.canPaste + _text: i18n("Paste") + _iconName: "edit-paste" + onTriggered: contextMenu.retFocus(() => mainTextArea.paste()) + } + + ShortcutMenuItem { + _sequence: StandardKey.Delete + _enabled: mainTextArea.selectedText.length > 0 + _iconName: "edit-delete" + _text: i18n("Delete") + onTriggered: contextMenu.retFocus(() => mainTextArea.remove(mainTextArea.selectionStart, mainTextArea.selectionEnd)) + } + + ShortcutMenuItem { + _enabled: mainTextArea.text.length > 0 + _iconName: "edit-clear" + _text: i18n("Clear") + onTriggered: contextMenu.retFocus(() => mainTextArea.clear()) + } + + QQC2.MenuSeparator {} + + ShortcutMenuItem { + _sequence: StandardKey.SelectAll + _enabled: mainTextArea.text.length > 0 + _iconName: "edit-select-all" + _text: i18n("Select All") + onTriggered: contextMenu.retFocus(() => mainTextArea.selectAll()) + } + + function retFocus(f) { + f() + documentHandler.reset() + mainTextArea.forceActiveFocus() + } } } } diff --git a/applets/notes/plugin/documenthandler.h b/applets/notes/plugin/documenthandler.h --- a/applets/notes/plugin/documenthandler.h +++ b/applets/notes/plugin/documenthandler.h @@ -120,6 +120,9 @@ void setDocumentTitle(QString arg); + void pasteWithoutFormatting(); + void reset(); + Q_SIGNALS: void targetChanged(); void cursorPositionChanged(); @@ -144,7 +147,6 @@ void documentTitleChanged(); private: - void reset(); QTextCursor textCursor() const; void mergeFormatOnWordOrSelection(const QTextCharFormat &format); diff --git a/applets/notes/plugin/documenthandler.cpp b/applets/notes/plugin/documenthandler.cpp --- a/applets/notes/plugin/documenthandler.cpp +++ b/applets/notes/plugin/documenthandler.cpp @@ -49,6 +49,9 @@ #include #include #include +#include +#include +#include DocumentHandler::DocumentHandler() : m_target(nullptr) @@ -88,6 +91,24 @@ } } +void DocumentHandler::pasteWithoutFormatting() +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return; + + QClipboard *clipboard = QGuiApplication::clipboard(); + if (!clipboard) + return; + + const QMimeData *mimeData = clipboard->mimeData(); + if (!mimeData) + return; + + QString content = mimeData->text(); + cursor.insertText(content, QTextCharFormat()); +} + void DocumentHandler::setText(const QString &arg) { if (m_text != arg) {