Skip to content
Snippets Groups Projects
Commit 0af0f47f authored by Ming Rui Zhang's avatar Ming Rui Zhang Committed by Sébastien Blin
Browse files

textedit: add missing context menus for text entry fields

Gitlab: #359

Change-Id: Iefe2dbde96e0613540b237571997c456231bb78c
parent a8378ab2
Branches
Tags
No related merge requests found
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<g id="Text-files">
<path d="M53.9791489,9.1429005H50.010849c-0.0826988,0-0.1562004,0.0283995-0.2331009,0.0469999V5.0228
C49.7777481,2.253,47.4731483,0,44.6398468,0h-34.422596C7.3839517,0,5.0793519,2.253,5.0793519,5.0228v46.8432999
c0,2.7697983,2.3045998,5.0228004,5.1378999,5.0228004h6.0367002v2.2678986C16.253952,61.8274002,18.4702511,64,21.1954517,64
h32.783699c2.7252007,0,4.9414978-2.1725998,4.9414978-4.8432007V13.9861002
C58.9206467,11.3155003,56.7043495,9.1429005,53.9791489,9.1429005z M7.1110516,51.8661003V5.0228
c0-1.6487999,1.3938999-2.9909999,3.1062002-2.9909999h34.422596c1.7123032,0,3.1062012,1.3422,3.1062012,2.9909999v46.8432999
c0,1.6487999-1.393898,2.9911003-3.1062012,2.9911003h-34.422596C8.5049515,54.8572006,7.1110516,53.5149002,7.1110516,51.8661003z
M56.8888474,59.1567993c0,1.550602-1.3055,2.8115005-2.9096985,2.8115005h-32.783699
c-1.6042004,0-2.9097996-1.2608986-2.9097996-2.8115005v-2.2678986h26.3541946
c2.8333015,0,5.1379013-2.2530022,5.1379013-5.0228004V11.1275997c0.0769005,0.0186005,0.1504021,0.0469999,0.2331009,0.0469999
h3.9682999c1.6041985,0,2.9096985,1.2609005,2.9096985,2.8115005V59.1567993z"/>
<path d="M38.6031494,13.2063999H16.253952c-0.5615005,0-1.0159006,0.4542999-1.0159006,1.0158005
c0,0.5615997,0.4544001,1.0158997,1.0159006,1.0158997h22.3491974c0.5615005,0,1.0158997-0.4542999,1.0158997-1.0158997
C39.6190491,13.6606998,39.16465,13.2063999,38.6031494,13.2063999z"/>
<path d="M38.6031494,21.3334007H16.253952c-0.5615005,0-1.0159006,0.4542999-1.0159006,1.0157986
c0,0.5615005,0.4544001,1.0159016,1.0159006,1.0159016h22.3491974c0.5615005,0,1.0158997-0.454401,1.0158997-1.0159016
C39.6190491,21.7877007,39.16465,21.3334007,38.6031494,21.3334007z"/>
<path d="M38.6031494,29.4603004H16.253952c-0.5615005,0-1.0159006,0.4543991-1.0159006,1.0158997
s0.4544001,1.0158997,1.0159006,1.0158997h22.3491974c0.5615005,0,1.0158997-0.4543991,1.0158997-1.0158997
S39.16465,29.4603004,38.6031494,29.4603004z"/>
<path d="M28.4444485,37.5872993H16.253952c-0.5615005,0-1.0159006,0.4543991-1.0159006,1.0158997
s0.4544001,1.0158997,1.0159006,1.0158997h12.1904964c0.5615025,0,1.0158005-0.4543991,1.0158005-1.0158997
S29.0059509,37.5872993,28.4444485,37.5872993z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
...@@ -138,5 +138,6 @@ ...@@ -138,5 +138,6 @@
<file>src/mainview/components/ParticipantOverlayMenu.qml</file> <file>src/mainview/components/ParticipantOverlayMenu.qml</file>
<file>src/commoncomponents/DaemonReconnectPopup.qml</file> <file>src/commoncomponents/DaemonReconnectPopup.qml</file>
<file>src/DaemonReconnectWindow.qml</file> <file>src/DaemonReconnectWindow.qml</file>
<file>src/commoncomponents/LineEditContextMenu.qml</file>
</qresource> </qresource>
</RCC> </RCC>
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
<file>images/icons/ic_check_white_18dp_2x.png</file> <file>images/icons/ic_check_white_18dp_2x.png</file>
<file>images/icons/ic_clear_24px.svg</file> <file>images/icons/ic_clear_24px.svg</file>
<file>images/icons/ic_close_white_24dp.png</file> <file>images/icons/ic_close_white_24dp.png</file>
<file>images/icons/ic_content_copy.svg</file>
<file>images/icons/ic_delete_black_18dp_2x.png</file> <file>images/icons/ic_delete_black_18dp_2x.png</file>
<file>images/icons/ic_done_white_24dp.png</file> <file>images/icons/ic_done_white_24dp.png</file>
<file>images/icons/ic_keypad.svg</file> <file>images/icons/ic_keypad.svg</file>
......
...@@ -53,6 +53,7 @@ MenuItem { ...@@ -53,6 +53,7 @@ MenuItem {
} }
anchors.fill: parent anchors.fill: parent
ResponsiveImage { ResponsiveImage {
id: contextMenuItemImage id: contextMenuItemImage
...@@ -72,8 +73,9 @@ MenuItem { ...@@ -72,8 +73,9 @@ MenuItem {
id: contextMenuItemText id: contextMenuItemText
anchors.left: contextMenuItemImage.right anchors.left: contextMenuItemImage.right
anchors.leftMargin: 20 anchors.leftMargin: contextMenuItemImage.visible ? 20 : 5
anchors.verticalCenter: menuItemContentRect.verticalCenter anchors.verticalCenter: menuItemContentRect.verticalCenter
width: contextMenuItemImage.visible ? width: contextMenuItemImage.visible ?
(preferredWidth - contextMenuItemImage.width - 58) : (preferredWidth - contextMenuItemImage.width - 58) :
preferredWidth - 24 preferredWidth - 24
......
/*
* Copyright (C) 2020 by Savoir-faire Linux
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* 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 3 of the License, 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 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 <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtGraphicalEffects 1.14
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import net.jami.Constants 1.0
import "js/contextmenugenerator.js" as ContextMenuGenerator
Item {
id: root
function openMenu(lineEditObj, mouseEvent) {
ContextMenuGenerator.initMenu(Qt.size(150, 25), 2)
if (lineEditObj.selectedText.length) {
ContextMenuGenerator.addMenuItem(qsTr("Copy"),
"",
function (){
lineEditObj.copy()
})
ContextMenuGenerator.addMenuItem(qsTr("Cut"),
"",
function (){
lineEditObj.cut()
})
}
ContextMenuGenerator.addMenuItem(qsTr("Paste"),
"",
function (){
lineEditObj.paste()
})
root.height = ContextMenuGenerator.getMenu().height
root.width = ContextMenuGenerator.getMenu().width
ContextMenuGenerator.getMenu().x = mouseEvent.x
ContextMenuGenerator.getMenu().y = mouseEvent.y
// lineEdit (TextEdit) selection will be lost when menu is opened
var selectionStartTemp = lineEditObj.selectionStart
var selectionEndTemp = lineEditObj.selectionEnd
ContextMenuGenerator.getMenu().open()
lineEditObj.select(selectionStartTemp, selectionEndTemp)
}
Component.onCompleted: {
ContextMenuGenerator.createBaseContextMenuObjects(root)
}
}
...@@ -24,6 +24,8 @@ import QtGraphicalEffects 1.14 ...@@ -24,6 +24,8 @@ import QtGraphicalEffects 1.14
import net.jami.Constants 1.0 import net.jami.Constants 1.0
TextField { TextField {
id: root
enum BorderColorMode { enum BorderColorMode {
NORMAL, NORMAL,
SEARCHING, SEARCHING,
...@@ -71,6 +73,7 @@ TextField { ...@@ -71,6 +73,7 @@ TextField {
wrapMode: Text.Wrap wrapMode: Text.Wrap
readOnly: false readOnly: false
selectByMouse: true selectByMouse: true
selectionColor: JamiTheme.contactSearchBarPlaceHolderTextFontColor
font.pointSize: 10 font.pointSize: 10
padding: 16 padding: 16
font.kerning: true font.kerning: true
...@@ -78,6 +81,10 @@ TextField { ...@@ -78,6 +81,10 @@ TextField {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor color: JamiTheme.textColor
LineEditContextMenu {
id: lineEditContextMenu
}
Image { Image {
id: lineEditImage id: lineEditImage
...@@ -127,8 +134,14 @@ TextField { ...@@ -127,8 +134,14 @@ TextField {
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: 4
radius: JamiTheme.lineEditRadius
border.color: readOnly? "transparent" : borderColor border.color: readOnly? "transparent" : borderColor
color: readOnly? "transparent" : backgroundColor color: readOnly? "transparent" : backgroundColor
} }
onReleased: {
if (event.button == Qt.RightButton)
lineEditContextMenu.openMenu(root, event)
}
} }
...@@ -20,14 +20,14 @@ ...@@ -20,14 +20,14 @@
var baseContextMenuComponent var baseContextMenuComponent
var baseContextMenuObject var baseContextMenuObject
var menuItemList = [] var menuItemList = []
var menuDefaultSeparatorHeight = 8
function createBaseContextMenuObjects(parent) { function createBaseContextMenuObjects(parent) {
// If already created, return, since object cannot be destroyed. // If already created, return, since object cannot be destroyed.
if (baseContextMenuObject) if (baseContextMenuObject)
return return
baseContextMenuComponent = Qt.createComponent( baseContextMenuComponent = Qt.createComponent("../BaseContextMenu.qml")
"../BaseContextMenu.qml")
if (baseContextMenuComponent.status === Component.Ready) if (baseContextMenuComponent.status === Component.Ready)
finishCreation(parent) finishCreation(parent)
else if (baseContextMenuComponent.status === Component.Error) else if (baseContextMenuComponent.status === Component.Error)
...@@ -35,13 +35,6 @@ function createBaseContextMenuObjects(parent) { ...@@ -35,13 +35,6 @@ function createBaseContextMenuObjects(parent) {
baseContextMenuComponent.errorString()) baseContextMenuComponent.errorString())
} }
function initMenu() {
// Clear any existing items in the menu.
for (var i = 0; i < menuItemList.length; i++) {
baseContextMenuObject.removeItem(menuItemList[i])
}
}
function finishCreation(parent) { function finishCreation(parent) {
baseContextMenuObject = baseContextMenuComponent.createObject(parent) baseContextMenuObject = baseContextMenuComponent.createObject(parent)
if (baseContextMenuObject === null) { if (baseContextMenuObject === null) {
...@@ -49,27 +42,45 @@ function finishCreation(parent) { ...@@ -49,27 +42,45 @@ function finishCreation(parent) {
console.log("Error creating object for base context menu") console.log("Error creating object for base context menu")
} }
baseContextMenuObject.closed.connect(function (){ baseContextMenuObject.closed.connect(function () {
// Remove the menu items when hidden. // Remove the menu items when hidden.
for (var i = 0; i < menuItemList.length; i++) { for (var i = 0; i < menuItemList.length; i++) {
baseContextMenuObject.removeItem(menuItemList[i]) baseContextMenuObject.removeItem(menuItemList[i])
} }
}) })
baseContextMenuObject.aboutToShow.connect(function (){ baseContextMenuObject.aboutToShow.connect(function () {
// Add default separator at the bottom. // Add default separator at the bottom.
addMenuSeparator(8, "transparent") addMenuSeparator(menuDefaultSeparatorHeight, "transparent")
}) })
} }
function initMenu(preferedMenuItemSize, defaultSeparatorHeight) {
// Clear any existing items in the menu.
for (var i = 0; i < menuItemList.length; i++) {
baseContextMenuObject.removeItem(menuItemList[i])
}
if (preferedMenuItemSize) {
baseContextMenuObject.menuItemsPreferredWidth = preferedMenuItemSize.width
baseContextMenuObject.menuItemsPreferredHeight = preferedMenuItemSize.height
}
if (defaultSeparatorHeight)
menuDefaultSeparatorHeight = defaultSeparatorHeight
}
function addMenuSeparator(separatorHeight, separatorColor) { function addMenuSeparator(separatorHeight, separatorColor) {
var menuSeparatorObject var menuSeparatorObject
var menuSeparatorComponent = Qt.createComponent("../GeneralMenuSeparator.qml"); var menuSeparatorComponent = Qt.createComponent(
"../GeneralMenuSeparator.qml")
if (menuSeparatorComponent.status === Component.Ready) { if (menuSeparatorComponent.status === Component.Ready) {
baseContextMenuObject.generalMenuSeparatorCount ++ baseContextMenuObject.generalMenuSeparatorCount++
menuSeparatorObject = menuSeparatorComponent.createObject(null, menuSeparatorObject = menuSeparatorComponent.createObject(
{preferredWidth: baseContextMenuObject.menuItemsPreferredWidth, null, {
preferredHeight: separatorHeight ? separatorHeight : 1}) "preferredWidth": baseContextMenuObject.menuItemsPreferredWidth,
"preferredHeight": separatorHeight ? separatorHeight : 1
})
if (separatorColor) if (separatorColor)
menuSeparatorObject.separatorColor = separatorColor menuSeparatorObject.separatorColor = separatorColor
} else if (menuSeparatorComponent.status === Component.Error) } else if (menuSeparatorComponent.status === Component.Error)
...@@ -85,30 +96,30 @@ function addMenuSeparator(separatorHeight, separatorColor) { ...@@ -85,30 +96,30 @@ function addMenuSeparator(separatorHeight, separatorColor) {
} }
} }
function addMenuItem(itemName, function addMenuItem(itemName, iconSource, onClickedCallback, iconColor) {
iconSource, if (!baseContextMenuObject.count) {
onClickedCallback,
iconColor="") {
if (!baseContextMenuObject.count){
// Add default separator at the top. // Add default separator at the top.
addMenuSeparator(8, "transparent") addMenuSeparator(menuDefaultSeparatorHeight, "transparent")
} }
var menuItemObject var menuItemObject
var menuItemComponent = Qt.createComponent("../GeneralMenuItem.qml"); var menuItemComponent = Qt.createComponent("../GeneralMenuItem.qml")
if (menuItemComponent.status === Component.Ready) { if (menuItemComponent.status === Component.Ready) {
menuItemObject = menuItemComponent.createObject(null, menuItemObject = menuItemComponent.createObject(
{itemName: itemName, null, {
iconSource: iconSource, "itemName": itemName,
iconColor: iconColor, "iconSource": iconSource,
leftBorderWidth: baseContextMenuObject.commonBorderWidth, "iconColor": iconColor,
rightBorderWidth: baseContextMenuObject.commonBorderWidth}) "preferredWidth": baseContextMenuObject.menuItemsPreferredWidth,
"preferredHeight": baseContextMenuObject.menuItemsPreferredHeight,
"leftBorderWidth": baseContextMenuObject.commonBorderWidth,
"rightBorderWidth": baseContextMenuObject.commonBorderWidth
})
} else if (menuItemComponent.status === Component.Error) } else if (menuItemComponent.status === Component.Error)
console.log("Error loading component:", console.log("Error loading component:", menuItemComponent.errorString())
menuItemComponent.errorString())
if (menuItemObject !== null) { if (menuItemObject !== null) {
menuItemObject.clicked.connect(function () { menuItemObject.clicked.connect(function () {
var callback = function(){ var callback = function () {
onClickedCallback() onClickedCallback()
baseContextMenuObject.onVisibleChanged.disconnect(callback) baseContextMenuObject.onVisibleChanged.disconnect(callback)
baseContextMenuObject.close() baseContextMenuObject.close()
......
...@@ -46,6 +46,10 @@ Rectangle { ...@@ -46,6 +46,10 @@ Rectangle {
id: fakeFocus id: fakeFocus
} }
LineEditContextMenu {
id: lineEditContextMenu
}
Image { Image {
id: searchIconImage id: searchIconImage
...@@ -94,6 +98,10 @@ Rectangle { ...@@ -94,6 +98,10 @@ Rectangle {
} }
onTextChanged: root.contactSearchBarTextChanged(contactSearchBar.text) onTextChanged: root.contactSearchBarTextChanged(contactSearchBar.text)
onReleased: {
if (event.button == Qt.RightButton)
lineEditContextMenu.openMenu(contactSearchBar, event)
}
} }
PushButton { PushButton {
......
...@@ -146,7 +146,7 @@ Rectangle { ...@@ -146,7 +146,7 @@ Rectangle {
source: "qrc:/images/icons/content_copy-24px.svg" source: "qrc:/images/icons/content_copy-24px.svg"
onClicked: { onClicked: {
UtilsAdapter.setText( UtilsAdapter.setClipboardText(
textMetricsjamiRegisteredNameText.text) textMetricsjamiRegisteredNameText.text)
} }
} }
......
...@@ -50,7 +50,7 @@ UtilsAdapter::getVersionStr() ...@@ -50,7 +50,7 @@ UtilsAdapter::getVersionStr()
} }
void void
UtilsAdapter::setText(QString text) UtilsAdapter::setClipboardText(QString text)
{ {
clipboard_->setText(text, QClipboard::Clipboard); clipboard_->setText(text, QClipboard::Clipboard);
} }
......
...@@ -41,7 +41,7 @@ public: ...@@ -41,7 +41,7 @@ public:
Q_INVOKABLE const QString getProjectCredits(); Q_INVOKABLE const QString getProjectCredits();
Q_INVOKABLE const QString getVersionStr(); Q_INVOKABLE const QString getVersionStr();
Q_INVOKABLE void setText(QString text); Q_INVOKABLE void setClipboardText(QString text);
Q_INVOKABLE const QString qStringFromFile(const QString& filename); Q_INVOKABLE const QString qStringFromFile(const QString& filename);
Q_INVOKABLE const QString getStyleSheet(const QString& name, const QString& source); Q_INVOKABLE const QString getStyleSheet(const QString& name, const QString& source);
Q_INVOKABLE const QString getCachePath(); Q_INVOKABLE const QString getCachePath();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment