diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f6b293..0b5b680 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,8 @@ add_executable(cutefish-filemanager model/dirlister.cpp model/positioner.cpp - dialogs/propertiesdialog.cpp dialogs/createfolderdialog.cpp + dialogs/filepropertiesdialog.cpp widgets/rubberband.cpp widgets/itemviewadapter.cpp diff --git a/dialogs/propertiesdialog.cpp b/dialogs/filepropertiesdialog.cpp similarity index 54% rename from dialogs/propertiesdialog.cpp rename to dialogs/filepropertiesdialog.cpp index 1a8b656..131dc65 100644 --- a/dialogs/propertiesdialog.cpp +++ b/dialogs/filepropertiesdialog.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2021 CutefishOS Team. * - * Author: revenmartin + * Author: Reion Wong * * 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 @@ -17,19 +17,15 @@ * along with this program. If not, see . */ -#include "propertiesdialog.h" +#include "filepropertiesdialog.h" #include "../desktopiconprovider.h" -#include -#include - -#include -#include - -#include -#include #include -#include +#include +#include +#include + +#include inline QString concatPaths(const QString &path1, const QString &path2) { @@ -44,109 +40,39 @@ inline QString concatPaths(const QString &path1, const QString &path2) } } -PropertiesDialog::PropertiesDialog(const KFileItem &item, QObject *parent) - : QObject(parent) +FilePropertiesDialog::FilePropertiesDialog(const KFileItem &item, QQuickView *parent) + : QQuickView(parent) { m_items.append(item); init(); } -PropertiesDialog::PropertiesDialog(const KFileItemList &items, QObject *parent) - : QObject(parent) +FilePropertiesDialog::FilePropertiesDialog(const KFileItemList &items, QQuickView *parent) + : QQuickView(parent) + , m_items(items) { - m_items = items; init(); } -PropertiesDialog::PropertiesDialog(const QUrl &url, QObject *parent) - : QObject(parent) +FilePropertiesDialog::FilePropertiesDialog(const QUrl &url, QQuickView *parent) + : QQuickView(parent) + , m_items { KFileItem(url) } { - m_items.append(KFileItem(url)); init(); } -PropertiesDialog::~PropertiesDialog() +FilePropertiesDialog::~FilePropertiesDialog() { - if (m_dirSizeJob) + if (m_dirSizeJob) { m_dirSizeJob->kill(); + m_dirSizeJob->deleteLater(); + m_dirSizeJob = nullptr; + } } -void PropertiesDialog::showDialog(const KFileItem &item) +void FilePropertiesDialog::accept(const QString &text) { - PropertiesDialog *dlg = new PropertiesDialog(item); - QQmlApplicationEngine *engine = new QQmlApplicationEngine; - engine->addImageProvider(QStringLiteral("icontheme"), new DesktopIconProvider()); - engine->rootContext()->setContextProperty("main", dlg); - engine->load(QUrl("qrc:/qml/Dialogs/PropertiesDialog.qml")); -} - -void PropertiesDialog::showDialog(const KFileItemList &items) -{ - PropertiesDialog *dlg = new PropertiesDialog(items); - QQmlApplicationEngine *engine = new QQmlApplicationEngine; - engine->addImageProvider(QStringLiteral("icontheme"), new DesktopIconProvider()); - engine->rootContext()->setContextProperty("main", dlg); - engine->load(QUrl("qrc:/qml/Dialogs/PropertiesDialog.qml")); -} - -bool PropertiesDialog::multiple() const -{ - return m_multiple; -} - -bool PropertiesDialog::isWritable() const -{ - return m_items.first().isWritable(); -} - -QString PropertiesDialog::location() const -{ - return m_location; -} - -QString PropertiesDialog::fileName() const -{ - return m_fileName; -} - -QString PropertiesDialog::iconName() const -{ - return m_iconName; -} - -QString PropertiesDialog::mimeType() const -{ - return m_mimeType; -} - -QString PropertiesDialog::size() const -{ - return m_size; -} - -QString PropertiesDialog::creationTime() const -{ - return m_creationTime; -} - -QString PropertiesDialog::modifiedTime() const -{ - return m_modifiedTime; -} - -QString PropertiesDialog::accessedTime() const -{ - return m_accessedTime; -} - -KFileItemList PropertiesDialog::items() const -{ - return m_items; -} - -void PropertiesDialog::accept(const QString &text) -{ - KFileItemList list = items(); + KFileItemList list = m_items; if (list.size() == 1) { KFileItem item = list.first(); @@ -173,19 +99,98 @@ void PropertiesDialog::accept(const QString &text) } } } + + this->destroy(); + this->deleteLater(); } -void PropertiesDialog::reject() +void FilePropertiesDialog::reject() { + this->destroy(); + this->deleteLater(); } -void PropertiesDialog::init() +bool FilePropertiesDialog::multiple() const { + return m_multiple; +} + +bool FilePropertiesDialog::isWritable() const +{ + return m_isWritable; +} + +QString FilePropertiesDialog::location() const +{ + return m_location; +} + +QString FilePropertiesDialog::fileName() const +{ + return m_fileName; +} + +QString FilePropertiesDialog::iconName() const +{ + return m_iconName; +} + +QString FilePropertiesDialog::mimeType() const +{ + return m_mimeType; +} + +QString FilePropertiesDialog::fileSize() const +{ + return m_size; +} + +QString FilePropertiesDialog::creationTime() const +{ + return m_creationTime; +} + +QString FilePropertiesDialog::modifiedTime() const +{ + return m_modifiedTime; +} + +QString FilePropertiesDialog::accessedTime() const +{ + return m_accessedTime; +} + +bool FilePropertiesDialog::event(QEvent *e) +{ + if (e->type() == QEvent::Close) { + this->deleteLater(); + } + + return QQuickView::event(e); +} + +void FilePropertiesDialog::init() +{ + engine()->rootContext()->setContextProperty("main", this); + engine()->addImageProvider(QStringLiteral("icontheme"), new DesktopIconProvider()); + + setFlag(Qt::Dialog); + setTitle(tr("Properties")); + setResizeMode(QQuickView::SizeViewToRootObject); + setSource(QUrl("qrc:/qml/Dialogs/PropertiesDialog.qml")); + m_multiple = m_items.count() > 1; - m_dirSizeJob = KIO::directorySize(m_items); - connect(m_dirSizeJob, &KIO::DirectorySizeJob::result, this, &PropertiesDialog::slotDirSizeFinished); + // Update + m_dirSizeUpdateTimer = new QTimer(this); + connect(m_dirSizeUpdateTimer, &QTimer::timeout, this, [=] { + m_size = KIO::convertSize(m_dirSizeJob->totalSize()); + emit fileSizeChanged(); + }); + m_dirSizeUpdateTimer->start(500); + + connect(m_dirSizeJob, &KIO::DirectorySizeJob::result, this, &FilePropertiesDialog::slotDirSizeFinished); if (!m_multiple) { KFileItem item = m_items.first(); @@ -205,20 +210,39 @@ void PropertiesDialog::init() m_creationTime = item.time(KFileItem::CreationTime).toString(); m_modifiedTime = item.time(KFileItem::ModificationTime).toString(); m_accessedTime = item.time(KFileItem::AccessTime).toString(); + + m_isWritable = m_items.first().isWritable(); + + emit fileNameChanged(); + emit iconNameChanged(); + emit mimeTypeChanged(); + emit fileSizeChanged(); + emit locationChanged(); + emit creationTimeChanged(); + emit modifiedTimeChanged(); + emit accessedTimeChanged(); } else { + m_isWritable = false; m_fileName = tr("%1 files").arg(m_items.count()); m_location = QFileInfo(m_items.first().localPath()).dir().path(); + + emit fileNameChanged(); + emit locationChanged(); } + + emit isWritableChanged(); } -void PropertiesDialog::slotDirSizeFinished(KJob *job) +void FilePropertiesDialog::slotDirSizeFinished(KJob *job) { if (job->error()) return; + m_dirSizeUpdateTimer->stop(); m_size = KIO::convertSize(m_dirSizeJob->totalSize()); m_dirSizeJob = 0; - emit sizeChanged(); + emit fileSizeChanged(); } + diff --git a/dialogs/propertiesdialog.h b/dialogs/filepropertiesdialog.h similarity index 56% rename from dialogs/propertiesdialog.h rename to dialogs/filepropertiesdialog.h index 9cdc65c..aff09b1 100644 --- a/dialogs/propertiesdialog.h +++ b/dialogs/filepropertiesdialog.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2021 CutefishOS Team. * - * Author: revenmartin + * Author: Reion Wong * * 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 @@ -17,37 +17,38 @@ * along with this program. If not, see . */ -#ifndef PROPERTIESDIALOG_H -#define PROPERTIESDIALOG_H +#ifndef FILEPROPERTIESDIALOG_H +#define FILEPROPERTIESDIALOG_H -#include +#include +#include #include #include #include -class PropertiesDialog : public QObject +class FilePropertiesDialog : public QQuickView { Q_OBJECT - Q_PROPERTY(QString location READ location CONSTANT) + Q_PROPERTY(QString location READ location NOTIFY locationChanged) Q_PROPERTY(QString fileName READ fileName NOTIFY fileNameChanged) Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged) - Q_PROPERTY(QString mimeType READ mimeType CONSTANT) - Q_PROPERTY(QString size READ size NOTIFY sizeChanged) - Q_PROPERTY(QString creationTime READ creationTime CONSTANT) - Q_PROPERTY(QString modifiedTime READ modifiedTime CONSTANT) - Q_PROPERTY(QString accessedTime READ accessedTime CONSTANT) + Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged) + Q_PROPERTY(QString fileSize READ fileSize NOTIFY fileSizeChanged) + Q_PROPERTY(QString creationTime READ creationTime NOTIFY creationTimeChanged) + Q_PROPERTY(QString modifiedTime READ modifiedTime NOTIFY modifiedTimeChanged) + Q_PROPERTY(QString accessedTime READ accessedTime NOTIFY accessedTimeChanged) Q_PROPERTY(bool multiple READ multiple CONSTANT) - Q_PROPERTY(bool isWritable READ isWritable CONSTANT) + Q_PROPERTY(bool isWritable READ isWritable NOTIFY isWritableChanged) public: - explicit PropertiesDialog(const KFileItem &item, QObject *parent = nullptr); - explicit PropertiesDialog(const KFileItemList &items, QObject *parent = nullptr); - explicit PropertiesDialog(const QUrl &url, QObject *parent = nullptr); - ~PropertiesDialog(); + explicit FilePropertiesDialog(const KFileItem &item, QQuickView *parent = nullptr); + explicit FilePropertiesDialog(const KFileItemList &items, QQuickView *parent = nullptr); + explicit FilePropertiesDialog(const QUrl &url, QQuickView *parent = nullptr); + ~FilePropertiesDialog(); - static void showDialog(const KFileItem &item); - static void showDialog(const KFileItemList &items); + Q_INVOKABLE void accept(const QString &text); + Q_INVOKABLE void reject(); bool multiple() const; bool isWritable() const; @@ -56,21 +57,26 @@ public: QString fileName() const; QString iconName() const; QString mimeType() const; - QString size() const; + QString fileSize() const; QString creationTime() const; QString modifiedTime() const; QString accessedTime() const; - KFileItemList items() const; - - Q_INVOKABLE void accept(const QString &text); - Q_INVOKABLE void reject(); - signals: + void locationChanged(); void fileNameChanged(); void iconNameChanged(); - void sizeChanged(); + void mimeTypeChanged(); + void fileSizeChanged(); + + void creationTimeChanged(); + void modifiedTimeChanged(); + void accessedTimeChanged(); + void isWritableChanged(); + +protected: + bool event(QEvent *e) override; private: void init(); @@ -89,9 +95,11 @@ private: QString m_modifiedTime; QString m_accessedTime; + QTimer *m_dirSizeUpdateTimer = nullptr; KIO::DirectorySizeJob *m_dirSizeJob; bool m_multiple; + bool m_isWritable; }; -#endif // PROPERTIESDIALOG_H +#endif // FILEPROPERTIESDIALOG_H diff --git a/model/foldermodel.cpp b/model/foldermodel.cpp index 94486b2..48f2be4 100644 --- a/model/foldermodel.cpp +++ b/model/foldermodel.cpp @@ -25,7 +25,7 @@ #include "foldermodel.h" #include "dirlister.h" -#include "../dialogs/propertiesdialog.h" +#include "../dialogs/filepropertiesdialog.h" #include "../dialogs/createfolderdialog.h" #include "../helper/datehelper.h" @@ -936,7 +936,8 @@ void FolderModel::openPropertiesDialog() const QModelIndexList indexes = m_selectionModel->selectedIndexes(); if (indexes.isEmpty()) { - PropertiesDialog::showDialog(QUrl::fromLocalFile(url())); + FilePropertiesDialog *dlg = new FilePropertiesDialog(QUrl::fromLocalFile(url())); + dlg->show(); return; } @@ -949,7 +950,8 @@ void FolderModel::openPropertiesDialog() } } - PropertiesDialog::showDialog(items); + FilePropertiesDialog *dlg = new FilePropertiesDialog(items); + dlg->show(); } void FolderModel::openInTerminal() diff --git a/qml/Dialogs/PropertiesDialog.qml b/qml/Dialogs/PropertiesDialog.qml index 0291675..cd80ded 100644 --- a/qml/Dialogs/PropertiesDialog.qml +++ b/qml/Dialogs/PropertiesDialog.qml @@ -23,12 +23,15 @@ import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import FishUI 1.0 as FishUI -Window { +Item { id: control - title: qsTr("Properties") - flags: Qt.Dialog - visible: true + width: _mainLayout.implicitWidth + FishUI.Units.largeSpacing * 4 + height: _mainLayout.implicitHeight + FishUI.Units.largeSpacing * 2 + + focus: true + Keys.enabled: true + Keys.onEscapePressed: main.reject() Rectangle { anchors.fill: parent @@ -39,169 +42,151 @@ Window { if (visible) updateWindowSize() } + function close() { + main.close() + } + function updateWindowSize() { if (visible) { - control.width = _mainLayout.implicitWidth + _mainLayout.anchors.leftMargin + _mainLayout.anchors.rightMargin - control.height = _mainLayout.implicitHeight + _mainLayout.anchors.topMargin + _mainLayout.anchors.bottomMargin - control.minimumWidth = control.width - control.minimumHeight = control.height - control.maximumWidth = control.width - control.maximumHeight = control.height - if (_textField.enabled) _textField.forceActiveFocus() } } - Item { - id: _contentItem + ColumnLayout { + id: _mainLayout anchors.fill: parent - focus: true + anchors.leftMargin: FishUI.Units.largeSpacing * 2 + anchors.rightMargin: FishUI.Units.largeSpacing * 2 + anchors.topMargin: FishUI.Units.smallSpacing + anchors.bottomMargin: FishUI.Units.largeSpacing * 1.5 + spacing: FishUI.Units.largeSpacing - Keys.enabled: true - Keys.onEscapePressed: control.close() + RowLayout { + spacing: FishUI.Units.largeSpacing * 2 - ColumnLayout { - id: _mainLayout - anchors.fill: parent - anchors.leftMargin: FishUI.Units.largeSpacing * 2 - anchors.rightMargin: FishUI.Units.largeSpacing * 2 - anchors.topMargin: FishUI.Units.largeSpacing - anchors.bottomMargin: FishUI.Units.largeSpacing * 1.5 + Image { + width: 64 + height: width + sourceSize: Qt.size(width, height) + source: "image://icontheme/" + main.iconName + } + + TextField { + id: _textField + text: main.fileName + focus: true + Layout.fillWidth: true + Keys.onEscapePressed: main.reject() + enabled: main.isWritable + } + } + + GridLayout { + columns: 2 + columnSpacing: FishUI.Units.largeSpacing + rowSpacing: FishUI.Units.largeSpacing + Layout.alignment: Qt.AlignTop + + onHeightChanged: updateWindowSize() + onImplicitHeightChanged: updateWindowSize() + + Label { + text: qsTr("Type:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + visible: mimeType.visible + } + + Label { + id: mimeType + text: main.mimeType + visible: text + } + + Label { + text: qsTr("Location:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + } + + Label { + id: location + text: main.location + } + + Label { + text: qsTr("Size:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + } + + Label { + id: size + text: main.fileSize ? main.fileSize : qsTr("Calculating...") + } + + Label { + text: qsTr("Created:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + visible: creationTime.visible + } + + Label { + id: creationTime + text: main.creationTime + visible: text + } + + Label { + text: qsTr("Modified:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + visible: modifiedTime.visible + } + + Label { + id: modifiedTime + text: main.modifiedTime + visible: text + } + + Label { + text: qsTr("Accessed:") + Layout.alignment: Qt.AlignRight + color: FishUI.Theme.disabledTextColor + visible: accessTime.visible + } + + Label { + id: accessTime + text: main.accessedTime + visible: text + } + } + + Item { + height: FishUI.Units.smallSpacing + } + + RowLayout { + Layout.alignment: Qt.AlignRight spacing: FishUI.Units.largeSpacing - RowLayout { - spacing: FishUI.Units.largeSpacing * 2 - - Image { - width: 64 - height: width - sourceSize: Qt.size(width, height) - source: "image://icontheme/" + main.iconName - } - - TextField { - id: _textField - text: main.fileName - focus: true - Layout.fillWidth: true - Keys.onEscapePressed: control.close() - enabled: !main.multiple && main.isWritable - } + Button { + text: qsTr("Cancel") + Layout.fillWidth: true + onClicked: main.reject() } - GridLayout { - columns: 2 - columnSpacing: FishUI.Units.largeSpacing - rowSpacing: FishUI.Units.largeSpacing - Layout.alignment: Qt.AlignTop - - onHeightChanged: updateWindowSize() - onImplicitHeightChanged: updateWindowSize() - - Label { - text: qsTr("Type:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - visible: mimeType.visible - } - - Label { - id: mimeType - text: main.mimeType - visible: text - } - - Label { - text: qsTr("Location:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - } - - Label { - id: location - text: main.location - } - - Label { - text: qsTr("Size:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - // visible: size.visible - } - - Label { - id: size - text: main.size ? main.size : qsTr("Calculating...") - // visible: text - } - - Label { - text: qsTr("Created:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - visible: creationTime.visible - } - - Label { - id: creationTime - text: main.creationTime - visible: text - } - - Label { - text: qsTr("Modified:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - visible: modifiedTime.visible - } - - Label { - id: modifiedTime - text: main.modifiedTime - visible: text - } - - Label { - text: qsTr("Accessed:") - Layout.alignment: Qt.AlignRight - color: FishUI.Theme.disabledTextColor - visible: accessTime.visible - } - - Label { - id: accessTime - text: main.accessedTime - visible: text - } - } - - Item { - height: FishUI.Units.largeSpacing - } - - RowLayout { - Layout.alignment: Qt.AlignRight - spacing: FishUI.Units.largeSpacing - - Button { - text: qsTr("Cancel") - Layout.fillWidth: true - onClicked: { - control.close() - main.reject() - } - } - - Button { - text: qsTr("OK") - Layout.fillWidth: true - onClicked: { - main.accept(_textField.text) - control.close() - } - flat: true + Button { + text: qsTr("OK") + Layout.fillWidth: true + onClicked: { + main.accept(_textField.text) } + flat: true } } }