Index: libs/libmythtv/eitfixup.cpp
===================================================================
--- libs/libmythtv/eitfixup.cpp	(revision 18237)
+++ libs/libmythtv/eitfixup.cpp	(working copy)
@@ -1,3 +1,4 @@
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
 // C++ headers
 #include <algorithm>
 
@@ -25,7 +26,7 @@
       m_ukNew("(New\\.|\\s*(Brand New|New)\\s*(Series|Episode)\\s*[:\\.\\-])",false),
       m_ukCEPQ("[:\\!\\.\\?]"),
       m_ukColonPeriod("[:\\.]"),
-      m_ukDotSpaceStart("^\\. "),
+      m_ukDotSpaceStart("^(?:\\. | )"),
       m_ukDotEnd("\\.$"),
       m_ukSpaceColonStart("^[ |:]*"),
       m_ukSpaceStart("^ "),
@@ -36,15 +37,17 @@
       m_uk24ep("^\\d{1,2}:00[ap]m to \\d{1,2}:00[ap]m: "),
       m_ukStarring("(?:Western\\s)?[Ss]tarring ([\\w\\s\\-']+)[Aa]nd\\s([\\w\\s\\-']+)[\\.|,](?:\\s)*(\\d{4})?(?:\\.\\s)?"),
       m_ukBBC7rpt("\\[Rptd?[^]]+\\d{1,2}\\.\\d{1,2}[ap]m\\]\\."),
-      m_ukDescriptionRemove("^(?:CBBC\\s*\\.|CBeebies\\s*\\.|Class TV\\s*:|BBC Switch\\.)"),
+      m_ukDescriptionRemove("^(?:CBBC\\s*\\.|CBeebies\\s*\\.|Class TV\\s*:|BBC Switch(?:\\.|:))"),
       m_ukTitleRemove("^(?:[tT]4:|Schools\\s*:)"),
       m_ukDoubleDotEnd("\\.\\.+$"),
       m_ukDoubleDotStart("^\\.\\.+"),
       m_ukTime("\\d{1,2}[\\.:]\\d{1,2}\\s*(am|pm|)"),
       m_ukBBC34("BBC (?:THREE|FOUR) on BBC (?:ONE|TWO)\\.",false),
       m_ukYearColon("^[\\d]{4}:"),
-      m_ukExclusionFromSubtitle("(starring|stars\\s|drama|series|sitcom)",false),
+      m_ukExclusionFromSubtitle("(starring|stars|drama|series|sitcom|serial|^crime)",false),
       m_ukCompleteDots("^\\.\\.+$"),
+      m_uk5xNumberHyphen3xNumber("\\d\\d\\d\\d\\d-\\d\\d\\d [A-Z]"),
+      m_ukTerminus("\\d"),
       m_comHemCountry("^(\\(.+\\))?\\s?([^ ]+)\\s([^\\.0-9]+)"
                       "(?:\\sfrån\\s([0-9]{4}))(?:\\smed\\s([^\\.]+))?\\.?"),
       m_comHemDirector("[Rr]egi"),
@@ -305,7 +308,10 @@
  */
 void EITFixUp::SetUKSubtitle(DBEvent &event) const
 {
-    QStringList strListColon = event.description.split(":");
+    if (!event.subtitle.isEmpty())
+        return;
+
+    QStringList strListColon = QStringList::split(":",event.description,TRUE);
     QStringList strListEnd;
 
     bool fColon = false;
@@ -329,9 +335,8 @@
          {
              QString strTmp = event.description.mid(nPosition1+1,
                                      nLength-nPosition1);
-
-             QStringList tmp = strTmp.split(" ");
-             if (((uint) tmp.size()) < kMaxDotToColon)
+             QStringList tmp = strTmp.split(" ",QString::SkipEmptyParts);
+             if (((uint) tmp.size()) <= kMaxDotToColon)
                  fSingleDot = false;
          }
 
@@ -342,74 +347,84 @@
          }
          else if (!fSingleDot)
          {
-             QStringList strListTmp;
-             uint nTitle=0;
-             int nTitleMax=-1;
+             int nCount=strListColon.count();
+             int nMaxLength=0; 
+             int nMaxTitle=0;
              int i;
-             for (i =0; (i<(int)strListColon.count()) && (nTitleMax==-1);i++)
+             for (i=0;i<(nCount-1);i++)
              {
-                 const QStringList tmp = strListColon[i].split(" ");
-
-                 nTitle += tmp.size();
-
-                 if (nTitle < kMaxToTitle)
-                     strListTmp.push_back(strListColon[i]);
-                 else
-                     nTitleMax=i;
+                 QString strTmp = strListColon[i+1].stripWhiteSpace();
+                 QChar aLetter = strTmp.at(0);
+                 QChar bLetter = aLetter.lower();
+                 uint nTmp=
+                     QStringList::split(" ",strListColon[i],FALSE).count();
+                 if ((nMaxLength+nTmp > kMaxToTitle) || (aLetter==bLetter))
+                     break;
+                 nMaxLength = nMaxLength+nTmp;
+                 nMaxTitle = i;
              }
-             QString strPartial;
-             for (i=0;i<(nTitleMax-1);i++)
-                 strPartial+=strListTmp[i]+":";
-             if (nTitleMax>0)
+             if (nMaxLength)
              {
-                 strPartial+=strListTmp[nTitleMax-1];
+                 QString strPartial;
+                 for (i=0;i<=nMaxTitle;i++)
+                 {
+                     strPartial+=strListColon[i];
+                     if (i<(nMaxTitle))
+                          strPartial+=":";
+                 }
                  strListEnd.push_back(strPartial);
-             }
-             for (i=nTitleMax+1;i<(int)strListColon.count();i++)
-                 strListEnd.push_back(strListColon[i]);
-             fColon = true;
+                 for (i=(nMaxTitle+1);i<nCount;i++)
+                     strListEnd.push_back(strListColon[i]);
+                 fColon=true;
+             }             
          }
     }
+
     QStringList strListPeriod;
     QStringList strListQuestion;
     QStringList strListExcl;
     if (!fColon)
     {
-        strListPeriod = event.description.split(".");
+        int nLength=INT_MAX;
+        strListPeriod = QStringList::split(".",event.description,TRUE);
+        strListQuestion = QStringList::split("?",event.description,TRUE);
+        strListExcl = QStringList::split("!",event.description,TRUE);
+
         if (strListPeriod.count() >1)
         {
             nPosition1 = event.description.find(".");
             int nPosition2 = event.description.find("..");
             if ((nPosition1 < nPosition2) || (nPosition2==-1))
+            {
+                nLength = strListPeriod[0].length();  
                 strListEnd = strListPeriod;
+            }
         }
 
-        strListQuestion = event.description.split("?");
-        strListExcl = event.description.split("!");
-        if ((strListQuestion.size() > 1) &&
-            ((uint)strListQuestion.size() <= kMaxQuestionExclamation))
+        if ((strListQuestion.size()>1) &&
+                 ((uint)strListQuestion.size()<=kMaxQuestionExclamation) &&
+                 ((int)(strListQuestion[0].length())<nLength))
         {
             strListEnd = strListQuestion;
             strEnd = "?";
         }
-        else if ((strListExcl.size() > 1) &&
-                 ((uint)strListExcl.size() <= kMaxQuestionExclamation))
+        else if ((strListExcl.size()>1) &&
+                 ((uint)strListExcl.size()<=kMaxQuestionExclamation) &&
+                 ((int)(strListExcl[0].length())<nLength))
         {
             strListEnd = strListExcl;
             strEnd = "!";
         }
         else
-            strEnd = QString::null;
+            strEnd = "";
     }
 
     if (!strListEnd.empty())
     {
         QStringList strListSpace = strListEnd[0].split(
             " ", QString::SkipEmptyParts);
-        if (fColon && ((uint)strListSpace.size() > kMaxToTitle))
+        if (strListSpace.count() > (int)kMaxToTitle)
              return;
-        if ((uint)strListSpace.size() > kDotToTitle)
-             return;
         if (strListSpace.grep(m_ukExclusionFromSubtitle).empty())
         {
              event.subtitle = strListEnd[0]+strEnd;
@@ -501,7 +516,9 @@
     }
 
     QRegExp tmp24ep = m_uk24ep;
-    if (!event.title.startsWith("CSI:") && !event.title.startsWith("CD:"))
+    if (!event.title.startsWith("CSI:") && 
+        !event.title.startsWith("Law & Order:") && 
+        !event.title.startsWith("CD:"))
     {
         if (((position1=event.title.find(m_ukDoubleDotEnd)) != -1) &&
             ((position2=event.description.find(m_ukDoubleDotStart)) != -1))
@@ -558,7 +575,9 @@
                         event.title.setLength(position1);
                         event.subtitle = strTmp+event.subtitle;
                     }
-                    else if ((uint)position1 < SUBTITLE_MAX_LEN)
+                    else if (
+                        (event.title.mid(position1+1).find(m_ukTerminus)!=0) &&
+                        ((uint)position1 < SUBTITLE_MAX_LEN))
                     {
                         event.subtitle = event.title.mid(position1 + 1);
                         event.title = event.title.left(position1);
@@ -589,6 +608,14 @@
         }
         else
             SetUKSubtitle(event);
+
+        if (event.subtitle.isEmpty() && 
+            (position1=event.description.find(m_uk5xNumberHyphen3xNumber)) &&
+            (position1 >0) && ((uint)position1<SUBTITLE_MAX_LEN))
+        {
+            event.subtitle = event.description.left(position1+9); 
+            event.description = event.description.mid(position1+9); 
+        }
     }
 
     // Work out the year (if any)
@@ -606,10 +633,19 @@
     }
 
     // Trim leading/trailing '.'
+    event.description.remove(m_ukDotSpaceStart);
     event.subtitle.remove(m_ukDotSpaceStart);
     if (event.subtitle.findRev("..") != (((int)event.subtitle.length())-2))
         event.subtitle.remove(m_ukDotEnd);
 
+    // Demote the subtitle if it matches the title
+    if (!event.title.isEmpty() && !event.subtitle.isEmpty() &&
+         event.title == event.subtitle)
+    {
+        event.description=event.subtitle+" "+event.description;
+        event.subtitle=QString::null;
+    }
+
     // Reverse the subtitle and empty description
     if (event.description.isEmpty() && !event.subtitle.isEmpty())
     {
Index: libs/libmythtv/eitfixup.h
===================================================================
--- libs/libmythtv/eitfixup.h	(revision 18237)
+++ libs/libmythtv/eitfixup.h	(working copy)
@@ -1,4 +1,5 @@
 /*
+ *  vim: set expandtab tabstop=4 shiftwidth=4:
  *  Copyright 2004 - Taylor Jacob (rtjacob at earthlink.net)
  */
 
@@ -18,13 +19,11 @@
      // max length of subtitle field in db.
      static const uint SUBTITLE_MAX_LEN = 128;
      // max number of words included in a subtitle
-     static const uint kMaxToTitle = 14;
-     // max number of words up to a period, question mark
-     static const uint kDotToTitle = 9;
+     static const uint kMaxToTitle = 10;
      // max number of question/exclamation marks
      static const uint kMaxQuestionExclamation = 2;
      // max number of difference in words between a period and a colon
-     static const uint kMaxDotToColon = 5;
+     static const uint kMaxDotToColon = 6;
 
   public:
     enum FixUpType
@@ -108,6 +107,8 @@
     const QRegExp m_ukYearColon;
     const QRegExp m_ukExclusionFromSubtitle;
     const QRegExp m_ukCompleteDots;
+    const QRegExp m_uk5xNumberHyphen3xNumber;
+    const QRegExp m_ukTerminus;
     const QRegExp m_comHemCountry;
     const QRegExp m_comHemDirector;
     const QRegExp m_comHemActor;
