1 | /* smplayer, GUI front-end for mplayer.
|
---|
2 | Copyright (C) 2006-2014 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 |
|
---|
106 | if (f_list[n].file() == _filename) {
|
---|
107 | qDebug("Favorites::populateMenu: infinite recursion detected. Ignoring item.");
|
---|
108 | break;
|
---|
109 | }
|
---|
110 |
|
---|
111 | Favorites * new_fav = createNewObject(f_list[n].file(), parent_widget);
|
---|
112 | new_fav->getCurrentMedia(received_file_playing, received_title);
|
---|
113 | connect(this, SIGNAL(sendCurrentMedia(const QString &, const QString &)),
|
---|
114 | new_fav, SLOT(getCurrentMedia(const QString &, const QString &)));
|
---|
115 | /*
|
---|
116 | new_fav->editAct()->setText( editAct()->text() );
|
---|
117 | new_fav->jumpAct()->setText( jumpAct()->text() );
|
---|
118 | new_fav->nextAct()->setText( nextAct()->text() );
|
---|
119 | new_fav->previousAct()->setText( previousAct()->text() );
|
---|
120 | new_fav->addCurrentAct()->setText( addCurrentAct()->text() );
|
---|
121 | */
|
---|
122 |
|
---|
123 | child.push_back(new_fav);
|
---|
124 |
|
---|
125 | QAction * a = addMenu( new_fav );
|
---|
126 | a->setText( name );
|
---|
127 | a->setIcon( QIcon( f_list[n].icon() ) );
|
---|
128 | } else {
|
---|
129 | QAction * a = addAction( name );
|
---|
130 | a->setData( f_list[n].file() );
|
---|
131 | a->setIcon( QIcon( f_list[n].icon() ) );
|
---|
132 | a->setStatusTip( f_list[n].file() );
|
---|
133 | }
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 | void Favorites::updateMenu() {
|
---|
138 | // Remove all except the first 2 items
|
---|
139 | while (actions().count() > FIRST_MENU_ENTRY) {
|
---|
140 | QAction * a = actions()[FIRST_MENU_ENTRY];
|
---|
141 | removeAction( a );
|
---|
142 | a->deleteLater();
|
---|
143 | }
|
---|
144 |
|
---|
145 | delete_children();
|
---|
146 |
|
---|
147 | populateMenu();
|
---|
148 | markCurrent();
|
---|
149 | }
|
---|
150 |
|
---|
151 | void Favorites::triggered_slot(QAction * action) {
|
---|
152 | if (action->data().isValid()) {
|
---|
153 | QString file = action->data().toString();
|
---|
154 | emit activated( file );
|
---|
155 | current_file = file;;
|
---|
156 | markCurrent();
|
---|
157 | }
|
---|
158 | }
|
---|
159 |
|
---|
160 | void Favorites::markCurrent() {
|
---|
161 | for (int n = FIRST_MENU_ENTRY; n < actions().count(); n++) {
|
---|
162 | QAction * a = actions()[n];
|
---|
163 | QString file = a->data().toString();
|
---|
164 | QFont f = a->font();
|
---|
165 |
|
---|
166 | if ((!file.isEmpty()) && (file == current_file)) {
|
---|
167 | f.setBold(true);
|
---|
168 | a->setFont( f );
|
---|
169 | } else {
|
---|
170 | f.setBold(false);
|
---|
171 | a->setFont( f );
|
---|
172 | }
|
---|
173 | }
|
---|
174 | }
|
---|
175 |
|
---|
176 | int Favorites::findFile(QString filename) {
|
---|
177 | for (int n = 0; n < f_list.count(); n++) {
|
---|
178 | if (f_list[n].file() == filename) return n;
|
---|
179 | }
|
---|
180 | return -1;
|
---|
181 | }
|
---|
182 |
|
---|
183 | bool Favorites::anyItemAvailable() {
|
---|
184 | if (f_list.isEmpty()) return false;
|
---|
185 |
|
---|
186 | bool item_available = false;
|
---|
187 | for (int n = 0; n < f_list.count(); n++) {
|
---|
188 | if (!f_list[n].isSubentry()) {
|
---|
189 | item_available = true;
|
---|
190 | break;
|
---|
191 | }
|
---|
192 | }
|
---|
193 |
|
---|
194 | return item_available;
|
---|
195 | }
|
---|
196 |
|
---|
197 | void Favorites::next() {
|
---|
198 | qDebug("Favorites::next");
|
---|
199 |
|
---|
200 | if (!anyItemAvailable()) return;
|
---|
201 |
|
---|
202 | int current = findFile(current_file);
|
---|
203 |
|
---|
204 | int i = current;
|
---|
205 | if (current < 0) current = 0;
|
---|
206 |
|
---|
207 | do {
|
---|
208 | i++;
|
---|
209 | if (i == current) break;
|
---|
210 | if (i >= f_list.count()) i = 0;
|
---|
211 | } while (f_list[i].isSubentry());
|
---|
212 |
|
---|
213 | QAction * a = actions()[i+FIRST_MENU_ENTRY]; // Skip "edit" and separator
|
---|
214 | if (a != 0) {
|
---|
215 | a->trigger();
|
---|
216 | }
|
---|
217 | }
|
---|
218 |
|
---|
219 | void Favorites::previous() {
|
---|
220 | qDebug("Favorites::previous");
|
---|
221 |
|
---|
222 | if (!anyItemAvailable()) return;
|
---|
223 |
|
---|
224 | int current = findFile(current_file);
|
---|
225 |
|
---|
226 | int i = current;
|
---|
227 | if (current < 0) current = 0;
|
---|
228 |
|
---|
229 | do {
|
---|
230 | i--;
|
---|
231 | if (i == current) break;
|
---|
232 | if (i < 0) i = f_list.count()-1;
|
---|
233 | } while (f_list[i].isSubentry());
|
---|
234 |
|
---|
235 | QAction * a = actions()[i+FIRST_MENU_ENTRY]; // Skip "edit" and separator
|
---|
236 | if (a != 0) {
|
---|
237 | a->trigger();
|
---|
238 | }
|
---|
239 | }
|
---|
240 |
|
---|
241 | void Favorites::getCurrentMedia(const QString & filename, const QString & title) {
|
---|
242 | qDebug("Favorites::getCurrentMedia: '%s', '%s'", filename.toUtf8().constData(), title.toUtf8().constData());
|
---|
243 |
|
---|
244 | if (!filename.isEmpty()) {
|
---|
245 | received_file_playing = filename;
|
---|
246 | received_title = title;
|
---|
247 |
|
---|
248 | emit sendCurrentMedia(filename, title);
|
---|
249 |
|
---|
250 | add_current_act->setEnabled(true);
|
---|
251 | }
|
---|
252 | }
|
---|
253 |
|
---|
254 | void Favorites::addCurrentPlaying() {
|
---|
255 | if (received_file_playing.isEmpty()) {
|
---|
256 | qDebug("Favorites::addCurrentPlaying: received file is empty, doing nothing");
|
---|
257 | } else {
|
---|
258 | Favorite fav;
|
---|
259 | fav.setName(received_title.replace(",", ""));
|
---|
260 | fav.setFile(received_file_playing);
|
---|
261 | f_list.append(fav);
|
---|
262 | save();
|
---|
263 | updateMenu();
|
---|
264 | }
|
---|
265 | }
|
---|
266 |
|
---|
267 | void Favorites::save() {
|
---|
268 | qDebug("Favorites::save");
|
---|
269 |
|
---|
270 | QFile f( _filename );
|
---|
271 | if ( f.open( QIODevice::WriteOnly ) ) {
|
---|
272 | QTextStream stream( &f );
|
---|
273 | stream.setCodec("UTF-8");
|
---|
274 |
|
---|
275 | stream << "#EXTM3U" << "\n";
|
---|
276 | for (int n = 0; n < f_list.count(); n++) {
|
---|
277 | stream << "#EXTINF:0,";
|
---|
278 | stream << f_list[n].name() << ",";
|
---|
279 | stream << f_list[n].icon() << ",";
|
---|
280 | stream << f_list[n].isSubentry() << "\n";
|
---|
281 | stream << f_list[n].file() << "\n";
|
---|
282 | }
|
---|
283 | f.close();
|
---|
284 | }
|
---|
285 | }
|
---|
286 |
|
---|
287 | void Favorites::load() {
|
---|
288 | qDebug("Favorites::load");
|
---|
289 |
|
---|
290 | QRegExp m3u_id("^#EXTM3U|^#M3U");
|
---|
291 | QRegExp info1("^#EXTINF:(.*),(.*),(.*)");
|
---|
292 | QRegExp info2("^#EXTINF:(.*),(.*),(.*),(.*)");
|
---|
293 |
|
---|
294 | QFile f( _filename );
|
---|
295 | if ( f.open( QIODevice::ReadOnly ) ) {
|
---|
296 |
|
---|
297 | f_list.clear();
|
---|
298 |
|
---|
299 | Favorite fav;
|
---|
300 |
|
---|
301 | QTextStream stream( &f );
|
---|
302 | stream.setCodec("UTF-8");
|
---|
303 |
|
---|
304 | QString line;
|
---|
305 | while ( !stream.atEnd() ) {
|
---|
306 | line = stream.readLine(); // line of text excluding '\n'
|
---|
307 | //qDebug("info2.indexIn: %d", info2.indexIn(line));
|
---|
308 | //qDebug("info1.indexIn: %d", info1.indexIn(line));
|
---|
309 | //qDebug( " * line: '%s'", line.toUtf8().data() );
|
---|
310 | if (m3u_id.indexIn(line)!=-1) {
|
---|
311 | //#EXTM3U
|
---|
312 | // Ignore line
|
---|
313 | }
|
---|
314 | else
|
---|
315 | if (info2.indexIn(line) != -1) {
|
---|
316 | fav.setName( info2.cap(2) );
|
---|
317 | fav.setIcon( info2.cap(3) );
|
---|
318 | fav.setSubentry( info2.cap(4).toInt() == 1 );
|
---|
319 | }
|
---|
320 | else
|
---|
321 | // Compatibility with old files
|
---|
322 | if (info1.indexIn(line) != -1) {
|
---|
323 | fav.setName( info1.cap(2) );
|
---|
324 | fav.setIcon( info1.cap(3) );
|
---|
325 | fav.setSubentry( false );
|
---|
326 | }
|
---|
327 | else
|
---|
328 | if (line.startsWith("#")) {
|
---|
329 | // Comment
|
---|
330 | // Ignore
|
---|
331 | } else {
|
---|
332 | fav.setFile( line );
|
---|
333 | if (fav.name().isEmpty()) fav.setName(line);
|
---|
334 | //qDebug("Favorites::load: adding '%s' '%s'", fav.name().toUtf8().constData(), fav.file().toUtf8().constData());
|
---|
335 | f_list.append(fav);
|
---|
336 |
|
---|
337 | // Clear data
|
---|
338 | fav.setName("");
|
---|
339 | fav.setFile("");
|
---|
340 | fav.setIcon("");
|
---|
341 | fav.setSubentry(false);
|
---|
342 | }
|
---|
343 | }
|
---|
344 | f.close();
|
---|
345 | }
|
---|
346 | }
|
---|
347 |
|
---|
348 | void Favorites::edit() {
|
---|
349 | qDebug("Favorites::edit");
|
---|
350 |
|
---|
351 | FavoriteEditor e(parent_widget);
|
---|
352 |
|
---|
353 | e.setData(f_list);
|
---|
354 | e.setStorePath( QFileInfo(_filename).absolutePath() );
|
---|
355 |
|
---|
356 | if (e.exec() == QDialog::Accepted) {
|
---|
357 | f_list = e.data();
|
---|
358 | save();
|
---|
359 | updateMenu();
|
---|
360 | /*
|
---|
361 | for (int n = 0; n < f_list.count(); n++) {
|
---|
362 | qDebug("item %d: name: '%s' file: '%s'", n, f_list[n].name().toUtf8().constData(), f_list[n].file().toUtf8().constData());
|
---|
363 | }
|
---|
364 | */
|
---|
365 | }
|
---|
366 | }
|
---|
367 |
|
---|
368 | void Favorites::jump() {
|
---|
369 | qDebug("Favorites::jump");
|
---|
370 |
|
---|
371 | bool ok;
|
---|
372 | #if QT_VERSION >= 0x050000
|
---|
373 | int item = QInputDialog::getInt(parent_widget, tr("Jump to item"),
|
---|
374 | tr("Enter the number of the item in the list to jump:"),
|
---|
375 | last_item, 1, f_list.count(), 1, &ok);
|
---|
376 | #else
|
---|
377 | int item = QInputDialog::getInteger(parent_widget, tr("Jump to item"),
|
---|
378 | tr("Enter the number of the item in the list to jump:"),
|
---|
379 | last_item, 1, f_list.count(), 1, &ok);
|
---|
380 | #endif
|
---|
381 | if (ok) {
|
---|
382 | last_item = item;
|
---|
383 | item--;
|
---|
384 | actions()[item+FIRST_MENU_ENTRY]->trigger();
|
---|
385 | }
|
---|
386 | }
|
---|
387 |
|
---|
388 | // Language change stuff
|
---|
389 | void Favorites::changeEvent(QEvent *e) {
|
---|
390 | if (e->type() == QEvent::LanguageChange) {
|
---|
391 | retranslateStrings();
|
---|
392 | } else {
|
---|
393 | QWidget::changeEvent(e);
|
---|
394 | }
|
---|
395 | }
|
---|
396 |
|
---|
397 | #include "moc_favorites.cpp"
|
---|
398 |
|
---|