The branch, dharma has been updated
       via  d754deb91e502c1eb99bce506c5913d0b64daa9a (commit)
      from  8fd256e7e7eb4b100a79667383e4cd52b584f79a (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=d754deb91e502c1eb99bce506c5913d0b64daa9a

commit d754deb91e502c1eb99bce506c5913d0b64daa9a
Author: amet <[email protected]>
Date:   Tue Apr 19 13:03:17 2011 +0400

    [script.moviequiz] -v0.3.2
    
    - Improved support for XBMC Eden nightly builds
    - Added support for Cinema Experience integration
    - Use fanart instead of movie clips where relevant
    - Improved data selection for some questions
    - Added icons for replaying movie clip and exiting the game
    - Removed 'When was episode first aired?' question as it's too difficult
    - Removed French translation as it was outdated

diff --git a/script.moviequiz/addon.xml b/script.moviequiz/addon.xml
index 7e05626..14fb22c 100644
--- a/script.moviequiz/addon.xml
+++ b/script.moviequiz/addon.xml
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="script.moviequiz"
        name="Movie Quiz"
-       version="0.3.1"
+       version="0.3.2"
        provider-name="twinther [[email protected]]">
     <requires>
         <import addon="xbmc.python"/>
         <import addon="script.module.pysqlite" version="2.5.6"/>
         <import addon="script.module.myconnpy" version="0.3.2"/>
+        <import addon="script.module.elementtree" version="1.2.7"/>
     </requires>
     <extension point="xbmc.python.script" library="addon.py"/>
     <extension point="xbmc.addon.metadata">
diff --git a/script.moviequiz/changelog.txt b/script.moviequiz/changelog.txt
index 844e1ba..9e02fcd 100644
--- a/script.moviequiz/changelog.txt
+++ b/script.moviequiz/changelog.txt
@@ -1,3 +1,12 @@
+[B]Version 0.3.2 - 2011-04-17[/B]
+- Improved support for XBMC Eden nightly builds
+- Added support for Cinema Experience integration
+- Use fanart instead of movie clips where relevant
+- Improved data selection for some questions
+- Added icons for replaying movie clip and exiting the game
+- Removed 'When was episode first aired?' question as it's too difficult
+- Removed French translation as it was outdated
+
 [B]Version 0.3.1 - 2011-03-27[/B]
 - Added support for XBMC Eden nightly builds
 - Fixed Imdb data download
diff --git a/script.moviequiz/quizlib/db.py b/script.moviequiz/quizlib/db.py
index 8f1782c..07fa07b 100644
--- a/script.moviequiz/quizlib/db.py
+++ b/script.moviequiz/quizlib/db.py
@@ -1,8 +1,17 @@
 from elementtree import ElementTree
-from pysqlite2 import dbapi2 as sqlite3
+from xml.parsers.expat import ExpatError
+
 import os
 import xbmc
 import mysql.connector
+import glob
+
+try:
+    # Used by Eden/external python
+    from sqlite3 import dbapi2 as sqlite3
+except:
+    # Used by Dharma/internal python
+    from pysqlite2 import dbapi2 as sqlite3
 
 __author__ = 'twinther'
 
@@ -154,10 +163,9 @@ class SQLiteDatabase(Database):
         found = True
         db_file = None
 
-        candidates = [
-            'MyVideos48.db', # Eden
-            'MyVideos34.db'  # Dharma
-        ]
+        # Find newest MyVideos.db and use that
+        candidates = glob.glob(settings['host'] + '/MyVideos*.db')
+        list.sort(candidates, reverse=True)
         if settings.has_key('name') and settings['name'] is not None:
             candidates.insert(0, settings['name'] + '.db') # defined in 
settings
 
@@ -172,7 +180,7 @@ class SQLiteDatabase(Database):
             return
 
         xbmc.log("Connecting to SQLite database file: %s" % db_file)
-        self.conn = sqlite3.connect(db_file)
+        self.conn = sqlite3.connect(db_file, check_same_thread = False)
         self.conn.row_factory = self._sqlite_dict_factory
         xbmc.log("SQLiteDatabase opened")
 
@@ -224,19 +232,23 @@ def _loadSettings():
     advancedSettings = 
xbmc.translatePath('special://userdata/advancedsettings.xml')
     if os.path.exists(advancedSettings):
         f = open(advancedSettings)
-        doc = ElementTree.fromstring(f.read())
+        xml = f.read()
         f.close()
-
-        if doc.findtext('videodatabase/type') is not None:
-            settings['type'] = doc.findtext('videodatabase/type')
-        if doc.findtext('videodatabase/host') is not None:
-            settings['host'] = doc.findtext('videodatabase/host')
-        if doc.findtext('videodatabase/name') is not None:
-            settings['name'] = doc.findtext('videodatabase/name')
-        if doc.findtext('videodatabase/user') is not None:
-            settings['user'] = doc.findtext('videodatabase/user')
-        if doc.findtext('videodatabase/pass') is not None:
-            settings['pass'] = doc.findtext('videodatabase/pass')
+        try:
+            doc = ElementTree.fromstring(xml)
+
+            if doc.findtext('videodatabase/type') is not None:
+                settings['type'] = doc.findtext('videodatabase/type')
+            if doc.findtext('videodatabase/host') is not None:
+                settings['host'] = doc.findtext('videodatabase/host')
+            if doc.findtext('videodatabase/name') is not None:
+                settings['name'] = doc.findtext('videodatabase/name')
+            if doc.findtext('videodatabase/user') is not None:
+                settings['user'] = doc.findtext('videodatabase/user')
+            if doc.findtext('videodatabase/pass') is not None:
+                settings['pass'] = doc.findtext('videodatabase/pass')
+        except ExpatError:
+           xbmc.log("Unable to parse advancedsettings.xml")
 
     return settings
-    
\ No newline at end of file
+    
diff --git a/script.moviequiz/quizlib/gui.py b/script.moviequiz/quizlib/gui.py
index f09031c..f89f59f 100644
--- a/script.moviequiz/quizlib/gui.py
+++ b/script.moviequiz/quizlib/gui.py
@@ -1,5 +1,7 @@
 import threading
 import os
+import re
+
 import xbmc
 import xbmcgui
 
@@ -10,6 +12,10 @@ from strings import *
 
 __author__ = 'twinther'
 
+# Constants from [xbmc]/xbmc/guilib/Key.h
+ACTION_PARENT_DIR = 9
+ACTION_PREVIOUS_MENU = 10
+
 class MenuGui(xbmcgui.WindowXML):
     C_MENU_MOVIE_QUIZ = 4001
     C_MENU_TVSHOW_QUIZ = 4002
@@ -78,7 +84,7 @@ class MenuGui(xbmcgui.WindowXML):
         self.getControl(self.C_MENU_COLLECTION_TRIVIA).setLabel(label)
 
     def onAction(self, action):
-        if action.getId() == 9 or action.getId() == 10:
+        if action.getId() == ACTION_PARENT_DIR or action.getId() == 
ACTION_PREVIOUS_MENU:
             self.close()
 
     def onClick(self, controlId):
@@ -119,6 +125,8 @@ class MenuGui(xbmcgui.WindowXML):
 class QuizGui(xbmcgui.WindowXML):
     C_MAIN_FIRST_ANSWER = 4000
     C_MAIN_LAST_ANSWER = 4003
+    C_MAIN_REPLAY = 4010
+    C_MAIN_EXIT = 4011
     C_MAIN_CORRECT_SCORE = 4101
     C_MAIN_INCORRECT_SCORE = 4103
     C_MAIN_QUESTION_COUNT = 4104
@@ -138,6 +146,7 @@ class QuizGui(xbmcgui.WindowXML):
     C_MAIN_CORRECT_VISIBILITY = 5002
     C_MAIN_INCORRECT_VISIBILITY = 5003
     C_MAIN_LOADING_VISIBILITY = 5005
+    C_MAIN_REPLAY_BUTTON_VISIBILITY = 5007
 
 
     def __init__(self, xmlFilename, scriptPath, addon, type, questionLimit = 
-1, maxRating = None, interactive = True):
@@ -149,6 +158,12 @@ class QuizGui(xbmcgui.WindowXML):
         self.maxRating = maxRating
         self.interactive = interactive
 
+        path = self.addon.getAddonInfo('path')
+        if self.type == question.TYPE_TV:
+            self.defaultBackground = os.path.join(path, 'resources', 'skins', 
'Default', 'media', 'quiz-background-tvshows.png')
+        else:
+            self.defaultBackground = os.path.join(path, 'resources', 'skins', 
'Default', 'media', 'quiz-background.png')
+
         self.database = db.connect()
         self.player = player.TenSecondPlayer(database=self.database)
         self.question = question.Question(self.database, None, None, None)
@@ -156,7 +171,9 @@ class QuizGui(xbmcgui.WindowXML):
         self.score = {'correct': 0, 'wrong': 0}
 
         self.maxRating = None
-        if self.type == question.TYPE_MOVIE and 
self.addon.getSetting('movie.rating.limit.enabled') == 'true':
+        if maxRating is not None:
+            self.maxRating = maxRating
+        elif self.type == question.TYPE_MOVIE and 
self.addon.getSetting('movie.rating.limit.enabled') == 'true':
             self.maxRating = self.addon.getSetting('movie.rating.limit')
         elif self.type == question.TYPE_TV and 
self.addon.getSetting('tvshow.rating.limit.enabled') == 'true':
             self.maxRating = self.addon.getSetting('tvshow.rating.limit')
@@ -166,35 +183,40 @@ class QuizGui(xbmcgui.WindowXML):
         try :
             xbmcgui.lock()
             if self.type == question.TYPE_TV:
-                self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setVisible(False)
+                
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.defaultBackground)
         finally:
             xbmcgui.unlock()
 
         self._setup_question()
 
     def close(self):
-        if hasattr(self, 'player') and self.player.isPlaying():
+        if self.player and self.player.isPlaying():
             self.player.stop()
         # TODO self.database.close()
         xbmcgui.WindowXML.close(self)
         
     def onAction(self, action):
-        if action.getId() == 9 or action.getId() == 10:
+        if action.getId() == ACTION_PARENT_DIR or action.getId() == 
ACTION_PREVIOUS_MENU:
             self._game_over()
             self.close()
 
+
     def onClick(self, controlId):
         if not self.interactive:
             return # ignore
 
-        if hasattr(self, 'question') and (controlId >= 
self.C_MAIN_FIRST_ANSWER  or controlId <= self.C_MAIN_LAST_ANSWER):
+        if self.question and (controlId >= self.C_MAIN_FIRST_ANSWER and 
controlId <= self.C_MAIN_LAST_ANSWER):
             answer = self.question.getAnswer(controlId - 
self.C_MAIN_FIRST_ANSWER)
             self._handle_answer(answer)
             self._setup_question()
+        elif controlId == self.C_MAIN_EXIT:
+            self._game_over()
+        elif controlId == self.C_MAIN_REPLAY:
+            self.player.replay()
 
     #noinspection PyUnusedLocal
     def onFocus(self, controlId):
-        self._update_thumb()
+        self._update_thumb(controlId)
 
     def _game_over(self):
         if self.interactive:
@@ -225,10 +247,10 @@ class QuizGui(xbmcgui.WindowXML):
             button = self.getControl(self.C_MAIN_FIRST_ANSWER + idx)
             if idx >= len(answers):
                 button.setLabel('')
-                button.setEnabled(False)
+                button.setVisible(False)
             else:
                 button.setLabel(answers[idx].text, textColor='0xFFFFFFFF')
-                button.setEnabled(True)
+                button.setVisible(True)
 
             if not self.interactive and answers[idx].correct:
                 # highlight correct answer
@@ -237,50 +259,40 @@ class QuizGui(xbmcgui.WindowXML):
         self._update_thumb()
         self._update_stats()
 
+        print self.question.getFanartFile()
+        if self.question.getFanartFile() is not None and 
os.path.exists(self.question.getFanartFile()):
+            
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.question.getFanartFile())
+        else:
+            
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.defaultBackground)
+
         correctAnswer = self.question.getCorrectAnswer()
         if self.question.getDisplay() == question.DISPLAY_VIDEO:
-            self.show(self.C_MAIN_VIDEO_VISIBILITY)
-            self.hide(self.C_MAIN_PHOTO_VISIBILITY)
-            self.hide(self.C_MAIN_QUOTE_VISIBILITY)
-            self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+            self._changeVisibility(video = True)
             xbmc.sleep(1500) # give skin animation time to execute
             self.player.playWindowed(self.question.getVideoFile(), 
correctAnswer.idFile)
 
         elif self.question.getDisplay() == question.DISPLAY_PHOTO:
             
self.getControl(self.C_MAIN_PHOTO).setImage(self.question.getPhotoFile())
-
-            self.hide(self.C_MAIN_VIDEO_VISIBILITY)
-            self.show(self.C_MAIN_PHOTO_VISIBILITY)
-            self.hide(self.C_MAIN_QUOTE_VISIBILITY)
-            self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+            self._changeVisibility(photo = True)
 
         elif self.question.getDisplay() == question.DISPLAY_QUOTE:
-            
self.getControl(self.C_MAIN_QUOTE_LABEL).setText(self.question.getQuoteText())
-
-            self.hide(self.C_MAIN_VIDEO_VISIBILITY)
-            self.hide(self.C_MAIN_PHOTO_VISIBILITY)
-            self.show(self.C_MAIN_QUOTE_VISIBILITY)
-            self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+            quoteText = self.question.getQuoteText()
+            quoteText = self._obfuscateQuote(quoteText)
+            self.getControl(self.C_MAIN_QUOTE_LABEL).setText(quoteText)
+            self._changeVisibility(quote = True)
 
         elif self.question.getDisplay() == question.DISPLAY_NONE:
-            self.hide(self.C_MAIN_VIDEO_VISIBILITY)
-            self.hide(self.C_MAIN_PHOTO_VISIBILITY)
-            self.hide(self.C_MAIN_QUOTE_VISIBILITY)
-            self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+            self._changeVisibility()
 
         elif self.question.getDisplay() == question.DISPLAY_THREE_PHOTOS:
             
self.getControl(self.C_MAIN_PHOTO_1).setImage(self.question.getPhotoFile(0))
             
self.getControl(self.C_MAIN_PHOTO_2).setImage(self.question.getPhotoFile(1))
             
self.getControl(self.C_MAIN_PHOTO_3).setImage(self.question.getPhotoFile(2))
-
-            self.hide(self.C_MAIN_VIDEO_VISIBILITY)
-            self.hide(self.C_MAIN_PHOTO_VISIBILITY)
-            self.hide(self.C_MAIN_QUOTE_VISIBILITY)
-            self.show(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+            self._changeVisibility(threePhotos = True)
 
         if not self.interactive:
             # answers correctly in ten seconds
-            threading.Timer(3.0, self._answer_correctly).start()
+            threading.Timer(10.0, self._answer_correctly).start()
 
         self.getControl(self.C_MAIN_LOADING_VISIBILITY).setVisible(False)
 
@@ -311,10 +323,10 @@ class QuizGui(xbmcgui.WindowXML):
     def _handle_answer(self, answer):
         if answer is not None and answer.correct:
             self.score['correct'] += 1
-            self.show(self.C_MAIN_CORRECT_VISIBILITY)
+            self.getControl(self.C_MAIN_CORRECT_VISIBILITY).setVisible(False)
         else:
             self.score['wrong'] += 1
-            self.show(self.C_MAIN_INCORRECT_VISIBILITY)
+            self.getControl(self.C_MAIN_INCORRECT_VISIBILITY).setVisible(False)
 
         if self.player.isPlaying():
             self.player.stop()
@@ -328,6 +340,10 @@ class QuizGui(xbmcgui.WindowXML):
                 else:
                     self.getControl(self.C_MAIN_FIRST_ANSWER + 
idx).setLabel(textColor='0x88888888')
 
+            if self.question.getDisplay() == question.DISPLAY_QUOTE:
+                # Display non-obfuscated quote text
+                
self.getControl(self.C_MAIN_QUOTE_LABEL).setText(self.question.getQuoteText())
+
             xbmc.sleep(3000)
 
     def _update_stats(self):
@@ -341,11 +357,12 @@ class QuizGui(xbmcgui.WindowXML):
             label.setLabel('')
 
 
-    def _update_thumb(self):
+    def _update_thumb(self, controlId = None):
         if self.question is None:
             return # not initialized yet
 
-        controlId = self.getFocusId()
+        if controlId is None:
+            controlId = self.getFocusId()
         if controlId >= self.C_MAIN_FIRST_ANSWER or controlId <= 
self.C_MAIN_LAST_ANSWER:
             answer = self.question.getAnswer(controlId - 
self.C_MAIN_FIRST_ANSWER)
             coverImage = self.getControl(self.C_MAIN_COVER_IMAGE)
@@ -360,14 +377,34 @@ class QuizGui(xbmcgui.WindowXML):
                 coverImage.setVisible(False)
 
     def _hide_icons(self):
-        self.hide(self.C_MAIN_CORRECT_VISIBILITY)
-        self.hide(self.C_MAIN_INCORRECT_VISIBILITY)
+        """Visibility is inverted in skin
+        """
+        self.getControl(self.C_MAIN_CORRECT_VISIBILITY).setVisible(True)
+        self.getControl(self.C_MAIN_INCORRECT_VISIBILITY).setVisible(True)
+
+    def _changeVisibility(self, video = False, photo = False, quote = False, 
threePhotos = False):
+        """Visibility is inverted in skin
+        """
+        self.getControl(self.C_MAIN_VIDEO_VISIBILITY).setVisible(not video)
+        self.getControl(self.C_MAIN_PHOTO_VISIBILITY).setVisible(not photo)
+        self.getControl(self.C_MAIN_QUOTE_VISIBILITY).setVisible(not quote)
+        self.getControl(self.C_MAIN_THREE_PHOTOS_VISIBILITY).setVisible(not 
threePhotos)
+        
+        self.getControl(self.C_MAIN_REPLAY_BUTTON_VISIBILITY).setVisible(video)
+
+    def _obfuscateQuote(self, quote):
+        names = list()
+        for m in re.finditer('(.*?\:)', quote):
+            name = m.group(1)
+            if not name in names:
+                names.append(name)
+
+        for idx, name in enumerate(names):
+            repl = '#%d:' % (idx + 1)
+            quote = quote.replace(name, repl)
 
-    def show(self, controlId):
-        self.getControl(controlId).setVisible(False) # Visibility is inverted 
in skin
+        return quote
 
-    def hide(self, controlId):
-        self.getControl(controlId).setVisible(True) # Visibility is inverted 
in skin
 
 
 class ClapperDialog(xbmcgui.WindowXMLDialog):
diff --git a/script.moviequiz/quizlib/imdb.py b/script.moviequiz/quizlib/imdb.py
index de6ebc7..b77d74e 100644
--- a/script.moviequiz/quizlib/imdb.py
+++ b/script.moviequiz/quizlib/imdb.py
@@ -10,22 +10,44 @@ import xbmc
 import xbmcgui
 import xbmcaddon
 
-
 class Imdb(object):
+    ACTOR_PATTERN = re.compile('^([^\t\(]+)( \([^\)]+\))?\t.*?$')
+
     QUOTES_LIST = 'quotes.list'
-    FILES = [
-        {'name' : QUOTES_LIST, 'url' : 
'http://ftp.sunet.se/pub/tv+movies/imdb/quotes.list.gz'}
-    ]
+    QUOTES_URL = 'http://ftp.sunet.se/pub/tv+movies/imdb/quotes.list.gz' 
+    ACTORS_LIST = 'actors.list'
+    ACTORS_URL = 'http://ftp.sunet.se/pub/tv+movies/imdb/actors.list.gz' 
 
     def __init__(self, listsPath):
         self.path = listsPath
 
-    def downloadFiles(self, progressCallback):
-        for file in self.FILES:
-            self._downloadGzipFile(file['url'], file['name'], progressCallback)
-        
+        actorsPath = os.path.join(self.path, self.ACTORS_LIST)
+        if os.path.exists(actorsPath):
+            f = open(actorsPath)
+            self.actorsData = f.read()
+            f.close()
+        else:
+            self.actorsData = None
+
+
+    def downloadFiles(self, progressCallback = None):
+        self._downloadGzipFile(self.QUOTES_URL, self.QUOTES_LIST, 
progressCallback)
+        self._downloadGzipFile(self.ACTORS_URL, self.ACTORS_LIST, 
progressCallback, self._postprocessActorNames)
 
-    def _downloadGzipFile(self, url, destination, progressCallback):
+
+    def _postprocessActorNames(self, line):
+        m = self.ACTOR_PATTERN.search(line)
+        if m is not None:
+            lastnameFirstname = m.group(1).strip()
+            parts = lastnameFirstname.split(', ', 2)
+            if len(parts) == 2:
+                firstnameLastname = "%s %s\n" % (parts[1], parts[0])
+                return firstnameLastname
+
+        return ''
+ 
+
+    def _downloadGzipFile(self, url, destination, progressCallback = None, 
postprocessLineCallback = None):
         """
         Downloads a gzip compressed file and extracts it on the fly.
 
@@ -38,6 +60,8 @@ class Imdb(object):
         file = open(os.path.join(self.path, destination), 'wb')
         decompressor = zlib.decompressobj(16+zlib.MAX_WBITS)
 
+        partialLine = None
+        previousLine = None
         contentReceived = 0
         contentLength = int(response.info()['Content-Length'])
         while True:
@@ -46,40 +70,50 @@ class Imdb(object):
                 break
             contentReceived += len(chunk)
             decompressedChunk = decompressor.decompress(chunk)
-            file.write(decompressedChunk)
 
-            percentage = int(contentReceived * 100 / contentLength)
-            if not progressCallback(contentReceived, contentLength, 
percentage):
-                break
+            if postprocessLineCallback is not None:
+                if partialLine is not None:
+                    decompressedChunk = partialLine + decompressedChunk
+                    partialLine = None
+
+                lines = decompressedChunk.splitlines(True)
+                processedChunk = ''
+                
+                for line in lines:
+                    if line[-1:] == '\n': # We have a complete line
+                        processedLine = postprocessLineCallback(line)
+                        if processedLine != previousLine and processedLine != 
'':
+                            previousLine = processedLine
+                            processedChunk += processedLine
+                    else: # partial line
+                        partialLine = line
+                file.write(processedChunk)
+            
+            else:
+                file.write(decompressedChunk)
+
+            if progressCallback is not None:
+                percentage = int(contentReceived * 100 / contentLength)
+                if not progressCallback(contentReceived, contentLength, 
percentage):
+                    break
 
         file.close()
         response.close()
 
-    def getRandomQuote(self, movie, obfuscate = True):
+    def getRandomQuote(self, movie, maxLength = None):
         quotes = self._parseMovieQuotes(movie)
         if quotes is None:
             return None
 
-        quote = quotes[random.randint(0, len(quotes)-1)]
-        quote = self._filterAndCleanup(quote)
-        if obfuscate:
-            quote = self.obfuscateQuote(quote)
-
-        return quote
-
-    def obfuscateQuote(self, quote):
-        names = list()
-        for m in re.finditer('(.*?\:)', quote):
-            name = m.group(1)
-            if not name in names:
-                names.append(name)
-
-        print names
-        for idx, name in enumerate(names):
-            repl = '#%d:' % (idx + 1)
-            quote = quote.replace(name, repl)
+        quote = None
+        retries = 0
+        while retries < 10:
+            retries += 1
+            quote = quotes[random.randint(0, len(quotes)-1)]
+            if maxLength is None or len(quote) < maxLength:
+                break
 
-        print "Quote: %s" % quote
+        quote = self._filterAndCleanup(quote)
 
         return quote
 
@@ -91,7 +125,6 @@ class Imdb(object):
         pattern = '\n# %s [^\n]+\n(.*?)\n\n#' % movie
 
         path = os.path.join(self.path, self.QUOTES_LIST)
-
         if os.path.exists(path):
             f = open(path)
             
@@ -110,6 +143,14 @@ class Imdb(object):
             xbmc.log("%s does not exists, has it been downloaded yet?" % 
self.QUOTES_LIST)
             return None
 
+    def isActor(self, name):
+        if self.actorsData is not None:
+            m = re.search('^%s$' % name, self.actorsData, re.MULTILINE)
+            return m is not None
+        else:
+            # if we don't have data all actors are Female
+            return False
+
 
 if __name__ == '__main__':
     # this script is invoked from addon settings
diff --git a/script.moviequiz/quizlib/player.py 
b/script.moviequiz/quizlib/player.py
index d62ed8b..43a2127 100644
--- a/script.moviequiz/quizlib/player.py
+++ b/script.moviequiz/quizlib/player.py
@@ -18,12 +18,23 @@ class TenSecondPlayer(xbmc.Player):
         xbmc.Player.__init__(self)
         xbmc.log(">> TenSecondPlayer.__init__()")
         self.tenSecondTimer = None
-        self.startTime = None
 
         self.database = database
         self.bookmark = None
         self.startingPlayback = False
 
+        self.replaying = False
+        self.lastFile = None
+        self.lastIdFile = None
+        self.lastStartTime = None
+
+    def replay(self):
+        xbmc.log(">> TenSecondPlayer.replay()")
+        if self.lastFile is not None:
+            self.replaying = True
+            self.playWindowed(self.lastFile, self.lastIdFile)
+            self.replaying = False
+
     def stop(self):
         """
         Cancels the Timer in case it's active and stars a new Timer for a 
delayed stop.
@@ -56,6 +67,13 @@ class TenSecondPlayer(xbmc.Player):
         """
         xbmc.log(">> TenSecondPlayer.playWindowed()")
         self.startingPlayback = True
+
+        self.lastFile = file
+        self.lastIdFile= idFile
+
+        if not self.replaying:
+            self.lastStartTime = None
+
         if self.tenSecondTimer is not None:
             #self.stop()
             self.tenSecondTimer.cancel()
@@ -119,12 +137,16 @@ class TenSecondPlayer(xbmc.Player):
     def onPlayBackStarted(self):
         xbmc.log(">> TenSecondPlayer.onPlayBackStarted()")
 
-        totalTime = self.getTotalTime()
-        # find start time, ignore first 10% and last 20% of movie
-        self.startTime = random.randint(int(totalTime * 0.1), int(totalTime * 
0.8))
+        if self.lastStartTime is not None:
+            startTime = self.lastStartTime
+        else:
+            totalTime = self.getTotalTime()
+            # find start time, ignore first 10% and last 20% of movie
+            startTime = random.randint(int(totalTime * 0.1), int(totalTime * 
0.8))
+            self.lastStartTime = startTime
 
-        xbmc.log(">> Playback from %d secs. to %d secs." % (self.startTime, 
self.startTime + 10))
-        self.seekTime(self.startTime)
+        xbmc.log(">> Playback from %d secs. to %d secs." % (startTime, 
startTime + 10))
+        self.seekTime(startTime)
 
         self.tenSecondTimer = threading.Timer(10.0, self.onTenSecondsPassed)
         self.tenSecondTimer.start()
diff --git a/script.moviequiz/quizlib/question.py 
b/script.moviequiz/quizlib/question.py
index 66b15be..f1560b4 100644
--- a/script.moviequiz/quizlib/question.py
+++ b/script.moviequiz/quizlib/question.py
@@ -38,11 +38,15 @@ class Answer(object):
             self.coverFile = thumb.getCachedVideoThumb(path, filename)
 
 class Question(object):
+    ADDON = xbmcaddon.Addon(id = 'script.moviequiz')
+    IMDB = imdb.Imdb(ADDON.getAddonInfo('profile'))
+    
     def __init__(self, database, display, maxRating, onlyWatchedMovies):
         self.database = database
         self.answers = list()
         self.text = None
         self.videoFile = None
+        self.fanartFile = None
         self.photos = list()
         self.quoteText = None
 
@@ -61,9 +65,9 @@ class Question(object):
         return self.answers
 
     def getAnswer(self, idx):
-        if idx < len(self.answers):
+        try:
             return self.answers[idx]
-        else:
+        except IndexError:
             return None
 
     def getCorrectAnswer(self):
@@ -96,6 +100,12 @@ class Question(object):
     def getQuoteText(self):
         return self.quoteText
 
+    def setFanartFile(self, path, filename = None):
+        self.fanartFile = thumb.getCachedVideoFanart(path, filename)
+
+    def getFanartFile(self):
+        return self.fanartFile
+
     def _get_movie_ids(self):
         movieIds = list()
         for movie in self.answers:
@@ -222,7 +232,6 @@ class ActorNotInMovieQuestion(MovieQuestion):
             """ % (self._get_max_rating_clause(), 
self._get_watched_movies_clause()))
         # try to find an actor with a cached photo (if non are found we bail 
out)
         for row in rows:
-            print row['strActor']
             photoFile = thumb.getCachedActorThumb(row['strActor'])
             if os.path.exists(photoFile):
                 actor = row
@@ -270,7 +279,7 @@ class WhatYearWasMovieReleasedQuestion(MovieQuestion):
         WhatYearWasMovieReleasedQuestion
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT mv.idFile, mv.c00 AS title, mv.c07 AS year, mv.strPath, 
mv.strFileName
@@ -303,7 +312,8 @@ class WhatYearWasMovieReleasedQuestion(MovieQuestion):
             self.answers.append(a)
 
         self.text = strings(Q_WHAT_YEAR_WAS_MOVIE_RELEASED, row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'], row['strFileName'])
 
 
 class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
@@ -311,7 +321,7 @@ class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
         WhatTagLineBelongsToMovieQuestion
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT mv.idMovie, mv.idFile, mv.c00 AS title, mv.c03 AS tagline, 
mv.strPath, mv.strFileName
@@ -339,7 +349,8 @@ class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
 
         random.shuffle(self.answers)
         self.text = strings(Q_WHAT_TAGLINE_BELONGS_TO_MOVIE, row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'], row['strFileName'])
 
 
 class WhoDirectedThisMovieQuestion(MovieQuestion):
@@ -347,7 +358,7 @@ class WhoDirectedThisMovieQuestion(MovieQuestion):
         WhoDirectedThisMovieQuestion
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT idActor, a.strActor, mv.idFile, mv.c00 AS title, 
mv.strPath, mv.strFileName
@@ -373,7 +384,8 @@ class WhoDirectedThisMovieQuestion(MovieQuestion):
 
         random.shuffle(self.answers)
         self.text = strings(Q_WHO_DIRECTED_THIS_MOVIE, row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'], row['strFileName'])
 
 
 class WhatStudioReleasedMovieQuestion(MovieQuestion):
@@ -381,7 +393,7 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
         WhatStudioReleasedMovieQuestion
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT s.idStudio, s.strStudio, mv.idFile, mv.c00 AS title, 
mv.strPath, mv.strFileName
@@ -394,11 +406,11 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
         a.setCoverFile(row['strPath'], row['strFileName'])
         self.answers.append(a)
 
-        # todo only select movie studios
         otherAnswers = self.database.fetchall("""
             SELECT s.idStudio, s.strStudio
             FROM studio s
             WHERE s.idStudio != ?
+            AND s.idStudio IN (SELECT idStudio FROM studiolinkmovie)
             ORDER BY random() LIMIT 3
         """, row['idStudio'])
         for movie in otherAnswers:
@@ -408,7 +420,8 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
 
         random.shuffle(self.answers)
         self.text = strings(Q_WHAT_STUDIO_RELEASED_MOVIE, row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'], row['strFileName'])
 
 
 class WhatActorIsThisQuestion(MovieQuestion):
@@ -447,10 +460,17 @@ class WhatActorIsThisQuestion(MovieQuestion):
         actors = self.database.fetchall("""
             SELECT a.idActor, a.strActor
             FROM actors a, actorlinkmovie alm WHERE a.idActor = alm.idActor 
AND a.idActor != ?
-            ORDER BY random() LIMIT 3
+            ORDER BY random() LIMIT 50
             """, actor['idActor'])
+
+        # Check gender
+        actorGender = self.IMDB.isActor(actor['strActor'])
+
         for actor in actors:
-            self.answers.append(Answer(False, actor['idActor'], 
actor['strActor']))
+            if self.IMDB.isActor(actor['strActor']) == actorGender:
+                self.answers.append(Answer(False, actor['idActor'], 
actor['strActor']))
+                if len(self.answers) == 4:
+                    break
 
         random.shuffle(self.answers)
         self.text = strings(Q_WHAT_ACTOR_IS_THIS)
@@ -461,7 +481,7 @@ class WhoPlayedRoleInMovieQuestion(MovieQuestion):
         WhoPlayedRoleInMovieQuestion
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT alm.idActor, a.strActor, alm.strRole, mv.idMovie, mv.c00 AS 
title, mv.strPath, mv.strFileName, mv.c14 AS genre
@@ -497,7 +517,8 @@ class WhoPlayedRoleInMovieQuestion(MovieQuestion):
             self.text = strings(Q_WHO_VOICES_ROLE_IN_MOVIE) % (role, 
row['title'])
         else:
             self.text = strings(Q_WHO_PLAYS_ROLE_IN_MOVIE) % (role, 
row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'], row['strFileName'])
 
         
 class WhatMovieIsThisQuoteFrom(MovieQuestion):
@@ -506,10 +527,6 @@ class WhatMovieIsThisQuoteFrom(MovieQuestion):
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
         MovieQuestion.__init__(self, database, DISPLAY_QUOTE, maxRating, 
onlyWatchedMovies)
-        # todo limit length of quotes
-        addon = xbmcaddon.Addon(id = 'script.moviequiz') # TODO
-        i = imdb.Imdb(addon.getAddonInfo('profile'))
-
         rows = self.database.fetchall("""
             SELECT mv.idMovie, mv.c00 AS title, mv.c07 AS year, mv.strPath, 
mv.strFileName
             FROM movieview mv
@@ -520,7 +537,7 @@ class WhatMovieIsThisQuoteFrom(MovieQuestion):
         quoteText = None
         row = None
         for r in rows:
-            quoteText = i.getRandomQuote(r['title'])
+            quoteText = Question.IMDB.getRandomQuote(r['title'], maxLength = 
256)
 
             if quoteText is not None:
                 row = r
@@ -556,7 +573,6 @@ class WhatMovieIsNewestQuestion(MovieQuestion):
     """
     def __init__(self, database, maxRating, onlyWatchedMovies):
         MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
-        # todo make sure not to select one of the 3 oldest movies
         row = self.database.fetchone("""
             SELECT mv.idMovie, mv.idFile, mv.c00 AS title, mv.strPath, 
mv.strFileName, mv.c07 AS year
             FROM movieview mv
@@ -575,6 +591,9 @@ class WhatMovieIsNewestQuestion(MovieQuestion):
             %s %s
             ORDER BY random() LIMIT 3
         """ % (self._get_max_rating_clause(), 
self._get_watched_movies_clause()), row['year'])
+        if len(movies) < 3:
+            raise QuestionException("Less than 3 movies found; bailing out")
+
         for movie in movies:
             a = Answer(False, movie['idMovie'], movie['title'])
             a.setCoverFile(movie['strPath'], movie['strFileName'])
@@ -752,6 +771,7 @@ class WhatTVShowIsThisQuestion(TVQuestion):
         random.shuffle(self.answers)
         self.text = strings(Q_WHAT_TVSHOW_IS_THIS)
         self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setFanartFile(row['strPath'], row['strFileName'])
 
 
 class WhatSeasonIsThisQuestion(TVQuestion):
@@ -790,6 +810,8 @@ class WhatSeasonIsThisQuestion(TVQuestion):
 
         self.text = strings(Q_WHAT_SEASON_IS_THIS) % row['title']
         self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setFanartFile(row['strPath'], row['strFileName'])
+
 
 class WhatEpisodeIsThisQuestion(TVQuestion):
     """
@@ -831,48 +853,7 @@ class WhatEpisodeIsThisQuestion(TVQuestion):
 
         self.text = strings(Q_WHAT_EPISODE_IS_THIS) % row['title']
         self.setVideoFile(row['strPath'], row['strFileName'])
-
-
-class WhenWasEpisodeFirstAiredQuestion(TVQuestion):
-    """
-        WhenWasEpisodeFirstAiredQuestion
-    """
-
-    def __init__(self, database, maxRating, onlyWatchedMovies):
-        TVQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
-
-        row = self.database.fetchone("""
-            SELECT ev.idFile, ev.c00 AS episodeTitle, ev.c12 AS season, ev.c13 
AS episode, ev.c05 AS firstAired, tv.c00 AS title, ev.idShow, ev.strPath, 
ev.strFileName,
-                (SELECT COUNT(DISTINCT c13) FROM episodeview WHERE 
idShow=ev.idShow) AS episodes
-            FROM episodeview ev, tvshowview tv
-            WHERE ev.idShow=tv.idShow AND episodes > 2 AND ev.c05 != '' AND 
ev.strFileName NOT LIKE '%%.nfo'
-            %s %s
-            ORDER BY random() LIMIT 1
-            """ % (self._get_watched_episodes_clause(), 
self._get_max_rating_clause()))
-        a = Answer(True, row['episode'], self._format_date(row['firstAired']), 
row['idFile'])
-        a.setCoverFile(row['strPath'], row['strFileName'])
-        self.answers.append(a)
-
-        # Fill with random episodes from this show
-        shows = self.database.fetchall("""
-            SELECT ev.c00 AS episodeTitle, ev.c12 AS season, ev.c13 AS 
episode, ev.c05 AS firstAired
-            FROM episodeview ev
-            WHERE ev.idShow = ? AND ev.c12 = ? AND ev.c13 != ? AND ev.c05 != 
'' AND ev.strFileName NOT LIKE '%%.nfo'
-            ORDER BY random() LIMIT 3
-            """, (row['idShow'], row['season'], row['episode']))
-        for show in shows:
-            a = Answer(False, show['episode'], 
self._format_date(show['firstAired']))
-            a.setCoverFile(row['strPath'], row['strFileName'])
-            self.answers.append(a)
-
-        self.answers = sorted(self.answers, key=lambda answer: int(answer.id))
-
-        self.text = strings(Q_WHEN_WAS_EPISODE_FIRST_AIRED) % 
(self._get_episode_title(row['season'], row['episode'], row['episodeTitle']), 
row['title'])
-        self.setVideoFile(row['strPath'], row['strFileName'])
-
-    def _format_date(self, dateString):
-        d = time.strptime(dateString, '%Y-%m-%d')
-        return time.strftime(strings(Q_FIRST_AIRED_DATEFORMAT), d)
+#        self.setFanartFile(row['strPath'], row['strFileName'])
 
 class WhenWasTVShowFirstAiredQuestion(TVQuestion):
     """
@@ -880,12 +861,12 @@ class WhenWasTVShowFirstAiredQuestion(TVQuestion):
     """
 
     def __init__(self, database, maxRating, onlyWatchedMovies):
-        TVQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating, 
onlyWatchedMovies)
+        TVQuestion.__init__(self, database, DISPLAY_NONE, maxRating, 
onlyWatchedMovies)
 
         row = self.database.fetchone("""
             SELECT ev.idFile, ev.c12 AS season, ev.c13 AS episode, ev.c05 AS 
firstAired, tv.c00 AS title, ev.idShow, ev.strPath, ev.strFileName
             FROM episodeview ev, tvshowview tv
-            WHERE ev.idShow=tv.idShow AND ev.c12 = 1 AND ev.c13 != 0 AND 
ev.c05 != '' AND ev.strFileName NOT LIKE '%%.nfo'
+            WHERE ev.idShow=tv.idShow AND ev.c12 != 0 AND ev.c13 = 1 AND 
ev.c05 != '' AND ev.strFileName NOT LIKE '%%.nfo'
             %s %s
             ORDER BY random() LIMIT 1
             """ % (self._get_watched_episodes_clause(), 
self._get_max_rating_clause()))
@@ -916,7 +897,9 @@ class WhenWasTVShowFirstAiredQuestion(TVQuestion):
             self.answers.append(a)
 
         self.text = strings(Q_WHEN_WAS_TVSHOW_FIRST_AIRED) % (row['title'] + ' 
- ' + self._get_season_title(row['season']))
-        self.setVideoFile(row['strPath'], row['strFileName'])
+#        self.setVideoFile(row['strPath'], row['strFileName'])
+        self.setFanartFile(row['strPath'])
+
 
 class WhoPlayedRoleInTVShowQuestion(TVQuestion):
     """
@@ -972,8 +955,10 @@ def getRandomQuestion(type, database, maxRating, 
onlyWatchedMovies):
     """
     subclasses = []
     if type == TYPE_MOVIE:
+        #noinspection PyUnresolvedReferences
         subclasses = MovieQuestion.__subclasses__()
     elif type == TYPE_TV:
+        #noinspection PyUnresolvedReferences
         subclasses = TVQuestion.__subclasses__()
     random.shuffle(subclasses)
 
diff --git a/script.moviequiz/quizlib/thumb.py 
b/script.moviequiz/quizlib/thumb.py
index de4468d..9ff6f8b 100644
--- a/script.moviequiz/quizlib/thumb.py
+++ b/script.moviequiz/quizlib/thumb.py
@@ -3,25 +3,31 @@ import os
 
 __author__ = 'tommy'
 
-def getCachedThumb(file):
-    if file[0:8] == 'stack://':
-        commaPos = file.find(' , ')
-        file = file[8:commaPos].strip()
+def _getFilename(path, filename = None):
+    if filename is not None and filename[0:8] == 'stack://':
+        commaPos = filename.find(' , ')
+        file = filename[8:commaPos].strip()
+    elif filename is not None:
+        file = os.path.join(path, filename)
+    else:
+        file = path
+
+    return file
 
-    crc = xbmc.getCacheThumbName(file.lower())
+def _getCachedThumb(path, filename = None):
+    crc = xbmc.getCacheThumbName(_getFilename(path, filename).lower())
     return xbmc.translatePath('special://profile/Thumbnails/Video/%s/%s' % 
(crc[0], crc))
 
 def getCachedVideoThumb(path, filename):
-    if filename[0:8] == 'stack://':
-        videoFile = filename
-    else:
-        videoFile = os.path.join(path, filename)
-        
-    return getCachedThumb(videoFile)
+    return _getCachedThumb(path, filename)
+
+def getCachedVideoFanart(path, filename):
+    crc = xbmc.getCacheThumbName(_getFilename(path, filename).lower())
+    return xbmc.translatePath('special://profile/Thumbnails/Video/Fanart/%s' % 
crc)
 
 
 def getCachedActorThumb(name):
-    return getCachedThumb('actor' + name)
+    return _getCachedThumb('actor' + name)
 
 def getCachedSeasonThumb(path, label):
     """
@@ -30,7 +36,7 @@ def getCachedSeasonThumb(path, label):
             for English this can be Specials, Season 1, Season 10, etc
 
     """
-    return getCachedThumb('season' + path + label)
+    return _getCachedThumb('season' + path + label)
 
 def getCachedTVShowThumb(path):
-    return getCachedThumb(path)
\ No newline at end of file
+    return _getCachedThumb(path)
\ No newline at end of file
diff --git a/script.moviequiz/resources/language/Danish/strings.xml 
b/script.moviequiz/resources/language/Danish/strings.xml
index eb584e6..045b310 100644
--- a/script.moviequiz/resources/language/Danish/strings.xml
+++ b/script.moviequiz/resources/language/Danish/strings.xml
@@ -13,7 +13,6 @@
     <string id="30007">%e. %B %Y</string><!-- episode first aired date format: 
http://docs.python.org/library/time.html#time.strftime -->
     <string id="30008">[B]Indlæser[/B]</string>
 
-
     <!-- Menu -->
     <string id="30100">Spil Film Quiz</string>
     <string id="30101">Spil TV Quiz</string>
@@ -56,7 +55,6 @@
     <string id="30455">Hvem spiller [B]%s[/B] i [B]%s[/B]?</string><!-- 1st %s 
is role, 2nd %s is tvshow title -->
     <string id="30456">Hvem ligger stemme til [B]%s[/B] i 
[B]%s[/B]?</string><!-- 1st %s is role, 2nd %s is movie title -->
 
-
     <!-- Settings strings -->
     <string id="30500">Generelt</string>
     <string id="30501">Film</string>
diff --git a/script.moviequiz/resources/language/English/strings.xml 
b/script.moviequiz/resources/language/English/strings.xml
index 137757b..0000bf5 100644
--- a/script.moviequiz/resources/language/English/strings.xml
+++ b/script.moviequiz/resources/language/English/strings.xml
@@ -31,7 +31,6 @@
     <string id="30122">%d seasons</string><!-- %d is season count -->
     <string id="30123">%d episodes</string><!-- %d is episodes count -->
 
-
     <!-- Movie Questions -->
     <string id="30400">What movie is this?</string>
     <string id="30401">What movie is [B]%s[/B] not in?</string><!-- %s is 
actor name -->
diff --git a/script.moviequiz/resources/language/German/strings.xml 
b/script.moviequiz/resources/language/German/strings.xml
index 00a49aa..216e3ff 100644
--- a/script.moviequiz/resources/language/German/strings.xml
+++ b/script.moviequiz/resources/language/German/strings.xml
@@ -12,6 +12,7 @@
     <string id="30006">Staffel %d</string>
     <string id="30007">%B %e, %Y</string><!-- episode first aired date format: 
http://docs.python.org/library/time.html#time.strftime -->
        <string id="30008">[B]Lade...[/B]</string>
+
        <!-- Menu -->
     <string id="30100">Movie Quiz spielen</string>
     <string id="30101">TV Quiz spielen</string>
diff --git 
a/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml 
b/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
index bd76a9c..88e4793 100644
--- a/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
+++ b/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
@@ -30,25 +30,37 @@
         <control type="label" id="5006">
             <description>visibility marker for three photos group</description>
         </control>
+        <control type="label" id="5007">
+            <description>visibility marker for replay button</description>
+        </control>
 
 
 
         <!-- Background -->
-        <control type="image" id="4501">
-            <description>TV Quiz background</description>
+        <control type="image" id="4500">
+            <description>Background</description>
             <posx>0</posx>
             <posy>0</posy>
             <width>1280</width>
             <height>720</height>
-            <texture>quiz-background-tvshows.png</texture>
+            <texture>quiz-background.png</texture>
         </control>
-        <control type="image" id="4500">
-            <description>Movie Quiz background</description>
+
+        <control type="image">
+            <description>Glasspane for question and answers</description>
             <posx>0</posx>
-            <posy>0</posy>
+            <posy>484</posy>
             <width>1280</width>
-            <height>720</height>
-            <texture>quiz-background.png</texture>
+            <height>256</height>
+            <texture>quiz-background-glass.png</texture>
+        </control>
+        <control type="image">
+            <description>Glasspane for score</description>
+            <posx>10</posx>
+            <posy>10</posy>
+            <width>215</width>
+            <height>145</height>
+            <texture>quiz-background-glass.png</texture>
         </control>
 
         <!-- photo group -->
@@ -357,9 +369,9 @@
         <!-- Answer buttons -->
         <control type="button" id="4000">
             <description>Answer 1</description>
-            <posx>182</posx>
+            <posx>222</posx>
             <posy>540</posy>
-            <width>1075</width>
+            <width>955</width>
             <height>40</height>
             <textoffsetx>8</textoffsetx>
             <textoffsety>4</textoffsety>
@@ -369,12 +381,23 @@
             <texturenofocus />
             <onup>4003</onup>
             <ondown>4001</ondown>
+            <onright>4010</onright>
+        </control>
+        <control type="image">
+            <description>Red square</description>
+            <posx>192</posx>
+            <posy>550</posy>
+            <width>20</width>
+            <height>20</height>
+            <texture>quiz-white-square.png</texture>
+            <colordiffuse>ffff0000</colordiffuse>
+            <visible>Control.IsVisible(4000)</visible>
         </control>
         <control type="button" id="4001">
             <description>Answer 2</description>
-            <posx>182</posx>
+            <posx>222</posx>
             <posy>580</posy>
-            <width>1075</width>
+            <width>955</width>
             <height>40</height>
             <textoffsetx>8</textoffsetx>
             <textoffsety>4</textoffsety>
@@ -384,12 +407,23 @@
             <texturenofocus />
             <onup>4000</onup>
             <ondown>4002</ondown>
+            <onright>4010</onright>
+        </control>
+        <control type="image">
+            <description>Green square</description>
+            <posx>192</posx>
+            <posy>590</posy>
+            <width>20</width>
+            <height>20</height>
+            <texture>quiz-white-square.png</texture>
+            <colordiffuse>ff00ff00</colordiffuse>
+            <visible>Control.IsVisible(4001)</visible>
         </control>
         <control type="button" id="4002">
             <description>Answer 3</description>
-            <posx>182</posx>
+            <posx>222</posx>
             <posy>620</posy>
-            <width>1075</width>
+            <width>955</width>
             <height>40</height>
             <textoffsetx>8</textoffsetx>
             <textoffsety>4</textoffsety>
@@ -399,12 +433,23 @@
             <texturenofocus />
             <onup>4001</onup>
             <ondown>4003</ondown>
+            <onright>4011</onright>
+        </control>
+        <control type="image">
+            <description>Yellow square</description>
+            <posx>192</posx>
+            <posy>630</posy>
+            <width>20</width>
+            <height>20</height>
+            <texture>quiz-white-square.png</texture>
+            <colordiffuse>ffffff00</colordiffuse>
+            <visible>Control.IsVisible(4002)</visible>
         </control>
         <control type="button" id="4003">
             <description>Answer 4</description>
-            <posx>182</posx>
+            <posx>222</posx>
             <posy>660</posy>
-            <width>1075</width>
+            <width>955</width>
             <height>40</height>
             <textoffsetx>8</textoffsetx>
             <textoffsety>4</textoffsety>
@@ -414,9 +459,64 @@
             <texturenofocus />
             <onup>4002</onup>
             <ondown>4000</ondown>
+            <onright>4011</onright>
+        </control>
+        <control type="image">
+            <description>Blue square</description>
+            <posx>192</posx>
+            <posy>670</posy>
+            <width>20</width>
+            <height>20</height>
+            <texture>quiz-white-square.png</texture>
+            <colordiffuse>ff0000ff</colordiffuse>
+            <visible>Control.IsVisible(4003)</visible>
+        </control>
+
+        <control type="button" id="4010">
+            <description>Replay video</description>
+            <posx>1177</posx>
+            <posy>540</posy>
+            <width>80</width>
+            <height>80</height>
+            <texturefocus>quiz-button-background.png</texturefocus>
+            <texturenofocus />
+            <onup>4011</onup>
+            <ondown>4011</ondown>
+            <onleft>4000</onleft>
+            <visible>Control.IsVisible(5007)</visible>
+        </control>
+        <control type="image">
+            <description>Replay video image</description>
+            <posx>1190</posx>
+            <posy>553</posy>
+            <width>54</width>
+            <height>54</height>
+            <texture>quiz-button-replay.png</texture>
+            <animation effect="fade" start="100" end="33" time="400" 
condition="!Control.IsVisible(5007)">Conditional</animation>
+        </control>
+        <control type="button" id="4011">
+            <description>Exit quiz</description>
+            <posx>1177</posx>
+            <posy>620</posy>
+            <width>80</width>
+            <height>80</height>
+            <texturefocus>quiz-button-background.png</texturefocus>
+            <texturenofocus />
+            <onup>4010</onup>
+            <ondown>4010</ondown>
+            <onleft>4002</onleft>
+        </control>
+        <control type="image">
+            <description>Exit quiz image</description>
+            <posx>1190</posx>
+            <posy>633</posy>
+            <width>54</width>
+            <height>54</height>
+            <texture>quiz-button-exit.png</texture>
         </control>
 
         <control type="image">
+            <description>Correct answer</description>
             <posx>1085</posx>
             <posy>35</posy>
             <width>150</width>
@@ -427,6 +527,7 @@
             <animation effect="slide" start="200,0" 
time="1000">Visible</animation>
         </control>
         <control type="image">
+            <description>Wrong answer</description>
             <posx>1085</posx>
             <posy>35</posy>
             <width>150</width>
diff --git 
a/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png 
b/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png
index 3feb730..252e4a1 100644
Binary files 
a/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png 
and 
b/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png 
differ
diff --git a/script.moviequiz/resources/skins/Default/media/quiz-background.png 
b/script.moviequiz/resources/skins/Default/media/quiz-background.png
index 9328dc9..d608c15 100644
Binary files 
a/script.moviequiz/resources/skins/Default/media/quiz-background.png and 
b/script.moviequiz/resources/skins/Default/media/quiz-background.png differ
diff --git a/script.moviequiz/todo.txt b/script.moviequiz/todo.txt
index f600eb5..236c450 100644
--- a/script.moviequiz/todo.txt
+++ b/script.moviequiz/todo.txt
@@ -1,9 +1,7 @@
 TODOs and suggestions in no particular order
 
-- Add support for non-interactive execution to run from Cinema Experience
 - DVD ISO's plays menu instead of movie
 - Add support for global statistics, eg. "lifetime" correct/incorrect answers 
and such
-- Use fanart instead of movie (fallback / option in settings)
 
 Movie Question suggestions:
 * Which actor was also in movie xy besides actor z?

-----------------------------------------------------------------------

Summary of changes:
 script.moviequiz/addon.xml                         |    3 +-
 script.moviequiz/changelog.txt                     |    9 ++
 script.moviequiz/quizlib/db.py                     |   50 +++++---
 script.moviequiz/quizlib/gui.py                    |  125 ++++++++++++-------
 script.moviequiz/quizlib/imdb.py                   |  109 +++++++++++-----
 script.moviequiz/quizlib/mq_ce_play.py             |   27 ++++
 script.moviequiz/quizlib/player.py                 |   34 ++++-
 script.moviequiz/quizlib/question.py               |  119 ++++++++----------
 script.moviequiz/quizlib/thumb.py                  |   34 +++--
 .../resources/language/Danish/strings.xml          |    2 -
 .../resources/language/English/strings.xml         |    1 -
 .../resources/language/French/strings.xml          |   25 ----
 .../resources/language/German/strings.xml          |    1 +
 .../skins/Default/720p/script-moviequiz-main.xml   |  133 +++++++++++++++++---
 .../Default/media/quiz-background-tvshows.png      |  Bin 1331700 -> 1535996 
bytes
 .../skins/Default/media/quiz-background.png        |  Bin 1230462 -> 1447692 
bytes
 .../skins/Default/media/quiz-button-exit.png       |  Bin 0 -> 1164 bytes
 .../skins/Default/media/quiz-button-icons.xcf      |  Bin 0 -> 8060 bytes
 .../skins/Default/media/quiz-button-replay.png     |  Bin 0 -> 1267 bytes
 .../skins/Default/media/quiz-white-square.png      |  Bin 0 -> 177 bytes
 script.moviequiz/todo.txt                          |    2 -
 21 files changed, 443 insertions(+), 231 deletions(-)
 create mode 100644 script.moviequiz/quizlib/mq_ce_play.py
 delete mode 100644 script.moviequiz/resources/language/French/strings.xml
 create mode 100644 
script.moviequiz/resources/skins/Default/media/quiz-button-exit.png
 create mode 100644 
script.moviequiz/resources/skins/Default/media/quiz-button-icons.xcf
 create mode 100644 
script.moviequiz/resources/skins/Default/media/quiz-button-replay.png
 create mode 100644 
script.moviequiz/resources/skins/Default/media/quiz-white-square.png


hooks/post-receive
-- 
Scripts

------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload 
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve 
application availability and disaster protection. Learn more about boosting 
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to