Improved random mode
authorNikolay Tischenko <niktischenko@gmail.com>
Tue, 28 Sep 2010 14:59:00 +0000 (21:59 +0700)
committerNikolay Tischenko <niktischenko@gmail.com>
Tue, 28 Sep 2010 14:59:00 +0000 (21:59 +0700)
Improved save playlist dialog

someplayer.pro
src/mainwindow.cpp
src/mediascanner.cpp
src/player/player.cpp
src/player/player.h
src/saveplaylistdialog.cpp [new file with mode: 0644]
src/saveplaylistdialog.h [new file with mode: 0644]
src/tagresolver.cpp
src/ui/saveplaylistdialog.ui [new file with mode: 0644]

index 32a62e7..cc7fa1b 100644 (file)
@@ -118,7 +118,8 @@ SOURCES += src/main.cpp\
     src/taglib/wavpack/wavpackfile.cpp \
     src/edittagsdialog.cpp \
     src/timerdialog.cpp \
-    src/equalizerdialog.cpp
+    src/equalizerdialog.cpp \
+    src/saveplaylistdialog.cpp
 
 HEADERS  += src/mainwindow.h \
                src/player/player.h \
@@ -214,7 +215,8 @@ HEADERS  += src/mainwindow.h \
     src/taglib/wavpack/wavpackfile.h \
     src/edittagsdialog.h \
     src/timerdialog.h \
-    src/equalizerdialog.h
+    src/equalizerdialog.h \
+    src/saveplaylistdialog.h
 
 FORMS    += src/ui/mainwindow.ui \
     src/ui/playerform.ui \
@@ -223,7 +225,8 @@ FORMS    += src/ui/mainwindow.ui \
     src/ui/playlistdialog.ui \
     src/ui/edittagsdialog.ui \
     src/ui/timerdialog.ui \
-    src/ui/equalizerdialog.ui
+    src/ui/equalizerdialog.ui \
+    src/ui/saveplaylistdialog.ui
 
 CONFIG += mobility
 MOBILITY = 
index 8f88fc6..688e1ae 100644 (file)
@@ -29,6 +29,7 @@
 #include "library.h"
 #include "timerdialog.h"
 #include "equalizerdialog.h"
+#include "saveplaylistdialog.h"
 
 using namespace SomePlayer::DataObjects;
 using namespace SomePlayer::Storage;
@@ -125,30 +126,35 @@ void MainWindow::_add_directory() {
 }
 
 void MainWindow::_save_playlist() {
-       QString name = QInputDialog::getText(this, "Playlist name", "Name:");
        QList<QString> playlists = _library->getPlaylistsNames();
-       bool append = false;
-       if (playlists.contains(name)) {
-               if (QMessageBox::question(this, "Append to playlist?", "Playlist with name \""+name+"\" already exists.\n"
-                                         "Dow you want to append current playlist to it?",
-                                         QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) {
-                       append = true;
-               } else {
-                       append = false;
+       playlists.removeOne(_CURRENT_PLAYLIST_SUBST_);
+       SavePlaylistDialog dialog(this);
+       dialog.setPlaylistNames(playlists);
+       if (dialog.exec() == QDialog::Accepted) {
+               QString name = dialog.selectedName();
+               bool append = false;
+               if (playlists.contains(name)) {
+                       if (QMessageBox::question(this, "Append to playlist?", "Playlist with name \""+name+"\" already exists.\n"
+                                                 "Dow you want to append current playlist to it?",
+                                                 QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) {
+                               append = true;
+                       } else {
+                               append = false;
+                       }
                }
-       }
-       if (append) {
-               Playlist cur = _library->getCurrentPlaylist();
-               Playlist target = _library->getPlaylist(name);
-               QList<Track> tracks = cur.tracks();
-               foreach (Track track, tracks) {
-                       target.addTrack(track);
+               if (append) {
+                       Playlist cur = _library->getCurrentPlaylist();
+                       Playlist target = _library->getPlaylist(name);
+                       QList<Track> tracks = cur.tracks();
+                       foreach (Track track, tracks) {
+                               target.addTrack(track);
+                       }
+                       _library->savePlaylist(target);
+               } else {
+                       Playlist playlist = _library->getCurrentPlaylist();
+                       playlist.setName(name);
+                       _library->savePlaylist(playlist);
                }
-               _library->savePlaylist(target);
-       } else {
-               Playlist playlist = _library->getCurrentPlaylist();
-               playlist.setName(name);
-               _library->savePlaylist(playlist);
        }
 }
 
index 1b84640..f6a32c1 100644 (file)
@@ -27,7 +27,7 @@ using namespace SomePlayer::Storage;
 MediaScanner::MediaScanner(QObject *parent) :
                QThread(parent), _stopped(false), _initialized(false)
 {
-       REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "acc" << "ogg";
+       REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "aac" << "ogg";
 }
 
 void MediaScanner::run() {
index 17976ba..6aa78d6 100644 (file)
@@ -29,6 +29,40 @@ using namespace SomePlayer::Playback;
 using namespace SomePlayer::DataObjects;
 using namespace SomePlayer::Storage;
 
+int Randomizer::next() {
+       int res = 0;
+       if (_current == _rand.count()) {
+               _shuffle();
+               _current = 0;
+               res = next();
+       } else {
+               res = _rand.at(_current);
+       }
+       ++_current;
+       return res;
+}
+
+void Randomizer::setPlaylist(QList<int> pl) {
+       _playlist = pl;
+       _current = 0;
+       _shuffle();
+}
+
+void Randomizer::_shuffle() {
+       _rand.clear();
+       // Fisher-Yates algorithm:
+       _rand = _playlist;
+       int cnt = _playlist.count();
+       int j = 0;
+       int tmp = 0;
+       for (int i = cnt-1; i > 0; i--) {
+               j = qrand() % (i+1);
+               tmp = _rand[i];
+               _rand[i] = _rand[j];
+               _rand[j] = tmp;
+       }
+}
+
 Player::Player(QObject *parent) :
     QObject(parent)
 {
@@ -105,7 +139,7 @@ void Player::next() {
                _current = _prev_history.pop();
        } else {
                if (_random) {
-                       _current = (count + (qrand()  + qrand() + qrand()) % count) % count;
+                       _current = _randomizer.next();
                } else {
                        _current = _current + 1;
                }
@@ -180,6 +214,12 @@ void Player::setPlaylist(Playlist playlist) {
        _history.clear();
        _prev_history.clear();
        _queue.clear();
+       QList<int> ids;
+       int count = playlist.tracks().count();
+       for (int i = 0; i < count; i++) {
+               ids.append(i);
+       }
+       _randomizer.setPlaylist(ids);
 }
 
 void Player::seek(int s) {
index 50ab1f8..be12b08 100644 (file)
@@ -45,6 +45,17 @@ namespace SomePlayer {
 
                enum PlayerState { PLAYER_STOPPED, PLAYER_PLAYING, PLAYER_PAUSED, PLAYER_LOADING, PLAYER_DONE, PLAYER_ERROR };
 
+               class Randomizer {
+               public:
+                       void setPlaylist(QList<int>);
+                       int next();
+               private:
+                       QList<int> _playlist;
+                       QList<int> _rand;
+                       void _shuffle();
+                       int _current;
+               };
+
                class Player : public QObject
                {
                        Q_OBJECT
@@ -85,6 +96,7 @@ namespace SomePlayer {
                        void _stateChanged(Phonon::State, Phonon::State);
                        void _tick(qint64);
                private:
+                       Randomizer _randomizer;
                        int _current;
                        Track _track; // current track (workaround)
                        bool _random;
diff --git a/src/saveplaylistdialog.cpp b/src/saveplaylistdialog.cpp
new file mode 100644 (file)
index 0000000..06dfa0b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SomePlayer - An alternate music player for Maemo 5
+ * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "saveplaylistdialog.h"
+#include "ui_saveplaylistdialog.h"
+
+SavePlaylistDialog::SavePlaylistDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::SavePlaylistDialog)
+{
+       ui->setupUi(this);
+       selectedItem = "";
+       connect(ui->listWidget, SIGNAL(activated(QModelIndex)), this, SLOT(_select_item(QModelIndex)));
+}
+
+SavePlaylistDialog::~SavePlaylistDialog()
+{
+       delete ui;
+}
+
+void SavePlaylistDialog::setPlaylistNames(QList<QString> names) {
+       ui->listWidget->addItems(names);
+       ui->lineEdit->setText("New playlist");
+}
+
+QString SavePlaylistDialog::selectedName() {
+       if (selectedItem.isEmpty())
+               return ui->lineEdit->text();
+       else return ui->listWidget->selectedItems().at(0)->text();
+}
+
+void SavePlaylistDialog::_select_item(QModelIndex id) {
+       selectedItem = id.data().toString();
+       done(QDialog::Accepted);
+}
+
diff --git a/src/saveplaylistdialog.h b/src/saveplaylistdialog.h
new file mode 100644 (file)
index 0000000..8479153
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SomePlayer - An alternate music player for Maemo 5
+ * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef SAVEPLAYLISTDIALOG_H
+#define SAVEPLAYLISTDIALOG_H
+
+#include <QDialog>
+#include <QList>
+#include <QModelIndex>
+
+namespace Ui {
+       class SavePlaylistDialog;
+}
+
+class SavePlaylistDialog : public QDialog
+{
+       Q_OBJECT
+
+public:
+       explicit SavePlaylistDialog(QWidget *parent = 0);
+       ~SavePlaylistDialog();
+       void setPlaylistNames(QList<QString>);
+       QString selectedName();
+
+private slots:
+       void _select_item(QModelIndex);
+private:
+       Ui::SavePlaylistDialog *ui;
+       QString selectedItem;
+};
+
+#endif // SAVEPLAYLISTDIALOG_H
index a91c8e2..170296d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "tagresolver.h"
 #include <QFile>
+#include <QFileInfo>
 #include <tag.h>
 #include <fileref.h>
 
@@ -45,6 +46,14 @@ void TagResolver::decode(QStringList files) {
                                        emit decoded(track);
                                }
                        }
+               } else { // workaround
+                       TrackMetadata meta;
+                       meta.setLength(0);
+                       QFileInfo fi(filename);
+                       meta.setArtist(fi.suffix().toUpper());
+                       meta.setTitle(fi.baseName());
+                       Track track(0, meta, filename);
+                       emit decoded(track);
                }
        }
        emit done();
diff --git a/src/ui/saveplaylistdialog.ui b/src/ui/saveplaylistdialog.ui
new file mode 100644 (file)
index 0000000..cc12090
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SavePlaylistDialog</class>
+ <widget class="QDialog" name="SavePlaylistDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Save playlist</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Existed playlists:</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QListWidget" name="listWidget"/>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>New: </string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="lineEdit"/>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>SavePlaylistDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>SavePlaylistDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>