1 | /* smplayer, GUI front-end for mplayer.
|
---|
2 | Copyright (C) 2006-2013 Ricardo Villalba <rvm@users.sourceforge.net>
|
---|
3 |
|
---|
4 | This program is free software; you can redistribute it and/or modify
|
---|
5 | it under the terms of the GNU General Public License as published by
|
---|
6 | the Free Software Foundation; either version 2 of the License, or
|
---|
7 | (at your option) any later version.
|
---|
8 |
|
---|
9 | This program is distributed in the hope that it will be useful,
|
---|
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
12 | GNU General Public License for more details.
|
---|
13 |
|
---|
14 | You should have received a copy of the GNU General Public License
|
---|
15 | along with this program; if not, write to the Free Software
|
---|
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
17 | */
|
---|
18 |
|
---|
19 | #include "favorites.h"
|
---|
20 | #include "favoriteeditor.h"
|
---|
21 |
|
---|
22 | #include <QAction>
|
---|
23 | #include <QSettings>
|
---|
24 | #include <QFile>
|
---|
25 | #include <QTextStream>
|
---|
26 | #include <QInputDialog>
|
---|
27 | #include <QFileInfo>
|
---|
28 |
|
---|
29 | //#define FIRST_MENU_ENTRY 4
|
---|
30 | #define FIRST_MENU_ENTRY 3
|
---|
31 |
|
---|
32 | Favorites::Favorites(QString filename, QWidget * parent) : QMenu(parent)
|
---|
33 | {
|
---|
34 | _filename = filename;
|
---|
35 |
|
---|
36 | parent_widget = parent;
|
---|
37 |
|
---|
38 | current_file = QString::null;
|
---|
39 | last_item = 1;
|
---|
40 |
|
---|
41 | edit_act = new QAction( "Edit...", this);
|
---|
42 | connect(edit_act, SIGNAL(triggered()), this, SLOT(edit()));
|
---|
43 |
|
---|
44 | jump_act = new QAction( "Jump...", this);
|
---|
45 | connect(jump_act, SIGNAL(triggered()), this, SLOT(jump()));
|
---|
46 |
|
---|
47 | next_act = new QAction(this);
|
---|
48 | connect(next_act, SIGNAL(triggered()), this, SLOT(next()));
|
---|
49 |
|
---|
50 | previous_act = new QAction(this);
|
---|
51 | connect(previous_act, SIGNAL(triggered()), this, SLOT(previous()));
|
---|
52 |
|
---|
53 | add_current_act = new QAction( "Add current media", this);
|
---|
54 | add_current_act->setEnabled(false);
|
---|
55 | connect(add_current_act, SIGNAL(triggered()), SLOT(addCurrentPlaying()));
|
---|
56 |
|
---|
57 | retranslateStrings();
|
---|
58 |
|
---|
59 | load();
|
---|
60 |
|
---|
61 | connect( this, SIGNAL(triggered(QAction *)),
|
---|
62 | this, SLOT(triggered_slot(QAction *)) );
|
---|
63 |
|
---|
64 | addAction(edit_act);
|
---|
65 | addAction(add_current_act);
|
---|
66 | //addAction(jump_act);
|
---|
67 | addSeparator();
|
---|
68 |
|
---|
69 | populateMenu();
|
---|
70 |
|
---|
71 | }
|
---|
72 |
|
---|
73 | Favorites::~Favorites() {
|
---|
74 | /* qDebug("Favorites::~Favorites"); */
|
---|
75 |
|
---|
76 | save();
|
---|
77 | delete_children();
|
---|
78 | }
|
---|
79 |
|
---|
80 | void Favorites::delete_children() {
|
---|
81 | for (int n=0; n < child.count(); n++) {
|
---|
82 | if (child[n]) delete child[n];
|
---|
83 | child[n] = 0;
|
---|
84 | }
|
---|
85 | child.clear();
|
---|
86 | }
|
---|
87 |
|
---|
88 | void Favorites::retranslateStrings() {
|
---|
89 | edit_act->setText( tr("&Edit...") );
|
---|
90 | jump_act->setText( tr("&Jump...") );
|
---|
91 | next_act->setText( tr("&Next") );
|
---|
92 | previous_act->setText( tr("&Previous") );
|
---|
93 | add_current_act->setText( tr("&Add current media") );
|
---|
94 | }
|
---|
95 |
|
---|
96 | Favorites * Favorites::createNewObject(QString filename, QWidget * parent) {
|
---|
97 | return new Favorites(filename, parent);
|
---|
98 | }
|
---|
99 |
|
---|
100 | void Favorites::populateMenu() {
|
---|
101 | for (int n = 0; n < f_list.count(); n++) {
|
---|
102 | QString i = QString::number(n+1);
|
---|
103 | QString name = QString("%1 - " + f_list[n].name() ).arg( i.insert( i.size()-1, '&' ), 3, ' ' );
|
---|
104 | if (f_list[n].isSubentry()) {
|
---|
105 | Favorites * new_fav = createNewObject(f_list[n].file(), parent_widget);
|
---|
106 | new_fav->getCurrentMedia(received_file_playing, received_title);
|
---|
107 | connect(this, SIGNAL(sendCurrentMedia(const QString &, const QString &)),
|
---|
108 | new_fav, SLOT(getCurrentMedia(const QString &, const QString &)));
|
---|
109 | /*
|
---|
110 | new_fav->editAct()->setText( editAct()->text() );
|
---|
111 | new_fav->jumpAct()->setText( jumpAct()->text() );
|
---|
112 | new_fav->nextAct()->setText( nextAct()->text() );
|
---|
113 | new_fav->previousAct()->setText( previousAct()->text() );
|
---|
114 | new_fav->addCurrentAct()->setText( addCurrentAct()->text() );
|
---|
115 | */
|
---|
116 |
|
---|
117 | child.push_back(new_fav);
|
---|
118 |
|
---|
119 | QAction * a = addMenu( new_fav );
|
---|
120 | a->setText( name );
|
---|
121 | a->setIcon( QIcon( f_list[n].icon() ) );
|
---|
122 | } else {
|
---|
123 | QAction * a = addAction( name );
|
---|
124 | a->setData( f_list[n].file() );
|
---|
125 | a->setIcon( QIcon( f_list[n].icon() ) );
|
---|
126 | a->setStatusTip( f_list[n].file() );
|
---|
127 | }
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | void Favorites::updateMenu() {
|
---|
132 | // Remove all except the first 2 items
|
---|
133 | while (actions().count() > FIRST_MENU_ENTRY) {
|
---|
134 | QAction * a = actions()[FIRST_MENU_ENTRY];
|
---|
135 | removeAction( a );
|
---|
136 | a->deleteLater();
|
---|
137 | }
|
---|
138 |
|
---|
139 | delete_children();
|
---|
140 |
|
---|
141 | populateMenu();
|
---|
142 | markCurrent();
|
---|
143 | }
|
---|
144 |
|
---|
145 | void Favorites::triggered_slot(QAction * action) {
|
---|
146 | if (action->data().isValid()) {
|
---|
147 | QString file = action->data().toString();
|
---|
148 | emit activated( file );
|
---|
149 | current_file = file;;
|
---|
150 | markCurrent();
|
---|
151 | }
|
---|
152 | }
|
---|
153 |
|
---|
154 | void Favorites::markCurrent() {
|
---|
155 | for (int n = FIRST_MENU_ENTRY; n < actions().count(); n++) {
|
---|
156 | QAction * a = actions()[n];
|
---|
157 | QString file = a->data().toString();
|
---|
158 | QFont f = a->font();
|
---|
159 |
|
---|
160 | if ((!file.isEmpty()) && (file == current_file)) {
|
---|
161 | f.setBold(true);
|
---|
162 | a->setFont( f );
|
---|
163 | } else {
|
---|
164 | f.setBold(false);
|
---|
165 | a->setFont( f );
|
---|
166 | }
|
---|
167 | }
|
---|
168 | }
|
---|
169 |
|
---|
170 | int Favorites::findFile(QString filename) {
|
---|
171 | for (int n = 0; n < f_list.count(); n++) {
|
---|
172 | if (f_list[n].file() == filename) return n;
|
---|
173 | }
|
---|
174 | return -1;
|
---|
175 | }
|
---|
176 |
|
---|
177 | bool Favorites::anyItemAvailable() {
|
---|
178 | if (f_list.isEmpty()) return false;
|
---|
179 |
|
---|
180 | bool item_available = false;
|
---|
181 | for (int n = 0; n < f_list.count(); n++) {
|
---|
182 | if (!f_list[n].isSubentry()) {
|
---|
183 | item_available = true;
|
---|
184 | break;
|
---|
185 | }
|
---|
186 | }
|
---|
187 |
|
---|
188 | return item_available;
|
---|
189 | }
|
---|
190 |
|
---|
191 | void Favorites::next() {
|
---|
192 | qDebug("Favorites::next");
|
---|
193 |
|
---|
194 | if (!anyItemAvailable()) return;
|
---|
195 |
|
---|
196 | int current = findFile(current_file);
|
---|
197 |
|
---|
198 | int i = current;
|
---|
199 | if (current < 0) current = 0;
|
---|
200 |
|
---|
201 | do {
|
---|
202 | i++;
|
---|
203 | if (i == current) break;
|
---|
204 | if (i >= f_list.count()) i = 0;
|
---|
205 | } while (f_list[i].isSubentry());
|
---|
206 |
|
---|
207 | QAction * a = actions()[i+FIRST_MENU_ENTRY]; // Skip "edit" and separator
|
---|
208 | if (a != 0) {
|
---|
209 | a->trigger();
|
---|
210 | }
|
---|
211 | }
|
---|
212 |
|
---|
213 | void Favorites::previous() {
|
---|
214 | qDebug("Favorites::previous");
|
---|
215 |
|
---|
216 | if (!anyItemAvailable()) return;
|
---|
217 |
|
---|
218 | int current = findFile(current_file);
|
---|
219 |
|
---|
220 | int i = current;
|
---|
221 | if (current < 0) current = 0;
|
---|
222 |
|
---|
223 | do {
|
---|
224 | i--;
|
---|
225 | if (i == current) break;
|
---|
226 | if (i < 0) i = f_list.count()-1;
|
---|
227 | } while (f_list[i].isSubentry());
|
---|
228 |
|
---|
229 | QAction * a = actions()[i+FIRST_MENU_ENTRY]; // Skip "edit" and separator
|
---|
230 | if (a != 0) {
|
---|
231 | a->trigger();
|
---|
232 | }
|
---|
233 | }
|
---|
234 |
|
---|
235 | void Favorites::getCurrentMedia(const QString & filename, const QString & title) {
|
---|
236 | qDebug("Favorites::getCurrentMedia: '%s', '%s'", filename.toUtf8().constData(), title.toUtf8().constData());
|
---|
237 |
|
---|
238 | if (!filename.isEmpty()) {
|
---|
239 | received_file_playing = filename;
|
---|
240 | received_title = title;
|
---|
241 |
|
---|
242 | emit sendCurrentMedia(filename, title);
|
---|
243 |
|
---|
244 | add_current_act->setEnabled(true);
|
---|
245 | }
|
---|
246 | }
|
---|
247 |
|
---|
248 | void Favorites::addCurrentPlaying() {
|
---|
249 | if (received_file_playing.isEmpty()) {
|
---|
250 | qDebug("Favorites::addCurrentPlaying: received file is empty, doing nothing");
|
---|
251 | } else {
|
---|
252 | Favorite fav;
|
---|
253 | fav.setName(received_title);
|
---|
254 | fav.setFile(received_file_playing);
|
---|
255 | f_list.append(fav);
|
---|
256 | save();
|
---|
257 | updateMenu();
|
---|
258 | }
|
---|
259 | }
|
---|
260 |
|
---|
261 | void Favorites::save() {
|
---|
262 | qDebug("Favorites::save");
|
---|
263 |
|
---|
264 | QFile f( _filename );
|
---|
265 | if ( f.open( QIODevice::WriteOnly ) ) {
|
---|
266 | QTextStream stream( &f );
|
---|
267 | stream.setCodec("UTF-8");
|
---|
268 |
|
---|
269 | stream << "#EXTM3U" << "\n";
|
---|
270 | for (int n = 0; n < f_list.count(); n++) {
|
---|
271 | stream << "#EXTINF:0,";
|
---|
272 | stream << f_list[n].name() << ",";
|
---|
273 | stream << f_list[n].icon() << ",";
|
---|
274 | stream << f_list[n].isSubentry() << "\n";
|
---|
275 | stream << f_list[n].file() << "\n";
|
---|
276 | }
|
---|
277 | f.close();
|
---|
278 | }
|
---|
279 | }
|
---|
280 |
|
---|
281 | void Favorites::load() {
|
---|
282 | qDebug("Favorites::load");
|
---|
283 |
|
---|
284 | QRegExp m3u_id("^#EXTM3U|^#M3U");
|
---|
285 | QRegExp info1("^#EXTINF:(.*),(.*),(.*)");
|
---|
286 | QRegExp info2("^#EXTINF:(.*),(.*),(.*),(.*)");
|
---|
287 |
|
---|
288 | QFile f( _filename );
|
---|
289 | if ( f.open( QIODevice::ReadOnly ) ) {
|
---|
290 |
|
---|
291 | f_list.clear();
|
---|
292 |
|
---|
293 | Favorite fav;
|
---|
294 |
|
---|
295 | QTextStream stream( &f );
|
---|
296 | stream.setCodec("UTF-8");
|
---|
297 |
|
---|
298 | QString line;
|
---|
299 | while ( !stream.atEnd() ) {
|
---|
300 | line = stream.readLine(); // line of text excluding '\n'
|
---|
301 | //qDebug("info2.indexIn: %d", info2.indexIn(line));
|
---|
302 | //qDebug("info1.indexIn: %d", info1.indexIn(line));
|
---|
303 | //qDebug( " * line: '%s'", line.toUtf8().data() );
|
---|
304 | if (m3u_id.indexIn(line)!=-1) {
|
---|
305 | //#EXTM3U
|
---|
306 | // Ignore line
|
---|
307 | }
|
---|
308 | else
|
---|
309 | if (info2.indexIn(line) != -1) {
|
---|
310 | fav.setName( info2.cap(2) );
|
---|
311 | fav.setIcon( info2.cap(3) );
|
---|
312 | fav.setSubentry( info2.cap(4).toInt() == 1 );
|
---|
313 | }
|
---|
314 | else
|
---|
315 | // Compatibility with old files
|
---|
316 | if (info1.indexIn(line) != -1) {
|
---|
317 | fav.setName( info1.cap(2) );
|
---|
318 | fav.setIcon( info1.cap(3) );
|
---|
319 | fav.setSubentry( false );
|
---|
320 | }
|
---|
321 | else
|
---|
322 | if (line.startsWith("#")) {
|
---|
323 | // Comment
|
---|
324 | // Ignore
|
---|
325 | } else {
|
---|
326 | fav.setFile( line );
|
---|
327 | if (fav.name().isEmpty()) fav.setName(line);
|
---|
328 | //qDebug("Favorites::load: adding '%s' '%s'", fav.name().toUtf8().constData(), fav.file().toUtf8().constData());
|
---|
329 | f_list.append(fav);
|
---|
330 |
|
---|
331 | // Clear data
|
---|
332 | fav.setName("");
|
---|
333 | fav.setFile("");
|
---|
334 | fav.setIcon("");
|
---|
335 | fav.setSubentry(false);
|
---|
336 | }
|
---|
337 | }
|
---|
338 | f.close();
|
---|
339 | }
|
---|
340 | }
|
---|
341 |
|
---|
342 | void Favorites::edit() {
|
---|
343 | qDebug("Favorites::edit");
|
---|
344 |
|
---|
345 | FavoriteEditor e(parent_widget);
|
---|
346 |
|
---|
347 | e.setData(f_list);
|
---|
348 | e.setStorePath( QFileInfo(_filename).absolutePath() );
|
---|
349 |
|
---|
350 | if (e.exec() == QDialog::Accepted) {
|
---|
351 | f_list = e.data();
|
---|
352 | save();
|
---|
353 | updateMenu();
|
---|
354 | /*
|
---|
355 | for (int n = 0; n < f_list.count(); n++) {
|
---|
356 | qDebug("item %d: name: '%s' file: '%s'", n, f_list[n].name().toUtf8().constData(), f_list[n].file().toUtf8().constData());
|
---|
357 | }
|
---|
358 | */
|
---|
359 | }
|
---|
360 | }
|
---|
361 |
|
---|
362 | void Favorites::jump() {
|
---|
363 | qDebug("Favorites::jump");
|
---|
364 |
|
---|
365 | bool ok;
|
---|
366 | int item = QInputDialog::getInteger(parent_widget, tr("Jump to item"),
|
---|
367 | tr("Enter the number of the item in the list to jump:"),
|
---|
368 | last_item, 1, f_list.count(), 1, &ok);
|
---|
369 | if (ok) {
|
---|
370 | last_item = item;
|
---|
371 | item--;
|
---|
372 | actions()[item+FIRST_MENU_ENTRY]->trigger();
|
---|
373 | }
|
---|
374 | }
|
---|
375 |
|
---|
376 | // Language change stuff
|
---|
377 | void Favorites::changeEvent(QEvent *e) {
|
---|
378 | if (e->type() == QEvent::LanguageChange) {
|
---|
379 | retranslateStrings();
|
---|
380 | } else {
|
---|
381 | QWidget::changeEvent(e);
|
---|
382 | }
|
---|
383 | }
|
---|
384 |
|
---|
385 | #include "moc_favorites.cpp"
|
---|
386 |
|
---|