mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 07:36:44 +00:00
feat(BRIDGE-88): added context menu for quick actions on input labels: cut, copy, paste
This commit is contained in:
@ -75,7 +75,7 @@ if(NOT UNIX)
|
|||||||
set(CMAKE_INSTALL_BINDIR ".")
|
set(CMAKE_INSTALL_BINDIR ".")
|
||||||
endif(NOT UNIX)
|
endif(NOT UNIX)
|
||||||
|
|
||||||
find_package(Qt6 COMPONENTS Core Quick Qml QuickControls2 Widgets Svg REQUIRED)
|
find_package(Qt6 COMPONENTS Core Quick Qml QuickControls2 Widgets Svg Gui REQUIRED)
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
message(STATUS "Using Qt ${Qt6_VERSION}")
|
message(STATUS "Using Qt ${Qt6_VERSION}")
|
||||||
@ -120,6 +120,7 @@ add_executable(bridge-gui
|
|||||||
UserList.cpp UserList.h
|
UserList.cpp UserList.h
|
||||||
SentryUtils.cpp SentryUtils.h
|
SentryUtils.cpp SentryUtils.h
|
||||||
Settings.cpp Settings.h
|
Settings.cpp Settings.h
|
||||||
|
ClipboardProxy.cpp ClipboardProxy.h
|
||||||
${DOCK_ICON_SRC_FILE} MacOS/DockIcon.h
|
${DOCK_ICON_SRC_FILE} MacOS/DockIcon.h
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -148,6 +149,7 @@ target_link_libraries(bridge-gui
|
|||||||
Qt6::Qml
|
Qt6::Qml
|
||||||
Qt6::QuickControls2
|
Qt6::QuickControls2
|
||||||
Qt6::Svg
|
Qt6::Svg
|
||||||
|
Qt6::Gui
|
||||||
sentry::sentry
|
sentry::sentry
|
||||||
bridgepp
|
bridgepp
|
||||||
)
|
)
|
||||||
|
|||||||
25
internal/frontend/bridge-gui/bridge-gui/ClipboardProxy.cpp
Normal file
25
internal/frontend/bridge-gui/bridge-gui/ClipboardProxy.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) 2024 Proton AG
|
||||||
|
// This file is part of Proton Mail Bridge.
|
||||||
|
// Proton Mail Bridge 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
// Proton Mail Bridge 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#include "ClipboardProxy.h"
|
||||||
|
|
||||||
|
// The following definitions were taken and adapted from:
|
||||||
|
// https://stackoverflow.com/questions/40092352/passing-qclipboard-to-qml
|
||||||
|
// Author: krzaq
|
||||||
|
|
||||||
|
ClipboardProxy::ClipboardProxy(QClipboard* c) : clipboard(c) {
|
||||||
|
connect(clipboard, &QClipboard::dataChanged, this, &ClipboardProxy::textChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ClipboardProxy::text() const {
|
||||||
|
return clipboard->text();
|
||||||
|
}
|
||||||
38
internal/frontend/bridge-gui/bridge-gui/ClipboardProxy.h
Normal file
38
internal/frontend/bridge-gui/bridge-gui/ClipboardProxy.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2024 Proton AG
|
||||||
|
// This file is part of Proton Mail Bridge.
|
||||||
|
// Proton Mail Bridge 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
// Proton Mail Bridge 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#ifndef BRIDGE_GUI_CLIPBOARDPROXY_H
|
||||||
|
#define BRIDGE_GUI_CLIPBOARDPROXY_H
|
||||||
|
|
||||||
|
// The following class declarations were taken and adapted from:
|
||||||
|
// https://stackoverflow.com/questions/40092352/passing-qclipboard-to-qml
|
||||||
|
// Author: krzaq
|
||||||
|
|
||||||
|
|
||||||
|
class ClipboardProxy : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString text READ text NOTIFY textChanged)
|
||||||
|
public:
|
||||||
|
explicit ClipboardProxy(QClipboard*);
|
||||||
|
|
||||||
|
QString text() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QClipboard* clipboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //BRIDGE_GUI_CLIPBOARDPROXY_H
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <QtQuickControls2>
|
#include <QtQuickControls2>
|
||||||
#include <QtSvg>
|
#include <QtSvg>
|
||||||
|
#include <QtGui>
|
||||||
#include <AppController.h>
|
#include <AppController.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -132,5 +132,6 @@
|
|||||||
<file>qml/ConnectionModeSettings.qml</file>
|
<file>qml/ConnectionModeSettings.qml</file>
|
||||||
<file>qml/SplashScreen.qml</file>
|
<file>qml/SplashScreen.qml</file>
|
||||||
<file>qml/Status.qml</file>
|
<file>qml/Status.qml</file>
|
||||||
|
<file>qml/Proton/ContextMenu.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include <bridgepp/Log/Log.h>
|
#include <bridgepp/Log/Log.h>
|
||||||
#include <bridgepp/Log/LogUtils.h>
|
#include <bridgepp/Log/LogUtils.h>
|
||||||
#include <bridgepp/ProcessMonitor.h>
|
#include <bridgepp/ProcessMonitor.h>
|
||||||
|
#include <ClipboardProxy.h>
|
||||||
|
|
||||||
#include "bridgepp/CLI/CLIUtils.h"
|
#include "bridgepp/CLI/CLIUtils.h"
|
||||||
|
|
||||||
@ -347,6 +348,8 @@ int main(int argc, char *argv[]) {
|
|||||||
log.info(QString("Qt Quick renderer: %1").arg(QQuickWindow::sceneGraphBackend()));
|
log.info(QString("Qt Quick renderer: %1").arg(QQuickWindow::sceneGraphBackend()));
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
// Set up clipboard
|
||||||
|
engine.rootContext()->setContextProperty("clipboard", new ClipboardProxy(QGuiApplication::clipboard()));
|
||||||
std::unique_ptr<QQmlComponent> rootComponent(createRootQmlComponent(engine));
|
std::unique_ptr<QQmlComponent> rootComponent(createRootQmlComponent(engine));
|
||||||
std::unique_ptr<QObject> rootObject(rootComponent->create(engine.rootContext()));
|
std::unique_ptr<QObject> rootObject(rootComponent->create(engine.rootContext()));
|
||||||
if (!rootObject) {
|
if (!rootObject) {
|
||||||
|
|||||||
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2024 Proton AG
|
||||||
|
// This file is part of Proton Mail Bridge.
|
||||||
|
// Proton Mail Bridge 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
// Proton Mail Bridge 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property var parentObject: null
|
||||||
|
property var colorScheme: null
|
||||||
|
property bool readOnly: false
|
||||||
|
property bool isPassword: false
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: controlMouseArea
|
||||||
|
width: parentObject ? parentObject.width : 0
|
||||||
|
height: parentObject ? parentObject.height : 0
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onClicked: controlContextMenu.popup()
|
||||||
|
|
||||||
|
propagateComposedEvents: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: controlContextMenu
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (controlContextMenu.visible) {
|
||||||
|
const hasSelectedText = parentObject.selectedText.length > 0;
|
||||||
|
const hasClipboardText = clipboard.text.length > 0;
|
||||||
|
|
||||||
|
copyMenuItem.visible = hasSelectedText && !isPassword;
|
||||||
|
cutMenuItem.visible = hasSelectedText && !readOnly && !isPassword;
|
||||||
|
pasteMenuItem.visible = hasClipboardText && !readOnly;
|
||||||
|
controlContextMenu.visible = copyMenuItem.visible || cutMenuItem.visible || pasteMenuItem.visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
id: cutMenuItem
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
text: qsTr("Cut")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
parentObject.cut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
id: copyMenuItem
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
text: qsTr("Copy")
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
parentObject.copy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
id: pasteMenuItem
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
|
||||||
|
text: qsTr("Paste")
|
||||||
|
onTriggered: {
|
||||||
|
parentObject.paste()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -362,4 +362,9 @@ FocusScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Proton.ContextMenu {
|
||||||
|
parentObject: root
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -331,6 +331,15 @@ FocusScope {
|
|||||||
x: control.leftPadding
|
x: control.leftPadding
|
||||||
y: control.topPadding
|
y: control.topPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Proton.ContextMenu {
|
||||||
|
parentObject: control
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
isPassword: control.echoMode === TextInput.Password
|
||||||
|
readOnly: control.readOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Proton.Button {
|
Proton.Button {
|
||||||
id: eyeButton
|
id: eyeButton
|
||||||
|
|||||||
@ -39,3 +39,4 @@ TextArea 4.0 TextArea.qml
|
|||||||
TextField 4.0 TextField.qml
|
TextField 4.0 TextField.qml
|
||||||
Toggle 4.0 Toggle.qml
|
Toggle 4.0 Toggle.qml
|
||||||
WebFrame 4.0 WebFrame.qml
|
WebFrame 4.0 WebFrame.qml
|
||||||
|
ContextMenu 4.0 ContextMenu.qml
|
||||||
|
|||||||
Reference in New Issue
Block a user