[mupen64plus-qt] 03/05: Import Upstream version 1.10

Markus Koschany apo at moszumanska.debian.org
Sat Oct 21 16:15:16 UTC 2017


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch master
in repository mupen64plus-qt.

commit 646da4f8b646a9b9166d472f60e35c5b711fbf84
Author: Markus Koschany <apo at debian.org>
Date:   Sat Oct 21 18:12:15 2017 +0200

    Import Upstream version 1.10
---
 .travis.yml                                        |    7 +-
 README.md                                          |    6 +-
 VERSION                                            |    2 +-
 build-scripts/platform/linux.sh                    |    4 +-
 build-scripts/platform/osx.sh                      |   18 +-
 build-scripts/platform/windows.sh                  |   10 +-
 dist/debian/install                                |    2 +-
 dist/redhat/mupen64plus-qt.spec.in                 |    4 +-
 mupen64plus-qt.pro                                 |   60 +-
 resources/locale/mupen64plus-qt_fr.qm              |  Bin 15075 -> 20451 bytes
 resources/locale/mupen64plus-qt_fr.ts              |  690 ++++++++------
 src/common.cpp                                     |   53 +-
 src/common.h                                       |    3 +
 src/{ => dialogs}/aboutdialog.cpp                  |   25 +-
 src/{ => dialogs}/aboutdialog.h                    |    3 +-
 src/{ => dialogs}/configeditor.cpp                 |    5 +-
 src/{ => dialogs}/configeditor.h                   |    0
 src/{ => dialogs}/downloaddialog.cpp               |   10 +-
 src/{ => dialogs}/downloaddialog.h                 |    4 +-
 src/{ => dialogs}/gamesettingsdialog.cpp           |    3 +-
 src/{ => dialogs}/gamesettingsdialog.h             |    0
 src/{ => dialogs}/gamesettingsdialog.ui            |    0
 src/{ => dialogs}/logdialog.cpp                    |    5 +-
 src/{ => dialogs}/logdialog.h                      |    0
 src/{ => dialogs}/settingsdialog.cpp               |  102 +-
 src/{ => dialogs}/settingsdialog.h                 |    4 +-
 src/{ => dialogs}/settingsdialog.ui                |   84 +-
 src/{ => emulation}/emulatorhandler.cpp            |   44 +-
 src/{ => emulation}/emulatorhandler.h              |    0
 src/global.h                                       |   25 +-
 src/main.cpp                                       |    9 +-
 src/mainwindow.cpp                                 | 1001 +++++++-------------
 src/mainwindow.h                                   |   52 +-
 src/{ => roms}/romcollection.cpp                   |  136 ++-
 src/{ => roms}/romcollection.h                     |   12 +-
 .../thegamesdbscraper.cpp}                         |   27 +-
 .../thegamesdbscraper.h}                           |   10 +-
 src/views/gridview.cpp                             |  374 ++++++++
 src/{downloaddialog.h => views/gridview.h}         |   59 +-
 src/views/listview.cpp                             |  329 +++++++
 src/{emulatorhandler.h => views/listview.h}        |   53 +-
 src/views/tableview.cpp                            |  353 +++++++
 src/{emulatorhandler.h => views/tableview.h}       |   51 +-
 src/{ => views/widgets}/clickablewidget.cpp        |   20 +-
 src/{ => views/widgets}/clickablewidget.h          |    3 +
 src/{ => views/widgets}/treewidgetitem.cpp         |    0
 src/{ => views/widgets}/treewidgetitem.h           |    0
 47 files changed, 2388 insertions(+), 1274 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index f31f648..9ec318a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,14 +27,15 @@ deploy:
   bucket: dh4
   skip_cleanup: true
   local_dir: build
-  upload-dir: mupen64plus-qt/latest
+  upload-dir: mupen64plus-qt
   on:
-    branch: master
+    all_branches: true
+    condition: $TRAVIS_PULL_REQUEST = false
 - provider: releases
   api_key:
     secure: P/QbvYtOmGixPZLFozvpEHOrIFb0TisCN9kQOrhpXY3lA6hxdZK0wUDkvI/R8xQLZf8Z6s1D3WMJR6S5ifEciLo3bi+arNUOierYw4+WaLi5LT1Jbj9cEUiuKOnPFJU23H2LHruAk03L2m5D7uqWj9CFiBg8PDRf3Xd1Ek8sIqms4yAvoN5OtFnLgYSn2gYR7fnVAqY3SBw7NTgCr4aB0jqWhqQprXIPpsbp/ZkyFA0ej27fyi8NLTY0fmpqXU4CxgR3PxhY+v+n7HZVt5Dafrf2WyJptGC7pUA6a0TQos8UIeBXluyA6BgvIJrApwU0RxeXQyC6wLtlabSWDQSMkL0UnT6yFGJYKwufSKlVdKLKsB4p21/YasL60o0Xd5FwOX96nh3510VbWrGWWxtp5hpHgVEdc8Dty1wjTq1DinVlGyJywZ1trwIdYDa2J+FWYHJmgq1xxhhBkcFR0C9oa2d9pIuqG3Sr [...]
   skip_cleanup: true
   file_glob: true
-  file: build/mupen64plus-qt_*
+  file: build/master/mupen64plus-qt_*
   on:
     tags: true
diff --git a/README.md b/README.md
index 0dfad56..2df55d3 100644
--- a/README.md
+++ b/README.md
@@ -48,9 +48,9 @@ _Redhat/Fedora:_ See the section below on [creating a .rpm package](#creating-a-
 ### Development Builds
 
 Automatic builds of the latest git commit can be downloaded here:  
-Linux: [mupen64plus-qt_linux_git-latest.tar.gz](https://s3.amazonaws.com/dh4/mupen64plus-qt/latest/mupen64plus-qt_linux_git-latest.tar.gz)  
-Windows: [mupen64plus-qt_win_git-latest.zip](https://s3.amazonaws.com/dh4/mupen64plus-qt/latest/mupen64plus-qt_win_git-latest.zip)  
-OSX: [mupen64plus-qt_osx_git-latest.dmg](https://s3.amazonaws.com/dh4/mupen64plus-qt/latest/mupen64plus-qt_osx_git-latest.dmg)
+Linux: [mupen64plus-qt_linux_git-latest.tar.gz](https://s3.amazonaws.com/dh4/mupen64plus-qt/master/mupen64plus-qt_linux_git-latest.tar.gz)  
+Windows: [mupen64plus-qt_win_git-latest.zip](https://s3.amazonaws.com/dh4/mupen64plus-qt/master/mupen64plus-qt_win_git-latest.zip)  
+OSX: [mupen64plus-qt_osx_git-latest.dmg](https://s3.amazonaws.com/dh4/mupen64plus-qt/master/mupen64plus-qt_osx_git-latest.dmg)
 
 Be aware that these may contain bugs not present in the stable releases.
 
diff --git a/VERSION b/VERSION
index 2e0e38c..c044b1a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.9
+1.10
diff --git a/build-scripts/platform/linux.sh b/build-scripts/platform/linux.sh
index bf00568..d24ccb7 100755
--- a/build-scripts/platform/linux.sh
+++ b/build-scripts/platform/linux.sh
@@ -24,10 +24,10 @@ case "$1" in
     ;;
 
     'package')
-        mkdir build
+        mkdir -p "build/$TRAVIS_BRANCH"
 
         mv resources/README.txt .
-        tar -cvzpf build/mupen64plus-qt_linux_$VERSION.tar.gz mupen64plus-qt README.txt
+        tar -cvzpf "build/$TRAVIS_BRANCH/mupen64plus-qt_linux_$VERSION.tar.gz" mupen64plus-qt README.txt
     ;;
 
 esac
diff --git a/build-scripts/platform/osx.sh b/build-scripts/platform/osx.sh
index e6ae2d4..7228641 100755
--- a/build-scripts/platform/osx.sh
+++ b/build-scripts/platform/osx.sh
@@ -7,8 +7,8 @@
 case "$1" in
 
     'setup_qt')
-        mkdir $WORKING_DIR/../osx
-        cd $WORKING_DIR/../osx
+        mkdir "$WORKING_DIR/../osx"
+        cd "$WORKING_DIR/../osx"
 
         if [[ $BUILD_OSX_QT ]]; then
             # Build Qt
@@ -22,7 +22,7 @@ case "$1" in
             tar -xvzf macosx-qt5.tar.gz >& /dev/null
         fi
 
-        cd $WORKING_DIR/mupen64plus-qt
+        cd "$WORKING_DIR/mupen64plus-qt"
     ;;
 
     'get_quazip')
@@ -38,19 +38,19 @@ case "$1" in
     ;;
 
     'package')
-        mkdir build
+        mkdir -p "build/$TRAVIS_BRANCH"
 
-        hdiutil create -megabytes 20 -fs HFS+ -volname Mupen64Plus-Qt mupen64plus-qt_osx_$VERSION
-        hdiutil attach mupen64plus-qt_osx_$VERSION.dmg
+        hdiutil create -megabytes 20 -fs HFS+ -volname Mupen64Plus-Qt "mupen64plus-qt_osx_$VERSION"
+        hdiutil attach "mupen64plus-qt_osx_$VERSION.dmg"
 
         cp -r Mupen64Plus-Qt.app /Volumes/Mupen64Plus-Qt/Mupen64Plus-Qt.app
         cp resources/README.txt /Volumes/Mupen64Plus-Qt/README.txt
 
         hdiutil detach /Volumes/Mupen64Plus-Qt
-        hdiutil convert -format UDZO -o mupen64plus-qt_osx_$VERSION.dmg \
-                        -ov mupen64plus-qt_osx_$VERSION.dmg
+        hdiutil convert -format UDZO -o "mupen64plus-qt_osx_$VERSION.dmg" \
+                        -ov "mupen64plus-qt_osx_$VERSION.dmg"
 
-        mv mupen64plus-qt_osx_$VERSION.dmg build/
+        mv "mupen64plus-qt_osx_$VERSION.dmg" "build/$TRAVIS_BRANCH"
     ;;
 
 esac
diff --git a/build-scripts/platform/windows.sh b/build-scripts/platform/windows.sh
index 8177928..105c68d 100755
--- a/build-scripts/platform/windows.sh
+++ b/build-scripts/platform/windows.sh
@@ -7,7 +7,7 @@
 case "$1" in
 
     'setup_qt')
-        cd $WORKING_DIR/../
+        cd "$WORKING_DIR/../"
 
         if [[ $BUILD_MXE_QT ]]; then
             # Build Qt with mxe
@@ -27,7 +27,7 @@ case "$1" in
             tar -xvzf travis-mxe-qt5.tar.gz > /dev/null
         fi
 
-        cd $WORKING_DIR/mupen64plus-qt
+        cd "$WORKING_DIR/mupen64plus-qt"
     ;;
 
     'get_quazip')
@@ -37,7 +37,7 @@ case "$1" in
     ;;
 
     'build')
-        export PATH=$PATH:$WORKING_DIR/../mxe/usr/bin
+        export PATH="$PATH:$WORKING_DIR/../mxe/usr/bin"
 
         ./build-scripts/revision.sh
         i686-w64-mingw32.static-qmake-qt5
@@ -45,10 +45,10 @@ case "$1" in
     ;;
 
     'package')
-        mkdir build
+        mkdir -p "build/$TRAVIS_BRANCH"
 
         mv release/mupen64plus-qt.exe resources/README.txt .
-        zip build/mupen64plus-qt_win_$VERSION.zip mupen64plus-qt.exe README.txt
+        zip "build/$TRAVIS_BRANCH/mupen64plus-qt_win_$VERSION.zip" mupen64plus-qt.exe README.txt
     ;;
 
 esac
diff --git a/dist/debian/install b/dist/debian/install
index 22d27bd..1da72d4 100644
--- a/dist/debian/install
+++ b/dist/debian/install
@@ -1,4 +1,4 @@
 mupen64plus-qt                      usr/games
 resources/mupen64plus-qt.desktop    usr/share/applications
-resources/mupen64plus-qt.1          usr/share/man/man1
+resources/mupen64plus-qt.6          usr/share/man/man6
 resources/images/mupen64plus.png    usr/share/icons/hicolor/128x128/apps/mupen64plus-qt.png
diff --git a/dist/redhat/mupen64plus-qt.spec.in b/dist/redhat/mupen64plus-qt.spec.in
index a1f66f9..710fcab 100644
--- a/dist/redhat/mupen64plus-qt.spec.in
+++ b/dist/redhat/mupen64plus-qt.spec.in
@@ -31,7 +31,7 @@ make %{?_smp_mflags}
 install -Dm755 "mupen64plus-qt"                     "%{buildroot}%{_bindir}/mupen64plus-qt"
 install -Dm644 "resources/mupen64plus-qt.desktop"   "%{buildroot}%{_datadir}/applications/mupen64plus-qt.desktop"
 install -Dm644 "resources/images/mupen64plus.png"   "%{buildroot}%{_datadir}/icons/hicolor/128x128/apps/mupen64plus-qt.png"
-install -Dm644 "resources/mupen64plus-qt.1"         "%{buildroot}%{_mandir}/man1/mupen64plus-qt.1"
+install -Dm644 "resources/mupen64plus-qt.6"         "%{buildroot}%{_mandir}/man6/mupen64plus-qt.6"
 
 %files
 %license LICENSE
@@ -39,7 +39,7 @@ install -Dm644 "resources/mupen64plus-qt.1"         "%{buildroot}%{_mandir}/man1
 %{_bindir}/mupen64plus-qt
 %{_datadir}/applications/mupen64plus-qt.desktop
 %{_datadir}/icons/hicolor/128x128/apps/mupen64plus-qt.png
-%{_mandir}/man1/mupen64plus-qt.1*
+%{_mandir}/man6/mupen64plus-qt.6*
 
 %changelog
 * Tue Oct 06 2015 Dan Hasting
diff --git a/mupen64plus-qt.pro b/mupen64plus-qt.pro
index dd1bd8d..ddf0f1e 100644
--- a/mupen64plus-qt.pro
+++ b/mupen64plus-qt.pro
@@ -20,37 +20,43 @@ win32:RC_FILE = dist/windows/icon.rc
 SOURCES += src/main.cpp \
     src/common.cpp \
     src/mainwindow.cpp \
-    src/aboutdialog.cpp \
-    src/settingsdialog.cpp \
-    src/gamesettingsdialog.cpp \
-    src/treewidgetitem.cpp \
-    src/clickablewidget.cpp \
-    src/configeditor.cpp \
-    src/downloaddialog.cpp \
-    src/logdialog.cpp \
-    src/emulatorhandler.cpp \
-    src/romcollection.cpp \
-    src/thegamesdbscrapper.cpp
+    src/dialogs/aboutdialog.cpp \
+    src/dialogs/configeditor.cpp \
+    src/dialogs/downloaddialog.cpp \
+    src/dialogs/gamesettingsdialog.cpp \
+    src/dialogs/logdialog.cpp \
+    src/dialogs/settingsdialog.cpp \
+    src/emulation/emulatorhandler.cpp \
+    src/roms/romcollection.cpp \
+    src/roms/thegamesdbscraper.cpp \
+    src/views/gridview.cpp \
+    src/views/listview.cpp \
+    src/views/tableview.cpp \
+    src/views/widgets/clickablewidget.cpp \
+    src/views/widgets/treewidgetitem.cpp
 
 HEADERS += src/global.h \
     src/common.h \
     src/mainwindow.h \
-    src/aboutdialog.h \
-    src/settingsdialog.h \
-    src/gamesettingsdialog.h \
-    src/treewidgetitem.h \
-    src/clickablewidget.h \
-    src/configeditor.h \
-    src/downloaddialog.h \
-    src/logdialog.h \
-    src/emulatorhandler.h \
-    src/romcollection.h \
-    src/thegamesdbscrapper.h
+    src/dialogs/aboutdialog.h \
+    src/dialogs/configeditor.h \
+    src/dialogs/downloaddialog.h \
+    src/dialogs/gamesettingsdialog.h \
+    src/dialogs/logdialog.h \
+    src/dialogs/settingsdialog.h \
+    src/emulation/emulatorhandler.h \
+    src/roms/romcollection.h \
+    src/roms/thegamesdbscraper.h \
+    src/views/gridview.h \
+    src/views/listview.h \
+    src/views/tableview.h \
+    src/views/widgets/clickablewidget.h \
+    src/views/widgets/treewidgetitem.h
 
 RESOURCES += resources/mupen64plusqt.qrc
 
-FORMS += src/settingsdialog.ui \
-    src/gamesettingsdialog.ui
+FORMS += src/dialogs/gamesettingsdialog.ui \
+    src/dialogs/settingsdialog.ui
 
 TRANSLATIONS += resources/locale/mupen64plus-qt_fr.ts
 
@@ -68,10 +74,10 @@ win32|macx|linux_quazip_static {
     } else {
         # Debian distributions use a different library name for Qt5 quazip
         system("which dpkg > /dev/null 2>&1") {
-            system("dpkg -l | grep libquazip5-dev | grep ^ii > /dev/null") {
-                LIBS += -lquazip5
-            } else {
+            system("dpkg -l | grep libquazip-qt5-dev | grep ^ii > /dev/null") {
                 LIBS += -lquazip-qt5
+            } else {
+                LIBS += -lquazip5
             }
         } else {
             LIBS += -lquazip5
diff --git a/resources/locale/mupen64plus-qt_fr.qm b/resources/locale/mupen64plus-qt_fr.qm
index ed43d45..8b1d3f3 100644
Binary files a/resources/locale/mupen64plus-qt_fr.qm and b/resources/locale/mupen64plus-qt_fr.qm differ
diff --git a/resources/locale/mupen64plus-qt_fr.ts b/resources/locale/mupen64plus-qt_fr.ts
index 14cef1a..a4d5541 100644
--- a/resources/locale/mupen64plus-qt_fr.ts
+++ b/resources/locale/mupen64plus-qt_fr.ts
@@ -4,73 +4,58 @@
 <context>
     <name>AboutDialog</name>
     <message>
-        <location filename="../../src/aboutdialog.cpp" line="44"/>
-        <source>About Mupen64Plus-Qt</source>
-        <translation>À propos de Mupen64Plus-Qt</translation>
+        <location filename="../../src/dialogs/aboutdialog.cpp" line="45"/>
+        <source>About <AppName></source>
+        <translation>À propos de <AppName></translation>
     </message>
     <message>
-        <location filename="../../src/aboutdialog.cpp" line="58"/>
+        <location filename="../../src/dialogs/aboutdialog.cpp" line="59"/>
         <source>Version</source>
         <translation>Version</translation>
     </message>
-    <message>
-        <location filename="../../src/aboutdialog.cpp" line="59"/>
-        <source>A basic launcher for Mupen64Plus using Qt.</source>
-        <translation>Une interface graphique simple et élémentaire pour Mupen64Plus.</translation>
-    </message>
-    <message>
-        <location filename="../../src/aboutdialog.cpp" line="60"/>
-        <source>Mupen64Plus website</source>
-        <translation>Site web de Mupen64Plus</translation>
-    </message>
-    <message>
-        <location filename="../../src/aboutdialog.cpp" line="61"/>
-        <source>GitHub repository</source>
-        <translation>Dépôt GitHub</translation>
-    </message>
 </context>
 <context>
     <name>ConfigEditor</name>
     <message>
-        <location filename="../../src/configeditor.cpp" line="48"/>
-        <source>Mupen64Plus Config Editor</source>
-        <translation type="unfinished"></translation>
+        <location filename="../../src/dialogs/configeditor.cpp" line="49"/>
+        <source><ParentName> Config Editor</source>
+        <translation>Éditeur de configuration <ParentName></translation>
     </message>
     <message>
-        <location filename="../../src/configeditor.cpp" line="72"/>
+        <location filename="../../src/dialogs/configeditor.cpp" line="73"/>
         <source>Save</source>
-        <translation type="unfinished"></translation>
+        <translation>Sauvegarder</translation>
     </message>
 </context>
 <context>
     <name>DownloadDialog</name>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="48"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="50"/>
         <source>Search Game Information</source>
         <translation>Chercher des informations sur le jeu</translation>
     </message>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="52"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="54"/>
         <source>File</source>
         <translation>Fichier</translation>
     </message>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="54"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="56"/>
         <source>Name of Game:</source>
         <translation>Nom du jeu :</translation>
     </message>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="55"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="57"/>
         <source>or Game ID:</source>
         <translation>ou identifiant du jeu :</translation>
     </message>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="61"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="63"/>
         <source>From thegamesdb.net URL of game</source>
         <translation>URL du jeu sur thegamesdb.net</translation>
     </message>
     <message>
-        <location filename="../../src/downloaddialog.cpp" line="64"/>
+        <location filename="../../src/dialogs/downloaddialog.cpp" line="66"/>
         <source>Search</source>
         <translation>Chercher</translation>
     </message>
@@ -78,35 +63,35 @@
 <context>
     <name>EmulatorHandler</name>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="56"/>
-        <location filename="../../src/emulatorhandler.cpp" line="183"/>
-        <location filename="../../src/emulatorhandler.cpp" line="189"/>
-        <location filename="../../src/emulatorhandler.cpp" line="199"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="57"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="185"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="192"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="202"/>
         <source>Warning</source>
         <translation>Attention</translation>
     </message>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="57"/>
-        <source>Mupen64Plus quit unexpectedly. Check the log for more information.</source>
-        <translation>Mupen64Plus a quitté de manière inattendue. Consultez les journaux pour plus d'informations.</translation>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="58"/>
+        <source><ParentName> quit unexpectedly. Check the log for more information.</source>
+        <translation><ParentName> a quitté de manière inattendue. Consultez les journaux pour plus d'informations.</translation>
     </message>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="60"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="62"/>
         <source>View Log...</source>
         <translation>Consulter les journaux...</translation>
     </message>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="199"/>
-        <source>Not a valid ROM File.</source>
-        <translation type="unfinished"></translation>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="186"/>
+        <source><ParentName> executable not found.</source>
+        <translation>Executable <ParentName> non trouvé.</translation>
     </message>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="183"/>
-        <source>Mupen64Plus executable not found.</source>
-        <translation>Executable Mupen64Plus non trouvé.</translation>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="202"/>
+        <source>Not a valid ROM File.</source>
+        <translation>Fichier ROM invalide.</translation>
     </message>
     <message>
-        <location filename="../../src/emulatorhandler.cpp" line="189"/>
+        <location filename="../../src/emulation/emulatorhandler.cpp" line="192"/>
         <source>ROM file not found.</source>
         <translation>Fichier ROM manquant.</translation>
     </message>
@@ -114,88 +99,104 @@
 <context>
     <name>GameSettingsDialog</name>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="20"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="20"/>
         <source>Game Settings</source>
-        <translation type="unfinished"></translation>
+        <translation>Paramètres du jeu</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="26"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="26"/>
         <source>Game settings for: </source>
-        <translation type="unfinished"></translation>
+        <translation>Paramètres du jeu pour :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="33"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="33"/>
         <source>These settings will override any global settings. If there's a setting you want to modify for this game, but it doesn't appear here, add the parameter for it to "Other Parameters."</source>
-        <translation type="unfinished"></translation>
+        <translation>Ces paramètres prévaleront sur tous les paramètres généraux. Si vous souhaitez modifier un paramètre pour ce jeu, mais qu'il n'apparaît pas ici, ajoutez-le dans "Autres paramètres."</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="43"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="43"/>
         <source>Plugins</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugins</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="57"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="57"/>
         <source>Audio Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin audio :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="64"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="64"/>
         <source>Input Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin d'entrée :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="71"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="71"/>
         <source>RSP Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin RSP :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="78"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="78"/>
         <source>Video Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin vidéo :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="86"/>
-        <location filename="../../src/gamesettingsdialog.ui" line="95"/>
-        <location filename="../../src/gamesettingsdialog.ui" line="104"/>
-        <location filename="../../src/gamesettingsdialog.ui" line="113"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="86"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="95"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="104"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="113"/>
         <source>default</source>
-        <translation type="unfinished"></translation>
+        <translation>Défaut</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="126"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="126"/>
         <source>Additional Settings</source>
-        <translation type="unfinished"></translation>
+        <translation>Paramètres supplémentaires</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="137"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="137"/>
         <source>Config Directory:</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier de configuration :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="144"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="144"/>
         <source>Other Parameters:</source>
-        <translation type="unfinished"></translation>
+        <translation>Autres paramètres :</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.ui" line="151"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.ui" line="151"/>
         <source>Browse...</source>
         <translation>Naviguer...</translation>
     </message>
     <message>
-        <location filename="../../src/gamesettingsdialog.cpp" line="106"/>
+        <location filename="../../src/dialogs/gamesettingsdialog.cpp" line="107"/>
         <source>Config Directory</source>
+        <translation>Dossier de configuration</translation>
+    </message>
+</context>
+<context>
+    <name>GridView</name>
+    <message>
+        <location filename="../../src/views/gridview.cpp" line="144"/>
+        <source>No Cart</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ListView</name>
+    <message>
+        <location filename="../../src/views/listview.cpp" line="158"/>
+        <source>No Cart</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
 <context>
     <name>LogDialog</name>
     <message>
-        <location filename="../../src/logdialog.cpp" line="46"/>
-        <source>Mupen64Plus Log</source>
-        <translation>Journaux Mupen64Plus</translation>
+        <location filename="../../src/dialogs/logdialog.cpp" line="47"/>
+        <source><ParentName> Log</source>
+        <translation>Journaux <ParentName></translation>
     </message>
     <message>
-        <location filename="../../src/logdialog.cpp" line="66"/>
+        <location filename="../../src/dialogs/logdialog.cpp" line="67"/>
         <source>Close</source>
         <translation>Fermer</translation>
     </message>
@@ -203,172 +204,182 @@
 <context>
     <name>MainWindow</name>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="69"/>
-        <source>Mupen64Plus-Qt</source>
-        <translation>Mupen64Plus-Qt</translation>
-    </message>
-    <message>
-        <location filename="../../src/mainwindow.cpp" line="517"/>
+        <location filename="../../src/mainwindow.cpp" line="250"/>
         <source>&File</source>
         <translation>&Fichier</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="518"/>
+        <location filename="../../src/mainwindow.cpp" line="251"/>
         <source>&Open ROM...</source>
         <translation>&Ouvrir une ROM...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="520"/>
+        <location filename="../../src/mainwindow.cpp" line="253"/>
         <source>&Refresh List</source>
         <translation>&Recharger la liste</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="521"/>
+        <location filename="../../src/mainwindow.cpp" line="254"/>
+        <location filename="../../src/mainwindow.cpp" line="885"/>
         <source>&Download/Update Info...</source>
         <translation>&Télécharger/Mettre à jour les infos...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="522"/>
+        <location filename="../../src/mainwindow.cpp" line="255"/>
+        <location filename="../../src/mainwindow.cpp" line="886"/>
         <source>D&elete Current Info...</source>
         <translation>&Effacer les infos actuelles...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="526"/>
+        <location filename="../../src/mainwindow.cpp" line="259"/>
         <source>&Quit</source>
         <translation>&Quitter</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="538"/>
+        <location filename="../../src/mainwindow.cpp" line="278"/>
         <source>&Emulation</source>
         <translation>&Émulation</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="539"/>
+        <location filename="../../src/mainwindow.cpp" line="279"/>
+        <location filename="../../src/mainwindow.cpp" line="875"/>
         <source>&Start</source>
         <translation>&Démarrer</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="540"/>
+        <location filename="../../src/mainwindow.cpp" line="280"/>
         <source>St&op</source>
         <translation>&Arrêter</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="542"/>
+        <location filename="../../src/mainwindow.cpp" line="282"/>
         <source>View Log...</source>
         <translation>Consulter les journaux...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="553"/>
+        <location filename="../../src/mainwindow.cpp" line="298"/>
         <source>&Settings</source>
         <translation>&Paramètres</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="579"/>
+        <location filename="../../src/mainwindow.cpp" line="299"/>
         <source>Edit mupen64plus.cfg...</source>
-        <translation type="unfinished"></translation>
+        <translation>Éditer mupen64plus.cfg...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="581"/>
+        <location filename="../../src/mainwindow.cpp" line="301"/>
+        <location filename="../../src/mainwindow.cpp" line="878"/>
         <source>Configure &Game...</source>
-        <translation type="unfinished"></translation>
+        <translation>Configurer le &jeu...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="585"/>
+        <location filename="../../src/mainwindow.cpp" line="305"/>
         <source>&Configure...</source>
         <translation>&Configurer...</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="554"/>
+        <location filename="../../src/mainwindow.cpp" line="713"/>
+        <source>There is no log. Either <ParentName> has not yet run or there was no output from the last run.</source>
+        <translation>Il n'y a pas de journaux. Soit <ParentName> n’a pas encore été lancé, soit il n’y a pas de données concernant le dernier démarrage.</translation>
+    </message>
+    <message>
+        <location filename="../../src/mainwindow.cpp" line="319"/>
         <source>&Layout</source>
         <translation>&Disposition</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="558"/>
+        <location filename="../../src/mainwindow.cpp" line="318"/>
+        <source>&View</source>
+        <translation>&Affichage</translation>
+    </message>
+    <message>
+        <location filename="../../src/mainwindow.cpp" line="323"/>
         <source>None</source>
         <translation>Aucune</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="559"/>
+        <location filename="../../src/mainwindow.cpp" line="324"/>
         <source>Table View</source>
         <translation>Vue en tableau</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="560"/>
+        <location filename="../../src/mainwindow.cpp" line="325"/>
         <source>Grid View</source>
         <translation>Vue en vignettes</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="561"/>
+        <location filename="../../src/mainwindow.cpp" line="326"/>
         <source>List View</source>
         <translation>Vue en liste</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="593"/>
+        <location filename="../../src/mainwindow.cpp" line="349"/>
+        <location filename="../../src/mainwindow.cpp" line="353"/>
+        <source>&Full-screen</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/mainwindow.cpp" line="367"/>
         <source>&Help</source>
         <translation>&Aide</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="594"/>
+        <location filename="../../src/mainwindow.cpp" line="368"/>
         <source>&About</source>
         <translation>À &propos</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="944"/>
+        <location filename="../../src/mainwindow.cpp" line="690"/>
         <source>Not Found</source>
-        <translation type="unfinished"></translation>
+        <translation>Non trouvé</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="944"/>
+        <location filename="../../src/mainwindow.cpp" line="690"/>
         <source>Editor requires config directory to be </source>
-        <translation type="unfinished"></translation>
+        <translation>L'éditeur nécessite que le dossier de configuration soit </translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="945"/>
+        <location filename="../../src/mainwindow.cpp" line="691"/>
         <source>set to a directory with mupen64plus.cfg.</source>
-        <translation type="unfinished"></translation>
+        <translation>un dossier contenant mupen64plus.cfg.</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="946"/>
+        <location filename="../../src/mainwindow.cpp" line="692"/>
         <source>See here for the default config location:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="975"/>
+        <location filename="../../src/mainwindow.cpp" line="712"/>
         <source>No Output</source>
         <translation>Pas de sortie</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="976"/>
-        <source>There is no log. Either Mupen64Plus has not yet run or there was no output from the last run.</source>
-        <translation>Il n'y a pas de journaux. Soit Mupen64Plus n’a pas encore été lancé, soit il n’y a pas de données concernant le dernier démarrage. </translation>
-    </message>
-    <message>
-        <location filename="../../src/mainwindow.cpp" line="1026"/>
+        <location filename="../../src/mainwindow.cpp" line="765"/>
         <source>All Files</source>
         <translation>Tous les fichiers</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="1028"/>
+        <location filename="../../src/mainwindow.cpp" line="775"/>
         <source>Open ROM File</source>
         <translation>Ouvrir un fichier ROM</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="1046"/>
+        <location filename="../../src/mainwindow.cpp" line="793"/>
         <source>No ROMs</source>
         <translation>Aucune ROM</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="1046"/>
+        <location filename="../../src/mainwindow.cpp" line="793"/>
         <source>No ROMs found in ZIP file.</source>
         <translation>Aucune ROM trouvée dans le fichier ZIP.</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="1061"/>
+        <location filename="../../src/mainwindow.cpp" line="808"/>
         <source>Select ROM</source>
         <translation>Choisir une ROM</translation>
     </message>
     <message>
-        <location filename="../../src/mainwindow.cpp" line="1078"/>
+        <location filename="../../src/mainwindow.cpp" line="825"/>
         <source>Launch</source>
         <translation>Lancer</translation>
     </message>
@@ -376,184 +387,203 @@
 <context>
     <name>QObject</name>
     <message>
-        <location filename="../../src/common.cpp" line="277"/>
+        <location filename="../../src/common.cpp" line="321"/>
         <source>GoodName</source>
-        <translatorcomment>me</translatorcomment>
         <translation>GoodName</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="278"/>
+        <location filename="../../src/common.cpp" line="322"/>
         <source>Filename</source>
         <translation>Nom du fichier</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="279"/>
+        <location filename="../../src/common.cpp" line="323"/>
         <source>Filename (extension)</source>
         <translation>Nom du fichier (extension)</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="280"/>
+        <location filename="../../src/common.cpp" line="324"/>
         <source>Zip File</source>
         <translation>Fichier Zip</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="281"/>
+        <location filename="../../src/common.cpp" line="325"/>
         <source>Internal Name</source>
         <translation>Nom interne</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="282"/>
+        <location filename="../../src/common.cpp" line="326"/>
         <source>Size</source>
         <translation>Taille</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="283"/>
+        <location filename="../../src/common.cpp" line="327"/>
         <source>MD5</source>
         <translation>MD5</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="284"/>
+        <location filename="../../src/common.cpp" line="328"/>
         <source>CRC1</source>
         <translation>CRC1</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="285"/>
+        <location filename="../../src/common.cpp" line="329"/>
         <source>CRC2</source>
-        <translation></translation>
+        <translation>CRC2</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="286"/>
+        <location filename="../../src/common.cpp" line="330"/>
         <source>Players</source>
         <translation>Joueurs</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="287"/>
+        <location filename="../../src/common.cpp" line="331"/>
         <source>Rumble</source>
         <translation>Rumble</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="288"/>
+        <location filename="../../src/common.cpp" line="332"/>
         <source>Save Type</source>
         <translation>Type de sauvegarde</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="289"/>
+        <location filename="../../src/common.cpp" line="333"/>
         <source>Game Title</source>
         <translation>Titre du jeu</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="290"/>
+        <location filename="../../src/common.cpp" line="334"/>
         <source>Release Date</source>
         <translation>Date de sortie</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="291"/>
+        <location filename="../../src/common.cpp" line="335"/>
         <source>Overview</source>
         <translation>Aperçu</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="292"/>
+        <location filename="../../src/common.cpp" line="336"/>
         <source>ESRB</source>
         <translation>ESRB</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="293"/>
+        <location filename="../../src/common.cpp" line="337"/>
         <source>Genre</source>
         <translation>Genre</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="294"/>
+        <location filename="../../src/common.cpp" line="338"/>
         <source>Publisher</source>
         <translation>Éditeur</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="295"/>
+        <location filename="../../src/common.cpp" line="339"/>
         <source>Developer</source>
         <translation>Développeur</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="296"/>
+        <location filename="../../src/common.cpp" line="340"/>
         <source>Rating</source>
         <translation>Certification</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="297"/>
+        <location filename="../../src/common.cpp" line="341"/>
+        <source>Game Cover</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/common.cpp" line="342"/>
         <source>Unknown ROM</source>
         <translation>ROM inconnue</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="298"/>
+        <location filename="../../src/common.cpp" line="343"/>
         <source>Requires catalog file</source>
         <translation>Fichier catalogue demandé</translation>
     </message>
     <message>
-        <location filename="../../src/common.cpp" line="299"/>
+        <location filename="../../src/common.cpp" line="344"/>
         <source>Not found</source>
         <translation>Non trouvé</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="296"/>
+        <location filename="../../src/roms/romcollection.cpp" line="343"/>
         <source>%1 MB</source>
         <translation>%1 - MB</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="166"/>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="203"/>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="248"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="171"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="208"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="253"/>
         <source>Game Information Download</source>
         <translation>Télécharger des informations sur le jeu</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="199"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="204"/>
         <source>No results found.</source>
         <translation>Aucun résultat.</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="201"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="206"/>
         <source>No more results found.</source>
         <translation>Pas d'autre résultat.</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="249"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="254"/>
         <source>Download Complete!</source>
         <translation>Téléchargement terminé !</translation>
     </message>
+    <message>
+        <location filename="../../src/global.h" line="44"/>
+        <source>A basic launcher for <ParentName> using Qt.</source>
+        <translation>Une interface élémentaire pour <ParentName>.</translation>
+    </message>
+    <message>
+        <location filename="../../src/global.h" line="47"/>
+        <source><ParentName> website</source>
+        <translation>Site web de <ParentName></translation>
+    </message>
+    <message>
+        <location filename="../../src/global.h" line="50"/>
+        <source>GitHub repository</source>
+        <translation>Dépôt GitHub</translation>
+    </message>
 </context>
 <context>
     <name>RomCollection</name>
     <message>
-        <location filename="../../src/romcollection.cpp" line="171"/>
-        <location filename="../../src/romcollection.cpp" line="178"/>
+        <location filename="../../src/roms/romcollection.cpp" line="189"/>
+        <location filename="../../src/roms/romcollection.cpp" line="195"/>
         <source>Warning</source>
         <translation>Attention</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="171"/>
+        <location filename="../../src/roms/romcollection.cpp" line="189"/>
         <source>No ROMs found in </source>
         <translation>Aucune ROM trouvée dans</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="178"/>
+        <location filename="../../src/roms/romcollection.cpp" line="195"/>
         <source>No ROMs found.</source>
         <translation>Aucune ROM trouvée.</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="424"/>
+        <location filename="../../src/roms/romcollection.cpp" line="471"/>
         <source>Database Not Loaded</source>
         <translation>Base de données non chargée</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="425"/>
+        <location filename="../../src/roms/romcollection.cpp" line="472"/>
         <source>Could not connect to Sqlite database. Application may misbehave.</source>
         <translation>Impossible de se connecter à la base de données Sqlite. L'application peut dysfonctionner.</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="453"/>
+        <location filename="../../src/roms/romcollection.cpp" line="501"/>
         <source>Loading ROMs...</source>
         <translation>Chargement des ROMS...</translation>
     </message>
     <message>
-        <location filename="../../src/romcollection.cpp" line="453"/>
+        <location filename="../../src/roms/romcollection.cpp" line="501"/>
         <source>Cancel</source>
         <translation>Annuler</translation>
     </message>
@@ -561,489 +591,535 @@
 <context>
     <name>SettingsDialog</name>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="20"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="20"/>
         <source>Settings</source>
         <translation>Paramètres</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="43"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="43"/>
         <source>Paths</source>
         <translation>Chemins</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="60"/>
-        <location filename="../../src/settingsdialog.ui" line="67"/>
-        <location filename="../../src/settingsdialog.ui" line="87"/>
-        <location filename="../../src/settingsdialog.ui" line="101"/>
-        <location filename="../../src/settingsdialog.ui" line="712"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="60"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="67"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="87"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="101"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="712"/>
         <source>Browse...</source>
         <translation>Naviguer...</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="49"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="49"/>
         <source>Mupen64Plus Files</source>
         <translation>Fichier Mupen64Plus</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="108"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="108"/>
         <source>Mupen64Plus executable: </source>
         <translation>Exécutable Mupen64Plus :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="149"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="149"/>
         <source>ROM Directories</source>
         <translation>Dossier des ROMS</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="191"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="191"/>
         <source>Add...</source>
         <translation>Ajouter...</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="198"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="198"/>
         <source>Remove</source>
         <translation>Supprimer</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="214"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="214"/>
         <source>Emulation</source>
         <translation>Émulation</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="80"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="80"/>
         <source>Config directory:</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier de configuration :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="94"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="94"/>
         <source>Plugins directory:</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier des plugins :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="118"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="118"/>
         <source>Data directory:</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier des données :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="175"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="175"/>
         <source>Mupen64Plus-Qt will search for all .z64, .v64, .n64, and .zip files in these directories</source>
-        <translation type="unfinished"></translation>
+        <translation>Mupen64Plus-Qt cherchera tous les fichiers z64, v64, n64 et zip dans ces dossiers</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="225"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="225"/>
         <source>Cached Interpreter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="232"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="232"/>
         <source>Pure Interpreter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="239"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="239"/>
         <source>Dynamic Recompiler</source>
-        <translation type="unfinished"></translation>
+        <translation>Recompilation dynamique</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="275"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="275"/>
         <source>Graphics</source>
-        <translation type="unfinished"></translation>
+        <translation>Graphique</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="286"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="286"/>
         <source>On Screen Display:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="293"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="293"/>
         <source>Fullscreen:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plein écran :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="300"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="300"/>
         <source>Resolution:</source>
-        <translation type="unfinished"></translation>
+        <translation>Résolution :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="360"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="360"/>
         <source>Plugins</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugins</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="368"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="368"/>
         <source>Video Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin vidéo :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="375"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="375"/>
         <source>Audio Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin audio :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="382"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="382"/>
         <source>Input Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin d'entrée :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="389"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="389"/>
         <source>RSP Plugin:</source>
-        <translation type="unfinished"></translation>
+        <translation>Plugin RSP :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="424"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="424"/>
         <source>Table</source>
         <translation>Tableau</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="438"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="438"/>
         <source>Image:</source>
         <translation>Image :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="475"/>
-        <location filename="../../src/settingsdialog.ui" line="485"/>
-        <location filename="../../src/settingsdialog.ui" line="527"/>
-        <location filename="../../src/settingsdialog.ui" line="537"/>
-        <location filename="../../src/settingsdialog.ui" line="939"/>
-        <location filename="../../src/settingsdialog.ui" line="949"/>
-        <location filename="../../src/settingsdialog.ui" line="985"/>
-        <location filename="../../src/settingsdialog.ui" line="995"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="475"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="485"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="527"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="537"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="949"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="959"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="995"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1005"/>
         <source>...</source>
         <translation>...</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="552"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="552"/>
         <source>Current Columns:</source>
         <translation>Colonnes utilisées :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="559"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="566"/>
         <source>Stretch First Column</source>
         <translation>Étendre la première colonne</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="566"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="559"/>
         <source>Available Columns:</source>
         <translation>Colonnes disponibles :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="615"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="615"/>
         <source>Grid</source>
         <translation>Vignettes</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="621"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="621"/>
         <source>ROM Label</source>
         <translation>Intitulé de la ROM</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="632"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="632"/>
         <source>Show Label:</source>
         <translation>Montrer l'intitulé :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="655"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="655"/>
         <source>Label Text:</source>
         <translation>Texte de l'intitulé :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="669"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="669"/>
         <source>Label Color:</source>
         <translation>Couleur de l'intitulé :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="704"/>
-        <location filename="../../src/settingsdialog.ui" line="1097"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="704"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1134"/>
         <source>Other</source>
         <translation>Autre</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="719"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="719"/>
         <source>Custom Background:</source>
         <translation>Choisir un arrière-plan :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="726"/>
-        <location filename="../../src/settingsdialog.ui" line="1051"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="726"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1051"/>
         <source>Sorting:</source>
         <translation>Classement :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="736"/>
-        <location filename="../../src/settingsdialog.ui" line="1044"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="736"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1044"/>
         <source>Descending</source>
         <translation>Descendant</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="758"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="753"/>
+        <source>Background:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="768"/>
         <source>ROM Image</source>
         <translation>Images des ROMS</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="791"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="801"/>
         <source>Shadow Inactive Color:</source>
         <translation>Couleur de l’ombre des vignettes inactives :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="798"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="808"/>
         <source>Shadow Active Color:</source>
         <translation>Couleur de l’ombre de la vignette active : </translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="805"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="815"/>
         <source>Columns:</source>
         <translation>Nombre de colonnes :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="812"/>
-        <location filename="../../src/settingsdialog.ui" line="1037"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="822"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1037"/>
         <source>Image Size:</source>
         <translation>Taille des images :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="887"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="878"/>
+        <source>Adjust Automatically</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="904"/>
         <source>List</source>
         <translation>Liste</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="914"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1071"/>
         <source>First Item as Header</source>
         <translation>Premier intitulé comme en-tête</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="921"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="931"/>
         <source>Current Items:</source>
         <translation>Intitulé actuel :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1020"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1030"/>
         <source>Available Items:</source>
         <translation>Intitulés disponibles :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1030"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1078"/>
         <source>Display Cover Image</source>
         <translation>Afficher les vignettes</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1131"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1085"/>
+        <source>Text Size:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1092"/>
+        <source>Theme:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1168"/>
         <source>Additional Parameters:</source>
-        <translation>Paramètres supplémentaires : </translation>
+        <translation>Paramètres supplémentaires :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1151"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1188"/>
         <source>Save Options:</source>
-        <translation type="unfinished"></translation>
+        <translation>Sauvegarder les options :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1144"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1181"/>
         <source>Download Game Information (thegamesdb.net):</source>
         <translation>Télécharger les informations sur les jeux (thegamesdb.net) :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1158"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1195"/>
         <source>Language:</source>
         <translation>Langue :</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1168"/>
-        <source><html><head/><body><p>Use to pass additional parameters to Mupen64Plus (cheats, etc.). See <a href="https://code.google.com/p/mupen64plus/wiki/UIConsoleUsage"><span style=" text-decoration: underline; color:#0057ae;">https://code.google.com/p/mupen64plus/wiki/UIConsoleUsage</span></a> for more information.</p></body></html></source>
-        <translation type="unfinished"></translation>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1205"/>
+        <source><html><head/><body><p>Use to pass additional parameters to Mupen64Plus (cheats, etc.). See <a href="http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage"><span style=" text-decoration: underline; color:#0057ae;">http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage</span></a> for more information.</p></body></html></source>
+        <translation><html><head/><body><p>À utiliser pour ajouter des paramètres supplémentaires (cheats, etc.). Voir <a href="http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage"><span style=" text-decoration: underline; color:#0057ae;">http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage</span></a> pour plus d'informations.</p></body></html></translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.ui" line="1203"/>
+        <location filename="../../src/dialogs/settingsdialog.ui" line="1240"/>
         <source><b>Note:</b> Language changes will not take place until application restart.</source>
-        <translation><b>Remarque : </b>Le changement de langue ne prendra effet qu'après le redémarrage du programme.</translation>
+        <translation><b>Remarque :</b> Le changement de langue ne prendra effet qu'après le redémarrage du programme.</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="178"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="179"/>
         <source>Extra Small</source>
         <translation>Très petite</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="179"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="180"/>
         <source>Small</source>
         <translation>Petite</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="180"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="181"/>
         <source>Medium</source>
         <translation>Moyenne</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="181"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="182"/>
         <source>Large</source>
         <translation>Grande</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="182"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="183"/>
         <source>Extra Large</source>
         <translation>Très grande</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="214"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="216"/>
         <source>Black</source>
         <translation>Noir</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="215"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="217"/>
         <source>White</source>
         <translation>Blanc</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="216"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="218"/>
         <source>Light Gray</source>
         <translation>Gris clair</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="217"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="219"/>
         <source>Dark Gray</source>
         <translation>Gris foncé</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="218"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="220"/>
         <source>Green</source>
         <translation>Vert</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="219"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="221"/>
         <source>Cyan</source>
         <translation>Cyan</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="220"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="222"/>
         <source>Blue</source>
         <translation>Bleu</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="221"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="223"/>
         <source>Purple</source>
         <translation>Violet</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="222"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="224"/>
         <source>Red</source>
         <translation>Rouge</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="223"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="225"/>
         <source>Pink</source>
         <translation>Rose</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="224"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="226"/>
         <source>Orange</source>
         <translation>Orange</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="225"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="227"/>
         <source>Yellow</source>
         <translation>Jaune</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="226"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="228"/>
         <source>Brown</source>
         <translation>Marron</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="375"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="231"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="310"/>
+        <source>Light</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="232"/>
+        <source>Normal</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="233"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="311"/>
+        <source>Dark</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="418"/>
         <source>ROM Directory</source>
         <translation>Dossiers des ROMS</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="416"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="442"/>
+        <source><ParentName> Executable</source>
+        <translation>Fichier exécutable <ParentName></translation>
+    </message>
+    <message>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="460"/>
         <source>Plugin Directory</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier des plugins</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="425"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="469"/>
         <source>Data Directory</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier des données</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="433"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="477"/>
         <source>Config Directory</source>
-        <translation type="unfinished"></translation>
+        <translation>Dossier de configuration</translation>
     </message>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="391"/>
+        <location filename="../../src/dialogs/settingsdialog.cpp" line="434"/>
         <source>Background Image</source>
         <translation>Image d'arrière-plan</translation>
     </message>
+</context>
+<context>
+    <name>TableView</name>
     <message>
-        <location filename="../../src/settingsdialog.cpp" line="399"/>
-        <source>Mupen64Plus Executable</source>
-        <translation>Fichier exécutable Mupen64Plus</translation>
+        <location filename="../../src/views/tableview.cpp" line="76"/>
+        <location filename="../../src/views/tableview.cpp" line="79"/>
+        <source>No Cart</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 <context>
-    <name>TheGamesDBScrapper</name>
+    <name>TheGamesDBScraper</name>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="60"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="61"/>
         <source><b>NOTE:</b> If you are deleting this game's information because the game doesn't </source>
-        <translation><b>Remarque :</b> Si vous effacez les informations de ce jeu parce que le jeu</translation>
-    </message>
-    <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="61"/>
-        <source>exist on TheGamesDB and Mupen64Plus-Qt pulled the information for different game, it's </source>
-        <translation>n’est pas dans TheGamesDB et que Mupen64PlusQt vous propose des informations pour un autre jeu,</translation>
+        <translation><b>Remarque :</b> Si vous effacez les informations de ce jeu parce que le jeu </translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="62"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="63"/>
         <source>better to create an account on</source>
         <translation>il est préférable de créer un compte</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="63"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="64"/>
         <source>and add the game so other users can benefit as well.</source>
         <translation>et d’ajouter le jeu afin d’en faire profiter également les autres utilisateurs.</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="65"/>
-        <source>This will cause Mupen64Plus-Qt to not update the information for this game until you </source>
-        <translation>Mupen64Plus-QT ne mettra pas à jour les informations jusqu'à ce que vous</translation>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="62"/>
+        <source>exist on TheGamesDB and <AppName> pulled the information for different game, it's </source>
+        <translation>n’est pas dans TheGamesDB et que <AppName> vous propose des informations pour un autre jeu, </translation>
+    </message>
+    <message>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="66"/>
+        <source>This will cause <AppName> to not update the information for this game until you </source>
+        <translation><AppName> ne mettra pas à jour les informations jusqu'à ce que vous </translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="66"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="67"/>
         <source>force it with "Download/Update Info..."</source>
-        <translation>relanciez le téléchargement/la mise à jour des informations...</translation>
+        <translation>relanciez le "Télécharger/Mettre à jour les infos..."</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="68"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="69"/>
         <source>Delete the current information for</source>
         <translation>Effacer les informations actuelles pour</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="70"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="72"/>
         <source>Delete Game Information</source>
         <translation>Effacer les informations du jeu</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="163"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="168"/>
         <source>Released on: </source>
         <translation>Publié le :</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="164"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="169"/>
         <source>Does this look correct?</source>
         <translation>Ces informations vous semblent-elles correctes ?</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="283"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="288"/>
         <source>Request timed out. Check your network settings.</source>
         <translation>Temps dépassé. Vérifier vos paramètres de connexion.</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="291"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="296"/>
         <source>Continue scraping information?</source>
         <translation>Continuer à récolter des informations ?</translation>
     </message>
     <message>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="294"/>
-        <location filename="../../src/thegamesdbscrapper.cpp" line="296"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="299"/>
+        <location filename="../../src/roms/thegamesdbscraper.cpp" line="301"/>
         <source>Network Error</source>
         <translatorcomment>Erreur réseau</translatorcomment>
-        <translation></translation>
+        <translation>Erreur réseau</translation>
     </message>
 </context>
 </TS>
diff --git a/src/common.cpp b/src/common.cpp
index 1b7eb5b..19deefc 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -30,12 +30,14 @@
  ***/
 
 #include "common.h"
+
 #include "global.h"
 
 #include <QColor>
 #include <QDir>
 #include <QEventLoop>
 #include <QFile>
+#include <QLocale>
 #include <QSize>
 
 #include <quazip/quazip.h>
@@ -75,10 +77,10 @@ QString getDataLocation()
 
 #if QT_VERSION >= 0x050000
     dataDir = QStandardPaths::writableLocation(QStandardPaths::DataLocation)
-                    .replace("Mupen64Plus/Mupen64Plus-Qt","mupen64plus-qt");
+                    .replace(ParentName+"/"+AppName,AppNameLower);
 #else
     dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation)
-                    .remove("data/").replace("Mupen64Plus/Mupen64Plus-Qt","mupen64plus-qt");
+                    .remove("data/").replace(ParentName+"/"+AppName,AppNameLower);
 #endif
 
 #endif
@@ -113,6 +115,18 @@ QColor getColor(QString color, int transparency)
 }
 
 
+QString getDefaultLanguage()
+{
+    QString systemLanguage = QLocale::system().name().left(2);
+
+    //Add other languages here as translations are done
+    if (systemLanguage == "fr")
+        return "FR";
+    else
+        return "EN";
+}
+
+
 int getDefaultWidth(QString id, int imageWidth)
 {
     if (id == "Overview")
@@ -272,6 +286,36 @@ QGraphicsDropShadowEffect *getShadow(bool active)
 }
 
 
+int getTableDataIndexFromName(QString infoName)
+{
+    if (infoName == "fileName")
+        return 0;
+    else if (infoName == "dirName")
+        return 1;
+    else if (infoName == "search")
+        return 2;
+    else if (infoName == "romMD5")
+        return 3;
+    else if (infoName == "zipFile")
+        return 4;
+
+    return 0;
+}
+
+
+int getTextSize()
+{
+    QString size = SETTINGS.value("List/textsize","Medium").toString();
+
+    if (size == "Extra Small") return 7;
+    if (size == "Small")       return 9;
+    if (size == "Medium")      return 10;
+    if (size == "Large")       return 12;
+    if (size == "Extra Large") return 14;
+    return 10;
+}
+
+
 QString getTranslation(QString text)
 {
     if (text == "GoodName")                     return QObject::tr("GoodName");
@@ -294,6 +338,7 @@ QString getTranslation(QString text)
     else if (text == "Publisher")               return QObject::tr("Publisher");
     else if (text == "Developer")               return QObject::tr("Developer");
     else if (text == "Rating")                  return QObject::tr("Rating");
+    else if (text == "Game Cover")              return QObject::tr("Game Cover");
     else if (text == "Unknown ROM")             return QObject::tr("Unknown ROM");
     else if (text == "Requires catalog file")   return QObject::tr("Requires catalog file");
     else if (text == "Not found")               return QObject::tr("Not found");
@@ -342,10 +387,10 @@ bool romSorter(const Rom &firstRom, const Rom &lastRom)
     QString sort, direction;
 
     QString layout = SETTINGS.value("View/layout", "None").toString();
-    if (layout == "Grid View") {
+    if (layout == "grid") {
         sort = SETTINGS.value("Grid/sort", "Filename").toString();
         direction = SETTINGS.value("Grid/sortdirection", "ascending").toString();
-    } else if (layout == "List View") {
+    } else if (layout == "list") {
         sort = SETTINGS.value("List/sort", "Filename").toString();
         direction = SETTINGS.value("List/sortdirection", "ascending").toString();
     } else //just return sort by filename
diff --git a/src/common.h b/src/common.h
index c690cba..079f392 100644
--- a/src/common.h
+++ b/src/common.h
@@ -77,11 +77,14 @@ struct Rom {
 bool romSorter(const Rom &firstRom, const Rom &lastRom);
 int getDefaultWidth(QString id, int imageWidth);
 int getGridSize(QString which);
+int getTableDataIndexFromName(QString infoName);
+int getTextSize();
 
 QByteArray byteswap(QByteArray romData);
 QStringList getZippedFiles(QString completeFileName);
 QByteArray *getZippedRom(QString romFileName, QString zipFile);
 QColor getColor(QString color, int transparency = 255);
+QString getDefaultLanguage();
 QString getTranslation(QString text);
 QGraphicsDropShadowEffect *getShadow(bool active);
 QSize getImageSize(QString view);
diff --git a/src/aboutdialog.cpp b/src/dialogs/aboutdialog.cpp
similarity index 79%
rename from src/aboutdialog.cpp
rename to src/dialogs/aboutdialog.cpp
index 7255ec6..7006b2b 100644
--- a/src/aboutdialog.cpp
+++ b/src/dialogs/aboutdialog.cpp
@@ -30,8 +30,9 @@
  ***/
 
 #include "aboutdialog.h"
-#include "common.h"
-#include "global.h"
+
+#include "../global.h"
+#include "../common.h"
 
 #include <QDialogButtonBox>
 #include <QGridLayout>
@@ -41,13 +42,13 @@
 
 AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent)
 {
-    setWindowTitle(tr("About Mupen64Plus-Qt"));
+    setWindowTitle(tr("About <AppName>").replace("<AppName>",AppName));
     setMinimumSize(600, 300);
 
     aboutLayout = new QGridLayout(this);
 
     icon = new QLabel(this);
-    icon->setPixmap(QPixmap(":/images/mupen64plus.png"));
+    icon->setPixmap(QPixmap(":/images/"+ParentNameLower+".png"));
 
     QFile licenseFile(":/other/LICENSE");
     licenseFile.open(QIODevice::ReadOnly);
@@ -55,16 +56,15 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent)
     license->setReadOnly(true);
     licenseFile.close();
 
-    QString description = "<b>Mupen64Plus-Qt</b><br />" + tr("Version") + " " + getVersion() + "<br /><br />";
-    description += tr("A basic launcher for Mupen64Plus using Qt.");
-    QString mupen64 = "<a href=\"http://www.mupen64plus.org/\">" + tr("Mupen64Plus website") + "</a>";
-    QString github = "<a href=\"https://github.com/dh4/mupen64plus-qt\">" + tr("GitHub repository") + "</a>";
+    QString description = "<b>"+AppName+"</b><br />" + tr("Version") + " " + getVersion() + "<br /><br />";
+    description += Description;
 
     descriptionLabel = new QLabel(description, this);
-    mupen64Link = new QLabel(mupen64, this);
-    githubLink = new QLabel(github, this);
+    copyrightLabel = new QLabel(Copyright, this);
+    websiteLink = new QLabel(Website, this);
+    githubLink = new QLabel(GitHub, this);
 
-    mupen64Link->setOpenExternalLinks(true);
+    websiteLink->setOpenExternalLinks(true);
     githubLink->setOpenExternalLinks(true);
 
     buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this);
@@ -72,7 +72,8 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent)
     aboutLayout->addWidget(icon, 0, 0, 4, 1);
     aboutLayout->addWidget(descriptionLabel, 0, 1);
     aboutLayout->addWidget(license, 1, 1);
-    aboutLayout->addWidget(mupen64Link, 3, 1);
+    aboutLayout->addWidget(copyrightLabel, 2, 1);
+    aboutLayout->addWidget(websiteLink, 3, 1);
     aboutLayout->addWidget(githubLink, 4, 1);
     aboutLayout->addWidget(buttonBox, 5, 1);
     aboutLayout->setColumnStretch(1, 1);
diff --git a/src/aboutdialog.h b/src/dialogs/aboutdialog.h
similarity index 97%
rename from src/aboutdialog.h
rename to src/dialogs/aboutdialog.h
index 74684f0..fb378ba 100644
--- a/src/aboutdialog.h
+++ b/src/dialogs/aboutdialog.h
@@ -50,9 +50,10 @@ public:
 private:
     QDialogButtonBox *buttonBox;
     QGridLayout *aboutLayout;
+    QLabel *copyrightLabel;
     QLabel *descriptionLabel;
     QLabel *githubLink;
-    QLabel *mupen64Link;
+    QLabel *websiteLink;
     QLabel *icon;
     QPlainTextEdit *license;
 };
diff --git a/src/configeditor.cpp b/src/dialogs/configeditor.cpp
similarity index 97%
rename from src/configeditor.cpp
rename to src/dialogs/configeditor.cpp
index f302355..04fb850 100644
--- a/src/configeditor.cpp
+++ b/src/dialogs/configeditor.cpp
@@ -30,7 +30,8 @@
  ***/
 
 #include "configeditor.h"
-#include "global.h"
+
+#include "../global.h"
 
 #include <QDialogButtonBox>
 #include <QGridLayout>
@@ -45,7 +46,7 @@ ConfigEditor::ConfigEditor(QString configFile, QWidget *parent) : QDialog(parent
 {
     config.setFileName(configFile);
 
-    setWindowTitle(tr("Mupen64Plus Config Editor"));
+    setWindowTitle(tr("<ParentName> Config Editor").replace("<ParentName>",ParentName));
     setMinimumSize(600, 400);
 
     editorLayout = new QGridLayout(this);
diff --git a/src/configeditor.h b/src/dialogs/configeditor.h
similarity index 100%
rename from src/configeditor.h
rename to src/dialogs/configeditor.h
diff --git a/src/downloaddialog.cpp b/src/dialogs/downloaddialog.cpp
similarity index 94%
rename from src/downloaddialog.cpp
rename to src/dialogs/downloaddialog.cpp
index e5ed54e..2a8bc51 100644
--- a/src/downloaddialog.cpp
+++ b/src/dialogs/downloaddialog.cpp
@@ -30,8 +30,10 @@
  ***/
 
 #include "downloaddialog.h"
-#include "common.h"
-#include "thegamesdbscrapper.h"
+
+#include "../common.h"
+
+#include "../roms/thegamesdbscraper.h"
 
 #include <QDialogButtonBox>
 #include <QGridLayout>
@@ -88,6 +90,6 @@ void DownloadDialog::runDownloader()
 {
     close();
 
-    scrapper = new TheGamesDBScrapper(parent, true);
-    scrapper->downloadGameInfo(romMD5, gameNameField->text(), gameIDField->text());
+    scraper = new TheGamesDBScraper(parent, true);
+    scraper->downloadGameInfo(romMD5, gameNameField->text(), gameIDField->text());
 }
diff --git a/src/downloaddialog.h b/src/dialogs/downloaddialog.h
similarity index 97%
copy from src/downloaddialog.h
copy to src/dialogs/downloaddialog.h
index cbebb7f..31bbe4c 100644
--- a/src/downloaddialog.h
+++ b/src/dialogs/downloaddialog.h
@@ -38,7 +38,7 @@ class QDialogButtonBox;
 class QGridLayout;
 class QLabel;
 class QLineEdit;
-class TheGamesDBScrapper;
+class TheGamesDBScraper;
 
 
 class DownloadDialog : public QDialog
@@ -58,7 +58,7 @@ private:
     QString romMD5;
     QWidget *parent;
 
-    TheGamesDBScrapper *scrapper;
+    TheGamesDBScraper *scraper;
 
 private slots:
     void runDownloader();
diff --git a/src/gamesettingsdialog.cpp b/src/dialogs/gamesettingsdialog.cpp
similarity index 99%
rename from src/gamesettingsdialog.cpp
rename to src/dialogs/gamesettingsdialog.cpp
index b5f9fa2..b1dca12 100644
--- a/src/gamesettingsdialog.cpp
+++ b/src/dialogs/gamesettingsdialog.cpp
@@ -31,7 +31,8 @@
 
 #include "gamesettingsdialog.h"
 #include "ui_gamesettingsdialog.h"
-#include "global.h"
+
+#include "../global.h"
 
 #include <QFileDialog>
 
diff --git a/src/gamesettingsdialog.h b/src/dialogs/gamesettingsdialog.h
similarity index 100%
rename from src/gamesettingsdialog.h
rename to src/dialogs/gamesettingsdialog.h
diff --git a/src/gamesettingsdialog.ui b/src/dialogs/gamesettingsdialog.ui
similarity index 100%
rename from src/gamesettingsdialog.ui
rename to src/dialogs/gamesettingsdialog.ui
diff --git a/src/logdialog.cpp b/src/dialogs/logdialog.cpp
similarity index 96%
rename from src/logdialog.cpp
rename to src/dialogs/logdialog.cpp
index 78bf29a..625488d 100644
--- a/src/logdialog.cpp
+++ b/src/dialogs/logdialog.cpp
@@ -30,7 +30,8 @@
  ***/
 
 #include "logdialog.h"
-#include "global.h"
+
+#include "../global.h"
 
 #include <QDialogButtonBox>
 #include <QGridLayout>
@@ -43,7 +44,7 @@
 
 LogDialog::LogDialog(QString lastOutput, QWidget *parent) : QDialog(parent)
 {
-    setWindowTitle(tr("Mupen64Plus Log"));
+    setWindowTitle(tr("<ParentName> Log").replace("<ParentName>",ParentName));
     setMinimumSize(600, 400);
 
     logLayout = new QGridLayout(this);
diff --git a/src/logdialog.h b/src/dialogs/logdialog.h
similarity index 100%
rename from src/logdialog.h
rename to src/dialogs/logdialog.h
diff --git a/src/settingsdialog.cpp b/src/dialogs/settingsdialog.cpp
similarity index 88%
rename from src/settingsdialog.cpp
rename to src/dialogs/settingsdialog.cpp
index c3f7261..510e46f 100644
--- a/src/settingsdialog.cpp
+++ b/src/dialogs/settingsdialog.cpp
@@ -31,8 +31,9 @@
 
 #include "settingsdialog.h"
 #include "ui_settingsdialog.h"
-#include "common.h"
-#include "global.h"
+
+#include "../global.h"
+#include "../common.h"
 
 #include <QDesktopWidget>
 #include <QFileDialog>
@@ -47,7 +48,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
 
 
     //Populate Paths tab
-    ui->mupen64Path->setText(SETTINGS.value("Paths/mupen64plus", "").toString());
+    ui->emulatorPath->setText(SETTINGS.value("Paths/mupen64plus", "").toString());
     ui->pluginPath->setText(SETTINGS.value("Paths/plugins", "").toString());
     ui->dataPath->setText(SETTINGS.value("Paths/data", "").toString());
     ui->configPath->setText(SETTINGS.value("Paths/config", "").toString());
@@ -57,7 +58,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
     foreach (QString directory, romDirectories)
         ui->romList->addItem(directory);
 
-    connect(ui->mupen64Button, SIGNAL(clicked()), this, SLOT(browseMupen64()));
+    connect(ui->emulatorButton, SIGNAL(clicked()), this, SLOT(browseEmulator()));
     connect(ui->pluginButton, SIGNAL(clicked()), this, SLOT(browsePlugin()));
     connect(ui->dataButton, SIGNAL(clicked()), this, SLOT(browseData()));
     connect(ui->configButton, SIGNAL(clicked()), this, SLOT(browseConfig()));
@@ -204,11 +205,12 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
 
 
     //Populate Grid tab
-    int gridSizeIndex = 0, activeIndex = 0, inactiveIndex = 0, labelColorIndex = 0;
+    int gridSizeIndex = 0, activeIndex = 0, inactiveIndex = 0, labelColorIndex = 0, bgThemeIndex = 0;
     QString currentGridSize = SETTINGS.value("Grid/imagesize","Medium").toString();
     QString currentActiveColor = SETTINGS.value("Grid/activecolor","Cyan").toString();
     QString currentInactiveColor = SETTINGS.value("Grid/inactivecolor","Black").toString();
     QString currentLabelColor = SETTINGS.value("Grid/labelcolor","White").toString();
+    QString currentBGTheme = SETTINGS.value("Grid/theme","Normal").toString();
 
     QList<QStringList> colors;
     colors << (QStringList() << tr("Black")      << "Black")
@@ -225,6 +227,11 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
            << (QStringList() << tr("Yellow")     << "Yellow")
            << (QStringList() << tr("Brown")      << "Brown");
 
+    QList<QStringList> bgThemes;
+    bgThemes << (QStringList() << tr("Light")   << "Light")
+             << (QStringList() << tr("Normal")  << "Normal")
+             << (QStringList() << tr("Dark")    << "Dark");
+
     for (int i = 0; i < sizes.length(); i++)
     {
         ui->gridSizeBox->insertItem(i, sizes.at(i).at(0), sizes.at(i).at(1));
@@ -236,6 +243,12 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
     int gridColumnCount = SETTINGS.value("Grid/columncount","4").toInt();
     ui->columnCountBox->setValue(gridColumnCount);
 
+    if (SETTINGS.value("Grid/autocolumns", "true").toString() == "true") {
+        toggleGridColumn(true);
+        ui->autoColumnOption->setChecked(true);
+    } else
+        toggleGridColumn(false);
+
     for (int i = 0; i < colors.length(); i++)
     {
         ui->shadowActiveBox->insertItem(i, colors.at(i).at(0), colors.at(i).at(1));
@@ -266,18 +279,36 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
     } else
         toggleLabel(false);
 
-    ui->backgroundPath->setText(SETTINGS.value("Grid/background", "").toString());
+    for (int i = 0; i < bgThemes.length(); i++)
+    {
+        ui->bgThemeBox->insertItem(i, bgThemes.at(i).at(0), bgThemes.at(i).at(1));
+        if (currentBGTheme == bgThemes.at(i).at(1))
+            bgThemeIndex = i;
+    }
+    if (bgThemeIndex >= 0) ui->bgThemeBox->setCurrentIndex(bgThemeIndex);
+
+    QString imagePath = SETTINGS.value("Grid/background", "").toString();
+    ui->backgroundPath->setText(imagePath);
+    hideBGTheme(imagePath);
 
     if (SETTINGS.value("Grid/sortdirection", "ascending").toString() == "descending")
         ui->gridDescendingOption->setChecked(true);
 
+    connect(ui->autoColumnOption, SIGNAL(toggled(bool)), this, SLOT(toggleGridColumn(bool)));
+    connect(ui->backgroundPath, SIGNAL(textChanged(QString)), this, SLOT(hideBGTheme(QString)));
     connect(ui->backgroundButton, SIGNAL(clicked()), this, SLOT(browseBackground()));
     connect(ui->labelOption, SIGNAL(toggled(bool)), this, SLOT(toggleLabel(bool)));
 
 
     //Populate List tab
-    int listSizeIndex = 0;
+    int listSizeIndex = 0, listTextIndex = 0, listThemeIndex = 0;
     QString currentListSize = SETTINGS.value("List/imagesize","Medium").toString();
+    QString currentListText = SETTINGS.value("List/textsize","Medium").toString();
+    QString currentListTheme = SETTINGS.value("List/theme","Light").toString();
+
+    QList<QStringList> themes;
+    themes << (QStringList() << tr("Light") << "Light")
+           << (QStringList() << tr("Dark")  << "Dark");
 
     listCoverEnable << ui->listSizeLabel
                     << ui->listSizeBox;
@@ -296,8 +327,20 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
         ui->listSizeBox->insertItem(i, sizes.at(i).at(0), sizes.at(i).at(1));
         if (currentListSize == sizes.at(i).at(1))
             listSizeIndex = i;
+        ui->listTextBox->insertItem(i, sizes.at(i).at(0), sizes.at(i).at(1));
+        if (currentListText == sizes.at(i).at(1))
+            listTextIndex = i;
     }
     if (listSizeIndex >= 0) ui->listSizeBox->setCurrentIndex(listSizeIndex);
+    if (listTextIndex >= 0) ui->listTextBox->setCurrentIndex(listTextIndex);
+
+    for (int i = 0; i < themes.length(); i++)
+    {
+        ui->listThemeBox->insertItem(i, themes.at(i).at(0), themes.at(i).at(1));
+        if (currentListTheme == themes.at(i).at(1))
+            listThemeIndex = i;
+    }
+    if (listThemeIndex >= 0) ui->listThemeBox->setCurrentIndex(listThemeIndex);
 
     if (SETTINGS.value("List/sortdirection", "ascending").toString() == "descending")
         ui->listDescendingOption->setChecked(true);
@@ -312,7 +355,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, int activeTab) : QDialog(parent)
 
     //Populate Other tab
     int languageIndex = 0;
-    QString currentLanguage = SETTINGS.value("language", "EN").toString();
+    QString currentLanguage = SETTINGS.value("language", getDefaultLanguage()).toString();
 
     QList<QStringList> languages;
     languages << (QStringList() << QString::fromUtf8("English")  << "EN")
@@ -394,16 +437,17 @@ void SettingsDialog::browseBackground()
 }
 
 
-void SettingsDialog::browseMupen64()
+void SettingsDialog::browseEmulator()
 {
-    QString path = QFileDialog::getOpenFileName(this, tr("Mupen64Plus Executable"));
+    QString path = QFileDialog::getOpenFileName(this, tr("<ParentName> Executable")
+                                                .replace("<ParentName>",ParentName));
     if (path != "")
-        ui->mupen64Path->setText(path);
+        ui->emulatorPath->setText(path);
 
 #ifdef Q_OS_OSX
     //Allow OSX users to just select the .app directory and auto-populate for them
     if (path.right(15) == "mupen64plus.app") {
-        ui->mupen64Path->setText(path+"/Contents/MacOS/mupen64plus");
+        ui->emulatorPath->setText(path+"/Contents/MacOS/mupen64plus");
         ui->pluginPath->setText(path+"/Contents/MacOS");
         ui->dataPath->setText(path+"/Contents/Resources");
     }
@@ -449,7 +493,7 @@ void SettingsDialog::editSettings()
 
 
     //Paths tab
-    SETTINGS.setValue("Paths/mupen64plus", ui->mupen64Path->text());
+    SETTINGS.setValue("Paths/mupen64plus", ui->emulatorPath->text());
     SETTINGS.setValue("Paths/plugins", ui->pluginPath->text());
     SETTINGS.setValue("Paths/data", ui->dataPath->text());
     SETTINGS.setValue("Paths/config", ui->configPath->text());
@@ -513,8 +557,15 @@ void SettingsDialog::editSettings()
     //Grid tab
     SETTINGS.setValue("Grid/imagesize", ui->gridSizeBox->itemData(ui->gridSizeBox->currentIndex()));
     SETTINGS.setValue("Grid/columncount", ui->columnCountBox->value());
+
+    if (ui->autoColumnOption->isChecked())
+        SETTINGS.setValue("Grid/autocolumns", true);
+    else
+        SETTINGS.setValue("Grid/autocolumns", "");
+
     SETTINGS.setValue("Grid/inactivecolor", ui->shadowInactiveBox->itemData(ui->shadowInactiveBox->currentIndex()));
     SETTINGS.setValue("Grid/activecolor", ui->shadowActiveBox->itemData(ui->shadowActiveBox->currentIndex()));
+    SETTINGS.setValue("Grid/theme", ui->bgThemeBox->itemData(ui->bgThemeBox->currentIndex()));
     SETTINGS.setValue("Grid/background", ui->backgroundPath->text());
 
     if (ui->labelOption->isChecked())
@@ -551,6 +602,8 @@ void SettingsDialog::editSettings()
         SETTINGS.setValue("List/displaycover", "");
 
     SETTINGS.setValue("List/imagesize", ui->listSizeBox->itemData(ui->listSizeBox->currentIndex()));
+    SETTINGS.setValue("List/textsize", ui->listTextBox->itemData(ui->listTextBox->currentIndex()));
+    SETTINGS.setValue("List/theme", ui->listThemeBox->itemData(ui->listThemeBox->currentIndex()));
     SETTINGS.setValue("List/sort", ui->listSortBox->itemData(ui->listSortBox->currentIndex()));
 
     if (ui->listDescendingOption->isChecked())
@@ -572,6 +625,18 @@ void SettingsDialog::editSettings()
 }
 
 
+void SettingsDialog::hideBGTheme(QString imagePath)
+{
+    if (imagePath == "") {
+        ui->bgThemeLabel->setEnabled(true);
+        ui->bgThemeBox->setEnabled(true);
+    } else {
+        ui->bgThemeLabel->setEnabled(false);
+        ui->bgThemeBox->setEnabled(false);
+    }
+}
+
+
 void SettingsDialog::listAddColumn()
 {
     addColumn(ui->listCurrentList, ui->listAvailableList);
@@ -844,6 +909,15 @@ void SettingsDialog::toggleDownload(bool active)
 }
 
 
+void SettingsDialog::toggleGridColumn(bool active)
+{
+    if (active)
+        ui->columnCountBox->setEnabled(false);
+    else
+        ui->columnCountBox->setEnabled(true);
+}
+
+
 void SettingsDialog::toggleLabel(bool active)
 {
     foreach (QWidget *next, labelEnable)
@@ -866,7 +940,7 @@ void SettingsDialog::updateLanguageInfo()
 
     QTranslator translator;
     QString language = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString().toLower();
-    QString resource = ":/locale/mupen64plus-qt_"+language+".qm";
+    QString resource = ":/locale/"+AppNameLower+"_"+language+".qm";
     if (QFileInfo(resource).exists()) {
         translator.load(resource);
         ui->languageInfoLabel->setText(translator.translate("SettingsDialog", sourceText));
diff --git a/src/settingsdialog.h b/src/dialogs/settingsdialog.h
similarity index 96%
rename from src/settingsdialog.h
rename to src/dialogs/settingsdialog.h
index b50b567..64d0522 100644
--- a/src/settingsdialog.h
+++ b/src/dialogs/settingsdialog.h
@@ -69,11 +69,12 @@ private slots:
     void addColumn(QListWidget *currentList, QListWidget *availableList);
     void addRomDirectory();
     void browseBackground();
-    void browseMupen64();
+    void browseEmulator();
     void browsePlugin();
     void browseData();
     void browseConfig();
     void editSettings();
+    void hideBGTheme(QString imagePath);
     void listAddColumn();
     void listRemoveColumn();
     void listSortDown();
@@ -88,6 +89,7 @@ private slots:
     void tableSortDown();
     void tableSortUp();
     void toggleDownload(bool active);
+    void toggleGridColumn(bool active);
     void toggleLabel(bool active);
     void toggleListCover(bool active);
     void updateLanguageInfo();
diff --git a/src/settingsdialog.ui b/src/dialogs/settingsdialog.ui
similarity index 94%
rename from src/settingsdialog.ui
rename to src/dialogs/settingsdialog.ui
index 4a2037e..3da36f0 100644
--- a/src/settingsdialog.ui
+++ b/src/dialogs/settingsdialog.ui
@@ -7,13 +7,13 @@
     <x>0</x>
     <y>0</y>
     <width>600</width>
-    <height>550</height>
+    <height>600</height>
    </rect>
   </property>
   <property name="minimumSize">
    <size>
     <width>550</width>
-    <height>500</height>
+    <height>575</height>
    </size>
   </property>
   <property name="windowTitle">
@@ -36,7 +36,7 @@
       <enum>QTabWidget::Rounded</enum>
      </property>
      <property name="currentIndex">
-      <number>4</number>
+      <number>0</number>
      </property>
      <widget class="QWidget" name="pathsWidget">
       <attribute name="title">
@@ -82,7 +82,7 @@
              </widget>
             </item>
             <item row="0" column="2">
-             <widget class="QPushButton" name="mupen64Button">
+             <widget class="QPushButton" name="emulatorButton">
               <property name="text">
                <string>Browse...</string>
               </property>
@@ -103,14 +103,14 @@
              </widget>
             </item>
             <item row="0" column="0">
-             <widget class="QLabel" name="mupen64PathLabel">
+             <widget class="QLabel" name="emulatorPathLabel">
               <property name="text">
                <string>Mupen64Plus executable: </string>
               </property>
              </widget>
             </item>
             <item row="0" column="1">
-             <widget class="QLineEdit" name="mupen64Path"/>
+             <widget class="QLineEdit" name="emulatorPath"/>
             </item>
             <item row="2" column="0">
              <widget class="QLabel" name="dataPathLabel">
@@ -706,38 +706,38 @@
          <layout class="QGridLayout" name="gridLayout6">
           <item row="2" column="0">
            <layout class="QGridLayout" name="gridOtherLayout" columnstretch="0,1,1,0" columnminimumwidth="150,0,0,0">
-            <item row="0" column="3">
+            <item row="1" column="3">
              <widget class="QPushButton" name="backgroundButton">
               <property name="text">
                <string>Browse...</string>
               </property>
              </widget>
             </item>
-            <item row="0" column="0">
+            <item row="1" column="0">
              <widget class="QLabel" name="backgroundLabel">
               <property name="text">
                <string>Custom Background:</string>
               </property>
              </widget>
             </item>
-            <item row="1" column="0">
+            <item row="2" column="0">
              <widget class="QLabel" name="gridSortLabel">
               <property name="text">
                <string>Sorting:</string>
               </property>
              </widget>
             </item>
-            <item row="0" column="1" colspan="2">
+            <item row="1" column="1" colspan="2">
              <widget class="QLineEdit" name="backgroundPath"/>
             </item>
-            <item row="1" column="2" colspan="2">
+            <item row="2" column="2" colspan="2">
              <widget class="QCheckBox" name="gridDescendingOption">
               <property name="text">
                <string>Descending</string>
               </property>
              </widget>
             </item>
-            <item row="1" column="1">
+            <item row="2" column="1">
              <widget class="QComboBox" name="gridSortBox">
               <property name="maximumSize">
                <size>
@@ -747,6 +747,16 @@
               </property>
              </widget>
             </item>
+            <item row="0" column="0">
+             <widget class="QLabel" name="bgThemeLabel">
+              <property name="text">
+               <string>Background:</string>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="1">
+             <widget class="QComboBox" name="bgThemeBox"/>
+            </item>
            </layout>
           </item>
          </layout>
@@ -772,7 +782,7 @@
            </spacer>
           </item>
           <item row="0" column="0">
-           <layout class="QGridLayout" name="gridImageLayout" rowstretch="0,0,0,0" columnstretch="0,0" columnminimumwidth="150,0">
+           <layout class="QGridLayout" name="gridImageLayout" rowstretch="0,0,0,0" columnstretch="0,0,0" columnminimumwidth="150,0,0">
             <property name="leftMargin">
              <number>0</number>
             </property>
@@ -862,6 +872,13 @@
               </property>
              </widget>
             </item>
+            <item row="1" column="2">
+             <widget class="QCheckBox" name="autoColumnOption">
+              <property name="text">
+               <string>Adjust Automatically</string>
+              </property>
+             </widget>
+            </item>
            </layout>
           </item>
          </layout>
@@ -1021,21 +1038,21 @@
            </property>
           </widget>
          </item>
-         <item row="4" column="3">
+         <item row="6" column="3">
           <widget class="QCheckBox" name="listDescendingOption">
            <property name="text">
             <string>Descending</string>
            </property>
           </widget>
          </item>
-         <item row="4" column="0">
+         <item row="6" column="0">
           <widget class="QLabel" name="listSortLabel">
            <property name="text">
             <string>Sorting:</string>
            </property>
           </widget>
          </item>
-         <item row="4" column="1" colspan="2">
+         <item row="6" column="1" colspan="2">
           <widget class="QComboBox" name="listSortBox">
            <property name="maximumSize">
             <size>
@@ -1045,6 +1062,9 @@
            </property>
           </widget>
          </item>
+         <item row="3" column="1" colspan="2">
+          <widget class="QComboBox" name="listSizeBox"/>
+         </item>
          <item row="2" column="3" colspan="2">
           <widget class="QCheckBox" name="listHeaderOption">
            <property name="text">
@@ -1059,8 +1079,25 @@
            </property>
           </widget>
          </item>
-         <item row="3" column="1" colspan="2">
-          <widget class="QComboBox" name="listSizeBox"/>
+         <item row="4" column="0">
+          <widget class="QLabel" name="listTextLabel">
+           <property name="text">
+            <string>Text Size:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="0">
+          <widget class="QLabel" name="listThemeLabel">
+           <property name="text">
+            <string>Theme:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1" colspan="2">
+          <widget class="QComboBox" name="listTextBox"/>
+         </item>
+         <item row="5" column="1" colspan="2">
+          <widget class="QComboBox" name="listThemeBox"/>
          </item>
         </layout>
        </item>
@@ -1165,7 +1202,7 @@
          <item row="2" column="1" colspan="2">
           <widget class="QLineEdit" name="parametersLine">
            <property name="toolTip">
-            <string><html><head/><body><p>Use to pass additional parameters to Mupen64Plus (cheats, etc.). See <a href="https://code.google.com/p/mupen64plus/wiki/UIConsoleUsage"><span style=" text-decoration: underline; color:#0057ae;">https://code.google.com/p/mupen64plus/wiki/UIConsoleUsage</span></a> for more information.</p></body></html></string>
+            <string><html><head/><body><p>Use to pass additional parameters to Mupen64Plus (cheats, etc.). See <a href="http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage"><span style=" text-decoration: underline; color:#0057ae;">http://mupen64plus.org/wiki/index.php?title=UIConsoleUsage</span></a> for more information.</p></body></html></string>
            </property>
           </widget>
          </item>
@@ -1218,11 +1255,11 @@
  </widget>
  <tabstops>
   <tabstop>tabWidget</tabstop>
-  <tabstop>mupen64Path</tabstop>
+  <tabstop>emulatorPath</tabstop>
   <tabstop>pluginPath</tabstop>
   <tabstop>dataPath</tabstop>
   <tabstop>configPath</tabstop>
-  <tabstop>mupen64Button</tabstop>
+  <tabstop>emulatorButton</tabstop>
   <tabstop>pluginButton</tabstop>
   <tabstop>dataButton</tabstop>
   <tabstop>configButton</tabstop>
@@ -1249,11 +1286,13 @@
   <tabstop>tableStretchOption</tabstop>
   <tabstop>gridSizeBox</tabstop>
   <tabstop>columnCountBox</tabstop>
+  <tabstop>autoColumnOption</tabstop>
   <tabstop>shadowInactiveBox</tabstop>
   <tabstop>shadowActiveBox</tabstop>
   <tabstop>labelOption</tabstop>
   <tabstop>labelTextBox</tabstop>
   <tabstop>labelColorBox</tabstop>
+  <tabstop>bgThemeBox</tabstop>
   <tabstop>backgroundPath</tabstop>
   <tabstop>backgroundButton</tabstop>
   <tabstop>gridSortBox</tabstop>
@@ -1267,11 +1306,14 @@
   <tabstop>listCoverOption</tabstop>
   <tabstop>listHeaderOption</tabstop>
   <tabstop>listSizeBox</tabstop>
+  <tabstop>listTextBox</tabstop>
+  <tabstop>listThemeBox</tabstop>
   <tabstop>listSortBox</tabstop>
   <tabstop>listDescendingOption</tabstop>
   <tabstop>downloadOption</tabstop>
   <tabstop>saveOption</tabstop>
   <tabstop>parametersLine</tabstop>
+  <tabstop>languageBox</tabstop>
  </tabstops>
  <resources/>
  <connections/>
diff --git a/src/emulatorhandler.cpp b/src/emulation/emulatorhandler.cpp
similarity index 87%
rename from src/emulatorhandler.cpp
rename to src/emulation/emulatorhandler.cpp
index 86c13b1..40dbef8 100644
--- a/src/emulatorhandler.cpp
+++ b/src/emulation/emulatorhandler.cpp
@@ -30,8 +30,9 @@
  ***/
 
 #include "emulatorhandler.h"
-#include "common.h"
-#include "global.h"
+
+#include "../global.h"
+#include "../common.h"
 
 #include <QDir>
 #include <QFile>
@@ -54,7 +55,8 @@ void EmulatorHandler::checkStatus(int status)
     if (status > 0) {
         QMessageBox exitDialog(parent);
         exitDialog.setWindowTitle(tr("Warning"));
-        exitDialog.setText(tr("Mupen64Plus quit unexpectedly. Check the log for more information."));
+        exitDialog.setText(tr("<ParentName> quit unexpectedly. Check the log for more information.")
+                           .replace("<ParentName>",ParentName));
         exitDialog.setIcon(QMessageBox::Warning);
         exitDialog.addButton(QMessageBox::Ok);
         exitDialog.addButton(tr("View Log..."), QMessageBox::HelpRole);
@@ -67,7 +69,7 @@ void EmulatorHandler::checkStatus(int status)
 
 void EmulatorHandler::cleanTemp()
 {
-    QFile::remove(QDir::tempPath() + "/mupen64plus-qt/temp.z64");
+    QFile::remove(QDir::tempPath() + "/"+AppNameLower+"/temp.z64");
 }
 
 
@@ -118,7 +120,7 @@ QStringList EmulatorHandler::parseArgString(QString argString)
 
 void EmulatorHandler::readOutput()
 {
-    lastOutput = emulatorProc->readAllStandardOutput();
+    lastOutput.append(emulatorProc->readAllStandardOutput());
 }
 
 
@@ -138,7 +140,7 @@ void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zi
         romData.append(zippedFile.readAll());
         zippedFile.close();
 
-        QString tempDir = QDir::tempPath() + "/mupen64plus-qt";
+        QString tempDir = QDir::tempPath() + "/"+AppNameLower;
         QDir().mkdir(tempDir);
         completeRomPath = tempDir + "/temp.n64";
 
@@ -149,7 +151,7 @@ void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zi
     } else
         completeRomPath = romDir.absoluteFilePath(romFileName);
 
-    QString mupen64Path = SETTINGS.value("Paths/mupen64plus", "").toString();
+    QString emulatorPath = SETTINGS.value("Paths/mupen64plus", "").toString();
     QString dataPath = SETTINGS.value("Paths/data", "").toString();
     QString configPath = SETTINGS.value("Paths/config", "").toString();
     QString pluginPath = SETTINGS.value("Paths/plugins", "").toString();
@@ -166,7 +168,7 @@ void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zi
     QString inputPlugin = SETTINGS.value("Plugins/input", "").toString();
     QString rspPlugin = SETTINGS.value("Plugins/rsp", "").toString();
 
-    QFile mupen64File(mupen64Path);
+    QFile emulatorFile(emulatorPath);
     QFile romFile(completeRomPath);
 
     QString gameVideoPlugin = SETTINGS.value(romFileName+"/video", "").toString();
@@ -179,8 +181,9 @@ void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zi
 
 
     //Sanity checks
-    if(!mupen64File.exists() || QFileInfo(mupen64File).isDir() || !QFileInfo(mupen64File).isExecutable()) {
-        QMessageBox::warning(parent, tr("Warning"), tr("Mupen64Plus executable not found."));
+    if(!emulatorFile.exists() || QFileInfo(emulatorFile).isDir() || !QFileInfo(emulatorFile).isExecutable()) {
+        QMessageBox::warning(parent, tr("Warning"),
+                             tr("<ParentName> executable not found.").replace("<ParentName>",ParentName));
         if (zip) cleanTemp();
         return;
     }
@@ -277,9 +280,26 @@ void EmulatorHandler::startEmulator(QDir romDir, QString romFileName, QString zi
         emulatorProc->setProcessEnvironment(emulatorEnv);
     }
 
-    emulatorProc->setWorkingDirectory(QFileInfo(mupen64File).dir().canonicalPath());
+    emulatorProc->setWorkingDirectory(QFileInfo(emulatorFile).dir().canonicalPath());
     emulatorProc->setProcessChannelMode(QProcess::MergedChannels);
-    emulatorProc->start(mupen64Path, args);
+    emulatorProc->start(emulatorPath, args);
+
+    //Add command to log
+    QString executable = emulatorPath;
+    if (executable.contains(" "))
+        executable = '"' + executable + '"';
+
+    QString argString;
+    foreach(QString arg, args)
+    {
+        if (arg.contains(" "))
+            argString += " \"" + arg + "\"";
+        else
+            argString += " " + arg;
+    }
+
+    lastOutput = executable + argString + "\n\n";
+
 
     emit started();
 }
diff --git a/src/emulatorhandler.h b/src/emulation/emulatorhandler.h
similarity index 100%
copy from src/emulatorhandler.h
copy to src/emulation/emulatorhandler.h
diff --git a/src/global.h b/src/global.h
index 1f0bb6e..1ff0935 100644
--- a/src/global.h
+++ b/src/global.h
@@ -32,17 +32,32 @@
 #ifndef GLOBAL_H
 #define GLOBAL_H
 
+#include <QObject>
 #include <QSettings>
 
 
-#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD)
-    #define OS_LINUX_OR_BSD
-#endif
+const QString AppName           = "Mupen64Plus-Qt";
+const QString AppNameLower      = "mupen64plus-qt";
+const QString ParentName        = "Mupen64Plus";
+const QString ParentNameLower   = "mupen64plus";
+
+const QString Description = QObject::tr("A basic launcher for <ParentName> using Qt.").replace("<ParentName>",ParentName);
+const QString Copyright = "";
+const QString Website = "<a href=\"http://www.mupen64plus.org/\">"
+        + QObject::tr("<ParentName> website").replace("<ParentName>",ParentName)
+        + "</a>";
+const QString GitHub = "<a href=\"https://github.com/dh4/mupen64plus-qt\">"
+        + QObject::tr("GitHub repository")
+        + "</a>";
 
 #ifdef Q_OS_WIN
-    #define SETTINGS QSettings("mupen64plus-qt.ini", QSettings::IniFormat)
+    #define SETTINGS    QSettings(AppNameLower+".ini", QSettings::IniFormat)
 #else
-    #define SETTINGS QSettings("mupen64plus", "mupen64plus-qt")
+    #define SETTINGS    QSettings(ParentNameLower, AppNameLower)
+#endif
+
+#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD)
+    #define OS_LINUX_OR_BSD
 #endif
 
 #endif // GLOBAL_H
diff --git a/src/main.cpp b/src/main.cpp
index ea24ef1..95b80bf 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,6 +30,7 @@
  ***/
 
 #include "global.h"
+#include "common.h"
 #include "mainwindow.h"
 
 #include <QApplication>
@@ -43,18 +44,18 @@ int main(int argc, char *argv[])
     QApplication application(argc, argv);
 
     QTranslator translator;
-    QString language = SETTINGS.value("language", "EN").toString();
+    QString language = SETTINGS.value("language", getDefaultLanguage()).toString();
 
     if (language != "EN") {
-        QString resource = ":/locale/mupen64plus-qt_"+language.toLower()+".qm";
+        QString resource = ":/locale/"+AppNameLower+"_"+language.toLower()+".qm";
         if (QFileInfo(resource).exists()) {
             translator.load(resource);
             application.installTranslator(&translator);
         }
     }
 
-    QCoreApplication::setOrganizationName("Mupen64Plus");
-    QCoreApplication::setApplicationName("Mupen64Plus-Qt");
+    QCoreApplication::setOrganizationName(ParentName);
+    QCoreApplication::setApplicationName(AppName);
 
     MainWindow window;
 
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index a26851f..251a2e3 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -30,32 +30,35 @@
  ***/
 
 #include "mainwindow.h"
-#include "aboutdialog.h"
-#include "clickablewidget.h"
-#include "common.h"
-#include "configeditor.h"
-#include "downloaddialog.h"
-#include "emulatorhandler.h"
-#include "gamesettingsdialog.h"
+
 #include "global.h"
-#include "logdialog.h"
-#include "romcollection.h"
-#include "settingsdialog.h"
-#include "thegamesdbscrapper.h"
-#include "treewidgetitem.h"
+#include "common.h"
+
+#include "dialogs/aboutdialog.h"
+#include "dialogs/configeditor.h"
+#include "dialogs/downloaddialog.h"
+#include "dialogs/gamesettingsdialog.h"
+#include "dialogs/logdialog.h"
+#include "dialogs/settingsdialog.h"
+
+#include "emulation/emulatorhandler.h"
+
+#include "roms/romcollection.h"
+#include "roms/thegamesdbscraper.h"
+
+#include "views/gridview.h"
+#include "views/listview.h"
+#include "views/tableview.h"
 
 #include <QCloseEvent>
 #include <QDesktopServices>
 #include <QDialogButtonBox>
 #include <QFileDialog>
 #include <QGridLayout>
-#include <QHeaderView>
 #include <QLabel>
 #include <QListWidget>
 #include <QMenuBar>
 #include <QMessageBox>
-#include <QScrollArea>
-#include <QScrollBar>
 #include <QTimer>
 #include <QVBoxLayout>
 
@@ -66,26 +69,29 @@
 
 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 {
-    setWindowTitle(tr("Mupen64Plus-Qt"));
-    setWindowIcon(QIcon(":/images/mupen64plus.png"));
+    setWindowTitle(AppName);
+    setWindowIcon(QIcon(":/images/"+ParentNameLower+".png"));
+    installEventFilter(this);
 
     autoloadSettings();
 
     emulation = new EmulatorHandler(this);
+    romCollection = new RomCollection(QStringList() << "*.z64" << "*.v64" << "*.n64" << "*.zip",
+                                      QStringList() << SETTINGS.value("Paths/roms","").toString().split("|"),
+                                      this);
+    createMenu();
+    createRomView();
 
     connect(emulation, SIGNAL(started()), this, SLOT(disableButtons()));
     connect(emulation, SIGNAL(finished()), this, SLOT(enableButtons()));
     connect(emulation, SIGNAL(showLog()), this, SLOT(openLog()));
 
-
-    romCollection = new RomCollection(QStringList() << "*.z64" << "*.v64" << "*.n64" << "*.zip",
-                                      QStringList() << SETTINGS.value("Paths/roms","").toString().split("|"),
-                                      this);
-
     connect(romCollection, SIGNAL(updateStarted(bool)), this, SLOT(disableViews(bool)));
     connect(romCollection, SIGNAL(romAdded(Rom*, int)), this, SLOT(addToView(Rom*, int)));
     connect(romCollection, SIGNAL(updateEnded(int, bool)), this, SLOT(enableViews(int, bool)));
 
+    romCollection->cachedRoms();
+
 
     mainWidget = new QWidget(this);
     setCentralWidget(mainWidget);
@@ -94,8 +100,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
                       SETTINGS.value("Geometry/width", 900).toInt(),
                       SETTINGS.value("Geometry/height", 600).toInt()));
 
-    createMenu();
-    createRomView();
+    if (SETTINGS.value("View/fullscreen", "").toString() == "true")
+        updateFullScreenMode();
 
     mainLayout = new QVBoxLayout(mainWidget);
     mainLayout->setMenuBar(menuBar);
@@ -104,6 +110,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
     mainLayout->addWidget(tableView);
     mainLayout->addWidget(gridView);
     mainLayout->addWidget(listView);
+    mainLayout->addWidget(disabledView);
 
     mainLayout->setMargin(0);
 
@@ -114,304 +121,29 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 
 void MainWindow::addToView(Rom *currentRom, int count)
 {
-    if (SETTINGS.value("View/layout", "none") == "table")
-        addToTableView(currentRom);
-    else if (SETTINGS.value("View/layout", "none") == "grid")
-        addToGridView(currentRom, count);
-    else if (SETTINGS.value("View/layout", "none") == "list")
-        addToListView(currentRom, count);
-}
-
-
-void MainWindow::addToGridView(Rom *currentRom, int count)
-{
-    ClickableWidget *gameGridItem = new ClickableWidget(gridWidget);
-    gameGridItem->setMinimumWidth(getGridSize("width"));
-    gameGridItem->setMaximumWidth(getGridSize("width"));
-    gameGridItem->setGraphicsEffect(getShadow(false));
-
-    //Assign ROM data to widget for use in click events
-    gameGridItem->setProperty("fileName", currentRom->fileName);
-    gameGridItem->setProperty("directory", currentRom->directory);
-    if (currentRom->goodName == getTranslation("Unknown ROM") ||
-        currentRom->goodName == getTranslation("Requires catalog file"))
-        gameGridItem->setProperty("search", currentRom->internalName);
-    else
-        gameGridItem->setProperty("search", currentRom->goodName);
-    gameGridItem->setProperty("romMD5", currentRom->romMD5);
-    gameGridItem->setProperty("zipFile", currentRom->zipFile);
-
-    QGridLayout *gameGridLayout = new QGridLayout(gameGridItem);
-    gameGridLayout->setColumnStretch(0, 1);
-    gameGridLayout->setColumnStretch(3, 1);
-    gameGridLayout->setRowMinimumHeight(1, getImageSize("Grid").height());
-
-    QLabel *gridImageLabel = new QLabel(gameGridItem);
-    gridImageLabel->setMinimumHeight(getImageSize("Grid").height());
-    gridImageLabel->setMinimumWidth(getImageSize("Grid").width());
-    QPixmap image;
-
-    if (currentRom->imageExists) {
-        //Use uniform aspect ratio to account for fluctuations in TheGamesDB box art
-        Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio;
-
-        //Don't warp aspect ratio though if image is too far away from standard size (JP box art)
-        float aspectRatio = float(currentRom->image.width()) / currentRom->image.height();
-
-        if (aspectRatio < 1.1 || aspectRatio > 1.8)
-            aspectRatioMode = Qt::KeepAspectRatio;
-
-        image = currentRom->image.scaled(getImageSize("Grid"), aspectRatioMode, Qt::SmoothTransformation);
-    } else
-        image = QPixmap(":/images/not-found.png").scaled(getImageSize("Grid"), Qt::IgnoreAspectRatio,
-                                                         Qt::SmoothTransformation);
-
-    gridImageLabel->setPixmap(image);
-    gridImageLabel->setAlignment(Qt::AlignCenter);
-    gameGridLayout->addWidget(gridImageLabel, 1, 1);
-
-    if (SETTINGS.value("Grid/label","true") == "true") {
-        QLabel *gridTextLabel = new QLabel(gameGridItem);
-
-        //Don't allow label to be wider than image
-        gridTextLabel->setMaximumWidth(getImageSize("Grid").width());
-
-        QString text = "";
-        QString labelText = SETTINGS.value("Grid/labeltext","Filename").toString();
-
-        text = getRomInfo(labelText, currentRom);
-
-        gridTextLabel->setText(text);
-
-        QString textHex = getColor(SETTINGS.value("Grid/labelcolor","White").toString()).name();
-        int fontSize = getGridSize("font");
-
-        gridTextLabel->setStyleSheet("QLabel { font-weight: bold; color: " + textHex + "; font-size: "
-                                     + QString::number(fontSize) + "px; }");
-        gridTextLabel->setWordWrap(true);
-        gridTextLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
-
-        gameGridLayout->addWidget(gridTextLabel, 2, 1);
-    }
-
-    gameGridItem->setLayout(gameGridLayout);
-
-    gameGridItem->setMinimumHeight(gameGridItem->sizeHint().height());
-
-    int columnCount = SETTINGS.value("Grid/columncount", "4").toInt();
-    gridLayout->addWidget(gameGridItem, count / columnCount + 1, count % columnCount + 1);
-    gridWidget->adjustSize();
-
-    connect(gameGridItem, SIGNAL(singleClicked(QWidget*)), this, SLOT(highlightGridWidget(QWidget*)));
-    connect(gameGridItem, SIGNAL(doubleClicked(QWidget*)), this, SLOT(launchRomFromWidget(QWidget*)));
-}
-
-
-void MainWindow::addToListView(Rom *currentRom, int count)
-{
-    QStringList visible = SETTINGS.value("List/columns", "Filename|Internal Name|Size").toString().split("|");
-
-    if (visible.join("") == "" && SETTINGS.value("List/displaycover", "") != "true")
-        //Otherwise no columns, so don't bother populating
-        return;
-
-    ClickableWidget *gameListItem = new ClickableWidget(listWidget);
-    gameListItem->setContentsMargins(0, 0, 20, 0);
-
-    //Assign ROM data to widget for use in click events
-    gameListItem->setProperty("fileName", currentRom->fileName);
-    gameListItem->setProperty("directory", currentRom->directory);
-    if (currentRom->goodName == getTranslation("Unknown ROM") ||
-        currentRom->goodName == getTranslation("Requires catalog file"))
-        gameListItem->setProperty("search", currentRom->internalName);
-    else
-        gameListItem->setProperty("search", currentRom->goodName);
-    gameListItem->setProperty("romMD5", currentRom->romMD5);
-    gameListItem->setProperty("zipFile", currentRom->zipFile);
-
-    QGridLayout *gameListLayout = new QGridLayout(gameListItem);
-    gameListLayout->setColumnStretch(3, 1);
-
-    //Add image
-    if (SETTINGS.value("List/displaycover", "") == "true") {
-        QLabel *listImageLabel = new QLabel(gameListItem);
-        listImageLabel->setMinimumHeight(getImageSize("List").height());
-        listImageLabel->setMinimumWidth(getImageSize("List").width());
-
-        QPixmap image;
-
-        if (currentRom->imageExists)
-            image = currentRom->image.scaled(getImageSize("List"), Qt::KeepAspectRatio,
-                                            Qt::SmoothTransformation);
-        else
-            image = QPixmap(":/images/not-found.png").scaled(getImageSize("List"), Qt::KeepAspectRatio,
-                                                             Qt::SmoothTransformation);
-
-        listImageLabel->setPixmap(image);
-        listImageLabel->setAlignment(Qt::AlignCenter);
-        gameListLayout->addWidget(listImageLabel, 0, 1);
-    }
-
-    //Create text label
-    QLabel *listTextLabel = new QLabel("", gameListItem);
-    QString listText = "";
-
-    int i = 0;
-
-    foreach (QString current, visible)
-    {
-        QString addition = "<style>h2 { margin: 0; }</style>";
-
-        if (i == 0 && SETTINGS.value("List/firstitemheader","true") == "true")
-            addition += "<h2>";
-        else
-            addition += "<b>" + current + ":</b> ";
-
-        addition += getRomInfo(current, currentRom, true) + "<br />";
-
-        if (i == 0 && SETTINGS.value("List/firstitemheader","true") == "true")
-            addition += "</h2>";
-
-        if (addition != "<style>h2 { margin: 0; }</style><b>" + current + ":</b> <br />")
-            listText += addition;
-
-        i++;
-    }
-
-    //Remove last break tag
-    listText.remove(QRegExp("<br />$"));
-
-    listTextLabel->setText(listText);
-    listTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
-    listTextLabel->setWordWrap(true);
-    gameListLayout->addWidget(listTextLabel, 0, 3);
-
-    gameListLayout->setColumnMinimumWidth(0, 20);
-    gameListLayout->setColumnMinimumWidth(2, 10);
-    gameListItem->setLayout(gameListLayout);
-
-    if (count != 0) {
-        QFrame *separator = new QFrame();
-        separator->setFrameShape(QFrame::HLine);
-        separator->setStyleSheet("margin:0;padding:0;");
-        listLayout->addWidget(separator);
-    }
-
-    listLayout->addWidget(gameListItem);
-
-    connect(gameListItem, SIGNAL(singleClicked(QWidget*)), this, SLOT(highlightListWidget(QWidget*)));
-    connect(gameListItem, SIGNAL(doubleClicked(QWidget*)), this, SLOT(launchRomFromWidget(QWidget*)));
-}
-
-
-void MainWindow::addToTableView(Rom *currentRom)
-{
-    QStringList visible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
-
-    if (visible.join("") == "") //Otherwise no columns, so don't bother populating
-        return;
-
-    fileItem = new TreeWidgetItem(tableView);
-
-    //Filename for launching ROM
-    fileItem->setText(0, currentRom->fileName);
-
-    //Directory ROM is located in
-    fileItem->setText(1, currentRom->directory);
-
-    //GoodName or Internal Name for searching
-    if (currentRom->goodName == getTranslation("Unknown ROM") ||
-        currentRom->goodName == getTranslation("Requires catalog file"))
-        fileItem->setText(2, currentRom->internalName);
-    else
-        fileItem->setText(2, currentRom->goodName);
-
-    //MD5 for cache info
-    fileItem->setText(3, currentRom->romMD5.toLower());
-
-    //Zip file
-    fileItem->setText(4, currentRom->zipFile);
-
-    int i = 5, c = 0;
-    bool addImage = false;
-
-    foreach (QString current, visible)
-    {
-        QString text = getRomInfo(current, currentRom);
-        fileItem->setText(i, text);
-
-        if (current == "GoodName" || current == "Game Title") {
-            if (text == getTranslation("Unknown ROM") ||
-                text == getTranslation("Requires catalog file") ||
-                text == getTranslation("Not found")) {
-                fileItem->setForeground(i, QBrush(Qt::gray));
-                fileItem->setData(i, Qt::UserRole, "ZZZ"); //end of sorting
-            } else
-                fileItem->setData(i, Qt::UserRole, text);
-        }
-
-        if (current == "Size")
-            fileItem->setData(i, Qt::UserRole, currentRom->sortSize);
-
-        if (current == "Release Date")
-            fileItem->setData(i, Qt::UserRole, currentRom->sortDate);
-
-        if (current == "Game Cover") {
-            c = i;
-            addImage = true;
-        }
-
-        QStringList center, right;
-
-        center << "MD5" << "CRC1" << "CRC2" << "Rumble" << "ESRB" << "Genre" << "Publisher" << "Developer";
-        right << "Size" << "Players" << "Save Type" << "Release Date" << "Rating";
-
-        if (center.contains(current))
-            fileItem->setTextAlignment(i, Qt::AlignHCenter | Qt::AlignVCenter);
-        else if (right.contains(current))
-            fileItem->setTextAlignment(i, Qt::AlignRight | Qt::AlignVCenter);
-
-        i++;
-    }
-
-    tableView->addTopLevelItem(fileItem);
-
-
-    if (currentRom->imageExists && addImage) {
-        QPixmap image(currentRom->image.scaled(getImageSize("Table"), Qt::KeepAspectRatio,
-                                              Qt::SmoothTransformation));
-
-        QWidget *imageContainer = new QWidget(tableView);
-        QGridLayout *imageGrid = new QGridLayout(imageContainer);
-        QLabel *imageLabel = new QLabel(imageContainer);
-
-        imageLabel->setPixmap(image);
-        imageGrid->addWidget(imageLabel, 1, 1);
-        imageGrid->setColumnStretch(0, 1);
-        imageGrid->setColumnStretch(2, 1);
-        imageGrid->setRowStretch(0, 1);
-        imageGrid->setRowStretch(2, 1);
-        imageGrid->setContentsMargins(0,0,0,0);
-
-        imageContainer->setLayout(imageGrid);
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
 
-        tableView->setItemWidget(fileItem, c, imageContainer);
-    }
+    if (visibleLayout == "table")
+        tableView->addToTableView(currentRom);
+    else if (visibleLayout == "grid")
+        gridView->addToGridView(currentRom, count, false);
+    else if (visibleLayout == "list")
+        listView->addToListView(currentRom, count, false);
 }
 
 
 void MainWindow::autoloadSettings()
 {
-    QString mupen64Path = SETTINGS.value("Paths/mupen64plus", "").toString();
+    QString emulatorPath = SETTINGS.value("Paths/mupen64plus", "").toString();
     QString dataPath = SETTINGS.value("Paths/data", "").toString();
     QString pluginPath = SETTINGS.value("Paths/plugins", "").toString();
 
-    if (mupen64Path == "" && dataPath == "" && pluginPath == "") {
+    if (emulatorPath == "" && dataPath == "" && pluginPath == "") {
 #ifdef OS_LINUX_OR_BSD
         //If user has not entered any settings, check common locations for them
-        QStringList mupen64Check, dataCheck, pluginCheck;
+        QStringList emulatorCheck, dataCheck, pluginCheck;
 
-        mupen64Check << "/usr/bin/mupen64plus"
+        emulatorCheck << "/usr/bin/mupen64plus"
                      << "/usr/games/mupen64plus"
                      << "/usr/local/bin/mupen64plus";
 
@@ -428,7 +160,7 @@ void MainWindow::autoloadSettings()
                      << "/usr/local/share/mupen64plus";
 
 
-        foreach (QString check, mupen64Check)
+        foreach (QString check, emulatorCheck)
             if (QFileInfo(check).exists())
                 SETTINGS.setValue("Paths/mupen64plus", check);
 
@@ -503,7 +235,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
     else
         SETTINGS.setValue("Geometry/maximized", "");
 
-    saveColumnWidths();
+    tableView->saveColumnWidths();
 
     event->accept();
 }
@@ -514,6 +246,7 @@ void MainWindow::createMenu()
     menuBar = new QMenuBar(this);
 
 
+    //File
     fileMenu = new QMenu(tr("&File"), this);
     openAction = fileMenu->addAction(tr("&Open ROM..."));
     fileMenu->addSeparator();
@@ -534,7 +267,14 @@ void MainWindow::createMenu()
 
     menuBar->addMenu(fileMenu);
 
+    connect(openAction, SIGNAL(triggered()), this, SLOT(openRom()));
+    connect(refreshAction, SIGNAL(triggered()), romCollection, SLOT(addRoms()));
+    connect(downloadAction, SIGNAL(triggered()), this, SLOT(openDownloader()));
+    connect(deleteAction, SIGNAL(triggered()), this, SLOT(openDeleteDialog()));
+    connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+
 
+    //Emulation
     emulationMenu = new QMenu(tr("&Emulation"), this);
     startAction = emulationMenu->addAction(tr("&Start"));
     stopAction = emulationMenu->addAction(tr("St&op"));
@@ -549,9 +289,34 @@ void MainWindow::createMenu()
 
     menuBar->addMenu(emulationMenu);
 
+    connect(startAction, SIGNAL(triggered()), this, SLOT(launchRomFromMenu()));
+    connect(stopAction, SIGNAL(triggered()), this, SLOT(stopEmulator()));
+    connect(logAction, SIGNAL(triggered()), this, SLOT(openLog()));
+
 
+    //Settings
     settingsMenu = new QMenu(tr("&Settings"), this);
-    layoutMenu = settingsMenu->addMenu(tr("&Layout"));
+    editorAction = settingsMenu->addAction(tr("Edit mupen64plus.cfg..."));
+    settingsMenu->addSeparator();
+    configureGameAction = settingsMenu->addAction(tr("Configure &Game..."));
+#ifndef Q_OS_OSX //OSX does not show the quit action so the separator is unneeded
+    settingsMenu->addSeparator();
+#endif
+    configureAction = settingsMenu->addAction(tr("&Configure..."));
+    configureAction->setIcon(QIcon::fromTheme("preferences-other"));
+
+    configureGameAction->setEnabled(false);
+
+    menuBar->addMenu(settingsMenu);
+
+    connect(editorAction, SIGNAL(triggered()), this, SLOT(openEditor()));
+    connect(configureGameAction, SIGNAL(triggered()), this, SLOT(openGameSettings()));
+    connect(configureAction, SIGNAL(triggered()), this, SLOT(openSettings()));
+
+
+    //View
+    viewMenu = new QMenu(tr("&View"), this);
+    layoutMenu = viewMenu->addMenu(tr("&Layout"));
     layoutGroup = new QActionGroup(this);
 
     QList<QStringList> layouts;
@@ -569,34 +334,45 @@ void MainWindow::createMenu()
         layoutItem->setCheckable(true);
         layoutGroup->addAction(layoutItem);
 
-        //Only enable layout changes when Mupen64Plus is not running
+        //Only enable layout changes when emulator is not running
         menuEnable << layoutItem;
 
         if(layoutValue == layoutName.at(1))
             layoutItem->setChecked(true);
     }
 
-    editorAction = settingsMenu->addAction(tr("Edit mupen64plus.cfg..."));
-    settingsMenu->addSeparator();
-    configureGameAction = settingsMenu->addAction(tr("Configure &Game..."));
-#ifndef Q_OS_OSX //OSX does not show the configure action so the separator is unneeded
-    settingsMenu->addSeparator();
+    viewMenu->addSeparator();
+
+#if QT_VERSION >= 0x050000
+    //OSX El Capitan adds it's own full-screen option
+    if (QSysInfo::macVersion() < QSysInfo::MV_ELCAPITAN || QSysInfo::macVersion() == QSysInfo::MV_None)
+        fullScreenAction = viewMenu->addAction(tr("&Full-screen"));
+    else
+        fullScreenAction = new QAction(this);
+#else
+    fullScreenAction = viewMenu->addAction(tr("&Full-screen"));
 #endif
-    configureAction = settingsMenu->addAction(tr("&Configure..."));
-    configureAction->setIcon(QIcon::fromTheme("preferences-other"));
+    fullScreenAction->setCheckable(true);
 
-    configureGameAction->setEnabled(false);
+    if (SETTINGS.value("View/fullscreen", "") == "true")
+        fullScreenAction->setChecked(true);
 
-    menuBar->addMenu(settingsMenu);
+    menuBar->addMenu(viewMenu);
 
+    connect(layoutGroup, SIGNAL(triggered(QAction*)), this, SLOT(updateLayoutSetting()));
+    connect(fullScreenAction, SIGNAL(triggered()), this, SLOT(updateFullScreenMode()));
 
+
+    //Help
     helpMenu = new QMenu(tr("&Help"), this);
     aboutAction = helpMenu->addAction(tr("&About"));
     aboutAction->setIcon(QIcon::fromTheme("help-about"));
     menuBar->addMenu(helpMenu);
 
+    connect(aboutAction, SIGNAL(triggered()), this, SLOT(openAbout()));
+
 
-    //Create list of actions that are enabled only when Mupen64Plus is not running
+    //Create list of actions that are enabled only when emulator is not running
     menuEnable << startAction
                << logAction
                << openAction
@@ -608,22 +384,14 @@ void MainWindow::createMenu()
                << editorAction
                << quitAction;
 
-    //Create list of actions that are disabled when Mupen64Plus is not running
+    //Create list of actions that are disabled when emulator is not running
     menuDisable << stopAction;
 
-    connect(openAction, SIGNAL(triggered()), this, SLOT(openRom()));
-    connect(refreshAction, SIGNAL(triggered()), romCollection, SLOT(addRoms()));
-    connect(downloadAction, SIGNAL(triggered()), this, SLOT(openDownloader()));
-    connect(deleteAction, SIGNAL(triggered()), this, SLOT(openDeleteDialog()));
-    connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
-    connect(startAction, SIGNAL(triggered()), this, SLOT(launchRomFromMenu()));
-    connect(stopAction, SIGNAL(triggered()), this, SLOT(stopEmulator()));
-    connect(logAction, SIGNAL(triggered()), this, SLOT(openLog()));
-    connect(configureAction, SIGNAL(triggered()), this, SLOT(openSettings()));
-    connect(configureGameAction, SIGNAL(triggered()), this, SLOT(openGameSettings()));
-    connect(editorAction, SIGNAL(triggered()), this, SLOT(openEditor()));
-    connect(aboutAction, SIGNAL(triggered()), this, SLOT(openAbout()));
-    connect(layoutGroup, SIGNAL(triggered(QAction*)), this, SLOT(updateLayoutSetting()));
+    //Create list of actions that are only active when a ROM is selected
+    menuRomSelected << startAction
+                    << deleteAction
+                    << downloadAction
+                    << configureGameAction;
 }
 
 
@@ -639,7 +407,7 @@ void MainWindow::createRomView()
     emptyLayout = new QGridLayout(emptyView);
 
     emptyIcon = new QLabel(emptyView);
-    emptyIcon->setPixmap(QPixmap(":/images/mupen64plus.png"));
+    emptyIcon->setPixmap(QPixmap(":/images/"+ParentNameLower+".png"));
 
     emptyLayout->addWidget(emptyIcon, 1, 1);
     emptyLayout->setColumnStretch(0, 1);
@@ -651,81 +419,41 @@ void MainWindow::createRomView()
 
 
     //Create table view
-    tableView = new QTreeWidget(this);
-    tableView->setWordWrap(false);
-    tableView->setAllColumnsShowFocus(true);
-    tableView->setRootIsDecorated(false);
-    tableView->setSortingEnabled(true);
-    tableView->setStyleSheet("QTreeView { border: none; } QTreeView::item { height: 25px; }");
-
-    headerView = new QHeaderView(Qt::Horizontal, this);
-    tableView->setHeader(headerView);
-    tableView->setHidden(true);
+    tableView = new TableView(this);
+    connect(tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(enableButtons()));
+    connect(tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(launchRomFromTable()));
+    connect(tableView, SIGNAL(tableActive()), this, SLOT(enableButtons()));
+    connect(tableView, SIGNAL(enterPressed()), this, SLOT(launchRomFromTable()));
 
 
     //Create grid view
-    gridView = new QScrollArea(this);
-    gridView->setObjectName("gridView");
-    gridView->setStyleSheet("#gridView { border: none; }");
-    gridView->setBackgroundRole(QPalette::Dark);
-    gridView->setAlignment(Qt::AlignHCenter);
-    gridView->setHidden(true);
-
-    gridView->verticalScrollBar()->setObjectName("vScrollBar");
-    gridView->horizontalScrollBar()->setObjectName("hScrollBar");
-
-    setGridBackground();
-
-
-    gridWidget = new QWidget(gridView);
-    gridWidget->setObjectName("gridWidget");
-    gridView->setWidget(gridWidget);
-
-    gridLayout = new QGridLayout(gridWidget);
-    gridLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
-    gridLayout->setRowMinimumHeight(0, 10);
-
-    gridWidget->setLayout(gridLayout);
-
-    gridCurrent = false;
-    currentGridRom = 0;
+    gridView = new GridView(this);
+    connect(gridView, SIGNAL(gridItemSelected(bool)), this, SLOT(toggleMenus(bool)));
 
 
     //Create list view
-    listView = new QScrollArea(this);
-    listView->setStyleSheet("QScrollArea { border: none; }");
-    listView->setBackgroundRole(QPalette::Base);
-    listView->setWidgetResizable(true);
-    listView->setHidden(true);
+    listView = new ListView(this);
+    connect(listView, SIGNAL(listItemSelected(bool)), this, SLOT(toggleMenus(bool)));
 
-    listWidget = new QWidget(listView);
-    listView->setWidget(listWidget);
 
-    listLayout = new QVBoxLayout(listWidget);
-    listLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
-    listWidget->setLayout(listLayout);
+    //Create disabled view
+    disabledView = new QWidget(this);
+    disabledView->setHidden(true);
+    disabledView->setDisabled(true);
 
-    listCurrent = false;
-    currentListRom = 0;
+    disabledLayout = new QVBoxLayout(disabledView);
+    disabledLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+    disabledView->setLayout(disabledLayout);
 
+    QString disabledText = QString("Add a directory containing ROMs under ")
+                         + "Settings->Configure->Paths to use this view.";
+    disabledLabel = new QLabel(disabledText, disabledView);
+    disabledLabel->setWordWrap(true);
+    disabledLabel->setAlignment(Qt::AlignCenter);
+    disabledLayout->addWidget(disabledLabel);
 
-    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
 
-    if (visibleLayout == "table")
-        tableView->setHidden(false);
-    else if (visibleLayout == "grid")
-        gridView->setHidden(false);
-    else if (visibleLayout == "list")
-        listView->setHidden(false);
-    else
-        emptyView->setHidden(false);
-
-    romCollection->cachedRoms();
-
-    connect(tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(enableButtons()));
-    connect(tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(launchRomFromTable()));
-    connect(headerView, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
-            this, SLOT(saveSortOrder(int,Qt::SortOrder)));
+    showActiveView();
 }
 
 
@@ -737,32 +465,25 @@ void MainWindow::disableButtons()
 
 void MainWindow::disableViews(bool imageUpdated)
 {
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
+
+    //Save position in current layout
+    if (visibleLayout == "table")
+        tableView->saveTablePosition();
+    else if (visibleLayout == "grid")
+        gridView->saveGridPosition();
+    else if (visibleLayout == "list")
+        listView->saveListPosition();
+
     resetLayouts(imageUpdated);
     tableView->clear();
 
     tableView->setEnabled(false);
     gridView->setEnabled(false);
     listView->setEnabled(false);
-    configureGameAction->setEnabled(false);
-    downloadAction->setEnabled(false);
-    deleteAction->setEnabled(false);
-    startAction->setEnabled(false);
-    stopAction->setEnabled(false);
 
-    //Save position in current layout
-    positionx = 0;
-    positiony = 0;
-
-    if (SETTINGS.value("View/layout", "none") == "table") {
-        positionx = tableView->horizontalScrollBar()->value();
-        positiony = tableView->verticalScrollBar()->value();
-    } else if (SETTINGS.value("View/layout", "none") == "grid") {
-        positionx = gridView->horizontalScrollBar()->value();
-        positiony = gridView->verticalScrollBar()->value();
-    } else if (SETTINGS.value("View/layout", "none") == "list") {
-        positionx = listView->horizontalScrollBar()->value();
-        positiony = listView->verticalScrollBar()->value();
-    }
+    foreach (QAction *next, menuRomSelected)
+        next->setEnabled(false);
 }
 
 
@@ -774,6 +495,8 @@ void MainWindow::enableButtons()
 
 void MainWindow::enableViews(int romCount, bool cached)
 {
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
+
     if (romCount != 0) { //else no ROMs, so leave views disabled
         QStringList tableVisible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
 
@@ -783,87 +506,107 @@ void MainWindow::enableViews(int romCount, bool cached)
         gridView->setEnabled(true);
         listView->setEnabled(true);
 
+        if (visibleLayout == "table")
+            tableView->setFocus();
+        else if (visibleLayout == "grid")
+            gridView->setFocus();
+        else if (visibleLayout == "list")
+            listView->setFocus();
+
+        //Check if disabled view is showing. If it is, re-enabled the selected view
+        if (!disabledView->isHidden()) {
+            disabledView->setHidden(true);
+            showActiveView();
+        }
+
         if (cached) {
             QTimer *timer = new QTimer(this);
             timer->setSingleShot(true);
             timer->setInterval(0);
             timer->start();
 
-            if (SETTINGS.value("View/layout", "none") == "table")
-                connect(timer, SIGNAL(timeout()), this, SLOT(setTablePosition()));
-            else if (SETTINGS.value("View/layout", "none") == "grid")
-                connect(timer, SIGNAL(timeout()), this, SLOT(setGridPosition()));
-            else if (SETTINGS.value("View/layout", "none") == "list")
-                connect(timer, SIGNAL(timeout()), this, SLOT(setListPosition()));
+            if (visibleLayout == "table")
+                connect(timer, SIGNAL(timeout()), tableView, SLOT(setTablePosition()));
+            else if (visibleLayout == "grid")
+                connect(timer, SIGNAL(timeout()), gridView, SLOT(setGridPosition()));
+            else if (visibleLayout == "list")
+                connect(timer, SIGNAL(timeout()), listView, SLOT(setListPosition()));
+        }
+    } else {
+        if (visibleLayout != "none") {
+            tableView->setHidden(true);
+            gridView->setHidden(true);
+            listView->setHidden(true);
+            disabledView->setHidden(false);
         }
     }
 }
 
 
-QString MainWindow::getCurrentRomInfo(int index)
+bool MainWindow::eventFilter(QObject*, QEvent *event)
 {
-    if (index < 3) {
-        const char *infoChar;
-        int table;
-
-        switch (index) {
-            case 0:  infoChar = "fileName"; table = 0; break;
-            case 1:  infoChar = "search";   table = 2; break;
-            case 2:  infoChar = "romMD5";   table = 3; break;
-            default: infoChar = "";         table = 0; break;
-        }
+    //Show menu bar if mouse is at top of screen in full-screen mode
+    if (event->type() == QEvent::HoverMove && isFullScreen()) {
+        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
 
-        QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
+        //x and y axis are reversed in Qt4
+#if QT_VERSION >= 0x050000
+        int mousePos = mouseEvent->pos().y();
+#else
+        int mousePos = mouseEvent->pos().x();
+#endif
 
-        if (visibleLayout == "table")
-            return tableView->currentItem()->data(table, 0).toString();
-        else if (visibleLayout == "grid" && gridCurrent)
-            return gridLayout->itemAt(currentGridRom)->widget()->property(infoChar).toString();
-        else if (visibleLayout == "list" && listCurrent)
-            return listLayout->itemAt(currentListRom)->widget()->property(infoChar).toString();
+        if (mousePos < 5)
+            showMenuBar(true);
+        if (mousePos > 30)
+            showMenuBar(false);
     }
 
-    return "";
-}
-
-
-void MainWindow::highlightGridWidget(QWidget *current)
-{
-    //Set all to inactive shadow
-    QLayoutItem *gridItem;
-    for (int item = 0; (gridItem = gridLayout->itemAt(item)) != NULL; item++)
-    {
-        gridItem->widget()->setGraphicsEffect(getShadow(false));
+    if (event->type() == QEvent::KeyPress) {
+        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
 
-        if (gridItem->widget() == current)
-            currentGridRom = item;
+        //Exit fullscreen mode if Esc key is pressed
+        if (keyEvent->key() == Qt::Key_Escape && isFullScreen())
+            updateFullScreenMode();
     }
 
-    //Set current to active shadow
-    current->setGraphicsEffect(getShadow(true));
+#if QT_VERSION >= 0x050000
+    //OSX El Capitan adds it's own full-screen option, so handle the event change here
+    if (QSysInfo::macVersion() >= QSysInfo::MV_ELCAPITAN && QSysInfo::macVersion() != QSysInfo::MV_None) {
+        if (event->type() == QEvent::WindowStateChange) {
+            QWindowStateChangeEvent *windowEvent = static_cast<QWindowStateChangeEvent*>(event);
+
+            if (windowEvent->oldState() == Qt::WindowNoState) {
+                SETTINGS.setValue("View/fullscreen", true);
+                tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+                gridView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+                listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+            } else {
+                SETTINGS.setValue("View/fullscreen", "");
+                tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+                gridView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+                listView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+            }
+        }
+    }
+#endif
 
-    gridCurrent = true;
-    toggleMenus(true);
+    return false;
 }
 
 
-void MainWindow::highlightListWidget(QWidget *current)
+QString MainWindow::getCurrentRomInfoFromView(QString infoName)
 {
-    //Reset all margins
-    QLayoutItem *listItem;
-    for (int item = 0; (listItem = listLayout->itemAt(item)) != NULL; item++)
-    {
-        listItem->widget()->setContentsMargins(0, 0, 20, 0);
-
-        if (listItem->widget() == current)
-            currentListRom = item;
-    }
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
 
-    //Give current left margin to stand out
-    current->setContentsMargins(20, 0, 0, 0);
+    if (visibleLayout == "table")
+        return tableView->getCurrentRomInfo(infoName);
+    else if (visibleLayout == "grid" && gridView->hasSelectedRom())
+        return gridView->getCurrentRomInfo(infoName);
+    else if (visibleLayout == "list" && listView->hasSelectedRom())
+        return listView->getCurrentRomInfo(infoName);
 
-    listCurrent = true;
-    toggleMenus(true);
+    return "";
 }
 
 
@@ -873,18 +616,18 @@ void MainWindow::launchRomFromMenu()
 
     if (visibleLayout == "table")
         launchRomFromTable();
-    else if (visibleLayout == "grid" && gridCurrent)
-        launchRomFromWidget(gridLayout->itemAt(currentGridRom)->widget());
-    else if (visibleLayout == "list" && listCurrent)
-        launchRomFromWidget(listLayout->itemAt(currentListRom)->widget());
+    else if (visibleLayout == "grid")
+        launchRomFromWidget(gridView->getCurrentRomWidget());
+    else if (visibleLayout == "list")
+        launchRomFromWidget(listView->getCurrentRomWidget());
 }
 
 
 void MainWindow::launchRomFromTable()
 {
-    QString romFileName = QVariant(tableView->currentItem()->data(0, 0)).toString();
-    QString romDirName = QVariant(tableView->currentItem()->data(1, 0)).toString();
-    QString zipFileName = QVariant(tableView->currentItem()->data(4, 0)).toString();
+    QString romFileName = tableView->getCurrentRomInfo("fileName");
+    QString romDirName = tableView->getCurrentRomInfo("dirName");
+    QString zipFileName = tableView->getCurrentRomInfo("zipFile");
     emulation->startEmulator(QDir(romDirName), romFileName, zipFileName);
 }
 
@@ -916,9 +659,9 @@ void MainWindow::openAbout()
 
 void MainWindow::openDeleteDialog()
 {
-    scrapper = new TheGamesDBScrapper(this);
-    scrapper->deleteGameInfo(getCurrentRomInfo(0), getCurrentRomInfo(2));
-    delete scrapper;
+    scraper = new TheGamesDBScraper(this);
+    scraper->deleteGameInfo(getCurrentRomInfoFromView("fileName"), getCurrentRomInfoFromView("romMD5"));
+    delete scraper;
 
     romCollection->cachedRoms();
 }
@@ -926,7 +669,10 @@ void MainWindow::openDeleteDialog()
 
 void MainWindow::openDownloader()
 {
-    DownloadDialog downloadDialog(getCurrentRomInfo(0), getCurrentRomInfo(1), getCurrentRomInfo(2), this);
+    DownloadDialog downloadDialog(getCurrentRomInfoFromView("fileName"),
+                                  getCurrentRomInfoFromView("search"),
+                                  getCurrentRomInfoFromView("romMD5"),
+                                  this);
     downloadDialog.exec();
 
     romCollection->cachedRoms();
@@ -942,9 +688,10 @@ void MainWindow::openEditor()
 
     if (configPath == "" || !config.exists()) {
         QMessageBox::information(this, tr("Not Found"), QString(tr("Editor requires config directory to be "))
-                                 + tr("set to a directory with mupen64plus.cfg.") + "\n\n"
-                                 + tr("See here for the default config location:") + "\n"
-                                 + "https://code.google.com/p/mupen64plus/wiki/FileLocations");
+                                 + tr("set to a directory with mupen64plus.cfg.") + "<br /><br />"
+                                 + tr("See here for the default config location:") + "<br />"
+                                 + "<a href=\"http://mupen64plus.org/wiki/index.php?title=FileLocations\">"
+                                 + "http://mupen64plus.org/wiki/index.php?title=FileLocations</a>");
     } else {
         ConfigEditor configEditor(configFile, this);
         configEditor.exec();
@@ -954,17 +701,7 @@ void MainWindow::openEditor()
 
 void MainWindow::openGameSettings()
 {
-    QString romFileName;
-    QString visibleLayout = layoutGroup->checkedAction()->data().toString();
-
-    if (visibleLayout == "table")
-        romFileName = QVariant(tableView->currentItem()->data(0, 0)).toString();
-    else if (visibleLayout == "grid" && gridCurrent)
-        romFileName = gridLayout->itemAt(currentGridRom)->widget()->property("fileName").toString();
-    else if (visibleLayout == "list" && listCurrent)
-        romFileName = listLayout->itemAt(currentListRom)->widget()->property("fileName").toString();
-
-    GameSettingsDialog gameSettingsDialog(romFileName, this);
+    GameSettingsDialog gameSettingsDialog(getCurrentRomInfoFromView("fileName"), this);
     gameSettingsDialog.exec();
 }
 
@@ -973,7 +710,8 @@ void MainWindow::openLog()
 {
     if (emulation->lastOutput == "") {
         QMessageBox::information(this, tr("No Output"),
-            tr("There is no log. Either Mupen64Plus has not yet run or there was no output from the last run."));
+            tr("There is no log. Either <ParentName> has not yet run or there was no output from the last run.")
+            .replace("<ParentName>",ParentName));
     } else {
         LogDialog logDialog(emulation->lastOutput, this);
         logDialog.exec();
@@ -1014,7 +752,8 @@ void MainWindow::openSettings()
             romCollection->cachedRoms(false);
     }
 
-    setGridBackground();
+    gridView->setGridBackground();
+    listView->setListBackground();
     toggleMenus(true);
 }
 
@@ -1025,7 +764,15 @@ void MainWindow::openRom()
     foreach (QString type, romCollection->getFileTypes(true)) filter += type + " ";
     filter += ");;" + tr("All Files") + " (*)";
 
-    openPath = QFileDialog::getOpenFileName(this, tr("Open ROM File"), romCollection->romPaths.at(0), filter);
+#if QT_VERSION >= 0x050000
+    QString searchPath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first();
+#else
+    QString searchPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
+#endif
+    if (romCollection->romPaths.count() > 0)
+        searchPath = romCollection->romPaths.at(0);
+
+    openPath = QFileDialog::getOpenFileName(this, tr("Open ROM File"), searchPath, filter);
     if (openPath != "") {
         if (QFileInfo(openPath).suffix() == "zip") {
             QStringList zippedFiles = getZippedFiles(openPath);
@@ -1093,173 +840,67 @@ void MainWindow::openZipDialog(QStringList zippedFiles)
 
 void MainWindow::resetLayouts(bool imageUpdated)
 {
-    QStringList tableVisible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
-
-    QStringList translations;
-    foreach (QString header, tableVisible) translations << getTranslation(header);
-
-    int hidden = 5;
-
-    saveColumnWidths();
-    QStringList widths = SETTINGS.value("Table/width", "").toString().split("|");
-
-    headerLabels.clear();
-    headerLabels << "" << "" << "" << "" << "" << translations; //First 5 blank for hidden columns
-
-    //Remove Game Cover title for aesthetics
-    for (int i = 0; i < headerLabels.size(); i++)
-        if (headerLabels.at(i) == getTranslation("Game Cover")) headerLabels.replace(i, "");
-
-    tableView->setColumnCount(headerLabels.size());
-    tableView->setHeaderLabels(headerLabels);
-    headerView->setSortIndicatorShown(false);
-
-    int height = 0, width = 0;
-    if (tableVisible.contains("Game Cover")) {
-        //Get optimal height/width for cover column
-        height = getImageSize("Table").height() * 1.1;
-        width = getImageSize("Table").width() * 1.2;
-
-        tableView->setStyleSheet("QTreeView { border: none; } QTreeView::item { height: "
-                               + QString::number(height) + "px; }");
-    } else
-        tableView->setStyleSheet("QTreeView { border: none; } QTreeView::item { height: 25px; }");
-
-    QStringList sort = SETTINGS.value("Table/sort", "").toString().split("|");
-    if (sort.size() == 2) {
-        if (sort[1] == "descending")
-            headerView->setSortIndicator(tableVisible.indexOf(sort[0]) + hidden, Qt::DescendingOrder);
-        else
-            headerView->setSortIndicator(tableVisible.indexOf(sort[0]) + hidden, Qt::AscendingOrder);
-    }
-
-    tableView->setColumnHidden(0, true); //Hidden filename for launching emulator
-    tableView->setColumnHidden(1, true); //Hidden directory of ROM location
-    tableView->setColumnHidden(2, true); //Hidden goodname for searching
-    tableView->setColumnHidden(3, true); //Hidden md5 for cache info
-    tableView->setColumnHidden(4, true); //Hidden column for zip file
-
-    int i = hidden;
-    foreach (QString current, tableVisible)
-    {
-        if (i == hidden) {
-            int c = i;
-            if (current == "Game Cover") c++; //If first column is game cover, use next column
-
-            if (SETTINGS.value("Table/stretchfirstcolumn", "true") == "true")
-#if QT_VERSION >= 0x050000
-                tableView->header()->setSectionResizeMode(c, QHeaderView::Stretch);
-#else
-                tableView->header()->setResizeMode(c, QHeaderView::Stretch);
-#endif
-            else
-#if QT_VERSION >= 0x050000
-                tableView->header()->setSectionResizeMode(c, QHeaderView::Interactive);
-#else
-                tableView->header()->setResizeMode(c, QHeaderView::Interactive);
-#endif
-        }
-
-        if (widths.size() == tableVisible.size())
-            tableView->setColumnWidth(i, widths[i - hidden].toInt());
-        else
-            tableView->setColumnWidth(i, getDefaultWidth(current, width));
-
-        //Overwrite saved value if switching image sizes
-        if (imageUpdated && current == "Game Cover")
-            tableView->setColumnWidth(i, width);
-
-        i++;
-    }
-
-
-    //Reset grid view
-    QLayoutItem *gridItem;
-    while ((gridItem = gridLayout->takeAt(0)) != NULL)
-    {
-        delete gridItem->widget();
-        delete gridItem;
-    }
-
-    gridCurrent = false;
-
-
-    //Reset list view
-    QLayoutItem *listItem;
-    while ((listItem = listLayout->takeAt(0)) != NULL)
-    {
-        delete listItem->widget();
-        delete listItem;
-    }
-
-    listCurrent = false;
+    tableView->resetView(imageUpdated);
+    gridView->resetView();
+    listView->resetView();
 }
 
 
-void MainWindow::saveColumnWidths()
+void MainWindow::showActiveView()
 {
-    QStringList widths;
-
-    for (int i = 5; i < tableView->columnCount(); i++)
-    {
-        widths << QString::number(tableView->columnWidth(i));
-    }
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
 
-    if (widths.size() > 0)
-        SETTINGS.setValue("Table/width", widths.join("|"));
+    if (visibleLayout == "table")
+        tableView->setHidden(false);
+    else if (visibleLayout == "grid")
+        gridView->setHidden(false);
+    else if (visibleLayout == "list")
+        listView->setHidden(false);
+    else
+        emptyView->setHidden(false);
 }
 
 
-void MainWindow::saveSortOrder(int column, Qt::SortOrder order)
+void MainWindow::showMenuBar(bool mouseAtTop)
 {
-    QString columnName = headerLabels.value(column);
-
-    if (order == Qt::DescendingOrder)
-        SETTINGS.setValue("Table/sort", columnName + "|descending");
-    else
-        SETTINGS.setValue("Table/sort", columnName + "|ascending");
+    menuBar->setHidden(!mouseAtTop);
 }
 
 
-void MainWindow::setGridBackground()
+
+void MainWindow::showRomMenu(const QPoint &pos)
 {
-    gridView->setStyleSheet("#gridView { border: none; }");
-
-    QString background = SETTINGS.value("Grid/background", "").toString();
-    if (background != "") {
-        QFile backgroundFile(background);
-
-        if (backgroundFile.exists() && !QFileInfo(backgroundFile).isDir())
-            gridView->setStyleSheet(QString()
-                + "#gridView { "
-                    + "border: none; "
-                    + "background: url(" + background + "); "
-                    + "background-attachment: fixed; "
-                    + "background-position: top center; "
-                + "} #gridWidget { background: transparent; } "
-            );
-    }
-}
+    QMenu *contextMenu = new QMenu(this);
 
+    QAction *contextStartAction = contextMenu->addAction(tr("&Start"));
+    contextStartAction->setIcon(QIcon::fromTheme("media-playback-start"));
+    contextMenu->addSeparator();
+    QAction *contextConfigureGameAction = contextMenu->addAction(tr("Configure &Game..."));
 
-void MainWindow::setGridPosition()
-{
-    gridView->horizontalScrollBar()->setValue(positionx);
-    gridView->verticalScrollBar()->setValue(positiony);
-}
+    connect(contextStartAction, SIGNAL(triggered()), this, SLOT(launchRomFromMenu()));
+    connect(contextConfigureGameAction, SIGNAL(triggered()), this, SLOT(openGameSettings()));
 
+    if (SETTINGS.value("Other/downloadinfo", "").toString() == "true") {
+        contextMenu->addSeparator();
+        QAction *contextDownloadAction = contextMenu->addAction(tr("&Download/Update Info..."));
+        QAction *contextDeleteAction = contextMenu->addAction(tr("D&elete Current Info..."));
 
-void MainWindow::setListPosition()
-{
-    listView->horizontalScrollBar()->setValue(positionx);
-    listView->verticalScrollBar()->setValue(positiony);
-}
+        connect(contextDownloadAction, SIGNAL(triggered()), this, SLOT(openDownloader()));
+        connect(contextDeleteAction, SIGNAL(triggered()), this, SLOT(openDeleteDialog()));
+    }
 
 
-void MainWindow::setTablePosition()
-{
-    tableView->horizontalScrollBar()->setValue(positionx);
-    tableView->verticalScrollBar()->setValue(positiony);
+    QWidget *activeWidget = new QWidget(this);
+    QString visibleLayout = SETTINGS.value("View/layout", "none").toString();
+
+    if (visibleLayout == "table")
+        activeWidget = tableView->viewport();
+    else if (visibleLayout == "grid")
+        activeWidget = gridView->getCurrentRomWidget();
+    else if (visibleLayout == "list")
+        activeWidget = listView->getCurrentRomWidget();
+
+    contextMenu->exec(activeWidget->mapToGlobal(pos));
 }
 
 
@@ -1281,11 +922,12 @@ void MainWindow::toggleMenus(bool active)
     gridView->setEnabled(active);
     listView->setEnabled(active);
 
-    if (tableView->currentItem() == NULL && !gridCurrent && !listCurrent) {
-        configureGameAction->setEnabled(false);
-        downloadAction->setEnabled(false);
-        deleteAction->setEnabled(false);
-        startAction->setEnabled(false);
+    if (!tableView->hasSelectedRom() &&
+        !gridView->hasSelectedRom() &&
+        !listView->hasSelectedRom()
+    ) {
+        foreach (QAction *next, menuRomSelected)
+            next->setEnabled(false);
     }
 
     if (SETTINGS.value("Other/downloadinfo", "").toString() == "") {
@@ -1294,6 +936,31 @@ void MainWindow::toggleMenus(bool active)
     }
 }
 
+
+void MainWindow::updateFullScreenMode()
+{
+    if (isFullScreen()) {
+        fullScreenAction->setChecked(false);
+        SETTINGS.setValue("View/fullscreen", "");
+
+        menuBar->setHidden(false);
+        tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+        gridView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+        listView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+        showNormal();
+    } else {
+        fullScreenAction->setChecked(true);
+        SETTINGS.setValue("View/fullscreen", true);
+
+        menuBar->setHidden(true);
+        tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+        gridView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+        listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+        showFullScreen();
+    }
+}
+
+
 void MainWindow::updateLayoutSetting()
 {
     QString visibleLayout = layoutGroup->checkedAction()->data().toString();
@@ -1303,20 +970,14 @@ void MainWindow::updateLayoutSetting()
     tableView->setHidden(true);
     gridView->setHidden(true);
     listView->setHidden(true);
+    disabledView->setHidden(true);
 
-    romCollection->cachedRoms();
+    int romCount = romCollection->cachedRoms();
 
-    if (visibleLayout == "table")
-        tableView->setHidden(false);
-    else if (visibleLayout == "grid")
-        gridView->setHidden(false);
-    else if (visibleLayout == "list")
-        listView->setHidden(false);
-    else
-        emptyView->setHidden(false);
+    if (romCount > 0 || visibleLayout == "none")
+        showActiveView();
 
-    startAction->setEnabled(false);
-    configureGameAction->setEnabled(false);
-    downloadAction->setEnabled(false);
-    deleteAction->setEnabled(false);
+    //View was updated so no ROM will be selected. Update menu items accordingly
+    foreach (QAction *next, menuRomSelected)
+        next->setEnabled(false);
 }
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 2e2175c..a86a154 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -46,8 +46,11 @@ class QScrollArea;
 class QTreeWidget;
 class QVBoxLayout;
 class EmulatorHandler;
+class GridView;
+class ListView;
 class RomCollection;
-class TheGamesDBScrapper;
+class TableView;
+class TheGamesDBScraper;
 class TreeWidgetItem;
 struct Rom;
 
@@ -61,30 +64,18 @@ public:
 
 protected:
     void closeEvent(QCloseEvent *event);
+    bool eventFilter(QObject*, QEvent *event);
 
 private:
-    void addToGridView(Rom *currentRom, int count);
-    void addToListView(Rom *currentRom, int count);
-    void addToTableView(Rom *currentRom);
     void autoloadSettings();
     void createMenu();
     void createRomView();
     void openZipDialog(QStringList zippedFiles);
     void resetLayouts(bool imageUpdated = false);
-    void saveColumnWidths();
-    void setGridBackground();
-    void toggleMenus(bool active);
-
-    int currentGridRom;
-    int currentListRom;
-    int positionx;
-    int positiony;
-    bool gridCurrent;
-    bool listCurrent;
+    void showActiveView();
 
-    QString getCurrentRomInfo(int index);
+    QString getCurrentRomInfoFromView(QString infoName);
     QString openPath;
-    QStringList headerLabels;
 
     QAction *aboutAction;
     QAction *configureAction;
@@ -92,6 +83,7 @@ private:
     QAction *deleteAction;
     QAction *downloadAction;
     QAction *editorAction;
+    QAction *fullScreenAction;
     QAction *logAction;
     QAction *openAction;
     QAction *quitAction;
@@ -102,32 +94,32 @@ private:
     QDialog *zipDialog;
     QDialogButtonBox *zipButtonBox;
     QGridLayout *emptyLayout;
-    QGridLayout *gridLayout;
     QGridLayout *zipLayout;
-    QHeaderView *headerView;
     QLabel *emptyIcon;
+    QLabel *disabledLabel;
     QList<QAction*> menuEnable;
     QList<QAction*> menuDisable;
+    QList<QAction*> menuRomSelected;
     QListWidget *zipList;
     QMenu *emulationMenu;
     QMenu *fileMenu;
     QMenu *helpMenu;
     QMenu *layoutMenu;
     QMenu *settingsMenu;
+    QMenu *viewMenu;
     QMenuBar *menuBar;
     QScrollArea *emptyView;
-    QScrollArea *listView;
-    QScrollArea *gridView;
-    QTreeWidget *tableView;
-    QVBoxLayout *listLayout;
+    QVBoxLayout *disabledLayout;
     QVBoxLayout *mainLayout;
-    QWidget *gridWidget;
-    QWidget *listWidget;
+    QWidget *disabledView;
     QWidget *mainWidget;
 
     EmulatorHandler *emulation;
+    GridView *gridView;
+    ListView *listView;
     RomCollection *romCollection;
-    TheGamesDBScrapper *scrapper;
+    TableView *tableView;
+    TheGamesDBScraper *scraper;
     TreeWidgetItem *fileItem;
 
 private slots:
@@ -136,8 +128,6 @@ private slots:
     void disableViews(bool imageUpdated);
     void enableButtons();
     void enableViews(int romCount, bool cached);
-    void highlightGridWidget(QWidget *current);
-    void highlightListWidget(QWidget *current);
     void launchRomFromMenu();
     void launchRomFromTable();
     void launchRomFromWidget(QWidget *current);
@@ -150,11 +140,11 @@ private slots:
     void openLog();
     void openSettings();
     void openRom();
-    void saveSortOrder(int column, Qt::SortOrder order);
-    void setGridPosition();
-    void setListPosition();
-    void setTablePosition();
+    void showMenuBar(bool mouseAtTop);
+    void showRomMenu(const QPoint &);
     void stopEmulator();
+    void toggleMenus(bool active);
+    void updateFullScreenMode();
     void updateLayoutSetting();
 
 };
diff --git a/src/romcollection.cpp b/src/roms/romcollection.cpp
similarity index 81%
rename from src/romcollection.cpp
rename to src/roms/romcollection.cpp
index 26fd703..6a59189 100644
--- a/src/romcollection.cpp
+++ b/src/roms/romcollection.cpp
@@ -30,9 +30,11 @@
  ***/
 
 #include "romcollection.h"
-#include "common.h"
-#include "global.h"
-#include "thegamesdbscrapper.h"
+
+#include "../global.h"
+#include "../common.h"
+
+#include "thegamesdbscraper.h"
 
 #include <QCoreApplication>
 #include <QCryptographicHash>
@@ -57,13 +59,18 @@ RomCollection::RomCollection(QStringList fileTypes, QStringList romPaths, QWidge
 
 
 Rom RomCollection::addRom(QByteArray *romData, QString fileName, QString directory, QString zipFile,
-                          QSqlQuery query)
+                          QSqlQuery query, bool ddRom)
 {
     Rom currentRom;
 
     currentRom.fileName = fileName;
     currentRom.directory = directory;
-    currentRom.internalName = QString(romData->mid(32, 20)).trimmed();
+
+    if (ddRom)
+        currentRom.internalName = "";
+    else
+        currentRom.internalName = QString(romData->mid(32, 20)).trimmed();
+
     currentRom.romMD5 = QString(QCryptographicHash::hash(*romData,
                                 QCryptographicHash::Md5).toHex());
     currentRom.zipFile = zipFile;
@@ -75,15 +82,22 @@ Rom RomCollection::addRom(QByteArray *romData, QString fileName, QString directo
     query.bindValue(":md5",           currentRom.romMD5);
     query.bindValue(":zip_file",      currentRom.zipFile);
     query.bindValue(":size",          currentRom.sortSize);
+
+    if (ddRom)
+        query.bindValue(":dd_rom", 1);
+    else
+        query.bindValue(":dd_rom", 0);
+
     query.exec();
 
-    initializeRom(&currentRom, false);
+    if (!ddRom)
+        initializeRom(&currentRom, false);
 
     return currentRom;
 }
 
 
-void RomCollection::addRoms()
+int RomCollection::addRoms()
 {
     emit updateStarted();
 
@@ -100,18 +114,20 @@ void RomCollection::addRoms()
     }
 
     QList<Rom> roms;
+    QList<Rom> ddRoms;
+
+    database.open();
+    QSqlQuery query("DELETE FROM rom_collection", database);
 
     if (totalCount != 0) {
         int count = 0;
         setupProgressDialog(totalCount);
 
-        database.open();
-        QSqlQuery query("DELETE FROM rom_collection", database);
         query.prepare(QString("INSERT INTO rom_collection ")
-                      + "(filename, directory, internal_name, md5, zip_file, size) "
-                      + "VALUES (:filename, :directory, :internal_name, :md5, :zip_file, :size)");
+                      + "(filename, directory, internal_name, md5, zip_file, size, dd_rom) "
+                      + "VALUES (:filename, :directory, :internal_name, :md5, :zip_file, :size, :dd_rom)");
 
-        scrapper = new TheGamesDBScrapper(parent);
+        scraper = new TheGamesDBScraper(parent);
 
         foreach (QString romPath, romPaths)
         {
@@ -129,22 +145,21 @@ void RomCollection::addRoms()
                 if (QFileInfo(file).suffix().toLower() == "zip") {
                     foreach (QString zippedFile, getZippedFiles(completeFileName))
                     {
-                        QString ext = zippedFile.right(4).toLower();
-
                         //check for ROM files
-                        if (fileTypes.contains("*" + ext)) {
-                            QByteArray *romData = getZippedRom(zippedFile, completeFileName);
-
-                            if (fileTypes.contains("*.v64"))
-                                *romData = byteswap(*romData);
+                        QByteArray *romData = getZippedRom(zippedFile, completeFileName);
 
-                            if (romData->left(4).toHex() == "80371240") { //Else invalid
-                                roms.append(addRom(romData, zippedFile, romPath, fileName, query));
-                                romCount++;
-                            }
+                        if (fileTypes.contains("*.v64"))
+                            *romData = byteswap(*romData);
 
-                            delete romData;
+                        if (romData->left(4).toHex() == "80371240") { //Z64 ROM
+                            roms.append(addRom(romData, zippedFile, romPath, fileName, query));
+                            romCount++;
+                        } else if (romData->left(4).toHex() == "e848d316") { //64DD ROM
+                            ddRoms.append(addRom(romData, zippedFile, romPath, fileName, query, true));
+                            romCount++;
                         }
+
+                        delete romData;
                     }
                 } else { //Just a normal file
                     file.open(QIODevice::ReadOnly);
@@ -154,9 +169,12 @@ void RomCollection::addRoms()
                     if (fileTypes.contains("*.v64"))
                         *romData = byteswap(*romData);
 
-                    if (romData->left(4).toHex() == "80371240") { //Else invalid
+                    if (romData->left(4).toHex() == "80371240") { //Z64 ROM
                         roms.append(addRom(romData, fileName, romPath, "", query));
                         romCount++;
+                    } else if (romData->left(4).toHex() == "e848d316") { //64DD ROM
+                        ddRoms.append(addRom(romData, fileName, romPath, "", query, true));
+                        romCount++;
                     }
 
                     delete romData;
@@ -171,40 +189,49 @@ void RomCollection::addRoms()
                 QMessageBox::warning(parent, tr("Warning"), tr("No ROMs found in ") + romPath + ".");
         }
 
-        delete scrapper;
-        database.close();
+        delete scraper;
         progress->close();
     } else if (romPaths.size() != 0) {
         QMessageBox::warning(parent, tr("Warning"), tr("No ROMs found."));
     }
 
+    database.close();
+
+    //Emit signals for regular roms
     qSort(roms.begin(), roms.end(), romSorter);
 
     for (int i = 0; i < roms.size(); i++)
         emit romAdded(&roms[i], i);
 
+    //Emit signals for 64DD roms
+    qSort(ddRoms.begin(), ddRoms.end(), romSorter);
+
+    for (int i = 0; i < ddRoms.size(); i++)
+        emit ddRomAdded(&ddRoms[i]);
+
     emit updateEnded(roms.size());
+
+    return roms.size();
 }
 
 
-void RomCollection::cachedRoms(bool imageUpdated)
+int RomCollection::cachedRoms(bool imageUpdated)
 {
     emit updateStarted(imageUpdated);
 
     database.open();
-    QSqlQuery query("SELECT filename, directory, md5, internal_name, zip_file, size FROM rom_collection",
-                    database);
+    QSqlQuery query(QString("SELECT filename, directory, md5, internal_name, zip_file, size, dd_rom ")
+                    + "FROM rom_collection", database);
 
     query.last();
     int romCount = query.at() + 1;
     query.seek(-1);
 
-    if (romCount == -1) { //Nothing cached so try adding ROMs instead
-        addRoms();
-        return;
-    }
+    if (romCount == -1) //Nothing cached so try adding ROMs instead
+        return addRoms();
 
     QList<Rom> roms;
+    QList<Rom> ddRoms;
 
     int count = 0;
     bool showProgress = false;
@@ -220,12 +247,17 @@ void RomCollection::cachedRoms(bool imageUpdated)
         currentRom.internalName = query.value(3).toString();
         currentRom.zipFile = query.value(4).toString();
         currentRom.sortSize = query.value(5).toInt();
+        int ddRom = query.value(6).toInt();
 
         //Check performance of adding first item to see if progress dialog needs to be shown
         if (count == 0) checkPerformance.start();
 
-        initializeRom(&currentRom, true);
-        roms.append(currentRom);
+        if (ddRom == 1)
+            ddRoms.append(currentRom);
+        else {
+            initializeRom(&currentRom, true);
+            roms.append(currentRom);
+        }
 
         if (count == 0) {
             int runtime = checkPerformance.elapsed();
@@ -250,12 +282,21 @@ void RomCollection::cachedRoms(bool imageUpdated)
     if (showProgress)
         progress->close();
 
+    //Emit signals for regular roms
     qSort(roms.begin(), roms.end(), romSorter);
 
     for (int i = 0; i < roms.size(); i++)
         emit romAdded(&roms[i], i);
 
+    //Emit signals for 64DD roms
+    qSort(ddRoms.begin(), ddRoms.end(), romSorter);
+
+    for (int i = 0; i < ddRoms.size(); i++)
+        emit ddRomAdded(&ddRoms[i]);
+
     emit updateEnded(roms.size(), true);
+
+    return roms.size();
 }
 
 
@@ -273,9 +314,15 @@ QStringList RomCollection::getFileTypes(bool archives)
 void RomCollection::initializeRom(Rom *currentRom, bool cached)
 {
     QSettings *romCatalog = new QSettings(parent);
-    QString dataPath = SETTINGS.value("Paths/data", "").toString();
-    QDir dataDir(dataPath);
-    QString catalogFile = dataDir.absoluteFilePath("mupen64plus.ini");
+
+    QString catalogFile = SETTINGS.value("Paths/catalog", "").toString();
+    if (catalogFile == "") {
+        QString dataPath = SETTINGS.value("Paths/data", "").toString();
+        QDir dataDir(dataPath);
+
+        if (QFileInfo(dataDir.absoluteFilePath("mupen64plus.ini")).exists())
+            catalogFile = dataDir.absoluteFilePath("mupen64plus.ini");
+    }
 
     QDir romDir(currentRom->directory);
 
@@ -319,13 +366,13 @@ void RomCollection::initializeRom(Rom *currentRom, bool cached)
     if (!cached && SETTINGS.value("Other/downloadinfo", "").toString() == "true") {
         if (currentRom->goodName != getTranslation("Unknown ROM") &&
             currentRom->goodName != getTranslation("Requires catalog file")) {
-            scrapper->downloadGameInfo(currentRom->romMD5, currentRom->goodName);
+            scraper->downloadGameInfo(currentRom->romMD5, currentRom->goodName);
         } else {
             //tweak internal name by adding spaces to get better results
             QString search = currentRom->internalName;
             search.replace(QRegExp("([a-z])([A-Z])"),"\\1 \\2");
             search.replace(QRegExp("([^ \\d])(\\d)"),"\\1 \\2");
-            scrapper->downloadGameInfo(currentRom->romMD5, search);
+            scraper->downloadGameInfo(currentRom->romMD5, search);
         }
 
     }
@@ -415,10 +462,10 @@ void RomCollection::setupDatabase()
 {
     // Bump this when updating rom_collection structure
     // Will cause clients to delete and recreate the table
-    int dbVersion = 1;
+    int dbVersion = 2;
 
     database = QSqlDatabase::addDatabase("QSQLITE");
-    database.setDatabaseName(getDataLocation() + "/mupen64plus-qt.sqlite");
+    database.setDatabaseName(getDataLocation() + "/"+AppNameLower+".sqlite");
 
     if (!database.open())
         QMessageBox::warning(parent, tr("Database Not Loaded"),
@@ -442,7 +489,8 @@ void RomCollection::setupDatabase()
                         + "md5 TEXT NOT NULL, "
                         + "internal_name TEXT, "
                         + "zip_file TEXT, "
-                        + "size INTEGER)");
+                        + "size INTEGER, "
+                        + "dd_rom INTEGER)");
 
     database.close();
 }
diff --git a/src/romcollection.h b/src/roms/romcollection.h
similarity index 91%
rename from src/romcollection.h
rename to src/roms/romcollection.h
index f193320..54bd836 100644
--- a/src/romcollection.h
+++ b/src/roms/romcollection.h
@@ -38,7 +38,7 @@
 
 class QDir;
 class QProgressDialog;
-class TheGamesDBScrapper;
+class TheGamesDBScraper;
 struct Rom;
 
 
@@ -47,16 +47,17 @@ class RomCollection : public QObject
     Q_OBJECT
 public:
     explicit RomCollection(QStringList fileTypes, QStringList romPaths, QWidget *parent = 0);
-    void cachedRoms(bool imageUpdated = false);
+    int cachedRoms(bool imageUpdated = false);
     void updatePaths(QStringList romPaths);
 
     QStringList getFileTypes(bool archives = false);
     QStringList romPaths;
 
 public slots:
-    void addRoms();
+    int addRoms();
 
 signals:
+    void ddRomAdded(Rom *currentRom);
     void romAdded(Rom *currentRom, int count);
     void updateEnded(int romCount, bool cached = false);
     void updateStarted(bool imageUpdated = false);
@@ -66,7 +67,8 @@ private:
     void setupDatabase();
     void setupProgressDialog(int size);
 
-    Rom addRom(QByteArray *romData, QString fileName, QString directory, QString zipFile, QSqlQuery query);
+    Rom addRom(QByteArray *romData, QString fileName, QString directory, QString zipFile, QSqlQuery query,
+               bool ddRom = false);
 
     QStringList fileTypes;
     QStringList scanDirectory(QDir romDir);
@@ -75,7 +77,7 @@ private:
     QProgressDialog *progress;
     QSqlDatabase database;
 
-    TheGamesDBScrapper *scrapper;
+    TheGamesDBScraper *scraper;
 };
 
 #endif // ROMCOLLECTION_H
diff --git a/src/thegamesdbscrapper.cpp b/src/roms/thegamesdbscraper.cpp
similarity index 91%
rename from src/thegamesdbscrapper.cpp
rename to src/roms/thegamesdbscraper.cpp
index bb666a6..dabb413 100644
--- a/src/thegamesdbscrapper.cpp
+++ b/src/roms/thegamesdbscraper.cpp
@@ -29,9 +29,10 @@
  *
  ***/
 
-#include "thegamesdbscrapper.h"
-#include "common.h"
-#include "global.h"
+#include "thegamesdbscraper.h"
+
+#include "../global.h"
+#include "../common.h"
 
 #include <QDir>
 #include <QEventLoop>
@@ -46,7 +47,7 @@
 #include <QtXml/QDomDocument>
 
 
-TheGamesDBScrapper::TheGamesDBScrapper(QWidget *parent, bool force) : QObject(parent)
+TheGamesDBScraper::TheGamesDBScraper(QWidget *parent, bool force) : QObject(parent)
 {
     this->parent = parent;
     this->force = force;
@@ -54,18 +55,19 @@ TheGamesDBScrapper::TheGamesDBScrapper(QWidget *parent, bool force) : QObject(pa
 }
 
 
-void TheGamesDBScrapper::deleteGameInfo(QString fileName, QString identifier)
+void TheGamesDBScraper::deleteGameInfo(QString fileName, QString identifier)
 {
     QString text;
     text = QString(tr("<b>NOTE:</b> If you are deleting this game's information because the game doesn't "))
-                 + tr("exist on TheGamesDB and Mupen64Plus-Qt pulled the information for different game, it's ")
+                 + tr("exist on TheGamesDB and <AppName> pulled the information for different game, it's ")
                  + tr("better to create an account on")+" <a href=\"http://thegamesdb.net/\">TheGamesDB</a> "
                  + tr("and add the game so other users can benefit as well.")
                  + "<br /><br />"
-                 + tr("This will cause Mupen64Plus-Qt to not update the information for this game until you ")
+                 + tr("This will cause <AppName> to not update the information for this game until you ")
                  + tr("force it with \"Download/Update Info...\"")
                  + "<br /><br />"
                  + tr("Delete the current information for") + " <b>" + fileName + "</b>?";
+    text.replace("<AppName>",AppName);
 
     int answer = QMessageBox::question(parent, tr("Delete Game Information"), text,
                                        QMessageBox::Yes | QMessageBox::No);
@@ -101,7 +103,7 @@ void TheGamesDBScrapper::deleteGameInfo(QString fileName, QString identifier)
 }
 
 
-void TheGamesDBScrapper::downloadGameInfo(QString identifier, QString searchName, QString gameID)
+void TheGamesDBScraper::downloadGameInfo(QString identifier, QString searchName, QString gameID)
 {
     if (keepGoing && identifier != "") {
         if (force) parent->setEnabled(false);
@@ -131,6 +133,9 @@ void TheGamesDBScrapper::downloadGameInfo(QString identifier, QString searchName
                 searchName = "Majora's Mask";
             else if (searchName == "Legend of Zelda, The - Ocarina of Time - Master Quest")
                 searchName = "Master Quest";
+            else if (searchName == "Legend of Zelda, The - Ocarina of Time" ||
+                     searchName == "THE LEGEND OF ZELDA")
+                searchName = "Ocarina of Time";
             else if (searchName.toLower() == "f-zero x")
                 gameID = "10836";
 
@@ -253,13 +258,13 @@ void TheGamesDBScrapper::downloadGameInfo(QString identifier, QString searchName
 }
 
 
-QByteArray TheGamesDBScrapper::getUrlContents(QUrl url)
+QByteArray TheGamesDBScraper::getUrlContents(QUrl url)
 {
     QNetworkAccessManager *manager = new QNetworkAccessManager;
 
     QNetworkRequest request;
     request.setUrl(url);
-    request.setRawHeader("User-Agent", "Mupen64Plus-Qt");
+    request.setRawHeader("User-Agent", AppName.toUtf8().constData());
     QNetworkReply *reply = manager->get(request);
 
     QTimer timer;
@@ -286,7 +291,7 @@ QByteArray TheGamesDBScrapper::getUrlContents(QUrl url)
 }
 
 
-void TheGamesDBScrapper::showError(QString error)
+void TheGamesDBScraper::showError(QString error)
 {
     QString question = "\n\n" + tr("Continue scraping information?");
 
diff --git a/src/thegamesdbscrapper.h b/src/roms/thegamesdbscraper.h
similarity index 90%
rename from src/thegamesdbscrapper.h
rename to src/roms/thegamesdbscraper.h
index 938255d..b7b146a 100644
--- a/src/thegamesdbscrapper.h
+++ b/src/roms/thegamesdbscraper.h
@@ -29,19 +29,19 @@
  *
  ***/
 
-#ifndef THEGAMESDBSCRAPPER_H
-#define THEGAMESDBSCRAPPER_H
+#ifndef THEGAMESDBSCRAPER_H
+#define THEGAMESDBSCRAPER_H
 
 #include <QWidget>
 
 class QUrl;
 
 
-class TheGamesDBScrapper : public QObject
+class TheGamesDBScraper : public QObject
 {
     Q_OBJECT
 public:
-    explicit TheGamesDBScrapper(QWidget *parent = 0, bool force = false);
+    explicit TheGamesDBScraper(QWidget *parent = 0, bool force = false);
     void deleteGameInfo(QString fileName, QString identifier);
     void downloadGameInfo(QString identifier, QString searchName, QString gameID = "");
 
@@ -54,4 +54,4 @@ private:
     QWidget *parent;
 };
 
-#endif // THEGAMESDBSCRAPPER_H
+#endif // THEGAMESDBSCRAPER_H
diff --git a/src/views/gridview.cpp b/src/views/gridview.cpp
new file mode 100644
index 0000000..f99e82a
--- /dev/null
+++ b/src/views/gridview.cpp
@@ -0,0 +1,374 @@
+/***
+ * Copyright (c) 2013, Dan Hasting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the organization nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***/
+
+#include "gridview.h"
+
+#include "../global.h"
+#include "../common.h"
+
+#include "widgets/clickablewidget.h"
+
+#include <QFile>
+#include <QFileInfo>
+#include <QGridLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QScrollArea>
+#include <QScrollBar>
+
+
+GridView::GridView(QWidget *parent) : QScrollArea(parent)
+{
+    this->parent = parent;
+
+    setObjectName("gridView");
+    setStyleSheet("#gridView { border: none; }");
+    setBackgroundRole(QPalette::Dark);
+    setAlignment(Qt::AlignHCenter);
+    setHidden(true);
+
+    setGridBackground();
+
+
+    gridWidget = new QWidget(this);
+    gridWidget->setObjectName("gridWidget");
+    setWidget(gridWidget);
+
+    gridLayout = new QGridLayout(gridWidget);
+    gridLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+    gridLayout->setRowMinimumHeight(0, 10);
+
+    gridWidget->setLayout(gridLayout);
+
+    gridCurrent = false;
+    currentGridRom = 0;
+}
+
+
+void GridView::addToGridView(Rom *currentRom, int count, bool ddEnabled)
+{
+    if (ddEnabled) // Add place for "No Cart" entry
+        count++;
+
+    ClickableWidget *gameGridItem = new ClickableWidget(gridWidget);
+    gameGridItem->setMinimumWidth(getGridSize("width"));
+    gameGridItem->setMaximumWidth(getGridSize("width"));
+    gameGridItem->setGraphicsEffect(getShadow(false));
+    gameGridItem->setContextMenuPolicy(Qt::CustomContextMenu);
+
+    //Assign ROM data to widget for use in click events
+    gameGridItem->setProperty("fileName", currentRom->fileName);
+    gameGridItem->setProperty("directory", currentRom->directory);
+    if (currentRom->goodName == getTranslation("Unknown ROM") ||
+        currentRom->goodName == getTranslation("Requires catalog file"))
+        gameGridItem->setProperty("search", currentRom->internalName);
+    else
+        gameGridItem->setProperty("search", currentRom->goodName);
+    gameGridItem->setProperty("romMD5", currentRom->romMD5);
+    gameGridItem->setProperty("zipFile", currentRom->zipFile);
+
+    QGridLayout *gameGridLayout = new QGridLayout(gameGridItem);
+    gameGridLayout->setColumnStretch(0, 1);
+    gameGridLayout->setColumnStretch(3, 1);
+    gameGridLayout->setRowMinimumHeight(1, getImageSize("Grid").height());
+
+    QLabel *gridImageLabel = new QLabel(gameGridItem);
+    gridImageLabel->setMinimumHeight(getImageSize("Grid").height());
+    gridImageLabel->setMinimumWidth(getImageSize("Grid").width());
+    QPixmap image;
+
+    if (currentRom->imageExists) {
+        //Use uniform aspect ratio to account for fluctuations in TheGamesDB box art
+        Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio;
+
+        //Don't warp aspect ratio though if image is too far away from standard size (JP box art)
+        float aspectRatio = float(currentRom->image.width()) / currentRom->image.height();
+
+        if (aspectRatio < 1.1 || aspectRatio > 1.8)
+            aspectRatioMode = Qt::KeepAspectRatio;
+
+        image = currentRom->image.scaled(getImageSize("Grid"), aspectRatioMode, Qt::SmoothTransformation);
+    } else {
+        if (ddEnabled && count == 0)
+            image = QPixmap(":/images/no-cart.png").scaled(getImageSize("Grid"), Qt::IgnoreAspectRatio,
+                                                             Qt::SmoothTransformation);
+        else
+            image = QPixmap(":/images/not-found.png").scaled(getImageSize("Grid"), Qt::IgnoreAspectRatio,
+                                                             Qt::SmoothTransformation);
+    }
+
+    gridImageLabel->setPixmap(image);
+    gridImageLabel->setAlignment(Qt::AlignCenter);
+    gameGridLayout->addWidget(gridImageLabel, 1, 1);
+
+    if (SETTINGS.value("Grid/label","true") == "true") {
+        QLabel *gridTextLabel = new QLabel(gameGridItem);
+
+        //Don't allow label to be wider than image
+        gridTextLabel->setMaximumWidth(getImageSize("Grid").width());
+
+        QString text = "";
+        QString labelText = SETTINGS.value("Grid/labeltext","Filename").toString();
+
+        text = getRomInfo(labelText, currentRom);
+
+        if (ddEnabled && count == 0)
+            text = tr("No Cart");
+
+        gridTextLabel->setText(text);
+
+        QString textHex = getColor(SETTINGS.value("Grid/labelcolor","White").toString()).name();
+        int fontSize = getGridSize("font");
+
+        gridTextLabel->setStyleSheet("QLabel { font-weight: bold; color: " + textHex + "; font-size: "
+                                     + QString::number(fontSize) + "px; }");
+        gridTextLabel->setWordWrap(true);
+        gridTextLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
+
+        gameGridLayout->addWidget(gridTextLabel, 2, 1);
+    }
+
+    gameGridItem->setLayout(gameGridLayout);
+
+    gameGridItem->setMinimumHeight(gameGridItem->sizeHint().height());
+
+    int columnCount;
+    if (SETTINGS.value("Grid/autocolumns","true").toString() == "true")
+        columnCount = viewport()->width() / (getGridSize("width") + 10);
+    else
+        columnCount = SETTINGS.value("Grid/columncount", "4").toInt();
+
+    if (columnCount == 0) columnCount = 1;
+
+    gridLayout->addWidget(gameGridItem, count / columnCount + 1, count % columnCount + 1);
+    gridWidget->adjustSize();
+
+    connect(gameGridItem, SIGNAL(singleClicked(QWidget*)), this, SLOT(highlightGridWidget(QWidget*)));
+    connect(gameGridItem, SIGNAL(doubleClicked(QWidget*)), parent, SLOT(launchRomFromWidget(QWidget*)));
+    connect(gameGridItem, SIGNAL(arrowPressed(QWidget*, QString)), this, SLOT(selectNextRom(QWidget*, QString)));
+    connect(gameGridItem, SIGNAL(enterPressed(QWidget*)), parent, SLOT(launchRomFromWidget(QWidget*)));
+    connect(gameGridItem, SIGNAL(customContextMenuRequested(const QPoint &)), parent, SLOT(showRomMenu(const QPoint &)));
+}
+
+
+int GridView::getCurrentRom()
+{
+    return currentGridRom;
+}
+
+
+QString GridView::getCurrentRomInfo(QString infoName)
+{
+    const char *property = infoName.toUtf8().constData();
+
+    if (gridLayout->count() > currentGridRom)
+        return gridLayout->itemAt(currentGridRom)->widget()->property(property).toString();
+    return "";
+}
+
+
+QWidget *GridView::getCurrentRomWidget()
+{
+    return gridLayout->itemAt(currentGridRom)->widget();
+}
+
+
+bool GridView::hasSelectedRom()
+{
+    return gridCurrent;
+}
+
+
+void GridView::highlightGridWidget(QWidget *current)
+{
+    current->setFocus();
+
+    //Set all to inactive shadow
+    QLayoutItem *gridItem;
+    for (int item = 0; (gridItem = gridLayout->itemAt(item)) != NULL; item++)
+    {
+        gridItem->widget()->setGraphicsEffect(getShadow(false));
+
+        if (gridItem->widget() == current)
+            currentGridRom = item;
+    }
+
+    //Set current to active shadow
+    current->setGraphicsEffect(getShadow(true));
+
+    gridCurrent = true;
+    emit gridItemSelected(true);
+}
+
+
+void GridView::keyPressEvent(QKeyEvent *event)
+{
+    if ((event->key() == Qt::Key_Down || event->key() == Qt::Key_Right) && gridLayout->count() > 0) {
+        highlightGridWidget(gridLayout->itemAt(0)->widget());
+        ensureWidgetVisible(gridLayout->itemAt(0)->widget());
+    } else
+        QScrollArea::keyPressEvent(event);
+}
+
+
+void GridView::resetView()
+{
+    QLayoutItem *gridItem;
+    while ((gridItem = gridLayout->takeAt(0)) != NULL)
+    {
+        delete gridItem->widget();
+        delete gridItem;
+    }
+
+    gridCurrent = false;
+}
+
+
+void GridView::resizeEvent(QResizeEvent *event)
+{
+    int check = event->size().width() / (getGridSize("width") + 10);
+    bool autoAdjustColumns = SETTINGS.value("Grid/autocolumns","true").toString() == "true";
+
+    if (autoAdjustColumns && check != autoColumnCount && check != 0) {
+        autoColumnCount = check;
+        updateGridColumns(event->size().width());
+    } else
+        QScrollArea::resizeEvent(event);
+}
+
+
+void GridView::saveGridPosition()
+{
+    positionx = horizontalScrollBar()->value();
+    positiony = verticalScrollBar()->value();
+
+    if (gridCurrent)
+        savedGridRom = currentGridRom;
+    else
+        savedGridRom = -1;
+    savedGridRomFilename = getCurrentRomInfo("fileName");
+}
+
+
+void GridView::selectNextRom(QWidget* current, QString keypress)
+{
+    int columnCount;
+    if (SETTINGS.value("Grid/autocolumns","true").toString() == "true")
+        columnCount = autoColumnCount;
+    else
+        columnCount = SETTINGS.value("Grid/columncount", "4").toInt();
+
+    int offset = 0;
+    if (keypress == "UP")
+        offset = columnCount * -1;
+    else if (keypress == "DOWN")
+        offset = columnCount;
+    else if (keypress == "RIGHT")
+        offset = 1;
+    else if (keypress == "LEFT")
+        offset = -1;
+
+    QLayoutItem *gridItem;
+    for (int item = 0; (gridItem = gridLayout->itemAt(item)) != NULL; item++)
+    {
+        if (gridItem->widget() == current && item + offset >= 0 && gridLayout->itemAt(item + offset) != NULL) {
+            ensureWidgetVisible(gridLayout->itemAt(item + offset)->widget());
+            highlightGridWidget(gridLayout->itemAt(item + offset)->widget());
+        }
+    }
+}
+
+
+void GridView::setGridBackground()
+{
+    QString theme = SETTINGS.value("Grid/theme", "Normal").toString();
+    if (theme == "Light")
+        setStyleSheet("#gridView { border: none; background: #FFF; } #gridWidget { background: transparent; }");
+    else if (theme == "Dark")
+        setStyleSheet("#gridView { border: none; background: #222; } #gridWidget { background: transparent; }");
+    else
+        setStyleSheet("#gridView { border: none; }");
+
+    QString background = SETTINGS.value("Grid/background", "").toString();
+    if (background != "") {
+        QFile backgroundFile(background);
+
+        if (backgroundFile.exists() && !QFileInfo(backgroundFile).isDir())
+            setStyleSheet(QString()
+                + "#gridView { "
+                    + "border: none; "
+                    + "background: url(" + background + "); "
+                    + "background-attachment: fixed; "
+                    + "background-position: top center; "
+                + "} #gridWidget { background: transparent; } "
+            );
+    }
+}
+
+
+void GridView::setGridPosition()
+{
+    horizontalScrollBar()->setValue(positionx);
+    verticalScrollBar()->setValue(positiony);
+
+    //Restore selected ROM if it is in the same position
+    if (savedGridRom != -1 && gridLayout->count() > savedGridRom) {
+        QWidget *checkWidget = gridLayout->itemAt(savedGridRom)->widget();
+        if (checkWidget->property("fileName").toString() == savedGridRomFilename)
+            highlightGridWidget(checkWidget);
+    }
+
+    if (SETTINGS.value("Grid/autocolumns","true").toString() == "true")
+        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    else
+        setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+}
+
+
+void GridView::updateGridColumns(int width)
+{
+    int columnCount = width / (getGridSize("width") + 10);
+
+    int gridCount = gridLayout->count();
+    QList<QWidget*> gridItems;
+    for (int count = 0; count < gridCount; count++)
+        gridItems << gridLayout->takeAt(0)->widget();
+
+    int count = 0;
+    foreach(QWidget *gridItem, gridItems)
+    {
+        gridLayout->addWidget(gridItem, count / columnCount + 1, count % columnCount + 1);
+        count++;
+    }
+
+    gridWidget->adjustSize();
+}
+
diff --git a/src/downloaddialog.h b/src/views/gridview.h
similarity index 62%
rename from src/downloaddialog.h
rename to src/views/gridview.h
index cbebb7f..14161c7 100644
--- a/src/downloaddialog.h
+++ b/src/views/gridview.h
@@ -29,39 +29,56 @@
  *
  ***/
 
-#ifndef DOWNLOADDIALOG_H
-#define DOWNLOADDIALOG_H
+#ifndef GRIDVIEW_H
+#define GRIDVIEW_H
 
-#include <QDialog>
+#include <QScrollArea>
 
-class QDialogButtonBox;
 class QGridLayout;
-class QLabel;
-class QLineEdit;
-class TheGamesDBScrapper;
+struct Rom;
 
 
-class DownloadDialog : public QDialog
+class GridView : public QScrollArea
 {
     Q_OBJECT
+
 public:
-    explicit DownloadDialog(QString fileText, QString defaultText, QString romMD5, QWidget *parent = 0);
+    explicit GridView(QWidget *parent = 0);
+    void addToGridView(Rom *currentRom, int count, bool ddEnabled);
+    int getCurrentRom();
+    QString getCurrentRomInfo(QString infoName);
+    QWidget *getCurrentRomWidget();
+    bool hasSelectedRom();
+    void resetView();
+    void saveGridPosition();
+    void setGridBackground();
+
+protected:
+    void keyPressEvent(QKeyEvent *event);
+    void resizeEvent(QResizeEvent *event);
+
+signals:
+    void gridItemSelected(bool active);
 
 private:
-    QDialogButtonBox *downloadButtonBox;
-    QGridLayout *downloadLayout;
-    QLabel *fileLabel;
-    QLabel *gameNameLabel;
-    QLabel *gameIDLabel;
-    QLineEdit *gameNameField;
-    QLineEdit *gameIDField;
-    QString romMD5;
-    QWidget *parent;
+    void updateGridColumns(int width);
+
+    int autoColumnCount;
+    int currentGridRom;
+    bool gridCurrent;
+    int savedGridRom;
+    QString savedGridRomFilename;
+    int positionx;
+    int positiony;
 
-    TheGamesDBScrapper *scrapper;
+    QGridLayout *gridLayout;
+    QWidget *gridWidget;
+    QWidget *parent;
 
 private slots:
-    void runDownloader();
+    void highlightGridWidget(QWidget *current);
+    void selectNextRom(QWidget *current, QString keypress);
+    void setGridPosition();
 };
 
-#endif // DOWNLOADDIALOG_H
+#endif // GRIDVIEW_H
diff --git a/src/views/listview.cpp b/src/views/listview.cpp
new file mode 100644
index 0000000..8801646
--- /dev/null
+++ b/src/views/listview.cpp
@@ -0,0 +1,329 @@
+/***
+ * Copyright (c) 2013, Dan Hasting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the organization nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***/
+
+#include "listview.h"
+
+#include "../global.h"
+#include "../common.h"
+
+#include "widgets/clickablewidget.h"
+
+#include <QFile>
+#include <QFileInfo>
+#include <QGridLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QTimer>
+
+
+ListView::ListView(QWidget *parent) : QScrollArea(parent)
+{
+    this->parent = parent;
+
+    setObjectName("listView");
+    setWidgetResizable(true);
+    setHidden(true);
+
+    setListBackground();
+
+
+    listWidget = new QWidget(this);
+    listWidget->setObjectName("listWidget");
+    setWidget(listWidget);
+
+    listLayout = new QVBoxLayout(listWidget);
+    listLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+    listWidget->setLayout(listLayout);
+
+    listCurrent = false;
+    currentListRom = 0;
+}
+
+
+void ListView::addToListView(Rom *currentRom, int count, bool ddEnabled)
+{
+    if (ddEnabled) // Add place for "No Cart" entry
+        count++;
+
+    QStringList visible = SETTINGS.value("List/columns", "Filename|Internal Name|Size").toString().split("|");
+
+    if (visible.join("") == "" && SETTINGS.value("List/displaycover", "") != "true")
+        //Otherwise no columns, so don't bother populating
+        return;
+
+    ClickableWidget *gameListItem = new ClickableWidget(listWidget);
+    gameListItem->setContentsMargins(0, 0, 20, 0);
+    gameListItem->setContextMenuPolicy(Qt::CustomContextMenu);
+    if (SETTINGS.value("List/theme","Light").toString() == "Dark")
+        gameListItem->setStyleSheet("color:#EEE;");
+
+    //Assign ROM data to widget for use in click events
+    gameListItem->setProperty("fileName", currentRom->fileName);
+    gameListItem->setProperty("directory", currentRom->directory);
+    if (currentRom->goodName == getTranslation("Unknown ROM") ||
+        currentRom->goodName == getTranslation("Requires catalog file"))
+        gameListItem->setProperty("search", currentRom->internalName);
+    else
+        gameListItem->setProperty("search", currentRom->goodName);
+    gameListItem->setProperty("romMD5", currentRom->romMD5);
+    gameListItem->setProperty("zipFile", currentRom->zipFile);
+
+    QGridLayout *gameListLayout = new QGridLayout(gameListItem);
+    gameListLayout->setColumnStretch(3, 1);
+
+    //Add image
+    if (SETTINGS.value("List/displaycover", "") == "true") {
+        QLabel *listImageLabel = new QLabel(gameListItem);
+        listImageLabel->setMinimumHeight(getImageSize("List").height());
+        listImageLabel->setMinimumWidth(getImageSize("List").width());
+
+        QPixmap image;
+
+        if (currentRom->imageExists)
+            image = currentRom->image.scaled(getImageSize("List"), Qt::KeepAspectRatio,
+                                            Qt::SmoothTransformation);
+        else {
+            if (ddEnabled && count == 0)
+                image = QPixmap(":/images/no-cart.png").scaled(getImageSize("List"), Qt::KeepAspectRatio,
+                                                                 Qt::SmoothTransformation);
+            else
+                image = QPixmap(":/images/not-found.png").scaled(getImageSize("List"), Qt::KeepAspectRatio,
+                                                                 Qt::SmoothTransformation);
+        }
+
+        listImageLabel->setPixmap(image);
+        listImageLabel->setAlignment(Qt::AlignCenter);
+        gameListLayout->addWidget(listImageLabel, 0, 1);
+    }
+
+    //Create text label
+    QLabel *listTextLabel = new QLabel("", gameListItem);
+    QString listText = "";
+
+    int i = 0;
+
+    foreach (QString current, visible)
+    {
+        QString addition = "";
+
+        if (i == 0 && SETTINGS.value("List/firstitemheader","true") == "true")
+            addition += "<h2 style='line-height:120%;margin:0;padding:0;'>";
+        else
+            addition += "<div style='line-height:120%;margin:0;padding:0;'><b>" + current + ":</b> ";
+
+        addition += getRomInfo(current, currentRom, true);
+
+        if (i == 0 && SETTINGS.value("List/firstitemheader","true") == "true")
+            addition += "</h2>";
+        else
+            addition += "</div>";
+
+        if (addition.right(12) != ":</b> </div>")
+            listText += addition;
+
+        i++;
+    }
+
+    if (ddEnabled && count == 0)
+        listText = "<h2>" + tr("No Cart") + "</h2>";
+
+    listTextLabel->setText(listText);
+    listTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+    listTextLabel->setWordWrap(true);
+    QFont font = listTextLabel->font();
+    font.setPointSize(getTextSize());
+    listTextLabel->setFont(font);
+    gameListLayout->addWidget(listTextLabel, 0, 3);
+
+    gameListLayout->setColumnMinimumWidth(0, 20);
+    gameListLayout->setColumnMinimumWidth(2, 10);
+    gameListItem->setLayout(gameListLayout);
+
+    if (count != 0) {
+        QFrame *separator = new QFrame();
+        separator->setFrameShape(QFrame::HLine);
+        separator->setStyleSheet("margin:0;padding:0;");
+        QPalette palette = separator->palette();
+        if (SETTINGS.value("List/theme","Light").toString() == "Dark")
+            palette.setColor(QPalette::Window, Qt::black);
+        else
+            palette.setColor(QPalette::Window, Qt::gray);
+        separator->setPalette(palette);
+        listLayout->addWidget(separator);
+    }
+
+    listLayout->addWidget(gameListItem);
+
+    connect(gameListItem, SIGNAL(singleClicked(QWidget*)), this, SLOT(highlightListWidget(QWidget*)));
+    connect(gameListItem, SIGNAL(doubleClicked(QWidget*)), parent, SLOT(launchRomFromWidget(QWidget*)));
+    connect(gameListItem, SIGNAL(arrowPressed(QWidget*, QString)), this, SLOT(selectNextRom(QWidget*, QString)));
+    connect(gameListItem, SIGNAL(enterPressed(QWidget*)), parent, SLOT(launchRomFromWidget(QWidget*)));
+    connect(gameListItem, SIGNAL(customContextMenuRequested(const QPoint &)), parent, SLOT(showRomMenu(const QPoint &)));
+}
+
+
+int ListView::getCurrentRom()
+{
+    return currentListRom;
+}
+
+
+QString ListView::getCurrentRomInfo(QString infoName)
+{
+    const char *property = infoName.toUtf8().constData();
+
+    if (listLayout->count() > currentListRom)
+        return listLayout->itemAt(currentListRom)->widget()->property(property).toString();
+    return "";
+}
+
+
+QWidget *ListView::getCurrentRomWidget()
+{
+    return listLayout->itemAt(currentListRom)->widget();
+}
+
+
+bool ListView::hasSelectedRom()
+{
+    return listCurrent;
+}
+
+
+void ListView::highlightListWidget(QWidget *current)
+{
+    current->setFocus();
+
+    QLayoutItem *listItem;
+    for (int item = 0; (listItem = listLayout->itemAt(item)) != NULL; item++)
+    {
+        if (listItem->widget() == current)
+            currentListRom = item;
+    }
+
+    //Give current left margin to stand out
+    //Delay with QTimer so right-click menu appears correctly
+    QTimer::singleShot(5, this, SLOT(highlightListWidgetSetMargin()));
+
+    listCurrent = true;
+    emit listItemSelected(true);
+}
+
+
+void ListView::highlightListWidgetSetMargin()
+{
+    //Reset all margins
+    QLayoutItem *listItem;
+    for (int item = 0; (listItem = listLayout->itemAt(item)) != NULL; item++)
+        listItem->widget()->setContentsMargins(0, 0, 20, 0);
+
+    getCurrentRomWidget()->setContentsMargins(20, 0, 0, 0);
+}
+
+
+void ListView::keyPressEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Down && listLayout->count() > 0) {
+        highlightListWidget(listLayout->itemAt(0)->widget());
+        ensureWidgetVisible(listLayout->itemAt(0)->widget());
+    } else
+        QScrollArea::keyPressEvent(event);
+}
+
+
+void ListView::resetView()
+{
+    QLayoutItem *listItem;
+    while ((listItem = listLayout->takeAt(0)) != NULL)
+    {
+        delete listItem->widget();
+        delete listItem;
+    }
+
+    listCurrent = false;
+}
+
+
+void ListView::saveListPosition()
+{
+    positionx = horizontalScrollBar()->value();
+    positiony = verticalScrollBar()->value();
+
+    if (listCurrent)
+        savedListRom = currentListRom;
+    else
+        savedListRom = -1;
+    savedListRomFilename = getCurrentRomInfo("fileName");
+}
+
+
+void ListView::selectNextRom(QWidget* current, QString keypress)
+{
+    int offset = 0;
+    if (keypress == "UP" || keypress == "LEFT")
+        offset = -2;
+    else if (keypress == "DOWN" || keypress == "RIGHT")
+        offset = 2;
+
+    QLayoutItem *listItem;
+    for (int item = 0; (listItem = listLayout->itemAt(item)) != NULL; item++)
+    {
+        if (listItem->widget() == current && item + offset >= 0 && listLayout->itemAt(item + offset) != NULL) {
+            ensureWidgetVisible(listLayout->itemAt(item + offset)->widget());
+            highlightListWidget(listLayout->itemAt(item + offset)->widget());
+        }
+    }
+}
+
+
+void ListView::setListBackground()
+{
+    if (SETTINGS.value("List/theme","Light").toString() == "Dark")
+        setStyleSheet("#listView { border: none; background: #222; } #listWidget { background: transparent; }");
+    else
+        setStyleSheet("#listView { border: none; background: #FFF; } #listWidget { background: transparent; }");
+}
+
+
+void ListView::setListPosition()
+{
+    horizontalScrollBar()->setValue(positionx);
+    verticalScrollBar()->setValue(positiony);
+
+    //Restore selected ROM if it is in the same position
+    if (savedListRom != -1 && listLayout->count() > savedListRom) {
+        QWidget *checkWidget = listLayout->itemAt(savedListRom)->widget();
+        if (checkWidget->property("fileName").toString() == savedListRomFilename)
+            highlightListWidget(checkWidget);
+    }
+}
diff --git a/src/emulatorhandler.h b/src/views/listview.h
similarity index 63%
copy from src/emulatorhandler.h
copy to src/views/listview.h
index 243fd54..22d2c7e 100644
--- a/src/emulatorhandler.h
+++ b/src/views/listview.h
@@ -29,41 +29,54 @@
  *
  ***/
 
-#ifndef EMULATORHANDLER_H
-#define EMULATORHANDLER_H
+#ifndef LISTVIEW_H
+#define LISTVIEW_H
 
-#include <QObject>
+#include <QScrollArea>
 
-class QDir;
-class QProcess;
+class QVBoxLayout;
+struct Rom;
 
 
-class EmulatorHandler : public QObject
+class ListView : public QScrollArea
 {
     Q_OBJECT
+
 public:
-    explicit EmulatorHandler(QWidget *parent = 0);
-    void startEmulator(QDir romDir, QString romFileName, QString zipFileName = "");
-    void stopEmulator();
+    explicit ListView(QWidget *parent = 0);
+    void addToListView(Rom *currentRom, int count, bool ddEnabled);
+    int getCurrentRom();
+    QString getCurrentRomInfo(QString infoName);
+    QWidget *getCurrentRomWidget();
+    bool hasSelectedRom();
+    void resetView();
+    void saveListPosition();
+    void setListBackground();
 
-    QString lastOutput;
+protected:
+    void keyPressEvent(QKeyEvent *event);
 
 signals:
-    void finished();
-    void showLog();
-    void started();
+    void listItemSelected(bool active);
 
 private:
-    QStringList parseArgString(QString argString);
+    int currentListRom;
+    bool listCurrent;
+    int savedListRom;
+    QString savedListRomFilename;
+    int positionx;
+    int positiony;
 
-    QProcess *emulatorProc;
+    QVBoxLayout *listLayout;
+    QWidget *listWidget;
     QWidget *parent;
 
 private slots:
-    void checkStatus(int status);
-    void cleanTemp();
-    void emitFinished();
-    void readOutput();
+    void highlightListWidget(QWidget *current);
+    void highlightListWidgetSetMargin();
+    void selectNextRom(QWidget *current, QString keypress);
+    void setListPosition();
+
 };
 
-#endif // EMULATORHANDLER_H
+#endif // LISTVIEW_H
diff --git a/src/views/tableview.cpp b/src/views/tableview.cpp
new file mode 100644
index 0000000..22bfa83
--- /dev/null
+++ b/src/views/tableview.cpp
@@ -0,0 +1,353 @@
+/***
+ * Copyright (c) 2013, Dan Hasting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the organization nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***/
+
+#include "tableview.h"
+
+#include "../global.h"
+#include "../common.h"
+
+#include "widgets/treewidgetitem.h"
+
+#include <QFile>
+#include <QFileInfo>
+#include <QGridLayout>
+#include <QHeaderView>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QScrollBar>
+
+
+TableView::TableView(QWidget *parent) : QTreeWidget(parent)
+{ 
+    this->parent = parent;
+
+    setWordWrap(false);
+    setAllColumnsShowFocus(true);
+    setRootIsDecorated(false);
+    setSortingEnabled(true);
+    setContextMenuPolicy(Qt::CustomContextMenu);
+    setStyleSheet("QTreeView { border: none; } QTreeView::item { height: 25px; }");
+
+    headerView = new QHeaderView(Qt::Horizontal, this);
+    setHeader(headerView);
+    setHidden(true);
+
+    connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), parent, SLOT(showRomMenu(const QPoint &)));
+    connect(headerView, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
+            this, SLOT(saveSortOrder(int,Qt::SortOrder)));
+}
+
+
+void TableView::addNoCartRow()
+{
+    QStringList visible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
+
+    fileItem = new TreeWidgetItem(this);
+
+    if (visible.at(0) == "Game Cover") {
+        fileItem->setText(6, " " + tr("No Cart"));
+        fileItem->setForeground(6, QBrush(Qt::gray));
+    } else {
+        fileItem->setText(5, " " + tr("No Cart"));
+        fileItem->setForeground(5, QBrush(Qt::gray));
+    }
+    addTopLevelItem(fileItem);
+}
+
+
+void TableView::addToTableView(Rom *currentRom)
+{
+    QStringList visible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
+
+    if (visible.join("") == "") //Otherwise no columns, so don't bother populating
+        return;
+
+    fileItem = new TreeWidgetItem(this);
+
+    //Filename for launching ROM
+    fileItem->setText(0, currentRom->fileName);
+
+    //Directory ROM is located in
+    fileItem->setText(1, currentRom->directory);
+
+    //GoodName or Internal Name for searching
+    if (currentRom->goodName == getTranslation("Unknown ROM") ||
+        currentRom->goodName == getTranslation("Requires catalog file"))
+        fileItem->setText(2, currentRom->internalName);
+    else
+        fileItem->setText(2, currentRom->goodName);
+
+    //MD5 for cache info
+    fileItem->setText(3, currentRom->romMD5.toLower());
+
+    //Zip file
+    fileItem->setText(4, currentRom->zipFile);
+
+    int i = 5, c = 0;
+    bool addImage = false;
+
+    foreach (QString current, visible)
+    {
+        QString text = getRomInfo(current, currentRom);
+        fileItem->setText(i, text);
+
+        if (current == "GoodName" || current == "Game Title") {
+            if (text == getTranslation("Unknown ROM") ||
+                text == getTranslation("Requires catalog file") ||
+                text == getTranslation("Not found")) {
+                fileItem->setForeground(i, QBrush(Qt::gray));
+                fileItem->setData(i, Qt::UserRole, "ZZZ"); //end of sorting
+            } else
+                fileItem->setData(i, Qt::UserRole, text);
+        }
+
+        if (current == "Size")
+            fileItem->setData(i, Qt::UserRole, currentRom->sortSize);
+
+        if (current == "Release Date")
+            fileItem->setData(i, Qt::UserRole, currentRom->sortDate);
+
+        if (current == "Game Cover") {
+            c = i;
+            addImage = true;
+        }
+
+        QStringList center, right;
+
+        center << "MD5" << "CRC1" << "CRC2" << "Rumble" << "ESRB" << "Genre" << "Publisher" << "Developer";
+        right << "Size" << "Players" << "Save Type" << "Release Date" << "Rating";
+
+        if (center.contains(current))
+            fileItem->setTextAlignment(i, Qt::AlignHCenter | Qt::AlignVCenter);
+        else if (right.contains(current))
+            fileItem->setTextAlignment(i, Qt::AlignRight | Qt::AlignVCenter);
+
+        i++;
+    }
+
+    addTopLevelItem(fileItem);
+
+
+    if (currentRom->imageExists && addImage) {
+        QPixmap image(currentRom->image.scaled(getImageSize("Table"), Qt::KeepAspectRatio,
+                                              Qt::SmoothTransformation));
+
+        QWidget *imageContainer = new QWidget(this);
+        QGridLayout *imageGrid = new QGridLayout(imageContainer);
+        QLabel *imageLabel = new QLabel(imageContainer);
+
+        imageLabel->setPixmap(image);
+        imageGrid->addWidget(imageLabel, 1, 1);
+        imageGrid->setColumnStretch(0, 1);
+        imageGrid->setColumnStretch(2, 1);
+        imageGrid->setRowStretch(0, 1);
+        imageGrid->setRowStretch(2, 1);
+        imageGrid->setContentsMargins(0,0,0,0);
+
+        imageContainer->setLayout(imageGrid);
+
+        setItemWidget(fileItem, c, imageContainer);
+    }
+}
+
+
+QString TableView::getCurrentRomInfo(QString infoName)
+{
+    int index = getTableDataIndexFromName(infoName);
+    return QVariant(currentItem()->data(index, 0)).toString();
+}
+
+
+bool TableView::hasSelectedRom()
+{
+    return currentItem() != NULL;
+}
+
+
+void TableView::keyPressEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
+        emit enterPressed();
+    else if (event->key() == Qt::Key_Down && selectedItems().count() == 0) {
+        setCurrentItem(topLevelItem(0));
+        emit tableActive();
+    } else if (event->key() == Qt::Key_Down  && selectedItems().count() == 1) {
+        int current = indexOfTopLevelItem(selectedItems().at(0));
+        if (current < topLevelItemCount() - 1)
+            setCurrentItem(topLevelItem(current + 1));
+    } else if (event->key() == Qt::Key_Up  && selectedItems().count() == 1) {
+        int current = indexOfTopLevelItem(selectedItems().at(0));
+        if (current > 0)
+            setCurrentItem(topLevelItem(current - 1));
+    } else
+        QTreeWidget::keyPressEvent(event);
+}
+
+
+void TableView::resetView(bool imageUpdated)
+{
+    QStringList tableVisible = SETTINGS.value("Table/columns", "Filename|Size").toString().split("|");
+
+    QStringList translations;
+    foreach (QString header, tableVisible) translations << getTranslation(header);
+
+    int hidden = 5;
+
+    saveColumnWidths();
+    QStringList widths = SETTINGS.value("Table/width", "").toString().split("|");
+
+    headerLabels.clear();
+    headerLabels << "" << "" << "" << "" << "" << translations; //First 5 blank for hidden columns
+
+    //Remove Game Cover title for aesthetics
+    for (int i = 0; i < headerLabels.size(); i++)
+        if (headerLabels.at(i) == getTranslation("Game Cover")) headerLabels.replace(i, "");
+
+    setColumnCount(headerLabels.size());
+    setHeaderLabels(headerLabels);
+    headerView->setSortIndicatorShown(false);
+
+    int height = 0, width = 0;
+    if (tableVisible.contains("Game Cover")) {
+        //Get optimal height/width for cover column
+        height = getImageSize("Table").height() * 1.1;
+        width = getImageSize("Table").width() * 1.2;
+
+        setStyleSheet("QTreeView { border: none; } QTreeView::item { height: "
+                               + QString::number(height) + "px; }");
+    } else
+        setStyleSheet("QTreeView { border: none; } QTreeView::item { height: 25px; }");
+
+    QStringList sort = SETTINGS.value("Table/sort", "").toString().split("|");
+    if (sort.size() == 2) {
+        if (sort[1] == "descending")
+            headerView->setSortIndicator(tableVisible.indexOf(sort[0]) + hidden, Qt::DescendingOrder);
+        else
+            headerView->setSortIndicator(tableVisible.indexOf(sort[0]) + hidden, Qt::AscendingOrder);
+    }
+
+    setColumnHidden(0, true); //Hidden filename for launching emulator
+    setColumnHidden(1, true); //Hidden directory of ROM location
+    setColumnHidden(2, true); //Hidden goodname for searching
+    setColumnHidden(3, true); //Hidden md5 for cache info
+    setColumnHidden(4, true); //Hidden column for zip file
+
+    int i = hidden;
+    foreach (QString current, tableVisible)
+    {
+        if (i == hidden) {
+            int c = i;
+            if (current == "Game Cover") c++; //If first column is game cover, use next column
+
+            if (SETTINGS.value("Table/stretchfirstcolumn", "true") == "true")
+#if QT_VERSION >= 0x050000
+                header()->setSectionResizeMode(c, QHeaderView::Stretch);
+#else
+                header()->setResizeMode(c, QHeaderView::Stretch);
+#endif
+            else
+#if QT_VERSION >= 0x050000
+                header()->setSectionResizeMode(c, QHeaderView::Interactive);
+#else
+                header()->setResizeMode(c, QHeaderView::Interactive);
+#endif
+        }
+
+        if (widths.size() == tableVisible.size())
+            setColumnWidth(i, widths[i - hidden].toInt());
+        else
+            setColumnWidth(i, getDefaultWidth(current, width));
+
+        //Overwrite saved value if switching image sizes
+        if (imageUpdated && current == "Game Cover")
+            setColumnWidth(i, width);
+
+        i++;
+    }
+}
+
+
+void TableView::saveColumnWidths()
+{
+    QStringList widths;
+
+    for (int i = 5; i < columnCount(); i++)
+    {
+        widths << QString::number(columnWidth(i));
+    }
+
+    if (widths.size() > 0)
+        SETTINGS.setValue("Table/width", widths.join("|"));
+}
+
+
+void TableView::saveSortOrder(int column, Qt::SortOrder order)
+{
+    QString columnName = headerLabels.value(column);
+
+    if (order == Qt::DescendingOrder)
+        SETTINGS.setValue("Table/sort", columnName + "|descending");
+    else
+        SETTINGS.setValue("Table/sort", columnName + "|ascending");
+}
+
+
+void TableView::saveTablePosition()
+{
+    positionx = horizontalScrollBar()->value();
+    positiony = verticalScrollBar()->value();
+
+    if (selectedItems().count() > 0) {
+        int index = getTableDataIndexFromName("fileName");
+        savedTableRom = indexOfTopLevelItem(selectedItems().at(0));
+        savedTableRomFilename = QVariant(topLevelItem(savedTableRom)->data(index, 0)).toString();
+    } else {
+        savedTableRom = -1;
+        savedTableRomFilename = "";
+    }
+}
+
+
+void TableView::setTablePosition()
+{
+    horizontalScrollBar()->setValue(positionx);
+    verticalScrollBar()->setValue(positiony);
+
+    //Restore selected ROM if it is in the same position
+    if (savedTableRom >= 0) {
+        int index = getTableDataIndexFromName("fileName");
+        QString checkFilename = QVariant(topLevelItem(savedTableRom)->data(index, 0)).toString();
+        if (savedTableRomFilename == checkFilename) {
+            setCurrentItem(topLevelItem(savedTableRom));
+            emit tableActive();
+        }
+    }
+}
diff --git a/src/emulatorhandler.h b/src/views/tableview.h
similarity index 67%
rename from src/emulatorhandler.h
rename to src/views/tableview.h
index 243fd54..5208ec5 100644
--- a/src/emulatorhandler.h
+++ b/src/views/tableview.h
@@ -29,41 +29,50 @@
  *
  ***/
 
-#ifndef EMULATORHANDLER_H
-#define EMULATORHANDLER_H
+#ifndef TABLEVIEW_H
+#define TABLEVIEW_H
 
-#include <QObject>
+#include <QTreeWidget>
 
-class QDir;
-class QProcess;
+class TreeWidgetItem;
+struct Rom;
 
 
-class EmulatorHandler : public QObject
+class TableView : public QTreeWidget
 {
     Q_OBJECT
+
 public:
-    explicit EmulatorHandler(QWidget *parent = 0);
-    void startEmulator(QDir romDir, QString romFileName, QString zipFileName = "");
-    void stopEmulator();
+    explicit TableView(QWidget *parent = 0);
+    void addNoCartRow();
+    void addToTableView(Rom *currentRom);
+    QString getCurrentRomInfo(QString infoName);
+    bool hasSelectedRom();
+    void resetView(bool imageUpdated);
+    void saveColumnWidths();
+    void saveTablePosition();
 
-    QString lastOutput;
+protected:
+    void keyPressEvent(QKeyEvent *event);
 
 signals:
-    void finished();
-    void showLog();
-    void started();
+    void enterPressed();
+    void tableActive();
 
 private:
-    QStringList parseArgString(QString argString);
-
-    QProcess *emulatorProc;
+    int positionx;
+    int positiony;
+    int savedTableRom;
+    QString savedTableRomFilename;
+    QStringList headerLabels;
+    QHeaderView *headerView;
     QWidget *parent;
+    TreeWidgetItem *fileItem;
 
 private slots:
-    void checkStatus(int status);
-    void cleanTemp();
-    void emitFinished();
-    void readOutput();
+    void saveSortOrder(int column, Qt::SortOrder order);
+    void setTablePosition();
+
 };
 
-#endif // EMULATORHANDLER_H
+#endif // TABLEVIEW_H
diff --git a/src/clickablewidget.cpp b/src/views/widgets/clickablewidget.cpp
similarity index 74%
rename from src/clickablewidget.cpp
rename to src/views/widgets/clickablewidget.cpp
index 71cde07..ca938f8 100644
--- a/src/clickablewidget.cpp
+++ b/src/views/widgets/clickablewidget.cpp
@@ -36,12 +36,30 @@
 
 ClickableWidget::ClickableWidget(QWidget *parent) : QWidget(parent)
 {
+    setFocusPolicy(Qt::StrongFocus);
+}
+
+
+void ClickableWidget::keyPressEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Up)
+        emit arrowPressed(this, "UP");
+    else if (event->key() == Qt::Key_Down)
+        emit arrowPressed(this, "DOWN");
+    else if (event->key() == Qt::Key_Left)
+        emit arrowPressed(this, "LEFT");
+    else if (event->key() == Qt::Key_Right)
+        emit arrowPressed(this, "RIGHT");
+    else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
+        emit enterPressed(this);
+    else
+        QWidget::keyPressEvent(event);
 }
 
 
 void ClickableWidget::mousePressEvent(QMouseEvent *event)
 {
-    if (event->button() == Qt::LeftButton)
+    if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton)
         emit singleClicked(this);
 }
 
diff --git a/src/clickablewidget.h b/src/views/widgets/clickablewidget.h
similarity index 93%
rename from src/clickablewidget.h
rename to src/views/widgets/clickablewidget.h
index 7576965..ef02843 100644
--- a/src/clickablewidget.h
+++ b/src/views/widgets/clickablewidget.h
@@ -44,10 +44,13 @@ public:
     explicit ClickableWidget(QWidget *parent = 0);
 
 protected:
+    void keyPressEvent(QKeyEvent* event);
     void mousePressEvent(QMouseEvent *event);
     void mouseDoubleClickEvent(QMouseEvent *event);
 
 signals:
+    void arrowPressed(QWidget *current, QString keypress);
+    void enterPressed(QWidget *current);
     void singleClicked(QWidget *current);
     void doubleClicked(QWidget *current);
 };
diff --git a/src/treewidgetitem.cpp b/src/views/widgets/treewidgetitem.cpp
similarity index 100%
rename from src/treewidgetitem.cpp
rename to src/views/widgets/treewidgetitem.cpp
diff --git a/src/treewidgetitem.h b/src/views/widgets/treewidgetitem.h
similarity index 100%
rename from src/treewidgetitem.h
rename to src/views/widgets/treewidgetitem.h

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus-qt.git



More information about the Pkg-games-commits mailing list