Ability to sort cur.playlist by long tap on it
authorNikolay Tischenko <niktischenko@gmail.com>
Sun, 26 Dec 2010 20:32:01 +0000 (02:32 +0600)
committerNikolay Tischenko <niktischenko@gmail.com>
Sun, 26 Dec 2010 20:32:01 +0000 (02:32 +0600)
Manual sorting and autosorting: alphabet (asc/desc),
artists/album, shuffle

20 files changed:
resources/black/arrow_bottom.png [new file with mode: 0644]
resources/black/arrow_top.png [new file with mode: 0644]
resources/black/sort_alpha_asc.png [new file with mode: 0644]
resources/black/sort_alpha_desc.png [new file with mode: 0644]
resources/resources.qrc
resources/someplayer_ru.ts
resources/white/arrow_bottom.png [new file with mode: 0644]
resources/white/arrow_top.png [new file with mode: 0644]
resources/white/sort_alpha_asc.png [new file with mode: 0644]
resources/white/sort_alpha_desc.png [new file with mode: 0644]
someplayer.pro
src/playerform.cpp
src/playerform.h
src/playlistsortform.cpp [new file with mode: 0644]
src/playlistsortform.h [new file with mode: 0644]
src/track.cpp
src/track.h
src/trackrenderer.cpp
src/ui/playerform.ui
src/ui/playlistsortform.ui [new file with mode: 0644]

diff --git a/resources/black/arrow_bottom.png b/resources/black/arrow_bottom.png
new file mode 100644 (file)
index 0000000..751d013
Binary files /dev/null and b/resources/black/arrow_bottom.png differ
diff --git a/resources/black/arrow_top.png b/resources/black/arrow_top.png
new file mode 100644 (file)
index 0000000..2e4685a
Binary files /dev/null and b/resources/black/arrow_top.png differ
diff --git a/resources/black/sort_alpha_asc.png b/resources/black/sort_alpha_asc.png
new file mode 100644 (file)
index 0000000..1e5c971
Binary files /dev/null and b/resources/black/sort_alpha_asc.png differ
diff --git a/resources/black/sort_alpha_desc.png b/resources/black/sort_alpha_desc.png
new file mode 100644 (file)
index 0000000..03aae09
Binary files /dev/null and b/resources/black/sort_alpha_desc.png differ
index 2b1e138..9150bda 100644 (file)
         <file>white/fav.png</file>
         <file>black/tags.png</file>
         <file>white/tags.png</file>
+        <file>black/sort_alpha_asc.png</file>
+        <file>white/sort_alpha_asc.png</file>
+        <file>black/sort_alpha_desc.png</file>
+        <file>white/sort_alpha_desc.png</file>
+        <file>black/arrow_bottom.png</file>
+        <file>black/arrow_top.png</file>
+        <file>white/arrow_top.png</file>
+        <file>white/arrow_bottom.png</file>
     </qresource>
     <qresource prefix="/images">
         <file>defaultcover.png</file>
index 577727e..fd01b5a 100644 (file)
@@ -501,72 +501,72 @@ By Nikolay Tischenko (somebody)&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;b
         <translation>Выключение: 00:00:00</translation>
     </message>
     <message>
-        <location filename="../src/ui/playerform.ui" line="484"/>
+        <location filename="../src/ui/playerform.ui" line="472"/>
         <source>0/0</source>
         <translation>0/0</translation>
     </message>
     <message>
-        <location filename="../src/ui/playerform.ui" line="520"/>
+        <location filename="../src/ui/playerform.ui" line="508"/>
         <source>&lt;h3&gt;Title&lt;/h3&gt;</source>
         <translation>&lt;h3&gt;Название&lt;/h3&gt;</translation>
     </message>
     <message>
-        <location filename="../src/ui/playerform.ui" line="547"/>
-        <location filename="../src/ui/playerform.ui" line="567"/>
+        <location filename="../src/ui/playerform.ui" line="535"/>
+        <location filename="../src/ui/playerform.ui" line="555"/>
         <source>00:00</source>
         <translation>00:00</translation>
     </message>
     <message>
-        <location filename="../src/ui/playerform.ui" line="643"/>
+        <location filename="../src/ui/playerform.ui" line="631"/>
         <source>&lt;b&gt;Artist&lt;/b&gt;&lt;br/&gt;album</source>
         <translation>&lt;b&gt;Исполнитель&lt;/b&gt;&lt;br/&gt;альбом</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="90"/>
-        <location filename="../src/playerform.cpp" line="750"/>
+        <location filename="../src/playerform.cpp" line="91"/>
+        <location filename="../src/playerform.cpp" line="762"/>
         <source>Clear playlist</source>
         <translation>Очистить плейлист</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="91"/>
-        <location filename="../src/playerform.cpp" line="751"/>
+        <location filename="../src/playerform.cpp" line="92"/>
+        <location filename="../src/playerform.cpp" line="763"/>
         <source>Delete</source>
         <translation>Удалить</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="92"/>
-        <location filename="../src/playerform.cpp" line="231"/>
-        <location filename="../src/playerform.cpp" line="306"/>
-        <location filename="../src/playerform.cpp" line="752"/>
+        <location filename="../src/playerform.cpp" line="93"/>
+        <location filename="../src/playerform.cpp" line="239"/>
+        <location filename="../src/playerform.cpp" line="314"/>
+        <location filename="../src/playerform.cpp" line="764"/>
         <source>Add to favorites</source>
         <translation>В избранное</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="93"/>
-        <location filename="../src/playerform.cpp" line="753"/>
+        <location filename="../src/playerform.cpp" line="94"/>
+        <location filename="../src/playerform.cpp" line="765"/>
         <source>Enqueue</source>
         <translation>В очередь</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="94"/>
-        <location filename="../src/playerform.cpp" line="754"/>
+        <location filename="../src/playerform.cpp" line="95"/>
+        <location filename="../src/playerform.cpp" line="766"/>
         <source>Add to playlists</source>
         <translation>Добавить в плейлисты</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="95"/>
-        <location filename="../src/playerform.cpp" line="755"/>
+        <location filename="../src/playerform.cpp" line="96"/>
+        <location filename="../src/playerform.cpp" line="767"/>
         <source>Edit tags</source>
         <translation>Редактировать теги</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="231"/>
-        <location filename="../src/playerform.cpp" line="306"/>
+        <location filename="../src/playerform.cpp" line="239"/>
+        <location filename="../src/playerform.cpp" line="314"/>
         <source>Remove from favorites</source>
         <translation>Удалить из избранного</translation>
     </message>
     <message>
-        <location filename="../src/playerform.cpp" line="267"/>
+        <location filename="../src/playerform.cpp" line="275"/>
         <source>Delete track?</source>
         <translation>Удалить трек?</translation>
     </message>
@@ -580,6 +580,14 @@ By Nikolay Tischenko (somebody)&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;b
     </message>
 </context>
 <context>
+    <name>PlaylistSortForm</name>
+    <message>
+        <location filename="../src/ui/playlistsortform.ui" line="14"/>
+        <source>Sorting</source>
+        <translation>Сортировка</translation>
+    </message>
+</context>
+<context>
     <name>QObject</name>
     <message>
         <location filename="../src/libraryform.cpp" line="65"/>
diff --git a/resources/white/arrow_bottom.png b/resources/white/arrow_bottom.png
new file mode 100644 (file)
index 0000000..a37a806
Binary files /dev/null and b/resources/white/arrow_bottom.png differ
diff --git a/resources/white/arrow_top.png b/resources/white/arrow_top.png
new file mode 100644 (file)
index 0000000..8a66151
Binary files /dev/null and b/resources/white/arrow_top.png differ
diff --git a/resources/white/sort_alpha_asc.png b/resources/white/sort_alpha_asc.png
new file mode 100644 (file)
index 0000000..6ccdc5e
Binary files /dev/null and b/resources/white/sort_alpha_asc.png differ
diff --git a/resources/white/sort_alpha_desc.png b/resources/white/sort_alpha_desc.png
new file mode 100644 (file)
index 0000000..449280c
Binary files /dev/null and b/resources/white/sort_alpha_desc.png differ
index eb13cc2..26ec243 100644 (file)
@@ -129,7 +129,8 @@ SOURCES += src/main.cpp\
     src/settingsform.cpp \
     src/dbusclient.cpp \
     src/fmtxsettingsdialog.cpp \
-    src/aboutform.cpp
+    src/aboutform.cpp \
+    src/playlistsortform.cpp
 
 HEADERS  += src/mainwindow.h \
                src/player/player.h \
@@ -237,7 +238,8 @@ HEADERS  += src/mainwindow.h \
     src/settingsform.h \
     src/dbusclient.h \
     src/fmtxsettingsdialog.h \
-    src/aboutform.h
+    src/aboutform.h \
+    src/playlistsortform.h
 
 FORMS    += src/ui/mainwindow.ui \
     src/ui/playerform.ui \
@@ -253,7 +255,8 @@ FORMS    += src/ui/mainwindow.ui \
     src/ui/directoryview.ui \
     src/ui/settingsform.ui \
     src/ui/fmtxsettingsdialog.ui \
-    src/ui/aboutform.ui
+    src/ui/aboutform.ui \
+    src/ui/playlistsortform.ui
 
 CONFIG += mobility
 MOBILITY = 
index 945e380..538ae17 100644 (file)
@@ -46,6 +46,7 @@ inline void __fill_list(QStandardItemModel *_model, Playlist playlist) {
                time.setHMS(0, meta.length()/60, meta.length() % 60);
                QString t = meta.title()+"#_#"+meta.artist()+"#_#"+meta.album()+"#_#"+time.toString("mm:ss");
                _model->setItem(i, 1, new QStandardItem(t));
+               _model->setItem(i, 0, new QStandardItem("##arrow_r.png"));
        }
 }
 
@@ -111,9 +112,12 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) :
        _cover->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        _cover->setPixmap(QPixmap::fromImage(_coverfinder->defaultCover()));
 
+       _pls_sort_form = new PlaylistSortForm(parent);
+       _pls_sort_form->hide();
+
        connect(ui->libraryButton, SIGNAL(clicked()), this, SLOT(_library()));
        connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_toggle_view()));
-       connect(ui->playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(_process_click(QModelIndex)));
+       connect(ui->playlistView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_click(QModelIndex)));
        connect(ui->playpauseButton, SIGNAL(clicked()), _player, SLOT(toggle()));
        connect(ui->nextButton, SIGNAL(clicked()), _player, SLOT(next()));
        connect(ui->stopButton, SIGNAL(clicked()), _player, SLOT(stop()));
@@ -123,7 +127,7 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) :
        connect(ui->randomButton, SIGNAL(clicked()), this, SLOT(_toggle_random()));
        connect(ui->repeatButton, SIGNAL(clicked()), this, SLOT(_toggle_repeat()));
        connect(ui->seekSlider, SIGNAL(sliderMoved(int)), _player, SLOT(seek(int)));
-       connect(ui->playlistView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(_custom_context_menu_requested(QPoint)));
+       connect(ui->playlistView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(_sort_playlist()));
        connect(__clear_playlist, SIGNAL(triggered()), this, SIGNAL(clearPlaylist()));
        connect(__delete_action, SIGNAL(triggered()), this, SLOT(_delete_track()));
        connect(__enqueue_action, SIGNAL(triggered()), this, SLOT(_enqueue_track()));
@@ -150,6 +154,7 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) :
        connect(_cover, SIGNAL(clicked()), this, SLOT(_toggle_extra_buttons()));
        connect(_player, SIGNAL(startPlaylist()), this, SLOT(_start_playlist()));
        connect(_player, SIGNAL(saveLastPlayed(LastPlayed)), _lib, SLOT(saveLastPlayedForCurPlaylist(LastPlayed)));
+       connect(_pls_sort_form, SIGNAL(playlistChanged()), this, SLOT(_playlist_sorted()));
        ui->viewButton->setIcon(QIcon(":/icons/"+_icons_theme+"/playback.png"));
        _top_gradient = ui->topWidget->styleSheet();
        _bottom_gradient = ui->bottomWidget->styleSheet();
@@ -209,6 +214,9 @@ void PlayerForm::_toggle_view() {
 }
 
 void PlayerForm::_process_click(QModelIndex index) {
+       if (_pls_sort_form->isVisible()) {
+               return;
+       }
        if (index.column() == 1) {
                int id = index.row();
                _player->setTrackId(id);
@@ -503,6 +511,7 @@ void PlayerForm::landscapeMode() {
        } else {
                ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/more.png"));
        }
+       _pls_sort_form->landscapeMode();
 }
 
 void PlayerForm::portraitMode() {
@@ -578,6 +587,7 @@ void PlayerForm::portraitMode() {
        } else {
                ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/more.png"));
        }
+       _pls_sort_form->portraitMode();
 }
 
 void PlayerForm::_tools_widget_toggle() {
@@ -646,6 +656,7 @@ void PlayerForm::updateIcons() {
        } else {
                ui->randomButton->setIcon(QIcon(":/icons/"+_icons_theme+"/random_off.png"));
        }
+       _pls_sort_form->updateIcons();
 }
 
 void PlayerForm::checkGradient() {
@@ -657,6 +668,7 @@ void PlayerForm::checkGradient() {
                ui->topWidget->setStyleSheet("");
                ui->bottomWidget->setStyleSheet("");
        }
+       _pls_sort_form->updateGradiend();
 }
 
 void PlayerForm::play(Track track) {
@@ -753,6 +765,7 @@ void PlayerForm::updateTranslations() {
        __enqueue_action->setText(tr("Enqueue"));
        __add_to_playlists->setText(tr("Add to playlists"));
        __edit_tags->setText(tr("Edit tags"));
+       _pls_sort_form->updateTranslations();
 }
 
 void PlayerForm::updateTrackColor() {
@@ -786,3 +799,17 @@ void PlayerForm::_start_playlist() {
        _player->setTrackId(lp.trackId);
        _player->setAwaitingSeek(lp.position);
 }
+
+void PlayerForm::_sort_playlist() {
+       _pls_sort_form->setPlaylist(_current_playlist);
+       _pls_sort_form->show();
+}
+
+void PlayerForm::_playlist_sorted() {
+       _current_playlist = _pls_sort_form->getPlaylist();
+       _lib->saveCurrentPlaylist(_current_playlist);
+       _player->setPlaylist(_current_playlist);
+       __fill_list(_model, _current_playlist);
+       ui->playlistView->setColumnWidth(0, 50);
+       _track_renderer->setActiveRow(_current_playlist.tracks().indexOf(_player->current()));
+}
index a5fa890..9606b77 100644 (file)
@@ -35,6 +35,7 @@
 #include "toolswidget.h"
 #include "coverfinder.h"
 #include "clickablelabel.h"
+#include "playlistsortform.h"
 
 namespace Ui {
     class PlayerForm;
@@ -116,6 +117,8 @@ private slots:
        void _display_cover(QImage);
        void _toggle_extra_buttons();
        void _start_playlist();
+       void _sort_playlist();
+       void _playlist_sorted();
 
 private:
     Ui::PlayerForm *ui;
@@ -150,6 +153,8 @@ private:
        int _search_current_id;
 
        DBusAdaptop *_dbusadaptor;
+
+       PlaylistSortForm *_pls_sort_form;
 };
 
 #endif // PLAYERFORM_H
diff --git a/src/playlistsortform.cpp b/src/playlistsortform.cpp
new file mode 100644 (file)
index 0000000..e39a455
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * 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 "playlistsortform.h"
+#include "ui_playlistsortform.h"
+#include <QTime>
+#include "track.h"
+#include <QDebug>
+#include "config.h"
+
+using namespace SomePlayer::DataObjects;
+using namespace SomePlayer::Storage;
+
+inline void __fill_model(QStandardItemModel *_model, Playlist playlist) {
+       _model->clear();
+       QList<Track> tracks = playlist.tracks();
+       int count = tracks.count();
+       _model->setRowCount(count);
+       _model->setColumnCount(2);
+       QTime time;
+       for (int i = 0; i < count; i++) {
+               TrackMetadata meta = tracks.at(i).metadata();
+               time.setHMS(0, meta.length()/60, meta.length() % 60);
+               QString t = meta.title()+"#_#"+meta.artist()+"#_#"+meta.album()+"#_#"+time.toString("mm:ss");
+               _model->setItem(i, 1, new QStandardItem(t));
+               _model->setItem(i, 0, new QStandardItem("##deselect_all.png"));
+       }
+}
+
+PlaylistSortForm::PlaylistSortForm(QWidget *parent) :
+               QWidget(parent),
+               ui(new Ui::PlaylistSortForm)
+{
+       ui->setupUi(this);
+       setAttribute(Qt::WA_Maemo5StackedWindow);
+       setWindowFlags(Qt::Window | windowFlags());
+       _track_renderer = new TrackRenderer(this);
+       _track_renderer->setActiveRow(-1);
+       _track_renderer->setSearchRow(-1);
+       ui->playlistView->setItemDelegateForColumn(0, _track_renderer);
+       ui->playlistView->setItemDelegateForColumn(1, _track_renderer);
+       _model = new QStandardItemModel(this);
+       ui->playlistView->setModel(_model);
+       _top_gradient = ui->topWidget->styleSheet();
+       _bottom_gradient = ui->bottomWidget->styleSheet();
+
+       connect(ui->doneButton, SIGNAL(clicked()), this, SLOT(done()));
+       connect(ui->playlistView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+               this, SLOT(_process_selection(QItemSelection,QItemSelection)));
+       connect(ui->moveDownButton, SIGNAL(clicked()), this, SLOT(moveDown()));
+       connect(ui->moveTopButton, SIGNAL(clicked()), this, SLOT(moveUp()));
+       connect(ui->sortAlphAscButton, SIGNAL(clicked()), this, SLOT(sortAlphAsc()));
+       connect(ui->sortAlphDescButton, SIGNAL(clicked()), this, SLOT(sortAlphDesc()));
+       connect(ui->shuffleButton, SIGNAL(clicked()), this, SLOT(shuffle()));
+       connect(ui->artistsButton, SIGNAL(clicked()), this, SLOT(sortArtist()));
+}
+
+PlaylistSortForm::~PlaylistSortForm()
+{
+       delete ui;
+}
+
+void PlaylistSortForm::done() {
+       emit playlistChanged();
+       hide();
+}
+
+void PlaylistSortForm::setPlaylist(Playlist playlist) {
+       _playlist = playlist;
+       updateView();
+}
+
+Playlist PlaylistSortForm::getPlaylist() {
+       return _playlist;
+}
+
+void PlaylistSortForm::updateView() {
+       __fill_model(_model, _playlist);
+       ui->playlistView->setColumnWidth(0, 50);
+}
+
+void PlaylistSortForm::_process_selection(QItemSelection selected, QItemSelection deselected) {
+       foreach (QModelIndex id, selected.indexes()) {
+               if (id.column() == 0) {
+                       _model->item(id.row(), 0)->setText("##select_all.png");
+               }
+               ui->playlistView->selectionModel()->select(id, QItemSelectionModel::Select);
+       }
+       foreach (QModelIndex id, deselected.indexes()) {
+               if (id.column() == 0) {
+                       _model->item(id.row(), 0)->setText("##deselect_all.png");
+               }
+               ui->playlistView->selectionModel()->select(id, QItemSelectionModel::Deselect);
+       }
+}
+
+void PlaylistSortForm::moveDown() {
+       QModelIndexList idx = ui->playlistView->selectionModel()->selectedIndexes();
+       if (idx.isEmpty()) {
+               return;
+       }
+       QList<int> rows;
+       foreach (QModelIndex id, idx) {
+               if (id.column() == 1) {
+                       rows << id.row();
+               }
+       }
+       _move(rows, 1);
+}
+
+void PlaylistSortForm::moveUp() {
+       QModelIndexList idx = ui->playlistView->selectionModel()->selectedIndexes();
+       if (idx.isEmpty()) {
+               return;
+       }
+       QList<int> rows;
+       foreach (QModelIndex id, idx) {
+               if (id.column() == 1) {
+                       rows << id.row();
+               }
+       }
+       _move(rows, -1);
+}
+
+void PlaylistSortForm::sortAlphAsc() {
+       QList<Track> tracks = _playlist.tracks();
+       qSort(tracks);
+       _playlist.setTracks(tracks);
+       updateView();
+}
+
+void PlaylistSortForm::sortAlphDesc() {
+       QList<Track> tracks = _playlist.tracks();
+       qSort(tracks);
+       for(int i = 0; i < (tracks.size()/2); i++) {
+               tracks.swap(i,tracks.size()-(1+i));
+       }
+       _playlist.setTracks(tracks);
+       updateView();
+}
+
+void PlaylistSortForm::sortArtist() {
+       QList<Track> tracks = _playlist.tracks();
+       QList<Track> ntracks;
+       // first step: artists
+       QMap<QString, QList<Track> > artists_tracks;
+       foreach (Track t, tracks) {
+               artists_tracks[t.metadata().artist()].append(t);;
+       }
+       // second step: albums;
+       QMap<QString, QList<Track> > album_tracks;
+       QList<QString> artists = artists_tracks.keys();
+       qSort(artists);
+       foreach (QString artist, artists) {
+               album_tracks.clear();
+               foreach (Track t, artists_tracks[artist]) {
+                       album_tracks[t.metadata().album()].append(t);
+               }
+               QList<QString> albums = album_tracks.keys();
+               qSort(albums);
+               foreach (QString album, albums) {
+                       qWarning() << album;
+                       foreach (Track t, album_tracks[album]) {
+                               ntracks << t;
+                       }
+               }
+       }
+       _playlist.setTracks(ntracks);
+       updateView();
+}
+
+void PlaylistSortForm::shuffle() {
+       qsrand(QTime::currentTime().msec());
+       QList<Track> tracks = _playlist.tracks();
+       QList<Track> ntracks;
+       int size = tracks.size();
+       int pos = 0;
+       for (int i = 0; i < size; i++) {
+               pos = qrand() % tracks.count();
+               ntracks << tracks.at(pos);
+               tracks.removeAt(pos);
+       }
+       _playlist.setTracks(ntracks);
+       updateView();
+}
+
+void PlaylistSortForm::_move(QList<int> rows, int diff) {
+       qSort(rows);
+       QList<Track> tracks = _playlist.tracks();
+       if ((diff > 0 && (rows.last() == tracks.count()-diff)) ||
+           (diff < 0 && (rows.first() == -diff - 1))) {
+               return;
+       }
+       if (diff > 0) {
+               for (int i = rows.count()-1; i>=0; i--) {
+                       tracks.swap(rows[i], rows[i]+diff);
+                       rows[i] += diff;
+               }
+       } else {
+               for (int i = 0; i < rows.count(); i++) {
+                       tracks.swap(rows[i], rows[i]+diff);
+                       rows[i] += diff;
+               }
+       }
+       _playlist.setTracks(tracks);
+       updateView();
+       foreach (int i, rows) {
+               ui->playlistView->selectRow(i);
+       }
+       ui->playlistView->scrollTo(_model->index(rows[rows.count()/2], 0), QAbstractItemView::PositionAtCenter);
+}
+
+void PlaylistSortForm::landscapeMode() {
+       ui->topWidget->hide();
+       ui->bottomWidget->hide();
+       ui->bhorWidget->hide();
+
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
+       ui->topWidget->layout()->removeWidget(ui->sortAlphAscButton);
+       ui->topWidget->layout()->removeWidget(ui->sortAlphDescButton);
+       ui->topWidget->layout()->removeWidget(ui->artistsButton);
+
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_0);
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_1);
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_2);
+       ui->bottomWidget->layout()->removeWidget(ui->doneButton);
+       ui->bottomWidget->layout()->removeWidget(ui->moveDownButton);
+       ui->bottomWidget->layout()->removeWidget(ui->moveTopButton);
+       ui->bottomWidget->layout()->removeWidget(ui->shuffleButton);
+
+       ui->bhorWidget->layout()->removeWidget(ui->doneButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_0);
+       ui->bhorWidget->layout()->removeWidget(ui->moveTopButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_1);
+       ui->bhorWidget->layout()->removeWidget(ui->sortAlphAscButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_2);
+       ui->bhorWidget->layout()->removeWidget(ui->artistsButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_3);
+       ui->bhorWidget->layout()->removeWidget(ui->sortAlphDescButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_4);
+       ui->bhorWidget->layout()->removeWidget(ui->moveDownButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_5);
+       ui->bhorWidget->layout()->removeWidget(ui->shuffleButton);
+
+       ui->bhorWidget->layout()->addWidget(ui->doneButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_0);
+       ui->bhorWidget->layout()->addWidget(ui->sortAlphAscButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_1);
+       ui->bhorWidget->layout()->addWidget(ui->moveTopButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_2);
+       ui->bhorWidget->layout()->addWidget(ui->artistsButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_3);
+       ui->bhorWidget->layout()->addWidget(ui->moveDownButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_4);
+       ui->bhorWidget->layout()->addWidget(ui->sortAlphDescButton);
+       ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_5);
+       ui->bhorWidget->layout()->addWidget(ui->shuffleButton);
+
+       ui->bhorWidget->show();
+}
+
+void PlaylistSortForm::portraitMode() {
+       ui->topWidget->hide();
+       ui->bottomWidget->hide();
+       ui->bhorWidget->hide();
+
+       ui->bhorWidget->layout()->removeWidget(ui->doneButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_0);
+       ui->bhorWidget->layout()->removeWidget(ui->moveTopButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_1);
+       ui->bhorWidget->layout()->removeWidget(ui->sortAlphAscButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_2);
+       ui->bhorWidget->layout()->removeWidget(ui->artistsButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_3);
+       ui->bhorWidget->layout()->removeWidget(ui->sortAlphDescButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_4);
+       ui->bhorWidget->layout()->removeWidget(ui->moveDownButton);
+       ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_5);
+       ui->bhorWidget->layout()->removeWidget(ui->shuffleButton);
+
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
+       ui->topWidget->layout()->removeWidget(ui->sortAlphAscButton);
+       ui->topWidget->layout()->removeWidget(ui->sortAlphDescButton);
+       ui->topWidget->layout()->removeWidget(ui->artistsButton);
+
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_0);
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_1);
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_2);
+       ui->bottomWidget->layout()->removeWidget(ui->doneButton);
+       ui->bottomWidget->layout()->removeWidget(ui->moveDownButton);
+       ui->bottomWidget->layout()->removeWidget(ui->moveTopButton);
+       ui->bottomWidget->layout()->removeWidget(ui->shuffleButton);
+
+       ui->topWidget->layout()->addWidget(ui->sortAlphAscButton);
+       ui->topWidget->layout()->addItem(ui->thorizontalSpacer_0);
+       ui->topWidget->layout()->addWidget(ui->artistsButton);
+       ui->topWidget->layout()->addItem(ui->thorizontalSpacer_1);
+       ui->topWidget->layout()->addWidget(ui->sortAlphDescButton);
+
+       ui->bottomWidget->layout()->addWidget(ui->doneButton);
+       ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_0);
+       ui->bottomWidget->layout()->addWidget(ui->moveDownButton);
+       ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_1);
+       ui->bottomWidget->layout()->addWidget(ui->moveTopButton);
+       ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_2);
+       ui->bottomWidget->layout()->addWidget(ui->shuffleButton);
+
+       ui->topWidget->show();
+       ui->bottomWidget->show();
+}
+
+void PlaylistSortForm::updateTranslations() {
+       ui->retranslateUi(this);
+}
+
+void PlaylistSortForm::updateGradiend() {
+       Config config;
+       if (config.getValue("ui/gradient").toString() == "yes") {
+               ui->bottomWidget->setStyleSheet(_bottom_gradient);
+               ui->topWidget->setStyleSheet(_top_gradient);
+       } else {
+               ui->topWidget->setStyleSheet("");
+               ui->bottomWidget->setStyleSheet("");
+       }
+}
+
+void PlaylistSortForm::updateIcons() {
+       Config config;
+       QString icons_theme = config.getValue("ui/iconstheme").toString();
+       ui->doneButton->setIcon(QIcon(":/icons/"+icons_theme+"/use.png"));
+       ui->moveDownButton->setIcon(QIcon(":/icons/"+icons_theme+"/arrow_bottom.png"));
+       ui->moveTopButton->setIcon(QIcon(":/icons/"+icons_theme+"/arrow_top.png"));
+       ui->shuffleButton->setIcon(QIcon(":/icons/"+icons_theme+"/random_on.png"));
+       ui->sortAlphAscButton->setIcon(QIcon(":/icons/"+icons_theme+"/sort_alpha_asc.png"));
+       ui->sortAlphDescButton->setIcon(QIcon(":/icons/"+icons_theme+"/sort_alpha_desc.png"));
+       ui->artistsButton->setIcon(QIcon(":/icons/"+icons_theme+"/artists.png"));
+}
diff --git a/src/playlistsortform.h b/src/playlistsortform.h
new file mode 100644 (file)
index 0000000..ee2727a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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 PLAYLISTSORTFORM_H
+#define PLAYLISTSORTFORM_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QStandardItem>
+#include <QItemSelection>
+#include <QItemSelectionModel>
+#include "someplayer.h"
+#include "playlist.h"
+#include "trackrenderer.h"
+
+using SomePlayer::DataObjects::Playlist;
+
+namespace Ui {
+       class PlaylistSortForm;
+}
+
+class PlaylistSortForm : public QWidget
+{
+       Q_OBJECT
+
+public:
+       explicit PlaylistSortForm(QWidget *parent = 0);
+       ~PlaylistSortForm();
+       void setPlaylist(Playlist playlist);
+       Playlist getPlaylist();
+
+private slots:
+       void done();
+       void updateView();
+       void _process_selection(QItemSelection,QItemSelection);
+       void moveUp();
+       void moveDown();
+       void sortAlphAsc();
+       void sortAlphDesc();
+       void sortArtist();
+       void shuffle();
+
+public slots:
+       void landscapeMode();
+       void portraitMode();
+       void updateTranslations();
+       void updateGradiend();
+       void updateIcons();
+
+signals:
+       void playlistChanged();
+
+private:
+       Ui::PlaylistSortForm *ui;
+       Playlist _playlist;
+       TrackRenderer *_track_renderer;
+       QStandardItemModel *_model;
+       void _move(QList<int> rows, int diff);
+       QString _bottom_gradient;
+       QString _top_gradient;
+};
+
+#endif // PLAYLISTSORTFORM_H
index 50f5315..0f36353 100644 (file)
@@ -91,6 +91,14 @@ Track &Track::operator =(const Track &track) {
 
 Track::~Track() {}
 
-bool Track::operator ==(const Track &track) {
+bool Track::operator ==(const Track &track) const {
        return _source == track._source;
 }
+
+bool Track::operator >= (const Track &track) const {
+       return (metadata().title().compare(track.metadata().title()) >= 0);
+}
+
+bool Track::operator < (const Track &track) const {
+       return (metadata().title().compare(track.metadata().title()) < 0);
+}
index cd9c307..54810dc 100644 (file)
@@ -46,7 +46,9 @@ namespace SomePlayer {
                        void setSource (QString source);
                        int count() const; //count of plays
                        void setCount(int count); //for restoring from database and counting from player
-                       bool operator == (const Track &track);
+                       bool operator == (const Track &track) const;
+                       bool operator >= (const Track &track) const; // comparing only title
+                       bool operator < (const Track &track) const; // comparing only title
 
                private:
                        TrackMetadata _metadata;
index 3a72ef8..a09fee0 100644 (file)
@@ -44,15 +44,16 @@ void TrackRenderer::updateIcons() {
 }
 
 void TrackRenderer::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
-       if (index.column() == 0) {
+       QString value = index.data().toString();
+       if (value.startsWith("##")) {
+               value.remove("##");
                int x1, y1, x2, y2;
                option.rect.getCoords(&x1, &y1, &x2, &y2);
-               QImage image(":/icons/"+_icons_theme+"/arrow_r.png");
+               QImage image(":/icons/"+_icons_theme+"/"+value);
                x1 += (x2 - x1 - image.width())/2;
                y1 += (y2 - y1 - image.width())/2;
                painter->drawImage(x1, y1, image);
        } else {
-               QString value = index.data().toString();
                QStringList meta = value.split("#_#");
 
                QFont f = painter->font();
index fe140ca..cac7122 100644 (file)
            <property name="editTriggers">
             <set>QAbstractItemView::NoEditTriggers</set>
            </property>
-           <property name="showDropIndicator" stdset="0">
-            <bool>false</bool>
-           </property>
-           <property name="dragEnabled">
-            <bool>false</bool>
-           </property>
-           <property name="dragDropOverwriteMode">
-            <bool>false</bool>
-           </property>
-           <property name="dragDropMode">
-            <enum>QAbstractItemView::NoDragDrop</enum>
-           </property>
            <property name="selectionMode">
             <enum>QAbstractItemView::SingleSelection</enum>
            </property>
diff --git a/src/ui/playlistsortform.ui b/src/ui/playlistsortform.ui
new file mode 100644 (file)
index 0000000..aa0b5a1
--- /dev/null
@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PlaylistSortForm</class>
+ <widget class="QWidget" name="PlaylistSortForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Sorting</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QWidget" name="topWidget" native="true">
+     <property name="styleSheet">
+      <string notr="true">background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(38, 38, 38, 255), stop:1 rgba(92, 92, 92, 255))</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_4">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QPushButton" name="sortAlphAscButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/sort_alpha_asc.png</normaloff>:/icons/white/sort_alpha_asc.png</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>48</width>
+          <height>58</height>
+         </size>
+        </property>
+        <property name="checkable">
+         <bool>false</bool>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="thorizontalSpacer_0">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="artistsButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/artists.png</normaloff>:/icons/white/artists.png</iconset>
+        </property>
+        <property name="checkable">
+         <bool>false</bool>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="thorizontalSpacer_1">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="sortAlphDescButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/sort_alpha_desc.png</normaloff>:/icons/white/sort_alpha_desc.png</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>48</width>
+          <height>48</height>
+         </size>
+        </property>
+        <property name="checkable">
+         <bool>false</bool>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTableView" name="playlistView">
+     <property name="contextMenuPolicy">
+      <enum>Qt::CustomContextMenu</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Sunken</enum>
+     </property>
+     <property name="horizontalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOff</enum>
+     </property>
+     <property name="autoScroll">
+      <bool>false</bool>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::MultiSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectRows</enum>
+     </property>
+     <property name="iconSize">
+      <size>
+       <width>50</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="showGrid">
+      <bool>false</bool>
+     </property>
+     <property name="cornerButtonEnabled">
+      <bool>false</bool>
+     </property>
+     <attribute name="horizontalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="horizontalHeaderStretchLastSection">
+      <bool>true</bool>
+     </attribute>
+     <attribute name="verticalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="verticalHeaderDefaultSectionSize">
+      <number>70</number>
+     </attribute>
+     <attribute name="verticalHeaderMinimumSectionSize">
+      <number>70</number>
+     </attribute>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="bhorWidget" native="true">
+     <layout class="QHBoxLayout" name="bhorizontalLayout">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="chorizontalSpacer_0">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <spacer name="chorizontalSpacer_1">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <spacer name="chorizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <spacer name="chorizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <spacer name="chorizontalSpacer_4">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <spacer name="chorizontalSpacer_5">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="bottomWidget" native="true">
+     <property name="minimumSize">
+      <size>
+       <width>78</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">background:qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 rgba(38, 38, 38, 255), stop:1 rgba(92, 92, 92, 255))</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QPushButton" name="doneButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/use.png</normaloff>:/icons/white/use.png</iconset>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="bhorizontalSpacer_0">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="moveTopButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/arrow_top.png</normaloff>:/icons/white/arrow_top.png</iconset>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="bhorizontalSpacer_1">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="moveDownButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/arrow_bottom.png</normaloff>:/icons/white/arrow_bottom.png</iconset>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="bhorizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="shuffleButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>70</width>
+          <height>70</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../../resources/resources.qrc">
+          <normaloff>:/icons/white/random_on.png</normaloff>:/icons/white/random_on.png</iconset>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../resources/resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>