[mythtv] [PATCH] Semi-unify Record/Delete menus

Jim Radford mythtv-dev@snowman.net
Mon, 11 Nov 2002 23:36:44 -0800


On Mon, Nov 11, 2002 at 11:45:37PM -0500, Isaac Richards wrote:
> On Monday 11 November 2002 08:39 pm, Jim Radford wrote:
> > Great!  I assume you'd do the same for re-encode as well?  If so, then
> > looking at the code and at my changes I think the cleanest thing, in
> > terms of minimizing code duplication, might be still to unify
> > PlaybackBox and DeleteBox and to just pass in one parameter that says
> > what the default action (play, delete, er-encode) is.  We can key
> > showing the size off that as well.  I'll work up a patch if this is
> > ok.

> Yeah, if you want to do that, it'd be cool.  Most of those two files are 
> already duplicates anyway, so it shouldn't be all that hard.

Here's the merge.  With this you can now 'P' (play) or 'D' (delete)
from either menu and Space/Enter performs the default action.

There are a few "spacing" differences between play and record that I
emulated verbatim.  Isaac, you might want to check and see if one or
the other of values would be sufficient.

-Jim

Index: keys.txt
===================================================================
RCS file: /var/lib/cvs/MC/keys.txt,v
retrieving revision 1.1
diff -u -r1.1 keys.txt
--- keys.txt	9 Nov 2002 19:53:43 -0000	1.1
+++ keys.txt	12 Nov 2002 07:22:02 -0000
@@ -6,13 +6,15 @@
 - Arrow keys are used to move the highlight point around.
 - ALT-F4 to exit out of the application.
 - Space or Enter to take action on the item under the highlight point.
+- P to play   in both "Watch a Recording" and "Delete a Recording".
+- D to delete in both "Watch a Recording" and "Delete a Recording".
 
 Watching TV or a recording
 --------------------------
 
 - Up and down arrow keys change the channel.
 - Type the channel number to go directly to the channel.
-- P to pause / unpause.
+- P to pause / play.
 - Left arrow to rewind the configured number of seconds.  (default is 5)
 - Right arrow to fast forward the configured number of seconds. (default is 30)
 - C to hange inputs on TV Tuner card
Index: programs/mythfrontend/main.cpp
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/main.cpp,v
retrieving revision 1.41
diff -u -r1.41 main.cpp
--- programs/mythfrontend/main.cpp	30 Oct 2002 18:20:36 -0000	1.41
+++ programs/mythfrontend/main.cpp	12 Nov 2002 07:22:05 -0000
@@ -42,7 +42,7 @@
 int startPlayback(MythContext *context)
 {
     QSqlDatabase *db = QSqlDatabase::database();  
-    PlaybackBox pbb(context, tvList.begin().data(), db);
+    PlaybackBox pbb(context, tvList.begin().data(), db, PlaybackBox::Play);
 
     pbb.Show();
 
@@ -54,7 +54,7 @@
 int startDelete(MythContext *context)
 {
     QSqlDatabase *db = QSqlDatabase::database();
-    DeleteBox delbox(context, tvList.begin().data(), db);
+    PlaybackBox delbox(context, tvList.begin().data(), db, PlaybackBox::Delete);
    
     delbox.Show();
     
Index: programs/mythfrontend/mythfrontend.pro
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/mythfrontend.pro,v
retrieving revision 1.21
diff -u -r1.21 mythfrontend.pro
--- programs/mythfrontend/mythfrontend.pro	29 Oct 2002 04:58:52 -0000	1.21
+++ programs/mythfrontend/mythfrontend.pro	12 Nov 2002 07:22:05 -0000
@@ -28,8 +28,8 @@
 TARGETDEPS += ../../libs/libavcodec/libavcodec.a
 
 # Input
-HEADERS += scheduler.h playbackbox.h deletebox.h programlistitem.h 
+HEADERS += scheduler.h playbackbox.h programlistitem.h 
 HEADERS += viewscheduled.h
 
-SOURCES += main.cpp scheduler.cpp playbackbox.cpp deletebox.cpp 
+SOURCES += main.cpp scheduler.cpp playbackbox.cpp
 SOURCES += programlistitem.cpp viewscheduled.cpp
Index: programs/mythfrontend/playbackbox.cpp
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/playbackbox.cpp,v
retrieving revision 1.30
diff -u -r1.30 playbackbox.cpp
--- programs/mythfrontend/playbackbox.cpp	31 Oct 2002 20:23:49 -0000	1.30
+++ programs/mythfrontend/playbackbox.cpp	12 Nov 2002 07:22:05 -0000
@@ -6,6 +6,7 @@
 #include <qsqldatabase.h>
 #include <qlistview.h>
 #include <qdatetime.h>
+#include <qprogressbar.h>
 #include <qapplication.h>
 #include <qtimer.h>
 #include <qimage.h>
@@ -18,13 +19,16 @@
 #include "NuppelVideoPlayer.h"
 #include "yuv2rgb.h"
 
-#include "libmyth/mythcontext.h"
 #include "libmyth/programinfo.h"
+#include "libmyth/dialogbox.h"
+#include "libmyth/mythcontext.h"
 
 PlaybackBox::PlaybackBox(MythContext *context, TV *ltv, QSqlDatabase *ldb, 
+                         PlaybackBox::BoxType ltype,
                          QWidget *parent, const char *name)
            : QDialog(parent, name)
 {
+    type = ltype;
     tv = ltv;
     db = ldb;
     fileprefix = context->GetFilePrefix();
@@ -42,20 +46,31 @@
             QFont::Bold));
     setCursor(QCursor(Qt::BlankCursor));
 
-    QVBoxLayout *vbox = new QVBoxLayout(this, (int)(20 * wmult));
+    QVBoxLayout *vbox = 
+      new QVBoxLayout(this, (int)((type == Delete ? 15 : 20) * wmult));
 
-    QLabel *label = new QLabel("Select a recording to view:", this);
+    QLabel *label = new QLabel(type == Delete ? 
+                                "Select a recording to permanantly delete:" :
+                                "Select a recording to view:",
+                               this);
     vbox->addWidget(label);
 
-    QListView *listview = new QListView(this);
-
+    listview = new MyListView(this);
     listview->addColumn("Date");
     listview->addColumn("Title");
+    if(type == Delete)
+      listview->addColumn("Size");
  
-    listview->setColumnWidth(0, (int)(220 * wmult)); 
-    listview->setColumnWidth(1, (int)(520 * wmult));
-    listview->setColumnWidthMode(0, QListView::Manual);
-    listview->setColumnWidthMode(1, QListView::Manual);
+    if(type == Delete) {
+      listview->setColumnWidth(0, (int)(200 * wmult)); 
+      listview->setColumnWidth(1, (int)(455 * wmult));
+      listview->setColumnWidth(2, (int)(90 * wmult));
+    } else {
+      listview->setColumnWidth(0, (int)(220 * wmult)); 
+      listview->setColumnWidth(1, (int)(520 * wmult));
+      listview->setColumnWidthMode(0, QListView::Manual);
+      listview->setColumnWidthMode(1, QListView::Manual);
+    }
 
     listview->setSorting(-1, false);
     listview->setAllColumnsShowFocus(TRUE);
@@ -63,7 +78,11 @@
     connect(listview, SIGNAL(returnPressed(QListViewItem *)), this,
             SLOT(selected(QListViewItem *)));
     connect(listview, SIGNAL(spacePressed(QListViewItem *)), this,
-            SLOT(selected(QListViewItem *))); 
+            SLOT(selected(QListViewItem *)));
+    connect(listview, SIGNAL(deletePressed(QListViewItem *)), this,
+            SLOT(remove(QListViewItem *)));
+    connect(listview, SIGNAL(playPressed(QListViewItem *)), this,
+            SLOT(play(QListViewItem *))); 
     connect(listview, SIGNAL(selectionChanged(QListViewItem *)), this,
             SLOT(changed(QListViewItem *)));
 
@@ -74,8 +93,8 @@
     ProgramListItem *item = NULL;
    
     thequery = "SELECT chanid,starttime,endtime,title,subtitle,description "
-               "FROM recorded ORDER BY starttime;";
- 
+               "FROM recorded ORDER BY starttime DESC;";
+
     query = db->exec(thequery);
 
     if (query.isActive() && query.numRowsAffected() > 0)
@@ -119,11 +138,11 @@
             else
             {
                 proginfo->chanstr = "#" + proginfo->chanid;
-                proginfo->channame = "#" + proginfo->chanid;
-                proginfo->chansign = "#" + proginfo->chanid;
+                proginfo->channame = proginfo->chanstr;
+                proginfo->chansign = proginfo->chanstr;
             }
 
-            item = new ProgramListItem(context, listview, proginfo, 0, tv, 
+            item = new ProgramListItem(context, listview, proginfo, type==Delete, tv, 
                                        fileprefix);
         }
     }
@@ -131,8 +150,11 @@
     {
         // TODO: no recordings
     }
-   
-    listview->setFixedHeight((int)(300 * hmult));
+
+    if(type == Delete)
+      listview->setFixedHeight((int)(225 * hmult));
+    else
+      listview->setFixedHeight((int)(300 * hmult));
 
     QHBoxLayout *hbox = new QHBoxLayout(vbox, (int)(10 * wmult));
 
@@ -168,8 +190,8 @@
     grid->setColStretch(1, 1);
     grid->setRowStretch(4, 1);
 
-    if (m_context->GetNumSetting("GeneratePreviewPixmap") == 1 ||
-        m_context->GetNumSetting("PlaybackPreview") == 1)
+    if (context->GetNumSetting("GeneratePreviewPixmap") == 1 ||
+        context->GetNumSetting("PlaybackPreview") == 1)
     {
         QPixmap temp((int)(160 * wmult), (int)(120 * hmult));
 
@@ -181,6 +203,15 @@
     else
         pixlabel = NULL;
 
+    if(type == Delete) {
+    freespace = new QLabel(" ", this);
+    vbox->addWidget(freespace);
+    
+    progressbar = new QProgressBar(this);
+    UpdateProgressBar();
+    vbox->addWidget(progressbar);
+    }
+
     nvp = NULL;
     timer = new QTimer(this);
 
@@ -264,13 +295,22 @@
 {
     killPlayer();
 
+    if (!title)
+        return;
+
     ProgramListItem *pgitem = (ProgramListItem *)lvitem;
     if (!pgitem)
+    {
+        title->setText("");
+        date->setText("");
+        chan->setText("");
+        subtitle->setText("");
+        description->setText("");
+        if (pixlabel)
+            pixlabel->setPixmap(QPixmap(0, 0));
         return;
+    }
    
-    if (!title)
-        return;
-
     ProgramInfo *rec = pgitem->getProgramInfo();
 
     if (m_context->GetNumSetting("PlaybackPreview") == 1)
@@ -321,8 +361,35 @@
     timer->start(1000 / 30);
 }
 
+static void *SpawnDelete(void *param)
+{   
+    QString *filenameptr = (QString *)param;
+    QString filename = *filenameptr;
+
+    unlink(filename.ascii());
+
+    filename += ".png";
+    unlink(filename.ascii());
+
+    filename = *filenameptr;
+    filename += ".bookmark";
+    unlink(filename.ascii());
+
+    delete filenameptr;
+
+    return NULL;
+}   
+
 void PlaybackBox::selected(QListViewItem *lvitem)
 {
+    switch(type) {
+    case Play:   play(lvitem);   break;
+    case Delete: remove(lvitem); break;
+    }
+}
+
+void PlaybackBox::play(QListViewItem *lvitem)
+{
     killPlayer();
 
     ProgramListItem *pgitem = (ProgramListItem *)lvitem;
@@ -336,6 +403,156 @@
 
     startPlayer(rec);
     timer->start(1000 / 30);
+}
+
+void PlaybackBox::remove(QListViewItem *lvitem)
+{
+    killPlayer();
+	
+    ProgramListItem *pgitem = (ProgramListItem *)lvitem;
+    ProgramInfo *rec = pgitem->getProgramInfo();
+
+    QString message = "Are you sure you want to delete:<br><br>";
+    message += rec->title;
+    message += "<br>";
+    
+    QDateTime startts = rec->startts;
+    QDateTime endts = rec->endts;
+
+    QString dateformat = m_context->GetSetting("DateFormat");
+    if (dateformat == "")
+        dateformat = "ddd MMMM d";
+    QString timeformat = m_context->GetSetting("TimeFormat");
+    if (timeformat == "")
+        timeformat = "h:mm AP";
+
+    QString timedate = endts.date().toString(dateformat) + QString(", ") +
+                       startts.time().toString(timeformat) + QString(" - ") +
+                       endts.time().toString(timeformat);
+
+    message += timedate;
+    message += "<br>";
+    if (rec->subtitle != "(null)")
+        message += rec->subtitle;
+    message += "<br>";
+    if (rec->description != "(null)")
+        message += rec->description;
+
+    message += "<br><br>It will be gone forever.";
+
+    DialogBox diag(m_context, message);
+
+    diag.AddButton("Yes, get rid of it");
+    diag.AddButton("No, keep it, I changed my mind");
+
+    diag.Show();
+
+    int result = diag.exec();
+
+    if (result == 1)
+    {
+        QString filename = rec->GetRecordFilename(fileprefix);
+
+        QSqlQuery query;
+        QString thequery;
+
+        QString startts = rec->startts.toString("yyyyMMddhhmm");
+        startts += "00";
+        QString endts = rec->endts.toString("yyyyMMddhhmm");
+        endts += "00";
+
+        thequery = QString("DELETE FROM recorded WHERE chanid = %1 AND title "
+                           "= \"%2\" AND starttime = %3 AND endtime = %4;")
+                           .arg(rec->chanid).arg(rec->title).arg(startts)
+                           .arg(endts);
+
+        query = db->exec(thequery);
+        if (!query.isActive())
+        {
+            cerr << "DB Error: recorded program deletion failed, SQL query "
+                 << "was:" << endl;
+            cerr << thequery << endl;
+        }
+
+        QString *fileptr = new QString(filename);
+
+        pthread_t deletethread;
+        pthread_attr_t attr;
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+        pthread_create(&deletethread, &attr, SpawnDelete, fileptr);
+
+        if (lvitem->itemBelow())
+        {
+            listview->setCurrentItem(lvitem->itemBelow());
+            listview->setSelected(lvitem->itemBelow(), true);
+        }
+        else if (lvitem->itemAbove())
+        {
+            listview->setCurrentItem(lvitem->itemAbove());
+            listview->setSelected(lvitem->itemAbove(), true);
+        }
+        else
+            changed(NULL);
+
+        delete lvitem;
+        UpdateProgressBar();
+    }    
+    else if (m_context->GetNumSetting("PlaybackPreview") == 1)
+        startPlayer(rec);
+
+    setActiveWindow();
+    raise();
+
+    timer->start(1000 / 30);
+}
+
+void PlaybackBox::GetFreeSpaceStats(int &totalspace, int &usedspace)
+{
+    QString command;
+    command.sprintf("df -k -P %s", fileprefix.ascii());
+
+    FILE *file = popen(command.ascii(), "r");
+
+    if (!file)
+    {
+        totalspace = -1;
+        usedspace = -1;
+    }
+    else
+    {
+        char buffer[1024];
+        fgets(buffer, 1024, file);
+        fgets(buffer, 1024, file);
+
+        char dummy[1024];
+        int dummyi;
+        sscanf(buffer, "%s %d %d %d %s %s\n", dummy, &totalspace, &usedspace,
+               &dummyi, dummy, dummy);
+
+        totalspace /= 1000;
+        usedspace /= 1000; 
+        pclose(file);
+    }
+}
+ 
+void PlaybackBox::UpdateProgressBar(void)
+{
+    int total, used;
+    GetFreeSpaceStats(total, used);
+
+    QString usestr;
+    char text[128];
+    sprintf(text, "Storage: %d,%03d MB used out of %d,%03d MB total", 
+            used / 1000, used % 1000, 
+            total / 1000, total % 1000);
+
+    usestr = text;
+
+    freespace->setText(usestr);
+    progressbar->setTotalSteps(total);
+    progressbar->setProgress(used);
 }
 
 void PlaybackBox::timeout(void)
Index: programs/mythfrontend/playbackbox.h
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/playbackbox.h,v
retrieving revision 1.8
diff -u -r1.8 playbackbox.h
--- programs/mythfrontend/playbackbox.h	31 Oct 2002 20:23:49 -0000	1.8
+++ programs/mythfrontend/playbackbox.h	12 Nov 2002 07:22:05 -0000
@@ -8,7 +8,9 @@
 
 class QSqlDatabase;
 class QListViewItem;
+class MyListView;
 class QLabel;
+class QProgressBar;
 class TV;
 class NuppelVideoPlayer;
 class RingBuffer;
@@ -20,7 +22,10 @@
 {
     Q_OBJECT
   public:
+    typedef enum { Play, Delete } BoxType;
+    BoxType type;
     PlaybackBox(MythContext *context, TV *ltv, QSqlDatabase *ldb, 
+                BoxType ltype,
                 QWidget *parent = 0, const char *name = 0);
    ~PlaybackBox(void);
     
@@ -28,10 +33,15 @@
   
   protected slots:
     void selected(QListViewItem *);
+    void remove(QListViewItem *);
+    void play(QListViewItem *);
     void changed(QListViewItem *);
     void timeout(void);
 
   private:
+    void GetFreeSpaceStats(int &totalspace, int &usedspace); 
+    void UpdateProgressBar(void);
+
     QSqlDatabase *db;
     TV *tv;
 
@@ -44,6 +54,11 @@
     QLabel *chan;
     QLabel *pixlabel;
 
+    MyListView *listview;
+
+    QLabel *freespace;
+    QProgressBar *progressbar;
+ 
     float wmult, hmult;
     int descwidth;
 
Index: programs/mythfrontend/programlistitem.cpp
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/programlistitem.cpp,v
retrieving revision 1.22
diff -u -r1.22 programlistitem.cpp
--- programs/mythfrontend/programlistitem.cpp	30 Oct 2002 14:52:14 -0000	1.22
+++ programs/mythfrontend/programlistitem.cpp	12 Nov 2002 07:22:05 -0000
@@ -14,16 +14,23 @@
 
 void MyListView::keyPressEvent(QKeyEvent *e)
 {
-    if (e->key() == Key_Space) 
+    if ( currentItem() && !currentItem()->isEnabled() )
     {
-        if ( currentItem() && !currentItem()->isEnabled() )
-        {
-        }
-        else
-        {   
-            emit spacePressed( currentItem() );
-            return;
-        }
+    }
+    else
+    switch(e->key()) 
+    {
+    case 'D':
+      emit deletePressed( currentItem() );
+      return;
+    case 'P':
+      emit playPressed( currentItem() );
+      return;
+    case Key_Space:
+      emit spacePressed( currentItem() );
+      return;
+    default:
+      cout << "Unhandled Key Jim: " << e->key() << endl;
     }
 
     QListView::keyPressEvent(e);
Index: programs/mythfrontend/programlistitem.h
===================================================================
RCS file: /var/lib/cvs/MC/programs/mythfrontend/programlistitem.h,v
retrieving revision 1.7
diff -u -r1.7 programlistitem.h
--- programs/mythfrontend/programlistitem.h	30 Oct 2002 06:30:34 -0000	1.7
+++ programs/mythfrontend/programlistitem.h	12 Nov 2002 07:22:05 -0000
@@ -2,17 +2,27 @@
 #define PROGRAMLISTITEM_H_
 
 #include <qlistview.h>
+#include <qpixmap.h>
+
+#include "libmyth/programinfo.h"
 
 class ProgramInfo;
 class QPixmap;
+class MythContext;
+class TV;
 
 class MyListView : public QListView
 {
+  Q_OBJECT
   public:
     MyListView(QWidget *parent) : QListView(parent) {}
 
   protected:
     void keyPressEvent( QKeyEvent *e );
+
+  signals:
+    void playPressed( QListViewItem * );
+    void deletePressed( QListViewItem * );
 };
 
 class ProgramListItem : public QListViewItem