some work on the grid layout and items

This commit is contained in:
Crylia
2024-06-08 19:00:34 +02:00
parent b1cfa155f9
commit 09987eed01
13 changed files with 290 additions and 36 deletions

83
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,83 @@
{
"files.associations": {
"cctype": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stdfloat": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"text_encoding": "cpp",
"thread": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"__bit_reference": "cpp",
"__config": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__verbose_abort": "cpp",
"ios": "cpp",
"locale": "cpp"
}
}

View File

@@ -4,12 +4,19 @@
#include <iostream> #include <iostream>
FileController::FileController( ) { FileController::FileController( ) {
m_fmWorker = std::make_shared<FileMonitor>(QString("/home/crylia/Dokumente"), #ifdef _WIN32
m_fmWorker = std::make_shared<FileMonitor>(std::filesystem::path(std::getenv("USERPROFILE")),
std::chrono::milliseconds(1000)); std::chrono::milliseconds(1000));
#else
m_fmWorker = std::make_shared<FileMonitor>(std::filesystem::path("/home/crylia/Dokumente"),
std::chrono::milliseconds(1000));
#endif
m_fmWorker->moveToThread(&m_fsThread); m_fmWorker->moveToThread(&m_fsThread);
connect(this, &FileController::operate, m_fmWorker.get( ), &FileMonitor::start); connect(this, &FileController::operate, m_fmWorker.get( ), &FileMonitor::start);
connect(m_fmWorker.get( ), &FileMonitor::update, this, &FileController::update); connect(m_fmWorker.get( ), &FileMonitor::update, this, &FileController::update);
connect(m_fmWorker.get( ), &FileMonitor::newPathEntered, this, &FileController::emitNewPath);
m_fsThread.start( ); m_fsThread.start( );
@@ -21,6 +28,11 @@ FileController::~FileController( ) {
m_fsThread.wait( ); m_fsThread.wait( );
} }
void FileController::update(const QString path, const FileEvent event) { void FileController::update(const std::filesystem::path path, const FileEvent event) {
std::cout << path.toStdString( ) << std::endl; std::cout << path.string( ) << std::endl;
}
void FileController::emitNewPath(const std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> paths) {
std::cout << "test" << std::endl;
emit newPathEntered(paths);
} }

View File

@@ -18,7 +18,8 @@ private:
private slots: private slots:
void update(const QString path, const FileEvent); void update(const std::filesystem::path path, const FileEvent);
void emitNewPath(const std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> paths);
signals: signals:
// Start signal to start the function in the thread // Start signal to start the function in the thread
@@ -26,5 +27,7 @@ signals:
// Stop signal to stop the function in the thread // Stop signal to stop the function in the thread
void pause( ); void pause( );
// Signal to update the path inside the thread // Signal to update the path inside the thread
void updatePath(const QString&); void updatePath(const std::filesystem::path&);
void newPathEntered(const std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> paths);
}; };

View File

@@ -1,16 +1,19 @@
#include "FileMonitor.hpp" #include "FileMonitor.hpp"
#include <filesystem> #include <filesystem>
#include <thread> #include <thread>
#include <iostream>
FileMonitor::FileMonitor(QString path, FileMonitor::FileMonitor(std::filesystem::path path,
std::chrono::duration<int, std::milli> delay) std::chrono::duration<int, std::milli> delay)
: m_path(path), m_delay(delay) { : m_path(path), m_delay(delay) {
for (auto& file : for (auto& file :
std::filesystem::directory_iterator(m_path.toStdString( ))) { std::filesystem::directory_iterator(m_path)) {
m_paths[QString::fromStdString(file.path( ).string( ))] = m_paths[file.path( )] = std::filesystem::last_write_time(file);
std::filesystem::last_write_time(file); std::cout << file.path( ).string( ) << std::endl;
} }
emit newPathEntered(m_paths);
} }
void FileMonitor::start( ) { void FileMonitor::start( ) {
@@ -19,7 +22,7 @@ void FileMonitor::start( ) {
auto pbegin = m_paths.begin( ); auto pbegin = m_paths.begin( );
while (pbegin != m_paths.end( )) { while (pbegin != m_paths.end( )) {
if (!std::filesystem::exists(pbegin->first.toStdString( ))) { if (!std::filesystem::exists(pbegin->first)) {
emit update(pbegin->first, FileEvent::erased); emit update(pbegin->first, FileEvent::erased);
pbegin = m_paths.erase(pbegin); pbegin = m_paths.erase(pbegin);
} else } else
@@ -27,21 +30,19 @@ void FileMonitor::start( ) {
} }
for (auto& file : for (auto& file :
std::filesystem::directory_iterator(m_path.toStdString( ))) { std::filesystem::directory_iterator(m_path)) {
auto curr_file_last_write = std::filesystem::last_write_time(file); auto curr_file_last_write = std::filesystem::last_write_time(file);
if (!contains(QString::fromStdString(file.path( ).string( )))) { if (!contains(file.path( ))) {
m_paths[QString::fromStdString(file.path( ).string( ))] = m_paths[file.path( )] =
curr_file_last_write; curr_file_last_write;
emit update(QString::fromStdString(file.path( ).string( )), emit update(file.path( ), FileEvent::created);
FileEvent::created);
} else { } else {
if (m_paths[QString::fromStdString(file.path( ).string( ))] != if (m_paths[file.path( )] !=
curr_file_last_write) { curr_file_last_write) {
m_paths[QString::fromStdString(file.path( ).string( ))] = m_paths[file.path( )] =
curr_file_last_write; curr_file_last_write;
emit update(QString::fromStdString(file.path( ).string( )), emit update(file.path( ), FileEvent::modified);
FileEvent::modified);
} }
} }
} }
@@ -50,6 +51,6 @@ void FileMonitor::start( ) {
void FileMonitor::stop( ) { m_running = false; } void FileMonitor::stop( ) { m_running = false; }
bool FileMonitor::contains(const QString& key) { bool FileMonitor::contains(const std::filesystem::path& key) {
return m_paths.find(key) != m_paths.end( ); return m_paths.find(key) != m_paths.end( );
} }

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
#include <QString>
#include <chrono> #include <chrono>
#include <filesystem> #include <filesystem>
#include <unordered_map> #include <unordered_map>
@@ -13,22 +12,23 @@ class FileMonitor : public QObject {
public: public:
std::chrono::duration<int, std::milli> m_delay; std::chrono::duration<int, std::milli> m_delay;
FileMonitor(QString path, std::chrono::duration<int, std::milli> delay); FileMonitor(std::filesystem::path path, std::chrono::duration<int, std::milli> delay);
~FileMonitor( ) = default; ~FileMonitor( ) = default;
void SetPath(QString path) { m_path = path; } void SetPath(std::filesystem::path path) { m_path = path; }
public slots: public slots:
void start( ); void start( );
void stop( ); void stop( );
private: private:
std::unordered_map<QString, std::filesystem::file_time_type> m_paths; std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> m_paths;
bool m_running; bool m_running;
QString m_path; std::filesystem::path m_path;
bool contains(const QString& key); bool contains(const std::filesystem::path& key);
signals: signals:
void update(const QString path, const FileEvent); void update(const std::filesystem::path path, const FileEvent);
void newPathEntered(const std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> paths);
}; };

View File

@@ -0,0 +1,20 @@
#include "GridItemView.hpp"
#include <iostream>
GridItemView::GridItemView(QWidget* parent)
: QFrame(parent),
fileController(std::make_shared<FileController>( )) {
QGridLayout* mainLayout = new QGridLayout( );
connect(fileController.get( ), &FileController::newPathEntered, this, [this, mainLayout](const std::unordered_map<std::filesystem::path, std::filesystem::file_time_type> paths) {
std::cout << "path.first" << std::endl;
for (auto path : paths) {
mainLayout->addWidget(new GridItem(path.first, this));
}
});
}
GridItemView::~GridItemView( ) { }

View File

@@ -0,0 +1,25 @@
#pragma once
#include <QFrame>
#include "../Widgets/GridItem/GridItem.hpp"
#include "../../Controller/FileController/FileController.hpp"
class GridItemView : public QFrame {
Q_OBJECT
private:
int m_rows;
int m_cols;
int m_spacing;
QList<GridItem> m_gridItemList;
std::shared_ptr<FileController> fileController;
public:
GridItemView(QWidget* parent = nullptr);
~GridItemView( );
private slots:
//void onSizeChanged( );
};

View File

@@ -2,14 +2,16 @@
MainWidget::MainWidget(QWidget* parent) { MainWidget::MainWidget(QWidget* parent) {
auto path_mainContentLayout = std::make_shared<QHBoxLayout>(this); auto path_mainContentLayout = new QHBoxLayout(this);
auto fileTree_fileGridLayout = std::make_shared<QVBoxLayout>(this); auto fileTree_fileGridLayout = new QVBoxLayout(this);
path_mainContentLayout->addLayout(fileTree_fileGridLayout.get( )); auto gridLayout = new GridItemView(this);
setLayout(path_mainContentLayout.get( )); fileTree_fileGridLayout->addWidget(gridLayout);
auto fmc = new FileController( ); path_mainContentLayout->addLayout(fileTree_fileGridLayout);
setLayout(path_mainContentLayout);
} }
MainWidget::~MainWidget( ) { } MainWidget::~MainWidget( ) { }

View File

@@ -3,8 +3,10 @@
#include <QLayout> #include <QLayout>
#include <QLabel> #include <QLabel>
#include <QWidget> #include <QWidget>
#include <QGridLayout>
#include "../../Controller/FileController/FileController.hpp" #include "../Widgets/GridItem/GridItem.hpp"
#include "../GridItemView/GridItemView.hpp"
class MainWidget : public QWidget { class MainWidget : public QWidget {
Q_OBJECT Q_OBJECT

View File

@@ -1,12 +1,12 @@
#include "MainWindow.hpp" #include "MainWindow.hpp"
MainWindow::MainWindow(QWidget* parent) MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent), m_mainWidget(std::make_shared<MainWidget>( )) { : QMainWindow(parent), m_mainWidget(new MainWidget( )) {
setWindowTitle("QutieFM"); setWindowTitle("QutieFM");
setObjectName("MainWindow"); setObjectName("MainWindow");
this->setCentralWidget(m_mainWidget.get( )); this->setCentralWidget(m_mainWidget);
} }
MainWindow::~MainWindow( ) { } MainWindow::~MainWindow( ) { }

View File

@@ -12,5 +12,5 @@ public:
private: private:
std::shared_ptr<MainWidget> m_mainWidget; MainWidget* m_mainWidget;
}; };

View File

@@ -0,0 +1,67 @@
#include "GridItem.hpp"
GridItem::GridItem(const std::filesystem::path path, QWidget* parent)
: QWidget(parent),
m_path(path),
m_name(QString::fromStdString(path.filename( ).string( ))),
m_icon(getIconForFileType(path)) {
widgetSize = QSize(128, 128);
setMinimumSize(widgetSize);
setMaximumSize(widgetSize);
auto vLayout = new QVBoxLayout(this);
vLayout->setSpacing(10);
m_iconLabel = new QLabel(this);
m_iconLabel->setPixmap(m_icon.pixmap(widgetSize.width( ), widgetSize.height( )));
m_iconLabel->setAlignment(Qt::AlignCenter);
m_nameLabel = new QLabel(m_name, this);
m_nameLabel->setAlignment(Qt::AlignCenter);
m_nameLabel->setWordWrap(true);
vLayout->addWidget(m_iconLabel);
vLayout->addWidget(m_nameLabel);
}
GridItem::~GridItem( ) { }
QString GridItem::formatText(const QString& text) {
QFontMetrics fm(font( ));
QString elidedText = fm.elidedText(text, Qt::ElideRight, widgetSize.width( ));
QString result;
QStringList lines = elidedText.split('\n');
for (int i = 0; i < std::min((int)lines.size( ), 3); ++i)
result.append(lines.at(i)).append('\n');
if (lines.size( ) > 3)
result.append("...");
return result.trimmed( );
}
QIcon GridItem::getIconForFileType(const std::filesystem::path path) const {
if (!std::filesystem::is_directory(path)) {
QIcon icon;
QList<QMimeType> mime_types = mime_database.mimeTypesForFileName(QString::fromStdString(path.string( )));
for (int i = 0; i < mime_types.count( ) && icon.isNull( ); ++i)
icon = QIcon::fromTheme(mime_types[i].iconName( ));
return icon.isNull( ) ? QApplication::style( )->standardIcon(QStyle::SP_FileIcon) : icon;
} else {
return QIcon::fromTheme("folder");
}
}
void GridItem::setIconSize(const QSize& size) {
widgetSize = size;
}
void GridItem::paintEvent(QPaintEvent* event) {
QStyleOption opt;
opt.initFrom(this);
QPainter p(this);
style( )->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
QWidget::paintEvent(event);
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <QWidget>
#include <QLabel>
#include <QLayout>
#include <QStyleOption>
#include <QPainter>
#include <QMimeDatabase>
#include <QApplication>
#include <filesystem>
class GridItem : public QWidget {
Q_OBJECT
private:
QString m_name;
QIcon m_icon;
int m_size;
std::filesystem::path m_path;
QSize widgetSize;
QMimeDatabase mime_database;
QString formatText(const QString& text);
QIcon getIconForFileType(const std::filesystem::path path) const;
public:
GridItem(const std::filesystem::path path, QWidget* parent = nullptr);
~GridItem( );
QLabel* m_nameLabel;
QLabel* m_iconLabel;
void setIconSize(const QSize& size);
protected:
void paintEvent(QPaintEvent* event)override;
};