<file>src/gui/tray/ActivityItemContent.qml</file>
<file>src/gui/tray/TalkReplyTextField.qml</file>
<file>src/gui/tray/CallNotificationDialog.qml</file>
+ <file>src/gui/tray/EditFileLocallyLoadingDialog.qml</file>
<file>src/gui/tray/NCBusyIndicator.qml</file>
<file>src/gui/tray/NCToolTip.qml</file>
</qresource>
return;
}
- // In case the VFS mode is enabled and a file is not yet hydrated, we must call QDesktopServices::openUrl from a separate thread, or, there will be a freeze.
- // To avoid searching for a specific folder and checking if the VFS is enabled - we just always call it from a separate thread.
- QtConcurrent::run([foundFiles] {
- QDesktopServices::openUrl(QUrl::fromLocalFile(foundFiles.first()));
- });
+ const auto localFilePath = foundFiles.first();
+ const auto folderForFile = folderForPath(localFilePath);
+
+ if (!folderForFile) {
+ showError(accountFound, tr("Could not find a folder to sync."), relPath);
+ return;
+ }
+
+ const auto relPathSplit = relPath.split(QLatin1Char('/'));
+ if (relPathSplit.size() > 0) {
+ Systray::instance()->createEditFileLocallyLoadingDialog(relPathSplit.last());
+ } else {
+ showError(accountFound, tr("Could not find a file for local editing. Make sure its path is valid and it is synced locally."), relPath);
+ return;
+ }
+ folderForFile->startSync();
+ _localFileEditingSyncFinishedConnections.insert(localFilePath, QObject::connect(folderForFile, &Folder::syncFinished, this,
+ [this, localFilePath](const OCC::SyncResult &result) {
+ Q_UNUSED(result);
+ const auto foundConnectionIt = _localFileEditingSyncFinishedConnections.find(localFilePath);
+ if (foundConnectionIt != std::end(_localFileEditingSyncFinishedConnections) && foundConnectionIt.value()) {
+ QObject::disconnect(foundConnectionIt.value());
+ _localFileEditingSyncFinishedConnections.erase(foundConnectionIt);
+ }
+ // In case the VFS mode is enabled and a file is not yet hydrated, we must call QDesktopServices::openUrl
+ // from a separate thread, or, there will be a freeze. To avoid searching for a specific folder and checking
+ // if the VFS is enabled - we just always call it from a separate thread.
+ QtConcurrent::run([localFilePath]() {
+ QDesktopServices::openUrl(QUrl::fromLocalFile(localFilePath));
+ Systray::instance()->destroyEditFileLocallyLoadingDialog();
+ });
+ }));
}
void FolderMan::trayOverallStatus(const QList<Folder *> &folders,
bool _appRestartRequired = false;
+ QMap<QString, QMetaObject::Connection> _localFileEditingSyncFinishedConnections;
+
static FolderMan *_instance;
explicit FolderMan(QObject *parent = nullptr);
friend class OCC::Application;
}();
if (iconBaseColors.contains(customColorName)) {
- result = QImage{QString{OCC::Theme::themePrefix} + customColorName + QStringLiteral("/") + fileName};
+ if (requestedSize.width() > 0 && requestedSize.height() > 0) {
+ result = QIcon(QString{OCC::Theme::themePrefix} + customColorName + QStringLiteral("/") + fileName).pixmap(requestedSize).toImage();
+ } else {
+ result = QImage{QString{OCC::Theme::themePrefix} + customColorName + QStringLiteral("/") + fileName};
+ }
if (!result.isNull()) {
return result;
}
}
}
+void Systray::createEditFileLocallyLoadingDialog(const QString &fileName)
+{
+ if (_editFileLocallyLoadingDialog) {
+ return;
+ }
+
+ qCDebug(lcSystray) << "Opening a file local editing dialog...";
+
+ const auto editFileLocallyLoadingDialog = new QQmlComponent(_trayEngine, QStringLiteral("qrc:/qml/src/gui/tray/EditFileLocallyLoadingDialog.qml"));
+
+ if (editFileLocallyLoadingDialog->isError()) {
+ qCWarning(lcSystray) << editFileLocallyLoadingDialog->errorString();
+ return;
+ }
+
+ _editFileLocallyLoadingDialog = editFileLocallyLoadingDialog->createWithInitialProperties(QVariantMap{{QStringLiteral("fileName"), fileName}});
+}
+
+void Systray::destroyEditFileLocallyLoadingDialog()
+{
+ if (!_editFileLocallyLoadingDialog) {
+ return;
+ }
+ qCDebug(lcSystray) << "Closing a file local editing dialog...";
+ _editFileLocallyLoadingDialog->deleteLater();
+ _editFileLocallyLoadingDialog = nullptr;
+}
+
void Systray::slotCurrentUserChanged()
{
if (_trayEngine) {
void showUpdateMessage(const QString &title, const QString &message, const QUrl &webUrl);
void setToolTip(const QString &tip);
void createCallDialog(const Activity &callNotification, const AccountStatePtr accountState);
+ void createEditFileLocallyLoadingDialog(const QString &fileName);
+ void destroyEditFileLocallyLoadingDialog();
Q_REQUIRED_RESULT QString windowTitle() const;
Q_REQUIRED_RESULT bool useNormalWindow() const;
AccessManagerFactory _accessManagerFactory;
QSet<qlonglong> _callsAlreadyNotified;
+
+ QPointer<QObject> _editFileLocallyLoadingDialog;
};
} // namespace OCC
--- /dev/null
+import QtQuick 2.15
+import QtQuick.Window 2.15
+import Style 1.0
+import com.nextcloud.desktopclient 1.0
+import QtQuick.Layouts 1.15
+import QtQuick.Controls 2.15
+
+Window {
+ id: root
+ flags: Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
+
+ color: "transparent"
+
+ width: 320
+ height: contentLayout.implicitHeight
+
+ property string fileName: ""
+
+ readonly property real fontPixelSize: Style.topLinePixelSize * 1.5
+ readonly property real iconWidth: fontPixelSize * 2
+
+ Component.onCompleted: {
+ Systray.forceWindowInit(root);
+ x = Screen.width / 2 - width / 2
+ y = Screen.height / 2 - height / 2
+ root.show();
+ root.raise();
+ root.requestActivate();
+ }
+
+ Rectangle {
+ id: windowBackground
+ color: Style.backgroundColor
+ radius: Style.trayWindowRadius
+ border.color: Style.ncTextColor
+ anchors.fill: parent
+ }
+
+ ColumnLayout {
+ id: contentLayout
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: Style.standardSpacing
+ anchors.rightMargin: Style.standardSpacing
+ spacing: Style.standardSpacing
+ NCBusyIndicator {
+ id: busyIndicator
+ Layout.topMargin: Style.standardSpacing
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredWidth: root.iconWidth
+ Layout.preferredHeight: root.iconWidth
+ imageSourceSizeHeight: root.iconWidth
+ imageSourceSizeWidth: root.iconWidth
+ padding: 0
+ color: Style.ncTextColor
+ running: true
+ }
+ Label {
+ id: labelFileName
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ text: root.fileName
+ elide: Text.ElideRight
+ font.bold: true
+ font.pixelSize: root.fontPixelSize
+ color: Style.ncTextColor
+ horizontalAlignment: Text.AlignHCenter
+ }
+ Label {
+ id: labelMessage
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.bottomMargin: Style.standardSpacing
+ text: qsTr("Opening for local editing")
+ elide: Text.ElideRight
+ font.pixelSize: root.fontPixelSize
+ color: Style.ncTextColor
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+}
property color color: Style.ncSecondaryTextColor
property string imageSource: "image://svgimage-custom-color/change.svg/"
+ property int imageSourceSizeWidth: 64
+ property int imageSourceSizeHeight: 64
+
contentItem: Image {
id: contentImage
verticalAlignment: Image.AlignVCenter
source: colourableImage ? root.imageSource + root.color : root.imageSource
- sourceSize.width: 64
- sourceSize.height: 64
+ sourceSize.width: root.imageSourceSizeWidth
+ sourceSize.height: root.imageSourceSizeHeight
fillMode: Image.PreserveAspectFit
mipmap: true