<file>src/gui/tray/ActivityActionButton.qml</file>
<file>src/gui/tray/ActivityItem.qml</file>
<file>src/gui/tray/AutoSizingMenu.qml</file>
+ <file>src/gui/tray/ActivityList.qml</file>
+ <file>src/gui/tray/FileActivityDialog.qml</file>
</qresource>
</RCC>
UserStatusSelectorDialog.qml
tray/ActivityActionButton.qml
tray/ActivityItem.qml
+ tray/ActivityList.qml
tray/Window.qml
tray/UserLine.qml
wizard/flow2authwidget.ui
remotewipe.cpp
userstatusselectormodel.cpp
emojimodel.cpp
+ fileactivitylistmodel.cpp
tray/ActivityData.cpp
tray/ActivityListModel.cpp
tray/UserModel.cpp
connect(FolderMan::instance()->socketApi(), &SocketApi::shareCommandReceived,
_gui.data(), &ownCloudGui::slotShowShareDialog);
+ connect(FolderMan::instance()->socketApi(), &SocketApi::fileActivityCommandReceived,
+ Systray::instance(), &Systray::showFileActivityDialog);
+
// startup procedure.
connect(&_checkConnectionTimer, &QTimer::timeout, this, &Application::slotCheckConnection);
_checkConnectionTimer.setInterval(ConnectionValidator::DefaultCallingIntervalMsec); // check for connection every 32 seconds.
--- /dev/null
+/*
+ * Copyright (C) by Felix Weilbach <felix.weilbach@nextcloud.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 2 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.
+ */
+
+#include "fileactivitylistmodel.h"
+#include "folderman.h"
+#include "tray/ActivityListModel.h"
+
+namespace OCC {
+
+Q_LOGGING_CATEGORY(lcFileActivityListModel, "nextcloud.gui.fileactivitylistmodel", QtInfoMsg)
+
+FileActivityListModel::FileActivityListModel(QObject *parent)
+ : ActivityListModel(nullptr, parent)
+{
+ setDisplayActions(false);
+}
+
+void FileActivityListModel::load(AccountState *accountState, const QString &localPath)
+{
+ Q_ASSERT(accountState);
+ if (!accountState || currentlyFetching()) {
+ return;
+ }
+ setAccountState(accountState);
+
+ const auto folder = FolderMan::instance()->folderForPath(localPath);
+ if (!folder) {
+ return;
+ }
+
+ const auto file = folder->fileFromLocalPath(localPath);
+ SyncJournalFileRecord fileRecord;
+ if (!folder->journalDb()->getFileRecord(file, &fileRecord) || !fileRecord.isValid()) {
+ return;
+ }
+
+ _fileId = fileRecord._fileId;
+ slotRefreshActivity();
+}
+
+void FileActivityListModel::startFetchJob()
+{
+ if (!accountState()->isConnected()) {
+ return;
+ }
+ setCurrentlyFetching(true);
+
+ const QString url(QStringLiteral("ocs/v2.php/apps/activity/api/v2/activity/filter"));
+ auto job = new JsonApiJob(accountState()->account(), url, this);
+ QObject::connect(job, &JsonApiJob::jsonReceived,
+ this, &FileActivityListModel::activitiesReceived);
+
+ QUrlQuery params;
+ params.addQueryItem(QStringLiteral("sort"), QStringLiteral("asc"));
+ params.addQueryItem(QStringLiteral("object_type"), "files");
+ params.addQueryItem(QStringLiteral("object_id"), _fileId);
+ job->addQueryParams(params);
+ setDoneFetching(true);
+ setHideOldActivities(true);
+ job->start();
+}
+}
--- /dev/null
+/*
+ * Copyright (C) by Felix Weilbach <felix.weilbach@nextcloud.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 2 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.
+ */
+
+#pragma once
+
+#include "accountstate.h"
+#include "tray/ActivityListModel.h"
+
+namespace OCC {
+
+class FileActivityListModel : public ActivityListModel
+{
+ Q_OBJECT
+
+public:
+ explicit FileActivityListModel(QObject *parent = nullptr);
+
+public slots:
+ void load(AccountState *accountState, const QString &fileId);
+
+protected:
+ void startFetchJob() override;
+
+private:
+ QString _fileId;
+};
+}
msgBox->open();
}
+QString Folder::fileFromLocalPath(const QString &localPath) const
+{
+ return localPath.mid(cleanPath().length() + 1);
+}
+
void FolderDefinition::save(QSettings &settings, const FolderDefinition &folder)
{
settings.setValue(QLatin1String("localPath"), folder.localPath);
return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user());
}
+
} // namespace OCC
/** Whether this folder should show selective sync ui */
bool supportsSelectiveSync() const;
+ QString fileFromLocalPath(const QString &localPath) const;
+
signals:
void syncStateChange();
void syncStarted();
#endif
#include "application.h"
+#include "fileactivitylistmodel.h"
#include "theme.h"
#include "common/utility.h"
#include "cocoainitializer.h"
Q_INIT_RESOURCE(theme);
qmlRegisterType<EmojiModel>("com.nextcloud.desktopclient", 1, 0, "EmojiModel");
+ qmlRegisterType<UserStatusSelectorModel>("com.nextcloud.desktopclient", 1, 0, "UserStatusSelectorModel");
+ qmlRegisterType<OCC::ActivityListModel>("com.nextcloud.desktopclient", 1, 0, "ActivityListModel");
+ qmlRegisterType<OCC::FileActivityListModel>("com.nextcloud.desktopclient", 1, 0, "FileActivityListModel");
+
+ qmlRegisterUncreatableType<OCC::UserStatus>("com.nextcloud.desktopclient", 1, 0, "UserStatus", "Access to Status enum");
+
qRegisterMetaTypeStreamOperators<Emoji>();
- qmlRegisterType<UserStatusSelectorModel>("com.nextcloud.desktopclient", 1, 0,
- "UserStatusSelectorModel");
- qmlRegisterUncreatableType<OCC::UserStatus>("com.nextcloud.desktopclient", 1, 0, "UserStatus",
- "Access to Status enum");
qRegisterMetaType<OCC::UserStatus>("UserStatus");
}
}
+void SocketApi::processFileActivityRequest(const QString &localFile)
+{
+ const auto fileData = FileData::get(localFile);
+ emit fileActivityCommandReceived(fileData.serverRelativePath, fileData.localPath);
+}
+
void SocketApi::processShareRequest(const QString &localFile, SocketListener *listener, ShareDialogStartPage startPage)
{
auto theme = Theme::instance();
processShareRequest(localFile, listener, ShareDialogStartPage::UsersAndGroups);
}
+void SocketApi::command_ACTIVITY(const QString &localFile, SocketListener *listener)
+{
+ Q_UNUSED(listener);
+
+ processFileActivityRequest(localFile);
+}
+
void SocketApi::command_MANAGE_PUBLIC_LINKS(const QString &localFile, SocketListener *listener)
{
processShareRequest(localFile, listener, ShareDialogStartPage::PublicLinks);
void SocketApi::command_GET_STRINGS(const QString &argument, SocketListener *listener)
{
- static std::array<std::pair<const char *, QString>, 5> strings { {
+ static std::array<std::pair<const char *, QString>, 6> strings { {
{ "SHARE_MENU_TITLE", tr("Share options") },
+ { "FILE_ACTIVITY_MENU_TITLE", tr("Activity") },
{ "CONTEXT_MENU_TITLE", Theme::instance()->appNameGUI() },
{ "COPY_PRIVATE_LINK_MENU_TITLE", tr("Copy private link to clipboard") },
{ "EMAIL_PRIVATE_LINK_MENU_TITLE", tr("Send private link by email …") },
- { "CONTEXT_MENU_ICON", APPLICATION_ICON_NAME},
+ { "CONTEXT_MENU_ICON", APPLICATION_ICON_NAME },
} };
listener->sendMessage(QString("GET_STRINGS:BEGIN"));
for (const auto& key_value : strings) {
const auto isE2eEncryptedPath = fileData.journalRecord()._isE2eEncrypted || !fileData.journalRecord()._e2eMangledName.isEmpty();
auto flagString = isOnTheServer && !isE2eEncryptedPath ? QLatin1String("::") : QLatin1String(":d:");
+ const QFileInfo fileInfo(fileData.localPath);
+ if (!fileInfo.isDir()) {
+ listener->sendMessage(QLatin1String("MENU_ITEM:ACTIVITY") + flagString + tr("Activity"));
+ }
+
DirectEditor* editor = getDirectEditorForLocalFile(fileData.localPath);
if (editor) {
//listener->sendMessage(QLatin1String("MENU_ITEM:EDIT") + flagString + tr("Edit via ") + editor->name());
bool isConflict = Utility::isConflictFile(fileData.folderRelativePath);
if (isConflict || !isOnTheServer) {
// Check whether this new file is in a read-only directory
- QFileInfo fileInfo(fileData.localPath);
const auto parentDir = fileData.parentFolder();
const auto parentRecord = parentDir.journalRecord();
const bool canAddToDir =
signals:
void shareCommandReceived(const QString &sharePath, const QString &localPath, ShareDialogStartPage startPage);
+ void fileActivityCommandReceived(const QString &sharePath, const QString &localPath);
private slots:
void slotNewConnection();
// opens share dialog, sends reply
void processShareRequest(const QString &localFile, SocketListener *listener, ShareDialogStartPage startPage);
+ void processFileActivityRequest(const QString &localFile);
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString &argument, SocketListener *listener);
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString &argument, SocketListener *listener);
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString &argument, SocketListener *listener);
// The context menu actions
+ Q_INVOKABLE void command_ACTIVITY(const QString &localFile, SocketListener *listener);
Q_INVOKABLE void command_SHARE(const QString &localFile, SocketListener *listener);
Q_INVOKABLE void command_MANAGE_PUBLIC_LINKS(const QString &localFile, SocketListener *listener);
Q_INVOKABLE void command_COPY_PUBLIC_LINK(const QString &localFile, SocketListener *listener);
void hideWindow();
void showWindow();
void openShareDialog(const QString &sharePath, const QString &localPath);
+ void showFileActivityDialog(const QString &sharePath, const QString &localPath);
public slots:
void slotNewUserSelected();
MouseArea {
id: activityMouseArea
+
+ readonly property int maxActionButtons: 2
+ property Flickable flickable
+
+ signal fileActivityButtonClicked(string absolutePath)
+
enabled: (path !== "" || link !== "")
hoverEnabled: true
-
+
Rectangle {
anchors.fill: parent
anchors.margins: 2
}
Repeater {
- model: activityItem.links.length > activityListView.maxActionButtons ? 1 : activityItem.links.length
+ model: activityItem.links.length > maxActionButtons ? 1 : activityItem.links.length
ActivityActionButton {
id: activityActionButton
}
}
+
+ Button {
+ id: shareButton
+
+ Layout.preferredWidth: parent.height
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignRight
+ flat: true
+ hoverEnabled: true
+ visible: displayActions && (path !== "")
+ 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: Qt.styleHints.mousePressAndHoldInterval
+ 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()
+ }
Button {
id: moreActionsButton
flat: true
hoverEnabled: true
- visible: activityItem.links.length > activityListView.maxActionButtons
+ visible: displayActions && ((path !== "") || (activityItem.links.length > maxActionButtons))
display: AbstractButton.IconOnly
icon.source: "qrc:///client/theme/more.svg"
icon.color: "transparent"
color: parent.hovered ? Style.lightHover : "transparent"
}
ToolTip.visible: hovered
- ToolTip.delay: 1000
+ ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
ToolTip.text: qsTr("Show more actions")
Accessible.role: Accessible.Button
onClicked: moreActionsButtonContextMenu.popup();
Connections {
- target: trayWindow
- function onActiveChanged() {
- if (!trayWindow.active) {
- moreActionsButtonContextMenu.close();
- }
- }
- }
-
- Connections {
- target: activityListView
+ target: flickable
function onMovementStarted() {
moreActionsButtonContextMenu.close();
// 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) {
+ if (activityItem.links.length <= maxActionButtons) {
return actionList;
}
return reducedActionList;
}
+
+ MenuItem {
+ text: qsTr("View activity")
+ onClicked: fileActivityButtonClicked(absolutePath)
+ }
Repeater {
id: moreActionsButtonContextMenuRepeater
}
}
}
-
- 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()
- }
}
}
}
--- /dev/null
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+
+import Style 1.0
+
+import com.nextcloud.desktopclient 1.0 as NC
+
+ScrollView {
+ property alias model: activityList.model
+
+ signal showFileActivity(string displayPath, string absolutePath)
+ signal activityItemClicked(int index)
+
+ contentWidth: availableWidth
+
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
+
+ ListView {
+ id: activityList
+
+ keyNavigationEnabled: true
+
+ Accessible.role: Accessible.List
+ Accessible.name: qsTr("Activity list")
+
+ clip: true
+
+ delegate: ActivityItem {
+ width: activityList.contentWidth
+ height: Style.trayWindowHeaderHeight
+ flickable: activityList
+ onClicked: activityItemClicked(model.index)
+ onFileActivityButtonClicked: showFileActivity(displayPath, absolutePath)
+ }
+ }
+}
#include <QWidget>
#include <QJsonObject>
#include <QJsonDocument>
+#include <qloggingcategory.h>
#include "account.h"
#include "accountstate.h"
Q_LOGGING_CATEGORY(lcActivity, "nextcloud.gui.activity", QtInfoMsg)
-ActivityListModel::ActivityListModel(AccountState *accountState, QObject *parent)
+ActivityListModel::ActivityListModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+ActivityListModel::ActivityListModel(AccountState *accountState,
+ QObject *parent)
: QAbstractListModel(parent)
, _accountState(accountState)
{
roles[ActionTextColorRole] = "activityTextTitleColor";
roles[ObjectTypeRole] = "objectType";
roles[PointInTimeRole] = "dateTime";
+ roles[DisplayActions] = "displayActions";
return roles;
}
+void ActivityListModel::setAccountState(AccountState *state)
+{
+ _accountState = state;
+}
+
+void ActivityListModel::setCurrentlyFetching(bool value)
+{
+ _currentlyFetching = value;
+}
+
+bool ActivityListModel::currentlyFetching() const
+{
+ return _currentlyFetching;
+}
+
+void ActivityListModel::setDoneFetching(bool value)
+{
+ _doneFetching = value;
+}
+
+void ActivityListModel::setHideOldActivities(bool value)
+{
+ _hideOldActivities = value;
+}
+
+void ActivityListModel::setDisplayActions(bool value)
+{
+ _displayActions = value;
+}
+
QVariant ActivityListModel::data(const QModelIndex &index, int role) const
{
Activity a;
return a._id == -1 ? "" : Utility::timeAgoInWords(a._dateTime.toLocalTime());
case AccountConnectedRole:
return (ast && ast->isConnected());
+ case DisplayActions:
+ return _displayActions;
default:
return QVariant();
}
}
auto *job = new JsonApiJob(_accountState->account(), QLatin1String("ocs/v2.php/apps/activity/api/v2/activity"), this);
QObject::connect(job, &JsonApiJob::jsonReceived,
- this, &ActivityListModel::slotActivitiesReceived);
+ this, &ActivityListModel::activitiesReceived);
QUrlQuery params;
params.addQueryItem(QLatin1String("since"), QString::number(_currentItem));
job->start();
}
-void ActivityListModel::slotActivitiesReceived(const QJsonDocument &json, int statusCode)
+void ActivityListModel::activitiesReceived(const QJsonDocument &json, int statusCode)
{
auto activities = json.object().value("ocs").toObject().value("data").toArray();
_currentItem = list.last()._id;
_totalActivitiesFetched++;
- if(_totalActivitiesFetched == _maxActivities ||
- a._dateTime < oldestDate) {
-
+ if (_totalActivitiesFetched == _maxActivities
+ || (_hideOldActivities && a._dateTime < oldestDate)) {
_showMoreActivitiesAvailableEntry = true;
_doneFetching = true;
break;
emit sendNotificationRequest(activity._accName, action._link, action._verb, activityIndex);
}
+AccountState *ActivityListModel::accountState() const
+{
+ return _accountState;
+}
+
void ActivityListModel::combineActivityLists()
{
ActivityList resultList;
class ActivityListModel : public QAbstractListModel
{
Q_OBJECT
+
+ Q_PROPERTY(AccountState *accountState READ accountState CONSTANT)
public:
enum DataRole {
- ActionIconRole = Qt::UserRole + 1,
- UserIconRole,
- AccountRole,
- ObjectTypeRole,
- ActionsLinksRole,
- ActionTextRole,
- ActionTextColorRole,
- ActionRole,
- MessageRole,
- DisplayPathRole,
- PathRole,
- AbsolutePathRole,
- LinkRole,
- PointInTimeRole,
- AccountConnectedRole,
- SyncFileStatusRole};
-
- explicit ActivityListModel(AccountState *accountState, QObject* parent = nullptr);
+ ActionIconRole = Qt::UserRole + 1,
+ UserIconRole,
+ AccountRole,
+ ObjectTypeRole,
+ ActionsLinksRole,
+ ActionTextRole,
+ ActionTextColorRole,
+ ActionRole,
+ MessageRole,
+ DisplayPathRole,
+ PathRole,
+ AbsolutePathRole,
+ LinkRole,
+ PointInTimeRole,
+ AccountConnectedRole,
+ SyncFileStatusRole,
+ DisplayActions,
+ };
+ Q_ENUM(DataRole)
+
+ explicit ActivityListModel(QObject *parent = nullptr);
+
+ explicit ActivityListModel(AccountState *accountState,
+ QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
Q_INVOKABLE void triggerDefaultAction(int activityIndex);
Q_INVOKABLE void triggerAction(int activityIndex, int actionIndex);
+ AccountState *accountState() const;
+
public slots:
void slotRefreshActivity();
void slotRemoveAccount();
-private slots:
- void slotActivitiesReceived(const QJsonDocument &json, int statusCode);
-
signals:
void activityJobStatusCode(int statusCode);
void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row);
protected:
+ void activitiesReceived(const QJsonDocument &json, int statusCode);
QHash<int, QByteArray> roleNames() const override;
+ void setAccountState(AccountState *state);
+ void setCurrentlyFetching(bool value);
+ bool currentlyFetching() const;
+ void setDoneFetching(bool value);
+ void setHideOldActivities(bool value);
+ void setDisplayActions(bool value);
+
+ virtual void startFetchJob();
+
private:
- void startFetchJob();
void combineActivityLists();
bool canFetchActivities() const;
Activity _notificationIgnoredFiles;
ActivityList _notificationErrorsLists;
ActivityList _finalList;
- AccountState *_accountState;
- bool _currentlyFetching = false;
- bool _doneFetching = false;
int _currentItem = 0;
+ bool _displayActions = true;
+
int _totalActivitiesFetched = 0;
int _maxActivities = 100;
int _maxActivitiesDays = 30;
QPointer<ConflictDialog> _currentConflictDialog;
QPointer<InvalidFilenameDialog> _currentInvalidFilenameDialog;
+
+ AccountState *_accountState = nullptr;
+ bool _currentlyFetching = false;
+ bool _doneFetching = false;
+ bool _hideOldActivities = true;
};
}
--- /dev/null
+import QtQuick.Window 2.15
+
+import com.nextcloud.desktopclient 1.0 as NC
+
+Window {
+ id: dialog
+
+ property alias model: activityModel
+
+ NC.FileActivityListModel {
+ id: activityModel
+ }
+
+ width: 500
+ height: 500
+
+ ActivityList {
+ anchors.fill: parent
+ model: dialog.model
+ }
+}
flags: Systray.useNormalWindow ? Qt.Window : Qt.Dialog | Qt.FramelessWindowHint\r
\r
\r
+ property var fileActivityDialogAbsolutePath: ""\r
readonly property int maxMenuHeight: Style.trayWindowHeight - Style.trayWindowHeaderHeight - 2 * Style.trayWindowBorderWidth\r
\r
+ function openFileActivityDialog(displayPath, absolutePath) {\r
+ fileActivityDialogLoader.displayPath = displayPath\r
+ fileActivityDialogLoader.absolutePath = absolutePath\r
+ fileActivityDialogLoader.refresh()\r
+ }\r
+\r
Component.onCompleted: Systray.forceWindowInit(trayWindow)\r
\r
// Close tray window when focus is lost (e.g. click somewhere else on the screen)\r
trayWindow.hide();\r
Systray.setClosed();\r
}\r
+\r
+ function onShowFileActivityDialog(displayPath, absolutePath) {\r
+ openFileActivityDialog(displayPath, absolutePath)\r
+ }\r
}\r
\r
OpacityMask {\r
}\r
} // Rectangle trayWindowHeaderBackground\r
\r
- ListView {\r
- id: activityListView\r
- anchors.top: trayWindowHeaderBackground.bottom\r
- anchors.left: trayWindowBackground.left\r
- anchors.right: trayWindowBackground.right\r
- anchors.bottom: trayWindowBackground.bottom\r
- clip: true\r
- ScrollBar.vertical: ScrollBar {\r
- id: listViewScrollbar\r
+ ActivityList {\r
+ anchors.top: trayWindowHeaderBackground.bottom\r
+ anchors.left: trayWindowBackground.left\r
+ anchors.right: trayWindowBackground.right\r
+ anchors.bottom: trayWindowBackground.bottom\r
+ \r
+ model: activityModel\r
+ onShowFileActivity: {\r
+ openFileActivityDialog(displayPath, absolutePath)\r
+ }\r
+ onActivityItemClicked: {\r
+ model.triggerDefaultAction(index)\r
+ }\r
+ }\r
+\r
+ Loader {\r
+ id: fileActivityDialogLoader\r
+\r
+ property string displayPath: ""\r
+ property string absolutePath: ""\r
+\r
+ function refresh() {\r
+ active = true\r
+ item.model.load(activityModel.accountState, absolutePath)\r
+ item.show() \r
}\r
\r
- readonly property int maxActionButtons: 2\r
-\r
- keyNavigationEnabled: true\r
-\r
- Accessible.role: Accessible.List\r
- Accessible.name: qsTr("Activity list")\r
-\r
- model: activityModel\r
-\r
- delegate: ActivityItem { \r
- width: activityListView.width\r
- height: Style.trayWindowHeaderHeight\r
- onClicked: activityModel.triggerDefaultAction(model.index)\r
+ active: false\r
+ sourceComponent: FileActivityDialog {\r
+ title: qsTr("%1 - File activity").arg(fileActivityDialogLoader.displayPath)\r
+ onClosing: fileActivityDialogLoader.active = false\r
}\r
+\r
+ onLoaded: refresh()\r
}\r
- } // Rectangle trayWindowBackground\r
+ } // Rectangle trayWindowBackground\r
}\r