[SCM] bangarang packaging branch, master, updated. debian/1.0.beta2-1-19-gd74ae09
ryanakca-guest at users.alioth.debian.org
ryanakca-guest at users.alioth.debian.org
Thu Jan 7 04:13:20 UTC 2010
The following commit has been merged in the master branch:
commit 15180ee4bca33277b82c732046b77dd518109ac3
Author: Ryan Kavanagh <ryanakca at kubuntu.org>
Date: Fri Jan 1 21:18:04 2010 -0500
Imported Upstream version 1.0~beta3
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ebc440..4247ac6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
PROJECT(Bangarang)
set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
-
+set( WITHTRANSLATIONS:BOOL YES )
FIND_PACKAGE(KDE4 REQUIRED)
FIND_PACKAGE(Nepomuk REQUIRED)
FIND_PACKAGE(KdeMultimedia REQUIRED)
@@ -10,6 +10,8 @@ INCLUDE(KDE4Defaults)
ADD_DEFINITIONS( ${QT_DEFINITIONS} ${KDE4_DEFINITIONS} )
+find_package(Taglib REQUIRED)
+
INCLUDE_DIRECTORIES(
${KDE4_INCLUDES}
${KDEMULTIMEDIA_INCLUDE_DIR}
@@ -19,62 +21,16 @@ INCLUDE_DIRECTORIES(
/usr/include/taglib
)
-SET(BangarangSources
- mainwindow.cpp
- main.cpp
- sensiblewidgets.cpp
- mediaitemdelegate.cpp
- nowplayingdelegate.cpp
- mediaview.cpp
- infomanager.cpp
- savedlistsmanager.cpp
- actionsmanager.cpp
- platform/mediaitemmodel.cpp
- platform/musiclistengine.cpp
- platform/videolistengine.cpp
- platform/filelistengine.cpp
- platform/cdlistengine.cpp
- platform/dvdlistengine.cpp
- platform/medialistsengine.cpp
- platform/audiostreamlistengine.cpp
- platform/nepomuklistengine.cpp
- platform/semanticslistengine.cpp
- platform/playlist.cpp
- platform/utilities.cpp
- platform/listengine.cpp
- platform/savedlistsengine.cpp
- platform/listenginefactory.cpp
- platform/mediaindexer.cpp
- platform/mediavocabulary.cpp
- platform/medialistcache.cpp
- platform/cachelistengine.cpp
- platform/audioclipslistengine.cpp
-)
-
-KDE4_ADD_UI_FILES(BangarangSources mainwindow.ui)
-
-kde4_add_app_icon(BangarangSources "${CMAKE_CURRENT_SOURCE_DIR}/hi*.png")
+add_subdirectory( icons )
+add_subdirectory( src )
-
-KDE4_ADD_EXECUTABLE(bangarang ${BangarangSources})
-
-TARGET_LINK_LIBRARIES(bangarang
- ${KDE4_KDEUI_LIBS}
- ${KDE4_KPARTS_LIBS}
- ${KDE4_PHONON_LIBS}
- ${NEPOMUK_LIBRARIES}
- ${KDEMULTIMEDIA_LIBRARIES}
- ${SOPRANO_LIBRARIES}
- ${TAGLIB_LIBRARIES}
- tag
-)
+find_package(Msgfmt REQUIRED)
+find_package(Gettext REQUIRED)
+add_subdirectory( translations )
########### install files ###############
-install(TARGETS bangarang ${INSTALL_TARGETS_DEFAULT_ARGS})
-install(FILES bangarang.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
+install(FILES data/bangarang.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
+install(FILES data/bangarang_play_dvd.desktop data/bangarang_play_cd.desktop DESTINATION ${DATA_INSTALL_DIR}/solid/actions)
#install(FILES <bangarangDataFilesHere> DESTINATION ${DATA_INSTALL_DIR}/bangarang)
#install(FILES bangarangrc DESTINATION ${CONFIG_INSTALL_DIR})
-
-kde4_install_icons( ${ICON_INSTALL_DIR} )
-
diff --git a/actionsmanager.cpp b/actionsmanager.cpp
deleted file mode 100644
index 607ff49..0000000
--- a/actionsmanager.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "actionsmanager.h"
-#include "platform/utilities.h"
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include "platform/mediaitemmodel.h"
-#include "platform/playlist.h"
-#include "infomanager.h"
-
-#include <KStandardDirs>
-#include <KMessageBox>
-#include <KHelpMenu>
-#include <KMenu>
-#include <KDebug>
-#include <QFile>
-
-ActionsManager::ActionsManager(MainWindow * parent) : QObject(parent)
-{
- m_parent = parent;
- ui = m_parent->ui;
-
- m_actionCollection = new KActionCollection(this);
-
- //Add standard quit shortcut
- m_quit = new QAction(this);
- m_quit->setShortcut(Qt::CTRL + Qt::Key_Q);
- connect(m_quit, SIGNAL(triggered()), qApp, SLOT(quit()));
- m_parent->addAction(m_quit);
- m_actionCollection->addAction(tr("Quit"), m_quit);
-
- //Play/Pause Action
- m_playPause = new QAction(this);
- m_playPause->setShortcut(Qt::Key_Space);
- connect(m_playPause, SIGNAL(triggered()), this, SLOT(simplePlayPause()));
- m_parent->addAction(m_playPause);
-
- //Play Next
- m_playNext = new QAction(KIcon("media-skip-forward"), tr("Play next"), this);
- m_playNext->setShortcut(Qt::Key_Right);
- connect(m_playNext, SIGNAL(triggered()), m_parent->playlist(), SLOT(playNext()));
- m_parent->addAction(m_playNext);
-
- //Play Previous
- m_playPrevious = new QAction(KIcon("media-skip-backward"), tr("Play previous"), this);
- m_playPrevious->setShortcut(Qt::Key_Left);
- connect(m_playPrevious, SIGNAL(triggered()), m_parent->playlist(), SLOT(playPrevious()));
- m_parent->addAction(m_playPrevious);
-
- //Mute
- m_mute = new QAction(this);
- m_mute->setShortcut(Qt::Key_M);
- connect(m_mute, SIGNAL(triggered()), this, SLOT(muteAudio()));
- m_parent->addAction(m_mute);
-
- //Play All Action
- m_playAllAction = new QAction(KIcon("media-playback-start"), tr("Play all"), this);
- connect(m_playAllAction, SIGNAL(triggered()), m_parent, SLOT(playAll()));
- m_actionCollection->addAction(tr("Play All"), m_playAllAction);
-
- //Play Selected Action
- m_playSelectedAction = new QAction(KIcon("media-playback-start"), tr("Play selected"), this);
- connect(m_playSelectedAction, SIGNAL(triggered()), m_parent, SLOT(playSelected()));
- m_actionCollection->addAction(tr("Play Selected"), m_playSelectedAction);
-
- //Add Selected To Playlist Action
- m_addSelectedToPlayListAction = new QAction(KIcon("mail-mark-notjunk"), tr("Add to playlist"), this);
- connect(m_addSelectedToPlayListAction, SIGNAL(triggered()), m_parent, SLOT(addSelectedToPlaylist()));
- m_actionCollection->addAction(tr("Add to playlist"), m_addSelectedToPlayListAction);
-
- //Remove Selected From Playlist Action
- m_removeSelectedToPlayListAction = new QAction(KIcon(), tr("Remove from playlist"), this);
- connect(m_removeSelectedToPlayListAction, SIGNAL(triggered()), m_parent, SLOT(removeSelectedFromPlaylist()));
- m_actionCollection->addAction(tr("Remove from playlist"), m_removeSelectedToPlayListAction);
-
- //Show/Hide Controls Shortcut
- m_showHideControls = new QAction(KIcon("layer-visible-off"), tr("Hide controls"), this);
- m_showHideControls->setShortcut(Qt::CTRL + Qt::Key_H);
- connect(m_showHideControls, SIGNAL(triggered()), this, SLOT(toggleControls()));
- m_parent->addAction(m_showHideControls);
- m_actionCollection->addAction(tr("Hide controls"), m_showHideControls);
-
-
- //Full Screen
- m_fullScreen = new QAction(this);
- m_fullScreen->setShortcut(Qt::Key_F11);
- connect(m_fullScreen, SIGNAL(triggered()), this, SLOT(fullScreenToggle()));
- m_parent->addAction(m_fullScreen);
- m_actionCollection->addAction(tr("Toggle fullscreen"), m_fullScreen);
-
- //Cancel FullScreen/Cancel Hide Controls
- m_cancelFullScreenHideControls = new QAction(this);
- m_cancelFullScreenHideControls->setShortcut(Qt::Key_Escape);
- connect(m_cancelFullScreenHideControls, SIGNAL(triggered()), this, SLOT(cancelFSHC()));
- m_parent->addAction(m_cancelFullScreenHideControls);
-
- //Remove Info for Selected MediaItems
- m_removeSelectedItemsInfo = new QAction(KIcon("edit-delete-shred"), tr("Remove selected info"), this);
- connect(m_removeSelectedItemsInfo, SIGNAL(triggered()), m_parent->infoManager(), SLOT(removeSelectedItemsInfo()));
- m_parent->addAction(m_removeSelectedItemsInfo);
-
- //Refresh Media View
- m_refreshMediaView = new QAction(KIcon("view-refresh"), tr("Refresh"), this);
- m_refreshMediaView->setShortcut(Qt::Key_F5);
- connect(m_refreshMediaView, SIGNAL(triggered()), m_parent->m_mediaItemModel, SLOT(reload()));
- m_parent->addAction(m_refreshMediaView);
-
- //Edit Shortcuts
- //FIXME: Need to figure out how to use KShortcutsEditor
- m_editShortcuts = new QAction(KIcon("configure-shortcuts"), tr("Configure shortcuts..."), this);
- connect(m_editShortcuts, SIGNAL(triggered()), this, SLOT(showShortcutsEditor()));
- connect(ui->cancelEditShortcuts, SIGNAL(clicked()), this, SLOT(hideShortcutsEditor()));
- ui->shortcutsEditor->addCollection(m_actionCollection);
-}
-
-ActionsManager::~ActionsManager()
-{
-}
-
-QAction * ActionsManager::quit()
-{
- return m_quit;
-}
-
-QAction * ActionsManager::playPause()
-{
- return m_playPause;
-}
-
-QAction * ActionsManager::playNext()
-{
- return m_playNext;
-}
-
-QAction * ActionsManager::playPrevious()
-{
- return m_playPrevious;
-}
-
-QAction * ActionsManager::mute()
-{
- return m_mute;
-}
-
-QAction * ActionsManager::playAll()
-{
- return m_playAllAction;
-}
-
-QAction * ActionsManager::playSelected()
-{
- return m_playSelectedAction;
-}
-
-QAction * ActionsManager::addSelectedToPlaylist()
-{
- return m_addSelectedToPlayListAction;
-}
-
-QAction * ActionsManager::removeSelectedFromPlaylist()
-{
- return m_removeSelectedToPlayListAction;
-}
-
-QAction * ActionsManager::showHideControls()
-{
- return m_showHideControls;
-}
-
-QAction * ActionsManager::fullScreen()
-{
- return m_fullScreen;
-}
-
-QAction * ActionsManager::cancelFullScreenHideControls()
-{
- return m_cancelFullScreenHideControls;
-}
-
-QAction * ActionsManager::editShortcuts()
-{
- return m_editShortcuts;
-}
-
-QAction * ActionsManager::removeSelectedItemsInfo()
-{
- return m_removeSelectedItemsInfo;
-}
-
-QAction * ActionsManager::refreshMediaView()
-{
- return m_refreshMediaView;
-}
-
-QMenu * ActionsManager::mediaViewMenu(bool showAbout)
-{
- KHelpMenu * helpMenu = new KHelpMenu(m_parent, m_parent->aboutData(), false);
- helpMenu->menu();
-
- QMenu *menu = new QMenu(m_parent);
- QString type;
- bool selection = false;
- if (ui->mediaView->selectionModel()->selectedIndexes().count() != 0) {
- QModelIndex index = ui->mediaView->selectionModel()->selectedIndexes().at(0);
- type = index.data(MediaItem::TypeRole).toString();
- selection = true;
- } else if (m_parent->m_mediaItemModel->rowCount() > 0) {
- type = m_parent->m_mediaItemModel->mediaItemAt(0).type;
- }
- bool isMedia = false;
- if ((type == "Audio") ||(type == "Video") || (type == "Image")) {
- isMedia = true;
- }
- bool isCategory = false;
- if (type == "Category") {
- isCategory = true;
- }
- if (isMedia || isCategory) {
- if (selection && isMedia) {
- menu->addAction(addSelectedToPlaylist());
- menu->addAction(removeSelectedFromPlaylist());
- menu->addSeparator();
- }
- if (selection) menu->addAction(playSelected());
- menu->addAction(playAll());
- menu->addSeparator();
- if (selection && isMedia) {
- menu->addAction(removeSelectedItemsInfo());
- menu->addSeparator();
- }
- menu->addAction(refreshMediaView());
- menu->addSeparator();
-
- }
- if (showAbout) menu->addAction(helpMenu->action(KHelpMenu::menuAboutApp));
- return menu;
-}
-
-//------------------
-//-- Action SLOTS --
-//------------------
-
-void ActionsManager::fullScreenToggle()
-{
- if (m_parent->isFullScreen()) {
- m_parent->on_fullScreen_toggled(false);
- } else {
- m_parent->on_fullScreen_toggled(true);
- }
-}
-
-void ActionsManager::toggleControls()
-{
- if ((!m_parent->isFullScreen()) && (ui->stackedWidget->currentIndex() == 1)) {
- if (ui->widgetSet->isVisible()) {
- ui->widgetSet->setVisible(false);
- ui->nowPlayingToolbar->setVisible(false);
- m_showHideControls->setIcon(KIcon("layer-visible-on"));
- } else {
- ui->widgetSet->setVisible(true);
- ui->nowPlayingToolbar->setVisible(true);
- m_showHideControls->setIcon(KIcon("layer-visible-off"));
- }
- }
-}
-
-void ActionsManager::cancelFSHC()
-{
- if (m_parent->isFullScreen()) {
- m_parent->on_fullScreen_toggled(false);
- } else {
- if (ui->stackedWidget->currentIndex() == 1) {
- ui->widgetSet->setVisible(true);
- ui->nowPlayingToolbar->setVisible(true);
- m_showHideControls->setIcon(KIcon("layer-visible-off"));
- }
- }
-}
-
-void ActionsManager::showShortcutsEditor()
-{
- ui->contextStack->setCurrentIndex(2);
- ui->contextStack->setVisible(true);
-}
-
-void ActionsManager::hideShortcutsEditor()
-{
- ui->contextStack->setCurrentIndex(0);
- ui->contextStack->setVisible(false);
-}
-
-void ActionsManager::simplePlayPause()
-{
- if (m_parent->playlist()->mediaObject()->state() == Phonon::PlayingState) {
- m_parent->playlist()->mediaObject()->pause();
- } else if (m_parent->playlist()->mediaObject()->state() == Phonon::PausedState) {
- m_parent->playlist()->mediaObject()->play();
- }
-}
-
-void ActionsManager::muteAudio()
-{
- bool muted = m_parent->audioOutput()->isMuted();
- m_parent->audioOutput()->setMuted(!muted);
-}
diff --git a/bangarang.desktop b/bangarang.desktop
deleted file mode 100644
index 08d943e..0000000
--- a/bangarang.desktop
+++ /dev/null
@@ -1,29 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-[Desktop Entry]
-Type=Application
-Version=1.0
-Name=Bangarang
-GenericName=Media Player
-Icon=bangarang
-X-DocPath=bangarang/index.html
-TryExec=bangarang
-Exec=bangarang %u
-MimeType=video/ogg;video/x-theora+ogg;video/x-ogm+ogg;video/x-ms-wmv;video/x-msvideo;video/x-ms-asf;video/x-matroska;video/mpeg;video/avi;video/quicktime;video/vnd.rn-realvideo;video/x-flic;video/mp4;video/divx;video/x-msvideo;video/x-wmv;video/x-flv;video/flv;audio/mpeg;audio/mp4;audio/ogg;audio/vorbis;audio/aac;audio/aiff;audio/basic;audio/flac;audio/mp2;audio/mp3;audio/vnd.rn-realaudio;audio/wav;application/ogg;audio/x-flac;audio/x-musepack
-Categories=Qt;KDE;AudioVideo;Player;
\ No newline at end of file
diff --git a/data/bangarang.desktop b/data/bangarang.desktop
new file mode 100644
index 0000000..2db1305
--- /dev/null
+++ b/data/bangarang.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Type=Application
+Version=1.0
+Name=Bangarang
+GenericName=Media Player
+GenericName[nl]=Mediaspeler
+Icon=bangarang
+X-DocPath=bangarang/index.html
+TryExec=bangarang
+Exec=bangarang %u
+MimeType=video/ogg;video/x-theora+ogg;video/x-ogm+ogg;video/x-ms-wmv;video/x-msvideo;video/x-ms-asf;video/x-matroska;video/mpeg;video/avi;video/quicktime;video/vnd.rn-realvideo;video/x-flic;video/mp4;video/divx;video/x-msvideo;video/x-wmv;video/x-flv;video/flv;audio/mpeg;audio/mp4;audio/ogg;audio/vorbis;audio/aac;audio/aiff;audio/basic;audio/flac;audio/mp2;audio/mp3;audio/vnd.rn-realaudio;audio/wav;application/ogg;audio/x-flac;audio/x-musepack;audio/m3u;audio/x-mpegurl;audio/x-scpls
+Categories=Qt;KDE;AudioVideo;Player;
\ No newline at end of file
diff --git a/bangarang.svg b/data/bangarang.svg
similarity index 100%
rename from bangarang.svg
rename to data/bangarang.svg
diff --git a/data/bangarang_play_cd.desktop b/data/bangarang_play_cd.desktop
new file mode 100644
index 0000000..f7a7c1d
--- /dev/null
+++ b/data/bangarang_play_cd.desktop
@@ -0,0 +1,11 @@
+[Desktop Action open]
+Exec=bangarang --play-cd %u
+Icon=bangarang
+Name=Play CD with Bangarang
+Name[nl]=CD afspelen met Bangarang
+
+[Desktop Entry]
+Actions=open;
+Type=Service
+X-KDE-Action-Custom=true
+X-KDE-Solid-Predicate=[ OpticalDisc.availableContent == 'Audio' AND StorageVolume.ignored == false ]
diff --git a/data/bangarang_play_dvd.desktop b/data/bangarang_play_dvd.desktop
new file mode 100644
index 0000000..051e9be
--- /dev/null
+++ b/data/bangarang_play_dvd.desktop
@@ -0,0 +1,12 @@
+[Desktop Action open]
+Exec=bangarang --play-dvd %u
+Icon=bangarang
+Name=Play DVD with Bangarang
+Name[nl]=DVD afspelen met Bangarang
+X-Ubuntu-Gettext-Domain=desktop_kdebase-workspace
+
+[Desktop Entry]
+Actions=open;
+Type=Service
+X-KDE-Action-Custom=true
+X-KDE-Solid-Predicate=[ OpticalDisc.availableContent == 'Data|VideoDvd' AND StorageVolume.ignored == false ]
diff --git a/icons/CMakeLists.txt b/icons/CMakeLists.txt
new file mode 100644
index 0000000..ea5a81e
--- /dev/null
+++ b/icons/CMakeLists.txt
@@ -0,0 +1,11 @@
+PROJECT(Bangarang)
+
+set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
+
+FIND_PACKAGE(KDE4 REQUIRED)
+
+INCLUDE(KDE4Defaults)
+
+ADD_DEFINITIONS( ${QT_DEFINITIONS} ${KDE4_DEFINITIONS} )
+
+kde4_install_icons( ${ICON_INSTALL_DIR} )
diff --git a/bangarang-svgexport.png b/icons/bangarang-svgexport.png
similarity index 100%
rename from bangarang-svgexport.png
rename to icons/bangarang-svgexport.png
diff --git a/hi128-app-bangarang.png b/icons/hi128-app-bangarang.png
similarity index 100%
rename from hi128-app-bangarang.png
rename to icons/hi128-app-bangarang.png
diff --git a/hi16-app-bangarang.png b/icons/hi16-app-bangarang.png
similarity index 100%
rename from hi16-app-bangarang.png
rename to icons/hi16-app-bangarang.png
diff --git a/hi16-status-bangarang-loading-0.png b/icons/hi16-status-bangarang-loading-0.png
similarity index 100%
rename from hi16-status-bangarang-loading-0.png
rename to icons/hi16-status-bangarang-loading-0.png
diff --git a/hi16-status-bangarang-loading-1.png b/icons/hi16-status-bangarang-loading-1.png
similarity index 100%
rename from hi16-status-bangarang-loading-1.png
rename to icons/hi16-status-bangarang-loading-1.png
diff --git a/hi16-status-bangarang-loading-2.png b/icons/hi16-status-bangarang-loading-2.png
similarity index 100%
rename from hi16-status-bangarang-loading-2.png
rename to icons/hi16-status-bangarang-loading-2.png
diff --git a/hi16-status-bangarang-loading-3.png b/icons/hi16-status-bangarang-loading-3.png
similarity index 100%
rename from hi16-status-bangarang-loading-3.png
rename to icons/hi16-status-bangarang-loading-3.png
diff --git a/hi16-status-bangarang-loading-4.png b/icons/hi16-status-bangarang-loading-4.png
similarity index 100%
rename from hi16-status-bangarang-loading-4.png
rename to icons/hi16-status-bangarang-loading-4.png
diff --git a/hi16-status-bangarang-loading-5.png b/icons/hi16-status-bangarang-loading-5.png
similarity index 100%
rename from hi16-status-bangarang-loading-5.png
rename to icons/hi16-status-bangarang-loading-5.png
diff --git a/hi16-status-bangarang-loading-6.png b/icons/hi16-status-bangarang-loading-6.png
similarity index 100%
rename from hi16-status-bangarang-loading-6.png
rename to icons/hi16-status-bangarang-loading-6.png
diff --git a/hi16-status-bangarang-loading-7.png b/icons/hi16-status-bangarang-loading-7.png
similarity index 100%
rename from hi16-status-bangarang-loading-7.png
rename to icons/hi16-status-bangarang-loading-7.png
diff --git a/hi22-actions-bangarang-clearplaylist.png b/icons/hi22-actions-bangarang-clearplaylist.png
similarity index 100%
rename from hi22-actions-bangarang-clearplaylist.png
rename to icons/hi22-actions-bangarang-clearplaylist.png
diff --git a/hi22-actions-bangarang-preview.png b/icons/hi22-actions-bangarang-preview.png
similarity index 100%
rename from hi22-actions-bangarang-preview.png
rename to icons/hi22-actions-bangarang-preview.png
diff --git a/hi22-actions-bangarang-repeat.png b/icons/hi22-actions-bangarang-repeat.png
similarity index 100%
rename from hi22-actions-bangarang-repeat.png
rename to icons/hi22-actions-bangarang-repeat.png
diff --git a/hi22-actions-bangarang-shuffle.png b/icons/hi22-actions-bangarang-shuffle.png
similarity index 100%
rename from hi22-actions-bangarang-shuffle.png
rename to icons/hi22-actions-bangarang-shuffle.png
diff --git a/hi22-app-bangarang.png b/icons/hi22-app-bangarang.png
similarity index 100%
rename from hi22-app-bangarang.png
rename to icons/hi22-app-bangarang.png
diff --git a/hi22-status-bangarang-loading-0.png b/icons/hi22-status-bangarang-loading-0.png
similarity index 100%
rename from hi22-status-bangarang-loading-0.png
rename to icons/hi22-status-bangarang-loading-0.png
diff --git a/hi22-status-bangarang-loading-1.png b/icons/hi22-status-bangarang-loading-1.png
similarity index 100%
rename from hi22-status-bangarang-loading-1.png
rename to icons/hi22-status-bangarang-loading-1.png
diff --git a/hi22-status-bangarang-loading-2.png b/icons/hi22-status-bangarang-loading-2.png
similarity index 100%
rename from hi22-status-bangarang-loading-2.png
rename to icons/hi22-status-bangarang-loading-2.png
diff --git a/hi22-status-bangarang-loading-3.png b/icons/hi22-status-bangarang-loading-3.png
similarity index 100%
rename from hi22-status-bangarang-loading-3.png
rename to icons/hi22-status-bangarang-loading-3.png
diff --git a/hi22-status-bangarang-loading-4.png b/icons/hi22-status-bangarang-loading-4.png
similarity index 100%
rename from hi22-status-bangarang-loading-4.png
rename to icons/hi22-status-bangarang-loading-4.png
diff --git a/hi22-status-bangarang-loading-5.png b/icons/hi22-status-bangarang-loading-5.png
similarity index 100%
rename from hi22-status-bangarang-loading-5.png
rename to icons/hi22-status-bangarang-loading-5.png
diff --git a/hi22-status-bangarang-loading-6.png b/icons/hi22-status-bangarang-loading-6.png
similarity index 100%
rename from hi22-status-bangarang-loading-6.png
rename to icons/hi22-status-bangarang-loading-6.png
diff --git a/hi22-status-bangarang-loading-7.png b/icons/hi22-status-bangarang-loading-7.png
similarity index 100%
rename from hi22-status-bangarang-loading-7.png
rename to icons/hi22-status-bangarang-loading-7.png
diff --git a/hi32-app-bangarang.png b/icons/hi32-app-bangarang.png
similarity index 100%
rename from hi32-app-bangarang.png
rename to icons/hi32-app-bangarang.png
diff --git a/hi32-status-bangarang-loading-0.png b/icons/hi32-status-bangarang-loading-0.png
similarity index 100%
rename from hi32-status-bangarang-loading-0.png
rename to icons/hi32-status-bangarang-loading-0.png
diff --git a/hi32-status-bangarang-loading-1.png b/icons/hi32-status-bangarang-loading-1.png
similarity index 100%
rename from hi32-status-bangarang-loading-1.png
rename to icons/hi32-status-bangarang-loading-1.png
diff --git a/hi32-status-bangarang-loading-2.png b/icons/hi32-status-bangarang-loading-2.png
similarity index 100%
rename from hi32-status-bangarang-loading-2.png
rename to icons/hi32-status-bangarang-loading-2.png
diff --git a/hi32-status-bangarang-loading-3.png b/icons/hi32-status-bangarang-loading-3.png
similarity index 100%
rename from hi32-status-bangarang-loading-3.png
rename to icons/hi32-status-bangarang-loading-3.png
diff --git a/hi32-status-bangarang-loading-4.png b/icons/hi32-status-bangarang-loading-4.png
similarity index 100%
rename from hi32-status-bangarang-loading-4.png
rename to icons/hi32-status-bangarang-loading-4.png
diff --git a/hi32-status-bangarang-loading-5.png b/icons/hi32-status-bangarang-loading-5.png
similarity index 100%
rename from hi32-status-bangarang-loading-5.png
rename to icons/hi32-status-bangarang-loading-5.png
diff --git a/hi32-status-bangarang-loading-6.png b/icons/hi32-status-bangarang-loading-6.png
similarity index 100%
rename from hi32-status-bangarang-loading-6.png
rename to icons/hi32-status-bangarang-loading-6.png
diff --git a/hi32-status-bangarang-loading-7.png b/icons/hi32-status-bangarang-loading-7.png
similarity index 100%
rename from hi32-status-bangarang-loading-7.png
rename to icons/hi32-status-bangarang-loading-7.png
diff --git a/hi48-app-bangarang.png b/icons/hi48-app-bangarang.png
similarity index 100%
rename from hi48-app-bangarang.png
rename to icons/hi48-app-bangarang.png
diff --git a/hi64-app-bangarang.png b/icons/hi64-app-bangarang.png
similarity index 100%
rename from hi64-app-bangarang.png
rename to icons/hi64-app-bangarang.png
diff --git a/hi8-app-bangarang.png b/icons/hi8-app-bangarang.png
similarity index 100%
rename from hi8-app-bangarang.png
rename to icons/hi8-app-bangarang.png
diff --git a/platform/listengine.h b/platform/listengine.h
deleted file mode 100644
index 6df53b5..0000000
--- a/platform/listengine.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef LISTENGINE_H
-#define LISTENGINE_H
-
-#include "mediaitemmodel.h"
-#include "listenginefactory.h"
-#include <QtCore>
-
-class ListEngine : public QThread
-{
- Q_OBJECT
-
- public:
- ListEngine(ListEngineFactory *parent);
- virtual ~ListEngine();
-
- void setMediaListProperties(const MediaListProperties& mediaListProperties);
- const MediaListProperties& mediaListProperties() const;
- void setRequestSignature(const QString& requestSignature);
- void setSubRequestSignature(const QString& subRequestSignature);
- const QString& requestSignature() const;
- const QString& subRequestSignature() const;
-
- void setModel(MediaItemModel * mediaItemModel);
- MediaItemModel * model();
-
- virtual void setFilterForSources(const QString& engineFilter)
- {
- Q_UNUSED(engineFilter);
- }
- virtual void activateAction(){}
- virtual void removeSourceInfo(QList<MediaItem> mediaList)
- {
- Q_UNUSED(mediaList);
- }
- virtual void updateSourceInfo(QList<MediaItem> mediaList)
- {
- Q_UNUSED(mediaList);
- }
-
- protected:
- MediaListProperties m_mediaListProperties;
- QString m_requestSignature;
- QString m_subRequestSignature;
-
- private:
- MediaItemModel * m_mediaItemModel;
-};
-#endif // LISTENGINE_H
diff --git a/platform/mediaindexer.cpp b/platform/mediaindexer.cpp
deleted file mode 100644
index 75f1d04..0000000
--- a/platform/mediaindexer.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "mediaindexer.h"
-#include "mediaitemmodel.h"
-#include "utilities.h"
-#include "mediavocabulary.h"
-
-#include <KUrl>
-#include <KDebug>
-#include <kuiserverjobtracker.h>
-#include <Soprano/QueryResultIterator>
-#include <Soprano/Vocabulary/Xesam>
-#include <Soprano/Vocabulary/RDF>
-#include <Soprano/Vocabulary/XMLSchema>
-#include <nepomuk/resource.h>
-#include <nepomuk/variant.h>
-#include <Nepomuk/ResourceManager>
-#include <taglib/fileref.h>
-#include <taglib/tstring.h>
-#include <id3v2tag.h>
-
-#include <QApplication>
-
-MediaIndexerJob::MediaIndexerJob(QObject * parent) : KJob(parent)
-{
- setCapabilities(KJob::NoCapabilities);
- running = false;
-}
-
-MediaIndexerJob::~MediaIndexerJob()
-{
- if (running) {
- setPercent(100);
- emitResult();
- }
-}
-
-void MediaIndexerJob::start()
-{
- running = true;
- index();
-}
-
-void MediaIndexerJob::index()
-{
- if (m_indexType == MediaIndexer::IndexUrl) {
- QList<QString> urlsToIndex = m_urlsToIndex;
- m_urlsToIndex.clear();
- QString descriptionTitle = QString("Bangarang: Indexing %1 items").arg(urlsToIndex.count());
- for (int i = 0; i < urlsToIndex.count(); ++i) {
- emit description(this, descriptionTitle, qMakePair(QString("Current Item"), QString("%1").arg(urlsToIndex.at(i))));
-
- indexUrl(urlsToIndex.at(i));
- setPercent(100*i/urlsToIndex.count());
- }
- emit description(this, QString("Bangarang: %1 items indexed").arg(urlsToIndex.count()));
- emitResult();
- running = false;
- } else if (m_indexType == MediaIndexer::IndexMediaItem) {
- QList<MediaItem> mediaList = m_mediaListToIndex;
- m_mediaListToIndex.clear();
- QString descriptionTitle = QString("Bangarang: Indexing %1 items").arg(mediaList.count());
- for (int i = 0; i < mediaList.count(); ++i) {
- emit description(this, descriptionTitle, qMakePair(QString("Current Item"), QString("%1").arg(mediaList.at(i).title)));
-
- indexMediaItem(mediaList.at(i));
- emit sourceInfoUpdated(mediaList.at(i));
- setPercent(100*i/mediaList.count());
- }
- emit description(this, QString("Bangarang: %1 items indexed").arg(mediaList.count()));
- emitResult();
- running = false;
- } else if (m_indexType == MediaIndexer::RemoveInfo) {
- QList<MediaItem> mediaList = m_mediaListToIndex;
- m_mediaListToIndex.clear();
- QString descriptionTitle = QString("Bangarang: Removing Info for %1 items").arg(mediaList.count());
- for (int i = 0; i < mediaList.count(); ++i) {
- emit description(this, descriptionTitle, qMakePair(QString("Current Item"), QString("%1").arg(mediaList.at(i).title)));
-
- removeInfo(mediaList.at(i));
- emit urlInfoRemoved(mediaList.at(i).url);
- setPercent(100*i/mediaList.count());
- }
- emit description(this, QString("Bangarang: Info for %1 items removed").arg(mediaList.count()));
- emitResult();
- running = false;
- }
- emit jobComplete();
-}
-
-void MediaIndexerJob::setUrlsToIndex(QList<QString> urls)
-{
- if (!running) {
- m_urlsToIndex << urls;
- m_indexType = MediaIndexer::IndexUrl;
- }
-}
-
-void MediaIndexerJob::setMediaListToIndex(QList<MediaItem> mediaList)
-{
- if (!running) {
- m_mediaListToIndex << mediaList;
- m_indexType = MediaIndexer::IndexMediaItem;
- }
-}
-
-void MediaIndexerJob::setInfoToRemove(QList<MediaItem> mediaList)
-{
- if (!running) {
- m_mediaListToIndex << mediaList;
- m_indexType = MediaIndexer::RemoveInfo;
- }
-}
-
-void MediaIndexerJob::indexUrl(QString url)
-{
- //Update RDF store
- MediaVocabulary mediaVocabulary = MediaVocabulary();
- Nepomuk::Resource res(url);
- if (Utilities::isMusic(url)) {
- if (!res.exists()) {
- res = Nepomuk::Resource(url, mediaVocabulary.typeAudioMusic());
- }
- if (!res.hasType(mediaVocabulary.typeAudioMusic())) {
- res.addType(mediaVocabulary.typeAudioMusic());
- }
- TagLib::FileRef file(KUrl(url).path().toUtf8());
- QString title = TStringToQString(file.tag()->title()).trimmed();
- QString artist = TStringToQString(file.tag()->artist()).trimmed();
- QString album = TStringToQString(file.tag()->album()).trimmed();
- int track = file.tag()->track();
- QString genre = TStringToQString(file.tag()->genre()).trimmed();
- int duration = file.audioProperties()->length();
- res.setProperty(mediaVocabulary.title(), Nepomuk::Variant(title));
- res.setProperty(mediaVocabulary.musicArtist(), Nepomuk::Variant(artist));
- res.setProperty(mediaVocabulary.musicAlbumName(), Nepomuk::Variant(album));
- res.setProperty(mediaVocabulary.musicTrackNumber(), Nepomuk::Variant(track));
- res.setProperty(mediaVocabulary.musicGenre(), Nepomuk::Variant(genre));
- res.setProperty(mediaVocabulary.duration(), Nepomuk::Variant(duration));
- }
-}
-
-void MediaIndexerJob::indexMediaItem(MediaItem mediaItem)
-{
- //Update RDF store
- MediaVocabulary mediaVocabulary = MediaVocabulary();
- Nepomuk::Resource res(mediaItem.url);
- if (mediaItem.type == "Audio") {
- // Update the media type
- QUrl audioType;
- if (mediaItem.fields["audioType"] == "Music") {
- audioType = mediaVocabulary.typeAudioMusic();
- if (!res.exists()) {
- res = Nepomuk::Resource(mediaItem.url, audioType);
- }
- removeType(res, mediaVocabulary.typeAudioStream());
- removeType(res, mediaVocabulary.typeAudio());
- } else if (mediaItem.fields["audioType"] == "Audio Stream") {
- audioType = mediaVocabulary.typeAudioStream();
- if (!res.exists()) {
- res = Nepomuk::Resource(mediaItem.url, audioType);
- }
- removeType(res, mediaVocabulary.typeAudioMusic());
- removeType(res, mediaVocabulary.typeAudio());
- } else if (mediaItem.fields["audioType"] == "Audio Clip") {
- audioType = mediaVocabulary.typeAudio();
- if (!res.exists()) {
- res = Nepomuk::Resource(mediaItem.url, audioType);
- }
- removeType(res, mediaVocabulary.typeAudioMusic());
- removeType(res, mediaVocabulary.typeAudioStream());
- }
- if (!res.hasType(audioType)) {
- res.addType(audioType);
- }
-
- // Update the properties
- QString title = mediaItem.fields["title"].toString();
- res.setProperty(mediaVocabulary.title(), Nepomuk::Variant(title));
- QString description = mediaItem.fields["description"].toString();
- res.setProperty(mediaVocabulary.description(), Nepomuk::Variant(description));
- QString artworkUrl = mediaItem.fields["artworkUrl"].toString();
- if (!artworkUrl.isEmpty()) {
- Nepomuk::Resource artworkRes(artworkUrl);
- if (!artworkRes.exists()) {
- artworkRes = Nepomuk::Resource(QUrl(artworkUrl), QUrl("http://http://www.semanticdesktop.org/ontologies/nfo#Image"));
- }
- res.setProperty(mediaVocabulary.artwork(), Nepomuk::Variant(artworkRes));
- }
- if (mediaItem.fields["audioType"] == "Music") {
- QString artist = mediaItem.fields["artist"].toString();
- QString album = mediaItem.fields["album"].toString();
- int track = mediaItem.fields["trackNumber"].toInt();
- QString genre = mediaItem.fields["genre"].toString();
- int duration = mediaItem.fields["duration"].toInt();
- int year = mediaItem.fields["year"].toInt();
- res.setProperty(mediaVocabulary.musicArtist(), Nepomuk::Variant(artist));
- res.setProperty(mediaVocabulary.musicAlbumName(), Nepomuk::Variant(album));
- res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
- if (track != 0) {
- res.setProperty(mediaVocabulary.musicTrackNumber(), Nepomuk::Variant(track));
- }
- if (duration != 0) {
- res.setProperty(mediaVocabulary.duration(), Nepomuk::Variant(duration));
- }
- if (year != 0) {
- QDate created = QDate(year, 1, 1);
- res.setProperty(mediaVocabulary.created(), Nepomuk::Variant(created));
- }
- } else if ((mediaItem.fields["audioType"] == "Audio Stream") ||
- (mediaItem.fields["audioType"] == "Audio Clip")) {
- }
- } else if (mediaItem.type == "Video") {
- //Update the media type
- if (!res.exists()) {
- res = Nepomuk::Resource(mediaItem.url, mediaVocabulary.typeVideo());
- }
- if (!res.hasType(mediaVocabulary.typeVideo())) {
- res.addType(mediaVocabulary.typeVideo());
- }
-
- //Update the properties
- QString title = mediaItem.fields["title"].toString();
- res.setProperty(mediaVocabulary.title(), Nepomuk::Variant(title));
- QString description = mediaItem.fields["description"].toString();
- res.setProperty(mediaVocabulary.description(), Nepomuk::Variant(description));
- QString artworkUrl = mediaItem.fields["artworkUrl"].toString();
- if (!artworkUrl.isEmpty()) {
- Nepomuk::Resource artworkRes(artworkUrl);
- if (!artworkRes.exists()) {
- artworkRes = Nepomuk::Resource(QUrl(artworkUrl), mediaVocabulary.typeImage());
- }
- res.setProperty(mediaVocabulary.artwork(), Nepomuk::Variant(artworkRes));
- }
- if (mediaItem.fields["videoType"] == "Movie") {
- res.setProperty(mediaVocabulary.videoIsMovie(), Nepomuk::Variant(true));
- res.removeProperty(mediaVocabulary.videoIsTVShow());
- QString seriesName = mediaItem.fields["seriesName"].toString();
- res.setProperty(mediaVocabulary.videoSeriesName(), Nepomuk::Variant(seriesName));
- QString genre = mediaItem.fields["genre"].toString();
- res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
- int year = mediaItem.fields["year"].toInt();
- if (year != 0) {
- QDate created = QDate(year, 1, 1);
- res.setProperty(mediaVocabulary.created(), Nepomuk::Variant(created));
- }
- } else if (mediaItem.fields["videoType"] == "TV Show") {
- res.setProperty(mediaVocabulary.videoIsTVShow(), Nepomuk::Variant(true));
- res.removeProperty(mediaVocabulary.videoIsMovie());
- QString seriesName = mediaItem.fields["seriesName"].toString();
- res.setProperty(mediaVocabulary.videoSeriesName(), Nepomuk::Variant(seriesName));
- int season = mediaItem.fields["season"].toInt();
- if (season != 0) {
- res.setProperty(mediaVocabulary.videoSeriesSeason(), Nepomuk::Variant(season));
- } else {
- res.removeProperty(mediaVocabulary.videoSeriesSeason());
- }
- int episode = mediaItem.fields["episode"].toInt();
- if (episode != 0) {
- res.setProperty(mediaVocabulary.videoSeriesEpisode(), Nepomuk::Variant(episode));
- } else {
- res.removeProperty(mediaVocabulary.videoSeriesEpisode());
- }
- QString genre = mediaItem.fields["genre"].toString();
- res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
- int year = mediaItem.fields["year"].toInt();
- if (year != 0) {
- QDate created = QDate(year, 1, 1);
- res.setProperty(mediaVocabulary.created(), Nepomuk::Variant(created));
- }
- } else if (mediaItem.fields["videoType"] == "Video Clip") {
- //Remove properties identifying video as a movie or tv show
- res.removeProperty(mediaVocabulary.videoIsMovie());
- res.removeProperty(mediaVocabulary.videoIsTVShow());
- }
- }
-}
-
-void MediaIndexerJob::removeInfo(MediaItem mediaItem)
-{
- kDebug() << "removing info for " << mediaItem.url;
- //Update RDF store
- MediaVocabulary mediaVocabulary = MediaVocabulary();
- Nepomuk::Resource res(mediaItem.url);
- if (!res.exists()) {
- return;
- }
- if (mediaItem.type == "Audio") {
- // Update the media type
- QUrl audioType;
- if (mediaItem.fields["audioType"] == "Music") {
- audioType = mediaVocabulary.typeAudioMusic();
- } else if (mediaItem.fields["audioType"] == "Audio Stream") {
- audioType = mediaVocabulary.typeAudioStream();
- } else if (mediaItem.fields["audioType"] == "Audio Clip") {
- audioType = mediaVocabulary.typeAudio();
- }
- if (res.hasType(audioType)) {
- removeType(res, audioType);
- }
-
- // Update the properties
- res.removeProperty(mediaVocabulary.title());
- res.removeProperty(mediaVocabulary.description());
- res.removeProperty(mediaVocabulary.artwork());
-
- if (mediaItem.fields["audioType"] == "Music") {
- res.removeProperty(mediaVocabulary.musicArtist());
- res.removeProperty(mediaVocabulary.musicAlbumName());
- res.removeProperty(mediaVocabulary.genre());
- res.removeProperty(mediaVocabulary.musicTrackNumber());
- res.removeProperty(mediaVocabulary.duration());
- res.removeProperty(mediaVocabulary.created());
- } else if ((mediaItem.fields["audioType"] == "Audio Stream") ||
- (mediaItem.fields["audioType"] == "Audio Clip")) {
- }
- } else if (mediaItem.type == "Video") {
- //Update the media type
- if (res.hasType(mediaVocabulary.typeVideo())) {
- removeType(res, mediaVocabulary.typeVideo());
- }
-
- //Update the properties
- res.removeProperty(mediaVocabulary.title());
- res.removeProperty(mediaVocabulary.description());
- res.removeProperty(mediaVocabulary.artwork());
- if (mediaItem.fields["videoType"] == "Movie") {
- res.removeProperty(mediaVocabulary.videoIsMovie());
- res.removeProperty(mediaVocabulary.videoSeriesName());
- res.removeProperty(mediaVocabulary.genre());
- res.removeProperty(mediaVocabulary.created());
- } else if (mediaItem.fields["videoType"] == "TV Show") {
- res.removeProperty(mediaVocabulary.videoIsTVShow());
- res.removeProperty(mediaVocabulary.videoSeriesName());
- res.removeProperty(mediaVocabulary.videoSeriesSeason());
- res.removeProperty(mediaVocabulary.videoSeriesEpisode());
- res.removeProperty(mediaVocabulary.genre());
- res.removeProperty(mediaVocabulary.created());
- } else if (mediaItem.fields["videoType"] == "Video Clip") {
- res.removeProperty(mediaVocabulary.videoIsMovie());
- res.removeProperty(mediaVocabulary.videoIsTVShow());
- }
- }
-}
-
-void MediaIndexerJob::removeType(Nepomuk::Resource res, QUrl mediaType)
-{
- QList<QUrl> types = res.types();
- for (int i = 0; i < types.count(); i++) {
- if (types.at(i).toString() == mediaType.toString()) {
- types.removeAt(i);
- break;
- }
- }
- res.setTypes(types);
-}
-
-MediaIndexer::MediaIndexer(QObject * parent) : QThread(parent)
-{
- Nepomuk::ResourceManager::instance()->init();
- if (Nepomuk::ResourceManager::instance()->initialized()) {
- m_nepomukInited = true; //resource manager inited successfully
- } else {
- m_nepomukInited = false; //no resource manager
- }
-}
-
-MediaIndexer::~MediaIndexer()
-{
-}
-
-void MediaIndexer::run()
-{
- if (m_nepomukInited) {
- if (m_indexType == MediaIndexer::IndexUrl) {
- if (m_urls.count() > 0) {
- MediaIndexerJob * indexerJob = new MediaIndexerJob(this);
- indexerJob->setUrlsToIndex(m_urls);
- KUiServerJobTracker * jt = new KUiServerJobTracker(this);
- jt->registerJob(indexerJob);
- indexerJob->start();
- }
- } else if (m_indexType == MediaIndexer::IndexMediaItem) {
- if (m_mediaList.count() > 0) {
- MediaIndexerJob * indexerJob = new MediaIndexerJob(this);
- connect(indexerJob, SIGNAL(jobComplete()), this, SLOT(jobComplete()));
- connect(indexerJob, SIGNAL(sourceInfoUpdated(MediaItem)), this, SIGNAL(sourceInfoUpdated(MediaItem)));
- indexerJob->setMediaListToIndex(m_mediaList);
- KUiServerJobTracker * jt = new KUiServerJobTracker(this);
- jt->registerJob(indexerJob);
- indexerJob->start();
- }
- } else if (m_indexType == MediaIndexer::RemoveInfo) {
- if (m_mediaList.count() > 0) {
- MediaIndexerJob * indexerJob = new MediaIndexerJob(this);
- connect(indexerJob, SIGNAL(jobComplete()), this, SLOT(jobComplete()));
- connect(indexerJob, SIGNAL(urlInfoRemoved(QString)), this, SIGNAL(urlInfoRemoved(QString)));
- indexerJob->setInfoToRemove(m_mediaList);
- KUiServerJobTracker * jt = new KUiServerJobTracker(this);
- jt->registerJob(indexerJob);
- indexerJob->start();
- }
- }
- } else {
- emit indexingComplete();
- }
-}
-
-void MediaIndexer::indexUrls(QList<QString> urls)
-{
- m_indexType = MediaIndexer::IndexUrl;
- m_urls = urls;
- start();
-}
-
-void MediaIndexer::indexMediaItems(QList<MediaItem> mediaList)
-{
- m_indexType = MediaIndexer::IndexMediaItem;
- m_mediaList = mediaList;
- start();
-}
-
-void MediaIndexer::removeInfo(QList<MediaItem> mediaList)
-{
- m_indexType = MediaIndexer::RemoveInfo;
- m_mediaList = mediaList;
- start();
-}
-
-void MediaIndexer::jobComplete()
-{
- emit indexingComplete();
-}
diff --git a/platform/mediaindexer.h b/platform/mediaindexer.h
deleted file mode 100644
index bbaee74..0000000
--- a/platform/mediaindexer.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef MEDIAINDEXER_H
-#define MEDIAINDEXER_H
-
-#include <QtCore>
-#include <KJob>
-
-class MediaItem;
-namespace Nepomuk
-{
- class Resource;
-}
-
-class MediaIndexerJob: public KJob
-{
- Q_OBJECT
-
- public:
- MediaIndexerJob(QObject *parent);
- ~MediaIndexerJob();
- void setUrlsToIndex(QList<QString> urls);
- void setMediaListToIndex(QList<MediaItem> mediaList);
- void indexUrl(QString url);
- void indexMediaItem(MediaItem mediaItem);
- void setInfoToRemove(QList<MediaItem> mediaList);
- void removeInfo(MediaItem mediaItem);
- void start();
-
- private:
- void index();
- QList<QString> m_urlsToIndex;
- QList<MediaItem> m_mediaListToIndex;
- bool running;
- int m_indexType;
- void removeType(Nepomuk::Resource res, QUrl mediaType);
-
- Q_SIGNALS:
- void jobComplete();
- void urlInfoRemoved(QString url);
- void sourceInfoUpdated(MediaItem mediaItem);
-};
-
-class MediaIndexer : public QThread
-{
- Q_OBJECT
-
- public:
- enum IndexType { IndexUrl = Qt::UserRole + 1,
- IndexMediaItem = Qt::UserRole + 2,
- RemoveInfo = Qt::UserRole + 3};
- MediaIndexer(QObject *parent);
- ~MediaIndexer();
- void run();
- void indexUrls(QList<QString> urls);
- void indexMediaItems(QList<MediaItem> mediaList);
- void removeInfo(QList<MediaItem> mediaList);
-
- private:
- QList<QString> m_urls;
- QList<MediaItem> m_mediaList;
- int m_indexType;
- bool m_nepomukInited;
-
- private slots:
- void jobComplete();
-
- Q_SIGNALS:
- void indexingComplete();
- void urlInfoRemoved(QString url);
- void sourceInfoUpdated(MediaItem mediaItem);
-
-};
-#endif // MEDIAINDEXER_H
diff --git a/platform/mediaitemmodel.h b/platform/mediaitemmodel.h
deleted file mode 100644
index b7eb305..0000000
--- a/platform/mediaitemmodel.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef MEDIAITEMMODEL_H
-#define MEDIAITEMMODEL_H
-
-#include <QStandardItemModel>
-#include <QObject>
-#include <QPixmap>
-#include <QList>
-
-class MusicListEngine;
-class FileListEngine;
-class ListEngineFactory;
-class MediaListCache;
-
-struct MediaItem {
- enum MediaItemRole { UrlRole = Qt::UserRole + 1,
- SubTitleRole = Qt::UserRole + 2,
- DurationRole = Qt::UserRole + 3,
- RatingRole = Qt::UserRole + 4,
- TypeRole = Qt::UserRole + 5,
- FilterRole = Qt::UserRole + 6,
- PlaylistIndexRole = Qt::UserRole + 7,
- NowPlayingRole = Qt::UserRole + 8,
- IsSavedListRole = Qt::UserRole + 9,
- ExistsRole = Qt::UserRole + 10 };
- QIcon artwork;
- QString title;
- QString subTitle;
- QString duration;
- QString type;
- QString url;
- QString filter;
- int playlistIndex;
- bool nowPlaying;
- bool isSavedList;
- bool exists;
- QHash <QString, QVariant> fields;
- MediaItem() : nowPlaying(false), isSavedList(false), exists(true) {}
-};
-
-Q_DECLARE_METATYPE(MediaItem);
-
-class MediaListProperties {
-
-public:
- QString name;
- QString summary;
- QString lri; //List Resource Identifier
- QString engine() {
- if (lri.indexOf("://") != -1) {
- return lri.left(lri.indexOf("://") + 3);
- } else {
- return QString();
- }
- }
- QString engineArg() {
- int endOfArg = (lri.indexOf("?") != -1) ? lri.indexOf("?") - 1: lri.size() - 1;
- if ((lri.indexOf("://") != -1) && (lri.indexOf("://") != lri.size() - 3)) {
- //return lri.mid(lri.indexOf("://") + 3, lri.size() - endOfArg + 1);
- return lri.mid(lri.indexOf("://") + 3, endOfArg - (lri.indexOf("://") + 2));
- } else {
- return QString();
- }
- }
- QString engineFilter() {
- if ((lri.indexOf("://") != -1) && (lri.indexOf("?") != -1) && (lri.indexOf("?") != lri.size() - 1)){
- return lri.right(lri.size() - (lri.indexOf("?") + 1));
- } else {
- return QString();
- }
- }
- QString type;
-};
-
-class MediaList : QList<MediaItem>{};
-
-class MediaItemModel : public QStandardItemModel
-{
- Q_OBJECT
- public:
- MediaItemModel(QObject * parent);
- ~MediaItemModel();
- QString dataEngine();
- QString filter();
- void clearMediaListData(bool emitMediaListChanged = false);
- void load();
- QList<MediaItem> mediaList();
- void loadMediaList(QList<MediaItem>, bool emitMediaListChanged = false);
- MediaItem mediaItemAt(int row);
- void loadMediaItem(MediaItem mediaItem, bool emitMediaListChanged = false);
- MediaListProperties mediaListProperties();
- void setMediaListProperties(MediaListProperties mediaListProperties);
- int rowOfUrl(QString url);
- void loadSources(QList<MediaItem> mediaList);
- void removeMediaItemAt(int row, bool emitMediaListChanged = false);
- void replaceMediaItemAt(int row, MediaItem mediaItem, bool emitMediaListChanged = false);
- void setListEngineFactory(ListEngineFactory * listEngineFactory);
- void removeSourceInfo(QList<MediaItem> mediaList);
- void updateSourceInfo(QList<MediaItem> mediaList);
- void setMediaListCache(MediaListCache * mediaListCache);
- MediaListCache * mediaListCache();
- void setCacheThreshold(int msec);
- int cacheThreshold();
-
- Qt::DropActions supportedDropActions() const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
-
- private:
- void hideLoadingMessage();
- void showNoResultsMessage();
- QList<QStandardItem *> rowDataFromMediaItem(MediaItem mediaItem);
- QObject * m_parent;
- QString m_dataEngine;
- QString m_filter;
- MediaListProperties m_mediaListProperties;
- ListEngineFactory * m_listEngineFactory;
- QString m_requestSignature;
- QStringList m_subRequestSignatures;
- QList< QList<MediaItem> > m_subRequestMediaLists;
- int m_subRequestsDone;
- QStringList m_urlList;
- QList<MediaItem> m_mediaList;
- bool m_emitChangedAfterDrop;
- int m_loadingProgress;
- bool m_loadingState;
- void setLoadingState(bool state);
- int m_cacheThreshold;
- MediaListCache * m_mediaListCache;
- bool m_forceRefreshFromSource;
- QHash<QString, QTime> m_lriStartTimes;
- QList<QString> m_lrisLoading;
-
- Q_SIGNALS:
- void propertiesChanged();
- void mediaListChanged();
- void loading();
-
- protected Q_SLOTS:
- void categoryActivated(QModelIndex index);
- void actionActivated(QModelIndex index);
- void synchRemoveRows(const QModelIndex &index, int start, int end);
- void showLoadingMessage();
-
- public Q_SLOTS:
- void addResults(QString requestSignature, QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done, QString subRequestSignature);
- void reload();
- void updateMediaItems(QList<MediaItem> mediaList);
- void updateMediaItem(MediaItem mediaItem);
- void removeMediaItem(QString url);
-};
-
-#endif // MEDIAITEMMODEL_H
diff --git a/platform/nepomuklistengine.cpp b/platform/nepomuklistengine.cpp
deleted file mode 100644
index 0a95404..0000000
--- a/platform/nepomuklistengine.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "nepomuklistengine.h"
-#include <KDebug>
-
-NepomukListEngine::NepomukListEngine(ListEngineFactory * parent) : ListEngine(parent)
-{
- Nepomuk::ResourceManager::instance()->init();
- if (Nepomuk::ResourceManager::instance()->initialized()) {
- m_nepomukInited = true; //resource manager inited successfully
- m_mainModel = Nepomuk::ResourceManager::instance()->mainModel();
- m_mediaIndexer = new MediaIndexer(this);
- } else {
- m_nepomukInited = false; //no resource manager
- }
- m_removeSourceInfo = false;
-
-}
-
-NepomukListEngine::~NepomukListEngine()
-{
- if (m_nepomukInited) {
- delete m_mediaIndexer;
- }
-}
-
-void NepomukListEngine::run()
-{
- if (m_removeSourceInfo) {
- connect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SLOT(removeMediaItem(QString)));
- connect(m_mediaIndexer, SIGNAL(indexingComplete()), this, SLOT(disconnectIndexer()));
- m_mediaIndexer->removeInfo(m_mediaItemsInfoToRemove);
- m_removeSourceInfo = false;
- m_mediaItemsInfoToRemove.clear();
- }
- if (m_updateSourceInfo) {
- connect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SLOT(updateMediaItem(MediaItem)));
- connect(m_mediaIndexer, SIGNAL(indexingComplete()), this, SLOT(disconnectIndexer()));
- m_mediaIndexer->indexMediaItems(m_mediaItemsInfoToUpdate);
- m_updateSourceInfo = false;
- m_mediaItemsInfoToUpdate.clear();
- }
-}
-
-void NepomukListEngine::removeSourceInfo(QList<MediaItem> mediaList)
-{
- if (m_nepomukInited) {
- m_mediaItemsInfoToRemove = mediaList;
- m_removeSourceInfo = true;
- NepomukListEngine::run();
- }
-}
-
-void NepomukListEngine::updateSourceInfo(QList<MediaItem> mediaList)
-{
- if (m_nepomukInited) {
- m_mediaItemsInfoToUpdate = mediaList;
- m_updateSourceInfo = true;
- NepomukListEngine::run();
- }
-}
-
-void NepomukListEngine::disconnectIndexer()
-{
- disconnect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SLOT(removeMediaItem(QString)));
- disconnect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SLOT(updateMediaItem(MediaItem)));
-}
diff --git a/platform/playlist.h b/platform/playlist.h
deleted file mode 100644
index a4b9594..0000000
--- a/platform/playlist.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef PLAYLIST_H
-#define PLAYLIST_H
-
-#include <QObject>
-#include <Phonon/MediaObject>
-#include <Phonon/MediaController>
-
-class MediaItemModel;
-class MediaItem;
-
-class Playlist : public QObject
-{
- Q_OBJECT
-
- public:
- enum Mode { Normal = 0, Shuffle = 1};
- enum Model { PlaylistModel = 0, QueueModel = 1};
- enum State { LoadingComplete = 0, Loading = 1};
- Playlist(QObject * parent, Phonon::MediaObject * mediaObject);
- ~Playlist();
- MediaItemModel * playlistModel();
- MediaItemModel * queueModel();
- MediaItemModel * nowPlayingModel();
- Phonon::MediaObject * mediaObject();
- void start();
- void playItemAt(int row, int model = 0);
- void stop();
- void playMediaList(QList<MediaItem> mediaList);
- void addMediaList(QList<MediaItem> mediaList);
- void addMediaItem(MediaItem mediaItem);
- void removeMediaItemAt(int row);
- void clearPlaylist();
- void setMode(int mode);
- int mode();
- void shuffle();
- void orderByPlaylist();
- void addToQueue();
- void setRepeat(bool repeat);
- void buildQueueFrom(int playlistRow);
- int loadingState();
-
- private:
- QObject * m_parent;
- MediaItemModel * m_currentPlaylist;
- MediaItemModel * m_nowPlaying;
- MediaItemModel * m_queue;
- int m_mode;
- int m_repeat;
- int m_queueDepth;
- int m_oldPlaylistLength;
- QList<int> m_playlistIndices;
- QList<int> m_playlistIndicesHistory;
- QList<QString> m_playlistUrlHistory;
- Phonon::MediaObject * m_mediaObject;
- Phonon::MediaController * m_mediaController;
- bool playWhenPlaylistChanges;
- bool m_playlistFinished;
- void createUrlHistoryFromIndices();
- void updateNowPlaying();
- bool m_nepomukInited;
- int m_loadingState;
-
- public slots:
- void playNext();
- void playPrevious();
-
- private slots:
- void currentSourceChanged(const Phonon::MediaSource & newSource);
- void titleChanged(int newTitle);
- void playlistChanged();
- void queueNextPlaylistItem();
- void confirmPlaylistFinished();
- void stateChanged(Phonon::State newstate, Phonon::State oldstate);
-
- Q_SIGNALS:
- void playlistFinished();
- void loading();
-
-};
-#endif // PLAYLIST_H
diff --git a/platform/savedlistsengine.cpp b/platform/savedlistsengine.cpp
deleted file mode 100644
index 70bd5cc..0000000
--- a/platform/savedlistsengine.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "mediaitemmodel.h"
-#include "savedlistsengine.h"
-#include "listenginefactory.h"
-#include "utilities.h"
-#include "mediavocabulary.h"
-
-#include <KIcon>
-#include <KMimeType>
-#include <KStandardDirs>
-#include <KUrl>
-#include <taglib/fileref.h>
-#include <taglib/tstring.h>
-#include <id3v2tag.h>
-
-SavedListsEngine::SavedListsEngine(ListEngineFactory * parent) : ListEngine(parent)
-{
-}
-
-SavedListsEngine::~SavedListsEngine()
-{
-}
-
-void SavedListsEngine::run()
-{
- QList<MediaItem> mediaList;
-
-
- if (!m_mediaListProperties.engineArg().isEmpty()) {
- QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1").arg(m_mediaListProperties.engineArg()), false));
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
- return;
- }
-
- //Make sure it's a valid M3U fileref
- QTextStream in(&file);
- bool valid = false;
- if (!in.atEnd()) {
- QString line = in.readLine();
- if (line.trimmed() == "#EXTM3U") {
- valid = true;
- }
- }
-
- //Create a MediaItem for each entry
- if (valid) {
- while (!in.atEnd()) {
- QString line = in.readLine();
- if (line.startsWith("#EXTINF:")) {
- line = line.replace("#EXTINF:","");
- QStringList durTitle = line.split(",");
- QString title;
- int duration;
- if (durTitle.count() == 1) {
- //No title
- duration = 0;
- title = durTitle.at(0);
- } else {
- duration = durTitle.at(0).toInt();
- title = durTitle.at(1);
- }
- QString url = in.readLine().trimmed();
- MediaItem mediaItem;
- if (!url.isEmpty()) {
- mediaItem = Utilities::mediaItemFromUrl(KUrl(url));
- } else {
- continue;
- }
- if ((!mediaItem.title.isEmpty()) && (url.contains(mediaItem.title))) {
- mediaItem.title = title;
- }
- if ((duration > 0) && (mediaItem.fields["duration"].toInt() <= 0)) {
- mediaItem.duration = QTime(0,0,0,0).addSecs(duration).toString("m:ss");
- mediaItem.fields["duration"] = duration;
- }
- mediaList << mediaItem;
- }
- }
- }
-
- }
-
- m_mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
- m_requestSignature = QString();
- m_subRequestSignature = QString();
-}
diff --git a/platform/videolistengine.cpp b/platform/videolistengine.cpp
deleted file mode 100644
index ab649a0..0000000
--- a/platform/videolistengine.cpp
+++ /dev/null
@@ -1,747 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "mediaitemmodel.h"
-#include "videolistengine.h"
-#include "listenginefactory.h"
-#include "mediavocabulary.h"
-#include "utilities.h"
-
-#include <Soprano/QueryResultIterator>
-#include <Soprano/Vocabulary/Xesam>
-#include <Soprano/Vocabulary/RDF>
-#include <Soprano/Vocabulary/XMLSchema>
-#include <Soprano/Vocabulary/NAO>
-#include <QApplication>
-#include <KIcon>
-#include <KUrl>
-#include <taglib/fileref.h>
-#include <QTime>
-#include <nepomuk/variant.h>
-
-
-VideoListEngine::VideoListEngine(ListEngineFactory * parent) : NepomukListEngine(parent)
-{
-}
-
-VideoListEngine::~VideoListEngine()
-{
-}
-
-MediaItem VideoListEngine::createMediaItem(Soprano::QueryResultIterator& it) {
- MediaItem mediaItem;
- QUrl url = it.binding("url").uri().isEmpty() ?
- it.binding("r").uri() :
- it.binding("url").uri();
- mediaItem.url = url.toString();
- mediaItem.title = it.binding("title").literal().toString();
- if (mediaItem.title.isEmpty()) {
- if (KUrl(mediaItem.url).isLocalFile()) {
- mediaItem.title = KUrl(mediaItem.url).fileName();
- } else {
- mediaItem.title = mediaItem.url;
- }
- }
- int duration = it.binding("duration").literal().toInt();
- if (duration != 0) {
- mediaItem.duration = QTime(0,0,0,0).addSecs(duration).toString("m:ss");
- }
-
- QString seriesName = it.binding("seriesName").literal().toString();
- if (!seriesName.isEmpty()) {
- mediaItem.fields["seriesName"] = seriesName;
- mediaItem.subTitle = seriesName;
- }
-
- int season = it.binding("season").literal().toInt();
- if (season !=0 ) {
- mediaItem.fields["season"] = season;
- if (!mediaItem.subTitle.isEmpty()) {
- mediaItem.subTitle += " - ";
- }
- mediaItem.subTitle += QString("Season %1").arg(season);
- }
-
- int episode = it.binding("episode").literal().toInt();
- if (episode != 0) {
- mediaItem.fields["episode"] = episode;
- if (!mediaItem.subTitle.isEmpty()) {
- mediaItem.subTitle += " - ";
- }
- mediaItem.subTitle += QString("Episode %1").arg(episode);
- }
-
- if (it.binding("created").isValid()) {
- QDate created = it.binding("created").literal().toDate();
- if (created.isValid()) {
- mediaItem.fields["year"] = created.year();
- }
- }
- mediaItem.type = "Video";
- mediaItem.nowPlaying = false;
- mediaItem.fields["url"] = mediaItem.url;
- mediaItem.fields["title"] = it.binding("title").literal().toString();
- mediaItem.fields["duration"] = it.binding("duration").literal().toInt();
- mediaItem.fields["description"] = it.binding("description").literal().toString();
- mediaItem.fields["genre"] = it.binding("genre").literal().toString();
- mediaItem.fields["artworkUrl"] = it.binding("artwork").uri().toString();
- mediaItem.fields["rating"] = it.binding("rating").literal().toInt();
-
- return mediaItem;
-}
-
-
-void VideoListEngine::run()
-{
-
- //Create media list based on engine argument and filter
- QList<MediaItem> mediaList;
-
- MediaVocabulary mediaVocabulary = MediaVocabulary();
-
- QString engineArg = m_mediaListProperties.engineArg();
- QString engineFilter = m_mediaListProperties.engineFilter();
-
- if (m_nepomukInited) {
- if (engineArg.toLower() == "clips") {
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectResource();
- videoQuery.selectTitle();
- videoQuery.selectDuration(true);
- videoQuery.selectSeason(true);
- videoQuery.selectDescription(true);
- videoQuery.isTVShow(false);
- videoQuery.isMovie(false);
- videoQuery.orderBy("?title");
-
- //Execute Query
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- MediaItem mediaItem = createMediaItem(it);
-
- mediaItem.artwork = KIcon("video-x-generic");
- mediaItem.fields["videoType"] = "Video Clip";
- mediaList.append(mediaItem);
- }
-
- m_mediaListProperties.name = QString("Video Clips");
- m_mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- m_mediaListProperties.type = QString("Sources");
- } else if (engineArg.toLower() == "tvshows") {
- VideoQuery query = VideoQuery(true);
- query.isTVShow(true);
- query.selectSeriesName();
- query.orderBy("?seriesName");
- Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- QString name = it.binding("seriesName").literal().toString();
- if (!name.isEmpty()) {
- MediaItem mediaItem;
- mediaItem.url = QString("video://seasons?%1").arg(name);
- mediaItem.title = name;
- mediaItem.type = QString("Category");
- mediaItem.nowPlaying = false;
- mediaItem.artwork = KIcon("video-television");
- mediaList.append(mediaItem);
- }
- }
-
-
- /* Check, whether there are videos which have the TV show flag set,
- * but no series name is entered. If so, add an entry which allows
- * access to those files.
- */
- VideoQuery noSeriesQuery = VideoQuery();
- noSeriesQuery.isTVShow(true);
- noSeriesQuery.hasNoSeriesName();
-
- if(noSeriesQuery.executeAsk(m_mainModel)) {
- MediaItem mediaItem;
- mediaItem.url = QString("video://episodes?||");
- mediaItem.title = QString("Uncategorized TV Shows");
- mediaItem.type = QString("Category");
- mediaItem.nowPlaying = false;
- mediaItem.artwork = KIcon("video-television");
- mediaList.append(mediaItem);
- }
-
- m_mediaListProperties.name = QString("TV Shows");
- m_mediaListProperties.summary = QString("%1 shows").arg(mediaList.count());
- m_mediaListProperties.type = QString("Categories");
- } else if (engineArg.toLower() == "seasons") {
- QString seriesName = engineFilter;
-
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectSeason();
- videoQuery.isTVShow(true);
- videoQuery.hasSeriesName(seriesName);
- videoQuery.orderBy("?season");
-
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- int season = it.binding("season").literal().toInt();
- MediaItem mediaItem;
- mediaItem.url = QString("video://episodes?%1||%2")
- .arg(seriesName).arg(season);
- mediaItem.title = seriesName;
- mediaItem.subTitle = QString("Season %1").arg(season);
- mediaItem.type = QString("Category");
- mediaItem.nowPlaying = false;
- mediaItem.artwork = KIcon("video-television");
- mediaList.append(mediaItem);
- }
-
- /* Check, whether there are TV shows, which have no series entered.
- * If so, add an entry which allows access to those files.
- */
- VideoQuery noSeasonsQuery = VideoQuery();
- noSeasonsQuery.isTVShow(true);
- noSeasonsQuery.hasSeriesName(seriesName);
- noSeasonsQuery.hasNoSeason();
-
- if(noSeasonsQuery.executeAsk(m_mainModel)) {
- MediaItem mediaItem;
- mediaItem.url = QString("video://episodes?%1||").arg(seriesName);
- mediaItem.title = seriesName;
- mediaItem.subTitle = QString("Uncategorized seasons");
- mediaItem.type = QString("Category");
- mediaItem.nowPlaying = false;
- mediaItem.artwork = KIcon("video-television");
- mediaList.append(mediaItem);
- }
-
- m_mediaListProperties.name = QString("%1").arg(seriesName);
- m_mediaListProperties.summary = QString("%1 seasons").arg(mediaList.count());
-
- m_mediaListProperties.type = QString("Categories");
- } else if (engineArg.toLower() == "episodes") {
- QString seriesName;
- int season = 0;
- bool hasSeason = false;
-
- //Parse filter
- if (!engineFilter.isNull()) {
- QStringList argList = engineFilter.split("||");
- seriesName = argList.at(0);
- hasSeason = !argList.at(1).isEmpty();
- if (hasSeason)
- season = argList.at(1).toInt();
- }
-
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectResource();
- videoQuery.selectTitle();
- videoQuery.isTVShow(true);
- videoQuery.selectSeriesName(true);
- videoQuery.selectSeason(true);
- if (!seriesName.isEmpty()) {
- videoQuery.hasSeriesName(seriesName);
- } else {
- videoQuery.hasNoSeriesName();
- }
- if (hasSeason) {
- videoQuery.hasSeason(season);
- } else {
- videoQuery.hasNoSeason();
- }
- videoQuery.selectDuration(true);
- videoQuery.selectDescription(true);
- videoQuery.selectRating(true);
- videoQuery.selectEpisode(true);
- videoQuery.selectCreated(true);
- videoQuery.selectGenre(true);
- videoQuery.selectArtwork(true);
- videoQuery.orderBy("?episode ?created");
-
-
- //Execute Query
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- MediaItem mediaItem = createMediaItem(it);
-
- if (!seriesName.isEmpty()) {
- mediaItem.fields["seriesName"] = seriesName;
- }
- if (season != 0) {
- mediaItem.fields["season"] = season;
- }
-
- mediaItem.artwork = KIcon("video-television");
- mediaItem.fields["videoType"] = "TV Show";
- mediaList.append(mediaItem);
- }
-
- if (seriesName.isEmpty()) {
- m_mediaListProperties.name = QString("Uncategorized TV Shows");
- m_mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- } else if (hasSeason) {
- m_mediaListProperties.name = QString("%1 - Season %2")
- .arg(seriesName)
- .arg(season);
- m_mediaListProperties.summary = QString("%1 episodes").arg(mediaList.count());
- } else {
- m_mediaListProperties.name = QString(
- "%1 - Uncategorized Seasons")
- .arg(seriesName);
- m_mediaListProperties.summary = QString("%1 episodes").arg(mediaList.count());
- }
- m_mediaListProperties.type = QString("Sources");
-
- } else if (engineArg.toLower() == "movies") {
- QString genre;
-
- //Parse filter
- if (!engineFilter.isNull()) {
- QStringList argList = engineFilter.split("||");
- genre = argList.at(0);
- }
-
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectResource();
- videoQuery.selectTitle();
- videoQuery.isMovie(true);
- videoQuery.selectDescription(true);
- videoQuery.selectSeriesName(true);
- videoQuery.selectRating(true);
- videoQuery.selectDuration(true);
- videoQuery.selectCreated(true);
- videoQuery.selectGenre(true);
- videoQuery.selectArtwork(true);
- if (!genre.isEmpty()) {
- videoQuery.hasGenre(genre);
- }
- videoQuery.orderBy("?title ?created");
-
- //Execute Query
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- MediaItem mediaItem = createMediaItem(it);
- mediaItem.artwork = KIcon("tool-animator");
- mediaItem.fields["videoType"] = "Movie";
- mediaList.append(mediaItem);
- }
-
- m_mediaListProperties.name = QString("Movies");
- if (!genre.isEmpty()) {
- m_mediaListProperties.name = QString("Movies - %1").arg(genre);
- }
- m_mediaListProperties.summary = QString("%1 movies").arg(mediaList.count());
- m_mediaListProperties.type = QString("Sources");
-
- } else if (engineArg.toLower() == "genres") {
- QString genre;
-
- //Parse filter
- if (!engineFilter.isNull()) {
- QStringList argList = engineFilter.split("||");
- genre = argList.at(0);
- }
-
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectGenre();
- videoQuery.isMovie(true);
- if (!genre.isEmpty()) {
- videoQuery.hasGenre(genre);
- }
- videoQuery.orderBy("?genre");
-
- //Execute Query
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- QString genre = it.binding("genre").literal().toString().trimmed();
- if (!genre.isEmpty()) {
- MediaItem mediaItem;
- mediaItem.url = QString("video://movies?%1").arg(genre);
- mediaItem.title = genre;
- mediaItem.type = QString("Category");
- mediaItem.nowPlaying = false;
- mediaItem.artwork = KIcon("flag-green");
- mediaList.append(mediaItem);
- }
- }
-
- m_mediaListProperties.name = QString("Genre");
- m_mediaListProperties.summary = QString("%1 genres").arg(mediaList.count());
- m_mediaListProperties.type = QString("Categories");
-
- } else if (engineArg.toLower() == "search") {
- VideoQuery videoQuery = VideoQuery(true);
- videoQuery.selectResource();
- videoQuery.selectTitle(true);
- videoQuery.selectDescription(true);
- videoQuery.selectRating(true);
- videoQuery.selectDuration(true);
- videoQuery.selectSeriesName(true);
- videoQuery.selectSeason(true);
- videoQuery.selectEpisode(true);
- videoQuery.selectCreated(true);
- videoQuery.selectGenre(true);
- videoQuery.selectIsMovie(true);
- videoQuery.selectIsTVShow(true);
- videoQuery.selectArtwork(true);
- videoQuery.searchString(engineFilter);
- videoQuery.orderBy("?title ?created");
-
- //Execute Query
- Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
-
- //Build media list from results
- while( it.next() ) {
- MediaItem mediaItem = createMediaItem(it);
- if (it.binding("isMovie").literal().toBool()) {
- mediaItem.artwork = KIcon("tool-animator");
- mediaItem.fields["videoType"] = "Movie";
- } else if (it.binding("isTVShow").literal().toBool()) {
- mediaItem.artwork = KIcon("video-television");
- mediaItem.fields["videoType"] = "TV Show";
- } else {
- mediaItem.artwork = KIcon("video-x-generic");
- mediaItem.fields["videoType"] = "Video Clip";
- }
- mediaList.append(mediaItem);
- }
-
- if (mediaList.isEmpty()) {
- MediaItem noResults;
- noResults.url = "video://";
- noResults.title = "No results";
- noResults.type = "Message";
- mediaList << noResults;
- }
-
- m_mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- m_mediaListProperties.type = QString("Sources");
-
- }
- }
-
- model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
-
- //Check if MediaItems in mediaList exist
- QList<MediaItem> mediaItems = Utilities::mediaItemsDontExist(mediaList);
- if (mediaItems.count() > 0) {
- model()->updateMediaItems(mediaItems);
- }
-
- m_requestSignature = QString();
- m_subRequestSignature = QString();
- //exec();
-
-}
-
-void VideoListEngine::setFilterForSources(const QString& engineFilter)
-{
- //Always return songs
- m_mediaListProperties.lri = QString("video://?%1").arg(engineFilter);
-}
-
-
-
-VideoQuery::VideoQuery(bool distinct) :
- m_distinct(distinct),
- m_selectResource(false),
- m_selectSeason(false),
- m_selectSeriesName(false),
- m_selectTitle(false),
- m_selectDuration(false),
- m_selectEpisode(false),
- m_selectDescription(false),
- m_selectIsTVShow(false),
- m_selectIsMovie(false) {
-}
-
-void VideoQuery::selectResource() {
- m_selectResource = true;
-}
-
-void VideoQuery::selectSeason(bool optional) {
- m_selectSeason = true;
- m_seasonCondition = addOptional(optional,
- QString("?r <%1> ?season . ")
- .arg(MediaVocabulary().videoSeriesSeason().toString()));
-}
-
-void VideoQuery::selectSeriesName(bool optional) {
- m_selectSeriesName = true;
- m_seriesNameCondition = addOptional(optional,
- QString("?r <%1> ?seriesName . ")
- .arg(MediaVocabulary().videoSeriesName().toString()));
-}
-
-void VideoQuery::selectTitle(bool optional) {
- m_selectTitle = true;
- m_titleCondition = addOptional(optional,
- QString("?r <%1> ?title . ")
- .arg(MediaVocabulary().title().toString()));
-}
-
-void VideoQuery::selectDuration(bool optional) {
- m_selectDuration = true;
- m_durationCondition = addOptional(optional,
- QString("?r <%1> ?duration . ")
- .arg(MediaVocabulary().duration().toString()));
-}
-
-void VideoQuery::selectEpisode(bool optional) {
- m_selectEpisode = true;
- m_episodeCondition = addOptional(optional,
- QString("?r <%1> ?episode . ")
- .arg(MediaVocabulary().videoSeriesEpisode().toString()));
-}
-
-void VideoQuery::selectDescription(bool optional) {
- m_selectDescription = true;
- m_descriptionCondition = addOptional(optional,
- QString("?r <%1> ?description . ")
- .arg(MediaVocabulary().description().toString()));
-}
-
-void VideoQuery::selectCreated(bool optional) {
- m_selectCreated = true;
- m_createdCondition = addOptional(optional,
- QString("?r <%1> ?created . ")
- .arg(MediaVocabulary().created().toString()));
-}
-void VideoQuery::selectGenre(bool optional) {
- m_selectGenre = true;
- m_genreCondition = addOptional(optional,
- QString("?r <%1> ?genre . ")
- .arg(MediaVocabulary().genre().toString()));
-}
-
-void VideoQuery::selectArtwork(bool optional) {
- m_selectArtwork = true;
- m_artworkCondition = addOptional(optional,
- QString("?r <%1> ?artwork . ")
- .arg(MediaVocabulary().artwork().toString()));
-}
-
-void VideoQuery::selectRating(bool optional) {
- m_selectRating = true;
- m_ratingCondition = addOptional(optional,
- QString("?r <%1> ?rating . ")
- .arg(Soprano::Vocabulary::NAO::numericRating().toString()));
-}
-
-void VideoQuery::selectIsTVShow(bool optional) {
- m_selectIsTVShow = true;
- m_TVShowCondition = addOptional(optional,
- QString("?r <%1> ?isTVShow . ")
- .arg(MediaVocabulary().videoIsTVShow().toString()));
-}
-
-void VideoQuery::selectIsMovie(bool optional) {
- m_selectIsMovie = true;
- m_movieCondition = addOptional(optional,
- QString("?r <%1> ?isMovie . ")
- .arg(MediaVocabulary().videoIsMovie().toString()));
-}
-
-void VideoQuery::isTVShow(bool flag) {
- if (flag) {
- m_TVShowCondition = QString("?r <%1> %2 . ")
- .arg(MediaVocabulary().videoIsTVShow().toString())
- .arg(Soprano::Node::literalToN3(true));
- } else {
- m_TVShowCondition = QString(
- "OPTIONAL { ?r <%1> ?isTVShow } "
- "FILTER ( !bound(?isTVShow) || !?isTVShow ) ")
- .arg(MediaVocabulary().videoIsTVShow().toString());
- }
-
-}
-
-void VideoQuery::isMovie(bool flag) {
- if (flag) {
- m_movieCondition = QString("?r <%1> %2 . ")
- .arg(MediaVocabulary().videoIsMovie().toString())
- .arg(Soprano::Node::literalToN3(true));
- } else {
- m_movieCondition = QString(
- "OPTIONAL { ?r <%1> ?isMovie } "
- "FILTER ( !bound(?isMovie) || !?isMovie ) ")
- .arg(MediaVocabulary().videoIsMovie().toString());
- }
-}
-
-void VideoQuery::hasSeason(int season) {
- m_seasonCondition = QString("?r <%1> %2 . "
- "?r <%1> ?season . ")
- .arg(MediaVocabulary().videoSeriesSeason().toString())
- .arg(Soprano::Node::literalToN3(season));
-}
-
-void VideoQuery::hasNoSeason() {
- m_seasonCondition = QString(
- "OPTIONAL { ?r <%1> ?season } "
- "FILTER ( !bound(?season) ) ")
- .arg(MediaVocabulary().videoSeriesSeason().toString());
-}
-
-void VideoQuery::hasSeriesName(QString seriesName) {
- m_seriesNameCondition = QString("?r <%1> %2 . "
- "?r <%1> ?seriesName . ")
- .arg(MediaVocabulary().videoSeriesName().toString())
- .arg(Soprano::Node::literalToN3(seriesName));
-}
-
-void VideoQuery::hasGenre(QString genre) {
- m_genreCondition = QString("?r <%1> %2 . "
- "?r <%1> ?genre . ")
- .arg(MediaVocabulary().genre().toString())
- .arg(Soprano::Node::literalToN3(genre));
-}
-
-void VideoQuery::hasNoSeriesName() {
- m_seriesNameCondition = QString(
- "OPTIONAL { ?r <%1> ?seriesName } "
- "FILTER (!bound(?seriesName) || regex(str(?seriesName), \"^$\")) ")
- .arg(MediaVocabulary().videoSeriesName().toString());
-}
-
-void VideoQuery::searchString(QString str) {
- if (! str.isEmpty()) {
- m_searchCondition = QString(
- "FILTER (regex(str(?title),\"%1\",\"i\") || "
- "regex(str(?description),\"%1\",\"i\")) ")
- .arg(str);
- }
-}
-
-
-void VideoQuery::orderBy(QString var) {
- if (!var.isEmpty()) {
- m_order = "ORDER BY " + var;
- }
-}
-
-
-QString VideoQuery::addOptional(bool optional, QString str) {
- if (optional) {
- return QString("OPTIONAL { ") + str + "} . ";
- } else {
- return str;
- }
-}
-
-QString VideoQuery::getPrefix() {
- return QString("PREFIX xesam: <%1> "
- "PREFIX rdf: <%2> "
- "PREFIX nmm: <%3> "
- "PREFIX xls: <%4> "
- "PREFIX nie: <http://www.semanticdesktop.org/ontologies/2007/01/19/nie#> ")
- .arg(Soprano::Vocabulary::Xesam::xesamNamespace().toString())
- .arg(Soprano::Vocabulary::RDF::rdfNamespace().toString())
- .arg("http://www.semanticdesktop.org/ontologies/nmm#")
- .arg(Soprano::Vocabulary::XMLSchema::xsdNamespace().toString());
-}
-
-Soprano::QueryResultIterator VideoQuery::executeSelect(Soprano::Model* model) {
- QString queryString = getPrefix();
- queryString += "SELECT ";
-
- if (m_distinct)
- queryString += "DISTINCT ";
- if (m_selectResource)
- queryString += "?r ?url ";
- if (m_selectSeason)
- queryString += "?season ";
- if (m_selectSeriesName)
- queryString += "?seriesName ";
- if (m_selectTitle)
- queryString += "?title ";
- if (m_selectDuration)
- queryString += "?duration ";
- if (m_selectEpisode)
- queryString += "?episode ";
- if (m_selectDescription)
- queryString += "?description ";
- if (m_selectCreated)
- queryString += "?created ";
- if (m_selectGenre)
- queryString += "?genre ";
- if (m_selectRating)
- queryString += "?rating ";
- if (m_selectIsTVShow)
- queryString += "?isTVShow ";
- if (m_selectIsMovie)
- queryString += "?isMovie ";
- if (m_selectArtwork)
- queryString += "?artwork ";
-
- //NOTE: nie:url is not in any released nie ontology that I can find.
- // In future KDE will use nfo:fileUrl so this will need to be changed.
- queryString += QString("WHERE { ?r rdf:type <%1> . OPTIONAL { ?r nie:url ?url } . ")
- .arg(MediaVocabulary().typeVideo().toString());
-
- queryString += m_seasonCondition;
- queryString += m_seriesNameCondition;
- queryString += m_titleCondition;
- queryString += m_durationCondition;
- queryString += m_episodeCondition;
- queryString += m_descriptionCondition;
- queryString += m_createdCondition;
- queryString += m_genreCondition;
- queryString += m_ratingCondition;
- queryString += m_TVShowCondition;
- queryString += m_movieCondition;
- queryString += m_searchCondition;
- queryString += m_artworkCondition;
-
- queryString += "} ";
-
- queryString += m_order;
-
- return model->executeQuery(queryString,
- Soprano::Query::QueryLanguageSparql);
-}
-
-bool VideoQuery::executeAsk(Soprano::Model* model) {
- QString queryString = getPrefix();
- queryString += QString("ASK { ?r rdf:type <%1> . ")
- .arg(MediaVocabulary().typeVideo().toString());
-
- queryString += m_seasonCondition;
- queryString += m_seriesNameCondition;
- queryString += m_titleCondition;
- queryString += m_durationCondition;
- queryString += m_episodeCondition;
- queryString += m_descriptionCondition;
- queryString += m_createdCondition;
- queryString += m_genreCondition;
- queryString += m_TVShowCondition;
- queryString += m_movieCondition;
- queryString += m_artworkCondition;
- queryString += "} ";
-
- return model->executeQuery(queryString,
- Soprano::Query::QueryLanguageSparql)
- .boolValue();
-}
diff --git a/platform/videolistengine.h b/platform/videolistengine.h
deleted file mode 100644
index 41a156c..0000000
--- a/platform/videolistengine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef VIDEOLISTENGINE_H
-#define VIDEOLISTENGINE_H
-
-#include "nepomuklistengine.h"
-#include <QtCore>
-
-class MediaItem;
-class MediaListProperties;
-class ListEngineFactory;
-
-class VideoQuery {
-public:
- VideoQuery(bool distinct = true);
-
- void selectResource();
- void selectSeason(bool optional=false);
- void selectSeriesName(bool optional=false);
- void selectTitle(bool optional=false);
- void selectDuration(bool optional=false);
- void selectEpisode(bool optional=false);
- void selectDescription(bool optional=false);
- void selectCreated(bool optional=false);
- void selectGenre(bool optional=false);
- void selectIsTVShow(bool optional=false);
- void selectIsMovie(bool optional=false);
- void selectRating(bool optional=false);
- void selectArtwork(bool optional=false);
-
- void isTVShow(bool flag);
- void isMovie(bool flag);
-
- void hasSeason(int season);
- void hasNoSeason();
-
- void hasSeriesName(QString seriesName);
- void hasGenre(QString genre);
- void hasNoSeriesName();
-
- void searchString(QString str);
-
- void orderBy(QString var);
-
-
- Soprano::QueryResultIterator executeSelect(Soprano::Model* model);
- bool executeAsk(Soprano::Model* model);
-
-private:
- bool m_distinct;
-
- bool m_selectResource;
- bool m_selectSeason;
- bool m_selectSeriesName;
- bool m_selectTitle;
- bool m_selectDuration;
- bool m_selectEpisode;
- bool m_selectDescription;
- bool m_selectCreated;
- bool m_selectGenre;
- bool m_selectIsTVShow;
- bool m_selectIsMovie;
- bool m_selectRating;
- bool m_selectArtwork;
-
- QString m_seasonCondition;
- QString m_seriesNameCondition;
- QString m_titleCondition;
- QString m_durationCondition;
- QString m_episodeCondition;
- QString m_descriptionCondition;
- QString m_createdCondition;
- QString m_genreCondition;
- QString m_TVShowCondition;
- QString m_movieCondition;
- QString m_searchCondition;
- QString m_ratingCondition;
- QString m_artworkCondition;
-
- QString m_order;
-
- QString addOptional(bool optional, QString str);
- QString getPrefix();
-};
-
-class VideoListEngine : public NepomukListEngine
-{
- Q_OBJECT
-
- public:
- VideoListEngine(ListEngineFactory *parent);
- ~VideoListEngine();
- void run();
- void setFilterForSources(const QString& engineFilter);
-
- private:
- MediaItem createMediaItem(Soprano::QueryResultIterator& it);
-
-
- Q_SIGNALS:
- void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
-};
-#endif // VIDEOLISTENGINE_H
-
diff --git a/savedlistsmanager.cpp b/savedlistsmanager.cpp
deleted file mode 100644
index 95c3d2f..0000000
--- a/savedlistsmanager.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-/* BANGARANG MEDIA PLAYER
-* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
-* <http://gitorious.org/bangarang>
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "savedlistsmanager.h"
-#include "platform/utilities.h"
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include "platform/mediaitemmodel.h"
-#include "platform/playlist.h"
-
-#include <KStandardDirs>
-#include <KMessageBox>
-#include <QFile>
-#include <Nepomuk/ResourceManager>
-
-SavedListsManager::SavedListsManager(MainWindow * parent) : QObject(parent)
-{
- m_parent = parent;
- ui = m_parent->ui;
-
- ui->aListSourceSelection->setEnabled(false);
- ui->vListSourceSelection->setEnabled(false);
- loadSavedListsIndex();
-
- connect(ui->addAudioList, SIGNAL(clicked()), this, SLOT(showAudioListSave()));
- connect(ui->addVideoList, SIGNAL(clicked()), this, SLOT(showVideoListSave()));
- connect(ui->aCancelSaveList, SIGNAL(clicked()), this, SLOT(hideAudioListSave()));
- connect(ui->vCancelSaveList, SIGNAL(clicked()), this, SLOT(hideVideoListSave()));
- connect(ui->saveAudioList, SIGNAL(clicked()), this, SLOT(saveAudioList()));
- connect(ui->saveVideoList, SIGNAL(clicked()), this, SLOT(saveVideoList()));
- connect(ui->aNewListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
- connect(ui->vNewListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
- connect(ui->aNewListName, SIGNAL(returnPressed()), this, SLOT(saveAudioList()));
- connect(ui->vNewListName, SIGNAL(returnPressed()), this, SLOT(saveVideoList()));
- connect(ui->removeAudioList, SIGNAL(clicked()), this, SLOT(removeAudioList()));
- connect(ui->removeVideoList, SIGNAL(clicked()), this, SLOT(removeVideoList()));
-
-
- connect(ui->mediaView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(selectionChanged(const QItemSelection, const QItemSelection)));
- connect(ui->audioLists->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(audioListsSelectionChanged(const QItemSelection, const QItemSelection)));
- connect(ui->videoLists->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(videoListsSelectionChanged(const QItemSelection, const QItemSelection)));
- connect(m_parent->m_mediaItemModel, SIGNAL(mediaListChanged()), this, SLOT(mediaListChanged()));
-
- Nepomuk::ResourceManager::instance()->init();
- if (Nepomuk::ResourceManager::instance()->initialized()) {
- m_nepomukInited = true;
- } else {
- m_nepomukInited = false;
- }
-
-}
-
-SavedListsManager::~SavedListsManager()
-{
-}
-
-void SavedListsManager::showAudioListSave()
-{
- ui->audioListsStack->setCurrentIndex(1);
- ui->aNewListName->setText("Untitled");
- if (ui->aListSourceSelection->isEnabled()) {
- ui->aListSourceSelection->setChecked(true);
- } else if (ui->aListSourceView->isEnabled()) {
- ui->aListSourceView->setChecked(true);
- } else {
- ui->aListSourcePlaylist->setChecked(true);
- }
- ui->aNewListName->setFocus();
- enableValidSave();
-}
-
-void SavedListsManager::showVideoListSave()
-{
- ui->videoListsStack->setCurrentIndex(1);
- ui->vNewListName->setText("Untitled");
- if (ui->vListSourceSelection->isEnabled()) {
- ui->vListSourceSelection->setChecked(true);
- } else if (ui->vListSourceView->isEnabled()) {
- ui->vListSourceView->setChecked(true);
- } else {
- ui->vListSourcePlaylist->setChecked(true);
- }
- ui->vNewListName->setFocus();
- enableValidSave();
-}
-
-void SavedListsManager::hideAudioListSave()
-{
- ui->aNewListName->clear();
- ui->audioListsStack->setCurrentIndex(0);
-}
-
-void SavedListsManager::hideVideoListSave()
-{
- ui->vNewListName->clear();
- ui->videoListsStack->setCurrentIndex(0);
-}
-
-void SavedListsManager::saveAudioList()
-{
- if (ui->aListSourceSelection->isChecked()) {
- //Get selected media items and save
- QList<MediaItem> mediaList;
- QList<MediaItem> viewMediaList = m_parent->m_mediaItemModel->mediaList();
- QModelIndexList selectedRows = ui->mediaView->selectionModel()->selectedRows();
- for (int i = 0 ; i < selectedRows.count() ; ++i) {
- mediaList.append(viewMediaList.at(selectedRows.at(i).row()));
- }
- saveMediaList(mediaList, ui->aNewListName->text(), QString("Audio"));
- } else if (ui->aListSourceView->isChecked()) {
- saveView(ui->aNewListName->text(), QString("Audio"));
- } else if (ui->aListSourcePlaylist->isChecked()) {
- QList<MediaItem> mediaList = m_parent->m_playlist->playlistModel()->mediaList();
- saveMediaList(mediaList, ui->aNewListName->text(), QString("Audio"));
- }
- MediaListProperties audioListsProperties = m_parent->m_audioListsModel->mediaListProperties();
- m_parent->m_audioListsModel->clearMediaListData();
- m_parent->m_audioListsModel->setMediaListProperties(audioListsProperties);
- m_parent->m_audioListsModel->load();
- hideAudioListSave();
-}
-
-void SavedListsManager::saveVideoList()
-{
- if (ui->vListSourceSelection->isChecked()) {
- //Get selected media items and save
- QList<MediaItem> mediaList;
- QList<MediaItem> viewMediaList = m_parent->m_mediaItemModel->mediaList();
- QModelIndexList selectedRows = ui->mediaView->selectionModel()->selectedRows();
- for (int i = 0 ; i < selectedRows.count() ; ++i) {
- mediaList.append(viewMediaList.at(selectedRows.at(i).row()));
- }
- saveMediaList(mediaList, ui->vNewListName->text(), QString("Video"));
- } else if (ui->vListSourceView->isChecked()) {
- saveView(ui->vNewListName->text(), QString("Video"));
- } else if (ui->vListSourcePlaylist->isChecked()) {
- QList<MediaItem> mediaList = m_parent->m_playlist->playlistModel()->mediaList();
- saveMediaList(mediaList, ui->vNewListName->text(), QString("Video"));
- }
- MediaListProperties videoListsProperties = m_parent->m_videoListsModel->mediaListProperties();
- m_parent->m_videoListsModel->clearMediaListData();
- m_parent->m_videoListsModel->setMediaListProperties(videoListsProperties);
- m_parent->m_videoListsModel->load();
- hideVideoListSave();
-}
-
-void SavedListsManager::removeAudioList()
-{
- if (ui->audioLists->selectionModel()->selectedIndexes().count() > 0){
- int selectedRow = ui->audioLists->selectionModel()->selectedIndexes().at(0).row();
- QString name = m_parent->m_audioListsModel->mediaItemAt(selectedRow).title;
-
- KGuiItem removeSavedList;
- removeSavedList.setText(QString("Remove"));
- removeSavedList.setIcon(KIcon("list-remove"));
- QString message = QString("Are you sure you want to remove \"%1\"?").arg(name);
-
- if (KMessageBox::warningContinueCancel(m_parent, message, QString(), removeSavedList) == KMessageBox::Continue) {
- //Remove M3U file
- QString filename = name;
- filename = filename.replace(" ", "");
- QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/Audio-%1.m3u").arg(filename), false));
-
- QString savedListEntry = QString("Audio:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedAudioLists.count(); i++) {
- if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedAudioLists.removeAt(rowsToRemove.at(i));
- }
- updateSavedListsIndex();
- MediaListProperties audioListsProperties = m_parent->m_audioListsModel->mediaListProperties();
- m_parent->m_audioListsModel->clearMediaListData();
- m_parent->m_audioListsModel->setMediaListProperties(audioListsProperties);
- m_parent->m_audioListsModel->load();
- }
- }
-}
-
-void SavedListsManager::removeVideoList()
-{
- if (ui->videoLists->selectionModel()->selectedIndexes().count() > 0){
- int selectedRow = ui->videoLists->selectionModel()->selectedIndexes().at(0).row();
- QString name = m_parent->m_videoListsModel->mediaItemAt(selectedRow).title;
-
- KGuiItem removeSavedList;
- removeSavedList.setText(QString("Remove"));
- removeSavedList.setIcon(KIcon("list-remove"));
- QString message = QString("Are you sure you want to remove \"%1\"?").arg(name);
-
- if (KMessageBox::warningContinueCancel(m_parent, message, QString(), removeSavedList) == KMessageBox::Continue) {
- //Remove M3U file
- QString filename = name;
- filename = filename.replace(" ", "");
- QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/Video-%1.m3u").arg(filename), false));
-
- QString savedListEntry = QString("Video:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedVideoLists.count(); i++) {
- if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedVideoLists.removeAt(rowsToRemove.at(i));
- }
- updateSavedListsIndex();
- MediaListProperties videoListsProperties = m_parent->m_videoListsModel->mediaListProperties();
- m_parent->m_videoListsModel->clearMediaListData();
- m_parent->m_videoListsModel->setMediaListProperties(videoListsProperties);
- m_parent->m_videoListsModel->load();
- }
- }
-}
-
-void SavedListsManager::enableValidSave(QString newText)
-{
- ui->saveAudioList->setEnabled(true);
- if (!ui->aNewListName->text().isEmpty()) {
- ui->saveAudioList->setEnabled(true);
- } else {
- ui->saveAudioList->setEnabled(false);
- }
- if (!ui->vNewListName->text().isEmpty()) {
- ui->saveVideoList->setEnabled(true);
- } else {
- ui->saveVideoList->setEnabled(false);
- }
- Q_UNUSED(newText); //not used since method may be called directly
-}
-
-void SavedListsManager::audioListsSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
-{
- if (selected.indexes().count() > 0) {
- bool isSavedList = selected.indexes().at(0).data(MediaItem::IsSavedListRole).toBool();
- if (isSavedList) {
- ui->removeAudioList->setEnabled(true);
- } else {
- ui->removeAudioList->setEnabled(false);
- }
- }
- Q_UNUSED(selected);
- Q_UNUSED(deselected);
-}
-
-void SavedListsManager::videoListsSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
-{
- if (selected.indexes().count() > 0) {
- bool isSavedList = selected.indexes().at(0).data(MediaItem::IsSavedListRole).toBool();
- if (isSavedList) {
- ui->removeVideoList->setEnabled(true);
- } else {
- ui->removeVideoList->setEnabled(false);
- }
- }
- Q_UNUSED(selected);
- Q_UNUSED(deselected);
-}
-
-void SavedListsManager::selectionChanged (const QItemSelection & selected, const QItemSelection & deselected )
-{
- if (ui->mediaView->selectionModel()->selectedRows().count() > 0) {
- QString listItemType = m_parent->m_mediaItemModel->mediaItemAt(0).type;
- if ((listItemType == "Audio") || (listItemType == "Video") || (listItemType == "Image")) {
- ui->aListSourceSelection->setEnabled(true);
- ui->vListSourceSelection->setEnabled(true);
- }
- } else {
- ui->aListSourceSelection->setChecked(false);
- ui->vListSourceSelection->setChecked(false);
- ui->aListSourceSelection->setEnabled(false);
- ui->vListSourceSelection->setEnabled(false);
- }
- Q_UNUSED(selected);
- Q_UNUSED(deselected);
-}
-
-void SavedListsManager::mediaListChanged()
-{
- if (m_parent->m_mediaItemModel->rowCount() > 0) {
- QString listItemType = m_parent->m_mediaItemModel->mediaItemAt(0).type;
- if (listItemType == "Audio" && m_nepomukInited) {
- ui->aListSourceView->setEnabled(true);
- } else if (listItemType == "Video" && m_nepomukInited) {
- ui->vListSourceView->setEnabled(true);
- } else {
- ui->aListSourceView->setChecked(false);
- ui->vListSourceView->setChecked(false);
- ui->aListSourceView->setEnabled(false);
- ui->vListSourceView->setEnabled(false);
- }
- }
-}
-
-void SavedListsManager::saveMediaList(QList<MediaItem> mediaList, QString name, QString type)
-{
- if (!name.isEmpty()) {
-
- //Create and populate M3U file
- QString filename = name;
- filename = filename.replace(" ", "");
- QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), false));
- QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), true));
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- return;
- }
- QTextStream out(&file);
- out << "#EXTM3U" << "\r\n";
- for (int i = 0; i < mediaList.count(); i++) {
- out << "#EXTINF:" << mediaList.at(i).fields["duration"].toInt() << "," << mediaList.at(i).title << "\r\n";
- out << mediaList.at(i).url << "\r\n";
- }
- file.close();
-
- //Save list to index file
- if (type == "Audio") {
- QString indexEntry = QString("%1:::%2:::%3")
- .arg(type)
- .arg(name)
- .arg(QString("savedlists://%1-%2.m3u").arg(type).arg(filename));
- QString savedListEntry = QString("Audio:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedAudioLists.count(); i++) {
- if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedAudioLists.removeAt(rowsToRemove.at(i));
- }
- m_savedAudioLists << indexEntry;
- } else if (type == "Video") {
- QString indexEntry = QString("%1:::%2:::%3")
- .arg(type)
- .arg(name)
- .arg(QString("savedlists://%1-%2.m3u").arg(type).arg(filename));
- QString savedListEntry = QString("Video:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedVideoLists.count(); i++) {
- if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedVideoLists.removeAt(rowsToRemove.at(i));
- }
- m_savedVideoLists << indexEntry;
- }
- updateSavedListsIndex();
- }
-}
-
-void SavedListsManager::saveView(QString name, QString type)
-{
- if (!name.isEmpty()) {
- //Add to saved list index
- if (type == "Audio") {
- QString indexEntry = QString("%1:::%2:::%3")
- .arg(type)
- .arg(name)
- .arg(m_parent->m_mediaItemModel->mediaListProperties().lri);
- QString savedListEntry = QString("Audio:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedAudioLists.count(); i++) {
- if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedAudioLists.removeAt(rowsToRemove.at(i));
- }
- m_savedAudioLists << indexEntry;
- } else if (type == "Video") {
- QString indexEntry = QString("%1:::%2:::%3")
- .arg(type)
- .arg(name)
- .arg(m_parent->m_mediaItemModel->mediaListProperties().lri);
- QString savedListEntry = QString("Video:::%1")
- .arg(name);
- QList<int> rowsToRemove;
- for (int i = 0; i < m_savedVideoLists.count(); i++) {
- if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
- rowsToRemove << i;
- }
- }
- for (int i = 0; i < rowsToRemove.count(); i++) {
- m_savedVideoLists.removeAt(rowsToRemove.at(i));
- }
- m_savedVideoLists << indexEntry;
- }
- updateSavedListsIndex();
- }
-}
-
-
-void SavedListsManager::loadSavedListsIndex()
-{
- //Load lists from index
- m_savedAudioLists.clear();
- m_savedVideoLists.clear();
- QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
- if (!indexFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return;
- }
- QTextStream in(&indexFile);
- while (!in.atEnd()) {
- QString line = in.readLine();
- QStringList nameUrl = line.split(":::");
- if (nameUrl.count() >= 3) {
- QString type = nameUrl.at(0).trimmed();
- if (type == "Audio") {
- m_savedAudioLists << line;
- } else if (type == "Video") {
- m_savedVideoLists << line;
- }
- }
- }
- indexFile.close();
-}
-void SavedListsManager::updateSavedListsIndex()
-{
- QFile::remove(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
- QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", true));
- if (!indexFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- return;
- }
- QTextStream outIndex(&indexFile);
- for (int i = 0; i < m_savedAudioLists.count(); i++) {
- outIndex << m_savedAudioLists.at(i) << "\r\n";
- }
- for (int i = 0; i < m_savedVideoLists.count(); i++) {
- outIndex << m_savedVideoLists.at(i) << "\r\n";
- }
- indexFile.close();
-}
-
-
-
diff --git a/CMakeLists.txt b/src/CMakeLists.txt
similarity index 76%
copy from CMakeLists.txt
copy to src/CMakeLists.txt
index 1ebc440..57aa923 100644
--- a/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,8 @@ INCLUDE(KDE4Defaults)
ADD_DEFINITIONS( ${QT_DEFINITIONS} ${KDE4_DEFINITIONS} )
+add_subdirectory( platform/nepomukwriter )
+
INCLUDE_DIRECTORIES(
${KDE4_INCLUDES}
${KDEMULTIMEDIA_INCLUDE_DIR}
@@ -29,23 +31,24 @@ SET(BangarangSources
infomanager.cpp
savedlistsmanager.cpp
actionsmanager.cpp
- platform/mediaitemmodel.cpp
- platform/musiclistengine.cpp
- platform/videolistengine.cpp
- platform/filelistengine.cpp
- platform/cdlistengine.cpp
- platform/dvdlistengine.cpp
+ videosettings.cpp
+ platform/mediaitemmodel.cpp
+ platform/musiclistengine.cpp
+ platform/videolistengine.cpp
+ platform/filelistengine.cpp
+ platform/cdlistengine.cpp
+ platform/dvdlistengine.cpp
platform/medialistsengine.cpp
platform/audiostreamlistengine.cpp
platform/nepomuklistengine.cpp
platform/semanticslistengine.cpp
- platform/playlist.cpp
- platform/utilities.cpp
- platform/listengine.cpp
- platform/savedlistsengine.cpp
- platform/listenginefactory.cpp
- platform/mediaindexer.cpp
- platform/mediavocabulary.cpp
+ platform/playlist.cpp
+ platform/utilities.cpp
+ platform/listengine.cpp
+ platform/savedlistsengine.cpp
+ platform/listenginefactory.cpp
+ platform/mediaindexer.cpp
+ platform/mediavocabulary.cpp
platform/medialistcache.cpp
platform/cachelistengine.cpp
platform/audioclipslistengine.cpp
@@ -53,11 +56,10 @@ SET(BangarangSources
KDE4_ADD_UI_FILES(BangarangSources mainwindow.ui)
-kde4_add_app_icon(BangarangSources "${CMAKE_CURRENT_SOURCE_DIR}/hi*.png")
-
-
KDE4_ADD_EXECUTABLE(bangarang ${BangarangSources})
+kde4_add_app_icon(BangarangSources "${CMAKE_CURRENT_SOURCE_DIR}/../icons/hi*.png")
+
TARGET_LINK_LIBRARIES(bangarang
${KDE4_KDEUI_LIBS}
${KDE4_KPARTS_LIBS}
@@ -72,9 +74,6 @@ TARGET_LINK_LIBRARIES(bangarang
########### install files ###############
install(TARGETS bangarang ${INSTALL_TARGETS_DEFAULT_ARGS})
-install(FILES bangarang.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
#install(FILES <bangarangDataFilesHere> DESTINATION ${DATA_INSTALL_DIR}/bangarang)
#install(FILES bangarangrc DESTINATION ${CONFIG_INSTALL_DIR})
-
kde4_install_icons( ${ICON_INSTALL_DIR} )
-
diff --git a/src/Messages.sh b/src/Messages.sh
new file mode 100755
index 0000000..c6e840c
--- /dev/null
+++ b/src/Messages.sh
@@ -0,0 +1,14 @@
+#! /bin/bash
+#Script to extract translateble messages from the code.
+#The following part is used to do the same as Scripty in KDE svn
+
+XGETTEXT="xgettext --copyright-holder=This_file_is_part_of_KDE --from-code=UTF-8 -C --kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 --msgid-bugs-address=http://bugs.kde.org"
+EXTRACTRC="extractrc"
+export XGETTEXT EXTRACTRC
+
+echo 'i18nc("NAME OF TRANSLATORS","Your names");' >> rc.cpp
+echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> rc.cpp
+
+$EXTRACTRC *.ui >> rc.cpp
+$XGETTEXT *.cpp platform/*.cpp -o ../translations/bangarang.pot
+rm -f rc.cpp
\ No newline at end of file
diff --git a/src/actionsmanager.cpp b/src/actionsmanager.cpp
new file mode 100644
index 0000000..61bc64c
--- /dev/null
+++ b/src/actionsmanager.cpp
@@ -0,0 +1,530 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "actionsmanager.h"
+#include "platform/utilities.h"
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "platform/mediaitemmodel.h"
+#include "platform/playlist.h"
+#include "infomanager.h"
+#include "savedlistsmanager.h"
+#include "videosettings.h"
+
+#include <KStandardDirs>
+#include <KMessageBox>
+#include <KHelpMenu>
+#include <KMenu>
+#include <KDebug>
+#include <QFile>
+
+ActionsManager::ActionsManager(MainWindow * parent) : QObject(parent)
+{
+ m_parent = parent;
+ ui = m_parent->ui;
+
+ m_actionCollection = new KActionCollection(this);
+
+ //Add standard quit shortcut
+ m_quit = new QAction(this);
+ m_quit->setShortcut(Qt::CTRL + Qt::Key_Q);
+ connect(m_quit, SIGNAL(triggered()), qApp, SLOT(quit()));
+ m_parent->addAction(m_quit);
+ m_actionCollection->addAction(i18n("Quit"), m_quit);
+
+ //Play/Pause Action
+ m_playPause = new QAction(this);
+ m_playPause->setShortcut(Qt::Key_Space);
+ connect(m_playPause, SIGNAL(triggered()), this, SLOT(simplePlayPause()));
+ m_parent->addAction(m_playPause);
+
+ //Play Next
+ m_playNext = new QAction(KIcon("media-skip-forward"), i18n("Play next"), this);
+ m_playNext->setShortcut(Qt::Key_Right);
+ connect(m_playNext, SIGNAL(triggered()), m_parent->playlist(), SLOT(playNext()));
+ m_parent->addAction(m_playNext);
+
+ //Play Previous
+ m_playPrevious = new QAction(KIcon("media-skip-backward"), i18n("Play previous"), this);
+ m_playPrevious->setShortcut(Qt::Key_Left);
+ connect(m_playPrevious, SIGNAL(triggered()), m_parent->playlist(), SLOT(playPrevious()));
+ m_parent->addAction(m_playPrevious);
+
+ //Mute
+ m_mute = new QAction(this);
+ m_mute->setShortcut(Qt::Key_M);
+ connect(m_mute, SIGNAL(triggered()), this, SLOT(muteAudio()));
+ m_parent->addAction(m_mute);
+
+ //Play All Action
+ m_playAllAction = new QAction(KIcon("media-playback-start"), i18n("Play all"), this);
+ connect(m_playAllAction, SIGNAL(triggered()), m_parent, SLOT(playAll()));
+ m_actionCollection->addAction(i18n("Play All"), m_playAllAction);
+
+ //Play Selected Action
+ m_playSelectedAction = new QAction(KIcon("media-playback-start"), i18n("Play selected"), this);
+ connect(m_playSelectedAction, SIGNAL(triggered()), m_parent, SLOT(playSelected()));
+ m_actionCollection->addAction(i18n("Play Selected"), m_playSelectedAction);
+
+ //Add Selected To Playlist Action
+ m_addSelectedToPlayListAction = new QAction(KIcon("mail-mark-notjunk"), i18n("Add to playlist"), this);
+ connect(m_addSelectedToPlayListAction, SIGNAL(triggered()), m_parent, SLOT(addSelectedToPlaylist()));
+ m_actionCollection->addAction(i18n("Add to playlist"), m_addSelectedToPlayListAction);
+
+ //Remove Selected From Playlist Action
+ m_removeSelectedToPlayListAction = new QAction(KIcon(), i18n("Remove from playlist"), this);
+ connect(m_removeSelectedToPlayListAction, SIGNAL(triggered()), m_parent, SLOT(removeSelectedFromPlaylist()));
+ m_actionCollection->addAction(i18n("Remove from playlist"), m_removeSelectedToPlayListAction);
+
+ //Show/Hide Controls Shortcut
+ m_showHideControls = new QAction(KIcon("layer-visible-off"), i18n("Hide controls"), this);
+ m_showHideControls->setShortcut(Qt::CTRL + Qt::Key_H);
+ connect(m_showHideControls, SIGNAL(triggered()), this, SLOT(toggleControls()));
+ m_parent->addAction(m_showHideControls);
+ m_actionCollection->addAction(i18n("Hide controls"), m_showHideControls);
+
+ //Show VideoSettings
+ m_showVideoSettings = new QAction(KIcon("video-display"),tr("Show Video Settings"),this);
+ m_showVideoSettings->setShortcut(Qt::CTRL + Qt::Key_V);
+ connect(m_showVideoSettings, SIGNAL(triggered()), this, SLOT(toggleVideoSettings()));
+ m_parent->addAction(m_showVideoSettings);
+ m_actionCollection->addAction(i18n("Show Video Settings"),m_showVideoSettings);
+
+ //Full Screen
+ m_fullScreen = new QAction(this);
+ m_fullScreen->setShortcut(Qt::Key_F11);
+ connect(m_fullScreen, SIGNAL(triggered()), this, SLOT(fullScreenToggle()));
+ m_parent->addAction(m_fullScreen);
+ m_actionCollection->addAction(i18n("Toggle fullscreen"), m_fullScreen);
+
+ //Cancel FullScreen/Cancel Hide Controls
+ m_cancelFullScreenHideControls = new QAction(this);
+ m_cancelFullScreenHideControls->setShortcut(Qt::Key_Escape);
+ connect(m_cancelFullScreenHideControls, SIGNAL(triggered()), this, SLOT(cancelFSHC()));
+ m_parent->addAction(m_cancelFullScreenHideControls);
+
+ //Remove Info for Selected MediaItems
+ m_removeSelectedItemsInfo = new QAction(KIcon("edit-delete-shred"), i18n("Remove selected info"), this);
+ connect(m_removeSelectedItemsInfo, SIGNAL(triggered()), m_parent->infoManager(), SLOT(removeSelectedItemsInfo()));
+ m_parent->addAction(m_removeSelectedItemsInfo);
+
+ //Refresh Media View
+ m_refreshMediaView = new QAction(KIcon("view-refresh"), i18n("Refresh"), this);
+ m_refreshMediaView->setShortcut(Qt::Key_F5);
+ connect(m_refreshMediaView, SIGNAL(triggered()), m_parent->m_mediaItemModel, SLOT(reload()));
+ m_parent->addAction(m_refreshMediaView);
+
+ //Remove selected from playlist
+ m_removeFromSavedList = new QAction(i18n("Remove from list"), this);
+ connect(m_removeFromSavedList, SIGNAL(triggered()), m_parent->savedListsManager(), SLOT(removeSelected()));
+
+ //Add selected to saved audio list
+ m_addToAudioSavedList = new QMenu(i18n("Add to list"), m_parent);
+ connect(m_addToAudioSavedList, SIGNAL(triggered(QAction *)), this, SLOT(addToSavedAudioList(QAction *)));
+
+ //Add selected to saved video list
+ m_addToVideoSavedList = new QMenu(i18n("Add to list "), m_parent);
+ connect(m_addToVideoSavedList, SIGNAL(triggered(QAction *)), this, SLOT(addToSavedVideoList(QAction *)));
+
+ //Add a new audio list
+ m_newAudioList = new QAction(KIcon("list-add"), i18n("New list"), m_parent);
+ connect(m_newAudioList, SIGNAL(triggered()), m_parent->savedListsManager(), SLOT(showAudioListSave()));
+
+ //Add a new video list
+ m_newVideoList = new QAction(KIcon("list-add"), i18n("New list"), m_parent);
+ connect(m_newVideoList, SIGNAL(triggered()), m_parent->savedListsManager(), SLOT(showVideoListSave()));
+
+ //Show Items
+ m_showItems = new QAction(KIcon("system-run"), i18n("Show items"), m_parent);
+ connect(m_showItems, SIGNAL(triggered()), this, SLOT(loadSelectedSources()));
+
+ //Show Info
+ m_showNowPlayingInfo = new QAction(KIcon("help-about"), i18n("Show info"), m_parent);
+ connect(m_showNowPlayingInfo, SIGNAL(triggered()), this, SLOT(showInfoForNowPlaying()));
+
+ //Edit Shortcuts
+ //FIXME: Need to figure out how to use KShortcutsEditor
+ m_editShortcuts = new QAction(KIcon("configure-shortcuts"), i18n("Configure shortcuts..."), this);
+ connect(m_editShortcuts, SIGNAL(triggered()), this, SLOT(showShortcutsEditor()));
+ connect(ui->cancelEditShortcuts, SIGNAL(clicked()), this, SLOT(hideShortcutsEditor()));
+ ui->shortcutsEditor->addCollection(m_actionCollection);
+
+}
+
+ActionsManager::~ActionsManager()
+{
+}
+
+QAction * ActionsManager::quit()
+{
+ return m_quit;
+}
+
+QAction * ActionsManager::playPause()
+{
+ return m_playPause;
+}
+
+QAction * ActionsManager::playNext()
+{
+ return m_playNext;
+}
+
+QAction * ActionsManager::playPrevious()
+{
+ return m_playPrevious;
+}
+
+QAction * ActionsManager::mute()
+{
+ return m_mute;
+}
+
+QAction * ActionsManager::playAll()
+{
+ return m_playAllAction;
+}
+
+QAction * ActionsManager::playSelected()
+{
+ return m_playSelectedAction;
+}
+
+QAction * ActionsManager::addSelectedToPlaylist()
+{
+ return m_addSelectedToPlayListAction;
+}
+
+QAction * ActionsManager::removeSelectedFromPlaylist()
+{
+ return m_removeSelectedToPlayListAction;
+}
+
+QAction * ActionsManager::showHideControls()
+{
+ return m_showHideControls;
+}
+
+QAction * ActionsManager::fullScreen()
+{
+ return m_fullScreen;
+}
+
+QAction * ActionsManager::cancelFullScreenHideControls()
+{
+ return m_cancelFullScreenHideControls;
+}
+
+QAction * ActionsManager::editShortcuts()
+{
+ return m_editShortcuts;
+}
+
+QAction * ActionsManager::removeSelectedItemsInfo()
+{
+ return m_removeSelectedItemsInfo;
+}
+
+QAction * ActionsManager::refreshMediaView()
+{
+ return m_refreshMediaView;
+}
+
+QAction * ActionsManager::showVideoSettings()
+{
+ return m_showVideoSettings;
+}
+
+QAction * ActionsManager::showNowPlayingInfo()
+{
+ return m_showNowPlayingInfo;
+}
+
+QMenu * ActionsManager::mediaViewMenu(bool showAbout)
+{
+ KHelpMenu * helpMenu = new KHelpMenu(m_parent, m_parent->aboutData(), false);
+ helpMenu->menu();
+
+ updateSavedListsMenus();
+
+ QMenu *menu = new QMenu(m_parent);
+ QString type;
+ bool selection = false;
+ int selectedCount = ui->mediaView->selectionModel()->selectedIndexes().count();
+ if (selectedCount != 0) {
+ QModelIndex index = ui->mediaView->selectionModel()->selectedIndexes().at(0);
+ type = index.data(MediaItem::TypeRole).toString();
+ selection = true;
+ } else if (m_parent->m_mediaItemModel->rowCount() > 0) {
+ type = m_parent->m_mediaItemModel->mediaItemAt(0).type;
+ }
+ bool isMedia = false;
+ if ((type == "Audio") ||(type == "Video") || (type == "Image")) {
+ isMedia = true;
+ }
+ bool isCategory = false;
+ if (type == "Category") {
+ isCategory = true;
+ }
+ if (isMedia || isCategory) {
+ if (selection && isMedia) {
+ menu->addAction(addSelectedToPlaylist());
+ menu->addAction(removeSelectedFromPlaylist());
+ menu->addSeparator();
+ }
+ if (selection) menu->addAction(playSelected());
+ menu->addAction(playAll());
+ menu->addSeparator();
+ if (selection && isCategory) {
+ menu->addAction(m_showItems);
+ menu->addSeparator();
+ }
+ if (selection && isMedia) {
+ if (type == "Audio") {
+ if (m_addToAudioSavedList->actions().count() > 0) {
+ menu->addMenu(m_addToAudioSavedList);
+ }
+ } else if (type == "Video") {
+ if (m_addToVideoSavedList->actions().count() > 0) {
+ menu->addMenu(m_addToVideoSavedList);
+ }
+ }
+ if (m_parent->m_mediaItemModel->mediaListProperties().lri.startsWith("savedlists://")) {
+ menu->addAction(removeFromSavedList());
+ }
+ menu->addSeparator();
+ }
+ if (selection && isMedia) {
+ menu->addAction(removeSelectedItemsInfo());
+ menu->addSeparator();
+ }
+
+ menu->addAction(refreshMediaView());
+ menu->addSeparator();
+
+ }
+ if (showAbout) menu->addAction(helpMenu->action(KHelpMenu::menuAboutApp));
+ return menu;
+}
+
+QAction *ActionsManager::removeFromSavedList()
+{
+ return m_removeFromSavedList;
+}
+
+QAction *ActionsManager::newAudioList()
+{
+ return m_newAudioList;
+}
+
+QAction *ActionsManager::newVideoList()
+{
+ return m_newVideoList;
+}
+
+QMenu *ActionsManager::addToSavedAudioListMenu()
+{
+ return m_addToAudioSavedList;
+}
+
+QMenu *ActionsManager::addToSavedVideoListMenu()
+{
+ return m_addToVideoSavedList;
+}
+
+
+//------------------
+//-- Action SLOTS --
+//------------------
+
+void ActionsManager::fullScreenToggle()
+{
+ if (m_parent->isFullScreen()) {
+ m_parent->on_fullScreen_toggled(false);
+ } else {
+ m_parent->on_fullScreen_toggled(true);
+ }
+}
+
+void ActionsManager::toggleControls()
+{
+ if ((!m_parent->isFullScreen()) && (ui->stackedWidget->currentIndex() == 1)) {
+ if (ui->widgetSet->isVisible()) {
+ ui->widgetSet->setVisible(false);
+ ui->nowPlayingToolbar->setVisible(false);
+ m_showHideControls->setIcon(KIcon("layer-visible-on"));
+ } else {
+ ui->widgetSet->setVisible(true);
+ ui->nowPlayingToolbar->setVisible(true);
+ m_showHideControls->setIcon(KIcon("layer-visible-off"));
+ }
+ }
+}
+
+void ActionsManager::toggleVideoSettings()
+{
+ if(ui->contextStack->currentIndex() != 1 ) {
+ m_contextStackWasVisible = ui->contextStack->isVisible();
+ m_previousContextStackIndex = ui->contextStack->currentIndex();
+ ui->contextStack->setCurrentIndex(1);
+ ui->contextStack->setVisible(true);
+ m_showVideoSettings->setText(i18n("Hide Video Settings"));
+ } else {
+ ui->contextStack->setVisible(m_contextStackWasVisible);
+ ui->contextStack->setCurrentIndex(m_previousContextStackIndex);
+ m_showVideoSettings->setText(i18n("Show Video Settings"));
+ }
+}
+
+void ActionsManager::cancelFSHC()
+{
+ if (m_parent->isFullScreen()) {
+ m_parent->on_fullScreen_toggled(false);
+ } else {
+ if (ui->stackedWidget->currentIndex() == 1) {
+ ui->widgetSet->setVisible(true);
+ ui->nowPlayingToolbar->setVisible(true);
+ m_showHideControls->setIcon(KIcon("layer-visible-off"));
+ }
+ }
+}
+
+void ActionsManager::showShortcutsEditor()
+{
+ ui->contextStack->setCurrentIndex(2);
+ ui->contextStack->setVisible(true);
+}
+
+void ActionsManager::hideShortcutsEditor()
+{
+ ui->contextStack->setCurrentIndex(0);
+ ui->contextStack->setVisible(false);
+}
+
+void ActionsManager::simplePlayPause()
+{
+ if (m_parent->playlist()->mediaObject()->state() == Phonon::PlayingState) {
+ m_parent->playlist()->mediaObject()->pause();
+ } else if (m_parent->playlist()->mediaObject()->state() == Phonon::PausedState) {
+ m_parent->playlist()->mediaObject()->play();
+ }
+}
+
+void ActionsManager::muteAudio()
+{
+ bool muted = m_parent->audioOutput()->isMuted();
+ m_parent->audioOutput()->setMuted(!muted);
+}
+
+void ActionsManager::updateSavedListsMenus()
+{
+ m_addToAudioSavedList->clear();
+ m_addToAudioSavedList->addAction(m_newAudioList);
+ QStringList audioListNames = m_parent->savedListsManager()->savedListNames("Audio");
+ for (int i = 0; i < audioListNames.count(); i++) {
+ if (!((audioListNames.at(i) == m_parent->m_mediaItemModel->mediaListProperties().name)
+ && (m_parent->m_mediaItemModel->mediaListProperties().lri.startsWith("savedlists://")))) {
+ QAction * addToSavedList = new QAction(KIcon("view-list-text"), audioListNames.at(i), m_addToAudioSavedList);
+ addToSavedList->setData(audioListNames.at(i));
+ m_addToAudioSavedList->addAction(addToSavedList);
+ }
+ }
+
+ m_addToVideoSavedList->clear();
+ m_addToVideoSavedList->addAction(m_newVideoList);
+ QStringList videoListNames = m_parent->savedListsManager()->savedListNames("Video");
+ for (int i = 0; i < videoListNames.count(); i++) {
+ if (!((videoListNames.at(i) == m_parent->m_mediaItemModel->mediaListProperties().name)
+ && (m_parent->m_mediaItemModel->mediaListProperties().lri.startsWith("savedlists://")))) {
+ QAction * addToSavedList = new QAction(KIcon("view-list-text"), videoListNames.at(i), m_addToVideoSavedList);
+ addToSavedList->setData(audioListNames.at(i));
+ m_addToVideoSavedList->addAction(addToSavedList);
+ }
+ }
+}
+
+void ActionsManager::addToSavedAudioList(QAction *addAction)
+{
+ //Get list of selected items to add
+ QTreeView * view;
+ MediaItemModel * model;
+ if (ui->stackedWidget->currentIndex() == 0 ) {
+ view = ui->mediaView;
+ model = m_parent->m_mediaItemModel;
+ } else {
+ view = ui->playlistView;
+ model = m_parent->playlist()->playlistModel();
+ }
+ QList<MediaItem> mediaList;
+ QModelIndexList selectedRows = view->selectionModel()->selectedRows();
+ for (int i = 0 ; i < selectedRows.count() ; ++i) {
+ mediaList.append(model->mediaItemAt(selectedRows.at(i).row()));
+ }
+
+ //Add to saved list
+ if (mediaList.count() > 0) {
+ QString audioListName = addAction->data().toString();
+ m_parent->savedListsManager()->saveMediaList(mediaList, audioListName, "Audio", true);
+ }
+}
+
+void ActionsManager::addToSavedVideoList(QAction *addAction)
+{
+ //Get list of selected items to add
+ QTreeView * view;
+ MediaItemModel * model;
+ if (ui->stackedWidget->currentIndex() == 0 ) {
+ view = ui->mediaView;
+ model = m_parent->m_mediaItemModel;
+ } else {
+ view = ui->playlistView;
+ model = m_parent->playlist()->playlistModel();
+ }
+ QList<MediaItem> mediaList;
+ QModelIndexList selectedRows = view->selectionModel()->selectedRows();
+ for (int i = 0 ; i < selectedRows.count() ; ++i) {
+ mediaList.append(model->mediaItemAt(selectedRows.at(i).row()));
+ }
+
+ //Add to saved list
+ if (mediaList.count() > 0) {
+ QString videoListName = addAction->data().toString();
+ m_parent->savedListsManager()->saveMediaList(mediaList, videoListName, "Video", true);
+ }
+}
+
+void ActionsManager::loadSelectedSources()
+{
+ m_parent->addListToHistory();
+ QList<MediaItem> mediaList;
+ QModelIndexList selectedRows = ui->mediaView->selectionModel()->selectedRows();
+ for (int i = 0 ; i < selectedRows.count() ; ++i) {
+ mediaList.append(m_parent->m_mediaItemModel->mediaItemAt(selectedRows.at(i).row()));
+ }
+ m_parent->m_mediaItemModel->clearMediaListData();
+ m_parent->m_mediaItemModel->loadSources(mediaList);
+}
+
+void ActionsManager::showInfoForNowPlaying()
+{
+ MediaItemModel * nowPlayingModel = m_parent->playlist()->nowPlayingModel();
+ if(nowPlayingModel->rowCount() > 0) {
+ MediaItem mediaItem = nowPlayingModel->mediaItemAt(0);
+ m_parent->infoManager()->showInfoViewForMediaItem(mediaItem);
+ }
+}
diff --git a/actionsmanager.h b/src/actionsmanager.h
similarity index 70%
rename from actionsmanager.h
rename to src/actionsmanager.h
index 8299d53..1cc57f5 100644
--- a/actionsmanager.h
+++ b/src/actionsmanager.h
@@ -19,6 +19,7 @@
#ifndef ACTIONSMANAGER_H
#define ACTIONSMANAGER_H
+#include "videosettings.h"
#include <KActionCollection>
#include <QObject>
#include <QAction>
@@ -29,6 +30,9 @@ namespace Ui
}
class MainWindow;
+/*
+ * This class creates and manages all actions for bangarang.
+ */
class ActionsManager : public QObject
{
Q_OBJECT
@@ -52,15 +56,26 @@ class ActionsManager : public QObject
QAction *mute();
QAction *removeSelectedItemsInfo();
QAction *refreshMediaView();
-
+ QAction *showVideoSettings();
+ QAction *removeFromSavedList();
+ QAction *newAudioList();
+ QAction *newVideoList();
+ QAction *showItems();
+ QAction *showNowPlayingInfo();
+ QMenu *addToSavedAudioListMenu();
+ QMenu *addToSavedVideoListMenu();
+
QMenu * mediaViewMenu(bool showAbout = false);
public slots:
+ void updateSavedListsMenus();
private:
+
MainWindow *m_parent;
Ui::MainWindowClass *ui;
-
+ VideoSettings *m_videoSettings;
+
QAction *m_quit;
QAction *m_playAllAction;
QAction *m_playSelectedAction;
@@ -76,16 +91,31 @@ class ActionsManager : public QObject
QAction *m_mute;
QAction *m_removeSelectedItemsInfo;
QAction *m_refreshMediaView;
+ QAction *m_showVideoSettings;
+ QAction *m_removeFromSavedList;
+ QAction *m_newAudioList;
+ QAction *m_newVideoList;
+ QAction *m_showItems;
+ QAction *m_showNowPlayingInfo;
+ QMenu *m_addToAudioSavedList;
+ QMenu *m_addToVideoSavedList;
+ bool m_contextStackWasVisible;
+ int m_previousContextStackIndex;
+
KActionCollection *m_actionCollection;
private slots:
void fullScreenToggle();
void toggleControls();
+ void toggleVideoSettings();
void cancelFSHC();
void showShortcutsEditor();
void hideShortcutsEditor();
void simplePlayPause();
void muteAudio();
-
+ void addToSavedAudioList(QAction *addAction);
+ void addToSavedVideoList(QAction *addAction);
+ void loadSelectedSources();
+ void showInfoForNowPlaying();
};
-#endif //ACTIONSMANAGER_H
\ No newline at end of file
+#endif //ACTIONSMANAGER_H
diff --git a/infomanager.cpp b/src/infomanager.cpp
similarity index 72%
rename from infomanager.cpp
rename to src/infomanager.cpp
index b0e9862..ee33449 100644
--- a/infomanager.cpp
+++ b/src/infomanager.cpp
@@ -22,9 +22,10 @@
#include "ui_mainwindow.h"
#include "platform/mediaitemmodel.h"
#include "mediaitemdelegate.h"
-#include "platform/mediaindexer.h"
#include <KUrlRequester>
#include <KLineEdit>
+#include <KDebug>
+#include <QDateEdit>
#include <Soprano/QueryResultIterator>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/RDF>
@@ -38,12 +39,13 @@
#include <taglib/tstring.h>
#include <taglib/id3v2tag.h>
+//TODO:This module could use a good deal of simplification. :-)
+
InfoManager::InfoManager(MainWindow * parent) : QObject(parent)
{
m_parent = parent;
ui = m_parent->ui;
m_infoMediaItemsModel = new MediaItemModel(this);
- m_mediaIndexer = new MediaIndexer(this);
connect(ui->saveInfo, SIGNAL(clicked()), this, SLOT(saveInfoView()));
connect(ui->showInfo, SIGNAL(clicked()), this, SLOT(showInfoView()));
connect(ui->editInfo, SIGNAL(clicked()), this, SLOT(editInfoView()));
@@ -94,6 +96,29 @@ void InfoManager::showInfoView()
loadInfoView();
}
+void InfoManager::showInfoViewForMediaItem(MediaItem mediaItem)
+{
+ ui->stackedWidget->setCurrentIndex(0);
+ ui->mediaViewHolder->setCurrentIndex(1);
+ ui->previous->setVisible(true);
+ ui->previous->setText(ui->listTitle->text());
+
+ m_rows.clear();
+ QList<MediaItem> mediaList;
+ mediaList << mediaItem;
+ if (mediaList.count() == 0) {
+ return;
+ }
+ m_infoMediaItemsModel->clearMediaListData();
+ m_infoMediaItemsModel->loadMediaList(mediaList);
+ showFields();
+ m_editToggle = false;
+ ui->editInfo->setText("Edit");
+ ui->editInfo->setIcon(KIcon("document-edit"));
+ ui->playSelected->setVisible(false);
+ ui->playAll->setVisible(false);
+}
+
void InfoManager::editInfoView()
{
m_editToggle = !m_editToggle;
@@ -255,7 +280,13 @@ void InfoManager::showCommonFields(bool edit)
} else {
setInfo(startRow + 1, QPixmap());
}
- setInfo(startRow + 2, commonValue("description").toString());
+ QString description;
+ if (!commonValue("synopsis").toString().isEmpty()) {
+ description = commonValue("synopsis").toString();
+ } else {
+ description = commonValue("description").toString();
+ }
+ setInfo(startRow + 2, description);
setInfo(startRow + 3, commonValue("url").toString());
} else {
setEditWidget(startRow, new KLineEdit(), commonValue("title").toString());
@@ -266,7 +297,13 @@ void InfoManager::showCommonFields(bool edit)
} else {
setEditWidget(startRow + 1, new ArtworkWidget(), QPixmap());
}
- setEditWidget(startRow + 2, new QTextEdit(), commonValue("description").toString());
+ QString description;
+ if (!commonValue("synopsis").toString().isEmpty()) {
+ description = commonValue("synopsis").toString();
+ } else {
+ description = commonValue("description").toString();
+ }
+ setEditWidget(startRow + 2, new QTextEdit(), description);
if (m_infoMediaItemsModel->rowCount() == 1) {
MediaItem mediaItem = m_infoMediaItemsModel->mediaItemAt(0);
if (mediaItem.type == "Audio" && mediaItem.fields["audioType"].toString() == "Audio Stream") {
@@ -363,25 +400,41 @@ void InfoManager::showVideoMovieFields(bool edit)
{
int startRow = ui->infoView->topLevelItemCount();
ui->infoView->addTopLevelItem(new QTreeWidgetItem());
- setLabel(startRow, tr2i18n("Collection/Series Name"));
+ setLabel(startRow, tr2i18n("Year"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 1, tr2i18n("Genre"));
ui->infoView->addTopLevelItem(new QTreeWidgetItem());
- setLabel(startRow + 1, tr2i18n("Year"));
+ setLabel(startRow + 2, tr2i18n("Writer"));
ui->infoView->addTopLevelItem(new QTreeWidgetItem());
- setLabel(startRow + 2, tr2i18n("Genre"));
+ setLabel(startRow + 3, tr2i18n("Director"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 4, tr2i18n("Producer"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 5, tr2i18n("Actor"));
if (!edit) {
- setInfo(startRow, QString("%1").arg(commonValue("seriesName").toString()));
- setInfo(startRow + 1, QString("%1").arg(commonValue("year").toInt()));
- setInfo(startRow + 2, commonValue("genre").toString());
+ QDate releaseDate = commonValue("releaseDate").toDate();
+ QString year;
+ if (releaseDate.isValid()) {
+ year = QString("%1").arg(commonValue("releaseDate").toDate().year());
+ }
+ setInfo(startRow, year);
+ setInfo(startRow + 1, commonValue("genre").toString());
+ setInfo(startRow + 2, commonValue("writer").toString());
+ setInfo(startRow + 3, commonValue("director").toString());
+ setInfo(startRow + 4, commonValue("producer").toString());
+ setInfo(startRow + 5, commonValue("actor").toString());
} else {
- setEditWidget(startRow, new KLineEdit(), commonValue("seriesName").toString());
- setEditWidget(startRow + 1, new QSpinBox());
- QSpinBox * yw = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(startRow + 1), 1));
+ setEditWidget(startRow, new QSpinBox());
+ QSpinBox * yw = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(startRow), 1));
yw->setRange(0, 9999);
- yw->setValue(commonValue("year").toInt());
- setEditWidget(startRow + 2, new QComboBox(), commonValue("genre").toString(), valueList("genre"), true);
-
+ yw->setValue(commonValue("releaseDate").toDate().year());
+ setEditWidget(startRow + 1, new QComboBox(), commonValue("genre").toString(), valueList("genre"), true);
+ setEditWidget(startRow + 2, new QComboBox(), commonValue("writer").toString(), valueList("writer"), true);
+ setEditWidget(startRow + 3, new QComboBox(), commonValue("director").toString(), valueList("director"), true);
+ setEditWidget(startRow + 4, new QComboBox(), commonValue("producer").toString(), valueList("producer"), true);
+ setEditWidget(startRow + 5, new QComboBox(), commonValue("actor").toString(), valueList("actor"), true);
}
}
@@ -395,21 +448,46 @@ void InfoManager::showVideoTVShowFields(bool edit)
setLabel(startRow + 1, tr2i18n("Season"));
ui->infoView->addTopLevelItem(new QTreeWidgetItem());
setLabel(startRow + 2, tr2i18n("Episode")); ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
setLabel(startRow + 3, tr2i18n("Year"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 4, tr2i18n("Genre"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 5, tr2i18n("Writer"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 6, tr2i18n("Director"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 7, tr2i18n("Producer"));
+ ui->infoView->addTopLevelItem(new QTreeWidgetItem());
+ setLabel(startRow + 8, tr2i18n("Actor"));
if (!edit) {
- setInfo(startRow, QString("%1").arg(commonValue("seriesName").toString()));
+ setInfo(startRow, commonValue("seriesName").toString());
setInfo(startRow + 1, QString("%1").arg(commonValue("season").toInt()));
- setInfo(startRow + 2, QString("%1").arg(commonValue("episode").toInt()));
- setInfo(startRow + 3, QString("%1").arg(commonValue("year").toInt()));
+ setInfo(startRow + 2, QString("%1").arg(commonValue("episodeNumber").toInt()));
+ QDate releaseDate = commonValue("releaseDate").toDate();
+ QString year;
+ if (releaseDate.isValid()) {
+ year = QString("%1").arg(commonValue("releaseDate").toDate().year());
+ }
+ setInfo(startRow + 3, year);
+ setInfo(startRow + 4, commonValue("genre").toString());
+ setInfo(startRow + 5, commonValue("writer").toString());
+ setInfo(startRow + 6, commonValue("director").toString());
+ setInfo(startRow + 7, commonValue("producer").toString());
+ setInfo(startRow + 8, commonValue("actor").toString());
} else {
setEditWidget(startRow, new KLineEdit(), commonValue("seriesName").toString());
setEditWidget(startRow + 1, new QSpinBox(), commonValue("season").toInt());
- setEditWidget(startRow + 2, new QSpinBox(), commonValue("episode").toInt());
+ setEditWidget(startRow + 2, new QSpinBox(), commonValue("episodeNumber").toInt());
setEditWidget(startRow + 3, new QSpinBox());
QSpinBox * yw = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(startRow + 3), 1));
yw->setRange(0, 9999);
- yw->setValue(commonValue("year").toInt());
+ setEditWidget(startRow + 4, new QComboBox(), commonValue("genre").toString(), valueList("genre"), true);
+ setEditWidget(startRow + 5, new QComboBox(), commonValue("writer").toString(), valueList("writer"), true);
+ setEditWidget(startRow + 6, new QComboBox(), commonValue("director").toString(), valueList("director"), true);
+ setEditWidget(startRow + 7, new QComboBox(), commonValue("producer").toString(), valueList("producer"), true);
+ setEditWidget(startRow + 8, new QComboBox(), commonValue("actor").toString(), valueList("actor"), true);
}
}
@@ -471,7 +549,11 @@ void InfoManager::saveInfoToMediaModel()
QTextEdit * descriptionWidget = static_cast<QTextEdit*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(2), 1));
QString description = descriptionWidget->toPlainText();
if (!description.isEmpty()) {
- mediaItem.fields["description"] = description;
+ if (mediaItem.type == "Video") {
+ mediaItem.fields["synopsis"] = description;
+ } else {
+ mediaItem.fields["description"] = description;
+ }
}
if (mediaItem.type == "Audio" ) {
@@ -510,6 +592,7 @@ void InfoManager::saveInfoToMediaModel()
if (!genre.isEmpty()) {
mediaItem.fields["genre"] = genre;
}
+
} else if (typeComboBox->currentIndex() == 1) {
mediaItem.type = "Audio";
mediaItem.fields["audioType"] = "Audio Stream";
@@ -530,24 +613,43 @@ void InfoManager::saveInfoToMediaModel()
mediaItem.type = "Video";
mediaItem.fields["videoType"] = "Movie";
- KLineEdit * seriesNameWidget = static_cast<KLineEdit*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(5), 1));
- QString seriesName = seriesNameWidget->text();
- if (!seriesName.isEmpty()) {
- mediaItem.fields["seriesName"] = seriesName.trimmed();
- }
-
- QSpinBox *yearWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(6), 1));
- int year = yearWidget->value();
- if (year != 0) {
- mediaItem.fields["year"] = year;
+ QSpinBox *yearWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(5), 1));
+ if (yearWidget->value() != 0) {
+ QDate releaseDate = QDate(yearWidget->value(), 1, 1);
+ mediaItem.fields["releaseDate"] = releaseDate;
}
- QComboBox *genreWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(7), 1));
+ QComboBox *genreWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(6), 1));
QString genre = genreWidget->currentText();
if (!genre.isEmpty()) {
mediaItem.fields["genre"] = genre;
}
+ QComboBox *writerWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(7), 1));
+ QString writer = writerWidget->currentText();
+ kDebug() << "Writer:" << writer;
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = writer;
+ }
+
+ QComboBox *directorWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(8), 1));
+ QString director = directorWidget->currentText();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
+ }
+
+ QComboBox *producerWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(9), 1));
+ QString producer = producerWidget->currentText();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+
+ QComboBox *actorWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(10), 1));
+ QString actor = actorWidget->currentText();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
+ }
+
} else if (typeComboBox->currentIndex() == 1) {
mediaItem.type = "Video";
mediaItem.fields["videoType"] = "TV Show";
@@ -556,22 +658,60 @@ void InfoManager::saveInfoToMediaModel()
QString seriesName = seriesNameWidget->text();
if (!seriesName.isEmpty()) {
mediaItem.fields["seriesName"] = seriesName;
+ mediaItem.subTitle = seriesName;
}
QSpinBox *seasonWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(6), 1));
int season = seasonWidget->value();
mediaItem.fields["season"] = season;
- mediaItem.subTitle = QString("Season %1 ").arg(season);
+ if (!mediaItem.subTitle.isEmpty()) {
+ mediaItem.subTitle += " - ";
+ }
+ mediaItem.subTitle += QString("Season %1").arg(season);
QSpinBox *episodeWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(7), 1));
- int episode = episodeWidget->value();
- mediaItem.fields["episode"] = episode;
- mediaItem.subTitle = mediaItem.subTitle + QString("Episode %1").arg(episode);
+ int episodeNumber = episodeWidget->value();
+ mediaItem.fields["episodeNumber"] = episodeNumber;
+ if (!mediaItem.subTitle.isEmpty()) {
+ mediaItem.subTitle += " - ";
+ }
+ mediaItem.subTitle += QString("Episode %1").arg(episodeNumber);
- QSpinBox *yearWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(8), 1));
- int year = yearWidget->value();
- if (year != 0) {
- mediaItem.fields["year"] = year;
+ QSpinBox *yearWidget = static_cast<QSpinBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(5), 1));
+ if (yearWidget->value() != 0) {
+ QDate releaseDate = QDate(yearWidget->value(), 1, 1);
+ mediaItem.fields["releaseDate"] = releaseDate;
+ }
+
+ QComboBox *genreWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(9), 1));
+ QString genre = genreWidget->currentText();
+ if (!genre.isEmpty()) {
+ mediaItem.fields["genre"] = genre;
+ }
+
+
+ QComboBox *writerWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(10), 1));
+ QString writer = writerWidget->currentText();
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = genre;
+ }
+
+ QComboBox *directorWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(11), 1));
+ QString director = directorWidget->currentText();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
+ }
+
+ QComboBox *producerWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(12), 1));
+ QString producer = producerWidget->currentText();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+
+ QComboBox *actorWidget = static_cast<QComboBox*>(ui->infoView->itemWidget(ui->infoView->topLevelItem(13), 1));
+ QString actor = actorWidget->currentText();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
}
} else if (typeComboBox->currentIndex() == 2) {
@@ -718,3 +858,11 @@ void InfoManager::setEditWidget(int row, ArtworkWidget *artworkWidget, QPixmap p
artworkWidget->setPixmap(pixmap);
ui->infoView->setItemWidget(ui->infoView->topLevelItem(row), 1, artworkWidget);
}
+
+void InfoManager::setEditWidget(int row, QDateEdit *dateEdit, QDate date)
+{
+ dateEdit->setMinimumDate(QDate(-4000,1,1));
+ dateEdit->setDisplayFormat("MMMM dd yyyy");
+ dateEdit->setDate(date);
+ ui->infoView->setItemWidget(ui->infoView->topLevelItem(row ), 1, dateEdit);
+}
diff --git a/infomanager.h b/src/infomanager.h
similarity index 91%
rename from infomanager.h
rename to src/infomanager.h
index 4c99a8e..8ee5443 100644
--- a/infomanager.h
+++ b/src/infomanager.h
@@ -20,12 +20,14 @@
#define INFOMANAGER_H
#include <KLineEdit>
+#include <QDateEdit>
#include <KUrlRequester>
#include <QComboBox>
#include <QSpinBox>
#include <QObject>
#include <QTreeWidgetItem>
#include <QTextEdit>
+#include <QDate>
namespace Ui
{
@@ -33,10 +35,14 @@ namespace Ui
}
class MainWindow;
class MediaItemModel;
+class MediaItem;
class MediaItemDelegate;
class MediaIndexer;
class ArtworkWidget;
+/*
+ * This class provides a user interface for updating information associated with MediaItems
+ */
class InfoManager : public QObject
{
Q_OBJECT
@@ -53,6 +59,7 @@ class InfoManager : public QObject
public slots:
void saveInfoView();
void showInfoView();
+ void showInfoViewForMediaItem(MediaItem mediaItem);
void editInfoView();
void removeSelectedItemsInfo();
@@ -87,6 +94,7 @@ class InfoManager : public QObject
void setEditWidget(int row, KUrlRequester *urlRequester, QString value = QString());
void setEditWidget(int row, QSpinBox *spinBox, int value = 0);
void setEditWidget(int row, ArtworkWidget *artworkWidget, QPixmap pixmap);
+ void setEditWidget(int row, QDateEdit *dateEdit, QDate date = QDate());
private slots:
diff --git a/main.cpp b/src/main.cpp
similarity index 93%
rename from main.cpp
rename to src/main.cpp
index 06c6bb1..a487665 100644
--- a/main.cpp
+++ b/src/main.cpp
@@ -25,10 +25,10 @@
#include <KLocalizedString>
#include <KAboutData>
-static KAboutData aboutData( "Bangarang", 0,
- ki18n("Bangarang"), "0.92 (1.0~beta2)",
+static KAboutData aboutData( "bangarang", 0,
+ ki18n("Bangarang"), "0.93 (1.0~beta3)",
ki18n("A Media Player"), KAboutData::License_GPL_V2,
- ki18n("Copyright 2009, Andrew Lake"), ki18n(""),
+ ki18n("Copyright 2009, Andrew Lake"), KLocalizedString(),
"" );
int main(int argc, char *argv[])
diff --git a/mainwindow.cpp b/src/mainwindow.cpp
similarity index 81%
rename from mainwindow.cpp
rename to src/mainwindow.cpp
index 52f6cba..a3af216 100644
--- a/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -27,7 +27,7 @@
#include "actionsmanager.h"
#include "mediaitemdelegate.h"
#include "nowplayingdelegate.h"
-
+#include "videosettings.h"
#include <KCmdLineArgs>
#include <KCursor>
@@ -41,6 +41,9 @@
#include <KDebug>
#include <KHelpMenu>
#include <KMenu>
+#include <kio/netaccess.h>
+#include <kio/copyjob.h>
+#include <kio/job.h>
#include <Solid/Device>
#include <Solid/DeviceInterface>
#include <Solid/OpticalDisc>
@@ -157,6 +160,15 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(ui->mediaView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(mediaSelectionChanged(const QItemSelection, const QItemSelection)));
ui->mediaView->setMainWindow(this);
+ //Set up MediaItemModel notifications
+ ui->notificationWidget->setVisible(false);
+ connect(m_mediaItemModel, SIGNAL(sourceInfoUpdateRemovalStarted()), this, SLOT(showNotification()));
+ connect(m_mediaItemModel, SIGNAL(sourceInfoUpdateProgress(int)), ui->notificationProgress, SLOT(setValue(int)));
+ connect(m_mediaItemModel, SIGNAL(sourceInfoRemovalProgress(int)), ui->notificationProgress, SLOT(setValue(int)));
+ connect(m_mediaItemModel, SIGNAL(sourceInfoUpdateRemovalComplete()), this, SLOT(delayedNotificationHide()));
+ connect(m_mediaItemModel, SIGNAL(sourceInfoUpdated(MediaItem)), this, SLOT(sourceInfoUpdated(MediaItem)));
+ connect(m_mediaItemModel, SIGNAL(sourceInfoRemoved(QString)), this, SLOT(sourceInfoRemoved(QString)));
+
//Set up playlist
m_playlist = new Playlist(this, m_media);
connect(m_playlist, SIGNAL(playlistFinished()), this, SLOT(playlistFinished()));
@@ -180,6 +192,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(m_nowPlaying, SIGNAL(mediaListChanged()), this, SLOT(nowPlayingChanged()));
ui->nowPlayingView->header()->setVisible(false);
ui->nowPlayingView->header()->hideSection(1);
+ updateNowPlayingStyleSheet();
+ connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(updateNowPlayingStyleSheet()));
//Setup Info View
m_infoManager = new InfoManager(this);
@@ -190,16 +204,25 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
//Setup Actions Manager
m_actionsManager = new ActionsManager(this);
+ //Setup Video Settings
+ VideoSettings *videoSettings = new VideoSettings(m_videoWidget, this);
+ videoSettings->setHideAction(m_actionsManager->showVideoSettings());
+ ui->videoSettingsPage->layout()->addWidget(videoSettings);
+
//Set up defaults
+ ui->nowPlayingSplitter->setCollapsible(0,true);
+ ui->nowPlayingSplitter->setCollapsible(1,false);
ui->stackedWidget->setCurrentIndex(1);
ui->mediaViewHolder->setCurrentIndex(0);
ui->audioListsStack->setCurrentIndex(0);
ui->videoListsStack->setCurrentIndex(0);
+ ui->contextStack->setCurrentIndex(0);
ui->mediaPlayPause->setHoldDelay(1000);
ui->mediaPrevious->setDefaultAction(m_actionsManager->playPrevious());
ui->mediaNext->setDefaultAction(m_actionsManager->playNext());
ui->listSummary->setFont(KGlobalSettings::smallestReadableFont());
ui->playlistDuration->setFont(KGlobalSettings::smallestReadableFont());
+ ui->playbackMessage->clear();
updateSeekTime(0);
showApplicationBanner();
updateCachedDevicesList();
@@ -215,13 +238,36 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
if (args->count() > 0) {
if (args->isSet("play-dvd")) {
//Play DVD
-
+ kDebug() << "playing DVD";
+ MediaItem mediaItem;
+ mediaItem.title = i18n("DVD Video");
+ mediaItem.url = "dvdvideo://";
+ mediaItem.type = "Category";
+ QList<MediaItem> mediaList;
+ mediaList << mediaItem;
+ m_playlist->playMediaList(mediaList);
} else if (args->isSet("play-cd")) {
//Play CD
-
+ kDebug() << "playing CD";
+ MediaItem mediaItem;
+ mediaItem.title = i18n("Audio CD");
+ mediaItem.url = "cdaudio://";
+ mediaItem.type = "Category";
+ QList<MediaItem> mediaList;
+ mediaList << mediaItem;
+ m_playlist->playMediaList(mediaList);
} else {
//Play Url
KUrl cmdLineKUrl = args->url(0);
+ if (!cmdLineKUrl.isLocalFile()) {
+ QString tmpFile;
+ if( KIO::NetAccess::download(cmdLineKUrl, tmpFile, this)) {
+ //KMessageBox::information(this,tmpFile);
+ cmdLineKUrl = KUrl(tmpFile);
+ } else {
+ cmdLineKUrl = KUrl();
+ }
+ }
MediaItem mediaItem = Utilities::mediaItemFromUrl(cmdLineKUrl);
QList<MediaItem> mediaList;
mediaList << mediaItem;
@@ -230,10 +276,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
} else {
if (m_nepomukInited) {
//Preload queries that are likely to be long so that, if necessary, they can be cached early
- //(prehaps this could be configurable in the future)
- //FIXME:This is disabled for now since it somehow blocks the
- // playlist Phonon::MediaObject::setCurrentSource() method
-
+ //TODO:prehaps this could be configurable.
/*MediaListProperties mediaListProperties;
mediaListProperties.lri = "music://songs";
m_mediaItemModel->setMediaListProperties(mediaListProperties);
@@ -242,7 +285,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
m_mediaItemModel->setMediaListProperties(mediaListProperties);
m_mediaItemModel->load();*/
} else {
- KMessageBox::information(this, tr("Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media library, rating and play count functions will be unavailable."), tr("Bangarang"), tr("Don't show this message again"));
+ KMessageBox::information(this, i18n("Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media library, rating and play count functions will be unavailable."), i18n("Bangarang"), i18n("Don't show this message again"));
}
}
@@ -251,7 +294,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
ui->mediaLists->setCurrentIndex(0);
//Install event filter for hiding widgets in Now Playing view
- ui->nowPlayingView->installEventFilter(this);
+ ui->nowPlayingView->setMouseTracking(true);
+ m_videoWidget->setMouseTracking(true);
+ ui->nowPlayingView->viewport()->installEventFilter(this);
m_videoWidget->installEventFilter(this);
// Set up cursor hiding for videos.
@@ -314,6 +359,7 @@ void MainWindow::on_showPlaylist_clicked(bool checked)
{
ui->contextStack->setVisible(checked);
ui->contextStack->setCurrentIndex(0);
+ m_actionsManager->showVideoSettings()->setText(i18n("Show Video Settings"));
}
void MainWindow::on_fullScreen_toggled(bool fullScreen)
@@ -321,14 +367,14 @@ void MainWindow::on_fullScreen_toggled(bool fullScreen)
if (fullScreen) {
showFullScreen();
ui->fullScreen->setIcon(KIcon("view-restore"));
- ui->fullScreen->setToolTip("<b>Fullscreen</b><br>Click to exit fullscreen");
+ ui->fullScreen->setToolTip(i18n("<b>Fullscreen</b><br>Click to exit fullscreen"));
ui->fullScreen->setChecked(true);
ui->widgetSet->setVisible(false);
ui->nowPlayingToolbar->setVisible(false);
} else {
showNormal();
ui->fullScreen->setIcon(KIcon("view-fullscreen"));
- ui->fullScreen->setToolTip("Show fullscreen");
+ ui->fullScreen->setToolTip(i18n("Show fullscreen"));
ui->fullScreen->setChecked(false);
ui->widgetSet->setVisible(true);
ui->nowPlayingToolbar->setVisible(true);
@@ -339,9 +385,9 @@ void MainWindow::on_seekTime_clicked()
{
showRemainingTime = !showRemainingTime;
if (showRemainingTime) {
- ui->seekTime->setToolTip("<b>Time remaining</b><br>Click to show elapsed time");
+ ui->seekTime->setToolTip(i18n("<b>Time remaining</b><br>Click to show elapsed time"));
} else {
- ui->seekTime->setToolTip("<b>Time elapsed</b><br>Click to show remaining time");
+ ui->seekTime->setToolTip(i18n("<b>Time elapsed</b><br>Click to show remaining time"));
}
}
@@ -350,7 +396,7 @@ void MainWindow::on_mediaPlayPause_pressed()
if ((m_media->state() == Phonon::PlayingState)) {
m_media->pause();
m_pausePressed = true;
- ui->mediaPlayPause->setToolTip("<b>Paused</b><br>Hold to stop");
+ ui->mediaPlayPause->setToolTip(i18n("<b>Paused</b><br>Hold to stop"));
}
}
@@ -393,6 +439,7 @@ void MainWindow::on_playlistView_doubleClicked(const QModelIndex & index)
} else {
m_playlist->playItemAt(index.row(), Playlist::QueueModel);
}
+ ui->playlistView->selectionModel()->clear();
}
void MainWindow::on_previous_clicked()
@@ -480,7 +527,7 @@ void MainWindow::on_mediaLists_currentChanged(int i)
currentProperties.lri = m_audioListsModel->mediaItemAt(selectedRow).url;
}
ui->audioLists->setFocus();
- ui->Filter->setClickMessage("Search for audio");
+ ui->Filter->setClickMessage(i18n("Search for audio"));
} else {
if (ui->videoLists->selectionModel()->selectedIndexes().count() > 0){
selectedRow = ui->videoLists->selectionModel()->selectedIndexes().at(0).row();
@@ -488,7 +535,7 @@ void MainWindow::on_mediaLists_currentChanged(int i)
currentProperties.lri = m_videoListsModel->mediaItemAt(selectedRow).url;
}
ui->videoLists->setFocus();
- ui->Filter->setClickMessage("Search for video");
+ ui->Filter->setClickMessage(i18n("Search for video"));
}
if (selectedRow != -1) {
if ((m_mediaItemModel->mediaListProperties().engine() != currentProperties.engine()) || (m_mediaItemModel->mediaListProperties().engineArg() != currentProperties.engineArg())) {
@@ -511,13 +558,13 @@ void MainWindow::on_clearPlaylist_clicked()
{
ui->clearPlaylist->setIcon(KIcon("bangarang-clearplaylist"));
KGuiItem clearPlaylist;
- clearPlaylist.setText(QString("Clear Playlist"));
- if (KMessageBox::warningContinueCancel(this, "Are you sure you want to clear the current playlist?", QString(), clearPlaylist) == KMessageBox::Continue) {
+ clearPlaylist.setText(i18n("Clear Playlist"));
+ if (KMessageBox::warningContinueCancel(this, i18n("Are you sure you want to clear the current playlist?"), QString(), clearPlaylist) == KMessageBox::Continue) {
m_playlist->clearPlaylist();
showApplicationBanner();
- setWindowTitle(QString("Bangarang"));
+ setWindowTitle(i18n("Bangarang"));
ui->nowPlaying->setIcon(KIcon("tool-animator"));
- ui->nowPlaying->setText("Now Playing");
+ ui->nowPlaying->setText(i18n("Now Playing"));
}
ui->clearPlaylist->setIcon(turnIconOff(KIcon("bangarang-clearplaylist"), QSize(22, 22)));
}
@@ -527,11 +574,11 @@ void MainWindow::on_shuffle_clicked()
m_shuffle = !m_shuffle;
if (m_shuffle) {
m_playlist->setMode(Playlist::Shuffle);
- ui->shuffle->setToolTip("<b>Shuffle On</b><br>Click to turn off Shuffle");
+ ui->shuffle->setToolTip(i18n("<b>Shuffle On</b><br>Click to turn off Shuffle"));
ui->shuffle->setIcon(KIcon("bangarang-shuffle"));
} else {
m_playlist->setMode(Playlist::Normal);
- ui->shuffle->setToolTip("Turn on Shuffle");
+ ui->shuffle->setToolTip(i18n("Turn on Shuffle"));
ui->shuffle->setIcon(turnIconOff(KIcon("bangarang-shuffle"), QSize(22, 22)));
}
}
@@ -542,10 +589,10 @@ void MainWindow::on_repeat_clicked()
m_playlist->setRepeat(m_repeat);
if (m_repeat) {
ui->repeat->setIcon(KIcon("bangarang-repeat"));
- ui->repeat->setToolTip("<b>Repeat On</b><br>Click to turn off repeat");
+ ui->repeat->setToolTip(i18n("<b>Repeat On</b><br>Click to turn off repeat"));
} else {
ui->repeat->setIcon(turnIconOff(KIcon("bangarang-repeat"), QSize(22, 22)));
- ui->repeat->setToolTip("Turn on Repeat");
+ ui->repeat->setToolTip(i18n("Turn on Repeat"));
}
}
@@ -554,12 +601,12 @@ void MainWindow::on_showQueue_clicked()
m_showQueue = !m_showQueue;
if (m_showQueue) {
ui->playlistView->setModel(m_playlist->queueModel());
- ui->showQueue->setToolTip("<b>Showing Upcoming</b><br>Click to show playlist");
- ui->playlistName->setText(QString("<b>Playlist</b>(Upcoming)"));
+ ui->showQueue->setToolTip(i18n("<b>Showing Upcoming</b><br>Click to show playlist"));
+ ui->playlistName->setText(i18n("<b>Playlist</b>(Upcoming)"));
ui->showQueue->setIcon(KIcon("bangarang-preview"));
} else {
ui->playlistView->setModel(m_playlist->playlistModel());
- ui->showQueue->setToolTip("Show Upcoming");
+ ui->showQueue->setToolTip(i18n("Show Upcoming"));
playlistChanged();
ui->showQueue->setIcon(turnIconOff(KIcon("bangarang-preview"), QSize(22, 22)));
}
@@ -571,6 +618,13 @@ void MainWindow::on_showMenu_clicked()
m_helpMenu->menu();
m_menu = new KMenu(this);
//m_menu->addAction(m_actionsManager->editShortcuts());
+ if (m_playlist->nowPlayingModel()->rowCount() > 0) {
+ MediaItem mediaItem = m_playlist->nowPlayingModel()->mediaItemAt(0);
+ if ((mediaItem.type == "Audio") || (mediaItem.type == "Video")) {
+ m_menu->addAction(m_actionsManager->showNowPlayingInfo());
+ }
+ }
+ m_menu->addAction(m_actionsManager->showVideoSettings());
if (!isFullScreen()) {
m_menu->addAction(m_actionsManager->showHideControls());
m_menu->addSeparator();
@@ -607,21 +661,19 @@ void MainWindow::updateSeekTime(qint64 time)
ui->seekTime->setToolButtonStyle(Qt::ToolButtonTextOnly);
ui->seekTime->setText(displayTime);
if (showRemainingTime) {
- ui->seekTime->setToolTip("<b>Time remaining</b><br>Click to show elapsed time");
+ ui->seekTime->setToolTip(i18n("<b>Time remaining</b><br>Click to show elapsed time"));
} else {
- ui->seekTime->setToolTip("<b>Time elapsed</b><br>Click to show remaining time");
+ ui->seekTime->setToolTip(i18n("<b>Time elapsed</b><br>Click to show remaining time"));
}
//Update Now Playing Button text
- QString title;
if (m_nowPlaying->rowCount() > 0) {
- if (m_nowPlaying->mediaItemAt(0).type != "Application Banner") {
- title = QString("\n") + m_nowPlaying->item(0,0)->data(Qt::DisplayRole).toString();
- QString subTitle = m_nowPlaying->item(0,0)->data(MediaItem::SubTitleRole).toString();
- ui->nowPlaying->setText(QString("Now Playing") + QString("(")+ displayTime + QString(")") + title);
+ if (m_nowPlaying->mediaItemAt(0).type != "Application Banner") {
+ QString title = m_nowPlaying->mediaItemAt(0).title;
+ ui->nowPlaying->setText(i18n("Now Playing") + QString("(")+ displayTime + QString(")\n") + title);
} else {
- ui->nowPlaying->setText(QString("Now Playing"));
+ ui->nowPlaying->setText(i18n("Now Playing"));
}
}
}
@@ -631,11 +683,11 @@ void MainWindow::mediaStateChanged(Phonon::State newstate, Phonon::State oldstat
if (newstate == Phonon::PlayingState) {
ui->mediaPlayPause->setIcon(KIcon("media-playback-pause"));
if (m_media->hasVideo()) {
- ui->viewerStack->setCurrentIndex(1);
- } else {
- ui->viewerStack->setCurrentIndex(0);
+ ui->viewerStack->setCurrentIndex(1);
+ } else {
+ ui->viewerStack->setCurrentIndex(0);
}
- ui->mediaPlayPause->setToolTip("<b>Playing</b><br>Click to pause<br>Click and hold to stop");
+ ui->mediaPlayPause->setToolTip(i18n("<b>Playing</b><br>Click to pause<br>Click and hold to stop"));
} else {
if ((!m_pausePressed) && (!m_stopPressed)) {
ui->mediaPlayPause->setIcon(KIcon("media-playback-start"));
@@ -645,12 +697,19 @@ void MainWindow::mediaStateChanged(Phonon::State newstate, Phonon::State oldstat
showLoading();
}
+ if (newstate == Phonon::ErrorState) {
+ ui->playbackMessage->setText(i18n("An error has been encountered during playback"));
+ QTimer::singleShot(3000, ui->playbackMessage, SLOT(clear()));
+ }
Q_UNUSED(oldstate);
}
void MainWindow::showLoading()
{
- if (m_media->state() == Phonon::LoadingState || m_media->state() == Phonon::BufferingState || m_playlist->loadingState() == Playlist::Loading) {
+ if ((m_media->state() == Phonon::LoadingState ||
+ m_media->state() == Phonon::BufferingState ||
+ m_playlist->state() == Playlist::Loading) &&
+ (m_playlist->state() != Playlist::Finished)) {
m_loadingProgress += 1;
if ((m_loadingProgress > 7) || (m_loadingProgress < 0)) {
m_loadingProgress = 0;
@@ -658,14 +717,16 @@ void MainWindow::showLoading()
QString iconName= QString("bangarang-loading-%1").arg(m_loadingProgress);
ui->seekTime->setToolButtonStyle(Qt::ToolButtonIconOnly);
ui->seekTime->setIcon(KIcon(iconName));
- if (m_playlist->loadingState() == Playlist::Loading) {
- ui->seekTime->setToolTip("Loading playlist...");
+ if (m_playlist->state() == Playlist::Loading) {
+ ui->seekTime->setToolTip(i18n("Loading playlist..."));
} else if (m_media->state() == Phonon::BufferingState) {
- ui->seekTime->setToolTip("Buffering...");
+ ui->seekTime->setToolTip(i18n("Buffering..."));
} else {
- ui->seekTime->setToolTip("Loading...");
+ ui->seekTime->setToolTip(i18n("Loading..."));
}
QTimer::singleShot(100, this, SLOT(showLoading()));
+ } else {
+ ui->seekTime->setToolButtonStyle(Qt::ToolButtonTextOnly);
}
}
@@ -673,10 +734,10 @@ void MainWindow::updateMuteStatus(bool muted)
{
if (muted) {
ui->volumeIcon->setIcon(KIcon("dialog-cancel"));
- ui->volumeIcon->setToolTip("<b>Muted</b><br>Click to restore volume");
+ ui->volumeIcon->setToolTip(i18n("<b>Muted</b><br>Click to restore volume"));
} else {
ui->volumeIcon->setIcon(KIcon("speaker"));
- ui->volumeIcon->setToolTip("Mute volume");
+ ui->volumeIcon->setToolTip(i18n("Mute volume"));
}
}
@@ -711,6 +772,30 @@ void MainWindow::mediaListChanged()
}
}
+void MainWindow::showNotification()
+{
+ ui->notificationText->setText(i18n("Updating..."));
+ ui->notificationWidget->setVisible(true);
+}
+
+void MainWindow::delayedNotificationHide()
+{
+ ui->notificationText->setText(i18n("Complete"));
+ QTimer::singleShot(3000, ui->notificationWidget, SLOT(hide()));
+}
+
+void MainWindow::sourceInfoUpdated(MediaItem mediaItem)
+{
+ ui->notificationText->setText(i18n("Updated info for ") + QString("<i>%1, %2</i>").arg(mediaItem.title).arg(mediaItem.subTitle));
+ ui->notificationWidget->setVisible(true);
+}
+
+void MainWindow::sourceInfoRemoved(QString url)
+{
+ ui->notificationText->setText(i18n("Removed info for ") + QString("<i>%1</i>").arg(url));
+ ui->notificationWidget->setVisible(true);
+}
+
void MainWindow::mediaSelectionChanged (const QItemSelection & selected, const QItemSelection & deselected )
{
if (ui->mediaView->selectionModel()->selectedRows().count() > 0) {
@@ -811,12 +896,10 @@ void MainWindow::playlistChanged()
ui->playlistView->header()->setResizeMode(0, QHeaderView::Stretch);
ui->playlistView->header()->setResizeMode(1, QHeaderView::ResizeToContents);
if (!m_showQueue) {
- ui->playlistName->setText("<b>Playlist</b>");
+ ui->playlistName->setText(i18n("<b>Playlist</b>"));
if (m_playlist->playlistModel()->rowCount() > 0) {
QString duration = Utilities::mediaListDurationText(m_playlist->playlistModel()->mediaList());
- ui->playlistDuration->setText(QString("%1 items, %2")
- .arg(m_playlist->playlistModel()->rowCount())
- .arg(duration));
+ ui->playlistDuration->setText(i18np("1 item, %2", "%1 items, %2", m_playlist->playlistModel()->rowCount(), duration));
} else {
ui->playlistDuration->setText(QString());
}
@@ -828,6 +911,17 @@ void MainWindow::nowPlayingChanged()
if (m_nowPlaying->rowCount() > 0) {
if (m_nowPlaying->mediaItemAt(0).type != "Application Banner") {
ui->nowPlaying->setIcon(m_nowPlaying->mediaItemAt(0).artwork);
+ QString title = m_nowPlaying->mediaItemAt(0).title;
+ QString subTitle = m_nowPlaying->mediaItemAt(0).subTitle;
+ QString description = m_nowPlaying->mediaItemAt(0).fields["description"].toString();
+ QString toolTipText = i18n("View Now Playing") + QString("<br><b>%1</b>").arg(title);
+ if (!subTitle.isEmpty()) {
+ toolTipText += QString("<br><i>%2</i>").arg(subTitle);
+ }
+ if (!description.isEmpty()) {
+ toolTipText += QString("<br>%3").arg(description);
+ }
+ ui->nowPlaying->setToolTip(toolTipText);
setWindowTitle(QString(m_nowPlaying->mediaItemAt(0).title + " - Bangarang"));
}
@@ -847,9 +941,10 @@ void MainWindow::nowPlayingChanged()
void MainWindow::playlistFinished()
{
showApplicationBanner();
- setWindowTitle(QString("Bangarang"));
+ setWindowTitle(i18n("Bangarang"));
ui->nowPlaying->setIcon(KIcon("tool-animator"));
- ui->nowPlaying->setText("Now Playing");
+ ui->nowPlaying->setText(i18n("Now Playing"));
+ ui->nowPlaying->setToolTip(i18n("View Now Playing"));
ui->seekTime->setText("0:00");
}
@@ -972,6 +1067,7 @@ void MainWindow::setupIcons()
ui->removeAudioList->setIcon(KIcon("list-remove"));
ui->configureAudioList->setIcon(KIcon("configure"));
ui->saveAudioList->setIcon(KIcon("document-save"));
+ ui->aslsSave->setIcon(KIcon("document-save"));
//Video List Icons
@@ -979,6 +1075,7 @@ void MainWindow::setupIcons()
ui->removeVideoList->setIcon(KIcon("list-remove"));
ui->configureVideoList->setIcon(KIcon("configure"));
ui->saveVideoList->setIcon(KIcon("document-save"));
+ ui->vslsSave->setIcon(KIcon("document-save"));
//Media View Icons
ui->sortList->setIcon(KIcon("view-sort-ascending"));
@@ -1007,18 +1104,19 @@ void MainWindow::setupIcons()
void MainWindow::setupActions()
{
- playAllAction = new QAction(KIcon("media-playback-start"), tr("Play all"), this);
+ playAllAction = new QAction(KIcon("media-playback-start"), i18n("Play all"), this);
connect(playAllAction, SIGNAL(triggered()), this, SLOT(playAll()));
- playSelectedAction = new QAction(KIcon("media-playback-start"), tr("Play selected"), this);
+ playSelectedAction = new QAction(KIcon("media-playback-start"), i18n("Play selected"), this);
connect(playSelectedAction, SIGNAL(triggered()), this, SLOT(playSelected()));
+
}
void MainWindow::showApplicationBanner()
{
MediaItem applicationBanner;
applicationBanner.artwork = KIcon("bangarang");
- applicationBanner.title = "Bangarang";
- applicationBanner.subTitle = "Entertainment... Now";
+ applicationBanner.title = i18n("Bangarang");
+ applicationBanner.subTitle = i18n("Entertainment... Now");
applicationBanner.type = "Application Banner";
applicationBanner.url = "-";
m_nowPlaying->loadMediaItem(applicationBanner, true);
@@ -1121,11 +1219,26 @@ void MainWindow::deviceRemoved(const QString &udi)
}
}
+void MainWindow::updateNowPlayingStyleSheet()
+{
+ QColor highlightColor = QApplication::palette().color(QPalette::Highlight);
+ int r = highlightColor.red();
+ int g = highlightColor.green();
+ int b = highlightColor.blue();
+ QString styleSheet = QString("background-color: qlineargradient(spread:reflect, x1:0.494, y1:0, x2:0.505682, y2:1, stop:0 rgba(0, 0, 0, 0), stop:0.20 rgba(%1, %2, %3, 25), stop:0.5 rgba(%1, %2, %3, 55), stop:0.75 rgba(%1, %2, %3, 30), stop:1 rgba(0, 0, 0, 0)); color: rgb(255, 255, 255);").arg(r).arg(g).arg(b);
+ ui->nowPlayingView->setStyleSheet(styleSheet);
+}
+
ActionsManager * MainWindow::actionsManager()
{
return m_actionsManager;
}
+SavedListsManager * MainWindow::savedListsManager()
+{
+ return m_savedListsManager;
+}
+
void MainWindow::setAboutData(KAboutData *aboutData)
{
m_aboutData = aboutData;
@@ -1150,3 +1263,8 @@ InfoManager * MainWindow::infoManager()
{
return m_infoManager;
}
+
+Phonon::VideoWidget * MainWindow::videoWidget()
+{
+ return m_videoWidget;
+}
diff --git a/mainwindow.h b/src/mainwindow.h
similarity index 93%
rename from mainwindow.h
rename to src/mainwindow.h
index 249756f..4c2a0a3 100644
--- a/mainwindow.h
+++ b/src/mainwindow.h
@@ -67,26 +67,41 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- MainWindow(QWidget *parent = 0);
- ~MainWindow();
+
+ /* FIXME: These should be moved to private and provide
+ * getter functions instead.
+ */
+ Ui::MainWindowClass *ui;
MediaItemModel * m_audioListsModel;
MediaItemModel * m_videoListsModel;
MediaItemModel * m_mediaItemModel;
MediaItemModel * m_currentPlaylist;
MediaItemModel * m_nowPlaying;
- Playlist * m_playlist;
- void addListToHistory();
- Ui::MainWindowClass *ui;
QList< QList<MediaItem> > m_mediaListHistory;
QList<MediaListProperties> m_mediaListPropertiesHistory;
- ActionsManager * actionsManager();
- void setAboutData(KAboutData *aboutData);
+ Playlist * m_playlist;
+
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
KAboutData * aboutData();
- Playlist * playlist();
+ ActionsManager * actionsManager();
+ SavedListsManager * savedListsManager();
Phonon::AudioOutput * audioOutput();
+ void addListToHistory();
InfoManager *infoManager();
+ Playlist * playlist();
+ void setAboutData(KAboutData *aboutData);
+ Phonon::VideoWidget * videoWidget();
+public slots:
+ void addSelectedToPlaylist();
+ void on_fullScreen_toggled(bool fullScreen);
+ void playAll();
+ void playSelected();
+ void removeSelectedFromPlaylist();
+
private:
Phonon::VideoPlayer *m_player;
MediaItemDelegate * m_itemDelegate;
@@ -99,16 +114,8 @@ private:
QGraphicsScene *m_Scene;
QString m_addItemsMessage;
QTime m_messageTime;
- bool playWhenPlaylistChanges;
- bool showRemainingTime;
- void setupModel();
QList<MediaItem> m_mediaList;
QList<int> m_mediaListScrollHistory;
- KIcon addItemsIcon();
- void setupIcons();
- void setupActions();
- void showApplicationBanner();
- KIcon turnIconOff(KIcon icon, QSize size);
bool m_showQueue;
bool m_repeat;
bool m_shuffle;
@@ -119,23 +126,24 @@ private:
bool m_pausePressed;
bool m_stopPressed;
QList<QString> m_devicesAdded;
- void updateCachedDevicesList();
int m_loadingProgress;
KAboutData *m_aboutData;
KHelpMenu *m_helpMenu;
KMenu *m_menu;
bool m_nepomukInited;
MediaListCache * m_sharedMediaListCache;
-
+ bool playWhenPlaylistChanges;
+ bool showRemainingTime;
QAction * playAllAction;
QAction * playSelectedAction;
-public slots:
- void playAll();
- void playSelected();
- void addSelectedToPlaylist();
- void removeSelectedFromPlaylist();
- void on_fullScreen_toggled(bool fullScreen);
+ void setupModel();
+ KIcon addItemsIcon();
+ void setupIcons();
+ void setupActions();
+ void showApplicationBanner();
+ KIcon turnIconOff(KIcon icon, QSize size);
+ void updateCachedDevicesList();
private slots:
void on_nowPlaying_clicked();
@@ -143,15 +151,24 @@ private slots:
void on_mediaPlayPause_pressed();
void on_mediaPlayPause_held();
void on_mediaPlayPause_released();
- void updateSeekTime(qint64 time);
- void updateMuteStatus(bool muted);
void on_previous_clicked();
- void mediaStateChanged(Phonon::State newstate, Phonon::State oldstate);
- void mediaSelectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
void on_playAll_clicked();
void on_playSelected_clicked();
void on_mediaLists_currentChanged(int i);
void on_showPlaylist_clicked(bool checked);
+ void on_clearPlaylist_clicked();
+ void on_playlistView_doubleClicked(const QModelIndex & index);
+ void on_seekTime_clicked();
+ void on_shuffle_clicked();
+ void on_repeat_clicked();
+ void on_showQueue_clicked();
+ void on_Filter_returnPressed();
+ void on_showMenu_clicked();
+ void on_showMediaViewMenu_clicked();
+ void updateSeekTime(qint64 time);
+ void updateMuteStatus(bool muted);
+ void mediaStateChanged(Phonon::State newstate, Phonon::State oldstate);
+ void mediaSelectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
void mediaListChanged();
void audioListsSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
void audioListsChanged();
@@ -162,23 +179,18 @@ private slots:
void playlistFinished();
void hidePlayButtons();
void updateListHeader();
- void on_clearPlaylist_clicked();
- void on_playlistView_doubleClicked(const QModelIndex & index);
- void on_seekTime_clicked();
- void on_shuffle_clicked();
- void on_repeat_clicked();
- void on_showQueue_clicked();
- void on_Filter_returnPressed();
void deviceAdded(const QString &udi);
void deviceRemoved(const QString &udi);
void showLoading();
- void on_showMenu_clicked();
- void on_showMediaViewMenu_clicked();
+ void showNotification();
+ void delayedNotificationHide();
+ void sourceInfoUpdated(MediaItem mediaItem);
+ void sourceInfoRemoved(QString url);
+ void updateNowPlayingStyleSheet();
protected:
bool eventFilter(QObject *obj, QEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
- //void keyPressEvent(QKeyEvent *event);
};
class MouseMoveDetector : public QObject
diff --git a/mainwindow.ui b/src/mainwindow.ui
similarity index 83%
rename from mainwindow.ui
rename to src/mainwindow.ui
index e118efc..80f6230 100644
--- a/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>680</width>
+ <width>720</width>
<height>480</height>
</rect>
</property>
@@ -289,7 +289,7 @@
<x>0</x>
<y>0</y>
<width>154</width>
- <height>322</height>
+ <height>324</height>
</rect>
</property>
<attribute name="label">
@@ -317,9 +317,9 @@
<item>
<widget class="QStackedWidget" name="audioListsStack">
<property name="currentIndex">
- <number>0</number>
+ <number>2</number>
</property>
- <widget class="QWidget" name="page_2">
+ <widget class="QWidget" name="audioListsPage">
<layout class="QVBoxLayout" name="verticalLayout_22">
<property name="spacing">
<number>0</number>
@@ -360,12 +360,15 @@
</property>
<item>
<widget class="QToolButton" name="addAudioList">
+ <property name="toolTip">
+ <string>Add list</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/list-add.png</normaloff>convenience/list-add.png</iconset>
+ <normaloff>../convenience/list-add.png</normaloff>../convenience/list-add.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -374,12 +377,15 @@
</item>
<item>
<widget class="QToolButton" name="removeAudioList">
+ <property name="toolTip">
+ <string>Remove list</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/list-remove.png</normaloff>convenience/list-remove.png</iconset>
+ <normaloff>../convenience/list-remove.png</normaloff>../convenience/list-remove.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -401,12 +407,15 @@
</item>
<item>
<widget class="QToolButton" name="configureAudioList">
+ <property name="toolTip">
+ <string>Settings</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/configure.png</normaloff>convenience/configure.png</iconset>
+ <normaloff>../convenience/configure.png</normaloff>../convenience/configure.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -418,7 +427,7 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="page_3">
+ <widget class="QWidget" name="addListPage">
<layout class="QVBoxLayout" name="verticalLayout_25">
<property name="spacing">
<number>0</number>
@@ -430,7 +439,7 @@
<widget class="QWidget" name="widget_4" native="true">
<layout class="QVBoxLayout" name="verticalLayout_24">
<property name="bottomMargin">
- <number>8</number>
+ <number>4</number>
</property>
<item>
<spacer name="verticalSpacer_2">
@@ -446,25 +455,34 @@
</spacer>
</item>
<item>
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Add List</string>
</property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>150</height>
- </size>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
</property>
- <property name="title">
- <string>Add list from</string>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_26">
- <property name="leftMargin">
- <number>2</number>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Source</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_6" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_21">
+ <property name="spacing">
+ <number>-1</number>
</property>
<property name="topMargin">
<number>0</number>
@@ -473,26 +491,20 @@
<number>0</number>
</property>
<property name="bottomMargin">
- <number>0</number>
+ <number>10</number>
</property>
<item>
- <widget class="QRadioButton" name="aListSourceSelection">
+ <widget class="QRadioButton" name="aListSourceView">
<property name="text">
- <string>Current Selection</string>
+ <string>Current View</string>
</property>
- <attribute name="buttonGroup">
- <string>buttonGroup</string>
- </attribute>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="aListSourceView">
+ <widget class="QRadioButton" name="aListSourceSelection">
<property name="text">
- <string>Current View</string>
+ <string>Current Selection</string>
</property>
- <attribute name="buttonGroup">
- <string>buttonGroup</string>
- </attribute>
</widget>
</item>
<item>
@@ -500,32 +512,19 @@
<property name="text">
<string>Current Playlist</string>
</property>
- <attribute name="buttonGroup">
- <string>buttonGroup</string>
- </attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
<widget class="KLineEdit" name="aNewListName">
<property name="clickMessage">
<string>New List Name</string>
</property>
+ <property name="showClearButton" stdset="0">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
@@ -547,10 +546,23 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/document-save.png</normaloff>convenience/document-save.png</iconset>
+ <normaloff>../convenience/document-save.png</normaloff>../convenience/document-save.png</iconset>
</property>
</widget>
</item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
</item>
@@ -602,6 +614,123 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="audioSavedListSettings">
+ <layout class="QVBoxLayout" name="verticalLayout_28">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Saved List Settings</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_8" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_32">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KLineEdit" name="aslsListName"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="aslsSave">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>../convenience/document-save.png</normaloff>../convenience/document-save.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="aslsCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Return to Lists</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::LeftArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -611,8 +740,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>154</width>
- <height>322</height>
+ <width>131</width>
+ <height>224</height>
</rect>
</property>
<attribute name="label">
@@ -628,7 +757,7 @@
<item>
<widget class="QStackedWidget" name="videoListsStack">
<property name="currentIndex">
- <number>0</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="page_4">
<layout class="QVBoxLayout" name="verticalLayout_23">
@@ -668,12 +797,15 @@
</property>
<item>
<widget class="QToolButton" name="addVideoList">
+ <property name="toolTip">
+ <string>Add list</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/list-add.png</normaloff>convenience/list-add.png</iconset>
+ <normaloff>../convenience/list-add.png</normaloff>../convenience/list-add.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -682,12 +814,15 @@
</item>
<item>
<widget class="QToolButton" name="removeVideoList">
+ <property name="toolTip">
+ <string>Remove list</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/list-remove.png</normaloff>convenience/list-remove.png</iconset>
+ <normaloff>../convenience/list-remove.png</normaloff>../convenience/list-remove.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -709,12 +844,15 @@
</item>
<item>
<widget class="QToolButton" name="configureVideoList">
+ <property name="toolTip">
+ <string>Settings</string>
+ </property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/configure.png</normaloff>convenience/configure.png</iconset>
+ <normaloff>../convenience/configure.png</normaloff>../convenience/configure.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@@ -748,32 +886,38 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>48</height>
+ <height>100</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Add List</string>
</property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>150</height>
- </size>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
</property>
- <property name="title">
- <string>Add list from</string>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_28">
- <property name="leftMargin">
- <number>2</number>
- </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Source</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_7" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_26">
<property name="topMargin">
<number>0</number>
</property>
@@ -808,19 +952,6 @@
</widget>
</item>
<item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>48</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
<widget class="KLineEdit" name="vNewListName">
<property name="clickMessage">
<string>New List Name</string>
@@ -846,10 +977,23 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/document-save.png</normaloff>convenience/document-save.png</iconset>
+ <normaloff>../convenience/document-save.png</normaloff>../convenience/document-save.png</iconset>
</property>
</widget>
</item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>100</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
</item>
@@ -877,6 +1021,123 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="page_2">
+ <layout class="QVBoxLayout" name="verticalLayout_31">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>91</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Saved List Settings</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_9" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_33">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KLineEdit" name="vslsListName"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="vslsSave">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>../convenience/document-save.png</normaloff>../convenience/document-save.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>90</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="vslsCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Return to Lists</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::LeftArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -887,33 +1148,6 @@
</widget>
</item>
<item>
- <widget class="QFrame" name="frame_4">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>1</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>1</number>
- </property>
- </layout>
- </widget>
- </item>
- <item>
<widget class="QFrame" name="frame_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
@@ -965,11 +1199,11 @@
<string>View Now Playing</string>
</property>
<property name="text">
- <string notr="true">Now Playing</string>
+ <string>Now Playing</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/tool-animator.png</normaloff>convenience/tool-animator.png</iconset>
+ <normaloff>../convenience/tool-animator.png</normaloff>../convenience/tool-animator.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -1142,7 +1376,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/view-sort-ascending.png</normaloff>convenience/view-sort-ascending.png</iconset>
+ <normaloff>../convenience/view-sort-ascending.png</normaloff>../convenience/view-sort-ascending.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1360,6 +1594,102 @@
</widget>
</widget>
</item>
+ <item>
+ <widget class="QWidget" name="notificationWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_21">
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>1</number>
+ </property>
+ <property name="bottomMargin">
+ <number>1</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="notificationText">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>390</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>390</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Notification Text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_9">
+ <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="QProgressBar" name="notificationProgress">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="value">
+ <number>24</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -1453,7 +1783,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/document-save.png</normaloff>convenience/document-save.png</iconset>
+ <normaloff>../convenience/document-save.png</normaloff>../convenience/document-save.png</iconset>
</property>
</widget>
</item>
@@ -1482,7 +1812,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/media-playback-start16.png</normaloff>convenience/media-playback-start16.png</iconset>
+ <normaloff>../convenience/media-playback-start16.png</normaloff>../convenience/media-playback-start16.png</iconset>
</property>
</widget>
</item>
@@ -1508,7 +1838,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/media-playback-start16.png</normaloff>convenience/media-playback-start16.png</iconset>
+ <normaloff>../convenience/media-playback-start16.png</normaloff>../convenience/media-playback-start16.png</iconset>
</property>
</widget>
</item>
@@ -1974,6 +2304,53 @@
<number>0</number>
</property>
<item>
+ <widget class="QLabel" name="playbackMessage">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>160</red>
+ <green>160</green>
+ <blue>160</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>160</red>
+ <green>160</green>
+ <blue>160</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="text">
+ <string>Playback message</string>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -1999,7 +2376,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/mail-mark-notjunk.png</normaloff>convenience/mail-mark-notjunk.png</iconset>
+ <normaloff>../convenience/mail-mark-notjunk.png</normaloff>../convenience/mail-mark-notjunk.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
@@ -2019,7 +2396,7 @@
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/configure.png</normaloff>convenience/configure.png</iconset>
+ <normaloff>../convenience/configure.png</normaloff>../convenience/configure.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::DelayedPopup</enum>
@@ -2465,22 +2842,428 @@
<property name="spacing">
<number>0</number>
</property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>1</number>
- </property>
- <property name="rightMargin">
+ <property name="margin">
<number>0</number>
</property>
- <property name="bottomMargin">
- <number>1</number>
- </property>
<item>
- <widget class="QSplitter" name="splitter">
+ <widget class="QSplitter" name="nowPlayingSplitter">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>72</red>
+ <green>72</green>
+ <blue>72</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>60</red>
+ <green>60</green>
+ <blue>60</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>32</red>
+ <green>32</green>
+ <blue>32</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>72</red>
+ <green>72</green>
+ <blue>72</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>60</red>
+ <green>60</green>
+ <blue>60</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>32</red>
+ <green>32</green>
+ <blue>32</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>72</red>
+ <green>72</green>
+ <blue>72</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>60</red>
+ <green>60</green>
+ <blue>60</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>32</red>
+ <green>32</green>
+ <blue>32</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>24</red>
+ <green>24</green>
+ <blue>24</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>48</red>
+ <green>48</green>
+ <blue>48</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
<property name="autoFillBackground">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -2493,7 +3276,7 @@
</size>
</property>
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="audioNowPlaying">
<property name="palette">
@@ -4255,9 +5038,18 @@ color: rgb(255, 255, 255);</string>
<property name="spacing">
<number>0</number>
</property>
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
<number>2</number>
</property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
<item>
<widget class="QFrame" name="frame_16">
<property name="sizePolicy">
@@ -4304,7 +5096,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>hi22-actions-bangarang-preview.png</normaloff>hi22-actions-bangarang-preview.png</iconset>
+ <normaloff>../icons/hi22-actions-bangarang-preview.png</normaloff>../icons/hi22-actions-bangarang-preview.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -4356,7 +5148,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>hi22-actions-bangarang-clearplaylist.png</normaloff>hi22-actions-bangarang-clearplaylist.png</iconset>
+ <normaloff>../icons/hi22-actions-bangarang-clearplaylist.png</normaloff>../icons/hi22-actions-bangarang-clearplaylist.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -4386,7 +5178,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>hi22-actions-bangarang-repeat.png</normaloff>hi22-actions-bangarang-repeat.png</iconset>
+ <normaloff>../icons/hi22-actions-bangarang-repeat.png</normaloff>../icons/hi22-actions-bangarang-repeat.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -4415,7 +5207,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>hi22-actions-bangarang-shuffle.png</normaloff>hi22-actions-bangarang-shuffle.png</iconset>
+ <normaloff>../icons/hi22-actions-bangarang-shuffle.png</normaloff>../icons/hi22-actions-bangarang-shuffle.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -4490,450 +5282,35 @@ color: rgb(255, 255, 255);</string>
<property name="spacing">
<number>0</number>
</property>
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
- <widget class="QFrame" name="frame_21">
- <property name="palette">
- <palette>
- <active>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>61</red>
- <green>61</green>
- <blue>61</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>32</red>
- <green>32</green>
- <blue>32</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>10</red>
- <green>10</green>
- <blue>10</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>219</red>
- <green>219</green>
- <blue>219</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>28</red>
- <green>28</green>
- <blue>28</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </active>
- <inactive>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>61</red>
- <green>61</green>
- <blue>61</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>32</red>
- <green>32</green>
- <blue>32</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>10</red>
- <green>10</green>
- <blue>10</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>219</red>
- <green>219</green>
- <blue>219</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>28</red>
- <green>28</green>
- <blue>28</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </inactive>
- <disabled>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>61</red>
- <green>61</green>
- <blue>61</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>32</red>
- <green>32</green>
- <blue>32</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>24</red>
- <green>24</green>
- <blue>24</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>48</red>
- <green>48</green>
- <blue>48</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>219</red>
- <green>219</green>
- <blue>219</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>28</red>
- <green>28</green>
- <blue>28</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </disabled>
- </palette>
+ <widget class="QLabel" name="label_3">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
</property>
- <property name="autoFillBackground">
- <bool>true</bool>
+ <property name="text">
+ <string>Video Settings</string>
</property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
+ <property name="margin">
+ <number>4</number>
</property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
+ <property name="indent">
+ <number>4</number>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_21">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="margin">
- <number>2</number>
- </property>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Video Settings can go here!</string>
- </property>
- </widget>
- </item>
- </layout>
</widget>
</item>
</layout>
@@ -5029,7 +5406,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/view-media-playlist.png</normaloff>convenience/view-media-playlist.png</iconset>
+ <normaloff>../convenience/view-media-playlist.png</normaloff>../convenience/view-media-playlist.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5073,7 +5450,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/view-fullscreen.png</normaloff>convenience/view-fullscreen.png</iconset>
+ <normaloff>../convenience/view-fullscreen.png</normaloff>../convenience/view-fullscreen.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5288,7 +5665,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/preferences-desktop-text-to-speech.png</normaloff>convenience/preferences-desktop-text-to-speech.png</iconset>
+ <normaloff>../convenience/preferences-desktop-text-to-speech.png</normaloff>../convenience/preferences-desktop-text-to-speech.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5349,7 +5726,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/media-skip-backward.png</normaloff>convenience/media-skip-backward.png</iconset>
+ <normaloff>../convenience/media-skip-backward.png</normaloff>../convenience/media-skip-backward.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5378,7 +5755,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/media-playback-start.png</normaloff>convenience/media-playback-start.png</iconset>
+ <normaloff>../convenience/media-playback-start.png</normaloff>../convenience/media-playback-start.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5398,7 +5775,7 @@ color: rgb(255, 255, 255);</string>
</property>
<property name="icon">
<iconset>
- <normaloff>convenience/media-skip-forward.png</normaloff>convenience/media-skip-forward.png</iconset>
+ <normaloff>../convenience/media-skip-forward.png</normaloff>../convenience/media-skip-forward.png</iconset>
</property>
<property name="iconSize">
<size>
@@ -5506,20 +5883,10 @@ color: rgb(255, 255, 255);</string>
<tabstop>seekTime</tabstop>
<tabstop>audioLists</tabstop>
<tabstop>aCancelSaveList</tabstop>
- <tabstop>aListSourceSelection</tabstop>
- <tabstop>aListSourceView</tabstop>
- <tabstop>aListSourcePlaylist</tabstop>
- <tabstop>aNewListName</tabstop>
<tabstop>saveAudioList</tabstop>
<tabstop>videoLists</tabstop>
- <tabstop>vListSourceSelection</tabstop>
- <tabstop>vListSourceView</tabstop>
- <tabstop>vListSourcePlaylist</tabstop>
<tabstop>showMenu</tabstop>
</tabstops>
<resources/>
<connections/>
- <buttongroups>
- <buttongroup name="buttonGroup"/>
- </buttongroups>
</ui>
diff --git a/mediaitemdelegate.cpp b/src/mediaitemdelegate.cpp
similarity index 95%
rename from mediaitemdelegate.cpp
rename to src/mediaitemdelegate.cpp
index cfdda22..b9aa123 100644
--- a/mediaitemdelegate.cpp
+++ b/src/mediaitemdelegate.cpp
@@ -19,6 +19,7 @@
#include "mediaitemdelegate.h"
#include "platform/playlist.h"
#include "platform/mediaitemmodel.h"
+#include "platform/mediaindexer.h"
#include "mainwindow.h"
#include <KGlobalSettings>
@@ -57,6 +58,7 @@ MediaItemDelegate::MediaItemDelegate(QObject *parent) : QItemDelegate(parent)
Nepomuk::ResourceManager::instance()->init();
if (Nepomuk::ResourceManager::instance()->initialized()) {
m_nepomukInited = true; //resource manager inited successfully
+ m_mediaIndexer = new MediaIndexer(this);
} else {
m_nepomukInited = false; //no resource manager
}
@@ -83,7 +85,8 @@ void MediaItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
QColor subColor = (option.state.testFlag(QStyle::State_Selected))?
option.palette.color(QPalette::HighlightedText) :
KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText).color();
-
+ QColor nowPlayingColor = option.palette.color(QPalette::Highlight);
+ nowPlayingColor.setAlpha(70);
//Determine item type
bool isMediaItem = false;
@@ -110,7 +113,6 @@ void MediaItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
QPainter p(&pixmap);
p.translate(-option.rect.topLeft());
-
if (index.column() == 0) {
//Paint Icon
KIcon icon(index.data(Qt::DecorationRole).value<QIcon>());
@@ -119,6 +121,12 @@ void MediaItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
MediaItem nowPlayingItem = m_parent->m_nowPlaying->mediaItemAt(0);
if (nowPlayingItem.url == index.data(MediaItem::UrlRole).toString()) {
icon = m_showPlaying;
+ QLinearGradient linearGrad(QPointF(left, top), QPointF(left+width, top));
+ linearGrad.setColorAt(0, nowPlayingColor);
+ linearGrad.setColorAt(0.7, nowPlayingColor);
+ linearGrad.setColorAt(1.0, Qt::transparent);
+ QBrush brush(linearGrad);
+ p.fillRect(left, top, width, height, brush);
}
}
int iconWidth = 22;
@@ -266,8 +274,7 @@ bool MediaItemDelegate::editorEvent( QEvent *event, QAbstractItemModel *model,
MediaItem updatedMediaItem = model->mediaItemAt(index.row());
updatedMediaItem.fields["rating"] = newRating;
model->replaceMediaItemAt(index.row(), updatedMediaItem);
- Nepomuk::Resource res(QUrl(updatedMediaItem.url));
- res.setRating(newRating);
+ m_mediaIndexer->updateInfo(updatedMediaItem);
//Keep other views of same mediaItem in sync
int playlistRow = m_parent->m_playlist->playlistModel()->rowOfUrl(updatedMediaItem.url);
if (playlistRow != -1) {
diff --git a/mediaitemdelegate.h b/src/mediaitemdelegate.h
similarity index 88%
rename from mediaitemdelegate.h
rename to src/mediaitemdelegate.h
index 5bcc643..493bdea 100644
--- a/mediaitemdelegate.h
+++ b/src/mediaitemdelegate.h
@@ -27,6 +27,14 @@
#include <QTreeView>
class MainWindow;
+class MediaIndexer;
+
+/*
+ * This Item Delegate is responsible for painting items in a
+ * MediaItemModel for a View. It is also responsible for communicating ui
+ * events to the model to activate categories or actions, etc.
+ *
+ */
class MediaItemDelegate : public QItemDelegate
{
Q_OBJECT
@@ -51,6 +59,7 @@ class MediaItemDelegate : public QItemDelegate
KIcon m_showNotInPlaylist;
int calcItemHeight(const QStyleOptionViewItem &option) const;
bool m_nepomukInited;
+ MediaIndexer * m_mediaIndexer;
Q_SIGNALS:
diff --git a/mediaview.cpp b/src/mediaview.cpp
similarity index 100%
rename from mediaview.cpp
rename to src/mediaview.cpp
diff --git a/mediaview.h b/src/mediaview.h
similarity index 92%
rename from mediaview.h
rename to src/mediaview.h
index 983d959..48a4708 100644
--- a/mediaview.h
+++ b/src/mediaview.h
@@ -23,6 +23,11 @@
#include <QAction>
class MainWindow;
+
+/*
+ * This class is mostly to provide custom context menus for the QTreeView
+ * used to display media lists.
+ */
class MediaView : public QTreeView
{
Q_OBJECT
diff --git a/nowplayingdelegate.cpp b/src/nowplayingdelegate.cpp
similarity index 98%
rename from nowplayingdelegate.cpp
rename to src/nowplayingdelegate.cpp
index 9501077..f4dae60 100644
--- a/nowplayingdelegate.cpp
+++ b/src/nowplayingdelegate.cpp
@@ -19,6 +19,7 @@
#include "nowplayingdelegate.h"
#include "platform/utilities.h"
#include "platform/mediaitemmodel.h"
+#include "platform/mediaindexer.h"
#include "platform/mediavocabulary.h"
#include "platform/playlist.h"
@@ -46,6 +47,7 @@ NowPlayingDelegate::NowPlayingDelegate(QObject *parent) : QItemDelegate(parent)
Nepomuk::ResourceManager::instance()->init();
if (Nepomuk::ResourceManager::instance()->initialized()) {
m_nepomukInited = true; //resource manager inited successfully
+ m_mediaIndexer = new MediaIndexer(this);
} else {
m_nepomukInited = false; //no resource manager
}
@@ -201,8 +203,7 @@ bool NowPlayingDelegate::editorEvent( QEvent *event, QAbstractItemModel *model,
MediaItem updatedMediaItem = model->mediaItemAt(index.row());
updatedMediaItem.fields["rating"] = newRating;
model->replaceMediaItemAt(index.row(), updatedMediaItem);
- Nepomuk::Resource res(QUrl(updatedMediaItem.url));
- res.setRating(newRating);
+ m_mediaIndexer->updateInfo(updatedMediaItem);
//Keep other views of same mediaItem in sync
int playlistRow = m_parent->m_playlist->playlistModel()->rowOfUrl(updatedMediaItem.url);
if (playlistRow != -1) {
diff --git a/nowplayingdelegate.h b/src/nowplayingdelegate.h
similarity index 85%
rename from nowplayingdelegate.h
rename to src/nowplayingdelegate.h
index b9ef0d1..3d88607 100644
--- a/nowplayingdelegate.h
+++ b/src/nowplayingdelegate.h
@@ -25,6 +25,14 @@
#include <QStyleOptionViewItem>
class MainWindow;
+class MediaIndexer;
+
+/*
+ * This ItemDelegate is responsible for painting the currently
+ * playing MediaItem for the Now Playing View. It is
+ * also responsible for updating the rating when the user changes
+ * the rating from the Now Playing View.
+ */
class NowPlayingDelegate : public QItemDelegate
{
Q_OBJECT
@@ -42,6 +50,7 @@ class NowPlayingDelegate : public QItemDelegate
QPixmap m_ratingCount;
QPixmap m_ratingNotCount;
bool m_nepomukInited;
+ MediaIndexer * m_mediaIndexer;
};
diff --git a/platform/audioclipslistengine.cpp b/src/platform/audioclipslistengine.cpp
similarity index 96%
rename from platform/audioclipslistengine.cpp
rename to src/platform/audioclipslistengine.cpp
index 00e296b..0077e97 100644
--- a/platform/audioclipslistengine.cpp
+++ b/src/platform/audioclipslistengine.cpp
@@ -22,6 +22,7 @@
#include "mediavocabulary.h"
#include <KIcon>
#include <KUrl>
+#include <KLocale>
#include <Soprano/QueryResultIterator>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/NAO>
@@ -71,6 +72,10 @@ MediaItem AudioClipsListEngine::createMediaItem(Soprano::QueryResultIterator& it
void AudioClipsListEngine::run()
{
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+ NepomukListEngine::run();
+ return;
+ }
//Create media list based on engine argument and filter
QList<MediaItem> mediaList;
@@ -99,7 +104,7 @@ void AudioClipsListEngine::run()
mediaList.append(mediaItem);
}
- m_mediaListProperties.summary = QString("%1 clips").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 clip", "%1 clips", mediaList.count());
m_mediaListProperties.type = QString("Sources");
@@ -123,7 +128,7 @@ void AudioClipsListEngine::run()
mediaList.append(mediaItem);
}
- m_mediaListProperties.summary = QString("%1 clips").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 clip", "%1 clips", mediaList.count());
m_mediaListProperties.type = QString("Sources");
}
}
@@ -136,8 +141,7 @@ void AudioClipsListEngine::run()
void AudioClipsListEngine::setFilterForSources(const QString& engineFilter)
{
//Always return songs
- // FIXME: Is it intentional that %1 is missing?
- m_mediaListProperties.lri = QString("audioclips://").arg(engineFilter);
+ m_mediaListProperties.lri = QString("audioclips://?%1").arg(engineFilter);
}
diff --git a/platform/audioclipslistengine.h b/src/platform/audioclipslistengine.h
similarity index 91%
rename from platform/audioclipslistengine.h
rename to src/platform/audioclipslistengine.h
index 15bfc5b..6089785 100644
--- a/platform/audioclipslistengine.h
+++ b/src/platform/audioclipslistengine.h
@@ -27,6 +27,34 @@ class MediaItem;
class MediaListProperties;
class ListEngineFactory;
+
+/**
+ * This ListEngine retrieves Audio Clips from the nepmuk data store.
+ * List Resource Identifiers handled are:
+ * audioclips://
+ * audioclips://search?[search term]
+ */
+class AudioClipsListEngine : public NepomukListEngine
+{
+ Q_OBJECT
+
+ public:
+ AudioClipsListEngine(ListEngineFactory *parent);
+ ~AudioClipsListEngine();
+ void run();
+ void setFilterForSources(const QString& engineFilter);
+
+ private:
+ MediaItem createMediaItem(Soprano::QueryResultIterator& it);
+
+ Q_SIGNALS:
+ void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
+
+};
+
+/**
+* This class constructs a SPARQL query to query the nepomuk store.
+*/
class AudioClipsQuery {
public:
AudioClipsQuery(bool distinct = true);
@@ -68,22 +96,5 @@ class AudioClipsQuery {
QString getPrefix();
};
-class AudioClipsListEngine : public NepomukListEngine
-{
- Q_OBJECT
-
- public:
- AudioClipsListEngine(ListEngineFactory *parent);
- ~AudioClipsListEngine();
- void run();
- void setFilterForSources(const QString& engineFilter);
-
- private:
- MediaItem createMediaItem(Soprano::QueryResultIterator& it);
-
- Q_SIGNALS:
- void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
-
-};
#endif // AUDIOCLIPSLISTENGINE_H
diff --git a/platform/audiostreamlistengine.cpp b/src/platform/audiostreamlistengine.cpp
similarity index 93%
rename from platform/audiostreamlistengine.cpp
rename to src/platform/audiostreamlistengine.cpp
index 2ed6ecf..3252693 100644
--- a/platform/audiostreamlistengine.cpp
+++ b/src/platform/audiostreamlistengine.cpp
@@ -22,6 +22,7 @@
#include "mediavocabulary.h"
#include <KIcon>
#include <KUrl>
+#include <KLocale>
#include <Soprano/QueryResultIterator>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/NAO>
@@ -71,6 +72,10 @@ MediaItem AudioStreamListEngine::createMediaItem(Soprano::QueryResultIterator& i
void AudioStreamListEngine::run()
{
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+ NepomukListEngine::run();
+ return;
+ }
//Create media list based on engine argument and filter
QList<MediaItem> mediaList;
@@ -99,12 +104,12 @@ void AudioStreamListEngine::run()
mediaList.append(mediaItem);
}
- m_mediaListProperties.summary = QString("%1 streams").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 stream", "%1 streams", mediaList.count());
MediaItem mediaItem;
mediaItem.type = "Action";
mediaItem.url = "audiostreams://";
- mediaItem.title = "Create new audio stream item";
+ mediaItem.title = i18n("Create new audio stream item");
mediaItem.artwork = KIcon("document-new");
mediaList.append(mediaItem);
@@ -130,7 +135,7 @@ void AudioStreamListEngine::run()
mediaList.append(mediaItem);
}
- m_mediaListProperties.summary = QString("%1 streams").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 stream", "%1 streams", mediaList.count());
m_mediaListProperties.type = QString("Sources");
}
}
@@ -143,8 +148,7 @@ void AudioStreamListEngine::run()
void AudioStreamListEngine::setFilterForSources(const QString& engineFilter)
{
//Always return songs
- // FIXME: Is it intentional that %1 is missing?
- m_mediaListProperties.lri = QString("audiostreams://").arg(engineFilter);
+ m_mediaListProperties.lri = QString("audiostreams://?%1").arg(engineFilter);
}
void AudioStreamListEngine::activateAction()
@@ -152,8 +156,8 @@ void AudioStreamListEngine::activateAction()
MediaItem mediaItem;
mediaItem.type = "Audio";
mediaItem.url = QString();
- mediaItem.title = "Untitled Audio Stream";
- mediaItem.subTitle = "Select this item, click Info then Edit to enter audio stream info";
+ mediaItem.title = i18n("Untitled Audio Stream");
+ mediaItem.subTitle = i18n("Select this item, click Info then Edit to enter audio stream info");
mediaItem.artwork = KIcon("x-media-podcast");
mediaItem.fields["title"] = "Untitled";
mediaItem.fields["audioType"] = "Audio Stream";
@@ -162,7 +166,7 @@ void AudioStreamListEngine::activateAction()
QList<MediaItem> mediaList;
mediaList << mediaItem;
- m_mediaListProperties.name = "New Audio Stream";
+ m_mediaListProperties.name = i18n("New Audio Stream");
model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
}
diff --git a/platform/audiostreamlistengine.h b/src/platform/audiostreamlistengine.h
similarity index 94%
rename from platform/audiostreamlistengine.h
rename to src/platform/audiostreamlistengine.h
index 61e6df7..2a55583 100644
--- a/platform/audiostreamlistengine.h
+++ b/src/platform/audiostreamlistengine.h
@@ -27,6 +27,31 @@ class MediaItem;
class MediaListProperties;
class ListEngineFactory;
+/**
+* This ListEngine retrieves Audio Streams from the nepomuk data store.
+* List Resource Identifiers handled are:
+* audiostreams://
+* audiostreams://search
+*/
+class AudioStreamListEngine : public NepomukListEngine
+{
+ Q_OBJECT
+
+ public:
+ AudioStreamListEngine(ListEngineFactory *parent);
+ ~AudioStreamListEngine();
+ void run();
+ void setFilterForSources(const QString& engineFilter);
+ void activateAction();
+
+ private:
+ MediaItem createMediaItem(Soprano::QueryResultIterator& it);
+
+ Q_SIGNALS:
+ void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
+
+};
+
class AudioStreamQuery {
public:
AudioStreamQuery(bool distinct = true);
@@ -68,23 +93,5 @@ class AudioStreamQuery {
QString getPrefix();
};
-class AudioStreamListEngine : public NepomukListEngine
-{
- Q_OBJECT
-
- public:
- AudioStreamListEngine(ListEngineFactory *parent);
- ~AudioStreamListEngine();
- void run();
- void setFilterForSources(const QString& engineFilter);
- void activateAction();
-
- private:
- MediaItem createMediaItem(Soprano::QueryResultIterator& it);
-
- Q_SIGNALS:
- void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
-
-};
#endif // AUDIOSTREAMLISTENGINE_H
diff --git a/platform/cachelistengine.cpp b/src/platform/cachelistengine.cpp
similarity index 100%
rename from platform/cachelistengine.cpp
rename to src/platform/cachelistengine.cpp
diff --git a/platform/cachelistengine.h b/src/platform/cachelistengine.h
similarity index 90%
rename from platform/cachelistengine.h
rename to src/platform/cachelistengine.h
index 777b0f6..da2e6c4 100644
--- a/platform/cachelistengine.h
+++ b/src/platform/cachelistengine.h
@@ -26,6 +26,11 @@ class MediaItem;
class MediaListProperties;
class ListEngineFactory;
+/**
+* This ListEngine retrieves cached media lists from the cache.
+* List Resource Identifiers handled are:
+* cache://?[lri]
+*/
class CacheListEngine : public ListEngine
{
Q_OBJECT
diff --git a/platform/cdlistengine.cpp b/src/platform/cdlistengine.cpp
similarity index 90%
rename from platform/cdlistengine.cpp
rename to src/platform/cdlistengine.cpp
index 6ee5304..3655e83 100644
--- a/platform/cdlistengine.cpp
+++ b/src/platform/cdlistengine.cpp
@@ -31,6 +31,7 @@
#include <KIcon>
#include <KFileDialog>
#include <KMimeType>
+#include <KLocale>
#include <Phonon/MediaController>
#include <Solid/Device>
#include <Solid/DeviceInterface>
@@ -76,11 +77,11 @@ void CDListEngine::run()
QString artist;
//int duration;
for (int i = 1; i <= trackCount; i++) {
- title = QString("Track %1").arg(i);
+ title = i18n("Track %1", i);
mediaItem.url = QString("CDTRACK%1").arg(i);
mediaItem.artwork = KIcon("media-optical-audio");
mediaItem.title = title;
- mediaItem.subTitle = QString("Audio CD - %1 Tracks").arg(trackCount);
+ mediaItem.subTitle = i18n("Audio CD - %1 Tracks", trackCount);
mediaItem.type = "Audio";
mediaItem.fields["url"] = mediaItem.url;
mediaItem.fields["title"] = mediaItem.title;
@@ -89,11 +90,7 @@ void CDListEngine::run()
mediaList << mediaItem;
}
- /*mediaItem.url = "-";
- mediaItem.title = QString("Number of tracks: %1").arg(trackCount);
- mediaItem.type = "Audio";
- mediaList << mediaItem;*/
- m_mediaListProperties.summary = QString("%1 tracks").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 track", "%1 tracks", mediaList.count());
model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
m_requestSignature = QString();
m_subRequestSignature = QString();
diff --git a/platform/cdlistengine.h b/src/platform/cdlistengine.h
similarity index 93%
rename from platform/cdlistengine.h
rename to src/platform/cdlistengine.h
index 3c4fe06..f511015 100644
--- a/platform/cdlistengine.h
+++ b/src/platform/cdlistengine.h
@@ -32,6 +32,11 @@ class MediaListProperties;
class ListEngineFactory;
class MediaIndexer;
+/**
+* This ListEngine retrieves CD tracks from an Audio CD.
+* List Resource Identifiers handled are:
+* cdaudio://
+*/
class CDListEngine : public ListEngine
{
Q_OBJECT
diff --git a/platform/dvdlistengine.cpp b/src/platform/dvdlistengine.cpp
similarity index 92%
rename from platform/dvdlistengine.cpp
rename to src/platform/dvdlistengine.cpp
index 8825be8..c498c0a 100644
--- a/platform/dvdlistengine.cpp
+++ b/src/platform/dvdlistengine.cpp
@@ -27,6 +27,7 @@
#include <KIcon>
#include <KFileDialog>
#include <KMimeType>
+#include <KLocale>
#include <Phonon/MediaController>
#include <Solid/Device>
#include <Solid/DeviceInterface>
@@ -72,11 +73,11 @@ void DVDListEngine::run()
QString artist;
//int duration;
for (int i = 1; i <= trackCount; i++) {
- title = QString("Title %1").arg(i);
+ title = i18n("Title %1", i);
mediaItem.url = QString("DVDTRACK%1").arg(i);
mediaItem.artwork = KIcon("media-optical-dvd");
mediaItem.title = title;
- mediaItem.subTitle = QString("DVD Video - %1 Titles").arg(trackCount);
+ mediaItem.subTitle = i18n("DVD Video - %1 Titles", trackCount);
mediaItem.type = "Video";
mediaItem.fields["url"] = mediaItem.url;
mediaItem.fields["title"] = mediaItem.title;
@@ -85,10 +86,6 @@ void DVDListEngine::run()
mediaList << mediaItem;
}
- /*mediaItem.url = "-";
- mediaItem.title = QString("Number of tracks: %1").arg(trackCount);
- mediaItem.type = "Audio";
- mediaList << mediaItem;*/
model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
m_requestSignature = QString();
m_subRequestSignature = QString();
diff --git a/platform/dvdlistengine.h b/src/platform/dvdlistengine.h
similarity index 93%
rename from platform/dvdlistengine.h
rename to src/platform/dvdlistengine.h
index d37d4ad..8b329b6 100644
--- a/platform/dvdlistengine.h
+++ b/src/platform/dvdlistengine.h
@@ -31,6 +31,11 @@ class MediaListProperties;
class ListEngineFactory;
class MediaIndexer;
+/**
+* This ListEngine retrieves video Titles from an DVD.
+* List Resource Identifiers handled are:
+* dvdvideo://
+*/
class DVDListEngine : public ListEngine
{
Q_OBJECT
diff --git a/platform/filelistengine.cpp b/src/platform/filelistengine.cpp
similarity index 51%
rename from platform/filelistengine.cpp
rename to src/platform/filelistengine.cpp
index b7f25d9..892cb7a 100644
--- a/platform/filelistengine.cpp
+++ b/src/platform/filelistengine.cpp
@@ -28,6 +28,8 @@
#include <Soprano/Vocabulary/RDF>
#include <Soprano/Vocabulary/XMLSchema>
#include <QApplication>
+#include <KEncodingProber>
+#include <KLocale>
#include <KIcon>
#include <KFileDialog>
#include <KMimeType>
@@ -41,6 +43,8 @@
FileListEngine::FileListEngine(ListEngineFactory * parent) : NepomukListEngine(parent)
{
+ m_getFilesAction = false;
+ m_getFolderAction = false;
}
FileListEngine::~FileListEngine()
@@ -49,40 +53,100 @@ FileListEngine::~FileListEngine()
void FileListEngine::run()
{
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+ NepomukListEngine::run();
+ return;
+ }
+
MediaItem mediaItem;
QList<MediaItem> mediaList;
+
+ if (m_getFilesAction || m_getFolderAction) {
+ MediaListProperties mediaListProperties;
+ if (m_mediaListProperties.engineFilter() == "getFiles") {
+ if (m_mediaListProperties.engineArg() == "audio") {
+ mediaList = readAudioUrlList(m_fileList);
+ mediaListProperties.name = i18n("Audio Files");
+ mediaListProperties.lri = QString("files://audio?getFiles||%1").arg(engineFilterFromUrlList(m_fileList));
+ }
+ if (m_mediaListProperties.engineArg() == "video") {
+ mediaList = readVideoUrlList(m_fileList);
+ mediaListProperties.name = i18n("Video Files");
+ mediaListProperties.lri = QString("files://video?getFiles||%1").arg(engineFilterFromUrlList(m_fileList));
+ }
+ m_getFilesAction = false;
+ } else if (m_mediaListProperties.engineFilter() == "getFolder") {
+ if (m_mediaListProperties.engineArg() == "audio") {
+ if (!m_directoryPath.isEmpty()) {
+ QDir directory(m_directoryPath);
+ QFileInfoList fileInfoList = crawlDir(directory, Utilities::audioMimeFilter().split(" "));
+ KUrl::List fileList = QFileInfoListToKUrlList(fileInfoList);
+ mediaList = readAudioUrlList(fileList);
+ }
+ mediaListProperties.name = i18n("Audio Files");
+ mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
+ mediaListProperties.lri = QString("files://audio?getFolder||%1").arg(m_directoryPath);
+ }
+ if (m_mediaListProperties.engineArg() == "video") {
+ if (!m_directoryPath.isEmpty()) {
+ QDir directory(m_directoryPath);
+ QFileInfoList fileInfoList = crawlDir(directory, Utilities::videoMimeFilter().split(" "));
+ KUrl::List fileList = QFileInfoListToKUrlList(fileInfoList);
+ mediaList = readVideoUrlList(fileList);
+ }
+ mediaListProperties.name = i18n("Video Files");
+ mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
+ mediaListProperties.lri = QString("files://video?getFolder||%1").arg(m_directoryPath);
+ }
+ m_getFolderAction = false;
+ }
+ model()->addResults(m_requestSignature, mediaList, mediaListProperties, true, m_subRequestSignature);
+ if (m_nepomukInited && m_mediaListToIndex.count() > 0) {
+ NepomukListEngine::updateSourceInfo(m_mediaListToIndex);
+ m_mediaIndexer = new MediaIndexer(this);
+ connectIndexer();
+ m_mediaIndexer->updateInfo(m_mediaListToIndex);
+ m_updateSourceInfo = false;
+ m_mediaListToIndex.clear();
+ m_requestSignature = QString();
+ m_subRequestSignature = QString();
+ exec();
+ }
+ return;
+ }
+
if (m_mediaListProperties.engineFilter().isEmpty()) {
if (m_mediaListProperties.engineArg() == "audio") {
mediaItem.artwork = KIcon("document-open");
mediaItem.url = "files://audio?getFiles";
- mediaItem.title = "Open audio file(s)";
+ mediaItem.title = i18n("Open audio file(s)");
mediaItem.type = "Action";
mediaList << mediaItem;
mediaItem.artwork = KIcon("document-open-folder");
mediaItem.url = "files://audio?getFolder";
- mediaItem.title = "Open folder containing audio file(s)";
+ mediaItem.title = i18n("Open folder containing audio file(s)");
mediaItem.type = "Action";
- mediaList << mediaItem;
+ mediaList << mediaItem;
} else if (m_mediaListProperties.engineArg() == "video") {
mediaItem.artwork = KIcon("document-open");
mediaItem.url = "files://video?getFiles";
- mediaItem.title = "Open video file(s)";
+ mediaItem.title = i18n("Open video file(s)");
mediaItem.type = "Action";
mediaList << mediaItem;
mediaItem.artwork = KIcon("document-open-folder");
mediaItem.url = "files://video?getFolder";
- mediaItem.title = "Open folder containing video file(s)";
+ mediaItem.title = i18n("Open folder containing video file(s)");
mediaItem.type = "Action";
mediaList << mediaItem;
} else if (m_mediaListProperties.engineArg() == "images") {
mediaItem.artwork = KIcon("document-open");
mediaItem.url = "files://images?getFiles";
- mediaItem.title = "Open image file(s)";
+ mediaItem.title = i18n("Open image file(s)");
mediaItem.type = "Action";
mediaList << mediaItem;
mediaItem.artwork = KIcon("document-open-folder");
mediaItem.url = "files://images?getFolder";
- mediaItem.title = "Open folder containing image file(s)";
+ mediaItem.title = i18n("Open folder containing image file(s)");
mediaItem.type = "Action";
mediaList << mediaItem;
}
@@ -115,13 +179,13 @@ void FileListEngine::run()
}
}
}
- m_mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
}
model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
m_requestSignature = QString();
m_subRequestSignature = QString();
- //exec();
+ //exec();
}
void FileListEngine::activateAction()
@@ -130,45 +194,27 @@ void FileListEngine::activateAction()
MediaListProperties mediaListProperties;
if (m_mediaListProperties.engineFilter() == "getFiles") {
if (m_mediaListProperties.engineArg() == "audio") {
- KUrl::List fileList = KFileDialog::getOpenUrls(KUrl(), Utilities::audioMimeFilter(), 0, "Open audio file(s)");
- mediaList = readAudioUrlList(fileList);
- mediaListProperties.name = "Audio Files";
- mediaListProperties.lri = QString("files://audio?getFiles||%1").arg(engineFilterFromUrlList(fileList));
+ m_fileList = KFileDialog::getOpenUrls(KUrl(), Utilities::audioMimeFilter(), 0, i18n("Open audio file(s)"));
+ m_getFilesAction = true;
+ start();
}
if (m_mediaListProperties.engineArg() == "video") {
- KUrl::List fileList = KFileDialog::getOpenUrls(KUrl(), Utilities::videoMimeFilter(), 0, "Open video file(s)");
- mediaList = readVideoUrlList(fileList);
- mediaListProperties.name = "Video Files";
- mediaListProperties.lri = QString("files://video?getFiles||%1").arg(engineFilterFromUrlList(fileList));
+ m_fileList = KFileDialog::getOpenUrls(KUrl(), Utilities::videoMimeFilter(), 0, i18n("Open video file(s)"));
+ m_getFilesAction = true;
+ start();
}
} else if (m_mediaListProperties.engineFilter() == "getFolder") {
if (m_mediaListProperties.engineArg() == "audio") {
- QString directoryPath = KFileDialog::getExistingDirectory(KUrl(), 0, "Open folder containing audio file(s)");
- if (!directoryPath.isEmpty()) {
- QDir directory(directoryPath);
- QFileInfoList fileInfoList = crawlDir(directory, Utilities::audioMimeFilter().split(" "));
- KUrl::List fileList = QFileInfoListToKUrlList(fileInfoList);
- mediaList = readAudioUrlList(fileList);
- }
- mediaListProperties.name = "Audio Files";
- mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- mediaListProperties.lri = QString("files://audio?getFolder||%1").arg(directoryPath);
+ m_directoryPath = KFileDialog::getExistingDirectory(KUrl(), 0, i18n("Open folder containing audio file(s)"));
+ m_getFolderAction = true;
+ start();
}
if (m_mediaListProperties.engineArg() == "video") {
- QString directoryPath = KFileDialog::getExistingDirectory(KUrl(), 0, "Open folder containing video file(s)");
- if (!directoryPath.isEmpty()) {
- QDir directory(directoryPath);
- QFileInfoList fileInfoList = crawlDir(directory, Utilities::videoMimeFilter().split(" "));
- KUrl::List fileList = QFileInfoListToKUrlList(fileInfoList);
- mediaList = readVideoUrlList(fileList);
- }
- mediaListProperties.name = "Video Files";
- mediaListProperties.summary = QString("%1 items").arg(mediaList.count());
- mediaListProperties.lri = QString("files://video?getFolder||%1").arg(directoryPath);
+ m_directoryPath = KFileDialog::getExistingDirectory(KUrl(), 0, i18n("Open folder containing video file(s)"));
+ m_getFolderAction = true;
+ start();
}
}
-
- model()->addResults(m_requestSignature, mediaList, mediaListProperties, true, m_subRequestSignature);
}
QFileInfoList FileListEngine::crawlDir(QDir dir, QStringList mimeFilter)
@@ -205,9 +251,17 @@ QList<MediaItem> FileListEngine::readAudioUrlList(KUrl::List fileList)
{
MediaVocabulary mediaVocabulary = MediaVocabulary();
QList<MediaItem> mediaList;
- QList<MediaItem> mediaListToIndex;
+ //QList<MediaItem> mediaListToIndex;
for (int i = 0; i < fileList.count(); ++i) {
MediaItem mediaItem;
+ if (Utilities::isM3u(fileList.at(i).url()) || Utilities::isPls(fileList.at(i).url())) {
+ mediaItem.artwork = KIcon("view-list-text");
+ mediaItem.url = QString("savedlists://%1").arg(fileList.at(i).url());
+ mediaItem.title = fileList.at(i).fileName();
+ mediaItem.type = "Category";
+ mediaList << mediaItem;
+ continue;
+ }
mediaItem.artwork = KIcon("audio-mp4");
mediaItem.url = fileList.at(i).url();
mediaItem.title = fileList.at(i).fileName();
@@ -215,7 +269,7 @@ QList<MediaItem> FileListEngine::readAudioUrlList(KUrl::List fileList)
mediaItem.fields["url"] = mediaItem.url;
mediaItem.fields["title"] = fileList.at(i).fileName();
if (Utilities::isMusic(mediaItem.url)) {
- TagLib::FileRef file(KUrl(mediaItem.url).path().toUtf8());
+ TagLib::FileRef file(KUrl(mediaItem.url).path().toLocal8Bit());
if (file.isNull()) {
continue;
}
@@ -223,6 +277,31 @@ QList<MediaItem> FileListEngine::readAudioUrlList(KUrl::List fileList)
QString artist = TStringToQString(file.tag()->artist()).trimmed();
QString album = TStringToQString(file.tag()->album()).trimmed();
QString genre = TStringToQString(file.tag()->genre()).trimmed();
+ if (KUrl(mediaItem.url).path().endsWith(".mp3")) {
+ // detect encoding for mpeg id3v2
+ QString tmp = title + artist + album + genre;
+ KEncodingProber prober(KEncodingProber::Universal);
+ KEncodingProber::ProberState result = prober.feed(tmp.toAscii());
+ if (result != KEncodingProber::NotMe) {
+ QByteArray encodingname = prober.encoding();
+ QString track_encoding(encodingname);
+ if ( ( track_encoding.toLatin1() == "gb18030" )
+ || ( track_encoding.toLatin1() == "big5" )
+ || ( track_encoding.toLatin1() == "euc-kr" )
+ || ( track_encoding.toLatin1() == "euc-jp" )
+ || ( track_encoding.toLatin1() == "koi8-r" ) ) {
+ title = QTextCodec::codecForName(encodingname)->toUnicode(title.toAscii());
+ artist = QTextCodec::codecForName(encodingname)->toUnicode(artist.toAscii());
+ album = QTextCodec::codecForName(encodingname)->toUnicode(album.toAscii());
+ genre = QTextCodec::codecForName(encodingname)->toUnicode(genre.toAscii());
+ } else if (QTextCodec::codecForLocale()->name().toLower() != "utf-8") {
+ title = QTextCodec::codecForLocale()->toUnicode(title.toAscii());
+ artist = QTextCodec::codecForLocale()->toUnicode(artist.toAscii());
+ album = QTextCodec::codecForLocale()->toUnicode(album.toAscii());
+ genre = QTextCodec::codecForLocale()->toUnicode(genre.toAscii());
+ }
+ }
+ }
int track = file.tag()->track();
int duration = file.audioProperties()->length();
int year = file.tag()->year();
@@ -250,9 +329,9 @@ QList<MediaItem> FileListEngine::readAudioUrlList(KUrl::List fileList)
}
}
//Index all music files
- mediaListToIndex << mediaItem;
+ m_mediaListToIndex << mediaItem;
} else {
- mediaItem.fields["audioType"] = "Audio Clip";
+ mediaItem.fields["audioType"] = i18n("Audio Clip");
if (m_nepomukInited) {
Nepomuk::Resource res(mediaItem.url);
if (res.exists()) {
@@ -268,23 +347,22 @@ QList<MediaItem> FileListEngine::readAudioUrlList(KUrl::List fileList)
}
} else {
//Index Audio Clips not found in nepomuk store
- mediaListToIndex << mediaItem;
+ m_mediaListToIndex << mediaItem;
}
}
}
mediaList << mediaItem;
}
- if (m_nepomukInited) {
- m_mediaIndexer->indexMediaItems(mediaListToIndex);
- }
return mediaList;
}
QList<MediaItem> FileListEngine::readVideoUrlList(KUrl::List fileList)
{
MediaVocabulary mediaVocabulary = MediaVocabulary();
+ mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ mediaVocabulary.setVideoVocabulary(MediaVocabulary::nmm);
QList<MediaItem> mediaList;
- QList<MediaItem> mediaListToIndex;
+ //QList<MediaItem> mediaListToIndex;
for (int i = 0; i < fileList.count(); ++i) {
MediaItem mediaItem;
mediaItem.artwork = KIcon("video-x-generic");
@@ -307,27 +385,56 @@ QList<MediaItem> FileListEngine::readVideoUrlList(KUrl::List fileList)
if (!description.isEmpty()) {
mediaItem.fields["description"] = description;
}
- if (res.hasProperty(mediaVocabulary.videoIsMovie())) {
- if (res.property(mediaVocabulary.videoIsMovie()).toBool()) {
- mediaItem.artwork = KIcon("tool-animator");
- mediaItem.fields["videoType"] = "Movie";
- QString seriesName = res.property(mediaVocabulary.videoSeriesName()).toString();
- if (!seriesName.isEmpty()) {
- mediaItem.fields["seriesName"] = seriesName;
- mediaItem.subTitle = seriesName;
- }
+ if (res.hasType(mediaVocabulary.typeVideoMovie())) {
+ mediaItem.artwork = KIcon("tool-animator");
+ mediaItem.fields["videoType"] = "Movie";
+ QString synopsis = res.property(mediaVocabulary.videoSynopsis()).toString();
+ if (!synopsis.isEmpty()) {
+ mediaItem.fields["synopsis"] = synopsis;
+ }
+ QString genre = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!genre.isEmpty()) {
+ mediaItem.fields["genre"] = genre;
+ }
+ QDate releaseDate = res.property(mediaVocabulary.releaseDate()).toDate();
+ if (releaseDate.isValid()) {
+ mediaItem.fields["releaseDate"] = releaseDate;
+ }
+ QString writer = res.property(mediaVocabulary.videoWriter()).toString();
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = writer;
+ }
+ QString director = res.property(mediaVocabulary.videoDirector()).toString();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
}
- } else if (res.hasProperty(mediaVocabulary.videoIsTVShow())) {
- if (res.property(mediaVocabulary.videoIsTVShow()).toBool()) {
- mediaItem.artwork = KIcon("video-television");
- mediaItem.fields["videoType"] = "TV Show";
+ QString assistantDirector = res.property(mediaVocabulary.videoAssistantDirector()).toString();
+ if (!assistantDirector.isEmpty()) {
+ mediaItem.fields["assistantDirector"] = assistantDirector;
}
- QString seriesName = res.property(mediaVocabulary.videoSeriesName()).toString();
+ QString producer = res.property(mediaVocabulary.videoProducer()).toString();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+ QString actor = res.property(mediaVocabulary.videoActor()).toString();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
+ }
+ QString cinematographer = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!cinematographer.isEmpty()) {
+ mediaItem.fields["cinematographer"] = cinematographer;
+ }
+
+ } else if (res.hasType(mediaVocabulary.typeVideoTVShow())) {
+ mediaItem.artwork = KIcon("video-television");
+ mediaItem.fields["videoType"] = "TV Show";
+ Nepomuk::Resource series = res.property(mediaVocabulary.videoSeries()).toResource();
+ QString seriesName = series.property(mediaVocabulary.title()).toString();
if (!seriesName.isEmpty()) {
mediaItem.fields["seriesName"] = seriesName;
mediaItem.subTitle = seriesName;
}
- int season = res.property(mediaVocabulary.videoSeriesSeason()).toInt();
+ int season = res.property(mediaVocabulary.videoSeason()).toInt();
if (season !=0 ) {
mediaItem.fields["season"] = season;
if (!mediaItem.subTitle.isEmpty()) {
@@ -338,17 +445,52 @@ QList<MediaItem> FileListEngine::readVideoUrlList(KUrl::List fileList)
mediaItem.subTitle = QString("Season %1").arg(season);
}
}
- int episode = res.property(mediaVocabulary.videoSeriesEpisode()).toInt();
+ int episode = res.property(mediaVocabulary.videoEpisodeNumber()).toInt();
if (episode !=0 ) {
mediaItem.fields["episode"] = episode;
if (!mediaItem.subTitle.isEmpty()) {
- mediaItem.subTitle = QString("%1 - Episode %2")
- .arg(mediaItem.subTitle)
- .arg(episode);
+ mediaItem.subTitle = i18n("%1 - Episode %2", mediaItem.subTitle, episode);
} else {
- mediaItem.subTitle = QString("Episode %2").arg(episode);
+ mediaItem.subTitle = i18n("Episode %1", episode);
}
}
+ QString synopsis = res.property(mediaVocabulary.videoSynopsis()).toString();
+ if (!synopsis.isEmpty()) {
+ mediaItem.fields["synopsis"] = synopsis;
+ }
+ QString genre = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!genre.isEmpty()) {
+ mediaItem.fields["genre"] = genre;
+ }
+ QDate releaseDate = res.property(mediaVocabulary.releaseDate()).toDate();
+ if (releaseDate.isValid()) {
+ mediaItem.fields["releaseDate"] = releaseDate;
+ }
+ QString writer = res.property(mediaVocabulary.videoWriter()).toString();
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = writer;
+ }
+ QString director = res.property(mediaVocabulary.videoDirector()).toString();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
+ }
+ QString assistantDirector = res.property(mediaVocabulary.videoAssistantDirector()).toString();
+ if (!assistantDirector.isEmpty()) {
+ mediaItem.fields["assistantDirector"] = assistantDirector;
+ }
+ QString producer = res.property(mediaVocabulary.videoProducer()).toString();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+ QString actor = res.property(mediaVocabulary.videoActor()).toString();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
+ }
+ QString cinematographer = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!cinematographer.isEmpty()) {
+ mediaItem.fields["cinematographer"] = cinematographer;
+ }
+
} else {
mediaItem.fields["videoType"] = "Video Clip";
mediaItem.artwork = KIcon("video-x-generic");
@@ -363,14 +505,11 @@ QList<MediaItem> FileListEngine::readVideoUrlList(KUrl::List fileList)
}
} else {
//Index video items not found in nepomuk store
- mediaListToIndex << mediaItem;
+ m_mediaListToIndex << mediaItem;
}
}
mediaList << mediaItem;
}
- if (m_nepomukInited) {
- m_mediaIndexer->indexMediaItems(mediaListToIndex);
- }
return mediaList;
}
@@ -383,3 +522,4 @@ QString FileListEngine::engineFilterFromUrlList(KUrl::List fileList)
}
return engineFilter;
}
+
diff --git a/platform/filelistengine.h b/src/platform/filelistengine.h
similarity index 77%
rename from platform/filelistengine.h
rename to src/platform/filelistengine.h
index 03926d7..39a9d99 100644
--- a/platform/filelistengine.h
+++ b/src/platform/filelistengine.h
@@ -32,6 +32,17 @@ class MediaListProperties;
class ListEngineFactory;
class MediaIndexer;
+/**
+* This ListEngine retrieves media files.
+* It also automatically updates Music file information in the nepomuk data store.
+* List Resource Identifiers handled are:
+* files://audio
+* files://video
+* files://audio?getFiles||[filelist]
+* files://audio?getFolder||[folder]
+* files://video?getFiles||[filelist]
+* files://video?getFolder||[folder]
+*/
class FileListEngine : public NepomukListEngine
{
Q_OBJECT
@@ -48,6 +59,11 @@ class FileListEngine : public NepomukListEngine
QList<MediaItem> readAudioUrlList(KUrl::List fileList);
QList<MediaItem> readVideoUrlList(KUrl::List fileList);
QString engineFilterFromUrlList(KUrl::List fileList);
+ KUrl::List m_fileList;
+ QString m_directoryPath;
+ bool m_getFilesAction;
+ bool m_getFolderAction;
+ QList<MediaItem> m_mediaListToIndex;
Q_SIGNALS:
void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
diff --git a/platform/listengine.cpp b/src/platform/listengine.cpp
similarity index 100%
rename from platform/listengine.cpp
rename to src/platform/listengine.cpp
diff --git a/src/platform/listengine.h b/src/platform/listengine.h
new file mode 100644
index 0000000..2197a1a
--- /dev/null
+++ b/src/platform/listengine.h
@@ -0,0 +1,146 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef LISTENGINE_H
+#define LISTENGINE_H
+
+#include "mediaitemmodel.h"
+#include "listenginefactory.h"
+#include <QtCore>
+
+/**
+* This is the base ListEngine class.
+* It is a QThread to allow it to run asynchronously without blocking the gui
+* on long queries.
+*/
+class ListEngine : public QThread
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor
+ */
+ ListEngine(ListEngineFactory *parent);
+
+ /**
+ * Destructor
+ */
+ virtual ~ListEngine();
+
+ /**
+ * Returns MediaListProperties currently used by the ListEngine
+ */
+ const MediaListProperties& mediaListProperties() const;
+
+ /**
+ * Returns the requestSignature currently used by the ListEngine
+ */
+ const QString& requestSignature() const;
+
+ /**
+ * Sets the MediaListProperties to be used by the ListEngine
+ *
+ * @param mediaListProperties the MediaListProperties to be used
+ */
+ void setMediaListProperties(const MediaListProperties& mediaListProperties);
+
+ /**
+ * Sets the request signature to be used by the ListEngine
+ *
+ * @param requestSignature the request signature to be used
+ */
+ void setRequestSignature(const QString& requestSignature);
+
+ /**
+ * Sets the sub-request signature to be used by the ListEngine.
+ * This is used by the MediaItemModel when the ListEngine is used
+ * to retrieve a list of MediaItems corresponding to a "Category"
+ * MediaItem found in while performing MediaItemModel::loadSources().
+ */
+ void setSubRequestSignature(const QString& subRequestSignature);
+
+ /**
+ * Returns the sub-request signature currently used by the ListEngine.
+ *
+ * @param subRequestSignature the sub-request signature to be used
+ */
+ const QString& subRequestSignature() const;
+
+ /**
+ * Sets model using this ListEngine
+ *
+ * @param mediaItemModel MediaItemModel using this ListEngine.
+ */
+ void setModel(MediaItemModel * mediaItemModel);
+
+ /**
+ * Returns the model used by this ListEngine
+ */
+ MediaItemModel * model();
+
+ /**
+ * Sets the filter to be used when loading only playable MediaItems.
+ * This supports MediaItemModel::loadSources() method.
+ *
+ * @param engineFilter engine filter to be used for loading playable
+ * MediaItems.
+ *
+ */
+ virtual void setFilterForSources(const QString& engineFilter)
+ {
+ Q_UNUSED(engineFilter);
+ }
+
+ /**
+ * Method called by MediaItemModel to activate and "Action" MediaItem
+ */
+ virtual void activateAction(){}
+
+ /**
+ * Removes information for specified MediaItems from the source of
+ * the mediaItems.
+ *
+ * @param mediaList list of MediaItems whose information should be
+ * removed from the source.
+ */
+ virtual void removeSourceInfo(QList<MediaItem> mediaList)
+ {
+ Q_UNUSED(mediaList);
+ }
+
+ /**
+ * Update source with information from specified MediaItems.
+ *
+ * @param mediaList list of MediaItems whose information should be
+ * upated in the source.
+ */
+ virtual void updateSourceInfo(QList<MediaItem> mediaList)
+ {
+ Q_UNUSED(mediaList);
+ }
+
+ protected:
+ MediaListProperties m_mediaListProperties;
+ QString m_requestSignature;
+ QString m_subRequestSignature;
+
+ private:
+ MediaItemModel * m_mediaItemModel;
+};
+#endif // LISTENGINE_H
diff --git a/platform/listenginefactory.cpp b/src/platform/listenginefactory.cpp
similarity index 100%
rename from platform/listenginefactory.cpp
rename to src/platform/listenginefactory.cpp
diff --git a/platform/listenginefactory.h b/src/platform/listenginefactory.h
similarity index 71%
rename from platform/listenginefactory.h
rename to src/platform/listenginefactory.h
index 93f335c..dd118d0 100644
--- a/platform/listenginefactory.h
+++ b/src/platform/listenginefactory.h
@@ -36,15 +36,47 @@ class SemanticsListEngine;
class CacheListEngine;
class AudioClipsListEngine;
+/**
+ * This class creates ListEngines as needed for the MediaItemModel.
+ */
+
class ListEngineFactory : public QObject
{
Q_OBJECT
public:
+ /**
+ * Constructor
+ */
ListEngineFactory(MediaItemModel *parent);
+
+ /**
+ * Destructor
+ */
~ListEngineFactory();
+
+ /**
+ * Returns an available ListEngine for the specified engine`.
+ * ListEngineFactory factory will reuse ListEngines that are
+ * idle and create a new ListEngine if no idle ListEngines
+ * are available.
+ *
+ * @param engine the engine (from the lri) for which a
+ * ListEngine should be returned.
+ */
+
virtual ListEngine* availableListEngine(QString engine);
+
+ /**
+ * Generates a unique request signature the MediaItemModel
+ * can use to uniquely identify a ListEngine load request.
+ */
QString generateRequestSignature();
+
+ /**
+ * Returns true if a ListEngine exists for the specified
+ * engine.
+ */
bool engineExists(QString engine);
private:
diff --git a/src/platform/mediaindexer.cpp b/src/platform/mediaindexer.cpp
new file mode 100644
index 0000000..c7317a9
--- /dev/null
+++ b/src/platform/mediaindexer.cpp
@@ -0,0 +1,283 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "mediaindexer.h"
+#include "mediaitemmodel.h"
+#include "utilities.h"
+#include "mediavocabulary.h"
+
+#include <KUrl>
+#include <KDebug>
+#include <KStandardDirs>
+#include <nepomuk/resource.h>
+#include <nepomuk/variant.h>
+#include <Nepomuk/ResourceManager>
+#include <QTextStream>
+#include <QProcess>
+#include <QFile>
+#include <QHash>
+
+MediaIndexer::MediaIndexer(QObject * parent) : QObject(parent)
+{
+ Nepomuk::ResourceManager::instance()->init();
+ if (Nepomuk::ResourceManager::instance()->initialized()) {
+ m_nepomukInited = true; //resource manager inited successfully
+ } else {
+ m_nepomukInited = false; //no resource manager
+ }
+ m_state = Idle;
+}
+
+MediaIndexer::~MediaIndexer()
+{
+}
+
+void MediaIndexer::updateInfo(QList<MediaItem> mediaList)
+{
+ if (m_nepomukInited && (mediaList.count() > 0)) {
+ QString filename = QString("bangarang/%1.jb")
+ .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
+ QString path = KStandardDirs::locateLocal("data", filename, true);
+ QFile file(path);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "#Count = " << mediaList.count() << "\n";
+ QList<QString> urls;
+ for (int i = 0; i < mediaList.count(); i++) {
+ writeUpdateInfo(mediaList.at(i), out);
+ out << "\n";
+ urls << mediaList.at(i).url;
+ }
+ out << "\n" <<"\n";
+ file.close();
+ KProcess * writer = new KProcess();
+ writer->setProgram("bangarangnepomukwriter", QStringList(path));
+ writer->setOutputChannelMode(KProcess::OnlyStdoutChannel);
+ connect(writer, SIGNAL(readyReadStandardOutput()), this, SLOT(processWriterOutput()));
+ connect(writer, SIGNAL(started()), this, SIGNAL(started()));
+ connect(writer, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
+ connect(writer, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ m_mediaLists.insert(m_writers.count(), mediaList);
+ m_urlLists.insert(m_writers.count(), urls);
+ m_writers.append(writer);
+ writer->start();
+ m_state = Running;
+ emit percentComplete(0);
+ }
+}
+
+void MediaIndexer::updateInfo(MediaItem mediaItem)
+{
+ QList<MediaItem> mediaList;
+ mediaList << mediaItem;
+ updateInfo(mediaList);
+}
+
+void MediaIndexer::removeInfo(QList<MediaItem> mediaList)
+{
+ if (m_nepomukInited && (mediaList.count() > 0)) {
+ QString filename = QString("bangarang/%1.jb")
+ .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
+ QString path = KStandardDirs::locateLocal("data", filename, true);
+ QFile file(path);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "#Count = " << mediaList.count() << "\n";
+ for (int i = 0; i < mediaList.count(); i++) {
+ writeRemoveInfo(mediaList.at(i), out);
+ out << "\n";
+ }
+ out << "\n" <<"\n";
+ file.close();
+ KProcess * writer = new KProcess();
+ writer->setProgram("bangarangnepomukwriter", QStringList(path));
+ writer->setWorkingDirectory(KStandardDirs::locateLocal("data", "bangarang/", true));
+ writer->setOutputChannelMode(KProcess::OnlyStdoutChannel);
+ connect(writer, SIGNAL(readyReadStandardOutput()), this, SLOT(processWriterOutput()));
+ connect(writer, SIGNAL(started()), this, SIGNAL(started()));
+ connect(writer, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
+ connect(writer, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ m_writers.append(writer);
+ writer->start();
+ m_state = Running;
+ emit percentComplete(0);
+ }
+}
+
+void MediaIndexer::removeInfo(MediaItem mediaItem)
+{
+ QList<MediaItem> mediaList;
+ mediaList << mediaItem;
+ removeInfo(mediaList);
+}
+
+void MediaIndexer::updatePlaybackInfo(QString url, bool incrementPlayCount, QDateTime playDateTime)
+{
+ if (m_nepomukInited && !url.isEmpty()) {
+ QString filename = QString("bangarang/%1.jb")
+ .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
+ QString path = KStandardDirs::locateLocal("data", filename, true);
+ QFile file(path);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "[" << url << "]\n";
+ out << "lastPlayed = " << playDateTime.toString("yyyyMMddhhmmss") << "\n";
+ if (incrementPlayCount) {
+ int playCount = 0;
+ Nepomuk::Resource res(url);
+ if (res.exists()) {
+ playCount = res.property(MediaVocabulary().playCount()).toInt();
+ }
+ playCount = playCount + 1;
+ out << "playCount = " << playCount << "\n";
+ }
+ out << "\n" << "\n";
+ KProcess * writer = new KProcess();
+ writer->setProgram("bangarangnepomukwriter", QStringList(path));
+ writer->setWorkingDirectory(KStandardDirs::locateLocal("data", "bangarang/", true));
+ writer->setOutputChannelMode(KProcess::OnlyStdoutChannel);
+ connect(writer, SIGNAL(started()), this, SIGNAL(started()));
+ connect(writer, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
+ connect(writer, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ m_writers.append(writer);
+ writer->start();
+ m_state = Running;
+ emit percentComplete(0);
+ }
+}
+
+void MediaIndexer::updateRating(QString url, int rating)
+{
+ if (m_nepomukInited && !url.isEmpty()
+ && (rating >= 0) && (rating <= 10)) {
+ QString filename = QString("bangarang/%1.jb")
+ .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));
+ QString path = KStandardDirs::locateLocal("data", filename, true);
+ QFile file(path);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "[" << url << "]\n";
+ out << "rating = " << rating << "\n";
+ out << "\n" << "\n";
+ KProcess * writer = new KProcess();
+ writer->setProgram("bangarangnepomukwriter", QStringList(path));
+ writer->setWorkingDirectory(KStandardDirs::locateLocal("data", "bangarang/", true));
+ writer->setOutputChannelMode(KProcess::OnlyStdoutChannel);
+ connect(writer, SIGNAL(started()), this, SIGNAL(started()));
+ connect(writer, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
+ connect(writer, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ m_writers.append(writer);
+ writer->start();
+ m_state = Running;
+ emit percentComplete(0);
+ }
+}
+
+void MediaIndexer::writeRemoveInfo(MediaItem mediaItem, QTextStream &out)
+{
+ out << "[" << mediaItem.url << "]\n";;
+ out << "type = " << mediaItem.type << "\n";;
+ if (mediaItem.type == "Audio") {
+ out << "audioType = " << mediaItem.fields["audioType"].toString() << "\n";
+ } else if (mediaItem.type == "Video") {
+ out << "videoType = " << mediaItem.fields["videoType"].toString() << "\n";
+ }
+ out << "removeInfo = true" << "\n";
+}
+
+void MediaIndexer::writeUpdateInfo(MediaItem mediaItem, QTextStream &out)
+{
+ out << "[" << mediaItem.url << "]\n";;
+ out << "type = " << mediaItem.type << "\n";;
+
+ QHashIterator<QString, QVariant> i(mediaItem.fields);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value().type() == QVariant::DateTime) {
+ out << i.key() << " = " << i.value().toDateTime().toString("yyyyMMddhhmmss") << "\n";
+ } else if (i.value().type() == QVariant::DateTime) {
+ out << i.key() << " = " << i.value().toDateTime().toString("yyyyMMdd") << "\n";
+ } else {
+ out << i.key() << " = " << i.value().toString() << "\n";
+ }
+ }
+}
+
+void MediaIndexer::processWriterOutput()
+{
+ for (int i = 0; i < m_writers.count(); i++) {
+ m_writers.at(i)->setReadChannel(QProcess::StandardOutput);
+ while (!m_writers.at(i)->atEnd()) {
+ if (m_writers.at(i)->canReadLine()) {
+ char buffer[1024];
+ qint64 lineLength = m_writers.at(i)->readLine(buffer, sizeof(buffer));
+ if (lineLength != -1) {
+ QString line(buffer);
+ //kDebug() << line;
+ if (line.startsWith("BangarangProgress:")) {
+ int percent = line.remove("BangarangProgress:").trimmed().toInt();
+ emit percentComplete(percent);
+ } else if (line.startsWith("BangarangSignal:sourceInfoUpdated:")) {
+ QString url = line.remove("BangarangSignal:sourceInfoUpdated:").trimmed();
+ QList<QString> urls = m_urlLists[i];
+ int index = urls.indexOf(url);
+ if (index != -1) {
+ MediaItem mediaItem = m_mediaLists[i].at(index);
+ emit sourceInfoUpdated(mediaItem);
+ }
+ } else if (line.startsWith("BangrangSignal:urlInfoRemoved:")) {
+ QString url = line.remove("BangrangSignal:urlInfoRemoved:").trimmed();
+ emit urlInfoRemoved(url);
+ }
+ }
+ }
+ }
+ }
+}
+
+void MediaIndexer::finished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ emit finished();
+ bool isAllFinished = true;
+ for (int i = 0; i < m_writers.count(); i++) {
+ if (m_writers.at(i)->state() == QProcess::Running ||
+ m_writers.at(i)->state() == QProcess::Starting) {
+ isAllFinished = false;
+ }
+ }
+
+ if (isAllFinished) {
+ m_state = Idle;
+ emit allFinished();
+ }
+ Q_UNUSED(exitCode);
+ Q_UNUSED(exitStatus);
+}
+
+void MediaIndexer::error(QProcess::ProcessError error)
+{
+ kDebug() << error;
+}
diff --git a/src/platform/mediaindexer.h b/src/platform/mediaindexer.h
new file mode 100644
index 0000000..e1f7c72
--- /dev/null
+++ b/src/platform/mediaindexer.h
@@ -0,0 +1,145 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MEDIAINDEXER_H
+#define MEDIAINDEXER_H
+
+#include <QtCore>
+#include <KProcess>
+
+class MediaItem;
+
+/**
+* MediaIndexer provides a way to asynchronous write to the nepomuk datastore.
+*/
+class MediaIndexer : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum State {Idle = 0, Running = 1};
+ /**
+ * Constructor
+ */
+ MediaIndexer(QObject *parent);
+
+ /**
+ *Destructor
+ */
+ ~MediaIndexer();
+
+ /**
+ * Update information in the Nepomuk datastore using the specified
+ * mediaList.
+ *
+ * @param mediaList List of MediaItems containing updated information.
+ */
+ void updateInfo(QList<MediaItem> mediaList);
+
+ /**
+ * Update information in the Nepomuk datastore using the specified
+ * MediaItem.
+ *
+ * @param mediaItem MediaItem containing updated information.
+ */
+ void updateInfo(MediaItem mediaItem);
+
+ /**
+ * Remove media information from the Nepomuk datastore corresponding
+ * specified medialist.
+ *
+ * @param mediaList List of MediaItems whose information should be
+ * removed from the datastore.
+ */
+ void removeInfo(QList<MediaItem> mediaList);
+
+ /**
+ * Remove media information from the Nepomuk datastore corresponding
+ * specified MediaItem.
+ *
+ * @param mediaItem MediaItem whose information should be
+ * removed from the datastore.
+ */
+ void removeInfo(MediaItem mediaItem);
+
+ /**
+ * Update the playback time and/or play count for the specified url.
+ *
+ * @param url url of media item to updateInfo
+ * @param incrementPlayCount if true, the play count will be incremented
+ * @param playDateTime DateTime of playback
+ */
+ void updatePlaybackInfo(QString url, bool incrementPlayCount, QDateTime playDateTime);
+
+ /**
+ * Update the rating of the specified url.
+ *
+ * @param url Url of MediaItem
+ * @param rating Rating: and integer between 0 and 10
+ */
+ void updateRating(QString url, int rating);
+
+ void state();
+
+ Q_SIGNALS:
+ /**
+ * Emitted when the update/removal has started
+ */
+ void started();
+
+ /**
+ * Emitted when the update/removal has finished
+ */
+ void finished();
+
+ /**
+ * Emitted when all update/removal tasks managed by this MediaIndexer
+ * is finished.
+ */
+ void allFinished();
+
+ /**
+ * Emitted when media information for the url has been removed
+ */
+ void urlInfoRemoved(QString url);
+
+ /**
+ * Emitted when media information for MediaItem has been updated
+ */
+ void sourceInfoUpdated(MediaItem mediaItem);
+
+ /**
+ * Emitted when media information has been updated/removed.
+ */
+ void percentComplete(int percent);
+
+ private:
+ bool m_nepomukInited;
+ QList<KProcess *> m_writers;
+ QHash<int, QList<MediaItem> > m_mediaLists;
+ QHash<int, QList<QString> > m_urlLists;
+ State m_state;
+ void writeRemoveInfo(MediaItem mediaItem, QTextStream &out);
+ void writeUpdateInfo(MediaItem mediaItem, QTextStream &out);
+
+ private Q_SLOTS:
+ void processWriterOutput();
+ void finished(int exitCode, QProcess::ExitStatus exitStatus);
+ void error(QProcess::ProcessError error);
+};
+#endif // MEDIAINDEXER_H
diff --git a/platform/mediaitemmodel.cpp b/src/platform/mediaitemmodel.cpp
similarity index 77%
rename from platform/mediaitemmodel.cpp
rename to src/platform/mediaitemmodel.cpp
index 436bcab..fee9114 100644
--- a/platform/mediaitemmodel.cpp
+++ b/src/platform/mediaitemmodel.cpp
@@ -25,6 +25,7 @@
#include <QDateTime>
#include <KIcon>
#include <KDebug>
+#include <KLocale>
MediaItemModel::MediaItemModel(QObject * parent) : QStandardItemModel(parent)
{
@@ -86,6 +87,9 @@ MediaListProperties MediaItemModel::mediaListProperties()
void MediaItemModel::setMediaListProperties(MediaListProperties mediaListProperties)
{
+ if (m_mediaListProperties.lri != mediaListProperties.lri) {
+ setLoadingState(false);
+ }
m_mediaListProperties = mediaListProperties;
emit propertiesChanged();
}
@@ -107,46 +111,50 @@ int MediaItemModel::rowOfUrl(QString url)
void MediaItemModel::load()
{
- if (m_mediaListCache->isInCache(m_mediaListProperties.lri) && !m_forceRefreshFromSource) {
- setLoadingState(true);
- // Load data from from the cache
- ListEngine * listEngine = m_listEngineFactory->availableListEngine("cache://");
- MediaListProperties cacheListProperties;
- cacheListProperties.lri = QString("cache://dummyarg?%1").arg(m_mediaListProperties.lri);
- m_requestSignature = m_listEngineFactory->generateRequestSignature();
- listEngine->setRequestSignature(m_requestSignature);
- listEngine->setMediaListProperties(cacheListProperties);
- listEngine->start();
- kDebug() << "loading from cache for " << m_mediaListProperties.lri;
- } else {
- if (m_listEngineFactory->engineExists(m_mediaListProperties.engine())) {
+ if (!m_mediaListProperties.lri.isEmpty()) {
+ if (m_mediaListCache->isInCache(m_mediaListProperties.lri) && !m_forceRefreshFromSource) {
setLoadingState(true);
- if (m_lrisLoading.indexOf(m_mediaListProperties.lri) == -1) {
- // Since this lri is not currently being loaded by any list engine
- // go ahead and start a new load
- ListEngine * listEngine = m_listEngineFactory->availableListEngine(m_mediaListProperties.engine());
- m_requestSignature = m_listEngineFactory->generateRequestSignature();
- listEngine->setRequestSignature(m_requestSignature);
- listEngine->setMediaListProperties(m_mediaListProperties);
- m_lriStartTimes.insert(m_mediaListProperties.lri, QTime::currentTime());
- m_lrisLoading.append(m_mediaListProperties.lri);
- listEngine->start();
- kDebug() << "started new load for " << m_mediaListProperties.lri;
+ // Load data from from the cache
+ ListEngine * listEngine = m_listEngineFactory->availableListEngine("cache://");
+ MediaListProperties cacheListProperties;
+ cacheListProperties.lri = QString("cache://dummyarg?%1").arg(m_mediaListProperties.lri);
+ m_requestSignature = m_listEngineFactory->generateRequestSignature();
+ listEngine->setRequestSignature(m_requestSignature);
+ listEngine->setMediaListProperties(cacheListProperties);
+ listEngine->start();
+ kDebug() << "loading from cache for " << m_mediaListProperties.lri;
+ } else {
+ if (m_listEngineFactory->engineExists(m_mediaListProperties.engine())) {
+ setLoadingState(true);
+ if (m_lrisLoading.indexOf(m_mediaListProperties.lri) == -1) {
+ // Since this lri is not currently being loaded by any list engine
+ // go ahead and start a new load
+ ListEngine * listEngine = m_listEngineFactory->availableListEngine(m_mediaListProperties.engine());
+ m_requestSignature = m_listEngineFactory->generateRequestSignature();
+ listEngine->setRequestSignature(m_requestSignature);
+ listEngine->setMediaListProperties(m_mediaListProperties);
+ m_lriStartTimes.insert(m_mediaListProperties.lri, QTime::currentTime());
+ m_lrisLoading.append(m_mediaListProperties.lri);
+ listEngine->start();
+ kDebug() << "started new load for " << m_mediaListProperties.lri;
+ } else {
+ kDebug() << "waiting for " << m_mediaListProperties.lri;
+ }
} else {
- kDebug() << "waiting for " << m_mediaListProperties.lri;
+ showNoResultsMessage();
}
- } else {
- showNoResultsMessage();
+ m_forceRefreshFromSource = false;
}
- m_forceRefreshFromSource = false;
}
}
void MediaItemModel::reload()
{
- clearMediaListData();
- m_forceRefreshFromSource = true;
- load();
+ if (!m_mediaListProperties.lri.isEmpty()) {
+ clearMediaListData();
+ m_forceRefreshFromSource = true;
+ load();
+ }
}
void MediaItemModel::loadMediaList(QList<MediaItem> mediaList, bool emitMediaListChanged)
@@ -173,6 +181,7 @@ void MediaItemModel::categoryActivated(QModelIndex index)
{
MediaListProperties mediaListProperties;
mediaListProperties.lri = itemFromIndex(index)->data(MediaItem::UrlRole).toString();
+ mediaListProperties.name = m_mediaList.at(index.row()).title;
m_mediaListProperties = mediaListProperties;
if (m_mediaListCache->isInCache(m_mediaListProperties.lri)) {
@@ -240,19 +249,37 @@ void MediaItemModel::loadSources(QList<MediaItem> mediaList)
loadMediaItem(mediaList.at(i));
}
} else if (mediaList.at(i).type == "Category") {
- //Generate signatures and media list holders for each subrequest
- //This must be complete for all categories before launching subrequests
- //to ensure full order of subrequests are available when results are returned
onlySources = false;
- MediaListProperties mediaListProperties;
- mediaListProperties.lri = mediaList.at(i).url;
- mediaListProperties.name = mediaList.at(i).title;
- if (m_listEngineFactory->engineExists(mediaListProperties.engine())) {
- QString subRequestSignature = m_listEngineFactory->generateRequestSignature();
- m_subRequestSignatures.append(subRequestSignature);
- QList<MediaItem> emptyList;
- m_subRequestMediaLists.append(emptyList);
+ if (mediaList.count() == 1) {
+ MediaListProperties mediaListProperties;
+ mediaListProperties.lri = mediaList.at(i).url;
+ mediaListProperties.name = mediaList.at(i).title;
+
+ // - Get the lri for loading sources using this category item
+ ListEngine * listEngine = m_listEngineFactory->availableListEngine(m_mediaListProperties.engine());
+ listEngine->setMediaListProperties(m_mediaListProperties);
+ listEngine->setFilterForSources(m_mediaListProperties.engineFilter());
+ QString loadSourcesLri = listEngine->mediaListProperties().lri;
+ mediaListProperties.lri = loadSourcesLri;
+
+ //Just directly load the sources since it's one category
+ m_mediaListProperties = mediaListProperties;
+ } else {
+ //Generate signatures and media list holders for each subrequest
+ //This must be complete for all categories before launching subrequests
+ //to ensure full order of subrequests are available when results are returned
+ MediaListProperties mediaListProperties;
+ mediaListProperties.lri = mediaList.at(i).url;
+ mediaListProperties.name = mediaList.at(i).title;
+ if (m_listEngineFactory->engineExists(mediaListProperties.engine())) {
+ QString subRequestSignature = m_listEngineFactory->generateRequestSignature();
+ m_subRequestSignatures.append(subRequestSignature);
+ QList<MediaItem> emptyList;
+ m_subRequestMediaLists.append(emptyList);
+ }
}
+ } else {
+ setLoadingState(false);
}
}
if (onlySources) {
@@ -261,32 +288,43 @@ void MediaItemModel::loadSources(QList<MediaItem> mediaList)
}
emit mediaListChanged();
} else {
- //Launch subrequests
+ //Launch load requests
for (int i = 0; i < mediaList.count(); ++i) {
MediaListProperties mediaListProperties;
mediaListProperties.lri = mediaList.at(i).url;
- if (m_mediaListCache->isInCache(mediaListProperties.lri)) {
- // Load data from from the cache
- ListEngine * listEngine = m_listEngineFactory->availableListEngine("cache://");
- MediaListProperties cacheListProperties;
- cacheListProperties.lri = QString("cache://dummyarg?%1").arg(mediaListProperties.lri);
- m_requestSignature = m_listEngineFactory->generateRequestSignature();
- listEngine->setRequestSignature(m_requestSignature);
- listEngine->setMediaListProperties(cacheListProperties);
- listEngine->start();
- } else {
- if (m_listEngineFactory->engineExists(mediaListProperties.engine())) {
- if (m_lrisLoading.indexOf(mediaListProperties.lri) == -1) {
+ mediaListProperties.name = mediaList.at(i).title;
+ if (m_listEngineFactory->engineExists(mediaListProperties.engine())) {
+
+ ListEngine * listEngine = m_listEngineFactory->availableListEngine(mediaListProperties.engine());
+ listEngine->setMediaListProperties(mediaListProperties);
+ listEngine->setFilterForSources(mediaListProperties.engineFilter());
+ QString loadSourcesLri = listEngine->mediaListProperties().lri;
+
+ if (m_mediaListCache->isInCache(loadSourcesLri)) {
+ // Load data from from the cache
+ listEngine = m_listEngineFactory->availableListEngine("cache://");
+ MediaListProperties cacheListProperties;
+ cacheListProperties.lri = QString("cache://dummyarg?%1").arg(loadSourcesLri);
+ m_requestSignature = m_listEngineFactory->generateRequestSignature();
+ listEngine->setRequestSignature(m_requestSignature);
+ if (mediaList.count() > 1) {
+ listEngine->setSubRequestSignature(m_subRequestSignatures.at(i));
+ }
+ listEngine->setMediaListProperties(cacheListProperties);
+ listEngine->start();
+
+ } else {
+ if (m_lrisLoading.indexOf(loadSourcesLri) == -1) {
// Since this lri is not currently being loaded by any list engine
// go ahead and start a new load
- ListEngine * listEngine = m_listEngineFactory->availableListEngine(mediaListProperties.engine());
listEngine->setRequestSignature(m_requestSignature);
- listEngine->setSubRequestSignature(m_subRequestSignatures.at(i));
- listEngine->setFilterForSources(mediaListProperties.engineFilter());
- m_lriStartTimes.insert(mediaListProperties.lri, QTime::currentTime());
- m_lrisLoading.append(m_mediaListProperties.lri);
+ if (mediaList.count() > 1) {
+ listEngine->setSubRequestSignature(m_subRequestSignatures.at(i));
+ }
+ m_lriStartTimes.insert(loadSourcesLri, QTime::currentTime());
+ m_lrisLoading.append(loadSourcesLri);
listEngine->start();
- kDebug()<< "started load for " << mediaListProperties.lri;
+ kDebug()<< "started load for " << loadSourcesLri;
} else {
kDebug()<< "waiting for " << mediaListProperties.lri;
}
@@ -308,7 +346,6 @@ void MediaItemModel::addResults(QString requestSignature, QList<MediaItem> media
// if (requestSignature == m_requestSignature) {
kDebug() << "results returned for " << mediaListProperties.lri;
if ((mediaListProperties.lri == m_mediaListProperties.lri) || (requestSignature == m_requestSignature)) {
-
if (m_subRequestSignatures.count() == 0) {
setLoadingState(false);
loadMediaList(mediaList);
@@ -331,15 +368,20 @@ void MediaItemModel::addResults(QString requestSignature, QList<MediaItem> media
if (m_subRequestsDone == m_subRequestSignatures.count()) {
setLoadingState(false);
//All the subrequests results are in, go ahead and load results in correct order
+ int count = 0;
for (int i = 0; i < m_subRequestMediaLists.count(); ++i) {
loadMediaList(m_subRequestMediaLists.at(i));
+ count += m_subRequestMediaLists.at(i).count();
}
- m_subRequestMediaLists.clear();
- m_subRequestSignatures.clear();
- m_subRequestsDone = 0;
if (rowCount() == 0) {
showNoResultsMessage();
}
+ m_mediaListProperties.lri = QString();
+ m_mediaListProperties.name = i18n("Multiple %1", m_mediaListProperties.name);
+ m_mediaListProperties.summary = i18np("1 item", "%1 items", count);
+ m_subRequestMediaLists.clear();
+ m_subRequestSignatures.clear();
+ m_subRequestsDone = 0;
emit mediaListChanged();
}
}
@@ -377,11 +419,10 @@ void MediaItemModel::removeMediaItem(QString url)
{
int row = rowOfUrl(url);
if (row != -1) {
- disconnect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
- m_urlList.removeAt(row);
- m_mediaList.removeAt(row);
removeMediaItemAt(row, true);
- connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
+ if (rowCount() == 0) {
+ showNoResultsMessage();
+ }
}
}
@@ -398,7 +439,12 @@ void MediaItemModel::clearMediaListData(bool emitMediaListChanged)
void MediaItemModel::removeMediaItemAt(int row, bool emitMediaListChanged)
{
if (row < rowCount()) {
+ disconnect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
removeRows(row, 1);
+ m_urlList.removeAt(row);
+ m_mediaList.removeAt(row);
+ connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
+
}
if (emitMediaListChanged) {
emit mediaListChanged();
@@ -452,8 +498,9 @@ void MediaItemModel::showLoadingMessage()
}
QString iconName = QString("bangarang-loading-%1").arg(m_loadingProgress);
loadingMessage.artwork = KIcon(iconName);
- loadingMessage.title = "Loading...";
+ loadingMessage.title = i18n("Loading...");
loadingMessage.type = "Message";
+ loadingMessage.fields["messageType"] = "Loading";
if (rowCount() == 0) {
loadMediaItem(loadingMessage, false);
} else {
@@ -467,18 +514,14 @@ void MediaItemModel::hideLoadingMessage()
{
int row = -1;
for (int i = 0; i < m_mediaList.count(); ++i) {
- if ((m_mediaList.at(i).title == "Loading...") && (m_mediaList.at(i).type == "Message")) {
+ if ((m_mediaList.at(i).fields["messageType"].toString() == "Loading") && (m_mediaList.at(i).type == "Message")) {
row = i;
break;
}
}
if (row != -1) {
if (m_mediaList.count() > 0) {
- disconnect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
removeMediaItemAt(row, false);
- m_urlList.removeAt(row);
- m_mediaList.removeAt(row);
- connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(synchRemoveRows(const QModelIndex &, int, int)));
}
}
}
@@ -486,8 +529,9 @@ void MediaItemModel::hideLoadingMessage()
void MediaItemModel::showNoResultsMessage()
{
MediaItem loadingMessage;
- loadingMessage.title = "No results";
+ loadingMessage.title = i18n("No results");
loadingMessage.type = "Message";
+ loadingMessage.fields["messageType"] = "No Results";
loadMediaItem(loadingMessage, false);
}
@@ -516,7 +560,7 @@ QList<QStandardItem *> MediaItemModel::rowDataFromMediaItem(MediaItem mediaItem)
QStandardItem * markPlaylistItem = new QStandardItem(KIcon(), QString());
markPlaylistItem->setData(mediaItem.url, MediaItem::UrlRole);
markPlaylistItem->setData(mediaItem.type, MediaItem::TypeRole);
- markPlaylistItem->setData("Add to playlist/Remove from playlist", Qt::ToolTipRole);
+ markPlaylistItem->setData(i18n("Add to playlist/Remove from playlist"), Qt::ToolTipRole);
rowData << markPlaylistItem;
} else if (mediaItem.type == "Category") {
KIcon categoryActionIcon;
diff --git a/src/platform/mediaitemmodel.h b/src/platform/mediaitemmodel.h
new file mode 100644
index 0000000..43ea03b
--- /dev/null
+++ b/src/platform/mediaitemmodel.h
@@ -0,0 +1,582 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MEDIAITEMMODEL_H
+#define MEDIAITEMMODEL_H
+
+/** @file
+ * This file contains the definition of the MediaItem, MediaListProperties
+ * and MediaItemModel.
+ *
+ * @author Andrew Lake
+ */
+
+#include <QStandardItemModel>
+#include <QObject>
+#include <QPixmap>
+#include <QList>
+
+class MusicListEngine;
+class FileListEngine;
+class ListEngineFactory;
+class MediaListCache;
+
+
+/**
+ * MediaItem is a simple object that can represent any playable
+ * item of media (audio clip, music, video clip, movie, etc.).
+ * MediaItem can also refer to a collection of MediaItems (Artist,
+ * Album, Genre, Movies, TV series, etc.) or an action or a
+ * message.
+ * Multiple MediaItems, a media list, are generally handled with
+ * QList< MediaItem >.
+ */
+
+struct MediaItem {
+
+ enum MediaItemRole { UrlRole = Qt::UserRole + 1, /** QStandardItem role containing MediaItem url.*/
+
+ SubTitleRole = Qt::UserRole + 2, /** QStandardItem role containing MediaItem sub title.*/
+
+ DurationRole = Qt::UserRole + 3, /** QStandardItem role containing MediaItem duration.*/
+
+ RatingRole = Qt::UserRole + 4, /** QStandardItem role containing MediaItem rating.*/
+
+ TypeRole = Qt::UserRole + 5, /** QStandardItem role containing MediaItem type.*/
+
+ FilterRole = Qt::UserRole + 6, /** QStandardItem role containing MediaItem filter.*/
+
+ PlaylistIndexRole = Qt::UserRole + 7, /** QStandardItem role containing Playlist
+ *index of MediaItem.*/
+
+ NowPlayingRole = Qt::UserRole + 8,
+
+ IsSavedListRole = Qt::UserRole + 9, /** QStandardItem role containing whether
+ *or not the media list represented by the
+ *MediaItem is a saved list.*/
+
+ ExistsRole = Qt::UserRole + 10 }; /** QStandardItem role containing whether or
+ *the file the MediaItem.url refers to exists.*/
+
+ QString url; /** Url of MediaItem. The may be a standard url representing a
+ * location of a media resource or a List Resource Identifier (lri).*/
+
+ QIcon artwork; /** Icon containing artwork representing MediaItem.*/
+
+ QString title; /** Title of the Media Item. */
+
+ QString subTitle; /** Subtitle of the Media Item. */
+
+ QString duration; /** Displayed representation of duration of the Media Item. */
+
+ QString type; /** Type of the Media Item.
+ * "Audio" - MediaItem is a playable audio resource.
+ * "Video" - MediaItem is a playable video resource.
+ * "Category" - MediaItem is a category which refers to other
+ * MediaItems. The url for this type of MediaItem
+ * is an lri that a MediaItemModel can use to
+ * load a list of MediaItems
+ * "Action" - MediaItem is an action. A MediaItemModel can use this
+ * to load a list of MediaItems by means other than
+ * an just an lri. e.g. Open a dialog, etc.
+ * "Message" - MediaItem is a message. A MediaItemModel can use this
+ * to display messages in associated views.
+ * e.g. "Loading...", "No results", etc.
+ * */
+
+ QString filter;
+
+ int playlistIndex; /** Row of Playlist::playListModel() that contains this MediaItem.*/
+
+ bool nowPlaying;
+
+ bool isSavedList; /** If the MediaItem.url is an lri, this bool is true if the lri
+ * refers to a saved media list, otherwise is false.*/
+
+ bool exists; /** If the MediaItem.url point to a playable media resource, this
+ * bool is true if the playable media resource exists, otherwise is false.
+ * Note that this is only useful for file resources.*/
+
+ QHash <QString, QVariant> fields; /** Collection of all key, value pairs containing
+ * the metadata fields associated with this MediaItem.
+ * key - A string containing the field name.
+ * value - A variant conatining the value of the field.*/
+
+ MediaItem() : nowPlaying(false), isSavedList(false), exists(true) {}
+};
+
+Q_DECLARE_METATYPE(MediaItem);
+
+
+/**
+ * MediaListProperties contains the properties associated with a list of
+ * MediaItems.
+ */
+
+class MediaListProperties {
+
+public:
+ QString name; /** Name of media list */
+
+ QString summary; /** Summary text describing the number of items in the media list */
+
+ QString lri; /** List Resource Identifier associated with media list. This string
+ * is the essentially how the media list is retrieved. */
+
+ /**
+ * Returns the engine portion of the lri string.
+ */
+ QString engine() {
+ if (lri.indexOf("://") != -1) {
+ return lri.left(lri.indexOf("://") + 3);
+ } else {
+ return QString();
+ }
+ }
+
+ /**
+ * Returns the engine argument portion of the lri string.
+ */
+ QString engineArg() {
+ int endOfArg = (lri.indexOf("?") != -1) ? lri.indexOf("?") - 1: lri.size() - 1;
+ if ((lri.indexOf("://") != -1) && (lri.indexOf("://") != lri.size() - 3)) {
+ //return lri.mid(lri.indexOf("://") + 3, lri.size() - endOfArg + 1);
+ return lri.mid(lri.indexOf("://") + 3, endOfArg - (lri.indexOf("://") + 2));
+ } else {
+ return QString();
+ }
+ }
+
+ /**
+ * Returns the engine filter portion of the lri string.
+ */
+ QString engineFilter() {
+ if ((lri.indexOf("://") != -1) && (lri.indexOf("?") != -1) && (lri.indexOf("?") != lri.size() - 1)){
+ return lri.right(lri.size() - (lri.indexOf("?") + 1));
+ } else {
+ return QString();
+ }
+ }
+
+ QString type; /** The type of media list.
+ * "Categories" - a list of MediaItems that are categories.
+ * "Sources" - a list of MediaItems that are playable media
+ * resources (files, streams, etc.). */
+
+};
+
+class MediaList : QList<MediaItem>{};
+
+
+/**
+ * MediaItemModel contains information for a list of MediaItems
+ * repesented in the form of a model.
+ * It provides facilities for loading a list of MediaItems from a
+ * variety of sources as well as adding, updating or removing
+ * information associated with any MediaItem it contains.
+ * A subclass of QStandardItemModel, MediaItemModel may be used
+ * with a view to visually respresent the information it contains.
+ */
+
+class MediaItemModel : public QStandardItemModel
+{
+ Q_OBJECT
+ public:
+ /**
+ * Default constructor.
+ */
+ MediaItemModel(QObject * parent);
+
+ /**
+ * Default destructor
+ */
+ ~MediaItemModel();
+
+ /**
+ * Clears all information contained in the model.
+ * This includes MediaListProperties which a call to removeRows()
+ * will not clear.
+ *
+ * @param emitMediaListChanged set true to emit the mediaListChanged()
+ * signal after clearing data. Default is
+ * false.
+ */
+ void clearMediaListData(bool emitMediaListChanged = false);
+
+ /**
+ * Returns the threshold, in milliseconds, used to cache data loaded by
+ * by the model.
+ *
+ */
+ int cacheThreshold();
+
+ /**
+ * Handler for data that is dropped onto a view associated with the
+ * mdel.
+ */
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+ /**
+ * Flags for items dragged from a view associated with the model.
+ */
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ /**
+ * Loads list of MediaItems as specified by the MediaListProperties.lri
+ *
+ * Note: Loading is asynchronous. Use mediaListChanged() signal to detect
+ * when loading is complete.
+ */
+ void load();
+
+ /**
+ * Loads a list of MediaItems directly into the model
+ *
+ * @param mediaList list of MediaItems to load
+ *
+ * Note: After using this method, MediaListProperties returned by
+ * mediaListProperties() is likely stale.
+ * MediaListProperties.lri should either be updated to correspond
+ * to mediaList or set to QString().
+ */
+ void loadMediaList(QList<MediaItem> mediaList, bool emitMediaListChanged = false);
+
+ /**
+ * Loads a MediaItem directly into the model
+ *
+ * @param mediaItem MediaItem to load
+ *
+ * Note: After using this method, MediaListProperties returned by
+ * mediaListProperties() is likely stale.
+ * MediaListProperties.lri should either be updated to correspond
+ * to mediaList or set to QString().
+ */
+ void loadMediaItem(MediaItem mediaItem, bool emitMediaListChanged = false);
+
+ /**
+ * Loads playable MediaItems into the model.
+ *
+ * @param mediaList mediaList containing MediaItems to load.
+ * If mediaList contains "Category" type MediaItems
+ * then the playable MediaItems associated with that
+ * category (as specified by the lri in MediaItem.url)
+ * will be loaded.
+ * If the mediaList contains playable MediaItems
+ * (type = "Audio" or "Video") then they will be directly
+ * loaded into the model.
+ */
+ void loadSources(QList<MediaItem> mediaList);
+
+ /**
+ * Returns the MediaItem associated with the specified row in the model.
+ */
+ MediaItem mediaItemAt(int row);
+
+ /**
+ * Returns the list of MediaItems contained in the model.
+ */
+ QList<MediaItem> mediaList();
+
+ /**
+ * Returns a pointer to the MediaListCache used by the model.
+ * This is useful for sharing a common cache between different
+ * models.
+ */
+ MediaListCache * mediaListCache();
+
+ /**
+ * Returns the MediaListProperties associated with the media list
+ * contained in the model
+ */
+ MediaListProperties mediaListProperties();
+
+ /**
+ * Returns the QMimeData associated with a list of model indexes
+ */
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+
+ /**
+ * Returns a list of mimetypes associated with items in the model
+ */
+ QStringList mimeTypes() const;
+
+ /**
+ * Remove MediaItem at the specified row of the model
+ *
+ * @param row row of model
+ * @param emitMediaListChanged emits mediaListChanged() signal if true,
+ * otherwise don't emit mediaListChanged().
+ */
+ void removeMediaItemAt(int row, bool emitMediaListChanged = false);
+
+ /**
+ * Remove information associated with MediaItems in mediaList from
+ * the source from which the model retrieved the MediaItems.
+ *
+ * @param mediaList list containing the MediaItems whose information
+ * should be removed from the source.
+ *
+ * Note: mediaList does not have to contain the same MediaItems contained
+ * in the model. However, the current model MediaListProperties
+ * should refer to an lri whose ListEngine is capable of removing
+ * information from the source. As a general rule, if the lri
+ * can be used to retrieve the MediaItem, its ListEngine can
+ * remove information for the MediaItem.
+ */
+ void removeSourceInfo(QList<MediaItem> mediaList);
+
+ /**
+ * Replace MediaItem at the specified row in the model with the one
+ * provided.
+ *
+ * @param row row of model
+ * @param mediaItem MediaItem to replace with
+ * @param emitMediaListChanged emits mediaListChanged() signal if true,
+ * otherwise don't emit mediaListChanged().
+ *
+ */
+ void replaceMediaItemAt(int row, MediaItem mediaItem, bool emitMediaListChanged = false);
+
+ /**
+ * Return the row of a MediaItem whose url matches the one provided
+ *
+ * @param url url to match
+ *
+ * @return row of model
+ */
+ int rowOfUrl(QString url);
+
+ /**
+ * Sets the threshold for the cache.
+ *
+ * @param msec cache threshold in milliseconds.
+ * If any load the model performs takes longer
+ * than this threshold it will be stored in the
+ * cache.
+ */
+ void setCacheThreshold(int msec);
+
+ /**
+ * Sets the MediaListProperties for the model
+ *
+ * @param mediaListProperties MediaListProperties to be used by the
+ * model. A subsequent load() call will
+ * use the MediaListProperties.lri.
+ */
+ void setMediaListProperties(MediaListProperties mediaListProperties);
+
+ /**
+ * Sets the cache for the model to use.
+ * This is useful for sharing a common cache between different
+ * models.
+ *
+ * @param mediaListCache pointer to MediaListCache for the
+ * model to use.
+ */
+ void setMediaListCache(MediaListCache * mediaListCache);
+
+ /**
+ * Sets the ListEngineFactory for the model to use.
+ * This is mostly useful if using a custom ListEngineFactory.
+ *
+ * @param listEngineFactory ListEngineFactory for the model to use
+ */
+ void setListEngineFactory(ListEngineFactory * listEngineFactory);
+
+ /**
+ * Returns the DropActions supported by the model
+ */
+ Qt::DropActions supportedDropActions() const;
+
+ /**
+ * Update information associated with MediaItems in mediaList in the
+ * the source from which the model retrieved the MediaItems.
+ *
+ * @param mediaList list containing the MediaItems whose information
+ * should be update in the source.
+ *
+ * Note: mediaList does not have to contain the same MediaItems contained
+ * in the model. However, the current model MediaListProperties
+ * should refer to an lri whose ListEngine is capable of updating
+ * information in the source. As a general rule, if the lri
+ * can be used to retrieve the MediaItem, its ListEngine can
+ * update information for the MediaItem.
+ */
+ void updateSourceInfo(QList<MediaItem> mediaList);
+
+ QString dataEngine();
+ QString filter();
+
+ Q_SIGNALS:
+ /**
+ * Emitted when the model's MediaListProperties have changed.
+ */
+ void propertiesChanged();
+
+ /**
+ * Emitted when the list of MediaItems in the model have changed.
+ * This signal may be suppressed when using certain methods.
+ */
+ void mediaListChanged();
+
+ /**
+ * Emitted when the model is loading a list of MediaItems.
+ */
+ void loading();
+
+ /**
+ * Emmited when the source information for a MediaItem is updated.
+ *
+ * @param mediaItem MediaItem whose information was updated in
+ * the source.
+ */
+ void sourceInfoUpdated(MediaItem mediaItem);
+
+ /**
+ * Emitted when the source information for a MediaItem is updated
+ *
+ * @param percent percentage of MediaItems updated (from the
+ * list of MediaItems being updated).
+ */
+ void sourceInfoUpdateProgress(int percent);
+
+ /**
+ * Emmited when the source information for MediaItem is removed.
+ *
+ * @param url url of MediaItem remove from the source
+ */
+ void sourceInfoRemoved(QString url);
+
+ /**
+ * Emitted when the source information for a MediaItem is removed
+ *
+ * @param percent percentage of MediaItems removed (of the
+ * list of MediaItems being removed).
+ */
+ void sourceInfoRemovalProgress(int percent);
+
+ /**
+ * Emitted when the update or removal of the list MediaItems is complete.
+ */
+ void sourceInfoUpdateRemovalComplete();
+
+ /**
+ * Emitted when the update or removal of the list MediaItems has started.
+ */
+ void sourceInfoUpdateRemovalStarted();
+
+ public Q_SLOTS:
+ /**
+ * Activate the action associated with "Action" mediaItem
+ * at the specified model index.
+ *
+ * @param index QModelIndex of action.
+ * (This slot is useful for View ItemDelegates to tell the
+ * model to activate the action when clicked. e.g. Open File.)
+ */
+ void actionActivated(QModelIndex index);
+
+ /**
+ * Loads the list of MediaItems associated with "Category" mediaItem
+ * at the specified model index.
+ *
+ * @param index QModelIndex of category. The url of the "Category" type
+ * MediaItem associated with the row of this index contains
+ * the lri representing the list of MediaItems to load.
+ * (This slot is useful for View ItemDelegates to tell the
+ * model to load the category when clicked.)
+ */
+ void categoryActivated(QModelIndex index);
+
+ /**
+ * Reloads the information in the current model.
+ */
+ void reload();
+
+ /**
+ * Update MediaItem contained in the model to the MediaItem specified
+ * Only MediaItems in the model whose url matches the url of the
+ * specifed MediaItem will be updated.
+ *
+ * @param mediaItem MediaItem with updated information.
+ *
+ * Note: This method only updates the information in the model. It
+ * does not update the source from which the MediaItems were
+ * retrieved. Use updateSourceInfo() method to do that.
+ */
+ void updateMediaItem(MediaItem mediaItem);
+
+ /**
+ * Update MediaItems contained in the model to those in the specified
+ * list of MediaItems. Only MediaItems in the model whose url matches
+ * those in the list of MediaItems will be updated.
+ *
+ * @param mediaList List of MediaItems with updated information.
+ *
+ * Note: This method only updates the information in the model. It
+ * does not update the source from which the MediaItems were
+ * retrieved. Use updateSourceInfo() method to do that.
+ */
+ void updateMediaItems(QList<MediaItem> mediaList);
+
+ /**
+ * Remove MediaItem in model that matches the url specified.
+ *
+ * @param url url of MediaItem to remove.
+ *
+ * Note: This method only removes the information in the model. It
+ * does not remove information in the source from which the
+ * MediaItems were retrieved. Use removeSourceInfo() method
+ * to do that.
+ */
+ void removeMediaItem(QString url);
+
+ void addResults(QString requestSignature, QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done, QString subRequestSignature);
+
+ private Q_SLOTS:
+ void synchRemoveRows(const QModelIndex &index, int start, int end);
+ void showLoadingMessage();
+
+ private:
+ void hideLoadingMessage();
+ void showNoResultsMessage();
+ QList<QStandardItem *> rowDataFromMediaItem(MediaItem mediaItem);
+ QObject * m_parent;
+ QString m_dataEngine;
+ QString m_filter;
+ MediaListProperties m_mediaListProperties;
+ ListEngineFactory * m_listEngineFactory;
+ QString m_requestSignature;
+ QStringList m_subRequestSignatures;
+ QList< QList<MediaItem> > m_subRequestMediaLists;
+ int m_subRequestsDone;
+ QStringList m_urlList;
+ QList<MediaItem> m_mediaList;
+ bool m_emitChangedAfterDrop;
+ int m_loadingProgress;
+ bool m_loadingState;
+ void setLoadingState(bool state);
+ int m_cacheThreshold;
+ MediaListCache * m_mediaListCache;
+ bool m_forceRefreshFromSource;
+ QHash<QString, QTime> m_lriStartTimes;
+ QList<QString> m_lrisLoading;
+
+};
+
+#endif // MEDIAITEMMODEL_H
diff --git a/platform/medialistcache.cpp b/src/platform/medialistcache.cpp
similarity index 100%
rename from platform/medialistcache.cpp
rename to src/platform/medialistcache.cpp
diff --git a/platform/medialistcache.h b/src/platform/medialistcache.h
similarity index 88%
rename from platform/medialistcache.h
rename to src/platform/medialistcache.h
index 739717f..349cf54 100644
--- a/platform/medialistcache.h
+++ b/src/platform/medialistcache.h
@@ -22,6 +22,11 @@
#include "mediaitemmodel.h"
#include <QObject>
+/**
+* This class caches lists of MediaItems.
+* Media lists are stored with their associated MediaListProperties
+* and are retrieved from the cache using the lri.
+*/
class MediaListCache : public QObject
{
Q_OBJECT
diff --git a/platform/medialistsengine.cpp b/src/platform/medialistsengine.cpp
similarity index 88%
rename from platform/medialistsengine.cpp
rename to src/platform/medialistsengine.cpp
index 9e83c09..61062b7 100644
--- a/platform/medialistsengine.cpp
+++ b/src/platform/medialistsengine.cpp
@@ -25,6 +25,7 @@
#include <QApplication>
#include <KIcon>
+#include <KLocale>
#include <KMimeType>
#include <KStandardDirs>
#include <QFile>
@@ -48,47 +49,35 @@ void MediaListsEngine::run()
MediaItem mediaItem;
mediaItem.type = "Category";
mediaItem.isSavedList = false;
- mediaItem.title = "Files and Folders";
+ mediaItem.title = i18n("Files and Folders");
mediaItem.url = "files://audio";
mediaItem.artwork = KIcon("document-open-folder");
mediaList << mediaItem;
if (m_nepomukInited) {
- mediaItem.title = "Artists";
+ mediaItem.title = i18n("Artists");
mediaItem.url = "music://artists";
mediaItem.artwork = KIcon("system-users");
mediaList << mediaItem;
- mediaItem.title = "Albums";
+ mediaItem.title = i18n("Albums");
mediaItem.url = "music://albums";
mediaItem.artwork = KIcon("media-optical");
mediaList << mediaItem;
- mediaItem.title = "Songs";
+ mediaItem.title = i18n("Songs");
mediaItem.url = "music://songs";
mediaItem.artwork = KIcon("audio-mpeg");
mediaList << mediaItem;
- mediaItem.title = "Genres";
+ mediaItem.title = i18n("Genres");
mediaItem.url = "music://genres";
mediaItem.artwork = KIcon("flag-blue");
mediaList << mediaItem;
- mediaItem.title = "Clips";
+ mediaItem.title = i18n("Clips");
mediaItem.url = "audioclips://";
mediaItem.artwork = KIcon("audio-x-wav");
mediaList << mediaItem;
- mediaItem.title = "Audio Streams";
+ mediaItem.title = i18n("Audio Streams");
mediaItem.url = "audiostreams://";
mediaItem.artwork = KIcon("x-media-podcast");
mediaList << mediaItem;
- mediaItem.title = "Frequently Played";
- mediaItem.url = "semantics://frequent?audio";
- mediaItem.artwork = KIcon("office-chart-bar");
- mediaList << mediaItem;
- mediaItem.title = "Recently Played";
- mediaItem.url = "semantics://recent?audio";
- mediaItem.artwork = KIcon("chronometer");
- mediaList << mediaItem;
- mediaItem.title = "Highest Rated";
- mediaItem.url = "semantics://highest?audio";
- mediaItem.artwork = KIcon("rating");
- mediaList << mediaItem;
}
//Show Audio CD if present
@@ -101,12 +90,27 @@ void MediaListsEngine::run()
}
}
if (audioCDFound) {
- mediaItem.title = "Audio CD";
+ mediaItem.title = i18n("Audio CD");
mediaItem.url = "cdaudio://";
mediaItem.artwork = KIcon("media-optical-audio");
mediaList << mediaItem;
}
+ if (m_nepomukInited) {
+ mediaItem.title = i18n("Frequently Played");
+ mediaItem.url = "semantics://frequent?audio";
+ mediaItem.artwork = KIcon("office-chart-bar");
+ mediaList << mediaItem;
+ mediaItem.title = i18n("Recently Played");
+ mediaItem.url = "semantics://recent?audio";
+ mediaItem.artwork = KIcon("chronometer");
+ mediaList << mediaItem;
+ mediaItem.title = i18n("Highest Rated");
+ mediaItem.url = "semantics://highest?audio";
+ mediaItem.artwork = KIcon("rating");
+ mediaList << mediaItem;
+ }
+
//Load saved lists from index
QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
if (indexFile.exists()) {
@@ -143,39 +147,27 @@ void MediaListsEngine::run()
MediaItem mediaItem;
mediaItem.type = "Category";
mediaItem.isSavedList = false;
- mediaItem.title = "Files and Folders";
+ mediaItem.title = i18n("Files and Folders");
mediaItem.url = "files://video";
mediaItem.artwork = KIcon("document-open-folder");
mediaList << mediaItem;
if (m_nepomukInited) {
- mediaItem.title = "Movies";
+ mediaItem.title = i18n("Movies");
mediaItem.url = "video://movies";
mediaItem.artwork = KIcon("tool-animator");
mediaList << mediaItem;
- mediaItem.title = "Genres";
+ mediaItem.title = i18n("Genres");
mediaItem.url = "video://genres";
mediaItem.artwork = KIcon("flag-green");
mediaList << mediaItem;
- mediaItem.title = "TV Shows";
+ mediaItem.title = i18n("TV Shows");
mediaItem.url = "video://tvshows";
mediaItem.artwork = KIcon("video-television");
mediaList << mediaItem;
- mediaItem.title = "Video Clips";
+ mediaItem.title = i18n("Video Clips");
mediaItem.url = "video://clips";
mediaItem.artwork = KIcon("video-x-generic");
mediaList << mediaItem;
- mediaItem.title = "Frequently Played";
- mediaItem.url = "semantics://frequent?video";
- mediaItem.artwork = KIcon("office-chart-bar");
- mediaList << mediaItem;
- mediaItem.title = "Recently Played";
- mediaItem.url = "semantics://recent?video";
- mediaItem.artwork = KIcon("chronometer");
- mediaList << mediaItem;
- mediaItem.title = "Highest Rated";
- mediaItem.url = "semantics://highest?video";
- mediaItem.artwork = KIcon("rating");
- mediaList << mediaItem;
}
//Show DVD if present
@@ -188,12 +180,27 @@ void MediaListsEngine::run()
}
}
if (DVDFound) {
- mediaItem.title = "DVD Video";
+ mediaItem.title = i18n("DVD Video");
mediaItem.url = "dvdvideo://";
mediaItem.artwork = KIcon("media-optical-dvd");
mediaList << mediaItem;
}
+ if (m_nepomukInited) {
+ mediaItem.title = i18n("Frequently Played");
+ mediaItem.url = "semantics://frequent?video";
+ mediaItem.artwork = KIcon("office-chart-bar");
+ mediaList << mediaItem;
+ mediaItem.title = i18n("Recently Played");
+ mediaItem.url = "semantics://recent?video";
+ mediaItem.artwork = KIcon("chronometer");
+ mediaList << mediaItem;
+ mediaItem.title = i18n("Highest Rated");
+ mediaItem.url = "semantics://highest?video";
+ mediaItem.artwork = KIcon("rating");
+ mediaList << mediaItem;
+ }
+
//Load saved lists from index
QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
if (indexFile.exists()) {
diff --git a/platform/medialistsengine.h b/src/platform/medialistsengine.h
similarity index 87%
rename from platform/medialistsengine.h
rename to src/platform/medialistsengine.h
index ea1e42e..7c986ba 100644
--- a/platform/medialistsengine.h
+++ b/src/platform/medialistsengine.h
@@ -29,6 +29,13 @@ class MediaListProperties;
class ListEngineFactory;
class MediaIndexer;
+/**
+* This ListEngine retrieves a convenient list of "Category" MediaItems.
+* e.g. Albums, Highest Rated, Movies, Audio CD, etc.
+* List Resource Identifiers handled are:
+* medialists://audio
+* medialists://video
+*/
class MediaListsEngine : public NepomukListEngine
{
Q_OBJECT
diff --git a/platform/mediavocabulary.cpp b/src/platform/mediavocabulary.cpp
similarity index 81%
rename from platform/mediavocabulary.cpp
rename to src/platform/mediavocabulary.cpp
index 957468d..b4809db 100644
--- a/platform/mediavocabulary.cpp
+++ b/src/platform/mediavocabulary.cpp
@@ -159,18 +159,47 @@ QUrl MediaVocabulary::typeAudioStream()
QUrl MediaVocabulary::typeVideo()
{
QUrl returnUrl = QUrl();
- if (m_vocabulary == MediaVocabulary::xesam) {
+ if (m_videoVocabulary == MediaVocabulary::xesam) {
returnUrl = Soprano::Vocabulary::Xesam::Video();
- } else if (m_vocabulary == MediaVocabulary::nie) {
+ } else if (m_videoVocabulary == MediaVocabulary::nie) {
returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nfo#Video");
- } else if (m_vocabulary == MediaVocabulary::nmm) {
- //Bangarang uses nfo:Video not nmm:Video - can't see semantic benefit
+ } else if (m_videoVocabulary == MediaVocabulary::nmm) {
returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nfo#Video");
}
return returnUrl;
}
+QUrl MediaVocabulary::typeVideoMovie()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#Movie");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::typeVideoTVShow()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#TVShow");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::typeTVSeries()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#TVSeries");
+ }
+
+ return returnUrl;
+}
+
QUrl MediaVocabulary::typeImage()
{
QUrl returnUrl = QUrl();
@@ -276,6 +305,17 @@ QUrl MediaVocabulary::created()
return returnUrl;
}
+QUrl MediaVocabulary::releaseDate()
+{
+ QUrl returnUrl = QUrl();
+ if (m_vocabulary == MediaVocabulary::nmm) {
+ //Draft nmm ontology is extension of nie
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#releaseDate");
+ }
+
+ return returnUrl;
+}
+
QUrl MediaVocabulary::genre()
{
QUrl returnUrl = QUrl();
@@ -349,7 +389,7 @@ QUrl MediaVocabulary::musicAlbumYear()
if (m_musicVocabulary == MediaVocabulary::xesam) {
returnUrl = Soprano::Vocabulary::Xesam::contentCreated();
} else if (m_musicVocabulary == MediaVocabulary::nmm) {
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nie#contentCreated");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#releaseDate");
} else if (m_musicVocabulary == MediaVocabulary::nid3) {
returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nid3#recordingYear");
}
@@ -385,68 +425,126 @@ QUrl MediaVocabulary::musicGenre()
return returnUrl;
}
-QUrl MediaVocabulary::videoIsMovie()
+QUrl MediaVocabulary::videoGenre()
{
QUrl returnUrl = QUrl();
- if (m_videoVocabulary == MediaVocabulary::nmm) {
- //Bangarang extension to nmm ontology draft
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#isMovie");
+ if (m_videoVocabulary == MediaVocabulary::xesam) {
+ returnUrl = Soprano::Vocabulary::Xesam::genre();
+ } else if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#genre");
}
return returnUrl;
}
-QUrl MediaVocabulary::videoIsTVShow()
+QUrl MediaVocabulary::videoSeries()
{
QUrl returnUrl = QUrl();
if (m_videoVocabulary == MediaVocabulary::nmm) {
- //Bangarang extension to nmm ontology draft
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#isTVShow");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#series");
}
return returnUrl;
}
-QUrl MediaVocabulary::videoGenre()
+QUrl MediaVocabulary::videoSynopsis()
{
QUrl returnUrl = QUrl();
if (m_videoVocabulary == MediaVocabulary::xesam) {
returnUrl = Soprano::Vocabulary::Xesam::genre();
} else if (m_videoVocabulary == MediaVocabulary::nmm) {
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#genre");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#synopsis");
}
return returnUrl;
}
-QUrl MediaVocabulary::videoSeriesName()
+QUrl MediaVocabulary::videoSeason()
{
QUrl returnUrl = QUrl();
if (m_videoVocabulary == MediaVocabulary::nmm) {
- //Bangarang extension of nmm ontology draft
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#seriesName");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#season");
}
return returnUrl;
}
-QUrl MediaVocabulary::videoSeriesSeason()
+QUrl MediaVocabulary::videoEpisodeNumber()
{
QUrl returnUrl = QUrl();
if (m_videoVocabulary == MediaVocabulary::nmm) {
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#season");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#episodeNumber");
}
return returnUrl;
}
-QUrl MediaVocabulary::videoSeriesEpisode()
+QUrl MediaVocabulary::videoAudienceRating()
{
QUrl returnUrl = QUrl();
if (m_videoVocabulary == MediaVocabulary::nmm) {
- returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#episodeNumber");
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#audienceRating");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::videoWriter()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#writer");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::videoDirector()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#director");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::videoAssistantDirector()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#assistantDirector");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::videoProducer()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#producer");
+ }
+
+ return returnUrl;
+}
+
+QUrl MediaVocabulary::videoActor()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#actor");
}
return returnUrl;
}
+QUrl MediaVocabulary::videoCinematographer()
+{
+ QUrl returnUrl = QUrl();
+ if (m_videoVocabulary == MediaVocabulary::nmm) {
+ returnUrl = QUrl("http://www.semanticdesktop.org/ontologies/nmm#cinematographer");
+ }
+
+ return returnUrl;
+}
diff --git a/platform/mediavocabulary.h b/src/platform/mediavocabulary.h
similarity index 79%
rename from platform/mediavocabulary.h
rename to src/platform/mediavocabulary.h
index b3ee7ab..d2788b5 100644
--- a/platform/mediavocabulary.h
+++ b/src/platform/mediavocabulary.h
@@ -27,7 +27,7 @@ class MediaVocabulary {
MediaVocabulary();
~MediaVocabulary();
- enum MediaVocabularies { xesam = Qt::UserRole + 1,
+ enum MediaVocabularyNamespace { xesam = Qt::UserRole + 1,
nie = Qt::UserRole + 2,
nmm = Qt::UserRole + 3,
nid3 = Qt::UserRole + 4};
@@ -47,8 +47,13 @@ class MediaVocabulary {
QUrl typeAudioMusic();
QUrl typeAudioStream();
QUrl typeVideo();
+ QUrl typeVideoMovie();
+ QUrl typeVideoTVShow();
QUrl typeImage();
+ //Media-related types
+ QUrl typeTVSeries();
+
//These properties are applicable to all media types
QUrl title();
QUrl description();
@@ -58,6 +63,7 @@ class MediaVocabulary {
QUrl artwork();
QUrl created();
QUrl genre();
+ QUrl releaseDate();
QUrl musicArtist();
QUrl musicArtistName();
@@ -67,12 +73,18 @@ class MediaVocabulary {
QUrl musicTrackNumber();
QUrl musicGenre();
- QUrl videoIsMovie();
- QUrl videoIsTVShow();
QUrl videoGenre();
- QUrl videoSeriesName();
- QUrl videoSeriesSeason();
- QUrl videoSeriesEpisode();
+ QUrl videoSeries();
+ QUrl videoSynopsis();
+ QUrl videoSeason();
+ QUrl videoEpisodeNumber();
+ QUrl videoAudienceRating();
+ QUrl videoWriter();
+ QUrl videoDirector();
+ QUrl videoAssistantDirector();
+ QUrl videoProducer();
+ QUrl videoActor();
+ QUrl videoCinematographer();
private:
int m_vocabulary;
diff --git a/platform/musiclistengine.cpp b/src/platform/musiclistengine.cpp
similarity index 83%
rename from platform/musiclistengine.cpp
rename to src/platform/musiclistengine.cpp
index 458f226..823f50c 100644
--- a/platform/musiclistengine.cpp
+++ b/src/platform/musiclistengine.cpp
@@ -23,6 +23,7 @@
#include "utilities.h"
#include <KIcon>
#include <KUrl>
+#include <KLocale>
#include <KDebug>
#include <Soprano/QueryResultIterator>
#include <Soprano/Vocabulary/Xesam>
@@ -109,6 +110,62 @@ void MusicListEngine::run()
{
QThread::setTerminationEnabled(true);
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+
+ if (m_updateSourceInfo) {
+ //Update to file metadata as well
+ QList<MediaItem> mediaList = m_mediaItemsInfoToUpdate;
+ for (int i = 0; i < mediaList.count(); i++) {
+ MediaItem mediaItem = mediaList.at(i);
+ if ((mediaItem.type == "Audio") && (mediaItem.fields["audioType"] == "Music")) {
+ if (Utilities::isMusic(mediaList.at(i).url)) {
+ TagLib::FileRef file(KUrl(mediaList.at(i).url).path().toLocal8Bit());
+ if (!file.isNull()) {
+ QString title = mediaItem.title;
+ if (!title.isEmpty()) {
+ TagLib::String tTitle(title.trimmed().toUtf8().data(), TagLib::String::UTF8);
+ file.tag()->setTitle(tTitle);
+ }
+ QUrl url = mediaItem.fields["artworkUrl"].toString();
+ if (!url.isEmpty()) {
+ //FIXME: Can't understand why this doesn't work.
+ Utilities::saveArtworkToTag(mediaList.at(i).url, url.toString());
+ }
+ QString artist = mediaItem.fields["artist"].toString();
+ if (!artist.isEmpty()) {
+ TagLib::String tArtist(artist.trimmed().toUtf8().data(), TagLib::String::UTF8);
+ file.tag()->setArtist(tArtist);
+ }
+ QString album = mediaItem.fields["album"].toString();
+ if (!album.isEmpty()) {
+ TagLib::String tAlbum(album.trimmed().toUtf8().data(), TagLib::String::UTF8);
+ file.tag()->setAlbum(tAlbum);
+ }
+ int year = mediaItem.fields["year"].toInt();
+ if (year != 0) {
+ file.tag()->setYear(year);
+ }
+ int trackNumber = mediaItem.fields["trackNumber"].toInt();
+ if (trackNumber != 0) {
+ file.tag()->setTrack(trackNumber);
+ }
+ QString genre = mediaItem.fields["genre"].toString();
+ if (!genre.isEmpty()) {
+ TagLib::String tGenre(genre.trimmed().toUtf8().data(), TagLib::String::UTF8);
+ file.tag()->setGenre(tGenre);
+ }
+ file.save();
+ }
+ }
+ }
+ }
+ }
+
+ NepomukListEngine::run();
+ return;
+ }
+
+
//Create media list based on engine argument and filter
QList<MediaItem> mediaList;
MediaVocabulary mediaVocabulary = MediaVocabulary();
@@ -123,10 +180,10 @@ void MusicListEngine::run()
if (!engineFilter.isNull()) {
QStringList argList = engineFilter.split("||");
artist = argList.at(0);
- if (argList.count() == 2) {
+ if (argList.count() >= 2) {
album = argList.at(1);
}
- if (argList.count() == 3) {
+ if (argList.count() >= 3) {
genre = argList.at(2);
}
}
@@ -162,11 +219,11 @@ void MusicListEngine::run()
}
++i;
}
- m_mediaListProperties.name = "Artists";
+ m_mediaListProperties.name = i18n("Artists");
if (!genre.isEmpty()) {
- m_mediaListProperties.name = QString("Artists - %1").arg(genre);
+ m_mediaListProperties.name = i18n("Artists - %1", genre);
}
- m_mediaListProperties.summary = QString("%1 artists").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 artist", "%1 artists", mediaList.count());
m_mediaListProperties.type = QString("Categories");
} else if (engineArg.toLower() == "albums") {
@@ -202,18 +259,18 @@ void MusicListEngine::run()
}
++i;
}
- m_mediaListProperties.name = "Albums";
+ m_mediaListProperties.name = i18n("Albums");
if (!artist.isEmpty()) {
- m_mediaListProperties.name = QString("Albums - %1").arg(artist);
+ m_mediaListProperties.name = i18n("Albums - %1", artist);
}
if (!genre.isEmpty()) {
- m_mediaListProperties.name = QString("Albums - %1").arg(genre);
+ m_mediaListProperties.name = i18n("Albums - %1", genre);
}
if (!artist.isEmpty() && !genre.isEmpty()) {
- m_mediaListProperties.name = QString("Albums - %1 - %2").arg(album, genre);
+ m_mediaListProperties.name = i18n("Albums - %1 - %2", album, genre);
}
- m_mediaListProperties.summary = QString("%1 albums").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 album", "%1 albums", mediaList.count());
m_mediaListProperties.type = QString("Categories");
} else if (engineArg.toLower() == "genres") {
@@ -246,8 +303,8 @@ void MusicListEngine::run()
}
++i;
}
- m_mediaListProperties.name = "Genres";
- m_mediaListProperties.summary = QString("%1 genres").arg(mediaList.count());
+ m_mediaListProperties.name = i18n("Genres");
+ m_mediaListProperties.summary = i18np("1 genre", "%1 genres", mediaList.count());
m_mediaListProperties.type = QString("Categories");
} else if (engineArg.toLower() == "songs") {
@@ -293,9 +350,9 @@ void MusicListEngine::run()
} else if (!artist.isEmpty()) {
m_mediaListProperties.name = QString("%1").arg(artist);
} else {
- m_mediaListProperties.name = QString("Songs");
+ m_mediaListProperties.name = i18n("Songs");
}
- m_mediaListProperties.summary = QString("%1 songs").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 song", "%1 songs", mediaList.count());
m_mediaListProperties.type = QString("Sources");
} else if (engineArg.toLower() == "search") {
@@ -323,7 +380,7 @@ void MusicListEngine::run()
mediaList.append(mediaItem);
}
- m_mediaListProperties.summary = QString("%1 songs").arg(mediaList.count());
+ m_mediaListProperties.summary = i18np("1 song", "%1 songs", mediaList.count());
m_mediaListProperties.type = QString("Sources");
}
}
@@ -346,58 +403,6 @@ void MusicListEngine::setFilterForSources(const QString& engineFilter)
m_mediaListProperties.lri = QString("music://songs?%1").arg(engineFilter);
}
-void MusicListEngine::updateSourceInfo(QList<MediaItem> mediaList)
-{
- NepomukListEngine::updateSourceInfo(mediaList);
-
- //Update to file metadata as well
- for (int i = 0; i < mediaList.count(); i++) {
- MediaItem mediaItem = mediaList.at(i);
- if ((mediaItem.type == "Audio") && (mediaItem.fields["audioType"] == "Music")) {
- if (Utilities::isMusic(mediaList.at(i).url)) {
- TagLib::FileRef file(KUrl(mediaList.at(i).url).path().toUtf8());
- if (!file.isNull()) {
- QString title = mediaItem.title;
- if (!title.isEmpty()) {
- TagLib::String tTitle(title.trimmed().toUtf8().data(), TagLib::String::UTF8);
- file.tag()->setTitle(tTitle);
- }
- QUrl url = mediaItem.fields["artworkUrl"].toString();
- if (!url.isEmpty()) {
- //FIXME: Can't understand why this doesn't work.
- Utilities::saveArtworkToTag(mediaList.at(i).url, url.toString());
- }
- QString artist = mediaItem.fields["artist"].toString();
- if (!artist.isEmpty()) {
- TagLib::String tArtist(artist.trimmed().toUtf8().data(), TagLib::String::UTF8);
- file.tag()->setArtist(tArtist);
- }
- QString album = mediaItem.fields["album"].toString();
- if (!album.isEmpty()) {
- TagLib::String tAlbum(album.trimmed().toUtf8().data(), TagLib::String::UTF8);
- file.tag()->setAlbum(tAlbum);
- }
- int year = mediaItem.fields["year"].toInt();
- if (year != 0) {
- file.tag()->setYear(year);
- }
- int trackNumber = mediaItem.fields["trackNumber"].toInt();
- if (trackNumber != 0) {
- file.tag()->setTrack(trackNumber);
- }
- QString genre = mediaItem.fields["genre"].toString();
- if (!genre.isEmpty()) {
- TagLib::String tGenre(genre.trimmed().toUtf8().data(), TagLib::String::UTF8);
- file.tag()->setGenre(tGenre);
- }
- file.save();
- }
- }
- }
- }
-
-}
-
MusicQuery::MusicQuery(bool distinct) :
m_distinct(distinct),
m_selectResource(false),
diff --git a/platform/musiclistengine.h b/src/platform/musiclistengine.h
similarity index 92%
rename from platform/musiclistengine.h
rename to src/platform/musiclistengine.h
index 8618f1f..fd5522a 100644
--- a/platform/musiclistengine.h
+++ b/src/platform/musiclistengine.h
@@ -27,6 +27,32 @@ class MediaItem;
class MediaListProperties;
class ListEngineFactory;
+/**
+* This ListEngine retrieves Music MediaItems from the nepomuk data store.
+* List Resource Identifiers handled are:
+* music://artists?[artist]||[album]||[genre]
+* music://albums?[artist]||[album]||[genre]
+* music://songs?[artist]||[album]||[genre]
+* music://search?[search term]
+*/
+class MusicListEngine : public NepomukListEngine
+{
+ Q_OBJECT
+
+ public:
+ MusicListEngine(ListEngineFactory *parent);
+ ~MusicListEngine();
+ void run();
+ void setFilterForSources(const QString& engineFilter);
+
+ private:
+ MediaItem createMediaItem(Soprano::QueryResultIterator& it);
+
+ Q_SIGNALS:
+ void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
+
+};
+
class MusicQuery {
public:
MusicQuery(bool distinct = true);
@@ -91,23 +117,5 @@ class MusicQuery {
QString getPrefix();
};
-class MusicListEngine : public NepomukListEngine
-{
- Q_OBJECT
-
- public:
- MusicListEngine(ListEngineFactory *parent);
- ~MusicListEngine();
- void run();
- void setFilterForSources(const QString& engineFilter);
- void updateSourceInfo(QList<MediaItem> mediaList);
-
- private:
- MediaItem createMediaItem(Soprano::QueryResultIterator& it);
-
- Q_SIGNALS:
- void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
-
-};
#endif // MUSICLISTENGINE_H
diff --git a/src/platform/nepomuklistengine.cpp b/src/platform/nepomuklistengine.cpp
new file mode 100644
index 0000000..1b2bd7c
--- /dev/null
+++ b/src/platform/nepomuklistengine.cpp
@@ -0,0 +1,110 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "nepomuklistengine.h"
+#include "mediavocabulary.h"
+#include <nepomuk/resource.h>
+#include <nepomuk/variant.h>
+#include <KDebug>
+
+NepomukListEngine::NepomukListEngine(ListEngineFactory * parent) : ListEngine(parent)
+{
+ Nepomuk::ResourceManager::instance()->init();
+ if (Nepomuk::ResourceManager::instance()->initialized()) {
+ m_nepomukInited = true; //resource manager inited successfully
+ m_mainModel = Nepomuk::ResourceManager::instance()->mainModel();
+ } else {
+ m_nepomukInited = false; //no resource manager
+ }
+ m_removeSourceInfo = false;
+ m_updateSourceInfo = false;
+
+}
+
+NepomukListEngine::~NepomukListEngine()
+{
+}
+
+void NepomukListEngine::run()
+{
+ m_mediaIndexer = new MediaIndexer(this);
+ if (m_removeSourceInfo) {
+ connectIndexer();
+ m_mediaIndexer->removeInfo(m_mediaItemsInfoToRemove);
+ m_removeSourceInfo = false;
+ m_mediaItemsInfoToRemove.clear();
+ exec();
+ }
+ if (m_updateSourceInfo) {
+ connectIndexer();
+ m_mediaIndexer->updateInfo(m_mediaItemsInfoToUpdate);
+ m_updateSourceInfo = false;
+ m_mediaItemsInfoToUpdate.clear();
+ exec();
+ }
+}
+
+void NepomukListEngine::removeSourceInfo(QList<MediaItem> mediaList)
+{
+ if (m_nepomukInited) {
+ m_mediaItemsInfoToRemove = mediaList;
+ m_removeSourceInfo = true;
+ start();
+ }
+}
+
+void NepomukListEngine::updateSourceInfo(QList<MediaItem> mediaList)
+{
+ if (m_nepomukInited) {
+ m_mediaItemsInfoToUpdate = mediaList;
+ m_updateSourceInfo = true;
+ start();
+ }
+}
+
+void NepomukListEngine::connectIndexer()
+{
+ connect(m_mediaIndexer, SIGNAL(started()), model(), SIGNAL(sourceInfoUpdateRemovalStarted()));
+ connect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SLOT(removeMediaItem(QString)));
+ connect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SIGNAL(sourceInfoRemoved(QString)));
+ connect(m_mediaIndexer, SIGNAL(percentComplete(int)), model(), SIGNAL(sourceInfoRemovalProgress(int)));
+ connect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SLOT(updateMediaItem(MediaItem)));
+ connect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SIGNAL(sourceInfoUpdated(MediaItem)));
+ connect(m_mediaIndexer, SIGNAL(percentComplete(int)), model(), SIGNAL(sourceInfoUpdateProgress(int)));
+ connect(m_mediaIndexer, SIGNAL(finished()), model(), SIGNAL(sourceInfoUpdateRemovalComplete()));
+ connect(m_mediaIndexer, SIGNAL(allFinished()), this, SLOT(indexerFinished()));
+}
+
+void NepomukListEngine::disconnectIndexer()
+{
+ disconnect(m_mediaIndexer, SIGNAL(started()), model(), SIGNAL(sourceInfoUpdateRemovalStarted()));
+ disconnect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SLOT(removeMediaItem(QString)));
+ disconnect(m_mediaIndexer, SIGNAL(urlInfoRemoved(QString)), model(), SIGNAL(sourceInfoRemoved(QString)));
+ disconnect(m_mediaIndexer, SIGNAL(percentComplete(int)), model(), SIGNAL(sourceInfoRemovalProgress(int)));
+ disconnect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SLOT(updateMediaItem(MediaItem)));
+ disconnect(m_mediaIndexer, SIGNAL(sourceInfoUpdated(MediaItem)), model(), SIGNAL(sourceInfoUpdated(MediaItem)));
+ disconnect(m_mediaIndexer, SIGNAL(percentComplete(int)), model(), SIGNAL(sourceInfoUpdateProgress(int)));
+ disconnect(m_mediaIndexer, SIGNAL(finished()), model(), SIGNAL(sourceInfoUpdateRemovalComplete()));
+ disconnect(m_mediaIndexer, SIGNAL(allFinished()), this, SLOT(indexerFinished()));
+}
+
+void NepomukListEngine::indexerFinished()
+{
+ exit();
+}
+
diff --git a/platform/nepomuklistengine.h b/src/platform/nepomuklistengine.h
similarity index 79%
rename from platform/nepomuklistengine.h
rename to src/platform/nepomuklistengine.h
index 9a2fa21..3820917 100644
--- a/platform/nepomuklistengine.h
+++ b/src/platform/nepomuklistengine.h
@@ -28,9 +28,11 @@
#include <Nepomuk/ResourceManager>
#include <Soprano/Model>
-/* This is an abstract base class for all list engines which
+/** This is an abstract base class for all list engines which
* use nepomuk. It simply tries to initialize nepomuk during construction
* and stores the result in local variables.
+ * It also provides a common interface to update or remove MediaItem
+ * information in the nepomuk datastore.
*/
class NepomukListEngine : public ListEngine
{
@@ -44,6 +46,7 @@ class NepomukListEngine : public ListEngine
virtual void removeSourceInfo(QList<MediaItem> mediaList);
virtual void updateSourceInfo(QList<MediaItem> mediaList);
+ void connectIndexer();
protected:
MediaIndexer* m_mediaIndexer;
@@ -56,6 +59,14 @@ class NepomukListEngine : public ListEngine
private Q_SLOTS:
void disconnectIndexer();
-
+ void indexerFinished();
+
+ Q_SIGNALS:
+ void updateRemovalStarted();
+ void updateRemovalComplete();
+ void urlInfoRemoved(QString url);
+ void sourceInfoUpdated(MediaItem mediaItem);
+ void percentComplete(int percent);
+
};
#endif // NEPOMUKLISTENGINE_H
diff --git a/src/platform/nepomukwriter/CMakeLists.txt b/src/platform/nepomukwriter/CMakeLists.txt
new file mode 100644
index 0000000..b591bab
--- /dev/null
+++ b/src/platform/nepomukwriter/CMakeLists.txt
@@ -0,0 +1,34 @@
+PROJECT(Bangarang)
+
+set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
+
+FIND_PACKAGE(KDE4 REQUIRED)
+FIND_PACKAGE(Nepomuk REQUIRED)
+
+INCLUDE(KDE4Defaults)
+
+ADD_DEFINITIONS( ${QT_DEFINITIONS} ${KDE4_DEFINITIONS} )
+
+INCLUDE_DIRECTORIES(
+ ${KDE4_INCLUDES}
+ ${KDEMULTIMEDIA_INCLUDE_DIR}
+ ${NEPOMUK_INCLUDE_DIR}
+)
+
+SET(BangarangNepomukWriterSources
+ main.cpp
+# ../mediaitemmodel.cpp
+ ../mediavocabulary.cpp
+)
+
+KDE4_ADD_EXECUTABLE(bangarangnepomukwriter ${BangarangNepomukWriterSources})
+
+TARGET_LINK_LIBRARIES(bangarangnepomukwriter
+ ${NEPOMUK_LIBRARIES}
+ ${KDEMULTIMEDIA_LIBRARIES}
+ ${SOPRANO_LIBRARIES}
+)
+
+########### install files ###############
+
+install(TARGETS bangarangnepomukwriter ${INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/platform/nepomukwriter/main.cpp b/src/platform/nepomukwriter/main.cpp
new file mode 100644
index 0000000..2359719
--- /dev/null
+++ b/src/platform/nepomukwriter/main.cpp
@@ -0,0 +1,600 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../mediavocabulary.h"
+#include <KCmdLineArgs>
+#include <KCmdLineOptions>
+#include <KLocalizedString>
+#include <KAboutData>
+#include <KDebug>
+#include <nepomuk/resource.h>
+#include <nepomuk/variant.h>
+#include <Nepomuk/ResourceManager>
+#include <KApplication>
+#include <QTextStream>
+#include <QFile>
+#include <QString>
+#include <QUrl>
+
+static KAboutData aboutData( "bangarangnepomukwriter", 0,
+ KLocalizedString(), "0.92 (1.0~beta2)",
+ KLocalizedString(), KAboutData::License_GPL_V3,
+ ki18n("Copyright 2009, Andrew Lake"), KLocalizedString(),
+ "" );
+
+void removeType(Nepomuk::Resource res, QUrl mediaType)
+{
+ QList<QUrl> types = res.types();
+ for (int i = 0; i < types.count(); i++) {
+ if (types.at(i).toString() == mediaType.toString()) {
+ types.removeAt(i);
+ break;
+ }
+ }
+ res.setTypes(types);
+}
+
+void writeToNepomuk(QTextStream &cout, QHash <QString, QVariant> fields)
+{
+ //QTextStream cout(stdout, QIODevice::WriteOnly);
+
+ MediaVocabulary mediaVocabulary = MediaVocabulary();
+ QString url = fields["url"].toString();
+ QString type = fields["type"].toString();
+
+ cout << QString("URL: %1\n").arg(url);
+
+ if (fields["removeInfo"].toString() == "true") {
+
+ //Remove metadata for media from nepomuk store
+ Nepomuk::Resource res(url);
+ if (!res.exists()) {
+ return;
+ }
+ if (type == "Audio") {
+ // Update the media type
+ cout << "Removing type...\n";
+ QUrl audioType;
+ if (fields["audioType"] == "Music") {
+ audioType = mediaVocabulary.typeAudioMusic();
+ } else if (fields["audioType"] == "Audio Stream") {
+ audioType = mediaVocabulary.typeAudioStream();
+ } else if (fields["audioType"] == "Audio Clip") {
+ audioType = mediaVocabulary.typeAudio();
+ }
+ if (res.hasType(audioType)) {
+ removeType(res, audioType);
+ }
+
+ // Update the properties
+ if (res.hasProperty(mediaVocabulary.title())){
+ cout << "Removing title...\n";
+ res.removeProperty(mediaVocabulary.title());
+ }
+ if (res.hasProperty(mediaVocabulary.description())) {
+ cout << "Removing description...\n";
+ res.removeProperty(mediaVocabulary.description());
+ }
+ if (res.hasProperty(mediaVocabulary.artwork())) {
+ cout << "Removing artwork...\n";
+ res.removeProperty(mediaVocabulary.artwork());
+ }
+
+ if (fields["audioType"] == "Music") {
+ if (res.hasProperty(mediaVocabulary.musicArtist())) {
+ cout << "Removing artist...\n";
+ res.removeProperty(mediaVocabulary.musicArtist());
+ }
+ if (res.hasProperty(mediaVocabulary.musicAlbumName())) {
+ cout << "Removing album...\n";
+ res.removeProperty(mediaVocabulary.musicAlbumName());
+ }
+ if (res.hasProperty(mediaVocabulary.genre())) {
+ cout << "Removing genre...\n";
+ res.removeProperty(mediaVocabulary.genre());
+ }
+ if (res.hasProperty(mediaVocabulary.musicTrackNumber())) {
+ cout << "Removing trackNumber...\n";
+ res.removeProperty(mediaVocabulary.musicTrackNumber());
+ }
+ if (res.hasProperty(mediaVocabulary.duration())) {
+ cout << "Removing duration...\n";
+ res.removeProperty(mediaVocabulary.duration());
+ }
+ if (res.hasProperty(mediaVocabulary.created())) {
+ cout << "Removing year...\n";
+ res.removeProperty(mediaVocabulary.created());
+ }
+ } else if ((fields["audioType"] == "Audio Stream") ||
+ (fields["audioType"] == "Audio Clip")) {
+ }
+ } else if (type == "Video") {
+ mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ //Update the media type
+ if (res.hasType(mediaVocabulary.typeVideo())) {
+ removeType(res, mediaVocabulary.typeVideo());
+ }
+ if (res.hasType(mediaVocabulary.typeVideoMovie())) {
+ removeType(res, mediaVocabulary.typeVideoMovie());
+ }
+ if (res.hasType(mediaVocabulary.typeVideoTVShow())) {
+ removeType(res, mediaVocabulary.typeVideoTVShow());
+ }
+
+ //Update the properties
+ if (res.hasProperty(mediaVocabulary.title())){
+ cout << "Removing title...\n";
+ res.removeProperty(mediaVocabulary.title());
+ }
+ if (res.hasProperty(mediaVocabulary.description())) {
+ cout << "Removing description...\n";
+ res.removeProperty(mediaVocabulary.description());
+ }
+ if (res.hasProperty(mediaVocabulary.artwork())) {
+ cout << "Removing artwork...\n";
+ res.removeProperty(mediaVocabulary.artwork());
+ }
+ if (fields["videoType"] == "Movie") {
+ if (res.hasProperty(mediaVocabulary.genre())) {
+ res.removeProperty(mediaVocabulary.genre());
+ }
+ if (res.hasProperty(mediaVocabulary.videoSynopsis())) {
+ res.removeProperty(mediaVocabulary.videoSynopsis());
+ }
+ if (res.hasProperty(mediaVocabulary.created())) {
+ res.removeProperty(mediaVocabulary.created());
+ }
+ if (res.hasProperty(mediaVocabulary.releaseDate())) {
+ res.removeProperty(mediaVocabulary.releaseDate());
+ }
+ if (res.hasProperty(mediaVocabulary.videoWriter())) {
+ res.removeProperty(mediaVocabulary.videoWriter());
+ }
+ if (res.hasProperty(mediaVocabulary.videoDirector())) {
+ res.removeProperty(mediaVocabulary.videoDirector());
+ }
+ if (res.hasProperty(mediaVocabulary.videoAssistantDirector())) {
+ res.removeProperty(mediaVocabulary.videoAssistantDirector());
+ }
+ if (res.hasProperty(mediaVocabulary.videoProducer())) {
+ res.removeProperty(mediaVocabulary.videoProducer());
+ }
+ if (res.hasProperty(mediaVocabulary.videoActor())) {
+ res.removeProperty(mediaVocabulary.videoActor());
+ }
+ if (res.hasProperty(mediaVocabulary.videoCinematographer())) {
+ res.removeProperty(mediaVocabulary.videoCinematographer());
+ }
+
+ } else if (fields["videoType"] == "TV Show") {
+ if (res.hasProperty(mediaVocabulary.videoSeries())) {
+ res.removeProperty(mediaVocabulary.videoSeries());
+ }
+ if (res.hasProperty(mediaVocabulary.videoSeason())) {
+ res.removeProperty(mediaVocabulary.videoSeason());
+ }
+ if (res.hasProperty(mediaVocabulary.videoEpisodeNumber())) {
+ res.removeProperty(mediaVocabulary.videoEpisodeNumber());
+ }
+ if (res.hasProperty(mediaVocabulary.genre())) {
+ res.removeProperty(mediaVocabulary.genre());
+ }
+ if (res.hasProperty(mediaVocabulary.videoSynopsis())) {
+ res.removeProperty(mediaVocabulary.videoSynopsis());
+ }
+ if (res.hasProperty(mediaVocabulary.created())) {
+ res.removeProperty(mediaVocabulary.created());
+ }
+ if (res.hasProperty(mediaVocabulary.releaseDate())) {
+ res.removeProperty(mediaVocabulary.releaseDate());
+ }
+ if (res.hasProperty(mediaVocabulary.videoWriter())) {
+ res.removeProperty(mediaVocabulary.videoWriter());
+ }
+ if (res.hasProperty(mediaVocabulary.videoDirector())) {
+ res.removeProperty(mediaVocabulary.videoDirector());
+ }
+ if (res.hasProperty(mediaVocabulary.videoAssistantDirector())) {
+ res.removeProperty(mediaVocabulary.videoAssistantDirector());
+ }
+ if (res.hasProperty(mediaVocabulary.videoProducer())) {
+ res.removeProperty(mediaVocabulary.videoProducer());
+ }
+ if (res.hasProperty(mediaVocabulary.videoActor())) {
+ res.removeProperty(mediaVocabulary.videoActor());
+ }
+ if (res.hasProperty(mediaVocabulary.videoCinematographer())) {
+ res.removeProperty(mediaVocabulary.videoCinematographer());
+ }
+ }
+ }
+ cout << QString("BangrangSignal:urlInfoRemoved:%1\n").arg(url);
+ cout.flush();
+ //debug << QString("BangrangSignal:urlInfoRemoved:%1\n").arg(url);
+
+ } else {
+ //Write media metadata info to nepomuk store;
+ Nepomuk::Resource res(url);
+
+ if (fields.contains("rating")) {
+ cout << "Setting Rating...\n";
+ int rating = fields["rating"].toInt();
+ res.setRating(rating);
+ }
+
+ if (fields.contains("playCount")) {
+ cout << "Setting Play Count...\n";
+ int playCount = fields["playCount"].toInt();
+ res.setProperty(mediaVocabulary.playCount(), Nepomuk::Variant(playCount));
+ }
+
+ if (fields.contains("lastPlayed")) {
+ cout << "Setting Last Played...\n";
+ QDateTime lastPlayed = fields["lastPlayed"].toDateTime();
+ res.setProperty(mediaVocabulary.lastPlayed(), Nepomuk::Variant(lastPlayed));
+ }
+
+ if (type == "Audio") {
+ // Update the media type
+ cout << "Writing type...\n";
+ QUrl audioType;
+ if (fields["audioType"] == "Music") {
+ audioType = mediaVocabulary.typeAudioMusic();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, audioType);
+ }
+ removeType(res, mediaVocabulary.typeAudioStream());
+ removeType(res, mediaVocabulary.typeAudio());
+ } else if (fields["audioType"] == "Audio Stream") {
+ audioType = mediaVocabulary.typeAudioStream();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, audioType);
+ }
+ removeType(res, mediaVocabulary.typeAudioMusic());
+ removeType(res, mediaVocabulary.typeAudio());
+ } else if (fields["audioType"] == "Audio Clip") {
+ audioType = mediaVocabulary.typeAudio();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, audioType);
+ }
+ removeType(res, mediaVocabulary.typeAudioMusic());
+ removeType(res, mediaVocabulary.typeAudioStream());
+ }
+ if (!res.hasType(audioType)) {
+ res.addType(audioType);
+ }
+
+ // Update the properties
+ QString title = fields["title"].toString();
+ if (!title.isEmpty()) {
+ cout << "Writing title...\n";
+ res.setProperty(mediaVocabulary.title(), Nepomuk::Variant(title));
+ }
+ QString description = fields["description"].toString();
+ if (!description.isEmpty()) {
+ cout << "Writing description...\n";
+ res.setProperty(mediaVocabulary.description(), Nepomuk::Variant(description));
+ }
+ QString artworkUrl = fields["artworkUrl"].toString();
+ if (!artworkUrl.isEmpty()) {
+ Nepomuk::Resource artworkRes(artworkUrl);
+ cout << "Writing artworkurl...\n";
+ if (!artworkRes.exists()) {
+ artworkRes = Nepomuk::Resource(QUrl(artworkUrl), QUrl("http://http://www.semanticdesktop.org/ontologies/nfo#Image"));
+ }
+ res.setProperty(mediaVocabulary.artwork(), Nepomuk::Variant(artworkRes));
+ }
+ if (fields["audioType"] == "Music") {
+ QString artist = fields["artist"].toString();
+ if (!artist.isEmpty()) {
+ cout << "Writing artist...\n";
+ res.setProperty(mediaVocabulary.musicArtist(), Nepomuk::Variant(artist));
+ }
+ QString album = fields["album"].toString();
+ if (!album.isEmpty()) {
+ cout << "Writing album...\n";
+ res.setProperty(mediaVocabulary.musicAlbumName(), Nepomuk::Variant(album));
+ }
+ QString genre = fields["genre"].toString();
+ if (!genre.isEmpty()) {
+ cout << "Writing genre...\n";
+ res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
+ }
+ int track = fields["trackNumber"].toInt();
+ if (track != 0) {
+ cout << "Writing track...\n";
+ res.setProperty(mediaVocabulary.musicTrackNumber(), Nepomuk::Variant(track));
+ }
+ int duration = fields["duration"].toInt();
+ if (duration != 0) {
+ cout << "Writing duration...\n";
+ res.setProperty(mediaVocabulary.duration(), Nepomuk::Variant(duration));
+ }
+ int year = fields["year"].toInt();
+ if (year != 0) {
+ QDate created = QDate(year, 1, 1);
+ cout << "Writing year..." << year << "\n";
+ res.setProperty(mediaVocabulary.created(), Nepomuk::Variant(created));
+ }
+ } else if ((fields["audioType"] == "Audio Stream") ||
+ (fields["audioType"] == "Audio Clip")) {
+ }
+ } else if (type == "Video") {
+ mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ //Update the media type
+ QUrl videoType;
+ if (fields["videoType"] == "Movie") {
+ videoType = mediaVocabulary.typeVideoMovie();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, videoType);
+ }
+ removeType(res, mediaVocabulary.typeVideoTVShow());
+ removeType(res, mediaVocabulary.typeVideo());
+ } else if (fields["videoType"] == "TV Show") {
+ videoType = mediaVocabulary.typeVideoTVShow();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, videoType);
+ }
+ removeType(res, mediaVocabulary.typeVideoMovie());
+ removeType(res, mediaVocabulary.typeVideo());
+ } else if (fields["videoType"] == "Video Clip") {
+ videoType = mediaVocabulary.typeVideo();
+ if (!res.exists()) {
+ res = Nepomuk::Resource(url, videoType);
+ }
+ removeType(res, mediaVocabulary.typeVideoMovie());
+ removeType(res, mediaVocabulary.typeVideoTVShow());
+ }
+ if (!res.hasType(videoType)) {
+ res.addType(videoType);
+ }
+
+ //Update the properties
+ QString title = fields["title"].toString();
+ if (!title.isEmpty()) {
+ cout << "Writing title...\n";
+ res.setProperty(mediaVocabulary.title(), Nepomuk::Variant(title));
+ }
+ QString description = fields["description"].toString();
+ if (!description.isEmpty()) {
+ cout << "Writing description...\n";
+ res.setProperty(mediaVocabulary.description(), Nepomuk::Variant(description));
+ }
+ QString artworkUrl = fields["artworkUrl"].toString();
+ if (!artworkUrl.isEmpty()) {
+ Nepomuk::Resource artworkRes(artworkUrl);
+ cout << "Writing artworkurl...\n";
+ if (!artworkRes.exists()) {
+ artworkRes = Nepomuk::Resource(QUrl(artworkUrl), QUrl("http://http://www.semanticdesktop.org/ontologies/nfo#Image"));
+ }
+ res.setProperty(mediaVocabulary.artwork(), Nepomuk::Variant(artworkRes));
+ }
+ if (fields["videoType"] == "Movie") {
+ QString genre = fields["genre"].toString();
+ if (!genre.isEmpty()) {
+ res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
+ }
+ QString synopsis = fields["synopsis"].toString();
+ if (!synopsis.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoSynopsis(), Nepomuk::Variant(synopsis));
+ }
+ int year = fields["year"].toInt();
+ if (year != 0) {
+ QDate releaseDate = QDate(year, 1, 1);
+ res.setProperty(mediaVocabulary.releaseDate(), Nepomuk::Variant(releaseDate));
+ }
+ QDate releaseDate = fields["releaseDate"].toDate();
+ if (releaseDate.isValid()) {
+ res.setProperty(mediaVocabulary.releaseDate(), Nepomuk::Variant(releaseDate));
+ }
+ QString writer = fields["writer"].toString();
+ if (!writer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoWriter(), Nepomuk::Variant(writer));
+ }
+ QString director = fields["director"].toString();
+ if (!director.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoDirector(), Nepomuk::Variant(director));
+ }
+ QString assistantDirector = fields["assistantDirector"].toString();
+ if (!assistantDirector.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoAssistantDirector(), Nepomuk::Variant(assistantDirector));
+ }
+ QString producer = fields["producer"].toString();
+ if (!producer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoProducer(), Nepomuk::Variant(producer));
+ }
+ QString actor = fields["actor"].toString();
+ if (!actor.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoActor(), Nepomuk::Variant(actor));
+ }
+ QString cinematographer = fields["cinematographer"].toString();
+ if (!cinematographer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoCinematographer(), Nepomuk::Variant(cinematographer));
+ }
+
+ } else if (fields["videoType"] == "TV Show") {
+ QString seriesName = fields["seriesName"].toString();
+ if (!seriesName.isEmpty()) {
+ Nepomuk::Resource series(fields["seriesName"].toString());
+ if (!series.exists()) {
+ Nepomuk::Resource(fields["seriesName"].toString(), mediaVocabulary.typeTVSeries());
+ }
+ res.setProperty(mediaVocabulary.videoSeries(), Nepomuk::Variant(series));
+ series.setProperty(mediaVocabulary.title(), Nepomuk::Variant(seriesName));
+ }
+ int season = fields["season"].toInt();
+ if (season != 0) {
+ res.setProperty(mediaVocabulary.videoSeason(), Nepomuk::Variant(season));
+ } else {
+ if (res.hasProperty(mediaVocabulary.videoSeason())) {
+ res.removeProperty(mediaVocabulary.videoSeason());
+ }
+ }
+ int episodeNumber = fields["episodeNumber"].toInt();
+ if (episodeNumber != 0) {
+ res.setProperty(mediaVocabulary.videoEpisodeNumber(), Nepomuk::Variant(episodeNumber));
+ } else {
+ if (res.hasProperty(mediaVocabulary.videoEpisodeNumber())) {
+ res.removeProperty(mediaVocabulary.videoEpisodeNumber());
+ }
+ }
+ QString genre = fields["genre"].toString();
+ if (!genre.isEmpty()) {
+ res.setProperty(mediaVocabulary.genre(), Nepomuk::Variant(genre));
+ }
+ QString synopsis = fields["synopsis"].toString();
+ if (!synopsis.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoSynopsis(), Nepomuk::Variant(synopsis));
+ }
+ int year = fields["year"].toInt();
+ if (year != 0) {
+ QDate releaseDate = QDate(year, 1, 1);
+ res.setProperty(mediaVocabulary.releaseDate(), Nepomuk::Variant(releaseDate));
+ }
+ QDate releaseDate = fields["releaseDate"].toDate();
+ if (releaseDate.isValid()) {
+ res.setProperty(mediaVocabulary.releaseDate(), Nepomuk::Variant(releaseDate));
+ }
+ QString writer = fields["writer"].toString();
+ if (!writer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoWriter(), Nepomuk::Variant(writer));
+ }
+ QString director = fields["director"].toString();
+ if (!director.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoDirector(), Nepomuk::Variant(director));
+ }
+ QString assistantDirector = fields["assistantDirector"].toString();
+ if (!assistantDirector.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoAssistantDirector(), Nepomuk::Variant(assistantDirector));
+ }
+ QString producer = fields["producer"].toString();
+ if (!producer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoProducer(), Nepomuk::Variant(producer));
+ }
+ QString actor = fields["actor"].toString();
+ if (!actor.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoActor(), Nepomuk::Variant(actor));
+ }
+ QString cinematographer = fields["cinematographer"].toString();
+ if (!cinematographer.isEmpty()) {
+ res.setProperty(mediaVocabulary.videoCinematographer(), Nepomuk::Variant(cinematographer));
+ }
+ }
+ }
+ cout << QString("BangarangSignal:sourceInfoUpdated:%1\n").arg(url);
+ cout.flush();
+ //debug << QString("BangarangSignal:sourceInfoUpdated:%1\n").arg(url);
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineOptions options;
+ options.add("+[URL]", ki18n( "File directive" ));
+ KCmdLineArgs::addCmdLineOptions( options );
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KApplication application;
+
+ QTextStream cout(stdout, QIODevice::WriteOnly);
+
+ bool nepomukInited;
+ Nepomuk::ResourceManager::instance()->init();
+ if (Nepomuk::ResourceManager::instance()->initialized()) {
+ nepomukInited = true; //resource manager inited successfully
+ } else {
+ nepomukInited = false; //no resource manager
+ }
+
+ if (args->count() > 0) {
+ /*QFile debugFile(QString("%1.debug").arg(args->arg(0)));
+ debugFile.open(QIODevice::WriteOnly);
+ QTextStream debug(&debugFile);*/
+
+ QFile file(args->arg(0));
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ cout << QString("BangarangError:Couldn't open %1\n").arg(args->arg(0));
+ //debug << QString("BangarangError:Couldn't open %1\n").arg(args->arg(0));
+ return 0;
+ }
+ QTextStream in(&file);
+
+ QHash <QString, QVariant> fields;
+
+ QString line;
+ int count = 0;
+ int processed = 0;
+
+ while (!in.atEnd()) {
+ if (!line.isEmpty()) {
+ if (line.startsWith("#Count")) {
+ count = line.split("=").at(1).trimmed().toInt();
+ } else if (line.startsWith("[") && line.endsWith("]")) {
+ QString url = line.mid(1, line.length()-2);
+ fields.insert("url",url);
+ } else {
+ int equalLocation = line.indexOf("=");
+ QString field;
+ QString value;
+ if (equalLocation != -1) {
+ field = line.left(equalLocation).trimmed();
+ value = line.mid(equalLocation+1).trimmed();
+ }
+ if (field == "duration" ||
+ field == "trackNumber" ||
+ field == "year" ||
+ field == "season" ||
+ field == "episodeNumber" ||
+ field == "rating" ||
+ field == "playCount") {
+ fields.insert(field, value.toInt());
+ } else if (field == "lastPlayed") {
+ fields.insert(field, QDateTime::fromString(value, "yyyyMMddhhmmss"));
+ } else {
+ fields.insert(field, value);
+ //debug << field << ":" << value << "\n";
+ }
+ }
+ }
+
+ line = in.readLine().trimmed();
+ if ((line.startsWith("[") && line.endsWith("]")) || in.atEnd()) {
+ if (fields.count() > 0) {
+ writeToNepomuk(cout, fields);
+ fields.clear();
+ processed = processed + 1;
+ if (count > 0) {
+ cout << QString("BangarangProgress:%1\n").arg(processed*100/count);
+ cout.flush();
+ }
+ }
+ //debug << QString("BangarangProgress:%1\n").arg(processed*100/count);
+ }
+ }
+ file.close();
+ file.remove();
+ cout << "Done!\n";
+ cout.flush();
+ } else {
+ cout << "You didn't provide an argument!\n";
+ }
+
+ return 0;
+}
diff --git a/platform/playlist.cpp b/src/platform/playlist.cpp
similarity index 82%
rename from platform/playlist.cpp
rename to src/platform/playlist.cpp
index 30c07ea..68474f4 100644
--- a/platform/playlist.cpp
+++ b/src/platform/playlist.cpp
@@ -20,6 +20,7 @@
#include "mediaitemmodel.h"
#include "utilities.h"
#include "mediavocabulary.h"
+#include "mediaindexer.h"
#include <time.h>
#include <KUrl>
#include <KIcon>
@@ -45,20 +46,23 @@ Playlist::Playlist(QObject * parent, Phonon::MediaObject * mediaObject) : QObjec
m_mode = Playlist::Normal;
m_repeat = false;
m_queueDepth = 10;
- m_playlistFinished = false;
- m_loadingState = Playlist::LoadingComplete;
+ m_state = Playlist::Finished;
+ m_hadVideo = false;
Nepomuk::ResourceManager::instance()->init();
if (Nepomuk::ResourceManager::instance()->initialized()) {
m_nepomukInited = true; //resource manager inited successfully
+ m_mediaIndexer = new MediaIndexer(this);
} else {
m_nepomukInited = false; //no resource manager
}
+ connect(m_mediaObject, SIGNAL(tick(qint64)), this, SLOT(updatePlaybackInfo(qint64)));
connect(m_mediaObject, SIGNAL(aboutToFinish()), this, SLOT(queueNextPlaylistItem()));
connect(m_mediaObject, SIGNAL(finished()), this, SLOT(confirmPlaylistFinished()));
connect(m_mediaObject, SIGNAL(currentSourceChanged (const Phonon::MediaSource & )), this, SLOT(currentSourceChanged(const Phonon::MediaSource & )));
connect(m_mediaObject, SIGNAL(stateChanged (Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State)));
+ connect(m_mediaObject, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
connect(m_mediaController, SIGNAL(titleChanged (int)), this, SLOT(titleChanged(int)));
connect(m_currentPlaylist, SIGNAL(mediaListChanged()), this, SLOT(playlistChanged()));
@@ -66,10 +70,6 @@ Playlist::Playlist(QObject * parent, Phonon::MediaObject * mediaObject) : QObjec
Playlist::~Playlist()
{
- delete m_currentPlaylist;
- delete m_nowPlaying;
- delete m_queue;
- //delete m_mediaController;
}
MediaItemModel * Playlist::playlistModel()
@@ -95,7 +95,7 @@ Phonon::MediaObject * Playlist::mediaObject()
//----------------------------------------
//--- Primary playback control methods ---
//----------------------------------------
-void Playlist::playItemAt(int row, int model)
+void Playlist::playItemAt(int row, Playlist::Model model)
{
MediaItem nextMediaItem;
if (model == Playlist::PlaylistModel) {
@@ -110,41 +110,7 @@ void Playlist::playItemAt(int row, int model)
isNowPlaying = true;
}
}
-
- //Play media Item
- m_mediaObject->clearQueue();
- if (nextMediaItem.fields["audioType"].toString() == "CD Track") {
- if (!isNowPlaying) {
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
- }
- m_mediaObject->setCurrentSource(Phonon::Cd);
- m_mediaController->setAutoplayTitles(false);
- m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
- m_mediaObject->play();
- } else if (nextMediaItem.fields["videoType"].toString() == "DVD Title") {
- if (!isNowPlaying) {
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
- }
- m_mediaObject->setCurrentSource(Phonon::Dvd);
- m_mediaController->setAutoplayTitles(false);
- m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
- m_mediaObject->play();
- } else {
- if (!isNowPlaying) {
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
- }
- m_mediaObject->setCurrentSource(Phonon::MediaSource(QUrl::fromPercentEncoding(nextMediaItem.url.toUtf8())));
- m_mediaObject->play();
- // - Get album artwork
- MediaItem itemWithArtwork = nextMediaItem;
- QPixmap artwork = Utilities::getArtworkFromMediaItem(nextMediaItem);
- if (!artwork.isNull()) {
- itemWithArtwork.artwork = KIcon(artwork);
- m_nowPlaying->replaceMediaItemAt(0, itemWithArtwork, false);
- }
- }
- m_playlistFinished = false;
-
+
//Update Queue Model
if (m_mode == Playlist::Normal) {
//Just build a new queue from the specified row
@@ -178,34 +144,29 @@ void Playlist::playItemAt(int row, int model)
}
}
- } else if (model == Playlist::QueueModel) {
- //Get media item from queue list
- nextMediaItem = m_queue->mediaItemAt(row);
- nextMediaItem.nowPlaying = true;
-
//Play media Item
m_mediaObject->clearQueue();
if (nextMediaItem.fields["audioType"].toString() == "CD Track") {
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
m_mediaObject->setCurrentSource(Phonon::Cd);
m_mediaController->setAutoplayTitles(false);
m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
+ m_mediaObject->play();
} else if (nextMediaItem.fields["videoType"].toString() == "DVD Title") {
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
m_mediaObject->setCurrentSource(Phonon::Dvd);
m_mediaController->setAutoplayTitles(false);
m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
+ m_mediaObject->play();
} else {
- // - Get album artwork
- QPixmap artwork = Utilities::getArtworkFromMediaItem(nextMediaItem);
- if (!artwork.isNull()) {
- nextMediaItem.artwork = KIcon(artwork);
- }
- m_nowPlaying->loadMediaItem(nextMediaItem, true);
m_mediaObject->setCurrentSource(Phonon::MediaSource(QUrl::fromPercentEncoding(nextMediaItem.url.toUtf8())));
+ m_mediaObject->play();
}
- m_mediaObject->play();
- m_playlistFinished = false;
+ m_state = Playlist::Playing;
+
+
+ } else if (model == Playlist::QueueModel) {
+ //Get media item from queue list
+ nextMediaItem = m_queue->mediaItemAt(row);
+ nextMediaItem.nowPlaying = true;
//Update Queue Model
if (m_mode == Playlist::Normal) {
@@ -220,6 +181,22 @@ void Playlist::playItemAt(int row, int model)
m_queue->loadMediaList(queueMediaList, true);
}
}
+
+ //Play media Item
+ m_mediaObject->clearQueue();
+ if (nextMediaItem.fields["audioType"].toString() == "CD Track") {
+ m_mediaObject->setCurrentSource(Phonon::Cd);
+ m_mediaController->setAutoplayTitles(false);
+ m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
+ } else if (nextMediaItem.fields["videoType"].toString() == "DVD Title") {
+ m_mediaObject->setCurrentSource(Phonon::Dvd);
+ m_mediaController->setAutoplayTitles(false);
+ m_mediaController->setCurrentTitle(nextMediaItem.fields["trackNumber"].toInt());
+ } else {
+ m_mediaObject->setCurrentSource(Phonon::MediaSource(QUrl::fromPercentEncoding(nextMediaItem.url.toUtf8())));
+ }
+ m_mediaObject->play();
+ m_state = Playlist::Playing;
}
@@ -227,25 +204,33 @@ void Playlist::playItemAt(int row, int model)
void Playlist::playNext()
{
- if (m_queue->rowCount() > 1) {
- m_queue->removeMediaItemAt(0);
- playItemAt(0, Playlist::QueueModel);
+ if (m_mediaObject->state() == Phonon::PlayingState || m_mediaObject->state() == Phonon::PausedState || m_mediaObject->state() == Phonon::LoadingState) {
+ //Add currently playing item to history
+ if (m_nowPlaying->rowCount() > 0) {
+ int row = m_nowPlaying->mediaItemAt(0).playlistIndex;
+ m_playlistIndicesHistory.append(row);
+ m_playlistUrlHistory.append(m_nowPlaying->mediaItemAt(0).url);
+ }
+
+ if (m_queue->rowCount() > 1) {
+ m_queue->removeMediaItemAt(0);
+ playItemAt(0, Playlist::QueueModel);
+ }
+ addToQueue();
}
- addToQueue();
}
void Playlist::playPrevious()
{
- if (m_playlistIndicesHistory.count() > 0) {
- int previousRow = m_playlistIndicesHistory.last();
- int oldItemRow = m_nowPlaying->mediaItemAt(0).playlistIndex;
- m_nowPlaying->removeMediaItemAt(0);
- if (oldItemRow != previousRow && oldItemRow >= 0 and oldItemRow < m_currentPlaylist->rowCount()) {
- //Cycle through true and false to ensure data change forces update
- m_currentPlaylist->item(oldItemRow,0)->setData(true, MediaItem::NowPlayingRole);
- m_currentPlaylist->item(oldItemRow,0)->setData(false, MediaItem::NowPlayingRole);
+ if (m_mediaObject->state() == Phonon::PlayingState || m_mediaObject->state() == Phonon::PausedState || m_mediaObject->state() == Phonon::LoadingState) {
+ if (m_playlistIndicesHistory.count() > 0) {
+ //Get previously played item and remove from history
+ int previousRow = m_playlistIndicesHistory.last();
+ m_playlistIndicesHistory.removeLast();
+ m_playlistUrlHistory.removeLast();
+
+ playItemAt(previousRow, Playlist::PlaylistModel);
}
- playItemAt(previousRow, Playlist::PlaylistModel);
}
}
@@ -268,6 +253,7 @@ void Playlist::start()
void Playlist::stop()
{
+ m_hadVideo = false;
m_mediaObject->stop();
m_queue->clearMediaListData();
if (m_nowPlaying->rowCount() > 0) {
@@ -287,14 +273,13 @@ void Playlist::playMediaList(QList<MediaItem> mediaList)
//Clear playlist
clearPlaylist();
-
//Load playlist with all media items
//Note: Because playlist loads asynchronously we have to
//wait for signal from playlist model that loading is
//complete (playlistChanged) before starting playback
// - hence the use of playWhenPlaylistChanges.
playWhenPlaylistChanges = true;
- m_loadingState = Playlist::Loading;
+ m_state = Playlist::Loading;
emit loading();
m_currentPlaylist->loadSources(mediaList);
}
@@ -339,16 +324,16 @@ void Playlist::removeMediaItemAt(int row)
void Playlist::clearPlaylist()
{
+ stop();
m_currentPlaylist->clearMediaListData(true);
m_queue->clearMediaListData();
m_nowPlaying->clearMediaListData();
m_playlistIndices.clear();
m_playlistIndicesHistory.clear();
m_playlistUrlHistory.clear();
- m_mediaObject->stop();
}
-void Playlist::setMode(int mode)
+void Playlist::setMode(Playlist::Mode mode)
{
if (mode <= 1) {
m_mode = mode;
@@ -390,7 +375,7 @@ void Playlist::setMode(int mode)
}
}
-int Playlist::mode()
+Playlist::Mode Playlist::mode()
{
return m_mode;
}
@@ -400,9 +385,9 @@ void Playlist::setRepeat(bool repeat)
m_repeat = repeat;
}
-int Playlist::loadingState()
+Playlist::State Playlist::state()
{
- return m_loadingState;
+ return m_state;
}
@@ -420,7 +405,7 @@ void Playlist::queueNextPlaylistItem() // connected to MediaObject::aboutToFinis
addToQueue();
if (m_queue->rowCount() == 1) {
//Playlist is finished
- m_playlistFinished = true;
+ m_state = Playlist::Finished;
}
if (m_queue->rowCount() > 1) {
m_queue->removeMediaItemAt(0);
@@ -435,15 +420,10 @@ void Playlist::queueNextPlaylistItem() // connected to MediaObject::aboutToFinis
queue << Phonon::MediaSource(Phonon::Dvd);
m_mediaObject->setQueue(queue);
} else {
- QPixmap artwork = Utilities::getArtworkFromMediaItem(nextMediaItem);
- if (!artwork.isNull()) {
- nextMediaItem.artwork = KIcon(artwork);
- }
QList<QUrl> queue;
queue << QUrl::fromPercentEncoding(nextMediaItem.url.toUtf8());
m_mediaObject->setQueue(queue);
}
- m_nowPlaying->loadMediaItem(nextMediaItem);
}
}
@@ -462,19 +442,15 @@ void Playlist::currentSourceChanged(const Phonon::MediaSource & newSource) //con
}
}
}
- if (newSource.discType() == Phonon::NoDisc) {
- updateNowPlaying();
- }
+ updateNowPlaying();
}
void Playlist::titleChanged(int newTitle) //connected to MediaController::titleChanged
{
- //TODO:Confirm that titleChanged signal is not emitted for first track on cd
if ((m_queue->rowCount() > 1)) {
MediaItem mediaItem = m_queue->mediaItemAt(1);
if (mediaItem.fields["trackNumber"].toInt() == newTitle) {
m_queue->removeMediaItemAt(0);
- m_nowPlaying->loadMediaItem(mediaItem);
}
}
updateNowPlaying();
@@ -482,7 +458,7 @@ void Playlist::titleChanged(int newTitle) //connected to MediaController::titleC
void Playlist::confirmPlaylistFinished() //connected to MediaObject::finished()
{
- if (m_playlistFinished) {
+ if (m_state == Playlist::Finished) {
//Refresh playlist model to ensure views get updated
int row = -1;
if (m_nowPlaying->rowCount() > 0) {
@@ -496,6 +472,8 @@ void Playlist::confirmPlaylistFinished() //connected to MediaObject::finished()
//Clear nowPlaying and queue and emit playlistFinished
m_nowPlaying->removeMediaItemAt(0);
m_queue->removeMediaItemAt(0);
+ m_playlistIndicesHistory.clear();
+ m_playlistUrlHistory.clear();
emit playlistFinished();
}
}
@@ -507,10 +485,17 @@ void Playlist::stateChanged(Phonon::State newstate, Phonon::State oldstate) {
* so no connecting to Phonon::MediaObject::hasVideoChanged() is
* necessary.
*/
- if (!m_mediaObject->hasVideo()) {
+ if (!m_mediaObject->hasVideo()) {
return;
}
-
+
+ if (m_hadVideo && m_mediaObject->hasVideo()) {
+ return;
+ }
+ if (newstate == Phonon::PlayingState || newstate == Phonon::PausedState) {
+ m_hadVideo = m_mediaObject->hasVideo();
+ }
+
QDBusInterface iface(
"org.kde.kded",
"/modules/powerdevil",
@@ -526,22 +511,45 @@ void Playlist::stateChanged(Phonon::State newstate, Phonon::State oldstate) {
* We therefore set the profile always to performance and let the
* refreshStatus call handle the case when the computer runs on battery.
*/
- iface.call("setProfile", "Performance");
+ //iface.call("setProfile", "Performance");
iface.call("refreshStatus");
}
}
+void Playlist::updatePlaybackInfo(qint64 time)
+{
+ if (time >= 10000 && !m_playbackInfoWritten) {
+ //Update last played date and play count after 10 seconds
+ if (m_nepomukInited && m_nowPlaying->rowCount() > 0) {
+ Nepomuk::Resource res(m_nowPlaying->mediaItemAt(0).url);
+ if (res.exists()) {
+ m_mediaIndexer->updatePlaybackInfo(m_nowPlaying->mediaItemAt(0).url, true, QDateTime::currentDateTime());
+ }
+ }
+ m_playbackInfoWritten = true;
+ }
+}
+
//--------------------------------
//--- MediaItemModel SLOTS ---
//--------------------------------
void Playlist::playlistChanged()
{
- m_loadingState = Playlist::LoadingComplete;
+ m_state = Playlist::Finished;
if (playWhenPlaylistChanges && m_currentPlaylist->rowCount() > 0) {
//Start playing with clean playlist, queue and history
- start();
playWhenPlaylistChanges = false;
+ if (m_currentPlaylist->mediaItemAt(0).type == "Audio" ||
+ m_currentPlaylist->mediaItemAt(0).type == "Video") {
+ start();
+ } else {
+ if (m_currentPlaylist->mediaItemAt(0).fields["messageType"].toString() == "No Results") {
+ m_currentPlaylist->removeMediaItemAt(0,false);
+ }
+ m_mediaObject->stop();
+ emit playlistFinished();
+ }
} else if (m_currentPlaylist->rowCount() > 0){
//if playlist mode is normal (sequential)
// - rebuild history to just before currently playing/paused url
@@ -566,8 +574,8 @@ void Playlist::playlistChanged()
buildQueueFrom(currentRow);
} else {
//if playlist mode is shuffle
- // - remove from history any items NOT in the current playlistChanged
- // - remove from queue any items NOT in the current playlistChanged
+ // - remove from history any items NOT in the current playlist
+ // - remove from queue any items NOT in the current playlist
// - rebuild playlist indices using remaining items
// - add items to queu to fill queue depth
QList<QString> oldPlaylistUrlHistory = m_playlistUrlHistory;
@@ -596,11 +604,11 @@ void Playlist::playlistChanged()
m_playlistIndices.clear();
for (int i = 0; i < m_currentPlaylist->rowCount(); i++) {
if (m_playlistIndicesHistory.indexOf(i) == -1) {
- MediaItem mediaItem = m_queue->mediaItemAt(i);
+ MediaItem mediaItem = m_currentPlaylist->mediaItemAt(i);
QString urlToSearch = mediaItem.url;
- int rowOfUrl = m_queue->rowOfUrl(urlToSearch);
- if (rowOfUrl == -1) {
- m_playlistIndices.append(rowOfUrl);
+ int rowInQueue = m_queue->rowOfUrl(urlToSearch);
+ if (rowInQueue == -1) {
+ m_playlistIndices.append(i);
}
}
}
@@ -639,39 +647,41 @@ void Playlist::updateNowPlaying()
//ACTUALLY UPDATE THE NOW PLAYING VIEW HERE!
//THIS SHOULD BE THE ONLY PLACE THAT UPDATES THE NOW PLAYING VIEW!
- //Get row of previously playing item and add to history
- MediaItem mediaItem;
- bool itemIsMedia = false;
+ //Get row and url of previously playing item and add to history
+ int oldItemRow = -1;
if (m_nowPlaying->rowCount() > 0) {
- mediaItem = m_nowPlaying->mediaItemAt(0);
- if ((mediaItem.type == "Audio") || (mediaItem.type == "Video") || (mediaItem.type == "Image")) {
- itemIsMedia = true;
- }
+ oldItemRow = m_nowPlaying->mediaItemAt(0).playlistIndex;
}
- bool itemIsStale = true;
- if (itemIsMedia) {
- if ((mediaItem.fields["audioType"].toString() == "CD Track") || (mediaItem.fields["videoType"].toString() == "DVD Title")) {
- if (mediaItem.fields["trackNumber"].toInt() == m_mediaController->currentTitle()) {
- itemIsStale = false;
- }
+ //Find matching item in queue
+ int queueRow = -1;
+ for (int i = 0; i < m_queue->rowCount(); i++) {
+ QString currentUrl;
+ if (m_mediaObject->currentSource().discType() == Phonon::Cd) {
+ currentUrl = QString("CDTRACK%1").arg(m_mediaController->currentTitle());
+ } else if (m_mediaObject->currentSource().discType() == Phonon::Dvd) {
+ currentUrl = QString("DVDTRACK%1").arg(m_mediaController->currentTitle());
} else {
- QUrl mediaItemUrl = QUrl::fromPercentEncoding(mediaItem.url.toUtf8());
- if (mediaItemUrl == m_mediaObject->currentSource().url()) {
- itemIsStale = false;
- }
+ currentUrl = m_mediaObject->currentSource().url().toString();
+ }
+ if ((currentUrl == QUrl::fromPercentEncoding(m_queue->mediaItemAt(i).url.toUtf8()))) {
+ queueRow = i;
+ break;
}
}
-
- int oldItemRow = -1;
- if (itemIsStale) {
- if (itemIsMedia) {
- oldItemRow = m_nowPlaying->mediaItemAt(0).playlistIndex;
- m_playlistIndicesHistory.append(oldItemRow);
- m_playlistUrlHistory.append(m_currentPlaylist->mediaItemAt(oldItemRow).url);
+
+ //Update Now Playing view
+ if (queueRow != -1) {
+ MediaItem nowPlayingItem = m_queue->mediaItemAt(queueRow);
+ QPixmap artwork = Utilities::getArtworkFromMediaItem(nowPlayingItem);
+ if (!artwork.isNull()) {
+ nowPlayingItem.artwork = KIcon(artwork);
+ }
+ if (m_nowPlaying->rowCount() > 0) {
+ m_nowPlaying->replaceMediaItemAt(0, nowPlayingItem, true);
+ } else {
+ m_nowPlaying->loadMediaItem(nowPlayingItem, true);
}
- //Update Now Playing view
- m_nowPlaying->removeMediaItemAt(0, true); //remove old now playing item
}
//Refresh playlist model to ensure views get updated
@@ -689,21 +699,10 @@ void Playlist::updateNowPlaying()
m_currentPlaylist->item(oldItemRow,0)->setData(false, MediaItem::NowPlayingRole);
}
- if (m_mediaObject->currentSource().discType() == Phonon::Cd) {
- //m_mediaController->setCurrentTitle(m_nowPlaying->mediaItemAt(0).fields["trackNumber"].toInt());
- } else if (m_mediaObject->currentSource().discType() == Phonon::Dvd) {
- //m_mediaController->setCurrentTitle(m_nowPlaying->mediaItemAt(0).fields["trackNumber"].toInt());
- } else {
+ if ((m_mediaObject->currentSource().discType() != Phonon::Cd) && (m_mediaObject->currentSource().discType() != Phonon::Dvd)) {
//Update last played date and play count
if (m_nepomukInited && m_nowPlaying->rowCount() > 0) {
- MediaVocabulary mediaVocabulary = MediaVocabulary();
- Nepomuk::Resource res(m_nowPlaying->mediaItemAt(0).url);
- if (res.exists()) {
- res.setProperty(mediaVocabulary.lastPlayed(), Nepomuk::Variant(QDateTime::currentDateTime()));
- int playCount = res.property(mediaVocabulary.playCount()).toInt();
- playCount = playCount + 1;
- res.setProperty(mediaVocabulary.playCount(), Nepomuk::Variant(playCount));
- }
+ m_playbackInfoWritten = false; // Written 10 seconds later with updatePlaybackInfo()
}
}
}
@@ -779,3 +778,15 @@ void Playlist::createUrlHistoryFromIndices()
m_playlistUrlHistory.append(m_currentPlaylist->mediaItemAt(m_playlistIndicesHistory.at(i)).url);
}
}
+
+void Playlist::metaDataChanged()
+{
+ if (m_nowPlaying->rowCount()>0) {
+ MediaItem mediaItem = m_nowPlaying->mediaItemAt(0);
+ if ((mediaItem.type == "Audio") && (mediaItem.fields["audioType"].toString() == "Audio Stream")) {
+
+ mediaItem.subTitle = m_mediaObject->metaData("TITLE").join(" ");
+ m_nowPlaying->replaceMediaItemAt(0, mediaItem);
+ }
+ }
+}
diff --git a/src/platform/playlist.h b/src/platform/playlist.h
new file mode 100644
index 0000000..e52291a
--- /dev/null
+++ b/src/platform/playlist.h
@@ -0,0 +1,231 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PLAYLIST_H
+#define PLAYLIST_H
+
+#include <QObject>
+#include <Phonon/MediaObject>
+#include <Phonon/MediaController>
+
+class MediaItemModel;
+class MediaItem;
+class MediaIndexer;
+
+/**
+ * This class provides MediaItemModels for a playlist and a queue.
+ * It additionally provides an interface to playback MediaItems
+ * in the playlist or the queue, shuffle and repeat. It also
+ * provides a MediaItemModel containing the currently playing
+ * MediaItem.
+ *
+ * The queue MediaItemModel contains MediaItems in the order they
+ * will be played.
+ * The playlist MediaItemModel is the model from which MediaItems
+ * are added to the queue according to the Playlist::Mode.
+ */
+class Playlist : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum Mode { Normal = 0, Shuffle = 1};
+ enum Model { PlaylistModel = 0, QueueModel = 1};
+ enum State { Finished = 0, Loading = 1, Playing = 2};
+
+ /**
+ * Constructor
+ *
+ * @param mediaObject MediaObject the Playlist should use for playback
+ */
+ Playlist(QObject * parent, Phonon::MediaObject * mediaObject);
+
+ /**
+ * Destructor
+ */
+ ~Playlist();
+
+ /**
+ * Adds a list of MediaItems to the playlist
+ *
+ * @param mediaList List of MediaItems to add
+ */
+ void addMediaList(QList<MediaItem> mediaList);
+
+ /**
+ * Adds a MediaItem to playlist.
+ *
+ * @param mediaItem MediaItem to add.
+ */
+ void addMediaItem(MediaItem mediaItem);
+
+ /**
+ * Clears the playlist
+ */
+ void clearPlaylist();
+
+ /**
+ * Returns the loading state of the Playlist.
+ *
+ * @returns Playlist::State (see enum)
+ */
+ Playlist::State state();
+
+ /**
+ * Returns the Phonon::MediaObject used by Playlist.
+ */
+ Phonon::MediaObject * mediaObject();
+
+ /**
+ * Returns the current Playlist mode.
+ *
+ * @returns Playlist::Mode (see enum)
+ */
+ Playlist::Mode mode();
+
+ /**
+ * Returns the MediaItemModel containing the currently
+ * playing MediaItem.
+ */
+ MediaItemModel * nowPlayingModel();
+
+ /**
+ * Plays item at the specified row of the specified model
+ *
+ * @param row row of the specified model
+ * @param model either Playlist::PlaylistModel or Playlist::QueueModel
+ */
+ void playItemAt(int row, Playlist::Model model = Playlist::PlaylistModel);
+
+ /**
+ * Returns the MediaItemModel containing the list of MediaItems
+ * in the playlist.
+ */
+ MediaItemModel * playlistModel();
+
+ /**
+ * Plays the specified list of MediaItems
+ *
+ * @param mediaList list of MediaItems to play
+ */
+ void playMediaList(QList<MediaItem> mediaList);
+
+ /**
+ * Returns the MediaItemModel containing the list of MediaItems
+ * in the queue.
+ */
+ MediaItemModel * queueModel();
+
+ /**
+ * Removes MediaItem corresponding to the specified row in the
+ * playlist model.
+ *
+ * @param row row of playlist model
+ */
+ void removeMediaItemAt(int row);
+
+ /**
+ * Sets the Playlist queuing mode
+ *
+ * @param mode mode to add MediaItems to the queue.
+ * Either Playlist::Normal or Playlist::Shuffle.
+ */
+ void setMode(Playlist::Mode mode);
+
+ /**
+ * Sets whether or playback should repeat after playing
+ * all items in the playlist.
+ *
+ * @param repeat true to repeat, false to end playback
+ * when all items in the playlist has
+ * been played.
+ */
+ void setRepeat(bool repeat);
+
+ public slots:
+ /**
+ * Play next MediaItem in queue.
+ */
+ void playNext();
+
+ /**
+ * Play previous MediaItem in queue.
+ */
+ void playPrevious();
+
+ /**
+ * Start playback.
+ */
+ void start();
+
+ /**
+ * Stop playback
+ */
+ void stop();
+
+ Q_SIGNALS:
+ /**
+ * Emitted when loading MediaItems into the playlist.
+ */
+ void loading();
+
+ /**
+ * Emitting when all items in playlist have been played.
+ */
+ void playlistFinished();
+
+ private:
+ QObject * m_parent;
+ MediaItemModel * m_currentPlaylist;
+ MediaItemModel * m_nowPlaying;
+ MediaItemModel * m_queue;
+ Playlist::Mode m_mode;
+ int m_repeat;
+ int m_queueDepth;
+ int m_oldPlaylistLength;
+ QList<int> m_playlistIndices;
+ QList<int> m_playlistIndicesHistory;
+ QList<QString> m_playlistUrlHistory;
+ Phonon::MediaObject * m_mediaObject;
+ Phonon::MediaController * m_mediaController;
+ bool playWhenPlaylistChanges;
+ bool m_playlistFinished;
+ void createUrlHistoryFromIndices();
+ void updateNowPlaying();
+ bool m_nepomukInited;
+ Playlist::State m_state;
+ MediaIndexer * m_mediaIndexer;
+ bool m_playbackInfoWritten;
+ void buildQueueFrom(int playlistRow);
+ void shuffle();
+ void orderByPlaylist();
+ void addToQueue();
+ bool m_hadVideo;
+
+ private slots:
+ void currentSourceChanged(const Phonon::MediaSource & newSource);
+ void titleChanged(int newTitle);
+ void playlistChanged();
+ void queueNextPlaylistItem();
+ void confirmPlaylistFinished();
+ void stateChanged(Phonon::State newstate, Phonon::State oldstate);
+ void updatePlaybackInfo(qint64 time);
+ void metaDataChanged();
+
+};
+#endif // PLAYLIST_H
diff --git a/src/platform/savedlistsengine.cpp b/src/platform/savedlistsengine.cpp
new file mode 100644
index 0000000..9b46a4c
--- /dev/null
+++ b/src/platform/savedlistsengine.cpp
@@ -0,0 +1,156 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "mediaitemmodel.h"
+#include "savedlistsengine.h"
+#include "listenginefactory.h"
+#include "utilities.h"
+#include "mediavocabulary.h"
+
+#include <KIcon>
+#include <KMimeType>
+#include <KStandardDirs>
+#include <KUrl>
+#include <KLocale>
+#include <KDebug>
+#include <taglib/fileref.h>
+#include <taglib/tstring.h>
+#include <id3v2tag.h>
+
+SavedListsEngine::SavedListsEngine(ListEngineFactory * parent) : ListEngine(parent)
+{
+}
+
+SavedListsEngine::~SavedListsEngine()
+{
+}
+
+void SavedListsEngine::run()
+{
+ QList<MediaItem> mediaList;
+
+
+ if (!m_mediaListProperties.engineArg().isEmpty()) {
+ QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1").arg(m_mediaListProperties.engineArg()), false));
+ if (file.exists()) {
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
+ return;
+ }
+ } else {
+ KUrl url(m_mediaListProperties.engineArg());
+ file.setFileName(url.path());
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
+ return;
+ }
+ }
+
+ //Make sure it's a valid M3U fileref
+ QTextStream in(&file);
+ bool valid = false;
+ bool isM3U = false;
+ bool isPLS = false;
+ if (!in.atEnd()) {
+ QString line = in.readLine();
+ if (line.trimmed() == "#EXTM3U") {
+ valid = true;
+ isM3U = true;
+ } else if (line.trimmed() == "[playlist]") {
+ valid = true;
+ isPLS = true;
+ }
+ }
+
+ //Create a MediaItem for each entry
+ if (valid) {
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ if ((isM3U) && line.startsWith("#EXTINF:")) {
+ line = line.replace("#EXTINF:","");
+ QStringList durTitle = line.split(",");
+ QString title;
+ int duration;
+ if (durTitle.count() == 1) {
+ //No title
+ duration = 0;
+ title = durTitle.at(0);
+ } else {
+ duration = durTitle.at(0).toInt();
+ title = durTitle.at(1);
+ }
+ QString url = in.readLine().trimmed();
+ MediaItem mediaItem;
+ if (!url.isEmpty()) {
+ mediaItem = Utilities::mediaItemFromUrl(KUrl(url));
+ } else {
+ continue;
+ }
+ if ((!mediaItem.title.isEmpty()) && (url.contains(mediaItem.title))) {
+ mediaItem.title = title;
+ }
+ if ((duration > 0) && (mediaItem.fields["duration"].toInt() <= 0)) {
+ mediaItem.duration = QTime(0,0,0,0).addSecs(duration).toString("m:ss");
+ mediaItem.fields["duration"] = duration;
+ } else if (duration == -1) {
+ mediaItem.duration = QString();
+ mediaItem.fields["audioType"] = "Audio Stream";
+ }
+ mediaList << mediaItem;
+ }
+ if ((isPLS) && line.startsWith("File")) {
+ QString url = line.mid(line.indexOf("=") + 1).trimmed();
+ QString title;
+ if (!in.atEnd()) {
+ line = in.readLine();
+ title = line.mid(line.indexOf("=") + 1).trimmed();
+ }
+ int duration = 0;
+ if (!in.atEnd()) {
+ line = in.readLine();
+ duration = line.mid(line.indexOf("=") + 1).trimmed().toInt();
+ }
+
+ MediaItem mediaItem;
+ if (!url.isEmpty()) {
+ mediaItem = Utilities::mediaItemFromUrl(KUrl(url));
+ } else {
+ continue;
+ }
+ if ((!mediaItem.title.isEmpty()) && (url.contains(mediaItem.title))) {
+ mediaItem.title = title;
+ }
+ if ((duration > 0) && (mediaItem.fields["duration"].toInt() <= 0)) {
+ mediaItem.duration = QTime(0,0,0,0).addSecs(duration).toString("m:ss");
+ mediaItem.fields["duration"] = duration;
+ } else if (duration == -1) {
+ mediaItem.duration = QString();
+ mediaItem.fields["audioType"] = "Audio Stream";
+ }
+ mediaList << mediaItem;
+ }
+ }
+ }
+
+ }
+
+ m_mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
+ model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
+ m_requestSignature = QString();
+ m_subRequestSignature = QString();
+}
diff --git a/platform/savedlistsengine.h b/src/platform/savedlistsengine.h
similarity index 92%
rename from platform/savedlistsengine.h
rename to src/platform/savedlistsengine.h
index cb87214..cba5767 100644
--- a/platform/savedlistsengine.h
+++ b/src/platform/savedlistsengine.h
@@ -33,6 +33,11 @@ class MediaListProperties;
class ListEngineFactory;
class MediaIndexer;
+/**
+* This ListEngine retrieves saved media lists.
+* List Resource Identifiers handled are:
+* savedlists://[name]
+*/
class SavedListsEngine : public ListEngine
{
Q_OBJECT
diff --git a/platform/semanticslistengine.cpp b/src/platform/semanticslistengine.cpp
similarity index 90%
rename from platform/semanticslistengine.cpp
rename to src/platform/semanticslistengine.cpp
index 38266b2..8735bf9 100644
--- a/platform/semanticslistengine.cpp
+++ b/src/platform/semanticslistengine.cpp
@@ -24,6 +24,7 @@
#include <KIcon>
#include <KUrl>
#include <KDebug>
+#include <KLocale>
#include <Soprano/QueryResultIterator>
#include <Soprano/Vocabulary/Xesam>
#include <Soprano/Vocabulary/NAO>
@@ -44,6 +45,10 @@ SemanticsListEngine::~SemanticsListEngine()
void SemanticsListEngine::run()
{
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+ NepomukListEngine::run();
+ return;
+ }
//Create media list based on engine argument and filter
QList<MediaItem> mediaList;
@@ -70,6 +75,7 @@ void SemanticsListEngine::run()
query.selectPlayCount();
query.selectLastPlayed(true);
query.orderBy("DESC(?playcount) DESC(?lastplayed)");
+
Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
//Build media list from results
@@ -81,7 +87,7 @@ void SemanticsListEngine::run()
mediaItem.fields["description"] = mediaItem.fields["description"].toString() + QString(" - Played %1 times").arg(it.binding("playcount").literal().toInt());
mediaList.append(mediaItem);
}
- m_mediaListProperties.name = "Frequently Played";
+ m_mediaListProperties.name = i18n("Frequently Played");
m_mediaListProperties.type = QString("Sources");
}
}
@@ -107,7 +113,7 @@ void SemanticsListEngine::run()
mediaItem.fields["description"] = mediaItem.fields["description"].toString() + QString(" - Last Played: %1").arg(lastPlayed);
mediaList.append(mediaItem);
}
- m_mediaListProperties.name = "Recently Played";
+ m_mediaListProperties.name = i18n("Recently Played");
m_mediaListProperties.type = QString("Sources");
}
}
@@ -132,7 +138,7 @@ void SemanticsListEngine::run()
MediaItem mediaItem = Utilities::mediaItemFromUrl(url);
mediaList.append(mediaItem);
}
- m_mediaListProperties.name = "Highest Rated";
+ m_mediaListProperties.name = i18n("Highest Rated");
m_mediaListProperties.type = QString("Sources");
}
}
@@ -180,15 +186,15 @@ void SemanticsQuery::selectVideoResource() {
m_selectVideoResource = true;
//NOTE: nie:url is not in any released nie ontology that I can find.
// In future KDE will use nfo:fileUrl so this will need to be changed.
- m_videoResourceCondition = QString("?r rdf:type <%1> . "
- " OPTIONAL { ?r <%2> %3 } "
- " OPTIONAL { ?r <%4> %5 } "
- " OPTIONAL { ?r nie:url ?url } . ")
- .arg(MediaVocabulary().typeVideo().toString())
- .arg(MediaVocabulary().videoIsMovie().toString())
- .arg(Soprano::Node::literalToN3(true))
- .arg(MediaVocabulary().videoIsTVShow().toString())
- .arg(Soprano::Node::literalToN3(true));
+ m_videoResourceCondition = QString(" { ?r rdf:type <%1> } "
+ " UNION "
+ " { ?r rdf:type <%2> } "
+ " UNION "
+ " { ?r rdf:type <%3> } "
+ " OPTIONAL { ?r nie:url ?url } . ")
+ .arg(MediaVocabulary().typeVideo().toString())
+ .arg(MediaVocabulary().typeVideoMovie().toString())
+ .arg(MediaVocabulary().typeVideoTVShow().toString());
}
void SemanticsQuery::selectRating(bool optional) {
@@ -251,7 +257,7 @@ QString SemanticsQuery::getPrefix() {
.arg(Soprano::Vocabulary::XMLSchema::xsdNamespace().toString());
}
-Soprano::QueryResultIterator SemanticsQuery::executeSelect(Soprano::Model* model) {
+QString SemanticsQuery::query() {
QString queryString = getPrefix();
queryString += "SELECT ";
@@ -279,6 +285,11 @@ Soprano::QueryResultIterator SemanticsQuery::executeSelect(Soprano::Model* model
queryString += m_order;
queryString += " LIMIT 20 ";
+ return queryString;
+}
+
+Soprano::QueryResultIterator SemanticsQuery::executeSelect(Soprano::Model* model) {
+ QString queryString = query();
return model->executeQuery(queryString,
Soprano::Query::QueryLanguageSparql);
}
diff --git a/platform/semanticslistengine.h b/src/platform/semanticslistengine.h
similarity index 85%
rename from platform/semanticslistengine.h
rename to src/platform/semanticslistengine.h
index a905eed..2247380 100644
--- a/platform/semanticslistengine.h
+++ b/src/platform/semanticslistengine.h
@@ -27,6 +27,32 @@ class MediaItem;
class MediaListProperties;
class ListEngineFactory;
+/**
+ * This class retrieves a list of MediaItems based on
+ * playback semantics in the nepomuk data store.
+ * e.g. Highest rated, Frequently played, etc.
+ * List Resource Identifiers handled are:
+ * semantics://frequent?audio
+ * semantics://frequent?video
+ * semantics://recent?audio
+ * semantics://recent?video
+ * semantics://highest?audio
+ * semantics://highest?video
+ */
+class SemanticsListEngine : public NepomukListEngine
+{
+ Q_OBJECT
+
+ public:
+ SemanticsListEngine(ListEngineFactory *parent);
+ ~SemanticsListEngine();
+ void run();
+
+ Q_SIGNALS:
+ void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
+
+};
+
class SemanticsQuery {
public:
SemanticsQuery(bool distinct = true);
@@ -41,7 +67,7 @@ class SemanticsQuery {
void orderBy(QString var);
-
+ QString query();
Soprano::QueryResultIterator executeSelect(Soprano::Model* model);
bool executeAsk(Soprano::Model* model);
@@ -67,18 +93,5 @@ class SemanticsQuery {
QString getPrefix();
};
-class SemanticsListEngine : public NepomukListEngine
-{
- Q_OBJECT
-
- public:
- SemanticsListEngine(ListEngineFactory *parent);
- ~SemanticsListEngine();
- void run();
-
- Q_SIGNALS:
- void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
-
-};
#endif // SEMANTICSLISTENGINE_H
diff --git a/platform/utilities.cpp b/src/platform/utilities.cpp
similarity index 65%
rename from platform/utilities.cpp
rename to src/platform/utilities.cpp
index ddae998..6839922 100644
--- a/platform/utilities.cpp
+++ b/src/platform/utilities.cpp
@@ -21,6 +21,7 @@
#include "mediavocabulary.h"
#include <KUrl>
+#include <KEncodingProber>
#include <KMimeType>
#include <KIcon>
#include <KIconEffect>
@@ -39,6 +40,7 @@
#include <QPainter>
#include <QImage>
#include <QTime>
+#include <Phonon/BackendCapabilities>
#include <taglib/mpegfile.h>
#include <taglib/fileref.h>
@@ -49,7 +51,7 @@
QPixmap Utilities::getArtworkFromTag(QString url, QSize size)
{
- TagLib::MPEG::File mpegFile(KUrl(url).path().toUtf8());
+ TagLib::MPEG::File mpegFile(KUrl(url).path().toLocal8Bit());
TagLib::ID3v2::Tag *id3tag = mpegFile.ID3v2Tag(false);
if (!id3tag) {
@@ -91,7 +93,7 @@ QString Utilities::getArtistFromTag(QString url)
{
QString artist;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
artist = TStringToQString(file.tag()->artist()).trimmed();
}
return artist;
@@ -101,7 +103,7 @@ QString Utilities::getAlbumFromTag(QString url)
{
QString album;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
album = TStringToQString(file.tag()->album()).trimmed();
}
return album;
@@ -111,7 +113,7 @@ QString Utilities::getTitleFromTag(QString url)
{
QString title;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
title = TStringToQString(file.tag()->title()).trimmed();
}
return title;
@@ -121,7 +123,7 @@ QString Utilities::getGenreFromTag(QString url)
{
QString genre;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
genre = TStringToQString(file.tag()->genre()).trimmed();
}
return genre;
@@ -131,7 +133,7 @@ int Utilities::getYearFromTag(QString url)
{
int year = 0;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
year = file.tag()->year();
}
return year;
@@ -141,7 +143,7 @@ int Utilities::getDurationFromTag(QString url)
{
int duration = 0;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
duration = file.audioProperties()->length();
}
return duration;
@@ -151,7 +153,7 @@ int Utilities::getTrackNumberFromTag(QString url)
{
int track = 0;
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
track = file.tag()->track();
}
return track;
@@ -160,7 +162,7 @@ int Utilities::getTrackNumberFromTag(QString url)
bool Utilities::saveArtworkToTag(QString url, const QPixmap *pixmap)
{
//FIXME:: HELP! Can't figure out why this doesn't work
- TagLib::MPEG::File mpegFile(KUrl(url).path().toUtf8());
+ TagLib::MPEG::File mpegFile(KUrl(url).path().toLocal8Bit());
TagLib::ID3v2::Tag *id3tag = mpegFile.ID3v2Tag(true);
TagLib::ID3v2::AttachedPictureFrame *frame = Utilities::attachedPictureFrame(id3tag, true);
@@ -181,7 +183,7 @@ bool Utilities::saveArtworkToTag(QString url, const QPixmap *pixmap)
bool Utilities::saveArtworkToTag(QString url, QString imageurl)
{
//QByteArray filePath = QFile::encodeName(KUrl(url).path());
- TagLib::MPEG::File mpegFile(KUrl(url).path().toUtf8());
+ TagLib::MPEG::File mpegFile(KUrl(url).path().toLocal8Bit());
TagLib::ID3v2::Tag *id3tag = mpegFile.ID3v2Tag(true);
TagLib::ID3v2::AttachedPictureFrame *frame = Utilities::attachedPictureFrame(id3tag, true);
@@ -203,7 +205,7 @@ void Utilities::setArtistTag(QString url, QString artist)
{
if (Utilities::isMusic(url)) {
TagLib::String tArtist(artist.trimmed().toUtf8().data(), TagLib::String::UTF8);
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setArtist(tArtist);
file.save();
}
@@ -213,7 +215,7 @@ void Utilities::setAlbumTag(QString url, QString album)
{
if (Utilities::isMusic(url)) {
TagLib::String tAlbum(album.trimmed().toUtf8().data(), TagLib::String::UTF8);
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setAlbum(tAlbum);
file.save();
}
@@ -223,7 +225,7 @@ void Utilities::setTitleTag(QString url, QString title)
{
if (Utilities::isMusic(url)) {
TagLib::String tTitle(title.trimmed().toUtf8().data(), TagLib::String::UTF8);
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setTitle(tTitle);
file.save();
}
@@ -233,7 +235,7 @@ void Utilities::setGenreTag(QString url, QString genre)
{
if (Utilities::isMusic(url)) {
TagLib::String tGenre(genre.trimmed().toUtf8().data(), TagLib::String::UTF8);
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setGenre(tGenre);
file.save();
}
@@ -242,7 +244,7 @@ void Utilities::setGenreTag(QString url, QString genre)
void Utilities::setYearTag(QString url, int year)
{
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setYear(year);
file.save();
}
@@ -251,7 +253,7 @@ void Utilities::setYearTag(QString url, int year)
void Utilities::setTrackNumberTag(QString url, int trackNumber)
{
if (Utilities::isMusic(url)) {
- TagLib::FileRef file(KUrl(url).path().toUtf8());
+ TagLib::FileRef file(KUrl(url).path().toLocal8Bit());
file.tag()->setTrack(trackNumber);
file.save();
}
@@ -277,6 +279,20 @@ bool Utilities::isVideo(QString url)
return result->is("video/mp4") || result->is("video/mpeg") || result->is("video/ogg") || result->is("video/quicktime") || result->is("video/msvideo") || result->is("video/x-theora")|| result->is("video/x-theora+ogg") || result->is("video/x-ogm")|| result->is("video/x-ogm+ogg") || result->is("video/divx") || result->is("video/x-msvideo") || result->is("video/x-wmv") || result->is("video/x-flv") || result->is("video/x-flv");
}
+bool Utilities::isM3u(QString url)
+{
+ KMimeType::Ptr result = KMimeType::findByUrl(KUrl(url), 0, true);
+
+ return result->is("audio/m3u") || result->is("audio/x-mpegurl");
+}
+
+bool Utilities::isPls(QString url)
+{
+ KMimeType::Ptr result = KMimeType::findByUrl(KUrl(url), 0, true);
+
+ return result->is("audio/x-scpls");
+}
+
QPixmap Utilities::reflection(QPixmap &pixmap)
{
QMatrix flipMatrix;
@@ -313,6 +329,15 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
MediaItem mediaItem;
url.cleanPath();
url = QUrl::fromPercentEncoding(url.url().toUtf8());
+
+ if (Utilities::isM3u(url.url()) || Utilities::isPls(url.url())) {
+ mediaItem.artwork = KIcon("view-list-text");
+ mediaItem.url = QString("savedlists://%1").arg(url.url());
+ mediaItem.title = url.fileName();
+ mediaItem.type = "Category";
+ return mediaItem;
+ }
+
mediaItem.url = url.url();
mediaItem.title = url.fileName();
mediaItem.fields["url"] = mediaItem.url;
@@ -336,11 +361,13 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
}
foundInNepomuk = true;
}
- if (res.hasType(mediaVocabulary.typeVideo())) {
+ if (res.hasType(mediaVocabulary.typeVideo()) ||
+ res.hasType(mediaVocabulary.typeVideoMovie()) ||
+ res.hasType(mediaVocabulary.typeVideoTVShow())) {
mediaItem.type = "Video";
- if (res.property(mediaVocabulary.videoIsMovie()).toBool()) {
+ if (res.hasType(mediaVocabulary.typeVideoMovie())) {
mediaItem.fields["videoType"] = "Movie";
- } else if (res.property(mediaVocabulary.videoIsTVShow()).toBool()) {
+ } else if (res.hasType(mediaVocabulary.typeVideoTVShow())) {
mediaItem.fields["videoType"] = "TV Show";
} else {
mediaItem.fields["videoType"] = "Video Clip";
@@ -348,6 +375,9 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
foundInNepomuk = true;
}
if (foundInNepomuk) {
+ if (mediaItem.type == "Video") {
+ mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ }
// Get metadata common to all media types
QString title = res.property(mediaVocabulary.title()).toString();
if (!title.isEmpty()) {
@@ -389,6 +419,11 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
mediaItem.type = "Video";
mediaItem.fields["videoType"] = "Video Clip";
}
+ if (!url.isLocalFile()) {
+ mediaItem.type = "Audio";
+ mediaItem.fields["audioType"] = "Audio Stream";
+ mediaItem.title = url.prettyUrl();
+ }
}
if (mediaItem.type == "Audio") {
@@ -397,12 +432,37 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
} else if (mediaItem.fields["audioType"] == "Music") {
mediaItem.artwork = KIcon("audio-mp4");
//File metadata is always primary for music items.
- TagLib::FileRef file(KUrl(mediaItem.url).path().toUtf8());
+ TagLib::FileRef file(KUrl(mediaItem.url).path().toLocal8Bit());
if (!file.isNull()) {
QString title = TStringToQString(file.tag()->title()).trimmed();
QString artist = TStringToQString(file.tag()->artist()).trimmed();
QString album = TStringToQString(file.tag()->album()).trimmed();
QString genre = TStringToQString(file.tag()->genre()).trimmed();
+ if (KUrl(mediaItem.url).path().endsWith(".mp3")) {
+ // detect encoding for mpeg id3v2
+ QString tmp = title + artist + album + genre;
+ KEncodingProber prober(KEncodingProber::Universal);
+ KEncodingProber::ProberState result = prober.feed(tmp.toAscii());
+ if (result != KEncodingProber::NotMe) {
+ QByteArray encodingname = prober.encoding();
+ QString track_encoding(encodingname);
+ if ( ( track_encoding.toLatin1() == "gb18030" )
+ || ( track_encoding.toLatin1() == "big5" )
+ || ( track_encoding.toLatin1() == "euc-kr" )
+ || ( track_encoding.toLatin1() == "euc-jp" )
+ || ( track_encoding.toLatin1() == "koi8-r" ) ) {
+ title = QTextCodec::codecForName(encodingname)->toUnicode(title.toAscii());
+ artist = QTextCodec::codecForName(encodingname)->toUnicode(artist.toAscii());
+ album = QTextCodec::codecForName(encodingname)->toUnicode(album.toAscii());
+ genre = QTextCodec::codecForName(encodingname)->toUnicode(genre.toAscii());
+ } else if (QTextCodec::codecForLocale()->name().toLower() != "utf-8") {
+ title = QTextCodec::codecForLocale()->toUnicode(title.toAscii());
+ artist = QTextCodec::codecForLocale()->toUnicode(artist.toAscii());
+ album = QTextCodec::codecForLocale()->toUnicode(album.toAscii());
+ genre = QTextCodec::codecForLocale()->toUnicode(genre.toAscii());
+ }
+ }
+ }
int track = file.tag()->track();
int duration = file.audioProperties()->length();
int year = file.tag()->year();
@@ -428,56 +488,102 @@ MediaItem Utilities::mediaItemFromUrl(KUrl url)
} else if (mediaItem.fields["videoType"] == "Movie") {
mediaItem.artwork = KIcon("tool-animator");
Nepomuk::Resource res(mediaItem.url);
- QString seriesName = res.property(mediaVocabulary.videoSeriesName()).toString();
- if (!seriesName.isEmpty()) {
- mediaItem.fields["seriesName"] = seriesName;
- mediaItem.subTitle = seriesName;
+ QString synopsis = res.property(mediaVocabulary.videoSynopsis()).toString();
+ if (!synopsis.isEmpty()) {
+ mediaItem.fields["synopsis"] = synopsis;
}
- QString genre = res.property(mediaVocabulary.genre()).toString();
+ QString genre = res.property(mediaVocabulary.videoGenre()).toString();
if (!genre.isEmpty()) {
mediaItem.fields["genre"] = genre;
}
- QDate created = res.property(mediaVocabulary.created()).toDate();
- if (created.isValid()) {
- mediaItem.fields["year"] = created.year();
+ QDate releaseDate = res.property(mediaVocabulary.releaseDate()).toDate();
+ if (releaseDate.isValid()) {
+ mediaItem.fields["releaseDate"] = releaseDate;
+ }
+ QString writer = res.property(mediaVocabulary.videoWriter()).toString();
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = writer;
+ }
+ QString director = res.property(mediaVocabulary.videoDirector()).toString();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
+ }
+ QString assistantDirector = res.property(mediaVocabulary.videoAssistantDirector()).toString();
+ if (!assistantDirector.isEmpty()) {
+ mediaItem.fields["assistantDirector"] = assistantDirector;
+ }
+ QString producer = res.property(mediaVocabulary.videoProducer()).toString();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+ QString actor = res.property(mediaVocabulary.videoActor()).toString();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
+ }
+ QString cinematographer = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!cinematographer.isEmpty()) {
+ mediaItem.fields["cinematographer"] = cinematographer;
}
} else if (mediaItem.fields["videoType"] == "TV Show") {
mediaItem.artwork = KIcon("video-television");
Nepomuk::Resource res(mediaItem.url);
- QString seriesName = res.property(mediaVocabulary.videoSeriesName()).toString();
+ Nepomuk::Resource series = res.property(mediaVocabulary.videoSeries()).toResource();
+ QString seriesName = series.property(mediaVocabulary.title()).toString();
if (!seriesName.isEmpty()) {
mediaItem.fields["seriesName"] = seriesName;
mediaItem.subTitle = seriesName;
}
- int season = res.property(mediaVocabulary.videoSeriesSeason()).toInt();
+ int season = res.property(mediaVocabulary.videoSeason()).toInt();
if (season !=0 ) {
mediaItem.fields["season"] = season;
if (!mediaItem.subTitle.isEmpty()) {
- mediaItem.subTitle = QString("%1 - Season %2")
- .arg(mediaItem.subTitle)
- .arg(season);
- } else {
- mediaItem.subTitle = QString("Season %1").arg(season);
+ mediaItem.subTitle += " - ";
}
+ mediaItem.subTitle += QString("Season %1").arg(season);
}
- int episode = res.property(mediaVocabulary.videoSeriesEpisode()).toInt();
- if (episode !=0 ) {
- mediaItem.fields["episode"] = episode;
+ int episodeNumber = res.property(mediaVocabulary.videoEpisodeNumber()).toInt();
+ if (episodeNumber !=0 ) {
+ mediaItem.fields["episodeNumber"] = episodeNumber;
if (!mediaItem.subTitle.isEmpty()) {
- mediaItem.subTitle = QString("%1 - Episode %2")
- .arg(mediaItem.subTitle)
- .arg(episode);
- } else {
- mediaItem.subTitle = QString("Episode %2").arg(episode);
+ mediaItem.subTitle += " - ";
}
+ mediaItem.subTitle += QString("Episode %1").arg(episodeNumber);
+ }
+ QString synopsis = res.property(mediaVocabulary.videoSynopsis()).toString();
+ if (!synopsis.isEmpty()) {
+ mediaItem.fields["synopsis"] = synopsis;
}
- QString genre = res.property(mediaVocabulary.genre()).toString();
+ QString genre = res.property(mediaVocabulary.videoGenre()).toString();
if (!genre.isEmpty()) {
mediaItem.fields["genre"] = genre;
}
- QDate created = res.property(mediaVocabulary.created()).toDate();
- if (created.isValid()) {
- mediaItem.fields["year"] = created.year();
+ QDate releaseDate = res.property(mediaVocabulary.releaseDate()).toDate();
+ if (releaseDate.isValid()) {
+ mediaItem.fields["releaseDate"] = releaseDate;
+ }
+ QString writer = res.property(mediaVocabulary.videoWriter()).toString();
+ if (!writer.isEmpty()) {
+ mediaItem.fields["writer"] = writer;
+ }
+ QString director = res.property(mediaVocabulary.videoDirector()).toString();
+ if (!director.isEmpty()) {
+ mediaItem.fields["director"] = director;
+ }
+ QString assistantDirector = res.property(mediaVocabulary.videoAssistantDirector()).toString();
+ if (!assistantDirector.isEmpty()) {
+ mediaItem.fields["assistantDirector"] = assistantDirector;
+ }
+ QString producer = res.property(mediaVocabulary.videoProducer()).toString();
+ if (!producer.isEmpty()) {
+ mediaItem.fields["producer"] = producer;
+ }
+ QString actor = res.property(mediaVocabulary.videoActor()).toString();
+ if (!actor.isEmpty()) {
+ mediaItem.fields["actor"] = actor;
+ }
+ QString cinematographer = res.property(mediaVocabulary.videoGenre()).toString();
+ if (!cinematographer.isEmpty()) {
+ mediaItem.fields["cinematographer"] = cinematographer;
}
}
}
@@ -607,10 +713,42 @@ QList<MediaItem> Utilities::mediaItemsDontExist(QList<MediaItem> mediaList)
QString Utilities::audioMimeFilter()
{
- return QString("audio/mpeg audio/mp4 audio/ogg audio/vorbis audio/aac audio/aiff audio/basic audio/flac audio/mp2 audio/mp3 audio/vnd.rn-realaudio audio/wav application/ogg audio/x-flac audio/x-musepack");
+ QStringList supportedList = Phonon::BackendCapabilities::availableMimeTypes().filter("audio");
+ QStringList appList = Phonon::BackendCapabilities::availableMimeTypes().filter("application");
+ QStringList ambiguousList;
+ for (int i = 0; i < appList.count(); i++) {
+ if (!appList.at(i).contains("video") && !appList.at(i).contains("audio")) {
+ ambiguousList.append(appList.at(i));
+ }
+ }
+ supportedList << ambiguousList;
+ supportedList << "audio/m3u" << "audio/x-mpegurl" << "audio/x-scpls"; //add playlist mimetypes
+ return supportedList.join(" ");
+ /* This section might be useful if Phonon doesn't report
+ * supported mimetypes correctly. For now I'll assume it
+ * does so it is disabled. */
+ /*QString mimeFilter = QString("audio/mpeg audio/mp4 audio/ogg audio/vorbis audio/aac audio/aiff audio/basic audio/flac audio/mp2 audio/mp3 audio/vnd.rn-realaudio audio/wav application/ogg audio/x-flac audio/x-musepack ");
+ mimeFilter += supportedList.join(" ");
+ return mimeFilter;*/
}
QString Utilities::videoMimeFilter()
{
- return QString("video/mp4 video/mpeg video/ogg video/quicktime video/msvideo video/x-theora video/x-theora+ogg video/x-ogm video/x-ogm+ogg video/divx video/x-msvideo video/x-wmv video/x-flv video/flv");
+ QStringList supportedList = Phonon::BackendCapabilities::availableMimeTypes().filter("video");
+ QStringList appList = Phonon::BackendCapabilities::availableMimeTypes().filter("application");
+ QStringList ambiguousList;
+ for (int i = 0; i < appList.count(); i++) {
+ if (!appList.at(i).contains("video") && !appList.at(i).contains("audio")) {
+ ambiguousList.append(appList.at(i));
+ }
+ }
+ supportedList << ambiguousList;
+ return supportedList.join(" ");
+
+ /* This section might be useful if Phonon doesn't report
+ * supported mimetypes correctly. For now I'll assume it
+ * does so it is disabled. */
+ /*QString mimeFilter = QString("video/mp4 video/mpeg video/ogg video/quicktime video/msvideo video/x-theora video/x-theora+ogg video/x-ogm video/x-ogm+ogg video/divx video/x-msvideo video/x-wmv video/x-flv video/flv");
+ mimeFilter += supportedList.join(" ");
+ return mimeFilter;*/
}
diff --git a/platform/utilities.h b/src/platform/utilities.h
similarity index 93%
rename from platform/utilities.h
rename to src/platform/utilities.h
index df7dd3f..05ab4fd 100644
--- a/platform/utilities.h
+++ b/src/platform/utilities.h
@@ -27,6 +27,11 @@
class MediaItem;
+
+/**
+ * This namespace provides a list of convenience functions
+ * used throughout bangarang.
+ */
namespace Utilities {
QPixmap getArtworkFromTag(QString url, QSize size = QSize(128,128));
QPixmap getArtworkFromMediaItem(MediaItem mediaItem);
@@ -49,6 +54,8 @@ namespace Utilities {
bool isMusic(QString url);
bool isAudio(QString url);
bool isVideo(QString url);
+ bool isM3u(QString url);
+ bool isPls(QString url);
QPixmap reflection(QPixmap &pixmap);
void shadowBlur(QImage &image, int radius, const QColor &color);
MediaItem mediaItemFromUrl(KUrl url);
diff --git a/src/platform/videolistengine.cpp b/src/platform/videolistengine.cpp
new file mode 100644
index 0000000..2bb1fd8
--- /dev/null
+++ b/src/platform/videolistengine.cpp
@@ -0,0 +1,1017 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "mediaitemmodel.h"
+#include "videolistengine.h"
+#include "listenginefactory.h"
+#include "mediavocabulary.h"
+#include "utilities.h"
+
+#include <Soprano/QueryResultIterator>
+#include <Soprano/Vocabulary/Xesam>
+#include <Soprano/Vocabulary/RDF>
+#include <Soprano/Vocabulary/XMLSchema>
+#include <Soprano/Vocabulary/NAO>
+#include <QApplication>
+#include <KIcon>
+#include <KUrl>
+#include <KLocale>
+#include <KDebug>
+#include <taglib/fileref.h>
+#include <QTime>
+#include <nepomuk/variant.h>
+
+
+VideoListEngine::VideoListEngine(ListEngineFactory * parent) : NepomukListEngine(parent)
+{
+}
+
+VideoListEngine::~VideoListEngine()
+{
+}
+
+MediaItem VideoListEngine::createMediaItem(Soprano::QueryResultIterator& it) {
+ MediaVocabulary mediaVocabulary;
+ mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ mediaVocabulary.setVideoVocabulary(MediaVocabulary::nmm);
+
+ MediaItem mediaItem;
+ QUrl url = it.binding("url").uri().isEmpty() ?
+ it.binding("r").uri() :
+ it.binding("url").uri();
+ mediaItem.url = url.toString();
+
+ mediaItem.fields["videoType"] = "Video Clip";
+ mediaItem.artwork = KIcon("video-x-generic");
+
+ Nepomuk::Resource res(url.toString());
+ if (res.exists()) {
+ if (res.hasType(mediaVocabulary.typeVideoMovie())) {
+ mediaItem.fields["videoType"] = "Movie";
+ mediaItem.artwork = KIcon("tool-animator");
+ }
+ if (res.hasType(mediaVocabulary.typeVideoTVShow())) {
+ mediaItem.fields["videoType"] = "TV Show";
+ mediaItem.artwork = KIcon("video-television");
+ }
+ }
+
+ mediaItem.title = it.binding("title").literal().toString();
+ if (mediaItem.title.isEmpty()) {
+ if (KUrl(mediaItem.url).isLocalFile()) {
+ mediaItem.title = KUrl(mediaItem.url).fileName();
+ } else {
+ mediaItem.title = mediaItem.url;
+ }
+ }
+ int duration = it.binding("duration").literal().toInt();
+ if (duration != 0) {
+ mediaItem.duration = QTime(0,0,0,0).addSecs(duration).toString("m:ss");
+ }
+
+ QString seriesName = it.binding("seriesName").literal().toString();
+ if (!seriesName.isEmpty()) {
+ mediaItem.fields["seriesName"] = seriesName;
+ mediaItem.subTitle = seriesName;
+ }
+
+ int season = it.binding("season").literal().toInt();
+ if (season !=0 ) {
+ mediaItem.fields["season"] = season;
+ if (!mediaItem.subTitle.isEmpty()) {
+ mediaItem.subTitle += " - ";
+ }
+ mediaItem.subTitle += QString("Season %1").arg(season);
+ }
+
+ int episodeNumber = it.binding("episodeNumber").literal().toInt();
+ if (episodeNumber != 0) {
+ mediaItem.fields["episodeNumber"] = episodeNumber;
+ if (!mediaItem.subTitle.isEmpty()) {
+ mediaItem.subTitle += " - ";
+ }
+ mediaItem.subTitle += QString("Episode %1").arg(episodeNumber);
+ }
+
+ if (it.binding("created").isValid()) {
+ QDate created = it.binding("created").literal().toDate();
+ if (created.isValid()) {
+ mediaItem.fields["year"] = created.year();
+ }
+ }
+ if (it.binding("releaseDate").isValid()) {
+ QDate releaseDate = it.binding("releaseDate").literal().toDate();
+ if (releaseDate.isValid()) {
+ mediaItem.fields["releaseDate"] = releaseDate;
+ mediaItem.fields["year"] = releaseDate.year();
+ }
+ }
+
+ mediaItem.type = "Video";
+ mediaItem.nowPlaying = false;
+ mediaItem.fields["url"] = mediaItem.url;
+ mediaItem.fields["title"] = it.binding("title").literal().toString();
+ mediaItem.fields["duration"] = it.binding("duration").literal().toInt();
+ mediaItem.fields["description"] = it.binding("description").literal().toString();
+ mediaItem.fields["synopsis"] = it.binding("synopsis").literal().toString();
+ mediaItem.fields["genre"] = it.binding("genre").literal().toString();
+ mediaItem.fields["artworkUrl"] = it.binding("artwork").uri().toString();
+ mediaItem.fields["rating"] = it.binding("rating").literal().toInt();
+ mediaItem.fields["writer"] = it.binding("writer").literal().toString();
+ mediaItem.fields["director"] = it.binding("director").literal().toString();
+ mediaItem.fields["assistantDirector"] = it.binding("assistantDirector").literal().toString();
+ mediaItem.fields["producer"] = it.binding("producer").literal().toString();
+ mediaItem.fields["actor"] = it.binding("actor").literal().toString();
+ mediaItem.fields["cinematographer"] = it.binding("cinematographer").literal().toString();
+
+ return mediaItem;
+}
+
+
+void VideoListEngine::run()
+{
+
+ if (m_updateSourceInfo || m_removeSourceInfo) {
+ NepomukListEngine::run();
+ return;
+ }
+
+ //Create media list based on engine argument and filter
+ QList<MediaItem> mediaList;
+
+ MediaVocabulary mediaVocabulary = MediaVocabulary();
+
+ QString engineArg = m_mediaListProperties.engineArg();
+ //Parse filter
+ //Engine filter format:
+ // searchTerm||genre||seriesName||season||episode
+ QString engineFilter = m_mediaListProperties.engineFilter();
+ QString searchTerm;
+ QString genre;
+ QString seriesName;
+ int season = 0;
+ int episode = 0;
+
+ if (!engineFilter.isEmpty()) {
+ QStringList argList = engineFilter.split("||");
+ searchTerm = argList.at(0);
+ if (argList.count() >= 2) {
+ genre = argList.at(1);
+ }
+ if (argList.count() >= 3) {
+ seriesName = argList.at(2);
+ }
+ if (argList.count() >= 4) {
+ season = argList.at(3).toInt();
+ }
+ if (argList.count() >= 5) {
+ episode = argList.at(4).toInt();
+ }
+ }
+
+ if (m_nepomukInited) {
+ if (engineArg.toLower() == "clips") {
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.selectVideoResource();
+ videoQuery.selectTitle(true);
+ videoQuery.selectDuration(true);
+ videoQuery.selectSeason(true);
+ videoQuery.selectDescription(true);
+ videoQuery.orderBy("?title");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ MediaItem mediaItem = createMediaItem(it);
+
+ mediaItem.artwork = KIcon("video-x-generic");
+ mediaItem.fields["videoType"] = "Video Clip";
+ mediaList.append(mediaItem);
+ }
+
+ m_mediaListProperties.name = i18n("Video Clips");
+ m_mediaListProperties.summary = i18np("1 clip", "%1 clips", mediaList.count());
+ m_mediaListProperties.type = QString("Sources");
+ } else if (engineArg.toLower() == "tvshows") {
+ VideoQuery query = VideoQuery(true);
+ query.isTVShow();
+ query.selectSeriesName();
+ if (!genre.isEmpty()) {
+ query.hasGenre(genre);
+ }
+ query.orderBy("?seriesName");
+
+ Soprano::QueryResultIterator it = query.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ QString seriesName = it.binding("seriesName").literal().toString();
+ if (!seriesName.isEmpty()) {
+ MediaItem mediaItem;
+ mediaItem.url = QString("video://seasons?||%1||%2").arg(genre).arg(seriesName);
+ mediaItem.title = seriesName;
+ mediaItem.type = QString("Category");
+ mediaItem.nowPlaying = false;
+ mediaItem.artwork = KIcon("video-television");
+ mediaList.append(mediaItem);
+ }
+ }
+
+
+ /* Check, whether there are videos which have the TV show flag set,
+ * but no series name is entered. If so, add an entry which allows
+ * access to those files. Only do so if no category (Genre) is
+ * specified.
+ */
+ if (genre.isEmpty()) {
+ VideoQuery noSeriesQuery = VideoQuery();
+ noSeriesQuery.isTVShow();
+ noSeriesQuery.hasNoSeriesName();
+
+ if(noSeriesQuery.executeAsk(m_mainModel)) {
+ MediaItem mediaItem;
+ mediaItem.url = QString("video://episodes?||||~");
+ mediaItem.title = i18n("Uncategorized TV Shows");
+ mediaItem.type = QString("Category");
+ mediaItem.nowPlaying = false;
+ mediaItem.artwork = KIcon("video-television");
+ mediaList.append(mediaItem);
+ }
+ }
+
+ m_mediaListProperties.name = i18n("TV Shows");
+ m_mediaListProperties.summary = i18np("1 show", "%1 shows", mediaList.count());
+ m_mediaListProperties.type = QString("Categories");
+ } else if (engineArg.toLower() == "seasons") {
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.isTVShow();
+ videoQuery.selectSeason();
+ if (!genre.isEmpty()) {
+ if (genre == "~") genre = QString();
+ videoQuery.hasGenre(genre);
+ }
+ if (!seriesName.isEmpty()) {
+ if (seriesName != "~") {
+ videoQuery.hasSeriesName(seriesName);
+ } else {
+ videoQuery.hasNoSeriesName();
+ }
+ }
+ videoQuery.orderBy("?season");
+
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ int season = it.binding("season").literal().toInt();
+ MediaItem mediaItem;
+ mediaItem.url = QString("video://episodes?||%1||%2||%3")
+ .arg(genre).arg(seriesName).arg(season);
+ mediaItem.title = seriesName;
+ mediaItem.subTitle = i18n("Season %1", season);
+ mediaItem.type = QString("Category");
+ mediaItem.nowPlaying = false;
+ mediaItem.artwork = KIcon("video-television");
+ mediaList.append(mediaItem);
+ }
+
+ /* Check, whether there are TV shows, which have no series entered.
+ * If so, add an entry which allows access to those files.
+ */
+ VideoQuery noSeasonsQuery = VideoQuery();
+ noSeasonsQuery.isTVShow();
+ noSeasonsQuery.hasSeriesName(seriesName);
+ noSeasonsQuery.hasNoSeason();
+
+ if(noSeasonsQuery.executeAsk(m_mainModel)) {
+ MediaItem mediaItem;
+ mediaItem.url = QString("video://episodes?||%1||%2||-1").arg(genre).arg(seriesName);
+ mediaItem.title = seriesName;
+ mediaItem.subTitle = i18n("Uncategorized seasons");
+ mediaItem.type = QString("Category");
+ mediaItem.nowPlaying = false;
+ mediaItem.artwork = KIcon("video-television");
+ mediaList.append(mediaItem);
+ }
+
+ m_mediaListProperties.name = i18n("Seasons - %1", seriesName);
+ m_mediaListProperties.summary = i18np("1 season", "%1 seasons", mediaList.count());
+
+ m_mediaListProperties.type = QString("Categories");
+ } else if (engineArg.toLower() == "episodes") {
+ bool hasSeason = false;
+
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.selectTVShowResource();
+ videoQuery.selectTitle();
+ videoQuery.selectSeriesName(true);
+ videoQuery.selectSeason(true);
+ if (!genre.isEmpty()) {
+ if (genre == "~") genre = QString();
+ videoQuery.hasGenre(genre);
+ }
+ if (!seriesName.isEmpty()) {
+ if (seriesName != "~") {
+ videoQuery.hasSeriesName(seriesName);
+ } else {
+ videoQuery.hasNoSeriesName();
+ }
+ }
+ if (season > 0) {
+ videoQuery.hasSeason(season);
+ hasSeason = true;
+ } else if (season == -1) {
+ videoQuery.hasNoSeason();
+ }
+ videoQuery.selectDuration(true);
+ videoQuery.selectDescription(true);
+ videoQuery.selectSynopsis(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectEpisode(true);
+ videoQuery.selectCreated(true);
+ videoQuery.selectReleaseDate(true);
+ videoQuery.selectGenre(true);
+ videoQuery.selectArtwork(true);
+ videoQuery.selectWriter(true);
+ videoQuery.selectDirector(true);
+ videoQuery.selectAssistantDirector(true);
+ videoQuery.selectProducer(true);
+ videoQuery.selectActor(true);
+ videoQuery.selectCinematographer(true);
+ videoQuery.orderBy("?seriesName ?season ?episodeNumber");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ MediaItem mediaItem = createMediaItem(it);
+ mediaItem.artwork = KIcon("video-television");
+ mediaItem.fields["videoType"] = "TV Show";
+ mediaList.append(mediaItem);
+ }
+
+ if (seriesName == "~") {
+ m_mediaListProperties.name = i18n("Uncategorized TV Shows");
+ } else if (hasSeason) {
+ m_mediaListProperties.name = i18n("%1 - Season %2", seriesName, season);
+ } else {
+ m_mediaListProperties.name = i18n("%1 - Uncategorized Seasons", seriesName);
+ }
+ m_mediaListProperties.summary = i18np("1 episode", "%1 episodes", mediaList.count());
+ m_mediaListProperties.type = QString("Sources");
+
+ } else if (engineArg.toLower() == "movies") {
+ VideoQuery videoQuery = VideoQuery(false);
+ videoQuery.selectMovieResource();
+ videoQuery.selectTitle();
+ videoQuery.selectDuration(true);
+ videoQuery.selectDescription(true);
+ videoQuery.selectSynopsis(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectCreated(true);
+ videoQuery.selectReleaseDate(true);
+ videoQuery.selectGenre(true);
+ videoQuery.selectArtwork(true);
+ videoQuery.selectWriter(true);
+ videoQuery.selectDirector(true);
+ videoQuery.selectAssistantDirector(true);
+ videoQuery.selectProducer(true);
+ videoQuery.selectActor(true);
+ videoQuery.selectCinematographer(true);
+ if (!genre.isEmpty()) {
+ videoQuery.hasGenre(genre);
+ }
+ videoQuery.orderBy("?title ?created");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ MediaItem mediaItem = createMediaItem(it);
+ mediaItem.artwork = KIcon("tool-animator");
+ mediaItem.fields["videoType"] = "Movie";
+ mediaList.append(mediaItem);
+ }
+
+ m_mediaListProperties.name = i18n("Movies");
+ if (!genre.isEmpty()) {
+ m_mediaListProperties.name = i18n("Movies - %1", genre);
+ }
+ m_mediaListProperties.summary = i18np("1 movie", "%1 movies", mediaList.count());
+ m_mediaListProperties.type = QString("Sources");
+
+ } else if (engineArg.toLower() == "genres") {
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.isAnyVideoType();
+ videoQuery.selectGenre();
+ if (!genre.isEmpty()) {
+ videoQuery.hasGenre(genre);
+ }
+ videoQuery.orderBy("?genre");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ QString genre = it.binding("genre").literal().toString().trimmed();
+ if (!genre.isEmpty()) {
+ MediaItem mediaItem;
+ mediaItem.url = QString("video://sources?||%1").arg(genre);
+ mediaItem.title = genre;
+ mediaItem.type = QString("Category");
+ mediaItem.nowPlaying = false;
+ mediaItem.artwork = KIcon("flag-green");
+ mediaList.append(mediaItem);
+ }
+ }
+
+ m_mediaListProperties.name = i18n("Genres");
+ m_mediaListProperties.summary = i18np("1 genre", "%1 genres", mediaList.count());
+ m_mediaListProperties.type = QString("Categories");
+
+ } else if (engineArg.toLower() == "search") {
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.selectAllVideoResources();
+ videoQuery.selectTitle(true);
+ videoQuery.selectDescription(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectDuration(true);
+ videoQuery.selectSeriesName(true);
+ videoQuery.selectSeason(true);
+ videoQuery.selectSynopsis(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectEpisode(true);
+ videoQuery.selectCreated(true);
+ videoQuery.selectReleaseDate(true);
+ videoQuery.selectGenre(true);
+ videoQuery.selectArtwork(true);
+ videoQuery.selectWriter(true);
+ videoQuery.selectDirector(true);
+ videoQuery.selectAssistantDirector(true);
+ videoQuery.selectProducer(true);
+ videoQuery.selectActor(true);
+ videoQuery.selectCinematographer(true);
+ videoQuery.searchString(searchTerm);
+ videoQuery.orderBy("?title ?seriesName ?season ?episodeNumber");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ MediaItem mediaItem = createMediaItem(it);
+ mediaList.append(mediaItem);
+ }
+
+ /*if (mediaList.isEmpty()) {
+ MediaItem noResults;
+ noResults.url = "video://";
+ noResults.title = "No results";
+ noResults.type = "Message";
+ mediaList << noResults;
+ }*/
+
+ m_mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
+ m_mediaListProperties.type = QString("Sources");
+
+ } else if (engineArg.toLower() == "sources") {
+ VideoQuery videoQuery = VideoQuery(true);
+ videoQuery.selectAllVideoResources();
+ videoQuery.selectTitle(true);
+ videoQuery.selectDescription(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectDuration(true);
+ videoQuery.selectSynopsis(true);
+ videoQuery.selectRating(true);
+ videoQuery.selectSeriesName(true);
+ videoQuery.selectSeason(true);
+ videoQuery.selectEpisode(true);
+ videoQuery.selectCreated(true);
+ videoQuery.selectReleaseDate(true);
+ videoQuery.selectGenre(true);
+ videoQuery.selectArtwork(true);
+ videoQuery.selectWriter(true);
+ videoQuery.selectDirector(true);
+ videoQuery.selectAssistantDirector(true);
+ videoQuery.selectProducer(true);
+ videoQuery.selectActor(true);
+ videoQuery.selectCinematographer(true);
+ if (!searchTerm.isEmpty()) {
+ videoQuery.searchString(searchTerm);
+ }
+ if (!genre.isEmpty()) {
+ if (genre == "~") genre = QString();
+ videoQuery.hasGenre(genre);
+ }
+ if (!seriesName.isEmpty()) {
+ if (seriesName != "~") {
+ videoQuery.hasSeriesName(seriesName);
+ } else {
+ videoQuery.hasNoSeriesName();
+ }
+ }
+ if (season > 0) {
+ videoQuery.hasSeason(season);
+ } else if (season == -1) {
+ videoQuery.hasNoSeason();
+ }
+ videoQuery.orderBy("?seriesName ?season ?episodeNumber ?title");
+
+ //Execute Query
+ Soprano::QueryResultIterator it = videoQuery.executeSelect(m_mainModel);
+
+ //Build media list from results
+ while( it.next() ) {
+ MediaItem mediaItem = createMediaItem(it);
+ mediaList.append(mediaItem);
+ }
+
+ /*if (mediaList.isEmpty()) {
+ MediaItem noResults;
+ noResults.url = "video://";
+ noResults.title = "No results";
+ noResults.type = "Message";
+ mediaList << noResults;
+ }*/
+
+ m_mediaListProperties.summary = i18np("1 item", "%1 items", mediaList.count());
+ m_mediaListProperties.type = QString("Sources");
+
+ }
+ }
+
+ model()->addResults(m_requestSignature, mediaList, m_mediaListProperties, true, m_subRequestSignature);
+
+ //Check if MediaItems in mediaList exist
+ QList<MediaItem> mediaItems = Utilities::mediaItemsDontExist(mediaList);
+ if (mediaItems.count() > 0) {
+ model()->updateMediaItems(mediaItems);
+ }
+
+ m_requestSignature = QString();
+ m_subRequestSignature = QString();
+ //exec();
+
+}
+
+void VideoListEngine::setFilterForSources(const QString& engineFilter)
+{
+ //Always return songs
+ m_mediaListProperties.lri = QString("video://sources?%1").arg(engineFilter);
+}
+
+
+
+VideoQuery::VideoQuery(bool distinct) :
+ m_distinct(distinct),
+ m_selectAllVideoResources(false),
+ m_selectVideoResource(false),
+ m_selectMovieResource(false),
+ m_selectTVShowResource(false),
+ m_selectSeason(false),
+ m_selectSeriesName(false),
+ m_selectTitle(false),
+ m_selectDuration(false),
+ m_selectEpisode(false),
+ m_selectDescription(false),
+ m_selectSynopsis(false),
+ m_selectReleaseDate(false),
+ m_selectCreated(false),
+ m_selectGenre(false),
+ m_selectRating(false),
+ m_selectArtwork(false),
+ m_selectWriter(false),
+ m_selectDirector(false),
+ m_selectAssistantDirector(false),
+ m_selectProducer(false),
+ m_selectActor(false),
+ m_selectCinematographer(false)
+
+{
+ m_mediaVocabulary = MediaVocabulary();
+ m_mediaVocabulary.setVocabulary(MediaVocabulary::nmm);
+ m_mediaVocabulary.setVideoVocabulary(MediaVocabulary::nmm);
+}
+
+void VideoQuery::selectAllVideoResources(bool optional) {
+ m_selectAllVideoResources = true;
+ m_allVideoResourcesCondition = addOptional(optional,
+ QString(" { ?r rdf:type <%1> } "
+ " UNION "
+ " { ?r rdf:type <%2> } "
+ " UNION "
+ " { ?r rdf:type <%3> } "
+ " OPTIONAL { ?r nie:url ?url } . ")
+ .arg(MediaVocabulary().typeVideo().toString())
+ .arg(MediaVocabulary().typeVideoMovie().toString())
+ .arg(MediaVocabulary().typeVideoTVShow().toString()));
+}
+
+void VideoQuery::selectVideoResource(bool optional) {
+ m_selectVideoResource = true;
+ m_videoResourceCondition = addOptional(optional,
+ QString("?r rdf:type <%1> . "
+ "OPTIONAL { ?r nie:url ?url } . ")
+ .arg(m_mediaVocabulary.typeVideo().toString()));
+}
+
+void VideoQuery::selectMovieResource(bool optional) {
+ m_selectMovieResource = true;
+ m_movieResourceCondition = addOptional(optional,
+ QString("?r rdf:type <%1> . "
+ "OPTIONAL { ?r nie:url ?url } . ")
+ .arg(m_mediaVocabulary.typeVideoMovie().toString()));
+}
+
+void VideoQuery::selectTVShowResource(bool optional) {
+ m_selectTVShowResource = true;
+ m_tVShowResourceCondition = addOptional(optional,
+ QString("?r rdf:type <%1> . "
+ "OPTIONAL { ?r nie:url ?url } . ")
+ .arg(m_mediaVocabulary.typeVideoTVShow().toString()));
+}
+
+void VideoQuery::selectSeason(bool optional) {
+ m_selectSeason = true;
+ m_seasonCondition = addOptional(optional,
+ QString("?r <%1> ?season . ")
+ .arg(m_mediaVocabulary.videoSeason().toString()));
+}
+
+void VideoQuery::selectSeriesName(bool optional) {
+ m_selectSeriesName = true;
+ m_seriesNameCondition = addOptional(optional,
+ QString("?r <%1> ?series . "
+ "?series <%2> ?seriesName . ")
+ .arg(m_mediaVocabulary.videoSeries().toString())
+ .arg(m_mediaVocabulary.title().toString()));
+}
+
+void VideoQuery::selectTitle(bool optional) {
+ m_selectTitle = true;
+ m_titleCondition = addOptional(optional,
+ QString("?r <%1> ?title . ")
+ .arg(m_mediaVocabulary.title().toString()));
+}
+
+void VideoQuery::selectDuration(bool optional) {
+ m_selectDuration = true;
+ m_durationCondition = addOptional(optional,
+ QString("?r <%1> ?duration . ")
+ .arg(m_mediaVocabulary.duration().toString()));
+}
+
+void VideoQuery::selectEpisode(bool optional) {
+ m_selectEpisode = true;
+ m_episodeCondition = addOptional(optional,
+ QString("?r <%1> ?episodeNumber . ")
+ .arg(m_mediaVocabulary.videoEpisodeNumber().toString()));
+}
+
+void VideoQuery::selectDescription(bool optional) {
+ m_selectDescription = true;
+ m_descriptionCondition = addOptional(optional,
+ QString("?r <%1> ?description . ")
+ .arg(m_mediaVocabulary.description().toString()));
+}
+
+void VideoQuery::selectSynopsis(bool optional) {
+ m_selectSynopsis = true;
+ m_synopsisCondition = addOptional(optional,
+ QString("?r <%1> ?synopsis . ")
+ .arg(m_mediaVocabulary.videoSynopsis().toString()));
+}
+
+void VideoQuery::selectCreated(bool optional) {
+ m_selectCreated = true;
+ m_createdCondition = addOptional(optional,
+ QString("?r <%1> ?created . ")
+ .arg(m_mediaVocabulary.created().toString()));
+}
+
+void VideoQuery::selectReleaseDate(bool optional) {
+ m_selectReleaseDate = true;
+ m_releaseDateCondition = addOptional(optional,
+ QString("?r <%1> ?releaseDate . ")
+ .arg(m_mediaVocabulary.releaseDate().toString()));
+}
+
+void VideoQuery::selectGenre(bool optional) {
+ m_selectGenre = true;
+ m_genreCondition = addOptional(optional,
+ QString("?r <%1> ?genre . ")
+ .arg(m_mediaVocabulary.genre().toString()));
+}
+
+void VideoQuery::selectRating(bool optional) {
+ m_selectRating = true;
+ m_ratingCondition = addOptional(optional,
+ QString("?r <%1> ?rating . ")
+ .arg(Soprano::Vocabulary::NAO::numericRating().toString()));
+}
+
+void VideoQuery::selectArtwork(bool optional) {
+ m_selectArtwork = true;
+ m_artworkCondition = addOptional(optional,
+ QString("?r <%1> ?artwork . ")
+ .arg(m_mediaVocabulary.artwork().toString()));
+}
+
+void VideoQuery::selectWriter(bool optional) {
+ m_selectWriter = true;
+ m_writerCondition = addOptional(optional,
+ QString("?r <%1> ?writer . ")
+ .arg(m_mediaVocabulary.videoWriter().toString()));
+}
+
+void VideoQuery::selectDirector(bool optional) {
+ m_selectDirector = true;
+ m_directorCondition = addOptional(optional,
+ QString("?r <%1> ?director . ")
+ .arg(m_mediaVocabulary.videoDirector().toString()));
+}
+
+void VideoQuery::selectAssistantDirector(bool optional) {
+ m_selectAssistantDirector = true;
+ m_assistantDirectorCondition = addOptional(optional,
+ QString("?r <%1> ?assistantDirector . ")
+ .arg(m_mediaVocabulary.videoAssistantDirector().toString()));
+}
+
+void VideoQuery::selectProducer(bool optional) {
+ m_selectProducer = true;
+ m_producerCondition = addOptional(optional,
+ QString("?r <%1> ?producer . ")
+ .arg(m_mediaVocabulary.videoProducer().toString()));
+}
+
+void VideoQuery::selectActor(bool optional) {
+ m_selectActor = true;
+ m_actorCondition = addOptional(optional,
+ QString("?r <%1> ?actor . ")
+ .arg(m_mediaVocabulary.videoActor().toString()));
+}
+
+void VideoQuery::selectCinematographer(bool optional) {
+ m_selectCinematographer = true;
+ m_cinematographerCondition = addOptional(optional,
+ QString("?r <%1> ?cinematographer . ")
+ .arg(m_mediaVocabulary.videoCinematographer().toString()));
+}
+
+void VideoQuery::isVideo()
+{
+ m_selectVideoResource = false;
+ m_videoResourceCondition = QString("?r rdf:type <%1> . ")
+ .arg(m_mediaVocabulary.typeVideo().toString());
+}
+
+void VideoQuery::isMovie()
+{
+ m_selectMovieResource = false;
+ m_movieResourceCondition = QString("?r rdf:type <%1> . ")
+ .arg(m_mediaVocabulary.typeVideoMovie().toString());
+}
+
+void VideoQuery::isTVShow()
+{
+ m_selectTVShowResource = false;
+ m_tVShowResourceCondition = QString("?r rdf:type <%1> . ")
+ .arg(m_mediaVocabulary.typeVideoTVShow().toString());
+}
+
+void VideoQuery::isAnyVideoType()
+{
+ m_selectAllVideoResources = false;
+ m_allVideoResourcesCondition = QString(" { ?r rdf:type <%1> } "
+ " UNION "
+ " { ?r rdf:type <%2> } "
+ " UNION "
+ " { ?r rdf:type <%3> } ")
+ .arg(MediaVocabulary().typeVideo().toString())
+ .arg(MediaVocabulary().typeVideoMovie().toString())
+ .arg(MediaVocabulary().typeVideoTVShow().toString());
+}
+
+void VideoQuery::hasSeason(int season) {
+ m_seasonCondition = QString("?r <%1> %2 . "
+ "?r <%1> ?season . ")
+ .arg(m_mediaVocabulary.videoSeason().toString())
+ .arg(Soprano::Node::literalToN3(season));
+}
+
+void VideoQuery::hasNoSeason() {
+ m_seasonCondition = QString(
+ "OPTIONAL { ?r <%1> ?season } "
+ "FILTER ( !bound(?season) ) ")
+ .arg(m_mediaVocabulary.videoSeason().toString());
+}
+
+void VideoQuery::hasSeriesName(QString seriesName) {
+ m_seriesNameCondition = QString("?r <%1> ?series . "
+ "?series <%2> ?seriesName . "
+ "?series <%2> %3 . ")
+ .arg(m_mediaVocabulary.videoSeries().toString())
+ .arg(m_mediaVocabulary.title().toString())
+ .arg(Soprano::Node::literalToN3(seriesName));
+}
+
+void VideoQuery::hasGenre(QString genre) {
+ m_genreCondition = QString("?r <%1> %2 . "
+ "?r <%1> ?genre . ")
+ .arg(m_mediaVocabulary.genre().toString())
+ .arg(Soprano::Node::literalToN3(genre));
+}
+
+void VideoQuery::hasNoSeriesName() {
+ m_seriesNameCondition = QString(
+ "OPTIONAL { ?r <%1> ?series . "
+ "?series <%2> ?seriesName . } "
+ "FILTER (!bound(?seriesName) || regex(str(?seriesName), \"^$\")) ")
+ .arg(m_mediaVocabulary.videoSeries().toString())
+ .arg(m_mediaVocabulary.title().toString());
+}
+
+void VideoQuery::searchString(QString str) {
+ if (! str.isEmpty()) {
+ m_searchCondition = QString(
+ "FILTER (regex(str(?title),\"%1\",\"i\") || "
+ "regex(str(?description),\"%1\",\"i\") || "
+ "regex(str(?synopsis),\"%1\",\"i\") || "
+ "regex(str(?writer),\"%1\",\"i\") || "
+ "regex(str(?director),\"%1\",\"i\") || "
+ "regex(str(?assistantDirector),\"%1\",\"i\") || "
+ "regex(str(?producer),\"%1\",\"i\") || "
+ "regex(str(?actor),\"%1\",\"i\") || "
+ "regex(str(?cinematographer),\"%1\",\"i\")) ")
+ .arg(str);
+ }
+}
+
+
+void VideoQuery::orderBy(QString var) {
+ if (!var.isEmpty()) {
+ m_order = "ORDER BY " + var;
+ }
+}
+
+
+QString VideoQuery::addOptional(bool optional, QString str) {
+ if (optional) {
+ return QString("OPTIONAL { ") + str + "} . ";
+ } else {
+ return str;
+ }
+}
+
+QString VideoQuery::getPrefix() {
+ return QString("PREFIX xesam: <%1> "
+ "PREFIX rdf: <%2> "
+ "PREFIX nmm: <%3> "
+ "PREFIX xls: <%4> "
+ "PREFIX nie: <http://www.semanticdesktop.org/ontologies/2007/01/19/nie#> ")
+ .arg(Soprano::Vocabulary::Xesam::xesamNamespace().toString())
+ .arg(Soprano::Vocabulary::RDF::rdfNamespace().toString())
+ .arg("http://www.semanticdesktop.org/ontologies/nmm#")
+ .arg(Soprano::Vocabulary::XMLSchema::xsdNamespace().toString());
+}
+
+QString VideoQuery::query()
+{
+ QString queryString = getPrefix();
+ queryString += "SELECT ";
+
+ if (m_distinct)
+ queryString += "DISTINCT ";
+ if (m_selectAllVideoResources || m_selectVideoResource || m_selectMovieResource || m_selectTVShowResource)
+ queryString += "?r ?url ?type ";
+ if (m_selectSeason)
+ queryString += "?season ";
+ if (m_selectSeriesName)
+ queryString += "?seriesName ";
+ if (m_selectTitle)
+ queryString += "?title ";
+ if (m_selectDuration)
+ queryString += "?duration ";
+ if (m_selectEpisode)
+ queryString += "?episodeNumber ";
+ if (m_selectDescription)
+ queryString += "?description ";
+ if (m_selectSynopsis)
+ queryString += "?synopsis ";
+ if (m_selectReleaseDate)
+ queryString += "?releaseDate ";
+ if (m_selectCreated)
+ queryString += "?created ";
+ if (m_selectGenre)
+ queryString += "?genre ";
+ if (m_selectRating)
+ queryString += "?rating ";
+ if (m_selectArtwork)
+ queryString += "?artwork ";
+ if (m_selectWriter)
+ queryString += "?writer ";
+ if (m_selectDirector)
+ queryString += "?director ";
+ if (m_selectAssistantDirector)
+ queryString += "?assistantDirector ";
+ if (m_selectProducer)
+ queryString += "?producer ";
+ if (m_selectActor)
+ queryString += "?actor ";
+ if (m_selectCinematographer)
+ queryString += "?cinematographer ";
+
+ //NOTE: nie:url is not in any released nie ontology that I can find.
+ // In future KDE will use nfo:fileUrl so this will need to be changed.
+ queryString += QString("WHERE { ");
+
+ queryString += m_allVideoResourcesCondition;
+ queryString += m_videoResourceCondition;
+ queryString += m_movieResourceCondition;
+ queryString += m_tVShowResourceCondition;
+ queryString += m_seasonCondition;
+ queryString += m_seriesNameCondition;
+ queryString += m_titleCondition;
+ queryString += m_durationCondition;
+ queryString += m_episodeCondition;
+ queryString += m_descriptionCondition;
+ queryString += m_synopsisCondition;
+ queryString += m_createdCondition;
+ queryString += m_releaseDateCondition;
+ queryString += m_genreCondition;
+ queryString += m_ratingCondition;
+ queryString += m_artworkCondition;
+ queryString += m_writerCondition;
+ queryString += m_directorCondition;
+ queryString += m_assistantDirectorCondition;
+ queryString += m_producerCondition;
+ queryString += m_actorCondition;
+ queryString += m_cinematographerCondition;
+ queryString += m_searchCondition;
+ queryString += "} ";
+
+ queryString += m_order;
+
+ return queryString;
+}
+
+Soprano::QueryResultIterator VideoQuery::executeSelect(Soprano::Model* model) {
+ QString queryString = query();
+ return model->executeQuery(queryString,
+ Soprano::Query::QueryLanguageSparql);
+}
+
+bool VideoQuery::executeAsk(Soprano::Model* model) {
+ QString queryString = getPrefix();
+ queryString += QString("ASK { ");
+
+ queryString += m_allVideoResourcesCondition;
+ queryString += m_videoResourceCondition;
+ queryString += m_movieResourceCondition;
+ queryString += m_tVShowResourceCondition;
+ queryString += m_seasonCondition;
+ queryString += m_seriesNameCondition;
+ queryString += m_titleCondition;
+ queryString += m_durationCondition;
+ queryString += m_episodeCondition;
+ queryString += m_descriptionCondition;
+ queryString += m_synopsisCondition;
+ queryString += m_createdCondition;
+ queryString += m_releaseDateCondition;
+ queryString += m_genreCondition;
+ queryString += m_ratingCondition;
+ queryString += m_searchCondition;
+ queryString += m_artworkCondition;
+ queryString += m_writerCondition;
+ queryString += m_directorCondition;
+ queryString += m_assistantDirectorCondition;
+ queryString += m_producerCondition;
+ queryString += m_actorCondition;
+ queryString += m_cinematographerCondition;
+ queryString += "} ";
+
+ return model->executeQuery(queryString,
+ Soprano::Query::QueryLanguageSparql)
+ .boolValue();
+}
diff --git a/src/platform/videolistengine.h b/src/platform/videolistengine.h
new file mode 100644
index 0000000..ce67884
--- /dev/null
+++ b/src/platform/videolistengine.h
@@ -0,0 +1,164 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEOLISTENGINE_H
+#define VIDEOLISTENGINE_H
+
+#include "nepomuklistengine.h"
+#include "mediavocabulary.h"
+#include <QtCore>
+
+class MediaItem;
+class MediaListProperties;
+class ListEngineFactory;
+
+/**
+ * This class retrieve video MediaItems from the nepomuk data store.
+ * List Resource Identifiers handled are:
+ * video://clips
+ * video://tvshows?[genre]
+ * video://seasons?[genre]||[series name]
+ * video://episodes?[genre]||[series name]||[season]
+ * video://movies?[genre]||[series name]
+ * video://search?[search term]
+ * video://sources?[genre]||[series name]||[season]
+ */
+class VideoListEngine : public NepomukListEngine
+{
+ Q_OBJECT
+
+ public:
+ VideoListEngine(ListEngineFactory *parent);
+ ~VideoListEngine();
+ void run();
+ void setFilterForSources(const QString& engineFilter);
+
+ private:
+ MediaItem createMediaItem(Soprano::QueryResultIterator& it);
+
+
+ Q_SIGNALS:
+ void results(QList<MediaItem> mediaList, MediaListProperties mediaListProperties, bool done);
+};
+
+class VideoQuery {
+ public:
+ VideoQuery(bool distinct = true);
+
+ void selectAllVideoResources(bool optional=false);
+ void selectVideoResource(bool optional=false);
+ void selectMovieResource(bool optional=false);
+ void selectTVShowResource(bool optional=false);
+ void selectSeason(bool optional=false);
+ void selectSeriesName(bool optional=false);
+ void selectTitle(bool optional=false);
+ void selectDuration(bool optional=false);
+ void selectEpisode(bool optional=false);
+ void selectDescription(bool optional=false);
+ void selectSynopsis(bool optional=false);
+ void selectReleaseDate(bool optional=false);
+ void selectCreated(bool optional=false);
+ void selectGenre(bool optional=false);
+ void selectRating(bool optional=false);
+ void selectArtwork(bool optional=false);
+ void selectWriter(bool optional=false);
+ void selectDirector(bool optional=false);
+ void selectAssistantDirector(bool optional=false);
+ void selectProducer(bool optional=false);
+ void selectActor(bool optional=false);
+ void selectCinematographer(bool optional=false);
+
+ void isVideo();
+ void isMovie();
+ void isTVShow();
+ void isAnyVideoType();
+
+ void hasSeason(int season);
+ void hasNoSeason();
+
+ void hasSeriesName(QString seriesName);
+ void hasGenre(QString genre);
+ void hasNoSeriesName();
+
+ void searchString(QString str);
+
+ void orderBy(QString var);
+
+ QString query();
+ Soprano::QueryResultIterator executeSelect(Soprano::Model* model);
+ bool executeAsk(Soprano::Model* model);
+
+ private:
+ MediaVocabulary m_mediaVocabulary;
+ bool m_distinct;
+
+ bool m_selectAllVideoResources;
+ bool m_selectVideoResource;
+ bool m_selectMovieResource;
+ bool m_selectTVShowResource;
+ bool m_selectSeason;
+ bool m_selectSeriesName;
+ bool m_selectTitle;
+ bool m_selectDuration;
+ bool m_selectEpisode;
+ bool m_selectDescription;
+ bool m_selectSynopsis;
+ bool m_selectReleaseDate;
+ bool m_selectCreated;
+ bool m_selectGenre;
+ bool m_selectRating;
+ bool m_selectArtwork;
+ bool m_selectWriter;
+ bool m_selectDirector;
+ bool m_selectAssistantDirector;
+ bool m_selectProducer;
+ bool m_selectActor;
+ bool m_selectCinematographer;
+
+ QString m_allVideoResourcesCondition;
+ QString m_videoResourceCondition;
+ QString m_movieResourceCondition;
+ QString m_tVShowResourceCondition;
+ QString m_seasonCondition;
+ QString m_seriesNameCondition;
+ QString m_titleCondition;
+ QString m_durationCondition;
+ QString m_episodeCondition;
+ QString m_descriptionCondition;
+ QString m_synopsisCondition;
+ QString m_releaseDateCondition;
+ QString m_createdCondition;
+ QString m_genreCondition;
+ QString m_searchCondition;
+ QString m_ratingCondition;
+ QString m_artworkCondition;
+ QString m_writerCondition;
+ QString m_directorCondition;
+ QString m_assistantDirectorCondition;
+ QString m_producerCondition;
+ QString m_actorCondition;
+ QString m_cinematographerCondition;
+
+ QString m_order;
+
+ QString addOptional(bool optional, QString str);
+ QString getPrefix();
+};
+
+#endif // VIDEOLISTENGINE_H
+
diff --git a/src/savedlistsmanager.cpp b/src/savedlistsmanager.cpp
new file mode 100644
index 0000000..bee3814
--- /dev/null
+++ b/src/savedlistsmanager.cpp
@@ -0,0 +1,729 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "savedlistsmanager.h"
+#include "platform/utilities.h"
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "platform/mediaitemmodel.h"
+#include "platform/playlist.h"
+
+#include <KStandardDirs>
+#include <KMessageBox>
+#include <KDebug>
+#include <QFile>
+#include <Nepomuk/ResourceManager>
+
+SavedListsManager::SavedListsManager(MainWindow * parent) : QObject(parent)
+{
+ m_parent = parent;
+ ui = m_parent->ui;
+
+ ui->aListSourceSelection->setEnabled(false);
+ ui->vListSourceSelection->setEnabled(false);
+ loadSavedListsIndex();
+
+ connect(ui->addAudioList, SIGNAL(clicked()), this, SLOT(showAudioListSave()));
+ connect(ui->addVideoList, SIGNAL(clicked()), this, SLOT(showVideoListSave()));
+ connect(ui->aCancelSaveList, SIGNAL(clicked()), this, SLOT(returnToAudioList()));
+ connect(ui->vCancelSaveList, SIGNAL(clicked()), this, SLOT(returnToVideoList()));
+ connect(ui->saveAudioList, SIGNAL(clicked()), this, SLOT(saveAudioList()));
+ connect(ui->saveVideoList, SIGNAL(clicked()), this, SLOT(saveVideoList()));
+ connect(ui->aNewListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
+ connect(ui->vNewListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
+ connect(ui->aNewListName, SIGNAL(returnPressed()), this, SLOT(saveAudioList()));
+ connect(ui->vNewListName, SIGNAL(returnPressed()), this, SLOT(saveVideoList()));
+ connect(ui->removeAudioList, SIGNAL(clicked()), this, SLOT(removeAudioList()));
+ connect(ui->removeVideoList, SIGNAL(clicked()), this, SLOT(removeVideoList()));
+ connect(ui->configureAudioList, SIGNAL(clicked()), this, SLOT(showAudioSavedListSettings()));
+ connect(ui->configureVideoList, SIGNAL(clicked()), this, SLOT(showVideoSavedListSettings()));
+ connect(ui->aslsCancel, SIGNAL(clicked()), this, SLOT(returnToAudioList()));
+ connect(ui->vslsCancel, SIGNAL(clicked()), this, SLOT(returnToVideoList()));
+ connect(ui->aslsSave, SIGNAL(clicked()), this, SLOT(saveAudioListSettings()));
+ connect(ui->vslsSave, SIGNAL(clicked()), this, SLOT(saveVideoListSettings()));
+ connect(ui->aslsListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
+ connect(ui->vslsListName, SIGNAL(textChanged(QString)), this, SLOT(enableValidSave(QString)));
+ connect(ui->aslsListName, SIGNAL(returnPressed()), this, SLOT(saveAudioListSettings()));
+ connect(ui->vslsListName, SIGNAL(returnPressed()), this, SLOT(saveVideoListSettings()));
+
+ connect(ui->mediaView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(selectionChanged(const QItemSelection, const QItemSelection)));
+ connect(ui->audioLists->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(audioListsSelectionChanged(const QItemSelection, const QItemSelection)));
+ connect(ui->videoLists->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(videoListsSelectionChanged(const QItemSelection, const QItemSelection)));
+ connect(m_parent->m_mediaItemModel, SIGNAL(mediaListChanged()), this, SLOT(mediaListChanged()));
+
+ Nepomuk::ResourceManager::instance()->init();
+ if (Nepomuk::ResourceManager::instance()->initialized()) {
+ m_nepomukInited = true;
+ } else {
+ m_nepomukInited = false;
+ }
+
+}
+
+SavedListsManager::~SavedListsManager()
+{
+}
+
+void SavedListsManager::showAudioListSave()
+{
+ ui->audioListsStack->setCurrentIndex(1);
+ ui->aNewListName->setText("Untitled");
+ if (ui->aListSourceSelection->isEnabled()) {
+ ui->aListSourceSelection->setChecked(true);
+ } else if (ui->aListSourceView->isEnabled()) {
+ ui->aListSourceView->setChecked(true);
+ } else {
+ ui->aListSourcePlaylist->setChecked(true);
+ }
+ ui->aNewListName->setFocus();
+ enableValidSave();
+}
+
+void SavedListsManager::showVideoListSave()
+{
+ ui->videoListsStack->setCurrentIndex(1);
+ ui->vNewListName->setText("Untitled");
+ if (ui->vListSourceSelection->isEnabled()) {
+ ui->vListSourceSelection->setChecked(true);
+ } else if (ui->vListSourceView->isEnabled()) {
+ ui->vListSourceView->setChecked(true);
+ } else {
+ ui->vListSourcePlaylist->setChecked(true);
+ }
+ ui->vNewListName->setFocus();
+ enableValidSave();
+}
+
+void SavedListsManager::returnToAudioList()
+{
+ ui->aNewListName->clear();
+ ui->aslsListName->clear();
+ ui->audioListsStack->setCurrentIndex(0);
+}
+
+void SavedListsManager::returnToVideoList()
+{
+ ui->vNewListName->clear();
+ ui->vslsListName->clear();
+ ui->videoListsStack->setCurrentIndex(0);
+}
+
+void SavedListsManager::saveAudioList()
+{
+ if (ui->aListSourceSelection->isChecked()) {
+ //Get selected media items and save
+ QList<MediaItem> mediaList;
+ QList<MediaItem> viewMediaList = m_parent->m_mediaItemModel->mediaList();
+ QModelIndexList selectedRows = ui->mediaView->selectionModel()->selectedRows();
+ for (int i = 0 ; i < selectedRows.count() ; ++i) {
+ mediaList.append(viewMediaList.at(selectedRows.at(i).row()));
+ }
+ saveMediaList(mediaList, ui->aNewListName->text(), QString("Audio"));
+ } else if (ui->aListSourceView->isChecked()) {
+ saveView(ui->aNewListName->text(), QString("Audio"));
+ } else if (ui->aListSourcePlaylist->isChecked()) {
+ QList<MediaItem> mediaList = m_parent->m_playlist->playlistModel()->mediaList();
+ saveMediaList(mediaList, ui->aNewListName->text(), QString("Audio"));
+ }
+ MediaListProperties audioListsProperties = m_parent->m_audioListsModel->mediaListProperties();
+ m_parent->m_audioListsModel->clearMediaListData();
+ m_parent->m_audioListsModel->setMediaListProperties(audioListsProperties);
+ m_parent->m_audioListsModel->load();
+ returnToAudioList();
+}
+
+void SavedListsManager::saveVideoList()
+{
+ if (ui->vListSourceSelection->isChecked()) {
+ //Get selected media items and save
+ QList<MediaItem> mediaList;
+ QList<MediaItem> viewMediaList = m_parent->m_mediaItemModel->mediaList();
+ QModelIndexList selectedRows = ui->mediaView->selectionModel()->selectedRows();
+ for (int i = 0 ; i < selectedRows.count() ; ++i) {
+ mediaList.append(viewMediaList.at(selectedRows.at(i).row()));
+ }
+ saveMediaList(mediaList, ui->vNewListName->text(), QString("Video"));
+ } else if (ui->vListSourceView->isChecked()) {
+ saveView(ui->vNewListName->text(), QString("Video"));
+ } else if (ui->vListSourcePlaylist->isChecked()) {
+ QList<MediaItem> mediaList = m_parent->m_playlist->playlistModel()->mediaList();
+ saveMediaList(mediaList, ui->vNewListName->text(), QString("Video"));
+ }
+ MediaListProperties videoListsProperties = m_parent->m_videoListsModel->mediaListProperties();
+ m_parent->m_videoListsModel->clearMediaListData();
+ m_parent->m_videoListsModel->setMediaListProperties(videoListsProperties);
+ m_parent->m_videoListsModel->load();
+ returnToVideoList();
+}
+
+void SavedListsManager::removeAudioList()
+{
+ if (ui->audioLists->selectionModel()->selectedIndexes().count() > 0){
+ int selectedRow = ui->audioLists->selectionModel()->selectedIndexes().at(0).row();
+ QString name = m_parent->m_audioListsModel->mediaItemAt(selectedRow).title;
+
+ KGuiItem removeSavedList;
+ removeSavedList.setText(QString("Remove"));
+ removeSavedList.setIcon(KIcon("list-remove"));
+ QString message = QString("Are you sure you want to remove \"%1\"?").arg(name);
+
+ if (KMessageBox::warningContinueCancel(m_parent, message, QString(), removeSavedList) == KMessageBox::Continue) {
+ //Remove M3U file
+ QString filename = name;
+ filename = filename.replace(" ", "");
+ QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/Audio-%1.m3u").arg(filename), false));
+
+ QString savedListEntry = QString("Audio:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedAudioLists.count(); i++) {
+ if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedAudioLists.removeAt(rowsToRemove.at(i));
+ }
+ updateSavedListsIndex();
+ MediaListProperties audioListsProperties = m_parent->m_audioListsModel->mediaListProperties();
+ m_parent->m_audioListsModel->clearMediaListData();
+ m_parent->m_audioListsModel->setMediaListProperties(audioListsProperties);
+ m_parent->m_audioListsModel->load();
+ emit savedListsChanged();
+ }
+ }
+}
+
+void SavedListsManager::removeVideoList()
+{
+ if (ui->videoLists->selectionModel()->selectedIndexes().count() > 0){
+ int selectedRow = ui->videoLists->selectionModel()->selectedIndexes().at(0).row();
+ QString name = m_parent->m_videoListsModel->mediaItemAt(selectedRow).title;
+
+ KGuiItem removeSavedList;
+ removeSavedList.setText(QString("Remove"));
+ removeSavedList.setIcon(KIcon("list-remove"));
+ QString message = QString("Are you sure you want to remove \"%1\"?").arg(name);
+
+ if (KMessageBox::warningContinueCancel(m_parent, message, QString(), removeSavedList) == KMessageBox::Continue) {
+ //Remove M3U file
+ QString filename = name;
+ filename = filename.replace(" ", "");
+ QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/Video-%1.m3u").arg(filename), false));
+
+ QString savedListEntry = QString("Video:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedVideoLists.count(); i++) {
+ if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedVideoLists.removeAt(rowsToRemove.at(i));
+ }
+ updateSavedListsIndex();
+ MediaListProperties videoListsProperties = m_parent->m_videoListsModel->mediaListProperties();
+ m_parent->m_videoListsModel->clearMediaListData();
+ m_parent->m_videoListsModel->setMediaListProperties(videoListsProperties);
+ m_parent->m_videoListsModel->load();
+ emit savedListsChanged();
+ }
+ }
+}
+
+void SavedListsManager::enableValidSave(QString newText)
+{
+ ui->saveAudioList->setEnabled(true);
+ if (!ui->aNewListName->text().isEmpty()) {
+ ui->saveAudioList->setEnabled(true);
+ } else {
+ ui->saveAudioList->setEnabled(false);
+ }
+ if (!ui->vNewListName->text().isEmpty()) {
+ ui->saveVideoList->setEnabled(true);
+ } else {
+ ui->saveVideoList->setEnabled(false);
+ }
+ if (!ui->aslsListName->text().isEmpty()) {
+ ui->aslsSave->setEnabled(true);
+ } else {
+ ui->aslsSave->setEnabled(false);
+ }
+ if (!ui->vslsListName->text().isEmpty()) {
+ ui->vslsSave->setEnabled(true);
+ } else {
+ ui->vslsSave->setEnabled(false);
+ }
+ Q_UNUSED(newText); //not used since method may be called directly
+}
+
+void SavedListsManager::audioListsSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
+{
+ if (selected.indexes().count() > 0) {
+ bool isSavedList = selected.indexes().at(0).data(MediaItem::IsSavedListRole).toBool();
+ if (isSavedList) {
+ ui->removeAudioList->setEnabled(true);
+ ui->configureAudioList->setVisible(true);
+ } else {
+ ui->removeAudioList->setEnabled(false);
+ ui->configureAudioList->setVisible(false);
+ }
+ }
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+}
+
+void SavedListsManager::videoListsSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
+{
+ if (selected.indexes().count() > 0) {
+ bool isSavedList = selected.indexes().at(0).data(MediaItem::IsSavedListRole).toBool();
+ if (isSavedList) {
+ ui->removeVideoList->setEnabled(true);
+ ui->configureVideoList->setVisible(true);
+ } else {
+ ui->removeVideoList->setEnabled(false);
+ ui->configureVideoList->setVisible(false);
+ }
+ }
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+}
+
+void SavedListsManager::selectionChanged (const QItemSelection & selected, const QItemSelection & deselected )
+{
+ if (ui->mediaView->selectionModel()->selectedRows().count() > 0) {
+ QString listItemType = m_parent->m_mediaItemModel->mediaItemAt(0).type;
+ if ((listItemType == "Audio") || (listItemType == "Video") || (listItemType == "Image")) {
+ ui->aListSourceSelection->setEnabled(true);
+ ui->vListSourceSelection->setEnabled(true);
+ }
+ } else {
+ ui->aListSourceSelection->setChecked(false);
+ ui->vListSourceSelection->setChecked(false);
+ ui->aListSourceSelection->setEnabled(false);
+ ui->vListSourceSelection->setEnabled(false);
+ }
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+}
+
+void SavedListsManager::showAudioSavedListSettings()
+{
+ ui->audioListsStack->setCurrentIndex(2);
+ QModelIndexList selectedIndexes = ui->audioLists->selectionModel()->selectedIndexes();
+ for(int i = 0; i < selectedIndexes.count(); i++) {
+ int row = selectedIndexes.at(i).row();
+ ui->aslsListName->setText(m_parent->m_audioListsModel->mediaItemAt(row).title);
+ }
+ ui->aslsListName->setFocus();
+}
+
+void SavedListsManager::showVideoSavedListSettings()
+{
+ ui->videoListsStack->setCurrentIndex(2);
+ QModelIndexList selectedIndexes = ui->videoLists->selectionModel()->selectedIndexes();
+ for(int i = 0; i < selectedIndexes.count(); i++) {
+ int row = selectedIndexes.at(i).row();
+ ui->vslsListName->setText(m_parent->m_videoListsModel->mediaItemAt(row).title);
+ }
+ ui->vslsListName->setFocus();
+}
+
+
+void SavedListsManager::mediaListChanged()
+{
+ if (m_parent->m_mediaItemModel->rowCount() > 0) {
+ QString listItemType = m_parent->m_mediaItemModel->mediaItemAt(0).type;
+ if (listItemType == "Audio" && m_nepomukInited) {
+ ui->aListSourceView->setEnabled(true);
+ } else if (listItemType == "Video" && m_nepomukInited) {
+ ui->vListSourceView->setEnabled(true);
+ } else {
+ ui->aListSourceView->setChecked(false);
+ ui->vListSourceView->setChecked(false);
+ ui->aListSourceView->setEnabled(false);
+ ui->vListSourceView->setEnabled(false);
+ }
+ }
+}
+
+void SavedListsManager::saveMediaList(QList<MediaItem> mediaList, QString name, QString type, bool append)
+{
+ if (!name.isEmpty()) {
+
+ //Create and populate M3U file
+ QString filename = name;
+ filename = filename.replace(" ", "");
+ QIODevice::OpenMode openMode;
+ if (append) {
+ openMode = QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append;
+ } else {
+ QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), false));
+ openMode = QIODevice::WriteOnly | QIODevice::Text;
+ }
+ QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), true));
+ if (!file.open(openMode)) {
+ return;
+ }
+ QTextStream out(&file);
+ if (!append) {
+ out << "#EXTM3U" << "\r\n";
+ }
+ for (int i = 0; i < mediaList.count(); i++) {
+ out << "#EXTINF:" << mediaList.at(i).fields["duration"].toInt() << "," << mediaList.at(i).title << "\r\n";
+ out << mediaList.at(i).url << "\r\n";
+ }
+ file.close();
+
+ //Save list to index file
+ if (type == "Audio") {
+ QString indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(name)
+ .arg(QString("savedlists://%1-%2.m3u").arg(type).arg(filename));
+ QString savedListEntry = QString("Audio:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedAudioLists.count(); i++) {
+ if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedAudioLists.removeAt(rowsToRemove.at(i));
+ }
+ m_savedAudioLists << indexEntry;
+ } else if (type == "Video") {
+ QString indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(name)
+ .arg(QString("savedlists://%1-%2.m3u").arg(type).arg(filename));
+ QString savedListEntry = QString("Video:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedVideoLists.count(); i++) {
+ if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedVideoLists.removeAt(rowsToRemove.at(i));
+ }
+ m_savedVideoLists << indexEntry;
+ }
+ updateSavedListsIndex();
+ emit savedListsChanged();
+ }
+}
+
+void SavedListsManager::saveView(QString name, QString type)
+{
+ if (!name.isEmpty()) {
+ //Add to saved list index
+ if (type == "Audio") {
+ QString indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(name)
+ .arg(m_parent->m_mediaItemModel->mediaListProperties().lri);
+ QString savedListEntry = QString("Audio:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedAudioLists.count(); i++) {
+ if (m_savedAudioLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedAudioLists.removeAt(rowsToRemove.at(i));
+ }
+ m_savedAudioLists << indexEntry;
+ } else if (type == "Video") {
+ QString indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(name)
+ .arg(m_parent->m_mediaItemModel->mediaListProperties().lri);
+ QString savedListEntry = QString("Video:::%1")
+ .arg(name);
+ QList<int> rowsToRemove;
+ for (int i = 0; i < m_savedVideoLists.count(); i++) {
+ if (m_savedVideoLists.at(i).startsWith(savedListEntry)) {
+ rowsToRemove << i;
+ }
+ }
+ for (int i = 0; i < rowsToRemove.count(); i++) {
+ m_savedVideoLists.removeAt(rowsToRemove.at(i));
+ }
+ m_savedVideoLists << indexEntry;
+ }
+ updateSavedListsIndex();
+ emit savedListsChanged();
+ }
+}
+
+
+void SavedListsManager::loadSavedListsIndex()
+{
+ //Load lists from index
+ m_savedAudioLists.clear();
+ m_savedVideoLists.clear();
+ QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
+ if (!indexFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return;
+ }
+ QTextStream in(&indexFile);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ QStringList nameUrl = line.split(":::");
+ if (nameUrl.count() >= 3) {
+ QString type = nameUrl.at(0).trimmed();
+ if (type == "Audio") {
+ m_savedAudioLists << line;
+ } else if (type == "Video") {
+ m_savedVideoLists << line;
+ }
+ }
+ }
+ indexFile.close();
+ emit savedListsChanged();
+}
+void SavedListsManager::updateSavedListsIndex()
+{
+ QFile::remove(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
+ QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", true));
+ if (!indexFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ return;
+ }
+ QTextStream outIndex(&indexFile);
+ for (int i = 0; i < m_savedAudioLists.count(); i++) {
+ outIndex << m_savedAudioLists.at(i) << "\r\n";
+ }
+ for (int i = 0; i < m_savedVideoLists.count(); i++) {
+ outIndex << m_savedVideoLists.at(i) << "\r\n";
+ }
+ indexFile.close();
+}
+
+QStringList SavedListsManager::savedListNames(QString type)
+{
+ QList<QString> savedLists ;
+ if (type == "Audio") {
+ savedLists = m_savedAudioLists;
+ } else if (type == "Video") {
+ savedLists = m_savedVideoLists;
+ }
+ QStringList savedListNames;
+ for (int i = 0; i < savedLists.count(); i++) {
+ QString name = savedLists.at(i).split(":::").at(1);
+ QString lri = savedLists.at(i).split(":::").at(2);
+ if (lri.startsWith("savedlists://")) {
+ savedListNames.append(name);
+ }
+ }
+ return savedListNames;
+}
+
+void SavedListsManager::removeSelected()
+{
+ if (m_parent->m_mediaItemModel->mediaListProperties().lri.startsWith("savedlists://")) {
+ QList<MediaItem> mediaList;
+
+ QList<int> rowsToRemove;
+ //Rebuild mediaList without selected items
+ for (int i = 0; i < m_parent->m_mediaItemModel->rowCount(); i++) {
+ QModelIndex index = m_parent->m_mediaItemModel->index(i, 0);
+ if (!ui->mediaView->selectionModel()->isSelected(index)) {
+ mediaList.append(m_parent->m_mediaItemModel->mediaItemAt(i));
+ } else {
+ rowsToRemove.append(i);
+ }
+ }
+
+ //Save new medialist
+ QString lri = m_parent->m_mediaItemModel->mediaListProperties().lri;
+ QString name = savedListLriName(lri);
+ saveMediaList(mediaList, name, m_parent->m_mediaItemModel->mediaItemAt(0).type);
+
+ //Remove items from model
+ m_parent->m_mediaItemModel->reload();
+ }
+
+}
+
+void SavedListsManager::saveAudioListSettings()
+{
+ //Get old list name
+ QString oldName;
+ QModelIndexList selectedIndexes = ui->audioLists->selectionModel()->selectedIndexes();
+ int audioListsRow = selectedIndexes.at(0).row();
+ MediaItem mediaItem;
+ if (selectedIndexes.count() > 0) {
+ oldName = m_parent->m_audioListsModel->mediaItemAt(audioListsRow).title;
+ mediaItem = m_parent->m_audioListsModel->mediaItemAt(audioListsRow);
+ }
+
+ //Read index file to locate and rename saved list name
+ QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
+ if (!indexFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return;
+ }
+ m_savedAudioLists.clear();
+ QTextStream in(&indexFile);
+ while (!in.atEnd()) {
+ QString line = in.readLine().trimmed();
+ QStringList nameUrl = line.split(":::");
+ if (nameUrl.count() >= 3) {
+ QString type = nameUrl.at(0).trimmed();
+ QString name = nameUrl.at(1).trimmed();
+ QString lri = nameUrl.at(2).trimmed();
+ if (type == "Audio") {
+ QString indexEntry = line;
+ if (name == oldName) {
+ QString newName = ui->aslsListName->text();
+ if (lri.startsWith("savedlists://")) {
+ //rename file
+ QString filename = name.replace(" ", "");
+ QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), true));
+ QString newFilename = QString(newName).replace(" ", "");
+ QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(newFilename), true));
+ QString renamedFileName = file.fileName();
+ renamedFileName.replace(QString("%1.m3u").arg(filename), QString("%1.m3u").arg(newFilename));
+ file.rename(renamedFileName);
+ lri.replace(QString("%1.m3u").arg(filename), QString("%1.m3u").arg(newFilename));
+ }
+
+ //Update Audio ListView
+ mediaItem.title = newName;
+ mediaItem.url = lri;
+ m_parent->m_audioListsModel->replaceMediaItemAt(audioListsRow, mediaItem);
+ ui->listTitle->setText(newName);
+
+ //create new index entry for index file
+ indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(newName)
+ .arg(lri);
+ }
+ m_savedAudioLists.append(indexEntry);
+ }
+ }
+ }
+ indexFile.close();
+
+ //Update index file
+ updateSavedListsIndex();
+
+ emit savedListsChanged();
+ if (selectedIndexes.count() > 0) {
+ ui->audioLists->selectionModel()->select(selectedIndexes.at(0), QItemSelectionModel::Select);
+ }
+ returnToAudioList();
+}
+
+void SavedListsManager::saveVideoListSettings()
+{
+ //Get old list name
+ QString oldName;
+ QModelIndexList selectedIndexes = ui->videoLists->selectionModel()->selectedIndexes();
+ int videoListsRow = selectedIndexes.at(0).row();
+ MediaItem mediaItem;
+ if (selectedIndexes.count() > 0) {
+ oldName = m_parent->m_videoListsModel->mediaItemAt(videoListsRow).title;
+ mediaItem = m_parent->m_videoListsModel->mediaItemAt(videoListsRow);
+ }
+
+ //Read index file to locate and rename saved list name
+ QFile indexFile(KStandardDirs::locateLocal("data", "bangarang/savedlists", false));
+ if (!indexFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return;
+ }
+ m_savedVideoLists.clear();
+ QTextStream in(&indexFile);
+ while (!in.atEnd()) {
+ QString line = in.readLine().trimmed();
+ QStringList nameUrl = line.split(":::");
+ if (nameUrl.count() >= 3) {
+ QString type = nameUrl.at(0).trimmed();
+ QString name = nameUrl.at(1).trimmed();
+ QString lri = nameUrl.at(2).trimmed();
+ if (type == "Video") {
+ QString indexEntry = line;
+ if (name == oldName) {
+ QString newName = ui->vslsListName->text();
+ if (lri.startsWith("savedlists://")) {
+ //rename file
+ QString filename = name.replace(" ", "");
+ QFile file(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(filename), true));
+ QString newFilename = QString(newName).replace(" ", "");
+ QFile::remove(KStandardDirs::locateLocal("data", QString("bangarang/%1-%2.m3u").arg(type).arg(newFilename), true));
+ QString renamedFileName = file.fileName();
+ renamedFileName.replace(QString("%1.m3u").arg(filename), QString("%1.m3u").arg(newFilename));
+ file.rename(renamedFileName);
+ lri.replace(QString("%1.m3u").arg(filename), QString("%1.m3u").arg(newFilename));
+ }
+
+ //Update Video ListView
+ mediaItem.title = newName;
+ mediaItem.url = lri;
+ m_parent->m_videoListsModel->replaceMediaItemAt(videoListsRow, mediaItem);
+ ui->listTitle->setText(newName);
+
+ //create new index entry for index file
+ indexEntry = QString("%1:::%2:::%3")
+ .arg(type)
+ .arg(newName)
+ .arg(lri);
+ }
+ m_savedVideoLists.append(indexEntry);
+ }
+ }
+ }
+ indexFile.close();
+
+ //Update index file
+ updateSavedListsIndex();
+
+ emit savedListsChanged();
+ if (selectedIndexes.count() > 0) {
+ ui->videoLists->selectionModel()->select(selectedIndexes.at(0), QItemSelectionModel::Select);
+ }
+ returnToVideoList();
+}
+
+QString SavedListsManager::savedListLriName(QString lri)
+{
+ QString name;
+ for (int i = 0; i < m_savedAudioLists.count(); i++) {
+ if (m_savedAudioLists.at(i).endsWith(lri)) {
+ QString indexEntry = m_savedAudioLists.at(i);
+ name = indexEntry.split(":::").at(1);
+ }
+ }
+
+ for (int i = 0; i < m_savedVideoLists.count(); i++) {
+ if (m_savedAudioLists.at(i).endsWith(lri)) {
+ QString indexEntry = m_savedAudioLists.at(i);
+ name = indexEntry.split(":::").at(1);
+ }
+ }
+
+ return name;
+}
+
+
+
diff --git a/savedlistsmanager.h b/src/savedlistsmanager.h
similarity index 75%
rename from savedlistsmanager.h
rename to src/savedlistsmanager.h
index e2a9d5a..2980b01 100644
--- a/savedlistsmanager.h
+++ b/src/savedlistsmanager.h
@@ -21,6 +21,7 @@
#include <QObject>
#include <QItemSelection>
+#include <QStringList>
namespace Ui
{
@@ -29,6 +30,10 @@ namespace Ui
class MainWindow;
class MediaItem;
+/*
+ * This class provides a user interface for saving and removing media lists
+ * FIXME: Need interface to rename (or configure?) media lists
+ */
class SavedListsManager : public QObject
{
Q_OBJECT
@@ -36,16 +41,24 @@ class SavedListsManager : public QObject
public:
SavedListsManager(MainWindow * parent);
~SavedListsManager();
- void saveMediaList(QList<MediaItem> mediaList, QString name, QString type);
+ void saveMediaList(QList<MediaItem> mediaList, QString name, QString type, bool append = false);
void saveView(QString name, QString type);
+ QStringList savedListNames(QString type);
+ QString savedListLriName(QString lri);
+
+ signals:
+ void savedListsChanged();
public slots:
void showAudioListSave();
void showVideoListSave();
- void hideAudioListSave();
- void hideVideoListSave();
+ void returnToAudioList();
+ void returnToVideoList();
void saveAudioList();
void saveVideoList();
+ void removeSelected();
+ void saveAudioListSettings();
+ void saveVideoListSettings();
private:
MainWindow *m_parent;
@@ -53,8 +66,8 @@ class SavedListsManager : public QObject
int m_startRow;
QList<int> m_savedAudioListRows;
QList<int> m_savedVideoListRows;
- QList<QString> m_savedAudioLists;
- QList<QString> m_savedVideoLists;
+ QStringList m_savedAudioLists;
+ QStringList m_savedVideoLists;
void updateSavedListsIndex();
bool m_nepomukInited;
@@ -67,7 +80,8 @@ class SavedListsManager : public QObject
void removeAudioList();
void removeVideoList();
void loadSavedListsIndex();
-
+ void showAudioSavedListSettings();
+ void showVideoSavedListSettings();
};
-#endif //SAVEDLISTSMANAGER_H
\ No newline at end of file
+#endif //SAVEDLISTSMANAGER_H
diff --git a/sensiblewidgets.cpp b/src/sensiblewidgets.cpp
similarity index 100%
rename from sensiblewidgets.cpp
rename to src/sensiblewidgets.cpp
diff --git a/sensiblewidgets.h b/src/sensiblewidgets.h
similarity index 100%
rename from sensiblewidgets.h
rename to src/sensiblewidgets.h
diff --git a/src/videosettings.cpp b/src/videosettings.cpp
new file mode 100644
index 0000000..b47342c
--- /dev/null
+++ b/src/videosettings.cpp
@@ -0,0 +1,294 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andrew Lake (jamboarder at yahoo.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videosettings.h"
+#include <QWidget>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QGridLayout>
+#include <QSlider>
+#include <QButtonGroup>
+#include <QRadioButton>
+#include <QAbstractButton>
+#include <KButtonGroup>
+#include <QLabel>
+#include <KLocale>
+#include <QAction>
+
+#include <phonon/videowidget.h>
+
+#include <KPushButton>
+
+using namespace Phonon;
+
+VideoSettings::VideoSettings(VideoWidget *widget ,
+ QWidget *parent): QWidget(parent) ,
+ m_layout(0) ,
+ colorSettings_layout(0) ,
+ sizeSettings_layout(0) ,
+ button_layout(0) ,
+ brightnessSlider(0) ,
+ contrastSlider(0) ,
+ hueSlider(0) ,
+ saturationSlider(0) ,
+ brightnessLabel(0) ,
+ contrastLabel(0) ,
+ hueLabel(0) ,
+ saturationLabel(0) ,
+ aspectRatio_Widget(0) ,
+ aspectRatio_layout(0) ,
+ aspectRatioLabel(0) ,
+ aspectRatioAuto(0) ,
+ aspectRatioWidget(0) ,
+ aspectRatio4_3(0) ,
+ aspectRatio16_9(0) ,
+ scaleMode_Widget(0) ,
+ scaleMode_layout(0) ,
+ scaleModeLabel(0) ,
+ scaleModeFitInView(0) ,
+ scaleModeScaleAndCrop(0) ,
+ restoreButton(0) ,
+ videoWidget(0)
+{
+ m_layout = new QVBoxLayout(this) ;
+ colorSettings_layout = new QGridLayout();
+ videoColorWidget = new QWidget();
+ button_layout = new QHBoxLayout();
+
+ brightnessLabel = new QLabel(i18n("Brightness"));
+ brightnessSlider = new QSlider();
+
+ brightnessSlider->setMaximum(99);
+ brightnessSlider->setMinimum(-99);
+ brightnessSlider->setOrientation(Qt::Horizontal);
+ brightnessSlider->setValue(int(widget->brightness() * 100));
+ colorSettings_layout->addWidget(brightnessLabel , 0,0);
+ colorSettings_layout->addWidget(brightnessSlider, 0,1);
+
+ contrastLabel= new QLabel(i18n("Contrast"));
+ contrastSlider = new QSlider();
+
+ contrastSlider->setMaximum(99);
+ contrastSlider->setMinimum(-99);
+ contrastSlider->setOrientation(Qt::Horizontal);
+ contrastSlider->setValue(int(widget->contrast() * 100));
+ colorSettings_layout->addWidget(contrastLabel , 1,0);
+ colorSettings_layout->addWidget(contrastSlider, 1,1);
+
+ hueLabel= new QLabel(i18n("Hue"));
+ hueSlider = new QSlider();
+
+ hueSlider->setMaximum(99);
+ hueSlider->setMinimum(-99);
+ hueSlider->setOrientation(Qt::Horizontal);
+ hueSlider->setValue(int(widget->hue() * 100));
+ colorSettings_layout->addWidget(hueLabel , 2,0);
+ colorSettings_layout->addWidget(hueSlider, 2,1);
+
+ saturationLabel= new QLabel(i18n("Saturation"));
+ saturationSlider = new QSlider();
+
+ saturationSlider->setMaximum(99);
+ saturationSlider->setMinimum(-99);
+ saturationSlider->setOrientation(Qt::Horizontal);
+ saturationSlider->setValue(int(widget->saturation() * 100));
+ colorSettings_layout->addWidget(saturationLabel , 3,0);
+ colorSettings_layout->addWidget(saturationSlider, 3,1);
+
+ videoColorWidget->setLayout(colorSettings_layout);
+
+ sizeSettings_layout = new QVBoxLayout();
+ aspectRatio_Widget = new QWidget();
+ aspectRatio_layout = new QVBoxLayout();
+ aspectRatioLabel = new QLabel(i18n("Aspect Ratio Settings"));
+ aspectRatio_layout->addWidget(aspectRatioLabel);
+ aspectRatioAuto = new QRadioButton(i18n("Automatic"));
+ aspectRatio_layout->addWidget(aspectRatioAuto);
+ aspectRatio4_3 = new QRadioButton(i18n("4:3"));
+ aspectRatio_layout->addWidget(aspectRatio4_3);
+ aspectRatio16_9 = new QRadioButton(i18n("16:9"));
+ aspectRatio_layout->addWidget(aspectRatio16_9);
+ aspectRatioWidget = new QRadioButton(i18n("Fit"));
+ aspectRatio_layout->addWidget(aspectRatioWidget);
+ aspectRatio_Widget->setLayout(aspectRatio_layout);
+
+ scaleMode_Widget = new QWidget();
+ scaleMode_layout = new QVBoxLayout();
+
+ scaleModeLabel = new QLabel(i18n("Scaling Mode")) ;
+ scaleMode_layout->addWidget(scaleModeLabel);
+ scaleModeFitInView = new QRadioButton(i18n("Scale to fit"));
+ scaleMode_layout->addWidget(scaleModeFitInView);
+ scaleModeScaleAndCrop = new QRadioButton(i18n("Scale and crop"));
+ scaleMode_layout->addWidget(scaleModeScaleAndCrop);
+ scaleMode_Widget->setLayout(scaleMode_layout);
+
+ sizeSettings_layout->addWidget(aspectRatio_Widget);
+ sizeSettings_layout->addWidget(scaleMode_Widget);
+
+
+ restoreButton = new KPushButton();
+ restoreButton->setIcon(KIcon("view-restore"));
+ restoreButton->setText(i18n("Restore Defaults"));
+ hideButton = new KPushButton();
+ hideButton->setText(i18n("Hide"));
+ button_layout->addWidget(restoreButton);
+ button_layout->addWidget(hideButton);
+
+ m_layout->addWidget(videoColorWidget);
+ m_layout->addLayout(sizeSettings_layout);
+ m_layout->addLayout(button_layout);
+ videoWidget = widget;
+
+ if(widget->aspectRatio() == VideoWidget::AspectRatioAuto)
+ aspectRatioAuto->setChecked(true);
+ if(widget->aspectRatio() == VideoWidget::AspectRatioWidget)
+ aspectRatioWidget->setChecked(true);
+ if(widget->aspectRatio() == VideoWidget::AspectRatio4_3)
+ aspectRatio4_3->setChecked(true);
+ if(widget->aspectRatio() == VideoWidget::AspectRatio16_9)
+ aspectRatio16_9->setChecked(true);
+
+ if(widget->scaleMode() == VideoWidget::FitInView)
+ scaleModeFitInView->setChecked(true);
+ if(widget->scaleMode() == VideoWidget::ScaleAndCrop)
+ scaleModeScaleAndCrop->setChecked(true);
+
+ setLayout(m_layout);
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ setupConnections();
+}
+void
+VideoSettings::setupConnections()
+{
+ connect(brightnessSlider,SIGNAL(valueChanged(int)),this,SLOT(setBrightness(int)));
+ connect(contrastSlider,SIGNAL(valueChanged(int)),this,SLOT(setContrast(int)));
+ connect(hueSlider,SIGNAL(valueChanged(int)),this,SLOT(setHue(int)));
+ connect(saturationSlider,SIGNAL(valueChanged(int)),this,SLOT(setSaturation(int)));
+
+ connect(aspectRatioAuto,SIGNAL(toggled(bool)),
+ this,SLOT(setAspectRatioAuto(bool)));
+ connect(aspectRatioWidget,SIGNAL(toggled(bool)),
+ this,SLOT(setAspectRatioWidget(bool)));
+ connect(aspectRatio4_3,SIGNAL(toggled(bool)),
+ this,SLOT(setAspectRatio4_3(bool)));
+ connect(aspectRatio16_9,SIGNAL(toggled(bool)),
+ this,SLOT(setAspectRatio16_9(bool)));
+
+ connect(scaleModeFitInView,SIGNAL(toggled(bool)),
+ this,SLOT(setScaleModeFitInView(bool)));
+ connect(scaleModeScaleAndCrop,SIGNAL(toggled(bool)),
+ this,SLOT(setScaleModeScaleAndCrop(bool)));
+
+ connect(restoreButton,SIGNAL(clicked()),this,SLOT(restoreClicked()));
+}
+
+VideoSettings::~VideoSettings()
+{
+
+}
+
+void VideoSettings::setBrightness(int ch)
+{
+ videoWidget->setBrightness(qreal(ch)/100);
+}
+
+void VideoSettings::setContrast(int ch)
+{
+ videoWidget->setContrast(qreal(ch)/100);
+}
+
+void VideoSettings::setHue(int ch)
+{
+ videoWidget->setHue(qreal(ch)/100);
+}
+
+void VideoSettings::setSaturation(int ch)
+{
+ videoWidget->setSaturation(qreal(ch)/100);
+}
+
+void VideoSettings::setAspectRatioAuto(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setAspectRatio(VideoWidget::AspectRatioAuto);
+ setScaleSettingsEnabled(true);
+}
+
+void VideoSettings::setAspectRatio4_3(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setAspectRatio(VideoWidget::AspectRatio4_3);
+ setScaleSettingsEnabled(true);
+}
+
+void VideoSettings::setAspectRatio16_9(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setAspectRatio(VideoWidget::AspectRatio16_9);
+ setScaleSettingsEnabled(true);
+}
+
+void VideoSettings::setAspectRatioWidget(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setAspectRatio(VideoWidget::AspectRatioWidget);
+ setScaleSettingsEnabled(false);
+}
+
+void VideoSettings::setScaleModeFitInView(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setScaleMode(VideoWidget::FitInView);
+}
+
+void VideoSettings::setScaleModeScaleAndCrop(bool checked)
+{
+ Q_UNUSED(checked);
+ videoWidget->setScaleMode(VideoWidget::ScaleAndCrop);
+}
+
+void VideoSettings::restoreClicked()
+{
+ videoWidget->setBrightness(0);
+ videoWidget->setContrast(0);
+ videoWidget->setHue(0);
+ videoWidget->setSaturation(0);
+
+ videoWidget->setAspectRatio(VideoWidget::AspectRatioAuto);
+ videoWidget->setScaleMode(VideoWidget::FitInView);
+
+ brightnessSlider->setValue(0);
+ contrastSlider->setValue(0);
+ hueSlider->setValue(0);
+ saturationSlider->setValue(0);
+ aspectRatioAuto->setChecked(true);
+ scaleModeFitInView->setChecked(true);
+}
+
+void VideoSettings::setHideAction(QAction * hideAction)
+{
+ connect(hideButton, SIGNAL(clicked()), hideAction, SLOT(trigger()));
+}
+
+void VideoSettings::setScaleSettingsEnabled(bool enabled)
+{
+ scaleModeFitInView->setEnabled(enabled);
+ scaleModeScaleAndCrop->setEnabled(enabled);
+}
+#include "moc_videosettings.cpp"
diff --git a/src/videosettings.h b/src/videosettings.h
new file mode 100644
index 0000000..f82af8b
--- /dev/null
+++ b/src/videosettings.h
@@ -0,0 +1,124 @@
+/* BANGARANG MEDIA PLAYER
+* Copyright (C) 2009 Andreas Marschke (xxtjaxx at gmail.com)
+* <http://gitorious.org/bangarang>
+*
+* 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEOSETTINGS_H
+#define VIDEOSETTINGS_H
+
+#include <QWidget>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QGridLayout>
+#include <QSlider>
+#include <QLabel>
+#include <QRadioButton>
+#include <QButtonGroup>
+#include <QGroupBox>
+
+#include <KPushButton>
+#include <KButtonGroup>
+
+#include <phonon/videowidget.h>
+
+/**
+ * @short Video Settings
+ * @author Andreas Marschke xxtjaxx at gmail.com
+ * @version 0.1
+ **/
+using namespace Phonon;
+
+class VideoSettings : public QWidget
+{
+ Q_OBJECT
+public:
+
+ /**
+ * Default constructor
+ **/
+ VideoSettings(VideoWidget *videoWidget ,QWidget *parent);
+
+ /**
+ * Destructor
+ */
+ virtual ~VideoSettings();
+ void setHideAction(QAction *hideAction);
+
+private:
+ //Qt
+ QVBoxLayout *m_layout;
+ QGridLayout *colorSettings_layout;
+ QVBoxLayout *sizeSettings_layout;
+ QHBoxLayout *button_layout;
+
+ //to have to uninterferring radio groups
+ QWidget *videoColorWidget;
+ QSlider *brightnessSlider;
+ QSlider *contrastSlider;
+ QSlider *hueSlider;
+ QSlider *saturationSlider;
+
+ QLabel *brightnessLabel;
+ QLabel *contrastLabel;
+ QLabel *hueLabel;
+ QLabel *saturationLabel;
+
+ QWidget *aspectRatio_Widget;
+ QVBoxLayout *aspectRatio_layout;
+ QLabel *aspectRatioLabel;
+ QRadioButton *aspectRatioAuto;
+ QRadioButton *aspectRatioWidget;
+ QRadioButton *aspectRatio4_3;
+ QRadioButton *aspectRatio16_9;
+
+ QWidget *scaleMode_Widget;
+ QVBoxLayout *scaleMode_layout;
+ QLabel *scaleModeLabel;
+ QRadioButton *scaleModeFitInView;
+ QRadioButton *scaleModeScaleAndCrop;
+
+ KPushButton *restoreButton;
+ KPushButton *hideButton;
+
+ VideoWidget *videoWidget;
+ void setupConnections();
+ void setScaleSettingsEnabled(bool enabled);
+
+signals:
+ void brightnessChanged(qreal num);
+ void contrastChanged(qreal num);
+ void hueChanged(qreal num);
+ void saturationChanged(qreal num);
+ void okClicked();
+private slots:
+ void setBrightness(int ch);
+ void setContrast(int ch);
+ void setHue(int ch);
+ void setSaturation(int ch);
+
+ void setAspectRatioAuto(bool checked);
+ void setAspectRatioWidget(bool checked);
+ void setAspectRatio4_3(bool checked);
+ void setAspectRatio16_9(bool checked);
+
+ void setScaleModeFitInView(bool checked);
+ void setScaleModeScaleAndCrop(bool checked);
+
+ void restoreClicked();
+
+};
+
+#endif // VIDEOSETTINGS_H
diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt
new file mode 100644
index 0000000..fe983ec
--- /dev/null
+++ b/translations/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory( nl )
+add_subdirectory( de )
+add_subdirectory( fr )
diff --git a/translations/bangarang.pot b/translations/bangarang.pot
new file mode 100644
index 0000000..bfe8e7f
--- /dev/null
+++ b/translations/bangarang.pot
@@ -0,0 +1,1040 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR This_file_is_part_of_KDE
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2009-12-21 22:58-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: actionsmanager.cpp:48
+msgid "Quit"
+msgstr ""
+
+#: actionsmanager.cpp:57
+msgid "Play next"
+msgstr ""
+
+#: actionsmanager.cpp:63
+msgid "Play previous"
+msgstr ""
+
+#: actionsmanager.cpp:75 mainwindow.cpp:1087
+msgid "Play all"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1811
+#. i18n: ectx: property (text), widget (QPushButton, playAll)
+#: actionsmanager.cpp:77 rc.cpp:158
+msgid "Play All"
+msgstr ""
+
+#: actionsmanager.cpp:80 mainwindow.cpp:1089
+msgid "Play selected"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1837
+#. i18n: ectx: property (text), widget (QPushButton, playSelected)
+#: actionsmanager.cpp:82 rc.cpp:164
+msgid "Play Selected"
+msgstr ""
+
+#: actionsmanager.cpp:85 actionsmanager.cpp:87
+msgid "Add to playlist"
+msgstr ""
+
+#: actionsmanager.cpp:90 actionsmanager.cpp:92
+msgid "Remove from playlist"
+msgstr ""
+
+#: actionsmanager.cpp:95 actionsmanager.cpp:99
+msgid "Hide controls"
+msgstr ""
+
+#: actionsmanager.cpp:106 actionsmanager.cpp:381 mainwindow.cpp:348
+msgid "Show Video Settings"
+msgstr ""
+
+#: actionsmanager.cpp:113
+msgid "Toggle fullscreen"
+msgstr ""
+
+#: actionsmanager.cpp:122
+msgid "Remove selected info"
+msgstr ""
+
+#: actionsmanager.cpp:127
+msgid "Refresh"
+msgstr ""
+
+#: actionsmanager.cpp:133
+msgid "Remove from list"
+msgstr ""
+
+#: actionsmanager.cpp:137
+msgid "Add to list"
+msgstr ""
+
+#: actionsmanager.cpp:141
+msgid "Add to list "
+msgstr ""
+
+#: actionsmanager.cpp:145 actionsmanager.cpp:149
+msgid "New list"
+msgstr ""
+
+#: actionsmanager.cpp:153
+msgid "Show items"
+msgstr ""
+
+#: actionsmanager.cpp:158
+msgid "Configure shortcuts..."
+msgstr ""
+
+#: actionsmanager.cpp:377
+msgid "Hide Video Settings"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1673
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:239 rc.cpp:143
+msgid "Title"
+msgstr ""
+
+#: infomanager.cpp:241
+msgid "Artwork"
+msgstr ""
+
+#: infomanager.cpp:243
+msgid "Description"
+msgstr ""
+
+#: infomanager.cpp:245
+msgid "Location"
+msgstr ""
+
+#: infomanager.cpp:287 infomanager.cpp:345
+msgid "Type"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1681
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:306 rc.cpp:146
+msgid "Artist"
+msgstr ""
+
+#: infomanager.cpp:308
+msgid "Album"
+msgstr ""
+
+#: infomanager.cpp:310 infomanager.cpp:366 infomanager.cpp:396
+msgid "Year"
+msgstr ""
+
+#: infomanager.cpp:312
+msgid "Track Number"
+msgstr ""
+
+#: infomanager.cpp:314 infomanager.cpp:368
+msgid "Genre"
+msgstr ""
+
+#: infomanager.cpp:364
+msgid "Collection/Series Name"
+msgstr ""
+
+#: infomanager.cpp:391
+msgid "Series Name"
+msgstr ""
+
+#: infomanager.cpp:393
+msgid "Season"
+msgstr ""
+
+#: infomanager.cpp:395
+msgid "Episode"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:23
+#. i18n: ectx: property (windowTitle), widget (QMainWindow, MainWindowClass)
+#: main.cpp:29 mainwindow.cpp:274 mainwindow.cpp:551 mainwindow.cpp:924
+#: mainwindow.cpp:1098 rc.cpp:5
+msgid "Bangarang"
+msgstr ""
+
+#: main.cpp:30
+msgid "A Media Player"
+msgstr ""
+
+#: main.cpp:31
+msgid "Copyright 2009, Andrew Lake"
+msgstr ""
+
+#: main.cpp:38
+msgid "Andrew (Jamboarder) Lake"
+msgstr ""
+
+#: main.cpp:38
+msgid "Creator"
+msgstr ""
+
+#: main.cpp:39
+msgid "Sebastian Jambor"
+msgstr ""
+
+#: main.cpp:39 main.cpp:40 main.cpp:41
+msgid "Contributor"
+msgstr ""
+
+#: main.cpp:40
+msgid "Janusz Lewandowski"
+msgstr ""
+
+#: main.cpp:41
+msgid "Andreas Marschke"
+msgstr ""
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at http://code.google.com/p/bangarangissuetracking/"
+msgstr ""
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>Bangarang Issue Tracker</a>"
+msgstr ""
+
+#: main.cpp:50
+msgid "Play 'URL'"
+msgstr ""
+
+#: main.cpp:51
+msgid "Play DVD Video"
+msgstr ""
+
+#: main.cpp:52
+msgid "Play CD Music"
+msgstr ""
+
+#: main.cpp:53
+msgid "Show Additional Debug Output"
+msgstr ""
+
+#: mainwindow.cpp:238 platform/medialistsengine.cpp:183
+msgid "DVD Video"
+msgstr ""
+
+#: mainwindow.cpp:248 platform/medialistsengine.cpp:93
+msgid "Audio CD"
+msgstr ""
+
+#: mainwindow.cpp:274
+msgid ""
+"Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media "
+"library, rating and play count functions will be unavailable."
+msgstr ""
+
+#: mainwindow.cpp:274
+msgid "Don't show this message again"
+msgstr ""
+
+#: mainwindow.cpp:356
+msgid "<b>Fullscreen</b><br>Click to exit fullscreen"
+msgstr ""
+
+#: mainwindow.cpp:363
+msgid "Show fullscreen"
+msgstr ""
+
+#: mainwindow.cpp:374 mainwindow.cpp:644
+msgid "<b>Time remaining</b><br>Click to show elapsed time"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5535
+#. i18n: ectx: property (toolTip), widget (QToolButton, seekTime)
+#: mainwindow.cpp:376 mainwindow.cpp:646 rc.cpp:215
+msgid "<b>Time elapsed</b><br>Click to show remaining time"
+msgstr ""
+
+#: mainwindow.cpp:385
+msgid "<b>Paused</b><br>Hold to stop"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:253
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, Filter)
+#: mainwindow.cpp:516 rc.cpp:11
+msgid "Search for audio"
+msgstr ""
+
+#: mainwindow.cpp:524
+msgid "Search for video"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5147
+#. i18n: ectx: property (toolTip), widget (QToolButton, clearPlaylist)
+#: mainwindow.cpp:547 rc.cpp:179
+msgid "Clear Playlist"
+msgstr ""
+
+#: mainwindow.cpp:548
+msgid "Are you sure you want to clear the current playlist?"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1202
+#. i18n: ectx: property (text), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:553 mainwindow.cpp:654 mainwindow.cpp:656 mainwindow.cpp:926
+#: rc.cpp:113
+msgid "Now Playing"
+msgstr ""
+
+#: mainwindow.cpp:563
+msgid "<b>Shuffle On</b><br>Click to turn off Shuffle"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5203
+#. i18n: ectx: property (toolTip), widget (QToolButton, shuffle)
+#: mainwindow.cpp:567 rc.cpp:188
+msgid "Turn on Shuffle"
+msgstr ""
+
+#: mainwindow.cpp:578
+msgid "<b>Repeat On</b><br>Click to turn off repeat"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5174
+#. i18n: ectx: property (toolTip), widget (QToolButton, repeat)
+#: mainwindow.cpp:581 rc.cpp:182
+msgid "Turn on Repeat"
+msgstr ""
+
+#: mainwindow.cpp:590
+msgid "<b>Showing Upcoming</b><br>Click to show playlist"
+msgstr ""
+
+#: mainwindow.cpp:591
+msgid "<b>Playlist</b>(Upcoming)"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5092
+#. i18n: ectx: property (toolTip), widget (QToolButton, showQueue)
+#: mainwindow.cpp:595 rc.cpp:173
+msgid "Show Upcoming"
+msgstr ""
+
+#: mainwindow.cpp:670
+msgid "<b>Playing</b><br>Click to pause<br>Click and hold to stop"
+msgstr ""
+
+#: mainwindow.cpp:681
+msgid "An error has been encountered during playback"
+msgstr ""
+
+#: mainwindow.cpp:701
+msgid "Loading playlist..."
+msgstr ""
+
+#: mainwindow.cpp:703
+msgid "Buffering..."
+msgstr ""
+
+#: mainwindow.cpp:705 platform/mediaitemmodel.cpp:501
+msgid "Loading..."
+msgstr ""
+
+#: mainwindow.cpp:717
+msgid "<b>Muted</b><br>Click to restore volume"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5661
+#. i18n: ectx: property (toolTip), widget (SToolButton, volumeIcon)
+#: mainwindow.cpp:720 rc.cpp:221
+msgid "Mute volume"
+msgstr ""
+
+#: mainwindow.cpp:757
+msgid "Updating..."
+msgstr ""
+
+#: mainwindow.cpp:763
+msgid "Complete"
+msgstr ""
+
+#: mainwindow.cpp:769
+msgid "Updated info for "
+msgstr ""
+
+#: mainwindow.cpp:775
+msgid "Removed info for "
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5124
+#. i18n: ectx: property (text), widget (QLabel, playlistName)
+#: mainwindow.cpp:879 rc.cpp:176
+msgid "<b>Playlist</b>"
+msgstr ""
+
+#: mainwindow.cpp:882
+#, kde-format
+msgid "1 item, %2"
+msgid_plural "%1 items, %2"
+msgstr[0] ""
+msgstr[1] ""
+
+#. i18n: file: mainwindow.ui:1199
+#. i18n: ectx: property (toolTip), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:897 mainwindow.cpp:927 rc.cpp:110
+msgid "View Now Playing"
+msgstr ""
+
+#: mainwindow.cpp:1099
+msgid "Entertainment... Now"
+msgstr ""
+
+#: rc.cpp:1
+msgctxt "NAME OF TRANSLATORS"
+msgid "Your names"
+msgstr ""
+
+#: rc.cpp:2
+msgctxt "EMAIL OF TRANSLATORS"
+msgid "Your emails"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:149
+#. i18n: ectx: property (text), widget (QLabel, label)
+#. i18n: file: mainwindow.ui:5405
+#. i18n: ectx: property (text), widget (QToolButton, collectionButton)
+#: rc.cpp:8 rc.cpp:206
+msgid "Media Lists"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:296
+#. i18n: ectx: attribute (label), widget (QWidget, AudioTool_2)
+#: rc.cpp:14
+msgid "Audio"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:364
+#. i18n: ectx: property (toolTip), widget (QToolButton, addAudioList)
+#. i18n: file: mainwindow.ui:801
+#. i18n: ectx: property (toolTip), widget (QToolButton, addVideoList)
+#: rc.cpp:17 rc.cpp:65
+msgid "Add list"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:381
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeAudioList)
+#. i18n: file: mainwindow.ui:818
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeVideoList)
+#: rc.cpp:20 rc.cpp:68
+msgid "Remove list"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:411
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureAudioList)
+#. i18n: file: mainwindow.ui:848
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureVideoList)
+#: rc.cpp:23 rc.cpp:71
+msgid "Settings"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:460
+#. i18n: ectx: property (text), widget (QLabel, label_5)
+#. i18n: file: mainwindow.ui:897
+#. i18n: ectx: property (text), widget (QLabel, label_7)
+#: rc.cpp:26 rc.cpp:74
+msgid "Add List"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:477
+#. i18n: ectx: property (text), widget (QLabel, label_4)
+#. i18n: file: mainwindow.ui:914
+#. i18n: ectx: property (text), widget (QLabel, label_6)
+#: rc.cpp:29 rc.cpp:77
+msgid "Source"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:499
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceView)
+#. i18n: file: mainwindow.ui:940
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceView)
+#: rc.cpp:32 rc.cpp:83
+msgid "Current View"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:506
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceSelection)
+#. i18n: file: mainwindow.ui:933
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceSelection)
+#: rc.cpp:35 rc.cpp:80
+msgid "Current Selection"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:513
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourcePlaylist)
+#. i18n: file: mainwindow.ui:947
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourcePlaylist)
+#: rc.cpp:38 rc.cpp:86
+msgid "Current Playlist"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:523
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, aNewListName)
+#. i18n: file: mainwindow.ui:957
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, vNewListName)
+#: rc.cpp:41 rc.cpp:89
+msgid "New List Name"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:545
+#. i18n: ectx: property (text), widget (QPushButton, saveAudioList)
+#. i18n: file: mainwindow.ui:689
+#. i18n: ectx: property (text), widget (QPushButton, aslsSave)
+#. i18n: file: mainwindow.ui:976
+#. i18n: ectx: property (text), widget (QPushButton, saveVideoList)
+#. i18n: file: mainwindow.ui:1096
+#. i18n: ectx: property (text), widget (QPushButton, vslsSave)
+#. i18n: file: mainwindow.ui:1782
+#. i18n: ectx: property (text), widget (QPushButton, saveInfo)
+#: rc.cpp:44 rc.cpp:56 rc.cpp:92 rc.cpp:104 rc.cpp:152
+msgid "Save"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:599
+#. i18n: ectx: property (text), widget (QToolButton, aCancelSaveList)
+#. i18n: file: mainwindow.ui:719
+#. i18n: ectx: property (text), widget (QToolButton, aslsCancel)
+#. i18n: file: mainwindow.ui:1126
+#. i18n: ectx: property (text), widget (QToolButton, vslsCancel)
+#: rc.cpp:47 rc.cpp:59 rc.cpp:107
+msgid "Return to Lists"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:638
+#. i18n: ectx: property (text), widget (QLabel, label_8)
+#. i18n: file: mainwindow.ui:1045
+#. i18n: ectx: property (text), widget (QLabel, label_11)
+#: rc.cpp:50 rc.cpp:98
+msgid "Saved List Settings"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:664
+#. i18n: ectx: property (text), widget (QLabel, label_9)
+#. i18n: file: mainwindow.ui:1071
+#. i18n: ectx: property (text), widget (QLabel, label_10)
+#: rc.cpp:53 rc.cpp:101
+msgid "Name"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:748
+#. i18n: ectx: attribute (label), widget (QWidget, videoTool_2)
+#: rc.cpp:62
+msgid "Video"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1009
+#. i18n: ectx: property (text), widget (QToolButton, vCancelSaveList)
+#: rc.cpp:95
+msgid "Return To Lists"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1352
+#. i18n: ectx: property (text), widget (QLabel, listTitle)
+#: rc.cpp:116
+msgid "List Title"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1365
+#. i18n: ectx: property (text), widget (QLabel, listSummary)
+#: rc.cpp:119
+msgid "Summary"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1375
+#. i18n: ectx: property (text), widget (QToolButton, sortList)
+#: rc.cpp:122
+msgid "Sort"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1399
+#. i18n: ectx: property (text), widget (QToolButton, showInfo)
+#: rc.cpp:125
+msgid "Info"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1514
+#. i18n: ectx: property (text), widget (QLabel, notificationText)
+#: rc.cpp:128
+msgid "Notification Text"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1589
+#. i18n: ectx: property (text), widget (QLabel, label_2)
+#: rc.cpp:131
+msgid "Information"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1596
+#. i18n: ectx: property (text), widget (QToolButton, editInfo)
+#: rc.cpp:134
+msgid "Edit"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1663
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:137
+msgid "1"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1668
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:140
+msgid "2"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1747
+#. i18n: ectx: property (text), widget (QToolButton, previous)
+#: rc.cpp:149
+msgid "Previous"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1805
+#. i18n: ectx: property (toolTip), widget (QPushButton, playAll)
+#: rc.cpp:155
+msgid "Play all media in list"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1834
+#. i18n: ectx: property (toolTip), widget (QPushButton, playSelected)
+#: rc.cpp:161
+msgid "Play selected media in list"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:2346
+#. i18n: ectx: property (text), widget (QLabel, playbackMessage)
+#: rc.cpp:167
+msgid "Playback message"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:2375
+#. i18n: ectx: property (text), widget (QToolButton, showPlaylist)
+#: rc.cpp:170
+msgid "Playlist"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5177
+#. i18n: ectx: property (text), widget (QToolButton, repeat)
+#. i18n: file: mainwindow.ui:5206
+#. i18n: ectx: property (text), widget (QToolButton, shuffle)
+#. i18n: file: mainwindow.ui:5449
+#. i18n: ectx: property (text), widget (SToolButton, fullScreen)
+#: rc.cpp:185 rc.cpp:191 rc.cpp:212
+msgid "[ ]"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5306
+#. i18n: ectx: property (text), widget (QLabel, label_3)
+#: rc.cpp:194
+msgid "Video Settings"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5335
+#. i18n: ectx: property (text), widget (QPushButton, saveShortCuts)
+#: rc.cpp:197
+msgid "Save Shortcuts"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5342
+#. i18n: ectx: property (text), widget (QPushButton, cancelEditShortcuts)
+#: rc.cpp:200
+msgid "Cancel"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5402
+#. i18n: ectx: property (toolTip), widget (QToolButton, collectionButton)
+#: rc.cpp:203
+msgid "View Media Lists"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5446
+#. i18n: ectx: property (toolTip), widget (SToolButton, fullScreen)
+#: rc.cpp:209
+msgid "Show full screen"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5538
+#. i18n: ectx: property (text), widget (QToolButton, seekTime)
+#: rc.cpp:218
+msgid "03:00"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5699
+#. i18n: ectx: property (toolTip), widget (Phonon::VolumeSlider, volumeSlider)
+#: rc.cpp:224
+msgid "Volume"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5725
+#. i18n: ectx: property (text), widget (QToolButton, mediaPrevious)
+#. i18n: file: mainwindow.ui:5754
+#. i18n: ectx: property (text), widget (SToolButton, mediaPlayPause)
+#. i18n: file: mainwindow.ui:5774
+#. i18n: ectx: property (text), widget (QToolButton, mediaNext)
+#: rc.cpp:227 rc.cpp:230 rc.cpp:233
+msgid "..."
+msgstr ""
+
+#: videosettings.cpp:73
+msgid "Brightness"
+msgstr ""
+
+#: videosettings.cpp:83
+msgid "Contrast"
+msgstr ""
+
+#: videosettings.cpp:93
+msgid "Hue"
+msgstr ""
+
+#: videosettings.cpp:103
+msgid "Saturation"
+msgstr ""
+
+#: videosettings.cpp:118
+msgid "Aspect Ratio Settings"
+msgstr ""
+
+#: videosettings.cpp:120
+msgid "Automatic"
+msgstr ""
+
+#: videosettings.cpp:122
+msgid "4:3"
+msgstr ""
+
+#: videosettings.cpp:124
+msgid "16:9"
+msgstr ""
+
+#: videosettings.cpp:126
+msgid "Fit"
+msgstr ""
+
+#: videosettings.cpp:133
+msgid "Scaling Mode"
+msgstr ""
+
+#: videosettings.cpp:135
+msgid "Scale to fit"
+msgstr ""
+
+#: videosettings.cpp:137
+msgid "Scale and crop"
+msgstr ""
+
+#: videosettings.cpp:147
+msgid "Restore Defaults"
+msgstr ""
+
+#: videosettings.cpp:149
+msgid "Hide"
+msgstr ""
+
+#: platform/audioclipslistengine.cpp:107 platform/audioclipslistengine.cpp:131
+#: platform/videolistengine.cpp:176
+#, kde-format
+msgid "1 clip"
+msgid_plural "%1 clips"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/audiostreamlistengine.cpp:103
+#: platform/audiostreamlistengine.cpp:134
+#, kde-format
+msgid "1 stream"
+msgid_plural "%1 streams"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/audiostreamlistengine.cpp:108
+msgid "Create new audio stream item"
+msgstr ""
+
+#: platform/audiostreamlistengine.cpp:155
+msgid "Untitled Audio Stream"
+msgstr ""
+
+#: platform/audiostreamlistengine.cpp:156
+msgid "Select this item, click Info then Edit to enter audio stream info"
+msgstr ""
+
+#: platform/audiostreamlistengine.cpp:165
+msgid "New Audio Stream"
+msgstr ""
+
+#: platform/cdlistengine.cpp:80
+#, kde-format
+msgid "Track %1"
+msgstr ""
+
+#: platform/cdlistengine.cpp:84
+#, kde-format
+msgid "Audio CD - %1 Tracks"
+msgstr ""
+
+#: platform/cdlistengine.cpp:93
+#, kde-format
+msgid "1 track"
+msgid_plural "%1 tracks"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/dvdlistengine.cpp:76
+#, kde-format
+msgid "Title %1"
+msgstr ""
+
+#: platform/dvdlistengine.cpp:80
+#, kde-format
+msgid "DVD Video - %1 Titles"
+msgstr ""
+
+#: platform/filelistengine.cpp:69 platform/filelistengine.cpp:86
+msgid "Audio Files"
+msgstr ""
+
+#: platform/filelistengine.cpp:74 platform/filelistengine.cpp:97
+msgid "Video Files"
+msgstr ""
+
+#: platform/filelistengine.cpp:87 platform/filelistengine.cpp:98
+#: platform/filelistengine.cpp:182 platform/mediaitemmodel.cpp:381
+#: platform/savedlistsengine.cpp:102 platform/videolistengine.cpp:451
+#: platform/videolistengine.cpp:517
+#, kde-format
+msgid "1 item"
+msgid_plural "%1 items"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/filelistengine.cpp:122 platform/filelistengine.cpp:197
+msgid "Open audio file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:127 platform/filelistengine.cpp:208
+msgid "Open folder containing audio file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:133 platform/filelistengine.cpp:202
+msgid "Open video file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:138 platform/filelistengine.cpp:213
+msgid "Open folder containing video file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:144
+msgid "Open image file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:149
+msgid "Open folder containing image file(s)"
+msgstr ""
+
+#: platform/filelistengine.cpp:326
+msgid "Audio Clip"
+msgstr ""
+
+#: platform/filelistengine.cpp:413
+#, kde-format
+msgid "%1 - Episode %2"
+msgstr ""
+
+#: platform/filelistengine.cpp:415
+#, kde-format
+msgid "Episode %1"
+msgstr ""
+
+#: platform/mediaitemmodel.cpp:380
+#, kde-format
+msgid "Multiple %1"
+msgstr ""
+
+#: platform/mediaitemmodel.cpp:532
+msgid "No results"
+msgstr ""
+
+#: platform/mediaitemmodel.cpp:563
+msgid "Add to playlist/Remove from playlist"
+msgstr ""
+
+#: platform/medialistsengine.cpp:52 platform/medialistsengine.cpp:150
+msgid "Files and Folders"
+msgstr ""
+
+#: platform/medialistsengine.cpp:57 platform/musiclistengine.cpp:222
+msgid "Artists"
+msgstr ""
+
+#: platform/medialistsengine.cpp:61 platform/musiclistengine.cpp:262
+msgid "Albums"
+msgstr ""
+
+#: platform/medialistsengine.cpp:65 platform/musiclistengine.cpp:353
+msgid "Songs"
+msgstr ""
+
+#: platform/medialistsengine.cpp:69 platform/medialistsengine.cpp:159
+#: platform/musiclistengine.cpp:306 platform/videolistengine.cpp:402
+msgid "Genres"
+msgstr ""
+
+#: platform/medialistsengine.cpp:73
+msgid "Clips"
+msgstr ""
+
+#: platform/medialistsengine.cpp:77
+msgid "Audio Streams"
+msgstr ""
+
+#: platform/medialistsengine.cpp:100 platform/medialistsengine.cpp:190
+#: platform/semanticslistengine.cpp:89
+msgid "Frequently Played"
+msgstr ""
+
+#: platform/medialistsengine.cpp:104 platform/medialistsengine.cpp:194
+#: platform/semanticslistengine.cpp:115
+msgid "Recently Played"
+msgstr ""
+
+#: platform/medialistsengine.cpp:108 platform/medialistsengine.cpp:198
+#: platform/semanticslistengine.cpp:140
+msgid "Highest Rated"
+msgstr ""
+
+#: platform/medialistsengine.cpp:155 platform/videolistengine.cpp:369
+msgid "Movies"
+msgstr ""
+
+#: platform/medialistsengine.cpp:163 platform/videolistengine.cpp:224
+msgid "TV Shows"
+msgstr ""
+
+#: platform/medialistsengine.cpp:167 platform/videolistengine.cpp:175
+msgid "Video Clips"
+msgstr ""
+
+#: platform/musiclistengine.cpp:224
+#, kde-format
+msgid "Artists - %1"
+msgstr ""
+
+#: platform/musiclistengine.cpp:226
+#, kde-format
+msgid "1 artist"
+msgid_plural "%1 artists"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:264 platform/musiclistengine.cpp:267
+#, kde-format
+msgid "Albums - %1"
+msgstr ""
+
+#: platform/musiclistengine.cpp:270
+#, kde-format
+msgid "Albums - %1 - %2"
+msgstr ""
+
+#: platform/musiclistengine.cpp:273
+#, kde-format
+msgid "1 album"
+msgid_plural "%1 albums"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:307 platform/videolistengine.cpp:403
+#, kde-format
+msgid "1 genre"
+msgid_plural "%1 genres"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:355 platform/musiclistengine.cpp:383
+#, kde-format
+msgid "1 song"
+msgid_plural "%1 songs"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:216 platform/videolistengine.cpp:332
+msgid "Uncategorized TV Shows"
+msgstr ""
+
+#: platform/videolistengine.cpp:225
+#, kde-format
+msgid "1 show"
+msgid_plural "%1 shows"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:253
+#, kde-format
+msgid "Season %1"
+msgstr ""
+
+#: platform/videolistengine.cpp:272
+msgid "Uncategorized seasons"
+msgstr ""
+
+#: platform/videolistengine.cpp:279
+#, kde-format
+msgid "Seasons - %1"
+msgstr ""
+
+#: platform/videolistengine.cpp:280
+#, kde-format
+msgid "1 season"
+msgid_plural "%1 seasons"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:334
+#, kde-format
+msgid "%1 - Season %2"
+msgstr ""
+
+#: platform/videolistengine.cpp:336
+#, kde-format
+msgid "%1 - Uncategorized Seasons"
+msgstr ""
+
+#: platform/videolistengine.cpp:338
+#, kde-format
+msgid "1 episode"
+msgid_plural "%1 episodes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:371
+#, kde-format
+msgid "Movies - %1"
+msgstr ""
+
+#: platform/videolistengine.cpp:373
+#, kde-format
+msgid "1 movie"
+msgid_plural "%1 movies"
+msgstr[0] ""
+msgstr[1] ""
diff --git a/translations/de/CMakeLists.txt b/translations/de/CMakeLists.txt
new file mode 100644
index 0000000..2346309
--- /dev/null
+++ b/translations/de/CMakeLists.txt
@@ -0,0 +1,2 @@
+file(GLOB _po_files *.po)
+GETTEXT_PROCESS_PO_FILES( de ALL INSTALL_DESTINATION ${LOCALE_INSTALL_DIR} ${_po_files} )
diff --git a/translations/de/bangarang.po b/translations/de/bangarang.po
new file mode 100644
index 0000000..ec473f6
--- /dev/null
+++ b/translations/de/bangarang.po
@@ -0,0 +1,1077 @@
+# This is the german translation of bangarang.
+# Copyright (C) 2009 bangarang-project
+# This file is distributed under the same license as the bangarang package.
+# Andreas Marschke <xxtjaxx at gmail.com>, 2009.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2009-12-21 22:58-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Andreas Marschke <xxtjaxx at gmail.com>\n"
+"Language-Team: GERMAN <DE at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: actionsmanager.cpp:48
+msgid "Quit"
+msgstr "Schliessen"
+
+#: actionsmanager.cpp:57
+msgid "Play next"
+msgstr "Nächstes abspielen"
+
+#: actionsmanager.cpp:63
+msgid "Play previous"
+msgstr "Vorheriges abspielen"
+
+#: actionsmanager.cpp:75 mainwindow.cpp:1087
+msgid "Play all"
+msgstr "Alle abspielen"
+
+#. i18n: file: mainwindow.ui:1811
+#. i18n: ectx: property (text), widget (QPushButton, playAll)
+#: actionsmanager.cpp:77 rc.cpp:158
+msgid "Play All"
+msgstr "Alle Abspielen"
+
+#: actionsmanager.cpp:80 mainwindow.cpp:1089
+msgid "Play selected"
+msgstr "Auswahl abspielen"
+
+#. i18n: file: mainwindow.ui:1837
+#. i18n: ectx: property (text), widget (QPushButton, playSelected)
+#: actionsmanager.cpp:82 rc.cpp:164
+msgid "Play Selected"
+msgstr "Auswahl Abspielen"
+
+#: actionsmanager.cpp:85 actionsmanager.cpp:87
+msgid "Add to playlist"
+msgstr "Zur Wiedergabeliste hinzufügen"
+
+#: actionsmanager.cpp:90 actionsmanager.cpp:92
+msgid "Remove from playlist"
+msgstr "Von Wiedergabeliste entfernen"
+
+#: actionsmanager.cpp:95 actionsmanager.cpp:99
+msgid "Hide controls"
+msgstr "Verstecke Steuerelemente"
+
+#: actionsmanager.cpp:106 actionsmanager.cpp:381 mainwindow.cpp:348
+msgid "Show Video Settings"
+msgstr ""
+
+#: actionsmanager.cpp:113
+msgid "Toggle fullscreen"
+msgstr "Vollbild Ein-/Ausschalten"
+
+#: actionsmanager.cpp:122
+msgid "Remove selected info"
+msgstr "Angewählte Informationen Entfernen"
+
+#: actionsmanager.cpp:127
+msgid "Refresh"
+msgstr "Aktualisieren"
+
+#: actionsmanager.cpp:133
+#, fuzzy
+msgid "Remove from list"
+msgstr "Von Wiedergabeliste entfernen"
+
+#: actionsmanager.cpp:137
+#, fuzzy
+msgid "Add to list"
+msgstr "Zur Wiedergabeliste hinzufügen"
+
+#: actionsmanager.cpp:141
+#, fuzzy
+msgid "Add to list "
+msgstr "Zur Wiedergabeliste hinzufügen"
+
+#: actionsmanager.cpp:145 actionsmanager.cpp:149
+#, fuzzy
+msgid "New list"
+msgstr "Neuer Listenname"
+
+#: actionsmanager.cpp:153
+#, fuzzy
+msgid "Show items"
+msgstr "1 Stück"
+
+#: actionsmanager.cpp:158
+msgid "Configure shortcuts..."
+msgstr "Kurzbefehle festlegen..."
+
+#: actionsmanager.cpp:377
+msgid "Hide Video Settings"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1673
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:239 rc.cpp:143
+msgid "Title"
+msgstr "Titel"
+
+#: infomanager.cpp:241
+msgid "Artwork"
+msgstr "Titelbild"
+
+#: infomanager.cpp:243
+msgid "Description"
+msgstr "Beschreibung"
+
+#: infomanager.cpp:245
+msgid "Location"
+msgstr "Ort"
+
+#: infomanager.cpp:287 infomanager.cpp:345
+msgid "Type"
+msgstr "Typ"
+
+#. i18n: file: mainwindow.ui:1681
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:306 rc.cpp:146
+msgid "Artist"
+msgstr "Künstler"
+
+#: infomanager.cpp:308
+msgid "Album"
+msgstr "Album"
+
+#: infomanager.cpp:310 infomanager.cpp:366 infomanager.cpp:396
+msgid "Year"
+msgstr "Jahr"
+
+#: infomanager.cpp:312
+msgid "Track Number"
+msgstr "Titelnummer"
+
+#: infomanager.cpp:314 infomanager.cpp:368
+msgid "Genre"
+msgstr "Genre"
+
+#: infomanager.cpp:364
+msgid "Collection/Series Name"
+msgstr "Sammlung/Serie"
+
+#: infomanager.cpp:391
+msgid "Series Name"
+msgstr "Serienname"
+
+#: infomanager.cpp:393
+msgid "Season"
+msgstr "Staffel"
+
+#: infomanager.cpp:395
+msgid "Episode"
+msgstr "Episode"
+
+#. i18n: file: mainwindow.ui:23
+#. i18n: ectx: property (windowTitle), widget (QMainWindow, MainWindowClass)
+#: main.cpp:29 mainwindow.cpp:274 mainwindow.cpp:551 mainwindow.cpp:924
+#: mainwindow.cpp:1098 rc.cpp:5
+msgid "Bangarang"
+msgstr "Bangarang"
+
+#: main.cpp:30
+msgid "A Media Player"
+msgstr "Ein Media Player"
+
+#: main.cpp:31
+msgid "Copyright 2009, Andrew Lake"
+msgstr "Copyright 2009, Andrew Lake"
+
+#: main.cpp:38
+msgid "Andrew (Jamboarder) Lake"
+msgstr "Andrew (Jamboarder) Lake"
+
+#: main.cpp:38
+msgid "Creator"
+msgstr "Betreuer"
+
+#: main.cpp:39
+msgid "Sebastian Jambor"
+msgstr "Sebastian Jambor"
+
+#: main.cpp:39 main.cpp:40 main.cpp:41
+msgid "Contributor"
+msgstr "Entwickler"
+
+#: main.cpp:40
+msgid "Janusz Lewandowski"
+msgstr "Janusz Lewandowski"
+
+#: main.cpp:41
+msgid "Andreas Marschke"
+msgstr "Andreas Marschke"
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at http://code.google.com/p/bangarangissuetracking/"
+msgstr ""
+"Fehlerberichte für Bangarang bitte hier melden http://code.google.com/p/"
+"bangarangissuetracking/"
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>Bangarang Issue Tracker</a>"
+msgstr ""
+"Fehlerberichte bitte an den <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>Bangarang Issue Tracker</a> senden"
+
+#: main.cpp:50
+msgid "Play 'URL'"
+msgstr "URL abspielen"
+
+#: main.cpp:51
+msgid "Play DVD Video"
+msgstr "Video DVD abspielen"
+
+#: main.cpp:52
+msgid "Play CD Music"
+msgstr "Music CD abspielen"
+
+# @TODO This one really isnt well
+#: main.cpp:53
+msgid "Show Additional Debug Output"
+msgstr ""
+
+#: mainwindow.cpp:238 platform/medialistsengine.cpp:183
+msgid "DVD Video"
+msgstr "DVD Video"
+
+#: mainwindow.cpp:248 platform/medialistsengine.cpp:93
+msgid "Audio CD"
+msgstr "Audio CD"
+
+#: mainwindow.cpp:274
+msgid ""
+"Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media "
+"library, rating and play count functions will be unavailable."
+msgstr ""
+"Bangarang ist es nicht möglich Nepomuks Semantisches Desktop Repository zu "
+"erreichen. MedienBibliothek, Bewertung und Abspiel zähl-Funktionen werden "
+"nicht benutzbar sein."
+
+#: mainwindow.cpp:274
+msgid "Don't show this message again"
+msgstr "Diese Nachricht nicht wieder anzeigen."
+
+# @TODO feels fishy!!
+#: mainwindow.cpp:356
+#, fuzzy
+msgid "<b>Fullscreen</b><br>Click to exit fullscreen"
+msgstr "<b>Shuffle An</b><br>Clicken sie hier um Shuffle ab zu schalten"
+
+#: mainwindow.cpp:363
+#, fuzzy
+msgid "Show fullscreen"
+msgstr "Vollbild anzeigen"
+
+#: mainwindow.cpp:374 mainwindow.cpp:644
+msgid "<b>Time remaining</b><br>Click to show elapsed time"
+msgstr "<b>Verbleibende Zeit</b><br>Hier Clicken um verbleibende Zeit zu sehen"
+
+#. i18n: file: mainwindow.ui:5535
+#. i18n: ectx: property (toolTip), widget (QToolButton, seekTime)
+#: mainwindow.cpp:376 mainwindow.cpp:646 rc.cpp:215
+msgid "<b>Time elapsed</b><br>Click to show remaining time"
+msgstr ""
+"<b>Zeit Verstrichen</b><br>Hier Clicken um die verstrichene Zeit zu sehen"
+
+#: mainwindow.cpp:385
+#, fuzzy
+msgid "<b>Paused</b><br>Hold to stop"
+msgstr "<b>Ton aus</b>Hier Clicken um Ton einzuschalten"
+
+#. i18n: file: mainwindow.ui:253
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, Filter)
+#: mainwindow.cpp:516 rc.cpp:11
+msgid "Search for audio"
+msgstr "Nach Audio-Dateien Suchen"
+
+#: mainwindow.cpp:524
+msgid "Search for video"
+msgstr "Nach Video-Dateien Suchen"
+
+#. i18n: file: mainwindow.ui:5147
+#. i18n: ectx: property (toolTip), widget (QToolButton, clearPlaylist)
+#: mainwindow.cpp:547 rc.cpp:179
+msgid "Clear Playlist"
+msgstr "Playlist leeren"
+
+#: mainwindow.cpp:548
+msgid "Are you sure you want to clear the current playlist?"
+msgstr ""
+"Sind sie sich sicher, dass sie die momentane Abspielliste leeren möchten?"
+
+#. i18n: file: mainwindow.ui:1202
+#. i18n: ectx: property (text), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:553 mainwindow.cpp:654 mainwindow.cpp:656 mainwindow.cpp:926
+#: rc.cpp:113
+msgid "Now Playing"
+msgstr "Jetzt Spielt"
+
+# @TODO feels fishy!!
+#: mainwindow.cpp:563
+msgid "<b>Shuffle On</b><br>Click to turn off Shuffle"
+msgstr "<b>Shuffle An</b><br>Clicken sie hier um Shuffle ab zu schalten"
+
+#. i18n: file: mainwindow.ui:5203
+#. i18n: ectx: property (toolTip), widget (QToolButton, shuffle)
+#: mainwindow.cpp:567 rc.cpp:188
+msgid "Turn on Shuffle"
+msgstr "Shuffle Aktivieren"
+
+#: mainwindow.cpp:578
+msgid "<b>Repeat On</b><br>Click to turn off repeat"
+msgstr "<b>Wiederholen An</b><br>Hier Clicken um Wiederholen ab zu schalten"
+
+#. i18n: file: mainwindow.ui:5174
+#. i18n: ectx: property (toolTip), widget (QToolButton, repeat)
+#: mainwindow.cpp:581 rc.cpp:182
+msgid "Turn on Repeat"
+msgstr "Wiederholen Aktivieren"
+
+#: mainwindow.cpp:590
+msgid "<b>Showing Upcoming</b><br>Click to show playlist"
+msgstr "<b>Vorschau An</b><br>Hier Clicken um Playlist an zu zeigen"
+
+#: mainwindow.cpp:591
+msgid "<b>Playlist</b>(Upcoming)"
+msgstr "<b>Abspielliste</b>(Nächstes)"
+
+#. i18n: file: mainwindow.ui:5092
+#. i18n: ectx: property (toolTip), widget (QToolButton, showQueue)
+#: mainwindow.cpp:595 rc.cpp:173
+msgid "Show Upcoming"
+msgstr "Nächstes Anzeigen"
+
+#: mainwindow.cpp:670
+msgid "<b>Playing</b><br>Click to pause<br>Click and hold to stop"
+msgstr ""
+"<b>Spielt</b><br>Hier clicken für Pause<br>Hier clicken und halt um zu "
+"Stoppen "
+
+#: mainwindow.cpp:681
+msgid "An error has been encountered during playback"
+msgstr ""
+
+#: mainwindow.cpp:701
+msgid "Loading playlist..."
+msgstr "Lade Abspielliste..."
+
+#: mainwindow.cpp:703
+msgid "Buffering..."
+msgstr "Puffern..."
+
+#: mainwindow.cpp:705 platform/mediaitemmodel.cpp:501
+msgid "Loading..."
+msgstr "Laden..."
+
+#: mainwindow.cpp:717
+msgid "<b>Muted</b><br>Click to restore volume"
+msgstr "<b>Ton aus</b>Hier Clicken um Ton einzuschalten"
+
+#. i18n: file: mainwindow.ui:5661
+#. i18n: ectx: property (toolTip), widget (SToolButton, volumeIcon)
+#: mainwindow.cpp:720 rc.cpp:221
+msgid "Mute volume"
+msgstr "Ton aus"
+
+#: mainwindow.cpp:757
+#, fuzzy
+msgid "Updating..."
+msgstr "Laden..."
+
+#: mainwindow.cpp:763
+msgid "Complete"
+msgstr ""
+
+#: mainwindow.cpp:769
+msgid "Updated info for "
+msgstr ""
+
+#: mainwindow.cpp:775
+#, fuzzy
+msgid "Removed info for "
+msgstr "Angewählte Informationen Entfernen"
+
+#. i18n: file: mainwindow.ui:5124
+#. i18n: ectx: property (text), widget (QLabel, playlistName)
+#: mainwindow.cpp:879 rc.cpp:176
+msgid "<b>Playlist</b>"
+msgstr "<b>Abspielliste<b>"
+
+#: mainwindow.cpp:882
+#, kde-format
+msgid "1 item, %2"
+msgid_plural "%1 items, %2"
+msgstr[0] "1 Stück, %2"
+msgstr[1] "%1 Stücke, %2"
+
+#. i18n: file: mainwindow.ui:1199
+#. i18n: ectx: property (toolTip), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:897 mainwindow.cpp:927 rc.cpp:110
+msgid "View Now Playing"
+msgstr "Jetzt Spielen Ansicht"
+
+#: mainwindow.cpp:1099
+msgid "Entertainment... Now"
+msgstr "Unterhaltung... Jetzt"
+
+#: rc.cpp:1
+#, fuzzy
+msgctxt "NAME OF TRANSLATORS"
+msgid "Your names"
+msgstr "Dein Name"
+
+#: rc.cpp:2
+msgctxt "EMAIL OF TRANSLATORS"
+msgid "Your emails"
+msgstr "Deine E-Mail Adresse"
+
+#. i18n: file: mainwindow.ui:149
+#. i18n: ectx: property (text), widget (QLabel, label)
+#. i18n: file: mainwindow.ui:5405
+#. i18n: ectx: property (text), widget (QToolButton, collectionButton)
+#: rc.cpp:8 rc.cpp:206
+msgid "Media Lists"
+msgstr "Medienlisten"
+
+#. i18n: file: mainwindow.ui:296
+#. i18n: ectx: attribute (label), widget (QWidget, AudioTool_2)
+#: rc.cpp:14
+msgid "Audio"
+msgstr "Audio"
+
+#. i18n: file: mainwindow.ui:364
+#. i18n: ectx: property (toolTip), widget (QToolButton, addAudioList)
+#. i18n: file: mainwindow.ui:801
+#. i18n: ectx: property (toolTip), widget (QToolButton, addVideoList)
+#: rc.cpp:17 rc.cpp:65
+#, fuzzy
+msgid "Add list"
+msgstr "Liste hinzufügen von"
+
+#. i18n: file: mainwindow.ui:381
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeAudioList)
+#. i18n: file: mainwindow.ui:818
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeVideoList)
+#: rc.cpp:20 rc.cpp:68
+#, fuzzy
+msgid "Remove list"
+msgstr "Von Wiedergabeliste entfernen"
+
+#. i18n: file: mainwindow.ui:411
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureAudioList)
+#. i18n: file: mainwindow.ui:848
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureVideoList)
+#: rc.cpp:23 rc.cpp:71
+#, fuzzy
+msgid "Settings"
+msgstr "Videodateien"
+
+#. i18n: file: mainwindow.ui:460
+#. i18n: ectx: property (text), widget (QLabel, label_5)
+#. i18n: file: mainwindow.ui:897
+#. i18n: ectx: property (text), widget (QLabel, label_7)
+#: rc.cpp:26 rc.cpp:74
+#, fuzzy
+msgid "Add List"
+msgstr "Liste hinzufügen von"
+
+#. i18n: file: mainwindow.ui:477
+#. i18n: ectx: property (text), widget (QLabel, label_4)
+#. i18n: file: mainwindow.ui:914
+#. i18n: ectx: property (text), widget (QLabel, label_6)
+#: rc.cpp:29 rc.cpp:77
+#, fuzzy
+msgid "Source"
+msgstr "Sortieren"
+
+#. i18n: file: mainwindow.ui:499
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceView)
+#. i18n: file: mainwindow.ui:940
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceView)
+#: rc.cpp:32 rc.cpp:83
+msgid "Current View"
+msgstr "Momentane Ansicht"
+
+#. i18n: file: mainwindow.ui:506
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceSelection)
+#. i18n: file: mainwindow.ui:933
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceSelection)
+#: rc.cpp:35 rc.cpp:80
+msgid "Current Selection"
+msgstr "Momentane Auswahl"
+
+#. i18n: file: mainwindow.ui:513
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourcePlaylist)
+#. i18n: file: mainwindow.ui:947
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourcePlaylist)
+#: rc.cpp:38 rc.cpp:86
+msgid "Current Playlist"
+msgstr "Momentane Abspielliste"
+
+#. i18n: file: mainwindow.ui:523
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, aNewListName)
+#. i18n: file: mainwindow.ui:957
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, vNewListName)
+#: rc.cpp:41 rc.cpp:89
+msgid "New List Name"
+msgstr "Neuer Listenname"
+
+#. i18n: file: mainwindow.ui:545
+#. i18n: ectx: property (text), widget (QPushButton, saveAudioList)
+#. i18n: file: mainwindow.ui:689
+#. i18n: ectx: property (text), widget (QPushButton, aslsSave)
+#. i18n: file: mainwindow.ui:976
+#. i18n: ectx: property (text), widget (QPushButton, saveVideoList)
+#. i18n: file: mainwindow.ui:1096
+#. i18n: ectx: property (text), widget (QPushButton, vslsSave)
+#. i18n: file: mainwindow.ui:1782
+#. i18n: ectx: property (text), widget (QPushButton, saveInfo)
+#: rc.cpp:44 rc.cpp:56 rc.cpp:92 rc.cpp:104 rc.cpp:152
+msgid "Save"
+msgstr "Speichern"
+
+#. i18n: file: mainwindow.ui:599
+#. i18n: ectx: property (text), widget (QToolButton, aCancelSaveList)
+#. i18n: file: mainwindow.ui:719
+#. i18n: ectx: property (text), widget (QToolButton, aslsCancel)
+#. i18n: file: mainwindow.ui:1126
+#. i18n: ectx: property (text), widget (QToolButton, vslsCancel)
+#: rc.cpp:47 rc.cpp:59 rc.cpp:107
+msgid "Return to Lists"
+msgstr "Zurück zu Listen"
+
+#. i18n: file: mainwindow.ui:638
+#. i18n: ectx: property (text), widget (QLabel, label_8)
+#. i18n: file: mainwindow.ui:1045
+#. i18n: ectx: property (text), widget (QLabel, label_11)
+#: rc.cpp:50 rc.cpp:98
+#, fuzzy
+msgid "Saved List Settings"
+msgstr "Videodateien"
+
+#. i18n: file: mainwindow.ui:664
+#. i18n: ectx: property (text), widget (QLabel, label_9)
+#. i18n: file: mainwindow.ui:1071
+#. i18n: ectx: property (text), widget (QLabel, label_10)
+#: rc.cpp:53 rc.cpp:101
+msgid "Name"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:748
+#. i18n: ectx: attribute (label), widget (QWidget, videoTool_2)
+#: rc.cpp:62
+msgid "Video"
+msgstr "Video"
+
+#. i18n: file: mainwindow.ui:1009
+#. i18n: ectx: property (text), widget (QToolButton, vCancelSaveList)
+#: rc.cpp:95
+msgid "Return To Lists"
+msgstr "Zurück zu Listen"
+
+#. i18n: file: mainwindow.ui:1352
+#. i18n: ectx: property (text), widget (QLabel, listTitle)
+#: rc.cpp:116
+msgid "List Title"
+msgstr "Listen Titel"
+
+#. i18n: file: mainwindow.ui:1365
+#. i18n: ectx: property (text), widget (QLabel, listSummary)
+#: rc.cpp:119
+msgid "Summary"
+msgstr "Zusammenfassung"
+
+#. i18n: file: mainwindow.ui:1375
+#. i18n: ectx: property (text), widget (QToolButton, sortList)
+#: rc.cpp:122
+msgid "Sort"
+msgstr "Sortieren"
+
+#. i18n: file: mainwindow.ui:1399
+#. i18n: ectx: property (text), widget (QToolButton, showInfo)
+#: rc.cpp:125
+msgid "Info"
+msgstr "Info"
+
+#. i18n: file: mainwindow.ui:1514
+#. i18n: ectx: property (text), widget (QLabel, notificationText)
+#: rc.cpp:128
+msgid "Notification Text"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:1589
+#. i18n: ectx: property (text), widget (QLabel, label_2)
+#: rc.cpp:131
+msgid "Information"
+msgstr "Information"
+
+#. i18n: file: mainwindow.ui:1596
+#. i18n: ectx: property (text), widget (QToolButton, editInfo)
+#: rc.cpp:134
+msgid "Edit"
+msgstr "Editieren"
+
+#. i18n: file: mainwindow.ui:1663
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:137
+msgid "1"
+msgstr "1"
+
+#. i18n: file: mainwindow.ui:1668
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:140
+msgid "2"
+msgstr "2"
+
+#. i18n: file: mainwindow.ui:1747
+#. i18n: ectx: property (text), widget (QToolButton, previous)
+#: rc.cpp:149
+msgid "Previous"
+msgstr "Vorher"
+
+#. i18n: file: mainwindow.ui:1805
+#. i18n: ectx: property (toolTip), widget (QPushButton, playAll)
+#: rc.cpp:155
+msgid "Play all media in list"
+msgstr "Alle von Liste abspielen"
+
+#. i18n: file: mainwindow.ui:1834
+#. i18n: ectx: property (toolTip), widget (QPushButton, playSelected)
+#: rc.cpp:161
+msgid "Play selected media in list"
+msgstr "Alle ausgewählten abspielen"
+
+#. i18n: file: mainwindow.ui:2346
+#. i18n: ectx: property (text), widget (QLabel, playbackMessage)
+#: rc.cpp:167
+msgid "Playback message"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:2375
+#. i18n: ectx: property (text), widget (QToolButton, showPlaylist)
+#: rc.cpp:170
+msgid "Playlist"
+msgstr "Abspielliste"
+
+#. i18n: file: mainwindow.ui:5177
+#. i18n: ectx: property (text), widget (QToolButton, repeat)
+#. i18n: file: mainwindow.ui:5206
+#. i18n: ectx: property (text), widget (QToolButton, shuffle)
+#. i18n: file: mainwindow.ui:5449
+#. i18n: ectx: property (text), widget (SToolButton, fullScreen)
+#: rc.cpp:185 rc.cpp:191 rc.cpp:212
+msgid "[ ]"
+msgstr "[ ]"
+
+#. i18n: file: mainwindow.ui:5306
+#. i18n: ectx: property (text), widget (QLabel, label_3)
+#: rc.cpp:194
+#, fuzzy
+msgid "Video Settings"
+msgstr "Videodateien"
+
+#. i18n: file: mainwindow.ui:5335
+#. i18n: ectx: property (text), widget (QPushButton, saveShortCuts)
+#: rc.cpp:197
+msgid "Save Shortcuts"
+msgstr "Tastenkürzel Speichern"
+
+#. i18n: file: mainwindow.ui:5342
+#. i18n: ectx: property (text), widget (QPushButton, cancelEditShortcuts)
+#: rc.cpp:200
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#. i18n: file: mainwindow.ui:5402
+#. i18n: ectx: property (toolTip), widget (QToolButton, collectionButton)
+#: rc.cpp:203
+msgid "View Media Lists"
+msgstr "Zeige Medienlisten"
+
+#. i18n: file: mainwindow.ui:5446
+#. i18n: ectx: property (toolTip), widget (SToolButton, fullScreen)
+#: rc.cpp:209
+msgid "Show full screen"
+msgstr "Vollbild anzeigen"
+
+#. i18n: file: mainwindow.ui:5538
+#. i18n: ectx: property (text), widget (QToolButton, seekTime)
+#: rc.cpp:218
+msgid "03:00"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:5699
+#. i18n: ectx: property (toolTip), widget (Phonon::VolumeSlider, volumeSlider)
+#: rc.cpp:224
+msgid "Volume"
+msgstr "Lautstärke"
+
+#. i18n: file: mainwindow.ui:5725
+#. i18n: ectx: property (text), widget (QToolButton, mediaPrevious)
+#. i18n: file: mainwindow.ui:5754
+#. i18n: ectx: property (text), widget (SToolButton, mediaPlayPause)
+#. i18n: file: mainwindow.ui:5774
+#. i18n: ectx: property (text), widget (QToolButton, mediaNext)
+#: rc.cpp:227 rc.cpp:230 rc.cpp:233
+msgid "..."
+msgstr "..."
+
+#: videosettings.cpp:73
+msgid "Brightness"
+msgstr ""
+
+#: videosettings.cpp:83
+#, fuzzy
+msgid "Contrast"
+msgstr "Entwickler"
+
+#: videosettings.cpp:93
+msgid "Hue"
+msgstr ""
+
+#: videosettings.cpp:103
+msgid "Saturation"
+msgstr ""
+
+#: videosettings.cpp:118
+msgid "Aspect Ratio Settings"
+msgstr ""
+
+#: videosettings.cpp:120
+msgid "Automatic"
+msgstr ""
+
+#: videosettings.cpp:122
+msgid "4:3"
+msgstr ""
+
+#: videosettings.cpp:124
+msgid "16:9"
+msgstr ""
+
+#: videosettings.cpp:126
+msgid "Fit"
+msgstr ""
+
+#: videosettings.cpp:133
+msgid "Scaling Mode"
+msgstr ""
+
+#: videosettings.cpp:135
+msgid "Scale to fit"
+msgstr ""
+
+#: videosettings.cpp:137
+msgid "Scale and crop"
+msgstr ""
+
+#: videosettings.cpp:147
+msgid "Restore Defaults"
+msgstr ""
+
+#: videosettings.cpp:149
+#, fuzzy
+msgid "Hide"
+msgstr "Video"
+
+#: platform/audioclipslistengine.cpp:107 platform/audioclipslistengine.cpp:131
+#: platform/videolistengine.cpp:176
+#, kde-format
+msgid "1 clip"
+msgid_plural "%1 clips"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/audiostreamlistengine.cpp:103
+#: platform/audiostreamlistengine.cpp:134
+#, fuzzy, kde-format
+msgid "1 stream"
+msgid_plural "%1 streams"
+msgstr[0] "1 Stück"
+msgstr[1] "%1 Stück"
+
+#: platform/audiostreamlistengine.cpp:108
+msgid "Create new audio stream item"
+msgstr ""
+
+#: platform/audiostreamlistengine.cpp:155
+#, fuzzy
+msgid "Untitled Audio Stream"
+msgstr "Audiostreams"
+
+#: platform/audiostreamlistengine.cpp:156
+msgid "Select this item, click Info then Edit to enter audio stream info"
+msgstr ""
+
+#: platform/audiostreamlistengine.cpp:165
+#, fuzzy
+msgid "New Audio Stream"
+msgstr "Audiostreams"
+
+#: platform/cdlistengine.cpp:80
+#, fuzzy, kde-format
+msgid "Track %1"
+msgstr "Titelnummer"
+
+#: platform/cdlistengine.cpp:84
+#, kde-format
+msgid "Audio CD - %1 Tracks"
+msgstr ""
+
+#: platform/cdlistengine.cpp:93
+#, kde-format
+msgid "1 track"
+msgid_plural "%1 tracks"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/dvdlistengine.cpp:76
+#, fuzzy, kde-format
+msgid "Title %1"
+msgstr "Titel"
+
+#: platform/dvdlistengine.cpp:80
+#, fuzzy, kde-format
+msgid "DVD Video - %1 Titles"
+msgstr "Videodateien"
+
+#: platform/filelistengine.cpp:69 platform/filelistengine.cpp:86
+msgid "Audio Files"
+msgstr "Audiodateien"
+
+#: platform/filelistengine.cpp:74 platform/filelistengine.cpp:97
+msgid "Video Files"
+msgstr "Videodateien"
+
+#: platform/filelistengine.cpp:87 platform/filelistengine.cpp:98
+#: platform/filelistengine.cpp:182 platform/mediaitemmodel.cpp:381
+#: platform/savedlistsengine.cpp:102 platform/videolistengine.cpp:451
+#: platform/videolistengine.cpp:517
+#, kde-format
+msgid "1 item"
+msgid_plural "%1 items"
+msgstr[0] "1 Stück"
+msgstr[1] "%1 Stück"
+
+#: platform/filelistengine.cpp:122 platform/filelistengine.cpp:197
+msgid "Open audio file(s)"
+msgstr "Audiodatei(en) Öffen"
+
+#: platform/filelistengine.cpp:127 platform/filelistengine.cpp:208
+msgid "Open folder containing audio file(s)"
+msgstr "Öffne Ordner mit Audiodatei(en)"
+
+#: platform/filelistengine.cpp:133 platform/filelistengine.cpp:202
+msgid "Open video file(s)"
+msgstr "Öffne Videodatei(en)"
+
+#: platform/filelistengine.cpp:138 platform/filelistengine.cpp:213
+msgid "Open folder containing video file(s)"
+msgstr "Öffne Ordner mit Videodatei(en)"
+
+#: platform/filelistengine.cpp:144
+msgid "Open image file(s)"
+msgstr "Öffne Bild(er)"
+
+#: platform/filelistengine.cpp:149
+msgid "Open folder containing image file(s)"
+msgstr "Öffne Ordner mit Bild(ern)"
+
+#: platform/filelistengine.cpp:326
+msgid "Audio Clip"
+msgstr "Audio Clip"
+
+#: platform/filelistengine.cpp:413
+#, kde-format
+msgid "%1 - Episode %2"
+msgstr "%1 - Episode %2"
+
+#: platform/filelistengine.cpp:415
+#, kde-format
+msgid "Episode %1"
+msgstr "Episode %1"
+
+#: platform/mediaitemmodel.cpp:380
+#, fuzzy, kde-format
+msgid "Multiple %1"
+msgstr "Titel"
+
+#: platform/mediaitemmodel.cpp:532
+msgid "No results"
+msgstr ""
+
+#: platform/mediaitemmodel.cpp:563
+#, fuzzy
+msgid "Add to playlist/Remove from playlist"
+msgstr "Von Wiedergabeliste entfernen"
+
+#: platform/medialistsengine.cpp:52 platform/medialistsengine.cpp:150
+msgid "Files and Folders"
+msgstr "Dateien und Ordner"
+
+#: platform/medialistsengine.cpp:57 platform/musiclistengine.cpp:222
+msgid "Artists"
+msgstr "Künstler"
+
+#: platform/medialistsengine.cpp:61 platform/musiclistengine.cpp:262
+msgid "Albums"
+msgstr "Alben"
+
+#: platform/medialistsengine.cpp:65 platform/musiclistengine.cpp:353
+msgid "Songs"
+msgstr "Lieder"
+
+#: platform/medialistsengine.cpp:69 platform/medialistsengine.cpp:159
+#: platform/musiclistengine.cpp:306 platform/videolistengine.cpp:402
+msgid "Genres"
+msgstr "Genre"
+
+#: platform/medialistsengine.cpp:73
+msgid "Clips"
+msgstr "Clips"
+
+#: platform/medialistsengine.cpp:77
+msgid "Audio Streams"
+msgstr "Audiostreams"
+
+#: platform/medialistsengine.cpp:100 platform/medialistsengine.cpp:190
+#: platform/semanticslistengine.cpp:89
+msgid "Frequently Played"
+msgstr "Oft gespielt"
+
+#: platform/medialistsengine.cpp:104 platform/medialistsengine.cpp:194
+#: platform/semanticslistengine.cpp:115
+msgid "Recently Played"
+msgstr "Vor kurzem gespielt"
+
+#: platform/medialistsengine.cpp:108 platform/medialistsengine.cpp:198
+#: platform/semanticslistengine.cpp:140
+msgid "Highest Rated"
+msgstr "Höchst bewertet"
+
+#: platform/medialistsengine.cpp:155 platform/videolistengine.cpp:369
+msgid "Movies"
+msgstr "Filme"
+
+#: platform/medialistsengine.cpp:163 platform/videolistengine.cpp:224
+msgid "TV Shows"
+msgstr "TV Shows"
+
+#: platform/medialistsengine.cpp:167 platform/videolistengine.cpp:175
+msgid "Video Clips"
+msgstr "Video Clips"
+
+#: platform/musiclistengine.cpp:224
+#, fuzzy, kde-format
+msgid "Artists - %1"
+msgstr "Künstler"
+
+#: platform/musiclistengine.cpp:226
+#, fuzzy, kde-format
+msgid "1 artist"
+msgid_plural "%1 artists"
+msgstr[0] "Künstler"
+msgstr[1] "Künstler"
+
+#: platform/musiclistengine.cpp:264 platform/musiclistengine.cpp:267
+#, fuzzy, kde-format
+msgid "Albums - %1"
+msgstr "Alben"
+
+#: platform/musiclistengine.cpp:270
+#, kde-format
+msgid "Albums - %1 - %2"
+msgstr ""
+
+#: platform/musiclistengine.cpp:273
+#, fuzzy, kde-format
+msgid "1 album"
+msgid_plural "%1 albums"
+msgstr[0] "Album"
+msgstr[1] "Album"
+
+#: platform/musiclistengine.cpp:307 platform/videolistengine.cpp:403
+#, fuzzy, kde-format
+msgid "1 genre"
+msgid_plural "%1 genres"
+msgstr[0] "Genre"
+msgstr[1] "Genre"
+
+#: platform/musiclistengine.cpp:355 platform/musiclistengine.cpp:383
+#, kde-format
+msgid "1 song"
+msgid_plural "%1 songs"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:216 platform/videolistengine.cpp:332
+msgid "Uncategorized TV Shows"
+msgstr ""
+
+#: platform/videolistengine.cpp:225
+#, kde-format
+msgid "1 show"
+msgid_plural "%1 shows"
+msgstr[0] ""
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:253
+#, fuzzy, kde-format
+msgid "Season %1"
+msgstr "Staffel"
+
+#: platform/videolistengine.cpp:272
+msgid "Uncategorized seasons"
+msgstr ""
+
+#: platform/videolistengine.cpp:279
+#, fuzzy, kde-format
+msgid "Seasons - %1"
+msgstr "Staffel"
+
+#: platform/videolistengine.cpp:280
+#, fuzzy, kde-format
+msgid "1 season"
+msgid_plural "%1 seasons"
+msgstr[0] "Staffel"
+msgstr[1] "Staffel"
+
+#: platform/videolistengine.cpp:334
+#, fuzzy, kde-format
+msgid "%1 - Season %2"
+msgstr "%1 - Episode %2"
+
+#: platform/videolistengine.cpp:336
+#, kde-format
+msgid "%1 - Uncategorized Seasons"
+msgstr ""
+
+#: platform/videolistengine.cpp:338
+#, fuzzy, kde-format
+msgid "1 episode"
+msgid_plural "%1 episodes"
+msgstr[0] "Episode"
+msgstr[1] "Episode"
+
+#: platform/videolistengine.cpp:371
+#, fuzzy, kde-format
+msgid "Movies - %1"
+msgstr "Filme"
+
+#: platform/videolistengine.cpp:373
+#, fuzzy, kde-format
+msgid "1 movie"
+msgid_plural "%1 movies"
+msgstr[0] "1 Stück"
+msgstr[1] "%1 Stück"
diff --git a/translations/fr/CMakeLists.txt b/translations/fr/CMakeLists.txt
new file mode 100644
index 0000000..423b4ca
--- /dev/null
+++ b/translations/fr/CMakeLists.txt
@@ -0,0 +1,2 @@
+file(GLOB _po_files *.po)
+GETTEXT_PROCESS_PO_FILES( fr ALL INSTALL_DESTINATION ${LOCALE_INSTALL_DIR} ${_po_files} )
diff --git a/translations/fr/bangarang.po b/translations/fr/bangarang.po
new file mode 100644
index 0000000..8c77adb
--- /dev/null
+++ b/translations/fr/bangarang.po
@@ -0,0 +1,1070 @@
+# Copyright (C) 2009 Ryan Kavanagh <ryanakca at kubuntu.org>
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2009-12-21 22:58-0800\n"
+"PO-Revision-Date: 2009-12-05 13:09-0500\n"
+"Last-Translator: Ryan Kavanagh <ryanakca at kubuntu.org>\n"
+"Language-Team: Français <kde-i18n-doc at kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: actionsmanager.cpp:48
+msgid "Quit"
+msgstr "Quitter"
+
+#: actionsmanager.cpp:57
+msgid "Play next"
+msgstr "Lire l'élément suivant"
+
+#: actionsmanager.cpp:63
+msgid "Play previous"
+msgstr "Lire l'élément précédent"
+
+#: actionsmanager.cpp:75 mainwindow.cpp:1087
+msgid "Play all"
+msgstr "Lire tous les éléments"
+
+#. i18n: file: mainwindow.ui:1811
+#. i18n: ectx: property (text), widget (QPushButton, playAll)
+#: actionsmanager.cpp:77 rc.cpp:158
+msgid "Play All"
+msgstr "Lire tous les éléments"
+
+#: actionsmanager.cpp:80 mainwindow.cpp:1089
+msgid "Play selected"
+msgstr "Lire les sélectionnés"
+
+#. i18n: file: mainwindow.ui:1837
+#. i18n: ectx: property (text), widget (QPushButton, playSelected)
+#: actionsmanager.cpp:82 rc.cpp:164
+msgid "Play Selected"
+msgstr "Lire les sélectionnés"
+
+#: actionsmanager.cpp:85 actionsmanager.cpp:87
+msgid "Add to playlist"
+msgstr "Ajouter à la liste de lecture"
+
+#: actionsmanager.cpp:90 actionsmanager.cpp:92
+msgid "Remove from playlist"
+msgstr "Retirer de la liste de lecture"
+
+#: actionsmanager.cpp:95 actionsmanager.cpp:99
+msgid "Hide controls"
+msgstr "Cacher les contrôles"
+
+#: actionsmanager.cpp:106 actionsmanager.cpp:381 mainwindow.cpp:348
+#, fuzzy
+msgid "Show Video Settings"
+msgstr "Réglages audios ici!"
+
+#: actionsmanager.cpp:113
+msgid "Toggle fullscreen"
+msgstr "Activer / désactiver le mode plein écran"
+
+#: actionsmanager.cpp:122
+msgid "Remove selected info"
+msgstr "Enlever l'information sélectionnée"
+
+#: actionsmanager.cpp:127
+msgid "Refresh"
+msgstr "Rafraîchir"
+
+#: actionsmanager.cpp:133
+#, fuzzy
+msgid "Remove from list"
+msgstr "Retirer de la liste de lecture"
+
+#: actionsmanager.cpp:137
+#, fuzzy
+msgid "Add to list"
+msgstr "Ajouter à la liste de lecture"
+
+#: actionsmanager.cpp:141
+#, fuzzy
+msgid "Add to list "
+msgstr "Ajouter à la liste de lecture"
+
+#: actionsmanager.cpp:145 actionsmanager.cpp:149
+#, fuzzy
+msgid "New list"
+msgstr "Nom de la nouvelle liste"
+
+#: actionsmanager.cpp:153
+#, fuzzy
+msgid "Show items"
+msgstr "Un élément"
+
+#: actionsmanager.cpp:158
+msgid "Configure shortcuts..."
+msgstr "Configurer les raccourcis claviers..."
+
+#: actionsmanager.cpp:377
+#, fuzzy
+msgid "Hide Video Settings"
+msgstr "Réglages audios ici!"
+
+#. i18n: file: mainwindow.ui:1673
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:239 rc.cpp:143
+msgid "Title"
+msgstr "Titre"
+
+#: infomanager.cpp:241
+msgid "Artwork"
+msgstr "Pochette"
+
+#: infomanager.cpp:243
+msgid "Description"
+msgstr "Description"
+
+#: infomanager.cpp:245
+msgid "Location"
+msgstr "Emplacement : "
+
+#: infomanager.cpp:287 infomanager.cpp:345
+msgid "Type"
+msgstr "Type"
+
+#. i18n: file: mainwindow.ui:1681
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:306 rc.cpp:146
+msgid "Artist"
+msgstr "Artiste"
+
+#: infomanager.cpp:308
+msgid "Album"
+msgstr "Album"
+
+#: infomanager.cpp:310 infomanager.cpp:366 infomanager.cpp:396
+msgid "Year"
+msgstr "Année"
+
+#: infomanager.cpp:312
+msgid "Track Number"
+msgstr "Numéro de la piste"
+
+#: infomanager.cpp:314 infomanager.cpp:368
+msgid "Genre"
+msgstr "Style"
+
+#: infomanager.cpp:364
+msgid "Collection/Series Name"
+msgstr "Nom de la collection / série"
+
+#: infomanager.cpp:391
+msgid "Series Name"
+msgstr "Nom de la série"
+
+#: infomanager.cpp:393
+msgid "Season"
+msgstr "Saison"
+
+#: infomanager.cpp:395
+msgid "Episode"
+msgstr "Épisode"
+
+#. i18n: file: mainwindow.ui:23
+#. i18n: ectx: property (windowTitle), widget (QMainWindow, MainWindowClass)
+#: main.cpp:29 mainwindow.cpp:274 mainwindow.cpp:551 mainwindow.cpp:924
+#: mainwindow.cpp:1098 rc.cpp:5
+msgid "Bangarang"
+msgstr "Bangarang"
+
+#: main.cpp:30
+msgid "A Media Player"
+msgstr "Un lecteur multimédia"
+
+#: main.cpp:31
+msgid "Copyright 2009, Andrew Lake"
+msgstr ""
+
+#: main.cpp:38
+msgid "Andrew (Jamboarder) Lake"
+msgstr ""
+
+#: main.cpp:38
+msgid "Creator"
+msgstr "Créateur"
+
+#: main.cpp:39
+msgid "Sebastian Jambor"
+msgstr ""
+
+#: main.cpp:39 main.cpp:40 main.cpp:41
+msgid "Contributor"
+msgstr "Contributeur"
+
+#: main.cpp:40
+msgid "Janusz Lewandowski"
+msgstr ""
+
+#: main.cpp:41
+msgid "Andreas Marschke"
+msgstr ""
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at http://code.google.com/p/bangarangissuetracking/"
+msgstr ""
+"Veuillez utiliser http://code.google.com/p/bangarangissuetracking/ pour "
+"signaler des bogues."
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>Bangarang Issue Tracker</a>"
+msgstr ""
+"Veuillez utiliser le <a href=\"http://code.google.com/p/"
+"bangarangissuetracking/\">gérant de bogues à Bangarang</a> pour signaler des "
+"bogues."
+
+#: main.cpp:50
+msgid "Play 'URL'"
+msgstr "Lire un 'URL'"
+
+#: main.cpp:51
+msgid "Play DVD Video"
+msgstr "Lire un DVD"
+
+#: main.cpp:52
+msgid "Play CD Music"
+msgstr "Lire un CD audio"
+
+#: main.cpp:53
+msgid "Show Additional Debug Output"
+msgstr "Voir les informations de débogage"
+
+#: mainwindow.cpp:238 platform/medialistsengine.cpp:183
+msgid "DVD Video"
+msgstr "Vidéo DVD"
+
+#: mainwindow.cpp:248 platform/medialistsengine.cpp:93
+msgid "Audio CD"
+msgstr "CD audio"
+
+#: mainwindow.cpp:274
+msgid ""
+"Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media "
+"library, rating and play count functions will be unavailable."
+msgstr ""
+"Bangarang est incapable d'accéder le référentiel du bureau sémantique "
+"Nepomuk. La bibliothèque multimédia, les fonctions vote et nombre d'écoutes "
+"ne seront pas disponibles."
+
+#: mainwindow.cpp:274
+msgid "Don't show this message again"
+msgstr "Ne plus afficher ce message"
+
+#: mainwindow.cpp:356
+msgid "<b>Fullscreen</b><br>Click to exit fullscreen"
+msgstr "<b>Plein écran</b><br>Cliquer pour sortir du mode plein écran"
+
+#: mainwindow.cpp:363
+msgid "Show fullscreen"
+msgstr "Plein écran"
+
+#: mainwindow.cpp:374 mainwindow.cpp:644
+msgid "<b>Time remaining</b><br>Click to show elapsed time"
+msgstr "<b>Temps restant</b><br>Cliquer pour afficher le temps écoulé"
+
+#. i18n: file: mainwindow.ui:5535
+#. i18n: ectx: property (toolTip), widget (QToolButton, seekTime)
+#: mainwindow.cpp:376 mainwindow.cpp:646 rc.cpp:215
+msgid "<b>Time elapsed</b><br>Click to show remaining time"
+msgstr "<b>Temps écoulé</b><br>Cliquer pour afficher le temps restant"
+
+#: mainwindow.cpp:385
+msgid "<b>Paused</b><br>Hold to stop"
+msgstr "<b>Pause</b><br>Tenir pour arrêter"
+
+#. i18n: file: mainwindow.ui:253
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, Filter)
+#: mainwindow.cpp:516 rc.cpp:11
+msgid "Search for audio"
+msgstr "Rechercher de l'audio"
+
+#: mainwindow.cpp:524
+msgid "Search for video"
+msgstr "Recherche des vidéos"
+
+#. i18n: file: mainwindow.ui:5147
+#. i18n: ectx: property (toolTip), widget (QToolButton, clearPlaylist)
+#: mainwindow.cpp:547 rc.cpp:179
+msgid "Clear Playlist"
+msgstr "Nettoyer la liste de lecture"
+
+#: mainwindow.cpp:548
+msgid "Are you sure you want to clear the current playlist?"
+msgstr "Voulez-vous vraiment effacer cette liste de lecture ?"
+
+#. i18n: file: mainwindow.ui:1202
+#. i18n: ectx: property (text), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:553 mainwindow.cpp:654 mainwindow.cpp:656 mainwindow.cpp:926
+#: rc.cpp:113
+msgid "Now Playing"
+msgstr "En cours de lecture"
+
+#: mainwindow.cpp:563
+msgid "<b>Shuffle On</b><br>Click to turn off Shuffle"
+msgstr ""
+"<b>Mode aléatoire activé</b><br>Cliquer pour désactiver le mode aléatoire"
+
+#. i18n: file: mainwindow.ui:5203
+#. i18n: ectx: property (toolTip), widget (QToolButton, shuffle)
+#: mainwindow.cpp:567 rc.cpp:188
+msgid "Turn on Shuffle"
+msgstr "Activer le mode aléatoire"
+
+#: mainwindow.cpp:578
+msgid "<b>Repeat On</b><br>Click to turn off repeat"
+msgstr "<b>Mode répète activé</b><br>Cliquer pour désactiver le mode répète"
+
+#. i18n: file: mainwindow.ui:5174
+#. i18n: ectx: property (toolTip), widget (QToolButton, repeat)
+#: mainwindow.cpp:581 rc.cpp:182
+msgid "Turn on Repeat"
+msgstr "Activer le mode répète"
+
+#: mainwindow.cpp:590
+msgid "<b>Showing Upcoming</b><br>Click to show playlist"
+msgstr ""
+"<b>Afficher les prochaines pistes</b><br>Cliquer pour afficher la liste de "
+"lecture"
+
+#: mainwindow.cpp:591
+msgid "<b>Playlist</b>(Upcoming)"
+msgstr "<b>Liste de lecture</b>(Prochaines pistes)"
+
+#. i18n: file: mainwindow.ui:5092
+#. i18n: ectx: property (toolTip), widget (QToolButton, showQueue)
+#: mainwindow.cpp:595 rc.cpp:173
+msgid "Show Upcoming"
+msgstr "Afficher les prochaines pistes"
+
+#: mainwindow.cpp:670
+msgid "<b>Playing</b><br>Click to pause<br>Click and hold to stop"
+msgstr ""
+"<b>En cours de lecture</b><br>Cliquer pour mettre en pause<br>Cliquer et "
+"tenir pour arrêter"
+
+#: mainwindow.cpp:681
+msgid "An error has been encountered during playback"
+msgstr ""
+
+#: mainwindow.cpp:701
+msgid "Loading playlist..."
+msgstr "Chargement de la liste de lecture..."
+
+#: mainwindow.cpp:703
+msgid "Buffering..."
+msgstr "Tamponnage..."
+
+#: mainwindow.cpp:705 platform/mediaitemmodel.cpp:501
+msgid "Loading..."
+msgstr "Chargement..."
+
+#: mainwindow.cpp:717
+msgid "<b>Muted</b><br>Click to restore volume"
+msgstr "<b>Muet</b><br>Cliquer pour restaurer le volume"
+
+#. i18n: file: mainwindow.ui:5661
+#. i18n: ectx: property (toolTip), widget (SToolButton, volumeIcon)
+#: mainwindow.cpp:720 rc.cpp:221
+msgid "Mute volume"
+msgstr "Couper le volume"
+
+#: mainwindow.cpp:757
+msgid "Updating..."
+msgstr "Actualisation..."
+
+#: mainwindow.cpp:763
+msgid "Complete"
+msgstr ""
+
+#: mainwindow.cpp:769
+msgid "Updated info for "
+msgstr "Mise à jour des données pour "
+
+#: mainwindow.cpp:775
+msgid "Removed info for "
+msgstr "Supprimé les données pour "
+
+#. i18n: file: mainwindow.ui:5124
+#. i18n: ectx: property (text), widget (QLabel, playlistName)
+#: mainwindow.cpp:879 rc.cpp:176
+msgid "<b>Playlist</b>"
+msgstr "<b>Liste de lecture</b>"
+
+#: mainwindow.cpp:882
+#, kde-format
+msgid "1 item, %2"
+msgid_plural "%1 items, %2"
+msgstr[0] "Un élément, %2"
+msgstr[1] ""
+
+#. i18n: file: mainwindow.ui:1199
+#. i18n: ectx: property (toolTip), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:897 mainwindow.cpp:927 rc.cpp:110
+msgid "View Now Playing"
+msgstr "Afficher en cours de lecture"
+
+#: mainwindow.cpp:1099
+msgid "Entertainment... Now"
+msgstr "Divertissements... Maintenant"
+
+#: rc.cpp:1
+msgctxt "NAME OF TRANSLATORS"
+msgid "Your names"
+msgstr "Ryan Kavanagh"
+
+#: rc.cpp:2
+msgctxt "EMAIL OF TRANSLATORS"
+msgid "Your emails"
+msgstr "ryanakca at kubuntu.org"
+
+#. i18n: file: mainwindow.ui:149
+#. i18n: ectx: property (text), widget (QLabel, label)
+#. i18n: file: mainwindow.ui:5405
+#. i18n: ectx: property (text), widget (QToolButton, collectionButton)
+#: rc.cpp:8 rc.cpp:206
+msgid "Media Lists"
+msgstr "Listes de médias"
+
+#. i18n: file: mainwindow.ui:296
+#. i18n: ectx: attribute (label), widget (QWidget, AudioTool_2)
+#: rc.cpp:14
+msgid "Audio"
+msgstr "Audio"
+
+#. i18n: file: mainwindow.ui:364
+#. i18n: ectx: property (toolTip), widget (QToolButton, addAudioList)
+#. i18n: file: mainwindow.ui:801
+#. i18n: ectx: property (toolTip), widget (QToolButton, addVideoList)
+#: rc.cpp:17 rc.cpp:65
+#, fuzzy
+msgid "Add list"
+msgstr "Ajouter à la liste de"
+
+#. i18n: file: mainwindow.ui:381
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeAudioList)
+#. i18n: file: mainwindow.ui:818
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeVideoList)
+#: rc.cpp:20 rc.cpp:68
+#, fuzzy
+msgid "Remove list"
+msgstr "Retirer de la liste de lecture"
+
+#. i18n: file: mainwindow.ui:411
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureAudioList)
+#. i18n: file: mainwindow.ui:848
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureVideoList)
+#: rc.cpp:23 rc.cpp:71
+#, fuzzy
+msgid "Settings"
+msgstr "Réglages audios ici!"
+
+#. i18n: file: mainwindow.ui:460
+#. i18n: ectx: property (text), widget (QLabel, label_5)
+#. i18n: file: mainwindow.ui:897
+#. i18n: ectx: property (text), widget (QLabel, label_7)
+#: rc.cpp:26 rc.cpp:74
+#, fuzzy
+msgid "Add List"
+msgstr "Ajouter à la liste de"
+
+#. i18n: file: mainwindow.ui:477
+#. i18n: ectx: property (text), widget (QLabel, label_4)
+#. i18n: file: mainwindow.ui:914
+#. i18n: ectx: property (text), widget (QLabel, label_6)
+#: rc.cpp:29 rc.cpp:77
+#, fuzzy
+msgid "Source"
+msgstr "Tri"
+
+#. i18n: file: mainwindow.ui:499
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceView)
+#. i18n: file: mainwindow.ui:940
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceView)
+#: rc.cpp:32 rc.cpp:83
+msgid "Current View"
+msgstr "Vue en cours"
+
+#. i18n: file: mainwindow.ui:506
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceSelection)
+#. i18n: file: mainwindow.ui:933
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceSelection)
+#: rc.cpp:35 rc.cpp:80
+msgid "Current Selection"
+msgstr "Sélection courante"
+
+#. i18n: file: mainwindow.ui:513
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourcePlaylist)
+#. i18n: file: mainwindow.ui:947
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourcePlaylist)
+#: rc.cpp:38 rc.cpp:86
+msgid "Current Playlist"
+msgstr "Liste de lecture en cours"
+
+#. i18n: file: mainwindow.ui:523
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, aNewListName)
+#. i18n: file: mainwindow.ui:957
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, vNewListName)
+#: rc.cpp:41 rc.cpp:89
+msgid "New List Name"
+msgstr "Nom de la nouvelle liste"
+
+#. i18n: file: mainwindow.ui:545
+#. i18n: ectx: property (text), widget (QPushButton, saveAudioList)
+#. i18n: file: mainwindow.ui:689
+#. i18n: ectx: property (text), widget (QPushButton, aslsSave)
+#. i18n: file: mainwindow.ui:976
+#. i18n: ectx: property (text), widget (QPushButton, saveVideoList)
+#. i18n: file: mainwindow.ui:1096
+#. i18n: ectx: property (text), widget (QPushButton, vslsSave)
+#. i18n: file: mainwindow.ui:1782
+#. i18n: ectx: property (text), widget (QPushButton, saveInfo)
+#: rc.cpp:44 rc.cpp:56 rc.cpp:92 rc.cpp:104 rc.cpp:152
+msgid "Save"
+msgstr "Enregistrer"
+
+#. i18n: file: mainwindow.ui:599
+#. i18n: ectx: property (text), widget (QToolButton, aCancelSaveList)
+#. i18n: file: mainwindow.ui:719
+#. i18n: ectx: property (text), widget (QToolButton, aslsCancel)
+#. i18n: file: mainwindow.ui:1126
+#. i18n: ectx: property (text), widget (QToolButton, vslsCancel)
+#: rc.cpp:47 rc.cpp:59 rc.cpp:107
+msgid "Return to Lists"
+msgstr "Retour aux listes"
+
+#. i18n: file: mainwindow.ui:638
+#. i18n: ectx: property (text), widget (QLabel, label_8)
+#. i18n: file: mainwindow.ui:1045
+#. i18n: ectx: property (text), widget (QLabel, label_11)
+#: rc.cpp:50 rc.cpp:98
+#, fuzzy
+msgid "Saved List Settings"
+msgstr "Réglages audios ici!"
+
+#. i18n: file: mainwindow.ui:664
+#. i18n: ectx: property (text), widget (QLabel, label_9)
+#. i18n: file: mainwindow.ui:1071
+#. i18n: ectx: property (text), widget (QLabel, label_10)
+#: rc.cpp:53 rc.cpp:101
+msgid "Name"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:748
+#. i18n: ectx: attribute (label), widget (QWidget, videoTool_2)
+#: rc.cpp:62
+msgid "Video"
+msgstr "Vidéo"
+
+#. i18n: file: mainwindow.ui:1009
+#. i18n: ectx: property (text), widget (QToolButton, vCancelSaveList)
+#: rc.cpp:95
+msgid "Return To Lists"
+msgstr "Retour aux listes"
+
+#. i18n: file: mainwindow.ui:1352
+#. i18n: ectx: property (text), widget (QLabel, listTitle)
+#: rc.cpp:116
+msgid "List Title"
+msgstr "Titre de la liste"
+
+#. i18n: file: mainwindow.ui:1365
+#. i18n: ectx: property (text), widget (QLabel, listSummary)
+#: rc.cpp:119
+msgid "Summary"
+msgstr "Résumé"
+
+#. i18n: file: mainwindow.ui:1375
+#. i18n: ectx: property (text), widget (QToolButton, sortList)
+#: rc.cpp:122
+msgid "Sort"
+msgstr "Tri"
+
+#. i18n: file: mainwindow.ui:1399
+#. i18n: ectx: property (text), widget (QToolButton, showInfo)
+#: rc.cpp:125
+msgid "Info"
+msgstr "Informations"
+
+#. i18n: file: mainwindow.ui:1514
+#. i18n: ectx: property (text), widget (QLabel, notificationText)
+#: rc.cpp:128
+msgid "Notification Text"
+msgstr "Texte de notification"
+
+#. i18n: file: mainwindow.ui:1589
+#. i18n: ectx: property (text), widget (QLabel, label_2)
+#: rc.cpp:131
+msgid "Information"
+msgstr "Information"
+
+#. i18n: file: mainwindow.ui:1596
+#. i18n: ectx: property (text), widget (QToolButton, editInfo)
+#: rc.cpp:134
+msgid "Edit"
+msgstr "Modifier"
+
+#. i18n: file: mainwindow.ui:1663
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:137
+msgid "1"
+msgstr "1"
+
+#. i18n: file: mainwindow.ui:1668
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:140
+msgid "2"
+msgstr "2"
+
+#. i18n: file: mainwindow.ui:1747
+#. i18n: ectx: property (text), widget (QToolButton, previous)
+#: rc.cpp:149
+msgid "Previous"
+msgstr "Précédent"
+
+#. i18n: file: mainwindow.ui:1805
+#. i18n: ectx: property (toolTip), widget (QPushButton, playAll)
+#: rc.cpp:155
+msgid "Play all media in list"
+msgstr "Lire tout les médias dans la liste"
+
+#. i18n: file: mainwindow.ui:1834
+#. i18n: ectx: property (toolTip), widget (QPushButton, playSelected)
+#: rc.cpp:161
+msgid "Play selected media in list"
+msgstr "Lire les médias sélectionnés dans la liste"
+
+#. i18n: file: mainwindow.ui:2346
+#. i18n: ectx: property (text), widget (QLabel, playbackMessage)
+#: rc.cpp:167
+msgid "Playback message"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:2375
+#. i18n: ectx: property (text), widget (QToolButton, showPlaylist)
+#: rc.cpp:170
+msgid "Playlist"
+msgstr "Liste de lecture"
+
+#. i18n: file: mainwindow.ui:5177
+#. i18n: ectx: property (text), widget (QToolButton, repeat)
+#. i18n: file: mainwindow.ui:5206
+#. i18n: ectx: property (text), widget (QToolButton, shuffle)
+#. i18n: file: mainwindow.ui:5449
+#. i18n: ectx: property (text), widget (SToolButton, fullScreen)
+#: rc.cpp:185 rc.cpp:191 rc.cpp:212
+msgid "[ ]"
+msgstr "[]"
+
+#. i18n: file: mainwindow.ui:5306
+#. i18n: ectx: property (text), widget (QLabel, label_3)
+#: rc.cpp:194
+#, fuzzy
+msgid "Video Settings"
+msgstr "Réglages audios ici!"
+
+#. i18n: file: mainwindow.ui:5335
+#. i18n: ectx: property (text), widget (QPushButton, saveShortCuts)
+#: rc.cpp:197
+msgid "Save Shortcuts"
+msgstr "Enregistrer les raccourcis claviers"
+
+#. i18n: file: mainwindow.ui:5342
+#. i18n: ectx: property (text), widget (QPushButton, cancelEditShortcuts)
+#: rc.cpp:200
+msgid "Cancel"
+msgstr "Annuler"
+
+#. i18n: file: mainwindow.ui:5402
+#. i18n: ectx: property (toolTip), widget (QToolButton, collectionButton)
+#: rc.cpp:203
+msgid "View Media Lists"
+msgstr "Afficher les listes de médias"
+
+#. i18n: file: mainwindow.ui:5446
+#. i18n: ectx: property (toolTip), widget (SToolButton, fullScreen)
+#: rc.cpp:209
+msgid "Show full screen"
+msgstr "Afficher le plein écran"
+
+#. i18n: file: mainwindow.ui:5538
+#. i18n: ectx: property (text), widget (QToolButton, seekTime)
+#: rc.cpp:218
+msgid "03:00"
+msgstr "03:00"
+
+#. i18n: file: mainwindow.ui:5699
+#. i18n: ectx: property (toolTip), widget (Phonon::VolumeSlider, volumeSlider)
+#: rc.cpp:224
+msgid "Volume"
+msgstr "Volume"
+
+#. i18n: file: mainwindow.ui:5725
+#. i18n: ectx: property (text), widget (QToolButton, mediaPrevious)
+#. i18n: file: mainwindow.ui:5754
+#. i18n: ectx: property (text), widget (SToolButton, mediaPlayPause)
+#. i18n: file: mainwindow.ui:5774
+#. i18n: ectx: property (text), widget (QToolButton, mediaNext)
+#: rc.cpp:227 rc.cpp:230 rc.cpp:233
+msgid "..."
+msgstr "..."
+
+#: videosettings.cpp:73
+msgid "Brightness"
+msgstr ""
+
+#: videosettings.cpp:83
+#, fuzzy
+msgid "Contrast"
+msgstr "Contributeur"
+
+#: videosettings.cpp:93
+msgid "Hue"
+msgstr ""
+
+#: videosettings.cpp:103
+msgid "Saturation"
+msgstr ""
+
+#: videosettings.cpp:118
+msgid "Aspect Ratio Settings"
+msgstr ""
+
+#: videosettings.cpp:120
+msgid "Automatic"
+msgstr ""
+
+#: videosettings.cpp:122
+msgid "4:3"
+msgstr ""
+
+#: videosettings.cpp:124
+msgid "16:9"
+msgstr ""
+
+#: videosettings.cpp:126
+msgid "Fit"
+msgstr ""
+
+#: videosettings.cpp:133
+msgid "Scaling Mode"
+msgstr ""
+
+#: videosettings.cpp:135
+msgid "Scale to fit"
+msgstr ""
+
+#: videosettings.cpp:137
+msgid "Scale and crop"
+msgstr ""
+
+#: videosettings.cpp:147
+msgid "Restore Defaults"
+msgstr ""
+
+#: videosettings.cpp:149
+#, fuzzy
+msgid "Hide"
+msgstr "Vidéo"
+
+#: platform/audioclipslistengine.cpp:107 platform/audioclipslistengine.cpp:131
+#: platform/videolistengine.cpp:176
+#, kde-format
+msgid "1 clip"
+msgid_plural "%1 clips"
+msgstr[0] "Un clip"
+msgstr[1] ""
+
+#: platform/audiostreamlistengine.cpp:103
+#: platform/audiostreamlistengine.cpp:134
+#, kde-format
+msgid "1 stream"
+msgid_plural "%1 streams"
+msgstr[0] "Un flux"
+msgstr[1] ""
+
+#: platform/audiostreamlistengine.cpp:108
+msgid "Create new audio stream item"
+msgstr "Créer un nouveau élément de flux audio"
+
+#: platform/audiostreamlistengine.cpp:155
+msgid "Untitled Audio Stream"
+msgstr "Flux audio sans titre"
+
+#: platform/audiostreamlistengine.cpp:156
+msgid "Select this item, click Info then Edit to enter audio stream info"
+msgstr ""
+"Sélectionnez cet élément, cliquez Info et Editer pour entrer les détails du "
+"flux audio"
+
+#: platform/audiostreamlistengine.cpp:165
+msgid "New Audio Stream"
+msgstr "Nouveau flux audio"
+
+#: platform/cdlistengine.cpp:80
+#, kde-format
+msgid "Track %1"
+msgstr "Piste %1"
+
+#: platform/cdlistengine.cpp:84
+#, kde-format
+msgid "Audio CD - %1 Tracks"
+msgstr "CD Audio - %1 pistes"
+
+#: platform/cdlistengine.cpp:93
+#, kde-format
+msgid "1 track"
+msgid_plural "%1 tracks"
+msgstr[0] "Une piste"
+msgstr[1] ""
+
+#: platform/dvdlistengine.cpp:76
+#, kde-format
+msgid "Title %1"
+msgstr "Titre %1"
+
+#: platform/dvdlistengine.cpp:80
+#, kde-format
+msgid "DVD Video - %1 Titles"
+msgstr "Vidéo DVD - %1 titres"
+
+#: platform/filelistengine.cpp:69 platform/filelistengine.cpp:86
+msgid "Audio Files"
+msgstr "Fichiers audio"
+
+#: platform/filelistengine.cpp:74 platform/filelistengine.cpp:97
+msgid "Video Files"
+msgstr "Fichiers vidéo"
+
+#: platform/filelistengine.cpp:87 platform/filelistengine.cpp:98
+#: platform/filelistengine.cpp:182 platform/mediaitemmodel.cpp:381
+#: platform/savedlistsengine.cpp:102 platform/videolistengine.cpp:451
+#: platform/videolistengine.cpp:517
+#, kde-format
+msgid "1 item"
+msgid_plural "%1 items"
+msgstr[0] "Un élément"
+msgstr[1] ""
+
+#: platform/filelistengine.cpp:122 platform/filelistengine.cpp:197
+msgid "Open audio file(s)"
+msgstr "Ouvrir des fichiers audio"
+
+#: platform/filelistengine.cpp:127 platform/filelistengine.cpp:208
+msgid "Open folder containing audio file(s)"
+msgstr "Ouvrir un dossier qui contient des fichiers audio"
+
+#: platform/filelistengine.cpp:133 platform/filelistengine.cpp:202
+msgid "Open video file(s)"
+msgstr "Ouvrir des fichiers vidéo"
+
+#: platform/filelistengine.cpp:138 platform/filelistengine.cpp:213
+msgid "Open folder containing video file(s)"
+msgstr "Ouvrir un dossier qui contient des fichiers vidéo"
+
+#: platform/filelistengine.cpp:144
+msgid "Open image file(s)"
+msgstr "Ouvrir des images"
+
+#: platform/filelistengine.cpp:149
+msgid "Open folder containing image file(s)"
+msgstr "Ouvrir un dossier qui contient des images"
+
+#: platform/filelistengine.cpp:326
+msgid "Audio Clip"
+msgstr "Clip audio"
+
+#: platform/filelistengine.cpp:413
+#, kde-format
+msgid "%1 - Episode %2"
+msgstr "%1 - Épisode %2"
+
+#: platform/filelistengine.cpp:415
+#, kde-format
+msgid "Episode %1"
+msgstr "Épisode %1"
+
+#: platform/mediaitemmodel.cpp:380
+#, fuzzy, kde-format
+msgid "Multiple %1"
+msgstr "Titre %1"
+
+#: platform/mediaitemmodel.cpp:532
+msgid "No results"
+msgstr ""
+
+#: platform/mediaitemmodel.cpp:563
+msgid "Add to playlist/Remove from playlist"
+msgstr "Ajouter à la liste de lecture/Retirer de la liste de lecture"
+
+#: platform/medialistsengine.cpp:52 platform/medialistsengine.cpp:150
+msgid "Files and Folders"
+msgstr "Fichiers et dossiers"
+
+#: platform/medialistsengine.cpp:57 platform/musiclistengine.cpp:222
+msgid "Artists"
+msgstr "Artistes"
+
+#: platform/medialistsengine.cpp:61 platform/musiclistengine.cpp:262
+msgid "Albums"
+msgstr "Albums"
+
+#: platform/medialistsengine.cpp:65 platform/musiclistengine.cpp:353
+msgid "Songs"
+msgstr "Chansons"
+
+#: platform/medialistsengine.cpp:69 platform/medialistsengine.cpp:159
+#: platform/musiclistengine.cpp:306 platform/videolistengine.cpp:402
+msgid "Genres"
+msgstr "Styles"
+
+#: platform/medialistsengine.cpp:73
+msgid "Clips"
+msgstr "Clips"
+
+#: platform/medialistsengine.cpp:77
+msgid "Audio Streams"
+msgstr "Flux audio"
+
+#: platform/medialistsengine.cpp:100 platform/medialistsengine.cpp:190
+#: platform/semanticslistengine.cpp:89
+msgid "Frequently Played"
+msgstr "Écoutés fréquemment"
+
+#: platform/medialistsengine.cpp:104 platform/medialistsengine.cpp:194
+#: platform/semanticslistengine.cpp:115
+msgid "Recently Played"
+msgstr "Écoutés récemment"
+
+#: platform/medialistsengine.cpp:108 platform/medialistsengine.cpp:198
+#: platform/semanticslistengine.cpp:140
+msgid "Highest Rated"
+msgstr "Plus de votes"
+
+#: platform/medialistsengine.cpp:155 platform/videolistengine.cpp:369
+msgid "Movies"
+msgstr "Films"
+
+#: platform/medialistsengine.cpp:163 platform/videolistengine.cpp:224
+msgid "TV Shows"
+msgstr "Émissions de télé"
+
+#: platform/medialistsengine.cpp:167 platform/videolistengine.cpp:175
+msgid "Video Clips"
+msgstr "Clips vidéo"
+
+#: platform/musiclistengine.cpp:224
+#, kde-format
+msgid "Artists - %1"
+msgstr "Artistes - %1"
+
+#: platform/musiclistengine.cpp:226
+#, kde-format
+msgid "1 artist"
+msgid_plural "%1 artists"
+msgstr[0] "Un artiste"
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:264 platform/musiclistengine.cpp:267
+#, kde-format
+msgid "Albums - %1"
+msgstr "Albums - %1"
+
+#: platform/musiclistengine.cpp:270
+#, kde-format
+msgid "Albums - %1 - %2"
+msgstr "Albums - %1 - %2"
+
+#: platform/musiclistengine.cpp:273
+#, kde-format
+msgid "1 album"
+msgid_plural "%1 albums"
+msgstr[0] "Un album"
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:307 platform/videolistengine.cpp:403
+#, kde-format
+msgid "1 genre"
+msgid_plural "%1 genres"
+msgstr[0] "Un style"
+msgstr[1] ""
+
+#: platform/musiclistengine.cpp:355 platform/musiclistengine.cpp:383
+#, kde-format
+msgid "1 song"
+msgid_plural "%1 songs"
+msgstr[0] "Une chanson"
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:216 platform/videolistengine.cpp:332
+msgid "Uncategorized TV Shows"
+msgstr "Émissions de télé sans catégories"
+
+#: platform/videolistengine.cpp:225
+#, kde-format
+msgid "1 show"
+msgid_plural "%1 shows"
+msgstr[0] "Une émission"
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:253
+#, kde-format
+msgid "Season %1"
+msgstr "Saison %1"
+
+#: platform/videolistengine.cpp:272
+msgid "Uncategorized seasons"
+msgstr "Saisons sans catégories"
+
+#: platform/videolistengine.cpp:279
+#, fuzzy, kde-format
+msgid "Seasons - %1"
+msgstr "Saison %1"
+
+#: platform/videolistengine.cpp:280
+#, kde-format
+msgid "1 season"
+msgid_plural "%1 seasons"
+msgstr[0] "Une saison"
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:334
+#, kde-format
+msgid "%1 - Season %2"
+msgstr "%1 - Saison %2"
+
+#: platform/videolistengine.cpp:336
+#, kde-format
+msgid "%1 - Uncategorized Seasons"
+msgstr "%1 - Saisons sans catégories"
+
+#: platform/videolistengine.cpp:338
+#, kde-format
+msgid "1 episode"
+msgid_plural "%1 episodes"
+msgstr[0] "Une épisode"
+msgstr[1] ""
+
+#: platform/videolistengine.cpp:371
+#, kde-format
+msgid "Movies - %1"
+msgstr "Films - %1"
+
+#: platform/videolistengine.cpp:373
+#, kde-format
+msgid "1 movie"
+msgid_plural "%1 movies"
+msgstr[0] "Un film"
+msgstr[1] ""
+
+#~ msgid "buttonGroup"
+#~ msgstr "buttonGroup"
diff --git a/translations/merge.sh b/translations/merge.sh
new file mode 100644
index 0000000..0253538
--- /dev/null
+++ b/translations/merge.sh
@@ -0,0 +1,6 @@
+#! /bin/bash
+#Add your translation here to have it merged.
+
+msgmerge -U nl/bangarang.po bangarang.pot
+msgmerge -U de/bangarang.po bangarang.pot
+msgmerge -U fr/bangarang.po bangarang.pot
diff --git a/translations/nl/CMakeLists.txt b/translations/nl/CMakeLists.txt
new file mode 100644
index 0000000..b312828
--- /dev/null
+++ b/translations/nl/CMakeLists.txt
@@ -0,0 +1,2 @@
+file(GLOB _po_files *.po)
+GETTEXT_PROCESS_PO_FILES( nl ALL INSTALL_DESTINATION ${LOCALE_INSTALL_DIR} ${_po_files} )
diff --git a/translations/nl/bangarang.po b/translations/nl/bangarang.po
new file mode 100644
index 0000000..357e6dc
--- /dev/null
+++ b/translations/nl/bangarang.po
@@ -0,0 +1,1060 @@
+# Copyright (C) YEAR This_file_is_part_of_KDE
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Kristof Bal <kristof.bal at gmail.com>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2009-12-21 22:58-0800\n"
+"PO-Revision-Date: 2009-12-12 11:28+0100\n"
+"Last-Translator: Kristof Bal <kristof.bal at gmail.com>\n"
+"Language-Team: Dutch <kde-i18n-nl at kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: actionsmanager.cpp:48
+msgid "Quit"
+msgstr "Afsluiten"
+
+#: actionsmanager.cpp:57
+msgid "Play next"
+msgstr "Volgende afspelen"
+
+#: actionsmanager.cpp:63
+msgid "Play previous"
+msgstr "Vorige afspelen"
+
+#: actionsmanager.cpp:75 mainwindow.cpp:1087
+msgid "Play all"
+msgstr "Alles afspelen"
+
+#. i18n: file: mainwindow.ui:1811
+#. i18n: ectx: property (text), widget (QPushButton, playAll)
+#: actionsmanager.cpp:77 rc.cpp:158
+msgid "Play All"
+msgstr "Alles afspelen"
+
+#: actionsmanager.cpp:80 mainwindow.cpp:1089
+msgid "Play selected"
+msgstr "Geselecteerde afspelen"
+
+#. i18n: file: mainwindow.ui:1837
+#. i18n: ectx: property (text), widget (QPushButton, playSelected)
+#: actionsmanager.cpp:82 rc.cpp:164
+msgid "Play Selected"
+msgstr "Geselecteerde afspelen"
+
+#: actionsmanager.cpp:85 actionsmanager.cpp:87
+msgid "Add to playlist"
+msgstr "Toevoegen aan afspeellijst"
+
+#: actionsmanager.cpp:90 actionsmanager.cpp:92
+msgid "Remove from playlist"
+msgstr "Uit afspeellijst verwijderen"
+
+#: actionsmanager.cpp:95 actionsmanager.cpp:99
+msgid "Hide controls"
+msgstr "Bediening verbergen"
+
+#: actionsmanager.cpp:106 actionsmanager.cpp:381 mainwindow.cpp:348
+msgid "Show Video Settings"
+msgstr "Video-instellingen tonen"
+
+#: actionsmanager.cpp:113
+msgid "Toggle fullscreen"
+msgstr "Volledig scherm wisselen"
+
+#: actionsmanager.cpp:122
+msgid "Remove selected info"
+msgstr "Geselecteerd informatie verwijderen"
+
+#: actionsmanager.cpp:127
+msgid "Refresh"
+msgstr "Vernieuwen"
+
+#: actionsmanager.cpp:133
+#, fuzzy
+msgid "Remove from list"
+msgstr "Uit afspeellijst verwijderen"
+
+#: actionsmanager.cpp:137
+#, fuzzy
+msgid "Add to list"
+msgstr "Toevoegen aan afspeellijst"
+
+#: actionsmanager.cpp:141
+#, fuzzy
+msgid "Add to list "
+msgstr "Toevoegen aan afspeellijst"
+
+#: actionsmanager.cpp:145 actionsmanager.cpp:149
+#, fuzzy
+msgid "New list"
+msgstr "Nieuwe naam van de lijst"
+
+#: actionsmanager.cpp:153
+#, fuzzy
+msgid "Show items"
+msgstr "1 item"
+
+#: actionsmanager.cpp:158
+msgid "Configure shortcuts..."
+msgstr "Sneltoetsen instellen..."
+
+#: actionsmanager.cpp:377
+msgid "Hide Video Settings"
+msgstr "Video-instellingen verbergen"
+
+#. i18n: file: mainwindow.ui:1673
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:239 rc.cpp:143
+msgid "Title"
+msgstr "Titel"
+
+#: infomanager.cpp:241
+msgid "Artwork"
+msgstr "Illustraties"
+
+#: infomanager.cpp:243
+msgid "Description"
+msgstr "Beschrijving"
+
+#: infomanager.cpp:245
+msgid "Location"
+msgstr "Locatie"
+
+#: infomanager.cpp:287 infomanager.cpp:345
+msgid "Type"
+msgstr "Type"
+
+#. i18n: file: mainwindow.ui:1681
+#. i18n: ectx: property (text), item, widget (QTreeWidget, infoView)
+#: infomanager.cpp:306 rc.cpp:146
+msgid "Artist"
+msgstr "Artiest"
+
+#: infomanager.cpp:308
+msgid "Album"
+msgstr "Album"
+
+#: infomanager.cpp:310 infomanager.cpp:366 infomanager.cpp:396
+msgid "Year"
+msgstr "Jaar"
+
+#: infomanager.cpp:312
+msgid "Track Number"
+msgstr "Tracknummer"
+
+#: infomanager.cpp:314 infomanager.cpp:368
+msgid "Genre"
+msgstr "Genre"
+
+#: infomanager.cpp:364
+msgid "Collection/Series Name"
+msgstr "Naam van de verzameling/serie"
+
+#: infomanager.cpp:391
+msgid "Series Name"
+msgstr "Naam van de serie"
+
+#: infomanager.cpp:393
+msgid "Season"
+msgstr "Seizoen"
+
+#: infomanager.cpp:395
+msgid "Episode"
+msgstr "Episode"
+
+#. i18n: file: mainwindow.ui:23
+#. i18n: ectx: property (windowTitle), widget (QMainWindow, MainWindowClass)
+#: main.cpp:29 mainwindow.cpp:274 mainwindow.cpp:551 mainwindow.cpp:924
+#: mainwindow.cpp:1098 rc.cpp:5
+msgid "Bangarang"
+msgstr "Bangarang"
+
+#: main.cpp:30
+msgid "A Media Player"
+msgstr "Een mediaspeler"
+
+#: main.cpp:31
+msgid "Copyright 2009, Andrew Lake"
+msgstr "Copyright 2009, Andrew Lake"
+
+#: main.cpp:38
+msgid "Andrew (Jamboarder) Lake"
+msgstr "Andrew (Jamboarder) Lake"
+
+#: main.cpp:38
+msgid "Creator"
+msgstr "Maker"
+
+#: main.cpp:39
+msgid "Sebastian Jambor"
+msgstr "Sebastian Jambor"
+
+#: main.cpp:39 main.cpp:40 main.cpp:41
+msgid "Contributor"
+msgstr "Bijdragen"
+
+#: main.cpp:40
+msgid "Janusz Lewandowski"
+msgstr "Janusz Lewandowski"
+
+#: main.cpp:41
+msgid "Andreas Marschke"
+msgstr "Andreas Marschke"
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at http://code.google.com/p/bangarangissuetracking/"
+msgstr ""
+"Fouten mogen worden gemeld op http://code.google.com/p/"
+"bangarangissuetracking/"
+
+#: main.cpp:43
+msgid ""
+"Defects may be reported at <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>Bangarang Issue Tracker</a>"
+msgstr ""
+"Fouten mogen worden gerapporteerd bij <a href='http://code.google.com/p/"
+"bangarangissuetracking/'>de foutentracker van Bangarang</a>"
+
+#: main.cpp:50
+msgid "Play 'URL'"
+msgstr "'URL' afspelen"
+
+#: main.cpp:51
+msgid "Play DVD Video"
+msgstr "DVD afspelen"
+
+#: main.cpp:52
+msgid "Play CD Music"
+msgstr "CD afspelen"
+
+#: main.cpp:53
+msgid "Show Additional Debug Output"
+msgstr "Extra debuguitvoer tonen"
+
+#: mainwindow.cpp:238 platform/medialistsengine.cpp:183
+msgid "DVD Video"
+msgstr "DVD-video"
+
+#: mainwindow.cpp:248 platform/medialistsengine.cpp:93
+msgid "Audio CD"
+msgstr "Audio-cd"
+
+#: mainwindow.cpp:274
+msgid ""
+"Bangarang is unable to access the Nepomuk Semantic Desktop repository. Media "
+"library, rating and play count functions will be unavailable."
+msgstr ""
+"Bangarang heeft geen toegang tot Nepomuk. De mediabibliotheek, waarderingen "
+"en afspeelteller zullen niet beschikbaar zijn."
+
+#: mainwindow.cpp:274
+msgid "Don't show this message again"
+msgstr "Deze boodschap niet meer tonen"
+
+#: mainwindow.cpp:356
+msgid "<b>Fullscreen</b><br>Click to exit fullscreen"
+msgstr ""
+"<b>Volledig scherm</b><br>Klik hier om volledig scherm uit te schakelen"
+
+#: mainwindow.cpp:363
+msgid "Show fullscreen"
+msgstr "Volledig scherm tonen"
+
+#: mainwindow.cpp:374 mainwindow.cpp:644
+msgid "<b>Time remaining</b><br>Click to show elapsed time"
+msgstr "<b>Resterende tijd</b><br>Klik hier om de verstreken tijd te tonen"
+
+#. i18n: file: mainwindow.ui:5535
+#. i18n: ectx: property (toolTip), widget (QToolButton, seekTime)
+#: mainwindow.cpp:376 mainwindow.cpp:646 rc.cpp:215
+msgid "<b>Time elapsed</b><br>Click to show remaining time"
+msgstr "<b>Verstreken tijd</b><br>Klik hier om de resterende tijd te tonen"
+
+#: mainwindow.cpp:385
+msgid "<b>Paused</b><br>Hold to stop"
+msgstr "<b>Gepauzeerd</b><br>Houden om te stoppen"
+
+#. i18n: file: mainwindow.ui:253
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, Filter)
+#: mainwindow.cpp:516 rc.cpp:11
+msgid "Search for audio"
+msgstr "Zoeken naar audio"
+
+#: mainwindow.cpp:524
+msgid "Search for video"
+msgstr "Zoeken naar video"
+
+#. i18n: file: mainwindow.ui:5147
+#. i18n: ectx: property (toolTip), widget (QToolButton, clearPlaylist)
+#: mainwindow.cpp:547 rc.cpp:179
+msgid "Clear Playlist"
+msgstr "Afspeellijst wissen"
+
+#: mainwindow.cpp:548
+msgid "Are you sure you want to clear the current playlist?"
+msgstr "Bent u zeker dat u de huidige afspeellijst wil wissen?"
+
+#. i18n: file: mainwindow.ui:1202
+#. i18n: ectx: property (text), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:553 mainwindow.cpp:654 mainwindow.cpp:656 mainwindow.cpp:926
+#: rc.cpp:113
+msgid "Now Playing"
+msgstr "Speelt nu"
+
+#: mainwindow.cpp:563
+msgid "<b>Shuffle On</b><br>Click to turn off Shuffle"
+msgstr "<b>Shuffle aan</b><br>Klik hier om shuffle uit te schakelen"
+
+#. i18n: file: mainwindow.ui:5203
+#. i18n: ectx: property (toolTip), widget (QToolButton, shuffle)
+#: mainwindow.cpp:567 rc.cpp:188
+msgid "Turn on Shuffle"
+msgstr "Shuffle inschakelen"
+
+#: mainwindow.cpp:578
+msgid "<b>Repeat On</b><br>Click to turn off repeat"
+msgstr "<b>Herhalen aan</b><br>Klik hier om herhalen uit te schakelen"
+
+#. i18n: file: mainwindow.ui:5174
+#. i18n: ectx: property (toolTip), widget (QToolButton, repeat)
+#: mainwindow.cpp:581 rc.cpp:182
+msgid "Turn on Repeat"
+msgstr "Herhalen inschakelen"
+
+#: mainwindow.cpp:590
+msgid "<b>Showing Upcoming</b><br>Click to show playlist"
+msgstr "<b>Volgende tonen</b><br>Klik om de afspeellijst te tonen"
+
+#: mainwindow.cpp:591
+msgid "<b>Playlist</b>(Upcoming)"
+msgstr "<b>Afspeellijst</b>(Volgende)"
+
+#. i18n: file: mainwindow.ui:5092
+#. i18n: ectx: property (toolTip), widget (QToolButton, showQueue)
+#: mainwindow.cpp:595 rc.cpp:173
+msgid "Show Upcoming"
+msgstr "Volgende tonen"
+
+#: mainwindow.cpp:670
+msgid "<b>Playing</b><br>Click to pause<br>Click and hold to stop"
+msgstr ""
+"<b>Aan het spelen</b><br>Klik om te pauzeren<br>Klik en houden om te stoppen"
+
+#: mainwindow.cpp:681
+msgid "An error has been encountered during playback"
+msgstr ""
+
+#: mainwindow.cpp:701
+msgid "Loading playlist..."
+msgstr "Afspeellijst laden..."
+
+#: mainwindow.cpp:703
+msgid "Buffering..."
+msgstr "Bufferen..."
+
+#: mainwindow.cpp:705 platform/mediaitemmodel.cpp:501
+msgid "Loading..."
+msgstr "Bezig met laden..."
+
+#: mainwindow.cpp:717
+msgid "<b>Muted</b><br>Click to restore volume"
+msgstr "<b>Gedempt</b><br>Klik hier om het volume te herstellen"
+
+#. i18n: file: mainwindow.ui:5661
+#. i18n: ectx: property (toolTip), widget (SToolButton, volumeIcon)
+#: mainwindow.cpp:720 rc.cpp:221
+msgid "Mute volume"
+msgstr "Volume dempen"
+
+#: mainwindow.cpp:757
+msgid "Updating..."
+msgstr "Bijwerken..."
+
+#: mainwindow.cpp:763
+msgid "Complete"
+msgstr ""
+
+#: mainwindow.cpp:769
+msgid "Updated info for "
+msgstr "Informatie bijgewerkt voor "
+
+#: mainwindow.cpp:775
+msgid "Removed info for "
+msgstr "Informatie verwijderd voor "
+
+#. i18n: file: mainwindow.ui:5124
+#. i18n: ectx: property (text), widget (QLabel, playlistName)
+#: mainwindow.cpp:879 rc.cpp:176
+msgid "<b>Playlist</b>"
+msgstr "<b>Afspeellijst</b>"
+
+#: mainwindow.cpp:882
+#, kde-format
+msgid "1 item, %2"
+msgid_plural "%1 items, %2"
+msgstr[0] "1 item, %2"
+msgstr[1] "%1 items, %2"
+
+#. i18n: file: mainwindow.ui:1199
+#. i18n: ectx: property (toolTip), widget (QToolButton, nowPlaying)
+#: mainwindow.cpp:897 mainwindow.cpp:927 rc.cpp:110
+msgid "View Now Playing"
+msgstr "Nu afspelende bekijken"
+
+#: mainwindow.cpp:1099
+msgid "Entertainment... Now"
+msgstr "Amusement... Nu"
+
+#: rc.cpp:1
+msgctxt "NAME OF TRANSLATORS"
+msgid "Your names"
+msgstr "Kristof Bal"
+
+#: rc.cpp:2
+msgctxt "EMAIL OF TRANSLATORS"
+msgid "Your emails"
+msgstr "kristof.bal at gmail.com"
+
+#. i18n: file: mainwindow.ui:149
+#. i18n: ectx: property (text), widget (QLabel, label)
+#. i18n: file: mainwindow.ui:5405
+#. i18n: ectx: property (text), widget (QToolButton, collectionButton)
+#: rc.cpp:8 rc.cpp:206
+msgid "Media Lists"
+msgstr "Medialijst"
+
+#. i18n: file: mainwindow.ui:296
+#. i18n: ectx: attribute (label), widget (QWidget, AudioTool_2)
+#: rc.cpp:14
+msgid "Audio"
+msgstr "Audio"
+
+#. i18n: file: mainwindow.ui:364
+#. i18n: ectx: property (toolTip), widget (QToolButton, addAudioList)
+#. i18n: file: mainwindow.ui:801
+#. i18n: ectx: property (toolTip), widget (QToolButton, addVideoList)
+#: rc.cpp:17 rc.cpp:65
+#, fuzzy
+msgid "Add list"
+msgstr "Lijst toevoegen van"
+
+#. i18n: file: mainwindow.ui:381
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeAudioList)
+#. i18n: file: mainwindow.ui:818
+#. i18n: ectx: property (toolTip), widget (QToolButton, removeVideoList)
+#: rc.cpp:20 rc.cpp:68
+#, fuzzy
+msgid "Remove list"
+msgstr "Uit afspeellijst verwijderen"
+
+#. i18n: file: mainwindow.ui:411
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureAudioList)
+#. i18n: file: mainwindow.ui:848
+#. i18n: ectx: property (toolTip), widget (QToolButton, configureVideoList)
+#: rc.cpp:23 rc.cpp:71
+#, fuzzy
+msgid "Settings"
+msgstr "Video-instellingen"
+
+#. i18n: file: mainwindow.ui:460
+#. i18n: ectx: property (text), widget (QLabel, label_5)
+#. i18n: file: mainwindow.ui:897
+#. i18n: ectx: property (text), widget (QLabel, label_7)
+#: rc.cpp:26 rc.cpp:74
+#, fuzzy
+msgid "Add List"
+msgstr "Lijst toevoegen van"
+
+#. i18n: file: mainwindow.ui:477
+#. i18n: ectx: property (text), widget (QLabel, label_4)
+#. i18n: file: mainwindow.ui:914
+#. i18n: ectx: property (text), widget (QLabel, label_6)
+#: rc.cpp:29 rc.cpp:77
+#, fuzzy
+msgid "Source"
+msgstr "Sorteren"
+
+#. i18n: file: mainwindow.ui:499
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceView)
+#. i18n: file: mainwindow.ui:940
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceView)
+#: rc.cpp:32 rc.cpp:83
+msgid "Current View"
+msgstr "Huidig beeld"
+
+#. i18n: file: mainwindow.ui:506
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourceSelection)
+#. i18n: file: mainwindow.ui:933
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourceSelection)
+#: rc.cpp:35 rc.cpp:80
+msgid "Current Selection"
+msgstr "Huidige selectie"
+
+#. i18n: file: mainwindow.ui:513
+#. i18n: ectx: property (text), widget (QRadioButton, aListSourcePlaylist)
+#. i18n: file: mainwindow.ui:947
+#. i18n: ectx: property (text), widget (QRadioButton, vListSourcePlaylist)
+#: rc.cpp:38 rc.cpp:86
+msgid "Current Playlist"
+msgstr "Huidige afspeellijst"
+
+#. i18n: file: mainwindow.ui:523
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, aNewListName)
+#. i18n: file: mainwindow.ui:957
+#. i18n: ectx: property (clickMessage), widget (KLineEdit, vNewListName)
+#: rc.cpp:41 rc.cpp:89
+msgid "New List Name"
+msgstr "Nieuwe naam van de lijst"
+
+#. i18n: file: mainwindow.ui:545
+#. i18n: ectx: property (text), widget (QPushButton, saveAudioList)
+#. i18n: file: mainwindow.ui:689
+#. i18n: ectx: property (text), widget (QPushButton, aslsSave)
+#. i18n: file: mainwindow.ui:976
+#. i18n: ectx: property (text), widget (QPushButton, saveVideoList)
+#. i18n: file: mainwindow.ui:1096
+#. i18n: ectx: property (text), widget (QPushButton, vslsSave)
+#. i18n: file: mainwindow.ui:1782
+#. i18n: ectx: property (text), widget (QPushButton, saveInfo)
+#: rc.cpp:44 rc.cpp:56 rc.cpp:92 rc.cpp:104 rc.cpp:152
+msgid "Save"
+msgstr "Opslaan"
+
+#. i18n: file: mainwindow.ui:599
+#. i18n: ectx: property (text), widget (QToolButton, aCancelSaveList)
+#. i18n: file: mainwindow.ui:719
+#. i18n: ectx: property (text), widget (QToolButton, aslsCancel)
+#. i18n: file: mainwindow.ui:1126
+#. i18n: ectx: property (text), widget (QToolButton, vslsCancel)
+#: rc.cpp:47 rc.cpp:59 rc.cpp:107
+msgid "Return to Lists"
+msgstr "Terug naar lijsten"
+
+#. i18n: file: mainwindow.ui:638
+#. i18n: ectx: property (text), widget (QLabel, label_8)
+#. i18n: file: mainwindow.ui:1045
+#. i18n: ectx: property (text), widget (QLabel, label_11)
+#: rc.cpp:50 rc.cpp:98
+#, fuzzy
+msgid "Saved List Settings"
+msgstr "Video-instellingen tonen"
+
+#. i18n: file: mainwindow.ui:664
+#. i18n: ectx: property (text), widget (QLabel, label_9)
+#. i18n: file: mainwindow.ui:1071
+#. i18n: ectx: property (text), widget (QLabel, label_10)
+#: rc.cpp:53 rc.cpp:101
+msgid "Name"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:748
+#. i18n: ectx: attribute (label), widget (QWidget, videoTool_2)
+#: rc.cpp:62
+msgid "Video"
+msgstr "Video"
+
+#. i18n: file: mainwindow.ui:1009
+#. i18n: ectx: property (text), widget (QToolButton, vCancelSaveList)
+#: rc.cpp:95
+msgid "Return To Lists"
+msgstr "Terug naar lijsten"
+
+#. i18n: file: mainwindow.ui:1352
+#. i18n: ectx: property (text), widget (QLabel, listTitle)
+#: rc.cpp:116
+msgid "List Title"
+msgstr "Titel van de lijst"
+
+#. i18n: file: mainwindow.ui:1365
+#. i18n: ectx: property (text), widget (QLabel, listSummary)
+#: rc.cpp:119
+msgid "Summary"
+msgstr "Samenvatting"
+
+#. i18n: file: mainwindow.ui:1375
+#. i18n: ectx: property (text), widget (QToolButton, sortList)
+#: rc.cpp:122
+msgid "Sort"
+msgstr "Sorteren"
+
+#. i18n: file: mainwindow.ui:1399
+#. i18n: ectx: property (text), widget (QToolButton, showInfo)
+#: rc.cpp:125
+msgid "Info"
+msgstr "Info"
+
+#. i18n: file: mainwindow.ui:1514
+#. i18n: ectx: property (text), widget (QLabel, notificationText)
+#: rc.cpp:128
+msgid "Notification Text"
+msgstr "Notification Text"
+
+#. i18n: file: mainwindow.ui:1589
+#. i18n: ectx: property (text), widget (QLabel, label_2)
+#: rc.cpp:131
+msgid "Information"
+msgstr "Informatie"
+
+#. i18n: file: mainwindow.ui:1596
+#. i18n: ectx: property (text), widget (QToolButton, editInfo)
+#: rc.cpp:134
+msgid "Edit"
+msgstr "Bewerken"
+
+#. i18n: file: mainwindow.ui:1663
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:137
+msgid "1"
+msgstr "1"
+
+#. i18n: file: mainwindow.ui:1668
+#. i18n: ectx: property (text), widget (QTreeWidget, infoView)
+#: rc.cpp:140
+msgid "2"
+msgstr "2"
+
+#. i18n: file: mainwindow.ui:1747
+#. i18n: ectx: property (text), widget (QToolButton, previous)
+#: rc.cpp:149
+msgid "Previous"
+msgstr "Vorige"
+
+#. i18n: file: mainwindow.ui:1805
+#. i18n: ectx: property (toolTip), widget (QPushButton, playAll)
+#: rc.cpp:155
+msgid "Play all media in list"
+msgstr "Alle media in lijst afspelen"
+
+#. i18n: file: mainwindow.ui:1834
+#. i18n: ectx: property (toolTip), widget (QPushButton, playSelected)
+#: rc.cpp:161
+msgid "Play selected media in list"
+msgstr "Geselecteerde media in lijst afspelen"
+
+#. i18n: file: mainwindow.ui:2346
+#. i18n: ectx: property (text), widget (QLabel, playbackMessage)
+#: rc.cpp:167
+msgid "Playback message"
+msgstr ""
+
+#. i18n: file: mainwindow.ui:2375
+#. i18n: ectx: property (text), widget (QToolButton, showPlaylist)
+#: rc.cpp:170
+msgid "Playlist"
+msgstr "Afspeellijst"
+
+#. i18n: file: mainwindow.ui:5177
+#. i18n: ectx: property (text), widget (QToolButton, repeat)
+#. i18n: file: mainwindow.ui:5206
+#. i18n: ectx: property (text), widget (QToolButton, shuffle)
+#. i18n: file: mainwindow.ui:5449
+#. i18n: ectx: property (text), widget (SToolButton, fullScreen)
+#: rc.cpp:185 rc.cpp:191 rc.cpp:212
+msgid "[ ]"
+msgstr "[ ]"
+
+#. i18n: file: mainwindow.ui:5306
+#. i18n: ectx: property (text), widget (QLabel, label_3)
+#: rc.cpp:194
+msgid "Video Settings"
+msgstr "Video-instellingen"
+
+#. i18n: file: mainwindow.ui:5335
+#. i18n: ectx: property (text), widget (QPushButton, saveShortCuts)
+#: rc.cpp:197
+msgid "Save Shortcuts"
+msgstr "Sneltoetsen opslaan"
+
+#. i18n: file: mainwindow.ui:5342
+#. i18n: ectx: property (text), widget (QPushButton, cancelEditShortcuts)
+#: rc.cpp:200
+msgid "Cancel"
+msgstr "Annuleren"
+
+#. i18n: file: mainwindow.ui:5402
+#. i18n: ectx: property (toolTip), widget (QToolButton, collectionButton)
+#: rc.cpp:203
+msgid "View Media Lists"
+msgstr "Medialijsten tonen"
+
+#. i18n: file: mainwindow.ui:5446
+#. i18n: ectx: property (toolTip), widget (SToolButton, fullScreen)
+#: rc.cpp:209
+msgid "Show full screen"
+msgstr "Volledig scherm tonen"
+
+#. i18n: file: mainwindow.ui:5538
+#. i18n: ectx: property (text), widget (QToolButton, seekTime)
+#: rc.cpp:218
+msgid "03:00"
+msgstr "03:00"
+
+#. i18n: file: mainwindow.ui:5699
+#. i18n: ectx: property (toolTip), widget (Phonon::VolumeSlider, volumeSlider)
+#: rc.cpp:224
+msgid "Volume"
+msgstr "Volume"
+
+#. i18n: file: mainwindow.ui:5725
+#. i18n: ectx: property (text), widget (QToolButton, mediaPrevious)
+#. i18n: file: mainwindow.ui:5754
+#. i18n: ectx: property (text), widget (SToolButton, mediaPlayPause)
+#. i18n: file: mainwindow.ui:5774
+#. i18n: ectx: property (text), widget (QToolButton, mediaNext)
+#: rc.cpp:227 rc.cpp:230 rc.cpp:233
+msgid "..."
+msgstr "..."
+
+#: videosettings.cpp:73
+msgid "Brightness"
+msgstr "Helderheid"
+
+#: videosettings.cpp:83
+msgid "Contrast"
+msgstr "Contrast"
+
+#: videosettings.cpp:93
+msgid "Hue"
+msgstr "Tint"
+
+#: videosettings.cpp:103
+msgid "Saturation"
+msgstr "Verzadiging"
+
+#: videosettings.cpp:118
+msgid "Aspect Ratio Settings"
+msgstr "Hoogte/breedteverhouding"
+
+#: videosettings.cpp:120
+msgid "Automatic"
+msgstr "Automatisch"
+
+#: videosettings.cpp:122
+msgid "4:3"
+msgstr "4:3"
+
+#: videosettings.cpp:124
+msgid "16:9"
+msgstr "16:9"
+
+#: videosettings.cpp:126
+msgid "Fit"
+msgstr "Passend"
+
+#: videosettings.cpp:133
+msgid "Scaling Mode"
+msgstr "Schaalmodus"
+
+#: videosettings.cpp:135
+msgid "Scale to fit"
+msgstr "Passend schalen"
+
+#: videosettings.cpp:137
+msgid "Scale and crop"
+msgstr "Schalen en bijsnijden"
+
+#: videosettings.cpp:147
+msgid "Restore Defaults"
+msgstr "Standaardwaarden"
+
+#: videosettings.cpp:149
+msgid "Hide"
+msgstr "Verbergen"
+
+#: platform/audioclipslistengine.cpp:107 platform/audioclipslistengine.cpp:131
+#: platform/videolistengine.cpp:176
+#, kde-format
+msgid "1 clip"
+msgid_plural "%1 clips"
+msgstr[0] "1 clip"
+msgstr[1] "%1 clips"
+
+#: platform/audiostreamlistengine.cpp:103
+#: platform/audiostreamlistengine.cpp:134
+#, kde-format
+msgid "1 stream"
+msgid_plural "%1 streams"
+msgstr[0] "1 stream"
+msgstr[1] "%1 streams"
+
+#: platform/audiostreamlistengine.cpp:108
+msgid "Create new audio stream item"
+msgstr "Nieuwe audiostreamitem aanmaken"
+
+#: platform/audiostreamlistengine.cpp:155
+msgid "Untitled Audio Stream"
+msgstr "Naamloze audiostream"
+
+#: platform/audiostreamlistengine.cpp:156
+msgid "Select this item, click Info then Edit to enter audio stream info"
+msgstr ""
+"Selecteer dit item, klik op Info, dan Bewerken om nieuwe "
+"audiostreaminformatie toe te voegen"
+
+#: platform/audiostreamlistengine.cpp:165
+msgid "New Audio Stream"
+msgstr "Nieuwe audiostream"
+
+#: platform/cdlistengine.cpp:80
+#, kde-format
+msgid "Track %1"
+msgstr "Track %1"
+
+#: platform/cdlistengine.cpp:84
+#, kde-format
+msgid "Audio CD - %1 Tracks"
+msgstr "Audio-CD - %1 tracks"
+
+#: platform/cdlistengine.cpp:93
+#, kde-format
+msgid "1 track"
+msgid_plural "%1 tracks"
+msgstr[0] "1 track"
+msgstr[1] "%1 tracks"
+
+#: platform/dvdlistengine.cpp:76
+#, kde-format
+msgid "Title %1"
+msgstr "Titel %1"
+
+#: platform/dvdlistengine.cpp:80
+#, kde-format
+msgid "DVD Video - %1 Titles"
+msgstr "DVD-video - %1 titels"
+
+#: platform/filelistengine.cpp:69 platform/filelistengine.cpp:86
+msgid "Audio Files"
+msgstr "Audiobestanden"
+
+#: platform/filelistengine.cpp:74 platform/filelistengine.cpp:97
+msgid "Video Files"
+msgstr "Videobestanden"
+
+#: platform/filelistengine.cpp:87 platform/filelistengine.cpp:98
+#: platform/filelistengine.cpp:182 platform/mediaitemmodel.cpp:381
+#: platform/savedlistsengine.cpp:102 platform/videolistengine.cpp:451
+#: platform/videolistengine.cpp:517
+#, kde-format
+msgid "1 item"
+msgid_plural "%1 items"
+msgstr[0] "1 item"
+msgstr[1] "%1 items"
+
+#: platform/filelistengine.cpp:122 platform/filelistengine.cpp:197
+msgid "Open audio file(s)"
+msgstr "Audiobestanden openen"
+
+#: platform/filelistengine.cpp:127 platform/filelistengine.cpp:208
+msgid "Open folder containing audio file(s)"
+msgstr "Map openen met audiobestanden"
+
+#: platform/filelistengine.cpp:133 platform/filelistengine.cpp:202
+msgid "Open video file(s)"
+msgstr "Videobestanden openen"
+
+#: platform/filelistengine.cpp:138 platform/filelistengine.cpp:213
+msgid "Open folder containing video file(s)"
+msgstr "Map openen met videobestanden"
+
+#: platform/filelistengine.cpp:144
+msgid "Open image file(s)"
+msgstr "Afbeeldingen openen"
+
+#: platform/filelistengine.cpp:149
+msgid "Open folder containing image file(s)"
+msgstr "Map openen met afbeeldingen"
+
+#: platform/filelistengine.cpp:326
+msgid "Audio Clip"
+msgstr "Audioclip"
+
+#: platform/filelistengine.cpp:413
+#, kde-format
+msgid "%1 - Episode %2"
+msgstr "%1 - Episode %2"
+
+#: platform/filelistengine.cpp:415
+#, kde-format
+msgid "Episode %1"
+msgstr "Episode %1"
+
+#: platform/mediaitemmodel.cpp:380
+#, fuzzy, kde-format
+msgid "Multiple %1"
+msgstr "Titel %1"
+
+#: platform/mediaitemmodel.cpp:532
+msgid "No results"
+msgstr "Geen resultaten"
+
+#: platform/mediaitemmodel.cpp:563
+msgid "Add to playlist/Remove from playlist"
+msgstr "Aan afspeellijst toevoegen/Uit afspeellijst verwijderen"
+
+#: platform/medialistsengine.cpp:52 platform/medialistsengine.cpp:150
+msgid "Files and Folders"
+msgstr "Bestanden en mappen"
+
+#: platform/medialistsengine.cpp:57 platform/musiclistengine.cpp:222
+msgid "Artists"
+msgstr "Artiesten"
+
+#: platform/medialistsengine.cpp:61 platform/musiclistengine.cpp:262
+msgid "Albums"
+msgstr "Albums"
+
+#: platform/medialistsengine.cpp:65 platform/musiclistengine.cpp:353
+msgid "Songs"
+msgstr "Tracks"
+
+#: platform/medialistsengine.cpp:69 platform/medialistsengine.cpp:159
+#: platform/musiclistengine.cpp:306 platform/videolistengine.cpp:402
+msgid "Genres"
+msgstr "Genres"
+
+#: platform/medialistsengine.cpp:73
+msgid "Clips"
+msgstr "Clips"
+
+#: platform/medialistsengine.cpp:77
+msgid "Audio Streams"
+msgstr "Audiostreams"
+
+#: platform/medialistsengine.cpp:100 platform/medialistsengine.cpp:190
+#: platform/semanticslistengine.cpp:89
+msgid "Frequently Played"
+msgstr "Veel afgespeeld"
+
+#: platform/medialistsengine.cpp:104 platform/medialistsengine.cpp:194
+#: platform/semanticslistengine.cpp:115
+msgid "Recently Played"
+msgstr "Recent afgespeeld"
+
+#: platform/medialistsengine.cpp:108 platform/medialistsengine.cpp:198
+#: platform/semanticslistengine.cpp:140
+msgid "Highest Rated"
+msgstr "Hoogst beoordeeld"
+
+#: platform/medialistsengine.cpp:155 platform/videolistengine.cpp:369
+msgid "Movies"
+msgstr "Films"
+
+#: platform/medialistsengine.cpp:163 platform/videolistengine.cpp:224
+msgid "TV Shows"
+msgstr "TV-programma's"
+
+#: platform/medialistsengine.cpp:167 platform/videolistengine.cpp:175
+msgid "Video Clips"
+msgstr "Videoclips"
+
+#: platform/musiclistengine.cpp:224
+#, kde-format
+msgid "Artists - %1"
+msgstr "Artiesten - %1"
+
+#: platform/musiclistengine.cpp:226
+#, kde-format
+msgid "1 artist"
+msgid_plural "%1 artists"
+msgstr[0] "1 artiest"
+msgstr[1] "%1 artiesten"
+
+#: platform/musiclistengine.cpp:264 platform/musiclistengine.cpp:267
+#, kde-format
+msgid "Albums - %1"
+msgstr "Albums - %1"
+
+#: platform/musiclistengine.cpp:270
+#, kde-format
+msgid "Albums - %1 - %2"
+msgstr "Albums - %1 - %2"
+
+#: platform/musiclistengine.cpp:273
+#, kde-format
+msgid "1 album"
+msgid_plural "%1 albums"
+msgstr[0] "1 album"
+msgstr[1] "%1 albums"
+
+#: platform/musiclistengine.cpp:307 platform/videolistengine.cpp:403
+#, kde-format
+msgid "1 genre"
+msgid_plural "%1 genres"
+msgstr[0] "1 genre"
+msgstr[1] "%1 genres"
+
+#: platform/musiclistengine.cpp:355 platform/musiclistengine.cpp:383
+#, kde-format
+msgid "1 song"
+msgid_plural "%1 songs"
+msgstr[0] "1 track"
+msgstr[1] "%1 tracks"
+
+#: platform/videolistengine.cpp:216 platform/videolistengine.cpp:332
+msgid "Uncategorized TV Shows"
+msgstr "TV-programma's zonder categorie"
+
+#: platform/videolistengine.cpp:225
+#, kde-format
+msgid "1 show"
+msgid_plural "%1 shows"
+msgstr[0] "1 TV-programma"
+msgstr[1] "%1 TV-programma's"
+
+#: platform/videolistengine.cpp:253
+#, kde-format
+msgid "Season %1"
+msgstr "Seizoen %1"
+
+#: platform/videolistengine.cpp:272
+msgid "Uncategorized seasons"
+msgstr "Seizoenen zonder categorie"
+
+#: platform/videolistengine.cpp:279
+#, fuzzy, kde-format
+msgid "Seasons - %1"
+msgstr "Seizoen %1"
+
+#: platform/videolistengine.cpp:280
+#, kde-format
+msgid "1 season"
+msgid_plural "%1 seasons"
+msgstr[0] "1 seizoen"
+msgstr[1] "%1 seizoenen"
+
+#: platform/videolistengine.cpp:334
+#, kde-format
+msgid "%1 - Season %2"
+msgstr "%1 - Seizoen %2"
+
+#: platform/videolistengine.cpp:336
+#, kde-format
+msgid "%1 - Uncategorized Seasons"
+msgstr "%1 - Seizoenen zonder categorie"
+
+#: platform/videolistengine.cpp:338
+#, kde-format
+msgid "1 episode"
+msgid_plural "%1 episodes"
+msgstr[0] "1 episode"
+msgstr[1] "%1 episodes"
+
+#: platform/videolistengine.cpp:371
+#, kde-format
+msgid "Movies - %1"
+msgstr "Films - %1"
+
+#: platform/videolistengine.cpp:373
+#, kde-format
+msgid "1 movie"
+msgid_plural "%1 movies"
+msgstr[0] "1 film"
+msgstr[1] "%1 films"
--
bangarang packaging
More information about the pkg-multimedia-commits
mailing list