Ticket #10161: lazystrings_v13.patch

File lazystrings_v13.patch, 16.2 KB (added by Jim Stichnoth, 7 years ago)

Simplify the event structure and the background state. Also, apply the same principle to Previously Recorded and other screens in proglist.cpp.

  • mythtv/programs/mythfrontend/playbackbox.cpp

    diff --git a/mythtv/programs/mythfrontend/playbackbox.cpp b/mythtv/programs/mythfrontend/playbackbox.cpp
    index 2e65654..ebf3166 100644
    a b PlaybackBox::PlaybackBox(MythScreenStack *parent, QString name, BoxType ltype, 
    403403      m_programInfoCache(this),           m_playingSomething(false),
    404404      // Selection state variables
    405405      m_needUpdate(false),
     406      // Background buttonlist loading state
     407      m_bgLoadCur(0),
     408      m_bgLoadPending(false),
    406409      // Other
    407410      m_player(NULL),
    408411      m_helper(this)
    void PlaybackBox::UpdateUIListItem(MythUIButtonListItem *item, 
    890893    }
    891894}
    892895
     896void PlaybackBox::ItemVisibleCore(MythUIButtonListItem *item)
     897{
     898    ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData());
     899    if (item->GetText("is_item_initialized").isNull())
     900    {
     901        QMap<AudioProps, QString> audioFlags;
     902        audioFlags[AUD_DOLBY] = "dolby";
     903        audioFlags[AUD_SURROUND] = "surround";
     904        audioFlags[AUD_STEREO] = "stereo";
     905        audioFlags[AUD_MONO] = "mono";
     906
     907        QMap<VideoProps, QString> videoFlags;
     908        videoFlags[VID_1080] = "hd1080";
     909        videoFlags[VID_720] = "hd720";
     910        videoFlags[VID_HDTV] = "hdtv";
     911        videoFlags[VID_WIDESCREEN] = "widescreen";
     912
     913        QMap<SubtitleTypes, QString> subtitleFlags;
     914        subtitleFlags[SUB_SIGNED] = "deafsigned";
     915        subtitleFlags[SUB_ONSCREEN] = "onscreensub";
     916        subtitleFlags[SUB_NORMAL] = "subtitles";
     917        subtitleFlags[SUB_HARDHEAR] = "cc";
     918
     919        QString groupname =
     920            m_groupList->GetItemCurrent()->GetData().toString();
     921
     922        QString state = extract_main_state(*pginfo, m_player);
     923
     924        item->SetFontState(state);
     925
     926        InfoMap infoMap;
     927        pginfo->ToMap(infoMap);
     928        item->SetTextFromMap(infoMap);
     929
     930        QString tempSubTitle  = extract_subtitle(*pginfo, groupname);
     931
     932        if (groupname == pginfo->GetTitle().toLower())
     933            item->SetText(tempSubTitle, "titlesubtitle");
     934
     935        item->DisplayState(state, "status");
     936
     937        item->DisplayState(QString::number(pginfo->GetStars(10)),
     938                           "ratingstate");
     939
     940        SetItemIcons(item, pginfo);
     941
     942        QMap<AudioProps, QString>::iterator ait;
     943        for (ait = audioFlags.begin(); ait != audioFlags.end(); ++ait)
     944        {
     945            if (pginfo->GetAudioProperties() & ait.key())
     946                item->DisplayState(ait.value(), "audioprops");
     947        }
     948
     949        QMap<VideoProps, QString>::iterator vit;
     950        for (vit = videoFlags.begin(); vit != videoFlags.end(); ++vit)
     951        {
     952            if (pginfo->GetVideoProperties() & vit.key())
     953                item->DisplayState(vit.value(), "videoprops");
     954        }
     955
     956        QMap<SubtitleTypes, QString>::iterator sit;
     957        for (sit = subtitleFlags.begin(); sit != subtitleFlags.end(); ++sit)
     958        {
     959            if (pginfo->GetSubtitleType() & sit.key())
     960                item->DisplayState(sit.value(), "subtitletypes");
     961        }
     962
     963        item->DisplayState(pginfo->GetCategoryType(), "categorytype");
     964
     965        // Mark this button list item as initialized.
     966        item->SetText("yes", "is_item_initialized");
     967    }
     968
     969}
     970
    893971void PlaybackBox::ItemVisible(MythUIButtonListItem *item)
    894972{
    895973    ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData());
    896974
     975    ItemVisibleCore(item);
    897976    // Job status (recording, transcoding, flagging)
    898977    QString job = extract_job_state(*pginfo);
    899978    item->DisplayState(job, "jobstate");
    void PlaybackBox::updateRecList(MythUIButtonListItem *sel_item) 
    13161395
    13171396    ProgramList &progList = *pmit;
    13181397
    1319     QMap<AudioProps, QString> audioFlags;
    1320     audioFlags[AUD_DOLBY] = "dolby";
    1321     audioFlags[AUD_SURROUND] = "surround";
    1322     audioFlags[AUD_STEREO] = "stereo";
    1323     audioFlags[AUD_MONO] = "mono";
    1324 
    1325     QMap<VideoProps, QString> videoFlags;
    1326     videoFlags[VID_1080] = "hd1080";
    1327     videoFlags[VID_720] = "hd720";
    1328     videoFlags[VID_HDTV] = "hdtv";
    1329     videoFlags[VID_WIDESCREEN] = "widescreen";
    1330 
    1331     QMap<SubtitleTypes, QString> subtitleFlags;
    1332     subtitleFlags[SUB_SIGNED] = "deafsigned";
    1333     subtitleFlags[SUB_ONSCREEN] = "onscreensub";
    1334     subtitleFlags[SUB_NORMAL] = "subtitles";
    1335     subtitleFlags[SUB_HARDHEAR] = "cc";
    1336 
    13371398    ProgramList::iterator it = progList.begin();
    13381399    for (; it != progList.end(); ++it)
    13391400    {
    void PlaybackBox::updateRecList(MythUIButtonListItem *sel_item) 
    13411402            (*it)->GetAvailableStatus() == asDeleted)
    13421403            continue;
    13431404
    1344         MythUIButtonListItem *item =
    1345             new PlaybackBoxListItem(this, m_recordingList, *it);
    1346 
    1347         QString state = extract_main_state(**it, m_player);
    1348 
    1349         item->SetFontState(state);
    1350 
    1351         InfoMap infoMap;
    1352         (*it)->ToMap(infoMap);
    1353         item->SetTextFromMap(infoMap);
    1354 
    1355         QString tempSubTitle  = extract_subtitle(**it, groupname);
    1356 
    1357         if (groupname == (*it)->GetTitle().toLower())
    1358             item->SetText(tempSubTitle,       "titlesubtitle");
    1359 
    1360         item->DisplayState(state, "status");
    1361 
    1362         item->DisplayState(QString::number((*it)->GetStars(10)), "ratingstate");
    1363 
    1364         SetItemIcons(item, (*it));
    1365 
    1366         QMap<AudioProps, QString>::iterator ait;
    1367         for (ait = audioFlags.begin(); ait != audioFlags.end(); ++ait)
    1368         {
    1369             if ((*it)->GetAudioProperties() & ait.key())
    1370                 item->DisplayState(ait.value(), "audioprops");
    1371         }
    1372 
    1373         QMap<VideoProps, QString>::iterator vit;
    1374         for (vit = videoFlags.begin(); vit != videoFlags.end(); ++vit)
    1375         {
    1376             if ((*it)->GetVideoProperties() & vit.key())
    1377                 item->DisplayState(vit.value(), "videoprops");
    1378         }
    1379 
    1380         QMap<SubtitleTypes, QString>::iterator sit;
    1381         for (sit = subtitleFlags.begin(); sit != subtitleFlags.end(); ++sit)
    1382         {
    1383             if ((*it)->GetSubtitleType() & sit.key())
    1384                 item->DisplayState(sit.value(), "subtitletypes");
    1385         }
    1386 
    1387         item->DisplayState((*it)->GetCategoryType(), "categorytype");
     1405        new PlaybackBoxListItem(this, m_recordingList, *it);
    13881406    }
     1407    ComputeNextButtonListPage(true);
    13891408
    13901409    if (m_noRecordingsText)
    13911410    {
    void PlaybackBox::customEvent(QEvent *event) 
    41594178        {
    41604179            m_playListPlay.clear();
    41614180        }
     4181        else if (message == "NEXT_BG_PAGE")
     4182        {
     4183            // Lazily compute a "page" of the next 20 button list
     4184            // items before the next screen refresh.  The value 20 is
     4185            // chosen to be large enough that the background
     4186            // computation finishes reasonably quickly, while small
     4187            // enough that it doesn't noticeably affect
     4188            // scrolling/paging UI responsiveness.
     4189            const int pageSize = 20;
     4190            m_bgLoadPending = false;
     4191            if (m_playingSomething)
     4192                m_needUpdate = true;
     4193            else if (m_recordingList)
     4194            {
     4195                int last = min(m_bgLoadCur + pageSize,
     4196                               m_recordingList->GetCount());
     4197                for (; m_bgLoadCur < last; ++m_bgLoadCur)
     4198                    ItemVisibleCore(m_recordingList->GetItemAt(m_bgLoadCur));
     4199                if (m_bgLoadCur < m_recordingList->GetCount())
     4200                    ComputeNextButtonListPage(false);
     4201            }
     4202        }
    41624203    }
    41634204    else
    41644205        ScheduleCommon::customEvent(event);
    void PlaybackBox::SetRecGroupPassword(const QString &newPassword) 
    49034944    m_recGroupPwCache[m_recGroup] = newPassword;
    49044945}
    49054946
     4947void PlaybackBox::ComputeNextButtonListPage(bool restart)
     4948{
     4949    if (restart)
     4950        m_bgLoadCur = 0;
     4951    LOG(VB_GENERAL, LOG_INFO,
     4952        QString("Background buttonlist building: start=%1")
     4953        .arg(m_bgLoadCur));
     4954    if (!m_bgLoadPending)
     4955    {
     4956        QCoreApplication::postEvent(this, new MythEvent("NEXT_BG_PAGE"));
     4957        m_bgLoadPending = true;
     4958    }
     4959}
    49064960///////////////////////////////////////////////////
    49074961
    49084962GroupSelector::GroupSelector(MythScreenStack *lparent, const QString &label,
  • mythtv/programs/mythfrontend/playbackbox.h

    diff --git a/mythtv/programs/mythfrontend/playbackbox.h b/mythtv/programs/mythfrontend/playbackbox.h
    index c6a9a2d..d870a46 100644
    a b class PlaybackBox : public ScheduleCommon 
    142142    void ItemSelected(MythUIButtonListItem *item)
    143143        { UpdateUIListItem(item, true); }
    144144    void ItemVisible(MythUIButtonListItem *item);
     145    void ItemVisibleCore(MythUIButtonListItem *item);
    145146    void selected(MythUIButtonListItem *item);
    146147    void PlayFromBookmark(MythUIButtonListItem *item = NULL);
    147148    void PlayFromBeginning(MythUIButtonListItem *item = NULL);
    class PlaybackBox : public ScheduleCommon 
    435436    mutable QMutex      m_ncLock;
    436437    deque<QString>      m_networkControlCommands;
    437438
     439    // Background button list loading
     440    void ComputeNextButtonListPage(bool restart);
     441    int  m_bgLoadCur;     // index of next buttonlist item to load
     442    bool m_bgLoadPending; // whether a background load event is queued
     443
    438444    // Other
    439445    TV                 *m_player;
    440446    QStringList         m_player_selected_new_show;
  • mythtv/programs/mythfrontend/proglist.cpp

    diff --git a/mythtv/programs/mythfrontend/proglist.cpp b/mythtv/programs/mythfrontend/proglist.cpp
    index ddda2af..b2641a5 100644
    a b ProgLister::ProgLister(MythScreenStack *parent, ProgListType pltype, 
    4444    m_viewTextList(),
    4545
    4646    m_itemList(),
     47    m_itemListSave(),
    4748    m_schedList(),
    4849
    4950    m_typeList(),
    ProgLister::ProgLister(MythScreenStack *parent, ProgListType pltype, 
    5960    m_curviewText(NULL),
    6061    m_positionText(NULL),
    6162    m_progList(NULL),
    62     m_messageText(NULL)
     63    m_messageText(NULL),
     64
     65    // Background buttonlist loading state
     66    m_bgLoadCur(0),
     67    m_bgLoadPending(false)
    6368{
    6469    switch (pltype)
    6570    {
    ProgLister::ProgLister( 
    9398    m_viewTextList(),
    9499
    95100    m_itemList(),
     101    m_itemListSave(),
    96102    m_schedList(),
    97103
    98104    m_typeList(),
    ProgLister::ProgLister( 
    108114    m_curviewText(NULL),
    109115    m_positionText(NULL),
    110116    m_progList(NULL),
    111     m_messageText(NULL)
     117    m_messageText(NULL),
     118
     119    // Background buttonlist loading state
     120    m_bgLoadCur(0),
     121    m_bgLoadPending(false)
    112122{
    113123}
    114124
    115125ProgLister::~ProgLister()
    116126{
    117127    m_itemList.clear();
     128    m_itemListSave.clear();
    118129    gCoreContext->removeListener(this);
    119130}
    120131
    bool ProgLister::Create() 
    139150    connect(m_progList, SIGNAL(itemSelected(MythUIButtonListItem*)),
    140151            this,       SLOT(  HandleSelected(  MythUIButtonListItem*)));
    141152
     153    connect(m_progList, SIGNAL(itemVisible(MythUIButtonListItem*)),
     154            this,       SLOT(  HandleVisible(  MythUIButtonListItem*)));
     155
    142156    connect(m_progList, SIGNAL(itemClicked(MythUIButtonListItem*)),
    143157            this,       SLOT(  HandleClicked()));
    144158
    void ProgLister::FillItemList(bool restorePosition, bool updateDisp) 
    13421356        selectedP = &selected;
    13431357    }
    13441358
     1359    // Save a copy of m_itemList so that deletion of the ProgramInfo
     1360    // objects can be deferred until background processing of old
     1361    // ProgramInfo objects has completed.
     1362    m_itemListSave.clear();
     1363    m_itemListSave = m_itemList;
     1364    m_itemList.setAutoDelete(false);
    13451365    m_itemList.clear();
     1366    m_itemList.setAutoDelete(true);
    13461367
    13471368    if (m_type == plPreviouslyRecorded)
    13481369    {
    void ProgLister::RestoreSelection(const ProgramInfo *selected, 
    14891510    m_progList->SetItemCurrent(i + 1, i + 1 - selectedOffset);
    14901511}
    14911512
    1492 void ProgLister::UpdateButtonList(void)
     1513void ProgLister::ComputeNextButtonListPage(bool restart)
    14931514{
    1494     ProgramList::const_iterator it = m_itemList.begin();
    1495     for (; it != m_itemList.end(); ++it)
     1515    if (restart)
     1516        m_bgLoadCur = 0;
     1517    if (m_bgLoadCur % 100 == 0) // don't overwhelm the logs
     1518        LOG(VB_GENERAL, LOG_INFO,
     1519            QString("Background buttonlist building: start=%1")
     1520            .arg(m_bgLoadCur));
     1521    if (!m_bgLoadPending)
    14961522    {
    1497         MythUIButtonListItem *item =
    1498             new MythUIButtonListItem(
    1499                 m_progList, "", qVariantFromValue(*it));
     1523        QCoreApplication::postEvent(this, new MythEvent("NEXT_BG_PAGE"));
     1524        m_bgLoadPending = true;
     1525    }
     1526}
    15001527
     1528void ProgLister::HandleVisible(MythUIButtonListItem *item)
     1529{
     1530    ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData());
     1531
     1532    if (item->GetText("is_item_initialized").isNull())
     1533    {
    15011534        InfoMap infoMap;
    1502         (**it).ToMap(infoMap);
     1535        pginfo->ToMap(infoMap);
    15031536
    1504         QString state = toUIState((**it).GetRecordingStatus());
     1537        QString state = toUIState(pginfo->GetRecordingStatus());
    15051538        if ((state == "warning") && (plPreviouslyRecorded == m_type))
    15061539            state = "disabled";
    15071540
    void ProgLister::UpdateButtonList(void) 
    15091542
    15101543        if (m_type == plTitle)
    15111544        {
    1512             QString tempSubTitle = (**it).GetSubtitle();
     1545            QString tempSubTitle = pginfo->GetSubtitle();
    15131546            if (tempSubTitle.trimmed().isEmpty())
    1514                 tempSubTitle = (**it).GetTitle();
     1547                tempSubTitle = pginfo->GetTitle();
    15151548            item->SetText(tempSubTitle, "titlesubtitle", state);
    15161549        }
    15171550
    1518         item->DisplayState(
    1519             QString::number((**it).GetStars(10)), "ratingstate");
     1551        item->DisplayState(QString::number(pginfo->GetStars(10)),
     1552                          "ratingstate");
    15201553
    15211554        item->DisplayState(state, "status");
     1555
     1556        // Mark this button list item as initialized.
     1557        item->SetText("yes", "is_item_initialized");
    15221558    }
     1559}
     1560
     1561void ProgLister::UpdateButtonList(void)
     1562{
     1563    ProgramList::const_iterator it = m_itemList.begin();
     1564    for (; it != m_itemList.end(); ++it)
     1565        new MythUIButtonListItem(m_progList, "", qVariantFromValue(*it));
     1566    ComputeNextButtonListPage(true);
    15231567
    15241568    if (m_positionText)
    15251569    {
    void ProgLister::customEvent(QEvent *event) 
    16671711            ShowChooseViewMenu();
    16681712        else if (message == "SCHEDULE_CHANGE")
    16691713            needUpdate = true;
     1714        else if (message == "NEXT_BG_PAGE")
     1715        {
     1716            // Lazily compute a "page" of the next 20 button list
     1717            // items before the next screen refresh.  The value 20 is
     1718            // chosen to be large enough that the background
     1719            // computation finishes reasonably quickly, while small
     1720            // enough that it doesn't noticeably affect
     1721            // scrolling/paging UI responsiveness.
     1722            const int pageSize = 20;
     1723            m_bgLoadPending = false;
     1724            if (m_progList)
     1725            {
     1726                int last = min(m_bgLoadCur + pageSize,
     1727                               m_progList->GetCount());
     1728                for (; m_bgLoadCur < last; ++m_bgLoadCur)
     1729                    HandleVisible(m_progList->GetItemAt(m_bgLoadCur));
     1730                if (m_bgLoadCur < m_progList->GetCount())
     1731                    ComputeNextButtonListPage(false);
     1732            }
     1733        }
    16701734    }
    16711735
    16721736    if (needUpdate)
  • mythtv/programs/mythfrontend/proglist.h

    diff --git a/mythtv/programs/mythfrontend/proglist.h b/mythtv/programs/mythfrontend/proglist.h
    index 1fc9020..b4b47a0 100644
    a b class ProgLister : public ScheduleCommon 
    5050
    5151  protected slots:
    5252    void HandleSelected(MythUIButtonListItem *item);
     53    void HandleVisible(MythUIButtonListItem *item);
    5354    void HandleClicked(void);
    5455
    5556    void DeleteOldEpisode(bool ok);
    class ProgLister : public ScheduleCommon 
    115116    QStringList       m_viewTextList;
    116117
    117118    ProgramList       m_itemList;
     119    ProgramList       m_itemListSave;
    118120    ProgramList       m_schedList;
    119121
    120122    QStringList       m_typeList;
    class ProgLister : public ScheduleCommon 
    131133    MythUIText       *m_positionText;
    132134    MythUIButtonList *m_progList;
    133135    MythUIText       *m_messageText;
     136
     137    // Background button list loading
     138    void ComputeNextButtonListPage(bool restart);
     139    int  m_bgLoadCur;     // index of next buttonlist item to load
     140    bool m_bgLoadPending; // whether a background load event is queued
    134141};
    135142
    136143#endif