[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