mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2025-04-23 23:15:41 +02:00
Implemented notification action buttons and context menu for confirm/dismiss and other actions.
Signed-off-by: allexzander <blackslayer4@gmail.com>
This commit is contained in:
parent
7721832ee0
commit
f04281cb69
@ -5,5 +5,6 @@
|
||||
<file>src/gui/tray/HeaderButton.qml</file>
|
||||
<file>theme/Style/Style.qml</file>
|
||||
<file>theme/Style/qmldir</file>
|
||||
<file>src/gui/tray/ActivityActionButton.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -43,6 +43,7 @@ set(client_UI_SRCS
|
||||
addcertificatedialog.ui
|
||||
proxyauthdialog.ui
|
||||
mnemonicdialog.ui
|
||||
tray/ActivityActionButton.qml
|
||||
tray/Window.qml
|
||||
tray/UserLine.qml
|
||||
wizard/flow2authwidget.ui
|
||||
|
106
src/gui/tray/ActivityActionButton.qml
Normal file
106
src/gui/tray/ActivityActionButton.qml
Normal file
@ -0,0 +1,106 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.3
|
||||
import Style 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
readonly property bool labelVisible: label.visible
|
||||
readonly property bool iconVisible: icon.visible
|
||||
|
||||
// label value
|
||||
property string text: ""
|
||||
|
||||
// icon value
|
||||
property string imageSource: ""
|
||||
|
||||
// Tooltip value
|
||||
property string tooltipText: text
|
||||
|
||||
// text color
|
||||
property color textColor: Style.ncTextColor
|
||||
property color textColorHovered: Style.lightHover
|
||||
|
||||
// text background color
|
||||
property color textBgColor: "transparent"
|
||||
property color textBgColorHovered: Style.lightHover
|
||||
|
||||
// icon background color
|
||||
property color iconBgColor: "transparent"
|
||||
property color iconBgColorHovered: Style.lightHover
|
||||
|
||||
// text border color
|
||||
property color textBorderColor: "transparent"
|
||||
|
||||
property alias hovered: mouseArea.containsMouse
|
||||
|
||||
signal clicked()
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text !== "" ? text : (tooltipText !== "" ? tooltipText : qsTr("Activity action button"))
|
||||
Accessible.onPressAction: clicked()
|
||||
|
||||
// background with border around the Text
|
||||
Rectangle {
|
||||
visible: parent.labelVisible
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
// padding
|
||||
anchors.topMargin: 10
|
||||
anchors.bottomMargin: 10
|
||||
|
||||
border.color: parent.textBorderColor
|
||||
border.width: 1
|
||||
|
||||
color: parent.hovered ? parent.textBgColorHovered : parent.textBgColor
|
||||
|
||||
radius: 25
|
||||
}
|
||||
|
||||
// background with border around the Image
|
||||
Rectangle {
|
||||
visible: parent.iconVisible
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
color: parent.hovered ? parent.iconBgColorHovered : parent.iconBgColor
|
||||
}
|
||||
|
||||
// label
|
||||
Text {
|
||||
id: label
|
||||
visible: parent.text !== ""
|
||||
text: parent.text
|
||||
font: parent.font
|
||||
color: parent.hovered ? parent.textColorHovered : parent.textColor
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
// icon
|
||||
Image {
|
||||
id: icon
|
||||
visible: parent.imageSource !== ""
|
||||
anchors.centerIn: parent
|
||||
source: parent.imageSource
|
||||
sourceSize.width: visible ? 32 : 0
|
||||
sourceSize.height: visible ? 32 : 0
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: parent.clicked()
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
ToolTip {
|
||||
text: parent.tooltipText
|
||||
delay: 1000
|
||||
visible: text != "" && parent.hovered
|
||||
}
|
||||
}
|
@ -27,11 +27,18 @@ namespace OCC {
|
||||
|
||||
class ActivityLink
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
Q_PROPERTY(QString label MEMBER _label)
|
||||
Q_PROPERTY(QString link MEMBER _link)
|
||||
Q_PROPERTY(QByteArray verb MEMBER _verb)
|
||||
Q_PROPERTY(bool primary MEMBER _primary)
|
||||
|
||||
public:
|
||||
QString _label;
|
||||
QString _link;
|
||||
QByteArray _verb;
|
||||
bool _isPrimary;
|
||||
bool _primary;
|
||||
};
|
||||
|
||||
/* ==================================================================== */
|
||||
|
@ -53,6 +53,7 @@ QHash<int, QByteArray> ActivityListModel::roleNames() const
|
||||
roles[ActionRole] = "type";
|
||||
roles[ActionIconRole] = "icon";
|
||||
roles[ActionTextRole] = "subject";
|
||||
roles[ActionsLinksRole] = "links";
|
||||
roles[ActionTextColorRole] = "activityTextTitleColor";
|
||||
roles[ObjectTypeRole] = "objectType";
|
||||
roles[PointInTimeRole] = "dateTime";
|
||||
@ -139,10 +140,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
case ActionsLinksRole: {
|
||||
QList<QVariant> customList;
|
||||
foreach (ActivityLink customItem, a._links) {
|
||||
QVariant customVariant;
|
||||
customVariant.setValue(customItem);
|
||||
customList << customVariant;
|
||||
foreach (ActivityLink activityLink, a._links) {
|
||||
customList << QVariant::fromValue(activityLink);
|
||||
}
|
||||
return customList;
|
||||
}
|
||||
@ -418,17 +417,17 @@ void ActivityListModel::removeActivityFromActivityList(Activity activity)
|
||||
}
|
||||
}
|
||||
|
||||
void ActivityListModel::triggerActionAtIndex(int id) const
|
||||
void ActivityListModel::triggerDefaultAction(int activityIndex) const
|
||||
{
|
||||
if (id < 0 || id >= _finalList.size()) {
|
||||
qCWarning(lcActivity) << "Couldn't trigger action at index" << id << "/ final list size:" << _finalList.size();
|
||||
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
||||
qCWarning(lcActivity) << "Couldn't trigger default action at index" << activityIndex << "/ final list size:" << _finalList.size();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto modelIndex = index(id);
|
||||
const auto modelIndex = index(activityIndex);
|
||||
const auto path = data(modelIndex, PathRole).toUrl();
|
||||
|
||||
const auto activity = _finalList.at(id);
|
||||
const auto activity = _finalList.at(activityIndex);
|
||||
if (activity._status == SyncFileItem::Conflict) {
|
||||
Q_ASSERT(!activity._file.isEmpty());
|
||||
Q_ASSERT(!activity._folder.isEmpty());
|
||||
@ -461,6 +460,30 @@ void ActivityListModel::triggerActionAtIndex(int id) const
|
||||
}
|
||||
}
|
||||
|
||||
void ActivityListModel::triggerAction(int activityIndex, int actionIndex)
|
||||
{
|
||||
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
||||
qCWarning(lcActivity) << "Couldn't trigger action on activity at index" << activityIndex << "/ final list size:" << _finalList.size();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto activity = _finalList[activityIndex];
|
||||
|
||||
if (actionIndex < 0 || actionIndex >= activity._links.size()) {
|
||||
qCWarning(lcActivity) << "Couldn't trigger action at index" << actionIndex << "/ actions list size:" << activity._links.size();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto action = activity._links[actionIndex];
|
||||
|
||||
if (action._verb == "WEB") {
|
||||
QDesktopServices::openUrl(QUrl(action._link));
|
||||
return;
|
||||
}
|
||||
|
||||
emit sendNotificationRequest(activity._accName, action._link, action._verb, activityIndex);
|
||||
}
|
||||
|
||||
void ActivityListModel::combineActivityLists()
|
||||
{
|
||||
ActivityList resultList;
|
||||
|
@ -74,7 +74,8 @@ public:
|
||||
void removeActivityFromActivityList(int row);
|
||||
void removeActivityFromActivityList(Activity activity);
|
||||
|
||||
Q_INVOKABLE void triggerActionAtIndex(int id) const;
|
||||
Q_INVOKABLE void triggerDefaultAction(int activityIndex) const;
|
||||
Q_INVOKABLE void triggerAction(int activityIndex, int actionIndex);
|
||||
|
||||
public slots:
|
||||
void slotRefreshActivity();
|
||||
@ -86,6 +87,7 @@ private slots:
|
||||
|
||||
signals:
|
||||
void activityJobStatusCode(int statusCode);
|
||||
void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
@ -128,7 +128,7 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j
|
||||
al._label = QUrl::fromPercentEncoding(actionJson.value("label").toString().toUtf8());
|
||||
al._link = actionJson.value("link").toString();
|
||||
al._verb = actionJson.value("type").toString().toUtf8();
|
||||
al._isPrimary = actionJson.value("primary").toBool();
|
||||
al._primary = actionJson.value("primary").toBool();
|
||||
|
||||
a._links.append(al);
|
||||
}
|
||||
@ -139,7 +139,7 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j
|
||||
al._label = tr("Dismiss");
|
||||
al._link = Utility::concatUrlPath(ai->account()->url(), notificationsPath + "/" + QString::number(a._id)).toString();
|
||||
al._verb = "DELETE";
|
||||
al._isPrimary = false;
|
||||
al._primary = false;
|
||||
a._links.append(al);
|
||||
|
||||
list.append(a);
|
||||
|
@ -51,6 +51,8 @@ User::User(AccountStatePtr &account, const bool &isCurrent, QObject *parent)
|
||||
connect(this, &User::guiLog, Logger::instance(), &Logger::guiLog);
|
||||
|
||||
connect(_account->account().data(), &Account::accountChangedAvatar, this, &User::avatarChanged);
|
||||
|
||||
connect(_activityModel, &ActivityListModel::sendNotificationRequest, this, &User::slotSendNotificationRequest);
|
||||
}
|
||||
|
||||
void User::slotBuildNotificationDisplay(const ActivityList &list)
|
||||
@ -329,7 +331,7 @@ void User::slotAddError(const QString &folderAlias, const QString &message, Erro
|
||||
link._label = tr("Retry all uploads");
|
||||
link._link = folderInstance->path();
|
||||
link._verb = "";
|
||||
link._isPrimary = true;
|
||||
link._primary = true;
|
||||
activity._links.append(link);
|
||||
}
|
||||
|
||||
|
@ -108,23 +108,11 @@ Window {
|
||||
id: trayWindowHeaderBackground
|
||||
|
||||
anchors.left: trayWindowBackground.left
|
||||
anchors.right: trayWindowBackground.right
|
||||
anchors.top: trayWindowBackground.top
|
||||
height: Style.trayWindowHeaderHeight
|
||||
width: Style.trayWindowWidth
|
||||
color: Style.ncBlue
|
||||
|
||||
// The overlay rectangle below eliminates the rounded corners from the bottom of the header
|
||||
// as Qt only allows setting the radius for all corners right now, not specific ones
|
||||
Rectangle {
|
||||
id: trayWindowHeaderButtomHalfBackground
|
||||
|
||||
anchors.left: trayWindowHeaderBackground.left
|
||||
anchors.bottom: trayWindowHeaderBackground.bottom
|
||||
height: Style.trayWindowHeaderHeight / 2
|
||||
width: Style.trayWindowWidth
|
||||
color: Style.ncBlue
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: trayWindowHeaderLayout
|
||||
|
||||
@ -511,16 +499,17 @@ Window {
|
||||
|
||||
ListView {
|
||||
id: activityListView
|
||||
|
||||
anchors.top: trayWindowHeaderBackground.bottom
|
||||
anchors.horizontalCenter: trayWindowBackground.horizontalCenter
|
||||
width: Style.trayWindowWidth - Style.trayWindowBorderWidth
|
||||
height: Style.trayWindowHeight - Style.trayWindowHeaderHeight
|
||||
anchors.left: trayWindowBackground.left
|
||||
anchors.right: trayWindowBackground.right
|
||||
anchors.bottom: trayWindowBackground.bottom
|
||||
clip: true
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: listViewScrollbar
|
||||
}
|
||||
|
||||
readonly property int maxActionButtons: 2
|
||||
|
||||
keyNavigationEnabled: true
|
||||
|
||||
Accessible.role: Accessible.List
|
||||
@ -531,26 +520,28 @@ Window {
|
||||
delegate: RowLayout {
|
||||
id: activityItem
|
||||
|
||||
readonly property variant links: model.links
|
||||
|
||||
readonly property int itemIndex: model.index
|
||||
|
||||
width: parent.width
|
||||
height: Style.trayWindowHeaderHeight
|
||||
spacing: 0
|
||||
|
||||
Accessible.role: Accessible.ListItem
|
||||
Accessible.name: path !== "" ? qsTr("Open %1 locally").arg(displayPath)
|
||||
: message
|
||||
: message
|
||||
Accessible.onPressAction: activityMouseArea.clicked()
|
||||
|
||||
MouseArea {
|
||||
id: activityMouseArea
|
||||
enabled: (path !== "" || link !== "")
|
||||
anchors.left: activityItem.left
|
||||
anchors.right: (shareButton.visible) ? shareButton.left
|
||||
: (replyButton.visible) ? replyButton.left
|
||||
: activityItem.right
|
||||
anchors.right: activityActionsLayout.right
|
||||
height: parent.height
|
||||
anchors.margins: 2
|
||||
hoverEnabled: true
|
||||
onClicked: activityModel.triggerActionAtIndex(model.index)
|
||||
onClicked: activityModel.triggerDefaultAction(model.index)
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
@ -575,13 +566,14 @@ Window {
|
||||
Column {
|
||||
id: activityTextColumn
|
||||
anchors.left: activityIcon.right
|
||||
anchors.right: activityActionsLayout.left
|
||||
anchors.leftMargin: 8
|
||||
spacing: 4
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Text {
|
||||
id: activityTextTitle
|
||||
text: (type === "Activity" || type === "Notification") ? subject : message
|
||||
width: Style.activityLabelBaseWidth + ((path === "") ? activityItem.height : 0) + ((link === "") ? activityItem.height : 0) - 8
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Style.topLinePixelSize
|
||||
color: activityTextTitleColor
|
||||
@ -594,7 +586,7 @@ Window {
|
||||
: (type === "Notification") ? message
|
||||
: ""
|
||||
height: (text === "") ? 0 : activityTextTitle.height
|
||||
width: Style.activityLabelBaseWidth + ((path === "") ? activityItem.height : 0) + ((link === "") ? activityItem.height : 0) - 8
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Style.subLinePixelSize
|
||||
}
|
||||
@ -603,7 +595,7 @@ Window {
|
||||
id: activityTextDateTime
|
||||
text: dateTime
|
||||
height: (text === "") ? 0 : activityTextTitle.height
|
||||
width: Style.activityLabelBaseWidth + ((path === "") ? activityItem.height : 0) + ((link === "") ? activityItem.height : 0) - 8
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Style.subLinePixelSize
|
||||
color: "#808080"
|
||||
@ -624,56 +616,175 @@ Window {
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
id: shareButton
|
||||
RowLayout {
|
||||
id: activityActionsLayout
|
||||
anchors.right: activityItem.right
|
||||
|
||||
Layout.preferredWidth: (path === "") ? 0 : parent.height
|
||||
Layout.preferredHeight: parent.height
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignRight
|
||||
flat: true
|
||||
hoverEnabled: true
|
||||
visible: (path === "") ? false : true
|
||||
display: AbstractButton.IconOnly
|
||||
icon.source: "qrc:///client/theme/share.svg"
|
||||
icon.color: "transparent"
|
||||
background: Rectangle {
|
||||
color: parent.hovered ? Style.lightHover : "transparent"
|
||||
|
||||
function actionButtonIcon(actionIndex) {
|
||||
const verb = String(model.links[actionIndex].verb);
|
||||
if (verb === "WEB" && (model.objectType === "chat" || model.objectType === "call")) {
|
||||
return "qrc:///client/theme/reply.svg";
|
||||
} else if (verb === "DELETE") {
|
||||
return "qrc:///client/theme/close.svg";
|
||||
}
|
||||
|
||||
return "qrc:///client/theme/confirm.svg";
|
||||
}
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 1000
|
||||
ToolTip.text: qsTr("Open share dialog")
|
||||
onClicked: Systray.openShareDialog(displayPath,absolutePath)
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("Share %1").arg(displayPath)
|
||||
Accessible.onPressAction: shareButton.clicked()
|
||||
}
|
||||
Repeater {
|
||||
model: activityItem.links.length > activityListView.maxActionButtons ? 1 : activityItem.links.length
|
||||
|
||||
Button {
|
||||
id: replyButton
|
||||
anchors.right: activityItem.right
|
||||
ActivityActionButton {
|
||||
id: activityActionButton
|
||||
|
||||
readonly property int actionIndex: model.index
|
||||
readonly property bool primary: model.index === 0 && String(activityItem.links[actionIndex].verb) !== "DELETE"
|
||||
|
||||
height: activityItem.height
|
||||
|
||||
text: !primary ? "" : activityItem.links[actionIndex].label
|
||||
|
||||
imageSource: !primary ? activityActionsLayout.actionButtonIcon(actionIndex) : ""
|
||||
|
||||
textColor: primary ? Style.ncBlue : "black"
|
||||
textColorHovered: Style.lightHover
|
||||
|
||||
textBorderColor: Style.ncBlue
|
||||
|
||||
textBgColor: "transparent"
|
||||
textBgColorHovered: Style.ncBlue
|
||||
|
||||
tooltipText: activityItem.links[actionIndex].label
|
||||
|
||||
Layout.minimumWidth: primary ? 80 : -1
|
||||
Layout.minimumHeight: parent.height
|
||||
|
||||
Layout.preferredWidth: primary ? -1 : parent.height
|
||||
|
||||
onClicked: activityModel.triggerAction(activityItem.itemIndex, actionIndex)
|
||||
}
|
||||
|
||||
Layout.preferredWidth: (objectType == "chat" || objectType == "call") ? parent.height : 0
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.alignment: Qt.AlignRight
|
||||
flat: true
|
||||
hoverEnabled: true
|
||||
visible: (objectType == "chat" || objectType == "call") ? true : false
|
||||
display: AbstractButton.IconOnly
|
||||
icon.source: "qrc:///client/theme/reply.svg"
|
||||
icon.color: "transparent"
|
||||
background: Rectangle {
|
||||
color: parent.hovered ? Style.lightHover : "transparent"
|
||||
}
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 1000
|
||||
ToolTip.text: qsTr("Open Talk")
|
||||
onClicked: Qt.openUrlExternally(link)
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("Open Talk %1").arg(link)
|
||||
Accessible.onPressAction: replyButton.clicked()
|
||||
Button {
|
||||
id: moreActionsButton
|
||||
|
||||
Layout.preferredWidth: parent.height
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
flat: true
|
||||
hoverEnabled: true
|
||||
visible: activityItem.links.length > activityListView.maxActionButtons
|
||||
display: AbstractButton.IconOnly
|
||||
icon.source: "qrc:///client/theme/more.svg"
|
||||
icon.color: "transparent"
|
||||
background: Rectangle {
|
||||
color: parent.hovered ? Style.lightHover : "transparent"
|
||||
}
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 1000
|
||||
ToolTip.text: qsTr("Show more actions")
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("Show more actions")
|
||||
Accessible.onPressAction: moreActionsButton.clicked()
|
||||
|
||||
onClicked: moreActionsButtonContextMenu.popup();
|
||||
|
||||
Connections {
|
||||
target: trayWindow
|
||||
onActiveChanged: {
|
||||
if (!trayWindow.active) {
|
||||
moreActionsButtonContextMenu.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: activityListView
|
||||
|
||||
onMovementStarted: {
|
||||
moreActionsButtonContextMenu.close();
|
||||
}
|
||||
}
|
||||
|
||||
Container {
|
||||
id: moreActionsButtonContextMenuContainer
|
||||
visible: moreActionsButtonContextMenu.opened
|
||||
|
||||
width: moreActionsButtonContextMenu.width
|
||||
height: moreActionsButtonContextMenu.height
|
||||
anchors.right: moreActionsButton.right
|
||||
anchors.top: moreActionsButton.top
|
||||
|
||||
Menu {
|
||||
id: moreActionsButtonContextMenu
|
||||
anchors.centerIn: parent
|
||||
|
||||
// transform model to contain indexed actions with primary action filtered out
|
||||
function actionListToContextMenuList(actionList) {
|
||||
// early out with non-altered data
|
||||
if (activityItem.links.length <= activityListView.maxActionButtons) {
|
||||
return actionList;
|
||||
}
|
||||
|
||||
// add index to every action and filter 'primary' action out
|
||||
var reducedActionList = actionList.reduce(function(reduced, action, index) {
|
||||
if (!action.primary) {
|
||||
var actionWithIndex = { actionIndex: index, label: action.label };
|
||||
reduced.push(actionWithIndex);
|
||||
}
|
||||
return reduced;
|
||||
}, []);
|
||||
|
||||
|
||||
return reducedActionList;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: moreActionsButtonContextMenuRepeater
|
||||
|
||||
model: moreActionsButtonContextMenu.actionListToContextMenuList(activityItem.links)
|
||||
|
||||
delegate: MenuItem {
|
||||
id: moreActionsButtonContextMenuEntry
|
||||
readonly property int actionIndex: model.modelData.actionIndex
|
||||
readonly property string label: model.modelData.label
|
||||
text: label
|
||||
onTriggered: activityModel.triggerAction(activityItem.itemIndex, actionIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: shareButton
|
||||
|
||||
Layout.preferredWidth: (path === "") ? 0 : parent.height
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.alignment: Qt.AlignRight
|
||||
flat: true
|
||||
hoverEnabled: true
|
||||
visible: (path === "") ? false : true
|
||||
display: AbstractButton.IconOnly
|
||||
icon.source: "qrc:///client/theme/share.svg"
|
||||
icon.color: "transparent"
|
||||
background: Rectangle {
|
||||
color: parent.hovered ? Style.lightHover : "transparent"
|
||||
}
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 1000
|
||||
ToolTip.text: qsTr("Open share dialog")
|
||||
onClicked: Systray.openShareDialog(displayPath,absolutePath)
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("Share %1").arg(displayPath)
|
||||
Accessible.onPressAction: shareButton.clicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user