Skip to content

Commit 156a077

Browse files
feat: add filesystem filter issue
1 parent dc13385 commit 156a077

13 files changed

Lines changed: 244 additions & 35 deletions

desktop/base/file_operations/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_library(cffilesystem STATIC)
44
# Sources
55
target_sources(cffilesystem PRIVATE
66
file_op.cpp
7+
filter_target.cpp
78
)
89

910
# Include directories
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "filter_target.h"
2+
#include <QDir>
3+
#include <QFileInfo>
4+
#include <QMap>
5+
6+
namespace cf::desktop::base::filesystem {
7+
8+
namespace {
9+
10+
class FilterPool {
11+
public:
12+
static FilterPool& instance() {
13+
static FilterPool pool;
14+
return pool;
15+
}
16+
17+
QString filter_string(FilterType type) const { return m_filterStrings.value(type); }
18+
19+
QStringList& filter_list(FilterType type) { return m_filterLists[type]; }
20+
21+
private:
22+
FilterPool() {
23+
// Pictures
24+
m_filterLists[FilterType::Pictures] = {"*.png", "*.jpg", "*.jpeg", "*.bmp", "*.gif",
25+
"*.webp", "*.svg", "*.tiff", "*.ico"};
26+
m_filterStrings[FilterType::Pictures] =
27+
QString("Images (%1)").arg(m_filterLists[FilterType::Pictures].join(' '));
28+
29+
// AllFiles (files only)
30+
m_filterLists[FilterType::AllFiles] = {"*"};
31+
m_filterStrings[FilterType::AllFiles] = QString("All Files (*)");
32+
33+
// All (files + directories)
34+
m_filterLists[FilterType::All] = {"*"};
35+
m_filterStrings[FilterType::All] = QString("All (*)");
36+
37+
// Dirent
38+
m_filterLists[FilterType::Dirent] = {};
39+
m_filterStrings[FilterType::Dirent] = QString("Directories");
40+
}
41+
42+
QMap<FilterType, QStringList> m_filterLists;
43+
QMap<FilterType, QString> m_filterStrings;
44+
};
45+
46+
} // namespace
47+
48+
QString request_filter(const FilterType what) {
49+
return FilterPool::instance().filter_string(what);
50+
}
51+
52+
QStringList& request_filterlist(const FilterType what) {
53+
return FilterPool::instance().filter_list(what);
54+
}
55+
56+
QStringList filter_target(const QString& dirent_path, const QStringList& filters) {
57+
QStringList result;
58+
QDir dir(dirent_path);
59+
60+
if (!dir.exists()) {
61+
return result;
62+
}
63+
64+
const QFileInfoList entries = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot);
65+
for (const auto& entry : entries) {
66+
result.append(entry.absoluteFilePath());
67+
}
68+
69+
return result;
70+
}
71+
72+
} // namespace cf::desktop::base::filesystem
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @file desktop/base/file_operations/filter_target.h
3+
* @brief File-system filtering utilities for directory traversal.
4+
*
5+
* Provides filter types and functions for listing files in a directory
6+
* that match specific criteria (e.g., pictures, all files).
7+
*
8+
* @author Charliechen114514 (chengh1922@mails.jlu.edu.cn)
9+
* @date 2026-04-09
10+
* @version 0.1
11+
* @since 0.1
12+
* @ingroup filesystem
13+
*/
14+
15+
#pragma once
16+
#include <QStringList>
17+
18+
namespace cf::desktop::base::filesystem {
19+
20+
/**
21+
* @brief File filter categories for directory traversal.
22+
*
23+
* @ingroup filesystem
24+
*/
25+
enum class FilterType {
26+
Pictures, ///< Common image file extensions.
27+
AllFiles, ///< All regular files.
28+
All, ///< All entries including hidden files.
29+
Dirent ///< Directory entries only.
30+
};
31+
32+
QString request_filter(const FilterType what);
33+
QStringList& request_filterlist(const FilterType what);
34+
35+
/**
36+
* @brief Get the file associate the filters
37+
*
38+
* @param dirent_path
39+
* @param filters
40+
* @return QStringList
41+
*/
42+
QStringList filter_target(const QString& dirent_path, const QStringList& filters);
43+
} // namespace cf::desktop::base::filesystem

desktop/ui/components/shell_layer_impl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ target_link_libraries(
2121
cfdesktop_wallpaper
2222
cfpath
2323
cfconfig
24+
cffilesystem
2425
)

desktop/ui/components/shell_layer_impl/wallpaper_setup.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "wallpaper_setup.h"
2+
#include "cflog.h"
3+
#include "filter_target.h"
24
#include "shell_layer_impl/WallpaperShellLayerStrategy.h"
35
#include "wallpaper/ImageWallPaperLayer.h"
46
#include "wallpaper/WallPaperAccessStorage.h"
@@ -14,19 +16,20 @@ namespace {
1416
* @return std::unique_ptr<WallPaperLayer>
1517
*/
1618
std::unique_ptr<WallPaperLayer> make_layer() {
17-
auto layer = std::make_unique<ImageWallPaperLayer>();
18-
19-
// Resolve wallpaper source through policy chain
20-
auto chain = WallpaperImages();
21-
auto source = chain.execute();
19+
using namespace base::filesystem;
2220

23-
if (source.has_value() && !source->isEmpty()) {
24-
auto storage = std::make_unique<WallPaperAccessStorage>();
25-
auto token = WallPaperTokenFactory::fromFile(*source).create();
26-
storage->addToken(std::move(token));
27-
layer->setTokenStorage(std::move(storage));
21+
auto layer = std::make_unique<ImageWallPaperLayer>();
22+
// Resolve wallpaper pictures through policy chain
23+
auto picture_dirent = WallpaperImages().execute();
24+
if (!picture_dirent.has_value() || picture_dirent->isEmpty()) {
25+
return layer; // return out!
2826
}
2927

28+
auto pictures = filter_target(picture_dirent.value(), request_filterlist(FilterType::Pictures));
29+
auto storage = std::make_unique<WallPaperAccessStorage>();
30+
storage->addTokens(WallPaperTokenFactory::fromFiles(pictures));
31+
log::tracef("Initialized with {} files", storage->size());
32+
layer->setTokenStorage(std::move(storage));
3033
return layer;
3134
}
3235

desktop/ui/components/shell_layer_impl/wallpaper_src_chain.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "wallpaper_src_chain.h"
22
#include "base/policy_chain/policy_chain.hpp"
33
#include "cfconfig.hpp"
4+
#include "cflog.h"
45
#include "cfpath/desktop_main_path_resolvers.h"
56
#include <QDir>
67
#include <QFileInfo>
@@ -10,28 +11,23 @@ PolicyChain<QString> WallpaperImages() {
1011
return policy_chain_builder<QString>()
1112
.then([]() -> std::optional<QString> {
1213
// Policy 1: Load from ConfigStore wallpaper domain
14+
log::trace("Scanning from the config file to load wallpaper");
1315
auto wp = cf::config::ConfigStore::instance().domain("wallpaper");
1416
auto path = wp.query<std::string>(
1517
cf::config::KeyView{.group = "wallpaper", .key = "source_path"}, "");
1618
if (!path.empty()) {
1719
QString qpath = QString::fromStdString(path);
20+
log::tracef("scan out the dirent: {}", qpath.toStdString());
1821
if (QFileInfo::exists(qpath)) {
1922
return qpath;
2023
}
2124
}
2225
return std::nullopt;
2326
})
2427
.then([]() -> std::optional<QString> {
25-
// Policy 2: Scan Pictures directory for any image
26-
auto pictures = path::DesktopMainPathProvider::instance().absolutePath(
28+
/* If not, we use the pictures in Picture Dirent */
29+
return path::DesktopMainPathProvider::instance().absolutePath(
2730
path::DesktopMainPathProvider::PathType::Pictures);
28-
QDir dir(pictures);
29-
QStringList files = dir.entryList({"*.png", "*.jpg", "*.jpeg", "*.bmp", "*.webp"},
30-
QDir::Files, QDir::Name);
31-
if (!files.isEmpty()) {
32-
return dir.absoluteFilePath(files.first());
33-
}
34-
return std::nullopt;
3531
})
3632
.build();
3733
}

desktop/ui/components/wallpaper/ImageWallPaperLayer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ void ImageWallPaperLayer::setTokenStorage(std::unique_ptr<WallPaperAccessStorage
3939
}
4040
}
4141

42+
WallPaperAccessStorage& ImageWallPaperLayer::tokenStorage() const {
43+
return *d->storage; // OK, Deref
44+
}
45+
4246
bool ImageWallPaperLayer::showNextOne() {
4347
if (!d->storage) {
4448
return false;

desktop/ui/components/wallpaper/ImageWallPaperLayer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ class ImageWallPaperLayer : public WallPaperLayer {
4444

4545
void setTokenStorage(std::unique_ptr<WallPaperAccessStorage> storage) override;
4646

47+
/**
48+
* @brief Returns a reference to the current token storage.
49+
*
50+
* @return Reference to the active WallPaperAccessStorage.
51+
*
52+
* @throws None.
53+
*
54+
* @note None.
55+
* @warning None.
56+
* @since 0.15
57+
* @ingroup wallpaper
58+
*/
59+
WallPaperAccessStorage& tokenStorage() const override;
60+
4761
/**
4862
* @brief Switches to the next wallpaper in the collection.
4963
*

desktop/ui/components/wallpaper/WallPaperAccessStorage.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ void WallPaperAccessStorage::addToken(std::unique_ptr<WallPaperToken> token) {
5252
wallpaper_images.push_back(std::move(token));
5353
}
5454

55+
void WallPaperAccessStorage::addTokens(std::vector<std::unique_ptr<WallPaperToken>> tokens) {
56+
wallpaper_images.reserve(wallpaper_images.size() + tokens.size());
57+
for (auto& t : tokens)
58+
wallpaper_images.push_back(std::move(t));
59+
}
60+
5561
void WallPaperAccessStorage::insertToken(size_t index, std::unique_ptr<WallPaperToken> token) {
5662
wallpaper_images.insert(wallpaper_images.begin() + static_cast<std::ptrdiff_t>(index),
5763
std::move(token));
@@ -65,4 +71,8 @@ size_t WallPaperAccessStorage::indexOf(const wallpaper_token_id_t& token) const
6571
return static_cast<size_t>(it - wallpaper_images.begin());
6672
}
6773

74+
size_t WallPaperAccessStorage::size() const {
75+
return wallpaper_images.size();
76+
}
77+
6878
} // namespace cf::desktop::wallpaper

desktop/ui/components/wallpaper/WallPaperAccessStorage.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ class WallPaperAccessStorage : public QObject {
7474
*/
7575
void addToken(std::unique_ptr<WallPaperToken> token);
7676

77+
/**
78+
* @brief Appends multiple wallpaper tokens to the storage.
79+
*
80+
* Ownership of all tokens transfers to this storage.
81+
*
82+
* @param[in] tokens The wallpaper tokens to add. Moved from; empty on
83+
* return.
84+
*
85+
* @throws None.
86+
*
87+
* @note None.
88+
* @warning None.
89+
* @since 0.18
90+
* @ingroup wallpaper
91+
*/
92+
void addTokens(std::vector<std::unique_ptr<WallPaperToken>> tokens);
93+
7794
/**
7895
* @brief Inserts a wallpaper token at the given index.
7996
*
@@ -107,6 +124,20 @@ class WallPaperAccessStorage : public QObject {
107124
*/
108125
size_t indexOf(const wallpaper_token_id_t& token) const;
109126

127+
/**
128+
* @brief Returns the number of wallpaper tokens in the storage.
129+
*
130+
* @return Number of stored tokens.
131+
*
132+
* @throws None.
133+
*
134+
* @note None.
135+
* @warning None.
136+
* @since 0.15
137+
* @ingroup wallpaper
138+
*/
139+
size_t size() const;
140+
110141
enum class OverFlowType { OverFlow, UnderFlow };
111142
signals:
112143
/**

0 commit comments

Comments
 (0)