Ticket #13135: 20171017_#13135_prevrec.patch

File 20171017_#13135_prevrec.patch, 62.6 KB (added by Peter Bennett, 7 years ago)

Implementation of new Previously Recorded screen

  • mythtv/libs/libmythtv/recordingrule.cpp

    diff --git a/mythtv/libs/libmythtv/recordingrule.cpp b/mythtv/libs/libmythtv/recordingrule.cpp
    index a6cbec1..5afd8c5 100644
    a b bool RecordingRule::LoadByProgram(const ProgramInfo* proginfo) 
    204204
    205205    m_recordID = proginfo->GetRecordingRuleID();
    206206    if (m_recordID)
    207         Load();
     207    {
     208        if (!Load())
     209            return false;
     210    }
    208211    else
    209212        LoadTemplate(proginfo->GetCategory(), proginfo->GetCategoryTypeString());
    210213
  • mythtv/libs/libmythui/mythrect.cpp

    diff --git a/mythtv/libs/libmythui/mythrect.cpp b/mythtv/libs/libmythui/mythrect.cpp
    index c7a5904..ed8731f 100644
    a b  
    33
    44#include "mythrect.h"
    55#include "mythmainwindow.h"
     6#include "mythuihelper.h"
    67
    78MythRect::MythRect()
    89         : QRect()
    MythRect::MythRect(int x, int y, int width, int height) 
    1718}
    1819
    1920MythRect::MythRect(const QString &sX, const QString &sY, const QString &sWidth,
    20                    const QString &sHeight)
     21                   const QString &sHeight, const QString &baseRes)
    2122         : QRect()
    2223{
    2324    Init();
    24     setRect(sX,sY,sWidth,sHeight);
     25    setRect(sX,sY,sWidth,sHeight,baseRes);
    2526}
    2627
    2728MythRect::MythRect(QRect rect)
    void MythRect::NormRect(void) 
    119120}
    120121
    121122void MythRect::setRect(const QString &sX, const QString &sY,
    122                        const QString &sWidth, const QString &sHeight)
     123                       const QString &sWidth, const QString &sHeight,
     124                       const QString &rectBaseRes)
    123125{
    124     setX(sX);
    125     setY(sY);
    126     setWidth(sWidth);
    127     setHeight(sHeight);
     126
     127    // cater for an extra paramater on area and similar tags
     128    // for base resolution.
     129
     130    QString vX = sX;
     131    QString vY = sY;
     132    QString vWidth = sWidth;
     133    QString vHeight = sHeight;
     134    if (!rectBaseRes.isEmpty())
     135    {
     136        QStringList res = rectBaseRes.split('x');
     137        if (res.size() == 2)
     138        {
     139            QSize themeBaseSize = GetMythUI()->GetBaseSize();
     140            int rectBaseWidth = res[0].toInt();
     141            int rectBaseHeight = res[1].toInt();
     142            if (rectBaseWidth > 0 && rectBaseHeight > 0)
     143            {
     144                int iX = sX.toInt();
     145                if (iX > 0)
     146                {
     147                    iX = iX * themeBaseSize.width() / rectBaseWidth;
     148                    vX = QString::number(iX);
     149                }
     150                int iY = sY.toInt();
     151                if (iY > 0)
     152                {
     153                    iY = iY * themeBaseSize.height() / rectBaseHeight;
     154                    vY = QString::number(iY);
     155                }
     156                int iWidth = sWidth.toInt();
     157                if (iWidth > 0)
     158                {
     159                    iWidth = iWidth * themeBaseSize.width() / rectBaseWidth;
     160                    vWidth = QString::number(iWidth);
     161                }
     162                int iHeight = sHeight.toInt();
     163                if (iHeight > 0)
     164                {
     165                    iHeight = iHeight * themeBaseSize.height() / rectBaseHeight;
     166                    vHeight = QString::number(iHeight);
     167                }
     168            }
     169        }
     170    }
     171    setX(vX);
     172    setY(vY);
     173    setWidth(vWidth);
     174    setHeight(vHeight);
    128175}
    129176
    130177/**
  • mythtv/libs/libmythui/mythrect.h

    diff --git a/mythtv/libs/libmythui/mythrect.h b/mythtv/libs/libmythui/mythrect.h
    index bb8d407..eb440c5 100644
    a b class MUI_PUBLIC MythRect : public QRect 
    2121    MythRect();
    2222    MythRect(int x, int y, int width, int height);
    2323    MythRect(const QString &sX, const QString &sY, const QString &sWidth,
    24              const QString &sHeight);
     24             const QString &sHeight, const QString &baseRes = QString());
    2525    MythRect(QRect rect);
    2626    bool operator== (const MythRect &other) const;
    2727
    class MUI_PUBLIC MythRect : public QRect 
    3232    void NormRect(void);
    3333
    3434    void setRect(const QString &sX, const QString &sY, const QString &sWidth,
    35                  const QString &sHeight);
     35                 const QString &sHeight, const QString &baseRes = QString());
    3636    void setRect(int X, int Y, int w,int h) { QRect::setRect(X,Y,w,h); }
    3737    void setX(const QString &sX);
    3838    void setX(int X) { QRect::setX(X); }
  • mythtv/libs/libmythui/xmlparsebase.cpp

    diff --git a/mythtv/libs/libmythui/xmlparsebase.cpp b/mythtv/libs/libmythui/xmlparsebase.cpp
    index 2c9a96a..5c1e734 100644
    a b MythRect XMLParseBase::parseRect(const QString &text, bool normalize) 
    134134    QStringList values = text.split(',', QString::SkipEmptyParts);
    135135    if (values.size() == 4)
    136136        retval = MythRect(values[0], values[1], values[2], values[3]);
     137    if (values.size() == 5)
     138        retval = MythRect(values[0], values[1], values[2], values[3],
     139            values[4]);
    137140
    138141     if (normalize)
    139142         retval.NormRect();
  • mythtv/programs/mythfrontend/main.cpp

    diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp
    index 142379b..08d22e1 100644
    a b using namespace std; 
    2828#include "mythsystemlegacy.h"
    2929#include "tv.h"
    3030#include "proglist.h"
     31#include "prevreclist.h"
    3132#include "progfind.h"
    3233#include "scheduleeditor.h"
    3334#include "manualschedule.h"
    static void startPlayback(void) 
    546547static void startPrevious(void)
    547548{
    548549    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
     550    PrevRecordedList *pl = new PrevRecordedList(mainStack);
     551    if (pl->Create())
     552        mainStack->AddScreen(pl);
     553    else
     554        delete pl;
     555}
     556
     557static void startPreviousOld(void)
     558{
     559    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
    549560    ProgLister *pl = new ProgLister(mainStack);
    550561    if (pl->Create())
    551562        mainStack->AddScreen(pl);
    static void TVMenuCallback(void *data, QString &selection) 
    890901        startSearchTime();
    891902    else if (sel == "tv_previous")
    892903        startPrevious();
     904    else if (sel == "tv_previous_old")
     905        startPreviousOld();
    893906    else if (sel == "settings appearance")
    894907    {
    895908        MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
  • mythtv/programs/mythfrontend/mythfrontend.pro

    diff --git a/mythtv/programs/mythfrontend/mythfrontend.pro b/mythtv/programs/mythfrontend/mythfrontend.pro
    index 926d01e..3b79a9e 100644
    a b HEADERS += commandlineparser.h idlescreen.h 
    5555HEADERS += gallerythumbview.h           galleryslideview.h
    5656HEADERS += galleryconfig.h              galleryviews.h
    5757HEADERS += galleryslide.h               gallerytransitions.h
    58 HEADERS += galleryinfo.h
     58HEADERS += galleryinfo.h                prevreclist.h
    5959
    6060SOURCES += main.cpp playbackbox.cpp viewscheduled.cpp audiogeneralsettings.cpp
    6161SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp
    SOURCES += commandlineparser.cpp idlescreen.cpp 
    8080SOURCES += gallerythumbview.cpp         galleryslideview.cpp
    8181SOURCES += galleryconfig.cpp            galleryviews.cpp
    8282SOURCES += galleryslide.cpp             gallerytransitions.cpp
    83 SOURCES += galleryinfo.cpp
     83SOURCES += galleryinfo.cpp              prevreclist.cpp
    8484
    8585HEADERS += serviceHosts/frontendServiceHost.h
    8686HEADERS += services/frontend.h
  • new file mythtv/programs/mythfrontend/prevreclist.cpp

    diff --git a/mythtv/programs/mythfrontend/prevreclist.cpp b/mythtv/programs/mythfrontend/prevreclist.cpp
    new file mode 100644
    index 0000000..6875ddd
    - +  
     1/*
     2 * Copyright (c) 2017 Peter G Bennett <pbennett@mythtv.org>
     3 *
     4 * This file is part of MythTV.
     5 *
     6 * MythTV is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Public License as
     8 * published by the Free Software Foundation; either
     9 * version 2 of the License, or (at your option) any later version.
     10 *
     11 * MythTV is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with MythTV. If not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "prevreclist.h"
     21
     22// C/C++
     23#include <algorithm>
     24#include <deque>                        // for _Deque_iterator, operator-, etc
     25#include <iterator>                     // for reverse_iterator
     26using namespace std;
     27
     28// QT
     29#include <QString>
     30#include <QDateTime>
     31
     32//MythTV
     33#include "mythcorecontext.h"
     34#include "mythdb.h"
     35#include "xmlparsebase.h"
     36#include "recordinginfo.h"
     37#include "recordingrule.h"
     38#include "scheduledrecording.h"
     39
     40// MythUI
     41#include "mythuitext.h"
     42#include "mythuibuttonlist.h"
     43#include "mythuibutton.h"
     44#include "mythscreenstack.h"
     45#include "mythmainwindow.h"
     46#include "mythuiutils.h"                // for UIUtilE, UIUtilW
     47#include "mythdialogbox.h"
     48
     49#define LOC      QString("PrevRecordedList: ")
     50
     51PrevRecordedList::PrevRecordedList(MythScreenStack *parent, uint recid,
     52    const QString &title) :
     53    ScheduleCommon(parent,"PrevRecordedList"),
     54    m_searchText(NULL),
     55    m_help1Text(NULL),
     56    m_help2Text(NULL),
     57    m_titleGroup(true),
     58    m_reverseSort(false),
     59    m_allowEvents(true),
     60    m_recid(recid),
     61    m_title(title)
     62{
     63    if (m_recid && !m_title.isEmpty())
     64    {
     65        m_where = QString(" AND ( recordid = %1 OR title = :MTITLE )")
     66            .arg(m_recid);
     67    }
     68    else if (!m_title.isEmpty())
     69    {
     70        m_where = QString("AND title = :MTITLE ");
     71    }
     72    else if (m_recid)
     73    {
     74        m_where = QString("AND recordid = %1 ").arg(m_recid);
     75    }
     76}
     77
     78PrevRecordedList::~PrevRecordedList()
     79{
     80    m_titleData.clear();
     81    m_showData.clear();
     82    gCoreContext->removeListener(this);
     83}
     84
     85bool PrevRecordedList::Create(void)
     86{
     87    if (!LoadWindowFromXML("schedule-ui.xml", "prevreclist", this))
     88        return false;
     89
     90    bool err = false;
     91    UIUtilE::Assign(this, m_titleList, "titles", &err);
     92    if (!err)
     93        UIUtilE::Assign(this, m_showList, "shows", &err);
     94    UIUtilW::Assign(this, m_help1Text, "help1text");
     95    UIUtilW::Assign(this, m_help2Text, "help2text");
     96    UIUtilW::Assign(this, m_searchText, "search");
     97
     98    if (err)
     99    {
     100        LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'prevreclist'");
     101        return false;
     102    }
     103
     104    m_titleList->SetLCDTitles(tr("Programs"), "title");
     105    m_showList->SetLCDTitles(tr("Episodes"), "startdate|parttitle");
     106
     107    BuildFocusList();
     108    gCoreContext->addListener(this);
     109    LoadInBackground();
     110
     111    return true;
     112}
     113
     114void PrevRecordedList::Init(void)
     115{
     116    gCoreContext->addListener(this);
     117    connect(m_showList, &MythUIButtonList::itemSelected,
     118            this, &PrevRecordedList::updateInfo);
     119    connect(m_showList, &MythUIButtonList::LosingFocus,
     120            this, &PrevRecordedList::showListLoseFocus);
     121    connect(m_showList, &MythUIButtonList::TakingFocus,
     122            this, &PrevRecordedList::showListTakeFocus);
     123    connect(m_showList, SIGNAL(itemClicked(MythUIButtonListItem*)),
     124                this,  SLOT(ShowMenu()));
     125
     126    UpdateTitleList();
     127    updateInfo();
     128}
     129
     130void PrevRecordedList::Load(void)
     131{
     132    if (m_titleGroup)
     133        LoadTitles();
     134    else
     135        LoadDates();
     136
     137    ScreenLoadCompletionEvent *slce =
     138        new ScreenLoadCompletionEvent(objectName());
     139    QCoreApplication::postEvent(this, slce);
     140}
     141
     142static bool comp_sorttitle_lt(
     143    const ProgramInfo *a, const ProgramInfo *b)
     144{
     145    return a->sortTitle.compare(b->sortTitle,Qt::CaseInsensitive) < 0;
     146}
     147
     148static bool comp_sorttitle_lt_rev(
     149    const ProgramInfo *a, const ProgramInfo *b)
     150{
     151    return b->sortTitle.compare(a->sortTitle,Qt::CaseInsensitive) < 0;
     152}
     153
     154static bool comp_sortdate_lt(
     155    const ProgramInfo *a, const ProgramInfo *b)
     156{
     157    return a->GetRecordingStartTime() < b->GetRecordingStartTime();
     158}
     159
     160static bool comp_sortdate_lt_rev(
     161    const ProgramInfo *a, const ProgramInfo *b)
     162{
     163    return b->GetRecordingStartTime() < a->GetRecordingStartTime();
     164}
     165
     166// Load a list of titles without subtitle or other info.
     167// each title can represent multiple recordings.
     168bool PrevRecordedList::LoadTitles(void)
     169{
     170    QString querystr = "SELECT DISTINCT title FROM oldrecorded "
     171        "WHERE oldrecorded.future = 0 " + m_where;
     172
     173    m_titleData.clear();
     174
     175    MSqlQuery query(MSqlQuery::InitCon());
     176    query.prepare(querystr);
     177
     178    if (!m_title.isEmpty())
     179        query.bindValue(":MTITLE", m_title);
     180
     181    if (!query.exec())
     182    {
     183        MythDB::DBError("PrevRecordedList::LoadTitles", query);
     184        return false;
     185    }
     186
     187    const QRegExp prefixes(
     188        tr("^(The |A |An )",
     189           "Regular Expression for what to ignore when sorting"));
     190
     191    while (query.next())
     192    {
     193        QString title(query.value(0).toString());
     194        ProgramInfo *program = new ProgramInfo();
     195        program->SetTitle(title);
     196        program->sortTitle = title;
     197        program->sortTitle.remove(prefixes);
     198        m_titleData.push_back(program);
     199    }
     200    if (m_reverseSort)
     201        std::stable_sort(m_titleData.begin(), m_titleData.end(),
     202            comp_sorttitle_lt_rev);
     203    else
     204        std::stable_sort(m_titleData.begin(), m_titleData.end(),
     205            comp_sorttitle_lt);
     206    return true;
     207}
     208
     209bool PrevRecordedList::LoadDates(void)
     210{
     211    QString querystr = "SELECT DISTINCT YEAR(starttime), MONTH(starttime) "
     212        "FROM oldrecorded "
     213        "WHERE oldrecorded.future = 0 " + m_where;
     214
     215    m_titleData.clear();
     216
     217    MSqlQuery query(MSqlQuery::InitCon());
     218    query.prepare(querystr);
     219
     220    if (!m_title.isEmpty())
     221        query.bindValue(":MTITLE", m_title);
     222
     223    if (!query.exec())
     224    {
     225        MythDB::DBError("PrevRecordedList::LoadDates", query);
     226        return false;
     227    }
     228
     229    while (query.next())
     230    {
     231        int year(query.value(0).toInt());
     232        int month(query.value(1).toInt());
     233        ProgramInfo *program = new ProgramInfo();
     234        QDate startdate(year,month,1);
     235        QDateTime starttime(startdate);
     236        program->SetRecordingStartTime(starttime);
     237        QString date(QString::asprintf("%4.4d/%2.2d",year,month));
     238        QLocale locale = gCoreContext->GetLocale()->ToQLocale();
     239        QString title = QString("%1 %2").
     240            arg(locale.monthName(month)).arg(year);
     241        program->SetTitle(title);
     242        program->sortTitle = date;
     243        m_titleData.push_back(program);
     244    }
     245    if (m_reverseSort)
     246        std::stable_sort(m_titleData.begin(), m_titleData.end(),
     247            comp_sortdate_lt_rev);
     248    else
     249        std::stable_sort(m_titleData.begin(), m_titleData.end(),
     250            comp_sortdate_lt);
     251    return true;
     252}
     253
     254void PrevRecordedList::UpdateTitleList(void)
     255{
     256    UpdateList(m_titleList, &m_titleData);
     257}
     258
     259void PrevRecordedList::UpdateShowList(void)
     260{
     261    UpdateList(m_showList, &m_showData);
     262}
     263
     264void PrevRecordedList::UpdateList(MythUIButtonList *bnList, ProgramList *progData)
     265{
     266    bnList->Reset();
     267    for (uint i = 0; i < progData->size(); ++i)
     268    {
     269        MythUIButtonListItem *item =
     270            new MythUIButtonListItem(bnList, "", QVariant::fromValue((*progData)[i]));
     271        InfoMap infoMap;
     272        (*progData)[i]->ToMap(infoMap,true);
     273        QString partTitle;
     274        if (m_titleGroup)
     275            partTitle = infoMap["subtitle"];
     276        else
     277            partTitle = infoMap["titlesubtitle"];
     278        infoMap["parttitle"] = partTitle;
     279        QString state = RecStatus::toUIState((*progData)[i]->GetRecordingStatus());
     280        if ((state == "warning"))
     281            state = "disabled";
     282
     283        item->SetTextFromMap(infoMap, state);
     284    }
     285}
     286
     287void PrevRecordedList::updateInfo(void)
     288{
     289    if (m_help1Text)
     290        m_help1Text->Reset();
     291    if (m_help2Text)
     292        m_help2Text->Reset();
     293
     294    if (m_showData.size() > 0)
     295    {
     296        InfoMap infoMap;
     297        m_showData[m_showList->GetCurrentPos()]->ToMap(infoMap,true);
     298        SetTextFromMap(infoMap);
     299        m_infoMap = infoMap;
     300    }
     301    else
     302    {
     303        ResetMap(m_infoMap);
     304
     305        if (m_titleGroup)
     306        {
     307            m_titleList->SetLCDTitles(tr("Programs"), "title");
     308            m_showList->SetLCDTitles(tr("Episodes"), "startdate|parttitle");
     309            if (m_help1Text)
     310                m_help1Text->SetText(tr("Select a program..."));
     311            if (m_help2Text)
     312                m_help2Text->SetText(tr(
     313                "Select the title of the program you wish to find. "
     314                "When finished return with the left arrow key. "
     315                "To search by date press 1."));
     316        }
     317        else
     318        {
     319            m_titleList->SetLCDTitles(tr("Dates"), "title");
     320            m_showList->SetLCDTitles(tr("Programs"), "startdate|parttitle");
     321            if (m_help1Text)
     322                m_help1Text->SetText(tr("Select a month ..."));
     323            if (m_help2Text)
     324                m_help2Text->SetText(tr(
     325                "Select a month to search. "
     326                "When finished return with the left arrow key. "
     327                "To search by title press 2."));
     328        }
     329    }
     330}
     331
     332void PrevRecordedList::showListLoseFocus(void)
     333{
     334    m_showData.clear();
     335    m_showList->Reset();
     336    updateInfo();
     337}
     338
     339void PrevRecordedList::showListTakeFocus(void)
     340{
     341    if (m_titleGroup)
     342        LoadShowsByTitle();
     343    else
     344        LoadShowsByDate();
     345    UpdateShowList();
     346}
     347
     348void PrevRecordedList::LoadShowsByTitle(void)
     349{
     350    MSqlBindings bindings;
     351    QString sql = " AND oldrecorded.title = :TITLE " + m_where;
     352    int selected = m_titleList->GetCurrentPos();
     353    bindings[":TITLE"] = m_titleData[selected]->GetTitle();
     354    if (!m_title.isEmpty())
     355        bindings[":MTITLE"] = m_title;
     356    m_showData.clear();
     357    LoadFromOldRecorded(m_showData, sql, bindings);
     358}
     359
     360void PrevRecordedList::LoadShowsByDate(void)
     361{
     362    MSqlBindings bindings;
     363    int selected = m_titleList->GetCurrentPos();
     364    QString sortTitle = m_titleData[selected]->sortTitle;
     365    QStringList dateParts = sortTitle.split('/');
     366    if (dateParts.size() != 2)
     367    {
     368        LOG(VB_GENERAL, LOG_ERR, LOC +
     369            QString("Invalid sort Date: %1").arg(sortTitle));
     370        return;
     371    }
     372    QString sortorder;
     373    if (m_reverseSort)
     374        sortorder = "DESC";
     375    QString sql = QString(
     376        " AND YEAR(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :YEAR "
     377        " AND MONTH(CONVERT_TZ(starttime,'UTC','SYSTEM')) = :MONTH ")
     378         + m_where + QString(
     379        " ORDER BY starttime %1 ").arg(sortorder);
     380    bindings[":YEAR"] = dateParts[0];
     381    bindings[":MONTH"] = dateParts[1];
     382    if (!m_title.isEmpty())
     383        bindings[":MTITLE"] = m_title;
     384    m_showData.clear();
     385    LoadFromOldRecorded(m_showData, sql, bindings);
     386}
     387
     388bool PrevRecordedList::keyPressEvent(QKeyEvent *e)
     389{
     390    if (!m_allowEvents)
     391        return true;
     392
     393    if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(e))
     394    {
     395        m_allowEvents = true;
     396        return true;
     397    }
     398
     399    m_allowEvents = false;
     400
     401    QStringList actions;
     402    bool handled = GetMythMainWindow()->TranslateKeyPress(
     403        "TV Frontend", e, actions);
     404
     405    bool needUpdate = false;
     406    for (uint i = 0; i < uint(actions.size()) && !handled; ++i)
     407    {
     408        QString action = actions[i];
     409        handled = true;
     410
     411        if (action == "CUSTOMEDIT")
     412             EditCustom();
     413        else if (action == "EDIT")
     414             EditScheduled();
     415        else if (action == "DELETE")
     416             deleteMenu(true);
     417        else if (action == "DETAILS" || action == "INFO")
     418             ShowDetails();
     419        else if (action == "GUIDE")
     420             ShowGuide();
     421        else if (action == "1")
     422        {
     423            if (m_titleGroup == true)
     424            {
     425                m_titleGroup = false;
     426                m_reverseSort = true;
     427            }
     428            else
     429            {
     430                m_reverseSort = !m_reverseSort;
     431            }
     432            needUpdate = true;
     433        }
     434        else if (action == "2")
     435        {
     436            if (m_titleGroup == false)
     437            {
     438                m_titleGroup = true;
     439                m_reverseSort = false;
     440            }
     441            else
     442            {
     443                m_reverseSort = !m_reverseSort;
     444            }
     445            needUpdate = true;
     446        }
     447        else
     448        {
     449            handled = false;
     450        }
     451    }
     452
     453    if (!handled && MythScreenType::keyPressEvent(e))
     454        handled = true;
     455
     456    if (needUpdate)
     457        LoadInBackground();
     458
     459    m_allowEvents = true;
     460
     461    return handled;
     462}
     463
     464void PrevRecordedList::ShowMenu(void)
     465{
     466    MythMenu *sortMenu = new MythMenu(tr("Sort Options"), this, "sortmenu");
     467    sortMenu->AddItem(tr("Reverse Sort Order"));
     468    sortMenu->AddItem(tr("Sort By Title"));
     469    sortMenu->AddItem(tr("Sort By Time"));
     470
     471    MythMenu *menu = new MythMenu(tr("Options"), this, "menu");
     472
     473    menu->AddItem(tr("Sort"), NULL, sortMenu);
     474
     475    ProgramInfo *pi = GetCurrentProgram();
     476    if (pi && pi->GetRecordingStatus() == RecStatus::Recorded)
     477    {
     478        if (pi->IsDuplicate())
     479            menu->AddItem(tr("Allow to Rerecord"),   SLOT(AllowRecord()));
     480        else
     481            menu->AddItem(tr("Prevent From Rerecording"), SLOT(PreventRecord()));
     482    }
     483    if (pi)
     484    {
     485        menu->AddItem(tr("Edit Schedule"),   SLOT(EditScheduled()));
     486        menu->AddItem(tr("Custom Edit"),     SLOT(EditCustom()));
     487        menu->AddItem(tr("Program Details"), SLOT(ShowDetails()));
     488        menu->AddItem(tr("Program Guide"),   SLOT(ShowGuide()));
     489        MythMenu *dmenu = deleteMenu(false);
     490        if (dmenu)
     491            menu->AddItem(tr("Delete"), NULL, dmenu);
     492    }
     493    MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
     494    MythDialogBox *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
     495
     496    if (!menuPopup->Create())
     497    {
     498        delete menuPopup;
     499        return;
     500    }
     501
     502    popupStack->AddScreen(menuPopup);
     503}
     504
     505MythMenu *PrevRecordedList::deleteMenu(bool bShow)
     506{
     507    ProgramInfo *pi = GetCurrentProgram();
     508    if (!pi)
     509        return 0;
     510    MythMenu *dmenu = new MythMenu(tr("Delete Options"), this, "deletemenu");
     511    if (pi->GetRecordingStatus() == RecStatus::Recorded)
     512    {
     513        if (pi->IsDuplicate())
     514            dmenu->AddItem(tr("Allow to Rerecord"),   SLOT(AllowRecord()));
     515        else
     516            dmenu->AddItem(tr("Prevent From Rerecording"), SLOT(PreventRecord()));
     517    }
     518    dmenu->AddItem(tr("Delete Episode"),
     519        SLOT(ShowDeleteOldEpisodeMenu()));
     520    dmenu->AddItem(tr("Delete Series"),
     521        SLOT(ShowDeleteOldSeriesMenu()));
     522    if (!bShow)
     523        return dmenu;
     524    MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
     525    MythDialogBox *menuPopup = new MythDialogBox(dmenu, popupStack, "menuPopup");
     526    if (!menuPopup->Create())
     527    {
     528        delete menuPopup;
     529        return 0;
     530    }
     531    popupStack->AddScreen(menuPopup);
     532    return 0;
     533}
     534
     535void PrevRecordedList::customEvent(QEvent *event)
     536{
     537    bool needUpdate = false;
     538
     539    if (event->type() == DialogCompletionEvent::kEventType)
     540    {
     541        DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
     542
     543        QString resultid   = dce->GetId();
     544        QString resulttext = dce->GetResultText();
     545        int     buttonnum  = dce->GetResult();
     546
     547        if (resultid == "sortmenu")
     548        {
     549            switch (buttonnum)
     550            {
     551                case 0:
     552                    m_reverseSort = !m_reverseSort;
     553                    needUpdate    = true;
     554                    break;
     555                case 1:
     556                    m_titleGroup   = true;
     557                    m_reverseSort = false;
     558                    needUpdate    = true;
     559                    break;
     560                case 2:
     561                    m_titleGroup   = false;
     562                    m_reverseSort = true;
     563                    needUpdate    = true;
     564                    break;
     565            }
     566        }
     567        else if (resultid == "deleterule")
     568        {
     569            RecordingRule *record =
     570                dce->GetData().value<RecordingRule *>();
     571            if (record && buttonnum > 0 && !record->Delete())
     572            {
     573                LOG(VB_GENERAL, LOG_ERR, LOC +
     574                    "Failed to delete recording rule");
     575            }
     576            if (record)
     577                delete record;
     578        }
     579        else
     580        {
     581            ScheduleCommon::customEvent(event);
     582        }
     583    }
     584    else if (event->type() == ScreenLoadCompletionEvent::kEventType)
     585    {
     586        ScreenLoadCompletionEvent *slce = (ScreenLoadCompletionEvent*)(event);
     587        QString id = slce->GetId();
     588
     589        if (id == objectName())
     590        {
     591            CloseBusyPopup(); // opened by LoadInBackground()
     592            UpdateTitleList();
     593            m_showData.clear();
     594            m_showList->Reset();
     595            updateInfo();
     596            SetFocusWidget(m_titleList);
     597        }
     598    }
     599
     600    if (needUpdate)
     601        LoadInBackground();
     602}
     603
     604void PrevRecordedList::AllowRecord(void)
     605{
     606    ProgramInfo *pi = GetCurrentProgram();
     607    if (pi)
     608    {
     609        int pos = m_showList->GetCurrentPos();
     610        RecordingInfo ri(*pi);
     611        ri.ForgetHistory();
     612        showListTakeFocus();
     613        updateInfo();
     614        m_showList->SetItemCurrent(pos);
     615    }
     616}
     617
     618void PrevRecordedList::PreventRecord(void)
     619{
     620    ProgramInfo *pi = GetCurrentProgram();
     621    if (pi)
     622    {
     623        int pos = m_showList->GetCurrentPos();
     624        RecordingInfo ri(*pi);
     625        ri.SetDupHistory();
     626        showListTakeFocus();
     627        updateInfo();
     628        m_showList->SetItemCurrent(pos);
     629    }
     630}
     631
     632
     633ProgramInfo *PrevRecordedList::GetCurrentProgram(void) const
     634{
     635    int pos = m_showList->GetCurrentPos();
     636    if (pos >= 0 && pos < (int) m_showData.size())
     637        return m_showData[pos];
     638    return NULL;
     639}
     640
     641void PrevRecordedList::ShowDeleteOldEpisodeMenu(void)
     642{
     643    ProgramInfo *pi = GetCurrentProgram();
     644
     645    if (!pi)
     646        return;
     647
     648    QString message = tr("Delete this episode of '%1' from the previously recorded history?").arg(pi->GetTitle());
     649
     650    ShowOkPopup(message, this, SLOT(DeleteOldEpisode(bool)), true);
     651}
     652
     653void PrevRecordedList::DeleteOldEpisode(bool ok)
     654{
     655    ProgramInfo *pi = GetCurrentProgram();
     656    if (!ok || !pi)
     657        return;
     658
     659    MSqlQuery query(MSqlQuery::InitCon());
     660    query.prepare(
     661        "DELETE FROM oldrecorded "
     662        "WHERE chanid    = :CHANID AND "
     663        "      starttime = :STARTTIME");
     664    query.bindValue(":CHANID",    pi->GetChanID());
     665    query.bindValue(":STARTTIME", pi->GetScheduledStartTime());
     666
     667    if (!query.exec())
     668        MythDB::DBError("ProgLister::DeleteOldEpisode", query);
     669
     670    ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode");
     671    showListTakeFocus();
     672}
     673
     674void PrevRecordedList::ShowDeleteOldSeriesMenu(void)
     675{
     676    ProgramInfo *pi = GetCurrentProgram();
     677
     678    if (!pi)
     679        return;
     680
     681    QString message = tr("Delete all episodes of '%1' from the previously recorded history?").arg(pi->GetTitle());
     682
     683    ShowOkPopup(message, this, SLOT(DeleteOldSeries(bool)), true);
     684}
     685
     686void PrevRecordedList::DeleteOldSeries(bool ok)
     687{
     688    ProgramInfo *pi = GetCurrentProgram();
     689    if (!ok || !pi)
     690        return;
     691
     692    MSqlQuery query(MSqlQuery::InitCon());
     693    query.prepare("DELETE FROM oldrecorded "
     694                  "WHERE title = :TITLE AND future = 0");
     695    query.bindValue(":TITLE", pi->GetTitle());
     696    if (!query.exec())
     697        MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query);
     698
     699    // Set the programid to the special value of "**any**" which the
     700    // scheduler recognizes to mean the entire series was deleted.
     701    RecordingInfo tempri(*pi);
     702    tempri.SetProgramID("**any**");
     703    ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries");
     704    showListTakeFocus();
     705}
  • new file mythtv/programs/mythfrontend/prevreclist.h

    diff --git a/mythtv/programs/mythfrontend/prevreclist.h b/mythtv/programs/mythfrontend/prevreclist.h
    new file mode 100644
    index 0000000..737fe0a
    - +  
     1/*
     2 * Copyright (c) 2017 Peter G Bennett <pbennett@mythtv.org>
     3 *
     4 * This file is part of MythTV.
     5 *
     6 * MythTV is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Public License as
     8 * published by the Free Software Foundation; either
     9 * version 2 of the License, or (at your option) any later version.
     10 *
     11 * MythTV is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with MythTV. If not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#ifndef PREVRECLIST_H_
     21#define PREVRECLIST_H_
     22
     23// mythfrontend
     24#include "schedulecommon.h"
     25#include "programinfo.h"
     26
     27class MythMenu;
     28
     29class PrevRecordedList : public ScheduleCommon
     30{
     31    Q_OBJECT
     32  public:
     33    explicit PrevRecordedList(MythScreenStack *parent, uint recid = 0,
     34                        const QString &title = QString());
     35    ~PrevRecordedList();
     36    bool Create(void);
     37    bool keyPressEvent(QKeyEvent *e);
     38    void customEvent(QEvent *event);
     39
     40  protected slots:
     41    void ShowMenu(void);
     42    void updateInfo(void);
     43    void showListLoseFocus(void);
     44    void showListTakeFocus(void);
     45    void DeleteOldEpisode(bool ok);
     46    void AllowRecord(void);
     47    void PreventRecord(void);
     48    void DeleteOldSeries(bool ok);
     49    void ShowDeleteOldSeriesMenu(void);
     50    void ShowDeleteOldEpisodeMenu(void);
     51
     52  protected:
     53    void Init(void);
     54    void Load(void);
     55
     56    bool LoadTitles(void);
     57    bool LoadDates(void);
     58    void UpdateTitleList(void);
     59    void UpdateShowList(void);
     60    void UpdateList(MythUIButtonList *bnList, ProgramList *progData);
     61    void LoadShowsByTitle(void);
     62    void LoadShowsByDate(void);
     63
     64    ProgramInfo *GetCurrentProgram(void) const;
     65    MythMenu *deleteMenu(bool bShow=true);
     66
     67    // Left hand list - titles or dates
     68    ProgramList m_titleData;
     69    MythUIButtonList *m_titleList;
     70    // Right hand list - show details
     71    ProgramList m_showData;
     72    MythUIButtonList *m_showList;
     73    // MythUIStateType *m_groupByState;
     74
     75    MythUIText       *m_searchText;
     76    MythUIText       *m_help1Text;
     77    MythUIText       *m_help2Text;
     78
     79    InfoMap m_infoMap;
     80
     81    bool              m_titleGroup;
     82    bool              m_reverseSort;
     83    bool              m_allowEvents;
     84    uint              m_recid;
     85    QString           m_title;
     86    QString           m_where;
     87};
     88
     89#endif
  • mythtv/programs/mythfrontend/schedulecommon.cpp

    diff --git a/mythtv/programs/mythfrontend/schedulecommon.cpp b/mythtv/programs/mythfrontend/schedulecommon.cpp
    index 697e8ce..5d2a7a7 100644
    a b  
    2222#include "scheduleeditor.h"
    2323
    2424#include "proglist.h"
     25#include "prevreclist.h"
    2526#include "customedit.h"
    2627#include "guidegrid.h"
    2728#include "progdetails.h"
    void ScheduleCommon::EditScheduled(RecordingInfo *recinfo) 
    190191    if (schededit->Create())
    191192        mainStack->AddScreen(schededit);
    192193    else
     194    {
    193195        delete schededit;
     196        ShowOkPopup(tr("Recording rule does not exist."));
     197    }
    194198}
    195199
    196200/**
    void ScheduleCommon::ShowPrevious(void) const 
    257261void ScheduleCommon::ShowPrevious(uint ruleid, const QString &title) const
    258262{
    259263    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
    260     ProgLister *pl = new ProgLister(mainStack, ruleid, title);
     264    PrevRecordedList *pl = new PrevRecordedList(mainStack, ruleid, title);
    261265    if (pl->Create())
    262266        mainStack->AddScreen(pl);
    263267    else
  • mythtv/themes/MythCenter-wide/schedule-ui.xml

    diff --git a/mythtv/themes/MythCenter-wide/schedule-ui.xml b/mythtv/themes/MythCenter-wide/schedule-ui.xml
    index 9b1ff20..f78ebb1 100644
    a b  
    11061106
    11071107    </window>
    11081108
     1109    <window name="prevreclist">
     1110
     1111        <shape name="details_background" from="basebackground">
     1112            <area>38,29,1203,259</area>
     1113        </shape>
     1114
     1115        <shape name="titles_background" from="basebackground">
     1116            <area>38,302,480,389</area>
     1117        </shape>
     1118
     1119        <shape name="shows_background" from="basebackground">
     1120            <area>538,302,704,389</area>
     1121        </shape>
     1122
     1123        <buttonlist name="titles" from="basebuttonlist2">
     1124            <area>54,307,448,384</area>
     1125            <scrollstyle>center</scrollstyle>
     1126            <!-- <wrapstyle>items</wrapstyle> -->
     1127            <spacing>0</spacing>
     1128            <buttonarea>0,0,448,384</buttonarea>
     1129            <statetype name="buttonitem">
     1130                <area>0,0,448,38</area>
     1131                <state name="active">
     1132                    <textarea name="title" from="basetextarea">
     1133                        <area>8,0,432,38</area>
     1134                        <font>basesmallgrey</font>
     1135                        <cutdown>yes</cutdown>
     1136                        <align>left,vcenter</align>
     1137                    </textarea>
     1138                </state>
     1139                <state name="selectedactive" from="active">
     1140                    <textarea name="title">
     1141                        <font>basesmall</font>
     1142                    </textarea>
     1143                    <shape name="selectbar">
     1144                        <area>0,0,448,38</area>
     1145                    </shape>
     1146                </state>
     1147                <state name="selectedinactive" from="selectedactive">
     1148                    <textarea name="title">
     1149                        <font>basesmallpurple</font>
     1150                    </textarea>
     1151                    <shape name="selectbar">
     1152                        <area>0,0,448,38</area>
     1153                    </shape>
     1154                </state>
     1155            </statetype>
     1156            <statetype name="upscrollarrow">
     1157                <state type="off">
     1158                    <imagetype name="upon">
     1159                        <filename></filename>
     1160                    </imagetype>
     1161                </state>
     1162                <state type="full">
     1163                    <imagetype name="upoff">
     1164                        <filename></filename>
     1165                    </imagetype>
     1166                </state>
     1167            </statetype>
     1168            <statetype name="downscrollarrow">
     1169                <state type="off">
     1170                    <imagetype name="dnon">
     1171                        <filename></filename>
     1172                    </imagetype>
     1173                </state>
     1174                <state type="full">
     1175                    <imagetype name="dnoff">
     1176                        <filename></filename>
     1177                    </imagetype>
     1178                </state>
     1179            </statetype>
     1180        </buttonlist>
     1181
     1182        <buttonlist name="shows" from="titles">
     1183            <area>554,307,672,384</area>
     1184            <buttonarea>0,0,672,384</buttonarea>
     1185            <statetype name="buttonitem">
     1186                <area>0,0,672,38</area>
     1187                <state name="active">
     1188                    <textarea name="title">
     1189                        <area>0,0,0,0</area>
     1190                    </textarea>
     1191                    <textarea name="startdate" from="basetextarea">
     1192                        <area>8,0,184,38</area>
     1193                        <font>basesmall</font>
     1194                        <font state="disabled">basesmallpurple</font>
     1195                        <font state="error">basesmallred</font>
     1196                        <font state="warning">basesmallyellow</font>
     1197                        <font state="normal">basesmallblue</font>
     1198                        <font state="running">basesmallgreen</font>
     1199                        <align>left,vcenter</align>
     1200                        <cutdown>no</cutdown>
     1201                    </textarea>
     1202                    <textarea name="parttitle" from="startdate">
     1203                        <area>200,0,448,38</area>
     1204                        <cutdown>yes</cutdown>
     1205                    </textarea>
     1206                    <textarea name="card" from="startdate">
     1207                        <area>648,0,16,38</area>
     1208                        <cutdown>no</cutdown>
     1209                    </textarea>
     1210                </state>
     1211                <state name="selectedactive" from="active">
     1212                    <shape name="selectbar">
     1213                        <area>0,0,672,38</area>
     1214                    </shape>
     1215                </state>
     1216                <state name="selectedinactive" from="selectedactive" />
     1217                <state name="inactive" from="selectedactive" />
     1218            </statetype>
     1219        </buttonlist>
     1220
     1221        <textarea name="title" from="basetextarea">
     1222            <area>80,42,1120,54</area>
     1223            <font>baselarge</font>
     1224        </textarea>
     1225        <textarea name="timedate" from="basetextarea">
     1226            <area>80,216,704,32</area>
     1227        </textarea>
     1228        <textarea name="channel" from="basetextarea">
     1229            <area>880,216,320,42</area>
     1230            <align>right</align>
     1231        </textarea>
     1232        <textarea name="rectypestatus" from="basetextarea">
     1233            <area>80,246,960,42</area>
     1234            <font>basesmallyellow</font>
     1235        </textarea>
     1236        <textarea name="description" from="basetextarea">
     1237            <area>80,84,1120,144</area>
     1238            <multiline>yes</multiline>
     1239            <template>%"|SUBTITLE|"\n%%LONGREPEAT%%(|STARS|) %%DESCRIPTION%</template>
     1240        </textarea>
     1241
     1242        <textarea name="help1text" from="basetextarea">
     1243            <area>72,54,1120,36</area>
     1244        </textarea>
     1245        <textarea name="help2text" from="basetextarea">
     1246            <area>72,120,1120,144</area>
     1247            <multiline>yes</multiline>
     1248        </textarea>
     1249
     1250    </window>
     1251
    11091252    <window name="progdetails">
    11101253
    11111254        <textarea name="title" from="basetextarea">
  • mythtv/themes/MythCenter/schedule-ui.xml

    diff --git a/mythtv/themes/MythCenter/schedule-ui.xml b/mythtv/themes/MythCenter/schedule-ui.xml
    index 26599f6..be62754 100644
    a b  
    10461046
    10471047    </window>
    10481048
     1049    <window name="prevreclist">
     1050
     1051        <shape name="details_background" from="basebackground">
     1052            <area>24,24,752,216</area>
     1053        </shape>
     1054
     1055        <shape name="titles_background" from="basebackground">
     1056            <area>24,252,300,324</area>
     1057        </shape>
     1058
     1059        <shape name="shows_background" from="basebackground">
     1060            <area>336,252,440,324</area>
     1061        </shape>
     1062
     1063        <buttonlist name="titles" from="basebuttonlist2">
     1064            <area>34,256,280,320</area>
     1065            <scrollstyle>center</scrollstyle>
     1066            <!-- <wrapstyle>items</wrapstyle> -->
     1067            <spacing>0</spacing>
     1068            <buttonarea>0,0,280,320</buttonarea>
     1069            <statetype name="buttonitem">
     1070                <area>0,0,280,32</area>
     1071                <state name="active">
     1072                    <textarea name="title" from="basetextarea">
     1073                        <area>5,0,270,32</area>
     1074                        <font>basesmallgrey</font>
     1075                        <cutdown>yes</cutdown>
     1076                        <align>left,vcenter</align>
     1077                    </textarea>
     1078                </state>
     1079                <state name="selectedactive" from="active">
     1080                    <textarea name="title">
     1081                        <font>basesmall</font>
     1082                    </textarea>
     1083                    <shape name="selectbar">
     1084                        <area>0,0,280,32</area>
     1085                    </shape>
     1086                </state>
     1087                <state name="selectedinactive" from="selectedactive">
     1088                    <textarea name="title">
     1089                        <font>basesmallpurple</font>
     1090                    </textarea>
     1091                    <shape name="selectbar">
     1092                        <area>0,0,280,32</area>
     1093                    </shape>
     1094                </state>
     1095            </statetype>
     1096            <statetype name="upscrollarrow">
     1097                <state type="off">
     1098                    <imagetype name="upon">
     1099                        <filename></filename>
     1100                    </imagetype>
     1101                </state>
     1102                <state type="full">
     1103                    <imagetype name="upoff">
     1104                        <filename></filename>
     1105                    </imagetype>
     1106                </state>
     1107            </statetype>
     1108            <statetype name="downscrollarrow">
     1109                <state type="off">
     1110                    <imagetype name="dnon">
     1111                        <filename></filename>
     1112                    </imagetype>
     1113                </state>
     1114                <state type="full">
     1115                    <imagetype name="dnoff">
     1116                        <filename></filename>
     1117                    </imagetype>
     1118                </state>
     1119            </statetype>
     1120        </buttonlist>
     1121
     1122        <buttonlist name="shows" from="titles">
     1123            <area>346,256,420,320</area>
     1124            <buttonarea>0,0,420,320</buttonarea>
     1125            <statetype name="buttonitem">
     1126                <area>0,0,420,32</area>
     1127                <state name="active">
     1128                    <textarea name="title">
     1129                        <area>0,0,0,0</area>
     1130                    </textarea>
     1131                    <textarea name="startdate" from="basetextarea">
     1132                        <area>5,0,155,32</area>
     1133                        <font>basesmall</font>
     1134                        <font state="disabled">basesmallpurple</font>
     1135                        <font state="error">basesmallred</font>
     1136                        <font state="warning">basesmallyellow</font>
     1137                        <font state="normal">basesmallblue</font>
     1138                        <font state="running">basesmallgreen</font>
     1139                        <align>left,vcenter</align>
     1140                        <cutdown>no</cutdown>
     1141                    </textarea>
     1142                    <textarea name="parttitle" from="startdate">
     1143                        <area>165,0,240,32</area>
     1144                        <cutdown>yes</cutdown>
     1145                    </textarea>
     1146                    <textarea name="card" from="startdate">
     1147                        <area>405,0,10,32</area>
     1148                        <cutdown>no</cutdown>
     1149                    </textarea>
     1150                </state>
     1151                <state name="selectedactive" from="active">
     1152                    <shape name="selectbar">
     1153                        <area>0,0,420,32</area>
     1154                    </shape>
     1155                </state>
     1156                <state name="selectedinactive" from="selectedactive" />
     1157                <state name="inactive" from="selectedactive" />
     1158            </statetype>
     1159        </buttonlist>
     1160
     1161        <textarea name="title" from="basetextarea">
     1162            <area>50,35,700,45</area>
     1163            <font>baselarge</font>
     1164        </textarea>
     1165        <textarea name="timedate" from="basetextarea">
     1166            <area>50,180,440,27</area>
     1167        </textarea>
     1168        <textarea name="channel" from="basetextarea">
     1169            <area>550,180,200,35</area>
     1170            <align>right</align>
     1171        </textarea>
     1172        <textarea name="rectypestatus" from="basetextarea">
     1173            <area>50,205,600,35</area>
     1174            <font>basesmallyellow</font>
     1175        </textarea>
     1176        <textarea name="description" from="basetextarea">
     1177            <area>50,70,700,120</area>
     1178            <multiline>yes</multiline>
     1179            <template>%"|SUBTITLE|"\n%%LONGREPEAT%%(|STARS|) %%DESCRIPTION%</template>
     1180        </textarea>
     1181
     1182        <textarea name="help1text" from="basetextarea">
     1183            <area>45,45,700,30</area>
     1184        </textarea>
     1185        <textarea name="help2text" from="basetextarea">
     1186            <area>45,100,700,120</area>
     1187            <multiline>yes</multiline>
     1188        </textarea>
     1189
     1190    </window>
     1191
    10491192    <window name="progdetails">
    10501193
    10511194        <textarea name="title" from="basetextarea">
  • mythtv/themes/Terra/schedule-ui.xml

    diff --git a/mythtv/themes/Terra/schedule-ui.xml b/mythtv/themes/Terra/schedule-ui.xml
    index ed7d521..68cc970 100644
    a b  
    985985
    986986    </window>
    987987
     988    <window name="prevreclist">
     989
     990        <imagetype name="backdrop" from="basebackdrop" />
     991        <imagetype name="topbar" from="basetopbar" />
     992
     993        <textarea name="heading" from="baseheading">
     994            <value>Previously Recorded</value>
     995        </textarea>
     996
     997        <shape name="details_background" from="basebackground">
     998            <area>38,50,1203,238</area>
     999        </shape>
     1000
     1001        <shape name="titles_background" from="basebackground">
     1002            <area>38,302,376,374</area>
     1003        </shape>
     1004
     1005        <shape name="shows_background" from="basebackground">
     1006            <area>434,302,808,374</area>
     1007        </shape>
     1008
     1009        <buttonlist name="titles" from="basebuttonlist2">
     1010            <area>54,307,344,370</area>
     1011            <scrollstyle>center</scrollstyle>
     1012            <!-- <wrapstyle>items</wrapstyle> -->
     1013            <spacing>0</spacing>
     1014            <buttonarea>0,0,344,370</buttonarea>
     1015            <statetype name="buttonitem">
     1016                <area>0,0,344,38</area>
     1017                <state name="active">
     1018                    <textarea name="title" from="basetextarea">
     1019                        <area>8,0,328,38</area>
     1020                        <font>basesmallgrey</font>
     1021                        <cutdown>yes</cutdown>
     1022                        <align>left,vcenter</align>
     1023                    </textarea>
     1024                </state>
     1025                <state name="selectedactive" from="active">
     1026                    <textarea name="title">
     1027                        <font>basesmall</font>
     1028                    </textarea>
     1029                    <shape name="selectbar">
     1030                        <area>0,0,344,38</area>
     1031                    </shape>
     1032                </state>
     1033                <state name="selectedinactive" from="selectedactive">
     1034                    <textarea name="title">
     1035                        <font>basesmallpurple</font>
     1036                    </textarea>
     1037                    <shape name="selectbar">
     1038                        <area>0,0,344,38</area>
     1039                    </shape>
     1040                </state>
     1041            </statetype>
     1042            <statetype name="upscrollarrow">
     1043                <state type="off">
     1044                    <imagetype name="upon">
     1045                        <filename></filename>
     1046                    </imagetype>
     1047                </state>
     1048                <state type="full">
     1049                    <imagetype name="upoff">
     1050                        <filename></filename>
     1051                    </imagetype>
     1052                </state>
     1053            </statetype>
     1054            <statetype name="downscrollarrow">
     1055                <state type="off">
     1056                    <imagetype name="dnon">
     1057                        <filename></filename>
     1058                    </imagetype>
     1059                </state>
     1060                <state type="full">
     1061                    <imagetype name="dnoff">
     1062                        <filename></filename>
     1063                    </imagetype>
     1064                </state>
     1065            </statetype>
     1066        </buttonlist>
     1067
     1068        <buttonlist name="shows" from="titles">
     1069            <area>450,307,776,370</area>
     1070            <buttonarea>0,0,776,370</buttonarea>
     1071            <statetype name="buttonitem">
     1072                <area>0,0,776,38</area>
     1073                <state name="active">
     1074                    <textarea name="title">
     1075                        <area>0,0,0,0</area>
     1076                    </textarea>
     1077                    <textarea name="startdate" from="basetextarea">
     1078                        <area>8,0,216,38</area>
     1079                        <font>basesmall</font>
     1080                        <align>left,vcenter</align>
     1081                        <cutdown>no</cutdown>
     1082                    </textarea>
     1083                    <textarea name="parttitle" from="startdate">
     1084                        <area>232,0,512,38</area>
     1085                        <cutdown>yes</cutdown>
     1086                    </textarea>
     1087                    <textarea name="card" from="startdate">
     1088                        <area>744,0,24,38</area>
     1089                        <font state="disabled">basesmallpurple</font>
     1090                        <font state="error">basesmallred</font>
     1091                        <font state="warning">basesmallyellow</font>
     1092                        <font state="normal">basesmallblue</font>
     1093                        <font state="running">basesmallgreen</font>
     1094                        <cutdown>no</cutdown>
     1095                    </textarea>
     1096                </state>
     1097                <state name="selectedactive" from="active">
     1098                    <shape name="selectbar">
     1099                        <area>0,0,776,38</area>
     1100                    </shape>
     1101                </state>
     1102                <state name="selectedinactive" from="selectedactive" />
     1103                <state name="inactive" from="active" />
     1104            </statetype>
     1105        </buttonlist>
     1106
     1107        <textarea name="title" from="basetextarea">
     1108            <area>80,63,1120,54</area>
     1109            <font>baselarge</font>
     1110        </textarea>
     1111        <textarea name="timedate" from="basetextarea">
     1112            <area>80,216,704,32</area>
     1113        </textarea>
     1114        <textarea name="channel" from="basetextarea">
     1115            <area>880,216,320,42</area>
     1116            <align>right</align>
     1117        </textarea>
     1118        <textarea name="rectypestatus" from="basetextarea">
     1119            <area>80,246,960,42</area>
     1120            <font>basesmallyellow</font>
     1121        </textarea>
     1122        <textarea name="description" from="basetextarea">
     1123            <area>80,105,1120,144</area>
     1124            <multiline>yes</multiline>
     1125            <template>%"|SUBTITLE|"\n%%LONGREPEAT%%(|STARS|) %%DESCRIPTION%</template>
     1126        </textarea>
     1127
     1128        <textarea name="help1text" from="basetextarea">
     1129            <area>72,75,1120,36</area>
     1130        </textarea>
     1131        <textarea name="help2text" from="basetextarea">
     1132            <area>72,120,1120,144</area>
     1133            <multiline>yes</multiline>
     1134        </textarea>
     1135
     1136    </window>
     1137
    9881138    <window name="programguide">
    9891139
    9901140        <imagetype name="backdrop" from="basebackdrop" />
  • mythtv/themes/default-wide/schedule-ui.xml

    diff --git a/mythtv/themes/default-wide/schedule-ui.xml b/mythtv/themes/default-wide/schedule-ui.xml
    index 1fb8a0a..546f181 100644
    a b  
    10711071
    10721072    </window>
    10731073
     1074    <window name="prevreclist">
     1075
     1076        <shape name="details_background" from="basebackground">
     1077            <area>38,29,1203,259,1280x720</area>
     1078        </shape>
     1079
     1080        <shape name="titles_background" from="basebackground">
     1081            <area>38,302,376,389,1280x720</area>
     1082        </shape>
     1083
     1084        <shape name="shows_background" from="basebackground">
     1085            <area>434,302,808,389,1280x720</area>
     1086        </shape>
     1087
     1088        <buttonlist name="titles" from="basebuttonlist2">
     1089            <area>54,307,344,384,1280x720</area>
     1090            <scrollstyle>center</scrollstyle>
     1091            <!-- <wrapstyle>items</wrapstyle> -->
     1092            <spacing>0</spacing>
     1093            <buttonarea>0,0,344,384,1280x720</buttonarea>
     1094            <statetype name="buttonitem">
     1095                <area>0,0,344,38,1280x720</area>
     1096                <state name="active">
     1097                    <textarea name="title" from="basetextarea">
     1098                        <area>8,0,328,38,1280x720</area>
     1099                        <font>basesmallgrey</font>
     1100                        <cutdown>yes</cutdown>
     1101                        <align>left,vcenter</align>
     1102                    </textarea>
     1103                </state>
     1104                <state name="selectedactive" from="active">
     1105                    <textarea name="title">
     1106                        <font>basesmall</font>
     1107                    </textarea>
     1108                    <shape name="selectbar">
     1109                        <area>0,0,344,38,1280x720</area>
     1110                    </shape>
     1111                </state>
     1112                <state name="selectedinactive" from="selectedactive">
     1113                    <textarea name="title">
     1114                        <font>basesmallpurple</font>
     1115                    </textarea>
     1116                    <shape name="selectbar">
     1117                        <area>0,0,344,38,1280x720</area>
     1118                    </shape>
     1119                </state>
     1120            </statetype>
     1121            <statetype name="upscrollarrow">
     1122                <state type="off">
     1123                    <imagetype name="upon">
     1124                        <filename></filename>
     1125                    </imagetype>
     1126                </state>
     1127                <state type="full">
     1128                    <imagetype name="upoff">
     1129                        <filename></filename>
     1130                    </imagetype>
     1131                </state>
     1132            </statetype>
     1133            <statetype name="downscrollarrow">
     1134                <state type="off">
     1135                    <imagetype name="dnon">
     1136                        <filename></filename>
     1137                    </imagetype>
     1138                </state>
     1139                <state type="full">
     1140                    <imagetype name="dnoff">
     1141                        <filename></filename>
     1142                    </imagetype>
     1143                </state>
     1144            </statetype>
     1145        </buttonlist>
     1146
     1147        <buttonlist name="shows" from="titles">
     1148            <area>450,307,776,384,1280x720</area>
     1149            <buttonarea>0,0,776,384,1280x720</buttonarea>
     1150            <statetype name="buttonitem">
     1151                <area>0,0,776,38,1280x720</area>
     1152                <state name="active">
     1153                    <textarea name="title">
     1154                        <area>0,0,0,0</area>
     1155                    </textarea>
     1156                    <textarea name="startdate" from="basetextarea">
     1157                        <area>8,0,216,38,1280x720</area>
     1158                        <font>basesmall</font>
     1159                        <align>left,vcenter</align>
     1160                        <cutdown>no</cutdown>
     1161                    </textarea>
     1162                    <textarea name="parttitle" from="startdate">
     1163                        <area>232,0,512,38,1280x720</area>
     1164                        <cutdown>yes</cutdown>
     1165                    </textarea>
     1166                    <textarea name="card" from="startdate">
     1167                        <area>744,0,24,38,1280x720</area>
     1168                        <font state="disabled">basesmallpurple</font>
     1169                        <font state="error">basesmallred</font>
     1170                        <font state="warning">basesmallyellow</font>
     1171                        <font state="normal">basesmallblue</font>
     1172                        <font state="running">basesmallgreen</font>
     1173                        <cutdown>no</cutdown>
     1174                    </textarea>
     1175                </state>
     1176                <state name="selectedactive" from="active">
     1177                    <shape name="selectbar">
     1178                        <area>0,0,776,38,1280x720</area>
     1179                    </shape>
     1180                </state>
     1181                <state name="selectedinactive" from="selectedactive" />
     1182                <state name="inactive" from="selectedactive" />
     1183            </statetype>
     1184        </buttonlist>
     1185
     1186        <textarea name="title" from="basetextarea">
     1187            <area>80,42,1120,54,1280x720</area>
     1188            <font>baselarge</font>
     1189        </textarea>
     1190        <textarea name="timedate" from="basetextarea">
     1191            <area>80,216,704,32,1280x720</area>
     1192        </textarea>
     1193        <textarea name="channel" from="basetextarea">
     1194            <area>880,216,320,42,1280x720</area>
     1195            <align>right</align>
     1196        </textarea>
     1197        <textarea name="rectypestatus" from="basetextarea">
     1198            <area>80,246,960,42,1280x720</area>
     1199            <font>basesmallyellow</font>
     1200        </textarea>
     1201        <textarea name="description" from="basetextarea">
     1202            <area>80,84,1120,144,1280x720</area>
     1203            <multiline>yes</multiline>
     1204            <template>%"|SUBTITLE|"\n%%LONGREPEAT%%(|STARS|) %%DESCRIPTION%</template>
     1205        </textarea>
     1206
     1207        <textarea name="help1text" from="basetextarea">
     1208            <area>72,54,1120,36,1280x720</area>
     1209        </textarea>
     1210        <textarea name="help2text" from="basetextarea">
     1211            <area>72,120,1120,144,1280x720</area>
     1212            <multiline>yes</multiline>
     1213        </textarea>
     1214
     1215    </window>
     1216
    10741217    <window name="progdetails">
    10751218
    10761219        <textarea name="title" from="basetextarea">
  • mythtv/themes/default/schedule-ui.xml

    diff --git a/mythtv/themes/default/schedule-ui.xml b/mythtv/themes/default/schedule-ui.xml
    index 0229cb5..1b3ea87 100644
    a b  
    11311131
    11321132    </window>
    11331133
     1134    <window name="prevreclist">
     1135
     1136        <shape name="details_background" from="basebackground">
     1137            <area>24,24,752,216,800x600</area>
     1138        </shape>
     1139
     1140        <shape name="titles_background" from="basebackground">
     1141            <area>24,252,300,324,800x600</area>
     1142        </shape>
     1143
     1144        <shape name="shows_background" from="basebackground">
     1145            <area>336,252,440,324,800x600</area>
     1146        </shape>
     1147
     1148        <buttonlist name="titles" from="basebuttonlist2">
     1149            <area>34,256,280,320,800x600</area>
     1150            <scrollstyle>center</scrollstyle>
     1151            <!-- <wrapstyle>items</wrapstyle> -->
     1152            <spacing>0</spacing>
     1153            <buttonarea>0,0,280,320,800x600</buttonarea>
     1154            <statetype name="buttonitem">
     1155                <area>0,0,280,32,800x600</area>
     1156                <state name="active">
     1157                    <textarea name="title" from="basetextarea">
     1158                        <area>5,0,270,32,800x600</area>
     1159                        <font>basesmallgrey</font>
     1160                        <cutdown>yes</cutdown>
     1161                        <align>left,vcenter</align>
     1162                    </textarea>
     1163                </state>
     1164                <state name="selectedactive" from="active">
     1165                    <textarea name="title">
     1166                        <font>basesmall</font>
     1167                    </textarea>
     1168                    <shape name="selectbar">
     1169                        <area>0,0,280,32,800x600</area>
     1170                    </shape>
     1171                </state>
     1172                <state name="selectedinactive" from="selectedactive">
     1173                    <textarea name="title">
     1174                        <font>basesmallpurple</font>
     1175                    </textarea>
     1176                    <shape name="selectbar">
     1177                        <area>0,0,280,32,800x600</area>
     1178                    </shape>
     1179                </state>
     1180            </statetype>
     1181            <statetype name="upscrollarrow">
     1182                <state type="off">
     1183                    <imagetype name="upon">
     1184                        <filename></filename>
     1185                    </imagetype>
     1186                </state>
     1187                <state type="full">
     1188                    <imagetype name="upoff">
     1189                        <filename></filename>
     1190                    </imagetype>
     1191                </state>
     1192            </statetype>
     1193            <statetype name="downscrollarrow">
     1194                <state type="off">
     1195                    <imagetype name="dnon">
     1196                        <filename></filename>
     1197                    </imagetype>
     1198                </state>
     1199                <state type="full">
     1200                    <imagetype name="dnoff">
     1201                        <filename></filename>
     1202                    </imagetype>
     1203                </state>
     1204            </statetype>
     1205        </buttonlist>
     1206
     1207        <buttonlist name="shows" from="titles">
     1208            <area>346,256,420,320,800x600</area>
     1209            <buttonarea>0,0,420,320,800x600</buttonarea>
     1210            <statetype name="buttonitem">
     1211                <area>0,0,420,32,800x600</area>
     1212                <state name="active">
     1213                    <textarea name="title">
     1214                        <area>0,0,0,0</area>
     1215                    </textarea>
     1216                    <textarea name="startdate" from="basetextarea">
     1217                        <area>5,0,115,32,800x600</area>
     1218                        <font>basesmall</font>
     1219                        <align>left,vcenter</align>
     1220                        <cutdown>no</cutdown>
     1221                    </textarea>
     1222                    <textarea name="parttitle" from="startdate">
     1223                        <area>125,0,280,32,800x600</area>
     1224                        <cutdown>yes</cutdown>
     1225                    </textarea>
     1226                    <textarea name="card" from="startdate">
     1227                        <area>405,0,10,32,800x600</area>
     1228                        <font state="disabled">basesmallpurple</font>
     1229                        <font state="error">basesmallred</font>
     1230                        <font state="warning">basesmallyellow</font>
     1231                        <font state="normal">basesmallblue</font>
     1232                        <font state="running">basesmallgreen</font>
     1233                        <cutdown>no</cutdown>
     1234                    </textarea>
     1235                </state>
     1236                <state name="selectedactive" from="active">
     1237                    <shape name="selectbar">
     1238                        <area>0,0,420,32,800x600</area>
     1239                    </shape>
     1240                </state>
     1241                <state name="selectedinactive" from="selectedactive" />
     1242                <state name="inactive" from="selectedactive" />
     1243            </statetype>
     1244        </buttonlist>
     1245
     1246        <textarea name="title" from="basetextarea">
     1247            <area>50,35,700,45,800x600</area>
     1248            <font>baselarge</font>
     1249        </textarea>
     1250        <textarea name="timedate" from="basetextarea">
     1251            <area>50,180,440,27,800x600</area>
     1252        </textarea>
     1253        <textarea name="channel" from="basetextarea">
     1254            <area>550,180,200,35,800x600</area>
     1255            <align>right</align>
     1256        </textarea>
     1257        <textarea name="rectypestatus" from="basetextarea">
     1258            <area>50,205,600,35,800x600</area>
     1259            <font>basesmallyellow</font>
     1260        </textarea>
     1261        <textarea name="description" from="basetextarea">
     1262            <area>50,70,700,120,800x600</area>
     1263            <multiline>yes</multiline>
     1264            <template>%"|SUBTITLE|"\n%%LONGREPEAT%%(|STARS|) %%DESCRIPTION%</template>
     1265        </textarea>
     1266
     1267        <textarea name="help1text" from="basetextarea">
     1268            <area>45,45,700,30,800x600</area>
     1269        </textarea>
     1270        <textarea name="help2text" from="basetextarea">
     1271            <area>45,100,700,120,800x600</area>
     1272            <multiline>yes</multiline>
     1273        </textarea>
     1274
     1275    </window>
     1276
    11341277    <window name="programdetails">
    11351278
    11361279        <textarea name="title" from="basetextarea">
  • mythtv/themes/defaultmenu/manage_recordings.xml

    diff --git a/mythtv/themes/defaultmenu/manage_recordings.xml b/mythtv/themes/defaultmenu/manage_recordings.xml
    index c091d8b..972163f 100644
    a b  
    2929        <action>TV_PREVIOUS</action>
    3030    </button>
    3131
     32    <button>
     33        <type>TV_PREVIOUS</type>
     34        <text>Prev Rec (Deprecated)</text>
     35        <description>Old version of Previously Recorded</description>
     36        <action>TV_PREVIOUS_OLD</action>
     37    </button>
     38
    3239</mythmenu>