Reconstructed the file properties dialog

This commit is contained in:
reionwong 2021-07-29 16:17:03 +08:00
parent db01805563
commit 8f9b973b2d
5 changed files with 303 additions and 284 deletions

View file

@ -26,8 +26,8 @@ add_executable(cutefish-filemanager
model/dirlister.cpp model/dirlister.cpp
model/positioner.cpp model/positioner.cpp
dialogs/propertiesdialog.cpp
dialogs/createfolderdialog.cpp dialogs/createfolderdialog.cpp
dialogs/filepropertiesdialog.cpp
widgets/rubberband.cpp widgets/rubberband.cpp
widgets/itemviewadapter.cpp widgets/itemviewadapter.cpp

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (C) 2021 CutefishOS Team. * Copyright (C) 2021 CutefishOS Team.
* *
* Author: revenmartin <revenmartin@gmail.com> * Author: Reion Wong <reionwong@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -17,19 +17,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "propertiesdialog.h" #include "filepropertiesdialog.h"
#include "../desktopiconprovider.h" #include "../desktopiconprovider.h"
#include <KFileItemListProperties>
#include <KIO/CopyJob>
#include <QDir>
#include <QFileInfo>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext> #include <QQmlContext>
#include <QDebug> #include <QQmlEngine>
#include <QFileInfo>
#include <QDir>
#include <KIO/CopyJob>
inline QString concatPaths(const QString &path1, const QString &path2) 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) FilePropertiesDialog::FilePropertiesDialog(const KFileItem &item, QQuickView *parent)
: QObject(parent) : QQuickView(parent)
{ {
m_items.append(item); m_items.append(item);
init(); init();
} }
PropertiesDialog::PropertiesDialog(const KFileItemList &items, QObject *parent) FilePropertiesDialog::FilePropertiesDialog(const KFileItemList &items, QQuickView *parent)
: QObject(parent) : QQuickView(parent)
, m_items(items)
{ {
m_items = items;
init(); init();
} }
PropertiesDialog::PropertiesDialog(const QUrl &url, QObject *parent) FilePropertiesDialog::FilePropertiesDialog(const QUrl &url, QQuickView *parent)
: QObject(parent) : QQuickView(parent)
, m_items { KFileItem(url) }
{ {
m_items.append(KFileItem(url));
init(); init();
} }
PropertiesDialog::~PropertiesDialog() FilePropertiesDialog::~FilePropertiesDialog()
{ {
if (m_dirSizeJob) if (m_dirSizeJob) {
m_dirSizeJob->kill(); 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); KFileItemList list = m_items;
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();
if (list.size() == 1) { if (list.size() == 1) {
KFileItem item = list.first(); 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_multiple = m_items.count() > 1;
m_dirSizeJob = KIO::directorySize(m_items); 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) { if (!m_multiple) {
KFileItem item = m_items.first(); KFileItem item = m_items.first();
@ -205,20 +210,39 @@ void PropertiesDialog::init()
m_creationTime = item.time(KFileItem::CreationTime).toString(); m_creationTime = item.time(KFileItem::CreationTime).toString();
m_modifiedTime = item.time(KFileItem::ModificationTime).toString(); m_modifiedTime = item.time(KFileItem::ModificationTime).toString();
m_accessedTime = item.time(KFileItem::AccessTime).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 { } else {
m_isWritable = false;
m_fileName = tr("%1 files").arg(m_items.count()); m_fileName = tr("%1 files").arg(m_items.count());
m_location = QFileInfo(m_items.first().localPath()).dir().path(); 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()) if (job->error())
return; return;
m_dirSizeUpdateTimer->stop();
m_size = KIO::convertSize(m_dirSizeJob->totalSize()); m_size = KIO::convertSize(m_dirSizeJob->totalSize());
m_dirSizeJob = 0; m_dirSizeJob = 0;
emit sizeChanged(); emit fileSizeChanged();
} }

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (C) 2021 CutefishOS Team. * Copyright (C) 2021 CutefishOS Team.
* *
* Author: revenmartin <revenmartin@gmail.com> * Author: Reion Wong <reionwong@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -17,37 +17,38 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PROPERTIESDIALOG_H #ifndef FILEPROPERTIESDIALOG_H
#define PROPERTIESDIALOG_H #define FILEPROPERTIESDIALOG_H
#include <QObject> #include <QQuickView>
#include <QTimer>
#include <QUrl> #include <QUrl>
#include <KFileItem> #include <KFileItem>
#include <KIO/DirectorySizeJob> #include <KIO/DirectorySizeJob>
class PropertiesDialog : public QObject class FilePropertiesDialog : public QQuickView
{ {
Q_OBJECT 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 fileName READ fileName NOTIFY fileNameChanged)
Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged) Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged)
Q_PROPERTY(QString mimeType READ mimeType CONSTANT) Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged)
Q_PROPERTY(QString size READ size NOTIFY sizeChanged) Q_PROPERTY(QString fileSize READ fileSize NOTIFY fileSizeChanged)
Q_PROPERTY(QString creationTime READ creationTime CONSTANT) Q_PROPERTY(QString creationTime READ creationTime NOTIFY creationTimeChanged)
Q_PROPERTY(QString modifiedTime READ modifiedTime CONSTANT) Q_PROPERTY(QString modifiedTime READ modifiedTime NOTIFY modifiedTimeChanged)
Q_PROPERTY(QString accessedTime READ accessedTime CONSTANT) Q_PROPERTY(QString accessedTime READ accessedTime NOTIFY accessedTimeChanged)
Q_PROPERTY(bool multiple READ multiple CONSTANT) Q_PROPERTY(bool multiple READ multiple CONSTANT)
Q_PROPERTY(bool isWritable READ isWritable CONSTANT) Q_PROPERTY(bool isWritable READ isWritable NOTIFY isWritableChanged)
public: public:
explicit PropertiesDialog(const KFileItem &item, QObject *parent = nullptr); explicit FilePropertiesDialog(const KFileItem &item, QQuickView *parent = nullptr);
explicit PropertiesDialog(const KFileItemList &items, QObject *parent = nullptr); explicit FilePropertiesDialog(const KFileItemList &items, QQuickView *parent = nullptr);
explicit PropertiesDialog(const QUrl &url, QObject *parent = nullptr); explicit FilePropertiesDialog(const QUrl &url, QQuickView *parent = nullptr);
~PropertiesDialog(); ~FilePropertiesDialog();
static void showDialog(const KFileItem &item); Q_INVOKABLE void accept(const QString &text);
static void showDialog(const KFileItemList &items); Q_INVOKABLE void reject();
bool multiple() const; bool multiple() const;
bool isWritable() const; bool isWritable() const;
@ -56,21 +57,26 @@ public:
QString fileName() const; QString fileName() const;
QString iconName() const; QString iconName() const;
QString mimeType() const; QString mimeType() const;
QString size() const; QString fileSize() const;
QString creationTime() const; QString creationTime() const;
QString modifiedTime() const; QString modifiedTime() const;
QString accessedTime() const; QString accessedTime() const;
KFileItemList items() const;
Q_INVOKABLE void accept(const QString &text);
Q_INVOKABLE void reject();
signals: signals:
void locationChanged();
void fileNameChanged(); void fileNameChanged();
void iconNameChanged(); void iconNameChanged();
void sizeChanged(); void mimeTypeChanged();
void fileSizeChanged();
void creationTimeChanged();
void modifiedTimeChanged();
void accessedTimeChanged();
void isWritableChanged();
protected:
bool event(QEvent *e) override;
private: private:
void init(); void init();
@ -89,9 +95,11 @@ private:
QString m_modifiedTime; QString m_modifiedTime;
QString m_accessedTime; QString m_accessedTime;
QTimer *m_dirSizeUpdateTimer = nullptr;
KIO::DirectorySizeJob *m_dirSizeJob; KIO::DirectorySizeJob *m_dirSizeJob;
bool m_multiple; bool m_multiple;
bool m_isWritable;
}; };
#endif // PROPERTIESDIALOG_H #endif // FILEPROPERTIESDIALOG_H

View file

@ -25,7 +25,7 @@
#include "foldermodel.h" #include "foldermodel.h"
#include "dirlister.h" #include "dirlister.h"
#include "../dialogs/propertiesdialog.h" #include "../dialogs/filepropertiesdialog.h"
#include "../dialogs/createfolderdialog.h" #include "../dialogs/createfolderdialog.h"
#include "../helper/datehelper.h" #include "../helper/datehelper.h"
@ -936,7 +936,8 @@ void FolderModel::openPropertiesDialog()
const QModelIndexList indexes = m_selectionModel->selectedIndexes(); const QModelIndexList indexes = m_selectionModel->selectedIndexes();
if (indexes.isEmpty()) { if (indexes.isEmpty()) {
PropertiesDialog::showDialog(QUrl::fromLocalFile(url())); FilePropertiesDialog *dlg = new FilePropertiesDialog(QUrl::fromLocalFile(url()));
dlg->show();
return; return;
} }
@ -949,7 +950,8 @@ void FolderModel::openPropertiesDialog()
} }
} }
PropertiesDialog::showDialog(items); FilePropertiesDialog *dlg = new FilePropertiesDialog(items);
dlg->show();
} }
void FolderModel::openInTerminal() void FolderModel::openInTerminal()

View file

@ -23,12 +23,15 @@ import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import FishUI 1.0 as FishUI import FishUI 1.0 as FishUI
Window { Item {
id: control 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 { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -39,169 +42,151 @@ Window {
if (visible) updateWindowSize() if (visible) updateWindowSize()
} }
function close() {
main.close()
}
function updateWindowSize() { function updateWindowSize() {
if (visible) { 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) if (_textField.enabled)
_textField.forceActiveFocus() _textField.forceActiveFocus()
} }
} }
Item { ColumnLayout {
id: _contentItem id: _mainLayout
anchors.fill: parent 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 RowLayout {
Keys.onEscapePressed: control.close() spacing: FishUI.Units.largeSpacing * 2
ColumnLayout { Image {
id: _mainLayout width: 64
anchors.fill: parent height: width
anchors.leftMargin: FishUI.Units.largeSpacing * 2 sourceSize: Qt.size(width, height)
anchors.rightMargin: FishUI.Units.largeSpacing * 2 source: "image://icontheme/" + main.iconName
anchors.topMargin: FishUI.Units.largeSpacing }
anchors.bottomMargin: FishUI.Units.largeSpacing * 1.5
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 spacing: FishUI.Units.largeSpacing
RowLayout { Button {
spacing: FishUI.Units.largeSpacing * 2 text: qsTr("Cancel")
Layout.fillWidth: true
Image { onClicked: main.reject()
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
}
} }
GridLayout { Button {
columns: 2 text: qsTr("OK")
columnSpacing: FishUI.Units.largeSpacing Layout.fillWidth: true
rowSpacing: FishUI.Units.largeSpacing onClicked: {
Layout.alignment: Qt.AlignTop main.accept(_textField.text)
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
} }
flat: true
} }
} }
} }