Index: mythvideo/videodlg.h
===================================================================
--- mythvideo/videodlg.h	(revision 6799)
+++ mythvideo/videodlg.h	(working copy)
@@ -51,7 +51,6 @@
         virtual void updateBackground(void);
         virtual void parseContainer(QDomElement&) = 0;
         virtual void loadWindow(QDomElement &element);
-        virtual void handleMetaFetch(Metadata*){}
         virtual void fetchVideos();
         virtual void setParentalLevel(int which_level);
         void shiftParental(int amount);
Index: mythvideo/videolist.h
===================================================================
--- mythvideo/videolist.h	(revision 6799)
+++ mythvideo/videolist.h	(working copy)
@@ -28,10 +28,11 @@
 
         GenericTree *buildVideoList(bool filebrowser, bool flatlist,
                                                         int parental_level);
-        Metadata *getVideoListMetadata(int id);
-        QMap<int, Metadata>& getVideoListMetas(void);
+        Metadata *getVideoListMetadata(int index);
         void wantVideoListUpdirs(bool yes);
         VideoFilterSettings *getCurrentVideoFilter() { return currentVideoFilter; }
+        unsigned int count(void) const { return metas.count(); }
+
     private:
         void buildFsysList(bool flatlist, int parental_level);
         void buildDbList(bool flatlist, int parental_level);
@@ -50,8 +51,10 @@
         bool has_updirs; // True if tree has updirs
         QStringList  browser_mode_files;
         GenericTree *video_tree_root;
-        QMap<int, Metadata> metas;
+        QValueVector<Metadata> metas;   // sorted/indexed by current filter
         VideoFilterSettings *currentVideoFilter;
 };
 
 #endif // VIDEOLIST_H
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: mythvideo/videobrowser.h
===================================================================
--- mythvideo/videobrowser.h	(revision 6799)
+++ mythvideo/videobrowser.h	(working copy)
@@ -14,8 +14,6 @@
 
 #include "videodlg.h"
 
-typedef QValueList<Metadata>  ValueMetadata;
-
 class VideoBrowser : public VideoDialog
 {
     Q_OBJECT
@@ -29,7 +27,6 @@
     void cursorRight();
     
     virtual void slotParentalLevelChanged();
-    
 
   protected:
     virtual void parseContainer(QDomElement &element);
@@ -37,35 +34,26 @@
     void keyPressEvent(QKeyEvent *e);
     void doMenu(bool info=false);
     virtual void fetchVideos();
-    virtual void handleMetaFetch(Metadata* meta);
     
     LayerSet* getContainer(const QString &name);
     
   private:
     QPixmap getPixmap(QString &level);
+    void jumpToSelection(int amount);
     void jumpSelection(int amount);
-    void RefreshMovieList();
-    void SetCurrentItem();
+    void SetCurrentItem(unsigned int index);
     void updateInfo(QPainter *);
     void updateBrowsing(QPainter *);
     void updatePlayWait(QPainter *);
     void grayOut(QPainter *);
 
-    bool updateML;
-    bool allowselect;
-           
-    ValueMetadata m_list;
-    
     QPixmap *bgTransBackup;
-    
-
     QPainter backup;
 
-    int inData;
+    unsigned int inData;	// index of curItem in VideoList.metas
     int m_state;
 
     QString m_title;
-    QString curitemMovie;
     
     QRect infoRect;
     QRect browsingRect;
Index: mythvideo/videofilter.h
===================================================================
--- mythvideo/videofilter.h	(revision 6799)
+++ mythvideo/videofilter.h	(working copy)
@@ -27,6 +27,15 @@
         QString BuildClauseWhere();
         QString BuildClauseOrderBy();
         void saveAsDefault();
+
+        enum ordering {
+            // These values must be explicitly assigned; they represent
+            // database values
+            kOrderByTitle = 0,
+            kOrderByYearDescending = 1,
+            kOrderByUserRatingDescending = 2,
+            kOrderByLength = 3,
+        };
         
         int getCategory(void){return category;};
         void setCategory (int lcategory){category = lcategory;};
@@ -40,13 +49,10 @@
         void setRuntime (int lruntime){runtime = lruntime;};
         int getUserrating(void){return userrating;};
         void setUserrating (int luserrating){userrating = luserrating;};
-        /*int getShowlevel(void){return showlevel;};
-        void setShowlevel (int lshowlevel)
-        {showlevel = lshowlevel;};*/
         int getBrowse(void){return browse;};
         void setBrowse(int lbrowse){browse = lbrowse;};
-        int getOrderby (void) {return orderby;};
-        void setOrderby (int lorderby) {orderby = lorderby;};
+        enum ordering getOrderby (void) {return orderby;};
+        void setOrderby (enum ordering lorderby) {orderby = lorderby;};
     
     private : 
         int category;
@@ -56,7 +62,7 @@
         int runtime;
         int userrating;
         int browse;
-        int orderby;
+        enum ordering orderby;
         QString prefix;
 };
 
@@ -95,9 +101,8 @@
     void setCountry(int new_country);
     void setGenre(int new_genre);
     void setRunTime(int new_runtime);
-//    void setShowlevel(int new_showlevel);
     void setBrowse(int new_browse);
-    void setOrderby(int new_orderby);
+    void setOrderby(/* enum VideoFilterSettings::ordering */ int new_orderby);
  private:
     void update_numvideo();
     VideoFilterSettings *originalSettings;
@@ -121,3 +126,5 @@
 
 
 #endif
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: mythvideo/videoselected.h
===================================================================
--- mythvideo/videoselected.h	(revision 6799)
+++ mythvideo/videoselected.h	(working copy)
@@ -33,7 +33,7 @@
     Q_OBJECT
   public:
     VideoSelected(VideoList *lvideolist,
-                 MythMainWindow *parent, const char *name = 0, int idnum = 0);
+                 MythMainWindow *parent, const char *name = 0, int index = 0);
     ~VideoSelected();
     void VideoSelected::processEvents() { qApp->processEvents(); }
     
Index: mythvideo/main.cpp
===================================================================
--- mythvideo/main.cpp	(revision 6799)
+++ mythvideo/main.cpp	(working copy)
@@ -73,6 +73,9 @@
     REG_KEY("Video","BROWSE","Change browsable in video manager","B");
     REG_KEY("Video","INCPARENT","Increase Parental Level","],},F11");
     REG_KEY("Video","DECPARENT","Decrease Parental Level","[,{,F10");
+
+    REG_KEY("Video","HOME","Go to the first video","Home");
+    REG_KEY("Video","END","Go to the last video","End");
 }
 
 
Index: mythvideo/videogallery.h
===================================================================
--- mythvideo/videogallery.h	(revision 6799)
+++ mythvideo/videogallery.h	(working copy)
@@ -28,14 +28,11 @@
 #include "videodlg.h"
 
 
-typedef QValueList<Metadata>  ValueMetadata;
-
 class VideoGallery : public VideoDialog
 {
     Q_OBJECT
   public:
     VideoGallery(MythMainWindow *parent, const char *name = 0);
-    ~VideoGallery();
     
     void processEvents() { qApp->processEvents(); }
     
@@ -74,7 +71,6 @@
 
     void positionIcon();
     
-    int curView;
     bool subtitleOn;
     bool keepAspectRatio;
     QString curPath;
@@ -103,14 +99,13 @@
     int thumbH;
 
     bool allowselect;
-    bool updateML;
     
     QString prefix;
     
     GenericTree *video_tree_root;
     GenericTree *where_we_are;
 
-    //typedef void (VideoGallery::*Action)(UIListBtnTypeItem*);
+    void computeLastRowCol(int list_count);
 };
 
 #endif
Index: mythvideo/videodlg.cpp
===================================================================
--- mythvideo/videodlg.cpp	(revision 6799)
+++ mythvideo/videodlg.cpp	(working copy)
@@ -456,21 +456,8 @@
 
 void VideoDialog::fetchVideos()
 {
-    typedef QMap<int, Metadata> metaMap;
-    
-    metaMap myMetas;
-    metaMap::Iterator it;
-
     video_tree_root = video_list->buildVideoList(isFileBrowser, isFlatList,
                                                  currentParentalLevel);
-
-    // XXX: This is suboptimal. The classes should not need this. They
-    //      can retrieve the data through VideoList::getVideoListMetadata()
-    myMetas = video_list->getVideoListMetas();
-    for (it = myMetas.begin(); it != myMetas.end(); ++it) {
-            handleMetaFetch(&it.data());
-    }
-
 }
 
 void VideoDialog::slotDoFilter()
Index: mythvideo/videolist.cpp
===================================================================
--- mythvideo/videolist.cpp	(revision 6799)
+++ mythvideo/videolist.cpp	(working copy)
@@ -20,24 +20,17 @@
     delete currentVideoFilter;
 }
 
-Metadata *VideoList::getVideoListMetadata(int id)
+Metadata *VideoList::getVideoListMetadata(int index)
 {
-    if (id < 0) {
-        // These are special node types
-        return NULL;
-    }
-    if (metas.contains(id))
-        return(&metas[id]);
-    else {
-        cerr << __FILE__ << ": getVideoListMetadata: unknown key:"
-                << id << endl;
-        return NULL;
-    }
-}
+    if (index < 0)
+        return NULL;    // Special node types
 
-QMap<int, Metadata>& VideoList::getVideoListMetas(void)
-{
-    return(metas);
+    if ((unsigned int)index < count())
+        return(&metas[index]);
+
+    cerr << __FILE__ << ": getVideoListMetadata: index out of bounds: "
+        << index << endl;
+    return NULL;
 }
 
 void VideoList::wantVideoListUpdirs(bool yes)
@@ -68,7 +61,8 @@
 //      If false, the hierarchy present on the filesystem or in the database
 //      is preserved. In this mode, both sub-dirs and updirs are present.
 
-GenericTree *VideoList::buildVideoList(bool filebrowser, bool flatlist, int parental_level)
+GenericTree *VideoList::buildVideoList(bool filebrowser, bool flatlist,
+    int parental_level)
 {
     // Clear out the old stuff
     browser_mode_files.clear();
@@ -119,76 +113,100 @@
         
     MSqlQuery query(MSqlQuery::InitCon());
     query.exec(thequery);
-    Metadata *myData;
+    unsigned int numrows;
 
-    if(!query.isActive())
+    if (!query.isActive())
     {
         cerr << __FILE__ << ": Your database sucks" << endl;
+        return;
     }
-    else if (query.numRowsAffected() > 0)
+
+    if ((numrows = query.numRowsAffected()) <= 0)
+        return;
+
+    QString prefix = gContext->GetSetting("VideoStartupDir");
+    if (prefix.length() < 1)
     {
-        QString prefix = gContext->GetSetting("VideoStartupDir");
-        if(prefix.length() < 1)
-        {
-            cerr << __FILE__ <<
-                         ": Seems unlikely that this is going to work" << endl;
-        }
+        cerr << __FILE__ << ": Seems unlikely that this is going to work" <<
+            endl;
+    }
 
-        if (!flatlist)
-            (void)addDirNode(video_tree_root, "videos");
+    if (!flatlist)
+        (void)addDirNode(video_tree_root, "videos");
 
-        
-        // Let's loop over the query and build a sorted list
-        QMap<QString, Metadata*> sortedList;
+    //
+    //  Accumulate query results into the metaptrs list. The "parental_level"
+    //  filtering really ought to be incorporated into BuildClauseWhere().
+    //
+    QPtrList<Metadata> metaptrs;
+    while (query.next())
+    {
+        unsigned int intid = query.value(0).toUInt();
+        Metadata *myData = new Metadata();
+        myData->setID(intid);
+        myData->fillDataFromID();
+        if (myData->ShowLevel() <= parental_level && myData->ShowLevel() != 0)
+            metaptrs.append(myData);
+        else
+            delete myData;
+    }
+
+    //
+    //  If sorting by title, re-sort by hand because the SQL sort doesn't
+    //  ignore articles when sorting. This assumes all titles are in English.
+    //  This means a movie with a foreign-language title like "A la carte" will
+    //  be incorrectly alphabetized, because the "A" is actually significant.
+    //  The set of ignored prefixes should be a database option, or each
+    //  video's metadata should include a separate sort key.
+    //
+    if (currentVideoFilter->getOrderby() == VideoFilterSettings::kOrderByTitle)
+    {
+        //
+        //  Pull things off the metaptrs list and put them into the
+        //  "stringsort" qmap (which will automatically sort them by qmap key).
+        //
+        QMap<QString, Metadata*> stringsort;
         QRegExp prefixes = QObject::tr("^(The |A |An )");
-        QString sTitle = "";
-    
-        while (query.next())
+        while (!metaptrs.isEmpty())
         {
-            unsigned int idnum = query.value(0).toUInt();
-            //
-            //  Create metadata object and fill it
-            //
-        
-            myData = new Metadata();
-            myData->setID(idnum);
-            myData->fillDataFromID();
-            sTitle = myData->Title();
+            Metadata *myData = metaptrs.take(0);
+            QString sTitle = myData->Title();
             sTitle.remove(prefixes);
-            sortedList[sTitle] = myData;
+            stringsort[sTitle] = myData;
         }
-        
-        QMap<QString, Metadata*>::iterator it = sortedList.begin();
-        
-        for ( ; it != sortedList.end(); it++)
+
+        //
+        //  Now walk through the "stringsort" qmap and put them back on the
+        //  list (in stringsort order).
+        //
+        for (QMap<QString, Metadata*>::iterator it = stringsort.begin();
+                it != stringsort.end();
+                it++)
         {
-            GenericTree *where_to_add = video_tree_root->getChildAt(0);
+            metaptrs.append(*it);
+        }
+    }
 
-            //
-            //  Create metadata object and fill it
-            //
-        
-            myData = *it;
-            if ((myData->ShowLevel() <= parental_level) &&
-                (myData->ShowLevel() != 0))
-            {
-                QString file_string = myData->Filename();
-                file_string.remove(0, prefix.length());
-                if (!flatlist) 
-                {
-
-                    where_to_add = addFileNode(where_to_add, file_string, myData->ID());
-                }
-                else 
-                {
-                    video_tree_root->addNode(file_string, myData->ID(), true);
-                    nitems++;
-                }
-                metas[myData->ID()] = *myData; 
-            }
-
-            delete myData;
+    //
+    //  Build list of videos.
+    //
+    for (unsigned int count = 0; !metaptrs.isEmpty(); count++)
+    {
+        Metadata *myData = metaptrs.take(0);
+        GenericTree *where_to_add = video_tree_root->getChildAt(0);
+        QString file_string = myData->Filename();
+        file_string.remove(0, prefix.length());
+        if (flatlist) 
+        {
+            video_tree_root->addNode(file_string, count, true);
+            nitems++;
         }
+        else 
+        {
+            where_to_add = addFileNode(where_to_add, file_string, count);
+        }
+        metas.append(*myData);
+        delete myData;
     }
 }
 
@@ -304,7 +322,7 @@
             // XXX: Maybe more...
         }
 
-        metas[i] = *myData; 
+        metas.append(*myData); 
 
         if (myData->ShowLevel() <= parental_level && myData->ShowLevel() != 0)
         {
@@ -389,7 +407,7 @@
 }
 
 GenericTree *VideoList::addFileNode(GenericTree *where_to_add,
-                                                const QString& fname, int id)
+                                                const QString& fname, int index)
 {
     int a_counter = 0;
     GenericTree *sub_node;
@@ -401,7 +419,8 @@
         if(a_counter + 1 >= (int) list.count()) // video
         {
             QString title = (*an_it);
-            sub_node = where_to_add->addNode(title.section(".",0,-2), id, true);
+            sub_node = where_to_add->addNode(title.section(".",0,-2),
+                    index, true);
             sub_node->setAttribute(0, ORDER_ITEM);
             sub_node->setOrderingIndex(0);
             nitems++;
@@ -458,3 +477,5 @@
         else browser_mode_files.append(filename);
     }
 }
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: mythvideo/videobrowser.cpp
===================================================================
--- mythvideo/videobrowser.cpp	(revision 6799)
+++ mythvideo/videobrowser.cpp	(working copy)
@@ -24,11 +24,7 @@
 VideoBrowser::VideoBrowser(MythMainWindow *parent, const char *name)
             : VideoDialog(DLG_BROWSER, parent, "browser", name)
 {
-    updateML = false;
-    
     m_state = 0;
-    curitem = NULL;
-    inData = 0;
     
     setFileBrowser(gContext->GetNumSetting("VideoBrowserNoDB", 0));
     loadWindow(xmldata);        
@@ -40,16 +36,11 @@
     setNoErase();
 
     fetchVideos();
-
-    SetCurrentItem();
     updateBackground();
 }
 
 VideoBrowser::~VideoBrowser()
 {
-    if (curitem)
-        delete curitem;
-
     delete bgTransBackup;
 }
 
@@ -69,34 +60,39 @@
 {
     bool handled = false;
     QStringList actions;
-    gContext->GetMainWindow()->TranslateKeyPress("Video", e, actions);
 
+    gContext->GetMainWindow()->TranslateKeyPress("Video", e, actions);
     for (unsigned int i = 0; i < actions.size() && !handled; i++)
     {
         QString action = actions[i];
         handled = true;
 
-        if ((action == "SELECT" || action == "PLAY") && allowselect)
+        if ((action == "SELECT" || action == "PLAY") && curitem)
             playVideo(curitem);
         else if (action == "INFO")
             doMenu(true);
-        else if (action == "UP")
-            jumpSelection(1);
         else if (action == "DOWN")
+            jumpSelection(1);
+        else if (action == "UP")
             jumpSelection(-1);
         else if (action == "PAGEDOWN")
-            jumpSelection((int)(m_list.count() / 5));
+            jumpSelection(video_list->count() / 5);
         else if (action == "PAGEUP")
-            jumpSelection(0-(int)(m_list.count() / 5));
-        else if (action == "INCPARENT")
-            shiftParental(1);
-        else if (action == "DECPARENT")
-            shiftParental(-1);            
+            jumpSelection(-(video_list->count() / 5));
         else if (action == "LEFT")
             cursorLeft();
         else if (action == "RIGHT")
             cursorRight();
-        else if (action == "1" || action == "2" || action == "3" || action == "4")
+        else if (action == "HOME")
+            jumpToSelection(0);
+        else if (action == "END")
+            jumpToSelection(video_list->count() - 1);
+        else if (action == "INCPARENT")
+            shiftParental(1);
+        else if (action == "DECPARENT")
+            shiftParental(-1);            
+        else if (action == "1" || action == "2" ||
+                action == "3" || action == "4")
             setParentalLevel(action.toInt());
         else if (action == "FILTER")
             slotDoFilter();
@@ -120,7 +116,6 @@
             }
         }            
     }
-
     
     if (!handled)
         MythDialog::keyPressEvent(e);
@@ -159,27 +154,15 @@
 
 void VideoBrowser::fetchVideos()
 {
-    if (updateML == true)
-        return;
-    
-    updateML = true;
-    m_list.clear();
-
     VideoDialog::fetchVideos();
-    video_list->wantVideoListUpdirs(true);
+    video_list->wantVideoListUpdirs(isFileBrowser);
     
-    updateML = false;
-    SetCurrentItem();
+    SetCurrentItem(0);
     update(infoRect);
     update(browsingRect);
     repaint();
 }
 
-void VideoBrowser::handleMetaFetch(Metadata* meta)
-{
-    m_list.append(*meta);
-}
-
 void VideoBrowser::grayOut(QPainter *tmp)
 {
    int transparentFlag = gContext->GetNumSetting("PlayBoxShading", 0);
@@ -243,44 +226,17 @@
 }
 
 
-void VideoBrowser::SetCurrentItem()
+void VideoBrowser::SetCurrentItem(unsigned int index)
 {
-    ValueMetadata::Iterator it;
-
-    if(curitem)
-    {
-        delete curitem;
-    }
     curitem = NULL;
     
+    unsigned int list_count = video_list->count();
     
-    //
-    //  The count may have changed because
-    //  the Parental Level might have been
-    //  altered
-    //
+    if (list_count == 0)
+        return;
 
-    int list_count = m_list.count();
-    
-    if(list_count == 0)
-    {
-        inData = 0;
-        allowselect = false;
-    }
-    else
-    {
-        if(inData < list_count)
-        {
-            it = m_list.at(inData);
-        }
-        else
-        {
-            inData = 0;
-            it = m_list.begin();
-        }
-
-        curitem = new Metadata(*(it));
-    }
+    inData = QMIN(list_count - 1, index);
+    curitem = video_list->getVideoListMetadata(inData);
 }
 
 void VideoBrowser::updateBrowsing(QPainter *p)
@@ -289,16 +245,13 @@
     QPixmap pix(pr.size());
     pix.fill(this, pr.topLeft());
     QPainter tmp(&pix);
+    unsigned int list_count = video_list->count();
 
     QString vidnum;  
-    if(m_list.count() > 0)
-    {
-        vidnum = QString(tr("%1 of %2")).arg(inData + 1).arg(m_list.count());
-    }
+    if (list_count > 0)
+        vidnum = QString(tr("%1 of %2")).arg(inData + 1).arg(list_count);
     else
-    {
         vidnum = tr("No Videos");
-    }
 
     LayerSet *container = NULL;
     container = theme->GetSet("browsing");
@@ -334,7 +287,7 @@
     pix.fill(this, pr.topLeft());
     QPainter tmp(&pix);
 
-    if (m_list.count() > 0 && curitem)
+    if (video_list->count() > 0 && curitem)
     {
        QString title = curitem->Title();
        QString filename = curitem->Filename();
@@ -426,8 +379,6 @@
            container->Draw(&tmp, 7, 0);
            container->Draw(&tmp, 8, 0);
        }
-
-       allowselect = true;
     }
     else
     {
@@ -440,27 +391,31 @@
            norec->Draw(&tmp, 7, 0);
            norec->Draw(&tmp, 8, 0);
        }
-
-       allowselect = false;
     }
     tmp.end();
     p->drawPixmap(pr.topLeft(), pix);
 
 }
 
-void VideoBrowser::jumpSelection(int amount)
+void VideoBrowser::jumpToSelection(int index)
 {
-    inData += amount;
-     
-    if (inData < 0)
-        inData = m_list.count() + inData;
-    else if(inData >= (int)m_list.count())
-        inData = inData - m_list.count();
-     
-    SetCurrentItem();
+    SetCurrentItem(index);
     update(infoRect);
     update(browsingRect);
 }
+
+void VideoBrowser::jumpSelection(int amount)
+{
+    unsigned int list_count = video_list->count();
+    int index;
+
+    if (amount >= 0 || inData >= (unsigned int)-amount)
+        index = (inData + amount) % list_count;
+    else
+        index = list_count + amount + inData;  // unsigned arithmetic
+
+    jumpToSelection(index);
+}
    
 
 void VideoBrowser::cursorLeft()
@@ -486,3 +441,4 @@
         browsingRect = area;
 }
 
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: mythvideo/videofilter.cpp
===================================================================
--- mythvideo/videofilter.cpp	(revision 6799)
+++ mythvideo/videofilter.cpp	(working copy)
@@ -26,7 +26,8 @@
         runtime = gContext->GetNumSetting( QString("%1Runtime").arg(prefix),-2);
         userrating = gContext->GetNumSetting( QString("%1Userrating").arg(prefix),-1);
         browse = gContext->GetNumSetting( QString("%1Browse").arg(prefix),-1);
-        orderby = gContext->GetNumSetting( QString("%1Orderby").arg(prefix),0);
+        orderby = (enum ordering)gContext->GetNumSetting(
+                QString("%1Orderby").arg(prefix),kOrderByTitle);
     }
     else
     {
@@ -37,7 +38,7 @@
         runtime = -2;
         userrating = -1;
         browse = -1;
-        orderby = 0;
+        orderby = kOrderByTitle;
     }
 
 }
@@ -206,13 +207,13 @@
 {
     switch (orderby)
     {
-        case 0 : 
+        case kOrderByTitle : 
             return " ORDER BY title";
-        case 1 : 
+        case kOrderByYearDescending : 
             return " ORDER BY year DESC";
-        case 2 : 
+        case kOrderByUserRatingDescending : 
             return " ORDER BY userrating DESC";
-        case 3 : 
+        case kOrderByLength : 
             return " ORDER BY length";
         default:
             return "";        
@@ -493,8 +494,8 @@
 
 void VideoFilterDialog::saveAndExit()
 {
-     if (originalSettings)
-     {
+    if (originalSettings)
+    {
         originalSettings->setCategory(currentSettings->getCategory());
         originalSettings->setGenre(currentSettings->getGenre());
         originalSettings->setCountry(currentSettings->getCountry());
@@ -557,7 +558,8 @@
 
 void VideoFilterDialog::setOrderby(int new_orderby)
 {
-        currentSettings->setOrderby(new_orderby);
+        currentSettings->setOrderby(
+                (enum VideoFilterSettings::ordering)new_orderby);
         update_numvideo();
 }
 
@@ -630,3 +632,4 @@
 {
 }
 
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: mythvideo/videoselected.cpp
===================================================================
--- mythvideo/videoselected.cpp	(revision 6799)
+++ mythvideo/videoselected.cpp	(working copy)
@@ -33,12 +33,12 @@
 
 VideoSelected::VideoSelected(VideoList *lvideo_list,
                              MythMainWindow *parent, const char *name, 
-                             int idnum)
+                             int index)
             : MythDialog(parent, name)
 {
     video_list = lvideo_list;
 
-    curitem = video_list->getVideoListMetadata(idnum);
+    curitem = video_list->getVideoListMetadata(index);
     curitem->fillDataFromID();
 
     noUpdate = false;
Index: mythvideo/metadata.h
===================================================================
--- mythvideo/metadata.h	(revision 6799)
+++ mythvideo/metadata.h	(working copy)
@@ -200,7 +200,7 @@
     QStringList genres;
     QStringList countries;
     QString player;
-    unsigned int id;
+    unsigned int id;	// videometadata.intid
     
     QString filename;
     QString coverfile;
Index: mythvideo/videogallery.cpp
===================================================================
--- mythvideo/videogallery.cpp	(revision 6799)
+++ mythvideo/videogallery.cpp	(working copy)
@@ -27,41 +27,20 @@
 #include <mythtv/mythcontext.h>
 #include <mythtv/util.h>
 
-enum GAL_VIEWS { VIEW_DB, VIEW_FILE };
-
 VideoGallery::VideoGallery(MythMainWindow *parent, const char *name)
             : VideoDialog(DLG_GALLERY, parent, "gallery", name)
 {
-    updateML = false;
+    setFileBrowser(gContext->GetNumSetting("VideoGalleryNoDB", 0));
+    setFlatList(!isFileBrowser);
 
-    // load default settings from the database
-    
-    if (gContext->GetNumSetting("VideoGalleryNoDB", false) == false)
-        curView = VIEW_DB;
-    else
-        curView = VIEW_FILE;
-        
     nCols                = gContext->GetNumSetting("VideoGalleryColsPerPage",4);
     nRows                = gContext->GetNumSetting("VideoGalleryRowsPerPage",3);
     subtitleOn           = gContext->GetNumSetting("VideoGallerySubtitle",1);
     keepAspectRatio      = gContext->GetNumSetting("VideoGalleryAspectRatio",1);
 
-
     // XXX Fixme: this is wrong...
     prefix = gContext->GetSetting("VideoStartupDir");
 
-    if (curView == VIEW_DB)
-    {
-        setFlatList(true);
-        setFileBrowser(false);
-    }
-    else
-    {
-        setFlatList(false);
-        setFileBrowser(true);
-    }
-    
-    
     loadWindow(xmldata);
     LoadIconWindow(); // load icon settings
 
@@ -70,91 +49,42 @@
     setNoErase();
 }
 
-VideoGallery::~VideoGallery()
-{
-    // save current settings as default
-    gContext->SaveSetting("VideoDefaultView", curView);
-}
-
-
-
 void VideoGallery::keyPressEvent(QKeyEvent *e)
 {
-    
     bool handled = false;
     QStringList actions;
     
-    gContext->GetMainWindow()->TranslateKeyPress("Global", e, actions);
+    gContext->GetMainWindow()->TranslateKeyPress("Video", e, actions);
     for (unsigned int i = 0; i < actions.size() && !handled; i++)
     {
         QString action = actions[i];
+        handled = true;
 
         if (action == "SELECT")
-        {
-            handled = true;
             handled = handleSelect();
-        }
-        else if ( (action == "UP")  || (action == "DOWN") ||
-                  (action == "LEFT") ||(action == "RIGHT") ||
-                  (action == "PAGEUP") || (action == "PAGEDOWN"))
-        {
-            handled = true;
+        else if (action == "INFO") {
+            if (where_we_are->getInt() > SUB_FOLDER)
+                doMenu(true);
+        } else if (action == "UP" || action == "DOWN" ||
+                 action == "LEFT" || action == "RIGHT" ||
+                 action == "PAGEUP" || action == "PAGEDOWN" ||
+                 action == "HOME" || action == "END")
             moveCursor(action);
-        }
+        else if (action == "INCPARENT")
+            shiftParental(1);
+        else if (action == "DECPARENT")
+            shiftParental(-1);            
         else if (action == "1" || action == "2" ||
                  action == "3" || action == "4")
-        {
-            handled = true;
-            setParentalLevel(action.toInt());        // parental control
-        }
-        
-        if (handled)
-            break;
-    }    
-    
-    
-    if (!handled)
-    {
-        gContext->GetMainWindow()->TranslateKeyPress("Video", e, actions);
-        for (unsigned int i = 0; i < actions.size() && !handled; i++)
-        {
-            QString action = actions[i];
-            handled = true;
-    
-            if (action == "SELECT")
-            {
-                handled = handleSelect();
-            }
-            else if (action == "FILTER")
-            {
-                slotDoFilter();
-            }
-            else if (action == "INFO")
-            {
-                // pop-up menu with video description
-                if ((where_we_are->getInt() > SUB_FOLDER ))
-                {
-                    doMenu(true);
-                }
-            }
-            else if (action == "INCPARENT")
-                shiftParental(1);
-            else if (action == "DECPARENT")
-                shiftParental(-1);            
-            else if (action == "MENU")
-            {
-                doMenu(false);
-            }
-            else if (action == "ESCAPE")
-            {
-                 handled = goBack();
-            }
-            else
-                handled = false;
-            
-            if (handled)
-                break;
-        }
+            setParentalLevel(action.toInt());
+        else if (action == "FILTER")
+            slotDoFilter();
+        else if (action == "MENU")
+            doMenu(false);
+        else if (action == "ESCAPE")
+            handled = goBack();
+        else
+            handled = false;
     }
     
     if (!handled)
@@ -180,7 +110,7 @@
 {
     bool handled = false;
     // one dir up
-    if ((curView == VIEW_FILE) && !jumping)
+    if (isFileBrowser && !jumping)
     {
         GenericTree *parent = where_we_are->getParent();
         if (parent)
@@ -205,18 +135,19 @@
      return handled;
 }
 
+void VideoGallery::computeLastRowCol(int list_count)
+{
+    lastRow = QMAX((int)ceilf((float)list_count / nCols) - 1, 0);
+    lastCol = (list_count % nCols - 1 + nCols) % nCols;
+}
+
 void VideoGallery::fetchVideos()
 {
-    if (updateML == true)
-        return;
-    updateML = true;
-    
     VideoDialog::fetchVideos();
-    video_tree_root = VideoDialog::getVideoTreeRoot();
+    video_list->wantVideoListUpdirs(isFileBrowser);
 
-    video_list->wantVideoListUpdirs(curView != VIEW_DB);
+    video_tree_root = VideoDialog::getVideoTreeRoot();
     video_tree_root->setOrderingIndex(0);
-    video_tree_root->sortByAttributeThenByString(0);
 
     //
     // Select initial view
@@ -228,7 +159,8 @@
 
     if (video_tree_root->childCount() > 0)
         where_we_are = video_tree_root->getChildAt(0,0);
-    else where_we_are = video_tree_root;
+    else
+        where_we_are = video_tree_root;
     
     // Move a node down if there is a single directory item here...
     if (where_we_are->siblingCount() == 1 && where_we_are->getInt() < 0)
@@ -236,24 +168,23 @@
         // Get rid of the up node, if it's there, it _should_ be the first
         // child...
         GenericTree *upnode = where_we_are->getChildAt(0,0);
-        if ((upnode != NULL) && (upnode->getInt() == UP_FOLDER))
-                where_we_are->removeNode(upnode);
+        if (upnode && upnode->getInt() == UP_FOLDER)
+            where_we_are->removeNode(upnode);
         if (where_we_are->childCount() > 1)
-                where_we_are = where_we_are->getChildAt(0,0);
+            where_we_are = where_we_are->getChildAt(0,0);
         // else { we have an empty tree! }
     }
     int list_count = where_we_are->siblingCount();
-    lastRow = QMAX((int)ceilf((float)list_count/(float)nCols)-1,0);
-    lastCol = QMAX(list_count-lastRow*nCols-1,0);
+    computeLastRowCol(list_count);
     
-    allowselect = (bool)(where_we_are->siblingCount() > 0);
+    allowselect = list_count > 0;
 
-    updateML = false;
     update();         // renew the screen
     
     if (where_we_are->getInt() >= 0)
         curitem = video_list->getVideoListMetadata(where_we_are->getInt());
-    else curitem = NULL;
+    else
+        curitem = NULL;
 }
 
 void VideoGallery::paintEvent(QPaintEvent *e)
@@ -350,17 +281,14 @@
 
     int list_count = parent->childCount();
 
-    int curPos = topRow*nCols;
-
-    for (int y = 0; y < nRows; y++)    {
-
+    for (int y = 0, curPos = topRow * nCols;
+            y < nRows && curPos < list_count;
+            y++)
+    {
         int ypos = y * (spaceH + thumbH);
 
-        for (int x = 0; x < nCols; x++)
+        for (int x = 0; x < nCols && curPos < list_count; x++)
         {
-            if (curPos >= list_count)
-                continue;
-
             int xpos = x * (spaceW + thumbW);
 
             GenericTree* curTreePos = parent->getChildAt(curPos,0);
@@ -414,7 +342,6 @@
 {
     QImage *image = 0;
     int yoffset = 0;
-    bool myImage = true;
     Metadata *meta = NULL;
 
     if (curTreePos->getInt() < 0) // directory
@@ -457,7 +384,6 @@
         meta = video_list->getVideoListMetadata(curTreePos->getInt());
 
         image = meta->getCoverImage();
-        myImage = false;
     }
 
     int bw  = backRegPix.width();
@@ -470,7 +396,7 @@
     {
 
         QPixmap *pixmap = NULL;
-        if (!myImage && meta && meta->haveCoverPixmap())
+        if (meta && meta->haveCoverPixmap())
             pixmap = meta->getCoverPixmap();
 
         if (!pixmap)
@@ -485,10 +411,10 @@
                           (pixmap->height()-bh+yoffset)/2+sh,
                           bw-2*sw, bh-2*sh-yoffset);
 
-        if (myImage)
-            delete pixmap;
-        else
+        if (meta)
             meta->setCoverPixmap(pixmap);
+        else
+            delete pixmap;
     }
 
 
@@ -546,7 +472,7 @@
         ttype->Draw(p, 3, 0);
     }
 
-    if (image && myImage)
+    if (image && !meta)
         delete image;
 }
 
@@ -663,97 +589,143 @@
 
 void VideoGallery::moveCursor(const QString& action)
 {
+    // Support wrap-around navigation, but not wrap-around display
+    int lastTopRow = QMAX(lastRow - nRows + 1, 0);
     int prevCol = currCol;
     int prevRow = currRow;
     int oldRow  = topRow;
 
     if (action == "LEFT")
     {
-        if (currRow == 0 && currCol == 0)
-            return;
-
-        currCol--;
-        if (currCol < 0) {
-            currCol = nCols - 1;
-            currRow--;
-            if (currRow < topRow)
-                topRow = currRow;
+        if (currCol > 0) {
+            currCol--;
+        } else {
+            if (currRow > 0) {
+                if (topRow == currRow)
+                    topRow--;
+                currRow--;
+                currCol = nCols - 1;
+            } else {
+                // "Flip" to last page
+                topRow = lastTopRow;
+                currRow = lastRow;
+                currCol = lastCol;
+            }
         }
     }
     else if (action == "RIGHT")
     {
-        if (currRow*nCols+currCol >= (int)(where_we_are->siblingCount())-1)
-            return;
-
-        currCol++;
-        if (currCol >= nCols) {
-            currCol = 0;
-            currRow++;
-            if (currRow >= topRow+nRows)
-                topRow++;
+        if (currRow < lastRow) {
+            if (currCol < nCols - 1) {
+                currCol++;
+            } else {
+                if (topRow + nRows - 1 == currRow)
+                    topRow++;
+                currRow++;
+                currCol = 0;
+            }
+        } else {
+            if (currCol < lastCol) {
+                currCol++;
+            } else {
+                // "Flip" to first page
+                topRow = 0;
+                currRow = 0;
+                currCol = 0;
+            }
         }
     }
     else if (action == "UP")
     {
-        if (currRow == 0) {
-            currRow = lastRow;
-            currCol = QMIN(currCol,lastCol);
-            topRow  = QMAX(currRow - nRows + 1,0);
-        } else {
+        if (currRow > 0) {
+            if (topRow == currRow)
+                topRow--;
             currRow--;
-            if (currRow < topRow)
-                topRow = currRow;
+        } else {
+            // "Flip" to last page
+            topRow = lastTopRow;
+            currRow = lastRow;
+            currCol = QMIN(currCol, lastCol);
         }
     }
     else if (action == "DOWN")
     {
-        if (currRow == lastRow) {
-            currRow = 0;
-            topRow = 0;
-        } else {
+        if (currRow < lastRow) {
+            if (topRow + nRows - 1 == currRow)
+                topRow++;
             currRow++;
-
             if (currRow == lastRow)
-                currCol = QMIN(currCol,lastCol);
-
-            if (currRow >= topRow+nRows)
-                topRow++;
+                currCol = QMIN(currCol, lastCol);
+        } else {
+            // "Flip" to first page
+            topRow = 0;
+            currRow = 0;
         }
     }
     else if (action == "PAGEUP")
     {
-        if (currRow == 0)
-            return; // or wrap around: currRow = QMAX(lastRow - nRows + 1, 0);
-        else
-            currRow = QMAX(currRow - nRows, 0);
-
-        topRow = currRow;
+        // Converge to (0,0), then "flip" to last page
+        if (topRow >= nRows) {
+            topRow -= nRows;
+            currRow -= nRows;
+        } else if (topRow > 0) {
+            unsigned int scrollrows = topRow;
+            topRow -= scrollrows;
+            currRow -= scrollrows;
+        } else if (currRow > 0 || currCol > 0) {
+            currRow = 0;
+            currCol = 0;
+        } else {
+            // "Flip" to last page
+            topRow = lastTopRow;
+            currRow = lastRow;
+            currCol = QMIN(currCol, lastCol);
+        }
     }
     else if (action == "PAGEDOWN")
     {
-        if (currRow == lastRow)
-            return; // or wrap around: currRow = QMAX(nRows - 1,0);
-        else
+        // Converge to (lastRow,lastCol), then "flip" to first page
+        if (topRow <= lastTopRow - nRows) {
+            topRow += nRows;
             currRow += nRows;
-
-        if (currRow >= lastRow) {
+            if (currRow == lastRow)
+                currCol = QMIN(currCol, lastCol);
+        } else if (topRow < lastTopRow) {
+            unsigned int scrollrows = lastTopRow - topRow;
+            topRow += scrollrows;
+            currRow += scrollrows;
+            if (currRow == lastRow)
+                currCol = QMIN(currCol, lastCol);
+        } else if (currRow < lastRow || currCol < lastCol) {
             currRow = lastRow;
-            currCol = QMIN(currCol,lastCol);
+            currCol = lastCol;
+        } else {
+            // "Flip" to first page
+            topRow = 0;
+            currRow = 0;
         }
-
-        topRow = QMAX(currRow - nRows + 1,0);
     }
+    else if (action == "HOME")
+    {
+        topRow = 0;
+        currRow = 0;
+        currCol = 0;
+    }
+    else if (action == "END")
+    {
+        topRow = lastTopRow;
+        currRow = lastRow;
+        currCol = lastCol;
+    }
     else
         return;
 
     GenericTree *parent = where_we_are->getParent();
     if (parent)
-        where_we_are = parent->getChildAt(currRow * nCols + currCol,0);
+        where_we_are = parent->getChildAt(currRow * nCols + currCol, 0);
 
-
     curitem = video_list->getVideoListMetadata(where_we_are->getInt());
 
-
     if (topRow != oldRow)     // renew the whole screen
     {
         update(viewRect);
@@ -776,18 +748,8 @@
     // menu option to toggle between plain and folder view
     //
     cancelPopup();
-    curView = curView ? VIEW_DB : VIEW_FILE;
-
-    if (curView == VIEW_DB)
-    {
-        setFlatList(true);
-        setFileBrowser(false);
-    }
-    else
-    {
-        setFlatList(false);
-        setFileBrowser(true);
-    }
+    setFileBrowser(!isFileBrowser);
+    setFlatList(!isFileBrowser);
     
     fetchVideos(); // reload videos
 }
@@ -797,14 +759,12 @@
 {
     // determine the x,y position of the current icon anew
     int inData = where_we_are->getPosition(0);
-    currRow = (int)floorf((float)inData/(float)nCols);
-    currCol = (int)(inData-currRow*nCols);
+    currRow = inData / nCols;
+    currCol = inData % nCols;
 
     // determine which part of the list is shown
-    int list_count = where_we_are->siblingCount();
-    lastRow = QMAX((int)ceilf((float)list_count/(float)nCols)-1,0);
-    lastCol = QMAX(list_count-lastRow*nCols-1,0);
-    topRow  = QMIN(currRow, QMAX(lastRow - nRows + 1, 0));
+    computeLastRowCol(where_we_are->siblingCount());
+    topRow = QMIN(currRow, QMAX(lastRow - nRows + 1, 0));
 }
 
 
@@ -820,11 +780,14 @@
 
         where_we_are = where_we_are->getChildAt(0,0);
 
-        lastRow = QMAX((int)ceilf((float)list_count/(float)nCols)-1,0);
-        lastCol = QMAX(list_count-lastRow*nCols-1,0);
-    }
+        computeLastRowCol(list_count);
 
-    allowselect = (bool)(list_count > 0);
+        allowselect = true;
+    }
+    else
+    {
+        allowselect = false;
+    }
 }
 
 void VideoGallery::handleUpDirSelect()
@@ -901,3 +864,5 @@
     else if (name.lower() == "arrows")
         arrowsRect = area;
 }
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
