File indexing completed on 2025-01-05 05:22:01

0001 /*
0002  * Copyright (c) 2018 Sune Vuorela <sune@vuorela.dk>
0003  *
0004  * Permission is hereby granted, free of charge, to any person
0005  * obtaining a copy of this software and associated documentation
0006  * files (the "Software"), to deal in the Software without
0007  * restriction, including without limitation the rights to use,
0008  * copy, modify, merge, publish, distribute, sublicense, and/or sell
0009  * copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following
0011  * conditions:
0012  *
0013  * The above copyright notice and this permission notice shall be
0014  * included in all copies or substantial portions of the Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0017  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
0018  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0019  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0020  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
0021  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0022  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0023  * OTHER DEALINGS IN THE SOFTWARE.
0024  */
0025 #pragma once
0026 
0027 #include <QObject>
0028 #include <QAbstractListModel>
0029 #include <QDir>
0030 #include <memory>
0031 #include <QVector>
0032 #include <QFileInfo>
0033 
0034 class QSortFilterProxyModel;
0035 class DirModelModel;
0036 /**
0037  * Backend class for FileOpen dialog. Provides a filterable model of current directory
0038  * and ability to change current directory
0039  */
0040 class DirModel : public QObject
0041 {
0042     Q_OBJECT
0043 
0044 public:
0045     enum Mode {
0046         Folders = QDir::Dirs,
0047         Files = QDir::Files,
0048         Drives = QDir::Drives,
0049         Hidden = QDir::Hidden,
0050         AllEntries = QDir::AllEntries
0051     };
0052     Q_ENUM(Mode)
0053     DirModel(QObject* parent = nullptr);
0054     ~DirModel();
0055     /** The potentially filtered model */
0056     Q_PROPERTY(QObject* filteredModel READ filteredModel CONSTANT)
0057     /** Filter string for the filtered model */
0058     Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
0059     /** Current path */
0060     Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
0061     /** Current directory name */
0062     Q_PROPERTY(QString dirName READ dirName NOTIFY pathChanged)
0063     /** The current mode (available files types)*/
0064     Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged)
0065     // TODO Q_PROPERTY(QStringList filterList ....) to be able to match e.g. *.pdf or whatever
0066     /** changes directory one level up */
0067     Q_INVOKABLE void cdUp();
0068     /** changes to directory */
0069     Q_INVOKABLE void cd(const QString& directory);
0070     QObject* filteredModel() const;
0071     QString filter() const;
0072     void setFilter(const QString& newFilter);
0073     QString path() const;
0074     void setPath(const QString& newPath);
0075     Mode mode() const;
0076     void setMode(Mode mode);
0077     QString dirName() const;
0078 
0079 Q_SIGNALS:
0080     void filterChanged();
0081     void pathChanged();
0082     void modeChanged();
0083 private:
0084     std::unique_ptr<QSortFilterProxyModel> m_filterModel;
0085     std::unique_ptr<DirModelModel> m_sourceModel;
0086     QString m_filter;
0087 };
0088 
0089 /**
0090  * QAIM backend for DirModel
0091  * When using a filtered model in \ref DirModel, the following roles are available
0092  *  "display" - file name
0093  *  "icon" - xdg spec'ed icon for current file if applicaple
0094  *  "fullpath" - full path to file
0095  *  "type" - "file" or "folder"
0096  */
0097 class DirModelModel : public QAbstractListModel {
0098     Q_OBJECT
0099 public:
0100     DirModelModel(QObject* parent = nullptr);
0101     ~DirModelModel();
0102     void cdUp();
0103     void cd(const QString& directory);
0104     void setPath(const QString& newPath);
0105     QString path() const;
0106     // QAIM api
0107     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
0108     QHash<int, QByteArray> roleNames() const override;
0109     int rowCount(const QModelIndex & parent) const override;
0110     enum MyRoles {
0111         FullPath = Qt::UserRole + 1,
0112         Type
0113     };
0114     void setMode(DirModel::Mode newMode);
0115     DirModel::Mode mode() const;
0116     QString dirName() const;
0117 
0118 
0119 private:
0120     void refresh();
0121     QDir m_path;
0122     DirModel::Mode m_mode;
0123     QVector<QFileInfo> m_files;
0124 };