#ifndef FAVOURITECOLLECTION_HPP #define FAVOURITECOLLECTION_HPP #include #include #include #include #include struct Favourite { QString title; QUrl destination; bool isValid() const { return destination.isValid(); } QString getTitle() const { if(title.isEmpty()) return destination.toString(QUrl::FullyEncoded); else return title; } }; class FavouriteCollection : public QAbstractItemModel { Q_OBJECT struct Node { enum Type { Root, Group, Favourite }; Node * parent = nullptr; int index = 0; std::vector> children; Type type; explicit Node(Type t) : type(t) { } Node(Node const &) = delete; Node(Node &&) = delete; virtual ~Node() = default; template T & as() { return *static_cast(this); } template T const & as() const { return *static_cast(this); } }; struct FavouriteNode : Node { ::Favourite favourite; FavouriteNode() : Node(Favourite) { } FavouriteNode(FavouriteNode const &) = delete; FavouriteNode(FavouriteNode &&) = delete; ~FavouriteNode() override = default; }; struct GroupNode : Node { QString title; GroupNode() : Node(Group) { } GroupNode(GroupNode const &) = delete; GroupNode(GroupNode &&) = delete; ~GroupNode() override = default; }; struct RootNode : Node { RootNode() : Node(Root) { } RootNode(RootNode const &) = delete; RootNode(RootNode &&) = delete; ~RootNode() override = default; }; public: explicit FavouriteCollection(QObject *parent = nullptr); FavouriteCollection(FavouriteCollection const & other); FavouriteCollection(FavouriteCollection && other); ~FavouriteCollection(); FavouriteCollection & operator=(FavouriteCollection const &); FavouriteCollection & operator=(FavouriteCollection &&); public: void load(QSettings & settings); void save(QSettings & settings) const; bool addGroup(QString const & group); bool renameGroup(QString const & old_name, QString const & new_name); bool addFavourite(QString const & group, Favourite const & fav); void editFavouriteTitle(const QModelIndex &index, const QString &title); bool editFavouriteTitle(const QUrl &url, const QString &new_title); void editFavouriteDest(const QModelIndex & index, const QUrl & url); bool editFavouriteGroup(const QUrl &url, const QString &group_name); Favourite getFavourite(const QUrl &url) const; Favourite getFavourite(QModelIndex const & index) const; Favourite * getMutableFavourite(QModelIndex const & index); QString groupForFavourite(QUrl const & url) const; QStringList groups() const; //! Returns the group name of the index. QString group(QModelIndex const & index) const; bool destroyFavourite(QModelIndex const & index); bool canDeleteGroup(QString const & group_name); bool deleteGroup(QString const & group_name); bool deleteGroupRecursive(QString const & group_name); //! Returns a list of non-mutable references to all contained favourites. //! Note that the group will change in-order, so all favourites for group a //! will be listed, then all for group b, no intermixing is done. QVector> allFavourites() const; bool containsUrl(QUrl const & url) const; bool addUnsorted(QUrl const & url, QString const & title); bool removeUrl(QUrl const & url); public: // Header: // QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; // Basic functionality: QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; // Drag'n'Drop Qt::ItemFlags flags(const QModelIndex &index) const override; QStringList mimeTypes() const override; QMimeData *mimeData(const QModelIndexList &indexes) const override; bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDragActions() const override; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; private: void relayout(); bool internalAddGroup(QString const & group_name, GroupNode * & out_group); private: RootNode root; }; #endif // FAVOURITECOLLECTION_HPP