Index: programs/mythfrontend/playbackbox.cpp
===================================================================
--- programs/mythfrontend/playbackbox.cpp	(revision 7946)
+++ programs/mythfrontend/playbackbox.cpp	(working copy)
@@ -98,6 +98,58 @@
         return (dt1 > dt2 ? 1 : -1);
 }
 
+static PlaybackBox::ViewMask viewMaskToggle(PlaybackBox::ViewMask mask,
+        PlaybackBox::ViewMask toggle)
+{
+    // only works for single-bit toggle values
+    if ((mask & toggle))
+        return (PlaybackBox::ViewMask)(mask & ~toggle);
+    return (PlaybackBox::ViewMask)(mask | toggle);
+}
+
+static QString sortTitle(QString title, PlaybackBox::ViewMask viewmask,
+        PlaybackBox::ViewTitleSort titleSort, int recpriority)
+{
+    if (title == "")
+        return title;
+
+    QRegExp prefixes = QObject::tr("^(The |A |An )");
+    QString sTitle = title;
+
+    sTitle.remove(prefixes);
+    if (viewmask == PlaybackBox::VIEW_TITLES &&
+            titleSort == PlaybackBox::TitleSortRecPriority)
+    {
+        // Also incorporate recpriority (reverse numeric sort).
+        //
+        // Take advantage of QMap sorting. Positive recpriority values have a
+        // '+' prefix (sorts before '-'). Positive recpriority values are
+        // "inverted" by substracting them from 1000, so that high
+        // recpriorities are sorted first.
+        //
+        // For example (first column is sort key; second column is
+        // recpriority):
+        //
+        //      +905     95
+        //      +910     90
+        //      +911     89
+        //      +999      1
+        //      -000      0
+        //      -005     -5
+        //      -010    -10
+        //      -099    -99
+
+        QString sortprefix;
+        if (recpriority > 0)
+            sortprefix.sprintf("+%03u", 1000 - recpriority);
+        else
+            sortprefix.sprintf("-%03u", -recpriority);
+
+        sTitle = sortprefix + "-" + sTitle;
+    }
+    return sTitle;
+}
+
 PlaybackBox::PlaybackBox(BoxType ltype, MythMainWindow *parent, 
                          const char *name)
            : MythDialog(parent, name)
@@ -146,15 +198,8 @@
 
     recGroupPopup = NULL;
 
-    // titleView controls showing titles in group list 
-    titleView = true;
+    viewMask = VIEW_TITLES;
 
-    // useCategories controls showing categories in group list
-    useCategories = false;
-
-    // useRecGroups controls showing of recording groups in group list
-    useRecGroups = false;
-
     if (gContext->GetNumSetting("UseArrowAccels", 1))
         arrowAccel = true;
     else
@@ -185,7 +230,8 @@
     else
         recGroupType[recGroup] = "recgroup";
 
-    setDefaultView(gContext->GetNumSetting("DisplayGroupDefaultView", 0));
+    setDefaultView((ViewType)gContext->GetNumSetting("DisplayGroupDefaultView",
+                TitlesOnly));
 
     fullRect = QRect(0, 0, size().width(), size().height());
     listRect = QRect(0, 0, 0, 0);
@@ -313,26 +359,36 @@
     }
 }
 
-void PlaybackBox::setDefaultView(int defaultView)
+void PlaybackBox::setDefaultView(ViewType defaultView)
 {
+    int mask;
+
     switch (defaultView)
     {
         default:
-        case TitlesOnly: titleView = true; useCategories = false; 
-                         useRecGroups = false; break;
-        case TitlesCategories: titleView = true; useCategories = true; 
-                               useRecGroups = false; break;
-        case TitlesCategoriesRecGroups: titleView = true; useCategories = true;
-                                        useRecGroups = true; break;
-        case TitlesRecGroups: titleView = true; useCategories = false; 
-                              useRecGroups = true; break;
-        case Categories: titleView = false; useCategories = true; 
-                         useRecGroups = false; break;
-        case CategoriesRecGroups: titleView = false; useCategories = true; 
-                                  useRecGroups = true; break;
-        case RecGroups: titleView = false; useCategories = false; 
-                        useRecGroups = true; break;
+        case TitlesOnly:
+            mask = VIEW_TITLES;
+            break;
+        case TitlesCategories:
+            mask = VIEW_TITLES |    VIEW_CATEGORIES;
+            break;
+        case TitlesCategoriesRecGroups:
+            mask = VIEW_TITLES |    VIEW_CATEGORIES |   VIEW_RECGROUPS;
+            break;
+        case TitlesRecGroups:
+            mask = VIEW_TITLES |                        VIEW_RECGROUPS;
+            break;
+        case Categories:
+            mask =                  VIEW_CATEGORIES;
+            break;
+        case CategoriesRecGroups:
+            mask =                  VIEW_CATEGORIES |   VIEW_RECGROUPS;
+            break;
+        case RecGroups:
+            mask =                                      VIEW_RECGROUPS;
+            break;
     }
+    viewMask = (PlaybackBox::ViewMask)mask;
 }
 
 /* blocks until playing has stopped */
@@ -1133,14 +1189,15 @@
 
                 tempInfo = plist->at(skip+cnt);
 
-                if ((titleList[titleIndex] == "") || (!(titleView)))
+                if (titleList[titleIndex] == "" || !(viewMask & VIEW_TITLES))
                     tempSubTitle = tempInfo->title; 
                 else
                     tempSubTitle = tempInfo->subtitle;
                 if (tempSubTitle.stripWhiteSpace().length() == 0)
                     tempSubTitle = tempInfo->title;
                 if ((tempInfo->subtitle).stripWhiteSpace().length() > 0 
-                    && ((titleList[titleIndex] == "") || (!(titleView))))
+                    && (titleList[titleIndex] == ""
+                        || !(viewMask & VIEW_TITLES)))
                 {
                     tempSubTitle = tempSubTitle + " - \"" + 
                         tempInfo->subtitle + "\"";
@@ -1351,6 +1408,7 @@
     QString oldprogramid;
     QDate oldoriginalAirDate;
     QDateTime oldstartts;
+    int oldrecpriority = 0;
     p = progLists[oldtitle].at(progIndex);
     if (p)
     {
@@ -1358,6 +1416,7 @@
         oldstartts = p->recstartts;
         oldprogramid = p->programid;
         oldoriginalAirDate = p->originalAirDate;
+        oldrecpriority = p->recpriority;
     }
 
     QMap<QString, AvailableStatusType> asCache;
@@ -1377,8 +1436,10 @@
 
     fillRecGroupPasswordCache();
 
+    ViewTitleSort titleSort = (ViewTitleSort)gContext->GetNumSetting(
+            "DisplayGroupTitleSort", TitleSortAlphabetical);
+
     QMap<QString, QString> sortedList;
-    QRegExp prefixes = tr("^(The |A |An )");
     QString sTitle = "";
 
     vector<ProgramInfo *> *infoList;
@@ -1397,7 +1458,7 @@
                  (p->category == recGroup ) &&
                  ( !recGroupPwCache.contains(p->recgroup))))
             {
-                if ((titleView) || (useCategories) || (useRecGroups))
+                if (viewMask != VIEW_NONE)
                     progLists[""].prepend(p);
 
                 asKey = p->MakeUniqueKey();
@@ -1406,30 +1467,32 @@
                 else
                     p->availableStatus = asAvailable;
 
-                if (titleView) // Normal title view 
+                if ((viewMask & VIEW_TITLES)) // Show titles
                 {
                     progLists[p->title].prepend(p);
-                    sTitle = p->title;
-                    sTitle.remove(prefixes);
+                    sTitle = sortTitle(p->title, viewMask, titleSort,
+                            p->recpriority);
                     sortedList[sTitle] = p->title;
                 } 
 
-                if (useRecGroups) // Show recording groups                 
+                if ((viewMask & VIEW_RECGROUPS)) // Show recording groups                 
                 { 
                     progLists[p->recgroup].prepend(p);
                     sortedList[p->recgroup] = p->recgroup;
 
-                    // If another view is also used, unset autodelete as another group will do it.
-                    if ((useCategories) || (titleView))
+                    // If another view is also used, unset autodelete as
+                    // another group will do it.
+                    if ((viewMask & ~VIEW_RECGROUPS))
                         progLists[p->recgroup].setAutoDelete(false);
                 }
 
-                if (useCategories) // Show categories
+                if ((viewMask & VIEW_CATEGORIES)) // Show categories
                 {
                     progLists[p->category].prepend(p);
                     sortedList[p->category] = p->category;
-                    // If another view is also used, unset autodelete as another group will do it
-                    if ((useRecGroups) || (titleView)) 
+                    // If another view is also used, unset autodelete as
+                    // another group will do it
+                    if ((viewMask & ~VIEW_CATEGORIES))
                         progLists[p->category].setAutoDelete(false);
                 }
             }
@@ -1450,8 +1513,6 @@
         return 0;
     }
 
-    titleList = sortedList.values();
-
     QString episodeSort = gContext->GetSetting("PlayBoxEpisodeSort", "Date");
 
     if (episodeSort == "OrigAirDate")
@@ -1487,19 +1548,23 @@
     // titles backwards until we find where we were or go past.  This
     // is somewhat inefficient, but it works.
 
-    QString oldsTitle = oldtitle;
-    oldsTitle.remove(prefixes);
+    QStringList sTitleList = sortedList.keys();
+    titleList = sortedList.values();
+
+    QString oldsTitle = sortTitle(oldtitle, viewMask, titleSort,
+            oldrecpriority);
     titleIndex = titleList.count() - 1;
-    for (int i = titleIndex; i >= 0; i--)
+    for (titleIndex = titleList.count() - 1; titleIndex >= 0; titleIndex--)
     {
-        sTitle = titleList[i];
-        sTitle.remove(prefixes);
+        sTitle = sTitleList[titleIndex];
         
         if (oldsTitle > sTitle)
+        {
+            if (titleIndex + 1 < (int)titleList.count())
+                titleIndex++;
             break;
+        }
 
-        titleIndex = i;
-
         if (oldsTitle == sTitle)
             break;
     }
@@ -2219,7 +2284,7 @@
  
     if (inTitle)
     {
-        if (titleView)
+        if ((viewMask & VIEW_TITLES))
             popup->addButton(tr("Toggle playlist for this Category/Title"),
                              this, SLOT(togglePlayListTitle()));
         else 
@@ -3105,8 +3170,7 @@
     if (expectingPopup)
         cancelPopup();
 
-    if (titleView) titleView = false;
-    else titleView = true;
+    viewMask = viewMaskToggle(viewMask, VIEW_TITLES);
 
     playList.clear();
     connected = FillList();      
@@ -3252,8 +3316,7 @@
         }
         else if (action == "TOGGLERECORD")
         {
-            if (titleView) titleView = false;
-            else titleView = true;
+            viewMask = viewMaskToggle(viewMask, VIEW_TITLES);
             connected = FillList();
             skipUpdate = false;
             update(fullRect);
@@ -3760,7 +3823,7 @@
     int result = recGroupPopup->ExecPopup();
 
     if (result == MythDialog::Accepted)
-        setDefaultView(recGroupComboBox->currentItem());
+        setDefaultView((ViewType)recGroupComboBox->currentItem());
 
     delete recGroupComboBox;
 
@@ -4324,3 +4387,5 @@
     else
         recGroupOkButton->setEnabled(false);
 }
+
+// vim:set sw=4 ts=4 expandtab:
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 7946)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -4,6 +4,7 @@
 #include "dbsettings.h"
 #include "langsettings.h"
 #include "mpeg/iso639.h"
+#include "playbackbox.h"
 #include "globalsettings.h"
 #include "recordingprofile.h"
 #include "scheduledrecording.h"
@@ -288,13 +289,21 @@
     HostComboBox *gc = new HostComboBox("DisplayGroupDefaultView");
     gc->setLabel(QObject::tr("Default View"));
 
-    gc->addSelection(QObject::tr("Show Titles only"), "0");
-    gc->addSelection(QObject::tr("Show Titles and Categories"), "1");
-    gc->addSelection(QObject::tr("Show Titles, Categories, and Recording Groups"), "2");
-    gc->addSelection(QObject::tr("Show Titles and Recording Groups"), "3");
-    gc->addSelection(QObject::tr("Show Categories only"), "4");
-    gc->addSelection(QObject::tr("Show Categories and Recording Groups"), "5");
-    gc->addSelection(QObject::tr("Show Recording Groups only"), "6");
+    gc->addSelection(QObject::tr("Show Titles only"),
+            QString::number(PlaybackBox::TitlesOnly));
+    gc->addSelection(QObject::tr("Show Titles and Categories"),
+            QString::number(PlaybackBox::TitlesCategories));
+    gc->addSelection(QObject::tr(
+                "Show Titles, Categories, and Recording Groups"),
+            QString::number(PlaybackBox::TitlesCategoriesRecGroups));
+    gc->addSelection(QObject::tr("Show Titles and Recording Groups"),
+            QString::number(PlaybackBox::TitlesRecGroups));
+    gc->addSelection(QObject::tr("Show Categories only"),
+            QString::number(PlaybackBox::Categories));
+    gc->addSelection(QObject::tr("Show Categories and Recording Groups"),
+            QString::number(PlaybackBox::CategoriesRecGroups));
+    gc->addSelection(QObject::tr("Show Recording Groups only"),
+            QString::number(PlaybackBox::RecGroups));
 
     gc->setHelpText(QObject::tr("Select what type of grouping to show on the Watch Recordings screen "
                     "by default."));
@@ -2217,6 +2226,35 @@
     return gc;
 }
 
+class DefaultViewSettings: public VerticalConfigurationGroup,
+                           public TriggeredConfigurationGroup {
+public:
+    DefaultViewSettings():
+            VerticalConfigurationGroup(false, false, true, true),
+            TriggeredConfigurationGroup(false) {
+
+        HostComboBox *defaultView = DefaultView();
+        addChild(defaultView);
+        setTrigger(defaultView);
+
+        HostComboBox *titleSort = new HostComboBox("DisplayGroupTitleSort");
+        titleSort->setLabel(tr("Sort Titles"));
+        titleSort->addSelection(tr("Alphabetically"),
+                QString::number(PlaybackBox::TitleSortAlphabetical));
+        titleSort->addSelection(tr("By Recording Priority"),
+                QString::number(PlaybackBox::TitleSortRecPriority));
+
+        for (unsigned int ii = 0; ii < PlaybackBox::ViewTypes; ii++)
+        {
+            if (ii == PlaybackBox::TitlesOnly)
+                addTarget(QString::number(ii), titleSort);
+            else
+                addTarget(QString::number(ii),
+                        new VerticalConfigurationGroup(false, false));
+        }
+    }
+};
+
 static HostCheckBox *PVR350OutputEnable()
 {
     HostCheckBox *gc = new HostCheckBox("PVR350OutputEnable");
@@ -3017,7 +3055,7 @@
     pbox2->addChild(QueryInitialFilter());
     pbox2->addChild(RememberRecGroup());
     pbox2->addChild(UseGroupNameAsAllPrograms());
-    pbox2->addChild(DefaultView());
+    pbox2->addChild(new DefaultViewSettings());
     addChild(pbox2);
 
     addChild(new HwDecSettings());
@@ -3244,3 +3282,4 @@
     addChild(xboxset);
 }
 
+// vim:set sw=4 ts=4 expandtab:
Index: programs/mythfrontend/playbackbox.h
===================================================================
--- programs/mythfrontend/playbackbox.h	(revision 7946)
+++ programs/mythfrontend/playbackbox.h	(working copy)
@@ -1,4 +1,5 @@
 // -*- Mode: c++ -*-
+// vim:set sw=4 ts=4 expandtab:
 #ifndef PLAYBACKBOX_H_
 #define PLAYBACKBOX_H_
 
@@ -32,10 +33,34 @@
     Q_OBJECT
   public:
     typedef enum { Play, Delete } BoxType;
-    typedef enum { TitlesOnly, TitlesCategories, TitlesCategoriesRecGroups,
-                   TitlesRecGroups, Categories, CategoriesRecGroups, RecGroups} ViewType;
 
+    // ViewType values cannot change; they are stored in the database.
+    typedef enum {
+        TitlesOnly = 0,
+        TitlesCategories = 1,
+        TitlesCategoriesRecGroups = 2,
+        TitlesRecGroups = 3,
+        Categories = 4,
+        CategoriesRecGroups = 5,
+        RecGroups = 6,
+        ViewTypes,                  // placeholder value, not in database
+    } ViewType;
 
+    // Sort function when TitlesOnly. Values are stored in database.
+    typedef enum {
+        TitleSortAlphabetical = 0,
+        TitleSortRecPriority = 1,
+        TitleSortMethods,           // placeholder value, not in database
+    } ViewTitleSort;
+
+    typedef enum {
+        VIEW_NONE       =  0x00,
+        VIEW_TITLES     =  0x01,
+        VIEW_CATEGORIES =  0x02,
+        VIEW_RECGROUPS  =  0x04,
+        VIEW_ALL        = ~0x00,
+    } ViewMask;
+
     PlaybackBox(BoxType ltype, MythMainWindow *parent, const char *name = 0);
    ~PlaybackBox(void);
    
@@ -322,11 +347,9 @@
     int listOrder;
 
     bool playingSomething;
-    bool titleView;
 
-    bool useRecGroups;
-    bool useCategories;
-    void setDefaultView(int defaultView);
+    ViewMask viewMask;
+    void setDefaultView(ViewType defaultView);
 
     yuv2rgb_fun    conv_yuv2rgba;
     unsigned char *conv_rgba_buf;
Index: programs/mythbackend/mainserver.cpp
===================================================================
--- programs/mythbackend/mainserver.cpp	(revision 7946)
+++ programs/mythbackend/mainserver.cpp	(working copy)
@@ -957,7 +957,7 @@
                        "recorded.lastmodified, recorded.findid, "
                        "recorded.originalairdate, recorded.timestretch, "
                        "recorded.basename, recorded.progstart, "
-                       "recorded.progend "
+                       "recorded.progend, recorded.recpriority "
                        "FROM recorded "
                        "LEFT JOIN record ON recorded.recordid = record.recordid "
                        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
@@ -1069,6 +1069,8 @@
 
             proginfo->recgroup = query.value(16).toString();
 
+            proginfo->recpriority = query.value(31).toInt();
+
             proginfo->recstatus = rsRecorded;
             if (proginfo->recendts > rectime)
             {
@@ -3955,3 +3957,4 @@
     recording.setAttribute( "preRollSeconds", gContext->GetNumSetting("RecordPreRoll", 0));
 }
 
+// vim:set sw=4 ts=4 expandtab:
