diff --git a/CMakeLists.txt b/CMakeLists.txt index f6ed1fc..eb74bfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable(cutefish-filemanager widgets/rubberband.cpp widgets/itemviewadapter.cpp + desktop/desktop.cpp desktop/desktopview.cpp desktop/desktopsettings.cpp diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp new file mode 100644 index 0000000..37757af --- /dev/null +++ b/desktop/desktop.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "desktop.h" +#include + +Desktop::Desktop(QObject *parent) + : QObject(parent) +{ + for (QScreen *screen : QGuiApplication::screens()) { + screenAdded(screen); + } + + connect(qApp, &QGuiApplication::screenAdded, this, &Desktop::screenAdded); + connect(qApp, &QGuiApplication::screenRemoved, this, &Desktop::screenRemoved); +} + +void Desktop::screenAdded(QScreen *screen) +{ + if (!m_list.contains(screen)) { + DesktopView *view = new DesktopView(screen); + view->show(); + m_list.insert(screen, view); + } +} + +void Desktop::screenRemoved(QScreen *screen) +{ + if (m_list.contains(screen)) { + DesktopView *view = m_list.find(screen).value(); + view->setVisible(false); + view->deleteLater(); + m_list.remove(screen); + } +} diff --git a/desktop/desktop.h b/desktop/desktop.h new file mode 100644 index 0000000..f11f371 --- /dev/null +++ b/desktop/desktop.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DESKTOP_H +#define DESKTOP_H + +#include +#include + +#include "desktopview.h" + +class Desktop : public QObject +{ + Q_OBJECT + +public: + explicit Desktop(QObject *parent = nullptr); + +private slots: + void screenAdded(QScreen *qscreen); + void screenRemoved(QScreen *qscreen); + +private: + QMap m_list; +}; + +#endif // DESKTOP_H diff --git a/desktop/desktopview.cpp b/desktop/desktopview.cpp index e408bd5..b1d7a90 100644 --- a/desktop/desktopview.cpp +++ b/desktop/desktopview.cpp @@ -24,16 +24,19 @@ #include #include -#include +#include #include #include -DesktopView::DesktopView(QQuickView *parent) +DesktopView::DesktopView(QScreen *screen, QQuickView *parent) : QQuickView(parent) + , m_screen(screen) { - m_screenRect = qApp->primaryScreen()->geometry(); - m_screenAvailableRect = qApp->primaryScreen()->availableVirtualGeometry(); + m_screenRect = m_screen->geometry(); + m_screenAvailableRect = m_screen->availableVirtualGeometry(); + + qDebug() << screen->name() << m_screenAvailableRect; KWindowSystem::setType(winId(), NET::Desktop); KWindowSystem::setState(winId(), NET::KeepBelow); @@ -42,16 +45,19 @@ DesktopView::DesktopView(QQuickView *parent) engine()->addImageProvider("thumbnailer", new ThumbnailProvider()); setTitle(tr("Desktop")); - setScreen(qApp->primaryScreen()); + setScreen(m_screen); setResizeMode(QQuickView::SizeRootObjectToView); - setSource(QStringLiteral("qrc:/qml/Desktop/Main.qml")); onGeometryChanged(); + onPrimaryScreenChanged(QGuiApplication::primaryScreen()); - connect(qApp->primaryScreen(), &QScreen::virtualGeometryChanged, this, &DesktopView::onGeometryChanged); - connect(qApp->primaryScreen(), &QScreen::geometryChanged, this, &DesktopView::onGeometryChanged); - connect(qApp->primaryScreen(), &QScreen::availableGeometryChanged, this, &DesktopView::onAvailableGeometryChanged); - connect(qApp->primaryScreen(), &QScreen::virtualGeometryChanged, this, &DesktopView::onAvailableGeometryChanged); + // 主屏改变 + connect(qGuiApp, &QGuiApplication::primaryScreenChanged, this, &DesktopView::onPrimaryScreenChanged); + + connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::onGeometryChanged); + connect(m_screen, &QScreen::geometryChanged, this, &DesktopView::onGeometryChanged); + connect(m_screen, &QScreen::availableGeometryChanged, this, &DesktopView::onAvailableGeometryChanged); + connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::onAvailableGeometryChanged); } QRect DesktopView::screenRect() @@ -64,9 +70,17 @@ QRect DesktopView::screenAvailableRect() return m_screenAvailableRect; } +void DesktopView::onPrimaryScreenChanged(QScreen *screen) +{ + bool isPrimaryScreen = m_screen->name() == screen->name(); + + setSource(isPrimaryScreen ? QStringLiteral("qrc:/qml/Desktop/Main.qml") + : QStringLiteral("qrc:/qml/Desktop/Wallpaper.qml")); +} + void DesktopView::onGeometryChanged() { - m_screenRect = qApp->primaryScreen()->geometry().adjusted(0, 0, 1, 1); + m_screenRect = m_screen->geometry().adjusted(0, 0, 1, 1); setGeometry(m_screenRect); emit screenRectChanged(); } @@ -75,6 +89,6 @@ void DesktopView::onAvailableGeometryChanged(const QRect &geometry) { Q_UNUSED(geometry); - m_screenAvailableRect = qApp->primaryScreen()->availableVirtualGeometry(); + m_screenAvailableRect = m_screen->availableVirtualGeometry(); emit screenAvailableGeometryChanged(); } diff --git a/desktop/desktopview.h b/desktop/desktopview.h index ee6ba55..d9cc1a8 100644 --- a/desktop/desktopview.h +++ b/desktop/desktopview.h @@ -21,6 +21,7 @@ #define DESKTOPVIEW_H #include +#include class DesktopView : public QQuickView { @@ -29,7 +30,7 @@ class DesktopView : public QQuickView Q_PROPERTY(QRect screenAvailableRect READ screenAvailableRect NOTIFY screenAvailableGeometryChanged) public: - explicit DesktopView(QQuickView *parent = nullptr); + explicit DesktopView(QScreen *screen = nullptr, QQuickView *parent = nullptr); QRect screenRect(); QRect screenAvailableRect(); @@ -39,10 +40,12 @@ signals: void screenAvailableGeometryChanged(); private slots: + void onPrimaryScreenChanged(QScreen *screen); void onGeometryChanged(); void onAvailableGeometryChanged(const QRect &geometry); private: + QScreen *m_screen; QRect m_screenRect; QRect m_screenAvailableRect; }; diff --git a/main.cpp b/main.cpp index 8c64a99..3af13ac 100644 --- a/main.cpp +++ b/main.cpp @@ -31,6 +31,7 @@ #include "model/positioner.h" #include "widgets/rubberband.h" #include "widgets/itemviewadapter.h" +#include "desktop/desktop.h" #include "desktop/desktopsettings.h" #include "desktop/desktopview.h" #include "helper/datehelper.h" @@ -94,8 +95,7 @@ int main(int argc, char *argv[]) if (parser.isSet(desktopOption)) { app.setApplicationName("cutefish-desktop"); - DesktopView view; - view.show(); + Desktop desktop; return app.exec(); } else if (parser.isSet(emptyTrashOption)) { // Empty Dialog diff --git a/model/foldermodel.cpp b/model/foldermodel.cpp index 79517e1..40af04c 100644 --- a/model/foldermodel.cpp +++ b/model/foldermodel.cpp @@ -32,6 +32,8 @@ #include "../helper/datehelper.h" #include "../helper/filelauncher.h" +#include "../cio/cfilesizejob.h" + // Qt #include #include @@ -79,10 +81,12 @@ FolderModel::FolderModel(QObject *parent) , m_filterPatternMatchAll(true) , m_complete(false) , m_isDesktop(false) + , m_selectedItemSize("") , m_actionCollection(this) , m_dragInProgress(false) , m_viewAdapter(nullptr) , m_mimeAppManager(MimeAppManager::self()) + , m_sizeJob(nullptr) { DirLister *dirLister = new DirLister(this); dirLister->setDelayedMimeTypes(true); @@ -1100,6 +1104,10 @@ void FolderModel::openDeleteDialog() view->show(); } +void FolderModel::updateSelectedItemsSize() +{ +} + void FolderModel::restoreFromTrash() { if (!m_selectionModel->hasSelection()) @@ -1134,6 +1142,35 @@ void FolderModel::selectionChanged(const QItemSelection &selected, const QItemSe } } + if (m_sizeJob == nullptr) { + m_sizeJob = new CFileSizeJob; + + connect(m_sizeJob, &CFileSizeJob::sizeChanged, this, [=] { + m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize()); + if (!m_selectionModel->hasSelection()) + m_selectedItemSize = ""; + emit selectedItemSizeChanged(); + }); + + connect(m_sizeJob, &CFileSizeJob::result, this, [=] { + m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize()); + if (!m_selectionModel->hasSelection()) + m_selectedItemSize = ""; + emit selectedItemSizeChanged(); + }); + } + + m_sizeJob->stop(); + + if (!m_selectionModel->hasSelection()) { + m_sizeJob->blockSignals(true); + m_selectedItemSize = ""; + emit selectedItemSizeChanged(); + } else { + m_sizeJob->blockSignals(false); + m_sizeJob->start(selectedUrls()); + } + updateActions(); emit selectionCountChanged(); @@ -1246,6 +1283,11 @@ bool FolderModel::matchPattern(const KFileItem &item) const return false; } +QString FolderModel::selectedItemSize() const +{ + return m_selectedItemSize; +} + bool FolderModel::isDesktop() const { return m_isDesktop; diff --git a/model/foldermodel.h b/model/foldermodel.h index 116f2ae..503edc4 100644 --- a/model/foldermodel.h +++ b/model/foldermodel.h @@ -41,6 +41,7 @@ #include class QDrag; +class CFileSizeJob; class FolderModel : public QSortFilterProxyModel, public QQmlParserStatus { Q_OBJECT @@ -57,6 +58,7 @@ class FolderModel : public QSortFilterProxyModel, public QQmlParserStatus Q_PROPERTY(QString filterPattern READ filterPattern WRITE setFilterPattern NOTIFY filterPatternChanged) Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QStringList filterMimeTypes READ filterMimeTypes WRITE setFilterMimeTypes NOTIFY filterMimeTypesChanged) + Q_PROPERTY(QString selectedItemSize READ selectedItemSize NOTIFY selectedItemSizeChanged) public: enum DataRole { @@ -198,11 +200,15 @@ public: Q_INVOKABLE void openChangeWallpaperDialog(); Q_INVOKABLE void openDeleteDialog(); + Q_INVOKABLE void updateSelectedItemsSize(); + void restoreFromTrash(); bool isDesktop() const; void setIsDesktop(bool isDesktop); + QString selectedItemSize() const; + signals: void urlChanged(); void resolvedUrlChanged(); @@ -219,6 +225,7 @@ signals: void countChanged(); void filterPatternChanged(); void filterMimeTypesChanged(); + void selectedItemSizeChanged(); void notification(const QString &message); @@ -263,6 +270,8 @@ private: bool m_isDesktop; bool m_suffixVisible; + QString m_selectedItemSize; + KActionCollection m_actionCollection; QHash m_dragImages; QModelIndexList m_dragIndexes; @@ -274,6 +283,8 @@ private: // Save path history PathHistory m_pathHistory; MimeAppManager *m_mimeAppManager; + + CFileSizeJob *m_sizeJob; }; #endif // FOLDERMODEL_H diff --git a/qml.qrc b/qml.qrc index 0e4cf08..67469ff 100644 --- a/qml.qrc +++ b/qml.qrc @@ -59,5 +59,6 @@ images/light/drive-optical.svg qml/Dialogs/OpenWithDialog.qml qml/Dialogs/DeleteDialog.qml + qml/Desktop/Wallpaper.qml diff --git a/qml/Desktop/Main.qml b/qml/Desktop/Main.qml index 9ce8c8a..efec338 100644 --- a/qml/Desktop/Main.qml +++ b/qml/Desktop/Main.qml @@ -30,56 +30,12 @@ import "../" Item { id: rootItem - FM.DesktopSettings { - id: settings - } - GlobalSettings { id: globalSettings } - Loader { - id: backgroundLoader + Wallpaper { anchors.fill: parent - anchors.margins: 0 - sourceComponent: settings.backgroundType === 0 ? wallpaper : background - } - - Component { - id: background - - Rectangle { - anchors.fill: parent - color: settings.backgroundColor - } - } - - Component { - id: wallpaper - - Image { - source: "file://" + settings.wallpaper - sourceSize: Qt.size(width * Screen.devicePixelRatio, - height * Screen.devicePixelRatio) - fillMode: Image.PreserveAspectCrop - clip: true - cache: false - - ColorOverlay { - id: dimsWallpaper - anchors.fill: parent - source: parent - color: "#000000" - opacity: FishUI.Theme.darkMode && settings.dimsWallpaper ? 0.4 : 0.0 - - Behavior on opacity { - NumberAnimation { - duration: 200 - } - } - - } - } } FM.FolderModel { diff --git a/qml/Desktop/Wallpaper.qml b/qml/Desktop/Wallpaper.qml new file mode 100644 index 0000000..07f011b --- /dev/null +++ b/qml/Desktop/Wallpaper.qml @@ -0,0 +1,60 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtQuick.Window 2.12 +import QtGraphicalEffects 1.0 + +import Cutefish.FileManager 1.0 as FM +import FishUI 1.0 as FishUI + +Item { + id: control + + FM.DesktopSettings { + id: settings + } + + Loader { + id: backgroundLoader + anchors.fill: parent + anchors.margins: 0 + sourceComponent: settings.backgroundType === 0 ? wallpaper : background + } + + Component { + id: background + + Rectangle { + anchors.fill: parent + color: settings.backgroundColor + } + } + + Component { + id: wallpaper + + Image { + source: "file://" + settings.wallpaper + sourceSize: Qt.size(width * Screen.devicePixelRatio, + height * Screen.devicePixelRatio) + fillMode: Image.PreserveAspectCrop + clip: true + cache: false + + ColorOverlay { + id: dimsWallpaper + anchors.fill: parent + source: parent + color: "#000000" + opacity: FishUI.Theme.darkMode && settings.dimsWallpaper ? 0.4 : 0.0 + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } + + } + } + } +} diff --git a/qml/FolderGridView.qml b/qml/FolderGridView.qml index 92353fe..4253a7a 100644 --- a/qml/FolderGridView.qml +++ b/qml/FolderGridView.qml @@ -64,7 +64,7 @@ GridView { signal keyPress(var event) - cacheBuffer: Math.max(0, contentHeight) + cacheBuffer: Math.max(0, control.height * 1.5) onIconSizeChanged: { // 图标大小改变时需要重置状态,否则选中定位不准确 @@ -461,6 +461,8 @@ GridView { dirModel.setSelected(pressedItem.index) } + dirModel.updateSelectedItemsSize() + pressCanceled() } diff --git a/qml/FolderListView.qml b/qml/FolderListView.qml index dc517c7..d6a2c8f 100644 --- a/qml/FolderListView.qml +++ b/qml/FolderListView.qml @@ -53,6 +53,7 @@ ListView { currentIndex: -1 clip: true + cacheBuffer: width ScrollBar.vertical: ScrollBar { } boundsBehavior: Flickable.StopAtBounds diff --git a/qml/FolderPage.qml b/qml/FolderPage.qml index db09609..f5368be 100644 --- a/qml/FolderPage.qml +++ b/qml/FolderPage.qml @@ -249,6 +249,10 @@ Item { visible: dirModel.selectionCount >= 1 } + Label { + text: dirModel.selectedItemSize + } + Item { Layout.fillWidth: true }