1 /* vi:set ts=8 sts=8 sw=8:
2  *
3  * PMS  <<Practical Music Search>>
4  * Copyright (C) 2006-2010  Kim Tore Jensen
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * 	list.h
20  * 		Playlist class, holds info about a lot of songs
21  */
22 
23 #ifndef _PMS_LIST_H_
24 #define _PMS_LIST_H_
25 
26 
27 #include <algorithm>
28 #include <string>
29 #include <vector>
30 #include "libmpdclient.h"
31 #include "song.h"
32 #include "types.h"
33 #include "field.h"
34 #include "filter.h"
35 
36 using namespace std;
37 
38 #define MATCH_FAILED -1
39 
40 enum
41 {
42 	MATCH_ID		= 1 << 0,
43 	MATCH_POS		= 1 << 1,
44 	MATCH_FILE		= 1 << 2,
45 	MATCH_ARTIST		= 1 << 3,
46 	MATCH_ARTISTSORT	= 1 << 4,
47 	MATCH_ALBUMARTIST	= 1 << 5,
48 	MATCH_ALBUMARTISTSORT	= 1 << 6,
49 	MATCH_TITLE		= 1 << 7,
50 	MATCH_ALBUM		= 1 << 8,
51 	MATCH_TRACKSHORT	= 1 << 9,
52 	MATCH_DATE		= 1 << 10,
53 	MATCH_TIME		= 1 << 11,
54 	MATCH_GENRE		= 1 << 12,
55 	MATCH_COMPOSER		= 1 << 13,
56 	MATCH_PERFORMER		= 1 << 14,
57 	MATCH_DISC		= 1 << 15,
58 	MATCH_COMMENT		= 1 << 16,
59 	MATCH_YEAR		= 1 << 17,
60 
61 	MATCH_ALL		= (1 << 18) - 1,
62 
63 	MATCH_NOT		= 1 << 18,
64 	MATCH_EXACT		= 1 << 19,
65 	MATCH_REVERSE		= 1 << 20,
66 	MATCH_ALMOST		= 1 << 21,
67 	MATCH_LT		= 1 << 22,
68 	MATCH_LTE		= 1 << 23,
69 	MATCH_GT		= 1 << 24,
70 	MATCH_GTE		= 1 << 25
71 };
72 
73 typedef enum
74 {
75 	LIST_ROLE_MAIN,
76 	LIST_ROLE_LIBRARY,
77 	LIST_ROLE_PLAYLIST
78 }
79 List_role;
80 
81 struct Selection
82 {
83 	song_t				size;
84 	song_t				length;
85 };
86 
87 class Songlist
88 {
89 private:
90 	song_t					position;
91 	song_t					qlen;
92 	song_t					qpos;
93 	song_t					qnum;
94 	song_t					qsize;
95 
96 	Song *					lastget;
97 	vector<Song *>::iterator		seliter;
98 	vector<Song *>::reverse_iterator	rseliter;
99 
100 	vector<Song *>				songs;
101 	vector<Song *>				filtersongs;
102 	vector<Filter *>			filters;
103 
104 public:
105 				Songlist();
106 				~Songlist();
107 
108 	bool			ignorecase;
109 	bool			wrap;
110 	List_role		role;
111 	string			filename;
112 
113 	Song *			song(song_t);
114 	unsigned int		length;
115 	void			clear();
116 	Selection		selection;
117 	void			set(Songlist *);
118 	void			truncate(unsigned int);
119 
120 	bool			sort(string);
121 
122 	vector<song_t> *	matchall(string, long);
123 	song_t			match(string, unsigned int, unsigned int, long);
124 	bool			match(Song *, string, long);
125 #ifdef HAVE_LIBBOOST_REGEX
126 	bool			regexmatch(string *, string *);
127 #endif
128 	bool			exactmatch(string *, string *);
129 	bool			inmatch(string *, string *);
130 	bool			perform_match(string *, string *, int);
131 
132 	void			movecursor(song_t);
133 	int			setcursor(song_t);
134 	bool			gotocurrent();
135 	unsigned int		cursor();
136 	Song *			cursorsong();
137 	int			locatesong(Song *);
138 
139 	bool			selectsong(Song *, bool);
140 	Song *			getnextselected();
141 	Song *			getprevselected();
142 	Song *			popnextselected();
143 	void			resetgets();
144 	bool			swap(int, int);
145 
146 	/* Pick songs based on playmode */
147 	Song *			nextsong(song_t * = NULL);
148 	Song *			prevsong(song_t * = NULL);
149 	Song *			randsong(song_t * = NULL);
150 
151 	/* Next-of and prev-of functions */
152 	song_t			nextof(string);
153 	song_t			prevof(string);
154 	song_t			findentry(Item, bool);
155 
156 	/* Filter functions */
157 	Filter *		filter_add(string param, long fields);
158 	void			filter_remove(Filter *);
159 	void			filter_clear();
160 	void			filter_scan();
161 	bool			filter_match(Song *);
162 	Filter *		lastfilter();
filtercount()163 	unsigned int		filtercount() { return filters.size(); };
164 
165 	song_t			add(Song *);
166 	song_t			add(Songlist *);
167 	int			remove(Song *);
168 	int			remove(int);
169 	bool			move(unsigned int, unsigned int);
realsize()170 	unsigned int		realsize() { return songs.size(); };
size()171 	unsigned int		size() { return filtersongs.size(); };
end()172 	unsigned int		end() { return filtersongs.size() - 1; };
173 	unsigned int		qlength();
qnumber()174 	unsigned int		qnumber() { return qnum; };
175 };
176 
177 bool		lcstrcmp(string &, string &);
178 bool		icstrsort(string &, string &);
179 
180 /* Sorts */
181 bool		sort_compare_file(Song *, Song *);
182 bool		sort_compare_artist(Song *, Song *);
183 bool		sort_compare_albumartist(Song *, Song *);
184 bool		sort_compare_albumartistsort(Song *, Song *);
185 bool		sort_compare_artistsort(Song *, Song *);
186 bool		sort_compare_title(Song *, Song *);
187 bool		sort_compare_album(Song *, Song *);
188 bool		sort_compare_track(Song *, Song *);
189 bool		sort_compare_length(Song *, Song *);
190 bool		sort_compare_name(Song *, Song *);
191 bool		sort_compare_date(Song *, Song *);
192 bool		sort_compare_year(Song *, Song *);
193 bool		sort_compare_genre(Song *, Song *);
194 bool		sort_compare_composer(Song *, Song *);
195 bool		sort_compare_performer(Song *, Song *);
196 bool		sort_compare_disc(Song *, Song *);
197 bool		sort_compare_comment(Song *, Song *);
198 
199 
200 #endif
201