File indexing completed on 2023-05-30 11:30:50

0001 /**
0002  * Copyright (C) 2003-2004 Scott Wheeler <wheeler@kde.org>
0003  *
0004  * This program is free software; you can redistribute it and/or modify it under
0005  * the terms of the GNU General Public License as published by the Free Software
0006  * Foundation; either version 2 of the License, or (at your option) any later
0007  * version.
0008  *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.
0012  *
0013  * You should have received a copy of the GNU General Public License along with
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.
0015  */
0016 
0017 #ifndef PLAYLISTSEARCH_H
0018 #define PLAYLISTSEARCH_H
0019 
0020 #include <QRegExp>
0021 #include <QVector>
0022 #include <QSortFilterProxyModel>
0023 
0024 class Playlist;
0025 class PlaylistItem;
0026 
0027 typedef QVector<int> ColumnList;
0028 typedef QVector<PlaylistItem *> PlaylistItemList;
0029 typedef QVector<Playlist *> PlaylistList;
0030 
0031 class PlaylistSearch : QSortFilterProxyModel
0032 {
0033 public:
0034     class Component;
0035     typedef QVector<Component> ComponentList;
0036 
0037     enum SearchMode { MatchAny = 0, MatchAll = 1 };
0038 
0039     PlaylistSearch(QObject* parent = nullptr);
0040     PlaylistSearch(const PlaylistList &playlists,
0041                    const ComponentList &components,
0042                    SearchMode mode = MatchAny,
0043                    QObject* parent = nullptr);
0044 
0045     void search();
0046     bool checkItem(QModelIndex *item);
0047 
0048     QModelIndexList matchedItems() const;
0049 
0050     void addPlaylist(Playlist *p);
0051     void clearPlaylists();
0052     PlaylistList playlists() const { return m_playlists; }
0053 
0054     void addComponent(const Component &c);
0055     void clearComponents();
0056     ComponentList components() const;
0057 
0058     void setSearchMode(SearchMode m) { m_mode = m; }
0059     SearchMode searchMode() const { return m_mode; }
0060 
0061     bool isNull() const;
0062     bool isEmpty() const;
0063 
0064     bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
0065 
0066     /**
0067      * This is used to clear an item from the matched and unmatched lists.  This
0068      * is useful because it can prevent keeping a dangling pointer around without
0069      * requiring invalidating the search.
0070      */
0071     void clearItem(PlaylistItem *item);
0072 
0073 private:
0074 
0075     PlaylistList m_playlists;
0076     ComponentList m_components;
0077     SearchMode m_mode;
0078 };
0079 
0080 /**
0081  * A search is built from several search components.  These correspond to to lines
0082  * in the search bar.
0083  */
0084 
0085 class PlaylistSearch::Component
0086 {
0087 public:
0088     enum MatchMode { Contains = 0, Exact = 1, ContainsWord = 2 };
0089 
0090     /**
0091      * Create an empty search component.  This is only provided for use by
0092      * QValueList and should not be used in any other context.
0093      */
0094     Component();
0095 
0096     /**
0097      * Create a query component.  This defaults to searching all visible columns.
0098      */
0099     Component(const QString &query,
0100               bool caseSensitive = false,
0101               const ColumnList &columns = ColumnList(),
0102               MatchMode mode = Contains);
0103 
0104     /**
0105      * Create a query component.  This defaults to searching all visible coulumns.
0106      */
0107     Component(const QRegExp &query, const ColumnList &columns = ColumnList());
0108 
0109     QString query() const { return m_query; }
0110     QRegExp pattern() const { return m_queryRe; }
0111     ColumnList columns() const { return m_columns; }
0112 
0113     bool matches(int row, QModelIndex parent, QAbstractItemModel* model) const;
0114     bool isPatternSearch() const { return m_re; }
0115     bool isCaseSensitive() const { return m_caseSensitive; }
0116     MatchMode matchMode() const { return m_mode; }
0117 
0118     bool operator==(const Component &v) const;
0119 
0120 private:
0121     QString m_query;
0122     QRegExp m_queryRe;
0123     mutable ColumnList m_columns;
0124     MatchMode m_mode;
0125     bool m_searchAllVisible;
0126     bool m_caseSensitive;
0127     bool m_re;
0128 };
0129 
0130 /**
0131  * Streams \a search to the stream \a s.
0132  * \note This does not save the playlist list, but instead will assume that the
0133  * search is just relevant to the collection list.  This is all that is presently
0134  * needed by JuK.
0135  */
0136 QDataStream &operator<<(QDataStream &s, const PlaylistSearch &search);
0137 
0138 /**
0139  * Streams \a search from the stream \a s.
0140  * \note This does not save the playlist list, but instead will assume that the
0141  * search is just relevant to the collection list.  This is all that is presently
0142  * needed by JuK.
0143  */
0144 QDataStream &operator>>(QDataStream &s, PlaylistSearch &search);
0145 
0146 QDataStream &operator<<(QDataStream &s, const PlaylistSearch::Component &c);
0147 QDataStream &operator>>(QDataStream &s, PlaylistSearch::Component &c);
0148 
0149 #endif
0150 
0151 // vim: set et sw=4 tw=0 sta: